# HG changeset patch # User Yuya Nishihara # Date 2019-10-06 03:20:35 # Node ID 90b9a7e06c2ca3a7019db8b1f26aa0fc355ee5b8 # Parent f1c5358f0d6590a17223dc8bb49006256b97274d formatter: parse name of built-in formatter templates in standard way This slightly makes it easier to add "-Tjson(...)" handling, which should be enabled only if the template specifier doesn't look like a literal template. In other words, it should be handled after "if '{' in tmpl". This makes "log -Tpickle" and "log -Tdebug" abort, which I think is better than just printing "picklepicklepickle...". diff --git a/mercurial/formatter.py b/mercurial/formatter.py --- a/mercurial/formatter.py +++ b/mercurial/formatter.py @@ -531,6 +531,7 @@ def lookuptemplate(ui, topic, tmpl): 'tmpl' can be any of the following: - a literal template (e.g. '{rev}') + - a reference to built-in template (i.e. formatter) - a map-file name or path (e.g. 'changelog') - a reference to [templates] in config file - a path to raw template file @@ -544,10 +545,17 @@ def lookuptemplate(ui, topic, tmpl): available as well as aliases in [templatealias]. """ + if not tmpl: + return templatespec(None, None, None) + # looks like a literal template? if b'{' in tmpl: return templatespec(b'', tmpl, None) + # a reference to built-in (formatter) template + if tmpl in {b'cbor', b'json', b'pickle', b'debug'}: + return templatespec(tmpl, None, None) + # perhaps a stock style? if not os.path.split(tmpl)[0]: mapname = templater.templatepath( @@ -712,17 +720,16 @@ class templateresources(templater.resour def formatter(ui, out, topic, opts): - template = opts.get(b"template", b"") - if template == b"cbor": + spec = lookuptemplate(ui, topic, opts.get(b'template', b'')) + if spec.ref == b"cbor": return cborformatter(ui, out, topic, opts) - elif template == b"json": + elif spec.ref == b"json": return jsonformatter(ui, out, topic, opts) - elif template == b"pickle": + elif spec.ref == b"pickle": return pickleformatter(ui, out, topic, opts) - elif template == b"debug": + elif spec.ref == b"debug": return debugformatter(ui, out, topic, opts) - elif template != b"": - spec = lookuptemplate(ui, topic, opts.get(b'template', b'')) + elif spec.ref or spec.tmpl or spec.mapfile: return templateformatter(ui, out, topic, opts, spec) # developer config: ui.formatdebug elif ui.configbool(b'ui', b'formatdebug'): diff --git a/mercurial/logcmdutil.py b/mercurial/logcmdutil.py --- a/mercurial/logcmdutil.py +++ b/mercurial/logcmdutil.py @@ -617,9 +617,6 @@ def _lookuptemplate(ui, tmpl, style): mapfile = mapname return templatespec(None, mapfile) - if not tmpl: - return templatespec(None, None) - return formatter.lookuptemplate(ui, b'changeset', tmpl) @@ -642,12 +639,15 @@ def changesetdisplayer(ui, repo, opts, d regular display via changesetprinter() is done. """ postargs = (differ, opts, buffered) - if opts.get(b'template') in {b'cbor', b'json'}: + spec = _lookuptemplate(ui, opts.get(b'template'), opts.get(b'style')) + + # machine-readable formats have slightly different keyword set than + # plain templates, which are handled by changesetformatter. + # note that {b'pickle', b'debug'} can also be added to the list if needed. + if spec.ref in {b'cbor', b'json'}: fm = ui.formatter(b'log', opts) return changesetformatter(ui, repo, fm, *postargs) - spec = _lookuptemplate(ui, opts.get(b'template'), opts.get(b'style')) - if not spec.ref and not spec.tmpl and not spec.mapfile: return changesetprinter(ui, repo, *postargs) diff --git a/tests/test-template-map.t b/tests/test-template-map.t --- a/tests/test-template-map.t +++ b/tests/test-template-map.t @@ -1101,6 +1101,15 @@ honor --git but not format-breaking diff } ] +Other unsupported formatter styles: + + $ hg log -qr . -Tpickle + abort: "pickle" not in template map + [255] + $ hg log -qr . -Tdebug + abort: "debug" not in template map + [255] + Error if style not readable: #if unix-permissions no-root