##// END OF EJS Templates
templatespec: use new factory functions in hooklib...
Martin von Zweigbergk -
r45828:3c2fae87 default
parent child Browse files
Show More
@@ -1,139 +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 16 pretxnclose.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 formatter,
29 30 logcmdutil,
30 31 mail,
31 32 obsutil,
32 33 pycompat,
33 34 registrar,
34 35 )
35 36 from mercurial.utils import dateutil
36 37 from .. import notify
37 38
38 39 configtable = {}
39 40 configitem = registrar.configitem(configtable)
40 41
41 42 configitem(
42 43 b'notify_obsoleted', b'domain', default=None,
43 44 )
44 45 configitem(
45 46 b'notify_obsoleted', b'messageidseed', default=None,
46 47 )
47 48 configitem(
48 49 b'notify_obsoleted',
49 50 b'template',
50 51 default=b'''Subject: changeset abandoned
51 52
52 53 This changeset has been abandoned.
53 54 ''',
54 55 )
55 56
56 57
57 58 def _report_commit(ui, repo, ctx):
58 59 domain = ui.config(b'notify_obsoleted', b'domain') or ui.config(
59 60 b'notify', b'domain'
60 61 )
61 62 messageidseed = ui.config(
62 63 b'notify_obsoleted', b'messageidseed'
63 64 ) or ui.config(b'notify', b'messageidseed')
64 65 template = ui.config(b'notify_obsoleted', b'template')
65 spec = logcmdutil.templatespec(template, None)
66 spec = formatter.literal_templatespec(template)
66 67 templater = logcmdutil.changesettemplater(ui, repo, spec)
67 68 ui.pushbuffer()
68 69 n = notify.notifier(ui, repo, b'incoming')
69 70
70 71 subs = set()
71 72 for sub, spec in n.subs:
72 73 if spec is None:
73 74 subs.add(sub)
74 75 continue
75 76 revs = repo.revs(b'%r and %d:', spec, ctx.rev())
76 77 if len(revs):
77 78 subs.add(sub)
78 79 continue
79 80 if len(subs) == 0:
80 81 ui.debug(
81 82 b'notify_obsoleted: no subscribers to selected repo and revset\n'
82 83 )
83 84 return
84 85
85 86 templater.show(
86 87 ctx,
87 88 changes=ctx.changeset(),
88 89 baseurl=ui.config(b'web', b'baseurl'),
89 90 root=repo.root,
90 91 webroot=n.root,
91 92 )
92 93 data = ui.popbuffer()
93 94
94 95 try:
95 96 msg = mail.parsebytes(data)
96 97 except emailerrors.MessageParseError as inst:
97 98 raise error.Abort(inst)
98 99
99 100 msg['In-reply-to'] = notify.messageid(ctx, domain, messageidseed)
100 101 msg['Message-Id'] = notify.messageid(
101 102 ctx, domain, messageidseed + b'-obsoleted'
102 103 )
103 104 msg['Date'] = encoding.strfromlocal(
104 105 dateutil.datestr(format=b"%a, %d %b %Y %H:%M:%S %1%2")
105 106 )
106 107 if not msg['From']:
107 108 sender = ui.config(b'email', b'from') or ui.username()
108 109 if b'@' not in sender or b'@localhost' in sender:
109 110 sender = n.fixmail(sender)
110 111 msg['From'] = mail.addressencode(ui, sender, n.charsets, n.test)
111 112 msg['To'] = ', '.join(sorted(subs))
112 113
113 114 msgtext = msg.as_bytes() if pycompat.ispy3 else msg.as_string()
114 115 if ui.configbool(b'notify', b'test'):
115 116 ui.write(msgtext)
116 117 if not msgtext.endswith(b'\n'):
117 118 ui.write(b'\n')
118 119 else:
119 120 ui.status(_(b'notify_obsoleted: sending mail for %d\n') % ctx.rev())
120 121 mail.sendmail(
121 122 ui, emailutils.parseaddr(msg['From'])[1], subs, msgtext, mbox=n.mbox
122 123 )
123 124
124 125
125 126 def has_successor(repo, rev):
126 127 return any(
127 128 r for r in obsutil.allsuccessors(repo.obsstore, [rev]) if r != rev
128 129 )
129 130
130 131
131 132 def hook(ui, repo, hooktype, node=None, **kwargs):
132 133 if hooktype != b"txnclose":
133 134 raise error.Abort(
134 135 _(b'Unsupported hook type %r') % pycompat.bytestr(hooktype)
135 136 )
136 137 for rev in obsutil.getobsoleted(repo, changes=kwargs['changes']):
137 138 ctx = repo.unfiltered()[rev]
138 139 if not has_successor(repo, ctx.node()):
139 140 _report_commit(ui, repo, ctx)
@@ -1,131 +1,132 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_published is a hook to send a mail when an
6 6 existing draft changeset is moved to the public phase.
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 16 txnclose-phase.changeset_published = \
17 17 python:hgext.hooklib.changeset_published.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 formatter,
29 30 logcmdutil,
30 31 mail,
31 32 pycompat,
32 33 registrar,
33 34 )
34 35 from mercurial.utils import dateutil
35 36 from .. import notify
36 37
37 38 configtable = {}
38 39 configitem = registrar.configitem(configtable)
39 40
40 41 configitem(
41 42 b'notify_published', b'domain', default=None,
42 43 )
43 44 configitem(
44 45 b'notify_published', b'messageidseed', default=None,
45 46 )
46 47 configitem(
47 48 b'notify_published',
48 49 b'template',
49 50 default=b'''Subject: changeset published
50 51
51 52 This changeset has been published.
52 53 ''',
53 54 )
54 55
55 56
56 57 def _report_commit(ui, repo, ctx):
57 58 domain = ui.config(b'notify_published', b'domain') or ui.config(
58 59 b'notify', b'domain'
59 60 )
60 61 messageidseed = ui.config(
61 62 b'notify_published', b'messageidseed'
62 63 ) or ui.config(b'notify', b'messageidseed')
63 64 template = ui.config(b'notify_published', b'template')
64 spec = logcmdutil.templatespec(template, None)
65 spec = formatter.literal_templatespec(template)
65 66 templater = logcmdutil.changesettemplater(ui, repo, spec)
66 67 ui.pushbuffer()
67 68 n = notify.notifier(ui, repo, b'incoming')
68 69
69 70 subs = set()
70 71 for sub, spec in n.subs:
71 72 if spec is None:
72 73 subs.add(sub)
73 74 continue
74 75 revs = repo.revs(b'%r and %d:', spec, ctx.rev())
75 76 if len(revs):
76 77 subs.add(sub)
77 78 continue
78 79 if len(subs) == 0:
79 80 ui.debug(
80 81 b'notify_published: no subscribers to selected repo and revset\n'
81 82 )
82 83 return
83 84
84 85 templater.show(
85 86 ctx,
86 87 changes=ctx.changeset(),
87 88 baseurl=ui.config(b'web', b'baseurl'),
88 89 root=repo.root,
89 90 webroot=n.root,
90 91 )
91 92 data = ui.popbuffer()
92 93
93 94 try:
94 95 msg = mail.parsebytes(data)
95 96 except emailerrors.MessageParseError as inst:
96 97 raise error.Abort(inst)
97 98
98 99 msg['In-reply-to'] = notify.messageid(ctx, domain, messageidseed)
99 100 msg['Message-Id'] = notify.messageid(
100 101 ctx, domain, messageidseed + b'-published'
101 102 )
102 103 msg['Date'] = encoding.strfromlocal(
103 104 dateutil.datestr(format=b"%a, %d %b %Y %H:%M:%S %1%2")
104 105 )
105 106 if not msg['From']:
106 107 sender = ui.config(b'email', b'from') or ui.username()
107 108 if b'@' not in sender or b'@localhost' in sender:
108 109 sender = n.fixmail(sender)
109 110 msg['From'] = mail.addressencode(ui, sender, n.charsets, n.test)
110 111 msg['To'] = ', '.join(sorted(subs))
111 112
112 113 msgtext = msg.as_bytes() if pycompat.ispy3 else msg.as_string()
113 114 if ui.configbool(b'notify', b'test'):
114 115 ui.write(msgtext)
115 116 if not msgtext.endswith(b'\n'):
116 117 ui.write(b'\n')
117 118 else:
118 119 ui.status(_(b'notify_published: sending mail for %d\n') % ctx.rev())
119 120 mail.sendmail(
120 121 ui, emailutils.parseaddr(msg['From'])[1], subs, msgtext, mbox=n.mbox
121 122 )
122 123
123 124
124 125 def hook(ui, repo, hooktype, node=None, **kwargs):
125 126 if hooktype != b"txnclose-phase":
126 127 raise error.Abort(
127 128 _(b'Unsupported hook type %r') % pycompat.bytestr(hooktype)
128 129 )
129 130 ctx = repo.unfiltered()[node]
130 131 if kwargs['oldphase'] == b'draft' and kwargs['phase'] == b'public':
131 132 _report_commit(ui, repo, ctx)
General Comments 0
You need to be logged in to leave comments. Login now