Ejemplo n.º 1
0
async def resolve_target(
    hydrated_struct: HydratedStruct,
    registered_target_types: RegisteredTargetTypes,
    union_membership: UnionMembership,
) -> WrappedTarget:
    kwargs = hydrated_struct.value.kwargs().copy()
    type_alias = kwargs.pop("type_alias")

    # We special case `address` and the field `name`. The `Target` constructor requires an
    # `Address`, so we use the value pre-calculated via `build_files.py`'s `hydrate_struct` rule.
    # We throw away the field `name` because it can be accessed via `tgt.address.target_name`, so
    # there is no (known) reason to preserve the field.
    address = cast(Address, kwargs.pop("address"))
    kwargs.pop("name", None)

    target_type = registered_target_types.aliases_to_types.get(type_alias, None)
    if target_type is None:
        raise UnrecognizedTargetTypeException(type_alias, registered_target_types, address=address)

    # Not every target type has the Dependencies field registered, but the StructWithDependencies
    # code means that `kwargs` will always have an entry. We must remove `dependencies` from
    # `kwargs` for target types without the value, otherwise we'll get an "unrecognized field"
    # error. But, we also need to be careful to error if the user did explicitly specify
    # `dependencies` in the BUILD file.
    if kwargs["dependencies"] is None and not target_type.class_has_field(
        Dependencies, union_membership=union_membership
    ):
        kwargs.pop("dependencies")

    return WrappedTarget(target_type(kwargs, address=address))
Ejemplo n.º 2
0
    def filter_target_type(target_type: str) -> TargetFilter:
        if target_type not in registered_target_types.aliases:
            raise UnrecognizedTargetTypeException(target_type,
                                                  registered_target_types)

        def filt(tgt: Target) -> bool:
            if tgt.alias == target_type:
                return True
            if tgt.deprecated_alias == target_type:
                warn_deprecated_target_type(type(tgt))
                return True
            return False

        return filt
Ejemplo n.º 3
0
        def outer_filter(target_alias: str) -> TargetFilter:
            if target_alias not in registered_target_types.aliases:
                raise UnrecognizedTargetTypeException(target_alias, registered_target_types)

            target_type = registered_target_types.aliases_to_types[target_alias]
            if target_type.deprecated_alias and target_alias == target_type.deprecated_alias:
                warn_deprecated_target_type(target_type)

            def inner_filter(tgt: Target) -> bool:
                return tgt.alias == target_alias or bool(
                    tgt.deprecated_alias and tgt.deprecated_alias == target_alias
                )

            return inner_filter
Ejemplo n.º 4
0
async def resolve_target(
    address: Address,
    registered_target_types: RegisteredTargetTypes,
    union_membership: UnionMembership,
) -> WrappedTarget:
    if address.is_file_target:
        build_target = await Get(WrappedTarget, Address, address.maybe_convert_to_build_target())
        subtarget = generate_subtarget(
            build_target.target, full_file_name=address.filename, union_membership=union_membership
        )
        return WrappedTarget(subtarget)

    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=address
        )
    target = target_type(target_adaptor.kwargs, address=address, union_membership=union_membership)
    return WrappedTarget(target)
Ejemplo n.º 5
0
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])
Ejemplo n.º 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)
Ejemplo n.º 7
0
 def filter_target_type(target_type: str) -> TargetFilter:
     if target_type not in registered_target_types.aliases:
         raise UnrecognizedTargetTypeException(target_type,
                                               registered_target_types)
     return lambda tgt: tgt.alias == target_type