[PATCH] formatter: allow json to handle more levels of depth
Yuya Nishihara
yuya at tcha.org
Sun Mar 13 07:50:26 EDT 2016
On Tue, 08 Mar 2016 15:43:23 -0600, Matt Mackall wrote:
> On Wed, 2016-03-09 at 00:56 +0900, Yuya Nishihara wrote:
> > 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
I think a sub formatter or something can help this case. For example,
fm = ui.formatter('summary', opts)
f = fm.sub()
f.write('rev node desc', '%d:%s\n %s', rev, node, desc)
fm.startitem()
fm.write('parent', 'parent: %s\n', f.end())
...
fm.end()
For plain output, a sub formatter 'f' uses ui.push/popbuffer().
f.write('rev node desc', '%d:%s\n %s', rev, node, desc)
# write to ui._buffer
f.end()
# return '{rev}:{node}\n {desc}'
For json output, a sub formatter 'f' just keeps raw data.
f.write('rev node desc', '%d:%s\n %s', rev, node, desc)
# _data = {'rev': rev, 'node': node, 'desc': desc}
f.end()
# return _data
So, the output will be like:
[
{
"parent": {"node": "deadbeef1234", "rev": 10, "desc": "foo"},
...
}
]
> > > > 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"}]
I have no idea how to handle this cleanly. Maybe fm.writelist() or something
will be simple and can handle common cases.
fm.writelist('tags', '%s', ['tip'], sep=' ', templatename='tag')
# plain output: ' '.join('%s' % v for v in ['tip'])
# json: "tags": ["tip"]
# templater: 'tags': [{'tag': v} for v in ['tip']]
More information about the Mercurial-devel
mailing list