def _run(): root_dir = get_buildroot() version = get_version() if not os.path.exists(root_dir): _exit_and_fail('PANTS_BUILD_ROOT does not point to a valid path: %s' % root_dir) if len(sys.argv) < 2 or (len(sys.argv) == 2 and sys.argv[1] in _HELP_ALIASES): _help(version, root_dir) command_class, command_args = _parse_command(root_dir, sys.argv[1:]) parser = optparse.OptionParser(version = '%%prog %s' % version) RcFile.install_disable_rc_option(parser) parser.add_option(_LOG_EXIT_OPTION, action = 'store_true', dest = 'log_exit', default = False, help = 'Log an exit message on success or failure') command = command_class(root_dir, parser, command_args) if command.serialized(): def onwait(pid): print('Waiting on pants process %s to complete' % _process_info(pid), file=sys.stderr) return True runfile = os.path.join(root_dir, '.pants.run') lock = Lock.acquire(runfile, onwait=onwait) else: lock = Lock.unlocked() try: result = command.run(lock) _do_exit(result) finally: lock.release()
def _run(): root_dir = get_buildroot() version = get_version() if not os.path.exists(root_dir): _exit_and_fail('PANTS_BUILD_ROOT does not point to a valid path: %s' % root_dir) if len(sys.argv) < 2 or (len(sys.argv) == 2 and sys.argv[1] in _HELP_ALIASES): _help(version, root_dir) command_class, command_args = _parse_command(root_dir, sys.argv[1:]) parser = optparse.OptionParser(version = '%%prog %s' % version) RcFile.install_disable_rc_option(parser) parser.add_option(_LOG_EXIT_OPTION, action = 'store_true', dest = 'log_exit', default = False, help = 'Log an exit message on success or failure') command = command_class(root_dir, parser, command_args) if command.serialized(): def onwait(pid): print('Waiting on pants process %s to complete' % _process_info(pid), file=sys.stderr) return True runfile = os.path.join(root_dir, '.pants.run') lock = Lock.acquire(runfile, onwait=onwait) else: lock = Lock.unlocked() try: result = command.run(lock) _do_exit(result) except KeyboardInterrupt: command.cleanup() raise finally: lock.release()
def _run(): version = get_version() if len(sys.argv) == 2 and sys.argv[1] == _VERSION_OPTION: _do_exit(version) root_dir = get_buildroot() if not os.path.exists(root_dir): _exit_and_fail('PANTS_BUILD_ROOT does not point to a valid path: %s' % root_dir) if len(sys.argv) < 2 or (len(sys.argv) == 2 and sys.argv[1] in _HELP_ALIASES): _help(version, root_dir) command_class, command_args = _parse_command(root_dir, sys.argv[1:]) parser = optparse.OptionParser(version=version) RcFile.install_disable_rc_option(parser) parser.add_option(_LOG_EXIT_OPTION, action='store_true', default=False, dest='log_exit', help='Log an exit message on success or failure.') config = Config.load() run_tracker = RunTracker(config) report = default_report(config, run_tracker) run_tracker.start(report) url = run_tracker.run_info.get_info('report_url') run_tracker.log(Report.INFO, 'See a report at: %s' % url) run_tracker.log(Report.INFO, '(To run a reporting server: ./pants server)') try: command = command_class(run_tracker, root_dir, parser, command_args) if command.serialized(): def onwait(pid): print('Waiting on pants process %s to complete' % _process_info(pid), file=sys.stderr) return True runfile = os.path.join(root_dir, '.pants.run') lock = Lock.acquire(runfile, onwait=onwait) else: lock = Lock.unlocked() try: result = command.run(lock) _do_exit(result) except KeyboardInterrupt: command.cleanup() raise finally: lock.release() finally: run_tracker.end()
def _run(): version = get_version() if len(sys.argv) == 2 and sys.argv[1] == _VERSION_OPTION: _do_exit(version) root_dir = get_buildroot() if not os.path.exists(root_dir): _exit_and_fail('PANTS_BUILD_ROOT does not point to a valid path: %s' % root_dir) if len(sys.argv) < 2 or (len(sys.argv) == 2 and sys.argv[1] in _HELP_ALIASES): _help(version, root_dir) command_class, command_args = _parse_command(root_dir, sys.argv[1:]) parser = optparse.OptionParser(version=version) RcFile.install_disable_rc_option(parser) parser.add_option(_LOG_EXIT_OPTION, action='store_true', default=False, dest='log_exit', help = 'Log an exit message on success or failure.') config = Config.load() run_tracker = RunTracker(config) report = initial_reporting(config, run_tracker) run_tracker.start(report) url = run_tracker.run_info.get_info('report_url') if url: run_tracker.log(Report.INFO, 'See a report at: %s' % url) else: run_tracker.log(Report.INFO, '(To run a reporting server: ./pants server)') command = command_class(run_tracker, root_dir, parser, command_args) try: if command.serialized(): def onwait(pid): print('Waiting on pants process %s to complete' % _process_info(pid), file=sys.stderr) return True runfile = os.path.join(root_dir, '.pants.run') lock = Lock.acquire(runfile, onwait=onwait) else: lock = Lock.unlocked() try: result = command.run(lock) _do_exit(result) except KeyboardInterrupt: command.cleanup() raise finally: lock.release() finally: run_tracker.end() # Must kill nailguns only after run_tracker.end() is called, because there may still # be pending background work that needs a nailgun. if (hasattr(command.options, 'cleanup_nailguns') and command.options.cleanup_nailguns) \ or config.get('nailgun', 'autokill', default=False): NailgunTask.killall(None)
def release_lock(self): """Release the global lock if it's held. Returns True if the lock was held before this call. """ if self._lock is Lock.unlocked(): return False else: self._lock.release() self._lock = Lock.unlocked() return True
def test_acquire_nowait(self): with temporary_file() as fd: def throw(pid): self.fail('Did not expect to wait for the 1st lock, held by %d' % pid) lock = Lock.acquire(fd.name, onwait=throw) try: def onwait(pid): self.assertEquals(os.getpid(), pid, "This process should hold the lock.") return False self.assertFalse(Lock.acquire(fd.name, onwait=onwait)) finally: self.assertTrue(lock.release()) self.assertFalse(lock.release())
def __init__(self, config, options, run_tracker, target_roots, requested_goals=None, lock=None, log=None, target_base=None, build_graph=None, build_file_parser=None): self._config = config self._options = options self.build_graph = build_graph self.build_file_parser = build_file_parser self.run_tracker = run_tracker self._lock = lock or Lock.unlocked() self._log = log or Context.Log(run_tracker) self._target_base = target_base or Target self._state = {} self._products = Products() self._buildroot = get_buildroot() self._java_sysprops = None # Computed lazily. self.requested_goals = requested_goals or [] self.replace_targets(target_roots)
def __init__(self, config, options, run_tracker, target_roots, requested_goals=None, lock=None, log=None, target_base=None, build_graph=None, build_file_parser=None, address_mapper=None, console_outstream=None, scm=None, workspace=None): self._config = config self._options = options self.build_graph = build_graph self.build_file_parser = build_file_parser self.address_mapper = address_mapper self.run_tracker = run_tracker self._lock = lock or Lock.unlocked() self._log = log or Context.Log(run_tracker) self._target_base = target_base or Target self._products = Products() self._buildroot = get_buildroot() self._java_sysprops = None # Computed lazily. self.requested_goals = requested_goals or [] self._console_outstream = console_outstream or sys.stdout self._scm = scm or get_scm() self._workspace = workspace or (ScmWorkspace(self._scm) if self._scm else None) self.replace_targets(target_roots)
def __init__(self, config, options, target_roots, lock=None, log=None): self._config = config self._options = options self._lock = lock or Lock.unlocked() self._log = log or Context.Log() self._state = {} self._products = Products() self.replace_targets(target_roots)
def acquire_lock(self): """ Acquire the global lock for the root directory associated with this context. When a goal requires serialization, it will call this to acquire the lock. """ def onwait(pid): print('Waiting on pants process %s to complete' % _process_info(pid), file=sys.stderr) return True if self._lock.is_unlocked(): runfile = os.path.join(self._buildroot, '.pants.run') self._lock = Lock.acquire(runfile, onwait=onwait)
def __init__(self, config, options, target_roots, lock=Lock.unlocked(), log=None, timer=None): self._config = config self._options = options self._lock = lock self._log = log or Context.Log() self._state = {} self._products = Products() self._buildroot = get_buildroot() self.timer = timer self.replace_targets(target_roots)
def test_acquire_nowait(self): with temporary_file() as fd: def throw(pid): self.fail( 'Did not expect to wait for the 1st lock, held by %d' % pid) lock = Lock.acquire(fd.name, onwait=throw) try: def onwait(pid): self.assertEquals(os.getpid(), pid, "This process should hold the lock.") return False self.assertFalse(Lock.acquire(fd.name, onwait=onwait)) finally: self.assertTrue(lock.release()) self.assertFalse(lock.release())
def test_acquire_wait(self): with temporary_dir() as path: lockfile = os.path.join(path, 'lock') childpid = os.fork() if childpid == 0: lock = Lock.acquire(lockfile) try: while True: time.sleep(1) except KeyboardInterrupt: lock.release() else: def childup(): if not os.path.exists(lockfile): return False else: with open(lockfile) as fd: pid = fd.read().strip() return pid and pid == str(childpid) while not childup(): time.sleep(0.1) # We should be blocked by the forked child lock owner def onwait(pid): self.assertEquals(childpid, pid) return False self.assertFalse(Lock.acquire(lockfile, onwait=onwait)) # We should unblock after we 'kill' the forked child owner os.kill(childpid, signal.SIGINT) lock = Lock.acquire(lockfile) try: self.assertTrue(lock) finally: self.assertTrue(lock.release())
def __init__(self, config, options, run_tracker, target_roots, requested_goals=None, lock=None, log=None): self._config = config self._options = options self.run_tracker = run_tracker self._lock = lock or Lock.unlocked() self._log = log or Context.Log(run_tracker) self._state = {} self._products = Products() self._buildroot = get_buildroot() self._java_home = None # Computed lazily. self.requested_goals = requested_goals or [] self.replace_targets(target_roots)
def __init__(self, config, options, run_tracker, target_roots, requested_goals=None, lock=Lock.unlocked(), log=None, target_base=None): self._config = config self._options = options self.run_tracker = run_tracker self._lock = lock self._log = log or Context.Log(run_tracker) self._target_base = target_base or Target self._state = {} self._products = Products() self._buildroot = get_buildroot() self.requested_goals = requested_goals or [] self.replace_targets(target_roots)
def __init__(self, config, options, run_tracker, target_roots, requested_goals=None, lock=None, log=None, target_base=None, build_graph=None, build_file_parser=None): self._config = config self._options = options self.build_graph = build_graph self.build_file_parser = build_file_parser self.run_tracker = run_tracker self._lock = lock or Lock.unlocked() self._log = log or Context.Log(run_tracker) self._target_base = target_base or Target self._products = Products() self._buildroot = get_buildroot() self._java_sysprops = None # Computed lazily. self.requested_goals = requested_goals or [] self.replace_targets(target_roots)
def _run(): """ To add additional paths to sys.path, add a block to the config similar to the following: [main] roots: ['src/python/twitter/pants_internal/test/',] """ version = get_version() if len(sys.argv) == 2 and sys.argv[1] == _VERSION_OPTION: _do_exit(version) root_dir = get_buildroot() if not os.path.exists(root_dir): _exit_and_fail('PANTS_BUILD_ROOT does not point to a valid path: %s' % root_dir) if len(sys.argv) < 2 or (len(sys.argv) == 2 and sys.argv[1] in _HELP_ALIASES): _help(version, root_dir) command_class, command_args = _parse_command(root_dir, sys.argv[1:]) parser = optparse.OptionParser(version=version) RcFile.install_disable_rc_option(parser) parser.add_option(_LOG_EXIT_OPTION, action='store_true', default=False, dest='log_exit', help='Log an exit message on success or failure.') config = Config.load() # TODO: This can be replaced once extensions are enabled with # https://github.com/pantsbuild/pants/issues/5 roots = config.getlist('parse', 'roots', default=[]) sys.path.extend(map(lambda root: os.path.join(root_dir, root), roots)) # XXX(wickman) This should be in the command goal, not un pants_exe.py! run_tracker = RunTracker.from_config(config) report = initial_reporting(config, run_tracker) run_tracker.start(report) url = run_tracker.run_info.get_info('report_url') if url: run_tracker.log(Report.INFO, 'See a report at: %s' % url) else: run_tracker.log(Report.INFO, '(To run a reporting server: ./pants server)') command = command_class(run_tracker, root_dir, parser, command_args) try: if command.serialized(): def onwait(pid): print('Waiting on pants process %s to complete' % _process_info(pid), file=sys.stderr) return True runfile = os.path.join(root_dir, '.pants.run') lock = Lock.acquire(runfile, onwait=onwait) else: lock = Lock.unlocked() try: result = command.run(lock) _do_exit(result) except KeyboardInterrupt: command.cleanup() raise finally: lock.release() finally: run_tracker.end() # Must kill nailguns only after run_tracker.end() is called, because there may still # be pending background work that needs a nailgun. if (hasattr(command.options, 'cleanup_nailguns') and command.options.cleanup_nailguns) \ or config.get('nailgun', 'autokill', default=False): NailgunTask.killall(None)
def _run(): # Place the registration of the unhandled exception hook as early as possible in the code. sys.excepthook = _unhandled_exception_hook """ To add additional paths to sys.path, add a block to the config similar to the following: [main] roots: ['src/python/pants_internal/test/',] """ logging.basicConfig() version = pants_version() if len(sys.argv) == 2 and sys.argv[1] == _VERSION_OPTION: _do_exit(msg=version, out=sys.stdout) root_dir = get_buildroot() if not os.path.exists(root_dir): _exit_and_fail('PANTS_BUILD_ROOT does not point to a valid path: %s' % root_dir) if len(sys.argv) < 2: argv = ['goal'] else: argv = sys.argv[1:] # Hack to force ./pants -h etc. to redirect to goal. if argv[0] != 'goal' and set(['-h', '--help', 'help']).intersection(argv): argv = ['goal'] + argv parser = optparse.OptionParser(add_help_option=False, version=version) RcFile.install_disable_rc_option(parser) parser.add_option(_LOG_EXIT_OPTION, action='store_true', default=False, dest='log_exit', help='Log an exit message on success or failure.') config = Config.load() # XXX(wickman) This should be in the command goal, not in pants_exe.py! run_tracker = RunTracker.from_config(config) report = initial_reporting(config, run_tracker) run_tracker.start(report) url = run_tracker.run_info.get_info('report_url') if url: run_tracker.log(Report.INFO, 'See a report at: %s' % url) else: run_tracker.log(Report.INFO, '(To run a reporting server: ./pants goal server)') backend_packages = config.getlist('backends', 'packages') build_configuration = load_build_configuration_from_source(additional_backends=backend_packages) build_file_parser = BuildFileParser(build_configuration=build_configuration, root_dir=root_dir, run_tracker=run_tracker) address_mapper = BuildFileAddressMapper(build_file_parser) build_graph = BuildGraph(run_tracker=run_tracker, address_mapper=address_mapper) command_class, command_args = _parse_command(root_dir, argv) command = command_class(run_tracker, root_dir, parser, command_args, build_file_parser, address_mapper, build_graph) try: if command.serialized(): def onwait(pid): process = psutil.Process(pid) print('Waiting on pants process %d (%s) to complete' % (pid, ' '.join(process.cmdline)), file=sys.stderr) return True runfile = os.path.join(root_dir, '.pants.run') lock = Lock.acquire(runfile, onwait=onwait) else: lock = Lock.unlocked() try: result = command.run(lock) if result: run_tracker.set_root_outcome(WorkUnit.FAILURE) _do_exit(result) except KeyboardInterrupt: command.cleanup() raise except Exception: run_tracker.set_root_outcome(WorkUnit.FAILURE) raise finally: lock.release() finally: run_tracker.end() # Must kill nailguns only after run_tracker.end() is called, because there may still # be pending background work that needs a nailgun. if (hasattr(command.old_options, 'cleanup_nailguns') and command.old_options.cleanup_nailguns) \ or config.get('nailgun', 'autokill', default=False): NailgunTask.killall(None)
def test_unlocked(self): lock1 = Lock.unlocked() lock2 = Lock.unlocked() self.assertFalse(lock1.release()) self.assertFalse(lock1.release()) self.assertFalse(lock2.release())
def _run(): """ To add additional paths to sys.path, add a block to the config similar to the following: [main] roots: ['src/python/pants_internal/test/',] """ version = get_version() if len(sys.argv) == 2 and sys.argv[1] == _VERSION_OPTION: _do_exit(version) root_dir = get_buildroot() if not os.path.exists(root_dir): _exit_and_fail('PANTS_BUILD_ROOT does not point to a valid path: %s' % root_dir) if len(sys.argv) < 2: argv = ['goal'] else: argv = sys.argv[1:] # Hack to force ./pants -h etc. to redirect to goal. if argv[0] != 'goal' and set(['-h', '--help', 'help']).intersection(argv): argv = ['goal'] + argv parser = optparse.OptionParser(add_help_option=False, version=version) RcFile.install_disable_rc_option(parser) parser.add_option(_LOG_EXIT_OPTION, action='store_true', default=False, dest='log_exit', help = 'Log an exit message on success or failure.') config = Config.load() # XXX(wickman) This should be in the command goal, not un pants_exe.py! run_tracker = RunTracker.from_config(config) report = initial_reporting(config, run_tracker) run_tracker.start(report) url = run_tracker.run_info.get_info('report_url') if url: run_tracker.log(Report.INFO, 'See a report at: %s' % url) else: run_tracker.log(Report.INFO, '(To run a reporting server: ./pants goal server)') build_file_parser = BuildFileParser(root_dir=root_dir, run_tracker=run_tracker) build_graph = BuildGraph(run_tracker=run_tracker) additional_backends = config.getlist('backends', 'packages') load_backends_from_source(build_file_parser, additional_backends=additional_backends) command_class, command_args = _parse_command(root_dir, argv) command = command_class(run_tracker, root_dir, parser, command_args, build_file_parser, build_graph) try: if command.serialized(): def onwait(pid): process = psutil.Process(pid) print('Waiting on pants process %d (%s) to complete' % (pid, ' '.join(process.cmdline)), file=sys.stderr) return True runfile = os.path.join(root_dir, '.pants.run') lock = Lock.acquire(runfile, onwait=onwait) else: lock = Lock.unlocked() try: result = command.run(lock) if result: run_tracker.set_root_outcome(WorkUnit.FAILURE) _do_exit(result) except KeyboardInterrupt: command.cleanup() raise finally: lock.release() finally: run_tracker.end() # Must kill nailguns only after run_tracker.end() is called, because there may still # be pending background work that needs a nailgun. if (hasattr(command.options, 'cleanup_nailguns') and command.options.cleanup_nailguns) \ or config.get('nailgun', 'autokill', default=False): NailgunTask.killall(None)
def _run(): """ To add additional paths to sys.path, add a block to the config similar to the following: [main] roots: ['src/python/twitter/pants_internal/test/',] """ version = get_version() if len(sys.argv) == 2 and sys.argv[1] == _VERSION_OPTION: _do_exit(version) root_dir = get_buildroot() if not os.path.exists(root_dir): _exit_and_fail('PANTS_BUILD_ROOT does not point to a valid path: %s' % root_dir) if len(sys.argv) < 2 or (len(sys.argv) == 2 and sys.argv[1] in _HELP_ALIASES): _help(version, root_dir) command_class, command_args = _parse_command(root_dir, sys.argv[1:]) parser = optparse.OptionParser(version=version) RcFile.install_disable_rc_option(parser) parser.add_option(_LOG_EXIT_OPTION, action='store_true', default=False, dest='log_exit', help = 'Log an exit message on success or failure.') config = Config.load() # TODO: This can be replaced once extensions are enabled with # https://github.com/pantsbuild/pants/issues/5 roots = config.getlist('parse', 'roots', default=[]) sys.path.extend(map(lambda root: os.path.join(root_dir, root), roots)) # XXX(wickman) This should be in the command goal, not un pants_exe.py! run_tracker = RunTracker.from_config(config) report = initial_reporting(config, run_tracker) run_tracker.start(report) url = run_tracker.run_info.get_info('report_url') if url: run_tracker.log(Report.INFO, 'See a report at: %s' % url) else: run_tracker.log(Report.INFO, '(To run a reporting server: ./pants server)') command = command_class(run_tracker, root_dir, parser, command_args) try: if command.serialized(): def onwait(pid): print('Waiting on pants process %s to complete' % _process_info(pid), file=sys.stderr) return True runfile = os.path.join(root_dir, '.pants.run') lock = Lock.acquire(runfile, onwait=onwait) else: lock = Lock.unlocked() try: result = command.run(lock) _do_exit(result) except KeyboardInterrupt: command.cleanup() raise finally: lock.release() finally: run_tracker.end() # Must kill nailguns only after run_tracker.end() is called, because there may still # be pending background work that needs a nailgun. if (hasattr(command.options, 'cleanup_nailguns') and command.options.cleanup_nailguns) \ or config.get('nailgun', 'autokill', default=False): NailgunTask.killall(None)