##// END OF EJS Templates
convert: darcs use absolute_import
timeless -
r28368:b9296b33 default
parent child Browse files
Show More
@@ -1,208 +1,221 b''
1 1 # darcs.py - darcs support for the convert extension
2 2 #
3 3 # Copyright 2007-2009 Matt Mackall <mpm@selenic.com> and others
4 4 #
5 5 # This software may be used and distributed according to the terms of the
6 6 # GNU General Public License version 2 or any later version.
7 from __future__ import absolute_import
7 8
8 from common import NoRepo, checktool, commandline, commit, converter_source
9 import errno
10 import os
11 import re
12 import shutil
13 import tempfile
9 14 from mercurial.i18n import _
10 from mercurial import util, error
11 import os, shutil, tempfile, re, errno
15 from mercurial import (
16 error,
17 util,
18 )
19 from . import common
20 NoRepo = common.NoRepo
12 21
13 22 # The naming drift of ElementTree is fun!
14 23
15 24 try:
16 from xml.etree.cElementTree import ElementTree, XMLParser
25 import xml.etree.cElementTree.ElementTree as ElementTree
26 import xml.etree.cElementTree.XMLParser as XMLParser
17 27 except ImportError:
18 28 try:
19 from xml.etree.ElementTree import ElementTree, XMLParser
29 import xml.etree.ElementTree.ElementTree as ElementTree
30 import xml.etree.ElementTree.XMLParser as XMLParser
20 31 except ImportError:
21 32 try:
22 from elementtree.cElementTree import ElementTree, XMLParser
33 import elementtree.cElementTree.ElementTree as ElementTree
34 import elementtree.cElementTree.XMLParser as XMLParser
23 35 except ImportError:
24 36 try:
25 from elementtree.ElementTree import ElementTree, XMLParser
37 import elementtree.ElementTree.ElementTree as ElementTree
38 import elementtree.ElementTree.XMLParser as XMLParser
26 39 except ImportError:
27 40 pass
28 41
29 class darcs_source(converter_source, commandline):
42 class darcs_source(common.converter_source, common.commandline):
30 43 def __init__(self, ui, path, revs=None):
31 converter_source.__init__(self, ui, path, revs=revs)
32 commandline.__init__(self, ui, 'darcs')
44 common.converter_source.__init__(self, ui, path, revs=revs)
45 common.commandline.__init__(self, ui, 'darcs')
33 46
34 47 # check for _darcs, ElementTree so that we can easily skip
35 48 # test-convert-darcs if ElementTree is not around
36 49 if not os.path.exists(os.path.join(path, '_darcs')):
37 50 raise NoRepo(_("%s does not look like a darcs repository") % path)
38 51
39 checktool('darcs')
52 common.checktool('darcs')
40 53 version = self.run0('--version').splitlines()[0].strip()
41 54 if version < '2.1':
42 55 raise error.Abort(_('darcs version 2.1 or newer needed (found %r)')
43 56 % version)
44 57
45 58 if "ElementTree" not in globals():
46 59 raise error.Abort(_("Python ElementTree module is not available"))
47 60
48 61 self.path = os.path.realpath(path)
49 62
50 63 self.lastrev = None
51 64 self.changes = {}
52 65 self.parents = {}
53 66 self.tags = {}
54 67
55 68 # Check darcs repository format
56 69 format = self.format()
57 70 if format:
58 71 if format in ('darcs-1.0', 'hashed'):
59 72 raise NoRepo(_("%s repository format is unsupported, "
60 73 "please upgrade") % format)
61 74 else:
62 75 self.ui.warn(_('failed to detect repository format!'))
63 76
64 77 def before(self):
65 78 self.tmppath = tempfile.mkdtemp(
66 79 prefix='convert-' + os.path.basename(self.path) + '-')
67 80 output, status = self.run('init', repodir=self.tmppath)
68 81 self.checkexit(status)
69 82
70 83 tree = self.xml('changes', xml_output=True, summary=True,
71 84 repodir=self.path)
72 85 tagname = None
73 86 child = None
74 87 for elt in tree.findall('patch'):
75 88 node = elt.get('hash')
76 89 name = elt.findtext('name', '')
77 90 if name.startswith('TAG '):
78 91 tagname = name[4:].strip()
79 92 elif tagname is not None:
80 93 self.tags[tagname] = node
81 94 tagname = None
82 95 self.changes[node] = elt
83 96 self.parents[child] = [node]
84 97 child = node
85 98 self.parents[child] = []
86 99
87 100 def after(self):
88 101 self.ui.debug('cleaning up %s\n' % self.tmppath)
89 102 shutil.rmtree(self.tmppath, ignore_errors=True)
90 103
91 104 def recode(self, s, encoding=None):
92 105 if isinstance(s, unicode):
93 106 # XMLParser returns unicode objects for anything it can't
94 107 # encode into ASCII. We convert them back to str to get
95 108 # recode's normal conversion behavior.
96 109 s = s.encode('latin-1')
97 110 return super(darcs_source, self).recode(s, encoding)
98 111
99 112 def xml(self, cmd, **kwargs):
100 113 # NOTE: darcs is currently encoding agnostic and will print
101 114 # patch metadata byte-for-byte, even in the XML changelog.
102 115 etree = ElementTree()
103 116 # While we are decoding the XML as latin-1 to be as liberal as
104 117 # possible, etree will still raise an exception if any
105 118 # non-printable characters are in the XML changelog.
106 119 parser = XMLParser(encoding='latin-1')
107 120 p = self._run(cmd, **kwargs)
108 121 etree.parse(p.stdout, parser=parser)
109 122 p.wait()
110 123 self.checkexit(p.returncode)
111 124 return etree.getroot()
112 125
113 126 def format(self):
114 127 output, status = self.run('show', 'repo', no_files=True,
115 128 repodir=self.path)
116 129 self.checkexit(status)
117 130 m = re.search(r'^\s*Format:\s*(.*)$', output, re.MULTILINE)
118 131 if not m:
119 132 return None
120 133 return ','.join(sorted(f.strip() for f in m.group(1).split(',')))
121 134
122 135 def manifest(self):
123 136 man = []
124 137 output, status = self.run('show', 'files', no_directories=True,
125 138 repodir=self.tmppath)
126 139 self.checkexit(status)
127 140 for line in output.split('\n'):
128 141 path = line[2:]
129 142 if path:
130 143 man.append(path)
131 144 return man
132 145
133 146 def getheads(self):
134 147 return self.parents[None]
135 148
136 149 def getcommit(self, rev):
137 150 elt = self.changes[rev]
138 151 date = util.strdate(elt.get('local_date'), '%a %b %d %H:%M:%S %Z %Y')
139 152 desc = elt.findtext('name') + '\n' + elt.findtext('comment', '')
140 153 # etree can return unicode objects for name, comment, and author,
141 154 # so recode() is used to ensure str objects are emitted.
142 return commit(author=self.recode(elt.get('author')),
143 date=util.datestr(date, '%Y-%m-%d %H:%M:%S %1%2'),
144 desc=self.recode(desc).strip(),
145 parents=self.parents[rev])
155 return common.commit(author=self.recode(elt.get('author')),
156 date=util.datestr(date, '%Y-%m-%d %H:%M:%S %1%2'),
157 desc=self.recode(desc).strip(),
158 parents=self.parents[rev])
146 159
147 160 def pull(self, rev):
148 161 output, status = self.run('pull', self.path, all=True,
149 162 match='hash %s' % rev,
150 163 no_test=True, no_posthook=True,
151 164 external_merge='/bin/false',
152 165 repodir=self.tmppath)
153 166 if status:
154 167 if output.find('We have conflicts in') == -1:
155 168 self.checkexit(status, output)
156 169 output, status = self.run('revert', all=True, repodir=self.tmppath)
157 170 self.checkexit(status, output)
158 171
159 172 def getchanges(self, rev, full):
160 173 if full:
161 174 raise error.Abort(_("convert from darcs does not support --full"))
162 175 copies = {}
163 176 changes = []
164 177 man = None
165 178 for elt in self.changes[rev].find('summary').getchildren():
166 179 if elt.tag in ('add_directory', 'remove_directory'):
167 180 continue
168 181 if elt.tag == 'move':
169 182 if man is None:
170 183 man = self.manifest()
171 184 source, dest = elt.get('from'), elt.get('to')
172 185 if source in man:
173 186 # File move
174 187 changes.append((source, rev))
175 188 changes.append((dest, rev))
176 189 copies[dest] = source
177 190 else:
178 191 # Directory move, deduce file moves from manifest
179 192 source = source + '/'
180 193 for f in man:
181 194 if not f.startswith(source):
182 195 continue
183 196 fdest = dest + '/' + f[len(source):]
184 197 changes.append((f, rev))
185 198 changes.append((fdest, rev))
186 199 copies[fdest] = f
187 200 else:
188 201 changes.append((elt.text.strip(), rev))
189 202 self.pull(rev)
190 203 self.lastrev = rev
191 204 return sorted(changes), copies, set()
192 205
193 206 def getfile(self, name, rev):
194 207 if rev != self.lastrev:
195 208 raise error.Abort(_('internal calling inconsistency'))
196 209 path = os.path.join(self.tmppath, name)
197 210 try:
198 211 data = util.readfile(path)
199 212 mode = os.lstat(path).st_mode
200 213 except IOError as inst:
201 214 if inst.errno == errno.ENOENT:
202 215 return None, None
203 216 raise
204 217 mode = (mode & 0o111) and 'x' or ''
205 218 return data, mode
206 219
207 220 def gettags(self):
208 221 return self.tags
@@ -1,155 +1,154 b''
1 1 #require test-repo
2 2
3 3 $ cd "$TESTDIR"/..
4 4
5 5 $ hg files 'set:(**.py)' | sed 's|\\|/|g' | xargs python contrib/check-py3-compat.py
6 6 contrib/check-code.py not using absolute_import
7 7 contrib/check-code.py requires print_function
8 8 contrib/debugshell.py not using absolute_import
9 9 contrib/hgfixes/fix_bytes.py not using absolute_import
10 10 contrib/hgfixes/fix_bytesmod.py not using absolute_import
11 11 contrib/hgfixes/fix_leftover_imports.py not using absolute_import
12 12 contrib/import-checker.py not using absolute_import
13 13 contrib/import-checker.py requires print_function
14 14 contrib/memory.py not using absolute_import
15 15 contrib/perf.py not using absolute_import
16 16 contrib/python-hook-examples.py not using absolute_import
17 17 contrib/revsetbenchmarks.py not using absolute_import
18 18 contrib/revsetbenchmarks.py requires print_function
19 19 contrib/showstack.py not using absolute_import
20 20 contrib/synthrepo.py not using absolute_import
21 21 contrib/win32/hgwebdir_wsgi.py not using absolute_import
22 22 doc/check-seclevel.py not using absolute_import
23 23 doc/gendoc.py not using absolute_import
24 24 doc/hgmanpage.py not using absolute_import
25 25 hgext/__init__.py not using absolute_import
26 26 hgext/color.py not using absolute_import
27 27 hgext/convert/__init__.py not using absolute_import
28 28 hgext/convert/bzr.py not using absolute_import
29 29 hgext/convert/common.py not using absolute_import
30 30 hgext/convert/convcmd.py not using absolute_import
31 31 hgext/convert/cvs.py not using absolute_import
32 32 hgext/convert/cvsps.py not using absolute_import
33 hgext/convert/darcs.py not using absolute_import
34 33 hgext/convert/hg.py not using absolute_import
35 34 hgext/convert/monotone.py not using absolute_import
36 35 hgext/convert/p4.py not using absolute_import
37 36 hgext/convert/subversion.py not using absolute_import
38 37 hgext/convert/transport.py not using absolute_import
39 38 hgext/eol.py not using absolute_import
40 39 hgext/extdiff.py not using absolute_import
41 40 hgext/factotum.py not using absolute_import
42 41 hgext/fetch.py not using absolute_import
43 42 hgext/gpg.py not using absolute_import
44 43 hgext/graphlog.py not using absolute_import
45 44 hgext/hgcia.py not using absolute_import
46 45 hgext/hgk.py not using absolute_import
47 46 hgext/highlight/__init__.py not using absolute_import
48 47 hgext/highlight/highlight.py not using absolute_import
49 48 hgext/histedit.py not using absolute_import
50 49 hgext/largefiles/__init__.py not using absolute_import
51 50 hgext/largefiles/basestore.py not using absolute_import
52 51 hgext/largefiles/lfcommands.py not using absolute_import
53 52 hgext/largefiles/lfutil.py not using absolute_import
54 53 hgext/largefiles/localstore.py not using absolute_import
55 54 hgext/largefiles/overrides.py not using absolute_import
56 55 hgext/largefiles/proto.py not using absolute_import
57 56 hgext/largefiles/remotestore.py not using absolute_import
58 57 hgext/largefiles/reposetup.py not using absolute_import
59 58 hgext/largefiles/uisetup.py not using absolute_import
60 59 hgext/largefiles/wirestore.py not using absolute_import
61 60 hgext/mq.py not using absolute_import
62 61 hgext/notify.py not using absolute_import
63 62 hgext/patchbomb.py not using absolute_import
64 63 hgext/purge.py not using absolute_import
65 64 hgext/rebase.py not using absolute_import
66 65 hgext/record.py not using absolute_import
67 66 hgext/relink.py not using absolute_import
68 67 hgext/schemes.py not using absolute_import
69 68 hgext/share.py not using absolute_import
70 69 hgext/shelve.py not using absolute_import
71 70 hgext/strip.py not using absolute_import
72 71 hgext/transplant.py not using absolute_import
73 72 hgext/win32mbcs.py not using absolute_import
74 73 hgext/win32text.py not using absolute_import
75 74 i18n/check-translation.py not using absolute_import
76 75 i18n/polib.py not using absolute_import
77 76 setup.py not using absolute_import
78 77 tests/filterpyflakes.py requires print_function
79 78 tests/generate-working-copy-states.py requires print_function
80 79 tests/get-with-headers.py requires print_function
81 80 tests/heredoctest.py requires print_function
82 81 tests/hypothesishelpers.py not using absolute_import
83 82 tests/hypothesishelpers.py requires print_function
84 83 tests/killdaemons.py not using absolute_import
85 84 tests/md5sum.py not using absolute_import
86 85 tests/mockblackbox.py not using absolute_import
87 86 tests/printenv.py not using absolute_import
88 87 tests/readlink.py not using absolute_import
89 88 tests/readlink.py requires print_function
90 89 tests/revlog-formatv0.py not using absolute_import
91 90 tests/run-tests.py not using absolute_import
92 91 tests/seq.py not using absolute_import
93 92 tests/seq.py requires print_function
94 93 tests/silenttestrunner.py not using absolute_import
95 94 tests/silenttestrunner.py requires print_function
96 95 tests/sitecustomize.py not using absolute_import
97 96 tests/svn-safe-append.py not using absolute_import
98 97 tests/svnxml.py not using absolute_import
99 98 tests/test-ancestor.py requires print_function
100 99 tests/test-atomictempfile.py not using absolute_import
101 100 tests/test-batching.py not using absolute_import
102 101 tests/test-batching.py requires print_function
103 102 tests/test-bdiff.py not using absolute_import
104 103 tests/test-bdiff.py requires print_function
105 104 tests/test-context.py not using absolute_import
106 105 tests/test-context.py requires print_function
107 106 tests/test-demandimport.py not using absolute_import
108 107 tests/test-demandimport.py requires print_function
109 108 tests/test-dispatch.py not using absolute_import
110 109 tests/test-dispatch.py requires print_function
111 110 tests/test-doctest.py not using absolute_import
112 111 tests/test-duplicateoptions.py not using absolute_import
113 112 tests/test-duplicateoptions.py requires print_function
114 113 tests/test-filecache.py not using absolute_import
115 114 tests/test-filecache.py requires print_function
116 115 tests/test-filelog.py not using absolute_import
117 116 tests/test-filelog.py requires print_function
118 117 tests/test-hg-parseurl.py not using absolute_import
119 118 tests/test-hg-parseurl.py requires print_function
120 119 tests/test-hgweb-auth.py not using absolute_import
121 120 tests/test-hgweb-auth.py requires print_function
122 121 tests/test-hgwebdir-paths.py not using absolute_import
123 122 tests/test-hybridencode.py not using absolute_import
124 123 tests/test-hybridencode.py requires print_function
125 124 tests/test-lrucachedict.py not using absolute_import
126 125 tests/test-lrucachedict.py requires print_function
127 126 tests/test-manifest.py not using absolute_import
128 127 tests/test-minirst.py not using absolute_import
129 128 tests/test-minirst.py requires print_function
130 129 tests/test-parseindex2.py not using absolute_import
131 130 tests/test-parseindex2.py requires print_function
132 131 tests/test-pathencode.py not using absolute_import
133 132 tests/test-pathencode.py requires print_function
134 133 tests/test-propertycache.py not using absolute_import
135 134 tests/test-propertycache.py requires print_function
136 135 tests/test-revlog-ancestry.py not using absolute_import
137 136 tests/test-revlog-ancestry.py requires print_function
138 137 tests/test-run-tests.py not using absolute_import
139 138 tests/test-simplemerge.py not using absolute_import
140 139 tests/test-status-inprocess.py not using absolute_import
141 140 tests/test-status-inprocess.py requires print_function
142 141 tests/test-symlink-os-yes-fs-no.py not using absolute_import
143 142 tests/test-trusted.py not using absolute_import
144 143 tests/test-trusted.py requires print_function
145 144 tests/test-ui-color.py not using absolute_import
146 145 tests/test-ui-color.py requires print_function
147 146 tests/test-ui-config.py not using absolute_import
148 147 tests/test-ui-config.py requires print_function
149 148 tests/test-ui-verbosity.py not using absolute_import
150 149 tests/test-ui-verbosity.py requires print_function
151 150 tests/test-url.py not using absolute_import
152 151 tests/test-url.py requires print_function
153 152 tests/test-walkrepo.py requires print_function
154 153 tests/test-wireproto.py requires print_function
155 154 tests/tinyproxy.py requires print_function
General Comments 0
You need to be logged in to leave comments. Login now