aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdam Harrison <adamdharrison@gmail.com>2024-03-31 16:26:36 -0400
committerAdam Harrison <adamdharrison@gmail.com>2024-03-31 16:26:36 -0400
commit388c1937c2990d5690cf3a8714a9d25ba1c7a4c1 (patch)
treeb90cc51994503dfef41e0947bbd4f9e5c6d4a0ab
parentdd06ba252e662b6f7525e6a88fef3d55326c20c3 (diff)
downloadlite-xl-plugin-manager-388c1937c2990d5690cf3a8714a9d25ba1c7a4c1.tar.gz
lite-xl-plugin-manager-388c1937c2990d5690cf3a8714a9d25ba1c7a4c1.zip
Restructured functions to be more modular, and moved things to globals, so that they can easily be modified by plugins instead of as upvalues.
-rw-r--r--src/lpm.c2
-rw-r--r--src/lpm.lua132
2 files changed, 68 insertions, 66 deletions
diff --git a/src/lpm.c b/src/lpm.c
index 835c633..c464bae 100644
--- a/src/lpm.c
+++ b/src/lpm.c
@@ -1520,7 +1520,7 @@ int main(int argc, char* argv[]) {
lua_setglobal(L, "EXEFILE");
lua_pushliteral(L, LITE_ARCH_TUPLE);
- lua_setglobal(L, "ARCH");
+ lua_setglobal(L, "DEFAULT_ARCH");
lua_pushliteral(L, LPM_DEFAULT_REPOSITORY);
lua_setglobal(L, "DEFAULT_REPO_URL");
lua_pushliteral(L, LPM_DEFAULT_RELEASE);
diff --git a/src/lpm.lua b/src/lpm.lua
index 8959f87..14ce0fc 100644
--- a/src/lpm.lua
+++ b/src/lpm.lua
@@ -1,4 +1,6 @@
-setmetatable(_G, { __index = function(t, k) if not rawget(t, k) then error("cannot get undefined global variable: " .. k, 2) end end, __newindex = function(t, k) error("cannot set global variable: " .. k, 2) end })
+_S = {}
+function global(g) if #g > 0 then for i,v in ipairs(g) do rawset(_S, g[i], true) end else for k,v in pairs(g) do rawset(_G, k, v) rawset(_S, k, true) end end end
+setmetatable(_G, { __index = function(t, k) if not rawget(_S, k) then error("cannot get undefined global variable: " .. k, 2) end end, __newindex = function(t, k, v) if rawget(_S, k) then rawset(t, k, v) else error("cannot set global variable: " .. k, 2) end end })
-- Begin rxi JSON library.
local json = { _version = "0.1.2" }
@@ -377,7 +379,7 @@ end
-- End JSON library.
-local common = {}
+global({ common = {} })
function common.merge(dst, src) for k, v in pairs(src) do dst[k] = v end return dst end
function common.map(l, p) local t = {} for i, v in ipairs(l) do table.insert(t, p(v, i)) end return t end
function common.each(l, p) for i, v in ipairs(l) do p(v) end end
@@ -529,11 +531,13 @@ function common.args(arguments, options)
return args
end
-local LATEST_MOD_VERSION = "3.0.0"
-local EXECUTABLE_EXTENSION = PLATFORM == "windows" and ".exe" or ""
-local HOME, USERDIR, CACHEDIR, JSON, TABLE, HEADER, RAW, VERBOSE, FILTRATION, MOD_VERSION, QUIET, FORCE, REINSTALL, CONFIG, NO_COLOR, AUTO_PULL_REMOTES, ARCH, ASSUME_YES, NO_INSTALL_OPTIONAL, TMPDIR, DATADIR, BINARY, POST, PROGRESS, SYMLINK, REPOSITORY, EPHEMERAL, MASK, settings, repositories, lite_xls, system_bottle, progress_bar_label, write_progress_bar
-local SHOULD_COLOR = (PLATFORM == "windows" or (os.getenv("TERM") and os.getenv("TERM") ~= "dumb")) and not os.getenv("NO_COLOR")
-local Addon, Repository, LiteXL, Bottle, lpm, log = {}, {}, {}, {}, {}, {}
+global({
+ LATEST_MOD_VERSION = "3.0.0",
+ EXECUTABLE_EXTENSION = PLATFORM == "windows" and ".exe" or "",
+ SHOULD_COLOR = (PLATFORM == "windows" or (os.getenv("TERM") and os.getenv("TERM") ~= "dumb")) and not os.getenv("NO_COLOR")
+})
+global({ "HOME", "USERDIR", "CACHEDIR", "JSON", "TABLE", "HEADER", "RAW", "VERBOSE", "FILTRATION", "MOD_VERSION", "QUIET", "FORCE", "REINSTALL", "CONFIG", "NO_COLOR", "AUTO_PULL_REMOTES", "ARCH", "ASSUME_YES", "NO_INSTALL_OPTIONAL", "TMPDIR", "DATADIR", "BINARY", "POST", "PROGRESS", "SYMLINK", "REPOSITORY", "EPHEMERAL", "MASK", "settings", "repositories", "lite_xls", "system_bottle", "progress_bar_label", "write_progress_bar" })
+global({ Addon = {}, Repository = {}, LiteXL = {}, Bottle = {}, lpm = {}, log = {} })
local function engage_locks(func, err, warn)
if not system.stat(CACHEDIR) then common.mkdirp(CACHEDIR) end
@@ -1334,8 +1338,8 @@ function LiteXL.new(repository, metadata)
end
function LiteXL:get_binary_path(arch)
- if self.binary_path and self.binary_path[arch or _G.ARCH] then return self.binary_path[arch or _G.ARCH] end
- return self.local_path .. PATHSEP .. "lite-xl." .. (arch or _G.ARCH)
+ if self.binary_path and self.binary_path[arch or DEFAULT_ARCH] then return self.binary_path[arch or DEFAULT_ARCH] end
+ return self.local_path .. PATHSEP .. "lite-xl." .. (arch or DEFAULT_ARCH)
end
function LiteXL:is_system() return system_bottle and system_bottle.lite_xl == self end
@@ -2084,9 +2088,54 @@ function lpm.purge()
common.rmrf(CACHEDIR)
end
+-- Base setup; initialize default repos if applicable, read them in. Determine Lite XL system binary if not specified, and pull in a list of all local lite-xl's.
+function lpm.setup()
+ settings = { lite_xls = {}, repositories = {}, installed = {}, version = VERSION }
+ lpm.repo_init(ARGS[2] == "init" and #ARGS > 2 and (ARGS[3] ~= "none" and common.map(common.slice(ARGS, 3), function(url) return Repository.url(url) end) or {}) or nil)
+ repositories, lite_xls = {}, {}
+ if system.stat(CACHEDIR .. PATHSEP .. "settings.json") then settings = json.decode(common.read(CACHEDIR .. PATHSEP .. "settings.json")) end
+ repositories = common.map(settings.repositories or {}, function(url) local repo = Repository.url(url) repo:parse_manifest() return repo end)
+ lite_xls = common.map(settings.lite_xls or {}, function(lite_xl) return LiteXL.new(nil, { version = lite_xl.version, mod_version = lite_xl.mod_version, binary_path = lite_xl.binary_path, datadir_path = lite_xl.datadir_path, path = lite_xl.path, tags = { "local" } }) end)
+
+ if BINARY and not system.stat(BINARY) then error("can't find specified --binary") end
+ if DATADIR and not system.stat(DATADIR) then error("can't find specified --datadir") end
+ local lite_xl_binary = BINARY or common.path("lite-xl" .. EXECUTABLE_EXTENSION)
+ if lite_xl_binary then
+ local stat = system.stat(lite_xl_binary)
+ if not stat then error("can't find lite-xl binary " .. lite_xl_binary) end
+ lite_xl_binary = stat.symlink or lite_xl_binary
+ local system_lite_xl = common.first(common.concat(common.flat_map(repositories, function(r) return r.lite_xls end), lite_xls), function(lite_xl) return lite_xl:get_binary_path() == lite_xl_binary end)
+ if not system_lite_xl then
+ system_lite_xl = common.first(lite_xls, function(e) return e.version == "system" end)
+
+ local directory = common.dirname(lite_xl_binary)
+ local lite_xl_datadirs = { DATADIR or "", directory .. PATHSEP .. "data", directory:find(PATHSEP .. "bin$") and common.dirname(directory) .. PATHSEP .. "share" .. PATHSEP .. "lite-xl" or "", directory .. PATHSEP .. "data" }
+ local lite_xl_datadir = common.first(lite_xl_datadirs, function(p) return p and system.stat(p) end)
+
+ if not BINARY and not DATADIR and system_lite_xl then error("can't find existing system lite (does " .. system_lite_xl:get_binary_path() .. " exist? was it moved?); run `lpm purge`, or specify --binary and --datadir.") end
+ local detected_lite_xl = LiteXL.new(nil, { path = directory, datadir_path = lite_xl_datadir, binary_path = { [DEFAULT_ARCH] = lite_xl_binary }, mod_version = MOD_VERSION or LATEST_MOD_VERSION, version = "system", tags = { "system", "local" } })
+ if not system_lite_xl then
+ system_lite_xl = detected_lite_xl
+ table.insert(lite_xls, system_lite_xl)
+ lpm.lite_xl_save()
+ else
+ lite_xls = common.grep(lite_xls, function(e) return e ~= system_lite_xl end)
+ system_lite_xl = detected_lite_xl
+ table.insert(lite_xls, system_lite_xl)
+ end
+ else
+ if DATADIR then system_lite_xl.datadir_path = DATADIR end
+ table.insert(system_lite_xl.tags, "system")
+ end
+ system_bottle = Bottle.new(system_lite_xl, nil, nil, true)
+ else
+ system_bottle = Bottle.new(LiteXL.new(nil, { mod_version = MOD_VERSION or LATEST_MOD_VERSION, datadir_path = DATADIR, version = "system", tags = { "system", "local" } }), nil, nil, true)
+ end
+ if not system_bottle then system_bottle = Bottle.new(nil, nil, nil, true) end
+ if REPOSITORY then repositories = common.map(type(REPOSITORY) == "table" and REPOSITORY or { REPOSITORY }, function(url) local repo = Repository.url(url) repo:parse_manifest() return repo end) end
+end
-
-local function run_command(ARGS)
+function lpm.run_command(ARGS)
if not ARGS[2]:find("%S") then return
elseif ARGS[2] == "init" then return
elseif ARGS[2] == "repo" and ARGS[3] == "add" then lpm.repo_add(table.unpack(common.slice(ARGS, 4)))
@@ -2170,7 +2219,7 @@ xpcall(function()
io.stdout:write([[
Usage: lpm COMMAND [...ARGUMENTS] [--json] [--userdir=directory]
[--cachedir=directory] [--quiet] [--version] [--help] [--remotes]
- [--ssl-certs=directory/file] [--force] [--arch=]] .. _G.ARCH .. [[]
+ [--ssl-certs=directory/file] [--force] [--arch=]] .. DEFAULT_ARCH .. [[]
[--assume-yes] [--no-install-optional] [--verbose] [--mod-version=3]
[--datadir=directory] [--binary=path] [--symlink] [--post] [--reinstall]
[--no-color] [--table=...] [--plugin=file/url]
@@ -2274,7 +2323,7 @@ Flags have the following effects:
--help Displays this help text.
--ssl-certs Sets the SSL certificate store. Can be a directory,
or path to a certificate bundle.
- --arch=architecture Sets the architecture (default: ]] .. _G.ARCH .. [[).
+ --arch=architecture Sets the architecture (default: ]] .. DEFAULT_ARCH .. [[).
--assume-yes Ignores any prompts, and automatically answers yes
to all.
--no-install-optional On install, anything marked as optional
@@ -2403,7 +2452,7 @@ not commonly used publically.
DATADIR = common.normalize_path(ARGS["datadir"])
BINARY = common.normalize_path(ARGS["binary"])
NO_INSTALL_OPTIONAL = ARGS["no-install-optional"]
- ARCH = ARGS["arch"] or { _G.ARCH }
+ ARCH = ARGS["arch"] or { DEFAULT_ARCH }
ASSUME_YES = ARGS["assume-yes"] or FORCE
MOD_VERSION = ARGS["mod-version"] or os.getenv("LPM_MODVERSION")
if MOD_VERSION == "any" then MOD_VERSION = nil end
@@ -2518,11 +2567,7 @@ not commonly used publically.
local lpm_plugins_path = HOME .. PATHSEP .. ".config" .. PATHSEP .. "lpm" .. PATHSEP .. "plugins"
local lpm_plugins = system.stat(lpm_plugins_path) and common.map(common.grep(system.ls(lpm_plugins_path), function(path) return path:find("%.lua$") end), function(path) return lpm_plugins_path .. PATHSEP .. path end) or {}
- local env = setmetatable({
- EXECUTABLE_EXTENSION = EXECUTABLE_EXTENSION, SHOULD_COLOR = SHOULD_COLOR, HOME = HOME, USERDIR = USERDIR, CACHEDIR = CACHEDIR, JSON = JSON, TABLE = TABLE, HEADER = HEADER, RAW = RAW, VERBOSE = VERBOSE, FILTRATION = FILTRATION, MOD_VERSION = MOD_VERSION, QUIET = QUIET, FORCE = FORCE, REINSTALL = REINSTALL, CONFIG = CONFIG, NO_COLOR = NO_COLOR, AUTO_PULL_REMOTES = AUTO_PULL_REMOTES, ARCH = ARCH, ASSUME_YES = ASSUME_YES, NO_INSTALL_OPTIONAL = NO_INSTALL_OPTIONAL, TMPDIR = TMPDIR, DATADIR = DATADIR, BINARY = BINARY, POST = POST, PROGRESS = PROGRESS, SYMLINK = SYMLINK, REPOSITORY = REPOSITORY, EPHEMERAL = EPHEMERAL, MASK = MASK,
- Addon = Addon, Repository = Repository, LiteXL = LiteXL, Bottle = Bottle, lpm = lpm, common = common, json = json, log = log,
- settings = settings, repositories = repositories, lite_xls = lite_xls, system_bottle = system_bottle, progress_bar_label = progress_bar_label, write_progress_bar = write_progress_bar
- }, { __index = _G, __newindex = function(t, k, v) _G[k] = v end })
+ local env = setmetatable({}, { __index = _G, __newindex = function(t, k, v) _G[k] = v end })
for i,v in ipairs(common.concat(ARGS["plugin"] or {}, { common.split(",", os.getenv("LPM_PLUGINS") or "") }, lpm_plugins)) do
if v ~= "" then
@@ -2616,57 +2661,14 @@ not commonly used publically.
end
if not system.stat(USERDIR) then common.mkdirp(USERDIR) end
- -- Base setup; initialize default repos if applicable, read them in. Determine Lite XL system binary if not specified, and pull in a list of all local lite-xl's.
if engage_locks(function()
- settings = { lite_xls = {}, repositories = {}, installed = {}, version = VERSION }
- lpm.repo_init(ARGS[2] == "init" and #ARGS > 2 and (ARGS[3] ~= "none" and common.map(common.slice(ARGS, 3), function(url) return Repository.url(url) end) or {}) or nil)
- repositories, lite_xls = {}, {}
- if system.stat(CACHEDIR .. PATHSEP .. "settings.json") then settings = json.decode(common.read(CACHEDIR .. PATHSEP .. "settings.json")) end
- repositories = common.map(settings.repositories or {}, function(url) local repo = Repository.url(url) repo:parse_manifest() return repo end)
- lite_xls = common.map(settings.lite_xls or {}, function(lite_xl) return LiteXL.new(nil, { version = lite_xl.version, mod_version = lite_xl.mod_version, binary_path = lite_xl.binary_path, datadir_path = lite_xl.datadir_path, path = lite_xl.path, tags = { "local" } }) end)
-
- if BINARY and not system.stat(BINARY) then error("can't find specified --binary") end
- if DATADIR and not system.stat(DATADIR) then error("can't find specified --datadir") end
- local lite_xl_binary = BINARY or common.path("lite-xl" .. EXECUTABLE_EXTENSION)
- if lite_xl_binary then
- local stat = system.stat(lite_xl_binary)
- if not stat then error("can't find lite-xl binary " .. lite_xl_binary) end
- lite_xl_binary = stat.symlink or lite_xl_binary
- local system_lite_xl = common.first(common.concat(common.flat_map(repositories, function(r) return r.lite_xls end), lite_xls), function(lite_xl) return lite_xl:get_binary_path() == lite_xl_binary end)
- if not system_lite_xl then
- system_lite_xl = common.first(lite_xls, function(e) return e.version == "system" end)
-
- local directory = common.dirname(lite_xl_binary)
- local lite_xl_datadirs = { DATADIR or "", directory .. PATHSEP .. "data", directory:find(PATHSEP .. "bin$") and common.dirname(directory) .. PATHSEP .. "share" .. PATHSEP .. "lite-xl" or "", directory .. PATHSEP .. "data" }
- local lite_xl_datadir = common.first(lite_xl_datadirs, function(p) return p and system.stat(p) end)
-
- if not BINARY and not DATADIR and system_lite_xl then error("can't find existing system lite (does " .. system_lite_xl:get_binary_path() .. " exist? was it moved?); run `lpm purge`, or specify --binary and --datadir.") end
- local detected_lite_xl = LiteXL.new(nil, { path = directory, datadir_path = lite_xl_datadir, binary_path = { [_G.ARCH] = lite_xl_binary }, mod_version = MOD_VERSION or LATEST_MOD_VERSION, version = "system", tags = { "system", "local" } })
- if not system_lite_xl then
- system_lite_xl = detected_lite_xl
- table.insert(lite_xls, system_lite_xl)
- lpm.lite_xl_save()
- else
- lite_xls = common.grep(lite_xls, function(e) return e ~= system_lite_xl end)
- system_lite_xl = detected_lite_xl
- table.insert(lite_xls, system_lite_xl)
- end
- else
- if DATADIR then system_lite_xl.datadir_path = DATADIR end
- table.insert(system_lite_xl.tags, "system")
- end
- system_bottle = Bottle.new(system_lite_xl, nil, nil, true)
- else
- system_bottle = Bottle.new(LiteXL.new(nil, { mod_version = MOD_VERSION or LATEST_MOD_VERSION, datadir_path = DATADIR, version = "system", tags = { "system", "local" } }), nil, nil, true)
- end
- if not system_bottle then system_bottle = Bottle.new(nil, nil, nil, true) end
- if REPOSITORY then repositories = common.map(type(REPOSITORY) == "table" and REPOSITORY or { REPOSITORY }, function(url) local repo = Repository.url(url) repo:parse_manifest() return repo end) end
+ lpm.setup()
end, error_handler, lock_warning) then return end
if ARGS[2] ~= '-' then
local res
engage_locks(function()
- res = run_command(ARGS)
+ res = lpm.run_command(ARGS)
end, error_handler, lock_warning)
if res then
res()
@@ -2686,7 +2688,7 @@ not commonly used publically.
xpcall(function()
local res
engage_locks(function()
- res = run_command(args)
+ res = lpm.run_command(args)
end, error_handler, lock_warning)
if res then
res()