mercurial/match.py
author Yuya Nishihara <yuya@tcha.org>
Sun, 10 Jun 2018 16:08:58 +0900
changeset 38581 9f9ffe5f687c
parent 38580 ec0cee4c1fff
child 38582 6467286b829c
permissions -rw-r--r--
match: compose 'set:' pattern as matcher Baby step towards porting fileset to matcher composition. We can't use the exactmatcher since it would provide a computed set as exact paths. That's why we use the predicatematcher with fset.__contains__. This will be cleaned up later. The test change in test-glog.t means that the "set:copied()" pattern is no longer be processed as a slow path. That's because the fset is empty. This will also change in future patches.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
8761
0289f384e1e5 Generally replace "file name" with "filename" in help and comments.
timeless <timeless@gmail.com>
parents: 8682
diff changeset
     1
# match.py - filename matching
8231
5d4d88a4f5e6 match: add copyright and license header
Martin Geisler <mg@lazybytes.net>
parents: 8152
diff changeset
     2
#
5d4d88a4f5e6 match: add copyright and license header
Martin Geisler <mg@lazybytes.net>
parents: 8152
diff changeset
     3
#  Copyright 2008, 2009 Matt Mackall <mpm@selenic.com> and others
5d4d88a4f5e6 match: add copyright and license header
Martin Geisler <mg@lazybytes.net>
parents: 8152
diff changeset
     4
#
5d4d88a4f5e6 match: add copyright and license header
Martin Geisler <mg@lazybytes.net>
parents: 8152
diff changeset
     5
# This software may be used and distributed according to the terms of the
10263
25e572394f5c Update license to GPLv2+
Matt Mackall <mpm@selenic.com>
parents: 9036
diff changeset
     6
# GNU General Public License version 2 or any later version.
8231
5d4d88a4f5e6 match: add copyright and license header
Martin Geisler <mg@lazybytes.net>
parents: 8152
diff changeset
     7
34152
a8994d08e4a2 doctest: use print_function and convert bytes to unicode where needed
Yuya Nishihara <yuya@tcha.org>
parents: 34146
diff changeset
     8
from __future__ import absolute_import, print_function
25958
c4ccf2d394a7 match: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25875
diff changeset
     9
c4ccf2d394a7 match: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25875
diff changeset
    10
import copy
c4ccf2d394a7 match: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25875
diff changeset
    11
import os
c4ccf2d394a7 match: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25875
diff changeset
    12
import re
c4ccf2d394a7 match: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25875
diff changeset
    13
c4ccf2d394a7 match: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25875
diff changeset
    14
from .i18n import _
c4ccf2d394a7 match: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25875
diff changeset
    15
from . import (
36088
c4fa47f880d3 py3: make sure we return str from __repr__
Pulkit Goyal <7895pulkit@gmail.com>
parents: 35659
diff changeset
    16
    encoding,
26587
56b2bcea2529 error: get Abort from 'error' instead of 'util'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26014
diff changeset
    17
    error,
25958
c4ccf2d394a7 match: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25875
diff changeset
    18
    pathutil,
36601
9adfa48792a7 match: some minimal pycompat fixes guided by test-hgignore.t
Augie Fackler <augie@google.com>
parents: 36088
diff changeset
    19
    pycompat,
25958
c4ccf2d394a7 match: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25875
diff changeset
    20
    util,
c4ccf2d394a7 match: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25875
diff changeset
    21
)
37087
f0b6fbea00cf stringutil: bulk-replace call sites to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 36601
diff changeset
    22
from .utils import (
f0b6fbea00cf stringutil: bulk-replace call sites to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 36601
diff changeset
    23
    stringutil,
f0b6fbea00cf stringutil: bulk-replace call sites to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 36601
diff changeset
    24
)
6576
69f3e9ac7c56 walk: introduce match objects
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    25
33710
2be0bf186950 match: expose some data and functionality to other modules
Kostia Balytskyi <ikostia@fb.com>
parents: 33582
diff changeset
    26
allpatternkinds = ('re', 'glob', 'path', 'relglob', 'relpath', 'relre',
2be0bf186950 match: expose some data and functionality to other modules
Kostia Balytskyi <ikostia@fb.com>
parents: 33582
diff changeset
    27
                   'listfile', 'listfile0', 'set', 'include', 'subinclude',
2be0bf186950 match: expose some data and functionality to other modules
Kostia Balytskyi <ikostia@fb.com>
parents: 33582
diff changeset
    28
                   'rootfilesin')
2be0bf186950 match: expose some data and functionality to other modules
Kostia Balytskyi <ikostia@fb.com>
parents: 33582
diff changeset
    29
cwdrelativepatternkinds = ('relpath', 'glob')
2be0bf186950 match: expose some data and functionality to other modules
Kostia Balytskyi <ikostia@fb.com>
parents: 33582
diff changeset
    30
24636
36872036169b treemanifest: further optimize treemanifest.matches()
Drew Gottlieb <drgott@google.com>
parents: 24452
diff changeset
    31
propertycache = util.propertycache
36872036169b treemanifest: further optimize treemanifest.matches()
Drew Gottlieb <drgott@google.com>
parents: 24452
diff changeset
    32
21111
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
    33
def _rematcher(regex):
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
    34
    '''compile the regexp with the best available regexp engine and return a
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
    35
    matcher function'''
21909
335bb8b80443 match: use util.re.compile instead of util.compilere
Siddharth Agarwal <sid0@fb.com>
parents: 21815
diff changeset
    36
    m = util.re.compile(regex)
16943
8d08a28aa63e matcher: use re2 bindings if available
Bryan O'Sullivan <bryano@fb.com>
parents: 16791
diff changeset
    37
    try:
8d08a28aa63e matcher: use re2 bindings if available
Bryan O'Sullivan <bryano@fb.com>
parents: 16791
diff changeset
    38
        # slightly faster, provided by facebook's re2 bindings
8d08a28aa63e matcher: use re2 bindings if available
Bryan O'Sullivan <bryano@fb.com>
parents: 16791
diff changeset
    39
        return m.test_match
8d08a28aa63e matcher: use re2 bindings if available
Bryan O'Sullivan <bryano@fb.com>
parents: 16791
diff changeset
    40
    except AttributeError:
8d08a28aa63e matcher: use re2 bindings if available
Bryan O'Sullivan <bryano@fb.com>
parents: 16791
diff changeset
    41
        return m.match
8d08a28aa63e matcher: use re2 bindings if available
Bryan O'Sullivan <bryano@fb.com>
parents: 16791
diff changeset
    42
25122
755d23a49170 match: resolve filesets in subrepos for commands given the '-S' argument
Matt Harbison <matt_harbison@yahoo.com>
parents: 25114
diff changeset
    43
def _expandsets(kindpats, ctx, listsubrepos):
21111
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
    44
    '''Returns the kindpats list with the 'set' patterns expanded.'''
14675
cfc89398f710 match: introduce basic fileset support
Matt Mackall <mpm@selenic.com>
parents: 14674
diff changeset
    45
    fset = set()
cfc89398f710 match: introduce basic fileset support
Matt Mackall <mpm@selenic.com>
parents: 14674
diff changeset
    46
    other = []
cfc89398f710 match: introduce basic fileset support
Matt Mackall <mpm@selenic.com>
parents: 14674
diff changeset
    47
25213
08a8e9da0ae7 match: add source to kindpats list
Durham Goode <durham@fb.com>
parents: 25195
diff changeset
    48
    for kind, pat, source in kindpats:
14675
cfc89398f710 match: introduce basic fileset support
Matt Mackall <mpm@selenic.com>
parents: 14674
diff changeset
    49
        if kind == 'set':
cfc89398f710 match: introduce basic fileset support
Matt Mackall <mpm@selenic.com>
parents: 14674
diff changeset
    50
            if not ctx:
32482
57d6c0c74b1b match: use ProgrammingError where appropriate
Martin von Zweigbergk <martinvonz@google.com>
parents: 32453
diff changeset
    51
                raise error.ProgrammingError("fileset expression with no "
57d6c0c74b1b match: use ProgrammingError where appropriate
Martin von Zweigbergk <martinvonz@google.com>
parents: 32453
diff changeset
    52
                                             "context")
21111
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
    53
            s = ctx.getfileset(pat)
14675
cfc89398f710 match: introduce basic fileset support
Matt Mackall <mpm@selenic.com>
parents: 14674
diff changeset
    54
            fset.update(s)
25122
755d23a49170 match: resolve filesets in subrepos for commands given the '-S' argument
Matt Harbison <matt_harbison@yahoo.com>
parents: 25114
diff changeset
    55
755d23a49170 match: resolve filesets in subrepos for commands given the '-S' argument
Matt Harbison <matt_harbison@yahoo.com>
parents: 25114
diff changeset
    56
            if listsubrepos:
755d23a49170 match: resolve filesets in subrepos for commands given the '-S' argument
Matt Harbison <matt_harbison@yahoo.com>
parents: 25114
diff changeset
    57
                for subpath in ctx.substate:
755d23a49170 match: resolve filesets in subrepos for commands given the '-S' argument
Matt Harbison <matt_harbison@yahoo.com>
parents: 25114
diff changeset
    58
                    s = ctx.sub(subpath).getfileset(pat)
755d23a49170 match: resolve filesets in subrepos for commands given the '-S' argument
Matt Harbison <matt_harbison@yahoo.com>
parents: 25114
diff changeset
    59
                    fset.update(subpath + '/' + f for f in s)
755d23a49170 match: resolve filesets in subrepos for commands given the '-S' argument
Matt Harbison <matt_harbison@yahoo.com>
parents: 25114
diff changeset
    60
14675
cfc89398f710 match: introduce basic fileset support
Matt Mackall <mpm@selenic.com>
parents: 14674
diff changeset
    61
            continue
25213
08a8e9da0ae7 match: add source to kindpats list
Durham Goode <durham@fb.com>
parents: 25195
diff changeset
    62
        other.append((kind, pat, source))
14675
cfc89398f710 match: introduce basic fileset support
Matt Mackall <mpm@selenic.com>
parents: 14674
diff changeset
    63
    return fset, other
cfc89398f710 match: introduce basic fileset support
Matt Mackall <mpm@selenic.com>
parents: 14674
diff changeset
    64
25283
19d0e5efa6ca match: enable 'subinclude:' syntax
Durham Goode <durham@fb.com>
parents: 25250
diff changeset
    65
def _expandsubinclude(kindpats, root):
32185
6dea1701f170 match: make subinclude construction lazy
Durham Goode <durham@fb.com>
parents: 31442
diff changeset
    66
    '''Returns the list of subinclude matcher args and the kindpats without the
25283
19d0e5efa6ca match: enable 'subinclude:' syntax
Durham Goode <durham@fb.com>
parents: 25250
diff changeset
    67
    subincludes in it.'''
19d0e5efa6ca match: enable 'subinclude:' syntax
Durham Goode <durham@fb.com>
parents: 25250
diff changeset
    68
    relmatchers = []
19d0e5efa6ca match: enable 'subinclude:' syntax
Durham Goode <durham@fb.com>
parents: 25250
diff changeset
    69
    other = []
19d0e5efa6ca match: enable 'subinclude:' syntax
Durham Goode <durham@fb.com>
parents: 25250
diff changeset
    70
19d0e5efa6ca match: enable 'subinclude:' syntax
Durham Goode <durham@fb.com>
parents: 25250
diff changeset
    71
    for kind, pat, source in kindpats:
19d0e5efa6ca match: enable 'subinclude:' syntax
Durham Goode <durham@fb.com>
parents: 25250
diff changeset
    72
        if kind == 'subinclude':
25301
caaf4045eca8 match: normpath the ignore source when expanding the 'subinclude' kind
Matt Harbison <matt_harbison@yahoo.com>
parents: 25283
diff changeset
    73
            sourceroot = pathutil.dirname(util.normpath(source))
25283
19d0e5efa6ca match: enable 'subinclude:' syntax
Durham Goode <durham@fb.com>
parents: 25250
diff changeset
    74
            pat = util.pconvert(pat)
19d0e5efa6ca match: enable 'subinclude:' syntax
Durham Goode <durham@fb.com>
parents: 25250
diff changeset
    75
            path = pathutil.join(sourceroot, pat)
19d0e5efa6ca match: enable 'subinclude:' syntax
Durham Goode <durham@fb.com>
parents: 25250
diff changeset
    76
19d0e5efa6ca match: enable 'subinclude:' syntax
Durham Goode <durham@fb.com>
parents: 25250
diff changeset
    77
            newroot = pathutil.dirname(path)
32185
6dea1701f170 match: make subinclude construction lazy
Durham Goode <durham@fb.com>
parents: 31442
diff changeset
    78
            matcherargs = (newroot, '', [], ['include:%s' % path])
25283
19d0e5efa6ca match: enable 'subinclude:' syntax
Durham Goode <durham@fb.com>
parents: 25250
diff changeset
    79
19d0e5efa6ca match: enable 'subinclude:' syntax
Durham Goode <durham@fb.com>
parents: 25250
diff changeset
    80
            prefix = pathutil.canonpath(root, root, newroot)
19d0e5efa6ca match: enable 'subinclude:' syntax
Durham Goode <durham@fb.com>
parents: 25250
diff changeset
    81
            if prefix:
19d0e5efa6ca match: enable 'subinclude:' syntax
Durham Goode <durham@fb.com>
parents: 25250
diff changeset
    82
                prefix += '/'
32185
6dea1701f170 match: make subinclude construction lazy
Durham Goode <durham@fb.com>
parents: 31442
diff changeset
    83
            relmatchers.append((prefix, matcherargs))
25283
19d0e5efa6ca match: enable 'subinclude:' syntax
Durham Goode <durham@fb.com>
parents: 25250
diff changeset
    84
        else:
19d0e5efa6ca match: enable 'subinclude:' syntax
Durham Goode <durham@fb.com>
parents: 25250
diff changeset
    85
            other.append((kind, pat, source))
19d0e5efa6ca match: enable 'subinclude:' syntax
Durham Goode <durham@fb.com>
parents: 25250
diff changeset
    86
19d0e5efa6ca match: enable 'subinclude:' syntax
Durham Goode <durham@fb.com>
parents: 25250
diff changeset
    87
    return relmatchers, other
19d0e5efa6ca match: enable 'subinclude:' syntax
Durham Goode <durham@fb.com>
parents: 25250
diff changeset
    88
24447
d44d53bc9a1e matcher: make e.g. 'relpath:.' lead to fast paths
Martin von Zweigbergk <martinvonz@google.com>
parents: 23686
diff changeset
    89
def _kindpatsalwaysmatch(kindpats):
d44d53bc9a1e matcher: make e.g. 'relpath:.' lead to fast paths
Martin von Zweigbergk <martinvonz@google.com>
parents: 23686
diff changeset
    90
    """"Checks whether the kindspats match everything, as e.g.
d44d53bc9a1e matcher: make e.g. 'relpath:.' lead to fast paths
Martin von Zweigbergk <martinvonz@google.com>
parents: 23686
diff changeset
    91
    'relpath:.' does.
d44d53bc9a1e matcher: make e.g. 'relpath:.' lead to fast paths
Martin von Zweigbergk <martinvonz@google.com>
parents: 23686
diff changeset
    92
    """
25213
08a8e9da0ae7 match: add source to kindpats list
Durham Goode <durham@fb.com>
parents: 25195
diff changeset
    93
    for kind, pat, source in kindpats:
24447
d44d53bc9a1e matcher: make e.g. 'relpath:.' lead to fast paths
Martin von Zweigbergk <martinvonz@google.com>
parents: 23686
diff changeset
    94
        if pat != '' or kind not in ['relpath', 'glob']:
d44d53bc9a1e matcher: make e.g. 'relpath:.' lead to fast paths
Martin von Zweigbergk <martinvonz@google.com>
parents: 23686
diff changeset
    95
            return False
d44d53bc9a1e matcher: make e.g. 'relpath:.' lead to fast paths
Martin von Zweigbergk <martinvonz@google.com>
parents: 23686
diff changeset
    96
    return True
d44d53bc9a1e matcher: make e.g. 'relpath:.' lead to fast paths
Martin von Zweigbergk <martinvonz@google.com>
parents: 23686
diff changeset
    97
38581
9f9ffe5f687c match: compose 'set:' pattern as matcher
Yuya Nishihara <yuya@tcha.org>
parents: 38580
diff changeset
    98
def _buildkindpatsmatcher(matchercls, root, cwd, kindpats, ctx=None,
9f9ffe5f687c match: compose 'set:' pattern as matcher
Yuya Nishihara <yuya@tcha.org>
parents: 38580
diff changeset
    99
                          listsubrepos=False, badfn=None):
9f9ffe5f687c match: compose 'set:' pattern as matcher
Yuya Nishihara <yuya@tcha.org>
parents: 38580
diff changeset
   100
    fset, kindpats = _expandsets(kindpats, ctx, listsubrepos)
9f9ffe5f687c match: compose 'set:' pattern as matcher
Yuya Nishihara <yuya@tcha.org>
parents: 38580
diff changeset
   101
    matchers = []
9f9ffe5f687c match: compose 'set:' pattern as matcher
Yuya Nishihara <yuya@tcha.org>
parents: 38580
diff changeset
   102
    if kindpats:
9f9ffe5f687c match: compose 'set:' pattern as matcher
Yuya Nishihara <yuya@tcha.org>
parents: 38580
diff changeset
   103
        m = matchercls(root, cwd, kindpats, ctx=ctx, listsubrepos=listsubrepos,
9f9ffe5f687c match: compose 'set:' pattern as matcher
Yuya Nishihara <yuya@tcha.org>
parents: 38580
diff changeset
   104
                       badfn=badfn)
9f9ffe5f687c match: compose 'set:' pattern as matcher
Yuya Nishihara <yuya@tcha.org>
parents: 38580
diff changeset
   105
        matchers.append(m)
9f9ffe5f687c match: compose 'set:' pattern as matcher
Yuya Nishihara <yuya@tcha.org>
parents: 38580
diff changeset
   106
    if fset:
9f9ffe5f687c match: compose 'set:' pattern as matcher
Yuya Nishihara <yuya@tcha.org>
parents: 38580
diff changeset
   107
        m = predicatematcher(root, cwd, fset.__contains__,
9f9ffe5f687c match: compose 'set:' pattern as matcher
Yuya Nishihara <yuya@tcha.org>
parents: 38580
diff changeset
   108
                             predrepr='fileset', badfn=badfn)
9f9ffe5f687c match: compose 'set:' pattern as matcher
Yuya Nishihara <yuya@tcha.org>
parents: 38580
diff changeset
   109
        matchers.append(m)
9f9ffe5f687c match: compose 'set:' pattern as matcher
Yuya Nishihara <yuya@tcha.org>
parents: 38580
diff changeset
   110
    if not matchers:
9f9ffe5f687c match: compose 'set:' pattern as matcher
Yuya Nishihara <yuya@tcha.org>
parents: 38580
diff changeset
   111
        return nevermatcher(root, cwd, badfn=badfn)
9f9ffe5f687c match: compose 'set:' pattern as matcher
Yuya Nishihara <yuya@tcha.org>
parents: 38580
diff changeset
   112
    if len(matchers) == 1:
9f9ffe5f687c match: compose 'set:' pattern as matcher
Yuya Nishihara <yuya@tcha.org>
parents: 38580
diff changeset
   113
        return matchers[0]
9f9ffe5f687c match: compose 'set:' pattern as matcher
Yuya Nishihara <yuya@tcha.org>
parents: 38580
diff changeset
   114
    return unionmatcher(matchers)
9f9ffe5f687c match: compose 'set:' pattern as matcher
Yuya Nishihara <yuya@tcha.org>
parents: 38580
diff changeset
   115
32748
3e8eb6d84a5c match: allow pats to be None
Martin von Zweigbergk <martinvonz@google.com>
parents: 32673
diff changeset
   116
def match(root, cwd, patterns=None, include=None, exclude=None, default='glob',
32433
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32365
diff changeset
   117
          exact=False, auditor=None, ctx=None, listsubrepos=False, warn=None,
32439
284b18303f61 match: replace icasefsmatch() function by flag to regular match()
Martin von Zweigbergk <martinvonz@google.com>
parents: 32438
diff changeset
   118
          badfn=None, icasefs=False):
32433
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32365
diff changeset
   119
    """build an object to match a set of file patterns
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32365
diff changeset
   120
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32365
diff changeset
   121
    arguments:
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32365
diff changeset
   122
    root - the canonical root of the tree you're matching against
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32365
diff changeset
   123
    cwd - the current working directory, if relevant
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32365
diff changeset
   124
    patterns - patterns to find
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32365
diff changeset
   125
    include - patterns to include (unless they are excluded)
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32365
diff changeset
   126
    exclude - patterns to exclude (even if they are included)
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32365
diff changeset
   127
    default - if a pattern in patterns has no explicit type, assume this one
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32365
diff changeset
   128
    exact - patterns are actually filenames (include/exclude still apply)
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32365
diff changeset
   129
    warn - optional function used for printing warnings
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32365
diff changeset
   130
    badfn - optional bad() callback for this matcher instead of the default
32439
284b18303f61 match: replace icasefsmatch() function by flag to regular match()
Martin von Zweigbergk <martinvonz@google.com>
parents: 32438
diff changeset
   131
    icasefs - make a matcher for wdir on case insensitive filesystems, which
284b18303f61 match: replace icasefsmatch() function by flag to regular match()
Martin von Zweigbergk <martinvonz@google.com>
parents: 32438
diff changeset
   132
        normalizes the given patterns to the case in the filesystem
32433
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32365
diff changeset
   133
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32365
diff changeset
   134
    a pattern is one of:
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32365
diff changeset
   135
    'glob:<glob>' - a glob relative to cwd
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32365
diff changeset
   136
    're:<regexp>' - a regular expression
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32365
diff changeset
   137
    'path:<path>' - a path relative to repository root, which is matched
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32365
diff changeset
   138
                    recursively
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32365
diff changeset
   139
    'rootfilesin:<path>' - a path relative to repository root, which is
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32365
diff changeset
   140
                    matched non-recursively (will not match subdirectories)
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32365
diff changeset
   141
    'relglob:<glob>' - an unrooted glob (*.c matches C files in all dirs)
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32365
diff changeset
   142
    'relpath:<path>' - a path relative to cwd
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32365
diff changeset
   143
    'relre:<regexp>' - a regexp that needn't match the start of a name
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32365
diff changeset
   144
    'set:<fileset>' - a fileset expression
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32365
diff changeset
   145
    'include:<path>' - a file of patterns to read and include
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32365
diff changeset
   146
    'subinclude:<path>' - a file of patterns to match against files under
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32365
diff changeset
   147
                          the same directory
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32365
diff changeset
   148
    '<something>' - a pattern of the specified default type
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32365
diff changeset
   149
    """
32439
284b18303f61 match: replace icasefsmatch() function by flag to regular match()
Martin von Zweigbergk <martinvonz@google.com>
parents: 32438
diff changeset
   150
    normalize = _donormalize
284b18303f61 match: replace icasefsmatch() function by flag to regular match()
Martin von Zweigbergk <martinvonz@google.com>
parents: 32438
diff changeset
   151
    if icasefs:
32453
9695aca1a3a0 match: catch attempts to create case-insenstive exact matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32444
diff changeset
   152
        if exact:
32482
57d6c0c74b1b match: use ProgrammingError where appropriate
Martin von Zweigbergk <martinvonz@google.com>
parents: 32453
diff changeset
   153
            raise error.ProgrammingError("a case-insensitive exact matcher "
57d6c0c74b1b match: use ProgrammingError where appropriate
Martin von Zweigbergk <martinvonz@google.com>
parents: 32453
diff changeset
   154
                                         "doesn't make sense")
32439
284b18303f61 match: replace icasefsmatch() function by flag to regular match()
Martin von Zweigbergk <martinvonz@google.com>
parents: 32438
diff changeset
   155
        dirstate = ctx.repo().dirstate
284b18303f61 match: replace icasefsmatch() function by flag to regular match()
Martin von Zweigbergk <martinvonz@google.com>
parents: 32438
diff changeset
   156
        dsnormalize = dirstate.normalize
284b18303f61 match: replace icasefsmatch() function by flag to regular match()
Martin von Zweigbergk <martinvonz@google.com>
parents: 32438
diff changeset
   157
284b18303f61 match: replace icasefsmatch() function by flag to regular match()
Martin von Zweigbergk <martinvonz@google.com>
parents: 32438
diff changeset
   158
        def normalize(patterns, default, root, cwd, auditor, warn):
284b18303f61 match: replace icasefsmatch() function by flag to regular match()
Martin von Zweigbergk <martinvonz@google.com>
parents: 32438
diff changeset
   159
            kp = _donormalize(patterns, default, root, cwd, auditor, warn)
284b18303f61 match: replace icasefsmatch() function by flag to regular match()
Martin von Zweigbergk <martinvonz@google.com>
parents: 32438
diff changeset
   160
            kindpats = []
284b18303f61 match: replace icasefsmatch() function by flag to regular match()
Martin von Zweigbergk <martinvonz@google.com>
parents: 32438
diff changeset
   161
            for kind, pats, source in kp:
284b18303f61 match: replace icasefsmatch() function by flag to regular match()
Martin von Zweigbergk <martinvonz@google.com>
parents: 32438
diff changeset
   162
                if kind not in ('re', 'relre'):  # regex can't be normalized
284b18303f61 match: replace icasefsmatch() function by flag to regular match()
Martin von Zweigbergk <martinvonz@google.com>
parents: 32438
diff changeset
   163
                    p = pats
284b18303f61 match: replace icasefsmatch() function by flag to regular match()
Martin von Zweigbergk <martinvonz@google.com>
parents: 32438
diff changeset
   164
                    pats = dsnormalize(pats)
284b18303f61 match: replace icasefsmatch() function by flag to regular match()
Martin von Zweigbergk <martinvonz@google.com>
parents: 32438
diff changeset
   165
284b18303f61 match: replace icasefsmatch() function by flag to regular match()
Martin von Zweigbergk <martinvonz@google.com>
parents: 32438
diff changeset
   166
                    # Preserve the original to handle a case only rename.
284b18303f61 match: replace icasefsmatch() function by flag to regular match()
Martin von Zweigbergk <martinvonz@google.com>
parents: 32438
diff changeset
   167
                    if p != pats and p in dirstate:
284b18303f61 match: replace icasefsmatch() function by flag to regular match()
Martin von Zweigbergk <martinvonz@google.com>
parents: 32438
diff changeset
   168
                        kindpats.append((kind, p, source))
284b18303f61 match: replace icasefsmatch() function by flag to regular match()
Martin von Zweigbergk <martinvonz@google.com>
parents: 32438
diff changeset
   169
284b18303f61 match: replace icasefsmatch() function by flag to regular match()
Martin von Zweigbergk <martinvonz@google.com>
parents: 32438
diff changeset
   170
                kindpats.append((kind, pats, source))
284b18303f61 match: replace icasefsmatch() function by flag to regular match()
Martin von Zweigbergk <martinvonz@google.com>
parents: 32438
diff changeset
   171
            return kindpats
284b18303f61 match: replace icasefsmatch() function by flag to regular match()
Martin von Zweigbergk <martinvonz@google.com>
parents: 32438
diff changeset
   172
32532
a3583852861a match: handle exact matching using new exactmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32530
diff changeset
   173
    if exact:
a3583852861a match: handle exact matching using new exactmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32530
diff changeset
   174
        m = exactmatcher(root, cwd, patterns, badfn)
32586
20c9f3ecc192 match: handle everything-matching using new alwaysmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32585
diff changeset
   175
    elif patterns:
32589
5f08eca8f8d3 match: move normalize() call out of matcher constructors
Martin von Zweigbergk <martinvonz@google.com>
parents: 32588
diff changeset
   176
        kindpats = normalize(patterns, default, root, cwd, auditor, warn)
32590
3fdcc34c0aba match: remove special-casing of always-matching patterns in patternmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32589
diff changeset
   177
        if _kindpatsalwaysmatch(kindpats):
3fdcc34c0aba match: remove special-casing of always-matching patterns in patternmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32589
diff changeset
   178
            m = alwaysmatcher(root, cwd, badfn, relativeuipath=True)
3fdcc34c0aba match: remove special-casing of always-matching patterns in patternmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32589
diff changeset
   179
        else:
38581
9f9ffe5f687c match: compose 'set:' pattern as matcher
Yuya Nishihara <yuya@tcha.org>
parents: 38580
diff changeset
   180
            m = _buildkindpatsmatcher(patternmatcher, root, cwd, kindpats,
9f9ffe5f687c match: compose 'set:' pattern as matcher
Yuya Nishihara <yuya@tcha.org>
parents: 38580
diff changeset
   181
                                      ctx=ctx, listsubrepos=listsubrepos,
9f9ffe5f687c match: compose 'set:' pattern as matcher
Yuya Nishihara <yuya@tcha.org>
parents: 38580
diff changeset
   182
                                      badfn=badfn)
32586
20c9f3ecc192 match: handle everything-matching using new alwaysmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32585
diff changeset
   183
    else:
20c9f3ecc192 match: handle everything-matching using new alwaysmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32585
diff changeset
   184
        # It's a little strange that no patterns means to match everything.
32673
783394c0c978 match: simplify nevermatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32631
diff changeset
   185
        # Consider changing this to match nothing (probably using nevermatcher).
32586
20c9f3ecc192 match: handle everything-matching using new alwaysmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32585
diff changeset
   186
        m = alwaysmatcher(root, cwd, badfn)
20c9f3ecc192 match: handle everything-matching using new alwaysmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32585
diff changeset
   187
32530
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32529
diff changeset
   188
    if include:
32589
5f08eca8f8d3 match: move normalize() call out of matcher constructors
Martin von Zweigbergk <martinvonz@google.com>
parents: 32588
diff changeset
   189
        kindpats = normalize(include, 'glob', root, cwd, auditor, warn)
38581
9f9ffe5f687c match: compose 'set:' pattern as matcher
Yuya Nishihara <yuya@tcha.org>
parents: 38580
diff changeset
   190
        im = _buildkindpatsmatcher(includematcher, root, cwd, kindpats, ctx=ctx,
9f9ffe5f687c match: compose 'set:' pattern as matcher
Yuya Nishihara <yuya@tcha.org>
parents: 38580
diff changeset
   191
                                   listsubrepos=listsubrepos, badfn=None)
32530
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32529
diff changeset
   192
        m = intersectmatchers(m, im)
32499
a83a7d27911e match: handle excludes using new differencematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32498
diff changeset
   193
    if exclude:
32589
5f08eca8f8d3 match: move normalize() call out of matcher constructors
Martin von Zweigbergk <martinvonz@google.com>
parents: 32588
diff changeset
   194
        kindpats = normalize(exclude, 'glob', root, cwd, auditor, warn)
38581
9f9ffe5f687c match: compose 'set:' pattern as matcher
Yuya Nishihara <yuya@tcha.org>
parents: 38580
diff changeset
   195
        em = _buildkindpatsmatcher(includematcher, root, cwd, kindpats, ctx=ctx,
9f9ffe5f687c match: compose 'set:' pattern as matcher
Yuya Nishihara <yuya@tcha.org>
parents: 38580
diff changeset
   196
                                   listsubrepos=listsubrepos, badfn=None)
32499
a83a7d27911e match: handle excludes using new differencematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32498
diff changeset
   197
        m = differencematcher(m, em)
a83a7d27911e match: handle excludes using new differencematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32498
diff changeset
   198
    return m
32433
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32365
diff changeset
   199
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32365
diff changeset
   200
def exact(root, cwd, files, badfn=None):
32532
a3583852861a match: handle exact matching using new exactmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32530
diff changeset
   201
    return exactmatcher(root, cwd, files, badfn=badfn)
32433
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32365
diff changeset
   202
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32365
diff changeset
   203
def always(root, cwd):
32586
20c9f3ecc192 match: handle everything-matching using new alwaysmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32585
diff changeset
   204
    return alwaysmatcher(root, cwd)
32433
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32365
diff changeset
   205
32631
e6ff007e107e match: introduce nevermatcher for when no ignore files are present
Siddharth Agarwal <sid0@fb.com>
parents: 32590
diff changeset
   206
def never(root, cwd):
e6ff007e107e match: introduce nevermatcher for when no ignore files are present
Siddharth Agarwal <sid0@fb.com>
parents: 32590
diff changeset
   207
    return nevermatcher(root, cwd)
e6ff007e107e match: introduce nevermatcher for when no ignore files are present
Siddharth Agarwal <sid0@fb.com>
parents: 32590
diff changeset
   208
32433
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32365
diff changeset
   209
def badmatch(match, badfn):
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32365
diff changeset
   210
    """Make a copy of the given matcher, replacing its bad method with the given
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32365
diff changeset
   211
    one.
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32365
diff changeset
   212
    """
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32365
diff changeset
   213
    m = copy.copy(match)
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32365
diff changeset
   214
    m.bad = badfn
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32365
diff changeset
   215
    return m
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32365
diff changeset
   216
32435
0ec4cd6fe051 match: move body of _normalize() to a static function
Martin von Zweigbergk <martinvonz@google.com>
parents: 32434
diff changeset
   217
def _donormalize(patterns, default, root, cwd, auditor, warn):
0ec4cd6fe051 match: move body of _normalize() to a static function
Martin von Zweigbergk <martinvonz@google.com>
parents: 32434
diff changeset
   218
    '''Convert 'kind:pat' from the patterns list to tuples with kind and
0ec4cd6fe051 match: move body of _normalize() to a static function
Martin von Zweigbergk <martinvonz@google.com>
parents: 32434
diff changeset
   219
    normalized and rooted patterns and with listfiles expanded.'''
0ec4cd6fe051 match: move body of _normalize() to a static function
Martin von Zweigbergk <martinvonz@google.com>
parents: 32434
diff changeset
   220
    kindpats = []
0ec4cd6fe051 match: move body of _normalize() to a static function
Martin von Zweigbergk <martinvonz@google.com>
parents: 32434
diff changeset
   221
    for kind, pat in [_patsplit(p, default) for p in patterns]:
33710
2be0bf186950 match: expose some data and functionality to other modules
Kostia Balytskyi <ikostia@fb.com>
parents: 33582
diff changeset
   222
        if kind in cwdrelativepatternkinds:
32435
0ec4cd6fe051 match: move body of _normalize() to a static function
Martin von Zweigbergk <martinvonz@google.com>
parents: 32434
diff changeset
   223
            pat = pathutil.canonpath(root, cwd, pat, auditor)
0ec4cd6fe051 match: move body of _normalize() to a static function
Martin von Zweigbergk <martinvonz@google.com>
parents: 32434
diff changeset
   224
        elif kind in ('relglob', 'path', 'rootfilesin'):
0ec4cd6fe051 match: move body of _normalize() to a static function
Martin von Zweigbergk <martinvonz@google.com>
parents: 32434
diff changeset
   225
            pat = util.normpath(pat)
0ec4cd6fe051 match: move body of _normalize() to a static function
Martin von Zweigbergk <martinvonz@google.com>
parents: 32434
diff changeset
   226
        elif kind in ('listfile', 'listfile0'):
0ec4cd6fe051 match: move body of _normalize() to a static function
Martin von Zweigbergk <martinvonz@google.com>
parents: 32434
diff changeset
   227
            try:
0ec4cd6fe051 match: move body of _normalize() to a static function
Martin von Zweigbergk <martinvonz@google.com>
parents: 32434
diff changeset
   228
                files = util.readfile(pat)
0ec4cd6fe051 match: move body of _normalize() to a static function
Martin von Zweigbergk <martinvonz@google.com>
parents: 32434
diff changeset
   229
                if kind == 'listfile0':
0ec4cd6fe051 match: move body of _normalize() to a static function
Martin von Zweigbergk <martinvonz@google.com>
parents: 32434
diff changeset
   230
                    files = files.split('\0')
0ec4cd6fe051 match: move body of _normalize() to a static function
Martin von Zweigbergk <martinvonz@google.com>
parents: 32434
diff changeset
   231
                else:
0ec4cd6fe051 match: move body of _normalize() to a static function
Martin von Zweigbergk <martinvonz@google.com>
parents: 32434
diff changeset
   232
                    files = files.splitlines()
0ec4cd6fe051 match: move body of _normalize() to a static function
Martin von Zweigbergk <martinvonz@google.com>
parents: 32434
diff changeset
   233
                files = [f for f in files if f]
0ec4cd6fe051 match: move body of _normalize() to a static function
Martin von Zweigbergk <martinvonz@google.com>
parents: 32434
diff changeset
   234
            except EnvironmentError:
0ec4cd6fe051 match: move body of _normalize() to a static function
Martin von Zweigbergk <martinvonz@google.com>
parents: 32434
diff changeset
   235
                raise error.Abort(_("unable to read file list (%s)") % pat)
0ec4cd6fe051 match: move body of _normalize() to a static function
Martin von Zweigbergk <martinvonz@google.com>
parents: 32434
diff changeset
   236
            for k, p, source in _donormalize(files, default, root, cwd,
0ec4cd6fe051 match: move body of _normalize() to a static function
Martin von Zweigbergk <martinvonz@google.com>
parents: 32434
diff changeset
   237
                                             auditor, warn):
0ec4cd6fe051 match: move body of _normalize() to a static function
Martin von Zweigbergk <martinvonz@google.com>
parents: 32434
diff changeset
   238
                kindpats.append((k, p, pat))
0ec4cd6fe051 match: move body of _normalize() to a static function
Martin von Zweigbergk <martinvonz@google.com>
parents: 32434
diff changeset
   239
            continue
0ec4cd6fe051 match: move body of _normalize() to a static function
Martin von Zweigbergk <martinvonz@google.com>
parents: 32434
diff changeset
   240
        elif kind == 'include':
0ec4cd6fe051 match: move body of _normalize() to a static function
Martin von Zweigbergk <martinvonz@google.com>
parents: 32434
diff changeset
   241
            try:
0ec4cd6fe051 match: move body of _normalize() to a static function
Martin von Zweigbergk <martinvonz@google.com>
parents: 32434
diff changeset
   242
                fullpath = os.path.join(root, util.localpath(pat))
0ec4cd6fe051 match: move body of _normalize() to a static function
Martin von Zweigbergk <martinvonz@google.com>
parents: 32434
diff changeset
   243
                includepats = readpatternfile(fullpath, warn)
0ec4cd6fe051 match: move body of _normalize() to a static function
Martin von Zweigbergk <martinvonz@google.com>
parents: 32434
diff changeset
   244
                for k, p, source in _donormalize(includepats, default,
0ec4cd6fe051 match: move body of _normalize() to a static function
Martin von Zweigbergk <martinvonz@google.com>
parents: 32434
diff changeset
   245
                                                 root, cwd, auditor, warn):
0ec4cd6fe051 match: move body of _normalize() to a static function
Martin von Zweigbergk <martinvonz@google.com>
parents: 32434
diff changeset
   246
                    kindpats.append((k, p, source or pat))
0ec4cd6fe051 match: move body of _normalize() to a static function
Martin von Zweigbergk <martinvonz@google.com>
parents: 32434
diff changeset
   247
            except error.Abort as inst:
0ec4cd6fe051 match: move body of _normalize() to a static function
Martin von Zweigbergk <martinvonz@google.com>
parents: 32434
diff changeset
   248
                raise error.Abort('%s: %s' % (pat, inst[0]))
0ec4cd6fe051 match: move body of _normalize() to a static function
Martin von Zweigbergk <martinvonz@google.com>
parents: 32434
diff changeset
   249
            except IOError as inst:
0ec4cd6fe051 match: move body of _normalize() to a static function
Martin von Zweigbergk <martinvonz@google.com>
parents: 32434
diff changeset
   250
                if warn:
0ec4cd6fe051 match: move body of _normalize() to a static function
Martin von Zweigbergk <martinvonz@google.com>
parents: 32434
diff changeset
   251
                    warn(_("skipping unreadable pattern file '%s': %s\n") %
37087
f0b6fbea00cf stringutil: bulk-replace call sites to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 36601
diff changeset
   252
                         (pat, stringutil.forcebytestr(inst.strerror)))
32435
0ec4cd6fe051 match: move body of _normalize() to a static function
Martin von Zweigbergk <martinvonz@google.com>
parents: 32434
diff changeset
   253
            continue
0ec4cd6fe051 match: move body of _normalize() to a static function
Martin von Zweigbergk <martinvonz@google.com>
parents: 32434
diff changeset
   254
        # else: re or relre - which cannot be normalized
0ec4cd6fe051 match: move body of _normalize() to a static function
Martin von Zweigbergk <martinvonz@google.com>
parents: 32434
diff changeset
   255
        kindpats.append((kind, pat, ''))
0ec4cd6fe051 match: move body of _normalize() to a static function
Martin von Zweigbergk <martinvonz@google.com>
parents: 32434
diff changeset
   256
    return kindpats
0ec4cd6fe051 match: move body of _normalize() to a static function
Martin von Zweigbergk <martinvonz@google.com>
parents: 32434
diff changeset
   257
32492
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32482
diff changeset
   258
class basematcher(object):
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32482
diff changeset
   259
32529
ca77a243ffa7 match: move entire uipath() implementation to basematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32500
diff changeset
   260
    def __init__(self, root, cwd, badfn=None, relativeuipath=True):
32492
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32482
diff changeset
   261
        self._root = root
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32482
diff changeset
   262
        self._cwd = cwd
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32482
diff changeset
   263
        if badfn is not None:
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32482
diff changeset
   264
            self.bad = badfn
32529
ca77a243ffa7 match: move entire uipath() implementation to basematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32500
diff changeset
   265
        self._relativeuipath = relativeuipath
32492
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32482
diff changeset
   266
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32482
diff changeset
   267
    def __call__(self, fn):
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32482
diff changeset
   268
        return self.matchfn(fn)
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32482
diff changeset
   269
    def __iter__(self):
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32482
diff changeset
   270
        for f in self._files:
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32482
diff changeset
   271
            yield f
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32482
diff changeset
   272
    # Callbacks related to how the matcher is used by dirstate.walk.
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32482
diff changeset
   273
    # Subscribers to these events must monkeypatch the matcher object.
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32482
diff changeset
   274
    def bad(self, f, msg):
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32482
diff changeset
   275
        '''Callback from dirstate.walk for each explicit file that can't be
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32482
diff changeset
   276
        found/accessed, with an error message.'''
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32482
diff changeset
   277
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32482
diff changeset
   278
    # If an explicitdir is set, it will be called when an explicitly listed
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32482
diff changeset
   279
    # directory is visited.
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32482
diff changeset
   280
    explicitdir = None
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32482
diff changeset
   281
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32482
diff changeset
   282
    # If an traversedir is set, it will be called when a directory discovered
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32482
diff changeset
   283
    # by recursive traversal is visited.
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32482
diff changeset
   284
    traversedir = None
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32482
diff changeset
   285
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32482
diff changeset
   286
    def abs(self, f):
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32482
diff changeset
   287
        '''Convert a repo path back to path that is relative to the root of the
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32482
diff changeset
   288
        matcher.'''
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32482
diff changeset
   289
        return f
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32482
diff changeset
   290
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32482
diff changeset
   291
    def rel(self, f):
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32482
diff changeset
   292
        '''Convert repo path back to path that is relative to cwd of matcher.'''
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32482
diff changeset
   293
        return util.pathto(self._root, self._cwd, f)
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32482
diff changeset
   294
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32482
diff changeset
   295
    def uipath(self, f):
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32482
diff changeset
   296
        '''Convert repo path to a display path.  If patterns or -I/-X were used
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32482
diff changeset
   297
        to create this matcher, the display path will be relative to cwd.
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32482
diff changeset
   298
        Otherwise it is relative to the root of the repo.'''
32529
ca77a243ffa7 match: move entire uipath() implementation to basematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32500
diff changeset
   299
        return (self._relativeuipath and self.rel(f)) or self.abs(f)
32492
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32482
diff changeset
   300
32493
9f781f43f2ce match: make basematcher._files a @propertycache
Martin von Zweigbergk <martinvonz@google.com>
parents: 32492
diff changeset
   301
    @propertycache
9f781f43f2ce match: make basematcher._files a @propertycache
Martin von Zweigbergk <martinvonz@google.com>
parents: 32492
diff changeset
   302
    def _files(self):
9f781f43f2ce match: make basematcher._files a @propertycache
Martin von Zweigbergk <martinvonz@google.com>
parents: 32492
diff changeset
   303
        return []
9f781f43f2ce match: make basematcher._files a @propertycache
Martin von Zweigbergk <martinvonz@google.com>
parents: 32492
diff changeset
   304
32492
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32482
diff changeset
   305
    def files(self):
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32482
diff changeset
   306
        '''Explicitly listed files or patterns or roots:
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32482
diff changeset
   307
        if no patterns or .always(): empty list,
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32482
diff changeset
   308
        if exact: list exact files,
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32482
diff changeset
   309
        if not .anypats(): list all files and dirs,
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32482
diff changeset
   310
        else: optimal roots'''
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32482
diff changeset
   311
        return self._files
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32482
diff changeset
   312
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32482
diff changeset
   313
    @propertycache
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32482
diff changeset
   314
    def _fileset(self):
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32482
diff changeset
   315
        return set(self._files)
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32482
diff changeset
   316
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32482
diff changeset
   317
    def exact(self, f):
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32482
diff changeset
   318
        '''Returns True if f is in .files().'''
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32482
diff changeset
   319
        return f in self._fileset
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32482
diff changeset
   320
32497
43e091847c4d match: make matchfn a method on the class
Martin von Zweigbergk <martinvonz@google.com>
parents: 32495
diff changeset
   321
    def matchfn(self, f):
43e091847c4d match: make matchfn a method on the class
Martin von Zweigbergk <martinvonz@google.com>
parents: 32495
diff changeset
   322
        return False
43e091847c4d match: make matchfn a method on the class
Martin von Zweigbergk <martinvonz@google.com>
parents: 32495
diff changeset
   323
32492
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32482
diff changeset
   324
    def visitdir(self, dir):
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32482
diff changeset
   325
        '''Decides whether a directory should be visited based on whether it
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32482
diff changeset
   326
        has potential matches in it or one of its subdirectories. This is
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32482
diff changeset
   327
        based on the match's primary, included, and excluded patterns.
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32482
diff changeset
   328
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32482
diff changeset
   329
        Returns the string 'all' if the given directory and all subdirectories
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32482
diff changeset
   330
        should be visited. Otherwise returns True or False indicating whether
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32482
diff changeset
   331
        the given directory should be visited.
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32482
diff changeset
   332
        '''
33478
cf15c3cc304c match: make base matcher return True for visitdir
Durham Goode <durham@fb.com>
parents: 33448
diff changeset
   333
        return True
32492
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32482
diff changeset
   334
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32482
diff changeset
   335
    def always(self):
33379
7ddb2aa2b7af match: express anypats(), not prefix(), in terms of the others
Martin von Zweigbergk <martinvonz@google.com>
parents: 33378
diff changeset
   336
        '''Matcher will match everything and .files() will be empty --
7ddb2aa2b7af match: express anypats(), not prefix(), in terms of the others
Martin von Zweigbergk <martinvonz@google.com>
parents: 33378
diff changeset
   337
        optimization might be possible.'''
32492
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32482
diff changeset
   338
        return False
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32482
diff changeset
   339
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32482
diff changeset
   340
    def isexact(self):
33379
7ddb2aa2b7af match: express anypats(), not prefix(), in terms of the others
Martin von Zweigbergk <martinvonz@google.com>
parents: 33378
diff changeset
   341
        '''Matcher will match exactly the list of files in .files() --
7ddb2aa2b7af match: express anypats(), not prefix(), in terms of the others
Martin von Zweigbergk <martinvonz@google.com>
parents: 33378
diff changeset
   342
        optimization might be possible.'''
32492
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32482
diff changeset
   343
        return False
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32482
diff changeset
   344
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32482
diff changeset
   345
    def prefix(self):
33379
7ddb2aa2b7af match: express anypats(), not prefix(), in terms of the others
Martin von Zweigbergk <martinvonz@google.com>
parents: 33378
diff changeset
   346
        '''Matcher will match the paths in .files() recursively --
7ddb2aa2b7af match: express anypats(), not prefix(), in terms of the others
Martin von Zweigbergk <martinvonz@google.com>
parents: 33378
diff changeset
   347
        optimization might be possible.'''
7ddb2aa2b7af match: express anypats(), not prefix(), in terms of the others
Martin von Zweigbergk <martinvonz@google.com>
parents: 33378
diff changeset
   348
        return False
7ddb2aa2b7af match: express anypats(), not prefix(), in terms of the others
Martin von Zweigbergk <martinvonz@google.com>
parents: 33378
diff changeset
   349
7ddb2aa2b7af match: express anypats(), not prefix(), in terms of the others
Martin von Zweigbergk <martinvonz@google.com>
parents: 33378
diff changeset
   350
    def anypats(self):
7ddb2aa2b7af match: express anypats(), not prefix(), in terms of the others
Martin von Zweigbergk <martinvonz@google.com>
parents: 33378
diff changeset
   351
        '''None of .always(), .isexact(), and .prefix() is true --
7ddb2aa2b7af match: express anypats(), not prefix(), in terms of the others
Martin von Zweigbergk <martinvonz@google.com>
parents: 33378
diff changeset
   352
        optimizations will be difficult.'''
7ddb2aa2b7af match: express anypats(), not prefix(), in terms of the others
Martin von Zweigbergk <martinvonz@google.com>
parents: 33378
diff changeset
   353
        return not self.always() and not self.isexact() and not self.prefix()
32492
a04bc55201c3 match: extract base class for matchers
Martin von Zweigbergk <martinvonz@google.com>
parents: 32482
diff changeset
   354
32586
20c9f3ecc192 match: handle everything-matching using new alwaysmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32585
diff changeset
   355
class alwaysmatcher(basematcher):
20c9f3ecc192 match: handle everything-matching using new alwaysmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32585
diff changeset
   356
    '''Matches everything.'''
20c9f3ecc192 match: handle everything-matching using new alwaysmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32585
diff changeset
   357
32590
3fdcc34c0aba match: remove special-casing of always-matching patterns in patternmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32589
diff changeset
   358
    def __init__(self, root, cwd, badfn=None, relativeuipath=False):
32586
20c9f3ecc192 match: handle everything-matching using new alwaysmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32585
diff changeset
   359
        super(alwaysmatcher, self).__init__(root, cwd, badfn,
32590
3fdcc34c0aba match: remove special-casing of always-matching patterns in patternmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32589
diff changeset
   360
                                            relativeuipath=relativeuipath)
32586
20c9f3ecc192 match: handle everything-matching using new alwaysmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32585
diff changeset
   361
20c9f3ecc192 match: handle everything-matching using new alwaysmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32585
diff changeset
   362
    def always(self):
20c9f3ecc192 match: handle everything-matching using new alwaysmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32585
diff changeset
   363
        return True
20c9f3ecc192 match: handle everything-matching using new alwaysmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32585
diff changeset
   364
20c9f3ecc192 match: handle everything-matching using new alwaysmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32585
diff changeset
   365
    def matchfn(self, f):
20c9f3ecc192 match: handle everything-matching using new alwaysmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32585
diff changeset
   366
        return True
20c9f3ecc192 match: handle everything-matching using new alwaysmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32585
diff changeset
   367
20c9f3ecc192 match: handle everything-matching using new alwaysmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32585
diff changeset
   368
    def visitdir(self, dir):
20c9f3ecc192 match: handle everything-matching using new alwaysmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32585
diff changeset
   369
        return 'all'
20c9f3ecc192 match: handle everything-matching using new alwaysmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32585
diff changeset
   370
20c9f3ecc192 match: handle everything-matching using new alwaysmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32585
diff changeset
   371
    def __repr__(self):
36088
c4fa47f880d3 py3: make sure we return str from __repr__
Pulkit Goyal <7895pulkit@gmail.com>
parents: 35659
diff changeset
   372
        return r'<alwaysmatcher>'
32586
20c9f3ecc192 match: handle everything-matching using new alwaysmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32585
diff changeset
   373
32631
e6ff007e107e match: introduce nevermatcher for when no ignore files are present
Siddharth Agarwal <sid0@fb.com>
parents: 32590
diff changeset
   374
class nevermatcher(basematcher):
e6ff007e107e match: introduce nevermatcher for when no ignore files are present
Siddharth Agarwal <sid0@fb.com>
parents: 32590
diff changeset
   375
    '''Matches nothing.'''
e6ff007e107e match: introduce nevermatcher for when no ignore files are present
Siddharth Agarwal <sid0@fb.com>
parents: 32590
diff changeset
   376
32673
783394c0c978 match: simplify nevermatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32631
diff changeset
   377
    def __init__(self, root, cwd, badfn=None):
783394c0c978 match: simplify nevermatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32631
diff changeset
   378
        super(nevermatcher, self).__init__(root, cwd, badfn)
32631
e6ff007e107e match: introduce nevermatcher for when no ignore files are present
Siddharth Agarwal <sid0@fb.com>
parents: 32590
diff changeset
   379
33378
adf95bfb423a match: make nevermatcher an exact matcher and a prefix matcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 33358
diff changeset
   380
    # It's a little weird to say that the nevermatcher is an exact matcher
adf95bfb423a match: make nevermatcher an exact matcher and a prefix matcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 33358
diff changeset
   381
    # or a prefix matcher, but it seems to make sense to let callers take
adf95bfb423a match: make nevermatcher an exact matcher and a prefix matcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 33358
diff changeset
   382
    # fast paths based on either. There will be no exact matches, nor any
adf95bfb423a match: make nevermatcher an exact matcher and a prefix matcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 33358
diff changeset
   383
    # prefixes (files() returns []), so fast paths iterating over them should
adf95bfb423a match: make nevermatcher an exact matcher and a prefix matcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 33358
diff changeset
   384
    # be efficient (and correct).
adf95bfb423a match: make nevermatcher an exact matcher and a prefix matcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 33358
diff changeset
   385
    def isexact(self):
adf95bfb423a match: make nevermatcher an exact matcher and a prefix matcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 33358
diff changeset
   386
        return True
adf95bfb423a match: make nevermatcher an exact matcher and a prefix matcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 33358
diff changeset
   387
adf95bfb423a match: make nevermatcher an exact matcher and a prefix matcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 33358
diff changeset
   388
    def prefix(self):
adf95bfb423a match: make nevermatcher an exact matcher and a prefix matcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 33358
diff changeset
   389
        return True
adf95bfb423a match: make nevermatcher an exact matcher and a prefix matcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 33358
diff changeset
   390
33582
44bc181b9835 match: override visitdir() in nevermatcher to return False
Martin von Zweigbergk <martinvonz@google.com>
parents: 33497
diff changeset
   391
    def visitdir(self, dir):
44bc181b9835 match: override visitdir() in nevermatcher to return False
Martin von Zweigbergk <martinvonz@google.com>
parents: 33497
diff changeset
   392
        return False
44bc181b9835 match: override visitdir() in nevermatcher to return False
Martin von Zweigbergk <martinvonz@google.com>
parents: 33497
diff changeset
   393
32631
e6ff007e107e match: introduce nevermatcher for when no ignore files are present
Siddharth Agarwal <sid0@fb.com>
parents: 32590
diff changeset
   394
    def __repr__(self):
36088
c4fa47f880d3 py3: make sure we return str from __repr__
Pulkit Goyal <7895pulkit@gmail.com>
parents: 35659
diff changeset
   395
        return r'<nevermatcher>'
32631
e6ff007e107e match: introduce nevermatcher for when no ignore files are present
Siddharth Agarwal <sid0@fb.com>
parents: 32590
diff changeset
   396
38578
76838305b9dd match: add basic wrapper for boolean function
Yuya Nishihara <yuya@tcha.org>
parents: 38479
diff changeset
   397
class predicatematcher(basematcher):
76838305b9dd match: add basic wrapper for boolean function
Yuya Nishihara <yuya@tcha.org>
parents: 38479
diff changeset
   398
    """A matcher adapter for a simple boolean function"""
76838305b9dd match: add basic wrapper for boolean function
Yuya Nishihara <yuya@tcha.org>
parents: 38479
diff changeset
   399
76838305b9dd match: add basic wrapper for boolean function
Yuya Nishihara <yuya@tcha.org>
parents: 38479
diff changeset
   400
    def __init__(self, root, cwd, predfn, predrepr=None, badfn=None):
76838305b9dd match: add basic wrapper for boolean function
Yuya Nishihara <yuya@tcha.org>
parents: 38479
diff changeset
   401
        super(predicatematcher, self).__init__(root, cwd, badfn)
76838305b9dd match: add basic wrapper for boolean function
Yuya Nishihara <yuya@tcha.org>
parents: 38479
diff changeset
   402
        self.matchfn = predfn
76838305b9dd match: add basic wrapper for boolean function
Yuya Nishihara <yuya@tcha.org>
parents: 38479
diff changeset
   403
        self._predrepr = predrepr
76838305b9dd match: add basic wrapper for boolean function
Yuya Nishihara <yuya@tcha.org>
parents: 38479
diff changeset
   404
76838305b9dd match: add basic wrapper for boolean function
Yuya Nishihara <yuya@tcha.org>
parents: 38479
diff changeset
   405
    @encoding.strmethod
76838305b9dd match: add basic wrapper for boolean function
Yuya Nishihara <yuya@tcha.org>
parents: 38479
diff changeset
   406
    def __repr__(self):
76838305b9dd match: add basic wrapper for boolean function
Yuya Nishihara <yuya@tcha.org>
parents: 38479
diff changeset
   407
        s = (stringutil.buildrepr(self._predrepr)
76838305b9dd match: add basic wrapper for boolean function
Yuya Nishihara <yuya@tcha.org>
parents: 38479
diff changeset
   408
             or pycompat.byterepr(self.matchfn))
76838305b9dd match: add basic wrapper for boolean function
Yuya Nishihara <yuya@tcha.org>
parents: 38479
diff changeset
   409
        return '<predicatenmatcher pred=%s>' % s
76838305b9dd match: add basic wrapper for boolean function
Yuya Nishihara <yuya@tcha.org>
parents: 38479
diff changeset
   410
32534
7095dbc266e3 match: split up main matcher into patternmatcher and includematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32533
diff changeset
   411
class patternmatcher(basematcher):
32433
24245b54aa8a match: replace match class by match function (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32365
diff changeset
   412
32589
5f08eca8f8d3 match: move normalize() call out of matcher constructors
Martin von Zweigbergk <martinvonz@google.com>
parents: 32588
diff changeset
   413
    def __init__(self, root, cwd, kindpats, ctx=None, listsubrepos=False,
32537
2ba4d3b74ba8 match: remove support for includes from patternmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32536
diff changeset
   414
                 badfn=None):
32588
b3083be7dcb9 match: drop support for empty pattern list in patternmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32587
diff changeset
   415
        super(patternmatcher, self).__init__(root, cwd, badfn)
8581
101d305c1d0b match: fold _matcher into match.__init__
Matt Mackall <mpm@selenic.com>
parents: 8580
diff changeset
   416
32590
3fdcc34c0aba match: remove special-casing of always-matching patterns in patternmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32589
diff changeset
   417
        self._files = _explicitfiles(kindpats)
33405
6aa643762641 match: inverse _anypats(), making it _prefix()
Martin von Zweigbergk <martinvonz@google.com>
parents: 33380
diff changeset
   418
        self._prefix = _prefix(kindpats)
33306
a9808bd1449e match: minor cleanups to patternmatcher and includematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32748
diff changeset
   419
        self._pats, self.matchfn = _buildmatch(ctx, kindpats, '$', listsubrepos,
a9808bd1449e match: minor cleanups to patternmatcher and includematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32748
diff changeset
   420
                                               root)
8587
8f15d54437b9 match: fold match into _match base class
Matt Mackall <mpm@selenic.com>
parents: 8586
diff changeset
   421
32362
23c9a2a71c6e match: make _fileroots a @propertycache and rename it to _fileset
Martin von Zweigbergk <martinvonz@google.com>
parents: 32352
diff changeset
   422
    @propertycache
24636
36872036169b treemanifest: further optimize treemanifest.matches()
Drew Gottlieb <drgott@google.com>
parents: 24452
diff changeset
   423
    def _dirs(self):
32362
23c9a2a71c6e match: make _fileroots a @propertycache and rename it to _fileset
Martin von Zweigbergk <martinvonz@google.com>
parents: 32352
diff changeset
   424
        return set(util.dirs(self._fileset)) | {'.'}
24636
36872036169b treemanifest: further optimize treemanifest.matches()
Drew Gottlieb <drgott@google.com>
parents: 24452
diff changeset
   425
36872036169b treemanifest: further optimize treemanifest.matches()
Drew Gottlieb <drgott@google.com>
parents: 24452
diff changeset
   426
    def visitdir(self, dir):
33405
6aa643762641 match: inverse _anypats(), making it _prefix()
Martin von Zweigbergk <martinvonz@google.com>
parents: 33380
diff changeset
   427
        if self._prefix and dir in self._fileset:
27343
c59647c6694d treemanifest: don't iterate entire matching submanifests on match()
Martin von Zweigbergk <martinvonz@google.com>
parents: 27327
diff changeset
   428
            return 'all'
32587
f44ea253ffe2 match: optimize visitdir() for when no explicit files are listed
Martin von Zweigbergk <martinvonz@google.com>
parents: 32586
diff changeset
   429
        return ('.' in self._fileset or
32362
23c9a2a71c6e match: make _fileroots a @propertycache and rename it to _fileset
Martin von Zweigbergk <martinvonz@google.com>
parents: 32352
diff changeset
   430
                dir in self._fileset or
25576
d02f4b3e71f5 match: break boolean expressions into one operand per line
Martin von Zweigbergk <martinvonz@google.com>
parents: 25575
diff changeset
   431
                dir in self._dirs or
32362
23c9a2a71c6e match: make _fileroots a @propertycache and rename it to _fileset
Martin von Zweigbergk <martinvonz@google.com>
parents: 32352
diff changeset
   432
                any(parentdir in self._fileset
25577
a410479c7ee7 match: drop optimization (?) of 'parentdirs' calculation
Martin von Zweigbergk <martinvonz@google.com>
parents: 25576
diff changeset
   433
                    for parentdir in util.finddirs(dir)))
24636
36872036169b treemanifest: further optimize treemanifest.matches()
Drew Gottlieb <drgott@google.com>
parents: 24452
diff changeset
   434
33379
7ddb2aa2b7af match: express anypats(), not prefix(), in terms of the others
Martin von Zweigbergk <martinvonz@google.com>
parents: 33378
diff changeset
   435
    def prefix(self):
33405
6aa643762641 match: inverse _anypats(), making it _prefix()
Martin von Zweigbergk <martinvonz@google.com>
parents: 33380
diff changeset
   436
        return self._prefix
21111
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
   437
36088
c4fa47f880d3 py3: make sure we return str from __repr__
Pulkit Goyal <7895pulkit@gmail.com>
parents: 35659
diff changeset
   438
    @encoding.strmethod
32444
952017471f93 match: implement __repr__() and update users (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32439
diff changeset
   439
    def __repr__(self):
38061
2f406142d7b4 py3: use pycompat.bytestr() on bytes before %r-ing it
Pulkit Goyal <7895pulkit@gmail.com>
parents: 37087
diff changeset
   440
        return ('<patternmatcher patterns=%r>' % pycompat.bytestr(self._pats))
32534
7095dbc266e3 match: split up main matcher into patternmatcher and includematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32533
diff changeset
   441
7095dbc266e3 match: split up main matcher into patternmatcher and includematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32533
diff changeset
   442
class includematcher(basematcher):
7095dbc266e3 match: split up main matcher into patternmatcher and includematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32533
diff changeset
   443
32589
5f08eca8f8d3 match: move normalize() call out of matcher constructors
Martin von Zweigbergk <martinvonz@google.com>
parents: 32588
diff changeset
   444
    def __init__(self, root, cwd, kindpats, ctx=None, listsubrepos=False,
5f08eca8f8d3 match: move normalize() call out of matcher constructors
Martin von Zweigbergk <martinvonz@google.com>
parents: 32588
diff changeset
   445
                 badfn=None):
32535
3026f19b4b01 match: remove support for non-include patterns from includematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32534
diff changeset
   446
        super(includematcher, self).__init__(root, cwd, badfn)
32534
7095dbc266e3 match: split up main matcher into patternmatcher and includematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32533
diff changeset
   447
33306
a9808bd1449e match: minor cleanups to patternmatcher and includematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32748
diff changeset
   448
        self._pats, self.matchfn = _buildmatch(ctx, kindpats, '(?:/|$)',
a9808bd1449e match: minor cleanups to patternmatcher and includematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32748
diff changeset
   449
                                               listsubrepos, root)
33405
6aa643762641 match: inverse _anypats(), making it _prefix()
Martin von Zweigbergk <martinvonz@google.com>
parents: 33380
diff changeset
   450
        self._prefix = _prefix(kindpats)
32535
3026f19b4b01 match: remove support for non-include patterns from includematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32534
diff changeset
   451
        roots, dirs = _rootsanddirs(kindpats)
3026f19b4b01 match: remove support for non-include patterns from includematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32534
diff changeset
   452
        # roots are directories which are recursively included.
32536
361808a2b0b8 match: simplify includematcher a bit
Martin von Zweigbergk <martinvonz@google.com>
parents: 32535
diff changeset
   453
        self._roots = set(roots)
32535
3026f19b4b01 match: remove support for non-include patterns from includematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32534
diff changeset
   454
        # dirs are directories which are non-recursively included.
32536
361808a2b0b8 match: simplify includematcher a bit
Martin von Zweigbergk <martinvonz@google.com>
parents: 32535
diff changeset
   455
        self._dirs = set(dirs)
32534
7095dbc266e3 match: split up main matcher into patternmatcher and includematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32533
diff changeset
   456
7095dbc266e3 match: split up main matcher into patternmatcher and includematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32533
diff changeset
   457
    def visitdir(self, dir):
33405
6aa643762641 match: inverse _anypats(), making it _prefix()
Martin von Zweigbergk <martinvonz@google.com>
parents: 33380
diff changeset
   458
        if self._prefix and dir in self._roots:
32534
7095dbc266e3 match: split up main matcher into patternmatcher and includematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32533
diff changeset
   459
            return 'all'
32536
361808a2b0b8 match: simplify includematcher a bit
Martin von Zweigbergk <martinvonz@google.com>
parents: 32535
diff changeset
   460
        return ('.' in self._roots or
361808a2b0b8 match: simplify includematcher a bit
Martin von Zweigbergk <martinvonz@google.com>
parents: 32535
diff changeset
   461
                dir in self._roots or
361808a2b0b8 match: simplify includematcher a bit
Martin von Zweigbergk <martinvonz@google.com>
parents: 32535
diff changeset
   462
                dir in self._dirs or
361808a2b0b8 match: simplify includematcher a bit
Martin von Zweigbergk <martinvonz@google.com>
parents: 32535
diff changeset
   463
                any(parentdir in self._roots
361808a2b0b8 match: simplify includematcher a bit
Martin von Zweigbergk <martinvonz@google.com>
parents: 32535
diff changeset
   464
                    for parentdir in util.finddirs(dir)))
32534
7095dbc266e3 match: split up main matcher into patternmatcher and includematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32533
diff changeset
   465
36088
c4fa47f880d3 py3: make sure we return str from __repr__
Pulkit Goyal <7895pulkit@gmail.com>
parents: 35659
diff changeset
   466
    @encoding.strmethod
32534
7095dbc266e3 match: split up main matcher into patternmatcher and includematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32533
diff changeset
   467
    def __repr__(self):
36601
9adfa48792a7 match: some minimal pycompat fixes guided by test-hgignore.t
Augie Fackler <augie@google.com>
parents: 36088
diff changeset
   468
        return ('<includematcher includes=%r>' % pycompat.bytestr(self._pats))
32444
952017471f93 match: implement __repr__() and update users (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32439
diff changeset
   469
32532
a3583852861a match: handle exact matching using new exactmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32530
diff changeset
   470
class exactmatcher(basematcher):
a3583852861a match: handle exact matching using new exactmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32530
diff changeset
   471
    '''Matches the input files exactly. They are interpreted as paths, not
a3583852861a match: handle exact matching using new exactmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32530
diff changeset
   472
    patterns (so no kind-prefixes).
a3583852861a match: handle exact matching using new exactmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32530
diff changeset
   473
    '''
a3583852861a match: handle exact matching using new exactmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32530
diff changeset
   474
a3583852861a match: handle exact matching using new exactmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32530
diff changeset
   475
    def __init__(self, root, cwd, files, badfn=None):
a3583852861a match: handle exact matching using new exactmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32530
diff changeset
   476
        super(exactmatcher, self).__init__(root, cwd, badfn)
a3583852861a match: handle exact matching using new exactmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32530
diff changeset
   477
a3583852861a match: handle exact matching using new exactmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32530
diff changeset
   478
        if isinstance(files, list):
a3583852861a match: handle exact matching using new exactmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32530
diff changeset
   479
            self._files = files
a3583852861a match: handle exact matching using new exactmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32530
diff changeset
   480
        else:
a3583852861a match: handle exact matching using new exactmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32530
diff changeset
   481
            self._files = list(files)
32576
cf7c88986e9f match: define exactmatcher.matchfn statically
Yuya Nishihara <yuya@tcha.org>
parents: 32575
diff changeset
   482
cf7c88986e9f match: define exactmatcher.matchfn statically
Yuya Nishihara <yuya@tcha.org>
parents: 32575
diff changeset
   483
    matchfn = basematcher.exact
32532
a3583852861a match: handle exact matching using new exactmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32530
diff changeset
   484
a3583852861a match: handle exact matching using new exactmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32530
diff changeset
   485
    @propertycache
a3583852861a match: handle exact matching using new exactmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32530
diff changeset
   486
    def _dirs(self):
a3583852861a match: handle exact matching using new exactmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32530
diff changeset
   487
        return set(util.dirs(self._fileset)) | {'.'}
a3583852861a match: handle exact matching using new exactmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32530
diff changeset
   488
a3583852861a match: handle exact matching using new exactmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32530
diff changeset
   489
    def visitdir(self, dir):
a3583852861a match: handle exact matching using new exactmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32530
diff changeset
   490
        return dir in self._dirs
a3583852861a match: handle exact matching using new exactmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32530
diff changeset
   491
a3583852861a match: handle exact matching using new exactmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32530
diff changeset
   492
    def isexact(self):
a3583852861a match: handle exact matching using new exactmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32530
diff changeset
   493
        return True
a3583852861a match: handle exact matching using new exactmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32530
diff changeset
   494
36088
c4fa47f880d3 py3: make sure we return str from __repr__
Pulkit Goyal <7895pulkit@gmail.com>
parents: 35659
diff changeset
   495
    @encoding.strmethod
32532
a3583852861a match: handle exact matching using new exactmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32530
diff changeset
   496
    def __repr__(self):
a3583852861a match: handle exact matching using new exactmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32530
diff changeset
   497
        return ('<exactmatcher files=%r>' % self._files)
a3583852861a match: handle exact matching using new exactmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32530
diff changeset
   498
32499
a83a7d27911e match: handle excludes using new differencematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32498
diff changeset
   499
class differencematcher(basematcher):
a83a7d27911e match: handle excludes using new differencematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32498
diff changeset
   500
    '''Composes two matchers by matching if the first matches and the second
35659
821d8a5ab4ff match: do not weirdly include explicit files excluded by -X option
Yuya Nishihara <yuya@tcha.org>
parents: 35185
diff changeset
   501
    does not.
32499
a83a7d27911e match: handle excludes using new differencematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32498
diff changeset
   502
a83a7d27911e match: handle excludes using new differencematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32498
diff changeset
   503
    The second matcher's non-matching-attributes (root, cwd, bad, explicitdir,
a83a7d27911e match: handle excludes using new differencematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32498
diff changeset
   504
    traversedir) are ignored.
a83a7d27911e match: handle excludes using new differencematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32498
diff changeset
   505
    '''
a83a7d27911e match: handle excludes using new differencematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32498
diff changeset
   506
    def __init__(self, m1, m2):
a83a7d27911e match: handle excludes using new differencematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32498
diff changeset
   507
        super(differencematcher, self).__init__(m1._root, m1._cwd)
a83a7d27911e match: handle excludes using new differencematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32498
diff changeset
   508
        self._m1 = m1
a83a7d27911e match: handle excludes using new differencematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32498
diff changeset
   509
        self._m2 = m2
a83a7d27911e match: handle excludes using new differencematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32498
diff changeset
   510
        self.bad = m1.bad
a83a7d27911e match: handle excludes using new differencematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32498
diff changeset
   511
        self.explicitdir = m1.explicitdir
a83a7d27911e match: handle excludes using new differencematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32498
diff changeset
   512
        self.traversedir = m1.traversedir
a83a7d27911e match: handle excludes using new differencematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32498
diff changeset
   513
a83a7d27911e match: handle excludes using new differencematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32498
diff changeset
   514
    def matchfn(self, f):
35659
821d8a5ab4ff match: do not weirdly include explicit files excluded by -X option
Yuya Nishihara <yuya@tcha.org>
parents: 35185
diff changeset
   515
        return self._m1(f) and not self._m2(f)
32499
a83a7d27911e match: handle excludes using new differencematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32498
diff changeset
   516
a83a7d27911e match: handle excludes using new differencematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32498
diff changeset
   517
    @propertycache
a83a7d27911e match: handle excludes using new differencematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32498
diff changeset
   518
    def _files(self):
a83a7d27911e match: handle excludes using new differencematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32498
diff changeset
   519
        if self.isexact():
a83a7d27911e match: handle excludes using new differencematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32498
diff changeset
   520
            return [f for f in self._m1.files() if self(f)]
a83a7d27911e match: handle excludes using new differencematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32498
diff changeset
   521
        # If m1 is not an exact matcher, we can't easily figure out the set of
a83a7d27911e match: handle excludes using new differencematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32498
diff changeset
   522
        # files, because its files() are not always files. For example, if
a83a7d27911e match: handle excludes using new differencematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32498
diff changeset
   523
        # m1 is "path:dir" and m2 is "rootfileins:.", we don't
a83a7d27911e match: handle excludes using new differencematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32498
diff changeset
   524
        # want to remove "dir" from the set even though it would match m2,
a83a7d27911e match: handle excludes using new differencematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32498
diff changeset
   525
        # because the "dir" in m1 may not be a file.
a83a7d27911e match: handle excludes using new differencematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32498
diff changeset
   526
        return self._m1.files()
a83a7d27911e match: handle excludes using new differencematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32498
diff changeset
   527
a83a7d27911e match: handle excludes using new differencematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32498
diff changeset
   528
    def visitdir(self, dir):
a83a7d27911e match: handle excludes using new differencematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32498
diff changeset
   529
        if self._m2.visitdir(dir) == 'all':
a83a7d27911e match: handle excludes using new differencematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32498
diff changeset
   530
            return False
a83a7d27911e match: handle excludes using new differencematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32498
diff changeset
   531
        return bool(self._m1.visitdir(dir))
a83a7d27911e match: handle excludes using new differencematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32498
diff changeset
   532
a83a7d27911e match: handle excludes using new differencematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32498
diff changeset
   533
    def isexact(self):
a83a7d27911e match: handle excludes using new differencematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32498
diff changeset
   534
        return self._m1.isexact()
a83a7d27911e match: handle excludes using new differencematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32498
diff changeset
   535
36088
c4fa47f880d3 py3: make sure we return str from __repr__
Pulkit Goyal <7895pulkit@gmail.com>
parents: 35659
diff changeset
   536
    @encoding.strmethod
32499
a83a7d27911e match: handle excludes using new differencematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32498
diff changeset
   537
    def __repr__(self):
a83a7d27911e match: handle excludes using new differencematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32498
diff changeset
   538
        return ('<differencematcher m1=%r, m2=%r>' % (self._m1, self._m2))
a83a7d27911e match: handle excludes using new differencematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32498
diff changeset
   539
32530
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32529
diff changeset
   540
def intersectmatchers(m1, m2):
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32529
diff changeset
   541
    '''Composes two matchers by matching if both of them match.
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32529
diff changeset
   542
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32529
diff changeset
   543
    The second matcher's non-matching-attributes (root, cwd, bad, explicitdir,
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32529
diff changeset
   544
    traversedir) are ignored.
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32529
diff changeset
   545
    '''
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32529
diff changeset
   546
    if m1 is None or m2 is None:
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32529
diff changeset
   547
        return m1 or m2
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32529
diff changeset
   548
    if m1.always():
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32529
diff changeset
   549
        m = copy.copy(m2)
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32529
diff changeset
   550
        # TODO: Consider encapsulating these things in a class so there's only
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32529
diff changeset
   551
        # one thing to copy from m1.
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32529
diff changeset
   552
        m.bad = m1.bad
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32529
diff changeset
   553
        m.explicitdir = m1.explicitdir
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32529
diff changeset
   554
        m.traversedir = m1.traversedir
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32529
diff changeset
   555
        m.abs = m1.abs
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32529
diff changeset
   556
        m.rel = m1.rel
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32529
diff changeset
   557
        m._relativeuipath |= m1._relativeuipath
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32529
diff changeset
   558
        return m
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32529
diff changeset
   559
    if m2.always():
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32529
diff changeset
   560
        m = copy.copy(m1)
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32529
diff changeset
   561
        m._relativeuipath |= m2._relativeuipath
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32529
diff changeset
   562
        return m
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32529
diff changeset
   563
    return intersectionmatcher(m1, m2)
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32529
diff changeset
   564
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32529
diff changeset
   565
class intersectionmatcher(basematcher):
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32529
diff changeset
   566
    def __init__(self, m1, m2):
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32529
diff changeset
   567
        super(intersectionmatcher, self).__init__(m1._root, m1._cwd)
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32529
diff changeset
   568
        self._m1 = m1
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32529
diff changeset
   569
        self._m2 = m2
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32529
diff changeset
   570
        self.bad = m1.bad
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32529
diff changeset
   571
        self.explicitdir = m1.explicitdir
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32529
diff changeset
   572
        self.traversedir = m1.traversedir
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32529
diff changeset
   573
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32529
diff changeset
   574
    @propertycache
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32529
diff changeset
   575
    def _files(self):
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32529
diff changeset
   576
        if self.isexact():
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32529
diff changeset
   577
            m1, m2 = self._m1, self._m2
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32529
diff changeset
   578
            if not m1.isexact():
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32529
diff changeset
   579
                m1, m2 = m2, m1
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32529
diff changeset
   580
            return [f for f in m1.files() if m2(f)]
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32529
diff changeset
   581
        # It neither m1 nor m2 is an exact matcher, we can't easily intersect
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32529
diff changeset
   582
        # the set of files, because their files() are not always files. For
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32529
diff changeset
   583
        # example, if intersecting a matcher "-I glob:foo.txt" with matcher of
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32529
diff changeset
   584
        # "path:dir2", we don't want to remove "dir2" from the set.
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32529
diff changeset
   585
        return self._m1.files() + self._m2.files()
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32529
diff changeset
   586
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32529
diff changeset
   587
    def matchfn(self, f):
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32529
diff changeset
   588
        return self._m1(f) and self._m2(f)
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32529
diff changeset
   589
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32529
diff changeset
   590
    def visitdir(self, dir):
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32529
diff changeset
   591
        visit1 = self._m1.visitdir(dir)
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32529
diff changeset
   592
        if visit1 == 'all':
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32529
diff changeset
   593
            return self._m2.visitdir(dir)
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32529
diff changeset
   594
        # bool() because visit1=True + visit2='all' should not be 'all'
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32529
diff changeset
   595
        return bool(visit1 and self._m2.visitdir(dir))
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32529
diff changeset
   596
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32529
diff changeset
   597
    def always(self):
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32529
diff changeset
   598
        return self._m1.always() and self._m2.always()
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32529
diff changeset
   599
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32529
diff changeset
   600
    def isexact(self):
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32529
diff changeset
   601
        return self._m1.isexact() or self._m2.isexact()
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32529
diff changeset
   602
36088
c4fa47f880d3 py3: make sure we return str from __repr__
Pulkit Goyal <7895pulkit@gmail.com>
parents: 35659
diff changeset
   603
    @encoding.strmethod
32530
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32529
diff changeset
   604
    def __repr__(self):
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32529
diff changeset
   605
        return ('<intersectionmatcher m1=%r, m2=%r>' % (self._m1, self._m2))
9eccd559c592 match: handle includes using new intersectionmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32529
diff changeset
   606
32494
f9445b528687 match: make subdirmatcher extend basematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32493
diff changeset
   607
class subdirmatcher(basematcher):
12165
b7fbf24c8a93 match: add narrowmatcher class
Martin Geisler <mg@lazybytes.net>
parents: 12163
diff changeset
   608
    """Adapt a matcher to work on a subdirectory only.
b7fbf24c8a93 match: add narrowmatcher class
Martin Geisler <mg@lazybytes.net>
parents: 12163
diff changeset
   609
b7fbf24c8a93 match: add narrowmatcher class
Martin Geisler <mg@lazybytes.net>
parents: 12163
diff changeset
   610
    The paths are remapped to remove/insert the path as needed:
b7fbf24c8a93 match: add narrowmatcher class
Martin Geisler <mg@lazybytes.net>
parents: 12163
diff changeset
   611
34152
a8994d08e4a2 doctest: use print_function and convert bytes to unicode where needed
Yuya Nishihara <yuya@tcha.org>
parents: 34146
diff changeset
   612
    >>> from . import pycompat
34146
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 33710
diff changeset
   613
    >>> m1 = match(b'root', b'', [b'a.txt', b'sub/b.txt'])
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 33710
diff changeset
   614
    >>> m2 = subdirmatcher(b'sub', m1)
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 33710
diff changeset
   615
    >>> bool(m2(b'a.txt'))
12165
b7fbf24c8a93 match: add narrowmatcher class
Martin Geisler <mg@lazybytes.net>
parents: 12163
diff changeset
   616
    False
34146
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 33710
diff changeset
   617
    >>> bool(m2(b'b.txt'))
12165
b7fbf24c8a93 match: add narrowmatcher class
Martin Geisler <mg@lazybytes.net>
parents: 12163
diff changeset
   618
    True
34146
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 33710
diff changeset
   619
    >>> bool(m2.matchfn(b'a.txt'))
12165
b7fbf24c8a93 match: add narrowmatcher class
Martin Geisler <mg@lazybytes.net>
parents: 12163
diff changeset
   620
    False
34146
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 33710
diff changeset
   621
    >>> bool(m2.matchfn(b'b.txt'))
12165
b7fbf24c8a93 match: add narrowmatcher class
Martin Geisler <mg@lazybytes.net>
parents: 12163
diff changeset
   622
    True
b7fbf24c8a93 match: add narrowmatcher class
Martin Geisler <mg@lazybytes.net>
parents: 12163
diff changeset
   623
    >>> m2.files()
b7fbf24c8a93 match: add narrowmatcher class
Martin Geisler <mg@lazybytes.net>
parents: 12163
diff changeset
   624
    ['b.txt']
34146
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 33710
diff changeset
   625
    >>> m2.exact(b'b.txt')
12165
b7fbf24c8a93 match: add narrowmatcher class
Martin Geisler <mg@lazybytes.net>
parents: 12163
diff changeset
   626
    True
34146
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 33710
diff changeset
   627
    >>> util.pconvert(m2.rel(b'b.txt'))
23686
164915e8ef7b narrowmatcher: propagate the rel() method
Matt Harbison <matt_harbison@yahoo.com>
parents: 23685
diff changeset
   628
    'sub/b.txt'
12268
83aaeba32b88 narrowmatcher: propagate bad method
Martin Geisler <mg@lazybytes.net>
parents: 12267
diff changeset
   629
    >>> def bad(f, msg):
34152
a8994d08e4a2 doctest: use print_function and convert bytes to unicode where needed
Yuya Nishihara <yuya@tcha.org>
parents: 34146
diff changeset
   630
    ...     print(pycompat.sysstr(b"%s: %s" % (f, msg)))
12268
83aaeba32b88 narrowmatcher: propagate bad method
Martin Geisler <mg@lazybytes.net>
parents: 12267
diff changeset
   631
    >>> m1.bad = bad
34146
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 33710
diff changeset
   632
    >>> m2.bad(b'x.txt', b'No such file')
12268
83aaeba32b88 narrowmatcher: propagate bad method
Martin Geisler <mg@lazybytes.net>
parents: 12267
diff changeset
   633
    sub/x.txt: No such file
34146
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 33710
diff changeset
   634
    >>> m2.abs(b'c.txt')
23685
5b1eac343ccd match: add the abs() method
Matt Harbison <matt_harbison@yahoo.com>
parents: 23549
diff changeset
   635
    'sub/c.txt'
12165
b7fbf24c8a93 match: add narrowmatcher class
Martin Geisler <mg@lazybytes.net>
parents: 12163
diff changeset
   636
    """
b7fbf24c8a93 match: add narrowmatcher class
Martin Geisler <mg@lazybytes.net>
parents: 12163
diff changeset
   637
b7fbf24c8a93 match: add narrowmatcher class
Martin Geisler <mg@lazybytes.net>
parents: 12163
diff changeset
   638
    def __init__(self, path, matcher):
32494
f9445b528687 match: make subdirmatcher extend basematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32493
diff changeset
   639
        super(subdirmatcher, self).__init__(matcher._root, matcher._cwd)
12165
b7fbf24c8a93 match: add narrowmatcher class
Martin Geisler <mg@lazybytes.net>
parents: 12163
diff changeset
   640
        self._path = path
b7fbf24c8a93 match: add narrowmatcher class
Martin Geisler <mg@lazybytes.net>
parents: 12163
diff changeset
   641
        self._matcher = matcher
32494
f9445b528687 match: make subdirmatcher extend basematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32493
diff changeset
   642
        self._always = matcher.always()
12165
b7fbf24c8a93 match: add narrowmatcher class
Martin Geisler <mg@lazybytes.net>
parents: 12163
diff changeset
   643
b7fbf24c8a93 match: add narrowmatcher class
Martin Geisler <mg@lazybytes.net>
parents: 12163
diff changeset
   644
        self._files = [f[len(path) + 1:] for f in matcher._files
b7fbf24c8a93 match: add narrowmatcher class
Martin Geisler <mg@lazybytes.net>
parents: 12163
diff changeset
   645
                       if f.startswith(path + "/")]
25194
ef4538ba67ef match: explicitly naming a subrepo implies always() for the submatcher
Matt Harbison <matt_harbison@yahoo.com>
parents: 24790
diff changeset
   646
32365
763d72925691 match: use match.prefix() in subdirmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32364
diff changeset
   647
        # If the parent repo had a path to this subrepo and the matcher is
763d72925691 match: use match.prefix() in subdirmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32364
diff changeset
   648
        # a prefix matcher, this submatcher always matches.
763d72925691 match: use match.prefix() in subdirmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32364
diff changeset
   649
        if matcher.prefix():
25195
472a685a4961 merge with stable
Matt Mackall <mpm@selenic.com>
parents: 25189 25194
diff changeset
   650
            self._always = any(f == path for f in matcher._files)
25194
ef4538ba67ef match: explicitly naming a subrepo implies always() for the submatcher
Matt Harbison <matt_harbison@yahoo.com>
parents: 24790
diff changeset
   651
32364
77dac8fd30ee match: avoid accessing match._pathrestricted from subdirmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32363
diff changeset
   652
    def bad(self, f, msg):
77dac8fd30ee match: avoid accessing match._pathrestricted from subdirmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32363
diff changeset
   653
        self._matcher.bad(self._path + "/" + f, msg)
77dac8fd30ee match: avoid accessing match._pathrestricted from subdirmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32363
diff changeset
   654
23685
5b1eac343ccd match: add the abs() method
Matt Harbison <matt_harbison@yahoo.com>
parents: 23549
diff changeset
   655
    def abs(self, f):
5b1eac343ccd match: add the abs() method
Matt Harbison <matt_harbison@yahoo.com>
parents: 23549
diff changeset
   656
        return self._matcher.abs(self._path + "/" + f)
5b1eac343ccd match: add the abs() method
Matt Harbison <matt_harbison@yahoo.com>
parents: 23549
diff changeset
   657
23686
164915e8ef7b narrowmatcher: propagate the rel() method
Matt Harbison <matt_harbison@yahoo.com>
parents: 23685
diff changeset
   658
    def rel(self, f):
164915e8ef7b narrowmatcher: propagate the rel() method
Matt Harbison <matt_harbison@yahoo.com>
parents: 23685
diff changeset
   659
        return self._matcher.rel(self._path + "/" + f)
164915e8ef7b narrowmatcher: propagate the rel() method
Matt Harbison <matt_harbison@yahoo.com>
parents: 23685
diff changeset
   660
32364
77dac8fd30ee match: avoid accessing match._pathrestricted from subdirmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32363
diff changeset
   661
    def uipath(self, f):
77dac8fd30ee match: avoid accessing match._pathrestricted from subdirmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32363
diff changeset
   662
        return self._matcher.uipath(self._path + "/" + f)
77dac8fd30ee match: avoid accessing match._pathrestricted from subdirmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32363
diff changeset
   663
32498
2e80a691e575 match: override matchfn() the usual way in subdirmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32497
diff changeset
   664
    def matchfn(self, f):
2e80a691e575 match: override matchfn() the usual way in subdirmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32497
diff changeset
   665
        # Some information is lost in the superclass's constructor, so we
2e80a691e575 match: override matchfn() the usual way in subdirmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32497
diff changeset
   666
        # can not accurately create the matching function for the subdirectory
2e80a691e575 match: override matchfn() the usual way in subdirmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32497
diff changeset
   667
        # from the inputs. Instead, we override matchfn() and visitdir() to
2e80a691e575 match: override matchfn() the usual way in subdirmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32497
diff changeset
   668
        # call the original matcher with the subdirectory path prepended.
2e80a691e575 match: override matchfn() the usual way in subdirmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32497
diff changeset
   669
        return self._matcher.matchfn(self._path + "/" + f)
2e80a691e575 match: override matchfn() the usual way in subdirmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32497
diff changeset
   670
32363
0aa4032a97e1 match: override visitdir() the usual way in subdirmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32362
diff changeset
   671
    def visitdir(self, dir):
0aa4032a97e1 match: override visitdir() the usual way in subdirmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32362
diff changeset
   672
        if dir == '.':
0aa4032a97e1 match: override visitdir() the usual way in subdirmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32362
diff changeset
   673
            dir = self._path
0aa4032a97e1 match: override visitdir() the usual way in subdirmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32362
diff changeset
   674
        else:
0aa4032a97e1 match: override visitdir() the usual way in subdirmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32362
diff changeset
   675
            dir = self._path + "/" + dir
0aa4032a97e1 match: override visitdir() the usual way in subdirmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32362
diff changeset
   676
        return self._matcher.visitdir(dir)
0aa4032a97e1 match: override visitdir() the usual way in subdirmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32362
diff changeset
   677
32494
f9445b528687 match: make subdirmatcher extend basematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32493
diff changeset
   678
    def always(self):
f9445b528687 match: make subdirmatcher extend basematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32493
diff changeset
   679
        return self._always
f9445b528687 match: make subdirmatcher extend basematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32493
diff changeset
   680
33379
7ddb2aa2b7af match: express anypats(), not prefix(), in terms of the others
Martin von Zweigbergk <martinvonz@google.com>
parents: 33378
diff changeset
   681
    def prefix(self):
7ddb2aa2b7af match: express anypats(), not prefix(), in terms of the others
Martin von Zweigbergk <martinvonz@google.com>
parents: 33378
diff changeset
   682
        return self._matcher.prefix() and not self._always
32494
f9445b528687 match: make subdirmatcher extend basematcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32493
diff changeset
   683
36088
c4fa47f880d3 py3: make sure we return str from __repr__
Pulkit Goyal <7895pulkit@gmail.com>
parents: 35659
diff changeset
   684
    @encoding.strmethod
32585
e7aa11f3abcd match: add __repr__ for subdirmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32576
diff changeset
   685
    def __repr__(self):
e7aa11f3abcd match: add __repr__ for subdirmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32576
diff changeset
   686
        return ('<subdirmatcher path=%r, matcher=%r>' %
e7aa11f3abcd match: add __repr__ for subdirmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32576
diff changeset
   687
                (self._path, self._matcher))
e7aa11f3abcd match: add __repr__ for subdirmatcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 32576
diff changeset
   688
33319
3c84591e7321 match: move matchers from sparse into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33306
diff changeset
   689
class unionmatcher(basematcher):
33448
04be8aec44a8 match: make unionmatcher a proper matcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 33447
diff changeset
   690
    """A matcher that is the union of several matchers.
04be8aec44a8 match: make unionmatcher a proper matcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 33447
diff changeset
   691
04be8aec44a8 match: make unionmatcher a proper matcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 33447
diff changeset
   692
    The non-matching-attributes (root, cwd, bad, explicitdir, traversedir) are
04be8aec44a8 match: make unionmatcher a proper matcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 33447
diff changeset
   693
    taken from the first matcher.
04be8aec44a8 match: make unionmatcher a proper matcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 33447
diff changeset
   694
    """
04be8aec44a8 match: make unionmatcher a proper matcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 33447
diff changeset
   695
33319
3c84591e7321 match: move matchers from sparse into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33306
diff changeset
   696
    def __init__(self, matchers):
33448
04be8aec44a8 match: make unionmatcher a proper matcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 33447
diff changeset
   697
        m1 = matchers[0]
04be8aec44a8 match: make unionmatcher a proper matcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 33447
diff changeset
   698
        super(unionmatcher, self).__init__(m1._root, m1._cwd)
04be8aec44a8 match: make unionmatcher a proper matcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 33447
diff changeset
   699
        self.explicitdir = m1.explicitdir
04be8aec44a8 match: make unionmatcher a proper matcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 33447
diff changeset
   700
        self.traversedir = m1.traversedir
33319
3c84591e7321 match: move matchers from sparse into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33306
diff changeset
   701
        self._matchers = matchers
3c84591e7321 match: move matchers from sparse into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33306
diff changeset
   702
33380
892d255ec2a1 match: override matchfn instead of __call__ for consistency
Martin von Zweigbergk <martinvonz@google.com>
parents: 33379
diff changeset
   703
    def matchfn(self, f):
33319
3c84591e7321 match: move matchers from sparse into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33306
diff changeset
   704
        for match in self._matchers:
33380
892d255ec2a1 match: override matchfn instead of __call__ for consistency
Martin von Zweigbergk <martinvonz@google.com>
parents: 33379
diff changeset
   705
            if match(f):
33319
3c84591e7321 match: move matchers from sparse into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33306
diff changeset
   706
                return True
3c84591e7321 match: move matchers from sparse into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33306
diff changeset
   707
        return False
3c84591e7321 match: move matchers from sparse into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33306
diff changeset
   708
33448
04be8aec44a8 match: make unionmatcher a proper matcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 33447
diff changeset
   709
    def visitdir(self, dir):
04be8aec44a8 match: make unionmatcher a proper matcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 33447
diff changeset
   710
        r = False
04be8aec44a8 match: make unionmatcher a proper matcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 33447
diff changeset
   711
        for m in self._matchers:
04be8aec44a8 match: make unionmatcher a proper matcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 33447
diff changeset
   712
            v = m.visitdir(dir)
04be8aec44a8 match: make unionmatcher a proper matcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 33447
diff changeset
   713
            if v == 'all':
04be8aec44a8 match: make unionmatcher a proper matcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 33447
diff changeset
   714
                return v
04be8aec44a8 match: make unionmatcher a proper matcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 33447
diff changeset
   715
            r |= v
04be8aec44a8 match: make unionmatcher a proper matcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 33447
diff changeset
   716
        return r
04be8aec44a8 match: make unionmatcher a proper matcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 33447
diff changeset
   717
36088
c4fa47f880d3 py3: make sure we return str from __repr__
Pulkit Goyal <7895pulkit@gmail.com>
parents: 35659
diff changeset
   718
    @encoding.strmethod
33319
3c84591e7321 match: move matchers from sparse into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33306
diff changeset
   719
    def __repr__(self):
3c84591e7321 match: move matchers from sparse into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33306
diff changeset
   720
        return ('<unionmatcher matchers=%r>' % self._matchers)
3c84591e7321 match: move matchers from sparse into core
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33306
diff changeset
   721
21111
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
   722
def patkind(pattern, default=None):
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
   723
    '''If pattern is 'kind:pat' with a known kind, return kind.'''
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
   724
    return _patsplit(pattern, default)[0]
8570
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
   725
21111
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
   726
def _patsplit(pattern, default):
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
   727
    """Split a string into the optional pattern kind prefix and the actual
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
   728
    pattern."""
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
   729
    if ':' in pattern:
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
   730
        kind, pat = pattern.split(':', 1)
33710
2be0bf186950 match: expose some data and functionality to other modules
Kostia Balytskyi <ikostia@fb.com>
parents: 33582
diff changeset
   731
        if kind in allpatternkinds:
21111
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
   732
            return kind, pat
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
   733
    return default, pattern
8570
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
   734
8582
a4c199e12b5a match: remove head and tail args from _globre
Matt Mackall <mpm@selenic.com>
parents: 8581
diff changeset
   735
def _globre(pat):
21112
03782d2fc776 match: _globre doctests
Mads Kiilerich <madski@unity3d.com>
parents: 21111
diff changeset
   736
    r'''Convert an extended glob string to a regexp string.
03782d2fc776 match: _globre doctests
Mads Kiilerich <madski@unity3d.com>
parents: 21111
diff changeset
   737
34152
a8994d08e4a2 doctest: use print_function and convert bytes to unicode where needed
Yuya Nishihara <yuya@tcha.org>
parents: 34146
diff changeset
   738
    >>> from . import pycompat
a8994d08e4a2 doctest: use print_function and convert bytes to unicode where needed
Yuya Nishihara <yuya@tcha.org>
parents: 34146
diff changeset
   739
    >>> def bprint(s):
a8994d08e4a2 doctest: use print_function and convert bytes to unicode where needed
Yuya Nishihara <yuya@tcha.org>
parents: 34146
diff changeset
   740
    ...     print(pycompat.sysstr(s))
a8994d08e4a2 doctest: use print_function and convert bytes to unicode where needed
Yuya Nishihara <yuya@tcha.org>
parents: 34146
diff changeset
   741
    >>> bprint(_globre(br'?'))
21112
03782d2fc776 match: _globre doctests
Mads Kiilerich <madski@unity3d.com>
parents: 21111
diff changeset
   742
    .
34152
a8994d08e4a2 doctest: use print_function and convert bytes to unicode where needed
Yuya Nishihara <yuya@tcha.org>
parents: 34146
diff changeset
   743
    >>> bprint(_globre(br'*'))
21112
03782d2fc776 match: _globre doctests
Mads Kiilerich <madski@unity3d.com>
parents: 21111
diff changeset
   744
    [^/]*
34152
a8994d08e4a2 doctest: use print_function and convert bytes to unicode where needed
Yuya Nishihara <yuya@tcha.org>
parents: 34146
diff changeset
   745
    >>> bprint(_globre(br'**'))
21112
03782d2fc776 match: _globre doctests
Mads Kiilerich <madski@unity3d.com>
parents: 21111
diff changeset
   746
    .*
34152
a8994d08e4a2 doctest: use print_function and convert bytes to unicode where needed
Yuya Nishihara <yuya@tcha.org>
parents: 34146
diff changeset
   747
    >>> bprint(_globre(br'**/a'))
21815
a4b67bf1f0a5 match: make glob '**/' match the empty string
Siddharth Agarwal <sid0@fb.com>
parents: 21191
diff changeset
   748
    (?:.*/)?a
34152
a8994d08e4a2 doctest: use print_function and convert bytes to unicode where needed
Yuya Nishihara <yuya@tcha.org>
parents: 34146
diff changeset
   749
    >>> bprint(_globre(br'a/**/b'))
38479
67dc32d4e790 cleanup: migrate from re.escape to stringutil.reescape
Augie Fackler <augie@google.com>
parents: 38061
diff changeset
   750
    a/(?:.*/)?b
34152
a8994d08e4a2 doctest: use print_function and convert bytes to unicode where needed
Yuya Nishihara <yuya@tcha.org>
parents: 34146
diff changeset
   751
    >>> bprint(_globre(br'[a*?!^][^b][!c]'))
21112
03782d2fc776 match: _globre doctests
Mads Kiilerich <madski@unity3d.com>
parents: 21111
diff changeset
   752
    [a*?!^][\^b][^c]
34152
a8994d08e4a2 doctest: use print_function and convert bytes to unicode where needed
Yuya Nishihara <yuya@tcha.org>
parents: 34146
diff changeset
   753
    >>> bprint(_globre(br'{a,b}'))
21112
03782d2fc776 match: _globre doctests
Mads Kiilerich <madski@unity3d.com>
parents: 21111
diff changeset
   754
    (?:a|b)
34152
a8994d08e4a2 doctest: use print_function and convert bytes to unicode where needed
Yuya Nishihara <yuya@tcha.org>
parents: 34146
diff changeset
   755
    >>> bprint(_globre(br'.\*\?'))
21112
03782d2fc776 match: _globre doctests
Mads Kiilerich <madski@unity3d.com>
parents: 21111
diff changeset
   756
    \.\*\?
03782d2fc776 match: _globre doctests
Mads Kiilerich <madski@unity3d.com>
parents: 21111
diff changeset
   757
    '''
8570
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
   758
    i, n = 0, len(pat)
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
   759
    res = ''
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
   760
    group = 0
38479
67dc32d4e790 cleanup: migrate from re.escape to stringutil.reescape
Augie Fackler <augie@google.com>
parents: 38061
diff changeset
   761
    escape = util.stringutil.reescape
10282
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10263
diff changeset
   762
    def peek():
31430
5c9cda37d7f6 match: slice over bytes to get the byteschr instead of ascii value
Pulkit Goyal <7895pulkit@gmail.com>
parents: 31429
diff changeset
   763
        return i < n and pat[i:i + 1]
8570
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
   764
    while i < n:
31430
5c9cda37d7f6 match: slice over bytes to get the byteschr instead of ascii value
Pulkit Goyal <7895pulkit@gmail.com>
parents: 31429
diff changeset
   765
        c = pat[i:i + 1]
10282
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10263
diff changeset
   766
        i += 1
8583
19d1b2aec562 match: optimize escaping in _globre
Matt Mackall <mpm@selenic.com>
parents: 8582
diff changeset
   767
        if c not in '*?[{},\\':
19d1b2aec562 match: optimize escaping in _globre
Matt Mackall <mpm@selenic.com>
parents: 8582
diff changeset
   768
            res += escape(c)
19d1b2aec562 match: optimize escaping in _globre
Matt Mackall <mpm@selenic.com>
parents: 8582
diff changeset
   769
        elif c == '*':
8570
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
   770
            if peek() == '*':
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
   771
                i += 1
21815
a4b67bf1f0a5 match: make glob '**/' match the empty string
Siddharth Agarwal <sid0@fb.com>
parents: 21191
diff changeset
   772
                if peek() == '/':
a4b67bf1f0a5 match: make glob '**/' match the empty string
Siddharth Agarwal <sid0@fb.com>
parents: 21191
diff changeset
   773
                    i += 1
a4b67bf1f0a5 match: make glob '**/' match the empty string
Siddharth Agarwal <sid0@fb.com>
parents: 21191
diff changeset
   774
                    res += '(?:.*/)?'
a4b67bf1f0a5 match: make glob '**/' match the empty string
Siddharth Agarwal <sid0@fb.com>
parents: 21191
diff changeset
   775
                else:
a4b67bf1f0a5 match: make glob '**/' match the empty string
Siddharth Agarwal <sid0@fb.com>
parents: 21191
diff changeset
   776
                    res += '.*'
8570
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
   777
            else:
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
   778
                res += '[^/]*'
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
   779
        elif c == '?':
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
   780
            res += '.'
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
   781
        elif c == '[':
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
   782
            j = i
31430
5c9cda37d7f6 match: slice over bytes to get the byteschr instead of ascii value
Pulkit Goyal <7895pulkit@gmail.com>
parents: 31429
diff changeset
   783
            if j < n and pat[j:j + 1] in '!]':
8570
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
   784
                j += 1
31430
5c9cda37d7f6 match: slice over bytes to get the byteschr instead of ascii value
Pulkit Goyal <7895pulkit@gmail.com>
parents: 31429
diff changeset
   785
            while j < n and pat[j:j + 1] != ']':
8570
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
   786
                j += 1
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
   787
            if j >= n:
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
   788
                res += '\\['
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
   789
            else:
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
   790
                stuff = pat[i:j].replace('\\','\\\\')
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
   791
                i = j + 1
31430
5c9cda37d7f6 match: slice over bytes to get the byteschr instead of ascii value
Pulkit Goyal <7895pulkit@gmail.com>
parents: 31429
diff changeset
   792
                if stuff[0:1] == '!':
8570
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
   793
                    stuff = '^' + stuff[1:]
31430
5c9cda37d7f6 match: slice over bytes to get the byteschr instead of ascii value
Pulkit Goyal <7895pulkit@gmail.com>
parents: 31429
diff changeset
   794
                elif stuff[0:1] == '^':
8570
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
   795
                    stuff = '\\' + stuff
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
   796
                res = '%s[%s]' % (res, stuff)
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
   797
        elif c == '{':
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
   798
            group += 1
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
   799
            res += '(?:'
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
   800
        elif c == '}' and group:
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
   801
            res += ')'
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
   802
            group -= 1
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
   803
        elif c == ',' and group:
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
   804
            res += '|'
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
   805
        elif c == '\\':
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
   806
            p = peek()
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
   807
            if p:
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
   808
                i += 1
8583
19d1b2aec562 match: optimize escaping in _globre
Matt Mackall <mpm@selenic.com>
parents: 8582
diff changeset
   809
                res += escape(p)
8570
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
   810
            else:
8583
19d1b2aec562 match: optimize escaping in _globre
Matt Mackall <mpm@selenic.com>
parents: 8582
diff changeset
   811
                res += escape(c)
8570
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
   812
        else:
8583
19d1b2aec562 match: optimize escaping in _globre
Matt Mackall <mpm@selenic.com>
parents: 8582
diff changeset
   813
            res += escape(c)
8582
a4c199e12b5a match: remove head and tail args from _globre
Matt Mackall <mpm@selenic.com>
parents: 8581
diff changeset
   814
    return res
8570
7fe2012b3bd0 match: move util match functions over
Matt Mackall <mpm@selenic.com>
parents: 8568
diff changeset
   815
21111
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
   816
def _regex(kind, pat, globsuffix):
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
   817
    '''Convert a (normalized) pattern of any kind into a regular expression.
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
   818
    globsuffix is appended to the regexp of globs.'''
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
   819
    if not pat:
8574
63a7ed2128d5 match: unnest functions in _matcher
Matt Mackall <mpm@selenic.com>
parents: 8573
diff changeset
   820
        return ''
63a7ed2128d5 match: unnest functions in _matcher
Matt Mackall <mpm@selenic.com>
parents: 8573
diff changeset
   821
    if kind == 're':
21111
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
   822
        return pat
33358
38b6122df5c7 match: combine regex code for path: and relpath:
Martin von Zweigbergk <martinvonz@google.com>
parents: 33357
diff changeset
   823
    if kind in ('path', 'relpath'):
25636
bfe9ed85f27c match: let 'path:.' and 'path:' match everything (issue4687)
Matt Harbison <matt_harbison@yahoo.com>
parents: 25194
diff changeset
   824
        if pat == '.':
bfe9ed85f27c match: let 'path:.' and 'path:' match everything (issue4687)
Matt Harbison <matt_harbison@yahoo.com>
parents: 25194
diff changeset
   825
            return ''
38479
67dc32d4e790 cleanup: migrate from re.escape to stringutil.reescape
Augie Fackler <augie@google.com>
parents: 38061
diff changeset
   826
        return util.stringutil.reescape(pat) + '(?:/|$)'
31032
88358446da16 match: adding support for matching files inside a directory
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 30409
diff changeset
   827
    if kind == 'rootfilesin':
88358446da16 match: adding support for matching files inside a directory
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 30409
diff changeset
   828
        if pat == '.':
88358446da16 match: adding support for matching files inside a directory
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 30409
diff changeset
   829
            escaped = ''
88358446da16 match: adding support for matching files inside a directory
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 30409
diff changeset
   830
        else:
88358446da16 match: adding support for matching files inside a directory
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 30409
diff changeset
   831
            # Pattern is a directory name.
38479
67dc32d4e790 cleanup: migrate from re.escape to stringutil.reescape
Augie Fackler <augie@google.com>
parents: 38061
diff changeset
   832
            escaped = util.stringutil.reescape(pat) + '/'
31032
88358446da16 match: adding support for matching files inside a directory
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 30409
diff changeset
   833
        # Anything after the pattern must be a non-directory.
33357
a21819f439fe match: remove unnecessary '^' from regexes
Martin von Zweigbergk <martinvonz@google.com>
parents: 33319
diff changeset
   834
        return escaped + '[^/]+$'
21111
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
   835
    if kind == 'relglob':
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
   836
        return '(?:|.*/)' + _globre(pat) + globsuffix
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
   837
    if kind == 'relre':
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
   838
        if pat.startswith('^'):
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
   839
            return pat
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
   840
        return '.*' + pat
38579
2d487b9cac07 match: explode if unsupported pattern passed down to _regex() builder
Yuya Nishihara <yuya@tcha.org>
parents: 38578
diff changeset
   841
    if kind == 'glob':
2d487b9cac07 match: explode if unsupported pattern passed down to _regex() builder
Yuya Nishihara <yuya@tcha.org>
parents: 38578
diff changeset
   842
        return _globre(pat) + globsuffix
2d487b9cac07 match: explode if unsupported pattern passed down to _regex() builder
Yuya Nishihara <yuya@tcha.org>
parents: 38578
diff changeset
   843
    raise error.ProgrammingError('not a regex pattern: %s:%s' % (kind, pat))
8574
63a7ed2128d5 match: unnest functions in _matcher
Matt Mackall <mpm@selenic.com>
parents: 8573
diff changeset
   844
25238
5a55ad6e8e24 match: add root to _buildmatch
Durham Goode <durham@fb.com>
parents: 25233
diff changeset
   845
def _buildmatch(ctx, kindpats, globsuffix, listsubrepos, root):
21111
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
   846
    '''Return regexp string and a matcher function for kindpats.
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
   847
    globsuffix is appended to the regexp of globs.'''
25239
714f612f2afc match: allow unioning arbitrary match functions
Durham Goode <durham@fb.com>
parents: 25238
diff changeset
   848
    matchfuncs = []
714f612f2afc match: allow unioning arbitrary match functions
Durham Goode <durham@fb.com>
parents: 25238
diff changeset
   849
25283
19d0e5efa6ca match: enable 'subinclude:' syntax
Durham Goode <durham@fb.com>
parents: 25250
diff changeset
   850
    subincludes, kindpats = _expandsubinclude(kindpats, root)
19d0e5efa6ca match: enable 'subinclude:' syntax
Durham Goode <durham@fb.com>
parents: 25250
diff changeset
   851
    if subincludes:
32185
6dea1701f170 match: make subinclude construction lazy
Durham Goode <durham@fb.com>
parents: 31442
diff changeset
   852
        submatchers = {}
25283
19d0e5efa6ca match: enable 'subinclude:' syntax
Durham Goode <durham@fb.com>
parents: 25250
diff changeset
   853
        def matchsubinclude(f):
32185
6dea1701f170 match: make subinclude construction lazy
Durham Goode <durham@fb.com>
parents: 31442
diff changeset
   854
            for prefix, matcherargs in subincludes:
6dea1701f170 match: make subinclude construction lazy
Durham Goode <durham@fb.com>
parents: 31442
diff changeset
   855
                if f.startswith(prefix):
6dea1701f170 match: make subinclude construction lazy
Durham Goode <durham@fb.com>
parents: 31442
diff changeset
   856
                    mf = submatchers.get(prefix)
6dea1701f170 match: make subinclude construction lazy
Durham Goode <durham@fb.com>
parents: 31442
diff changeset
   857
                    if mf is None:
6dea1701f170 match: make subinclude construction lazy
Durham Goode <durham@fb.com>
parents: 31442
diff changeset
   858
                        mf = match(*matcherargs)
6dea1701f170 match: make subinclude construction lazy
Durham Goode <durham@fb.com>
parents: 31442
diff changeset
   859
                        submatchers[prefix] = mf
6dea1701f170 match: make subinclude construction lazy
Durham Goode <durham@fb.com>
parents: 31442
diff changeset
   860
6dea1701f170 match: make subinclude construction lazy
Durham Goode <durham@fb.com>
parents: 31442
diff changeset
   861
                    if mf(f[len(prefix):]):
6dea1701f170 match: make subinclude construction lazy
Durham Goode <durham@fb.com>
parents: 31442
diff changeset
   862
                        return True
25283
19d0e5efa6ca match: enable 'subinclude:' syntax
Durham Goode <durham@fb.com>
parents: 25250
diff changeset
   863
            return False
19d0e5efa6ca match: enable 'subinclude:' syntax
Durham Goode <durham@fb.com>
parents: 25250
diff changeset
   864
        matchfuncs.append(matchsubinclude)
14675
cfc89398f710 match: introduce basic fileset support
Matt Mackall <mpm@selenic.com>
parents: 14674
diff changeset
   865
25239
714f612f2afc match: allow unioning arbitrary match functions
Durham Goode <durham@fb.com>
parents: 25238
diff changeset
   866
    regex = ''
714f612f2afc match: allow unioning arbitrary match functions
Durham Goode <durham@fb.com>
parents: 25238
diff changeset
   867
    if kindpats:
714f612f2afc match: allow unioning arbitrary match functions
Durham Goode <durham@fb.com>
parents: 25238
diff changeset
   868
        regex, mf = _buildregexmatch(kindpats, globsuffix)
714f612f2afc match: allow unioning arbitrary match functions
Durham Goode <durham@fb.com>
parents: 25238
diff changeset
   869
        matchfuncs.append(mf)
714f612f2afc match: allow unioning arbitrary match functions
Durham Goode <durham@fb.com>
parents: 25238
diff changeset
   870
714f612f2afc match: allow unioning arbitrary match functions
Durham Goode <durham@fb.com>
parents: 25238
diff changeset
   871
    if len(matchfuncs) == 1:
714f612f2afc match: allow unioning arbitrary match functions
Durham Goode <durham@fb.com>
parents: 25238
diff changeset
   872
        return regex, matchfuncs[0]
714f612f2afc match: allow unioning arbitrary match functions
Durham Goode <durham@fb.com>
parents: 25238
diff changeset
   873
    else:
714f612f2afc match: allow unioning arbitrary match functions
Durham Goode <durham@fb.com>
parents: 25238
diff changeset
   874
        return regex, lambda f: any(mf(f) for mf in matchfuncs)
14675
cfc89398f710 match: introduce basic fileset support
Matt Mackall <mpm@selenic.com>
parents: 14674
diff changeset
   875
21111
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
   876
def _buildregexmatch(kindpats, globsuffix):
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
   877
    """Build a match function from a list of kinds and kindpats,
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
   878
    return regexp string and a matcher function."""
8574
63a7ed2128d5 match: unnest functions in _matcher
Matt Mackall <mpm@selenic.com>
parents: 8573
diff changeset
   879
    try:
21111
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
   880
        regex = '(?:%s)' % '|'.join([_regex(k, p, globsuffix)
25213
08a8e9da0ae7 match: add source to kindpats list
Durham Goode <durham@fb.com>
parents: 25195
diff changeset
   881
                                     for (k, p, s) in kindpats])
21111
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
   882
        if len(regex) > 20000:
16687
e34106fa0dc3 cleanup: "raise SomeException()" -> "raise SomeException"
Brodie Rao <brodie@sf.io>
parents: 16645
diff changeset
   883
            raise OverflowError
21111
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
   884
        return regex, _rematcher(regex)
8574
63a7ed2128d5 match: unnest functions in _matcher
Matt Mackall <mpm@selenic.com>
parents: 8573
diff changeset
   885
    except OverflowError:
63a7ed2128d5 match: unnest functions in _matcher
Matt Mackall <mpm@selenic.com>
parents: 8573
diff changeset
   886
        # We're using a Python with a tiny regex engine and we
63a7ed2128d5 match: unnest functions in _matcher
Matt Mackall <mpm@selenic.com>
parents: 8573
diff changeset
   887
        # made it explode, so we'll divide the pattern list in two
63a7ed2128d5 match: unnest functions in _matcher
Matt Mackall <mpm@selenic.com>
parents: 8573
diff changeset
   888
        # until it works
21111
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
   889
        l = len(kindpats)
8574
63a7ed2128d5 match: unnest functions in _matcher
Matt Mackall <mpm@selenic.com>
parents: 8573
diff changeset
   890
        if l < 2:
63a7ed2128d5 match: unnest functions in _matcher
Matt Mackall <mpm@selenic.com>
parents: 8573
diff changeset
   891
            raise
21111
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
   892
        regexa, a = _buildregexmatch(kindpats[:l//2], globsuffix)
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
   893
        regexb, b = _buildregexmatch(kindpats[l//2:], globsuffix)
21191
a2f4ea82d6d3 match: fix NameError 'pat' on overflow of regex pattern length
Yuya Nishihara <yuya@tcha.org>
parents: 21113
diff changeset
   894
        return regex, lambda s: a(s) or b(s)
8574
63a7ed2128d5 match: unnest functions in _matcher
Matt Mackall <mpm@selenic.com>
parents: 8573
diff changeset
   895
    except re.error:
25213
08a8e9da0ae7 match: add source to kindpats list
Durham Goode <durham@fb.com>
parents: 25195
diff changeset
   896
        for k, p, s in kindpats:
8574
63a7ed2128d5 match: unnest functions in _matcher
Matt Mackall <mpm@selenic.com>
parents: 8573
diff changeset
   897
            try:
21111
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
   898
                _rematcher('(?:%s)' % _regex(k, p, globsuffix))
8574
63a7ed2128d5 match: unnest functions in _matcher
Matt Mackall <mpm@selenic.com>
parents: 8573
diff changeset
   899
            except re.error:
25213
08a8e9da0ae7 match: add source to kindpats list
Durham Goode <durham@fb.com>
parents: 25195
diff changeset
   900
                if s:
26587
56b2bcea2529 error: get Abort from 'error' instead of 'util'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26014
diff changeset
   901
                    raise error.Abort(_("%s: invalid pattern (%s): %s") %
25213
08a8e9da0ae7 match: add source to kindpats list
Durham Goode <durham@fb.com>
parents: 25195
diff changeset
   902
                                     (s, k, p))
08a8e9da0ae7 match: add source to kindpats list
Durham Goode <durham@fb.com>
parents: 25195
diff changeset
   903
                else:
26587
56b2bcea2529 error: get Abort from 'error' instead of 'util'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26014
diff changeset
   904
                    raise error.Abort(_("invalid pattern (%s): %s") % (k, p))
56b2bcea2529 error: get Abort from 'error' instead of 'util'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26014
diff changeset
   905
        raise error.Abort(_("invalid pattern"))
8574
63a7ed2128d5 match: unnest functions in _matcher
Matt Mackall <mpm@selenic.com>
parents: 8573
diff changeset
   906
31033
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31032
diff changeset
   907
def _patternrootsanddirs(kindpats):
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31032
diff changeset
   908
    '''Returns roots and directories corresponding to each pattern.
21079
b02ab6486a78 match: make it more clear what _roots do and that it ends up in match()._files
Mads Kiilerich <madski@unity3d.com>
parents: 20401
diff changeset
   909
31033
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31032
diff changeset
   910
    This calculates the roots and directories exactly matching the patterns and
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31032
diff changeset
   911
    returns a tuple of (roots, dirs) for each. It does not return other
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31032
diff changeset
   912
    directories which may also need to be considered, like the parent
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31032
diff changeset
   913
    directories.
21079
b02ab6486a78 match: make it more clear what _roots do and that it ends up in match()._files
Mads Kiilerich <madski@unity3d.com>
parents: 20401
diff changeset
   914
    '''
8576
ec4ed21db4b2 match: split up _normalizepats
Matt Mackall <mpm@selenic.com>
parents: 8575
diff changeset
   915
    r = []
31033
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31032
diff changeset
   916
    d = []
25213
08a8e9da0ae7 match: add source to kindpats list
Durham Goode <durham@fb.com>
parents: 25195
diff changeset
   917
    for kind, pat, source in kindpats:
8584
0f06e72abfdc match: fold _globprefix into _roots
Matt Mackall <mpm@selenic.com>
parents: 8583
diff changeset
   918
        if kind == 'glob': # find the non-glob prefix
0f06e72abfdc match: fold _globprefix into _roots
Matt Mackall <mpm@selenic.com>
parents: 8583
diff changeset
   919
            root = []
21111
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
   920
            for p in pat.split('/'):
8584
0f06e72abfdc match: fold _globprefix into _roots
Matt Mackall <mpm@selenic.com>
parents: 8583
diff changeset
   921
                if '[' in p or '{' in p or '*' in p or '?' in p:
0f06e72abfdc match: fold _globprefix into _roots
Matt Mackall <mpm@selenic.com>
parents: 8583
diff changeset
   922
                    break
0f06e72abfdc match: fold _globprefix into _roots
Matt Mackall <mpm@selenic.com>
parents: 8583
diff changeset
   923
                root.append(p)
0f06e72abfdc match: fold _globprefix into _roots
Matt Mackall <mpm@selenic.com>
parents: 8583
diff changeset
   924
            r.append('/'.join(root) or '.')
31033
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31032
diff changeset
   925
        elif kind in ('relpath', 'path'):
21111
9d28fd795215 match: improve documentation - docstrings and more descriptive variable naming
Mads Kiilerich <madski@unity3d.com>
parents: 21079
diff changeset
   926
            r.append(pat or '.')
31033
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31032
diff changeset
   927
        elif kind in ('rootfilesin',):
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31032
diff changeset
   928
            d.append(pat or '.')
19107
fcf08023c011 match: fix root calculation for combining regexps with simple paths
Mads Kiilerich <madski@unity3d.com>
parents: 18713
diff changeset
   929
        else: # relglob, re, relre
8576
ec4ed21db4b2 match: split up _normalizepats
Matt Mackall <mpm@selenic.com>
parents: 8575
diff changeset
   930
            r.append('.')
31033
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31032
diff changeset
   931
    return r, d
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31032
diff changeset
   932
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31032
diff changeset
   933
def _roots(kindpats):
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31032
diff changeset
   934
    '''Returns root directories to match recursively from the given patterns.'''
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31032
diff changeset
   935
    roots, dirs = _patternrootsanddirs(kindpats)
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31032
diff changeset
   936
    return roots
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31032
diff changeset
   937
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31032
diff changeset
   938
def _rootsanddirs(kindpats):
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31032
diff changeset
   939
    '''Returns roots and exact directories from patterns.
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31032
diff changeset
   940
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31032
diff changeset
   941
    roots are directories to match recursively, whereas exact directories should
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31032
diff changeset
   942
    be matched non-recursively. The returned (roots, dirs) tuple will also
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31032
diff changeset
   943
    include directories that need to be implicitly considered as either, such as
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31032
diff changeset
   944
    parent directories.
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31032
diff changeset
   945
34146
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 33710
diff changeset
   946
    >>> _rootsanddirs(
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 33710
diff changeset
   947
    ...     [(b'glob', b'g/h/*', b''), (b'glob', b'g/h', b''),
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 33710
diff changeset
   948
    ...      (b'glob', b'g*', b'')])
32225
cf042543afa2 match: optimize visitdir() for patterns matching only root directory
Martin von Zweigbergk <martinvonz@google.com>
parents: 32185
diff changeset
   949
    (['g/h', 'g/h', '.'], ['g', '.'])
34146
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 33710
diff changeset
   950
    >>> _rootsanddirs(
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 33710
diff changeset
   951
    ...     [(b'rootfilesin', b'g/h', b''), (b'rootfilesin', b'', b'')])
32225
cf042543afa2 match: optimize visitdir() for patterns matching only root directory
Martin von Zweigbergk <martinvonz@google.com>
parents: 32185
diff changeset
   952
    ([], ['g/h', '.', 'g', '.'])
34146
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 33710
diff changeset
   953
    >>> _rootsanddirs(
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 33710
diff changeset
   954
    ...     [(b'relpath', b'r', b''), (b'path', b'p/p', b''),
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 33710
diff changeset
   955
    ...      (b'path', b'', b'')])
32225
cf042543afa2 match: optimize visitdir() for patterns matching only root directory
Martin von Zweigbergk <martinvonz@google.com>
parents: 32185
diff changeset
   956
    (['r', 'p/p', '.'], ['p', '.'])
34146
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 33710
diff changeset
   957
    >>> _rootsanddirs(
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 33710
diff changeset
   958
    ...     [(b'relglob', b'rg*', b''), (b're', b're/', b''),
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 33710
diff changeset
   959
    ...      (b'relre', b'rr', b'')])
32225
cf042543afa2 match: optimize visitdir() for patterns matching only root directory
Martin von Zweigbergk <martinvonz@google.com>
parents: 32185
diff changeset
   960
    (['.', '.', '.'], ['.'])
31033
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31032
diff changeset
   961
    '''
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31032
diff changeset
   962
    r, d = _patternrootsanddirs(kindpats)
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31032
diff changeset
   963
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31032
diff changeset
   964
    # Append the parents as non-recursive/exact directories, since they must be
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31032
diff changeset
   965
    # scanned to get to either the roots or the other exact directories.
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31032
diff changeset
   966
    d.extend(util.dirs(d))
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31032
diff changeset
   967
    d.extend(util.dirs(r))
32225
cf042543afa2 match: optimize visitdir() for patterns matching only root directory
Martin von Zweigbergk <martinvonz@google.com>
parents: 32185
diff changeset
   968
    # util.dirs() does not include the root directory, so add it manually
cf042543afa2 match: optimize visitdir() for patterns matching only root directory
Martin von Zweigbergk <martinvonz@google.com>
parents: 32185
diff changeset
   969
    d.append('.')
31033
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31032
diff changeset
   970
693a5bb47854 match: making visitdir() deal with non-recursive entries
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 31032
diff changeset
   971
    return r, d
8576
ec4ed21db4b2 match: split up _normalizepats
Matt Mackall <mpm@selenic.com>
parents: 8575
diff changeset
   972
31032
88358446da16 match: adding support for matching files inside a directory
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 30409
diff changeset
   973
def _explicitfiles(kindpats):
88358446da16 match: adding support for matching files inside a directory
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 30409
diff changeset
   974
    '''Returns the potential explicit filenames from the patterns.
88358446da16 match: adding support for matching files inside a directory
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 30409
diff changeset
   975
34146
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 33710
diff changeset
   976
    >>> _explicitfiles([(b'path', b'foo/bar', b'')])
31032
88358446da16 match: adding support for matching files inside a directory
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 30409
diff changeset
   977
    ['foo/bar']
34146
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 33710
diff changeset
   978
    >>> _explicitfiles([(b'rootfilesin', b'foo/bar', b'')])
31032
88358446da16 match: adding support for matching files inside a directory
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 30409
diff changeset
   979
    []
88358446da16 match: adding support for matching files inside a directory
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 30409
diff changeset
   980
    '''
88358446da16 match: adding support for matching files inside a directory
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 30409
diff changeset
   981
    # Keep only the pattern kinds where one can specify filenames (vs only
88358446da16 match: adding support for matching files inside a directory
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 30409
diff changeset
   982
    # directory names).
88358446da16 match: adding support for matching files inside a directory
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 30409
diff changeset
   983
    filable = [kp for kp in kindpats if kp[0] not in ('rootfilesin',)]
88358446da16 match: adding support for matching files inside a directory
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 30409
diff changeset
   984
    return _roots(filable)
88358446da16 match: adding support for matching files inside a directory
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents: 30409
diff changeset
   985
33405
6aa643762641 match: inverse _anypats(), making it _prefix()
Martin von Zweigbergk <martinvonz@google.com>
parents: 33380
diff changeset
   986
def _prefix(kindpats):
6aa643762641 match: inverse _anypats(), making it _prefix()
Martin von Zweigbergk <martinvonz@google.com>
parents: 33380
diff changeset
   987
    '''Whether all the patterns match a prefix (i.e. recursively)'''
25213
08a8e9da0ae7 match: add source to kindpats list
Durham Goode <durham@fb.com>
parents: 25195
diff changeset
   988
    for kind, pat, source in kindpats:
33405
6aa643762641 match: inverse _anypats(), making it _prefix()
Martin von Zweigbergk <martinvonz@google.com>
parents: 33380
diff changeset
   989
        if kind not in ('path', 'relpath'):
6aa643762641 match: inverse _anypats(), making it _prefix()
Martin von Zweigbergk <martinvonz@google.com>
parents: 33380
diff changeset
   990
            return False
6aa643762641 match: inverse _anypats(), making it _prefix()
Martin von Zweigbergk <martinvonz@google.com>
parents: 33380
diff changeset
   991
    return True
25167
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
   992
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
   993
_commentre = None
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
   994
27595
9e2d01707e71 match: add option to return line and lineno from readpattern
Laurent Charignon <lcharignon@fb.com>
parents: 27343
diff changeset
   995
def readpatternfile(filepath, warn, sourceinfo=False):
25167
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
   996
    '''parse a pattern file, returning a list of
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
   997
    patterns. These patterns should be given to compile()
25216
dc562165044a ignore: use 'include:' rules instead of custom syntax
Durham Goode <durham@fb.com>
parents: 25215
diff changeset
   998
    to be validated and converted into a match function.
dc562165044a ignore: use 'include:' rules instead of custom syntax
Durham Goode <durham@fb.com>
parents: 25215
diff changeset
   999
dc562165044a ignore: use 'include:' rules instead of custom syntax
Durham Goode <durham@fb.com>
parents: 25215
diff changeset
  1000
    trailing white space is dropped.
dc562165044a ignore: use 'include:' rules instead of custom syntax
Durham Goode <durham@fb.com>
parents: 25215
diff changeset
  1001
    the escape character is backslash.
dc562165044a ignore: use 'include:' rules instead of custom syntax
Durham Goode <durham@fb.com>
parents: 25215
diff changeset
  1002
    comments start with #.
dc562165044a ignore: use 'include:' rules instead of custom syntax
Durham Goode <durham@fb.com>
parents: 25215
diff changeset
  1003
    empty lines are skipped.
dc562165044a ignore: use 'include:' rules instead of custom syntax
Durham Goode <durham@fb.com>
parents: 25215
diff changeset
  1004
dc562165044a ignore: use 'include:' rules instead of custom syntax
Durham Goode <durham@fb.com>
parents: 25215
diff changeset
  1005
    lines can be of the following formats:
dc562165044a ignore: use 'include:' rules instead of custom syntax
Durham Goode <durham@fb.com>
parents: 25215
diff changeset
  1006
dc562165044a ignore: use 'include:' rules instead of custom syntax
Durham Goode <durham@fb.com>
parents: 25215
diff changeset
  1007
    syntax: regexp # defaults following lines to non-rooted regexps
dc562165044a ignore: use 'include:' rules instead of custom syntax
Durham Goode <durham@fb.com>
parents: 25215
diff changeset
  1008
    syntax: glob   # defaults following lines to non-rooted globs
dc562165044a ignore: use 'include:' rules instead of custom syntax
Durham Goode <durham@fb.com>
parents: 25215
diff changeset
  1009
    re:pattern     # non-rooted regular expression
dc562165044a ignore: use 'include:' rules instead of custom syntax
Durham Goode <durham@fb.com>
parents: 25215
diff changeset
  1010
    glob:pattern   # non-rooted glob
27595
9e2d01707e71 match: add option to return line and lineno from readpattern
Laurent Charignon <lcharignon@fb.com>
parents: 27343
diff changeset
  1011
    pattern        # pattern of the current default type
9e2d01707e71 match: add option to return line and lineno from readpattern
Laurent Charignon <lcharignon@fb.com>
parents: 27343
diff changeset
  1012
9e2d01707e71 match: add option to return line and lineno from readpattern
Laurent Charignon <lcharignon@fb.com>
parents: 27343
diff changeset
  1013
    if sourceinfo is set, returns a list of tuples:
9e2d01707e71 match: add option to return line and lineno from readpattern
Laurent Charignon <lcharignon@fb.com>
parents: 27343
diff changeset
  1014
    (pattern, lineno, originalline). This is useful to debug ignore patterns.
9e2d01707e71 match: add option to return line and lineno from readpattern
Laurent Charignon <lcharignon@fb.com>
parents: 27343
diff changeset
  1015
    '''
25216
dc562165044a ignore: use 'include:' rules instead of custom syntax
Durham Goode <durham@fb.com>
parents: 25215
diff changeset
  1016
25215
4040e06e9b99 match: add 'include:' syntax
Durham Goode <durham@fb.com>
parents: 25214
diff changeset
  1017
    syntaxes = {'re': 'relre:', 'regexp': 'relre:', 'glob': 'relglob:',
25283
19d0e5efa6ca match: enable 'subinclude:' syntax
Durham Goode <durham@fb.com>
parents: 25250
diff changeset
  1018
                'include': 'include', 'subinclude': 'subinclude'}
25167
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
  1019
    syntax = 'relre:'
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
  1020
    patterns = []
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
  1021
31412
10c17f8bfcf3 py3: open file in rb mode
Rishabh Madan <rishabhmadan96@gmail.com>
parents: 31401
diff changeset
  1022
    fp = open(filepath, 'rb')
30409
7f3593c29473 match: migrate to util.iterfile
Jun Wu <quark@fb.com>
parents: 29814
diff changeset
  1023
    for lineno, line in enumerate(util.iterfile(fp), start=1):
25167
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
  1024
        if "#" in line:
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
  1025
            global _commentre
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
  1026
            if not _commentre:
31429
40704098853f match: make regular expression bytes to prevent TypeError
Pulkit Goyal <7895pulkit@gmail.com>
parents: 31412
diff changeset
  1027
                _commentre = util.re.compile(br'((?:^|[^\\])(?:\\\\)*)#.*')
25167
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
  1028
            # remove comments prefixed by an even number of escapes
27327
d500341e4f55 match: use re2 in readpatternfile if possible
Bryan O'Sullivan <bos@serpentine.com>
parents: 26781
diff changeset
  1029
            m = _commentre.search(line)
d500341e4f55 match: use re2 in readpatternfile if possible
Bryan O'Sullivan <bos@serpentine.com>
parents: 26781
diff changeset
  1030
            if m:
d500341e4f55 match: use re2 in readpatternfile if possible
Bryan O'Sullivan <bos@serpentine.com>
parents: 26781
diff changeset
  1031
                line = line[:m.end(1)]
25167
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
  1032
            # fixup properly escaped comments that survived the above
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
  1033
            line = line.replace("\\#", "#")
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
  1034
        line = line.rstrip()
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
  1035
        if not line:
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
  1036
            continue
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
  1037
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
  1038
        if line.startswith('syntax:'):
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
  1039
            s = line[7:].strip()
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
  1040
            try:
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
  1041
                syntax = syntaxes[s]
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
  1042
            except KeyError:
25214
08703b10c3ae match: add optional warn argument
Durham Goode <durham@fb.com>
parents: 25213
diff changeset
  1043
                if warn:
08703b10c3ae match: add optional warn argument
Durham Goode <durham@fb.com>
parents: 25213
diff changeset
  1044
                    warn(_("%s: ignoring invalid syntax '%s'\n") %
08703b10c3ae match: add optional warn argument
Durham Goode <durham@fb.com>
parents: 25213
diff changeset
  1045
                         (filepath, s))
25167
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
  1046
            continue
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
  1047
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
  1048
        linesyntax = syntax
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
  1049
        for s, rels in syntaxes.iteritems():
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
  1050
            if line.startswith(rels):
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
  1051
                linesyntax = rels
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
  1052
                line = line[len(rels):]
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
  1053
                break
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
  1054
            elif line.startswith(s+':'):
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
  1055
                linesyntax = rels
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
  1056
                line = line[len(s) + 1:]
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
  1057
                break
27595
9e2d01707e71 match: add option to return line and lineno from readpattern
Laurent Charignon <lcharignon@fb.com>
parents: 27343
diff changeset
  1058
        if sourceinfo:
9e2d01707e71 match: add option to return line and lineno from readpattern
Laurent Charignon <lcharignon@fb.com>
parents: 27343
diff changeset
  1059
            patterns.append((linesyntax + line, lineno, line))
9e2d01707e71 match: add option to return line and lineno from readpattern
Laurent Charignon <lcharignon@fb.com>
parents: 27343
diff changeset
  1060
        else:
9e2d01707e71 match: add option to return line and lineno from readpattern
Laurent Charignon <lcharignon@fb.com>
parents: 27343
diff changeset
  1061
            patterns.append(linesyntax + line)
25167
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
  1062
    fp.close()
6f7048cc2419 ignore: move readpatternfile to match.py
Durham Goode <durham@fb.com>
parents: 25122
diff changeset
  1063
    return patterns