예제 #1
0
파일: graph.py 프로젝트: rhysyngsun/pants
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)
예제 #2
0
파일: test_test.py 프로젝트: tushar19/pants
    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()