Example #1
0
async def addresses_with_origins_from_filesystem_specs(
    filesystem_specs: FilesystemSpecs,
    global_options: GlobalOptions,
) -> AddressesWithOrigins:
    """Find the owner(s) for each FilesystemSpec while preserving the original FilesystemSpec those
  owners come from.
  """
    pathglobs_per_include = (filesystem_specs.path_globs_for_spec(spec)
                             for spec in filesystem_specs.includes)
    snapshot_per_include = await MultiGet(Get[Snapshot](PathGlobs, pg)
                                          for pg in pathglobs_per_include)
    owners_per_include = await MultiGet(
        Get[Owners](OwnersRequest(sources=snapshot.files))
        for snapshot in snapshot_per_include)
    result: List[AddressWithOrigin] = []
    for spec, owners in zip(filesystem_specs.includes, owners_per_include):
        if (global_options.owners_not_found_behavior !=
                OwnersNotFoundBehavior.ignore
                and isinstance(spec, FilesystemLiteralSpec)
                and not owners.addresses):
            file_path = PurePath(spec.to_spec_string())
            msg = (
                f"No owning targets could be found for the file `{file_path}`.\n\nPlease check "
                f"that there is a BUILD file in `{file_path.parent}` with a target whose `sources` field "
                f"includes `{file_path}`. See https://www.pantsbuild.org/build_files.html."
            )
            if global_options.owners_not_found_behavior == OwnersNotFoundBehavior.warn:
                logger.warning(msg)
            else:
                raise ResolveError(msg)
        result.extend(
            AddressWithOrigin(address=bfa, origin=spec)
            for bfa in owners.addresses)
    return AddressesWithOrigins(result)
Example #2
0
 def make_addresses_with_origins(
         *addresses: Address) -> AddressesWithOrigins:
     return AddressesWithOrigins([
         AddressWithOrigin(
             address=address,
             origin=SingleAddress(directory=address.spec_path,
                                  name=address.target_name),
         ) for address in addresses
     ])
Example #3
0
async def addresses_with_origins_from_address_families(
    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
       - the AddressSpec matches no addresses for SingleAddresses.
    :raises: :class:`AddressLookupError` if no targets are matched for non-SingleAddress specs.
    """
    # Capture a Snapshot covering all paths for these AddressSpecs, then group by directory.
    snapshot = await Get[Snapshot](PathGlobs,
                                   _address_spec_to_globs(
                                       address_mapper, address_specs))
    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:
        # NB: if an address spec is provided which expands to some number of targets, but those targets
        # match --exclude-target-regexp, we do NOT fail! This is why we wait to apply the tag and
        # exclude patterns until we gather all the targets the address spec would have matched
        # without them.
        try:
            addr_families_for_spec = address_spec.matching_address_families(
                address_family_by_directory)
        except AddressSpec.AddressFamilyResolutionError as e:
            raise ResolveError(e) from e

        try:
            all_bfaddr_tgt_pairs = address_spec.address_target_pairs_from_address_families(
                addr_families_for_spec)
            for bfaddr, _ in all_bfaddr_tgt_pairs:
                addr = bfaddr.to_address()
                # A target might be covered by multiple specs, so we take the most specific one.
                addr_to_origin[addr] = more_specific(addr_to_origin.get(addr),
                                                     address_spec)
        except AddressSpec.AddressResolutionError as e:
            raise AddressLookupError(e) from e
        except SingleAddress._SingleAddressResolutionError as e:
            _raise_did_you_mean(e.single_address_family, e.name, source=e)

        matched_addresses.update(
            bfaddr.to_address() for (bfaddr, tgt) in all_bfaddr_tgt_pairs
            if address_specs.matcher.matches_target_address_pair(bfaddr, tgt))

    # NB: This may be empty, as the result of filtering by tag and exclude patterns!
    return AddressesWithOrigins(
        AddressWithOrigin(address=addr, origin=addr_to_origin[addr])
        for addr in matched_addresses)
Example #4
0
async def addresses_with_origins_from_filesystem_specs(
    filesystem_specs: FilesystemSpecs,
    global_options: GlobalOptions,
) -> AddressesWithOrigins:
    """Find the owner(s) for each FilesystemSpec while preserving the original FilesystemSpec those
    owners come from.

    This will merge FilesystemSpecs that come from the same owning target into a single
    FilesystemMergedSpec.
    """
    pathglobs_per_include = (filesystem_specs.path_globs_for_spec(spec)
                             for spec in filesystem_specs.includes)
    snapshot_per_include = await MultiGet(Get[Snapshot](PathGlobs, pg)
                                          for pg in pathglobs_per_include)
    owners_per_include = await MultiGet(
        Get[Owners](OwnersRequest(sources=snapshot.files))
        for snapshot in snapshot_per_include)
    addresses_to_specs: DefaultDict[
        Address, List[Union[FilesystemLiteralSpec,
                            FilesystemResolvedGlobSpec]]] = defaultdict(list)
    for spec, snapshot, owners in zip(filesystem_specs.includes,
                                      snapshot_per_include,
                                      owners_per_include):
        if (global_options.options.owners_not_found_behavior !=
                OwnersNotFoundBehavior.ignore
                and isinstance(spec, FilesystemLiteralSpec)
                and not owners.addresses):
            file_path = PurePath(spec.to_spec_string())
            msg = (
                f"No owning targets could be found for the file `{file_path}`.\n\nPlease check "
                f"that there is a BUILD file in `{file_path.parent}` with a target whose `sources` field "
                f"includes `{file_path}`. See https://www.pantsbuild.org/build_files.html."
            )
            if global_options.options.owners_not_found_behavior == OwnersNotFoundBehavior.warn:
                logger.warning(msg)
            else:
                raise ResolveError(msg)
        # We preserve what literal files any globs resolved to. This allows downstream goals to be
        # more precise in which files they operate on.
        origin: Union[FilesystemLiteralSpec, FilesystemResolvedGlobSpec] = (
            spec if isinstance(spec, FilesystemLiteralSpec) else
            FilesystemResolvedGlobSpec(glob=spec.glob, files=snapshot.files))
        for address in owners.addresses:
            addresses_to_specs[address].append(origin)
    return AddressesWithOrigins(
        AddressWithOrigin(
            address, specs[0] if len(specs) ==
            1 else FilesystemMergedSpec.create(specs))
        for address, specs in addresses_to_specs.items())