annotate hgext/hooklib/changeset_published.py @ 45613:ddcee0b0fd67

changing-files: add a utility to compute the merged files post-commit We will need it in `_getsidedata` as soon as we start persisting that set. Differential Revision: https://phab.mercurial-scm.org/D9089
author Pierre-Yves David <pierre-yves.david@octobus.net>
date Fri, 25 Sep 2020 11:29:19 +0200
parents 3c2fae87bd5a
children 89a2afe31e82
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
44413
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,
45268
3c2fae87bd5a templatespec: use new factory functions in hooklib
Martin von Zweigbergk <martinvonz@google.com>
parents: 44413
diff changeset
29 formatter,
44413
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(
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
42 b'notify_published', b'domain', default=None,
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
43 )
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
44 configitem(
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
45 b'notify_published', b'messageidseed', default=None,
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
46 )
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
47 configitem(
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
48 b'notify_published',
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
49 b'template',
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
50 default=b'''Subject: changeset published
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
51
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
52 This changeset has been published.
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
53 ''',
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
54 )
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
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
57 def _report_commit(ui, repo, ctx):
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
58 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
59 b'notify', b'domain'
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 messageidseed = ui.config(
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
62 b'notify_published', b'messageidseed'
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
63 ) or ui.config(b'notify', b'messageidseed')
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
64 template = ui.config(b'notify_published', b'template')
45268
3c2fae87bd5a templatespec: use new factory functions in hooklib
Martin von Zweigbergk <martinvonz@google.com>
parents: 44413
diff changeset
65 spec = formatter.literal_templatespec(template)
44413
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
66 templater = logcmdutil.changesettemplater(ui, repo, spec)
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
67 ui.pushbuffer()
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
68 n = notify.notifier(ui, repo, b'incoming')
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
69
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
70 subs = set()
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
71 for sub, spec in n.subs:
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
72 if spec is None:
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
73 subs.add(sub)
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
74 continue
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
75 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
76 if len(revs):
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 if len(subs) == 0:
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
80 ui.debug(
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
81 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
82 )
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
83 return
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
84
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
85 templater.show(
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
86 ctx,
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
87 changes=ctx.changeset(),
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
88 baseurl=ui.config(b'web', b'baseurl'),
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
89 root=repo.root,
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
90 webroot=n.root,
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
91 )
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
92 data = ui.popbuffer()
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
93
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
94 try:
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
95 msg = mail.parsebytes(data)
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
96 except emailerrors.MessageParseError as inst:
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
97 raise error.Abort(inst)
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
98
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
99 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
100 msg['Message-Id'] = notify.messageid(
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
101 ctx, domain, messageidseed + b'-published'
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['Date'] = encoding.strfromlocal(
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
104 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
105 )
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
106 if not msg['From']:
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
107 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
108 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
109 sender = n.fixmail(sender)
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
110 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
111 msg['To'] = ', '.join(sorted(subs))
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
112
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
113 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
114 if ui.configbool(b'notify', b'test'):
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
115 ui.write(msgtext)
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
116 if not msgtext.endswith(b'\n'):
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
117 ui.write(b'\n')
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
118 else:
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
119 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
120 mail.sendmail(
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
121 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
122 )
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
123
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
124
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
125 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
126 if hooktype != b"txnclose-phase":
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
127 raise error.Abort(
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
128 _(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
129 )
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
130 ctx = repo.unfiltered()[node]
4cabeea6d214 hgext: start building a library for simple hooks
Joerg Sonnenberger <joerg@bec.de>
parents:
diff changeset
131 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
132 _report_commit(ui, repo, ctx)