annotate hgext/phabricator.py @ 42295:af13e2088f77

phabricator: add custom vcr matcher to match request bodies Currently when the phabricator extension's conduit output changes the tests don't notice since the default vcr matcher only matches on 'method' and 'uri', not the body. Add a custom matcher that checks the same params are in the body (ignoring ordering). vcr's in-built body matcher can't be used since it fails under py3 with a "UnicodeEncodeError" on the "€ in commit message" tests. The DREV ids have decreased since the recordings were generated against a different phabricator instance to avoid spamming mercurial-devel. Differential Revision: https://phab.mercurial-scm.org/D6347
author Ian Moody <moz-ian@perix.co.uk>
date Sun, 05 May 2019 17:04:48 +0100
parents 231334c1ee96
children 29528c4235a1
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
33200
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
1 # phabricator.py - simple Phabricator integration
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
2 #
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
3 # Copyright 2017 Facebook, Inc.
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
4 #
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
5 # This software may be used and distributed according to the terms of the
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
6 # GNU General Public License version 2 or any later version.
39671
87539f615b87 phabricator: mark extension as experimental for now
Augie Fackler <raf@durin42.com>
parents: 39670
diff changeset
7 """simple Phabricator integration (EXPERIMENTAL)
33200
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
8
33201
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33200
diff changeset
9 This extension provides a ``phabsend`` command which sends a stack of
33993
07ffff841863 phabsend: make --amend the default
Jun Wu <quark@fb.com>
parents: 33992
diff changeset
10 changesets to Phabricator, and a ``phabread`` command which prints a stack of
07ffff841863 phabsend: make --amend the default
Jun Wu <quark@fb.com>
parents: 33992
diff changeset
11 revisions in a format suitable for :hg:`import`, and a ``phabupdate`` command
07ffff841863 phabsend: make --amend the default
Jun Wu <quark@fb.com>
parents: 33992
diff changeset
12 to update statuses in batch.
33201
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33200
diff changeset
13
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33200
diff changeset
14 By default, Phabricator requires ``Test Plan`` which might prevent some
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33200
diff changeset
15 changeset from being sent. The requirement could be disabled by changing
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33200
diff changeset
16 ``differential.require-test-plan-field`` config server side.
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33200
diff changeset
17
33200
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
18 Config::
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
19
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
20 [phabricator]
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
21 # Phabricator URL
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
22 url = https://phab.example.com/
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
23
33201
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33200
diff changeset
24 # Repo callsign. If a repo has a URL https://$HOST/diffusion/FOO, then its
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33200
diff changeset
25 # callsign is "FOO".
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33200
diff changeset
26 callsign = FOO
33202
04cf9927f350 phabricator: add phabread command to read patches
Jun Wu <quark@fb.com>
parents: 33201
diff changeset
27
34081
8b659b7388c0 phabricator: add a config to use curl for communication
Jun Wu <quark@fb.com>
parents: 34080
diff changeset
28 # curl command to use. If not set (default), use builtin HTTP library to
8b659b7388c0 phabricator: add a config to use curl for communication
Jun Wu <quark@fb.com>
parents: 34080
diff changeset
29 # communicate. If set, use the specified curl command. This could be useful
8b659b7388c0 phabricator: add a config to use curl for communication
Jun Wu <quark@fb.com>
parents: 34080
diff changeset
30 # if you need to specify advanced options that is not easily supported by
8b659b7388c0 phabricator: add a config to use curl for communication
Jun Wu <quark@fb.com>
parents: 34080
diff changeset
31 # the internal library.
8b659b7388c0 phabricator: add a config to use curl for communication
Jun Wu <quark@fb.com>
parents: 34080
diff changeset
32 curlcmd = curl --connect-timeout 2 --retry 3 --silent
36795
4397909f82d3 phabricator: specify API tokens per host, rather than per repo
Tom Prince <mozilla@hocat.ca>
parents: 36543
diff changeset
33
38039
0fa050bc68cb phabricator: migrate [phabricator.auth] to [auth]
Matt Harbison <matt_harbison@yahoo.com>
parents: 38020
diff changeset
34 [auth]
38040
71cf20d47f25 phabricator: split auth.url into the standard auth.schemes and auth.prefix
Matt Harbison <matt_harbison@yahoo.com>
parents: 38039
diff changeset
35 example.schemes = https
71cf20d47f25 phabricator: split auth.url into the standard auth.schemes and auth.prefix
Matt Harbison <matt_harbison@yahoo.com>
parents: 38039
diff changeset
36 example.prefix = phab.example.com
71cf20d47f25 phabricator: split auth.url into the standard auth.schemes and auth.prefix
Matt Harbison <matt_harbison@yahoo.com>
parents: 38039
diff changeset
37
36795
4397909f82d3 phabricator: specify API tokens per host, rather than per repo
Tom Prince <mozilla@hocat.ca>
parents: 36543
diff changeset
38 # API token. Get it from https://$HOST/conduit/login/
38039
0fa050bc68cb phabricator: migrate [phabricator.auth] to [auth]
Matt Harbison <matt_harbison@yahoo.com>
parents: 38020
diff changeset
39 example.phabtoken = cli-xxxxxxxxxxxxxxxxxxxxxxxxxxxx
33200
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
40 """
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
41
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
42 from __future__ import absolute_import
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
43
41083
9d35ae3d9999 phabricator: ensure that the return of urlopener.open() is closed
Matt Harbison <matt_harbison@yahoo.com>
parents: 41081
diff changeset
44 import contextlib
33853
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33852
diff changeset
45 import itertools
33200
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
46 import json
33853
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33852
diff changeset
47 import operator
33201
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33200
diff changeset
48 import re
33200
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
49
33443
e48082e0a8d5 phabricator: verify local tags before trusting them
Jun Wu <quark@fb.com>
parents: 33442
diff changeset
50 from mercurial.node import bin, nullid
33200
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
51 from mercurial.i18n import _
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
52 from mercurial import (
33808
fa3aa6c98bb7 phabricator: add --amend option to phabsend
Jun Wu <quark@fb.com>
parents: 33806
diff changeset
53 cmdutil,
fa3aa6c98bb7 phabricator: add --amend option to phabsend
Jun Wu <quark@fb.com>
parents: 33806
diff changeset
54 context,
33201
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33200
diff changeset
55 encoding,
33200
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
56 error,
38040
71cf20d47f25 phabricator: split auth.url into the standard auth.schemes and auth.prefix
Matt Harbison <matt_harbison@yahoo.com>
parents: 38039
diff changeset
57 httpconnection as httpconnectionmod,
33201
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33200
diff changeset
58 mdiff,
33761
e6d8ee3c9ec3 obsutil: rename allprecursors into allpredecessors
Boris Feld <boris.feld@octobus.net>
parents: 33718
diff changeset
59 obsutil,
33853
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33852
diff changeset
60 parser,
33201
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33200
diff changeset
61 patch,
41163
0101a35deae2 phabricator: warn if unable to amend, instead of aborting after posting
Matt Harbison <matt_harbison@yahoo.com>
parents: 41083
diff changeset
62 phases,
41902
c340a8ac7ef3 phabricator: convert conduit response JSON unicode to bytes inside callconduit
Ian Moody <moz-ian@perix.co.uk>
parents: 41716
diff changeset
63 pycompat,
33200
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
64 registrar,
33201
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33200
diff changeset
65 scmutil,
33853
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33852
diff changeset
66 smartset,
33201
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33200
diff changeset
67 tags,
42226
289d82a070e9 phabricator: use templatefilters.json in writediffproperties
Ian Moody <moz-ian@perix.co.uk>
parents: 41976
diff changeset
68 templatefilters,
39670
4057e38bba76 phabricator: fix templating bug by using hybriddict
Augie Fackler <raf@durin42.com>
parents: 39668
diff changeset
69 templateutil,
33200
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
70 url as urlmod,
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
71 util,
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
72 )
37123
a8a902d7176e procutil: bulk-replace function calls to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 36826
diff changeset
73 from mercurial.utils import (
a8a902d7176e procutil: bulk-replace function calls to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 36826
diff changeset
74 procutil,
37800
6cf5f5b4eb57 phabricator: specify some metadata compatibly with arc
Tom Prince <mozilla@hocat.ca>
parents: 37123
diff changeset
75 stringutil,
37123
a8a902d7176e procutil: bulk-replace function calls to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 36826
diff changeset
76 )
33200
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
77
39751
c0c703861b60 phabricator: add testedwith boilerplate
Yuya Nishihara <yuya@tcha.org>
parents: 39671
diff changeset
78 # Note for extension authors: ONLY specify testedwith = 'ships-with-hg-core' for
c0c703861b60 phabricator: add testedwith boilerplate
Yuya Nishihara <yuya@tcha.org>
parents: 39671
diff changeset
79 # extensions which SHIP WITH MERCURIAL. Non-mainline extensions should
c0c703861b60 phabricator: add testedwith boilerplate
Yuya Nishihara <yuya@tcha.org>
parents: 39671
diff changeset
80 # be specifying the version(s) of Mercurial they are tested with, or
c0c703861b60 phabricator: add testedwith boilerplate
Yuya Nishihara <yuya@tcha.org>
parents: 39671
diff changeset
81 # leave the attribute unspecified.
c0c703861b60 phabricator: add testedwith boilerplate
Yuya Nishihara <yuya@tcha.org>
parents: 39671
diff changeset
82 testedwith = 'ships-with-hg-core'
c0c703861b60 phabricator: add testedwith boilerplate
Yuya Nishihara <yuya@tcha.org>
parents: 39671
diff changeset
83
33200
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
84 cmdtable = {}
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
85 command = registrar.command(cmdtable)
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
86
38075
5a7cf42ba6ef phabricator: register config settings
Matt Harbison <matt_harbison@yahoo.com>
parents: 38040
diff changeset
87 configtable = {}
5a7cf42ba6ef phabricator: register config settings
Matt Harbison <matt_harbison@yahoo.com>
parents: 38040
diff changeset
88 configitem = registrar.configitem(configtable)
5a7cf42ba6ef phabricator: register config settings
Matt Harbison <matt_harbison@yahoo.com>
parents: 38040
diff changeset
89
5a7cf42ba6ef phabricator: register config settings
Matt Harbison <matt_harbison@yahoo.com>
parents: 38040
diff changeset
90 # developer config: phabricator.batchsize
38398
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38342
diff changeset
91 configitem(b'phabricator', b'batchsize',
38075
5a7cf42ba6ef phabricator: register config settings
Matt Harbison <matt_harbison@yahoo.com>
parents: 38040
diff changeset
92 default=12,
5a7cf42ba6ef phabricator: register config settings
Matt Harbison <matt_harbison@yahoo.com>
parents: 38040
diff changeset
93 )
38398
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38342
diff changeset
94 configitem(b'phabricator', b'callsign',
38075
5a7cf42ba6ef phabricator: register config settings
Matt Harbison <matt_harbison@yahoo.com>
parents: 38040
diff changeset
95 default=None,
5a7cf42ba6ef phabricator: register config settings
Matt Harbison <matt_harbison@yahoo.com>
parents: 38040
diff changeset
96 )
38398
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38342
diff changeset
97 configitem(b'phabricator', b'curlcmd',
38075
5a7cf42ba6ef phabricator: register config settings
Matt Harbison <matt_harbison@yahoo.com>
parents: 38040
diff changeset
98 default=None,
5a7cf42ba6ef phabricator: register config settings
Matt Harbison <matt_harbison@yahoo.com>
parents: 38040
diff changeset
99 )
5a7cf42ba6ef phabricator: register config settings
Matt Harbison <matt_harbison@yahoo.com>
parents: 38040
diff changeset
100 # developer config: phabricator.repophid
38398
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38342
diff changeset
101 configitem(b'phabricator', b'repophid',
38075
5a7cf42ba6ef phabricator: register config settings
Matt Harbison <matt_harbison@yahoo.com>
parents: 38040
diff changeset
102 default=None,
5a7cf42ba6ef phabricator: register config settings
Matt Harbison <matt_harbison@yahoo.com>
parents: 38040
diff changeset
103 )
38398
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38342
diff changeset
104 configitem(b'phabricator', b'url',
38075
5a7cf42ba6ef phabricator: register config settings
Matt Harbison <matt_harbison@yahoo.com>
parents: 38040
diff changeset
105 default=None,
5a7cf42ba6ef phabricator: register config settings
Matt Harbison <matt_harbison@yahoo.com>
parents: 38040
diff changeset
106 )
38398
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38342
diff changeset
107 configitem(b'phabsend', b'confirm',
38075
5a7cf42ba6ef phabricator: register config settings
Matt Harbison <matt_harbison@yahoo.com>
parents: 38040
diff changeset
108 default=False,
5a7cf42ba6ef phabricator: register config settings
Matt Harbison <matt_harbison@yahoo.com>
parents: 38040
diff changeset
109 )
5a7cf42ba6ef phabricator: register config settings
Matt Harbison <matt_harbison@yahoo.com>
parents: 38040
diff changeset
110
34080
941c33cfde81 phabricator: standardize colors
Jun Wu <quark@fb.com>
parents: 33996
diff changeset
111 colortable = {
38398
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38342
diff changeset
112 b'phabricator.action.created': b'green',
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38342
diff changeset
113 b'phabricator.action.skipped': b'magenta',
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38342
diff changeset
114 b'phabricator.action.updated': b'magenta',
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38342
diff changeset
115 b'phabricator.desc': b'',
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38342
diff changeset
116 b'phabricator.drev': b'bold',
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38342
diff changeset
117 b'phabricator.node': b'',
34080
941c33cfde81 phabricator: standardize colors
Jun Wu <quark@fb.com>
parents: 33996
diff changeset
118 }
941c33cfde81 phabricator: standardize colors
Jun Wu <quark@fb.com>
parents: 33996
diff changeset
119
39666
d8f07b16abfc phabricator: add support for using the vcr library to mock interactions
Augie Fackler <raf@durin42.com>
parents: 38983
diff changeset
120 _VCR_FLAGS = [
d8f07b16abfc phabricator: add support for using the vcr library to mock interactions
Augie Fackler <raf@durin42.com>
parents: 38983
diff changeset
121 (b'', b'test-vcr', b'',
d8f07b16abfc phabricator: add support for using the vcr library to mock interactions
Augie Fackler <raf@durin42.com>
parents: 38983
diff changeset
122 _(b'Path to a vcr file. If nonexistent, will record a new vcr transcript'
d8f07b16abfc phabricator: add support for using the vcr library to mock interactions
Augie Fackler <raf@durin42.com>
parents: 38983
diff changeset
123 b', otherwise will mock all http requests using the specified vcr file.'
d8f07b16abfc phabricator: add support for using the vcr library to mock interactions
Augie Fackler <raf@durin42.com>
parents: 38983
diff changeset
124 b' (ADVANCED)'
d8f07b16abfc phabricator: add support for using the vcr library to mock interactions
Augie Fackler <raf@durin42.com>
parents: 38983
diff changeset
125 )),
d8f07b16abfc phabricator: add support for using the vcr library to mock interactions
Augie Fackler <raf@durin42.com>
parents: 38983
diff changeset
126 ]
d8f07b16abfc phabricator: add support for using the vcr library to mock interactions
Augie Fackler <raf@durin42.com>
parents: 38983
diff changeset
127
41076
536beb130f3c phabricator: assign commands to help categories
Matt Harbison <matt_harbison@yahoo.com>
parents: 40435
diff changeset
128 def vcrcommand(name, flags, spec, helpcategory=None):
39666
d8f07b16abfc phabricator: add support for using the vcr library to mock interactions
Augie Fackler <raf@durin42.com>
parents: 38983
diff changeset
129 fullflags = flags + _VCR_FLAGS
42295
af13e2088f77 phabricator: add custom vcr matcher to match request bodies
Ian Moody <moz-ian@perix.co.uk>
parents: 42286
diff changeset
130 def hgmatcher(r1, r2):
af13e2088f77 phabricator: add custom vcr matcher to match request bodies
Ian Moody <moz-ian@perix.co.uk>
parents: 42286
diff changeset
131 if r1.uri != r2.uri or r1.method != r2.method:
af13e2088f77 phabricator: add custom vcr matcher to match request bodies
Ian Moody <moz-ian@perix.co.uk>
parents: 42286
diff changeset
132 return False
af13e2088f77 phabricator: add custom vcr matcher to match request bodies
Ian Moody <moz-ian@perix.co.uk>
parents: 42286
diff changeset
133 r1params = r1.body.split(b'&')
af13e2088f77 phabricator: add custom vcr matcher to match request bodies
Ian Moody <moz-ian@perix.co.uk>
parents: 42286
diff changeset
134 r2params = r2.body.split(b'&')
af13e2088f77 phabricator: add custom vcr matcher to match request bodies
Ian Moody <moz-ian@perix.co.uk>
parents: 42286
diff changeset
135 return set(r1params) == set(r2params)
af13e2088f77 phabricator: add custom vcr matcher to match request bodies
Ian Moody <moz-ian@perix.co.uk>
parents: 42286
diff changeset
136
39666
d8f07b16abfc phabricator: add support for using the vcr library to mock interactions
Augie Fackler <raf@durin42.com>
parents: 38983
diff changeset
137 def decorate(fn):
d8f07b16abfc phabricator: add support for using the vcr library to mock interactions
Augie Fackler <raf@durin42.com>
parents: 38983
diff changeset
138 def inner(*args, **kwargs):
41903
2bad8f92cebf py3: use fsencode for vcr recording paths and strings for custom_patches args
Ian Moody <moz-ian@perix.co.uk>
parents: 41902
diff changeset
139 cassette = pycompat.fsdecode(kwargs.pop(r'test_vcr', None))
39666
d8f07b16abfc phabricator: add support for using the vcr library to mock interactions
Augie Fackler <raf@durin42.com>
parents: 38983
diff changeset
140 if cassette:
d8f07b16abfc phabricator: add support for using the vcr library to mock interactions
Augie Fackler <raf@durin42.com>
parents: 38983
diff changeset
141 import hgdemandimport
d8f07b16abfc phabricator: add support for using the vcr library to mock interactions
Augie Fackler <raf@durin42.com>
parents: 38983
diff changeset
142 with hgdemandimport.deactivated():
d8f07b16abfc phabricator: add support for using the vcr library to mock interactions
Augie Fackler <raf@durin42.com>
parents: 38983
diff changeset
143 import vcr as vcrmod
d8f07b16abfc phabricator: add support for using the vcr library to mock interactions
Augie Fackler <raf@durin42.com>
parents: 38983
diff changeset
144 import vcr.stubs as stubs
40378
b015f30a91fb phabricator: do more of the VCR work in demandimport.deactivated()
Augie Fackler <augie@google.com>
parents: 40151
diff changeset
145 vcr = vcrmod.VCR(
b015f30a91fb phabricator: do more of the VCR work in demandimport.deactivated()
Augie Fackler <augie@google.com>
parents: 40151
diff changeset
146 serializer=r'json',
b015f30a91fb phabricator: do more of the VCR work in demandimport.deactivated()
Augie Fackler <augie@google.com>
parents: 40151
diff changeset
147 custom_patches=[
41903
2bad8f92cebf py3: use fsencode for vcr recording paths and strings for custom_patches args
Ian Moody <moz-ian@perix.co.uk>
parents: 41902
diff changeset
148 (urlmod, r'httpconnection',
2bad8f92cebf py3: use fsencode for vcr recording paths and strings for custom_patches args
Ian Moody <moz-ian@perix.co.uk>
parents: 41902
diff changeset
149 stubs.VCRHTTPConnection),
2bad8f92cebf py3: use fsencode for vcr recording paths and strings for custom_patches args
Ian Moody <moz-ian@perix.co.uk>
parents: 41902
diff changeset
150 (urlmod, r'httpsconnection',
40378
b015f30a91fb phabricator: do more of the VCR work in demandimport.deactivated()
Augie Fackler <augie@google.com>
parents: 40151
diff changeset
151 stubs.VCRHTTPSConnection),
b015f30a91fb phabricator: do more of the VCR work in demandimport.deactivated()
Augie Fackler <augie@google.com>
parents: 40151
diff changeset
152 ])
42295
af13e2088f77 phabricator: add custom vcr matcher to match request bodies
Ian Moody <moz-ian@perix.co.uk>
parents: 42286
diff changeset
153 vcr.register_matcher(r'hgmatcher', hgmatcher)
af13e2088f77 phabricator: add custom vcr matcher to match request bodies
Ian Moody <moz-ian@perix.co.uk>
parents: 42286
diff changeset
154 with vcr.use_cassette(cassette, match_on=[r'hgmatcher']):
40378
b015f30a91fb phabricator: do more of the VCR work in demandimport.deactivated()
Augie Fackler <augie@google.com>
parents: 40151
diff changeset
155 return fn(*args, **kwargs)
39666
d8f07b16abfc phabricator: add support for using the vcr library to mock interactions
Augie Fackler <raf@durin42.com>
parents: 38983
diff changeset
156 return fn(*args, **kwargs)
d8f07b16abfc phabricator: add support for using the vcr library to mock interactions
Augie Fackler <raf@durin42.com>
parents: 38983
diff changeset
157 inner.__name__ = fn.__name__
40435
7e2c58b08e74 phabricator: ensure the command summaries are available in extension help
Matt Harbison <matt_harbison@yahoo.com>
parents: 40378
diff changeset
158 inner.__doc__ = fn.__doc__
41076
536beb130f3c phabricator: assign commands to help categories
Matt Harbison <matt_harbison@yahoo.com>
parents: 40435
diff changeset
159 return command(name, fullflags, spec, helpcategory=helpcategory)(inner)
39666
d8f07b16abfc phabricator: add support for using the vcr library to mock interactions
Augie Fackler <raf@durin42.com>
parents: 38983
diff changeset
160 return decorate
d8f07b16abfc phabricator: add support for using the vcr library to mock interactions
Augie Fackler <raf@durin42.com>
parents: 38983
diff changeset
161
33200
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
162 def urlencodenested(params):
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
163 """like urlencode, but works with nested parameters.
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
164
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
165 For example, if params is {'a': ['b', 'c'], 'd': {'e': 'f'}}, it will be
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
166 flattened to {'a[0]': 'b', 'a[1]': 'c', 'd[e]': 'f'} and then passed to
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
167 urlencode. Note: the encoding is consistent with PHP's http_build_query.
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
168 """
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
169 flatparams = util.sortdict()
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
170 def process(prefix, obj):
40473
d7d3164e6a31 phabricator: properly encode boolean types in the request body
Matt Harbison <matt_harbison@yahoo.com>
parents: 40435
diff changeset
171 if isinstance(obj, bool):
d7d3164e6a31 phabricator: properly encode boolean types in the request body
Matt Harbison <matt_harbison@yahoo.com>
parents: 40435
diff changeset
172 obj = {True: b'true', False: b'false'}[obj] # Python -> PHP form
41905
47125193bad0 py3: convert indexes into bytes when enumerating lists in urlencodenested
Ian Moody <moz-ian@perix.co.uk>
parents: 41904
diff changeset
173 lister = lambda l: [(b'%d' % k, v) for k, v in enumerate(l)]
47125193bad0 py3: convert indexes into bytes when enumerating lists in urlencodenested
Ian Moody <moz-ian@perix.co.uk>
parents: 41904
diff changeset
174 items = {list: lister, dict: lambda x: x.items()}.get(type(obj))
33200
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
175 if items is None:
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
176 flatparams[prefix] = obj
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
177 else:
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
178 for k, v in items(obj):
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
179 if prefix:
38398
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38342
diff changeset
180 process(b'%s[%s]' % (prefix, k), v)
33200
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
181 else:
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
182 process(k, v)
38398
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38342
diff changeset
183 process(b'', params)
33200
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
184 return util.urlreq.urlencode(flatparams)
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
185
38039
0fa050bc68cb phabricator: migrate [phabricator.auth] to [auth]
Matt Harbison <matt_harbison@yahoo.com>
parents: 38020
diff changeset
186 def readurltoken(repo):
0fa050bc68cb phabricator: migrate [phabricator.auth] to [auth]
Matt Harbison <matt_harbison@yahoo.com>
parents: 38020
diff changeset
187 """return conduit url, token and make sure they exist
0fa050bc68cb phabricator: migrate [phabricator.auth] to [auth]
Matt Harbison <matt_harbison@yahoo.com>
parents: 38020
diff changeset
188
38040
71cf20d47f25 phabricator: split auth.url into the standard auth.schemes and auth.prefix
Matt Harbison <matt_harbison@yahoo.com>
parents: 38039
diff changeset
189 Currently read from [auth] config section. In the future, it might
38039
0fa050bc68cb phabricator: migrate [phabricator.auth] to [auth]
Matt Harbison <matt_harbison@yahoo.com>
parents: 38020
diff changeset
190 make sense to read from .arcconfig and .arcrc as well.
0fa050bc68cb phabricator: migrate [phabricator.auth] to [auth]
Matt Harbison <matt_harbison@yahoo.com>
parents: 38020
diff changeset
191 """
38398
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38342
diff changeset
192 url = repo.ui.config(b'phabricator', b'url')
38039
0fa050bc68cb phabricator: migrate [phabricator.auth] to [auth]
Matt Harbison <matt_harbison@yahoo.com>
parents: 38020
diff changeset
193 if not url:
38398
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38342
diff changeset
194 raise error.Abort(_(b'config %s.%s is required')
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38342
diff changeset
195 % (b'phabricator', b'url'))
38039
0fa050bc68cb phabricator: migrate [phabricator.auth] to [auth]
Matt Harbison <matt_harbison@yahoo.com>
parents: 38020
diff changeset
196
38040
71cf20d47f25 phabricator: split auth.url into the standard auth.schemes and auth.prefix
Matt Harbison <matt_harbison@yahoo.com>
parents: 38039
diff changeset
197 res = httpconnectionmod.readauthforuri(repo.ui, url, util.url(url).user)
71cf20d47f25 phabricator: split auth.url into the standard auth.schemes and auth.prefix
Matt Harbison <matt_harbison@yahoo.com>
parents: 38039
diff changeset
198 token = None
38039
0fa050bc68cb phabricator: migrate [phabricator.auth] to [auth]
Matt Harbison <matt_harbison@yahoo.com>
parents: 38020
diff changeset
199
38040
71cf20d47f25 phabricator: split auth.url into the standard auth.schemes and auth.prefix
Matt Harbison <matt_harbison@yahoo.com>
parents: 38039
diff changeset
200 if res:
71cf20d47f25 phabricator: split auth.url into the standard auth.schemes and auth.prefix
Matt Harbison <matt_harbison@yahoo.com>
parents: 38039
diff changeset
201 group, auth = res
71cf20d47f25 phabricator: split auth.url into the standard auth.schemes and auth.prefix
Matt Harbison <matt_harbison@yahoo.com>
parents: 38039
diff changeset
202
38398
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38342
diff changeset
203 repo.ui.debug(b"using auth.%s.* for authentication\n" % group)
38040
71cf20d47f25 phabricator: split auth.url into the standard auth.schemes and auth.prefix
Matt Harbison <matt_harbison@yahoo.com>
parents: 38039
diff changeset
204
38398
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38342
diff changeset
205 token = auth.get(b'phabtoken')
38039
0fa050bc68cb phabricator: migrate [phabricator.auth] to [auth]
Matt Harbison <matt_harbison@yahoo.com>
parents: 38020
diff changeset
206
36795
4397909f82d3 phabricator: specify API tokens per host, rather than per repo
Tom Prince <mozilla@hocat.ca>
parents: 36543
diff changeset
207 if not token:
40151
38ac525b44c9 phabricator: drop support for the legacy phabricator.auth.token config (BC)
Matt Harbison <matt_harbison@yahoo.com>
parents: 39751
diff changeset
208 raise error.Abort(_(b'Can\'t find conduit token associated to %s')
38ac525b44c9 phabricator: drop support for the legacy phabricator.auth.token config (BC)
Matt Harbison <matt_harbison@yahoo.com>
parents: 39751
diff changeset
209 % (url,))
36795
4397909f82d3 phabricator: specify API tokens per host, rather than per repo
Tom Prince <mozilla@hocat.ca>
parents: 36543
diff changeset
210
4397909f82d3 phabricator: specify API tokens per host, rather than per repo
Tom Prince <mozilla@hocat.ca>
parents: 36543
diff changeset
211 return url, token
33200
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
212
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
213 def callconduit(repo, name, params):
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
214 """call Conduit API, params is a dict. return json.loads result, or None"""
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
215 host, token = readurltoken(repo)
38398
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38342
diff changeset
216 url, authinfo = util.url(b'/'.join([host, b'api', name])).authinfo()
41904
9a8c7c17d816 py3: don't try and format a bare dict into a byte string in callconduit
Ian Moody <moz-ian@perix.co.uk>
parents: 41903
diff changeset
217 repo.ui.debug(b'Conduit Call: %s %s\n' % (url, pycompat.byterepr(params)))
33200
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
218 params = params.copy()
38398
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38342
diff changeset
219 params[b'api.token'] = token
34081
8b659b7388c0 phabricator: add a config to use curl for communication
Jun Wu <quark@fb.com>
parents: 34080
diff changeset
220 data = urlencodenested(params)
38398
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38342
diff changeset
221 curlcmd = repo.ui.config(b'phabricator', b'curlcmd')
34081
8b659b7388c0 phabricator: add a config to use curl for communication
Jun Wu <quark@fb.com>
parents: 34080
diff changeset
222 if curlcmd:
38398
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38342
diff changeset
223 sin, sout = procutil.popen2(b'%s -d @- %s'
37123
a8a902d7176e procutil: bulk-replace function calls to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 36826
diff changeset
224 % (curlcmd, procutil.shellquote(url)))
34081
8b659b7388c0 phabricator: add a config to use curl for communication
Jun Wu <quark@fb.com>
parents: 34080
diff changeset
225 sin.write(data)
8b659b7388c0 phabricator: add a config to use curl for communication
Jun Wu <quark@fb.com>
parents: 34080
diff changeset
226 sin.close()
8b659b7388c0 phabricator: add a config to use curl for communication
Jun Wu <quark@fb.com>
parents: 34080
diff changeset
227 body = sout.read()
8b659b7388c0 phabricator: add a config to use curl for communication
Jun Wu <quark@fb.com>
parents: 34080
diff changeset
228 else:
8b659b7388c0 phabricator: add a config to use curl for communication
Jun Wu <quark@fb.com>
parents: 34080
diff changeset
229 urlopener = urlmod.opener(repo.ui, authinfo)
41906
a98dabdb5a7b py3: convert URL to str before passing it to request
Ian Moody <moz-ian@perix.co.uk>
parents: 41905
diff changeset
230 request = util.urlreq.request(pycompat.strurl(url), data=data)
41083
9d35ae3d9999 phabricator: ensure that the return of urlopener.open() is closed
Matt Harbison <matt_harbison@yahoo.com>
parents: 41081
diff changeset
231 with contextlib.closing(urlopener.open(request)) as rsp:
9d35ae3d9999 phabricator: ensure that the return of urlopener.open() is closed
Matt Harbison <matt_harbison@yahoo.com>
parents: 41081
diff changeset
232 body = rsp.read()
38398
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38342
diff changeset
233 repo.ui.debug(b'Conduit Response: %s\n' % body)
41902
c340a8ac7ef3 phabricator: convert conduit response JSON unicode to bytes inside callconduit
Ian Moody <moz-ian@perix.co.uk>
parents: 41716
diff changeset
234 parsed = pycompat.rapply(
c340a8ac7ef3 phabricator: convert conduit response JSON unicode to bytes inside callconduit
Ian Moody <moz-ian@perix.co.uk>
parents: 41716
diff changeset
235 lambda x: encoding.unitolocal(x) if isinstance(x, pycompat.unicode)
c340a8ac7ef3 phabricator: convert conduit response JSON unicode to bytes inside callconduit
Ian Moody <moz-ian@perix.co.uk>
parents: 41716
diff changeset
236 else x,
c340a8ac7ef3 phabricator: convert conduit response JSON unicode to bytes inside callconduit
Ian Moody <moz-ian@perix.co.uk>
parents: 41716
diff changeset
237 json.loads(body)
c340a8ac7ef3 phabricator: convert conduit response JSON unicode to bytes inside callconduit
Ian Moody <moz-ian@perix.co.uk>
parents: 41716
diff changeset
238 )
c340a8ac7ef3 phabricator: convert conduit response JSON unicode to bytes inside callconduit
Ian Moody <moz-ian@perix.co.uk>
parents: 41716
diff changeset
239 if parsed.get(b'error_code'):
38398
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38342
diff changeset
240 msg = (_(b'Conduit Error (%s): %s')
41902
c340a8ac7ef3 phabricator: convert conduit response JSON unicode to bytes inside callconduit
Ian Moody <moz-ian@perix.co.uk>
parents: 41716
diff changeset
241 % (parsed[b'error_code'], parsed[b'error_info']))
33200
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
242 raise error.Abort(msg)
41902
c340a8ac7ef3 phabricator: convert conduit response JSON unicode to bytes inside callconduit
Ian Moody <moz-ian@perix.co.uk>
parents: 41716
diff changeset
243 return parsed[b'result']
33200
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
244
39666
d8f07b16abfc phabricator: add support for using the vcr library to mock interactions
Augie Fackler <raf@durin42.com>
parents: 38983
diff changeset
245 @vcrcommand(b'debugcallconduit', [], _(b'METHOD'))
33200
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
246 def debugcallconduit(ui, repo, name):
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
247 """call Conduit API
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
248
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
249 Call parameters are read from stdin as a JSON blob. Result will be written
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
250 to stdout as a JSON blob.
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
251 """
41976
99e00e5c4746 py3: convert to/from bytes/unicode for json.(dump|load)s in debugcallconduit
Ian Moody <moz-ian@perix.co.uk>
parents: 41975
diff changeset
252 # json.loads only accepts bytes from 3.6+
99e00e5c4746 py3: convert to/from bytes/unicode for json.(dump|load)s in debugcallconduit
Ian Moody <moz-ian@perix.co.uk>
parents: 41975
diff changeset
253 rawparams = encoding.unifromlocal(ui.fin.read())
99e00e5c4746 py3: convert to/from bytes/unicode for json.(dump|load)s in debugcallconduit
Ian Moody <moz-ian@perix.co.uk>
parents: 41975
diff changeset
254 # json.loads only returns unicode strings
99e00e5c4746 py3: convert to/from bytes/unicode for json.(dump|load)s in debugcallconduit
Ian Moody <moz-ian@perix.co.uk>
parents: 41975
diff changeset
255 params = pycompat.rapply(lambda x:
99e00e5c4746 py3: convert to/from bytes/unicode for json.(dump|load)s in debugcallconduit
Ian Moody <moz-ian@perix.co.uk>
parents: 41975
diff changeset
256 encoding.unitolocal(x) if isinstance(x, pycompat.unicode) else x,
99e00e5c4746 py3: convert to/from bytes/unicode for json.(dump|load)s in debugcallconduit
Ian Moody <moz-ian@perix.co.uk>
parents: 41975
diff changeset
257 json.loads(rawparams)
99e00e5c4746 py3: convert to/from bytes/unicode for json.(dump|load)s in debugcallconduit
Ian Moody <moz-ian@perix.co.uk>
parents: 41975
diff changeset
258 )
99e00e5c4746 py3: convert to/from bytes/unicode for json.(dump|load)s in debugcallconduit
Ian Moody <moz-ian@perix.co.uk>
parents: 41975
diff changeset
259 # json.dumps only accepts unicode strings
99e00e5c4746 py3: convert to/from bytes/unicode for json.(dump|load)s in debugcallconduit
Ian Moody <moz-ian@perix.co.uk>
parents: 41975
diff changeset
260 result = pycompat.rapply(lambda x:
99e00e5c4746 py3: convert to/from bytes/unicode for json.(dump|load)s in debugcallconduit
Ian Moody <moz-ian@perix.co.uk>
parents: 41975
diff changeset
261 encoding.unifromlocal(x) if isinstance(x, bytes) else x,
99e00e5c4746 py3: convert to/from bytes/unicode for json.(dump|load)s in debugcallconduit
Ian Moody <moz-ian@perix.co.uk>
parents: 41975
diff changeset
262 callconduit(repo, name, params)
99e00e5c4746 py3: convert to/from bytes/unicode for json.(dump|load)s in debugcallconduit
Ian Moody <moz-ian@perix.co.uk>
parents: 41975
diff changeset
263 )
99e00e5c4746 py3: convert to/from bytes/unicode for json.(dump|load)s in debugcallconduit
Ian Moody <moz-ian@perix.co.uk>
parents: 41975
diff changeset
264 s = json.dumps(result, sort_keys=True, indent=2, separators=(u',', u': '))
99e00e5c4746 py3: convert to/from bytes/unicode for json.(dump|load)s in debugcallconduit
Ian Moody <moz-ian@perix.co.uk>
parents: 41975
diff changeset
265 ui.write(b'%s\n' % encoding.unitolocal(s))
33201
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33200
diff changeset
266
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33200
diff changeset
267 def getrepophid(repo):
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33200
diff changeset
268 """given callsign, return repository PHID or None"""
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33200
diff changeset
269 # developer config: phabricator.repophid
38398
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38342
diff changeset
270 repophid = repo.ui.config(b'phabricator', b'repophid')
33201
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33200
diff changeset
271 if repophid:
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33200
diff changeset
272 return repophid
38398
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38342
diff changeset
273 callsign = repo.ui.config(b'phabricator', b'callsign')
33201
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33200
diff changeset
274 if not callsign:
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33200
diff changeset
275 return None
38398
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38342
diff changeset
276 query = callconduit(repo, b'diffusion.repository.search',
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38342
diff changeset
277 {b'constraints': {b'callsigns': [callsign]}})
41902
c340a8ac7ef3 phabricator: convert conduit response JSON unicode to bytes inside callconduit
Ian Moody <moz-ian@perix.co.uk>
parents: 41716
diff changeset
278 if len(query[b'data']) == 0:
33201
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33200
diff changeset
279 return None
41902
c340a8ac7ef3 phabricator: convert conduit response JSON unicode to bytes inside callconduit
Ian Moody <moz-ian@perix.co.uk>
parents: 41716
diff changeset
280 repophid = query[b'data'][0][b'phid']
38398
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38342
diff changeset
281 repo.ui.setconfig(b'phabricator', b'repophid', repophid)
33201
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33200
diff changeset
282 return repophid
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33200
diff changeset
283
41546
bd3f03d8cc9f global: use raw strings for regular expressions with escapes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 41387
diff changeset
284 _differentialrevisiontagre = re.compile(br'\AD([1-9][0-9]*)\Z')
33263
ed61189763ef phabricator: check associated Differential Revision from commit message
Jun Wu <quark@fb.com>
parents: 33202
diff changeset
285 _differentialrevisiondescre = re.compile(
41546
bd3f03d8cc9f global: use raw strings for regular expressions with escapes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 41387
diff changeset
286 br'^Differential Revision:\s*(?P<url>(?:.*)D(?P<id>[1-9][0-9]*))$', re.M)
33201
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33200
diff changeset
287
33442
3ab0d5767b54 phabricator: finding old nodes in batch
Jun Wu <quark@fb.com>
parents: 33441
diff changeset
288 def getoldnodedrevmap(repo, nodelist):
3ab0d5767b54 phabricator: finding old nodes in batch
Jun Wu <quark@fb.com>
parents: 33441
diff changeset
289 """find previous nodes that has been sent to Phabricator
3ab0d5767b54 phabricator: finding old nodes in batch
Jun Wu <quark@fb.com>
parents: 33441
diff changeset
290
33717
1664406a44d9 phabricator: use Phabricator's last node information
Jun Wu <quark@fb.com>
parents: 33716
diff changeset
291 return {node: (oldnode, Differential diff, Differential Revision ID)}
33442
3ab0d5767b54 phabricator: finding old nodes in batch
Jun Wu <quark@fb.com>
parents: 33441
diff changeset
292 for node in nodelist with known previous sent versions, or associated
33717
1664406a44d9 phabricator: use Phabricator's last node information
Jun Wu <quark@fb.com>
parents: 33716
diff changeset
293 Differential Revision IDs. ``oldnode`` and ``Differential diff`` could
1664406a44d9 phabricator: use Phabricator's last node information
Jun Wu <quark@fb.com>
parents: 33716
diff changeset
294 be ``None``.
33201
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33200
diff changeset
295
33717
1664406a44d9 phabricator: use Phabricator's last node information
Jun Wu <quark@fb.com>
parents: 33716
diff changeset
296 Examines commit messages like "Differential Revision:" to get the
1664406a44d9 phabricator: use Phabricator's last node information
Jun Wu <quark@fb.com>
parents: 33716
diff changeset
297 association information.
33263
ed61189763ef phabricator: check associated Differential Revision from commit message
Jun Wu <quark@fb.com>
parents: 33202
diff changeset
298
33717
1664406a44d9 phabricator: use Phabricator's last node information
Jun Wu <quark@fb.com>
parents: 33716
diff changeset
299 If such commit message line is not found, examines all precursors and their
1664406a44d9 phabricator: use Phabricator's last node information
Jun Wu <quark@fb.com>
parents: 33716
diff changeset
300 tags. Tags with format like "D1234" are considered a match and the node
1664406a44d9 phabricator: use Phabricator's last node information
Jun Wu <quark@fb.com>
parents: 33716
diff changeset
301 with that tag, and the number after "D" (ex. 1234) will be returned.
1664406a44d9 phabricator: use Phabricator's last node information
Jun Wu <quark@fb.com>
parents: 33716
diff changeset
302
1664406a44d9 phabricator: use Phabricator's last node information
Jun Wu <quark@fb.com>
parents: 33716
diff changeset
303 The ``old node``, if not None, is guaranteed to be the last diff of
1664406a44d9 phabricator: use Phabricator's last node information
Jun Wu <quark@fb.com>
parents: 33716
diff changeset
304 corresponding Differential Revision, and exist in the repo.
33201
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33200
diff changeset
305 """
33442
3ab0d5767b54 phabricator: finding old nodes in batch
Jun Wu <quark@fb.com>
parents: 33441
diff changeset
306 unfi = repo.unfiltered()
33201
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33200
diff changeset
307 nodemap = unfi.changelog.nodemap
33263
ed61189763ef phabricator: check associated Differential Revision from commit message
Jun Wu <quark@fb.com>
parents: 33202
diff changeset
308
33717
1664406a44d9 phabricator: use Phabricator's last node information
Jun Wu <quark@fb.com>
parents: 33716
diff changeset
309 result = {} # {node: (oldnode?, lastdiff?, drev)}
1664406a44d9 phabricator: use Phabricator's last node information
Jun Wu <quark@fb.com>
parents: 33716
diff changeset
310 toconfirm = {} # {node: (force, {precnode}, drev)}
33442
3ab0d5767b54 phabricator: finding old nodes in batch
Jun Wu <quark@fb.com>
parents: 33441
diff changeset
311 for node in nodelist:
3ab0d5767b54 phabricator: finding old nodes in batch
Jun Wu <quark@fb.com>
parents: 33441
diff changeset
312 ctx = unfi[node]
33443
e48082e0a8d5 phabricator: verify local tags before trusting them
Jun Wu <quark@fb.com>
parents: 33442
diff changeset
313 # For tags like "D123", put them into "toconfirm" to verify later
33761
e6d8ee3c9ec3 obsutil: rename allprecursors into allpredecessors
Boris Feld <boris.feld@octobus.net>
parents: 33718
diff changeset
314 precnodes = list(obsutil.allpredecessors(unfi.obsstore, [node]))
33443
e48082e0a8d5 phabricator: verify local tags before trusting them
Jun Wu <quark@fb.com>
parents: 33442
diff changeset
315 for n in precnodes:
33442
3ab0d5767b54 phabricator: finding old nodes in batch
Jun Wu <quark@fb.com>
parents: 33441
diff changeset
316 if n in nodemap:
3ab0d5767b54 phabricator: finding old nodes in batch
Jun Wu <quark@fb.com>
parents: 33441
diff changeset
317 for tag in unfi.nodetags(n):
3ab0d5767b54 phabricator: finding old nodes in batch
Jun Wu <quark@fb.com>
parents: 33441
diff changeset
318 m = _differentialrevisiontagre.match(tag)
3ab0d5767b54 phabricator: finding old nodes in batch
Jun Wu <quark@fb.com>
parents: 33441
diff changeset
319 if m:
33717
1664406a44d9 phabricator: use Phabricator's last node information
Jun Wu <quark@fb.com>
parents: 33716
diff changeset
320 toconfirm[node] = (0, set(precnodes), int(m.group(1)))
33442
3ab0d5767b54 phabricator: finding old nodes in batch
Jun Wu <quark@fb.com>
parents: 33441
diff changeset
321 continue
33263
ed61189763ef phabricator: check associated Differential Revision from commit message
Jun Wu <quark@fb.com>
parents: 33202
diff changeset
322
33717
1664406a44d9 phabricator: use Phabricator's last node information
Jun Wu <quark@fb.com>
parents: 33716
diff changeset
323 # Check commit message
33442
3ab0d5767b54 phabricator: finding old nodes in batch
Jun Wu <quark@fb.com>
parents: 33441
diff changeset
324 m = _differentialrevisiondescre.search(ctx.description())
3ab0d5767b54 phabricator: finding old nodes in batch
Jun Wu <quark@fb.com>
parents: 33441
diff changeset
325 if m:
41910
16d050678047 py3: use r'' for group name arguments to MatchObjects in phabricator.py
Ian Moody <moz-ian@perix.co.uk>
parents: 41909
diff changeset
326 toconfirm[node] = (1, set(precnodes), int(m.group(r'id')))
33263
ed61189763ef phabricator: check associated Differential Revision from commit message
Jun Wu <quark@fb.com>
parents: 33202
diff changeset
327
33443
e48082e0a8d5 phabricator: verify local tags before trusting them
Jun Wu <quark@fb.com>
parents: 33442
diff changeset
328 # Double check if tags are genuine by collecting all old nodes from
e48082e0a8d5 phabricator: verify local tags before trusting them
Jun Wu <quark@fb.com>
parents: 33442
diff changeset
329 # Phabricator, and expect precursors overlap with it.
e48082e0a8d5 phabricator: verify local tags before trusting them
Jun Wu <quark@fb.com>
parents: 33442
diff changeset
330 if toconfirm:
33717
1664406a44d9 phabricator: use Phabricator's last node information
Jun Wu <quark@fb.com>
parents: 33716
diff changeset
331 drevs = [drev for force, precs, drev in toconfirm.values()]
38398
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38342
diff changeset
332 alldiffs = callconduit(unfi, b'differential.querydiffs',
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38342
diff changeset
333 {b'revisionIDs': drevs})
41902
c340a8ac7ef3 phabricator: convert conduit response JSON unicode to bytes inside callconduit
Ian Moody <moz-ian@perix.co.uk>
parents: 41716
diff changeset
334 getnode = lambda d: bin(
c340a8ac7ef3 phabricator: convert conduit response JSON unicode to bytes inside callconduit
Ian Moody <moz-ian@perix.co.uk>
parents: 41716
diff changeset
335 getdiffmeta(d).get(b'node', b'')) or None
33717
1664406a44d9 phabricator: use Phabricator's last node information
Jun Wu <quark@fb.com>
parents: 33716
diff changeset
336 for newnode, (force, precset, drev) in toconfirm.items():
1664406a44d9 phabricator: use Phabricator's last node information
Jun Wu <quark@fb.com>
parents: 33716
diff changeset
337 diffs = [d for d in alldiffs.values()
41902
c340a8ac7ef3 phabricator: convert conduit response JSON unicode to bytes inside callconduit
Ian Moody <moz-ian@perix.co.uk>
parents: 41716
diff changeset
338 if int(d[b'revisionID']) == drev]
33717
1664406a44d9 phabricator: use Phabricator's last node information
Jun Wu <quark@fb.com>
parents: 33716
diff changeset
339
1664406a44d9 phabricator: use Phabricator's last node information
Jun Wu <quark@fb.com>
parents: 33716
diff changeset
340 # "precursors" as known by Phabricator
1664406a44d9 phabricator: use Phabricator's last node information
Jun Wu <quark@fb.com>
parents: 33716
diff changeset
341 phprecset = set(getnode(d) for d in diffs)
1664406a44d9 phabricator: use Phabricator's last node information
Jun Wu <quark@fb.com>
parents: 33716
diff changeset
342
1664406a44d9 phabricator: use Phabricator's last node information
Jun Wu <quark@fb.com>
parents: 33716
diff changeset
343 # Ignore if precursors (Phabricator and local repo) do not overlap,
1664406a44d9 phabricator: use Phabricator's last node information
Jun Wu <quark@fb.com>
parents: 33716
diff changeset
344 # and force is not set (when commit message says nothing)
1664406a44d9 phabricator: use Phabricator's last node information
Jun Wu <quark@fb.com>
parents: 33716
diff changeset
345 if not force and not bool(phprecset & precset):
38398
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38342
diff changeset
346 tagname = b'D%d' % drev
33443
e48082e0a8d5 phabricator: verify local tags before trusting them
Jun Wu <quark@fb.com>
parents: 33442
diff changeset
347 tags.tag(repo, tagname, nullid, message=None, user=None,
e48082e0a8d5 phabricator: verify local tags before trusting them
Jun Wu <quark@fb.com>
parents: 33442
diff changeset
348 date=None, local=True)
38398
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38342
diff changeset
349 unfi.ui.warn(_(b'D%s: local tag removed - does not match '
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38342
diff changeset
350 b'Differential history\n') % drev)
33717
1664406a44d9 phabricator: use Phabricator's last node information
Jun Wu <quark@fb.com>
parents: 33716
diff changeset
351 continue
1664406a44d9 phabricator: use Phabricator's last node information
Jun Wu <quark@fb.com>
parents: 33716
diff changeset
352
1664406a44d9 phabricator: use Phabricator's last node information
Jun Wu <quark@fb.com>
parents: 33716
diff changeset
353 # Find the last node using Phabricator metadata, and make sure it
1664406a44d9 phabricator: use Phabricator's last node information
Jun Wu <quark@fb.com>
parents: 33716
diff changeset
354 # exists in the repo
1664406a44d9 phabricator: use Phabricator's last node information
Jun Wu <quark@fb.com>
parents: 33716
diff changeset
355 oldnode = lastdiff = None
1664406a44d9 phabricator: use Phabricator's last node information
Jun Wu <quark@fb.com>
parents: 33716
diff changeset
356 if diffs:
41902
c340a8ac7ef3 phabricator: convert conduit response JSON unicode to bytes inside callconduit
Ian Moody <moz-ian@perix.co.uk>
parents: 41716
diff changeset
357 lastdiff = max(diffs, key=lambda d: int(d[b'id']))
33717
1664406a44d9 phabricator: use Phabricator's last node information
Jun Wu <quark@fb.com>
parents: 33716
diff changeset
358 oldnode = getnode(lastdiff)
1664406a44d9 phabricator: use Phabricator's last node information
Jun Wu <quark@fb.com>
parents: 33716
diff changeset
359 if oldnode and oldnode not in nodemap:
1664406a44d9 phabricator: use Phabricator's last node information
Jun Wu <quark@fb.com>
parents: 33716
diff changeset
360 oldnode = None
1664406a44d9 phabricator: use Phabricator's last node information
Jun Wu <quark@fb.com>
parents: 33716
diff changeset
361
1664406a44d9 phabricator: use Phabricator's last node information
Jun Wu <quark@fb.com>
parents: 33716
diff changeset
362 result[newnode] = (oldnode, lastdiff, drev)
33443
e48082e0a8d5 phabricator: verify local tags before trusting them
Jun Wu <quark@fb.com>
parents: 33442
diff changeset
363
33442
3ab0d5767b54 phabricator: finding old nodes in batch
Jun Wu <quark@fb.com>
parents: 33441
diff changeset
364 return result
33201
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33200
diff changeset
365
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33200
diff changeset
366 def getdiff(ctx, diffopts):
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33200
diff changeset
367 """plain-text diff without header (user, commit message, etc)"""
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33200
diff changeset
368 output = util.stringio()
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33200
diff changeset
369 for chunk, _label in patch.diffui(ctx.repo(), ctx.p1().node(), ctx.node(),
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33200
diff changeset
370 None, opts=diffopts):
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33200
diff changeset
371 output.write(chunk)
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33200
diff changeset
372 return output.getvalue()
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33200
diff changeset
373
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33200
diff changeset
374 def creatediff(ctx):
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33200
diff changeset
375 """create a Differential Diff"""
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33200
diff changeset
376 repo = ctx.repo()
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33200
diff changeset
377 repophid = getrepophid(repo)
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33200
diff changeset
378 # Create a "Differential Diff" via "differential.createrawdiff" API
38398
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38342
diff changeset
379 params = {b'diff': getdiff(ctx, mdiff.diffopts(git=True, context=32767))}
33201
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33200
diff changeset
380 if repophid:
38398
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38342
diff changeset
381 params[b'repositoryPHID'] = repophid
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38342
diff changeset
382 diff = callconduit(repo, b'differential.createrawdiff', params)
33201
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33200
diff changeset
383 if not diff:
38398
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38342
diff changeset
384 raise error.Abort(_(b'cannot create diff for %s') % ctx)
33201
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33200
diff changeset
385 return diff
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33200
diff changeset
386
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33200
diff changeset
387 def writediffproperties(ctx, diff):
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33200
diff changeset
388 """write metadata to diff so patches could be applied losslessly"""
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33200
diff changeset
389 params = {
41902
c340a8ac7ef3 phabricator: convert conduit response JSON unicode to bytes inside callconduit
Ian Moody <moz-ian@perix.co.uk>
parents: 41716
diff changeset
390 b'diff_id': diff[b'id'],
38398
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38342
diff changeset
391 b'name': b'hg:meta',
42226
289d82a070e9 phabricator: use templatefilters.json in writediffproperties
Ian Moody <moz-ian@perix.co.uk>
parents: 41976
diff changeset
392 b'data': templatefilters.json({
289d82a070e9 phabricator: use templatefilters.json in writediffproperties
Ian Moody <moz-ian@perix.co.uk>
parents: 41976
diff changeset
393 b'user': ctx.user(),
289d82a070e9 phabricator: use templatefilters.json in writediffproperties
Ian Moody <moz-ian@perix.co.uk>
parents: 41976
diff changeset
394 b'date': b'%d %d' % ctx.date(),
42233
d49ab47be8a6 phabricator: include branch in the diffproperty metadata
Ian Moody <moz-ian@perix.co.uk>
parents: 42227
diff changeset
395 b'branch': ctx.branch(),
42226
289d82a070e9 phabricator: use templatefilters.json in writediffproperties
Ian Moody <moz-ian@perix.co.uk>
parents: 41976
diff changeset
396 b'node': ctx.hex(),
289d82a070e9 phabricator: use templatefilters.json in writediffproperties
Ian Moody <moz-ian@perix.co.uk>
parents: 41976
diff changeset
397 b'parent': ctx.p1().hex(),
33201
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33200
diff changeset
398 }),
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33200
diff changeset
399 }
38398
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38342
diff changeset
400 callconduit(ctx.repo(), b'differential.setdiffproperty', params)
33201
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33200
diff changeset
401
37800
6cf5f5b4eb57 phabricator: specify some metadata compatibly with arc
Tom Prince <mozilla@hocat.ca>
parents: 37123
diff changeset
402 params = {
41902
c340a8ac7ef3 phabricator: convert conduit response JSON unicode to bytes inside callconduit
Ian Moody <moz-ian@perix.co.uk>
parents: 41716
diff changeset
403 b'diff_id': diff[b'id'],
38398
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38342
diff changeset
404 b'name': b'local:commits',
42226
289d82a070e9 phabricator: use templatefilters.json in writediffproperties
Ian Moody <moz-ian@perix.co.uk>
parents: 41976
diff changeset
405 b'data': templatefilters.json({
289d82a070e9 phabricator: use templatefilters.json in writediffproperties
Ian Moody <moz-ian@perix.co.uk>
parents: 41976
diff changeset
406 ctx.hex(): {
289d82a070e9 phabricator: use templatefilters.json in writediffproperties
Ian Moody <moz-ian@perix.co.uk>
parents: 41976
diff changeset
407 b'author': stringutil.person(ctx.user()),
289d82a070e9 phabricator: use templatefilters.json in writediffproperties
Ian Moody <moz-ian@perix.co.uk>
parents: 41976
diff changeset
408 b'authorEmail': stringutil.email(ctx.user()),
42227
c0e30c9ee5ba phabricator: set local:commits time metadata as an int, not a string
Ian Moody <moz-ian@perix.co.uk>
parents: 42226
diff changeset
409 b'time': int(ctx.date()[0]),
42284
9421d7e12888 phabricator: include commit (node) and parent in the local:commits metadata
Ian Moody <moz-ian@perix.co.uk>
parents: 42235
diff changeset
410 b'commit': ctx.hex(),
9421d7e12888 phabricator: include commit (node) and parent in the local:commits metadata
Ian Moody <moz-ian@perix.co.uk>
parents: 42235
diff changeset
411 b'parents': [ctx.p1().hex()],
42233
d49ab47be8a6 phabricator: include branch in the diffproperty metadata
Ian Moody <moz-ian@perix.co.uk>
parents: 42227
diff changeset
412 b'branch': ctx.branch(),
37800
6cf5f5b4eb57 phabricator: specify some metadata compatibly with arc
Tom Prince <mozilla@hocat.ca>
parents: 37123
diff changeset
413 },
6cf5f5b4eb57 phabricator: specify some metadata compatibly with arc
Tom Prince <mozilla@hocat.ca>
parents: 37123
diff changeset
414 }),
6cf5f5b4eb57 phabricator: specify some metadata compatibly with arc
Tom Prince <mozilla@hocat.ca>
parents: 37123
diff changeset
415 }
38398
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38342
diff changeset
416 callconduit(ctx.repo(), b'differential.setdiffproperty', params)
37800
6cf5f5b4eb57 phabricator: specify some metadata compatibly with arc
Tom Prince <mozilla@hocat.ca>
parents: 37123
diff changeset
417
33498
b7a75b9a3386 phabricator: allow specifying reviewers on phabsend
Jun Wu <quark@fb.com>
parents: 33443
diff changeset
418 def createdifferentialrevision(ctx, revid=None, parentrevid=None, oldnode=None,
33718
f100354cce52 phabricator: update diff property even if we choose not to create a new diff
Jun Wu <quark@fb.com>
parents: 33717
diff changeset
419 olddiff=None, actions=None):
33201
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33200
diff changeset
420 """create or update a Differential Revision
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33200
diff changeset
421
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33200
diff changeset
422 If revid is None, create a new Differential Revision, otherwise update
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33200
diff changeset
423 revid. If parentrevid is not None, set it as a dependency.
33265
95f658b558a3 phabricator: do not upload new diff if nothing changes
Jun Wu <quark@fb.com>
parents: 33264
diff changeset
424
95f658b558a3 phabricator: do not upload new diff if nothing changes
Jun Wu <quark@fb.com>
parents: 33264
diff changeset
425 If oldnode is not None, check if the patch content (without commit message
95f658b558a3 phabricator: do not upload new diff if nothing changes
Jun Wu <quark@fb.com>
parents: 33264
diff changeset
426 and metadata) has changed before creating another diff.
33498
b7a75b9a3386 phabricator: allow specifying reviewers on phabsend
Jun Wu <quark@fb.com>
parents: 33443
diff changeset
427
b7a75b9a3386 phabricator: allow specifying reviewers on phabsend
Jun Wu <quark@fb.com>
parents: 33443
diff changeset
428 If actions is not None, they will be appended to the transaction.
33201
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33200
diff changeset
429 """
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33200
diff changeset
430 repo = ctx.repo()
33265
95f658b558a3 phabricator: do not upload new diff if nothing changes
Jun Wu <quark@fb.com>
parents: 33264
diff changeset
431 if oldnode:
33994
27ff2a87d8c0 phabsend: detect patch change with larger context
Jun Wu <quark@fb.com>
parents: 33993
diff changeset
432 diffopts = mdiff.diffopts(git=True, context=32767)
33265
95f658b558a3 phabricator: do not upload new diff if nothing changes
Jun Wu <quark@fb.com>
parents: 33264
diff changeset
433 oldctx = repo.unfiltered()[oldnode]
95f658b558a3 phabricator: do not upload new diff if nothing changes
Jun Wu <quark@fb.com>
parents: 33264
diff changeset
434 neednewdiff = (getdiff(ctx, diffopts) != getdiff(oldctx, diffopts))
95f658b558a3 phabricator: do not upload new diff if nothing changes
Jun Wu <quark@fb.com>
parents: 33264
diff changeset
435 else:
95f658b558a3 phabricator: do not upload new diff if nothing changes
Jun Wu <quark@fb.com>
parents: 33264
diff changeset
436 neednewdiff = True
33201
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33200
diff changeset
437
33265
95f658b558a3 phabricator: do not upload new diff if nothing changes
Jun Wu <quark@fb.com>
parents: 33264
diff changeset
438 transactions = []
95f658b558a3 phabricator: do not upload new diff if nothing changes
Jun Wu <quark@fb.com>
parents: 33264
diff changeset
439 if neednewdiff:
95f658b558a3 phabricator: do not upload new diff if nothing changes
Jun Wu <quark@fb.com>
parents: 33264
diff changeset
440 diff = creatediff(ctx)
41902
c340a8ac7ef3 phabricator: convert conduit response JSON unicode to bytes inside callconduit
Ian Moody <moz-ian@perix.co.uk>
parents: 41716
diff changeset
441 transactions.append({b'type': b'update', b'value': diff[b'phid']})
33718
f100354cce52 phabricator: update diff property even if we choose not to create a new diff
Jun Wu <quark@fb.com>
parents: 33717
diff changeset
442 else:
f100354cce52 phabricator: update diff property even if we choose not to create a new diff
Jun Wu <quark@fb.com>
parents: 33717
diff changeset
443 # Even if we don't need to upload a new diff because the patch content
f100354cce52 phabricator: update diff property even if we choose not to create a new diff
Jun Wu <quark@fb.com>
parents: 33717
diff changeset
444 # does not change. We might still need to update its metadata so
f100354cce52 phabricator: update diff property even if we choose not to create a new diff
Jun Wu <quark@fb.com>
parents: 33717
diff changeset
445 # pushers could know the correct node metadata.
f100354cce52 phabricator: update diff property even if we choose not to create a new diff
Jun Wu <quark@fb.com>
parents: 33717
diff changeset
446 assert olddiff
f100354cce52 phabricator: update diff property even if we choose not to create a new diff
Jun Wu <quark@fb.com>
parents: 33717
diff changeset
447 diff = olddiff
f100354cce52 phabricator: update diff property even if we choose not to create a new diff
Jun Wu <quark@fb.com>
parents: 33717
diff changeset
448 writediffproperties(ctx, diff)
33201
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33200
diff changeset
449
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33200
diff changeset
450 # Use a temporary summary to set dependency. There might be better ways but
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33200
diff changeset
451 # I cannot find them for now. But do not do that if we are updating an
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33200
diff changeset
452 # existing revision (revid is not None) since that introduces visible
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33200
diff changeset
453 # churns (someone edited "Summary" twice) on the web page.
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33200
diff changeset
454 if parentrevid and revid is None:
41909
634b56b54e7c py3: use %d instead of %s when formatting an int into a byte string
Ian Moody <moz-ian@perix.co.uk>
parents: 41908
diff changeset
455 summary = b'Depends on D%d' % parentrevid
38398
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38342
diff changeset
456 transactions += [{b'type': b'summary', b'value': summary},
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38342
diff changeset
457 {b'type': b'summary', b'value': b' '}]
33201
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33200
diff changeset
458
33498
b7a75b9a3386 phabricator: allow specifying reviewers on phabsend
Jun Wu <quark@fb.com>
parents: 33443
diff changeset
459 if actions:
b7a75b9a3386 phabricator: allow specifying reviewers on phabsend
Jun Wu <quark@fb.com>
parents: 33443
diff changeset
460 transactions += actions
b7a75b9a3386 phabricator: allow specifying reviewers on phabsend
Jun Wu <quark@fb.com>
parents: 33443
diff changeset
461
33201
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33200
diff changeset
462 # Parse commit message and update related fields.
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33200
diff changeset
463 desc = ctx.description()
38398
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38342
diff changeset
464 info = callconduit(repo, b'differential.parsecommitmessage',
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38342
diff changeset
465 {b'corpus': desc})
41902
c340a8ac7ef3 phabricator: convert conduit response JSON unicode to bytes inside callconduit
Ian Moody <moz-ian@perix.co.uk>
parents: 41716
diff changeset
466 for k, v in info[b'fields'].items():
38398
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38342
diff changeset
467 if k in [b'title', b'summary', b'testPlan']:
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38342
diff changeset
468 transactions.append({b'type': k, b'value': v})
33201
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33200
diff changeset
469
38398
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38342
diff changeset
470 params = {b'transactions': transactions}
33201
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33200
diff changeset
471 if revid is not None:
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33200
diff changeset
472 # Update an existing Differential Revision
38398
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38342
diff changeset
473 params[b'objectIdentifier'] = revid
33201
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33200
diff changeset
474
38398
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38342
diff changeset
475 revision = callconduit(repo, b'differential.revision.edit', params)
33201
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33200
diff changeset
476 if not revision:
38398
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38342
diff changeset
477 raise error.Abort(_(b'cannot create revision for %s') % ctx)
33201
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33200
diff changeset
478
33808
fa3aa6c98bb7 phabricator: add --amend option to phabsend
Jun Wu <quark@fb.com>
parents: 33806
diff changeset
479 return revision, diff
33201
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33200
diff changeset
480
33498
b7a75b9a3386 phabricator: allow specifying reviewers on phabsend
Jun Wu <quark@fb.com>
parents: 33443
diff changeset
481 def userphids(repo, names):
b7a75b9a3386 phabricator: allow specifying reviewers on phabsend
Jun Wu <quark@fb.com>
parents: 33443
diff changeset
482 """convert user names to PHIDs"""
41716
570e62f1dcf2 phabricator: make user searches case-insensitive
Julien Cristau <jcristau@mozilla.com>
parents: 41546
diff changeset
483 names = [name.lower() for name in names]
38398
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38342
diff changeset
484 query = {b'constraints': {b'usernames': names}}
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38342
diff changeset
485 result = callconduit(repo, b'user.search', query)
33498
b7a75b9a3386 phabricator: allow specifying reviewers on phabsend
Jun Wu <quark@fb.com>
parents: 33443
diff changeset
486 # username not found is not an error of the API. So check if we have missed
b7a75b9a3386 phabricator: allow specifying reviewers on phabsend
Jun Wu <quark@fb.com>
parents: 33443
diff changeset
487 # some names here.
41902
c340a8ac7ef3 phabricator: convert conduit response JSON unicode to bytes inside callconduit
Ian Moody <moz-ian@perix.co.uk>
parents: 41716
diff changeset
488 data = result[b'data']
c340a8ac7ef3 phabricator: convert conduit response JSON unicode to bytes inside callconduit
Ian Moody <moz-ian@perix.co.uk>
parents: 41716
diff changeset
489 resolved = set(entry[b'fields'][b'username'].lower() for entry in data)
33498
b7a75b9a3386 phabricator: allow specifying reviewers on phabsend
Jun Wu <quark@fb.com>
parents: 33443
diff changeset
490 unresolved = set(names) - resolved
b7a75b9a3386 phabricator: allow specifying reviewers on phabsend
Jun Wu <quark@fb.com>
parents: 33443
diff changeset
491 if unresolved:
38398
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38342
diff changeset
492 raise error.Abort(_(b'unknown username: %s')
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38342
diff changeset
493 % b' '.join(sorted(unresolved)))
41902
c340a8ac7ef3 phabricator: convert conduit response JSON unicode to bytes inside callconduit
Ian Moody <moz-ian@perix.co.uk>
parents: 41716
diff changeset
494 return [entry[b'phid'] for entry in data]
33498
b7a75b9a3386 phabricator: allow specifying reviewers on phabsend
Jun Wu <quark@fb.com>
parents: 33443
diff changeset
495
39666
d8f07b16abfc phabricator: add support for using the vcr library to mock interactions
Augie Fackler <raf@durin42.com>
parents: 38983
diff changeset
496 @vcrcommand(b'phabsend',
38398
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38342
diff changeset
497 [(b'r', b'rev', [], _(b'revisions to send'), _(b'REV')),
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38342
diff changeset
498 (b'', b'amend', True, _(b'update commit messages')),
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38342
diff changeset
499 (b'', b'reviewer', [], _(b'specify reviewers')),
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38342
diff changeset
500 (b'', b'confirm', None, _(b'ask for confirmation before sending'))],
41076
536beb130f3c phabricator: assign commands to help categories
Matt Harbison <matt_harbison@yahoo.com>
parents: 40435
diff changeset
501 _(b'REV [OPTIONS]'),
536beb130f3c phabricator: assign commands to help categories
Matt Harbison <matt_harbison@yahoo.com>
parents: 40435
diff changeset
502 helpcategory=command.CATEGORY_IMPORT_EXPORT)
33201
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33200
diff changeset
503 def phabsend(ui, repo, *revs, **opts):
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33200
diff changeset
504 """upload changesets to Phabricator
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33200
diff changeset
505
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33200
diff changeset
506 If there are multiple revisions specified, they will be send as a stack
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33200
diff changeset
507 with a linear dependencies relationship using the order specified by the
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33200
diff changeset
508 revset.
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33200
diff changeset
509
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33200
diff changeset
510 For the first time uploading changesets, local tags will be created to
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33200
diff changeset
511 maintain the association. After the first time, phabsend will check
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33200
diff changeset
512 obsstore and tags information so it can figure out whether to update an
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33200
diff changeset
513 existing Differential Revision, or create a new one.
33716
40cfe3197bc1 phabricator: add --confirm option to phabsend command
Pulkit Goyal <7895pulkit@gmail.com>
parents: 33601
diff changeset
514
33808
fa3aa6c98bb7 phabricator: add --amend option to phabsend
Jun Wu <quark@fb.com>
parents: 33806
diff changeset
515 If --amend is set, update commit messages so they have the
fa3aa6c98bb7 phabricator: add --amend option to phabsend
Jun Wu <quark@fb.com>
parents: 33806
diff changeset
516 ``Differential Revision`` URL, remove related tags. This is similar to what
fa3aa6c98bb7 phabricator: add --amend option to phabsend
Jun Wu <quark@fb.com>
parents: 33806
diff changeset
517 arcanist will do, and is more desired in author-push workflows. Otherwise,
fa3aa6c98bb7 phabricator: add --amend option to phabsend
Jun Wu <quark@fb.com>
parents: 33806
diff changeset
518 use local tags to record the ``Differential Revision`` association.
fa3aa6c98bb7 phabricator: add --amend option to phabsend
Jun Wu <quark@fb.com>
parents: 33806
diff changeset
519
33716
40cfe3197bc1 phabricator: add --confirm option to phabsend command
Pulkit Goyal <7895pulkit@gmail.com>
parents: 33601
diff changeset
520 The --confirm option lets you confirm changesets before sending them. You
40cfe3197bc1 phabricator: add --confirm option to phabsend command
Pulkit Goyal <7895pulkit@gmail.com>
parents: 33601
diff changeset
521 can also add following to your configuration file to make it default
33992
45a8cd74de4e phabsend: polish the docstring a bit
Jun Wu <quark@fb.com>
parents: 33855
diff changeset
522 behaviour::
33716
40cfe3197bc1 phabricator: add --confirm option to phabsend command
Pulkit Goyal <7895pulkit@gmail.com>
parents: 33601
diff changeset
523
33992
45a8cd74de4e phabsend: polish the docstring a bit
Jun Wu <quark@fb.com>
parents: 33855
diff changeset
524 [phabsend]
45a8cd74de4e phabsend: polish the docstring a bit
Jun Wu <quark@fb.com>
parents: 33855
diff changeset
525 confirm = true
33808
fa3aa6c98bb7 phabricator: add --amend option to phabsend
Jun Wu <quark@fb.com>
parents: 33806
diff changeset
526
fa3aa6c98bb7 phabricator: add --amend option to phabsend
Jun Wu <quark@fb.com>
parents: 33806
diff changeset
527 phabsend will check obsstore and the above association to decide whether to
fa3aa6c98bb7 phabricator: add --amend option to phabsend
Jun Wu <quark@fb.com>
parents: 33806
diff changeset
528 update an existing Differential Revision, or create a new one.
33201
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33200
diff changeset
529 """
41975
51ba9fbcca52 py3: use pycompat.byteskwargs on opts in phabricator.py
Ian Moody <moz-ian@perix.co.uk>
parents: 41955
diff changeset
530 opts = pycompat.byteskwargs(opts)
38398
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38342
diff changeset
531 revs = list(revs) + opts.get(b'rev', [])
33201
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33200
diff changeset
532 revs = scmutil.revrange(repo, revs)
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33200
diff changeset
533
33266
5b2391b46906 phabricator: abort if phabsend gets empty revs
Jun Wu <quark@fb.com>
parents: 33265
diff changeset
534 if not revs:
38398
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38342
diff changeset
535 raise error.Abort(_(b'phabsend requires at least one changeset'))
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38342
diff changeset
536 if opts.get(b'amend'):
33808
fa3aa6c98bb7 phabricator: add --amend option to phabsend
Jun Wu <quark@fb.com>
parents: 33806
diff changeset
537 cmdutil.checkunfinished(repo)
33266
5b2391b46906 phabricator: abort if phabsend gets empty revs
Jun Wu <quark@fb.com>
parents: 33265
diff changeset
538
33996
088598153aa2 phabsend: show associated Differential Revisions with --confirm
Jun Wu <quark@fb.com>
parents: 33995
diff changeset
539 # {newnode: (oldnode, olddiff, olddrev}
088598153aa2 phabsend: show associated Differential Revisions with --confirm
Jun Wu <quark@fb.com>
parents: 33995
diff changeset
540 oldmap = getoldnodedrevmap(repo, [repo[r].node() for r in revs])
088598153aa2 phabsend: show associated Differential Revisions with --confirm
Jun Wu <quark@fb.com>
parents: 33995
diff changeset
541
38398
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38342
diff changeset
542 confirm = ui.configbool(b'phabsend', b'confirm')
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38342
diff changeset
543 confirm |= bool(opts.get(b'confirm'))
33716
40cfe3197bc1 phabricator: add --confirm option to phabsend command
Pulkit Goyal <7895pulkit@gmail.com>
parents: 33601
diff changeset
544 if confirm:
33996
088598153aa2 phabsend: show associated Differential Revisions with --confirm
Jun Wu <quark@fb.com>
parents: 33995
diff changeset
545 confirmed = _confirmbeforesend(repo, revs, oldmap)
33716
40cfe3197bc1 phabricator: add --confirm option to phabsend command
Pulkit Goyal <7895pulkit@gmail.com>
parents: 33601
diff changeset
546 if not confirmed:
38398
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38342
diff changeset
547 raise error.Abort(_(b'phabsend cancelled'))
33716
40cfe3197bc1 phabricator: add --confirm option to phabsend command
Pulkit Goyal <7895pulkit@gmail.com>
parents: 33601
diff changeset
548
33498
b7a75b9a3386 phabricator: allow specifying reviewers on phabsend
Jun Wu <quark@fb.com>
parents: 33443
diff changeset
549 actions = []
38398
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38342
diff changeset
550 reviewers = opts.get(b'reviewer', [])
33498
b7a75b9a3386 phabricator: allow specifying reviewers on phabsend
Jun Wu <quark@fb.com>
parents: 33443
diff changeset
551 if reviewers:
b7a75b9a3386 phabricator: allow specifying reviewers on phabsend
Jun Wu <quark@fb.com>
parents: 33443
diff changeset
552 phids = userphids(repo, reviewers)
38398
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38342
diff changeset
553 actions.append({b'type': b'reviewers.add', b'value': phids})
33498
b7a75b9a3386 phabricator: allow specifying reviewers on phabsend
Jun Wu <quark@fb.com>
parents: 33443
diff changeset
554
33808
fa3aa6c98bb7 phabricator: add --amend option to phabsend
Jun Wu <quark@fb.com>
parents: 33806
diff changeset
555 drevids = [] # [int]
fa3aa6c98bb7 phabricator: add --amend option to phabsend
Jun Wu <quark@fb.com>
parents: 33806
diff changeset
556 diffmap = {} # {newnode: diff}
fa3aa6c98bb7 phabricator: add --amend option to phabsend
Jun Wu <quark@fb.com>
parents: 33806
diff changeset
557
33201
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33200
diff changeset
558 # Send patches one by one so we know their Differential Revision IDs and
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33200
diff changeset
559 # can provide dependency relationship
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33200
diff changeset
560 lastrevid = None
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33200
diff changeset
561 for rev in revs:
38398
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38342
diff changeset
562 ui.debug(b'sending rev %d\n' % rev)
33201
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33200
diff changeset
563 ctx = repo[rev]
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33200
diff changeset
564
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33200
diff changeset
565 # Get Differential Revision ID
33717
1664406a44d9 phabricator: use Phabricator's last node information
Jun Wu <quark@fb.com>
parents: 33716
diff changeset
566 oldnode, olddiff, revid = oldmap.get(ctx.node(), (None, None, None))
38398
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38342
diff changeset
567 if oldnode != ctx.node() or opts.get(b'amend'):
33201
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33200
diff changeset
568 # Create or update Differential Revision
33808
fa3aa6c98bb7 phabricator: add --amend option to phabsend
Jun Wu <quark@fb.com>
parents: 33806
diff changeset
569 revision, diff = createdifferentialrevision(
fa3aa6c98bb7 phabricator: add --amend option to phabsend
Jun Wu <quark@fb.com>
parents: 33806
diff changeset
570 ctx, revid, lastrevid, oldnode, olddiff, actions)
fa3aa6c98bb7 phabricator: add --amend option to phabsend
Jun Wu <quark@fb.com>
parents: 33806
diff changeset
571 diffmap[ctx.node()] = diff
41902
c340a8ac7ef3 phabricator: convert conduit response JSON unicode to bytes inside callconduit
Ian Moody <moz-ian@perix.co.uk>
parents: 41716
diff changeset
572 newrevid = int(revision[b'object'][b'id'])
33201
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33200
diff changeset
573 if revid:
38398
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38342
diff changeset
574 action = b'updated'
33201
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33200
diff changeset
575 else:
38398
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38342
diff changeset
576 action = b'created'
33201
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33200
diff changeset
577
33808
fa3aa6c98bb7 phabricator: add --amend option to phabsend
Jun Wu <quark@fb.com>
parents: 33806
diff changeset
578 # Create a local tag to note the association, if commit message
fa3aa6c98bb7 phabricator: add --amend option to phabsend
Jun Wu <quark@fb.com>
parents: 33806
diff changeset
579 # does not have it already
fa3aa6c98bb7 phabricator: add --amend option to phabsend
Jun Wu <quark@fb.com>
parents: 33806
diff changeset
580 m = _differentialrevisiondescre.search(ctx.description())
41910
16d050678047 py3: use r'' for group name arguments to MatchObjects in phabricator.py
Ian Moody <moz-ian@perix.co.uk>
parents: 41909
diff changeset
581 if not m or int(m.group(r'id')) != newrevid:
38398
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38342
diff changeset
582 tagname = b'D%d' % newrevid
33808
fa3aa6c98bb7 phabricator: add --amend option to phabsend
Jun Wu <quark@fb.com>
parents: 33806
diff changeset
583 tags.tag(repo, tagname, ctx.node(), message=None, user=None,
fa3aa6c98bb7 phabricator: add --amend option to phabsend
Jun Wu <quark@fb.com>
parents: 33806
diff changeset
584 date=None, local=True)
33201
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33200
diff changeset
585 else:
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33200
diff changeset
586 # Nothing changed. But still set "newrevid" so the next revision
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33200
diff changeset
587 # could depend on this one.
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33200
diff changeset
588 newrevid = revid
38398
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38342
diff changeset
589 action = b'skipped'
33201
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33200
diff changeset
590
34080
941c33cfde81 phabricator: standardize colors
Jun Wu <quark@fb.com>
parents: 33996
diff changeset
591 actiondesc = ui.label(
38398
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38342
diff changeset
592 {b'created': _(b'created'),
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38342
diff changeset
593 b'skipped': _(b'skipped'),
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38342
diff changeset
594 b'updated': _(b'updated')}[action],
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38342
diff changeset
595 b'phabricator.action.%s' % action)
41909
634b56b54e7c py3: use %d instead of %s when formatting an int into a byte string
Ian Moody <moz-ian@perix.co.uk>
parents: 41908
diff changeset
596 drevdesc = ui.label(b'D%d' % newrevid, b'phabricator.drev')
38398
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38342
diff changeset
597 nodedesc = ui.label(bytes(ctx), b'phabricator.node')
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38342
diff changeset
598 desc = ui.label(ctx.description().split(b'\n')[0], b'phabricator.desc')
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38342
diff changeset
599 ui.write(_(b'%s - %s - %s: %s\n') % (drevdesc, actiondesc, nodedesc,
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38342
diff changeset
600 desc))
33808
fa3aa6c98bb7 phabricator: add --amend option to phabsend
Jun Wu <quark@fb.com>
parents: 33806
diff changeset
601 drevids.append(newrevid)
33201
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33200
diff changeset
602 lastrevid = newrevid
33202
04cf9927f350 phabricator: add phabread command to read patches
Jun Wu <quark@fb.com>
parents: 33201
diff changeset
603
33808
fa3aa6c98bb7 phabricator: add --amend option to phabsend
Jun Wu <quark@fb.com>
parents: 33806
diff changeset
604 # Update commit messages and remove tags
38398
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38342
diff changeset
605 if opts.get(b'amend'):
33808
fa3aa6c98bb7 phabricator: add --amend option to phabsend
Jun Wu <quark@fb.com>
parents: 33806
diff changeset
606 unfi = repo.unfiltered()
38398
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38342
diff changeset
607 drevs = callconduit(repo, b'differential.query', {b'ids': drevids})
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38342
diff changeset
608 with repo.wlock(), repo.lock(), repo.transaction(b'phabsend'):
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38342
diff changeset
609 wnode = unfi[b'.'].node()
33808
fa3aa6c98bb7 phabricator: add --amend option to phabsend
Jun Wu <quark@fb.com>
parents: 33806
diff changeset
610 mapping = {} # {oldnode: [newnode]}
fa3aa6c98bb7 phabricator: add --amend option to phabsend
Jun Wu <quark@fb.com>
parents: 33806
diff changeset
611 for i, rev in enumerate(revs):
fa3aa6c98bb7 phabricator: add --amend option to phabsend
Jun Wu <quark@fb.com>
parents: 33806
diff changeset
612 old = unfi[rev]
fa3aa6c98bb7 phabricator: add --amend option to phabsend
Jun Wu <quark@fb.com>
parents: 33806
diff changeset
613 drevid = drevids[i]
41902
c340a8ac7ef3 phabricator: convert conduit response JSON unicode to bytes inside callconduit
Ian Moody <moz-ian@perix.co.uk>
parents: 41716
diff changeset
614 drev = [d for d in drevs if int(d[b'id']) == drevid][0]
33808
fa3aa6c98bb7 phabricator: add --amend option to phabsend
Jun Wu <quark@fb.com>
parents: 33806
diff changeset
615 newdesc = getdescfromdrev(drev)
fa3aa6c98bb7 phabricator: add --amend option to phabsend
Jun Wu <quark@fb.com>
parents: 33806
diff changeset
616 # Make sure commit message contain "Differential Revision"
fa3aa6c98bb7 phabricator: add --amend option to phabsend
Jun Wu <quark@fb.com>
parents: 33806
diff changeset
617 if old.description() != newdesc:
41163
0101a35deae2 phabricator: warn if unable to amend, instead of aborting after posting
Matt Harbison <matt_harbison@yahoo.com>
parents: 41083
diff changeset
618 if old.phase() == phases.public:
0101a35deae2 phabricator: warn if unable to amend, instead of aborting after posting
Matt Harbison <matt_harbison@yahoo.com>
parents: 41083
diff changeset
619 ui.warn(_("warning: not updating public commit %s\n")
0101a35deae2 phabricator: warn if unable to amend, instead of aborting after posting
Matt Harbison <matt_harbison@yahoo.com>
parents: 41083
diff changeset
620 % scmutil.formatchangeid(old))
0101a35deae2 phabricator: warn if unable to amend, instead of aborting after posting
Matt Harbison <matt_harbison@yahoo.com>
parents: 41083
diff changeset
621 continue
33808
fa3aa6c98bb7 phabricator: add --amend option to phabsend
Jun Wu <quark@fb.com>
parents: 33806
diff changeset
622 parents = [
fa3aa6c98bb7 phabricator: add --amend option to phabsend
Jun Wu <quark@fb.com>
parents: 33806
diff changeset
623 mapping.get(old.p1().node(), (old.p1(),))[0],
fa3aa6c98bb7 phabricator: add --amend option to phabsend
Jun Wu <quark@fb.com>
parents: 33806
diff changeset
624 mapping.get(old.p2().node(), (old.p2(),))[0],
fa3aa6c98bb7 phabricator: add --amend option to phabsend
Jun Wu <quark@fb.com>
parents: 33806
diff changeset
625 ]
fa3aa6c98bb7 phabricator: add --amend option to phabsend
Jun Wu <quark@fb.com>
parents: 33806
diff changeset
626 new = context.metadataonlyctx(
fa3aa6c98bb7 phabricator: add --amend option to phabsend
Jun Wu <quark@fb.com>
parents: 33806
diff changeset
627 repo, old, parents=parents, text=newdesc,
fa3aa6c98bb7 phabricator: add --amend option to phabsend
Jun Wu <quark@fb.com>
parents: 33806
diff changeset
628 user=old.user(), date=old.date(), extra=old.extra())
38342
bb7e3c6ef592 phabricator: preserve the phase when amending in the Differential fields
Matt Harbison <matt_harbison@yahoo.com>
parents: 38075
diff changeset
629
38429
32fba6fe893d scmutil: make cleanupnodes optionally also fix the phase
Martin von Zweigbergk <martinvonz@google.com>
parents: 38398
diff changeset
630 newnode = new.commit()
38342
bb7e3c6ef592 phabricator: preserve the phase when amending in the Differential fields
Matt Harbison <matt_harbison@yahoo.com>
parents: 38075
diff changeset
631
33808
fa3aa6c98bb7 phabricator: add --amend option to phabsend
Jun Wu <quark@fb.com>
parents: 33806
diff changeset
632 mapping[old.node()] = [newnode]
fa3aa6c98bb7 phabricator: add --amend option to phabsend
Jun Wu <quark@fb.com>
parents: 33806
diff changeset
633 # Update diff property
fa3aa6c98bb7 phabricator: add --amend option to phabsend
Jun Wu <quark@fb.com>
parents: 33806
diff changeset
634 writediffproperties(unfi[newnode], diffmap[old.node()])
fa3aa6c98bb7 phabricator: add --amend option to phabsend
Jun Wu <quark@fb.com>
parents: 33806
diff changeset
635 # Remove local tags since it's no longer necessary
38398
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38342
diff changeset
636 tagname = b'D%d' % drevid
33808
fa3aa6c98bb7 phabricator: add --amend option to phabsend
Jun Wu <quark@fb.com>
parents: 33806
diff changeset
637 if tagname in repo.tags():
fa3aa6c98bb7 phabricator: add --amend option to phabsend
Jun Wu <quark@fb.com>
parents: 33806
diff changeset
638 tags.tag(repo, tagname, nullid, message=None, user=None,
fa3aa6c98bb7 phabricator: add --amend option to phabsend
Jun Wu <quark@fb.com>
parents: 33806
diff changeset
639 date=None, local=True)
38429
32fba6fe893d scmutil: make cleanupnodes optionally also fix the phase
Martin von Zweigbergk <martinvonz@google.com>
parents: 38398
diff changeset
640 scmutil.cleanupnodes(repo, mapping, b'phabsend', fixphase=True)
33808
fa3aa6c98bb7 phabricator: add --amend option to phabsend
Jun Wu <quark@fb.com>
parents: 33806
diff changeset
641 if wnode in mapping:
fa3aa6c98bb7 phabricator: add --amend option to phabsend
Jun Wu <quark@fb.com>
parents: 33806
diff changeset
642 unfi.setparents(mapping[wnode][0])
fa3aa6c98bb7 phabricator: add --amend option to phabsend
Jun Wu <quark@fb.com>
parents: 33806
diff changeset
643
33264
266321579c68 phabricator: add node and p1 to hg:meta property
Jun Wu <quark@fb.com>
parents: 33263
diff changeset
644 # Map from "hg:meta" keys to header understood by "hg import". The order is
266321579c68 phabricator: add node and p1 to hg:meta property
Jun Wu <quark@fb.com>
parents: 33263
diff changeset
645 # consistent with "hg export" output.
41902
c340a8ac7ef3 phabricator: convert conduit response JSON unicode to bytes inside callconduit
Ian Moody <moz-ian@perix.co.uk>
parents: 41716
diff changeset
646 _metanamemap = util.sortdict([(b'user', b'User'), (b'date', b'Date'),
42286
231334c1ee96 phabricator: include branch in the phabread output
Ian Moody <moz-ian@perix.co.uk>
parents: 42285
diff changeset
647 (b'branch', b'Branch'), (b'node', b'Node ID'),
231334c1ee96 phabricator: include branch in the phabread output
Ian Moody <moz-ian@perix.co.uk>
parents: 42285
diff changeset
648 (b'parent', b'Parent ')])
33264
266321579c68 phabricator: add node and p1 to hg:meta property
Jun Wu <quark@fb.com>
parents: 33263
diff changeset
649
33996
088598153aa2 phabsend: show associated Differential Revisions with --confirm
Jun Wu <quark@fb.com>
parents: 33995
diff changeset
650 def _confirmbeforesend(repo, revs, oldmap):
33995
edeb8f28c031 phabsend: print the actual URL with --confirm
Jun Wu <quark@fb.com>
parents: 33994
diff changeset
651 url, token = readurltoken(repo)
33716
40cfe3197bc1 phabricator: add --confirm option to phabsend command
Pulkit Goyal <7895pulkit@gmail.com>
parents: 33601
diff changeset
652 ui = repo.ui
40cfe3197bc1 phabricator: add --confirm option to phabsend command
Pulkit Goyal <7895pulkit@gmail.com>
parents: 33601
diff changeset
653 for rev in revs:
40cfe3197bc1 phabricator: add --confirm option to phabsend command
Pulkit Goyal <7895pulkit@gmail.com>
parents: 33601
diff changeset
654 ctx = repo[rev]
40cfe3197bc1 phabricator: add --confirm option to phabsend command
Pulkit Goyal <7895pulkit@gmail.com>
parents: 33601
diff changeset
655 desc = ctx.description().splitlines()[0]
33996
088598153aa2 phabsend: show associated Differential Revisions with --confirm
Jun Wu <quark@fb.com>
parents: 33995
diff changeset
656 oldnode, olddiff, drevid = oldmap.get(ctx.node(), (None, None, None))
088598153aa2 phabsend: show associated Differential Revisions with --confirm
Jun Wu <quark@fb.com>
parents: 33995
diff changeset
657 if drevid:
38398
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38342
diff changeset
658 drevdesc = ui.label(b'D%s' % drevid, b'phabricator.drev')
33996
088598153aa2 phabsend: show associated Differential Revisions with --confirm
Jun Wu <quark@fb.com>
parents: 33995
diff changeset
659 else:
38398
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38342
diff changeset
660 drevdesc = ui.label(_(b'NEW'), b'phabricator.drev')
33996
088598153aa2 phabsend: show associated Differential Revisions with --confirm
Jun Wu <quark@fb.com>
parents: 33995
diff changeset
661
38398
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38342
diff changeset
662 ui.write(_(b'%s - %s: %s\n')
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38342
diff changeset
663 % (drevdesc,
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38342
diff changeset
664 ui.label(bytes(ctx), b'phabricator.node'),
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38342
diff changeset
665 ui.label(desc, b'phabricator.desc')))
33716
40cfe3197bc1 phabricator: add --confirm option to phabsend command
Pulkit Goyal <7895pulkit@gmail.com>
parents: 33601
diff changeset
666
38398
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38342
diff changeset
667 if ui.promptchoice(_(b'Send the above changes to %s (yn)?'
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38342
diff changeset
668 b'$$ &Yes $$ &No') % url):
33716
40cfe3197bc1 phabricator: add --confirm option to phabsend command
Pulkit Goyal <7895pulkit@gmail.com>
parents: 33601
diff changeset
669 return False
40cfe3197bc1 phabricator: add --confirm option to phabsend command
Pulkit Goyal <7895pulkit@gmail.com>
parents: 33601
diff changeset
670
40cfe3197bc1 phabricator: add --confirm option to phabsend command
Pulkit Goyal <7895pulkit@gmail.com>
parents: 33601
diff changeset
671 return True
40cfe3197bc1 phabricator: add --confirm option to phabsend command
Pulkit Goyal <7895pulkit@gmail.com>
parents: 33601
diff changeset
672
38398
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38342
diff changeset
673 _knownstatusnames = {b'accepted', b'needsreview', b'needsrevision', b'closed',
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38342
diff changeset
674 b'abandoned'}
33854
fb59192b4981 phabricator: add status to revision query language
Jun Wu <quark@fb.com>
parents: 33853
diff changeset
675
fb59192b4981 phabricator: add status to revision query language
Jun Wu <quark@fb.com>
parents: 33853
diff changeset
676 def _getstatusname(drev):
fb59192b4981 phabricator: add status to revision query language
Jun Wu <quark@fb.com>
parents: 33853
diff changeset
677 """get normalized status name from a Differential Revision"""
41902
c340a8ac7ef3 phabricator: convert conduit response JSON unicode to bytes inside callconduit
Ian Moody <moz-ian@perix.co.uk>
parents: 41716
diff changeset
678 return drev[b'statusName'].replace(b' ', b'').lower()
33854
fb59192b4981 phabricator: add status to revision query language
Jun Wu <quark@fb.com>
parents: 33853
diff changeset
679
33853
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33852
diff changeset
680 # Small language to specify differential revisions. Support symbols: (), :X,
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33852
diff changeset
681 # +, and -.
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33852
diff changeset
682
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33852
diff changeset
683 _elements = {
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33852
diff changeset
684 # token-type: binding-strength, primary, prefix, infix, suffix
38398
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38342
diff changeset
685 b'(': (12, None, (b'group', 1, b')'), None, None),
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38342
diff changeset
686 b':': (8, None, (b'ancestors', 8), None, None),
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38342
diff changeset
687 b'&': (5, None, None, (b'and_', 5), None),
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38342
diff changeset
688 b'+': (4, None, None, (b'add', 4), None),
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38342
diff changeset
689 b'-': (4, None, None, (b'sub', 4), None),
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38342
diff changeset
690 b')': (0, None, None, None, None),
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38342
diff changeset
691 b'symbol': (0, b'symbol', None, None, None),
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38342
diff changeset
692 b'end': (0, None, None, None, None),
33853
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33852
diff changeset
693 }
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33852
diff changeset
694
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33852
diff changeset
695 def _tokenize(text):
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33852
diff changeset
696 view = memoryview(text) # zero-copy slice
38398
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38342
diff changeset
697 special = b'():+-& '
33853
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33852
diff changeset
698 pos = 0
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33852
diff changeset
699 length = len(text)
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33852
diff changeset
700 while pos < length:
38398
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38342
diff changeset
701 symbol = b''.join(itertools.takewhile(lambda ch: ch not in special,
41955
e7b84ffb06d9 py3: use pycompat.iterbytestr to convert memoryview slice to bytestring
Ian Moody <moz-ian@perix.co.uk>
parents: 41911
diff changeset
702 pycompat.iterbytestr(view[pos:])))
33853
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33852
diff changeset
703 if symbol:
38398
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38342
diff changeset
704 yield (b'symbol', symbol, pos)
33853
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33852
diff changeset
705 pos += len(symbol)
33854
fb59192b4981 phabricator: add status to revision query language
Jun Wu <quark@fb.com>
parents: 33853
diff changeset
706 else: # special char, ignore space
38398
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38342
diff changeset
707 if text[pos] != b' ':
33854
fb59192b4981 phabricator: add status to revision query language
Jun Wu <quark@fb.com>
parents: 33853
diff changeset
708 yield (text[pos], None, pos)
33853
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33852
diff changeset
709 pos += 1
38398
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38342
diff changeset
710 yield (b'end', None, pos)
33853
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33852
diff changeset
711
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33852
diff changeset
712 def _parse(text):
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33852
diff changeset
713 tree, pos = parser.parser(_elements).parse(_tokenize(text))
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33852
diff changeset
714 if pos != len(text):
38398
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38342
diff changeset
715 raise error.ParseError(b'invalid token', pos)
33853
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33852
diff changeset
716 return tree
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33852
diff changeset
717
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33852
diff changeset
718 def _parsedrev(symbol):
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33852
diff changeset
719 """str -> int or None, ex. 'D45' -> 45; '12' -> 12; 'x' -> None"""
38398
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38342
diff changeset
720 if symbol.startswith(b'D') and symbol[1:].isdigit():
33853
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33852
diff changeset
721 return int(symbol[1:])
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33852
diff changeset
722 if symbol.isdigit():
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33852
diff changeset
723 return int(symbol)
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33852
diff changeset
724
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33852
diff changeset
725 def _prefetchdrevs(tree):
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33852
diff changeset
726 """return ({single-drev-id}, {ancestor-drev-id}) to prefetch"""
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33852
diff changeset
727 drevs = set()
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33852
diff changeset
728 ancestordrevs = set()
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33852
diff changeset
729 op = tree[0]
38398
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38342
diff changeset
730 if op == b'symbol':
33853
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33852
diff changeset
731 r = _parsedrev(tree[1])
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33852
diff changeset
732 if r:
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33852
diff changeset
733 drevs.add(r)
38398
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38342
diff changeset
734 elif op == b'ancestors':
33853
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33852
diff changeset
735 r, a = _prefetchdrevs(tree[1])
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33852
diff changeset
736 drevs.update(r)
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33852
diff changeset
737 ancestordrevs.update(r)
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33852
diff changeset
738 ancestordrevs.update(a)
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33852
diff changeset
739 else:
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33852
diff changeset
740 for t in tree[1:]:
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33852
diff changeset
741 r, a = _prefetchdrevs(t)
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33852
diff changeset
742 drevs.update(r)
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33852
diff changeset
743 ancestordrevs.update(a)
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33852
diff changeset
744 return drevs, ancestordrevs
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33852
diff changeset
745
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33852
diff changeset
746 def querydrev(repo, spec):
33267
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
747 """return a list of "Differential Revision" dicts
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
748
33853
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33852
diff changeset
749 spec is a string using a simple query language, see docstring in phabread
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33852
diff changeset
750 for details.
33267
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
751
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
752 A "Differential Revision dict" looks like:
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
753
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
754 {
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
755 "id": "2",
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
756 "phid": "PHID-DREV-672qvysjcczopag46qty",
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
757 "title": "example",
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
758 "uri": "https://phab.example.com/D2",
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
759 "dateCreated": "1499181406",
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
760 "dateModified": "1499182103",
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
761 "authorPHID": "PHID-USER-tv3ohwc4v4jeu34otlye",
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
762 "status": "0",
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
763 "statusName": "Needs Review",
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
764 "properties": [],
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
765 "branch": null,
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
766 "summary": "",
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
767 "testPlan": "",
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
768 "lineCount": "2",
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
769 "activeDiffPHID": "PHID-DIFF-xoqnjkobbm6k4dk6hi72",
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
770 "diffs": [
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
771 "3",
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
772 "4",
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
773 ],
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
774 "commits": [],
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
775 "reviewers": [],
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
776 "ccs": [],
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
777 "hashes": [],
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
778 "auxiliary": {
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
779 "phabricator:projects": [],
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
780 "phabricator:depends-on": [
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
781 "PHID-DREV-gbapp366kutjebt7agcd"
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
782 ]
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
783 },
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
784 "repositoryPHID": "PHID-REPO-hub2hx62ieuqeheznasv",
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
785 "sourcePath": null
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
786 }
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
787 """
33269
ead6749354e1 phabricator: try to fetch differential revisions in batch
Jun Wu <quark@fb.com>
parents: 33268
diff changeset
788 def fetch(params):
ead6749354e1 phabricator: try to fetch differential revisions in batch
Jun Wu <quark@fb.com>
parents: 33268
diff changeset
789 """params -> single drev or None"""
41907
59bae59b7498 py3: fix a few "dict keys as str instead of bytes" issues in phabricator.py
Ian Moody <moz-ian@perix.co.uk>
parents: 41906
diff changeset
790 key = (params.get(b'ids') or params.get(b'phids') or [None])[0]
33269
ead6749354e1 phabricator: try to fetch differential revisions in batch
Jun Wu <quark@fb.com>
parents: 33268
diff changeset
791 if key in prefetched:
ead6749354e1 phabricator: try to fetch differential revisions in batch
Jun Wu <quark@fb.com>
parents: 33268
diff changeset
792 return prefetched[key]
38398
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38342
diff changeset
793 drevs = callconduit(repo, b'differential.query', params)
33269
ead6749354e1 phabricator: try to fetch differential revisions in batch
Jun Wu <quark@fb.com>
parents: 33268
diff changeset
794 # Fill prefetched with the result
ead6749354e1 phabricator: try to fetch differential revisions in batch
Jun Wu <quark@fb.com>
parents: 33268
diff changeset
795 for drev in drevs:
41902
c340a8ac7ef3 phabricator: convert conduit response JSON unicode to bytes inside callconduit
Ian Moody <moz-ian@perix.co.uk>
parents: 41716
diff changeset
796 prefetched[drev[b'phid']] = drev
c340a8ac7ef3 phabricator: convert conduit response JSON unicode to bytes inside callconduit
Ian Moody <moz-ian@perix.co.uk>
parents: 41716
diff changeset
797 prefetched[int(drev[b'id'])] = drev
33269
ead6749354e1 phabricator: try to fetch differential revisions in batch
Jun Wu <quark@fb.com>
parents: 33268
diff changeset
798 if key not in prefetched:
38398
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38342
diff changeset
799 raise error.Abort(_(b'cannot get Differential Revision %r')
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38342
diff changeset
800 % params)
33269
ead6749354e1 phabricator: try to fetch differential revisions in batch
Jun Wu <quark@fb.com>
parents: 33268
diff changeset
801 return prefetched[key]
ead6749354e1 phabricator: try to fetch differential revisions in batch
Jun Wu <quark@fb.com>
parents: 33268
diff changeset
802
33853
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33852
diff changeset
803 def getstack(topdrevids):
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33852
diff changeset
804 """given a top, get a stack from the bottom, [id] -> [id]"""
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33852
diff changeset
805 visited = set()
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33852
diff changeset
806 result = []
41907
59bae59b7498 py3: fix a few "dict keys as str instead of bytes" issues in phabricator.py
Ian Moody <moz-ian@perix.co.uk>
parents: 41906
diff changeset
807 queue = [{b'ids': [i]} for i in topdrevids]
33853
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33852
diff changeset
808 while queue:
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33852
diff changeset
809 params = queue.pop()
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33852
diff changeset
810 drev = fetch(params)
41902
c340a8ac7ef3 phabricator: convert conduit response JSON unicode to bytes inside callconduit
Ian Moody <moz-ian@perix.co.uk>
parents: 41716
diff changeset
811 if drev[b'id'] in visited:
33853
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33852
diff changeset
812 continue
41902
c340a8ac7ef3 phabricator: convert conduit response JSON unicode to bytes inside callconduit
Ian Moody <moz-ian@perix.co.uk>
parents: 41716
diff changeset
813 visited.add(drev[b'id'])
c340a8ac7ef3 phabricator: convert conduit response JSON unicode to bytes inside callconduit
Ian Moody <moz-ian@perix.co.uk>
parents: 41716
diff changeset
814 result.append(int(drev[b'id']))
c340a8ac7ef3 phabricator: convert conduit response JSON unicode to bytes inside callconduit
Ian Moody <moz-ian@perix.co.uk>
parents: 41716
diff changeset
815 auxiliary = drev.get(b'auxiliary', {})
c340a8ac7ef3 phabricator: convert conduit response JSON unicode to bytes inside callconduit
Ian Moody <moz-ian@perix.co.uk>
parents: 41716
diff changeset
816 depends = auxiliary.get(b'phabricator:depends-on', [])
33267
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
817 for phid in depends:
38398
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38342
diff changeset
818 queue.append({b'phids': [phid]})
33853
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33852
diff changeset
819 result.reverse()
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33852
diff changeset
820 return smartset.baseset(result)
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33852
diff changeset
821
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33852
diff changeset
822 # Initialize prefetch cache
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33852
diff changeset
823 prefetched = {} # {id or phid: drev}
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33852
diff changeset
824
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33852
diff changeset
825 tree = _parse(spec)
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33852
diff changeset
826 drevs, ancestordrevs = _prefetchdrevs(tree)
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33852
diff changeset
827
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33852
diff changeset
828 # developer config: phabricator.batchsize
38398
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38342
diff changeset
829 batchsize = repo.ui.configint(b'phabricator', b'batchsize')
33853
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33852
diff changeset
830
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33852
diff changeset
831 # Prefetch Differential Revisions in batch
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33852
diff changeset
832 tofetch = set(drevs)
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33852
diff changeset
833 for r in ancestordrevs:
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33852
diff changeset
834 tofetch.update(range(max(1, r - batchsize), r + 1))
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33852
diff changeset
835 if drevs:
41902
c340a8ac7ef3 phabricator: convert conduit response JSON unicode to bytes inside callconduit
Ian Moody <moz-ian@perix.co.uk>
parents: 41716
diff changeset
836 fetch({b'ids': list(tofetch)})
33854
fb59192b4981 phabricator: add status to revision query language
Jun Wu <quark@fb.com>
parents: 33853
diff changeset
837 validids = sorted(set(getstack(list(ancestordrevs))) | set(drevs))
33853
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33852
diff changeset
838
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33852
diff changeset
839 # Walk through the tree, return smartsets
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33852
diff changeset
840 def walk(tree):
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33852
diff changeset
841 op = tree[0]
38398
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38342
diff changeset
842 if op == b'symbol':
33853
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33852
diff changeset
843 drev = _parsedrev(tree[1])
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33852
diff changeset
844 if drev:
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33852
diff changeset
845 return smartset.baseset([drev])
33854
fb59192b4981 phabricator: add status to revision query language
Jun Wu <quark@fb.com>
parents: 33853
diff changeset
846 elif tree[1] in _knownstatusnames:
fb59192b4981 phabricator: add status to revision query language
Jun Wu <quark@fb.com>
parents: 33853
diff changeset
847 drevs = [r for r in validids
fb59192b4981 phabricator: add status to revision query language
Jun Wu <quark@fb.com>
parents: 33853
diff changeset
848 if _getstatusname(prefetched[r]) == tree[1]]
fb59192b4981 phabricator: add status to revision query language
Jun Wu <quark@fb.com>
parents: 33853
diff changeset
849 return smartset.baseset(drevs)
33853
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33852
diff changeset
850 else:
38398
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38342
diff changeset
851 raise error.Abort(_(b'unknown symbol: %s') % tree[1])
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38342
diff changeset
852 elif op in {b'and_', b'add', b'sub'}:
33853
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33852
diff changeset
853 assert len(tree) == 3
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33852
diff changeset
854 return getattr(operator, op)(walk(tree[1]), walk(tree[2]))
38398
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38342
diff changeset
855 elif op == b'group':
33853
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33852
diff changeset
856 return walk(tree[1])
38398
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38342
diff changeset
857 elif op == b'ancestors':
33853
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33852
diff changeset
858 return getstack(walk(tree[1]))
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33852
diff changeset
859 else:
38398
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38342
diff changeset
860 raise error.ProgrammingError(b'illegal tree: %r' % tree)
33853
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33852
diff changeset
861
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33852
diff changeset
862 return [prefetched[r] for r in walk(tree)]
33267
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
863
33268
85391b95961d phabricator: avoid calling differential.getcommitmessage
Jun Wu <quark@fb.com>
parents: 33267
diff changeset
864 def getdescfromdrev(drev):
85391b95961d phabricator: avoid calling differential.getcommitmessage
Jun Wu <quark@fb.com>
parents: 33267
diff changeset
865 """get description (commit message) from "Differential Revision"
85391b95961d phabricator: avoid calling differential.getcommitmessage
Jun Wu <quark@fb.com>
parents: 33267
diff changeset
866
85391b95961d phabricator: avoid calling differential.getcommitmessage
Jun Wu <quark@fb.com>
parents: 33267
diff changeset
867 This is similar to differential.getcommitmessage API. But we only care
85391b95961d phabricator: avoid calling differential.getcommitmessage
Jun Wu <quark@fb.com>
parents: 33267
diff changeset
868 about limited fields: title, summary, test plan, and URL.
85391b95961d phabricator: avoid calling differential.getcommitmessage
Jun Wu <quark@fb.com>
parents: 33267
diff changeset
869 """
41902
c340a8ac7ef3 phabricator: convert conduit response JSON unicode to bytes inside callconduit
Ian Moody <moz-ian@perix.co.uk>
parents: 41716
diff changeset
870 title = drev[b'title']
c340a8ac7ef3 phabricator: convert conduit response JSON unicode to bytes inside callconduit
Ian Moody <moz-ian@perix.co.uk>
parents: 41716
diff changeset
871 summary = drev[b'summary'].rstrip()
c340a8ac7ef3 phabricator: convert conduit response JSON unicode to bytes inside callconduit
Ian Moody <moz-ian@perix.co.uk>
parents: 41716
diff changeset
872 testplan = drev[b'testPlan'].rstrip()
33268
85391b95961d phabricator: avoid calling differential.getcommitmessage
Jun Wu <quark@fb.com>
parents: 33267
diff changeset
873 if testplan:
38398
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38342
diff changeset
874 testplan = b'Test Plan:\n%s' % testplan
41902
c340a8ac7ef3 phabricator: convert conduit response JSON unicode to bytes inside callconduit
Ian Moody <moz-ian@perix.co.uk>
parents: 41716
diff changeset
875 uri = b'Differential Revision: %s' % drev[b'uri']
38398
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38342
diff changeset
876 return b'\n\n'.join(filter(None, [title, summary, testplan, uri]))
33268
85391b95961d phabricator: avoid calling differential.getcommitmessage
Jun Wu <quark@fb.com>
parents: 33267
diff changeset
877
33441
de7c6ec27d99 phabricator: respect metadata sent by arc
Jun Wu <quark@fb.com>
parents: 33271
diff changeset
878 def getdiffmeta(diff):
de7c6ec27d99 phabricator: respect metadata sent by arc
Jun Wu <quark@fb.com>
parents: 33271
diff changeset
879 """get commit metadata (date, node, user, p1) from a diff object
de7c6ec27d99 phabricator: respect metadata sent by arc
Jun Wu <quark@fb.com>
parents: 33271
diff changeset
880
de7c6ec27d99 phabricator: respect metadata sent by arc
Jun Wu <quark@fb.com>
parents: 33271
diff changeset
881 The metadata could be "hg:meta", sent by phabsend, like:
de7c6ec27d99 phabricator: respect metadata sent by arc
Jun Wu <quark@fb.com>
parents: 33271
diff changeset
882
de7c6ec27d99 phabricator: respect metadata sent by arc
Jun Wu <quark@fb.com>
parents: 33271
diff changeset
883 "properties": {
de7c6ec27d99 phabricator: respect metadata sent by arc
Jun Wu <quark@fb.com>
parents: 33271
diff changeset
884 "hg:meta": {
de7c6ec27d99 phabricator: respect metadata sent by arc
Jun Wu <quark@fb.com>
parents: 33271
diff changeset
885 "date": "1499571514 25200",
de7c6ec27d99 phabricator: respect metadata sent by arc
Jun Wu <quark@fb.com>
parents: 33271
diff changeset
886 "node": "98c08acae292b2faf60a279b4189beb6cff1414d",
de7c6ec27d99 phabricator: respect metadata sent by arc
Jun Wu <quark@fb.com>
parents: 33271
diff changeset
887 "user": "Foo Bar <foo@example.com>",
de7c6ec27d99 phabricator: respect metadata sent by arc
Jun Wu <quark@fb.com>
parents: 33271
diff changeset
888 "parent": "6d0abad76b30e4724a37ab8721d630394070fe16"
de7c6ec27d99 phabricator: respect metadata sent by arc
Jun Wu <quark@fb.com>
parents: 33271
diff changeset
889 }
de7c6ec27d99 phabricator: respect metadata sent by arc
Jun Wu <quark@fb.com>
parents: 33271
diff changeset
890 }
de7c6ec27d99 phabricator: respect metadata sent by arc
Jun Wu <quark@fb.com>
parents: 33271
diff changeset
891
de7c6ec27d99 phabricator: respect metadata sent by arc
Jun Wu <quark@fb.com>
parents: 33271
diff changeset
892 Or converted from "local:commits", sent by "arc", like:
de7c6ec27d99 phabricator: respect metadata sent by arc
Jun Wu <quark@fb.com>
parents: 33271
diff changeset
893
de7c6ec27d99 phabricator: respect metadata sent by arc
Jun Wu <quark@fb.com>
parents: 33271
diff changeset
894 "properties": {
de7c6ec27d99 phabricator: respect metadata sent by arc
Jun Wu <quark@fb.com>
parents: 33271
diff changeset
895 "local:commits": {
de7c6ec27d99 phabricator: respect metadata sent by arc
Jun Wu <quark@fb.com>
parents: 33271
diff changeset
896 "98c08acae292b2faf60a279b4189beb6cff1414d": {
de7c6ec27d99 phabricator: respect metadata sent by arc
Jun Wu <quark@fb.com>
parents: 33271
diff changeset
897 "author": "Foo Bar",
de7c6ec27d99 phabricator: respect metadata sent by arc
Jun Wu <quark@fb.com>
parents: 33271
diff changeset
898 "time": 1499546314,
de7c6ec27d99 phabricator: respect metadata sent by arc
Jun Wu <quark@fb.com>
parents: 33271
diff changeset
899 "branch": "default",
de7c6ec27d99 phabricator: respect metadata sent by arc
Jun Wu <quark@fb.com>
parents: 33271
diff changeset
900 "tag": "",
de7c6ec27d99 phabricator: respect metadata sent by arc
Jun Wu <quark@fb.com>
parents: 33271
diff changeset
901 "commit": "98c08acae292b2faf60a279b4189beb6cff1414d",
de7c6ec27d99 phabricator: respect metadata sent by arc
Jun Wu <quark@fb.com>
parents: 33271
diff changeset
902 "rev": "98c08acae292b2faf60a279b4189beb6cff1414d",
de7c6ec27d99 phabricator: respect metadata sent by arc
Jun Wu <quark@fb.com>
parents: 33271
diff changeset
903 "local": "1000",
de7c6ec27d99 phabricator: respect metadata sent by arc
Jun Wu <quark@fb.com>
parents: 33271
diff changeset
904 "parents": ["6d0abad76b30e4724a37ab8721d630394070fe16"],
de7c6ec27d99 phabricator: respect metadata sent by arc
Jun Wu <quark@fb.com>
parents: 33271
diff changeset
905 "summary": "...",
de7c6ec27d99 phabricator: respect metadata sent by arc
Jun Wu <quark@fb.com>
parents: 33271
diff changeset
906 "message": "...",
de7c6ec27d99 phabricator: respect metadata sent by arc
Jun Wu <quark@fb.com>
parents: 33271
diff changeset
907 "authorEmail": "foo@example.com"
de7c6ec27d99 phabricator: respect metadata sent by arc
Jun Wu <quark@fb.com>
parents: 33271
diff changeset
908 }
de7c6ec27d99 phabricator: respect metadata sent by arc
Jun Wu <quark@fb.com>
parents: 33271
diff changeset
909 }
de7c6ec27d99 phabricator: respect metadata sent by arc
Jun Wu <quark@fb.com>
parents: 33271
diff changeset
910 }
de7c6ec27d99 phabricator: respect metadata sent by arc
Jun Wu <quark@fb.com>
parents: 33271
diff changeset
911
de7c6ec27d99 phabricator: respect metadata sent by arc
Jun Wu <quark@fb.com>
parents: 33271
diff changeset
912 Note: metadata extracted from "local:commits" will lose time zone
de7c6ec27d99 phabricator: respect metadata sent by arc
Jun Wu <quark@fb.com>
parents: 33271
diff changeset
913 information.
de7c6ec27d99 phabricator: respect metadata sent by arc
Jun Wu <quark@fb.com>
parents: 33271
diff changeset
914 """
41902
c340a8ac7ef3 phabricator: convert conduit response JSON unicode to bytes inside callconduit
Ian Moody <moz-ian@perix.co.uk>
parents: 41716
diff changeset
915 props = diff.get(b'properties') or {}
c340a8ac7ef3 phabricator: convert conduit response JSON unicode to bytes inside callconduit
Ian Moody <moz-ian@perix.co.uk>
parents: 41716
diff changeset
916 meta = props.get(b'hg:meta')
42285
a4f7dceb07bf phabricator: fallback to reading metadata from diff for phabread
Ian Moody <moz-ian@perix.co.uk>
parents: 42284
diff changeset
917 if not meta:
a4f7dceb07bf phabricator: fallback to reading metadata from diff for phabread
Ian Moody <moz-ian@perix.co.uk>
parents: 42284
diff changeset
918 if props.get(b'local:commits'):
a4f7dceb07bf phabricator: fallback to reading metadata from diff for phabread
Ian Moody <moz-ian@perix.co.uk>
parents: 42284
diff changeset
919 commit = sorted(props[b'local:commits'].values())[0]
a4f7dceb07bf phabricator: fallback to reading metadata from diff for phabread
Ian Moody <moz-ian@perix.co.uk>
parents: 42284
diff changeset
920 meta = {}
a4f7dceb07bf phabricator: fallback to reading metadata from diff for phabread
Ian Moody <moz-ian@perix.co.uk>
parents: 42284
diff changeset
921 if b'author' in commit and b'authorEmail' in commit:
a4f7dceb07bf phabricator: fallback to reading metadata from diff for phabread
Ian Moody <moz-ian@perix.co.uk>
parents: 42284
diff changeset
922 meta[b'user'] = b'%s <%s>' % (commit[b'author'],
a4f7dceb07bf phabricator: fallback to reading metadata from diff for phabread
Ian Moody <moz-ian@perix.co.uk>
parents: 42284
diff changeset
923 commit[b'authorEmail'])
a4f7dceb07bf phabricator: fallback to reading metadata from diff for phabread
Ian Moody <moz-ian@perix.co.uk>
parents: 42284
diff changeset
924 if b'time' in commit:
a4f7dceb07bf phabricator: fallback to reading metadata from diff for phabread
Ian Moody <moz-ian@perix.co.uk>
parents: 42284
diff changeset
925 meta[b'date'] = b'%d 0' % commit[b'time']
a4f7dceb07bf phabricator: fallback to reading metadata from diff for phabread
Ian Moody <moz-ian@perix.co.uk>
parents: 42284
diff changeset
926 if b'branch' in commit:
a4f7dceb07bf phabricator: fallback to reading metadata from diff for phabread
Ian Moody <moz-ian@perix.co.uk>
parents: 42284
diff changeset
927 meta[b'branch'] = commit[b'branch']
a4f7dceb07bf phabricator: fallback to reading metadata from diff for phabread
Ian Moody <moz-ian@perix.co.uk>
parents: 42284
diff changeset
928 node = commit.get(b'commit', commit.get(b'rev'))
a4f7dceb07bf phabricator: fallback to reading metadata from diff for phabread
Ian Moody <moz-ian@perix.co.uk>
parents: 42284
diff changeset
929 if node:
a4f7dceb07bf phabricator: fallback to reading metadata from diff for phabread
Ian Moody <moz-ian@perix.co.uk>
parents: 42284
diff changeset
930 meta[b'node'] = node
a4f7dceb07bf phabricator: fallback to reading metadata from diff for phabread
Ian Moody <moz-ian@perix.co.uk>
parents: 42284
diff changeset
931 if len(commit.get(b'parents', ())) >= 1:
a4f7dceb07bf phabricator: fallback to reading metadata from diff for phabread
Ian Moody <moz-ian@perix.co.uk>
parents: 42284
diff changeset
932 meta[b'parent'] = commit[b'parents'][0]
a4f7dceb07bf phabricator: fallback to reading metadata from diff for phabread
Ian Moody <moz-ian@perix.co.uk>
parents: 42284
diff changeset
933 else:
a4f7dceb07bf phabricator: fallback to reading metadata from diff for phabread
Ian Moody <moz-ian@perix.co.uk>
parents: 42284
diff changeset
934 meta = {}
a4f7dceb07bf phabricator: fallback to reading metadata from diff for phabread
Ian Moody <moz-ian@perix.co.uk>
parents: 42284
diff changeset
935 if b'date' not in meta and b'dateCreated' in diff:
a4f7dceb07bf phabricator: fallback to reading metadata from diff for phabread
Ian Moody <moz-ian@perix.co.uk>
parents: 42284
diff changeset
936 meta[b'date'] = b'%s 0' % diff[b'dateCreated']
a4f7dceb07bf phabricator: fallback to reading metadata from diff for phabread
Ian Moody <moz-ian@perix.co.uk>
parents: 42284
diff changeset
937 if b'branch' not in meta and diff.get(b'branch'):
a4f7dceb07bf phabricator: fallback to reading metadata from diff for phabread
Ian Moody <moz-ian@perix.co.uk>
parents: 42284
diff changeset
938 meta[b'branch'] = diff[b'branch']
a4f7dceb07bf phabricator: fallback to reading metadata from diff for phabread
Ian Moody <moz-ian@perix.co.uk>
parents: 42284
diff changeset
939 if b'parent' not in meta and diff.get(b'sourceControlBaseRevision'):
a4f7dceb07bf phabricator: fallback to reading metadata from diff for phabread
Ian Moody <moz-ian@perix.co.uk>
parents: 42284
diff changeset
940 meta[b'parent'] = diff[b'sourceControlBaseRevision']
a4f7dceb07bf phabricator: fallback to reading metadata from diff for phabread
Ian Moody <moz-ian@perix.co.uk>
parents: 42284
diff changeset
941 return meta
33441
de7c6ec27d99 phabricator: respect metadata sent by arc
Jun Wu <quark@fb.com>
parents: 33271
diff changeset
942
33852
75fdaf851e83 phabricator: change "readpatch" to be more flexible
Jun Wu <quark@fb.com>
parents: 33808
diff changeset
943 def readpatch(repo, drevs, write):
33202
04cf9927f350 phabricator: add phabread command to read patches
Jun Wu <quark@fb.com>
parents: 33201
diff changeset
944 """generate plain-text patch readable by 'hg import'
04cf9927f350 phabricator: add phabread command to read patches
Jun Wu <quark@fb.com>
parents: 33201
diff changeset
945
33852
75fdaf851e83 phabricator: change "readpatch" to be more flexible
Jun Wu <quark@fb.com>
parents: 33808
diff changeset
946 write is usually ui.write. drevs is what "querydrev" returns, results of
75fdaf851e83 phabricator: change "readpatch" to be more flexible
Jun Wu <quark@fb.com>
parents: 33808
diff changeset
947 "differential.query".
33202
04cf9927f350 phabricator: add phabread command to read patches
Jun Wu <quark@fb.com>
parents: 33201
diff changeset
948 """
33267
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
949 # Prefetch hg:meta property for all diffs
41902
c340a8ac7ef3 phabricator: convert conduit response JSON unicode to bytes inside callconduit
Ian Moody <moz-ian@perix.co.uk>
parents: 41716
diff changeset
950 diffids = sorted(set(max(int(v) for v in drev[b'diffs']) for drev in drevs))
38398
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38342
diff changeset
951 diffs = callconduit(repo, b'differential.querydiffs', {b'ids': diffids})
33202
04cf9927f350 phabricator: add phabread command to read patches
Jun Wu <quark@fb.com>
parents: 33201
diff changeset
952
33267
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
953 # Generate patch for each drev
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
954 for drev in drevs:
41902
c340a8ac7ef3 phabricator: convert conduit response JSON unicode to bytes inside callconduit
Ian Moody <moz-ian@perix.co.uk>
parents: 41716
diff changeset
955 repo.ui.note(_(b'reading D%s\n') % drev[b'id'])
33202
04cf9927f350 phabricator: add phabread command to read patches
Jun Wu <quark@fb.com>
parents: 33201
diff changeset
956
41902
c340a8ac7ef3 phabricator: convert conduit response JSON unicode to bytes inside callconduit
Ian Moody <moz-ian@perix.co.uk>
parents: 41716
diff changeset
957 diffid = max(int(v) for v in drev[b'diffs'])
38398
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38342
diff changeset
958 body = callconduit(repo, b'differential.getrawdiff',
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38342
diff changeset
959 {b'diffID': diffid})
33268
85391b95961d phabricator: avoid calling differential.getcommitmessage
Jun Wu <quark@fb.com>
parents: 33267
diff changeset
960 desc = getdescfromdrev(drev)
38398
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38342
diff changeset
961 header = b'# HG changeset patch\n'
33267
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
962
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
963 # Try to preserve metadata from hg:meta property. Write hg patch
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
964 # headers that can be read by the "import" command. See patchheadermap
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
965 # and extract in mercurial/patch.py for supported headers.
41907
59bae59b7498 py3: fix a few "dict keys as str instead of bytes" issues in phabricator.py
Ian Moody <moz-ian@perix.co.uk>
parents: 41906
diff changeset
966 meta = getdiffmeta(diffs[b'%d' % diffid])
33441
de7c6ec27d99 phabricator: respect metadata sent by arc
Jun Wu <quark@fb.com>
parents: 33271
diff changeset
967 for k in _metanamemap.keys():
de7c6ec27d99 phabricator: respect metadata sent by arc
Jun Wu <quark@fb.com>
parents: 33271
diff changeset
968 if k in meta:
38398
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38342
diff changeset
969 header += b'# %s %s\n' % (_metanamemap[k], meta[k])
33202
04cf9927f350 phabricator: add phabread command to read patches
Jun Wu <quark@fb.com>
parents: 33201
diff changeset
970
38398
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38342
diff changeset
971 content = b'%s%s\n%s' % (header, desc, body)
41902
c340a8ac7ef3 phabricator: convert conduit response JSON unicode to bytes inside callconduit
Ian Moody <moz-ian@perix.co.uk>
parents: 41716
diff changeset
972 write(content)
33202
04cf9927f350 phabricator: add phabread command to read patches
Jun Wu <quark@fb.com>
parents: 33201
diff changeset
973
39666
d8f07b16abfc phabricator: add support for using the vcr library to mock interactions
Augie Fackler <raf@durin42.com>
parents: 38983
diff changeset
974 @vcrcommand(b'phabread',
38398
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38342
diff changeset
975 [(b'', b'stack', False, _(b'read dependencies'))],
41076
536beb130f3c phabricator: assign commands to help categories
Matt Harbison <matt_harbison@yahoo.com>
parents: 40435
diff changeset
976 _(b'DREVSPEC [OPTIONS]'),
536beb130f3c phabricator: assign commands to help categories
Matt Harbison <matt_harbison@yahoo.com>
parents: 40435
diff changeset
977 helpcategory=command.CATEGORY_IMPORT_EXPORT)
33853
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33852
diff changeset
978 def phabread(ui, repo, spec, **opts):
33202
04cf9927f350 phabricator: add phabread command to read patches
Jun Wu <quark@fb.com>
parents: 33201
diff changeset
979 """print patches from Phabricator suitable for importing
04cf9927f350 phabricator: add phabread command to read patches
Jun Wu <quark@fb.com>
parents: 33201
diff changeset
980
33853
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33852
diff changeset
981 DREVSPEC could be a Differential Revision identity, like ``D123``, or just
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33852
diff changeset
982 the number ``123``. It could also have common operators like ``+``, ``-``,
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33852
diff changeset
983 ``&``, ``(``, ``)`` for complex queries. Prefix ``:`` could be used to
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33852
diff changeset
984 select a stack.
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33852
diff changeset
985
33854
fb59192b4981 phabricator: add status to revision query language
Jun Wu <quark@fb.com>
parents: 33853
diff changeset
986 ``abandoned``, ``accepted``, ``closed``, ``needsreview``, ``needsrevision``
fb59192b4981 phabricator: add status to revision query language
Jun Wu <quark@fb.com>
parents: 33853
diff changeset
987 could be used to filter patches by status. For performance reason, they
fb59192b4981 phabricator: add status to revision query language
Jun Wu <quark@fb.com>
parents: 33853
diff changeset
988 only represent a subset of non-status selections and cannot be used alone.
fb59192b4981 phabricator: add status to revision query language
Jun Wu <quark@fb.com>
parents: 33853
diff changeset
989
33853
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33852
diff changeset
990 For example, ``:D6+8-(2+D4)`` selects a stack up to D6, plus D8 and exclude
33854
fb59192b4981 phabricator: add status to revision query language
Jun Wu <quark@fb.com>
parents: 33853
diff changeset
991 D2 and D4. ``:D9 & needsreview`` selects "Needs Review" revisions in a
fb59192b4981 phabricator: add status to revision query language
Jun Wu <quark@fb.com>
parents: 33853
diff changeset
992 stack up to D9.
33202
04cf9927f350 phabricator: add phabread command to read patches
Jun Wu <quark@fb.com>
parents: 33201
diff changeset
993
04cf9927f350 phabricator: add phabread command to read patches
Jun Wu <quark@fb.com>
parents: 33201
diff changeset
994 If --stack is given, follow dependencies information and read all patches.
33853
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33852
diff changeset
995 It is equivalent to the ``:`` operator.
33202
04cf9927f350 phabricator: add phabread command to read patches
Jun Wu <quark@fb.com>
parents: 33201
diff changeset
996 """
41975
51ba9fbcca52 py3: use pycompat.byteskwargs on opts in phabricator.py
Ian Moody <moz-ian@perix.co.uk>
parents: 41955
diff changeset
997 opts = pycompat.byteskwargs(opts)
38398
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38342
diff changeset
998 if opts.get(b'stack'):
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38342
diff changeset
999 spec = b':(%s)' % spec
33853
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33852
diff changeset
1000 drevs = querydrev(repo, spec)
33852
75fdaf851e83 phabricator: change "readpatch" to be more flexible
Jun Wu <quark@fb.com>
parents: 33808
diff changeset
1001 readpatch(repo, drevs, ui.write)
33855
6e666cd59879 phabricator: add phabupdate command to update status in batch
Jun Wu <quark@fb.com>
parents: 33854
diff changeset
1002
39666
d8f07b16abfc phabricator: add support for using the vcr library to mock interactions
Augie Fackler <raf@durin42.com>
parents: 38983
diff changeset
1003 @vcrcommand(b'phabupdate',
38398
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38342
diff changeset
1004 [(b'', b'accept', False, _(b'accept revisions')),
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38342
diff changeset
1005 (b'', b'reject', False, _(b'reject revisions')),
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38342
diff changeset
1006 (b'', b'abandon', False, _(b'abandon revisions')),
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38342
diff changeset
1007 (b'', b'reclaim', False, _(b'reclaim revisions')),
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38342
diff changeset
1008 (b'm', b'comment', b'', _(b'comment on the last revision')),
41076
536beb130f3c phabricator: assign commands to help categories
Matt Harbison <matt_harbison@yahoo.com>
parents: 40435
diff changeset
1009 ], _(b'DREVSPEC [OPTIONS]'),
536beb130f3c phabricator: assign commands to help categories
Matt Harbison <matt_harbison@yahoo.com>
parents: 40435
diff changeset
1010 helpcategory=command.CATEGORY_IMPORT_EXPORT)
33855
6e666cd59879 phabricator: add phabupdate command to update status in batch
Jun Wu <quark@fb.com>
parents: 33854
diff changeset
1011 def phabupdate(ui, repo, spec, **opts):
6e666cd59879 phabricator: add phabupdate command to update status in batch
Jun Wu <quark@fb.com>
parents: 33854
diff changeset
1012 """update Differential Revision in batch
6e666cd59879 phabricator: add phabupdate command to update status in batch
Jun Wu <quark@fb.com>
parents: 33854
diff changeset
1013
6e666cd59879 phabricator: add phabupdate command to update status in batch
Jun Wu <quark@fb.com>
parents: 33854
diff changeset
1014 DREVSPEC selects revisions. See :hg:`help phabread` for its usage.
6e666cd59879 phabricator: add phabupdate command to update status in batch
Jun Wu <quark@fb.com>
parents: 33854
diff changeset
1015 """
41975
51ba9fbcca52 py3: use pycompat.byteskwargs on opts in phabricator.py
Ian Moody <moz-ian@perix.co.uk>
parents: 41955
diff changeset
1016 opts = pycompat.byteskwargs(opts)
38398
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38342
diff changeset
1017 flags = [n for n in b'accept reject abandon reclaim'.split() if opts.get(n)]
33855
6e666cd59879 phabricator: add phabupdate command to update status in batch
Jun Wu <quark@fb.com>
parents: 33854
diff changeset
1018 if len(flags) > 1:
38398
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38342
diff changeset
1019 raise error.Abort(_(b'%s cannot be used together') % b', '.join(flags))
33855
6e666cd59879 phabricator: add phabupdate command to update status in batch
Jun Wu <quark@fb.com>
parents: 33854
diff changeset
1020
6e666cd59879 phabricator: add phabupdate command to update status in batch
Jun Wu <quark@fb.com>
parents: 33854
diff changeset
1021 actions = []
6e666cd59879 phabricator: add phabupdate command to update status in batch
Jun Wu <quark@fb.com>
parents: 33854
diff changeset
1022 for f in flags:
38398
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38342
diff changeset
1023 actions.append({b'type': f, b'value': b'true'})
33855
6e666cd59879 phabricator: add phabupdate command to update status in batch
Jun Wu <quark@fb.com>
parents: 33854
diff changeset
1024
6e666cd59879 phabricator: add phabupdate command to update status in batch
Jun Wu <quark@fb.com>
parents: 33854
diff changeset
1025 drevs = querydrev(repo, spec)
6e666cd59879 phabricator: add phabupdate command to update status in batch
Jun Wu <quark@fb.com>
parents: 33854
diff changeset
1026 for i, drev in enumerate(drevs):
38398
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38342
diff changeset
1027 if i + 1 == len(drevs) and opts.get(b'comment'):
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38342
diff changeset
1028 actions.append({b'type': b'comment', b'value': opts[b'comment']})
33855
6e666cd59879 phabricator: add phabupdate command to update status in batch
Jun Wu <quark@fb.com>
parents: 33854
diff changeset
1029 if actions:
41902
c340a8ac7ef3 phabricator: convert conduit response JSON unicode to bytes inside callconduit
Ian Moody <moz-ian@perix.co.uk>
parents: 41716
diff changeset
1030 params = {b'objectIdentifier': drev[b'phid'],
38398
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38342
diff changeset
1031 b'transactions': actions}
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38342
diff changeset
1032 callconduit(repo, b'differential.revision.edit', params)
35722
f18ba40d792f phabricator: add a template item for linking to a differential review
Tom Prince <mozilla@hocat.ca>
parents: 35626
diff changeset
1033
f18ba40d792f phabricator: add a template item for linking to a differential review
Tom Prince <mozilla@hocat.ca>
parents: 35626
diff changeset
1034 templatekeyword = registrar.templatekeyword()
f18ba40d792f phabricator: add a template item for linking to a differential review
Tom Prince <mozilla@hocat.ca>
parents: 35626
diff changeset
1035
38398
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38342
diff changeset
1036 @templatekeyword(b'phabreview', requires={b'ctx'})
36543
7b74afec6772 templatekw: switch non-showlist template keywords to new API
Yuya Nishihara <yuya@tcha.org>
parents: 35722
diff changeset
1037 def template_review(context, mapping):
35722
f18ba40d792f phabricator: add a template item for linking to a differential review
Tom Prince <mozilla@hocat.ca>
parents: 35626
diff changeset
1038 """:phabreview: Object describing the review for this changeset.
f18ba40d792f phabricator: add a template item for linking to a differential review
Tom Prince <mozilla@hocat.ca>
parents: 35626
diff changeset
1039 Has attributes `url` and `id`.
f18ba40d792f phabricator: add a template item for linking to a differential review
Tom Prince <mozilla@hocat.ca>
parents: 35626
diff changeset
1040 """
38398
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38342
diff changeset
1041 ctx = context.resource(mapping, b'ctx')
35722
f18ba40d792f phabricator: add a template item for linking to a differential review
Tom Prince <mozilla@hocat.ca>
parents: 35626
diff changeset
1042 m = _differentialrevisiondescre.search(ctx.description())
f18ba40d792f phabricator: add a template item for linking to a differential review
Tom Prince <mozilla@hocat.ca>
parents: 35626
diff changeset
1043 if m:
39670
4057e38bba76 phabricator: fix templating bug by using hybriddict
Augie Fackler <raf@durin42.com>
parents: 39668
diff changeset
1044 return templateutil.hybriddict({
41910
16d050678047 py3: use r'' for group name arguments to MatchObjects in phabricator.py
Ian Moody <moz-ian@perix.co.uk>
parents: 41909
diff changeset
1045 b'url': m.group(r'url'),
41911
2b21c7fbb3a1 py3: use % instead of .format() on a bytestring
Ian Moody <moz-ian@perix.co.uk>
parents: 41910
diff changeset
1046 b'id': b"D%s" % m.group(r'id'),
39670
4057e38bba76 phabricator: fix templating bug by using hybriddict
Augie Fackler <raf@durin42.com>
parents: 39668
diff changeset
1047 })
41164
43fd1947301d phabricator: teach {phabreview} to work without --amend
Matt Harbison <matt_harbison@yahoo.com>
parents: 41163
diff changeset
1048 else:
43fd1947301d phabricator: teach {phabreview} to work without --amend
Matt Harbison <matt_harbison@yahoo.com>
parents: 41163
diff changeset
1049 tags = ctx.repo().nodetags(ctx.node())
43fd1947301d phabricator: teach {phabreview} to work without --amend
Matt Harbison <matt_harbison@yahoo.com>
parents: 41163
diff changeset
1050 for t in tags:
43fd1947301d phabricator: teach {phabreview} to work without --amend
Matt Harbison <matt_harbison@yahoo.com>
parents: 41163
diff changeset
1051 if _differentialrevisiontagre.match(t):
43fd1947301d phabricator: teach {phabreview} to work without --amend
Matt Harbison <matt_harbison@yahoo.com>
parents: 41163
diff changeset
1052 url = ctx.repo().ui.config(b'phabricator', b'url')
43fd1947301d phabricator: teach {phabreview} to work without --amend
Matt Harbison <matt_harbison@yahoo.com>
parents: 41163
diff changeset
1053 if not url.endswith(b'/'):
43fd1947301d phabricator: teach {phabreview} to work without --amend
Matt Harbison <matt_harbison@yahoo.com>
parents: 41163
diff changeset
1054 url += b'/'
43fd1947301d phabricator: teach {phabreview} to work without --amend
Matt Harbison <matt_harbison@yahoo.com>
parents: 41163
diff changeset
1055 url += t
43fd1947301d phabricator: teach {phabreview} to work without --amend
Matt Harbison <matt_harbison@yahoo.com>
parents: 41163
diff changeset
1056
43fd1947301d phabricator: teach {phabreview} to work without --amend
Matt Harbison <matt_harbison@yahoo.com>
parents: 41163
diff changeset
1057 return templateutil.hybriddict({
43fd1947301d phabricator: teach {phabreview} to work without --amend
Matt Harbison <matt_harbison@yahoo.com>
parents: 41163
diff changeset
1058 b'url': url,
43fd1947301d phabricator: teach {phabreview} to work without --amend
Matt Harbison <matt_harbison@yahoo.com>
parents: 41163
diff changeset
1059 b'id': t,
43fd1947301d phabricator: teach {phabreview} to work without --amend
Matt Harbison <matt_harbison@yahoo.com>
parents: 41163
diff changeset
1060 })
43fd1947301d phabricator: teach {phabreview} to work without --amend
Matt Harbison <matt_harbison@yahoo.com>
parents: 41163
diff changeset
1061 return None