diff options
author | Daniel Silverstone <dsilvers@digital-scurf.org> | 2012-06-29 23:04:44 +0100 |
---|---|---|
committer | Daniel Silverstone <dsilvers@digital-scurf.org> | 2012-06-29 23:04:44 +0100 |
commit | 3b13d8680a57b9761b4cf61903f067ce1b62753b (patch) | |
tree | f1d7d7ba0302647078270efe11b5cc7c15c42ef9 | |
parent | f862a5ee162fa129dc7fd2595011d78a8b8ff109 (diff) | |
download | gitano-3b13d8680a57b9761b4cf61903f067ce1b62753b.tar.gz |
LIB: Create an admin command module and move 'as' into it. Also ensure help distinguishes the admin commands
-rw-r--r-- | lib/gitano/admincommand.lua | 98 | ||||
-rw-r--r-- | lib/gitano/command.lua | 42 | ||||
-rw-r--r-- | lib/gitano/usercommand.lua | 81 |
3 files changed, 132 insertions, 89 deletions
diff --git a/lib/gitano/admincommand.lua b/lib/gitano/admincommand.lua new file mode 100644 index 0000000..3eb8c22 --- /dev/null +++ b/lib/gitano/admincommand.lua @@ -0,0 +1,98 @@ +-- gitano.admincommand +-- +-- Gitano admin-commands +-- +-- Copyright 2012 Daniel Silverstone <dsilvers@digital-scurf.org> + +local log = require 'gitano.log' +local util = require 'gitano.util' +local repository = require 'gitano.repository' +local config = require 'gitano.config' + +local function cmdmod() + return require 'gitano.command' +end + +local builtin_as_short = "Become someone else" +local builtin_as_helptext = [[ +usage: as <user> <cmdline>... + +Runs the given command line as the given user. The only limitation +is that you are not permitted to run 'as' as someone else. +]] + +local function builtin_as_validate(config, _, cmdline) + -- as + if #cmdline < 3 then + log.error("usage: as <user> <cmdline>...") + return false + end + if cmdline[3] == "as" then + log.error("Cannot use 'as' to run 'as'") + return false + end + -- Strip the cmdline + local cmdline_copy = util.deep_copy(cmdline) + table.remove(cmdline_copy,1) + table.remove(cmdline_copy,1) + cmdline.copy = cmdline_copy + -- Attempt to locate the command + local cmd = cmdmod().get(cmdline[3]) + if not cmd then + log.error("Unknown command <" .. cmdline[3] .. ">") + return false + end + cmdline.cmd = cmd + -- If the returned command needs a repo, find it (and save it for later) + local repo + if cmd.takes_repo and #cmdline > 3 then + -- Acquire the repository object for the target repo + local msg + repo, msg = gitano.repository.find(config, cmdline[4]) + if not repo then + gitano.log.critical("Unable to locate repository.") + gitano.log.critical(" * " .. (tostring(msg))) + gitano.log.fatal("Cannot continue") + end + + if repo.is_nascent then + gitano.log.info("Repository " .. repo.name .. " is nascent") + end + cmdline.repo = repo + end + + -- Finally, validate us + return cmd.validate(config, cmdline.repo, cmdline.copy) +end + +local function builtin_as_prep(conf, _, cmdline, context) + -- The context contains the user we are right now. + -- We need to acquire information about that, so ask the config + local as = { user = context.user } + config.populate_context(conf, as) + for k, v in pairs(as) do + context["as_" .. k] = v + end + context.user = cmdline[2] + -- Okay, we're now ready to chain through to the called command + return cmdline.cmd.prep(conf, cmdline.repo, cmdline.copy, context) +end + +local function builtin_as_run(conf, _, cmdline, env) + -- Override some of the environment + env.GITANO_USER = cmdline[2] + env.GITANO_KEYTAG = "<*>" + env.GITANO_PROJECT = (cmdline.repo or {}).name + -- And then simply chain through + return cmdline.cmd.run(conf, cmdline.repo, cmdline.copy, env) +end + +local function register_commands(reg) + assert(reg("as", builtin_as_short, builtin_as_helptext, + builtin_as_validate, builtin_as_prep, builtin_as_run, + false, false, true)) +end + +return { + register = register_commands +} diff --git a/lib/gitano/command.lua b/lib/gitano/command.lua index 27072bf..55f78bc 100644 --- a/lib/gitano/command.lua +++ b/lib/gitano/command.lua @@ -14,7 +14,7 @@ local cmds = {} local function register_cmd(cmdname, short, helptext, validate_fn, prep_fn, run_fn, - takes_repo, hidden) + takes_repo, hidden, is_admin) --[[ log.ddebug("Register command", cmdname) if takes_repo then @@ -32,6 +32,7 @@ local function register_cmd(cmdname, short, helptext, run = run_fn, takes_repo = takes_repo, hidden = hidden, + admin = is_admin, short = short, helptext = helptext } @@ -55,18 +56,25 @@ end local builtin_help_short = "Ask for help" local builtin_help_helptext = [[ -usage: help [cmd] +usage: help [admin|command] Without the command argument, lists all visible commands. With the command argument, provides detailed help about the given command. + +If the command argument is specifically 'admin' then list the +admin commands instead of the normal commands. If it is 'all' then +list all the commands, even the hidden commands. ]] local function builtin_help_validate(config, repo, cmdline) if #cmdline > 2 then - log.error("usage: help [cmd]") + log.error("usage: help [admin|command]") return false end if #cmdline == 2 then + if cmdline[2] == "all" or cmdline[2] == "admin" then + return true + end if not cmds[cmdline[2]] then log.error("Unknown command:", help) return false @@ -80,12 +88,27 @@ local function builtin_help_prep(config, repo, cmdline, context) end local function builtin_help_run(config, repo, cmdline, env) - if #cmdline == 1 then + local function do_want(cmd) + if cmdline[2] == "all" then + return true + end + if cmdline[2] == "admin" then + return cmd.admin + end + return not (cmd.hidden or cmd.admin) + end + local function do_sep(cmd) + local first = cmd.hidden and "-H" or "--" + local second = cmd.admin and "A-" or "--" + return first .. second + end + if #cmdline == 1 or cmdline[2] == "admin" or cmdline[2] == "all" then -- List all commands local maxcmdn = 0 for i = 1, #cmds do local cmd = cmds[cmds[i]] - if not cmd.hidden then + local wanted = do_want(cmd) + if wanted then if #cmd.name > maxcmdn then maxcmdn = #cmd.name end @@ -93,13 +116,14 @@ local function builtin_help_run(config, repo, cmdline, env) end for i = 1, #cmds do local cmd = cmds[cmds[i]] - if not cmd.hidden then + local wanted = do_want(cmd) + if wanted then local gap = (" "):rep(maxcmdn - #cmd.name) local desc = (cmd.short or "No description") if cmd.takes_repo then desc = desc .. " (Takes a repo)" end - log.state(gap .. cmd.name, "--", desc) + log.state(gap .. cmd.name, do_sep(cmd), desc) end end else @@ -108,7 +132,7 @@ local function builtin_help_run(config, repo, cmdline, env) if cmd.takes_repo then desc = desc .. " (Takes a repo)" end - log.state(cmd.name, "--", desc) + log.state(cmd.name, do_sep(cmd), desc) if cmd.helptext then log.state("") for line in (cmd.helptext):gmatch("([^\n]*)\n") do @@ -671,6 +695,8 @@ assert(register_cmd("count-objects", builtin_count_objects_short, local usercmds = require 'gitano.usercommand' usercmds.register(register_cmd) +local admincmds = require 'gitano.admincommand' +admincmds.register(register_cmd) return { register = register_cmd, diff --git a/lib/gitano/usercommand.lua b/lib/gitano/usercommand.lua index d9e1326..55911ca 100644 --- a/lib/gitano/usercommand.lua +++ b/lib/gitano/usercommand.lua @@ -11,84 +11,6 @@ local config = require 'gitano.config' local sio = require 'luxio.simple' -local function cmdmod() - return require 'gitano.command' -end - -local builtin_as_short = "Become someone else" -local builtin_as_helptext = [[ -usage: as <user> <cmdline>... - -Runs the given command line as the given user. The only limitation -is that you are not permitted to run 'as' as someone else. -]] - -local function builtin_as_validate(config, _, cmdline) - -- as - if #cmdline < 3 then - log.error("usage: as <user> <cmdline>...") - return false - end - if cmdline[3] == "as" then - log.error("Cannot use 'as' to run 'as'") - return false - end - -- Strip the cmdline - local cmdline_copy = util.deep_copy(cmdline) - table.remove(cmdline_copy,1) - table.remove(cmdline_copy,1) - cmdline.copy = cmdline_copy - -- Attempt to locate the command - local cmd = cmdmod().get(cmdline[3]) - if not cmd then - log.error("Unknown command <" .. cmdline[3] .. ">") - return false - end - cmdline.cmd = cmd - -- If the returned command needs a repo, find it (and save it for later) - local repo - if cmd.takes_repo and #cmdline > 3 then - -- Acquire the repository object for the target repo - local msg - repo, msg = gitano.repository.find(config, cmdline[4]) - if not repo then - gitano.log.critical("Unable to locate repository.") - gitano.log.critical(" * " .. (tostring(msg))) - gitano.log.fatal("Cannot continue") - end - - if repo.is_nascent then - gitano.log.info("Repository " .. repo.name .. " is nascent") - end - cmdline.repo = repo - end - - -- Finally, validate us - return cmd.validate(config, cmdline.repo, cmdline.copy) -end - -local function builtin_as_prep(conf, _, cmdline, context) - -- The context contains the user we are right now. - -- We need to acquire information about that, so ask the config - local as = { user = context.user } - config.populate_context(conf, as) - for k, v in pairs(as) do - context["as_" .. k] = v - end - context.user = cmdline[2] - -- Okay, we're now ready to chain through to the called command - return cmdline.cmd.prep(conf, cmdline.repo, cmdline.copy, context) -end - -local function builtin_as_run(conf, _, cmdline, env) - -- Override some of the environment - env.GITANO_USER = cmdline[2] - env.GITANO_KEYTAG = "<*>" - env.GITANO_PROJECT = (cmdline.repo or {}).name - -- And then simply chain through - return cmdline.cmd.run(conf, cmdline.repo, cmdline.copy, env) -end - local builtin_whoami_short = "Find out how Gitano identifies you" local builtin_whoami_helptext = [[ @@ -274,9 +196,6 @@ local function builtin_sshkey_run(conf, _, cmdline, env) end local function register_commands(reg) - assert(reg("as", builtin_as_short, builtin_as_helptext, - builtin_as_validate, builtin_as_prep, builtin_as_run, - false, false)) assert(reg("whoami", builtin_whoami_short, builtin_whoami_helptext, builtin_whoami_validate, builtin_whoami_prep, builtin_whoami_run, false, false)) |