Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(48)

Unified Diff: gclient_utils.py

Issue 3104036: Cleanup the code in gclient_utils to standardize on CheckCall nomenclature. (Closed)
Patch Set: Rewrote the patch in part as I had introduced regressions. Removed a lot of dead code Created 10 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « gclient_scm.py ('k') | scm.py » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: gclient_utils.py
diff --git a/gclient_utils.py b/gclient_utils.py
index e0c9e8e276c2532c14b2669b6796641aacd24034..66514f12aeb5991e2131aa1c987875e1e242dacb 100644
--- a/gclient_utils.py
+++ b/gclient_utils.py
@@ -118,6 +118,7 @@ def GetNodeNamedAttributeText(node, node_name, attribute_name):
class Error(Exception):
"""gclient exception class."""
+ # TODO(maruel): Merge with CheckCallError.
pass
@@ -251,54 +252,56 @@ def RemoveDirectory(*path):
os.rmdir(file_path)
-def SubprocessCall(args, **kwargs):
- """Wraps SubprocessCallAndFilter() with different default arguments.
+def CheckCallAndFilterAndHeader(args, always=False, **kwargs):
+ """Adds 'header' support to CheckCallAndFilter.
- Calls subprocess and capture nothing."""
- kwargs['print_messages'] = True
+ If |always| is True, a message indicating what is being done
+ is printed to stdout all the time even if not output is generated. Otherwise
+ the message header is printed only if the call generated any ouput.
+ """
+ stdout = kwargs.get('stdout', None) or sys.stdout
+ if always:
+ stdout.write('\n________ running \'%s\' in \'%s\'\n'
+ % (' '.join(args), kwargs.get('cwd', '.')))
+ else:
+ filter_fn = kwargs.get('filter_fn', None)
+ def filter_msg(line):
+ if line is None:
+ stdout.write('\n________ running \'%s\' in \'%s\'\n'
+ % (' '.join(args), kwargs.get('cwd', '.')))
+ elif filter_fn:
+ filter_fn(line)
+ kwargs['filter_fn'] = filter_msg
+ kwargs['call_filter_on_first_line'] = True
+ # Obviously.
kwargs['print_stdout'] = True
- return SubprocessCallAndFilter(args, **kwargs)
-
-
-def SubprocessCallAndFilter(args, **kwargs):
- """Runs a command and prints a header line if appropriate.
+ return CheckCallAndFilter(args, **kwargs)
- If |print_messages| is True, a message indicating what is being done
- is printed to stdout. Otherwise the message is printed only if the call
- generated any ouput. If both |print_messages| and |print_stdout| are False,
- no output at all is generated.
- If |print_stdout| is True, the command's stdout is also forwarded to stdout.
+def CheckCallAndFilter(args, stdout=None, filter_fn=None,
+ print_stdout=None, call_filter_on_first_line=False,
+ **kwargs):
+ """Runs a command and calls back a filter function if needed.
- If |filter_fn| function is specified, it is expected to take a single
- string argument, and it will be called with each line of the
- subprocess's output. Each line has had the trailing newline character
- trimmed.
+ Accepts all subprocess.Popen() parameters plus:
+ print_stdout: If True, the command's stdout is forwarded to stdout.
+ filter_fn: A function taking a single string argument called with each line
+ of the subprocess's output. Each line has the trailing newline
+ character trimmed.
+ stdout: Can be any bufferable output.
- If the command fails, as indicated by a nonzero exit status, gclient will
- exit with an exit status of fail_status. If fail_status is None (the
- default), gclient will raise an Error exception.
-
- Other subprocess.Popen parameters can be specified.
+ stderr is always redirected to stdout.
"""
- stdout = kwargs.pop('stdout', sys.stdout) or sys.stdout
+ assert print_stdout or filter_fn
+ stdout = stdout or sys.stdout
+ filter_fn = filter_fn or (lambda x: None)
assert not 'stderr' in kwargs
- filter_fn = kwargs.pop('filter_fn', None)
- print_messages = kwargs.pop('print_messages', False)
- print_stdout = kwargs.pop('print_stdout', False)
- fail_status = kwargs.pop('fail_status', None)
-
logging.debug(args)
- if print_messages:
- stdout.write('\n________ running \'%s\' in \'%s\'\n'
- % (' '.join(args), kwargs['cwd']))
-
kid = Popen(args, bufsize=0,
stdout=subprocess.PIPE, stderr=subprocess.STDOUT,
**kwargs)
- # Do a flush of sys.stdout before we begin reading from the subprocess's
- # stdout.
+ # Do a flush of stdout before we begin reading from the subprocess's stdout
last_flushed_at = time.time()
stdout.flush()
@@ -307,40 +310,34 @@ def SubprocessCallAndFilter(args, **kwargs):
# normally buffering is done for each line, but if svn requests input, no
# end-of-line character is output after the prompt and it would not show up.
in_byte = kid.stdout.read(1)
- in_line = ''
- while in_byte:
- if in_byte != '\r':
- if print_stdout:
- if not print_messages:
- stdout.write('\n________ running \'%s\' in \'%s\'\n'
- % (' '.join(args), kwargs['cwd']))
- print_messages = True
- stdout.write(in_byte)
- if in_byte != '\n':
- in_line += in_byte
- if in_byte == '\n':
- if filter_fn:
- filter_fn(in_line)
- in_line = ''
- # Flush at least 10 seconds between line writes. We wait at least 10
- # seconds to avoid overloading the reader that called us with output,
- # which can slow busy readers down.
- if (time.time() - last_flushed_at) > 10:
- last_flushed_at = time.time()
- stdout.flush()
- in_byte = kid.stdout.read(1)
- # Flush the rest of buffered output. This is only an issue with files not
- # ending with a \n.
- if len(in_line) and filter_fn:
- filter_fn(in_line)
+ if in_byte:
+ if call_filter_on_first_line:
+ filter_fn(None)
+ in_line = ''
+ while in_byte:
+ if in_byte != '\r':
+ if print_stdout:
+ stdout.write(in_byte)
+ if in_byte != '\n':
+ in_line += in_byte
+ else:
+ filter_fn(in_line)
+ in_line = ''
+ # Flush at least 10 seconds between line writes. We wait at least 10
+ # seconds to avoid overloading the reader that called us with output,
+ # which can slow busy readers down.
+ if (time.time() - last_flushed_at) > 10:
+ last_flushed_at = time.time()
+ stdout.flush()
+ in_byte = kid.stdout.read(1)
+ # Flush the rest of buffered output. This is only an issue with
+ # stdout/stderr not ending with a \n.
+ if len(in_line):
+ filter_fn(in_line)
rv = kid.wait()
-
if rv:
- msg = 'failed to run command: %s' % ' '.join(args)
- if fail_status != None:
- sys.stderr.write(msg + '\n')
- sys.exit(fail_status)
- raise Error(msg)
+ raise Error('failed to run command: %s' % ' '.join(args))
+ return 0
def FindGclientRoot(from_dir, filename='.gclient'):
« no previous file with comments | « gclient_scm.py ('k') | scm.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698