summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bin/gitano-post-receive-hook.in3
-rw-r--r--bin/gitano-pre-receive-hook.in3
-rw-r--r--bin/gitano-setup.in9
-rw-r--r--lib/gitano.lua5
-rw-r--r--lib/gitano/actions.lua5
-rw-r--r--lib/gitano/admincommand.lua31
-rw-r--r--lib/gitano/command.lua15
-rw-r--r--lib/gitano/config.lua17
-rw-r--r--lib/gitano/lace.lua3
-rw-r--r--lib/gitano/patterns.lua74
-rw-r--r--lib/gitano/plugins.lua5
-rw-r--r--lib/gitano/repository.lua54
-rw-r--r--lib/gitano/supple.lua3
-rw-r--r--lib/gitano/usercommand.lua5
-rw-r--r--testing/02-commands-user.yarn12
15 files changed, 179 insertions, 65 deletions
diff --git a/bin/gitano-post-receive-hook.in b/bin/gitano-post-receive-hook.in
index 3386e71..cb77e06 100644
--- a/bin/gitano-post-receive-hook.in
+++ b/bin/gitano-post-receive-hook.in
@@ -36,6 +36,7 @@
-- @@GITANO_LUA_PATH
local gitano = require "gitano"
+local pat = gitano.patterns
local gall = require "gall"
local luxio = require "luxio"
local sio = require "luxio.simple"
@@ -113,7 +114,7 @@ end
-- emails, ensuring that new rules are applied, etc)
local updates = {}
-for oldsha, newsha, refname in (sio.stdin:read("*a")):gmatch("([^ ]+) ([^ ]+) ([^\n]+)\n?") do
+for oldsha, newsha, refname in (sio.stdin:read("*a")):gmatch(pat.GITHOOK_PARSE_CHANGESET) do
gitano.log.ddebug("post-receive:", oldsha, newsha, refname)
updates[refname] = {oldsha, newsha, oldsha=oldsha, newsha=newsha}
end
diff --git a/bin/gitano-pre-receive-hook.in b/bin/gitano-pre-receive-hook.in
index c244c47..a81f892 100644
--- a/bin/gitano-pre-receive-hook.in
+++ b/bin/gitano-pre-receive-hook.in
@@ -36,6 +36,7 @@
-- @@GITANO_LUA_PATH
local gitano = require "gitano"
+local pat = gitano.patterns
local gall = require "gall"
local luxio = require "luxio"
local sio = require "luxio.simple"
@@ -116,7 +117,7 @@ end
-- you.
local updates = {}
-for oldsha, newsha, refname in (sio.stdin:read("*a")):gmatch("([^ ]+) ([^ ]+) ([^\n]+)") do
+for oldsha, newsha, refname in (sio.stdin:read("*a")):gmatch(pat.GITHOOK_PARSE_CHANGESET) do
gitano.log.ddebug("pre-receive:", oldsha, newsha, refname)
updates[refname] = {oldsha, newsha, oldsha=oldsha, newsha=newsha}
end
diff --git a/bin/gitano-setup.in b/bin/gitano-setup.in
index 86b2e08..209104d 100644
--- a/bin/gitano-setup.in
+++ b/bin/gitano-setup.in
@@ -36,6 +36,7 @@
-- @@GITANO_LUA_PATH
local gitano = require "gitano"
+local pat = gitano.patterns
local gall = require "gall"
local luxio = require "luxio"
local sio = require "luxio.simple"
@@ -170,8 +171,8 @@ function file_exists(path)
return true
end
-function validate_name(n)
- if not n:match("^[a-z_][a-z0-9_%-]*$") then
+function validate_name(n, pattern)
+ if not n:match(pattern) then
error(gitano.i18n.expand("SETUP_ERROR_INVALID_NAME", { name=n }), 2)
end
end
@@ -214,7 +215,7 @@ ask_for("paths.repos", gitano.i18n.expand("SETUP_PATHS_REPOS_INFO"),
get("paths.home") .. "/repos")
validate_name(ask_for("admin.username", gitano.i18n.expand("SETUP_ADMIN_USERNAME_INFO"),
- "admin"))
+ "admin"), pat.VALID_USERNAME)
ask_for("admin.realname", gitano.i18n.expand("SETUP_ADMIN_REALNAME_INFO"),
"Administrator")
@@ -222,7 +223,7 @@ ask_for("admin.email", gitano.i18n.expand("SETUP_ADMIN_EMAIL_INFO"),
"admin@administrator.local")
validate_name(ask_for("admin.keyname", gitano.i18n.expand("SETUP_ADMIN_KEYNAME_INFO"),
- "default"))
+ "default"), pat.VALID_SSHKEYNAME)
ask_for("site.name", gitano.i18n.expand("SETUP_SITE_NAME_INFO"), "a random Gitano instance")
ask_for("log.prefix", gitano.i18n.expand("SETUP_LOG_PREFIX_INFO"), "gitano")
diff --git a/lib/gitano.lua b/lib/gitano.lua
index 5abf8c8..5354a0f 100644
--- a/lib/gitano.lua
+++ b/lib/gitano.lua
@@ -41,7 +41,11 @@ local supple = require 'gitano.supple'
local auth = require 'gitano.auth'
local plugins = require 'gitano.plugins'
local i18n = require 'gitano.i18n'
+<<<<<<< HEAD
+local patterns = require 'gitano.patterns'
+=======
local hooks = require 'gitano.hooks'
+>>>>>>> dsilvers/hooks
local _VERSION = {1, 1, 0}
_VERSION.major = _VERSION[1]
@@ -69,5 +73,6 @@ return {
auth = auth,
plugins = plugins,
i18n = i18n,
+ patterns = patterns,
hooks = hooks,
}
diff --git a/lib/gitano/actions.lua b/lib/gitano/actions.lua
index 8568d72..dbb5fe1 100644
--- a/lib/gitano/actions.lua
+++ b/lib/gitano/actions.lua
@@ -34,6 +34,7 @@ local util = require "gitano.util"
local log = require "gitano.log"
local gall = require "gall"
local config = require "gitano.config"
+local pat = require "gitano.patterns"
local i18n = require 'gitano.i18n'
local sio = require 'luxio.simple'
local supple = require 'gitano.supple'
@@ -106,9 +107,9 @@ local function _curl_txn(url, headers, body, content_type)
if (how ~= "exit" or why ~= 0) then
return "500", err, {}, ""
end
- local code, msg, _headers, content = response:match("^HTTP/1.[01] (...) ?([^\r\n]+)\r?\n(.-)\r?\n\r?\n(.*)$")
+ local code, msg, _headers, content = response:match(pat.HTTP_RESPONSE)
local headers = {}
- for k, v in _headers:gmatch("([^:\r\n]+): *([^\r\n]+)") do
+ for k, v in _headers:gmatch(pat.HTTP_HEADER) do
local r = headers[k] or {}
r[#r+1] = v
headers[k] = r
diff --git a/lib/gitano/admincommand.lua b/lib/gitano/admincommand.lua
index cb60851..e9f2fdf 100644
--- a/lib/gitano/admincommand.lua
+++ b/lib/gitano/admincommand.lua
@@ -34,6 +34,7 @@ local log = require 'gitano.log'
local util = require 'gitano.util'
local repository = require 'gitano.repository'
local config = require 'gitano.config'
+local pat = require 'gitano.patterns'
local clod = require 'clod'
local luxio = require 'luxio'
local sio = require 'luxio.simple'
@@ -176,7 +177,7 @@ local function builtin_user_validate(conf, _, cmdline)
log.error("user add takes a username, email address and real name")
return false
end
- if cmdline[2] == "add" and not cmdline[3]:match("^[a-z][a-z0-9_.-]+$") then
+ if cmdline[2] == "add" and not cmdline[3]:match(pat.VALID_USERNAME) then
log.error("user name '" .. cmdline[3] .. "' not valid.")
return false
end
@@ -343,6 +344,20 @@ local function builtin_user_run(conf, _, cmdline, env)
log.fatal(commit)
end
log.state("Committed: " .. reason)
+ if cmdline[2] == "rename" then
+ local function reown_repo(_, repo)
+ if repo:conf_get("project.owner") == cmdline[3] then
+ local ok, msg = repo:conf_set_and_save(
+ "project.owner", cmdline[4],
+ env.GITANO_USER, env.GITANO_ORIG_USER)
+ if not ok then
+ log.error(msg)
+ return "exit", 1
+ end
+ end
+ end
+ repository.foreach(conf, reown_repo)
+ end
end
return "exit", 0
end
@@ -406,7 +421,7 @@ local function builtin_group_validate(conf, _, cmdline)
log.error("Add takes a group name and a description")
return false
end
- if cmdline[2] == "add" and not cmdline[3]:match("^[a-z][a-z0-9_.-]+$") then
+ if cmdline[2] == "add" and not cmdline[3]:match(pat.VALID_GROUPNAME) then
log.error("group name '" .. cmdline[3] .. "' not valid.")
return false
end
@@ -739,7 +754,7 @@ local function builtin_keyring_validate(conf, _, cmdline)
if #cmdline > 3 then
local ok = true
for i = 4, #cmdline do
- if not cmdline[i]:match("^" .. string.rep("[0-9A-Fa-f]", 40) .. "$") then
+ if not cmdline[i]:match(pat.VALID_KEY_FINGERPINRT) then
log.error("error: '" .. cmdline[i] .. "' is not a valid fingerprint")
ok = false
end
@@ -750,7 +765,7 @@ local function builtin_keyring_validate(conf, _, cmdline)
end
if cmdline[2] == "delkey" then
if #cmdline == 4 or #cmdline == 5 then
- if not cmdline[4]:match("^" .. string.rep("[0-9A-Fa-f]", 40) .. "$") then
+ if not cmdline[4]:match(pat.VALID_KEY_FINGERPRINT) then
log.error("error: '" .. cmdline[i] .. "' is not a valid fingerprint")
return false
end
@@ -795,7 +810,7 @@ local function builtin_keyring_run(conf, _, cmdline, env)
log.error("Keyring " .. keyringname .. " already exists")
return "exit", 1
end
- if not keyringname:match("^[a-z][a-z0-9_.-]+$") then
+ if not keyringname:match(pat.VALID_KEYRING_NAME) then
log.error("Keyring " .. keyringname .. " is not lower-alphanumeric")
return "exit", 1
end
@@ -867,7 +882,7 @@ local function builtin_keyring_run(conf, _, cmdline, env)
if code ~= 0 then
log.fatal("Unable to list keyring: GPG returned " .. tostring(code))
end
- for fingerprint in alloutput:gmatch("fpr:::::::::([0-9A-F]+):") do
+ for fingerprint in alloutput:gmatch(pat.GPG_OUTPUT_FINGERPRINT_MATCH) do
log.stdout(fingerprint)
end
end
@@ -1149,7 +1164,7 @@ local function builtin_graveyard_run(conf, _, cmdline, env)
repeat
e, i = luxio.readdir(dirp)
if e == 0 then
- if not i.d_name:find("^%.") then
+ if not i.d_name:find(pat.DOTFILE) then
log.stdout(i.d_name)
end
end
@@ -1200,7 +1215,7 @@ local function builtin_graveyard_run(conf, _, cmdline, env)
repeat
e, i = luxio.readdir(dirp)
if e == 0 then
- if not i.d_name:find("^%.") then
+ if not i.d_name:find(pat.DOTFILE) then
if not match or (match == i.d_name) then
to_remove[#to_remove+1] = i.d_name
end
diff --git a/lib/gitano/command.lua b/lib/gitano/command.lua
index f581dc1..3f433ca 100644
--- a/lib/gitano/command.lua
+++ b/lib/gitano/command.lua
@@ -33,6 +33,7 @@
local log = require 'gitano.log'
local util = require 'gitano.util'
local repository = require 'gitano.repository'
+local pattern = require 'gitano.patterns'
local sio = require "luxio.simple"
@@ -241,7 +242,7 @@ local function builtin_help_run(config, repo, cmdline, env)
log.state(cmd.name, do_sep(cmd), desc)
if cmd.helptext then
log.state("")
- for line in (cmd.helptext):gmatch("([^\n]*)\n") do
+ for line in (cmd.helptext):gmatch(pattern.TEXT_LINE) do
log.state("=>", line)
end
end
@@ -453,9 +454,9 @@ local function builtin_config_validate(conf, repo, cmdline)
return false
end
cmdline.orig_key = cmdline[4]
- if cmdline[4]:match("%.%*$") then
+ if cmdline[4]:match(pattern.CONF_ENDS_WILDCARD) then
-- Doing a wild removal, expand it now
- local prefix = cmdline[4]:match("^(.+)%.%*$")
+ local prefix = cmdline[4]:match(pattern.CONF_WILDCARD)
cmdline[4] = nil
for k in repo.project_config:each(prefix) do
cmdline[#cmdline+1] = k
@@ -525,7 +526,7 @@ local function builtin_config_run(conf, repo, cmdline, env)
for i = 1, #slist do
local key = slist[i]
local value = repo.project_config.settings[key]
- local prefix = key:match("^(.+)%.i_[0-9]+$")
+ local prefix = key:match(pattern.CONF_ARRAY_INDEX)
if prefix then
local neatkey = prefix .. ".*"
for i = 4, #cmdline do
@@ -539,7 +540,7 @@ local function builtin_config_run(conf, repo, cmdline, env)
end
elseif cmdline[3] == "set" then
local key, value = cmdline[4], cmdline[5]
- local vtype, rest = value:match("^([sbi]):(.*)$")
+ local vtype, rest = value:match(pattern.CONF_SET_TYPE_PREFIX)
if vtype then
if vtype == "s" then
value = rest
@@ -839,9 +840,9 @@ local function builtin_ls_run(config, _, cmdline, env)
pat = pat .. ".*"
end
if used_evil then
- pat = "^/" .. pat .. "%.git$"
+ pat = "^/" .. pat .. pattern.GIT_REPO_SUFFIX
else
- pat = "/" .. pat .. "%.git$"
+ pat = "/" .. pat .. pattern.GIT_REPO_SUFFIX
end
log.debug("PAT:", pat)
pats[#pats+1] = pat
diff --git a/lib/gitano/config.lua b/lib/gitano/config.lua
index a582db1..7227866 100644
--- a/lib/gitano/config.lua
+++ b/lib/gitano/config.lua
@@ -38,6 +38,7 @@ local gall = require 'gall'
local log = require 'gitano.log'
local lace = require 'gitano.lace'
local i18n = require 'gitano.i18n'
+local pat = require 'gitano.patterns'
local luxio = require 'luxio'
local sio = require 'luxio.simple'
local clod = require 'clod'
@@ -109,7 +110,7 @@ local function parse_admin_config(commit)
-- Gather the users
local users = {}
for filename, obj in pairs(flat_tree) do
- local prefix, username = filename:match("^(users/.-)([a-z][a-z0-9_.-]+)/user%.conf$")
+ local prefix, username = filename:match(pat.USER_CONF_MATCH)
if prefix and username then
if not is_blob(obj) then
return nil, prefix .. username .. "/user.conf is not a blob?"
@@ -144,7 +145,7 @@ local function parse_admin_config(commit)
-- Now gather the users' keys
local all_keys = {}
for filename, obj in pairs(flat_tree) do
- local prefix, username, keyname = filename:match("^(users/.-)([a-z][a-z0-9_.-]+)/([a-z][a-z0-9_.-]+)%.key$")
+ local prefix, username, keyname = filename:match(pat.USER_KEY_MATCH)
if prefix and username and keyname then
if not users[username] then
return nil, i18n.expand("ERROR_ORPHAN_KEY",
@@ -158,7 +159,7 @@ local function parse_admin_config(commit)
return nil, i18n.expand("ERROR_BAD_KEY_NEWLINES", {filename=filename})
end
- local keytype, keydata, keytag = this_key:match("^([^ ]+) ([^ ]+) ([^ ].*)$")
+ local keytype, keydata, keytag = this_key:match(pat.SSH_KEY_CONTENTS)
if not (keytype and keydata and keytag) then
return nil, i18n.expand("ERROR_BAD_KEY_SMELL", {filename=filename})
end
@@ -190,7 +191,7 @@ local function parse_admin_config(commit)
-- Now gather the groups
local groups = {}
for filename, obj in pairs(flat_tree) do
- local prefix, groupname = filename:match("^(groups/.-)([a-z][a-z0-9_.-]+)%.conf$")
+ local prefix, groupname = filename:match(pat.GROUP_CONF_MATCH)
if prefix and groupname then
if groups[groupname] then
return nil, i18n.expand("ERROR_DUPLICATE_GROUP", {name=groupname})
@@ -269,7 +270,7 @@ local function parse_admin_config(commit)
-- Now gather the keyrings
local keyrings = {}
for filename, obj in pairs(flat_tree) do
- local prefix, keyringname = filename:match("^(keyrings/.-)([a-z][a-z0-9_.-]+)%.gpg$")
+ local prefix, keyringname = filename:match(pat.KEYRING_MATCH)
if prefix and keyringname then
if keyrings[keyringname] then
return nil, i18n.expand("ERROR_DUPLICATE_KEYRING", {name=keyringname})
@@ -440,9 +441,9 @@ local function commit_config_changes(conf, desc, author, committer)
-- Shallow copy the tree ready for mods, skipping keyrings, users and groups
for k,v in pairs(conf.content) do
- if not (k:match("^users/") or
- k:match("^groups/") or
- k:match("^keyrings/")) then
+ if not (k:match(pat.USER_INFO_PREFIX) or
+ k:match(pat.GROUP_INFO_PREFIX) or
+ k:match(pat.KEYRING_INFO_PREFIX)) then
newtree[k] = v
end
end
diff --git a/lib/gitano/lace.lua b/lib/gitano/lace.lua
index 2ba0634..685d625 100644
--- a/lib/gitano/lace.lua
+++ b/lib/gitano/lace.lua
@@ -35,6 +35,7 @@ local util = require 'gitano.util'
local gall = require 'gall'
local log = require 'gitano.log'
local i18n = require 'gitano.i18n'
+local pat = require 'gitano.patterns'
local pcre = require "rex_pcre"
@@ -45,7 +46,7 @@ include global:core
}
local function _loader(ctx, _name)
- local global_name = _name:match("^global:(.+)$")
+ local global_name = _name:match(pat.LACE_GLOBAL_DEFINITION)
local name, tree, sha = global_name or _name
if not global_name then
-- Project load
diff --git a/lib/gitano/patterns.lua b/lib/gitano/patterns.lua
new file mode 100644
index 0000000..e8527a0
--- /dev/null
+++ b/lib/gitano/patterns.lua
@@ -0,0 +1,74 @@
+-- gitano.patterns
+--
+-- Centralised pattern definitions. Not stable ABI.
+--
+-- Copyright 2017 Richard Maw <richard.maw@gmail.com>
+-- All rights reserved.
+--
+-- Redistribution and use in source and binary forms, with or without
+-- modification, are permitted provided that the following conditions
+-- are met:
+-- 1. Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+-- 2. Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in the
+-- documentation and/or other materials provided with the distribution.
+-- 3. Neither the name of the author nor the names of their contributors
+-- may be used to endorse or promote products derived from this software
+-- without specific prior written permission.
+--
+-- THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+-- ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+-- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+-- ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+-- FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+-- DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+-- OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+-- HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+-- LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+-- OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+-- SUCH DAMAGE.
+--
+
+local _NICE_NAME = "[a-z][a-z0-9_.-]+"
+
+local USER_INFO_PREFIX = "^(users/.-)(".. _NICE_NAME .. ")/"
+local GROUP_INFO_PREFIX = "^(groups/.-)(".. _NICE_NAME .. ")"
+local KEYRING_INFO_PREFIX = "^(keyrings/.-)(".. _NICE_NAME .. ")"
+
+local CONF_ENDS_WILDCARD = "%.%*$"
+
+local GIT_REPO_SUFFIX = "%.git$"
+
+return {
+ TEXT_LINE = "([^\n]*)\n",
+ DOTFILE = "^%.",
+ VALID_USERNAME = "^" .. _NICE_NAME .. "$",
+ VALID_SSHKEYNAME = "^" .. _NICE_NAME .. "$",
+ USER_INFO_PREFIX = USER_INFO_PREFIX,
+ USER_CONF_MATCH = USER_INFO_PREFIX .. "user%.conf$",
+ USER_KEY_MATCH = USER_INFO_PREFIX .. "(" .. _NICE_NAME .. ")%.key$",
+ SSH_KEY_CONTENTS = "^([^ ]+) ([^ ]+) ([^ ].*)$",
+ VALID_GROUPNAME = "^" .. _NICE_NAME .. "$",
+ GROUP_INFO_PREFIX = GROUP_INFO_PREFIX,
+ GROUP_CONF_MATCH = GROUP_INFO_PREFIX .. "%.conf$",
+ VALID_KEY_FINGERPRINT = "^" .. string.rep("[0-9A-Fa-f]", 40) .. "$",
+ VALID_KEYRING_NAME = "^" .. _NICE_NAME .. "$",
+ KEYRING_INFO_PREFIX = KEYRING_INFO_PREFIX,
+ KEYRING_MATCH = KEYRING_INFO_PREFIX .. "%.gpg$",
+ GPG_OUTPUT_FINGERPRINT_MATCH = "fpr:::::::::([0-9A-F]+):",
+ HTTP_RESPONSE = "^HTTP/1.[01] (...) ?([^\r\n]+)\r?\n(.-)\r?\n\r?\n(.*)$",
+ HTTP_HEADER = "([^:\r\n]+): *([^\r\n]+)",
+ CONF_ENDS_WILDCARD = CONF_ENDS_WILDCARD,
+ CONF_WILDCARD = "^(.+)" .. CONF_ENDS_WILDCARD,
+ CONF_ARRAY_INDEX = "^(.+)%.i_[0-9]+$",
+ CONF_SET_TYPE_PREFIX = "^([sbi]):(.*)$",
+ GIT_REPO_SUFFIX = GIT_REPO_SUFFIX,
+ GIT_REPO_NAME_MATCH = "^(.+)" .. GIT_REPO_SUFFIX,
+ LACE_GLOBAL_DEFINITION = "^global:(.+)$",
+ PLUGIN_NAME = "^([^_]+)%.lua$",
+ REF_IS_NORMALISED = "^refs/",
+ PARSE_TIME_AND_TZOFFSET = "^([0-9]+) ([+-][0-9]+)$",
+ SUPPLE_MODULE_LOAD_MATCH = "^([^%.]+)%.(.+)$",
+ GITHOOK_PARSE_CHANGESET = "([^ ]+) ([^ ]+) ([^\n]+)\n?",
+}
diff --git a/lib/gitano/plugins.lua b/lib/gitano/plugins.lua
index fd393ef..81546e6 100644
--- a/lib/gitano/plugins.lua
+++ b/lib/gitano/plugins.lua
@@ -33,14 +33,13 @@
local util = require "gitano.util"
local log = require "gitano.log"
local i18n = require "gitano.i18n"
+local pat = require "gitano.patterns"
local luxio = require "luxio"
local sio = require "luxio.simple"
local gfind = string.gfind
-local plugin_name_pattern = "^([^_]+)%.lua$"
-
local function find_plugins(path)
local ret = {}
for _, entry in ipairs(path) do
@@ -50,7 +49,7 @@ local function find_plugins(path)
{dir=entry, reason=err}))
else
for filename, fileinfo in dirp:iterate() do
- local plugin_name = filename:match(plugin_name_pattern)
+ local plugin_name = filename:match(pat.PLUGIN_NAME)
if plugin_name then
if not ret[plugin_name] then
ret[plugin_name] = entry
diff --git a/lib/gitano/repository.lua b/lib/gitano/repository.lua
index b7e2ccc..be6a689 100644
--- a/lib/gitano/repository.lua
+++ b/lib/gitano/repository.lua
@@ -40,6 +40,7 @@ local config = require 'gitano.config'
local util = require 'gitano.util'
local lace = require 'gitano.lace'
local i18n = require 'gitano.i18n'
+local pat = require 'gitano.patterns'
local clod = require 'clod'
local base_rules = [[
@@ -455,8 +456,8 @@ function repo_method:populate_context(context)
if not self.is_nascent then
local lists_to_add = {}
for k, v in self.project_config:each() do
- if k:match("%.i_[0-9]+$") then
- lists_to_add[k:gsub("%.i_[0-9]+$", "")] = true
+ if k:match(pat.CONF_ARRAY_INDEX) then
+ lists_to_add[k:match(pat.CONF_ARRAY_INDEX)] = true
else
local confkey = "config/" .. k:gsub("%.", "/")
context[confkey] = v
@@ -512,7 +513,7 @@ function repo_method:conf_set_and_save(conf, newvalue, author, committer)
end
function repo_method:set_head(newhead, author, committer)
- if not newhead:match("^refs/") then
+ if not newhead:match(pat.REF_IS_NORMALISED) then
newhead = "refs/heads/" .. newhead
end
local oldhead = self:conf_get "project.head"
@@ -568,15 +569,27 @@ function repo_method:destroy_self(call_me)
return true
end
+local function normalise_repo_path(reponame)
+ -- Inject a leading '/'
+ reponame = "/" .. reponame
+ -- Remove any spaces, tabs, newlines or nulls
+ reponame = reponame:gsub("[%s%z]+", "")
+ -- Remove any '.' which follows a '/'
+ reponame = reponame:gsub("/%.+", "/")
+ -- simplify any sequence of '/' to a single '/'
+ reponame = reponame:gsub("/+", "/")
+ -- Remove any leading or trailing /
+ reponame = reponame:match("^/*(.-)/*$")
+ -- Remove trailing .git if present.
+ if reponame:match("."..pat.GIT_REPO_SUFFIX) then
+ reponame = reponame:match(pat.GIT_REPO_NAME_MATCH)
+ end
+ return reponame
+end
+
function repo_method:rename_to(somename)
-- Same cleanup as in find...
- if somename:match(".%.git$") then
- somename = somename:match("^(.+)%.git$")
- end
- -- Remove any '.'
- somename = somename:gsub("%.", "")
- -- Remove any leading or trailing /
- somename = somename:match("^/*(.-)/*$")
+ somename = normalise_repo_path(somename)
local newpath = self.fs_path({name=somename,config=self.config})
@@ -679,7 +692,7 @@ function repo_method:update_modified_date(shas)
if f then
local s = f:read("*l")
if s then
- local cur_mod_time, cur_mod_offset = s:find("^([0-9]+) ([+-][0-9]+)$")
+ local cur_mod_time, cur_mod_offset = s:find(pat.PARSE_TIME_AND_TZOFFSET)
if cur_mod_time then
update_based_on(cur_mod_time, cur_mod_offset)
end
@@ -830,20 +843,7 @@ local function find_repository(config, reponame)
--
-- If the repository exists, then it is examined and brought up-to-date
-- with any global config changes before being returned.
- -- Inject a leading '/'
- reponame = "/" .. reponame
- -- Remove any spaces, tabs, newlines or nulls
- reponame = reponame:gsub("[%s%z]+", "")
- -- Remove any '.' which follows a '/'
- reponame = reponame:gsub("/%.+", "/")
- -- simplify any sequence of '/' to a single '/'
- reponame = reponame:gsub("/+", "/")
- -- Remove any leading or trailing /
- reponame = reponame:match("^/*(.-)/*$")
- -- Remove trailing .git if present.
- if reponame:match(".%.git$") then
- reponame = reponame:match("^(.+)%.git$")
- end
+ reponame = normalise_repo_path(reponame)
-- Construct the repo
local repo = setmetatable({config = config, name = reponame}, repo_meta)
@@ -904,12 +904,12 @@ local function foreach_repository(conf, callback, filterfn)
repeat
e, i = luxio.readdir(dirp)
if e == 0 then
- if i.d_name:find("%.git$") then
+ if i.d_name:match(pat.GIT_REPO_SUFFIX) then
-- Might be a repo, save for later
all_repos[#all_repos+1] = (util.path_join(prefix, i.d_name)
):gsub("^/", "")
else
- if i.d_name:find("^[^%.]") then
+ if not i.d_name:match(pat.DOTFILE) then
recurse[#recurse+1] = i.d_name
end
end
diff --git a/lib/gitano/supple.lua b/lib/gitano/supple.lua
index 79ca3b4..49d62b1 100644
--- a/lib/gitano/supple.lua
+++ b/lib/gitano/supple.lua
@@ -36,6 +36,7 @@ local supple = require 'supple'
local log = require 'gitano.log'
local config = require 'gitano.config'
local i18n = require 'gitano.i18n'
+local pat = require 'gitano.patterns'
local repo_proxies = {}
local proxied_repo = {}
@@ -112,7 +113,7 @@ local function load_repo_module(fromrepo, prefix, module)
end
local function load_module_src(modname)
- local pfx, mod = modname:match("^([^%.]+)%.(.+)$")
+ local pfx, mod = modname:match(pat.SUPPLE_MODULE_LOAD_MATCH)
if not (pfx and mod) then
error(i18n.expand("ERROR_NOT_RIGHT_NAME_FORMAT", {modname=modname}))
end
diff --git a/lib/gitano/usercommand.lua b/lib/gitano/usercommand.lua
index 49f4694..5d3d7ac 100644
--- a/lib/gitano/usercommand.lua
+++ b/lib/gitano/usercommand.lua
@@ -34,6 +34,7 @@ local log = require 'gitano.log'
local util = require 'gitano.util'
local repository = require 'gitano.repository'
local config = require 'gitano.config'
+local pat = require 'gitano.patterns'
local sio = require 'luxio.simple'
local subprocess = require 'luxio.subprocess'
@@ -155,7 +156,7 @@ local function builtin_sshkey_validate(config, _, cmdline)
log.error("sshkey", cmdline[2] .. ": Expected tag and no more")
return false
end
- if not cmdline[3]:match("^[a-z][a-z0-9_-]+$") then
+ if not cmdline[3]:match(pat.VALID_SSHKEYNAME) then
log.error("sshkey:", cmdline[3], "is not a valid tag name.")
log.state("Tag names start with a letter and may contain only letters")
log.state("and numbers, underscores and dashes. Tag names must be at")
@@ -211,7 +212,7 @@ local function builtin_sshkey_run(conf, _, cmdline, env)
end
elseif cmdline[2] == "add" then
local sshkey = sio.stdin:read("*l")
- local keytype, keydata, keytag = sshkey:match("^([^ ]+) ([^ ]+) ([^ ].*)$")
+ local keytype, keydata, keytag = sshkey:match(pat.SSH_KEY_CONTENTS)
if not (keytype and keydata and keytag) then
log.error("Unable to parse key,", filename,
"did not smell like an OpenSSH v2 key")
diff --git a/testing/02-commands-user.yarn b/testing/02-commands-user.yarn
index 54f402b..e372918 100644
--- a/testing/02-commands-user.yarn
+++ b/testing/02-commands-user.yarn
@@ -74,6 +74,18 @@ but it is possible to rename users.
THEN stdout contains ^robert
THEN stdout does not contain ^bob
+In addition, you might want rename a user which owns repositories. When that
+is done, Gitano must re-own the repository in order that rules using the
+project's owner work properly.
+
+ WHEN testinstance adminkey runs create testrepo robert
+ AND testinstance adminkey runs config testrepo show project.owner
+ THEN stdout contains robert
+
+ WHEN testinstance adminkey runs user rename robert bob --force
+ AND testinstance adminkey runs config testrepo show project.owner
+ THEN stdout contains bob
+
FINALLY the instance is torn down
Deleting users