##// END OF EJS Templates
logtoprocess: rewrite dict building in py3-compatible way
Yuya Nishihara -
r40654:b2e5a554 default
parent child Browse files
Show More
@@ -1,89 +1,90 b''
1 1 # logtoprocess.py - send ui.log() data to a subprocess
2 2 #
3 3 # Copyright 2016 Facebook, Inc.
4 4 #
5 5 # This software may be used and distributed according to the terms of the
6 6 # GNU General Public License version 2 or any later version.
7 7 """send ui.log() data to a subprocess (EXPERIMENTAL)
8 8
9 9 This extension lets you specify a shell command per ui.log() event,
10 10 sending all remaining arguments to as environment variables to that command.
11 11
12 12 Each positional argument to the method results in a `MSG[N]` key in the
13 13 environment, starting at 1 (so `MSG1`, `MSG2`, etc.). Each keyword argument
14 14 is set as a `OPT_UPPERCASE_KEY` variable (so the key is uppercased, and
15 15 prefixed with `OPT_`). The original event name is passed in the `EVENT`
16 16 environment variable, and the process ID of mercurial is given in `HGPID`.
17 17
18 18 So given a call `ui.log('foo', 'bar', 'baz', spam='eggs'), a script configured
19 19 for the `foo` event can expect an environment with `MSG1=bar`, `MSG2=baz`, and
20 20 `OPT_SPAM=eggs`.
21 21
22 22 Scripts are configured in the `[logtoprocess]` section, each key an event name.
23 23 For example::
24 24
25 25 [logtoprocess]
26 26 commandexception = echo "$MSG2$MSG3" > /var/log/mercurial_exceptions.log
27 27
28 28 would log the warning message and traceback of any failed command dispatch.
29 29
30 30 Scripts are run asynchronously as detached daemon processes; mercurial will
31 31 not ensure that they exit cleanly.
32 32
33 33 """
34 34
35 35 from __future__ import absolute_import
36 36
37 import itertools
38 37 import os
39 38
39 from mercurial import (
40 pycompat,
41 )
40 42 from mercurial.utils import (
41 43 procutil,
42 44 )
43 45
44 46 # Note for extension authors: ONLY specify testedwith = 'ships-with-hg-core' for
45 47 # extensions which SHIP WITH MERCURIAL. Non-mainline extensions should
46 48 # be specifying the version(s) of Mercurial they are tested with, or
47 49 # leave the attribute unspecified.
48 50 testedwith = 'ships-with-hg-core'
49 51
50 52 def uisetup(ui):
51 53
52 54 class logtoprocessui(ui.__class__):
53 55 def log(self, event, *msg, **opts):
54 56 """Map log events to external commands
55 57
56 58 Arguments are passed on as environment variables.
57 59
58 60 """
59 61 script = self.config('logtoprocess', event)
60 62 if script:
61 63 if msg:
62 64 # try to format the log message given the remaining
63 65 # arguments
64 66 try:
65 67 # Format the message as blackbox does
66 68 formatted = msg[0] % msg[1:]
67 69 except (TypeError, KeyError):
68 70 # Failed to apply the arguments, ignore
69 71 formatted = msg[0]
70 72 messages = (formatted,) + msg[1:]
71 73 else:
72 74 messages = msg
75 env = {
76 b'EVENT': event,
77 b'HGPID': os.getpid(),
78 }
73 79 # positional arguments are listed as MSG[N] keys in the
74 80 # environment
75 msgpairs = (
76 ('MSG{0:d}'.format(i), m)
77 for i, m in enumerate(messages, 1))
81 env.update((b'MSG%d' % i, m) for i, m in enumerate(messages, 1))
78 82 # keyword arguments get prefixed with OPT_ and uppercased
79 optpairs = (
80 ('OPT_{0}'.format(key.upper()), value)
81 for key, value in opts.iteritems())
82 env = dict(itertools.chain(msgpairs, optpairs),
83 EVENT=event, HGPID=os.getpid())
83 env.update((b'OPT_%s' % key.upper(), value)
84 for key, value in pycompat.byteskwargs(opts).items())
84 85 fullenv = procutil.shellenviron(env)
85 86 procutil.runbgcommand(script, fullenv, shell=True)
86 87 return super(logtoprocessui, self).log(event, *msg, **opts)
87 88
88 89 # Replace the class for this instance and all clones created from it:
89 90 ui.__class__ = logtoprocessui
General Comments 0
You need to be logged in to leave comments. Login now