hgext/patchbomb.py
author Martin von Zweigbergk <martinvonz@google.com>
Tue, 19 Jun 2018 11:07:23 -0700
changeset 38422 a6addfd64507
parent 38403 8ce3f91d5f6f
child 38471 91228d9ae7c8
permissions -rw-r--r--
tests: add test of uncommit with default phase as secret We didn't seem to have any test checking that uncommitting a draft commit with phase.new-phase=secret preserved the draft phase. Differential Revision: https://phab.mercurial-scm.org/D3817
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
8252
9674d64b6416 patchbomb: add copyright and license header
Martin Geisler <mg@lazybytes.net>
parents: 8208
diff changeset
     1
# patchbomb.py - sending Mercurial changesets as patch emails
9674d64b6416 patchbomb: add copyright and license header
Martin Geisler <mg@lazybytes.net>
parents: 8208
diff changeset
     2
#
9674d64b6416 patchbomb: add copyright and license header
Martin Geisler <mg@lazybytes.net>
parents: 8208
diff changeset
     3
#  Copyright 2005-2009 Matt Mackall <mpm@selenic.com> and others
9674d64b6416 patchbomb: add copyright and license header
Martin Geisler <mg@lazybytes.net>
parents: 8208
diff changeset
     4
#
9674d64b6416 patchbomb: add copyright and license header
Martin Geisler <mg@lazybytes.net>
parents: 8208
diff changeset
     5
# This software may be used and distributed according to the terms of the
10263
25e572394f5c Update license to GPLv2+
Matt Mackall <mpm@selenic.com>
parents: 10022
diff changeset
     6
# GNU General Public License version 2 or any later version.
8252
9674d64b6416 patchbomb: add copyright and license header
Martin Geisler <mg@lazybytes.net>
parents: 8208
diff changeset
     7
8935
f4f0e902b750 extensions: change descriptions for hook-providing extensions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 8934
diff changeset
     8
'''command to send changesets as (a series of) patch emails
6666
53465a7464e2 convert comments to docstrings in a bunch of extensions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6548
diff changeset
     9
7997
8eb9f495e150 patchbomb: word-wrap help texts at 70 characters
Martin Geisler <mg@daimi.au.dk>
parents: 7983
diff changeset
    10
The series is started off with a "[PATCH 0 of N]" introduction, which
8eb9f495e150 patchbomb: word-wrap help texts at 70 characters
Martin Geisler <mg@daimi.au.dk>
parents: 7983
diff changeset
    11
describes the series as a whole.
6666
53465a7464e2 convert comments to docstrings in a bunch of extensions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6548
diff changeset
    12
9269
1d6499adf211 patchbomb: wrap docstrings at 70 characters
Martin Geisler <mg@lazybytes.net>
parents: 9214
diff changeset
    13
Each patch email has a Subject line of "[PATCH M of N] ...", using the
1d6499adf211 patchbomb: wrap docstrings at 70 characters
Martin Geisler <mg@lazybytes.net>
parents: 9214
diff changeset
    14
first line of the changeset description as the subject text. The
1d6499adf211 patchbomb: wrap docstrings at 70 characters
Martin Geisler <mg@lazybytes.net>
parents: 9214
diff changeset
    15
message contains two or three body parts:
6666
53465a7464e2 convert comments to docstrings in a bunch of extensions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6548
diff changeset
    16
9300
ad95ea1c975a patchbomb: use a list instead of indented paragraphs
Martin Geisler <mg@lazybytes.net>
parents: 9289
diff changeset
    17
- The changeset description.
ad95ea1c975a patchbomb: use a list instead of indented paragraphs
Martin Geisler <mg@lazybytes.net>
parents: 9289
diff changeset
    18
- [Optional] The result of running diffstat on the patch.
10973
49a07f441496 Use hg role in help strings
Martin Geisler <mg@aragost.com>
parents: 10734
diff changeset
    19
- The patch itself, as generated by :hg:`export`.
6666
53465a7464e2 convert comments to docstrings in a bunch of extensions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6548
diff changeset
    20
9269
1d6499adf211 patchbomb: wrap docstrings at 70 characters
Martin Geisler <mg@lazybytes.net>
parents: 9214
diff changeset
    21
Each message refers to the first in the series using the In-Reply-To
1d6499adf211 patchbomb: wrap docstrings at 70 characters
Martin Geisler <mg@lazybytes.net>
parents: 9214
diff changeset
    22
and References headers, so they will show up as a sequence in threaded
1d6499adf211 patchbomb: wrap docstrings at 70 characters
Martin Geisler <mg@lazybytes.net>
parents: 9214
diff changeset
    23
mail and news readers, and in mail archives.
6666
53465a7464e2 convert comments to docstrings in a bunch of extensions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6548
diff changeset
    24
13838
c5709dfa5c1e patchbomb, help/hgweb: do not refer to config files as hgrc files
Martin Geisler <mg@aragost.com>
parents: 13400
diff changeset
    25
To configure other defaults, add a section like this to your
c5709dfa5c1e patchbomb, help/hgweb: do not refer to config files as hgrc files
Martin Geisler <mg@aragost.com>
parents: 13400
diff changeset
    26
configuration file::
6666
53465a7464e2 convert comments to docstrings in a bunch of extensions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6548
diff changeset
    27
53465a7464e2 convert comments to docstrings in a bunch of extensions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6548
diff changeset
    28
  [email]
53465a7464e2 convert comments to docstrings in a bunch of extensions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6548
diff changeset
    29
  from = My Name <my@email>
53465a7464e2 convert comments to docstrings in a bunch of extensions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6548
diff changeset
    30
  to = recipient1, recipient2, ...
53465a7464e2 convert comments to docstrings in a bunch of extensions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6548
diff changeset
    31
  cc = cc1, cc2, ...
53465a7464e2 convert comments to docstrings in a bunch of extensions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6548
diff changeset
    32
  bcc = bcc1, bcc2, ...
11150
f66ca4431eb9 patchbomb: Reply-To support
Cédric Duval <cedricduval@free.fr>
parents: 10973
diff changeset
    33
  reply-to = address1, address2, ...
6666
53465a7464e2 convert comments to docstrings in a bunch of extensions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6548
diff changeset
    34
10284
b08ffd27dfc8 patchbomb: document [patchbomb] config section for addresses
Christian Ebert <blacktrash@gmx.net>
parents: 10263
diff changeset
    35
Use ``[patchbomb]`` as configuration section name if you need to
b08ffd27dfc8 patchbomb: document [patchbomb] config section for addresses
Christian Ebert <blacktrash@gmx.net>
parents: 10263
diff changeset
    36
override global ``[email]`` address settings.
b08ffd27dfc8 patchbomb: document [patchbomb] config section for addresses
Christian Ebert <blacktrash@gmx.net>
parents: 10263
diff changeset
    37
10973
49a07f441496 Use hg role in help strings
Martin Geisler <mg@aragost.com>
parents: 10734
diff changeset
    38
Then you can use the :hg:`email` command to mail a series of
49a07f441496 Use hg role in help strings
Martin Geisler <mg@aragost.com>
parents: 10734
diff changeset
    39
changesets as a patchbomb.
6666
53465a7464e2 convert comments to docstrings in a bunch of extensions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6548
diff changeset
    40
9269
1d6499adf211 patchbomb: wrap docstrings at 70 characters
Martin Geisler <mg@lazybytes.net>
parents: 9214
diff changeset
    41
You can also either configure the method option in the email section
1d6499adf211 patchbomb: wrap docstrings at 70 characters
Martin Geisler <mg@lazybytes.net>
parents: 9214
diff changeset
    42
to be a sendmail compatible mailer or fill out the [smtp] section so
1d6499adf211 patchbomb: wrap docstrings at 70 characters
Martin Geisler <mg@lazybytes.net>
parents: 9214
diff changeset
    43
that the patchbomb extension can automatically send patchbombs
1d6499adf211 patchbomb: wrap docstrings at 70 characters
Martin Geisler <mg@lazybytes.net>
parents: 9214
diff changeset
    44
directly from the commandline. See the [email] and [smtp] sections in
1d6499adf211 patchbomb: wrap docstrings at 70 characters
Martin Geisler <mg@lazybytes.net>
parents: 9214
diff changeset
    45
hgrc(5) for details.
23487
c14af817ab76 patchbomb: add a 'patchbomb.intro' option
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23486
diff changeset
    46
27697
0ce0cfee497f patchbomb: treat empty address list as no addresses
Bryan O'Sullivan <bos@serpentine.com>
parents: 27150
diff changeset
    47
By default, :hg:`email` will prompt for a ``To`` or ``CC`` header if
0ce0cfee497f patchbomb: treat empty address list as no addresses
Bryan O'Sullivan <bos@serpentine.com>
parents: 27150
diff changeset
    48
you do not supply one via configuration or the command line.  You can
0ce0cfee497f patchbomb: treat empty address list as no addresses
Bryan O'Sullivan <bos@serpentine.com>
parents: 27150
diff changeset
    49
override this to never prompt by configuring an empty value::
0ce0cfee497f patchbomb: treat empty address list as no addresses
Bryan O'Sullivan <bos@serpentine.com>
parents: 27150
diff changeset
    50
0ce0cfee497f patchbomb: treat empty address list as no addresses
Bryan O'Sullivan <bos@serpentine.com>
parents: 27150
diff changeset
    51
  [email]
0ce0cfee497f patchbomb: treat empty address list as no addresses
Bryan O'Sullivan <bos@serpentine.com>
parents: 27150
diff changeset
    52
  cc =
0ce0cfee497f patchbomb: treat empty address list as no addresses
Bryan O'Sullivan <bos@serpentine.com>
parents: 27150
diff changeset
    53
23487
c14af817ab76 patchbomb: add a 'patchbomb.intro' option
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23486
diff changeset
    54
You can control the default inclusion of an introduction message with the
c14af817ab76 patchbomb: add a 'patchbomb.intro' option
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23486
diff changeset
    55
``patchbomb.intro`` configuration option. The configuration is always
c14af817ab76 patchbomb: add a 'patchbomb.intro' option
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23486
diff changeset
    56
overwritten by command line flags like --intro and --desc::
c14af817ab76 patchbomb: add a 'patchbomb.intro' option
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23486
diff changeset
    57
c14af817ab76 patchbomb: add a 'patchbomb.intro' option
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23486
diff changeset
    58
  [patchbomb]
c14af817ab76 patchbomb: add a 'patchbomb.intro' option
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23486
diff changeset
    59
  intro=auto   # include introduction message if more than 1 patch (default)
c14af817ab76 patchbomb: add a 'patchbomb.intro' option
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23486
diff changeset
    60
  intro=never  # never include an introduction message
c14af817ab76 patchbomb: add a 'patchbomb.intro' option
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23486
diff changeset
    61
  intro=always # always include an introduction message
23488
11b215731e74 patchbomb: introduce a 'patchbomb.confirm' option
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23487
diff changeset
    62
31187
6b8e1a08ef1d patchbomb: add config knob to generate flags by template (issue5354)
Yuya Nishihara <yuya@tcha.org>
parents: 31186
diff changeset
    63
You can specify a template for flags to be added in subject prefixes. Flags
6b8e1a08ef1d patchbomb: add config knob to generate flags by template (issue5354)
Yuya Nishihara <yuya@tcha.org>
parents: 31186
diff changeset
    64
specified by --flag option are exported as ``{flags}`` keyword::
6b8e1a08ef1d patchbomb: add config knob to generate flags by template (issue5354)
Yuya Nishihara <yuya@tcha.org>
parents: 31186
diff changeset
    65
6b8e1a08ef1d patchbomb: add config knob to generate flags by template (issue5354)
Yuya Nishihara <yuya@tcha.org>
parents: 31186
diff changeset
    66
  [patchbomb]
6b8e1a08ef1d patchbomb: add config knob to generate flags by template (issue5354)
Yuya Nishihara <yuya@tcha.org>
parents: 31186
diff changeset
    67
  flagtemplate = "{separate(' ',
6b8e1a08ef1d patchbomb: add config knob to generate flags by template (issue5354)
Yuya Nishihara <yuya@tcha.org>
parents: 31186
diff changeset
    68
                            ifeq(branch, 'default', '', branch|upper),
6b8e1a08ef1d patchbomb: add config knob to generate flags by template (issue5354)
Yuya Nishihara <yuya@tcha.org>
parents: 31186
diff changeset
    69
                            flags)}"
6b8e1a08ef1d patchbomb: add config knob to generate flags by template (issue5354)
Yuya Nishihara <yuya@tcha.org>
parents: 31186
diff changeset
    70
23488
11b215731e74 patchbomb: introduce a 'patchbomb.confirm' option
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23487
diff changeset
    71
You can set patchbomb to always ask for confirmation by setting
11b215731e74 patchbomb: introduce a 'patchbomb.confirm' option
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23487
diff changeset
    72
``patchbomb.confirm`` to true.
9071
141e3ef20d84 patchbomb: wrapped docstrings at 78 characters
Martin Geisler <mg@lazybytes.net>
parents: 9047
diff changeset
    73
'''
28415
21524ae331b7 patchbomb: use absolute_import
timeless <timeless@mozdev.org>
parents: 27767
diff changeset
    74
from __future__ import absolute_import
875
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    75
27150
88aaddb1af88 patchbomb: rename email function
timeless <timeless@mozdev.org>
parents: 26626
diff changeset
    76
import email as emailmod
36435
f449138a52df py3: use email.generator module instead of email.Generator
Pulkit Goyal <7895pulkit@gmail.com>
parents: 36410
diff changeset
    77
import email.generator as emailgen
36448
39c9f339b692 py3: use email.utils module instead of email.Utils
Pulkit Goyal <7895pulkit@gmail.com>
parents: 36446
diff changeset
    78
import email.utils as eutil
28415
21524ae331b7 patchbomb: use absolute_import
timeless <timeless@mozdev.org>
parents: 27767
diff changeset
    79
import errno
21524ae331b7 patchbomb: use absolute_import
timeless <timeless@mozdev.org>
parents: 27767
diff changeset
    80
import os
21524ae331b7 patchbomb: use absolute_import
timeless <timeless@mozdev.org>
parents: 27767
diff changeset
    81
import socket
19810
c80feeb715d1 python2.4: fix imports of sub-packages of the email package
Augie Fackler <raf@durin42.com>
parents: 19791
diff changeset
    82
29205
a0939666b836 py3: move up symbol imports to enforce import-checker rules
Yuya Nishihara <yuya@tcha.org>
parents: 28981
diff changeset
    83
from mercurial.i18n import _
28415
21524ae331b7 patchbomb: use absolute_import
timeless <timeless@mozdev.org>
parents: 27767
diff changeset
    84
from mercurial import (
21524ae331b7 patchbomb: use absolute_import
timeless <timeless@mozdev.org>
parents: 27767
diff changeset
    85
    cmdutil,
21524ae331b7 patchbomb: use absolute_import
timeless <timeless@mozdev.org>
parents: 27767
diff changeset
    86
    commands,
36449
a918c996a881 py3: use encoding.strtolocal() to convert str to bytes
Pulkit Goyal <7895pulkit@gmail.com>
parents: 36448
diff changeset
    87
    encoding,
28415
21524ae331b7 patchbomb: use absolute_import
timeless <timeless@mozdev.org>
parents: 27767
diff changeset
    88
    error,
31187
6b8e1a08ef1d patchbomb: add config knob to generate flags by template (issue5354)
Yuya Nishihara <yuya@tcha.org>
parents: 31186
diff changeset
    89
    formatter,
28415
21524ae331b7 patchbomb: use absolute_import
timeless <timeless@mozdev.org>
parents: 27767
diff changeset
    90
    hg,
21524ae331b7 patchbomb: use absolute_import
timeless <timeless@mozdev.org>
parents: 27767
diff changeset
    91
    mail,
21524ae331b7 patchbomb: use absolute_import
timeless <timeless@mozdev.org>
parents: 27767
diff changeset
    92
    node as nodemod,
21524ae331b7 patchbomb: use absolute_import
timeless <timeless@mozdev.org>
parents: 27767
diff changeset
    93
    patch,
35044
71e63fe6b1ab py3: handle keyword arguments correctly in hgext/patchbomb.py
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34911
diff changeset
    94
    pycompat,
32337
46ba2cdda476 registrar: move cmdutil.command to registrar module (API)
Yuya Nishihara <yuya@tcha.org>
parents: 31490
diff changeset
    95
    registrar,
28415
21524ae331b7 patchbomb: use absolute_import
timeless <timeless@mozdev.org>
parents: 27767
diff changeset
    96
    scmutil,
31187
6b8e1a08ef1d patchbomb: add config knob to generate flags by template (issue5354)
Yuya Nishihara <yuya@tcha.org>
parents: 31186
diff changeset
    97
    templater,
28415
21524ae331b7 patchbomb: use absolute_import
timeless <timeless@mozdev.org>
parents: 27767
diff changeset
    98
    util,
21524ae331b7 patchbomb: use absolute_import
timeless <timeless@mozdev.org>
parents: 27767
diff changeset
    99
)
36607
c6061cadb400 util: extract all date-related utils in utils/dateutil module
Boris Feld <boris.feld@octobus.net>
parents: 36450
diff changeset
   100
from mercurial.utils import dateutil
28861
86db5cb55d46 pycompat: switch to util.stringio for py3 compat
timeless <timeless@mozdev.org>
parents: 28474
diff changeset
   101
stringio = util.stringio
875
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   102
14309
37e80214badf patchbomb: use cmdutil.command decorator
Adrian Buehlmann <adrian@cadifra.com>
parents: 14290
diff changeset
   103
cmdtable = {}
32337
46ba2cdda476 registrar: move cmdutil.command to registrar module (API)
Yuya Nishihara <yuya@tcha.org>
parents: 31490
diff changeset
   104
command = registrar.command(cmdtable)
34111
798b679680aa configitems: register the 'patchbomb.bundletype' config
Boris Feld <boris.feld@octobus.net>
parents: 34029
diff changeset
   105
798b679680aa configitems: register the 'patchbomb.bundletype' config
Boris Feld <boris.feld@octobus.net>
parents: 34029
diff changeset
   106
configtable = {}
798b679680aa configitems: register the 'patchbomb.bundletype' config
Boris Feld <boris.feld@octobus.net>
parents: 34029
diff changeset
   107
configitem = registrar.configitem(configtable)
798b679680aa configitems: register the 'patchbomb.bundletype' config
Boris Feld <boris.feld@octobus.net>
parents: 34029
diff changeset
   108
798b679680aa configitems: register the 'patchbomb.bundletype' config
Boris Feld <boris.feld@octobus.net>
parents: 34029
diff changeset
   109
configitem('patchbomb', 'bundletype',
798b679680aa configitems: register the 'patchbomb.bundletype' config
Boris Feld <boris.feld@octobus.net>
parents: 34029
diff changeset
   110
    default=None,
798b679680aa configitems: register the 'patchbomb.bundletype' config
Boris Feld <boris.feld@octobus.net>
parents: 34029
diff changeset
   111
)
34760
3819809198c6 configitems: register the 'patchbomb.bcc' config
Boris Feld <boris.feld@octobus.net>
parents: 34116
diff changeset
   112
configitem('patchbomb', 'bcc',
3819809198c6 configitems: register the 'patchbomb.bcc' config
Boris Feld <boris.feld@octobus.net>
parents: 34116
diff changeset
   113
    default=None,
3819809198c6 configitems: register the 'patchbomb.bcc' config
Boris Feld <boris.feld@octobus.net>
parents: 34116
diff changeset
   114
)
34761
cb1ea7ef773d configitems: register the 'patchbomb.cc' config
Boris Feld <boris.feld@octobus.net>
parents: 34760
diff changeset
   115
configitem('patchbomb', 'cc',
cb1ea7ef773d configitems: register the 'patchbomb.cc' config
Boris Feld <boris.feld@octobus.net>
parents: 34760
diff changeset
   116
    default=None,
cb1ea7ef773d configitems: register the 'patchbomb.cc' config
Boris Feld <boris.feld@octobus.net>
parents: 34760
diff changeset
   117
)
34112
4ec0029b76e8 configitems: register the 'patchbomb.confirm' config
Boris Feld <boris.feld@octobus.net>
parents: 34111
diff changeset
   118
configitem('patchbomb', 'confirm',
4ec0029b76e8 configitems: register the 'patchbomb.confirm' config
Boris Feld <boris.feld@octobus.net>
parents: 34111
diff changeset
   119
    default=False,
4ec0029b76e8 configitems: register the 'patchbomb.confirm' config
Boris Feld <boris.feld@octobus.net>
parents: 34111
diff changeset
   120
)
34113
a6fa5af781a4 configitems: register the 'patchbomb.flagtemplate' config
Boris Feld <boris.feld@octobus.net>
parents: 34112
diff changeset
   121
configitem('patchbomb', 'flagtemplate',
a6fa5af781a4 configitems: register the 'patchbomb.flagtemplate' config
Boris Feld <boris.feld@octobus.net>
parents: 34112
diff changeset
   122
    default=None,
a6fa5af781a4 configitems: register the 'patchbomb.flagtemplate' config
Boris Feld <boris.feld@octobus.net>
parents: 34112
diff changeset
   123
)
34114
7e2adac3dd60 configitems: register the 'patchbomb.from' config
Boris Feld <boris.feld@octobus.net>
parents: 34113
diff changeset
   124
configitem('patchbomb', 'from',
7e2adac3dd60 configitems: register the 'patchbomb.from' config
Boris Feld <boris.feld@octobus.net>
parents: 34113
diff changeset
   125
    default=None,
7e2adac3dd60 configitems: register the 'patchbomb.from' config
Boris Feld <boris.feld@octobus.net>
parents: 34113
diff changeset
   126
)
34115
97a3bb5aff25 configitems: register the 'patchbomb.intro' config
Boris Feld <boris.feld@octobus.net>
parents: 34114
diff changeset
   127
configitem('patchbomb', 'intro',
97a3bb5aff25 configitems: register the 'patchbomb.intro' config
Boris Feld <boris.feld@octobus.net>
parents: 34114
diff changeset
   128
    default='auto',
97a3bb5aff25 configitems: register the 'patchbomb.intro' config
Boris Feld <boris.feld@octobus.net>
parents: 34114
diff changeset
   129
)
34116
aeb956e7729f configitems: register the 'patchbomb.publicurl' config
Boris Feld <boris.feld@octobus.net>
parents: 34115
diff changeset
   130
configitem('patchbomb', 'publicurl',
aeb956e7729f configitems: register the 'patchbomb.publicurl' config
Boris Feld <boris.feld@octobus.net>
parents: 34115
diff changeset
   131
    default=None,
aeb956e7729f configitems: register the 'patchbomb.publicurl' config
Boris Feld <boris.feld@octobus.net>
parents: 34115
diff changeset
   132
)
34762
9223a437fdb6 configitems: register the 'patchbomb.reply-to' config
Boris Feld <boris.feld@octobus.net>
parents: 34761
diff changeset
   133
configitem('patchbomb', 'reply-to',
9223a437fdb6 configitems: register the 'patchbomb.reply-to' config
Boris Feld <boris.feld@octobus.net>
parents: 34761
diff changeset
   134
    default=None,
9223a437fdb6 configitems: register the 'patchbomb.reply-to' config
Boris Feld <boris.feld@octobus.net>
parents: 34761
diff changeset
   135
)
34911
645b6684cf5b configitems: register 'email.to' and 'patchbomb.to'
Yuya Nishihara <yuya@tcha.org>
parents: 34762
diff changeset
   136
configitem('patchbomb', 'to',
645b6684cf5b configitems: register 'email.to' and 'patchbomb.to'
Yuya Nishihara <yuya@tcha.org>
parents: 34762
diff changeset
   137
    default=None,
645b6684cf5b configitems: register 'email.to' and 'patchbomb.to'
Yuya Nishihara <yuya@tcha.org>
parents: 34762
diff changeset
   138
)
34111
798b679680aa configitems: register the 'patchbomb.bundletype' config
Boris Feld <boris.feld@octobus.net>
parents: 34029
diff changeset
   139
29841
d5883fd055c6 extensions: change magic "shipped with hg" string
Augie Fackler <augie@google.com>
parents: 29285
diff changeset
   140
# Note for extension authors: ONLY specify testedwith = 'ships-with-hg-core' for
25186
80c5b2666a96 extensions: document that `testedwith = 'internal'` is special
Augie Fackler <augie@google.com>
parents: 24568
diff changeset
   141
# extensions which SHIP WITH MERCURIAL. Non-mainline extensions should
80c5b2666a96 extensions: document that `testedwith = 'internal'` is special
Augie Fackler <augie@google.com>
parents: 24568
diff changeset
   142
# be specifying the version(s) of Mercurial they are tested with, or
80c5b2666a96 extensions: document that `testedwith = 'internal'` is special
Augie Fackler <augie@google.com>
parents: 24568
diff changeset
   143
# leave the attribute unspecified.
29841
d5883fd055c6 extensions: change magic "shipped with hg" string
Augie Fackler <augie@google.com>
parents: 29285
diff changeset
   144
testedwith = 'ships-with-hg-core'
14309
37e80214badf patchbomb: use cmdutil.command decorator
Adrian Buehlmann <adrian@cadifra.com>
parents: 14290
diff changeset
   145
26546
500386e65759 patchbomb: add experimental config of a "pullurl" and export it
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25826
diff changeset
   146
def _addpullheader(seq, ctx):
500386e65759 patchbomb: add experimental config of a "pullurl" and export it
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25826
diff changeset
   147
    """Add a header pointing to a public URL where the changeset is available
500386e65759 patchbomb: add experimental config of a "pullurl" and export it
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25826
diff changeset
   148
    """
500386e65759 patchbomb: add experimental config of a "pullurl" and export it
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25826
diff changeset
   149
    repo = ctx.repo()
500386e65759 patchbomb: add experimental config of a "pullurl" and export it
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25826
diff changeset
   150
    # experimental config: patchbomb.publicurl
500386e65759 patchbomb: add experimental config of a "pullurl" and export it
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25826
diff changeset
   151
    # waiting for some logic that check that the changeset are available on the
500386e65759 patchbomb: add experimental config of a "pullurl" and export it
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25826
diff changeset
   152
    # destination before patchbombing anything.
32824
d3b2d4587e73 patchbomb: make variable name for publicurl always be publicurl
Augie Fackler <augie@google.com>
parents: 32695
diff changeset
   153
    publicurl = repo.ui.config('patchbomb', 'publicurl')
32825
16ff5c6066a6 patchbomb: look for non-empty publicurl, not a non-None one
Augie Fackler <augie@google.com>
parents: 32824
diff changeset
   154
    if publicurl:
26546
500386e65759 patchbomb: add experimental config of a "pullurl" and export it
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25826
diff changeset
   155
        return ('Available At %s\n'
32824
d3b2d4587e73 patchbomb: make variable name for publicurl always be publicurl
Augie Fackler <augie@google.com>
parents: 32695
diff changeset
   156
                '#              hg pull %s -r %s' % (publicurl, publicurl, ctx))
26546
500386e65759 patchbomb: add experimental config of a "pullurl" and export it
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25826
diff changeset
   157
    return None
500386e65759 patchbomb: add experimental config of a "pullurl" and export it
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25826
diff changeset
   158
500386e65759 patchbomb: add experimental config of a "pullurl" and export it
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25826
diff changeset
   159
def uisetup(ui):
500386e65759 patchbomb: add experimental config of a "pullurl" and export it
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25826
diff changeset
   160
    cmdutil.extraexport.append('pullurl')
500386e65759 patchbomb: add experimental config of a "pullurl" and export it
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25826
diff changeset
   161
    cmdutil.extraexportmap['pullurl'] = _addpullheader
500386e65759 patchbomb: add experimental config of a "pullurl" and export it
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25826
diff changeset
   162
33436
9bb4decd43b0 repovfs: add a ward to check if locks are properly taken
Boris Feld <boris.feld@octobus.net>
parents: 32826
diff changeset
   163
def reposetup(ui, repo):
9bb4decd43b0 repovfs: add a ward to check if locks are properly taken
Boris Feld <boris.feld@octobus.net>
parents: 32826
diff changeset
   164
    if not repo.local():
9bb4decd43b0 repovfs: add a ward to check if locks are properly taken
Boris Feld <boris.feld@octobus.net>
parents: 32826
diff changeset
   165
        return
9bb4decd43b0 repovfs: add a ward to check if locks are properly taken
Boris Feld <boris.feld@octobus.net>
parents: 32826
diff changeset
   166
    repo._wlockfreeprefix.add('last-email.txt')
26546
500386e65759 patchbomb: add experimental config of a "pullurl" and export it
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25826
diff changeset
   167
9648
6064de41b7e4 patchbomb: accept default if it is empty string
Alexander Solovyov <piranha@piranha.org.ua>
parents: 9647
diff changeset
   168
def prompt(ui, prompt, default=None, rest=':'):
7354
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
   169
    if default:
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
   170
        prompt += ' [%s]' % default
15166
9ec9dd8d1b24 patchbomb: drop loop in prompt
Matt Mackall <mpm@selenic.com>
parents: 15165
diff changeset
   171
    return ui.prompt(prompt + rest, default)
7354
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
   172
23487
c14af817ab76 patchbomb: add a 'patchbomb.intro' option
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23486
diff changeset
   173
def introwanted(ui, opts, number):
15164
7bddec632821 patchbomb: make it easy for the user to decline sending an intro message.
Greg Ward <greg@gerg.ca>
parents: 15162
diff changeset
   174
    '''is an introductory message apparently wanted?'''
34115
97a3bb5aff25 configitems: register the 'patchbomb.intro' config
Boris Feld <boris.feld@octobus.net>
parents: 34114
diff changeset
   175
    introconfig = ui.config('patchbomb', 'intro')
23487
c14af817ab76 patchbomb: add a 'patchbomb.intro' option
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23486
diff changeset
   176
    if opts.get('intro') or opts.get('desc'):
c14af817ab76 patchbomb: add a 'patchbomb.intro' option
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23486
diff changeset
   177
        intro = True
c14af817ab76 patchbomb: add a 'patchbomb.intro' option
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23486
diff changeset
   178
    elif introconfig == 'always':
c14af817ab76 patchbomb: add a 'patchbomb.intro' option
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23486
diff changeset
   179
        intro = True
c14af817ab76 patchbomb: add a 'patchbomb.intro' option
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23486
diff changeset
   180
    elif introconfig == 'never':
c14af817ab76 patchbomb: add a 'patchbomb.intro' option
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23486
diff changeset
   181
        intro = False
c14af817ab76 patchbomb: add a 'patchbomb.intro' option
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23486
diff changeset
   182
    elif introconfig == 'auto':
c14af817ab76 patchbomb: add a 'patchbomb.intro' option
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23486
diff changeset
   183
        intro = 1 < number
c14af817ab76 patchbomb: add a 'patchbomb.intro' option
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23486
diff changeset
   184
    else:
c14af817ab76 patchbomb: add a 'patchbomb.intro' option
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23486
diff changeset
   185
        ui.write_err(_('warning: invalid patchbomb.intro value "%s"\n')
c14af817ab76 patchbomb: add a 'patchbomb.intro' option
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23486
diff changeset
   186
                     % introconfig)
c14af817ab76 patchbomb: add a 'patchbomb.intro' option
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23486
diff changeset
   187
        ui.write_err(_('(should be one of always, never, auto)\n'))
c14af817ab76 patchbomb: add a 'patchbomb.intro' option
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23486
diff changeset
   188
        intro = 1 < number
c14af817ab76 patchbomb: add a 'patchbomb.intro' option
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23486
diff changeset
   189
    return intro
10734
7a0502a6f9a1 patchbomb: --desc implies --intro
Cédric Duval <cedricduval@free.fr>
parents: 10611
diff changeset
   190
31187
6b8e1a08ef1d patchbomb: add config knob to generate flags by template (issue5354)
Yuya Nishihara <yuya@tcha.org>
parents: 31186
diff changeset
   191
def _formatflags(ui, repo, rev, flags):
6b8e1a08ef1d patchbomb: add config knob to generate flags by template (issue5354)
Yuya Nishihara <yuya@tcha.org>
parents: 31186
diff changeset
   192
    """build flag string optionally by template"""
6b8e1a08ef1d patchbomb: add config knob to generate flags by template (issue5354)
Yuya Nishihara <yuya@tcha.org>
parents: 31186
diff changeset
   193
    tmpl = ui.config('patchbomb', 'flagtemplate')
6b8e1a08ef1d patchbomb: add config knob to generate flags by template (issue5354)
Yuya Nishihara <yuya@tcha.org>
parents: 31186
diff changeset
   194
    if not tmpl:
6b8e1a08ef1d patchbomb: add config knob to generate flags by template (issue5354)
Yuya Nishihara <yuya@tcha.org>
parents: 31186
diff changeset
   195
        return ' '.join(flags)
6b8e1a08ef1d patchbomb: add config knob to generate flags by template (issue5354)
Yuya Nishihara <yuya@tcha.org>
parents: 31186
diff changeset
   196
    out = util.stringio()
6b8e1a08ef1d patchbomb: add config knob to generate flags by template (issue5354)
Yuya Nishihara <yuya@tcha.org>
parents: 31186
diff changeset
   197
    opts = {'template': templater.unquotestring(tmpl)}
6b8e1a08ef1d patchbomb: add config knob to generate flags by template (issue5354)
Yuya Nishihara <yuya@tcha.org>
parents: 31186
diff changeset
   198
    with formatter.templateformatter(ui, out, 'patchbombflag', opts) as fm:
6b8e1a08ef1d patchbomb: add config knob to generate flags by template (issue5354)
Yuya Nishihara <yuya@tcha.org>
parents: 31186
diff changeset
   199
        fm.startitem()
6b8e1a08ef1d patchbomb: add config knob to generate flags by template (issue5354)
Yuya Nishihara <yuya@tcha.org>
parents: 31186
diff changeset
   200
        fm.context(ctx=repo[rev])
6b8e1a08ef1d patchbomb: add config knob to generate flags by template (issue5354)
Yuya Nishihara <yuya@tcha.org>
parents: 31186
diff changeset
   201
        fm.write('flags', '%s', fm.formatlist(flags, name='flag'))
6b8e1a08ef1d patchbomb: add config knob to generate flags by template (issue5354)
Yuya Nishihara <yuya@tcha.org>
parents: 31186
diff changeset
   202
    return out.getvalue()
6b8e1a08ef1d patchbomb: add config knob to generate flags by template (issue5354)
Yuya Nishihara <yuya@tcha.org>
parents: 31186
diff changeset
   203
31186
83fa357edbd5 patchbomb: pass around ui and revs that are needed for flag template
Yuya Nishihara <yuya@tcha.org>
parents: 31185
diff changeset
   204
def _formatprefix(ui, repo, rev, flags, idx, total, numbered):
31183
8018b90f8307 patchbomb: factor out function that builds a prefix string to patch subject
Yuya Nishihara <yuya@tcha.org>
parents: 30848
diff changeset
   205
    """build prefix to patch subject"""
31187
6b8e1a08ef1d patchbomb: add config knob to generate flags by template (issue5354)
Yuya Nishihara <yuya@tcha.org>
parents: 31186
diff changeset
   206
    flag = _formatflags(ui, repo, rev, flags)
31183
8018b90f8307 patchbomb: factor out function that builds a prefix string to patch subject
Yuya Nishihara <yuya@tcha.org>
parents: 30848
diff changeset
   207
    if flag:
8018b90f8307 patchbomb: factor out function that builds a prefix string to patch subject
Yuya Nishihara <yuya@tcha.org>
parents: 30848
diff changeset
   208
        flag = ' ' + flag
8018b90f8307 patchbomb: factor out function that builds a prefix string to patch subject
Yuya Nishihara <yuya@tcha.org>
parents: 30848
diff changeset
   209
8018b90f8307 patchbomb: factor out function that builds a prefix string to patch subject
Yuya Nishihara <yuya@tcha.org>
parents: 30848
diff changeset
   210
    if not numbered:
8018b90f8307 patchbomb: factor out function that builds a prefix string to patch subject
Yuya Nishihara <yuya@tcha.org>
parents: 30848
diff changeset
   211
        return '[PATCH%s]' % flag
8018b90f8307 patchbomb: factor out function that builds a prefix string to patch subject
Yuya Nishihara <yuya@tcha.org>
parents: 30848
diff changeset
   212
    else:
36668
e77cee5de1c7 py3: use b"%d" to covert integer to bytes instead of str
Pulkit Goyal <7895pulkit@gmail.com>
parents: 36607
diff changeset
   213
        tlen = len("%d" % total)
31183
8018b90f8307 patchbomb: factor out function that builds a prefix string to patch subject
Yuya Nishihara <yuya@tcha.org>
parents: 30848
diff changeset
   214
        return '[PATCH %0*d of %d%s]' % (tlen, idx, total, flag)
8018b90f8307 patchbomb: factor out function that builds a prefix string to patch subject
Yuya Nishihara <yuya@tcha.org>
parents: 30848
diff changeset
   215
31186
83fa357edbd5 patchbomb: pass around ui and revs that are needed for flag template
Yuya Nishihara <yuya@tcha.org>
parents: 31185
diff changeset
   216
def makepatch(ui, repo, rev, patchlines, opts, _charsets, idx, total, numbered,
12199
17d604e522b4 patchbomb: rename argument to avoid shadowing patch module
Martin Geisler <mg@lazybytes.net>
parents: 12197
diff changeset
   217
              patchname=None):
7354
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
   218
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
   219
    desc = []
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
   220
    node = None
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
   221
    body = ''
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
   222
12199
17d604e522b4 patchbomb: rename argument to avoid shadowing patch module
Martin Geisler <mg@lazybytes.net>
parents: 12197
diff changeset
   223
    for line in patchlines:
7354
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
   224
        if line.startswith('#'):
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
   225
            if line.startswith('# Node ID'):
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
   226
                node = line.split()[-1]
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
   227
            continue
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
   228
        if line.startswith('diff -r') or line.startswith('diff --git'):
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
   229
            break
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
   230
        desc.append(line)
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
   231
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
   232
    if not patchname and not node:
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
   233
        raise ValueError
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
   234
16307
17a9a1f5cee2 patchbomb: add --body flag to send patches as inline message body text
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16233
diff changeset
   235
    if opts.get('attach') and not opts.get('body'):
7354
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
   236
        body = ('\n'.join(desc[1:]).strip() or
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
   237
                'Patch subject is complete summary.')
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
   238
        body += '\n\n\n'
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
   239
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
   240
    if opts.get('plain'):
12199
17d604e522b4 patchbomb: rename argument to avoid shadowing patch module
Martin Geisler <mg@lazybytes.net>
parents: 12197
diff changeset
   241
        while patchlines and patchlines[0].startswith('# '):
17d604e522b4 patchbomb: rename argument to avoid shadowing patch module
Martin Geisler <mg@lazybytes.net>
parents: 12197
diff changeset
   242
            patchlines.pop(0)
17d604e522b4 patchbomb: rename argument to avoid shadowing patch module
Martin Geisler <mg@lazybytes.net>
parents: 12197
diff changeset
   243
        if patchlines:
17d604e522b4 patchbomb: rename argument to avoid shadowing patch module
Martin Geisler <mg@lazybytes.net>
parents: 12197
diff changeset
   244
            patchlines.pop(0)
17d604e522b4 patchbomb: rename argument to avoid shadowing patch module
Martin Geisler <mg@lazybytes.net>
parents: 12197
diff changeset
   245
        while patchlines and not patchlines[0].strip():
17d604e522b4 patchbomb: rename argument to avoid shadowing patch module
Martin Geisler <mg@lazybytes.net>
parents: 12197
diff changeset
   246
            patchlines.pop(0)
7354
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
   247
30407
e1677cc29da6 patch: remove unused git parameter from patch.diffstat()
Henning Schild <henning@hennsch.de>
parents: 29841
diff changeset
   248
    ds = patch.diffstat(patchlines)
7354
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
   249
    if opts.get('diffstat'):
12200
aebb39d45500 patchbomb: let diffstat prompt only once with complete summary
Christian Ebert <blacktrash@gmx.net>
parents: 12199
diff changeset
   250
        body += ds + '\n\n'
7354
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
   251
16307
17a9a1f5cee2 patchbomb: add --body flag to send patches as inline message body text
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16233
diff changeset
   252
    addattachment = opts.get('attach') or opts.get('inline')
17a9a1f5cee2 patchbomb: add --body flag to send patches as inline message body text
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16233
diff changeset
   253
    if not addattachment or opts.get('body'):
17a9a1f5cee2 patchbomb: add --body flag to send patches as inline message body text
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16233
diff changeset
   254
        body += '\n'.join(patchlines)
17a9a1f5cee2 patchbomb: add --body flag to send patches as inline message body text
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16233
diff changeset
   255
17a9a1f5cee2 patchbomb: add --body flag to send patches as inline message body text
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16233
diff changeset
   256
    if addattachment:
27150
88aaddb1af88 patchbomb: rename email function
timeless <timeless@mozdev.org>
parents: 26626
diff changeset
   257
        msg = emailmod.MIMEMultipart.MIMEMultipart()
7354
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
   258
        if body:
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
   259
            msg.attach(mail.mimeencode(ui, body, _charsets, opts.get('test')))
16683
525fdb738975 cleanup: eradicate long lines
Brodie Rao <brodie@sf.io>
parents: 16307
diff changeset
   260
        p = mail.mimetextpatch('\n'.join(patchlines), 'x-patch',
525fdb738975 cleanup: eradicate long lines
Brodie Rao <brodie@sf.io>
parents: 16307
diff changeset
   261
                               opts.get('test'))
28415
21524ae331b7 patchbomb: use absolute_import
timeless <timeless@mozdev.org>
parents: 27767
diff changeset
   262
        binnode = nodemod.bin(node)
8761
0289f384e1e5 Generally replace "file name" with "filename" in help and comments.
timeless <timeless@gmail.com>
parents: 8520
diff changeset
   263
        # if node is mq patch, it will have the patch file's name as a tag
7354
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
   264
        if not patchname:
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
   265
            patchtags = [t for t in repo.nodetags(binnode)
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
   266
                         if t.endswith('.patch') or t.endswith('.diff')]
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
   267
            if patchtags:
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
   268
                patchname = patchtags[0]
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
   269
            elif total > 1:
36204
33ed8b511185 cmdutil: pass ctx to makefilename() in place of repo/node pair (API)
Yuya Nishihara <yuya@tcha.org>
parents: 35674
diff changeset
   270
                patchname = cmdutil.makefilename(repo[node], '%b-%n.patch',
33ed8b511185 cmdutil: pass ctx to makefilename() in place of repo/node pair (API)
Yuya Nishihara <yuya@tcha.org>
parents: 35674
diff changeset
   271
                                                 seqno=idx, total=total)
7354
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
   272
            else:
36204
33ed8b511185 cmdutil: pass ctx to makefilename() in place of repo/node pair (API)
Yuya Nishihara <yuya@tcha.org>
parents: 35674
diff changeset
   273
                patchname = cmdutil.makefilename(repo[node], '%b.patch')
7354
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
   274
        disposition = 'inline'
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
   275
        if opts.get('attach'):
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
   276
            disposition = 'attachment'
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
   277
        p['Content-Disposition'] = disposition + '; filename=' + patchname
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
   278
        msg.attach(p)
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
   279
    else:
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
   280
        msg = mail.mimetextpatch(body, display=opts.get('test'))
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
   281
31186
83fa357edbd5 patchbomb: pass around ui and revs that are needed for flag template
Yuya Nishihara <yuya@tcha.org>
parents: 31185
diff changeset
   282
    prefix = _formatprefix(ui, repo, rev, opts.get('flag'), idx, total,
83fa357edbd5 patchbomb: pass around ui and revs that are needed for flag template
Yuya Nishihara <yuya@tcha.org>
parents: 31185
diff changeset
   283
                           numbered)
7354
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
   284
    subj = desc[0].strip().rstrip('. ')
15164
7bddec632821 patchbomb: make it easy for the user to decline sending an intro message.
Greg Ward <greg@gerg.ca>
parents: 15162
diff changeset
   285
    if not numbered:
31183
8018b90f8307 patchbomb: factor out function that builds a prefix string to patch subject
Yuya Nishihara <yuya@tcha.org>
parents: 30848
diff changeset
   286
        subj = ' '.join([prefix, opts.get('subject') or subj])
7354
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
   287
    else:
31183
8018b90f8307 patchbomb: factor out function that builds a prefix string to patch subject
Yuya Nishihara <yuya@tcha.org>
parents: 30848
diff changeset
   288
        subj = ' '.join([prefix, subj])
7354
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
   289
    msg['Subject'] = mail.headencode(ui, subj, _charsets, opts.get('test'))
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
   290
    msg['X-Mercurial-Node'] = node
21282
697fba94dec9 patchbomb: includes series information in the header
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21055
diff changeset
   291
    msg['X-Mercurial-Series-Index'] = '%i' % idx
697fba94dec9 patchbomb: includes series information in the header
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21055
diff changeset
   292
    msg['X-Mercurial-Series-Total'] = '%i' % total
12200
aebb39d45500 patchbomb: let diffstat prompt only once with complete summary
Christian Ebert <blacktrash@gmx.net>
parents: 12199
diff changeset
   293
    return msg, subj, ds
7354
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
   294
23210
79f7444520bf patchbomb: extract 'getpatches' closure in its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23173
diff changeset
   295
def _getpatches(repo, revs, **opts):
79f7444520bf patchbomb: extract 'getpatches' closure in its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23173
diff changeset
   296
    """return a list of patches for a list of revisions
79f7444520bf patchbomb: extract 'getpatches' closure in its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23173
diff changeset
   297
79f7444520bf patchbomb: extract 'getpatches' closure in its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23173
diff changeset
   298
    Each patch in the list is itself a list of lines.
79f7444520bf patchbomb: extract 'getpatches' closure in its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23173
diff changeset
   299
    """
79f7444520bf patchbomb: extract 'getpatches' closure in its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23173
diff changeset
   300
    ui = repo.ui
79f7444520bf patchbomb: extract 'getpatches' closure in its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23173
diff changeset
   301
    prev = repo['.'].rev()
24568
2e5f6cdf01f6 patchbomb: factor out scmutil.revrange() calls
Yuya Nishihara <yuya@tcha.org>
parents: 24567
diff changeset
   302
    for r in revs:
23210
79f7444520bf patchbomb: extract 'getpatches' closure in its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23173
diff changeset
   303
        if r == prev and (repo[None].files() or repo[None].deleted()):
79f7444520bf patchbomb: extract 'getpatches' closure in its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23173
diff changeset
   304
            ui.warn(_('warning: working directory has '
79f7444520bf patchbomb: extract 'getpatches' closure in its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23173
diff changeset
   305
                      'uncommitted changes\n'))
28861
86db5cb55d46 pycompat: switch to util.stringio for py3 compat
timeless <timeless@mozdev.org>
parents: 28474
diff changeset
   306
        output = stringio()
37603
678d760c71ff export: extract function to write patch to file object (API)
Yuya Nishihara <yuya@tcha.org>
parents: 36668
diff changeset
   307
        cmdutil.exportfile(repo, [r], output,
678d760c71ff export: extract function to write patch to file object (API)
Yuya Nishihara <yuya@tcha.org>
parents: 36668
diff changeset
   308
                           opts=patch.difffeatureopts(ui, opts, git=True))
23210
79f7444520bf patchbomb: extract 'getpatches' closure in its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23173
diff changeset
   309
        yield output.getvalue().split('\n')
23211
6993282e5362 patchbomb: extract 'getbundle' closure in its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23210
diff changeset
   310
def _getbundle(repo, dest, **opts):
6993282e5362 patchbomb: extract 'getbundle' closure in its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23210
diff changeset
   311
    """return a bundle containing changesets missing in "dest"
6993282e5362 patchbomb: extract 'getbundle' closure in its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23210
diff changeset
   312
6993282e5362 patchbomb: extract 'getbundle' closure in its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23210
diff changeset
   313
    The `opts` keyword-arguments are the same as the one accepted by the
6993282e5362 patchbomb: extract 'getbundle' closure in its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23210
diff changeset
   314
    `bundle` command.
6993282e5362 patchbomb: extract 'getbundle' closure in its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23210
diff changeset
   315
6993282e5362 patchbomb: extract 'getbundle' closure in its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23210
diff changeset
   316
    The bundle is a returned as a single in-memory binary blob.
6993282e5362 patchbomb: extract 'getbundle' closure in its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23210
diff changeset
   317
    """
6993282e5362 patchbomb: extract 'getbundle' closure in its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23210
diff changeset
   318
    ui = repo.ui
38165
2ce60954b1b7 py3: wrap tempfile.mkdtemp() to use bytes path
Yuya Nishihara <yuya@tcha.org>
parents: 38131
diff changeset
   319
    tmpdir = pycompat.mkdtemp(prefix='hg-email-bundle-')
23211
6993282e5362 patchbomb: extract 'getbundle' closure in its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23210
diff changeset
   320
    tmpfn = os.path.join(tmpdir, 'bundle')
26563
d4a1bfe1de63 patchbomb: add a 'bundletype' config under 'patchbomb'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26546
diff changeset
   321
    btype = ui.config('patchbomb', 'bundletype')
d4a1bfe1de63 patchbomb: add a 'bundletype' config under 'patchbomb'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26546
diff changeset
   322
    if btype:
35044
71e63fe6b1ab py3: handle keyword arguments correctly in hgext/patchbomb.py
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34911
diff changeset
   323
        opts[r'type'] = btype
23211
6993282e5362 patchbomb: extract 'getbundle' closure in its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23210
diff changeset
   324
    try:
6993282e5362 patchbomb: extract 'getbundle' closure in its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23210
diff changeset
   325
        commands.bundle(ui, repo, tmpfn, dest, **opts)
27767
ddfb8887212d patchbomb: replace file I/O with util.readfile
Bryan O'Sullivan <bryano@fb.com>
parents: 27697
diff changeset
   326
        return util.readfile(tmpfn)
23211
6993282e5362 patchbomb: extract 'getbundle' closure in its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23210
diff changeset
   327
    finally:
6993282e5362 patchbomb: extract 'getbundle' closure in its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23210
diff changeset
   328
        try:
6993282e5362 patchbomb: extract 'getbundle' closure in its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23210
diff changeset
   329
            os.unlink(tmpfn)
6993282e5362 patchbomb: extract 'getbundle' closure in its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23210
diff changeset
   330
        except OSError:
6993282e5362 patchbomb: extract 'getbundle' closure in its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23210
diff changeset
   331
            pass
6993282e5362 patchbomb: extract 'getbundle' closure in its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23210
diff changeset
   332
        os.rmdir(tmpdir)
6993282e5362 patchbomb: extract 'getbundle' closure in its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23210
diff changeset
   333
23212
4b4eae00f9dd patchbomb: extract 'getdescription' closure in its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23211
diff changeset
   334
def _getdescription(repo, defaultbody, sender, **opts):
4b4eae00f9dd patchbomb: extract 'getdescription' closure in its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23211
diff changeset
   335
    """obtain the body of the introduction message and return it
4b4eae00f9dd patchbomb: extract 'getdescription' closure in its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23211
diff changeset
   336
4b4eae00f9dd patchbomb: extract 'getdescription' closure in its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23211
diff changeset
   337
    This is also used for the body of email with an attached bundle.
4b4eae00f9dd patchbomb: extract 'getdescription' closure in its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23211
diff changeset
   338
4b4eae00f9dd patchbomb: extract 'getdescription' closure in its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23211
diff changeset
   339
    The body can be obtained either from the command line option or entered by
4b4eae00f9dd patchbomb: extract 'getdescription' closure in its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23211
diff changeset
   340
    the user through the editor.
4b4eae00f9dd patchbomb: extract 'getdescription' closure in its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23211
diff changeset
   341
    """
4b4eae00f9dd patchbomb: extract 'getdescription' closure in its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23211
diff changeset
   342
    ui = repo.ui
35044
71e63fe6b1ab py3: handle keyword arguments correctly in hgext/patchbomb.py
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34911
diff changeset
   343
    if opts.get(r'desc'):
71e63fe6b1ab py3: handle keyword arguments correctly in hgext/patchbomb.py
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34911
diff changeset
   344
        body = open(opts.get(r'desc')).read()
23212
4b4eae00f9dd patchbomb: extract 'getdescription' closure in its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23211
diff changeset
   345
    else:
4b4eae00f9dd patchbomb: extract 'getdescription' closure in its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23211
diff changeset
   346
        ui.write(_('\nWrite the introductory message for the '
4b4eae00f9dd patchbomb: extract 'getdescription' closure in its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23211
diff changeset
   347
                   'patch series.\n\n'))
34029
6e6452bc441d editor: use an unambiguous path suffix for editor files
Michael Bolin <mbolin@fb.com>
parents: 33436
diff changeset
   348
        body = ui.edit(defaultbody, sender, repopath=repo.path,
6e6452bc441d editor: use an unambiguous path suffix for editor files
Michael Bolin <mbolin@fb.com>
parents: 33436
diff changeset
   349
                       action='patchbombbody')
23212
4b4eae00f9dd patchbomb: extract 'getdescription' closure in its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23211
diff changeset
   350
        # Save series description in case sendmail fails
23877
7cc77030c557 localrepo: remove all external users of localrepo.opener
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 23488
diff changeset
   351
        msgfile = repo.vfs('last-email.txt', 'wb')
23212
4b4eae00f9dd patchbomb: extract 'getdescription' closure in its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23211
diff changeset
   352
        msgfile.write(body)
4b4eae00f9dd patchbomb: extract 'getdescription' closure in its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23211
diff changeset
   353
        msgfile.close()
4b4eae00f9dd patchbomb: extract 'getdescription' closure in its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23211
diff changeset
   354
    return body
23211
6993282e5362 patchbomb: extract 'getbundle' closure in its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23210
diff changeset
   355
23213
23a78662b6dd patchbomb: extract 'getbundlemsgs' closure in its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23212
diff changeset
   356
def _getbundlemsgs(repo, sender, bundle, **opts):
23a78662b6dd patchbomb: extract 'getbundlemsgs' closure in its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23212
diff changeset
   357
    """Get the full email for sending a given bundle
23a78662b6dd patchbomb: extract 'getbundlemsgs' closure in its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23212
diff changeset
   358
23a78662b6dd patchbomb: extract 'getbundlemsgs' closure in its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23212
diff changeset
   359
    This function returns a list of "email" tuples (subject, content, None).
23a78662b6dd patchbomb: extract 'getbundlemsgs' closure in its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23212
diff changeset
   360
    The list is always one message long in that case.
23a78662b6dd patchbomb: extract 'getbundlemsgs' closure in its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23212
diff changeset
   361
    """
23a78662b6dd patchbomb: extract 'getbundlemsgs' closure in its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23212
diff changeset
   362
    ui = repo.ui
23a78662b6dd patchbomb: extract 'getbundlemsgs' closure in its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23212
diff changeset
   363
    _charsets = mail._charsets(ui)
35044
71e63fe6b1ab py3: handle keyword arguments correctly in hgext/patchbomb.py
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34911
diff changeset
   364
    subj = (opts.get(r'subject')
23213
23a78662b6dd patchbomb: extract 'getbundlemsgs' closure in its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23212
diff changeset
   365
            or prompt(ui, 'Subject:', 'A bundle for your repository'))
23a78662b6dd patchbomb: extract 'getbundlemsgs' closure in its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23212
diff changeset
   366
23a78662b6dd patchbomb: extract 'getbundlemsgs' closure in its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23212
diff changeset
   367
    body = _getdescription(repo, '', sender, **opts)
27150
88aaddb1af88 patchbomb: rename email function
timeless <timeless@mozdev.org>
parents: 26626
diff changeset
   368
    msg = emailmod.MIMEMultipart.MIMEMultipart()
23213
23a78662b6dd patchbomb: extract 'getbundlemsgs' closure in its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23212
diff changeset
   369
    if body:
35044
71e63fe6b1ab py3: handle keyword arguments correctly in hgext/patchbomb.py
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34911
diff changeset
   370
        msg.attach(mail.mimeencode(ui, body, _charsets, opts.get(r'test')))
27150
88aaddb1af88 patchbomb: rename email function
timeless <timeless@mozdev.org>
parents: 26626
diff changeset
   371
    datapart = emailmod.MIMEBase.MIMEBase('application', 'x-mercurial-bundle')
23213
23a78662b6dd patchbomb: extract 'getbundlemsgs' closure in its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23212
diff changeset
   372
    datapart.set_payload(bundle)
35044
71e63fe6b1ab py3: handle keyword arguments correctly in hgext/patchbomb.py
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34911
diff changeset
   373
    bundlename = '%s.hg' % opts.get(r'bundlename', 'bundle')
23213
23a78662b6dd patchbomb: extract 'getbundlemsgs' closure in its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23212
diff changeset
   374
    datapart.add_header('Content-Disposition', 'attachment',
23a78662b6dd patchbomb: extract 'getbundlemsgs' closure in its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23212
diff changeset
   375
                        filename=bundlename)
27150
88aaddb1af88 patchbomb: rename email function
timeless <timeless@mozdev.org>
parents: 26626
diff changeset
   376
    emailmod.Encoders.encode_base64(datapart)
23213
23a78662b6dd patchbomb: extract 'getbundlemsgs' closure in its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23212
diff changeset
   377
    msg.attach(datapart)
35044
71e63fe6b1ab py3: handle keyword arguments correctly in hgext/patchbomb.py
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34911
diff changeset
   378
    msg['Subject'] = mail.headencode(ui, subj, _charsets, opts.get(r'test'))
23213
23a78662b6dd patchbomb: extract 'getbundlemsgs' closure in its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23212
diff changeset
   379
    return [(msg, subj, None)]
23a78662b6dd patchbomb: extract 'getbundlemsgs' closure in its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23212
diff changeset
   380
31186
83fa357edbd5 patchbomb: pass around ui and revs that are needed for flag template
Yuya Nishihara <yuya@tcha.org>
parents: 31185
diff changeset
   381
def _makeintro(repo, sender, revs, patches, **opts):
23214
563d33fc4b3d patchbomb: extract 'makeintro' closure into its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23213
diff changeset
   382
    """make an introduction email, asking the user for content if needed
563d33fc4b3d patchbomb: extract 'makeintro' closure into its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23213
diff changeset
   383
563d33fc4b3d patchbomb: extract 'makeintro' closure into its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23213
diff changeset
   384
    email is returned as (subject, body, cumulative-diffstat)"""
563d33fc4b3d patchbomb: extract 'makeintro' closure into its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23213
diff changeset
   385
    ui = repo.ui
563d33fc4b3d patchbomb: extract 'makeintro' closure into its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23213
diff changeset
   386
    _charsets = mail._charsets(ui)
563d33fc4b3d patchbomb: extract 'makeintro' closure into its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23213
diff changeset
   387
31186
83fa357edbd5 patchbomb: pass around ui and revs that are needed for flag template
Yuya Nishihara <yuya@tcha.org>
parents: 31185
diff changeset
   388
    # use the last revision which is likely to be a bookmarked head
35044
71e63fe6b1ab py3: handle keyword arguments correctly in hgext/patchbomb.py
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34911
diff changeset
   389
    prefix = _formatprefix(ui, repo, revs.last(), opts.get(r'flag'),
31186
83fa357edbd5 patchbomb: pass around ui and revs that are needed for flag template
Yuya Nishihara <yuya@tcha.org>
parents: 31185
diff changeset
   390
                           0, len(patches), numbered=True)
35044
71e63fe6b1ab py3: handle keyword arguments correctly in hgext/patchbomb.py
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34911
diff changeset
   391
    subj = (opts.get(r'subject') or
23214
563d33fc4b3d patchbomb: extract 'makeintro' closure into its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23213
diff changeset
   392
            prompt(ui, '(optional) Subject: ', rest=prefix, default=''))
563d33fc4b3d patchbomb: extract 'makeintro' closure into its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23213
diff changeset
   393
    if not subj:
563d33fc4b3d patchbomb: extract 'makeintro' closure into its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23213
diff changeset
   394
        return None         # skip intro if the user doesn't bother
563d33fc4b3d patchbomb: extract 'makeintro' closure into its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23213
diff changeset
   395
563d33fc4b3d patchbomb: extract 'makeintro' closure into its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23213
diff changeset
   396
    subj = prefix + ' ' + subj
563d33fc4b3d patchbomb: extract 'makeintro' closure into its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23213
diff changeset
   397
563d33fc4b3d patchbomb: extract 'makeintro' closure into its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23213
diff changeset
   398
    body = ''
35044
71e63fe6b1ab py3: handle keyword arguments correctly in hgext/patchbomb.py
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34911
diff changeset
   399
    if opts.get(r'diffstat'):
23214
563d33fc4b3d patchbomb: extract 'makeintro' closure into its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23213
diff changeset
   400
        # generate a cumulative diffstat of the whole patch series
563d33fc4b3d patchbomb: extract 'makeintro' closure into its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23213
diff changeset
   401
        diffstat = patch.diffstat(sum(patches, []))
563d33fc4b3d patchbomb: extract 'makeintro' closure into its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23213
diff changeset
   402
        body = '\n' + diffstat
563d33fc4b3d patchbomb: extract 'makeintro' closure into its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23213
diff changeset
   403
    else:
563d33fc4b3d patchbomb: extract 'makeintro' closure into its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23213
diff changeset
   404
        diffstat = None
563d33fc4b3d patchbomb: extract 'makeintro' closure into its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23213
diff changeset
   405
563d33fc4b3d patchbomb: extract 'makeintro' closure into its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23213
diff changeset
   406
    body = _getdescription(repo, body, sender, **opts)
35044
71e63fe6b1ab py3: handle keyword arguments correctly in hgext/patchbomb.py
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34911
diff changeset
   407
    msg = mail.mimeencode(ui, body, _charsets, opts.get(r'test'))
23214
563d33fc4b3d patchbomb: extract 'makeintro' closure into its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23213
diff changeset
   408
    msg['Subject'] = mail.headencode(ui, subj, _charsets,
35044
71e63fe6b1ab py3: handle keyword arguments correctly in hgext/patchbomb.py
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34911
diff changeset
   409
                                     opts.get(r'test'))
23214
563d33fc4b3d patchbomb: extract 'makeintro' closure into its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23213
diff changeset
   410
    return (msg, subj, diffstat)
563d33fc4b3d patchbomb: extract 'makeintro' closure into its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23213
diff changeset
   411
31185
bbb5d2aa0bf0 patchbomb: build patch texts by _getpatchmsgs()
Yuya Nishihara <yuya@tcha.org>
parents: 31184
diff changeset
   412
def _getpatchmsgs(repo, sender, revs, patchnames=None, **opts):
23215
83a191031f94 patchbomb: extract 'getpatchmsgs' closure into its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23214
diff changeset
   413
    """return a list of emails from a list of patches
83a191031f94 patchbomb: extract 'getpatchmsgs' closure into its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23214
diff changeset
   414
83a191031f94 patchbomb: extract 'getpatchmsgs' closure into its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23214
diff changeset
   415
    This involves introduction message creation if necessary.
83a191031f94 patchbomb: extract 'getpatchmsgs' closure into its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23214
diff changeset
   416
83a191031f94 patchbomb: extract 'getpatchmsgs' closure into its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23214
diff changeset
   417
    This function returns a list of "email" tuples (subject, content, None).
83a191031f94 patchbomb: extract 'getpatchmsgs' closure into its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23214
diff changeset
   418
    """
35044
71e63fe6b1ab py3: handle keyword arguments correctly in hgext/patchbomb.py
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34911
diff changeset
   419
    bytesopts = pycompat.byteskwargs(opts)
23215
83a191031f94 patchbomb: extract 'getpatchmsgs' closure into its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23214
diff changeset
   420
    ui = repo.ui
83a191031f94 patchbomb: extract 'getpatchmsgs' closure into its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23214
diff changeset
   421
    _charsets = mail._charsets(ui)
31185
bbb5d2aa0bf0 patchbomb: build patch texts by _getpatchmsgs()
Yuya Nishihara <yuya@tcha.org>
parents: 31184
diff changeset
   422
    patches = list(_getpatches(repo, revs, **opts))
23215
83a191031f94 patchbomb: extract 'getpatchmsgs' closure into its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23214
diff changeset
   423
    msgs = []
83a191031f94 patchbomb: extract 'getpatchmsgs' closure into its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23214
diff changeset
   424
83a191031f94 patchbomb: extract 'getpatchmsgs' closure into its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23214
diff changeset
   425
    ui.write(_('this patch series consists of %d patches.\n\n')
83a191031f94 patchbomb: extract 'getpatchmsgs' closure into its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23214
diff changeset
   426
             % len(patches))
83a191031f94 patchbomb: extract 'getpatchmsgs' closure into its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23214
diff changeset
   427
83a191031f94 patchbomb: extract 'getpatchmsgs' closure into its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23214
diff changeset
   428
    # build the intro message, or skip it if the user declines
35044
71e63fe6b1ab py3: handle keyword arguments correctly in hgext/patchbomb.py
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34911
diff changeset
   429
    if introwanted(ui, bytesopts, len(patches)):
31186
83fa357edbd5 patchbomb: pass around ui and revs that are needed for flag template
Yuya Nishihara <yuya@tcha.org>
parents: 31185
diff changeset
   430
        msg = _makeintro(repo, sender, revs, patches, **opts)
23215
83a191031f94 patchbomb: extract 'getpatchmsgs' closure into its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23214
diff changeset
   431
        if msg:
83a191031f94 patchbomb: extract 'getpatchmsgs' closure into its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23214
diff changeset
   432
            msgs.append(msg)
83a191031f94 patchbomb: extract 'getpatchmsgs' closure into its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23214
diff changeset
   433
83a191031f94 patchbomb: extract 'getpatchmsgs' closure into its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23214
diff changeset
   434
    # are we going to send more than one message?
83a191031f94 patchbomb: extract 'getpatchmsgs' closure into its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23214
diff changeset
   435
    numbered = len(msgs) + len(patches) > 1
83a191031f94 patchbomb: extract 'getpatchmsgs' closure into its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23214
diff changeset
   436
83a191031f94 patchbomb: extract 'getpatchmsgs' closure into its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23214
diff changeset
   437
    # now generate the actual patch messages
83a191031f94 patchbomb: extract 'getpatchmsgs' closure into its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23214
diff changeset
   438
    name = None
31186
83fa357edbd5 patchbomb: pass around ui and revs that are needed for flag template
Yuya Nishihara <yuya@tcha.org>
parents: 31185
diff changeset
   439
    assert len(revs) == len(patches)
83fa357edbd5 patchbomb: pass around ui and revs that are needed for flag template
Yuya Nishihara <yuya@tcha.org>
parents: 31185
diff changeset
   440
    for i, (r, p) in enumerate(zip(revs, patches)):
23215
83a191031f94 patchbomb: extract 'getpatchmsgs' closure into its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23214
diff changeset
   441
        if patchnames:
83a191031f94 patchbomb: extract 'getpatchmsgs' closure into its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23214
diff changeset
   442
            name = patchnames[i]
35044
71e63fe6b1ab py3: handle keyword arguments correctly in hgext/patchbomb.py
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34911
diff changeset
   443
        msg = makepatch(ui, repo, r, p, bytesopts, _charsets,
71e63fe6b1ab py3: handle keyword arguments correctly in hgext/patchbomb.py
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34911
diff changeset
   444
                        i + 1, len(patches), numbered, name)
23215
83a191031f94 patchbomb: extract 'getpatchmsgs' closure into its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23214
diff changeset
   445
        msgs.append(msg)
83a191031f94 patchbomb: extract 'getpatchmsgs' closure into its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23214
diff changeset
   446
83a191031f94 patchbomb: extract 'getpatchmsgs' closure into its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23214
diff changeset
   447
    return msgs
83a191031f94 patchbomb: extract 'getpatchmsgs' closure into its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23214
diff changeset
   448
23486
1de214837f5e patchbomb: extract 'getoutgoing' closure into its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23450
diff changeset
   449
def _getoutgoing(repo, dest, revs):
1de214837f5e patchbomb: extract 'getoutgoing' closure into its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23450
diff changeset
   450
    '''Return the revisions present locally but not in dest'''
1de214837f5e patchbomb: extract 'getoutgoing' closure into its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23450
diff changeset
   451
    ui = repo.ui
1de214837f5e patchbomb: extract 'getoutgoing' closure into its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23450
diff changeset
   452
    url = ui.expandpath(dest or 'default-push', dest or 'default')
1de214837f5e patchbomb: extract 'getoutgoing' closure into its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23450
diff changeset
   453
    url = hg.parseurl(url)[0]
1de214837f5e patchbomb: extract 'getoutgoing' closure into its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23450
diff changeset
   454
    ui.status(_('comparing with %s\n') % util.hidepassword(url))
1de214837f5e patchbomb: extract 'getoutgoing' closure into its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23450
diff changeset
   455
24568
2e5f6cdf01f6 patchbomb: factor out scmutil.revrange() calls
Yuya Nishihara <yuya@tcha.org>
parents: 24567
diff changeset
   456
    revs = [r for r in revs if r >= 0]
23486
1de214837f5e patchbomb: extract 'getoutgoing' closure into its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23450
diff changeset
   457
    if not revs:
35674
e711906aa42c patchbomb: use 'tiprev' when appropriate
Boris Feld <boris.feld@octobus.net>
parents: 35466
diff changeset
   458
        revs = [repo.changelog.tiprev()]
23486
1de214837f5e patchbomb: extract 'getoutgoing' closure into its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23450
diff changeset
   459
    revs = repo.revs('outgoing(%s) and ::%ld', dest or '', revs)
1de214837f5e patchbomb: extract 'getoutgoing' closure into its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23450
diff changeset
   460
    if not revs:
1de214837f5e patchbomb: extract 'getoutgoing' closure into its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23450
diff changeset
   461
        ui.status(_("no changes found\n"))
24567
13f0af2a5a4c patchbomb: return outgoing revs as a smartset
Yuya Nishihara <yuya@tcha.org>
parents: 24306
diff changeset
   462
    return revs
23486
1de214837f5e patchbomb: extract 'getoutgoing' closure into its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23450
diff changeset
   463
14309
37e80214badf patchbomb: use cmdutil.command decorator
Adrian Buehlmann <adrian@cadifra.com>
parents: 14290
diff changeset
   464
emailopts = [
16307
17a9a1f5cee2 patchbomb: add --body flag to send patches as inline message body text
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16233
diff changeset
   465
    ('', 'body', None, _('send patches as inline message text (default)')),
14309
37e80214badf patchbomb: use cmdutil.command decorator
Adrian Buehlmann <adrian@cadifra.com>
parents: 14290
diff changeset
   466
    ('a', 'attach', None, _('send patches as attachments')),
37e80214badf patchbomb: use cmdutil.command decorator
Adrian Buehlmann <adrian@cadifra.com>
parents: 14290
diff changeset
   467
    ('i', 'inline', None, _('send patches as inline attachments')),
37e80214badf patchbomb: use cmdutil.command decorator
Adrian Buehlmann <adrian@cadifra.com>
parents: 14290
diff changeset
   468
    ('', 'bcc', [], _('email addresses of blind carbon copy recipients')),
37e80214badf patchbomb: use cmdutil.command decorator
Adrian Buehlmann <adrian@cadifra.com>
parents: 14290
diff changeset
   469
    ('c', 'cc', [], _('email addresses of copy recipients')),
37e80214badf patchbomb: use cmdutil.command decorator
Adrian Buehlmann <adrian@cadifra.com>
parents: 14290
diff changeset
   470
    ('', 'confirm', None, _('ask for confirmation before sending')),
37e80214badf patchbomb: use cmdutil.command decorator
Adrian Buehlmann <adrian@cadifra.com>
parents: 14290
diff changeset
   471
    ('d', 'diffstat', None, _('add diffstat output to messages')),
37e80214badf patchbomb: use cmdutil.command decorator
Adrian Buehlmann <adrian@cadifra.com>
parents: 14290
diff changeset
   472
    ('', 'date', '', _('use the given date as the sending date')),
37e80214badf patchbomb: use cmdutil.command decorator
Adrian Buehlmann <adrian@cadifra.com>
parents: 14290
diff changeset
   473
    ('', 'desc', '', _('use the given file as the series description')),
37e80214badf patchbomb: use cmdutil.command decorator
Adrian Buehlmann <adrian@cadifra.com>
parents: 14290
diff changeset
   474
    ('f', 'from', '', _('email address of sender')),
37e80214badf patchbomb: use cmdutil.command decorator
Adrian Buehlmann <adrian@cadifra.com>
parents: 14290
diff changeset
   475
    ('n', 'test', None, _('print messages that would be sent')),
37e80214badf patchbomb: use cmdutil.command decorator
Adrian Buehlmann <adrian@cadifra.com>
parents: 14290
diff changeset
   476
    ('m', 'mbox', '', _('write messages to mbox file instead of sending them')),
37e80214badf patchbomb: use cmdutil.command decorator
Adrian Buehlmann <adrian@cadifra.com>
parents: 14290
diff changeset
   477
    ('', 'reply-to', [], _('email addresses replies should be sent to')),
37e80214badf patchbomb: use cmdutil.command decorator
Adrian Buehlmann <adrian@cadifra.com>
parents: 14290
diff changeset
   478
    ('s', 'subject', '', _('subject of first message (intro or single patch)')),
37e80214badf patchbomb: use cmdutil.command decorator
Adrian Buehlmann <adrian@cadifra.com>
parents: 14290
diff changeset
   479
    ('', 'in-reply-to', '', _('message identifier to reply to')),
37e80214badf patchbomb: use cmdutil.command decorator
Adrian Buehlmann <adrian@cadifra.com>
parents: 14290
diff changeset
   480
    ('', 'flag', [], _('flags to add in subject prefixes')),
37e80214badf patchbomb: use cmdutil.command decorator
Adrian Buehlmann <adrian@cadifra.com>
parents: 14290
diff changeset
   481
    ('t', 'to', [], _('email addresses of recipients'))]
37e80214badf patchbomb: use cmdutil.command decorator
Adrian Buehlmann <adrian@cadifra.com>
parents: 14290
diff changeset
   482
37e80214badf patchbomb: use cmdutil.command decorator
Adrian Buehlmann <adrian@cadifra.com>
parents: 14290
diff changeset
   483
@command('email',
37e80214badf patchbomb: use cmdutil.command decorator
Adrian Buehlmann <adrian@cadifra.com>
parents: 14290
diff changeset
   484
    [('g', 'git', None, _('use git extended diff format')),
37e80214badf patchbomb: use cmdutil.command decorator
Adrian Buehlmann <adrian@cadifra.com>
parents: 14290
diff changeset
   485
    ('', 'plain', None, _('omit hg patch header')),
37e80214badf patchbomb: use cmdutil.command decorator
Adrian Buehlmann <adrian@cadifra.com>
parents: 14290
diff changeset
   486
    ('o', 'outgoing', None,
37e80214badf patchbomb: use cmdutil.command decorator
Adrian Buehlmann <adrian@cadifra.com>
parents: 14290
diff changeset
   487
     _('send changes not found in the target repository')),
37e80214badf patchbomb: use cmdutil.command decorator
Adrian Buehlmann <adrian@cadifra.com>
parents: 14290
diff changeset
   488
    ('b', 'bundle', None, _('send changes not in target as a binary bundle')),
32639
c2fe2b00db53 patchbomb: add -B option to select a bookmark
David Demelier <demelier.david@gmail.com>
parents: 32375
diff changeset
   489
    ('B', 'bookmark', '', _('send changes only reachable by given bookmark')),
14309
37e80214badf patchbomb: use cmdutil.command decorator
Adrian Buehlmann <adrian@cadifra.com>
parents: 14290
diff changeset
   490
    ('', 'bundlename', 'bundle',
37e80214badf patchbomb: use cmdutil.command decorator
Adrian Buehlmann <adrian@cadifra.com>
parents: 14290
diff changeset
   491
     _('name of the bundle attachment file'), _('NAME')),
37e80214badf patchbomb: use cmdutil.command decorator
Adrian Buehlmann <adrian@cadifra.com>
parents: 14290
diff changeset
   492
    ('r', 'rev', [], _('a revision to send'), _('REV')),
37e80214badf patchbomb: use cmdutil.command decorator
Adrian Buehlmann <adrian@cadifra.com>
parents: 14290
diff changeset
   493
    ('', 'force', None, _('run even when remote repository is unrelated '
37e80214badf patchbomb: use cmdutil.command decorator
Adrian Buehlmann <adrian@cadifra.com>
parents: 14290
diff changeset
   494
       '(with -b/--bundle)')),
37e80214badf patchbomb: use cmdutil.command decorator
Adrian Buehlmann <adrian@cadifra.com>
parents: 14290
diff changeset
   495
    ('', 'base', [], _('a base changeset to specify instead of a destination '
37e80214badf patchbomb: use cmdutil.command decorator
Adrian Buehlmann <adrian@cadifra.com>
parents: 14290
diff changeset
   496
       '(with -b/--bundle)'), _('REV')),
37e80214badf patchbomb: use cmdutil.command decorator
Adrian Buehlmann <adrian@cadifra.com>
parents: 14290
diff changeset
   497
    ('', 'intro', None, _('send an introduction email for a single patch')),
32375
04baab18d60a commands: move templates of common command options to cmdutil (API)
Yuya Nishihara <yuya@tcha.org>
parents: 32337
diff changeset
   498
    ] + emailopts + cmdutil.remoteopts,
14309
37e80214badf patchbomb: use cmdutil.command decorator
Adrian Buehlmann <adrian@cadifra.com>
parents: 14290
diff changeset
   499
    _('hg email [OPTION]... [DEST]...'))
27150
88aaddb1af88 patchbomb: rename email function
timeless <timeless@mozdev.org>
parents: 26626
diff changeset
   500
def email(ui, repo, *revs, **opts):
4283
8625504f507c Slight refining to help text in patchbomb.py
John Goerzen <jgoerzen@complete.org>
parents: 4280
diff changeset
   501
    '''send changesets by email
1204
b0f6053df539 patchbomb: continue if we can't import readline.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1154
diff changeset
   502
11193
687c7d395f20 Use our custom hg reStructuredText role some more
Martin Geisler <mg@aragost.com>
parents: 11183
diff changeset
   503
    By default, diffs are sent in the format generated by
687c7d395f20 Use our custom hg reStructuredText role some more
Martin Geisler <mg@aragost.com>
parents: 11183
diff changeset
   504
    :hg:`export`, one per message. The series starts with a "[PATCH 0
687c7d395f20 Use our custom hg reStructuredText role some more
Martin Geisler <mg@aragost.com>
parents: 11183
diff changeset
   505
    of N]" introduction, which describes the series as a whole.
1672
07f931af5f40 add documentation for email command.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1670
diff changeset
   506
9269
1d6499adf211 patchbomb: wrap docstrings at 70 characters
Martin Geisler <mg@lazybytes.net>
parents: 9214
diff changeset
   507
    Each patch email has a Subject line of "[PATCH M of N] ...", using
1d6499adf211 patchbomb: wrap docstrings at 70 characters
Martin Geisler <mg@lazybytes.net>
parents: 9214
diff changeset
   508
    the first line of the changeset description as the subject text.
1d6499adf211 patchbomb: wrap docstrings at 70 characters
Martin Geisler <mg@lazybytes.net>
parents: 9214
diff changeset
   509
    The message contains two or three parts. First, the changeset
12749
338b4b615d33 patchbomb: move command option help from the extension (patchbomb) to the command (email)
timeless <timeless@gmail.com>
parents: 12265
diff changeset
   510
    description.
338b4b615d33 patchbomb: move command option help from the extension (patchbomb) to the command (email)
timeless <timeless@gmail.com>
parents: 12265
diff changeset
   511
338b4b615d33 patchbomb: move command option help from the extension (patchbomb) to the command (email)
timeless <timeless@gmail.com>
parents: 12265
diff changeset
   512
    With the -d/--diffstat option, if the diffstat program is
338b4b615d33 patchbomb: move command option help from the extension (patchbomb) to the command (email)
timeless <timeless@gmail.com>
parents: 12265
diff changeset
   513
    installed, the result of running diffstat on the patch is inserted.
338b4b615d33 patchbomb: move command option help from the extension (patchbomb) to the command (email)
timeless <timeless@gmail.com>
parents: 12265
diff changeset
   514
338b4b615d33 patchbomb: move command option help from the extension (patchbomb) to the command (email)
timeless <timeless@gmail.com>
parents: 12265
diff changeset
   515
    Finally, the patch itself, as generated by :hg:`export`.
338b4b615d33 patchbomb: move command option help from the extension (patchbomb) to the command (email)
timeless <timeless@gmail.com>
parents: 12265
diff changeset
   516
17880
9f6044119166 patchbomb: -c is not an alias for the --confirm option
Julian Cowley <julian@lava.net>
parents: 17859
diff changeset
   517
    With the -d/--diffstat or --confirm options, you will be presented
12749
338b4b615d33 patchbomb: move command option help from the extension (patchbomb) to the command (email)
timeless <timeless@gmail.com>
parents: 12265
diff changeset
   518
    with a final summary of all messages and asked for confirmation before
338b4b615d33 patchbomb: move command option help from the extension (patchbomb) to the command (email)
timeless <timeless@gmail.com>
parents: 12265
diff changeset
   519
    the messages are sent.
4262
f51317e24114 Add --outgoing option to patchbomb
Brendan Cully <brendan@kublai.com>
parents: 4144
diff changeset
   520
9269
1d6499adf211 patchbomb: wrap docstrings at 70 characters
Martin Geisler <mg@lazybytes.net>
parents: 9214
diff changeset
   521
    By default the patch is included as text in the email body for
1d6499adf211 patchbomb: wrap docstrings at 70 characters
Martin Geisler <mg@lazybytes.net>
parents: 9214
diff changeset
   522
    easy reviewing. Using the -a/--attach option will instead create
1d6499adf211 patchbomb: wrap docstrings at 70 characters
Martin Geisler <mg@lazybytes.net>
parents: 9214
diff changeset
   523
    an attachment for the patch. With -i/--inline an inline attachment
16307
17a9a1f5cee2 patchbomb: add --body flag to send patches as inline message body text
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16233
diff changeset
   524
    will be created. You can include a patch both as text in the email
17a9a1f5cee2 patchbomb: add --body flag to send patches as inline message body text
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16233
diff changeset
   525
    body and as a regular or an inline attachment by combining the
17a9a1f5cee2 patchbomb: add --body flag to send patches as inline message body text
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16233
diff changeset
   526
    -a/--attach or -i/--inline with the --body option.
8472
223363bb6d66 patchbomb: describe --attach and --inline options in help
Martin Geisler <mg@lazybytes.net>
parents: 8471
diff changeset
   527
32639
c2fe2b00db53 patchbomb: add -B option to select a bookmark
David Demelier <demelier.david@gmail.com>
parents: 32375
diff changeset
   528
    With -B/--bookmark changesets reachable by the given bookmark are
c2fe2b00db53 patchbomb: add -B option to select a bookmark
David Demelier <demelier.david@gmail.com>
parents: 32375
diff changeset
   529
    selected.
c2fe2b00db53 patchbomb: add -B option to select a bookmark
David Demelier <demelier.david@gmail.com>
parents: 32375
diff changeset
   530
9269
1d6499adf211 patchbomb: wrap docstrings at 70 characters
Martin Geisler <mg@lazybytes.net>
parents: 9214
diff changeset
   531
    With -o/--outgoing, emails will be generated for patches not found
1d6499adf211 patchbomb: wrap docstrings at 70 characters
Martin Geisler <mg@lazybytes.net>
parents: 9214
diff changeset
   532
    in the destination repository (or only those which are ancestors
1d6499adf211 patchbomb: wrap docstrings at 70 characters
Martin Geisler <mg@lazybytes.net>
parents: 9214
diff changeset
   533
    of the specified revisions if any are provided)
4280
a9336520a4ee Improve documentation for patchbomb and email
John Goerzen <jgoerzen@complete.org>
parents: 4279
diff changeset
   534
9269
1d6499adf211 patchbomb: wrap docstrings at 70 characters
Martin Geisler <mg@lazybytes.net>
parents: 9214
diff changeset
   535
    With -b/--bundle, changesets are selected as for --outgoing, but a
1d6499adf211 patchbomb: wrap docstrings at 70 characters
Martin Geisler <mg@lazybytes.net>
parents: 9214
diff changeset
   536
    single email containing a binary Mercurial bundle as an attachment
26563
d4a1bfe1de63 patchbomb: add a 'bundletype' config under 'patchbomb'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26546
diff changeset
   537
    will be sent. Use the ``patchbomb.bundletype`` config option to
d4a1bfe1de63 patchbomb: add a 'bundletype' config under 'patchbomb'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26546
diff changeset
   538
    control the bundle type as with :hg:`bundle --type`.
4280
a9336520a4ee Improve documentation for patchbomb and email
John Goerzen <jgoerzen@complete.org>
parents: 4279
diff changeset
   539
12749
338b4b615d33 patchbomb: move command option help from the extension (patchbomb) to the command (email)
timeless <timeless@gmail.com>
parents: 12265
diff changeset
   540
    With -m/--mbox, instead of previewing each patchbomb message in a
338b4b615d33 patchbomb: move command option help from the extension (patchbomb) to the command (email)
timeless <timeless@gmail.com>
parents: 12265
diff changeset
   541
    pager or sending the messages directly, it will create a UNIX
338b4b615d33 patchbomb: move command option help from the extension (patchbomb) to the command (email)
timeless <timeless@gmail.com>
parents: 12265
diff changeset
   542
    mailbox file with the patch emails. This mailbox file can be
338b4b615d33 patchbomb: move command option help from the extension (patchbomb) to the command (email)
timeless <timeless@gmail.com>
parents: 12265
diff changeset
   543
    previewed with any mail user agent which supports UNIX mbox
338b4b615d33 patchbomb: move command option help from the extension (patchbomb) to the command (email)
timeless <timeless@gmail.com>
parents: 12265
diff changeset
   544
    files.
338b4b615d33 patchbomb: move command option help from the extension (patchbomb) to the command (email)
timeless <timeless@gmail.com>
parents: 12265
diff changeset
   545
338b4b615d33 patchbomb: move command option help from the extension (patchbomb) to the command (email)
timeless <timeless@gmail.com>
parents: 12265
diff changeset
   546
    With -n/--test, all steps will run, but mail will not be sent.
338b4b615d33 patchbomb: move command option help from the extension (patchbomb) to the command (email)
timeless <timeless@gmail.com>
parents: 12265
diff changeset
   547
    You will be prompted for an email recipient address, a subject and
338b4b615d33 patchbomb: move command option help from the extension (patchbomb) to the command (email)
timeless <timeless@gmail.com>
parents: 12265
diff changeset
   548
    an introductory message describing the patches of your patchbomb.
31489
5b2e1689b24d patchbomb: use modern pager to display -n/--test result (BC)
Yuya Nishihara <yuya@tcha.org>
parents: 31187
diff changeset
   549
    Then when all is done, patchbomb messages are displayed.
12749
338b4b615d33 patchbomb: move command option help from the extension (patchbomb) to the command (email)
timeless <timeless@gmail.com>
parents: 12265
diff changeset
   550
13198
e71b2aa74ce3 patchbomb: save introductory message in .hg/last-email.txt
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 12839
diff changeset
   551
    In case email sending fails, you will find a backup of your series
23488
11b215731e74 patchbomb: introduce a 'patchbomb.confirm' option
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23487
diff changeset
   552
    introductory message in ``.hg/last-email.txt``.
11b215731e74 patchbomb: introduce a 'patchbomb.confirm' option
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23487
diff changeset
   553
11b215731e74 patchbomb: introduce a 'patchbomb.confirm' option
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23487
diff changeset
   554
    The default behavior of this command can be customized through
11b215731e74 patchbomb: introduce a 'patchbomb.confirm' option
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23487
diff changeset
   555
    configuration. (See :hg:`help patchbomb` for details)
13198
e71b2aa74ce3 patchbomb: save introductory message in .hg/last-email.txt
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 12839
diff changeset
   556
9289
45aaf27f95b8 patchbomb: reST syntax for literal blocks in help text
Christian Ebert <blacktrash@gmx.net>
parents: 9286
diff changeset
   557
    Examples::
4280
a9336520a4ee Improve documentation for patchbomb and email
John Goerzen <jgoerzen@complete.org>
parents: 4279
diff changeset
   558
9289
45aaf27f95b8 patchbomb: reST syntax for literal blocks in help text
Christian Ebert <blacktrash@gmx.net>
parents: 9286
diff changeset
   559
      hg email -r 3000          # send patch 3000 only
45aaf27f95b8 patchbomb: reST syntax for literal blocks in help text
Christian Ebert <blacktrash@gmx.net>
parents: 9286
diff changeset
   560
      hg email -r 3000 -r 3001  # send patches 3000 and 3001
45aaf27f95b8 patchbomb: reST syntax for literal blocks in help text
Christian Ebert <blacktrash@gmx.net>
parents: 9286
diff changeset
   561
      hg email -r 3000:3005     # send patches 3000 through 3005
45aaf27f95b8 patchbomb: reST syntax for literal blocks in help text
Christian Ebert <blacktrash@gmx.net>
parents: 9286
diff changeset
   562
      hg email 3000             # send patch 3000 (deprecated)
4280
a9336520a4ee Improve documentation for patchbomb and email
John Goerzen <jgoerzen@complete.org>
parents: 4279
diff changeset
   563
9289
45aaf27f95b8 patchbomb: reST syntax for literal blocks in help text
Christian Ebert <blacktrash@gmx.net>
parents: 9286
diff changeset
   564
      hg email -o               # send all patches not in default
45aaf27f95b8 patchbomb: reST syntax for literal blocks in help text
Christian Ebert <blacktrash@gmx.net>
parents: 9286
diff changeset
   565
      hg email -o DEST          # send all patches not in DEST
45aaf27f95b8 patchbomb: reST syntax for literal blocks in help text
Christian Ebert <blacktrash@gmx.net>
parents: 9286
diff changeset
   566
      hg email -o -r 3000       # send all ancestors of 3000 not in default
45aaf27f95b8 patchbomb: reST syntax for literal blocks in help text
Christian Ebert <blacktrash@gmx.net>
parents: 9286
diff changeset
   567
      hg email -o -r 3000 DEST  # send all ancestors of 3000 not in DEST
4280
a9336520a4ee Improve documentation for patchbomb and email
John Goerzen <jgoerzen@complete.org>
parents: 4279
diff changeset
   568
32639
c2fe2b00db53 patchbomb: add -B option to select a bookmark
David Demelier <demelier.david@gmail.com>
parents: 32375
diff changeset
   569
      hg email -B feature       # send all ancestors of feature bookmark
c2fe2b00db53 patchbomb: add -B option to select a bookmark
David Demelier <demelier.david@gmail.com>
parents: 32375
diff changeset
   570
9289
45aaf27f95b8 patchbomb: reST syntax for literal blocks in help text
Christian Ebert <blacktrash@gmx.net>
parents: 9286
diff changeset
   571
      hg email -b               # send bundle of all patches not in default
45aaf27f95b8 patchbomb: reST syntax for literal blocks in help text
Christian Ebert <blacktrash@gmx.net>
parents: 9286
diff changeset
   572
      hg email -b DEST          # send bundle of all patches not in DEST
45aaf27f95b8 patchbomb: reST syntax for literal blocks in help text
Christian Ebert <blacktrash@gmx.net>
parents: 9286
diff changeset
   573
      hg email -b -r 3000       # bundle of all ancestors of 3000 not in default
45aaf27f95b8 patchbomb: reST syntax for literal blocks in help text
Christian Ebert <blacktrash@gmx.net>
parents: 9286
diff changeset
   574
      hg email -b -r 3000 DEST  # bundle of all ancestors of 3000 not in DEST
4280
a9336520a4ee Improve documentation for patchbomb and email
John Goerzen <jgoerzen@complete.org>
parents: 4279
diff changeset
   575
12749
338b4b615d33 patchbomb: move command option help from the extension (patchbomb) to the command (email)
timeless <timeless@gmail.com>
parents: 12265
diff changeset
   576
      hg email -o -m mbox &&    # generate an mbox file...
338b4b615d33 patchbomb: move command option help from the extension (patchbomb) to the command (email)
timeless <timeless@gmail.com>
parents: 12265
diff changeset
   577
        mutt -R -f mbox         # ... and view it with mutt
338b4b615d33 patchbomb: move command option help from the extension (patchbomb) to the command (email)
timeless <timeless@gmail.com>
parents: 12265
diff changeset
   578
      hg email -o -m mbox &&    # generate an mbox file ...
12839
d85e30889f26 patchbomb: fix stray backslash in docstring
Martin Geisler <mg@lazybytes.net>
parents: 12794
diff changeset
   579
        formail -s sendmail \\   # ... and use formail to send from the mbox
12749
338b4b615d33 patchbomb: move command option help from the extension (patchbomb) to the command (email)
timeless <timeless@gmail.com>
parents: 12265
diff changeset
   580
          -bm -t < mbox         # ... using sendmail
338b4b615d33 patchbomb: move command option help from the extension (patchbomb) to the command (email)
timeless <timeless@gmail.com>
parents: 12265
diff changeset
   581
9269
1d6499adf211 patchbomb: wrap docstrings at 70 characters
Martin Geisler <mg@lazybytes.net>
parents: 9214
diff changeset
   582
    Before using this command, you will need to enable email in your
1d6499adf211 patchbomb: wrap docstrings at 70 characters
Martin Geisler <mg@lazybytes.net>
parents: 9214
diff changeset
   583
    hgrc. See the [email] section in hgrc(5) for details.
4262
f51317e24114 Add --outgoing option to patchbomb
Brendan Cully <brendan@kublai.com>
parents: 4144
diff changeset
   584
    '''
35044
71e63fe6b1ab py3: handle keyword arguments correctly in hgext/patchbomb.py
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34911
diff changeset
   585
    opts = pycompat.byteskwargs(opts)
4262
f51317e24114 Add --outgoing option to patchbomb
Brendan Cully <brendan@kublai.com>
parents: 4144
diff changeset
   586
7115
c5c2d43b01da patchbomb: mime-encode headers and parts not containing patches
Christian Ebert <blacktrash@gmx.net>
parents: 7095
diff changeset
   587
    _charsets = mail._charsets(ui)
c5c2d43b01da patchbomb: mime-encode headers and parts not containing patches
Christian Ebert <blacktrash@gmx.net>
parents: 7095
diff changeset
   588
11413
4c1fe996838c patchbomb: reduce number of opts.get calls
Christian Ebert <blacktrash@gmx.net>
parents: 11321
diff changeset
   589
    bundle = opts.get('bundle')
4c1fe996838c patchbomb: reduce number of opts.get calls
Christian Ebert <blacktrash@gmx.net>
parents: 11321
diff changeset
   590
    date = opts.get('date')
4c1fe996838c patchbomb: reduce number of opts.get calls
Christian Ebert <blacktrash@gmx.net>
parents: 11321
diff changeset
   591
    mbox = opts.get('mbox')
4c1fe996838c patchbomb: reduce number of opts.get calls
Christian Ebert <blacktrash@gmx.net>
parents: 11321
diff changeset
   592
    outgoing = opts.get('outgoing')
4c1fe996838c patchbomb: reduce number of opts.get calls
Christian Ebert <blacktrash@gmx.net>
parents: 11321
diff changeset
   593
    rev = opts.get('rev')
32639
c2fe2b00db53 patchbomb: add -B option to select a bookmark
David Demelier <demelier.david@gmail.com>
parents: 32375
diff changeset
   594
    bookmark = opts.get('bookmark')
11413
4c1fe996838c patchbomb: reduce number of opts.get calls
Christian Ebert <blacktrash@gmx.net>
parents: 11321
diff changeset
   595
4c1fe996838c patchbomb: reduce number of opts.get calls
Christian Ebert <blacktrash@gmx.net>
parents: 11321
diff changeset
   596
    if not (opts.get('test') or mbox):
5472
23889160905a Catch smtp exceptions
Christian Ebert <blacktrash@gmx.net>
parents: 4887
diff changeset
   597
        # really sending
4489
a11e13d50645 patchbomb: Validate email config before we start prompting for info.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4486
diff changeset
   598
        mail.validateconfig(ui)
a11e13d50645 patchbomb: Validate email config before we start prompting for info.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4486
diff changeset
   599
32639
c2fe2b00db53 patchbomb: add -B option to select a bookmark
David Demelier <demelier.david@gmail.com>
parents: 32375
diff changeset
   600
    if not (revs or rev or outgoing or bundle or bookmark):
c2fe2b00db53 patchbomb: add -B option to select a bookmark
David Demelier <demelier.david@gmail.com>
parents: 32375
diff changeset
   601
        raise error.Abort(_('specify at least one changeset with -B, -r or -o'))
4493
ead2fa544cbf patchbomb: Fail early if no revs given to email
Bryan O'Sullivan <bos@serpentine.com>
parents: 4492
diff changeset
   602
11413
4c1fe996838c patchbomb: reduce number of opts.get calls
Christian Ebert <blacktrash@gmx.net>
parents: 11321
diff changeset
   603
    if outgoing and bundle:
26587
56b2bcea2529 error: get Abort from 'error' instead of 'util'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26563
diff changeset
   604
        raise error.Abort(_("--outgoing mode always on with --bundle;"
5746
d3ef7e86bc3b patchbomb: break lines > 80 chars (coding style)
Christian Ebert <blacktrash@gmx.net>
parents: 5677
diff changeset
   605
                           " do not re-specify --outgoing"))
32695
0841382d114a patchbomb: avoid -r and -B options at the same time
David Demelier <demelier.david@gmail.com>
parents: 32639
diff changeset
   606
    if rev and bookmark:
0841382d114a patchbomb: avoid -r and -B options at the same time
David Demelier <demelier.david@gmail.com>
parents: 32639
diff changeset
   607
        raise error.Abort(_("-r and -B are mutually exclusive"))
4278
cfe886c14ddf Add ability to send bundles to patchbomb extension
John Goerzen <jgoerzen@complete.org>
parents: 4262
diff changeset
   608
11413
4c1fe996838c patchbomb: reduce number of opts.get calls
Christian Ebert <blacktrash@gmx.net>
parents: 11321
diff changeset
   609
    if outgoing or bundle:
4262
f51317e24114 Add --outgoing option to patchbomb
Brendan Cully <brendan@kublai.com>
parents: 4144
diff changeset
   610
        if len(revs) > 1:
26587
56b2bcea2529 error: get Abort from 'error' instead of 'util'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26563
diff changeset
   611
            raise error.Abort(_("too many destinations"))
24306
6ddc86eedc3b style: kill ersatz if-else ternary operators
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 23877
diff changeset
   612
        if revs:
6ddc86eedc3b style: kill ersatz if-else ternary operators
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 23877
diff changeset
   613
            dest = revs[0]
6ddc86eedc3b style: kill ersatz if-else ternary operators
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 23877
diff changeset
   614
        else:
6ddc86eedc3b style: kill ersatz if-else ternary operators
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 23877
diff changeset
   615
            dest = None
4262
f51317e24114 Add --outgoing option to patchbomb
Brendan Cully <brendan@kublai.com>
parents: 4144
diff changeset
   616
        revs = []
f51317e24114 Add --outgoing option to patchbomb
Brendan Cully <brendan@kublai.com>
parents: 4144
diff changeset
   617
11413
4c1fe996838c patchbomb: reduce number of opts.get calls
Christian Ebert <blacktrash@gmx.net>
parents: 11321
diff changeset
   618
    if rev:
4262
f51317e24114 Add --outgoing option to patchbomb
Brendan Cully <brendan@kublai.com>
parents: 4144
diff changeset
   619
        if revs:
26587
56b2bcea2529 error: get Abort from 'error' instead of 'util'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26563
diff changeset
   620
            raise error.Abort(_('use only one form to specify the revision'))
11413
4c1fe996838c patchbomb: reduce number of opts.get calls
Christian Ebert <blacktrash@gmx.net>
parents: 11321
diff changeset
   621
        revs = rev
32639
c2fe2b00db53 patchbomb: add -B option to select a bookmark
David Demelier <demelier.david@gmail.com>
parents: 32375
diff changeset
   622
    elif bookmark:
c2fe2b00db53 patchbomb: add -B option to select a bookmark
David Demelier <demelier.david@gmail.com>
parents: 32375
diff changeset
   623
        if bookmark not in repo._bookmarks:
c2fe2b00db53 patchbomb: add -B option to select a bookmark
David Demelier <demelier.david@gmail.com>
parents: 32375
diff changeset
   624
            raise error.Abort(_("bookmark '%s' not found") % bookmark)
38131
46c2b19a1263 scmutil: move repair.stripbmrevset as scmutil.bookmarkrevs (API)
David Demelier <markand@malikania.fr>
parents: 37603
diff changeset
   625
        revs = scmutil.bookmarkrevs(repo, bookmark)
4262
f51317e24114 Add --outgoing option to patchbomb
Brendan Cully <brendan@kublai.com>
parents: 4144
diff changeset
   626
24568
2e5f6cdf01f6 patchbomb: factor out scmutil.revrange() calls
Yuya Nishihara <yuya@tcha.org>
parents: 24567
diff changeset
   627
    revs = scmutil.revrange(repo, revs)
11413
4c1fe996838c patchbomb: reduce number of opts.get calls
Christian Ebert <blacktrash@gmx.net>
parents: 11321
diff changeset
   628
    if outgoing:
24568
2e5f6cdf01f6 patchbomb: factor out scmutil.revrange() calls
Yuya Nishihara <yuya@tcha.org>
parents: 24567
diff changeset
   629
        revs = _getoutgoing(repo, dest, revs)
11413
4c1fe996838c patchbomb: reduce number of opts.get calls
Christian Ebert <blacktrash@gmx.net>
parents: 11321
diff changeset
   630
    if bundle:
36668
e77cee5de1c7 py3: use b"%d" to covert integer to bytes instead of str
Pulkit Goyal <7895pulkit@gmail.com>
parents: 36607
diff changeset
   631
        opts['revs'] = ["%d" % r for r in revs]
4262
f51317e24114 Add --outgoing option to patchbomb
Brendan Cully <brendan@kublai.com>
parents: 4144
diff changeset
   632
26626
dca161728dc9 patchbomb: check that targets exist at the publicurl
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26587
diff changeset
   633
    # check if revision exist on the public destination
dca161728dc9 patchbomb: check that targets exist at the publicurl
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26587
diff changeset
   634
    publicurl = repo.ui.config('patchbomb', 'publicurl')
32825
16ff5c6066a6 patchbomb: look for non-empty publicurl, not a non-None one
Augie Fackler <augie@google.com>
parents: 32824
diff changeset
   635
    if publicurl:
35466
7906354cbc68 debug: add newlines at the end of three locations that appear to need it
Kyle Lippincott <spectral@google.com>
parents: 35044
diff changeset
   636
        repo.ui.debug('checking that revision exist in the public repo\n')
26626
dca161728dc9 patchbomb: check that targets exist at the publicurl
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26587
diff changeset
   637
        try:
dca161728dc9 patchbomb: check that targets exist at the publicurl
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26587
diff changeset
   638
            publicpeer = hg.peer(repo, {}, publicurl)
dca161728dc9 patchbomb: check that targets exist at the publicurl
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26587
diff changeset
   639
        except error.RepoError:
dca161728dc9 patchbomb: check that targets exist at the publicurl
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26587
diff changeset
   640
            repo.ui.write_err(_('unable to access public repo: %s\n')
dca161728dc9 patchbomb: check that targets exist at the publicurl
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26587
diff changeset
   641
                              % publicurl)
dca161728dc9 patchbomb: check that targets exist at the publicurl
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26587
diff changeset
   642
            raise
dca161728dc9 patchbomb: check that targets exist at the publicurl
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26587
diff changeset
   643
        if not publicpeer.capable('known'):
35466
7906354cbc68 debug: add newlines at the end of three locations that appear to need it
Kyle Lippincott <spectral@google.com>
parents: 35044
diff changeset
   644
            repo.ui.debug('skipping existence checks: public repo too old\n')
26626
dca161728dc9 patchbomb: check that targets exist at the publicurl
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26587
diff changeset
   645
        else:
dca161728dc9 patchbomb: check that targets exist at the publicurl
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26587
diff changeset
   646
            out = [repo[r] for r in revs]
dca161728dc9 patchbomb: check that targets exist at the publicurl
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26587
diff changeset
   647
            known = publicpeer.known(h.node() for h in out)
dca161728dc9 patchbomb: check that targets exist at the publicurl
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26587
diff changeset
   648
            missing = []
dca161728dc9 patchbomb: check that targets exist at the publicurl
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26587
diff changeset
   649
            for idx, h in enumerate(out):
dca161728dc9 patchbomb: check that targets exist at the publicurl
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26587
diff changeset
   650
                if not known[idx]:
dca161728dc9 patchbomb: check that targets exist at the publicurl
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26587
diff changeset
   651
                    missing.append(h)
dca161728dc9 patchbomb: check that targets exist at the publicurl
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26587
diff changeset
   652
            if missing:
dca161728dc9 patchbomb: check that targets exist at the publicurl
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26587
diff changeset
   653
                if 1 < len(missing):
dca161728dc9 patchbomb: check that targets exist at the publicurl
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26587
diff changeset
   654
                    msg = _('public "%s" is missing %s and %i others')
dca161728dc9 patchbomb: check that targets exist at the publicurl
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26587
diff changeset
   655
                    msg %= (publicurl, missing[0], len(missing) - 1)
dca161728dc9 patchbomb: check that targets exist at the publicurl
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26587
diff changeset
   656
                else:
dca161728dc9 patchbomb: check that targets exist at the publicurl
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26587
diff changeset
   657
                    msg = _('public url %s is missing %s')
dca161728dc9 patchbomb: check that targets exist at the publicurl
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26587
diff changeset
   658
                    msg %= (publicurl, missing[0])
36410
67ec4ad815e6 patchbomb: resolve revs before evaluating %ld revset
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36204
diff changeset
   659
                missingrevs = [ctx.rev() for ctx in missing]
28907
66e647312d30 patchbomb: fix public-is-missing hint
timeless <timeless@mozdev.org>
parents: 28861
diff changeset
   660
                revhint = ' '.join('-r %s' % h
36410
67ec4ad815e6 patchbomb: resolve revs before evaluating %ld revset
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36204
diff changeset
   661
                                   for h in repo.set('heads(%ld)', missingrevs))
28981
7b188bc23942 patchbomb: use single quotes around command hint
timeless <timeless@mozdev.org>
parents: 28907
diff changeset
   662
                hint = _("use 'hg push %s %s'") % (publicurl, revhint)
26626
dca161728dc9 patchbomb: check that targets exist at the publicurl
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26587
diff changeset
   663
                raise error.Abort(msg, hint=hint)
dca161728dc9 patchbomb: check that targets exist at the publicurl
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26587
diff changeset
   664
4262
f51317e24114 Add --outgoing option to patchbomb
Brendan Cully <brendan@kublai.com>
parents: 4144
diff changeset
   665
    # start
11413
4c1fe996838c patchbomb: reduce number of opts.get calls
Christian Ebert <blacktrash@gmx.net>
parents: 11321
diff changeset
   666
    if date:
36607
c6061cadb400 util: extract all date-related utils in utils/dateutil module
Boris Feld <boris.feld@octobus.net>
parents: 36450
diff changeset
   667
        start_time = dateutil.parsedate(date)
4566
087b3ae4f08a patchbomb: add --date option
Bryan O'Sullivan <bos@serpentine.com>
parents: 4565
diff changeset
   668
    else:
36607
c6061cadb400 util: extract all date-related utils in utils/dateutil module
Boris Feld <boris.feld@octobus.net>
parents: 36450
diff changeset
   669
        start_time = dateutil.makedate()
875
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   670
876
14cfaaec2e8e Get patchbomb script to not use MIME attachments.
Bryan O'Sullivan <bos@serpentine.com>
parents: 875
diff changeset
   671
    def genmsgid(id):
36449
a918c996a881 py3: use encoding.strtolocal() to convert str to bytes
Pulkit Goyal <7895pulkit@gmail.com>
parents: 36448
diff changeset
   672
        return '<%s.%d@%s>' % (id[:20], int(start_time[0]),
a918c996a881 py3: use encoding.strtolocal() to convert str to bytes
Pulkit Goyal <7895pulkit@gmail.com>
parents: 36448
diff changeset
   673
                               encoding.strtolocal(socket.getfqdn()))
875
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   674
25825
577b050caada patchbomb: mark ancient option deprecated
Matt Mackall <mpm@selenic.com>
parents: 25660
diff changeset
   675
    # deprecated config: patchbomb.from
5818
77775ae8d5d9 patchbomb: consistently use opts.get
Christian Ebert <blacktrash@gmx.net>
parents: 5817
diff changeset
   676
    sender = (opts.get('from') or ui.config('email', 'from') or
2198
564034552f7f rename [patchbomb] section to [email] section in hgrc. old name still ok.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2165
diff changeset
   677
              ui.config('patchbomb', 'from') or
7354
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
   678
              prompt(ui, 'From', ui.username()))
875
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   679
31184
e3ab7c717129 patchbomb: drop internal option for pbranch extension (API)
Yuya Nishihara <yuya@tcha.org>
parents: 31183
diff changeset
   680
    if bundle:
35044
71e63fe6b1ab py3: handle keyword arguments correctly in hgext/patchbomb.py
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34911
diff changeset
   681
        stropts = pycompat.strkwargs(opts)
71e63fe6b1ab py3: handle keyword arguments correctly in hgext/patchbomb.py
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34911
diff changeset
   682
        bundledata = _getbundle(repo, dest, **stropts)
71e63fe6b1ab py3: handle keyword arguments correctly in hgext/patchbomb.py
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34911
diff changeset
   683
        bundleopts = stropts.copy()
71e63fe6b1ab py3: handle keyword arguments correctly in hgext/patchbomb.py
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34911
diff changeset
   684
        bundleopts.pop(r'bundle', None)  # already processed
23213
23a78662b6dd patchbomb: extract 'getbundlemsgs' closure in its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23212
diff changeset
   685
        msgs = _getbundlemsgs(repo, sender, bundledata, **bundleopts)
4278
cfe886c14ddf Add ability to send bundles to patchbomb extension
John Goerzen <jgoerzen@complete.org>
parents: 4262
diff changeset
   686
    else:
35044
71e63fe6b1ab py3: handle keyword arguments correctly in hgext/patchbomb.py
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34911
diff changeset
   687
        msgs = _getpatchmsgs(repo, sender, revs, **pycompat.strkwargs(opts))
875
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   688
12200
aebb39d45500 patchbomb: let diffstat prompt only once with complete summary
Christian Ebert <blacktrash@gmx.net>
parents: 12199
diff changeset
   689
    showaddrs = []
aebb39d45500 patchbomb: let diffstat prompt only once with complete summary
Christian Ebert <blacktrash@gmx.net>
parents: 12199
diff changeset
   690
15162
d67a15b2e608 patchbomb: simplify some contorted logic and odd variable names.
Greg Ward <greg@gerg.ca>
parents: 14556
diff changeset
   691
    def getaddrs(header, ask=False, default=None):
d67a15b2e608 patchbomb: simplify some contorted logic and odd variable names.
Greg Ward <greg@gerg.ca>
parents: 14556
diff changeset
   692
        configkey = header.lower()
d67a15b2e608 patchbomb: simplify some contorted logic and odd variable names.
Greg Ward <greg@gerg.ca>
parents: 14556
diff changeset
   693
        opt = header.replace('-', '_').lower()
d67a15b2e608 patchbomb: simplify some contorted logic and odd variable names.
Greg Ward <greg@gerg.ca>
parents: 14556
diff changeset
   694
        addrs = opts.get(opt)
11150
f66ca4431eb9 patchbomb: Reply-To support
Cédric Duval <cedricduval@free.fr>
parents: 10973
diff changeset
   695
        if addrs:
15162
d67a15b2e608 patchbomb: simplify some contorted logic and odd variable names.
Greg Ward <greg@gerg.ca>
parents: 14556
diff changeset
   696
            showaddrs.append('%s: %s' % (header, ', '.join(addrs)))
12264
b8146231c3de patchbomb: consistent code style in getaddrs()
Christian Ebert <blacktrash@gmx.net>
parents: 12201
diff changeset
   697
            return mail.addrlistencode(ui, addrs, _charsets, opts.get('test'))
9947
4600e6222efb patchbomb: fix parsing of multiple addresses, allow multiple addrs in --to/cc/bcc
Marti Raudsepp <marti@juffo.org>
parents: 9818
diff changeset
   698
15162
d67a15b2e608 patchbomb: simplify some contorted logic and odd variable names.
Greg Ward <greg@gerg.ca>
parents: 14556
diff changeset
   699
        # not on the command line: fallback to config and then maybe ask
d67a15b2e608 patchbomb: simplify some contorted logic and odd variable names.
Greg Ward <greg@gerg.ca>
parents: 14556
diff changeset
   700
        addr = (ui.config('email', configkey) or
27697
0ce0cfee497f patchbomb: treat empty address list as no addresses
Bryan O'Sullivan <bos@serpentine.com>
parents: 27150
diff changeset
   701
                ui.config('patchbomb', configkey))
0ce0cfee497f patchbomb: treat empty address list as no addresses
Bryan O'Sullivan <bos@serpentine.com>
parents: 27150
diff changeset
   702
        if not addr:
0ce0cfee497f patchbomb: treat empty address list as no addresses
Bryan O'Sullivan <bos@serpentine.com>
parents: 27150
diff changeset
   703
            specified = (ui.hasconfig('email', configkey) or
0ce0cfee497f patchbomb: treat empty address list as no addresses
Bryan O'Sullivan <bos@serpentine.com>
parents: 27150
diff changeset
   704
                         ui.hasconfig('patchbomb', configkey))
0ce0cfee497f patchbomb: treat empty address list as no addresses
Bryan O'Sullivan <bos@serpentine.com>
parents: 27150
diff changeset
   705
            if not specified and ask:
0ce0cfee497f patchbomb: treat empty address list as no addresses
Bryan O'Sullivan <bos@serpentine.com>
parents: 27150
diff changeset
   706
                addr = prompt(ui, header, default=default)
15162
d67a15b2e608 patchbomb: simplify some contorted logic and odd variable names.
Greg Ward <greg@gerg.ca>
parents: 14556
diff changeset
   707
        if addr:
d67a15b2e608 patchbomb: simplify some contorted logic and odd variable names.
Greg Ward <greg@gerg.ca>
parents: 14556
diff changeset
   708
            showaddrs.append('%s: %s' % (header, addr))
15164
7bddec632821 patchbomb: make it easy for the user to decline sending an intro message.
Greg Ward <greg@gerg.ca>
parents: 15162
diff changeset
   709
            return mail.addrlistencode(ui, [addr], _charsets, opts.get('test'))
32826
3abba5bc3454 patchbomb: make getaddrs function easier to work with
Augie Fackler <augie@google.com>
parents: 32825
diff changeset
   710
        elif default:
3abba5bc3454 patchbomb: make getaddrs function easier to work with
Augie Fackler <augie@google.com>
parents: 32825
diff changeset
   711
            return mail.addrlistencode(
3abba5bc3454 patchbomb: make getaddrs function easier to work with
Augie Fackler <augie@google.com>
parents: 32825
diff changeset
   712
                ui, [default], _charsets, opts.get('test'))
3abba5bc3454 patchbomb: make getaddrs function easier to work with
Augie Fackler <augie@google.com>
parents: 32825
diff changeset
   713
        return []
9947
4600e6222efb patchbomb: fix parsing of multiple addresses, allow multiple addrs in --to/cc/bcc
Marti Raudsepp <marti@juffo.org>
parents: 9818
diff changeset
   714
15162
d67a15b2e608 patchbomb: simplify some contorted logic and odd variable names.
Greg Ward <greg@gerg.ca>
parents: 14556
diff changeset
   715
    to = getaddrs('To', ask=True)
15164
7bddec632821 patchbomb: make it easy for the user to decline sending an intro message.
Greg Ward <greg@gerg.ca>
parents: 15162
diff changeset
   716
    if not to:
7bddec632821 patchbomb: make it easy for the user to decline sending an intro message.
Greg Ward <greg@gerg.ca>
parents: 15162
diff changeset
   717
        # we can get here in non-interactive mode
26587
56b2bcea2529 error: get Abort from 'error' instead of 'util'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26563
diff changeset
   718
        raise error.Abort(_('no recipient addresses provided'))
32826
3abba5bc3454 patchbomb: make getaddrs function easier to work with
Augie Fackler <augie@google.com>
parents: 32825
diff changeset
   719
    cc = getaddrs('Cc', ask=True, default='')
3abba5bc3454 patchbomb: make getaddrs function easier to work with
Augie Fackler <augie@google.com>
parents: 32825
diff changeset
   720
    bcc = getaddrs('Bcc')
15162
d67a15b2e608 patchbomb: simplify some contorted logic and odd variable names.
Greg Ward <greg@gerg.ca>
parents: 14556
diff changeset
   721
    replyto = getaddrs('Reply-To')
2679
f1de91be1d87 optionally send blind carbon copies
Christian Ebert <blacktrash@gmx.net>
parents: 2443
diff changeset
   722
23488
11b215731e74 patchbomb: introduce a 'patchbomb.confirm' option
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23487
diff changeset
   723
    confirm = ui.configbool('patchbomb', 'confirm')
11b215731e74 patchbomb: introduce a 'patchbomb.confirm' option
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23487
diff changeset
   724
    confirm |= bool(opts.get('diffstat') or opts.get('confirm'))
11b215731e74 patchbomb: introduce a 'patchbomb.confirm' option
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23487
diff changeset
   725
11b215731e74 patchbomb: introduce a 'patchbomb.confirm' option
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23487
diff changeset
   726
    if confirm:
23173
122f5c3f3308 patchbomb: add label and color to the confirm output
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21727
diff changeset
   727
        ui.write(_('\nFinal summary:\n\n'), label='patchbomb.finalsummary')
122f5c3f3308 patchbomb: add label and color to the confirm output
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21727
diff changeset
   728
        ui.write(('From: %s\n' % sender), label='patchbomb.from')
12200
aebb39d45500 patchbomb: let diffstat prompt only once with complete summary
Christian Ebert <blacktrash@gmx.net>
parents: 12199
diff changeset
   729
        for addr in showaddrs:
23173
122f5c3f3308 patchbomb: add label and color to the confirm output
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21727
diff changeset
   730
            ui.write('%s\n' % addr, label='patchbomb.to')
12200
aebb39d45500 patchbomb: let diffstat prompt only once with complete summary
Christian Ebert <blacktrash@gmx.net>
parents: 12199
diff changeset
   731
        for m, subj, ds in msgs:
23173
122f5c3f3308 patchbomb: add label and color to the confirm output
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21727
diff changeset
   732
            ui.write(('Subject: %s\n' % subj), label='patchbomb.subject')
12200
aebb39d45500 patchbomb: let diffstat prompt only once with complete summary
Christian Ebert <blacktrash@gmx.net>
parents: 12199
diff changeset
   733
            if ds:
23173
122f5c3f3308 patchbomb: add label and color to the confirm output
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21727
diff changeset
   734
                ui.write(ds, label='patchbomb.diffstats')
12200
aebb39d45500 patchbomb: let diffstat prompt only once with complete summary
Christian Ebert <blacktrash@gmx.net>
parents: 12199
diff changeset
   735
        ui.write('\n')
19226
c58b6ab4c26f ui: merge prompt text components into a singe string
Matt Mackall <mpm@selenic.com>
parents: 18888
diff changeset
   736
        if ui.promptchoice(_('are you sure you want to send (yn)?'
c58b6ab4c26f ui: merge prompt text components into a singe string
Matt Mackall <mpm@selenic.com>
parents: 18888
diff changeset
   737
                             '$$ &Yes $$ &No')):
26587
56b2bcea2529 error: get Abort from 'error' instead of 'util'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26563
diff changeset
   738
            raise error.Abort(_('patchbomb canceled'))
12200
aebb39d45500 patchbomb: let diffstat prompt only once with complete summary
Christian Ebert <blacktrash@gmx.net>
parents: 12199
diff changeset
   739
875
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   740
    ui.write('\n')
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   741
8025
1280934dd2dd patchbomb: Support initial in-reply-to header
Henrik Stuart <henrik.stuart at edlund.dk>
parents: 7997
diff changeset
   742
    parent = opts.get('in_reply_to') or None
8826
2aff285b902f patchbomb: do not assume the presence of angle brackets around msg-id
Cédric Duval <cedricduval@free.fr>
parents: 8761
diff changeset
   743
    # angle brackets may be omitted, they're not semantically part of the msg-id
2aff285b902f patchbomb: do not assume the presence of angle brackets around msg-id
Cédric Duval <cedricduval@free.fr>
parents: 8761
diff changeset
   744
    if parent is not None:
2aff285b902f patchbomb: do not assume the presence of angle brackets around msg-id
Cédric Duval <cedricduval@free.fr>
parents: 8761
diff changeset
   745
        if not parent.startswith('<'):
2aff285b902f patchbomb: do not assume the presence of angle brackets around msg-id
Cédric Duval <cedricduval@free.fr>
parents: 8761
diff changeset
   746
            parent = '<' + parent
2aff285b902f patchbomb: do not assume the presence of angle brackets around msg-id
Cédric Duval <cedricduval@free.fr>
parents: 8761
diff changeset
   747
        if not parent.endswith('>'):
2aff285b902f patchbomb: do not assume the presence of angle brackets around msg-id
Cédric Duval <cedricduval@free.fr>
parents: 8761
diff changeset
   748
            parent += '>'
2aff285b902f patchbomb: do not assume the presence of angle brackets around msg-id
Cédric Duval <cedricduval@free.fr>
parents: 8761
diff changeset
   749
36450
d478c8cd89d1 py3: convert bytes to str using encoding.strfromlocal
Pulkit Goyal <7895pulkit@gmail.com>
parents: 36449
diff changeset
   750
    sender_addr = eutil.parseaddr(encoding.strfromlocal(sender))[1]
7115
c5c2d43b01da patchbomb: mime-encode headers and parts not containing patches
Christian Ebert <blacktrash@gmx.net>
parents: 7095
diff changeset
   751
    sender = mail.addressencode(ui, sender, _charsets, opts.get('test'))
5973
ea77f6f77514 patchbomb: undo backout and fix bugs in the earlier patch
Matt Mackall <mpm@selenic.com>
parents: 5948
diff changeset
   752
    sendmail = None
21726
fae032549ca2 patchbomb: always use message-id of first patch for series-id
Augie Fackler <raf@durin42.com>
parents: 21724
diff changeset
   753
    firstpatch = None
38403
8ce3f91d5f6f patchbomb: use progress helper
Martin von Zweigbergk <martinvonz@google.com>
parents: 38402
diff changeset
   754
    progress = ui.makeprogress(_('sending'), unit=_('emails'), total=len(msgs))
12265
1ed2dc9d4368 patchbomb: show progress when sending emails or writing mbox
Yuya Nishihara <yuya@tcha.org>
parents: 12264
diff changeset
   755
    for i, (m, subj, ds) in enumerate(msgs):
875
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   756
        try:
876
14cfaaec2e8e Get patchbomb script to not use MIME attachments.
Bryan O'Sullivan <bos@serpentine.com>
parents: 875
diff changeset
   757
            m['Message-Id'] = genmsgid(m['X-Mercurial-Node'])
21726
fae032549ca2 patchbomb: always use message-id of first patch for series-id
Augie Fackler <raf@durin42.com>
parents: 21724
diff changeset
   758
            if not firstpatch:
fae032549ca2 patchbomb: always use message-id of first patch for series-id
Augie Fackler <raf@durin42.com>
parents: 21724
diff changeset
   759
                firstpatch = m['Message-Id']
21727
5f98ad8fb8d9 patchbomb: reorder header insertions to clarify code
Augie Fackler <raf@durin42.com>
parents: 21726
diff changeset
   760
            m['X-Mercurial-Series-Id'] = firstpatch
875
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   761
        except TypeError:
876
14cfaaec2e8e Get patchbomb script to not use MIME attachments.
Bryan O'Sullivan <bos@serpentine.com>
parents: 875
diff changeset
   762
            m['Message-Id'] = genmsgid('patchbomb')
875
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   763
        if parent:
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   764
            m['In-Reply-To'] = parent
7413
0b6428da1f22 email: add References field in the header
Benoit Allard <benoit@aeteurope.nl>
parents: 7360
diff changeset
   765
            m['References'] = parent
17859
d38d90ad5bbf patchbomb: respect --in-reply-to for all mails if no intro message is sent
Thomas Arendsen Hein <thomas@intevation.de>
parents: 17178
diff changeset
   766
        if not parent or 'X-Mercurial-Node' not in m:
876
14cfaaec2e8e Get patchbomb script to not use MIME attachments.
Bryan O'Sullivan <bos@serpentine.com>
parents: 875
diff changeset
   767
            parent = m['Message-Id']
8514
252232621165 patchbomb: with --in-reply-to, still thread message under first in series
Cédric Duval <cedricduval@free.fr>
parents: 8512
diff changeset
   768
8160
094e0d982c8a patchbomb: add user agent header to mails
Henrik Stuart <hg@hstuart.dk>
parents: 8076
diff changeset
   769
        m['User-Agent'] = 'Mercurial-patchbomb/%s' % util.version()
36448
39c9f339b692 py3: use email.utils module instead of email.Utils
Pulkit Goyal <7895pulkit@gmail.com>
parents: 36446
diff changeset
   770
        m['Date'] = eutil.formatdate(start_time[0], localtime=True)
2443
bd9c39e8f38b patchbomb does not handle email time stamp plattform independent
Volker Kleinfeld <Volker.Kleinfeld@gmx.de>
parents: 2292
diff changeset
   771
4027
2601ac9c54f0 patchbomb: fix timezone offset in message date header
Christian Ebert <blacktrash@gmx.net>
parents: 3473
diff changeset
   772
        start_time = (start_time[0] + 1, start_time[1])
875
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   773
        m['From'] = sender
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   774
        m['To'] = ', '.join(to)
5785
38cd1ce8650d patchbomb: add linebreaks after colons (coding style)
Christian Ebert <blacktrash@gmx.net>
parents: 5758
diff changeset
   775
        if cc:
38cd1ce8650d patchbomb: add linebreaks after colons (coding style)
Christian Ebert <blacktrash@gmx.net>
parents: 5758
diff changeset
   776
            m['Cc']  = ', '.join(cc)
38cd1ce8650d patchbomb: add linebreaks after colons (coding style)
Christian Ebert <blacktrash@gmx.net>
parents: 5758
diff changeset
   777
        if bcc:
38cd1ce8650d patchbomb: add linebreaks after colons (coding style)
Christian Ebert <blacktrash@gmx.net>
parents: 5758
diff changeset
   778
            m['Bcc'] = ', '.join(bcc)
11150
f66ca4431eb9 patchbomb: Reply-To support
Cédric Duval <cedricduval@free.fr>
parents: 10973
diff changeset
   779
        if replyto:
f66ca4431eb9 patchbomb: Reply-To support
Cédric Duval <cedricduval@free.fr>
parents: 10973
diff changeset
   780
            m['Reply-To'] = ', '.join(replyto)
5818
77775ae8d5d9 patchbomb: consistently use opts.get
Christian Ebert <blacktrash@gmx.net>
parents: 5817
diff changeset
   781
        if opts.get('test'):
16931
ee388b0a6f67 patchbomb: lowercase status messages
Martin Geisler <mg@aragost.com>
parents: 16743
diff changeset
   782
            ui.status(_('displaying '), subj, ' ...\n')
31489
5b2e1689b24d patchbomb: use modern pager to display -n/--test result (BC)
Yuya Nishihara <yuya@tcha.org>
parents: 31187
diff changeset
   783
            ui.pager('email')
36435
f449138a52df py3: use email.generator module instead of email.Generator
Pulkit Goyal <7895pulkit@gmail.com>
parents: 36410
diff changeset
   784
            generator = emailgen.Generator(ui, mangle_from_=False)
1871
258e3a7955b8 patchbomb: ignore exception if pager quits.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1846
diff changeset
   785
            try:
6447
9d2ce19bdacd patchbomb: Fix mangling of lines beginning with From
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 6229
diff changeset
   786
                generator.flatten(m, 0)
31489
5b2e1689b24d patchbomb: use modern pager to display -n/--test result (BC)
Yuya Nishihara <yuya@tcha.org>
parents: 31187
diff changeset
   787
                ui.write('\n')
25660
328739ea70c3 global: mass rewrite to use modern exception syntax
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25202
diff changeset
   788
            except IOError as inst:
1871
258e3a7955b8 patchbomb: ignore exception if pager quits.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1846
diff changeset
   789
                if inst.errno != errno.EPIPE:
258e3a7955b8 patchbomb: ignore exception if pager quits.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1846
diff changeset
   790
                    raise
15560
cc58c228503e mail: mbox handling as a part of mail handling, refactored from patchbomb
Mads Kiilerich <mads@kiilerich.com>
parents: 15559
diff changeset
   791
        else:
cc58c228503e mail: mbox handling as a part of mail handling, refactored from patchbomb
Mads Kiilerich <mads@kiilerich.com>
parents: 15559
diff changeset
   792
            if not sendmail:
29285
63a3749147af mail: unsupport smtp.verifycert (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29205
diff changeset
   793
                sendmail = mail.connect(ui, mbox=mbox)
16931
ee388b0a6f67 patchbomb: lowercase status messages
Martin Geisler <mg@aragost.com>
parents: 16743
diff changeset
   794
            ui.status(_('sending '), subj, ' ...\n')
38403
8ce3f91d5f6f patchbomb: use progress helper
Martin von Zweigbergk <martinvonz@google.com>
parents: 38402
diff changeset
   795
            progress.update(i, item=subj)
15560
cc58c228503e mail: mbox handling as a part of mail handling, refactored from patchbomb
Mads Kiilerich <mads@kiilerich.com>
parents: 15559
diff changeset
   796
            if not mbox:
cc58c228503e mail: mbox handling as a part of mail handling, refactored from patchbomb
Mads Kiilerich <mads@kiilerich.com>
parents: 15559
diff changeset
   797
                # Exim does not remove the Bcc field
cc58c228503e mail: mbox handling as a part of mail handling, refactored from patchbomb
Mads Kiilerich <mads@kiilerich.com>
parents: 15559
diff changeset
   798
                del m['Bcc']
28861
86db5cb55d46 pycompat: switch to util.stringio for py3 compat
timeless <timeless@mozdev.org>
parents: 28474
diff changeset
   799
            fp = stringio()
36435
f449138a52df py3: use email.generator module instead of email.Generator
Pulkit Goyal <7895pulkit@gmail.com>
parents: 36410
diff changeset
   800
            generator = emailgen.Generator(fp, mangle_from_=False)
6447
9d2ce19bdacd patchbomb: Fix mangling of lines beginning with From
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 6229
diff changeset
   801
            generator.flatten(m, 0)
15559
1830d0cc4bc1 patchbomb: minor refactoring of mbox functionality, preparing for move
Mads Kiilerich <mads@kiilerich.com>
parents: 15166
diff changeset
   802
            sendmail(sender_addr, to + bcc + cc, fp.getvalue())
875
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   803
38403
8ce3f91d5f6f patchbomb: use progress helper
Martin von Zweigbergk <martinvonz@google.com>
parents: 38402
diff changeset
   804
    progress.complete()