diff options
| author | ruki <[email protected]> | 2026-08-01 08:53:30 +0800 |
|---|---|---|
| committer | ruki <[email protected]> | 2026-08-01 08:53:30 +0800 |
| commit | 8d7a74306556a4c292c0345f1a9aa833116ebcec (patch) | |
| tree | 49b0b3ae14157a3f24193623d6adb69e282675e9 | |
| parent | f91724eb1d7f80e81772ad6f20b03b2a0cff8125 (diff) | |
improve tests
| -rw-r--r-- | tests/plugins/repository/test.lua | 135 | ||||
| -rw-r--r-- | xmake/plugins/plugin/main.lua | 26 | ||||
| -rw-r--r-- | xmake/plugins/plugin/xmake.lua | 12 |
3 files changed, 90 insertions, 83 deletions
diff --git a/tests/plugins/repository/test.lua b/tests/plugins/repository/test.lua index 4f1347317..f1cfba8c7 100644 --- a/tests/plugins/repository/test.lua +++ b/tests/plugins/repository/test.lua @@ -1,88 +1,105 @@ import("core.base.global") -function _write_plugin(dir, name, text) +-- write a minimal plugin that prints its name when run +function _write_plugin(dir, name) io.writefile(path.join(dir, "xmake.lua"), string.format([[ task("%s") set_category("plugin") on_run("main") - set_menu {usage = "xmake %s"} -]], name, name)) - io.writefile(path.join(dir, "main.lua"), string.format([[function main() print("%s") end]], text)) + set_menu {usage = "xmake %s", description = "say hello from %s"} +]], name, name, name)) + io.writefile(path.join(dir, "main.lua"), string.format([[function main() print("%s") end]], name)) end -function main(t) +-- create a temporary plugin repository (packages layout: plugins/<first-letter>/<name>) and register it +-- +-- @return reponame, names, cleanup +function _mock_repo(basenames) local suffix = path.filename(os.tmpfile()):gsub("[^%w]", "") - local reponame = "plugin-test-repository-" .. suffix - local hello_name = "plugin-test-hello-" .. suffix - local formatter_name = "plugin-test-formatter-" .. suffix - local available_name = "plugin-test-available-" .. suffix - local local_name = "plugin-test-local-" .. suffix - local repodir = os.tmpfile() .. ".plugins-repository" - local localdir = path.join(os.tmpfile() .. ".local-plugin", local_name) - local plugindir = path.join(global.directory(), "plugins") + local reponame = "plugin-test-repo-" .. suffix + local repodir = os.tmpfile() .. ".plugin-repo" + local names = {} + for _, base in ipairs(basenames) do + local name = base .. "-" .. suffix + _write_plugin(path.join(repodir, "plugins", name:sub(1, 1), name), name) + table.insert(names, name) + end + + -- register the repository into the cache local cachefile = path.join(global.cachedir(), "repository") + local cache = os.isfile(cachefile) and io.load(cachefile) or {} + cache.repositories = cache.repositories or {} + cache.repositories[reponame] = {repodir} + io.save(cachefile, cache) - -- reset test state local function cleanup() - for _, name in ipairs({hello_name, formatter_name, available_name, local_name}) do - os.tryrm(path.join(plugindir, name)) + for _, name in ipairs(names) do + os.tryrm(path.join(global.directory(), "plugins", name)) end local cache = os.isfile(cachefile) and io.load(cachefile) or {} - cache.repositories = cache.repositories or {} - cache.repositories[reponame] = nil + if cache.repositories then + cache.repositories[reponame] = nil + end io.save(cachefile, cache) os.tryrm(repodir) - os.tryrm(path.directory(localdir)) end - cleanup() + return reponame, names, cleanup +end - -- mock repository with installed and available plugins (packages-like layout: plugins/<first-letter>/<name>) - _write_plugin(path.join(repodir, "plugins", hello_name:sub(1, 1), hello_name), hello_name, "repo-ok") - _write_plugin(path.join(repodir, "plugins", formatter_name:sub(1, 1), formatter_name), formatter_name, "format-ok") - _write_plugin(path.join(repodir, "plugins", available_name:sub(1, 1), available_name), available_name, "available-ok") - os.mkdir(path.directory(cachefile)) - local cache = os.isfile(cachefile) and io.load(cachefile) or {} - cache.repositories = cache.repositories or {} - cache.repositories[reponame] = {repodir} - io.save(cachefile, cache) +-- install a plugin from a repository, by plain name and by repo@name +function test_install_from_repo(t) + local reponame, names, cleanup = _mock_repo({"hello"}) + local name = names[1] - -- Feature: install by plain name from repository - os.runv("xmake", {"plugin", "--install", hello_name}) - os.runv("xmake", {hello_name}) + -- install by plain name (searched across all repositories) + os.runv("xmake", {"plugin", "--install", name}) + t:require(os.iorunv("xmake", {name}):find(name, 1, true)) - -- Feature: install by repo@name format - os.runv("xmake", {"plugin", "--install", reponame .. "@" .. formatter_name}) - os.runv("xmake", {formatter_name}) + -- reinstall by repo@name + os.runv("xmake", {"plugin", "--remove", name}) + os.runv("xmake", {"plugin", "--install", reponame .. "@" .. name}) + t:require(os.iorunv("xmake", {name}):find(name, 1, true)) - -- Feature: --list shows installed and available repository plugins - local out = os.iorun("xmake plugin --list") - t:require(out:find("the built-in plugins:", 1, true)) - t:require(out:find("project", 1, true)) - t:require(out:find(hello_name, 1, true)) - t:require(out:find(formatter_name, 1, true)) - t:require(out:find(available_name, 1, true)) - t:require(out:find("xmake plugin --install " .. available_name, 1, true)) + os.runv("xmake", {"plugin", "--remove", name}) + cleanup() +end + +-- install a plugin from a local directory, then remove it +function test_install_from_local(t) + local suffix = path.filename(os.tmpfile()):gsub("[^%w]", "") + local name = "hello-local-" .. suffix + local dir = path.join(os.tmpfile() .. ".plugin-local", name) + _write_plugin(dir, name) - -- Feature: install from local directory - _write_plugin(localdir, local_name, "local-ok") - os.runv("xmake", {"plugin", "--install", localdir}) - os.runv("xmake", {local_name}) + os.runv("xmake", {"plugin", "--install", dir}) + t:require(os.iorunv("xmake", {name}):find(name, 1, true)) - out = os.iorun("xmake plugin --list") - t:require(out:find(local_name, 1, true)) + -- the removed plugin should no longer be runnable + os.runv("xmake", {"plugin", "--remove", name}) + t:require_not(try { function () os.runv("xmake", {name}); return true end }) - -- Feature: remove plugin - os.runv("xmake", {"plugin", "--remove", local_name}) - out = os.iorun("xmake plugin --list") - t:require_not(out:find(local_name, 1, true)) + os.tryrm(path.directory(dir)) +end - -- Feature: install non-existent plugin fails gracefully - local ok = try { function () os.runv("xmake", {"plugin", "--install", "plugin-test-missing-" .. suffix}) return true end } - t:require_not(ok) +-- --list shows the built-in, installed and available plugins +function test_list(t) + local reponame, names, cleanup = _mock_repo({"hello", "world"}) - -- Feature: reject plugin name traversal - ok = try { function () os.runv("xmake", {"plugin", "--install", reponame .. "@.."}) return true end } - t:require_not(ok) + -- install the first plugin, leave the second only available + os.runv("xmake", {"plugin", "--install", names[1]}) + local out = os.iorunv("xmake", {"plugin", "--list"}) + t:require(out:find("the built-in plugins:", 1, true)) + t:require(out:find("project", 1, true)) + t:require(out:find(names[1], 1, true)) + t:require(out:find(names[2], 1, true)) + t:require(out:find("xmake plugin --install " .. names[2], 1, true)) + os.runv("xmake", {"plugin", "--remove", names[1]}) cleanup() end + +-- invalid installs should fail +function test_install_invalid(t) + t:require_not(try { function () os.runv("xmake", {"plugin", "--install", "plugin-test-missing"}); return true end }) + t:require_not(try { function () os.runv("xmake", {"plugin", "--install", "somerepo@.."}); return true end }) +end diff --git a/xmake/plugins/plugin/main.lua b/xmake/plugins/plugin/main.lua index 48bae9cde..5158352c0 100644 --- a/xmake/plugins/plugin/main.lua +++ b/xmake/plugins/plugin/main.lua @@ -74,17 +74,17 @@ function _install_plugins_from_repo(name, reponame) raise("plugin(%s): not found in any repository! try ${bright}xrepo update-repo${clear} first.", name) end --- install a plugin from a local directory -function _install_from_local(dir) +-- install a single plugin from a source directory (as the given name, default to the directory name) +function _install_from_local(dir, name) assert(os.isdir(dir) and os.isfile(path.join(dir, "xmake.lua")), "plugin path(%s): ${bright}xmake.lua${clear} not found!", dir) - local name = path.filename(path.absolute(dir)) + name = name or path.filename(path.absolute(dir)) local dstdir = _get_plugindir(name) assert(not os.isdir(dstdir), "plugin(%s) already exists!", name) os.vcp(dir, dstdir) - cprint("${color.success}install ${bright}%s${clear} from ${bright}%s${clear} ok!", name, dir) + cprint("${color.success}install ${bright}%s${clear} ok!", name) end --- install a plugin from a git url or github shortcut +-- install a single plugin from a git url or github shortcut, e.g. https://github.com/xmake-io/hello-world function _install_from_git(url) local branch if url:startswith("github:") then @@ -95,9 +95,11 @@ function _install_from_git(url) end url = git.asgiturl(url) end + local name = (path.filename(url):gsub("%.git$", "")) local tmpdir = os.tmpfile() .. ".dir" git.clone(url, {verbose = option.get("verbose"), branch = branch, outputdir = tmpdir}) - _copy_plugins_from_dir(tmpdir) + os.tryrm(path.join(tmpdir, ".git")) + _install_from_local(tmpdir, name) os.tryrm(tmpdir) end @@ -131,18 +133,6 @@ function _install_one(name) _install_plugins_from_repo(name) end --- copy every plugin found under the cloned directory into the plugins directory -function _copy_plugins_from_dir(tmpdir) - for _, filepath in ipairs(os.files(path.join(tmpdir, "*", "xmake.lua"))) do - local srcdir = path.directory(filepath) - local name = path.filename(srcdir) - local dstdir = _get_plugindir(name) - assert(not os.isdir(dstdir), "plugin(%s) already exists!", name) - os.vcp(srcdir, dstdir) - cprint(" ${color.success}-> ${bright}%s${clear}", name) - end -end - -- install plugins function _install() local names = assert(option.get("plugins"), "please specify the plugins to be installed!") diff --git a/xmake/plugins/plugin/xmake.lua b/xmake/plugins/plugin/xmake.lua index 8da06a92e..4aab3daa4 100644 --- a/xmake/plugins/plugin/xmake.lua +++ b/xmake/plugins/plugin/xmake.lua @@ -31,13 +31,13 @@ task("plugin") {'c', "clear", "k", nil, "Clear all installed plugins."}, {nil, "plugins", "vs", nil, "The plugin paths, urls or names.", "e.g.", - " $ xmake plugin --install https://github.com/xmake-io/xmake-plugins", - " $ xmake plugin --install github:xmake-io/xmake-plugins", - " $ xmake plugin --install github:xmake-io/xmake-plugins#dev", + " $ xmake plugin --install https://github.com/myrepo/hello", + " $ xmake plugin --install github:myrepo/hello", + " $ xmake plugin --install github:myrepo/hello#dev", " $ xmake plugin --install /tmp/my-plugin", - " $ xmake plugin --install xmake-repo@hello-world", - " $ xmake plugin --install hello-world", - " $ xmake plugin --remove hello-world", + " $ xmake plugin --install xmake-repo@hello", + " $ xmake plugin --install hello", + " $ xmake plugin --remove hello", " $ xmake plugin --list"} } } |
