ignore.py
92 lines
| 3.0 KiB
| text/x-python
|
PythonLexer
/ mercurial / ignore.py
Matt Mackall
|
r4609 | # ignore.py - ignored file handling for mercurial | ||
# | ||||
# Copyright 2007 Matt Mackall <mpm@selenic.com> | ||||
# | ||||
Martin Geisler
|
r8225 | # This software may be used and distributed according to the terms of the | ||
# GNU General Public License version 2, incorporated herein by reference. | ||||
Matt Mackall
|
r4609 | |||
from i18n import _ | ||||
Matt Mackall
|
r8566 | import util, match | ||
Simon Heimberg
|
r8312 | import re | ||
Matt Mackall
|
r5640 | |||
_commentre = None | ||||
Matt Mackall
|
r4609 | |||
def _parselines(fp): | ||||
for line in fp: | ||||
Matt Mackall
|
r5640 | 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() | ||||
Matt Mackall
|
r4609 | if line: | ||
yield line | ||||
def ignore(root, files, warn): | ||||
'''return the contents of .hgignore files as a list of patterns. | ||||
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''' | ||||
syntaxes = {'re': 'relre:', 'regexp': 'relre:', 'glob': 'relglob:'} | ||||
pats = {} | ||||
for f in files: | ||||
try: | ||||
pats[f] = [] | ||||
fp = open(f) | ||||
syntax = 'relre:' | ||||
for line in _parselines(fp): | ||||
if line.startswith('syntax:'): | ||||
s = line[7:].strip() | ||||
try: | ||||
syntax = syntaxes[s] | ||||
except KeyError: | ||||
warn(_("%s: ignoring invalid syntax '%s'\n") % (f, s)) | ||||
continue | ||||
pat = syntax + line | ||||
Dirkjan Ochtman
|
r7622 | for s, rels in syntaxes.iteritems(): | ||
Thomas Arendsen Hein
|
r5029 | if line.startswith(rels): | ||
Matt Mackall
|
r4609 | pat = line | ||
break | ||||
Thomas Arendsen Hein
|
r5029 | elif line.startswith(s+':'): | ||
pat = rels + line[len(s)+1:] | ||||
break | ||||
Matt Mackall
|
r4609 | pats[f].append(pat) | ||
except IOError, inst: | ||||
if f != files[0]: | ||||
warn(_("skipping unreadable ignore file '%s': %s\n") % | ||||
(f, inst.strerror)) | ||||
allpats = [] | ||||
[allpats.extend(patlist) for patlist in pats.values()] | ||||
if not allpats: | ||||
return util.never | ||||
try: | ||||
Matt Mackall
|
r8567 | ignorefunc = match.match(root, '', [], allpats) | ||
Matt Mackall
|
r4609 | except util.Abort: | ||
# Re-raise an exception where the src is the right file | ||||
Dirkjan Ochtman
|
r7622 | for f, patlist in pats.iteritems(): | ||
Matt Mackall
|
r8566 | try: | ||
Matt Mackall
|
r8567 | match.match(root, '', [], patlist) | ||
Matt Mackall
|
r8566 | except util.Abort, inst: | ||
raise util.Abort('%s: %s' % (f, inst[0])) | ||||
Matt Mackall
|
r4609 | |||
return ignorefunc | ||||