Patchwork [2,of,2,V2] hgweb: explain instabilities of unstable changesets

login
register
mail settings
Submitter Anton Shestakov
Date Feb. 26, 2018, 2:05 p.m.
Message ID <026f4c5a52a0070c5b71.1519653927@neuro>
Download mbox | patch
Permalink /patch/28406/
State Superseded
Headers show

Comments

Anton Shestakov - Feb. 26, 2018, 2:05 p.m.
# HG changeset patch
# User Anton Shestakov <av6@dwimlabs.net>
# Date 1519649061 -28800
#      Mon Feb 26 20:44:21 2018 +0800
# Node ID 026f4c5a52a0070c5b712cad247818e6566d4748
# Parent  0aa1728931cc2c2c7d6ee0f18e0618fc17add42a
hgweb: explain instabilities of unstable changesets

Let's bikeshed a bit more before I touch other hgweb styles or start adding
non-hgweb template keywords/functions:

- I like "explainunstable", but it works as a function name, and not so much as
  a keyword name. Other options so far are: whyunstable, reasonsunstable,
  unstablereasons, unstablesources.

- What would be the best way to implement this feature in regular templates?
  Since there can be multiple instabilities, it needs to be a list, and then
  content-divergent changesets also have a list of divergent nodes... Is there
  a better way to do this than what's done in this patch?
Yuya Nishihara - Feb. 27, 2018, 12:01 p.m.
On Mon, 26 Feb 2018 22:05:27 +0800, Anton Shestakov wrote:
> # HG changeset patch
> # User Anton Shestakov <av6@dwimlabs.net>
> # Date 1519649061 -28800
> #      Mon Feb 26 20:44:21 2018 +0800
> # Node ID 026f4c5a52a0070c5b712cad247818e6566d4748
> # Parent  0aa1728931cc2c2c7d6ee0f18e0618fc17add42a
> hgweb: explain instabilities of unstable changesets
> 
> Let's bikeshed a bit more before I touch other hgweb styles or start adding
> non-hgweb template keywords/functions:
> 
> - I like "explainunstable", but it works as a function name, and not so much as
>   a keyword name. Other options so far are: whyunstable, reasonsunstable,
>   unstablereasons, unstablesources.

"whyunstable" or "unstablereasons" seems good to me. The latter can imply it
returns a list.

> - What would be the best way to implement this feature in regular templates?
>   Since there can be multiple instabilities, it needs to be a list, and then
>   content-divergent changesets also have a list of divergent nodes... Is there
>   a better way to do this than what's done in this patch?

Perhaps that depends on how we want to write a template. If we want to list
reasons per instability for example, it's probably better to return a dict
of lists.

  unstablereasons.orphan % '{node} {reason} ...'
  unstablereasons.contentdivergent % '{divergentnodes % "{node}"} {reason} ...'

Patch

diff --git a/mercurial/hgweb/webutil.py b/mercurial/hgweb/webutil.py
--- a/mercurial/hgweb/webutil.py
+++ b/mercurial/hgweb/webutil.py
@@ -28,6 +28,7 @@  from .. import (
     error,
     match,
     mdiff,
+    obsolete,
     patch,
     pathutil,
     pycompat,
@@ -358,6 +359,13 @@  def succsandmarkers(repo, ctx):
                                        for successor in item['successors'])
         yield item
 
+def whyunstable(repo, ctx):
+    entries = obsolete.explainunstable(repo, ctx)
+    for entry in entries:
+        if entry.get('divergentnodes'):
+            entry['divergentnodes'] = _siblings(entry['divergentnodes'])
+        yield entry
+
 def commonentry(repo, ctx):
     node = ctx.node()
     return {
@@ -371,6 +379,7 @@  def commonentry(repo, ctx):
         'obsolete': ctx.obsolete(),
         'succsandmarkers': lambda **x: succsandmarkers(repo, ctx),
         'instabilities': [{"instability": i} for i in ctx.instabilities()],
+        'whyunstable': lambda **x: whyunstable(repo, ctx),
         'branch': nodebranchnodefault(ctx),
         'inbranch': nodeinbranch(repo, ctx),
         'branches': nodebranchdict(repo, ctx),
diff --git a/mercurial/templates/paper/changeset.tmpl b/mercurial/templates/paper/changeset.tmpl
--- a/mercurial/templates/paper/changeset.tmpl
+++ b/mercurial/templates/paper/changeset.tmpl
@@ -53,6 +53,10 @@ 
  <th>obsolete</th>
  <td>{join(succsandmarkers%obsfateentry, '<br>\n')}</td>
 </tr>')}
+{if(instabilities, '<tr>
+ <th>unstable</th>
+ <td>{join(whyunstable%whyunstableentry, '<br>\n')}</td>
+</tr>')}
 <tr>
  <th class="author">parents</th>
  <td class="author">{ifeq(count(parent), '2', parent%changesetparentdiff, parent%changesetparent)}</td>
diff --git a/mercurial/templates/paper/map b/mercurial/templates/paper/map
--- a/mercurial/templates/paper/map
+++ b/mercurial/templates/paper/map
@@ -216,6 +216,9 @@  obsfateoperations = '{if(obsfateoperatio
 obsfateusers = '{if(obsfateusers(markers), ' by {join(obsfateusers(markers)%'{user|obfuscate}', ', ')}')}'
 obsfatedate = '{if(obsfatedate(markers), ' {ifeq(min(obsfatedate(markers)), max(obsfatedate(markers)), '<span class="age">{min(obsfatedate(markers))|rfc822date}</span>', 'between <span class="age">{min(obsfatedate(markers))|rfc822date}</span> and <span class="age">{max(obsfatedate(markers))|rfc822date}</span>')}')}'
 obsfateentry = '{obsfateverb}{obsfateoperations}{obsfatesuccessors}{obsfateusers}{obsfatedate}'
+instabilitychangesetlink = '<a href="{url|urlescape}rev/{node|short}{sessionvars%urlparameter}">{node|short}</a>'
+divergentnode = '{instabilitychangesetlink} ({phase})'
+whyunstableentry = '{instability}: {if(divergentnodes, divergentnodes%divergentnode)} {reason} {instabilitychangesetlink}'
 
 filediffparent = '
   <tr>
diff --git a/tests/test-hgweb-commands.t b/tests/test-hgweb-commands.t
--- a/tests/test-hgweb-commands.t
+++ b/tests/test-hgweb-commands.t
@@ -903,6 +903,7 @@  Logs and changes
    <td class="date age">Thu, 01 Jan 1970 00:00:00 +0000</td>
   </tr>
   
+  
   <tr>
    <th class="author">parents</th>
    <td class="author"></td>
diff --git a/tests/test-hgweb-diffs.t b/tests/test-hgweb-diffs.t
--- a/tests/test-hgweb-diffs.t
+++ b/tests/test-hgweb-diffs.t
@@ -104,6 +104,7 @@  revision
    <td class="date age">Thu, 01 Jan 1970 00:00:00 +0000</td>
   </tr>
   
+  
   <tr>
    <th class="author">parents</th>
    <td class="author"></td>
@@ -400,6 +401,7 @@  revision
    <td class="date age">Thu, 01 Jan 1970 00:00:00 +0000</td>
   </tr>
   
+  
   <tr>
    <th class="author">parents</th>
    <td class="author"></td>
diff --git a/tests/test-hgweb-removed.t b/tests/test-hgweb-removed.t
--- a/tests/test-hgweb-removed.t
+++ b/tests/test-hgweb-removed.t
@@ -85,6 +85,7 @@  revision
    <td class="date age">Thu, 01 Jan 1970 00:00:00 +0000</td>
   </tr>
   
+  
   <tr>
    <th class="author">parents</th>
    <td class="author"><a href="/rev/cb9a9f314b8b">cb9a9f314b8b</a> </td>
diff --git a/tests/test-obsolete-divergent.t b/tests/test-obsolete-divergent.t
--- a/tests/test-obsolete-divergent.t
+++ b/tests/test-obsolete-divergent.t
@@ -720,3 +720,19 @@  Use scmutil.cleanupnodes API to create d
 
   $ hg debugexplainunstable 1a2a9b5b0030
   content-divergent: 70d5a63ca112acb3764bc1d7320ca90ea688d671 (draft) predecessor a178212c3433c4e77b573f6011e29affb8aefa33
+
+#if serve
+
+  $ hg serve -n test -p $HGPORT -d --pid-file=hg.pid -A access.log -E errors.log
+  $ cat hg.pid >> $DAEMON_PIDS
+
+check explanation for a content-divergent changeset
+
+  $ get-with-headers.py localhost:$HGPORT 'rev/1a2a9b5b0030?style=paper' | grep divergent:
+   <td>content-divergent: <a href="/rev/70d5a63ca112?style=paper">70d5a63ca112</a> (draft) predecessor <a href="/rev/a178212c3433?style=paper">a178212c3433</a></td>
+  $ get-with-headers.py localhost:$HGPORT 'rev/1a2a9b5b0030?style=coal' | grep divergent:
+   <td>content-divergent: <a href="/rev/70d5a63ca112?style=coal">70d5a63ca112</a> (draft) predecessor <a href="/rev/a178212c3433?style=coal">a178212c3433</a></td>
+
+  $ killdaemons.py
+
+#endif
diff --git a/tests/test-obsolete.t b/tests/test-obsolete.t
--- a/tests/test-obsolete.t
+++ b/tests/test-obsolete.t
@@ -1072,9 +1072,19 @@  check changeset with instabilities
     <th class="instabilities">instabilities:</th>
     <td class="instabilities">orphan phase-divergent </td>
 
+check explanation for an orphan and phase-divergent changeset
+
+  $ get-with-headers.py localhost:$HGPORT 'rev/50c51b361e60?style=paper' | egrep '(orphan|phase-divergent):'
+   <td>orphan:  obsolete parent <a href="/rev/3de5eca88c00?style=paper">3de5eca88c00</a><br>
+  phase-divergent:  immutable predecessor <a href="/rev/245bde4270cd?style=paper">245bde4270cd</a></td>
+  $ get-with-headers.py localhost:$HGPORT 'rev/50c51b361e60?style=coal' | egrep '(orphan|phase-divergent):'
+   <td>orphan:  obsolete parent <a href="/rev/3de5eca88c00?style=coal">3de5eca88c00</a><br>
+  phase-divergent:  immutable predecessor <a href="/rev/245bde4270cd?style=coal">245bde4270cd</a></td>
+
   $ killdaemons.py
 
   $ rm hg.pid access.log errors.log
+
 #endif
 
 Test incoming/outcoming with changesets obsoleted remotely, known locally