OLD | NEW |
(Empty) | |
| 1 # Copyright 2014 The Chromium 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 from cStringIO import StringIO |
| 5 |
| 6 |
| 7 class _Invalid(object): |
| 8 def __call__(self, *_args, **_kwargs): |
| 9 return self |
| 10 |
| 11 def __getattr__(self, _key): |
| 12 return self |
| 13 |
| 14 def __eq__(self, _other): |
| 15 return False |
| 16 |
| 17 def __ne__(self, _other): # pylint: disable=R0201 |
| 18 return True |
| 19 |
| 20 INVALID = _Invalid() |
| 21 |
| 22 |
| 23 class CalledProcessError(Exception): |
| 24 """Almost like subprocess.CalledProcessError, but also captures stderr, |
| 25 and gives prettier error messages. |
| 26 """ |
| 27 def __init__(self, returncode, cmd, stdout, stderr): |
| 28 super(CalledProcessError, self).__init__() |
| 29 self.returncode = returncode |
| 30 self.cmd = cmd |
| 31 self.stdout = stdout |
| 32 self.stderr = stderr |
| 33 |
| 34 def __str__(self): |
| 35 msg = StringIO() |
| 36 |
| 37 suffix = ':' if self.stderr or self.stdout else '.' |
| 38 print >> msg, ( |
| 39 "Command %r returned non-zero exit status %d%s" |
| 40 % (self.cmd, self.returncode, suffix) |
| 41 ) |
| 42 |
| 43 def indent_data(banner, data): |
| 44 print >> msg, banner, '=' * 40 |
| 45 msg.writelines(' ' + l for l in data.splitlines(True)) |
| 46 |
| 47 if self.stdout: |
| 48 indent_data('STDOUT', self.stdout) |
| 49 |
| 50 if self.stderr: |
| 51 if self.stdout: |
| 52 print >> msg |
| 53 indent_data('STDERR', self.stderr) |
| 54 |
| 55 r = msg.getvalue() |
| 56 if r[-1] != '\n': |
| 57 r += '\n' |
| 58 return r |
| 59 |
OLD | NEW |