##// END OF EJS Templates
Mercurial 4.1 compatibility (#24999)...
Toshi MARUYAMA -
r15947:79fb434fecab
parent child
Show More
@@ -1,225 +1,226
1 1 # redminehelper: Redmine helper extension for Mercurial
2 2 #
3 3 # Copyright 2010 Alessio Franceschelli (alefranz.net)
4 4 # Copyright 2010-2011 Yuya Nishihara <yuya@tcha.org>
5 5 #
6 6 # This software may be used and distributed according to the terms of the
7 7 # GNU General Public License version 2 or any later version.
8 8 """helper commands for Redmine to reduce the number of hg calls
9 9
10 10 To test this extension, please try::
11 11
12 12 $ hg --config extensions.redminehelper=redminehelper.py rhsummary
13 13
14 14 I/O encoding:
15 15
16 16 :file path: urlencoded, raw string
17 17 :tag name: utf-8
18 18 :branch name: utf-8
19 19 :node: hex string
20 20
21 21 Output example of rhsummary::
22 22
23 23 <?xml version="1.0"?>
24 24 <rhsummary>
25 25 <repository root="/foo/bar">
26 26 <tip revision="1234" node="abcdef0123..."/>
27 27 <tag revision="123" node="34567abc..." name="1.1.1"/>
28 28 <branch .../>
29 29 ...
30 30 </repository>
31 31 </rhsummary>
32 32
33 33 Output example of rhmanifest::
34 34
35 35 <?xml version="1.0"?>
36 36 <rhmanifest>
37 37 <repository root="/foo/bar">
38 38 <manifest revision="1234" path="lib">
39 39 <file name="diff.rb" revision="123" node="34567abc..." time="12345"
40 40 size="100"/>
41 41 ...
42 42 <dir name="redmine"/>
43 43 ...
44 44 </manifest>
45 45 </repository>
46 46 </rhmanifest>
47 47 """
48 48 import re, time, cgi, urllib
49 49 from mercurial import cmdutil, commands, node, error, hg
50 50
51 cmdtable = {}
52 command = cmdutil.command(cmdtable)
53
51 54 _x = cgi.escape
52 55 _u = lambda s: cgi.escape(urllib.quote(s))
53 56
54 57 def _tip(ui, repo):
55 58 # see mercurial/commands.py:tip
56 59 def tiprev():
57 60 try:
58 61 return len(repo) - 1
59 62 except TypeError: # Mercurial < 1.1
60 63 return repo.changelog.count() - 1
61 64 tipctx = repo.changectx(tiprev())
62 65 ui.write('<tip revision="%d" node="%s"/>\n'
63 66 % (tipctx.rev(), _x(node.hex(tipctx.node()))))
64 67
65 68 _SPECIAL_TAGS = ('tip',)
66 69
67 70 def _tags(ui, repo):
68 71 # see mercurial/commands.py:tags
69 72 for t, n in reversed(repo.tagslist()):
70 73 if t in _SPECIAL_TAGS:
71 74 continue
72 75 try:
73 76 r = repo.changelog.rev(n)
74 77 except error.LookupError:
75 78 continue
76 79 ui.write('<tag revision="%d" node="%s" name="%s"/>\n'
77 80 % (r, _x(node.hex(n)), _x(t)))
78 81
79 82 def _branches(ui, repo):
80 83 # see mercurial/commands.py:branches
81 84 def iterbranches():
82 85 if getattr(repo, 'branchtags', None) is not None:
83 86 # Mercurial < 2.9
84 87 for t, n in repo.branchtags().iteritems():
85 88 yield t, n, repo.changelog.rev(n)
86 89 else:
87 90 for tag, heads, tip, isclosed in repo.branchmap().iterbranches():
88 91 yield tag, tip, repo.changelog.rev(tip)
89 92 def branchheads(branch):
90 93 try:
91 94 return repo.branchheads(branch, closed=False)
92 95 except TypeError: # Mercurial < 1.2
93 96 return repo.branchheads(branch)
94 97 for t, n, r in sorted(iterbranches(), key=lambda e: e[2], reverse=True):
95 98 if repo.lookup(r) in branchheads(t):
96 99 ui.write('<branch revision="%d" node="%s" name="%s"/>\n'
97 100 % (r, _x(node.hex(n)), _x(t)))
98 101
99 102 def _manifest(ui, repo, path, rev):
100 103 ctx = repo.changectx(rev)
101 104 ui.write('<manifest revision="%d" path="%s">\n'
102 105 % (ctx.rev(), _u(path)))
103 106
104 107 known = set()
105 108 pathprefix = (path.rstrip('/') + '/').lstrip('/')
106 109 for f, n in sorted(ctx.manifest().iteritems(), key=lambda e: e[0]):
107 110 if not f.startswith(pathprefix):
108 111 continue
109 112 name = re.sub(r'/.*', '/', f[len(pathprefix):])
110 113 if name in known:
111 114 continue
112 115 known.add(name)
113 116
114 117 if name.endswith('/'):
115 118 ui.write('<dir name="%s"/>\n'
116 119 % _x(urllib.quote(name[:-1])))
117 120 else:
118 121 fctx = repo.filectx(f, fileid=n)
119 122 tm, tzoffset = fctx.date()
120 123 ui.write('<file name="%s" revision="%d" node="%s" '
121 124 'time="%d" size="%d"/>\n'
122 125 % (_u(name), fctx.rev(), _x(node.hex(fctx.node())),
123 126 tm, fctx.size(), ))
124 127
125 128 ui.write('</manifest>\n')
126 129
130 @command('rhannotate',
131 [('r', 'rev', '', 'revision'),
132 ('u', 'user', None, 'list the author (long with -v)'),
133 ('n', 'number', None, 'list the revision number (default)'),
134 ('c', 'changeset', None, 'list the changeset'),
135 ],
136 'hg rhannotate [-r REV] [-u] [-n] [-c] FILE...')
127 137 def rhannotate(ui, repo, *pats, **opts):
128 138 rev = urllib.unquote_plus(opts.pop('rev', None))
129 139 opts['rev'] = rev
130 140 return commands.annotate(ui, repo, *map(urllib.unquote_plus, pats), **opts)
131 141
142 @command('rhcat',
143 [('r', 'rev', '', 'revision')],
144 'hg rhcat ([-r REV] ...) FILE...')
132 145 def rhcat(ui, repo, file1, *pats, **opts):
133 146 rev = urllib.unquote_plus(opts.pop('rev', None))
134 147 opts['rev'] = rev
135 148 return commands.cat(ui, repo, urllib.unquote_plus(file1), *map(urllib.unquote_plus, pats), **opts)
136 149
150 @command('rhdiff',
151 [('r', 'rev', [], 'revision'),
152 ('c', 'change', '', 'change made by revision')],
153 'hg rhdiff ([-c REV] | [-r REV] ...) [FILE]...')
137 154 def rhdiff(ui, repo, *pats, **opts):
138 155 """diff repository (or selected files)"""
139 156 change = opts.pop('change', None)
140 157 if change: # add -c option for Mercurial<1.1
141 158 base = repo.changectx(change).parents()[0].rev()
142 159 opts['rev'] = [str(base), change]
143 160 opts['nodates'] = True
144 161 return commands.diff(ui, repo, *map(urllib.unquote_plus, pats), **opts)
145 162
163 @command('rhlog',
164 [
165 ('r', 'rev', [], 'show the specified revision'),
166 ('b', 'branch', [],
167 'show changesets within the given named branch'),
168 ('l', 'limit', '',
169 'limit number of changes displayed'),
170 ('d', 'date', '',
171 'show revisions matching date spec'),
172 ('u', 'user', [],
173 'revisions committed by user'),
174 ('', 'from', '',
175 ''),
176 ('', 'to', '',
177 ''),
178 ('', 'rhbranch', '',
179 ''),
180 ('', 'template', '',
181 'display with template')],
182 'hg rhlog [OPTION]... [FILE]')
146 183 def rhlog(ui, repo, *pats, **opts):
147 184 rev = opts.pop('rev')
148 185 bra0 = opts.pop('branch')
149 186 from_rev = urllib.unquote_plus(opts.pop('from', None))
150 187 to_rev = urllib.unquote_plus(opts.pop('to' , None))
151 188 bra = urllib.unquote_plus(opts.pop('rhbranch', None))
152 189 from_rev = from_rev.replace('"', '\\"')
153 190 to_rev = to_rev.replace('"', '\\"')
154 191 if hg.util.version() >= '1.6':
155 192 opts['rev'] = ['"%s":"%s"' % (from_rev, to_rev)]
156 193 else:
157 194 opts['rev'] = ['%s:%s' % (from_rev, to_rev)]
158 195 opts['branch'] = [bra]
159 196 return commands.log(ui, repo, *map(urllib.unquote_plus, pats), **opts)
160 197
198 @command('rhmanifest',
199 [('r', 'rev', '', 'show the specified revision')],
200 'hg rhmanifest [-r REV] [PATH]')
161 201 def rhmanifest(ui, repo, path='', **opts):
162 202 """output the sub-manifest of the specified directory"""
163 203 ui.write('<?xml version="1.0"?>\n')
164 204 ui.write('<rhmanifest>\n')
165 205 ui.write('<repository root="%s">\n' % _u(repo.root))
166 206 try:
167 207 _manifest(ui, repo, urllib.unquote_plus(path), urllib.unquote_plus(opts.get('rev')))
168 208 finally:
169 209 ui.write('</repository>\n')
170 210 ui.write('</rhmanifest>\n')
171 211
212 @command('rhsummary',[], 'hg rhsummary')
172 213 def rhsummary(ui, repo, **opts):
173 214 """output the summary of the repository"""
174 215 ui.write('<?xml version="1.0"?>\n')
175 216 ui.write('<rhsummary>\n')
176 217 ui.write('<repository root="%s">\n' % _u(repo.root))
177 218 try:
178 219 _tip(ui, repo)
179 220 _tags(ui, repo)
180 221 _branches(ui, repo)
181 222 # TODO: bookmarks in core (Mercurial>=1.8)
182 223 finally:
183 224 ui.write('</repository>\n')
184 225 ui.write('</rhsummary>\n')
185 226
186 cmdtable = {
187 'rhannotate': (rhannotate,
188 [('r', 'rev', '', 'revision'),
189 ('u', 'user', None, 'list the author (long with -v)'),
190 ('n', 'number', None, 'list the revision number (default)'),
191 ('c', 'changeset', None, 'list the changeset'),
192 ],
193 'hg rhannotate [-r REV] [-u] [-n] [-c] FILE...'),
194 'rhcat': (rhcat,
195 [('r', 'rev', '', 'revision')],
196 'hg rhcat ([-r REV] ...) FILE...'),
197 'rhdiff': (rhdiff,
198 [('r', 'rev', [], 'revision'),
199 ('c', 'change', '', 'change made by revision')],
200 'hg rhdiff ([-c REV] | [-r REV] ...) [FILE]...'),
201 'rhlog': (rhlog,
202 [
203 ('r', 'rev', [], 'show the specified revision'),
204 ('b', 'branch', [],
205 'show changesets within the given named branch'),
206 ('l', 'limit', '',
207 'limit number of changes displayed'),
208 ('d', 'date', '',
209 'show revisions matching date spec'),
210 ('u', 'user', [],
211 'revisions committed by user'),
212 ('', 'from', '',
213 ''),
214 ('', 'to', '',
215 ''),
216 ('', 'rhbranch', '',
217 ''),
218 ('', 'template', '',
219 'display with template')],
220 'hg rhlog [OPTION]... [FILE]'),
221 'rhmanifest': (rhmanifest,
222 [('r', 'rev', '', 'show the specified revision')],
223 'hg rhmanifest [-r REV] [PATH]'),
224 'rhsummary': (rhsummary, [], 'hg rhsummary'),
225 }
General Comments 0
You need to be logged in to leave comments. Login now