def test_explicitly_provided_dependencies_maybe_warn_of_ambiguous_dependency_inference( caplog, ) -> None: def maybe_warn( *, ambiguous: List[Address], ignores: Optional[List[Address]] = None, includes: Optional[List[Address]] = None, ) -> None: caplog.clear() epd = ExplicitlyProvidedDependencies( includes=FrozenOrderedSet(includes or []), ignores=FrozenOrderedSet(ignores or []) ) epd.maybe_warn_of_ambiguous_dependency_inference( tuple(ambiguous), Address("some_dir"), import_reference="file", context="foo" ) maybe_warn(ambiguous=[]) assert not caplog.records # A mix of file and BUILD targets. tgt_a = Address("dir", target_name="a", relative_file_path="f") tgt_b = Address("dir", target_name="b", relative_file_path="f") tgt_c = Address("dir", target_name="c") all_tgts = [tgt_a, tgt_b, tgt_c] maybe_warn(ambiguous=all_tgts) assert len(caplog.records) == 1 assert f"['{tgt_a}', '{tgt_b}', '{tgt_c}']" in caplog.text # Ignored addresses do not show up in the list of ambiguous owners, including for ignores of # both file and BUILD targets. maybe_warn(ambiguous=all_tgts, ignores=[tgt_b]) assert len(caplog.records) assert f"['{tgt_a}', '{tgt_c}']" in caplog.text maybe_warn(ambiguous=all_tgts, ignores=[tgt_b.maybe_convert_to_build_target()]) assert len(caplog.records) assert f"['{tgt_a}', '{tgt_c}']" in caplog.text # Disambiguating via ignores turns off the warning, including for ignores of both file and # BUILD targets. maybe_warn(ambiguous=all_tgts, ignores=[tgt_a, tgt_b]) assert not caplog.records maybe_warn( ambiguous=all_tgts, ignores=[tgt_a.maybe_convert_to_build_target(), tgt_b.maybe_convert_to_build_target()], ) assert not caplog.records # Including a target turns off the warning, including for includes of both file and # BUILD targets. maybe_warn(ambiguous=all_tgts, includes=[tgt_a]) assert not caplog.records maybe_warn(ambiguous=all_tgts, includes=[tgt_a.maybe_convert_to_build_target()]) assert not caplog.records
def test_explicitly_provided_dependencies_disambiguated_via_ignores() -> None: def get_disambiguated( *, ambiguous: List[Address], ignores: List[Address], includes: Optional[List[Address]] = None, ) -> Optional[Address]: epd = ExplicitlyProvidedDependencies( includes=FrozenOrderedSet(includes or []), ignores=FrozenOrderedSet(ignores) ) return epd.disambiguated_via_ignores(tuple(ambiguous)) # A mix of file and BUILD targets. tgt_a = Address("dir", target_name="a", relative_file_path="f") tgt_b = Address("dir", target_name="b", relative_file_path="f") tgt_c = Address("dir", target_name="c") all_tgts = [tgt_a, tgt_b, tgt_c] # If 1 target remains after ignores, it's disambiguated. Note that the ignores can be file # targets or BUILD targets. assert get_disambiguated(ambiguous=all_tgts, ignores=[tgt_b, tgt_c]) == tgt_a assert ( get_disambiguated( ambiguous=all_tgts, ignores=[tgt_b.maybe_convert_to_build_target(), tgt_c], ) == tgt_a ) assert get_disambiguated(ambiguous=all_tgts, ignores=[tgt_a]) is None assert ( get_disambiguated(ambiguous=all_tgts, ignores=[tgt_a.maybe_convert_to_build_target()]) is None ) assert get_disambiguated(ambiguous=all_tgts, ignores=all_tgts) is None assert get_disambiguated(ambiguous=[], ignores=[]) is None # If any includes would disambiguate the ambiguous target, we don't consider disambiguating # via excludes as the user has already explicitly disambiguated the module. assert get_disambiguated(ambiguous=all_tgts, ignores=[tgt_a, tgt_b], includes=[tgt_a]) is None assert ( get_disambiguated( ambiguous=all_tgts, ignores=[tgt_a, tgt_b], includes=[tgt_a.maybe_convert_to_build_target()], ) is None )
async def find_build_file(address: Address) -> BuildFileAddress: address_family = await Get(AddressFamily, AddressFamilyDir(address.spec_path)) owning_address = address.maybe_convert_to_build_target() if address_family.get_target_adaptor(owning_address) is None: raise ResolveError.did_you_mean( bad_name=owning_address.target_name, known_names=address_family.target_names, namespace=address_family.namespace, ) bfa = next(build_file_address for build_file_address in address_family.build_file_addresses if build_file_address.address == owning_address) return (BuildFileAddress(rel_path=bfa.rel_path, address=address) if address.is_file_target else bfa)
async def resolve_target( address: Address, registered_target_types: RegisteredTargetTypes, union_membership: UnionMembership, ) -> WrappedTarget: if address.is_file_target: build_target = await Get(WrappedTarget, Address, address.maybe_convert_to_build_target()) subtarget = generate_subtarget( build_target.target, full_file_name=address.filename, union_membership=union_membership ) return WrappedTarget(subtarget) target_adaptor = await Get(TargetAdaptor, Address, address) target_type = registered_target_types.aliases_to_types.get(target_adaptor.type_alias, None) if target_type is None: raise UnrecognizedTargetTypeException( target_adaptor.type_alias, registered_target_types, address=address ) target = target_type(target_adaptor.kwargs, address=address, union_membership=union_membership) return WrappedTarget(target)