~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/globbing.py

  • Committer: John Arbash Meinel
  • Date: 2010-02-17 17:11:16 UTC
  • mfrom: (4797.2.17 2.1)
  • mto: (4797.2.18 2.1)
  • mto: This revision was merged to the branch mainline in revision 5055.
  • Revision ID: john@arbash-meinel.com-20100217171116-h7t9223ystbnx5h8
merge bzr.2.1 in preparation for NEWS entry.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2006, 2008 Canonical Ltd
 
1
# Copyright (C) 2006-2010 Canonical Ltd
2
2
 
3
3
# This program is free software; you can redistribute it and/or modify
4
4
# it under the terms of the GNU General Public License as published by
215
215
                return patterns[match.lastindex -1]
216
216
        return None
217
217
 
 
218
class ExceptionGlobster(object):
 
219
    """A Globster that supports exception patterns.
 
220
    
 
221
    Exceptions are ignore patterns prefixed with '!'.  Exception
 
222
    patterns take precedence over regular patterns and cause a 
 
223
    matching filename to return None from the match() function.  
 
224
    Patterns using a '!!' prefix are highest precedence, and act 
 
225
    as regular ignores. '!!' patterns are useful to establish ignores
 
226
    that apply under paths specified by '!' exception patterns.
 
227
    """
 
228
    
 
229
    def __init__(self,patterns):
 
230
        ignores = [[], [], []]
 
231
        for p in patterns:
 
232
            if p.startswith(u'!!'):
 
233
                ignores[2].append(p[2:])
 
234
            elif p.startswith(u'!'):
 
235
                ignores[1].append(p[1:])
 
236
            else:
 
237
                ignores[0].append(p)
 
238
        self._ignores = [Globster(i) for i in ignores]
 
239
        
 
240
    def match(self, filename):
 
241
        """Searches for a pattern that matches the given filename.
 
242
 
 
243
        :return A matching pattern or None if there is no matching pattern.
 
244
        """
 
245
        double_neg = self._ignores[2].match(filename)
 
246
        if double_neg:
 
247
            return "!!%s" % double_neg
 
248
        elif self._ignores[1].match(filename):
 
249
            return None
 
250
        else:
 
251
            return self._ignores[0].match(filename)
218
252
 
219
253
class _OrderedGlobster(Globster):
220
254
    """A Globster that keeps pattern order."""
238
272
                    prefix=r'(?:.*/)?(?!.*/)')
239
273
 
240
274
 
 
275
_slashes = re.compile(r'[\\/]+')
241
276
def normalize_pattern(pattern):
242
277
    """Converts backslashes in path patterns to forward slashes.
243
278
 
244
279
    Doesn't normalize regular expressions - they may contain escapes.
245
280
    """
246
 
    if not pattern.startswith('RE:'):
247
 
        pattern = pattern.replace('\\','/')
248
 
    return pattern.rstrip('/')
 
281
    if not (pattern.startswith('RE:') or pattern.startswith('!RE:')):
 
282
        pattern = _slashes.sub('/', pattern)
 
283
    if len(pattern) > 1:
 
284
        pattern = pattern.rstrip('/')
 
285
    return pattern