--- a/hgext/phabricator.py Tue Dec 10 14:40:44 2019 -0800
+++ b/hgext/phabricator.py Sat Nov 23 11:04:19 2019 +0100
@@ -11,6 +11,10 @@
revisions in a format suitable for :hg:`import`, and a ``phabupdate`` command
to update statuses in batch.
+A "phabstatus" view for :hg:`show` is also provided; it displays status
+information of Phabricator differentials associated with unfinished
+changesets.
+
By default, Phabricator requires ``Test Plan`` which might prevent some
changeset from being sent. The requirement could be disabled by changing
``differential.require-test-plan-field`` config server side.
@@ -60,7 +64,9 @@
encoding,
error,
exthelper,
+ graphmod,
httpconnection as httpconnectionmod,
+ logcmdutil,
match,
mdiff,
obsutil,
@@ -80,6 +86,8 @@
procutil,
stringutil,
)
+from . import show
+
# Note for extension authors: ONLY specify testedwith = 'ships-with-hg-core' for
# extensions which SHIP WITH MERCURIAL. Non-mainline extensions should
@@ -465,6 +473,29 @@
return result
+def getdrevmap(repo, revs):
+ """Return a dict mapping each rev in `revs` to their Differential Revision
+ ID or None.
+ """
+ result = {}
+ for rev in revs:
+ result[rev] = None
+ ctx = repo[rev]
+ # Check commit message
+ m = _differentialrevisiondescre.search(ctx.description())
+ if m:
+ result[rev] = int(m.group('id'))
+ continue
+ # Check tags
+ for tag in repo.nodetags(ctx.node()):
+ m = _differentialrevisiontagre.match(tag)
+ if m:
+ result[rev] = int(m.group(1))
+ break
+
+ return result
+
+
def getdiff(ctx, diffopts):
"""plain-text diff without header (user, commit message, etc)"""
output = util.stringio()
@@ -1651,3 +1682,42 @@
return templateutil.hybriddict({b'url': url, b'id': t,})
return None
+
+
+@show.showview(b'phabstatus', csettopic=b'work')
+def phabstatusshowview(ui, repo, displayer):
+ """Phabricator differiential status"""
+ revs = repo.revs('sort(_underway(), topo)')
+ drevmap = getdrevmap(repo, revs)
+ unknownrevs, drevids, revsbydrevid = [], set([]), {}
+ for rev, drevid in pycompat.iteritems(drevmap):
+ if drevid is not None:
+ drevids.add(drevid)
+ revsbydrevid.setdefault(drevid, set([])).add(rev)
+ else:
+ unknownrevs.append(rev)
+
+ drevs = callconduit(ui, b'differential.query', {b'ids': list(drevids)})
+ drevsbyrev = {}
+ for drev in drevs:
+ for rev in revsbydrevid[int(drev[b'id'])]:
+ drevsbyrev[rev] = drev
+
+ def phabstatus(ctx):
+ drev = drevsbyrev[ctx.rev()]
+ ui.write(b"\n%(uri)s %(statusName)s\n" % drev)
+
+ revs -= smartset.baseset(unknownrevs)
+ revdag = graphmod.dagwalker(repo, revs)
+
+ ui.setconfig(b'experimental', b'graphshorten', True)
+ displayer._exthook = phabstatus
+ nodelen = show.longestshortest(repo, revs)
+ logcmdutil.displaygraph(
+ ui,
+ repo,
+ revdag,
+ displayer,
+ graphmod.asciiedges,
+ props={b'nodelen': nodelen},
+ )