##// END OF EJS Templates
hooklib: update documentation of changeset_obsoletedfor for changed hook type...
Aay Jay Chan -
r45951:8b700e9b default
parent child Browse files
Show More
@@ -1,140 +1,140 b''
1 1 # Copyright 2020 Joerg Sonnenberger <joerg@bec.de>
2 2 #
3 3 # This software may be used and distributed according to the terms of the
4 4 # GNU General Public License version 2 or any later version.
5 5 """changeset_obsoleted is a hook to send a mail when an
6 6 existing draft changeset is obsoleted by an obsmarker without successor.
7 7
8 8 Correct message threading requires the same messageidseed to be used for both
9 9 the original notification and the new mail.
10 10
11 11 Usage:
12 12 [notify]
13 13 messageidseed = myseed
14 14
15 15 [hooks]
16 pretxnclose.changeset_obsoleted = \
16 txnclose.changeset_obsoleted = \
17 17 python:hgext.hooklib.changeset_obsoleted.hook
18 18 """
19 19
20 20 from __future__ import absolute_import
21 21
22 22 import email.errors as emailerrors
23 23 import email.utils as emailutils
24 24
25 25 from mercurial.i18n import _
26 26 from mercurial import (
27 27 encoding,
28 28 error,
29 29 formatter,
30 30 logcmdutil,
31 31 mail,
32 32 obsutil,
33 33 pycompat,
34 34 registrar,
35 35 )
36 36 from mercurial.utils import dateutil
37 37 from .. import notify
38 38
39 39 configtable = {}
40 40 configitem = registrar.configitem(configtable)
41 41
42 42 configitem(
43 43 b'notify_obsoleted', b'domain', default=None,
44 44 )
45 45 configitem(
46 46 b'notify_obsoleted', b'messageidseed', default=None,
47 47 )
48 48 configitem(
49 49 b'notify_obsoleted',
50 50 b'template',
51 51 default=b'''Subject: changeset abandoned
52 52
53 53 This changeset has been abandoned.
54 54 ''',
55 55 )
56 56
57 57
58 58 def _report_commit(ui, repo, ctx):
59 59 domain = ui.config(b'notify_obsoleted', b'domain') or ui.config(
60 60 b'notify', b'domain'
61 61 )
62 62 messageidseed = ui.config(
63 63 b'notify_obsoleted', b'messageidseed'
64 64 ) or ui.config(b'notify', b'messageidseed')
65 65 template = ui.config(b'notify_obsoleted', b'template')
66 66 spec = formatter.literal_templatespec(template)
67 67 templater = logcmdutil.changesettemplater(ui, repo, spec)
68 68 ui.pushbuffer()
69 69 n = notify.notifier(ui, repo, b'incoming')
70 70
71 71 subs = set()
72 72 for sub, spec in n.subs:
73 73 if spec is None:
74 74 subs.add(sub)
75 75 continue
76 76 revs = repo.revs(b'%r and %d:', spec, ctx.rev())
77 77 if len(revs):
78 78 subs.add(sub)
79 79 continue
80 80 if len(subs) == 0:
81 81 ui.debug(
82 82 b'notify_obsoleted: no subscribers to selected repo and revset\n'
83 83 )
84 84 return
85 85
86 86 templater.show(
87 87 ctx,
88 88 changes=ctx.changeset(),
89 89 baseurl=ui.config(b'web', b'baseurl'),
90 90 root=repo.root,
91 91 webroot=n.root,
92 92 )
93 93 data = ui.popbuffer()
94 94
95 95 try:
96 96 msg = mail.parsebytes(data)
97 97 except emailerrors.MessageParseError as inst:
98 98 raise error.Abort(inst)
99 99
100 100 msg['In-reply-to'] = notify.messageid(ctx, domain, messageidseed)
101 101 msg['Message-Id'] = notify.messageid(
102 102 ctx, domain, messageidseed + b'-obsoleted'
103 103 )
104 104 msg['Date'] = encoding.strfromlocal(
105 105 dateutil.datestr(format=b"%a, %d %b %Y %H:%M:%S %1%2")
106 106 )
107 107 if not msg['From']:
108 108 sender = ui.config(b'email', b'from') or ui.username()
109 109 if b'@' not in sender or b'@localhost' in sender:
110 110 sender = n.fixmail(sender)
111 111 msg['From'] = mail.addressencode(ui, sender, n.charsets, n.test)
112 112 msg['To'] = ', '.join(sorted(subs))
113 113
114 114 msgtext = msg.as_bytes() if pycompat.ispy3 else msg.as_string()
115 115 if ui.configbool(b'notify', b'test'):
116 116 ui.write(msgtext)
117 117 if not msgtext.endswith(b'\n'):
118 118 ui.write(b'\n')
119 119 else:
120 120 ui.status(_(b'notify_obsoleted: sending mail for %d\n') % ctx.rev())
121 121 mail.sendmail(
122 122 ui, emailutils.parseaddr(msg['From'])[1], subs, msgtext, mbox=n.mbox
123 123 )
124 124
125 125
126 126 def has_successor(repo, rev):
127 127 return any(
128 128 r for r in obsutil.allsuccessors(repo.obsstore, [rev]) if r != rev
129 129 )
130 130
131 131
132 132 def hook(ui, repo, hooktype, node=None, **kwargs):
133 133 if hooktype != b"txnclose":
134 134 raise error.Abort(
135 135 _(b'Unsupported hook type %r') % pycompat.bytestr(hooktype)
136 136 )
137 137 for rev in obsutil.getobsoleted(repo, changes=kwargs['changes']):
138 138 ctx = repo.unfiltered()[rev]
139 139 if not has_successor(repo, ctx.node()):
140 140 _report_commit(ui, repo, ctx)
General Comments 0
You need to be logged in to leave comments. Login now