From 1a83b0d3bfd5d357591eaa8b5e66c0279be3025c Mon Sep 17 00:00:00 2001 From: Mike Bland Date: Mon, 7 Oct 2024 15:27:14 -0400 Subject: [PATCH 1/3] Add scala.tools.cmd.CommandLineParser for >=2.13.9 Fixes //third_party/utils/src/test:test_util for Scala 2.13.9 and later by providing a thin `scala.tools.cmd.CommandLineParser` adapter. Before this change, building under Scala 2.13.14 produced: ```txt $ bazel build --repo_env=SCALA_VERSION=2.13.14 \ //third_party/utils/src/test:test_util ERROR: .../third_party/utils/src/test/BUILD:6:14: scala @@//third_party/utils/src/test:test_util failed: (Exit 1): scalac failed: error executing Scalac command (from target //third_party/utils/src/test:test_util) bazel-out/darwin_arm64-opt-exec-ST-d57f47055a04/bin/src/java/io/bazel/rulesscala/scalac/scalac @bazel-out/darwin_arm64-fastbuild/bin/third_party/utils/src/test/test_util.jar-0.params third_party/utils/src/test/io/bazel/rulesscala/utils/TestUtil.scala:10: error: object cmd is not a member of package tools import scala.tools.cmd.CommandLineParser ^ third_party/utils/src/test/io/bazel/rulesscala/utils/TestUtil.scala:119: error: not found: value CommandLineParser val options = CommandLineParser.tokenize(compileOptions) ^ ``` Turns out `CommandLineParser` disappered in Scala 2.13.9, and its `Parser` replacement is private: - https://github.com/scala/scala/pull/10057 --- third_party/utils/src/test/BUILD | 3 +++ .../scala/tools/cmd/Scala_2_13_9_CommandLineParser.scala | 8 ++++++++ 2 files changed, 11 insertions(+) create mode 100644 third_party/utils/src/test/scala/tools/cmd/Scala_2_13_9_CommandLineParser.scala diff --git a/third_party/utils/src/test/BUILD b/third_party/utils/src/test/BUILD index ff59918d5..01e22db91 100644 --- a/third_party/utils/src/test/BUILD +++ b/third_party/utils/src/test/BUILD @@ -13,6 +13,9 @@ scala_library( any_3 = [ "io/bazel/rulesscala/utils/Scala3CompilerUtils.scala", ], + between_2_13_9_and_3 = [ + "scala/tools/cmd/Scala_2_13_9_CommandLineParser.scala", + ], ), visibility = ["//visibility:public"], deps = [ diff --git a/third_party/utils/src/test/scala/tools/cmd/Scala_2_13_9_CommandLineParser.scala b/third_party/utils/src/test/scala/tools/cmd/Scala_2_13_9_CommandLineParser.scala new file mode 100644 index 000000000..783923264 --- /dev/null +++ b/third_party/utils/src/test/scala/tools/cmd/Scala_2_13_9_CommandLineParser.scala @@ -0,0 +1,8 @@ +package scala.tools.cmd; + +// Hack due to CommandLineParser disappearing in Scala 2.13.9: +// https://github.com/scala/scala/pull/10057 +object CommandLineParser { + def tokenize(line: String): List[String] = scala.sys.process.Parser + .tokenize(line) +} From 978f6d8a56501dbdd4996df876a678db8ba560d8 Mon Sep 17 00:00:00 2001 From: Mike Bland Date: Wed, 23 Oct 2024 20:24:58 -0400 Subject: [PATCH 2/3] Use local proxy instead of scala.tools.cmd patch Copied the `CompilerAPICompat` code verbatim from @WojciechMazur's suggestion on #1634. Definitely seems more robust than injecting `CommandLineParser` directly into `scala.tools.cmd`. --- third_party/utils/src/test/BUILD | 5 ++++- .../utils/CompilerAPICompat_before_2_13_9.scala | 7 +++++++ .../utils/CompilerAPICompat_since_2_13_9.scala | 14 ++++++++++++++ .../test/io/bazel/rulesscala/utils/TestUtil.scala | 5 ++--- .../tools/cmd/Scala_2_13_9_CommandLineParser.scala | 8 -------- 5 files changed, 27 insertions(+), 12 deletions(-) create mode 100644 third_party/utils/src/test/io/bazel/rulesscala/utils/CompilerAPICompat_before_2_13_9.scala create mode 100644 third_party/utils/src/test/io/bazel/rulesscala/utils/CompilerAPICompat_since_2_13_9.scala delete mode 100644 third_party/utils/src/test/scala/tools/cmd/Scala_2_13_9_CommandLineParser.scala diff --git a/third_party/utils/src/test/BUILD b/third_party/utils/src/test/BUILD index 01e22db91..8349439ab 100644 --- a/third_party/utils/src/test/BUILD +++ b/third_party/utils/src/test/BUILD @@ -13,8 +13,11 @@ scala_library( any_3 = [ "io/bazel/rulesscala/utils/Scala3CompilerUtils.scala", ], + before_2_13_9 = [ + "io/bazel/rulesscala/utils/CompilerAPICompat_before_2_13_9.scala", + ], between_2_13_9_and_3 = [ - "scala/tools/cmd/Scala_2_13_9_CommandLineParser.scala", + "io/bazel/rulesscala/utils/CompilerAPICompat_since_2_13_9.scala", ], ), visibility = ["//visibility:public"], diff --git a/third_party/utils/src/test/io/bazel/rulesscala/utils/CompilerAPICompat_before_2_13_9.scala b/third_party/utils/src/test/io/bazel/rulesscala/utils/CompilerAPICompat_before_2_13_9.scala new file mode 100644 index 000000000..e4b46e244 --- /dev/null +++ b/third_party/utils/src/test/io/bazel/rulesscala/utils/CompilerAPICompat_before_2_13_9.scala @@ -0,0 +1,7 @@ +package io.bazel.rulesscala.utils + +import scala.tools.cmd.CommandLineParser + +trait CompilerAPICompat { + def tokenize(cmd: String): List[String] = CommandLineParser.tokenize(cmd) +} diff --git a/third_party/utils/src/test/io/bazel/rulesscala/utils/CompilerAPICompat_since_2_13_9.scala b/third_party/utils/src/test/io/bazel/rulesscala/utils/CompilerAPICompat_since_2_13_9.scala new file mode 100644 index 000000000..2a7ca3897 --- /dev/null +++ b/third_party/utils/src/test/io/bazel/rulesscala/utils/CompilerAPICompat_since_2_13_9.scala @@ -0,0 +1,14 @@ +package scala { + package rulesscala { + // proxy to private[scala] compiler API + object Proxy { + def tokenize(cmd: String): List[String] = sys.process.Parser.tokenize(cmd) + } + } +} + +package io.bazel.rulesscala.utils { + trait CompilerAPICompat { + def tokenize(cmd: String): List[String] = scala.rulesscala.Proxy.tokenize(cmd) + } +} diff --git a/third_party/utils/src/test/io/bazel/rulesscala/utils/TestUtil.scala b/third_party/utils/src/test/io/bazel/rulesscala/utils/TestUtil.scala index 8f16951e2..0a32243b3 100644 --- a/third_party/utils/src/test/io/bazel/rulesscala/utils/TestUtil.scala +++ b/third_party/utils/src/test/io/bazel/rulesscala/utils/TestUtil.scala @@ -7,14 +7,13 @@ import scala.reflect.io.AbstractFile import scala.reflect.io.Directory import scala.reflect.io.PlainDirectory import scala.reflect.io.VirtualDirectory -import scala.tools.cmd.CommandLineParser import scala.tools.nsc.CompilerCommand import scala.tools.nsc.Global import scala.tools.nsc.Settings import scala.tools.nsc.reporters.StoreReporter import io.bazel.rulesscala.dependencyanalyzer.DependencyTrackingMethod -object TestUtil { +object TestUtil extends CompilerAPICompat { final val defaultTarget = "//..." val isWindows: Boolean = System.getProperty("os.name").toLowerCase.contains("windows") @@ -116,7 +115,7 @@ object TestUtil { output: AbstractFile ): List[StoreReporter#Info] = { // TODO: Optimize and cache global. - val options = CommandLineParser.tokenize(compileOptions) + val options = tokenize(compileOptions) val reporter = new StoreReporter() val settings = new Settings(println) val _ = new CompilerCommand(options, settings) diff --git a/third_party/utils/src/test/scala/tools/cmd/Scala_2_13_9_CommandLineParser.scala b/third_party/utils/src/test/scala/tools/cmd/Scala_2_13_9_CommandLineParser.scala deleted file mode 100644 index 783923264..000000000 --- a/third_party/utils/src/test/scala/tools/cmd/Scala_2_13_9_CommandLineParser.scala +++ /dev/null @@ -1,8 +0,0 @@ -package scala.tools.cmd; - -// Hack due to CommandLineParser disappearing in Scala 2.13.9: -// https://github.com/scala/scala/pull/10057 -object CommandLineParser { - def tokenize(line: String): List[String] = scala.sys.process.Parser - .tokenize(line) -} From e472de4c1d36225bed400239d47a41bba719bcbd Mon Sep 17 00:00:00 2001 From: Mike Bland Date: Fri, 25 Oct 2024 10:55:28 -0400 Subject: [PATCH 3/3] Convert CompilerAPICompat trait to adapter object Requested by @simuons in #1634. Renamed it as well to reflect its very specific function. --- third_party/utils/src/test/BUILD | 4 ++-- ..._9.scala => CommandLineParserAdapter_before_2_13_9.scala} | 2 +- ...3_9.scala => CommandLineParserAdapter_since_2_13_9.scala} | 5 +++-- .../utils/src/test/io/bazel/rulesscala/utils/TestUtil.scala | 4 ++-- 4 files changed, 8 insertions(+), 7 deletions(-) rename third_party/utils/src/test/io/bazel/rulesscala/utils/{CompilerAPICompat_before_2_13_9.scala => CommandLineParserAdapter_before_2_13_9.scala} (82%) rename third_party/utils/src/test/io/bazel/rulesscala/utils/{CompilerAPICompat_since_2_13_9.scala => CommandLineParserAdapter_since_2_13_9.scala} (65%) diff --git a/third_party/utils/src/test/BUILD b/third_party/utils/src/test/BUILD index 8349439ab..c00df5edd 100644 --- a/third_party/utils/src/test/BUILD +++ b/third_party/utils/src/test/BUILD @@ -14,10 +14,10 @@ scala_library( "io/bazel/rulesscala/utils/Scala3CompilerUtils.scala", ], before_2_13_9 = [ - "io/bazel/rulesscala/utils/CompilerAPICompat_before_2_13_9.scala", + "io/bazel/rulesscala/utils/CommandLineParserAdapter_before_2_13_9.scala", ], between_2_13_9_and_3 = [ - "io/bazel/rulesscala/utils/CompilerAPICompat_since_2_13_9.scala", + "io/bazel/rulesscala/utils/CommandLineParserAdapter_since_2_13_9.scala", ], ), visibility = ["//visibility:public"], diff --git a/third_party/utils/src/test/io/bazel/rulesscala/utils/CompilerAPICompat_before_2_13_9.scala b/third_party/utils/src/test/io/bazel/rulesscala/utils/CommandLineParserAdapter_before_2_13_9.scala similarity index 82% rename from third_party/utils/src/test/io/bazel/rulesscala/utils/CompilerAPICompat_before_2_13_9.scala rename to third_party/utils/src/test/io/bazel/rulesscala/utils/CommandLineParserAdapter_before_2_13_9.scala index e4b46e244..ab05c19f2 100644 --- a/third_party/utils/src/test/io/bazel/rulesscala/utils/CompilerAPICompat_before_2_13_9.scala +++ b/third_party/utils/src/test/io/bazel/rulesscala/utils/CommandLineParserAdapter_before_2_13_9.scala @@ -2,6 +2,6 @@ package io.bazel.rulesscala.utils import scala.tools.cmd.CommandLineParser -trait CompilerAPICompat { +object CommandLineParserAdapter { def tokenize(cmd: String): List[String] = CommandLineParser.tokenize(cmd) } diff --git a/third_party/utils/src/test/io/bazel/rulesscala/utils/CompilerAPICompat_since_2_13_9.scala b/third_party/utils/src/test/io/bazel/rulesscala/utils/CommandLineParserAdapter_since_2_13_9.scala similarity index 65% rename from third_party/utils/src/test/io/bazel/rulesscala/utils/CompilerAPICompat_since_2_13_9.scala rename to third_party/utils/src/test/io/bazel/rulesscala/utils/CommandLineParserAdapter_since_2_13_9.scala index 2a7ca3897..6b09bdf08 100644 --- a/third_party/utils/src/test/io/bazel/rulesscala/utils/CompilerAPICompat_since_2_13_9.scala +++ b/third_party/utils/src/test/io/bazel/rulesscala/utils/CommandLineParserAdapter_since_2_13_9.scala @@ -8,7 +8,8 @@ package scala { } package io.bazel.rulesscala.utils { - trait CompilerAPICompat { - def tokenize(cmd: String): List[String] = scala.rulesscala.Proxy.tokenize(cmd) + object CommandLineParserAdapter { + def tokenize(cmd: String): List[String] = + scala.rulesscala.Proxy.tokenize(cmd) } } diff --git a/third_party/utils/src/test/io/bazel/rulesscala/utils/TestUtil.scala b/third_party/utils/src/test/io/bazel/rulesscala/utils/TestUtil.scala index 0a32243b3..11e8e26f7 100644 --- a/third_party/utils/src/test/io/bazel/rulesscala/utils/TestUtil.scala +++ b/third_party/utils/src/test/io/bazel/rulesscala/utils/TestUtil.scala @@ -13,7 +13,7 @@ import scala.tools.nsc.Settings import scala.tools.nsc.reporters.StoreReporter import io.bazel.rulesscala.dependencyanalyzer.DependencyTrackingMethod -object TestUtil extends CompilerAPICompat { +object TestUtil { final val defaultTarget = "//..." val isWindows: Boolean = System.getProperty("os.name").toLowerCase.contains("windows") @@ -115,7 +115,7 @@ object TestUtil extends CompilerAPICompat { output: AbstractFile ): List[StoreReporter#Info] = { // TODO: Optimize and cache global. - val options = tokenize(compileOptions) + val options = CommandLineParserAdapter.tokenize(compileOptions) val reporter = new StoreReporter() val settings = new Settings(println) val _ = new CompilerCommand(options, settings)