async def mypy_typecheck(request: MyPyRequest, mypy: MyPy) -> CheckResults: if mypy.skip: return CheckResults([], checker_name=request.name) partitions = await Get(MyPyPartitions, MyPyRequest, request) partitioned_results = await MultiGet( Get(CheckResult, MyPyPartition, partition) for partition in partitions) return CheckResults(partitioned_results, checker_name=request.name)
def test_streaming_output_failure() -> None: results = CheckResults([CheckResult(18, "stdout", "stderr")], checker_name="typechecker") assert results.level() == LogLevel.ERROR assert results.message() == dedent("""\ typechecker failed (exit code 18). stdout stderr """)
def test_streaming_output_success() -> None: results = CheckResults([CheckResult(0, "stdout", "stderr")], checker_name="typechecker") assert results.level() == LogLevel.INFO assert results.message() == dedent("""\ typechecker succeeded. stdout stderr """)
async def check_go(request: GoCheckRequest) -> CheckResults: build_requests = await MultiGet( Get(FallibleBuildGoPackageRequest, BuildGoPackageTargetRequest(field_set.address)) for field_set in request.field_sets) invalid_requests = [] valid_requests = [] for fallible_request in build_requests: if fallible_request.request is None: invalid_requests.append(fallible_request) else: valid_requests.append(fallible_request.request) build_results = await MultiGet( Get(FallibleBuiltGoPackage, BuildGoPackageRequest, request) for request in valid_requests) # NB: We don't pass stdout/stderr as it will have already been rendered as streaming. exit_code = next( ( result.exit_code # type: ignore[attr-defined] for result in (*build_results, *invalid_requests) if result.exit_code != 0 # type: ignore[attr-defined] ), 0, ) return CheckResults([CheckResult(exit_code, "", "")], checker_name=request.name)
async def kotlinc_check( request: KotlincCheckRequest, classpath_entry_request: ClasspathEntryRequestFactory, ) -> CheckResults: coarsened_targets = await Get( CoarsenedTargets, Addresses(field_set.address for field_set in request.field_sets) ) # NB: Each root can have an independent resolve, because there is no inherent relation # between them other than that they were on the commandline together. resolves = await MultiGet( Get(CoursierResolveKey, CoarsenedTargets([t])) for t in coarsened_targets ) results = await MultiGet( Get( FallibleClasspathEntry, ClasspathEntryRequest, classpath_entry_request.for_targets(component=target, resolve=resolve), ) for target, resolve in zip(coarsened_targets, resolves) ) # NB: We don't pass stdout/stderr as it will have already been rendered as streaming. exit_code = next((result.exit_code for result in results if result.exit_code != 0), 0) return CheckResults([CheckResult(exit_code, "", "")], checker_name=request.name)
async def mypy_typecheck( request: MyPyRequest, mypy: MyPy, python_setup: PythonSetup ) -> CheckResults: if mypy.skip: return CheckResults([], checker_name="MyPy") # When determining how to batch by interpreter constraints, we must consider the entire # transitive closure to get the final resulting constraints. # TODO(#10863): Improve the performance of this. transitive_targets_per_field_set = await MultiGet( Get(TransitiveTargets, TransitiveTargetsRequest([field_set.address])) for field_set in request.field_sets ) interpreter_constraints_to_transitive_targets = defaultdict(set) for transitive_targets in transitive_targets_per_field_set: interpreter_constraints = ( InterpreterConstraints.create_from_targets(transitive_targets.closure, python_setup) or mypy.interpreter_constraints ) interpreter_constraints_to_transitive_targets[interpreter_constraints].add( transitive_targets ) partitions = [] for interpreter_constraints, all_transitive_targets in sorted( interpreter_constraints_to_transitive_targets.items() ): combined_roots: OrderedSet[Target] = OrderedSet() combined_closure: OrderedSet[Target] = OrderedSet() for transitive_targets in all_transitive_targets: combined_roots.update(transitive_targets.roots) combined_closure.update(transitive_targets.closure) partitions.append( MyPyPartition( FrozenOrderedSet(combined_roots), FrozenOrderedSet(combined_closure), interpreter_constraints, ) ) partitioned_results = await MultiGet( Get(CheckResult, MyPyPartition, partition) for partition in partitions ) return CheckResults(partitioned_results, checker_name="MyPy")
def test_streaming_output_partitions() -> None: results = CheckResults( [ CheckResult(21, "", "", partition_description="ghc8.1"), CheckResult(0, "stdout", "stderr", partition_description="ghc9.2"), ], checker_name="typechecker", ) assert results.level() == LogLevel.ERROR assert results.message() == dedent("""\ typechecker failed (exit code 21). Partition #1 - ghc8.1: Partition #2 - ghc9.2: stdout stderr """)
def check_results(self) -> CheckResults: addresses = [config.address for config in self.field_sets] return CheckResults( [CheckResult( self.exit_code(addresses), "", "", )], checker_name=self.checker_name, )
def test_write_reports() -> None: rule_runner = RuleRunner() report_digest = rule_runner.make_snapshot_of_empty_files(["r.txt"]).digest no_results = CheckResults([], checker_name="none") _empty_result = CheckResult(0, "", "", report=EMPTY_DIGEST) empty_results = CheckResults([_empty_result], checker_name="empty") _single_result = CheckResult(0, "", "", report=report_digest) single_results = CheckResults([_single_result], checker_name="single") duplicate_results = CheckResults( [_single_result, _single_result, _empty_result], checker_name="duplicate" ) partition_results = CheckResults( [ CheckResult(0, "", "", report=report_digest, partition_description="p1"), CheckResult(0, "", "", report=report_digest, partition_description="p2"), ], checker_name="partition", ) partition_duplicate_results = CheckResults( [ CheckResult(0, "", "", report=report_digest, partition_description="p"), CheckResult(0, "", "", report=report_digest, partition_description="p"), ], checker_name="partition_duplicate", ) def get_tool_name(res: CheckResults) -> str: return res.checker_name write_reports( ( no_results, empty_results, single_results, duplicate_results, partition_results, partition_duplicate_results, ), Workspace(rule_runner.scheduler, _enforce_effects=False), DistDir(Path("dist")), goal_name="check", get_tool_name=get_tool_name, ) check_dir = Path(rule_runner.build_root, "dist", "check") assert (check_dir / "none").exists() is False assert (check_dir / "empty").exists() is False assert (check_dir / "single/r.txt").exists() is True assert (check_dir / "duplicate/all/r.txt").exists() is True assert (check_dir / "duplicate/all_/r.txt").exists() is True assert (check_dir / "partition/p1/r.txt").exists() is True assert (check_dir / "partition/p2/r.txt").exists() is True assert (check_dir / "partition_duplicate/p/r.txt").exists() is True assert (check_dir / "partition_duplicate/p_/r.txt").exists() is True
async def javac_check(request: JavacCheckRequest) -> CheckResults: coarsened_targets = await Get( CoarsenedTargets, Addresses(field_set.address for field_set in request.field_sets)) # TODO: This should be fallible so that we exit cleanly. results = await MultiGet( Get(FallibleCompiledClassfiles, CompileJavaSourceRequest(component=t)) for t in coarsened_targets) # NB: We return CheckResults with exit codes for the root targets, but we do not pass # stdout/stderr because it will already have been rendered as streaming. return CheckResults( [ CheckResult( result.exit_code, stdout="", stderr="", partition_description=str(coarsened_target), ) for result, coarsened_target in zip(results, coarsened_targets) ], checker_name="javac", )
async def javac_check( request: JavacCheckRequest, union_membership: UnionMembership, ) -> CheckResults: coarsened_targets = await Get( CoarsenedTargets, Addresses(field_set.address for field_set in request.field_sets) ) resolves = await MultiGet( Get(CoursierResolveKey, Targets(t.members)) for t in coarsened_targets ) results = await MultiGet( Get( FallibleClasspathEntry, ClasspathEntryRequest, ClasspathEntryRequest.for_targets(union_membership, component=target, resolve=resolve), ) for target, resolve in zip(coarsened_targets, resolves) ) # NB: We don't pass stdout/stderr as it will have already been rendered as streaming. exit_code = next((result.exit_code for result in results if result.exit_code != 0), 0) return CheckResults([CheckResult(exit_code, "", "")], checker_name="javac")
def check_results(self) -> CheckResults: return CheckResults([], checker_name=self.name)
def test_streaming_output_skip() -> None: results = CheckResults([], checker_name="typechecker") assert results.level() == LogLevel.DEBUG assert results.message() == "typechecker skipped."
def check_results(self) -> CheckResults: return CheckResults([], checker_name="SkippedChecker")