Work with simple command table instead of decorators.

This commit is contained in:
Dirkjan Ochtman 2009-04-10 23:09:59 +02:00
parent 1365c9d1fd
commit b254838e8f
5 changed files with 73 additions and 86 deletions

View File

@ -26,8 +26,6 @@ import svncommands
import tag_repo
import util
from util import svn_subcommands, svn_commands_nourl
def reposetup(ui, repo):
if not util.is_svn_repo(repo):
return
@ -39,9 +37,9 @@ def svn(ui, repo, subcommand, *args, **opts):
'''see detailed help for list of subcommands'''
# guess command if prefix
if subcommand not in svn_subcommands:
if subcommand not in svncommands.table:
candidates = []
for c in svn_subcommands:
for c in svncommands.table:
if c.startswith(subcommand):
candidates.append(c)
if len(candidates) == 1:
@ -49,8 +47,8 @@ def svn(ui, repo, subcommand, *args, **opts):
path = os.path.dirname(repo.path)
try:
commandfunc = svn_subcommands[subcommand]
if commandfunc not in svn_commands_nourl:
commandfunc = svncommands.table[subcommand]
if commandfunc not in svncommands.nourl:
opts['svn_url'] = open(os.path.join(repo.path, 'svn', 'url')).read()
return commandfunc(ui, args=args, hg_repo_path=path, repo=repo, **opts)
except core.SubversionException, e:
@ -111,7 +109,7 @@ cmdtable = {
('', 'username', '', 'username for authentication'),
('', 'password', '', 'password for authentication'),
],
svncommands.generate_help(),
svncommands._helpgen(),
),
"svnclone":
(svn_fetch,

View File

@ -16,8 +16,6 @@ import cmdutil
import util
import utility_commands
from util import generate_help, svn_subcommands, register_subcommand
def pull(ui, svn_url, hg_repo_path, skipto_rev=0, stupid=None,
tag_locations='tags', authors=None, filemap=None, **opts):
@ -98,8 +96,6 @@ def pull(ui, svn_url, hg_repo_path, skipto_rev=0, stupid=None,
raise hgutil.Abort(*e.args)
util.swap_out_encoding(old_encoding)
pull = util.register_subcommand('pull')(pull)
def push(ui, repo, hg_repo_path, svn_url, stupid=False, **opts):
"""push revisions starting at a specified head back to Subversion.
@ -166,10 +162,8 @@ def push(ui, repo, hg_repo_path, svn_url, stupid=False, **opts):
if ctx.node() == oldest:
return
extra['branch'] = ctx.branch()
utility_commands.rebase_commits(ui, repo,
extrafn=extrafn,
sourcerev=needs_transplant,
**opts)
utility_commands.rebase(ui, repo, extrafn=extrafn,
sourcerev=needs_transplant, **opts)
repo = hg.repository(ui, hge.path)
for child in repo[replacement.node()].children():
rebasesrc = node.bin(child.extra().get('rebase_source', node.hex(node.nullid)))
@ -186,9 +180,6 @@ def push(ui, repo, hg_repo_path, svn_url, stupid=False, **opts):
svn_commit_hashes = dict(zip(hge.revmap.itervalues(), hge.revmap.iterkeys()))
util.swap_out_encoding(old_encoding)
return 0
push = util.register_subcommand('push')(push)
# for git expats
dcommit = util.register_subcommand('dcommit')(push)
def diff(ui, repo, hg_repo_path, **opts):
@ -213,7 +204,6 @@ def diff(ui, repo, hg_repo_path, **opts):
'text': False,
}))
ui.write(cmdutil.filterdiff(''.join(it), base_rev))
diff = util.register_subcommand('diff')(diff)
def rebuildmeta(ui, repo, hg_repo_path, args, **opts):
@ -329,8 +319,6 @@ def rebuildmeta(ui, repo, hg_repo_path, args, **opts):
tagsinfofile = open(os.path.join(svnmetadir, 'tag_info'), 'w')
pickle.dump(tagsinfo, tagsinfofile)
tagsinfofile.close()
rebuildmeta = util.register_subcommand('rebuildmeta')(rebuildmeta)
rebuildmeta = util.command_needs_no_url(rebuildmeta)
def help(ui, args=None, **opts):
@ -338,9 +326,9 @@ def help(ui, args=None, **opts):
"""
if args:
subcommand = args[0]
if subcommand not in svn_subcommands:
if subcommand not in table:
candidates = []
for c in svn_subcommands:
for c in table:
if c.startswith(subcommand):
candidates.append(c)
if len(candidates) == 1:
@ -349,13 +337,12 @@ def help(ui, args=None, **opts):
ui.status('Ambiguous command. Could have been:\n%s\n' %
' '.join(candidates))
return
doc = svn_subcommands[subcommand].__doc__
doc = table[subcommand].__doc__
if doc is None:
doc = "No documentation available for %s." % subcommand
ui.status(doc.strip(), '\n')
return
ui.status(generate_help())
help = register_subcommand('help')(help)
ui.status(_helpgen())
def update(ui, args, repo, clean=False, **opts):
@ -380,4 +367,27 @@ def update(ui, args, repo, clean=False, **opts):
ui.status('\n'.join(['%s on %s' % (node.hex(a[0]), a[1]) for a in
answers]+['']))
return 1
update = register_subcommand('up')(update)
nourl = ['rebuildmeta'] + utility_commands.nourl
table = {
'pull': pull,
'push': push,
'dcommit': push,
'update': update,
'help': help,
'rebuildmeta': rebuildmeta,
'diff': diff,
}
table.update(utility_commands.table)
def _helpgen():
ret = ['hg svn ...', '',
'subcommands for Subversion integration', '',
'list of subcommands:', '']
for name, func in sorted(table.items()):
short_description = (func.__doc__ or '').splitlines()[0]
ret.append(" %-10s %s" % (name, short_description))
return '\n'.join(ret) + '\n'

View File

@ -26,7 +26,7 @@ class UtilityTests(test_util.TestBase):
self._load_fixture_and_fetch('two_heads.svndump')
hg.update(self.repo, 'the_branch')
u = ui.ui()
utility_commands.run_svn_info(u, self.repo, self.wc_path)
utility_commands.info(u, self.repo, self.wc_path)
expected = (expected_info_output %
{'date': '2008-10-08 01:39:05 +0000 (Wed, 08 Oct 2008)',
'repourl': test_util.fileurl(self.repo_path),
@ -36,7 +36,7 @@ class UtilityTests(test_util.TestBase):
self.assertEqual(u.stream.getvalue(), expected)
hg.update(self.repo, 'default')
u = ui.ui()
utility_commands.run_svn_info(u, self.repo, self.wc_path)
utility_commands.info(u, self.repo, self.wc_path)
expected = (expected_info_output %
{'date': '2008-10-08 01:39:29 +0000 (Wed, 08 Oct 2008)',
'repourl': test_util.fileurl(self.repo_path),
@ -65,14 +65,14 @@ class UtilityTests(test_util.TestBase):
{'branch': 'localbranch', })
new = self.repo.commitctx(ctx)
hg.update(self.repo, new)
utility_commands.print_parent_revision(u, self.repo, self.wc_path)
utility_commands.parent(u, self.repo, self.wc_path)
self.assert_(node.hex(self.repo['the_branch'].node())[:8] in
u.stream.getvalue())
self.assert_('the_branch' in u.stream.getvalue())
self.assert_('r5' in u.stream.getvalue())
hg.update(self.repo, 'default')
u = ui.ui()
utility_commands.print_parent_revision(u, self.repo, self.wc_path)
utility_commands.parent(u, self.repo, self.wc_path)
self.assert_(node.hex(self.repo['default'].node())[:8] in
u.stream.getvalue())
self.assert_('trunk' in u.stream.getvalue())
@ -98,20 +98,20 @@ class UtilityTests(test_util.TestBase):
{'branch': 'localbranch', })
new = self.repo.commitctx(ctx)
hg.update(self.repo, new)
utility_commands.show_outgoing_to_svn(u, self.repo, self.wc_path)
utility_commands.outgoing(u, self.repo, self.wc_path)
self.assert_(node.hex(self.repo['localbranch'].node())[:8] in
u.stream.getvalue())
self.assert_('testy' in u.stream.getvalue())
hg.update(self.repo, 'default')
u = ui.ui()
utility_commands.show_outgoing_to_svn(u, self.repo, self.wc_path)
utility_commands.outgoing(u, self.repo, self.wc_path)
self.assertEqual(u.stream.getvalue(), 'No outgoing changes found.\n')
def test_url_output(self):
self._load_fixture_and_fetch('two_revs.svndump')
hg.update(self.repo, 'tip')
u = ui.ui()
utility_commands.print_wc_url(u, self.repo, self.wc_path)
utility_commands.url(u, self.repo, self.wc_path)
expected = test_util.fileurl(self.repo_path) + '\n'
self.assertEqual(u.stream.getvalue(), expected)
@ -136,7 +136,7 @@ class UtilityTests(test_util.TestBase):
self.assertEqual(self.repo['tip'].branch(), 'localbranch')
beforerebasehash = self.repo['tip'].node()
hg.update(self.repo, 'tip')
utility_commands.rebase_commits(ui.ui(), self.repo)
utility_commands.rebase(ui.ui(), self.repo)
self.assertEqual(self.repo['tip'].branch(), 'localbranch')
self.assertEqual(self.repo['tip'].parents()[0].parents()[0], self.repo[0])
self.assertNotEqual(beforerebasehash, self.repo['tip'].node())
@ -150,7 +150,7 @@ class UtilityTests(test_util.TestBase):
hg_repo_path=self.wc_path, stupid=False)
hg.update(self.repo, 'tip')
u = ui.ui()
utility_commands.print_wc_url(u, self.repo, self.wc_path)
utility_commands.url(u, self.repo, self.wc_path)
expected = test_util.fileurl(self.repo_path) + '\n'
self.assertEqual(u.stream.getvalue(), expected)
@ -163,7 +163,7 @@ class UtilityTests(test_util.TestBase):
hg_repo_path=self.wc_path, stupid=False)
hg.update(self.repo, 'tip')
u = ui.ui()
utility_commands.generate_ignore(u, self.repo, self.wc_path)
utility_commands.genignore(u, self.repo, self.wc_path)
self.assertEqual(open(os.path.join(self.wc_path, '.hgignore')).read(),
'.hgignore\nsyntax:glob\nblah\notherblah\nbaz/magic\n')
@ -171,9 +171,9 @@ class UtilityTests(test_util.TestBase):
test_util.load_svndump_fixture(self.repo_path,
'replace_trunk_with_branch.svndump')
u = ui.ui()
utility_commands.list_authors(u,
args=[test_util.fileurl(self.repo_path)],
authors=None)
utility_commands.listauthors(u,
args=[test_util.fileurl(self.repo_path)],
authors=None)
self.assertEqual(u.stream.getvalue(), 'Augie\nevil\n')
@ -181,9 +181,9 @@ class UtilityTests(test_util.TestBase):
test_util.load_svndump_fixture(self.repo_path,
'replace_trunk_with_branch.svndump')
author_path = os.path.join(self.repo_path, 'authors')
utility_commands.list_authors(ui.ui(),
args=[test_util.fileurl(self.repo_path)],
authors=author_path)
utility_commands.listauthors(ui.ui(),
args=[test_util.fileurl(self.repo_path)],
authors=author_path)
self.assertEqual(open(author_path).read(), 'Augie=\nevil=\n')

24
util.py
View File

@ -5,18 +5,6 @@ from mercurial import hg
from mercurial import node
from mercurial import util as hgutil
svn_subcommands = { }
def register_subcommand(name):
def inner(fn):
svn_subcommands[name] = fn
return fn
return inner
svn_commands_nourl = set()
def command_needs_no_url(fn):
svn_commands_nourl.add(fn)
return fn
def version(ui):
"""Guess the version of hgsubversion.
@ -27,18 +15,6 @@ def version(ui):
return node.hex(ver)[:12]
def generate_help():
ret = ['hg svn ...', '',
'subcommands for Subversion integration', '',
'list of subcommands:', '']
for name, func in sorted(svn_subcommands.items()):
short_description = (func.__doc__ or '').splitlines()[0]
ret.append(" %-10s %s" % (name, short_description))
return "\n".join(ret) + '\n'
def normalize_url(svn_url):
return svn_url.rstrip('/')

View File

@ -4,19 +4,18 @@ import mercurial
from mercurial import cmdutil
from mercurial import node
from mercurial import util as hgutil
from hgext import rebase
from hgext import rebase as hgrebase
import svnwrap
import util
import hg_delta_editor
def print_wc_url(ui, repo, hg_repo_path, **opts):
def url(ui, repo, hg_repo_path, **opts):
"""show the location (URL) of the Subversion repository
"""
hge = hg_delta_editor.HgChangeReceiver(hg_repo_path,
ui_=ui)
ui.status(hge.url, '\n')
print_wc_url = util.register_subcommand('url')(print_wc_url)
def find_wc_parent_rev(ui, repo, hge, svn_commit_hashes):
@ -29,7 +28,7 @@ def find_wc_parent_rev(ui, repo, hge, svn_commit_hashes):
return workingctx
def generate_ignore(ui, repo, hg_repo_path, force=False, **opts):
def genignore(ui, repo, hg_repo_path, force=False, **opts):
"""generate .hgignore from svn:ignore properties.
"""
ignpath = os.path.join(hg_repo_path, '.hgignore')
@ -63,10 +62,9 @@ def generate_ignore(ui, repo, hg_repo_path, force=False, **opts):
ignorefile.write('%s/%s\n' % (dir, prop))
else:
ignorefile.write('%s\n' % prop)
generate_ignore = util.register_subcommand('genignore')(generate_ignore)
def run_svn_info(ui, repo, hg_repo_path, **opts):
def info(ui, repo, hg_repo_path, **opts):
"""show Subversion details similar to `svn info'
"""
hge = hg_delta_editor.HgChangeReceiver(hg_repo_path,
@ -111,10 +109,9 @@ Last Changed Date: %(date)s\n''' %
'date': hgutil.datestr(parent.date(),
'%Y-%m-%d %H:%M:%S %1%2 (%a, %d %b %Y)')
})
run_svn_info = util.register_subcommand('info')(run_svn_info)
def print_parent_revision(ui, repo, hg_repo_path, **opts):
def parent(ui, repo, hg_repo_path, **opts):
"""show Mercurial & Subversion parents of the working dir or revision
"""
hge = hg_delta_editor.HgChangeReceiver(hg_repo_path,
@ -129,10 +126,9 @@ def print_parent_revision(ui, repo, hg_repo_path, **opts):
else:
ui.status('Working copy seems to have no parent svn revision.\n')
return 0
print_parent_revision = util.register_subcommand('parent')(print_parent_revision)
def rebase_commits(ui, repo, extrafn=None, sourcerev=None, **opts):
def rebase(ui, repo, extrafn=None, sourcerev=None, **opts):
"""rebase current unpushed revisions onto the Subversion head
This moves a line of development from making its own head to the top of
@ -175,13 +171,12 @@ def rebase_commits(ui, repo, extrafn=None, sourcerev=None, **opts):
ui.status('Already up to date!\n')
return 0
# TODO this is really hacky, there must be a more direct way
return rebase.rebase(ui, repo, dest=node.hex(target_rev.node()),
return hgrebase.rebase(ui, repo, dest=node.hex(target_rev.node()),
base=node.hex(sourcerev),
extrafn=extrafn)
rebase_commits = util.register_subcommand('rebase')(rebase_commits)
def show_outgoing_to_svn(ui, repo, hg_repo_path, **opts):
def outgoing(ui, repo, hg_repo_path, **opts):
"""show changesets not found in the Subversion repository
"""
hge = hg_delta_editor.HgChangeReceiver(hg_repo_path,
@ -195,10 +190,9 @@ def show_outgoing_to_svn(ui, repo, hg_repo_path, **opts):
displayer = cmdutil.show_changeset(ui, repo, opts, buffered=False)
for node in reversed(o_r):
displayer.show(repo[node])
show_outgoing_to_svn = util.register_subcommand('outgoing')(show_outgoing_to_svn)
def list_authors(ui, args, authors=None, **opts):
def listauthors(ui, args, authors=None, **opts):
"""list all authors in a Subversion repository
"""
if not len(args):
@ -214,8 +208,6 @@ def list_authors(ui, args, authors=None, **opts):
authorfile.close()
else:
ui.status('%s\n' % '\n'.join(sorted(author_set)))
list_authors = util.register_subcommand('listauthors')(list_authors)
list_authors = util.command_needs_no_url(list_authors)
def version(ui, **opts):
@ -224,5 +216,16 @@ def version(ui, **opts):
ui.status('hg: %s\n' % hgutil.version())
ui.status('svn bindings: %s\n' % svnwrap.version())
ui.status('hgsubversion: %s\n' % util.version(ui))
version = util.register_subcommand('version')(version)
version = util.command_needs_no_url(version)
nourl = ['version', 'listauthors']
table = {
'url': url,
'genignore': genignore,
'info': info,
'parent': parent,
'outgoing': outgoing,
'listauthors': listauthors,
'version': version,
'rebase': rebase,
}