formatter: add helper to create a formatter optionally backed by file
authorYuya Nishihara <yuya@tcha.org>
Sat, 27 May 2017 17:40:18 +0900
changeset 32580 35985d407d49
parent 32579 012e0da5b759
child 32581 e9bf3e132ea9
formatter: add helper to create a formatter optionally backed by file To make things simple, openformatter() and maybereopen() have no support for a plain object API. Callers must use the "with" statement. Unlike cmdutil.makefileobj(), append mode ('ab') isn't supported by these functions. This is because JSON output can't be simply concatenated. Perhaps cmdutil.export() will have to build a {filename: [revs...]} map first and write revs per file.
mercurial/formatter.py
--- a/mercurial/formatter.py	Sun Jan 18 18:04:44 2015 +0900
+++ b/mercurial/formatter.py	Sat May 27 17:40:18 2017 +0900
@@ -103,6 +103,7 @@
 
 from __future__ import absolute_import
 
+import contextlib
 import itertools
 import os
 
@@ -432,3 +433,29 @@
     elif ui.configbool('ui', 'formatjson'):
         return jsonformatter(ui, out, topic, opts)
     return plainformatter(ui, out, topic, opts)
+
+@contextlib.contextmanager
+def openformatter(ui, filename, topic, opts):
+    """Create a formatter that writes outputs to the specified file
+
+    Must be invoked using the 'with' statement.
+    """
+    with util.posixfile(filename, 'wb') as out:
+        with formatter(ui, out, topic, opts) as fm:
+            yield fm
+
+@contextlib.contextmanager
+def _neverending(fm):
+    yield fm
+
+def maybereopen(fm, filename, opts):
+    """Create a formatter backed by file if filename specified, else return
+    the given formatter
+
+    Must be invoked using the 'with' statement. This will never call fm.end()
+    of the given formatter.
+    """
+    if filename:
+        return openformatter(fm._ui, filename, fm._topic, opts)
+    else:
+        return _neverending(fm)