annotate hgext/patchbomb.py @ 30283:e1f6898a80e1

color: restore _style global after debugcolor ran Before this change, running 'debugcolor' would destroy all color style for the rest of the process life. We now properly backup and restore the variable content. Using a global variable is sketchy in general and could probably be removed. However, this is a quest for another adventure.
author Pierre-Yves David <pierre-yves.david@ens-lyon.org>
date Thu, 03 Nov 2016 14:29:19 +0100
parents d5883fd055c6
children e1677cc29da6
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
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
11b215731e74 patchbomb: introduce a 'patchbomb.confirm' option
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23487
diff changeset
63 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
64 ``patchbomb.confirm`` to true.
9071
141e3ef20d84 patchbomb: wrapped docstrings at 78 characters
Martin Geisler <mg@lazybytes.net>
parents: 9047
diff changeset
65 '''
28415
21524ae331b7 patchbomb: use absolute_import
timeless <timeless@mozdev.org>
parents: 27767
diff changeset
66 from __future__ import absolute_import
875
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
67
27150
88aaddb1af88 patchbomb: rename email function
timeless <timeless@mozdev.org>
parents: 26626
diff changeset
68 import email as emailmod
28415
21524ae331b7 patchbomb: use absolute_import
timeless <timeless@mozdev.org>
parents: 27767
diff changeset
69 import errno
21524ae331b7 patchbomb: use absolute_import
timeless <timeless@mozdev.org>
parents: 27767
diff changeset
70 import os
21524ae331b7 patchbomb: use absolute_import
timeless <timeless@mozdev.org>
parents: 27767
diff changeset
71 import socket
21524ae331b7 patchbomb: use absolute_import
timeless <timeless@mozdev.org>
parents: 27767
diff changeset
72 import tempfile
19810
c80feeb715d1 python2.4: fix imports of sub-packages of the email package
Augie Fackler <raf@durin42.com>
parents: 19791
diff changeset
73
29205
a0939666b836 py3: move up symbol imports to enforce import-checker rules
Yuya Nishihara <yuya@tcha.org>
parents: 28981
diff changeset
74 from mercurial.i18n import _
28415
21524ae331b7 patchbomb: use absolute_import
timeless <timeless@mozdev.org>
parents: 27767
diff changeset
75 from mercurial import (
21524ae331b7 patchbomb: use absolute_import
timeless <timeless@mozdev.org>
parents: 27767
diff changeset
76 cmdutil,
21524ae331b7 patchbomb: use absolute_import
timeless <timeless@mozdev.org>
parents: 27767
diff changeset
77 commands,
21524ae331b7 patchbomb: use absolute_import
timeless <timeless@mozdev.org>
parents: 27767
diff changeset
78 error,
21524ae331b7 patchbomb: use absolute_import
timeless <timeless@mozdev.org>
parents: 27767
diff changeset
79 hg,
21524ae331b7 patchbomb: use absolute_import
timeless <timeless@mozdev.org>
parents: 27767
diff changeset
80 mail,
21524ae331b7 patchbomb: use absolute_import
timeless <timeless@mozdev.org>
parents: 27767
diff changeset
81 node as nodemod,
21524ae331b7 patchbomb: use absolute_import
timeless <timeless@mozdev.org>
parents: 27767
diff changeset
82 patch,
21524ae331b7 patchbomb: use absolute_import
timeless <timeless@mozdev.org>
parents: 27767
diff changeset
83 scmutil,
21524ae331b7 patchbomb: use absolute_import
timeless <timeless@mozdev.org>
parents: 27767
diff changeset
84 util,
21524ae331b7 patchbomb: use absolute_import
timeless <timeless@mozdev.org>
parents: 27767
diff changeset
85 )
28861
86db5cb55d46 pycompat: switch to util.stringio for py3 compat
timeless <timeless@mozdev.org>
parents: 28474
diff changeset
86 stringio = util.stringio
875
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
87
14309
37e80214badf patchbomb: use cmdutil.command decorator
Adrian Buehlmann <adrian@cadifra.com>
parents: 14290
diff changeset
88 cmdtable = {}
37e80214badf patchbomb: use cmdutil.command decorator
Adrian Buehlmann <adrian@cadifra.com>
parents: 14290
diff changeset
89 command = cmdutil.command(cmdtable)
29841
d5883fd055c6 extensions: change magic "shipped with hg" string
Augie Fackler <augie@google.com>
parents: 29285
diff changeset
90 # 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
91 # 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
92 # 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
93 # leave the attribute unspecified.
29841
d5883fd055c6 extensions: change magic "shipped with hg" string
Augie Fackler <augie@google.com>
parents: 29285
diff changeset
94 testedwith = 'ships-with-hg-core'
14309
37e80214badf patchbomb: use cmdutil.command decorator
Adrian Buehlmann <adrian@cadifra.com>
parents: 14290
diff changeset
95
26546
500386e65759 patchbomb: add experimental config of a "pullurl" and export it
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25826
diff changeset
96 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
97 """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
98 """
500386e65759 patchbomb: add experimental config of a "pullurl" and export it
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25826
diff changeset
99 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
100 # 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
101 # 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
102 # destination before patchbombing anything.
500386e65759 patchbomb: add experimental config of a "pullurl" and export it
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25826
diff changeset
103 pullurl = repo.ui.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
104 if pullurl is not None:
500386e65759 patchbomb: add experimental config of a "pullurl" and export it
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25826
diff changeset
105 return ('Available At %s\n'
500386e65759 patchbomb: add experimental config of a "pullurl" and export it
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25826
diff changeset
106 '# hg pull %s -r %s' % (pullurl, pullurl, ctx))
500386e65759 patchbomb: add experimental config of a "pullurl" and export it
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25826
diff changeset
107 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
108
500386e65759 patchbomb: add experimental config of a "pullurl" and export it
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25826
diff changeset
109 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
110 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
111 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
112
500386e65759 patchbomb: add experimental config of a "pullurl" and export it
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25826
diff changeset
113
9648
6064de41b7e4 patchbomb: accept default if it is empty string
Alexander Solovyov <piranha@piranha.org.ua>
parents: 9647
diff changeset
114 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
115 if default:
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
116 prompt += ' [%s]' % default
15166
9ec9dd8d1b24 patchbomb: drop loop in prompt
Matt Mackall <mpm@selenic.com>
parents: 15165
diff changeset
117 return ui.prompt(prompt + rest, default)
7354
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
118
23487
c14af817ab76 patchbomb: add a 'patchbomb.intro' option
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23486
diff changeset
119 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
120 '''is an introductory message apparently wanted?'''
23487
c14af817ab76 patchbomb: add a 'patchbomb.intro' option
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23486
diff changeset
121 introconfig = ui.config('patchbomb', 'intro', 'auto')
c14af817ab76 patchbomb: add a 'patchbomb.intro' option
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23486
diff changeset
122 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
123 intro = True
c14af817ab76 patchbomb: add a 'patchbomb.intro' option
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23486
diff changeset
124 elif introconfig == 'always':
c14af817ab76 patchbomb: add a 'patchbomb.intro' option
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23486
diff changeset
125 intro = True
c14af817ab76 patchbomb: add a 'patchbomb.intro' option
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23486
diff changeset
126 elif introconfig == 'never':
c14af817ab76 patchbomb: add a 'patchbomb.intro' option
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23486
diff changeset
127 intro = False
c14af817ab76 patchbomb: add a 'patchbomb.intro' option
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23486
diff changeset
128 elif introconfig == 'auto':
c14af817ab76 patchbomb: add a 'patchbomb.intro' option
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23486
diff changeset
129 intro = 1 < number
c14af817ab76 patchbomb: add a 'patchbomb.intro' option
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23486
diff changeset
130 else:
c14af817ab76 patchbomb: add a 'patchbomb.intro' option
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23486
diff changeset
131 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
132 % introconfig)
c14af817ab76 patchbomb: add a 'patchbomb.intro' option
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23486
diff changeset
133 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
134 intro = 1 < number
c14af817ab76 patchbomb: add a 'patchbomb.intro' option
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23486
diff changeset
135 return intro
10734
7a0502a6f9a1 patchbomb: --desc implies --intro
Cédric Duval <cedricduval@free.fr>
parents: 10611
diff changeset
136
15164
7bddec632821 patchbomb: make it easy for the user to decline sending an intro message.
Greg Ward <greg@gerg.ca>
parents: 15162
diff changeset
137 def makepatch(ui, repo, 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
138 patchname=None):
7354
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
139
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
140 desc = []
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
141 node = None
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
142 body = ''
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
143
12199
17d604e522b4 patchbomb: rename argument to avoid shadowing patch module
Martin Geisler <mg@lazybytes.net>
parents: 12197
diff changeset
144 for line in patchlines:
7354
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
145 if line.startswith('#'):
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
146 if line.startswith('# Node ID'):
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
147 node = line.split()[-1]
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
148 continue
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
149 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
150 break
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
151 desc.append(line)
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
152
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
153 if not patchname and not node:
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
154 raise ValueError
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
155
16307
17a9a1f5cee2 patchbomb: add --body flag to send patches as inline message body text
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16233
diff changeset
156 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
157 body = ('\n'.join(desc[1:]).strip() or
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
158 'Patch subject is complete summary.')
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
159 body += '\n\n\n'
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
160
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
161 if opts.get('plain'):
12199
17d604e522b4 patchbomb: rename argument to avoid shadowing patch module
Martin Geisler <mg@lazybytes.net>
parents: 12197
diff changeset
162 while patchlines and patchlines[0].startswith('# '):
17d604e522b4 patchbomb: rename argument to avoid shadowing patch module
Martin Geisler <mg@lazybytes.net>
parents: 12197
diff changeset
163 patchlines.pop(0)
17d604e522b4 patchbomb: rename argument to avoid shadowing patch module
Martin Geisler <mg@lazybytes.net>
parents: 12197
diff changeset
164 if patchlines:
17d604e522b4 patchbomb: rename argument to avoid shadowing patch module
Martin Geisler <mg@lazybytes.net>
parents: 12197
diff changeset
165 patchlines.pop(0)
17d604e522b4 patchbomb: rename argument to avoid shadowing patch module
Martin Geisler <mg@lazybytes.net>
parents: 12197
diff changeset
166 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
167 patchlines.pop(0)
7354
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
168
14397
0368ad7963be patchbomb: pass --git argument to diffstat
Idan Kamara <idankk86@gmail.com>
parents: 14319
diff changeset
169 ds = patch.diffstat(patchlines, git=opts.get('git'))
7354
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
170 if opts.get('diffstat'):
12200
aebb39d45500 patchbomb: let diffstat prompt only once with complete summary
Christian Ebert <blacktrash@gmx.net>
parents: 12199
diff changeset
171 body += ds + '\n\n'
7354
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
172
16307
17a9a1f5cee2 patchbomb: add --body flag to send patches as inline message body text
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16233
diff changeset
173 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
174 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
175 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
176
17a9a1f5cee2 patchbomb: add --body flag to send patches as inline message body text
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16233
diff changeset
177 if addattachment:
27150
88aaddb1af88 patchbomb: rename email function
timeless <timeless@mozdev.org>
parents: 26626
diff changeset
178 msg = emailmod.MIMEMultipart.MIMEMultipart()
7354
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
179 if body:
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
180 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
181 p = mail.mimetextpatch('\n'.join(patchlines), 'x-patch',
525fdb738975 cleanup: eradicate long lines
Brodie Rao <brodie@sf.io>
parents: 16307
diff changeset
182 opts.get('test'))
28415
21524ae331b7 patchbomb: use absolute_import
timeless <timeless@mozdev.org>
parents: 27767
diff changeset
183 binnode = nodemod.bin(node)
8761
0289f384e1e5 Generally replace "file name" with "filename" in help and comments.
timeless <timeless@gmail.com>
parents: 8520
diff changeset
184 # 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
185 if not patchname:
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
186 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
187 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
188 if patchtags:
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
189 patchname = patchtags[0]
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
190 elif total > 1:
14290
86e70956da4f cmdutil: make_filename -> makefilename
Matt Mackall <mpm@selenic.com>
parents: 14076
diff changeset
191 patchname = cmdutil.makefilename(repo, '%b-%n.patch',
16683
525fdb738975 cleanup: eradicate long lines
Brodie Rao <brodie@sf.io>
parents: 16307
diff changeset
192 binnode, seqno=idx,
525fdb738975 cleanup: eradicate long lines
Brodie Rao <brodie@sf.io>
parents: 16307
diff changeset
193 total=total)
7354
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
194 else:
14290
86e70956da4f cmdutil: make_filename -> makefilename
Matt Mackall <mpm@selenic.com>
parents: 14076
diff changeset
195 patchname = cmdutil.makefilename(repo, '%b.patch', binnode)
7354
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
196 disposition = 'inline'
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
197 if opts.get('attach'):
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
198 disposition = 'attachment'
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
199 p['Content-Disposition'] = disposition + '; filename=' + patchname
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
200 msg.attach(p)
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
201 else:
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
202 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
203
9346
bb3f8f692bc6 patchbomb: add --flag to put flags in subject prefixes
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9300
diff changeset
204 flag = ' '.join(opts.get('flag'))
bb3f8f692bc6 patchbomb: add --flag to put flags in subject prefixes
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9300
diff changeset
205 if flag:
bb3f8f692bc6 patchbomb: add --flag to put flags in subject prefixes
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9300
diff changeset
206 flag = ' ' + flag
bb3f8f692bc6 patchbomb: add --flag to put flags in subject prefixes
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9300
diff changeset
207
7354
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
208 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
209 if not numbered:
9346
bb3f8f692bc6 patchbomb: add --flag to put flags in subject prefixes
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9300
diff changeset
210 subj = '[PATCH%s] %s' % (flag, opts.get('subject') or subj)
7354
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
211 else:
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
212 tlen = len(str(total))
9346
bb3f8f692bc6 patchbomb: add --flag to put flags in subject prefixes
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9300
diff changeset
213 subj = '[PATCH %0*d of %d%s] %s' % (tlen, idx, total, flag, subj)
7354
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
214 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
215 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
216 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
217 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
218 return msg, subj, ds
7354
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
219
23210
79f7444520bf patchbomb: extract 'getpatches' closure in its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23173
diff changeset
220 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
221 """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
222
79f7444520bf patchbomb: extract 'getpatches' closure in its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23173
diff changeset
223 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
224 """
79f7444520bf patchbomb: extract 'getpatches' closure in its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23173
diff changeset
225 ui = repo.ui
79f7444520bf patchbomb: extract 'getpatches' closure in its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23173
diff changeset
226 prev = repo['.'].rev()
24568
2e5f6cdf01f6 patchbomb: factor out scmutil.revrange() calls
Yuya Nishihara <yuya@tcha.org>
parents: 24567
diff changeset
227 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
228 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
229 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
230 'uncommitted changes\n'))
28861
86db5cb55d46 pycompat: switch to util.stringio for py3 compat
timeless <timeless@mozdev.org>
parents: 28474
diff changeset
231 output = stringio()
23210
79f7444520bf patchbomb: extract 'getpatches' closure in its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23173
diff changeset
232 cmdutil.export(repo, [r], fp=output,
23450
a074eeeabe32 patchbomb: don't honor whitespace and format-changing diffopts (BC)
Siddharth Agarwal <sid0@fb.com>
parents: 23215
diff changeset
233 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
234 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
235 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
236 """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
237
6993282e5362 patchbomb: extract 'getbundle' closure in its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23210
diff changeset
238 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
239 `bundle` command.
6993282e5362 patchbomb: extract 'getbundle' closure in its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23210
diff changeset
240
6993282e5362 patchbomb: extract 'getbundle' closure in its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23210
diff changeset
241 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
242 """
6993282e5362 patchbomb: extract 'getbundle' closure in its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23210
diff changeset
243 ui = repo.ui
6993282e5362 patchbomb: extract 'getbundle' closure in its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23210
diff changeset
244 tmpdir = tempfile.mkdtemp(prefix='hg-email-bundle-')
6993282e5362 patchbomb: extract 'getbundle' closure in its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23210
diff changeset
245 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
246 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
247 if btype:
d4a1bfe1de63 patchbomb: add a 'bundletype' config under 'patchbomb'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26546
diff changeset
248 opts['type'] = btype
23211
6993282e5362 patchbomb: extract 'getbundle' closure in its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23210
diff changeset
249 try:
6993282e5362 patchbomb: extract 'getbundle' closure in its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23210
diff changeset
250 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
251 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
252 finally:
6993282e5362 patchbomb: extract 'getbundle' closure in its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23210
diff changeset
253 try:
6993282e5362 patchbomb: extract 'getbundle' closure in its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23210
diff changeset
254 os.unlink(tmpfn)
6993282e5362 patchbomb: extract 'getbundle' closure in its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23210
diff changeset
255 except OSError:
6993282e5362 patchbomb: extract 'getbundle' closure in its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23210
diff changeset
256 pass
6993282e5362 patchbomb: extract 'getbundle' closure in its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23210
diff changeset
257 os.rmdir(tmpdir)
6993282e5362 patchbomb: extract 'getbundle' closure in its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23210
diff changeset
258
23212
4b4eae00f9dd patchbomb: extract 'getdescription' closure in its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23211
diff changeset
259 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
260 """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
261
4b4eae00f9dd patchbomb: extract 'getdescription' closure in its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23211
diff changeset
262 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
263
4b4eae00f9dd patchbomb: extract 'getdescription' closure in its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23211
diff changeset
264 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
265 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
266 """
4b4eae00f9dd patchbomb: extract 'getdescription' closure in its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23211
diff changeset
267 ui = repo.ui
4b4eae00f9dd patchbomb: extract 'getdescription' closure in its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23211
diff changeset
268 if opts.get('desc'):
4b4eae00f9dd patchbomb: extract 'getdescription' closure in its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23211
diff changeset
269 body = open(opts.get('desc')).read()
4b4eae00f9dd patchbomb: extract 'getdescription' closure in its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23211
diff changeset
270 else:
4b4eae00f9dd patchbomb: extract 'getdescription' closure in its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23211
diff changeset
271 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
272 'patch series.\n\n'))
4b4eae00f9dd patchbomb: extract 'getdescription' closure in its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23211
diff changeset
273 body = ui.edit(defaultbody, sender)
4b4eae00f9dd patchbomb: extract 'getdescription' closure in its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23211
diff changeset
274 # 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
275 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
276 msgfile.write(body)
4b4eae00f9dd patchbomb: extract 'getdescription' closure in its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23211
diff changeset
277 msgfile.close()
4b4eae00f9dd patchbomb: extract 'getdescription' closure in its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23211
diff changeset
278 return body
23211
6993282e5362 patchbomb: extract 'getbundle' closure in its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23210
diff changeset
279
23213
23a78662b6dd patchbomb: extract 'getbundlemsgs' closure in its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23212
diff changeset
280 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
281 """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
282
23a78662b6dd patchbomb: extract 'getbundlemsgs' closure in its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23212
diff changeset
283 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
284 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
285 """
23a78662b6dd patchbomb: extract 'getbundlemsgs' closure in its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23212
diff changeset
286 ui = repo.ui
23a78662b6dd patchbomb: extract 'getbundlemsgs' closure in its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23212
diff changeset
287 _charsets = mail._charsets(ui)
23a78662b6dd patchbomb: extract 'getbundlemsgs' closure in its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23212
diff changeset
288 subj = (opts.get('subject')
23a78662b6dd patchbomb: extract 'getbundlemsgs' closure in its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23212
diff changeset
289 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
290
23a78662b6dd patchbomb: extract 'getbundlemsgs' closure in its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23212
diff changeset
291 body = _getdescription(repo, '', sender, **opts)
27150
88aaddb1af88 patchbomb: rename email function
timeless <timeless@mozdev.org>
parents: 26626
diff changeset
292 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
293 if body:
23a78662b6dd patchbomb: extract 'getbundlemsgs' closure in its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23212
diff changeset
294 msg.attach(mail.mimeencode(ui, body, _charsets, opts.get('test')))
27150
88aaddb1af88 patchbomb: rename email function
timeless <timeless@mozdev.org>
parents: 26626
diff changeset
295 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
296 datapart.set_payload(bundle)
23a78662b6dd patchbomb: extract 'getbundlemsgs' closure in its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23212
diff changeset
297 bundlename = '%s.hg' % opts.get('bundlename', 'bundle')
23a78662b6dd patchbomb: extract 'getbundlemsgs' closure in its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23212
diff changeset
298 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
299 filename=bundlename)
27150
88aaddb1af88 patchbomb: rename email function
timeless <timeless@mozdev.org>
parents: 26626
diff changeset
300 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
301 msg.attach(datapart)
23a78662b6dd patchbomb: extract 'getbundlemsgs' closure in its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23212
diff changeset
302 msg['Subject'] = mail.headencode(ui, subj, _charsets, opts.get('test'))
23a78662b6dd patchbomb: extract 'getbundlemsgs' closure in its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23212
diff changeset
303 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
304
23214
563d33fc4b3d patchbomb: extract 'makeintro' closure into its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23213
diff changeset
305 def _makeintro(repo, sender, patches, **opts):
563d33fc4b3d patchbomb: extract 'makeintro' closure into its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23213
diff changeset
306 """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
307
563d33fc4b3d patchbomb: extract 'makeintro' closure into its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23213
diff changeset
308 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
309 ui = repo.ui
563d33fc4b3d patchbomb: extract 'makeintro' closure into its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23213
diff changeset
310 _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
311 tlen = len(str(len(patches)))
563d33fc4b3d patchbomb: extract 'makeintro' closure into its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23213
diff changeset
312
563d33fc4b3d patchbomb: extract 'makeintro' closure into its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23213
diff changeset
313 flag = opts.get('flag') or ''
563d33fc4b3d patchbomb: extract 'makeintro' closure into its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23213
diff changeset
314 if flag:
563d33fc4b3d patchbomb: extract 'makeintro' closure into its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23213
diff changeset
315 flag = ' ' + ' '.join(flag)
563d33fc4b3d patchbomb: extract 'makeintro' closure into its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23213
diff changeset
316 prefix = '[PATCH %0*d of %d%s]' % (tlen, 0, len(patches), flag)
563d33fc4b3d patchbomb: extract 'makeintro' closure into its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23213
diff changeset
317
563d33fc4b3d patchbomb: extract 'makeintro' closure into its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23213
diff changeset
318 subj = (opts.get('subject') or
563d33fc4b3d patchbomb: extract 'makeintro' closure into its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23213
diff changeset
319 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
320 if not subj:
563d33fc4b3d patchbomb: extract 'makeintro' closure into its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23213
diff changeset
321 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
322
563d33fc4b3d patchbomb: extract 'makeintro' closure into its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23213
diff changeset
323 subj = prefix + ' ' + subj
563d33fc4b3d patchbomb: extract 'makeintro' closure into its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23213
diff changeset
324
563d33fc4b3d patchbomb: extract 'makeintro' closure into its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23213
diff changeset
325 body = ''
563d33fc4b3d patchbomb: extract 'makeintro' closure into its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23213
diff changeset
326 if opts.get('diffstat'):
563d33fc4b3d patchbomb: extract 'makeintro' closure into its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23213
diff changeset
327 # 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
328 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
329 body = '\n' + diffstat
563d33fc4b3d patchbomb: extract 'makeintro' closure into its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23213
diff changeset
330 else:
563d33fc4b3d patchbomb: extract 'makeintro' closure into its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23213
diff changeset
331 diffstat = None
563d33fc4b3d patchbomb: extract 'makeintro' closure into its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23213
diff changeset
332
563d33fc4b3d patchbomb: extract 'makeintro' closure into its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23213
diff changeset
333 body = _getdescription(repo, body, sender, **opts)
563d33fc4b3d patchbomb: extract 'makeintro' closure into its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23213
diff changeset
334 msg = mail.mimeencode(ui, body, _charsets, opts.get('test'))
563d33fc4b3d patchbomb: extract 'makeintro' closure into its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23213
diff changeset
335 msg['Subject'] = mail.headencode(ui, subj, _charsets,
563d33fc4b3d patchbomb: extract 'makeintro' closure into its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23213
diff changeset
336 opts.get('test'))
563d33fc4b3d patchbomb: extract 'makeintro' closure into its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23213
diff changeset
337 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
338
23215
83a191031f94 patchbomb: extract 'getpatchmsgs' closure into its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23214
diff changeset
339 def _getpatchmsgs(repo, sender, patches, patchnames=None, **opts):
83a191031f94 patchbomb: extract 'getpatchmsgs' closure into its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23214
diff changeset
340 """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
341
83a191031f94 patchbomb: extract 'getpatchmsgs' closure into its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23214
diff changeset
342 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
343
83a191031f94 patchbomb: extract 'getpatchmsgs' closure into its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23214
diff changeset
344 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
345 """
83a191031f94 patchbomb: extract 'getpatchmsgs' closure into its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23214
diff changeset
346 ui = repo.ui
83a191031f94 patchbomb: extract 'getpatchmsgs' closure into its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23214
diff changeset
347 _charsets = mail._charsets(ui)
83a191031f94 patchbomb: extract 'getpatchmsgs' closure into its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23214
diff changeset
348 msgs = []
83a191031f94 patchbomb: extract 'getpatchmsgs' closure into its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23214
diff changeset
349
83a191031f94 patchbomb: extract 'getpatchmsgs' closure into its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23214
diff changeset
350 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
351 % len(patches))
83a191031f94 patchbomb: extract 'getpatchmsgs' closure into its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23214
diff changeset
352
83a191031f94 patchbomb: extract 'getpatchmsgs' closure into its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23214
diff changeset
353 # build the intro message, or skip it if the user declines
23487
c14af817ab76 patchbomb: add a 'patchbomb.intro' option
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23486
diff changeset
354 if introwanted(ui, opts, len(patches)):
23215
83a191031f94 patchbomb: extract 'getpatchmsgs' closure into its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23214
diff changeset
355 msg = _makeintro(repo, sender, patches, **opts)
83a191031f94 patchbomb: extract 'getpatchmsgs' closure into its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23214
diff changeset
356 if msg:
83a191031f94 patchbomb: extract 'getpatchmsgs' closure into its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23214
diff changeset
357 msgs.append(msg)
83a191031f94 patchbomb: extract 'getpatchmsgs' closure into its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23214
diff changeset
358
83a191031f94 patchbomb: extract 'getpatchmsgs' closure into its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23214
diff changeset
359 # 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
360 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
361
83a191031f94 patchbomb: extract 'getpatchmsgs' closure into its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23214
diff changeset
362 # 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
363 name = None
83a191031f94 patchbomb: extract 'getpatchmsgs' closure into its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23214
diff changeset
364 for i, p in enumerate(patches):
83a191031f94 patchbomb: extract 'getpatchmsgs' closure into its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23214
diff changeset
365 if patchnames:
83a191031f94 patchbomb: extract 'getpatchmsgs' closure into its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23214
diff changeset
366 name = patchnames[i]
83a191031f94 patchbomb: extract 'getpatchmsgs' closure into its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23214
diff changeset
367 msg = makepatch(ui, repo, p, opts, _charsets, i + 1,
83a191031f94 patchbomb: extract 'getpatchmsgs' closure into its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23214
diff changeset
368 len(patches), numbered, name)
83a191031f94 patchbomb: extract 'getpatchmsgs' closure into its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23214
diff changeset
369 msgs.append(msg)
83a191031f94 patchbomb: extract 'getpatchmsgs' closure into its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23214
diff changeset
370
83a191031f94 patchbomb: extract 'getpatchmsgs' closure into its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23214
diff changeset
371 return msgs
83a191031f94 patchbomb: extract 'getpatchmsgs' closure into its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23214
diff changeset
372
23486
1de214837f5e patchbomb: extract 'getoutgoing' closure into its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23450
diff changeset
373 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
374 '''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
375 ui = repo.ui
1de214837f5e patchbomb: extract 'getoutgoing' closure into its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23450
diff changeset
376 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
377 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
378 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
379
24568
2e5f6cdf01f6 patchbomb: factor out scmutil.revrange() calls
Yuya Nishihara <yuya@tcha.org>
parents: 24567
diff changeset
380 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
381 if not revs:
1de214837f5e patchbomb: extract 'getoutgoing' closure into its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23450
diff changeset
382 revs = [len(repo) - 1]
1de214837f5e patchbomb: extract 'getoutgoing' closure into its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23450
diff changeset
383 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
384 if not revs:
1de214837f5e patchbomb: extract 'getoutgoing' closure into its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23450
diff changeset
385 ui.status(_("no changes found\n"))
24567
13f0af2a5a4c patchbomb: return outgoing revs as a smartset
Yuya Nishihara <yuya@tcha.org>
parents: 24306
diff changeset
386 return revs
23486
1de214837f5e patchbomb: extract 'getoutgoing' closure into its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23450
diff changeset
387
14309
37e80214badf patchbomb: use cmdutil.command decorator
Adrian Buehlmann <adrian@cadifra.com>
parents: 14290
diff changeset
388 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
389 ('', '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
390 ('a', 'attach', None, _('send patches as attachments')),
37e80214badf patchbomb: use cmdutil.command decorator
Adrian Buehlmann <adrian@cadifra.com>
parents: 14290
diff changeset
391 ('i', 'inline', None, _('send patches as inline attachments')),
37e80214badf patchbomb: use cmdutil.command decorator
Adrian Buehlmann <adrian@cadifra.com>
parents: 14290
diff changeset
392 ('', 'bcc', [], _('email addresses of blind carbon copy recipients')),
37e80214badf patchbomb: use cmdutil.command decorator
Adrian Buehlmann <adrian@cadifra.com>
parents: 14290
diff changeset
393 ('c', 'cc', [], _('email addresses of copy recipients')),
37e80214badf patchbomb: use cmdutil.command decorator
Adrian Buehlmann <adrian@cadifra.com>
parents: 14290
diff changeset
394 ('', 'confirm', None, _('ask for confirmation before sending')),
37e80214badf patchbomb: use cmdutil.command decorator
Adrian Buehlmann <adrian@cadifra.com>
parents: 14290
diff changeset
395 ('d', 'diffstat', None, _('add diffstat output to messages')),
37e80214badf patchbomb: use cmdutil.command decorator
Adrian Buehlmann <adrian@cadifra.com>
parents: 14290
diff changeset
396 ('', 'date', '', _('use the given date as the sending date')),
37e80214badf patchbomb: use cmdutil.command decorator
Adrian Buehlmann <adrian@cadifra.com>
parents: 14290
diff changeset
397 ('', 'desc', '', _('use the given file as the series description')),
37e80214badf patchbomb: use cmdutil.command decorator
Adrian Buehlmann <adrian@cadifra.com>
parents: 14290
diff changeset
398 ('f', 'from', '', _('email address of sender')),
37e80214badf patchbomb: use cmdutil.command decorator
Adrian Buehlmann <adrian@cadifra.com>
parents: 14290
diff changeset
399 ('n', 'test', None, _('print messages that would be sent')),
37e80214badf patchbomb: use cmdutil.command decorator
Adrian Buehlmann <adrian@cadifra.com>
parents: 14290
diff changeset
400 ('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
401 ('', 'reply-to', [], _('email addresses replies should be sent to')),
37e80214badf patchbomb: use cmdutil.command decorator
Adrian Buehlmann <adrian@cadifra.com>
parents: 14290
diff changeset
402 ('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
403 ('', 'in-reply-to', '', _('message identifier to reply to')),
37e80214badf patchbomb: use cmdutil.command decorator
Adrian Buehlmann <adrian@cadifra.com>
parents: 14290
diff changeset
404 ('', 'flag', [], _('flags to add in subject prefixes')),
37e80214badf patchbomb: use cmdutil.command decorator
Adrian Buehlmann <adrian@cadifra.com>
parents: 14290
diff changeset
405 ('t', 'to', [], _('email addresses of recipients'))]
37e80214badf patchbomb: use cmdutil.command decorator
Adrian Buehlmann <adrian@cadifra.com>
parents: 14290
diff changeset
406
37e80214badf patchbomb: use cmdutil.command decorator
Adrian Buehlmann <adrian@cadifra.com>
parents: 14290
diff changeset
407 @command('email',
37e80214badf patchbomb: use cmdutil.command decorator
Adrian Buehlmann <adrian@cadifra.com>
parents: 14290
diff changeset
408 [('g', 'git', None, _('use git extended diff format')),
37e80214badf patchbomb: use cmdutil.command decorator
Adrian Buehlmann <adrian@cadifra.com>
parents: 14290
diff changeset
409 ('', 'plain', None, _('omit hg patch header')),
37e80214badf patchbomb: use cmdutil.command decorator
Adrian Buehlmann <adrian@cadifra.com>
parents: 14290
diff changeset
410 ('o', 'outgoing', None,
37e80214badf patchbomb: use cmdutil.command decorator
Adrian Buehlmann <adrian@cadifra.com>
parents: 14290
diff changeset
411 _('send changes not found in the target repository')),
37e80214badf patchbomb: use cmdutil.command decorator
Adrian Buehlmann <adrian@cadifra.com>
parents: 14290
diff changeset
412 ('b', 'bundle', None, _('send changes not in target as a binary bundle')),
37e80214badf patchbomb: use cmdutil.command decorator
Adrian Buehlmann <adrian@cadifra.com>
parents: 14290
diff changeset
413 ('', 'bundlename', 'bundle',
37e80214badf patchbomb: use cmdutil.command decorator
Adrian Buehlmann <adrian@cadifra.com>
parents: 14290
diff changeset
414 _('name of the bundle attachment file'), _('NAME')),
37e80214badf patchbomb: use cmdutil.command decorator
Adrian Buehlmann <adrian@cadifra.com>
parents: 14290
diff changeset
415 ('r', 'rev', [], _('a revision to send'), _('REV')),
37e80214badf patchbomb: use cmdutil.command decorator
Adrian Buehlmann <adrian@cadifra.com>
parents: 14290
diff changeset
416 ('', 'force', None, _('run even when remote repository is unrelated '
37e80214badf patchbomb: use cmdutil.command decorator
Adrian Buehlmann <adrian@cadifra.com>
parents: 14290
diff changeset
417 '(with -b/--bundle)')),
37e80214badf patchbomb: use cmdutil.command decorator
Adrian Buehlmann <adrian@cadifra.com>
parents: 14290
diff changeset
418 ('', '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
419 '(with -b/--bundle)'), _('REV')),
37e80214badf patchbomb: use cmdutil.command decorator
Adrian Buehlmann <adrian@cadifra.com>
parents: 14290
diff changeset
420 ('', 'intro', None, _('send an introduction email for a single patch')),
37e80214badf patchbomb: use cmdutil.command decorator
Adrian Buehlmann <adrian@cadifra.com>
parents: 14290
diff changeset
421 ] + emailopts + commands.remoteopts,
37e80214badf patchbomb: use cmdutil.command decorator
Adrian Buehlmann <adrian@cadifra.com>
parents: 14290
diff changeset
422 _('hg email [OPTION]... [DEST]...'))
27150
88aaddb1af88 patchbomb: rename email function
timeless <timeless@mozdev.org>
parents: 26626
diff changeset
423 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
424 '''send changesets by email
1204
b0f6053df539 patchbomb: continue if we can't import readline.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1154
diff changeset
425
11193
687c7d395f20 Use our custom hg reStructuredText role some more
Martin Geisler <mg@aragost.com>
parents: 11183
diff changeset
426 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
427 :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
428 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
429
9269
1d6499adf211 patchbomb: wrap docstrings at 70 characters
Martin Geisler <mg@lazybytes.net>
parents: 9214
diff changeset
430 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
431 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
432 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
433 description.
338b4b615d33 patchbomb: move command option help from the extension (patchbomb) to the command (email)
timeless <timeless@gmail.com>
parents: 12265
diff changeset
434
338b4b615d33 patchbomb: move command option help from the extension (patchbomb) to the command (email)
timeless <timeless@gmail.com>
parents: 12265
diff changeset
435 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
436 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
437
338b4b615d33 patchbomb: move command option help from the extension (patchbomb) to the command (email)
timeless <timeless@gmail.com>
parents: 12265
diff changeset
438 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
439
17880
9f6044119166 patchbomb: -c is not an alias for the --confirm option
Julian Cowley <julian@lava.net>
parents: 17859
diff changeset
440 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
441 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
442 the messages are sent.
4262
f51317e24114 Add --outgoing option to patchbomb
Brendan Cully <brendan@kublai.com>
parents: 4144
diff changeset
443
9269
1d6499adf211 patchbomb: wrap docstrings at 70 characters
Martin Geisler <mg@lazybytes.net>
parents: 9214
diff changeset
444 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
445 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
446 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
447 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
448 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
449 -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
450
9269
1d6499adf211 patchbomb: wrap docstrings at 70 characters
Martin Geisler <mg@lazybytes.net>
parents: 9214
diff changeset
451 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
452 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
453 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
454
9269
1d6499adf211 patchbomb: wrap docstrings at 70 characters
Martin Geisler <mg@lazybytes.net>
parents: 9214
diff changeset
455 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
456 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
457 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
458 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
459
12749
338b4b615d33 patchbomb: move command option help from the extension (patchbomb) to the command (email)
timeless <timeless@gmail.com>
parents: 12265
diff changeset
460 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
461 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
462 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
463 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
464 files.
338b4b615d33 patchbomb: move command option help from the extension (patchbomb) to the command (email)
timeless <timeless@gmail.com>
parents: 12265
diff changeset
465
338b4b615d33 patchbomb: move command option help from the extension (patchbomb) to the command (email)
timeless <timeless@gmail.com>
parents: 12265
diff changeset
466 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
467 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
468 an introductory message describing the patches of your patchbomb.
338b4b615d33 patchbomb: move command option help from the extension (patchbomb) to the command (email)
timeless <timeless@gmail.com>
parents: 12265
diff changeset
469 Then when all is done, patchbomb messages are displayed. If the
338b4b615d33 patchbomb: move command option help from the extension (patchbomb) to the command (email)
timeless <timeless@gmail.com>
parents: 12265
diff changeset
470 PAGER environment variable is set, your pager will be fired up once
338b4b615d33 patchbomb: move command option help from the extension (patchbomb) to the command (email)
timeless <timeless@gmail.com>
parents: 12265
diff changeset
471 for each patchbomb message, so you can verify everything is alright.
338b4b615d33 patchbomb: move command option help from the extension (patchbomb) to the command (email)
timeless <timeless@gmail.com>
parents: 12265
diff changeset
472
13198
e71b2aa74ce3 patchbomb: save introductory message in .hg/last-email.txt
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 12839
diff changeset
473 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
474 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
475
11b215731e74 patchbomb: introduce a 'patchbomb.confirm' option
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23487
diff changeset
476 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
477 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
478
9289
45aaf27f95b8 patchbomb: reST syntax for literal blocks in help text
Christian Ebert <blacktrash@gmx.net>
parents: 9286
diff changeset
479 Examples::
4280
a9336520a4ee Improve documentation for patchbomb and email
John Goerzen <jgoerzen@complete.org>
parents: 4279
diff changeset
480
9289
45aaf27f95b8 patchbomb: reST syntax for literal blocks in help text
Christian Ebert <blacktrash@gmx.net>
parents: 9286
diff changeset
481 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
482 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
483 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
484 hg email 3000 # send patch 3000 (deprecated)
4280
a9336520a4ee Improve documentation for patchbomb and email
John Goerzen <jgoerzen@complete.org>
parents: 4279
diff changeset
485
9289
45aaf27f95b8 patchbomb: reST syntax for literal blocks in help text
Christian Ebert <blacktrash@gmx.net>
parents: 9286
diff changeset
486 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
487 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
488 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
489 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
490
9289
45aaf27f95b8 patchbomb: reST syntax for literal blocks in help text
Christian Ebert <blacktrash@gmx.net>
parents: 9286
diff changeset
491 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
492 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
493 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
494 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
495
12749
338b4b615d33 patchbomb: move command option help from the extension (patchbomb) to the command (email)
timeless <timeless@gmail.com>
parents: 12265
diff changeset
496 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
497 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
498 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
499 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
500 -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
501
9269
1d6499adf211 patchbomb: wrap docstrings at 70 characters
Martin Geisler <mg@lazybytes.net>
parents: 9214
diff changeset
502 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
503 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
504 '''
f51317e24114 Add --outgoing option to patchbomb
Brendan Cully <brendan@kublai.com>
parents: 4144
diff changeset
505
7115
c5c2d43b01da patchbomb: mime-encode headers and parts not containing patches
Christian Ebert <blacktrash@gmx.net>
parents: 7095
diff changeset
506 _charsets = mail._charsets(ui)
c5c2d43b01da patchbomb: mime-encode headers and parts not containing patches
Christian Ebert <blacktrash@gmx.net>
parents: 7095
diff changeset
507
11413
4c1fe996838c patchbomb: reduce number of opts.get calls
Christian Ebert <blacktrash@gmx.net>
parents: 11321
diff changeset
508 bundle = opts.get('bundle')
4c1fe996838c patchbomb: reduce number of opts.get calls
Christian Ebert <blacktrash@gmx.net>
parents: 11321
diff changeset
509 date = opts.get('date')
4c1fe996838c patchbomb: reduce number of opts.get calls
Christian Ebert <blacktrash@gmx.net>
parents: 11321
diff changeset
510 mbox = opts.get('mbox')
4c1fe996838c patchbomb: reduce number of opts.get calls
Christian Ebert <blacktrash@gmx.net>
parents: 11321
diff changeset
511 outgoing = opts.get('outgoing')
4c1fe996838c patchbomb: reduce number of opts.get calls
Christian Ebert <blacktrash@gmx.net>
parents: 11321
diff changeset
512 rev = opts.get('rev')
4c1fe996838c patchbomb: reduce number of opts.get calls
Christian Ebert <blacktrash@gmx.net>
parents: 11321
diff changeset
513 # internal option used by pbranches
4c1fe996838c patchbomb: reduce number of opts.get calls
Christian Ebert <blacktrash@gmx.net>
parents: 11321
diff changeset
514 patches = opts.get('patches')
4c1fe996838c patchbomb: reduce number of opts.get calls
Christian Ebert <blacktrash@gmx.net>
parents: 11321
diff changeset
515
4c1fe996838c patchbomb: reduce number of opts.get calls
Christian Ebert <blacktrash@gmx.net>
parents: 11321
diff changeset
516 if not (opts.get('test') or mbox):
5472
23889160905a Catch smtp exceptions
Christian Ebert <blacktrash@gmx.net>
parents: 4887
diff changeset
517 # really sending
4489
a11e13d50645 patchbomb: Validate email config before we start prompting for info.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4486
diff changeset
518 mail.validateconfig(ui)
a11e13d50645 patchbomb: Validate email config before we start prompting for info.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4486
diff changeset
519
11413
4c1fe996838c patchbomb: reduce number of opts.get calls
Christian Ebert <blacktrash@gmx.net>
parents: 11321
diff changeset
520 if not (revs or rev or outgoing or bundle or patches):
26587
56b2bcea2529 error: get Abort from 'error' instead of 'util'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26563
diff changeset
521 raise error.Abort(_('specify at least one changeset with -r or -o'))
4493
ead2fa544cbf patchbomb: Fail early if no revs given to email
Bryan O'Sullivan <bos@serpentine.com>
parents: 4492
diff changeset
522
11413
4c1fe996838c patchbomb: reduce number of opts.get calls
Christian Ebert <blacktrash@gmx.net>
parents: 11321
diff changeset
523 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
524 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
525 " do not re-specify --outgoing"))
4278
cfe886c14ddf Add ability to send bundles to patchbomb extension
John Goerzen <jgoerzen@complete.org>
parents: 4262
diff changeset
526
11413
4c1fe996838c patchbomb: reduce number of opts.get calls
Christian Ebert <blacktrash@gmx.net>
parents: 11321
diff changeset
527 if outgoing or bundle:
4262
f51317e24114 Add --outgoing option to patchbomb
Brendan Cully <brendan@kublai.com>
parents: 4144
diff changeset
528 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
529 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
530 if revs:
6ddc86eedc3b style: kill ersatz if-else ternary operators
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 23877
diff changeset
531 dest = revs[0]
6ddc86eedc3b style: kill ersatz if-else ternary operators
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 23877
diff changeset
532 else:
6ddc86eedc3b style: kill ersatz if-else ternary operators
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 23877
diff changeset
533 dest = None
4262
f51317e24114 Add --outgoing option to patchbomb
Brendan Cully <brendan@kublai.com>
parents: 4144
diff changeset
534 revs = []
f51317e24114 Add --outgoing option to patchbomb
Brendan Cully <brendan@kublai.com>
parents: 4144
diff changeset
535
11413
4c1fe996838c patchbomb: reduce number of opts.get calls
Christian Ebert <blacktrash@gmx.net>
parents: 11321
diff changeset
536 if rev:
4262
f51317e24114 Add --outgoing option to patchbomb
Brendan Cully <brendan@kublai.com>
parents: 4144
diff changeset
537 if revs:
26587
56b2bcea2529 error: get Abort from 'error' instead of 'util'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26563
diff changeset
538 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
539 revs = rev
4262
f51317e24114 Add --outgoing option to patchbomb
Brendan Cully <brendan@kublai.com>
parents: 4144
diff changeset
540
24568
2e5f6cdf01f6 patchbomb: factor out scmutil.revrange() calls
Yuya Nishihara <yuya@tcha.org>
parents: 24567
diff changeset
541 revs = scmutil.revrange(repo, revs)
11413
4c1fe996838c patchbomb: reduce number of opts.get calls
Christian Ebert <blacktrash@gmx.net>
parents: 11321
diff changeset
542 if outgoing:
24568
2e5f6cdf01f6 patchbomb: factor out scmutil.revrange() calls
Yuya Nishihara <yuya@tcha.org>
parents: 24567
diff changeset
543 revs = _getoutgoing(repo, dest, revs)
11413
4c1fe996838c patchbomb: reduce number of opts.get calls
Christian Ebert <blacktrash@gmx.net>
parents: 11321
diff changeset
544 if bundle:
24567
13f0af2a5a4c patchbomb: return outgoing revs as a smartset
Yuya Nishihara <yuya@tcha.org>
parents: 24306
diff changeset
545 opts['revs'] = [str(r) for r in revs]
4262
f51317e24114 Add --outgoing option to patchbomb
Brendan Cully <brendan@kublai.com>
parents: 4144
diff changeset
546
26626
dca161728dc9 patchbomb: check that targets exist at the publicurl
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26587
diff changeset
547 # 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
548 publicurl = repo.ui.config('patchbomb', 'publicurl')
dca161728dc9 patchbomb: check that targets exist at the publicurl
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26587
diff changeset
549 if publicurl is not None:
dca161728dc9 patchbomb: check that targets exist at the publicurl
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26587
diff changeset
550 repo.ui.debug('checking that revision exist in the public repo')
dca161728dc9 patchbomb: check that targets exist at the publicurl
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26587
diff changeset
551 try:
dca161728dc9 patchbomb: check that targets exist at the publicurl
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26587
diff changeset
552 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
553 except error.RepoError:
dca161728dc9 patchbomb: check that targets exist at the publicurl
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26587
diff changeset
554 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
555 % publicurl)
dca161728dc9 patchbomb: check that targets exist at the publicurl
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26587
diff changeset
556 raise
dca161728dc9 patchbomb: check that targets exist at the publicurl
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26587
diff changeset
557 if not publicpeer.capable('known'):
dca161728dc9 patchbomb: check that targets exist at the publicurl
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26587
diff changeset
558 repo.ui.debug('skipping existence checks: public repo too old')
dca161728dc9 patchbomb: check that targets exist at the publicurl
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26587
diff changeset
559 else:
dca161728dc9 patchbomb: check that targets exist at the publicurl
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26587
diff changeset
560 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
561 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
562 missing = []
dca161728dc9 patchbomb: check that targets exist at the publicurl
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26587
diff changeset
563 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
564 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
565 missing.append(h)
dca161728dc9 patchbomb: check that targets exist at the publicurl
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26587
diff changeset
566 if missing:
dca161728dc9 patchbomb: check that targets exist at the publicurl
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26587
diff changeset
567 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
568 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
569 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
570 else:
dca161728dc9 patchbomb: check that targets exist at the publicurl
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26587
diff changeset
571 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
572 msg %= (publicurl, missing[0])
28907
66e647312d30 patchbomb: fix public-is-missing hint
timeless <timeless@mozdev.org>
parents: 28861
diff changeset
573 revhint = ' '.join('-r %s' % h
26626
dca161728dc9 patchbomb: check that targets exist at the publicurl
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26587
diff changeset
574 for h in repo.set('heads(%ld)', missing))
28981
7b188bc23942 patchbomb: use single quotes around command hint
timeless <timeless@mozdev.org>
parents: 28907
diff changeset
575 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
576 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
577
4262
f51317e24114 Add --outgoing option to patchbomb
Brendan Cully <brendan@kublai.com>
parents: 4144
diff changeset
578 # start
11413
4c1fe996838c patchbomb: reduce number of opts.get calls
Christian Ebert <blacktrash@gmx.net>
parents: 11321
diff changeset
579 if date:
4c1fe996838c patchbomb: reduce number of opts.get calls
Christian Ebert <blacktrash@gmx.net>
parents: 11321
diff changeset
580 start_time = util.parsedate(date)
4566
087b3ae4f08a patchbomb: add --date option
Bryan O'Sullivan <bos@serpentine.com>
parents: 4565
diff changeset
581 else:
087b3ae4f08a patchbomb: add --date option
Bryan O'Sullivan <bos@serpentine.com>
parents: 4565
diff changeset
582 start_time = util.makedate()
875
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
583
876
14cfaaec2e8e Get patchbomb script to not use MIME attachments.
Bryan O'Sullivan <bos@serpentine.com>
parents: 875
diff changeset
584 def genmsgid(id):
4027
2601ac9c54f0 patchbomb: fix timezone offset in message date header
Christian Ebert <blacktrash@gmx.net>
parents: 3473
diff changeset
585 return '<%s.%s@%s>' % (id[:20], int(start_time[0]), socket.getfqdn())
875
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
586
25825
577b050caada patchbomb: mark ancient option deprecated
Matt Mackall <mpm@selenic.com>
parents: 25660
diff changeset
587 # deprecated config: patchbomb.from
5818
77775ae8d5d9 patchbomb: consistently use opts.get
Christian Ebert <blacktrash@gmx.net>
parents: 5817
diff changeset
588 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
589 ui.config('patchbomb', 'from') or
7354
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
590 prompt(ui, 'From', ui.username()))
875
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
591
7353
982b55ec80be patchbomb: make `hg email` reusable for other patch sources
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 7352
diff changeset
592 if patches:
23215
83a191031f94 patchbomb: extract 'getpatchmsgs' closure into its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23214
diff changeset
593 msgs = _getpatchmsgs(repo, sender, patches, opts.get('patchnames'),
83a191031f94 patchbomb: extract 'getpatchmsgs' closure into its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23214
diff changeset
594 **opts)
11413
4c1fe996838c patchbomb: reduce number of opts.get calls
Christian Ebert <blacktrash@gmx.net>
parents: 11321
diff changeset
595 elif bundle:
23213
23a78662b6dd patchbomb: extract 'getbundlemsgs' closure in its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23212
diff changeset
596 bundledata = _getbundle(repo, dest, **opts)
23a78662b6dd patchbomb: extract 'getbundlemsgs' closure in its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23212
diff changeset
597 bundleopts = opts.copy()
23a78662b6dd patchbomb: extract 'getbundlemsgs' closure in its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23212
diff changeset
598 bundleopts.pop('bundle', None) # already processed
23a78662b6dd patchbomb: extract 'getbundlemsgs' closure in its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23212
diff changeset
599 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
600 else:
23215
83a191031f94 patchbomb: extract 'getpatchmsgs' closure into its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23214
diff changeset
601 _patches = list(_getpatches(repo, revs, **opts))
83a191031f94 patchbomb: extract 'getpatchmsgs' closure into its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23214
diff changeset
602 msgs = _getpatchmsgs(repo, sender, _patches, **opts)
875
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
603
12200
aebb39d45500 patchbomb: let diffstat prompt only once with complete summary
Christian Ebert <blacktrash@gmx.net>
parents: 12199
diff changeset
604 showaddrs = []
aebb39d45500 patchbomb: let diffstat prompt only once with complete summary
Christian Ebert <blacktrash@gmx.net>
parents: 12199
diff changeset
605
15162
d67a15b2e608 patchbomb: simplify some contorted logic and odd variable names.
Greg Ward <greg@gerg.ca>
parents: 14556
diff changeset
606 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
607 configkey = header.lower()
d67a15b2e608 patchbomb: simplify some contorted logic and odd variable names.
Greg Ward <greg@gerg.ca>
parents: 14556
diff changeset
608 opt = header.replace('-', '_').lower()
d67a15b2e608 patchbomb: simplify some contorted logic and odd variable names.
Greg Ward <greg@gerg.ca>
parents: 14556
diff changeset
609 addrs = opts.get(opt)
11150
f66ca4431eb9 patchbomb: Reply-To support
Cédric Duval <cedricduval@free.fr>
parents: 10973
diff changeset
610 if addrs:
15162
d67a15b2e608 patchbomb: simplify some contorted logic and odd variable names.
Greg Ward <greg@gerg.ca>
parents: 14556
diff changeset
611 showaddrs.append('%s: %s' % (header, ', '.join(addrs)))
12264
b8146231c3de patchbomb: consistent code style in getaddrs()
Christian Ebert <blacktrash@gmx.net>
parents: 12201
diff changeset
612 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
613
15162
d67a15b2e608 patchbomb: simplify some contorted logic and odd variable names.
Greg Ward <greg@gerg.ca>
parents: 14556
diff changeset
614 # 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
615 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
616 ui.config('patchbomb', configkey))
0ce0cfee497f patchbomb: treat empty address list as no addresses
Bryan O'Sullivan <bos@serpentine.com>
parents: 27150
diff changeset
617 if not addr:
0ce0cfee497f patchbomb: treat empty address list as no addresses
Bryan O'Sullivan <bos@serpentine.com>
parents: 27150
diff changeset
618 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
619 ui.hasconfig('patchbomb', configkey))
0ce0cfee497f patchbomb: treat empty address list as no addresses
Bryan O'Sullivan <bos@serpentine.com>
parents: 27150
diff changeset
620 if not specified and ask:
0ce0cfee497f patchbomb: treat empty address list as no addresses
Bryan O'Sullivan <bos@serpentine.com>
parents: 27150
diff changeset
621 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
622 if addr:
d67a15b2e608 patchbomb: simplify some contorted logic and odd variable names.
Greg Ward <greg@gerg.ca>
parents: 14556
diff changeset
623 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
624 return mail.addrlistencode(ui, [addr], _charsets, opts.get('test'))
7bddec632821 patchbomb: make it easy for the user to decline sending an intro message.
Greg Ward <greg@gerg.ca>
parents: 15162
diff changeset
625 else:
7bddec632821 patchbomb: make it easy for the user to decline sending an intro message.
Greg Ward <greg@gerg.ca>
parents: 15162
diff changeset
626 return default
9947
4600e6222efb patchbomb: fix parsing of multiple addresses, allow multiple addrs in --to/cc/bcc
Marti Raudsepp <marti@juffo.org>
parents: 9818
diff changeset
627
15162
d67a15b2e608 patchbomb: simplify some contorted logic and odd variable names.
Greg Ward <greg@gerg.ca>
parents: 14556
diff changeset
628 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
629 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
630 # 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
631 raise error.Abort(_('no recipient addresses provided'))
15164
7bddec632821 patchbomb: make it easy for the user to decline sending an intro message.
Greg Ward <greg@gerg.ca>
parents: 15162
diff changeset
632 cc = getaddrs('Cc', ask=True, default='') or []
7bddec632821 patchbomb: make it easy for the user to decline sending an intro message.
Greg Ward <greg@gerg.ca>
parents: 15162
diff changeset
633 bcc = getaddrs('Bcc') or []
15162
d67a15b2e608 patchbomb: simplify some contorted logic and odd variable names.
Greg Ward <greg@gerg.ca>
parents: 14556
diff changeset
634 replyto = getaddrs('Reply-To')
2679
f1de91be1d87 optionally send blind carbon copies
Christian Ebert <blacktrash@gmx.net>
parents: 2443
diff changeset
635
23488
11b215731e74 patchbomb: introduce a 'patchbomb.confirm' option
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23487
diff changeset
636 confirm = ui.configbool('patchbomb', 'confirm')
11b215731e74 patchbomb: introduce a 'patchbomb.confirm' option
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23487
diff changeset
637 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
638
11b215731e74 patchbomb: introduce a 'patchbomb.confirm' option
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23487
diff changeset
639 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
640 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
641 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
642 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
643 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
644 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
645 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
646 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
647 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
648 ui.write('\n')
19226
c58b6ab4c26f ui: merge prompt text components into a singe string
Matt Mackall <mpm@selenic.com>
parents: 18888
diff changeset
649 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
650 '$$ &Yes $$ &No')):
26587
56b2bcea2529 error: get Abort from 'error' instead of 'util'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26563
diff changeset
651 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
652
875
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
653 ui.write('\n')
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
654
8025
1280934dd2dd patchbomb: Support initial in-reply-to header
Henrik Stuart <henrik.stuart at edlund.dk>
parents: 7997
diff changeset
655 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
656 # 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
657 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
658 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
659 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
660 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
661 parent += '>'
2aff285b902f patchbomb: do not assume the presence of angle brackets around msg-id
Cédric Duval <cedricduval@free.fr>
parents: 8761
diff changeset
662
27150
88aaddb1af88 patchbomb: rename email function
timeless <timeless@mozdev.org>
parents: 26626
diff changeset
663 sender_addr = emailmod.Utils.parseaddr(sender)[1]
7115
c5c2d43b01da patchbomb: mime-encode headers and parts not containing patches
Christian Ebert <blacktrash@gmx.net>
parents: 7095
diff changeset
664 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
665 sendmail = None
21726
fae032549ca2 patchbomb: always use message-id of first patch for series-id
Augie Fackler <raf@durin42.com>
parents: 21724
diff changeset
666 firstpatch = None
12265
1ed2dc9d4368 patchbomb: show progress when sending emails or writing mbox
Yuya Nishihara <yuya@tcha.org>
parents: 12264
diff changeset
667 for i, (m, subj, ds) in enumerate(msgs):
875
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
668 try:
876
14cfaaec2e8e Get patchbomb script to not use MIME attachments.
Bryan O'Sullivan <bos@serpentine.com>
parents: 875
diff changeset
669 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
670 if not firstpatch:
fae032549ca2 patchbomb: always use message-id of first patch for series-id
Augie Fackler <raf@durin42.com>
parents: 21724
diff changeset
671 firstpatch = m['Message-Id']
21727
5f98ad8fb8d9 patchbomb: reorder header insertions to clarify code
Augie Fackler <raf@durin42.com>
parents: 21726
diff changeset
672 m['X-Mercurial-Series-Id'] = firstpatch
875
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
673 except TypeError:
876
14cfaaec2e8e Get patchbomb script to not use MIME attachments.
Bryan O'Sullivan <bos@serpentine.com>
parents: 875
diff changeset
674 m['Message-Id'] = genmsgid('patchbomb')
875
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
675 if parent:
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
676 m['In-Reply-To'] = parent
7413
0b6428da1f22 email: add References field in the header
Benoit Allard <benoit@aeteurope.nl>
parents: 7360
diff changeset
677 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
678 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
679 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
680
8160
094e0d982c8a patchbomb: add user agent header to mails
Henrik Stuart <hg@hstuart.dk>
parents: 8076
diff changeset
681 m['User-Agent'] = 'Mercurial-patchbomb/%s' % util.version()
27150
88aaddb1af88 patchbomb: rename email function
timeless <timeless@mozdev.org>
parents: 26626
diff changeset
682 m['Date'] = emailmod.Utils.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
683
4027
2601ac9c54f0 patchbomb: fix timezone offset in message date header
Christian Ebert <blacktrash@gmx.net>
parents: 3473
diff changeset
684 start_time = (start_time[0] + 1, start_time[1])
875
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
685 m['From'] = sender
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
686 m['To'] = ', '.join(to)
5785
38cd1ce8650d patchbomb: add linebreaks after colons (coding style)
Christian Ebert <blacktrash@gmx.net>
parents: 5758
diff changeset
687 if cc:
38cd1ce8650d patchbomb: add linebreaks after colons (coding style)
Christian Ebert <blacktrash@gmx.net>
parents: 5758
diff changeset
688 m['Cc'] = ', '.join(cc)
38cd1ce8650d patchbomb: add linebreaks after colons (coding style)
Christian Ebert <blacktrash@gmx.net>
parents: 5758
diff changeset
689 if bcc:
38cd1ce8650d patchbomb: add linebreaks after colons (coding style)
Christian Ebert <blacktrash@gmx.net>
parents: 5758
diff changeset
690 m['Bcc'] = ', '.join(bcc)
11150
f66ca4431eb9 patchbomb: Reply-To support
Cédric Duval <cedricduval@free.fr>
parents: 10973
diff changeset
691 if replyto:
f66ca4431eb9 patchbomb: Reply-To support
Cédric Duval <cedricduval@free.fr>
parents: 10973
diff changeset
692 m['Reply-To'] = ', '.join(replyto)
5818
77775ae8d5d9 patchbomb: consistently use opts.get
Christian Ebert <blacktrash@gmx.net>
parents: 5817
diff changeset
693 if opts.get('test'):
16931
ee388b0a6f67 patchbomb: lowercase status messages
Martin Geisler <mg@aragost.com>
parents: 16743
diff changeset
694 ui.status(_('displaying '), subj, ' ...\n')
4596
8e37342cb05d patchbomb: flush ui before delegating to pager.
Patrick Mezard <pmezard@gmail.com>
parents: 4142
diff changeset
695 ui.flush()
11183
b25464e9b448 patchbomb: respect HGPLAIN when piping --test output to PAGER
Yuya Nishihara <yuya@tcha.org>
parents: 11150
diff changeset
696 if 'PAGER' in os.environ and not ui.plain():
6548
962eb403165b replace usage of os.popen() with util.popen()
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6478
diff changeset
697 fp = util.popen(os.environ['PAGER'], 'w')
4599
88fc92b0b821 patchbomb: page patchbomb messages only if PAGER is defined.
Patrick Mezard <pmezard@gmail.com>
parents: 4597
diff changeset
698 else:
88fc92b0b821 patchbomb: page patchbomb messages only if PAGER is defined.
Patrick Mezard <pmezard@gmail.com>
parents: 4597
diff changeset
699 fp = ui
27150
88aaddb1af88 patchbomb: rename email function
timeless <timeless@mozdev.org>
parents: 26626
diff changeset
700 generator = emailmod.Generator.Generator(fp, mangle_from_=False)
1871
258e3a7955b8 patchbomb: ignore exception if pager quits.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1846
diff changeset
701 try:
6447
9d2ce19bdacd patchbomb: Fix mangling of lines beginning with From
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 6229
diff changeset
702 generator.flatten(m, 0)
1871
258e3a7955b8 patchbomb: ignore exception if pager quits.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1846
diff changeset
703 fp.write('\n')
25660
328739ea70c3 global: mass rewrite to use modern exception syntax
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25202
diff changeset
704 except IOError as inst:
1871
258e3a7955b8 patchbomb: ignore exception if pager quits.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1846
diff changeset
705 if inst.errno != errno.EPIPE:
258e3a7955b8 patchbomb: ignore exception if pager quits.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1846
diff changeset
706 raise
4599
88fc92b0b821 patchbomb: page patchbomb messages only if PAGER is defined.
Patrick Mezard <pmezard@gmail.com>
parents: 4597
diff changeset
707 if fp is not ui:
88fc92b0b821 patchbomb: page patchbomb messages only if PAGER is defined.
Patrick Mezard <pmezard@gmail.com>
parents: 4597
diff changeset
708 fp.close()
15560
cc58c228503e mail: mbox handling as a part of mail handling, refactored from patchbomb
Mads Kiilerich <mads@kiilerich.com>
parents: 15559
diff changeset
709 else:
cc58c228503e mail: mbox handling as a part of mail handling, refactored from patchbomb
Mads Kiilerich <mads@kiilerich.com>
parents: 15559
diff changeset
710 if not sendmail:
29285
63a3749147af mail: unsupport smtp.verifycert (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29205
diff changeset
711 sendmail = mail.connect(ui, mbox=mbox)
16931
ee388b0a6f67 patchbomb: lowercase status messages
Martin Geisler <mg@aragost.com>
parents: 16743
diff changeset
712 ui.status(_('sending '), subj, ' ...\n')
28474
00e6e0d0bfeb patchbomb: specify unit for ui.progress when sending emails
Anton Shestakov <av6@dwimlabs.net>
parents: 28415
diff changeset
713 ui.progress(_('sending'), i, item=subj, total=len(msgs),
00e6e0d0bfeb patchbomb: specify unit for ui.progress when sending emails
Anton Shestakov <av6@dwimlabs.net>
parents: 28415
diff changeset
714 unit=_('emails'))
15560
cc58c228503e mail: mbox handling as a part of mail handling, refactored from patchbomb
Mads Kiilerich <mads@kiilerich.com>
parents: 15559
diff changeset
715 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
716 # 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
717 del m['Bcc']
28861
86db5cb55d46 pycompat: switch to util.stringio for py3 compat
timeless <timeless@mozdev.org>
parents: 28474
diff changeset
718 fp = stringio()
27150
88aaddb1af88 patchbomb: rename email function
timeless <timeless@mozdev.org>
parents: 26626
diff changeset
719 generator = emailmod.Generator.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
720 generator.flatten(m, 0)
15559
1830d0cc4bc1 patchbomb: minor refactoring of mbox functionality, preparing for move
Mads Kiilerich <mads@kiilerich.com>
parents: 15166
diff changeset
721 sendmail(sender_addr, to + bcc + cc, fp.getvalue())
875
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
722
12265
1ed2dc9d4368 patchbomb: show progress when sending emails or writing mbox
Yuya Nishihara <yuya@tcha.org>
parents: 12264
diff changeset
723 ui.progress(_('writing'), None)
1ed2dc9d4368 patchbomb: show progress when sending emails or writing mbox
Yuya Nishihara <yuya@tcha.org>
parents: 12264
diff changeset
724 ui.progress(_('sending'), None)