Skip to content

Commit

Permalink
Added watch CLI action.
Browse files Browse the repository at this point in the history
  • Loading branch information
Avril112113 committed May 1, 2024
1 parent bc82e50 commit 6f595d3
Show file tree
Hide file tree
Showing 6 changed files with 142 additions and 21 deletions.
15 changes: 6 additions & 9 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
{
"Lua.runtime.version": "LuaJIT",
"Lua.workspace.library": [
"c:/Users/avril/.vscode/extensions/nameouschangey.lifeboatapi-0.0.33/assets/lua/Common/",
"c:/Users/avril/.vscode/extensions/nameouschangey.lifeboatapi-0.0.33/assets/lua/Addon/",
"c:/Users/avril/.vscode/extensions/nameouschangey.lifeboatapi-0.0.33/assets/lua/Common/",
"c:/Users/avril/.vscode/extensions/nameouschangey.lifeboatapi-0.0.33/assets/lua/Addon/",
"C:/Users/avril/AppData/Roaming/Code/User/globalStorage/sumneko.lua/addonManager/addons/luafilesystem/module/library",
"C:/Users/avril/AppData/Roaming/Code/User/globalStorage/sumneko.lua/addonManager/addons/luasocket/module/library",
"C:/Projects/Lua/Stormworks/AvrilsSWTools/AVCmds",
"../SelenScript",
"../SelenScript/libs"
],
Expand All @@ -12,16 +14,11 @@
"Lua.runtime.path": [
"?.lua",
"?/init.lua",
"../SelenScript/libs/?.lua",
"../SelenScript/libs/?/init.lua",
"../SelenScript/?.lua",
"../SelenScript/?/init.lua"
"typing/?.lua"
],
"Lua.workspace.ignoreDir": [
".vscode",
"release",
"test_addon",
"IMAI"
"release"
],
"json.schemas": [
{
Expand Down
1 change: 1 addition & 0 deletions tool/cli/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ local CLI = {}
CLI.actions = {
help = require("tool.cli.help")(CLI),
build = require("tool.cli.build")(CLI),
watch = require("tool.cli.watch")(CLI),
}

---@param args string[]
Expand Down
112 changes: 112 additions & 0 deletions tool/cli/watch.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
local ffi = require "ffi"
local LuaNotify = require "luanotify"
local AVPath = require "avpath"

local MultiProject = require "tool.multi_project"


ffi.cdef[[
void Sleep(int ms);
int poll(struct pollfd *fds, unsigned long nfds, int timeout);
]]
local sleep
if ffi.os == "Windows" then
function sleep(s)
ffi.C.Sleep(s*1000)
end
else
function sleep(s)
ffi.C.poll(nil, 0, s*1000)
end
end


---@param CLI SSWTool.CLI
return function(CLI)
---@type SSWTool.CLI.Action
return {
help = "Build a SW addon project.",
usage = "[path=./]",
---@param args string[]
---@param pos integer
handler = function(args, pos)
---@param project SSSWTool.MultiProject|SSSWTool.Project
local function get_watch_paths(project, paths)
paths = paths or {}
if project.__name == "Project" then
---@cast project SSSWTool.Project
local src = project.config.src
if type(src) == "table" then
for _, v in pairs(src) do
if not AVPath.getabs(v) then
v = AVPath.join{project.multiproject.project_path, v}
end
table.insert(paths, v)
end
elseif type(src) == "string" then
if not AVPath.getabs(src) then
src = AVPath.join{project.multiproject.project_path, src}
end
table.insert(paths, src)
end
elseif project.__name == "MultiPorject" then
---@cast project SSSWTool.MultiProject
table.insert(paths, project.config_path)
for _, subproject in pairs(project.projects) do
get_watch_paths(subproject, paths)
end
else
error(("Not a Project or MultiProject? '%s'"):format(tostring(project)))
end
return paths
end

---@param addon_dir string
local function build(addon_dir)
local multi_project, err = MultiProject.new(addon_dir .. "/ssswtool.json")
if not multi_project or err then
print_error(err or "FAIL project ~= nil")
elseif multi_project then
multi_project:build()
end
return multi_project, err
end

local addon_dir = args[pos] or "./"
pos = pos + 1
local multi_project = build(addon_dir)
if not multi_project then return -1 end
print("\n~ Beginning watch.")
local ok, err = xpcall(function()
while true do
local watcher = LuaNotify.new()
watcher:whitelist_glob("*.lua")
watcher:whitelist_glob("*.json")
watcher:blacklist_glob("*/_build/*")
for _, path in pairs(get_watch_paths(multi_project)) do
watcher:watch(path, true)
end
while true do
local event = watcher:poll()
if event then break end
end
sleep(100/1000)
print("\n~ Detected file change, building...")
local new_multi_project = build(addon_dir)
if new_multi_project then
multi_project = new_multi_project
end
end
end, debug.traceback)
if not ok then
if err ~= nil and err:sub(1, 12) ~= "interrupted!" then
print("Watch stopped.")
elseif err == nil or err:sub(1, 12) ~= "interrupted!" then
print(err or "watch not ok and missing error msg.")
return -1
end
end
return 0
end,
}
end
17 changes: 6 additions & 11 deletions tool/config.lua
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,17 @@ end
function Config:read(path)
local f, msg, code = io.open(path, "r")
if not f then
-- If file not found, then we just keep the config we have (should be default)
if code == 2 then
return true
end
return false, msg, code
end
local src = f:read("*a")
local src, err = f:read("*a")
f:close()
if err then
return false, ("Failed to read config '%s'\n%s"):format(path, err)
end
local ok, data = pcall(json.decode, src)
if not ok then
return false, ("Failed to parse config '%s'\n%s"):format(path, data:gsub(".-:.-: ", ""))
Expand All @@ -49,15 +54,5 @@ function Config:read(path)
return true
end

-- ---@param path string
-- function Config:write(path)
-- local f, msg, code = io.open(path, "w")
-- if not f then
-- return false, msg, code
-- end
-- error("TODO")
-- return true
-- end


return Config
8 changes: 8 additions & 0 deletions tool/multi_project.lua
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ local Project = require "tool.project"
---@field projects (SSSWTool.Project|SSSWTool.MultiProject)[]
---@field config SSSWTool.Config
local MultiPorject = {}
MultiPorject.__name = "MultiPorject"
MultiPorject.__index = MultiPorject


Expand Down Expand Up @@ -43,6 +44,13 @@ function MultiPorject.new(config_path)
return self
end

function MultiPorject:__tostring()
if self == MultiPorject then
return ("<%s>"):format(MultiPorject.__name)
end
return ("<%s %p '%s'>"):format(MultiPorject.__name, self, self.config_path)
end

---@param project_config SSSWTool.Project.Config
---@param project_path string
function MultiPorject:createProject(project_config, project_path)
Expand Down
10 changes: 9 additions & 1 deletion tool/project.lua
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ end
---@field multiproject SSSWTool.MultiProject
---@field config SSSWTool.Project.Config
local Project = {}
Project.__name = "Project"
Project.__index = Project

Project.TRANSFORMERS = {
Expand Down Expand Up @@ -81,7 +82,7 @@ end
---@param infer_name boolean
function Project.getDefaultConfig(multiproject, infer_name)
return {
name = infer_name and multiproject.project_path:match("/(.-)$") or nil,
name = infer_name and multiproject.project_path:match("[\\/](.-)$") or nil,
src = ".",
out = nil,
transformers = Project.DEFAULT_TRANSFORMERS,
Expand All @@ -100,6 +101,13 @@ function Project.new(multiproject, config)
return self
end

function Project:__tostring()
if self == Project then
return ("<%s>"):format(Project.__name)
end
return ("<%s %p '%s'>"):format(Project.__name, self, self.config and self.config.name)
end

---@param path string # Project local path to file.
---@return string, string, nil
---@overload fun(path:string): nil, nil, string
Expand Down

0 comments on commit 6f595d3

Please sign in to comment.