diff options
author | Daniel Silverstone <dsilvers@digital-scurf.org> | 2012-08-28 11:27:48 +0100 |
---|---|---|
committer | Daniel Silverstone <dsilvers@digital-scurf.org> | 2012-08-28 11:27:48 +0100 |
commit | a509b61051418af47a439b0325f89f74ddfa70ec (patch) | |
tree | b462ff07c116140a6deb5f09aff8fe7507f82c40 /lib/gitano/command.lua | |
parent | 6d06abc78102f54f6ba1705ae8df89ef3949c212 (diff) | |
download | gitano-a509b61051418af47a439b0325f89f74ddfa70ec.tar.gz |
COMMAND: Add config command, fix up set-head and set-description to use the same lace rules and update example lace
Diffstat (limited to 'lib/gitano/command.lua')
-rw-r--r-- | lib/gitano/command.lua | 188 |
1 files changed, 184 insertions, 4 deletions
diff --git a/lib/gitano/command.lua b/lib/gitano/command.lua index 922672d..b39e83b 100644 --- a/lib/gitano/command.lua +++ b/lib/gitano/command.lua @@ -339,8 +339,9 @@ local function builtin_set_head_validate(conf, repo, cmdline) end local function builtin_set_head_prep(conf, repo, cmdline, context) - context.operation = "sethead" - context.ref = cmdline[3] + context.operation = "config_set" + context.key = "project.head" + context.value = cmdline[3] return repo:run_lace(context) end @@ -384,8 +385,9 @@ local function builtin_set_description_validate(conf, repo, cmdline) end local function builtin_set_description_prep(conf, repo, cmdline, context) - context.operation = "setdescription" - context.description = cmdline[3] + context.operation = "config_set" + context.key = "project.description" + context.value = cmdline[3] return repo:run_lace(context) end @@ -402,6 +404,184 @@ assert(register_cmd("set-description", builtin_set_description_short, builtin_set_description_validate, builtin_set_description_prep, builtin_set_description_run, true, false)) +local builtin_config_short = "View and change configuration for a repository" +local builtin_config_helptext = [[ +usage: config <reponame> <cmd> [args...] + +View and manipulate the configuration of a repository. + +* config <reponame> show [<filter>...] + List all configuration variables in <reponame> which match any of + the filters provided. The filters are prefixes which are matched + against the keys of the configuration variables. + + For example: `config sampler list project` will list all the + project configuration entries for the sampler.git repository. + + Keys which represent lists are shown as `foo.*` If you wish to + show the detailed key, showing the index of the entry in the list + then you should set the filter exactly to `foo.*` which will cause + the show command to expand list keys into the form `foo.i_N` where N + is the index in the list. +* config <reponame> set key value + Set the given configuration key to the given value. If the key ends + in `.*` then the system will add the given value to the end of the + list represented by the key. To replace a specific entry, set the + specific `i_N` entry to the value you want to replace it. +* config <reponame> {del,delete,rm} key + Removes the given key from the configuration set. If the key ends in `.*` + then the system will remove all configuration values below that prefix. + To remove a specific element of a list, instead, be sure to delete + the `i_N` entry instead. +]] +local function builtin_config_validate(conf, repo, cmdline) + if not repo or repo.is_nascent then + log.error("Cannot access configuration of a nascent repository") + return false + end + if #cmdline < 3 then + cmdline[3] = "show" + end + if cmdline[3] == "show" then + -- No validation to do yet + elseif cmdline[3] == "set" then + if #cmdline < 5 then + log.error("config <repo> set: takes a key and a value to set") + return false + end + if #cmdline > 5 then + local cpy = {} + for i = #cmdline, 5, -1 do + table.insert(cpy, 1, cmdline[i]) + cmdline[i] = nil + end + cmdline[5] = table.concat(cpy, " ") + end + elseif cmdline[3] == "del" or cmdline[3] == "delete" or + cmdline[3] == "rm" then + cmdline[3] = "del" + if #cmdline ~= 4 then + log.error("config <repo> del: takes a key and nothing more") + return false + end + if cmdline[4]:match("%.%*$") then + -- Doing a wild removal, expand it now + local prefix = cmdline[4]:match("^(.+)%.%*$") + cmdline[4] = nil + for k in repo.project_config:each(prefix) do + cmdline[#cmdline+1] = k + end + end + else + log.error("Unknown subcommand <" .. cmdline[3] .. "> for config.") + log.info("Valid subcommands are <show> <set> and <del>") + return false + end + return true +end + +local function builtin_config_prep(conf, repo, cmdline, context) + if cmdline[3] == "show" then + context.operation = "config_show" + for i = 4, #cmdline do + local cpy = util.deep_copy(context) + cpy.key = cmdline[i] + local action, reason = repo:run_lace(cpy) + if action ~= "allow" then + return action, reason + end + end + return "allow", "Show not denied" + elseif cmdline[3] == "set" then + context.operation = "config_set" + context.key = cmdline[4] + context.value = cmdline[5] + return repo:run_lace(context) + elseif cmdline[3] == "del" then + context.operation = "config_del" + for i = 4, #cmdline do + local cpy = util.deep_copy(context) + cpy.key = cmdline[i] + local action, reason = repo:run_lace(cpy) + if action ~= "allow" then + return action, reason + end + end + return "allow", "Delete not denied" + end + return "deny", "Unknown sub command slipped through" +end + +local function builtin_config_run(conf, repo, cmdline, env) + if cmdline[3] == "show" then + local all_keys = {} + if #cmdline == 3 then + for k in repo.project_config:each() do + all_keys[k] = true + end + else + for i = 4, #cmdline do + for k in repo.project_config:each(cmdline[i]) do + all_keys[k] = true + end + end + end + -- Transform the all_keys set into a sorted list + local slist = {} + for k in pairs(all_keys) do + slist[#slist+1] = k + end + -- TODO: Fix this sort to cope with .i_N keys neatly + table.sort(slist) + for i = 1, #slist do + local key = slist[i] + local value = repo.project_config.settings[key] + local prefix = key:match("^(.+)%.i_[0-9]+$") + if prefix then + local neatkey = prefix .. ".*" + for i = 4, #cmdline do + if cmdline[i] == neatkey then + neatkey = key + break + end + end + end + log.stdout(key .. ": " .. value) + end + elseif cmdline[3] == "set" then + local key, value = cmdline[4], cmdline[5] + local vtype, rest = value:match("^([sbi]):(.*)$") + if vtype then + if vtype == "s" then + value = rest + end + if vtype == "i" then + value = tonumber(rest) + end + if vtype == "b" then + value = ((rest:lower() == "true") or (rest == "1") or + (rest:lower() == "on") or (rest:lower() == "yes")) + end + end + repo.project_config.settings[key] = value + repo:save_admin() + elseif cmdline[3] == "del" then + for i = 4, #cmdline do + repo.project_config.settings[cmdline[4]] = nil + end + repo:save_admin() + else + log.error("Unknown sub command slipped through") + return "exit", 1 + end + return "exit", 0 +end + +assert(register_cmd("config", builtin_config_short, + builtin_config_helptext, + builtin_config_validate, builtin_config_prep, + builtin_config_run, true, false)) + local builtin_readme_short = "View readme for a repository (if present)" local builtin_readme_helptext = [[ usage: readme <reponame> |