1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
|
import("core.base.global")
-- 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", description = "say hello from %s"}
]], name, name, name))
io.writefile(path.join(dir, "main.lua"), string.format([[function main() print("%s") end]], name))
end
-- write a plugin package description, the plugin sources are placed in its `src` directory
--
-- plugins in a repository are described as packages, e.g. <repodir>/plugins/<first-letter>/<name>/xmake.lua
function _write_plugin_package(dir, name)
io.writefile(path.join(dir, "xmake.lua"), string.format([[
package("%s")
set_kind("plugin")
set_description("say hello from %s")
set_sourcedir(path.join(os.scriptdir(), "src"))
]], name, name))
_write_plugin(path.join(dir, "src"), name)
end
-- 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-repo-" .. suffix
local repodir = os.tmpfile() .. ".plugin-repo"
local names = {}
for _, base in ipairs(basenames) do
local name = base .. "-" .. suffix
_write_plugin_package(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)
local function cleanup()
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 {}
if cache.repositories then
cache.repositories[reponame] = nil
end
io.save(cachefile, cache)
os.tryrm(repodir)
end
return reponame, names, cleanup
end
-- 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]
-- install by plain name (searched across all repositories)
os.runv("xmake", {"plugin", "--install", "-y", name})
t:require(os.iorunv("xmake", {name}):find(name, 1, true))
-- reinstall by repo@name
os.runv("xmake", {"plugin", "--remove", name})
os.runv("xmake", {"plugin", "--install", "-y", reponame .. "@" .. name})
t:require(os.iorunv("xmake", {name}):find(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)
os.runv("xmake", {"plugin", "--install", dir})
t:require(os.iorunv("xmake", {name}):find(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 })
os.tryrm(path.directory(dir))
end
-- --list shows the built-in, installed and available plugins
function test_list(t)
local reponame, names, cleanup = _mock_repo({"hello", "world"})
-- install the first plugin, leave the second only available
os.runv("xmake", {"plugin", "--install", "-y", 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", "-y", "plugin-test-missing"}); return true end })
t:require_not(try { function () os.runv("xmake", {"plugin", "--install", "-y", "somerepo@.."}); return true end })
end
|