| OLD | NEW |
| 1 # Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 # Copyright (c) 2012 The Chromium 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 """A wrapper for subprocess to make calling shell commands easier.""" | 5 """A wrapper for subprocess to make calling shell commands easier.""" |
| 6 | 6 |
| 7 import logging | 7 import logging |
| 8 import os | 8 import os |
| 9 import pipes | 9 import pipes |
| 10 import select | 10 import select |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 60 The string quoted using double quotes. | 60 The string quoted using double quotes. |
| 61 """ | 61 """ |
| 62 if not s: | 62 if not s: |
| 63 return '""' | 63 return '""' |
| 64 elif all(c in _SafeShellChars for c in s): | 64 elif all(c in _SafeShellChars for c in s): |
| 65 return s | 65 return s |
| 66 else: | 66 else: |
| 67 return '"' + s.replace('"', '\\"') + '"' | 67 return '"' + s.replace('"', '\\"') + '"' |
| 68 | 68 |
| 69 | 69 |
| 70 def ShrinkToSnippet(cmd_parts, var_name, var_value): |
| 71 """Constructs a shell snippet for a command using a variable to shrink it. |
| 72 |
| 73 Takes into account all quoting that needs to happen. |
| 74 |
| 75 Args: |
| 76 cmd_parts: A list of command arguments. |
| 77 var_name: The variable that holds var_value. |
| 78 var_value: The string to replace in cmd_parts with $var_name |
| 79 |
| 80 Returns: |
| 81 A shell snippet that does not include setting the variable. |
| 82 """ |
| 83 def shrink(value): |
| 84 parts = (x and SingleQuote(x) for x in value.split(var_value)) |
| 85 with_substitutions = ('"$%s"' % var_name).join(parts) |
| 86 return with_substitutions or "''" |
| 87 |
| 88 return ' '.join(shrink(part) for part in cmd_parts) |
| 89 |
| 90 |
| 70 def Popen(args, stdout=None, stderr=None, shell=None, cwd=None, env=None): | 91 def Popen(args, stdout=None, stderr=None, shell=None, cwd=None, env=None): |
| 71 return subprocess.Popen( | 92 return subprocess.Popen( |
| 72 args=args, cwd=cwd, stdout=stdout, stderr=stderr, | 93 args=args, cwd=cwd, stdout=stdout, stderr=stderr, |
| 73 shell=shell, close_fds=True, env=env, | 94 shell=shell, close_fds=True, env=env, |
| 74 preexec_fn=lambda: signal.signal(signal.SIGPIPE, signal.SIG_DFL)) | 95 preexec_fn=lambda: signal.signal(signal.SIGPIPE, signal.SIG_DFL)) |
| 75 | 96 |
| 76 | 97 |
| 77 def Call(args, stdout=None, stderr=None, shell=None, cwd=None, env=None): | 98 def Call(args, stdout=None, stderr=None, shell=None, cwd=None, env=None): |
| 78 pipe = Popen(args, stdout=stdout, stderr=stderr, shell=shell, cwd=cwd, | 99 pipe = Popen(args, stdout=stdout, stderr=stderr, shell=shell, cwd=cwd, |
| 79 env=env) | 100 env=env) |
| (...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 281 buffer_output += data | 302 buffer_output += data |
| 282 has_incomplete_line = buffer_output[-1] not in '\r\n' | 303 has_incomplete_line = buffer_output[-1] not in '\r\n' |
| 283 lines = buffer_output.splitlines() | 304 lines = buffer_output.splitlines() |
| 284 buffer_output = lines.pop() if has_incomplete_line else '' | 305 buffer_output = lines.pop() if has_incomplete_line else '' |
| 285 for line in lines: | 306 for line in lines: |
| 286 yield line | 307 yield line |
| 287 if buffer_output: | 308 if buffer_output: |
| 288 yield buffer_output | 309 yield buffer_output |
| 289 if check_status and process.returncode: | 310 if check_status and process.returncode: |
| 290 raise subprocess.CalledProcessError(process.returncode, cmd) | 311 raise subprocess.CalledProcessError(process.returncode, cmd) |
| OLD | NEW |