File: run.py

package info (click to toggle)
git-ubuntu 1.1-2
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 1,688 kB
  • sloc: python: 13,378; sh: 480; makefile: 2
file content (144 lines) | stat: -rw-r--r-- 4,175 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
import functools
import logging
import os
import subprocess


def quoted_cmd(args):
    ret = []
    needs_single = '!$(`"\n'
    needs_double = " *&'"
    for arg in args:
        singles = [i for i in needs_single if i in arg]
        doubles = [i for i in needs_double if i in arg]
        if len(singles) + len(doubles) == 0:
            ret.append(arg)
            continue
        if len(singles):
           arg.replace("'", "'\\''")
           ret.append("'%s'" % arg)
        else:
           ret.append('"%s"' % arg)
    return ' '.join(ret)


def runq(*args, **kwargs):
    kwargs.update({
        'stdout': subprocess.DEVNULL,
        'stderr': subprocess.DEVNULL,
        'verbose_on_failure': False,
    })
    return run(*args, **kwargs)


def run(
    args,
    env=None,
    check=True,
    shell=False,
    input=None,
    stderr=subprocess.PIPE,
    stdout=subprocess.PIPE,
    stdin=subprocess.DEVNULL,
    verbose_on_failure=True,
    rcs=None,
    decode=True,
):
    rcs = rcs or []
    if shell:
        if isinstance(args, str):
            pcmd = quoted_cmd(["sh", '-c', args])
        else:
            pcmd = quoted_cmd(["sh", '-c'] + args)
    else:
        pcmd = quoted_cmd(args)

    try:
        logging.debug("Executing: %s", pcmd)
        if input:
            cp = subprocess.run(
                args, env=env, check=check, shell=shell,
                input=input,
                stdout=stdout, stderr=stderr)
        else:
            cp = subprocess.run(
                args, env=env, check=check, shell=shell,
                stdout=stdout, stderr=stderr, stdin=stdin)
        ret = cp
    except subprocess.CalledProcessError as e:
        not_captured = "[Not captured]\n"
        out = not_captured
        err = not_captured
        if stdout is subprocess.PIPE:
            out = e.stdout.decode(errors='replace')
        if stderr is subprocess.PIPE:
            err = e.stderr.decode(errors='replace')
        if e.returncode not in rcs:
            if verbose_on_failure:
                logging.error("Command exited %d: %s", e.returncode, pcmd)
                logging.error(
                    "stdout: %s",
                    out.replace("\n", "\n  "),
                )
                logging.error(
                    "stderr: %s",
                    err.replace("\n", "\n  "),
                )
            raise e
        ret = e
        pass

    if decode:
        return (
            decode_binary(ret.stdout),
            decode_binary(ret.stderr),
        )
    else:
        return (ret.stdout, ret.stderr)

def decode_binary(binary, verbose=True):
    try:
        return binary if binary is None else binary.decode('utf-8')
    except UnicodeDecodeError as e:
        if verbose:
            logging.warning("Failed to decode blob: %s", e)
            logging.warning("blob=%s", binary.decode(errors='replace'))
        return binary.decode('utf-8', errors='replace')

def run_quilt(args, env=None, **kwargs):
    """execute quilt without reading any configuration files

    Params:
    args: A list of string arguments to pass to quilt.
    env: A namespace object to use as the environment. If not specified,
    the calling environment is inherited.
    kwargs: passed directly to run().

    Returns:
    A tuple of stdout, stderr from the quilt process.
    Raises a subprocess.CalledProcessError exception on error.
    """
    cmd = ['quilt', '--quiltrc', '-'] + args
    return run(cmd, env=env, **kwargs)

def run_gbp(args, env=None, **kwargs):
    """execute gbp without reading any configuration files

    Params:
    args: A list of string arguments to pass to gbp.
    env: A namespace object to use as the environment. If not specified,
    the calling environment is inherited.
    kwargs: passed directly to run().

    Returns:
    A tuple of stdout, stderr from the gbp process.
    Raises a subprocess.CalledProcessError exception on error.
    """
    cmd = ['gbp'] + args
    if env:
        env_no_gbp_conf = env.copy()
    else:
        env_no_gbp_conf = os.environ.copy()
    env_no_gbp_conf['GBP_CONF_FILES'] = '/dev/null'

    return run(cmd, env=env_no_gbp_conf, **kwargs)