aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/lpm.lua90
1 files changed, 75 insertions, 15 deletions
diff --git a/src/lpm.lua b/src/lpm.lua
index bfb9fb4..5a95b90 100644
--- a/src/lpm.lua
+++ b/src/lpm.lua
@@ -454,7 +454,7 @@ function common.chdir(dir, callback)
if not status then error(err) end
end
-local HOME, USERDIR, CACHEDIR, JSON, VERBOSE, MOD_VERSION, QUIET, FORCE, AUTO_PULL_REMOTES, ARCH, ASSUME_YES, NO_INSTALL_OPTIONAL, TMPDIR, DATADIR, BINARY, POST, repositories, lite_xls, system_bottle, progress_bar_label, write_progress_bar
+local HOME, USERDIR, CACHEDIR, JSON, VERBOSE, FILTRATION, MOD_VERSION, QUIET, FORCE, AUTO_PULL_REMOTES, ARCH, ASSUME_YES, NO_INSTALL_OPTIONAL, TMPDIR, DATADIR, BINARY, POST, repositories, lite_xls, system_bottle, progress_bar_label, write_progress_bar
local function engage_locks(func, err)
if not system.stat(USERDIR) then common.mkdirp(USERDIR) end
@@ -535,6 +535,7 @@ function common.get(source, target, checksum, callback, depth)
end
+
local function compare_version(a, b) -- compares semver
if not a or not b then return false end
local _, _, majora, minora, revisiona = tostring(a):find("(%d+)%.?(%d*)%.?(%d*)")
@@ -580,6 +581,7 @@ function Addon.new(repository, metadata)
path = nil,
remote = nil,
version = "1.0",
+ location = "user",
dependencies = {},
conflicts = {},
name = metadata.id
@@ -638,8 +640,8 @@ function Addon:get_install_path(bottle)
return path
end
-function Addon:is_core(bottle) return self.type == "core" end
-function Addon:is_bundled(bottle) return self.type == "bundled" end
+function Addon:is_core(bottle) return self.location == "core" end
+function Addon:is_bundled(bottle) return self.location == "bundled" end
function Addon:is_installed(bottle)
if self:is_core(bottle) or self:is_bundled(bottle) or not self.repository then return true end
local install_path = self:get_install_path(bottle)
@@ -1197,7 +1199,8 @@ function Bottle:all_addons()
if i == 2 or not hash[id] or not matching then
table.insert(t, Addon.new(nil, {
id = id,
- type = (addon_type == "plugins" and (i == 2 and (hash[id] and "bundled" or "core") or "plugin") or "library"),
+ type = (addon_type == "plugins" and "plugin") or "library",
+ location = (i == 2 and (hash[id] and "bundled" or "core")) or "user",
organization = (v:find("%.lua$") and "singleton" or "complex"),
local_path = path,
mod_version = self.lite_xl.mod_version,
@@ -1216,6 +1219,30 @@ function Bottle:installed_addons()
return common.grep(self:all_addons(), function(p) return p:is_installed(self) end)
end
+local function filter_match(field, filter)
+ if not field and not filter then return true end
+ if not field and filter then return false end
+ local filters = type(filter) == "table" and filter or { filter }
+ for i,v in ipairs(filters) do
+ local inverted = filter:find("^!")
+ local actual_filter = inverted and filter:sub(2) or filter
+ local matches = field:find("^" .. actual_filter .. "$")
+ if not matches and not inverted then return false end
+ if matches and inverted then return false end
+ end
+ return true
+end
+
+local function addon_matches_filter(addon, filters)
+ return filter_match(addon.author, filters["author"]) and
+ filter_match(addon.tags, filters["tag"]) and
+ filter_match(addon.status, filters["status"]) and
+ filter_match(addon.stub, filters["stub"]) and
+ filter_match(addon.dependencies, filters["dependency"]) and
+ filter_match(addon.type, filters["type"]) and
+ filter_match(addon.name or addon.id, filters["name"])
+end
+
function Bottle:get_addon(id, version, filter)
local candidates = {}
local wildcard = id:find("%*$")
@@ -1485,14 +1512,14 @@ local function lpm_repo_list()
end
end
-local function lpm_addon_list(type, id)
+local function lpm_addon_list(type, id, filters)
local max_id = 4
local plural = (type or "addon") .. "s"
local result = { [plural] = { } }
for j,addon in ipairs(common.grep(system_bottle:all_addons(), function(p) return (not type or p.type == type) and (not id or p.id:find(id)) end)) do
max_id = math.max(max_id, #addon.id)
local repo = addon.repository
- table.insert(result[plural], {
+ local hash = {
id = addon.id,
status = addon.repository and (addon:is_installed(system_bottle) and "installed" or (system_bottle.lite_xl:is_compatible(addon) and "available" or "incompatible")) or (addon:is_bundled(system_bottle) and "bundled" or (addon:is_core(system_bottle) and "core" or (addon:is_upgradable(system_bottle) and "upgradable" or "orphan"))),
version = "" .. addon.version,
@@ -1506,7 +1533,8 @@ local function lpm_addon_list(type, id)
organization = addon.organization,
repository = repo and repo:url(),
path = addon:get_path(system_bottle)
- })
+ }
+ if addon_matches_filter(hash, filters) then table.insert(result[plural], hash) end
end
if JSON then
io.stdout:write(json.encode(result) .. "\n")
@@ -1610,13 +1638,13 @@ local function run_command(ARGS)
elseif (ARGS[2] == "plugin" or ARGS[2] == "color" or ARGS[2] == "library") and ARGS[3] == "install" then lpm_install(ARGS[2], table.unpack(common.slice(ARGS, 4)))
elseif (ARGS[2] == "plugin" or ARGS[2] == "color" or ARGS[2] == "library") and ARGS[3] == "uninstall" then lpm_addon_uninstall(ARGS[2], table.unpack(common.slice(ARGS, 4)))
elseif (ARGS[2] == "plugin" or ARGS[2] == "color" or ARGS[2] == "library") and ARGS[3] == "reinstall" then lpm_addon_reinstall(ARGS[2], table.unpack(common.slice(ARGS, 4)))
- elseif (ARGS[2] == "plugin" or ARGS[2] == "color" or ARGS[2] == "library") and (#ARGS == 2 or ARGS[3] == "list") then return lpm_addon_list(ARGS[2], table.unpack(common.slice(ARGS, 4)))
+ elseif (ARGS[2] == "plugin" or ARGS[2] == "color" or ARGS[2] == "library") and (#ARGS == 2 or ARGS[3] == "list") then return lpm_addon_list(ARGS[2], ARGS[3], ARGS)
elseif ARGS[2] == "upgrade" then return lpm_addon_upgrade(table.unpack(common.slice(ARGS, 3)))
elseif ARGS[2] == "install" then lpm_install(nil, table.unpack(common.slice(ARGS, 3)))
elseif ARGS[2] == "uninstall" then lpm_addon_uninstall(nil, table.unpack(common.slice(ARGS, 3)))
elseif ARGS[2] == "reinstall" then lpm_addon_reinstall(nil, table.unpack(common.slice(ARGS, 3)))
elseif ARGS[2] == "describe" then lpm_describe(nil, table.unpack(common.slice(ARGS, 3)))
- elseif ARGS[2] == "list" then return lpm_addon_list(nil, table.unpack(common.slice(ARGS, 3)))
+ elseif ARGS[2] == "list" then return lpm_addon_list(nil, ARGS[3], ARGS)
elseif ARGS[2] == "lite-xl" and (#ARGS == 2 or ARGS[3] == "list") then return lpm_lite_xl_list(table.unpack(common.slice(ARGS, 4)))
elseif ARGS[2] == "lite-xl" and ARGS[3] == "uninstall" then return lpm_lite_xl_uninstall(table.unpack(common.slice(ARGS, 4)))
elseif ARGS[2] == "lite-xl" and ARGS[3] == "install" then return lpm_lite_xl_install(table.unpack(common.slice(ARGS, 4)))
@@ -1639,7 +1667,10 @@ xpcall(function()
json = "flag", userdir = "string", cachedir = "string", version = "flag", verbose = "flag",
quiet = "flag", version = "flag", ["mod-version"] = "string", remotes = "flag", help = "flag",
remotes = "flag", ["ssl-certs"] = "string", force = "flag", arch = "string", ["assume-yes"] = "flag",
- ["install-optional"] = "flag", datadir = "string", binary = "string", trace = "flag"
+ ["install-optional"] = "flag", datadir = "string", binary = "string", trace = "flag",
+ -- filtration flags
+ author = "string", tag = "string", stub = "string", dependency = "string", status = "string",
+ type = "string", name = "string"
})
if ARGS["version"] then
io.stdout:write(VERSION .. "\n")
@@ -1712,9 +1743,10 @@ It has the following commands:
lpm [lite-xl] switch <version> [<path>] Sets the active version of lite-xl
to be the specified version. Auto-detects
current install of lite-xl; if none found
- path can be specifeid.
- lpm lite-xl list Lists all installed versions of
- lite-xl.
+ path can be specified.
+ lpm lite-xl list [name pattern] Lists all installed versions of
+ [...filters] lite-xl. Can specify the flags listed
+ in the filtering seciton.
lpm run <version> [...addons] Sets up a "bottle" to run the specified
lite version, with the specified addons
and then opens it.
@@ -1731,6 +1763,7 @@ It has the following commands:
an interactive print-eval loop.
lpm help Displays this help text.
+
Flags have the following effects:
--json Performs all communication in JSON.
@@ -1744,7 +1777,7 @@ Flags have the following effects:
--verbose Spits out more information, including intermediate
steps to install and whatnot.
--quiet Outputs nothing but explicit responses.
- --mod-version Sets the mod version of lite-xl to install addons.
+ --mod-version=version Sets the mod version of lite-xl to install addons.
--version Returns version information.
--help Displays this help text.
--ssl-certs Sets the SSL certificate store. Can be a directory,
@@ -1758,6 +1791,20 @@ Flags have the following effects:
particular information relating to SSL connections,
and other network activity.
+The following flags are useful when listing plugins, or generating the plugin
+table. Putting a ! infront of the string will invert the filter. Multiple
+filters of the same type can be specified to create an OR relationship.
+
+ --author=author Only display addons by the specified author.
+ --tag=tag Only display addons with the specified tag.
+ --stub=git/file/false Only display the specified stubs.
+ --dependency=dep Only display addons that have a dependency on the
+ specified addon.
+ --status=status Only display addons that have the specified status.
+ --type=type Only display addons on the specified type.
+ --name=name Only display addons that have a name which matches the
+ specified filter.
+
There also several flags which are classified as "risky", and are never enabled
in any circumstance unless explicitly supplied.
@@ -1770,6 +1817,18 @@ in any circumstance unless explicitly supplied.
repository to the end of the resolution list.
--ssl-certs=noverify Ignores SSL certificate validation. Opens you up to
man-in-the-middle attacks.
+
+There exist also other debug commands that are potentially useful, but are
+not commonly used publically.
+
+ lpm test [test file] Runs the specified test suite.
+ lpm table <manifest> [...filters] Generates markdown table for the given
+ manifest. Used by repositories to build
+ READMEs.
+ lpm download <url> [target] Downloads the specified URL to stdout,
+ or to the specified target file.
+ lpm extract <file.[tar.gz|zip]> Extracts the specified archive at
+ [target] target, or the current working directory.
]]
)
return 0
@@ -1880,7 +1939,8 @@ in any circumstance unless explicitly supplied.
end
if ARGS[2] == "table" then
local info = json.decode(common.read(ARGS[3]))
- local addons = info["addons"] or info["plugins"]
+ local addons = common.grep(info["addons"] or info["plugins"], function(addon) return addon_matches_filter(addon, ARGS) end)
+ if #addons == 0 then return end
table.sort(addons, function(a,b) return string.lower(a.name or a.id) < string.lower(b.name or b.id) end)
local ids = common.map(addons, function(addon)
if addon.path and addon.path:find(".lua$") then return string.format("[`%s`](%s?raw=1)", addon.name or addon.id, addon.path) end