예제 #1
0
async def find_owners(owners_request: OwnersRequest) -> Owners:
    sources_set = FrozenOrderedSet(owners_request.sources)
    dirs_set = FrozenOrderedSet(
        os.path.dirname(source) for source in sources_set)

    # Walk up the buildroot looking for targets that would conceivably claim changed sources.
    candidate_specs = tuple(AscendantAddresses(directory=d) for d in dirs_set)
    candidate_targets = await Get[HydratedTargets](
        AddressSpecs(candidate_specs))

    # Match the source globs against the expanded candidate targets.
    def owns_any_source(legacy_target: HydratedTarget) -> bool:
        """Given a `HydratedTarget` instance, check if it owns the given source file."""
        target_kwargs = legacy_target.adaptor.kwargs()

        # Handle `sources`-declaring targets.
        # NB: Deleted files can only be matched against the 'filespec' (ie, `PathGlobs`) for a target,
        # so we don't actually call `fileset.matches` here.
        # TODO: This matching logic should be implemented using the rust `fs` crate for two reasons:
        #  1) having two implementations isn't great
        #  2) we're expanding sources via HydratedTarget, but it isn't necessary to do that to match
        target_sources = target_kwargs.get("sources", None)
        return target_sources and any_matches_filespec(
            paths=sources_set, spec=target_sources.filespec)

    build_file_addresses = await MultiGet(
        Get[BuildFileAddress](Address, ht.adaptor.address)
        for ht in candidate_targets)
    owners = Addresses(
        ht.adaptor.address
        for ht, bfa in zip(candidate_targets, build_file_addresses)
        if LegacyAddressMapper.any_is_declaring_file(bfa, sources_set)
        or owns_any_source(ht))
    return Owners(owners)
예제 #2
0
async def find_owners(build_configuration: BuildConfiguration,
                      address_mapper: AddressMapper,
                      owners_request: OwnersRequest) -> BuildFileAddresses:
    sources_set = OrderedSet(owners_request.sources)
    dirs_set = OrderedSet(dirname(source) for source in sources_set)

    # Walk up the buildroot looking for targets that would conceivably claim changed sources.
    candidate_specs = tuple(AscendantAddresses(directory=d) for d in dirs_set)
    candidate_targets = await Get(HydratedTargets, Specs(candidate_specs))

    # Match the source globs against the expanded candidate targets.
    def owns_any_source(legacy_target):
        """Given a `HydratedTarget` instance, check if it owns the given source file."""
        target_kwargs = legacy_target.adaptor.kwargs()

        # Handle `sources`-declaring targets.
        # NB: Deleted files can only be matched against the 'filespec' (ie, `PathGlobs`) for a target,
        # so we don't actually call `fileset.matches` here.
        # TODO: This matching logic should be implemented using the rust `fs` crate for two reasons:
        #  1) having two implementations isn't great
        #  2) we're expanding sources via HydratedTarget, but it isn't necessary to do that to match
        target_sources = target_kwargs.get('sources', None)
        if target_sources and any_matches_filespec(sources_set,
                                                   target_sources.filespec):
            return True

        return False

    direct_owners = tuple(
        ht.adaptor.address for ht in candidate_targets
        if LegacyAddressMapper.any_is_declaring_file(
            ht.adaptor.address, sources_set) or owns_any_source(ht))

    # If the OwnersRequest does not require dependees, then we're done.
    if owners_request.include_dependees == 'none':
        return BuildFileAddresses(direct_owners)
    else:
        # Otherwise: find dependees.
        all_addresses = await Get(BuildFileAddresses,
                                  Specs((DescendantAddresses(''), )))
        all_hydrated_structs = await MultiGet(
            Get(HydratedStruct, Address, a.to_address())
            for a in all_addresses)
        all_structs = [hs.value for hs in all_hydrated_structs]

        bfa = build_configuration.registered_aliases()
        graph = _DependentGraph.from_iterable(
            target_types_from_build_file_aliases(bfa), address_mapper,
            all_structs)
        if owners_request.include_dependees == 'direct':
            return BuildFileAddresses(
                tuple(graph.dependents_of_addresses(direct_owners)))
        else:
            assert owners_request.include_dependees == 'transitive'
            return BuildFileAddresses(
                tuple(graph.transitive_dependents_of_addresses(direct_owners)))
예제 #3
0
def find_owners(build_configuration, address_mapper, owners_request):
  sources_set = OrderedSet(owners_request.sources)
  dirs_set = OrderedSet(dirname(source) for source in sources_set)

  # Walk up the buildroot looking for targets that would conceivably claim changed sources.
  candidate_specs = tuple(AscendantAddresses(directory=d) for d in dirs_set)
  candidate_targets = yield Get(HydratedTargets, Specs(candidate_specs))

  # Match the source globs against the expanded candidate targets.
  def owns_any_source(legacy_target):
    """Given a `HydratedTarget` instance, check if it owns the given source file."""
    target_kwargs = legacy_target.adaptor.kwargs()

    # Handle `sources`-declaring targets.
    # NB: Deleted files can only be matched against the 'filespec' (ie, `PathGlobs`) for a target,
    # so we don't actually call `fileset.matches` here.
    # TODO: This matching logic should be implemented using the rust `fs` crate for two reasons:
    #  1) having two implementations isn't great
    #  2) we're expanding sources via HydratedTarget, but it isn't necessary to do that to match
    target_sources = target_kwargs.get('sources', None)
    if target_sources and any_matches_filespec(sources_set, target_sources.filespec):
      return True

    return False

  direct_owners = tuple(ht.adaptor.address
                        for ht in candidate_targets
                        if LegacyAddressMapper.any_is_declaring_file(ht.adaptor.address, sources_set) or
                           owns_any_source(ht))

  # If the OwnersRequest does not require dependees, then we're done.
  if owners_request.include_dependees == 'none':
    yield BuildFileAddresses(direct_owners)
  else:
    # Otherwise: find dependees.
    all_addresses = yield Get(BuildFileAddresses, Specs((DescendantAddresses(''),)))
    all_structs = yield [Get(HydratedStruct, Address, a.to_address()) for a in all_addresses]
    all_structs = [s.value for s in all_structs]

    bfa = build_configuration.registered_aliases()
    graph = _DependentGraph.from_iterable(target_types_from_build_file_aliases(bfa),
                                          address_mapper,
                                          all_structs)
    if owners_request.include_dependees == 'direct':
      yield BuildFileAddresses(tuple(graph.dependents_of_addresses(direct_owners)))
    else:
      assert owners_request.include_dependees == 'transitive'
      yield BuildFileAddresses(tuple(graph.transitive_dependents_of_addresses(direct_owners)))
예제 #4
0
  def iter_target_addresses_for_sources(self, sources):
    """Bulk, iterable form of `target_addresses_for_source`."""
    # Walk up the buildroot looking for targets that would conceivably claim changed sources.
    sources_set = set(sources)
    specs = tuple(AscendantAddresses(directory=d) for d in self._unique_dirs_for_sources(sources_set))

    # Uniqify all transitive hydrated targets.
    hydrated_target_to_address = {}
    hydrated_targets, = self._scheduler.product_request(HydratedTargets, [Specs(specs)])
    for hydrated_target in hydrated_targets.dependencies:
      if hydrated_target not in hydrated_target_to_address:
        hydrated_target_to_address[hydrated_target] = hydrated_target.adaptor.address

    for hydrated_target, legacy_address in six.iteritems(hydrated_target_to_address):
      # Handle BUILD files.
      if (LegacyAddressMapper.any_is_declaring_file(legacy_address, sources_set) or
          self._owns_any_source(sources_set, hydrated_target)):
        yield legacy_address