Differences between revisions 3 and 4
Revision 3 as of 2014-09-15 22:19:27
Size: 4618
Editor: mpm
Comment:
Revision 4 as of 2015-12-09 18:12:08
Size: 4624
Editor: mpm
Comment:
Deletions are marked like this. Additions are marked like this.
Line 2: Line 2:
Line 6: Line 5:
Line 12: Line 10:

Ideally, we should be able to generate customizable output for all output-oriented commands.
This will give users fine-grained control for numerous tasks without adding lots of new command line switches.
Additionally, we should be able to generate output in common formats such as JSON, XML, and pickle for convenient parsing and automation without any additional code.
Ideally, we should be able to generate customizable output for all output-oriented commands. This will give users fine-grained control for numerous tasks without adding lots of new command line switches. Additionally, we should be able to generate output in common formats such as JSON, XML, and pickle for convenient parsing and automation without any additional code.
Line 18: Line 13:
Line 37: Line 31:
Line 41: Line 34:
Line 58: Line 50:
Line 61: Line 52:
We'd also like to have single-file template maps that handle a variety of commands.
This might be done by having one map key per command.
Dealing with verbosity might be done either with template conditionals or with '.verbose' key suffixes.
We'd also like to have single-file template maps that handle a variety of commands.  This might be done by having one map key per command.  Dealing with verbosity might be done either with template conditionals or with '.verbose' key suffixes.
Line 66: Line 55:

Given our simple schema, it's a relatively easy matter to construct outputs in standard marshalling formats.
One trick here, however, is dealing with non-ASCII data. Given things like filenames may not be in UTF-8 and we often don't even know their encoding (see EncodingStrategy), we can't simply convert to Unicode. Instead, we'll use [[http://bsittler.livejournal.com/10381.html|"UTF-8b"]], a scheme that can round-trip arbitrary binary data through UTF-8. This is used in various places which have encountered similar problems, for instance Python 3 uses this scheme for dealing with Unix filenames.
Given our simple schema, it's a relatively easy matter to construct outputs in standard marshalling formats.  One trick here, however, is dealing with non-ASCII data. Given things like filenames may not be in UTF-8 and we often don't even know their encoding (see EncodingStrategy), we can't simply convert to Unicode. Instead, we'll use [[http://bsittler.livejournal.com/10381.html|"UTF-8b"]], a scheme that can round-trip arbitrary binary data through UTF-8. This is used in various places which have encountered similar problems, for instance Python 3 uses this scheme for dealing with Unix filenames.
Line 71: Line 58:
Line 78: Line 64:
 * add -T option handler (./)
 * add template backend (./)
Line 79: Line 67:
 * add template backend
 * add -T option handler (./)
 * convert core commands
 * convert log-like commands
 * convert remaining commands
 * convert remaining important commands:
   * summary
   * config
   * identify
   * paths
   * version
 
Line 86: Line 76:

Note:

This page is primarily intended for developers of Mercurial.

Generic Templating Plan

Adding advanced templating support to commands beyond log

1. Purpose

Ideally, we should be able to generate customizable output for all output-oriented commands. This will give users fine-grained control for numerous tasks without adding lots of new command line switches. Additionally, we should be able to generate output in common formats such as JSON, XML, and pickle for convenient parsing and automation without any additional code.

2. Interface

Here's what a simple use of templates might look like for a 'showfiles' command:

# create a templater from the command options
fm = ui.formatter('showfiles', opts)
wctx = repo[None]
for f in wctx:
    # start a new template item
    fm.startitem()
    # pass data that's otherwise not shown to the templater
    fm.data(size=wctx[f].size())
    # show some extra data with -v
    fm.condwrite(ui.verbose, 'flags', '%d %1s ', wctx[f].flags())
    # show the path
    fm.write('path', '%s\n', f)
# shut down the templater
fm.end()

Internally, template data is modeled as a list of dictionaries, which is well-matched to most of our output. Here, we construct a list of (size, flags, path) elements.

3. Specifying a format

There are several types of format we might want to specify:

  • built-in (json, xml, pickle...)
  • style we ship (compact, svn...)
  • path to a style (/home/bob/lib/myannotate)
  • inline template spec ("{path}\t{size}\n")
  • path to a file containing a template spec (not a style)

We've added a single new command-line option -T/--template that gives us convenient access to all of these modes:

  • -T xml
  • -T compact
  • -T /some/path
  • -T '{author}\n'

3.1. Per-command styles, legacy styles, and verbosity levels

The existing templating system for log doesn't envision support for more than just the log-like commands, but we'll need to continue to support template styles built for this scheme.

We'd also like to have single-file template maps that handle a variety of commands. This might be done by having one map key per command. Dealing with verbosity might be done either with template conditionals or with '.verbose' key suffixes.

4. JSON, XML, and encoding troubles

Given our simple schema, it's a relatively easy matter to construct outputs in standard marshalling formats. One trick here, however, is dealing with non-ASCII data. Given things like filenames may not be in UTF-8 and we often don't even know their encoding (see EncodingStrategy), we can't simply convert to Unicode. Instead, we'll use "UTF-8b", a scheme that can round-trip arbitrary binary data through UTF-8. This is used in various places which have encountered similar problems, for instance Python 3 uses this scheme for dealing with Unix filenames.

5. Steps

  • add a formatter object to track formatting state (./)

  • add pass-through backend (./)

  • add debugging backend (./)

  • add UTF-8b encoder (./)

  • add JSON backend (./)

  • add pickle backend (./)

  • add -T option handler (./)

  • add template backend (./)

  • add XML backend
  • convert remaining important commands:
    • summary
    • config
    • identify
    • paths
    • version

6. Status

As of 3.2, Mercurial can generate JSON output for log-like commands and JSON/pickle/debug formats for status/tags/manifest/files.

$ hg log -r3.1 -Tjson
[
 {
  "rev": 23089,
  "node": "3178e49892020336491cdc6945885c4de26ffa8b",
  "branch": "stable",
  "phase": "public",
  "user": "Pierre-Yves David <pierre-yves.david@fb.com>",
  "date": [1406923295, 25200],
  "desc": "status: do not reverse deleted and unknown\n\nWhen reversing a status, trading \"added\" and \"removed\" make sense.\nReversing \"deleted\" and \"unknown\" does not. We stop doing it.\n\nThe reversing is documented in place for the poor soul not even able to remember\nthe index of all status elements by heart.",
  "bookmarks": [],
  "tags": ["3.1"],
  "parents": ["8864528874f77272742551223b8265ff4d125534"]
 }
]

$ hg status -Tdebug
status = {
    {'status': 'M', 'path': 'mercurial/commands.py'},
    {'status': '?', 'path': 'changes.txt'},
    {'status': '?', 'path': 'clonecache.py'},
    {'status': '?', 'path': 'contrib/minimal.wsgi'},
    {'status': '?', 'path': 'mercurial-2.4-rc.tar.gz'},
    {'status': '?', 'path': 'mercurial-2.4.tar.gz'},
    {'status': '?', 'path': 'tests/test-symlink-replace-dir.t'},
}


CategoryNewFeatures

GenericTemplatingPlan (last edited 2018-10-16 10:47:02 by YuyaNishihara)