summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Silverstone <dsilvers@digital-scurf.org>2013-05-23 22:44:27 +0100
committerDaniel Silverstone <dsilvers@digital-scurf.org>2013-05-23 22:44:27 +0100
commited4297e2479d2712237efe28874f6be822224d8c (patch)
tree59d45afa6bc50da878f92eeb8df8106ad88f958e
parentca95775ad1bf14088333b86677525cecb62f0aef (diff)
parentd7f61fb014c80b2398d0ad58ba60ecc03e08ef9e (diff)
downloadgitano-ed4297e2479d2712237efe28874f6be822224d8c.tar.bz2
Merge branch 'dsilvers/revamp-patterns'
Reviewed-By: Richard Maw <richard.maw@gmail.com>
-rw-r--r--lib/gitano/lace.lua90
-rw-r--r--skel/gitano-admin/rules/adminchecks.lace4
-rw-r--r--skel/gitano-admin/rules/createrepo.lace2
-rw-r--r--skel/gitano-admin/rules/defines.lace2
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