blob: 825e43cc398555736340fe6ec7433ecc903f1ae1 [file] [log] [blame]
Scott Zawalski6bc41ac2010-09-08 12:47:28 -07001# 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
3# found in the LICENSE file.
4
5"""Common python commands used by various build scripts."""
6
Scott Zawalski98ac6b22010-09-08 15:59:23 -07007import os
Scott Zawalski6bc41ac2010-09-08 12:47:28 -07008import subprocess
9import sys
10
11_STDOUT_IS_TTY = hasattr(sys.stdout, 'isatty') and sys.stdout.isatty()
12
13def RunCommand(cmd, print_cmd=True, error_ok=False, error_message=None,
14 exit_code=False, redirect_stdout=False, redirect_stderr=False,
15 cwd=None, input=None, enter_chroot=False):
16 """Runs a shell command.
17
18 Keyword arguments:
19 cmd - cmd to run. Should be input to subprocess.POpen. If a string,
20 converted to an array using split().
21 print_cmd -- prints the command before running it.
22 error_ok -- does not raise an exception on error.
23 error_message -- prints out this message when an error occurrs.
24 exit_code -- returns the return code of the shell command.
25 redirect_stdout -- returns the stdout.
26 redirect_stderr -- holds stderr output until input is communicated.
27 cwd -- the working directory to run this cmd.
28 input -- input to pipe into this command through stdin.
29 enter_chroot -- this command should be run from within the chroot. If set,
30 cwd must point to the scripts directory.
31 Raises:
32 Exception: Raises generic exception on error with optional error_message.
33 """
34 # Set default for variables.
35 stdout = None
36 stderr = None
37 stdin = None
38 output = ''
39
40 # Modify defaults based on parameters.
41 if redirect_stdout: stdout = subprocess.PIPE
42 if redirect_stderr: stderr = subprocess.PIPE
43 if input: stdin = subprocess.PIPE
44 if enter_chroot: cmd = ['./enter_chroot.sh', '--'] + cmd
45
46 # Print out the command before running.
47 if print_cmd:
48 Info('RunCommand: %s' % ' '.join(cmd))
49
50 try:
51 proc = subprocess.Popen(cmd, cwd=cwd, stdin=stdin,
52 stdout=stdout, stderr=stderr)
53 (output, error) = proc.communicate(input)
54 if exit_code:
55 return proc.returncode
56
57 if not error_ok and proc.returncode:
58 raise Exception('Command "%s" failed.\n' % (' '.join(cmd)) +
59 (error_message or error or output or ''))
60 except Exception,e:
61 if not error_ok:
62 raise
63 else:
64 Warning(str(e))
65
66 return output
67
68
69class Color(object):
70 """Conditionally wraps text in ANSI color escape sequences."""
71 BLACK, RED, GREEN, YELLOW, BLUE, MAGENTA, CYAN, WHITE = range(8)
72 BOLD = -1
73 COLOR_START = '\033[1;%dm'
74 BOLD_START = '\033[1m'
75 RESET = '\033[0m'
76
77 def __init__(self, enabled=True):
78 self._enabled = enabled
79
80 def Color(self, color, text):
81 """Returns text with conditionally added color escape sequences.
82
83 Keyword arguments:
84 color: Text color -- one of the color constants defined in this class.
85 text: The text to color.
86
87 Returns:
88 If self._enabled is False, returns the original text. If it's True,
89 returns text with color escape sequences based on the value of color.
90 """
91 if not self._enabled:
92 return text
93 if color == self.BOLD:
94 start = self.BOLD_START
95 else:
96 start = self.COLOR_START % (color + 30)
97 return start + text + self.RESET
98
99
100def Die(message):
101 """Emits a red error message and halts execution.
102
103 Keyword arguments:
104 message: The message to be emitted before exiting.
105 """
106 print >> sys.stderr, (
107 Color(_STDOUT_IS_TTY).Color(Color.RED, '\nERROR: ' + message))
108 sys.exit(1)
109
110
111def Warning(message):
112 """Emits a yellow warning message and continues execution.
113
114 Keyword arguments:
115 message: The message to be emitted.
116 """
117 print >> sys.stderr, (
118 Color(_STDOUT_IS_TTY).Color(Color.YELLOW, '\nWARNING: ' + message))
119
120
121def Info(message):
122 """Emits a blue informational message and continues execution.
123
124 Keyword arguments:
125 message: The message to be emitted.
126 """
127 print >> sys.stderr, (
128 Color(_STDOUT_IS_TTY).Color(Color.BLUE, '\nINFO: ' + message))
Scott Zawalski98ac6b22010-09-08 15:59:23 -0700129
130
131def ListFiles(base_dir):
132 """Recurively list files in a directory.
133
134 Keyword arguments:
135 base_dir: directory to start recursively listing in.
136
137 Returns:
138 A list of files relative to the base_dir path or
139 An empty list of there are no files in the directories.
140 """
141 directories = [base_dir]
142 files_list = []
143 while directories:
144 directory = directories.pop()
145 for name in os.listdir(directory):
146 fullpath = os.path.join(directory, name)
147 if os.path.isfile(fullpath):
148 files_list.append(fullpath)
149 elif os.path.isdir(fullpath):
150 directories.append(fullpath)
151
152 return files_list