Mercurial > hgsubversion
annotate svnexternals.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 | 963d27a0b1c2 |
children | 4f4db3d2fdbb 75f082b5897e |
rev | line source |
---|---|
174
f80132c5fea5
Convert svn:externals properties into a .hgsvnexternals file
Patrick Mezard <pmezard@gmail.com>
parents:
diff
changeset
|
1 import cStringIO |
f80132c5fea5
Convert svn:externals properties into a .hgsvnexternals file
Patrick Mezard <pmezard@gmail.com>
parents:
diff
changeset
|
2 |
291
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
3 import os, re, shutil, stat, subprocess |
250
79349fd04836
utils: standardizing imported name to hgutil, our_util to util
Daniel Tang <dytang@cs.purdue.edu>
parents:
175
diff
changeset
|
4 from mercurial import util as hgutil |
291
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
5 from mercurial.i18n import _ |
174
f80132c5fea5
Convert svn:externals properties into a .hgsvnexternals file
Patrick Mezard <pmezard@gmail.com>
parents:
diff
changeset
|
6 |
f80132c5fea5
Convert svn:externals properties into a .hgsvnexternals file
Patrick Mezard <pmezard@gmail.com>
parents:
diff
changeset
|
7 class externalsfile(dict): |
f80132c5fea5
Convert svn:externals properties into a .hgsvnexternals file
Patrick Mezard <pmezard@gmail.com>
parents:
diff
changeset
|
8 """Map svn directories to lists of externals entries. |
f80132c5fea5
Convert svn:externals properties into a .hgsvnexternals file
Patrick Mezard <pmezard@gmail.com>
parents:
diff
changeset
|
9 """ |
f80132c5fea5
Convert svn:externals properties into a .hgsvnexternals file
Patrick Mezard <pmezard@gmail.com>
parents:
diff
changeset
|
10 def __init__(self): |
f80132c5fea5
Convert svn:externals properties into a .hgsvnexternals file
Patrick Mezard <pmezard@gmail.com>
parents:
diff
changeset
|
11 super(externalsfile, self).__init__() |
f80132c5fea5
Convert svn:externals properties into a .hgsvnexternals file
Patrick Mezard <pmezard@gmail.com>
parents:
diff
changeset
|
12 self.encoding = 'utf-8' |
f80132c5fea5
Convert svn:externals properties into a .hgsvnexternals file
Patrick Mezard <pmezard@gmail.com>
parents:
diff
changeset
|
13 |
f80132c5fea5
Convert svn:externals properties into a .hgsvnexternals file
Patrick Mezard <pmezard@gmail.com>
parents:
diff
changeset
|
14 def __setitem__(self, key, value): |
f80132c5fea5
Convert svn:externals properties into a .hgsvnexternals file
Patrick Mezard <pmezard@gmail.com>
parents:
diff
changeset
|
15 if value is None: |
f80132c5fea5
Convert svn:externals properties into a .hgsvnexternals file
Patrick Mezard <pmezard@gmail.com>
parents:
diff
changeset
|
16 value = [] |
f80132c5fea5
Convert svn:externals properties into a .hgsvnexternals file
Patrick Mezard <pmezard@gmail.com>
parents:
diff
changeset
|
17 elif isinstance(value, basestring): |
f80132c5fea5
Convert svn:externals properties into a .hgsvnexternals file
Patrick Mezard <pmezard@gmail.com>
parents:
diff
changeset
|
18 value = value.splitlines() |
f80132c5fea5
Convert svn:externals properties into a .hgsvnexternals file
Patrick Mezard <pmezard@gmail.com>
parents:
diff
changeset
|
19 if key == '.': |
f80132c5fea5
Convert svn:externals properties into a .hgsvnexternals file
Patrick Mezard <pmezard@gmail.com>
parents:
diff
changeset
|
20 key = '' |
f80132c5fea5
Convert svn:externals properties into a .hgsvnexternals file
Patrick Mezard <pmezard@gmail.com>
parents:
diff
changeset
|
21 if not value: |
f80132c5fea5
Convert svn:externals properties into a .hgsvnexternals file
Patrick Mezard <pmezard@gmail.com>
parents:
diff
changeset
|
22 if key in self: |
f80132c5fea5
Convert svn:externals properties into a .hgsvnexternals file
Patrick Mezard <pmezard@gmail.com>
parents:
diff
changeset
|
23 del self[key] |
f80132c5fea5
Convert svn:externals properties into a .hgsvnexternals file
Patrick Mezard <pmezard@gmail.com>
parents:
diff
changeset
|
24 else: |
f80132c5fea5
Convert svn:externals properties into a .hgsvnexternals file
Patrick Mezard <pmezard@gmail.com>
parents:
diff
changeset
|
25 super(externalsfile, self).__setitem__(key, value) |
f80132c5fea5
Convert svn:externals properties into a .hgsvnexternals file
Patrick Mezard <pmezard@gmail.com>
parents:
diff
changeset
|
26 |
f80132c5fea5
Convert svn:externals properties into a .hgsvnexternals file
Patrick Mezard <pmezard@gmail.com>
parents:
diff
changeset
|
27 def write(self): |
f80132c5fea5
Convert svn:externals properties into a .hgsvnexternals file
Patrick Mezard <pmezard@gmail.com>
parents:
diff
changeset
|
28 fp = cStringIO.StringIO() |
286
552deb1351ce
Replace mercurial.util.sort with sorted buildin (after mercurial a1a5a57efe90)
Martijn Pieters <mj@zopatista.com>
parents:
250
diff
changeset
|
29 for target in sorted(self): |
174
f80132c5fea5
Convert svn:externals properties into a .hgsvnexternals file
Patrick Mezard <pmezard@gmail.com>
parents:
diff
changeset
|
30 lines = self[target] |
f80132c5fea5
Convert svn:externals properties into a .hgsvnexternals file
Patrick Mezard <pmezard@gmail.com>
parents:
diff
changeset
|
31 if not lines: |
f80132c5fea5
Convert svn:externals properties into a .hgsvnexternals file
Patrick Mezard <pmezard@gmail.com>
parents:
diff
changeset
|
32 continue |
f80132c5fea5
Convert svn:externals properties into a .hgsvnexternals file
Patrick Mezard <pmezard@gmail.com>
parents:
diff
changeset
|
33 if not target: |
f80132c5fea5
Convert svn:externals properties into a .hgsvnexternals file
Patrick Mezard <pmezard@gmail.com>
parents:
diff
changeset
|
34 target = '.' |
f80132c5fea5
Convert svn:externals properties into a .hgsvnexternals file
Patrick Mezard <pmezard@gmail.com>
parents:
diff
changeset
|
35 fp.write('[%s]\n' % target) |
f80132c5fea5
Convert svn:externals properties into a .hgsvnexternals file
Patrick Mezard <pmezard@gmail.com>
parents:
diff
changeset
|
36 for l in lines: |
f80132c5fea5
Convert svn:externals properties into a .hgsvnexternals file
Patrick Mezard <pmezard@gmail.com>
parents:
diff
changeset
|
37 l = ' ' + l + '\n' |
f80132c5fea5
Convert svn:externals properties into a .hgsvnexternals file
Patrick Mezard <pmezard@gmail.com>
parents:
diff
changeset
|
38 fp.write(l) |
f80132c5fea5
Convert svn:externals properties into a .hgsvnexternals file
Patrick Mezard <pmezard@gmail.com>
parents:
diff
changeset
|
39 return fp.getvalue() |
f80132c5fea5
Convert svn:externals properties into a .hgsvnexternals file
Patrick Mezard <pmezard@gmail.com>
parents:
diff
changeset
|
40 |
f80132c5fea5
Convert svn:externals properties into a .hgsvnexternals file
Patrick Mezard <pmezard@gmail.com>
parents:
diff
changeset
|
41 def read(self, data): |
f80132c5fea5
Convert svn:externals properties into a .hgsvnexternals file
Patrick Mezard <pmezard@gmail.com>
parents:
diff
changeset
|
42 self.clear() |
f80132c5fea5
Convert svn:externals properties into a .hgsvnexternals file
Patrick Mezard <pmezard@gmail.com>
parents:
diff
changeset
|
43 fp = cStringIO.StringIO(data) |
f80132c5fea5
Convert svn:externals properties into a .hgsvnexternals file
Patrick Mezard <pmezard@gmail.com>
parents:
diff
changeset
|
44 dirs = {} |
f80132c5fea5
Convert svn:externals properties into a .hgsvnexternals file
Patrick Mezard <pmezard@gmail.com>
parents:
diff
changeset
|
45 target = None |
f80132c5fea5
Convert svn:externals properties into a .hgsvnexternals file
Patrick Mezard <pmezard@gmail.com>
parents:
diff
changeset
|
46 for line in fp.readlines(): |
f80132c5fea5
Convert svn:externals properties into a .hgsvnexternals file
Patrick Mezard <pmezard@gmail.com>
parents:
diff
changeset
|
47 if not line.strip(): |
f80132c5fea5
Convert svn:externals properties into a .hgsvnexternals file
Patrick Mezard <pmezard@gmail.com>
parents:
diff
changeset
|
48 continue |
f80132c5fea5
Convert svn:externals properties into a .hgsvnexternals file
Patrick Mezard <pmezard@gmail.com>
parents:
diff
changeset
|
49 if line.startswith('['): |
f80132c5fea5
Convert svn:externals properties into a .hgsvnexternals file
Patrick Mezard <pmezard@gmail.com>
parents:
diff
changeset
|
50 line = line.strip() |
f80132c5fea5
Convert svn:externals properties into a .hgsvnexternals file
Patrick Mezard <pmezard@gmail.com>
parents:
diff
changeset
|
51 if line[-1] != ']': |
250
79349fd04836
utils: standardizing imported name to hgutil, our_util to util
Daniel Tang <dytang@cs.purdue.edu>
parents:
175
diff
changeset
|
52 raise hgutil.Abort('invalid externals section name: %s' % line) |
174
f80132c5fea5
Convert svn:externals properties into a .hgsvnexternals file
Patrick Mezard <pmezard@gmail.com>
parents:
diff
changeset
|
53 target = line[1:-1] |
f80132c5fea5
Convert svn:externals properties into a .hgsvnexternals file
Patrick Mezard <pmezard@gmail.com>
parents:
diff
changeset
|
54 if target == '.': |
f80132c5fea5
Convert svn:externals properties into a .hgsvnexternals file
Patrick Mezard <pmezard@gmail.com>
parents:
diff
changeset
|
55 target = '' |
f80132c5fea5
Convert svn:externals properties into a .hgsvnexternals file
Patrick Mezard <pmezard@gmail.com>
parents:
diff
changeset
|
56 elif line.startswith(' '): |
f80132c5fea5
Convert svn:externals properties into a .hgsvnexternals file
Patrick Mezard <pmezard@gmail.com>
parents:
diff
changeset
|
57 line = line.rstrip('\n') |
f80132c5fea5
Convert svn:externals properties into a .hgsvnexternals file
Patrick Mezard <pmezard@gmail.com>
parents:
diff
changeset
|
58 if target is None or not line: |
f80132c5fea5
Convert svn:externals properties into a .hgsvnexternals file
Patrick Mezard <pmezard@gmail.com>
parents:
diff
changeset
|
59 continue |
f80132c5fea5
Convert svn:externals properties into a .hgsvnexternals file
Patrick Mezard <pmezard@gmail.com>
parents:
diff
changeset
|
60 self.setdefault(target, []).append(line[1:]) |
291
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
61 |
175
2412800b1258
Support svn:externals changes via .hgsvnexternals updates
Patrick Mezard <pmezard@gmail.com>
parents:
174
diff
changeset
|
62 def diff(ext1, ext2): |
2412800b1258
Support svn:externals changes via .hgsvnexternals updates
Patrick Mezard <pmezard@gmail.com>
parents:
174
diff
changeset
|
63 """Compare 2 externalsfile and yield tuples like (dir, value1, value2) |
2412800b1258
Support svn:externals changes via .hgsvnexternals updates
Patrick Mezard <pmezard@gmail.com>
parents:
174
diff
changeset
|
64 where value1 is the external value in ext1 for dir or None, and |
2412800b1258
Support svn:externals changes via .hgsvnexternals updates
Patrick Mezard <pmezard@gmail.com>
parents:
174
diff
changeset
|
65 value2 the same in ext2. |
2412800b1258
Support svn:externals changes via .hgsvnexternals updates
Patrick Mezard <pmezard@gmail.com>
parents:
174
diff
changeset
|
66 """ |
2412800b1258
Support svn:externals changes via .hgsvnexternals updates
Patrick Mezard <pmezard@gmail.com>
parents:
174
diff
changeset
|
67 for d in ext1: |
2412800b1258
Support svn:externals changes via .hgsvnexternals updates
Patrick Mezard <pmezard@gmail.com>
parents:
174
diff
changeset
|
68 if d not in ext2: |
2412800b1258
Support svn:externals changes via .hgsvnexternals updates
Patrick Mezard <pmezard@gmail.com>
parents:
174
diff
changeset
|
69 yield d, '\n'.join(ext1[d]), None |
2412800b1258
Support svn:externals changes via .hgsvnexternals updates
Patrick Mezard <pmezard@gmail.com>
parents:
174
diff
changeset
|
70 elif ext1[d] != ext2[d]: |
2412800b1258
Support svn:externals changes via .hgsvnexternals updates
Patrick Mezard <pmezard@gmail.com>
parents:
174
diff
changeset
|
71 yield d, '\n'.join(ext1[d]), '\n'.join(ext2[d]) |
2412800b1258
Support svn:externals changes via .hgsvnexternals updates
Patrick Mezard <pmezard@gmail.com>
parents:
174
diff
changeset
|
72 for d in ext2: |
2412800b1258
Support svn:externals changes via .hgsvnexternals updates
Patrick Mezard <pmezard@gmail.com>
parents:
174
diff
changeset
|
73 if d not in ext1: |
2412800b1258
Support svn:externals changes via .hgsvnexternals updates
Patrick Mezard <pmezard@gmail.com>
parents:
174
diff
changeset
|
74 yield d, None, '\n'.join(ext2[d]) |
291
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
75 |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
76 class BadDefinition(Exception): |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
77 pass |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
78 |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
79 re_defold = re.compile(r'^(.*?)\s+(?:-r\s*(\d+)\s+)?([a-zA-Z]+://.*)$') |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
80 re_defnew = re.compile(r'^(?:-r\s*(\d+)\s+)?((?:[a-zA-Z]+://|\^/).*)\s+(.*)$') |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
81 re_scheme = re.compile(r'^[a-zA-Z]+://') |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
82 |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
83 def parsedefinition(line): |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
84 """Parse an external definition line, return a tuple (path, rev, source) |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
85 or raise BadDefinition. |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
86 """ |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
87 # The parsing is probably not correct wrt path with whitespaces or |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
88 # potential quotes. svn documentation is not really talkative about |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
89 # these either. |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
90 line = line.strip() |
315
963d27a0b1c2
svnexternals: do not use peg revisions as --rev replacements
Patrick Mezard <pmezard@gmail.com>
parents:
291
diff
changeset
|
91 pegrev = None |
291
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
92 m = re_defnew.search(line) |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
93 if m: |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
94 rev, source, path = m.group(1, 2, 3) |
315
963d27a0b1c2
svnexternals: do not use peg revisions as --rev replacements
Patrick Mezard <pmezard@gmail.com>
parents:
291
diff
changeset
|
95 if '@' in source: |
963d27a0b1c2
svnexternals: do not use peg revisions as --rev replacements
Patrick Mezard <pmezard@gmail.com>
parents:
291
diff
changeset
|
96 source, pegrev = source.rsplit('@', 1) |
291
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
97 else: |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
98 m = re_defold.search(line) |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
99 if not m: |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
100 raise BadDefinition() |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
101 path, rev, source = m.group(1, 2, 3) |
315
963d27a0b1c2
svnexternals: do not use peg revisions as --rev replacements
Patrick Mezard <pmezard@gmail.com>
parents:
291
diff
changeset
|
102 return (path, rev, source, pegrev) |
291
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
103 |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
104 def parsedefinitions(ui, repo, svnroot, exts): |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
105 """Return (targetdir, revision, source) tuples. Fail if nested |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
106 targetdirs are detected. source is an svn project URL. |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
107 """ |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
108 defs = [] |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
109 for base in sorted(exts): |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
110 for line in exts[base]: |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
111 try: |
315
963d27a0b1c2
svnexternals: do not use peg revisions as --rev replacements
Patrick Mezard <pmezard@gmail.com>
parents:
291
diff
changeset
|
112 path, rev, source, pegrev = parsedefinition(line) |
291
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
113 except BadDefinition: |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
114 ui.warn(_('ignoring invalid external definition: %r' % line)) |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
115 continue |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
116 if re_scheme.search(source): |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
117 pass |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
118 elif source.startswith('^/'): |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
119 source = svnroot + source[1:] |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
120 else: |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
121 ui.warn(_('ignoring unsupported non-fully qualified external: %r' % source)) |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
122 continue |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
123 wpath = hgutil.pconvert(os.path.join(base, path)) |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
124 wpath = hgutil.canonpath(repo.root, '', wpath) |
315
963d27a0b1c2
svnexternals: do not use peg revisions as --rev replacements
Patrick Mezard <pmezard@gmail.com>
parents:
291
diff
changeset
|
125 defs.append((wpath, rev, source, pegrev)) |
291
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
126 # Check target dirs are not nested |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
127 defs.sort() |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
128 for i, d in enumerate(defs): |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
129 for d2 in defs[i+1:]: |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
130 if d2[0].startswith(d[0] + '/'): |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
131 raise hgutil.Abort(_('external directories cannot nest:\n%s\n%s') |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
132 % (d[0], d2[0])) |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
133 return defs |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
134 |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
135 def computeactions(ui, repo, svnroot, ext1, ext2): |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
136 |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
137 def listdefs(data): |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
138 defs = {} |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
139 exts = externalsfile() |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
140 exts.read(data) |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
141 for d in parsedefinitions(ui, repo, svnroot, exts): |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
142 defs[d[0]] = d |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
143 return defs |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
144 |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
145 ext1 = listdefs(ext1) |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
146 ext2 = listdefs(ext2) |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
147 for wp1 in ext1: |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
148 if wp1 in ext2: |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
149 yield 'u', ext2[wp1] |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
150 else: |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
151 yield 'd', ext1[wp1] |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
152 for wp2 in ext2: |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
153 if wp2 not in ext1: |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
154 yield 'u', ext2[wp2] |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
155 |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
156 def getsvninfo(svnurl): |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
157 """Return a tuple (url, root) for supplied svn URL or working |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
158 directory path. |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
159 """ |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
160 # Yes, this is ugly, but good enough for now |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
161 args = ['svn', 'info', '--xml', svnurl] |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
162 shell = os.name == 'nt' |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
163 p = subprocess.Popen(args, stdout=subprocess.PIPE, shell=shell) |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
164 stdout = p.communicate()[0] |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
165 if p.returncode: |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
166 raise hgutil.Abort(_('cannot get information about %s') |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
167 % svnurl) |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
168 m = re.search(r'<root>(.*)</root>', stdout, re.S) |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
169 if not m: |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
170 raise hgutil.Abort(_('cannot find SVN repository root from %s') |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
171 % svnurl) |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
172 root = m.group(1).rstrip('/') |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
173 |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
174 m = re.search(r'<url>(.*)</url>', stdout, re.S) |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
175 if not m: |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
176 raise hgutil.Abort(_('cannot find SVN repository URL from %s') % svnurl) |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
177 url = m.group(1) |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
178 |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
179 m = re.search(r'<entry[^>]+revision="([^"]+)"', stdout, re.S) |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
180 if not m: |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
181 raise hgutil.Abort(_('cannot find SVN revision from %s') % svnurl) |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
182 rev = m.group(1) |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
183 return url, root, rev |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
184 |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
185 class externalsupdater: |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
186 def __init__(self, ui, repo): |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
187 self.repo = repo |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
188 self.ui = ui |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
189 |
315
963d27a0b1c2
svnexternals: do not use peg revisions as --rev replacements
Patrick Mezard <pmezard@gmail.com>
parents:
291
diff
changeset
|
190 def update(self, wpath, rev, source, pegrev): |
291
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
191 path = self.repo.wjoin(wpath) |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
192 revspec = [] |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
193 if rev: |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
194 revspec = ['-r', rev] |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
195 if os.path.isdir(path): |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
196 exturl, extroot, extrev = getsvninfo(path) |
315
963d27a0b1c2
svnexternals: do not use peg revisions as --rev replacements
Patrick Mezard <pmezard@gmail.com>
parents:
291
diff
changeset
|
197 # Comparing the source paths is not enough, but I don't |
963d27a0b1c2
svnexternals: do not use peg revisions as --rev replacements
Patrick Mezard <pmezard@gmail.com>
parents:
291
diff
changeset
|
198 # know how to compare path+pegrev. The following update |
963d27a0b1c2
svnexternals: do not use peg revisions as --rev replacements
Patrick Mezard <pmezard@gmail.com>
parents:
291
diff
changeset
|
199 # might fail if the path was replaced by another unrelated |
963d27a0b1c2
svnexternals: do not use peg revisions as --rev replacements
Patrick Mezard <pmezard@gmail.com>
parents:
291
diff
changeset
|
200 # one. It can be fixed manually by deleting the externals |
963d27a0b1c2
svnexternals: do not use peg revisions as --rev replacements
Patrick Mezard <pmezard@gmail.com>
parents:
291
diff
changeset
|
201 # and updating again. |
291
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
202 if source == exturl: |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
203 if extrev != rev: |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
204 self.ui.status(_('updating external on %s@%s\n') % |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
205 (wpath, rev or 'HEAD')) |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
206 cwd = os.path.join(self.repo.root, path) |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
207 self.svn(['update'] + revspec, cwd) |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
208 return |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
209 self.delete(wpath) |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
210 cwd, dest = os.path.split(path) |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
211 cwd = os.path.join(self.repo.root, cwd) |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
212 if not os.path.isdir(cwd): |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
213 os.makedirs(cwd) |
315
963d27a0b1c2
svnexternals: do not use peg revisions as --rev replacements
Patrick Mezard <pmezard@gmail.com>
parents:
291
diff
changeset
|
214 if not pegrev and rev: |
963d27a0b1c2
svnexternals: do not use peg revisions as --rev replacements
Patrick Mezard <pmezard@gmail.com>
parents:
291
diff
changeset
|
215 pegrev = rev |
963d27a0b1c2
svnexternals: do not use peg revisions as --rev replacements
Patrick Mezard <pmezard@gmail.com>
parents:
291
diff
changeset
|
216 if pegrev: |
963d27a0b1c2
svnexternals: do not use peg revisions as --rev replacements
Patrick Mezard <pmezard@gmail.com>
parents:
291
diff
changeset
|
217 source = '%s@%s' % (source, pegrev) |
291
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
218 self.ui.status(_('fetching external %s@%s\n') % (wpath, rev or 'HEAD')) |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
219 self.svn(['co'] + revspec + [source, dest], cwd) |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
220 |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
221 def delete(self, wpath): |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
222 path = self.repo.wjoin(wpath) |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
223 if os.path.isdir(path): |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
224 self.ui.status(_('removing external %s\n') % wpath) |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
225 |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
226 def onerror(function, path, excinfo): |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
227 if function is not os.remove: |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
228 raise |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
229 # read-only files cannot be unlinked under Windows |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
230 s = os.stat(path) |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
231 if (s.st_mode & stat.S_IWRITE) != 0: |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
232 raise |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
233 os.chmod(path, stat.S_IMODE(s.st_mode) | stat.S_IWRITE) |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
234 os.remove(path) |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
235 |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
236 shutil.rmtree(path, onerror=onerror) |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
237 return 1 |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
238 |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
239 def svn(self, args, cwd): |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
240 args = ['svn'] + args |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
241 self.ui.debug(_('updating externals: %r, cwd=%s\n') % (args, cwd)) |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
242 shell = os.name == 'nt' |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
243 subprocess.check_call(args, cwd=cwd, shell=shell) |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
244 |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
245 def updateexternals(ui, args, repo, **opts): |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
246 """update repository externals |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
247 """ |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
248 if len(args) > 1: |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
249 raise hgutil.Abort(_('updateexternals expects at most one changeset')) |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
250 node = None |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
251 if args: |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
252 node = args[0] |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
253 |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
254 try: |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
255 svnurl = file(repo.join('svn/url'), 'rb').read() |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
256 except: |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
257 raise hgutil.Abort(_('failed to retrieve original svn URL')) |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
258 svnroot = getsvninfo(svnurl)[1] |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
259 |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
260 # Retrieve current externals status |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
261 try: |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
262 oldext = file(repo.join('svn/externals'), 'rb').read() |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
263 except IOError: |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
264 oldext = '' |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
265 newext = '' |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
266 ctx = repo[node] |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
267 if '.hgsvnexternals' in ctx: |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
268 newext = ctx['.hgsvnexternals'].data() |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
269 |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
270 updater = externalsupdater(ui, repo) |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
271 actions = computeactions(ui, repo, svnroot, oldext, newext) |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
272 for action, ext in actions: |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
273 if action == 'u': |
315
963d27a0b1c2
svnexternals: do not use peg revisions as --rev replacements
Patrick Mezard <pmezard@gmail.com>
parents:
291
diff
changeset
|
274 updater.update(ext[0], ext[1], ext[2], ext[3]) |
291
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
275 elif action == 'd': |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
276 updater.delete(ext[0]) |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
277 else: |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
278 raise hgutil.Abort(_('unknown update actions: %r') % action) |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
279 |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
280 file(repo.join('svn/externals'), 'wb').write(newext) |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
281 |