Mercurial > hg > truffle
comparison mxtool/mx.py @ 4225:339cf8d4904d
Made mx.run work properly when stderr is redirected to stdout.
Made outputparser redirect stderr to stdout.
Added copyright headers to outputparser.py and sanitycheck.py.
Reverted class path construction in mx.build() to use includeSelf=True to fix regression when running 'mx build -c'.
author | Doug Simon <doug.simon@oracle.com> |
---|---|
date | Thu, 05 Jan 2012 11:31:46 +0100 |
parents | 47f7d91d34cf |
children | e03ff10d4bfc |
comparison
equal
deleted
inserted
replaced
4224:26336f60ec7a | 4225:339cf8d4904d |
---|---|
533 def run(args, nonZeroIsFatal=True, out=None, err=None, cwd=None, timeout=None): | 533 def run(args, nonZeroIsFatal=True, out=None, err=None, cwd=None, timeout=None): |
534 """ | 534 """ |
535 Run a command in a subprocess, wait for it to complete and return the exit status of the process. | 535 Run a command in a subprocess, wait for it to complete and return the exit status of the process. |
536 If the exit status is non-zero and `nonZeroIsFatal` is true, then mx is exited with | 536 If the exit status is non-zero and `nonZeroIsFatal` is true, then mx is exited with |
537 the same exit status. | 537 the same exit status. |
538 Each line of the standard output and error streams of the subprocess are redirected to the | 538 Each line of the standard output and error streams of the subprocess are redirected to |
539 provided out and err functions if they are not None. | 539 out and err if they are callable objects. |
540 """ | 540 """ |
541 | 541 |
542 assert isinstance(args, types.ListType), "'args' must be a list: " + str(args) | 542 assert isinstance(args, types.ListType), "'args' must be a list: " + str(args) |
543 for arg in args: | 543 for arg in args: |
544 assert isinstance(arg, types.StringTypes), 'argument is not a string: ' + str(arg) | 544 assert isinstance(arg, types.StringTypes), 'argument is not a string: ' + str(arg) |
548 | 548 |
549 if timeout is None and _opts.timeout != 0: | 549 if timeout is None and _opts.timeout != 0: |
550 timeout = _opts.timeout | 550 timeout = _opts.timeout |
551 | 551 |
552 try: | 552 try: |
553 if out is None and err is None and timeout is None: | 553 if not callable(out) and not callable(err) and timeout is None: |
554 retcode = subprocess.call(args, cwd=cwd) | 554 retcode = subprocess.call(args, cwd=cwd) |
555 else: | 555 else: |
556 def redirect(stream, f): | 556 def redirect(stream, f): |
557 for line in iter(stream.readline, ''): | 557 for line in iter(stream.readline, ''): |
558 f(line) | 558 f(line) |
559 stream.close() | 559 stream.close() |
560 p = subprocess.Popen(args, cwd=cwd, stdout=None if out is None else subprocess.PIPE, stderr=None if err is None else subprocess.PIPE) | 560 stdout=out if not callable(out) else subprocess.PIPE |
561 if out is not None: | 561 stderr=err if not callable(err) else subprocess.PIPE |
562 p = subprocess.Popen(args, cwd=cwd, stdout=stdout, stderr=stderr) | |
563 if callable(out): | |
562 t = Thread(target=redirect, args=(p.stdout, out)) | 564 t = Thread(target=redirect, args=(p.stdout, out)) |
563 t.daemon = True # thread dies with the program | 565 t.daemon = True # thread dies with the program |
564 t.start() | 566 t.start() |
565 if err is not None: | 567 if callable(err): |
566 t = Thread(target=redirect, args=(p.stderr, err)) | 568 t = Thread(target=redirect, args=(p.stderr, err)) |
567 t.daemon = True # thread dies with the program | 569 t.daemon = True # thread dies with the program |
568 t.start() | 570 t.start() |
569 if timeout is None or timeout == 0: | 571 if timeout is None or timeout == 0: |
570 retcode = p.wait() | 572 retcode = p.wait() |
831 shutil.rmtree(outputDir) | 833 shutil.rmtree(outputDir) |
832 os.mkdir(outputDir) | 834 os.mkdir(outputDir) |
833 else: | 835 else: |
834 os.mkdir(outputDir) | 836 os.mkdir(outputDir) |
835 | 837 |
836 cp = classpath(p.name, includeSelf=False) | 838 cp = classpath(p.name, includeSelf=True) |
837 sourceDirs = p.source_dirs() | 839 sourceDirs = p.source_dirs() |
838 mustBuild = args.force | 840 mustBuild = args.force |
839 if not mustBuild: | 841 if not mustBuild: |
840 for dep in p.all_deps([], False): | 842 for dep in p.all_deps([], False): |
841 if dep.name in built: | 843 if dep.name in built: |
883 """ | 885 """ |
884 def __init__(self): | 886 def __init__(self): |
885 self.c = 0 | 887 self.c = 0 |
886 | 888 |
887 def eat(self, line): | 889 def eat(self, line): |
888 if 'proprietary API': | 890 if 'proprietary API' in line: |
889 self.c = 2 | 891 self.c = 2 |
890 elif self.c != 0: | 892 elif self.c != 0: |
891 self.c -= 1 | 893 self.c -= 1 |
892 else: | 894 else: |
893 log(line.rstrip()) | 895 log(line.rstrip()) |