[PATCH] formatter: allow json to handle more levels of depth

Matt Mackall mpm at selenic.com
Tue Mar 8 16:43:23 EST 2016


On Wed, 2016-03-09 at 00:56 +0900, Yuya Nishihara wrote:
> On Tue, 8 Mar 2016 15:26:38 +0000, Kostia Balytskyi wrote:
> > On 3/8/16, 3:17 PM, "Yuya Nishihara" <youjah at gmail.com on behalf of yuya at tch
> > a.org> wrote:
> > > The templater requires a list of dicts, which isn't always necessary in
> > > JSON.
> > > For example, "log -Tjson" renders "tags" as follows:
> > > 
> > >  "tags": ["tip"],
> > > 
> > > We can't do that with the current formatter API. To make it compatible
> > > with
> > > the template functions, we would have to render it as follows:
> > > 
> > >  "tags": [{"tag": "tip"}]
> > > 
> > > This is IMO ugly.
> > I agree, this is ugly. Technically, the change that I'm proposing can output
> > ``"tags": ["tip"]`` as well if you do ``fm.data(tags=["tip"])``. Bigger
> > problem would be to actually use in a templated output produced by
> > formatter.
> 
> Yep. Can you give me some time to consider this? I don't have enough time
> to hack on hg on weekdays.
> 
> > > > "JSON output should be stable".
> > > 
> > > It would be a big BC to change the structure of JSON output. I know it's
> > > okay
> > > for "evolve --list" since it is experimental, but this patch isn't
> > > specific to
> > > evolve.
> > 
> > I don't get how this change is breaking. All the existing behavior stays
> > the same, one-level json gets printed by formatter in the same way
> > (at least this was my goal).
> 
> I meant multi-level data could be used by another command, and it could render
> unfortunate JSON and force us to tackle on the compatibility hell.

A good example of such a command is "hg summary". It fits pretty poorly into the
the formatter's list of dicts of simple values model.

One idea I've considered is to have non-uniform list elements. So, something
like:

$ hg sum
parent: 34812:b9296b330a54 tip
 convert: darcs use absolute_import
branch: default
commit: 28 unknown (clean)
update: 61 new changesets, 13 branch heads (merge)
phases: 54 draft, 38 secret
unstable: 20 changesets
divergent: 2 changesets
unstable: 20 changesets
divergent: 2 changesets

..becomes something like:

[
 {
  "field": "parent",
  "rev": 34812,
  "node": ...,
  "tags": ["tip"],
  "desc": "convert:..."
 },
 {
  "field": "commit",
  "unknown": 28,
  "hint": "clean",
 }
]

This has the downside that if you want to show, for instance, just the commit
hint, you have to do something like:

$ hg sum -T "{ifeq(field, "commit", hint)}"

Note that there will also be an update hint in this example, so the hint field
is overloaded.

The alternative is to flatten all the lines into a single entry, so you could do
something like:

$ hg sum -T "unknown: {commitunknown} {commithint}\n"

-- 
Mathematics is the supreme nostalgia of our time.



More information about the Mercurial-devel mailing list