##// END OF EJS Templates
convert: added gnu arch (baz) tests
Aleix Conchillo Flaque -
r6078:ebc23d34 default
parent child Browse files
Show More
@@ -0,0 +1,66 b''
1 #!/bin/sh
2
3 "$TESTDIR/hghave" baz || exit 80
4
5 echo "[extensions]" >> $HGRCPATH
6 echo "convert=" >> $HGRCPATH
7 echo 'hgext.graphlog =' >> $HGRCPATH
8
9 echo % create baz archive
10 baz make-archive baz@mercurial--convert hg-test-convert-baz
11
12 echo % initialize baz repo
13 mkdir baz-repo
14 cd baz-repo/
15 baz init-tree baz@mercurial--convert/baz--test--0
16 baz import
17
18 echo % create initial files
19 echo 'this is a file' > a
20 baz add a
21 mkdir src
22 baz add src
23 cd src
24 dd count=1 if=/dev/zero of=b > /dev/null 2> /dev/null
25 baz add b
26 baz commit -s "added a file, src and src/b (binary)"
27
28 echo % create link file and modify a
29 ln -s ../a a-link
30 baz add a-link
31 echo 'this a modification to a' >> ../a
32 baz commit -s "added link to a and modify a"
33
34 echo % create second link and modify b
35 ln -s ../a a-link-2
36 baz add a-link-2
37 dd count=1 seek=1 if=/dev/zero of=b > /dev/null 2> /dev/null
38 baz commit -s "added second link and modify b"
39
40 echo % b file to link and a-link-2 to regular file
41 rm -f a-link-2
42 echo 'this is now a regular file' > a-link-2
43 ln -sf ../a b
44 baz commit -s "file to link and link to file test"
45
46 echo % move a-link-2 file and src directory
47 cd ..
48 baz mv src/a-link-2 c
49 baz mv src test
50 baz commit -s "move and rename a-link-2 file and src directory"
51
52 cd ..
53
54 echo % converting baz repo to Mercurial
55 hg convert baz-repo baz-repo-hg
56
57 baz register-archive -d baz@mercurial--convert
58
59 glog()
60 {
61 hg glog --template '#rev# "#desc|firstline#" files: #files#\n' "$@"
62 }
63
64 echo % show graph log
65 glog -R baz-repo-hg
66 hg -R baz-repo-hg manifest --debug
@@ -0,0 +1,75 b''
1 % create baz archive
2 % initialize baz repo
3 * creating version baz@mercurial--convert/baz--test--0
4 * imported baz@mercurial--convert/baz--test--0
5 % create initial files
6 * build pristine tree for baz@mercurial--convert/baz--test--0--base-0
7 * Scanning for full-tree revision: .
8 * from import revision: baz@mercurial--convert/baz--test--0--base-0
9 A/ .arch-ids
10 A/ src
11 A/ src/.arch-ids
12 A .arch-ids/a.id
13 A a
14 A src/.arch-ids/=id
15 A src/.arch-ids/b.id
16 A src/b
17 * update pristine tree (baz@mercurial--convert/baz--test--0--base-0 => baz--test--0--patch-1)
18 * committed baz@mercurial--convert/baz--test--0--patch-1
19 % create link file and modify a
20 A src/.arch-ids/a-link.id
21 A src/a-link
22 M a
23 * update pristine tree (baz@mercurial--convert/baz--test--0--patch-1 => baz--test--0--patch-2)
24 * committed baz@mercurial--convert/baz--test--0--patch-2
25 % create second link and modify b
26 A src/.arch-ids/a-link-2.id
27 A src/a-link-2
28 Mb src/b
29 * update pristine tree (baz@mercurial--convert/baz--test--0--patch-2 => baz--test--0--patch-3)
30 * committed baz@mercurial--convert/baz--test--0--patch-3
31 % b file to link and a-link-2 to regular file
32 fl src/b
33 lf src/a-link-2
34 * update pristine tree (baz@mercurial--convert/baz--test--0--patch-3 => baz--test--0--patch-4)
35 * committed baz@mercurial--convert/baz--test--0--patch-4
36 % move a-link-2 file and src directory
37 D/ src/.arch-ids
38 A/ test/.arch-ids
39 /> src test
40 => src/.arch-ids/a-link-2.id .arch-ids/c.id
41 => src/a-link-2 c
42 => src/.arch-ids/=id test/.arch-ids/=id
43 => src/.arch-ids/a-link.id test/.arch-ids/a-link.id
44 => src/.arch-ids/b.id test/.arch-ids/b.id
45 * update pristine tree (baz@mercurial--convert/baz--test--0--patch-4 => baz--test--0--patch-5)
46 * committed baz@mercurial--convert/baz--test--0--patch-5
47 % converting baz repo to Mercurial
48 initializing destination baz-repo-hg repository
49 analyzing tree version baz@mercurial--convert/baz--test--0...
50 scanning source...
51 sorting...
52 converting...
53 5 initial import
54 4 added a file, src and src/b (binary)
55 3 added link to a and modify a
56 2 added second link and modify b
57 1 file to link and link to file test
58 0 move and rename a-link-2 file and src directory
59 % show graph log
60 o 5 "move and rename a-link-2 file and src directory" files: c src/a-link src/a-link-2 src/b test/a-link test/b
61 |
62 o 4 "file to link and link to file test" files: src/a-link-2 src/b
63 |
64 o 3 "added second link and modify b" files: src/a-link-2 src/b
65 |
66 o 2 "added link to a and modify a" files: a src/a-link
67 |
68 o 1 "added a file, src and src/b (binary)" files: a src/b
69 |
70 o 0 "initial import" files:
71
72 c4072c4b72e1cabace081888efa148ee80ca3cbb 644 a
73 e3207be798aaf87a444a62903621edab4ddc1fb6 644 c
74 1f6b5bb93f1da278ef1fead1e4740a03d8802e9f 644 @ test/a-link
75 1f6b5bb93f1da278ef1fead1e4740a03d8802e9f 644 @ test/b
@@ -1,292 +1,292 b''
1 1 # GNU Arch support for the convert extension
2 2
3 3 from common import NoRepo, checktool, commandline, commit, converter_source
4 4 from mercurial.i18n import _
5 5 from mercurial import util
6 6 import os, shutil, tempfile, stat
7 7
8 8 class gnuarch_source(converter_source, commandline):
9 9
10 10 class gnuarch_rev:
11 11 def __init__(self, rev):
12 12 self.rev = rev
13 13 self.summary = ''
14 14 self.date = None
15 15 self.author = ''
16 16 self.add_files = []
17 17 self.mod_files = []
18 18 self.del_files = []
19 19 self.ren_files = {}
20 20 self.ren_dirs = {}
21 21
22 22 def __init__(self, ui, path, rev=None):
23 23 super(gnuarch_source, self).__init__(ui, path, rev=rev)
24 24
25 25 if not os.path.exists(os.path.join(path, '{arch}')):
26 raise NoRepo(_("couldn't open GNU Arch repo %s" % path))
26 raise NoRepo(_("%s does not look like a GNU Arch repo" % path))
27 27
28 28 # Could use checktool, but we want to check for baz or tla.
29 29 self.execmd = None
30 30 if util.find_exe('tla'):
31 31 self.execmd = 'tla'
32 32 else:
33 33 if util.find_exe('baz'):
34 34 self.execmd = 'baz'
35 35 else:
36 36 raise util.Abort(_('cannot find a GNU Arch tool'))
37 37
38 38 commandline.__init__(self, ui, self.execmd)
39 39
40 40 self.path = os.path.realpath(path)
41 41 self.tmppath = None
42 42
43 43 self.treeversion = None
44 44 self.lastrev = None
45 45 self.changes = {}
46 46 self.parents = {}
47 47 self.tags = {}
48 48 self.modecache = {}
49 49
50 50 def before(self):
51 51 if self.execmd == 'tla':
52 52 output = self.run0('tree-version', self.path)
53 53 else:
54 54 output = self.run0('tree-version', '-d', self.path)
55 55 self.treeversion = output.strip()
56 56
57 57 self.ui.status(_('analyzing tree version %s...\n' % self.treeversion))
58 58
59 59 # Get name of temporary directory
60 60 version = self.treeversion.split('/')
61 61 self.tmppath = os.path.join(tempfile.gettempdir(),
62 62 'hg-%s' % version[1])
63 63
64 64 # Generate parents dictionary
65 65 child = []
66 66 output, status = self.runlines('revisions', self.treeversion)
67 67 self.checkexit(status, 'archive registered?')
68 68 for l in output:
69 69 rev = l.strip()
70 70 self.changes[rev] = self.gnuarch_rev(rev)
71 71
72 72 # Read author, date and summary
73 73 catlog = self.runlines0('cat-log', '-d', self.path, rev)
74 74 self._parsecatlog(catlog, rev)
75 75
76 76 self.parents[rev] = child
77 77 child = [rev]
78 78 if rev == self.rev:
79 79 break
80 80 self.parents[None] = child
81 81
82 82 def after(self):
83 83 self.ui.debug(_('cleaning up %s\n' % self.tmppath))
84 84 shutil.rmtree(self.tmppath, ignore_errors=True)
85 85
86 86 def getheads(self):
87 87 return self.parents[None]
88 88
89 89 def getfile(self, name, rev):
90 90 if rev != self.lastrev:
91 91 raise util.Abort(_('internal calling inconsistency'))
92 92
93 93 # Raise IOError if necessary (i.e. deleted files).
94 94 if not os.path.exists(os.path.join(self.tmppath, name)):
95 95 raise IOError
96 96
97 97 data, mode = self._getfile(name, rev)
98 98 self.modecache[(name, rev)] = mode
99 99
100 100 return data
101 101
102 102 def getmode(self, name, rev):
103 103 return self.modecache[(name, rev)]
104 104
105 105 def getchanges(self, rev):
106 106 self.modecache = {}
107 107 self._update(rev)
108 108 changes = []
109 109 copies = {}
110 110
111 111 for f in self.changes[rev].add_files:
112 112 changes.append((f, rev))
113 113
114 114 for f in self.changes[rev].mod_files:
115 115 changes.append((f, rev))
116 116
117 117 for f in self.changes[rev].del_files:
118 118 changes.append((f, rev))
119 119
120 120 for src in self.changes[rev].ren_files:
121 121 to = self.changes[rev].ren_files[src]
122 122 changes.append((src, rev))
123 123 changes.append((to, rev))
124 124 copies[src] = to
125 125
126 126 for src in self.changes[rev].ren_dirs:
127 127 to = self.changes[rev].ren_dirs[src]
128 128 chgs, cps = self._rendirchanges(src, to);
129 129 changes += [(f, rev) for f in chgs]
130 130 for c in cps:
131 131 copies[c] = cps[c]
132 132
133 133 changes.sort()
134 134 self.lastrev = rev
135 135
136 136 return changes, copies
137 137
138 138 def getcommit(self, rev):
139 139 changes = self.changes[rev]
140 140 return commit(author = changes.author, date = changes.date,
141 141 desc = changes.summary, parents = self.parents[rev])
142 142
143 143 def gettags(self):
144 144 return self.tags
145 145
146 146 def _execute(self, cmd, *args, **kwargs):
147 147 cmdline = [self.execmd, cmd]
148 148 cmdline += args
149 149 cmdline = [util.shellquote(arg) for arg in cmdline]
150 150 cmdline += ['>', util.nulldev, '2>', util.nulldev]
151 151 cmdline = util.quotecommand(' '.join(cmdline))
152 152 self.ui.debug(cmdline, '\n')
153 153 return os.system(cmdline)
154 154
155 155 def _update(self, rev):
156 156 if rev == 'base-0':
157 157 # Initialise 'base-0' revision
158 158 self._obtainrevision(rev)
159 159 else:
160 160 self.ui.debug(_('applying revision %s...\n' % rev))
161 161 revision = '%s--%s' % (self.treeversion, rev)
162 162 changeset, status = self.runlines('replay', '-d', self.tmppath,
163 163 revision)
164 164 if status:
165 165 # Something went wrong while merging (baz or tla
166 166 # issue?), get latest revision and try from there
167 167 shutil.rmtree(self.tmppath, ignore_errors=True)
168 168 self._obtainrevision(rev)
169 169 else:
170 170 old_rev = self.parents[rev][0]
171 171 self.ui.debug(_('computing changeset between %s and %s...\n' \
172 172 % (old_rev, rev)))
173 173 rev_a = '%s--%s' % (self.treeversion, old_rev)
174 174 rev_b = '%s--%s' % (self.treeversion, rev)
175 175 self._parsechangeset(changeset, rev)
176 176
177 177 def _getfile(self, name, rev):
178 178 mode = os.lstat(os.path.join(self.tmppath, name)).st_mode
179 179 if stat.S_ISLNK(mode):
180 180 data = os.readlink(os.path.join(self.tmppath, name))
181 181 mode = mode and 'l' or ''
182 182 else:
183 183 data = open(os.path.join(self.tmppath, name), 'rb').read()
184 184 mode = (mode & 0111) and 'x' or ''
185 185 return data, mode
186 186
187 187 def _exclude(self, name):
188 188 exclude = [ '{arch}', '.arch-ids', '.arch-inventory' ]
189 189 for exc in exclude:
190 190 if name.find(exc) != -1:
191 191 return True
192 192 return False
193 193
194 194 def _readcontents(self, path):
195 195 files = []
196 196 contents = os.listdir(path)
197 197 while len(contents) > 0:
198 198 c = contents.pop()
199 199 p = os.path.join(path, c)
200 200 # os.walk could be used, but here we avoid internal GNU
201 201 # Arch files and directories, thus saving a lot time.
202 202 if not self._exclude(p):
203 203 if os.path.isdir(p):
204 204 contents += [os.path.join(c, f) for f in os.listdir(p)]
205 205 else:
206 206 files.append(c)
207 207 return files
208 208
209 209 def _rendirchanges(self, src, dest):
210 210 changes = []
211 211 copies = {}
212 212 files = self._readcontents(os.path.join(self.tmppath, dest))
213 213 for f in files:
214 214 s = os.path.join(src, f)
215 215 d = os.path.join(dest, f)
216 216 changes.append(s)
217 217 changes.append(d)
218 218 copies[s] = d
219 219 return changes, copies
220 220
221 221 def _obtainrevision(self, rev):
222 222 self.ui.debug(_('obtaining revision %s...\n' % rev))
223 223 revision = '%s--%s' % (self.treeversion, rev)
224 224 output = self._execute('get', revision, self.tmppath)
225 225 self.checkexit(output)
226 226 self.ui.debug(_('analysing revision %s...\n' % rev))
227 227 files = self._readcontents(self.tmppath)
228 228 self.changes[rev].add_files += files
229 229
230 230 def _parsecatlog(self, data, rev):
231 231 summary = []
232 232 for l in data:
233 233 l = l.strip()
234 234 if summary:
235 235 summary.append(l)
236 236 elif l.startswith('Summary:'):
237 237 summary.append(l[len('Summary: '):])
238 238 elif l.startswith('Standard-date:'):
239 239 date = l[len('Standard-date: '):]
240 240 strdate = util.strdate(date, '%Y-%m-%d %H:%M:%S')
241 241 self.changes[rev].date = util.datestr(strdate)
242 242 elif l.startswith('Creator:'):
243 243 self.changes[rev].author = l[len('Creator: '):]
244 244 self.changes[rev].summary = '\n'.join(summary)
245 245
246 246 def _parsechangeset(self, data, rev):
247 247 for l in data:
248 248 l = l.strip()
249 249 # Added file (ignore added directory)
250 250 if l.startswith('A') and not l.startswith('A/'):
251 251 file = l[1:].strip()
252 252 if not self._exclude(file):
253 253 self.changes[rev].add_files.append(file)
254 254 # Deleted file (ignore deleted directory)
255 255 elif l.startswith('D') and not l.startswith('D/'):
256 256 file = l[1:].strip()
257 257 if not self._exclude(file):
258 258 self.changes[rev].del_files.append(file)
259 259 # Modified binary file
260 260 elif l.startswith('Mb'):
261 261 file = l[2:].strip()
262 262 if not self._exclude(file):
263 263 self.changes[rev].mod_files.append(file)
264 264 # Modified link
265 265 elif l.startswith('M->'):
266 266 file = l[3:].strip()
267 267 if not self._exclude(file):
268 268 self.changes[rev].mod_files.append(file)
269 269 # Modified file
270 270 elif l.startswith('M'):
271 271 file = l[1:].strip()
272 272 if not self._exclude(file):
273 273 self.changes[rev].mod_files.append(file)
274 274 # Renamed file (or link)
275 275 elif l.startswith('=>'):
276 276 files = l[2:].strip().split(' ')
277 277 if len(files) == 1:
278 278 files = l[2:].strip().split('\t')
279 279 if not self._exclude(files[0]) and not self._exclude(files[1]):
280 280 self.changes[rev].ren_files[files[0]] = files[1]
281 281 # Conversion from file to link or from link to file (modified)
282 282 elif l.startswith('ch'):
283 283 file = l[2:].strip()
284 284 if not self._exclude(file):
285 285 self.changes[rev].mod_files.append(file)
286 286 # Renamed directory
287 287 elif l.startswith('/>'):
288 288 dirs = l[2:].strip().split(' ')
289 289 if len(dirs) == 1:
290 290 dirs = l[2:].strip().split('\t')
291 291 if not self._exclude(dirs[0]) and not self._exclude(dirs[1]):
292 292 self.changes[rev].ren_dirs[dirs[0]] = dirs[1]
@@ -1,165 +1,169 b''
1 1 #!/usr/bin/env python
2 2 """Test the running system for features availability. Exit with zero
3 3 if all features are there, non-zero otherwise. If a feature name is
4 4 prefixed with "no-", the absence of feature is tested.
5 5 """
6 6 import optparse
7 7 import os
8 8 import re
9 9 import sys
10 10 import tempfile
11 11
12 12 tempprefix = 'hg-hghave-'
13 13
14 14 def matchoutput(cmd, regexp, ignorestatus=False):
15 15 """Return True if cmd executes successfully and its output
16 16 is matched by the supplied regular expression.
17 17 """
18 18 r = re.compile(regexp)
19 19 fh = os.popen(cmd)
20 20 s = fh.read()
21 21 ret = fh.close()
22 22 return (ignorestatus or ret is None) and r.search(s)
23 23
24 def has_baz():
25 return matchoutput('baz --version 2>&1', r'baz Bazaar version')
26
24 27 def has_cvs():
25 28 return matchoutput('cvs --version 2>&1', r'Concurrent Versions System')
26 29
27 30 def has_cvsps():
28 31 return matchoutput('cvsps -h -q 2>&1', r'cvsps version', True)
29 32
30 33 def has_darcs():
31 34 return matchoutput('darcs', 'darcs version', True)
32 35
33 36 def has_eol_in_paths():
34 37 try:
35 38 fd, path = tempfile.mkstemp(prefix=tempprefix, suffix='\n\r')
36 39 os.close(fd)
37 40 os.remove(path)
38 41 return True
39 42 except:
40 43 return False
41 44
42 45 def has_executablebit():
43 46 fd, path = tempfile.mkstemp(prefix=tempprefix)
44 47 os.close(fd)
45 48 try:
46 49 s = os.lstat(path).st_mode
47 50 os.chmod(path, s | 0100)
48 51 return (os.lstat(path).st_mode & 0100 != 0)
49 52 finally:
50 53 os.remove(path)
51 54
52 55 def has_fifo():
53 56 return hasattr(os, "mkfifo")
54 57
55 58 def has_hotshot():
56 59 try:
57 60 # hotshot.stats tests hotshot and many problematic dependencies
58 61 # like profile.
59 62 import hotshot.stats
60 63 return True
61 64 except ImportError:
62 65 return False
63 66
64 67 def has_lsprof():
65 68 try:
66 69 import _lsprof
67 70 return True
68 71 except ImportError:
69 72 return False
70 73
71 74 def has_git():
72 75 return matchoutput('git --version 2>&1', r'^git version')
73 76
74 77 def has_svn():
75 78 return matchoutput('svn --version 2>&1', r'^svn, version') and \
76 79 matchoutput('svnadmin --version 2>&1', r'^svnadmin, version')
77 80
78 81 def has_svn_bindings():
79 82 try:
80 83 import svn.core
81 84 return True
82 85 except ImportError:
83 86 return False
84 87
85 88 def has_symlink():
86 89 return hasattr(os, "symlink")
87 90
88 91 def has_unix_permissions():
89 92 d = tempfile.mkdtemp(prefix=tempprefix, dir=".")
90 93 try:
91 94 fname = os.path.join(d, 'foo')
92 95 for umask in (077, 007, 022):
93 96 os.umask(umask)
94 97 f = open(fname, 'w')
95 98 f.close()
96 99 mode = os.stat(fname).st_mode
97 100 os.unlink(fname)
98 101 if mode & 0777 != ~umask & 0666:
99 102 return False
100 103 return True
101 104 finally:
102 105 os.rmdir(d)
103 106
104 107 checks = {
108 "baz": (has_baz, "GNU Arch baz client"),
105 109 "cvs": (has_cvs, "cvs client"),
106 110 "cvsps": (has_cvsps, "cvsps utility"),
107 111 "darcs": (has_darcs, "darcs client"),
108 112 "eol-in-paths": (has_eol_in_paths, "end-of-lines in paths"),
109 113 "execbit": (has_executablebit, "executable bit"),
110 114 "fifo": (has_fifo, "named pipes"),
111 115 "git": (has_git, "git command line client"),
112 116 "hotshot": (has_hotshot, "python hotshot module"),
113 117 "lsprof": (has_lsprof, "python lsprof module"),
114 118 "svn": (has_svn, "subversion client and admin tools"),
115 119 "svn-bindings": (has_svn_bindings, "subversion python bindings"),
116 120 "symlink": (has_symlink, "symbolic links"),
117 121 "unix-permissions": (has_unix_permissions, "unix-style permissions"),
118 122 }
119 123
120 124 def list_features():
121 125 for name, feature in checks.iteritems():
122 126 desc = feature[1]
123 127 print name + ':', desc
124 128
125 129 parser = optparse.OptionParser("%prog [options] [features]")
126 130 parser.add_option("--list-features", action="store_true",
127 131 help="list available features")
128 132 parser.add_option("-q", "--quiet", action="store_true",
129 133 help="check features silently")
130 134
131 135 if __name__ == '__main__':
132 136 options, args = parser.parse_args()
133 137 if options.list_features:
134 138 list_features()
135 139 sys.exit(0)
136 140
137 141 quiet = options.quiet
138 142
139 143 failures = 0
140 144
141 145 def error(msg):
142 146 global failures
143 147 if not quiet:
144 148 sys.stderr.write(msg + '\n')
145 149 failures += 1
146 150
147 151 for feature in args:
148 152 negate = feature.startswith('no-')
149 153 if negate:
150 154 feature = feature[3:]
151 155
152 156 if feature not in checks:
153 157 error('skipped: unknown feature: ' + feature)
154 158 continue
155 159
156 160 check, desc = checks[feature]
157 161 if not negate and not check():
158 162 error('skipped: missing feature: ' + desc)
159 163 elif negate and check():
160 164 error('skipped: system supports %s' % desc)
161 165
162 166 if failures != 0:
163 167 sys.exit(1)
164 168
165 169
General Comments 0
You need to be logged in to leave comments. Login now