def test_filesystem_specs_more_specific() -> None: literal = FilesystemLiteralSpec("foo.txt") glob = FilesystemGlobSpec("*.txt") assert literal == FilesystemSpecs.more_specific(literal, None) assert literal == FilesystemSpecs.more_specific(literal, glob) assert literal == FilesystemSpecs.more_specific(None, literal) assert literal == FilesystemSpecs.more_specific(glob, literal) assert glob == FilesystemSpecs.more_specific(None, glob) assert glob == FilesystemSpecs.more_specific(glob, None)
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() )