Mercurial > hg
comparison hgext/phabricator.py @ 43839:70060915c3f2
phabricator: add a "phabstatus" show view
We add a "phabstatus" show view (called as "hg show phabstatus") which
renders a dag with underway revisions associated with a differential
revision and displays their status.
The revisions shown is a subset of that shown by "work" view, only
including revisions with known by Phabricator.
Differential Revision: https://phab.mercurial-scm.org/D7506
author | Denis Laxalde <denis@laxalde.org> |
---|---|
date | Sat, 23 Nov 2019 11:04:19 +0100 |
parents | 16b607e9f714 |
children | 79c0121220e3 |
comparison
equal
deleted
inserted
replaced
43838:a47ccdcce4f9 | 43839:70060915c3f2 |
---|---|
8 | 8 |
9 This extension provides a ``phabsend`` command which sends a stack of | 9 This extension provides a ``phabsend`` command which sends a stack of |
10 changesets to Phabricator, and a ``phabread`` command which prints a stack of | 10 changesets to Phabricator, and a ``phabread`` command which prints a stack of |
11 revisions in a format suitable for :hg:`import`, and a ``phabupdate`` command | 11 revisions in a format suitable for :hg:`import`, and a ``phabupdate`` command |
12 to update statuses in batch. | 12 to update statuses in batch. |
13 | |
14 A "phabstatus" view for :hg:`show` is also provided; it displays status | |
15 information of Phabricator differentials associated with unfinished | |
16 changesets. | |
13 | 17 |
14 By default, Phabricator requires ``Test Plan`` which might prevent some | 18 By default, Phabricator requires ``Test Plan`` which might prevent some |
15 changeset from being sent. The requirement could be disabled by changing | 19 changeset from being sent. The requirement could be disabled by changing |
16 ``differential.require-test-plan-field`` config server side. | 20 ``differential.require-test-plan-field`` config server side. |
17 | 21 |
58 cmdutil, | 62 cmdutil, |
59 context, | 63 context, |
60 encoding, | 64 encoding, |
61 error, | 65 error, |
62 exthelper, | 66 exthelper, |
67 graphmod, | |
63 httpconnection as httpconnectionmod, | 68 httpconnection as httpconnectionmod, |
69 logcmdutil, | |
64 match, | 70 match, |
65 mdiff, | 71 mdiff, |
66 obsutil, | 72 obsutil, |
67 parser, | 73 parser, |
68 patch, | 74 patch, |
78 ) | 84 ) |
79 from mercurial.utils import ( | 85 from mercurial.utils import ( |
80 procutil, | 86 procutil, |
81 stringutil, | 87 stringutil, |
82 ) | 88 ) |
89 from . import show | |
90 | |
83 | 91 |
84 # Note for extension authors: ONLY specify testedwith = 'ships-with-hg-core' for | 92 # Note for extension authors: ONLY specify testedwith = 'ships-with-hg-core' for |
85 # extensions which SHIP WITH MERCURIAL. Non-mainline extensions should | 93 # extensions which SHIP WITH MERCURIAL. Non-mainline extensions should |
86 # be specifying the version(s) of Mercurial they are tested with, or | 94 # be specifying the version(s) of Mercurial they are tested with, or |
87 # leave the attribute unspecified. | 95 # leave the attribute unspecified. |
459 oldnode = getnode(lastdiff) | 467 oldnode = getnode(lastdiff) |
460 if oldnode and not has_node(oldnode): | 468 if oldnode and not has_node(oldnode): |
461 oldnode = None | 469 oldnode = None |
462 | 470 |
463 result[newnode] = (oldnode, lastdiff, drev) | 471 result[newnode] = (oldnode, lastdiff, drev) |
472 | |
473 return result | |
474 | |
475 | |
476 def getdrevmap(repo, revs): | |
477 """Return a dict mapping each rev in `revs` to their Differential Revision | |
478 ID or None. | |
479 """ | |
480 result = {} | |
481 for rev in revs: | |
482 result[rev] = None | |
483 ctx = repo[rev] | |
484 # Check commit message | |
485 m = _differentialrevisiondescre.search(ctx.description()) | |
486 if m: | |
487 result[rev] = int(m.group('id')) | |
488 continue | |
489 # Check tags | |
490 for tag in repo.nodetags(ctx.node()): | |
491 m = _differentialrevisiontagre.match(tag) | |
492 if m: | |
493 result[rev] = int(m.group(1)) | |
494 break | |
464 | 495 |
465 return result | 496 return result |
466 | 497 |
467 | 498 |
468 def getdiff(ctx, diffopts): | 499 def getdiff(ctx, diffopts): |
1649 url += b'/' | 1680 url += b'/' |
1650 url += t | 1681 url += t |
1651 | 1682 |
1652 return templateutil.hybriddict({b'url': url, b'id': t,}) | 1683 return templateutil.hybriddict({b'url': url, b'id': t,}) |
1653 return None | 1684 return None |
1685 | |
1686 | |
1687 @show.showview(b'phabstatus', csettopic=b'work') | |
1688 def phabstatusshowview(ui, repo, displayer): | |
1689 """Phabricator differiential status""" | |
1690 revs = repo.revs('sort(_underway(), topo)') | |
1691 drevmap = getdrevmap(repo, revs) | |
1692 unknownrevs, drevids, revsbydrevid = [], set([]), {} | |
1693 for rev, drevid in pycompat.iteritems(drevmap): | |
1694 if drevid is not None: | |
1695 drevids.add(drevid) | |
1696 revsbydrevid.setdefault(drevid, set([])).add(rev) | |
1697 else: | |
1698 unknownrevs.append(rev) | |
1699 | |
1700 drevs = callconduit(ui, b'differential.query', {b'ids': list(drevids)}) | |
1701 drevsbyrev = {} | |
1702 for drev in drevs: | |
1703 for rev in revsbydrevid[int(drev[b'id'])]: | |
1704 drevsbyrev[rev] = drev | |
1705 | |
1706 def phabstatus(ctx): | |
1707 drev = drevsbyrev[ctx.rev()] | |
1708 ui.write(b"\n%(uri)s %(statusName)s\n" % drev) | |
1709 | |
1710 revs -= smartset.baseset(unknownrevs) | |
1711 revdag = graphmod.dagwalker(repo, revs) | |
1712 | |
1713 ui.setconfig(b'experimental', b'graphshorten', True) | |
1714 displayer._exthook = phabstatus | |
1715 nodelen = show.longestshortest(repo, revs) | |
1716 logcmdutil.displaygraph( | |
1717 ui, | |
1718 repo, | |
1719 revdag, | |
1720 displayer, | |
1721 graphmod.asciiedges, | |
1722 props={b'nodelen': nodelen}, | |
1723 ) |