mercurial/fileset.py
author Yuya Nishihara <yuya@tcha.org>
Mon, 15 Feb 2016 22:46:07 +0900
branchstable
changeset 28253 c407583cf5f6
parent 28056 4f8ced23345e
child 28447 4eb5496c2bd4
permissions -rw-r--r--
log: fix order of revisions filtered by multiple OR options (issue5100) This is the simplest workaround for the issue of the ordering of revset, which is that the expression "x or y" takes over the ordering specified by the input set (or the left-hand-side expression.) For example, the following expression A & (x | y) will be evaluated as if (A & x) | (A & y) That's wrong because revset has ordering. I'm going to fix this problem in the revset module, but that wouldn't fit to stable. So, this patch just works around the common log cases. Since this change might have some impact on performance, it is enabled only if the expression built from log options has ' or ' operation.
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
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,
e194ada8d45f fileset: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25815
diff changeset
    15
    merge,
e194ada8d45f fileset: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25815
diff changeset
    16
    parser,
e194ada8d45f fileset: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25815
diff changeset
    17
    util,
e194ada8d45f fileset: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25815
diff changeset
    18
)
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    19
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    20
elements = {
25815
e71e5629e006 parser: separate actions for primary expression and prefix operator
Yuya Nishihara <yuya@tcha.org>
parents: 25801
diff changeset
    21
    # 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
    22
    "(": (20, None, ("group", 1, ")"), ("func", 1, ")"), None),
e71e5629e006 parser: separate actions for primary expression and prefix operator
Yuya Nishihara <yuya@tcha.org>
parents: 25801
diff changeset
    23
    "-": (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
    24
    "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
    25
    "!": (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
    26
    "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
    27
    "&": (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
    28
    "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
    29
    "|": (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
    30
    "+": (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
    31
    ",": (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
    32
    ")": (0, None, None, None, None),
e71e5629e006 parser: separate actions for primary expression and prefix operator
Yuya Nishihara <yuya@tcha.org>
parents: 25801
diff changeset
    33
    "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
    34
    "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
    35
    "end": (0, None, None, None, None),
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    36
}
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    37
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    38
keywords = set(['and', 'or', 'not'])
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    39
19470
19ac0d8ee9a2 fileset: handle underbar in symbols
Matt Mackall <mpm@selenic.com>
parents: 19194
diff changeset
    40
globchars = ".*{}[]?/\\_"
14551
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
    41
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    42
def tokenize(program):
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    43
    pos, l = 0, len(program)
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    44
    while pos < l:
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    45
        c = program[pos]
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    46
        if c.isspace(): # skip inter-token whitespace
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    47
            pass
14511
30506b894359 filesets: introduce basic fileset expression parser
Matt Mackall <mpm@selenic.com>
parents: 14509
diff changeset
    48
        elif c in "(),-|&+!": # handle simple operators
11289
4215ce511134 revset: raise ParseError exceptions
Matt Mackall <mpm@selenic.com>
parents: 11284
diff changeset
    49
            yield (c, None, pos)
12408
78a97859b90d revset: support raw string literals
Brodie Rao <brodie@bitheap.org>
parents: 12401
diff changeset
    50
        elif (c in '"\'' or c == 'r' and
78a97859b90d revset: support raw string literals
Brodie Rao <brodie@bitheap.org>
parents: 12401
diff changeset
    51
              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
    52
            if c == 'r':
78a97859b90d revset: support raw string literals
Brodie Rao <brodie@bitheap.org>
parents: 12401
diff changeset
    53
                pos += 1
78a97859b90d revset: support raw string literals
Brodie Rao <brodie@bitheap.org>
parents: 12401
diff changeset
    54
                c = program[pos]
78a97859b90d revset: support raw string literals
Brodie Rao <brodie@bitheap.org>
parents: 12401
diff changeset
    55
                decode = lambda x: x
78a97859b90d revset: support raw string literals
Brodie Rao <brodie@bitheap.org>
parents: 12401
diff changeset
    56
            else:
26233
d3dbb65c8dc6 fileset: handle error of string unescaping
Yuya Nishihara <yuya@tcha.org>
parents: 26195
diff changeset
    57
                decode = parser.unescapestr
11275
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
            s = pos
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    60
            while pos < l: # find closing quote
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    61
                d = program[pos]
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    62
                if d == '\\': # skip over escaped characters
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    63
                    pos += 2
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    64
                    continue
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    65
                if d == c:
12408
78a97859b90d revset: support raw string literals
Brodie Rao <brodie@bitheap.org>
parents: 12401
diff changeset
    66
                    yield ('string', decode(program[s:pos]), s)
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    67
                    break
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    68
                pos += 1
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    69
            else:
11383
de544774ebea revset: all your error messages are belong to _
Martin Geisler <mg@lazybytes.net>
parents: 11349
diff changeset
    70
                raise error.ParseError(_("unterminated string"), s)
14551
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
    71
        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
    72
            # gather up a symbol/keyword
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    73
            s = pos
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    74
            pos += 1
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    75
            while pos < l: # find end of symbol
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    76
                d = program[pos]
14551
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
    77
                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
    78
                    break
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    79
                pos += 1
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    80
            sym = program[s:pos]
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    81
            if sym in keywords: # operator keywords
11289
4215ce511134 revset: raise ParseError exceptions
Matt Mackall <mpm@selenic.com>
parents: 11284
diff changeset
    82
                yield (sym, None, s)
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    83
            else:
11289
4215ce511134 revset: raise ParseError exceptions
Matt Mackall <mpm@selenic.com>
parents: 11284
diff changeset
    84
                yield ('symbol', sym, s)
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    85
            pos -= 1
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    86
        else:
11383
de544774ebea revset: all your error messages are belong to _
Martin Geisler <mg@lazybytes.net>
parents: 11349
diff changeset
    87
            raise error.ParseError(_("syntax error"), pos)
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    88
        pos += 1
11289
4215ce511134 revset: raise ParseError exceptions
Matt Mackall <mpm@selenic.com>
parents: 11284
diff changeset
    89
    yield ('end', None, pos)
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    90
20208
61a47fd64f30 fileset, revset: do not use global parser object for thread safety
Yuya Nishihara <yuya@tcha.org>
parents: 19470
diff changeset
    91
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
    92
    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
    93
    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
    94
    if pos != len(expr):
ac381dd7a21f fileset: move validation of incomplete parsing to parse() function
Yuya Nishihara <yuya@tcha.org>
parents: 24408
diff changeset
    95
        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
    96
    return tree
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    97
14551
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
    98
def getstring(x, err):
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
    99
    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
   100
        return x[1]
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
   101
    raise error.ParseError(err)
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
   102
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
   103
def getset(mctx, x):
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
   104
    if not x:
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
   105
        raise error.ParseError(_("missing argument"))
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
   106
    return methods[x[0]](mctx, *x[1:])
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 stringset(mctx, x):
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
   109
    m = mctx.matcher([x])
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
   110
    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
   111
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
   112
def andset(mctx, x, y):
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
   113
    return getset(mctx.narrow(getset(mctx, x)), y)
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
   114
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
   115
def orset(mctx, x, y):
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
   116
    # needs optimizing
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
   117
    xl = getset(mctx, x)
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
   118
    yl = getset(mctx, y)
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
   119
    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
   120
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
   121
def notset(mctx, x):
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
   122
    s = set(getset(mctx, x))
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
   123
    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
   124
17363
5d9e2031c0b1 fileset: actually implement 'minusset'
Patrick Mezard <patrick@mezard.eu>
parents: 16443
diff changeset
   125
def minusset(mctx, x, y):
5d9e2031c0b1 fileset: actually implement 'minusset'
Patrick Mezard <patrick@mezard.eu>
parents: 16443
diff changeset
   126
    xl = getset(mctx, x)
5d9e2031c0b1 fileset: actually implement 'minusset'
Patrick Mezard <patrick@mezard.eu>
parents: 16443
diff changeset
   127
    yl = set(getset(mctx, y))
5d9e2031c0b1 fileset: actually implement 'minusset'
Patrick Mezard <patrick@mezard.eu>
parents: 16443
diff changeset
   128
    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
   129
14551
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
   130
def listset(mctx, a, b):
27518
737ffdabbde9 fileset: add hint for list error to use or
timeless <timeless@mozdev.org>
parents: 27464
diff changeset
   131
    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
   132
                           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
   133
27460
11286ac374f3 fileset: use decorator to mark a function as fileset predicate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27459
diff changeset
   134
# 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
   135
#  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
   136
# with:
11286ac374f3 fileset: use decorator to mark a function as fileset predicate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27459
diff changeset
   137
#  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
   138
#  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
   139
symbols = {}
11286ac374f3 fileset: use decorator to mark a function as fileset predicate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27459
diff changeset
   140
27461
afa76585c955 fileset: use decorator to mark a predicate as "status caller"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27460
diff changeset
   141
# 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
   142
_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
   143
27462
470ea34ba593 fileset: use decorator to mark a predicate as "existing caller"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27461
diff changeset
   144
# 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
   145
_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
   146
470ea34ba593 fileset: use decorator to mark a predicate as "existing caller"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27461
diff changeset
   147
def predicate(decl, callstatus=False, callexisting=False):
27460
11286ac374f3 fileset: use decorator to mark a function as fileset predicate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27459
diff changeset
   148
    """Return a decorator for fileset predicate function
11286ac374f3 fileset: use decorator to mark a function as fileset predicate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27459
diff changeset
   149
11286ac374f3 fileset: use decorator to mark a function as fileset predicate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27459
diff changeset
   150
    'decl' argument is the declaration (including argument list like
11286ac374f3 fileset: use decorator to mark a function as fileset predicate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27459
diff changeset
   151
    'adds(pattern)') or the name (for internal use only) of predicate.
27461
afa76585c955 fileset: use decorator to mark a predicate as "status caller"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27460
diff changeset
   152
afa76585c955 fileset: use decorator to mark a predicate as "status caller"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27460
diff changeset
   153
    Optional 'callstatus' argument indicates whether predicate implies
afa76585c955 fileset: use decorator to mark a predicate as "status caller"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27460
diff changeset
   154
    'matchctx.status()' at runtime or not (False, by default).
27462
470ea34ba593 fileset: use decorator to mark a predicate as "existing caller"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27461
diff changeset
   155
470ea34ba593 fileset: use decorator to mark a predicate as "existing caller"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27461
diff changeset
   156
    Optional 'callexisting' argument indicates whether predicate
470ea34ba593 fileset: use decorator to mark a predicate as "existing caller"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27461
diff changeset
   157
    implies 'matchctx.existing()' at runtime or not (False, by
470ea34ba593 fileset: use decorator to mark a predicate as "existing caller"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27461
diff changeset
   158
    default).
27460
11286ac374f3 fileset: use decorator to mark a function as fileset predicate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27459
diff changeset
   159
    """
11286ac374f3 fileset: use decorator to mark a function as fileset predicate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27459
diff changeset
   160
    def decorator(func):
11286ac374f3 fileset: use decorator to mark a function as fileset predicate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27459
diff changeset
   161
        i = decl.find('(')
11286ac374f3 fileset: use decorator to mark a function as fileset predicate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27459
diff changeset
   162
        if i > 0:
11286ac374f3 fileset: use decorator to mark a function as fileset predicate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27459
diff changeset
   163
            name = decl[:i]
11286ac374f3 fileset: use decorator to mark a function as fileset predicate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27459
diff changeset
   164
        else:
11286ac374f3 fileset: use decorator to mark a function as fileset predicate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27459
diff changeset
   165
            name = decl
11286ac374f3 fileset: use decorator to mark a function as fileset predicate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27459
diff changeset
   166
        symbols[name] = func
27461
afa76585c955 fileset: use decorator to mark a predicate as "status caller"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27460
diff changeset
   167
        if callstatus:
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
   168
            _statuscallers.add(name)
27462
470ea34ba593 fileset: use decorator to mark a predicate as "existing caller"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27461
diff changeset
   169
        if callexisting:
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
   170
            _existingcallers.add(name)
27460
11286ac374f3 fileset: use decorator to mark a function as fileset predicate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27459
diff changeset
   171
        if func.__doc__:
11286ac374f3 fileset: use decorator to mark a function as fileset predicate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27459
diff changeset
   172
            func.__doc__ = "``%s``\n    %s" % (decl, func.__doc__.strip())
11286ac374f3 fileset: use decorator to mark a function as fileset predicate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27459
diff changeset
   173
        return func
11286ac374f3 fileset: use decorator to mark a function as fileset predicate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27459
diff changeset
   174
    return decorator
11286ac374f3 fileset: use decorator to mark a function as fileset predicate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27459
diff changeset
   175
27461
afa76585c955 fileset: use decorator to mark a predicate as "status caller"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27460
diff changeset
   176
@predicate('modified()', callstatus=True)
14677
2a758ffc821e fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents: 14676
diff changeset
   177
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
   178
    """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
   179
    """
14785
0f0bd4d028d3 fileset: add i18n hints for keywords
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 14718
diff changeset
   180
    # i18n: "modified" 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, _("modified takes no arguments"))
22924
325babf1de93 fileset: access status fields by name rather than index
Martin von Zweigbergk <martinvonz@gmail.com>
parents: 20209
diff changeset
   182
    s = mctx.status().modified
14677
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
27461
afa76585c955 fileset: use decorator to mark a predicate as "status caller"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27460
diff changeset
   185
@predicate('added()', callstatus=True)
14677
2a758ffc821e fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents: 14676
diff changeset
   186
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
   187
    """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
   188
    """
14785
0f0bd4d028d3 fileset: add i18n hints for keywords
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 14718
diff changeset
   189
    # i18n: "added" is a keyword
14677
2a758ffc821e fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents: 14676
diff changeset
   190
    getargs(x, 0, 0, _("added takes no arguments"))
22924
325babf1de93 fileset: access status fields by name rather than index
Martin von Zweigbergk <martinvonz@gmail.com>
parents: 20209
diff changeset
   191
    s = mctx.status().added
14677
2a758ffc821e fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents: 14676
diff changeset
   192
    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
   193
27461
afa76585c955 fileset: use decorator to mark a predicate as "status caller"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27460
diff changeset
   194
@predicate('removed()', callstatus=True)
14677
2a758ffc821e fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents: 14676
diff changeset
   195
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
   196
    """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
   197
    """
14785
0f0bd4d028d3 fileset: add i18n hints for keywords
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 14718
diff changeset
   198
    # i18n: "removed" is a keyword
14677
2a758ffc821e fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents: 14676
diff changeset
   199
    getargs(x, 0, 0, _("removed takes no arguments"))
22924
325babf1de93 fileset: access status fields by name rather than index
Martin von Zweigbergk <martinvonz@gmail.com>
parents: 20209
diff changeset
   200
    s = mctx.status().removed
14677
2a758ffc821e fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents: 14676
diff changeset
   201
    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
   202
27461
afa76585c955 fileset: use decorator to mark a predicate as "status caller"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27460
diff changeset
   203
@predicate('deleted()', callstatus=True)
14677
2a758ffc821e fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents: 14676
diff changeset
   204
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
   205
    """Alias for ``missing()``.
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: "deleted" is a keyword
14677
2a758ffc821e fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents: 14676
diff changeset
   208
    getargs(x, 0, 0, _("deleted takes no arguments"))
22924
325babf1de93 fileset: access status fields by name rather than index
Martin von Zweigbergk <martinvonz@gmail.com>
parents: 20209
diff changeset
   209
    s = mctx.status().deleted
14677
2a758ffc821e fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents: 14676
diff changeset
   210
    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
   211
27461
afa76585c955 fileset: use decorator to mark a predicate as "status caller"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27460
diff changeset
   212
@predicate('missing()', callstatus=True)
27024
ceef5fb14872 fileset: add missing() predicate (issue4925)
liscju <piotr.listkiewicz@gmail.com>
parents: 26995
diff changeset
   213
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
   214
    """File that is missing according to :hg:`status`.
27024
ceef5fb14872 fileset: add missing() predicate (issue4925)
liscju <piotr.listkiewicz@gmail.com>
parents: 26995
diff changeset
   215
    """
ceef5fb14872 fileset: add missing() predicate (issue4925)
liscju <piotr.listkiewicz@gmail.com>
parents: 26995
diff changeset
   216
    # i18n: "missing" is a keyword
ceef5fb14872 fileset: add missing() predicate (issue4925)
liscju <piotr.listkiewicz@gmail.com>
parents: 26995
diff changeset
   217
    getargs(x, 0, 0, _("missing takes no arguments"))
ceef5fb14872 fileset: add missing() predicate (issue4925)
liscju <piotr.listkiewicz@gmail.com>
parents: 26995
diff changeset
   218
    s = mctx.status().deleted
ceef5fb14872 fileset: add missing() predicate (issue4925)
liscju <piotr.listkiewicz@gmail.com>
parents: 26995
diff changeset
   219
    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
   220
27461
afa76585c955 fileset: use decorator to mark a predicate as "status caller"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27460
diff changeset
   221
@predicate('unknown()', callstatus=True)
14677
2a758ffc821e fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents: 14676
diff changeset
   222
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
   223
    """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
   224
    considered if this predicate is used.
0744db5eb51c fileset: add some function help text
Matt Mackall <mpm@selenic.com>
parents: 14680
diff changeset
   225
    """
14785
0f0bd4d028d3 fileset: add i18n hints for keywords
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 14718
diff changeset
   226
    # i18n: "unknown" is a keyword
14677
2a758ffc821e fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents: 14676
diff changeset
   227
    getargs(x, 0, 0, _("unknown takes no arguments"))
22924
325babf1de93 fileset: access status fields by name rather than index
Martin von Zweigbergk <martinvonz@gmail.com>
parents: 20209
diff changeset
   228
    s = mctx.status().unknown
14677
2a758ffc821e fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents: 14676
diff changeset
   229
    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
   230
27461
afa76585c955 fileset: use decorator to mark a predicate as "status caller"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27460
diff changeset
   231
@predicate('ignored()', callstatus=True)
14677
2a758ffc821e fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents: 14676
diff changeset
   232
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
   233
    """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
   234
    considered if this predicate is used.
0744db5eb51c fileset: add some function help text
Matt Mackall <mpm@selenic.com>
parents: 14680
diff changeset
   235
    """
14785
0f0bd4d028d3 fileset: add i18n hints for keywords
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 14718
diff changeset
   236
    # i18n: "ignored" is a keyword
14677
2a758ffc821e fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents: 14676
diff changeset
   237
    getargs(x, 0, 0, _("ignored takes no arguments"))
22924
325babf1de93 fileset: access status fields by name rather than index
Martin von Zweigbergk <martinvonz@gmail.com>
parents: 20209
diff changeset
   238
    s = mctx.status().ignored
14677
2a758ffc821e fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents: 14676
diff changeset
   239
    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
   240
27461
afa76585c955 fileset: use decorator to mark a predicate as "status caller"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27460
diff changeset
   241
@predicate('clean()', callstatus=True)
14677
2a758ffc821e fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents: 14676
diff changeset
   242
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
   243
    """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
   244
    """
14785
0f0bd4d028d3 fileset: add i18n hints for keywords
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 14718
diff changeset
   245
    # i18n: "clean" is a keyword
14677
2a758ffc821e fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents: 14676
diff changeset
   246
    getargs(x, 0, 0, _("clean takes no arguments"))
22924
325babf1de93 fileset: access status fields by name rather than index
Martin von Zweigbergk <martinvonz@gmail.com>
parents: 20209
diff changeset
   247
    s = mctx.status().clean
14677
2a758ffc821e fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents: 14676
diff changeset
   248
    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
   249
14676
e80fa502b8cf fileset: add some basic predicates
Matt Mackall <mpm@selenic.com>
parents: 14673
diff changeset
   250
def func(mctx, a, b):
e80fa502b8cf fileset: add some basic predicates
Matt Mackall <mpm@selenic.com>
parents: 14673
diff changeset
   251
    if a[0] == 'symbol' and a[1] in symbols:
27464
c39ecb2b86b3 fileset: detect unintentional existing() invocation at runtime
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27463
diff changeset
   252
        funcname = a[1]
c39ecb2b86b3 fileset: detect unintentional existing() invocation at runtime
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27463
diff changeset
   253
        enabled = mctx._existingenabled
c39ecb2b86b3 fileset: detect unintentional existing() invocation at runtime
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27463
diff changeset
   254
        mctx._existingenabled = funcname in _existingcallers
c39ecb2b86b3 fileset: detect unintentional existing() invocation at runtime
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27463
diff changeset
   255
        try:
c39ecb2b86b3 fileset: detect unintentional existing() invocation at runtime
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27463
diff changeset
   256
            return symbols[funcname](mctx, b)
c39ecb2b86b3 fileset: detect unintentional existing() invocation at runtime
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27463
diff changeset
   257
        finally:
c39ecb2b86b3 fileset: detect unintentional existing() invocation at runtime
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27463
diff changeset
   258
            mctx._existingenabled = enabled
25633
0f44d35731d6 fileset: don't suggest private or undocumented queries
Matt Harbison <matt_harbison@yahoo.com>
parents: 25255
diff changeset
   259
0f44d35731d6 fileset: don't suggest private or undocumented queries
Matt Harbison <matt_harbison@yahoo.com>
parents: 25255
diff changeset
   260
    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
   261
0f44d35731d6 fileset: don't suggest private or undocumented queries
Matt Harbison <matt_harbison@yahoo.com>
parents: 25255
diff changeset
   262
    syms = [s for (s, fn) in symbols.items() if keep(fn)]
0f44d35731d6 fileset: don't suggest private or undocumented queries
Matt Harbison <matt_harbison@yahoo.com>
parents: 25255
diff changeset
   263
    raise error.UnknownIdentifier(a[1], syms)
14676
e80fa502b8cf fileset: add some basic predicates
Matt Mackall <mpm@selenic.com>
parents: 14673
diff changeset
   264
e80fa502b8cf fileset: add some basic predicates
Matt Mackall <mpm@selenic.com>
parents: 14673
diff changeset
   265
def getlist(x):
e80fa502b8cf fileset: add some basic predicates
Matt Mackall <mpm@selenic.com>
parents: 14673
diff changeset
   266
    if not x:
e80fa502b8cf fileset: add some basic predicates
Matt Mackall <mpm@selenic.com>
parents: 14673
diff changeset
   267
        return []
e80fa502b8cf fileset: add some basic predicates
Matt Mackall <mpm@selenic.com>
parents: 14673
diff changeset
   268
    if x[0] == 'list':
e80fa502b8cf fileset: add some basic predicates
Matt Mackall <mpm@selenic.com>
parents: 14673
diff changeset
   269
        return getlist(x[1]) + [x[2]]
e80fa502b8cf fileset: add some basic predicates
Matt Mackall <mpm@selenic.com>
parents: 14673
diff changeset
   270
    return [x]
e80fa502b8cf fileset: add some basic predicates
Matt Mackall <mpm@selenic.com>
parents: 14673
diff changeset
   271
e80fa502b8cf fileset: add some basic predicates
Matt Mackall <mpm@selenic.com>
parents: 14673
diff changeset
   272
def getargs(x, min, max, err):
e80fa502b8cf fileset: add some basic predicates
Matt Mackall <mpm@selenic.com>
parents: 14673
diff changeset
   273
    l = getlist(x)
e80fa502b8cf fileset: add some basic predicates
Matt Mackall <mpm@selenic.com>
parents: 14673
diff changeset
   274
    if len(l) < min or len(l) > max:
e80fa502b8cf fileset: add some basic predicates
Matt Mackall <mpm@selenic.com>
parents: 14673
diff changeset
   275
        raise error.ParseError(err)
e80fa502b8cf fileset: add some basic predicates
Matt Mackall <mpm@selenic.com>
parents: 14673
diff changeset
   276
    return l
e80fa502b8cf fileset: add some basic predicates
Matt Mackall <mpm@selenic.com>
parents: 14673
diff changeset
   277
27462
470ea34ba593 fileset: use decorator to mark a predicate as "existing caller"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27461
diff changeset
   278
@predicate('binary()', callexisting=True)
14676
e80fa502b8cf fileset: add some basic predicates
Matt Mackall <mpm@selenic.com>
parents: 14673
diff changeset
   279
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
   280
    """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
   281
    """
14785
0f0bd4d028d3 fileset: add i18n hints for keywords
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 14718
diff changeset
   282
    # i18n: "binary" is a keyword
14676
e80fa502b8cf fileset: add some basic predicates
Matt Mackall <mpm@selenic.com>
parents: 14673
diff changeset
   283
    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
   284
    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
   285
27462
470ea34ba593 fileset: use decorator to mark a predicate as "existing caller"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27461
diff changeset
   286
@predicate('exec()', callexisting=True)
14676
e80fa502b8cf fileset: add some basic predicates
Matt Mackall <mpm@selenic.com>
parents: 14673
diff changeset
   287
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
   288
    """File that is marked as executable.
14681
0744db5eb51c fileset: add some function help text
Matt Mackall <mpm@selenic.com>
parents: 14680
diff changeset
   289
    """
14785
0f0bd4d028d3 fileset: add i18n hints for keywords
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 14718
diff changeset
   290
    # i18n: "exec" is a keyword
14676
e80fa502b8cf fileset: add some basic predicates
Matt Mackall <mpm@selenic.com>
parents: 14673
diff changeset
   291
    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
   292
    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
   293
27462
470ea34ba593 fileset: use decorator to mark a predicate as "existing caller"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27461
diff changeset
   294
@predicate('symlink()', callexisting=True)
14676
e80fa502b8cf fileset: add some basic predicates
Matt Mackall <mpm@selenic.com>
parents: 14673
diff changeset
   295
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
   296
    """File that is marked as a symlink.
14681
0744db5eb51c fileset: add some function help text
Matt Mackall <mpm@selenic.com>
parents: 14680
diff changeset
   297
    """
14785
0f0bd4d028d3 fileset: add i18n hints for keywords
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 14718
diff changeset
   298
    # i18n: "symlink" is a keyword
14676
e80fa502b8cf fileset: add some basic predicates
Matt Mackall <mpm@selenic.com>
parents: 14673
diff changeset
   299
    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
   300
    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
   301
27460
11286ac374f3 fileset: use decorator to mark a function as fileset predicate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27459
diff changeset
   302
@predicate('resolved()')
14679
e141e1cee0cc fileset: add resolved and unresolved predicates
Matt Mackall <mpm@selenic.com>
parents: 14678
diff changeset
   303
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
   304
    """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
   305
    """
14785
0f0bd4d028d3 fileset: add i18n hints for keywords
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 14718
diff changeset
   306
    # i18n: "resolved" is a keyword
14679
e141e1cee0cc fileset: add resolved and unresolved predicates
Matt Mackall <mpm@selenic.com>
parents: 14678
diff changeset
   307
    getargs(x, 0, 0, _("resolved takes no arguments"))
e141e1cee0cc fileset: add resolved and unresolved predicates
Matt Mackall <mpm@selenic.com>
parents: 14678
diff changeset
   308
    if mctx.ctx.rev() is not None:
e141e1cee0cc fileset: add resolved and unresolved predicates
Matt Mackall <mpm@selenic.com>
parents: 14678
diff changeset
   309
        return []
26995
d5a6be56970b fileset: switch to mergestate.read()
Siddharth Agarwal <sid0@fb.com>
parents: 26587
diff changeset
   310
    ms = merge.mergestate.read(mctx.ctx.repo())
14679
e141e1cee0cc fileset: add resolved and unresolved predicates
Matt Mackall <mpm@selenic.com>
parents: 14678
diff changeset
   311
    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
   312
27460
11286ac374f3 fileset: use decorator to mark a function as fileset predicate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27459
diff changeset
   313
@predicate('unresolved()')
14679
e141e1cee0cc fileset: add resolved and unresolved predicates
Matt Mackall <mpm@selenic.com>
parents: 14678
diff changeset
   314
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
   315
    """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
   316
    """
14785
0f0bd4d028d3 fileset: add i18n hints for keywords
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 14718
diff changeset
   317
    # i18n: "unresolved" is a keyword
14679
e141e1cee0cc fileset: add resolved and unresolved predicates
Matt Mackall <mpm@selenic.com>
parents: 14678
diff changeset
   318
    getargs(x, 0, 0, _("unresolved takes no arguments"))
e141e1cee0cc fileset: add resolved and unresolved predicates
Matt Mackall <mpm@selenic.com>
parents: 14678
diff changeset
   319
    if mctx.ctx.rev() is not None:
e141e1cee0cc fileset: add resolved and unresolved predicates
Matt Mackall <mpm@selenic.com>
parents: 14678
diff changeset
   320
        return []
26995
d5a6be56970b fileset: switch to mergestate.read()
Siddharth Agarwal <sid0@fb.com>
parents: 26587
diff changeset
   321
    ms = merge.mergestate.read(mctx.ctx.repo())
14679
e141e1cee0cc fileset: add resolved and unresolved predicates
Matt Mackall <mpm@selenic.com>
parents: 14678
diff changeset
   322
    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
   323
27460
11286ac374f3 fileset: use decorator to mark a function as fileset predicate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27459
diff changeset
   324
@predicate('hgignore()')
14680
49af5fa3809b fileset: add hgignore
Matt Mackall <mpm@selenic.com>
parents: 14679
diff changeset
   325
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
   326
    """File that matches the active .hgignore pattern.
14681
0744db5eb51c fileset: add some function help text
Matt Mackall <mpm@selenic.com>
parents: 14680
diff changeset
   327
    """
23113
c2dd79ad99cb i18n: add i18n comment to error messages of filesets predicates
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 22924
diff changeset
   328
    # i18n: "hgignore" is a keyword
14680
49af5fa3809b fileset: add hgignore
Matt Mackall <mpm@selenic.com>
parents: 14679
diff changeset
   329
    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
   330
    ignore = mctx.ctx.repo().dirstate._ignore
14680
49af5fa3809b fileset: add hgignore
Matt Mackall <mpm@selenic.com>
parents: 14679
diff changeset
   331
    return [f for f in mctx.subset if ignore(f)]
49af5fa3809b fileset: add hgignore
Matt Mackall <mpm@selenic.com>
parents: 14679
diff changeset
   332
27460
11286ac374f3 fileset: use decorator to mark a function as fileset predicate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27459
diff changeset
   333
@predicate('portable()')
24408
caa6b6c65dc3 fileset: add a fileset for portable filenames
Siddharth Agarwal <sid0@fb.com>
parents: 24334
diff changeset
   334
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
   335
    """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
   336
    collisions.)
caa6b6c65dc3 fileset: add a fileset for portable filenames
Siddharth Agarwal <sid0@fb.com>
parents: 24334
diff changeset
   337
    """
caa6b6c65dc3 fileset: add a fileset for portable filenames
Siddharth Agarwal <sid0@fb.com>
parents: 24334
diff changeset
   338
    # i18n: "portable" is a keyword
caa6b6c65dc3 fileset: add a fileset for portable filenames
Siddharth Agarwal <sid0@fb.com>
parents: 24334
diff changeset
   339
    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
   340
    checkwinfilename = util.checkwinfilename
caa6b6c65dc3 fileset: add a fileset for portable filenames
Siddharth Agarwal <sid0@fb.com>
parents: 24334
diff changeset
   341
    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
   342
27462
470ea34ba593 fileset: use decorator to mark a predicate as "existing caller"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27461
diff changeset
   343
@predicate('grep(regex)', callexisting=True)
14682
8785fd757077 fileset: add grep predicate
Matt Mackall <mpm@selenic.com>
parents: 14681
diff changeset
   344
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
   345
    """File contains the given regular expression.
14682
8785fd757077 fileset: add grep predicate
Matt Mackall <mpm@selenic.com>
parents: 14681
diff changeset
   346
    """
17368
01cc267fc105 fileset: do not traceback on invalid grep pattern
Patrick Mezard <patrick@mezard.eu>
parents: 17367
diff changeset
   347
    try:
01cc267fc105 fileset: do not traceback on invalid grep pattern
Patrick Mezard <patrick@mezard.eu>
parents: 17367
diff changeset
   348
        # i18n: "grep" is a keyword
01cc267fc105 fileset: do not traceback on invalid grep pattern
Patrick Mezard <patrick@mezard.eu>
parents: 17367
diff changeset
   349
        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
   350
    except re.error as e:
17368
01cc267fc105 fileset: do not traceback on invalid grep pattern
Patrick Mezard <patrick@mezard.eu>
parents: 17367
diff changeset
   351
        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
   352
    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
   353
14683
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
   354
def _sizetomax(s):
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
   355
    try:
25925
23c4589fc678 filesets: ignore unit case in size() predicate for single value
Anton Shestakov <av6@dwimlabs.net>
parents: 25815
diff changeset
   356
        s = s.strip().lower()
19194
1d08df65cd3c util: migrate fileset._sizetoint to util.sizetoint
Bryan O'Sullivan <bryano@fb.com>
parents: 18842
diff changeset
   357
        for k, v in util._sizeunits:
14683
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
   358
            if s.endswith(k):
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
   359
                # max(4k) = 5k - 1, max(4.5k) = 4.6k - 1
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
   360
                n = s[:-len(k)]
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
   361
                inc = 1.0
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
   362
                if "." in n:
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
   363
                    inc /= 10 ** len(n.split(".")[1])
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
   364
                return int((float(n) + inc) * v) - 1
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
   365
        # no extension, this is a precise value
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
   366
        return int(s)
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
   367
    except ValueError:
14716
552329013bac fileset: use ParseError pos field correctly
Mads Kiilerich <mads@kiilerich.com>
parents: 14701
diff changeset
   368
        raise error.ParseError(_("couldn't parse size: %s") % s)
14683
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
   369
27462
470ea34ba593 fileset: use decorator to mark a predicate as "existing caller"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27461
diff changeset
   370
@predicate('size(expression)', callexisting=True)
14683
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
   371
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
   372
    """File size matches the given expression. Examples:
14683
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
   373
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
   374
    - 1k (files from 1024 to 2047 bytes)
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
   375
    - < 20k (files less than 20480 bytes)
14689
25e4d2f35965 fileset: drop backwards SI size units
Matt Mackall <mpm@selenic.com>
parents: 14685
diff changeset
   376
    - >= .5MB (files at least 524288 bytes)
14683
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
   377
    - 4k - 1MB (files from 4096 bytes to 1048576 bytes)
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
   378
    """
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
   379
14785
0f0bd4d028d3 fileset: add i18n hints for keywords
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 14718
diff changeset
   380
    # 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
   381
    expr = getstring(x, _("size requires an expression")).strip()
14683
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
   382
    if '-' in expr: # do we have a range?
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
   383
        a, b = expr.split('-', 1)
19194
1d08df65cd3c util: migrate fileset._sizetoint to util.sizetoint
Bryan O'Sullivan <bryano@fb.com>
parents: 18842
diff changeset
   384
        a = util.sizetoint(a)
1d08df65cd3c util: migrate fileset._sizetoint to util.sizetoint
Bryan O'Sullivan <bryano@fb.com>
parents: 18842
diff changeset
   385
        b = util.sizetoint(b)
14683
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
   386
        m = lambda x: x >= a and x <= b
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
   387
    elif expr.startswith("<="):
19194
1d08df65cd3c util: migrate fileset._sizetoint to util.sizetoint
Bryan O'Sullivan <bryano@fb.com>
parents: 18842
diff changeset
   388
        a = util.sizetoint(expr[2:])
14683
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
   389
        m = lambda x: x <= a
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
   390
    elif expr.startswith("<"):
19194
1d08df65cd3c util: migrate fileset._sizetoint to util.sizetoint
Bryan O'Sullivan <bryano@fb.com>
parents: 18842
diff changeset
   391
        a = util.sizetoint(expr[1:])
14683
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
   392
        m = lambda x: x < a
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
   393
    elif expr.startswith(">="):
19194
1d08df65cd3c util: migrate fileset._sizetoint to util.sizetoint
Bryan O'Sullivan <bryano@fb.com>
parents: 18842
diff changeset
   394
        a = util.sizetoint(expr[2:])
14683
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
   395
        m = lambda x: x >= a
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
   396
    elif expr.startswith(">"):
19194
1d08df65cd3c util: migrate fileset._sizetoint to util.sizetoint
Bryan O'Sullivan <bryano@fb.com>
parents: 18842
diff changeset
   397
        a = util.sizetoint(expr[1:])
14683
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
   398
        m = lambda x: x > a
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
   399
    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
   400
        a = util.sizetoint(expr)
14683
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
   401
        b = _sizetomax(expr)
14690
15faf0e66909 fileset: add missing whitespace around operator
Thomas Arendsen Hein <thomas@intevation.de>
parents: 14689
diff changeset
   402
        m = lambda x: x >= a and x <= b
14683
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
   403
    else:
14716
552329013bac fileset: use ParseError pos field correctly
Mads Kiilerich <mads@kiilerich.com>
parents: 14701
diff changeset
   404
        raise error.ParseError(_("couldn't parse size: %s") % expr)
14683
281102f37b24 fileset: add size() predicate
Matt Mackall <mpm@selenic.com>
parents: 14682
diff changeset
   405
15963
042e84e39dee fileset: don't attempt to check data predicates against removed files
Matt Mackall <mpm@selenic.com>
parents: 14830
diff changeset
   406
    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
   407
27462
470ea34ba593 fileset: use decorator to mark a predicate as "existing caller"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27461
diff changeset
   408
@predicate('encoding(name)', callexisting=True)
14684
87b9d6a7d807 fileset: add encoding() predicate
Matt Mackall <mpm@selenic.com>
parents: 14683
diff changeset
   409
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
   410
    """File can be successfully decoded with the given character
14684
87b9d6a7d807 fileset: add encoding() predicate
Matt Mackall <mpm@selenic.com>
parents: 14683
diff changeset
   411
    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
   412
    UTF-8.
87b9d6a7d807 fileset: add encoding() predicate
Matt Mackall <mpm@selenic.com>
parents: 14683
diff changeset
   413
    """
87b9d6a7d807 fileset: add encoding() predicate
Matt Mackall <mpm@selenic.com>
parents: 14683
diff changeset
   414
14785
0f0bd4d028d3 fileset: add i18n hints for keywords
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 14718
diff changeset
   415
    # i18n: "encoding" is a keyword
14684
87b9d6a7d807 fileset: add encoding() predicate
Matt Mackall <mpm@selenic.com>
parents: 14683
diff changeset
   416
    enc = getstring(x, _("encoding requires an encoding name"))
87b9d6a7d807 fileset: add encoding() predicate
Matt Mackall <mpm@selenic.com>
parents: 14683
diff changeset
   417
87b9d6a7d807 fileset: add encoding() predicate
Matt Mackall <mpm@selenic.com>
parents: 14683
diff changeset
   418
    s = []
15963
042e84e39dee fileset: don't attempt to check data predicates against removed files
Matt Mackall <mpm@selenic.com>
parents: 14830
diff changeset
   419
    for f in mctx.existing():
14684
87b9d6a7d807 fileset: add encoding() predicate
Matt Mackall <mpm@selenic.com>
parents: 14683
diff changeset
   420
        d = mctx.ctx[f].data()
87b9d6a7d807 fileset: add encoding() predicate
Matt Mackall <mpm@selenic.com>
parents: 14683
diff changeset
   421
        try:
87b9d6a7d807 fileset: add encoding() predicate
Matt Mackall <mpm@selenic.com>
parents: 14683
diff changeset
   422
            d.decode(enc)
87b9d6a7d807 fileset: add encoding() predicate
Matt Mackall <mpm@selenic.com>
parents: 14683
diff changeset
   423
        except LookupError:
26587
56b2bcea2529 error: get Abort from 'error' instead of 'util'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26233
diff changeset
   424
            raise error.Abort(_("unknown encoding '%s'") % enc)
14684
87b9d6a7d807 fileset: add encoding() predicate
Matt Mackall <mpm@selenic.com>
parents: 14683
diff changeset
   425
        except UnicodeDecodeError:
87b9d6a7d807 fileset: add encoding() predicate
Matt Mackall <mpm@selenic.com>
parents: 14683
diff changeset
   426
            continue
87b9d6a7d807 fileset: add encoding() predicate
Matt Mackall <mpm@selenic.com>
parents: 14683
diff changeset
   427
        s.append(f)
87b9d6a7d807 fileset: add encoding() predicate
Matt Mackall <mpm@selenic.com>
parents: 14683
diff changeset
   428
87b9d6a7d807 fileset: add encoding() predicate
Matt Mackall <mpm@selenic.com>
parents: 14683
diff changeset
   429
    return s
87b9d6a7d807 fileset: add encoding() predicate
Matt Mackall <mpm@selenic.com>
parents: 14683
diff changeset
   430
27462
470ea34ba593 fileset: use decorator to mark a predicate as "existing caller"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27461
diff changeset
   431
@predicate('eol(style)', callexisting=True)
18842
3ce3f2b059a1 filesets: add eol predicate
Matt Mackall <mpm@selenic.com>
parents: 18364
diff changeset
   432
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
   433
    """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
   434
    files are excluded, files with mixed line endings match multiple
3ce3f2b059a1 filesets: add eol predicate
Matt Mackall <mpm@selenic.com>
parents: 18364
diff changeset
   435
    styles.
3ce3f2b059a1 filesets: add eol predicate
Matt Mackall <mpm@selenic.com>
parents: 18364
diff changeset
   436
    """
3ce3f2b059a1 filesets: add eol predicate
Matt Mackall <mpm@selenic.com>
parents: 18364
diff changeset
   437
28056
4f8ced23345e fileset: fix copy/paste in eol() error message
Matt Harbison <matt_harbison@yahoo.com>
parents: 27518
diff changeset
   438
    # i18n: "eol" is a keyword
4f8ced23345e fileset: fix copy/paste in eol() error message
Matt Harbison <matt_harbison@yahoo.com>
parents: 27518
diff changeset
   439
    enc = getstring(x, _("eol requires a style name"))
18842
3ce3f2b059a1 filesets: add eol predicate
Matt Mackall <mpm@selenic.com>
parents: 18364
diff changeset
   440
3ce3f2b059a1 filesets: add eol predicate
Matt Mackall <mpm@selenic.com>
parents: 18364
diff changeset
   441
    s = []
3ce3f2b059a1 filesets: add eol predicate
Matt Mackall <mpm@selenic.com>
parents: 18364
diff changeset
   442
    for f in mctx.existing():
3ce3f2b059a1 filesets: add eol predicate
Matt Mackall <mpm@selenic.com>
parents: 18364
diff changeset
   443
        d = mctx.ctx[f].data()
3ce3f2b059a1 filesets: add eol predicate
Matt Mackall <mpm@selenic.com>
parents: 18364
diff changeset
   444
        if util.binary(d):
3ce3f2b059a1 filesets: add eol predicate
Matt Mackall <mpm@selenic.com>
parents: 18364
diff changeset
   445
            continue
3ce3f2b059a1 filesets: add eol predicate
Matt Mackall <mpm@selenic.com>
parents: 18364
diff changeset
   446
        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
   447
            s.append(f)
3ce3f2b059a1 filesets: add eol predicate
Matt Mackall <mpm@selenic.com>
parents: 18364
diff changeset
   448
        elif enc == 'unix' and re.search('(?<!\r)\n', d):
3ce3f2b059a1 filesets: add eol predicate
Matt Mackall <mpm@selenic.com>
parents: 18364
diff changeset
   449
            s.append(f)
3ce3f2b059a1 filesets: add eol predicate
Matt Mackall <mpm@selenic.com>
parents: 18364
diff changeset
   450
        elif enc == 'mac' and re.search('\r(?!\n)', d):
3ce3f2b059a1 filesets: add eol predicate
Matt Mackall <mpm@selenic.com>
parents: 18364
diff changeset
   451
            s.append(f)
3ce3f2b059a1 filesets: add eol predicate
Matt Mackall <mpm@selenic.com>
parents: 18364
diff changeset
   452
    return s
3ce3f2b059a1 filesets: add eol predicate
Matt Mackall <mpm@selenic.com>
parents: 18364
diff changeset
   453
27460
11286ac374f3 fileset: use decorator to mark a function as fileset predicate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27459
diff changeset
   454
@predicate('copied()')
14685
394121d9f4fc fileset: add copied predicate
Matt Mackall <mpm@selenic.com>
parents: 14684
diff changeset
   455
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
   456
    """File that is recorded as being copied.
14685
394121d9f4fc fileset: add copied predicate
Matt Mackall <mpm@selenic.com>
parents: 14684
diff changeset
   457
    """
14785
0f0bd4d028d3 fileset: add i18n hints for keywords
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 14718
diff changeset
   458
    # i18n: "copied" is a keyword
14718
0c81948636f3 fileset: copied takes no arguments
Mads Kiilerich <mads@kiilerich.com>
parents: 14717
diff changeset
   459
    getargs(x, 0, 0, _("copied takes no arguments"))
14685
394121d9f4fc fileset: add copied predicate
Matt Mackall <mpm@selenic.com>
parents: 14684
diff changeset
   460
    s = []
394121d9f4fc fileset: add copied predicate
Matt Mackall <mpm@selenic.com>
parents: 14684
diff changeset
   461
    for f in mctx.subset:
394121d9f4fc fileset: add copied predicate
Matt Mackall <mpm@selenic.com>
parents: 14684
diff changeset
   462
        p = mctx.ctx[f].parents()
394121d9f4fc fileset: add copied predicate
Matt Mackall <mpm@selenic.com>
parents: 14684
diff changeset
   463
        if p and p[0].path() != f:
394121d9f4fc fileset: add copied predicate
Matt Mackall <mpm@selenic.com>
parents: 14684
diff changeset
   464
            s.append(f)
394121d9f4fc fileset: add copied predicate
Matt Mackall <mpm@selenic.com>
parents: 14684
diff changeset
   465
    return s
394121d9f4fc fileset: add copied predicate
Matt Mackall <mpm@selenic.com>
parents: 14684
diff changeset
   466
27460
11286ac374f3 fileset: use decorator to mark a function as fileset predicate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27459
diff changeset
   467
@predicate('subrepo([pattern])')
16443
9e02e032b522 fileset: add "subrepo" fileset symbol
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 15963
diff changeset
   468
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
   469
    """Subrepositories whose paths match the given pattern.
16443
9e02e032b522 fileset: add "subrepo" fileset symbol
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 15963
diff changeset
   470
    """
9e02e032b522 fileset: add "subrepo" fileset symbol
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 15963
diff changeset
   471
    # i18n: "subrepo" is a keyword
9e02e032b522 fileset: add "subrepo" fileset symbol
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 15963
diff changeset
   472
    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
   473
    ctx = mctx.ctx
18364
6252b4f1c4b4 subrepos: process subrepos in sorted order
Mads Kiilerich <mads@kiilerich.com>
parents: 17371
diff changeset
   474
    sstate = sorted(ctx.substate)
16443
9e02e032b522 fileset: add "subrepo" fileset symbol
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 15963
diff changeset
   475
    if x:
23113
c2dd79ad99cb i18n: add i18n comment to error messages of filesets predicates
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 22924
diff changeset
   476
        # i18n: "subrepo" is a keyword
16443
9e02e032b522 fileset: add "subrepo" fileset symbol
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 15963
diff changeset
   477
        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
   478
25938
e194ada8d45f fileset: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25815
diff changeset
   479
        from . import match as matchmod # avoid circular import issues
16443
9e02e032b522 fileset: add "subrepo" fileset symbol
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 15963
diff changeset
   480
        fast = not matchmod.patkind(pat)
9e02e032b522 fileset: add "subrepo" fileset symbol
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 15963
diff changeset
   481
        if fast:
9e02e032b522 fileset: add "subrepo" fileset symbol
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 15963
diff changeset
   482
            def m(s):
9e02e032b522 fileset: add "subrepo" fileset symbol
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 15963
diff changeset
   483
                return (s == pat)
9e02e032b522 fileset: add "subrepo" fileset symbol
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 15963
diff changeset
   484
        else:
24334
eda2f36889b5 fileset: replace 'ctx._repo' with 'ctx.repo()'
Matt Harbison <matt_harbison@yahoo.com>
parents: 24218
diff changeset
   485
            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
   486
        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
   487
    else:
9e02e032b522 fileset: add "subrepo" fileset symbol
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 15963
diff changeset
   488
        return [sub for sub in sstate]
9e02e032b522 fileset: add "subrepo" fileset symbol
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 15963
diff changeset
   489
14551
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
   490
methods = {
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
   491
    'string': stringset,
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
   492
    'symbol': stringset,
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
   493
    'and': andset,
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
   494
    'or': orset,
17363
5d9e2031c0b1 fileset: actually implement 'minusset'
Patrick Mezard <patrick@mezard.eu>
parents: 16443
diff changeset
   495
    'minus': minusset,
14551
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
   496
    'list': listset,
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
   497
    'group': getset,
14676
e80fa502b8cf fileset: add some basic predicates
Matt Mackall <mpm@selenic.com>
parents: 14673
diff changeset
   498
    'not': notset,
e80fa502b8cf fileset: add some basic predicates
Matt Mackall <mpm@selenic.com>
parents: 14673
diff changeset
   499
    'func': func,
14551
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
   500
}
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
   501
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
   502
class matchctx(object):
14677
2a758ffc821e fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents: 14676
diff changeset
   503
    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
   504
        self.ctx = ctx
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
   505
        self.subset = subset
14677
2a758ffc821e fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents: 14676
diff changeset
   506
        self._status = status
27464
c39ecb2b86b3 fileset: detect unintentional existing() invocation at runtime
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27463
diff changeset
   507
        self._existingenabled = False
14677
2a758ffc821e fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents: 14676
diff changeset
   508
    def status(self):
2a758ffc821e fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents: 14676
diff changeset
   509
        return self._status
14673
b0566467c492 fileset: drop matchfn
Matt Mackall <mpm@selenic.com>
parents: 14554
diff changeset
   510
    def matcher(self, patterns):
b0566467c492 fileset: drop matchfn
Matt Mackall <mpm@selenic.com>
parents: 14554
diff changeset
   511
        return self.ctx.match(patterns)
14551
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
   512
    def filter(self, files):
68d814a3cefd fileset: basic pattern and boolean support
Matt Mackall <mpm@selenic.com>
parents: 14513
diff changeset
   513
        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
   514
    def existing(self):
27464
c39ecb2b86b3 fileset: detect unintentional existing() invocation at runtime
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27463
diff changeset
   515
        assert self._existingenabled, 'unexpected existing() invocation'
17365
8a0513bf030a fileset: exclude deleted files from matchctx.existing()
Patrick Mezard <patrick@mezard.eu>
parents: 17363
diff changeset
   516
        if self._status is not None:
8a0513bf030a fileset: exclude deleted files from matchctx.existing()
Patrick Mezard <patrick@mezard.eu>
parents: 17363
diff changeset
   517
            removed = set(self._status[3])
17367
ce625185cfd9 fileset: matchctx.existing() must consider ignored files
Patrick Mezard <patrick@mezard.eu>
parents: 17366
diff changeset
   518
            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
   519
        else:
8a0513bf030a fileset: exclude deleted files from matchctx.existing()
Patrick Mezard <patrick@mezard.eu>
parents: 17363
diff changeset
   520
            removed = set()
17366
04c65cb59467 fileset: matchctx.existing() must consider unknown files
Patrick Mezard <patrick@mezard.eu>
parents: 17365
diff changeset
   521
            unknown = set()
17365
8a0513bf030a fileset: exclude deleted files from matchctx.existing()
Patrick Mezard <patrick@mezard.eu>
parents: 17363
diff changeset
   522
        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
   523
                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
   524
    def narrow(self, files):
14677
2a758ffc821e fileset: add support for file status predicates
Matt Mackall <mpm@selenic.com>
parents: 14676
diff changeset
   525
        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
   526
14678
5ef7b87530f6 fileset: prescan parse tree to optimize status usage
Matt Mackall <mpm@selenic.com>
parents: 14677
diff changeset
   527
def _intree(funcs, tree):
5ef7b87530f6 fileset: prescan parse tree to optimize status usage
Matt Mackall <mpm@selenic.com>
parents: 14677
diff changeset
   528
    if isinstance(tree, tuple):
5ef7b87530f6 fileset: prescan parse tree to optimize status usage
Matt Mackall <mpm@selenic.com>
parents: 14677
diff changeset
   529
        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
   530
            if tree[1][1] in funcs:
5ef7b87530f6 fileset: prescan parse tree to optimize status usage
Matt Mackall <mpm@selenic.com>
parents: 14677
diff changeset
   531
                return True
5ef7b87530f6 fileset: prescan parse tree to optimize status usage
Matt Mackall <mpm@selenic.com>
parents: 14677
diff changeset
   532
        for s in tree[1:]:
5ef7b87530f6 fileset: prescan parse tree to optimize status usage
Matt Mackall <mpm@selenic.com>
parents: 14677
diff changeset
   533
            if _intree(funcs, s):
5ef7b87530f6 fileset: prescan parse tree to optimize status usage
Matt Mackall <mpm@selenic.com>
parents: 14677
diff changeset
   534
                return True
5ef7b87530f6 fileset: prescan parse tree to optimize status usage
Matt Mackall <mpm@selenic.com>
parents: 14677
diff changeset
   535
    return False
5ef7b87530f6 fileset: prescan parse tree to optimize status usage
Matt Mackall <mpm@selenic.com>
parents: 14677
diff changeset
   536
14673
b0566467c492 fileset: drop matchfn
Matt Mackall <mpm@selenic.com>
parents: 14554
diff changeset
   537
def getfileset(ctx, expr):
25252
ac381dd7a21f fileset: move validation of incomplete parsing to parse() function
Yuya Nishihara <yuya@tcha.org>
parents: 24408
diff changeset
   538
    tree = parse(expr)
14678
5ef7b87530f6 fileset: prescan parse tree to optimize status usage
Matt Mackall <mpm@selenic.com>
parents: 14677
diff changeset
   539
5ef7b87530f6 fileset: prescan parse tree to optimize status usage
Matt Mackall <mpm@selenic.com>
parents: 14677
diff changeset
   540
    # do we need status info?
27461
afa76585c955 fileset: use decorator to mark a predicate as "status caller"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27460
diff changeset
   541
    if (_intree(_statuscallers, tree) or
17365
8a0513bf030a fileset: exclude deleted files from matchctx.existing()
Patrick Mezard <patrick@mezard.eu>
parents: 17363
diff changeset
   542
        # 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
   543
        # for deleted files.
8a0513bf030a fileset: exclude deleted files from matchctx.existing()
Patrick Mezard <patrick@mezard.eu>
parents: 17363
diff changeset
   544
        (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
   545
        unknown = _intree(['unknown'], tree)
5ef7b87530f6 fileset: prescan parse tree to optimize status usage
Matt Mackall <mpm@selenic.com>
parents: 14677
diff changeset
   546
        ignored = _intree(['ignored'], tree)
5ef7b87530f6 fileset: prescan parse tree to optimize status usage
Matt Mackall <mpm@selenic.com>
parents: 14677
diff changeset
   547
24334
eda2f36889b5 fileset: replace 'ctx._repo' with 'ctx.repo()'
Matt Harbison <matt_harbison@yahoo.com>
parents: 24218
diff changeset
   548
        r = ctx.repo()
14678
5ef7b87530f6 fileset: prescan parse tree to optimize status usage
Matt Mackall <mpm@selenic.com>
parents: 14677
diff changeset
   549
        status = r.status(ctx.p1(), ctx,
5ef7b87530f6 fileset: prescan parse tree to optimize status usage
Matt Mackall <mpm@selenic.com>
parents: 14677
diff changeset
   550
                          unknown=unknown, ignored=ignored, clean=True)
5ef7b87530f6 fileset: prescan parse tree to optimize status usage
Matt Mackall <mpm@selenic.com>
parents: 14677
diff changeset
   551
        subset = []
5ef7b87530f6 fileset: prescan parse tree to optimize status usage
Matt Mackall <mpm@selenic.com>
parents: 14677
diff changeset
   552
        for c in status:
5ef7b87530f6 fileset: prescan parse tree to optimize status usage
Matt Mackall <mpm@selenic.com>
parents: 14677
diff changeset
   553
            subset.extend(c)
5ef7b87530f6 fileset: prescan parse tree to optimize status usage
Matt Mackall <mpm@selenic.com>
parents: 14677
diff changeset
   554
    else:
5ef7b87530f6 fileset: prescan parse tree to optimize status usage
Matt Mackall <mpm@selenic.com>
parents: 14677
diff changeset
   555
        status = None
17371
1310489eb5d6 fileset: fix generator vs list bug in fast path
Patrick Mezard <patrick@mezard.eu>
parents: 17368
diff changeset
   556
        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
   557
5ef7b87530f6 fileset: prescan parse tree to optimize status usage
Matt Mackall <mpm@selenic.com>
parents: 14677
diff changeset
   558
    return getset(matchctx(ctx, subset, status), tree)
14681
0744db5eb51c fileset: add some function help text
Matt Mackall <mpm@selenic.com>
parents: 14680
diff changeset
   559
25255
ad1d2c952889 fileset: pretty print syntax tree in debug output
Yuya Nishihara <yuya@tcha.org>
parents: 25252
diff changeset
   560
def prettyformat(tree):
ad1d2c952889 fileset: pretty print syntax tree in debug output
Yuya Nishihara <yuya@tcha.org>
parents: 25252
diff changeset
   561
    return parser.prettyformat(tree, ('string', 'symbol'))
ad1d2c952889 fileset: pretty print syntax tree in debug output
Yuya Nishihara <yuya@tcha.org>
parents: 25252
diff changeset
   562
14681
0744db5eb51c fileset: add some function help text
Matt Mackall <mpm@selenic.com>
parents: 14680
diff changeset
   563
# tell hggettext to extract docstrings from these functions:
0744db5eb51c fileset: add some function help text
Matt Mackall <mpm@selenic.com>
parents: 14680
diff changeset
   564
i18nfunctions = symbols.values()