convert: abstract map files into a class

This commit is contained in:
Bryan O'Sullivan 2007-11-07 17:06:02 -08:00
parent 33c2bc9eb9
commit 857e67d5db
4 changed files with 52 additions and 41 deletions

View File

@ -5,7 +5,7 @@
# This software may be used and distributed according to the terms
# of the GNU General Public License, incorporated herein by reference.
from common import NoRepo, SKIPREV, converter_source, converter_sink
from common import NoRepo, SKIPREV, converter_source, converter_sink, mapfile
from cvs import convert_cvs
from darcs import darcs_source
from git import convert_git
@ -57,23 +57,10 @@ class converter(object):
self.ui = ui
self.opts = opts
self.commitcache = {}
self.revmapfile = revmapfile
self.revmapfilefd = None
self.authors = {}
self.authorfile = None
self.maporder = []
self.map = {}
try:
origrevmapfile = open(self.revmapfile, 'r')
for l in origrevmapfile:
sv, dv = l[:-1].split()
if sv not in self.map:
self.maporder.append(sv)
self.map[sv] = dv
origrevmapfile.close()
except IOError:
pass
self.map = mapfile(ui, revmapfile)
# Read first the dst author map if any
authorfile = self.dest.authorfile()
@ -161,16 +148,6 @@ class converter(object):
return s
def mapentry(self, src, dst):
if self.revmapfilefd is None:
try:
self.revmapfilefd = open(self.revmapfile, "a")
except IOError, (errno, strerror):
raise util.Abort("Could not open map file %s: %s, %s\n" % (self.revmapfile, errno, strerror))
self.map[src] = dst
self.revmapfilefd.write("%s %s\n" % (src, dst))
self.revmapfilefd.flush()
def writeauthormap(self):
authorfile = self.authorfile
if authorfile:
@ -217,7 +194,7 @@ class converter(object):
dest = SKIPREV
else:
dest = self.map[changes]
self.mapentry(rev, dest)
self.map[rev] = dest
return
files, copies = changes
parents = [self.map[r] for r in commit.parents]
@ -245,13 +222,13 @@ class converter(object):
self.dest.copyfile(copyf, f)
newnode = self.dest.putcommit(filenames, parents, commit)
self.mapentry(rev, newnode)
self.map[rev] = newnode
def convert(self):
try:
self.source.before()
self.dest.before()
self.source.setrevmap(self.map, self.maporder)
self.source.setrevmap(self.map)
self.ui.status("scanning source...\n")
heads = self.source.getheads()
parents = self.walktree(heads)
@ -281,7 +258,7 @@ class converter(object):
# write another hash correspondence to override the previous
# one so we don't end up with extra tag heads
if nrev:
self.mapentry(c, nrev)
self.map[c] = nrev
self.writeauthormap()
finally:
@ -292,8 +269,7 @@ class converter(object):
self.dest.after()
finally:
self.source.after()
if self.revmapfilefd:
self.revmapfilefd.close()
self.map.close()
def convert(ui, src, dest=None, revmapfile=None, **opts):
"""Convert a foreign SCM repository to a Mercurial one.

View File

@ -1,5 +1,5 @@
# common code for the convert extension
import base64
import base64, errno
import cPickle as pickle
from mercurial import util
@ -54,11 +54,8 @@ class converter_source(object):
def after(self):
pass
def setrevmap(self, revmap, order):
"""set the map of already-converted revisions
order is a list with the keys from revmap in the order they
appear in the revision map file."""
def setrevmap(self, revmap):
"""set the map of already-converted revisions"""
pass
def getheads(self):
@ -190,3 +187,41 @@ class converter_sink(object):
filter empty revisions.
"""
pass
class mapfile(dict):
def __init__(self, ui, path):
super(mapfile, self).__init__()
self.ui = ui
self.path = path
self.fp = None
self.order = []
self._read()
def _read(self):
try:
fp = open(self.path, 'r')
except IOError, err:
if err.errno != errno.ENOENT:
raise
return
for line in fp:
key, value = line[:-1].split(' ', 1)
if key not in self:
self.order.append(key)
super(mapfile, self).__setitem__(key, value)
fp.close()
def __setitem__(self, key, value):
if self.fp is None:
try:
self.fp = open(self.path, 'a')
except IOError, err:
raise util.Abort(_('could not open map file %r: %s') %
(self.path, err.strerror))
self.fp.write('%s %s\n' % (key, value))
self.fp.flush()
super(mapfile, self).__setitem__(key, value)
def close(self):
self.fp.close()

View File

@ -128,7 +128,7 @@ class filemap_source(object):
self.children = {}
self.seenchildren = {}
def setrevmap(self, revmap, order):
def setrevmap(self, revmap):
# rebuild our state to make things restartable
#
# To avoid calling getcommit for every revision that has already
@ -143,7 +143,7 @@ class filemap_source(object):
seen = {SKIPREV: SKIPREV}
dummyset = util.set()
converted = []
for rev in order:
for rev in revmap.order:
mapped = revmap[rev]
wanted = mapped not in seen
if wanted:
@ -157,7 +157,7 @@ class filemap_source(object):
arg = None
converted.append((rev, wanted, arg))
self.convertedorder = converted
return self.base.setrevmap(revmap, order)
return self.base.setrevmap(revmap)
def rebuild(self):
if self._rebuilt:

View File

@ -149,7 +149,7 @@ class svn_source(converter_source):
self.head = self.revid(self.last_changed)
self._changescache = None
def setrevmap(self, revmap, order):
def setrevmap(self, revmap):
lastrevs = {}
for revid in revmap.keys():
uuid, module, revnum = self.revsplit(revid)