def test_sibling_references(self): with temporary_dir() as root_dir: buildfile = create_buildfile(root_dir, 'a', name='BUILD', content=dedent(""" dependencies(name='util', dependencies=[ jar(org='com.twitter', name='util', rev='0.0.1') ] ) """).strip()) sibling = create_buildfile(root_dir, 'a', name='BUILD.sibling', content=dedent(""" dependencies(name='util-ex', dependencies=[ pants(':util'), jar(org='com.twitter', name='util-ex', rev='0.0.1') ] ) """).strip()) ParseContext(buildfile).parse() utilex = Target.get( Address.parse(root_dir, 'a:util-ex', is_relative=False)) utilex_deps = set(utilex.resolve()) util = Target.get( Address.parse(root_dir, 'a:util', is_relative=False)) util_deps = set(util.resolve()) self.assertEquals(util_deps, util_deps.intersection(utilex_deps))
def parse_address(): if spec.startswith(':'): # the :[target] could be in a sibling BUILD - so parse using the canonical address pathish = "%s:%s" % (parse_context.buildfile.canonical_relpath, spec[1:]) return Address.parse(parse_context.buildfile.root_dir, pathish, False) else: return Address.parse(parse_context.buildfile.root_dir, spec, False)
def test_top_level(self): with self.workspace('BUILD') as root_dir: self.assertAddress(root_dir, 'BUILD', 'c', Address.parse(root_dir, ':c')) self.assertAddress(root_dir, 'BUILD', 'c', Address.parse(root_dir, '.:c')) self.assertAddress(root_dir, 'BUILD', 'c', Address.parse(root_dir, './:c')) self.assertAddress(root_dir, 'BUILD', 'c', Address.parse(root_dir, './BUILD:c')) self.assertAddress(root_dir, 'BUILD', 'c', Address.parse(root_dir, 'BUILD:c'))
def test_sibling_references(self): with temporary_dir() as root_dir: buildfile = create_buildfile(root_dir, 'a', name='BUILD', content=dedent(""" dependencies(name='util', dependencies=[ jar(org='com.twitter', name='util', rev='0.0.1') ] ) """).strip() ) sibling = create_buildfile(root_dir, 'a', name='BUILD.sibling', content=dedent(""" dependencies(name='util-ex', dependencies=[ pants(':util'), jar(org='com.twitter', name='util-ex', rev='0.0.1') ] ) """).strip() ) ParseContext(buildfile).parse() utilex = Target.get(Address.parse(root_dir, 'a:util-ex', is_relative=False)) utilex_deps = set(utilex.resolve()) util = Target.get(Address.parse(root_dir, 'a:util', is_relative=False)) util_deps = set(util.resolve()) self.assertEquals(util_deps, util_deps.intersection(utilex_deps))
def _coerce_to_targets(cls, from_str, to_str): if isinstance(from_str, Compatibility.string): if not isinstance(to_str, Compatibility.string): raise TaskError( 'Finding paths from string %s to non-string %s' % (from_str, str(to_str))) from_address = Address.parse(get_buildroot(), from_str) to_address = Address.parse(get_buildroot(), to_str) from_target = Target.get(from_address) to_target = Target.get(to_address) if not from_target: raise TaskError('Target %s doesn\'t exist' % from_address.reference()) if not to_target: raise TaskError('Target %s doesn\'t exist' % to_address.reference()) return from_target, to_target elif isinstance(to_str, Compatibility.string): raise TaskError('Finding paths from string %s to non-string %s' % (to_str, str(from_str))) return from_str, to_str
def test_parse_from_root_dir(self): with self.workspace('a/b/c/BUILD') as root_dir: self.assertAddress( root_dir, 'a/b/c/BUILD', 'c', Address.parse(root_dir, 'a/b/c', is_relative=False)) self.assertAddress( root_dir, 'a/b/c/BUILD', 'c', Address.parse(root_dir, 'a/b/c', is_relative=True))
def test_parse_from_sub_dir(self): with self.workspace('a/b/c/BUILD') as root_dir: with pushd(os.path.join(root_dir, 'a')): self.assertAddress(root_dir, 'a/b/c/BUILD', 'c', Address.parse(root_dir, 'b/c', is_relative=True)) with pytest.raises(IOError): Address.parse(root_dir, 'b/c', is_relative=False)
def test_default_form(self): with self.workspace('a/BUILD') as root_dir: self.assertAddress(root_dir, 'a/BUILD', 'a', Address.parse(root_dir, 'a')) self.assertAddress(root_dir, 'a/BUILD', 'a', Address.parse(root_dir, 'a/BUILD')) self.assertAddress(root_dir, 'a/BUILD', 'a', Address.parse(root_dir, 'a/BUILD/'))
def test_parse_from_sub_dir(self): with self.workspace('a/b/c/BUILD') as root_dir: with pushd(os.path.join(root_dir, 'a')): self.assertAddress( root_dir, 'a/b/c/BUILD', 'c', Address.parse(root_dir, 'b/c', is_relative=True)) with pytest.raises(IOError): Address.parse(root_dir, 'b/c', is_relative=False)
def test_full_forms(self): with self.workspace('a/BUILD') as root_dir: self.assertAddress(root_dir, 'a/BUILD', 'b', Address.parse(root_dir, 'a:b')) self.assertAddress(root_dir, 'a/BUILD', 'b', Address.parse(root_dir, 'a/:b')) self.assertAddress(root_dir, 'a/BUILD', 'b', Address.parse(root_dir, 'a/BUILD:b')) self.assertAddress(root_dir, 'a/BUILD', 'b', Address.parse(root_dir, 'a/BUILD/:b'))
def parse_jarcoordinate(coordinate): components = coordinate.split('#', 1) if len(components) == 2: org, name = components return org, name else: try: address = Address.parse(get_buildroot(), coordinate) try: target = Target.get(address) if not target: siblings = Target.get_all_addresses( address.buildfile) prompt = 'did you mean' if len( siblings ) == 1 else 'maybe you meant one of these' raise TaskError('%s => %s?:\n %s' % (address, prompt, '\n '.join( str(a) for a in siblings))) if not target.is_exported: raise TaskError('%s is not an exported target' % coordinate) return target.provides.org, target.provides.name except (ImportError, SyntaxError, TypeError): raise TaskError('Failed to parse %s' % address.buildfile.relpath) except IOError: raise TaskError('No BUILD file could be found at %s' % coordinate)
def _synthesize_command(root_dir, args): command = args[0] if command in Command.all_commands(): subcommand_args = args[1:] if len(args) > 1 else [] return command, _add_default_options(command, subcommand_args) if command.startswith('-'): _exit_and_fail('Invalid command: %s' % command) # assume 'build' if a command was omitted. try: Address.parse(root_dir, command) return _BUILD_COMMAND, _add_default_options(_BUILD_COMMAND, args) except: _exit_and_fail('Failed to execute pants build: %s' % traceback.format_exc())
def target(cls, address): """Resolves the given target address to a Target object. address: The BUILD target address to resolve. Returns the corresponding Target or else None if the address does not point to a defined Target. """ return Target.get(Address.parse(cls.build_root, address, is_relative=False))
def _get_target(address): try: address = Address.parse(get_buildroot(), address, is_relative=False) except IOError as e: raise TaskError('Failed to parse address: %s: %s' % (address, e)) match = Target.get(address) if not match: raise TaskError('Invalid target address: %s' % address) return match
def target(cls, address): """Resolves the given target address to a Target object. address: The BUILD target address to resolve. Returns the corresponding Target or else None if the address does not point to a defined Target. """ return Target.get( Address.parse(cls.build_root, address, is_relative=False))
def parse_url(spec): match = MarkdownToHtml.PANTS_LINK.match(spec) if match: page = Target.get(Address.parse(get_buildroot(), match.group(1))) anchor = match.group(2) or '' if not page: raise TaskError('Invalid link %s' % match.group(1)) alias, url = url_builder(page, config=get_config(page)) return alias, url + anchor else: return spec, spec
def _parse_addresses(self, spec): if spec.endswith('::'): dir = self._get_dir(spec[:-len('::')]) for buildfile in BuildFile.scan_buildfiles(self._root_dir, os.path.join(self._root_dir, dir)): for address in Target.get_all_addresses(buildfile): yield address elif spec.endswith(':'): dir = self._get_dir(spec[:-len(':')]) for address in Target.get_all_addresses(BuildFile(self._root_dir, dir)): yield address else: yield Address.parse(self._root_dir, spec)
def _coerce_to_targets(cls, from_str, to_str): if isinstance(from_str, Compatibility.string): if not isinstance(to_str, Compatibility.string): raise TaskError('Finding paths from string %s to non-string %s' % (from_str, str(to_str))) from_address = Address.parse(get_buildroot(), from_str) to_address = Address.parse(get_buildroot(), to_str) from_target = Target.get(from_address) to_target = Target.get(to_address) if not from_target: raise TaskError('Target %s doesn\'t exist' % from_address.reference()) if not to_target: raise TaskError('Target %s doesn\'t exist' % to_address.reference()) return from_target, to_target elif isinstance(to_str, Compatibility.string): raise TaskError('Finding paths from string %s to non-string %s' % (to_str, str(from_str))) return from_str, to_str
def __init__(self, run_tracker, root_dir, parser, argv): Command.__init__(self, run_tracker, root_dir, parser, argv) if not self.args: self.error("A spec argument is required") self.config = Config.load() self.interpreter_cache = PythonInterpreterCache(self.config, logger=self.debug) self.interpreter_cache.setup() interpreters = self.interpreter_cache.select_interpreter( list( self.interpreter_cache.matches( [self.options. interpreter] if self.options.interpreter else ['']))) if len(interpreters) != 1: self.error('Unable to detect suitable interpreter.') else: self.debug('Selected %s' % interpreters[0]) self.interpreter = interpreters[0] try: specs_end = self.args.index('--') if len(self.args) > specs_end: self.build_args = self.args[specs_end + 1:len(self.args) + 1] else: self.build_args = [] except ValueError: specs_end = 1 self.build_args = self.args[1:] if len(self.args) > 1 else [] self.targets = OrderedSet() for spec in self.args[0:specs_end]: try: address = Address.parse(root_dir, spec) except: self.error("Problem parsing spec %s: %s" % (spec, traceback.format_exc())) try: target = Target.get(address) except: self.error("Problem parsing BUILD target %s: %s" % (address, traceback.format_exc())) if not target: self.error("Target %s does not exist" % address) self.targets.update(tgt for tgt in target.resolve() if tgt.is_concrete)
def __init__(self, run_tracker, root_dir, parser, argv): Command.__init__(self, run_tracker, root_dir, parser, argv) if not self.args: self.error("A spec argument is required") self._config = Config.load() self._root = root_dir address = Address.parse(root_dir, self.args[0]) self.target = Target.get(address) if self.target is None: self.error('%s is not a valid target!' % self.args[0]) if not self.target.provides: self.error('Target must provide an artifact.')
def _run_lint(self, target, args): chroot = PythonChroot(target, self.root_dir, extra_targets=[ Target.get(Address.parse(self.root_dir, '3rdparty/python:pylint'))], conn_timeout=self._conn_timeout) chroot.builder.info.ignore_errors = True builder = chroot.dump() builder.info.entry_point = 'pylint.lint' builder.freeze() interpreter_args = [ '--rcfile=%s' % os.path.join(self.root_dir, 'build-support', 'pylint', 'pylint.rc')] interpreter_args.extend(args or []) sources = OrderedSet([]) target.walk(lambda trg: sources.update( trg.sources if hasattr(trg, 'sources') and trg.sources is not None else [])) pex = PEX(builder.path()) pex.run(args=interpreter_args + list(sources), with_chroot=True)
def __init__(self, run_tracker, root_dir, parser, argv): Command.__init__(self, run_tracker, root_dir, parser, argv) if not self.args: self.error("A spec argument is required") self.config = Config.load() self.interpreter_cache = PythonInterpreterCache(self.config, logger=self.debug) self.interpreter_cache.setup() interpreters = self.interpreter_cache.select_interpreter( list(self.interpreter_cache.matches([self.options.interpreter] if self.options.interpreter else ['']))) if len(interpreters) != 1: self.error('Unable to detect suitable interpreter.') else: self.debug('Selected %s' % interpreters[0]) self.interpreter = interpreters[0] try: specs_end = self.args.index('--') if len(self.args) > specs_end: self.build_args = self.args[specs_end+1:len(self.args)+1] else: self.build_args = [] except ValueError: specs_end = 1 self.build_args = self.args[1:] if len(self.args) > 1 else [] self.targets = OrderedSet() for spec in self.args[0:specs_end]: try: address = Address.parse(root_dir, spec) except: self.error("Problem parsing spec %s: %s" % (spec, traceback.format_exc())) try: target = Target.get(address) except: self.error("Problem parsing BUILD target %s: %s" % (address, traceback.format_exc())) if not target: self.error("Target %s does not exist" % address) self.targets.update(tgt for tgt in target.resolve() if tgt.is_concrete)
def parse_jarcoordinate(coordinate): components = coordinate.split('#', 1) if len(components) == 2: org, name = components return org, name else: try: address = Address.parse(get_buildroot(), coordinate) try: target = Target.get(address) if not target: siblings = Target.get_all_addresses(address.buildfile) prompt = 'did you mean' if len(siblings) == 1 else 'maybe you meant one of these' raise TaskError('%s => %s?:\n %s' % (address, prompt, '\n '.join(str(a) for a in siblings))) if not target.is_exported: raise TaskError('%s is not an exported target' % coordinate) return target.provides.org, target.provides.name except (ImportError, SyntaxError, TypeError): raise TaskError('Failed to parse %s' % address.buildfile.relpath) except IOError: raise TaskError('No BUILD file could be found at %s' % coordinate)
def _run_lint(self, target, args): chroot = PythonChroot(target, self.root_dir, extra_targets=[ Target.get( Address.parse(self.root_dir, '3rdparty/python:pylint')) ], conn_timeout=self._conn_timeout) chroot.builder.info.ignore_errors = True builder = chroot.dump() builder.info.entry_point = 'pylint.lint' builder.freeze() interpreter_args = [ '--rcfile=%s' % os.path.join(self.root_dir, 'build-support', 'pylint', 'pylint.rc') ] interpreter_args.extend(args or []) sources = OrderedSet([]) target.walk(lambda trg: sources.update(trg.sources if hasattr( trg, 'sources') and trg.sources is not None else [])) pex = PEX(builder.path()) pex.run(args=interpreter_args + list(sources), with_chroot=True)
def __init__(self, run_tracker, root_dir, parser, argv): Command.__init__(self, run_tracker, root_dir, parser, argv) self.target = None self.extra_targets = [] self.config = Config.load() self.interpreter_cache = PythonInterpreterCache(self.config, logger=self.debug) self.interpreter_cache.setup() interpreters = self.interpreter_cache.select_interpreter( list( self.interpreter_cache.matches( [self.options. interpreter] if self.options.interpreter else ['']))) if len(interpreters) != 1: self.error('Unable to detect suitable interpreter.') self.interpreter = interpreters[0] for req in self.options.extra_requirements: with ParseContext.temp(): self.extra_targets.append(PythonRequirement(req, use_2to3=True)) # We parse each arg in the context of the cli usage: # ./pants command (options) [spec] (build args) # ./pants command (options) [spec]... -- (build args) # Our command token and our options are parsed out so we see args of the form: # [spec] (build args) # [spec]... -- (build args) binaries = [] for k in range(len(self.args)): arg = self.args.pop(0) if arg == '--': break def not_a_target(debug_msg): self.debug('Not a target, assuming option: %s.' % e) # We failed to parse the arg as a target or else it was in valid address format but did not # correspond to a real target. Assume this is the 1st of the build args and terminate # processing args for target addresses. self.args.insert(0, arg) target = None try: address = Address.parse(root_dir, arg) target = Target.get(address) if target is None: not_a_target(debug_msg='Unrecognized target') break except Exception as e: not_a_target(debug_msg=e) break for resolved in filter(lambda t: t.is_concrete, target.resolve()): if isinstance(resolved, PythonBinary): binaries.append(resolved) else: self.extra_targets.append(resolved) if len(binaries) == 0: # treat as a chroot pass elif len(binaries) == 1: # We found a binary and are done, the rest of the args get passed to it self.target = binaries[0] else: self.error( 'Can only process 1 binary target, %s contains %d:\n\t%s' % (arg, len(binaries), '\n\t'.join( str(binary.address) for binary in binaries))) if self.target is None: if not self.extra_targets: self.error('No valid target specified!') self.target = self.extra_targets.pop(0)
def __init__(self, run_tracker, root_dir, parser, argv): Command.__init__(self, run_tracker, root_dir, parser, argv) self.target = None self.extra_targets = [] self.config = Config.load() self.interpreter_cache = PythonInterpreterCache(self.config, logger=self.debug) self.interpreter_cache.setup() interpreters = self.interpreter_cache.select_interpreter( list(self.interpreter_cache.matches([self.options.interpreter] if self.options.interpreter else ['']))) if len(interpreters) != 1: self.error('Unable to detect suitable interpreter.') self.interpreter = interpreters[0] for req in self.options.extra_requirements: with ParseContext.temp(): self.extra_targets.append(PythonRequirement(req, use_2to3=True)) # We parse each arg in the context of the cli usage: # ./pants command (options) [spec] (build args) # ./pants command (options) [spec]... -- (build args) # Our command token and our options are parsed out so we see args of the form: # [spec] (build args) # [spec]... -- (build args) binaries = [] for k in range(len(self.args)): arg = self.args.pop(0) if arg == '--': break def not_a_target(debug_msg): self.debug('Not a target, assuming option: %s.' % e) # We failed to parse the arg as a target or else it was in valid address format but did not # correspond to a real target. Assume this is the 1st of the build args and terminate # processing args for target addresses. self.args.insert(0, arg) target = None try: address = Address.parse(root_dir, arg) target = Target.get(address) if target is None: not_a_target(debug_msg='Unrecognized target') break except Exception as e: not_a_target(debug_msg=e) break for resolved in filter(lambda t: t.is_concrete, target.resolve()): if isinstance(resolved, PythonBinary): binaries.append(resolved) else: self.extra_targets.append(resolved) if len(binaries) == 0: # treat as a chroot pass elif len(binaries) == 1: # We found a binary and are done, the rest of the args get passed to it self.target = binaries[0] else: self.error('Can only process 1 binary target, %s contains %d:\n\t%s' % ( arg, len(binaries), '\n\t'.join(str(binary.address) for binary in binaries) )) if self.target is None: if not self.extra_targets: self.error('No valid target specified!') self.target = self.extra_targets.pop(0)
def locate(self): parse_context = ParseContext.locate() return Address(parse_context.buildfile, self.name)
def test_parse_from_root_dir(self): with self.workspace('a/b/c/BUILD') as root_dir: self.assertAddress(root_dir, 'a/b/c/BUILD', 'c', Address.parse(root_dir, 'a/b/c', is_relative=False)) self.assertAddress(root_dir, 'a/b/c/BUILD', 'c', Address.parse(root_dir, 'a/b/c', is_relative=True))