From e254237ad3cd4f8ce126603d457eec1382469dce Mon Sep 17 00:00:00 2001 From: Darren Gibson Date: Tue, 19 Dec 2023 16:28:42 -0600 Subject: [PATCH] Support several scalafixScalaBinaryVersion within a build (#380) --- .../internal/sbt/ScalafixInterface.scala | 81 +++++++++++-------- .../scala/scalafix/sbt/ScalafixPlugin.scala | 10 +-- .../.scalafix-2.conf | 3 + .../.scalafix-3.conf | 2 + .../build.sbt | 23 ++++++ .../project/build.properties | 1 + .../project/plugins.sbt | 2 + .../src/main/scala-2/Main.scala | 7 ++ .../src/main/scala-2/Main.scala.expected | 5 ++ .../src/main/scala-3/Main.scala | 7 ++ .../src/main/scala-3/Main.scala.expected | 7 ++ .../test | 6 ++ 12 files changed, 115 insertions(+), 39 deletions(-) create mode 100644 src/sbt-test/sbt-1.5/cross-build-scalafixScalaBinaryVersion/.scalafix-2.conf create mode 100644 src/sbt-test/sbt-1.5/cross-build-scalafixScalaBinaryVersion/.scalafix-3.conf create mode 100644 src/sbt-test/sbt-1.5/cross-build-scalafixScalaBinaryVersion/build.sbt create mode 100644 src/sbt-test/sbt-1.5/cross-build-scalafixScalaBinaryVersion/project/build.properties create mode 100644 src/sbt-test/sbt-1.5/cross-build-scalafixScalaBinaryVersion/project/plugins.sbt create mode 100644 src/sbt-test/sbt-1.5/cross-build-scalafixScalaBinaryVersion/src/main/scala-2/Main.scala create mode 100644 src/sbt-test/sbt-1.5/cross-build-scalafixScalaBinaryVersion/src/main/scala-2/Main.scala.expected create mode 100644 src/sbt-test/sbt-1.5/cross-build-scalafixScalaBinaryVersion/src/main/scala-3/Main.scala create mode 100644 src/sbt-test/sbt-1.5/cross-build-scalafixScalaBinaryVersion/src/main/scala-3/Main.scala.expected create mode 100644 src/sbt-test/sbt-1.5/cross-build-scalafixScalaBinaryVersion/test diff --git a/src/main/scala/scalafix/internal/sbt/ScalafixInterface.scala b/src/main/scala/scalafix/internal/sbt/ScalafixInterface.scala index 1a31a795..4179464f 100644 --- a/src/main/scala/scalafix/internal/sbt/ScalafixInterface.scala +++ b/src/main/scala/scalafix/internal/sbt/ScalafixInterface.scala @@ -116,6 +116,11 @@ object ScalafixInterface { private lazy val _value = scala.util.Try(thunk()) override def apply(): T = _value.get } + private val fromToolClasspathMemo: BlockingCache[ + (String, Seq[ModuleID], Seq[Repository]), + ScalafixInterface + ] = new BlockingCache + def fromToolClasspath( scalafixBinaryScalaVersion: String, scalafixDependencies: Seq[ModuleID], @@ -123,40 +128,48 @@ object ScalafixInterface { logger: Logger = ConsoleLogger(System.out) ): () => ScalafixInterface = new LazyValue({ () => - if (scalafixBinaryScalaVersion.startsWith("3")) - logger.error( - "To use Scalafix on Scala 3 projects, you must unset `scalafixBinaryScalaVersion`. " + - "Rules such as ExplicitResultTypes requiring the project version to match the Scalafix " + - "version are unsupported for the moment." - ) - else if (scalafixBinaryScalaVersion == "2.11") - logger.error( - "Scala 2.11 is no longer supported. Please downgrade to the final version supporting " + - "it: sbt-scalafix 0.10.4." - ) - val callback = new ScalafixLogger(logger) - val scalafixArguments = ScalafixAPI - .fetchAndClassloadInstance( + fromToolClasspathMemo.getOrElseUpdate( + ( scalafixBinaryScalaVersion, - scalafixCustomResolvers.asJava - ) - .newArguments() - .withMainCallback(callback) - val printStream = - new PrintStream( - LoggingOutputStream( - logger, - Level.Info - ) - ) - new ScalafixInterface(scalafixArguments, Nil) - .withArgs( - Arg.PrintStream(printStream), - Arg.ToolClasspath( - Nil, - scalafixDependencies, - scalafixCustomResolvers - ) - ) + scalafixDependencies, + scalafixCustomResolvers + ), { + if (scalafixBinaryScalaVersion.startsWith("3")) + logger.error( + "To use Scalafix on Scala 3 projects, you must unset `scalafixBinaryScalaVersion`. " + + "Rules such as ExplicitResultTypes requiring the project version to match the Scalafix " + + "version are unsupported for the moment." + ) + else if (scalafixBinaryScalaVersion == "2.11") + logger.error( + "Scala 2.11 is no longer supported. Please downgrade to the final version supporting " + + "it: sbt-scalafix 0.10.4." + ) + val callback = new ScalafixLogger(logger) + val scalafixArguments = ScalafixAPI + .fetchAndClassloadInstance( + scalafixBinaryScalaVersion, + scalafixCustomResolvers.asJava + ) + .newArguments() + .withMainCallback(callback) + val printStream = + new PrintStream( + LoggingOutputStream( + logger, + Level.Info + ) + ) + new ScalafixInterface(scalafixArguments, Nil) + .withArgs( + Arg.PrintStream(printStream), + Arg.ToolClasspath( + Nil, + scalafixDependencies, + scalafixCustomResolvers + ) + ) + } + ) }) } diff --git a/src/main/scala/scalafix/sbt/ScalafixPlugin.scala b/src/main/scala/scalafix/sbt/ScalafixPlugin.scala index 36542093..254b567a 100644 --- a/src/main/scala/scalafix/sbt/ScalafixPlugin.scala +++ b/src/main/scala/scalafix/sbt/ScalafixPlugin.scala @@ -158,6 +158,11 @@ object ScalafixPlugin extends AutoPlugin { SettingKey[Boolean]("bspEnabled") := false ) ), + scalafixInterfaceProvider := ScalafixInterface.fromToolClasspath( + scalafixScalaBinaryVersion.value, + scalafixDependencies = scalafixDependencies.value, + scalafixCustomResolvers = scalafixResolvers.value + ), update := { object SemanticdbScalac { def unapply(id: ModuleID): Option[String] = @@ -211,11 +216,6 @@ object ScalafixPlugin extends AutoPlugin { ), scalafixDependencies := Nil, commands += ScalafixEnable.command, - scalafixInterfaceProvider := ScalafixInterface.fromToolClasspath( - (ThisBuild / scalafixScalaBinaryVersion).value, - scalafixDependencies = (ThisBuild / scalafixDependencies).value, - scalafixCustomResolvers = (ThisBuild / scalafixResolvers).value - ), scalafixInterfaceCache := new BlockingCache[ ToolClasspath, ScalafixInterface diff --git a/src/sbt-test/sbt-1.5/cross-build-scalafixScalaBinaryVersion/.scalafix-2.conf b/src/sbt-test/sbt-1.5/cross-build-scalafixScalaBinaryVersion/.scalafix-2.conf new file mode 100644 index 00000000..bbc1675b --- /dev/null +++ b/src/sbt-test/sbt-1.5/cross-build-scalafixScalaBinaryVersion/.scalafix-2.conf @@ -0,0 +1,3 @@ +rules = [DisableSyntax, OrganizeImports, ExplicitResultTypes] +OrganizeImports.removeUnused = true +ExplicitResultTypes.skipSimpleDefinitions = false \ No newline at end of file diff --git a/src/sbt-test/sbt-1.5/cross-build-scalafixScalaBinaryVersion/.scalafix-3.conf b/src/sbt-test/sbt-1.5/cross-build-scalafixScalaBinaryVersion/.scalafix-3.conf new file mode 100644 index 00000000..c2231433 --- /dev/null +++ b/src/sbt-test/sbt-1.5/cross-build-scalafixScalaBinaryVersion/.scalafix-3.conf @@ -0,0 +1,2 @@ +rules = [DisableSyntax, OrganizeImports] +OrganizeImports.removeUnused = false \ No newline at end of file diff --git a/src/sbt-test/sbt-1.5/cross-build-scalafixScalaBinaryVersion/build.sbt b/src/sbt-test/sbt-1.5/cross-build-scalafixScalaBinaryVersion/build.sbt new file mode 100644 index 00000000..35f42a51 --- /dev/null +++ b/src/sbt-test/sbt-1.5/cross-build-scalafixScalaBinaryVersion/build.sbt @@ -0,0 +1,23 @@ +import _root_.scalafix.sbt.{BuildInfo => Versions} + +val scala3Version = "3.3.0" +ThisBuild / semanticdbEnabled := true +ThisBuild / semanticdbVersion := scalafixSemanticdb.revision + +lazy val root = project + .in(file(".")) + .settings( + scalaVersion := Versions.scala212, + crossScalaVersions := Seq(Versions.scala212, Versions.scala213, scala3Version), + scalacOptions ++= (if (scalaVersion.value.startsWith("2")) Seq("-Ywarn-unused") else Seq()), + scalafixScalaBinaryVersion := { + if (scalaBinaryVersion.value == "3") scalafixScalaBinaryVersion.value + else scalaBinaryVersion.value + }, + scalafixConfig := { + if (scalaBinaryVersion.value == "3") + Some(file(".scalafix-3.conf")) + else + Some(file(".scalafix-2.conf")) + } + ) diff --git a/src/sbt-test/sbt-1.5/cross-build-scalafixScalaBinaryVersion/project/build.properties b/src/sbt-test/sbt-1.5/cross-build-scalafixScalaBinaryVersion/project/build.properties new file mode 100644 index 00000000..e64c208f --- /dev/null +++ b/src/sbt-test/sbt-1.5/cross-build-scalafixScalaBinaryVersion/project/build.properties @@ -0,0 +1 @@ +sbt.version=1.5.8 diff --git a/src/sbt-test/sbt-1.5/cross-build-scalafixScalaBinaryVersion/project/plugins.sbt b/src/sbt-test/sbt-1.5/cross-build-scalafixScalaBinaryVersion/project/plugins.sbt new file mode 100644 index 00000000..2d3b4d3b --- /dev/null +++ b/src/sbt-test/sbt-1.5/cross-build-scalafixScalaBinaryVersion/project/plugins.sbt @@ -0,0 +1,2 @@ +resolvers += Resolver.sonatypeRepo("public") +addSbtPlugin("ch.epfl.scala" % "sbt-scalafix" % sys.props("plugin.version")) diff --git a/src/sbt-test/sbt-1.5/cross-build-scalafixScalaBinaryVersion/src/main/scala-2/Main.scala b/src/sbt-test/sbt-1.5/cross-build-scalafixScalaBinaryVersion/src/main/scala-2/Main.scala new file mode 100644 index 00000000..d2a9d310 --- /dev/null +++ b/src/sbt-test/sbt-1.5/cross-build-scalafixScalaBinaryVersion/src/main/scala-2/Main.scala @@ -0,0 +1,7 @@ +import scala.Int +import scala.collection.Seq +import scala.collection.AbstractSeq + +object Main { + def foo(a: Int) = a + 2.0f +} diff --git a/src/sbt-test/sbt-1.5/cross-build-scalafixScalaBinaryVersion/src/main/scala-2/Main.scala.expected b/src/sbt-test/sbt-1.5/cross-build-scalafixScalaBinaryVersion/src/main/scala-2/Main.scala.expected new file mode 100644 index 00000000..56c0e6be --- /dev/null +++ b/src/sbt-test/sbt-1.5/cross-build-scalafixScalaBinaryVersion/src/main/scala-2/Main.scala.expected @@ -0,0 +1,5 @@ +import scala.Int + +object Main { + def foo(a: Int): Float = a + 2.0f +} diff --git a/src/sbt-test/sbt-1.5/cross-build-scalafixScalaBinaryVersion/src/main/scala-3/Main.scala b/src/sbt-test/sbt-1.5/cross-build-scalafixScalaBinaryVersion/src/main/scala-3/Main.scala new file mode 100644 index 00000000..d2a9d310 --- /dev/null +++ b/src/sbt-test/sbt-1.5/cross-build-scalafixScalaBinaryVersion/src/main/scala-3/Main.scala @@ -0,0 +1,7 @@ +import scala.Int +import scala.collection.Seq +import scala.collection.AbstractSeq + +object Main { + def foo(a: Int) = a + 2.0f +} diff --git a/src/sbt-test/sbt-1.5/cross-build-scalafixScalaBinaryVersion/src/main/scala-3/Main.scala.expected b/src/sbt-test/sbt-1.5/cross-build-scalafixScalaBinaryVersion/src/main/scala-3/Main.scala.expected new file mode 100644 index 00000000..bf8fd25a --- /dev/null +++ b/src/sbt-test/sbt-1.5/cross-build-scalafixScalaBinaryVersion/src/main/scala-3/Main.scala.expected @@ -0,0 +1,7 @@ +import scala.Int +import scala.collection.AbstractSeq +import scala.collection.Seq + +object Main { + def foo(a: Int) = a + 2.0f +} \ No newline at end of file diff --git a/src/sbt-test/sbt-1.5/cross-build-scalafixScalaBinaryVersion/test b/src/sbt-test/sbt-1.5/cross-build-scalafixScalaBinaryVersion/test new file mode 100644 index 00000000..3d04cc01 --- /dev/null +++ b/src/sbt-test/sbt-1.5/cross-build-scalafixScalaBinaryVersion/test @@ -0,0 +1,6 @@ +> +compile + +> +scalafix + +$ must-mirror src/main/scala-2/Main.scala src/main/scala-2/Main.scala.expected +$ must-mirror src/main/scala-3/Main.scala src/main/scala-3/Main.scala.expected