Patchwork [5,of,5] version: add formatter support

login
register
mail settings
Submitter Yuya Nishihara
Date Aug. 22, 2016, 2:44 p.m.
Message ID <fc30d32758af268847d2.1471877077@mimosa>
Download mbox | patch
Permalink /patch/16383/
State Accepted
Headers show

Comments

Yuya Nishihara - Aug. 22, 2016, 2:44 p.m.
# HG changeset patch
# User Yuya Nishihara <yuya@tcha.org>
# Date 1471331947 -32400
#      Tue Aug 16 16:19:07 2016 +0900
# Node ID fc30d32758af268847d2b9b200071c7b58cd6050
# Parent  f6e34ad8025ba31a7ef463205c14a450c44baea6
version: add formatter support

The license message isn't exported, which I don't think is useful and I
couldn't find a way to restructure it for JSON or template outputs.
Augie Fackler - Aug. 24, 2016, 2:18 p.m.
On Mon, Aug 22, 2016 at 11:44:37PM +0900, Yuya Nishihara wrote:
> # HG changeset patch
> # User Yuya Nishihara <yuya@tcha.org>
> # Date 1471331947 -32400
> #      Tue Aug 16 16:19:07 2016 +0900
> # Node ID fc30d32758af268847d2b9b200071c7b58cd6050
> # Parent  f6e34ad8025ba31a7ef463205c14a450c44baea6
> version: add formatter support

Nice, queued. I think I'd like to eventually see the fm.nested() stuff
as a context manager, but there also isn't really a rush on that.

>
> The license message isn't exported, which I don't think is useful and I
> couldn't find a way to restructure it for JSON or template outputs.
>
> diff --git a/mercurial/commands.py b/mercurial/commands.py
> --- a/mercurial/commands.py
> +++ b/mercurial/commands.py
> @@ -7241,36 +7241,49 @@ def verify(ui, repo):
>      """
>      return hg.verify(repo)
>
> -@command('version', [], norepo=True)
> -def version_(ui):
> +@command('version', [] + formatteropts, norepo=True)
> +def version_(ui, **opts):
>      """output version and copyright information"""
> -    ui.write(_("Mercurial Distributed SCM (version %s)\n")
> -             % util.version())
> -    ui.status(_(
> +    fm = ui.formatter("version", opts)
> +    fm.startitem()
> +    fm.write("ver", _("Mercurial Distributed SCM (version %s)\n"),
> +             util.version())
> +    license = _(
>          "(see https://mercurial-scm.org for more information)\n"
>          "\nCopyright (C) 2005-2016 Matt Mackall and others\n"
>          "This is free software; see the source for copying conditions. "
>          "There is NO\nwarranty; "
>          "not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
> -    ))
> -
> -    ui.note(_("\nEnabled extensions:\n\n"))
> +    )
> +    if not ui.quiet:
> +        fm.plain(license)
> +
> +    if ui.verbose:
> +        fm.plain(_("\nEnabled extensions:\n\n"))
>      # format names and versions into columns
>      names = []
>      vers = []
>      isinternals = []
>      for name, module in extensions.extensions():
>          names.append(name)
> -        vers.append(extensions.moduleversion(module))
> +        vers.append(extensions.moduleversion(module) or None)
>          isinternals.append(extensions.ismoduleinternal(module))
> +    fn = fm.nested("extensions")
>      if names:
> -        maxnamelen = max(len(n) for n in names)
> -        places = [_("external"), _("internal")]
> -        for i, name in enumerate(names):
> -            p = isinternals[i]
> +        namefmt = "  %%-%ds  " % max(len(n) for n in names)
> +        if fn:
> +            places = ["external", "internal"]
> +        else:
> +            places = [_("external"), _("internal")]
> +        for n, v, p in zip(names, vers, isinternals):
> +            fn.startitem()
> +            fn.condwrite(ui.verbose, "name", namefmt, n)
> +            fn.condwrite(ui.verbose, "place", "%s  ", places[p])
> +            fn.condwrite(ui.verbose and v, "ver", "%s", v)
>              if ui.verbose:
> -                ui.write("  %-*s  %s  %s\n" %
> -                         (maxnamelen, name, places[p], vers[i]))
> +                fn.plain("\n")
> +    fn.end()
> +    fm.end()
>
>  def loadcmdtable(ui, name, cmdtable):
>      """Load command functions from specified cmdtable
> diff --git a/tests/test-completion.t b/tests/test-completion.t
> --- a/tests/test-completion.t
> +++ b/tests/test-completion.t
> @@ -301,7 +301,7 @@ Show all commands + options
>    tip: patch, git, style, template
>    unbundle: update
>    verify:
> -  version:
> +  version: template
>
>    $ hg init a
>    $ cd a
> diff --git a/tests/test-extension.t b/tests/test-extension.t
> --- a/tests/test-extension.t
> +++ b/tests/test-extension.t
> @@ -1240,6 +1240,39 @@ Test version number support in 'hg versi
>    $ hg version -q --config extensions.throw=throw.py
>    Mercurial Distributed SCM (version *) (glob)
>
> +Test JSON output of version:
> +
> +  $ hg version -Tjson
> +  [
> +   {
> +    "extensions": [],
> +    "ver": "*" (glob)
> +   }
> +  ]
> +
> +  $ hg version --config extensions.throw=throw.py -Tjson
> +  [
> +   {
> +    "extensions": [{"name": "throw", "place": "external", "ver": "1.twentythree"}],
> +    "ver": "3.2.2"
> +   }
> +  ]
> +
> +  $ LANGUAGE= LC_ALL=ja_JP.UTF-8 hg version --config extensions.strip= -Tjson
> +  [
> +   {
> +    "extensions": [{"name": "strip", "place": "internal", "ver": null}],
> +    "ver": "*" (glob)
> +   }
> +  ]
> +
> +Test template output of version:
> +
> +  $ hg version --config extensions.throw=throw.py --config extensions.strip= \
> +  > -T'{extensions % "{name}  {pad(ver, 16)}  ({place})\n"}'
> +  throw  1.twentythree     (external)
> +  strip                    (internal)
> +
>  Refuse to load extensions with minimum version requirements
>
>    $ cat > minversion1.py << EOF
> _______________________________________________
> Mercurial-devel mailing list
> Mercurial-devel@mercurial-scm.org
> https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Pierre-Yves David - Aug. 26, 2016, 9:12 a.m.
On 08/22/2016 04:44 PM, Yuya Nishihara wrote:
> # HG changeset patch
> # User Yuya Nishihara <yuya@tcha.org>
> # Date 1471331947 -32400
> #      Tue Aug 16 16:19:07 2016 +0900
> # Node ID fc30d32758af268847d2b9b200071c7b58cd6050
> # Parent  f6e34ad8025ba31a7ef463205c14a450c44baea6
> version: add formatter support
>
> The license message isn't exported, which I don't think is useful and I
> couldn't find a way to restructure it for JSON or template outputs.
>
> diff --git a/mercurial/commands.py b/mercurial/commands.py
> --- a/mercurial/commands.py
> +++ b/mercurial/commands.py
> @@ -7241,36 +7241,49 @@ def verify(ui, repo):
>      """
>      return hg.verify(repo)
>
> -@command('version', [], norepo=True)
> -def version_(ui):
> +@command('version', [] + formatteropts, norepo=True)
> +def version_(ui, **opts):
>      """output version and copyright information"""
> -    ui.write(_("Mercurial Distributed SCM (version %s)\n")
> -             % util.version())
> -    ui.status(_(
> +    fm = ui.formatter("version", opts)
> +    fm.startitem()
> +    fm.write("ver", _("Mercurial Distributed SCM (version %s)\n"),
> +             util.version())
> +    license = _(
>          "(see https://mercurial-scm.org for more information)\n"
>          "\nCopyright (C) 2005-2016 Matt Mackall and others\n"
>          "This is free software; see the source for copying conditions. "
>          "There is NO\nwarranty; "
>          "not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
> -    ))
> -
> -    ui.note(_("\nEnabled extensions:\n\n"))
> +    )
> +    if not ui.quiet:
> +        fm.plain(license)
> +
> +    if ui.verbose:
> +        fm.plain(_("\nEnabled extensions:\n\n"))
>      # format names and versions into columns
>      names = []
>      vers = []
>      isinternals = []
>      for name, module in extensions.extensions():
>          names.append(name)
> -        vers.append(extensions.moduleversion(module))
> +        vers.append(extensions.moduleversion(module) or None)
>          isinternals.append(extensions.ismoduleinternal(module))
> +    fn = fm.nested("extensions")
>      if names:
> -        maxnamelen = max(len(n) for n in names)
> -        places = [_("external"), _("internal")]

Place sounds a bit strange to me. We can probably find something a bit 
better like "bundled (true/False)" or 'vendor' 
internal/external(/vendorname?).

In all case this can be done as a followup.
Yuya Nishihara - Aug. 26, 2016, 2:46 p.m.
On Fri, 26 Aug 2016 11:12:52 +0200, Pierre-Yves David wrote:
> >      if names:
> > -        maxnamelen = max(len(n) for n in names)
> > -        places = [_("external"), _("internal")]
> 
> Place sounds a bit strange to me. We can probably find something a bit 
> better like "bundled (true/False)" or 'vendor' 
> internal/external(/vendorname?).

Boolean flag makes sense, thanks.

Patch

diff --git a/mercurial/commands.py b/mercurial/commands.py
--- a/mercurial/commands.py
+++ b/mercurial/commands.py
@@ -7241,36 +7241,49 @@  def verify(ui, repo):
     """
     return hg.verify(repo)
 
-@command('version', [], norepo=True)
-def version_(ui):
+@command('version', [] + formatteropts, norepo=True)
+def version_(ui, **opts):
     """output version and copyright information"""
-    ui.write(_("Mercurial Distributed SCM (version %s)\n")
-             % util.version())
-    ui.status(_(
+    fm = ui.formatter("version", opts)
+    fm.startitem()
+    fm.write("ver", _("Mercurial Distributed SCM (version %s)\n"),
+             util.version())
+    license = _(
         "(see https://mercurial-scm.org for more information)\n"
         "\nCopyright (C) 2005-2016 Matt Mackall and others\n"
         "This is free software; see the source for copying conditions. "
         "There is NO\nwarranty; "
         "not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
-    ))
-
-    ui.note(_("\nEnabled extensions:\n\n"))
+    )
+    if not ui.quiet:
+        fm.plain(license)
+
+    if ui.verbose:
+        fm.plain(_("\nEnabled extensions:\n\n"))
     # format names and versions into columns
     names = []
     vers = []
     isinternals = []
     for name, module in extensions.extensions():
         names.append(name)
-        vers.append(extensions.moduleversion(module))
+        vers.append(extensions.moduleversion(module) or None)
         isinternals.append(extensions.ismoduleinternal(module))
+    fn = fm.nested("extensions")
     if names:
-        maxnamelen = max(len(n) for n in names)
-        places = [_("external"), _("internal")]
-        for i, name in enumerate(names):
-            p = isinternals[i]
+        namefmt = "  %%-%ds  " % max(len(n) for n in names)
+        if fn:
+            places = ["external", "internal"]
+        else:
+            places = [_("external"), _("internal")]
+        for n, v, p in zip(names, vers, isinternals):
+            fn.startitem()
+            fn.condwrite(ui.verbose, "name", namefmt, n)
+            fn.condwrite(ui.verbose, "place", "%s  ", places[p])
+            fn.condwrite(ui.verbose and v, "ver", "%s", v)
             if ui.verbose:
-                ui.write("  %-*s  %s  %s\n" %
-                         (maxnamelen, name, places[p], vers[i]))
+                fn.plain("\n")
+    fn.end()
+    fm.end()
 
 def loadcmdtable(ui, name, cmdtable):
     """Load command functions from specified cmdtable
diff --git a/tests/test-completion.t b/tests/test-completion.t
--- a/tests/test-completion.t
+++ b/tests/test-completion.t
@@ -301,7 +301,7 @@  Show all commands + options
   tip: patch, git, style, template
   unbundle: update
   verify: 
-  version: 
+  version: template
 
   $ hg init a
   $ cd a
diff --git a/tests/test-extension.t b/tests/test-extension.t
--- a/tests/test-extension.t
+++ b/tests/test-extension.t
@@ -1240,6 +1240,39 @@  Test version number support in 'hg versi
   $ hg version -q --config extensions.throw=throw.py
   Mercurial Distributed SCM (version *) (glob)
 
+Test JSON output of version:
+
+  $ hg version -Tjson
+  [
+   {
+    "extensions": [],
+    "ver": "*" (glob)
+   }
+  ]
+
+  $ hg version --config extensions.throw=throw.py -Tjson
+  [
+   {
+    "extensions": [{"name": "throw", "place": "external", "ver": "1.twentythree"}],
+    "ver": "3.2.2"
+   }
+  ]
+
+  $ LANGUAGE= LC_ALL=ja_JP.UTF-8 hg version --config extensions.strip= -Tjson
+  [
+   {
+    "extensions": [{"name": "strip", "place": "internal", "ver": null}],
+    "ver": "*" (glob)
+   }
+  ]
+
+Test template output of version:
+
+  $ hg version --config extensions.throw=throw.py --config extensions.strip= \
+  > -T'{extensions % "{name}  {pad(ver, 16)}  ({place})\n"}'
+  throw  1.twentythree     (external)
+  strip                    (internal)
+
 Refuse to load extensions with minimum version requirements
 
   $ cat > minversion1.py << EOF