Mercurial > hg
comparison hgext/logtoprocess.py @ 40622:d2c997b8001f
logtoprocess: drop support for ui.log() call with invalid msg arguments (BC)
Before, the logtoprocess extension put a formatted message into $MSG1, and
its arguments to $MSG2... If the specified arguments couldn't be formatted
because of a caller bug, an unformatted message was passed in to $MSG1
instead of exploding. This behavior doesn't make sense.
Since I'm planning to formalize the ui.log() interface such that we'll no
longer have to extend the ui class, I want to remove any features not
conforming to the ui.log() API. So this patch removes the support for
ill-formed arguments, and $MSG{n} (where n > 1) parameters which seems
useless as long as the message can be formatted. The $MSG1 variable isn't
renamed for the maximum compatibility.
In future patches, a formatted msg will be passed to a processlogger object,
instead of overriding the ui.log() function.
.. bc::
The logtoprocess extension no longer supports invalid ``ui.log()``
arguments. A log message is always formatted and passed in to the
``$MSG1`` environment variable.
author | Yuya Nishihara <yuya@tcha.org> |
---|---|
date | Sun, 11 Nov 2018 12:55:58 +0900 |
parents | b2e5a554bc7b |
children | 2b859742ea15 |
comparison
equal
deleted
inserted
replaced
40621:175b590b1f51 | 40622:d2c997b8001f |
---|---|
7 """send ui.log() data to a subprocess (EXPERIMENTAL) | 7 """send ui.log() data to a subprocess (EXPERIMENTAL) |
8 | 8 |
9 This extension lets you specify a shell command per ui.log() event, | 9 This extension lets you specify a shell command per ui.log() event, |
10 sending all remaining arguments to as environment variables to that command. | 10 sending all remaining arguments to as environment variables to that command. |
11 | 11 |
12 Each positional argument to the method results in a `MSG[N]` key in the | 12 Positional arguments construct a log message, which is passed in the `MSG1` |
13 environment, starting at 1 (so `MSG1`, `MSG2`, etc.). Each keyword argument | 13 environment variables. Each keyword argument is set as a `OPT_UPPERCASE_KEY` |
14 is set as a `OPT_UPPERCASE_KEY` variable (so the key is uppercased, and | 14 variable (so the key is uppercased, and prefixed with `OPT_`). The original |
15 prefixed with `OPT_`). The original event name is passed in the `EVENT` | 15 event name is passed in the `EVENT` environment variable, and the process ID |
16 environment variable, and the process ID of mercurial is given in `HGPID`. | 16 of mercurial is given in `HGPID`. |
17 | 17 |
18 So given a call `ui.log('foo', 'bar', 'baz', spam='eggs'), a script configured | 18 So given a call `ui.log('foo', 'bar %s\n', 'baz', spam='eggs'), a script |
19 for the `foo` event can expect an environment with `MSG1=bar`, `MSG2=baz`, and | 19 configured for the `foo` event can expect an environment with `MSG1=bar baz`, |
20 `OPT_SPAM=eggs`. | 20 and `OPT_SPAM=eggs`. |
21 | 21 |
22 Scripts are configured in the `[logtoprocess]` section, each key an event name. | 22 Scripts are configured in the `[logtoprocess]` section, each key an event name. |
23 For example:: | 23 For example:: |
24 | 24 |
25 [logtoprocess] | 25 [logtoprocess] |
26 commandexception = echo "$MSG2$MSG3" > /var/log/mercurial_exceptions.log | 26 commandexception = echo "$MSG1" > /var/log/mercurial_exceptions.log |
27 | 27 |
28 would log the warning message and traceback of any failed command dispatch. | 28 would log the warning message and traceback of any failed command dispatch. |
29 | 29 |
30 Scripts are run asynchronously as detached daemon processes; mercurial will | 30 Scripts are run asynchronously as detached daemon processes; mercurial will |
31 not ensure that they exit cleanly. | 31 not ensure that they exit cleanly. |
58 Arguments are passed on as environment variables. | 58 Arguments are passed on as environment variables. |
59 | 59 |
60 """ | 60 """ |
61 script = self.config('logtoprocess', event) | 61 script = self.config('logtoprocess', event) |
62 if script: | 62 if script: |
63 if msg: | |
64 # try to format the log message given the remaining | |
65 # arguments | |
66 try: | |
67 # Format the message as blackbox does | |
68 formatted = msg[0] % msg[1:] | |
69 except (TypeError, KeyError): | |
70 # Failed to apply the arguments, ignore | |
71 formatted = msg[0] | |
72 messages = (formatted,) + msg[1:] | |
73 else: | |
74 messages = msg | |
75 env = { | 63 env = { |
76 b'EVENT': event, | 64 b'EVENT': event, |
77 b'HGPID': os.getpid(), | 65 b'HGPID': os.getpid(), |
66 b'MSG1': msg[0] % msg[1:], | |
78 } | 67 } |
79 # positional arguments are listed as MSG[N] keys in the | |
80 # environment | |
81 env.update((b'MSG%d' % i, m) for i, m in enumerate(messages, 1)) | |
82 # keyword arguments get prefixed with OPT_ and uppercased | 68 # keyword arguments get prefixed with OPT_ and uppercased |
83 env.update((b'OPT_%s' % key.upper(), value) | 69 env.update((b'OPT_%s' % key.upper(), value) |
84 for key, value in pycompat.byteskwargs(opts).items()) | 70 for key, value in pycompat.byteskwargs(opts).items()) |
85 fullenv = procutil.shellenviron(env) | 71 fullenv = procutil.shellenviron(env) |
86 procutil.runbgcommand(script, fullenv, shell=True) | 72 procutil.runbgcommand(script, fullenv, shell=True) |