summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorruki <[email protected]>2026-08-15 14:02:04 +0800
committerruki <[email protected]>2026-08-15 14:02:04 +0800
commit9926b3eb72c04382dd91e92d9c44fb03767e859e (patch)
tree7ca1df454aacaad9e3734b1a775d66dafe55453f
parent7cb21509f2a72f00927c4c5c53f3bbb884b8f7a0 (diff)
improve to install addons from repo
-rw-r--r--tests/actions/addon/test.lua10
-rw-r--r--xmake/actions/addon/main.lua59
2 files changed, 38 insertions, 31 deletions
diff --git a/tests/actions/addon/test.lua b/tests/actions/addon/test.lua
index d1e054598..192230b08 100644
--- a/tests/actions/addon/test.lua
+++ b/tests/actions/addon/test.lua
@@ -368,7 +368,8 @@ end
-- the addons can be installed from a repository, by plain name and by repo@name
function test_install_from_repo(t)
- local recipes = {["custom-plugin"] = ("set_sourcedir(%q)"):format(_addondir("custom-plugin"))}
+ local recipes = {["custom-plugin"] = ("set_sourcedir(%q)"):format(_addondir("custom-plugin")),
+ ["custom-module"] = ("set_sourcedir(%q)"):format(_addondir("custom-module"))}
_with_repo(recipes, function (reponame)
os.runv("xmake", {"addon", "--install", "-y", "custom-plugin"})
t:require(os.iorunv("xmake", {"hello_addon"}):find("hello from custom-plugin", 1, true))
@@ -384,6 +385,13 @@ function test_install_from_repo(t)
--
t:require(os.iorunv("xmake", {"addon", "--search", "custom-plugin"}):find("custom-plugin", 1, true))
t:require_not(os.iorunv("xmake", {"lua", "private.xrepo", "search", "custom-plugin"}):find("custom-plugin", 1, true))
+
+ -- and several of them can be installed in one shot, they are resolved and installed together
+ os.runv("xmake", {"addon", "--remove", "--force", "custom-plugin"})
+ os.runv("xmake", {"addon", "--install", "-y", "custom-plugin", reponame .. "@custom-module"})
+ t:require(os.iorunv("xmake", {"hello_addon"}):find("hello from custom-plugin", 1, true))
+ t:require(os.iorunv("xmake", {"lua", "-c", "import(\"@addon.custom-module.greeting\"); print(greeting(\"xmake\"))"})
+ :find("hello from custom-module: xmake", 1, true))
end)
end
diff --git a/xmake/actions/addon/main.lua b/xmake/actions/addon/main.lua
index 7138cb721..aa1edd04e 100644
--- a/xmake/actions/addon/main.lua
+++ b/xmake/actions/addon/main.lua
@@ -45,10 +45,16 @@ function _get_addondir(name, version)
return addondir
end
--- install an addon from the given repository or the first repository containing it
-function _install_from_repo(name, reponame)
- _check_addon_name(name)
- xrepo_addon("install", {reponame and (reponame .. "@" .. name) or name}, {force = option.get("force")})
+-- install the given addons from the repositories which provide them
+--
+-- @note we install them in one shot, xrepo resolves and installs them in parallel
+--
+function _install_from_repo(names)
+ for _, name in ipairs(names) do
+ -- e.g. myrepo@myaddon
+ _check_addon_name(name:split("@", {plain = true, limit = 2})[2] or name)
+ end
+ xrepo_addon("install", names, {force = option.get("force")})
end
-- install a single addon from a source directory (as the given name, default to the directory name)
@@ -82,7 +88,7 @@ function _install_from_local(dir, name)
if manifest then
for _, dep in ipairs(manifest.deps) do
if not addon.addons()[addon.dirname(dep)] then
- _install_from_repo(dep)
+ _install_from_repo({dep})
end
end
end
@@ -158,21 +164,11 @@ function _install_from_git(url)
environment.leave()
end
--- install a single addon
-function _install_one(name)
- -- parse repo@addon format
- local i = name:find("@", 1, true)
- if i and not name:find("[/\\:]") then
- local reponame = name:sub(1, i - 1)
- local addonname = name:sub(i + 1)
- _install_from_repo(addonname, reponame)
- return
- end
-
+-- does the given name come from a repository? e.g. `myaddon`, `myrepo@myaddon`
+function _is_from_repo(name)
-- github shortcut: github:user/repo or github:user/repo#branch
if name:startswith("github:") then
- _install_from_git(name)
- return
+ return false
end
-- local directory
@@ -180,25 +176,28 @@ function _install_one(name)
-- @note we need to check it before the git url, `git.asgiturl` also accepts
-- the local paths with a trailing separator, e.g. `/path/to/myaddon/`
if os.isdir(name) then
- _install_from_local(name)
- return
+ return false
end
-
- -- git url
- if git.asgiturl(name) then
- _install_from_git(name)
- return
- end
-
- -- plain name: try to find it in repositories
- _install_from_repo(name)
+ return not git.asgiturl(name)
end
-- install addons
function _install()
local names = assert(option.get("addons"), "please specify the addons to be installed!")
+
+ -- the addons from the repositories are installed in one shot, the others one by one
+ local requires = {}
for _, name in ipairs(names) do
- _install_one(name)
+ if _is_from_repo(name) then
+ table.insert(requires, name)
+ elseif os.isdir(name) then
+ _install_from_local(name)
+ else
+ _install_from_git(name)
+ end
+ end
+ if #requires > 0 then
+ _install_from_repo(requires)
end
end