diff options
author | Thijs Schreijer <thijs@thijsschreijer.nl> | 2018-07-04 23:15:07 +0200 |
---|---|---|
committer | Hisham Muhammad <hisham@gobolinux.org> | 2018-07-04 18:15:07 -0300 |
commit | 410e3e057d41e08f497c770ce0576072e6b83fe7 (patch) | |
tree | d051850c5cecc874f85ff73136a21790fa41460a | |
parent | dc0c08a4fba646845ec7b00e9a5f24eecec5ff17 (diff) | |
download | luarocks-410e3e057d41e08f497c770ce0576072e6b83fe7.tar.gz luarocks-410e3e057d41e08f497c770ce0576072e6b83fe7.tar.bz2 luarocks-410e3e057d41e08f497c770ce0576072e6b83fe7.zip |
cmd: dynamically load additional external commands
Instead of a fixed list of commands, a dynamic list of modules
residing within the `luarocks.cmd.external.<cmd_name>` in the Lua path
will be dynamically added. This allows extending LuaRocks with
additional commands.
Same for `luarocks.admin.cmd.external.<cmd_name>`.
-rwxr-xr-x | src/bin/luarocks | 5 | ||||
-rwxr-xr-x | src/bin/luarocks-admin | 2 | ||||
-rw-r--r-- | src/luarocks/cmd.lua | 14 | ||||
-rw-r--r-- | src/luarocks/fs/lua.lua | 46 |
4 files changed, 57 insertions, 10 deletions
diff --git a/src/bin/luarocks b/src/bin/luarocks index d0df0532..18a6179b 100755 --- a/src/bin/luarocks +++ b/src/bin/luarocks | |||
@@ -1,8 +1,5 @@ | |||
1 | #!/usr/bin/env lua | 1 | #!/usr/bin/env lua |
2 | 2 | ||
3 | -- this should be loaded first. | ||
4 | local cfg = require("luarocks.core.cfg") | ||
5 | |||
6 | local loader = require("luarocks.loader") | 3 | local loader = require("luarocks.loader") |
7 | local cmd = require("luarocks.cmd") | 4 | local cmd = require("luarocks.cmd") |
8 | 5 | ||
@@ -33,4 +30,4 @@ local commands = { | |||
33 | test = "luarocks.cmd.test", | 30 | test = "luarocks.cmd.test", |
34 | } | 31 | } |
35 | 32 | ||
36 | cmd.run_command(description, commands, ...) | 33 | cmd.run_command(description, commands, "luarocks.cmd.external", ...) |
diff --git a/src/bin/luarocks-admin b/src/bin/luarocks-admin index e27b8c01..77a51872 100755 --- a/src/bin/luarocks-admin +++ b/src/bin/luarocks-admin | |||
@@ -13,4 +13,4 @@ local commands = { | |||
13 | refresh_cache = "luarocks.admin.cmd.refresh_cache", | 13 | refresh_cache = "luarocks.admin.cmd.refresh_cache", |
14 | } | 14 | } |
15 | 15 | ||
16 | cmd.run_command(description, commands, ...) | 16 | cmd.run_command(description, commands, "luarocks.admin.cmd.external", ...) |
diff --git a/src/luarocks/cmd.lua b/src/luarocks/cmd.lua index 4200959c..7a7f9654 100644 --- a/src/luarocks/cmd.lua +++ b/src/luarocks/cmd.lua | |||
@@ -254,12 +254,11 @@ end | |||
254 | -- Parses input arguments and calls the appropriate driver function | 254 | -- Parses input arguments and calls the appropriate driver function |
255 | -- to execute the action requested on the command-line, forwarding | 255 | -- to execute the action requested on the command-line, forwarding |
256 | -- to it any additional arguments passed by the user. | 256 | -- to it any additional arguments passed by the user. |
257 | -- Uses the global table "commands", which contains | ||
258 | -- the loaded modules representing commands. | ||
259 | -- @param program_version string: The program version number as a string. | ||
260 | -- @param description string: Short summary description of the program. | 257 | -- @param description string: Short summary description of the program. |
258 | -- @param commands table: contains the loaded modules representing commands. | ||
259 | -- @param external_namespace string: where to look for external commands. | ||
261 | -- @param ... string: Arguments given on the command-line. | 260 | -- @param ... string: Arguments given on the command-line. |
262 | function cmd.run_command(description, commands, ...) | 261 | function cmd.run_command(description, commands, external_namespace, ...) |
263 | 262 | ||
264 | check_popen() | 263 | check_popen() |
265 | 264 | ||
@@ -377,6 +376,12 @@ function cmd.run_command(description, commands, ...) | |||
377 | os.exit(cmd.errorcodes.OK) | 376 | os.exit(cmd.errorcodes.OK) |
378 | end | 377 | end |
379 | 378 | ||
379 | for _, module_name in ipairs(fs.modules(external_namespace)) do | ||
380 | if not commands[module_name] then | ||
381 | commands[module_name] = external_namespace.."."..module_name | ||
382 | end | ||
383 | end | ||
384 | |||
380 | if flags["verbose"] then | 385 | if flags["verbose"] then |
381 | cfg.verbose = true | 386 | cfg.verbose = true |
382 | fs.verbose() | 387 | fs.verbose() |
@@ -386,7 +391,6 @@ function cmd.run_command(description, commands, ...) | |||
386 | die("Current directory does not exist. Please run LuaRocks from an existing directory.") | 391 | die("Current directory does not exist. Please run LuaRocks from an existing directory.") |
387 | end | 392 | end |
388 | 393 | ||
389 | local ok, err | ||
390 | ok, err = process_tree_flags(flags) | 394 | ok, err = process_tree_flags(flags) |
391 | if not ok then | 395 | if not ok then |
392 | die(err) | 396 | die(err) |
diff --git a/src/luarocks/fs/lua.lua b/src/luarocks/fs/lua.lua index 200a1b0c..373dcbdd 100644 --- a/src/luarocks/fs/lua.lua +++ b/src/luarocks/fs/lua.lua | |||
@@ -166,6 +166,52 @@ function fs_lua.dir(at) | |||
166 | return coroutine.wrap(function() fs.dir_iterator(at) end) | 166 | return coroutine.wrap(function() fs.dir_iterator(at) end) |
167 | end | 167 | end |
168 | 168 | ||
169 | --- List the Lua modules at a specific require path. | ||
170 | -- eg. `modules("luarocks.cmd")` would return a list of all LuaRocks command | ||
171 | -- modules, in the current Lua path. | ||
172 | function fs_lua.modules(at) | ||
173 | at = at or "" | ||
174 | if #at > 0 then | ||
175 | -- turn require path into file path | ||
176 | at = at:gsub("%.", package.config:sub(1,1)) .. package.config:sub(1,1) | ||
177 | end | ||
178 | |||
179 | local path = package.path:sub(-1, -1) == ";" and package.path or package.path .. ";" | ||
180 | local paths = {} | ||
181 | for location in path:gmatch("(.-);") do | ||
182 | if location:lower() == "?.lua" then | ||
183 | location = "./?.lua" | ||
184 | end | ||
185 | local _, q_count = location:gsub("%?", "") -- only use the ones with a single '?' | ||
186 | if location:match("%?%.[lL][uU][aA]$") and q_count == 1 then -- only use when ending with "?.lua" | ||
187 | location = location:gsub("%?%.[lL][uU][aA]$", at) | ||
188 | table.insert(paths, location) | ||
189 | end | ||
190 | end | ||
191 | |||
192 | if #paths == 0 then | ||
193 | return {} | ||
194 | end | ||
195 | |||
196 | local modules = {} | ||
197 | local is_duplicate = {} | ||
198 | for _, path in ipairs(paths) do | ||
199 | local files = fs.list_dir(path) | ||
200 | for _, filename in ipairs(files or {}) do | ||
201 | if filename:match("%.[lL][uU][aA]$") then | ||
202 | filename = filename:sub(1,-5) -- drop the extension | ||
203 | if not is_duplicate[filename] then | ||
204 | is_duplicate[filename] = true | ||
205 | table.insert(modules, filename) | ||
206 | end | ||
207 | end | ||
208 | end | ||
209 | end | ||
210 | |||
211 | return modules | ||
212 | end | ||
213 | |||
214 | |||
169 | --------------------------------------------------------------------- | 215 | --------------------------------------------------------------------- |
170 | -- LuaFileSystem functions | 216 | -- LuaFileSystem functions |
171 | --------------------------------------------------------------------- | 217 | --------------------------------------------------------------------- |