コード例 #1
0
    def test_build_files_scan_with_relpath_ignore(self):
        buildfiles = self.scan_buildfiles("",
                                          build_ignore_patterns=[
                                              "grandparent/parent/child1",
                                              "grandparent/parent/child2"
                                          ])
        self.assertEqual(
            OrderedSet([
                self.create_buildfile("BUILD"),
                self.create_buildfile("BUILD.twitter"),
                self.create_buildfile("grandparent/parent/BUILD"),
                self.create_buildfile("grandparent/parent/BUILD.twitter"),
                self.create_buildfile("grandparent/parent/child5/BUILD"),
                self.create_buildfile("issue_1742/BUILD.sibling"),
            ]),
            buildfiles,
        )

        buildfiles = self.scan_buildfiles(
            "grandparent/parent",
            build_ignore_patterns=["grandparent/parent/child1"])
        self.assertEqual(
            OrderedSet([
                self.create_buildfile("grandparent/parent/BUILD"),
                self.create_buildfile("grandparent/parent/BUILD.twitter"),
                self.create_buildfile(
                    "grandparent/parent/child2/child3/BUILD"),
                self.create_buildfile("grandparent/parent/child5/BUILD"),
            ]),
            buildfiles,
        )
コード例 #2
0
    def test_target_types(self):
        def target_types():
            return [DummyTarget, DummyTarget2]

        with self.create_register(
                target_types=target_types) as backend_package:
            load_backend(self.build_configuration,
                         backend_package,
                         is_v1_backend=True)
            assert self.build_configuration.target_types() == OrderedSet(
                [DummyTarget, DummyTarget2])

            load_backend(self.build_configuration,
                         backend_package,
                         is_v1_backend=False)
            assert self.build_configuration.target_types() == OrderedSet(
                [DummyTarget, DummyTarget2])

        class PluginTarget(Target):
            alias = "plugin_tgt"
            core_fields = ()

        def plugin_targets():
            return [PluginTarget]

        self.working_set.add(
            self.get_mock_plugin("new-targets",
                                 "0.0.1",
                                 target_types=plugin_targets))
        self.load_plugins(["new-targets"], is_v1_plugin=True)
        assert self.build_configuration.target_types() == OrderedSet(
            [DummyTarget, DummyTarget2, PluginTarget])
        self.load_plugins(["new-targets"], is_v1_plugin=False)
        assert self.build_configuration.target_types() == OrderedSet(
            [DummyTarget, DummyTarget2, PluginTarget])
コード例 #3
0
ファイル: rules.py プロジェクト: nadeemnazeer/pants
    def create(cls, rule_entries) -> RuleIndex:
        """Creates a RuleIndex with tasks indexed by their output type."""
        rules: OrderedSet[TaskRule] = OrderedSet()
        queries: OrderedSet[QueryRule] = OrderedSet()
        union_rules: OrderedSet[UnionRule] = OrderedSet()

        for entry in rule_entries:
            if isinstance(entry, TaskRule):
                rules.add(entry)
            elif isinstance(entry, UnionRule):
                union_rules.add(entry)
            elif isinstance(entry, QueryRule):
                queries.add(entry)
            elif hasattr(entry, "__call__"):
                rule = getattr(entry, "rule", None)
                if rule is None:
                    raise TypeError(
                        f"Expected function {entry} to be decorated with @rule."
                    )
                rules.add(rule)
            else:
                raise TypeError(
                    f"Rule entry {entry} had an unexpected type: {type(entry)}. Rules either "
                    "extend Rule or UnionRule, or are static functions decorated with @rule."
                )

        return RuleIndex(
            rules=FrozenOrderedSet(rules),
            queries=FrozenOrderedSet(queries),
            union_rules=FrozenOrderedSet(union_rules),
        )
コード例 #4
0
async def resolve_targets(targets: UnexpandedTargets) -> Targets:
    # TODO: This method duplicates `resolve_targets_with_origins`, because direct expansion of
    # `Addresses` to `Targets` is common in a few places: we can't always assume that we
    # have `AddressesWithOrigins`. One way to dedupe these two methods would be to fake some
    # origins, and then strip them afterward.

    # Split out and expand any base targets.
    # TODO: Should recursively expand alias targets here as well.
    other_targets = []
    base_targets = []
    for target in targets:
        if target.address.is_base_target:
            base_targets.append(target)
        else:
            other_targets.append(target)

    base_targets_subtargets = await MultiGet(
        Get(Subtargets, Address, bt.address) for bt in base_targets)
    # Zip the subtargets back to the base targets and replace them.
    # NB: If a target had no subtargets, we use the base.
    expanded_targets = OrderedSet(other_targets)
    expanded_targets.update(
        target for subtargets in base_targets_subtargets
        for target in (subtargets.subtargets if subtargets.subtargets else (
            subtargets.base, )))
    return Targets(expanded_targets)
コード例 #5
0
ファイル: test_union_products.py プロジェクト: wiwa/pants
    def test_copy(self):
        c = self.make_target("c")
        b = self.make_target("b", dependencies=[c])
        a = self.make_target("a", dependencies=[b, c])
        self.products.add_for_target(a, [1])
        self.products.add_for_target(b, [2])

        copied = self.products.copy()

        self.assertEqual(self.products.get_for_targets(a.closure(bfs=True)),
                         OrderedSet([1, 2]))
        self.assertEqual(self.products.get_for_targets(b.closure(bfs=True)),
                         OrderedSet([2]))
        self.assertEqual(copied.get_for_targets(a.closure(bfs=True)),
                         OrderedSet([1, 2]))
        self.assertEqual(copied.get_for_targets(b.closure(bfs=True)),
                         OrderedSet([2]))

        copied.add_for_target(c, [3])

        self.assertEqual(self.products.get_for_targets(a.closure(bfs=True)),
                         OrderedSet([1, 2]))
        self.assertEqual(self.products.get_for_targets(b.closure(bfs=True)),
                         OrderedSet([2]))
        self.assertEqual(self.products.get_for_targets(c.closure(bfs=True)),
                         OrderedSet())
        self.assertEqual(copied.get_for_targets(a.closure(bfs=True)),
                         OrderedSet([1, 2, 3]))
        self.assertEqual(copied.get_for_targets(b.closure(bfs=True)),
                         OrderedSet([2, 3]))
        self.assertEqual(copied.get_for_targets(c.closure(bfs=True)),
                         OrderedSet([3]))
コード例 #6
0
ファイル: pex_from_targets_test.py プロジェクト: hephex/pants
 def get_pex_request(
         constraints_file: str | None,
         resolve_all_constraints: bool | None,
         *,
         direct_deps_only: bool = False,
         additional_args: Iterable[str] = (),
         additional_lockfile_args: Iterable[str] = (),
 ) -> PexRequest:
     args = ["--backend-packages=pants.backend.python"]
     request = PexFromTargetsRequest(
         [Address("", target_name="app")],
         output_filename="demo.pex",
         internal_only=True,
         direct_deps_only=direct_deps_only,
         additional_args=additional_args,
         additional_lockfile_args=additional_lockfile_args,
     )
     if resolve_all_constraints is not None:
         args.append(
             f"--python-resolve-all-constraints={resolve_all_constraints!r}"
         )
     if constraints_file:
         args.append(f"--python-requirement-constraints={constraints_file}")
     args.append("--python-repos-indexes=[]")
     args.append(f"--python-repos-repos={find_links}")
     rule_runner.set_options(args, env_inherit={"PATH"})
     pex_request = rule_runner.request(PexRequest, [request])
     assert OrderedSet(additional_args).issubset(
         OrderedSet(pex_request.additional_args))
     return pex_request
コード例 #7
0
ファイル: dependencies.py プロジェクト: wiwa/pants
    def console_output(self, unused_method_argument):
        ordered_closure = OrderedSet()
        for target in self.context.target_roots:
            if self.act_transitively:
                target.walk(ordered_closure.add)
            else:
                ordered_closure.update(target.dependencies)

        include_source = self.get_options().type in [
            DependencyType.SOURCE,
            DependencyType.SOURCE_AND_THIRD_PARTY,
        ]
        include_3rdparty = self.get_options().type in [
            DependencyType.THIRD_PARTY,
            DependencyType.SOURCE_AND_THIRD_PARTY,
        ]
        for tgt in ordered_closure:
            if include_source:
                yield tgt.address.spec
            if include_3rdparty:
                # TODO(John Sirois): We need an external payload abstraction at which point knowledge
                # of jar and requirement payloads can go and this hairball will be untangled.
                if isinstance(tgt.payload.get_field("requirements"),
                              PythonRequirementsField):
                    for requirement in tgt.payload.requirements:
                        yield str(requirement.requirement)
                elif isinstance(tgt.payload.get_field("jars"), JarsField):
                    for jar in tgt.payload.jars:
                        data = dict(org=jar.org, name=jar.name, rev=jar.rev)
                        yield ("{org}:{name}:{rev}"
                               if jar.rev else "{org}:{name}").format(**data)
コード例 #8
0
    def parse_specs(
        cls,
        raw_specs: Iterable[str],
        build_root: Optional[str] = None,
        exclude_patterns: Optional[Iterable[str]] = None,
        tags: Optional[Iterable[str]] = None,
    ) -> Specs:
        """Parse raw string specs into a Specs object."""
        build_root = build_root or get_buildroot()
        spec_parser = CmdLineSpecParser(build_root)

        address_specs: OrderedSet[AddressSpec] = OrderedSet()
        filesystem_specs: OrderedSet[FilesystemSpec] = OrderedSet()
        for spec_str in raw_specs:
            parsed_spec = spec_parser.parse_spec(spec_str)
            if isinstance(parsed_spec, AddressSpec):
                address_specs.add(parsed_spec)
            else:
                filesystem_specs.add(parsed_spec)

        address_specs_collection = AddressSpecs(
            dependencies=address_specs,
            exclude_patterns=exclude_patterns if exclude_patterns else tuple(),
            tags=tags,
        )
        filesystem_specs_collection = FilesystemSpecs(filesystem_specs)
        return Specs(
            address_specs=address_specs_collection,
            filesystem_specs=filesystem_specs_collection,
        )
コード例 #9
0
ファイル: classpath_util.py プロジェクト: wisechengyi/pants
    def compute_classpath_entries(cls, targets, classpath_products,
                                  extra_classpath_tuples, confs):
        """Return the list of classpath entries for a classpath covering the passed targets.

        Filters and adds paths from extra_classpath_tuples to the end of the resulting list.

        :param targets: The targets to generate a classpath for.
        :param ClasspathProducts classpath_products: Product containing classpath elements.
        :param extra_classpath_tuples: Additional classpath entries as tuples of
          (string, ClasspathEntry).
        :param confs: The list of confs for use by this classpath.
        :returns: The classpath entries as a list of path elements.
        :rtype: list of ClasspathEntry
        """
        classpath_iter = cls._classpath_iter(
            classpath_products.get_classpath_entries_for_targets(targets),
            confs=confs,
        )
        total_classpath = OrderedSet(classpath_iter)

        filtered_extra_classpath_iter = cls._filtered_classpath_by_confs_iter(
            extra_classpath_tuples,
            confs,
        )
        extra_classpath_iter = cls._entries_iter(filtered_extra_classpath_iter)
        total_classpath.update(extra_classpath_iter)
        return list(total_classpath)
コード例 #10
0
ファイル: pex_build_util.py プロジェクト: wiwa/pants
    def resolve_distributions(
        self,
        reqs: List[PythonRequirement],
        platforms: Optional[List[Platform]] = None,
    ) -> Dict[str, List[Distribution]]:
        """Multi-platform dependency resolution.

        :param reqs: A list of :class:`PythonRequirement` to resolve.
        :param platforms: A list of platform strings to resolve requirements for.
                          Defaults to the platforms specified by PythonSetup.
        :returns: A tuple `(map, transitive_reqs)`, where `map` is a dict mapping distribution name
                  to a list of resolved distributions, and `reqs` contains all transitive ==
                  requirements
                  needed to resolve the initial given requirements `reqs` for the given platforms.
        """
        deduped_reqs = OrderedSet(reqs)
        find_links: OrderedSet[str] = OrderedSet()
        for req in deduped_reqs:
            self._log.debug(f"  Dumping requirement: {req}")
            self._builder.add_requirement(str(req.requirement))
            if req.repository:
                find_links.add(req.repository)

        # Resolve the requirements into distributions.
        distributions = self._resolve_multi(
            self._builder.interpreter,
            list(deduped_reqs),
            platforms,
            list(find_links),
        )
        return distributions
コード例 #11
0
 def test_suffix_only(self):
     self.makedirs("suffix-test")
     self.touch("suffix-test/BUILD.suffix")
     self.touch("suffix-test/BUILD.suffix2")
     self.makedirs("suffix-test/child")
     self.touch("suffix-test/child/BUILD.suffix3")
     buildfile = self.create_buildfile("suffix-test/BUILD.suffix")
     self.assertEqual(
         OrderedSet([
             buildfile,
             self.create_buildfile("suffix-test/BUILD.suffix2")
         ]),
         OrderedSet(self.get_build_files_family("suffix-test")),
     )
     self.assertEqual(
         OrderedSet([
             self.create_buildfile("suffix-test/BUILD.suffix"),
             self.create_buildfile("suffix-test/BUILD.suffix2"),
         ]),
         self.get_build_files_family("suffix-test"),
     )
     self.assertEqual(
         OrderedSet(
             [self.create_buildfile("suffix-test/child/BUILD.suffix3")]),
         self.scan_buildfiles("suffix-test/child"),
     )
コード例 #12
0
ファイル: round_engine.py プロジェクト: wiwa/pants
 def get_dependencies(self):
     """Returns the set of data dependencies as producer infos corresponding to data
     requirements."""
     producer_infos = OrderedSet()
     for product_type in self._dependencies:
         producer_infos.update(
             self._get_producer_infos_by_product_type(product_type))
     return producer_infos
コード例 #13
0
ファイル: test_build_graph.py プロジェクト: pyranja/pants
 def test_target_closure(self):
     a = self.make_target("a")
     self.assertEqual(OrderedSet([a]), a.closure())
     b = self.make_target("b", dependencies=[a])
     self.assertEqual(OrderedSet([b, a]), b.closure())
     c = self.make_target("c", dependencies=[b])
     self.assertEqual(OrderedSet([c, b, a]), c.closure())
     d = self.make_target("d", dependencies=[a, c])
     self.assertEqual(OrderedSet([d, a, c, b]), d.closure())
コード例 #14
0
ファイル: products.py プロジェクト: wiwa/pants
    def get_for_targets(self, targets):
        """Gets the union of the products for the given targets, preserving the input order.

        :API: public
        """
        products = OrderedSet()
        for target in targets:
            products.update(self._products_by_target[target])
        return products
コード例 #15
0
    def execute(self, **kwargs):
        # NB: kwargs are for testing and pass-through to underlying subprocess process spawning.

        go_targets = OrderedSet(target for target in self.context.target_roots
                                if self.is_go(target))
        args = self.get_passthru_args()
        if not go_targets or not args:
            template = yellow(
                "The pants `{goal}` goal expects at least one go target and at least one "
                "pass-through argument to be specified, call with:\n") + green(
                    "  ./pants {goal} {targets} -- {args}")
            msg = template.format(
                goal=self.options_scope,
                targets=(green(" ".join(t.address.reference()
                                        for t in go_targets))
                         if go_targets else red("[missing go targets]")),
                args=green(" ".join(args))
                if args else red("[missing pass-through args]"),
            )
            raise self.MissingArgsError(msg)

        go_path = OrderedSet()
        import_paths = OrderedSet()
        for target in go_targets:
            self.ensure_workspace(target)
            go_path.add(self.get_gopath(target))
            import_paths.add(target.import_path)

        self.execute_with_go_env(os.pathsep.join(go_path), list(import_paths),
                                 args, **kwargs)
コード例 #16
0
async def mypy_typecheck(
    request: MyPyRequest, mypy: MyPy, python_setup: PythonSetup
) -> TypecheckResults:
    if mypy.skip:
        return TypecheckResults([], typechecker_name="MyPy")

    # We batch targets by their interpreter constraints to ensure, for example, that all Python 2
    # targets run together and all Python 3 targets run together. We can only do this by setting
    # the `--python-version` option, but we allow the user to set it as a safety valve. We warn if
    # they've set the option.
    config_files = await Get(ConfigFiles, ConfigFilesRequest, mypy.config_request)
    config_content = await Get(DigestContents, Digest, config_files.snapshot.digest)
    python_version_configured = check_and_warn_if_python_version_configured(
        config=next(iter(config_content), None), args=mypy.args
    )

    # When determining how to batch by interpreter constraints, we must consider the entire
    # transitive closure to get the final resulting constraints.
    # TODO(#10863): Improve the performance of this.
    transitive_targets_per_field_set = await MultiGet(
        Get(TransitiveTargets, TransitiveTargetsRequest([field_set.address]))
        for field_set in request.field_sets
    )

    interpreter_constraints_to_transitive_targets = defaultdict(set)
    for transitive_targets in transitive_targets_per_field_set:
        interpreter_constraints = PexInterpreterConstraints.create_from_targets(
            transitive_targets.closure, python_setup
        ) or PexInterpreterConstraints(mypy.interpreter_constraints)
        interpreter_constraints_to_transitive_targets[interpreter_constraints].add(
            transitive_targets
        )

    partitions = []
    for interpreter_constraints, all_transitive_targets in sorted(
        interpreter_constraints_to_transitive_targets.items()
    ):
        combined_roots: OrderedSet[Target] = OrderedSet()
        combined_closure: OrderedSet[Target] = OrderedSet()
        for transitive_targets in all_transitive_targets:
            combined_roots.update(transitive_targets.roots)
            combined_closure.update(transitive_targets.closure)
        partitions.append(
            MyPyPartition(
                FrozenOrderedSet(combined_roots),
                FrozenOrderedSet(combined_closure),
                interpreter_constraints,
                python_version_already_configured=python_version_configured,
            )
        )

    partitioned_results = await MultiGet(
        Get(TypecheckResult, MyPyPartition, partition) for partition in partitions
    )
    return TypecheckResults(partitioned_results, typechecker_name="MyPy")
コード例 #17
0
def test_add() -> None:
    set1: OrderedSet[str] = OrderedSet()

    set1.add("a")
    assert set1 == OrderedSet("a")

    set1.add("b")
    assert set1 == OrderedSet("ab")

    set1.add("a")
    assert set1 == OrderedSet("ab")
コード例 #18
0
    def find_all_relevant_resources_targets(self):
        # NB: Ordering isn't relevant here, because it is applied during the dep walk to
        # consume from the runtime_classpath.
        def is_jvm_target(target):
            return isinstance(target, JvmTarget)

        jvm_targets = self.context.targets(predicate=is_jvm_target)

        all_resources_tgts = OrderedSet()
        for target in Target.closure_for_targets(jvm_targets, bfs=True):
            if isinstance(target, Resources):
                all_resources_tgts.add(target)
        return all_resources_tgts
コード例 #19
0
 def resolve_deps(self, unresolved_deps):
     """
     :API: public
     """
     deps = OrderedSet()
     for dep in unresolved_deps:
         try:
             deps.update(self.context.resolve(dep))
         except AddressLookupError as e:
             raise AddressLookupError(
                 "{message}\n  on dependency {dep}".format(message=e,
                                                           dep=dep))
     return deps
コード例 #20
0
    def parse_specs(self, specs: Iterable[str]) -> Specs:
        address_specs: OrderedSet[AddressSpec] = OrderedSet()
        filesystem_specs: OrderedSet[FilesystemSpec] = OrderedSet()
        for spec_str in specs:
            parsed_spec = self.parse_spec(spec_str)
            if isinstance(parsed_spec, AddressSpec):
                address_specs.add(parsed_spec)
            else:
                filesystem_specs.add(parsed_spec)

        return Specs(
            AddressSpecs(address_specs, filter_by_global_options=True),
            FilesystemSpecs(filesystem_specs),
        )
コード例 #21
0
    def test_build_files_family_lookup_2(self):
        self.assertEqual(
            OrderedSet([
                self.create_buildfile("grandparent/parent/BUILD"),
                self.create_buildfile("grandparent/parent/BUILD.twitter"),
            ]),
            self.get_build_files_family("grandparent/parent"),
        )

        buildfile = self.create_buildfile(
            "grandparent/parent/child2/child3/BUILD")
        self.assertEqual(
            OrderedSet([buildfile]),
            self.get_build_files_family("grandparent/parent/child2/child3"))
コード例 #22
0
ファイル: parse_search_dirs.py プロジェクト: wiwa/pants
    def _filter_existing_dirs(self, dir_candidates, compiler_exe):
        real_dirs = OrderedSet()

        for maybe_existing_dir in dir_candidates:
            # Could use a `seen_dir_paths` set if we want to avoid pinging the fs for duplicate entries.
            if is_readable_dir(maybe_existing_dir):
                real_dirs.add(os.path.realpath(maybe_existing_dir))
            else:
                logger.debug(
                    "non-existent or non-accessible directory at {} while "
                    "parsing directories from {}".format(
                        maybe_existing_dir, compiler_exe))

        return list(real_dirs)
コード例 #23
0
ファイル: context.py プロジェクト: wiwa/pants
    def _unfiltered_targets(self, **kwargs):
        def _collect_targets(root_targets, **kwargs):
            return Target.closure_for_targets(target_roots=root_targets,
                                              **kwargs)

        target_set = _collect_targets(self.target_roots, **kwargs)

        synthetics = OrderedSet()
        for synthetic_address in self.build_graph.synthetic_addresses:
            if self.build_graph.get_concrete_derived_from(
                    synthetic_address) in target_set:
                synthetics.add(self.build_graph.get_target(synthetic_address))
        target_set.update(_collect_targets(synthetics, **kwargs))

        return target_set
コード例 #24
0
ファイル: products.py プロジェクト: wiwa/pants
class RootedProducts:
    """File products of a build that have a concept of a 'root' directory.

    E.g., classfiles, under a root package directory.

    :API: public
    """
    def __init__(self, root):
        """
        :API: public
        """
        self._root = root
        self._rel_paths = OrderedSet()

    def add_abs_paths(self, abs_paths):
        """
        :API: public
        """
        for abs_path in abs_paths:
            self._rel_paths.add(fast_relpath(abs_path, self._root))

    def add_rel_paths(self, rel_paths):
        """
        :API: public
        """
        self._rel_paths.update(rel_paths)

    def root(self):
        """
        :API: public
        """
        return self._root

    def rel_paths(self):
        """
        :API: public
        """
        return self._rel_paths

    def abs_paths(self):
        """
        :API: public
        """
        for relpath in self._rel_paths:
            yield os.path.join(self._root, relpath)

    def __bool__(self):
        return self._rel_paths
コード例 #25
0
ファイル: rules.py プロジェクト: codealchemy/pants
async def infer_scala_dependencies_via_source_analysis(
    request: InferScalaSourceDependencies,
    scala_infer_subsystem: ScalaInferSubsystem,
    jvm: JvmSubsystem,
    first_party_symbol_map: FirstPartySymbolMapping,
    third_party_artifact_mapping: ThirdPartyPackageToArtifactMapping,
) -> InferredDependencies:
    if not scala_infer_subsystem.imports:
        return InferredDependencies([])

    address = request.sources_field.address
    wrapped_tgt = await Get(WrappedTarget, Address, address)
    tgt = wrapped_tgt.target
    explicitly_provided_deps, analysis = await MultiGet(
        Get(ExplicitlyProvidedDependencies, DependenciesRequest(tgt[Dependencies])),
        Get(ScalaSourceDependencyAnalysis, SourceFilesRequest([request.sources_field])),
    )

    symbols: OrderedSet[str] = OrderedSet()
    if scala_infer_subsystem.imports:
        symbols.update(analysis.all_imports())
    if scala_infer_subsystem.consumed_types:
        symbols.update(analysis.fully_qualified_consumed_symbols())

    resolve = tgt[JvmResolveField].normalized_value(jvm)

    dependencies: OrderedSet[Address] = OrderedSet()
    for symbol in symbols:
        first_party_matches = first_party_symbol_map.symbols.addresses_for_symbol(
            symbol, resolve=resolve
        )
        third_party_matches = third_party_artifact_mapping.addresses_for_symbol(symbol, resolve)
        matches = first_party_matches.union(third_party_matches)
        if not matches:
            continue

        explicitly_provided_deps.maybe_warn_of_ambiguous_dependency_inference(
            matches,
            address,
            import_reference="type",
            context=f"The target {address} imports `{symbol}`",
        )

        maybe_disambiguated = explicitly_provided_deps.disambiguated(matches)
        if maybe_disambiguated:
            dependencies.add(maybe_disambiguated)

    return InferredDependencies(dependencies)
コード例 #26
0
 def _compute_transitive_source_dependencies(
     self,
     target: Target,
     info_entry: Tuple[str, ...],
     modulizable_target_set: FrozenOrderedSet[Target],
 ) -> Tuple[str, ...]:
     if self._is_strict_deps(target):
         return info_entry
     else:
         transitive_targets = OrderedSet(info_entry)
         self.context.build_graph.walk_transitive_dependency_graph(
             addresses=[target.address],
             predicate=lambda d: d in modulizable_target_set,
             work=lambda d: transitive_targets.add(d.address.spec),
         )
         return tuple(transitive_targets)
コード例 #27
0
async def transitive_hydrated_targets(
        addresses: Addresses) -> TransitiveHydratedTargets:
    """Given Addresses, kicks off recursion on expansion of TransitiveHydratedTargets.

    The TransitiveHydratedTarget struct represents a structure-shared graph, which we walk and
    flatten here. The engine memoizes the computation of TransitiveHydratedTarget, so when multiple
    TransitiveHydratedTarget objects are being constructed for multiple roots, their structure will
    be shared.
    """

    transitive_hydrated_targets = await MultiGet(
        Get[TransitiveHydratedTarget](Address, a) for a in addresses)

    closure: OrderedSet[HydratedTarget] = OrderedSet()
    to_visit = deque(transitive_hydrated_targets)

    while to_visit:
        tht = to_visit.popleft()
        if tht.root in closure:
            continue
        closure.add(tht.root)
        to_visit.extend(tht.dependencies)

    return TransitiveHydratedTargets(
        tuple(tht.root for tht in transitive_hydrated_targets),
        FrozenOrderedSet(closure))
コード例 #28
0
async def infer_terraform_module_dependencies(
    request: InferTerraformModuleDependenciesRequest,
) -> InferredDependencies:
    hydrated_sources = await Get(HydratedSources,
                                 HydrateSourcesRequest(request.sources_field))

    paths = OrderedSet(filename for filename in hydrated_sources.snapshot.files
                       if filename.endswith(".tf"))
    result = await Get(
        ProcessResult,
        ParseTerraformModuleSources(
            sources_digest=hydrated_sources.snapshot.digest,
            paths=tuple(paths),
        ),
    )
    candidate_spec_paths = [
        line for line in result.stdout.decode("utf-8").split("\n") if line
    ]

    # For each path, see if there is a `terraform_module` target at the specified spec_path.
    candidate_targets = await Get(
        Targets,
        AddressSpecs([
            MaybeEmptySiblingAddresses(path) for path in candidate_spec_paths
        ]))
    # TODO: Need to either implement the standard ambiguous dependency logic or ban >1 terraform_module
    # per directory.
    terraform_module_addresses = [
        tgt.address for tgt in candidate_targets
        if tgt.has_field(TerraformModuleSourcesField)
    ]
    return InferredDependencies(terraform_module_addresses)
コード例 #29
0
ファイル: options.py プロジェクト: wisechengyi/pants
    def complete_scopes(
            cls,
            scope_infos: Iterable[ScopeInfo]) -> FrozenOrderedSet[ScopeInfo]:
        """Expand a set of scopes to include all enclosing scopes.

        E.g., if the set contains `foo.bar.baz`, ensure that it also contains `foo.bar` and `foo`.

        Also adds any deprecated scopes.
        """
        ret: OrderedSet[ScopeInfo] = OrderedSet()
        original_scopes: Dict[str, ScopeInfo] = {}
        for si in sorted(scope_infos, key=lambda si: si.scope):
            ret.add(si)
            if si.scope in original_scopes:
                raise cls.DuplicateScopeError(
                    "Scope `{}` claimed by {}, was also claimed by {}.".format(
                        si.scope, si, original_scopes[si.scope]))
            original_scopes[si.scope] = si
            if si.deprecated_scope:
                ret.add(
                    ScopeInfo(si.deprecated_scope, si.category,
                              si.optionable_cls))
                original_scopes[si.deprecated_scope] = si

        # TODO: Once scope name validation is enforced (so there can be no dots in scope name
        # components) we can replace this line with `for si in scope_infos:`, because it will
        # not be possible for a deprecated_scope to introduce any new intermediate scopes.
        for si in copy.copy(ret):
            for scope in all_enclosing_scopes(si.scope, allow_global=False):
                if scope not in original_scopes:
                    ret.add(ScopeInfo(scope, ScopeInfo.INTERMEDIATE))
        return FrozenOrderedSet(ret)
コード例 #30
0
    def test_binary_target_injected_into_reduced_dependencies(self):
        foo_bin_dep = self.create_python_library(relpath="foo/dep", name="dep")

        foo_bin = self.create_python_binary(relpath="foo/bin",
                                            name="bin",
                                            entry_point="foo.bin:foo",
                                            dependencies=["foo/dep"])

        foo = self.create_python_library(
            relpath="foo",
            name="foo",
            provides=dedent("""
                setup_py(
                    name='foo',
                    version='0.0.0'
                ).with_binaries(
                    foo_binary='foo/bin'
                )
                """),
        )

        self.assertEqual(self.dependency_calculator.reduced_dependencies(foo),
                         OrderedSet([foo_bin, foo_bin_dep]))
        entry_points = dict(SetupPy.iter_entry_points(foo))
        self.assertEqual(entry_points, {"foo_binary": "foo.bin:foo"})

        with self.run_execute(foo, recursive=False) as created:
            self.assertEqual([foo], list(created.keys()))

        with self.run_execute(foo, recursive=True) as created:
            self.assertEqual([foo], list(created.keys()))