OLD | NEW |
1 # Copyright (c) 2010 The Chromium OS Authors. All rights reserved. | 1 # Copyright (c) 2010 The Chromium OS Authors. All rights reserved. |
2 # Use of this source code is governed by a BSD-style license that can be | 2 # Use of this source code is governed by a BSD-style license that can be |
3 # found in the LICENSE file. | 3 # found in the LICENSE file. |
4 | 4 |
5 """Common python commands used by various build scripts.""" | 5 """Common python commands used by various build scripts.""" |
6 | 6 |
7 import inspect | 7 import inspect |
8 import os | 8 import os |
9 import subprocess | 9 import subprocess |
10 import sys | 10 import sys |
11 | 11 |
12 _STDOUT_IS_TTY = hasattr(sys.stdout, 'isatty') and sys.stdout.isatty() | 12 _STDOUT_IS_TTY = hasattr(sys.stdout, 'isatty') and sys.stdout.isatty() |
13 | 13 |
14 # TODO(sosa): Move logging to logging module. | 14 # TODO(sosa): Move logging to logging module. |
15 | 15 |
16 class RunCommandException(Exception): | 16 class RunCommandException(Exception): |
17 """Raised when there is an error in RunCommand.""" | 17 """Raised when there is an error in RunCommand.""" |
18 pass | 18 pass |
19 | 19 |
20 | 20 |
21 def GetCallerName(): | 21 def GetCallerName(): |
22 """Returns the name of the calling module with __main__.""" | 22 """Returns the name of the calling module with __main__.""" |
23 top_frame = inspect.stack()[-1][0] | 23 top_frame = inspect.stack()[-1][0] |
24 return os.path.basename(top_frame.f_code.co_filename) | 24 return os.path.basename(top_frame.f_code.co_filename) |
25 | 25 |
26 | 26 |
27 def RunCommand(cmd, print_cmd=True, error_ok=False, error_message=None, | 27 def RunCommand(cmd, print_cmd=True, error_ok=False, error_message=None, |
28 exit_code=False, redirect_stdout=False, redirect_stderr=False, | 28 exit_code=False, redirect_stdout=False, redirect_stderr=False, |
29 cwd=None, input=None, enter_chroot=False, num_retries=0): | 29 cwd=None, input=None, enter_chroot=False, num_retries=0, |
| 30 env=None): |
30 """Runs a shell command. | 31 """Runs a shell command. |
31 | 32 |
32 Arguments: | 33 Arguments: |
33 cmd: cmd to run. Should be input to subprocess.POpen. If a string, | 34 cmd: cmd to run. Should be input to subprocess.POpen. If a string, |
34 converted to an array using split(). | 35 converted to an array using split(). |
35 print_cmd: prints the command before running it. | 36 print_cmd: prints the command before running it. |
36 error_ok: does not raise an exception on error. | 37 error_ok: does not raise an exception on error. |
37 error_message: prints out this message when an error occurrs. | 38 error_message: prints out this message when an error occurrs. |
38 exit_code: returns the return code of the shell command. | 39 exit_code: returns the return code of the shell command. |
39 redirect_stdout: returns the stdout. | 40 redirect_stdout: returns the stdout. |
40 redirect_stderr: holds stderr output until input is communicated. | 41 redirect_stderr: holds stderr output until input is communicated. |
41 cwd: the working directory to run this cmd. | 42 cwd: the working directory to run this cmd. |
42 input: input to pipe into this command through stdin. | 43 input: input to pipe into this command through stdin. |
43 enter_chroot: this command should be run from within the chroot. If set, | 44 enter_chroot: this command should be run from within the chroot. If set, |
44 cwd must point to the scripts directory. | 45 cwd must point to the scripts directory. |
45 num_retries: the number of retries to perform before dying | 46 num_retries: the number of retries to perform before dying |
| 47 env: If non-None, should be a mapping for the environment variables of the |
| 48 command. Useful syntax: env=dict(os.environ.items() + [('VAR', 'val')]) |
46 | 49 |
47 Returns: | 50 Returns: |
48 If exit_code is True, returns the return code of the shell command. | 51 If exit_code is True, returns the return code of the shell command. |
49 Else returns the output of the shell command. | 52 Else returns the output of the shell command. |
50 | 53 |
51 Raises: | 54 Raises: |
52 Exception: Raises RunCommandException on error with optional error_message. | 55 Exception: Raises RunCommandException on error with optional error_message. |
53 """ | 56 """ |
54 # Set default for variables. | 57 # Set default for variables. |
55 stdout = None | 58 stdout = None |
56 stderr = None | 59 stderr = None |
57 stdin = None | 60 stdin = None |
58 output = '' | 61 output = '' |
59 | 62 |
60 # Modify defaults based on parameters. | 63 # Modify defaults based on parameters. |
61 if redirect_stdout: stdout = subprocess.PIPE | 64 if redirect_stdout: stdout = subprocess.PIPE |
62 if redirect_stderr: stderr = subprocess.PIPE | 65 if redirect_stderr: stderr = subprocess.PIPE |
63 if input: stdin = subprocess.PIPE | 66 if input: stdin = subprocess.PIPE |
64 if enter_chroot: cmd = ['./enter_chroot.sh', '--'] + cmd | 67 if enter_chroot: cmd = ['./enter_chroot.sh', '--'] + cmd |
65 | 68 |
66 # Print out the command before running. | 69 # Print out the command before running. |
67 if print_cmd: | 70 if print_cmd: |
68 Info('PROGRAM(%s) -> RunCommand: %r in dir %s' % | 71 Info('PROGRAM(%s) -> RunCommand: %r in dir %s' % |
69 (GetCallerName(), cmd, cwd)) | 72 (GetCallerName(), cmd, cwd)) |
70 | 73 |
71 for retry_count in range(num_retries + 1): | 74 for retry_count in range(num_retries + 1): |
72 try: | 75 try: |
73 proc = subprocess.Popen(cmd, cwd=cwd, stdin=stdin, | 76 proc = subprocess.Popen(cmd, cwd=cwd, env=env, stdin=stdin, |
74 stdout=stdout, stderr=stderr) | 77 stdout=stdout, stderr=stderr) |
75 (output, error) = proc.communicate(input) | 78 (output, error) = proc.communicate(input) |
76 if exit_code and retry_count == num_retries: | 79 if exit_code and retry_count == num_retries: |
77 return proc.returncode | 80 return proc.returncode |
78 | 81 |
79 if proc.returncode == 0: | 82 if proc.returncode == 0: |
80 break | 83 break |
81 | 84 |
82 raise RunCommandException('Command "%r" failed.\n' % (cmd) + | 85 raise RunCommandException('Command "%r" failed.\n' % (cmd) + |
83 (error_message or error or output or '')) | 86 (error_message or error or output or '')) |
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
232 root_abs_path = os.path.abspath(root_path) | 235 root_abs_path = os.path.abspath(root_path) |
233 | 236 |
234 # Strip the repository root from the path and strip first /. | 237 # Strip the repository root from the path and strip first /. |
235 relative_path = path_abs_path.replace(root_abs_path, '')[1:] | 238 relative_path = path_abs_path.replace(root_abs_path, '')[1:] |
236 | 239 |
237 if relative_path == path_abs_path: | 240 if relative_path == path_abs_path: |
238 raise Exception('Error: path is outside your src tree, cannot reinterpret.') | 241 raise Exception('Error: path is outside your src tree, cannot reinterpret.') |
239 | 242 |
240 new_path = os.path.join('/home', os.getenv('USER'), 'trunk', relative_path) | 243 new_path = os.path.join('/home', os.getenv('USER'), 'trunk', relative_path) |
241 return new_path | 244 return new_path |
OLD | NEW |