template: add CBOR output format
The whole output is wrapped as an array just like the other serialization
formats. It's an indefinite-length array since the size is unknown while
encoding. Maybe we can add 'cbor-stream' (and 'pickle-stream') as needed.
--- a/mercurial/formatter.py Tue Mar 19 23:00:07 2019 -0700
+++ b/mercurial/formatter.py Sun Mar 10 12:57:24 2019 +0900
@@ -130,6 +130,7 @@
util,
)
from .utils import (
+ cborutil,
dateutil,
stringutil,
)
@@ -341,6 +342,18 @@
baseformatter.end(self)
self._out.write(pickle.dumps(self._data))
+class cborformatter(baseformatter):
+ '''serialize items as an indefinite-length CBOR array'''
+ def __init__(self, ui, out, topic, opts):
+ baseformatter.__init__(self, ui, topic, opts, _nullconverter)
+ self._out = out
+ self._out.write(cborutil.BEGIN_INDEFINITE_ARRAY)
+ def _showitem(self):
+ self._out.write(b''.join(cborutil.streamencode(self._item)))
+ def end(self):
+ baseformatter.end(self)
+ self._out.write(cborutil.BREAK)
+
class jsonformatter(baseformatter):
def __init__(self, ui, out, topic, opts):
baseformatter.__init__(self, ui, topic, opts, _nullconverter)
@@ -617,7 +630,9 @@
def formatter(ui, out, topic, opts):
template = opts.get("template", "")
- if template == "json":
+ if template == "cbor":
+ return cborformatter(ui, out, topic, opts)
+ elif template == "json":
return jsonformatter(ui, out, topic, opts)
elif template == "pickle":
return pickleformatter(ui, out, topic, opts)
--- a/mercurial/help/scripting.txt Tue Mar 19 23:00:07 2019 -0700
+++ b/mercurial/help/scripting.txt Sun Mar 10 12:57:24 2019 +0900
@@ -142,9 +142,11 @@
using templates to make your life easier.
The ``-T/--template`` argument allows specifying pre-defined styles.
-Mercurial ships with the machine-readable styles ``json`` and ``xml``,
-which provide JSON and XML output, respectively. These are useful for
-producing output that is machine readable as-is.
+Mercurial ships with the machine-readable styles ``cbor``, ``json``,
+and ``xml``, which provide CBOR, JSON, and XML output, respectively.
+These are useful for producing output that is machine readable as-is.
+
+(Mercurial 5.0 is required for CBOR style.)
.. important::
--- a/mercurial/logcmdutil.py Tue Mar 19 23:00:07 2019 -0700
+++ b/mercurial/logcmdutil.py Sun Mar 10 12:57:24 2019 +0900
@@ -542,7 +542,7 @@
regular display via changesetprinter() is done.
"""
postargs = (differ, opts, buffered)
- if opts.get('template') == 'json':
+ if opts.get('template') in {'cbor', 'json'}:
fm = ui.formatter('log', opts)
return changesetformatter(ui, repo, fm, *postargs)
--- a/tests/test-template-map.t Tue Mar 19 23:00:07 2019 -0700
+++ b/tests/test-template-map.t Sun Mar 10 12:57:24 2019 +0900
@@ -669,6 +669,70 @@
</log>
+test CBOR style:
+
+ $ cat <<'EOF' > "$TESTTMP/decodecborarray.py"
+ > from __future__ import absolute_import
+ > from mercurial import pycompat
+ > from mercurial.utils import (
+ > cborutil,
+ > stringutil,
+ > )
+ > data = pycompat.stdin.read()
+ > # our CBOR decoder doesn't support parsing indefinite-length arrays,
+ > # but the log output is indefinite stream by nature.
+ > assert data[:1] == cborutil.BEGIN_INDEFINITE_ARRAY
+ > assert data[-1:] == cborutil.BREAK
+ > items = cborutil.decodeall(data[1:-1])
+ > pycompat.stdout.write(stringutil.pprint(items, indent=1) + b'\n')
+ > EOF
+
+ $ hg log -k nosuch -Tcbor | "$PYTHON" "$TESTTMP/decodecborarray.py"
+ []
+
+ $ hg log -qr0:1 -Tcbor | "$PYTHON" "$TESTTMP/decodecborarray.py"
+ [
+ {
+ 'node': '1e4e1b8f71e05681d422154f5421e385fec3454f',
+ 'rev': 0
+ },
+ {
+ 'node': 'b608e9d1a3f0273ccf70fb85fd6866b3482bf965',
+ 'rev': 1
+ }
+ ]
+
+ $ hg log -vpr . -Tcbor --stat | "$PYTHON" "$TESTTMP/decodecborarray.py"
+ [
+ {
+ 'bookmarks': [],
+ 'branch': 'default',
+ 'date': [
+ 1577872860,
+ 0
+ ],
+ 'desc': 'third',
+ 'diff': 'diff -r 29114dbae42b -r 95c24699272e fourth\n--- /dev/null\tThu Jan 01 00:00:00 1970 +0000\n+++ b/fourth\tWed Jan 01 10:01:00 2020 +0000\n@@ -0,0 +1,1 @@\n+second\ndiff -r 29114dbae42b -r 95c24699272e second\n--- a/second\tMon Jan 12 13:46:40 1970 +0000\n+++ /dev/null\tThu Jan 01 00:00:00 1970 +0000\n@@ -1,1 +0,0 @@\n-second\ndiff -r 29114dbae42b -r 95c24699272e third\n--- /dev/null\tThu Jan 01 00:00:00 1970 +0000\n+++ b/third\tWed Jan 01 10:01:00 2020 +0000\n@@ -0,0 +1,1 @@\n+third\n',
+ 'diffstat': ' fourth | 1 +\n second | 1 -\n third | 1 +\n 3 files changed, 2 insertions(+), 1 deletions(-)\n',
+ 'files': [
+ 'fourth',
+ 'second',
+ 'third'
+ ],
+ 'node': '95c24699272ef57d062b8bccc32c878bf841784a',
+ 'parents': [
+ '29114dbae42b9f078cf2714dbe3a86bba8ec7453'
+ ],
+ 'phase': 'draft',
+ 'rev': 8,
+ 'tags': [
+ 'tip'
+ ],
+ 'user': 'test'
+ }
+ ]
+
+
Test JSON style:
$ hg log -k nosuch -Tjson