comparison mxtool/mx.py @ 4242:3e25132be4b4

Disabled eager resolution of libraries as they are defined. Made CTRL-C kill off subprocesses of mx.
author Doug Simon <doug.simon@oracle.com>
date Sat, 07 Jan 2012 23:59:02 +0100
parents 8fece0287975
children 3f6c6e61614e
comparison
equal deleted inserted replaced
4241:8fece0287975 4242:3e25132be4b4
293 path = attrs['path'] 293 path = attrs['path']
294 mustExist = attrs.pop('optional', 'false') != 'true' 294 mustExist = attrs.pop('optional', 'false') != 'true'
295 urls = pop_list(attrs, 'urls') 295 urls = pop_list(attrs, 'urls')
296 l = Library(self, name, path, mustExist, urls) 296 l = Library(self, name, path, mustExist, urls)
297 l.__dict__.update(attrs) 297 l.__dict__.update(attrs)
298 l.get_path(True)
299 self.libs.append(l) 298 self.libs.append(l)
300 299
301 def _load_commands(self, mxDir): 300 def _load_commands(self, mxDir):
302 commands = join(mxDir, 'commands.py') 301 commands = join(mxDir, 'commands.py')
303 if exists(commands): 302 if exists(commands):
550 abort('Process timed out after {0} seconds: {1}'.format(timeout, ' '.join(args))) 549 abort('Process timed out after {0} seconds: {1}'.format(timeout, ' '.join(args)))
551 _kill_process_group(process.pid) 550 _kill_process_group(process.pid)
552 delay = min(delay * 2, remaining, .05) 551 delay = min(delay * 2, remaining, .05)
553 time.sleep(delay) 552 time.sleep(delay)
554 553
555 # Makes the current subprocess accessible to the timeout alarm handler 554 # Makes the current subprocess accessible to the abort() function
556 # This is a tuple of the process object and args. 555 # This is a tuple of the Popen object and args.
557 _currentSubprocess = None 556 _currentSubprocess = None
558 557
559 def run(args, nonZeroIsFatal=True, out=None, err=None, cwd=None, timeout=None): 558 def run(args, nonZeroIsFatal=True, out=None, err=None, cwd=None, timeout=None):
560 """ 559 """
561 Run a command in a subprocess, wait for it to complete and return the exit status of the process. 560 Run a command in a subprocess, wait for it to complete and return the exit status of the process.
583 preexec_fn = os.setsid if get_os() != 'windows' else None 582 preexec_fn = os.setsid if get_os() != 'windows' else None
584 583
585 if not callable(out) and not callable(err) and timeout is None: 584 if not callable(out) and not callable(err) and timeout is None:
586 # The preexec_fn=os.setsid 585 # The preexec_fn=os.setsid
587 p = subprocess.Popen(args, cwd=cwd, preexec_fn=preexec_fn) 586 p = subprocess.Popen(args, cwd=cwd, preexec_fn=preexec_fn)
588 _currentSubprocess = (p, args) 587 _currentSubprocess = (p, args)
589 retcode = p.wait() 588 retcode = p.wait()
590 else: 589 else:
591 def redirect(stream, f): 590 def redirect(stream, f):
592 for line in iter(stream.readline, ''): 591 for line in iter(stream.readline, ''):
593 f(line) 592 f(line)
613 except OSError as e: 612 except OSError as e:
614 log('Error executing \'' + ' '.join(args) + '\': ' + str(e)) 613 log('Error executing \'' + ' '.join(args) + '\': ' + str(e))
615 if _opts.verbose: 614 if _opts.verbose:
616 raise e 615 raise e
617 abort(e.errno) 616 abort(e.errno)
617 except KeyboardInterrupt:
618 abort(1)
618 finally: 619 finally:
619 _currentSubprocess = None 620 _currentSubprocess = None
620
621 621
622 if retcode and nonZeroIsFatal: 622 if retcode and nonZeroIsFatal:
623 if _opts.verbose: 623 if _opts.verbose:
624 raise subprocess.CalledProcessError(retcode, ' '.join(args)) 624 raise subprocess.CalledProcessError(retcode, ' '.join(args))
625 abort(retcode) 625 abort(retcode)
739 Aborts the program with a SystemExit exception. 739 Aborts the program with a SystemExit exception.
740 If 'codeOrMessage' is a plain integer, it specifies the system exit status; 740 If 'codeOrMessage' is a plain integer, it specifies the system exit status;
741 if it is None, the exit status is zero; if it has another type (such as a string), 741 if it is None, the exit status is zero; if it has another type (such as a string),
742 the object's value is printed and the exit status is one. 742 the object's value is printed and the exit status is one.
743 """ 743 """
744
745 #import traceback
746 #traceback.print_stack()
747 currentSubprocess = _currentSubprocess
748 if currentSubprocess is not None:
749 p, _ = currentSubprocess
750 _kill_process_group(p.pid)
751
744 raise SystemExit(codeOrMessage) 752 raise SystemExit(codeOrMessage)
745 753
746 def download(path, urls, verbose=False): 754 def download(path, urls, verbose=False):
747 """ 755 """
748 Attempts to downloads content for each URL in a list, stopping after the first successful download. 756 Attempts to downloads content for each URL in a list, stopping after the first successful download.
1243 1251
1244 c, _ = commands[command][:2] 1252 c, _ = commands[command][:2]
1245 try: 1253 try:
1246 if opts.timeout != 0: 1254 if opts.timeout != 0:
1247 def alarm_handler(signum, frame): 1255 def alarm_handler(signum, frame):
1248 #import traceback
1249 #traceback.print_stack()
1250 currentSubprocess = _currentSubprocess
1251 if currentSubprocess is not None:
1252 p, args = currentSubprocess
1253 log('Killing subprocess due to command timeout: ' + ' '.join(args))
1254 _kill_process_group(p.pid)
1255 abort('Command timed out after ' + str(opts.timeout) + ' seconds: ' + ' '.join(commandAndArgs)) 1256 abort('Command timed out after ' + str(opts.timeout) + ' seconds: ' + ' '.join(commandAndArgs))
1256 signal.signal(signal.SIGALRM, alarm_handler) 1257 signal.signal(signal.SIGALRM, alarm_handler)
1257 signal.alarm(opts.timeout) 1258 signal.alarm(opts.timeout)
1258 retcode = c(command_args) 1259 retcode = c(command_args)
1259 if retcode is not None and retcode != 0: 1260 if retcode is not None and retcode != 0:
1263 abort(1) 1264 abort(1)
1264 1265
1265 if __name__ == '__main__': 1266 if __name__ == '__main__':
1266 # rename this module as 'mx' so it is not imported twice by the commands.py modules 1267 # rename this module as 'mx' so it is not imported twice by the commands.py modules
1267 sys.modules['mx'] = sys.modules.pop('__main__') 1268 sys.modules['mx'] = sys.modules.pop('__main__')
1268 1269
1269 main() 1270 main()