Repository: pantsbuild/pants

Issue:
Allow pass-through options for JUnit
In #12812, we discussed the need for parsing JUnit results within Pants itself. The use case was replacing the hack in #12909, where all JUnit outputs were set to ASCII, since we needed to be able to deterministically scan the output of a JUnit process, which behaves unexpectedly on Mac OS (it replaces an ascii checkbox with a unicode emoji). 

For this task, we should make it so that we can selectively pass `--ascii` to JUnit processes that need it, but not others.


Discussion:

Resolving patch:
diff --git a/src/python/pants/backend/java/subsystems/__init__.py b/src/python/pants/backend/java/subsystems/__init__.py
new file mode 100644
diff --git a/src/python/pants/backend/java/subsystems/junit.py b/src/python/pants/backend/java/subsystems/junit.py
new file mode 100644
--- /dev/null
+++ b/src/python/pants/backend/java/subsystems/junit.py
@@ -0,0 +1,22 @@
+# Copyright 2021 Pants project contributors (see CONTRIBUTORS.md).
+# Licensed under the Apache License, Version 2.0 (see LICENSE).
+
+from pants.option.custom_types import shell_str
+from pants.option.subsystem import Subsystem
+
+
+class JUnit(Subsystem):
+    options_scope = "junit"
+    help = "The JUnit test framework (https://junit.org)"
+
+    @classmethod
+    def register_options(cls, register):
+        super().register_options(register)
+
+        register(
+            "--args",
+            type=list,
+            member_type=shell_str,
+            passthrough=True,
+            help="Arguments to pass directly to JUnit, e.g. `--disable-ansi-colors`",
+        )


Test patch:
diff --git a/src/python/pants/backend/java/test/junit.py b/src/python/pants/backend/java/test/junit.py
--- a/src/python/pants/backend/java/test/junit.py
+++ b/src/python/pants/backend/java/test/junit.py
@@ -5,6 +5,7 @@
 from dataclasses import dataclass
 
 from pants.backend.java.compile.javac import CompiledClassfiles, CompileJavaSourceRequest
+from pants.backend.java.subsystems.junit import JUnit
 from pants.backend.java.target_types import JavaTestsSources
 from pants.core.goals.test import TestDebugRequest, TestFieldSet, TestResult
 from pants.engine.addresses import Addresses
@@ -42,6 +43,7 @@ class JavaTestFieldSet(TestFieldSet):
 @rule(desc="Run JUnit", level=LogLevel.DEBUG)
 async def run_junit_test(
     coursier: Coursier,
+    junit: JUnit,
     field_set: JavaTestFieldSet,
 ) -> TestResult:
     transitive_targets = await Get(TransitiveTargets, TransitiveTargetsRequest([field_set.address]))
@@ -108,16 +110,11 @@ async def run_junit_test(
             "-cp",
             materialized_classpath.classpath_arg(),
             "org.junit.platform.console.ConsoleLauncher",
-            # TODO(12812): Make these options configurable by integration tests in `junit_test.py`.
-            # Remove these hard-coded options before general availability.
-            "--disable-ansi-colors",
-            "--details=flat",
-            "--details-theme=ascii",
-            # END TODO REMOVAL
             "--classpath",
             usercp_relpath,
             "--scan-class-path",
             usercp_relpath,
+            *junit.options.args,
         ],
         input_digest=merged_digest,
         description=f"Run JUnit 5 ConsoleLauncher against {field_set.address}",
diff --git a/src/python/pants/backend/java/test/junit_test.py b/src/python/pants/backend/java/test/junit_test.py
--- a/src/python/pants/backend/java/test/junit_test.py
+++ b/src/python/pants/backend/java/test/junit_test.py
@@ -55,7 +55,11 @@ def rule_runner() -> RuleRunner:
             QueryRule(TestResult, (JavaTestFieldSet,)),
         ],
         target_types=[JvmDependencyLockfile, JvmArtifact, JavaLibrary, JunitTests],
-        bootstrap_args=["--javac-jdk=system"],  # TODO(#12293): use a fixed JDK version.
+        bootstrap_args=[
+            "--javac-jdk=system",  # TODO(#12293): use a fixed JDK version.
+            # Makes JUnit output predictable and parseable across versions (#12933):
+            "--junit-args=['--disable-ansi-colors','--details=flat','--details-theme=ascii']",
+        ],
     )