changeset 32580:35985d407d49

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.
author Yuya Nishihara <yuya@tcha.org>
date Sat, 27 May 2017 17:40:18 +0900
parents 012e0da5b759
children e9bf3e132ea9
files mercurial/formatter.py
diffstat 1 files changed, 27 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- 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)