hgext/patchbomb.py
author Wagner Bruna <wbruna@softwareexpress.com.br>
Thu, 24 Feb 2011 13:57:52 -0300
branchstable
changeset 13492 ca940d06bf95
parent 13400 14f3795a5ed7
child 13838 c5709dfa5c1e
permissions -rw-r--r--
tests: test renaming a file added on two branches (issue2089) The issue was fixed by d100702326d5 .
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
8252
9674d64b6416 patchbomb: add copyright and license header
Martin Geisler <mg@lazybytes.net>
parents: 8208
diff changeset
     1
# patchbomb.py - sending Mercurial changesets as patch emails
9674d64b6416 patchbomb: add copyright and license header
Martin Geisler <mg@lazybytes.net>
parents: 8208
diff changeset
     2
#
9674d64b6416 patchbomb: add copyright and license header
Martin Geisler <mg@lazybytes.net>
parents: 8208
diff changeset
     3
#  Copyright 2005-2009 Matt Mackall <mpm@selenic.com> and others
9674d64b6416 patchbomb: add copyright and license header
Martin Geisler <mg@lazybytes.net>
parents: 8208
diff changeset
     4
#
9674d64b6416 patchbomb: add copyright and license header
Martin Geisler <mg@lazybytes.net>
parents: 8208
diff changeset
     5
# This software may be used and distributed according to the terms of the
10263
25e572394f5c Update license to GPLv2+
Matt Mackall <mpm@selenic.com>
parents: 10022
diff changeset
     6
# GNU General Public License version 2 or any later version.
8252
9674d64b6416 patchbomb: add copyright and license header
Martin Geisler <mg@lazybytes.net>
parents: 8208
diff changeset
     7
8935
f4f0e902b750 extensions: change descriptions for hook-providing extensions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 8934
diff changeset
     8
'''command to send changesets as (a series of) patch emails
6666
53465a7464e2 convert comments to docstrings in a bunch of extensions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6548
diff changeset
     9
7997
8eb9f495e150 patchbomb: word-wrap help texts at 70 characters
Martin Geisler <mg@daimi.au.dk>
parents: 7983
diff changeset
    10
The series is started off with a "[PATCH 0 of N]" introduction, which
8eb9f495e150 patchbomb: word-wrap help texts at 70 characters
Martin Geisler <mg@daimi.au.dk>
parents: 7983
diff changeset
    11
describes the series as a whole.
6666
53465a7464e2 convert comments to docstrings in a bunch of extensions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6548
diff changeset
    12
9269
1d6499adf211 patchbomb: wrap docstrings at 70 characters
Martin Geisler <mg@lazybytes.net>
parents: 9214
diff changeset
    13
Each patch email has a Subject line of "[PATCH M of N] ...", using the
1d6499adf211 patchbomb: wrap docstrings at 70 characters
Martin Geisler <mg@lazybytes.net>
parents: 9214
diff changeset
    14
first line of the changeset description as the subject text. The
1d6499adf211 patchbomb: wrap docstrings at 70 characters
Martin Geisler <mg@lazybytes.net>
parents: 9214
diff changeset
    15
message contains two or three body parts:
6666
53465a7464e2 convert comments to docstrings in a bunch of extensions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6548
diff changeset
    16
9300
ad95ea1c975a patchbomb: use a list instead of indented paragraphs
Martin Geisler <mg@lazybytes.net>
parents: 9289
diff changeset
    17
- The changeset description.
ad95ea1c975a patchbomb: use a list instead of indented paragraphs
Martin Geisler <mg@lazybytes.net>
parents: 9289
diff changeset
    18
- [Optional] The result of running diffstat on the patch.
10973
49a07f441496 Use hg role in help strings
Martin Geisler <mg@aragost.com>
parents: 10734
diff changeset
    19
- The patch itself, as generated by :hg:`export`.
6666
53465a7464e2 convert comments to docstrings in a bunch of extensions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6548
diff changeset
    20
9269
1d6499adf211 patchbomb: wrap docstrings at 70 characters
Martin Geisler <mg@lazybytes.net>
parents: 9214
diff changeset
    21
Each message refers to the first in the series using the In-Reply-To
1d6499adf211 patchbomb: wrap docstrings at 70 characters
Martin Geisler <mg@lazybytes.net>
parents: 9214
diff changeset
    22
and References headers, so they will show up as a sequence in threaded
1d6499adf211 patchbomb: wrap docstrings at 70 characters
Martin Geisler <mg@lazybytes.net>
parents: 9214
diff changeset
    23
mail and news readers, and in mail archives.
6666
53465a7464e2 convert comments to docstrings in a bunch of extensions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6548
diff changeset
    24
9269
1d6499adf211 patchbomb: wrap docstrings at 70 characters
Martin Geisler <mg@lazybytes.net>
parents: 9214
diff changeset
    25
To configure other defaults, add a section like this to your hgrc
1d6499adf211 patchbomb: wrap docstrings at 70 characters
Martin Geisler <mg@lazybytes.net>
parents: 9214
diff changeset
    26
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.
9071
141e3ef20d84 patchbomb: wrapped docstrings at 78 characters
Martin Geisler <mg@lazybytes.net>
parents: 9047
diff changeset
    46
'''
875
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    47
9046
1547126630e9 patchbomb: fix From_ in the message's envelope
Cédric Duval <cedricduval@free.fr>
parents: 8935
diff changeset
    48
import os, errno, socket, tempfile, cStringIO, time
7192
f31ba106fc19 patchbomb: mime-encode clean utf-8 patches (issue814)
Christian Ebert <blacktrash@gmx.net>
parents: 7115
diff changeset
    49
import email.MIMEMultipart, email.MIMEBase
6447
9d2ce19bdacd patchbomb: Fix mangling of lines beginning with From
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 6229
diff changeset
    50
import email.Utils, email.Encoders, email.Generator
12793
469850088fc1 patchbomb: hide passwords potentially embedded in urls
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 11413
diff changeset
    51
from mercurial import cmdutil, commands, hg, mail, patch, util, discovery, url
3891
6b4127c7d52a Simplify i18n imports
Matt Mackall <mpm@selenic.com>
parents: 3887
diff changeset
    52
from mercurial.i18n import _
6211
f89fd07fc51d Expand import * to allow Pyflakes to find problems
Joel Rosdahl <joel@rosdahl.net>
parents: 5973
diff changeset
    53
from mercurial.node import bin
875
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    54
9648
6064de41b7e4 patchbomb: accept default if it is empty string
Alexander Solovyov <piranha@piranha.org.ua>
parents: 9647
diff changeset
    55
def prompt(ui, prompt, default=None, rest=':'):
12197
540693065d40 patchbomb: show prompt and selection in non-interactive mode
Christian Ebert <blacktrash@gmx.net>
parents: 12196
diff changeset
    56
    if not ui.interactive() and default is None:
10282
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10264
diff changeset
    57
        raise util.Abort(_("%s Please enter a valid value" % (prompt + rest)))
7354
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
    58
    if default:
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
    59
        prompt += ' [%s]' % default
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
    60
    prompt += rest
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
    61
    while True:
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
    62
        r = ui.prompt(prompt, default=default)
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
    63
        if r:
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
    64
            return r
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
    65
        if default is not None:
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
    66
            return default
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
    67
        ui.warn(_('Please enter a valid value.\n'))
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
    68
10734
7a0502a6f9a1 patchbomb: --desc implies --intro
Cédric Duval <cedricduval@free.fr>
parents: 10611
diff changeset
    69
def introneeded(opts, number):
7a0502a6f9a1 patchbomb: --desc implies --intro
Cédric Duval <cedricduval@free.fr>
parents: 10611
diff changeset
    70
    '''is an introductory message required?'''
7a0502a6f9a1 patchbomb: --desc implies --intro
Cédric Duval <cedricduval@free.fr>
parents: 10611
diff changeset
    71
    return number > 1 or opts.get('intro') or opts.get('desc')
7a0502a6f9a1 patchbomb: --desc implies --intro
Cédric Duval <cedricduval@free.fr>
parents: 10611
diff changeset
    72
12199
17d604e522b4 patchbomb: rename argument to avoid shadowing patch module
Martin Geisler <mg@lazybytes.net>
parents: 12197
diff changeset
    73
def makepatch(ui, repo, patchlines, opts, _charsets, idx, total,
17d604e522b4 patchbomb: rename argument to avoid shadowing patch module
Martin Geisler <mg@lazybytes.net>
parents: 12197
diff changeset
    74
              patchname=None):
7354
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
    75
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
    76
    desc = []
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
    77
    node = None
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
    78
    body = ''
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
    79
12199
17d604e522b4 patchbomb: rename argument to avoid shadowing patch module
Martin Geisler <mg@lazybytes.net>
parents: 12197
diff changeset
    80
    for line in patchlines:
7354
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
    81
        if line.startswith('#'):
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
    82
            if line.startswith('# Node ID'):
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
    83
                node = line.split()[-1]
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
    84
            continue
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
    85
        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
    86
            break
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
    87
        desc.append(line)
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
    88
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
    89
    if not patchname and not node:
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
    90
        raise ValueError
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
    91
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
    92
    if opts.get('attach'):
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
    93
        body = ('\n'.join(desc[1:]).strip() or
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
    94
                'Patch subject is complete summary.')
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
    95
        body += '\n\n\n'
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
    96
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
    97
    if opts.get('plain'):
12199
17d604e522b4 patchbomb: rename argument to avoid shadowing patch module
Martin Geisler <mg@lazybytes.net>
parents: 12197
diff changeset
    98
        while patchlines and patchlines[0].startswith('# '):
17d604e522b4 patchbomb: rename argument to avoid shadowing patch module
Martin Geisler <mg@lazybytes.net>
parents: 12197
diff changeset
    99
            patchlines.pop(0)
17d604e522b4 patchbomb: rename argument to avoid shadowing patch module
Martin Geisler <mg@lazybytes.net>
parents: 12197
diff changeset
   100
        if patchlines:
17d604e522b4 patchbomb: rename argument to avoid shadowing patch module
Martin Geisler <mg@lazybytes.net>
parents: 12197
diff changeset
   101
            patchlines.pop(0)
17d604e522b4 patchbomb: rename argument to avoid shadowing patch module
Martin Geisler <mg@lazybytes.net>
parents: 12197
diff changeset
   102
        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
   103
            patchlines.pop(0)
7354
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
   104
12200
aebb39d45500 patchbomb: let diffstat prompt only once with complete summary
Christian Ebert <blacktrash@gmx.net>
parents: 12199
diff changeset
   105
    ds = patch.diffstat(patchlines)
7354
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
   106
    if opts.get('diffstat'):
12200
aebb39d45500 patchbomb: let diffstat prompt only once with complete summary
Christian Ebert <blacktrash@gmx.net>
parents: 12199
diff changeset
   107
        body += ds + '\n\n'
7354
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
   108
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
   109
    if opts.get('attach') or opts.get('inline'):
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
   110
        msg = email.MIMEMultipart.MIMEMultipart()
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
   111
        if body:
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
   112
            msg.attach(mail.mimeencode(ui, body, _charsets, opts.get('test')))
12199
17d604e522b4 patchbomb: rename argument to avoid shadowing patch module
Martin Geisler <mg@lazybytes.net>
parents: 12197
diff changeset
   113
        p = mail.mimetextpatch('\n'.join(patchlines), 'x-patch', opts.get('test'))
7354
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
   114
        binnode = bin(node)
8761
0289f384e1e5 Generally replace "file name" with "filename" in help and comments.
timeless <timeless@gmail.com>
parents: 8520
diff changeset
   115
        # 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
   116
        if not patchname:
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
   117
            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
   118
                         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
   119
            if patchtags:
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
   120
                patchname = patchtags[0]
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
   121
            elif total > 1:
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
   122
                patchname = cmdutil.make_filename(repo, '%b-%n.patch',
7359
b0fa5dbd9cdd patchbomb: fix patch name generation in patch series
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 7354
diff changeset
   123
                                                  binnode, seqno=idx, total=total)
7354
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
   124
            else:
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
   125
                patchname = cmdutil.make_filename(repo, '%b.patch', binnode)
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
   126
        disposition = 'inline'
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
   127
        if opts.get('attach'):
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
   128
            disposition = 'attachment'
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
   129
        p['Content-Disposition'] = disposition + '; filename=' + patchname
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
   130
        msg.attach(p)
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
   131
    else:
12199
17d604e522b4 patchbomb: rename argument to avoid shadowing patch module
Martin Geisler <mg@lazybytes.net>
parents: 12197
diff changeset
   132
        body += '\n'.join(patchlines)
7354
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
   133
        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
   134
9346
bb3f8f692bc6 patchbomb: add --flag to put flags in subject prefixes
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9300
diff changeset
   135
    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
   136
    if flag:
bb3f8f692bc6 patchbomb: add --flag to put flags in subject prefixes
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9300
diff changeset
   137
        flag = ' ' + flag
bb3f8f692bc6 patchbomb: add --flag to put flags in subject prefixes
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9300
diff changeset
   138
7354
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
   139
    subj = desc[0].strip().rstrip('. ')
10734
7a0502a6f9a1 patchbomb: --desc implies --intro
Cédric Duval <cedricduval@free.fr>
parents: 10611
diff changeset
   140
    if not introneeded(opts, total):
9346
bb3f8f692bc6 patchbomb: add --flag to put flags in subject prefixes
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9300
diff changeset
   141
        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
   142
    else:
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
   143
        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
   144
        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
   145
    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
   146
    msg['X-Mercurial-Node'] = node
12200
aebb39d45500 patchbomb: let diffstat prompt only once with complete summary
Christian Ebert <blacktrash@gmx.net>
parents: 12199
diff changeset
   147
    return msg, subj, ds
7354
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
   148
875
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   149
def patchbomb(ui, repo, *revs, **opts):
4283
8625504f507c Slight refining to help text in patchbomb.py
John Goerzen <jgoerzen@complete.org>
parents: 4280
diff changeset
   150
    '''send changesets by email
1204
b0f6053df539 patchbomb: continue if we can't import readline.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1154
diff changeset
   151
11193
687c7d395f20 Use our custom hg reStructuredText role some more
Martin Geisler <mg@aragost.com>
parents: 11183
diff changeset
   152
    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
   153
    :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
   154
    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
   155
9269
1d6499adf211 patchbomb: wrap docstrings at 70 characters
Martin Geisler <mg@lazybytes.net>
parents: 9214
diff changeset
   156
    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
   157
    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
   158
    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
   159
    description.
338b4b615d33 patchbomb: move command option help from the extension (patchbomb) to the command (email)
timeless <timeless@gmail.com>
parents: 12265
diff changeset
   160
338b4b615d33 patchbomb: move command option help from the extension (patchbomb) to the command (email)
timeless <timeless@gmail.com>
parents: 12265
diff changeset
   161
    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
   162
    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
   163
338b4b615d33 patchbomb: move command option help from the extension (patchbomb) to the command (email)
timeless <timeless@gmail.com>
parents: 12265
diff changeset
   164
    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
   165
338b4b615d33 patchbomb: move command option help from the extension (patchbomb) to the command (email)
timeless <timeless@gmail.com>
parents: 12265
diff changeset
   166
    With the -d/--diffstat or -c/--confirm options, you will be presented
338b4b615d33 patchbomb: move command option help from the extension (patchbomb) to the command (email)
timeless <timeless@gmail.com>
parents: 12265
diff changeset
   167
    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
   168
    the messages are sent.
4262
f51317e24114 Add --outgoing option to patchbomb
Brendan Cully <brendan@kublai.com>
parents: 4144
diff changeset
   169
9269
1d6499adf211 patchbomb: wrap docstrings at 70 characters
Martin Geisler <mg@lazybytes.net>
parents: 9214
diff changeset
   170
    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
   171
    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
   172
    an attachment for the patch. With -i/--inline an inline attachment
1d6499adf211 patchbomb: wrap docstrings at 70 characters
Martin Geisler <mg@lazybytes.net>
parents: 9214
diff changeset
   173
    will be created.
8472
223363bb6d66 patchbomb: describe --attach and --inline options in help
Martin Geisler <mg@lazybytes.net>
parents: 8471
diff changeset
   174
9269
1d6499adf211 patchbomb: wrap docstrings at 70 characters
Martin Geisler <mg@lazybytes.net>
parents: 9214
diff changeset
   175
    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
   176
    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
   177
    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
   178
9269
1d6499adf211 patchbomb: wrap docstrings at 70 characters
Martin Geisler <mg@lazybytes.net>
parents: 9214
diff changeset
   179
    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
   180
    single email containing a binary Mercurial bundle as an attachment
1d6499adf211 patchbomb: wrap docstrings at 70 characters
Martin Geisler <mg@lazybytes.net>
parents: 9214
diff changeset
   181
    will be sent.
4280
a9336520a4ee Improve documentation for patchbomb and email
John Goerzen <jgoerzen@complete.org>
parents: 4279
diff changeset
   182
12749
338b4b615d33 patchbomb: move command option help from the extension (patchbomb) to the command (email)
timeless <timeless@gmail.com>
parents: 12265
diff changeset
   183
    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
   184
    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
   185
    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
   186
    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
   187
    files.
338b4b615d33 patchbomb: move command option help from the extension (patchbomb) to the command (email)
timeless <timeless@gmail.com>
parents: 12265
diff changeset
   188
338b4b615d33 patchbomb: move command option help from the extension (patchbomb) to the command (email)
timeless <timeless@gmail.com>
parents: 12265
diff changeset
   189
    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
   190
    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
   191
    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
   192
    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
   193
    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
   194
    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
   195
13198
e71b2aa74ce3 patchbomb: save introductory message in .hg/last-email.txt
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 12839
diff changeset
   196
    In case email sending fails, you will find a backup of your series
e71b2aa74ce3 patchbomb: save introductory message in .hg/last-email.txt
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 12839
diff changeset
   197
    introductory message in ``.hg/last-email.txt``.
e71b2aa74ce3 patchbomb: save introductory message in .hg/last-email.txt
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 12839
diff changeset
   198
9289
45aaf27f95b8 patchbomb: reST syntax for literal blocks in help text
Christian Ebert <blacktrash@gmx.net>
parents: 9286
diff changeset
   199
    Examples::
4280
a9336520a4ee Improve documentation for patchbomb and email
John Goerzen <jgoerzen@complete.org>
parents: 4279
diff changeset
   200
9289
45aaf27f95b8 patchbomb: reST syntax for literal blocks in help text
Christian Ebert <blacktrash@gmx.net>
parents: 9286
diff changeset
   201
      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
   202
      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
   203
      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
   204
      hg email 3000             # send patch 3000 (deprecated)
4280
a9336520a4ee Improve documentation for patchbomb and email
John Goerzen <jgoerzen@complete.org>
parents: 4279
diff changeset
   205
9289
45aaf27f95b8 patchbomb: reST syntax for literal blocks in help text
Christian Ebert <blacktrash@gmx.net>
parents: 9286
diff changeset
   206
      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
   207
      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
   208
      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
   209
      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
   210
9289
45aaf27f95b8 patchbomb: reST syntax for literal blocks in help text
Christian Ebert <blacktrash@gmx.net>
parents: 9286
diff changeset
   211
      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
   212
      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
   213
      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
   214
      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
   215
12749
338b4b615d33 patchbomb: move command option help from the extension (patchbomb) to the command (email)
timeless <timeless@gmail.com>
parents: 12265
diff changeset
   216
      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
   217
        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
   218
      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
   219
        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
   220
          -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
   221
9269
1d6499adf211 patchbomb: wrap docstrings at 70 characters
Martin Geisler <mg@lazybytes.net>
parents: 9214
diff changeset
   222
    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
   223
    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
   224
    '''
f51317e24114 Add --outgoing option to patchbomb
Brendan Cully <brendan@kublai.com>
parents: 4144
diff changeset
   225
7115
c5c2d43b01da patchbomb: mime-encode headers and parts not containing patches
Christian Ebert <blacktrash@gmx.net>
parents: 7095
diff changeset
   226
    _charsets = mail._charsets(ui)
c5c2d43b01da patchbomb: mime-encode headers and parts not containing patches
Christian Ebert <blacktrash@gmx.net>
parents: 7095
diff changeset
   227
11413
4c1fe996838c patchbomb: reduce number of opts.get calls
Christian Ebert <blacktrash@gmx.net>
parents: 11321
diff changeset
   228
    bundle = opts.get('bundle')
4c1fe996838c patchbomb: reduce number of opts.get calls
Christian Ebert <blacktrash@gmx.net>
parents: 11321
diff changeset
   229
    date = opts.get('date')
4c1fe996838c patchbomb: reduce number of opts.get calls
Christian Ebert <blacktrash@gmx.net>
parents: 11321
diff changeset
   230
    mbox = opts.get('mbox')
4c1fe996838c patchbomb: reduce number of opts.get calls
Christian Ebert <blacktrash@gmx.net>
parents: 11321
diff changeset
   231
    outgoing = opts.get('outgoing')
4c1fe996838c patchbomb: reduce number of opts.get calls
Christian Ebert <blacktrash@gmx.net>
parents: 11321
diff changeset
   232
    rev = opts.get('rev')
4c1fe996838c patchbomb: reduce number of opts.get calls
Christian Ebert <blacktrash@gmx.net>
parents: 11321
diff changeset
   233
    # internal option used by pbranches
4c1fe996838c patchbomb: reduce number of opts.get calls
Christian Ebert <blacktrash@gmx.net>
parents: 11321
diff changeset
   234
    patches = opts.get('patches')
4c1fe996838c patchbomb: reduce number of opts.get calls
Christian Ebert <blacktrash@gmx.net>
parents: 11321
diff changeset
   235
4c1fe996838c patchbomb: reduce number of opts.get calls
Christian Ebert <blacktrash@gmx.net>
parents: 11321
diff changeset
   236
    def getoutgoing(dest, revs):
4262
f51317e24114 Add --outgoing option to patchbomb
Brendan Cully <brendan@kublai.com>
parents: 4144
diff changeset
   237
        '''Return the revisions present locally but not in dest'''
f51317e24114 Add --outgoing option to patchbomb
Brendan Cully <brendan@kublai.com>
parents: 4144
diff changeset
   238
        dest = ui.expandpath(dest or 'default-push', dest or 'default')
10365
d757bc0c7865 interpret repo#name url syntax as branch instead of revision
Sune Foldager <cryo@cyanite.org>
parents: 10285
diff changeset
   239
        dest, branches = hg.parseurl(dest)
d757bc0c7865 interpret repo#name url syntax as branch instead of revision
Sune Foldager <cryo@cyanite.org>
parents: 10285
diff changeset
   240
        revs, checkout = hg.addbranchrevs(repo, repo, branches, revs)
10022
585f51f8b5f0 patchbomb: fix bug introduced in 4ddfad7ebd98 and add test
Sune Foldager <cryo@cyanite.org>
parents: 10018
diff changeset
   241
        if revs:
585f51f8b5f0 patchbomb: fix bug introduced in 4ddfad7ebd98 and add test
Sune Foldager <cryo@cyanite.org>
parents: 10018
diff changeset
   242
            revs = [repo.lookup(rev) for rev in revs]
11273
d1908cb95a82 remoteui: move from cmdutil to hg
Matt Mackall <mpm@selenic.com>
parents: 11193
diff changeset
   243
        other = hg.repository(hg.remoteui(repo, opts), dest)
12793
469850088fc1 patchbomb: hide passwords potentially embedded in urls
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 11413
diff changeset
   244
        ui.status(_('comparing with %s\n') % url.hidepassword(dest))
11301
3d0591a66118 move discovery methods from localrepo into new discovery module
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 11273
diff changeset
   245
        o = discovery.findoutgoing(repo, other)
4262
f51317e24114 Add --outgoing option to patchbomb
Brendan Cully <brendan@kublai.com>
parents: 4144
diff changeset
   246
        if not o:
f51317e24114 Add --outgoing option to patchbomb
Brendan Cully <brendan@kublai.com>
parents: 4144
diff changeset
   247
            ui.status(_("no changes found\n"))
f51317e24114 Add --outgoing option to patchbomb
Brendan Cully <brendan@kublai.com>
parents: 4144
diff changeset
   248
            return []
10022
585f51f8b5f0 patchbomb: fix bug introduced in 4ddfad7ebd98 and add test
Sune Foldager <cryo@cyanite.org>
parents: 10018
diff changeset
   249
        o = repo.changelog.nodesbetween(o, revs)[0]
4262
f51317e24114 Add --outgoing option to patchbomb
Brendan Cully <brendan@kublai.com>
parents: 4144
diff changeset
   250
        return [str(repo.changelog.rev(r)) for r in o]
f51317e24114 Add --outgoing option to patchbomb
Brendan Cully <brendan@kublai.com>
parents: 4144
diff changeset
   251
7615
ab39d1813e51 patch: export shouldn't close files received as a parameter
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7600
diff changeset
   252
    def getpatches(revs):
ab39d1813e51 patch: export shouldn't close files received as a parameter
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7600
diff changeset
   253
        for r in cmdutil.revrange(repo, revs):
ab39d1813e51 patch: export shouldn't close files received as a parameter
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7600
diff changeset
   254
            output = cStringIO.StringIO()
10611
e764f24a45ee patch/diff: move patch.export() to cmdutil.export()
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 10365
diff changeset
   255
            cmdutil.export(repo, [r], fp=output,
7874
d812029cda85 cleanup: drop variables for unused return values
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 7807
diff changeset
   256
                         opts=patch.diffopts(ui, opts))
7615
ab39d1813e51 patch: export shouldn't close files received as a parameter
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7600
diff changeset
   257
            yield output.getvalue().split('\n')
ab39d1813e51 patch: export shouldn't close files received as a parameter
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7600
diff changeset
   258
4279
126d1967a3f8 Add common bundle/outgoing options to hg email
John Goerzen <jgoerzen@complete.org>
parents: 4278
diff changeset
   259
    def getbundle(dest):
4278
cfe886c14ddf Add ability to send bundles to patchbomb extension
John Goerzen <jgoerzen@complete.org>
parents: 4262
diff changeset
   260
        tmpdir = tempfile.mkdtemp(prefix='hg-email-bundle-')
cfe886c14ddf Add ability to send bundles to patchbomb extension
John Goerzen <jgoerzen@complete.org>
parents: 4262
diff changeset
   261
        tmpfn = os.path.join(tmpdir, 'bundle')
cfe886c14ddf Add ability to send bundles to patchbomb extension
John Goerzen <jgoerzen@complete.org>
parents: 4262
diff changeset
   262
        try:
4279
126d1967a3f8 Add common bundle/outgoing options to hg email
John Goerzen <jgoerzen@complete.org>
parents: 4278
diff changeset
   263
            commands.bundle(ui, repo, tmpfn, dest, **opts)
13400
14f3795a5ed7 explicitly close files
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 13198
diff changeset
   264
            fp = open(tmpfn, 'rb')
14f3795a5ed7 explicitly close files
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 13198
diff changeset
   265
            data = fp.read()
14f3795a5ed7 explicitly close files
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 13198
diff changeset
   266
            fp.close()
14f3795a5ed7 explicitly close files
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 13198
diff changeset
   267
            return data
4278
cfe886c14ddf Add ability to send bundles to patchbomb extension
John Goerzen <jgoerzen@complete.org>
parents: 4262
diff changeset
   268
        finally:
cfe886c14ddf Add ability to send bundles to patchbomb extension
John Goerzen <jgoerzen@complete.org>
parents: 4262
diff changeset
   269
            try:
cfe886c14ddf Add ability to send bundles to patchbomb extension
John Goerzen <jgoerzen@complete.org>
parents: 4262
diff changeset
   270
                os.unlink(tmpfn)
cfe886c14ddf Add ability to send bundles to patchbomb extension
John Goerzen <jgoerzen@complete.org>
parents: 4262
diff changeset
   271
            except:
cfe886c14ddf Add ability to send bundles to patchbomb extension
John Goerzen <jgoerzen@complete.org>
parents: 4262
diff changeset
   272
                pass
cfe886c14ddf Add ability to send bundles to patchbomb extension
John Goerzen <jgoerzen@complete.org>
parents: 4262
diff changeset
   273
            os.rmdir(tmpdir)
cfe886c14ddf Add ability to send bundles to patchbomb extension
John Goerzen <jgoerzen@complete.org>
parents: 4262
diff changeset
   274
11413
4c1fe996838c patchbomb: reduce number of opts.get calls
Christian Ebert <blacktrash@gmx.net>
parents: 11321
diff changeset
   275
    if not (opts.get('test') or mbox):
5472
23889160905a Catch smtp exceptions
Christian Ebert <blacktrash@gmx.net>
parents: 4887
diff changeset
   276
        # really sending
4489
a11e13d50645 patchbomb: Validate email config before we start prompting for info.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4486
diff changeset
   277
        mail.validateconfig(ui)
a11e13d50645 patchbomb: Validate email config before we start prompting for info.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4486
diff changeset
   278
11413
4c1fe996838c patchbomb: reduce number of opts.get calls
Christian Ebert <blacktrash@gmx.net>
parents: 11321
diff changeset
   279
    if not (revs or rev or outgoing or bundle or patches):
4493
ead2fa544cbf patchbomb: Fail early if no revs given to email
Bryan O'Sullivan <bos@serpentine.com>
parents: 4492
diff changeset
   280
        raise util.Abort(_('specify at least one changeset with -r or -o'))
ead2fa544cbf patchbomb: Fail early if no revs given to email
Bryan O'Sullivan <bos@serpentine.com>
parents: 4492
diff changeset
   281
11413
4c1fe996838c patchbomb: reduce number of opts.get calls
Christian Ebert <blacktrash@gmx.net>
parents: 11321
diff changeset
   282
    if outgoing and bundle:
5746
d3ef7e86bc3b patchbomb: break lines > 80 chars (coding style)
Christian Ebert <blacktrash@gmx.net>
parents: 5677
diff changeset
   283
        raise util.Abort(_("--outgoing mode always on with --bundle;"
d3ef7e86bc3b patchbomb: break lines > 80 chars (coding style)
Christian Ebert <blacktrash@gmx.net>
parents: 5677
diff changeset
   284
                           " do not re-specify --outgoing"))
4278
cfe886c14ddf Add ability to send bundles to patchbomb extension
John Goerzen <jgoerzen@complete.org>
parents: 4262
diff changeset
   285
11413
4c1fe996838c patchbomb: reduce number of opts.get calls
Christian Ebert <blacktrash@gmx.net>
parents: 11321
diff changeset
   286
    if outgoing or bundle:
4262
f51317e24114 Add --outgoing option to patchbomb
Brendan Cully <brendan@kublai.com>
parents: 4144
diff changeset
   287
        if len(revs) > 1:
f51317e24114 Add --outgoing option to patchbomb
Brendan Cully <brendan@kublai.com>
parents: 4144
diff changeset
   288
            raise util.Abort(_("too many destinations"))
f51317e24114 Add --outgoing option to patchbomb
Brendan Cully <brendan@kublai.com>
parents: 4144
diff changeset
   289
        dest = revs and revs[0] or None
f51317e24114 Add --outgoing option to patchbomb
Brendan Cully <brendan@kublai.com>
parents: 4144
diff changeset
   290
        revs = []
f51317e24114 Add --outgoing option to patchbomb
Brendan Cully <brendan@kublai.com>
parents: 4144
diff changeset
   291
11413
4c1fe996838c patchbomb: reduce number of opts.get calls
Christian Ebert <blacktrash@gmx.net>
parents: 11321
diff changeset
   292
    if rev:
4262
f51317e24114 Add --outgoing option to patchbomb
Brendan Cully <brendan@kublai.com>
parents: 4144
diff changeset
   293
        if revs:
f51317e24114 Add --outgoing option to patchbomb
Brendan Cully <brendan@kublai.com>
parents: 4144
diff changeset
   294
            raise util.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
   295
        revs = rev
4262
f51317e24114 Add --outgoing option to patchbomb
Brendan Cully <brendan@kublai.com>
parents: 4144
diff changeset
   296
11413
4c1fe996838c patchbomb: reduce number of opts.get calls
Christian Ebert <blacktrash@gmx.net>
parents: 11321
diff changeset
   297
    if outgoing:
4c1fe996838c patchbomb: reduce number of opts.get calls
Christian Ebert <blacktrash@gmx.net>
parents: 11321
diff changeset
   298
        revs = getoutgoing(dest, rev)
4c1fe996838c patchbomb: reduce number of opts.get calls
Christian Ebert <blacktrash@gmx.net>
parents: 11321
diff changeset
   299
    if bundle:
4279
126d1967a3f8 Add common bundle/outgoing options to hg email
John Goerzen <jgoerzen@complete.org>
parents: 4278
diff changeset
   300
        opts['revs'] = revs
4262
f51317e24114 Add --outgoing option to patchbomb
Brendan Cully <brendan@kublai.com>
parents: 4144
diff changeset
   301
f51317e24114 Add --outgoing option to patchbomb
Brendan Cully <brendan@kublai.com>
parents: 4144
diff changeset
   302
    # start
11413
4c1fe996838c patchbomb: reduce number of opts.get calls
Christian Ebert <blacktrash@gmx.net>
parents: 11321
diff changeset
   303
    if date:
4c1fe996838c patchbomb: reduce number of opts.get calls
Christian Ebert <blacktrash@gmx.net>
parents: 11321
diff changeset
   304
        start_time = util.parsedate(date)
4566
087b3ae4f08a patchbomb: add --date option
Bryan O'Sullivan <bos@serpentine.com>
parents: 4565
diff changeset
   305
    else:
087b3ae4f08a patchbomb: add --date option
Bryan O'Sullivan <bos@serpentine.com>
parents: 4565
diff changeset
   306
        start_time = util.makedate()
875
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   307
876
14cfaaec2e8e Get patchbomb script to not use MIME attachments.
Bryan O'Sullivan <bos@serpentine.com>
parents: 875
diff changeset
   308
    def genmsgid(id):
4027
2601ac9c54f0 patchbomb: fix timezone offset in message date header
Christian Ebert <blacktrash@gmx.net>
parents: 3473
diff changeset
   309
        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
   310
5753
ea1016b32e94 patchbomb: make --bundle respect --desc
Patrick Mezard <pmezard@gmail.com>
parents: 5752
diff changeset
   311
    def getdescription(body, sender):
5818
77775ae8d5d9 patchbomb: consistently use opts.get
Christian Ebert <blacktrash@gmx.net>
parents: 5817
diff changeset
   312
        if opts.get('desc'):
77775ae8d5d9 patchbomb: consistently use opts.get
Christian Ebert <blacktrash@gmx.net>
parents: 5817
diff changeset
   313
            body = open(opts.get('desc')).read()
5753
ea1016b32e94 patchbomb: make --bundle respect --desc
Patrick Mezard <pmezard@gmail.com>
parents: 5752
diff changeset
   314
        else:
ea1016b32e94 patchbomb: make --bundle respect --desc
Patrick Mezard <pmezard@gmail.com>
parents: 5752
diff changeset
   315
            ui.write(_('\nWrite the introductory message for the '
ea1016b32e94 patchbomb: make --bundle respect --desc
Patrick Mezard <pmezard@gmail.com>
parents: 5752
diff changeset
   316
                       'patch series.\n\n'))
ea1016b32e94 patchbomb: make --bundle respect --desc
Patrick Mezard <pmezard@gmail.com>
parents: 5752
diff changeset
   317
            body = ui.edit(body, sender)
13198
e71b2aa74ce3 patchbomb: save introductory message in .hg/last-email.txt
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 12839
diff changeset
   318
            # Save serie description in case sendmail fails
e71b2aa74ce3 patchbomb: save introductory message in .hg/last-email.txt
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 12839
diff changeset
   319
            msgfile = repo.opener('last-email.txt', 'wb')
e71b2aa74ce3 patchbomb: save introductory message in .hg/last-email.txt
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 12839
diff changeset
   320
            msgfile.write(body)
e71b2aa74ce3 patchbomb: save introductory message in .hg/last-email.txt
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 12839
diff changeset
   321
            msgfile.close()
5753
ea1016b32e94 patchbomb: make --bundle respect --desc
Patrick Mezard <pmezard@gmail.com>
parents: 5752
diff changeset
   322
        return body
ea1016b32e94 patchbomb: make --bundle respect --desc
Patrick Mezard <pmezard@gmail.com>
parents: 5752
diff changeset
   323
7353
982b55ec80be patchbomb: make `hg email` reusable for other patch sources
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 7352
diff changeset
   324
    def getpatchmsgs(patches, patchnames=None):
4278
cfe886c14ddf Add ability to send bundles to patchbomb extension
John Goerzen <jgoerzen@complete.org>
parents: 4262
diff changeset
   325
        jumbo = []
cfe886c14ddf Add ability to send bundles to patchbomb extension
John Goerzen <jgoerzen@complete.org>
parents: 4262
diff changeset
   326
        msgs = []
875
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   327
5746
d3ef7e86bc3b patchbomb: break lines > 80 chars (coding style)
Christian Ebert <blacktrash@gmx.net>
parents: 5677
diff changeset
   328
        ui.write(_('This patch series consists of %d patches.\n\n')
d3ef7e86bc3b patchbomb: break lines > 80 chars (coding style)
Christian Ebert <blacktrash@gmx.net>
parents: 5677
diff changeset
   329
                 % len(patches))
4278
cfe886c14ddf Add ability to send bundles to patchbomb extension
John Goerzen <jgoerzen@complete.org>
parents: 4262
diff changeset
   330
7353
982b55ec80be patchbomb: make `hg email` reusable for other patch sources
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 7352
diff changeset
   331
        name = None
7616
b9bd6f789633 use enumerate instead of zip
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7615
diff changeset
   332
        for i, p in enumerate(patches):
4278
cfe886c14ddf Add ability to send bundles to patchbomb extension
John Goerzen <jgoerzen@complete.org>
parents: 4262
diff changeset
   333
            jumbo.extend(p)
7353
982b55ec80be patchbomb: make `hg email` reusable for other patch sources
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 7352
diff changeset
   334
            if patchnames:
982b55ec80be patchbomb: make `hg email` reusable for other patch sources
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 7352
diff changeset
   335
                name = patchnames[i]
7354
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
   336
            msg = makepatch(ui, repo, p, opts, _charsets, i + 1,
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
   337
                            len(patches), name)
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
   338
            msgs.append(msg)
4278
cfe886c14ddf Add ability to send bundles to patchbomb extension
John Goerzen <jgoerzen@complete.org>
parents: 4262
diff changeset
   339
10734
7a0502a6f9a1 patchbomb: --desc implies --intro
Cédric Duval <cedricduval@free.fr>
parents: 10611
diff changeset
   340
        if introneeded(opts, len(patches)):
4278
cfe886c14ddf Add ability to send bundles to patchbomb extension
John Goerzen <jgoerzen@complete.org>
parents: 4262
diff changeset
   341
            tlen = len(str(len(patches)))
875
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   342
9346
bb3f8f692bc6 patchbomb: add --flag to put flags in subject prefixes
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9300
diff changeset
   343
            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
   344
            if flag:
9647
f69fd20d788d patchbomb: fix double-spaces in prompts
Martin Geisler <mg@lazybytes.net>
parents: 9612
diff changeset
   345
                subj = '[PATCH %0*d of %d %s]' % (tlen, 0, len(patches), flag)
9346
bb3f8f692bc6 patchbomb: add --flag to put flags in subject prefixes
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9300
diff changeset
   346
            else:
9647
f69fd20d788d patchbomb: fix double-spaces in prompts
Martin Geisler <mg@lazybytes.net>
parents: 9612
diff changeset
   347
                subj = '[PATCH %0*d of %d]' % (tlen, 0, len(patches))
f69fd20d788d patchbomb: fix double-spaces in prompts
Martin Geisler <mg@lazybytes.net>
parents: 9612
diff changeset
   348
            subj += ' ' + (opts.get('subject') or
f69fd20d788d patchbomb: fix double-spaces in prompts
Martin Geisler <mg@lazybytes.net>
parents: 9612
diff changeset
   349
                           prompt(ui, 'Subject: ', rest=subj))
875
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   350
4278
cfe886c14ddf Add ability to send bundles to patchbomb extension
John Goerzen <jgoerzen@complete.org>
parents: 4262
diff changeset
   351
            body = ''
12200
aebb39d45500 patchbomb: let diffstat prompt only once with complete summary
Christian Ebert <blacktrash@gmx.net>
parents: 12199
diff changeset
   352
            ds = patch.diffstat(jumbo)
aebb39d45500 patchbomb: let diffstat prompt only once with complete summary
Christian Ebert <blacktrash@gmx.net>
parents: 12199
diff changeset
   353
            if ds and opts.get('diffstat'):
aebb39d45500 patchbomb: let diffstat prompt only once with complete summary
Christian Ebert <blacktrash@gmx.net>
parents: 12199
diff changeset
   354
                body = '\n' + ds
4278
cfe886c14ddf Add ability to send bundles to patchbomb extension
John Goerzen <jgoerzen@complete.org>
parents: 4262
diff changeset
   355
5753
ea1016b32e94 patchbomb: make --bundle respect --desc
Patrick Mezard <pmezard@gmail.com>
parents: 5752
diff changeset
   356
            body = getdescription(body, sender)
7115
c5c2d43b01da patchbomb: mime-encode headers and parts not containing patches
Christian Ebert <blacktrash@gmx.net>
parents: 7095
diff changeset
   357
            msg = mail.mimeencode(ui, body, _charsets, opts.get('test'))
c5c2d43b01da patchbomb: mime-encode headers and parts not containing patches
Christian Ebert <blacktrash@gmx.net>
parents: 7095
diff changeset
   358
            msg['Subject'] = mail.headencode(ui, subj, _charsets,
c5c2d43b01da patchbomb: mime-encode headers and parts not containing patches
Christian Ebert <blacktrash@gmx.net>
parents: 7095
diff changeset
   359
                                             opts.get('test'))
875
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   360
12200
aebb39d45500 patchbomb: let diffstat prompt only once with complete summary
Christian Ebert <blacktrash@gmx.net>
parents: 12199
diff changeset
   361
            msgs.insert(0, (msg, subj, ds))
4278
cfe886c14ddf Add ability to send bundles to patchbomb extension
John Goerzen <jgoerzen@complete.org>
parents: 4262
diff changeset
   362
        return msgs
2704
99e7cf6bd2f7 make introductory message of patch series text/plain
Christian Ebert <blacktrash@gmx.net>
parents: 2443
diff changeset
   363
4278
cfe886c14ddf Add ability to send bundles to patchbomb extension
John Goerzen <jgoerzen@complete.org>
parents: 4262
diff changeset
   364
    def getbundlemsgs(bundle):
5818
77775ae8d5d9 patchbomb: consistently use opts.get
Christian Ebert <blacktrash@gmx.net>
parents: 5817
diff changeset
   365
        subj = (opts.get('subject')
7354
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
   366
                or prompt(ui, 'Subject:', 'A bundle for your repository'))
875
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   367
5753
ea1016b32e94 patchbomb: make --bundle respect --desc
Patrick Mezard <pmezard@gmail.com>
parents: 5752
diff changeset
   368
        body = getdescription('', sender)
4278
cfe886c14ddf Add ability to send bundles to patchbomb extension
John Goerzen <jgoerzen@complete.org>
parents: 4262
diff changeset
   369
        msg = email.MIMEMultipart.MIMEMultipart()
cfe886c14ddf Add ability to send bundles to patchbomb extension
John Goerzen <jgoerzen@complete.org>
parents: 4262
diff changeset
   370
        if body:
7115
c5c2d43b01da patchbomb: mime-encode headers and parts not containing patches
Christian Ebert <blacktrash@gmx.net>
parents: 7095
diff changeset
   371
            msg.attach(mail.mimeencode(ui, body, _charsets, opts.get('test')))
4278
cfe886c14ddf Add ability to send bundles to patchbomb extension
John Goerzen <jgoerzen@complete.org>
parents: 4262
diff changeset
   372
        datapart = email.MIMEBase.MIMEBase('application', 'x-mercurial-bundle')
cfe886c14ddf Add ability to send bundles to patchbomb extension
John Goerzen <jgoerzen@complete.org>
parents: 4262
diff changeset
   373
        datapart.set_payload(bundle)
7889
5ac1a72e5b74 patchbomb: option to set the name of bundle attachment (issue1452)
John Mulligan <phlogistonjohn@asynchrono.us>
parents: 7874
diff changeset
   374
        bundlename = '%s.hg' % opts.get('bundlename', 'bundle')
4284
a04141f51056 Add a filename for the bundle
John Goerzen <jgoerzen@complete.org>
parents: 4283
diff changeset
   375
        datapart.add_header('Content-Disposition', 'attachment',
7889
5ac1a72e5b74 patchbomb: option to set the name of bundle attachment (issue1452)
John Mulligan <phlogistonjohn@asynchrono.us>
parents: 7874
diff changeset
   376
                            filename=bundlename)
4278
cfe886c14ddf Add ability to send bundles to patchbomb extension
John Goerzen <jgoerzen@complete.org>
parents: 4262
diff changeset
   377
        email.Encoders.encode_base64(datapart)
cfe886c14ddf Add ability to send bundles to patchbomb extension
John Goerzen <jgoerzen@complete.org>
parents: 4262
diff changeset
   378
        msg.attach(datapart)
7115
c5c2d43b01da patchbomb: mime-encode headers and parts not containing patches
Christian Ebert <blacktrash@gmx.net>
parents: 7095
diff changeset
   379
        msg['Subject'] = mail.headencode(ui, subj, _charsets, opts.get('test'))
12200
aebb39d45500 patchbomb: let diffstat prompt only once with complete summary
Christian Ebert <blacktrash@gmx.net>
parents: 12199
diff changeset
   380
        return [(msg, subj, None)]
875
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   381
5818
77775ae8d5d9 patchbomb: consistently use opts.get
Christian Ebert <blacktrash@gmx.net>
parents: 5817
diff changeset
   382
    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
   383
              ui.config('patchbomb', 'from') or
7354
cad454f295b0 patchbomb: extract a bunch of nested functions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7353
diff changeset
   384
              prompt(ui, 'From', ui.username()))
875
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   385
7353
982b55ec80be patchbomb: make `hg email` reusable for other patch sources
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 7352
diff changeset
   386
    if patches:
982b55ec80be patchbomb: make `hg email` reusable for other patch sources
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 7352
diff changeset
   387
        msgs = getpatchmsgs(patches, opts.get('patchnames'))
11413
4c1fe996838c patchbomb: reduce number of opts.get calls
Christian Ebert <blacktrash@gmx.net>
parents: 11321
diff changeset
   388
    elif bundle:
4279
126d1967a3f8 Add common bundle/outgoing options to hg email
John Goerzen <jgoerzen@complete.org>
parents: 4278
diff changeset
   389
        msgs = getbundlemsgs(getbundle(dest))
4278
cfe886c14ddf Add ability to send bundles to patchbomb extension
John Goerzen <jgoerzen@complete.org>
parents: 4262
diff changeset
   390
    else:
7615
ab39d1813e51 patch: export shouldn't close files received as a parameter
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7600
diff changeset
   391
        msgs = getpatchmsgs(list(getpatches(revs)))
875
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   392
12200
aebb39d45500 patchbomb: let diffstat prompt only once with complete summary
Christian Ebert <blacktrash@gmx.net>
parents: 12199
diff changeset
   393
    showaddrs = []
aebb39d45500 patchbomb: let diffstat prompt only once with complete summary
Christian Ebert <blacktrash@gmx.net>
parents: 12199
diff changeset
   394
9947
4600e6222efb patchbomb: fix parsing of multiple addresses, allow multiple addrs in --to/cc/bcc
Marti Raudsepp <marti@juffo.org>
parents: 9818
diff changeset
   395
    def getaddrs(opt, prpt=None, default=None):
11150
f66ca4431eb9 patchbomb: Reply-To support
Cédric Duval <cedricduval@free.fr>
parents: 10973
diff changeset
   396
        addrs = opts.get(opt.replace('-', '_'))
12200
aebb39d45500 patchbomb: let diffstat prompt only once with complete summary
Christian Ebert <blacktrash@gmx.net>
parents: 12199
diff changeset
   397
        if opt != 'reply-to':
aebb39d45500 patchbomb: let diffstat prompt only once with complete summary
Christian Ebert <blacktrash@gmx.net>
parents: 12199
diff changeset
   398
            showaddr = '%s:' % opt.capitalize()
aebb39d45500 patchbomb: let diffstat prompt only once with complete summary
Christian Ebert <blacktrash@gmx.net>
parents: 12199
diff changeset
   399
        else:
aebb39d45500 patchbomb: let diffstat prompt only once with complete summary
Christian Ebert <blacktrash@gmx.net>
parents: 12199
diff changeset
   400
            showaddr = 'Reply-To:'
aebb39d45500 patchbomb: let diffstat prompt only once with complete summary
Christian Ebert <blacktrash@gmx.net>
parents: 12199
diff changeset
   401
11150
f66ca4431eb9 patchbomb: Reply-To support
Cédric Duval <cedricduval@free.fr>
parents: 10973
diff changeset
   402
        if addrs:
12200
aebb39d45500 patchbomb: let diffstat prompt only once with complete summary
Christian Ebert <blacktrash@gmx.net>
parents: 12199
diff changeset
   403
            showaddrs.append('%s %s' % (showaddr, ', '.join(addrs)))
12264
b8146231c3de patchbomb: consistent code style in getaddrs()
Christian Ebert <blacktrash@gmx.net>
parents: 12201
diff changeset
   404
            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
   405
12064
6449be7b8a3b patchbomb: remove unneeded line continuation
Christian Ebert <blacktrash@gmx.net>
parents: 11413
diff changeset
   406
        addrs = ui.config('email', opt) or ui.config('patchbomb', opt) or ''
9947
4600e6222efb patchbomb: fix parsing of multiple addresses, allow multiple addrs in --to/cc/bcc
Marti Raudsepp <marti@juffo.org>
parents: 9818
diff changeset
   407
        if not addrs and prpt:
4600e6222efb patchbomb: fix parsing of multiple addresses, allow multiple addrs in --to/cc/bcc
Marti Raudsepp <marti@juffo.org>
parents: 9818
diff changeset
   408
            addrs = prompt(ui, prpt, default)
4600e6222efb patchbomb: fix parsing of multiple addresses, allow multiple addrs in --to/cc/bcc
Marti Raudsepp <marti@juffo.org>
parents: 9818
diff changeset
   409
12200
aebb39d45500 patchbomb: let diffstat prompt only once with complete summary
Christian Ebert <blacktrash@gmx.net>
parents: 12199
diff changeset
   410
        if addrs:
12264
b8146231c3de patchbomb: consistent code style in getaddrs()
Christian Ebert <blacktrash@gmx.net>
parents: 12201
diff changeset
   411
            showaddrs.append('%s %s' % (showaddr, addrs))
9947
4600e6222efb patchbomb: fix parsing of multiple addresses, allow multiple addrs in --to/cc/bcc
Marti Raudsepp <marti@juffo.org>
parents: 9818
diff changeset
   412
        return mail.addrlistencode(ui, [addrs], _charsets, opts.get('test'))
4485
82bc6aef8b43 patchbomb: Don't prompt for headers until sure we have revs to export.
Bryan O'Sullivan <bos@serpentine.com>
parents: 4284
diff changeset
   413
1154
c3cb9f39a91f patchbomb: fix up confusion between strings and lists of strings.
bos@serpentine.internal.keyresearch.com
parents: 1136
diff changeset
   414
    to = getaddrs('to', 'To')
c3cb9f39a91f patchbomb: fix up confusion between strings and lists of strings.
bos@serpentine.internal.keyresearch.com
parents: 1136
diff changeset
   415
    cc = getaddrs('cc', 'Cc', '')
9947
4600e6222efb patchbomb: fix parsing of multiple addresses, allow multiple addrs in --to/cc/bcc
Marti Raudsepp <marti@juffo.org>
parents: 9818
diff changeset
   416
    bcc = getaddrs('bcc')
11150
f66ca4431eb9 patchbomb: Reply-To support
Cédric Duval <cedricduval@free.fr>
parents: 10973
diff changeset
   417
    replyto = getaddrs('reply-to')
2679
f1de91be1d87 optionally send blind carbon copies
Christian Ebert <blacktrash@gmx.net>
parents: 2443
diff changeset
   418
12201
5bfa45651cf6 patchbomb: add --confirm option to show series details and ask for confirmation
Christian Ebert <blacktrash@gmx.net>
parents: 12200
diff changeset
   419
    if opts.get('diffstat') or opts.get('confirm'):
12200
aebb39d45500 patchbomb: let diffstat prompt only once with complete summary
Christian Ebert <blacktrash@gmx.net>
parents: 12199
diff changeset
   420
        ui.write(_('\nFinal summary:\n\n'))
aebb39d45500 patchbomb: let diffstat prompt only once with complete summary
Christian Ebert <blacktrash@gmx.net>
parents: 12199
diff changeset
   421
        ui.write('From: %s\n' % sender)
aebb39d45500 patchbomb: let diffstat prompt only once with complete summary
Christian Ebert <blacktrash@gmx.net>
parents: 12199
diff changeset
   422
        for addr in showaddrs:
aebb39d45500 patchbomb: let diffstat prompt only once with complete summary
Christian Ebert <blacktrash@gmx.net>
parents: 12199
diff changeset
   423
            ui.write('%s\n' % addr)
aebb39d45500 patchbomb: let diffstat prompt only once with complete summary
Christian Ebert <blacktrash@gmx.net>
parents: 12199
diff changeset
   424
        for m, subj, ds in msgs:
aebb39d45500 patchbomb: let diffstat prompt only once with complete summary
Christian Ebert <blacktrash@gmx.net>
parents: 12199
diff changeset
   425
            ui.write('Subject: %s\n' % subj)
aebb39d45500 patchbomb: let diffstat prompt only once with complete summary
Christian Ebert <blacktrash@gmx.net>
parents: 12199
diff changeset
   426
            if ds:
aebb39d45500 patchbomb: let diffstat prompt only once with complete summary
Christian Ebert <blacktrash@gmx.net>
parents: 12199
diff changeset
   427
                ui.write(ds)
aebb39d45500 patchbomb: let diffstat prompt only once with complete summary
Christian Ebert <blacktrash@gmx.net>
parents: 12199
diff changeset
   428
        ui.write('\n')
aebb39d45500 patchbomb: let diffstat prompt only once with complete summary
Christian Ebert <blacktrash@gmx.net>
parents: 12199
diff changeset
   429
        if ui.promptchoice(_('are you sure you want to send (yn)?'),
aebb39d45500 patchbomb: let diffstat prompt only once with complete summary
Christian Ebert <blacktrash@gmx.net>
parents: 12199
diff changeset
   430
                           (_('&Yes'), _('&No'))):
aebb39d45500 patchbomb: let diffstat prompt only once with complete summary
Christian Ebert <blacktrash@gmx.net>
parents: 12199
diff changeset
   431
            raise util.Abort(_('patchbomb canceled'))
aebb39d45500 patchbomb: let diffstat prompt only once with complete summary
Christian Ebert <blacktrash@gmx.net>
parents: 12199
diff changeset
   432
875
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   433
    ui.write('\n')
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   434
8025
1280934dd2dd patchbomb: Support initial in-reply-to header
Henrik Stuart <henrik.stuart at edlund.dk>
parents: 7997
diff changeset
   435
    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
   436
    # 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
   437
    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
   438
        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
   439
            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
   440
        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
   441
            parent += '>'
2aff285b902f patchbomb: do not assume the presence of angle brackets around msg-id
Cédric Duval <cedricduval@free.fr>
parents: 8761
diff changeset
   442
8514
252232621165 patchbomb: with --in-reply-to, still thread message under first in series
Cédric Duval <cedricduval@free.fr>
parents: 8512
diff changeset
   443
    first = True
2443
bd9c39e8f38b patchbomb does not handle email time stamp plattform independent
Volker Kleinfeld <Volker.Kleinfeld@gmx.de>
parents: 2292
diff changeset
   444
1827
26dd4ae77b7b get patchbomb extension to use demandload. speeds up hg startup by 50%.
Vadim Gelfer <vadim.gelger@gmail.com>
parents: 1702
diff changeset
   445
    sender_addr = email.Utils.parseaddr(sender)[1]
7115
c5c2d43b01da patchbomb: mime-encode headers and parts not containing patches
Christian Ebert <blacktrash@gmx.net>
parents: 7095
diff changeset
   446
    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
   447
    sendmail = None
12265
1ed2dc9d4368 patchbomb: show progress when sending emails or writing mbox
Yuya Nishihara <yuya@tcha.org>
parents: 12264
diff changeset
   448
    for i, (m, subj, ds) in enumerate(msgs):
875
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   449
        try:
876
14cfaaec2e8e Get patchbomb script to not use MIME attachments.
Bryan O'Sullivan <bos@serpentine.com>
parents: 875
diff changeset
   450
            m['Message-Id'] = genmsgid(m['X-Mercurial-Node'])
875
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   451
        except TypeError:
876
14cfaaec2e8e Get patchbomb script to not use MIME attachments.
Bryan O'Sullivan <bos@serpentine.com>
parents: 875
diff changeset
   452
            m['Message-Id'] = genmsgid('patchbomb')
875
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   453
        if parent:
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   454
            m['In-Reply-To'] = parent
7413
0b6428da1f22 email: add References field in the header
Benoit Allard <benoit@aeteurope.nl>
parents: 7360
diff changeset
   455
            m['References'] = parent
8514
252232621165 patchbomb: with --in-reply-to, still thread message under first in series
Cédric Duval <cedricduval@free.fr>
parents: 8512
diff changeset
   456
        if first:
876
14cfaaec2e8e Get patchbomb script to not use MIME attachments.
Bryan O'Sullivan <bos@serpentine.com>
parents: 875
diff changeset
   457
            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
   458
            first = False
252232621165 patchbomb: with --in-reply-to, still thread message under first in series
Cédric Duval <cedricduval@free.fr>
parents: 8512
diff changeset
   459
8160
094e0d982c8a patchbomb: add user agent header to mails
Henrik Stuart <hg@hstuart.dk>
parents: 8076
diff changeset
   460
        m['User-Agent'] = 'Mercurial-patchbomb/%s' % util.version()
9047
8263d98ffb1c patchbomb: use local time for the Date: header
Cédric Duval <cedricduval@free.fr>
parents: 9046
diff changeset
   461
        m['Date'] = email.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
   462
4027
2601ac9c54f0 patchbomb: fix timezone offset in message date header
Christian Ebert <blacktrash@gmx.net>
parents: 3473
diff changeset
   463
        start_time = (start_time[0] + 1, start_time[1])
875
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   464
        m['From'] = sender
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   465
        m['To'] = ', '.join(to)
5785
38cd1ce8650d patchbomb: add linebreaks after colons (coding style)
Christian Ebert <blacktrash@gmx.net>
parents: 5758
diff changeset
   466
        if cc:
38cd1ce8650d patchbomb: add linebreaks after colons (coding style)
Christian Ebert <blacktrash@gmx.net>
parents: 5758
diff changeset
   467
            m['Cc']  = ', '.join(cc)
38cd1ce8650d patchbomb: add linebreaks after colons (coding style)
Christian Ebert <blacktrash@gmx.net>
parents: 5758
diff changeset
   468
        if bcc:
38cd1ce8650d patchbomb: add linebreaks after colons (coding style)
Christian Ebert <blacktrash@gmx.net>
parents: 5758
diff changeset
   469
            m['Bcc'] = ', '.join(bcc)
11150
f66ca4431eb9 patchbomb: Reply-To support
Cédric Duval <cedricduval@free.fr>
parents: 10973
diff changeset
   470
        if replyto:
f66ca4431eb9 patchbomb: Reply-To support
Cédric Duval <cedricduval@free.fr>
parents: 10973
diff changeset
   471
            m['Reply-To'] = ', '.join(replyto)
5818
77775ae8d5d9 patchbomb: consistently use opts.get
Christian Ebert <blacktrash@gmx.net>
parents: 5817
diff changeset
   472
        if opts.get('test'):
7115
c5c2d43b01da patchbomb: mime-encode headers and parts not containing patches
Christian Ebert <blacktrash@gmx.net>
parents: 7095
diff changeset
   473
            ui.status(_('Displaying '), subj, ' ...\n')
4596
8e37342cb05d patchbomb: flush ui before delegating to pager.
Patrick Mezard <pmezard@gmail.com>
parents: 4142
diff changeset
   474
            ui.flush()
11183
b25464e9b448 patchbomb: respect HGPLAIN when piping --test output to PAGER
Yuya Nishihara <yuya@tcha.org>
parents: 11150
diff changeset
   475
            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
   476
                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
   477
            else:
88fc92b0b821 patchbomb: page patchbomb messages only if PAGER is defined.
Patrick Mezard <pmezard@gmail.com>
parents: 4597
diff changeset
   478
                fp = ui
6447
9d2ce19bdacd patchbomb: Fix mangling of lines beginning with From
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 6229
diff changeset
   479
            generator = email.Generator.Generator(fp, mangle_from_=False)
1871
258e3a7955b8 patchbomb: ignore exception if pager quits.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1846
diff changeset
   480
            try:
6447
9d2ce19bdacd patchbomb: Fix mangling of lines beginning with From
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 6229
diff changeset
   481
                generator.flatten(m, 0)
1871
258e3a7955b8 patchbomb: ignore exception if pager quits.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1846
diff changeset
   482
                fp.write('\n')
258e3a7955b8 patchbomb: ignore exception if pager quits.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1846
diff changeset
   483
            except IOError, inst:
258e3a7955b8 patchbomb: ignore exception if pager quits.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1846
diff changeset
   484
                if inst.errno != errno.EPIPE:
258e3a7955b8 patchbomb: ignore exception if pager quits.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1846
diff changeset
   485
                    raise
4599
88fc92b0b821 patchbomb: page patchbomb messages only if PAGER is defined.
Patrick Mezard <pmezard@gmail.com>
parents: 4597
diff changeset
   486
            if fp is not ui:
88fc92b0b821 patchbomb: page patchbomb messages only if PAGER is defined.
Patrick Mezard <pmezard@gmail.com>
parents: 4597
diff changeset
   487
                fp.close()
11413
4c1fe996838c patchbomb: reduce number of opts.get calls
Christian Ebert <blacktrash@gmx.net>
parents: 11321
diff changeset
   488
        elif mbox:
7115
c5c2d43b01da patchbomb: mime-encode headers and parts not containing patches
Christian Ebert <blacktrash@gmx.net>
parents: 7095
diff changeset
   489
            ui.status(_('Writing '), subj, ' ...\n')
12265
1ed2dc9d4368 patchbomb: show progress when sending emails or writing mbox
Yuya Nishihara <yuya@tcha.org>
parents: 12264
diff changeset
   490
            ui.progress(_('writing'), i, item=subj, total=len(msgs))
11413
4c1fe996838c patchbomb: reduce number of opts.get calls
Christian Ebert <blacktrash@gmx.net>
parents: 11321
diff changeset
   491
            fp = open(mbox, 'In-Reply-To' in m and 'ab+' or 'wb+')
6447
9d2ce19bdacd patchbomb: Fix mangling of lines beginning with From
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 6229
diff changeset
   492
            generator = email.Generator.Generator(fp, mangle_from_=True)
9818
72d670c43f6e patchbomb: normalize date format in generated mboxes
Patrick Mezard <pmezard@gmail.com>
parents: 9648
diff changeset
   493
            # Should be time.asctime(), but Windows prints 2-characters day
72d670c43f6e patchbomb: normalize date format in generated mboxes
Patrick Mezard <pmezard@gmail.com>
parents: 9648
diff changeset
   494
            # of month instead of one. Make them print the same thing.
72d670c43f6e patchbomb: normalize date format in generated mboxes
Patrick Mezard <pmezard@gmail.com>
parents: 9648
diff changeset
   495
            date = time.strftime('%a %b %d %H:%M:%S %Y',
72d670c43f6e patchbomb: normalize date format in generated mboxes
Patrick Mezard <pmezard@gmail.com>
parents: 9648
diff changeset
   496
                                 time.localtime(start_time[0]))
1702
e291d9a30bef add --mbox output to patchbomb
Johannes Stezenbach <js@linuxtv.org>
parents: 1691
diff changeset
   497
            fp.write('From %s %s\n' % (sender_addr, date))
6447
9d2ce19bdacd patchbomb: Fix mangling of lines beginning with From
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 6229
diff changeset
   498
            generator.flatten(m, 0)
1702
e291d9a30bef add --mbox output to patchbomb
Johannes Stezenbach <js@linuxtv.org>
parents: 1691
diff changeset
   499
            fp.write('\n\n')
e291d9a30bef add --mbox output to patchbomb
Johannes Stezenbach <js@linuxtv.org>
parents: 1691
diff changeset
   500
            fp.close()
875
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   501
        else:
5973
ea77f6f77514 patchbomb: undo backout and fix bugs in the earlier patch
Matt Mackall <mpm@selenic.com>
parents: 5948
diff changeset
   502
            if not sendmail:
ea77f6f77514 patchbomb: undo backout and fix bugs in the earlier patch
Matt Mackall <mpm@selenic.com>
parents: 5948
diff changeset
   503
                sendmail = mail.connect(ui)
7115
c5c2d43b01da patchbomb: mime-encode headers and parts not containing patches
Christian Ebert <blacktrash@gmx.net>
parents: 7095
diff changeset
   504
            ui.status(_('Sending '), subj, ' ...\n')
12265
1ed2dc9d4368 patchbomb: show progress when sending emails or writing mbox
Yuya Nishihara <yuya@tcha.org>
parents: 12264
diff changeset
   505
            ui.progress(_('sending'), i, item=subj, total=len(msgs))
2790
58a679745b38 mailbomb: add a comment and remove the bcc in a more pythonic way
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 2732
diff changeset
   506
            # Exim does not remove the Bcc field
58a679745b38 mailbomb: add a comment and remove the bcc in a more pythonic way
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 2732
diff changeset
   507
            del m['Bcc']
6447
9d2ce19bdacd patchbomb: Fix mangling of lines beginning with From
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 6229
diff changeset
   508
            fp = cStringIO.StringIO()
9d2ce19bdacd patchbomb: Fix mangling of lines beginning with From
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 6229
diff changeset
   509
            generator = email.Generator.Generator(fp, mangle_from_=False)
9d2ce19bdacd patchbomb: Fix mangling of lines beginning with From
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 6229
diff changeset
   510
            generator.flatten(m, 0)
9d2ce19bdacd patchbomb: Fix mangling of lines beginning with From
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 6229
diff changeset
   511
            sendmail(sender, to + bcc + cc, fp.getvalue())
875
d3f836bf6cc1 Add patchbomb script.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
   512
12265
1ed2dc9d4368 patchbomb: show progress when sending emails or writing mbox
Yuya Nishihara <yuya@tcha.org>
parents: 12264
diff changeset
   513
    ui.progress(_('writing'), None)
1ed2dc9d4368 patchbomb: show progress when sending emails or writing mbox
Yuya Nishihara <yuya@tcha.org>
parents: 12264
diff changeset
   514
    ui.progress(_('sending'), None)
1ed2dc9d4368 patchbomb: show progress when sending emails or writing mbox
Yuya Nishihara <yuya@tcha.org>
parents: 12264
diff changeset
   515
7352
6c336e7dc145 patchbomb: make options to email command reusable
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 7322
diff changeset
   516
emailopts = [
6c336e7dc145 patchbomb: make options to email command reusable
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 7322
diff changeset
   517
          ('a', 'attach', None, _('send patches as attachments')),
5819
89ea99c7bdfd patchbomb: attachment options changed
Dennis Schoen <ds@1d10t.de>
parents: 5818
diff changeset
   518
          ('i', 'inline', None, _('send patches as inline attachments')),
7807
bd8f44638847 help: miscellaneous language fixes
timeless <timeless@gmail.com>
parents: 7694
diff changeset
   519
          ('', 'bcc', [], _('email addresses of blind carbon copy recipients')),
4730
eadfaa9ec487 Updated command tables in commands.py and hgext extensions.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4633
diff changeset
   520
          ('c', 'cc', [], _('email addresses of copy recipients')),
12201
5bfa45651cf6 patchbomb: add --confirm option to show series details and ask for confirmation
Christian Ebert <blacktrash@gmx.net>
parents: 12200
diff changeset
   521
          ('', 'confirm', None, _('ask for confirmation before sending')),
4730
eadfaa9ec487 Updated command tables in commands.py and hgext extensions.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4633
diff changeset
   522
          ('d', 'diffstat', None, _('add diffstat output to messages')),
eadfaa9ec487 Updated command tables in commands.py and hgext extensions.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4633
diff changeset
   523
          ('', 'date', '', _('use the given date as the sending date')),
4887
2f09df302f30 patchbomb: add --desc, to specify a file containing a series description
Bryan O'Sullivan <bos@serpentine.com>
parents: 4730
diff changeset
   524
          ('', 'desc', '', _('use the given file as the series description')),
4730
eadfaa9ec487 Updated command tables in commands.py and hgext extensions.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4633
diff changeset
   525
          ('f', 'from', '', _('email address of sender')),
eadfaa9ec487 Updated command tables in commands.py and hgext extensions.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4633
diff changeset
   526
          ('n', 'test', None, _('print messages that would be sent')),
eadfaa9ec487 Updated command tables in commands.py and hgext extensions.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4633
diff changeset
   527
          ('m', 'mbox', '',
eadfaa9ec487 Updated command tables in commands.py and hgext extensions.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4633
diff changeset
   528
           _('write messages to mbox file instead of sending them')),
11150
f66ca4431eb9 patchbomb: Reply-To support
Cédric Duval <cedricduval@free.fr>
parents: 10973
diff changeset
   529
          ('', 'reply-to', [], _('email addresses replies should be sent to')),
7352
6c336e7dc145 patchbomb: make options to email command reusable
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 7322
diff changeset
   530
          ('s', 'subject', '',
6c336e7dc145 patchbomb: make options to email command reusable
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 7322
diff changeset
   531
           _('subject of first message (intro or single patch)')),
8025
1280934dd2dd patchbomb: Support initial in-reply-to header
Henrik Stuart <henrik.stuart at edlund.dk>
parents: 7997
diff changeset
   532
          ('', 'in-reply-to', '',
8331
03cfc6ea93df patchbomb: fix quotes in help string
Martin Geisler <mg@lazybytes.net>
parents: 8252
diff changeset
   533
           _('message identifier to reply to')),
9346
bb3f8f692bc6 patchbomb: add --flag to put flags in subject prefixes
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9300
diff changeset
   534
          ('', 'flag', [], _('flags to add in subject prefixes')),
7352
6c336e7dc145 patchbomb: make options to email command reusable
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 7322
diff changeset
   535
          ('t', 'to', [], _('email addresses of recipients')),
6c336e7dc145 patchbomb: make options to email command reusable
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 7322
diff changeset
   536
         ]
6c336e7dc145 patchbomb: make options to email command reusable
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 7322
diff changeset
   537
6c336e7dc145 patchbomb: make options to email command reusable
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 7322
diff changeset
   538
6c336e7dc145 patchbomb: make options to email command reusable
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 7322
diff changeset
   539
cmdtable = {
6c336e7dc145 patchbomb: make options to email command reusable
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 7322
diff changeset
   540
    "email":
6c336e7dc145 patchbomb: make options to email command reusable
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 7322
diff changeset
   541
        (patchbomb,
6c336e7dc145 patchbomb: make options to email command reusable
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 7322
diff changeset
   542
         [('g', 'git', None, _('use git extended diff format')),
6c336e7dc145 patchbomb: make options to email command reusable
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 7322
diff changeset
   543
          ('', 'plain', None, _('omit hg patch header')),
4730
eadfaa9ec487 Updated command tables in commands.py and hgext extensions.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4633
diff changeset
   544
          ('o', 'outgoing', None,
eadfaa9ec487 Updated command tables in commands.py and hgext extensions.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4633
diff changeset
   545
           _('send changes not found in the target repository')),
eadfaa9ec487 Updated command tables in commands.py and hgext extensions.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4633
diff changeset
   546
          ('b', 'bundle', None,
eadfaa9ec487 Updated command tables in commands.py and hgext extensions.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4633
diff changeset
   547
           _('send changes not in target as a binary bundle')),
7889
5ac1a72e5b74 patchbomb: option to set the name of bundle attachment (issue1452)
John Mulligan <phlogistonjohn@asynchrono.us>
parents: 7874
diff changeset
   548
          ('', 'bundlename', 'bundle',
11321
40c06bbf58be help: show value requirement and multiple occurrence of options
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 11301
diff changeset
   549
           _('name of the bundle attachment file'), _('NAME')),
40c06bbf58be help: show value requirement and multiple occurrence of options
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 11301
diff changeset
   550
          ('r', 'rev', [],
40c06bbf58be help: show value requirement and multiple occurrence of options
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 11301
diff changeset
   551
           _('a revision to send'), _('REV')),
4730
eadfaa9ec487 Updated command tables in commands.py and hgext extensions.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4633
diff changeset
   552
          ('', 'force', None,
8076
5ec526c1a32f help texts: write command line switches as -a/--abc
Martin Geisler <mg@lazybytes.net>
parents: 8025
diff changeset
   553
           _('run even when remote repository is unrelated '
5ec526c1a32f help texts: write command line switches as -a/--abc
Martin Geisler <mg@lazybytes.net>
parents: 8025
diff changeset
   554
             '(with -b/--bundle)')),
4730
eadfaa9ec487 Updated command tables in commands.py and hgext extensions.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4633
diff changeset
   555
          ('', 'base', [],
8076
5ec526c1a32f help texts: write command line switches as -a/--abc
Martin Geisler <mg@lazybytes.net>
parents: 8025
diff changeset
   556
           _('a base changeset to specify instead of a destination '
11321
40c06bbf58be help: show value requirement and multiple occurrence of options
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 11301
diff changeset
   557
             '(with -b/--bundle)'),
40c06bbf58be help: show value requirement and multiple occurrence of options
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 11301
diff changeset
   558
           _('REV')),
7360
42f1b8cb9a60 patchbomb: add option to send intro email for a single patch (issue1120)
Chris Winter <elwintro@gmail.com>
parents: 7359
diff changeset
   559
          ('', 'intro', None,
42f1b8cb9a60 patchbomb: add option to send intro email for a single patch (issue1120)
Chris Winter <elwintro@gmail.com>
parents: 7359
diff changeset
   560
           _('send an introduction email for a single patch')),
7352
6c336e7dc145 patchbomb: make options to email command reusable
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 7322
diff changeset
   561
         ] + emailopts + commands.remoteopts,
4730
eadfaa9ec487 Updated command tables in commands.py and hgext extensions.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4633
diff changeset
   562
         _('hg email [OPTION]... [DEST]...'))
eadfaa9ec487 Updated command tables in commands.py and hgext extensions.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4633
diff changeset
   563
}