/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to breezy/globbing.py

  • Committer: Jelmer Vernooij
  • Date: 2020-03-22 01:35:14 UTC
  • mfrom: (7490.7.6 work)
  • mto: This revision was merged to the branch mainline in revision 7499.
  • Revision ID: jelmer@jelmer.uk-20200322013514-7vw1ntwho04rcuj3
merge lp:brz/3.1.

Show diffs side-by-side

added added

removed removed

Lines of Context:
20
20
expressions.
21
21
"""
22
22
 
23
 
from __future__ import absolute_import
24
 
 
25
23
import re
26
24
 
27
25
from . import (
28
 
    errors,
29
26
    lazy_regex,
30
27
    )
31
28
from .trace import (
80
77
    def __call__(self, text):
81
78
        if not self._pat:
82
79
            self._pat = lazy_regex.lazy_compile(
83
 
                    u'|'.join([u'(%s)' % p for p in self._pats]),
84
 
                    re.UNICODE)
 
80
                u'|'.join([u'(%s)' % p for p in self._pats]),
 
81
                re.UNICODE)
85
82
        return self._pat.sub(self._do_sub, text)
86
83
 
87
84
    def _do_sub(self, m):
137
134
 
138
135
 
139
136
_sub_fullpath = Replacer()
140
 
_sub_fullpath.add(r'^RE:.*', _sub_re) # RE:<anything> is a regex
141
 
_sub_fullpath.add(r'\[\^?\]?(?:[^][]|\[:[^]]+:\])+\]', _sub_group) # char group
142
 
_sub_fullpath.add(r'(?:(?<=/)|^)(?:\.?/)+', u'') # canonicalize path
143
 
_sub_fullpath.add(r'\\.', r'\&') # keep anything backslashed
144
 
_sub_fullpath.add(r'[(){}|^$+.]', r'\\&') # escape specials
145
 
_sub_fullpath.add(r'(?:(?<=/)|^)\*\*+/', r'(?:.*/)?') # **/ after ^ or /
146
 
_sub_fullpath.add(r'\*+', r'[^/]*') # * elsewhere
147
 
_sub_fullpath.add(r'\?', r'[^/]') # ? everywhere
 
137
_sub_fullpath.add(r'^RE:.*', _sub_re)  # RE:<anything> is a regex
 
138
_sub_fullpath.add(r'\[\^?\]?(?:[^][]|\[:[^]]+:\])+\]',
 
139
                  _sub_group)  # char group
 
140
_sub_fullpath.add(r'(?:(?<=/)|^)(?:\.?/)+', u'')  # canonicalize path
 
141
_sub_fullpath.add(r'\\.', r'\&')  # keep anything backslashed
 
142
_sub_fullpath.add(r'[(){}|^$+.]', r'\\&')  # escape specials
 
143
_sub_fullpath.add(r'(?:(?<=/)|^)\*\*+/', r'(?:.*/)?')  # **/ after ^ or /
 
144
_sub_fullpath.add(r'\*+', r'[^/]*')  # * elsewhere
 
145
_sub_fullpath.add(r'\?', r'[^/]')  # ? everywhere
148
146
 
149
147
 
150
148
_sub_basename = Replacer()
151
 
_sub_basename.add(r'\[\^?\]?(?:[^][]|\[:[^]]+:\])+\]', _sub_group) # char group
152
 
_sub_basename.add(r'\\.', r'\&') # keep anything backslashed
153
 
_sub_basename.add(r'[(){}|^$+.]', r'\\&') # escape specials
154
 
_sub_basename.add(r'\*+', r'.*') # * everywhere
155
 
_sub_basename.add(r'\?', r'.') # ? everywhere
 
149
_sub_basename.add(r'\[\^?\]?(?:[^][]|\[:[^]]+:\])+\]',
 
150
                  _sub_group)  # char group
 
151
_sub_basename.add(r'\\.', r'\&')  # keep anything backslashed
 
152
_sub_basename.add(r'[(){}|^$+.]', r'\\&')  # escape specials
 
153
_sub_basename.add(r'\*+', r'.*')  # * everywhere
 
154
_sub_basename.add(r'\?', r'.')  # ? everywhere
156
155
 
157
156
 
158
157
def _sub_extension(pattern):
188
187
    # starting with the shortest and going to the longest.
189
188
    # As some Python version don't support ordered dicts the list below is
190
189
    # used to select inputs for _add_pattern in a specific order.
191
 
    pattern_types = [ "extension", "basename", "fullpath" ]
 
190
    pattern_types = ["extension", "basename", "fullpath"]
192
191
 
193
192
    pattern_info = {
194
193
        "extension": {
195
 
            "translator" : _sub_extension,
196
 
            "prefix" : r'(?:.*/)?(?!.*/)(?:.*\.)'
 
194
            "translator": _sub_extension,
 
195
            "prefix": r'(?:.*/)?(?!.*/)(?:.*\.)'
197
196
        },
198
197
        "basename": {
199
 
            "translator" : _sub_basename,
200
 
            "prefix" : r'(?:.*/)?(?!.*/)'
 
198
            "translator": _sub_basename,
 
199
            "prefix": r'(?:.*/)?(?!.*/)'
201
200
        },
202
201
        "fullpath": {
203
 
            "translator" : _sub_fullpath,
204
 
            "prefix" : r''
 
202
            "translator": _sub_fullpath,
 
203
            "prefix": r''
205
204
        },
206
205
    }
207
206
 
218
217
        pi = Globster.pattern_info
219
218
        for t in Globster.pattern_types:
220
219
            self._add_patterns(pattern_lists[t], pi[t]["translator"],
221
 
                pi[t]["prefix"])
 
220
                               pi[t]["prefix"])
222
221
 
223
222
    def _add_patterns(self, patterns, translator, prefix=''):
224
223
        while patterns:
241
240
            for regex, patterns in self._regex_patterns:
242
241
                match = regex.match(filename)
243
242
                if match:
244
 
                    return patterns[match.lastindex -1]
 
243
                    return patterns[match.lastindex - 1]
245
244
        except lazy_regex.InvalidPattern as e:
246
245
            # We can't show the default e.msg to the user as thats for
247
246
            # the combined pattern we sent to regex. Instead we indicate to
248
247
            # the user that an ignore file needs fixing.
249
248
            mutter('Invalid pattern found in regex: %s.', e.msg)
250
 
            e.msg = "File ~/.bazaar/ignore or .bzrignore contains error(s)."
 
249
            e.msg = (
 
250
                "File ~/.config/breezy/ignore or "
 
251
                ".bzrignore contains error(s).")
251
252
            bad_patterns = ''
252
253
            for _, patterns in self._regex_patterns:
253
254
                for p in patterns:
281
282
        see: globbing.normalize_pattern
282
283
        """
283
284
        result = True
284
 
        translator = Globster.pattern_info[Globster.identify(pattern)]["translator"]
 
285
        translator = Globster.pattern_info[Globster.identify(
 
286
            pattern)]["translator"]
285
287
        tpattern = '(%s)' % translator(pattern)
286
288
        try:
287
289
            re_obj = lazy_regex.lazy_compile(tpattern, re.UNICODE)
288
 
            re_obj.search("") # force compile
289
 
        except lazy_regex.InvalidPattern as e:
 
290
            re_obj.search("")  # force compile
 
291
        except lazy_regex.InvalidPattern:
290
292
            result = False
291
293
        return result
292
294
 
293
295
 
294
296
class ExceptionGlobster(object):
295
297
    """A Globster that supports exception patterns.
296
 
    
 
298
 
297
299
    Exceptions are ignore patterns prefixed with '!'.  Exception
298
 
    patterns take precedence over regular patterns and cause a 
299
 
    matching filename to return None from the match() function.  
300
 
    Patterns using a '!!' prefix are highest precedence, and act 
 
300
    patterns take precedence over regular patterns and cause a
 
301
    matching filename to return None from the match() function.
 
302
    Patterns using a '!!' prefix are highest precedence, and act
301
303
    as regular ignores. '!!' patterns are useful to establish ignores
302
304
    that apply under paths specified by '!' exception patterns.
303
305
    """
304
 
    
 
306
 
305
307
    def __init__(self, patterns):
306
308
        ignores = [[], [], []]
307
309
        for p in patterns:
312
314
            else:
313
315
                ignores[0].append(p)
314
316
        self._ignores = [Globster(i) for i in ignores]
315
 
        
 
317
 
316
318
    def match(self, filename):
317
319
        """Searches for a pattern that matches the given filename.
318
320
 
326
328
        else:
327
329
            return self._ignores[0].match(filename)
328
330
 
 
331
 
329
332
class _OrderedGlobster(Globster):
330
333
    """A Globster that keeps pattern order."""
331
334
 
340
343
            pat = normalize_pattern(pat)
341
344
            t = Globster.identify(pat)
342
345
            self._add_patterns([pat], Globster.pattern_info[t]["translator"],
343
 
                Globster.pattern_info[t]["prefix"])
 
346
                               Globster.pattern_info[t]["prefix"])
344
347
 
345
348
 
346
349
_slashes = lazy_regex.lazy_compile(r'[\\/]+')
 
350
 
 
351
 
347
352
def normalize_pattern(pattern):
348
353
    """Converts backslashes in path patterns to forward slashes.
349
354