Reorganize and clean up plugin

This commit is contained in:
Lucien Greathouse
2019-10-01 18:23:29 -07:00
parent bdd9c58cae
commit f9a5fee364
16 changed files with 125 additions and 113 deletions

View File

@@ -14,13 +14,5 @@ remodel bin/put-plugin-in-test-place.lua "$PLUGIN_FILE" "$PLACE_FILE"
run-in-roblox -s plugin/testBootstrap.server.lua "$PLACE_FILE" run-in-roblox -s plugin/testBootstrap.server.lua "$PLACE_FILE"
pushd plugin pushd plugin
luacheck src luacheck src log http
popd
pushd rojo-plugin-http
luacheck src
popd
pushd rojo-plugin-log
luacheck src
popd popd

View File

@@ -1,7 +0,0 @@
#!/bin/sh
set -ev
cargo test --all --locked --verbose
cargo fmt -- --check
cargo clippy

View File

@@ -20,6 +20,7 @@ stds.roblox = {
"CFrame", "CFrame",
"Enum", "Enum",
"Instance", "Instance",
"DockWidgetPluginGuiInfo",
} }
} }

View File

@@ -5,6 +5,12 @@
"Plugin": { "Plugin": {
"$path": "src" "$path": "src"
}, },
"Log": {
"$path": "log"
},
"Http": {
"$path": "http"
},
"Roact": { "Roact": {
"$path": "modules/roact/src" "$path": "modules/roact/src"
}, },

View File

@@ -1,9 +1,7 @@
local Logging = require(script.Parent.Logging) local Error = {}
Error.__index = Error
local HttpError = {} Error.Kind = {
HttpError.__index = HttpError
HttpError.Error = {
HttpNotEnabled = { HttpNotEnabled = {
message = "Rojo requires HTTP access, which is not enabled.\n" .. message = "Rojo requires HTTP access, which is not enabled.\n" ..
"Check your game settings, located in the 'Home' tab of Studio.", "Check your game settings, located in the 'Home' tab of Studio.",
@@ -20,13 +18,13 @@ HttpError.Error = {
}, },
} }
setmetatable(HttpError.Error, { setmetatable(Error.Kind, {
__index = function(_, key) __index = function(_, key)
error(("%q is not a valid member of HttpError.Error"):format(tostring(key)), 2) error(("%q is not a valid member of Http.Error.Kind"):format(tostring(key)), 2)
end, end,
}) })
function HttpError.new(type, extraMessage) function Error.new(type, extraMessage)
extraMessage = extraMessage or "" extraMessage = extraMessage or ""
local message = type.message:gsub("{{message}}", extraMessage) local message = type.message:gsub("{{message}}", extraMessage)
@@ -35,38 +33,34 @@ function HttpError.new(type, extraMessage)
message = message, message = message,
} }
setmetatable(err, HttpError) setmetatable(err, Error)
return err return err
end end
function HttpError:__tostring() function Error:__tostring()
return self.message return self.message
end end
--[[ --[[
This method shouldn't have to exist. Ugh. This method shouldn't have to exist. Ugh.
]] ]]
function HttpError.fromErrorString(message) function Error.fromErrorString(message)
local lower = message:lower() local lower = message:lower()
if lower:find("^http requests are not enabled") then if lower:find("^http requests are not enabled") then
return HttpError.new(HttpError.Error.HttpNotEnabled) return Error.new(Error.Kind.HttpNotEnabled)
end end
if lower:find("^httperror: timedout") then if lower:find("^httperror: timedout") then
return HttpError.new(HttpError.Error.Timeout) return Error.new(Error.Kind.Timeout)
end end
if lower:find("^httperror: connectfail") then if lower:find("^httperror: connectfail") then
return HttpError.new(HttpError.Error.ConnectFailed) return Error.new(Error.Kind.ConnectFailed)
end end
return HttpError.new(HttpError.Error.Unknown, message) return Error.new(Error.Kind.Unknown, message)
end end
function HttpError:report() return Error
Logging.warn(self.message)
end
return HttpError

View File

@@ -1,34 +1,34 @@
local HttpService = game:GetService("HttpService") local HttpService = game:GetService("HttpService")
local stringTemplate = [[ local stringTemplate = [[
HttpResponse { Http.Response {
code: %d code: %d
body: %s body: %s
}]] }]]
local HttpResponse = {} local Response = {}
HttpResponse.__index = HttpResponse Response.__index = Response
function HttpResponse:__tostring() function Response:__tostring()
return stringTemplate:format(self.code, self.body) return stringTemplate:format(self.code, self.body)
end end
function HttpResponse.fromRobloxResponse(response) function Response.fromRobloxResponse(response)
local self = { local self = {
body = response.Body, body = response.Body,
code = response.StatusCode, code = response.StatusCode,
headers = response.Headers, headers = response.Headers,
} }
return setmetatable(self, HttpResponse) return setmetatable(self, Response)
end end
function HttpResponse:isSuccess() function Response:isSuccess()
return self.code >= 200 and self.code < 300 return self.code >= 200 and self.code < 300
end end
function HttpResponse:json() function Response:json()
return HttpService:JSONDecode(self.body) return HttpService:JSONDecode(self.body)
end end
return HttpResponse return Response

View File

@@ -1,21 +1,23 @@
local HttpService = game:GetService("HttpService") local HttpService = game:GetService("HttpService")
local Promise = require(script.Parent.Parent.Promise) local Promise = require(script.Parent.Promise)
local Log = require(script.Parent.Log)
local Logging = require(script.Parent.Logging) local HttpError = require(script.Error)
local HttpError = require(script.Parent.HttpError) local HttpResponse = require(script.Response)
local HttpResponse = require(script.Parent.HttpResponse)
local lastRequestId = 0 local lastRequestId = 0
-- TODO: Factor out into separate library, especially error handling
local Http = {} local Http = {}
Http.Error = HttpError
Http.Response = HttpResponse
function Http.get(url) function Http.get(url)
local requestId = lastRequestId + 1 local requestId = lastRequestId + 1
lastRequestId = requestId lastRequestId = requestId
Logging.trace("GET(%d) %s", requestId, url) Log.trace("GET(%d) %s", requestId, url)
return Promise.new(function(resolve, reject) return Promise.new(function(resolve, reject)
coroutine.wrap(function() coroutine.wrap(function()
@@ -27,10 +29,10 @@ function Http.get(url)
end) end)
if success then if success then
Logging.trace("Request %d success: status code %s", requestId, response.StatusCode) Log.trace("Request %d success: status code %s", requestId, response.StatusCode)
resolve(HttpResponse.fromRobloxResponse(response)) resolve(HttpResponse.fromRobloxResponse(response))
else else
Logging.trace("Request %d failure: %s", requestId, response) Log.trace("Request %d failure: %s", requestId, response)
reject(HttpError.fromErrorString(response)) reject(HttpError.fromErrorString(response))
end end
end)() end)()
@@ -41,7 +43,7 @@ function Http.post(url, body)
local requestId = lastRequestId + 1 local requestId = lastRequestId + 1
lastRequestId = requestId lastRequestId = requestId
Logging.trace("POST(%d) %s\n%s", requestId, url, body) Log.trace("POST(%d) %s\n%s", requestId, url, body)
return Promise.new(function(resolve, reject) return Promise.new(function(resolve, reject)
coroutine.wrap(function() coroutine.wrap(function()
@@ -54,10 +56,10 @@ function Http.post(url, body)
end) end)
if success then if success then
Logging.trace("Request %d success: status code %s", requestId, response.StatusCode) Log.trace("Request %d success: status code %s", requestId, response.StatusCode)
resolve(HttpResponse.fromRobloxResponse(response)) resolve(HttpResponse.fromRobloxResponse(response))
else else
Logging.trace("Request %d failure: %s", requestId, response) Log.trace("Request %d failure: %s", requestId, response)
reject(HttpError.fromErrorString(response)) reject(HttpError.fromErrorString(response))
end end
end)() end)()

View File

@@ -0,0 +1,5 @@
return function()
it("should load", function()
require(script.Parent)
end)
end

54
plugin/log/init.lua Normal file
View File

@@ -0,0 +1,54 @@
local Level = {
Error = 0,
Warning = 1,
Info = 2,
Debug = 3,
Trace = 4,
}
local function getLogLevel()
return Level.Info
end
local function addTags(tag, message)
return tag .. message:gsub("\n", "\n" .. tag)
end
local TRACE_TAG = (" "):rep(15) .. "[Rojo-Trace] "
local INFO_TAG = (" "):rep(15) .. "[Rojo-Info] "
local DEBUG_TAG = (" "):rep(15) .. "[Rojo-Debug] "
local WARN_TAG = "[Rojo-Warn] "
local Log = {}
Log.Level = Level
function Log.setLogLevelThunk(thunk)
getLogLevel = thunk
end
function Log.trace(template, ...)
if getLogLevel() >= Level.Trace then
print(addTags(TRACE_TAG, string.format(template, ...)))
end
end
function Log.info(template, ...)
if getLogLevel() >= Level.Info then
print(addTags(INFO_TAG, string.format(template, ...)))
end
end
function Log.debug(template, ...)
if getLogLevel() >= Level.Debug then
print(addTags(DEBUG_TAG, string.format(template, ...)))
end
end
function Log.warn(template, ...)
if getLogLevel() >= Level.Warning then
warn(addTags(WARN_TAG, string.format(template, ...)))
end
end
return Log

5
plugin/log/init.spec.lua Normal file
View File

@@ -0,0 +1,5 @@
return function()
it("should load", function()
require(script.Parent)
end)
end

View File

@@ -1,9 +1,8 @@
local Promise = require(script.Parent.Parent.Promise) local Promise = require(script.Parent.Parent.Promise)
local Http = require(script.Parent.Parent.Http)
local Config = require(script.Parent.Config) local Config = require(script.Parent.Config)
local Version = require(script.Parent.Version) local Version = require(script.Parent.Version)
local Http = require(script.Parent.Http)
local HttpError = require(script.Parent.HttpError)
local ApiContext = {} local ApiContext = {}
ApiContext.__index = ApiContext ApiContext.__index = ApiContext
@@ -143,7 +142,7 @@ function ApiContext:retrieveMessages()
local function sendRequest() local function sendRequest()
return Http.get(url) return Http.get(url)
:catch(function(err) :catch(function(err)
if err.type == HttpError.Error.Timeout then if err.type == Http.Error.Kind.Timeout then
return sendRequest() return sendRequest()
end end

View File

@@ -8,8 +8,6 @@ local Version = require(Plugin.Version)
local Assets = require(Plugin.Assets) local Assets = require(Plugin.Assets)
local Theme = require(Plugin.Theme) local Theme = require(Plugin.Theme)
local FitText = require(Plugin.Components.FitText)
local e = Roact.createElement local e = Roact.createElement
local RojoFooter = Roact.Component:extend("RojoFooter") local RojoFooter = Roact.Component:extend("RojoFooter")

View File

@@ -1,50 +1,2 @@
local DevSettings = require(script.Parent.DevSettings) -- TODO: Remove this once all references have been updated.
return require(script.Parent.Parent.Log)
local Level = {
Error = 0,
Warning = 1,
Info = 2,
Trace = 3,
}
local testLogLevel = nil
local function getLogLevel()
if testLogLevel ~= nil then
return testLogLevel
end
return DevSettings:getLogLevel()
end
local function addTags(tag, message)
return tag .. message:gsub("\n", "\n" .. tag)
end
local INFO_TAG = (" "):rep(15) .. "[Rojo-Info] "
local TRACE_TAG = (" "):rep(15) .. "[Rojo-Trace] "
local WARN_TAG = "[Rojo-Warn] "
local Log = {}
Log.Level = Level
function Log.trace(template, ...)
if getLogLevel() >= Level.Trace then
print(addTags(TRACE_TAG, string.format(template, ...)))
end
end
function Log.info(template, ...)
if getLogLevel() >= Level.Info then
print(addTags(INFO_TAG, string.format(template, ...)))
end
end
function Log.warn(template, ...)
if getLogLevel() >= Level.Warning then
warn(addTags(WARN_TAG, string.format(template, ...)))
end
end
return Log

View File

@@ -161,7 +161,10 @@ function Reconciler:__reify(virtualInstancesById, id, parent)
end) end)
if not ok then if not ok then
error(("Couldn't create an Instance of type %q, a child of %s"):format(virtualInstance.ClassName, parent:GetFullName())) error(("Couldn't create an Instance of type %q, a child of %s"):format(
virtualInstance.ClassName,
parent:GetFullName()
))
end end
for key, value in pairs(virtualInstance.Properties) do for key, value in pairs(virtualInstance.Properties) do

View File

@@ -2,6 +2,14 @@ if not plugin then
return return
end end
local Log = require(script.Parent.Log)
local DevSettings = require(script.DevSettings)
Log.setLogLevelThunk(function()
return DevSettings:getLogLevel()
end)
local Roact = require(script.Parent.Roact) local Roact = require(script.Parent.Roact)
local Config = require(script.Config) local Config = require(script.Config)

View File

@@ -12,7 +12,7 @@ if setDevSettings then
DevSettings:createTestSettings() DevSettings:createTestSettings()
end end
TestEZ.TestBootstrap:run({Rojo.Plugin}) TestEZ.TestBootstrap:run({ Rojo.Plugin, Rojo.Http, Rojo.Log })
if setDevSettings then if setDevSettings then
DevSettings:resetValues() DevSettings:resetValues()