async def hydrate_sources( request: HydrateSourcesRequest, global_options: GlobalOptions, union_membership: UnionMembership, ) -> HydratedSources: sources_field = request.field # First, find if there are any code generators for the input `sources_field`. This will be used # to determine if the sources_field is valid or not. # We could alternatively use `sources_field.can_generate()`, but we want to error if there are # 2+ generators due to ambiguity. generate_request_types = union_membership.get(GenerateSourcesRequest) relevant_generate_request_types = [ generate_request_type for generate_request_type in generate_request_types if isinstance(sources_field, generate_request_type.input) and issubclass(generate_request_type.output, request.for_sources_types) ] if request.enable_codegen and len(relevant_generate_request_types) > 1: raise AmbiguousCodegenImplementationsException( relevant_generate_request_types, for_sources_types=request.for_sources_types) generate_request_type = next(iter(relevant_generate_request_types), None) # Now, determine if any of the `for_sources_types` may be used, either because the # sources_field is a direct subclass or can be generated into one of the valid types. def compatible_with_sources_field(valid_type: Type[Sources]) -> bool: is_instance = isinstance(sources_field, valid_type) can_be_generated = (request.enable_codegen and generate_request_type is not None and issubclass(generate_request_type.output, valid_type)) return is_instance or can_be_generated sources_type = next( (valid_type for valid_type in request.for_sources_types if compatible_with_sources_field(valid_type)), None, ) if sources_type is None: return HydratedSources(EMPTY_SNAPSHOT, sources_field.filespec, sources_type=None) # Now, hydrate the `globs`. Even if we are going to use codegen, we will need the original # protocol sources to be hydrated. path_globs = sources_field.path_globs( global_options.options.files_not_found_behavior) snapshot = await Get(Snapshot, PathGlobs, path_globs) sources_field.validate_resolved_files(snapshot.files) # Finally, return if codegen is not in use; otherwise, run the relevant code generator. if not request.enable_codegen or generate_request_type is None: return HydratedSources(snapshot, sources_field.filespec, sources_type=sources_type) wrapped_protocol_target = await Get(WrappedTarget, Address, sources_field.address) generated_sources = await Get( GeneratedSources, GenerateSourcesRequest, generate_request_type(snapshot, wrapped_protocol_target.target), ) return HydratedSources(generated_sources.snapshot, sources_field.filespec, sources_type=sources_type)
def run_test_rule( self, *, config: Type[TestConfiguration], targets: List[TargetWithOrigin], debug: bool = False, include_sources: bool = True, ) -> Tuple[int, str]: console = MockConsole(use_colors=False) options = MockOptions(debug=debug, run_coverage=False) interactive_runner = InteractiveRunner(self.scheduler) workspace = Workspace(self.scheduler) union_membership = UnionMembership( {TestConfiguration: OrderedSet([config])}) def mock_coordinator_of_tests( wrapped_config: WrappedTestConfiguration, ) -> AddressAndTestResult: config = wrapped_config.config return AddressAndTestResult( address=config.address, test_result=config.test_result, # type: ignore[attr-defined] ) result: Test = run_rule( run_tests, rule_args=[ console, options, interactive_runner, TargetsWithOrigins(targets), workspace, union_membership, RegisteredTargetTypes.create([MockTarget]), ], mock_gets=[ MockGet( product_type=AddressAndTestResult, subject_type=WrappedTestConfiguration, mock=lambda wrapped_config: mock_coordinator_of_tests( wrapped_config), ), MockGet( product_type=TestDebugRequest, subject_type=TestConfiguration, mock=lambda _: TestDebugRequest(self.make_ipr()), ), MockGet( product_type=HydratedSources, subject_type=HydrateSourcesRequest, mock=lambda _: HydratedSources( Snapshot( directory_digest=EMPTY_DIRECTORY_DIGEST, files=cast(Tuple[str, ...], ("test.hs", ) if include_sources else ()), dirs=(), ), filespec={"globs": []}, ), ), MockGet( product_type=CoverageReport, subject_type=CoverageDataBatch, mock=lambda _: FilesystemCoverageReport( result_digest=EMPTY_DIRECTORY_DIGEST, directory_to_materialize_to=PurePath("mockety/mock"), report_file=None, ), ), ], union_membership=union_membership, ) return result.exit_code, console.stdout.getvalue()