# HG changeset patch # User Paul Crowley # Date 1303123476 -3600 # Node ID 31c2c6b383fda874ab0f1afdcb768146048c8d16 # Parent f41666a08b873e3dce321b3460d76b51bfee7b75 Refactor ruleset.py so I can be more confident it's correct diff -r f41666a08b87 -r 31c2c6b383fd src/mercurialserver/ruleset.py --- a/src/mercurialserver/ruleset.py Mon Apr 18 11:13:23 2011 +0100 +++ b/src/mercurialserver/ruleset.py Mon Apr 18 11:44:36 2011 +0100 @@ -13,22 +13,24 @@ # ** means "match recursively" ie "ignore directories" return re.compile(p.replace("[^/]*[^/]*", ".*") + "$") -# Returns True for a definite match -# False for a definite non-match -# None where we can't be sure because a key is None +# Returns 1 for a definite match +# -1 for a definite non-match +# 0 where we can't be sure because a key is None +def rmatch(k, m, kw): + if k not in kw: + return -1 + kkw = kw[k] + if kkw is None: + return 0 + elif m.match(kkw) is None: + return -1 + else: + return 1 + def rule(pairs): matchers = [(k, globmatcher(v)) for k, v in pairs] def c(kw): - best = True - for k, m in matchers: - if k not in kw: - return False - kkw = kw[k] - if kkw is None: - best = None - elif m.match(kkw) is None: - return False - return best + return min(rmatch(k, m, kw) for k, m in matchers) return c class Ruleset(object): @@ -41,33 +43,30 @@ self.preset = {} def add(self, action, conditions): - self.rules.append((action, conditions)) + # Unrecognized actions are off the high end + if action in self.levels: + self.rules.append((self.levels.index(action), conditions)) + else: + self.rules.append((len(self.levels), conditions)) def set(self, **kw): self.preset.update(kw) def get(self, k): return self.preset.get(k, None) - - def matchrules(self, kw): + + def allow(self, level, **kw): + levelindex = self.levels.index(level) d = self.preset.copy() d.update(kw) - res = set() for a, c in self.rules: m = c(d) - if m is None: - # "Maybe match" - add it and carry on - res.add(a) - elif m: - # Definite match - add it and stop - res.add(a) - break - return res - - def allow(self, level, **kw): - for a in self.matchrules(kw): - if a in self.levels: - if self.levels.index(a) <= self.levels.index(level): + if m == 1: + # Definite match - what it says goes + return a <= levelindex + elif m == 0: + # "Maybe match" - allow if it says yes, ignore if no + if a <= levelindex: return True return False