| Index: lib/cros_build_lib.py
|
| diff --git a/lib/cros_build_lib.py b/lib/cros_build_lib.py
|
| index f7ea5e9c332397e8b639f1e1407f13ed8efdc22c..46339f208d62014079e8045ac86e375d240a524b 100644
|
| --- a/lib/cros_build_lib.py
|
| +++ b/lib/cros_build_lib.py
|
| @@ -1,4 +1,4 @@
|
| -# Copyright (c) 2010 The Chromium OS Authors. All rights reserved.
|
| + # Copyright (c) 2011 The Chromium OS Authors. All rights reserved.
|
| # Use of this source code is governed by a BSD-style license that can be
|
| # found in the LICENSE file.
|
|
|
| @@ -43,11 +43,14 @@ class RunCommandError(Exception):
|
| def RunCommand(cmd, print_cmd=True, error_ok=False, error_message=None,
|
| exit_code=False, redirect_stdout=False, redirect_stderr=False,
|
| cwd=None, input=None, enter_chroot=False, shell=False,
|
| - env=None, ignore_sigint=False, combine_stdout_stderr=False):
|
| + env=None, extra_env=None, ignore_sigint=False,
|
| + combine_stdout_stderr=False):
|
| """Runs a command.
|
|
|
| Args:
|
| - cmd: cmd to run. Should be input to subprocess.Popen.
|
| + cmd: cmd to run. Should be input to subprocess.Popen. If a string, shell
|
| + must be true. Otherwise the command must be an array of arguments, and
|
| + shell must be false.
|
| print_cmd: prints the command before running it.
|
| error_ok: does not raise an exception on error.
|
| error_message: prints out this message when an error occurrs.
|
| @@ -58,9 +61,15 @@ def RunCommand(cmd, print_cmd=True, error_ok=False, error_message=None,
|
| input: input to pipe into this command through stdin.
|
| enter_chroot: this command should be run from within the chroot. If set,
|
| cwd must point to the scripts directory.
|
| - shell: If shell is True, the specified command will be executed through
|
| - the shell.
|
| - env: If non-None, this is the environment for the new process.
|
| + shell: Controls whether we add a shell as a command interpreter. See cmd
|
| + since it has to agree as to the type.
|
| + env: If non-None, this is the environment for the new process. If
|
| + enter_chroot is true then this is the environment of the enter_chroot,
|
| + most of which gets removed from the cmd run.
|
| + extra_env: If set, this is added to the environment for the new process.
|
| + In enter_chroot=True case, these are specified on the post-entry
|
| + side, and so are often more useful. This dictionary is not used to
|
| + clear any entries though.
|
| ignore_sigint: If True, we'll ignore signal.SIGINT before calling the
|
| child. This is the desired behavior if we know our child will handle
|
| Ctrl-C. If we don't do this, I think we and the child will both get
|
| @@ -86,24 +95,41 @@ def RunCommand(cmd, print_cmd=True, error_ok=False, error_message=None,
|
| # TODO(sosa): gpylint complains about redefining built-in 'input'.
|
| # Can we rename this variable?
|
| if input: stdin = subprocess.PIPE
|
| +
|
| if isinstance(cmd, basestring):
|
| - if enter_chroot: cmd = './enter_chroot.sh -- ' + cmd
|
| - cmd_str = cmd
|
| - else:
|
| - if enter_chroot: cmd = ['./enter_chroot.sh', '--'] + cmd
|
| - cmd_str = ' '.join(cmd)
|
| + if not shell:
|
| + raise Exception('Cannot run a string command without a shell')
|
| + cmd = ['/bin/sh', '-c', cmd]
|
| + shell = False
|
| + elif shell:
|
| + raise Exception('Cannot run an array command with a shell')
|
| +
|
| + # If we are using enter_chroot we need to use enterchroot pass env through
|
| + # to the final command.
|
| + if enter_chroot:
|
| + cmd = ['./enter_chroot.sh', '--'] + cmd
|
| + if extra_env:
|
| + for (key, value) in extra_env.items():
|
| + cmd.insert(1, '%s=%s' % (key, value))
|
| + elif extra_env:
|
| + if env is not None:
|
| + env = env.copy()
|
| + else:
|
| + env = os.environ.copy()
|
| +
|
| + env.update(extra_env)
|
|
|
| # Print out the command before running.
|
| if print_cmd:
|
| if cwd:
|
| - Info('RunCommand: %s in %s' % (cmd_str, cwd))
|
| + Info('RunCommand: %r in %s' % (cmd, cwd))
|
| else:
|
| - Info('RunCommand: %s' % cmd_str)
|
| + Info('RunCommand: %r' % cmd)
|
| cmd_result.cmd = cmd
|
|
|
| try:
|
| proc = subprocess.Popen(cmd, cwd=cwd, stdin=stdin, stdout=stdout,
|
| - stderr=stderr, shell=shell, env=env)
|
| + stderr=stderr, shell=False, env=env)
|
| if ignore_sigint:
|
| old_sigint = signal.signal(signal.SIGINT, signal.SIG_IGN)
|
| try:
|
| @@ -116,7 +142,7 @@ def RunCommand(cmd, print_cmd=True, error_ok=False, error_message=None,
|
| cmd_result.returncode = proc.returncode
|
|
|
| if not error_ok and proc.returncode:
|
| - msg = ('Command "%s" failed.\n' % cmd_str +
|
| + msg = ('Command "%r" failed.\n' % cmd +
|
| (error_message or cmd_result.error or cmd_result.output or ''))
|
| raise RunCommandError(msg, cmd)
|
| # TODO(sosa): is it possible not to use the catch-all Exception here?
|
|
|