Mercurial > hg
comparison mercurial/templatekw.py @ 43076:2372284d9457
formatting: blacken the codebase
This is using my patch to black
(https://github.com/psf/black/pull/826) so we don't un-wrap collection
literals.
Done with:
hg files 'set:**.py - mercurial/thirdparty/** - "contrib/python-zstandard/**"' | xargs black -S
# skip-blame mass-reformatting only
# no-check-commit reformats foo_bar functions
Differential Revision: https://phab.mercurial-scm.org/D6971
author | Augie Fackler <augie@google.com> |
---|---|
date | Sun, 06 Oct 2019 09:45:02 -0400 |
parents | 88ba0ff94605 |
children | 687b865b95ad |
comparison
equal
deleted
inserted
replaced
43075:57875cf423c9 | 43076:2372284d9457 |
---|---|
27 registrar, | 27 registrar, |
28 scmutil, | 28 scmutil, |
29 templateutil, | 29 templateutil, |
30 util, | 30 util, |
31 ) | 31 ) |
32 from .utils import ( | 32 from .utils import stringutil |
33 stringutil, | |
34 ) | |
35 | 33 |
36 _hybrid = templateutil.hybrid | 34 _hybrid = templateutil.hybrid |
37 hybriddict = templateutil.hybriddict | 35 hybriddict = templateutil.hybriddict |
38 hybridlist = templateutil.hybridlist | 36 hybridlist = templateutil.hybridlist |
39 compatdict = templateutil.compatdict | 37 compatdict = templateutil.compatdict |
40 compatlist = templateutil.compatlist | 38 compatlist = templateutil.compatlist |
41 _showcompatlist = templateutil._showcompatlist | 39 _showcompatlist = templateutil._showcompatlist |
40 | |
42 | 41 |
43 def getlatesttags(context, mapping, pattern=None): | 42 def getlatesttags(context, mapping, pattern=None): |
44 '''return date, distance and name for the latest tag of rev''' | 43 '''return date, distance and name for the latest tag of rev''' |
45 repo = context.resource(mapping, 'repo') | 44 repo = context.resource(mapping, 'repo') |
46 ctx = context.resource(mapping, 'ctx') | 45 ctx = context.resource(mapping, 'ctx') |
64 while todo: | 63 while todo: |
65 rev = todo.pop() | 64 rev = todo.pop() |
66 if rev in latesttags: | 65 if rev in latesttags: |
67 continue | 66 continue |
68 ctx = repo[rev] | 67 ctx = repo[rev] |
69 tags = [t for t in ctx.tags() | 68 tags = [ |
70 if (repo.tagtype(t) and repo.tagtype(t) != 'local' | 69 t |
71 and match(t))] | 70 for t in ctx.tags() |
71 if (repo.tagtype(t) and repo.tagtype(t) != 'local' and match(t)) | |
72 ] | |
72 if tags: | 73 if tags: |
73 latesttags[rev] = ctx.date()[0], 0, [t for t in sorted(tags)] | 74 latesttags[rev] = ctx.date()[0], 0, [t for t in sorted(tags)] |
74 continue | 75 continue |
75 try: | 76 try: |
76 ptags = [latesttags[p.rev()] for p in ctx.parents()] | 77 ptags = [latesttags[p.rev()] for p in ctx.parents()] |
78 if ptags[0][2] == ptags[1][2]: | 79 if ptags[0][2] == ptags[1][2]: |
79 # The tuples are laid out so the right one can be found by | 80 # The tuples are laid out so the right one can be found by |
80 # comparison in this case. | 81 # comparison in this case. |
81 pdate, pdist, ptag = max(ptags) | 82 pdate, pdist, ptag = max(ptags) |
82 else: | 83 else: |
84 | |
83 def key(x): | 85 def key(x): |
84 tag = x[2][0] | 86 tag = x[2][0] |
85 if ctx.rev() is None: | 87 if ctx.rev() is None: |
86 # only() doesn't support wdir | 88 # only() doesn't support wdir |
87 prevs = [c.rev() for c in ctx.parents()] | 89 prevs = [c.rev() for c in ctx.parents()] |
91 changes = repo.revs('only(%d, %s)', ctx.rev(), tag) | 93 changes = repo.revs('only(%d, %s)', ctx.rev(), tag) |
92 changessincetag = len(changes) | 94 changessincetag = len(changes) |
93 # Smallest number of changes since tag wins. Date is | 95 # Smallest number of changes since tag wins. Date is |
94 # used as tiebreaker. | 96 # used as tiebreaker. |
95 return [-changessincetag, x[0]] | 97 return [-changessincetag, x[0]] |
98 | |
96 pdate, pdist, ptag = max(ptags, key=key) | 99 pdate, pdist, ptag = max(ptags, key=key) |
97 else: | 100 else: |
98 pdate, pdist, ptag = ptags[0] | 101 pdate, pdist, ptag = ptags[0] |
99 except KeyError: | 102 except KeyError: |
100 # Cache miss - recurse | 103 # Cache miss - recurse |
102 todo.extend(p.rev() for p in ctx.parents()) | 105 todo.extend(p.rev() for p in ctx.parents()) |
103 continue | 106 continue |
104 latesttags[rev] = pdate, pdist + 1, ptag | 107 latesttags[rev] = pdate, pdist + 1, ptag |
105 return latesttags[rev] | 108 return latesttags[rev] |
106 | 109 |
110 | |
107 def getlogcolumns(): | 111 def getlogcolumns(): |
108 """Return a dict of log column labels""" | 112 """Return a dict of log column labels""" |
109 _ = pycompat.identity # temporarily disable gettext | 113 _ = pycompat.identity # temporarily disable gettext |
110 # i18n: column positioning for "hg log" | 114 # i18n: column positioning for "hg log" |
111 columns = _('bookmark: %s\n' | 115 columns = _( |
112 'branch: %s\n' | 116 'bookmark: %s\n' |
113 'changeset: %s\n' | 117 'branch: %s\n' |
114 'copies: %s\n' | 118 'changeset: %s\n' |
115 'date: %s\n' | 119 'copies: %s\n' |
116 'extra: %s=%s\n' | 120 'date: %s\n' |
117 'files+: %s\n' | 121 'extra: %s=%s\n' |
118 'files-: %s\n' | 122 'files+: %s\n' |
119 'files: %s\n' | 123 'files-: %s\n' |
120 'instability: %s\n' | 124 'files: %s\n' |
121 'manifest: %s\n' | 125 'instability: %s\n' |
122 'obsolete: %s\n' | 126 'manifest: %s\n' |
123 'parent: %s\n' | 127 'obsolete: %s\n' |
124 'phase: %s\n' | 128 'parent: %s\n' |
125 'summary: %s\n' | 129 'phase: %s\n' |
126 'tag: %s\n' | 130 'summary: %s\n' |
127 'user: %s\n') | 131 'tag: %s\n' |
128 return dict(zip([s.split(':', 1)[0] for s in columns.splitlines()], | 132 'user: %s\n' |
129 i18n._(columns).splitlines(True))) | 133 ) |
134 return dict( | |
135 zip( | |
136 [s.split(':', 1)[0] for s in columns.splitlines()], | |
137 i18n._(columns).splitlines(True), | |
138 ) | |
139 ) | |
140 | |
130 | 141 |
131 # basic internal templates | 142 # basic internal templates |
132 _changeidtmpl = '{rev}:{node|formatnode}' | 143 _changeidtmpl = '{rev}:{node|formatnode}' |
133 | 144 |
134 # default templates internally used for rendering of lists | 145 # default templates internally used for rendering of lists |
135 defaulttempl = { | 146 defaulttempl = { |
136 'parent': _changeidtmpl + ' ', | 147 'parent': _changeidtmpl + ' ', |
137 'manifest': _changeidtmpl, | 148 'manifest': _changeidtmpl, |
138 'file_copy': '{name} ({source})', | 149 'file_copy': '{name} ({source})', |
139 'envvar': '{key}={value}', | 150 'envvar': '{key}={value}', |
140 'extra': '{key}={value|stringescape}' | 151 'extra': '{key}={value|stringescape}', |
141 } | 152 } |
142 # filecopy is preserved for compatibility reasons | 153 # filecopy is preserved for compatibility reasons |
143 defaulttempl['filecopy'] = defaulttempl['file_copy'] | 154 defaulttempl['filecopy'] = defaulttempl['file_copy'] |
144 | 155 |
145 # keywords are callables (see registrar.templatekeyword for details) | 156 # keywords are callables (see registrar.templatekeyword for details) |
146 keywords = {} | 157 keywords = {} |
147 templatekeyword = registrar.templatekeyword(keywords) | 158 templatekeyword = registrar.templatekeyword(keywords) |
159 | |
148 | 160 |
149 @templatekeyword('author', requires={'ctx'}) | 161 @templatekeyword('author', requires={'ctx'}) |
150 def showauthor(context, mapping): | 162 def showauthor(context, mapping): |
151 """Alias for ``{user}``""" | 163 """Alias for ``{user}``""" |
152 return showuser(context, mapping) | 164 return showuser(context, mapping) |
153 | 165 |
166 | |
154 @templatekeyword('bisect', requires={'repo', 'ctx'}) | 167 @templatekeyword('bisect', requires={'repo', 'ctx'}) |
155 def showbisect(context, mapping): | 168 def showbisect(context, mapping): |
156 """String. The changeset bisection status.""" | 169 """String. The changeset bisection status.""" |
157 repo = context.resource(mapping, 'repo') | 170 repo = context.resource(mapping, 'repo') |
158 ctx = context.resource(mapping, 'ctx') | 171 ctx = context.resource(mapping, 'ctx') |
159 return hbisect.label(repo, ctx.node()) | 172 return hbisect.label(repo, ctx.node()) |
173 | |
160 | 174 |
161 @templatekeyword('branch', requires={'ctx'}) | 175 @templatekeyword('branch', requires={'ctx'}) |
162 def showbranch(context, mapping): | 176 def showbranch(context, mapping): |
163 """String. The name of the branch on which the changeset was | 177 """String. The name of the branch on which the changeset was |
164 committed. | 178 committed. |
165 """ | 179 """ |
166 ctx = context.resource(mapping, 'ctx') | 180 ctx = context.resource(mapping, 'ctx') |
167 return ctx.branch() | 181 return ctx.branch() |
182 | |
168 | 183 |
169 @templatekeyword('branches', requires={'ctx'}) | 184 @templatekeyword('branches', requires={'ctx'}) |
170 def showbranches(context, mapping): | 185 def showbranches(context, mapping): |
171 """List of strings. The name of the branch on which the | 186 """List of strings. The name of the branch on which the |
172 changeset was committed. Will be empty if the branch name was | 187 changeset was committed. Will be empty if the branch name was |
173 default. (DEPRECATED) | 188 default. (DEPRECATED) |
174 """ | 189 """ |
175 ctx = context.resource(mapping, 'ctx') | 190 ctx = context.resource(mapping, 'ctx') |
176 branch = ctx.branch() | 191 branch = ctx.branch() |
177 if branch != 'default': | 192 if branch != 'default': |
178 return compatlist(context, mapping, 'branch', [branch], | 193 return compatlist( |
179 plural='branches') | 194 context, mapping, 'branch', [branch], plural='branches' |
195 ) | |
180 return compatlist(context, mapping, 'branch', [], plural='branches') | 196 return compatlist(context, mapping, 'branch', [], plural='branches') |
197 | |
181 | 198 |
182 @templatekeyword('bookmarks', requires={'repo', 'ctx'}) | 199 @templatekeyword('bookmarks', requires={'repo', 'ctx'}) |
183 def showbookmarks(context, mapping): | 200 def showbookmarks(context, mapping): |
184 """List of strings. Any bookmarks associated with the | 201 """List of strings. Any bookmarks associated with the |
185 changeset. Also sets 'active', the name of the active bookmark. | 202 changeset. Also sets 'active', the name of the active bookmark. |
190 active = repo._activebookmark | 207 active = repo._activebookmark |
191 makemap = lambda v: {'bookmark': v, 'active': active, 'current': active} | 208 makemap = lambda v: {'bookmark': v, 'active': active, 'current': active} |
192 f = _showcompatlist(context, mapping, 'bookmark', bookmarks) | 209 f = _showcompatlist(context, mapping, 'bookmark', bookmarks) |
193 return _hybrid(f, bookmarks, makemap, pycompat.identity) | 210 return _hybrid(f, bookmarks, makemap, pycompat.identity) |
194 | 211 |
212 | |
195 @templatekeyword('children', requires={'ctx'}) | 213 @templatekeyword('children', requires={'ctx'}) |
196 def showchildren(context, mapping): | 214 def showchildren(context, mapping): |
197 """List of strings. The children of the changeset.""" | 215 """List of strings. The children of the changeset.""" |
198 ctx = context.resource(mapping, 'ctx') | 216 ctx = context.resource(mapping, 'ctx') |
199 childrevs = ['%d:%s' % (cctx.rev(), cctx) for cctx in ctx.children()] | 217 childrevs = ['%d:%s' % (cctx.rev(), cctx) for cctx in ctx.children()] |
200 return compatlist(context, mapping, 'children', childrevs, element='child') | 218 return compatlist(context, mapping, 'children', childrevs, element='child') |
219 | |
201 | 220 |
202 # Deprecated, but kept alive for help generation a purpose. | 221 # Deprecated, but kept alive for help generation a purpose. |
203 @templatekeyword('currentbookmark', requires={'repo', 'ctx'}) | 222 @templatekeyword('currentbookmark', requires={'repo', 'ctx'}) |
204 def showcurrentbookmark(context, mapping): | 223 def showcurrentbookmark(context, mapping): |
205 """String. The active bookmark, if it is associated with the changeset. | 224 """String. The active bookmark, if it is associated with the changeset. |
206 (DEPRECATED)""" | 225 (DEPRECATED)""" |
207 return showactivebookmark(context, mapping) | 226 return showactivebookmark(context, mapping) |
208 | 227 |
228 | |
209 @templatekeyword('activebookmark', requires={'repo', 'ctx'}) | 229 @templatekeyword('activebookmark', requires={'repo', 'ctx'}) |
210 def showactivebookmark(context, mapping): | 230 def showactivebookmark(context, mapping): |
211 """String. The active bookmark, if it is associated with the changeset.""" | 231 """String. The active bookmark, if it is associated with the changeset.""" |
212 repo = context.resource(mapping, 'repo') | 232 repo = context.resource(mapping, 'repo') |
213 ctx = context.resource(mapping, 'ctx') | 233 ctx = context.resource(mapping, 'ctx') |
214 active = repo._activebookmark | 234 active = repo._activebookmark |
215 if active and active in ctx.bookmarks(): | 235 if active and active in ctx.bookmarks(): |
216 return active | 236 return active |
217 return '' | 237 return '' |
218 | 238 |
239 | |
219 @templatekeyword('date', requires={'ctx'}) | 240 @templatekeyword('date', requires={'ctx'}) |
220 def showdate(context, mapping): | 241 def showdate(context, mapping): |
221 """Date information. The date when the changeset was committed.""" | 242 """Date information. The date when the changeset was committed.""" |
222 ctx = context.resource(mapping, 'ctx') | 243 ctx = context.resource(mapping, 'ctx') |
223 # the default string format is '<float(unixtime)><tzoffset>' because | 244 # the default string format is '<float(unixtime)><tzoffset>' because |
224 # python-hglib splits date at decimal separator. | 245 # python-hglib splits date at decimal separator. |
225 return templateutil.date(ctx.date(), showfmt='%d.0%d') | 246 return templateutil.date(ctx.date(), showfmt='%d.0%d') |
247 | |
226 | 248 |
227 @templatekeyword('desc', requires={'ctx'}) | 249 @templatekeyword('desc', requires={'ctx'}) |
228 def showdescription(context, mapping): | 250 def showdescription(context, mapping): |
229 """String. The text of the changeset description.""" | 251 """String. The text of the changeset description.""" |
230 ctx = context.resource(mapping, 'ctx') | 252 ctx = context.resource(mapping, 'ctx') |
235 elif isinstance(s, encoding.safelocalstr): | 257 elif isinstance(s, encoding.safelocalstr): |
236 return encoding.safelocalstr(s.strip()) | 258 return encoding.safelocalstr(s.strip()) |
237 else: | 259 else: |
238 return s.strip() | 260 return s.strip() |
239 | 261 |
262 | |
240 @templatekeyword('diffstat', requires={'ui', 'ctx'}) | 263 @templatekeyword('diffstat', requires={'ui', 'ctx'}) |
241 def showdiffstat(context, mapping): | 264 def showdiffstat(context, mapping): |
242 """String. Statistics of changes with the following format: | 265 """String. Statistics of changes with the following format: |
243 "modified files: +added/-removed lines" | 266 "modified files: +added/-removed lines" |
244 """ | 267 """ |
247 diffopts = diffutil.diffallopts(ui, {'noprefix': False}) | 270 diffopts = diffutil.diffallopts(ui, {'noprefix': False}) |
248 diff = ctx.diff(opts=diffopts) | 271 diff = ctx.diff(opts=diffopts) |
249 stats = patch.diffstatdata(util.iterlines(diff)) | 272 stats = patch.diffstatdata(util.iterlines(diff)) |
250 maxname, maxtotal, adds, removes, binary = patch.diffstatsum(stats) | 273 maxname, maxtotal, adds, removes, binary = patch.diffstatsum(stats) |
251 return '%d: +%d/-%d' % (len(stats), adds, removes) | 274 return '%d: +%d/-%d' % (len(stats), adds, removes) |
275 | |
252 | 276 |
253 @templatekeyword('envvars', requires={'ui'}) | 277 @templatekeyword('envvars', requires={'ui'}) |
254 def showenvvars(context, mapping): | 278 def showenvvars(context, mapping): |
255 """A dictionary of environment variables. (EXPERIMENTAL)""" | 279 """A dictionary of environment variables. (EXPERIMENTAL)""" |
256 ui = context.resource(mapping, 'ui') | 280 ui = context.resource(mapping, 'ui') |
257 env = ui.exportableenviron() | 281 env = ui.exportableenviron() |
258 env = util.sortdict((k, env[k]) for k in sorted(env)) | 282 env = util.sortdict((k, env[k]) for k in sorted(env)) |
259 return compatdict(context, mapping, 'envvar', env, plural='envvars') | 283 return compatdict(context, mapping, 'envvar', env, plural='envvars') |
260 | 284 |
285 | |
261 @templatekeyword('extras', requires={'ctx'}) | 286 @templatekeyword('extras', requires={'ctx'}) |
262 def showextras(context, mapping): | 287 def showextras(context, mapping): |
263 """List of dicts with key, value entries of the 'extras' | 288 """List of dicts with key, value entries of the 'extras' |
264 field of this changeset.""" | 289 field of this changeset.""" |
265 ctx = context.resource(mapping, 'ctx') | 290 ctx = context.resource(mapping, 'ctx') |
266 extras = ctx.extra() | 291 extras = ctx.extra() |
267 extras = util.sortdict((k, extras[k]) for k in sorted(extras)) | 292 extras = util.sortdict((k, extras[k]) for k in sorted(extras)) |
268 makemap = lambda k: {'key': k, 'value': extras[k]} | 293 makemap = lambda k: {'key': k, 'value': extras[k]} |
269 c = [makemap(k) for k in extras] | 294 c = [makemap(k) for k in extras] |
270 f = _showcompatlist(context, mapping, 'extra', c, plural='extras') | 295 f = _showcompatlist(context, mapping, 'extra', c, plural='extras') |
271 return _hybrid(f, extras, makemap, | 296 return _hybrid( |
272 lambda k: '%s=%s' % (k, stringutil.escapestr(extras[k]))) | 297 f, |
298 extras, | |
299 makemap, | |
300 lambda k: '%s=%s' % (k, stringutil.escapestr(extras[k])), | |
301 ) | |
302 | |
273 | 303 |
274 def _getfilestatus(context, mapping, listall=False): | 304 def _getfilestatus(context, mapping, listall=False): |
275 ctx = context.resource(mapping, 'ctx') | 305 ctx = context.resource(mapping, 'ctx') |
276 revcache = context.resource(mapping, 'revcache') | 306 revcache = context.resource(mapping, 'revcache') |
277 if 'filestatus' not in revcache or revcache['filestatusall'] < listall: | 307 if 'filestatus' not in revcache or revcache['filestatusall'] < listall: |
278 stat = ctx.p1().status(ctx, listignored=listall, listclean=listall, | 308 stat = ctx.p1().status( |
279 listunknown=listall) | 309 ctx, listignored=listall, listclean=listall, listunknown=listall |
310 ) | |
280 revcache['filestatus'] = stat | 311 revcache['filestatus'] = stat |
281 revcache['filestatusall'] = listall | 312 revcache['filestatusall'] = listall |
282 return revcache['filestatus'] | 313 return revcache['filestatus'] |
314 | |
283 | 315 |
284 def _getfilestatusmap(context, mapping, listall=False): | 316 def _getfilestatusmap(context, mapping, listall=False): |
285 revcache = context.resource(mapping, 'revcache') | 317 revcache = context.resource(mapping, 'revcache') |
286 if 'filestatusmap' not in revcache or revcache['filestatusall'] < listall: | 318 if 'filestatusmap' not in revcache or revcache['filestatusall'] < listall: |
287 stat = _getfilestatus(context, mapping, listall=listall) | 319 stat = _getfilestatus(context, mapping, listall=listall) |
288 revcache['filestatusmap'] = statmap = {} | 320 revcache['filestatusmap'] = statmap = {} |
289 for char, files in zip(pycompat.iterbytestr('MAR!?IC'), stat): | 321 for char, files in zip(pycompat.iterbytestr('MAR!?IC'), stat): |
290 statmap.update((f, char) for f in files) | 322 statmap.update((f, char) for f in files) |
291 return revcache['filestatusmap'] # {path: statchar} | 323 return revcache['filestatusmap'] # {path: statchar} |
292 | 324 |
293 @templatekeyword('file_copies', | 325 |
294 requires={'repo', 'ctx', 'cache', 'revcache'}) | 326 @templatekeyword('file_copies', requires={'repo', 'ctx', 'cache', 'revcache'}) |
295 def showfilecopies(context, mapping): | 327 def showfilecopies(context, mapping): |
296 """List of strings. Files copied in this changeset with | 328 """List of strings. Files copied in this changeset with |
297 their sources. | 329 their sources. |
298 """ | 330 """ |
299 repo = context.resource(mapping, 'repo') | 331 repo = context.resource(mapping, 'repo') |
303 if copies is None: | 335 if copies is None: |
304 if 'getcopies' not in cache: | 336 if 'getcopies' not in cache: |
305 cache['getcopies'] = scmutil.getcopiesfn(repo) | 337 cache['getcopies'] = scmutil.getcopiesfn(repo) |
306 getcopies = cache['getcopies'] | 338 getcopies = cache['getcopies'] |
307 copies = getcopies(ctx) | 339 copies = getcopies(ctx) |
308 return templateutil.compatfilecopiesdict(context, mapping, 'file_copy', | 340 return templateutil.compatfilecopiesdict( |
309 copies) | 341 context, mapping, 'file_copy', copies |
342 ) | |
343 | |
310 | 344 |
311 # showfilecopiesswitch() displays file copies only if copy records are | 345 # showfilecopiesswitch() displays file copies only if copy records are |
312 # provided before calling the templater, usually with a --copies | 346 # provided before calling the templater, usually with a --copies |
313 # command line switch. | 347 # command line switch. |
314 @templatekeyword('file_copies_switch', requires={'revcache'}) | 348 @templatekeyword('file_copies_switch', requires={'revcache'}) |
315 def showfilecopiesswitch(context, mapping): | 349 def showfilecopiesswitch(context, mapping): |
316 """List of strings. Like "file_copies" but displayed | 350 """List of strings. Like "file_copies" but displayed |
317 only if the --copied switch is set. | 351 only if the --copied switch is set. |
318 """ | 352 """ |
319 copies = context.resource(mapping, 'revcache').get('copies') or [] | 353 copies = context.resource(mapping, 'revcache').get('copies') or [] |
320 return templateutil.compatfilecopiesdict(context, mapping, 'file_copy', | 354 return templateutil.compatfilecopiesdict( |
321 copies) | 355 context, mapping, 'file_copy', copies |
356 ) | |
357 | |
322 | 358 |
323 @templatekeyword('file_adds', requires={'ctx', 'revcache'}) | 359 @templatekeyword('file_adds', requires={'ctx', 'revcache'}) |
324 def showfileadds(context, mapping): | 360 def showfileadds(context, mapping): |
325 """List of strings. Files added by this changeset.""" | 361 """List of strings. Files added by this changeset.""" |
326 ctx = context.resource(mapping, 'ctx') | 362 ctx = context.resource(mapping, 'ctx') |
327 return templateutil.compatfileslist(context, mapping, 'file_add', | 363 return templateutil.compatfileslist( |
328 ctx.filesadded()) | 364 context, mapping, 'file_add', ctx.filesadded() |
365 ) | |
366 | |
329 | 367 |
330 @templatekeyword('file_dels', requires={'ctx', 'revcache'}) | 368 @templatekeyword('file_dels', requires={'ctx', 'revcache'}) |
331 def showfiledels(context, mapping): | 369 def showfiledels(context, mapping): |
332 """List of strings. Files removed by this changeset.""" | 370 """List of strings. Files removed by this changeset.""" |
333 ctx = context.resource(mapping, 'ctx') | 371 ctx = context.resource(mapping, 'ctx') |
334 return templateutil.compatfileslist(context, mapping, 'file_del', | 372 return templateutil.compatfileslist( |
335 ctx.filesremoved()) | 373 context, mapping, 'file_del', ctx.filesremoved() |
374 ) | |
375 | |
336 | 376 |
337 @templatekeyword('file_mods', requires={'ctx', 'revcache'}) | 377 @templatekeyword('file_mods', requires={'ctx', 'revcache'}) |
338 def showfilemods(context, mapping): | 378 def showfilemods(context, mapping): |
339 """List of strings. Files modified by this changeset.""" | 379 """List of strings. Files modified by this changeset.""" |
340 ctx = context.resource(mapping, 'ctx') | 380 ctx = context.resource(mapping, 'ctx') |
341 return templateutil.compatfileslist(context, mapping, 'file_mod', | 381 return templateutil.compatfileslist( |
342 ctx.filesmodified()) | 382 context, mapping, 'file_mod', ctx.filesmodified() |
383 ) | |
384 | |
343 | 385 |
344 @templatekeyword('files', requires={'ctx'}) | 386 @templatekeyword('files', requires={'ctx'}) |
345 def showfiles(context, mapping): | 387 def showfiles(context, mapping): |
346 """List of strings. All files modified, added, or removed by this | 388 """List of strings. All files modified, added, or removed by this |
347 changeset. | 389 changeset. |
348 """ | 390 """ |
349 ctx = context.resource(mapping, 'ctx') | 391 ctx = context.resource(mapping, 'ctx') |
350 return templateutil.compatfileslist(context, mapping, 'file', ctx.files()) | 392 return templateutil.compatfileslist(context, mapping, 'file', ctx.files()) |
351 | 393 |
394 | |
352 @templatekeyword('graphnode', requires={'repo', 'ctx'}) | 395 @templatekeyword('graphnode', requires={'repo', 'ctx'}) |
353 def showgraphnode(context, mapping): | 396 def showgraphnode(context, mapping): |
354 """String. The character representing the changeset node in an ASCII | 397 """String. The character representing the changeset node in an ASCII |
355 revision graph.""" | 398 revision graph.""" |
356 repo = context.resource(mapping, 'repo') | 399 repo = context.resource(mapping, 'repo') |
357 ctx = context.resource(mapping, 'ctx') | 400 ctx = context.resource(mapping, 'ctx') |
358 return getgraphnode(repo, ctx) | 401 return getgraphnode(repo, ctx) |
359 | 402 |
403 | |
360 def getgraphnode(repo, ctx): | 404 def getgraphnode(repo, ctx): |
361 return getgraphnodecurrent(repo, ctx) or getgraphnodesymbol(ctx) | 405 return getgraphnodecurrent(repo, ctx) or getgraphnodesymbol(ctx) |
406 | |
362 | 407 |
363 def getgraphnodecurrent(repo, ctx): | 408 def getgraphnodecurrent(repo, ctx): |
364 wpnodes = repo.dirstate.parents() | 409 wpnodes = repo.dirstate.parents() |
365 if wpnodes[1] == nullid: | 410 if wpnodes[1] == nullid: |
366 wpnodes = wpnodes[:1] | 411 wpnodes = wpnodes[:1] |
367 if ctx.node() in wpnodes: | 412 if ctx.node() in wpnodes: |
368 return '@' | 413 return '@' |
369 else: | 414 else: |
370 return '' | 415 return '' |
416 | |
371 | 417 |
372 def getgraphnodesymbol(ctx): | 418 def getgraphnodesymbol(ctx): |
373 if ctx.obsolete(): | 419 if ctx.obsolete(): |
374 return 'x' | 420 return 'x' |
375 elif ctx.isunstable(): | 421 elif ctx.isunstable(): |
377 elif ctx.closesbranch(): | 423 elif ctx.closesbranch(): |
378 return '_' | 424 return '_' |
379 else: | 425 else: |
380 return 'o' | 426 return 'o' |
381 | 427 |
428 | |
382 @templatekeyword('graphwidth', requires=()) | 429 @templatekeyword('graphwidth', requires=()) |
383 def showgraphwidth(context, mapping): | 430 def showgraphwidth(context, mapping): |
384 """Integer. The width of the graph drawn by 'log --graph' or zero.""" | 431 """Integer. The width of the graph drawn by 'log --graph' or zero.""" |
385 # just hosts documentation; should be overridden by template mapping | 432 # just hosts documentation; should be overridden by template mapping |
386 return 0 | 433 return 0 |
387 | 434 |
435 | |
388 @templatekeyword('index', requires=()) | 436 @templatekeyword('index', requires=()) |
389 def showindex(context, mapping): | 437 def showindex(context, mapping): |
390 """Integer. The current iteration of the loop. (0 indexed)""" | 438 """Integer. The current iteration of the loop. (0 indexed)""" |
391 # just hosts documentation; should be overridden by template mapping | 439 # just hosts documentation; should be overridden by template mapping |
392 raise error.Abort(_("can't use index in this context")) | 440 raise error.Abort(_("can't use index in this context")) |
393 | 441 |
442 | |
394 @templatekeyword('latesttag', requires={'repo', 'ctx', 'cache'}) | 443 @templatekeyword('latesttag', requires={'repo', 'ctx', 'cache'}) |
395 def showlatesttag(context, mapping): | 444 def showlatesttag(context, mapping): |
396 """List of strings. The global tags on the most recent globally | 445 """List of strings. The global tags on the most recent globally |
397 tagged ancestor of this changeset. If no such tags exist, the list | 446 tagged ancestor of this changeset. If no such tags exist, the list |
398 consists of the single string "null". | 447 consists of the single string "null". |
399 """ | 448 """ |
400 return showlatesttags(context, mapping, None) | 449 return showlatesttags(context, mapping, None) |
450 | |
401 | 451 |
402 def showlatesttags(context, mapping, pattern): | 452 def showlatesttags(context, mapping, pattern): |
403 """helper method for the latesttag keyword and function""" | 453 """helper method for the latesttag keyword and function""" |
404 latesttags = getlatesttags(context, mapping, pattern) | 454 latesttags = getlatesttags(context, mapping, pattern) |
405 | 455 |
407 # branches in a stable manner- it is the date the tagged cset was created, | 457 # branches in a stable manner- it is the date the tagged cset was created, |
408 # not the date the tag was created. Therefore it isn't made visible here. | 458 # not the date the tag was created. Therefore it isn't made visible here. |
409 makemap = lambda v: { | 459 makemap = lambda v: { |
410 'changes': _showchangessincetag, | 460 'changes': _showchangessincetag, |
411 'distance': latesttags[1], | 461 'distance': latesttags[1], |
412 'latesttag': v, # BC with {latesttag % '{latesttag}'} | 462 'latesttag': v, # BC with {latesttag % '{latesttag}'} |
413 'tag': v | 463 'tag': v, |
414 } | 464 } |
415 | 465 |
416 tags = latesttags[2] | 466 tags = latesttags[2] |
417 f = _showcompatlist(context, mapping, 'latesttag', tags, separator=':') | 467 f = _showcompatlist(context, mapping, 'latesttag', tags, separator=':') |
418 return _hybrid(f, tags, makemap, pycompat.identity) | 468 return _hybrid(f, tags, makemap, pycompat.identity) |
469 | |
419 | 470 |
420 @templatekeyword('latesttagdistance', requires={'repo', 'ctx', 'cache'}) | 471 @templatekeyword('latesttagdistance', requires={'repo', 'ctx', 'cache'}) |
421 def showlatesttagdistance(context, mapping): | 472 def showlatesttagdistance(context, mapping): |
422 """Integer. Longest path to the latest tag.""" | 473 """Integer. Longest path to the latest tag.""" |
423 return getlatesttags(context, mapping)[1] | 474 return getlatesttags(context, mapping)[1] |
475 | |
424 | 476 |
425 @templatekeyword('changessincelatesttag', requires={'repo', 'ctx', 'cache'}) | 477 @templatekeyword('changessincelatesttag', requires={'repo', 'ctx', 'cache'}) |
426 def showchangessincelatesttag(context, mapping): | 478 def showchangessincelatesttag(context, mapping): |
427 """Integer. All ancestors not in the latest tag.""" | 479 """Integer. All ancestors not in the latest tag.""" |
428 tag = getlatesttags(context, mapping)[2][0] | 480 tag = getlatesttags(context, mapping)[2][0] |
429 mapping = context.overlaymap(mapping, {'tag': tag}) | 481 mapping = context.overlaymap(mapping, {'tag': tag}) |
430 return _showchangessincetag(context, mapping) | 482 return _showchangessincetag(context, mapping) |
431 | 483 |
484 | |
432 def _showchangessincetag(context, mapping): | 485 def _showchangessincetag(context, mapping): |
433 repo = context.resource(mapping, 'repo') | 486 repo = context.resource(mapping, 'repo') |
434 ctx = context.resource(mapping, 'ctx') | 487 ctx = context.resource(mapping, 'ctx') |
435 offset = 0 | 488 offset = 0 |
436 revs = [ctx.rev()] | 489 revs = [ctx.rev()] |
441 offset = 1 | 494 offset = 1 |
442 revs = [p.rev() for p in ctx.parents()] | 495 revs = [p.rev() for p in ctx.parents()] |
443 | 496 |
444 return len(repo.revs('only(%ld, %s)', revs, tag)) + offset | 497 return len(repo.revs('only(%ld, %s)', revs, tag)) + offset |
445 | 498 |
499 | |
446 # teach templater latesttags.changes is switched to (context, mapping) API | 500 # teach templater latesttags.changes is switched to (context, mapping) API |
447 _showchangessincetag._requires = {'repo', 'ctx'} | 501 _showchangessincetag._requires = {'repo', 'ctx'} |
502 | |
448 | 503 |
449 @templatekeyword('manifest', requires={'repo', 'ctx'}) | 504 @templatekeyword('manifest', requires={'repo', 'ctx'}) |
450 def showmanifest(context, mapping): | 505 def showmanifest(context, mapping): |
451 repo = context.resource(mapping, 'repo') | 506 repo = context.resource(mapping, 'repo') |
452 ctx = context.resource(mapping, 'ctx') | 507 ctx = context.resource(mapping, 'ctx') |
457 else: | 512 else: |
458 mrev = repo.manifestlog.rev(mnode) | 513 mrev = repo.manifestlog.rev(mnode) |
459 mhex = hex(mnode) | 514 mhex = hex(mnode) |
460 mapping = context.overlaymap(mapping, {'rev': mrev, 'node': mhex}) | 515 mapping = context.overlaymap(mapping, {'rev': mrev, 'node': mhex}) |
461 f = context.process('manifest', mapping) | 516 f = context.process('manifest', mapping) |
462 return templateutil.hybriditem(f, None, f, | 517 return templateutil.hybriditem( |
463 lambda x: {'rev': mrev, 'node': mhex}) | 518 f, None, f, lambda x: {'rev': mrev, 'node': mhex} |
519 ) | |
520 | |
464 | 521 |
465 @templatekeyword('obsfate', requires={'ui', 'repo', 'ctx'}) | 522 @templatekeyword('obsfate', requires={'ui', 'repo', 'ctx'}) |
466 def showobsfate(context, mapping): | 523 def showobsfate(context, mapping): |
467 # this function returns a list containing pre-formatted obsfate strings. | 524 # this function returns a list containing pre-formatted obsfate strings. |
468 # | 525 # |
473 ui = context.resource(mapping, 'ui') | 530 ui = context.resource(mapping, 'ui') |
474 repo = context.resource(mapping, 'repo') | 531 repo = context.resource(mapping, 'repo') |
475 values = [] | 532 values = [] |
476 | 533 |
477 for x in succsandmarkers.tovalue(context, mapping): | 534 for x in succsandmarkers.tovalue(context, mapping): |
478 v = obsutil.obsfateprinter(ui, repo, x['successors'], x['markers'], | 535 v = obsutil.obsfateprinter( |
479 scmutil.formatchangeid) | 536 ui, repo, x['successors'], x['markers'], scmutil.formatchangeid |
537 ) | |
480 values.append(v) | 538 values.append(v) |
481 | 539 |
482 return compatlist(context, mapping, "fate", values) | 540 return compatlist(context, mapping, "fate", values) |
541 | |
483 | 542 |
484 def shownames(context, mapping, namespace): | 543 def shownames(context, mapping, namespace): |
485 """helper method to generate a template keyword for a namespace""" | 544 """helper method to generate a template keyword for a namespace""" |
486 repo = context.resource(mapping, 'repo') | 545 repo = context.resource(mapping, 'repo') |
487 ctx = context.resource(mapping, 'ctx') | 546 ctx = context.resource(mapping, 'ctx') |
488 ns = repo.names[namespace] | 547 ns = repo.names[namespace] |
489 names = ns.names(repo, ctx.node()) | 548 names = ns.names(repo, ctx.node()) |
490 return compatlist(context, mapping, ns.templatename, names, | 549 return compatlist( |
491 plural=namespace) | 550 context, mapping, ns.templatename, names, plural=namespace |
551 ) | |
552 | |
492 | 553 |
493 @templatekeyword('namespaces', requires={'repo', 'ctx'}) | 554 @templatekeyword('namespaces', requires={'repo', 'ctx'}) |
494 def shownamespaces(context, mapping): | 555 def shownamespaces(context, mapping): |
495 """Dict of lists. Names attached to this changeset per | 556 """Dict of lists. Names attached to this changeset per |
496 namespace.""" | 557 namespace.""" |
497 repo = context.resource(mapping, 'repo') | 558 repo = context.resource(mapping, 'repo') |
498 ctx = context.resource(mapping, 'ctx') | 559 ctx = context.resource(mapping, 'ctx') |
499 | 560 |
500 namespaces = util.sortdict() | 561 namespaces = util.sortdict() |
562 | |
501 def makensmapfn(ns): | 563 def makensmapfn(ns): |
502 # 'name' for iterating over namespaces, templatename for local reference | 564 # 'name' for iterating over namespaces, templatename for local reference |
503 return lambda v: {'name': v, ns.templatename: v} | 565 return lambda v: {'name': v, ns.templatename: v} |
504 | 566 |
505 for k, ns in repo.names.iteritems(): | 567 for k, ns in repo.names.iteritems(): |
517 'colorname': repo.names[ns].colorname, | 579 'colorname': repo.names[ns].colorname, |
518 } | 580 } |
519 | 581 |
520 return _hybrid(f, namespaces, makemap, pycompat.identity) | 582 return _hybrid(f, namespaces, makemap, pycompat.identity) |
521 | 583 |
584 | |
522 @templatekeyword('negrev', requires={'repo', 'ctx'}) | 585 @templatekeyword('negrev', requires={'repo', 'ctx'}) |
523 def shownegrev(context, mapping): | 586 def shownegrev(context, mapping): |
524 """Integer. The repository-local changeset negative revision number, | 587 """Integer. The repository-local changeset negative revision number, |
525 which counts in the opposite direction.""" | 588 which counts in the opposite direction.""" |
526 ctx = context.resource(mapping, 'ctx') | 589 ctx = context.resource(mapping, 'ctx') |
528 if rev is None or rev < 0: # wdir() or nullrev? | 591 if rev is None or rev < 0: # wdir() or nullrev? |
529 return None | 592 return None |
530 repo = context.resource(mapping, 'repo') | 593 repo = context.resource(mapping, 'repo') |
531 return rev - len(repo) | 594 return rev - len(repo) |
532 | 595 |
596 | |
533 @templatekeyword('node', requires={'ctx'}) | 597 @templatekeyword('node', requires={'ctx'}) |
534 def shownode(context, mapping): | 598 def shownode(context, mapping): |
535 """String. The changeset identification hash, as a 40 hexadecimal | 599 """String. The changeset identification hash, as a 40 hexadecimal |
536 digit string. | 600 digit string. |
537 """ | 601 """ |
538 ctx = context.resource(mapping, 'ctx') | 602 ctx = context.resource(mapping, 'ctx') |
539 return ctx.hex() | 603 return ctx.hex() |
540 | 604 |
605 | |
541 @templatekeyword('obsolete', requires={'ctx'}) | 606 @templatekeyword('obsolete', requires={'ctx'}) |
542 def showobsolete(context, mapping): | 607 def showobsolete(context, mapping): |
543 """String. Whether the changeset is obsolete. (EXPERIMENTAL)""" | 608 """String. Whether the changeset is obsolete. (EXPERIMENTAL)""" |
544 ctx = context.resource(mapping, 'ctx') | 609 ctx = context.resource(mapping, 'ctx') |
545 if ctx.obsolete(): | 610 if ctx.obsolete(): |
546 return 'obsolete' | 611 return 'obsolete' |
547 return '' | 612 return '' |
613 | |
548 | 614 |
549 @templatekeyword('path', requires={'fctx'}) | 615 @templatekeyword('path', requires={'fctx'}) |
550 def showpath(context, mapping): | 616 def showpath(context, mapping): |
551 """String. Repository-absolute path of the current file. (EXPERIMENTAL)""" | 617 """String. Repository-absolute path of the current file. (EXPERIMENTAL)""" |
552 fctx = context.resource(mapping, 'fctx') | 618 fctx = context.resource(mapping, 'fctx') |
553 return fctx.path() | 619 return fctx.path() |
554 | 620 |
621 | |
555 @templatekeyword('peerurls', requires={'repo'}) | 622 @templatekeyword('peerurls', requires={'repo'}) |
556 def showpeerurls(context, mapping): | 623 def showpeerurls(context, mapping): |
557 """A dictionary of repository locations defined in the [paths] section | 624 """A dictionary of repository locations defined in the [paths] section |
558 of your configuration file.""" | 625 of your configuration file.""" |
559 repo = context.resource(mapping, 'repo') | 626 repo = context.resource(mapping, 'repo') |
560 # see commands.paths() for naming of dictionary keys | 627 # see commands.paths() for naming of dictionary keys |
561 paths = repo.ui.paths | 628 paths = repo.ui.paths |
562 urls = util.sortdict((k, p.rawloc) for k, p in sorted(paths.iteritems())) | 629 urls = util.sortdict((k, p.rawloc) for k, p in sorted(paths.iteritems())) |
630 | |
563 def makemap(k): | 631 def makemap(k): |
564 p = paths[k] | 632 p = paths[k] |
565 d = {'name': k, 'url': p.rawloc} | 633 d = {'name': k, 'url': p.rawloc} |
566 d.update((o, v) for o, v in sorted(p.suboptions.iteritems())) | 634 d.update((o, v) for o, v in sorted(p.suboptions.iteritems())) |
567 return d | 635 return d |
636 | |
568 return _hybrid(None, urls, makemap, lambda k: '%s=%s' % (k, urls[k])) | 637 return _hybrid(None, urls, makemap, lambda k: '%s=%s' % (k, urls[k])) |
638 | |
569 | 639 |
570 @templatekeyword("predecessors", requires={'repo', 'ctx'}) | 640 @templatekeyword("predecessors", requires={'repo', 'ctx'}) |
571 def showpredecessors(context, mapping): | 641 def showpredecessors(context, mapping): |
572 """Returns the list of the closest visible predecessors. (EXPERIMENTAL)""" | 642 """Returns the list of the closest visible predecessors. (EXPERIMENTAL)""" |
573 repo = context.resource(mapping, 'repo') | 643 repo = context.resource(mapping, 'repo') |
574 ctx = context.resource(mapping, 'ctx') | 644 ctx = context.resource(mapping, 'ctx') |
575 predecessors = sorted(obsutil.closestpredecessors(repo, ctx.node())) | 645 predecessors = sorted(obsutil.closestpredecessors(repo, ctx.node())) |
576 predecessors = pycompat.maplist(hex, predecessors) | 646 predecessors = pycompat.maplist(hex, predecessors) |
577 | 647 |
578 return _hybrid(None, predecessors, | 648 return _hybrid( |
579 lambda x: {'ctx': repo[x]}, | 649 None, |
580 lambda x: scmutil.formatchangeid(repo[x])) | 650 predecessors, |
651 lambda x: {'ctx': repo[x]}, | |
652 lambda x: scmutil.formatchangeid(repo[x]), | |
653 ) | |
654 | |
581 | 655 |
582 @templatekeyword('reporoot', requires={'repo'}) | 656 @templatekeyword('reporoot', requires={'repo'}) |
583 def showreporoot(context, mapping): | 657 def showreporoot(context, mapping): |
584 """String. The root directory of the current repository.""" | 658 """String. The root directory of the current repository.""" |
585 repo = context.resource(mapping, 'repo') | 659 repo = context.resource(mapping, 'repo') |
586 return repo.root | 660 return repo.root |
661 | |
587 | 662 |
588 @templatekeyword('size', requires={'fctx'}) | 663 @templatekeyword('size', requires={'fctx'}) |
589 def showsize(context, mapping): | 664 def showsize(context, mapping): |
590 """Integer. Size of the current file in bytes. (EXPERIMENTAL)""" | 665 """Integer. Size of the current file in bytes. (EXPERIMENTAL)""" |
591 fctx = context.resource(mapping, 'fctx') | 666 fctx = context.resource(mapping, 'fctx') |
592 return fctx.size() | 667 return fctx.size() |
668 | |
593 | 669 |
594 # requires 'fctx' to denote {status} depends on (ctx, path) pair | 670 # requires 'fctx' to denote {status} depends on (ctx, path) pair |
595 @templatekeyword('status', requires={'ctx', 'fctx', 'revcache'}) | 671 @templatekeyword('status', requires={'ctx', 'fctx', 'revcache'}) |
596 def showstatus(context, mapping): | 672 def showstatus(context, mapping): |
597 """String. Status code of the current file. (EXPERIMENTAL)""" | 673 """String. Status code of the current file. (EXPERIMENTAL)""" |
602 statmap = _getfilestatusmap(context, mapping) | 678 statmap = _getfilestatusmap(context, mapping) |
603 if path not in statmap: | 679 if path not in statmap: |
604 statmap = _getfilestatusmap(context, mapping, listall=True) | 680 statmap = _getfilestatusmap(context, mapping, listall=True) |
605 return statmap.get(path) | 681 return statmap.get(path) |
606 | 682 |
683 | |
607 @templatekeyword("successorssets", requires={'repo', 'ctx'}) | 684 @templatekeyword("successorssets", requires={'repo', 'ctx'}) |
608 def showsuccessorssets(context, mapping): | 685 def showsuccessorssets(context, mapping): |
609 """Returns a string of sets of successors for a changectx. Format used | 686 """Returns a string of sets of successors for a changectx. Format used |
610 is: [ctx1, ctx2], [ctx3] if ctx has been split into ctx1 and ctx2 | 687 is: [ctx1, ctx2], [ctx3] if ctx has been split into ctx1 and ctx2 |
611 while also diverged into ctx3. (EXPERIMENTAL)""" | 688 while also diverged into ctx3. (EXPERIMENTAL)""" |
617 ssets = obsutil.successorssets(repo, ctx.node(), closest=True) | 694 ssets = obsutil.successorssets(repo, ctx.node(), closest=True) |
618 ssets = [[hex(n) for n in ss] for ss in ssets] | 695 ssets = [[hex(n) for n in ss] for ss in ssets] |
619 | 696 |
620 data = [] | 697 data = [] |
621 for ss in ssets: | 698 for ss in ssets: |
622 h = _hybrid(None, ss, lambda x: {'ctx': repo[x]}, | 699 h = _hybrid( |
623 lambda x: scmutil.formatchangeid(repo[x])) | 700 None, |
701 ss, | |
702 lambda x: {'ctx': repo[x]}, | |
703 lambda x: scmutil.formatchangeid(repo[x]), | |
704 ) | |
624 data.append(h) | 705 data.append(h) |
625 | 706 |
626 # Format the successorssets | 707 # Format the successorssets |
627 def render(d): | 708 def render(d): |
628 return templateutil.stringify(context, mapping, d) | 709 return templateutil.stringify(context, mapping, d) |
629 | 710 |
630 def gen(data): | 711 def gen(data): |
631 yield "; ".join(render(d) for d in data) | 712 yield "; ".join(render(d) for d in data) |
632 | 713 |
633 return _hybrid(gen(data), data, lambda x: {'successorset': x}, | 714 return _hybrid( |
634 pycompat.identity) | 715 gen(data), data, lambda x: {'successorset': x}, pycompat.identity |
716 ) | |
717 | |
635 | 718 |
636 @templatekeyword("succsandmarkers", requires={'repo', 'ctx'}) | 719 @templatekeyword("succsandmarkers", requires={'repo', 'ctx'}) |
637 def showsuccsandmarkers(context, mapping): | 720 def showsuccsandmarkers(context, mapping): |
638 """Returns a list of dict for each final successor of ctx. The dict | 721 """Returns a list of dict for each final successor of ctx. The dict |
639 contains successors node id in "successors" keys and the list of | 722 contains successors node id in "successors" keys and the list of |
653 for i in values: | 736 for i in values: |
654 # Format successors | 737 # Format successors |
655 successors = i['successors'] | 738 successors = i['successors'] |
656 | 739 |
657 successors = [hex(n) for n in successors] | 740 successors = [hex(n) for n in successors] |
658 successors = _hybrid(None, successors, | 741 successors = _hybrid( |
659 lambda x: {'ctx': repo[x]}, | 742 None, |
660 lambda x: scmutil.formatchangeid(repo[x])) | 743 successors, |
744 lambda x: {'ctx': repo[x]}, | |
745 lambda x: scmutil.formatchangeid(repo[x]), | |
746 ) | |
661 | 747 |
662 # Format markers | 748 # Format markers |
663 finalmarkers = [] | 749 finalmarkers = [] |
664 for m in i['markers']: | 750 for m in i['markers']: |
665 hexprec = hex(m[0]) | 751 hexprec = hex(m[0]) |
672 | 758 |
673 data.append({'successors': successors, 'markers': finalmarkers}) | 759 data.append({'successors': successors, 'markers': finalmarkers}) |
674 | 760 |
675 return templateutil.mappinglist(data) | 761 return templateutil.mappinglist(data) |
676 | 762 |
763 | |
677 @templatekeyword('p1', requires={'ctx'}) | 764 @templatekeyword('p1', requires={'ctx'}) |
678 def showp1(context, mapping): | 765 def showp1(context, mapping): |
679 """Changeset. The changeset's first parent. ``{p1.rev}`` for the revision | 766 """Changeset. The changeset's first parent. ``{p1.rev}`` for the revision |
680 number, and ``{p1.node}`` for the identification hash.""" | 767 number, and ``{p1.node}`` for the identification hash.""" |
681 ctx = context.resource(mapping, 'ctx') | 768 ctx = context.resource(mapping, 'ctx') |
682 return templateutil.mappingdict({'ctx': ctx.p1()}, tmpl=_changeidtmpl) | 769 return templateutil.mappingdict({'ctx': ctx.p1()}, tmpl=_changeidtmpl) |
683 | 770 |
771 | |
684 @templatekeyword('p2', requires={'ctx'}) | 772 @templatekeyword('p2', requires={'ctx'}) |
685 def showp2(context, mapping): | 773 def showp2(context, mapping): |
686 """Changeset. The changeset's second parent. ``{p2.rev}`` for the revision | 774 """Changeset. The changeset's second parent. ``{p2.rev}`` for the revision |
687 number, and ``{p2.node}`` for the identification hash.""" | 775 number, and ``{p2.node}`` for the identification hash.""" |
688 ctx = context.resource(mapping, 'ctx') | 776 ctx = context.resource(mapping, 'ctx') |
689 return templateutil.mappingdict({'ctx': ctx.p2()}, tmpl=_changeidtmpl) | 777 return templateutil.mappingdict({'ctx': ctx.p2()}, tmpl=_changeidtmpl) |
690 | 778 |
779 | |
691 @templatekeyword('p1rev', requires={'ctx'}) | 780 @templatekeyword('p1rev', requires={'ctx'}) |
692 def showp1rev(context, mapping): | 781 def showp1rev(context, mapping): |
693 """Integer. The repository-local revision number of the changeset's | 782 """Integer. The repository-local revision number of the changeset's |
694 first parent, or -1 if the changeset has no parents. (DEPRECATED)""" | 783 first parent, or -1 if the changeset has no parents. (DEPRECATED)""" |
695 ctx = context.resource(mapping, 'ctx') | 784 ctx = context.resource(mapping, 'ctx') |
696 return ctx.p1().rev() | 785 return ctx.p1().rev() |
697 | 786 |
787 | |
698 @templatekeyword('p2rev', requires={'ctx'}) | 788 @templatekeyword('p2rev', requires={'ctx'}) |
699 def showp2rev(context, mapping): | 789 def showp2rev(context, mapping): |
700 """Integer. The repository-local revision number of the changeset's | 790 """Integer. The repository-local revision number of the changeset's |
701 second parent, or -1 if the changeset has no second parent. (DEPRECATED)""" | 791 second parent, or -1 if the changeset has no second parent. (DEPRECATED)""" |
702 ctx = context.resource(mapping, 'ctx') | 792 ctx = context.resource(mapping, 'ctx') |
703 return ctx.p2().rev() | 793 return ctx.p2().rev() |
794 | |
704 | 795 |
705 @templatekeyword('p1node', requires={'ctx'}) | 796 @templatekeyword('p1node', requires={'ctx'}) |
706 def showp1node(context, mapping): | 797 def showp1node(context, mapping): |
707 """String. The identification hash of the changeset's first parent, | 798 """String. The identification hash of the changeset's first parent, |
708 as a 40 digit hexadecimal string. If the changeset has no parents, all | 799 as a 40 digit hexadecimal string. If the changeset has no parents, all |
709 digits are 0. (DEPRECATED)""" | 800 digits are 0. (DEPRECATED)""" |
710 ctx = context.resource(mapping, 'ctx') | 801 ctx = context.resource(mapping, 'ctx') |
711 return ctx.p1().hex() | 802 return ctx.p1().hex() |
712 | 803 |
804 | |
713 @templatekeyword('p2node', requires={'ctx'}) | 805 @templatekeyword('p2node', requires={'ctx'}) |
714 def showp2node(context, mapping): | 806 def showp2node(context, mapping): |
715 """String. The identification hash of the changeset's second | 807 """String. The identification hash of the changeset's second |
716 parent, as a 40 digit hexadecimal string. If the changeset has no second | 808 parent, as a 40 digit hexadecimal string. If the changeset has no second |
717 parent, all digits are 0. (DEPRECATED)""" | 809 parent, all digits are 0. (DEPRECATED)""" |
718 ctx = context.resource(mapping, 'ctx') | 810 ctx = context.resource(mapping, 'ctx') |
719 return ctx.p2().hex() | 811 return ctx.p2().hex() |
720 | 812 |
813 | |
721 @templatekeyword('parents', requires={'repo', 'ctx'}) | 814 @templatekeyword('parents', requires={'repo', 'ctx'}) |
722 def showparents(context, mapping): | 815 def showparents(context, mapping): |
723 """List of strings. The parents of the changeset in "rev:node" | 816 """List of strings. The parents of the changeset in "rev:node" |
724 format. If the changeset has only one "natural" parent (the predecessor | 817 format. If the changeset has only one "natural" parent (the predecessor |
725 revision) nothing is shown.""" | 818 revision) nothing is shown.""" |
726 repo = context.resource(mapping, 'repo') | 819 repo = context.resource(mapping, 'repo') |
727 ctx = context.resource(mapping, 'ctx') | 820 ctx = context.resource(mapping, 'ctx') |
728 pctxs = scmutil.meaningfulparents(repo, ctx) | 821 pctxs = scmutil.meaningfulparents(repo, ctx) |
729 prevs = [p.rev() for p in pctxs] | 822 prevs = [p.rev() for p in pctxs] |
730 parents = [[('rev', p.rev()), | 823 parents = [ |
731 ('node', p.hex()), | 824 [('rev', p.rev()), ('node', p.hex()), ('phase', p.phasestr())] |
732 ('phase', p.phasestr())] | 825 for p in pctxs |
733 for p in pctxs] | 826 ] |
734 f = _showcompatlist(context, mapping, 'parent', parents) | 827 f = _showcompatlist(context, mapping, 'parent', parents) |
735 return _hybrid(f, prevs, lambda x: {'ctx': repo[x]}, | 828 return _hybrid( |
736 lambda x: scmutil.formatchangeid(repo[x]), keytype=int) | 829 f, |
830 prevs, | |
831 lambda x: {'ctx': repo[x]}, | |
832 lambda x: scmutil.formatchangeid(repo[x]), | |
833 keytype=int, | |
834 ) | |
835 | |
737 | 836 |
738 @templatekeyword('phase', requires={'ctx'}) | 837 @templatekeyword('phase', requires={'ctx'}) |
739 def showphase(context, mapping): | 838 def showphase(context, mapping): |
740 """String. The changeset phase name.""" | 839 """String. The changeset phase name.""" |
741 ctx = context.resource(mapping, 'ctx') | 840 ctx = context.resource(mapping, 'ctx') |
742 return ctx.phasestr() | 841 return ctx.phasestr() |
743 | 842 |
843 | |
744 @templatekeyword('phaseidx', requires={'ctx'}) | 844 @templatekeyword('phaseidx', requires={'ctx'}) |
745 def showphaseidx(context, mapping): | 845 def showphaseidx(context, mapping): |
746 """Integer. The changeset phase index. (ADVANCED)""" | 846 """Integer. The changeset phase index. (ADVANCED)""" |
747 ctx = context.resource(mapping, 'ctx') | 847 ctx = context.resource(mapping, 'ctx') |
748 return ctx.phase() | 848 return ctx.phase() |
749 | 849 |
850 | |
750 @templatekeyword('rev', requires={'ctx'}) | 851 @templatekeyword('rev', requires={'ctx'}) |
751 def showrev(context, mapping): | 852 def showrev(context, mapping): |
752 """Integer. The repository-local changeset revision number.""" | 853 """Integer. The repository-local changeset revision number.""" |
753 ctx = context.resource(mapping, 'ctx') | 854 ctx = context.resource(mapping, 'ctx') |
754 return scmutil.intrev(ctx) | 855 return scmutil.intrev(ctx) |
856 | |
755 | 857 |
756 def showrevslist(context, mapping, name, revs): | 858 def showrevslist(context, mapping, name, revs): |
757 """helper to generate a list of revisions in which a mapped template will | 859 """helper to generate a list of revisions in which a mapped template will |
758 be evaluated""" | 860 be evaluated""" |
759 repo = context.resource(mapping, 'repo') | 861 repo = context.resource(mapping, 'repo') |
760 # revs may be a smartset; don't compute it until f() has to be evaluated | 862 # revs may be a smartset; don't compute it until f() has to be evaluated |
761 def f(): | 863 def f(): |
762 srevs = ['%d' % r for r in revs] | 864 srevs = ['%d' % r for r in revs] |
763 return _showcompatlist(context, mapping, name, srevs) | 865 return _showcompatlist(context, mapping, name, srevs) |
764 return _hybrid(f, revs, | 866 |
765 lambda x: {name: x, 'ctx': repo[x]}, | 867 return _hybrid( |
766 pycompat.identity, keytype=int) | 868 f, |
869 revs, | |
870 lambda x: {name: x, 'ctx': repo[x]}, | |
871 pycompat.identity, | |
872 keytype=int, | |
873 ) | |
874 | |
767 | 875 |
768 @templatekeyword('subrepos', requires={'ctx'}) | 876 @templatekeyword('subrepos', requires={'ctx'}) |
769 def showsubrepos(context, mapping): | 877 def showsubrepos(context, mapping): |
770 """List of strings. Updated subrepositories in the changeset.""" | 878 """List of strings. Updated subrepositories in the changeset.""" |
771 ctx = context.resource(mapping, 'ctx') | 879 ctx = context.resource(mapping, 'ctx') |
774 return compatlist(context, mapping, 'subrepo', []) | 882 return compatlist(context, mapping, 'subrepo', []) |
775 psubstate = ctx.p1().substate or {} | 883 psubstate = ctx.p1().substate or {} |
776 subrepos = [] | 884 subrepos = [] |
777 for sub in substate: | 885 for sub in substate: |
778 if sub not in psubstate or substate[sub] != psubstate[sub]: | 886 if sub not in psubstate or substate[sub] != psubstate[sub]: |
779 subrepos.append(sub) # modified or newly added in ctx | 887 subrepos.append(sub) # modified or newly added in ctx |
780 for sub in psubstate: | 888 for sub in psubstate: |
781 if sub not in substate: | 889 if sub not in substate: |
782 subrepos.append(sub) # removed in ctx | 890 subrepos.append(sub) # removed in ctx |
783 return compatlist(context, mapping, 'subrepo', sorted(subrepos)) | 891 return compatlist(context, mapping, 'subrepo', sorted(subrepos)) |
892 | |
784 | 893 |
785 # don't remove "showtags" definition, even though namespaces will put | 894 # don't remove "showtags" definition, even though namespaces will put |
786 # a helper function for "tags" keyword into "keywords" map automatically, | 895 # a helper function for "tags" keyword into "keywords" map automatically, |
787 # because online help text is built without namespaces initialization | 896 # because online help text is built without namespaces initialization |
788 @templatekeyword('tags', requires={'repo', 'ctx'}) | 897 @templatekeyword('tags', requires={'repo', 'ctx'}) |
789 def showtags(context, mapping): | 898 def showtags(context, mapping): |
790 """List of strings. Any tags associated with the changeset.""" | 899 """List of strings. Any tags associated with the changeset.""" |
791 return shownames(context, mapping, 'tags') | 900 return shownames(context, mapping, 'tags') |
792 | 901 |
902 | |
793 @templatekeyword('termwidth', requires={'ui'}) | 903 @templatekeyword('termwidth', requires={'ui'}) |
794 def showtermwidth(context, mapping): | 904 def showtermwidth(context, mapping): |
795 """Integer. The width of the current terminal.""" | 905 """Integer. The width of the current terminal.""" |
796 ui = context.resource(mapping, 'ui') | 906 ui = context.resource(mapping, 'ui') |
797 return ui.termwidth() | 907 return ui.termwidth() |
798 | 908 |
909 | |
799 @templatekeyword('user', requires={'ctx'}) | 910 @templatekeyword('user', requires={'ctx'}) |
800 def showuser(context, mapping): | 911 def showuser(context, mapping): |
801 """String. The unmodified author of the changeset.""" | 912 """String. The unmodified author of the changeset.""" |
802 ctx = context.resource(mapping, 'ctx') | 913 ctx = context.resource(mapping, 'ctx') |
803 return ctx.user() | 914 return ctx.user() |
915 | |
804 | 916 |
805 @templatekeyword('instabilities', requires={'ctx'}) | 917 @templatekeyword('instabilities', requires={'ctx'}) |
806 def showinstabilities(context, mapping): | 918 def showinstabilities(context, mapping): |
807 """List of strings. Evolution instabilities affecting the changeset. | 919 """List of strings. Evolution instabilities affecting the changeset. |
808 (EXPERIMENTAL) | 920 (EXPERIMENTAL) |
809 """ | 921 """ |
810 ctx = context.resource(mapping, 'ctx') | 922 ctx = context.resource(mapping, 'ctx') |
811 return compatlist(context, mapping, 'instability', ctx.instabilities(), | 923 return compatlist( |
812 plural='instabilities') | 924 context, |
925 mapping, | |
926 'instability', | |
927 ctx.instabilities(), | |
928 plural='instabilities', | |
929 ) | |
930 | |
813 | 931 |
814 @templatekeyword('verbosity', requires={'ui'}) | 932 @templatekeyword('verbosity', requires={'ui'}) |
815 def showverbosity(context, mapping): | 933 def showverbosity(context, mapping): |
816 """String. The current output verbosity in 'debug', 'quiet', 'verbose', | 934 """String. The current output verbosity in 'debug', 'quiet', 'verbose', |
817 or ''.""" | 935 or ''.""" |
823 return 'quiet' | 941 return 'quiet' |
824 elif ui.verbose: | 942 elif ui.verbose: |
825 return 'verbose' | 943 return 'verbose' |
826 return '' | 944 return '' |
827 | 945 |
946 | |
828 @templatekeyword('whyunstable', requires={'repo', 'ctx'}) | 947 @templatekeyword('whyunstable', requires={'repo', 'ctx'}) |
829 def showwhyunstable(context, mapping): | 948 def showwhyunstable(context, mapping): |
830 """List of dicts explaining all instabilities of a changeset. | 949 """List of dicts explaining all instabilities of a changeset. |
831 (EXPERIMENTAL) | 950 (EXPERIMENTAL) |
832 """ | 951 """ |
839 entries = obsutil.whyunstable(repo, ctx) | 958 entries = obsutil.whyunstable(repo, ctx) |
840 | 959 |
841 for entry in entries: | 960 for entry in entries: |
842 if entry.get('divergentnodes'): | 961 if entry.get('divergentnodes'): |
843 dnodes = entry['divergentnodes'] | 962 dnodes = entry['divergentnodes'] |
844 dnhybrid = _hybrid(None, [dnode.hex() for dnode in dnodes], | 963 dnhybrid = _hybrid( |
845 lambda x: {'ctx': repo[x]}, | 964 None, |
846 lambda x: formatnode(repo[x])) | 965 [dnode.hex() for dnode in dnodes], |
966 lambda x: {'ctx': repo[x]}, | |
967 lambda x: formatnode(repo[x]), | |
968 ) | |
847 entry['divergentnodes'] = dnhybrid | 969 entry['divergentnodes'] = dnhybrid |
848 | 970 |
849 tmpl = ('{instability}:{if(divergentnodes, " ")}{divergentnodes} ' | 971 tmpl = ( |
850 '{reason} {node|short}') | 972 '{instability}:{if(divergentnodes, " ")}{divergentnodes} ' |
973 '{reason} {node|short}' | |
974 ) | |
851 return templateutil.mappinglist(entries, tmpl=tmpl, sep='\n') | 975 return templateutil.mappinglist(entries, tmpl=tmpl, sep='\n') |
976 | |
852 | 977 |
853 def loadkeyword(ui, extname, registrarobj): | 978 def loadkeyword(ui, extname, registrarobj): |
854 """Load template keyword from specified registrarobj | 979 """Load template keyword from specified registrarobj |
855 """ | 980 """ |
856 for name, func in registrarobj._table.iteritems(): | 981 for name, func in registrarobj._table.iteritems(): |
857 keywords[name] = func | 982 keywords[name] = func |
858 | 983 |
984 | |
859 # tell hggettext to extract docstrings from these functions: | 985 # tell hggettext to extract docstrings from these functions: |
860 i18nfunctions = keywords.values() | 986 i18nfunctions = keywords.values() |