annotate hgext/patchbomb.py @ 27752:29cfc474c5fd

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