diff options
author | Daniel Silverstone <dsilvers@digital-scurf.org> | 2013-05-23 22:44:27 +0100 |
---|---|---|
committer | Daniel Silverstone <dsilvers@digital-scurf.org> | 2013-05-23 22:44:27 +0100 |
commit | ed4297e2479d2712237efe28874f6be822224d8c (patch) | |
tree | 59d45afa6bc50da878f92eeb8df8106ad88f958e | |
parent | ca95775ad1bf14088333b86677525cecb62f0aef (diff) | |
parent | d7f61fb014c80b2398d0ad58ba60ecc03e08ef9e (diff) | |
download | gitano-ed4297e2479d2712237efe28874f6be822224d8c.tar.gz |
Merge branch 'dsilvers/revamp-patterns'
Reviewed-By: Richard Maw <richard.maw@gmail.com>
-rw-r--r-- | lib/gitano/lace.lua | 90 | ||||
-rw-r--r-- | skel/gitano-admin/rules/adminchecks.lace | 4 | ||||
-rw-r--r-- | skel/gitano-admin/rules/createrepo.lace | 2 | ||||
-rw-r--r-- | skel/gitano-admin/rules/defines.lace | 2 |
4 files changed, 65 insertions, 33 deletions
diff --git a/lib/gitano/lace.lua b/lib/gitano/lace.lua index 517c476..97ed91b 100644 --- a/lib/gitano/lace.lua +++ b/lib/gitano/lace.lua @@ -9,6 +9,8 @@ local util = require 'gitano.util' local gall = require 'gall' local log = require 'gitano.log' +local pcre = require "rex_pcre" + local function _loader(ctx, _name) local global_name = _name:match("^global:(.+)$") local name, tree, sha = global_name or _name @@ -44,49 +46,55 @@ local function _loader(ctx, _name) return real_name, tree[blob_name].obj.content end -local matchers = {} +local match_types = { + exact = function(want, have) + return want == have + end, + prefix = function(want, have) + return have:sub(1, #want) == want + end, + suffix = function(want, have) + return have:sub(-#want) == want + end, + pattern = function(want, have) + return (have:match(want) ~= nil) + end, + pcre = function(want, have) + return (pcre.match(have, want) ~= nil) + end +} -local function _do_simple_match(ctx, key, value) - value = util.process_expansion(ctx, value) - local sigil, value = value:match("^(.)(.*)$") - local inv = false - if sigil == "!" then - inv = true - elseif sigil ~= "=" then - value = sigil .. value +do + local inverted_matches = {} + for k, v in pairs(match_types) do + inverted_matches["!" .. k] = function(...) return not v(...) end end - local pat = value:match("^%~(.+)$") - local kk = ctx[key] or "" - local function check(v) - if pat then - if inv then - return (v:match(pat) == nil) - else - return (v:match(pat) ~= nil) - end - end - if inv then - return v ~= value - end - return v == value + for k, v in pairs(inverted_matches) do + match_types[k] = v end +end + +local function _do_simple_match(ctx, key, matchtype, value) + value = util.process_expansion(ctx, value) + local kk = ctx[key] or "" + local check = match_types[matchtype] if type(kk) == "function" then -- Realise the value first ctx[key] = kk(ctx) kk = ctx[key] end if type(kk) == "string" then - return check(kk) + return check(value, kk) else if pat and kk[1] ~= nil then for i = 1, #kk do - if check(kk[i]) then + if check(value, kk[i]) then return true end end return false else - if inv then + if matchtype:sub(1,1) == "!" then return kk[value] == nil end return kk[value] ~= nil @@ -94,13 +102,35 @@ local function _do_simple_match(ctx, key, value) end end -local function _simple_match(ctx, key, value, guard) +local function _simple_match(ctx, key, matchtype, value, guard) if guard ~= nil then - return lace.compiler.error("Unexpected additional argument", {3}) + return lace.compiler.error("Unexpected additional argument", {4}) + end + if value == nil then + matchtype, value = "", matchtype + local sigil, _value = value:match("^(.)(.*)$") + if sigil == "!" then + inv = true + matchtype = "!" + value = _value + end + sigil, _value = value:match("^(.)(.*)$") + if sigil == "=" then + matchtype = matchtype .. "exact" + value = _value + elseif sigil == "~" then + matchtype = matchtype .. "pattern" + value = _value + else + matchtype = matchtype .. "exact" + end + end + if match_types[matchtype] == nil then + return lace.compiler.error("Unknown match type", {2}) end return { fn = _do_simple_match, - args = { key, util.prep_expansion(value) } + args = { key, matchtype, util.prep_expansion(value) } } end @@ -122,6 +152,8 @@ local simples = { "member/prefix", "member/suffix", } +local matchers = {} + for _, s in ipairs(simples) do matchers[s] = _simple_match end diff --git a/skel/gitano-admin/rules/adminchecks.lace b/skel/gitano-admin/rules/adminchecks.lace index 75ca753..41bb170 100644 --- a/skel/gitano-admin/rules/adminchecks.lace +++ b/skel/gitano-admin/rules/adminchecks.lace @@ -9,8 +9,8 @@ deny "Non-administrators may not delete the admin ref" op_deleteref # By default, you don't want anything but gitano-admin members to touch # anything in the hooks/ tree, so don't allow that -define contains_hooks target_tree ~^hooks/ -define updates_hooks treediff/targets ~^hooks/ +define contains_hooks target_tree prefix hooks/ +define updates_hooks treediff/targets prefix hooks/ deny "Attempt to create hooks" op_createref contains_hooks deny "Attempt to alter hooks" op_is_update updates_hooks diff --git a/skel/gitano-admin/rules/createrepo.lace b/skel/gitano-admin/rules/createrepo.lace index 9085706..6807726 100644 --- a/skel/gitano-admin/rules/createrepo.lace +++ b/skel/gitano-admin/rules/createrepo.lace @@ -5,7 +5,7 @@ # Uncomment the following to allow repositories in personal/username/ -# define repo_is_personal repository ~^personal/${user}/ +# define repo_is_personal repository prefix personal/${user}/ # allow "Personal repo creation is okay" repo_is_personal # Otherwise the default is that non-admins can't create repositories diff --git a/skel/gitano-admin/rules/defines.lace b/skel/gitano-admin/rules/defines.lace index f920948..0d7882a 100644 --- a/skel/gitano-admin/rules/defines.lace +++ b/skel/gitano-admin/rules/defines.lace @@ -68,5 +68,5 @@ define op_is_normal anyof op_fastforward op_createref op_deleteref # Administration define is_admin_repo repository gitano-admin -define is_gitano_ref ref ~^refs/gitano/ +define is_gitano_ref ref prefix refs/gitano/ define is_admin_ref ref refs/gitano/admin |