hgext/convert/__init__.py
changeset 5376 d60a067227a5
parent 5375 dae323e453aa
child 5377 756a43a30e34
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