mercurial/fileset.py
author Yuya Nishihara <yuya@tcha.org>
Sat, 21 Dec 2013 12:44:19 +0900
branchstable
changeset 20208 61a47fd64f30
parent 19470 19ac0d8ee9a2
child 20209 174d9b8baf5d
permissions -rw-r--r--
fileset, revset: do not use global parser object for thread safety parse() cannot be called at the same time because a parser object keeps its states. This is no problem for command-line hg client, but it would cause strange errors in multi-threaded hgweb. Creating parser object is not too expensive. original: % python -m timeit -s 'from mercurial import revset' 'revset.parse("0::tip")' 100000 loops, best of 3: 11.3 usec per loop thread-safe: % python -m timeit -s 'from mercurial import revset' 'revset.parse("0::tip")' 100000 loops, best of 3: 13.1 usec per loop
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
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
14682
8785fd757077 fileset: add grep predicate
Matt Mackall <mpm@selenic.com>
parents: 14681
diff changeset
     8
import parser, error, util, merge, re
13593
cc4721ed7a2a help: extract items doc generation function
Patrick Mezard <pmezard@gmail.com>
parents: 13506
diff changeset
     9
from i18n import _
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    10
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    11
elements = {
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    12
    "(": (20, ("group", 1, ")"), ("func", 1, ")")),
12616
e797fdf91df4 revset: lower precedence of minus infix (issue2361)
Matt Mackall <mpm@selenic.com>
parents: 12615
diff changeset
    13
    "-": (5, ("negate", 19), ("minus", 5)),
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    14
    "not": (10, ("not", 10)),
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    15
    "!": (10, ("not", 10)),
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    16
    "and": (5, None, ("and", 5)),
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    17
    "&": (5, None, ("and", 5)),
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    18
    "or": (4, None, ("or", 4)),
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    19
    "|": (4, None, ("or", 4)),
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    20
    "+": (4, None, ("or", 4)),
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    21
    ",": (2, None, ("list", 2)),
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    22
    ")": (0, None, None),
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    23
    "symbol": (0, ("symbol",), None),
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    24
    "string": (0, ("string",), None),
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    25
    "end": (0, None, None),
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
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    28
keywords = set(['and', 'or', 'not'])
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    29
19470
19ac0d8ee9a2 fileset: handle underbar in symbols
Matt Mackall <mpm@selenic.com>
parents: 19194
diff changeset
    30
globchars = ".*{}[]?/\\_"
14551
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
    31
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    32
def tokenize(program):
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    33
    pos, l = 0, len(program)
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    34
    while pos < l:
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    35
        c = program[pos]
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    36
        if c.isspace(): # skip inter-token whitespace
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    37
            pass
14511
30506b894359 filesets: introduce basic fileset expression parser
Matt Mackall <mpm@selenic.com>
parents: 14509
diff changeset
    38
        elif c in "(),-|&+!": # handle simple operators
11289
4215ce511134 revset: raise ParseError exceptions
Matt Mackall <mpm@selenic.com>
parents: 11284
diff changeset
    39
            yield (c, None, pos)
12408
78a97859b90d revset: support raw string literals
Brodie Rao <brodie@bitheap.org>
parents: 12401
diff changeset
    40
        elif (c in '"\'' or c == 'r' and
78a97859b90d revset: support raw string literals
Brodie Rao <brodie@bitheap.org>
parents: 12401
diff changeset
    41
              program[pos:pos + 2] in ("r'", 'r"')): # handle quoted strings
78a97859b90d revset: support raw string literals
Brodie Rao <brodie@bitheap.org>
parents: 12401
diff changeset
    42
            if c == 'r':
78a97859b90d revset: support raw string literals
Brodie Rao <brodie@bitheap.org>
parents: 12401
diff changeset
    43
                pos += 1
78a97859b90d revset: support raw string literals
Brodie Rao <brodie@bitheap.org>
parents: 12401
diff changeset
    44
                c = program[pos]
78a97859b90d revset: support raw string literals
Brodie Rao <brodie@bitheap.org>
parents: 12401
diff changeset
    45
                decode = lambda x: x
78a97859b90d revset: support raw string literals
Brodie Rao <brodie@bitheap.org>
parents: 12401
diff changeset
    46
            else:
78a97859b90d revset: support raw string literals
Brodie Rao <brodie@bitheap.org>
parents: 12401
diff changeset
    47
                decode = lambda x: x.decode('string-escape')
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    48
            pos += 1
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    49
            s = pos
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    50
            while pos < l: # find closing quote
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    51
                d = program[pos]
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    52
                if d == '\\': # skip over escaped characters
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    53
                    pos += 2
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    54
                    continue
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    55
                if d == c:
12408
78a97859b90d revset: support raw string literals
Brodie Rao <brodie@bitheap.org>
parents: 12401
diff changeset
    56
                    yield ('string', decode(program[s:pos]), s)
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    57
                    break
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    58
                pos += 1
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    59
            else:
11383
de544774ebea revset: all your error messages are belong to _
Martin Geisler <mg@lazybytes.net>
parents: 11349
diff changeset
    60
                raise error.ParseError(_("unterminated string"), s)
14551
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
    61
        elif c.isalnum() or c in globchars or ord(c) > 127:
14513
85fe676c27e9 fileset: fix long line
Matt Mackall <mpm@selenic.com>
parents: 14511
diff changeset
    62
            # gather up a symbol/keyword
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    63
            s = pos
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    64
            pos += 1
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    65
            while pos < l: # find end of symbol
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    66
                d = program[pos]
14551
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
    67
                if not (d.isalnum() or d in globchars or ord(d) > 127):
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    68
                    break
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    69
                pos += 1
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    70
            sym = program[s:pos]
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    71
            if sym in keywords: # operator keywords
11289
4215ce511134 revset: raise ParseError exceptions
Matt Mackall <mpm@selenic.com>
parents: 11284
diff changeset
    72
                yield (sym, None, s)
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    73
            else:
11289
4215ce511134 revset: raise ParseError exceptions
Matt Mackall <mpm@selenic.com>
parents: 11284
diff changeset
    74
                yield ('symbol', sym, s)
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    75
            pos -= 1
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    76
        else:
11383
de544774ebea revset: all your error messages are belong to _
Martin Geisler <mg@lazybytes.net>
parents: 11349
diff changeset
    77
            raise error.ParseError(_("syntax error"), pos)
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    78
        pos += 1
11289
4215ce511134 revset: raise ParseError exceptions
Matt Mackall <mpm@selenic.com>
parents: 11284
diff changeset
    79
    yield ('end', None, pos)
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    80
20208
61a47fd64f30 fileset, revset: do not use global parser object for thread safety
Yuya Nishihara <yuya@tcha.org>
parents: 19470
diff changeset
    81
def parse(expr):
61a47fd64f30 fileset, revset: do not use global parser object for thread safety
Yuya Nishihara <yuya@tcha.org>
parents: 19470
diff changeset
    82
    p = parser.parser(tokenize, elements)
61a47fd64f30 fileset, revset: do not use global parser object for thread safety
Yuya Nishihara <yuya@tcha.org>
parents: 19470
diff changeset
    83
    return p.parse(expr)
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    84
14551
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
    85
def getstring(x, err):
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
    86
    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
    87
        return x[1]
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
    88
    raise error.ParseError(err)
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
    89
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
    90
def getset(mctx, x):
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
    91
    if not x:
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
    92
        raise error.ParseError(_("missing argument"))
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
    93
    return methods[x[0]](mctx, *x[1:])
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
    94
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
    95
def stringset(mctx, x):
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
    96
    m = mctx.matcher([x])
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
    97
    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
    98
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
    99
def andset(mctx, x, y):
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
   100
    return getset(mctx.narrow(getset(mctx, x)), y)
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
   101
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
   102
def orset(mctx, x, y):
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
   103
    # needs optimizing
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
   104
    xl = getset(mctx, x)
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
   105
    yl = getset(mctx, y)
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
   106
    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
   107
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
   108
def notset(mctx, x):
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
   109
    s = set(getset(mctx, x))
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
   110
    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
   111
17363
5d9e2031c0b1 fileset: actually implement 'minusset'
Patrick Mezard <patrick@mezard.eu>
parents: 16443
diff changeset
   112
def minusset(mctx, x, y):
5d9e2031c0b1 fileset: actually implement 'minusset'
Patrick Mezard <patrick@mezard.eu>
parents: 16443
diff changeset
   113
    xl = getset(mctx, x)
5d9e2031c0b1 fileset: actually implement 'minusset'
Patrick Mezard <patrick@mezard.eu>
parents: 16443
diff changeset
   114
    yl = set(getset(mctx, y))
5d9e2031c0b1 fileset: actually implement 'minusset'
Patrick Mezard <patrick@mezard.eu>
parents: 16443
diff changeset
   115
    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
   116
14551
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
   117
def listset(mctx, a, b):
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
   118
    raise error.ParseError(_("can't use a list in this context"))
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
   119
14677
2a758ffc821e fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents: 14676
diff changeset
   120
def modified(mctx, x):
14681
0744db5eb51c fileset: add some function help text
Matt Mackall <mpm@selenic.com>
parents: 14680
diff changeset
   121
    """``modified()``
0744db5eb51c fileset: add some function help text
Matt Mackall <mpm@selenic.com>
parents: 14680
diff changeset
   122
    File that is modified according to status.
0744db5eb51c fileset: add some function help text
Matt Mackall <mpm@selenic.com>
parents: 14680
diff changeset
   123
    """
14785
0f0bd4d028d3 fileset: add i18n hints for keywords
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 14718
diff changeset
   124
    # i18n: "modified" is a keyword
14677
2a758ffc821e fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents: 14676
diff changeset
   125
    getargs(x, 0, 0, _("modified takes no arguments"))
2a758ffc821e fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents: 14676
diff changeset
   126
    s = mctx.status()[0]
2a758ffc821e fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents: 14676
diff changeset
   127
    return [f for f in mctx.subset if f in s]
2a758ffc821e fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents: 14676
diff changeset
   128
2a758ffc821e fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents: 14676
diff changeset
   129
def added(mctx, x):
14681
0744db5eb51c fileset: add some function help text
Matt Mackall <mpm@selenic.com>
parents: 14680
diff changeset
   130
    """``added()``
0744db5eb51c fileset: add some function help text
Matt Mackall <mpm@selenic.com>
parents: 14680
diff changeset
   131
    File that is added according to status.
0744db5eb51c fileset: add some function help text
Matt Mackall <mpm@selenic.com>
parents: 14680
diff changeset
   132
    """
14785
0f0bd4d028d3 fileset: add i18n hints for keywords
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 14718
diff changeset
   133
    # i18n: "added" is a keyword
14677
2a758ffc821e fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents: 14676
diff changeset
   134
    getargs(x, 0, 0, _("added takes no arguments"))
2a758ffc821e fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents: 14676
diff changeset
   135
    s = mctx.status()[1]
2a758ffc821e fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents: 14676
diff changeset
   136
    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
   137
2a758ffc821e fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents: 14676
diff changeset
   138
def removed(mctx, x):
14681
0744db5eb51c fileset: add some function help text
Matt Mackall <mpm@selenic.com>
parents: 14680
diff changeset
   139
    """``removed()``
0744db5eb51c fileset: add some function help text
Matt Mackall <mpm@selenic.com>
parents: 14680
diff changeset
   140
    File that is removed according to status.
0744db5eb51c fileset: add some function help text
Matt Mackall <mpm@selenic.com>
parents: 14680
diff changeset
   141
    """
14785
0f0bd4d028d3 fileset: add i18n hints for keywords
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 14718
diff changeset
   142
    # i18n: "removed" is a keyword
14677
2a758ffc821e fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents: 14676
diff changeset
   143
    getargs(x, 0, 0, _("removed takes no arguments"))
2a758ffc821e fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents: 14676
diff changeset
   144
    s = mctx.status()[2]
2a758ffc821e fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents: 14676
diff changeset
   145
    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
   146
2a758ffc821e fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents: 14676
diff changeset
   147
def deleted(mctx, x):
14681
0744db5eb51c fileset: add some function help text
Matt Mackall <mpm@selenic.com>
parents: 14680
diff changeset
   148
    """``deleted()``
0744db5eb51c fileset: add some function help text
Matt Mackall <mpm@selenic.com>
parents: 14680
diff changeset
   149
    File that is deleted according to status.
0744db5eb51c fileset: add some function help text
Matt Mackall <mpm@selenic.com>
parents: 14680
diff changeset
   150
    """
14785
0f0bd4d028d3 fileset: add i18n hints for keywords
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 14718
diff changeset
   151
    # i18n: "deleted" is a keyword
14677
2a758ffc821e fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents: 14676
diff changeset
   152
    getargs(x, 0, 0, _("deleted takes no arguments"))
2a758ffc821e fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents: 14676
diff changeset
   153
    s = mctx.status()[3]
2a758ffc821e fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents: 14676
diff changeset
   154
    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
   155
2a758ffc821e fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents: 14676
diff changeset
   156
def unknown(mctx, x):
14681
0744db5eb51c fileset: add some function help text
Matt Mackall <mpm@selenic.com>
parents: 14680
diff changeset
   157
    """``unknown()``
0744db5eb51c fileset: add some function help text
Matt Mackall <mpm@selenic.com>
parents: 14680
diff changeset
   158
    File that is unknown according to status. These files will only be
0744db5eb51c fileset: add some function help text
Matt Mackall <mpm@selenic.com>
parents: 14680
diff changeset
   159
    considered if this predicate is used.
0744db5eb51c fileset: add some function help text
Matt Mackall <mpm@selenic.com>
parents: 14680
diff changeset
   160
    """
14785
0f0bd4d028d3 fileset: add i18n hints for keywords
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 14718
diff changeset
   161
    # i18n: "unknown" is a keyword
14677
2a758ffc821e fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents: 14676
diff changeset
   162
    getargs(x, 0, 0, _("unknown takes no arguments"))
2a758ffc821e fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents: 14676
diff changeset
   163
    s = mctx.status()[4]
2a758ffc821e fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents: 14676
diff changeset
   164
    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
   165
2a758ffc821e fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents: 14676
diff changeset
   166
def ignored(mctx, x):
14681
0744db5eb51c fileset: add some function help text
Matt Mackall <mpm@selenic.com>
parents: 14680
diff changeset
   167
    """``ignored()``
0744db5eb51c fileset: add some function help text
Matt Mackall <mpm@selenic.com>
parents: 14680
diff changeset
   168
    File that is ignored according to status. These files will only be
0744db5eb51c fileset: add some function help text
Matt Mackall <mpm@selenic.com>
parents: 14680
diff changeset
   169
    considered if this predicate is used.
0744db5eb51c fileset: add some function help text
Matt Mackall <mpm@selenic.com>
parents: 14680
diff changeset
   170
    """
14785
0f0bd4d028d3 fileset: add i18n hints for keywords
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 14718
diff changeset
   171
    # i18n: "ignored" is a keyword
14677
2a758ffc821e fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents: 14676
diff changeset
   172
    getargs(x, 0, 0, _("ignored takes no arguments"))
2a758ffc821e fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents: 14676
diff changeset
   173
    s = mctx.status()[5]
2a758ffc821e fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents: 14676
diff changeset
   174
    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
   175
2a758ffc821e fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents: 14676
diff changeset
   176
def clean(mctx, x):
14681
0744db5eb51c fileset: add some function help text
Matt Mackall <mpm@selenic.com>
parents: 14680
diff changeset
   177
    """``clean()``
0744db5eb51c fileset: add some function help text
Matt Mackall <mpm@selenic.com>
parents: 14680
diff changeset
   178
    File that is clean according to status.
0744db5eb51c fileset: add some function help text
Matt Mackall <mpm@selenic.com>
parents: 14680
diff changeset
   179
    """
14785
0f0bd4d028d3 fileset: add i18n hints for keywords
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 14718
diff changeset
   180
    # i18n: "clean" is a keyword
14677
2a758ffc821e fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents: 14676
diff changeset
   181
    getargs(x, 0, 0, _("clean takes no arguments"))
2a758ffc821e fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents: 14676
diff changeset
   182
    s = mctx.status()[6]
2a758ffc821e fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents: 14676
diff changeset
   183
    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
   184
14676
e80fa502b8cf fileset: add some basic predicates
Matt Mackall <mpm@selenic.com>
parents: 14673
diff changeset
   185
def func(mctx, a, b):
e80fa502b8cf fileset: add some basic predicates
Matt Mackall <mpm@selenic.com>
parents: 14673
diff changeset
   186
    if a[0] == 'symbol' and a[1] in symbols:
e80fa502b8cf fileset: add some basic predicates
Matt Mackall <mpm@selenic.com>
parents: 14673
diff changeset
   187
        return symbols[a[1]](mctx, b)
e80fa502b8cf fileset: add some basic predicates
Matt Mackall <mpm@selenic.com>
parents: 14673
diff changeset
   188
    raise error.ParseError(_("not a function: %s") % a[1])
e80fa502b8cf fileset: add some basic predicates
Matt Mackall <mpm@selenic.com>
parents: 14673
diff changeset
   189
e80fa502b8cf fileset: add some basic predicates
Matt Mackall <mpm@selenic.com>
parents: 14673
diff changeset
   190
def getlist(x):
e80fa502b8cf fileset: add some basic predicates
Matt Mackall <mpm@selenic.com>
parents: 14673
diff changeset
   191
    if not x:
e80fa502b8cf fileset: add some basic predicates
Matt Mackall <mpm@selenic.com>
parents: 14673
diff changeset
   192
        return []
e80fa502b8cf fileset: add some basic predicates
Matt Mackall <mpm@selenic.com>
parents: 14673
diff changeset
   193
    if x[0] == 'list':
e80fa502b8cf fileset: add some basic predicates
Matt Mackall <mpm@selenic.com>
parents: 14673
diff changeset
   194
        return getlist(x[1]) + [x[2]]
e80fa502b8cf fileset: add some basic predicates
Matt Mackall <mpm@selenic.com>
parents: 14673
diff changeset
   195
    return [x]
e80fa502b8cf fileset: add some basic predicates
Matt Mackall <mpm@selenic.com>
parents: 14673
diff changeset
   196
e80fa502b8cf fileset: add some basic predicates
Matt Mackall <mpm@selenic.com>
parents: 14673
diff changeset
   197
def getargs(x, min, max, err):
e80fa502b8cf fileset: add some basic predicates
Matt Mackall <mpm@selenic.com>
parents: 14673
diff changeset
   198
    l = getlist(x)
e80fa502b8cf fileset: add some basic predicates
Matt Mackall <mpm@selenic.com>
parents: 14673
diff changeset
   199
    if len(l) < min or len(l) > max:
e80fa502b8cf fileset: add some basic predicates
Matt Mackall <mpm@selenic.com>
parents: 14673
diff changeset
   200
        raise error.ParseError(err)
e80fa502b8cf fileset: add some basic predicates
Matt Mackall <mpm@selenic.com>
parents: 14673
diff changeset
   201
    return l
e80fa502b8cf fileset: add some basic predicates
Matt Mackall <mpm@selenic.com>
parents: 14673
diff changeset
   202
e80fa502b8cf fileset: add some basic predicates
Matt Mackall <mpm@selenic.com>
parents: 14673
diff changeset
   203
def binary(mctx, x):
14681
0744db5eb51c fileset: add some function help text
Matt Mackall <mpm@selenic.com>
parents: 14680
diff changeset
   204
    """``binary()``
14830
35f5cfdd0427 fileset: fix typo in binary() doc
Idan Kamara <idankk86@gmail.com>
parents: 14785
diff changeset
   205
    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
   206
    """
14785
0f0bd4d028d3 fileset: add i18n hints for keywords
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 14718
diff changeset
   207
    # i18n: "binary" is a keyword
14676
e80fa502b8cf fileset: add some basic predicates
Matt Mackall <mpm@selenic.com>
parents: 14673
diff changeset
   208
    getargs(x, 0, 0, _("binary 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
   209
    return [f for f in mctx.existing() if util.binary(mctx.ctx[f].data())]
14676
e80fa502b8cf fileset: add some basic predicates
Matt Mackall <mpm@selenic.com>
parents: 14673
diff changeset
   210
e80fa502b8cf fileset: add some basic predicates
Matt Mackall <mpm@selenic.com>
parents: 14673
diff changeset
   211
def exec_(mctx, x):
14681
0744db5eb51c fileset: add some function help text
Matt Mackall <mpm@selenic.com>
parents: 14680
diff changeset
   212
    """``exec()``
0744db5eb51c fileset: add some function help text
Matt Mackall <mpm@selenic.com>
parents: 14680
diff changeset
   213
    File that is marked as executable.
0744db5eb51c fileset: add some function help text
Matt Mackall <mpm@selenic.com>
parents: 14680
diff changeset
   214
    """
14785
0f0bd4d028d3 fileset: add i18n hints for keywords
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 14718
diff changeset
   215
    # i18n: "exec" is a keyword
14676
e80fa502b8cf fileset: add some basic predicates
Matt Mackall <mpm@selenic.com>
parents: 14673
diff changeset
   216
    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
   217
    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
   218
e80fa502b8cf fileset: add some basic predicates
Matt Mackall <mpm@selenic.com>
parents: 14673
diff changeset
   219
def symlink(mctx, x):
14681
0744db5eb51c fileset: add some function help text
Matt Mackall <mpm@selenic.com>
parents: 14680
diff changeset
   220
    """``symlink()``
0744db5eb51c fileset: add some function help text
Matt Mackall <mpm@selenic.com>
parents: 14680
diff changeset
   221
    File that is marked as a symlink.
0744db5eb51c fileset: add some function help text
Matt Mackall <mpm@selenic.com>
parents: 14680
diff changeset
   222
    """
14785
0f0bd4d028d3 fileset: add i18n hints for keywords
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 14718
diff changeset
   223
    # i18n: "symlink" is a keyword
14676
e80fa502b8cf fileset: add some basic predicates
Matt Mackall <mpm@selenic.com>
parents: 14673
diff changeset
   224
    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
   225
    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
   226
14679
e141e1cee0cc fileset: add resolved and unresolved predicates
Matt Mackall <mpm@selenic.com>
parents: 14678
diff changeset
   227
def resolved(mctx, x):
14681
0744db5eb51c fileset: add some function help text
Matt Mackall <mpm@selenic.com>
parents: 14680
diff changeset
   228
    """``resolved()``
0744db5eb51c fileset: add some function help text
Matt Mackall <mpm@selenic.com>
parents: 14680
diff changeset
   229
    File that is marked resolved according to the resolve state.
0744db5eb51c fileset: add some function help text
Matt Mackall <mpm@selenic.com>
parents: 14680
diff changeset
   230
    """
14785
0f0bd4d028d3 fileset: add i18n hints for keywords
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 14718
diff changeset
   231
    # i18n: "resolved" is a keyword
14679
e141e1cee0cc fileset: add resolved and unresolved predicates
Matt Mackall <mpm@selenic.com>
parents: 14678
diff changeset
   232
    getargs(x, 0, 0, _("resolved takes no arguments"))
e141e1cee0cc fileset: add resolved and unresolved predicates
Matt Mackall <mpm@selenic.com>
parents: 14678
diff changeset
   233
    if mctx.ctx.rev() is not None:
e141e1cee0cc fileset: add resolved and unresolved predicates
Matt Mackall <mpm@selenic.com>
parents: 14678
diff changeset
   234
        return []
e141e1cee0cc fileset: add resolved and unresolved predicates
Matt Mackall <mpm@selenic.com>
parents: 14678
diff changeset
   235
    ms = merge.mergestate(mctx.ctx._repo)
e141e1cee0cc fileset: add resolved and unresolved predicates
Matt Mackall <mpm@selenic.com>
parents: 14678
diff changeset
   236
    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
   237
e141e1cee0cc fileset: add resolved and unresolved predicates
Matt Mackall <mpm@selenic.com>
parents: 14678
diff changeset
   238
def unresolved(mctx, x):
14681
0744db5eb51c fileset: add some function help text
Matt Mackall <mpm@selenic.com>
parents: 14680
diff changeset
   239
    """``unresolved()``
0744db5eb51c fileset: add some function help text
Matt Mackall <mpm@selenic.com>
parents: 14680
diff changeset
   240
    File that is marked unresolved according to the resolve state.
0744db5eb51c fileset: add some function help text
Matt Mackall <mpm@selenic.com>
parents: 14680
diff changeset
   241
    """
14785
0f0bd4d028d3 fileset: add i18n hints for keywords
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 14718
diff changeset
   242
    # i18n: "unresolved" is a keyword
14679
e141e1cee0cc fileset: add resolved and unresolved predicates
Matt Mackall <mpm@selenic.com>
parents: 14678
diff changeset
   243
    getargs(x, 0, 0, _("unresolved takes no arguments"))
e141e1cee0cc fileset: add resolved and unresolved predicates
Matt Mackall <mpm@selenic.com>
parents: 14678
diff changeset
   244
    if mctx.ctx.rev() is not None:
e141e1cee0cc fileset: add resolved and unresolved predicates
Matt Mackall <mpm@selenic.com>
parents: 14678
diff changeset
   245
        return []
e141e1cee0cc fileset: add resolved and unresolved predicates
Matt Mackall <mpm@selenic.com>
parents: 14678
diff changeset
   246
    ms = merge.mergestate(mctx.ctx._repo)
e141e1cee0cc fileset: add resolved and unresolved predicates
Matt Mackall <mpm@selenic.com>
parents: 14678
diff changeset
   247
    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
   248
14680
49af5fa3809b fileset: add hgignore
Matt Mackall <mpm@selenic.com>
parents: 14679
diff changeset
   249
def hgignore(mctx, x):
14700
848a6658069e fileset: use correct function name for hgignore in docstring
Ollie Rutherfurd <orutherfurd@gmail.com>
parents: 14690
diff changeset
   250
    """``hgignore()``
14681
0744db5eb51c fileset: add some function help text
Matt Mackall <mpm@selenic.com>
parents: 14680
diff changeset
   251
    File that matches the active .hgignore pattern.
0744db5eb51c fileset: add some function help text
Matt Mackall <mpm@selenic.com>
parents: 14680
diff changeset
   252
    """
14680
49af5fa3809b fileset: add hgignore
Matt Mackall <mpm@selenic.com>
parents: 14679
diff changeset
   253
    getargs(x, 0, 0, _("hgignore takes no arguments"))
49af5fa3809b fileset: add hgignore
Matt Mackall <mpm@selenic.com>
parents: 14679
diff changeset
   254
    ignore = mctx.ctx._repo.dirstate._ignore
49af5fa3809b fileset: add hgignore
Matt Mackall <mpm@selenic.com>
parents: 14679
diff changeset
   255
    return [f for f in mctx.subset if ignore(f)]
49af5fa3809b fileset: add hgignore
Matt Mackall <mpm@selenic.com>
parents: 14679
diff changeset
   256
14682
8785fd757077 fileset: add grep predicate
Matt Mackall <mpm@selenic.com>
parents: 14681
diff changeset
   257
def grep(mctx, x):
8785fd757077 fileset: add grep predicate
Matt Mackall <mpm@selenic.com>
parents: 14681
diff changeset
   258
    """``grep(regex)``
8785fd757077 fileset: add grep predicate
Matt Mackall <mpm@selenic.com>
parents: 14681
diff changeset
   259
    File contains the given regular expression.
8785fd757077 fileset: add grep predicate
Matt Mackall <mpm@selenic.com>
parents: 14681
diff changeset
   260
    """
17368
01cc267fc105 fileset: do not traceback on invalid grep pattern
Patrick Mezard <patrick@mezard.eu>
parents: 17367
diff changeset
   261
    try:
01cc267fc105 fileset: do not traceback on invalid grep pattern
Patrick Mezard <patrick@mezard.eu>
parents: 17367
diff changeset
   262
        # i18n: "grep" is a keyword
01cc267fc105 fileset: do not traceback on invalid grep pattern
Patrick Mezard <patrick@mezard.eu>
parents: 17367
diff changeset
   263
        r = re.compile(getstring(x, _("grep requires a pattern")))
01cc267fc105 fileset: do not traceback on invalid grep pattern
Patrick Mezard <patrick@mezard.eu>
parents: 17367
diff changeset
   264
    except re.error, e:
01cc267fc105 fileset: do not traceback on invalid grep pattern
Patrick Mezard <patrick@mezard.eu>
parents: 17367
diff changeset
   265
        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
   266
    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
   267
14683
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
   268
def _sizetomax(s):
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
   269
    try:
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
   270
        s = s.strip()
19194
1d08df65cd3c util: migrate fileset._sizetoint to util.sizetoint
Bryan O'Sullivan <bryano@fb.com>
parents: 18842
diff changeset
   271
        for k, v in util._sizeunits:
14683
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
   272
            if s.endswith(k):
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
   273
                # max(4k) = 5k - 1, max(4.5k) = 4.6k - 1
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
   274
                n = s[:-len(k)]
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
   275
                inc = 1.0
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
   276
                if "." in n:
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
   277
                    inc /= 10 ** len(n.split(".")[1])
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
   278
                return int((float(n) + inc) * v) - 1
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
   279
        # no extension, this is a precise value
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
   280
        return int(s)
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
   281
    except ValueError:
14716
552329013bac fileset: use ParseError pos field correctly
Mads Kiilerich <mads@kiilerich.com>
parents: 14701
diff changeset
   282
        raise error.ParseError(_("couldn't parse size: %s") % s)
14683
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
   283
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
   284
def size(mctx, x):
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
   285
    """``size(expression)``
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
   286
    File size matches the given expression. Examples:
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
   287
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
   288
    - 1k (files from 1024 to 2047 bytes)
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
   289
    - < 20k (files less than 20480 bytes)
14689
25e4d2f35965 fileset: drop backwards SI size units
Matt Mackall <mpm@selenic.com>
parents: 14685
diff changeset
   290
    - >= .5MB (files at least 524288 bytes)
14683
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
   291
    - 4k - 1MB (files from 4096 bytes to 1048576 bytes)
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
   292
    """
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
   293
14785
0f0bd4d028d3 fileset: add i18n hints for keywords
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 14718
diff changeset
   294
    # i18n: "size" is a keyword
14717
c8ee2729e89f revset and fileset: fix typos in parser error messages
Mads Kiilerich <mads@kiilerich.com>
parents: 14716
diff changeset
   295
    expr = getstring(x, _("size requires an expression")).strip()
14683
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
   296
    if '-' in expr: # do we have a range?
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
   297
        a, b = expr.split('-', 1)
19194
1d08df65cd3c util: migrate fileset._sizetoint to util.sizetoint
Bryan O'Sullivan <bryano@fb.com>
parents: 18842
diff changeset
   298
        a = util.sizetoint(a)
1d08df65cd3c util: migrate fileset._sizetoint to util.sizetoint
Bryan O'Sullivan <bryano@fb.com>
parents: 18842
diff changeset
   299
        b = util.sizetoint(b)
14683
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
   300
        m = lambda x: x >= a and x <= b
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
   301
    elif expr.startswith("<="):
19194
1d08df65cd3c util: migrate fileset._sizetoint to util.sizetoint
Bryan O'Sullivan <bryano@fb.com>
parents: 18842
diff changeset
   302
        a = util.sizetoint(expr[2:])
14683
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
   303
        m = lambda x: x <= a
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
   304
    elif expr.startswith("<"):
19194
1d08df65cd3c util: migrate fileset._sizetoint to util.sizetoint
Bryan O'Sullivan <bryano@fb.com>
parents: 18842
diff changeset
   305
        a = util.sizetoint(expr[1:])
14683
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
   306
        m = lambda x: x < a
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
   307
    elif expr.startswith(">="):
19194
1d08df65cd3c util: migrate fileset._sizetoint to util.sizetoint
Bryan O'Sullivan <bryano@fb.com>
parents: 18842
diff changeset
   308
        a = util.sizetoint(expr[2:])
14683
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
   309
        m = lambda x: x >= a
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
   310
    elif expr.startswith(">"):
19194
1d08df65cd3c util: migrate fileset._sizetoint to util.sizetoint
Bryan O'Sullivan <bryano@fb.com>
parents: 18842
diff changeset
   311
        a = util.sizetoint(expr[1:])
14683
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
   312
        m = lambda x: x > a
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
   313
    elif expr[0].isdigit or expr[0] == '.':
19194
1d08df65cd3c util: migrate fileset._sizetoint to util.sizetoint
Bryan O'Sullivan <bryano@fb.com>
parents: 18842
diff changeset
   314
        a = util.sizetoint(expr)
14683
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
   315
        b = _sizetomax(expr)
14690
15faf0e66909 fileset: add missing whitespace around operator
Thomas Arendsen Hein <thomas@intevation.de>
parents: 14689
diff changeset
   316
        m = lambda x: x >= a and x <= b
14683
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
   317
    else:
14716
552329013bac fileset: use ParseError pos field correctly
Mads Kiilerich <mads@kiilerich.com>
parents: 14701
diff changeset
   318
        raise error.ParseError(_("couldn't parse size: %s") % expr)
14683
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
   319
15963
042e84e39dee fileset: don't attempt to check data predicates against removed files
Matt Mackall <mpm@selenic.com>
parents: 14830
diff changeset
   320
    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
   321
14684
87b9d6a7d807 fileset: add encoding() predicate
Matt Mackall <mpm@selenic.com>
parents: 14683
diff changeset
   322
def encoding(mctx, x):
87b9d6a7d807 fileset: add encoding() predicate
Matt Mackall <mpm@selenic.com>
parents: 14683
diff changeset
   323
    """``encoding(name)``
87b9d6a7d807 fileset: add encoding() predicate
Matt Mackall <mpm@selenic.com>
parents: 14683
diff changeset
   324
    File can be successfully decoded with the given character
87b9d6a7d807 fileset: add encoding() predicate
Matt Mackall <mpm@selenic.com>
parents: 14683
diff changeset
   325
    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
   326
    UTF-8.
87b9d6a7d807 fileset: add encoding() predicate
Matt Mackall <mpm@selenic.com>
parents: 14683
diff changeset
   327
    """
87b9d6a7d807 fileset: add encoding() predicate
Matt Mackall <mpm@selenic.com>
parents: 14683
diff changeset
   328
14785
0f0bd4d028d3 fileset: add i18n hints for keywords
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 14718
diff changeset
   329
    # i18n: "encoding" is a keyword
14684
87b9d6a7d807 fileset: add encoding() predicate
Matt Mackall <mpm@selenic.com>
parents: 14683
diff changeset
   330
    enc = getstring(x, _("encoding requires an encoding name"))
87b9d6a7d807 fileset: add encoding() predicate
Matt Mackall <mpm@selenic.com>
parents: 14683
diff changeset
   331
87b9d6a7d807 fileset: add encoding() predicate
Matt Mackall <mpm@selenic.com>
parents: 14683
diff changeset
   332
    s = []
15963
042e84e39dee fileset: don't attempt to check data predicates against removed files
Matt Mackall <mpm@selenic.com>
parents: 14830
diff changeset
   333
    for f in mctx.existing():
14684
87b9d6a7d807 fileset: add encoding() predicate
Matt Mackall <mpm@selenic.com>
parents: 14683
diff changeset
   334
        d = mctx.ctx[f].data()
87b9d6a7d807 fileset: add encoding() predicate
Matt Mackall <mpm@selenic.com>
parents: 14683
diff changeset
   335
        try:
87b9d6a7d807 fileset: add encoding() predicate
Matt Mackall <mpm@selenic.com>
parents: 14683
diff changeset
   336
            d.decode(enc)
87b9d6a7d807 fileset: add encoding() predicate
Matt Mackall <mpm@selenic.com>
parents: 14683
diff changeset
   337
        except LookupError:
87b9d6a7d807 fileset: add encoding() predicate
Matt Mackall <mpm@selenic.com>
parents: 14683
diff changeset
   338
            raise util.Abort(_("unknown encoding '%s'") % enc)
87b9d6a7d807 fileset: add encoding() predicate
Matt Mackall <mpm@selenic.com>
parents: 14683
diff changeset
   339
        except UnicodeDecodeError:
87b9d6a7d807 fileset: add encoding() predicate
Matt Mackall <mpm@selenic.com>
parents: 14683
diff changeset
   340
            continue
87b9d6a7d807 fileset: add encoding() predicate
Matt Mackall <mpm@selenic.com>
parents: 14683
diff changeset
   341
        s.append(f)
87b9d6a7d807 fileset: add encoding() predicate
Matt Mackall <mpm@selenic.com>
parents: 14683
diff changeset
   342
87b9d6a7d807 fileset: add encoding() predicate
Matt Mackall <mpm@selenic.com>
parents: 14683
diff changeset
   343
    return s
87b9d6a7d807 fileset: add encoding() predicate
Matt Mackall <mpm@selenic.com>
parents: 14683
diff changeset
   344
18842
3ce3f2b059a1 filesets: add eol predicate
Matt Mackall <mpm@selenic.com>
parents: 18364
diff changeset
   345
def eol(mctx, x):
3ce3f2b059a1 filesets: add eol predicate
Matt Mackall <mpm@selenic.com>
parents: 18364
diff changeset
   346
    """``eol(style)``
3ce3f2b059a1 filesets: add eol predicate
Matt Mackall <mpm@selenic.com>
parents: 18364
diff changeset
   347
    File contains newlines of the given style (dos, unix, mac). Binary
3ce3f2b059a1 filesets: add eol predicate
Matt Mackall <mpm@selenic.com>
parents: 18364
diff changeset
   348
    files are excluded, files with mixed line endings match multiple
3ce3f2b059a1 filesets: add eol predicate
Matt Mackall <mpm@selenic.com>
parents: 18364
diff changeset
   349
    styles.
3ce3f2b059a1 filesets: add eol predicate
Matt Mackall <mpm@selenic.com>
parents: 18364
diff changeset
   350
    """
3ce3f2b059a1 filesets: add eol predicate
Matt Mackall <mpm@selenic.com>
parents: 18364
diff changeset
   351
3ce3f2b059a1 filesets: add eol predicate
Matt Mackall <mpm@selenic.com>
parents: 18364
diff changeset
   352
    # i18n: "encoding" is a keyword
3ce3f2b059a1 filesets: add eol predicate
Matt Mackall <mpm@selenic.com>
parents: 18364
diff changeset
   353
    enc = getstring(x, _("encoding requires an encoding name"))
3ce3f2b059a1 filesets: add eol predicate
Matt Mackall <mpm@selenic.com>
parents: 18364
diff changeset
   354
3ce3f2b059a1 filesets: add eol predicate
Matt Mackall <mpm@selenic.com>
parents: 18364
diff changeset
   355
    s = []
3ce3f2b059a1 filesets: add eol predicate
Matt Mackall <mpm@selenic.com>
parents: 18364
diff changeset
   356
    for f in mctx.existing():
3ce3f2b059a1 filesets: add eol predicate
Matt Mackall <mpm@selenic.com>
parents: 18364
diff changeset
   357
        d = mctx.ctx[f].data()
3ce3f2b059a1 filesets: add eol predicate
Matt Mackall <mpm@selenic.com>
parents: 18364
diff changeset
   358
        if util.binary(d):
3ce3f2b059a1 filesets: add eol predicate
Matt Mackall <mpm@selenic.com>
parents: 18364
diff changeset
   359
            continue
3ce3f2b059a1 filesets: add eol predicate
Matt Mackall <mpm@selenic.com>
parents: 18364
diff changeset
   360
        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
   361
            s.append(f)
3ce3f2b059a1 filesets: add eol predicate
Matt Mackall <mpm@selenic.com>
parents: 18364
diff changeset
   362
        elif enc == 'unix' and re.search('(?<!\r)\n', d):
3ce3f2b059a1 filesets: add eol predicate
Matt Mackall <mpm@selenic.com>
parents: 18364
diff changeset
   363
            s.append(f)
3ce3f2b059a1 filesets: add eol predicate
Matt Mackall <mpm@selenic.com>
parents: 18364
diff changeset
   364
        elif enc == 'mac' and re.search('\r(?!\n)', d):
3ce3f2b059a1 filesets: add eol predicate
Matt Mackall <mpm@selenic.com>
parents: 18364
diff changeset
   365
            s.append(f)
3ce3f2b059a1 filesets: add eol predicate
Matt Mackall <mpm@selenic.com>
parents: 18364
diff changeset
   366
    return s
3ce3f2b059a1 filesets: add eol predicate
Matt Mackall <mpm@selenic.com>
parents: 18364
diff changeset
   367
14685
394121d9f4fc fileset: add copied predicate
Matt Mackall <mpm@selenic.com>
parents: 14684
diff changeset
   368
def copied(mctx, x):
394121d9f4fc fileset: add copied predicate
Matt Mackall <mpm@selenic.com>
parents: 14684
diff changeset
   369
    """``copied()``
394121d9f4fc fileset: add copied predicate
Matt Mackall <mpm@selenic.com>
parents: 14684
diff changeset
   370
    File that is recorded as being copied.
394121d9f4fc fileset: add copied predicate
Matt Mackall <mpm@selenic.com>
parents: 14684
diff changeset
   371
    """
14785
0f0bd4d028d3 fileset: add i18n hints for keywords
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 14718
diff changeset
   372
    # i18n: "copied" is a keyword
14718
0c81948636f3 fileset: copied takes no arguments
Mads Kiilerich <mads@kiilerich.com>
parents: 14717
diff changeset
   373
    getargs(x, 0, 0, _("copied takes no arguments"))
14685
394121d9f4fc fileset: add copied predicate
Matt Mackall <mpm@selenic.com>
parents: 14684
diff changeset
   374
    s = []
394121d9f4fc fileset: add copied predicate
Matt Mackall <mpm@selenic.com>
parents: 14684
diff changeset
   375
    for f in mctx.subset:
394121d9f4fc fileset: add copied predicate
Matt Mackall <mpm@selenic.com>
parents: 14684
diff changeset
   376
        p = mctx.ctx[f].parents()
394121d9f4fc fileset: add copied predicate
Matt Mackall <mpm@selenic.com>
parents: 14684
diff changeset
   377
        if p and p[0].path() != f:
394121d9f4fc fileset: add copied predicate
Matt Mackall <mpm@selenic.com>
parents: 14684
diff changeset
   378
            s.append(f)
394121d9f4fc fileset: add copied predicate
Matt Mackall <mpm@selenic.com>
parents: 14684
diff changeset
   379
    return s
394121d9f4fc fileset: add copied predicate
Matt Mackall <mpm@selenic.com>
parents: 14684
diff changeset
   380
16443
9e02e032b522 fileset: add "subrepo" fileset symbol
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 15963
diff changeset
   381
def subrepo(mctx, x):
9e02e032b522 fileset: add "subrepo" fileset symbol
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 15963
diff changeset
   382
    """``subrepo([pattern])``
9e02e032b522 fileset: add "subrepo" fileset symbol
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 15963
diff changeset
   383
    Subrepositories whose paths match the given pattern.
9e02e032b522 fileset: add "subrepo" fileset symbol
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 15963
diff changeset
   384
    """
9e02e032b522 fileset: add "subrepo" fileset symbol
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 15963
diff changeset
   385
    # i18n: "subrepo" is a keyword
9e02e032b522 fileset: add "subrepo" fileset symbol
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 15963
diff changeset
   386
    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
   387
    ctx = mctx.ctx
18364
6252b4f1c4b4 subrepos: process subrepos in sorted order
Mads Kiilerich <mads@kiilerich.com>
parents: 17371
diff changeset
   388
    sstate = sorted(ctx.substate)
16443
9e02e032b522 fileset: add "subrepo" fileset symbol
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 15963
diff changeset
   389
    if x:
9e02e032b522 fileset: add "subrepo" fileset symbol
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 15963
diff changeset
   390
        pat = getstring(x, _("subrepo requires a pattern or no arguments"))
9e02e032b522 fileset: add "subrepo" fileset symbol
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 15963
diff changeset
   391
9e02e032b522 fileset: add "subrepo" fileset symbol
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 15963
diff changeset
   392
        import match as matchmod # avoid circular import issues
9e02e032b522 fileset: add "subrepo" fileset symbol
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 15963
diff changeset
   393
        fast = not matchmod.patkind(pat)
9e02e032b522 fileset: add "subrepo" fileset symbol
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 15963
diff changeset
   394
        if fast:
9e02e032b522 fileset: add "subrepo" fileset symbol
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 15963
diff changeset
   395
            def m(s):
9e02e032b522 fileset: add "subrepo" fileset symbol
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 15963
diff changeset
   396
                return (s == pat)
9e02e032b522 fileset: add "subrepo" fileset symbol
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 15963
diff changeset
   397
        else:
9e02e032b522 fileset: add "subrepo" fileset symbol
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 15963
diff changeset
   398
            m = matchmod.match(ctx._repo.root, '', [pat], ctx=ctx)
9e02e032b522 fileset: add "subrepo" fileset symbol
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 15963
diff changeset
   399
        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
   400
    else:
9e02e032b522 fileset: add "subrepo" fileset symbol
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 15963
diff changeset
   401
        return [sub for sub in sstate]
9e02e032b522 fileset: add "subrepo" fileset symbol
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 15963
diff changeset
   402
14676
e80fa502b8cf fileset: add some basic predicates
Matt Mackall <mpm@selenic.com>
parents: 14673
diff changeset
   403
symbols = {
14677
2a758ffc821e fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents: 14676
diff changeset
   404
    'added': added,
14676
e80fa502b8cf fileset: add some basic predicates
Matt Mackall <mpm@selenic.com>
parents: 14673
diff changeset
   405
    'binary': binary,
14677
2a758ffc821e fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents: 14676
diff changeset
   406
    'clean': clean,
14685
394121d9f4fc fileset: add copied predicate
Matt Mackall <mpm@selenic.com>
parents: 14684
diff changeset
   407
    'copied': copied,
14677
2a758ffc821e fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents: 14676
diff changeset
   408
    'deleted': deleted,
14684
87b9d6a7d807 fileset: add encoding() predicate
Matt Mackall <mpm@selenic.com>
parents: 14683
diff changeset
   409
    'encoding': encoding,
18842
3ce3f2b059a1 filesets: add eol predicate
Matt Mackall <mpm@selenic.com>
parents: 18364
diff changeset
   410
    'eol': eol,
14676
e80fa502b8cf fileset: add some basic predicates
Matt Mackall <mpm@selenic.com>
parents: 14673
diff changeset
   411
    'exec': exec_,
14682
8785fd757077 fileset: add grep predicate
Matt Mackall <mpm@selenic.com>
parents: 14681
diff changeset
   412
    'grep': grep,
14677
2a758ffc821e fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents: 14676
diff changeset
   413
    'ignored': ignored,
14680
49af5fa3809b fileset: add hgignore
Matt Mackall <mpm@selenic.com>
parents: 14679
diff changeset
   414
    'hgignore': hgignore,
14677
2a758ffc821e fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents: 14676
diff changeset
   415
    'modified': modified,
2a758ffc821e fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents: 14676
diff changeset
   416
    'removed': removed,
14679
e141e1cee0cc fileset: add resolved and unresolved predicates
Matt Mackall <mpm@selenic.com>
parents: 14678
diff changeset
   417
    'resolved': resolved,
14683
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
   418
    'size': size,
14676
e80fa502b8cf fileset: add some basic predicates
Matt Mackall <mpm@selenic.com>
parents: 14673
diff changeset
   419
    'symlink': symlink,
14677
2a758ffc821e fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents: 14676
diff changeset
   420
    'unknown': unknown,
14679
e141e1cee0cc fileset: add resolved and unresolved predicates
Matt Mackall <mpm@selenic.com>
parents: 14678
diff changeset
   421
    'unresolved': unresolved,
16443
9e02e032b522 fileset: add "subrepo" fileset symbol
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 15963
diff changeset
   422
    'subrepo': subrepo,
14676
e80fa502b8cf fileset: add some basic predicates
Matt Mackall <mpm@selenic.com>
parents: 14673
diff changeset
   423
}
e80fa502b8cf fileset: add some basic predicates
Matt Mackall <mpm@selenic.com>
parents: 14673
diff changeset
   424
14551
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
   425
methods = {
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
   426
    'string': stringset,
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
   427
    'symbol': stringset,
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
   428
    'and': andset,
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
   429
    'or': orset,
17363
5d9e2031c0b1 fileset: actually implement 'minusset'
Patrick Mezard <patrick@mezard.eu>
parents: 16443
diff changeset
   430
    'minus': minusset,
14551
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
   431
    'list': listset,
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
   432
    'group': getset,
14676
e80fa502b8cf fileset: add some basic predicates
Matt Mackall <mpm@selenic.com>
parents: 14673
diff changeset
   433
    'not': notset,
e80fa502b8cf fileset: add some basic predicates
Matt Mackall <mpm@selenic.com>
parents: 14673
diff changeset
   434
    'func': func,
14551
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
   435
}
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
   436
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
   437
class matchctx(object):
14677
2a758ffc821e fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents: 14676
diff changeset
   438
    def __init__(self, ctx, subset=None, status=None):
14551
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
   439
        self.ctx = ctx
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
   440
        self.subset = subset
14677
2a758ffc821e fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents: 14676
diff changeset
   441
        self._status = status
2a758ffc821e fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents: 14676
diff changeset
   442
    def status(self):
2a758ffc821e fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents: 14676
diff changeset
   443
        return self._status
14673
b0566467c492 fileset: drop matchfn
Matt Mackall <mpm@selenic.com>
parents: 14554
diff changeset
   444
    def matcher(self, patterns):
b0566467c492 fileset: drop matchfn
Matt Mackall <mpm@selenic.com>
parents: 14554
diff changeset
   445
        return self.ctx.match(patterns)
14551
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
   446
    def filter(self, files):
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
   447
        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
   448
    def existing(self):
17365
8a0513bf030a fileset: exclude deleted files from matchctx.existing()
Patrick Mezard <patrick@mezard.eu>
parents: 17363
diff changeset
   449
        if self._status is not None:
8a0513bf030a fileset: exclude deleted files from matchctx.existing()
Patrick Mezard <patrick@mezard.eu>
parents: 17363
diff changeset
   450
            removed = set(self._status[3])
17367
ce625185cfd9 fileset: matchctx.existing() must consider ignored files
Patrick Mezard <patrick@mezard.eu>
parents: 17366
diff changeset
   451
            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
   452
        else:
8a0513bf030a fileset: exclude deleted files from matchctx.existing()
Patrick Mezard <patrick@mezard.eu>
parents: 17363
diff changeset
   453
            removed = set()
17366
04c65cb59467 fileset: matchctx.existing() must consider unknown files
Patrick Mezard <patrick@mezard.eu>
parents: 17365
diff changeset
   454
            unknown = set()
17365
8a0513bf030a fileset: exclude deleted files from matchctx.existing()
Patrick Mezard <patrick@mezard.eu>
parents: 17363
diff changeset
   455
        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
   456
                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
   457
    def narrow(self, files):
14677
2a758ffc821e fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents: 14676
diff changeset
   458
        return matchctx(self.ctx, self.filter(files), self._status)
14551
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
   459
14678
5ef7b87530f6 fileset: prescan parse tree to optimize status usage
Matt Mackall <mpm@selenic.com>
parents: 14677
diff changeset
   460
def _intree(funcs, tree):
5ef7b87530f6 fileset: prescan parse tree to optimize status usage
Matt Mackall <mpm@selenic.com>
parents: 14677
diff changeset
   461
    if isinstance(tree, tuple):
5ef7b87530f6 fileset: prescan parse tree to optimize status usage
Matt Mackall <mpm@selenic.com>
parents: 14677
diff changeset
   462
        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
   463
            if tree[1][1] in funcs:
5ef7b87530f6 fileset: prescan parse tree to optimize status usage
Matt Mackall <mpm@selenic.com>
parents: 14677
diff changeset
   464
                return True
5ef7b87530f6 fileset: prescan parse tree to optimize status usage
Matt Mackall <mpm@selenic.com>
parents: 14677
diff changeset
   465
        for s in tree[1:]:
5ef7b87530f6 fileset: prescan parse tree to optimize status usage
Matt Mackall <mpm@selenic.com>
parents: 14677
diff changeset
   466
            if _intree(funcs, s):
5ef7b87530f6 fileset: prescan parse tree to optimize status usage
Matt Mackall <mpm@selenic.com>
parents: 14677
diff changeset
   467
                return True
5ef7b87530f6 fileset: prescan parse tree to optimize status usage
Matt Mackall <mpm@selenic.com>
parents: 14677
diff changeset
   468
    return False
5ef7b87530f6 fileset: prescan parse tree to optimize status usage
Matt Mackall <mpm@selenic.com>
parents: 14677
diff changeset
   469
17365
8a0513bf030a fileset: exclude deleted files from matchctx.existing()
Patrick Mezard <patrick@mezard.eu>
parents: 17363
diff changeset
   470
# filesets using matchctx.existing()
8a0513bf030a fileset: exclude deleted files from matchctx.existing()
Patrick Mezard <patrick@mezard.eu>
parents: 17363
diff changeset
   471
_existingcallers = [
8a0513bf030a fileset: exclude deleted files from matchctx.existing()
Patrick Mezard <patrick@mezard.eu>
parents: 17363
diff changeset
   472
    'binary',
8a0513bf030a fileset: exclude deleted files from matchctx.existing()
Patrick Mezard <patrick@mezard.eu>
parents: 17363
diff changeset
   473
    'exec',
8a0513bf030a fileset: exclude deleted files from matchctx.existing()
Patrick Mezard <patrick@mezard.eu>
parents: 17363
diff changeset
   474
    'grep',
8a0513bf030a fileset: exclude deleted files from matchctx.existing()
Patrick Mezard <patrick@mezard.eu>
parents: 17363
diff changeset
   475
    'size',
8a0513bf030a fileset: exclude deleted files from matchctx.existing()
Patrick Mezard <patrick@mezard.eu>
parents: 17363
diff changeset
   476
    'symlink',
8a0513bf030a fileset: exclude deleted files from matchctx.existing()
Patrick Mezard <patrick@mezard.eu>
parents: 17363
diff changeset
   477
]
8a0513bf030a fileset: exclude deleted files from matchctx.existing()
Patrick Mezard <patrick@mezard.eu>
parents: 17363
diff changeset
   478
14673
b0566467c492 fileset: drop matchfn
Matt Mackall <mpm@selenic.com>
parents: 14554
diff changeset
   479
def getfileset(ctx, expr):
14551
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
   480
    tree, pos = parse(expr)
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
   481
    if (pos != len(expr)):
14701
4b93bd041772 parsers: fix localization markup of parser errors
Mads Kiilerich <mads@kiilerich.com>
parents: 14700
diff changeset
   482
        raise error.ParseError(_("invalid token"), pos)
14678
5ef7b87530f6 fileset: prescan parse tree to optimize status usage
Matt Mackall <mpm@selenic.com>
parents: 14677
diff changeset
   483
5ef7b87530f6 fileset: prescan parse tree to optimize status usage
Matt Mackall <mpm@selenic.com>
parents: 14677
diff changeset
   484
    # do we need status info?
17365
8a0513bf030a fileset: exclude deleted files from matchctx.existing()
Patrick Mezard <patrick@mezard.eu>
parents: 17363
diff changeset
   485
    if (_intree(['modified', 'added', 'removed', 'deleted',
8a0513bf030a fileset: exclude deleted files from matchctx.existing()
Patrick Mezard <patrick@mezard.eu>
parents: 17363
diff changeset
   486
                 'unknown', 'ignored', 'clean'], tree) or
8a0513bf030a fileset: exclude deleted files from matchctx.existing()
Patrick Mezard <patrick@mezard.eu>
parents: 17363
diff changeset
   487
        # 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
   488
        # for deleted files.
8a0513bf030a fileset: exclude deleted files from matchctx.existing()
Patrick Mezard <patrick@mezard.eu>
parents: 17363
diff changeset
   489
        (ctx.rev() is None and _intree(_existingcallers, tree))):
14678
5ef7b87530f6 fileset: prescan parse tree to optimize status usage
Matt Mackall <mpm@selenic.com>
parents: 14677
diff changeset
   490
        unknown = _intree(['unknown'], tree)
5ef7b87530f6 fileset: prescan parse tree to optimize status usage
Matt Mackall <mpm@selenic.com>
parents: 14677
diff changeset
   491
        ignored = _intree(['ignored'], tree)
5ef7b87530f6 fileset: prescan parse tree to optimize status usage
Matt Mackall <mpm@selenic.com>
parents: 14677
diff changeset
   492
5ef7b87530f6 fileset: prescan parse tree to optimize status usage
Matt Mackall <mpm@selenic.com>
parents: 14677
diff changeset
   493
        r = ctx._repo
5ef7b87530f6 fileset: prescan parse tree to optimize status usage
Matt Mackall <mpm@selenic.com>
parents: 14677
diff changeset
   494
        status = r.status(ctx.p1(), ctx,
5ef7b87530f6 fileset: prescan parse tree to optimize status usage
Matt Mackall <mpm@selenic.com>
parents: 14677
diff changeset
   495
                          unknown=unknown, ignored=ignored, clean=True)
5ef7b87530f6 fileset: prescan parse tree to optimize status usage
Matt Mackall <mpm@selenic.com>
parents: 14677
diff changeset
   496
        subset = []
5ef7b87530f6 fileset: prescan parse tree to optimize status usage
Matt Mackall <mpm@selenic.com>
parents: 14677
diff changeset
   497
        for c in status:
5ef7b87530f6 fileset: prescan parse tree to optimize status usage
Matt Mackall <mpm@selenic.com>
parents: 14677
diff changeset
   498
            subset.extend(c)
5ef7b87530f6 fileset: prescan parse tree to optimize status usage
Matt Mackall <mpm@selenic.com>
parents: 14677
diff changeset
   499
    else:
5ef7b87530f6 fileset: prescan parse tree to optimize status usage
Matt Mackall <mpm@selenic.com>
parents: 14677
diff changeset
   500
        status = None
17371
1310489eb5d6 fileset: fix generator vs list bug in fast path
Patrick Mezard <patrick@mezard.eu>
parents: 17368
diff changeset
   501
        subset = list(ctx.walk(ctx.match([])))
14678
5ef7b87530f6 fileset: prescan parse tree to optimize status usage
Matt Mackall <mpm@selenic.com>
parents: 14677
diff changeset
   502
5ef7b87530f6 fileset: prescan parse tree to optimize status usage
Matt Mackall <mpm@selenic.com>
parents: 14677
diff changeset
   503
    return getset(matchctx(ctx, subset, status), tree)
14681
0744db5eb51c fileset: add some function help text
Matt Mackall <mpm@selenic.com>
parents: 14680
diff changeset
   504
0744db5eb51c fileset: add some function help text
Matt Mackall <mpm@selenic.com>
parents: 14680
diff changeset
   505
# tell hggettext to extract docstrings from these functions:
0744db5eb51c fileset: add some function help text
Matt Mackall <mpm@selenic.com>
parents: 14680
diff changeset
   506
i18nfunctions = symbols.values()