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 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 add_targets(self, error, dir, buildfile): try: self.targets.extend(Target.get(addr) for addr in Target.get_all_addresses(buildfile)) except (TypeError, ImportError): error(dir, include_traceback=True) except (IOError, SyntaxError): error(dir)
def _find_paths(cls, from_target, to_target, log, find_all): from_target, to_target = cls._coerce_to_targets(from_target, to_target) log.debug('Looking for path from %s to %s' % (from_target.address.reference(), to_target.address.reference())) paths_found = False queue = [([from_target], 0)] while True: if not queue: if not paths_found: print 'no path found from %s to %s!' % (from_target.address.reference(), to_target.address.reference()) break path, indent = queue.pop(0) next_target = path[-1] log.debug('%sexamining %s' % (' ' * indent, next_target)) if next_target == to_target: if paths_found: print '' else: paths_found = True for target in path: print '%s' % target.address.reference() if find_all: continue else: break if hasattr(next_target, 'dependency_addresses'): for address in next_target.dependency_addresses: dep = Target.get(address) queue.append((path + [dep], indent + 1))
def execute(self): for buildfile in BuildFile.scan_buildfiles(self.root_dir): for address in Target.get_all_addresses(buildfile): target = Target.get(address) if hasattr(target, 'sources') and target.sources is not None: for sourcefile in target.sources: print sourcefile, address
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 is_exported(target): 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 configure_target(target): if target not in analyzed: analyzed.add(target) self.has_scala = self.has_scala or is_scala(target) if isinstance(target, JavaLibrary) or isinstance(target, ScalaLibrary): # TODO(John Sirois): this does not handle test resources, make test resources 1st class # in ant build and punch this through to pants model resources = set() if target.resources: resources.update(target.resources) if target.binary_resources: resources.update(target.binary_resources) if resources: self.resource_extensions.update(Project.extract_resource_extensions(resources)) configure_source_sets(ExportableJvmLibrary.RESOURCES_BASE_DIR, resources, is_test = False) if target.sources: test = is_test(target) self.has_tests = self.has_tests or test configure_source_sets(target.target_base, target.sources, is_test = test) siblings = Target.get_all_addresses(target.address.buildfile) return filter(accept_target, [ Target.get(a) for a in siblings if a != target.address ])
def __init__(self, root_dir, parser, argv): Command.__init__(self, root_dir, parser, argv) if not self.args: self.error("A spec argument is required") targets = [] # TODO(wickman) Ignore the -- crap for k in range(len(self.args)): arg = self.args[0] if arg == '--': self.args.pop(0) break try: address = Address.parse(root_dir, arg) target = Target.get(address) except Exception as e: break if not target: break targets.append(target) self.args.pop(0) # stop at PythonBinary target if isinstance(target, PythonBinary): break self.target = targets.pop(0) if targets else None self.extra_targets = targets if self.target is None: self.error('No valid target specified!')
def resolve(self): # De-reference this pants pointer to an actual parsed target. resolved = Target.get(self.address) if not resolved: raise KeyError("Failed to find target for: %s" % self.address) for dep in resolved.resolve(): yield dep
def __init__(self, root_dir, parser, argv): Command.__init__(self, root_dir, parser, argv) if not self.args: self.error("A spec argument is required") 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())) raise try: target = Target.get(address) except: self.error("Problem parsing BUILD target %s: %s" % (address, traceback.format_exc())) raise if not target: self.error("Target %s does not exist" % address) self.targets.add(target)
def _find_path(cls, from_target, to_target, log): from_target, to_target = cls._coerce_to_targets(from_target, to_target) log.debug('Looking for path from %s to %s' % (from_target.address.reference(), to_target.address.reference())) queue = [([from_target], 0)] while True: if not queue: print('no path found from %s to %s!' % (from_target.address.reference(), to_target.address.reference())) break path, indent = queue.pop(0) next_target = path[-1] if next_target in cls.examined_targets: continue cls.examined_targets.add(next_target) log.debug('%sexamining %s' % (' ' * indent, next_target)) if next_target == to_target: print('') for target in path: print('%s' % target.address.reference()) break if hasattr(next_target, 'dependency_addresses'): for address in next_target.dependency_addresses: dep = Target.get(address) queue.append((path + [dep], indent + 1))
def __init__(self, root_dir, parser, argv): Command.__init__(self, root_dir, parser, argv) if not self.args: self.error("A spec argument is required") targets = [] for k in range(len(self.args)): arg = self.args[0] if arg == '--': self.args.pop(0) break try: address = Address.parse(root_dir, arg) target = Target.get(address) except Exception as e: break if not target: break targets.append(target) self.args.pop(0) # stop at PythonBinary target if isinstance(target, PythonBinary): break self.target = targets.pop(0) if targets else None self.extra_targets = targets if self.target is None: self.error('No valid target specified!')
def _parse_targets(self, targets, root_dir): for spec in self.args: 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 target %s: %s" % (address, traceback.format_exc())) if address.is_meta: print("target is meta") target = target.do_in_context(lambda: bang.extract_target([target], None)) if not IvyResolve._is_resolvable(target): self.error("Target: %s is not resolvable" % address) targets.add(target) if not self.intransitive: def add_targets(ttarget): if hasattr(ttarget, 'internal_dependencies'): for dep in ttarget.internal_dependencies: if IvyResolve._is_resolvable(dep): targets.add(dep) else: print("skipping %s as it's not ivy resolvable" % dep.name) target.walk(add_targets) return targets
def __init__(self, root_dir, parser, argv): Command.__init__(self, root_dir, parser, argv) self.project_name = self.options.project_name addresses = self._parse_addresses( ) if self.args else Command.scan_addresses(root_dir) self.targets = [Target.get(address) for address in addresses]
def __init__(self, root_dir, parser, argv): Command.__init__(self, root_dir, parser, argv) if not self.args: self.error("A spec argument is required") 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 is_concrete(tgt))
def __init__(self, root_dir, parser, argv): Command.__init__(self, root_dir, parser, argv) self.project_name = self.options.project_name self.scala_compiler_profile = self.scala_compiler_profile_by_version[self.options.scala_version] addresses = self._parse_addresses() if self.args else Command.scan_addresses(root_dir) self.targets = [ Target.get(address) for address in addresses ]
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 __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.target = None self.extra_targets = [] # 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) for k in range(len(self.args)): arg = self.args.pop(0) if arg == '--': break target = None try: address = Address.parse(root_dir, arg) target = Target.get(address) except Exception: pass if not target: # 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. break binaries = [] concrete_targets = [t for t in target.resolve() if t.is_concrete] for resolved in concrete_targets: if isinstance(resolved, PythonBinary): binaries.append(resolved) else: self.extra_targets.append(resolved) if not binaries: # No binary encountered yet so move on to the next spec to find one or else accumulate more # libraries for ./pants py -> interpreter mode. 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] break 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) if not self.args: self.error("A spec argument is required") self.target = None self.extra_targets = [] # 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) for k in range(len(self.args)): arg = self.args.pop(0) if arg == '--': break target = None try: address = Address.parse(root_dir, arg) target = Target.get(address) except Exception: pass if not target: # 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. break binaries = [] for resolved in filter(is_concrete, target.resolve()): if isinstance(resolved, PythonBinary): binaries.append(resolved) else: self.extra_targets.append(resolved) if not binaries: # No binary encountered yet so move on to the next spec to find one or else accumulate more # libraries for ./pants py -> interpreter mode. 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] break 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 parse(self, spec): """Parses the given target spec into one or more targets. Returns a generator of target, address pairs in which the target may be None if the address points to a non-existent target. """ for address in self._parse_addresses(spec): target = Target.get(address) yield target, address
def _find_targets(self): if len(self.context.target_roots) > 0: for target in self.context.target_roots: yield target else: for buildfile in BuildFile.scan_buildfiles(get_buildroot()): target_addresses = Target.get_all_addresses(buildfile) for target_address in target_addresses: yield Target.get(target_address)
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_pytest_eggs(root): specs = ["3rdparty/python:pytest", "3rdparty/python:py"] eggs = [] for spec in specs: address = Address.parse(root, spec) target = Target.get(address) for dep in target.dependencies: for egg in dep.eggs: eggs.append(egg) return eggs
def parse_url(spec): match = MarkdownToHtml.PANTS_LINK.match(spec) if match: page = Target.get(Address.parse(get_buildroot(), match.group(1))) if not page: raise TaskError('Invalid link %s' % match.group(1)) alias, url = url_builder(page, config=get_config(page)) return alias, url else: return spec, spec
def execute(self, expanded_target_addresses): buildroot = get_buildroot() if len(self.context.target_roots) > 0: for target in self.context.target_roots: self._execute_target(target, buildroot) else: for buildfile in BuildFile.scan_buildfiles(buildroot): target_addresses = Target.get_all_addresses(buildfile) for target_address in target_addresses: target = Target.get(target_address) self._execute_target(target, buildroot)
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 execute(self): target = Target.get(self.address) if is_java(target): if self.is_graph: self._print_digraph(target) else: self._print_dependency_tree(target) elif is_python(target): if self.is_internal_only or self.is_external_only or self.is_minimal or self.is_graph: print >> sys.stderr, 'Unsupported option for Python target' sys.exit(1) self._print_python_dependencies(target, 0)
def execute(self): target = Target.get(self.address) if all(is_jvm(t) for t in target.resolve()): if self.is_graph: self._print_digraph(target) else: self._print_dependency_tree(target) elif is_python(target): if self.is_internal_only or self.is_external_only or self.is_minimal or self.is_graph: print('Unsupported option for Python target', file=sys.stderr) sys.exit(1) self._print_python_dependencies(target, 0)
def configure_target(target): if target not in analyzed: analyzed.add(target) self.has_scala = self.has_scala or is_scala(target) if isinstance(target, JavaLibrary) or isinstance( target, ScalaLibrary): # TODO(John Sirois): this does not handle test resources, make test resources 1st class # in ant build and punch this through to pants model resources = set() if target.resources: resources.update(target.resources) if target.binary_resources: resources.update(target.binary_resources) if resources: self.resource_extensions.update( Project.extract_resource_extensions(resources)) configure_source_sets( ExportableJvmLibrary.RESOURCES_BASE_DIR, resources, is_test=False) if target.sources: test = is_test(target) self.has_tests = self.has_tests or test configure_source_sets(target.target_base, target.sources, is_test=test) # Other BUILD files may specify sources in the same directory as this target. Those BUILD # files might be in parent directories (globs('a/b/*.java')) or even children directories if # this target globs children as well. Gather all these candidate BUILD files to test for # sources they own that live in the directories this targets sources live in. target_dirset = find_source_basedirs(target) candidates = Target.get_all_addresses(target.address.buildfile) for ancestor in target.address.buildfile.ancestors(): candidates.update(Target.get_all_addresses(ancestor)) for sibling in target.address.buildfile.siblings(): candidates.update(Target.get_all_addresses(sibling)) for descendant in target.address.buildfile.descendants(): candidates.update(Target.get_all_addresses(descendant)) def is_sibling(target): return source_target( target) and target_dirset.intersection( find_source_basedirs(target)) return filter( is_sibling, [Target.get(a) for a in candidates if a != target.address])
def _run_lint(self, target, args): chroot = PythonChroot(target, self.root_dir, extra_targets=[ Target.get(Address.parse(self.root_dir, '3rdparty/python:pylint'))]) 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, context): ConsoleTask.__init__(self, context) self._print_uptodate = context.options.check_deps_print_uptodate self.repos = context.config.getdict('jar-publish', 'repos') self._artifacts_to_targets = {} all_addresses = (address for buildfile in BuildFile.scan_buildfiles(get_buildroot()) for address in Target.get_all_addresses(buildfile)) for address in all_addresses: target = Target.get(address) if target.is_exported: provided_jar, _, _ = target.get_artifact_info() artifact = (provided_jar.org, provided_jar.name) if not artifact in self._artifacts_to_targets: self._artifacts_to_targets[artifact] = target
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") 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.') self.dependencies = self.minified_dependencies(self.target)
def __init__(self, root_dir, parser, argv): Command.__init__(self, root_dir, parser, argv) if not self.args: self.error("A spec argument is required") try: address = Address.parse(root_dir, self.args[0]) target = Target.get(address) except: self.error("Invalid target in %s" % self.args[0]) if not target: self.error("Target %s does not exist" % address) self.target = target self.args.pop(0)
def __init__(self, root_dir, parser, argv): Command.__init__(self, root_dir, parser, argv) if not self.args: self.error("A spec argument is required") try: address = Address.parse(root_dir, self.args[0]) target = Target.get(address) except Exception as e: self.error("Invalid target in %s (%s)" % (self.args[0], str(e))) if not target: self.error("Target %s does not exist" % address) self.target = target self.args.pop(0)
def __init__(self, root_dir, parser, argv): Command.__init__(self, root_dir, parser, argv) if not self.args: self.error("A spec argument is required") 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.') self.dependencies = self.minified_dependencies(self.target)
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 _find_paths_rec(cls, from_target, to_target): if from_target == to_target: return [[from_target]] if from_target not in cls.all_paths or to_target not in cls.all_paths[from_target]: paths = [] if hasattr(from_target, 'dependency_addresses'): for address in from_target.dependency_addresses: dep = Target.get(address) for path in cls._find_paths_rec(dep, to_target): new_path = copy.copy(path) new_path.insert(0, from_target) paths.append(new_path) cls.all_paths[from_target][to_target] = paths return cls.all_paths[from_target][to_target]
def __init__(self, root_dir, parser, argv): Command.__init__(self, root_dir, parser, argv) if not self.args: self.error("A spec argument is required") try: specs_end = self.args.index('--') if len(self.args) > specs_end: self.build_args = self.args.__getslice__( 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.__getslice__(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())) try: InternalTarget.check_cycles(target) except CycleException as e: self.error("Target contains an internal dependency cycle: %s" % e) if not target: self.error("Target %s does not exist" % address) if not target.address.is_meta: target.address.is_meta = self.options.is_meta or address.is_meta self.targets.add(target) self.is_ide = self.options.is_ide self.ide_transitivity = self.options.ide_transitivity
def get_pytest_eggs(root): specs = ["3rdparty/python:pytest"] eggs = [] for spec in specs: address = Address.parse(root, spec) target = Target.get(address) def add_eggs(target): deps = [] for dep in target.dependencies: if isinstance(dep, PythonEgg): for egg in dep.eggs: eggs.append(egg) else: deps.append(dep) return deps target.walk(lambda t: add_eggs(t)) return eggs
def _run_lint(self, target, args): lint_target = Target.get(Address.parse(self.root_dir, self._opts['lint_target'])) assert lint_target, 'Could not find target %r' % self._opts['lint_target'] chroot = PythonChroot(target, self.root_dir, extra_targets=[lint_target], conn_timeout=self._conn_timeout) chroot.builder.info().ignore_errors = True builder = chroot.dump() builder.info().entry_point = self._opts['entry_point'] builder.info().run_name = 'main' builder.freeze() interpreter_args = self._opts['interpreter_args'] 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 _parse_targets(self, root_dir): targets = OrderedSet() for spec in self.args: 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 target %s: %s" % (address, traceback.format_exc())) if not Doc._is_documentable(target): self.error("Target: %s is not documentable" % address) targets.add(target) return targets
def __init__(self, root_dir, parser, argv): Command.__init__(self, root_dir, parser, argv) if len(self.args) is not 1: self.error("Exactly one BUILD address is required.") spec = self.args[0] try: address = Address.parse(root_dir, spec) except IOError: self.error("Problem parsing spec %s: %s" % (spec, traceback.format_exc())) try: self.target = Target.get(address) except (ImportError, SyntaxError, TypeError): self.error("Problem parsing BUILD target %s: %s" % (address, traceback.format_exc())) if not self.target: self.error("Target %s does not exist" % address)