コード例 #1
0
async def resolve_targets(
    targets: UnexpandedTargets,
    target_types_to_generate_requests: TargetTypesToGenerateTargetsRequests,
) -> Targets:
    # Replace all generating targets with what they generate. Otherwise, keep them. If a target
    # generator does not generate any targets, keep the target generator.
    # TODO: This method does not preserve the order of inputs.
    expanded_targets: OrderedSet[Target] = OrderedSet()
    generator_targets = []
    parametrizations_gets = []
    for tgt in targets:
        if (target_types_to_generate_requests.is_generator(tgt)
                and not tgt.address.is_generated_target):
            generator_targets.append(tgt)
            parametrizations_gets.append(
                Get(
                    _TargetParametrizations,
                    _TargetParametrizationsRequest(
                        tgt.address.maybe_convert_to_target_generator(),
                        description_of_origin="TODO(#14468)",
                    ),
                ))
        else:
            expanded_targets.add(tgt)

    all_generated_targets = await MultiGet(parametrizations_gets)
    expanded_targets.update(
        tgt for generator, parametrizations in zip(generator_targets,
                                                   all_generated_targets)
        for tgt in parametrizations.generated_or_generator(generator.address))
    return Targets(expanded_targets)
コード例 #2
0
def target_types_to_generate_targets_requests(
    union_membership: UnionMembership,
) -> TargetTypesToGenerateTargetsRequests:
    return TargetTypesToGenerateTargetsRequests({
        request_cls.generate_from: request_cls  # type: ignore[misc]
        for request_cls in union_membership.get(GenerateTargetsRequest)
    })
コード例 #3
0
async def resolve_target(
    request: WrappedTargetRequest,
    target_types_to_generate_requests: TargetTypesToGenerateTargetsRequests,
) -> WrappedTarget:
    address = request.address
    base_address = address.maybe_convert_to_target_generator()
    parametrizations = await Get(
        _TargetParametrizations,
        _TargetParametrizationsRequest(
            base_address, description_of_origin=request.description_of_origin),
    )
    if address.is_generated_target:
        # TODO: This is an accommodation to allow using file/generator Addresses for
        # non-generator atom targets. See https://github.com/pantsbuild/pants/issues/14419.
        original_target = parametrizations.get(base_address)
        if original_target and not target_types_to_generate_requests.is_generator(
                original_target):
            return WrappedTarget(original_target)
    target = parametrizations.get(address)
    if target is None:
        raise ValueError(
            f"The address `{address}` was not generated by the target `{base_address}`, which "
            "only generated these addresses:\n\n"
            f"{bullet_list(str(t.address) for t in parametrizations.all)}\n\n"
            "Did you mean to use one of those addresses?")
    return WrappedTarget(target)
コード例 #4
0
ファイル: graph.py プロジェクト: patricklaw/pants
async def resolve_targets(
    targets: UnexpandedTargets,
    target_types_to_generate_requests: TargetTypesToGenerateTargetsRequests,
) -> Targets:
    # Replace all generating targets with what it generates. Otherwise, keep it. If a target
    # generator does not generate any targets, keep the target generator.
    expanded_targets: OrderedSet[Target] = OrderedSet()
    generator_targets = []
    generate_gets = []
    for tgt in targets:
        if (target_types_to_generate_requests.is_generator(tgt)
                and not tgt.address.is_generated_target):
            generator_targets.append(tgt)
            generate_request = target_types_to_generate_requests[type(tgt)]
            generate_gets.append(
                Get(GeneratedTargets, GenerateTargetsRequest,
                    generate_request(tgt)))
        else:
            expanded_targets.add(tgt)

    all_generated_targets = await MultiGet(generate_gets)
    expanded_targets.update(tgt for generator, generated_targets in zip(
        generator_targets, all_generated_targets) for tgt in (
            generated_targets.values() if generated_targets else {generator}))
    return Targets(expanded_targets)
コード例 #5
0
ファイル: graph.py プロジェクト: hephex/pants
async def resolve_target(
    address: Address,
    registered_target_types: RegisteredTargetTypes,
    union_membership: UnionMembership,
    target_types_to_generate_requests: TargetTypesToGenerateTargetsRequests,
) -> WrappedTarget:
    if not address.is_generated_target:
        target_adaptor = await Get(TargetAdaptor, Address, address)
        target_type = registered_target_types.aliases_to_types.get(
            target_adaptor.type_alias, None)
        if target_type is None:
            raise UnrecognizedTargetTypeException(target_adaptor.type_alias,
                                                  registered_target_types,
                                                  address)
        if (target_type.deprecated_alias is not None
                and target_type.deprecated_alias == target_adaptor.type_alias
                and not address.is_generated_target):
            await Get(_WarnDeprecatedTarget,
                      _WarnDeprecatedTargetRequest(target_type))
        target = target_type(target_adaptor.kwargs, address, union_membership)
        return WrappedTarget(target)

    wrapped_generator_tgt = await Get(
        WrappedTarget, Address, address.maybe_convert_to_target_generator())
    generator_tgt = wrapped_generator_tgt.target
    if not target_types_to_generate_requests.is_generator(generator_tgt):
        # TODO: Error in this case. You should not use a generator address (or file address) if
        #  the generator does not actually generate.
        return wrapped_generator_tgt

    generate_request = target_types_to_generate_requests[type(generator_tgt)]
    generated = await Get(GeneratedTargets, GenerateTargetsRequest,
                          generate_request(generator_tgt))
    if address not in generated:
        raise ValueError(
            f"The address `{address}` is not generated by the `{generator_tgt.alias}` target "
            f"`{generator_tgt.address}`, which only generates these addresses:\n\n"
            f"{bullet_list(addr.spec for addr in generated)}\n\n"
            "Did you mean to use one of those addresses?")
    return WrappedTarget(generated[address])
コード例 #6
0
async def resolve_target_parametrizations(
    request: _TargetParametrizationsRequest,
    registered_target_types: RegisteredTargetTypes,
    union_membership: UnionMembership,
    target_types_to_generate_requests: TargetTypesToGenerateTargetsRequests,
    unmatched_build_file_globs: UnmatchedBuildFileGlobs,
) -> _TargetParametrizations:
    address = request.address

    target_adaptor = await Get(TargetAdaptor, Address, address)
    target_type = registered_target_types.aliases_to_types.get(
        target_adaptor.type_alias, None)
    if target_type is None:
        raise UnrecognizedTargetTypeException(target_adaptor.type_alias,
                                              registered_target_types, address)
    if (target_type.deprecated_alias is not None
            and target_type.deprecated_alias == target_adaptor.type_alias
            and not address.is_generated_target):
        warn_deprecated_target_type(target_type)

    target = None
    parametrizations: list[_TargetParametrization] = []
    generate_request: type[GenerateTargetsRequest] | None = None
    if issubclass(target_type, TargetGenerator):
        generate_request = target_types_to_generate_requests.request_for(
            target_type)
    if generate_request:
        # Split out the `propagated_fields` before construction.
        generator_fields = dict(target_adaptor.kwargs)
        template_fields = {}
        if issubclass(target_type, TargetGenerator):
            copied_fields = (
                *target_type.copied_fields,
                *target_type._find_plugin_fields(union_membership),
            )
            for field_type in copied_fields:
                field_value = generator_fields.get(field_type.alias, None)
                if field_value is not None:
                    template_fields[field_type.alias] = field_value
            for field_type in target_type.moved_fields:
                field_value = generator_fields.pop(field_type.alias, None)
                if field_value is not None:
                    template_fields[field_type.alias] = field_value

        generator_fields_parametrized = {
            name
            for name, field in generator_fields.items()
            if isinstance(field, Parametrize)
        }
        if generator_fields_parametrized:
            noun = pluralize(len(generator_fields_parametrized),
                             "field",
                             include_count=False)
            raise ValueError(
                f"Only fields which will be moved to generated targets may be parametrized, "
                f"so target generator {address} (with type {target_type.alias}) cannot "
                f"parametrize the {generator_fields_parametrized} {noun}.")

        base_generator = target_type(
            generator_fields,
            address,
            name_explicitly_set=target_adaptor.name_explicitly_set,
            union_membership=union_membership,
        )

        overrides = {}
        if base_generator.has_field(OverridesField):
            overrides_field = base_generator[OverridesField]
            overrides_flattened = overrides_field.flatten()
            if issubclass(target_type, TargetFilesGenerator):
                override_globs = OverridesField.to_path_globs(
                    address, overrides_flattened, unmatched_build_file_globs)
                override_paths = await MultiGet(
                    Get(Paths, PathGlobs, path_globs)
                    for path_globs in override_globs)
                overrides = OverridesField.flatten_paths(
                    address,
                    zip(override_paths, override_globs,
                        overrides_flattened.values()),
                )
            else:
                overrides = overrides_field.flatten()

        generators = [(
            target_type(
                generator_fields,
                address,
                name_explicitly_set=target_adaptor.name is not None,
                union_membership=union_membership,
            ),
            template,
        ) for address, template in Parametrize.expand(address, template_fields)
                      ]
        all_generated = await MultiGet(
            Get(
                GeneratedTargets,
                GenerateTargetsRequest,
                generate_request(
                    generator,
                    template_address=generator.address,
                    template=template,
                    overrides={
                        name: dict(
                            Parametrize.expand(generator.address, override))
                        for name, override in overrides.items()
                    },
                ),
            ) for generator, template in generators)
        parametrizations.extend(
            _TargetParametrization(generator, generated_batch)
            for generated_batch, (generator,
                                  _) in zip(all_generated, generators))
    else:
        first, *rest = Parametrize.expand(address, target_adaptor.kwargs)
        if rest:
            # The target was parametrized, and so the original Target does not exist.
            generated = FrozenDict((
                parameterized_address,
                target_type(
                    parameterized_fields,
                    parameterized_address,
                    name_explicitly_set=target_adaptor.name_explicitly_set,
                    union_membership=union_membership,
                ),
            ) for parameterized_address, parameterized_fields in (first,
                                                                  *rest))
            parametrizations.append(_TargetParametrization(None, generated))
        else:
            # The target was not parametrized.
            target = target_type(
                target_adaptor.kwargs,
                address,
                name_explicitly_set=target_adaptor.name_explicitly_set,
                union_membership=union_membership,
            )
            parametrizations.append(
                _TargetParametrization(target, FrozenDict()))

    # TODO: Move to Target constructor.
    for field_type in target.field_types if target else ():
        if (field_type.deprecated_alias is not None
                and field_type.deprecated_alias in target_adaptor.kwargs):
            warn_deprecated_field_type(field_type)

    return _TargetParametrizations(parametrizations)
コード例 #7
0
async def resolve_dependencies(
    request: DependenciesRequest,
    target_types_to_generate_requests: TargetTypesToGenerateTargetsRequests,
    union_membership: UnionMembership,
    subproject_roots: SubprojectRoots,
) -> Addresses:
    wrapped_tgt, explicitly_provided = await MultiGet(
        Get(
            WrappedTarget,
            WrappedTargetRequest(request.field.address,
                                 description_of_origin="<infallible>"),
        ),
        Get(ExplicitlyProvidedDependencies, DependenciesRequest, request),
    )
    tgt = wrapped_tgt.target

    # Inject any dependencies (based on `Dependencies` field rather than `SourcesField`).
    inject_request_types = union_membership.get(InjectDependenciesRequest)
    injected = await MultiGet(
        Get(InjectedDependencies, InjectDependenciesRequest,
            inject_request_type(request.field))
        for inject_request_type in inject_request_types
        if isinstance(request.field, inject_request_type.inject_for))

    # Infer any dependencies (based on `SourcesField` field).
    inference_request_types = union_membership.get(InferDependenciesRequest)
    inferred: tuple[InferredDependencies, ...] = ()
    if inference_request_types:
        sources_field = tgt.get(SourcesField)
        relevant_inference_request_types = [
            inference_request_type
            for inference_request_type in inference_request_types
            if isinstance(sources_field, inference_request_type.infer_from)
        ]
        inferred = await MultiGet(
            Get(
                InferredDependencies,
                InferDependenciesRequest,
                inference_request_type(sources_field),
            ) for inference_request_type in relevant_inference_request_types)

    # If it's a target generator, inject dependencies on all of its generated targets.
    generated_addresses: tuple[Address, ...] = ()
    if target_types_to_generate_requests.is_generator(
            tgt) and not tgt.address.is_generated_target:
        parametrizations = await Get(
            _TargetParametrizations,
            _TargetParametrizationsRequest(
                tgt.address.maybe_convert_to_target_generator(),
                description_of_origin=
                (f"the target generator {tgt.address.maybe_convert_to_target_generator()}"
                 ),
            ),
        )
        generated_addresses = tuple(
            parametrizations.generated_for(tgt.address).keys())

    # If the target is parametrized, see whether any explicitly provided dependencies are also
    # parametrized, but with partial/no parameters. If so, fill them in.
    explicitly_provided_includes: Iterable[
        Address] = explicitly_provided.includes
    if request.field.address.is_parametrized and explicitly_provided_includes:
        explicit_dependency_parametrizations = await MultiGet(
            Get(
                _TargetParametrizations,
                _TargetParametrizationsRequest(
                    address.maybe_convert_to_target_generator(),
                    description_of_origin=
                    (f"the `{request.field.alias}` field of the target {tgt.address}"
                     ),
                ),
            ) for address in explicitly_provided_includes)

        explicitly_provided_includes = [
            parametrizations.get_subset(address, tgt).address
            for address, parametrizations in zip(
                explicitly_provided_includes,
                explicit_dependency_parametrizations)
        ]

    # If the target has `SpecialCasedDependencies`, such as the `archive` target having
    # `files` and `packages` fields, then we possibly include those too. We don't want to always
    # include those dependencies because they should often be excluded from the result due to
    # being handled elsewhere in the calling code.
    special_cased: tuple[Address, ...] = ()
    if request.include_special_cased_deps:
        # Unlike normal, we don't use `tgt.get()` because there may be >1 subclass of
        # SpecialCasedDependencies.
        special_cased_fields = tuple(
            field for field in tgt.field_values.values()
            if isinstance(field, SpecialCasedDependencies))
        # We can't use the normal `Get(Addresses, UnparsedAddressInputs)` due to a graph cycle.
        special_cased = await MultiGet(
            Get(
                Address,
                AddressInput,
                AddressInput.parse(
                    addr,
                    relative_to=tgt.address.spec_path,
                    subproject_roots=subproject_roots,
                    description_of_origin=
                    (f"the `{special_cased_field.alias}` field from the target {tgt.address}"
                     ),
                ),
            ) for special_cased_field in special_cased_fields
            for addr in special_cased_field.to_unparsed_address_inputs().values
        )

    result = Addresses(
        sorted({
            addr
            for addr in (
                *generated_addresses,
                *explicitly_provided_includes,
                *itertools.chain.from_iterable(injected),
                *itertools.chain.from_iterable(inferred),
                *special_cased,
            ) if addr not in explicitly_provided.ignores
        }))

    # Validate dependencies.
    _ = await MultiGet(
        Get(
            ValidatedDependencies,
            ValidateDependenciesRequest,
            vd_request_type(vd_request_type.field_set_type.create(tgt),
                            result),  # type: ignore[misc]
        ) for vd_request_type in union_membership.get(
            ValidateDependenciesRequest) if
        vd_request_type.field_set_type.is_applicable(tgt)  # type: ignore[misc]
    )

    return result
コード例 #8
0
ファイル: graph.py プロジェクト: patricklaw/pants
async def resolve_dependencies(
    request: DependenciesRequest,
    target_types_to_generate_requests: TargetTypesToGenerateTargetsRequests,
    union_membership: UnionMembership,
    global_options: GlobalOptions,
) -> Addresses:
    wrapped_tgt, explicitly_provided = await MultiGet(
        Get(WrappedTarget, Address, request.field.address),
        Get(ExplicitlyProvidedDependencies, DependenciesRequest, request),
    )
    tgt = wrapped_tgt.target

    # Inject any dependencies (based on `Dependencies` field rather than `Sources` field).
    inject_request_types = union_membership.get(InjectDependenciesRequest)
    injected = await MultiGet(
        Get(InjectedDependencies, InjectDependenciesRequest,
            inject_request_type(request.field))
        for inject_request_type in inject_request_types
        if isinstance(request.field, inject_request_type.inject_for))

    # Infer any dependencies (based on `Sources` field).
    inference_request_types = union_membership.get(InferDependenciesRequest)
    inferred: Tuple[InferredDependencies, ...] = ()
    if inference_request_types:
        sources_field = tgt.get(Sources)
        relevant_inference_request_types = [
            inference_request_type
            for inference_request_type in inference_request_types
            if isinstance(sources_field, inference_request_type.infer_from)
        ]
        inferred = await MultiGet(
            Get(
                InferredDependencies,
                InferDependenciesRequest,
                inference_request_type(sources_field),
            ) for inference_request_type in relevant_inference_request_types)

    # If it's a target generator, inject dependencies on all of its generated targets.
    generated_addresses: tuple[Address, ...] = ()
    if target_types_to_generate_requests.is_generator(
            tgt) and not tgt.address.is_generated_target:
        generate_request = target_types_to_generate_requests[type(tgt)]
        generated_targets = await Get(GeneratedTargets, GenerateTargetsRequest,
                                      generate_request(tgt))
        generated_addresses = tuple(generated_targets.keys())

    # If the target has `SpecialCasedDependencies`, such as the `archive` target having
    # `files` and `packages` fields, then we possibly include those too. We don't want to always
    # include those dependencies because they should often be excluded from the result due to
    # being handled elsewhere in the calling code.
    special_cased: Tuple[Address, ...] = ()
    if request.include_special_cased_deps:
        # Unlike normal, we don't use `tgt.get()` because there may be >1 subclass of
        # SpecialCasedDependencies.
        special_cased_fields = tuple(
            field for field in tgt.field_values.values()
            if isinstance(field, SpecialCasedDependencies))
        # We can't use the normal `Get(Addresses, UnparsedAddressInputs)` due to a graph cycle.
        special_cased = await MultiGet(
            Get(
                Address,
                AddressInput,
                AddressInput.parse(
                    addr,
                    relative_to=tgt.address.spec_path,
                    subproject_roots=global_options.options.subproject_roots,
                ),
            ) for special_cased_field in special_cased_fields
            for addr in special_cased_field.to_unparsed_address_inputs().values
        )

    result = {
        addr
        for addr in (
            *generated_addresses,
            *explicitly_provided.includes,
            *itertools.chain.from_iterable(injected),
            *itertools.chain.from_iterable(inferred),
            *special_cased,
        ) if addr not in explicitly_provided.ignores
    }
    return Addresses(sorted(result))