comparison hgext/convert/__init__.py @ 5376:d60a067227a5

convert: move filemapper class to a separate file
author Alexis S. L. Carvalho <alexis@cecm.usp.br>
date Thu, 04 Oct 2007 23:21:37 -0300
parents dae323e453aa
children 756a43a30e34
comparison
equal deleted inserted replaced
5375:dae323e453aa 5376:d60a067227a5
10 from darcs import darcs_source 10 from darcs import darcs_source
11 from git import convert_git 11 from git import convert_git
12 from hg import mercurial_source, mercurial_sink 12 from hg import mercurial_source, mercurial_sink
13 from subversion import convert_svn, debugsvnlog 13 from subversion import convert_svn, debugsvnlog
14 14
15 import os, shlex, shutil 15 import os, shutil
16 from mercurial import hg, ui, util, commands 16 from mercurial import hg, ui, util, commands
17 from mercurial.i18n import _ 17 from mercurial.i18n import _
18 18
19 commands.norepo += " convert debugsvnlog" 19 commands.norepo += " convert debugsvnlog"
20 20
283 finally: 283 finally:
284 self.source.after() 284 self.source.after()
285 if self.revmapfilefd: 285 if self.revmapfilefd:
286 self.revmapfilefd.close() 286 self.revmapfilefd.close()
287 287
288 def rpairs(name):
289 e = len(name)
290 while e != -1:
291 yield name[:e], name[e+1:]
292 e = name.rfind('/', 0, e)
293
294 class filemapper(object):
295 '''Map and filter filenames when importing.
296 A name can be mapped to itself, a new name, or None (omit from new
297 repository).'''
298
299 def __init__(self, ui, path=None):
300 self.ui = ui
301 self.include = {}
302 self.exclude = {}
303 self.rename = {}
304 if path:
305 if self.parse(path):
306 raise util.Abort(_('errors in filemap'))
307
308 def parse(self, path):
309 errs = 0
310 def check(name, mapping, listname):
311 if name in mapping:
312 self.ui.warn(_('%s:%d: %r already in %s list\n') %
313 (lex.infile, lex.lineno, name, listname))
314 return 1
315 return 0
316 lex = shlex.shlex(open(path), path, True)
317 lex.wordchars += '!@#$%^&*()-=+[]{}|;:,./<>?'
318 cmd = lex.get_token()
319 while cmd:
320 if cmd == 'include':
321 name = lex.get_token()
322 errs += check(name, self.exclude, 'exclude')
323 self.include[name] = name
324 elif cmd == 'exclude':
325 name = lex.get_token()
326 errs += check(name, self.include, 'include')
327 errs += check(name, self.rename, 'rename')
328 self.exclude[name] = name
329 elif cmd == 'rename':
330 src = lex.get_token()
331 dest = lex.get_token()
332 errs += check(src, self.exclude, 'exclude')
333 self.rename[src] = dest
334 elif cmd == 'source':
335 errs += self.parse(lex.get_token())
336 else:
337 self.ui.warn(_('%s:%d: unknown directive %r\n') %
338 (lex.infile, lex.lineno, cmd))
339 errs += 1
340 cmd = lex.get_token()
341 return errs
342
343 def lookup(self, name, mapping):
344 for pre, suf in rpairs(name):
345 try:
346 return mapping[pre], pre, suf
347 except KeyError, err:
348 pass
349 return '', name, ''
350
351 def __call__(self, name):
352 if self.include:
353 inc = self.lookup(name, self.include)[0]
354 else:
355 inc = name
356 if self.exclude:
357 exc = self.lookup(name, self.exclude)[0]
358 else:
359 exc = ''
360 if not inc or exc:
361 return None
362 newpre, pre, suf = self.lookup(name, self.rename)
363 if newpre:
364 if newpre == '.':
365 return suf
366 if suf:
367 return newpre + '/' + suf
368 return newpre
369 return name
370
371 def active(self):
372 return bool(self.include or self.exclude or self.rename)
373
374 def convert(ui, src, dest=None, revmapfile=None, **opts): 288 def convert(ui, src, dest=None, revmapfile=None, **opts):
375 """Convert a foreign SCM repository to a Mercurial one. 289 """Convert a foreign SCM repository to a Mercurial one.
376 290
377 Accepted source formats: 291 Accepted source formats:
378 - CVS 292 - CVS