annotate hgext/phabricator.py @ 42431:29528c4235a1

phabricator: add commenting to phabsend for new/updated Diffs Especially useful when sending updates to existing Revisions so one can specify the sort of changes e.g. "Address review comments" or "Rebase to tip" If the diff content hasn't changed then it only needs a metadata update which doesn't show in the Phabricator updates UI, so don't add a comment that will. Differential Revision: https://phab.mercurial-scm.org/D6496
author Ian Moody <moz-ian@perix.co.uk>
date Fri, 07 Jun 2019 20:19:55 +0100
parents af13e2088f77
children 500b64c5d991
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
33198
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.
39655
87539f615b87 phabricator: mark extension as experimental for now
Augie Fackler <raf@durin42.com>
parents: 39654
diff changeset
7 """simple Phabricator integration (EXPERIMENTAL)
33198
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
8
33199
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
9 This extension provides a ``phabsend`` command which sends a stack of
33975
07ffff841863 phabsend: make --amend the default
Jun Wu <quark@fb.com>
parents: 33974
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: 33974
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: 33974
diff changeset
12 to update statuses in batch.
33199
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
13
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
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: 33198
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: 33198
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: 33198
diff changeset
17
33198
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
33199
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
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: 33198
diff changeset
25 # callsign is "FOO".
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
26 callsign = FOO
33200
04cf9927f350 phabricator: add phabread command to read patches
Jun Wu <quark@fb.com>
parents: 33199
diff changeset
27
34064
8b659b7388c0 phabricator: add a config to use curl for communication
Jun Wu <quark@fb.com>
parents: 34063
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: 34063
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: 34063
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: 34063
diff changeset
31 # the internal library.
8b659b7388c0 phabricator: add a config to use curl for communication
Jun Wu <quark@fb.com>
parents: 34063
diff changeset
32 curlcmd = curl --connect-timeout 2 --retry 3 --silent
36787
4397909f82d3 phabricator: specify API tokens per host, rather than per repo
Tom Prince <mozilla@hocat.ca>
parents: 36514
diff changeset
33
37996
0fa050bc68cb phabricator: migrate [phabricator.auth] to [auth]
Matt Harbison <matt_harbison@yahoo.com>
parents: 37976
diff changeset
34 [auth]
37997
71cf20d47f25 phabricator: split auth.url into the standard auth.schemes and auth.prefix
Matt Harbison <matt_harbison@yahoo.com>
parents: 37996
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: 37996
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: 37996
diff changeset
37
36787
4397909f82d3 phabricator: specify API tokens per host, rather than per repo
Tom Prince <mozilla@hocat.ca>
parents: 36514
diff changeset
38 # API token. Get it from https://$HOST/conduit/login/
37996
0fa050bc68cb phabricator: migrate [phabricator.auth] to [auth]
Matt Harbison <matt_harbison@yahoo.com>
parents: 37976
diff changeset
39 example.phabtoken = cli-xxxxxxxxxxxxxxxxxxxxxxxxxxxx
33198
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
41080
9d35ae3d9999 phabricator: ensure that the return of urlopener.open() is closed
Matt Harbison <matt_harbison@yahoo.com>
parents: 41078
diff changeset
44 import contextlib
33832
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33831
diff changeset
45 import itertools
33198
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
46 import json
33832
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33831
diff changeset
47 import operator
33199
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
48 import re
33198
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
33198
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 (
33787
fa3aa6c98bb7 phabricator: add --amend option to phabsend
Jun Wu <quark@fb.com>
parents: 33785
diff changeset
53 cmdutil,
fa3aa6c98bb7 phabricator: add --amend option to phabsend
Jun Wu <quark@fb.com>
parents: 33785
diff changeset
54 context,
33199
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
55 encoding,
33198
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
56 error,
37997
71cf20d47f25 phabricator: split auth.url into the standard auth.schemes and auth.prefix
Matt Harbison <matt_harbison@yahoo.com>
parents: 37996
diff changeset
57 httpconnection as httpconnectionmod,
33199
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
58 mdiff,
33735
e6d8ee3c9ec3 obsutil: rename allprecursors into allpredecessors
Boris Feld <boris.feld@octobus.net>
parents: 33692
diff changeset
59 obsutil,
33832
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33831
diff changeset
60 parser,
33199
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
61 patch,
41163
0101a35deae2 phabricator: warn if unable to amend, instead of aborting after posting
Matt Harbison <matt_harbison@yahoo.com>
parents: 41080
diff changeset
62 phases,
41897
c340a8ac7ef3 phabricator: convert conduit response JSON unicode to bytes inside callconduit
Ian Moody <moz-ian@perix.co.uk>
parents: 41705
diff changeset
63 pycompat,
33198
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
64 registrar,
33199
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
65 scmutil,
33832
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33831
diff changeset
66 smartset,
33199
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
67 tags,
42188
289d82a070e9 phabricator: use templatefilters.json in writediffproperties
Ian Moody <moz-ian@perix.co.uk>
parents: 41971
diff changeset
68 templatefilters,
39654
4057e38bba76 phabricator: fix templating bug by using hybriddict
Augie Fackler <raf@durin42.com>
parents: 39652
diff changeset
69 templateutil,
33198
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 )
37120
a8a902d7176e procutil: bulk-replace function calls to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 36818
diff changeset
73 from mercurial.utils import (
a8a902d7176e procutil: bulk-replace function calls to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 36818
diff changeset
74 procutil,
37800
6cf5f5b4eb57 phabricator: specify some metadata compatibly with arc
Tom Prince <mozilla@hocat.ca>
parents: 37120
diff changeset
75 stringutil,
37120
a8a902d7176e procutil: bulk-replace function calls to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 36818
diff changeset
76 )
33198
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
77
39735
c0c703861b60 phabricator: add testedwith boilerplate
Yuya Nishihara <yuya@tcha.org>
parents: 39655
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: 39655
diff changeset
79 # extensions which SHIP WITH MERCURIAL. Non-mainline extensions should
c0c703861b60 phabricator: add testedwith boilerplate
Yuya Nishihara <yuya@tcha.org>
parents: 39655
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: 39655
diff changeset
81 # leave the attribute unspecified.
c0c703861b60 phabricator: add testedwith boilerplate
Yuya Nishihara <yuya@tcha.org>
parents: 39655
diff changeset
82 testedwith = 'ships-with-hg-core'
c0c703861b60 phabricator: add testedwith boilerplate
Yuya Nishihara <yuya@tcha.org>
parents: 39655
diff changeset
83
33198
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
38042
5a7cf42ba6ef phabricator: register config settings
Matt Harbison <matt_harbison@yahoo.com>
parents: 37997
diff changeset
87 configtable = {}
5a7cf42ba6ef phabricator: register config settings
Matt Harbison <matt_harbison@yahoo.com>
parents: 37997
diff changeset
88 configitem = registrar.configitem(configtable)
5a7cf42ba6ef phabricator: register config settings
Matt Harbison <matt_harbison@yahoo.com>
parents: 37997
diff changeset
89
5a7cf42ba6ef phabricator: register config settings
Matt Harbison <matt_harbison@yahoo.com>
parents: 37997
diff changeset
90 # developer config: phabricator.batchsize
38392
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38336
diff changeset
91 configitem(b'phabricator', b'batchsize',
38042
5a7cf42ba6ef phabricator: register config settings
Matt Harbison <matt_harbison@yahoo.com>
parents: 37997
diff changeset
92 default=12,
5a7cf42ba6ef phabricator: register config settings
Matt Harbison <matt_harbison@yahoo.com>
parents: 37997
diff changeset
93 )
38392
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38336
diff changeset
94 configitem(b'phabricator', b'callsign',
38042
5a7cf42ba6ef phabricator: register config settings
Matt Harbison <matt_harbison@yahoo.com>
parents: 37997
diff changeset
95 default=None,
5a7cf42ba6ef phabricator: register config settings
Matt Harbison <matt_harbison@yahoo.com>
parents: 37997
diff changeset
96 )
38392
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38336
diff changeset
97 configitem(b'phabricator', b'curlcmd',
38042
5a7cf42ba6ef phabricator: register config settings
Matt Harbison <matt_harbison@yahoo.com>
parents: 37997
diff changeset
98 default=None,
5a7cf42ba6ef phabricator: register config settings
Matt Harbison <matt_harbison@yahoo.com>
parents: 37997
diff changeset
99 )
5a7cf42ba6ef phabricator: register config settings
Matt Harbison <matt_harbison@yahoo.com>
parents: 37997
diff changeset
100 # developer config: phabricator.repophid
38392
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38336
diff changeset
101 configitem(b'phabricator', b'repophid',
38042
5a7cf42ba6ef phabricator: register config settings
Matt Harbison <matt_harbison@yahoo.com>
parents: 37997
diff changeset
102 default=None,
5a7cf42ba6ef phabricator: register config settings
Matt Harbison <matt_harbison@yahoo.com>
parents: 37997
diff changeset
103 )
38392
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38336
diff changeset
104 configitem(b'phabricator', b'url',
38042
5a7cf42ba6ef phabricator: register config settings
Matt Harbison <matt_harbison@yahoo.com>
parents: 37997
diff changeset
105 default=None,
5a7cf42ba6ef phabricator: register config settings
Matt Harbison <matt_harbison@yahoo.com>
parents: 37997
diff changeset
106 )
38392
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38336
diff changeset
107 configitem(b'phabsend', b'confirm',
38042
5a7cf42ba6ef phabricator: register config settings
Matt Harbison <matt_harbison@yahoo.com>
parents: 37997
diff changeset
108 default=False,
5a7cf42ba6ef phabricator: register config settings
Matt Harbison <matt_harbison@yahoo.com>
parents: 37997
diff changeset
109 )
5a7cf42ba6ef phabricator: register config settings
Matt Harbison <matt_harbison@yahoo.com>
parents: 37997
diff changeset
110
34063
941c33cfde81 phabricator: standardize colors
Jun Wu <quark@fb.com>
parents: 33978
diff changeset
111 colortable = {
38392
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38336
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: 38336
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: 38336
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: 38336
diff changeset
115 b'phabricator.desc': b'',
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38336
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: 38336
diff changeset
117 b'phabricator.node': b'',
34063
941c33cfde81 phabricator: standardize colors
Jun Wu <quark@fb.com>
parents: 33978
diff changeset
118 }
941c33cfde81 phabricator: standardize colors
Jun Wu <quark@fb.com>
parents: 33978
diff changeset
119
39650
d8f07b16abfc phabricator: add support for using the vcr library to mock interactions
Augie Fackler <raf@durin42.com>
parents: 38945
diff changeset
120 _VCR_FLAGS = [
d8f07b16abfc phabricator: add support for using the vcr library to mock interactions
Augie Fackler <raf@durin42.com>
parents: 38945
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: 38945
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: 38945
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: 38945
diff changeset
124 b' (ADVANCED)'
d8f07b16abfc phabricator: add support for using the vcr library to mock interactions
Augie Fackler <raf@durin42.com>
parents: 38945
diff changeset
125 )),
d8f07b16abfc phabricator: add support for using the vcr library to mock interactions
Augie Fackler <raf@durin42.com>
parents: 38945
diff changeset
126 ]
d8f07b16abfc phabricator: add support for using the vcr library to mock interactions
Augie Fackler <raf@durin42.com>
parents: 38945
diff changeset
127
41073
536beb130f3c phabricator: assign commands to help categories
Matt Harbison <matt_harbison@yahoo.com>
parents: 40546
diff changeset
128 def vcrcommand(name, flags, spec, helpcategory=None):
39650
d8f07b16abfc phabricator: add support for using the vcr library to mock interactions
Augie Fackler <raf@durin42.com>
parents: 38945
diff changeset
129 fullflags = flags + _VCR_FLAGS
42268
af13e2088f77 phabricator: add custom vcr matcher to match request bodies
Ian Moody <moz-ian@perix.co.uk>
parents: 42258
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: 42258
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: 42258
diff changeset
132 return False
af13e2088f77 phabricator: add custom vcr matcher to match request bodies
Ian Moody <moz-ian@perix.co.uk>
parents: 42258
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: 42258
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: 42258
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: 42258
diff changeset
136
39650
d8f07b16abfc phabricator: add support for using the vcr library to mock interactions
Augie Fackler <raf@durin42.com>
parents: 38945
diff changeset
137 def decorate(fn):
d8f07b16abfc phabricator: add support for using the vcr library to mock interactions
Augie Fackler <raf@durin42.com>
parents: 38945
diff changeset
138 def inner(*args, **kwargs):
41898
2bad8f92cebf py3: use fsencode for vcr recording paths and strings for custom_patches args
Ian Moody <moz-ian@perix.co.uk>
parents: 41897
diff changeset
139 cassette = pycompat.fsdecode(kwargs.pop(r'test_vcr', None))
39650
d8f07b16abfc phabricator: add support for using the vcr library to mock interactions
Augie Fackler <raf@durin42.com>
parents: 38945
diff changeset
140 if cassette:
d8f07b16abfc phabricator: add support for using the vcr library to mock interactions
Augie Fackler <raf@durin42.com>
parents: 38945
diff changeset
141 import hgdemandimport
d8f07b16abfc phabricator: add support for using the vcr library to mock interactions
Augie Fackler <raf@durin42.com>
parents: 38945
diff changeset
142 with hgdemandimport.deactivated():
d8f07b16abfc phabricator: add support for using the vcr library to mock interactions
Augie Fackler <raf@durin42.com>
parents: 38945
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: 38945
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=[
41898
2bad8f92cebf py3: use fsencode for vcr recording paths and strings for custom_patches args
Ian Moody <moz-ian@perix.co.uk>
parents: 41897
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: 41897
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: 41897
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 ])
42268
af13e2088f77 phabricator: add custom vcr matcher to match request bodies
Ian Moody <moz-ian@perix.co.uk>
parents: 42258
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: 42258
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)
39650
d8f07b16abfc phabricator: add support for using the vcr library to mock interactions
Augie Fackler <raf@durin42.com>
parents: 38945
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: 38945
diff changeset
157 inner.__name__ = fn.__name__
40546
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__
41073
536beb130f3c phabricator: assign commands to help categories
Matt Harbison <matt_harbison@yahoo.com>
parents: 40546
diff changeset
159 return command(name, fullflags, spec, helpcategory=helpcategory)(inner)
39650
d8f07b16abfc phabricator: add support for using the vcr library to mock interactions
Augie Fackler <raf@durin42.com>
parents: 38945
diff changeset
160 return decorate
d8f07b16abfc phabricator: add support for using the vcr library to mock interactions
Augie Fackler <raf@durin42.com>
parents: 38945
diff changeset
161
33198
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):
41017
d7d3164e6a31 phabricator: properly encode boolean types in the request body
Matt Harbison <matt_harbison@yahoo.com>
parents: 40546
diff changeset
171 if isinstance(obj, bool):
d7d3164e6a31 phabricator: properly encode boolean types in the request body
Matt Harbison <matt_harbison@yahoo.com>
parents: 40546
diff changeset
172 obj = {True: b'true', False: b'false'}[obj] # Python -> PHP form
41900
47125193bad0 py3: convert indexes into bytes when enumerating lists in urlencodenested
Ian Moody <moz-ian@perix.co.uk>
parents: 41899
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: 41899
diff changeset
174 items = {list: lister, dict: lambda x: x.items()}.get(type(obj))
33198
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:
38392
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38336
diff changeset
180 process(b'%s[%s]' % (prefix, k), v)
33198
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)
38392
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38336
diff changeset
183 process(b'', params)
33198
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
37996
0fa050bc68cb phabricator: migrate [phabricator.auth] to [auth]
Matt Harbison <matt_harbison@yahoo.com>
parents: 37976
diff changeset
186 def readurltoken(repo):
0fa050bc68cb phabricator: migrate [phabricator.auth] to [auth]
Matt Harbison <matt_harbison@yahoo.com>
parents: 37976
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: 37976
diff changeset
188
37997
71cf20d47f25 phabricator: split auth.url into the standard auth.schemes and auth.prefix
Matt Harbison <matt_harbison@yahoo.com>
parents: 37996
diff changeset
189 Currently read from [auth] config section. In the future, it might
37996
0fa050bc68cb phabricator: migrate [phabricator.auth] to [auth]
Matt Harbison <matt_harbison@yahoo.com>
parents: 37976
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: 37976
diff changeset
191 """
38392
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38336
diff changeset
192 url = repo.ui.config(b'phabricator', b'url')
37996
0fa050bc68cb phabricator: migrate [phabricator.auth] to [auth]
Matt Harbison <matt_harbison@yahoo.com>
parents: 37976
diff changeset
193 if not url:
38392
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38336
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: 38336
diff changeset
195 % (b'phabricator', b'url'))
37996
0fa050bc68cb phabricator: migrate [phabricator.auth] to [auth]
Matt Harbison <matt_harbison@yahoo.com>
parents: 37976
diff changeset
196
37997
71cf20d47f25 phabricator: split auth.url into the standard auth.schemes and auth.prefix
Matt Harbison <matt_harbison@yahoo.com>
parents: 37996
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: 37996
diff changeset
198 token = None
37996
0fa050bc68cb phabricator: migrate [phabricator.auth] to [auth]
Matt Harbison <matt_harbison@yahoo.com>
parents: 37976
diff changeset
199
37997
71cf20d47f25 phabricator: split auth.url into the standard auth.schemes and auth.prefix
Matt Harbison <matt_harbison@yahoo.com>
parents: 37996
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: 37996
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: 37996
diff changeset
202
38392
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38336
diff changeset
203 repo.ui.debug(b"using auth.%s.* for authentication\n" % group)
37997
71cf20d47f25 phabricator: split auth.url into the standard auth.schemes and auth.prefix
Matt Harbison <matt_harbison@yahoo.com>
parents: 37996
diff changeset
204
38392
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38336
diff changeset
205 token = auth.get(b'phabtoken')
37996
0fa050bc68cb phabricator: migrate [phabricator.auth] to [auth]
Matt Harbison <matt_harbison@yahoo.com>
parents: 37976
diff changeset
206
36787
4397909f82d3 phabricator: specify API tokens per host, rather than per repo
Tom Prince <mozilla@hocat.ca>
parents: 36514
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: 39735
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: 39735
diff changeset
209 % (url,))
36787
4397909f82d3 phabricator: specify API tokens per host, rather than per repo
Tom Prince <mozilla@hocat.ca>
parents: 36514
diff changeset
210
4397909f82d3 phabricator: specify API tokens per host, rather than per repo
Tom Prince <mozilla@hocat.ca>
parents: 36514
diff changeset
211 return url, token
33198
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)
38392
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38336
diff changeset
216 url, authinfo = util.url(b'/'.join([host, b'api', name])).authinfo()
41899
9a8c7c17d816 py3: don't try and format a bare dict into a byte string in callconduit
Ian Moody <moz-ian@perix.co.uk>
parents: 41898
diff changeset
217 repo.ui.debug(b'Conduit Call: %s %s\n' % (url, pycompat.byterepr(params)))
33198
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
218 params = params.copy()
38392
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38336
diff changeset
219 params[b'api.token'] = token
34064
8b659b7388c0 phabricator: add a config to use curl for communication
Jun Wu <quark@fb.com>
parents: 34063
diff changeset
220 data = urlencodenested(params)
38392
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38336
diff changeset
221 curlcmd = repo.ui.config(b'phabricator', b'curlcmd')
34064
8b659b7388c0 phabricator: add a config to use curl for communication
Jun Wu <quark@fb.com>
parents: 34063
diff changeset
222 if curlcmd:
38392
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38336
diff changeset
223 sin, sout = procutil.popen2(b'%s -d @- %s'
37120
a8a902d7176e procutil: bulk-replace function calls to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 36818
diff changeset
224 % (curlcmd, procutil.shellquote(url)))
34064
8b659b7388c0 phabricator: add a config to use curl for communication
Jun Wu <quark@fb.com>
parents: 34063
diff changeset
225 sin.write(data)
8b659b7388c0 phabricator: add a config to use curl for communication
Jun Wu <quark@fb.com>
parents: 34063
diff changeset
226 sin.close()
8b659b7388c0 phabricator: add a config to use curl for communication
Jun Wu <quark@fb.com>
parents: 34063
diff changeset
227 body = sout.read()
8b659b7388c0 phabricator: add a config to use curl for communication
Jun Wu <quark@fb.com>
parents: 34063
diff changeset
228 else:
8b659b7388c0 phabricator: add a config to use curl for communication
Jun Wu <quark@fb.com>
parents: 34063
diff changeset
229 urlopener = urlmod.opener(repo.ui, authinfo)
41901
a98dabdb5a7b py3: convert URL to str before passing it to request
Ian Moody <moz-ian@perix.co.uk>
parents: 41900
diff changeset
230 request = util.urlreq.request(pycompat.strurl(url), data=data)
41080
9d35ae3d9999 phabricator: ensure that the return of urlopener.open() is closed
Matt Harbison <matt_harbison@yahoo.com>
parents: 41078
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: 41078
diff changeset
232 body = rsp.read()
38392
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38336
diff changeset
233 repo.ui.debug(b'Conduit Response: %s\n' % body)
41897
c340a8ac7ef3 phabricator: convert conduit response JSON unicode to bytes inside callconduit
Ian Moody <moz-ian@perix.co.uk>
parents: 41705
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: 41705
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: 41705
diff changeset
236 else x,
c340a8ac7ef3 phabricator: convert conduit response JSON unicode to bytes inside callconduit
Ian Moody <moz-ian@perix.co.uk>
parents: 41705
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: 41705
diff changeset
238 )
c340a8ac7ef3 phabricator: convert conduit response JSON unicode to bytes inside callconduit
Ian Moody <moz-ian@perix.co.uk>
parents: 41705
diff changeset
239 if parsed.get(b'error_code'):
38392
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38336
diff changeset
240 msg = (_(b'Conduit Error (%s): %s')
41897
c340a8ac7ef3 phabricator: convert conduit response JSON unicode to bytes inside callconduit
Ian Moody <moz-ian@perix.co.uk>
parents: 41705
diff changeset
241 % (parsed[b'error_code'], parsed[b'error_info']))
33198
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
242 raise error.Abort(msg)
41897
c340a8ac7ef3 phabricator: convert conduit response JSON unicode to bytes inside callconduit
Ian Moody <moz-ian@perix.co.uk>
parents: 41705
diff changeset
243 return parsed[b'result']
33198
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
244
39650
d8f07b16abfc phabricator: add support for using the vcr library to mock interactions
Augie Fackler <raf@durin42.com>
parents: 38945
diff changeset
245 @vcrcommand(b'debugcallconduit', [], _(b'METHOD'))
33198
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 """
41971
99e00e5c4746 py3: convert to/from bytes/unicode for json.(dump|load)s in debugcallconduit
Ian Moody <moz-ian@perix.co.uk>
parents: 41970
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: 41970
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: 41970
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: 41970
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: 41970
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: 41970
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: 41970
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: 41970
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: 41970
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: 41970
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: 41970
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: 41970
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: 41970
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: 41970
diff changeset
265 ui.write(b'%s\n' % encoding.unitolocal(s))
33199
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
266
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
267 def getrepophid(repo):
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
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: 33198
diff changeset
269 # developer config: phabricator.repophid
38392
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38336
diff changeset
270 repophid = repo.ui.config(b'phabricator', b'repophid')
33199
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
271 if repophid:
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
272 return repophid
38392
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38336
diff changeset
273 callsign = repo.ui.config(b'phabricator', b'callsign')
33199
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
274 if not callsign:
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
275 return None
38392
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38336
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: 38336
diff changeset
277 {b'constraints': {b'callsigns': [callsign]}})
41897
c340a8ac7ef3 phabricator: convert conduit response JSON unicode to bytes inside callconduit
Ian Moody <moz-ian@perix.co.uk>
parents: 41705
diff changeset
278 if len(query[b'data']) == 0:
33199
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
279 return None
41897
c340a8ac7ef3 phabricator: convert conduit response JSON unicode to bytes inside callconduit
Ian Moody <moz-ian@perix.co.uk>
parents: 41705
diff changeset
280 repophid = query[b'data'][0][b'phid']
38392
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38336
diff changeset
281 repo.ui.setconfig(b'phabricator', b'repophid', repophid)
33199
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
282 return repophid
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
283
41532
bd3f03d8cc9f global: use raw strings for regular expressions with escapes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 41365
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: 33200
diff changeset
285 _differentialrevisiondescre = re.compile(
41532
bd3f03d8cc9f global: use raw strings for regular expressions with escapes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 41365
diff changeset
286 br'^Differential Revision:\s*(?P<url>(?:.*)D(?P<id>[1-9][0-9]*))$', re.M)
33199
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
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
33691
1664406a44d9 phabricator: use Phabricator's last node information
Jun Wu <quark@fb.com>
parents: 33690
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
33691
1664406a44d9 phabricator: use Phabricator's last node information
Jun Wu <quark@fb.com>
parents: 33690
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: 33690
diff changeset
294 be ``None``.
33199
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
295
33691
1664406a44d9 phabricator: use Phabricator's last node information
Jun Wu <quark@fb.com>
parents: 33690
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: 33690
diff changeset
297 association information.
33263
ed61189763ef phabricator: check associated Differential Revision from commit message
Jun Wu <quark@fb.com>
parents: 33200
diff changeset
298
33691
1664406a44d9 phabricator: use Phabricator's last node information
Jun Wu <quark@fb.com>
parents: 33690
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: 33690
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: 33690
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: 33690
diff changeset
302
1664406a44d9 phabricator: use Phabricator's last node information
Jun Wu <quark@fb.com>
parents: 33690
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: 33690
diff changeset
304 corresponding Differential Revision, and exist in the repo.
33199
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
305 """
33442
3ab0d5767b54 phabricator: finding old nodes in batch
Jun Wu <quark@fb.com>
parents: 33441
diff changeset
306 unfi = repo.unfiltered()
33199
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
307 nodemap = unfi.changelog.nodemap
33263
ed61189763ef phabricator: check associated Differential Revision from commit message
Jun Wu <quark@fb.com>
parents: 33200
diff changeset
308
33691
1664406a44d9 phabricator: use Phabricator's last node information
Jun Wu <quark@fb.com>
parents: 33690
diff changeset
309 result = {} # {node: (oldnode?, lastdiff?, drev)}
1664406a44d9 phabricator: use Phabricator's last node information
Jun Wu <quark@fb.com>
parents: 33690
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
33735
e6d8ee3c9ec3 obsutil: rename allprecursors into allpredecessors
Boris Feld <boris.feld@octobus.net>
parents: 33692
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:
33691
1664406a44d9 phabricator: use Phabricator's last node information
Jun Wu <quark@fb.com>
parents: 33690
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: 33200
diff changeset
322
33691
1664406a44d9 phabricator: use Phabricator's last node information
Jun Wu <quark@fb.com>
parents: 33690
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:
41905
16d050678047 py3: use r'' for group name arguments to MatchObjects in phabricator.py
Ian Moody <moz-ian@perix.co.uk>
parents: 41904
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: 33200
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:
33691
1664406a44d9 phabricator: use Phabricator's last node information
Jun Wu <quark@fb.com>
parents: 33690
diff changeset
331 drevs = [drev for force, precs, drev in toconfirm.values()]
38392
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38336
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: 38336
diff changeset
333 {b'revisionIDs': drevs})
41897
c340a8ac7ef3 phabricator: convert conduit response JSON unicode to bytes inside callconduit
Ian Moody <moz-ian@perix.co.uk>
parents: 41705
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: 41705
diff changeset
335 getdiffmeta(d).get(b'node', b'')) or None
33691
1664406a44d9 phabricator: use Phabricator's last node information
Jun Wu <quark@fb.com>
parents: 33690
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: 33690
diff changeset
337 diffs = [d for d in alldiffs.values()
41897
c340a8ac7ef3 phabricator: convert conduit response JSON unicode to bytes inside callconduit
Ian Moody <moz-ian@perix.co.uk>
parents: 41705
diff changeset
338 if int(d[b'revisionID']) == drev]
33691
1664406a44d9 phabricator: use Phabricator's last node information
Jun Wu <quark@fb.com>
parents: 33690
diff changeset
339
1664406a44d9 phabricator: use Phabricator's last node information
Jun Wu <quark@fb.com>
parents: 33690
diff changeset
340 # "precursors" as known by Phabricator
1664406a44d9 phabricator: use Phabricator's last node information
Jun Wu <quark@fb.com>
parents: 33690
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: 33690
diff changeset
342
1664406a44d9 phabricator: use Phabricator's last node information
Jun Wu <quark@fb.com>
parents: 33690
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: 33690
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: 33690
diff changeset
345 if not force and not bool(phprecset & precset):
38392
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38336
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)
38392
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38336
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: 38336
diff changeset
350 b'Differential history\n') % drev)
33691
1664406a44d9 phabricator: use Phabricator's last node information
Jun Wu <quark@fb.com>
parents: 33690
diff changeset
351 continue
1664406a44d9 phabricator: use Phabricator's last node information
Jun Wu <quark@fb.com>
parents: 33690
diff changeset
352
1664406a44d9 phabricator: use Phabricator's last node information
Jun Wu <quark@fb.com>
parents: 33690
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: 33690
diff changeset
354 # exists in the repo
1664406a44d9 phabricator: use Phabricator's last node information
Jun Wu <quark@fb.com>
parents: 33690
diff changeset
355 oldnode = lastdiff = None
1664406a44d9 phabricator: use Phabricator's last node information
Jun Wu <quark@fb.com>
parents: 33690
diff changeset
356 if diffs:
41897
c340a8ac7ef3 phabricator: convert conduit response JSON unicode to bytes inside callconduit
Ian Moody <moz-ian@perix.co.uk>
parents: 41705
diff changeset
357 lastdiff = max(diffs, key=lambda d: int(d[b'id']))
33691
1664406a44d9 phabricator: use Phabricator's last node information
Jun Wu <quark@fb.com>
parents: 33690
diff changeset
358 oldnode = getnode(lastdiff)
1664406a44d9 phabricator: use Phabricator's last node information
Jun Wu <quark@fb.com>
parents: 33690
diff changeset
359 if oldnode and oldnode not in nodemap:
1664406a44d9 phabricator: use Phabricator's last node information
Jun Wu <quark@fb.com>
parents: 33690
diff changeset
360 oldnode = None
1664406a44d9 phabricator: use Phabricator's last node information
Jun Wu <quark@fb.com>
parents: 33690
diff changeset
361
1664406a44d9 phabricator: use Phabricator's last node information
Jun Wu <quark@fb.com>
parents: 33690
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
33199
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
365
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
366 def getdiff(ctx, diffopts):
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
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: 33198
diff changeset
368 output = util.stringio()
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
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: 33198
diff changeset
370 None, opts=diffopts):
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
371 output.write(chunk)
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
372 return output.getvalue()
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
373
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
374 def creatediff(ctx):
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
375 """create a Differential Diff"""
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
376 repo = ctx.repo()
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
377 repophid = getrepophid(repo)
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
378 # Create a "Differential Diff" via "differential.createrawdiff" API
38392
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38336
diff changeset
379 params = {b'diff': getdiff(ctx, mdiff.diffopts(git=True, context=32767))}
33199
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
380 if repophid:
38392
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38336
diff changeset
381 params[b'repositoryPHID'] = repophid
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38336
diff changeset
382 diff = callconduit(repo, b'differential.createrawdiff', params)
33199
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
383 if not diff:
38392
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38336
diff changeset
384 raise error.Abort(_(b'cannot create diff for %s') % ctx)
33199
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
385 return diff
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
386
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
387 def writediffproperties(ctx, diff):
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
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: 33198
diff changeset
389 params = {
41897
c340a8ac7ef3 phabricator: convert conduit response JSON unicode to bytes inside callconduit
Ian Moody <moz-ian@perix.co.uk>
parents: 41705
diff changeset
390 b'diff_id': diff[b'id'],
38392
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38336
diff changeset
391 b'name': b'hg:meta',
42188
289d82a070e9 phabricator: use templatefilters.json in writediffproperties
Ian Moody <moz-ian@perix.co.uk>
parents: 41971
diff changeset
392 b'data': templatefilters.json({
289d82a070e9 phabricator: use templatefilters.json in writediffproperties
Ian Moody <moz-ian@perix.co.uk>
parents: 41971
diff changeset
393 b'user': ctx.user(),
289d82a070e9 phabricator: use templatefilters.json in writediffproperties
Ian Moody <moz-ian@perix.co.uk>
parents: 41971
diff changeset
394 b'date': b'%d %d' % ctx.date(),
42198
d49ab47be8a6 phabricator: include branch in the diffproperty metadata
Ian Moody <moz-ian@perix.co.uk>
parents: 42189
diff changeset
395 b'branch': ctx.branch(),
42188
289d82a070e9 phabricator: use templatefilters.json in writediffproperties
Ian Moody <moz-ian@perix.co.uk>
parents: 41971
diff changeset
396 b'node': ctx.hex(),
289d82a070e9 phabricator: use templatefilters.json in writediffproperties
Ian Moody <moz-ian@perix.co.uk>
parents: 41971
diff changeset
397 b'parent': ctx.p1().hex(),
33199
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
398 }),
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
399 }
38392
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38336
diff changeset
400 callconduit(ctx.repo(), b'differential.setdiffproperty', params)
33199
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
401
37800
6cf5f5b4eb57 phabricator: specify some metadata compatibly with arc
Tom Prince <mozilla@hocat.ca>
parents: 37120
diff changeset
402 params = {
41897
c340a8ac7ef3 phabricator: convert conduit response JSON unicode to bytes inside callconduit
Ian Moody <moz-ian@perix.co.uk>
parents: 41705
diff changeset
403 b'diff_id': diff[b'id'],
38392
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38336
diff changeset
404 b'name': b'local:commits',
42188
289d82a070e9 phabricator: use templatefilters.json in writediffproperties
Ian Moody <moz-ian@perix.co.uk>
parents: 41971
diff changeset
405 b'data': templatefilters.json({
289d82a070e9 phabricator: use templatefilters.json in writediffproperties
Ian Moody <moz-ian@perix.co.uk>
parents: 41971
diff changeset
406 ctx.hex(): {
289d82a070e9 phabricator: use templatefilters.json in writediffproperties
Ian Moody <moz-ian@perix.co.uk>
parents: 41971
diff changeset
407 b'author': stringutil.person(ctx.user()),
289d82a070e9 phabricator: use templatefilters.json in writediffproperties
Ian Moody <moz-ian@perix.co.uk>
parents: 41971
diff changeset
408 b'authorEmail': stringutil.email(ctx.user()),
42189
c0e30c9ee5ba phabricator: set local:commits time metadata as an int, not a string
Ian Moody <moz-ian@perix.co.uk>
parents: 42188
diff changeset
409 b'time': int(ctx.date()[0]),
42256
9421d7e12888 phabricator: include commit (node) and parent in the local:commits metadata
Ian Moody <moz-ian@perix.co.uk>
parents: 42200
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: 42200
diff changeset
411 b'parents': [ctx.p1().hex()],
42198
d49ab47be8a6 phabricator: include branch in the diffproperty metadata
Ian Moody <moz-ian@perix.co.uk>
parents: 42189
diff changeset
412 b'branch': ctx.branch(),
37800
6cf5f5b4eb57 phabricator: specify some metadata compatibly with arc
Tom Prince <mozilla@hocat.ca>
parents: 37120
diff changeset
413 },
6cf5f5b4eb57 phabricator: specify some metadata compatibly with arc
Tom Prince <mozilla@hocat.ca>
parents: 37120
diff changeset
414 }),
6cf5f5b4eb57 phabricator: specify some metadata compatibly with arc
Tom Prince <mozilla@hocat.ca>
parents: 37120
diff changeset
415 }
38392
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38336
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: 37120
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,
42431
29528c4235a1 phabricator: add commenting to phabsend for new/updated Diffs
Ian Moody <moz-ian@perix.co.uk>
parents: 42268
diff changeset
419 olddiff=None, actions=None, comment=None):
33199
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
420 """create or update a Differential Revision
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
421
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
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: 33198
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.
33199
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
429 """
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
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:
33976
27ff2a87d8c0 phabsend: detect patch change with larger context
Jun Wu <quark@fb.com>
parents: 33975
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
33199
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
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)
41897
c340a8ac7ef3 phabricator: convert conduit response JSON unicode to bytes inside callconduit
Ian Moody <moz-ian@perix.co.uk>
parents: 41705
diff changeset
441 transactions.append({b'type': b'update', b'value': diff[b'phid']})
42431
29528c4235a1 phabricator: add commenting to phabsend for new/updated Diffs
Ian Moody <moz-ian@perix.co.uk>
parents: 42268
diff changeset
442 if comment:
29528c4235a1 phabricator: add commenting to phabsend for new/updated Diffs
Ian Moody <moz-ian@perix.co.uk>
parents: 42268
diff changeset
443 transactions.append({b'type': b'comment', b'value': comment})
33692
f100354cce52 phabricator: update diff property even if we choose not to create a new diff
Jun Wu <quark@fb.com>
parents: 33691
diff changeset
444 else:
f100354cce52 phabricator: update diff property even if we choose not to create a new diff
Jun Wu <quark@fb.com>
parents: 33691
diff changeset
445 # 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: 33691
diff changeset
446 # 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: 33691
diff changeset
447 # 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: 33691
diff changeset
448 assert olddiff
f100354cce52 phabricator: update diff property even if we choose not to create a new diff
Jun Wu <quark@fb.com>
parents: 33691
diff changeset
449 diff = olddiff
f100354cce52 phabricator: update diff property even if we choose not to create a new diff
Jun Wu <quark@fb.com>
parents: 33691
diff changeset
450 writediffproperties(ctx, diff)
33199
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
451
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
452 # 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: 33198
diff changeset
453 # 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: 33198
diff changeset
454 # 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: 33198
diff changeset
455 # churns (someone edited "Summary" twice) on the web page.
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
456 if parentrevid and revid is None:
41904
634b56b54e7c py3: use %d instead of %s when formatting an int into a byte string
Ian Moody <moz-ian@perix.co.uk>
parents: 41903
diff changeset
457 summary = b'Depends on D%d' % parentrevid
38392
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38336
diff changeset
458 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: 38336
diff changeset
459 {b'type': b'summary', b'value': b' '}]
33199
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
460
33498
b7a75b9a3386 phabricator: allow specifying reviewers on phabsend
Jun Wu <quark@fb.com>
parents: 33443
diff changeset
461 if actions:
b7a75b9a3386 phabricator: allow specifying reviewers on phabsend
Jun Wu <quark@fb.com>
parents: 33443
diff changeset
462 transactions += actions
b7a75b9a3386 phabricator: allow specifying reviewers on phabsend
Jun Wu <quark@fb.com>
parents: 33443
diff changeset
463
33199
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
464 # Parse commit message and update related fields.
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
465 desc = ctx.description()
38392
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38336
diff changeset
466 info = callconduit(repo, b'differential.parsecommitmessage',
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38336
diff changeset
467 {b'corpus': desc})
41897
c340a8ac7ef3 phabricator: convert conduit response JSON unicode to bytes inside callconduit
Ian Moody <moz-ian@perix.co.uk>
parents: 41705
diff changeset
468 for k, v in info[b'fields'].items():
38392
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38336
diff changeset
469 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: 38336
diff changeset
470 transactions.append({b'type': k, b'value': v})
33199
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
471
38392
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38336
diff changeset
472 params = {b'transactions': transactions}
33199
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
473 if revid is not None:
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
474 # Update an existing Differential Revision
38392
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38336
diff changeset
475 params[b'objectIdentifier'] = revid
33199
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
476
38392
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38336
diff changeset
477 revision = callconduit(repo, b'differential.revision.edit', params)
33199
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
478 if not revision:
38392
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38336
diff changeset
479 raise error.Abort(_(b'cannot create revision for %s') % ctx)
33199
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
480
33787
fa3aa6c98bb7 phabricator: add --amend option to phabsend
Jun Wu <quark@fb.com>
parents: 33785
diff changeset
481 return revision, diff
33199
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
482
33498
b7a75b9a3386 phabricator: allow specifying reviewers on phabsend
Jun Wu <quark@fb.com>
parents: 33443
diff changeset
483 def userphids(repo, names):
b7a75b9a3386 phabricator: allow specifying reviewers on phabsend
Jun Wu <quark@fb.com>
parents: 33443
diff changeset
484 """convert user names to PHIDs"""
41705
570e62f1dcf2 phabricator: make user searches case-insensitive
Julien Cristau <jcristau@mozilla.com>
parents: 41532
diff changeset
485 names = [name.lower() for name in names]
38392
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38336
diff changeset
486 query = {b'constraints': {b'usernames': names}}
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38336
diff changeset
487 result = callconduit(repo, b'user.search', query)
33498
b7a75b9a3386 phabricator: allow specifying reviewers on phabsend
Jun Wu <quark@fb.com>
parents: 33443
diff changeset
488 # 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
489 # some names here.
41897
c340a8ac7ef3 phabricator: convert conduit response JSON unicode to bytes inside callconduit
Ian Moody <moz-ian@perix.co.uk>
parents: 41705
diff changeset
490 data = result[b'data']
c340a8ac7ef3 phabricator: convert conduit response JSON unicode to bytes inside callconduit
Ian Moody <moz-ian@perix.co.uk>
parents: 41705
diff changeset
491 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
492 unresolved = set(names) - resolved
b7a75b9a3386 phabricator: allow specifying reviewers on phabsend
Jun Wu <quark@fb.com>
parents: 33443
diff changeset
493 if unresolved:
38392
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38336
diff changeset
494 raise error.Abort(_(b'unknown username: %s')
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38336
diff changeset
495 % b' '.join(sorted(unresolved)))
41897
c340a8ac7ef3 phabricator: convert conduit response JSON unicode to bytes inside callconduit
Ian Moody <moz-ian@perix.co.uk>
parents: 41705
diff changeset
496 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
497
39650
d8f07b16abfc phabricator: add support for using the vcr library to mock interactions
Augie Fackler <raf@durin42.com>
parents: 38945
diff changeset
498 @vcrcommand(b'phabsend',
38392
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38336
diff changeset
499 [(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: 38336
diff changeset
500 (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: 38336
diff changeset
501 (b'', b'reviewer', [], _(b'specify reviewers')),
42431
29528c4235a1 phabricator: add commenting to phabsend for new/updated Diffs
Ian Moody <moz-ian@perix.co.uk>
parents: 42268
diff changeset
502 (b'm', b'comment', b'',
29528c4235a1 phabricator: add commenting to phabsend for new/updated Diffs
Ian Moody <moz-ian@perix.co.uk>
parents: 42268
diff changeset
503 _(b'add a comment to Revisions with new/updated Diffs')),
38392
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38336
diff changeset
504 (b'', b'confirm', None, _(b'ask for confirmation before sending'))],
41073
536beb130f3c phabricator: assign commands to help categories
Matt Harbison <matt_harbison@yahoo.com>
parents: 40546
diff changeset
505 _(b'REV [OPTIONS]'),
536beb130f3c phabricator: assign commands to help categories
Matt Harbison <matt_harbison@yahoo.com>
parents: 40546
diff changeset
506 helpcategory=command.CATEGORY_IMPORT_EXPORT)
33199
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
507 def phabsend(ui, repo, *revs, **opts):
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
508 """upload changesets to Phabricator
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
509
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
510 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: 33198
diff changeset
511 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: 33198
diff changeset
512 revset.
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
513
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
514 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: 33198
diff changeset
515 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: 33198
diff changeset
516 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: 33198
diff changeset
517 existing Differential Revision, or create a new one.
33690
40cfe3197bc1 phabricator: add --confirm option to phabsend command
Pulkit Goyal <7895pulkit@gmail.com>
parents: 33601
diff changeset
518
33787
fa3aa6c98bb7 phabricator: add --amend option to phabsend
Jun Wu <quark@fb.com>
parents: 33785
diff changeset
519 If --amend is set, update commit messages so they have the
fa3aa6c98bb7 phabricator: add --amend option to phabsend
Jun Wu <quark@fb.com>
parents: 33785
diff changeset
520 ``Differential Revision`` URL, remove related tags. This is similar to what
fa3aa6c98bb7 phabricator: add --amend option to phabsend
Jun Wu <quark@fb.com>
parents: 33785
diff changeset
521 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: 33785
diff changeset
522 use local tags to record the ``Differential Revision`` association.
fa3aa6c98bb7 phabricator: add --amend option to phabsend
Jun Wu <quark@fb.com>
parents: 33785
diff changeset
523
33690
40cfe3197bc1 phabricator: add --confirm option to phabsend command
Pulkit Goyal <7895pulkit@gmail.com>
parents: 33601
diff changeset
524 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
525 can also add following to your configuration file to make it default
33974
45a8cd74de4e phabsend: polish the docstring a bit
Jun Wu <quark@fb.com>
parents: 33834
diff changeset
526 behaviour::
33690
40cfe3197bc1 phabricator: add --confirm option to phabsend command
Pulkit Goyal <7895pulkit@gmail.com>
parents: 33601
diff changeset
527
33974
45a8cd74de4e phabsend: polish the docstring a bit
Jun Wu <quark@fb.com>
parents: 33834
diff changeset
528 [phabsend]
45a8cd74de4e phabsend: polish the docstring a bit
Jun Wu <quark@fb.com>
parents: 33834
diff changeset
529 confirm = true
33787
fa3aa6c98bb7 phabricator: add --amend option to phabsend
Jun Wu <quark@fb.com>
parents: 33785
diff changeset
530
fa3aa6c98bb7 phabricator: add --amend option to phabsend
Jun Wu <quark@fb.com>
parents: 33785
diff changeset
531 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: 33785
diff changeset
532 update an existing Differential Revision, or create a new one.
33199
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
533 """
41970
51ba9fbcca52 py3: use pycompat.byteskwargs on opts in phabricator.py
Ian Moody <moz-ian@perix.co.uk>
parents: 41950
diff changeset
534 opts = pycompat.byteskwargs(opts)
38392
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38336
diff changeset
535 revs = list(revs) + opts.get(b'rev', [])
33199
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
536 revs = scmutil.revrange(repo, revs)
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
537
33266
5b2391b46906 phabricator: abort if phabsend gets empty revs
Jun Wu <quark@fb.com>
parents: 33265
diff changeset
538 if not revs:
38392
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38336
diff changeset
539 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: 38336
diff changeset
540 if opts.get(b'amend'):
33787
fa3aa6c98bb7 phabricator: add --amend option to phabsend
Jun Wu <quark@fb.com>
parents: 33785
diff changeset
541 cmdutil.checkunfinished(repo)
33266
5b2391b46906 phabricator: abort if phabsend gets empty revs
Jun Wu <quark@fb.com>
parents: 33265
diff changeset
542
33978
088598153aa2 phabsend: show associated Differential Revisions with --confirm
Jun Wu <quark@fb.com>
parents: 33977
diff changeset
543 # {newnode: (oldnode, olddiff, olddrev}
088598153aa2 phabsend: show associated Differential Revisions with --confirm
Jun Wu <quark@fb.com>
parents: 33977
diff changeset
544 oldmap = getoldnodedrevmap(repo, [repo[r].node() for r in revs])
088598153aa2 phabsend: show associated Differential Revisions with --confirm
Jun Wu <quark@fb.com>
parents: 33977
diff changeset
545
38392
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38336
diff changeset
546 confirm = ui.configbool(b'phabsend', b'confirm')
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38336
diff changeset
547 confirm |= bool(opts.get(b'confirm'))
33690
40cfe3197bc1 phabricator: add --confirm option to phabsend command
Pulkit Goyal <7895pulkit@gmail.com>
parents: 33601
diff changeset
548 if confirm:
33978
088598153aa2 phabsend: show associated Differential Revisions with --confirm
Jun Wu <quark@fb.com>
parents: 33977
diff changeset
549 confirmed = _confirmbeforesend(repo, revs, oldmap)
33690
40cfe3197bc1 phabricator: add --confirm option to phabsend command
Pulkit Goyal <7895pulkit@gmail.com>
parents: 33601
diff changeset
550 if not confirmed:
38392
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38336
diff changeset
551 raise error.Abort(_(b'phabsend cancelled'))
33690
40cfe3197bc1 phabricator: add --confirm option to phabsend command
Pulkit Goyal <7895pulkit@gmail.com>
parents: 33601
diff changeset
552
33498
b7a75b9a3386 phabricator: allow specifying reviewers on phabsend
Jun Wu <quark@fb.com>
parents: 33443
diff changeset
553 actions = []
38392
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38336
diff changeset
554 reviewers = opts.get(b'reviewer', [])
33498
b7a75b9a3386 phabricator: allow specifying reviewers on phabsend
Jun Wu <quark@fb.com>
parents: 33443
diff changeset
555 if reviewers:
b7a75b9a3386 phabricator: allow specifying reviewers on phabsend
Jun Wu <quark@fb.com>
parents: 33443
diff changeset
556 phids = userphids(repo, reviewers)
38392
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38336
diff changeset
557 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
558
33787
fa3aa6c98bb7 phabricator: add --amend option to phabsend
Jun Wu <quark@fb.com>
parents: 33785
diff changeset
559 drevids = [] # [int]
fa3aa6c98bb7 phabricator: add --amend option to phabsend
Jun Wu <quark@fb.com>
parents: 33785
diff changeset
560 diffmap = {} # {newnode: diff}
fa3aa6c98bb7 phabricator: add --amend option to phabsend
Jun Wu <quark@fb.com>
parents: 33785
diff changeset
561
33199
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
562 # 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: 33198
diff changeset
563 # can provide dependency relationship
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
564 lastrevid = None
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
565 for rev in revs:
38392
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38336
diff changeset
566 ui.debug(b'sending rev %d\n' % rev)
33199
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
567 ctx = repo[rev]
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
568
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
569 # Get Differential Revision ID
33691
1664406a44d9 phabricator: use Phabricator's last node information
Jun Wu <quark@fb.com>
parents: 33690
diff changeset
570 oldnode, olddiff, revid = oldmap.get(ctx.node(), (None, None, None))
38392
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38336
diff changeset
571 if oldnode != ctx.node() or opts.get(b'amend'):
33199
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
572 # Create or update Differential Revision
33787
fa3aa6c98bb7 phabricator: add --amend option to phabsend
Jun Wu <quark@fb.com>
parents: 33785
diff changeset
573 revision, diff = createdifferentialrevision(
42431
29528c4235a1 phabricator: add commenting to phabsend for new/updated Diffs
Ian Moody <moz-ian@perix.co.uk>
parents: 42268
diff changeset
574 ctx, revid, lastrevid, oldnode, olddiff, actions,
29528c4235a1 phabricator: add commenting to phabsend for new/updated Diffs
Ian Moody <moz-ian@perix.co.uk>
parents: 42268
diff changeset
575 opts.get(b'comment'))
33787
fa3aa6c98bb7 phabricator: add --amend option to phabsend
Jun Wu <quark@fb.com>
parents: 33785
diff changeset
576 diffmap[ctx.node()] = diff
41897
c340a8ac7ef3 phabricator: convert conduit response JSON unicode to bytes inside callconduit
Ian Moody <moz-ian@perix.co.uk>
parents: 41705
diff changeset
577 newrevid = int(revision[b'object'][b'id'])
33199
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
578 if revid:
38392
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38336
diff changeset
579 action = b'updated'
33199
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
580 else:
38392
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38336
diff changeset
581 action = b'created'
33199
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
582
33787
fa3aa6c98bb7 phabricator: add --amend option to phabsend
Jun Wu <quark@fb.com>
parents: 33785
diff changeset
583 # Create a local tag to note the association, if commit message
fa3aa6c98bb7 phabricator: add --amend option to phabsend
Jun Wu <quark@fb.com>
parents: 33785
diff changeset
584 # does not have it already
fa3aa6c98bb7 phabricator: add --amend option to phabsend
Jun Wu <quark@fb.com>
parents: 33785
diff changeset
585 m = _differentialrevisiondescre.search(ctx.description())
41905
16d050678047 py3: use r'' for group name arguments to MatchObjects in phabricator.py
Ian Moody <moz-ian@perix.co.uk>
parents: 41904
diff changeset
586 if not m or int(m.group(r'id')) != newrevid:
38392
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38336
diff changeset
587 tagname = b'D%d' % newrevid
33787
fa3aa6c98bb7 phabricator: add --amend option to phabsend
Jun Wu <quark@fb.com>
parents: 33785
diff changeset
588 tags.tag(repo, tagname, ctx.node(), message=None, user=None,
fa3aa6c98bb7 phabricator: add --amend option to phabsend
Jun Wu <quark@fb.com>
parents: 33785
diff changeset
589 date=None, local=True)
33199
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
590 else:
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
591 # 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: 33198
diff changeset
592 # could depend on this one.
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
593 newrevid = revid
38392
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38336
diff changeset
594 action = b'skipped'
33199
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
595
34063
941c33cfde81 phabricator: standardize colors
Jun Wu <quark@fb.com>
parents: 33978
diff changeset
596 actiondesc = ui.label(
38392
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38336
diff changeset
597 {b'created': _(b'created'),
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38336
diff changeset
598 b'skipped': _(b'skipped'),
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38336
diff changeset
599 b'updated': _(b'updated')}[action],
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38336
diff changeset
600 b'phabricator.action.%s' % action)
41904
634b56b54e7c py3: use %d instead of %s when formatting an int into a byte string
Ian Moody <moz-ian@perix.co.uk>
parents: 41903
diff changeset
601 drevdesc = ui.label(b'D%d' % newrevid, b'phabricator.drev')
38392
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38336
diff changeset
602 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: 38336
diff changeset
603 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: 38336
diff changeset
604 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: 38336
diff changeset
605 desc))
33787
fa3aa6c98bb7 phabricator: add --amend option to phabsend
Jun Wu <quark@fb.com>
parents: 33785
diff changeset
606 drevids.append(newrevid)
33199
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
607 lastrevid = newrevid
33200
04cf9927f350 phabricator: add phabread command to read patches
Jun Wu <quark@fb.com>
parents: 33199
diff changeset
608
33787
fa3aa6c98bb7 phabricator: add --amend option to phabsend
Jun Wu <quark@fb.com>
parents: 33785
diff changeset
609 # Update commit messages and remove tags
38392
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38336
diff changeset
610 if opts.get(b'amend'):
33787
fa3aa6c98bb7 phabricator: add --amend option to phabsend
Jun Wu <quark@fb.com>
parents: 33785
diff changeset
611 unfi = repo.unfiltered()
38392
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38336
diff changeset
612 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: 38336
diff changeset
613 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: 38336
diff changeset
614 wnode = unfi[b'.'].node()
33787
fa3aa6c98bb7 phabricator: add --amend option to phabsend
Jun Wu <quark@fb.com>
parents: 33785
diff changeset
615 mapping = {} # {oldnode: [newnode]}
fa3aa6c98bb7 phabricator: add --amend option to phabsend
Jun Wu <quark@fb.com>
parents: 33785
diff changeset
616 for i, rev in enumerate(revs):
fa3aa6c98bb7 phabricator: add --amend option to phabsend
Jun Wu <quark@fb.com>
parents: 33785
diff changeset
617 old = unfi[rev]
fa3aa6c98bb7 phabricator: add --amend option to phabsend
Jun Wu <quark@fb.com>
parents: 33785
diff changeset
618 drevid = drevids[i]
41897
c340a8ac7ef3 phabricator: convert conduit response JSON unicode to bytes inside callconduit
Ian Moody <moz-ian@perix.co.uk>
parents: 41705
diff changeset
619 drev = [d for d in drevs if int(d[b'id']) == drevid][0]
33787
fa3aa6c98bb7 phabricator: add --amend option to phabsend
Jun Wu <quark@fb.com>
parents: 33785
diff changeset
620 newdesc = getdescfromdrev(drev)
fa3aa6c98bb7 phabricator: add --amend option to phabsend
Jun Wu <quark@fb.com>
parents: 33785
diff changeset
621 # Make sure commit message contain "Differential Revision"
fa3aa6c98bb7 phabricator: add --amend option to phabsend
Jun Wu <quark@fb.com>
parents: 33785
diff changeset
622 if old.description() != newdesc:
41163
0101a35deae2 phabricator: warn if unable to amend, instead of aborting after posting
Matt Harbison <matt_harbison@yahoo.com>
parents: 41080
diff changeset
623 if old.phase() == phases.public:
0101a35deae2 phabricator: warn if unable to amend, instead of aborting after posting
Matt Harbison <matt_harbison@yahoo.com>
parents: 41080
diff changeset
624 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: 41080
diff changeset
625 % scmutil.formatchangeid(old))
0101a35deae2 phabricator: warn if unable to amend, instead of aborting after posting
Matt Harbison <matt_harbison@yahoo.com>
parents: 41080
diff changeset
626 continue
33787
fa3aa6c98bb7 phabricator: add --amend option to phabsend
Jun Wu <quark@fb.com>
parents: 33785
diff changeset
627 parents = [
fa3aa6c98bb7 phabricator: add --amend option to phabsend
Jun Wu <quark@fb.com>
parents: 33785
diff changeset
628 mapping.get(old.p1().node(), (old.p1(),))[0],
fa3aa6c98bb7 phabricator: add --amend option to phabsend
Jun Wu <quark@fb.com>
parents: 33785
diff changeset
629 mapping.get(old.p2().node(), (old.p2(),))[0],
fa3aa6c98bb7 phabricator: add --amend option to phabsend
Jun Wu <quark@fb.com>
parents: 33785
diff changeset
630 ]
fa3aa6c98bb7 phabricator: add --amend option to phabsend
Jun Wu <quark@fb.com>
parents: 33785
diff changeset
631 new = context.metadataonlyctx(
fa3aa6c98bb7 phabricator: add --amend option to phabsend
Jun Wu <quark@fb.com>
parents: 33785
diff changeset
632 repo, old, parents=parents, text=newdesc,
fa3aa6c98bb7 phabricator: add --amend option to phabsend
Jun Wu <quark@fb.com>
parents: 33785
diff changeset
633 user=old.user(), date=old.date(), extra=old.extra())
38336
bb7e3c6ef592 phabricator: preserve the phase when amending in the Differential fields
Matt Harbison <matt_harbison@yahoo.com>
parents: 38042
diff changeset
634
38423
32fba6fe893d scmutil: make cleanupnodes optionally also fix the phase
Martin von Zweigbergk <martinvonz@google.com>
parents: 38392
diff changeset
635 newnode = new.commit()
38336
bb7e3c6ef592 phabricator: preserve the phase when amending in the Differential fields
Matt Harbison <matt_harbison@yahoo.com>
parents: 38042
diff changeset
636
33787
fa3aa6c98bb7 phabricator: add --amend option to phabsend
Jun Wu <quark@fb.com>
parents: 33785
diff changeset
637 mapping[old.node()] = [newnode]
fa3aa6c98bb7 phabricator: add --amend option to phabsend
Jun Wu <quark@fb.com>
parents: 33785
diff changeset
638 # Update diff property
fa3aa6c98bb7 phabricator: add --amend option to phabsend
Jun Wu <quark@fb.com>
parents: 33785
diff changeset
639 writediffproperties(unfi[newnode], diffmap[old.node()])
fa3aa6c98bb7 phabricator: add --amend option to phabsend
Jun Wu <quark@fb.com>
parents: 33785
diff changeset
640 # Remove local tags since it's no longer necessary
38392
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38336
diff changeset
641 tagname = b'D%d' % drevid
33787
fa3aa6c98bb7 phabricator: add --amend option to phabsend
Jun Wu <quark@fb.com>
parents: 33785
diff changeset
642 if tagname in repo.tags():
fa3aa6c98bb7 phabricator: add --amend option to phabsend
Jun Wu <quark@fb.com>
parents: 33785
diff changeset
643 tags.tag(repo, tagname, nullid, message=None, user=None,
fa3aa6c98bb7 phabricator: add --amend option to phabsend
Jun Wu <quark@fb.com>
parents: 33785
diff changeset
644 date=None, local=True)
38423
32fba6fe893d scmutil: make cleanupnodes optionally also fix the phase
Martin von Zweigbergk <martinvonz@google.com>
parents: 38392
diff changeset
645 scmutil.cleanupnodes(repo, mapping, b'phabsend', fixphase=True)
33787
fa3aa6c98bb7 phabricator: add --amend option to phabsend
Jun Wu <quark@fb.com>
parents: 33785
diff changeset
646 if wnode in mapping:
fa3aa6c98bb7 phabricator: add --amend option to phabsend
Jun Wu <quark@fb.com>
parents: 33785
diff changeset
647 unfi.setparents(mapping[wnode][0])
fa3aa6c98bb7 phabricator: add --amend option to phabsend
Jun Wu <quark@fb.com>
parents: 33785
diff changeset
648
33264
266321579c68 phabricator: add node and p1 to hg:meta property
Jun Wu <quark@fb.com>
parents: 33263
diff changeset
649 # 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
650 # consistent with "hg export" output.
41897
c340a8ac7ef3 phabricator: convert conduit response JSON unicode to bytes inside callconduit
Ian Moody <moz-ian@perix.co.uk>
parents: 41705
diff changeset
651 _metanamemap = util.sortdict([(b'user', b'User'), (b'date', b'Date'),
42258
231334c1ee96 phabricator: include branch in the phabread output
Ian Moody <moz-ian@perix.co.uk>
parents: 42257
diff changeset
652 (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: 42257
diff changeset
653 (b'parent', b'Parent ')])
33264
266321579c68 phabricator: add node and p1 to hg:meta property
Jun Wu <quark@fb.com>
parents: 33263
diff changeset
654
33978
088598153aa2 phabsend: show associated Differential Revisions with --confirm
Jun Wu <quark@fb.com>
parents: 33977
diff changeset
655 def _confirmbeforesend(repo, revs, oldmap):
33977
edeb8f28c031 phabsend: print the actual URL with --confirm
Jun Wu <quark@fb.com>
parents: 33976
diff changeset
656 url, token = readurltoken(repo)
33690
40cfe3197bc1 phabricator: add --confirm option to phabsend command
Pulkit Goyal <7895pulkit@gmail.com>
parents: 33601
diff changeset
657 ui = repo.ui
40cfe3197bc1 phabricator: add --confirm option to phabsend command
Pulkit Goyal <7895pulkit@gmail.com>
parents: 33601
diff changeset
658 for rev in revs:
40cfe3197bc1 phabricator: add --confirm option to phabsend command
Pulkit Goyal <7895pulkit@gmail.com>
parents: 33601
diff changeset
659 ctx = repo[rev]
40cfe3197bc1 phabricator: add --confirm option to phabsend command
Pulkit Goyal <7895pulkit@gmail.com>
parents: 33601
diff changeset
660 desc = ctx.description().splitlines()[0]
33978
088598153aa2 phabsend: show associated Differential Revisions with --confirm
Jun Wu <quark@fb.com>
parents: 33977
diff changeset
661 oldnode, olddiff, drevid = oldmap.get(ctx.node(), (None, None, None))
088598153aa2 phabsend: show associated Differential Revisions with --confirm
Jun Wu <quark@fb.com>
parents: 33977
diff changeset
662 if drevid:
38392
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38336
diff changeset
663 drevdesc = ui.label(b'D%s' % drevid, b'phabricator.drev')
33978
088598153aa2 phabsend: show associated Differential Revisions with --confirm
Jun Wu <quark@fb.com>
parents: 33977
diff changeset
664 else:
38392
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38336
diff changeset
665 drevdesc = ui.label(_(b'NEW'), b'phabricator.drev')
33978
088598153aa2 phabsend: show associated Differential Revisions with --confirm
Jun Wu <quark@fb.com>
parents: 33977
diff changeset
666
38392
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38336
diff changeset
667 ui.write(_(b'%s - %s: %s\n')
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38336
diff changeset
668 % (drevdesc,
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38336
diff changeset
669 ui.label(bytes(ctx), b'phabricator.node'),
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38336
diff changeset
670 ui.label(desc, b'phabricator.desc')))
33690
40cfe3197bc1 phabricator: add --confirm option to phabsend command
Pulkit Goyal <7895pulkit@gmail.com>
parents: 33601
diff changeset
671
38392
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38336
diff changeset
672 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: 38336
diff changeset
673 b'$$ &Yes $$ &No') % url):
33690
40cfe3197bc1 phabricator: add --confirm option to phabsend command
Pulkit Goyal <7895pulkit@gmail.com>
parents: 33601
diff changeset
674 return False
40cfe3197bc1 phabricator: add --confirm option to phabsend command
Pulkit Goyal <7895pulkit@gmail.com>
parents: 33601
diff changeset
675
40cfe3197bc1 phabricator: add --confirm option to phabsend command
Pulkit Goyal <7895pulkit@gmail.com>
parents: 33601
diff changeset
676 return True
40cfe3197bc1 phabricator: add --confirm option to phabsend command
Pulkit Goyal <7895pulkit@gmail.com>
parents: 33601
diff changeset
677
38392
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38336
diff changeset
678 _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: 38336
diff changeset
679 b'abandoned'}
33833
fb59192b4981 phabricator: add status to revision query language
Jun Wu <quark@fb.com>
parents: 33832
diff changeset
680
fb59192b4981 phabricator: add status to revision query language
Jun Wu <quark@fb.com>
parents: 33832
diff changeset
681 def _getstatusname(drev):
fb59192b4981 phabricator: add status to revision query language
Jun Wu <quark@fb.com>
parents: 33832
diff changeset
682 """get normalized status name from a Differential Revision"""
41897
c340a8ac7ef3 phabricator: convert conduit response JSON unicode to bytes inside callconduit
Ian Moody <moz-ian@perix.co.uk>
parents: 41705
diff changeset
683 return drev[b'statusName'].replace(b' ', b'').lower()
33833
fb59192b4981 phabricator: add status to revision query language
Jun Wu <quark@fb.com>
parents: 33832
diff changeset
684
33832
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33831
diff changeset
685 # 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: 33831
diff changeset
686 # +, and -.
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33831
diff changeset
687
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33831
diff changeset
688 _elements = {
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33831
diff changeset
689 # token-type: binding-strength, primary, prefix, infix, suffix
38392
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38336
diff changeset
690 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: 38336
diff changeset
691 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: 38336
diff changeset
692 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: 38336
diff changeset
693 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: 38336
diff changeset
694 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: 38336
diff changeset
695 b')': (0, None, None, None, None),
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38336
diff changeset
696 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: 38336
diff changeset
697 b'end': (0, None, None, None, None),
33832
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33831
diff changeset
698 }
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33831
diff changeset
699
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33831
diff changeset
700 def _tokenize(text):
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33831
diff changeset
701 view = memoryview(text) # zero-copy slice
38392
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38336
diff changeset
702 special = b'():+-& '
33832
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33831
diff changeset
703 pos = 0
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33831
diff changeset
704 length = len(text)
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33831
diff changeset
705 while pos < length:
38392
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38336
diff changeset
706 symbol = b''.join(itertools.takewhile(lambda ch: ch not in special,
41950
e7b84ffb06d9 py3: use pycompat.iterbytestr to convert memoryview slice to bytestring
Ian Moody <moz-ian@perix.co.uk>
parents: 41906
diff changeset
707 pycompat.iterbytestr(view[pos:])))
33832
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33831
diff changeset
708 if symbol:
38392
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38336
diff changeset
709 yield (b'symbol', symbol, pos)
33832
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33831
diff changeset
710 pos += len(symbol)
33833
fb59192b4981 phabricator: add status to revision query language
Jun Wu <quark@fb.com>
parents: 33832
diff changeset
711 else: # special char, ignore space
38392
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38336
diff changeset
712 if text[pos] != b' ':
33833
fb59192b4981 phabricator: add status to revision query language
Jun Wu <quark@fb.com>
parents: 33832
diff changeset
713 yield (text[pos], None, pos)
33832
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33831
diff changeset
714 pos += 1
38392
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38336
diff changeset
715 yield (b'end', None, pos)
33832
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33831
diff changeset
716
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33831
diff changeset
717 def _parse(text):
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33831
diff changeset
718 tree, pos = parser.parser(_elements).parse(_tokenize(text))
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33831
diff changeset
719 if pos != len(text):
38392
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38336
diff changeset
720 raise error.ParseError(b'invalid token', pos)
33832
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33831
diff changeset
721 return tree
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33831
diff changeset
722
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33831
diff changeset
723 def _parsedrev(symbol):
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33831
diff changeset
724 """str -> int or None, ex. 'D45' -> 45; '12' -> 12; 'x' -> None"""
38392
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38336
diff changeset
725 if symbol.startswith(b'D') and symbol[1:].isdigit():
33832
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33831
diff changeset
726 return int(symbol[1:])
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33831
diff changeset
727 if symbol.isdigit():
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33831
diff changeset
728 return int(symbol)
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33831
diff changeset
729
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33831
diff changeset
730 def _prefetchdrevs(tree):
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33831
diff changeset
731 """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: 33831
diff changeset
732 drevs = set()
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33831
diff changeset
733 ancestordrevs = set()
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33831
diff changeset
734 op = tree[0]
38392
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38336
diff changeset
735 if op == b'symbol':
33832
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33831
diff changeset
736 r = _parsedrev(tree[1])
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33831
diff changeset
737 if r:
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33831
diff changeset
738 drevs.add(r)
38392
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38336
diff changeset
739 elif op == b'ancestors':
33832
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33831
diff changeset
740 r, a = _prefetchdrevs(tree[1])
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33831
diff changeset
741 drevs.update(r)
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33831
diff changeset
742 ancestordrevs.update(r)
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33831
diff changeset
743 ancestordrevs.update(a)
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33831
diff changeset
744 else:
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33831
diff changeset
745 for t in tree[1:]:
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33831
diff changeset
746 r, a = _prefetchdrevs(t)
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33831
diff changeset
747 drevs.update(r)
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33831
diff changeset
748 ancestordrevs.update(a)
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33831
diff changeset
749 return drevs, ancestordrevs
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33831
diff changeset
750
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33831
diff changeset
751 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
752 """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
753
33832
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33831
diff changeset
754 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: 33831
diff changeset
755 for details.
33267
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
756
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
757 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
758
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
759 {
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
760 "id": "2",
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
761 "phid": "PHID-DREV-672qvysjcczopag46qty",
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
762 "title": "example",
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
763 "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
764 "dateCreated": "1499181406",
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
765 "dateModified": "1499182103",
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
766 "authorPHID": "PHID-USER-tv3ohwc4v4jeu34otlye",
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
767 "status": "0",
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
768 "statusName": "Needs Review",
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
769 "properties": [],
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
770 "branch": null,
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
771 "summary": "",
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
772 "testPlan": "",
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
773 "lineCount": "2",
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
774 "activeDiffPHID": "PHID-DIFF-xoqnjkobbm6k4dk6hi72",
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
775 "diffs": [
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
776 "3",
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
777 "4",
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
778 ],
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
779 "commits": [],
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
780 "reviewers": [],
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
781 "ccs": [],
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
782 "hashes": [],
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
783 "auxiliary": {
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
784 "phabricator:projects": [],
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
785 "phabricator:depends-on": [
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
786 "PHID-DREV-gbapp366kutjebt7agcd"
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
787 ]
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
788 },
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
789 "repositoryPHID": "PHID-REPO-hub2hx62ieuqeheznasv",
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
790 "sourcePath": null
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
791 }
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
792 """
33269
ead6749354e1 phabricator: try to fetch differential revisions in batch
Jun Wu <quark@fb.com>
parents: 33268
diff changeset
793 def fetch(params):
ead6749354e1 phabricator: try to fetch differential revisions in batch
Jun Wu <quark@fb.com>
parents: 33268
diff changeset
794 """params -> single drev or None"""
41902
59bae59b7498 py3: fix a few "dict keys as str instead of bytes" issues in phabricator.py
Ian Moody <moz-ian@perix.co.uk>
parents: 41901
diff changeset
795 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
796 if key in prefetched:
ead6749354e1 phabricator: try to fetch differential revisions in batch
Jun Wu <quark@fb.com>
parents: 33268
diff changeset
797 return prefetched[key]
38392
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38336
diff changeset
798 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
799 # Fill prefetched with the result
ead6749354e1 phabricator: try to fetch differential revisions in batch
Jun Wu <quark@fb.com>
parents: 33268
diff changeset
800 for drev in drevs:
41897
c340a8ac7ef3 phabricator: convert conduit response JSON unicode to bytes inside callconduit
Ian Moody <moz-ian@perix.co.uk>
parents: 41705
diff changeset
801 prefetched[drev[b'phid']] = drev
c340a8ac7ef3 phabricator: convert conduit response JSON unicode to bytes inside callconduit
Ian Moody <moz-ian@perix.co.uk>
parents: 41705
diff changeset
802 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
803 if key not in prefetched:
38392
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38336
diff changeset
804 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: 38336
diff changeset
805 % params)
33269
ead6749354e1 phabricator: try to fetch differential revisions in batch
Jun Wu <quark@fb.com>
parents: 33268
diff changeset
806 return prefetched[key]
ead6749354e1 phabricator: try to fetch differential revisions in batch
Jun Wu <quark@fb.com>
parents: 33268
diff changeset
807
33832
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33831
diff changeset
808 def getstack(topdrevids):
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33831
diff changeset
809 """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: 33831
diff changeset
810 visited = set()
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33831
diff changeset
811 result = []
41902
59bae59b7498 py3: fix a few "dict keys as str instead of bytes" issues in phabricator.py
Ian Moody <moz-ian@perix.co.uk>
parents: 41901
diff changeset
812 queue = [{b'ids': [i]} for i in topdrevids]
33832
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33831
diff changeset
813 while queue:
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33831
diff changeset
814 params = queue.pop()
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33831
diff changeset
815 drev = fetch(params)
41897
c340a8ac7ef3 phabricator: convert conduit response JSON unicode to bytes inside callconduit
Ian Moody <moz-ian@perix.co.uk>
parents: 41705
diff changeset
816 if drev[b'id'] in visited:
33832
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33831
diff changeset
817 continue
41897
c340a8ac7ef3 phabricator: convert conduit response JSON unicode to bytes inside callconduit
Ian Moody <moz-ian@perix.co.uk>
parents: 41705
diff changeset
818 visited.add(drev[b'id'])
c340a8ac7ef3 phabricator: convert conduit response JSON unicode to bytes inside callconduit
Ian Moody <moz-ian@perix.co.uk>
parents: 41705
diff changeset
819 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: 41705
diff changeset
820 auxiliary = drev.get(b'auxiliary', {})
c340a8ac7ef3 phabricator: convert conduit response JSON unicode to bytes inside callconduit
Ian Moody <moz-ian@perix.co.uk>
parents: 41705
diff changeset
821 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
822 for phid in depends:
38392
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38336
diff changeset
823 queue.append({b'phids': [phid]})
33832
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33831
diff changeset
824 result.reverse()
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33831
diff changeset
825 return smartset.baseset(result)
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33831
diff changeset
826
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33831
diff changeset
827 # Initialize prefetch cache
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33831
diff changeset
828 prefetched = {} # {id or phid: drev}
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33831
diff changeset
829
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33831
diff changeset
830 tree = _parse(spec)
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33831
diff changeset
831 drevs, ancestordrevs = _prefetchdrevs(tree)
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33831
diff changeset
832
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33831
diff changeset
833 # developer config: phabricator.batchsize
38392
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38336
diff changeset
834 batchsize = repo.ui.configint(b'phabricator', b'batchsize')
33832
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33831
diff changeset
835
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33831
diff changeset
836 # Prefetch Differential Revisions in batch
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33831
diff changeset
837 tofetch = set(drevs)
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33831
diff changeset
838 for r in ancestordrevs:
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33831
diff changeset
839 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: 33831
diff changeset
840 if drevs:
41897
c340a8ac7ef3 phabricator: convert conduit response JSON unicode to bytes inside callconduit
Ian Moody <moz-ian@perix.co.uk>
parents: 41705
diff changeset
841 fetch({b'ids': list(tofetch)})
33833
fb59192b4981 phabricator: add status to revision query language
Jun Wu <quark@fb.com>
parents: 33832
diff changeset
842 validids = sorted(set(getstack(list(ancestordrevs))) | set(drevs))
33832
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33831
diff changeset
843
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33831
diff changeset
844 # Walk through the tree, return smartsets
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33831
diff changeset
845 def walk(tree):
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33831
diff changeset
846 op = tree[0]
38392
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38336
diff changeset
847 if op == b'symbol':
33832
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33831
diff changeset
848 drev = _parsedrev(tree[1])
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33831
diff changeset
849 if drev:
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33831
diff changeset
850 return smartset.baseset([drev])
33833
fb59192b4981 phabricator: add status to revision query language
Jun Wu <quark@fb.com>
parents: 33832
diff changeset
851 elif tree[1] in _knownstatusnames:
fb59192b4981 phabricator: add status to revision query language
Jun Wu <quark@fb.com>
parents: 33832
diff changeset
852 drevs = [r for r in validids
fb59192b4981 phabricator: add status to revision query language
Jun Wu <quark@fb.com>
parents: 33832
diff changeset
853 if _getstatusname(prefetched[r]) == tree[1]]
fb59192b4981 phabricator: add status to revision query language
Jun Wu <quark@fb.com>
parents: 33832
diff changeset
854 return smartset.baseset(drevs)
33832
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33831
diff changeset
855 else:
38392
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38336
diff changeset
856 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: 38336
diff changeset
857 elif op in {b'and_', b'add', b'sub'}:
33832
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33831
diff changeset
858 assert len(tree) == 3
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33831
diff changeset
859 return getattr(operator, op)(walk(tree[1]), walk(tree[2]))
38392
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38336
diff changeset
860 elif op == b'group':
33832
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33831
diff changeset
861 return walk(tree[1])
38392
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38336
diff changeset
862 elif op == b'ancestors':
33832
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33831
diff changeset
863 return getstack(walk(tree[1]))
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33831
diff changeset
864 else:
38392
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38336
diff changeset
865 raise error.ProgrammingError(b'illegal tree: %r' % tree)
33832
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33831
diff changeset
866
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33831
diff changeset
867 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
868
33268
85391b95961d phabricator: avoid calling differential.getcommitmessage
Jun Wu <quark@fb.com>
parents: 33267
diff changeset
869 def getdescfromdrev(drev):
85391b95961d phabricator: avoid calling differential.getcommitmessage
Jun Wu <quark@fb.com>
parents: 33267
diff changeset
870 """get description (commit message) from "Differential Revision"
85391b95961d phabricator: avoid calling differential.getcommitmessage
Jun Wu <quark@fb.com>
parents: 33267
diff changeset
871
85391b95961d phabricator: avoid calling differential.getcommitmessage
Jun Wu <quark@fb.com>
parents: 33267
diff changeset
872 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
873 about limited fields: title, summary, test plan, and URL.
85391b95961d phabricator: avoid calling differential.getcommitmessage
Jun Wu <quark@fb.com>
parents: 33267
diff changeset
874 """
41897
c340a8ac7ef3 phabricator: convert conduit response JSON unicode to bytes inside callconduit
Ian Moody <moz-ian@perix.co.uk>
parents: 41705
diff changeset
875 title = drev[b'title']
c340a8ac7ef3 phabricator: convert conduit response JSON unicode to bytes inside callconduit
Ian Moody <moz-ian@perix.co.uk>
parents: 41705
diff changeset
876 summary = drev[b'summary'].rstrip()
c340a8ac7ef3 phabricator: convert conduit response JSON unicode to bytes inside callconduit
Ian Moody <moz-ian@perix.co.uk>
parents: 41705
diff changeset
877 testplan = drev[b'testPlan'].rstrip()
33268
85391b95961d phabricator: avoid calling differential.getcommitmessage
Jun Wu <quark@fb.com>
parents: 33267
diff changeset
878 if testplan:
38392
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38336
diff changeset
879 testplan = b'Test Plan:\n%s' % testplan
41897
c340a8ac7ef3 phabricator: convert conduit response JSON unicode to bytes inside callconduit
Ian Moody <moz-ian@perix.co.uk>
parents: 41705
diff changeset
880 uri = b'Differential Revision: %s' % drev[b'uri']
38392
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38336
diff changeset
881 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
882
33441
de7c6ec27d99 phabricator: respect metadata sent by arc
Jun Wu <quark@fb.com>
parents: 33271
diff changeset
883 def getdiffmeta(diff):
de7c6ec27d99 phabricator: respect metadata sent by arc
Jun Wu <quark@fb.com>
parents: 33271
diff changeset
884 """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
885
de7c6ec27d99 phabricator: respect metadata sent by arc
Jun Wu <quark@fb.com>
parents: 33271
diff changeset
886 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
887
de7c6ec27d99 phabricator: respect metadata sent by arc
Jun Wu <quark@fb.com>
parents: 33271
diff changeset
888 "properties": {
de7c6ec27d99 phabricator: respect metadata sent by arc
Jun Wu <quark@fb.com>
parents: 33271
diff changeset
889 "hg:meta": {
de7c6ec27d99 phabricator: respect metadata sent by arc
Jun Wu <quark@fb.com>
parents: 33271
diff changeset
890 "date": "1499571514 25200",
de7c6ec27d99 phabricator: respect metadata sent by arc
Jun Wu <quark@fb.com>
parents: 33271
diff changeset
891 "node": "98c08acae292b2faf60a279b4189beb6cff1414d",
de7c6ec27d99 phabricator: respect metadata sent by arc
Jun Wu <quark@fb.com>
parents: 33271
diff changeset
892 "user": "Foo Bar <foo@example.com>",
de7c6ec27d99 phabricator: respect metadata sent by arc
Jun Wu <quark@fb.com>
parents: 33271
diff changeset
893 "parent": "6d0abad76b30e4724a37ab8721d630394070fe16"
de7c6ec27d99 phabricator: respect metadata sent by arc
Jun Wu <quark@fb.com>
parents: 33271
diff changeset
894 }
de7c6ec27d99 phabricator: respect metadata sent by arc
Jun Wu <quark@fb.com>
parents: 33271
diff changeset
895 }
de7c6ec27d99 phabricator: respect metadata sent by arc
Jun Wu <quark@fb.com>
parents: 33271
diff changeset
896
de7c6ec27d99 phabricator: respect metadata sent by arc
Jun Wu <quark@fb.com>
parents: 33271
diff changeset
897 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
898
de7c6ec27d99 phabricator: respect metadata sent by arc
Jun Wu <quark@fb.com>
parents: 33271
diff changeset
899 "properties": {
de7c6ec27d99 phabricator: respect metadata sent by arc
Jun Wu <quark@fb.com>
parents: 33271
diff changeset
900 "local:commits": {
de7c6ec27d99 phabricator: respect metadata sent by arc
Jun Wu <quark@fb.com>
parents: 33271
diff changeset
901 "98c08acae292b2faf60a279b4189beb6cff1414d": {
de7c6ec27d99 phabricator: respect metadata sent by arc
Jun Wu <quark@fb.com>
parents: 33271
diff changeset
902 "author": "Foo Bar",
de7c6ec27d99 phabricator: respect metadata sent by arc
Jun Wu <quark@fb.com>
parents: 33271
diff changeset
903 "time": 1499546314,
de7c6ec27d99 phabricator: respect metadata sent by arc
Jun Wu <quark@fb.com>
parents: 33271
diff changeset
904 "branch": "default",
de7c6ec27d99 phabricator: respect metadata sent by arc
Jun Wu <quark@fb.com>
parents: 33271
diff changeset
905 "tag": "",
de7c6ec27d99 phabricator: respect metadata sent by arc
Jun Wu <quark@fb.com>
parents: 33271
diff changeset
906 "commit": "98c08acae292b2faf60a279b4189beb6cff1414d",
de7c6ec27d99 phabricator: respect metadata sent by arc
Jun Wu <quark@fb.com>
parents: 33271
diff changeset
907 "rev": "98c08acae292b2faf60a279b4189beb6cff1414d",
de7c6ec27d99 phabricator: respect metadata sent by arc
Jun Wu <quark@fb.com>
parents: 33271
diff changeset
908 "local": "1000",
de7c6ec27d99 phabricator: respect metadata sent by arc
Jun Wu <quark@fb.com>
parents: 33271
diff changeset
909 "parents": ["6d0abad76b30e4724a37ab8721d630394070fe16"],
de7c6ec27d99 phabricator: respect metadata sent by arc
Jun Wu <quark@fb.com>
parents: 33271
diff changeset
910 "summary": "...",
de7c6ec27d99 phabricator: respect metadata sent by arc
Jun Wu <quark@fb.com>
parents: 33271
diff changeset
911 "message": "...",
de7c6ec27d99 phabricator: respect metadata sent by arc
Jun Wu <quark@fb.com>
parents: 33271
diff changeset
912 "authorEmail": "foo@example.com"
de7c6ec27d99 phabricator: respect metadata sent by arc
Jun Wu <quark@fb.com>
parents: 33271
diff changeset
913 }
de7c6ec27d99 phabricator: respect metadata sent by arc
Jun Wu <quark@fb.com>
parents: 33271
diff changeset
914 }
de7c6ec27d99 phabricator: respect metadata sent by arc
Jun Wu <quark@fb.com>
parents: 33271
diff changeset
915 }
de7c6ec27d99 phabricator: respect metadata sent by arc
Jun Wu <quark@fb.com>
parents: 33271
diff changeset
916
de7c6ec27d99 phabricator: respect metadata sent by arc
Jun Wu <quark@fb.com>
parents: 33271
diff changeset
917 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
918 information.
de7c6ec27d99 phabricator: respect metadata sent by arc
Jun Wu <quark@fb.com>
parents: 33271
diff changeset
919 """
41897
c340a8ac7ef3 phabricator: convert conduit response JSON unicode to bytes inside callconduit
Ian Moody <moz-ian@perix.co.uk>
parents: 41705
diff changeset
920 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: 41705
diff changeset
921 meta = props.get(b'hg:meta')
42257
a4f7dceb07bf phabricator: fallback to reading metadata from diff for phabread
Ian Moody <moz-ian@perix.co.uk>
parents: 42256
diff changeset
922 if not meta:
a4f7dceb07bf phabricator: fallback to reading metadata from diff for phabread
Ian Moody <moz-ian@perix.co.uk>
parents: 42256
diff changeset
923 if props.get(b'local:commits'):
a4f7dceb07bf phabricator: fallback to reading metadata from diff for phabread
Ian Moody <moz-ian@perix.co.uk>
parents: 42256
diff changeset
924 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: 42256
diff changeset
925 meta = {}
a4f7dceb07bf phabricator: fallback to reading metadata from diff for phabread
Ian Moody <moz-ian@perix.co.uk>
parents: 42256
diff changeset
926 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: 42256
diff changeset
927 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: 42256
diff changeset
928 commit[b'authorEmail'])
a4f7dceb07bf phabricator: fallback to reading metadata from diff for phabread
Ian Moody <moz-ian@perix.co.uk>
parents: 42256
diff changeset
929 if b'time' in commit:
a4f7dceb07bf phabricator: fallback to reading metadata from diff for phabread
Ian Moody <moz-ian@perix.co.uk>
parents: 42256
diff changeset
930 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: 42256
diff changeset
931 if b'branch' in commit:
a4f7dceb07bf phabricator: fallback to reading metadata from diff for phabread
Ian Moody <moz-ian@perix.co.uk>
parents: 42256
diff changeset
932 meta[b'branch'] = commit[b'branch']
a4f7dceb07bf phabricator: fallback to reading metadata from diff for phabread
Ian Moody <moz-ian@perix.co.uk>
parents: 42256
diff changeset
933 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: 42256
diff changeset
934 if node:
a4f7dceb07bf phabricator: fallback to reading metadata from diff for phabread
Ian Moody <moz-ian@perix.co.uk>
parents: 42256
diff changeset
935 meta[b'node'] = node
a4f7dceb07bf phabricator: fallback to reading metadata from diff for phabread
Ian Moody <moz-ian@perix.co.uk>
parents: 42256
diff changeset
936 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: 42256
diff changeset
937 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: 42256
diff changeset
938 else:
a4f7dceb07bf phabricator: fallback to reading metadata from diff for phabread
Ian Moody <moz-ian@perix.co.uk>
parents: 42256
diff changeset
939 meta = {}
a4f7dceb07bf phabricator: fallback to reading metadata from diff for phabread
Ian Moody <moz-ian@perix.co.uk>
parents: 42256
diff changeset
940 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: 42256
diff changeset
941 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: 42256
diff changeset
942 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: 42256
diff changeset
943 meta[b'branch'] = diff[b'branch']
a4f7dceb07bf phabricator: fallback to reading metadata from diff for phabread
Ian Moody <moz-ian@perix.co.uk>
parents: 42256
diff changeset
944 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: 42256
diff changeset
945 meta[b'parent'] = diff[b'sourceControlBaseRevision']
a4f7dceb07bf phabricator: fallback to reading metadata from diff for phabread
Ian Moody <moz-ian@perix.co.uk>
parents: 42256
diff changeset
946 return meta
33441
de7c6ec27d99 phabricator: respect metadata sent by arc
Jun Wu <quark@fb.com>
parents: 33271
diff changeset
947
33831
75fdaf851e83 phabricator: change "readpatch" to be more flexible
Jun Wu <quark@fb.com>
parents: 33787
diff changeset
948 def readpatch(repo, drevs, write):
33200
04cf9927f350 phabricator: add phabread command to read patches
Jun Wu <quark@fb.com>
parents: 33199
diff changeset
949 """generate plain-text patch readable by 'hg import'
04cf9927f350 phabricator: add phabread command to read patches
Jun Wu <quark@fb.com>
parents: 33199
diff changeset
950
33831
75fdaf851e83 phabricator: change "readpatch" to be more flexible
Jun Wu <quark@fb.com>
parents: 33787
diff changeset
951 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: 33787
diff changeset
952 "differential.query".
33200
04cf9927f350 phabricator: add phabread command to read patches
Jun Wu <quark@fb.com>
parents: 33199
diff changeset
953 """
33267
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
954 # Prefetch hg:meta property for all diffs
41897
c340a8ac7ef3 phabricator: convert conduit response JSON unicode to bytes inside callconduit
Ian Moody <moz-ian@perix.co.uk>
parents: 41705
diff changeset
955 diffids = sorted(set(max(int(v) for v in drev[b'diffs']) for drev in drevs))
38392
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38336
diff changeset
956 diffs = callconduit(repo, b'differential.querydiffs', {b'ids': diffids})
33200
04cf9927f350 phabricator: add phabread command to read patches
Jun Wu <quark@fb.com>
parents: 33199
diff changeset
957
33267
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
958 # 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
959 for drev in drevs:
41897
c340a8ac7ef3 phabricator: convert conduit response JSON unicode to bytes inside callconduit
Ian Moody <moz-ian@perix.co.uk>
parents: 41705
diff changeset
960 repo.ui.note(_(b'reading D%s\n') % drev[b'id'])
33200
04cf9927f350 phabricator: add phabread command to read patches
Jun Wu <quark@fb.com>
parents: 33199
diff changeset
961
41897
c340a8ac7ef3 phabricator: convert conduit response JSON unicode to bytes inside callconduit
Ian Moody <moz-ian@perix.co.uk>
parents: 41705
diff changeset
962 diffid = max(int(v) for v in drev[b'diffs'])
38392
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38336
diff changeset
963 body = callconduit(repo, b'differential.getrawdiff',
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38336
diff changeset
964 {b'diffID': diffid})
33268
85391b95961d phabricator: avoid calling differential.getcommitmessage
Jun Wu <quark@fb.com>
parents: 33267
diff changeset
965 desc = getdescfromdrev(drev)
38392
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38336
diff changeset
966 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
967
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
968 # 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
969 # 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
970 # and extract in mercurial/patch.py for supported headers.
41902
59bae59b7498 py3: fix a few "dict keys as str instead of bytes" issues in phabricator.py
Ian Moody <moz-ian@perix.co.uk>
parents: 41901
diff changeset
971 meta = getdiffmeta(diffs[b'%d' % diffid])
33441
de7c6ec27d99 phabricator: respect metadata sent by arc
Jun Wu <quark@fb.com>
parents: 33271
diff changeset
972 for k in _metanamemap.keys():
de7c6ec27d99 phabricator: respect metadata sent by arc
Jun Wu <quark@fb.com>
parents: 33271
diff changeset
973 if k in meta:
38392
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38336
diff changeset
974 header += b'# %s %s\n' % (_metanamemap[k], meta[k])
33200
04cf9927f350 phabricator: add phabread command to read patches
Jun Wu <quark@fb.com>
parents: 33199
diff changeset
975
38392
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38336
diff changeset
976 content = b'%s%s\n%s' % (header, desc, body)
41897
c340a8ac7ef3 phabricator: convert conduit response JSON unicode to bytes inside callconduit
Ian Moody <moz-ian@perix.co.uk>
parents: 41705
diff changeset
977 write(content)
33200
04cf9927f350 phabricator: add phabread command to read patches
Jun Wu <quark@fb.com>
parents: 33199
diff changeset
978
39650
d8f07b16abfc phabricator: add support for using the vcr library to mock interactions
Augie Fackler <raf@durin42.com>
parents: 38945
diff changeset
979 @vcrcommand(b'phabread',
38392
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38336
diff changeset
980 [(b'', b'stack', False, _(b'read dependencies'))],
41073
536beb130f3c phabricator: assign commands to help categories
Matt Harbison <matt_harbison@yahoo.com>
parents: 40546
diff changeset
981 _(b'DREVSPEC [OPTIONS]'),
536beb130f3c phabricator: assign commands to help categories
Matt Harbison <matt_harbison@yahoo.com>
parents: 40546
diff changeset
982 helpcategory=command.CATEGORY_IMPORT_EXPORT)
33832
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33831
diff changeset
983 def phabread(ui, repo, spec, **opts):
33200
04cf9927f350 phabricator: add phabread command to read patches
Jun Wu <quark@fb.com>
parents: 33199
diff changeset
984 """print patches from Phabricator suitable for importing
04cf9927f350 phabricator: add phabread command to read patches
Jun Wu <quark@fb.com>
parents: 33199
diff changeset
985
33832
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33831
diff changeset
986 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: 33831
diff changeset
987 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: 33831
diff changeset
988 ``&``, ``(``, ``)`` for complex queries. Prefix ``:`` could be used to
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33831
diff changeset
989 select a stack.
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33831
diff changeset
990
33833
fb59192b4981 phabricator: add status to revision query language
Jun Wu <quark@fb.com>
parents: 33832
diff changeset
991 ``abandoned``, ``accepted``, ``closed``, ``needsreview``, ``needsrevision``
fb59192b4981 phabricator: add status to revision query language
Jun Wu <quark@fb.com>
parents: 33832
diff changeset
992 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: 33832
diff changeset
993 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: 33832
diff changeset
994
33832
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33831
diff changeset
995 For example, ``:D6+8-(2+D4)`` selects a stack up to D6, plus D8 and exclude
33833
fb59192b4981 phabricator: add status to revision query language
Jun Wu <quark@fb.com>
parents: 33832
diff changeset
996 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: 33832
diff changeset
997 stack up to D9.
33200
04cf9927f350 phabricator: add phabread command to read patches
Jun Wu <quark@fb.com>
parents: 33199
diff changeset
998
04cf9927f350 phabricator: add phabread command to read patches
Jun Wu <quark@fb.com>
parents: 33199
diff changeset
999 If --stack is given, follow dependencies information and read all patches.
33832
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33831
diff changeset
1000 It is equivalent to the ``:`` operator.
33200
04cf9927f350 phabricator: add phabread command to read patches
Jun Wu <quark@fb.com>
parents: 33199
diff changeset
1001 """
41970
51ba9fbcca52 py3: use pycompat.byteskwargs on opts in phabricator.py
Ian Moody <moz-ian@perix.co.uk>
parents: 41950
diff changeset
1002 opts = pycompat.byteskwargs(opts)
38392
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38336
diff changeset
1003 if opts.get(b'stack'):
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38336
diff changeset
1004 spec = b':(%s)' % spec
33832
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33831
diff changeset
1005 drevs = querydrev(repo, spec)
33831
75fdaf851e83 phabricator: change "readpatch" to be more flexible
Jun Wu <quark@fb.com>
parents: 33787
diff changeset
1006 readpatch(repo, drevs, ui.write)
33834
6e666cd59879 phabricator: add phabupdate command to update status in batch
Jun Wu <quark@fb.com>
parents: 33833
diff changeset
1007
39650
d8f07b16abfc phabricator: add support for using the vcr library to mock interactions
Augie Fackler <raf@durin42.com>
parents: 38945
diff changeset
1008 @vcrcommand(b'phabupdate',
38392
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38336
diff changeset
1009 [(b'', b'accept', False, _(b'accept revisions')),
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38336
diff changeset
1010 (b'', b'reject', False, _(b'reject revisions')),
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38336
diff changeset
1011 (b'', b'abandon', False, _(b'abandon revisions')),
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38336
diff changeset
1012 (b'', b'reclaim', False, _(b'reclaim revisions')),
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38336
diff changeset
1013 (b'm', b'comment', b'', _(b'comment on the last revision')),
41073
536beb130f3c phabricator: assign commands to help categories
Matt Harbison <matt_harbison@yahoo.com>
parents: 40546
diff changeset
1014 ], _(b'DREVSPEC [OPTIONS]'),
536beb130f3c phabricator: assign commands to help categories
Matt Harbison <matt_harbison@yahoo.com>
parents: 40546
diff changeset
1015 helpcategory=command.CATEGORY_IMPORT_EXPORT)
33834
6e666cd59879 phabricator: add phabupdate command to update status in batch
Jun Wu <quark@fb.com>
parents: 33833
diff changeset
1016 def phabupdate(ui, repo, spec, **opts):
6e666cd59879 phabricator: add phabupdate command to update status in batch
Jun Wu <quark@fb.com>
parents: 33833
diff changeset
1017 """update Differential Revision in batch
6e666cd59879 phabricator: add phabupdate command to update status in batch
Jun Wu <quark@fb.com>
parents: 33833
diff changeset
1018
6e666cd59879 phabricator: add phabupdate command to update status in batch
Jun Wu <quark@fb.com>
parents: 33833
diff changeset
1019 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: 33833
diff changeset
1020 """
41970
51ba9fbcca52 py3: use pycompat.byteskwargs on opts in phabricator.py
Ian Moody <moz-ian@perix.co.uk>
parents: 41950
diff changeset
1021 opts = pycompat.byteskwargs(opts)
38392
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38336
diff changeset
1022 flags = [n for n in b'accept reject abandon reclaim'.split() if opts.get(n)]
33834
6e666cd59879 phabricator: add phabupdate command to update status in batch
Jun Wu <quark@fb.com>
parents: 33833
diff changeset
1023 if len(flags) > 1:
38392
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38336
diff changeset
1024 raise error.Abort(_(b'%s cannot be used together') % b', '.join(flags))
33834
6e666cd59879 phabricator: add phabupdate command to update status in batch
Jun Wu <quark@fb.com>
parents: 33833
diff changeset
1025
6e666cd59879 phabricator: add phabupdate command to update status in batch
Jun Wu <quark@fb.com>
parents: 33833
diff changeset
1026 actions = []
6e666cd59879 phabricator: add phabupdate command to update status in batch
Jun Wu <quark@fb.com>
parents: 33833
diff changeset
1027 for f in flags:
38392
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38336
diff changeset
1028 actions.append({b'type': f, b'value': b'true'})
33834
6e666cd59879 phabricator: add phabupdate command to update status in batch
Jun Wu <quark@fb.com>
parents: 33833
diff changeset
1029
6e666cd59879 phabricator: add phabupdate command to update status in batch
Jun Wu <quark@fb.com>
parents: 33833
diff changeset
1030 drevs = querydrev(repo, spec)
6e666cd59879 phabricator: add phabupdate command to update status in batch
Jun Wu <quark@fb.com>
parents: 33833
diff changeset
1031 for i, drev in enumerate(drevs):
38392
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38336
diff changeset
1032 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: 38336
diff changeset
1033 actions.append({b'type': b'comment', b'value': opts[b'comment']})
33834
6e666cd59879 phabricator: add phabupdate command to update status in batch
Jun Wu <quark@fb.com>
parents: 33833
diff changeset
1034 if actions:
41897
c340a8ac7ef3 phabricator: convert conduit response JSON unicode to bytes inside callconduit
Ian Moody <moz-ian@perix.co.uk>
parents: 41705
diff changeset
1035 params = {b'objectIdentifier': drev[b'phid'],
38392
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38336
diff changeset
1036 b'transactions': actions}
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38336
diff changeset
1037 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
1038
f18ba40d792f phabricator: add a template item for linking to a differential review
Tom Prince <mozilla@hocat.ca>
parents: 35626
diff changeset
1039 templatekeyword = registrar.templatekeyword()
f18ba40d792f phabricator: add a template item for linking to a differential review
Tom Prince <mozilla@hocat.ca>
parents: 35626
diff changeset
1040
38392
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38336
diff changeset
1041 @templatekeyword(b'phabreview', requires={b'ctx'})
36514
7b74afec6772 templatekw: switch non-showlist template keywords to new API
Yuya Nishihara <yuya@tcha.org>
parents: 35722
diff changeset
1042 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
1043 """: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
1044 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
1045 """
38392
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38336
diff changeset
1046 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
1047 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
1048 if m:
39654
4057e38bba76 phabricator: fix templating bug by using hybriddict
Augie Fackler <raf@durin42.com>
parents: 39652
diff changeset
1049 return templateutil.hybriddict({
41905
16d050678047 py3: use r'' for group name arguments to MatchObjects in phabricator.py
Ian Moody <moz-ian@perix.co.uk>
parents: 41904
diff changeset
1050 b'url': m.group(r'url'),
41906
2b21c7fbb3a1 py3: use % instead of .format() on a bytestring
Ian Moody <moz-ian@perix.co.uk>
parents: 41905
diff changeset
1051 b'id': b"D%s" % m.group(r'id'),
39654
4057e38bba76 phabricator: fix templating bug by using hybriddict
Augie Fackler <raf@durin42.com>
parents: 39652
diff changeset
1052 })
41164
43fd1947301d phabricator: teach {phabreview} to work without --amend
Matt Harbison <matt_harbison@yahoo.com>
parents: 41163
diff changeset
1053 else:
43fd1947301d phabricator: teach {phabreview} to work without --amend
Matt Harbison <matt_harbison@yahoo.com>
parents: 41163
diff changeset
1054 tags = ctx.repo().nodetags(ctx.node())
43fd1947301d phabricator: teach {phabreview} to work without --amend
Matt Harbison <matt_harbison@yahoo.com>
parents: 41163
diff changeset
1055 for t in tags:
43fd1947301d phabricator: teach {phabreview} to work without --amend
Matt Harbison <matt_harbison@yahoo.com>
parents: 41163
diff changeset
1056 if _differentialrevisiontagre.match(t):
43fd1947301d phabricator: teach {phabreview} to work without --amend
Matt Harbison <matt_harbison@yahoo.com>
parents: 41163
diff changeset
1057 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
1058 if not url.endswith(b'/'):
43fd1947301d phabricator: teach {phabreview} to work without --amend
Matt Harbison <matt_harbison@yahoo.com>
parents: 41163
diff changeset
1059 url += b'/'
43fd1947301d phabricator: teach {phabreview} to work without --amend
Matt Harbison <matt_harbison@yahoo.com>
parents: 41163
diff changeset
1060 url += t
43fd1947301d phabricator: teach {phabreview} to work without --amend
Matt Harbison <matt_harbison@yahoo.com>
parents: 41163
diff changeset
1061
43fd1947301d phabricator: teach {phabreview} to work without --amend
Matt Harbison <matt_harbison@yahoo.com>
parents: 41163
diff changeset
1062 return templateutil.hybriddict({
43fd1947301d phabricator: teach {phabreview} to work without --amend
Matt Harbison <matt_harbison@yahoo.com>
parents: 41163
diff changeset
1063 b'url': url,
43fd1947301d phabricator: teach {phabreview} to work without --amend
Matt Harbison <matt_harbison@yahoo.com>
parents: 41163
diff changeset
1064 b'id': t,
43fd1947301d phabricator: teach {phabreview} to work without --amend
Matt Harbison <matt_harbison@yahoo.com>
parents: 41163
diff changeset
1065 })
43fd1947301d phabricator: teach {phabreview} to work without --amend
Matt Harbison <matt_harbison@yahoo.com>
parents: 41163
diff changeset
1066 return None