comparison hgsubversion/__init__.py @ 337:46e69be8e2c8

Reorganize to have a more conventional module structure. This means that hgsubversion now uses absolute imports instead of relative ones, which makes the tests more reliable.
author Augie Fackler <durin42@gmail.com>
date Wed, 13 May 2009 21:39:39 -0500
parents __init__.py@56d877e6ccbb
children 88ba55ad58c0
comparison
equal deleted inserted replaced
336:c0b943cef0c3 337:46e69be8e2c8
1 '''integration with Subversion repositories
2
3 hgsubversion is an extension for Mercurial that allows it to act as a Subversion
4 client, offering fast, incremental and bidirectional synchronisation.
5
6 Please note that hgsubversion should not be considered stable software. It is
7 not feature complete, and neither guarantees of functionality nor future
8 compatability can be offered. It is, however, quite useful for the cases where
9 it works, and a good platform for further improvements.
10
11 Before using hgsubversion, we *strongly* encourage running the
12 automated tests. See `README' in the hgsubversion directory for
13 details.
14
15 The operation of hgsubversion can be customised with the following variables:
16
17 <list not written yet>
18
19 '''
20 # TODO: The docstring should be slightly more helpful, and at least mention all
21 # configuration settings we support
22
23 import os
24 import sys
25 import traceback
26
27 from mercurial import commands
28 from mercurial import extensions
29 from mercurial import hg
30 from mercurial import util as hgutil
31
32 from svn import core
33
34 import svncommands
35 import svnrepo
36 import util
37 import wrappers
38 import svnexternals
39
40 schemes = ('svn', 'svn+ssh', 'svn+http', 'svn+file')
41
42 optionmap = {
43 'tagpaths': ('hgsubversion', 'tagpaths'),
44 'authors': ('hgsubversion', 'authormap'),
45 'filemap': ('hgsubversion', 'filemap'),
46 'stupid': ('hgsubversion', 'stupid'),
47 'defaulthost': ('hgsubversion', 'defaulthost'),
48 'defaultauthors': ('hgsubversion', 'defaultauthors'),
49 'usebranchnames': ('hgsubversion', 'usebranchnames'),
50 }
51
52 def wrapper(orig, ui, repo, *args, **opts):
53 """
54 Subversion repositories are also supported for this command. See
55 `hg help %(extension)s` for details.
56 """
57 for opt, (section, name) in optionmap.iteritems():
58 if opt in opts:
59 if isinstance(repo, str):
60 ui.setconfig(section, name, opts.pop(opt))
61 else:
62 repo.ui.setconfig(section, name, opts.pop(opt))
63
64 return orig(ui, repo, *args, **opts)
65
66 def uisetup(ui):
67 """Do our UI setup.
68
69 Does the following wrappings:
70 * parent -> utility_commands.parent
71 * outgoing -> utility_commands.outgoing
72 """
73 entry = extensions.wrapcommand(commands.table, 'parents',
74 wrappers.parent)
75 entry[1].append(('', 'svn', None, "show parent svn revision instead"))
76 entry = extensions.wrapcommand(commands.table, 'outgoing',
77 wrappers.outgoing)
78 entry[1].append(('', 'svn', None, "show revisions outgoing to subversion"))
79 entry = extensions.wrapcommand(commands.table, 'diff',
80 wrappers.diff)
81 entry[1].append(('', 'svn', None,
82 "show svn-style diffs, default against svn parent"))
83
84 newflags = (('A', 'authors', '', 'path to file containing username '
85 'mappings for Subversion sources'),
86 ('', 'filemap', '', 'path to file containing rules for file '
87 'name mapping used for sources)'),
88 ('T', 'tagpaths', ['tags'], 'list of paths to search for tags '
89 'in Subversion repositories.'))
90 extname = 'hgsubversion'
91
92 for command in ['clone']:
93 doc = wrapper.__doc__.strip() % { 'extension': extname }
94 getattr(commands, command).__doc__ += doc
95 entry = extensions.wrapcommand(commands.table, command, wrapper)
96 entry[1].extend(newflags)
97
98 try:
99 rebase = extensions.find('rebase')
100 if rebase:
101 entry = extensions.wrapcommand(rebase.cmdtable, 'rebase', wrappers.rebase)
102 entry[1].append(('', 'svn', None, 'automatic svn rebase', ))
103 except:
104 pass
105
106
107 def svn(ui, repo, subcommand, *args, **opts):
108 '''see detailed help for list of subcommands'''
109
110 # guess command if prefix
111 if subcommand not in svncommands.table:
112 candidates = []
113 for c in svncommands.table:
114 if c.startswith(subcommand):
115 candidates.append(c)
116 if len(candidates) == 1:
117 subcommand = candidates[0]
118
119 path = os.path.dirname(repo.path)
120 try:
121 commandfunc = svncommands.table[subcommand]
122 if subcommand not in svncommands.nourl:
123 opts['svn_url'] = open(os.path.join(repo.path, 'svn', 'url')).read()
124 return commandfunc(ui, args=args, hg_repo_path=path, repo=repo, **opts)
125 except core.SubversionException, e:
126 if e.apr_err == core.SVN_ERR_RA_SERF_SSL_CERT_UNTRUSTED:
127 raise hgutil.Abort('It appears svn does not trust the ssl cert for this site.\n'
128 'Please try running svn ls on that url first.')
129 raise
130 except TypeError:
131 tb = traceback.extract_tb(sys.exc_info()[2])
132 if len(tb) == 1:
133 ui.status('Bad arguments for subcommand %s\n' % subcommand)
134 else:
135 raise
136 except KeyError, e:
137 tb = traceback.extract_tb(sys.exc_info()[2])
138 if len(tb) == 1:
139 ui.status('Unknown subcommand %s\n' % subcommand)
140 else:
141 raise
142
143 def reposetup(ui, repo):
144 if repo.local():
145 svnrepo.generate_repo_class(ui, repo)
146
147 for scheme in schemes:
148 hg.schemes[scheme] = svnrepo
149
150 cmdtable = {
151 "svn":
152 (svn,
153 [('u', 'svn-url', '', 'path to the Subversion server.'),
154 ('', 'stupid', False, 'be stupid and use diffy replay.'),
155 ('A', 'authors', '', 'username mapping filename'),
156 ('', 'filemap', '',
157 'remap file to exclude paths or include only certain paths'),
158 ('', 'force', False, 'force an operation to happen'),
159 ('', 'username', '', 'username for authentication'),
160 ('', 'password', '', 'password for authentication'),
161 ],
162 svncommands._helpgen(),
163 ),
164 }