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())