17 sparse, |
17 sparse, |
18 util, |
18 util, |
19 ) |
19 ) |
20 |
20 |
21 FILENAME = 'narrowspec' |
21 FILENAME = 'narrowspec' |
|
22 |
|
23 # Pattern prefixes that are allowed in narrow patterns. This list MUST |
|
24 # only contain patterns that are fast and safe to evaluate. Keep in mind |
|
25 # that patterns are supplied by clients and executed on remote servers |
|
26 # as part of wire protocol commands. |
|
27 VALID_PREFIXES = ( |
|
28 b'path:', |
|
29 b'rootfilesin:', |
|
30 ) |
22 |
31 |
23 def parseserverpatterns(text): |
32 def parseserverpatterns(text): |
24 """Parses the narrowspec format that's returned by the server.""" |
33 """Parses the narrowspec format that's returned by the server.""" |
25 includepats = set() |
34 includepats = set() |
26 excludepats = set() |
35 excludepats = set() |
80 """ |
89 """ |
81 kind, pat = matchmod._patsplit(pattern, defaultkind) |
90 kind, pat = matchmod._patsplit(pattern, defaultkind) |
82 return '%s:%s' % normalizesplitpattern(kind, pat) |
91 return '%s:%s' % normalizesplitpattern(kind, pat) |
83 |
92 |
84 def parsepatterns(pats): |
93 def parsepatterns(pats): |
85 """Parses a list of patterns into a typed pattern set.""" |
94 """Parses an iterable of patterns into a typed pattern set. |
86 return set(normalizepattern(p) for p in pats) |
95 |
|
96 Patterns are assumed to be ``path:`` if no prefix is present. |
|
97 For safety and performance reasons, only some prefixes are allowed. |
|
98 See ``validatepatterns()``. |
|
99 |
|
100 This function should be used on patterns that come from the user to |
|
101 normalize and validate them to the internal data structure used for |
|
102 representing patterns. |
|
103 """ |
|
104 res = {normalizepattern(orig) for orig in pats} |
|
105 validatepatterns(res) |
|
106 return res |
|
107 |
|
108 def validatepatterns(pats): |
|
109 """Validate that patterns are in the expected data structure and format. |
|
110 |
|
111 And that is a set of normalized patterns beginning with ``path:`` or |
|
112 ``rootfilesin:``. |
|
113 |
|
114 This function should be used to validate internal data structures |
|
115 and patterns that are loaded from sources that use the internal, |
|
116 prefixed pattern representation (but can't necessarily be fully trusted). |
|
117 """ |
|
118 if not isinstance(pats, set): |
|
119 raise error.ProgrammingError('narrow patterns should be a set; ' |
|
120 'got %r' % pats) |
|
121 |
|
122 for pat in pats: |
|
123 if not pat.startswith(VALID_PREFIXES): |
|
124 # Use a Mercurial exception because this can happen due to user |
|
125 # bugs (e.g. manually updating spec file). |
|
126 raise error.Abort(_('invalid prefix on narrow pattern: %s') % pat, |
|
127 hint=_('narrow patterns must begin with one of ' |
|
128 'the following: %s') % |
|
129 ', '.join(VALID_PREFIXES)) |
87 |
130 |
88 def format(includes, excludes): |
131 def format(includes, excludes): |
89 output = '[include]\n' |
132 output = '[include]\n' |
90 for i in sorted(includes - excludes): |
133 for i in sorted(includes - excludes): |
91 output += i + '\n' |
134 output += i + '\n' |