annotate mercurial/fileset.py @ 37392:a4f02a17420d

copies: clean up _related logic The limit parameter was never actually used, since the only way the 4th case could be reached was if f1r and f2r converged. The new code makes this clear, and additionally reduces the conditional block to just 3 cases.
author Gábor Stefanik <gabor.stefanik@nng.com>
date Thu, 05 Apr 2018 17:51:10 +0200
parents f290f130d7fc
children 5f2dc1b71cf1
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
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
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
2 #
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
3 # Copyright 2010 Matt Mackall <mpm@selenic.com>
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
4 #
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
5 # This software may be used and distributed according to the terms of the
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
6 # GNU General Public License version 2 or any later version.
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
7
25938
e194ada8d45f fileset: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25815
diff changeset
8 from __future__ import absolute_import
e194ada8d45f fileset: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25815
diff changeset
9
20034
1e5b38a919dd cleanup: move stdlib imports to their own import statement
Augie Fackler <raf@durin42.com>
parents: 19470
diff changeset
10 import re
25938
e194ada8d45f fileset: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25815
diff changeset
11
e194ada8d45f fileset: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25815
diff changeset
12 from .i18n import _
e194ada8d45f fileset: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25815
diff changeset
13 from . import (
e194ada8d45f fileset: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25815
diff changeset
14 error,
35739
9eb5c400f488 fileset: move import of match module to top
Yuya Nishihara <yuya@tcha.org>
parents: 35692
diff changeset
15 match as matchmod,
25938
e194ada8d45f fileset: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25815
diff changeset
16 merge,
e194ada8d45f fileset: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25815
diff changeset
17 parser,
32523
1fb0a85fb20e py3: use pycompat.bytestr so that we don't get ascii values
Pulkit Goyal <7895pulkit@gmail.com>
parents: 32291
diff changeset
18 pycompat,
28448
7108834c76a2 fileset: replace predicate by filesetpredicate of registrar (API)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 28447
diff changeset
19 registrar,
31193
4140d49d2efb fileset: add revs(revs, fileset) to evaluate set in working directory
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31192
diff changeset
20 scmutil,
25938
e194ada8d45f fileset: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25815
diff changeset
21 util,
e194ada8d45f fileset: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25815
diff changeset
22 )
37084
f0b6fbea00cf stringutil: bulk-replace call sites to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 36505
diff changeset
23 from .utils import (
f0b6fbea00cf stringutil: bulk-replace call sites to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 36505
diff changeset
24 stringutil,
f0b6fbea00cf stringutil: bulk-replace call sites to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 36505
diff changeset
25 )
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
26
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
27 elements = {
25815
e71e5629e006 parser: separate actions for primary expression and prefix operator
Yuya Nishihara <yuya@tcha.org>
parents: 25801
diff changeset
28 # token-type: binding-strength, primary, prefix, infix, suffix
e71e5629e006 parser: separate actions for primary expression and prefix operator
Yuya Nishihara <yuya@tcha.org>
parents: 25801
diff changeset
29 "(": (20, None, ("group", 1, ")"), ("func", 1, ")"), None),
35741
73432eee0ac4 fileset: add kind:pat operator
Yuya Nishihara <yuya@tcha.org>
parents: 35739
diff changeset
30 ":": (15, None, None, ("kindpat", 15), None),
25815
e71e5629e006 parser: separate actions for primary expression and prefix operator
Yuya Nishihara <yuya@tcha.org>
parents: 25801
diff changeset
31 "-": (5, None, ("negate", 19), ("minus", 5), None),
e71e5629e006 parser: separate actions for primary expression and prefix operator
Yuya Nishihara <yuya@tcha.org>
parents: 25801
diff changeset
32 "not": (10, None, ("not", 10), None, None),
e71e5629e006 parser: separate actions for primary expression and prefix operator
Yuya Nishihara <yuya@tcha.org>
parents: 25801
diff changeset
33 "!": (10, None, ("not", 10), None, None),
e71e5629e006 parser: separate actions for primary expression and prefix operator
Yuya Nishihara <yuya@tcha.org>
parents: 25801
diff changeset
34 "and": (5, None, None, ("and", 5), None),
e71e5629e006 parser: separate actions for primary expression and prefix operator
Yuya Nishihara <yuya@tcha.org>
parents: 25801
diff changeset
35 "&": (5, None, None, ("and", 5), None),
e71e5629e006 parser: separate actions for primary expression and prefix operator
Yuya Nishihara <yuya@tcha.org>
parents: 25801
diff changeset
36 "or": (4, None, None, ("or", 4), None),
e71e5629e006 parser: separate actions for primary expression and prefix operator
Yuya Nishihara <yuya@tcha.org>
parents: 25801
diff changeset
37 "|": (4, None, None, ("or", 4), None),
e71e5629e006 parser: separate actions for primary expression and prefix operator
Yuya Nishihara <yuya@tcha.org>
parents: 25801
diff changeset
38 "+": (4, None, None, ("or", 4), None),
e71e5629e006 parser: separate actions for primary expression and prefix operator
Yuya Nishihara <yuya@tcha.org>
parents: 25801
diff changeset
39 ",": (2, None, None, ("list", 2), None),
e71e5629e006 parser: separate actions for primary expression and prefix operator
Yuya Nishihara <yuya@tcha.org>
parents: 25801
diff changeset
40 ")": (0, None, None, None, None),
e71e5629e006 parser: separate actions for primary expression and prefix operator
Yuya Nishihara <yuya@tcha.org>
parents: 25801
diff changeset
41 "symbol": (0, "symbol", None, None, None),
e71e5629e006 parser: separate actions for primary expression and prefix operator
Yuya Nishihara <yuya@tcha.org>
parents: 25801
diff changeset
42 "string": (0, "string", None, None, None),
e71e5629e006 parser: separate actions for primary expression and prefix operator
Yuya Nishihara <yuya@tcha.org>
parents: 25801
diff changeset
43 "end": (0, None, None, None, None),
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
44 }
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
45
32291
bd872f64a8ba cleanup: use set literals
Martin von Zweigbergk <martinvonz@google.com>
parents: 32134
diff changeset
46 keywords = {'and', 'or', 'not'}
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
47
19470
19ac0d8ee9a2 fileset: handle underbar in symbols
Matt Mackall <mpm@selenic.com>
parents: 19194
diff changeset
48 globchars = ".*{}[]?/\\_"
14551
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
49
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
50 def tokenize(program):
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
51 pos, l = 0, len(program)
32523
1fb0a85fb20e py3: use pycompat.bytestr so that we don't get ascii values
Pulkit Goyal <7895pulkit@gmail.com>
parents: 32291
diff changeset
52 program = pycompat.bytestr(program)
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
53 while pos < l:
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
54 c = program[pos]
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
55 if c.isspace(): # skip inter-token whitespace
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
56 pass
35741
73432eee0ac4 fileset: add kind:pat operator
Yuya Nishihara <yuya@tcha.org>
parents: 35739
diff changeset
57 elif c in "(),-:|&+!": # handle simple operators
11289
4215ce511134 revset: raise ParseError exceptions
Matt Mackall <mpm@selenic.com>
parents: 11284
diff changeset
58 yield (c, None, pos)
12408
78a97859b90d revset: support raw string literals
Brodie Rao <brodie@bitheap.org>
parents: 12401
diff changeset
59 elif (c in '"\'' or c == 'r' and
78a97859b90d revset: support raw string literals
Brodie Rao <brodie@bitheap.org>
parents: 12401
diff changeset
60 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
61 if c == 'r':
78a97859b90d revset: support raw string literals
Brodie Rao <brodie@bitheap.org>
parents: 12401
diff changeset
62 pos += 1
78a97859b90d revset: support raw string literals
Brodie Rao <brodie@bitheap.org>
parents: 12401
diff changeset
63 c = program[pos]
78a97859b90d revset: support raw string literals
Brodie Rao <brodie@bitheap.org>
parents: 12401
diff changeset
64 decode = lambda x: x
78a97859b90d revset: support raw string literals
Brodie Rao <brodie@bitheap.org>
parents: 12401
diff changeset
65 else:
26233
d3dbb65c8dc6 fileset: handle error of string unescaping
Yuya Nishihara <yuya@tcha.org>
parents: 26195
diff changeset
66 decode = parser.unescapestr
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
67 pos += 1
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
68 s = pos
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
69 while pos < l: # find closing quote
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
70 d = program[pos]
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
71 if d == '\\': # skip over escaped characters
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
72 pos += 2
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
73 continue
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
74 if d == c:
12408
78a97859b90d revset: support raw string literals
Brodie Rao <brodie@bitheap.org>
parents: 12401
diff changeset
75 yield ('string', decode(program[s:pos]), s)
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
76 break
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
77 pos += 1
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
78 else:
11383
de544774ebea revset: all your error messages are belong to _
Martin Geisler <mg@lazybytes.net>
parents: 11349
diff changeset
79 raise error.ParseError(_("unterminated string"), s)
14551
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
80 elif c.isalnum() or c in globchars or ord(c) > 127:
14513
85fe676c27e9 fileset: fix long line
Matt Mackall <mpm@selenic.com>
parents: 14511
diff changeset
81 # gather up a symbol/keyword
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
82 s = pos
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
83 pos += 1
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
84 while pos < l: # find end of symbol
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
85 d = program[pos]
14551
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
86 if not (d.isalnum() or d in globchars or ord(d) > 127):
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
87 break
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
88 pos += 1
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
89 sym = program[s:pos]
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
90 if sym in keywords: # operator keywords
11289
4215ce511134 revset: raise ParseError exceptions
Matt Mackall <mpm@selenic.com>
parents: 11284
diff changeset
91 yield (sym, None, s)
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
92 else:
11289
4215ce511134 revset: raise ParseError exceptions
Matt Mackall <mpm@selenic.com>
parents: 11284
diff changeset
93 yield ('symbol', sym, s)
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
94 pos -= 1
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
95 else:
11383
de544774ebea revset: all your error messages are belong to _
Martin Geisler <mg@lazybytes.net>
parents: 11349
diff changeset
96 raise error.ParseError(_("syntax error"), pos)
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
97 pos += 1
11289
4215ce511134 revset: raise ParseError exceptions
Matt Mackall <mpm@selenic.com>
parents: 11284
diff changeset
98 yield ('end', None, pos)
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
99
20208
61a47fd64f30 fileset, revset: do not use global parser object for thread safety
Yuya Nishihara <yuya@tcha.org>
parents: 19470
diff changeset
100 def parse(expr):
25654
af329a84310c parser: accept iterator of tokens instead of tokenizer function and program
Yuya Nishihara <yuya@tcha.org>
parents: 25633
diff changeset
101 p = parser.parser(elements)
af329a84310c parser: accept iterator of tokens instead of tokenizer function and program
Yuya Nishihara <yuya@tcha.org>
parents: 25633
diff changeset
102 tree, pos = p.parse(tokenize(expr))
25252
ac381dd7a21f fileset: move validation of incomplete parsing to parse() function
Yuya Nishihara <yuya@tcha.org>
parents: 24408
diff changeset
103 if pos != len(expr):
ac381dd7a21f fileset: move validation of incomplete parsing to parse() function
Yuya Nishihara <yuya@tcha.org>
parents: 24408
diff changeset
104 raise error.ParseError(_("invalid token"), pos)
ac381dd7a21f fileset: move validation of incomplete parsing to parse() function
Yuya Nishihara <yuya@tcha.org>
parents: 24408
diff changeset
105 return tree
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
106
35691
735f47b41521 fileset: make it robust for bad function calls
Yuya Nishihara <yuya@tcha.org>
parents: 35615
diff changeset
107 def getsymbol(x):
735f47b41521 fileset: make it robust for bad function calls
Yuya Nishihara <yuya@tcha.org>
parents: 35615
diff changeset
108 if x and x[0] == 'symbol':
735f47b41521 fileset: make it robust for bad function calls
Yuya Nishihara <yuya@tcha.org>
parents: 35615
diff changeset
109 return x[1]
735f47b41521 fileset: make it robust for bad function calls
Yuya Nishihara <yuya@tcha.org>
parents: 35615
diff changeset
110 raise error.ParseError(_('not a symbol'))
735f47b41521 fileset: make it robust for bad function calls
Yuya Nishihara <yuya@tcha.org>
parents: 35615
diff changeset
111
14551
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
112 def getstring(x, err):
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
113 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
114 return x[1]
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
115 raise error.ParseError(err)
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
116
35741
73432eee0ac4 fileset: add kind:pat operator
Yuya Nishihara <yuya@tcha.org>
parents: 35739
diff changeset
117 def _getkindpat(x, y, allkinds, err):
73432eee0ac4 fileset: add kind:pat operator
Yuya Nishihara <yuya@tcha.org>
parents: 35739
diff changeset
118 kind = getsymbol(x)
73432eee0ac4 fileset: add kind:pat operator
Yuya Nishihara <yuya@tcha.org>
parents: 35739
diff changeset
119 pat = getstring(y, err)
73432eee0ac4 fileset: add kind:pat operator
Yuya Nishihara <yuya@tcha.org>
parents: 35739
diff changeset
120 if kind not in allkinds:
73432eee0ac4 fileset: add kind:pat operator
Yuya Nishihara <yuya@tcha.org>
parents: 35739
diff changeset
121 raise error.ParseError(_("invalid pattern kind: %s") % kind)
73432eee0ac4 fileset: add kind:pat operator
Yuya Nishihara <yuya@tcha.org>
parents: 35739
diff changeset
122 return '%s:%s' % (kind, pat)
73432eee0ac4 fileset: add kind:pat operator
Yuya Nishihara <yuya@tcha.org>
parents: 35739
diff changeset
123
73432eee0ac4 fileset: add kind:pat operator
Yuya Nishihara <yuya@tcha.org>
parents: 35739
diff changeset
124 def getpattern(x, allkinds, err):
73432eee0ac4 fileset: add kind:pat operator
Yuya Nishihara <yuya@tcha.org>
parents: 35739
diff changeset
125 if x and x[0] == 'kindpat':
73432eee0ac4 fileset: add kind:pat operator
Yuya Nishihara <yuya@tcha.org>
parents: 35739
diff changeset
126 return _getkindpat(x[1], x[2], allkinds, err)
73432eee0ac4 fileset: add kind:pat operator
Yuya Nishihara <yuya@tcha.org>
parents: 35739
diff changeset
127 return getstring(x, err)
73432eee0ac4 fileset: add kind:pat operator
Yuya Nishihara <yuya@tcha.org>
parents: 35739
diff changeset
128
14551
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
129 def getset(mctx, x):
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
130 if not x:
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
131 raise error.ParseError(_("missing argument"))
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
132 return methods[x[0]](mctx, *x[1:])
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
133
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
134 def stringset(mctx, x):
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
135 m = mctx.matcher([x])
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
136 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
137
35741
73432eee0ac4 fileset: add kind:pat operator
Yuya Nishihara <yuya@tcha.org>
parents: 35739
diff changeset
138 def kindpatset(mctx, x, y):
73432eee0ac4 fileset: add kind:pat operator
Yuya Nishihara <yuya@tcha.org>
parents: 35739
diff changeset
139 return stringset(mctx, _getkindpat(x, y, matchmod.allpatternkinds,
73432eee0ac4 fileset: add kind:pat operator
Yuya Nishihara <yuya@tcha.org>
parents: 35739
diff changeset
140 _("pattern must be a string")))
73432eee0ac4 fileset: add kind:pat operator
Yuya Nishihara <yuya@tcha.org>
parents: 35739
diff changeset
141
14551
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
142 def andset(mctx, x, y):
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
143 return getset(mctx.narrow(getset(mctx, x)), y)
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
144
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
145 def orset(mctx, x, y):
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
146 # needs optimizing
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
147 xl = getset(mctx, x)
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
148 yl = getset(mctx, y)
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
149 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
150
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
151 def notset(mctx, x):
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
152 s = set(getset(mctx, x))
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
153 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
154
17363
5d9e2031c0b1 fileset: actually implement 'minusset'
Patrick Mezard <patrick@mezard.eu>
parents: 16443
diff changeset
155 def minusset(mctx, x, y):
5d9e2031c0b1 fileset: actually implement 'minusset'
Patrick Mezard <patrick@mezard.eu>
parents: 16443
diff changeset
156 xl = getset(mctx, x)
5d9e2031c0b1 fileset: actually implement 'minusset'
Patrick Mezard <patrick@mezard.eu>
parents: 16443
diff changeset
157 yl = set(getset(mctx, y))
5d9e2031c0b1 fileset: actually implement 'minusset'
Patrick Mezard <patrick@mezard.eu>
parents: 16443
diff changeset
158 return [f for f in xl if f not in yl]
5d9e2031c0b1 fileset: actually implement 'minusset'
Patrick Mezard <patrick@mezard.eu>
parents: 16443
diff changeset
159
35692
a62b08f6626b fileset: do not crash by unary negate operation
Yuya Nishihara <yuya@tcha.org>
parents: 35691
diff changeset
160 def negateset(mctx, x):
a62b08f6626b fileset: do not crash by unary negate operation
Yuya Nishihara <yuya@tcha.org>
parents: 35691
diff changeset
161 raise error.ParseError(_("can't use negate operator in this context"))
a62b08f6626b fileset: do not crash by unary negate operation
Yuya Nishihara <yuya@tcha.org>
parents: 35691
diff changeset
162
14551
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
163 def listset(mctx, a, b):
27518
737ffdabbde9 fileset: add hint for list error to use or
timeless <timeless@mozdev.org>
parents: 27464
diff changeset
164 raise error.ParseError(_("can't use a list in this context"),
737ffdabbde9 fileset: add hint for list error to use or
timeless <timeless@mozdev.org>
parents: 27464
diff changeset
165 hint=_('see hg help "filesets.x or y"'))
14551
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
166
27460
11286ac374f3 fileset: use decorator to mark a function as fileset predicate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27459
diff changeset
167 # symbols are callable like:
11286ac374f3 fileset: use decorator to mark a function as fileset predicate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27459
diff changeset
168 # fun(mctx, x)
11286ac374f3 fileset: use decorator to mark a function as fileset predicate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27459
diff changeset
169 # with:
11286ac374f3 fileset: use decorator to mark a function as fileset predicate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27459
diff changeset
170 # mctx - current matchctx instance
11286ac374f3 fileset: use decorator to mark a function as fileset predicate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27459
diff changeset
171 # x - argument in tree form
11286ac374f3 fileset: use decorator to mark a function as fileset predicate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27459
diff changeset
172 symbols = {}
11286ac374f3 fileset: use decorator to mark a function as fileset predicate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27459
diff changeset
173
27461
afa76585c955 fileset: use decorator to mark a predicate as "status caller"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27460
diff changeset
174 # filesets using matchctx.status()
27463
a8afdc5a7885 fileset: use set instead of list to mark predicates for efficiency (API)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27462
diff changeset
175 _statuscallers = set()
27461
afa76585c955 fileset: use decorator to mark a predicate as "status caller"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27460
diff changeset
176
27462
470ea34ba593 fileset: use decorator to mark a predicate as "existing caller"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27461
diff changeset
177 # filesets using matchctx.existing()
27463
a8afdc5a7885 fileset: use set instead of list to mark predicates for efficiency (API)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27462
diff changeset
178 _existingcallers = set()
27462
470ea34ba593 fileset: use decorator to mark a predicate as "existing caller"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27461
diff changeset
179
28448
7108834c76a2 fileset: replace predicate by filesetpredicate of registrar (API)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 28447
diff changeset
180 predicate = registrar.filesetpredicate()
27460
11286ac374f3 fileset: use decorator to mark a function as fileset predicate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27459
diff changeset
181
27461
afa76585c955 fileset: use decorator to mark a predicate as "status caller"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27460
diff changeset
182 @predicate('modified()', callstatus=True)
14677
2a758ffc821e fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents: 14676
diff changeset
183 def modified(mctx, x):
27460
11286ac374f3 fileset: use decorator to mark a function as fileset predicate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27459
diff changeset
184 """File that is modified according to :hg:`status`.
14681
0744db5eb51c fileset: add some function help text
Matt Mackall <mpm@selenic.com>
parents: 14680
diff changeset
185 """
14785
0f0bd4d028d3 fileset: add i18n hints for keywords
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 14718
diff changeset
186 # i18n: "modified" is a keyword
14677
2a758ffc821e fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents: 14676
diff changeset
187 getargs(x, 0, 0, _("modified takes no arguments"))
31697
992882cef7e1 fileset: perform membership test against set for status queries
Gregory Szorc <gregory.szorc@gmail.com>
parents: 31254
diff changeset
188 s = set(mctx.status().modified)
14677
2a758ffc821e fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents: 14676
diff changeset
189 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
190
27461
afa76585c955 fileset: use decorator to mark a predicate as "status caller"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27460
diff changeset
191 @predicate('added()', callstatus=True)
14677
2a758ffc821e fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents: 14676
diff changeset
192 def added(mctx, x):
27460
11286ac374f3 fileset: use decorator to mark a function as fileset predicate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27459
diff changeset
193 """File that is added according to :hg:`status`.
14681
0744db5eb51c fileset: add some function help text
Matt Mackall <mpm@selenic.com>
parents: 14680
diff changeset
194 """
14785
0f0bd4d028d3 fileset: add i18n hints for keywords
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 14718
diff changeset
195 # i18n: "added" is a keyword
14677
2a758ffc821e fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents: 14676
diff changeset
196 getargs(x, 0, 0, _("added takes no arguments"))
31697
992882cef7e1 fileset: perform membership test against set for status queries
Gregory Szorc <gregory.szorc@gmail.com>
parents: 31254
diff changeset
197 s = set(mctx.status().added)
14677
2a758ffc821e fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents: 14676
diff changeset
198 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
199
27461
afa76585c955 fileset: use decorator to mark a predicate as "status caller"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27460
diff changeset
200 @predicate('removed()', callstatus=True)
14677
2a758ffc821e fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents: 14676
diff changeset
201 def removed(mctx, x):
27460
11286ac374f3 fileset: use decorator to mark a function as fileset predicate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27459
diff changeset
202 """File that is removed according to :hg:`status`.
14681
0744db5eb51c fileset: add some function help text
Matt Mackall <mpm@selenic.com>
parents: 14680
diff changeset
203 """
14785
0f0bd4d028d3 fileset: add i18n hints for keywords
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 14718
diff changeset
204 # i18n: "removed" is a keyword
14677
2a758ffc821e fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents: 14676
diff changeset
205 getargs(x, 0, 0, _("removed takes no arguments"))
31697
992882cef7e1 fileset: perform membership test against set for status queries
Gregory Szorc <gregory.szorc@gmail.com>
parents: 31254
diff changeset
206 s = set(mctx.status().removed)
14677
2a758ffc821e fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents: 14676
diff changeset
207 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
208
27461
afa76585c955 fileset: use decorator to mark a predicate as "status caller"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27460
diff changeset
209 @predicate('deleted()', callstatus=True)
14677
2a758ffc821e fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents: 14676
diff changeset
210 def deleted(mctx, x):
27460
11286ac374f3 fileset: use decorator to mark a function as fileset predicate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27459
diff changeset
211 """Alias for ``missing()``.
14681
0744db5eb51c fileset: add some function help text
Matt Mackall <mpm@selenic.com>
parents: 14680
diff changeset
212 """
14785
0f0bd4d028d3 fileset: add i18n hints for keywords
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 14718
diff changeset
213 # i18n: "deleted" is a keyword
14677
2a758ffc821e fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents: 14676
diff changeset
214 getargs(x, 0, 0, _("deleted takes no arguments"))
31697
992882cef7e1 fileset: perform membership test against set for status queries
Gregory Szorc <gregory.szorc@gmail.com>
parents: 31254
diff changeset
215 s = set(mctx.status().deleted)
14677
2a758ffc821e fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents: 14676
diff changeset
216 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
217
27461
afa76585c955 fileset: use decorator to mark a predicate as "status caller"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27460
diff changeset
218 @predicate('missing()', callstatus=True)
27024
ceef5fb14872 fileset: add missing() predicate (issue4925)
liscju <piotr.listkiewicz@gmail.com>
parents: 26995
diff changeset
219 def missing(mctx, x):
27460
11286ac374f3 fileset: use decorator to mark a function as fileset predicate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27459
diff changeset
220 """File that is missing according to :hg:`status`.
27024
ceef5fb14872 fileset: add missing() predicate (issue4925)
liscju <piotr.listkiewicz@gmail.com>
parents: 26995
diff changeset
221 """
ceef5fb14872 fileset: add missing() predicate (issue4925)
liscju <piotr.listkiewicz@gmail.com>
parents: 26995
diff changeset
222 # i18n: "missing" is a keyword
ceef5fb14872 fileset: add missing() predicate (issue4925)
liscju <piotr.listkiewicz@gmail.com>
parents: 26995
diff changeset
223 getargs(x, 0, 0, _("missing takes no arguments"))
31697
992882cef7e1 fileset: perform membership test against set for status queries
Gregory Szorc <gregory.szorc@gmail.com>
parents: 31254
diff changeset
224 s = set(mctx.status().deleted)
27024
ceef5fb14872 fileset: add missing() predicate (issue4925)
liscju <piotr.listkiewicz@gmail.com>
parents: 26995
diff changeset
225 return [f for f in mctx.subset if f in s]
ceef5fb14872 fileset: add missing() predicate (issue4925)
liscju <piotr.listkiewicz@gmail.com>
parents: 26995
diff changeset
226
27461
afa76585c955 fileset: use decorator to mark a predicate as "status caller"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27460
diff changeset
227 @predicate('unknown()', callstatus=True)
14677
2a758ffc821e fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents: 14676
diff changeset
228 def unknown(mctx, x):
27460
11286ac374f3 fileset: use decorator to mark a function as fileset predicate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27459
diff changeset
229 """File that is unknown according to :hg:`status`. These files will only be
14681
0744db5eb51c fileset: add some function help text
Matt Mackall <mpm@selenic.com>
parents: 14680
diff changeset
230 considered if this predicate is used.
0744db5eb51c fileset: add some function help text
Matt Mackall <mpm@selenic.com>
parents: 14680
diff changeset
231 """
14785
0f0bd4d028d3 fileset: add i18n hints for keywords
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 14718
diff changeset
232 # i18n: "unknown" is a keyword
14677
2a758ffc821e fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents: 14676
diff changeset
233 getargs(x, 0, 0, _("unknown takes no arguments"))
31697
992882cef7e1 fileset: perform membership test against set for status queries
Gregory Szorc <gregory.szorc@gmail.com>
parents: 31254
diff changeset
234 s = set(mctx.status().unknown)
14677
2a758ffc821e fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents: 14676
diff changeset
235 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
236
27461
afa76585c955 fileset: use decorator to mark a predicate as "status caller"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27460
diff changeset
237 @predicate('ignored()', callstatus=True)
14677
2a758ffc821e fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents: 14676
diff changeset
238 def ignored(mctx, x):
27460
11286ac374f3 fileset: use decorator to mark a function as fileset predicate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27459
diff changeset
239 """File that is ignored according to :hg:`status`. These files will only be
14681
0744db5eb51c fileset: add some function help text
Matt Mackall <mpm@selenic.com>
parents: 14680
diff changeset
240 considered if this predicate is used.
0744db5eb51c fileset: add some function help text
Matt Mackall <mpm@selenic.com>
parents: 14680
diff changeset
241 """
14785
0f0bd4d028d3 fileset: add i18n hints for keywords
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 14718
diff changeset
242 # i18n: "ignored" is a keyword
14677
2a758ffc821e fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents: 14676
diff changeset
243 getargs(x, 0, 0, _("ignored takes no arguments"))
31697
992882cef7e1 fileset: perform membership test against set for status queries
Gregory Szorc <gregory.szorc@gmail.com>
parents: 31254
diff changeset
244 s = set(mctx.status().ignored)
14677
2a758ffc821e fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents: 14676
diff changeset
245 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
246
27461
afa76585c955 fileset: use decorator to mark a predicate as "status caller"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27460
diff changeset
247 @predicate('clean()', callstatus=True)
14677
2a758ffc821e fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents: 14676
diff changeset
248 def clean(mctx, x):
27460
11286ac374f3 fileset: use decorator to mark a function as fileset predicate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27459
diff changeset
249 """File that is clean according to :hg:`status`.
14681
0744db5eb51c fileset: add some function help text
Matt Mackall <mpm@selenic.com>
parents: 14680
diff changeset
250 """
14785
0f0bd4d028d3 fileset: add i18n hints for keywords
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 14718
diff changeset
251 # i18n: "clean" is a keyword
14677
2a758ffc821e fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents: 14676
diff changeset
252 getargs(x, 0, 0, _("clean takes no arguments"))
31697
992882cef7e1 fileset: perform membership test against set for status queries
Gregory Szorc <gregory.szorc@gmail.com>
parents: 31254
diff changeset
253 s = set(mctx.status().clean)
14677
2a758ffc821e fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents: 14676
diff changeset
254 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
255
14676
e80fa502b8cf fileset: add some basic predicates
Matt Mackall <mpm@selenic.com>
parents: 14673
diff changeset
256 def func(mctx, a, b):
35691
735f47b41521 fileset: make it robust for bad function calls
Yuya Nishihara <yuya@tcha.org>
parents: 35615
diff changeset
257 funcname = getsymbol(a)
735f47b41521 fileset: make it robust for bad function calls
Yuya Nishihara <yuya@tcha.org>
parents: 35615
diff changeset
258 if funcname in symbols:
27464
c39ecb2b86b3 fileset: detect unintentional existing() invocation at runtime
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27463
diff changeset
259 enabled = mctx._existingenabled
c39ecb2b86b3 fileset: detect unintentional existing() invocation at runtime
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27463
diff changeset
260 mctx._existingenabled = funcname in _existingcallers
c39ecb2b86b3 fileset: detect unintentional existing() invocation at runtime
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27463
diff changeset
261 try:
c39ecb2b86b3 fileset: detect unintentional existing() invocation at runtime
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27463
diff changeset
262 return symbols[funcname](mctx, b)
c39ecb2b86b3 fileset: detect unintentional existing() invocation at runtime
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27463
diff changeset
263 finally:
c39ecb2b86b3 fileset: detect unintentional existing() invocation at runtime
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27463
diff changeset
264 mctx._existingenabled = enabled
25633
0f44d35731d6 fileset: don't suggest private or undocumented queries
Matt Harbison <matt_harbison@yahoo.com>
parents: 25255
diff changeset
265
0f44d35731d6 fileset: don't suggest private or undocumented queries
Matt Harbison <matt_harbison@yahoo.com>
parents: 25255
diff changeset
266 keep = lambda fn: getattr(fn, '__doc__', None) is not None
0f44d35731d6 fileset: don't suggest private or undocumented queries
Matt Harbison <matt_harbison@yahoo.com>
parents: 25255
diff changeset
267
0f44d35731d6 fileset: don't suggest private or undocumented queries
Matt Harbison <matt_harbison@yahoo.com>
parents: 25255
diff changeset
268 syms = [s for (s, fn) in symbols.items() if keep(fn)]
35691
735f47b41521 fileset: make it robust for bad function calls
Yuya Nishihara <yuya@tcha.org>
parents: 35615
diff changeset
269 raise error.UnknownIdentifier(funcname, syms)
14676
e80fa502b8cf fileset: add some basic predicates
Matt Mackall <mpm@selenic.com>
parents: 14673
diff changeset
270
e80fa502b8cf fileset: add some basic predicates
Matt Mackall <mpm@selenic.com>
parents: 14673
diff changeset
271 def getlist(x):
e80fa502b8cf fileset: add some basic predicates
Matt Mackall <mpm@selenic.com>
parents: 14673
diff changeset
272 if not x:
e80fa502b8cf fileset: add some basic predicates
Matt Mackall <mpm@selenic.com>
parents: 14673
diff changeset
273 return []
e80fa502b8cf fileset: add some basic predicates
Matt Mackall <mpm@selenic.com>
parents: 14673
diff changeset
274 if x[0] == 'list':
e80fa502b8cf fileset: add some basic predicates
Matt Mackall <mpm@selenic.com>
parents: 14673
diff changeset
275 return getlist(x[1]) + [x[2]]
e80fa502b8cf fileset: add some basic predicates
Matt Mackall <mpm@selenic.com>
parents: 14673
diff changeset
276 return [x]
e80fa502b8cf fileset: add some basic predicates
Matt Mackall <mpm@selenic.com>
parents: 14673
diff changeset
277
e80fa502b8cf fileset: add some basic predicates
Matt Mackall <mpm@selenic.com>
parents: 14673
diff changeset
278 def getargs(x, min, max, err):
e80fa502b8cf fileset: add some basic predicates
Matt Mackall <mpm@selenic.com>
parents: 14673
diff changeset
279 l = getlist(x)
e80fa502b8cf fileset: add some basic predicates
Matt Mackall <mpm@selenic.com>
parents: 14673
diff changeset
280 if len(l) < min or len(l) > max:
e80fa502b8cf fileset: add some basic predicates
Matt Mackall <mpm@selenic.com>
parents: 14673
diff changeset
281 raise error.ParseError(err)
e80fa502b8cf fileset: add some basic predicates
Matt Mackall <mpm@selenic.com>
parents: 14673
diff changeset
282 return l
e80fa502b8cf fileset: add some basic predicates
Matt Mackall <mpm@selenic.com>
parents: 14673
diff changeset
283
27462
470ea34ba593 fileset: use decorator to mark a predicate as "existing caller"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27461
diff changeset
284 @predicate('binary()', callexisting=True)
14676
e80fa502b8cf fileset: add some basic predicates
Matt Mackall <mpm@selenic.com>
parents: 14673
diff changeset
285 def binary(mctx, x):
27460
11286ac374f3 fileset: use decorator to mark a function as fileset predicate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27459
diff changeset
286 """File that appears to be binary (contains NUL bytes).
14681
0744db5eb51c fileset: add some function help text
Matt Mackall <mpm@selenic.com>
parents: 14680
diff changeset
287 """
14785
0f0bd4d028d3 fileset: add i18n hints for keywords
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 14718
diff changeset
288 # i18n: "binary" is a keyword
14676
e80fa502b8cf fileset: add some basic predicates
Matt Mackall <mpm@selenic.com>
parents: 14673
diff changeset
289 getargs(x, 0, 0, _("binary takes no arguments"))
32134
4240be02df79 fileset: use fctx.isbinary instead of util.binary(fctx.data())
Jun Wu <quark@fb.com>
parents: 31697
diff changeset
290 return [f for f in mctx.existing() if mctx.ctx[f].isbinary()]
14676
e80fa502b8cf fileset: add some basic predicates
Matt Mackall <mpm@selenic.com>
parents: 14673
diff changeset
291
27462
470ea34ba593 fileset: use decorator to mark a predicate as "existing caller"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27461
diff changeset
292 @predicate('exec()', callexisting=True)
14676
e80fa502b8cf fileset: add some basic predicates
Matt Mackall <mpm@selenic.com>
parents: 14673
diff changeset
293 def exec_(mctx, x):
27460
11286ac374f3 fileset: use decorator to mark a function as fileset predicate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27459
diff changeset
294 """File that is marked as executable.
14681
0744db5eb51c fileset: add some function help text
Matt Mackall <mpm@selenic.com>
parents: 14680
diff changeset
295 """
14785
0f0bd4d028d3 fileset: add i18n hints for keywords
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 14718
diff changeset
296 # i18n: "exec" is a keyword
14676
e80fa502b8cf fileset: add some basic predicates
Matt Mackall <mpm@selenic.com>
parents: 14673
diff changeset
297 getargs(x, 0, 0, _("exec takes no arguments"))
15963
042e84e39dee fileset: don't attempt to check data predicates against removed files
Matt Mackall <mpm@selenic.com>
parents: 14830
diff changeset
298 return [f for f in mctx.existing() if mctx.ctx.flags(f) == 'x']
14676
e80fa502b8cf fileset: add some basic predicates
Matt Mackall <mpm@selenic.com>
parents: 14673
diff changeset
299
27462
470ea34ba593 fileset: use decorator to mark a predicate as "existing caller"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27461
diff changeset
300 @predicate('symlink()', callexisting=True)
14676
e80fa502b8cf fileset: add some basic predicates
Matt Mackall <mpm@selenic.com>
parents: 14673
diff changeset
301 def symlink(mctx, x):
27460
11286ac374f3 fileset: use decorator to mark a function as fileset predicate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27459
diff changeset
302 """File that is marked as a symlink.
14681
0744db5eb51c fileset: add some function help text
Matt Mackall <mpm@selenic.com>
parents: 14680
diff changeset
303 """
14785
0f0bd4d028d3 fileset: add i18n hints for keywords
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 14718
diff changeset
304 # i18n: "symlink" is a keyword
14676
e80fa502b8cf fileset: add some basic predicates
Matt Mackall <mpm@selenic.com>
parents: 14673
diff changeset
305 getargs(x, 0, 0, _("symlink takes no arguments"))
15963
042e84e39dee fileset: don't attempt to check data predicates against removed files
Matt Mackall <mpm@selenic.com>
parents: 14830
diff changeset
306 return [f for f in mctx.existing() if mctx.ctx.flags(f) == 'l']
14676
e80fa502b8cf fileset: add some basic predicates
Matt Mackall <mpm@selenic.com>
parents: 14673
diff changeset
307
27460
11286ac374f3 fileset: use decorator to mark a function as fileset predicate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27459
diff changeset
308 @predicate('resolved()')
14679
e141e1cee0cc fileset: add resolved and unresolved predicates
Matt Mackall <mpm@selenic.com>
parents: 14678
diff changeset
309 def resolved(mctx, x):
27460
11286ac374f3 fileset: use decorator to mark a function as fileset predicate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27459
diff changeset
310 """File that is marked resolved according to :hg:`resolve -l`.
14681
0744db5eb51c fileset: add some function help text
Matt Mackall <mpm@selenic.com>
parents: 14680
diff changeset
311 """
14785
0f0bd4d028d3 fileset: add i18n hints for keywords
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 14718
diff changeset
312 # i18n: "resolved" is a keyword
14679
e141e1cee0cc fileset: add resolved and unresolved predicates
Matt Mackall <mpm@selenic.com>
parents: 14678
diff changeset
313 getargs(x, 0, 0, _("resolved takes no arguments"))
e141e1cee0cc fileset: add resolved and unresolved predicates
Matt Mackall <mpm@selenic.com>
parents: 14678
diff changeset
314 if mctx.ctx.rev() is not None:
e141e1cee0cc fileset: add resolved and unresolved predicates
Matt Mackall <mpm@selenic.com>
parents: 14678
diff changeset
315 return []
26995
d5a6be56970b fileset: switch to mergestate.read()
Siddharth Agarwal <sid0@fb.com>
parents: 26587
diff changeset
316 ms = merge.mergestate.read(mctx.ctx.repo())
14679
e141e1cee0cc fileset: add resolved and unresolved predicates
Matt Mackall <mpm@selenic.com>
parents: 14678
diff changeset
317 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
318
27460
11286ac374f3 fileset: use decorator to mark a function as fileset predicate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27459
diff changeset
319 @predicate('unresolved()')
14679
e141e1cee0cc fileset: add resolved and unresolved predicates
Matt Mackall <mpm@selenic.com>
parents: 14678
diff changeset
320 def unresolved(mctx, x):
27460
11286ac374f3 fileset: use decorator to mark a function as fileset predicate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27459
diff changeset
321 """File that is marked unresolved according to :hg:`resolve -l`.
14681
0744db5eb51c fileset: add some function help text
Matt Mackall <mpm@selenic.com>
parents: 14680
diff changeset
322 """
14785
0f0bd4d028d3 fileset: add i18n hints for keywords
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 14718
diff changeset
323 # i18n: "unresolved" is a keyword
14679
e141e1cee0cc fileset: add resolved and unresolved predicates
Matt Mackall <mpm@selenic.com>
parents: 14678
diff changeset
324 getargs(x, 0, 0, _("unresolved takes no arguments"))
e141e1cee0cc fileset: add resolved and unresolved predicates
Matt Mackall <mpm@selenic.com>
parents: 14678
diff changeset
325 if mctx.ctx.rev() is not None:
e141e1cee0cc fileset: add resolved and unresolved predicates
Matt Mackall <mpm@selenic.com>
parents: 14678
diff changeset
326 return []
26995
d5a6be56970b fileset: switch to mergestate.read()
Siddharth Agarwal <sid0@fb.com>
parents: 26587
diff changeset
327 ms = merge.mergestate.read(mctx.ctx.repo())
14679
e141e1cee0cc fileset: add resolved and unresolved predicates
Matt Mackall <mpm@selenic.com>
parents: 14678
diff changeset
328 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
329
27460
11286ac374f3 fileset: use decorator to mark a function as fileset predicate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27459
diff changeset
330 @predicate('hgignore()')
14680
49af5fa3809b fileset: add hgignore
Matt Mackall <mpm@selenic.com>
parents: 14679
diff changeset
331 def hgignore(mctx, x):
27460
11286ac374f3 fileset: use decorator to mark a function as fileset predicate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27459
diff changeset
332 """File that matches the active .hgignore pattern.
14681
0744db5eb51c fileset: add some function help text
Matt Mackall <mpm@selenic.com>
parents: 14680
diff changeset
333 """
23113
c2dd79ad99cb i18n: add i18n comment to error messages of filesets predicates
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 22924
diff changeset
334 # i18n: "hgignore" is a keyword
14680
49af5fa3809b fileset: add hgignore
Matt Mackall <mpm@selenic.com>
parents: 14679
diff changeset
335 getargs(x, 0, 0, _("hgignore takes no arguments"))
24334
eda2f36889b5 fileset: replace 'ctx._repo' with 'ctx.repo()'
Matt Harbison <matt_harbison@yahoo.com>
parents: 24218
diff changeset
336 ignore = mctx.ctx.repo().dirstate._ignore
14680
49af5fa3809b fileset: add hgignore
Matt Mackall <mpm@selenic.com>
parents: 14679
diff changeset
337 return [f for f in mctx.subset if ignore(f)]
49af5fa3809b fileset: add hgignore
Matt Mackall <mpm@selenic.com>
parents: 14679
diff changeset
338
27460
11286ac374f3 fileset: use decorator to mark a function as fileset predicate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27459
diff changeset
339 @predicate('portable()')
24408
caa6b6c65dc3 fileset: add a fileset for portable filenames
Siddharth Agarwal <sid0@fb.com>
parents: 24334
diff changeset
340 def portable(mctx, x):
27460
11286ac374f3 fileset: use decorator to mark a function as fileset predicate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27459
diff changeset
341 """File that has a portable name. (This doesn't include filenames with case
24408
caa6b6c65dc3 fileset: add a fileset for portable filenames
Siddharth Agarwal <sid0@fb.com>
parents: 24334
diff changeset
342 collisions.)
caa6b6c65dc3 fileset: add a fileset for portable filenames
Siddharth Agarwal <sid0@fb.com>
parents: 24334
diff changeset
343 """
caa6b6c65dc3 fileset: add a fileset for portable filenames
Siddharth Agarwal <sid0@fb.com>
parents: 24334
diff changeset
344 # i18n: "portable" is a keyword
caa6b6c65dc3 fileset: add a fileset for portable filenames
Siddharth Agarwal <sid0@fb.com>
parents: 24334
diff changeset
345 getargs(x, 0, 0, _("portable takes no arguments"))
caa6b6c65dc3 fileset: add a fileset for portable filenames
Siddharth Agarwal <sid0@fb.com>
parents: 24334
diff changeset
346 checkwinfilename = util.checkwinfilename
caa6b6c65dc3 fileset: add a fileset for portable filenames
Siddharth Agarwal <sid0@fb.com>
parents: 24334
diff changeset
347 return [f for f in mctx.subset if checkwinfilename(f) is None]
caa6b6c65dc3 fileset: add a fileset for portable filenames
Siddharth Agarwal <sid0@fb.com>
parents: 24334
diff changeset
348
27462
470ea34ba593 fileset: use decorator to mark a predicate as "existing caller"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27461
diff changeset
349 @predicate('grep(regex)', callexisting=True)
14682
8785fd757077 fileset: add grep predicate
Matt Mackall <mpm@selenic.com>
parents: 14681
diff changeset
350 def grep(mctx, x):
27460
11286ac374f3 fileset: use decorator to mark a function as fileset predicate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27459
diff changeset
351 """File contains the given regular expression.
14682
8785fd757077 fileset: add grep predicate
Matt Mackall <mpm@selenic.com>
parents: 14681
diff changeset
352 """
17368
01cc267fc105 fileset: do not traceback on invalid grep pattern
Patrick Mezard <patrick@mezard.eu>
parents: 17367
diff changeset
353 try:
01cc267fc105 fileset: do not traceback on invalid grep pattern
Patrick Mezard <patrick@mezard.eu>
parents: 17367
diff changeset
354 # i18n: "grep" is a keyword
01cc267fc105 fileset: do not traceback on invalid grep pattern
Patrick Mezard <patrick@mezard.eu>
parents: 17367
diff changeset
355 r = re.compile(getstring(x, _("grep requires a pattern")))
25660
328739ea70c3 global: mass rewrite to use modern exception syntax
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25654
diff changeset
356 except re.error as e:
17368
01cc267fc105 fileset: do not traceback on invalid grep pattern
Patrick Mezard <patrick@mezard.eu>
parents: 17367
diff changeset
357 raise error.ParseError(_('invalid match pattern: %s') % e)
15963
042e84e39dee fileset: don't attempt to check data predicates against removed files
Matt Mackall <mpm@selenic.com>
parents: 14830
diff changeset
358 return [f for f in mctx.existing() if r.search(mctx.ctx[f].data())]
14682
8785fd757077 fileset: add grep predicate
Matt Mackall <mpm@selenic.com>
parents: 14681
diff changeset
359
14683
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
360 def _sizetomax(s):
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
361 try:
25925
23c4589fc678 filesets: ignore unit case in size() predicate for single value
Anton Shestakov <av6@dwimlabs.net>
parents: 25815
diff changeset
362 s = s.strip().lower()
19194
1d08df65cd3c util: migrate fileset._sizetoint to util.sizetoint
Bryan O'Sullivan <bryano@fb.com>
parents: 18842
diff changeset
363 for k, v in util._sizeunits:
14683
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
364 if s.endswith(k):
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
365 # max(4k) = 5k - 1, max(4.5k) = 4.6k - 1
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
366 n = s[:-len(k)]
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
367 inc = 1.0
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
368 if "." in n:
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
369 inc /= 10 ** len(n.split(".")[1])
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
370 return int((float(n) + inc) * v) - 1
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
371 # no extension, this is a precise value
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
372 return int(s)
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
373 except ValueError:
14716
552329013bac fileset: use ParseError pos field correctly
Mads Kiilerich <mads@kiilerich.com>
parents: 14701
diff changeset
374 raise error.ParseError(_("couldn't parse size: %s") % s)
14683
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
375
35615
0e369eca888f fileset: split the logic for matching a size expression to a separate method
Matt Harbison <matt_harbison@yahoo.com>
parents: 32523
diff changeset
376 def sizematcher(x):
0e369eca888f fileset: split the logic for matching a size expression to a separate method
Matt Harbison <matt_harbison@yahoo.com>
parents: 32523
diff changeset
377 """Return a function(size) -> bool from the ``size()`` expression"""
0e369eca888f fileset: split the logic for matching a size expression to a separate method
Matt Harbison <matt_harbison@yahoo.com>
parents: 32523
diff changeset
378
0e369eca888f fileset: split the logic for matching a size expression to a separate method
Matt Harbison <matt_harbison@yahoo.com>
parents: 32523
diff changeset
379 # i18n: "size" is a keyword
0e369eca888f fileset: split the logic for matching a size expression to a separate method
Matt Harbison <matt_harbison@yahoo.com>
parents: 32523
diff changeset
380 expr = getstring(x, _("size requires an expression")).strip()
0e369eca888f fileset: split the logic for matching a size expression to a separate method
Matt Harbison <matt_harbison@yahoo.com>
parents: 32523
diff changeset
381 if '-' in expr: # do we have a range?
0e369eca888f fileset: split the logic for matching a size expression to a separate method
Matt Harbison <matt_harbison@yahoo.com>
parents: 32523
diff changeset
382 a, b = expr.split('-', 1)
0e369eca888f fileset: split the logic for matching a size expression to a separate method
Matt Harbison <matt_harbison@yahoo.com>
parents: 32523
diff changeset
383 a = util.sizetoint(a)
0e369eca888f fileset: split the logic for matching a size expression to a separate method
Matt Harbison <matt_harbison@yahoo.com>
parents: 32523
diff changeset
384 b = util.sizetoint(b)
0e369eca888f fileset: split the logic for matching a size expression to a separate method
Matt Harbison <matt_harbison@yahoo.com>
parents: 32523
diff changeset
385 return lambda x: x >= a and x <= b
0e369eca888f fileset: split the logic for matching a size expression to a separate method
Matt Harbison <matt_harbison@yahoo.com>
parents: 32523
diff changeset
386 elif expr.startswith("<="):
0e369eca888f fileset: split the logic for matching a size expression to a separate method
Matt Harbison <matt_harbison@yahoo.com>
parents: 32523
diff changeset
387 a = util.sizetoint(expr[2:])
0e369eca888f fileset: split the logic for matching a size expression to a separate method
Matt Harbison <matt_harbison@yahoo.com>
parents: 32523
diff changeset
388 return lambda x: x <= a
0e369eca888f fileset: split the logic for matching a size expression to a separate method
Matt Harbison <matt_harbison@yahoo.com>
parents: 32523
diff changeset
389 elif expr.startswith("<"):
0e369eca888f fileset: split the logic for matching a size expression to a separate method
Matt Harbison <matt_harbison@yahoo.com>
parents: 32523
diff changeset
390 a = util.sizetoint(expr[1:])
0e369eca888f fileset: split the logic for matching a size expression to a separate method
Matt Harbison <matt_harbison@yahoo.com>
parents: 32523
diff changeset
391 return lambda x: x < a
0e369eca888f fileset: split the logic for matching a size expression to a separate method
Matt Harbison <matt_harbison@yahoo.com>
parents: 32523
diff changeset
392 elif expr.startswith(">="):
0e369eca888f fileset: split the logic for matching a size expression to a separate method
Matt Harbison <matt_harbison@yahoo.com>
parents: 32523
diff changeset
393 a = util.sizetoint(expr[2:])
0e369eca888f fileset: split the logic for matching a size expression to a separate method
Matt Harbison <matt_harbison@yahoo.com>
parents: 32523
diff changeset
394 return lambda x: x >= a
0e369eca888f fileset: split the logic for matching a size expression to a separate method
Matt Harbison <matt_harbison@yahoo.com>
parents: 32523
diff changeset
395 elif expr.startswith(">"):
0e369eca888f fileset: split the logic for matching a size expression to a separate method
Matt Harbison <matt_harbison@yahoo.com>
parents: 32523
diff changeset
396 a = util.sizetoint(expr[1:])
0e369eca888f fileset: split the logic for matching a size expression to a separate method
Matt Harbison <matt_harbison@yahoo.com>
parents: 32523
diff changeset
397 return lambda x: x > a
36505
db33c5bc781f fileset: drop bad "elif:" trying to check invalid size expression
Yuya Nishihara <yuya@tcha.org>
parents: 36473
diff changeset
398 else:
35615
0e369eca888f fileset: split the logic for matching a size expression to a separate method
Matt Harbison <matt_harbison@yahoo.com>
parents: 32523
diff changeset
399 a = util.sizetoint(expr)
0e369eca888f fileset: split the logic for matching a size expression to a separate method
Matt Harbison <matt_harbison@yahoo.com>
parents: 32523
diff changeset
400 b = _sizetomax(expr)
0e369eca888f fileset: split the logic for matching a size expression to a separate method
Matt Harbison <matt_harbison@yahoo.com>
parents: 32523
diff changeset
401 return lambda x: x >= a and x <= b
0e369eca888f fileset: split the logic for matching a size expression to a separate method
Matt Harbison <matt_harbison@yahoo.com>
parents: 32523
diff changeset
402
27462
470ea34ba593 fileset: use decorator to mark a predicate as "existing caller"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27461
diff changeset
403 @predicate('size(expression)', callexisting=True)
14683
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
404 def size(mctx, x):
27460
11286ac374f3 fileset: use decorator to mark a function as fileset predicate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27459
diff changeset
405 """File size matches the given expression. Examples:
14683
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
406
29987
d532ef155b0e help: clarify quotes are needed for filesets.size expressions
timeless <timeless@mozdev.org>
parents: 28448
diff changeset
407 - size('1k') - files from 1024 to 2047 bytes
d532ef155b0e help: clarify quotes are needed for filesets.size expressions
timeless <timeless@mozdev.org>
parents: 28448
diff changeset
408 - size('< 20k') - files less than 20480 bytes
d532ef155b0e help: clarify quotes are needed for filesets.size expressions
timeless <timeless@mozdev.org>
parents: 28448
diff changeset
409 - size('>= .5MB') - files at least 524288 bytes
d532ef155b0e help: clarify quotes are needed for filesets.size expressions
timeless <timeless@mozdev.org>
parents: 28448
diff changeset
410 - size('4k - 1MB') - files from 4096 bytes to 1048576 bytes
14683
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
411 """
35615
0e369eca888f fileset: split the logic for matching a size expression to a separate method
Matt Harbison <matt_harbison@yahoo.com>
parents: 32523
diff changeset
412 m = sizematcher(x)
15963
042e84e39dee fileset: don't attempt to check data predicates against removed files
Matt Mackall <mpm@selenic.com>
parents: 14830
diff changeset
413 return [f for f in mctx.existing() if m(mctx.ctx[f].size())]
14683
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
414
27462
470ea34ba593 fileset: use decorator to mark a predicate as "existing caller"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27461
diff changeset
415 @predicate('encoding(name)', callexisting=True)
14684
87b9d6a7d807 fileset: add encoding() predicate
Matt Mackall <mpm@selenic.com>
parents: 14683
diff changeset
416 def encoding(mctx, x):
27460
11286ac374f3 fileset: use decorator to mark a function as fileset predicate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27459
diff changeset
417 """File can be successfully decoded with the given character
14684
87b9d6a7d807 fileset: add encoding() predicate
Matt Mackall <mpm@selenic.com>
parents: 14683
diff changeset
418 encoding. May not be useful for encodings other than ASCII and
87b9d6a7d807 fileset: add encoding() predicate
Matt Mackall <mpm@selenic.com>
parents: 14683
diff changeset
419 UTF-8.
87b9d6a7d807 fileset: add encoding() predicate
Matt Mackall <mpm@selenic.com>
parents: 14683
diff changeset
420 """
87b9d6a7d807 fileset: add encoding() predicate
Matt Mackall <mpm@selenic.com>
parents: 14683
diff changeset
421
14785
0f0bd4d028d3 fileset: add i18n hints for keywords
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 14718
diff changeset
422 # i18n: "encoding" is a keyword
14684
87b9d6a7d807 fileset: add encoding() predicate
Matt Mackall <mpm@selenic.com>
parents: 14683
diff changeset
423 enc = getstring(x, _("encoding requires an encoding name"))
87b9d6a7d807 fileset: add encoding() predicate
Matt Mackall <mpm@selenic.com>
parents: 14683
diff changeset
424
87b9d6a7d807 fileset: add encoding() predicate
Matt Mackall <mpm@selenic.com>
parents: 14683
diff changeset
425 s = []
15963
042e84e39dee fileset: don't attempt to check data predicates against removed files
Matt Mackall <mpm@selenic.com>
parents: 14830
diff changeset
426 for f in mctx.existing():
14684
87b9d6a7d807 fileset: add encoding() predicate
Matt Mackall <mpm@selenic.com>
parents: 14683
diff changeset
427 d = mctx.ctx[f].data()
87b9d6a7d807 fileset: add encoding() predicate
Matt Mackall <mpm@selenic.com>
parents: 14683
diff changeset
428 try:
87b9d6a7d807 fileset: add encoding() predicate
Matt Mackall <mpm@selenic.com>
parents: 14683
diff changeset
429 d.decode(enc)
87b9d6a7d807 fileset: add encoding() predicate
Matt Mackall <mpm@selenic.com>
parents: 14683
diff changeset
430 except LookupError:
26587
56b2bcea2529 error: get Abort from 'error' instead of 'util'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26233
diff changeset
431 raise error.Abort(_("unknown encoding '%s'") % enc)
14684
87b9d6a7d807 fileset: add encoding() predicate
Matt Mackall <mpm@selenic.com>
parents: 14683
diff changeset
432 except UnicodeDecodeError:
87b9d6a7d807 fileset: add encoding() predicate
Matt Mackall <mpm@selenic.com>
parents: 14683
diff changeset
433 continue
87b9d6a7d807 fileset: add encoding() predicate
Matt Mackall <mpm@selenic.com>
parents: 14683
diff changeset
434 s.append(f)
87b9d6a7d807 fileset: add encoding() predicate
Matt Mackall <mpm@selenic.com>
parents: 14683
diff changeset
435
87b9d6a7d807 fileset: add encoding() predicate
Matt Mackall <mpm@selenic.com>
parents: 14683
diff changeset
436 return s
87b9d6a7d807 fileset: add encoding() predicate
Matt Mackall <mpm@selenic.com>
parents: 14683
diff changeset
437
27462
470ea34ba593 fileset: use decorator to mark a predicate as "existing caller"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27461
diff changeset
438 @predicate('eol(style)', callexisting=True)
18842
3ce3f2b059a1 filesets: add eol predicate
Matt Mackall <mpm@selenic.com>
parents: 18364
diff changeset
439 def eol(mctx, x):
27460
11286ac374f3 fileset: use decorator to mark a function as fileset predicate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27459
diff changeset
440 """File contains newlines of the given style (dos, unix, mac). Binary
18842
3ce3f2b059a1 filesets: add eol predicate
Matt Mackall <mpm@selenic.com>
parents: 18364
diff changeset
441 files are excluded, files with mixed line endings match multiple
3ce3f2b059a1 filesets: add eol predicate
Matt Mackall <mpm@selenic.com>
parents: 18364
diff changeset
442 styles.
3ce3f2b059a1 filesets: add eol predicate
Matt Mackall <mpm@selenic.com>
parents: 18364
diff changeset
443 """
3ce3f2b059a1 filesets: add eol predicate
Matt Mackall <mpm@selenic.com>
parents: 18364
diff changeset
444
28056
4f8ced23345e fileset: fix copy/paste in eol() error message
Matt Harbison <matt_harbison@yahoo.com>
parents: 27518
diff changeset
445 # i18n: "eol" is a keyword
4f8ced23345e fileset: fix copy/paste in eol() error message
Matt Harbison <matt_harbison@yahoo.com>
parents: 27518
diff changeset
446 enc = getstring(x, _("eol requires a style name"))
18842
3ce3f2b059a1 filesets: add eol predicate
Matt Mackall <mpm@selenic.com>
parents: 18364
diff changeset
447
3ce3f2b059a1 filesets: add eol predicate
Matt Mackall <mpm@selenic.com>
parents: 18364
diff changeset
448 s = []
3ce3f2b059a1 filesets: add eol predicate
Matt Mackall <mpm@selenic.com>
parents: 18364
diff changeset
449 for f in mctx.existing():
3ce3f2b059a1 filesets: add eol predicate
Matt Mackall <mpm@selenic.com>
parents: 18364
diff changeset
450 d = mctx.ctx[f].data()
37084
f0b6fbea00cf stringutil: bulk-replace call sites to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 36505
diff changeset
451 if stringutil.binary(d):
18842
3ce3f2b059a1 filesets: add eol predicate
Matt Mackall <mpm@selenic.com>
parents: 18364
diff changeset
452 continue
3ce3f2b059a1 filesets: add eol predicate
Matt Mackall <mpm@selenic.com>
parents: 18364
diff changeset
453 if (enc == 'dos' or enc == 'win') and '\r\n' in d:
3ce3f2b059a1 filesets: add eol predicate
Matt Mackall <mpm@selenic.com>
parents: 18364
diff changeset
454 s.append(f)
3ce3f2b059a1 filesets: add eol predicate
Matt Mackall <mpm@selenic.com>
parents: 18364
diff changeset
455 elif enc == 'unix' and re.search('(?<!\r)\n', d):
3ce3f2b059a1 filesets: add eol predicate
Matt Mackall <mpm@selenic.com>
parents: 18364
diff changeset
456 s.append(f)
3ce3f2b059a1 filesets: add eol predicate
Matt Mackall <mpm@selenic.com>
parents: 18364
diff changeset
457 elif enc == 'mac' and re.search('\r(?!\n)', d):
3ce3f2b059a1 filesets: add eol predicate
Matt Mackall <mpm@selenic.com>
parents: 18364
diff changeset
458 s.append(f)
3ce3f2b059a1 filesets: add eol predicate
Matt Mackall <mpm@selenic.com>
parents: 18364
diff changeset
459 return s
3ce3f2b059a1 filesets: add eol predicate
Matt Mackall <mpm@selenic.com>
parents: 18364
diff changeset
460
27460
11286ac374f3 fileset: use decorator to mark a function as fileset predicate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27459
diff changeset
461 @predicate('copied()')
14685
394121d9f4fc fileset: add copied predicate
Matt Mackall <mpm@selenic.com>
parents: 14684
diff changeset
462 def copied(mctx, x):
27460
11286ac374f3 fileset: use decorator to mark a function as fileset predicate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27459
diff changeset
463 """File that is recorded as being copied.
14685
394121d9f4fc fileset: add copied predicate
Matt Mackall <mpm@selenic.com>
parents: 14684
diff changeset
464 """
14785
0f0bd4d028d3 fileset: add i18n hints for keywords
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 14718
diff changeset
465 # i18n: "copied" is a keyword
14718
0c81948636f3 fileset: copied takes no arguments
Mads Kiilerich <mads@kiilerich.com>
parents: 14717
diff changeset
466 getargs(x, 0, 0, _("copied takes no arguments"))
14685
394121d9f4fc fileset: add copied predicate
Matt Mackall <mpm@selenic.com>
parents: 14684
diff changeset
467 s = []
394121d9f4fc fileset: add copied predicate
Matt Mackall <mpm@selenic.com>
parents: 14684
diff changeset
468 for f in mctx.subset:
35950
7b2b82f891bf fileset: don't abort when running copied() on a revision with a removed file
Matt Harbison <matt_harbison@yahoo.com>
parents: 35741
diff changeset
469 if f in mctx.ctx:
7b2b82f891bf fileset: don't abort when running copied() on a revision with a removed file
Matt Harbison <matt_harbison@yahoo.com>
parents: 35741
diff changeset
470 p = mctx.ctx[f].parents()
7b2b82f891bf fileset: don't abort when running copied() on a revision with a removed file
Matt Harbison <matt_harbison@yahoo.com>
parents: 35741
diff changeset
471 if p and p[0].path() != f:
7b2b82f891bf fileset: don't abort when running copied() on a revision with a removed file
Matt Harbison <matt_harbison@yahoo.com>
parents: 35741
diff changeset
472 s.append(f)
14685
394121d9f4fc fileset: add copied predicate
Matt Mackall <mpm@selenic.com>
parents: 14684
diff changeset
473 return s
394121d9f4fc fileset: add copied predicate
Matt Mackall <mpm@selenic.com>
parents: 14684
diff changeset
474
31193
4140d49d2efb fileset: add revs(revs, fileset) to evaluate set in working directory
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31192
diff changeset
475 @predicate('revs(revs, pattern)')
4140d49d2efb fileset: add revs(revs, fileset) to evaluate set in working directory
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31192
diff changeset
476 def revs(mctx, x):
31254
2140e12d3258 fileset: drop false function signatures from revs() and status() docs
Yuya Nishihara <yuya@tcha.org>
parents: 31195
diff changeset
477 """Evaluate set in the specified revisions. If the revset match multiple
2140e12d3258 fileset: drop false function signatures from revs() and status() docs
Yuya Nishihara <yuya@tcha.org>
parents: 31195
diff changeset
478 revs, this will return file matching pattern in any of the revision.
31193
4140d49d2efb fileset: add revs(revs, fileset) to evaluate set in working directory
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31192
diff changeset
479 """
4140d49d2efb fileset: add revs(revs, fileset) to evaluate set in working directory
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31192
diff changeset
480 # i18n: "revs" is a keyword
4140d49d2efb fileset: add revs(revs, fileset) to evaluate set in working directory
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31192
diff changeset
481 r, x = getargs(x, 2, 2, _("revs takes two arguments"))
4140d49d2efb fileset: add revs(revs, fileset) to evaluate set in working directory
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31192
diff changeset
482 # i18n: "revs" is a keyword
4140d49d2efb fileset: add revs(revs, fileset) to evaluate set in working directory
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31192
diff changeset
483 revspec = getstring(r, _("first argument to revs must be a revision"))
4140d49d2efb fileset: add revs(revs, fileset) to evaluate set in working directory
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31192
diff changeset
484 repo = mctx.ctx.repo()
4140d49d2efb fileset: add revs(revs, fileset) to evaluate set in working directory
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31192
diff changeset
485 revs = scmutil.revrange(repo, [revspec])
4140d49d2efb fileset: add revs(revs, fileset) to evaluate set in working directory
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31192
diff changeset
486
4140d49d2efb fileset: add revs(revs, fileset) to evaluate set in working directory
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31192
diff changeset
487 found = set()
4140d49d2efb fileset: add revs(revs, fileset) to evaluate set in working directory
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31192
diff changeset
488 result = []
4140d49d2efb fileset: add revs(revs, fileset) to evaluate set in working directory
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31192
diff changeset
489 for r in revs:
4140d49d2efb fileset: add revs(revs, fileset) to evaluate set in working directory
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31192
diff changeset
490 ctx = repo[r]
4140d49d2efb fileset: add revs(revs, fileset) to evaluate set in working directory
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31192
diff changeset
491 for f in getset(mctx.switch(ctx, _buildstatus(ctx, x)), x):
4140d49d2efb fileset: add revs(revs, fileset) to evaluate set in working directory
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31192
diff changeset
492 if f not in found:
4140d49d2efb fileset: add revs(revs, fileset) to evaluate set in working directory
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31192
diff changeset
493 found.add(f)
4140d49d2efb fileset: add revs(revs, fileset) to evaluate set in working directory
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31192
diff changeset
494 result.append(f)
4140d49d2efb fileset: add revs(revs, fileset) to evaluate set in working directory
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31192
diff changeset
495 return result
4140d49d2efb fileset: add revs(revs, fileset) to evaluate set in working directory
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31192
diff changeset
496
31195
6b098ac4542e fileset: add a 'status(...)' predicate to control evaluation context
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31194
diff changeset
497 @predicate('status(base, rev, pattern)')
6b098ac4542e fileset: add a 'status(...)' predicate to control evaluation context
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31194
diff changeset
498 def status(mctx, x):
31254
2140e12d3258 fileset: drop false function signatures from revs() and status() docs
Yuya Nishihara <yuya@tcha.org>
parents: 31195
diff changeset
499 """Evaluate predicate using status change between ``base`` and
31195
6b098ac4542e fileset: add a 'status(...)' predicate to control evaluation context
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31194
diff changeset
500 ``rev``. Examples:
6b098ac4542e fileset: add a 'status(...)' predicate to control evaluation context
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31194
diff changeset
501
6b098ac4542e fileset: add a 'status(...)' predicate to control evaluation context
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31194
diff changeset
502 - ``status(3, 7, added())`` - matches files added from "3" to "7"
6b098ac4542e fileset: add a 'status(...)' predicate to control evaluation context
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31194
diff changeset
503 """
6b098ac4542e fileset: add a 'status(...)' predicate to control evaluation context
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31194
diff changeset
504 repo = mctx.ctx.repo()
6b098ac4542e fileset: add a 'status(...)' predicate to control evaluation context
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31194
diff changeset
505 # i18n: "status" is a keyword
6b098ac4542e fileset: add a 'status(...)' predicate to control evaluation context
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31194
diff changeset
506 b, r, x = getargs(x, 3, 3, _("status takes three arguments"))
6b098ac4542e fileset: add a 'status(...)' predicate to control evaluation context
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31194
diff changeset
507 # i18n: "status" is a keyword
6b098ac4542e fileset: add a 'status(...)' predicate to control evaluation context
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31194
diff changeset
508 baseerr = _("first argument to status must be a revision")
6b098ac4542e fileset: add a 'status(...)' predicate to control evaluation context
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31194
diff changeset
509 baserevspec = getstring(b, baseerr)
6b098ac4542e fileset: add a 'status(...)' predicate to control evaluation context
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31194
diff changeset
510 if not baserevspec:
6b098ac4542e fileset: add a 'status(...)' predicate to control evaluation context
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31194
diff changeset
511 raise error.ParseError(baseerr)
6b098ac4542e fileset: add a 'status(...)' predicate to control evaluation context
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31194
diff changeset
512 reverr = _("second argument to status must be a revision")
6b098ac4542e fileset: add a 'status(...)' predicate to control evaluation context
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31194
diff changeset
513 revspec = getstring(r, reverr)
6b098ac4542e fileset: add a 'status(...)' predicate to control evaluation context
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31194
diff changeset
514 if not revspec:
6b098ac4542e fileset: add a 'status(...)' predicate to control evaluation context
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31194
diff changeset
515 raise error.ParseError(reverr)
37257
f290f130d7fc fileset: use context-returning revpair()
Martin von Zweigbergk <martinvonz@google.com>
parents: 37251
diff changeset
516 basectx, ctx = scmutil.revpair(repo, [baserevspec, revspec])
31195
6b098ac4542e fileset: add a 'status(...)' predicate to control evaluation context
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31194
diff changeset
517 return getset(mctx.switch(ctx, _buildstatus(ctx, x, basectx=basectx)), x)
6b098ac4542e fileset: add a 'status(...)' predicate to control evaluation context
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31194
diff changeset
518
27460
11286ac374f3 fileset: use decorator to mark a function as fileset predicate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27459
diff changeset
519 @predicate('subrepo([pattern])')
16443
9e02e032b522 fileset: add "subrepo" fileset symbol
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 15963
diff changeset
520 def subrepo(mctx, x):
27460
11286ac374f3 fileset: use decorator to mark a function as fileset predicate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27459
diff changeset
521 """Subrepositories whose paths match the given pattern.
16443
9e02e032b522 fileset: add "subrepo" fileset symbol
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 15963
diff changeset
522 """
9e02e032b522 fileset: add "subrepo" fileset symbol
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 15963
diff changeset
523 # i18n: "subrepo" is a keyword
9e02e032b522 fileset: add "subrepo" fileset symbol
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 15963
diff changeset
524 getargs(x, 0, 1, _("subrepo takes at most one argument"))
9e02e032b522 fileset: add "subrepo" fileset symbol
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 15963
diff changeset
525 ctx = mctx.ctx
18364
6252b4f1c4b4 subrepos: process subrepos in sorted order
Mads Kiilerich <mads@kiilerich.com>
parents: 17371
diff changeset
526 sstate = sorted(ctx.substate)
16443
9e02e032b522 fileset: add "subrepo" fileset symbol
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 15963
diff changeset
527 if x:
35741
73432eee0ac4 fileset: add kind:pat operator
Yuya Nishihara <yuya@tcha.org>
parents: 35739
diff changeset
528 pat = getpattern(x, matchmod.allpatternkinds,
73432eee0ac4 fileset: add kind:pat operator
Yuya Nishihara <yuya@tcha.org>
parents: 35739
diff changeset
529 # i18n: "subrepo" is a keyword
73432eee0ac4 fileset: add kind:pat operator
Yuya Nishihara <yuya@tcha.org>
parents: 35739
diff changeset
530 _("subrepo requires a pattern or no arguments"))
16443
9e02e032b522 fileset: add "subrepo" fileset symbol
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 15963
diff changeset
531 fast = not matchmod.patkind(pat)
9e02e032b522 fileset: add "subrepo" fileset symbol
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 15963
diff changeset
532 if fast:
9e02e032b522 fileset: add "subrepo" fileset symbol
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 15963
diff changeset
533 def m(s):
9e02e032b522 fileset: add "subrepo" fileset symbol
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 15963
diff changeset
534 return (s == pat)
9e02e032b522 fileset: add "subrepo" fileset symbol
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 15963
diff changeset
535 else:
24334
eda2f36889b5 fileset: replace 'ctx._repo' with 'ctx.repo()'
Matt Harbison <matt_harbison@yahoo.com>
parents: 24218
diff changeset
536 m = matchmod.match(ctx.repo().root, '', [pat], ctx=ctx)
16443
9e02e032b522 fileset: add "subrepo" fileset symbol
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 15963
diff changeset
537 return [sub for sub in sstate if m(sub)]
9e02e032b522 fileset: add "subrepo" fileset symbol
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 15963
diff changeset
538 else:
9e02e032b522 fileset: add "subrepo" fileset symbol
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 15963
diff changeset
539 return [sub for sub in sstate]
9e02e032b522 fileset: add "subrepo" fileset symbol
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 15963
diff changeset
540
14551
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
541 methods = {
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
542 'string': stringset,
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
543 'symbol': stringset,
35741
73432eee0ac4 fileset: add kind:pat operator
Yuya Nishihara <yuya@tcha.org>
parents: 35739
diff changeset
544 'kindpat': kindpatset,
14551
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
545 'and': andset,
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
546 'or': orset,
17363
5d9e2031c0b1 fileset: actually implement 'minusset'
Patrick Mezard <patrick@mezard.eu>
parents: 16443
diff changeset
547 'minus': minusset,
35692
a62b08f6626b fileset: do not crash by unary negate operation
Yuya Nishihara <yuya@tcha.org>
parents: 35691
diff changeset
548 'negate': negateset,
14551
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
549 'list': listset,
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
550 'group': getset,
14676
e80fa502b8cf fileset: add some basic predicates
Matt Mackall <mpm@selenic.com>
parents: 14673
diff changeset
551 'not': notset,
e80fa502b8cf fileset: add some basic predicates
Matt Mackall <mpm@selenic.com>
parents: 14673
diff changeset
552 'func': func,
14551
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
553 }
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
554
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
555 class matchctx(object):
31190
2f881e7d1ade fileset: build initial subset in fullmatchctx class
Yuya Nishihara <yuya@tcha.org>
parents: 31189
diff changeset
556 def __init__(self, ctx, subset, status=None):
14551
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
557 self.ctx = ctx
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
558 self.subset = subset
14677
2a758ffc821e fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents: 14676
diff changeset
559 self._status = status
27464
c39ecb2b86b3 fileset: detect unintentional existing() invocation at runtime
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27463
diff changeset
560 self._existingenabled = False
14677
2a758ffc821e fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents: 14676
diff changeset
561 def status(self):
2a758ffc821e fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents: 14676
diff changeset
562 return self._status
14673
b0566467c492 fileset: drop matchfn
Matt Mackall <mpm@selenic.com>
parents: 14554
diff changeset
563 def matcher(self, patterns):
b0566467c492 fileset: drop matchfn
Matt Mackall <mpm@selenic.com>
parents: 14554
diff changeset
564 return self.ctx.match(patterns)
14551
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
565 def filter(self, files):
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
566 return [f for f in files if f in self.subset]
15963
042e84e39dee fileset: don't attempt to check data predicates against removed files
Matt Mackall <mpm@selenic.com>
parents: 14830
diff changeset
567 def existing(self):
27464
c39ecb2b86b3 fileset: detect unintentional existing() invocation at runtime
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27463
diff changeset
568 assert self._existingenabled, 'unexpected existing() invocation'
17365
8a0513bf030a fileset: exclude deleted files from matchctx.existing()
Patrick Mezard <patrick@mezard.eu>
parents: 17363
diff changeset
569 if self._status is not None:
8a0513bf030a fileset: exclude deleted files from matchctx.existing()
Patrick Mezard <patrick@mezard.eu>
parents: 17363
diff changeset
570 removed = set(self._status[3])
17367
ce625185cfd9 fileset: matchctx.existing() must consider ignored files
Patrick Mezard <patrick@mezard.eu>
parents: 17366
diff changeset
571 unknown = set(self._status[4] + self._status[5])
17365
8a0513bf030a fileset: exclude deleted files from matchctx.existing()
Patrick Mezard <patrick@mezard.eu>
parents: 17363
diff changeset
572 else:
8a0513bf030a fileset: exclude deleted files from matchctx.existing()
Patrick Mezard <patrick@mezard.eu>
parents: 17363
diff changeset
573 removed = set()
17366
04c65cb59467 fileset: matchctx.existing() must consider unknown files
Patrick Mezard <patrick@mezard.eu>
parents: 17365
diff changeset
574 unknown = set()
17365
8a0513bf030a fileset: exclude deleted files from matchctx.existing()
Patrick Mezard <patrick@mezard.eu>
parents: 17363
diff changeset
575 return (f for f in self.subset
17366
04c65cb59467 fileset: matchctx.existing() must consider unknown files
Patrick Mezard <patrick@mezard.eu>
parents: 17365
diff changeset
576 if (f in self.ctx and f not in removed) or f in unknown)
14551
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
577 def narrow(self, files):
14677
2a758ffc821e fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents: 14676
diff changeset
578 return matchctx(self.ctx, self.filter(files), self._status)
31192
951d95b13487 fileset: add function to switch revision where fileset will be evaluated
Yuya Nishihara <yuya@tcha.org>
parents: 31191
diff changeset
579 def switch(self, ctx, status=None):
951d95b13487 fileset: add function to switch revision where fileset will be evaluated
Yuya Nishihara <yuya@tcha.org>
parents: 31191
diff changeset
580 subset = self.filter(_buildsubset(ctx, status))
951d95b13487 fileset: add function to switch revision where fileset will be evaluated
Yuya Nishihara <yuya@tcha.org>
parents: 31191
diff changeset
581 return matchctx(ctx, subset, status)
14551
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
582
31188
ec5b56b50e19 fileset: add class to host special handling of initial subset
Yuya Nishihara <yuya@tcha.org>
parents: 29987
diff changeset
583 class fullmatchctx(matchctx):
ec5b56b50e19 fileset: add class to host special handling of initial subset
Yuya Nishihara <yuya@tcha.org>
parents: 29987
diff changeset
584 """A match context where any files in any revisions should be valid"""
ec5b56b50e19 fileset: add class to host special handling of initial subset
Yuya Nishihara <yuya@tcha.org>
parents: 29987
diff changeset
585
31190
2f881e7d1ade fileset: build initial subset in fullmatchctx class
Yuya Nishihara <yuya@tcha.org>
parents: 31189
diff changeset
586 def __init__(self, ctx, status=None):
2f881e7d1ade fileset: build initial subset in fullmatchctx class
Yuya Nishihara <yuya@tcha.org>
parents: 31189
diff changeset
587 subset = _buildsubset(ctx, status)
31188
ec5b56b50e19 fileset: add class to host special handling of initial subset
Yuya Nishihara <yuya@tcha.org>
parents: 29987
diff changeset
588 super(fullmatchctx, self).__init__(ctx, subset, status)
31192
951d95b13487 fileset: add function to switch revision where fileset will be evaluated
Yuya Nishihara <yuya@tcha.org>
parents: 31191
diff changeset
589 def switch(self, ctx, status=None):
951d95b13487 fileset: add function to switch revision where fileset will be evaluated
Yuya Nishihara <yuya@tcha.org>
parents: 31191
diff changeset
590 return fullmatchctx(ctx, status)
951d95b13487 fileset: add function to switch revision where fileset will be evaluated
Yuya Nishihara <yuya@tcha.org>
parents: 31191
diff changeset
591
951d95b13487 fileset: add function to switch revision where fileset will be evaluated
Yuya Nishihara <yuya@tcha.org>
parents: 31191
diff changeset
592 # filesets using matchctx.switch()
951d95b13487 fileset: add function to switch revision where fileset will be evaluated
Yuya Nishihara <yuya@tcha.org>
parents: 31191
diff changeset
593 _switchcallers = [
31193
4140d49d2efb fileset: add revs(revs, fileset) to evaluate set in working directory
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31192
diff changeset
594 'revs',
31195
6b098ac4542e fileset: add a 'status(...)' predicate to control evaluation context
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31194
diff changeset
595 'status',
31192
951d95b13487 fileset: add function to switch revision where fileset will be evaluated
Yuya Nishihara <yuya@tcha.org>
parents: 31191
diff changeset
596 ]
31188
ec5b56b50e19 fileset: add class to host special handling of initial subset
Yuya Nishihara <yuya@tcha.org>
parents: 29987
diff changeset
597
14678
5ef7b87530f6 fileset: prescan parse tree to optimize status usage
Matt Mackall <mpm@selenic.com>
parents: 14677
diff changeset
598 def _intree(funcs, tree):
5ef7b87530f6 fileset: prescan parse tree to optimize status usage
Matt Mackall <mpm@selenic.com>
parents: 14677
diff changeset
599 if isinstance(tree, tuple):
5ef7b87530f6 fileset: prescan parse tree to optimize status usage
Matt Mackall <mpm@selenic.com>
parents: 14677
diff changeset
600 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
601 if tree[1][1] in funcs:
5ef7b87530f6 fileset: prescan parse tree to optimize status usage
Matt Mackall <mpm@selenic.com>
parents: 14677
diff changeset
602 return True
31192
951d95b13487 fileset: add function to switch revision where fileset will be evaluated
Yuya Nishihara <yuya@tcha.org>
parents: 31191
diff changeset
603 if tree[1][1] in _switchcallers:
951d95b13487 fileset: add function to switch revision where fileset will be evaluated
Yuya Nishihara <yuya@tcha.org>
parents: 31191
diff changeset
604 # arguments won't be evaluated in the current context
951d95b13487 fileset: add function to switch revision where fileset will be evaluated
Yuya Nishihara <yuya@tcha.org>
parents: 31191
diff changeset
605 return False
14678
5ef7b87530f6 fileset: prescan parse tree to optimize status usage
Matt Mackall <mpm@selenic.com>
parents: 14677
diff changeset
606 for s in tree[1:]:
5ef7b87530f6 fileset: prescan parse tree to optimize status usage
Matt Mackall <mpm@selenic.com>
parents: 14677
diff changeset
607 if _intree(funcs, s):
5ef7b87530f6 fileset: prescan parse tree to optimize status usage
Matt Mackall <mpm@selenic.com>
parents: 14677
diff changeset
608 return True
5ef7b87530f6 fileset: prescan parse tree to optimize status usage
Matt Mackall <mpm@selenic.com>
parents: 14677
diff changeset
609 return False
5ef7b87530f6 fileset: prescan parse tree to optimize status usage
Matt Mackall <mpm@selenic.com>
parents: 14677
diff changeset
610
31189
3c32a3fdfd16 fileset: extract function that builds initial subset from ctx or status
Yuya Nishihara <yuya@tcha.org>
parents: 31188
diff changeset
611 def _buildsubset(ctx, status):
3c32a3fdfd16 fileset: extract function that builds initial subset from ctx or status
Yuya Nishihara <yuya@tcha.org>
parents: 31188
diff changeset
612 if status:
3c32a3fdfd16 fileset: extract function that builds initial subset from ctx or status
Yuya Nishihara <yuya@tcha.org>
parents: 31188
diff changeset
613 subset = []
3c32a3fdfd16 fileset: extract function that builds initial subset from ctx or status
Yuya Nishihara <yuya@tcha.org>
parents: 31188
diff changeset
614 for c in status:
3c32a3fdfd16 fileset: extract function that builds initial subset from ctx or status
Yuya Nishihara <yuya@tcha.org>
parents: 31188
diff changeset
615 subset.extend(c)
3c32a3fdfd16 fileset: extract function that builds initial subset from ctx or status
Yuya Nishihara <yuya@tcha.org>
parents: 31188
diff changeset
616 return subset
3c32a3fdfd16 fileset: extract function that builds initial subset from ctx or status
Yuya Nishihara <yuya@tcha.org>
parents: 31188
diff changeset
617 else:
3c32a3fdfd16 fileset: extract function that builds initial subset from ctx or status
Yuya Nishihara <yuya@tcha.org>
parents: 31188
diff changeset
618 return list(ctx.walk(ctx.match([])))
3c32a3fdfd16 fileset: extract function that builds initial subset from ctx or status
Yuya Nishihara <yuya@tcha.org>
parents: 31188
diff changeset
619
14673
b0566467c492 fileset: drop matchfn
Matt Mackall <mpm@selenic.com>
parents: 14554
diff changeset
620 def getfileset(ctx, expr):
25252
ac381dd7a21f fileset: move validation of incomplete parsing to parse() function
Yuya Nishihara <yuya@tcha.org>
parents: 24408
diff changeset
621 tree = parse(expr)
31191
3c3ab84e6e78 fileset: extract function that builds status tuple only if necessary
Yuya Nishihara <yuya@tcha.org>
parents: 31190
diff changeset
622 return getset(fullmatchctx(ctx, _buildstatus(ctx, tree)), tree)
14678
5ef7b87530f6 fileset: prescan parse tree to optimize status usage
Matt Mackall <mpm@selenic.com>
parents: 14677
diff changeset
623
31194
016c63d6658c fileset: allow to specify a basectx for status
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31193
diff changeset
624 def _buildstatus(ctx, tree, basectx=None):
14678
5ef7b87530f6 fileset: prescan parse tree to optimize status usage
Matt Mackall <mpm@selenic.com>
parents: 14677
diff changeset
625 # do we need status info?
31194
016c63d6658c fileset: allow to specify a basectx for status
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31193
diff changeset
626
016c63d6658c fileset: allow to specify a basectx for status
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31193
diff changeset
627 # temporaty boolean to simplify the next conditional
016c63d6658c fileset: allow to specify a basectx for status
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31193
diff changeset
628 purewdir = ctx.rev() is None and basectx is None
016c63d6658c fileset: allow to specify a basectx for status
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31193
diff changeset
629
27461
afa76585c955 fileset: use decorator to mark a predicate as "status caller"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27460
diff changeset
630 if (_intree(_statuscallers, tree) or
17365
8a0513bf030a fileset: exclude deleted files from matchctx.existing()
Patrick Mezard <patrick@mezard.eu>
parents: 17363
diff changeset
631 # Using matchctx.existing() on a workingctx requires us to check
8a0513bf030a fileset: exclude deleted files from matchctx.existing()
Patrick Mezard <patrick@mezard.eu>
parents: 17363
diff changeset
632 # for deleted files.
31194
016c63d6658c fileset: allow to specify a basectx for status
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31193
diff changeset
633 (purewdir and _intree(_existingcallers, tree))):
14678
5ef7b87530f6 fileset: prescan parse tree to optimize status usage
Matt Mackall <mpm@selenic.com>
parents: 14677
diff changeset
634 unknown = _intree(['unknown'], tree)
5ef7b87530f6 fileset: prescan parse tree to optimize status usage
Matt Mackall <mpm@selenic.com>
parents: 14677
diff changeset
635 ignored = _intree(['ignored'], tree)
5ef7b87530f6 fileset: prescan parse tree to optimize status usage
Matt Mackall <mpm@selenic.com>
parents: 14677
diff changeset
636
24334
eda2f36889b5 fileset: replace 'ctx._repo' with 'ctx.repo()'
Matt Harbison <matt_harbison@yahoo.com>
parents: 24218
diff changeset
637 r = ctx.repo()
31194
016c63d6658c fileset: allow to specify a basectx for status
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31193
diff changeset
638 if basectx is None:
016c63d6658c fileset: allow to specify a basectx for status
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31193
diff changeset
639 basectx = ctx.p1()
016c63d6658c fileset: allow to specify a basectx for status
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31193
diff changeset
640 return r.status(basectx, ctx,
31191
3c3ab84e6e78 fileset: extract function that builds status tuple only if necessary
Yuya Nishihara <yuya@tcha.org>
parents: 31190
diff changeset
641 unknown=unknown, ignored=ignored, clean=True)
14678
5ef7b87530f6 fileset: prescan parse tree to optimize status usage
Matt Mackall <mpm@selenic.com>
parents: 14677
diff changeset
642 else:
31191
3c3ab84e6e78 fileset: extract function that builds status tuple only if necessary
Yuya Nishihara <yuya@tcha.org>
parents: 31190
diff changeset
643 return None
14681
0744db5eb51c fileset: add some function help text
Matt Mackall <mpm@selenic.com>
parents: 14680
diff changeset
644
25255
ad1d2c952889 fileset: pretty print syntax tree in debug output
Yuya Nishihara <yuya@tcha.org>
parents: 25252
diff changeset
645 def prettyformat(tree):
ad1d2c952889 fileset: pretty print syntax tree in debug output
Yuya Nishihara <yuya@tcha.org>
parents: 25252
diff changeset
646 return parser.prettyformat(tree, ('string', 'symbol'))
ad1d2c952889 fileset: pretty print syntax tree in debug output
Yuya Nishihara <yuya@tcha.org>
parents: 25252
diff changeset
647
28447
4eb5496c2bd4 registrar: add filesetpredicate to mark a function as fileset predicate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 28056
diff changeset
648 def loadpredicate(ui, extname, registrarobj):
4eb5496c2bd4 registrar: add filesetpredicate to mark a function as fileset predicate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 28056
diff changeset
649 """Load fileset predicates from specified registrarobj
4eb5496c2bd4 registrar: add filesetpredicate to mark a function as fileset predicate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 28056
diff changeset
650 """
4eb5496c2bd4 registrar: add filesetpredicate to mark a function as fileset predicate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 28056
diff changeset
651 for name, func in registrarobj._table.iteritems():
4eb5496c2bd4 registrar: add filesetpredicate to mark a function as fileset predicate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 28056
diff changeset
652 symbols[name] = func
4eb5496c2bd4 registrar: add filesetpredicate to mark a function as fileset predicate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 28056
diff changeset
653 if func._callstatus:
4eb5496c2bd4 registrar: add filesetpredicate to mark a function as fileset predicate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 28056
diff changeset
654 _statuscallers.add(name)
4eb5496c2bd4 registrar: add filesetpredicate to mark a function as fileset predicate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 28056
diff changeset
655 if func._callexisting:
4eb5496c2bd4 registrar: add filesetpredicate to mark a function as fileset predicate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 28056
diff changeset
656 _existingcallers.add(name)
4eb5496c2bd4 registrar: add filesetpredicate to mark a function as fileset predicate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 28056
diff changeset
657
28448
7108834c76a2 fileset: replace predicate by filesetpredicate of registrar (API)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 28447
diff changeset
658 # load built-in predicates explicitly to setup _statuscallers/_existingcallers
7108834c76a2 fileset: replace predicate by filesetpredicate of registrar (API)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 28447
diff changeset
659 loadpredicate(None, None, predicate)
7108834c76a2 fileset: replace predicate by filesetpredicate of registrar (API)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 28447
diff changeset
660
14681
0744db5eb51c fileset: add some function help text
Matt Mackall <mpm@selenic.com>
parents: 14680
diff changeset
661 # tell hggettext to extract docstrings from these functions:
0744db5eb51c fileset: add some function help text
Matt Mackall <mpm@selenic.com>
parents: 14680
diff changeset
662 i18nfunctions = symbols.values()