mirror of
https://github.com/facebook/sapling.git
synced 2024-10-10 00:45:18 +03:00
f7185e6387
A future commit will move the readignorefile logic into match.py so it can be used from general match rules. Let's rename the function to represent this new behavior.
113 lines
3.4 KiB
Python
113 lines
3.4 KiB
Python
# ignore.py - ignored file handling for mercurial
|
|
#
|
|
# Copyright 2007 Matt Mackall <mpm@selenic.com>
|
|
#
|
|
# This software may be used and distributed according to the terms of the
|
|
# GNU General Public License version 2 or any later version.
|
|
|
|
from i18n import _
|
|
import util, match
|
|
import re
|
|
|
|
_commentre = None
|
|
|
|
def readpatternfile(filepath, warn):
|
|
'''parse a pattern file, returning a list of
|
|
patterns. These patterns should be given to compile()
|
|
to be validated and converted into a match function.'''
|
|
syntaxes = {'re': 'relre:', 'regexp': 'relre:', 'glob': 'relglob:'}
|
|
syntax = 'relre:'
|
|
patterns = []
|
|
|
|
fp = open(filepath)
|
|
for line in fp:
|
|
if "#" in line:
|
|
global _commentre
|
|
if not _commentre:
|
|
_commentre = re.compile(r'((^|[^\\])(\\\\)*)#.*')
|
|
# remove comments prefixed by an even number of escapes
|
|
line = _commentre.sub(r'\1', line)
|
|
# fixup properly escaped comments that survived the above
|
|
line = line.replace("\\#", "#")
|
|
line = line.rstrip()
|
|
if not line:
|
|
continue
|
|
|
|
if line.startswith('syntax:'):
|
|
s = line[7:].strip()
|
|
try:
|
|
syntax = syntaxes[s]
|
|
except KeyError:
|
|
warn(_("%s: ignoring invalid syntax '%s'\n") % (filepath, s))
|
|
continue
|
|
|
|
linesyntax = syntax
|
|
for s, rels in syntaxes.iteritems():
|
|
if line.startswith(rels):
|
|
linesyntax = rels
|
|
line = line[len(rels):]
|
|
break
|
|
elif line.startswith(s+':'):
|
|
linesyntax = rels
|
|
line = line[len(s) + 1:]
|
|
break
|
|
patterns.append(linesyntax + line)
|
|
|
|
fp.close()
|
|
return patterns
|
|
|
|
def readpats(root, files, warn):
|
|
'''return a dict mapping ignore-file-name to list-of-patterns'''
|
|
|
|
pats = {}
|
|
for f in files:
|
|
if f in pats:
|
|
continue
|
|
try:
|
|
pats[f] = readpatternfile(f, warn)
|
|
except IOError, inst:
|
|
warn(_("skipping unreadable ignore file '%s': %s\n") %
|
|
(f, inst.strerror))
|
|
|
|
return [(f, pats[f]) for f in files if f in pats]
|
|
|
|
def ignore(root, files, warn):
|
|
'''return matcher covering patterns in 'files'.
|
|
|
|
the files parsed for patterns include:
|
|
.hgignore in the repository root
|
|
any additional files specified in the [ui] section of ~/.hgrc
|
|
|
|
trailing white space is dropped.
|
|
the escape character is backslash.
|
|
comments start with #.
|
|
empty lines are skipped.
|
|
|
|
lines can be of the following formats:
|
|
|
|
syntax: regexp # defaults following lines to non-rooted regexps
|
|
syntax: glob # defaults following lines to non-rooted globs
|
|
re:pattern # non-rooted regular expression
|
|
glob:pattern # non-rooted glob
|
|
pattern # pattern of the current default type'''
|
|
|
|
pats = readpats(root, files, warn)
|
|
|
|
allpats = []
|
|
for f, patlist in pats:
|
|
allpats.extend(patlist)
|
|
if not allpats:
|
|
return util.never
|
|
|
|
try:
|
|
ignorefunc = match.match(root, '', [], allpats)
|
|
except util.Abort:
|
|
# Re-raise an exception where the src is the right file
|
|
for f, patlist in pats:
|
|
try:
|
|
match.match(root, '', [], patlist)
|
|
except util.Abort, inst:
|
|
raise util.Abort('%s: %s' % (f, inst[0]))
|
|
|
|
return ignorefunc
|