OLD | NEW |
1 # Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 # Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 # Use of this source code is governed by a BSD-style license that can be | 2 # Use of this source code is governed by a BSD-style license that can be |
3 # found in the LICENSE file. | 3 # found in the LICENSE file. |
4 | 4 |
5 """Base classes to represent dependency rules, used by checkdeps.py""" | 5 """Base classes to represent dependency rules, used by checkdeps.py""" |
6 | 6 |
7 | 7 |
8 class Rule(object): | 8 class Rule(object): |
9 """Specifies a single rule for an include, which can be one of | 9 """Specifies a single rule for an include, which can be one of |
10 ALLOW, DISALLOW and TEMP_ALLOW. | 10 ALLOW, DISALLOW and TEMP_ALLOW. |
11 """ | 11 """ |
12 | 12 |
13 # These are the prefixes used to indicate each type of rule. These | 13 # These are the prefixes used to indicate each type of rule. These |
14 # are also used as values for self.allow to indicate which type of | 14 # are also used as values for self.allow to indicate which type of |
15 # rule this is. | 15 # rule this is. |
16 ALLOW = "+" | 16 ALLOW = '+' |
17 DISALLOW = "-" | 17 DISALLOW = '-' |
18 TEMP_ALLOW = "!" | 18 TEMP_ALLOW = '!' |
19 | 19 |
20 def __init__(self, allow, directory, source): | 20 def __init__(self, allow, directory, source): |
21 self.allow = allow | 21 self.allow = allow |
22 self._dir = directory | 22 self._dir = directory |
23 self._source = source | 23 self._source = source |
24 | 24 |
25 def __str__(self): | 25 def __str__(self): |
26 return '"%s%s" from %s.' % (self.allow, self._dir, self._source) | 26 return '"%s%s" from %s.' % (self.allow, self._dir, self._source) |
27 | 27 |
28 def ParentOrMatch(self, other): | 28 def ParentOrMatch(self, other): |
29 """Returns true if the input string is an exact match or is a parent | 29 """Returns true if the input string is an exact match or is a parent |
30 of the current rule. For example, the input "foo" would match "foo/bar".""" | 30 of the current rule. For example, the input "foo" would match "foo/bar".""" |
31 return self._dir == other or self._dir.startswith(other + "/") | 31 return self._dir == other or self._dir.startswith(other + '/') |
32 | 32 |
33 def ChildOrMatch(self, other): | 33 def ChildOrMatch(self, other): |
34 """Returns true if the input string would be covered by this rule. For | 34 """Returns true if the input string would be covered by this rule. For |
35 example, the input "foo/bar" would match the rule "foo".""" | 35 example, the input "foo/bar" would match the rule "foo".""" |
36 return self._dir == other or other.startswith(self._dir + "/") | 36 return self._dir == other or other.startswith(self._dir + '/') |
| 37 |
| 38 |
| 39 class SpecificRule(Rule): |
| 40 """A rule that has a specific reason not related to directory or |
| 41 source, for failing. |
| 42 """ |
| 43 |
| 44 def __init__(self, reason): |
| 45 super(SpecificRule, self).__init__(Rule.DISALLOW, '', '') |
| 46 self._reason = reason |
| 47 |
| 48 def __str__(self): |
| 49 return self._reason |
37 | 50 |
38 | 51 |
39 def ParseRuleString(rule_string, source): | 52 def ParseRuleString(rule_string, source): |
40 """Returns a tuple of a boolean indicating whether the directory is an allow | 53 """Returns a tuple of a boolean indicating whether the directory is an allow |
41 rule, and a string holding the directory name. | 54 rule, and a string holding the directory name. |
42 """ | 55 """ |
43 if not rule_string: | 56 if not rule_string: |
44 raise Exception('The rule string "%s" is empty\nin %s' % | 57 raise Exception('The rule string "%s" is empty\nin %s' % |
45 (rule_string, source)) | 58 (rule_string, source)) |
46 | 59 |
(...skipping 20 matching lines...) Expand all Loading... |
67 rule_string: The include_rule string read from the DEPS file to apply. | 80 rule_string: The include_rule string read from the DEPS file to apply. |
68 source: A string representing the location of that string (filename, etc.) | 81 source: A string representing the location of that string (filename, etc.) |
69 so that we can give meaningful errors. | 82 so that we can give meaningful errors. |
70 """ | 83 """ |
71 (add_rule, rule_dir) = ParseRuleString(rule_string, source) | 84 (add_rule, rule_dir) = ParseRuleString(rule_string, source) |
72 # Remove any existing rules or sub-rules that apply. For example, if we're | 85 # Remove any existing rules or sub-rules that apply. For example, if we're |
73 # passed "foo", we should remove "foo", "foo/bar", but not "foobar". | 86 # passed "foo", we should remove "foo", "foo/bar", but not "foobar". |
74 self._rules = [x for x in self._rules if not x.ParentOrMatch(rule_dir)] | 87 self._rules = [x for x in self._rules if not x.ParentOrMatch(rule_dir)] |
75 self._rules.insert(0, Rule(add_rule, rule_dir, source)) | 88 self._rules.insert(0, Rule(add_rule, rule_dir, source)) |
76 | 89 |
77 def DirAllowed(self, allowed_dir): | 90 def RuleApplyingTo(self, allowed_dir): |
78 """Returns a tuple (success, message), where success indicates if the given | 91 """Returns the rule that applies to 'allowed_dir'.""" |
79 directory is allowed given the current set of rules, and the message tells | |
80 why if the comparison failed.""" | |
81 for rule in self._rules: | 92 for rule in self._rules: |
82 if rule.ChildOrMatch(allowed_dir): | 93 if rule.ChildOrMatch(allowed_dir): |
83 # This rule applies. | 94 return rule |
84 why_failed = "" | 95 return SpecificRule('no rule applying.') |
85 if rule.allow != Rule.ALLOW: | |
86 why_failed = str(rule) | |
87 return (rule.allow, why_failed) | |
88 # No rules apply, fail. | |
89 return (Rule.DISALLOW, "no rule applying") | |
OLD | NEW |