Esempio n. 1
0
async def addresses_with_origins_from_address_specs(
        address_mapper: AddressMapper,
        address_specs: AddressSpecs) -> AddressesWithOrigins:
    """Given an AddressMapper and list of AddressSpecs, return matching AddressesWithOrigins.

    :raises: :class:`ResolveError` if there were no matching AddressFamilies or no targets
        were matched.
    """
    # Snapshot all BUILD files covered by the AddressSpecs, then group by directory.
    snapshot = await Get(
        Snapshot,
        PathGlobs,
        address_specs.to_path_globs(
            build_patterns=address_mapper.build_patterns,
            build_ignore_patterns=address_mapper.build_ignore_patterns,
        ),
    )
    dirnames = {os.path.dirname(f) for f in snapshot.files}
    address_families = await MultiGet(
        Get(AddressFamily, Dir(d)) for d in dirnames)
    address_family_by_directory = {af.namespace: af for af in address_families}

    matched_addresses: OrderedSet[Address] = OrderedSet()
    addr_to_origin: Dict[Address, AddressSpec] = {}

    for address_spec in address_specs:
        # These may raise ResolveError, depending on the type of spec.
        addr_families_for_spec = address_spec.matching_address_families(
            address_family_by_directory)
        addr_target_pairs_for_spec = address_spec.matching_addresses(
            addr_families_for_spec)

        if isinstance(address_spec,
                      SingleAddress) and not addr_target_pairs_for_spec:
            addr_family = assert_single_element(addr_families_for_spec)
            raise _did_you_mean_exception(addr_family, address_spec.name)

        for addr, _ in addr_target_pairs_for_spec:
            # A target might be covered by multiple specs, so we take the most specific one.
            addr_to_origin[addr] = AddressSpecs.more_specific(
                addr_to_origin.get(addr), address_spec)

        matched_addresses.update(
            addr for (addr, tgt) in addr_target_pairs_for_spec
            if (address_specs.filter_by_global_options is False
                or address_mapper.matches_filter_options(addr, tgt)))

    return AddressesWithOrigins(
        AddressWithOrigin(address=addr, origin=addr_to_origin[addr])
        for addr in matched_addresses)
Esempio n. 2
0
async def addresses_with_origins_from_address_specs(
    address_specs: AddressSpecs, global_options: GlobalOptions, specs_filter: AddressSpecsFilter
) -> AddressesWithOrigins:
    """Given an AddressMapper and list of AddressSpecs, return matching AddressesWithOrigins.

    :raises: :class:`ResolveError` if the provided specs fail to match targets, and those spec
        types expect to have matched something.
    """
    matched_addresses: OrderedSet[Address] = OrderedSet()
    addr_to_origin: Dict[Address, AddressSpec] = {}
    filtering_disabled = address_specs.filter_by_global_options is False

    # First convert all `AddressLiteralSpec`s. Some of the resulting addresses may be file
    # addresses. This will raise an exception if any of the addresses are not valid.
    literal_addresses = await MultiGet(
        Get(Address, AddressInput(spec.path_component, spec.target_component))
        for spec in address_specs.literals
    )
    literal_target_adaptors = await MultiGet(
        Get(TargetAdaptor, Address, addr.maybe_convert_to_base_target())
        for addr in literal_addresses
    )
    # We convert to targets for the side effect of validating that any file addresses actually
    # belong to the specified base targets.
    await Get(
        UnexpandedTargets, Addresses(addr for addr in literal_addresses if not addr.is_base_target)
    )
    for literal_spec, addr, target_adaptor in zip(
        address_specs.literals, literal_addresses, literal_target_adaptors
    ):
        addr_to_origin[addr] = literal_spec
        if filtering_disabled or specs_filter.matches(addr, target_adaptor):
            matched_addresses.add(addr)

    # Then, convert all `AddressGlobSpecs`. Snapshot all BUILD files covered by the specs, then
    # group by directory.
    snapshot = await Get(
        Snapshot,
        PathGlobs,
        address_specs.to_path_globs(
            build_patterns=global_options.options.build_patterns,
            build_ignore_patterns=global_options.options.build_ignore,
        ),
    )
    dirnames = {os.path.dirname(f) for f in snapshot.files}
    address_families = await MultiGet(Get(AddressFamily, Dir(d)) for d in dirnames)
    address_family_by_directory = {af.namespace: af for af in address_families}

    for glob_spec in address_specs.globs:
        # These may raise ResolveError, depending on the type of spec.
        addr_families_for_spec = glob_spec.matching_address_families(address_family_by_directory)
        addr_target_pairs_for_spec = glob_spec.matching_addresses(addr_families_for_spec)

        for addr, _ in addr_target_pairs_for_spec:
            # A target might be covered by multiple specs, so we take the most specific one.
            addr_to_origin[addr] = AddressSpecs.more_specific(addr_to_origin.get(addr), glob_spec)

        matched_addresses.update(
            addr
            for (addr, tgt) in addr_target_pairs_for_spec
            if filtering_disabled or specs_filter.matches(addr, tgt)
        )

    return AddressesWithOrigins(
        AddressWithOrigin(address=addr, origin=addr_to_origin[addr]) for addr in matched_addresses
    )
Esempio n. 3
0
def test_address_specs_more_specific() -> None:
    literal_addr = AddressLiteralSpec(path_component="foo/bar",
                                      target_component="baz")
    sibling_addresses = SiblingAddresses(directory="foo/bar")
    ascendant_addresses = AscendantAddresses(directory="foo/bar")
    descendant_addresses = DescendantAddresses(directory="foo/bar")

    assert literal_addr == AddressSpecs.more_specific(literal_addr, None)
    assert literal_addr == AddressSpecs.more_specific(literal_addr,
                                                      sibling_addresses)
    assert literal_addr == AddressSpecs.more_specific(literal_addr,
                                                      ascendant_addresses)
    assert literal_addr == AddressSpecs.more_specific(literal_addr,
                                                      descendant_addresses)
    assert literal_addr == AddressSpecs.more_specific(None, literal_addr)
    assert literal_addr == AddressSpecs.more_specific(sibling_addresses,
                                                      literal_addr)
    assert literal_addr == AddressSpecs.more_specific(ascendant_addresses,
                                                      literal_addr)
    assert literal_addr == AddressSpecs.more_specific(descendant_addresses,
                                                      literal_addr)

    assert sibling_addresses == AddressSpecs.more_specific(
        sibling_addresses, None)
    assert sibling_addresses == AddressSpecs.more_specific(
        sibling_addresses, ascendant_addresses)
    assert sibling_addresses == AddressSpecs.more_specific(
        sibling_addresses, descendant_addresses)
    assert sibling_addresses == AddressSpecs.more_specific(
        None, sibling_addresses)
    assert sibling_addresses == AddressSpecs.more_specific(
        ascendant_addresses, sibling_addresses)
    assert sibling_addresses == AddressSpecs.more_specific(
        descendant_addresses, sibling_addresses)

    assert ascendant_addresses == AddressSpecs.more_specific(
        ascendant_addresses, None)
    assert ascendant_addresses == AddressSpecs.more_specific(
        ascendant_addresses, descendant_addresses)
    assert ascendant_addresses == AddressSpecs.more_specific(
        None, ascendant_addresses)
    assert ascendant_addresses == AddressSpecs.more_specific(
        descendant_addresses, ascendant_addresses)

    assert descendant_addresses == AddressSpecs.more_specific(
        descendant_addresses, None)
    assert descendant_addresses == AddressSpecs.more_specific(
        None, descendant_addresses)
Esempio n. 4
0
def test_address_specs_more_specific() -> None:
    single_address = SingleAddress(directory="foo/bar", name="baz")
    sibling_addresses = SiblingAddresses(directory="foo/bar")
    ascendant_addresses = AscendantAddresses(directory="foo/bar")
    descendant_addresses = DescendantAddresses(directory="foo/bar")

    assert single_address == AddressSpecs.more_specific(single_address, None)
    assert single_address == AddressSpecs.more_specific(single_address, sibling_addresses)
    assert single_address == AddressSpecs.more_specific(single_address, ascendant_addresses)
    assert single_address == AddressSpecs.more_specific(single_address, descendant_addresses)
    assert single_address == AddressSpecs.more_specific(None, single_address)
    assert single_address == AddressSpecs.more_specific(sibling_addresses, single_address)
    assert single_address == AddressSpecs.more_specific(ascendant_addresses, single_address)
    assert single_address == AddressSpecs.more_specific(descendant_addresses, single_address)

    assert sibling_addresses == AddressSpecs.more_specific(sibling_addresses, None)
    assert sibling_addresses == AddressSpecs.more_specific(sibling_addresses, ascendant_addresses)
    assert sibling_addresses == AddressSpecs.more_specific(sibling_addresses, descendant_addresses)
    assert sibling_addresses == AddressSpecs.more_specific(None, sibling_addresses)
    assert sibling_addresses == AddressSpecs.more_specific(ascendant_addresses, sibling_addresses)
    assert sibling_addresses == AddressSpecs.more_specific(descendant_addresses, sibling_addresses)

    assert ascendant_addresses == AddressSpecs.more_specific(ascendant_addresses, None)
    assert ascendant_addresses == AddressSpecs.more_specific(
        ascendant_addresses, descendant_addresses
    )
    assert ascendant_addresses == AddressSpecs.more_specific(None, ascendant_addresses)
    assert ascendant_addresses == AddressSpecs.more_specific(
        descendant_addresses, ascendant_addresses
    )

    assert descendant_addresses == AddressSpecs.more_specific(descendant_addresses, None)
    assert descendant_addresses == AddressSpecs.more_specific(None, descendant_addresses)