def test_generate_subtarget() -> None: class MockTarget(Target): alias = "mock_target" core_fields = (Dependencies, Tags, Sources) # When the target already only has a single source, the result should be the same, except for a # different address. single_source_tgt = MockTarget( {Sources.alias: ["demo.f95"], Tags.alias: ["demo"]}, address=Address("src/fortran", target_name="demo"), ) expected_single_source_address = Address( "src/fortran", relative_file_path="demo.f95", target_name="demo" ) assert generate_subtarget( single_source_tgt, full_file_name="src/fortran/demo.f95" ) == MockTarget( {Sources.alias: ["demo.f95"], Tags.alias: ["demo"]}, address=expected_single_source_address ) assert ( generate_subtarget_address(single_source_tgt.address, full_file_name="src/fortran/demo.f95") == expected_single_source_address ) subdir_tgt = MockTarget( {Sources.alias: ["demo.f95", "subdir/demo.f95"]}, address=Address("src/fortran", target_name="demo"), ) expected_subdir_address = Address( "src/fortran", relative_file_path="subdir/demo.f95", target_name="demo" ) assert generate_subtarget( subdir_tgt, full_file_name="src/fortran/subdir/demo.f95" ) == MockTarget({Sources.alias: ["subdir/demo.f95"]}, address=expected_subdir_address) assert ( generate_subtarget_address(subdir_tgt.address, full_file_name="src/fortran/subdir/demo.f95") == expected_subdir_address ) # The full_file_name must match the filespec of the base target's Sources field. with pytest.raises(ValueError) as exc: generate_subtarget(single_source_tgt, full_file_name="src/fortran/fake_file.f95") assert "does not match a file src/fortran/fake_file.f95" in str(exc.value) class MissingFieldsTarget(Target): alias = "missing_fields_tgt" core_fields = (Tags,) missing_fields_tgt = MissingFieldsTarget( {Tags.alias: ["demo"]}, address=Address("", target_name="missing_fields") ) with pytest.raises(ValueError) as exc: generate_subtarget(missing_fields_tgt, full_file_name="fake.txt") assert "does not have both a `dependencies` and `sources` field" in str(exc.value)
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)