Mercurial > public > mercurial-scm > hg-stable
annotate mercurial/fileset.py @ 14682:8785fd757077
fileset: add grep predicate
author | Matt Mackall <mpm@selenic.com> |
---|---|
date | Sat, 18 Jun 2011 16:53:49 -0500 |
parents | 0744db5eb51c |
children | 281102f37b24 |
rev | line source |
---|---|
14511
30506b894359
filesets: introduce basic fileset expression parser
Matt Mackall <mpm@selenic.com>
parents:
14509
diff
changeset
|
1 # fileset.py - file set queries for mercurial |
11275 | 2 # |
3 # Copyright 2010 Matt Mackall <mpm@selenic.com> | |
4 # | |
5 # This software may be used and distributed according to the terms of the | |
6 # GNU General Public License version 2 or any later version. | |
7 | |
14682
8785fd757077
fileset: add grep predicate
Matt Mackall <mpm@selenic.com>
parents:
14681
diff
changeset
|
8 import parser, error, util, merge, re |
13593
cc4721ed7a2a
help: extract items doc generation function
Patrick Mezard <pmezard@gmail.com>
parents:
13506
diff
changeset
|
9 from i18n import _ |
11275 | 10 |
11 elements = { | |
12 "(": (20, ("group", 1, ")"), ("func", 1, ")")), | |
12616
e797fdf91df4
revset: lower precedence of minus infix (issue2361)
Matt Mackall <mpm@selenic.com>
parents:
12615
diff
changeset
|
13 "-": (5, ("negate", 19), ("minus", 5)), |
11275 | 14 "not": (10, ("not", 10)), |
15 "!": (10, ("not", 10)), | |
16 "and": (5, None, ("and", 5)), | |
17 "&": (5, None, ("and", 5)), | |
18 "or": (4, None, ("or", 4)), | |
19 "|": (4, None, ("or", 4)), | |
20 "+": (4, None, ("or", 4)), | |
21 ",": (2, None, ("list", 2)), | |
22 ")": (0, None, None), | |
23 "symbol": (0, ("symbol",), None), | |
24 "string": (0, ("string",), None), | |
25 "end": (0, None, None), | |
26 } | |
27 | |
28 keywords = set(['and', 'or', 'not']) | |
29 | |
14551
68d814a3cefd
fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents:
14513
diff
changeset
|
30 globchars = ".*{}[]?/\\" |
68d814a3cefd
fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents:
14513
diff
changeset
|
31 |
11275 | 32 def tokenize(program): |
33 pos, l = 0, len(program) | |
34 while pos < l: | |
35 c = program[pos] | |
36 if c.isspace(): # skip inter-token whitespace | |
37 pass | |
14511
30506b894359
filesets: introduce basic fileset expression parser
Matt Mackall <mpm@selenic.com>
parents:
14509
diff
changeset
|
38 elif c in "(),-|&+!": # handle simple operators |
11289
4215ce511134
revset: raise ParseError exceptions
Matt Mackall <mpm@selenic.com>
parents:
11284
diff
changeset
|
39 yield (c, None, pos) |
12408
78a97859b90d
revset: support raw string literals
Brodie Rao <brodie@bitheap.org>
parents:
12401
diff
changeset
|
40 elif (c in '"\'' or c == 'r' and |
78a97859b90d
revset: support raw string literals
Brodie Rao <brodie@bitheap.org>
parents:
12401
diff
changeset
|
41 program[pos:pos + 2] in ("r'", 'r"')): # handle quoted strings |
78a97859b90d
revset: support raw string literals
Brodie Rao <brodie@bitheap.org>
parents:
12401
diff
changeset
|
42 if c == 'r': |
78a97859b90d
revset: support raw string literals
Brodie Rao <brodie@bitheap.org>
parents:
12401
diff
changeset
|
43 pos += 1 |
78a97859b90d
revset: support raw string literals
Brodie Rao <brodie@bitheap.org>
parents:
12401
diff
changeset
|
44 c = program[pos] |
78a97859b90d
revset: support raw string literals
Brodie Rao <brodie@bitheap.org>
parents:
12401
diff
changeset
|
45 decode = lambda x: x |
78a97859b90d
revset: support raw string literals
Brodie Rao <brodie@bitheap.org>
parents:
12401
diff
changeset
|
46 else: |
78a97859b90d
revset: support raw string literals
Brodie Rao <brodie@bitheap.org>
parents:
12401
diff
changeset
|
47 decode = lambda x: x.decode('string-escape') |
11275 | 48 pos += 1 |
49 s = pos | |
50 while pos < l: # find closing quote | |
51 d = program[pos] | |
52 if d == '\\': # skip over escaped characters | |
53 pos += 2 | |
54 continue | |
55 if d == c: | |
12408
78a97859b90d
revset: support raw string literals
Brodie Rao <brodie@bitheap.org>
parents:
12401
diff
changeset
|
56 yield ('string', decode(program[s:pos]), s) |
11275 | 57 break |
58 pos += 1 | |
59 else: | |
11383
de544774ebea
revset: all your error messages are belong to _
Martin Geisler <mg@lazybytes.net>
parents:
11349
diff
changeset
|
60 raise error.ParseError(_("unterminated string"), s) |
14551
68d814a3cefd
fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents:
14513
diff
changeset
|
61 elif c.isalnum() or c in globchars or ord(c) > 127: |
14513 | 62 # gather up a symbol/keyword |
11275 | 63 s = pos |
64 pos += 1 | |
65 while pos < l: # find end of symbol | |
66 d = program[pos] | |
14551
68d814a3cefd
fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents:
14513
diff
changeset
|
67 if not (d.isalnum() or d in globchars or ord(d) > 127): |
11275 | 68 break |
69 pos += 1 | |
70 sym = program[s:pos] | |
71 if sym in keywords: # operator keywords | |
11289
4215ce511134
revset: raise ParseError exceptions
Matt Mackall <mpm@selenic.com>
parents:
11284
diff
changeset
|
72 yield (sym, None, s) |
11275 | 73 else: |
11289
4215ce511134
revset: raise ParseError exceptions
Matt Mackall <mpm@selenic.com>
parents:
11284
diff
changeset
|
74 yield ('symbol', sym, s) |
11275 | 75 pos -= 1 |
76 else: | |
11383
de544774ebea
revset: all your error messages are belong to _
Martin Geisler <mg@lazybytes.net>
parents:
11349
diff
changeset
|
77 raise error.ParseError(_("syntax error"), pos) |
11275 | 78 pos += 1 |
11289
4215ce511134
revset: raise ParseError exceptions
Matt Mackall <mpm@selenic.com>
parents:
11284
diff
changeset
|
79 yield ('end', None, pos) |
11275 | 80 |
81 parse = parser.parser(tokenize, elements).parse | |
82 | |
14551
68d814a3cefd
fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents:
14513
diff
changeset
|
83 def getstring(x, err): |
68d814a3cefd
fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents:
14513
diff
changeset
|
84 if x and (x[0] == 'string' or x[0] == 'symbol'): |
68d814a3cefd
fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents:
14513
diff
changeset
|
85 return x[1] |
68d814a3cefd
fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents:
14513
diff
changeset
|
86 raise error.ParseError(err) |
68d814a3cefd
fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents:
14513
diff
changeset
|
87 |
68d814a3cefd
fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents:
14513
diff
changeset
|
88 def getset(mctx, x): |
68d814a3cefd
fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents:
14513
diff
changeset
|
89 if not x: |
68d814a3cefd
fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents:
14513
diff
changeset
|
90 raise error.ParseError(_("missing argument")) |
68d814a3cefd
fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents:
14513
diff
changeset
|
91 return methods[x[0]](mctx, *x[1:]) |
68d814a3cefd
fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents:
14513
diff
changeset
|
92 |
68d814a3cefd
fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents:
14513
diff
changeset
|
93 def stringset(mctx, x): |
68d814a3cefd
fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents:
14513
diff
changeset
|
94 m = mctx.matcher([x]) |
68d814a3cefd
fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents:
14513
diff
changeset
|
95 return [f for f in mctx.subset if m(f)] |
68d814a3cefd
fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents:
14513
diff
changeset
|
96 |
68d814a3cefd
fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents:
14513
diff
changeset
|
97 def andset(mctx, x, y): |
68d814a3cefd
fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents:
14513
diff
changeset
|
98 return getset(mctx.narrow(getset(mctx, x)), y) |
68d814a3cefd
fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents:
14513
diff
changeset
|
99 |
68d814a3cefd
fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents:
14513
diff
changeset
|
100 def orset(mctx, x, y): |
68d814a3cefd
fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents:
14513
diff
changeset
|
101 # needs optimizing |
68d814a3cefd
fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents:
14513
diff
changeset
|
102 xl = getset(mctx, x) |
68d814a3cefd
fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents:
14513
diff
changeset
|
103 yl = getset(mctx, y) |
68d814a3cefd
fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents:
14513
diff
changeset
|
104 return xl + [f for f in yl if f not in xl] |
68d814a3cefd
fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents:
14513
diff
changeset
|
105 |
68d814a3cefd
fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents:
14513
diff
changeset
|
106 def notset(mctx, x): |
68d814a3cefd
fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents:
14513
diff
changeset
|
107 s = set(getset(mctx, x)) |
68d814a3cefd
fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents:
14513
diff
changeset
|
108 return [r for r in mctx.subset if r not in s] |
68d814a3cefd
fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents:
14513
diff
changeset
|
109 |
68d814a3cefd
fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents:
14513
diff
changeset
|
110 def listset(mctx, a, b): |
68d814a3cefd
fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents:
14513
diff
changeset
|
111 raise error.ParseError(_("can't use a list in this context")) |
68d814a3cefd
fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents:
14513
diff
changeset
|
112 |
14677
2a758ffc821e
fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents:
14676
diff
changeset
|
113 def modified(mctx, x): |
14681
0744db5eb51c
fileset: add some function help text
Matt Mackall <mpm@selenic.com>
parents:
14680
diff
changeset
|
114 """``modified()`` |
0744db5eb51c
fileset: add some function help text
Matt Mackall <mpm@selenic.com>
parents:
14680
diff
changeset
|
115 File that is modified according to status. |
0744db5eb51c
fileset: add some function help text
Matt Mackall <mpm@selenic.com>
parents:
14680
diff
changeset
|
116 """ |
14677
2a758ffc821e
fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents:
14676
diff
changeset
|
117 getargs(x, 0, 0, _("modified takes no arguments")) |
2a758ffc821e
fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents:
14676
diff
changeset
|
118 s = mctx.status()[0] |
2a758ffc821e
fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents:
14676
diff
changeset
|
119 return [f for f in mctx.subset if f in s] |
2a758ffc821e
fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents:
14676
diff
changeset
|
120 |
2a758ffc821e
fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents:
14676
diff
changeset
|
121 def added(mctx, x): |
14681
0744db5eb51c
fileset: add some function help text
Matt Mackall <mpm@selenic.com>
parents:
14680
diff
changeset
|
122 """``added()`` |
0744db5eb51c
fileset: add some function help text
Matt Mackall <mpm@selenic.com>
parents:
14680
diff
changeset
|
123 File that is added according to status. |
0744db5eb51c
fileset: add some function help text
Matt Mackall <mpm@selenic.com>
parents:
14680
diff
changeset
|
124 """ |
14677
2a758ffc821e
fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents:
14676
diff
changeset
|
125 getargs(x, 0, 0, _("added takes no arguments")) |
2a758ffc821e
fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents:
14676
diff
changeset
|
126 s = mctx.status()[1] |
2a758ffc821e
fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents:
14676
diff
changeset
|
127 return [f for f in mctx.subset if f in s] |
2a758ffc821e
fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents:
14676
diff
changeset
|
128 |
2a758ffc821e
fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents:
14676
diff
changeset
|
129 def removed(mctx, x): |
14681
0744db5eb51c
fileset: add some function help text
Matt Mackall <mpm@selenic.com>
parents:
14680
diff
changeset
|
130 """``removed()`` |
0744db5eb51c
fileset: add some function help text
Matt Mackall <mpm@selenic.com>
parents:
14680
diff
changeset
|
131 File that is removed according to status. |
0744db5eb51c
fileset: add some function help text
Matt Mackall <mpm@selenic.com>
parents:
14680
diff
changeset
|
132 """ |
14677
2a758ffc821e
fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents:
14676
diff
changeset
|
133 getargs(x, 0, 0, _("removed takes no arguments")) |
2a758ffc821e
fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents:
14676
diff
changeset
|
134 s = mctx.status()[2] |
2a758ffc821e
fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents:
14676
diff
changeset
|
135 return [f for f in mctx.subset if f in s] |
2a758ffc821e
fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents:
14676
diff
changeset
|
136 |
2a758ffc821e
fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents:
14676
diff
changeset
|
137 def deleted(mctx, x): |
14681
0744db5eb51c
fileset: add some function help text
Matt Mackall <mpm@selenic.com>
parents:
14680
diff
changeset
|
138 """``deleted()`` |
0744db5eb51c
fileset: add some function help text
Matt Mackall <mpm@selenic.com>
parents:
14680
diff
changeset
|
139 File that is deleted according to status. |
0744db5eb51c
fileset: add some function help text
Matt Mackall <mpm@selenic.com>
parents:
14680
diff
changeset
|
140 """ |
14677
2a758ffc821e
fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents:
14676
diff
changeset
|
141 getargs(x, 0, 0, _("deleted takes no arguments")) |
2a758ffc821e
fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents:
14676
diff
changeset
|
142 s = mctx.status()[3] |
2a758ffc821e
fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents:
14676
diff
changeset
|
143 return [f for f in mctx.subset if f in s] |
2a758ffc821e
fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents:
14676
diff
changeset
|
144 |
2a758ffc821e
fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents:
14676
diff
changeset
|
145 def unknown(mctx, x): |
14681
0744db5eb51c
fileset: add some function help text
Matt Mackall <mpm@selenic.com>
parents:
14680
diff
changeset
|
146 """``unknown()`` |
0744db5eb51c
fileset: add some function help text
Matt Mackall <mpm@selenic.com>
parents:
14680
diff
changeset
|
147 File that is unknown according to status. These files will only be |
0744db5eb51c
fileset: add some function help text
Matt Mackall <mpm@selenic.com>
parents:
14680
diff
changeset
|
148 considered if this predicate is used. |
0744db5eb51c
fileset: add some function help text
Matt Mackall <mpm@selenic.com>
parents:
14680
diff
changeset
|
149 """ |
14677
2a758ffc821e
fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents:
14676
diff
changeset
|
150 getargs(x, 0, 0, _("unknown takes no arguments")) |
2a758ffc821e
fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents:
14676
diff
changeset
|
151 s = mctx.status()[4] |
2a758ffc821e
fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents:
14676
diff
changeset
|
152 return [f for f in mctx.subset if f in s] |
2a758ffc821e
fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents:
14676
diff
changeset
|
153 |
2a758ffc821e
fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents:
14676
diff
changeset
|
154 def ignored(mctx, x): |
14681
0744db5eb51c
fileset: add some function help text
Matt Mackall <mpm@selenic.com>
parents:
14680
diff
changeset
|
155 """``ignored()`` |
0744db5eb51c
fileset: add some function help text
Matt Mackall <mpm@selenic.com>
parents:
14680
diff
changeset
|
156 File that is ignored according to status. These files will only be |
0744db5eb51c
fileset: add some function help text
Matt Mackall <mpm@selenic.com>
parents:
14680
diff
changeset
|
157 considered if this predicate is used. |
0744db5eb51c
fileset: add some function help text
Matt Mackall <mpm@selenic.com>
parents:
14680
diff
changeset
|
158 """ |
14677
2a758ffc821e
fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents:
14676
diff
changeset
|
159 getargs(x, 0, 0, _("ignored takes no arguments")) |
2a758ffc821e
fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents:
14676
diff
changeset
|
160 s = mctx.status()[5] |
2a758ffc821e
fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents:
14676
diff
changeset
|
161 return [f for f in mctx.subset if f in s] |
2a758ffc821e
fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents:
14676
diff
changeset
|
162 |
2a758ffc821e
fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents:
14676
diff
changeset
|
163 def clean(mctx, x): |
14681
0744db5eb51c
fileset: add some function help text
Matt Mackall <mpm@selenic.com>
parents:
14680
diff
changeset
|
164 """``clean()`` |
0744db5eb51c
fileset: add some function help text
Matt Mackall <mpm@selenic.com>
parents:
14680
diff
changeset
|
165 File that is clean according to status. |
0744db5eb51c
fileset: add some function help text
Matt Mackall <mpm@selenic.com>
parents:
14680
diff
changeset
|
166 """ |
14677
2a758ffc821e
fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents:
14676
diff
changeset
|
167 getargs(x, 0, 0, _("clean takes no arguments")) |
2a758ffc821e
fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents:
14676
diff
changeset
|
168 s = mctx.status()[6] |
2a758ffc821e
fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents:
14676
diff
changeset
|
169 return [f for f in mctx.subset if f in s] |
2a758ffc821e
fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents:
14676
diff
changeset
|
170 |
14676
e80fa502b8cf
fileset: add some basic predicates
Matt Mackall <mpm@selenic.com>
parents:
14673
diff
changeset
|
171 def func(mctx, a, b): |
e80fa502b8cf
fileset: add some basic predicates
Matt Mackall <mpm@selenic.com>
parents:
14673
diff
changeset
|
172 if a[0] == 'symbol' and a[1] in symbols: |
e80fa502b8cf
fileset: add some basic predicates
Matt Mackall <mpm@selenic.com>
parents:
14673
diff
changeset
|
173 return symbols[a[1]](mctx, b) |
e80fa502b8cf
fileset: add some basic predicates
Matt Mackall <mpm@selenic.com>
parents:
14673
diff
changeset
|
174 raise error.ParseError(_("not a function: %s") % a[1]) |
e80fa502b8cf
fileset: add some basic predicates
Matt Mackall <mpm@selenic.com>
parents:
14673
diff
changeset
|
175 |
e80fa502b8cf
fileset: add some basic predicates
Matt Mackall <mpm@selenic.com>
parents:
14673
diff
changeset
|
176 def getlist(x): |
e80fa502b8cf
fileset: add some basic predicates
Matt Mackall <mpm@selenic.com>
parents:
14673
diff
changeset
|
177 if not x: |
e80fa502b8cf
fileset: add some basic predicates
Matt Mackall <mpm@selenic.com>
parents:
14673
diff
changeset
|
178 return [] |
e80fa502b8cf
fileset: add some basic predicates
Matt Mackall <mpm@selenic.com>
parents:
14673
diff
changeset
|
179 if x[0] == 'list': |
e80fa502b8cf
fileset: add some basic predicates
Matt Mackall <mpm@selenic.com>
parents:
14673
diff
changeset
|
180 return getlist(x[1]) + [x[2]] |
e80fa502b8cf
fileset: add some basic predicates
Matt Mackall <mpm@selenic.com>
parents:
14673
diff
changeset
|
181 return [x] |
e80fa502b8cf
fileset: add some basic predicates
Matt Mackall <mpm@selenic.com>
parents:
14673
diff
changeset
|
182 |
e80fa502b8cf
fileset: add some basic predicates
Matt Mackall <mpm@selenic.com>
parents:
14673
diff
changeset
|
183 def getargs(x, min, max, err): |
e80fa502b8cf
fileset: add some basic predicates
Matt Mackall <mpm@selenic.com>
parents:
14673
diff
changeset
|
184 l = getlist(x) |
e80fa502b8cf
fileset: add some basic predicates
Matt Mackall <mpm@selenic.com>
parents:
14673
diff
changeset
|
185 if len(l) < min or len(l) > max: |
e80fa502b8cf
fileset: add some basic predicates
Matt Mackall <mpm@selenic.com>
parents:
14673
diff
changeset
|
186 raise error.ParseError(err) |
e80fa502b8cf
fileset: add some basic predicates
Matt Mackall <mpm@selenic.com>
parents:
14673
diff
changeset
|
187 return l |
e80fa502b8cf
fileset: add some basic predicates
Matt Mackall <mpm@selenic.com>
parents:
14673
diff
changeset
|
188 |
e80fa502b8cf
fileset: add some basic predicates
Matt Mackall <mpm@selenic.com>
parents:
14673
diff
changeset
|
189 def binary(mctx, x): |
14681
0744db5eb51c
fileset: add some function help text
Matt Mackall <mpm@selenic.com>
parents:
14680
diff
changeset
|
190 """``binary()`` |
0744db5eb51c
fileset: add some function help text
Matt Mackall <mpm@selenic.com>
parents:
14680
diff
changeset
|
191 File that appears to be binary (contails NUL bytes). |
0744db5eb51c
fileset: add some function help text
Matt Mackall <mpm@selenic.com>
parents:
14680
diff
changeset
|
192 """ |
14676
e80fa502b8cf
fileset: add some basic predicates
Matt Mackall <mpm@selenic.com>
parents:
14673
diff
changeset
|
193 getargs(x, 0, 0, _("binary takes no arguments")) |
e80fa502b8cf
fileset: add some basic predicates
Matt Mackall <mpm@selenic.com>
parents:
14673
diff
changeset
|
194 return [f for f in mctx.subset if util.binary(mctx.ctx[f].data())] |
e80fa502b8cf
fileset: add some basic predicates
Matt Mackall <mpm@selenic.com>
parents:
14673
diff
changeset
|
195 |
e80fa502b8cf
fileset: add some basic predicates
Matt Mackall <mpm@selenic.com>
parents:
14673
diff
changeset
|
196 def exec_(mctx, x): |
14681
0744db5eb51c
fileset: add some function help text
Matt Mackall <mpm@selenic.com>
parents:
14680
diff
changeset
|
197 """``exec()`` |
0744db5eb51c
fileset: add some function help text
Matt Mackall <mpm@selenic.com>
parents:
14680
diff
changeset
|
198 File that is marked as executable. |
0744db5eb51c
fileset: add some function help text
Matt Mackall <mpm@selenic.com>
parents:
14680
diff
changeset
|
199 """ |
14676
e80fa502b8cf
fileset: add some basic predicates
Matt Mackall <mpm@selenic.com>
parents:
14673
diff
changeset
|
200 getargs(x, 0, 0, _("exec takes no arguments")) |
e80fa502b8cf
fileset: add some basic predicates
Matt Mackall <mpm@selenic.com>
parents:
14673
diff
changeset
|
201 return [f for f in mctx.subset if mctx.ctx.flags(f) == 'x'] |
e80fa502b8cf
fileset: add some basic predicates
Matt Mackall <mpm@selenic.com>
parents:
14673
diff
changeset
|
202 |
e80fa502b8cf
fileset: add some basic predicates
Matt Mackall <mpm@selenic.com>
parents:
14673
diff
changeset
|
203 def symlink(mctx, x): |
14681
0744db5eb51c
fileset: add some function help text
Matt Mackall <mpm@selenic.com>
parents:
14680
diff
changeset
|
204 """``symlink()`` |
0744db5eb51c
fileset: add some function help text
Matt Mackall <mpm@selenic.com>
parents:
14680
diff
changeset
|
205 File that is marked as a symlink. |
0744db5eb51c
fileset: add some function help text
Matt Mackall <mpm@selenic.com>
parents:
14680
diff
changeset
|
206 """ |
14676
e80fa502b8cf
fileset: add some basic predicates
Matt Mackall <mpm@selenic.com>
parents:
14673
diff
changeset
|
207 getargs(x, 0, 0, _("symlink takes no arguments")) |
e80fa502b8cf
fileset: add some basic predicates
Matt Mackall <mpm@selenic.com>
parents:
14673
diff
changeset
|
208 return [f for f in mctx.subset if mctx.ctx.flags(f) == 'l'] |
e80fa502b8cf
fileset: add some basic predicates
Matt Mackall <mpm@selenic.com>
parents:
14673
diff
changeset
|
209 |
14679
e141e1cee0cc
fileset: add resolved and unresolved predicates
Matt Mackall <mpm@selenic.com>
parents:
14678
diff
changeset
|
210 def resolved(mctx, x): |
14681
0744db5eb51c
fileset: add some function help text
Matt Mackall <mpm@selenic.com>
parents:
14680
diff
changeset
|
211 """``resolved()`` |
0744db5eb51c
fileset: add some function help text
Matt Mackall <mpm@selenic.com>
parents:
14680
diff
changeset
|
212 File that is marked resolved according to the resolve state. |
0744db5eb51c
fileset: add some function help text
Matt Mackall <mpm@selenic.com>
parents:
14680
diff
changeset
|
213 """ |
14679
e141e1cee0cc
fileset: add resolved and unresolved predicates
Matt Mackall <mpm@selenic.com>
parents:
14678
diff
changeset
|
214 getargs(x, 0, 0, _("resolved takes no arguments")) |
e141e1cee0cc
fileset: add resolved and unresolved predicates
Matt Mackall <mpm@selenic.com>
parents:
14678
diff
changeset
|
215 if mctx.ctx.rev() is not None: |
e141e1cee0cc
fileset: add resolved and unresolved predicates
Matt Mackall <mpm@selenic.com>
parents:
14678
diff
changeset
|
216 return [] |
e141e1cee0cc
fileset: add resolved and unresolved predicates
Matt Mackall <mpm@selenic.com>
parents:
14678
diff
changeset
|
217 ms = merge.mergestate(mctx.ctx._repo) |
e141e1cee0cc
fileset: add resolved and unresolved predicates
Matt Mackall <mpm@selenic.com>
parents:
14678
diff
changeset
|
218 return [f for f in mctx.subset if f in ms and ms[f] == 'r'] |
e141e1cee0cc
fileset: add resolved and unresolved predicates
Matt Mackall <mpm@selenic.com>
parents:
14678
diff
changeset
|
219 |
e141e1cee0cc
fileset: add resolved and unresolved predicates
Matt Mackall <mpm@selenic.com>
parents:
14678
diff
changeset
|
220 def unresolved(mctx, x): |
14681
0744db5eb51c
fileset: add some function help text
Matt Mackall <mpm@selenic.com>
parents:
14680
diff
changeset
|
221 """``unresolved()`` |
0744db5eb51c
fileset: add some function help text
Matt Mackall <mpm@selenic.com>
parents:
14680
diff
changeset
|
222 File that is marked unresolved according to the resolve state. |
0744db5eb51c
fileset: add some function help text
Matt Mackall <mpm@selenic.com>
parents:
14680
diff
changeset
|
223 """ |
14679
e141e1cee0cc
fileset: add resolved and unresolved predicates
Matt Mackall <mpm@selenic.com>
parents:
14678
diff
changeset
|
224 getargs(x, 0, 0, _("unresolved takes no arguments")) |
e141e1cee0cc
fileset: add resolved and unresolved predicates
Matt Mackall <mpm@selenic.com>
parents:
14678
diff
changeset
|
225 if mctx.ctx.rev() is not None: |
e141e1cee0cc
fileset: add resolved and unresolved predicates
Matt Mackall <mpm@selenic.com>
parents:
14678
diff
changeset
|
226 return [] |
e141e1cee0cc
fileset: add resolved and unresolved predicates
Matt Mackall <mpm@selenic.com>
parents:
14678
diff
changeset
|
227 ms = merge.mergestate(mctx.ctx._repo) |
e141e1cee0cc
fileset: add resolved and unresolved predicates
Matt Mackall <mpm@selenic.com>
parents:
14678
diff
changeset
|
228 return [f for f in mctx.subset if f in ms and ms[f] == 'u'] |
e141e1cee0cc
fileset: add resolved and unresolved predicates
Matt Mackall <mpm@selenic.com>
parents:
14678
diff
changeset
|
229 |
14680 | 230 def hgignore(mctx, x): |
14681
0744db5eb51c
fileset: add some function help text
Matt Mackall <mpm@selenic.com>
parents:
14680
diff
changeset
|
231 """``resolved()`` |
0744db5eb51c
fileset: add some function help text
Matt Mackall <mpm@selenic.com>
parents:
14680
diff
changeset
|
232 File that matches the active .hgignore pattern. |
0744db5eb51c
fileset: add some function help text
Matt Mackall <mpm@selenic.com>
parents:
14680
diff
changeset
|
233 """ |
14680 | 234 getargs(x, 0, 0, _("hgignore takes no arguments")) |
235 ignore = mctx.ctx._repo.dirstate._ignore | |
236 return [f for f in mctx.subset if ignore(f)] | |
237 | |
14682
8785fd757077
fileset: add grep predicate
Matt Mackall <mpm@selenic.com>
parents:
14681
diff
changeset
|
238 def grep(mctx, x): |
8785fd757077
fileset: add grep predicate
Matt Mackall <mpm@selenic.com>
parents:
14681
diff
changeset
|
239 """``grep(regex)`` |
8785fd757077
fileset: add grep predicate
Matt Mackall <mpm@selenic.com>
parents:
14681
diff
changeset
|
240 File contains the given regular expression. |
8785fd757077
fileset: add grep predicate
Matt Mackall <mpm@selenic.com>
parents:
14681
diff
changeset
|
241 """ |
8785fd757077
fileset: add grep predicate
Matt Mackall <mpm@selenic.com>
parents:
14681
diff
changeset
|
242 pat = getstring(x, _("grep requires a pattern")) |
8785fd757077
fileset: add grep predicate
Matt Mackall <mpm@selenic.com>
parents:
14681
diff
changeset
|
243 r = re.compile(pat) |
8785fd757077
fileset: add grep predicate
Matt Mackall <mpm@selenic.com>
parents:
14681
diff
changeset
|
244 return [f for f in mctx.subset if r.search(mctx.ctx[f].data())] |
8785fd757077
fileset: add grep predicate
Matt Mackall <mpm@selenic.com>
parents:
14681
diff
changeset
|
245 |
14676
e80fa502b8cf
fileset: add some basic predicates
Matt Mackall <mpm@selenic.com>
parents:
14673
diff
changeset
|
246 symbols = { |
14677
2a758ffc821e
fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents:
14676
diff
changeset
|
247 'added': added, |
14676
e80fa502b8cf
fileset: add some basic predicates
Matt Mackall <mpm@selenic.com>
parents:
14673
diff
changeset
|
248 'binary': binary, |
14677
2a758ffc821e
fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents:
14676
diff
changeset
|
249 'clean': clean, |
2a758ffc821e
fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents:
14676
diff
changeset
|
250 'deleted': deleted, |
14676
e80fa502b8cf
fileset: add some basic predicates
Matt Mackall <mpm@selenic.com>
parents:
14673
diff
changeset
|
251 'exec': exec_, |
14682
8785fd757077
fileset: add grep predicate
Matt Mackall <mpm@selenic.com>
parents:
14681
diff
changeset
|
252 'grep': grep, |
14677
2a758ffc821e
fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents:
14676
diff
changeset
|
253 'ignored': ignored, |
14680 | 254 'hgignore': hgignore, |
14677
2a758ffc821e
fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents:
14676
diff
changeset
|
255 'modified': modified, |
2a758ffc821e
fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents:
14676
diff
changeset
|
256 'removed': removed, |
14679
e141e1cee0cc
fileset: add resolved and unresolved predicates
Matt Mackall <mpm@selenic.com>
parents:
14678
diff
changeset
|
257 'resolved': resolved, |
14676
e80fa502b8cf
fileset: add some basic predicates
Matt Mackall <mpm@selenic.com>
parents:
14673
diff
changeset
|
258 'symlink': symlink, |
14677
2a758ffc821e
fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents:
14676
diff
changeset
|
259 'unknown': unknown, |
14679
e141e1cee0cc
fileset: add resolved and unresolved predicates
Matt Mackall <mpm@selenic.com>
parents:
14678
diff
changeset
|
260 'unresolved': unresolved, |
14676
e80fa502b8cf
fileset: add some basic predicates
Matt Mackall <mpm@selenic.com>
parents:
14673
diff
changeset
|
261 } |
e80fa502b8cf
fileset: add some basic predicates
Matt Mackall <mpm@selenic.com>
parents:
14673
diff
changeset
|
262 |
14551
68d814a3cefd
fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents:
14513
diff
changeset
|
263 methods = { |
68d814a3cefd
fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents:
14513
diff
changeset
|
264 'string': stringset, |
68d814a3cefd
fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents:
14513
diff
changeset
|
265 'symbol': stringset, |
68d814a3cefd
fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents:
14513
diff
changeset
|
266 'and': andset, |
68d814a3cefd
fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents:
14513
diff
changeset
|
267 'or': orset, |
68d814a3cefd
fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents:
14513
diff
changeset
|
268 'list': listset, |
68d814a3cefd
fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents:
14513
diff
changeset
|
269 'group': getset, |
14676
e80fa502b8cf
fileset: add some basic predicates
Matt Mackall <mpm@selenic.com>
parents:
14673
diff
changeset
|
270 'not': notset, |
e80fa502b8cf
fileset: add some basic predicates
Matt Mackall <mpm@selenic.com>
parents:
14673
diff
changeset
|
271 'func': func, |
14551
68d814a3cefd
fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents:
14513
diff
changeset
|
272 } |
68d814a3cefd
fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents:
14513
diff
changeset
|
273 |
68d814a3cefd
fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents:
14513
diff
changeset
|
274 class matchctx(object): |
14677
2a758ffc821e
fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents:
14676
diff
changeset
|
275 def __init__(self, ctx, subset=None, status=None): |
14551
68d814a3cefd
fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents:
14513
diff
changeset
|
276 self.ctx = ctx |
68d814a3cefd
fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents:
14513
diff
changeset
|
277 self.subset = subset |
14677
2a758ffc821e
fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents:
14676
diff
changeset
|
278 self._status = status |
2a758ffc821e
fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents:
14676
diff
changeset
|
279 def status(self): |
2a758ffc821e
fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents:
14676
diff
changeset
|
280 return self._status |
14673 | 281 def matcher(self, patterns): |
282 return self.ctx.match(patterns) | |
14551
68d814a3cefd
fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents:
14513
diff
changeset
|
283 def filter(self, files): |
68d814a3cefd
fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents:
14513
diff
changeset
|
284 return [f for f in files if f in self.subset] |
68d814a3cefd
fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents:
14513
diff
changeset
|
285 def narrow(self, files): |
14677
2a758ffc821e
fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents:
14676
diff
changeset
|
286 return matchctx(self.ctx, self.filter(files), self._status) |
14551
68d814a3cefd
fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents:
14513
diff
changeset
|
287 |
14678
5ef7b87530f6
fileset: prescan parse tree to optimize status usage
Matt Mackall <mpm@selenic.com>
parents:
14677
diff
changeset
|
288 def _intree(funcs, tree): |
5ef7b87530f6
fileset: prescan parse tree to optimize status usage
Matt Mackall <mpm@selenic.com>
parents:
14677
diff
changeset
|
289 if isinstance(tree, tuple): |
5ef7b87530f6
fileset: prescan parse tree to optimize status usage
Matt Mackall <mpm@selenic.com>
parents:
14677
diff
changeset
|
290 if tree[0] == 'func' and tree[1][0] == 'symbol': |
5ef7b87530f6
fileset: prescan parse tree to optimize status usage
Matt Mackall <mpm@selenic.com>
parents:
14677
diff
changeset
|
291 if tree[1][1] in funcs: |
5ef7b87530f6
fileset: prescan parse tree to optimize status usage
Matt Mackall <mpm@selenic.com>
parents:
14677
diff
changeset
|
292 return True |
5ef7b87530f6
fileset: prescan parse tree to optimize status usage
Matt Mackall <mpm@selenic.com>
parents:
14677
diff
changeset
|
293 for s in tree[1:]: |
5ef7b87530f6
fileset: prescan parse tree to optimize status usage
Matt Mackall <mpm@selenic.com>
parents:
14677
diff
changeset
|
294 if _intree(funcs, s): |
5ef7b87530f6
fileset: prescan parse tree to optimize status usage
Matt Mackall <mpm@selenic.com>
parents:
14677
diff
changeset
|
295 return True |
5ef7b87530f6
fileset: prescan parse tree to optimize status usage
Matt Mackall <mpm@selenic.com>
parents:
14677
diff
changeset
|
296 return False |
5ef7b87530f6
fileset: prescan parse tree to optimize status usage
Matt Mackall <mpm@selenic.com>
parents:
14677
diff
changeset
|
297 |
14673 | 298 def getfileset(ctx, expr): |
14551
68d814a3cefd
fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents:
14513
diff
changeset
|
299 tree, pos = parse(expr) |
68d814a3cefd
fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents:
14513
diff
changeset
|
300 if (pos != len(expr)): |
68d814a3cefd
fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents:
14513
diff
changeset
|
301 raise error.ParseError("invalid token", pos) |
14678
5ef7b87530f6
fileset: prescan parse tree to optimize status usage
Matt Mackall <mpm@selenic.com>
parents:
14677
diff
changeset
|
302 |
5ef7b87530f6
fileset: prescan parse tree to optimize status usage
Matt Mackall <mpm@selenic.com>
parents:
14677
diff
changeset
|
303 # do we need status info? |
5ef7b87530f6
fileset: prescan parse tree to optimize status usage
Matt Mackall <mpm@selenic.com>
parents:
14677
diff
changeset
|
304 if _intree(['modified', 'added', 'removed', 'deleted', |
5ef7b87530f6
fileset: prescan parse tree to optimize status usage
Matt Mackall <mpm@selenic.com>
parents:
14677
diff
changeset
|
305 'unknown', 'ignored', 'clean'], tree): |
5ef7b87530f6
fileset: prescan parse tree to optimize status usage
Matt Mackall <mpm@selenic.com>
parents:
14677
diff
changeset
|
306 unknown = _intree(['unknown'], tree) |
5ef7b87530f6
fileset: prescan parse tree to optimize status usage
Matt Mackall <mpm@selenic.com>
parents:
14677
diff
changeset
|
307 ignored = _intree(['ignored'], tree) |
5ef7b87530f6
fileset: prescan parse tree to optimize status usage
Matt Mackall <mpm@selenic.com>
parents:
14677
diff
changeset
|
308 |
5ef7b87530f6
fileset: prescan parse tree to optimize status usage
Matt Mackall <mpm@selenic.com>
parents:
14677
diff
changeset
|
309 r = ctx._repo |
5ef7b87530f6
fileset: prescan parse tree to optimize status usage
Matt Mackall <mpm@selenic.com>
parents:
14677
diff
changeset
|
310 status = r.status(ctx.p1(), ctx, |
5ef7b87530f6
fileset: prescan parse tree to optimize status usage
Matt Mackall <mpm@selenic.com>
parents:
14677
diff
changeset
|
311 unknown=unknown, ignored=ignored, clean=True) |
5ef7b87530f6
fileset: prescan parse tree to optimize status usage
Matt Mackall <mpm@selenic.com>
parents:
14677
diff
changeset
|
312 subset = [] |
5ef7b87530f6
fileset: prescan parse tree to optimize status usage
Matt Mackall <mpm@selenic.com>
parents:
14677
diff
changeset
|
313 for c in status: |
5ef7b87530f6
fileset: prescan parse tree to optimize status usage
Matt Mackall <mpm@selenic.com>
parents:
14677
diff
changeset
|
314 subset.extend(c) |
5ef7b87530f6
fileset: prescan parse tree to optimize status usage
Matt Mackall <mpm@selenic.com>
parents:
14677
diff
changeset
|
315 else: |
5ef7b87530f6
fileset: prescan parse tree to optimize status usage
Matt Mackall <mpm@selenic.com>
parents:
14677
diff
changeset
|
316 status = None |
5ef7b87530f6
fileset: prescan parse tree to optimize status usage
Matt Mackall <mpm@selenic.com>
parents:
14677
diff
changeset
|
317 subset = ctx.walk(ctx.match([])) |
5ef7b87530f6
fileset: prescan parse tree to optimize status usage
Matt Mackall <mpm@selenic.com>
parents:
14677
diff
changeset
|
318 |
5ef7b87530f6
fileset: prescan parse tree to optimize status usage
Matt Mackall <mpm@selenic.com>
parents:
14677
diff
changeset
|
319 return getset(matchctx(ctx, subset, status), tree) |
14681
0744db5eb51c
fileset: add some function help text
Matt Mackall <mpm@selenic.com>
parents:
14680
diff
changeset
|
320 |
0744db5eb51c
fileset: add some function help text
Matt Mackall <mpm@selenic.com>
parents:
14680
diff
changeset
|
321 # tell hggettext to extract docstrings from these functions: |
0744db5eb51c
fileset: add some function help text
Matt Mackall <mpm@selenic.com>
parents:
14680
diff
changeset
|
322 i18nfunctions = symbols.values() |