comparison tag_repo.py @ 326:33736e2e25f0

alternate approach for supporting svn schemes for repository paths We now intercept the operations in the local repo class, and handle the relevant operation ourselves. This frees us from wrapping all relevant commands and replicating their functionality. The implementation is incomplete; only one test has been modified to use the standard Mercurial API with the changed URLs. Once changed, those tests will likely reveal bugs or missing features in the new wrappers. Also, new wrappers will be needed for handling conversion flags such as -A/--authormap.
author Dan Villiom Podlaski Christiansen <danchr@gmail.com>
date Thu, 07 May 2009 20:50:53 +0200
parents 91c818377703
children 98740f66a70c
comparison
equal deleted inserted replaced
320:1ba8ed29148e 326:33736e2e25f0
1 from mercurial import node 1 from mercurial import node
2 from mercurial import util as hgutil
3 import mercurial.repo
2 4
3 import hg_delta_editor 5 import hg_delta_editor
4 6 import util
5 7 import wrappers
6 def tags_from_tag_info(repo):
7 hg_editor = hg_delta_editor.HgChangeReceiver(repo=repo)
8 for tag, source in hg_editor.tags.iteritems():
9 source_ha = hg_editor.get_parent_revision(source[1]+1, source[0])
10 yield 'tag/%s'%tag, node.hex(source_ha)
11
12 8
13 def generate_repo_class(ui, repo): 9 def generate_repo_class(ui, repo):
10 def localsvn(fn):
11 '''
12 Filter for instance methods which only apply to local Subversion
13 repositories.
14 '''
15 if util.is_svn_repo(repo):
16 return fn
17 else:
18 original = repo.__getattribute__(fn.__name__)
19 return original
14 20
15 class svntagrepo(repo.__class__): 21 def remotesvn(fn):
22 '''
23 Filter for instance methods which require the first argument
24 to be a remote Subversion repository instance.
25 '''
26 original = repo.__getattribute__(fn.__name__)
27 def wrapper(self, *args, **opts):
28 print args
29 if not isinstance(args[0], svnremoterepo):
30 return original(*args, **opts)
31 else:
32 return fn(self, *args, **opts)
33 wrapper.__name__ = fn.__name__ + '_wrapper'
34 wrapper.__doc__ = fn.__doc__
35 return wrapper
36
37 class svnlocalrepo(repo.__class__):
38 @remotesvn
39 def pull(self, remote, heads=None, force=False):
40 try:
41 lock = self.wlock()
42 wrappers.pull(None, self.ui, self, source=remote.path,
43 svn=True, rev=heads, force=force)
44 except KeyboardInterrupt:
45 pass
46 finally:
47 lock.release()
48
49 @localsvn
16 def tags(self): 50 def tags(self):
17 tags = dict((k, node.bin(v)) 51 tags = super(svnlocalrepo, self).tags()
18 for k,v in tags_from_tag_info(self)) 52 hg_editor = hg_delta_editor.HgChangeReceiver(repo=self)
19 hg_tags = super(svntagrepo, self).tags() 53 for tag, source in hg_editor.tags.iteritems():
20 tags.update(hg_tags) 54 target = hg_editor.get_parent_revision(source[1]+1, source[0])
55 tags['tag/%s' % tag] = node.hex(target)
56 # TODO: should we even generate these tags?
57 if not hasattr(self, '_nofaketags'):
58 for (revnum, branch), node_hash in hg_editor.revmap.iteritems():
59 tags['%s@r%d' % (branch or 'trunk', revnum)] = node_hash
21 return tags 60 return tags
22 61
23 return svntagrepo 62 @localsvn
63 def tagslist(self):
64 try:
65 self._nofaketags = True
66 return super(svnlocalrepo, self).tagslist()
67 finally:
68 del self._nofaketags
69
70 repo.__class__ = svnlocalrepo
71
72 class svnremoterepo(mercurial.repo.repository):
73 def __init__(self, ui, path):
74 self.ui = ui
75 self.path = path
76 self.capabilities = set(['lookup'])
77
78 def url(self):
79 return self.path
80
81 def lookup(self, key):
82 return key
83
84 def cancopy(self):
85 return False
86
87 def heads(self, *args, **opts):
88 """
89 Whenever this function is hit, we abort. The traceback is useful for
90 figuring out where to intercept the functionality.
91 """
92 raise hgutil.Abort('command unavailable for Subversion repositories')
93
94 def instance(ui, url, create):
95 if create:
96 raise hgutil.Abort('cannot create new remote Subversion repository')
97
98 if url.startswith('svn+') and not url.startswith('svn+ssh:'):
99 url = url[4:]
100 return svnremoterepo(ui, util.normalize_url(url))