hgext/logtoprocess.py
author Gregory Szorc <gregory.szorc@gmail.com>
Sat, 26 Jan 2019 10:00:17 -0800
changeset 41425 e82288a9556c
parent 40795 691c68bc1222
child 43076 2372284d9457
permissions -rw-r--r--
wireprotov2server: use our JSON encoder Python's json module doesn't like to encode bytes instances. This makes this code difficult to work with Python 3. We simply swap in Mercurial's JSON encoder to work around it. Differential Revision: https://phab.mercurial-scm.org/D5712
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
28901
a368da441b32 logtoprocess: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
     1
# logtoprocess.py - send ui.log() data to a subprocess
a368da441b32 logtoprocess: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
     2
#
a368da441b32 logtoprocess: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
     3
# Copyright 2016 Facebook, Inc.
a368da441b32 logtoprocess: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
     4
#
a368da441b32 logtoprocess: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
     5
# This software may be used and distributed according to the terms of the
a368da441b32 logtoprocess: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
     6
# GNU General Public License version 2 or any later version.
31606
8e7feaad2d8d logtoprocess: use lowercase for docstring title
Jun Wu <quark@fb.com>
parents: 30643
diff changeset
     7
"""send ui.log() data to a subprocess (EXPERIMENTAL)
28901
a368da441b32 logtoprocess: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
     8
a368da441b32 logtoprocess: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
     9
This extension lets you specify a shell command per ui.log() event,
a368da441b32 logtoprocess: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    10
sending all remaining arguments to as environment variables to that command.
a368da441b32 logtoprocess: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    11
40666
d2c997b8001f logtoprocess: drop support for ui.log() call with invalid msg arguments (BC)
Yuya Nishihara <yuya@tcha.org>
parents: 40664
diff changeset
    12
Positional arguments construct a log message, which is passed in the `MSG1`
d2c997b8001f logtoprocess: drop support for ui.log() call with invalid msg arguments (BC)
Yuya Nishihara <yuya@tcha.org>
parents: 40664
diff changeset
    13
environment variables. Each keyword argument is set as a `OPT_UPPERCASE_KEY`
d2c997b8001f logtoprocess: drop support for ui.log() call with invalid msg arguments (BC)
Yuya Nishihara <yuya@tcha.org>
parents: 40664
diff changeset
    14
variable (so the key is uppercased, and prefixed with `OPT_`). The original
d2c997b8001f logtoprocess: drop support for ui.log() call with invalid msg arguments (BC)
Yuya Nishihara <yuya@tcha.org>
parents: 40664
diff changeset
    15
event name is passed in the `EVENT` environment variable, and the process ID
d2c997b8001f logtoprocess: drop support for ui.log() call with invalid msg arguments (BC)
Yuya Nishihara <yuya@tcha.org>
parents: 40664
diff changeset
    16
of mercurial is given in `HGPID`.
28901
a368da441b32 logtoprocess: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    17
40666
d2c997b8001f logtoprocess: drop support for ui.log() call with invalid msg arguments (BC)
Yuya Nishihara <yuya@tcha.org>
parents: 40664
diff changeset
    18
So given a call `ui.log('foo', 'bar %s\n', 'baz', spam='eggs'), a script
d2c997b8001f logtoprocess: drop support for ui.log() call with invalid msg arguments (BC)
Yuya Nishihara <yuya@tcha.org>
parents: 40664
diff changeset
    19
configured for the `foo` event can expect an environment with `MSG1=bar baz`,
d2c997b8001f logtoprocess: drop support for ui.log() call with invalid msg arguments (BC)
Yuya Nishihara <yuya@tcha.org>
parents: 40664
diff changeset
    20
and `OPT_SPAM=eggs`.
28901
a368da441b32 logtoprocess: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    21
a368da441b32 logtoprocess: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    22
Scripts are configured in the `[logtoprocess]` section, each key an event name.
a368da441b32 logtoprocess: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    23
For example::
a368da441b32 logtoprocess: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    24
a368da441b32 logtoprocess: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    25
  [logtoprocess]
40666
d2c997b8001f logtoprocess: drop support for ui.log() call with invalid msg arguments (BC)
Yuya Nishihara <yuya@tcha.org>
parents: 40664
diff changeset
    26
  commandexception = echo "$MSG1" > /var/log/mercurial_exceptions.log
28901
a368da441b32 logtoprocess: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    27
a368da441b32 logtoprocess: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    28
would log the warning message and traceback of any failed command dispatch.
a368da441b32 logtoprocess: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    29
30342
318a24b52eeb spelling: fixes of non-dictionary words
Mads Kiilerich <madski@unity3d.com>
parents: 29852
diff changeset
    30
Scripts are run asynchronously as detached daemon processes; mercurial will
28901
a368da441b32 logtoprocess: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    31
not ensure that they exit cleanly.
a368da441b32 logtoprocess: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    32
a368da441b32 logtoprocess: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    33
"""
a368da441b32 logtoprocess: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    34
a368da441b32 logtoprocess: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    35
from __future__ import absolute_import
a368da441b32 logtoprocess: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    36
a368da441b32 logtoprocess: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    37
import os
30643
1c5cbf28f007 py3: replace os.environ with encoding.environ (part 5 of 5)
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30342
diff changeset
    38
39831
c31ce080eb75 py3: convert arguments, cwd and env to native strings when spawning subprocess
Matt Harbison <matt_harbison@yahoo.com>
parents: 35086
diff changeset
    39
from mercurial.utils import (
c31ce080eb75 py3: convert arguments, cwd and env to native strings when spawning subprocess
Matt Harbison <matt_harbison@yahoo.com>
parents: 35086
diff changeset
    40
    procutil,
c31ce080eb75 py3: convert arguments, cwd and env to native strings when spawning subprocess
Matt Harbison <matt_harbison@yahoo.com>
parents: 35086
diff changeset
    41
)
c31ce080eb75 py3: convert arguments, cwd and env to native strings when spawning subprocess
Matt Harbison <matt_harbison@yahoo.com>
parents: 35086
diff changeset
    42
29852
d5883fd055c6 extensions: change magic "shipped with hg" string
Augie Fackler <augie@google.com>
parents: 29463
diff changeset
    43
# Note for extension authors: ONLY specify testedwith = 'ships-with-hg-core' for
28901
a368da441b32 logtoprocess: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    44
# extensions which SHIP WITH MERCURIAL. Non-mainline extensions should
a368da441b32 logtoprocess: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    45
# be specifying the version(s) of Mercurial they are tested with, or
a368da441b32 logtoprocess: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    46
# leave the attribute unspecified.
29852
d5883fd055c6 extensions: change magic "shipped with hg" string
Augie Fackler <augie@google.com>
parents: 29463
diff changeset
    47
testedwith = 'ships-with-hg-core'
28901
a368da441b32 logtoprocess: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    48
40716
2b859742ea15 logtoprocess: extract logger class from ui wrapper
Yuya Nishihara <yuya@tcha.org>
parents: 40666
diff changeset
    49
class processlogger(object):
2b859742ea15 logtoprocess: extract logger class from ui wrapper
Yuya Nishihara <yuya@tcha.org>
parents: 40666
diff changeset
    50
    """Map log events to external commands
2b859742ea15 logtoprocess: extract logger class from ui wrapper
Yuya Nishihara <yuya@tcha.org>
parents: 40666
diff changeset
    51
2b859742ea15 logtoprocess: extract logger class from ui wrapper
Yuya Nishihara <yuya@tcha.org>
parents: 40666
diff changeset
    52
    Arguments are passed on as environment variables.
2b859742ea15 logtoprocess: extract logger class from ui wrapper
Yuya Nishihara <yuya@tcha.org>
parents: 40666
diff changeset
    53
    """
2b859742ea15 logtoprocess: extract logger class from ui wrapper
Yuya Nishihara <yuya@tcha.org>
parents: 40666
diff changeset
    54
2b859742ea15 logtoprocess: extract logger class from ui wrapper
Yuya Nishihara <yuya@tcha.org>
parents: 40666
diff changeset
    55
    def __init__(self, ui):
2b859742ea15 logtoprocess: extract logger class from ui wrapper
Yuya Nishihara <yuya@tcha.org>
parents: 40666
diff changeset
    56
        self._scripts = dict(ui.configitems(b'logtoprocess'))
2b859742ea15 logtoprocess: extract logger class from ui wrapper
Yuya Nishihara <yuya@tcha.org>
parents: 40666
diff changeset
    57
2b859742ea15 logtoprocess: extract logger class from ui wrapper
Yuya Nishihara <yuya@tcha.org>
parents: 40666
diff changeset
    58
    def tracked(self, event):
2b859742ea15 logtoprocess: extract logger class from ui wrapper
Yuya Nishihara <yuya@tcha.org>
parents: 40666
diff changeset
    59
        return bool(self._scripts.get(event))
2b859742ea15 logtoprocess: extract logger class from ui wrapper
Yuya Nishihara <yuya@tcha.org>
parents: 40666
diff changeset
    60
2b859742ea15 logtoprocess: extract logger class from ui wrapper
Yuya Nishihara <yuya@tcha.org>
parents: 40666
diff changeset
    61
    def log(self, ui, event, msg, opts):
40764
55b053af7196 ui: manage logger instances and event filtering by core ui
Yuya Nishihara <yuya@tcha.org>
parents: 40716
diff changeset
    62
        script = self._scripts[event]
40716
2b859742ea15 logtoprocess: extract logger class from ui wrapper
Yuya Nishihara <yuya@tcha.org>
parents: 40666
diff changeset
    63
        env = {
2b859742ea15 logtoprocess: extract logger class from ui wrapper
Yuya Nishihara <yuya@tcha.org>
parents: 40666
diff changeset
    64
            b'EVENT': event,
2b859742ea15 logtoprocess: extract logger class from ui wrapper
Yuya Nishihara <yuya@tcha.org>
parents: 40666
diff changeset
    65
            b'HGPID': os.getpid(),
40794
ffd574c144d2 ui: pass in formatted message to logger.log()
Yuya Nishihara <yuya@tcha.org>
parents: 40764
diff changeset
    66
            b'MSG1': msg,
40716
2b859742ea15 logtoprocess: extract logger class from ui wrapper
Yuya Nishihara <yuya@tcha.org>
parents: 40666
diff changeset
    67
        }
2b859742ea15 logtoprocess: extract logger class from ui wrapper
Yuya Nishihara <yuya@tcha.org>
parents: 40666
diff changeset
    68
        # keyword arguments get prefixed with OPT_ and uppercased
2b859742ea15 logtoprocess: extract logger class from ui wrapper
Yuya Nishihara <yuya@tcha.org>
parents: 40666
diff changeset
    69
        env.update((b'OPT_%s' % key.upper(), value)
40795
691c68bc1222 ui: pass in bytes opts dict to logger.log()
Yuya Nishihara <yuya@tcha.org>
parents: 40794
diff changeset
    70
                   for key, value in opts.items())
40716
2b859742ea15 logtoprocess: extract logger class from ui wrapper
Yuya Nishihara <yuya@tcha.org>
parents: 40666
diff changeset
    71
        fullenv = procutil.shellenviron(env)
2b859742ea15 logtoprocess: extract logger class from ui wrapper
Yuya Nishihara <yuya@tcha.org>
parents: 40666
diff changeset
    72
        procutil.runbgcommand(script, fullenv, shell=True)
2b859742ea15 logtoprocess: extract logger class from ui wrapper
Yuya Nishihara <yuya@tcha.org>
parents: 40666
diff changeset
    73
40764
55b053af7196 ui: manage logger instances and event filtering by core ui
Yuya Nishihara <yuya@tcha.org>
parents: 40716
diff changeset
    74
def uipopulate(ui):
55b053af7196 ui: manage logger instances and event filtering by core ui
Yuya Nishihara <yuya@tcha.org>
parents: 40716
diff changeset
    75
    ui.setlogger(b'logtoprocess', processlogger(ui))