comparison hgext/convert/filemap.py @ 43076:2372284d9457

formatting: blacken the codebase This is using my patch to black (https://github.com/psf/black/pull/826) so we don't un-wrap collection literals. Done with: hg files 'set:**.py - mercurial/thirdparty/** - "contrib/python-zstandard/**"' | xargs black -S # skip-blame mass-reformatting only # no-check-commit reformats foo_bar functions Differential Revision: https://phab.mercurial-scm.org/D6971
author Augie Fackler <augie@google.com>
date Sun, 06 Oct 2019 09:45:02 -0400
parents 69804c040a04
children 687b865b95ad
comparison
equal deleted inserted replaced
43075:57875cf423c9 43076:2372284d9457
12 from mercurial import ( 12 from mercurial import (
13 error, 13 error,
14 pycompat, 14 pycompat,
15 ) 15 )
16 from . import common 16 from . import common
17
17 SKIPREV = common.SKIPREV 18 SKIPREV = common.SKIPREV
19
18 20
19 def rpairs(path): 21 def rpairs(path):
20 '''Yield tuples with path split at '/', starting with the full path. 22 '''Yield tuples with path split at '/', starting with the full path.
21 No leading, trailing or double '/', please. 23 No leading, trailing or double '/', please.
22 >>> for x in rpairs(b'foo/bar/baz'): print(x) 24 >>> for x in rpairs(b'foo/bar/baz'): print(x)
25 ('foo', 'bar/baz') 27 ('foo', 'bar/baz')
26 ('.', 'foo/bar/baz') 28 ('.', 'foo/bar/baz')
27 ''' 29 '''
28 i = len(path) 30 i = len(path)
29 while i != -1: 31 while i != -1:
30 yield path[:i], path[i + 1:] 32 yield path[:i], path[i + 1 :]
31 i = path.rfind('/', 0, i) 33 i = path.rfind('/', 0, i)
32 yield '.', path 34 yield '.', path
35
33 36
34 def normalize(path): 37 def normalize(path):
35 ''' We use posixpath.normpath to support cross-platform path format. 38 ''' We use posixpath.normpath to support cross-platform path format.
36 However, it doesn't handle None input. So we wrap it up. ''' 39 However, it doesn't handle None input. So we wrap it up. '''
37 if path is None: 40 if path is None:
38 return None 41 return None
39 return posixpath.normpath(path) 42 return posixpath.normpath(path)
43
40 44
41 class filemapper(object): 45 class filemapper(object):
42 '''Map and filter filenames when importing. 46 '''Map and filter filenames when importing.
43 A name can be mapped to itself, a new name, or None (omit from new 47 A name can be mapped to itself, a new name, or None (omit from new
44 repository).''' 48 repository).'''
53 if self.parse(path): 57 if self.parse(path):
54 raise error.Abort(_('errors in filemap')) 58 raise error.Abort(_('errors in filemap'))
55 59
56 def parse(self, path): 60 def parse(self, path):
57 errs = 0 61 errs = 0
62
58 def check(name, mapping, listname): 63 def check(name, mapping, listname):
59 if not name: 64 if not name:
60 self.ui.warn(_('%s:%d: path to %s is missing\n') % 65 self.ui.warn(
61 (lex.infile, lex.lineno, listname)) 66 _('%s:%d: path to %s is missing\n')
67 % (lex.infile, lex.lineno, listname)
68 )
62 return 1 69 return 1
63 if name in mapping: 70 if name in mapping:
64 self.ui.warn(_('%s:%d: %r already in %s list\n') % 71 self.ui.warn(
65 (lex.infile, lex.lineno, name, listname)) 72 _('%s:%d: %r already in %s list\n')
73 % (lex.infile, lex.lineno, name, listname)
74 )
66 return 1 75 return 1
67 if (name.startswith('/') or 76 if name.startswith('/') or name.endswith('/') or '//' in name:
68 name.endswith('/') or 77 self.ui.warn(
69 '//' in name): 78 _('%s:%d: superfluous / in %s %r\n')
70 self.ui.warn(_('%s:%d: superfluous / in %s %r\n') % 79 % (lex.infile, lex.lineno, listname, pycompat.bytestr(name))
71 (lex.infile, lex.lineno, listname, 80 )
72 pycompat.bytestr(name)))
73 return 1 81 return 1
74 return 0 82 return 0
83
75 lex = common.shlexer( 84 lex = common.shlexer(
76 filepath=path, wordchars='!@#$%^&*()-=+[]{}|;:,./<>?') 85 filepath=path, wordchars='!@#$%^&*()-=+[]{}|;:,./<>?'
86 )
77 cmd = lex.get_token() 87 cmd = lex.get_token()
78 while cmd: 88 while cmd:
79 if cmd == 'include': 89 if cmd == 'include':
80 name = normalize(lex.get_token()) 90 name = normalize(lex.get_token())
81 errs += check(name, self.exclude, 'exclude') 91 errs += check(name, self.exclude, 'exclude')
91 errs += check(src, self.exclude, 'exclude') 101 errs += check(src, self.exclude, 'exclude')
92 self.rename[src] = dest 102 self.rename[src] = dest
93 elif cmd == 'source': 103 elif cmd == 'source':
94 errs += self.parse(normalize(lex.get_token())) 104 errs += self.parse(normalize(lex.get_token()))
95 else: 105 else:
96 self.ui.warn(_('%s:%d: unknown directive %r\n') % 106 self.ui.warn(
97 (lex.infile, lex.lineno, pycompat.bytestr(cmd))) 107 _('%s:%d: unknown directive %r\n')
108 % (lex.infile, lex.lineno, pycompat.bytestr(cmd))
109 )
98 errs += 1 110 errs += 1
99 cmd = lex.get_token() 111 cmd = lex.get_token()
100 return errs 112 return errs
101 113
102 def lookup(self, name, mapping): 114 def lookup(self, name, mapping):
155 return name 167 return name
156 168
157 def active(self): 169 def active(self):
158 return bool(self.include or self.exclude or self.rename) 170 return bool(self.include or self.exclude or self.rename)
159 171
172
160 # This class does two additional things compared to a regular source: 173 # This class does two additional things compared to a regular source:
161 # 174 #
162 # - Filter and rename files. This is mostly wrapped by the filemapper 175 # - Filter and rename files. This is mostly wrapped by the filemapper
163 # class above. We hide the original filename in the revision that is 176 # class above. We hide the original filename in the revision that is
164 # returned by getchanges to be able to find things later in getfile. 177 # returned by getchanges to be able to find things later in getfile.
168 # create a graph that is restricted to those revisions. 181 # create a graph that is restricted to those revisions.
169 # 182 #
170 # This set of revisions includes not only revisions that directly 183 # This set of revisions includes not only revisions that directly
171 # touch files we're interested in, but also merges that merge two 184 # touch files we're interested in, but also merges that merge two
172 # or more interesting revisions. 185 # or more interesting revisions.
186
173 187
174 class filemap_source(common.converter_source): 188 class filemap_source(common.converter_source):
175 def __init__(self, ui, baseconverter, filemap): 189 def __init__(self, ui, baseconverter, filemap):
176 super(filemap_source, self).__init__(ui, baseconverter.repotype) 190 super(filemap_source, self).__init__(ui, baseconverter.repotype)
177 self.base = baseconverter 191 self.base = baseconverter
187 self._rebuilt = False 201 self._rebuilt = False
188 self.origparents = {} 202 self.origparents = {}
189 self.children = {} 203 self.children = {}
190 self.seenchildren = {} 204 self.seenchildren = {}
191 # experimental config: convert.ignoreancestorcheck 205 # experimental config: convert.ignoreancestorcheck
192 self.ignoreancestorcheck = self.ui.configbool('convert', 206 self.ignoreancestorcheck = self.ui.configbool(
193 'ignoreancestorcheck') 207 'convert', 'ignoreancestorcheck'
208 )
194 209
195 def before(self): 210 def before(self):
196 self.base.before() 211 self.base.before()
197 212
198 def after(self): 213 def after(self):
248 263
249 for rev, wanted, arg in self.convertedorder: 264 for rev, wanted, arg in self.convertedorder:
250 try: 265 try:
251 parents = self.origparents[rev] 266 parents = self.origparents[rev]
252 except KeyError: 267 except KeyError:
253 continue # unknown revmap source 268 continue # unknown revmap source
254 if wanted: 269 if wanted:
255 self.mark_wanted(rev, parents) 270 self.mark_wanted(rev, parents)
256 else: 271 else:
257 self.mark_not_wanted(rev, arg) 272 self.mark_not_wanted(rev, arg)
258 self._discard(arg, *parents) 273 self._discard(arg, *parents)
346 wrev = set() 361 wrev = set()
347 for p in parents: 362 for p in parents:
348 if p in self.wantedancestors: 363 if p in self.wantedancestors:
349 wrev.update(self.wantedancestors[p]) 364 wrev.update(self.wantedancestors[p])
350 else: 365 else:
351 self.ui.warn(_('warning: %s parent %s is missing\n') % 366 self.ui.warn(_('warning: %s parent %s is missing\n') % (rev, p))
352 (rev, p))
353 wrev.add(rev) 367 wrev.add(rev)
354 self.wantedancestors[rev] = wrev 368 self.wantedancestors[rev] = wrev
355 369
356 def getchanges(self, rev, full): 370 def getchanges(self, rev, full):
357 parents = self.commits[rev].parents 371 parents = self.commits[rev].parents
380 for i, p1 in enumerate(parents): 394 for i, p1 in enumerate(parents):
381 mp1 = self.parentmap[p1] 395 mp1 = self.parentmap[p1]
382 if mp1 == SKIPREV or mp1 in knownparents: 396 if mp1 == SKIPREV or mp1 in knownparents:
383 continue 397 continue
384 398
385 isancestor = (not self.ignoreancestorcheck and 399 isancestor = not self.ignoreancestorcheck and any(
386 any(p2 for p2 in parents 400 p2
387 if p1 != p2 and mp1 != self.parentmap[p2] 401 for p2 in parents
388 and mp1 in self.wantedancestors[p2])) 402 if p1 != p2
403 and mp1 != self.parentmap[p2]
404 and mp1 in self.wantedancestors[p2]
405 )
389 if not isancestor and not hasbranchparent and len(parents) > 1: 406 if not isancestor and not hasbranchparent and len(parents) > 1:
390 # This could be expensive, avoid unnecessary calls. 407 # This could be expensive, avoid unnecessary calls.
391 if self._cachedcommit(p1).branch == branch: 408 if self._cachedcommit(p1).branch == branch:
392 hasbranchparent = True 409 hasbranchparent = True
393 mparents.append((p1, mp1, i, isancestor)) 410 mparents.append((p1, mp1, i, isancestor))