Mercurial > hg
view mercurial/ignore.py @ 25087:559f24e3957d
tags: use try/except/finally
author | Matt Mackall <mpm@selenic.com> |
---|---|
date | Fri, 15 May 2015 09:58:02 -0500 |
parents | e91b32d3c67b |
children | 3139900f31b1 |
line wrap: on
line source
# 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 ignorepats(lines): '''parse lines (iterable) of .hgignore text, returning a tuple of (patterns, parse errors). 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 = [] warnings = [] for line in lines: 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: warnings.append(_("ignoring invalid syntax '%s'") % 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) return patterns, warnings def readignorefile(filepath, warn, skipwarning=False): try: pats = [] fp = open(filepath) pats, warnings = ignorepats(fp) fp.close() for warning in warnings: warn("%s: %s\n" % (filepath, warning)) except IOError, inst: if not skipwarning: warn(_("skipping unreadable ignore file '%s': %s\n") % (filepath, inst.strerror)) return pats 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 skipwarning = f == files[0] pats[f] = readignorefile(f, warn, skipwarning=skipwarning) 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