hgext/phabricator.py
author Ian Moody <moz-ian@perix.co.uk>
Sun, 06 Oct 2019 15:37:13 +0100
changeset 43189 9f802243a42e
parent 43188 24e8aac7c630
child 43190 c19b327017b9
permissions -rw-r--r--
phabricator: add makebinary and addoldbinary functions These populate the phabchange with the data for a binary file, much as maketext does for text files. Differential Revision: https://phab.mercurial-scm.org/D7048
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
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
43187
453079605242 phabricator: add the uploadchunks function
Ian Moody <moz-ian@perix.co.uk>
parents: 43186
diff changeset
    44
import base64
41080
9d35ae3d9999 phabricator: ensure that the return of urlopener.open() is closed
Matt Harbison <matt_harbison@yahoo.com>
parents: 41078
diff changeset
    45
import contextlib
43188
24e8aac7c630 phabricator: add the uploadfile function
Ian Moody <moz-ian@perix.co.uk>
parents: 43187
diff changeset
    46
import hashlib
33832
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33831
diff changeset
    47
import itertools
33198
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
    48
import json
43189
9f802243a42e phabricator: add makebinary and addoldbinary functions
Ian Moody <moz-ian@perix.co.uk>
parents: 43188
diff changeset
    49
import mimetypes
33832
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33831
diff changeset
    50
import operator
33199
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
    51
import re
33198
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
    52
33443
e48082e0a8d5 phabricator: verify local tags before trusting them
Jun Wu <quark@fb.com>
parents: 33442
diff changeset
    53
from mercurial.node import bin, nullid
33198
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
    54
from mercurial.i18n import _
43089
c59eb1560c44 py3: manually import getattr where it is needed
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43080
diff changeset
    55
from mercurial.pycompat import getattr
43183
73d4bc60e389 phabricator: add the phabhunk data structure
Ian Moody <moz-ian@perix.co.uk>
parents: 43182
diff changeset
    56
from mercurial.thirdparty import attr
33198
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
    57
from mercurial import (
33787
fa3aa6c98bb7 phabricator: add --amend option to phabsend
Jun Wu <quark@fb.com>
parents: 33785
diff changeset
    58
    cmdutil,
fa3aa6c98bb7 phabricator: add --amend option to phabsend
Jun Wu <quark@fb.com>
parents: 33785
diff changeset
    59
    context,
33199
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
    60
    encoding,
33198
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
    61
    error,
42973
24bf7a3d3c30 phabricator: use exthelper to register commands, config, and templates
Matt Harbison <matt_harbison@yahoo.com>
parents: 42951
diff changeset
    62
    exthelper,
37997
71cf20d47f25 phabricator: split auth.url into the standard auth.schemes and auth.prefix
Matt Harbison <matt_harbison@yahoo.com>
parents: 37996
diff changeset
    63
    httpconnection as httpconnectionmod,
43186
f742fabad507 phabricator: add the maketext function
Ian Moody <moz-ian@perix.co.uk>
parents: 43185
diff changeset
    64
    match,
33199
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
    65
    mdiff,
33735
e6d8ee3c9ec3 obsutil: rename allprecursors into allpredecessors
Boris Feld <boris.feld@octobus.net>
parents: 33692
diff changeset
    66
    obsutil,
33832
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33831
diff changeset
    67
    parser,
33199
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
    68
    patch,
41163
0101a35deae2 phabricator: warn if unable to amend, instead of aborting after posting
Matt Harbison <matt_harbison@yahoo.com>
parents: 41080
diff changeset
    69
    phases,
41897
c340a8ac7ef3 phabricator: convert conduit response JSON unicode to bytes inside callconduit
Ian Moody <moz-ian@perix.co.uk>
parents: 41705
diff changeset
    70
    pycompat,
33199
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
    71
    scmutil,
33832
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33831
diff changeset
    72
    smartset,
33199
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
    73
    tags,
42188
289d82a070e9 phabricator: use templatefilters.json in writediffproperties
Ian Moody <moz-ian@perix.co.uk>
parents: 41971
diff changeset
    74
    templatefilters,
39654
4057e38bba76 phabricator: fix templating bug by using hybriddict
Augie Fackler <raf@durin42.com>
parents: 39652
diff changeset
    75
    templateutil,
33198
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
    76
    url as urlmod,
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
    77
    util,
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
    78
)
37120
a8a902d7176e procutil: bulk-replace function calls to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 36818
diff changeset
    79
from mercurial.utils import (
a8a902d7176e procutil: bulk-replace function calls to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 36818
diff changeset
    80
    procutil,
37800
6cf5f5b4eb57 phabricator: specify some metadata compatibly with arc
Tom Prince <mozilla@hocat.ca>
parents: 37120
diff changeset
    81
    stringutil,
37120
a8a902d7176e procutil: bulk-replace function calls to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 36818
diff changeset
    82
)
33198
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
    83
39735
c0c703861b60 phabricator: add testedwith boilerplate
Yuya Nishihara <yuya@tcha.org>
parents: 39655
diff changeset
    84
# 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
    85
# extensions which SHIP WITH MERCURIAL. Non-mainline extensions should
c0c703861b60 phabricator: add testedwith boilerplate
Yuya Nishihara <yuya@tcha.org>
parents: 39655
diff changeset
    86
# 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
    87
# leave the attribute unspecified.
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
    88
testedwith = b'ships-with-hg-core'
39735
c0c703861b60 phabricator: add testedwith boilerplate
Yuya Nishihara <yuya@tcha.org>
parents: 39655
diff changeset
    89
42973
24bf7a3d3c30 phabricator: use exthelper to register commands, config, and templates
Matt Harbison <matt_harbison@yahoo.com>
parents: 42951
diff changeset
    90
eh = exthelper.exthelper()
33198
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
    91
42973
24bf7a3d3c30 phabricator: use exthelper to register commands, config, and templates
Matt Harbison <matt_harbison@yahoo.com>
parents: 42951
diff changeset
    92
cmdtable = eh.cmdtable
24bf7a3d3c30 phabricator: use exthelper to register commands, config, and templates
Matt Harbison <matt_harbison@yahoo.com>
parents: 42951
diff changeset
    93
command = eh.command
24bf7a3d3c30 phabricator: use exthelper to register commands, config, and templates
Matt Harbison <matt_harbison@yahoo.com>
parents: 42951
diff changeset
    94
configtable = eh.configtable
24bf7a3d3c30 phabricator: use exthelper to register commands, config, and templates
Matt Harbison <matt_harbison@yahoo.com>
parents: 42951
diff changeset
    95
templatekeyword = eh.templatekeyword
38042
5a7cf42ba6ef phabricator: register config settings
Matt Harbison <matt_harbison@yahoo.com>
parents: 37997
diff changeset
    96
5a7cf42ba6ef phabricator: register config settings
Matt Harbison <matt_harbison@yahoo.com>
parents: 37997
diff changeset
    97
# developer config: phabricator.batchsize
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
    98
eh.configitem(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
    99
    b'phabricator', b'batchsize', default=12,
38042
5a7cf42ba6ef phabricator: register config settings
Matt Harbison <matt_harbison@yahoo.com>
parents: 37997
diff changeset
   100
)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   101
eh.configitem(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   102
    b'phabricator', b'callsign', default=None,
38042
5a7cf42ba6ef phabricator: register config settings
Matt Harbison <matt_harbison@yahoo.com>
parents: 37997
diff changeset
   103
)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   104
eh.configitem(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   105
    b'phabricator', b'curlcmd', default=None,
38042
5a7cf42ba6ef phabricator: register config settings
Matt Harbison <matt_harbison@yahoo.com>
parents: 37997
diff changeset
   106
)
5a7cf42ba6ef phabricator: register config settings
Matt Harbison <matt_harbison@yahoo.com>
parents: 37997
diff changeset
   107
# developer config: phabricator.repophid
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   108
eh.configitem(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   109
    b'phabricator', b'repophid', default=None,
38042
5a7cf42ba6ef phabricator: register config settings
Matt Harbison <matt_harbison@yahoo.com>
parents: 37997
diff changeset
   110
)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   111
eh.configitem(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   112
    b'phabricator', b'url', default=None,
38042
5a7cf42ba6ef phabricator: register config settings
Matt Harbison <matt_harbison@yahoo.com>
parents: 37997
diff changeset
   113
)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   114
eh.configitem(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   115
    b'phabsend', b'confirm', default=False,
38042
5a7cf42ba6ef phabricator: register config settings
Matt Harbison <matt_harbison@yahoo.com>
parents: 37997
diff changeset
   116
)
5a7cf42ba6ef phabricator: register config settings
Matt Harbison <matt_harbison@yahoo.com>
parents: 37997
diff changeset
   117
34063
941c33cfde81 phabricator: standardize colors
Jun Wu <quark@fb.com>
parents: 33978
diff changeset
   118
colortable = {
38392
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38336
diff changeset
   119
    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
   120
    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
   121
    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
   122
    b'phabricator.desc': b'',
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38336
diff changeset
   123
    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
   124
    b'phabricator.node': b'',
34063
941c33cfde81 phabricator: standardize colors
Jun Wu <quark@fb.com>
parents: 33978
diff changeset
   125
}
941c33cfde81 phabricator: standardize colors
Jun Wu <quark@fb.com>
parents: 33978
diff changeset
   126
39650
d8f07b16abfc phabricator: add support for using the vcr library to mock interactions
Augie Fackler <raf@durin42.com>
parents: 38945
diff changeset
   127
_VCR_FLAGS = [
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   128
    (
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   129
        b'',
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   130
        b'test-vcr',
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   131
        b'',
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   132
        _(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   133
            b'Path to a vcr file. If nonexistent, will record a new vcr transcript'
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   134
            b', otherwise will mock all http requests using the specified vcr file.'
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   135
            b' (ADVANCED)'
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   136
        ),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   137
    ),
39650
d8f07b16abfc phabricator: add support for using the vcr library to mock interactions
Augie Fackler <raf@durin42.com>
parents: 38945
diff changeset
   138
]
d8f07b16abfc phabricator: add support for using the vcr library to mock interactions
Augie Fackler <raf@durin42.com>
parents: 38945
diff changeset
   139
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   140
42435
16312ea45a8b phabricator: make `hg debugcallconduit` work outside a hg repo
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42434
diff changeset
   141
def vcrcommand(name, flags, spec, helpcategory=None, optionalrepo=False):
39650
d8f07b16abfc phabricator: add support for using the vcr library to mock interactions
Augie Fackler <raf@durin42.com>
parents: 38945
diff changeset
   142
    fullflags = flags + _VCR_FLAGS
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   143
42268
af13e2088f77 phabricator: add custom vcr matcher to match request bodies
Ian Moody <moz-ian@perix.co.uk>
parents: 42258
diff changeset
   144
    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
   145
        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
   146
            return False
af13e2088f77 phabricator: add custom vcr matcher to match request bodies
Ian Moody <moz-ian@perix.co.uk>
parents: 42258
diff changeset
   147
        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
   148
        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
   149
        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
   150
42443
d3c81439e2ee phabricator: auto-sanitise API tokens and HTTP cookies from VCR recordings
Ian Moody <moz-ian@perix.co.uk>
parents: 42435
diff changeset
   151
    def sanitiserequest(request):
d3c81439e2ee phabricator: auto-sanitise API tokens and HTTP cookies from VCR recordings
Ian Moody <moz-ian@perix.co.uk>
parents: 42435
diff changeset
   152
        request.body = re.sub(
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   153
            br'cli-[a-z0-9]+', br'cli-hahayouwish', request.body
42443
d3c81439e2ee phabricator: auto-sanitise API tokens and HTTP cookies from VCR recordings
Ian Moody <moz-ian@perix.co.uk>
parents: 42435
diff changeset
   154
        )
d3c81439e2ee phabricator: auto-sanitise API tokens and HTTP cookies from VCR recordings
Ian Moody <moz-ian@perix.co.uk>
parents: 42435
diff changeset
   155
        return request
d3c81439e2ee phabricator: auto-sanitise API tokens and HTTP cookies from VCR recordings
Ian Moody <moz-ian@perix.co.uk>
parents: 42435
diff changeset
   156
d3c81439e2ee phabricator: auto-sanitise API tokens and HTTP cookies from VCR recordings
Ian Moody <moz-ian@perix.co.uk>
parents: 42435
diff changeset
   157
    def sanitiseresponse(response):
d3c81439e2ee phabricator: auto-sanitise API tokens and HTTP cookies from VCR recordings
Ian Moody <moz-ian@perix.co.uk>
parents: 42435
diff changeset
   158
        if r'set-cookie' in response[r'headers']:
d3c81439e2ee phabricator: auto-sanitise API tokens and HTTP cookies from VCR recordings
Ian Moody <moz-ian@perix.co.uk>
parents: 42435
diff changeset
   159
            del response[r'headers'][r'set-cookie']
d3c81439e2ee phabricator: auto-sanitise API tokens and HTTP cookies from VCR recordings
Ian Moody <moz-ian@perix.co.uk>
parents: 42435
diff changeset
   160
        return response
d3c81439e2ee phabricator: auto-sanitise API tokens and HTTP cookies from VCR recordings
Ian Moody <moz-ian@perix.co.uk>
parents: 42435
diff changeset
   161
39650
d8f07b16abfc phabricator: add support for using the vcr library to mock interactions
Augie Fackler <raf@durin42.com>
parents: 38945
diff changeset
   162
    def decorate(fn):
d8f07b16abfc phabricator: add support for using the vcr library to mock interactions
Augie Fackler <raf@durin42.com>
parents: 38945
diff changeset
   163
        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
   164
            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
   165
            if cassette:
d8f07b16abfc phabricator: add support for using the vcr library to mock interactions
Augie Fackler <raf@durin42.com>
parents: 38945
diff changeset
   166
                import hgdemandimport
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   167
39650
d8f07b16abfc phabricator: add support for using the vcr library to mock interactions
Augie Fackler <raf@durin42.com>
parents: 38945
diff changeset
   168
                with hgdemandimport.deactivated():
d8f07b16abfc phabricator: add support for using the vcr library to mock interactions
Augie Fackler <raf@durin42.com>
parents: 38945
diff changeset
   169
                    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
   170
                    import vcr.stubs as stubs
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   171
40378
b015f30a91fb phabricator: do more of the VCR work in demandimport.deactivated()
Augie Fackler <augie@google.com>
parents: 40151
diff changeset
   172
                    vcr = vcrmod.VCR(
b015f30a91fb phabricator: do more of the VCR work in demandimport.deactivated()
Augie Fackler <augie@google.com>
parents: 40151
diff changeset
   173
                        serializer=r'json',
42443
d3c81439e2ee phabricator: auto-sanitise API tokens and HTTP cookies from VCR recordings
Ian Moody <moz-ian@perix.co.uk>
parents: 42435
diff changeset
   174
                        before_record_request=sanitiserequest,
d3c81439e2ee phabricator: auto-sanitise API tokens and HTTP cookies from VCR recordings
Ian Moody <moz-ian@perix.co.uk>
parents: 42435
diff changeset
   175
                        before_record_response=sanitiseresponse,
40378
b015f30a91fb phabricator: do more of the VCR work in demandimport.deactivated()
Augie Fackler <augie@google.com>
parents: 40151
diff changeset
   176
                        custom_patches=[
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   177
                            (
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   178
                                urlmod,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   179
                                r'httpconnection',
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   180
                                stubs.VCRHTTPConnection,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   181
                            ),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   182
                            (
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   183
                                urlmod,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   184
                                r'httpsconnection',
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   185
                                stubs.VCRHTTPSConnection,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   186
                            ),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   187
                        ],
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   188
                    )
42268
af13e2088f77 phabricator: add custom vcr matcher to match request bodies
Ian Moody <moz-ian@perix.co.uk>
parents: 42258
diff changeset
   189
                    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
   190
                    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
   191
                        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
   192
            return fn(*args, **kwargs)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   193
39650
d8f07b16abfc phabricator: add support for using the vcr library to mock interactions
Augie Fackler <raf@durin42.com>
parents: 38945
diff changeset
   194
        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
   195
        inner.__doc__ = fn.__doc__
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   196
        return command(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   197
            name,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   198
            fullflags,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   199
            spec,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   200
            helpcategory=helpcategory,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   201
            optionalrepo=optionalrepo,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   202
        )(inner)
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   203
39650
d8f07b16abfc phabricator: add support for using the vcr library to mock interactions
Augie Fackler <raf@durin42.com>
parents: 38945
diff changeset
   204
    return decorate
d8f07b16abfc phabricator: add support for using the vcr library to mock interactions
Augie Fackler <raf@durin42.com>
parents: 38945
diff changeset
   205
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   206
33198
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
   207
def urlencodenested(params):
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
   208
    """like urlencode, but works with nested parameters.
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
   209
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
   210
    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
   211
    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
   212
    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
   213
    """
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
   214
    flatparams = util.sortdict()
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   215
33198
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
   216
    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
   217
        if isinstance(obj, bool):
d7d3164e6a31 phabricator: properly encode boolean types in the request body
Matt Harbison <matt_harbison@yahoo.com>
parents: 40546
diff changeset
   218
            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
   219
        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
   220
        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
   221
        if items is None:
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
   222
            flatparams[prefix] = obj
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
   223
        else:
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
   224
            for k, v in items(obj):
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
   225
                if prefix:
38392
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38336
diff changeset
   226
                    process(b'%s[%s]' % (prefix, k), v)
33198
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
   227
                else:
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
   228
                    process(k, v)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   229
38392
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38336
diff changeset
   230
    process(b'', params)
33198
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
   231
    return util.urlreq.urlencode(flatparams)
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
   232
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   233
42433
500b64c5d991 phabricator: pass ui into readurltoken instead of passing repo
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42431
diff changeset
   234
def readurltoken(ui):
37996
0fa050bc68cb phabricator: migrate [phabricator.auth] to [auth]
Matt Harbison <matt_harbison@yahoo.com>
parents: 37976
diff changeset
   235
    """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
   236
37997
71cf20d47f25 phabricator: split auth.url into the standard auth.schemes and auth.prefix
Matt Harbison <matt_harbison@yahoo.com>
parents: 37996
diff changeset
   237
    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
   238
    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
   239
    """
42433
500b64c5d991 phabricator: pass ui into readurltoken instead of passing repo
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42431
diff changeset
   240
    url = ui.config(b'phabricator', b'url')
37996
0fa050bc68cb phabricator: migrate [phabricator.auth] to [auth]
Matt Harbison <matt_harbison@yahoo.com>
parents: 37976
diff changeset
   241
    if not url:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   242
        raise error.Abort(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   243
            _(b'config %s.%s is required') % (b'phabricator', b'url')
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   244
        )
37996
0fa050bc68cb phabricator: migrate [phabricator.auth] to [auth]
Matt Harbison <matt_harbison@yahoo.com>
parents: 37976
diff changeset
   245
42433
500b64c5d991 phabricator: pass ui into readurltoken instead of passing repo
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42431
diff changeset
   246
    res = httpconnectionmod.readauthforuri(ui, url, util.url(url).user)
37997
71cf20d47f25 phabricator: split auth.url into the standard auth.schemes and auth.prefix
Matt Harbison <matt_harbison@yahoo.com>
parents: 37996
diff changeset
   247
    token = None
37996
0fa050bc68cb phabricator: migrate [phabricator.auth] to [auth]
Matt Harbison <matt_harbison@yahoo.com>
parents: 37976
diff changeset
   248
37997
71cf20d47f25 phabricator: split auth.url into the standard auth.schemes and auth.prefix
Matt Harbison <matt_harbison@yahoo.com>
parents: 37996
diff changeset
   249
    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
   250
        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
   251
42433
500b64c5d991 phabricator: pass ui into readurltoken instead of passing repo
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42431
diff changeset
   252
        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
   253
38392
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38336
diff changeset
   254
        token = auth.get(b'phabtoken')
37996
0fa050bc68cb phabricator: migrate [phabricator.auth] to [auth]
Matt Harbison <matt_harbison@yahoo.com>
parents: 37976
diff changeset
   255
36787
4397909f82d3 phabricator: specify API tokens per host, rather than per repo
Tom Prince <mozilla@hocat.ca>
parents: 36514
diff changeset
   256
    if not token:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   257
        raise error.Abort(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   258
            _(b'Can\'t find conduit token associated to %s') % (url,)
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   259
        )
36787
4397909f82d3 phabricator: specify API tokens per host, rather than per repo
Tom Prince <mozilla@hocat.ca>
parents: 36514
diff changeset
   260
4397909f82d3 phabricator: specify API tokens per host, rather than per repo
Tom Prince <mozilla@hocat.ca>
parents: 36514
diff changeset
   261
    return url, token
33198
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
   262
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   263
42434
f163e2b2594c phabricator: pass ui instead of repo to callconduit
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42433
diff changeset
   264
def callconduit(ui, name, params):
33198
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
   265
    """call Conduit API, params is a dict. return json.loads result, or None"""
42434
f163e2b2594c phabricator: pass ui instead of repo to callconduit
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42433
diff changeset
   266
    host, token = readurltoken(ui)
38392
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38336
diff changeset
   267
    url, authinfo = util.url(b'/'.join([host, b'api', name])).authinfo()
42434
f163e2b2594c phabricator: pass ui instead of repo to callconduit
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42433
diff changeset
   268
    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
   269
    params = params.copy()
38392
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38336
diff changeset
   270
    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
   271
    data = urlencodenested(params)
42434
f163e2b2594c phabricator: pass ui instead of repo to callconduit
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42433
diff changeset
   272
    curlcmd = 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
   273
    if curlcmd:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   274
        sin, sout = procutil.popen2(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   275
            b'%s -d @- %s' % (curlcmd, procutil.shellquote(url))
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   276
        )
34064
8b659b7388c0 phabricator: add a config to use curl for communication
Jun Wu <quark@fb.com>
parents: 34063
diff changeset
   277
        sin.write(data)
8b659b7388c0 phabricator: add a config to use curl for communication
Jun Wu <quark@fb.com>
parents: 34063
diff changeset
   278
        sin.close()
8b659b7388c0 phabricator: add a config to use curl for communication
Jun Wu <quark@fb.com>
parents: 34063
diff changeset
   279
        body = sout.read()
8b659b7388c0 phabricator: add a config to use curl for communication
Jun Wu <quark@fb.com>
parents: 34063
diff changeset
   280
    else:
42434
f163e2b2594c phabricator: pass ui instead of repo to callconduit
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42433
diff changeset
   281
        urlopener = urlmod.opener(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
   282
        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
   283
        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
   284
            body = rsp.read()
42434
f163e2b2594c phabricator: pass ui instead of repo to callconduit
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42433
diff changeset
   285
    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
   286
    parsed = pycompat.rapply(
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   287
        lambda x: encoding.unitolocal(x)
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   288
        if isinstance(x, pycompat.unicode)
41897
c340a8ac7ef3 phabricator: convert conduit response JSON unicode to bytes inside callconduit
Ian Moody <moz-ian@perix.co.uk>
parents: 41705
diff changeset
   289
        else x,
43047
0f90c2d2d7e8 py3: fix phabricator's use of json.loads() for py3.5
Ian Moody <moz-ian@perix.co.uk>
parents: 42973
diff changeset
   290
        # json.loads only accepts bytes from py3.6+
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   291
        json.loads(encoding.unifromlocal(body)),
41897
c340a8ac7ef3 phabricator: convert conduit response JSON unicode to bytes inside callconduit
Ian Moody <moz-ian@perix.co.uk>
parents: 41705
diff changeset
   292
    )
c340a8ac7ef3 phabricator: convert conduit response JSON unicode to bytes inside callconduit
Ian Moody <moz-ian@perix.co.uk>
parents: 41705
diff changeset
   293
    if parsed.get(b'error_code'):
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   294
        msg = _(b'Conduit Error (%s): %s') % (
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   295
            parsed[b'error_code'],
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   296
            parsed[b'error_info'],
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   297
        )
33198
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
   298
        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
   299
    return parsed[b'result']
33198
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
   300
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   301
42435
16312ea45a8b phabricator: make `hg debugcallconduit` work outside a hg repo
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42434
diff changeset
   302
@vcrcommand(b'debugcallconduit', [], _(b'METHOD'), optionalrepo=True)
33198
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
   303
def debugcallconduit(ui, repo, name):
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
   304
    """call Conduit API
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
   305
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
   306
    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
   307
    to stdout as a JSON blob.
36b3febd739f phabricator: add a contrib script
Jun Wu <quark@fb.com>
parents:
diff changeset
   308
    """
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
   309
    # 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
   310
    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
   311
    # json.loads only returns unicode strings
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   312
    params = pycompat.rapply(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   313
        lambda x: encoding.unitolocal(x)
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   314
        if isinstance(x, pycompat.unicode)
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   315
        else x,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   316
        json.loads(rawparams),
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
   317
    )
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
   318
    # json.dumps only accepts unicode strings
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   319
    result = pycompat.rapply(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   320
        lambda x: encoding.unifromlocal(x) if isinstance(x, bytes) else x,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   321
        callconduit(ui, name, params),
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
   322
    )
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
   323
    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
   324
    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
   325
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   326
33199
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
   327
def getrepophid(repo):
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
   328
    """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
   329
    # 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
   330
    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
   331
    if repophid:
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
   332
        return repophid
38392
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38336
diff changeset
   333
    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
   334
    if not callsign:
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
   335
        return None
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   336
    query = callconduit(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   337
        repo.ui,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   338
        b'diffusion.repository.search',
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   339
        {b'constraints': {b'callsigns': [callsign]}},
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   340
    )
41897
c340a8ac7ef3 phabricator: convert conduit response JSON unicode to bytes inside callconduit
Ian Moody <moz-ian@perix.co.uk>
parents: 41705
diff changeset
   341
    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
   342
        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
   343
    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
   344
    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
   345
    return repophid
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
   346
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   347
41532
bd3f03d8cc9f global: use raw strings for regular expressions with escapes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 41365
diff changeset
   348
_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
   349
_differentialrevisiondescre = re.compile(
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   350
    br'^Differential Revision:\s*(?P<url>(?:.*)D(?P<id>[1-9][0-9]*))$', re.M
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   351
)
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   352
33199
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
   353
33442
3ab0d5767b54 phabricator: finding old nodes in batch
Jun Wu <quark@fb.com>
parents: 33441
diff changeset
   354
def getoldnodedrevmap(repo, nodelist):
3ab0d5767b54 phabricator: finding old nodes in batch
Jun Wu <quark@fb.com>
parents: 33441
diff changeset
   355
    """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
   356
33691
1664406a44d9 phabricator: use Phabricator's last node information
Jun Wu <quark@fb.com>
parents: 33690
diff changeset
   357
    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
   358
    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
   359
    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
   360
    be ``None``.
33199
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
   361
33691
1664406a44d9 phabricator: use Phabricator's last node information
Jun Wu <quark@fb.com>
parents: 33690
diff changeset
   362
    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
   363
    association information.
33263
ed61189763ef phabricator: check associated Differential Revision from commit message
Jun Wu <quark@fb.com>
parents: 33200
diff changeset
   364
33691
1664406a44d9 phabricator: use Phabricator's last node information
Jun Wu <quark@fb.com>
parents: 33690
diff changeset
   365
    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
   366
    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
   367
    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
   368
1664406a44d9 phabricator: use Phabricator's last node information
Jun Wu <quark@fb.com>
parents: 33690
diff changeset
   369
    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
   370
    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
   371
    """
33442
3ab0d5767b54 phabricator: finding old nodes in batch
Jun Wu <quark@fb.com>
parents: 33441
diff changeset
   372
    unfi = repo.unfiltered()
33199
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
   373
    nodemap = unfi.changelog.nodemap
33263
ed61189763ef phabricator: check associated Differential Revision from commit message
Jun Wu <quark@fb.com>
parents: 33200
diff changeset
   374
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   375
    result = {}  # {node: (oldnode?, lastdiff?, drev)}
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   376
    toconfirm = {}  # {node: (force, {precnode}, drev)}
33442
3ab0d5767b54 phabricator: finding old nodes in batch
Jun Wu <quark@fb.com>
parents: 33441
diff changeset
   377
    for node in nodelist:
3ab0d5767b54 phabricator: finding old nodes in batch
Jun Wu <quark@fb.com>
parents: 33441
diff changeset
   378
        ctx = unfi[node]
33443
e48082e0a8d5 phabricator: verify local tags before trusting them
Jun Wu <quark@fb.com>
parents: 33442
diff changeset
   379
        # 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
   380
        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
   381
        for n in precnodes:
33442
3ab0d5767b54 phabricator: finding old nodes in batch
Jun Wu <quark@fb.com>
parents: 33441
diff changeset
   382
            if n in nodemap:
3ab0d5767b54 phabricator: finding old nodes in batch
Jun Wu <quark@fb.com>
parents: 33441
diff changeset
   383
                for tag in unfi.nodetags(n):
3ab0d5767b54 phabricator: finding old nodes in batch
Jun Wu <quark@fb.com>
parents: 33441
diff changeset
   384
                    m = _differentialrevisiontagre.match(tag)
3ab0d5767b54 phabricator: finding old nodes in batch
Jun Wu <quark@fb.com>
parents: 33441
diff changeset
   385
                    if m:
33691
1664406a44d9 phabricator: use Phabricator's last node information
Jun Wu <quark@fb.com>
parents: 33690
diff changeset
   386
                        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
   387
                        continue
33263
ed61189763ef phabricator: check associated Differential Revision from commit message
Jun Wu <quark@fb.com>
parents: 33200
diff changeset
   388
33691
1664406a44d9 phabricator: use Phabricator's last node information
Jun Wu <quark@fb.com>
parents: 33690
diff changeset
   389
        # Check commit message
33442
3ab0d5767b54 phabricator: finding old nodes in batch
Jun Wu <quark@fb.com>
parents: 33441
diff changeset
   390
        m = _differentialrevisiondescre.search(ctx.description())
3ab0d5767b54 phabricator: finding old nodes in batch
Jun Wu <quark@fb.com>
parents: 33441
diff changeset
   391
        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
   392
            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
   393
33443
e48082e0a8d5 phabricator: verify local tags before trusting them
Jun Wu <quark@fb.com>
parents: 33442
diff changeset
   394
    # 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
   395
    # Phabricator, and expect precursors overlap with it.
e48082e0a8d5 phabricator: verify local tags before trusting them
Jun Wu <quark@fb.com>
parents: 33442
diff changeset
   396
    if toconfirm:
33691
1664406a44d9 phabricator: use Phabricator's last node information
Jun Wu <quark@fb.com>
parents: 33690
diff changeset
   397
        drevs = [drev for force, precs, drev in toconfirm.values()]
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   398
        alldiffs = callconduit(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   399
            unfi.ui, b'differential.querydiffs', {b'revisionIDs': drevs}
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   400
        )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   401
        getnode = lambda d: bin(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
   402
        for newnode, (force, precset, drev) in toconfirm.items():
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   403
            diffs = [
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   404
                d for d in alldiffs.values() if int(d[b'revisionID']) == drev
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   405
            ]
33691
1664406a44d9 phabricator: use Phabricator's last node information
Jun Wu <quark@fb.com>
parents: 33690
diff changeset
   406
1664406a44d9 phabricator: use Phabricator's last node information
Jun Wu <quark@fb.com>
parents: 33690
diff changeset
   407
            # "precursors" as known by Phabricator
1664406a44d9 phabricator: use Phabricator's last node information
Jun Wu <quark@fb.com>
parents: 33690
diff changeset
   408
            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
   409
1664406a44d9 phabricator: use Phabricator's last node information
Jun Wu <quark@fb.com>
parents: 33690
diff changeset
   410
            # 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
   411
            # 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
   412
            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
   413
                tagname = b'D%d' % drev
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   414
                tags.tag(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   415
                    repo,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   416
                    tagname,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   417
                    nullid,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   418
                    message=None,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   419
                    user=None,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   420
                    date=None,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   421
                    local=True,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   422
                )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   423
                unfi.ui.warn(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   424
                    _(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   425
                        b'D%s: local tag removed - does not match '
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   426
                        b'Differential history\n'
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   427
                    )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   428
                    % drev
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   429
                )
33691
1664406a44d9 phabricator: use Phabricator's last node information
Jun Wu <quark@fb.com>
parents: 33690
diff changeset
   430
                continue
1664406a44d9 phabricator: use Phabricator's last node information
Jun Wu <quark@fb.com>
parents: 33690
diff changeset
   431
1664406a44d9 phabricator: use Phabricator's last node information
Jun Wu <quark@fb.com>
parents: 33690
diff changeset
   432
            # 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
   433
            # exists in the repo
1664406a44d9 phabricator: use Phabricator's last node information
Jun Wu <quark@fb.com>
parents: 33690
diff changeset
   434
            oldnode = lastdiff = None
1664406a44d9 phabricator: use Phabricator's last node information
Jun Wu <quark@fb.com>
parents: 33690
diff changeset
   435
            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
   436
                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
   437
                oldnode = getnode(lastdiff)
1664406a44d9 phabricator: use Phabricator's last node information
Jun Wu <quark@fb.com>
parents: 33690
diff changeset
   438
                if oldnode and oldnode not in nodemap:
1664406a44d9 phabricator: use Phabricator's last node information
Jun Wu <quark@fb.com>
parents: 33690
diff changeset
   439
                    oldnode = None
1664406a44d9 phabricator: use Phabricator's last node information
Jun Wu <quark@fb.com>
parents: 33690
diff changeset
   440
1664406a44d9 phabricator: use Phabricator's last node information
Jun Wu <quark@fb.com>
parents: 33690
diff changeset
   441
            result[newnode] = (oldnode, lastdiff, drev)
33443
e48082e0a8d5 phabricator: verify local tags before trusting them
Jun Wu <quark@fb.com>
parents: 33442
diff changeset
   442
33442
3ab0d5767b54 phabricator: finding old nodes in batch
Jun Wu <quark@fb.com>
parents: 33441
diff changeset
   443
    return result
33199
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
   444
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   445
33199
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
   446
def getdiff(ctx, diffopts):
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
   447
    """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
   448
    output = util.stringio()
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   449
    for chunk, _label in patch.diffui(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   450
        ctx.repo(), ctx.p1().node(), ctx.node(), None, opts=diffopts
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   451
    ):
33199
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
   452
        output.write(chunk)
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
   453
    return output.getvalue()
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
   454
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   455
43182
a66e2844b0c6 phabricator: add the DiffChangeType and DiffFileType constants
Ian Moody <moz-ian@perix.co.uk>
parents: 43117
diff changeset
   456
class DiffChangeType(object):
a66e2844b0c6 phabricator: add the DiffChangeType and DiffFileType constants
Ian Moody <moz-ian@perix.co.uk>
parents: 43117
diff changeset
   457
    ADD = 1
a66e2844b0c6 phabricator: add the DiffChangeType and DiffFileType constants
Ian Moody <moz-ian@perix.co.uk>
parents: 43117
diff changeset
   458
    CHANGE = 2
a66e2844b0c6 phabricator: add the DiffChangeType and DiffFileType constants
Ian Moody <moz-ian@perix.co.uk>
parents: 43117
diff changeset
   459
    DELETE = 3
a66e2844b0c6 phabricator: add the DiffChangeType and DiffFileType constants
Ian Moody <moz-ian@perix.co.uk>
parents: 43117
diff changeset
   460
    MOVE_AWAY = 4
a66e2844b0c6 phabricator: add the DiffChangeType and DiffFileType constants
Ian Moody <moz-ian@perix.co.uk>
parents: 43117
diff changeset
   461
    COPY_AWAY = 5
a66e2844b0c6 phabricator: add the DiffChangeType and DiffFileType constants
Ian Moody <moz-ian@perix.co.uk>
parents: 43117
diff changeset
   462
    MOVE_HERE = 6
a66e2844b0c6 phabricator: add the DiffChangeType and DiffFileType constants
Ian Moody <moz-ian@perix.co.uk>
parents: 43117
diff changeset
   463
    COPY_HERE = 7
a66e2844b0c6 phabricator: add the DiffChangeType and DiffFileType constants
Ian Moody <moz-ian@perix.co.uk>
parents: 43117
diff changeset
   464
    MULTICOPY = 8
a66e2844b0c6 phabricator: add the DiffChangeType and DiffFileType constants
Ian Moody <moz-ian@perix.co.uk>
parents: 43117
diff changeset
   465
a66e2844b0c6 phabricator: add the DiffChangeType and DiffFileType constants
Ian Moody <moz-ian@perix.co.uk>
parents: 43117
diff changeset
   466
a66e2844b0c6 phabricator: add the DiffChangeType and DiffFileType constants
Ian Moody <moz-ian@perix.co.uk>
parents: 43117
diff changeset
   467
class DiffFileType(object):
a66e2844b0c6 phabricator: add the DiffChangeType and DiffFileType constants
Ian Moody <moz-ian@perix.co.uk>
parents: 43117
diff changeset
   468
    TEXT = 1
a66e2844b0c6 phabricator: add the DiffChangeType and DiffFileType constants
Ian Moody <moz-ian@perix.co.uk>
parents: 43117
diff changeset
   469
    IMAGE = 2
a66e2844b0c6 phabricator: add the DiffChangeType and DiffFileType constants
Ian Moody <moz-ian@perix.co.uk>
parents: 43117
diff changeset
   470
    BINARY = 3
a66e2844b0c6 phabricator: add the DiffChangeType and DiffFileType constants
Ian Moody <moz-ian@perix.co.uk>
parents: 43117
diff changeset
   471
a66e2844b0c6 phabricator: add the DiffChangeType and DiffFileType constants
Ian Moody <moz-ian@perix.co.uk>
parents: 43117
diff changeset
   472
43183
73d4bc60e389 phabricator: add the phabhunk data structure
Ian Moody <moz-ian@perix.co.uk>
parents: 43182
diff changeset
   473
@attr.s
73d4bc60e389 phabricator: add the phabhunk data structure
Ian Moody <moz-ian@perix.co.uk>
parents: 43182
diff changeset
   474
class phabhunk(dict):
73d4bc60e389 phabricator: add the phabhunk data structure
Ian Moody <moz-ian@perix.co.uk>
parents: 43182
diff changeset
   475
    """Represents a Differential hunk, which is owned by a Differential change
73d4bc60e389 phabricator: add the phabhunk data structure
Ian Moody <moz-ian@perix.co.uk>
parents: 43182
diff changeset
   476
    """
73d4bc60e389 phabricator: add the phabhunk data structure
Ian Moody <moz-ian@perix.co.uk>
parents: 43182
diff changeset
   477
73d4bc60e389 phabricator: add the phabhunk data structure
Ian Moody <moz-ian@perix.co.uk>
parents: 43182
diff changeset
   478
    oldOffset = attr.ib(default=0)  # camelcase-required
73d4bc60e389 phabricator: add the phabhunk data structure
Ian Moody <moz-ian@perix.co.uk>
parents: 43182
diff changeset
   479
    oldLength = attr.ib(default=0)  # camelcase-required
73d4bc60e389 phabricator: add the phabhunk data structure
Ian Moody <moz-ian@perix.co.uk>
parents: 43182
diff changeset
   480
    newOffset = attr.ib(default=0)  # camelcase-required
73d4bc60e389 phabricator: add the phabhunk data structure
Ian Moody <moz-ian@perix.co.uk>
parents: 43182
diff changeset
   481
    newLength = attr.ib(default=0)  # camelcase-required
73d4bc60e389 phabricator: add the phabhunk data structure
Ian Moody <moz-ian@perix.co.uk>
parents: 43182
diff changeset
   482
    corpus = attr.ib(default='')
73d4bc60e389 phabricator: add the phabhunk data structure
Ian Moody <moz-ian@perix.co.uk>
parents: 43182
diff changeset
   483
    # These get added to the phabchange's equivalents
73d4bc60e389 phabricator: add the phabhunk data structure
Ian Moody <moz-ian@perix.co.uk>
parents: 43182
diff changeset
   484
    addLines = attr.ib(default=0)  # camelcase-required
73d4bc60e389 phabricator: add the phabhunk data structure
Ian Moody <moz-ian@perix.co.uk>
parents: 43182
diff changeset
   485
    delLines = attr.ib(default=0)  # camelcase-required
73d4bc60e389 phabricator: add the phabhunk data structure
Ian Moody <moz-ian@perix.co.uk>
parents: 43182
diff changeset
   486
73d4bc60e389 phabricator: add the phabhunk data structure
Ian Moody <moz-ian@perix.co.uk>
parents: 43182
diff changeset
   487
43184
99ee4afd352f phabricator: add the phabchange data structure
Ian Moody <moz-ian@perix.co.uk>
parents: 43183
diff changeset
   488
@attr.s
99ee4afd352f phabricator: add the phabchange data structure
Ian Moody <moz-ian@perix.co.uk>
parents: 43183
diff changeset
   489
class phabchange(object):
99ee4afd352f phabricator: add the phabchange data structure
Ian Moody <moz-ian@perix.co.uk>
parents: 43183
diff changeset
   490
    """Represents a Differential change, owns Differential hunks and owned by a
99ee4afd352f phabricator: add the phabchange data structure
Ian Moody <moz-ian@perix.co.uk>
parents: 43183
diff changeset
   491
    Differential diff.  Each one represents one file in a diff.
99ee4afd352f phabricator: add the phabchange data structure
Ian Moody <moz-ian@perix.co.uk>
parents: 43183
diff changeset
   492
    """
99ee4afd352f phabricator: add the phabchange data structure
Ian Moody <moz-ian@perix.co.uk>
parents: 43183
diff changeset
   493
99ee4afd352f phabricator: add the phabchange data structure
Ian Moody <moz-ian@perix.co.uk>
parents: 43183
diff changeset
   494
    currentPath = attr.ib(default=None)  # camelcase-required
99ee4afd352f phabricator: add the phabchange data structure
Ian Moody <moz-ian@perix.co.uk>
parents: 43183
diff changeset
   495
    oldPath = attr.ib(default=None)  # camelcase-required
99ee4afd352f phabricator: add the phabchange data structure
Ian Moody <moz-ian@perix.co.uk>
parents: 43183
diff changeset
   496
    awayPaths = attr.ib(default=attr.Factory(list))  # camelcase-required
99ee4afd352f phabricator: add the phabchange data structure
Ian Moody <moz-ian@perix.co.uk>
parents: 43183
diff changeset
   497
    metadata = attr.ib(default=attr.Factory(dict))
99ee4afd352f phabricator: add the phabchange data structure
Ian Moody <moz-ian@perix.co.uk>
parents: 43183
diff changeset
   498
    oldProperties = attr.ib(default=attr.Factory(dict))  # camelcase-required
99ee4afd352f phabricator: add the phabchange data structure
Ian Moody <moz-ian@perix.co.uk>
parents: 43183
diff changeset
   499
    newProperties = attr.ib(default=attr.Factory(dict))  # camelcase-required
99ee4afd352f phabricator: add the phabchange data structure
Ian Moody <moz-ian@perix.co.uk>
parents: 43183
diff changeset
   500
    type = attr.ib(default=DiffChangeType.CHANGE)
99ee4afd352f phabricator: add the phabchange data structure
Ian Moody <moz-ian@perix.co.uk>
parents: 43183
diff changeset
   501
    fileType = attr.ib(default=DiffFileType.TEXT)  # camelcase-required
99ee4afd352f phabricator: add the phabchange data structure
Ian Moody <moz-ian@perix.co.uk>
parents: 43183
diff changeset
   502
    commitHash = attr.ib(default=None)  # camelcase-required
99ee4afd352f phabricator: add the phabchange data structure
Ian Moody <moz-ian@perix.co.uk>
parents: 43183
diff changeset
   503
    addLines = attr.ib(default=0)  # camelcase-required
99ee4afd352f phabricator: add the phabchange data structure
Ian Moody <moz-ian@perix.co.uk>
parents: 43183
diff changeset
   504
    delLines = attr.ib(default=0)  # camelcase-required
99ee4afd352f phabricator: add the phabchange data structure
Ian Moody <moz-ian@perix.co.uk>
parents: 43183
diff changeset
   505
    hunks = attr.ib(default=attr.Factory(list))
99ee4afd352f phabricator: add the phabchange data structure
Ian Moody <moz-ian@perix.co.uk>
parents: 43183
diff changeset
   506
99ee4afd352f phabricator: add the phabchange data structure
Ian Moody <moz-ian@perix.co.uk>
parents: 43183
diff changeset
   507
    def copynewmetadatatoold(self):
99ee4afd352f phabricator: add the phabchange data structure
Ian Moody <moz-ian@perix.co.uk>
parents: 43183
diff changeset
   508
        for key in list(self.metadata.keys()):
99ee4afd352f phabricator: add the phabchange data structure
Ian Moody <moz-ian@perix.co.uk>
parents: 43183
diff changeset
   509
            newkey = key.replace(b'new:', b'old:')
99ee4afd352f phabricator: add the phabchange data structure
Ian Moody <moz-ian@perix.co.uk>
parents: 43183
diff changeset
   510
            self.metadata[newkey] = self.metadata[key]
99ee4afd352f phabricator: add the phabchange data structure
Ian Moody <moz-ian@perix.co.uk>
parents: 43183
diff changeset
   511
99ee4afd352f phabricator: add the phabchange data structure
Ian Moody <moz-ian@perix.co.uk>
parents: 43183
diff changeset
   512
    def addoldmode(self, value):
99ee4afd352f phabricator: add the phabchange data structure
Ian Moody <moz-ian@perix.co.uk>
parents: 43183
diff changeset
   513
        self.oldProperties[b'unix:filemode'] = value
99ee4afd352f phabricator: add the phabchange data structure
Ian Moody <moz-ian@perix.co.uk>
parents: 43183
diff changeset
   514
99ee4afd352f phabricator: add the phabchange data structure
Ian Moody <moz-ian@perix.co.uk>
parents: 43183
diff changeset
   515
    def addnewmode(self, value):
99ee4afd352f phabricator: add the phabchange data structure
Ian Moody <moz-ian@perix.co.uk>
parents: 43183
diff changeset
   516
        self.newProperties[b'unix:filemode'] = value
99ee4afd352f phabricator: add the phabchange data structure
Ian Moody <moz-ian@perix.co.uk>
parents: 43183
diff changeset
   517
99ee4afd352f phabricator: add the phabchange data structure
Ian Moody <moz-ian@perix.co.uk>
parents: 43183
diff changeset
   518
    def addhunk(self, hunk):
99ee4afd352f phabricator: add the phabchange data structure
Ian Moody <moz-ian@perix.co.uk>
parents: 43183
diff changeset
   519
        if not isinstance(hunk, phabhunk):
99ee4afd352f phabricator: add the phabchange data structure
Ian Moody <moz-ian@perix.co.uk>
parents: 43183
diff changeset
   520
            raise error.Abort(b'phabchange.addhunk only takes phabhunks')
99ee4afd352f phabricator: add the phabchange data structure
Ian Moody <moz-ian@perix.co.uk>
parents: 43183
diff changeset
   521
        self.hunks.append(hunk)
99ee4afd352f phabricator: add the phabchange data structure
Ian Moody <moz-ian@perix.co.uk>
parents: 43183
diff changeset
   522
        # It's useful to include these stats since the Phab web UI shows them,
99ee4afd352f phabricator: add the phabchange data structure
Ian Moody <moz-ian@perix.co.uk>
parents: 43183
diff changeset
   523
        # and uses them to estimate how large a change a Revision is. Also used
99ee4afd352f phabricator: add the phabchange data structure
Ian Moody <moz-ian@perix.co.uk>
parents: 43183
diff changeset
   524
        # in email subjects for the [+++--] bit.
99ee4afd352f phabricator: add the phabchange data structure
Ian Moody <moz-ian@perix.co.uk>
parents: 43183
diff changeset
   525
        self.addLines += hunk.addLines
99ee4afd352f phabricator: add the phabchange data structure
Ian Moody <moz-ian@perix.co.uk>
parents: 43183
diff changeset
   526
        self.delLines += hunk.delLines
99ee4afd352f phabricator: add the phabchange data structure
Ian Moody <moz-ian@perix.co.uk>
parents: 43183
diff changeset
   527
99ee4afd352f phabricator: add the phabchange data structure
Ian Moody <moz-ian@perix.co.uk>
parents: 43183
diff changeset
   528
43185
75e7628b488f phabricator: add the phabdiff data structure
Ian Moody <moz-ian@perix.co.uk>
parents: 43184
diff changeset
   529
@attr.s
75e7628b488f phabricator: add the phabdiff data structure
Ian Moody <moz-ian@perix.co.uk>
parents: 43184
diff changeset
   530
class phabdiff(object):
75e7628b488f phabricator: add the phabdiff data structure
Ian Moody <moz-ian@perix.co.uk>
parents: 43184
diff changeset
   531
    """Represents a Differential diff, owns Differential changes.  Corresponds
75e7628b488f phabricator: add the phabdiff data structure
Ian Moody <moz-ian@perix.co.uk>
parents: 43184
diff changeset
   532
    to a commit.
75e7628b488f phabricator: add the phabdiff data structure
Ian Moody <moz-ian@perix.co.uk>
parents: 43184
diff changeset
   533
    """
75e7628b488f phabricator: add the phabdiff data structure
Ian Moody <moz-ian@perix.co.uk>
parents: 43184
diff changeset
   534
75e7628b488f phabricator: add the phabdiff data structure
Ian Moody <moz-ian@perix.co.uk>
parents: 43184
diff changeset
   535
    # Doesn't seem to be any reason to send this (output of uname -n)
75e7628b488f phabricator: add the phabdiff data structure
Ian Moody <moz-ian@perix.co.uk>
parents: 43184
diff changeset
   536
    sourceMachine = attr.ib(default=b'')  # camelcase-required
75e7628b488f phabricator: add the phabdiff data structure
Ian Moody <moz-ian@perix.co.uk>
parents: 43184
diff changeset
   537
    sourcePath = attr.ib(default=b'/')  # camelcase-required
75e7628b488f phabricator: add the phabdiff data structure
Ian Moody <moz-ian@perix.co.uk>
parents: 43184
diff changeset
   538
    sourceControlBaseRevision = attr.ib(default=b'0' * 40)  # camelcase-required
75e7628b488f phabricator: add the phabdiff data structure
Ian Moody <moz-ian@perix.co.uk>
parents: 43184
diff changeset
   539
    sourceControlPath = attr.ib(default=b'/')  # camelcase-required
75e7628b488f phabricator: add the phabdiff data structure
Ian Moody <moz-ian@perix.co.uk>
parents: 43184
diff changeset
   540
    sourceControlSystem = attr.ib(default=b'hg')  # camelcase-required
75e7628b488f phabricator: add the phabdiff data structure
Ian Moody <moz-ian@perix.co.uk>
parents: 43184
diff changeset
   541
    branch = attr.ib(default=b'default')
75e7628b488f phabricator: add the phabdiff data structure
Ian Moody <moz-ian@perix.co.uk>
parents: 43184
diff changeset
   542
    bookmark = attr.ib(default=None)
75e7628b488f phabricator: add the phabdiff data structure
Ian Moody <moz-ian@perix.co.uk>
parents: 43184
diff changeset
   543
    creationMethod = attr.ib(default=b'phabsend')  # camelcase-required
75e7628b488f phabricator: add the phabdiff data structure
Ian Moody <moz-ian@perix.co.uk>
parents: 43184
diff changeset
   544
    lintStatus = attr.ib(default=b'none')  # camelcase-required
75e7628b488f phabricator: add the phabdiff data structure
Ian Moody <moz-ian@perix.co.uk>
parents: 43184
diff changeset
   545
    unitStatus = attr.ib(default=b'none')  # camelcase-required
75e7628b488f phabricator: add the phabdiff data structure
Ian Moody <moz-ian@perix.co.uk>
parents: 43184
diff changeset
   546
    changes = attr.ib(default=attr.Factory(dict))
75e7628b488f phabricator: add the phabdiff data structure
Ian Moody <moz-ian@perix.co.uk>
parents: 43184
diff changeset
   547
    repositoryPHID = attr.ib(default=None)  # camelcase-required
75e7628b488f phabricator: add the phabdiff data structure
Ian Moody <moz-ian@perix.co.uk>
parents: 43184
diff changeset
   548
75e7628b488f phabricator: add the phabdiff data structure
Ian Moody <moz-ian@perix.co.uk>
parents: 43184
diff changeset
   549
    def addchange(self, change):
75e7628b488f phabricator: add the phabdiff data structure
Ian Moody <moz-ian@perix.co.uk>
parents: 43184
diff changeset
   550
        if not isinstance(change, phabchange):
75e7628b488f phabricator: add the phabdiff data structure
Ian Moody <moz-ian@perix.co.uk>
parents: 43184
diff changeset
   551
            raise error.Abort(b'phabdiff.addchange only takes phabchanges')
75e7628b488f phabricator: add the phabdiff data structure
Ian Moody <moz-ian@perix.co.uk>
parents: 43184
diff changeset
   552
        self.changes[change.currentPath] = change
75e7628b488f phabricator: add the phabdiff data structure
Ian Moody <moz-ian@perix.co.uk>
parents: 43184
diff changeset
   553
75e7628b488f phabricator: add the phabdiff data structure
Ian Moody <moz-ian@perix.co.uk>
parents: 43184
diff changeset
   554
43186
f742fabad507 phabricator: add the maketext function
Ian Moody <moz-ian@perix.co.uk>
parents: 43185
diff changeset
   555
def maketext(pchange, ctx, fname):
f742fabad507 phabricator: add the maketext function
Ian Moody <moz-ian@perix.co.uk>
parents: 43185
diff changeset
   556
    """populate the phabchange for a text file"""
f742fabad507 phabricator: add the maketext function
Ian Moody <moz-ian@perix.co.uk>
parents: 43185
diff changeset
   557
    repo = ctx.repo()
f742fabad507 phabricator: add the maketext function
Ian Moody <moz-ian@perix.co.uk>
parents: 43185
diff changeset
   558
    fmatcher = match.exact([fname])
f742fabad507 phabricator: add the maketext function
Ian Moody <moz-ian@perix.co.uk>
parents: 43185
diff changeset
   559
    diffopts = mdiff.diffopts(git=True, context=32767)
f742fabad507 phabricator: add the maketext function
Ian Moody <moz-ian@perix.co.uk>
parents: 43185
diff changeset
   560
    _pfctx, _fctx, header, fhunks = next(
f742fabad507 phabricator: add the maketext function
Ian Moody <moz-ian@perix.co.uk>
parents: 43185
diff changeset
   561
        patch.diffhunks(repo, ctx.p1(), ctx, fmatcher, opts=diffopts)
f742fabad507 phabricator: add the maketext function
Ian Moody <moz-ian@perix.co.uk>
parents: 43185
diff changeset
   562
    )
f742fabad507 phabricator: add the maketext function
Ian Moody <moz-ian@perix.co.uk>
parents: 43185
diff changeset
   563
f742fabad507 phabricator: add the maketext function
Ian Moody <moz-ian@perix.co.uk>
parents: 43185
diff changeset
   564
    for fhunk in fhunks:
f742fabad507 phabricator: add the maketext function
Ian Moody <moz-ian@perix.co.uk>
parents: 43185
diff changeset
   565
        (oldOffset, oldLength, newOffset, newLength), lines = fhunk
f742fabad507 phabricator: add the maketext function
Ian Moody <moz-ian@perix.co.uk>
parents: 43185
diff changeset
   566
        corpus = b''.join(lines[1:])
f742fabad507 phabricator: add the maketext function
Ian Moody <moz-ian@perix.co.uk>
parents: 43185
diff changeset
   567
        shunk = list(header)
f742fabad507 phabricator: add the maketext function
Ian Moody <moz-ian@perix.co.uk>
parents: 43185
diff changeset
   568
        shunk.extend(lines)
f742fabad507 phabricator: add the maketext function
Ian Moody <moz-ian@perix.co.uk>
parents: 43185
diff changeset
   569
        _mf, _mt, addLines, delLines, _hb = patch.diffstatsum(
f742fabad507 phabricator: add the maketext function
Ian Moody <moz-ian@perix.co.uk>
parents: 43185
diff changeset
   570
            patch.diffstatdata(util.iterlines(shunk))
f742fabad507 phabricator: add the maketext function
Ian Moody <moz-ian@perix.co.uk>
parents: 43185
diff changeset
   571
        )
f742fabad507 phabricator: add the maketext function
Ian Moody <moz-ian@perix.co.uk>
parents: 43185
diff changeset
   572
        pchange.addhunk(
f742fabad507 phabricator: add the maketext function
Ian Moody <moz-ian@perix.co.uk>
parents: 43185
diff changeset
   573
            phabhunk(
f742fabad507 phabricator: add the maketext function
Ian Moody <moz-ian@perix.co.uk>
parents: 43185
diff changeset
   574
                oldOffset,
f742fabad507 phabricator: add the maketext function
Ian Moody <moz-ian@perix.co.uk>
parents: 43185
diff changeset
   575
                oldLength,
f742fabad507 phabricator: add the maketext function
Ian Moody <moz-ian@perix.co.uk>
parents: 43185
diff changeset
   576
                newOffset,
f742fabad507 phabricator: add the maketext function
Ian Moody <moz-ian@perix.co.uk>
parents: 43185
diff changeset
   577
                newLength,
f742fabad507 phabricator: add the maketext function
Ian Moody <moz-ian@perix.co.uk>
parents: 43185
diff changeset
   578
                corpus,
f742fabad507 phabricator: add the maketext function
Ian Moody <moz-ian@perix.co.uk>
parents: 43185
diff changeset
   579
                addLines,
f742fabad507 phabricator: add the maketext function
Ian Moody <moz-ian@perix.co.uk>
parents: 43185
diff changeset
   580
                delLines,
f742fabad507 phabricator: add the maketext function
Ian Moody <moz-ian@perix.co.uk>
parents: 43185
diff changeset
   581
            )
f742fabad507 phabricator: add the maketext function
Ian Moody <moz-ian@perix.co.uk>
parents: 43185
diff changeset
   582
        )
f742fabad507 phabricator: add the maketext function
Ian Moody <moz-ian@perix.co.uk>
parents: 43185
diff changeset
   583
f742fabad507 phabricator: add the maketext function
Ian Moody <moz-ian@perix.co.uk>
parents: 43185
diff changeset
   584
43187
453079605242 phabricator: add the uploadchunks function
Ian Moody <moz-ian@perix.co.uk>
parents: 43186
diff changeset
   585
def uploadchunks(fctx, fphid):
453079605242 phabricator: add the uploadchunks function
Ian Moody <moz-ian@perix.co.uk>
parents: 43186
diff changeset
   586
    """upload large binary files as separate chunks.
453079605242 phabricator: add the uploadchunks function
Ian Moody <moz-ian@perix.co.uk>
parents: 43186
diff changeset
   587
    Phab requests chunking over 8MiB, and splits into 4MiB chunks
453079605242 phabricator: add the uploadchunks function
Ian Moody <moz-ian@perix.co.uk>
parents: 43186
diff changeset
   588
    """
453079605242 phabricator: add the uploadchunks function
Ian Moody <moz-ian@perix.co.uk>
parents: 43186
diff changeset
   589
    ui = fctx.repo().ui
453079605242 phabricator: add the uploadchunks function
Ian Moody <moz-ian@perix.co.uk>
parents: 43186
diff changeset
   590
    chunks = callconduit(ui, b'file.querychunks', {b'filePHID': fphid})
453079605242 phabricator: add the uploadchunks function
Ian Moody <moz-ian@perix.co.uk>
parents: 43186
diff changeset
   591
    progress = ui.makeprogress(
453079605242 phabricator: add the uploadchunks function
Ian Moody <moz-ian@perix.co.uk>
parents: 43186
diff changeset
   592
        _(b'uploading file chunks'), unit=_(b'chunks'), total=len(chunks)
453079605242 phabricator: add the uploadchunks function
Ian Moody <moz-ian@perix.co.uk>
parents: 43186
diff changeset
   593
    )
453079605242 phabricator: add the uploadchunks function
Ian Moody <moz-ian@perix.co.uk>
parents: 43186
diff changeset
   594
    for chunk in chunks:
453079605242 phabricator: add the uploadchunks function
Ian Moody <moz-ian@perix.co.uk>
parents: 43186
diff changeset
   595
        progress.increment()
453079605242 phabricator: add the uploadchunks function
Ian Moody <moz-ian@perix.co.uk>
parents: 43186
diff changeset
   596
        if chunk[b'complete']:
453079605242 phabricator: add the uploadchunks function
Ian Moody <moz-ian@perix.co.uk>
parents: 43186
diff changeset
   597
            continue
453079605242 phabricator: add the uploadchunks function
Ian Moody <moz-ian@perix.co.uk>
parents: 43186
diff changeset
   598
        bstart = int(chunk[b'byteStart'])
453079605242 phabricator: add the uploadchunks function
Ian Moody <moz-ian@perix.co.uk>
parents: 43186
diff changeset
   599
        bend = int(chunk[b'byteEnd'])
453079605242 phabricator: add the uploadchunks function
Ian Moody <moz-ian@perix.co.uk>
parents: 43186
diff changeset
   600
        callconduit(
453079605242 phabricator: add the uploadchunks function
Ian Moody <moz-ian@perix.co.uk>
parents: 43186
diff changeset
   601
            ui,
453079605242 phabricator: add the uploadchunks function
Ian Moody <moz-ian@perix.co.uk>
parents: 43186
diff changeset
   602
            b'file.uploadchunk',
453079605242 phabricator: add the uploadchunks function
Ian Moody <moz-ian@perix.co.uk>
parents: 43186
diff changeset
   603
            {
453079605242 phabricator: add the uploadchunks function
Ian Moody <moz-ian@perix.co.uk>
parents: 43186
diff changeset
   604
                b'filePHID': fphid,
453079605242 phabricator: add the uploadchunks function
Ian Moody <moz-ian@perix.co.uk>
parents: 43186
diff changeset
   605
                b'byteStart': bstart,
453079605242 phabricator: add the uploadchunks function
Ian Moody <moz-ian@perix.co.uk>
parents: 43186
diff changeset
   606
                b'data': base64.b64encode(fctx.data()[bstart:bend]),
453079605242 phabricator: add the uploadchunks function
Ian Moody <moz-ian@perix.co.uk>
parents: 43186
diff changeset
   607
                b'dataEncoding': b'base64',
453079605242 phabricator: add the uploadchunks function
Ian Moody <moz-ian@perix.co.uk>
parents: 43186
diff changeset
   608
            },
453079605242 phabricator: add the uploadchunks function
Ian Moody <moz-ian@perix.co.uk>
parents: 43186
diff changeset
   609
        )
453079605242 phabricator: add the uploadchunks function
Ian Moody <moz-ian@perix.co.uk>
parents: 43186
diff changeset
   610
    progress.complete()
453079605242 phabricator: add the uploadchunks function
Ian Moody <moz-ian@perix.co.uk>
parents: 43186
diff changeset
   611
453079605242 phabricator: add the uploadchunks function
Ian Moody <moz-ian@perix.co.uk>
parents: 43186
diff changeset
   612
43188
24e8aac7c630 phabricator: add the uploadfile function
Ian Moody <moz-ian@perix.co.uk>
parents: 43187
diff changeset
   613
def uploadfile(fctx):
24e8aac7c630 phabricator: add the uploadfile function
Ian Moody <moz-ian@perix.co.uk>
parents: 43187
diff changeset
   614
    """upload binary files to Phabricator"""
24e8aac7c630 phabricator: add the uploadfile function
Ian Moody <moz-ian@perix.co.uk>
parents: 43187
diff changeset
   615
    repo = fctx.repo()
24e8aac7c630 phabricator: add the uploadfile function
Ian Moody <moz-ian@perix.co.uk>
parents: 43187
diff changeset
   616
    ui = repo.ui
24e8aac7c630 phabricator: add the uploadfile function
Ian Moody <moz-ian@perix.co.uk>
parents: 43187
diff changeset
   617
    fname = fctx.path()
24e8aac7c630 phabricator: add the uploadfile function
Ian Moody <moz-ian@perix.co.uk>
parents: 43187
diff changeset
   618
    size = fctx.size()
24e8aac7c630 phabricator: add the uploadfile function
Ian Moody <moz-ian@perix.co.uk>
parents: 43187
diff changeset
   619
    fhash = pycompat.bytestr(hashlib.sha256(fctx.data()).hexdigest())
24e8aac7c630 phabricator: add the uploadfile function
Ian Moody <moz-ian@perix.co.uk>
parents: 43187
diff changeset
   620
24e8aac7c630 phabricator: add the uploadfile function
Ian Moody <moz-ian@perix.co.uk>
parents: 43187
diff changeset
   621
    # an allocate call is required first to see if an upload is even required
24e8aac7c630 phabricator: add the uploadfile function
Ian Moody <moz-ian@perix.co.uk>
parents: 43187
diff changeset
   622
    # (Phab might already have it) and to determine if chunking is needed
24e8aac7c630 phabricator: add the uploadfile function
Ian Moody <moz-ian@perix.co.uk>
parents: 43187
diff changeset
   623
    allocateparams = {
24e8aac7c630 phabricator: add the uploadfile function
Ian Moody <moz-ian@perix.co.uk>
parents: 43187
diff changeset
   624
        b'name': fname,
24e8aac7c630 phabricator: add the uploadfile function
Ian Moody <moz-ian@perix.co.uk>
parents: 43187
diff changeset
   625
        b'contentLength': size,
24e8aac7c630 phabricator: add the uploadfile function
Ian Moody <moz-ian@perix.co.uk>
parents: 43187
diff changeset
   626
        b'contentHash': fhash,
24e8aac7c630 phabricator: add the uploadfile function
Ian Moody <moz-ian@perix.co.uk>
parents: 43187
diff changeset
   627
    }
24e8aac7c630 phabricator: add the uploadfile function
Ian Moody <moz-ian@perix.co.uk>
parents: 43187
diff changeset
   628
    filealloc = callconduit(ui, b'file.allocate', allocateparams)
24e8aac7c630 phabricator: add the uploadfile function
Ian Moody <moz-ian@perix.co.uk>
parents: 43187
diff changeset
   629
    fphid = filealloc[b'filePHID']
24e8aac7c630 phabricator: add the uploadfile function
Ian Moody <moz-ian@perix.co.uk>
parents: 43187
diff changeset
   630
24e8aac7c630 phabricator: add the uploadfile function
Ian Moody <moz-ian@perix.co.uk>
parents: 43187
diff changeset
   631
    if filealloc[b'upload']:
24e8aac7c630 phabricator: add the uploadfile function
Ian Moody <moz-ian@perix.co.uk>
parents: 43187
diff changeset
   632
        ui.write(_(b'uploading %s\n') % bytes(fctx))
24e8aac7c630 phabricator: add the uploadfile function
Ian Moody <moz-ian@perix.co.uk>
parents: 43187
diff changeset
   633
        if not fphid:
24e8aac7c630 phabricator: add the uploadfile function
Ian Moody <moz-ian@perix.co.uk>
parents: 43187
diff changeset
   634
            uploadparams = {
24e8aac7c630 phabricator: add the uploadfile function
Ian Moody <moz-ian@perix.co.uk>
parents: 43187
diff changeset
   635
                b'name': fname,
24e8aac7c630 phabricator: add the uploadfile function
Ian Moody <moz-ian@perix.co.uk>
parents: 43187
diff changeset
   636
                b'data_base64': base64.b64encode(fctx.data()),
24e8aac7c630 phabricator: add the uploadfile function
Ian Moody <moz-ian@perix.co.uk>
parents: 43187
diff changeset
   637
            }
24e8aac7c630 phabricator: add the uploadfile function
Ian Moody <moz-ian@perix.co.uk>
parents: 43187
diff changeset
   638
            fphid = callconduit(ui, b'file.upload', uploadparams)
24e8aac7c630 phabricator: add the uploadfile function
Ian Moody <moz-ian@perix.co.uk>
parents: 43187
diff changeset
   639
        else:
24e8aac7c630 phabricator: add the uploadfile function
Ian Moody <moz-ian@perix.co.uk>
parents: 43187
diff changeset
   640
            uploadchunks(fctx, fphid)
24e8aac7c630 phabricator: add the uploadfile function
Ian Moody <moz-ian@perix.co.uk>
parents: 43187
diff changeset
   641
    else:
24e8aac7c630 phabricator: add the uploadfile function
Ian Moody <moz-ian@perix.co.uk>
parents: 43187
diff changeset
   642
        ui.debug(b'server already has %s\n' % bytes(fctx))
24e8aac7c630 phabricator: add the uploadfile function
Ian Moody <moz-ian@perix.co.uk>
parents: 43187
diff changeset
   643
24e8aac7c630 phabricator: add the uploadfile function
Ian Moody <moz-ian@perix.co.uk>
parents: 43187
diff changeset
   644
    if not fphid:
24e8aac7c630 phabricator: add the uploadfile function
Ian Moody <moz-ian@perix.co.uk>
parents: 43187
diff changeset
   645
        raise error.Abort(b'Upload of %s failed.' % bytes(fctx))
24e8aac7c630 phabricator: add the uploadfile function
Ian Moody <moz-ian@perix.co.uk>
parents: 43187
diff changeset
   646
24e8aac7c630 phabricator: add the uploadfile function
Ian Moody <moz-ian@perix.co.uk>
parents: 43187
diff changeset
   647
    return fphid
24e8aac7c630 phabricator: add the uploadfile function
Ian Moody <moz-ian@perix.co.uk>
parents: 43187
diff changeset
   648
24e8aac7c630 phabricator: add the uploadfile function
Ian Moody <moz-ian@perix.co.uk>
parents: 43187
diff changeset
   649
43189
9f802243a42e phabricator: add makebinary and addoldbinary functions
Ian Moody <moz-ian@perix.co.uk>
parents: 43188
diff changeset
   650
def addoldbinary(pchange, fctx, originalfname):
9f802243a42e phabricator: add makebinary and addoldbinary functions
Ian Moody <moz-ian@perix.co.uk>
parents: 43188
diff changeset
   651
    """add the metadata for the previous version of a binary file to the
9f802243a42e phabricator: add makebinary and addoldbinary functions
Ian Moody <moz-ian@perix.co.uk>
parents: 43188
diff changeset
   652
    phabchange for the new version
9f802243a42e phabricator: add makebinary and addoldbinary functions
Ian Moody <moz-ian@perix.co.uk>
parents: 43188
diff changeset
   653
    """
9f802243a42e phabricator: add makebinary and addoldbinary functions
Ian Moody <moz-ian@perix.co.uk>
parents: 43188
diff changeset
   654
    oldfctx = fctx.p1()[originalfname]
9f802243a42e phabricator: add makebinary and addoldbinary functions
Ian Moody <moz-ian@perix.co.uk>
parents: 43188
diff changeset
   655
    if fctx.cmp(oldfctx):
9f802243a42e phabricator: add makebinary and addoldbinary functions
Ian Moody <moz-ian@perix.co.uk>
parents: 43188
diff changeset
   656
        # Files differ, add the old one
9f802243a42e phabricator: add makebinary and addoldbinary functions
Ian Moody <moz-ian@perix.co.uk>
parents: 43188
diff changeset
   657
        pchange.metadata[b'old:file:size'] = oldfctx.size()
9f802243a42e phabricator: add makebinary and addoldbinary functions
Ian Moody <moz-ian@perix.co.uk>
parents: 43188
diff changeset
   658
        mimeguess, _enc = mimetypes.guess_type(
9f802243a42e phabricator: add makebinary and addoldbinary functions
Ian Moody <moz-ian@perix.co.uk>
parents: 43188
diff changeset
   659
            encoding.unifromlocal(oldfctx.path())
9f802243a42e phabricator: add makebinary and addoldbinary functions
Ian Moody <moz-ian@perix.co.uk>
parents: 43188
diff changeset
   660
        )
9f802243a42e phabricator: add makebinary and addoldbinary functions
Ian Moody <moz-ian@perix.co.uk>
parents: 43188
diff changeset
   661
        if mimeguess:
9f802243a42e phabricator: add makebinary and addoldbinary functions
Ian Moody <moz-ian@perix.co.uk>
parents: 43188
diff changeset
   662
            pchange.metadata[b'old:file:mime-type'] = pycompat.bytestr(
9f802243a42e phabricator: add makebinary and addoldbinary functions
Ian Moody <moz-ian@perix.co.uk>
parents: 43188
diff changeset
   663
                mimeguess
9f802243a42e phabricator: add makebinary and addoldbinary functions
Ian Moody <moz-ian@perix.co.uk>
parents: 43188
diff changeset
   664
            )
9f802243a42e phabricator: add makebinary and addoldbinary functions
Ian Moody <moz-ian@perix.co.uk>
parents: 43188
diff changeset
   665
        fphid = uploadfile(oldfctx)
9f802243a42e phabricator: add makebinary and addoldbinary functions
Ian Moody <moz-ian@perix.co.uk>
parents: 43188
diff changeset
   666
        pchange.metadata[b'old:binary-phid'] = fphid
9f802243a42e phabricator: add makebinary and addoldbinary functions
Ian Moody <moz-ian@perix.co.uk>
parents: 43188
diff changeset
   667
    else:
9f802243a42e phabricator: add makebinary and addoldbinary functions
Ian Moody <moz-ian@perix.co.uk>
parents: 43188
diff changeset
   668
        # If it's left as IMAGE/BINARY web UI might try to display it
9f802243a42e phabricator: add makebinary and addoldbinary functions
Ian Moody <moz-ian@perix.co.uk>
parents: 43188
diff changeset
   669
        pchange.fileType = DiffFileType.TEXT
9f802243a42e phabricator: add makebinary and addoldbinary functions
Ian Moody <moz-ian@perix.co.uk>
parents: 43188
diff changeset
   670
        pchange.copynewmetadatatoold()
9f802243a42e phabricator: add makebinary and addoldbinary functions
Ian Moody <moz-ian@perix.co.uk>
parents: 43188
diff changeset
   671
9f802243a42e phabricator: add makebinary and addoldbinary functions
Ian Moody <moz-ian@perix.co.uk>
parents: 43188
diff changeset
   672
9f802243a42e phabricator: add makebinary and addoldbinary functions
Ian Moody <moz-ian@perix.co.uk>
parents: 43188
diff changeset
   673
def makebinary(pchange, fctx):
9f802243a42e phabricator: add makebinary and addoldbinary functions
Ian Moody <moz-ian@perix.co.uk>
parents: 43188
diff changeset
   674
    """populate the phabchange for a binary file"""
9f802243a42e phabricator: add makebinary and addoldbinary functions
Ian Moody <moz-ian@perix.co.uk>
parents: 43188
diff changeset
   675
    pchange.fileType = DiffFileType.BINARY
9f802243a42e phabricator: add makebinary and addoldbinary functions
Ian Moody <moz-ian@perix.co.uk>
parents: 43188
diff changeset
   676
    fphid = uploadfile(fctx)
9f802243a42e phabricator: add makebinary and addoldbinary functions
Ian Moody <moz-ian@perix.co.uk>
parents: 43188
diff changeset
   677
    pchange.metadata[b'new:binary-phid'] = fphid
9f802243a42e phabricator: add makebinary and addoldbinary functions
Ian Moody <moz-ian@perix.co.uk>
parents: 43188
diff changeset
   678
    pchange.metadata[b'new:file:size'] = fctx.size()
9f802243a42e phabricator: add makebinary and addoldbinary functions
Ian Moody <moz-ian@perix.co.uk>
parents: 43188
diff changeset
   679
    mimeguess, _enc = mimetypes.guess_type(encoding.unifromlocal(fctx.path()))
9f802243a42e phabricator: add makebinary and addoldbinary functions
Ian Moody <moz-ian@perix.co.uk>
parents: 43188
diff changeset
   680
    if mimeguess:
9f802243a42e phabricator: add makebinary and addoldbinary functions
Ian Moody <moz-ian@perix.co.uk>
parents: 43188
diff changeset
   681
        mimeguess = pycompat.bytestr(mimeguess)
9f802243a42e phabricator: add makebinary and addoldbinary functions
Ian Moody <moz-ian@perix.co.uk>
parents: 43188
diff changeset
   682
        pchange.metadata[b'new:file:mime-type'] = mimeguess
9f802243a42e phabricator: add makebinary and addoldbinary functions
Ian Moody <moz-ian@perix.co.uk>
parents: 43188
diff changeset
   683
        if mimeguess.startswith(b'image/'):
9f802243a42e phabricator: add makebinary and addoldbinary functions
Ian Moody <moz-ian@perix.co.uk>
parents: 43188
diff changeset
   684
            pchange.fileType = DiffFileType.IMAGE
9f802243a42e phabricator: add makebinary and addoldbinary functions
Ian Moody <moz-ian@perix.co.uk>
parents: 43188
diff changeset
   685
9f802243a42e phabricator: add makebinary and addoldbinary functions
Ian Moody <moz-ian@perix.co.uk>
parents: 43188
diff changeset
   686
33199
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
   687
def creatediff(ctx):
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
   688
    """create a Differential Diff"""
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
   689
    repo = ctx.repo()
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
   690
    repophid = getrepophid(repo)
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
   691
    # 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
   692
    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
   693
    if repophid:
38392
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38336
diff changeset
   694
        params[b'repositoryPHID'] = repophid
42434
f163e2b2594c phabricator: pass ui instead of repo to callconduit
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42433
diff changeset
   695
    diff = callconduit(repo.ui, b'differential.createrawdiff', params)
33199
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
   696
    if not diff:
38392
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38336
diff changeset
   697
        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
   698
    return diff
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
   699
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   700
33199
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
   701
def writediffproperties(ctx, diff):
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
   702
    """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
   703
    params = {
41897
c340a8ac7ef3 phabricator: convert conduit response JSON unicode to bytes inside callconduit
Ian Moody <moz-ian@perix.co.uk>
parents: 41705
diff changeset
   704
        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
   705
        b'name': b'hg:meta',
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   706
        b'data': templatefilters.json(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   707
            {
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   708
                b'user': ctx.user(),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   709
                b'date': b'%d %d' % ctx.date(),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   710
                b'branch': ctx.branch(),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   711
                b'node': ctx.hex(),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   712
                b'parent': ctx.p1().hex(),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   713
            }
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   714
        ),
33199
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
   715
    }
42434
f163e2b2594c phabricator: pass ui instead of repo to callconduit
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42433
diff changeset
   716
    callconduit(ctx.repo().ui, b'differential.setdiffproperty', params)
33199
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
   717
37800
6cf5f5b4eb57 phabricator: specify some metadata compatibly with arc
Tom Prince <mozilla@hocat.ca>
parents: 37120
diff changeset
   718
    params = {
41897
c340a8ac7ef3 phabricator: convert conduit response JSON unicode to bytes inside callconduit
Ian Moody <moz-ian@perix.co.uk>
parents: 41705
diff changeset
   719
        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
   720
        b'name': b'local:commits',
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   721
        b'data': templatefilters.json(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   722
            {
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   723
                ctx.hex(): {
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   724
                    b'author': stringutil.person(ctx.user()),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   725
                    b'authorEmail': stringutil.email(ctx.user()),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   726
                    b'time': int(ctx.date()[0]),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   727
                    b'commit': ctx.hex(),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   728
                    b'parents': [ctx.p1().hex()],
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   729
                    b'branch': ctx.branch(),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   730
                },
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   731
            }
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   732
        ),
37800
6cf5f5b4eb57 phabricator: specify some metadata compatibly with arc
Tom Prince <mozilla@hocat.ca>
parents: 37120
diff changeset
   733
    }
42434
f163e2b2594c phabricator: pass ui instead of repo to callconduit
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42433
diff changeset
   734
    callconduit(ctx.repo().ui, b'differential.setdiffproperty', params)
37800
6cf5f5b4eb57 phabricator: specify some metadata compatibly with arc
Tom Prince <mozilla@hocat.ca>
parents: 37120
diff changeset
   735
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   736
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   737
def createdifferentialrevision(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   738
    ctx,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   739
    revid=None,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   740
    parentrevphid=None,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   741
    oldnode=None,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   742
    olddiff=None,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   743
    actions=None,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   744
    comment=None,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   745
):
33199
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
   746
    """create or update a Differential Revision
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
   747
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
   748
    If revid is None, create a new Differential Revision, otherwise update
42449
c19d259fd6ad phabricator: use parents.set to always set dependencies
Ian Moody <moz-ian@perix.co.uk>
parents: 42444
diff changeset
   749
    revid. If parentrevphid 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
   750
95f658b558a3 phabricator: do not upload new diff if nothing changes
Jun Wu <quark@fb.com>
parents: 33264
diff changeset
   751
    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
   752
    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
   753
b7a75b9a3386 phabricator: allow specifying reviewers on phabsend
Jun Wu <quark@fb.com>
parents: 33443
diff changeset
   754
    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
   755
    """
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
   756
    repo = ctx.repo()
33265
95f658b558a3 phabricator: do not upload new diff if nothing changes
Jun Wu <quark@fb.com>
parents: 33264
diff changeset
   757
    if oldnode:
33976
27ff2a87d8c0 phabsend: detect patch change with larger context
Jun Wu <quark@fb.com>
parents: 33975
diff changeset
   758
        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
   759
        oldctx = repo.unfiltered()[oldnode]
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   760
        neednewdiff = getdiff(ctx, diffopts) != getdiff(oldctx, diffopts)
33265
95f658b558a3 phabricator: do not upload new diff if nothing changes
Jun Wu <quark@fb.com>
parents: 33264
diff changeset
   761
    else:
95f658b558a3 phabricator: do not upload new diff if nothing changes
Jun Wu <quark@fb.com>
parents: 33264
diff changeset
   762
        neednewdiff = True
33199
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
   763
33265
95f658b558a3 phabricator: do not upload new diff if nothing changes
Jun Wu <quark@fb.com>
parents: 33264
diff changeset
   764
    transactions = []
95f658b558a3 phabricator: do not upload new diff if nothing changes
Jun Wu <quark@fb.com>
parents: 33264
diff changeset
   765
    if neednewdiff:
95f658b558a3 phabricator: do not upload new diff if nothing changes
Jun Wu <quark@fb.com>
parents: 33264
diff changeset
   766
        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
   767
        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
   768
        if comment:
29528c4235a1 phabricator: add commenting to phabsend for new/updated Diffs
Ian Moody <moz-ian@perix.co.uk>
parents: 42268
diff changeset
   769
            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
   770
    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
   771
        # 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
   772
        # 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
   773
        # 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
   774
        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
   775
        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
   776
    writediffproperties(ctx, diff)
33199
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
   777
42449
c19d259fd6ad phabricator: use parents.set to always set dependencies
Ian Moody <moz-ian@perix.co.uk>
parents: 42444
diff changeset
   778
    # Set the parent Revision every time, so commit re-ordering is picked-up
c19d259fd6ad phabricator: use parents.set to always set dependencies
Ian Moody <moz-ian@perix.co.uk>
parents: 42444
diff changeset
   779
    if parentrevphid:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   780
        transactions.append(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   781
            {b'type': b'parents.set', b'value': [parentrevphid]}
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   782
        )
33199
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
   783
33498
b7a75b9a3386 phabricator: allow specifying reviewers on phabsend
Jun Wu <quark@fb.com>
parents: 33443
diff changeset
   784
    if actions:
b7a75b9a3386 phabricator: allow specifying reviewers on phabsend
Jun Wu <quark@fb.com>
parents: 33443
diff changeset
   785
        transactions += actions
b7a75b9a3386 phabricator: allow specifying reviewers on phabsend
Jun Wu <quark@fb.com>
parents: 33443
diff changeset
   786
33199
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
   787
    # 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
   788
    desc = ctx.description()
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   789
    info = callconduit(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   790
        repo.ui, b'differential.parsecommitmessage', {b'corpus': desc}
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   791
    )
41897
c340a8ac7ef3 phabricator: convert conduit response JSON unicode to bytes inside callconduit
Ian Moody <moz-ian@perix.co.uk>
parents: 41705
diff changeset
   792
    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
   793
        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
   794
            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
   795
38392
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38336
diff changeset
   796
    params = {b'transactions': transactions}
33199
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
   797
    if revid is not None:
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
   798
        # 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
   799
        params[b'objectIdentifier'] = revid
33199
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
   800
42434
f163e2b2594c phabricator: pass ui instead of repo to callconduit
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42433
diff changeset
   801
    revision = callconduit(repo.ui, b'differential.revision.edit', params)
33199
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
   802
    if not revision:
38392
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38336
diff changeset
   803
        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
   804
33787
fa3aa6c98bb7 phabricator: add --amend option to phabsend
Jun Wu <quark@fb.com>
parents: 33785
diff changeset
   805
    return revision, diff
33199
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
   806
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   807
33498
b7a75b9a3386 phabricator: allow specifying reviewers on phabsend
Jun Wu <quark@fb.com>
parents: 33443
diff changeset
   808
def userphids(repo, names):
b7a75b9a3386 phabricator: allow specifying reviewers on phabsend
Jun Wu <quark@fb.com>
parents: 33443
diff changeset
   809
    """convert user names to PHIDs"""
41705
570e62f1dcf2 phabricator: make user searches case-insensitive
Julien Cristau <jcristau@mozilla.com>
parents: 41532
diff changeset
   810
    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
   811
    query = {b'constraints': {b'usernames': names}}
42434
f163e2b2594c phabricator: pass ui instead of repo to callconduit
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42433
diff changeset
   812
    result = callconduit(repo.ui, b'user.search', query)
33498
b7a75b9a3386 phabricator: allow specifying reviewers on phabsend
Jun Wu <quark@fb.com>
parents: 33443
diff changeset
   813
    # 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
   814
    # 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
   815
    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
   816
    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
   817
    unresolved = set(names) - resolved
b7a75b9a3386 phabricator: allow specifying reviewers on phabsend
Jun Wu <quark@fb.com>
parents: 33443
diff changeset
   818
    if unresolved:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   819
        raise error.Abort(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   820
            _(b'unknown username: %s') % b' '.join(sorted(unresolved))
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   821
        )
41897
c340a8ac7ef3 phabricator: convert conduit response JSON unicode to bytes inside callconduit
Ian Moody <moz-ian@perix.co.uk>
parents: 41705
diff changeset
   822
    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
   823
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   824
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   825
@vcrcommand(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   826
    b'phabsend',
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   827
    [
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   828
        (b'r', b'rev', [], _(b'revisions to send'), _(b'REV')),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   829
        (b'', b'amend', True, _(b'update commit messages')),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   830
        (b'', b'reviewer', [], _(b'specify reviewers')),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   831
        (b'', b'blocker', [], _(b'specify blocking reviewers')),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   832
        (
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   833
            b'm',
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   834
            b'comment',
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   835
            b'',
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   836
            _(b'add a comment to Revisions with new/updated Diffs'),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   837
        ),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   838
        (b'', b'confirm', None, _(b'ask for confirmation before sending')),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   839
    ],
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   840
    _(b'REV [OPTIONS]'),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   841
    helpcategory=command.CATEGORY_IMPORT_EXPORT,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   842
)
33199
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
   843
def phabsend(ui, repo, *revs, **opts):
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
   844
    """upload changesets to Phabricator
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
   845
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
   846
    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
   847
    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
   848
    revset.
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
   849
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
   850
    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
   851
    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
   852
    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
   853
    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
   854
33787
fa3aa6c98bb7 phabricator: add --amend option to phabsend
Jun Wu <quark@fb.com>
parents: 33785
diff changeset
   855
    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
   856
    ``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
   857
    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
   858
    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
   859
33690
40cfe3197bc1 phabricator: add --confirm option to phabsend command
Pulkit Goyal <7895pulkit@gmail.com>
parents: 33601
diff changeset
   860
    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
   861
    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
   862
    behaviour::
33690
40cfe3197bc1 phabricator: add --confirm option to phabsend command
Pulkit Goyal <7895pulkit@gmail.com>
parents: 33601
diff changeset
   863
33974
45a8cd74de4e phabsend: polish the docstring a bit
Jun Wu <quark@fb.com>
parents: 33834
diff changeset
   864
        [phabsend]
45a8cd74de4e phabsend: polish the docstring a bit
Jun Wu <quark@fb.com>
parents: 33834
diff changeset
   865
        confirm = true
33787
fa3aa6c98bb7 phabricator: add --amend option to phabsend
Jun Wu <quark@fb.com>
parents: 33785
diff changeset
   866
fa3aa6c98bb7 phabricator: add --amend option to phabsend
Jun Wu <quark@fb.com>
parents: 33785
diff changeset
   867
    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
   868
    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
   869
    """
41970
51ba9fbcca52 py3: use pycompat.byteskwargs on opts in phabricator.py
Ian Moody <moz-ian@perix.co.uk>
parents: 41950
diff changeset
   870
    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
   871
    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
   872
    revs = scmutil.revrange(repo, revs)
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
   873
33266
5b2391b46906 phabricator: abort if phabsend gets empty revs
Jun Wu <quark@fb.com>
parents: 33265
diff changeset
   874
    if not revs:
38392
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38336
diff changeset
   875
        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
   876
    if opts.get(b'amend'):
33787
fa3aa6c98bb7 phabricator: add --amend option to phabsend
Jun Wu <quark@fb.com>
parents: 33785
diff changeset
   877
        cmdutil.checkunfinished(repo)
33266
5b2391b46906 phabricator: abort if phabsend gets empty revs
Jun Wu <quark@fb.com>
parents: 33265
diff changeset
   878
33978
088598153aa2 phabsend: show associated Differential Revisions with --confirm
Jun Wu <quark@fb.com>
parents: 33977
diff changeset
   879
    # {newnode: (oldnode, olddiff, olddrev}
088598153aa2 phabsend: show associated Differential Revisions with --confirm
Jun Wu <quark@fb.com>
parents: 33977
diff changeset
   880
    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
   881
38392
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38336
diff changeset
   882
    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
   883
    confirm |= bool(opts.get(b'confirm'))
33690
40cfe3197bc1 phabricator: add --confirm option to phabsend command
Pulkit Goyal <7895pulkit@gmail.com>
parents: 33601
diff changeset
   884
    if confirm:
33978
088598153aa2 phabsend: show associated Differential Revisions with --confirm
Jun Wu <quark@fb.com>
parents: 33977
diff changeset
   885
        confirmed = _confirmbeforesend(repo, revs, oldmap)
33690
40cfe3197bc1 phabricator: add --confirm option to phabsend command
Pulkit Goyal <7895pulkit@gmail.com>
parents: 33601
diff changeset
   886
        if not confirmed:
38392
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38336
diff changeset
   887
            raise error.Abort(_(b'phabsend cancelled'))
33690
40cfe3197bc1 phabricator: add --confirm option to phabsend command
Pulkit Goyal <7895pulkit@gmail.com>
parents: 33601
diff changeset
   888
33498
b7a75b9a3386 phabricator: allow specifying reviewers on phabsend
Jun Wu <quark@fb.com>
parents: 33443
diff changeset
   889
    actions = []
38392
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38336
diff changeset
   890
    reviewers = opts.get(b'reviewer', [])
42444
f33d3ee110da phabricator: add --blocker argument to phabsend to specify blocking reviewers
Ian Moody <moz-ian@perix.co.uk>
parents: 42443
diff changeset
   891
    blockers = opts.get(b'blocker', [])
f33d3ee110da phabricator: add --blocker argument to phabsend to specify blocking reviewers
Ian Moody <moz-ian@perix.co.uk>
parents: 42443
diff changeset
   892
    phids = []
33498
b7a75b9a3386 phabricator: allow specifying reviewers on phabsend
Jun Wu <quark@fb.com>
parents: 33443
diff changeset
   893
    if reviewers:
42444
f33d3ee110da phabricator: add --blocker argument to phabsend to specify blocking reviewers
Ian Moody <moz-ian@perix.co.uk>
parents: 42443
diff changeset
   894
        phids.extend(userphids(repo, reviewers))
f33d3ee110da phabricator: add --blocker argument to phabsend to specify blocking reviewers
Ian Moody <moz-ian@perix.co.uk>
parents: 42443
diff changeset
   895
    if blockers:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   896
        phids.extend(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   897
            map(lambda phid: b'blocking(%s)' % phid, userphids(repo, blockers))
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   898
        )
42444
f33d3ee110da phabricator: add --blocker argument to phabsend to specify blocking reviewers
Ian Moody <moz-ian@perix.co.uk>
parents: 42443
diff changeset
   899
    if phids:
38392
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38336
diff changeset
   900
        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
   901
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   902
    drevids = []  # [int]
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   903
    diffmap = {}  # {newnode: diff}
33787
fa3aa6c98bb7 phabricator: add --amend option to phabsend
Jun Wu <quark@fb.com>
parents: 33785
diff changeset
   904
42449
c19d259fd6ad phabricator: use parents.set to always set dependencies
Ian Moody <moz-ian@perix.co.uk>
parents: 42444
diff changeset
   905
    # Send patches one by one so we know their Differential Revision PHIDs and
33199
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
   906
    # can provide dependency relationship
42449
c19d259fd6ad phabricator: use parents.set to always set dependencies
Ian Moody <moz-ian@perix.co.uk>
parents: 42444
diff changeset
   907
    lastrevphid = None
33199
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
   908
    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
   909
        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
   910
        ctx = repo[rev]
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
   911
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
   912
        # Get Differential Revision ID
33691
1664406a44d9 phabricator: use Phabricator's last node information
Jun Wu <quark@fb.com>
parents: 33690
diff changeset
   913
        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
   914
        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
   915
            # Create or update Differential Revision
33787
fa3aa6c98bb7 phabricator: add --amend option to phabsend
Jun Wu <quark@fb.com>
parents: 33785
diff changeset
   916
            revision, diff = createdifferentialrevision(
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   917
                ctx,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   918
                revid,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   919
                lastrevphid,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   920
                oldnode,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   921
                olddiff,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   922
                actions,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   923
                opts.get(b'comment'),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   924
            )
33787
fa3aa6c98bb7 phabricator: add --amend option to phabsend
Jun Wu <quark@fb.com>
parents: 33785
diff changeset
   925
            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
   926
            newrevid = int(revision[b'object'][b'id'])
42449
c19d259fd6ad phabricator: use parents.set to always set dependencies
Ian Moody <moz-ian@perix.co.uk>
parents: 42444
diff changeset
   927
            newrevphid = revision[b'object'][b'phid']
33199
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
   928
            if revid:
38392
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38336
diff changeset
   929
                action = b'updated'
33199
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
   930
            else:
38392
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38336
diff changeset
   931
                action = b'created'
33199
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
   932
33787
fa3aa6c98bb7 phabricator: add --amend option to phabsend
Jun Wu <quark@fb.com>
parents: 33785
diff changeset
   933
            # 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
   934
            # does not have it already
fa3aa6c98bb7 phabricator: add --amend option to phabsend
Jun Wu <quark@fb.com>
parents: 33785
diff changeset
   935
            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
   936
            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
   937
                tagname = b'D%d' % newrevid
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   938
                tags.tag(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   939
                    repo,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   940
                    tagname,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   941
                    ctx.node(),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   942
                    message=None,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   943
                    user=None,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   944
                    date=None,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   945
                    local=True,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   946
                )
33199
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
   947
        else:
42449
c19d259fd6ad phabricator: use parents.set to always set dependencies
Ian Moody <moz-ian@perix.co.uk>
parents: 42444
diff changeset
   948
            # Nothing changed. But still set "newrevphid" so the next revision
c19d259fd6ad phabricator: use parents.set to always set dependencies
Ian Moody <moz-ian@perix.co.uk>
parents: 42444
diff changeset
   949
            # could depend on this one and "newrevid" for the summary line.
42950
6fb281f39c25 py3: pass a bytestring into querydrev instead of a string that'll TypeError
Ian Moody <moz-ian@perix.co.uk>
parents: 42917
diff changeset
   950
            newrevphid = querydrev(repo, b'%d' % revid)[0][b'phid']
33199
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
   951
            newrevid = revid
38392
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38336
diff changeset
   952
            action = b'skipped'
33199
228ad1e58a85 phabricator: add phabsend command to send a stack
Jun Wu <quark@fb.com>
parents: 33198
diff changeset
   953
34063
941c33cfde81 phabricator: standardize colors
Jun Wu <quark@fb.com>
parents: 33978
diff changeset
   954
        actiondesc = ui.label(
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   955
            {
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   956
                b'created': _(b'created'),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   957
                b'skipped': _(b'skipped'),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   958
                b'updated': _(b'updated'),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   959
            }[action],
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   960
            b'phabricator.action.%s' % action,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   961
        )
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
   962
        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
   963
        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
   964
        desc = ui.label(ctx.description().split(b'\n')[0], b'phabricator.desc')
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   965
        ui.write(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   966
            _(b'%s - %s - %s: %s\n') % (drevdesc, actiondesc, nodedesc, desc)
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   967
        )
33787
fa3aa6c98bb7 phabricator: add --amend option to phabsend
Jun Wu <quark@fb.com>
parents: 33785
diff changeset
   968
        drevids.append(newrevid)
42449
c19d259fd6ad phabricator: use parents.set to always set dependencies
Ian Moody <moz-ian@perix.co.uk>
parents: 42444
diff changeset
   969
        lastrevphid = newrevphid
33200
04cf9927f350 phabricator: add phabread command to read patches
Jun Wu <quark@fb.com>
parents: 33199
diff changeset
   970
33787
fa3aa6c98bb7 phabricator: add --amend option to phabsend
Jun Wu <quark@fb.com>
parents: 33785
diff changeset
   971
    # 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
   972
    if opts.get(b'amend'):
33787
fa3aa6c98bb7 phabricator: add --amend option to phabsend
Jun Wu <quark@fb.com>
parents: 33785
diff changeset
   973
        unfi = repo.unfiltered()
42434
f163e2b2594c phabricator: pass ui instead of repo to callconduit
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42433
diff changeset
   974
        drevs = callconduit(ui, b'differential.query', {b'ids': drevids})
38392
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38336
diff changeset
   975
        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
   976
            wnode = unfi[b'.'].node()
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   977
            mapping = {}  # {oldnode: [newnode]}
33787
fa3aa6c98bb7 phabricator: add --amend option to phabsend
Jun Wu <quark@fb.com>
parents: 33785
diff changeset
   978
            for i, rev in enumerate(revs):
fa3aa6c98bb7 phabricator: add --amend option to phabsend
Jun Wu <quark@fb.com>
parents: 33785
diff changeset
   979
                old = unfi[rev]
fa3aa6c98bb7 phabricator: add --amend option to phabsend
Jun Wu <quark@fb.com>
parents: 33785
diff changeset
   980
                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
   981
                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
   982
                newdesc = getdescfromdrev(drev)
fa3aa6c98bb7 phabricator: add --amend option to phabsend
Jun Wu <quark@fb.com>
parents: 33785
diff changeset
   983
                # Make sure commit message contain "Differential Revision"
fa3aa6c98bb7 phabricator: add --amend option to phabsend
Jun Wu <quark@fb.com>
parents: 33785
diff changeset
   984
                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
   985
                    if old.phase() == phases.public:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   986
                        ui.warn(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   987
                            _(b"warning: not updating public commit %s\n")
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   988
                            % scmutil.formatchangeid(old)
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   989
                        )
41163
0101a35deae2 phabricator: warn if unable to amend, instead of aborting after posting
Matt Harbison <matt_harbison@yahoo.com>
parents: 41080
diff changeset
   990
                        continue
33787
fa3aa6c98bb7 phabricator: add --amend option to phabsend
Jun Wu <quark@fb.com>
parents: 33785
diff changeset
   991
                    parents = [
fa3aa6c98bb7 phabricator: add --amend option to phabsend
Jun Wu <quark@fb.com>
parents: 33785
diff changeset
   992
                        mapping.get(old.p1().node(), (old.p1(),))[0],
fa3aa6c98bb7 phabricator: add --amend option to phabsend
Jun Wu <quark@fb.com>
parents: 33785
diff changeset
   993
                        mapping.get(old.p2().node(), (old.p2(),))[0],
fa3aa6c98bb7 phabricator: add --amend option to phabsend
Jun Wu <quark@fb.com>
parents: 33785
diff changeset
   994
                    ]
fa3aa6c98bb7 phabricator: add --amend option to phabsend
Jun Wu <quark@fb.com>
parents: 33785
diff changeset
   995
                    new = context.metadataonlyctx(
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   996
                        repo,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   997
                        old,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   998
                        parents=parents,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
   999
                        text=newdesc,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
  1000
                        user=old.user(),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
  1001
                        date=old.date(),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
  1002
                        extra=old.extra(),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
  1003
                    )
38336
bb7e3c6ef592 phabricator: preserve the phase when amending in the Differential fields
Matt Harbison <matt_harbison@yahoo.com>
parents: 38042
diff changeset
  1004
38423
32fba6fe893d scmutil: make cleanupnodes optionally also fix the phase
Martin von Zweigbergk <martinvonz@google.com>
parents: 38392
diff changeset
  1005
                    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
  1006
33787
fa3aa6c98bb7 phabricator: add --amend option to phabsend
Jun Wu <quark@fb.com>
parents: 33785
diff changeset
  1007
                    mapping[old.node()] = [newnode]
fa3aa6c98bb7 phabricator: add --amend option to phabsend
Jun Wu <quark@fb.com>
parents: 33785
diff changeset
  1008
                    # Update diff property
42917
e26c2440a030 phabricator: don't abort if property writing fails during amending
Ian Moody <moz-ian@perix.co.uk>
parents: 42618
diff changeset
  1009
                    # If it fails just warn and keep going, otherwise the DREV
e26c2440a030 phabricator: don't abort if property writing fails during amending
Ian Moody <moz-ian@perix.co.uk>
parents: 42618
diff changeset
  1010
                    # associations will be lost
e26c2440a030 phabricator: don't abort if property writing fails during amending
Ian Moody <moz-ian@perix.co.uk>
parents: 42618
diff changeset
  1011
                    try:
e26c2440a030 phabricator: don't abort if property writing fails during amending
Ian Moody <moz-ian@perix.co.uk>
parents: 42618
diff changeset
  1012
                        writediffproperties(unfi[newnode], diffmap[old.node()])
e26c2440a030 phabricator: don't abort if property writing fails during amending
Ian Moody <moz-ian@perix.co.uk>
parents: 42618
diff changeset
  1013
                    except util.urlerr.urlerror:
43094
e8cf9ad52a78 formatting: run black on all file again
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43089
diff changeset
  1014
                        ui.warnnoi18n(
e8cf9ad52a78 formatting: run black on all file again
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43089
diff changeset
  1015
                            b'Failed to update metadata for D%s\n' % drevid
e8cf9ad52a78 formatting: run black on all file again
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43089
diff changeset
  1016
                        )
33787
fa3aa6c98bb7 phabricator: add --amend option to phabsend
Jun Wu <quark@fb.com>
parents: 33785
diff changeset
  1017
                # 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
  1018
                tagname = b'D%d' % drevid
33787
fa3aa6c98bb7 phabricator: add --amend option to phabsend
Jun Wu <quark@fb.com>
parents: 33785
diff changeset
  1019
                if tagname in repo.tags():
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
  1020
                    tags.tag(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
  1021
                        repo,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
  1022
                        tagname,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
  1023
                        nullid,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
  1024
                        message=None,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
  1025
                        user=None,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
  1026
                        date=None,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
  1027
                        local=True,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
  1028
                    )
38423
32fba6fe893d scmutil: make cleanupnodes optionally also fix the phase
Martin von Zweigbergk <martinvonz@google.com>
parents: 38392
diff changeset
  1029
            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
  1030
            if wnode in mapping:
fa3aa6c98bb7 phabricator: add --amend option to phabsend
Jun Wu <quark@fb.com>
parents: 33785
diff changeset
  1031
                unfi.setparents(mapping[wnode][0])
fa3aa6c98bb7 phabricator: add --amend option to phabsend
Jun Wu <quark@fb.com>
parents: 33785
diff changeset
  1032
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
  1033
33264
266321579c68 phabricator: add node and p1 to hg:meta property
Jun Wu <quark@fb.com>
parents: 33263
diff changeset
  1034
# 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
  1035
# consistent with "hg export" output.
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
  1036
_metanamemap = util.sortdict(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
  1037
    [
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
  1038
        (b'user', b'User'),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
  1039
        (b'date', b'Date'),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
  1040
        (b'branch', b'Branch'),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
  1041
        (b'node', b'Node ID'),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
  1042
        (b'parent', b'Parent '),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
  1043
    ]
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
  1044
)
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
  1045
33264
266321579c68 phabricator: add node and p1 to hg:meta property
Jun Wu <quark@fb.com>
parents: 33263
diff changeset
  1046
33978
088598153aa2 phabsend: show associated Differential Revisions with --confirm
Jun Wu <quark@fb.com>
parents: 33977
diff changeset
  1047
def _confirmbeforesend(repo, revs, oldmap):
42433
500b64c5d991 phabricator: pass ui into readurltoken instead of passing repo
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42431
diff changeset
  1048
    url, token = readurltoken(repo.ui)
33690
40cfe3197bc1 phabricator: add --confirm option to phabsend command
Pulkit Goyal <7895pulkit@gmail.com>
parents: 33601
diff changeset
  1049
    ui = repo.ui
40cfe3197bc1 phabricator: add --confirm option to phabsend command
Pulkit Goyal <7895pulkit@gmail.com>
parents: 33601
diff changeset
  1050
    for rev in revs:
40cfe3197bc1 phabricator: add --confirm option to phabsend command
Pulkit Goyal <7895pulkit@gmail.com>
parents: 33601
diff changeset
  1051
        ctx = repo[rev]
40cfe3197bc1 phabricator: add --confirm option to phabsend command
Pulkit Goyal <7895pulkit@gmail.com>
parents: 33601
diff changeset
  1052
        desc = ctx.description().splitlines()[0]
33978
088598153aa2 phabsend: show associated Differential Revisions with --confirm
Jun Wu <quark@fb.com>
parents: 33977
diff changeset
  1053
        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
  1054
        if drevid:
38392
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38336
diff changeset
  1055
            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
  1056
        else:
38392
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38336
diff changeset
  1057
            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
  1058
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
  1059
        ui.write(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
  1060
            _(b'%s - %s: %s\n')
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
  1061
            % (
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
  1062
                drevdesc,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
  1063
                ui.label(bytes(ctx), b'phabricator.node'),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
  1064
                ui.label(desc, b'phabricator.desc'),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
  1065
            )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
  1066
        )
33690
40cfe3197bc1 phabricator: add --confirm option to phabsend command
Pulkit Goyal <7895pulkit@gmail.com>
parents: 33601
diff changeset
  1067
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
  1068
    if ui.promptchoice(
43117
8ff1ecfadcd1 cleanup: join string literals that are already on one line
Martin von Zweigbergk <martinvonz@google.com>
parents: 43094
diff changeset
  1069
        _(b'Send the above changes to %s (yn)?$$ &Yes $$ &No') % url
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
  1070
    ):
33690
40cfe3197bc1 phabricator: add --confirm option to phabsend command
Pulkit Goyal <7895pulkit@gmail.com>
parents: 33601
diff changeset
  1071
        return False
40cfe3197bc1 phabricator: add --confirm option to phabsend command
Pulkit Goyal <7895pulkit@gmail.com>
parents: 33601
diff changeset
  1072
40cfe3197bc1 phabricator: add --confirm option to phabsend command
Pulkit Goyal <7895pulkit@gmail.com>
parents: 33601
diff changeset
  1073
    return True
40cfe3197bc1 phabricator: add --confirm option to phabsend command
Pulkit Goyal <7895pulkit@gmail.com>
parents: 33601
diff changeset
  1074
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
  1075
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
  1076
_knownstatusnames = {
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
  1077
    b'accepted',
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
  1078
    b'needsreview',
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
  1079
    b'needsrevision',
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
  1080
    b'closed',
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
  1081
    b'abandoned',
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
  1082
}
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
  1083
33833
fb59192b4981 phabricator: add status to revision query language
Jun Wu <quark@fb.com>
parents: 33832
diff changeset
  1084
fb59192b4981 phabricator: add status to revision query language
Jun Wu <quark@fb.com>
parents: 33832
diff changeset
  1085
def _getstatusname(drev):
fb59192b4981 phabricator: add status to revision query language
Jun Wu <quark@fb.com>
parents: 33832
diff changeset
  1086
    """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
  1087
    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
  1088
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
  1089
33832
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33831
diff changeset
  1090
# 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
  1091
# +, and -.
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33831
diff changeset
  1092
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33831
diff changeset
  1093
_elements = {
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33831
diff changeset
  1094
    # token-type: binding-strength, primary, prefix, infix, suffix
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
  1095
    b'(': (12, None, (b'group', 1, b')'), None, None),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
  1096
    b':': (8, None, (b'ancestors', 8), None, None),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
  1097
    b'&': (5, None, None, (b'and_', 5), None),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
  1098
    b'+': (4, None, None, (b'add', 4), None),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
  1099
    b'-': (4, None, None, (b'sub', 4), None),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
  1100
    b')': (0, None, None, None, None),
38392
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38336
diff changeset
  1101
    b'symbol': (0, b'symbol', None, None, None),
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
  1102
    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
  1103
}
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33831
diff changeset
  1104
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
  1105
33832
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33831
diff changeset
  1106
def _tokenize(text):
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
  1107
    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
  1108
    special = b'():+-& '
33832
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33831
diff changeset
  1109
    pos = 0
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33831
diff changeset
  1110
    length = len(text)
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33831
diff changeset
  1111
    while pos < length:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
  1112
        symbol = b''.join(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
  1113
            itertools.takewhile(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
  1114
                lambda ch: ch not in special, pycompat.iterbytestr(view[pos:])
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
  1115
            )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
  1116
        )
33832
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33831
diff changeset
  1117
        if symbol:
38392
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38336
diff changeset
  1118
            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
  1119
            pos += len(symbol)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
  1120
        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
  1121
            if text[pos] != b' ':
33833
fb59192b4981 phabricator: add status to revision query language
Jun Wu <quark@fb.com>
parents: 33832
diff changeset
  1122
                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
  1123
            pos += 1
38392
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38336
diff changeset
  1124
    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
  1125
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
  1126
33832
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33831
diff changeset
  1127
def _parse(text):
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33831
diff changeset
  1128
    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
  1129
    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
  1130
        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
  1131
    return tree
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33831
diff changeset
  1132
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
  1133
33832
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33831
diff changeset
  1134
def _parsedrev(symbol):
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33831
diff changeset
  1135
    """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
  1136
    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
  1137
        return int(symbol[1:])
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33831
diff changeset
  1138
    if symbol.isdigit():
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33831
diff changeset
  1139
        return int(symbol)
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33831
diff changeset
  1140
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
  1141
33832
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33831
diff changeset
  1142
def _prefetchdrevs(tree):
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33831
diff changeset
  1143
    """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
  1144
    drevs = set()
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33831
diff changeset
  1145
    ancestordrevs = set()
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33831
diff changeset
  1146
    op = tree[0]
38392
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38336
diff changeset
  1147
    if op == b'symbol':
33832
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33831
diff changeset
  1148
        r = _parsedrev(tree[1])
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33831
diff changeset
  1149
        if r:
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33831
diff changeset
  1150
            drevs.add(r)
38392
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38336
diff changeset
  1151
    elif op == b'ancestors':
33832
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33831
diff changeset
  1152
        r, a = _prefetchdrevs(tree[1])
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33831
diff changeset
  1153
        drevs.update(r)
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33831
diff changeset
  1154
        ancestordrevs.update(r)
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33831
diff changeset
  1155
        ancestordrevs.update(a)
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33831
diff changeset
  1156
    else:
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33831
diff changeset
  1157
        for t in tree[1:]:
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33831
diff changeset
  1158
            r, a = _prefetchdrevs(t)
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33831
diff changeset
  1159
            drevs.update(r)
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33831
diff changeset
  1160
            ancestordrevs.update(a)
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33831
diff changeset
  1161
    return drevs, ancestordrevs
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33831
diff changeset
  1162
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
  1163
33832
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33831
diff changeset
  1164
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
  1165
    """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
  1166
33832
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33831
diff changeset
  1167
    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
  1168
    for details.
33267
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
  1169
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
  1170
    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
  1171
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
  1172
        {
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
  1173
            "id": "2",
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
  1174
            "phid": "PHID-DREV-672qvysjcczopag46qty",
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
  1175
            "title": "example",
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
  1176
            "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
  1177
            "dateCreated": "1499181406",
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
  1178
            "dateModified": "1499182103",
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
  1179
            "authorPHID": "PHID-USER-tv3ohwc4v4jeu34otlye",
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
  1180
            "status": "0",
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
  1181
            "statusName": "Needs Review",
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
  1182
            "properties": [],
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
  1183
            "branch": null,
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
  1184
            "summary": "",
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
  1185
            "testPlan": "",
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
  1186
            "lineCount": "2",
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
  1187
            "activeDiffPHID": "PHID-DIFF-xoqnjkobbm6k4dk6hi72",
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
  1188
            "diffs": [
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
  1189
              "3",
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
  1190
              "4",
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
  1191
            ],
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
  1192
            "commits": [],
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
  1193
            "reviewers": [],
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
  1194
            "ccs": [],
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
  1195
            "hashes": [],
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
  1196
            "auxiliary": {
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
  1197
              "phabricator:projects": [],
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
  1198
              "phabricator:depends-on": [
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
  1199
                "PHID-DREV-gbapp366kutjebt7agcd"
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
  1200
              ]
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
  1201
            },
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
  1202
            "repositoryPHID": "PHID-REPO-hub2hx62ieuqeheznasv",
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
  1203
            "sourcePath": null
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
  1204
        }
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
  1205
    """
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
  1206
33269
ead6749354e1 phabricator: try to fetch differential revisions in batch
Jun Wu <quark@fb.com>
parents: 33268
diff changeset
  1207
    def fetch(params):
ead6749354e1 phabricator: try to fetch differential revisions in batch
Jun Wu <quark@fb.com>
parents: 33268
diff changeset
  1208
        """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
  1209
        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
  1210
        if key in prefetched:
ead6749354e1 phabricator: try to fetch differential revisions in batch
Jun Wu <quark@fb.com>
parents: 33268
diff changeset
  1211
            return prefetched[key]
42434
f163e2b2594c phabricator: pass ui instead of repo to callconduit
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42433
diff changeset
  1212
        drevs = callconduit(repo.ui, b'differential.query', params)
33269
ead6749354e1 phabricator: try to fetch differential revisions in batch
Jun Wu <quark@fb.com>
parents: 33268
diff changeset
  1213
        # Fill prefetched with the result
ead6749354e1 phabricator: try to fetch differential revisions in batch
Jun Wu <quark@fb.com>
parents: 33268
diff changeset
  1214
        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
  1215
            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
  1216
            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
  1217
        if key not in prefetched:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
  1218
            raise error.Abort(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
  1219
                _(b'cannot get Differential Revision %r') % params
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
  1220
            )
33269
ead6749354e1 phabricator: try to fetch differential revisions in batch
Jun Wu <quark@fb.com>
parents: 33268
diff changeset
  1221
        return prefetched[key]
ead6749354e1 phabricator: try to fetch differential revisions in batch
Jun Wu <quark@fb.com>
parents: 33268
diff changeset
  1222
33832
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33831
diff changeset
  1223
    def getstack(topdrevids):
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33831
diff changeset
  1224
        """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
  1225
        visited = set()
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33831
diff changeset
  1226
        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
  1227
        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
  1228
        while queue:
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33831
diff changeset
  1229
            params = queue.pop()
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33831
diff changeset
  1230
            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
  1231
            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
  1232
                continue
41897
c340a8ac7ef3 phabricator: convert conduit response JSON unicode to bytes inside callconduit
Ian Moody <moz-ian@perix.co.uk>
parents: 41705
diff changeset
  1233
            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
  1234
            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
  1235
            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
  1236
            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
  1237
            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
  1238
                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
  1239
        result.reverse()
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33831
diff changeset
  1240
        return smartset.baseset(result)
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33831
diff changeset
  1241
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33831
diff changeset
  1242
    # Initialize prefetch cache
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
  1243
    prefetched = {}  # {id or phid: drev}
33832
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33831
diff changeset
  1244
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33831
diff changeset
  1245
    tree = _parse(spec)
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33831
diff changeset
  1246
    drevs, ancestordrevs = _prefetchdrevs(tree)
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33831
diff changeset
  1247
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33831
diff changeset
  1248
    # 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
  1249
    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
  1250
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33831
diff changeset
  1251
    # Prefetch Differential Revisions in batch
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33831
diff changeset
  1252
    tofetch = set(drevs)
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33831
diff changeset
  1253
    for r in ancestordrevs:
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33831
diff changeset
  1254
        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
  1255
    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
  1256
        fetch({b'ids': list(tofetch)})
33833
fb59192b4981 phabricator: add status to revision query language
Jun Wu <quark@fb.com>
parents: 33832
diff changeset
  1257
    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
  1258
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33831
diff changeset
  1259
    # 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
  1260
    def walk(tree):
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33831
diff changeset
  1261
        op = tree[0]
38392
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38336
diff changeset
  1262
        if op == b'symbol':
33832
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33831
diff changeset
  1263
            drev = _parsedrev(tree[1])
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33831
diff changeset
  1264
            if drev:
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33831
diff changeset
  1265
                return smartset.baseset([drev])
33833
fb59192b4981 phabricator: add status to revision query language
Jun Wu <quark@fb.com>
parents: 33832
diff changeset
  1266
            elif tree[1] in _knownstatusnames:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
  1267
                drevs = [
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
  1268
                    r
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
  1269
                    for r in validids
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
  1270
                    if _getstatusname(prefetched[r]) == tree[1]
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
  1271
                ]
33833
fb59192b4981 phabricator: add status to revision query language
Jun Wu <quark@fb.com>
parents: 33832
diff changeset
  1272
                return smartset.baseset(drevs)
33832
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33831
diff changeset
  1273
            else:
38392
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38336
diff changeset
  1274
                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
  1275
        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
  1276
            assert len(tree) == 3
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33831
diff changeset
  1277
            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
  1278
        elif op == b'group':
33832
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33831
diff changeset
  1279
            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
  1280
        elif op == b'ancestors':
33832
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33831
diff changeset
  1281
            return getstack(walk(tree[1]))
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33831
diff changeset
  1282
        else:
38392
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38336
diff changeset
  1283
            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
  1284
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33831
diff changeset
  1285
    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
  1286
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
  1287
33268
85391b95961d phabricator: avoid calling differential.getcommitmessage
Jun Wu <quark@fb.com>
parents: 33267
diff changeset
  1288
def getdescfromdrev(drev):
85391b95961d phabricator: avoid calling differential.getcommitmessage
Jun Wu <quark@fb.com>
parents: 33267
diff changeset
  1289
    """get description (commit message) from "Differential Revision"
85391b95961d phabricator: avoid calling differential.getcommitmessage
Jun Wu <quark@fb.com>
parents: 33267
diff changeset
  1290
85391b95961d phabricator: avoid calling differential.getcommitmessage
Jun Wu <quark@fb.com>
parents: 33267
diff changeset
  1291
    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
  1292
    about limited fields: title, summary, test plan, and URL.
85391b95961d phabricator: avoid calling differential.getcommitmessage
Jun Wu <quark@fb.com>
parents: 33267
diff changeset
  1293
    """
41897
c340a8ac7ef3 phabricator: convert conduit response JSON unicode to bytes inside callconduit
Ian Moody <moz-ian@perix.co.uk>
parents: 41705
diff changeset
  1294
    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
  1295
    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
  1296
    testplan = drev[b'testPlan'].rstrip()
33268
85391b95961d phabricator: avoid calling differential.getcommitmessage
Jun Wu <quark@fb.com>
parents: 33267
diff changeset
  1297
    if testplan:
38392
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38336
diff changeset
  1298
        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
  1299
    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
  1300
    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
  1301
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
  1302
33441
de7c6ec27d99 phabricator: respect metadata sent by arc
Jun Wu <quark@fb.com>
parents: 33271
diff changeset
  1303
def getdiffmeta(diff):
de7c6ec27d99 phabricator: respect metadata sent by arc
Jun Wu <quark@fb.com>
parents: 33271
diff changeset
  1304
    """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
  1305
de7c6ec27d99 phabricator: respect metadata sent by arc
Jun Wu <quark@fb.com>
parents: 33271
diff changeset
  1306
    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
  1307
de7c6ec27d99 phabricator: respect metadata sent by arc
Jun Wu <quark@fb.com>
parents: 33271
diff changeset
  1308
        "properties": {
de7c6ec27d99 phabricator: respect metadata sent by arc
Jun Wu <quark@fb.com>
parents: 33271
diff changeset
  1309
          "hg:meta": {
de7c6ec27d99 phabricator: respect metadata sent by arc
Jun Wu <quark@fb.com>
parents: 33271
diff changeset
  1310
            "date": "1499571514 25200",
de7c6ec27d99 phabricator: respect metadata sent by arc
Jun Wu <quark@fb.com>
parents: 33271
diff changeset
  1311
            "node": "98c08acae292b2faf60a279b4189beb6cff1414d",
de7c6ec27d99 phabricator: respect metadata sent by arc
Jun Wu <quark@fb.com>
parents: 33271
diff changeset
  1312
            "user": "Foo Bar <foo@example.com>",
de7c6ec27d99 phabricator: respect metadata sent by arc
Jun Wu <quark@fb.com>
parents: 33271
diff changeset
  1313
            "parent": "6d0abad76b30e4724a37ab8721d630394070fe16"
de7c6ec27d99 phabricator: respect metadata sent by arc
Jun Wu <quark@fb.com>
parents: 33271
diff changeset
  1314
          }
de7c6ec27d99 phabricator: respect metadata sent by arc
Jun Wu <quark@fb.com>
parents: 33271
diff changeset
  1315
        }
de7c6ec27d99 phabricator: respect metadata sent by arc
Jun Wu <quark@fb.com>
parents: 33271
diff changeset
  1316
de7c6ec27d99 phabricator: respect metadata sent by arc
Jun Wu <quark@fb.com>
parents: 33271
diff changeset
  1317
    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
  1318
de7c6ec27d99 phabricator: respect metadata sent by arc
Jun Wu <quark@fb.com>
parents: 33271
diff changeset
  1319
        "properties": {
de7c6ec27d99 phabricator: respect metadata sent by arc
Jun Wu <quark@fb.com>
parents: 33271
diff changeset
  1320
          "local:commits": {
de7c6ec27d99 phabricator: respect metadata sent by arc
Jun Wu <quark@fb.com>
parents: 33271
diff changeset
  1321
            "98c08acae292b2faf60a279b4189beb6cff1414d": {
de7c6ec27d99 phabricator: respect metadata sent by arc
Jun Wu <quark@fb.com>
parents: 33271
diff changeset
  1322
              "author": "Foo Bar",
de7c6ec27d99 phabricator: respect metadata sent by arc
Jun Wu <quark@fb.com>
parents: 33271
diff changeset
  1323
              "time": 1499546314,
de7c6ec27d99 phabricator: respect metadata sent by arc
Jun Wu <quark@fb.com>
parents: 33271
diff changeset
  1324
              "branch": "default",
de7c6ec27d99 phabricator: respect metadata sent by arc
Jun Wu <quark@fb.com>
parents: 33271
diff changeset
  1325
              "tag": "",
de7c6ec27d99 phabricator: respect metadata sent by arc
Jun Wu <quark@fb.com>
parents: 33271
diff changeset
  1326
              "commit": "98c08acae292b2faf60a279b4189beb6cff1414d",
de7c6ec27d99 phabricator: respect metadata sent by arc
Jun Wu <quark@fb.com>
parents: 33271
diff changeset
  1327
              "rev": "98c08acae292b2faf60a279b4189beb6cff1414d",
de7c6ec27d99 phabricator: respect metadata sent by arc
Jun Wu <quark@fb.com>
parents: 33271
diff changeset
  1328
              "local": "1000",
de7c6ec27d99 phabricator: respect metadata sent by arc
Jun Wu <quark@fb.com>
parents: 33271
diff changeset
  1329
              "parents": ["6d0abad76b30e4724a37ab8721d630394070fe16"],
de7c6ec27d99 phabricator: respect metadata sent by arc
Jun Wu <quark@fb.com>
parents: 33271
diff changeset
  1330
              "summary": "...",
de7c6ec27d99 phabricator: respect metadata sent by arc
Jun Wu <quark@fb.com>
parents: 33271
diff changeset
  1331
              "message": "...",
de7c6ec27d99 phabricator: respect metadata sent by arc
Jun Wu <quark@fb.com>
parents: 33271
diff changeset
  1332
              "authorEmail": "foo@example.com"
de7c6ec27d99 phabricator: respect metadata sent by arc
Jun Wu <quark@fb.com>
parents: 33271
diff changeset
  1333
            }
de7c6ec27d99 phabricator: respect metadata sent by arc
Jun Wu <quark@fb.com>
parents: 33271
diff changeset
  1334
          }
de7c6ec27d99 phabricator: respect metadata sent by arc
Jun Wu <quark@fb.com>
parents: 33271
diff changeset
  1335
        }
de7c6ec27d99 phabricator: respect metadata sent by arc
Jun Wu <quark@fb.com>
parents: 33271
diff changeset
  1336
de7c6ec27d99 phabricator: respect metadata sent by arc
Jun Wu <quark@fb.com>
parents: 33271
diff changeset
  1337
    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
  1338
    information.
de7c6ec27d99 phabricator: respect metadata sent by arc
Jun Wu <quark@fb.com>
parents: 33271
diff changeset
  1339
    """
41897
c340a8ac7ef3 phabricator: convert conduit response JSON unicode to bytes inside callconduit
Ian Moody <moz-ian@perix.co.uk>
parents: 41705
diff changeset
  1340
    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
  1341
    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
  1342
    if not meta:
a4f7dceb07bf phabricator: fallback to reading metadata from diff for phabread
Ian Moody <moz-ian@perix.co.uk>
parents: 42256
diff changeset
  1343
        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
  1344
            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
  1345
            meta = {}
a4f7dceb07bf phabricator: fallback to reading metadata from diff for phabread
Ian Moody <moz-ian@perix.co.uk>
parents: 42256
diff changeset
  1346
            if b'author' in commit and b'authorEmail' in commit:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
  1347
                meta[b'user'] = b'%s <%s>' % (
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
  1348
                    commit[b'author'],
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
  1349
                    commit[b'authorEmail'],
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
  1350
                )
42257
a4f7dceb07bf phabricator: fallback to reading metadata from diff for phabread
Ian Moody <moz-ian@perix.co.uk>
parents: 42256
diff changeset
  1351
            if b'time' in commit:
42618
c17e6a3e7356 phabricator: handle local:commits time being string or int
Ian Moody <moz-ian@perix.co.uk>
parents: 42449
diff changeset
  1352
                meta[b'date'] = b'%d 0' % int(commit[b'time'])
42257
a4f7dceb07bf phabricator: fallback to reading metadata from diff for phabread
Ian Moody <moz-ian@perix.co.uk>
parents: 42256
diff changeset
  1353
            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
  1354
                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
  1355
            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
  1356
            if node:
a4f7dceb07bf phabricator: fallback to reading metadata from diff for phabread
Ian Moody <moz-ian@perix.co.uk>
parents: 42256
diff changeset
  1357
                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
  1358
            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
  1359
                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
  1360
        else:
a4f7dceb07bf phabricator: fallback to reading metadata from diff for phabread
Ian Moody <moz-ian@perix.co.uk>
parents: 42256
diff changeset
  1361
            meta = {}
a4f7dceb07bf phabricator: fallback to reading metadata from diff for phabread
Ian Moody <moz-ian@perix.co.uk>
parents: 42256
diff changeset
  1362
    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
  1363
        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
  1364
    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
  1365
        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
  1366
    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
  1367
        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
  1368
    return meta
33441
de7c6ec27d99 phabricator: respect metadata sent by arc
Jun Wu <quark@fb.com>
parents: 33271
diff changeset
  1369
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
  1370
33831
75fdaf851e83 phabricator: change "readpatch" to be more flexible
Jun Wu <quark@fb.com>
parents: 33787
diff changeset
  1371
def readpatch(repo, drevs, write):
33200
04cf9927f350 phabricator: add phabread command to read patches
Jun Wu <quark@fb.com>
parents: 33199
diff changeset
  1372
    """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
  1373
33831
75fdaf851e83 phabricator: change "readpatch" to be more flexible
Jun Wu <quark@fb.com>
parents: 33787
diff changeset
  1374
    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
  1375
    "differential.query".
33200
04cf9927f350 phabricator: add phabread command to read patches
Jun Wu <quark@fb.com>
parents: 33199
diff changeset
  1376
    """
33267
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
  1377
    # 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
  1378
    diffids = sorted(set(max(int(v) for v in drev[b'diffs']) for drev in drevs))
42434
f163e2b2594c phabricator: pass ui instead of repo to callconduit
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42433
diff changeset
  1379
    diffs = callconduit(repo.ui, b'differential.querydiffs', {b'ids': diffids})
33200
04cf9927f350 phabricator: add phabread command to read patches
Jun Wu <quark@fb.com>
parents: 33199
diff changeset
  1380
33267
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
  1381
    # 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
  1382
    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
  1383
        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
  1384
41897
c340a8ac7ef3 phabricator: convert conduit response JSON unicode to bytes inside callconduit
Ian Moody <moz-ian@perix.co.uk>
parents: 41705
diff changeset
  1385
        diffid = max(int(v) for v in drev[b'diffs'])
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
  1386
        body = callconduit(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
  1387
            repo.ui, b'differential.getrawdiff', {b'diffID': diffid}
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
  1388
        )
33268
85391b95961d phabricator: avoid calling differential.getcommitmessage
Jun Wu <quark@fb.com>
parents: 33267
diff changeset
  1389
        desc = getdescfromdrev(drev)
38392
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38336
diff changeset
  1390
        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
  1391
dba9f88659a3 phabricator: rework phabread to reduce memory usage and round-trips
Jun Wu <quark@fb.com>
parents: 33266
diff changeset
  1392
        # 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
  1393
        # 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
  1394
        # 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
  1395
        meta = getdiffmeta(diffs[b'%d' % diffid])
33441
de7c6ec27d99 phabricator: respect metadata sent by arc
Jun Wu <quark@fb.com>
parents: 33271
diff changeset
  1396
        for k in _metanamemap.keys():
de7c6ec27d99 phabricator: respect metadata sent by arc
Jun Wu <quark@fb.com>
parents: 33271
diff changeset
  1397
            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
  1398
                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
  1399
38392
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38336
diff changeset
  1400
        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
  1401
        write(content)
33200
04cf9927f350 phabricator: add phabread command to read patches
Jun Wu <quark@fb.com>
parents: 33199
diff changeset
  1402
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
  1403
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
  1404
@vcrcommand(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
  1405
    b'phabread',
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
  1406
    [(b'', b'stack', False, _(b'read dependencies'))],
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
  1407
    _(b'DREVSPEC [OPTIONS]'),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
  1408
    helpcategory=command.CATEGORY_IMPORT_EXPORT,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
  1409
)
33832
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33831
diff changeset
  1410
def phabread(ui, repo, spec, **opts):
33200
04cf9927f350 phabricator: add phabread command to read patches
Jun Wu <quark@fb.com>
parents: 33199
diff changeset
  1411
    """print patches from Phabricator suitable for importing
04cf9927f350 phabricator: add phabread command to read patches
Jun Wu <quark@fb.com>
parents: 33199
diff changeset
  1412
33832
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33831
diff changeset
  1413
    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
  1414
    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
  1415
    ``&``, ``(``, ``)`` 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
  1416
    select a stack.
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33831
diff changeset
  1417
33833
fb59192b4981 phabricator: add status to revision query language
Jun Wu <quark@fb.com>
parents: 33832
diff changeset
  1418
    ``abandoned``, ``accepted``, ``closed``, ``needsreview``, ``needsrevision``
fb59192b4981 phabricator: add status to revision query language
Jun Wu <quark@fb.com>
parents: 33832
diff changeset
  1419
    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
  1420
    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
  1421
33832
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33831
diff changeset
  1422
    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
  1423
    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
  1424
    stack up to D9.
33200
04cf9927f350 phabricator: add phabread command to read patches
Jun Wu <quark@fb.com>
parents: 33199
diff changeset
  1425
04cf9927f350 phabricator: add phabread command to read patches
Jun Wu <quark@fb.com>
parents: 33199
diff changeset
  1426
    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
  1427
    It is equivalent to the ``:`` operator.
33200
04cf9927f350 phabricator: add phabread command to read patches
Jun Wu <quark@fb.com>
parents: 33199
diff changeset
  1428
    """
41970
51ba9fbcca52 py3: use pycompat.byteskwargs on opts in phabricator.py
Ian Moody <moz-ian@perix.co.uk>
parents: 41950
diff changeset
  1429
    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
  1430
    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
  1431
        spec = b':(%s)' % spec
33832
539541779010 phabricator: add a small language to query Differential Revisions
Jun Wu <quark@fb.com>
parents: 33831
diff changeset
  1432
    drevs = querydrev(repo, spec)
33831
75fdaf851e83 phabricator: change "readpatch" to be more flexible
Jun Wu <quark@fb.com>
parents: 33787
diff changeset
  1433
    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
  1434
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
  1435
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
  1436
@vcrcommand(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
  1437
    b'phabupdate',
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
  1438
    [
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
  1439
        (b'', b'accept', False, _(b'accept revisions')),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
  1440
        (b'', b'reject', False, _(b'reject revisions')),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
  1441
        (b'', b'abandon', False, _(b'abandon revisions')),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
  1442
        (b'', b'reclaim', False, _(b'reclaim revisions')),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
  1443
        (b'm', b'comment', b'', _(b'comment on the last revision')),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
  1444
    ],
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
  1445
    _(b'DREVSPEC [OPTIONS]'),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
  1446
    helpcategory=command.CATEGORY_IMPORT_EXPORT,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
  1447
)
33834
6e666cd59879 phabricator: add phabupdate command to update status in batch
Jun Wu <quark@fb.com>
parents: 33833
diff changeset
  1448
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
  1449
    """update Differential Revision in batch
6e666cd59879 phabricator: add phabupdate command to update status in batch
Jun Wu <quark@fb.com>
parents: 33833
diff changeset
  1450
6e666cd59879 phabricator: add phabupdate command to update status in batch
Jun Wu <quark@fb.com>
parents: 33833
diff changeset
  1451
    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
  1452
    """
41970
51ba9fbcca52 py3: use pycompat.byteskwargs on opts in phabricator.py
Ian Moody <moz-ian@perix.co.uk>
parents: 41950
diff changeset
  1453
    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
  1454
    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
  1455
    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
  1456
        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
  1457
6e666cd59879 phabricator: add phabupdate command to update status in batch
Jun Wu <quark@fb.com>
parents: 33833
diff changeset
  1458
    actions = []
6e666cd59879 phabricator: add phabupdate command to update status in batch
Jun Wu <quark@fb.com>
parents: 33833
diff changeset
  1459
    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
  1460
        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
  1461
6e666cd59879 phabricator: add phabupdate command to update status in batch
Jun Wu <quark@fb.com>
parents: 33833
diff changeset
  1462
    drevs = querydrev(repo, spec)
6e666cd59879 phabricator: add phabupdate command to update status in batch
Jun Wu <quark@fb.com>
parents: 33833
diff changeset
  1463
    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
  1464
        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
  1465
            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
  1466
        if actions:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
  1467
            params = {
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
  1468
                b'objectIdentifier': drev[b'phid'],
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
  1469
                b'transactions': actions,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
  1470
            }
42434
f163e2b2594c phabricator: pass ui instead of repo to callconduit
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42433
diff changeset
  1471
            callconduit(ui, 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
  1472
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
  1473
42973
24bf7a3d3c30 phabricator: use exthelper to register commands, config, and templates
Matt Harbison <matt_harbison@yahoo.com>
parents: 42951
diff changeset
  1474
@eh.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
  1475
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
  1476
    """: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
  1477
    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
  1478
    """
38392
81a4be7099fa py3: byte-stringify literals in contrib/phabricator.py as example
Yuya Nishihara <yuya@tcha.org>
parents: 38336
diff changeset
  1479
    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
  1480
    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
  1481
    if m:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
  1482
        return templateutil.hybriddict(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
  1483
            {b'url': m.group(r'url'), b'id': b"D%s" % m.group(r'id'),}
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
  1484
        )
41164
43fd1947301d phabricator: teach {phabreview} to work without --amend
Matt Harbison <matt_harbison@yahoo.com>
parents: 41163
diff changeset
  1485
    else:
43fd1947301d phabricator: teach {phabreview} to work without --amend
Matt Harbison <matt_harbison@yahoo.com>
parents: 41163
diff changeset
  1486
        tags = ctx.repo().nodetags(ctx.node())
43fd1947301d phabricator: teach {phabreview} to work without --amend
Matt Harbison <matt_harbison@yahoo.com>
parents: 41163
diff changeset
  1487
        for t in tags:
43fd1947301d phabricator: teach {phabreview} to work without --amend
Matt Harbison <matt_harbison@yahoo.com>
parents: 41163
diff changeset
  1488
            if _differentialrevisiontagre.match(t):
43fd1947301d phabricator: teach {phabreview} to work without --amend
Matt Harbison <matt_harbison@yahoo.com>
parents: 41163
diff changeset
  1489
                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
  1490
                if not url.endswith(b'/'):
43fd1947301d phabricator: teach {phabreview} to work without --amend
Matt Harbison <matt_harbison@yahoo.com>
parents: 41163
diff changeset
  1491
                    url += b'/'
43fd1947301d phabricator: teach {phabreview} to work without --amend
Matt Harbison <matt_harbison@yahoo.com>
parents: 41163
diff changeset
  1492
                url += t
43fd1947301d phabricator: teach {phabreview} to work without --amend
Matt Harbison <matt_harbison@yahoo.com>
parents: 41163
diff changeset
  1493
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43047
diff changeset
  1494
                return templateutil.hybriddict({b'url': url, b'id': t,})
41164
43fd1947301d phabricator: teach {phabreview} to work without --amend
Matt Harbison <matt_harbison@yahoo.com>
parents: 41163
diff changeset
  1495
    return None