hgext/hooklib/changeset_published.py
author Pierre-Yves David <pierre-yves.david@octobus.net>
Thu, 20 May 2021 21:47:09 +0200
changeset 47459 c252631500e4
parent 45957 89a2afe31e82
child 48966 6000f5b25c9b
permissions -rw-r--r--
revlog: add a way to keep track of older uids in the docket When the revlog content is rewritten, we will use new files, to avoid truncating the previous ones. We need some way to keep track of the older files before we clean them up. Differential Revision: https://phab.mercurial-scm.org/D10866
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
44440
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
     1
# Copyright 2020 Joerg Sonnenberger <joerg@bec.de>
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
     2
#
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
     3
# This software may be used and distributed according to the terms of the
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
     4
# GNU General Public License version 2 or any later version.
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
     5
"""changeset_published is a hook to send a mail when an
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
     6
existing draft changeset is moved to the public phase.
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
     7
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
     8
Correct message threading requires the same messageidseed to be used for both
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
     9
the original notification and the new mail.
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
    10
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
    11
Usage:
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
    12
  [notify]
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
    13
  messageidseed = myseed
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
    14
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
    15
  [hooks]
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
    16
  txnclose-phase.changeset_published = \
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
    17
    python:hgext.hooklib.changeset_published.hook
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
    18
"""
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
    19
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
    20
from __future__ import absolute_import
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
    21
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
    22
import email.errors as emailerrors
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
    23
import email.utils as emailutils
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
    24
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
    25
from mercurial.i18n import _
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
    26
from mercurial import (
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
    27
    encoding,
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
    28
    error,
45292
3c2fae87bd5a templatespec: use new factory functions in hooklib
Martin von Zweigbergk <martinvonz@google.com>
parents: 44440
diff changeset
    29
    formatter,
44440
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
    30
    logcmdutil,
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
    31
    mail,
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
    32
    pycompat,
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
    33
    registrar,
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
    34
)
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
    35
from mercurial.utils import dateutil
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
    36
from .. import notify
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
    37
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
    38
configtable = {}
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
    39
configitem = registrar.configitem(configtable)
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
    40
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
    41
configitem(
45957
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45292
diff changeset
    42
    b'notify_published',
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45292
diff changeset
    43
    b'domain',
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45292
diff changeset
    44
    default=None,
44440
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
    45
)
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
    46
configitem(
45957
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45292
diff changeset
    47
    b'notify_published',
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45292
diff changeset
    48
    b'messageidseed',
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45292
diff changeset
    49
    default=None,
44440
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
    50
)
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
    51
configitem(
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
    52
    b'notify_published',
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
    53
    b'template',
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
    54
    default=b'''Subject: changeset published
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
    55
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
    56
This changeset has been published.
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
    57
''',
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
    58
)
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
    59
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
    60
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
    61
def _report_commit(ui, repo, ctx):
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
    62
    domain = ui.config(b'notify_published', b'domain') or ui.config(
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
    63
        b'notify', b'domain'
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
    64
    )
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
    65
    messageidseed = ui.config(
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
    66
        b'notify_published', b'messageidseed'
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
    67
    ) or ui.config(b'notify', b'messageidseed')
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
    68
    template = ui.config(b'notify_published', b'template')
45292
3c2fae87bd5a templatespec: use new factory functions in hooklib
Martin von Zweigbergk <martinvonz@google.com>
parents: 44440
diff changeset
    69
    spec = formatter.literal_templatespec(template)
44440
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
    70
    templater = logcmdutil.changesettemplater(ui, repo, spec)
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
    71
    ui.pushbuffer()
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
    72
    n = notify.notifier(ui, repo, b'incoming')
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
    73
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
    74
    subs = set()
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
    75
    for sub, spec in n.subs:
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
    76
        if spec is None:
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
    77
            subs.add(sub)
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
    78
            continue
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
    79
        revs = repo.revs(b'%r and %d:', spec, ctx.rev())
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
    80
        if len(revs):
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
    81
            subs.add(sub)
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
    82
            continue
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
    83
    if len(subs) == 0:
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
    84
        ui.debug(
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
    85
            b'notify_published: no subscribers to selected repo and revset\n'
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
    86
        )
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
    87
        return
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
    88
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
    89
    templater.show(
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
    90
        ctx,
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
    91
        changes=ctx.changeset(),
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
    92
        baseurl=ui.config(b'web', b'baseurl'),
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
    93
        root=repo.root,
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
    94
        webroot=n.root,
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
    95
    )
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
    96
    data = ui.popbuffer()
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
    97
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
    98
    try:
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
    99
        msg = mail.parsebytes(data)
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
   100
    except emailerrors.MessageParseError as inst:
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
   101
        raise error.Abort(inst)
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
   102
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
   103
    msg['In-reply-to'] = notify.messageid(ctx, domain, messageidseed)
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
   104
    msg['Message-Id'] = notify.messageid(
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
   105
        ctx, domain, messageidseed + b'-published'
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
   106
    )
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
   107
    msg['Date'] = encoding.strfromlocal(
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
   108
        dateutil.datestr(format=b"%a, %d %b %Y %H:%M:%S %1%2")
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
   109
    )
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
   110
    if not msg['From']:
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
   111
        sender = ui.config(b'email', b'from') or ui.username()
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
   112
        if b'@' not in sender or b'@localhost' in sender:
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
   113
            sender = n.fixmail(sender)
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
   114
        msg['From'] = mail.addressencode(ui, sender, n.charsets, n.test)
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
   115
    msg['To'] = ', '.join(sorted(subs))
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
   116
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
   117
    msgtext = msg.as_bytes() if pycompat.ispy3 else msg.as_string()
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
   118
    if ui.configbool(b'notify', b'test'):
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
   119
        ui.write(msgtext)
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
   120
        if not msgtext.endswith(b'\n'):
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
   121
            ui.write(b'\n')
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
   122
    else:
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
   123
        ui.status(_(b'notify_published: sending mail for %d\n') % ctx.rev())
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
   124
        mail.sendmail(
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
   125
            ui, emailutils.parseaddr(msg['From'])[1], subs, msgtext, mbox=n.mbox
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
   126
        )
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
   127
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
   128
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
   129
def hook(ui, repo, hooktype, node=None, **kwargs):
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
   130
    if hooktype != b"txnclose-phase":
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
   131
        raise error.Abort(
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
   132
            _(b'Unsupported hook type %r') % pycompat.bytestr(hooktype)
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
   133
        )
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
   134
    ctx = repo.unfiltered()[node]
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
   135
    if kwargs['oldphase'] == b'draft' and kwargs['phase'] == b'public':
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
   136
        _report_commit(ui, repo, ctx)