async def addresses_from_filesystem_specs( filesystem_specs: FilesystemSpecs, global_options: GlobalOptions) -> Addresses: """Find the owner(s) for each FilesystemSpec. Every returned address will be a generated subtarget, meaning that each address will have exactly one file in its `sources` field. """ owners_not_found_behavior = global_options.options.owners_not_found_behavior paths_per_include = await MultiGet( Get( Paths, PathGlobs, filesystem_specs.path_globs_for_spec( spec, owners_not_found_behavior.to_glob_match_error_behavior()), ) for spec in filesystem_specs.includes) owners_per_include = await MultiGet( Get(Owners, OwnersRequest(sources=paths.files)) for paths in paths_per_include) addresses: Set[Address] = set() for spec, owners in zip(filesystem_specs.includes, owners_per_include): if (owners_not_found_behavior != OwnersNotFoundBehavior.ignore and isinstance(spec, FilesystemLiteralSpec) and not owners): _log_or_raise_unmatched_owners( [PurePath(str(spec))], global_options.options.owners_not_found_behavior, ignore_option="--owners-not-found-behavior=ignore", ) addresses.update(owners) return Addresses(sorted(addresses))
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)
async def addresses_from_filesystem_specs( filesystem_specs: FilesystemSpecs, owners_not_found_behavior: OwnersNotFoundBehavior) -> Addresses: """Find the owner(s) for each FilesystemSpec.""" paths_per_include = await MultiGet( Get( Paths, PathGlobs, filesystem_specs.path_globs_for_spec( spec, owners_not_found_behavior.to_glob_match_error_behavior()), ) for spec in filesystem_specs.file_includes) owners_per_include = await MultiGet( Get(Owners, OwnersRequest(sources=paths.files)) for paths in paths_per_include) addresses: set[Address] = set() for spec, owners in zip(filesystem_specs.file_includes, owners_per_include): if (owners_not_found_behavior != OwnersNotFoundBehavior.ignore and isinstance(spec, FileLiteralSpec) and not owners): _log_or_raise_unmatched_owners( [PurePath(str(spec))], owners_not_found_behavior, ignore_option="--owners-not-found-behavior=ignore", ) addresses.update(owners) return Addresses(sorted(addresses))
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, global_options.options.owners_not_found_behavior.to_glob_match_error_behavior(), ) 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://pants.readme.io/docs/targets for more " "information on target definitions.\n" "If you would like to ignore un-owned files, please pass `--owners-not-found-behavior=ignore`." ) 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() )
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. Every returned address will be a generated subtarget, meaning that each address will have exactly one file in its `sources` field. """ owners_not_found_behavior = global_options.options.owners_not_found_behavior paths_per_include = await MultiGet( Get( Paths, PathGlobs, filesystem_specs.path_globs_for_spec( spec, owners_not_found_behavior.to_glob_match_error_behavior() ), ) for spec in filesystem_specs.includes ) owners_per_include = await MultiGet( Get(Owners, OwnersRequest(sources=paths.files)) for paths in paths_per_include ) addresses_to_specs: Dict[Address, FilesystemSpec] = {} for spec, owners in zip(filesystem_specs.includes, owners_per_include): if ( owners_not_found_behavior != OwnersNotFoundBehavior.ignore and isinstance(spec, FilesystemLiteralSpec) and not owners ): _log_or_raise_unmatched_owners( [PurePath(str(spec))], global_options.options.owners_not_found_behavior, ignore_option="--owners-not-found-behavior=ignore", ) for address in owners: # A target might be covered by multiple specs, so we take the most specific one. addresses_to_specs[address] = FilesystemSpecs.more_specific( addresses_to_specs.get(address), spec ) return AddressesWithOrigins( AddressWithOrigin(address, spec) for address, spec in addresses_to_specs.items() )