Patchwork [6,of,6] show: show all namespaces in "work" view

login
register
mail settings
Submitter Gregory Szorc
Date June 24, 2017, 10:13 p.m.
Message ID <1992c1fd8f8babe1ea4b.1498342432@ubuntu-vm-main>
Download mbox | patch
Permalink /patch/21681/
State Accepted
Headers show

Comments

Gregory Szorc - June 24, 2017, 10:13 p.m.
# HG changeset patch
# User Gregory Szorc <gregory.szorc@gmail.com>
# Date 1498342265 25200
#      Sat Jun 24 15:11:05 2017 -0700
# Node ID 1992c1fd8f8babe1ea4b91dab7ae7b81977c94c5
# Parent  fca3aaf4880d79672d6301e3d40a94ec284dc548
show: show all namespaces in "work" view

This commit addresses a number of deficiencies in `hg show work`'s
output:

* Failure to render tags (it just wasn't implemented)
* Failure to render names associated with non-built-in namespaces
  (e.g. remotenames)
* Color names were hardcoded instead of coming from the canonical
  source in the namespace

This change has the intended effect of rendering tags and extra
namespaces. It solves an immediate need at Mozilla of having
names from a custom namespace printed, which is blocking us from
switching from a custom `hg wip` revset/template combo to `hg show
work`.

Note that the order of branches and bookmarks changes. This is
because bookmarks are registered before branches in namespaces.py.
We may want to register them last, after tags and branches. Or we
may want to added a weighted field to the namespace to control
display order. Something to think about.

I'm not a big fan of the complexity in the templating layer. There
is a lot of code to basically filter out the special case of
branch=='default' and tag=='tip'. Ideally, we would iterate over
a data structure that had irrelevant/unwanted names pre-filtered.
However, I wasn't sure how to best implement this. We probably
want {namespaces} to emit everything (its current behavior). I
was toying with the following:

* {namespacesnondefaults} variation that filtered values
* A filter function that operated on {namespaces} (I wasn't sure
  how to implement this since the filtering layer would see a
  "hybrid" instance as opposed to something that was definitely
  an iterable of namespaces.)
* A namespaces(...) function where you could specify which values
  to return. I like this the most. But it really wants named
  arguments to control filtering and we only support named arguments
  on revsets, not templates.

I figure perfect is the enemy of good and we can refine templating
support for namespaces in the future. At least now we have a
concrete example of a use case.
Yuya Nishihara - June 25, 2017, 11:43 a.m.
On Sat, 24 Jun 2017 15:13:52 -0700, Gregory Szorc wrote:
> # HG changeset patch
> # User Gregory Szorc <gregory.szorc@gmail.com>
> # Date 1498342265 25200
> #      Sat Jun 24 15:11:05 2017 -0700
> # Node ID 1992c1fd8f8babe1ea4b91dab7ae7b81977c94c5
> # Parent  fca3aaf4880d79672d6301e3d40a94ec284dc548
> show: show all namespaces in "work" view

> I'm not a big fan of the complexity in the templating layer. There
> is a lot of code to basically filter out the special case of
> branch=='default' and tag=='tip'. Ideally, we would iterate over
> a data structure that had irrelevant/unwanted names pre-filtered.
> However, I wasn't sure how to best implement this. We probably
> want {namespaces} to emit everything (its current behavior). I
> was toying with the following:
> 
> * {namespacesnondefaults} variation that filtered values
> * A filter function that operated on {namespaces} (I wasn't sure
>   how to implement this since the filtering layer would see a
>   "hybrid" instance as opposed to something that was definitely
>   an iterable of namespaces.)
> * A namespaces(...) function where you could specify which values
>   to return. I like this the most. But it really wants named
>   arguments to control filtering and we only support named arguments
>   on revsets, not templates.

It's there. See pad() for example.

> +# Treat branch and tags specially so we don't display "default" or "tip"
> +cset_namespace = '{ifeq(namespace, "branches", names_branches, ifeq(namespace, "tags", names_tags, names_others))}'
> +names_branches = '{ifeq(branch, "default", "", " ({label('log.{colorname}', branch)})")}'
> +names_tags = '{if(names % "{ifeq(name, 'tip', '', name)}", " ({label('log.{colorname}', join(names % "{ifeq(name, 'tip', '', name)}", ' '))})")}'
> +names_others = '{if(names, " ({label('log.{colorname}', join(names, ' '))})")}'

Maybe we'll need a switch expression?

  {case(namespace,
        "branches" => names_branches,
        "tags" => names_tags,
        names_others)}

('=>' instead of '=' because '=' is parsed as (key symbol, value) pair)

Patch

diff --git a/mercurial/templates/map-cmdline.show b/mercurial/templates/map-cmdline.show
--- a/mercurial/templates/map-cmdline.show
+++ b/mercurial/templates/map-cmdline.show
@@ -5,8 +5,14 @@ 
 #   map-cmdline.default.
 showbookmarks = '{if(active, "*", " ")} {pad(bookmark, longestbookmarklen + 4)}{shortest(node, 5)}\n'
 
-showwork = '{cset_shortnode}{cset_names} {cset_shortdesc}'
+showwork = '{cset_shortnode}{namespaces % cset_namespace} {cset_shortdesc}'
 
 cset_shortnode = '{label("log.changeset changeset.{phase}", shortest(node, 5))}'
-cset_names = '{if(branches, " ({label("log.branch", branch)})")}{if(bookmarks, " ({label("log.bookmarks", bookmarks)})")}'
+
+# Treat branch and tags specially so we don't display "default" or "tip"
+cset_namespace = '{ifeq(namespace, "branches", names_branches, ifeq(namespace, "tags", names_tags, names_others))}'
+names_branches = '{ifeq(branch, "default", "", " ({label('log.{colorname}', branch)})")}'
+names_tags = '{if(names % "{ifeq(name, 'tip', '', name)}", " ({label('log.{colorname}', join(names % "{ifeq(name, 'tip', '', name)}", ' '))})")}'
+names_others = '{if(names, " ({label('log.{colorname}', join(names, ' '))})")}'
+
 cset_shortdesc = '{label("log.description", desc|firstline)}'
diff --git a/tests/test-show-work.t b/tests/test-show-work.t
--- a/tests/test-show-work.t
+++ b/tests/test-show-work.t
@@ -181,10 +181,9 @@  Tags are rendered
   $ hg commit -m 'commit 3'
   $ hg tag 0.2
 
-TODO tags aren't yet rendered
   $ hg show work
   @  37582 Added tag 0.2 for changeset 6379c25b76f1
-  o  6379c commit 3
+  o  6379c (0.2) commit 3
   o  a2ad9 Added tag 0.1 for changeset 6a75536ea0b1
   |
   ~
@@ -206,14 +205,14 @@  Multiple names on same changeset render 
   $ hg commit -m 'commit 2'
 
   $ hg show work
-  @  34834 (mybranch) (mybook) commit 2
+  @  34834 (mybook) (mybranch) commit 2
   o  97fcc commit 1
 
 Multiple bookmarks on same changeset render properly
 
   $ hg book mybook2
   $ hg show work
-  @  34834 (mybranch) (mybook mybook2) commit 2
+  @  34834 (mybook mybook2) (mybranch) commit 2
   o  97fcc commit 1
 
   $ cd ..
@@ -230,10 +229,9 @@  Extra namespaces are rendered
   $ echo 2 > foo
   $ hg commit -m 'commit 3'
 
-TODO don't yet render extra namespaces
   $ hg --config extensions.revnames=$TESTDIR/revnamesext.py show work
-  @  32f3e commit 3
-  o  6a755 commit 2
-  o  97fcc commit 1
+  @  32f3e (r2) commit 3
+  o  6a755 (r1) commit 2
+  o  97fcc (r0) commit 1
 
   $ cd ..