From d46596b3d3793f1c704e62b324f9be9172a751fa Mon Sep 17 00:00:00 2001 From: "scala-center-steward[bot]" <111975575+scala-center-steward[bot]@users.noreply.github.com> Date: Fri, 15 Sep 2023 00:17:15 +0000 Subject: [PATCH 001/129] Update scalafmt-core to 3.7.14 --- .scalafmt.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.scalafmt.conf b/.scalafmt.conf index 39ce8fb3..5626b617 100644 --- a/.scalafmt.conf +++ b/.scalafmt.conf @@ -1,4 +1,4 @@ -version = "3.7.13" +version = "3.7.14" project.git=true align.preset=none assumeStandardLibraryStripMargin = true From b7431a3cdd2f4627de48f4f27a361db88949932f Mon Sep 17 00:00:00 2001 From: "scala-center-steward[bot]" <111975575+scala-center-steward[bot]@users.noreply.github.com> Date: Fri, 15 Sep 2023 00:17:21 +0000 Subject: [PATCH 002/129] Reformat with scalafmt 3.7.14 Executed command: scalafmt --non-interactive --- .../sbt-scalafix/unavailable-semanticdb-scalac/build.sbt | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/sbt-test/sbt-scalafix/unavailable-semanticdb-scalac/build.sbt b/src/sbt-test/sbt-scalafix/unavailable-semanticdb-scalac/build.sbt index 498f130f..622f2dc0 100644 --- a/src/sbt-test/sbt-scalafix/unavailable-semanticdb-scalac/build.sbt +++ b/src/sbt-test/sbt-scalafix/unavailable-semanticdb-scalac/build.sbt @@ -17,6 +17,10 @@ checkLogs := { .takeWhile(_ != null) .force assert( - logLines.exists(_.contains("Please upgrade to a more recent Scala patch version or uninstall sbt-scalafix")) + logLines.exists( + _.contains( + "Please upgrade to a more recent Scala patch version or uninstall sbt-scalafix" + ) + ) ) } From 5c03ebd4b9294fee8085a47ade2517fd4b893b16 Mon Sep 17 00:00:00 2001 From: "scala-center-steward[bot]" <111975575+scala-center-steward[bot]@users.noreply.github.com> Date: Fri, 15 Sep 2023 00:17:21 +0000 Subject: [PATCH 003/129] Add 'Reformat with scalafmt 3.7.14' to .git-blame-ignore-revs --- .git-blame-ignore-revs | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 .git-blame-ignore-revs diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs new file mode 100644 index 00000000..d3b99830 --- /dev/null +++ b/.git-blame-ignore-revs @@ -0,0 +1,2 @@ +# Scala Steward: Reformat with scalafmt 3.7.14 +b7431a3cdd2f4627de48f4f27a361db88949932f From 91db08754aa76888cbcf7564c39de7033c0fb3cb Mon Sep 17 00:00:00 2001 From: "scala-center-steward[bot]" <111975575+scala-center-steward[bot]@users.noreply.github.com> Date: Fri, 15 Sep 2023 00:17:34 +0000 Subject: [PATCH 004/129] Update scalatest to 3.2.17 --- build.sbt | 2 +- src/sbt-test/sbt-scalafix/basic/build.sbt | 2 +- src/sbt-test/sbt-scalafix/inconfig/build.sbt | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/build.sbt b/build.sbt index faa27b1a..eee8ce6b 100644 --- a/build.sbt +++ b/build.sbt @@ -42,7 +42,7 @@ resolvers ++= Resolver.sonatypeOssRepos("public") libraryDependencies ++= Dependencies.all libraryDependencies ++= List( "com.lihaoyi" %% "fansi" % "0.4.0" % Test, - "org.scalatest" %% "scalatest" % "3.2.16" % Test + "org.scalatest" %% "scalatest" % "3.2.17" % Test ) scalaVersion := "2.12.18" diff --git a/src/sbt-test/sbt-scalafix/basic/build.sbt b/src/sbt-test/sbt-scalafix/basic/build.sbt index 1c129e5a..e8d83917 100644 --- a/src/sbt-test/sbt-scalafix/basic/build.sbt +++ b/src/sbt-test/sbt-scalafix/basic/build.sbt @@ -5,7 +5,7 @@ inThisBuild( "org.scalameta" %% "testkit" % "4.3.10" % Test, "org.scalameta" %% "munit" % "0.7.9" % Test, "org.scalacheck" %% "scalacheck" % "1.13.5" % Test, - "org.scalatest" %% "scalatest" % "3.2.16" % Test + "org.scalatest" %% "scalatest" % "3.2.17" % Test ), scalafixDependencies := List( // Custom rule published to Maven Central https://github.com/scalacenter/example-scalafix-rule diff --git a/src/sbt-test/sbt-scalafix/inconfig/build.sbt b/src/sbt-test/sbt-scalafix/inconfig/build.sbt index ef88340a..1147c31c 100644 --- a/src/sbt-test/sbt-scalafix/inconfig/build.sbt +++ b/src/sbt-test/sbt-scalafix/inconfig/build.sbt @@ -5,7 +5,7 @@ inThisBuild( "org.scalameta" %% "testkit" % "4.3.10" % Test, "org.scalameta" %% "munit" % "0.7.9" % Test, "org.scalacheck" %% "scalacheck" % "1.13.5" % Test, - "org.scalatest" %% "scalatest" % "3.2.16" % Test + "org.scalatest" %% "scalatest" % "3.2.17" % Test ), scalafixDependencies := List( // Custom rule published to Maven Central https://github.com/scalacenter/example-scalafix-rule From fc0c62ca4993e19796df7153462d4be416a258fe Mon Sep 17 00:00:00 2001 From: "scala-center-steward[bot]" <111975575+scala-center-steward[bot]@users.noreply.github.com> Date: Sun, 1 Oct 2023 00:18:55 +0000 Subject: [PATCH 005/129] Update interface to 1.0.19 --- project/Dependencies.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project/Dependencies.scala b/project/Dependencies.scala index 00f457e2..75560d83 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -7,6 +7,6 @@ object Dependencies { val all = List( "org.eclipse.jgit" % "org.eclipse.jgit" % "5.13.2.202306221912-r", "ch.epfl.scala" % "scalafix-interfaces" % scalafixVersion, - "io.get-coursier" % "interface" % "1.0.18" + "io.get-coursier" % "interface" % "1.0.19" ) } From 473982f051aa1af06ba4e41f5a4a2aa88174b976 Mon Sep 17 00:00:00 2001 From: "scala-center-steward[bot]" <111975575+scala-center-steward[bot]@users.noreply.github.com> Date: Sun, 1 Oct 2023 00:19:08 +0000 Subject: [PATCH 006/129] Update sbt, scripted-plugin to 1.9.6 --- project/build.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project/build.properties b/project/build.properties index 30409871..27430827 100644 --- a/project/build.properties +++ b/project/build.properties @@ -1 +1 @@ -sbt.version=1.9.4 +sbt.version=1.9.6 From 7de7a5fe0d825e3b22bcc744231ff23750a06a95 Mon Sep 17 00:00:00 2001 From: "scala-center-steward[bot]" <111975575+scala-center-steward[bot]@users.noreply.github.com> Date: Wed, 1 Nov 2023 00:21:32 +0000 Subject: [PATCH 007/129] Update sbt, scripted-plugin to 1.9.7 --- project/build.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project/build.properties b/project/build.properties index 27430827..e8a1e246 100644 --- a/project/build.properties +++ b/project/build.properties @@ -1 +1 @@ -sbt.version=1.9.6 +sbt.version=1.9.7 From a11feafeae9dc09a9e23334b54ac1fe906ae9a34 Mon Sep 17 00:00:00 2001 From: "scala-center-steward[bot]" <111975575+scala-center-steward[bot]@users.noreply.github.com> Date: Wed, 1 Nov 2023 00:21:38 +0000 Subject: [PATCH 008/129] Update scalafmt-core to 3.7.15 --- .scalafmt.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.scalafmt.conf b/.scalafmt.conf index 5626b617..28e8fc54 100644 --- a/.scalafmt.conf +++ b/.scalafmt.conf @@ -1,4 +1,4 @@ -version = "3.7.14" +version = "3.7.15" project.git=true align.preset=none assumeStandardLibraryStripMargin = true From 32a9ff71e3ea4a97c2f4123bfc8215adca6a01e0 Mon Sep 17 00:00:00 2001 From: Brice Jaglin Date: Sun, 12 Nov 2023 18:02:58 +0100 Subject: [PATCH 009/129] improve --files CLI UX To avoid getting false positive errors (missing SemanticDB in presence of semantic rules), scalafix executions with `--files` should not aggregate as they are by nature specific to a given project / Configuration. - prevent usage of scalafixAll --files - validate --files values against unmanagedSourceDirectories - allow accurate completions - avoid aggregated executions: since requested files are not valid outside the project on which the task input was crafted, sbt simply ignores the runs --- .../internal/sbt/ScalafixCompletions.scala | 42 +++++++-- .../scala/scalafix/sbt/ScalafixPlugin.scala | 49 +++++----- .../explicit-files/.scalafix.conf | 2 +- .../sbt-scalafix/explicit-files/build.sbt | 14 ++- .../src/main/scala/KO.scala | 0 .../src/main/scala/OK.scala | 0 .../ok_only/src/main/scala/OK.scala | 1 + .../explicit-files/src/main/scala/OK.scala | 1 + src/sbt-test/sbt-scalafix/explicit-files/test | 44 ++++++--- .../internal/sbt/SbtCompletionsSuite.scala | 90 ++++++++++++++++--- 10 files changed, 187 insertions(+), 56 deletions(-) rename src/sbt-test/sbt-scalafix/explicit-files/{explicit => ok_and_ko}/src/main/scala/KO.scala (100%) rename src/sbt-test/sbt-scalafix/explicit-files/{explicit => ok_and_ko}/src/main/scala/OK.scala (100%) create mode 100644 src/sbt-test/sbt-scalafix/explicit-files/ok_only/src/main/scala/OK.scala create mode 100644 src/sbt-test/sbt-scalafix/explicit-files/src/main/scala/OK.scala diff --git a/src/main/scala/scalafix/internal/sbt/ScalafixCompletions.scala b/src/main/scala/scalafix/internal/sbt/ScalafixCompletions.scala index 0944d3e3..0855c740 100644 --- a/src/main/scala/scalafix/internal/sbt/ScalafixCompletions.scala +++ b/src/main/scala/scalafix/internal/sbt/ScalafixCompletions.scala @@ -10,8 +10,11 @@ import sbt.complete.DefaultParsers._ class ScalafixCompletions( workingDirectory: Path, + // Unfortunately, local rules will not show up as completions in the parser, as that parser can only + // depend on settings, while local rules classpath must be looked up via tasks loadedRules: () => Seq[ScalafixRule], - terminalWidth: Option[Int] + terminalWidth: Option[Int], + allowedTargetFilesPrefixes: Seq[Path] // Nil means all values are valid ) { private type P = Parser[String] @@ -28,14 +31,18 @@ class ScalafixCompletions( valueParser: ArgP ): KVArgP = { val keyParser = Parser.oneOf((key +: keyAliases).map(literal)).examples(key) - val sepValueParser = (sep ~> valueParser).!!!("missing or invalid value") + val sepValueParser = + if (valueParser.toString.contains("!!!")) sep ~> valueParser + else (sep ~> valueParser).!!!("missing or invalid value") keyParser.^^^(sepValueParser) } private def uri(protocol: String): Parser[ShellArgs.Rule] = token(protocol + ":") ~> NotQuoted.map(x => ShellArgs.Rule(s"$protocol:$x")) - private val filepathParser: Parser[Path] = { + private def filepathParser( + filterPrefixes: Option[Seq[Path]] = None + ): Parser[Path] = { def toAbsolutePath(path: Path, cwd: Path): Path = { if (path.isAbsolute) path else cwd.resolve(path) @@ -65,12 +72,25 @@ class ScalafixCompletions( } } + def isAllowedPrefix(path: Path): Boolean = filterPrefixes match { + case Some(prefixes) => + val absolutePath = path.toAbsolutePath.toString + prefixes.map(_.toAbsolutePath.toString).exists { prefix => + absolutePath.startsWith(prefix) || prefix.startsWith(absolutePath) + } + case None => true + } + string - .examples(new AbsolutePathExamples(workingDirectory)) + .examples( + exampleSource = new AbsolutePathExamples(workingDirectory), + maxNumberOfExamples = 25, + removeInvalidExamples = true + ) .map { f => toAbsolutePath(Paths.get(f), workingDirectory) } - .filter(f => Files.exists(f), x => x) + .filter(f => Files.exists(f) && isAllowedPrefix(f), x => x) } private val namedRule: P = { @@ -130,7 +150,7 @@ class ScalafixCompletions( def hide(p: P): P = p.examples() def parser: Parser[ShellArgs] = { - val pathParser: Parser[Path] = token(filepathParser) + val pathParser: Parser[Path] = token(filepathParser()) val fileRule: Parser[ShellArgs.Rule] = (token("file:") ~> pathParser) .map(path => ShellArgs.Rule(path.toUri.toString)) @@ -166,7 +186,15 @@ class ScalafixCompletions( gitDiffParser.map(v => ShellArgs.Extra("--diff-base", Some(v))) } val files: KVArgP = valueAfterKey("--files", "-f") { - pathParser.map(v => ShellArgs.File(v.toString)) + val errorMessage = + if (allowedTargetFilesPrefixes.nonEmpty) + "--files value(s) must reference existing files or directories in unmanagedSourceDirectories; " + + "are you running scalafix on the right project / Configuration?" + else + "--files can only be used on project-level invocations (i.e. myproject / scalafix --files=f.scala)" + token(filepathParser(Some(allowedTargetFilesPrefixes))) + .map(v => ShellArgs.File(v.toString)) + .!!!(errorMessage) } val rules: KVArgP = valueAfterKey("--rules", "-r")(rule) diff --git a/src/main/scala/scalafix/sbt/ScalafixPlugin.scala b/src/main/scala/scalafix/sbt/ScalafixPlugin.scala index 9952f185..36542093 100644 --- a/src/main/scala/scalafix/sbt/ScalafixPlugin.scala +++ b/src/main/scala/scalafix/sbt/ScalafixPlugin.scala @@ -127,13 +127,6 @@ object ScalafixPlugin extends AutoPlugin { Invisible ) - private val scalafixCompletions: SettingKey[ScalafixCompletions] = - SettingKey( - "scalafixCompletions", - "Implementation detail - do not use", - Invisible - ) - // Memoize ScalafixInterface instances initialized with a custom tool classpath across projects & configurations // during task execution, to amortize the classloading cost when invoking scalafix concurrently on many targets private val scalafixInterfaceCache @@ -223,13 +216,6 @@ object ScalafixPlugin extends AutoPlugin { scalafixDependencies = (ThisBuild / scalafixDependencies).value, scalafixCustomResolvers = (ThisBuild / scalafixResolvers).value ), - scalafixCompletions := new ScalafixCompletions( - workingDirectory = (ThisBuild / baseDirectory).value.toPath, - // Unfortunately, local rules will not show up as completions in the parser, as that parser can only - // depend on settings, while local rules classpath must be looked up via tasks - loadedRules = () => scalafixInterfaceProvider.value().availableRules(), - terminalWidth = Some(JLineAccess.terminalWidth) - ), scalafixInterfaceCache := new BlockingCache[ ToolClasspath, ScalafixInterface @@ -299,14 +285,22 @@ object ScalafixPlugin extends AutoPlugin { } - private def scalafixAllInputTask(): Def.Initialize[InputTask[Unit]] = + private def scalafixAllInputTask(): Def.Initialize[InputTask[Unit]] = { + val parser = Def.setting( + new ScalafixCompletions( + workingDirectory = (ThisBuild / baseDirectory).value.toPath, + loadedRules = () => scalafixInterfaceProvider.value().availableRules(), + terminalWidth = Some(JLineAccess.terminalWidth), + allowedTargetFilesPrefixes = Nil + ) + )(_.parser) // workaround https://github.com/sbt/sbt/issues/3572 by invoking directly what Def.inputTaskDyn would via macro - InputTask - .createDyn(InputTask.initParserAsInput(scalafixCompletions(_.parser)))( - Def.task(shellArgs => - scalafixAllTask(shellArgs, thisProject.value, resolvedScoped.value) - ) + InputTask.createDyn(InputTask.initParserAsInput(parser))( + Def.task(shellArgs => + scalafixAllTask(shellArgs, thisProject.value, resolvedScoped.value) ) + ) + } private def scalafixAllTask( shellArgs: ShellArgs, @@ -343,12 +337,23 @@ object ScalafixPlugin extends AutoPlugin { private def scalafixInputTask( config: Configuration - ): Def.Initialize[InputTask[Unit]] = + ): Def.Initialize[InputTask[Unit]] = { + val parser = Def.setting( + new ScalafixCompletions( + workingDirectory = (ThisBuild / baseDirectory).value.toPath, + loadedRules = () => scalafixInterfaceProvider.value().availableRules(), + terminalWidth = Some(JLineAccess.terminalWidth), + allowedTargetFilesPrefixes = + (scalafix / unmanagedSourceDirectories).value.map(_.toPath) + ) + )(_.parser) + // workaround https://github.com/sbt/sbt/issues/3572 by invoking directly what Def.inputTaskDyn would via macro InputTask - .createDyn(InputTask.initParserAsInput(scalafixCompletions(_.parser)))( + .createDyn(InputTask.initParserAsInput(parser))( Def.task(shellArgs => scalafixTask(shellArgs, config)) ) + } private def scalafixTask( shellArgs: ShellArgs, diff --git a/src/sbt-test/sbt-scalafix/explicit-files/.scalafix.conf b/src/sbt-test/sbt-scalafix/explicit-files/.scalafix.conf index 36d4003d..0c1e627d 100644 --- a/src/sbt-test/sbt-scalafix/explicit-files/.scalafix.conf +++ b/src/sbt-test/sbt-scalafix/explicit-files/.scalafix.conf @@ -1,2 +1,2 @@ -rules = [DisableSyntax] +rules = [DisableSyntax, RemoveUnused] DisableSyntax.keywords = [null] diff --git a/src/sbt-test/sbt-scalafix/explicit-files/build.sbt b/src/sbt-test/sbt-scalafix/explicit-files/build.sbt index 8749c7cb..e6a11e44 100644 --- a/src/sbt-test/sbt-scalafix/explicit-files/build.sbt +++ b/src/sbt-test/sbt-scalafix/explicit-files/build.sbt @@ -1,5 +1,15 @@ import _root_.scalafix.sbt.{BuildInfo => Versions} -val explicit = project.settings( - scalaVersion := Versions.scala212 +// support sbt 1.3.x, see https://github.com/sbt/sbt/issues/5110 +Global / semanticdbVersion := scalafixSemanticdb.revision + +inThisBuild( + List( + scalaVersion := Versions.scala212, + scalacOptions += "-Ywarn-unused", + semanticdbEnabled := true + ) ) + +val ok_and_ko = project +val ok_only = project diff --git a/src/sbt-test/sbt-scalafix/explicit-files/explicit/src/main/scala/KO.scala b/src/sbt-test/sbt-scalafix/explicit-files/ok_and_ko/src/main/scala/KO.scala similarity index 100% rename from src/sbt-test/sbt-scalafix/explicit-files/explicit/src/main/scala/KO.scala rename to src/sbt-test/sbt-scalafix/explicit-files/ok_and_ko/src/main/scala/KO.scala diff --git a/src/sbt-test/sbt-scalafix/explicit-files/explicit/src/main/scala/OK.scala b/src/sbt-test/sbt-scalafix/explicit-files/ok_and_ko/src/main/scala/OK.scala similarity index 100% rename from src/sbt-test/sbt-scalafix/explicit-files/explicit/src/main/scala/OK.scala rename to src/sbt-test/sbt-scalafix/explicit-files/ok_and_ko/src/main/scala/OK.scala diff --git a/src/sbt-test/sbt-scalafix/explicit-files/ok_only/src/main/scala/OK.scala b/src/sbt-test/sbt-scalafix/explicit-files/ok_only/src/main/scala/OK.scala new file mode 100644 index 00000000..38e47636 --- /dev/null +++ b/src/sbt-test/sbt-scalafix/explicit-files/ok_only/src/main/scala/OK.scala @@ -0,0 +1 @@ +class OK {} diff --git a/src/sbt-test/sbt-scalafix/explicit-files/src/main/scala/OK.scala b/src/sbt-test/sbt-scalafix/explicit-files/src/main/scala/OK.scala new file mode 100644 index 00000000..38e47636 --- /dev/null +++ b/src/sbt-test/sbt-scalafix/explicit-files/src/main/scala/OK.scala @@ -0,0 +1 @@ +class OK {} diff --git a/src/sbt-test/sbt-scalafix/explicit-files/test b/src/sbt-test/sbt-scalafix/explicit-files/test index ef9247d7..59ff840f 100644 --- a/src/sbt-test/sbt-scalafix/explicit-files/test +++ b/src/sbt-test/sbt-scalafix/explicit-files/test @@ -1,14 +1,38 @@ --> scalafix +> ok_only / scalafix +-> ok_and_ko / scalafix --> scalafix -f=explicit/src/main/scala/KO.scala --> scalafix --files=explicit/src/main/scala/KO.scala --> scalafix -f=explicit/src/main/scala/OK.scala --files=explicit/src/main/scala/KO.scala --> scalafix --files=explicit/src/main/scala/OK.scala -f=explicit/src/main/scala/KO.scala --> scalafix -f=explicit/src/main/scala/KO.scala -f=explicit/src/main/scala/OK.scala +# CORRECT USAGES +# -------------- -> scalafix -f=explicit/src/main/scala/OK.scala -> scalafix --files=explicit/src/main/scala/OK.scala +# Targeting valid files within a project containing invalid files succeeds, with or without a key/value separator +> ok_and_ko / scalafix -f=ok_and_ko/src/main/scala/OK.scala +> ok_and_ko / scalafix --files=ok_and_ko/src/main/scala/OK.scala +> ok_and_ko / scalafix -f ok_and_ko/src/main/scala/OK.scala +> ok_and_ko / scalafix --files ok_and_ko/src/main/scala/OK.scala -> scalafix -f explicit/src/main/scala/OK.scala -> scalafix --files explicit/src/main/scala/OK.scala \ No newline at end of file +# Targeting invalid files fails +-> ok_and_ko / scalafix -f=ok_and_ko/src/main/scala/KO.scala + +# Targeting valid and invalid files fails +-> ok_and_ko / scalafix -f=ok_and_ko/src/main/scala/OK.scala -f=ok_and_ko/src/main/scala/KO.scala +-> ok_and_ko / scalafix -f=ok_and_ko/src/main/scala/KO.scala -f=ok_and_ko/src/main/scala/OK.scala + +# Targeting valid files from the root project succeeds +> scalafix -f=src/main/scala/OK.scala + + +# INCORRECT USAGES +# ---------------- + +# Targeting non-existing files fails +-> ok_only / scalafix -f=ok_only/src/main/scala/NotHere.scala + +# Targeting with scalafixAll valid files from the correct project fails +-> ok_only / scalafixAll -f=ok_only/src/main/scala/OK.scala + +# Targeting valid files from a different project fails +-> ok_only / scalafix -f=ok_and_ko/src/main/scala/OK.scala + +# Targeting valid files from a different configuration fails +-> ok_only / Test / scalafix -f=ok_only/src/main/scala/OK.scala diff --git a/src/test/scala/scalafix/internal/sbt/SbtCompletionsSuite.scala b/src/test/scala/scalafix/internal/sbt/SbtCompletionsSuite.scala index c9067ff2..488b37a4 100644 --- a/src/test/scala/scalafix/internal/sbt/SbtCompletionsSuite.scala +++ b/src/test/scala/scalafix/internal/sbt/SbtCompletionsSuite.scala @@ -41,10 +41,11 @@ class SbtCompletionsSuite extends AnyFunSuite { )() val loadedRules = mainArgs.availableRules.toList - val parser = new ScalafixCompletions( + val defaultParser = new ScalafixCompletions( workingDirectory = fs.workingDirectory.toAbsolutePath, loadedRules = () => loadedRules, - terminalWidth = None + terminalWidth = None, + allowedTargetFilesPrefixes = Seq(fs.workingDirectory.resolve("foo")) ).parser def checkCompletion(name: String, testTags: Tag*)( @@ -58,7 +59,7 @@ class SbtCompletionsSuite extends AnyFunSuite { val input = " " + option val completions = - Parser.completions(parser, input, 0).get.toList.sortBy(_.display) + Parser.completions(defaultParser, input, 0).get.toList.sortBy(_.display) val appends = completions.map(_.append) val displays = completions.map(_.display) @@ -70,6 +71,14 @@ class SbtCompletionsSuite extends AnyFunSuite { def checkArgs( name: String, testTags: Tag* + )(assertArgs: Either[String, ShellArgs] => Unit): Unit = + checkArgs(defaultParser)(name, testTags*)(assertArgs) + + def checkArgs( + parser: Parser[ShellArgs] + )( + name: String, + testTags: Tag* )(assertArgs: Either[String, ShellArgs] => Unit): Unit = { test(name, testTags: _*) { val input = name @@ -137,6 +146,12 @@ class SbtCompletionsSuite extends AnyFunSuite { assert(appends == Seq("es=")) } + checkCompletion("--files=") { (appends, _) => + // allowedTargetFilesPrefixes affects `--files=` completion since bar and buzz are missing + assert(!appends.contains("bar")) + assert(!appends.contains("buzz")) + } + // only provide values suggestion after the key of a key/value arg checkCompletion("--diff-base ") { (appends, _) => assert(appends.nonEmpty) @@ -165,8 +180,9 @@ class SbtCompletionsSuite extends AnyFunSuite { checkCompletion("--rules file:bar/../", SkipWindows) { (appends, displays) => // resolve parent directories - assert(appends.contains("foo")) - assert(displays.contains("bar/../foo")) + // allowedTargetFilesPrefixes does not affect `file:` completion as buzz is not part of them + assert(appends.contains("buzz")) + assert(displays.contains("bar/../buzz")) } // shortcut for --rules @@ -180,36 +196,82 @@ class SbtCompletionsSuite extends AnyFunSuite { } checkArgs("--files --test") { args => - assert(args == Left("""missing or invalid value - | --files --test - | ^""".stripMargin)) + assert( + args == Left( + """--files value(s) must reference existing files or directories in unmanagedSourceDirectories; are you running scalafix on the right project / Configuration? + | --files --test + | ^""".stripMargin + ) + ) } checkArgs("--test --rules=Foo --files=NotHere", SkipWindows) { args => assert(args == Left("""--files=NotHere - |missing or invalid value + |--files value(s) must reference existing files or directories in unmanagedSourceDirectories; are you running scalafix on the right project / Configuration? | --test --rules=Foo --files=NotHere | ^""".stripMargin)) } checkArgs("--test -f= --rules=Foo", SkipWindows) { args => assert(args == Left("""Expected non-whitespace character - |missing or invalid value + |--files value(s) must reference existing files or directories in unmanagedSourceDirectories; are you running scalafix on the right project / Configuration? | --test -f= --rules=Foo | ^""".stripMargin)) } checkArgs("--test -f --rules=Foo", SkipWindows) { args => - assert(args == Left("""missing or invalid value - | --test -f --rules=Foo - | ^""".stripMargin)) + assert( + args == Left( + """--files value(s) must reference existing files or directories in unmanagedSourceDirectories; are you running scalafix on the right project / Configuration? + | --test -f --rules=Foo + | ^""".stripMargin + ) + ) } checkArgs("--test --rules=Foo -f", SkipWindows) { args => assert(args == Left("""-f - |missing or invalid value + |Expected '=' + |Expected ' ' | --test --rules=Foo -f | ^""".stripMargin)) } + checkArgs("--test -f foo/f.scala", SkipWindows) { args => + assert( + args == Right( + ShellArgs( + files = fs.workingDirectory.toAbsolutePath + .resolve("foo/f.scala") + .toString :: Nil, + extra = "--test" :: Nil + ) + ) + ) + } + + checkArgs("--test -f bar/b.scala", SkipWindows) { args => + assert( + args == Left( + """--files value(s) must reference existing files or directories in unmanagedSourceDirectories; are you running scalafix on the right project / Configuration? + | --test -f bar/b.scala + | ^""".stripMargin + ) + ) + } + + checkArgs( + new ScalafixCompletions( + workingDirectory = fs.workingDirectory.toAbsolutePath, + loadedRules = () => Nil, + terminalWidth = None, + allowedTargetFilesPrefixes = Nil + ).parser + )("--test --files=foo", SkipWindows) { args => + assert(args == Left("""--files=foo + |--files can only be used on project-level invocations (i.e. myproject / scalafix --files=f.scala) + | --test --files=foo + | ^""".stripMargin)) + } + } From a08d3d2d116b96ee78880aa817b39a75b7b813fe Mon Sep 17 00:00:00 2001 From: Brice Jaglin Date: Sun, 12 Nov 2023 22:23:05 +0100 Subject: [PATCH 010/129] document weird behavior --- src/sbt-test/sbt-scalafix/explicit-files/test | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/sbt-test/sbt-scalafix/explicit-files/test b/src/sbt-test/sbt-scalafix/explicit-files/test index 59ff840f..8ff0b913 100644 --- a/src/sbt-test/sbt-scalafix/explicit-files/test +++ b/src/sbt-test/sbt-scalafix/explicit-files/test @@ -22,6 +22,18 @@ > scalafix -f=src/main/scala/OK.scala +# QUESTIONNABLE USAGES +# -------------------- + +# Targeting valid files from an aggregated project succeeds: +# only the project for which the `--files` value is valid runs the invocation +> scalafix -f=ok_and_ko/src/main/scala/OK.scala + +# Targeting valid files both from an aggregating project and from one of its aggregated project fails: +# no project can validate both `--files` value, so the aggregating project shows the failure +-> scalafix -f=ok_and_ko/src/main/scala/OK.scala -f=src/main/scala/OK.scala + + # INCORRECT USAGES # ---------------- From 0da53750214660710d068c75c79f368e8353ef63 Mon Sep 17 00:00:00 2001 From: "scala-center-steward[bot]" <111975575+scala-center-steward[bot]@users.noreply.github.com> Date: Fri, 15 Dec 2023 00:16:54 +0000 Subject: [PATCH 011/129] Update sbt, scripted-plugin to 1.9.8 --- project/build.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project/build.properties b/project/build.properties index e8a1e246..abbbce5d 100644 --- a/project/build.properties +++ b/project/build.properties @@ -1 +1 @@ -sbt.version=1.9.7 +sbt.version=1.9.8 From 40f53c0074e9354849b89f21275d2c6e3f77481b Mon Sep 17 00:00:00 2001 From: "scala-center-steward[bot]" <111975575+scala-center-steward[bot]@users.noreply.github.com> Date: Fri, 15 Dec 2023 00:16:57 +0000 Subject: [PATCH 012/129] Update scalafmt-core to 3.7.17 --- .scalafmt.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.scalafmt.conf b/.scalafmt.conf index 28e8fc54..ba6d5896 100644 --- a/.scalafmt.conf +++ b/.scalafmt.conf @@ -1,4 +1,4 @@ -version = "3.7.15" +version = "3.7.17" project.git=true align.preset=none assumeStandardLibraryStripMargin = true From 14c30197a7d04b3fc355132881144bd7c95c441b Mon Sep 17 00:00:00 2001 From: "scala-center-steward[bot]" <111975575+scala-center-steward[bot]@users.noreply.github.com> Date: Fri, 15 Dec 2023 00:17:02 +0000 Subject: [PATCH 013/129] Reformat with scalafmt 3.7.17 Executed command: scalafmt --non-interactive --- src/sbt-test/sbt-scalafix/explicit-files/build.sbt | 2 +- src/test/scala/scalafix/internal/sbt/SbtCompletionsSuite.scala | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sbt-test/sbt-scalafix/explicit-files/build.sbt b/src/sbt-test/sbt-scalafix/explicit-files/build.sbt index e6a11e44..4cd1d044 100644 --- a/src/sbt-test/sbt-scalafix/explicit-files/build.sbt +++ b/src/sbt-test/sbt-scalafix/explicit-files/build.sbt @@ -5,7 +5,7 @@ Global / semanticdbVersion := scalafixSemanticdb.revision inThisBuild( List( - scalaVersion := Versions.scala212, + scalaVersion := Versions.scala212, scalacOptions += "-Ywarn-unused", semanticdbEnabled := true ) diff --git a/src/test/scala/scalafix/internal/sbt/SbtCompletionsSuite.scala b/src/test/scala/scalafix/internal/sbt/SbtCompletionsSuite.scala index 488b37a4..4d9f4db7 100644 --- a/src/test/scala/scalafix/internal/sbt/SbtCompletionsSuite.scala +++ b/src/test/scala/scalafix/internal/sbt/SbtCompletionsSuite.scala @@ -181,7 +181,7 @@ class SbtCompletionsSuite extends AnyFunSuite { checkCompletion("--rules file:bar/../", SkipWindows) { (appends, displays) => // resolve parent directories // allowedTargetFilesPrefixes does not affect `file:` completion as buzz is not part of them - assert(appends.contains("buzz")) + assert(appends.contains("buzz")) assert(displays.contains("bar/../buzz")) } From 02063f8c87205e163a65953bc3dad90a3b1fae17 Mon Sep 17 00:00:00 2001 From: "scala-center-steward[bot]" <111975575+scala-center-steward[bot]@users.noreply.github.com> Date: Fri, 15 Dec 2023 00:17:02 +0000 Subject: [PATCH 014/129] Add 'Reformat with scalafmt 3.7.17' to .git-blame-ignore-revs --- .git-blame-ignore-revs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs index d3b99830..ae932b74 100644 --- a/.git-blame-ignore-revs +++ b/.git-blame-ignore-revs @@ -1,2 +1,5 @@ # Scala Steward: Reformat with scalafmt 3.7.14 b7431a3cdd2f4627de48f4f27a361db88949932f + +# Scala Steward: Reformat with scalafmt 3.7.17 +14c30197a7d04b3fc355132881144bd7c95c441b From e254237ad3cd4f8ce126603d457eec1382469dce Mon Sep 17 00:00:00 2001 From: Darren Gibson Date: Tue, 19 Dec 2023 16:28:42 -0600 Subject: [PATCH 015/129] 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 From 396a8403a720ef1b81a0bfb0258df0dffd7243b3 Mon Sep 17 00:00:00 2001 From: "scala-center-steward[bot]" <111975575+scala-center-steward[bot]@users.noreply.github.com> Date: Mon, 15 Jan 2024 00:16:35 +0000 Subject: [PATCH 016/129] Update org.eclipse.jgit to 5.13.3.202401111512-r --- project/Dependencies.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project/Dependencies.scala b/project/Dependencies.scala index 75560d83..aa45e20d 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -5,7 +5,7 @@ object Dependencies { def scalafixVersion: String = "0.11.1" val all = List( - "org.eclipse.jgit" % "org.eclipse.jgit" % "5.13.2.202306221912-r", + "org.eclipse.jgit" % "org.eclipse.jgit" % "5.13.3.202401111512-r", "ch.epfl.scala" % "scalafix-interfaces" % scalafixVersion, "io.get-coursier" % "interface" % "1.0.19" ) From 818fe55b9100fc271b1a08fbb65ce34088bca6f9 Mon Sep 17 00:00:00 2001 From: Brice Jaglin Date: Wed, 24 Jan 2024 00:35:09 +0100 Subject: [PATCH 017/129] docs: ScalafixInterface is now at project-level (#385) --- src/main/scala/scalafix/sbt/ScalafixPlugin.scala | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/main/scala/scalafix/sbt/ScalafixPlugin.scala b/src/main/scala/scalafix/sbt/ScalafixPlugin.scala index 254b567a..d90cc3e8 100644 --- a/src/main/scala/scalafix/sbt/ScalafixPlugin.scala +++ b/src/main/scala/scalafix/sbt/ScalafixPlugin.scala @@ -56,19 +56,17 @@ object ScalafixPlugin extends AutoPlugin { val scalafixResolvers: SettingKey[Seq[Repository]] = settingKey[Seq[Repository]]( "Optional list of Maven/Ivy repositories to use for fetching custom rules. " + - "Must be set in ThisBuild." + "Can be set in ThisBuild or at project-level." ) val scalafixDependencies: SettingKey[Seq[ModuleID]] = settingKey[Seq[ModuleID]]( "Optional list of custom rules to install from Maven Central. " + - "Must be set in ThisBuild." + "Can be set in ThisBuild or at project-level." ) val scalafixScalaBinaryVersion: SettingKey[String] = settingKey[String]( - "The Scala binary version used for scalafix execution. Must be set in ThisBuild. " - + "Defaults to 2.12. Rules must be compiled against that binary version, or for " - + "advanced rules such as ExplicitResultTypes which have a full cross-version, " - + "against the corresponding full version that scalafix is built against." + "The Scala binary version used for scalafix execution. Can be set in ThisBuild or at project-level. " + + "Custom rules must be compiled against that binary version. Defaults to 2.12." ) val scalafixConfig: SettingKey[Option[File]] = settingKey[Option[File]]( From a540aebe45b62f67530d11b484f33b3a46624784 Mon Sep 17 00:00:00 2001 From: kenji yoshida <6b656e6a69@gmail.com> Date: Wed, 24 Jan 2024 15:08:47 +0900 Subject: [PATCH 018/129] add `scalafixCallback` setting key to customize diagnostics reporting (#384) --- .../scalafix/internal/sbt/ScalafixInterface.scala | 6 ++++-- src/main/scala/scalafix/sbt/ScalafixPlugin.scala | 14 ++++++++++++-- .../internal/sbt/SbtCompletionsSuite.scala | 4 +++- .../scalafix/internal/sbt/ScalafixAPISuite.scala | 3 ++- 4 files changed, 21 insertions(+), 6 deletions(-) diff --git a/src/main/scala/scalafix/internal/sbt/ScalafixInterface.scala b/src/main/scala/scalafix/internal/sbt/ScalafixInterface.scala index 4179464f..6cd41c58 100644 --- a/src/main/scala/scalafix/internal/sbt/ScalafixInterface.scala +++ b/src/main/scala/scalafix/internal/sbt/ScalafixInterface.scala @@ -121,11 +121,14 @@ object ScalafixInterface { ScalafixInterface ] = new BlockingCache + private[scalafix] val defaultLogger: Logger = ConsoleLogger(System.out) + def fromToolClasspath( scalafixBinaryScalaVersion: String, scalafixDependencies: Seq[ModuleID], scalafixCustomResolvers: Seq[Repository], - logger: Logger = ConsoleLogger(System.out) + logger: Logger, + callback: ScalafixMainCallback ): () => ScalafixInterface = new LazyValue({ () => fromToolClasspathMemo.getOrElseUpdate( @@ -145,7 +148,6 @@ object ScalafixInterface { "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, diff --git a/src/main/scala/scalafix/sbt/ScalafixPlugin.scala b/src/main/scala/scalafix/sbt/ScalafixPlugin.scala index d90cc3e8..69100f44 100644 --- a/src/main/scala/scalafix/sbt/ScalafixPlugin.scala +++ b/src/main/scala/scalafix/sbt/ScalafixPlugin.scala @@ -9,7 +9,7 @@ import sbt.Keys._ import sbt._ import sbt.internal.sbtscalafix.JLineAccess import sbt.plugins.JvmPlugin -import scalafix.interfaces.ScalafixError +import scalafix.interfaces.{ScalafixError, ScalafixMainCallback} import scalafix.internal.sbt.Arg.ToolClasspath import scalafix.internal.sbt._ @@ -73,6 +73,13 @@ object ScalafixPlugin extends AutoPlugin { "Optional location to .scalafix.conf file to specify which scalafix rules should run. " + "Defaults to the build base directory if a .scalafix.conf file exists." ) + + val scalafixCallback: SettingKey[ScalafixMainCallback] = + settingKey[ScalafixMainCallback]( + "The handler for the diagnostics emitted during scalafix execution. Must be set in ThisBuild. " + + "Defaults to a wrapper around `sbt.Logger`." + ) + val scalafixSemanticdb: ModuleID = scalafixSemanticdb(BuildInfo.scalametaVersion) def scalafixSemanticdb(scalametaVersion: String): ModuleID = @@ -159,7 +166,9 @@ object ScalafixPlugin extends AutoPlugin { scalafixInterfaceProvider := ScalafixInterface.fromToolClasspath( scalafixScalaBinaryVersion.value, scalafixDependencies = scalafixDependencies.value, - scalafixCustomResolvers = scalafixResolvers.value + scalafixCustomResolvers = scalafixResolvers.value, + logger = ScalafixInterface.defaultLogger, + callback = (ThisBuild / scalafixCallback).value ), update := { object SemanticdbScalac { @@ -197,6 +206,7 @@ object ScalafixPlugin extends AutoPlugin { ) override lazy val globalSettings: Seq[Def.Setting[_]] = Seq( + scalafixCallback := new ScalafixLogger(ScalafixInterface.defaultLogger), scalafixConfig := None, // let scalafix-cli try to infer $CWD/.scalafix.conf scalafixOnCompile := false, scalafixCaching := true, diff --git a/src/test/scala/scalafix/internal/sbt/SbtCompletionsSuite.scala b/src/test/scala/scalafix/internal/sbt/SbtCompletionsSuite.scala index 4d9f4db7..cda31de6 100644 --- a/src/test/scala/scalafix/internal/sbt/SbtCompletionsSuite.scala +++ b/src/test/scala/scalafix/internal/sbt/SbtCompletionsSuite.scala @@ -37,7 +37,9 @@ class SbtCompletionsSuite extends AnyFunSuite { MavenRepository.of( "https://oss.sonatype.org/content/repositories/snapshots" ) - ) + ), + ScalafixInterface.defaultLogger, + new ScalafixLogger(ScalafixInterface.defaultLogger) )() val loadedRules = mainArgs.availableRules.toList diff --git a/src/test/scala/scalafix/internal/sbt/ScalafixAPISuite.scala b/src/test/scala/scalafix/internal/sbt/ScalafixAPISuite.scala index 8247afc2..539ef62a 100644 --- a/src/test/scala/scalafix/internal/sbt/ScalafixAPISuite.scala +++ b/src/test/scala/scalafix/internal/sbt/ScalafixAPISuite.scala @@ -41,7 +41,8 @@ class ScalafixAPISuite extends AnyFunSuite { "https://oss.sonatype.org/content/repositories/snapshots" ) ), - logger + logger, + new ScalafixLogger(logger) )() .withArgs(Arg.PrintStream(new PrintStream(baos))) val tmp = Files.createTempFile("scalafix", "Tmp.scala") From a2a185ad61d6bf3445034e9d04c90c35ecd0539b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 5 Feb 2024 16:22:26 +0000 Subject: [PATCH 019/129] Bump release-drafter/release-drafter from 5 to 6 Bumps [release-drafter/release-drafter](https://github.com/release-drafter/release-drafter) from 5 to 6. - [Release notes](https://github.com/release-drafter/release-drafter/releases) - [Commits](https://github.com/release-drafter/release-drafter/compare/v5...v6) --- updated-dependencies: - dependency-name: release-drafter/release-drafter dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/release-drafter.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release-drafter.yml b/.github/workflows/release-drafter.yml index 896edaf4..340cea3e 100644 --- a/.github/workflows/release-drafter.yml +++ b/.github/workflows/release-drafter.yml @@ -9,6 +9,6 @@ jobs: update_release_draft: runs-on: ubuntu-latest steps: - - uses: release-drafter/release-drafter@v5 + - uses: release-drafter/release-drafter@v6 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} From 29f28bfdd8ba619331a26e763ed4defae47d1b43 Mon Sep 17 00:00:00 2001 From: "scala-center-steward[bot]" <111975575+scala-center-steward[bot]@users.noreply.github.com> Date: Thu, 15 Feb 2024 00:15:23 +0000 Subject: [PATCH 020/129] Update scalatest to 3.2.18 --- build.sbt | 2 +- src/sbt-test/sbt-scalafix/basic/build.sbt | 2 +- src/sbt-test/sbt-scalafix/inconfig/build.sbt | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/build.sbt b/build.sbt index eee8ce6b..435022ce 100644 --- a/build.sbt +++ b/build.sbt @@ -42,7 +42,7 @@ resolvers ++= Resolver.sonatypeOssRepos("public") libraryDependencies ++= Dependencies.all libraryDependencies ++= List( "com.lihaoyi" %% "fansi" % "0.4.0" % Test, - "org.scalatest" %% "scalatest" % "3.2.17" % Test + "org.scalatest" %% "scalatest" % "3.2.18" % Test ) scalaVersion := "2.12.18" diff --git a/src/sbt-test/sbt-scalafix/basic/build.sbt b/src/sbt-test/sbt-scalafix/basic/build.sbt index e8d83917..bd462e74 100644 --- a/src/sbt-test/sbt-scalafix/basic/build.sbt +++ b/src/sbt-test/sbt-scalafix/basic/build.sbt @@ -5,7 +5,7 @@ inThisBuild( "org.scalameta" %% "testkit" % "4.3.10" % Test, "org.scalameta" %% "munit" % "0.7.9" % Test, "org.scalacheck" %% "scalacheck" % "1.13.5" % Test, - "org.scalatest" %% "scalatest" % "3.2.17" % Test + "org.scalatest" %% "scalatest" % "3.2.18" % Test ), scalafixDependencies := List( // Custom rule published to Maven Central https://github.com/scalacenter/example-scalafix-rule diff --git a/src/sbt-test/sbt-scalafix/inconfig/build.sbt b/src/sbt-test/sbt-scalafix/inconfig/build.sbt index 1147c31c..8cb7cabf 100644 --- a/src/sbt-test/sbt-scalafix/inconfig/build.sbt +++ b/src/sbt-test/sbt-scalafix/inconfig/build.sbt @@ -5,7 +5,7 @@ inThisBuild( "org.scalameta" %% "testkit" % "4.3.10" % Test, "org.scalameta" %% "munit" % "0.7.9" % Test, "org.scalacheck" %% "scalacheck" % "1.13.5" % Test, - "org.scalatest" %% "scalatest" % "3.2.17" % Test + "org.scalatest" %% "scalatest" % "3.2.18" % Test ), scalafixDependencies := List( // Custom rule published to Maven Central https://github.com/scalacenter/example-scalafix-rule From e92dbd81b63f87dbbd86164c2d5ba14ee87736c1 Mon Sep 17 00:00:00 2001 From: Brice Jaglin Date: Fri, 23 Feb 2024 00:12:08 +0100 Subject: [PATCH 021/129] build with and test against Scala 2.12.19 --- build.sbt | 2 +- src/sbt-test/sbt-1.5/scalafixEnable/build.sbt | 2 +- src/sbt-test/sbt-scalafix/basic/build.sbt | 2 +- src/sbt-test/sbt-scalafix/inconfig/build.sbt | 2 +- src/sbt-test/sbt-scalafix/root-validation/build.sbt | 2 +- src/sbt-test/sbt-scalafix/semanticdb-enabled/build.sbt | 2 +- src/sbt-test/skip-java17/scalafixResolvers/build.sbt | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/build.sbt b/build.sbt index eee8ce6b..c42718f5 100644 --- a/build.sbt +++ b/build.sbt @@ -45,7 +45,7 @@ libraryDependencies ++= List( "org.scalatest" %% "scalatest" % "3.2.17" % Test ) -scalaVersion := "2.12.18" +scalaVersion := "2.12.19" // keep this as low as possible to avoid running into binary incompatibility such as https://github.com/sbt/sbt/issues/5049 pluginCrossBuild / sbtVersion := "1.3.1" diff --git a/src/sbt-test/sbt-1.5/scalafixEnable/build.sbt b/src/sbt-test/sbt-1.5/scalafixEnable/build.sbt index ea288dcc..86c4551d 100644 --- a/src/sbt-test/sbt-1.5/scalafixEnable/build.sbt +++ b/src/sbt-test/sbt-1.5/scalafixEnable/build.sbt @@ -15,7 +15,7 @@ lazy val scala211 = project lazy val scala212 = project .in(file("scala212")) .settings( - scalaVersion := "2.12.18" // supported by semanticdb-scalac + scalaVersion := "2.12.19" // supported by semanticdb-scalac ) lazy val scala3 = project diff --git a/src/sbt-test/sbt-scalafix/basic/build.sbt b/src/sbt-test/sbt-scalafix/basic/build.sbt index e8d83917..9163c6dd 100644 --- a/src/sbt-test/sbt-scalafix/basic/build.sbt +++ b/src/sbt-test/sbt-scalafix/basic/build.sbt @@ -1,6 +1,6 @@ inThisBuild( List( - scalaVersion := "2.12.18", + scalaVersion := "2.12.19", libraryDependencies ++= List( "org.scalameta" %% "testkit" % "4.3.10" % Test, "org.scalameta" %% "munit" % "0.7.9" % Test, diff --git a/src/sbt-test/sbt-scalafix/inconfig/build.sbt b/src/sbt-test/sbt-scalafix/inconfig/build.sbt index 1147c31c..44132597 100644 --- a/src/sbt-test/sbt-scalafix/inconfig/build.sbt +++ b/src/sbt-test/sbt-scalafix/inconfig/build.sbt @@ -1,6 +1,6 @@ inThisBuild( List( - scalaVersion := "2.12.18", + scalaVersion := "2.12.19", libraryDependencies ++= List( "org.scalameta" %% "testkit" % "4.3.10" % Test, "org.scalameta" %% "munit" % "0.7.9" % Test, diff --git a/src/sbt-test/sbt-scalafix/root-validation/build.sbt b/src/sbt-test/sbt-scalafix/root-validation/build.sbt index 0062c35d..e8003f6c 100644 --- a/src/sbt-test/sbt-scalafix/root-validation/build.sbt +++ b/src/sbt-test/sbt-scalafix/root-validation/build.sbt @@ -1,6 +1,6 @@ inThisBuild( List( - scalaVersion := "2.12.18" + scalaVersion := "2.12.19" ) ) diff --git a/src/sbt-test/sbt-scalafix/semanticdb-enabled/build.sbt b/src/sbt-test/sbt-scalafix/semanticdb-enabled/build.sbt index 884f00b9..35ed4c5b 100644 --- a/src/sbt-test/sbt-scalafix/semanticdb-enabled/build.sbt +++ b/src/sbt-test/sbt-scalafix/semanticdb-enabled/build.sbt @@ -1,6 +1,6 @@ inThisBuild( List( - scalaVersion := "2.12.18", + scalaVersion := "2.12.19", semanticdbEnabled := true, semanticdbVersion := scalafixSemanticdb.revision ) diff --git a/src/sbt-test/skip-java17/scalafixResolvers/build.sbt b/src/sbt-test/skip-java17/scalafixResolvers/build.sbt index 00660558..3cda631a 100644 --- a/src/sbt-test/skip-java17/scalafixResolvers/build.sbt +++ b/src/sbt-test/skip-java17/scalafixResolvers/build.sbt @@ -1,4 +1,4 @@ -scalaVersion := "2.12.18" +scalaVersion := "2.12.19" TaskKey[Unit]("check") := { val expectedRepositories: Seq[String] = Seq( From c65bcdb411d8b0cfba3bafcea173ead9ac99d9c3 Mon Sep 17 00:00:00 2001 From: Brice Jaglin Date: Sat, 24 Feb 2024 10:21:26 +0100 Subject: [PATCH 022/129] test against JDK21 (LTS) --- .github/workflows/ci.yml | 13 ++++++++++++- build.sbt | 10 +++++++--- 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1e9bacd9..67518a44 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -11,6 +11,8 @@ jobs: steps: - uses: actions/checkout@v4 - uses: olafurpg/setup-scala@v14 + with: + java-version: 8 - run: sbt test scripted jdk11: name: JDK11 tests @@ -19,7 +21,7 @@ jobs: - uses: actions/checkout@v4 - uses: olafurpg/setup-scala@v14 with: - java-version: adopt@1.11 + java-version: 11 - run: sbt test scripted jdk17: name: JDK17 tests @@ -30,6 +32,15 @@ jobs: with: java-version: 17 - run: sbt "test; scripted sbt-scalafix/*" + jdk21: + name: JDK21 tests + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: olafurpg/setup-scala@v14 + with: + java-version: 21 + - run: sbt "test; scripted sbt-scalafix/*" windows: name: Windows tests runs-on: windows-latest diff --git a/build.sbt b/build.sbt index 456ab008..f2fd7a88 100644 --- a/build.sbt +++ b/build.sbt @@ -51,10 +51,14 @@ scalaVersion := "2.12.19" pluginCrossBuild / sbtVersion := "1.3.1" scriptedSbt := { - if (System.getProperty("java.specification.version").toDouble < 17) - "1.3.0" - else + val jdk = System.getProperty("java.specification.version").toDouble + + if (jdk >= 21) + "1.9.0" // first release that supports JDK21 + else if (jdk >= 17) "1.5.5" // first release that supports JDK17 + else + "1.3.0" } libraryDependencies += compilerPlugin(scalafixSemanticdb) From f87c5c45dabbf8dbffc4179e951d5643fb7a972e Mon Sep 17 00:00:00 2001 From: Brice Jaglin Date: Sat, 24 Feb 2024 11:40:22 +0100 Subject: [PATCH 023/129] old sbt versions can run on recent JDKs when loaded with scripted --- build.sbt | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/build.sbt b/build.sbt index f2fd7a88..a37fa572 100644 --- a/build.sbt +++ b/build.sbt @@ -50,17 +50,6 @@ scalaVersion := "2.12.19" // keep this as low as possible to avoid running into binary incompatibility such as https://github.com/sbt/sbt/issues/5049 pluginCrossBuild / sbtVersion := "1.3.1" -scriptedSbt := { - val jdk = System.getProperty("java.specification.version").toDouble - - if (jdk >= 21) - "1.9.0" // first release that supports JDK21 - else if (jdk >= 17) - "1.5.5" // first release that supports JDK17 - else - "1.3.0" -} - libraryDependencies += compilerPlugin(scalafixSemanticdb) scalacOptions ++= List("-Ywarn-unused", "-Yrangepos") From e118f085a9e37a722be76d48197ce7fb5115e4bb Mon Sep 17 00:00:00 2001 From: Brice Jaglin Date: Sat, 24 Feb 2024 11:44:36 +0100 Subject: [PATCH 024/129] sbt 1.9.9 --- project/build.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project/build.properties b/project/build.properties index abbbce5d..04267b14 100644 --- a/project/build.properties +++ b/project/build.properties @@ -1 +1 @@ -sbt.version=1.9.8 +sbt.version=1.9.9 From 63ce39e6a62368f461eaec22ab961d941c0995e6 Mon Sep 17 00:00:00 2001 From: Brice Jaglin Date: Sat, 24 Feb 2024 09:31:39 +0100 Subject: [PATCH 025/129] remove unnecessary pin of sbt version in scripted --- .../sbt-scalafix/semanticdb-enabled/project/build.properties | 1 - 1 file changed, 1 deletion(-) delete mode 100644 src/sbt-test/sbt-scalafix/semanticdb-enabled/project/build.properties diff --git a/src/sbt-test/sbt-scalafix/semanticdb-enabled/project/build.properties b/src/sbt-test/sbt-scalafix/semanticdb-enabled/project/build.properties deleted file mode 100644 index 06703e34..00000000 --- a/src/sbt-test/sbt-scalafix/semanticdb-enabled/project/build.properties +++ /dev/null @@ -1 +0,0 @@ -sbt.version=1.3.9 From 149e3bf1e5753909505e45498f5d07e12742cd2a Mon Sep 17 00:00:00 2001 From: Brice Jaglin Date: Sat, 24 Feb 2024 14:19:06 +0100 Subject: [PATCH 026/129] test against scala 2.13.13 Don't use scalafix.sbt.BuildInfo since we want to test a version that is not used upstream yet (exercising scalameta's back-publishing). --- .../sbt-scalafix/semanticdb-enabled/build.sbt | 17 ++++++++++------- .../src/main/scala/example/Example.scala | 0 .../src/main/scala/example/Example.scala | 11 +++++++++++ .../sbt-scalafix/semanticdb-enabled/test | 10 +++++++--- 4 files changed, 28 insertions(+), 10 deletions(-) rename src/sbt-test/sbt-scalafix/semanticdb-enabled/{example => scala212}/src/main/scala/example/Example.scala (100%) create mode 100644 src/sbt-test/sbt-scalafix/semanticdb-enabled/scala213/src/main/scala/example/Example.scala diff --git a/src/sbt-test/sbt-scalafix/semanticdb-enabled/build.sbt b/src/sbt-test/sbt-scalafix/semanticdb-enabled/build.sbt index 35ed4c5b..a082fae0 100644 --- a/src/sbt-test/sbt-scalafix/semanticdb-enabled/build.sbt +++ b/src/sbt-test/sbt-scalafix/semanticdb-enabled/build.sbt @@ -1,12 +1,15 @@ -inThisBuild( - List( +// support sbt 1.3.x, see https://github.com/sbt/sbt/issues/5110 +Global / semanticdbVersion := scalafixSemanticdb.revision +ThisBuild / semanticdbEnabled := true + +lazy val scala212 = project + .settings( scalaVersion := "2.12.19", - semanticdbEnabled := true, - semanticdbVersion := scalafixSemanticdb.revision + scalacOptions += "-Ywarn-unused" ) -) -lazy val example = project +lazy val scala213 = project .settings( - scalacOptions += "-Ywarn-unused" + scalaVersion := "2.13.13", + scalacOptions += "-Wunused" ) diff --git a/src/sbt-test/sbt-scalafix/semanticdb-enabled/example/src/main/scala/example/Example.scala b/src/sbt-test/sbt-scalafix/semanticdb-enabled/scala212/src/main/scala/example/Example.scala similarity index 100% rename from src/sbt-test/sbt-scalafix/semanticdb-enabled/example/src/main/scala/example/Example.scala rename to src/sbt-test/sbt-scalafix/semanticdb-enabled/scala212/src/main/scala/example/Example.scala diff --git a/src/sbt-test/sbt-scalafix/semanticdb-enabled/scala213/src/main/scala/example/Example.scala b/src/sbt-test/sbt-scalafix/semanticdb-enabled/scala213/src/main/scala/example/Example.scala new file mode 100644 index 00000000..026d8dd5 --- /dev/null +++ b/src/sbt-test/sbt-scalafix/semanticdb-enabled/scala213/src/main/scala/example/Example.scala @@ -0,0 +1,11 @@ +package example + +import java.util.Map + +object Example { + private val a = 1 + def f(): Unit = { + val b = "" + println("f") + } +} diff --git a/src/sbt-test/sbt-scalafix/semanticdb-enabled/test b/src/sbt-test/sbt-scalafix/semanticdb-enabled/test index e1a13fc4..826b64e8 100644 --- a/src/sbt-test/sbt-scalafix/semanticdb-enabled/test +++ b/src/sbt-test/sbt-scalafix/semanticdb-enabled/test @@ -1,3 +1,7 @@ --> example/scalafix --check -> example/scalafix -> example/scalafix --check +-> scala212/scalafix --check +> scala212/scalafix +> scala212/scalafix --check + +-> scala213/scalafix --check +> scala213/scalafix +> scala213/scalafix --check \ No newline at end of file From b9feabebbab3c1cb3959669edc82ecd8796060b5 Mon Sep 17 00:00:00 2001 From: Brice Jaglin Date: Sat, 24 Feb 2024 23:51:57 +0100 Subject: [PATCH 027/129] switch to coursier/setup-action & use consistent JVM vendor --- .github/workflows/ci.yml | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 67518a44..bbb44de7 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -10,27 +10,27 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - - uses: olafurpg/setup-scala@v14 + - uses: coursier/setup-action@v1 with: - java-version: 8 + jvm: temurin:8 - run: sbt test scripted jdk11: name: JDK11 tests runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - - uses: olafurpg/setup-scala@v14 + - uses: coursier/setup-action@v1 with: - java-version: 11 + jvm: temurin:11 - run: sbt test scripted jdk17: name: JDK17 tests runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - - uses: olafurpg/setup-scala@v14 + - uses: coursier/setup-action@v1 with: - java-version: 17 + jvm: temurin:17 - run: sbt "test; scripted sbt-scalafix/*" jdk21: name: JDK21 tests @@ -39,14 +39,14 @@ jobs: - uses: actions/checkout@v4 - uses: olafurpg/setup-scala@v14 with: - java-version: 21 + jvm: temurin:17 - run: sbt "test; scripted sbt-scalafix/*" windows: name: Windows tests runs-on: windows-latest steps: - uses: actions/checkout@v4 - - uses: olafurpg/setup-scala@v14 + - uses: coursier/setup-action@v1 - run: sbt ci-windows shell: bash checks: From bf323abb9b10c2bc54bbbf92def77b467a3ac52c Mon Sep 17 00:00:00 2001 From: Brice Jaglin Date: Sun, 25 Feb 2024 00:15:15 +0100 Subject: [PATCH 028/129] run more scripted tests on recent JDKs --- .github/workflows/ci.yml | 4 ++-- src/sbt-test/skip-windows/caching/test | 4 ++++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index bbb44de7..a5eaa6fe 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -31,7 +31,7 @@ jobs: - uses: coursier/setup-action@v1 with: jvm: temurin:17 - - run: sbt "test; scripted sbt-scalafix/*" + - run: sbt "test; scripted sbt-*/* skip-windows/*" jdk21: name: JDK21 tests runs-on: ubuntu-latest @@ -40,7 +40,7 @@ jobs: - uses: olafurpg/setup-scala@v14 with: jvm: temurin:17 - - run: sbt "test; scripted sbt-scalafix/*" + - run: sbt "test; scripted sbt-*/* skip-windows/*" windows: name: Windows tests runs-on: windows-latest diff --git a/src/sbt-test/skip-windows/caching/test b/src/sbt-test/skip-windows/caching/test index 4a7e7b36..e51710c0 100644 --- a/src/sbt-test/skip-windows/caching/test +++ b/src/sbt-test/skip-windows/caching/test @@ -1,3 +1,7 @@ +# make sure unmanagedSources does not silently exclude 000-chmoded files on recent +# sbt versions (where input files are stamped with Hash by default) +> set unmanagedSources / inputFileStamper := sbt.nio.FileStamper.LastModified + # a re-run after a no-op, successful run should be cached > set scalafixConfig := Some(file("files/DisableSyntaxNull.scalafix.conf")) $ mkdir src/main/scala From 1ba092023921a9bd00793c7508d2c235c8d92eeb Mon Sep 17 00:00:00 2001 From: Brice Jaglin Date: Sun, 25 Feb 2024 18:38:44 +0100 Subject: [PATCH 029/129] move workaround to static build definition to speed up the run --- src/sbt-test/skip-windows/caching/build.sbt | 6 +++++- src/sbt-test/skip-windows/caching/test | 4 ---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/sbt-test/skip-windows/caching/build.sbt b/src/sbt-test/skip-windows/caching/build.sbt index d97c4be9..bfb4d0ee 100644 --- a/src/sbt-test/skip-windows/caching/build.sbt +++ b/src/sbt-test/skip-windows/caching/build.sbt @@ -9,7 +9,11 @@ inThisBuild( scalafixDependencies += "com.geirsson" %% "example-scalafix-rule" % "1.2.0", resolvers += // for retrieving SNAPSHOTS of `scalafix-interfaces` - Resolver.sonatypeRepo("snapshots") + Resolver.sonatypeRepo("snapshots"), + // On recent sbt versions, make sure unmanagedSources do not silently + // exclude 000-chmoded files (because input files are stamped with + // Hash by default), as it causes false positives in the test suite + unmanagedSources / inputFileStamper := sbt.nio.FileStamper.LastModified ) ) diff --git a/src/sbt-test/skip-windows/caching/test b/src/sbt-test/skip-windows/caching/test index e51710c0..4a7e7b36 100644 --- a/src/sbt-test/skip-windows/caching/test +++ b/src/sbt-test/skip-windows/caching/test @@ -1,7 +1,3 @@ -# make sure unmanagedSources does not silently exclude 000-chmoded files on recent -# sbt versions (where input files are stamped with Hash by default) -> set unmanagedSources / inputFileStamper := sbt.nio.FileStamper.LastModified - # a re-run after a no-op, successful run should be cached > set scalafixConfig := Some(file("files/DisableSyntaxNull.scalafix.conf")) $ mkdir src/main/scala From 6647652e547385c8f02cc60baac7bc5feab00b3e Mon Sep 17 00:00:00 2001 From: Brice Jaglin Date: Sun, 25 Feb 2024 01:00:29 +0100 Subject: [PATCH 030/129] Revert "old sbt versions can run on recent JDKs when loaded with scripted" This reverts commit f87c5c45dabbf8dbffc4179e951d5643fb7a972e. --- build.sbt | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/build.sbt b/build.sbt index a37fa572..f2fd7a88 100644 --- a/build.sbt +++ b/build.sbt @@ -50,6 +50,17 @@ scalaVersion := "2.12.19" // keep this as low as possible to avoid running into binary incompatibility such as https://github.com/sbt/sbt/issues/5049 pluginCrossBuild / sbtVersion := "1.3.1" +scriptedSbt := { + val jdk = System.getProperty("java.specification.version").toDouble + + if (jdk >= 21) + "1.9.0" // first release that supports JDK21 + else if (jdk >= 17) + "1.5.5" // first release that supports JDK17 + else + "1.3.0" +} + libraryDependencies += compilerPlugin(scalafixSemanticdb) scalacOptions ++= List("-Ywarn-unused", "-Yrangepos") From 8ae5b0947c75896edb146e50e328de68263de524 Mon Sep 17 00:00:00 2001 From: Brice Jaglin Date: Sun, 25 Feb 2024 01:21:28 +0100 Subject: [PATCH 031/129] remove unnecessary scripted override for JDK17 --- build.sbt | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/build.sbt b/build.sbt index f2fd7a88..3611c30f 100644 --- a/build.sbt +++ b/build.sbt @@ -55,10 +55,8 @@ scriptedSbt := { if (jdk >= 21) "1.9.0" // first release that supports JDK21 - else if (jdk >= 17) - "1.5.5" // first release that supports JDK17 else - "1.3.0" + (pluginCrossBuild / sbtVersion).value } libraryDependencies += compilerPlugin(scalafixSemanticdb) From 555d1f37f86a11a471bb5c6f2b5f7fff6d57e46c Mon Sep 17 00:00:00 2001 From: Brice Jaglin Date: Sun, 25 Feb 2024 19:21:31 +0100 Subject: [PATCH 032/129] actually use JDK21 for JDK21 CI - don't load artifacts built with old scala versions per https://docs.scala-lang.org/overviews/jdk-compatibility/overview.html - ignore tests with hardcoded old sbt versions, since these were built with Scala versions not supported by JDK21 - we need a way to run these tests with max(scriptedSbt, build.properties) if we want to re-enable them --- .github/workflows/ci.yml | 6 +++--- src/sbt-test/sbt-scalafix/dependency/build.sbt | 2 +- src/sbt-test/sbt-scalafix/local-rules/build.sbt | 4 ++-- src/sbt-test/sbt-scalafix/local-rules/test | 2 +- src/sbt-test/skip-windows/caching/test | 4 ++-- 5 files changed, 9 insertions(+), 9 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a5eaa6fe..66e458ff 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -37,10 +37,10 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - - uses: olafurpg/setup-scala@v14 + - uses: coursier/setup-action@v1 with: - jvm: temurin:17 - - run: sbt "test; scripted sbt-*/* skip-windows/*" + jvm: temurin:21 + - run: sbt "test; scripted sbt-scalafix/* skip-windows/*" windows: name: Windows tests runs-on: windows-latest diff --git a/src/sbt-test/sbt-scalafix/dependency/build.sbt b/src/sbt-test/sbt-scalafix/dependency/build.sbt index c331380b..5f87153f 100644 --- a/src/sbt-test/sbt-scalafix/dependency/build.sbt +++ b/src/sbt-test/sbt-scalafix/dependency/build.sbt @@ -1,4 +1,4 @@ -scalaVersion := "2.12.7" +scalaVersion := "2.12.18" TaskKey[Unit]("check") := { val a = IO.read((Compile / sourceDirectory).value / "scala" / "A.scala") diff --git a/src/sbt-test/sbt-scalafix/local-rules/build.sbt b/src/sbt-test/sbt-scalafix/local-rules/build.sbt index 2a578d31..1fef774b 100644 --- a/src/sbt-test/sbt-scalafix/local-rules/build.sbt +++ b/src/sbt-test/sbt-scalafix/local-rules/build.sbt @@ -7,7 +7,7 @@ inThisBuild( "ch.epfl.scala" %% "example-scalafix-rule" % "1.4.0" ), resolvers += Resolver.sonatypeRepo("snapshots"), - scalaVersion := "2.13.0", // out of sync with scalafix.sbt.BuildInfo.scala213 on purpose + scalaVersion := "2.13.11", // out of sync with scalafix.sbt.BuildInfo.scala213 on purpose scalafixScalaBinaryVersion := // this should be the default in sbt-scalafix 1.0 CrossVersion.binaryScalaVersion(scalaVersion.value) @@ -24,7 +24,7 @@ val rules = project val service = project .dependsOn(rules % ScalafixConfig) .settings( - libraryDependencies += "com.nequissimus" %% "sort-imports" % "0.5.2" % ScalafixConfig + libraryDependencies += "ch.epfl.scala" %% "example-scalafix-rule" % "3.0.0" % ScalafixConfig ) val sameproject = project diff --git a/src/sbt-test/sbt-scalafix/local-rules/test b/src/sbt-test/sbt-scalafix/local-rules/test index 5d3033f0..fbe71e93 100644 --- a/src/sbt-test/sbt-scalafix/local-rules/test +++ b/src/sbt-test/sbt-scalafix/local-rules/test @@ -10,6 +10,6 @@ $ delete rules/src/main/scala/local/NoOp.scala > service/scalafix SyntacticRule # run a rule included from a remote JAR referenced via the Scalafix ivy config -> service/scalafix SortImports +> service/scalafix SyntacticRule > sameproject/scalafix SameProjectSyntacticRule diff --git a/src/sbt-test/skip-windows/caching/test b/src/sbt-test/skip-windows/caching/test index 4a7e7b36..69abd4ba 100644 --- a/src/sbt-test/skip-windows/caching/test +++ b/src/sbt-test/skip-windows/caching/test @@ -335,7 +335,7 @@ $ mkdir src/main/scala $ copy-file files/Valid.scala src/main/scala/Valid.scala > scalafix --check ProcedureSyntax > reload plugins -> 'set dependencyOverrides += "ch.epfl.scala" % "scalafix-interfaces" % "0.9.17+5-86d5550d-SNAPSHOT"' // different than current, requires bumping when using new APIs +> 'set dependencyOverrides += "ch.epfl.scala" % "scalafix-interfaces" % "0.11.0"' // different than current, requires bumping when using new APIs > session save > reload return $ exec chmod 000 src/main/scala/Valid.scala @@ -349,7 +349,7 @@ $ copy-file files/Valid.scala src/main/scala/Valid.scala > set scalafixDependencies in ThisBuild := Nil > scalafix --check ProcedureSyntax > reload plugins -> 'set dependencyOverrides += "ch.epfl.scala" % "scalafix-interfaces" % "0.9.17+7-a1b6d972-SNAPSHOT"' // different than above, requires bumping when using new APIs +> 'set dependencyOverrides += "ch.epfl.scala" % "scalafix-interfaces" % "0.11.0+134-f4dcc6fa-SNAPSHOT"' // different than above, requires bumping when using new APIs > session save > reload return > set scalafixDependencies in ThisBuild := Nil From 94f3cb269dc87120370aa1fbee26b0b0b505ea3c Mon Sep 17 00:00:00 2001 From: "scala-center-steward[bot]" <111975575+scala-center-steward[bot]@users.noreply.github.com> Date: Fri, 1 Mar 2024 00:19:34 +0000 Subject: [PATCH 033/129] Update scalafmt-core to 3.8.0 --- .scalafmt.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.scalafmt.conf b/.scalafmt.conf index ba6d5896..387ba5f1 100644 --- a/.scalafmt.conf +++ b/.scalafmt.conf @@ -1,4 +1,4 @@ -version = "3.7.17" +version = "3.8.0" project.git=true align.preset=none assumeStandardLibraryStripMargin = true From 3f1d46f4372c3340624d53469cf236dbb14c0874 Mon Sep 17 00:00:00 2001 From: "scala-center-steward[bot]" <111975575+scala-center-steward[bot]@users.noreply.github.com> Date: Fri, 1 Mar 2024 00:19:39 +0000 Subject: [PATCH 034/129] Reformat with scalafmt 3.8.0 Executed command: scalafmt --non-interactive --- .../build.sbt | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) 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 index 35f42a51..29d01e99 100644 --- a/src/sbt-test/sbt-1.5/cross-build-scalafixScalaBinaryVersion/build.sbt +++ b/src/sbt-test/sbt-1.5/cross-build-scalafixScalaBinaryVersion/build.sbt @@ -8,16 +8,22 @@ 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()), + 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")) + Some(file(".scalafix-3.conf")) else - Some(file(".scalafix-2.conf")) + Some(file(".scalafix-2.conf")) } ) From eba6ff729928bed88701ead9852bb5f7dd9fd14b Mon Sep 17 00:00:00 2001 From: "scala-center-steward[bot]" <111975575+scala-center-steward[bot]@users.noreply.github.com> Date: Fri, 1 Mar 2024 00:19:39 +0000 Subject: [PATCH 035/129] Add 'Reformat with scalafmt 3.8.0' to .git-blame-ignore-revs --- .git-blame-ignore-revs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs index ae932b74..535f3784 100644 --- a/.git-blame-ignore-revs +++ b/.git-blame-ignore-revs @@ -3,3 +3,6 @@ b7431a3cdd2f4627de48f4f27a361db88949932f # Scala Steward: Reformat with scalafmt 3.7.17 14c30197a7d04b3fc355132881144bd7c95c441b + +# Scala Steward: Reformat with scalafmt 3.8.0 +3f1d46f4372c3340624d53469cf236dbb14c0874 From 1b96fa407975deb40750fe6309935013bab36e46 Mon Sep 17 00:00:00 2001 From: Brice Jaglin Date: Sat, 3 Feb 2024 16:42:09 +0100 Subject: [PATCH 036/129] scalafix 0.12.0 --- project/Dependencies.scala | 2 +- src/test/scala/scalafix/internal/sbt/SbtCompletionsSuite.scala | 3 ++- src/test/scala/scalafix/internal/sbt/ScalafixAPISuite.scala | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/project/Dependencies.scala b/project/Dependencies.scala index aa45e20d..be605d49 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -2,7 +2,7 @@ import sbt._ object Dependencies { val x = List(1) // scalafix:ok - def scalafixVersion: String = "0.11.1" + def scalafixVersion: String = "0.12.0" val all = List( "org.eclipse.jgit" % "org.eclipse.jgit" % "5.13.3.202401111512-r", diff --git a/src/test/scala/scalafix/internal/sbt/SbtCompletionsSuite.scala b/src/test/scala/scalafix/internal/sbt/SbtCompletionsSuite.scala index cda31de6..000f7e61 100644 --- a/src/test/scala/scalafix/internal/sbt/SbtCompletionsSuite.scala +++ b/src/test/scala/scalafix/internal/sbt/SbtCompletionsSuite.scala @@ -119,12 +119,13 @@ class SbtCompletionsSuite extends AnyFunSuite { |NoValInForComprehension | Removes deprecated val inside for-comprehension binders |OrganizeImports + | Organize import statements |ProcedureSyntax | Replaces deprecated procedure syntax with explicit ': Unit =' |RedundantSyntax | Removes redundant syntax such as `final` modifiers on an object |RemoveUnused - | Removes unused imports and terms that reported by the compiler under -Ywarn-unused + | Removes unused imports and terms that reported by the compiler under -Wunused |SemanticRule |SyntacticRule |class: diff --git a/src/test/scala/scalafix/internal/sbt/ScalafixAPISuite.scala b/src/test/scala/scalafix/internal/sbt/ScalafixAPISuite.scala index 539ef62a..313b5985 100644 --- a/src/test/scala/scalafix/internal/sbt/ScalafixAPISuite.scala +++ b/src/test/scala/scalafix/internal/sbt/ScalafixAPISuite.scala @@ -34,7 +34,7 @@ class ScalafixAPISuite extends AnyFunSuite { val interface = ScalafixInterface .fromToolClasspath( "2.12", - List("ch.epfl.scala" %% "example-scalafix-rule" % "3.0.0"), + List("ch.epfl.scala" %% "example-scalafix-rule" % "4.0.0"), Seq( Repository.central, MavenRepository.of( From 1869f7ae57c6215a6de73f44f913e202a6a9c07a Mon Sep 17 00:00:00 2001 From: Jason Pickens Date: Wed, 6 Mar 2024 10:41:49 +1300 Subject: [PATCH 037/129] Rename scalafixBinaryScalaVersion to scalafixScalaBinaryVersion --- .../scalafix/internal/sbt/ScalafixInterface.scala | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/main/scala/scalafix/internal/sbt/ScalafixInterface.scala b/src/main/scala/scalafix/internal/sbt/ScalafixInterface.scala index 6cd41c58..ec85a36f 100644 --- a/src/main/scala/scalafix/internal/sbt/ScalafixInterface.scala +++ b/src/main/scala/scalafix/internal/sbt/ScalafixInterface.scala @@ -124,7 +124,7 @@ object ScalafixInterface { private[scalafix] val defaultLogger: Logger = ConsoleLogger(System.out) def fromToolClasspath( - scalafixBinaryScalaVersion: String, + scalafixScalaBinaryVersion: String, scalafixDependencies: Seq[ModuleID], scalafixCustomResolvers: Seq[Repository], logger: Logger, @@ -133,24 +133,24 @@ object ScalafixInterface { new LazyValue({ () => fromToolClasspathMemo.getOrElseUpdate( ( - scalafixBinaryScalaVersion, + scalafixScalaBinaryVersion, scalafixDependencies, scalafixCustomResolvers ), { - if (scalafixBinaryScalaVersion.startsWith("3")) + if (scalafixScalaBinaryVersion.startsWith("3")) logger.error( - "To use Scalafix on Scala 3 projects, you must unset `scalafixBinaryScalaVersion`. " + + "To use Scalafix on Scala 3 projects, you must unset `scalafixScalaBinaryVersion`. " + "Rules such as ExplicitResultTypes requiring the project version to match the Scalafix " + "version are unsupported for the moment." ) - else if (scalafixBinaryScalaVersion == "2.11") + else if (scalafixScalaBinaryVersion == "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 scalafixArguments = ScalafixAPI .fetchAndClassloadInstance( - scalafixBinaryScalaVersion, + scalafixScalaBinaryVersion, scalafixCustomResolvers.asJava ) .newArguments() From b75e9c1d40ed264de4f56104fe5a33cacc455077 Mon Sep 17 00:00:00 2001 From: xuwei-k <6b656e6a69@gmail.com> Date: Sat, 23 Mar 2024 16:22:37 +0900 Subject: [PATCH 038/129] add scalafixJGitCompletion key. reduce memory usage --- .../internal/sbt/ScalafixCompletions.scala | 4 ++-- .../scala/scalafix/sbt/ScalafixPlugin.scala | 18 +++++++++++++++--- .../internal/sbt/SbtCompletionsSuite.scala | 6 ++++-- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/main/scala/scalafix/internal/sbt/ScalafixCompletions.scala b/src/main/scala/scalafix/internal/sbt/ScalafixCompletions.scala index 0855c740..b6b9c5c3 100644 --- a/src/main/scala/scalafix/internal/sbt/ScalafixCompletions.scala +++ b/src/main/scala/scalafix/internal/sbt/ScalafixCompletions.scala @@ -14,7 +14,8 @@ class ScalafixCompletions( // depend on settings, while local rules classpath must be looked up via tasks loadedRules: () => Seq[ScalafixRule], terminalWidth: Option[Int], - allowedTargetFilesPrefixes: Seq[Path] // Nil means all values are valid + allowedTargetFilesPrefixes: Seq[Path], // Nil means all values are valid + jgitCompletion: JGitCompletion ) { private type P = Parser[String] @@ -116,7 +117,6 @@ class ScalafixCompletions( private val namedRule2: Parser[ShellArgs.Rule] = namedRule.map(s => ShellArgs.Rule(s)) private lazy val gitDiffParser: P = { - val jgitCompletion = new JGitCompletion(workingDirectory) token( NotQuoted, TokenCompletions.fixed((seen, _) => { diff --git a/src/main/scala/scalafix/sbt/ScalafixPlugin.scala b/src/main/scala/scalafix/sbt/ScalafixPlugin.scala index 69100f44..6355f45c 100644 --- a/src/main/scala/scalafix/sbt/ScalafixPlugin.scala +++ b/src/main/scala/scalafix/sbt/ScalafixPlugin.scala @@ -118,6 +118,13 @@ object ScalafixPlugin extends AutoPlugin { import autoImport._ + private val scalafixJGitCompletion: SettingKey[JGitCompletion] = + SettingKey( + "scalafixJGitCompletion", + "Implementation detail - do not use", + Invisible + ) + private val scalafixDummyTask: TaskKey[Unit] = TaskKey( "scalafixDummyTask", @@ -233,7 +240,10 @@ object ScalafixPlugin extends AutoPlugin { override def buildSettings: Seq[Def.Setting[_]] = Seq( - scalafixScalaBinaryVersion := "2.12" + scalafixScalaBinaryVersion := "2.12", + scalafixJGitCompletion := new JGitCompletion( + (ThisBuild / baseDirectory).value.toPath + ) ) lazy val stdoutLogger = ConsoleLogger(System.out) @@ -299,7 +309,8 @@ object ScalafixPlugin extends AutoPlugin { workingDirectory = (ThisBuild / baseDirectory).value.toPath, loadedRules = () => scalafixInterfaceProvider.value().availableRules(), terminalWidth = Some(JLineAccess.terminalWidth), - allowedTargetFilesPrefixes = Nil + allowedTargetFilesPrefixes = Nil, + jgitCompletion = (ThisBuild / scalafixJGitCompletion).value ) )(_.parser) // workaround https://github.com/sbt/sbt/issues/3572 by invoking directly what Def.inputTaskDyn would via macro @@ -352,7 +363,8 @@ object ScalafixPlugin extends AutoPlugin { loadedRules = () => scalafixInterfaceProvider.value().availableRules(), terminalWidth = Some(JLineAccess.terminalWidth), allowedTargetFilesPrefixes = - (scalafix / unmanagedSourceDirectories).value.map(_.toPath) + (scalafix / unmanagedSourceDirectories).value.map(_.toPath), + jgitCompletion = (ThisBuild / scalafixJGitCompletion).value ) )(_.parser) diff --git a/src/test/scala/scalafix/internal/sbt/SbtCompletionsSuite.scala b/src/test/scala/scalafix/internal/sbt/SbtCompletionsSuite.scala index 000f7e61..5fa9eec6 100644 --- a/src/test/scala/scalafix/internal/sbt/SbtCompletionsSuite.scala +++ b/src/test/scala/scalafix/internal/sbt/SbtCompletionsSuite.scala @@ -47,7 +47,8 @@ class SbtCompletionsSuite extends AnyFunSuite { workingDirectory = fs.workingDirectory.toAbsolutePath, loadedRules = () => loadedRules, terminalWidth = None, - allowedTargetFilesPrefixes = Seq(fs.workingDirectory.resolve("foo")) + allowedTargetFilesPrefixes = Seq(fs.workingDirectory.resolve("foo")), + jgitCompletion = new JGitCompletion(fs.workingDirectory.toAbsolutePath) ).parser def checkCompletion(name: String, testTags: Tag*)( @@ -268,7 +269,8 @@ class SbtCompletionsSuite extends AnyFunSuite { workingDirectory = fs.workingDirectory.toAbsolutePath, loadedRules = () => Nil, terminalWidth = None, - allowedTargetFilesPrefixes = Nil + allowedTargetFilesPrefixes = Nil, + jgitCompletion = new JGitCompletion(fs.workingDirectory.toAbsolutePath) ).parser )("--test --files=foo", SkipWindows) { args => assert(args == Left("""--files=foo From 13ab8b7c69e20604928899d0217607c140689cc0 Mon Sep 17 00:00:00 2001 From: kenji yoshida <6b656e6a69@gmail.com> Date: Sat, 23 Mar 2024 19:46:51 +0900 Subject: [PATCH 039/129] Apply suggestions from code review Co-authored-by: Brice Jaglin --- src/main/scala/scalafix/sbt/ScalafixPlugin.scala | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/main/scala/scalafix/sbt/ScalafixPlugin.scala b/src/main/scala/scalafix/sbt/ScalafixPlugin.scala index 6355f45c..6a43993d 100644 --- a/src/main/scala/scalafix/sbt/ScalafixPlugin.scala +++ b/src/main/scala/scalafix/sbt/ScalafixPlugin.scala @@ -241,9 +241,7 @@ object ScalafixPlugin extends AutoPlugin { override def buildSettings: Seq[Def.Setting[_]] = Seq( scalafixScalaBinaryVersion := "2.12", - scalafixJGitCompletion := new JGitCompletion( - (ThisBuild / baseDirectory).value.toPath - ) + scalafixJGitCompletion := new JGitCompletion(baseDirectory.value.toPath) ) lazy val stdoutLogger = ConsoleLogger(System.out) @@ -310,7 +308,7 @@ object ScalafixPlugin extends AutoPlugin { loadedRules = () => scalafixInterfaceProvider.value().availableRules(), terminalWidth = Some(JLineAccess.terminalWidth), allowedTargetFilesPrefixes = Nil, - jgitCompletion = (ThisBuild / scalafixJGitCompletion).value + jgitCompletion = scalafixJGitCompletion.value ) )(_.parser) // workaround https://github.com/sbt/sbt/issues/3572 by invoking directly what Def.inputTaskDyn would via macro @@ -364,7 +362,7 @@ object ScalafixPlugin extends AutoPlugin { terminalWidth = Some(JLineAccess.terminalWidth), allowedTargetFilesPrefixes = (scalafix / unmanagedSourceDirectories).value.map(_.toPath), - jgitCompletion = (ThisBuild / scalafixJGitCompletion).value + jgitCompletion = scalafixJGitCompletion.value ) )(_.parser) From 3c0bfdf32213e91d404daab2e7cf0f0e49d13b4d Mon Sep 17 00:00:00 2001 From: "scala-center-steward[bot]" <111975575+scala-center-steward[bot]@users.noreply.github.com> Date: Mon, 1 Apr 2024 00:17:18 +0000 Subject: [PATCH 040/129] Update scalafmt-core to 3.8.1 --- .scalafmt.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.scalafmt.conf b/.scalafmt.conf index 387ba5f1..51535faf 100644 --- a/.scalafmt.conf +++ b/.scalafmt.conf @@ -1,4 +1,4 @@ -version = "3.8.0" +version = "3.8.1" project.git=true align.preset=none assumeStandardLibraryStripMargin = true From 1fd1241bd063360f588b0ef26f42c67184098ae9 Mon Sep 17 00:00:00 2001 From: "scala-center-steward[bot]" <111975575+scala-center-steward[bot]@users.noreply.github.com> Date: Mon, 15 Apr 2024 02:33:50 +0000 Subject: [PATCH 041/129] Update fansi to 0.5.0 --- build.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.sbt b/build.sbt index 3611c30f..fbe3b8a3 100644 --- a/build.sbt +++ b/build.sbt @@ -41,7 +41,7 @@ commands += Command.command("ci-windows") { s => resolvers ++= Resolver.sonatypeOssRepos("public") libraryDependencies ++= Dependencies.all libraryDependencies ++= List( - "com.lihaoyi" %% "fansi" % "0.4.0" % Test, + "com.lihaoyi" %% "fansi" % "0.5.0" % Test, "org.scalatest" %% "scalatest" % "3.2.18" % Test ) From 2b622ec403f85298e44ebf2bddf6abae17c0f169 Mon Sep 17 00:00:00 2001 From: kenji yoshida <6b656e6a69@gmail.com> Date: Tue, 16 Apr 2024 08:38:20 +0900 Subject: [PATCH 042/129] fix JGitCompletions memory leak --- .../internal/sbt/JGitCompletions.scala | 31 ++++++++++++------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/src/main/scala/scalafix/internal/sbt/JGitCompletions.scala b/src/main/scala/scalafix/internal/sbt/JGitCompletions.scala index f473a068..a9208029 100644 --- a/src/main/scala/scalafix/internal/sbt/JGitCompletions.scala +++ b/src/main/scala/scalafix/internal/sbt/JGitCompletions.scala @@ -18,27 +18,35 @@ class JGitCompletion(cwd: Path) { RepositoryCache.FileKey .isGitRepository(cwd.resolve(DOT_GIT).toFile, FS.DETECTED) - private val (refList, refs) = + val branchesAndTags: List[String] = { if (isGitRepository) { val builder = new FileRepositoryBuilder() val repo = builder.readEnvironment().setWorkTree(cwd.toFile).build() - val refList0 = + val refList = repo.getRefDatabase().getRefsByPrefix(RefDatabase.ALL).asScala - val git = new Git(repo) - val refs0 = - Try(git.log().setMaxCount(20).call().asScala.toList).getOrElse(Nil) - (refList0, refs0) + refList.map { ref => Repository.shortenRefName(ref.getName) }.toList } else { - (Nil, Nil) + Nil } - - val branchesAndTags: List[String] = - refList.map { ref => Repository.shortenRefName(ref.getName) }.toList + } private val dateFormatter = new GitDateFormatter( GitDateFormatter.Format.RELATIVE ) - val last20Commits: List[(String, String)] = + val last20Commits: List[(String, String)] = { + val refs = { + if (isGitRepository) { + val builder = new FileRepositoryBuilder() + val repo = builder.readEnvironment().setWorkTree(cwd.toFile).build() + val git = new Git(repo) + val refs0 = + Try(git.log().setMaxCount(20).call().asScala.toList).getOrElse(Nil) + refs0 + } else { + Nil + } + } + refs.map { ref => val relativeCommitTime = dateFormatter.formatDate(refs.head.getCommitterIdent) @@ -46,4 +54,5 @@ class JGitCompletion(cwd: Path) { val short = ref.getShortMessage (s"$abrev -- $short ($relativeCommitTime)", abrev) } + } } From 18c20a67a70c8b6f20fe4df33a4a733042e1733a Mon Sep 17 00:00:00 2001 From: Luigi <31082046+GreyPlane@users.noreply.github.com> Date: Wed, 17 Apr 2024 06:09:10 -0500 Subject: [PATCH 043/129] feat: honor sbt resolvers in addition to scalafixResolvers (#404) --- .jvmopts | 2 +- .../internal/sbt/CoursierRepoResolvers.scala | 178 ++++++++++++++++++ .../scala/scalafix/sbt/ScalafixPlugin.scala | 149 ++++++++++----- src/sbt-test/sbt-scalafix/resolvers/build.sbt | 7 + .../resolvers/project/plugins.sbt | 1 + .../resolvers/src/main/scala/A.scala | 1 + src/sbt-test/sbt-scalafix/resolvers/test | 8 + 7 files changed, 293 insertions(+), 53 deletions(-) create mode 100644 src/main/scala/scalafix/internal/sbt/CoursierRepoResolvers.scala create mode 100644 src/sbt-test/sbt-scalafix/resolvers/build.sbt create mode 100644 src/sbt-test/sbt-scalafix/resolvers/project/plugins.sbt create mode 100644 src/sbt-test/sbt-scalafix/resolvers/src/main/scala/A.scala create mode 100644 src/sbt-test/sbt-scalafix/resolvers/test diff --git a/.jvmopts b/.jvmopts index f9efc610..d188d8a5 100644 --- a/.jvmopts +++ b/.jvmopts @@ -3,4 +3,4 @@ -Xmx4G -XX:ReservedCodeCacheSize=1024m -XX:+TieredCompilation --Dfile.encoding=UTF-8 +-Dfile.encoding=UTF-8 \ No newline at end of file diff --git a/src/main/scala/scalafix/internal/sbt/CoursierRepoResolvers.scala b/src/main/scala/scalafix/internal/sbt/CoursierRepoResolvers.scala new file mode 100644 index 00000000..314e0060 --- /dev/null +++ b/src/main/scala/scalafix/internal/sbt/CoursierRepoResolvers.scala @@ -0,0 +1,178 @@ +package scalafix.internal.sbt + +import coursierapi.{Credentials, IvyRepository, MavenRepository, Repository} +import org.apache.ivy.plugins.resolver.IBiblioResolver +import sbt.librarymanagement.{Configuration as _, MavenRepository as _, *} +import sbt.util.Logger + +import java.net.MalformedURLException +import java.nio.file.Paths +import scala.collection.JavaConverters.* + +// vendor from sbt-coursier/lmcoursier.internal.Resolvers +object CoursierRepoResolvers { + + private def mavenCompatibleBaseOpt(patterns: Patterns): Option[String] = + if (patterns.isMavenCompatible) { + // input : /Users/user/custom/repo/[organisation]/[module](_[scalaVersion])(_[sbtVersion])/[revision]/[artifact]-[revision](-[classifier]).[ext] + // output : /Users/user/custom/repo/ + def basePattern(pattern: String): String = + pattern.takeWhile(c => c != '[' && c != '(') + + val baseIvyPattern = basePattern(patterns.ivyPatterns.head) + val baseArtifactPattern = basePattern(patterns.artifactPatterns.head) + + if (baseIvyPattern == baseArtifactPattern) + Some(baseIvyPattern) + else + None + } else + None + + private def mavenRepositoryOpt( + root: String, + log: Logger, + credentialsByHost: Map[String, Credentials] + ): Option[MavenRepository] = + try { + val rootURI = java.net.URI.create( + root + ) // ensure root is a URL whose protocol can be handled here + val root0 = if (root.endsWith("/")) root else root + "/" + val mavenRepository = MavenRepository.of(root0) + + Some( + credentialsByHost + .get(rootURI.getHost) + .fold(mavenRepository)(mavenRepository.withCredentials) + ) + } catch { + case e: MalformedURLException => + log.warn( + "Error parsing Maven repository base " + + root + + Option(e.getMessage).fold("")(" (" + _ + ")") + + ", ignoring it" + ) + + None + } + + // this handles whitespace in path + private def pathToUriString(path: String): String = { + val stopAtIdx = path.indexWhere(c => c == '[' || c == '$' || c == '(') + if (stopAtIdx > 0) { + val (pathPart, patternPart) = path.splitAt(stopAtIdx) + Paths.get(pathPart).toUri.toASCIIString + patternPart + } else if (stopAtIdx == 0) + "file://" + path + else + Paths.get(path).toUri.toASCIIString + } + + def repository( + resolver: Resolver, + log: Logger, + credentialsByHost: Map[String, Credentials] + ): Option[Repository] = + resolver match { + case r: sbt.librarymanagement.MavenRepository => + mavenRepositoryOpt(r.root, log, credentialsByHost) + + case r: FileRepository + if r.patterns.ivyPatterns.lengthCompare(1) == 0 && + r.patterns.artifactPatterns.lengthCompare(1) == 0 => + val mavenCompatibleBaseOpt0 = mavenCompatibleBaseOpt(r.patterns) + + mavenCompatibleBaseOpt0 match { + case None => + val repo = IvyRepository + .of(pathToUriString(r.patterns.artifactPatterns.head)) + .withMetadataPattern(pathToUriString(r.patterns.ivyPatterns.head)) + .withDropInfoAttributes(true) + + Some(repo) + + case Some(mavenCompatibleBase) => + mavenRepositoryOpt( + pathToUriString(mavenCompatibleBase), + log, + credentialsByHost + ) + } + + case r: URLRepository if patternMatchGuard(r.patterns) => + parseMavenCompatResolver(log, r.patterns, credentialsByHost) + + case raw: RawRepository + if raw.name == "inter-project" => // sbt.RawRepository.equals just compares names anyway + None + + // Pattern Match resolver-type-specific RawRepositories + case IBiblioRepository(p) => + parseMavenCompatResolver( + log, + p, + credentialsByHost + ) + + case other => + log.warn(s"Unrecognized repository ${other.name}, ignoring it") + None + } + + private object IBiblioRepository { + + private def stringVector(v: java.util.List[_]): Vector[String] = + Option(v).map(_.asScala.toVector).getOrElse(Vector.empty).collect { + case s: String => s + } + + private def patterns(resolver: IBiblioResolver): Patterns = Patterns( + ivyPatterns = stringVector(resolver.getIvyPatterns), + artifactPatterns = stringVector(resolver.getArtifactPatterns), + isMavenCompatible = resolver.isM2compatible, + descriptorOptional = !resolver.isUseMavenMetadata, + skipConsistencyCheck = !resolver.isCheckconsistency + ) + + def unapply(r: Resolver): Option[Patterns] = + r match { + case raw: RawRepository => + raw.resolver match { + case b: IBiblioResolver => + Some(patterns(b)) + .filter(patternMatchGuard) + case _ => + None + } + case _ => + None + } + } + + private def patternMatchGuard(patterns: Patterns): Boolean = + patterns.ivyPatterns.lengthCompare(1) == 0 && + patterns.artifactPatterns.lengthCompare(1) == 0 + + private def parseMavenCompatResolver( + log: Logger, + patterns: Patterns, + credentialsByHost: Map[String, Credentials] + ): Option[Repository] = { + val mavenCompatibleBaseOpt0 = mavenCompatibleBaseOpt(patterns) + + mavenCompatibleBaseOpt0 match { + case None => + val repo = IvyRepository + .of(pathToUriString(patterns.artifactPatterns.head)) + .withMetadataPattern(pathToUriString(patterns.ivyPatterns.head)) + .withDropInfoAttributes(true) + + Some(repo) + + case Some(mavenCompatibleBase) => + mavenRepositoryOpt(mavenCompatibleBase, log, credentialsByHost) + } + } +} diff --git a/src/main/scala/scalafix/sbt/ScalafixPlugin.scala b/src/main/scala/scalafix/sbt/ScalafixPlugin.scala index 6a43993d..6fd38862 100644 --- a/src/main/scala/scalafix/sbt/ScalafixPlugin.scala +++ b/src/main/scala/scalafix/sbt/ScalafixPlugin.scala @@ -2,21 +2,23 @@ package scalafix.sbt import java.io.PrintStream import java.nio.file.{Path, Paths} - import coursierapi.Repository import sbt.KeyRanks.Invisible -import sbt.Keys._ -import sbt._ +import sbt.Keys.* +import sbt.* import sbt.internal.sbtscalafix.JLineAccess +import sbt.internal.util.complete.Parser import sbt.plugins.JvmPlugin import scalafix.interfaces.{ScalafixError, ScalafixMainCallback} import scalafix.internal.sbt.Arg.ToolClasspath -import scalafix.internal.sbt._ +import scalafix.internal.sbt.* import scala.collection.JavaConverters.collectionAsScalaIterableConverter import scala.util.control.NoStackTrace import sbt.librarymanagement.ResolveException +import scala.util.Try + object ScalafixPlugin extends AutoPlugin { override def trigger: PluginTrigger = allRequirements override def requires: Plugins = JvmPlugin @@ -132,13 +134,39 @@ object ScalafixPlugin extends AutoPlugin { Invisible ) - private val scalafixInterfaceProvider: SettingKey[() => ScalafixInterface] = + private val scalafixInterfaceProvider + : SettingKey[Seq[Repository] => ScalafixInterface] = SettingKey( "scalafixInterfaceProvider", "Implementation detail - do not use", Invisible ) + private def scalafixParser: Def.Initialize[Parser[ShellArgs]] = + Def.setting { + val allowedTargetFilesPrefixes = + // only set in a config-level scope (i.e. scalafix, and not scalafixAll) + (scalafix / unmanagedSourceDirectories).?.value.toSeq.flatten + .map(_.toPath) + new ScalafixCompletions( + workingDirectory = (ThisBuild / baseDirectory).value.toPath, + loadedRules = () => + // `scalafixDependencies` might be resolvable only from one of the + // `scalafixSbtResolversAsCoursierRepositories` that we can't look up + // here, as it's a task and we are in a settings context. Therefore + // we fallback to an empty list of rules in case of resolution error + // to keep providing completions for the rest. + Try { + scalafixInterfaceProvider + .value((ThisBuild / scalafixResolvers).value) + .availableRules() + }.getOrElse(Seq.empty), + terminalWidth = Some(JLineAccess.terminalWidth), + allowedTargetFilesPrefixes = allowedTargetFilesPrefixes, + jgitCompletion = scalafixJGitCompletion.value + ) + }(_.parser) + // Memoize ScalafixInterface instances initialized with a custom tool classpath across projects & configurations // during task execution, to amortize the classloading cost when invoking scalafix concurrently on many targets private val scalafixInterfaceCache @@ -149,6 +177,13 @@ object ScalafixPlugin extends AutoPlugin { Invisible ) + private val scalafixSbtResolversAsCoursierRepositories + : TaskKey[Seq[Repository]] = TaskKey( + "scalafixSbtResolversAsCoursierRepositories", + "Implementation detail - do not use", + Invisible + ) + private lazy val cachingStyle = { val useLastModifiedCachingStyle = sys.props.get("sbt-scalafix.uselastmodified") == Some("true") @@ -156,6 +191,19 @@ object ScalafixPlugin extends AutoPlugin { else FileInfo.hash } + private lazy val defaultScalafixResolvers = + // Repository.defaults() defaults to Repository.ivy2Local() and Repository.central(). These can be overridden per + // env variable, e.g., export COURSIER_REPOSITORIES="ivy2Local|central|sonatype:releases|jitpack|https://corporate.com/repo". + // See https://github.com/coursier/coursier/blob/master/modules/coursier/jvm/src/main/scala/coursier/PlatformResolve.scala#L19-L68 + // and https://get-coursier.io/docs/other-repositories for more details. + // Also see src/sbt-test/sbt-scalafix/scalafixResolvers/test for a scripted test preserving this behavior. + Repository.defaults().asScala.toSeq ++ + Seq( + coursierapi.MavenRepository.of( + "https://oss.sonatype.org/content/repositories/public" + ) + ) + override lazy val projectConfigurations: Seq[Configuration] = Seq(ScalafixConfig) @@ -170,13 +218,17 @@ object ScalafixPlugin extends AutoPlugin { SettingKey[Boolean]("bspEnabled") := false ) ), - scalafixInterfaceProvider := ScalafixInterface.fromToolClasspath( - scalafixScalaBinaryVersion.value, - scalafixDependencies = scalafixDependencies.value, - scalafixCustomResolvers = scalafixResolvers.value, - logger = ScalafixInterface.defaultLogger, - callback = (ThisBuild / scalafixCallback).value - ), + scalafixInterfaceProvider := { (customResolvers: Seq[Repository]) => + ScalafixInterface + .fromToolClasspath( + scalafixScalaBinaryVersion.value, + scalafixDependencies = scalafixDependencies.value, + scalafixCustomResolvers = customResolvers, + logger = ScalafixInterface.defaultLogger, + callback = (ThisBuild / scalafixCallback).value + ) + .apply() + }, update := { object SemanticdbScalac { def unapply(id: ModuleID): Option[String] = @@ -217,18 +269,7 @@ object ScalafixPlugin extends AutoPlugin { scalafixConfig := None, // let scalafix-cli try to infer $CWD/.scalafix.conf scalafixOnCompile := false, scalafixCaching := true, - scalafixResolvers := - // Repository.defaults() defaults to Repository.ivy2Local() and Repository.central(). These can be overridden per - // env variable, e.g., export COURSIER_REPOSITORIES="ivy2Local|central|sonatype:releases|jitpack|https://corporate.com/repo". - // See https://github.com/coursier/coursier/blob/master/modules/coursier/jvm/src/main/scala/coursier/PlatformResolve.scala#L19-L68 - // and https://get-coursier.io/docs/other-repositories for more details. - // Also see src/sbt-test/sbt-scalafix/scalafixResolvers/test for a scripted test preserving this behavior. - Repository.defaults().asScala.toSeq ++ - Seq( - coursierapi.MavenRepository.of( - "https://oss.sonatype.org/content/repositories/public" - ) - ), + scalafixResolvers := defaultScalafixResolvers, scalafixDependencies := Nil, commands += ScalafixEnable.command, scalafixInterfaceCache := new BlockingCache[ @@ -240,6 +281,27 @@ object ScalafixPlugin extends AutoPlugin { override def buildSettings: Seq[Def.Setting[_]] = Seq( + scalafixSbtResolversAsCoursierRepositories := { + val logger = streams.value.log + + val credentialsByHost = Credentials + .allDirect(credentials.value) + .map { dc => + dc.host -> coursierapi.Credentials.of( + dc.userName, + dc.passwd + ) + } + .toMap + + resolvers.value.flatMap { resolver => + CoursierRepoResolvers.repository( + resolver, + logger, + credentialsByHost + ) + } + }, scalafixScalaBinaryVersion := "2.12", scalafixJGitCompletion := new JGitCompletion(baseDirectory.value.toPath) ) @@ -302,17 +364,8 @@ object ScalafixPlugin extends AutoPlugin { } private def scalafixAllInputTask(): Def.Initialize[InputTask[Unit]] = { - val parser = Def.setting( - new ScalafixCompletions( - workingDirectory = (ThisBuild / baseDirectory).value.toPath, - loadedRules = () => scalafixInterfaceProvider.value().availableRules(), - terminalWidth = Some(JLineAccess.terminalWidth), - allowedTargetFilesPrefixes = Nil, - jgitCompletion = scalafixJGitCompletion.value - ) - )(_.parser) // workaround https://github.com/sbt/sbt/issues/3572 by invoking directly what Def.inputTaskDyn would via macro - InputTask.createDyn(InputTask.initParserAsInput(parser))( + InputTask.createDyn(InputTask.initParserAsInput(scalafixParser))( Def.task(shellArgs => scalafixAllTask(shellArgs, thisProject.value, resolvedScoped.value) ) @@ -355,22 +408,10 @@ object ScalafixPlugin extends AutoPlugin { private def scalafixInputTask( config: Configuration ): Def.Initialize[InputTask[Unit]] = { - val parser = Def.setting( - new ScalafixCompletions( - workingDirectory = (ThisBuild / baseDirectory).value.toPath, - loadedRules = () => scalafixInterfaceProvider.value().availableRules(), - terminalWidth = Some(JLineAccess.terminalWidth), - allowedTargetFilesPrefixes = - (scalafix / unmanagedSourceDirectories).value.map(_.toPath), - jgitCompletion = scalafixJGitCompletion.value - ) - )(_.parser) - // workaround https://github.com/sbt/sbt/issues/3572 by invoking directly what Def.inputTaskDyn would via macro - InputTask - .createDyn(InputTask.initParserAsInput(parser))( - Def.task(shellArgs => scalafixTask(shellArgs, config)) - ) + InputTask.createDyn(InputTask.initParserAsInput(scalafixParser))( + Def.task(shellArgs => scalafixTask(shellArgs, config)) + ) } private def scalafixTask( @@ -395,13 +436,15 @@ object ScalafixPlugin extends AutoPlugin { scalafixHelp } else { val scalafixConf = (config / scalafixConfig).value.map(_.toPath) + val resolvers = + ((ThisBuild / scalafixResolvers).value ++ (ThisBuild / scalafixSbtResolversAsCoursierRepositories).value).distinct val (shell, mainInterface0) = scalafixArgsFromShell( shellArgs, - scalafixInterfaceProvider.value, + () => scalafixInterfaceProvider.value(resolvers), scalafixInterfaceCache.value, projectDepsExternal, (ThisBuild / scalafixDependencies).value, - (ThisBuild / scalafixResolvers).value, + resolvers, projectDepsInternal ) val maybeNoCache = @@ -431,8 +474,10 @@ object ScalafixPlugin extends AutoPlugin { private def scalafixHelp: Def.Initialize[Task[Unit]] = Def.task { + val resolvers = + ((ThisBuild / scalafixResolvers).value ++ (ThisBuild / scalafixSbtResolversAsCoursierRepositories).value).distinct scalafixInterfaceProvider - .value() + .value(resolvers) .withArgs(Arg.ParsedArgs(List("--help"))) .run() () diff --git a/src/sbt-test/sbt-scalafix/resolvers/build.sbt b/src/sbt-test/sbt-scalafix/resolvers/build.sbt new file mode 100644 index 00000000..4cadc389 --- /dev/null +++ b/src/sbt-test/sbt-scalafix/resolvers/build.sbt @@ -0,0 +1,7 @@ +ThisBuild / scalafixDependencies := List( + "ch.epfl.scala" %% "example-scalafix-rule" % "4.0.0+3-e9850db5-SNAPSHOT" +) + +import scala.collection.JavaConverters.collectionAsScalaIterableConverter + +ThisBuild / scalafixResolvers := coursierapi.Repository.defaults().asScala.toSeq diff --git a/src/sbt-test/sbt-scalafix/resolvers/project/plugins.sbt b/src/sbt-test/sbt-scalafix/resolvers/project/plugins.sbt new file mode 100644 index 00000000..843726fa --- /dev/null +++ b/src/sbt-test/sbt-scalafix/resolvers/project/plugins.sbt @@ -0,0 +1 @@ +addSbtPlugin("ch.epfl.scala" % "sbt-scalafix" % sys.props("plugin.version")) diff --git a/src/sbt-test/sbt-scalafix/resolvers/src/main/scala/A.scala b/src/sbt-test/sbt-scalafix/resolvers/src/main/scala/A.scala new file mode 100644 index 00000000..69c493db --- /dev/null +++ b/src/sbt-test/sbt-scalafix/resolvers/src/main/scala/A.scala @@ -0,0 +1 @@ +object A diff --git a/src/sbt-test/sbt-scalafix/resolvers/test b/src/sbt-test/sbt-scalafix/resolvers/test new file mode 100644 index 00000000..e97030e8 --- /dev/null +++ b/src/sbt-test/sbt-scalafix/resolvers/test @@ -0,0 +1,8 @@ +# without the proper resolver/repository, invocation of the community rule fails +-> scalafix SyntacticRule + +# once the proper resolver is setup via sbt, dependency fetching works fine and scalafix can be used normally +> set ThisBuild / resolvers += Resolver.sonatypeRepo("snapshots") +-> scalafix --check SyntacticRule +> scalafix SyntacticRule +> scalafix --check SyntacticRule \ No newline at end of file From 1ca5871f3371fb72b6d17caaef0bf8bf62694caf Mon Sep 17 00:00:00 2001 From: Brice Jaglin Date: Wed, 17 Apr 2024 14:31:24 +0200 Subject: [PATCH 044/129] scalafixResolvers can only be set at ThisBuild level --- src/main/scala/scalafix/sbt/ScalafixPlugin.scala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/scala/scalafix/sbt/ScalafixPlugin.scala b/src/main/scala/scalafix/sbt/ScalafixPlugin.scala index 6fd38862..dd03f7ac 100644 --- a/src/main/scala/scalafix/sbt/ScalafixPlugin.scala +++ b/src/main/scala/scalafix/sbt/ScalafixPlugin.scala @@ -58,11 +58,11 @@ object ScalafixPlugin extends AutoPlugin { val scalafixResolvers: SettingKey[Seq[Repository]] = settingKey[Seq[Repository]]( "Optional list of Maven/Ivy repositories to use for fetching custom rules. " + - "Can be set in ThisBuild or at project-level." + "Must be set in ThisBuild." ) val scalafixDependencies: SettingKey[Seq[ModuleID]] = settingKey[Seq[ModuleID]]( - "Optional list of custom rules to install from Maven Central. " + + "Optional list of artifacts to resolve to run custom rules. " + "Can be set in ThisBuild or at project-level." ) val scalafixScalaBinaryVersion: SettingKey[String] = From 6e05af88b61acb49969297f5b019dfb7117d4091 Mon Sep 17 00:00:00 2001 From: Brice Jaglin Date: Wed, 17 Apr 2024 13:25:15 +0200 Subject: [PATCH 045/129] ScalafixInterface now handles memoization so provider key is redundant --- .../internal/sbt/ScalafixInterface.scala | 95 +++++++++---------- .../scala/scalafix/sbt/ScalafixPlugin.scala | 71 +++++++------- .../internal/sbt/SbtCompletionsSuite.scala | 25 +++-- .../internal/sbt/ScalafixAPISuite.scala | 25 +++-- 4 files changed, 104 insertions(+), 112 deletions(-) diff --git a/src/main/scala/scalafix/internal/sbt/ScalafixInterface.scala b/src/main/scala/scalafix/internal/sbt/ScalafixInterface.scala index ec85a36f..516fe3a0 100644 --- a/src/main/scala/scalafix/internal/sbt/ScalafixInterface.scala +++ b/src/main/scala/scalafix/internal/sbt/ScalafixInterface.scala @@ -112,66 +112,61 @@ class ScalafixInterface private ( } object ScalafixInterface { - private class LazyValue[T](thunk: () => T) extends (() => T) { - private lazy val _value = scala.util.Try(thunk()) - override def apply(): T = _value.get - } - private val fromToolClasspathMemo: BlockingCache[ + + private val providerMemoization: BlockingCache[ (String, Seq[ModuleID], Seq[Repository]), ScalafixInterface ] = new BlockingCache private[scalafix] val defaultLogger: Logger = ConsoleLogger(System.out) - def fromToolClasspath( + def apply( scalafixScalaBinaryVersion: String, scalafixDependencies: Seq[ModuleID], - scalafixCustomResolvers: Seq[Repository], + scalafixResolvers: Seq[Repository], logger: Logger, callback: ScalafixMainCallback - ): () => ScalafixInterface = - new LazyValue({ () => - fromToolClasspathMemo.getOrElseUpdate( - ( - scalafixScalaBinaryVersion, - scalafixDependencies, - scalafixCustomResolvers - ), { - if (scalafixScalaBinaryVersion.startsWith("3")) - logger.error( - "To use Scalafix on Scala 3 projects, you must unset `scalafixScalaBinaryVersion`. " + - "Rules such as ExplicitResultTypes requiring the project version to match the Scalafix " + - "version are unsupported for the moment." - ) - else if (scalafixScalaBinaryVersion == "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 scalafixArguments = ScalafixAPI - .fetchAndClassloadInstance( - scalafixScalaBinaryVersion, - scalafixCustomResolvers.asJava + ): ScalafixInterface = + providerMemoization.getOrElseUpdate( + ( + scalafixScalaBinaryVersion, + scalafixDependencies, + scalafixResolvers + ), { + if (scalafixScalaBinaryVersion.startsWith("3")) + logger.error( + "To use Scalafix on Scala 3 projects, you must unset `scalafixScalaBinaryVersion`. " + + "Rules such as ExplicitResultTypes requiring the project version to match the Scalafix " + + "version are unsupported for the moment." + ) + else if (scalafixScalaBinaryVersion == "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 scalafixArguments = ScalafixAPI + .fetchAndClassloadInstance( + scalafixScalaBinaryVersion, + scalafixResolvers.asJava + ) + .newArguments() + .withMainCallback(callback) + val printStream = + new PrintStream( + LoggingOutputStream( + logger, + Level.Info ) - .newArguments() - .withMainCallback(callback) - val printStream = - new PrintStream( - LoggingOutputStream( - logger, - Level.Info - ) + ) + new ScalafixInterface(scalafixArguments, Nil) + .withArgs( + Arg.PrintStream(printStream), + Arg.ToolClasspath( + Nil, + scalafixDependencies, + scalafixResolvers ) - 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 6fd38862..ac21258f 100644 --- a/src/main/scala/scalafix/sbt/ScalafixPlugin.scala +++ b/src/main/scala/scalafix/sbt/ScalafixPlugin.scala @@ -134,14 +134,6 @@ object ScalafixPlugin extends AutoPlugin { Invisible ) - private val scalafixInterfaceProvider - : SettingKey[Seq[Repository] => ScalafixInterface] = - SettingKey( - "scalafixInterfaceProvider", - "Implementation detail - do not use", - Invisible - ) - private def scalafixParser: Def.Initialize[Parser[ShellArgs]] = Def.setting { val allowedTargetFilesPrefixes = @@ -150,17 +142,22 @@ object ScalafixPlugin extends AutoPlugin { .map(_.toPath) new ScalafixCompletions( workingDirectory = (ThisBuild / baseDirectory).value.toPath, - loadedRules = () => + loadedRules = { () => + val scalafixInterface = ScalafixInterface( + scalafixScalaBinaryVersion.value, + scalafixDependencies = scalafixDependencies.value, + // scalafixSbtResolversAsCoursierRepositories can't be looked up here as it's a task + scalafixResolvers = (ThisBuild / scalafixResolvers).value, + logger = ScalafixInterface.defaultLogger, + callback = (ThisBuild / scalafixCallback).value + ) // `scalafixDependencies` might be resolvable only from one of the // `scalafixSbtResolversAsCoursierRepositories` that we can't look up // here, as it's a task and we are in a settings context. Therefore // we fallback to an empty list of rules in case of resolution error // to keep providing completions for the rest. - Try { - scalafixInterfaceProvider - .value((ThisBuild / scalafixResolvers).value) - .availableRules() - }.getOrElse(Seq.empty), + Try(scalafixInterface.availableRules()).getOrElse(Seq.empty) + }, terminalWidth = Some(JLineAccess.terminalWidth), allowedTargetFilesPrefixes = allowedTargetFilesPrefixes, jgitCompletion = scalafixJGitCompletion.value @@ -218,17 +215,6 @@ object ScalafixPlugin extends AutoPlugin { SettingKey[Boolean]("bspEnabled") := false ) ), - scalafixInterfaceProvider := { (customResolvers: Seq[Repository]) => - ScalafixInterface - .fromToolClasspath( - scalafixScalaBinaryVersion.value, - scalafixDependencies = scalafixDependencies.value, - scalafixCustomResolvers = customResolvers, - logger = ScalafixInterface.defaultLogger, - callback = (ThisBuild / scalafixCallback).value - ) - .apply() - }, update := { object SemanticdbScalac { def unapply(id: ModuleID): Option[String] = @@ -313,8 +299,8 @@ object ScalafixPlugin extends AutoPlugin { scalafixInterface: () => ScalafixInterface, scalafixInterfaceCache: BlockingCache[ToolClasspath, ScalafixInterface], projectDepsExternal: Seq[ModuleID], - baseDepsExternal: Seq[ModuleID], - baseResolvers: Seq[Repository], + projectScalafixDependencies: Seq[ModuleID], + buildAllResolvers: Seq[Repository], projectDepsInternal: Seq[File] ): (ShellArgs, ScalafixInterface) = { val (dependencyRules, rules) = @@ -345,8 +331,8 @@ object ScalafixPlugin extends AutoPlugin { if (customToolClasspath) { val toolClasspath = ToolClasspath( projectDepsInternal0.map(_.toURI), - baseDepsExternal ++ projectDepsExternal ++ rulesDepsExternal, - baseResolvers + projectScalafixDependencies ++ projectDepsExternal ++ rulesDepsExternal, + buildAllResolvers ) scalafixInterfaceCache.getOrElseUpdate( toolClasspath, @@ -436,15 +422,23 @@ object ScalafixPlugin extends AutoPlugin { scalafixHelp } else { val scalafixConf = (config / scalafixConfig).value.map(_.toPath) - val resolvers = + val allResolvers = ((ThisBuild / scalafixResolvers).value ++ (ThisBuild / scalafixSbtResolversAsCoursierRepositories).value).distinct + val scalafixInterfaceProvider = () => + ScalafixInterface( + scalafixScalaBinaryVersion.value, + scalafixDependencies = scalafixDependencies.value, + scalafixResolvers = allResolvers, + logger = ScalafixInterface.defaultLogger, + callback = (ThisBuild / scalafixCallback).value + ) val (shell, mainInterface0) = scalafixArgsFromShell( shellArgs, - () => scalafixInterfaceProvider.value(resolvers), + scalafixInterfaceProvider, scalafixInterfaceCache.value, projectDepsExternal, - (ThisBuild / scalafixDependencies).value, - resolvers, + scalafixDependencies.value, + allResolvers, projectDepsInternal ) val maybeNoCache = @@ -474,10 +468,15 @@ object ScalafixPlugin extends AutoPlugin { private def scalafixHelp: Def.Initialize[Task[Unit]] = Def.task { - val resolvers = + val allResolvers = ((ThisBuild / scalafixResolvers).value ++ (ThisBuild / scalafixSbtResolversAsCoursierRepositories).value).distinct - scalafixInterfaceProvider - .value(resolvers) + ScalafixInterface( + scalafixScalaBinaryVersion.value, + scalafixDependencies = scalafixDependencies.value, + scalafixResolvers = allResolvers, + logger = ScalafixInterface.defaultLogger, + callback = (ThisBuild / scalafixCallback).value + ) .withArgs(Arg.ParsedArgs(List("--help"))) .run() () diff --git a/src/test/scala/scalafix/internal/sbt/SbtCompletionsSuite.scala b/src/test/scala/scalafix/internal/sbt/SbtCompletionsSuite.scala index 5fa9eec6..676ae179 100644 --- a/src/test/scala/scalafix/internal/sbt/SbtCompletionsSuite.scala +++ b/src/test/scala/scalafix/internal/sbt/SbtCompletionsSuite.scala @@ -28,19 +28,18 @@ class SbtCompletionsSuite extends AnyFunSuite { "ch.epfl.scala" %% "example-scalafix-rule" % "2.0.0-RC1" } val mainArgs = - ScalafixInterface - .fromToolClasspath( - "2.12", - Seq(exampleDependency), - Seq( - Repository.central, - MavenRepository.of( - "https://oss.sonatype.org/content/repositories/snapshots" - ) - ), - ScalafixInterface.defaultLogger, - new ScalafixLogger(ScalafixInterface.defaultLogger) - )() + ScalafixInterface( + "2.12", + Seq(exampleDependency), + Seq( + Repository.central, + MavenRepository.of( + "https://oss.sonatype.org/content/repositories/snapshots" + ) + ), + ScalafixInterface.defaultLogger, + new ScalafixLogger(ScalafixInterface.defaultLogger) + ) val loadedRules = mainArgs.availableRules.toList val defaultParser = new ScalafixCompletions( diff --git a/src/test/scala/scalafix/internal/sbt/ScalafixAPISuite.scala b/src/test/scala/scalafix/internal/sbt/ScalafixAPISuite.scala index 313b5985..3b00b980 100644 --- a/src/test/scala/scalafix/internal/sbt/ScalafixAPISuite.scala +++ b/src/test/scala/scalafix/internal/sbt/ScalafixAPISuite.scala @@ -31,19 +31,18 @@ class ScalafixAPISuite extends AnyFunSuite { assume(!Properties.isWin) val baos = new ByteArrayOutputStream() val logger = ConsoleLogger(new PrintStream(baos)) - val interface = ScalafixInterface - .fromToolClasspath( - "2.12", - List("ch.epfl.scala" %% "example-scalafix-rule" % "4.0.0"), - Seq( - Repository.central, - MavenRepository.of( - "https://oss.sonatype.org/content/repositories/snapshots" - ) - ), - logger, - new ScalafixLogger(logger) - )() + val interface = ScalafixInterface( + "2.12", + List("ch.epfl.scala" %% "example-scalafix-rule" % "4.0.0"), + Seq( + Repository.central, + MavenRepository.of( + "https://oss.sonatype.org/content/repositories/snapshots" + ) + ), + logger, + new ScalafixLogger(logger) + ) .withArgs(Arg.PrintStream(new PrintStream(baos))) val tmp = Files.createTempFile("scalafix", "Tmp.scala") tmp.toFile.deleteOnExit() From 5bb91676b4ac9832eb55f73ca88e36ef09b1af76 Mon Sep 17 00:00:00 2001 From: Brice Jaglin Date: Thu, 18 Apr 2024 00:21:49 +0200 Subject: [PATCH 046/129] rely on persistent cache and stamping for custom toolclasspath amortization The persistent cache is now bound to a setting key so that its lifecycle is aligned with an sbt session (allowing flushing via a `reload`) The per-invocation cache is merged into the persistent one, which means that the local rules classloader will now remain warm/JITed across invocations. The cache key and the stamping strategy prevents instances from leaking when local rules are being iterated on and recompiled between invocations. --- .../scalafix/internal/sbt/BlockingCache.scala | 32 +++-- .../internal/sbt/ScalafixInterface.scala | 136 ++++++++++++------ .../scala/scalafix/sbt/ScalafixPlugin.scala | 104 ++++++-------- .../internal/sbt/SbtCompletionsSuite.scala | 14 +- .../internal/sbt/ScalafixAPISuite.scala | 14 +- 5 files changed, 180 insertions(+), 120 deletions(-) diff --git a/src/main/scala/scalafix/internal/sbt/BlockingCache.scala b/src/main/scala/scalafix/internal/sbt/BlockingCache.scala index 1ea744db..8a2acd54 100644 --- a/src/main/scala/scalafix/internal/sbt/BlockingCache.scala +++ b/src/main/scala/scalafix/internal/sbt/BlockingCache.scala @@ -2,21 +2,33 @@ package scalafix.internal.sbt import java.{util => ju} +import scala.util.Try + /** A basic thread-safe cache without any eviction. */ class BlockingCache[K, V] { // Number of keys is expected to be very small so the global lock should not be a bottleneck private val underlying = ju.Collections.synchronizedMap(new ju.HashMap[K, V]) - /** @param value - * By-name parameter evaluated when the key if missing. Value computation - * is guaranteed to be called only once per key across all invocations. - */ - def getOrElseUpdate(key: K, value: => V): V = - underlying.computeIfAbsent( - key, - new ju.function.Function[K, V] { - override def apply(k: K): V = value - } + private case class SkipUpdate(prev: V) extends Exception + + // Evaluations of `transform` are guaranteed to be sequential for the same key + def compute(key: K, transform: Option[V] => Option[V]): V = { + Try( + underlying.compute( + key, + new ju.function.BiFunction[K, V, V] { + override def apply(key: K, prev: V): V = { + transform(Option(prev)).getOrElse(throw SkipUpdate(prev)) + } + } + ) + ).fold( + { + case SkipUpdate(prev) => prev + case ex => throw ex + }, + identity ) + } } diff --git a/src/main/scala/scalafix/internal/sbt/ScalafixInterface.scala b/src/main/scala/scalafix/internal/sbt/ScalafixInterface.scala index 516fe3a0..f52843e1 100644 --- a/src/main/scala/scalafix/internal/sbt/ScalafixInterface.scala +++ b/src/main/scala/scalafix/internal/sbt/ScalafixInterface.scala @@ -4,6 +4,7 @@ import java.nio.file.Path import java.{util => jutil} import coursierapi.Repository import sbt._ +import sbt.io.RegularFileFilter import scalafix.interfaces.{Scalafix => ScalafixAPI, _} import scalafix.sbt.InvalidArgument @@ -31,6 +32,16 @@ object Arg { customDependencies.map(_.asCoursierCoordinates).asJava, repositories.asJava ) + + def mutableFiles: Seq[File] = + customURIs + .map(uri => java.nio.file.Paths.get(uri).toFile) + .flatMap { + case classDirectory if classDirectory.isDirectory => + classDirectory.**(RegularFileFilter).get + case jar => + Seq(jar) + } } case class Rules(rules: Seq[String]) extends Arg with CacheKey { @@ -81,7 +92,7 @@ object Arg { class ScalafixInterface private ( scalafixArguments: ScalafixArguments, // hide it to force usage of withArgs so we can intercept arguments - val args: Seq[Arg] + val args: Seq[Arg] = Nil ) { def withArgs(args: Arg*): ScalafixInterface = { @@ -113,60 +124,103 @@ class ScalafixInterface private ( object ScalafixInterface { - private val providerMemoization: BlockingCache[ - (String, Seq[ModuleID], Seq[Repository]), - ScalafixInterface - ] = new BlockingCache + type Cache = BlockingCache[ + ( + String, // scalafixScalaBinaryVersion + Option[Arg.ToolClasspath] + ), + ( + ScalafixInterface, + Seq[Long] // mutable files stamping + ) + ] private[scalafix] val defaultLogger: Logger = ConsoleLogger(System.out) def apply( + cache: Cache, scalafixScalaBinaryVersion: String, - scalafixDependencies: Seq[ModuleID], - scalafixResolvers: Seq[Repository], + toolClasspath: Arg.ToolClasspath, logger: Logger, callback: ScalafixMainCallback - ): ScalafixInterface = - providerMemoization.getOrElseUpdate( + ): ScalafixInterface = { + + // Build or retrieve from the cache the scalafix interface that can run + // built-in rules. This is the most costly instantiation, which should be + // shared as much as possible. + val (buildinRulesInterface, _) = cache.compute( ( scalafixScalaBinaryVersion, - scalafixDependencies, - scalafixResolvers - ), { - if (scalafixScalaBinaryVersion.startsWith("3")) - logger.error( - "To use Scalafix on Scala 3 projects, you must unset `scalafixScalaBinaryVersion`. " + - "Rules such as ExplicitResultTypes requiring the project version to match the Scalafix " + - "version are unsupported for the moment." - ) - else if (scalafixScalaBinaryVersion == "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 scalafixArguments = ScalafixAPI - .fetchAndClassloadInstance( - scalafixScalaBinaryVersion, - scalafixResolvers.asJava + None + ), + { + case Some(_) => + // cache hit, don't update + None + case None => + // cache miss, resolve scalafix artifacts and classload them + if (scalafixScalaBinaryVersion.startsWith("3")) + logger.error( + "To use Scalafix on Scala 3 projects, you must unset `scalafixScalaBinaryVersion`. " + + "Rules such as ExplicitResultTypes requiring the project version to match the Scalafix " + + "version are unsupported for the moment." + ) + else if (scalafixScalaBinaryVersion == "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 scalafixArguments = ScalafixAPI + .fetchAndClassloadInstance( + scalafixScalaBinaryVersion, + toolClasspath.repositories.asJava + ) + .newArguments() + .withMainCallback(callback) + + val printStream = Arg.PrintStream( + new PrintStream( + LoggingOutputStream( + logger, + Level.Info + ) + ) ) - .newArguments() - .withMainCallback(callback) - val printStream = - new PrintStream( - LoggingOutputStream( - logger, - Level.Info + + Some( + ( + new ScalafixInterface(scalafixArguments).withArgs(printStream), + Nil ) ) - new ScalafixInterface(scalafixArguments, Nil) - .withArgs( - Arg.PrintStream(printStream), - Arg.ToolClasspath( - Nil, - scalafixDependencies, - scalafixResolvers + } + ) + + // stamp the files that might change, to potentialy force invalidation + // of the corresponding cache entry + val currentStamps = + toolClasspath.mutableFiles.map(IO.getModifiedTimeOrZero) + + val (toolClasspathInterface, _) = cache.compute( + ( + scalafixScalaBinaryVersion, + Some(toolClasspath) + ), + { + case Some((_, oldStamps)) if (currentStamps == oldStamps) => + // cache hit, don't update + None + case _ => + // cache miss or stale stamps, resolve custom rules artifacts and classload them + Some( + ( + buildinRulesInterface.withArgs(toolClasspath), + currentStamps ) ) } ) + + toolClasspathInterface + } } diff --git a/src/main/scala/scalafix/sbt/ScalafixPlugin.scala b/src/main/scala/scalafix/sbt/ScalafixPlugin.scala index ac21258f..652ff8a4 100644 --- a/src/main/scala/scalafix/sbt/ScalafixPlugin.scala +++ b/src/main/scala/scalafix/sbt/ScalafixPlugin.scala @@ -1,7 +1,7 @@ package scalafix.sbt import java.io.PrintStream -import java.nio.file.{Path, Paths} +import java.nio.file.Path import coursierapi.Repository import sbt.KeyRanks.Invisible import sbt.Keys.* @@ -10,7 +10,6 @@ import sbt.internal.sbtscalafix.JLineAccess import sbt.internal.util.complete.Parser import sbt.plugins.JvmPlugin import scalafix.interfaces.{ScalafixError, ScalafixMainCallback} -import scalafix.internal.sbt.Arg.ToolClasspath import scalafix.internal.sbt.* import scala.collection.JavaConverters.collectionAsScalaIterableConverter @@ -144,10 +143,15 @@ object ScalafixPlugin extends AutoPlugin { workingDirectory = (ThisBuild / baseDirectory).value.toPath, loadedRules = { () => val scalafixInterface = ScalafixInterface( + scalafixInterfaceCache.value, scalafixScalaBinaryVersion.value, - scalafixDependencies = scalafixDependencies.value, - // scalafixSbtResolversAsCoursierRepositories can't be looked up here as it's a task - scalafixResolvers = (ThisBuild / scalafixResolvers).value, + toolClasspath = Arg.ToolClasspath( + Nil, + scalafixDependencies.value, + // scalafixSbtResolversAsCoursierRepositories can't be + // looked up here as it's a task + (ThisBuild / scalafixResolvers).value + ), logger = ScalafixInterface.defaultLogger, callback = (ThisBuild / scalafixCallback).value ) @@ -164,11 +168,10 @@ object ScalafixPlugin extends AutoPlugin { ) }(_.parser) - // Memoize ScalafixInterface instances initialized with a custom tool classpath across projects & configurations - // during task execution, to amortize the classloading cost when invoking scalafix concurrently on many targets - private val scalafixInterfaceCache - : TaskKey[BlockingCache[ToolClasspath, ScalafixInterface]] = - TaskKey( + // Memoize ScalafixInterface instances across projects, configurations & invocations + // to amortize the costs of artifact resolution & classloading. + private val scalafixInterfaceCache: SettingKey[ScalafixInterface.Cache] = + SettingKey( "scalafixInterfaceCache", "Implementation detail - do not use", Invisible @@ -258,10 +261,7 @@ object ScalafixPlugin extends AutoPlugin { scalafixResolvers := defaultScalafixResolvers, scalafixDependencies := Nil, commands += ScalafixEnable.command, - scalafixInterfaceCache := new BlockingCache[ - ToolClasspath, - ScalafixInterface - ], + scalafixInterfaceCache := new BlockingCache, concurrentRestrictions += Tags.exclusiveGroup(Scalafix) ) @@ -296,12 +296,13 @@ object ScalafixPlugin extends AutoPlugin { private def scalafixArgsFromShell( shell: ShellArgs, - scalafixInterface: () => ScalafixInterface, - scalafixInterfaceCache: BlockingCache[ToolClasspath, ScalafixInterface], projectDepsExternal: Seq[ModuleID], + projectDepsInternal: Seq[File], + projectScalafixScalaBinaryVersion: String, projectScalafixDependencies: Seq[ModuleID], buildAllResolvers: Seq[Repository], - projectDepsInternal: Seq[File] + buildScalafixMainCallback: ScalafixMainCallback, + buildScalafixInterfaceCache: ScalafixInterface.Cache ): (ShellArgs, ScalafixInterface) = { val (dependencyRules, rules) = shell.rules.partition(_.startsWith("dependency:")) @@ -318,31 +319,27 @@ object ScalafixPlugin extends AutoPlugin { ) throw new ScalafixFailed(List(ScalafixError.CommandLineError)) } - val rulesDepsExternal = parsed.map(_.dependency) + val invocationDepsExternal = parsed.map(_.dependency) val projectDepsInternal0 = projectDepsInternal.filter { case directory if directory.isDirectory => directory.**(AllPassFilter).get.exists(_.isFile) case file if file.isFile => true case _ => false } - val customToolClasspath = - (projectDepsInternal0 ++ projectDepsExternal ++ rulesDepsExternal).nonEmpty - val interface = - if (customToolClasspath) { - val toolClasspath = ToolClasspath( - projectDepsInternal0.map(_.toURI), - projectScalafixDependencies ++ projectDepsExternal ++ rulesDepsExternal, - buildAllResolvers - ) - scalafixInterfaceCache.getOrElseUpdate( - toolClasspath, - // costly: triggers artifact resolution & classloader creation - scalafixInterface().withArgs(toolClasspath) - ) - } else - // if there is nothing specific to the project or the invocation, reuse the default - // interface which already has the baseDepsExternal loaded - scalafixInterface() + + val toolClasspath = Arg.ToolClasspath( + projectDepsInternal0.map(_.toURI), + projectScalafixDependencies ++ projectDepsExternal ++ invocationDepsExternal, + buildAllResolvers + ) + + val interface = ScalafixInterface( + cache = buildScalafixInterfaceCache, + scalafixScalaBinaryVersion = projectScalafixScalaBinaryVersion, + toolClasspath = toolClasspath, + logger = ScalafixInterface.defaultLogger, + callback = buildScalafixMainCallback + ) val newShell = shell.copy(rules = rules ++ parsed.map(_.ruleName)) (newShell, interface) @@ -424,22 +421,15 @@ object ScalafixPlugin extends AutoPlugin { val scalafixConf = (config / scalafixConfig).value.map(_.toPath) val allResolvers = ((ThisBuild / scalafixResolvers).value ++ (ThisBuild / scalafixSbtResolversAsCoursierRepositories).value).distinct - val scalafixInterfaceProvider = () => - ScalafixInterface( - scalafixScalaBinaryVersion.value, - scalafixDependencies = scalafixDependencies.value, - scalafixResolvers = allResolvers, - logger = ScalafixInterface.defaultLogger, - callback = (ThisBuild / scalafixCallback).value - ) val (shell, mainInterface0) = scalafixArgsFromShell( shellArgs, - scalafixInterfaceProvider, - scalafixInterfaceCache.value, projectDepsExternal, + projectDepsInternal, + scalafixScalaBinaryVersion.value, scalafixDependencies.value, allResolvers, - projectDepsInternal + (ThisBuild / scalafixCallback).value, + scalafixInterfaceCache.value ) val maybeNoCache = if (shell.noCache || !scalafixCaching.value) Seq(Arg.NoCache) else Nil @@ -471,9 +461,13 @@ object ScalafixPlugin extends AutoPlugin { val allResolvers = ((ThisBuild / scalafixResolvers).value ++ (ThisBuild / scalafixSbtResolversAsCoursierRepositories).value).distinct ScalafixInterface( + scalafixInterfaceCache.value, scalafixScalaBinaryVersion.value, - scalafixDependencies = scalafixDependencies.value, - scalafixResolvers = allResolvers, + toolClasspath = Arg.ToolClasspath( + Nil, + scalafixDependencies.value, + allResolvers + ), logger = ScalafixInterface.defaultLogger, callback = (ThisBuild / scalafixCallback).value ) @@ -567,16 +561,8 @@ object ScalafixPlugin extends AutoPlugin { private def stamp[J]( obj: Arg.CacheKey )(implicit builder: Builder[J]): Unit = obj match { - case Arg.ToolClasspath(customURIs, customDependencies, _) => - val files = customURIs - .map(uri => Paths.get(uri).toFile) - .flatMap { - case classDirectory if classDirectory.isDirectory => - classDirectory.**(AllPassFilter).get - case jar => - Seq(jar) - } - write(files.map(stampFile).sorted) + case toolClasspath @ Arg.ToolClasspath(_, customDependencies, _) => + write(toolClasspath.mutableFiles.map(stampFile).sorted) write(customDependencies.map(_.toString).sorted) case Arg.Rules(rules) => rules.foreach { diff --git a/src/test/scala/scalafix/internal/sbt/SbtCompletionsSuite.scala b/src/test/scala/scalafix/internal/sbt/SbtCompletionsSuite.scala index 676ae179..3f3d70da 100644 --- a/src/test/scala/scalafix/internal/sbt/SbtCompletionsSuite.scala +++ b/src/test/scala/scalafix/internal/sbt/SbtCompletionsSuite.scala @@ -29,12 +29,16 @@ class SbtCompletionsSuite extends AnyFunSuite { } val mainArgs = ScalafixInterface( + new BlockingCache(), "2.12", - Seq(exampleDependency), - Seq( - Repository.central, - MavenRepository.of( - "https://oss.sonatype.org/content/repositories/snapshots" + Arg.ToolClasspath( + Nil, + Seq(exampleDependency), + Seq( + Repository.central, + MavenRepository.of( + "https://oss.sonatype.org/content/repositories/snapshots" + ) ) ), ScalafixInterface.defaultLogger, diff --git a/src/test/scala/scalafix/internal/sbt/ScalafixAPISuite.scala b/src/test/scala/scalafix/internal/sbt/ScalafixAPISuite.scala index 3b00b980..c3a55508 100644 --- a/src/test/scala/scalafix/internal/sbt/ScalafixAPISuite.scala +++ b/src/test/scala/scalafix/internal/sbt/ScalafixAPISuite.scala @@ -32,12 +32,16 @@ class ScalafixAPISuite extends AnyFunSuite { val baos = new ByteArrayOutputStream() val logger = ConsoleLogger(new PrintStream(baos)) val interface = ScalafixInterface( + new BlockingCache(), "2.12", - List("ch.epfl.scala" %% "example-scalafix-rule" % "4.0.0"), - Seq( - Repository.central, - MavenRepository.of( - "https://oss.sonatype.org/content/repositories/snapshots" + Arg.ToolClasspath( + Nil, + List("ch.epfl.scala" %% "example-scalafix-rule" % "4.0.0"), + Seq( + Repository.central, + MavenRepository.of( + "https://oss.sonatype.org/content/repositories/snapshots" + ) ) ), logger, From 52d677b3e95f523643ebc78f8800a9da505b13ee Mon Sep 17 00:00:00 2001 From: Brice Jaglin Date: Wed, 17 Apr 2024 15:17:25 +0200 Subject: [PATCH 047/129] use same interface for normal and compilation-less, informational ones --- .../scala/scalafix/sbt/ScalafixPlugin.scala | 57 +++++++------------ 1 file changed, 22 insertions(+), 35 deletions(-) diff --git a/src/main/scala/scalafix/sbt/ScalafixPlugin.scala b/src/main/scala/scalafix/sbt/ScalafixPlugin.scala index 652ff8a4..b224bf2b 100644 --- a/src/main/scala/scalafix/sbt/ScalafixPlugin.scala +++ b/src/main/scala/scalafix/sbt/ScalafixPlugin.scala @@ -415,25 +415,32 @@ object ScalafixPlugin extends AutoPlugin { (ScalafixConfig / externalDependencyClasspath).value .flatMap(_.get(moduleID.key)) - if (shellArgs.rules.isEmpty && shellArgs.extra == List("--help")) { - scalafixHelp + val allResolvers = + ((ThisBuild / scalafixResolvers).value ++ (ThisBuild / scalafixSbtResolversAsCoursierRepositories).value).distinct + val (shell, baseInterface) = scalafixArgsFromShell( + shellArgs, + projectDepsExternal, + projectDepsInternal, + scalafixScalaBinaryVersion.value, + scalafixDependencies.value, + allResolvers, + (ThisBuild / scalafixCallback).value, + scalafixInterfaceCache.value + ) + + val informationalInvocation = shellArgs.extra + .intersect(List("--help", "-h", "--version", "-v")) + .nonEmpty + + if (informationalInvocation) { + Def.task[Unit]( + baseInterface.withArgs(Arg.ParsedArgs(shell.extra)).run() + ) } else { val scalafixConf = (config / scalafixConfig).value.map(_.toPath) - val allResolvers = - ((ThisBuild / scalafixResolvers).value ++ (ThisBuild / scalafixSbtResolversAsCoursierRepositories).value).distinct - val (shell, mainInterface0) = scalafixArgsFromShell( - shellArgs, - projectDepsExternal, - projectDepsInternal, - scalafixScalaBinaryVersion.value, - scalafixDependencies.value, - allResolvers, - (ThisBuild / scalafixCallback).value, - scalafixInterfaceCache.value - ) val maybeNoCache = if (shell.noCache || !scalafixCaching.value) Seq(Arg.NoCache) else Nil - val mainInterface = mainInterface0 + val mainInterface = baseInterface .withArgs(maybeNoCache: _*) .withArgs( Arg.PrintStream(errorLogger), @@ -456,26 +463,6 @@ object ScalafixPlugin extends AutoPlugin { task.tag(Scalafix) } - private def scalafixHelp: Def.Initialize[Task[Unit]] = - Def.task { - val allResolvers = - ((ThisBuild / scalafixResolvers).value ++ (ThisBuild / scalafixSbtResolversAsCoursierRepositories).value).distinct - ScalafixInterface( - scalafixInterfaceCache.value, - scalafixScalaBinaryVersion.value, - toolClasspath = Arg.ToolClasspath( - Nil, - scalafixDependencies.value, - allResolvers - ), - logger = ScalafixInterface.defaultLogger, - callback = (ThisBuild / scalafixCallback).value - ) - .withArgs(Arg.ParsedArgs(List("--help"))) - .run() - () - } - private def scalafixSyntactic( mainInterface: ScalafixInterface, shellArgs: ShellArgs, From ff8e68247a38fdbc34f761b0a9aacb79fe485562 Mon Sep 17 00:00:00 2001 From: Brice Jaglin Date: Wed, 17 Apr 2024 15:59:01 +0200 Subject: [PATCH 048/129] move existing comment closer to where it actually applies --- src/main/scala/scalafix/internal/sbt/ScalafixCompletions.scala | 2 -- src/main/scala/scalafix/sbt/ScalafixPlugin.scala | 1 + 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main/scala/scalafix/internal/sbt/ScalafixCompletions.scala b/src/main/scala/scalafix/internal/sbt/ScalafixCompletions.scala index b6b9c5c3..f2dcf391 100644 --- a/src/main/scala/scalafix/internal/sbt/ScalafixCompletions.scala +++ b/src/main/scala/scalafix/internal/sbt/ScalafixCompletions.scala @@ -10,8 +10,6 @@ import sbt.complete.DefaultParsers._ class ScalafixCompletions( workingDirectory: Path, - // Unfortunately, local rules will not show up as completions in the parser, as that parser can only - // depend on settings, while local rules classpath must be looked up via tasks loadedRules: () => Seq[ScalafixRule], terminalWidth: Option[Int], allowedTargetFilesPrefixes: Seq[Path], // Nil means all values are valid diff --git a/src/main/scala/scalafix/sbt/ScalafixPlugin.scala b/src/main/scala/scalafix/sbt/ScalafixPlugin.scala index b224bf2b..a399065e 100644 --- a/src/main/scala/scalafix/sbt/ScalafixPlugin.scala +++ b/src/main/scala/scalafix/sbt/ScalafixPlugin.scala @@ -146,6 +146,7 @@ object ScalafixPlugin extends AutoPlugin { scalafixInterfaceCache.value, scalafixScalaBinaryVersion.value, toolClasspath = Arg.ToolClasspath( + // Local rules classpath must be looked up via tasks so they can't appear in completions Nil, scalafixDependencies.value, // scalafixSbtResolversAsCoursierRepositories can't be From d834da8fbac6727fd481be2792e441a57b70e379 Mon Sep 17 00:00:00 2001 From: Brice Jaglin Date: Thu, 18 Apr 2024 00:43:35 +0200 Subject: [PATCH 049/129] use ConcurrentHashMap to parallelize invocations with different tool classpaths --- src/main/scala/scalafix/internal/sbt/BlockingCache.scala | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main/scala/scalafix/internal/sbt/BlockingCache.scala b/src/main/scala/scalafix/internal/sbt/BlockingCache.scala index 8a2acd54..d1d4546e 100644 --- a/src/main/scala/scalafix/internal/sbt/BlockingCache.scala +++ b/src/main/scala/scalafix/internal/sbt/BlockingCache.scala @@ -7,8 +7,7 @@ import scala.util.Try /** A basic thread-safe cache without any eviction. */ class BlockingCache[K, V] { - // Number of keys is expected to be very small so the global lock should not be a bottleneck - private val underlying = ju.Collections.synchronizedMap(new ju.HashMap[K, V]) + private val underlying = new ju.concurrent.ConcurrentHashMap[K, V] private case class SkipUpdate(prev: V) extends Exception From d12e4d4768ea763885245a0d44294cb7512399fa Mon Sep 17 00:00:00 2001 From: Brice Jaglin Date: Tue, 23 Apr 2024 08:05:12 +0200 Subject: [PATCH 050/129] avoid full (re)compilation after cold scalafix invocations The Zinc analysis is now saved on compilations triggered by scalafix invocations. This allows subsequent scalafix invocations not to re-trigger compilations, and subsequent regular compilations to be either incremental (in case the build contains `-Xfatal-warnings` or alike) or a full cache hit otherwise. --- .../scala/scalafix/sbt/ScalafixPlugin.scala | 38 +++++++++------- .../relax-scalacOptions/build.sbt | 13 +----- .../sbt-scalafix/relax-scalacOptions/test | 43 ++++++++++++++----- 3 files changed, 56 insertions(+), 38 deletions(-) diff --git a/src/main/scala/scalafix/sbt/ScalafixPlugin.scala b/src/main/scala/scalafix/sbt/ScalafixPlugin.scala index 720a2d4d..1f4cb6d0 100644 --- a/src/main/scala/scalafix/sbt/ScalafixPlugin.scala +++ b/src/main/scala/scalafix/sbt/ScalafixPlugin.scala @@ -102,9 +102,20 @@ object ScalafixPlugin extends AutoPlugin { val oldCompile = compile.value // evaluated first, before the potential scalafix evaluation if (scalafixOnCompile.value) - scalafix - .toTask(" --triggered") - .map(_ => oldCompile) + Def.taskDyn { + // evaluate scalafixInvoked only when scalafixOnCompile is set + // to reduce risk of side effects on the build + if (scalafixInvoked.value) + // don't trigger scalafix if it was explicitly invoked, + // as it would be not only inefficient, but incorrect since + // scalafix might run with different CLI args, potentially + // rewriting files while `--check` was used + Def.task(oldCompile) + else + scalafix + .toTask(" --triggered") + .map(_ => oldCompile) + } else Def.task(oldCompile) }.value, // In some cases (I haven't been able to understand when/why, but this also happens for bgRunMain while @@ -505,8 +516,13 @@ object ScalafixPlugin extends AutoPlugin { (config / scalafix / streams).value ) } - // sub-task of compile after which bytecode should not be modified - task.dependsOn(config / manipulateBytecode) + // we should not and cannot (circular dependency) trigger compilation + // if this is an non-explicit invocation - we use the presence of a + // flag rather than checking !scalafixInvoked, in order to trigger + // compile in case scalafix is wrapped in another task that + // scalafixInvoked does not know about + if (shellArgs.extra.contains("--triggered")) task + else task.dependsOn(config / compile) } else { Def.task { if (errors.length == 1) { @@ -583,7 +599,7 @@ object ScalafixPlugin extends AutoPlugin { case "--stdout" => // --stdout cannot be cached as we don't capture the output to replay it throw StampingImpossible - case "--tool-classpath" => + case tcp if tcp.startsWith("--tool-classpath") => // custom tool classpaths might contain directories for which we would need to stamp all files, so // just disable caching for now to keep it simple and to be safe throw StampingImpossible @@ -743,16 +759,6 @@ object ScalafixPlugin extends AutoPlugin { options.ignoredScalacOptions() ++ scalacOptionsToRelax.map(_.pattern()) ) - }, - manipulateBytecode := { - val analysis = manipulateBytecode.value - if (!scalafixInvoked.value) analysis - else { - // prevent storage of the analysis with relaxed scalacOptions - despite not depending explicitly on compile, - // it is being triggered for parent configs/projects through evaluation of dependencyClasspath (TrackAlways) - // in the scope where scalafix is invoked - analysis.withHasModified(false) - } } ) diff --git a/src/sbt-test/sbt-scalafix/relax-scalacOptions/build.sbt b/src/sbt-test/sbt-scalafix/relax-scalacOptions/build.sbt index cc0547a4..1bfde9f8 100644 --- a/src/sbt-test/sbt-scalafix/relax-scalacOptions/build.sbt +++ b/src/sbt-test/sbt-scalafix/relax-scalacOptions/build.sbt @@ -1,14 +1,8 @@ val V = _root_.scalafix.sbt.BuildInfo addCompilerPlugin(scalafixSemanticdb) -scalacOptions ++= Seq("-Yrangepos") - +scalacOptions ++= Seq("-Yrangepos", "-Ywarn-unused") scalaVersion := V.scala212 -scalacOptions ++= Seq( - // generate errors on unused imports - "-Xfatal-warnings", - "-Ywarn-unused" -) Compile / compile / scalacOptions ++= Seq( // generate errors on procedure syntax "-Wconf:cat=deprecation:e", @@ -38,11 +32,6 @@ TaskKey[Unit]("checkLastCompilationCached") := { } } -TaskKey[Unit]("checkZincAnalysisPresent") := { - val isPresent = (Compile / previousCompile).value.analysis.isPresent() - assert(isPresent, "zinc analysis not found") -} - // https://github.com/sbt/sbt/commit/dbb47b3ce822ff7ec25881dadd71a3b29e202273 // must be outside a macro to workaround "Illegal dynamic reference: Def" def streamScopedKey(scope: Scope) = Def.ScopedKey(scope, Keys.streams.key) diff --git a/src/sbt-test/sbt-scalafix/relax-scalacOptions/test b/src/sbt-test/sbt-scalafix/relax-scalacOptions/test index 0b61661c..678f60ff 100644 --- a/src/sbt-test/sbt-scalafix/relax-scalacOptions/test +++ b/src/sbt-test/sbt-scalafix/relax-scalacOptions/test @@ -1,22 +1,45 @@ -# we have 2 fatal warnings preventing compilation +# when the build does not contain any flag relaxed on scalafix invocation +# check that regular compilation benefits froma prior direct scalafix invocation ... +-> scalafix --check RemoveUnused +-> checkLastCompilationCached +> compile +> checkLastCompilationCached + +# ... and indirect scalafix invocation +> clean +> test:scalafix --check RemoveUnused +-> checkLastCompilationCached +> compile +> checkLastCompilationCached + +# we now have 2 fatal warnings preventing compilation +> set scalacOptions ++= Seq("-Xfatal-warnings") -> compile # ensure that a semantic rule can be ran despite warnings, to fix one of the warning -> scalafixAll RemoveUnused +> scalafix RemoveUnused -# but that the zinc analysis file has not been persisted, otherwise the run with relax scalacOptions would -# cause the next compile to be full (non-incremental) no matter if there was a previous successful compilation --> checkZincAnalysisPresent +# confirm that the rule was applied and that triggered compilation is cached once the updated file recompiled +> scalafix --check RemoveUnused +-> checkLastCompilationCached +> scalafix --check RemoveUnused +> checkLastCompilationCached # and that -Xfatal-warnings remains honored for regular compilation -> compile -# confirm that compilation succeeds after fixing the last warning +# confirm that regular compilation succeeds after fixing the last warning > scalafix ProcedureSyntax > compile -> checkZincAnalysisPresent -# check that there is no recompilation when running a semantic rule after a successful compilation --> checkLastCompilationCached -> scalafixAll RemoveUnused +# check that regular compilation is cached as usual +> compile > checkLastCompilationCached + +# check that there is no recompilation when running a semantic rule after a regular compilation ... +> scalafix RemoveUnused +> checkLastCompilationCached + +# nor when compiling after running a semantic rule +> compile +> checkLastCompilationCached \ No newline at end of file From 41e755397c74e22d820eb95a74a87d68845c61d5 Mon Sep 17 00:00:00 2001 From: Brice Jaglin Date: Mon, 22 Apr 2024 23:26:48 +0200 Subject: [PATCH 051/129] bump minimum sbt version at runtime to prevent race conditions on classes.bak --- build.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.sbt b/build.sbt index fbe3b8a3..23ce6dc3 100644 --- a/build.sbt +++ b/build.sbt @@ -56,7 +56,7 @@ scriptedSbt := { if (jdk >= 21) "1.9.0" // first release that supports JDK21 else - (pluginCrossBuild / sbtVersion).value + "1.3.3" // get https://github.com/sbt/sbt/issues/1673 to avoid race conditions } libraryDependencies += compilerPlugin(scalafixSemanticdb) From 5e606c2b85720d9ce1459de5516a9adfd2bec4c2 Mon Sep 17 00:00:00 2001 From: Brice Jaglin Date: Wed, 24 Apr 2024 19:12:54 +0200 Subject: [PATCH 052/129] move away from deprecated olafurpg/setup-scala --- .github/workflows/ci.yml | 2 +- .github/workflows/release.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 66e458ff..5f4218b9 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -54,5 +54,5 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - - uses: olafurpg/setup-scala@v14 + - uses: coursier/setup-action@v1 - run: ./bin/scalafmt --test diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 97d1304f..bddb3aef 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -8,7 +8,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - - uses: olafurpg/setup-scala@v14 + - uses: coursier/setup-action@v1 - uses: olafurpg/setup-gpg@v3 - run: git fetch --unshallow - name: Publish ${{ github.ref }} From 33911c01f4ba1f933026501c2be35dc3c1a3419b Mon Sep 17 00:00:00 2001 From: Brice Jaglin Date: Wed, 24 Apr 2024 22:26:07 +0200 Subject: [PATCH 053/129] remove unused file --- .../skip-windows/caching/files/RemoveUnused.scalafix.conf | 1 - 1 file changed, 1 deletion(-) delete mode 100644 src/sbt-test/skip-windows/caching/files/RemoveUnused.scalafix.conf diff --git a/src/sbt-test/skip-windows/caching/files/RemoveUnused.scalafix.conf b/src/sbt-test/skip-windows/caching/files/RemoveUnused.scalafix.conf deleted file mode 100644 index 286cbbb4..00000000 --- a/src/sbt-test/skip-windows/caching/files/RemoveUnused.scalafix.conf +++ /dev/null @@ -1 +0,0 @@ -rules = [RemoveUnused] \ No newline at end of file From 0572c3f97fd146071881da74f815df50f7861ebe Mon Sep 17 00:00:00 2001 From: Brice Jaglin Date: Wed, 24 Apr 2024 23:07:48 +0200 Subject: [PATCH 054/129] guard current cache invalidation behavior with --settings --- src/sbt-test/skip-windows/caching/test | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/sbt-test/skip-windows/caching/test b/src/sbt-test/skip-windows/caching/test index 69abd4ba..dfe6b223 100644 --- a/src/sbt-test/skip-windows/caching/test +++ b/src/sbt-test/skip-windows/caching/test @@ -162,6 +162,17 @@ $ copy-file files/Null.scala src/main/scala/InitiallyValid.scala -> scalafix --check $ delete src/main/scala +# files should be re-checked if custom rule configuration is added or removed from the CLI (even if the rule is the same) +> set scalafixConfig := Some(file("files/DisableSyntaxVar.scalafix.conf")) +$ mkdir src/main/scala +$ copy-file files/Null.scala src/main/scala/ValidWithoutCustomSettings.scala +-> scalafix --check --settings.DisableSyntax.noNulls=true +> scalafix --check +-> scalafix --check --settings.DisableSyntax.noNulls=true +$ exec chmod 000 src/main/scala/ValidWithoutCustomSettings.scala +-> scalafix --check --settings.DisableSyntax.noNulls=true +$ delete src/main/scala + # files should be re-checked after updating the default configuration (even if the rule is the same) > set scalafixConfig := None $ mkdir src/main/scala From 386a44d9c832060d99f4d97fc1fae8e40d531a9b Mon Sep 17 00:00:00 2001 From: Brice Jaglin Date: Wed, 1 May 2024 00:22:26 +0200 Subject: [PATCH 055/129] test against Scala 2.13.14 --- src/sbt-test/sbt-scalafix/semanticdb-enabled/build.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sbt-test/sbt-scalafix/semanticdb-enabled/build.sbt b/src/sbt-test/sbt-scalafix/semanticdb-enabled/build.sbt index a082fae0..5aa0bf5e 100644 --- a/src/sbt-test/sbt-scalafix/semanticdb-enabled/build.sbt +++ b/src/sbt-test/sbt-scalafix/semanticdb-enabled/build.sbt @@ -10,6 +10,6 @@ lazy val scala212 = project lazy val scala213 = project .settings( - scalaVersion := "2.13.13", + scalaVersion := "2.13.14", scalacOptions += "-Wunused" ) From 19183afb4ccaf2a9ac4bcffcbc8311eb9f659940 Mon Sep 17 00:00:00 2001 From: Brice Jaglin Date: Wed, 1 May 2024 19:59:43 +0200 Subject: [PATCH 056/129] let scalafixScalaBV follow scalaBV to leverage 2.13 & deprecate it --- .../scala/scalafix/sbt/ScalafixPlugin.scala | 26 +++++++++++++------ src/sbt-test/sbt-1.4/build-lint/build.sbt | 1 - .../cross-build-scala3/.scalafix-2.conf | 2 ++ .../cross-build-scala3/.scalafix-3.conf | 1 + .../build.sbt | 13 +++++----- .../project/build.properties | 0 .../project/plugins.sbt | 0 .../src/main/scala-2/Main.scala | 0 .../src/main/scala-2/Main.scala.expected | 0 .../src/main/scala-3/Main.scala | 0 .../src/main/scala-3/Main.scala.expected | 5 ++++ .../test | 0 .../.scalafix-2.conf | 3 --- .../.scalafix-3.conf | 2 -- .../src/main/scala-3/Main.scala.expected | 7 ----- .../sbt-scalafix/local-rules/build.sbt | 5 +--- .../scalafixScalaBinaryVersion/build.sbt | 10 ------- .../project/plugins.sbt | 2 -- .../main/scala/NeedExplicitResultTypes.scala | 6 ----- .../scalafixScalaBinaryVersion/test | 5 ---- 20 files changed, 33 insertions(+), 55 deletions(-) create mode 100644 src/sbt-test/sbt-1.5/cross-build-scala3/.scalafix-2.conf create mode 100644 src/sbt-test/sbt-1.5/cross-build-scala3/.scalafix-3.conf rename src/sbt-test/sbt-1.5/{cross-build-scalafixScalaBinaryVersion => cross-build-scala3}/build.sbt (62%) rename src/sbt-test/sbt-1.5/{cross-build-scalafixScalaBinaryVersion => cross-build-scala3}/project/build.properties (100%) rename src/sbt-test/sbt-1.5/{cross-build-scalafixScalaBinaryVersion => cross-build-scala3}/project/plugins.sbt (100%) rename src/sbt-test/sbt-1.5/{cross-build-scalafixScalaBinaryVersion => cross-build-scala3}/src/main/scala-2/Main.scala (100%) rename src/sbt-test/sbt-1.5/{cross-build-scalafixScalaBinaryVersion => cross-build-scala3}/src/main/scala-2/Main.scala.expected (100%) rename src/sbt-test/sbt-1.5/{cross-build-scalafixScalaBinaryVersion => cross-build-scala3}/src/main/scala-3/Main.scala (100%) create mode 100644 src/sbt-test/sbt-1.5/cross-build-scala3/src/main/scala-3/Main.scala.expected rename src/sbt-test/sbt-1.5/{cross-build-scalafixScalaBinaryVersion => cross-build-scala3}/test (100%) delete mode 100644 src/sbt-test/sbt-1.5/cross-build-scalafixScalaBinaryVersion/.scalafix-2.conf delete mode 100644 src/sbt-test/sbt-1.5/cross-build-scalafixScalaBinaryVersion/.scalafix-3.conf delete mode 100644 src/sbt-test/sbt-1.5/cross-build-scalafixScalaBinaryVersion/src/main/scala-3/Main.scala.expected delete mode 100644 src/sbt-test/sbt-scalafix/scalafixScalaBinaryVersion/build.sbt delete mode 100644 src/sbt-test/sbt-scalafix/scalafixScalaBinaryVersion/project/plugins.sbt delete mode 100644 src/sbt-test/sbt-scalafix/scalafixScalaBinaryVersion/src/main/scala/NeedExplicitResultTypes.scala delete mode 100644 src/sbt-test/sbt-scalafix/scalafixScalaBinaryVersion/test diff --git a/src/main/scala/scalafix/sbt/ScalafixPlugin.scala b/src/main/scala/scalafix/sbt/ScalafixPlugin.scala index 1f4cb6d0..1242584a 100644 --- a/src/main/scala/scalafix/sbt/ScalafixPlugin.scala +++ b/src/main/scala/scalafix/sbt/ScalafixPlugin.scala @@ -9,13 +9,13 @@ import sbt.* import sbt.internal.sbtscalafix.JLineAccess import sbt.internal.util.complete.Parser import sbt.plugins.JvmPlugin +import sbt.librarymanagement.ResolveException import scalafix.interfaces.{ScalafixError, ScalafixMainCallback} import scalafix.internal.sbt.* +import scala.annotation.nowarn import scala.collection.JavaConverters.collectionAsScalaIterableConverter import scala.util.control.NoStackTrace -import sbt.librarymanagement.ResolveException - import scala.util.Try object ScalafixPlugin extends AutoPlugin { @@ -64,10 +64,15 @@ object ScalafixPlugin extends AutoPlugin { "Optional list of artifacts to resolve to run custom rules. " + "Can be set in ThisBuild or at project-level." ) + @deprecated( + "scalafixScalaBinaryVersion now follows scalaBinaryVersion by default", + "0.12.1" + ) val scalafixScalaBinaryVersion: SettingKey[String] = settingKey[String]( - "The Scala binary version used for scalafix execution. Can be set in ThisBuild or at project-level. " + - "Custom rules must be compiled against that binary version. Defaults to 2.12." + "The Scala binary version used for scalafix execution. Must be set at project-level. " + + "Custom rules must be compiled against that binary version. Defaults to 2.12 for 2.12 projects, " + + "2.13 otherwise." ) val scalafixConfig: SettingKey[Option[File]] = settingKey[Option[File]]( @@ -155,7 +160,7 @@ object ScalafixPlugin extends AutoPlugin { loadedRules = { () => val scalafixInterface = ScalafixInterface( scalafixInterfaceCache.value, - scalafixScalaBinaryVersion.value, + scalafixScalaBinaryVersion.value: @nowarn, toolClasspath = Arg.ToolClasspath( // Local rules classpath must be looked up via tasks so they can't appear in completions Nil, @@ -262,7 +267,13 @@ object ScalafixPlugin extends AutoPlugin { } }, ivyConfigurations += ScalafixConfig, - scalafixAll := scalafixAllInputTask.evaluated + scalafixAll := scalafixAllInputTask.evaluated, + (scalafixScalaBinaryVersion: @nowarn) := { + scalaBinaryVersion.value match { + case "2.12" => "2.12" + case _ => "2.13" + } + } ) override lazy val globalSettings: Seq[Def.Setting[_]] = Seq( @@ -300,7 +311,6 @@ object ScalafixPlugin extends AutoPlugin { ) } }, - scalafixScalaBinaryVersion := "2.12", scalafixJGitCompletion := new JGitCompletion(baseDirectory.value.toPath) ) @@ -433,7 +443,7 @@ object ScalafixPlugin extends AutoPlugin { shellArgs, projectDepsExternal, projectDepsInternal, - scalafixScalaBinaryVersion.value, + scalafixScalaBinaryVersion.value: @nowarn, scalafixDependencies.value, allResolvers, (ThisBuild / scalafixCallback).value, diff --git a/src/sbt-test/sbt-1.4/build-lint/build.sbt b/src/sbt-test/sbt-1.4/build-lint/build.sbt index 8639100a..4e7833be 100644 --- a/src/sbt-test/sbt-1.4/build-lint/build.sbt +++ b/src/sbt-test/sbt-1.4/build-lint/build.sbt @@ -1,6 +1,5 @@ ThisBuild / scalafixDependencies := Nil ThisBuild / scalafixResolvers := Nil -ThisBuild / scalafixScalaBinaryVersion := "2.12" scalafixCaching := false scalafixConfig := None scalafixOnCompile := false diff --git a/src/sbt-test/sbt-1.5/cross-build-scala3/.scalafix-2.conf b/src/sbt-test/sbt-1.5/cross-build-scala3/.scalafix-2.conf new file mode 100644 index 00000000..3a228107 --- /dev/null +++ b/src/sbt-test/sbt-1.5/cross-build-scala3/.scalafix-2.conf @@ -0,0 +1,2 @@ +rules = [OrganizeImports, ExplicitResultTypes] +ExplicitResultTypes.skipSimpleDefinitions = false \ No newline at end of file diff --git a/src/sbt-test/sbt-1.5/cross-build-scala3/.scalafix-3.conf b/src/sbt-test/sbt-1.5/cross-build-scala3/.scalafix-3.conf new file mode 100644 index 00000000..21c30ce0 --- /dev/null +++ b/src/sbt-test/sbt-1.5/cross-build-scala3/.scalafix-3.conf @@ -0,0 +1 @@ +rules = [OrganizeImports] diff --git a/src/sbt-test/sbt-1.5/cross-build-scalafixScalaBinaryVersion/build.sbt b/src/sbt-test/sbt-1.5/cross-build-scala3/build.sbt similarity index 62% rename from src/sbt-test/sbt-1.5/cross-build-scalafixScalaBinaryVersion/build.sbt rename to src/sbt-test/sbt-1.5/cross-build-scala3/build.sbt index 29d01e99..eba0e41b 100644 --- a/src/sbt-test/sbt-1.5/cross-build-scalafixScalaBinaryVersion/build.sbt +++ b/src/sbt-test/sbt-1.5/cross-build-scala3/build.sbt @@ -1,6 +1,6 @@ import _root_.scalafix.sbt.{BuildInfo => Versions} -val scala3Version = "3.3.0" +val scala3Version = "3.4.1" ThisBuild / semanticdbEnabled := true ThisBuild / semanticdbVersion := scalafixSemanticdb.revision @@ -13,12 +13,11 @@ lazy val root = project Versions.scala213, scala3Version ), - scalacOptions ++= (if (scalaVersion.value.startsWith("2")) - Seq("-Ywarn-unused") - else Seq()), - scalafixScalaBinaryVersion := { - if (scalaBinaryVersion.value == "3") scalafixScalaBinaryVersion.value - else scalaBinaryVersion.value + scalacOptions += { + if (scalaVersion.value.startsWith("2.12")) + "-Ywarn-unused-import" + else + "-Wunused:imports" }, scalafixConfig := { if (scalaBinaryVersion.value == "3") diff --git a/src/sbt-test/sbt-1.5/cross-build-scalafixScalaBinaryVersion/project/build.properties b/src/sbt-test/sbt-1.5/cross-build-scala3/project/build.properties similarity index 100% rename from src/sbt-test/sbt-1.5/cross-build-scalafixScalaBinaryVersion/project/build.properties rename to src/sbt-test/sbt-1.5/cross-build-scala3/project/build.properties diff --git a/src/sbt-test/sbt-1.5/cross-build-scalafixScalaBinaryVersion/project/plugins.sbt b/src/sbt-test/sbt-1.5/cross-build-scala3/project/plugins.sbt similarity index 100% rename from src/sbt-test/sbt-1.5/cross-build-scalafixScalaBinaryVersion/project/plugins.sbt rename to src/sbt-test/sbt-1.5/cross-build-scala3/project/plugins.sbt 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-scala3/src/main/scala-2/Main.scala similarity index 100% rename from src/sbt-test/sbt-1.5/cross-build-scalafixScalaBinaryVersion/src/main/scala-2/Main.scala rename to src/sbt-test/sbt-1.5/cross-build-scala3/src/main/scala-2/Main.scala 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-scala3/src/main/scala-2/Main.scala.expected similarity index 100% rename from src/sbt-test/sbt-1.5/cross-build-scalafixScalaBinaryVersion/src/main/scala-2/Main.scala.expected rename to src/sbt-test/sbt-1.5/cross-build-scala3/src/main/scala-2/Main.scala.expected 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-scala3/src/main/scala-3/Main.scala similarity index 100% rename from src/sbt-test/sbt-1.5/cross-build-scalafixScalaBinaryVersion/src/main/scala-3/Main.scala rename to src/sbt-test/sbt-1.5/cross-build-scala3/src/main/scala-3/Main.scala diff --git a/src/sbt-test/sbt-1.5/cross-build-scala3/src/main/scala-3/Main.scala.expected b/src/sbt-test/sbt-1.5/cross-build-scala3/src/main/scala-3/Main.scala.expected new file mode 100644 index 00000000..cb096903 --- /dev/null +++ b/src/sbt-test/sbt-1.5/cross-build-scala3/src/main/scala-3/Main.scala.expected @@ -0,0 +1,5 @@ +import scala.Int + +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-scala3/test similarity index 100% rename from src/sbt-test/sbt-1.5/cross-build-scalafixScalaBinaryVersion/test rename to src/sbt-test/sbt-1.5/cross-build-scala3/test 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 deleted file mode 100644 index bbc1675b..00000000 --- a/src/sbt-test/sbt-1.5/cross-build-scalafixScalaBinaryVersion/.scalafix-2.conf +++ /dev/null @@ -1,3 +0,0 @@ -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 deleted file mode 100644 index c2231433..00000000 --- a/src/sbt-test/sbt-1.5/cross-build-scalafixScalaBinaryVersion/.scalafix-3.conf +++ /dev/null @@ -1,2 +0,0 @@ -rules = [DisableSyntax, OrganizeImports] -OrganizeImports.removeUnused = false \ No newline at end of file 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 deleted file mode 100644 index bf8fd25a..00000000 --- a/src/sbt-test/sbt-1.5/cross-build-scalafixScalaBinaryVersion/src/main/scala-3/Main.scala.expected +++ /dev/null @@ -1,7 +0,0 @@ -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-scalafix/local-rules/build.sbt b/src/sbt-test/sbt-scalafix/local-rules/build.sbt index 1fef774b..03b7f94a 100644 --- a/src/sbt-test/sbt-scalafix/local-rules/build.sbt +++ b/src/sbt-test/sbt-scalafix/local-rules/build.sbt @@ -7,10 +7,7 @@ inThisBuild( "ch.epfl.scala" %% "example-scalafix-rule" % "1.4.0" ), resolvers += Resolver.sonatypeRepo("snapshots"), - scalaVersion := "2.13.11", // out of sync with scalafix.sbt.BuildInfo.scala213 on purpose - scalafixScalaBinaryVersion := - // this should be the default in sbt-scalafix 1.0 - CrossVersion.binaryScalaVersion(scalaVersion.value) + scalaVersion := "2.13.11" // out of sync with scalafix.sbt.BuildInfo.scala213 on purpose ) ) diff --git a/src/sbt-test/sbt-scalafix/scalafixScalaBinaryVersion/build.sbt b/src/sbt-test/sbt-scalafix/scalafixScalaBinaryVersion/build.sbt deleted file mode 100644 index 21462e27..00000000 --- a/src/sbt-test/sbt-scalafix/scalafixScalaBinaryVersion/build.sbt +++ /dev/null @@ -1,10 +0,0 @@ -import _root_.scalafix.sbt.{BuildInfo => V} - -inThisBuild( - List( - addCompilerPlugin(scalafixSemanticdb), - scalacOptions += "-Yrangepos", - scalaVersion := V.scala213, - scalafixScalaBinaryVersion := scalaBinaryVersion.value // this should be the default in sbt-scalafix 1.0 - ) -) diff --git a/src/sbt-test/sbt-scalafix/scalafixScalaBinaryVersion/project/plugins.sbt b/src/sbt-test/sbt-scalafix/scalafixScalaBinaryVersion/project/plugins.sbt deleted file mode 100644 index 2d3b4d3b..00000000 --- a/src/sbt-test/sbt-scalafix/scalafixScalaBinaryVersion/project/plugins.sbt +++ /dev/null @@ -1,2 +0,0 @@ -resolvers += Resolver.sonatypeRepo("public") -addSbtPlugin("ch.epfl.scala" % "sbt-scalafix" % sys.props("plugin.version")) diff --git a/src/sbt-test/sbt-scalafix/scalafixScalaBinaryVersion/src/main/scala/NeedExplicitResultTypes.scala b/src/sbt-test/sbt-scalafix/scalafixScalaBinaryVersion/src/main/scala/NeedExplicitResultTypes.scala deleted file mode 100644 index 1da5a2da..00000000 --- a/src/sbt-test/sbt-scalafix/scalafixScalaBinaryVersion/src/main/scala/NeedExplicitResultTypes.scala +++ /dev/null @@ -1,6 +0,0 @@ -object NeedExplicitResultTypes { - def a = { - println("foobar") - 123 - } -} diff --git a/src/sbt-test/sbt-scalafix/scalafixScalaBinaryVersion/test b/src/sbt-test/sbt-scalafix/scalafixScalaBinaryVersion/test deleted file mode 100644 index 06f59062..00000000 --- a/src/sbt-test/sbt-scalafix/scalafixScalaBinaryVersion/test +++ /dev/null @@ -1,5 +0,0 @@ -# ExplicitResultTypes uses the presentation compiler so the rule must run with the same scala binary version as the target --> scalafix --check ExplicitResultTypes -> scalafix ExplicitResultTypes -> scalafix --check ExplicitResultTypes - From 09be992a87baae0fc75d4d215c084ded6bbc1a52 Mon Sep 17 00:00:00 2001 From: Brice Jaglin Date: Wed, 1 May 2024 21:28:55 +0200 Subject: [PATCH 057/129] scalafix 0.12.1 --- project/Dependencies.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project/Dependencies.scala b/project/Dependencies.scala index be605d49..a77117c2 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -2,7 +2,7 @@ import sbt._ object Dependencies { val x = List(1) // scalafix:ok - def scalafixVersion: String = "0.12.0" + def scalafixVersion: String = "0.12.1" val all = List( "org.eclipse.jgit" % "org.eclipse.jgit" % "5.13.3.202401111512-r", From d9b838e03bbfcd58090c040b395c23a247f53592 Mon Sep 17 00:00:00 2001 From: "scala-center-steward[bot]" <111975575+scala-center-steward[bot]@users.noreply.github.com> Date: Wed, 15 May 2024 00:18:18 +0000 Subject: [PATCH 058/129] Update sbt, scripted-plugin to 1.10.0 --- project/build.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project/build.properties b/project/build.properties index 04267b14..081fdbbc 100644 --- a/project/build.properties +++ b/project/build.properties @@ -1 +1 @@ -sbt.version=1.9.9 +sbt.version=1.10.0 From ae181d36aad736d693839ac036faf06d7a833432 Mon Sep 17 00:00:00 2001 From: "scala-center-steward[bot]" <111975575+scala-center-steward[bot]@users.noreply.github.com> Date: Sat, 15 Jun 2024 00:16:44 +0000 Subject: [PATCH 059/129] Update scalafmt-core to 3.8.2 --- .scalafmt.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.scalafmt.conf b/.scalafmt.conf index 51535faf..b6db84f7 100644 --- a/.scalafmt.conf +++ b/.scalafmt.conf @@ -1,4 +1,4 @@ -version = "3.8.1" +version = "3.8.2" project.git=true align.preset=none assumeStandardLibraryStripMargin = true From 133467fc60093d13dd8f41d05f64d5342df0cd43 Mon Sep 17 00:00:00 2001 From: Brice Jaglin Date: Sun, 23 Jun 2024 18:56:40 +0200 Subject: [PATCH 060/129] ignore missing credential files instead of failing hard --- .../scala/scalafix/sbt/ScalafixPlugin.scala | 24 +++++++++++++++---- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/src/main/scala/scalafix/sbt/ScalafixPlugin.scala b/src/main/scala/scalafix/sbt/ScalafixPlugin.scala index 1242584a..880df397 100644 --- a/src/main/scala/scalafix/sbt/ScalafixPlugin.scala +++ b/src/main/scala/scalafix/sbt/ScalafixPlugin.scala @@ -293,15 +293,29 @@ object ScalafixPlugin extends AutoPlugin { scalafixSbtResolversAsCoursierRepositories := { val logger = streams.value.log - val credentialsByHost = Credentials - .allDirect(credentials.value) - .map { dc => + // mimics https://github.com/sbt/librarymanagement/blob/v1.10.0/ivy/src/main/scala/sbt/librarymanagement/ivy/Credentials.scala#L23-L28 + val asDirectCredentials = credentials.value.flatMap { + _ match { + case dc: DirectCredentials => + Some(dc) + case fc: FileCredentials => + Credentials.loadCredentials(fc.path) match { + case Left(err) => + logger.warn(err) + None + case Right(dc) => + Some(dc) + } + } + } + + val credentialsByHost = + asDirectCredentials.map { dc => dc.host -> coursierapi.Credentials.of( dc.userName, dc.passwd ) - } - .toMap + }.toMap resolvers.value.flatMap { resolver => CoursierRepoResolvers.repository( From 324e71edb0729f4e946b4ceb6e618576f0e42cf1 Mon Sep 17 00:00:00 2001 From: "scala-center-steward[bot]" <111975575+scala-center-steward[bot]@users.noreply.github.com> Date: Mon, 1 Jul 2024 00:19:06 +0000 Subject: [PATCH 061/129] Update scalatest to 3.2.19 --- build.sbt | 2 +- src/sbt-test/sbt-scalafix/basic/build.sbt | 2 +- src/sbt-test/sbt-scalafix/inconfig/build.sbt | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/build.sbt b/build.sbt index 23ce6dc3..cecab580 100644 --- a/build.sbt +++ b/build.sbt @@ -42,7 +42,7 @@ resolvers ++= Resolver.sonatypeOssRepos("public") libraryDependencies ++= Dependencies.all libraryDependencies ++= List( "com.lihaoyi" %% "fansi" % "0.5.0" % Test, - "org.scalatest" %% "scalatest" % "3.2.18" % Test + "org.scalatest" %% "scalatest" % "3.2.19" % Test ) scalaVersion := "2.12.19" diff --git a/src/sbt-test/sbt-scalafix/basic/build.sbt b/src/sbt-test/sbt-scalafix/basic/build.sbt index 297c3104..f5464d86 100644 --- a/src/sbt-test/sbt-scalafix/basic/build.sbt +++ b/src/sbt-test/sbt-scalafix/basic/build.sbt @@ -5,7 +5,7 @@ inThisBuild( "org.scalameta" %% "testkit" % "4.3.10" % Test, "org.scalameta" %% "munit" % "0.7.9" % Test, "org.scalacheck" %% "scalacheck" % "1.13.5" % Test, - "org.scalatest" %% "scalatest" % "3.2.18" % Test + "org.scalatest" %% "scalatest" % "3.2.19" % Test ), scalafixDependencies := List( // Custom rule published to Maven Central https://github.com/scalacenter/example-scalafix-rule diff --git a/src/sbt-test/sbt-scalafix/inconfig/build.sbt b/src/sbt-test/sbt-scalafix/inconfig/build.sbt index 300e59d7..a8bf1888 100644 --- a/src/sbt-test/sbt-scalafix/inconfig/build.sbt +++ b/src/sbt-test/sbt-scalafix/inconfig/build.sbt @@ -5,7 +5,7 @@ inThisBuild( "org.scalameta" %% "testkit" % "4.3.10" % Test, "org.scalameta" %% "munit" % "0.7.9" % Test, "org.scalacheck" %% "scalacheck" % "1.13.5" % Test, - "org.scalatest" %% "scalatest" % "3.2.18" % Test + "org.scalatest" %% "scalatest" % "3.2.19" % Test ), scalafixDependencies := List( // Custom rule published to Maven Central https://github.com/scalacenter/example-scalafix-rule From 3371c736289c764edea2e1395bc80d0d59ad78fe Mon Sep 17 00:00:00 2001 From: "scala-center-steward[bot]" <111975575+scala-center-steward[bot]@users.noreply.github.com> Date: Mon, 15 Jul 2024 00:19:29 +0000 Subject: [PATCH 062/129] Update sbt, scripted-plugin to 1.10.1 --- project/build.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project/build.properties b/project/build.properties index 081fdbbc..ee4c672c 100644 --- a/project/build.properties +++ b/project/build.properties @@ -1 +1 @@ -sbt.version=1.10.0 +sbt.version=1.10.1 From 518c503f7d8ef4e509baba7696cc5da0c96a9707 Mon Sep 17 00:00:00 2001 From: "scala-center-steward[bot]" <111975575+scala-center-steward[bot]@users.noreply.github.com> Date: Thu, 1 Aug 2024 00:22:22 +0000 Subject: [PATCH 063/129] Update scalafmt-core to 3.8.3 --- .scalafmt.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.scalafmt.conf b/.scalafmt.conf index b6db84f7..7dca62d2 100644 --- a/.scalafmt.conf +++ b/.scalafmt.conf @@ -1,4 +1,4 @@ -version = "3.8.2" +version = "3.8.3" project.git=true align.preset=none assumeStandardLibraryStripMargin = true From 698f99a710cf7c5c43e5d748b23df2719a615400 Mon Sep 17 00:00:00 2001 From: Brice Jaglin Date: Tue, 13 Aug 2024 08:58:44 +0200 Subject: [PATCH 064/129] avoid deprecated old shell syntax https://github.com/sbt/sbt/commit/2305abd81ead3533920c960fa5e20384a6541c3d --- .../scala/scalafix/sbt/ScalafixPlugin.scala | 2 +- src/sbt-test/sbt-1.5/scalafixEnable/test | 16 ++++---- src/sbt-test/sbt-1.5/testkit/test | 6 +-- src/sbt-test/sbt-scalafix/basic/test | 8 ++-- src/sbt-test/sbt-scalafix/cross-build/test | 40 +++++++++---------- .../sbt-scalafix/custom-src-directory/test | 6 +-- src/sbt-test/sbt-scalafix/inconfig/test | 18 ++++----- src/sbt-test/sbt-scalafix/local-rules/test | 12 +++--- .../sbt-scalafix/relax-scalacOptions/test | 2 +- .../sbt-scalafix/root-validation/test | 6 +-- src/sbt-test/sbt-scalafix/scalafixEnable/test | 6 +-- .../sbt-scalafix/scalafixOnCompile/test | 26 ++++++------ .../sbt-scalafix/semanticdb-enabled/test | 12 +++--- src/sbt-test/sbt-scalafix/suppress/test | 6 +-- src/sbt-test/skip-windows/caching/test | 34 ++++++++-------- 15 files changed, 100 insertions(+), 100 deletions(-) diff --git a/src/main/scala/scalafix/sbt/ScalafixPlugin.scala b/src/main/scala/scalafix/sbt/ScalafixPlugin.scala index 1242584a..6dc1da83 100644 --- a/src/main/scala/scalafix/sbt/ScalafixPlugin.scala +++ b/src/main/scala/scalafix/sbt/ScalafixPlugin.scala @@ -32,7 +32,7 @@ object ScalafixPlugin extends AutoPlugin { inputKey[Unit]( "Run scalafix rule(s) in this project and configuration. " + "For example: scalafix RemoveUnused. " + - "To run on test sources use test:scalafix or scalafixAll. " + + "To run on test sources use `Test / scalafix` or scalafixAll. " + "When invoked, prior compilation with -Xfatal-warnings relaxed will be triggered for semantic rules." ) val scalafixAll: InputKey[Unit] = diff --git a/src/sbt-test/sbt-1.5/scalafixEnable/test b/src/sbt-test/sbt-1.5/scalafixEnable/test index 3deb3b46..f9664229 100644 --- a/src/sbt-test/sbt-1.5/scalafixEnable/test +++ b/src/sbt-test/sbt-1.5/scalafixEnable/test @@ -2,15 +2,15 @@ > scalafixEnable # check that projects not supported by sbt-scalafix can still compile -> scala210/compile -> scala211/compile +> scala210 / compile +> scala211 / compile # check that we can run a semantic rule against a Scala 2.12 dialect source file --> scala212/scalafix --check SemanticRule -> scala212/scalafix SemanticRule -> scala212/scalafix --check SemanticRule +-> scala212 / scalafix --check SemanticRule +> scala212 / scalafix SemanticRule +> scala212 / scalafix --check SemanticRule # check that we can run a semantic rule against a Scala 3 dialect source file --> scala3/scalafix --check SemanticRule -> scala3/scalafix SemanticRule -> scala3/scalafix --check SemanticRule \ No newline at end of file +-> scala3 / scalafix --check SemanticRule +> scala3 / scalafix SemanticRule +> scala3 / scalafix --check SemanticRule \ No newline at end of file diff --git a/src/sbt-test/sbt-1.5/testkit/test b/src/sbt-test/sbt-1.5/testkit/test index 775b00ef..f6b0ddac 100644 --- a/src/sbt-test/sbt-1.5/testkit/test +++ b/src/sbt-test/sbt-1.5/testkit/test @@ -1,3 +1,3 @@ --> tests/test -> testsTarget2_13/test:run --save-expect -> tests/test +-> tests / test +> testsTarget2_13 / Test / run --save-expect +> tests / test diff --git a/src/sbt-test/sbt-scalafix/basic/test b/src/sbt-test/sbt-scalafix/basic/test index 06da863e..7d7b65f0 100644 --- a/src/sbt-test/sbt-scalafix/basic/test +++ b/src/sbt-test/sbt-scalafix/basic/test @@ -1,6 +1,6 @@ --> example/scalafix --test +-> example / scalafix --test $ sleep 2000 > checkLogs -> example/scalafix -> example/scalafix --test -> tests/test +> example / scalafix +> example / scalafix --test +> tests / test diff --git a/src/sbt-test/sbt-scalafix/cross-build/test b/src/sbt-test/sbt-scalafix/cross-build/test index 3e4b8c04..005052f4 100644 --- a/src/sbt-test/sbt-scalafix/cross-build/test +++ b/src/sbt-test/sbt-scalafix/cross-build/test @@ -3,32 +3,32 @@ -> scalafixAll --test ProcedureSyntax -> scalafix --test ProcedureSyntax --> compile:scalafix --test ProcedureSyntax --> test:scalafix --test ProcedureSyntax --> it:scalafix --test ProcedureSyntax +-> Compile / scalafix --test ProcedureSyntax +-> Test / scalafix --test ProcedureSyntax +-> IntegrationTest / scalafix --test ProcedureSyntax > scalafix ProcedureSyntax > scalafix --test ProcedureSyntax -> compile:scalafix ProcedureSyntax -> compile:scalafix --test ProcedureSyntax --> test:scalafix --test ProcedureSyntax --> it:scalafix --test ProcedureSyntax +> Compile / scalafix ProcedureSyntax +> Compile / scalafix --test ProcedureSyntax +-> Test / scalafix --test ProcedureSyntax +-> IntegrationTest / scalafix --test ProcedureSyntax -> test:scalafix ProcedureSyntax -> test:scalafix --test ProcedureSyntax --> it:scalafix --test ProcedureSyntax +> Test / scalafix ProcedureSyntax +> Test / scalafix --test ProcedureSyntax +-> IntegrationTest / scalafix --test ProcedureSyntax > scalafixAll ProcedureSyntax -> it:scalafix --test ProcedureSyntax +> IntegrationTest / scalafix --test ProcedureSyntax -> javaProject/compile:scalafix ProcedureSyntax +> javaProject / Compile /scalafix ProcedureSyntax -# it config exists only for 2.12 -> it:scalafix +# IntegrationTest exists only for scala212 +> IntegrationTest / scalafix -> scala212/compile:scalafix -> scala212/test:scalafix -> scala212/it:scalafix -> scala212/compile:scalafix --test -> scala212/test:scalafix --test -> scala212/it:scalafix --test +> scala212 / Compile / scalafix +> scala212 / Test / scalafix +> scala212 / IntegrationTest / scalafix +> scala212 / Compile / scalafix --test +> scala212 / Test / scalafix --test +> scala212 / IntegrationTest / scalafix --test diff --git a/src/sbt-test/sbt-scalafix/custom-src-directory/test b/src/sbt-test/sbt-scalafix/custom-src-directory/test index 353d25b5..71fe2353 100644 --- a/src/sbt-test/sbt-scalafix/custom-src-directory/test +++ b/src/sbt-test/sbt-scalafix/custom-src-directory/test @@ -1,3 +1,3 @@ --> app/scalafix --test ProcedureSyntax -> app/scalafix ProcedureSyntax -> app/scalafix --test ProcedureSyntax \ No newline at end of file +-> app / scalafix --test ProcedureSyntax +> app / scalafix ProcedureSyntax +> app / scalafix --test ProcedureSyntax \ No newline at end of file diff --git a/src/sbt-test/sbt-scalafix/inconfig/test b/src/sbt-test/sbt-scalafix/inconfig/test index 278899a0..1c1e040a 100644 --- a/src/sbt-test/sbt-scalafix/inconfig/test +++ b/src/sbt-test/sbt-scalafix/inconfig/test @@ -1,9 +1,9 @@ --> ; example/scalafix --test ; example/it:scalafix --test --> example/scalafixAll --test -> example/it:scalafix -> example/it:scalafix --test --> example/scalafix --test -> tests/test -> example/scalafixAll -> example/scalafixAll --test -> example/scalafix --test +-> ; example / scalafix --test ; example / IntegrationTest / scalafix --test +-> example / scalafixAll --test +> example / IntegrationTest / scalafix +> example / IntegrationTest / scalafix --test +-> example / scalafix --test +> tests / test +> example / scalafixAll +> example / scalafixAll --test +> example / scalafix --test diff --git a/src/sbt-test/sbt-scalafix/local-rules/test b/src/sbt-test/sbt-scalafix/local-rules/test index fbe71e93..15808542 100644 --- a/src/sbt-test/sbt-scalafix/local-rules/test +++ b/src/sbt-test/sbt-scalafix/local-rules/test @@ -1,15 +1,15 @@ -> service/scalafix LocalSyntacticRule +> service / scalafix LocalSyntacticRule # ensure updates to the rule definition (that we make sure compiles first) is reflected in the next run -> rules/test:compile +> rules / Test / compile $ copy-file rules/src/test/scala/local/Boom.scala rules/src/main/scala/local/Boom.scala $ delete rules/src/main/scala/local/NoOp.scala --> service/scalafix LocalSyntacticRule +-> service / scalafix LocalSyntacticRule # make sure scalafixDependencies is also honored by running a rule from a remote JAR -> service/scalafix SyntacticRule +> service / scalafix SyntacticRule # run a rule included from a remote JAR referenced via the Scalafix ivy config -> service/scalafix SyntacticRule +> service / scalafix SyntacticRule -> sameproject/scalafix SameProjectSyntacticRule +> sameproject / scalafix SameProjectSyntacticRule diff --git a/src/sbt-test/sbt-scalafix/relax-scalacOptions/test b/src/sbt-test/sbt-scalafix/relax-scalacOptions/test index 678f60ff..273d23e2 100644 --- a/src/sbt-test/sbt-scalafix/relax-scalacOptions/test +++ b/src/sbt-test/sbt-scalafix/relax-scalacOptions/test @@ -7,7 +7,7 @@ # ... and indirect scalafix invocation > clean -> test:scalafix --check RemoveUnused +> Test / scalafix --check RemoveUnused -> checkLastCompilationCached > compile > checkLastCompilationCached diff --git a/src/sbt-test/sbt-scalafix/root-validation/test b/src/sbt-test/sbt-scalafix/root-validation/test index 55d8f8c9..0d3f6706 100644 --- a/src/sbt-test/sbt-scalafix/root-validation/test +++ b/src/sbt-test/sbt-scalafix/root-validation/test @@ -1,3 +1,3 @@ --> root/scalafix --check RemoveUnused -> root/scalafix RemoveUnused -> root/scalafix --check RemoveUnused +-> root / scalafix --check RemoveUnused +> root / scalafix RemoveUnused +> root / scalafix --check RemoveUnused diff --git a/src/sbt-test/sbt-scalafix/scalafixEnable/test b/src/sbt-test/sbt-scalafix/scalafixEnable/test index c43cb601..adf36307 100644 --- a/src/sbt-test/sbt-scalafix/scalafixEnable/test +++ b/src/sbt-test/sbt-scalafix/scalafixEnable/test @@ -2,9 +2,9 @@ > scalafixEnable > check --> config/test:compile -> config/scalafixAll RemoveUnused -> config/test:compile +-> config / Test / compile +> config / scalafixAll RemoveUnused +> config / Test / compile -> checkVersion > ++2.12.15 -v diff --git a/src/sbt-test/sbt-scalafix/scalafixOnCompile/test b/src/sbt-test/sbt-scalafix/scalafixOnCompile/test index 7af329a5..81509374 100644 --- a/src/sbt-test/sbt-scalafix/scalafixOnCompile/test +++ b/src/sbt-test/sbt-scalafix/scalafixOnCompile/test @@ -7,27 +7,27 @@ > scalafix --check # check explicit rewrite of rewrite/src/it/scala/UnusedImports.scala via `scalafix` --> it:scalafix --check -> it:scalafix -> it:scalafix --check +-> IntegrationTest / scalafix --check +> IntegrationTest / scalafix +> IntegrationTest / scalafix --check # check lint for lint/src/test/scala/Null.scala --> lint/test:scalafix --check --> lint/test:scalafix --> lint/test:compile +-> lint / Test / scalafix --check +-> lint / Test / scalafix +-> lint / Test / compile # check that default rules are ignored when rules are passed explicitly --> lint/test:scalafix --check -> lint/test:scalafix --check RemoveUnused -> lint/test:scalafix RemoveUnused +-> lint / Test / scalafix --check +> lint / Test / scalafix --check RemoveUnused +> lint / Test / scalafix RemoveUnused # check configuration granularity for scalafixOnCompile > set lint / Test / scalafixOnCompile := false -> lint/test:compile +> lint / Test / compile # check that triggered rules are respected on compilation, and ignored on explicit invocation. # `private var` is detected by `DisableSyntax.noVars = true` on explicit invocation, # and removed by `triggered.RemoveUnused.privates = true` on compilation. --> triggered/test:scalafix -> triggered/test:compile -> triggered/test:scalafix +-> triggered / Test / scalafix +> triggered / Test / compile +> triggered / Test / scalafix diff --git a/src/sbt-test/sbt-scalafix/semanticdb-enabled/test b/src/sbt-test/sbt-scalafix/semanticdb-enabled/test index 826b64e8..11f6e281 100644 --- a/src/sbt-test/sbt-scalafix/semanticdb-enabled/test +++ b/src/sbt-test/sbt-scalafix/semanticdb-enabled/test @@ -1,7 +1,7 @@ --> scala212/scalafix --check -> scala212/scalafix -> scala212/scalafix --check +-> scala212 / scalafix --check +> scala212 / scalafix +> scala212 / scalafix --check --> scala213/scalafix --check -> scala213/scalafix -> scala213/scalafix --check \ No newline at end of file +-> scala213 / scalafix --check +> scala213 / scalafix +> scala213 / scalafix --check \ No newline at end of file diff --git a/src/sbt-test/sbt-scalafix/suppress/test b/src/sbt-test/sbt-scalafix/suppress/test index 2643ea09..2b6e5199 100644 --- a/src/sbt-test/sbt-scalafix/suppress/test +++ b/src/sbt-test/sbt-scalafix/suppress/test @@ -1,6 +1,6 @@ > scalafixEnable --> compile:scalafix --test -> compile:scalafix --auto-suppress-linter-errors -> compile:scalafix --test +-> Compile / scalafix --test +> Compile / scalafix --auto-suppress-linter-errors +> Compile / scalafix --test > check diff --git a/src/sbt-test/skip-windows/caching/test b/src/sbt-test/skip-windows/caching/test index dfe6b223..a0bc326d 100644 --- a/src/sbt-test/skip-windows/caching/test +++ b/src/sbt-test/skip-windows/caching/test @@ -41,10 +41,10 @@ $ copy-file files/ProcedureSyntax.scala src/test/scala/ToPatch.scala $ copy-file files/Valid.scala src/test/scala/Valid.scala # avoid rounding in mtime that could cause false negatives in `newer` $ sleep 1000 -> test:scalafix ProcedureSyntax DisableSyntax +> Test / scalafix ProcedureSyntax DisableSyntax $ newer src/test/scala/ToPatch.scala src/test/scala/Valid.scala $ exec chmod 000 src/test/scala/ToPatch.scala --> test:scalafix ProcedureSyntax DisableSyntax +-> Test / scalafix ProcedureSyntax DisableSyntax $ delete src/test/scala # an added file after a successful run should be checked @@ -90,8 +90,8 @@ $ delete src/main/scala > set scalafixConfig := None $ mkdir src/test/scala $ copy-file files/ProcedureSyntax.scala src/test/scala/InitiallyValid.scala -> test:scalafix --check RemoveUnused --> test:scalafix --check RemoveUnused ProcedureSyntax +> Test / scalafix --check RemoveUnused +-> Test / scalafix --check RemoveUnused ProcedureSyntax $ delete src/test/scala # updating the rule-related flags should not invalidate the cache as long as rules that will run do not change @@ -144,13 +144,13 @@ $ delete src/main/scala > set scalafixConfig := Some(file("files/DisableSyntaxVar.scalafix.conf")) $ mkdir src/test/scala $ copy-file files/Valid.scala src/test/scala/Valid.scala -> test:scalafix ProcedureSyntax -> test:scalafix --check +> Test / scalafix ProcedureSyntax +> Test / scalafix --check $ exec chmod 000 src/test/scala/Valid.scala -> test:scalafix --check ProcedureSyntax DisableSyntax -> test:scalafix --syntactic ProcedureSyntax -> test:scalafix DisableSyntax ProcedureSyntax -> test:scalafix +> Test / scalafix --check ProcedureSyntax DisableSyntax +> Test / scalafix --syntactic ProcedureSyntax +> Test / scalafix DisableSyntax ProcedureSyntax +> Test / scalafix $ delete src/test/scala # files should be re-checked after updating the configuration (even if the rule is the same) @@ -254,11 +254,11 @@ $ mkdir src/test/scala $ copy-file files/UnusedImports.scala src/main/scala/Valid.scala $ copy-file files/Null.scala src/test/scala/Valid.scala > scalafix --check ProcedureSyntax -> test:scalafix --check ProcedureSyntax +> Test / scalafix --check ProcedureSyntax $ exec chmod 000 src/main/scala/Valid.scala $ exec chmod 000 src/test/scala/Valid.scala > scalafix --check ProcedureSyntax -> test:scalafix --check ProcedureSyntax +> Test / scalafix --check ProcedureSyntax $ delete src/main/scala $ delete src/test/scala @@ -271,12 +271,12 @@ $ copy-file files/ProcedureSyntax.scala src/test/scala/InitiallyInvalid.scala -> scalafixAll --check ProcedureSyntax $ exec chmod 000 src/main/scala/Valid.scala > scalafix --check ProcedureSyntax --> test:scalafix --check ProcedureSyntax -> test:scalafix ProcedureSyntax -> test:scalafix ProcedureSyntax +-> Test / scalafix --check ProcedureSyntax +> Test / scalafix ProcedureSyntax +> Test / scalafix ProcedureSyntax $ exec chmod 000 src/test/scala/InitiallyInvalid.scala > scalafix --check ProcedureSyntax -> test:scalafix --check ProcedureSyntax +> Test / scalafix --check ProcedureSyntax > scalafixAll --check ProcedureSyntax $ delete src/main/scala $ delete src/test/scala @@ -334,7 +334,7 @@ $ delete src/main/scala $ mkdir src/main/scala $ copy-file files/Valid.scala src/main/scala/InitiallyValid.scala > scalafix LocalSyntacticRule -> rules/test:compile +> rules / Test / compile $ copy-file rules/src/test/scala/local/Boom.scala rules/src/main/scala/local/Boom.scala $ delete rules/src/main/scala/local/NoOp.scala -> scalafix LocalSyntacticRule From 20c0a14f2dbd787016f54c5a5a7955b2b7668e8e Mon Sep 17 00:00:00 2001 From: "scala-center-steward[bot]" <111975575+scala-center-steward[bot]@users.noreply.github.com> Date: Thu, 15 Aug 2024 00:17:03 +0000 Subject: [PATCH 065/129] Update sbt-ci-release to 1.6.0 --- project/plugins.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project/plugins.sbt b/project/plugins.sbt index 244860e8..0cc2d33c 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -1,5 +1,5 @@ resolvers ++= Resolver.sonatypeOssRepos("public") -addSbtPlugin("com.github.sbt" % "sbt-ci-release" % "1.5.12") +addSbtPlugin("com.github.sbt" % "sbt-ci-release" % "1.6.0") libraryDependencies += "org.scala-sbt" %% "scripted-plugin" % sbtVersion.value Compile / unmanagedSourceDirectories ++= { From 8d0820d76d374a7fc2a6a51291f7e8b8211395ca Mon Sep 17 00:00:00 2001 From: Brice Jaglin Date: Tue, 20 Aug 2024 08:47:45 +0200 Subject: [PATCH 066/129] bump sbt-ci-release to fix JDK8 support --- project/plugins.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project/plugins.sbt b/project/plugins.sbt index 0cc2d33c..d205d7a6 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -1,5 +1,5 @@ resolvers ++= Resolver.sonatypeOssRepos("public") -addSbtPlugin("com.github.sbt" % "sbt-ci-release" % "1.6.0") +addSbtPlugin("com.github.sbt" % "sbt-ci-release" % "1.6.1") libraryDependencies += "org.scala-sbt" %% "scripted-plugin" % sbtVersion.value Compile / unmanagedSourceDirectories ++= { From ab31f5d88afc50c5b07ecc870437e6ae6fcf00b5 Mon Sep 17 00:00:00 2001 From: Brice Jaglin Date: Thu, 22 Aug 2024 18:31:59 +0200 Subject: [PATCH 067/129] bump to scalafix version exposing cli_3.x.y --- project/Dependencies.scala | 2 +- src/sbt-test/sbt-scalafix/resolvers/project/plugins.sbt | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/project/Dependencies.scala b/project/Dependencies.scala index a77117c2..cee11289 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -2,7 +2,7 @@ import sbt._ object Dependencies { val x = List(1) // scalafix:ok - def scalafixVersion: String = "0.12.1" + def scalafixVersion: String = "0.12.1+81-c6766833-SNAPSHOT" val all = List( "org.eclipse.jgit" % "org.eclipse.jgit" % "5.13.3.202401111512-r", diff --git a/src/sbt-test/sbt-scalafix/resolvers/project/plugins.sbt b/src/sbt-test/sbt-scalafix/resolvers/project/plugins.sbt index 843726fa..2d3b4d3b 100644 --- a/src/sbt-test/sbt-scalafix/resolvers/project/plugins.sbt +++ b/src/sbt-test/sbt-scalafix/resolvers/project/plugins.sbt @@ -1 +1,2 @@ +resolvers += Resolver.sonatypeRepo("public") addSbtPlugin("ch.epfl.scala" % "sbt-scalafix" % sys.props("plugin.version")) From 9ad48bbee83f56696ee9e6b645b21fdea50c6313 Mon Sep 17 00:00:00 2001 From: Brice Jaglin Date: Fri, 23 Aug 2024 00:57:48 +0200 Subject: [PATCH 068/129] use cli3.x.y for Scala 3 projects --- .../scalafix/internal/sbt/ScalafixInterface.scala | 8 +------- src/main/scala/scalafix/sbt/ScalafixPlugin.scala | 14 ++++---------- src/sbt-test/sbt-scalafix/scalafixEnable/build.sbt | 9 ++++++++- src/sbt-test/skip-windows/caching/test | 2 ++ 4 files changed, 15 insertions(+), 18 deletions(-) diff --git a/src/main/scala/scalafix/internal/sbt/ScalafixInterface.scala b/src/main/scala/scalafix/internal/sbt/ScalafixInterface.scala index f52843e1..cee229ea 100644 --- a/src/main/scala/scalafix/internal/sbt/ScalafixInterface.scala +++ b/src/main/scala/scalafix/internal/sbt/ScalafixInterface.scala @@ -159,13 +159,7 @@ object ScalafixInterface { None case None => // cache miss, resolve scalafix artifacts and classload them - if (scalafixScalaBinaryVersion.startsWith("3")) - logger.error( - "To use Scalafix on Scala 3 projects, you must unset `scalafixScalaBinaryVersion`. " + - "Rules such as ExplicitResultTypes requiring the project version to match the Scalafix " + - "version are unsupported for the moment." - ) - else if (scalafixScalaBinaryVersion == "2.11") + if (scalafixScalaBinaryVersion == "2.11") logger.error( "Scala 2.11 is no longer supported. Please downgrade to the final version supporting " + "it: sbt-scalafix 0.10.4." diff --git a/src/main/scala/scalafix/sbt/ScalafixPlugin.scala b/src/main/scala/scalafix/sbt/ScalafixPlugin.scala index 6d3f75ea..cc1b44ba 100644 --- a/src/main/scala/scalafix/sbt/ScalafixPlugin.scala +++ b/src/main/scala/scalafix/sbt/ScalafixPlugin.scala @@ -65,14 +65,13 @@ object ScalafixPlugin extends AutoPlugin { "Can be set in ThisBuild or at project-level." ) @deprecated( - "scalafixScalaBinaryVersion now follows scalaBinaryVersion by default", + "scalafixScalaBinaryVersion now follows scalaVersion by default", "0.12.1" ) val scalafixScalaBinaryVersion: SettingKey[String] = settingKey[String]( - "The Scala binary version used for scalafix execution. Must be set at project-level. " + - "Custom rules must be compiled against that binary version. Defaults to 2.12 for 2.12 projects, " + - "2.13 otherwise." + "The Scala version used for scalafix execution. Must be set at project-level. " + + "Custom rules must be compiled against that binary version. Defaults to the project's scalaVersion." ) val scalafixConfig: SettingKey[Option[File]] = settingKey[Option[File]]( @@ -268,12 +267,7 @@ object ScalafixPlugin extends AutoPlugin { }, ivyConfigurations += ScalafixConfig, scalafixAll := scalafixAllInputTask.evaluated, - (scalafixScalaBinaryVersion: @nowarn) := { - scalaBinaryVersion.value match { - case "2.12" => "2.12" - case _ => "2.13" - } - } + (scalafixScalaBinaryVersion: @nowarn) := scalaVersion.value ) override lazy val globalSettings: Seq[Def.Setting[_]] = Seq( diff --git a/src/sbt-test/sbt-scalafix/scalafixEnable/build.sbt b/src/sbt-test/sbt-scalafix/scalafixEnable/build.sbt index 6cf892ac..886bbddd 100644 --- a/src/sbt-test/sbt-scalafix/scalafixEnable/build.sbt +++ b/src/sbt-test/sbt-scalafix/scalafixEnable/build.sbt @@ -1,28 +1,35 @@ val V = _root_.scalafix.sbt.BuildInfo -lazy val config = project +lazy val config = project.settings( + scalafixScalaBinaryVersion := scalaBinaryVersion.value // to support old scalafix-interface +) lazy val unsupported = project.settings( + scalafixScalaBinaryVersion := scalaBinaryVersion.value, // to support old scalafix-interface // 2.11.x is not supported scalaVersion := "2.11.12" ) lazy val bumpScala = project.settings( + scalafixScalaBinaryVersion := scalaBinaryVersion.value, // to support old scalafix-interface // semanticdb-scalac_2.12.0 was never available scalaVersion := "2.12.0" ) lazy val downgradeScalameta = project.settings( + scalafixScalaBinaryVersion := scalaBinaryVersion.value, // to support old scalafix-interface // semanticdb-scalac_2.12.4 no longer available after 4.1.9 scalaVersion := "2.12.4" ) lazy val upgradeScalameta = project.settings( + scalafixScalaBinaryVersion := scalaBinaryVersion.value, // to support old scalafix-interface // semanticdb-scalac_2.12.15 not yet available in 4.4.10, became available as of 4.4.28 scalaVersion := "2.12.15" ) lazy val available = project.settings( + scalafixScalaBinaryVersion := scalaBinaryVersion.value, // to support old scalafix-interface // semanticdb-scalac_2.13.4 available in 4.4.10 scalaVersion := "2.13.4", crossScalaVersions := Seq("2.12.15") diff --git a/src/sbt-test/skip-windows/caching/test b/src/sbt-test/skip-windows/caching/test index a0bc326d..6f15cdea 100644 --- a/src/sbt-test/skip-windows/caching/test +++ b/src/sbt-test/skip-windows/caching/test @@ -341,6 +341,7 @@ $ delete rules/src/main/scala/local/NoOp.scala $ delete src/main/scala # make sure cache is invalidated after changing scalafix version +> set scalafixScalaBinaryVersion := scalaBinaryVersion.value // to support old scalafix-interface > set scalafixConfig := None $ mkdir src/main/scala $ copy-file files/Valid.scala src/main/scala/Valid.scala @@ -354,6 +355,7 @@ $ exec chmod 000 src/main/scala/Valid.scala $ delete src/main/scala # make sure cache is invalidated after changing scalafix version when no custom dependency is set +> set scalafixScalaBinaryVersion := scalaBinaryVersion.value // to support old scalafix-interface > set scalafixConfig := None $ mkdir src/main/scala $ copy-file files/Valid.scala src/main/scala/Valid.scala From 98866a4af64ff264802a8d6ffa555eddf0dc3070 Mon Sep 17 00:00:00 2001 From: "scala-center-steward[bot]" <111975575+scala-center-steward[bot]@users.noreply.github.com> Date: Sun, 15 Sep 2024 00:20:31 +0000 Subject: [PATCH 069/129] Update interface to 1.0.20 --- project/Dependencies.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project/Dependencies.scala b/project/Dependencies.scala index cee11289..1145abce 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -7,6 +7,6 @@ object Dependencies { val all = List( "org.eclipse.jgit" % "org.eclipse.jgit" % "5.13.3.202401111512-r", "ch.epfl.scala" % "scalafix-interfaces" % scalafixVersion, - "io.get-coursier" % "interface" % "1.0.19" + "io.get-coursier" % "interface" % "1.0.20" ) } From 0939b83ad17c5639d07c4773e8b8c012b9e3a09c Mon Sep 17 00:00:00 2001 From: "scala-center-steward[bot]" <111975575+scala-center-steward[bot]@users.noreply.github.com> Date: Sun, 15 Sep 2024 00:20:40 +0000 Subject: [PATCH 070/129] Update scala-library to 2.12.20 --- build.sbt | 2 +- src/sbt-test/sbt-1.5/scalafixEnable/build.sbt | 2 +- src/sbt-test/sbt-scalafix/basic/build.sbt | 2 +- src/sbt-test/sbt-scalafix/inconfig/build.sbt | 2 +- src/sbt-test/sbt-scalafix/root-validation/build.sbt | 2 +- src/sbt-test/sbt-scalafix/semanticdb-enabled/build.sbt | 2 +- src/sbt-test/skip-java17/scalafixResolvers/build.sbt | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/build.sbt b/build.sbt index cecab580..c6e8f114 100644 --- a/build.sbt +++ b/build.sbt @@ -45,7 +45,7 @@ libraryDependencies ++= List( "org.scalatest" %% "scalatest" % "3.2.19" % Test ) -scalaVersion := "2.12.19" +scalaVersion := "2.12.20" // keep this as low as possible to avoid running into binary incompatibility such as https://github.com/sbt/sbt/issues/5049 pluginCrossBuild / sbtVersion := "1.3.1" diff --git a/src/sbt-test/sbt-1.5/scalafixEnable/build.sbt b/src/sbt-test/sbt-1.5/scalafixEnable/build.sbt index 86c4551d..93274b51 100644 --- a/src/sbt-test/sbt-1.5/scalafixEnable/build.sbt +++ b/src/sbt-test/sbt-1.5/scalafixEnable/build.sbt @@ -15,7 +15,7 @@ lazy val scala211 = project lazy val scala212 = project .in(file("scala212")) .settings( - scalaVersion := "2.12.19" // supported by semanticdb-scalac + scalaVersion := "2.12.20" // supported by semanticdb-scalac ) lazy val scala3 = project diff --git a/src/sbt-test/sbt-scalafix/basic/build.sbt b/src/sbt-test/sbt-scalafix/basic/build.sbt index f5464d86..3a077a01 100644 --- a/src/sbt-test/sbt-scalafix/basic/build.sbt +++ b/src/sbt-test/sbt-scalafix/basic/build.sbt @@ -1,6 +1,6 @@ inThisBuild( List( - scalaVersion := "2.12.19", + scalaVersion := "2.12.20", libraryDependencies ++= List( "org.scalameta" %% "testkit" % "4.3.10" % Test, "org.scalameta" %% "munit" % "0.7.9" % Test, diff --git a/src/sbt-test/sbt-scalafix/inconfig/build.sbt b/src/sbt-test/sbt-scalafix/inconfig/build.sbt index a8bf1888..fd6f8a37 100644 --- a/src/sbt-test/sbt-scalafix/inconfig/build.sbt +++ b/src/sbt-test/sbt-scalafix/inconfig/build.sbt @@ -1,6 +1,6 @@ inThisBuild( List( - scalaVersion := "2.12.19", + scalaVersion := "2.12.20", libraryDependencies ++= List( "org.scalameta" %% "testkit" % "4.3.10" % Test, "org.scalameta" %% "munit" % "0.7.9" % Test, diff --git a/src/sbt-test/sbt-scalafix/root-validation/build.sbt b/src/sbt-test/sbt-scalafix/root-validation/build.sbt index e8003f6c..0f61111b 100644 --- a/src/sbt-test/sbt-scalafix/root-validation/build.sbt +++ b/src/sbt-test/sbt-scalafix/root-validation/build.sbt @@ -1,6 +1,6 @@ inThisBuild( List( - scalaVersion := "2.12.19" + scalaVersion := "2.12.20" ) ) diff --git a/src/sbt-test/sbt-scalafix/semanticdb-enabled/build.sbt b/src/sbt-test/sbt-scalafix/semanticdb-enabled/build.sbt index 5aa0bf5e..dfd9d9a1 100644 --- a/src/sbt-test/sbt-scalafix/semanticdb-enabled/build.sbt +++ b/src/sbt-test/sbt-scalafix/semanticdb-enabled/build.sbt @@ -4,7 +4,7 @@ ThisBuild / semanticdbEnabled := true lazy val scala212 = project .settings( - scalaVersion := "2.12.19", + scalaVersion := "2.12.20", scalacOptions += "-Ywarn-unused" ) diff --git a/src/sbt-test/skip-java17/scalafixResolvers/build.sbt b/src/sbt-test/skip-java17/scalafixResolvers/build.sbt index 3cda631a..266146e1 100644 --- a/src/sbt-test/skip-java17/scalafixResolvers/build.sbt +++ b/src/sbt-test/skip-java17/scalafixResolvers/build.sbt @@ -1,4 +1,4 @@ -scalaVersion := "2.12.19" +scalaVersion := "2.12.20" TaskKey[Unit]("check") := { val expectedRepositories: Seq[String] = Seq( From 75100db53af98251c7835f1649fc013a248a4585 Mon Sep 17 00:00:00 2001 From: Brice Jaglin Date: Mon, 23 Sep 2024 21:46:11 +0200 Subject: [PATCH 071/129] test against Scala 2.13.15 project --- src/sbt-test/sbt-scalafix/semanticdb-enabled/build.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sbt-test/sbt-scalafix/semanticdb-enabled/build.sbt b/src/sbt-test/sbt-scalafix/semanticdb-enabled/build.sbt index dfd9d9a1..c05f6321 100644 --- a/src/sbt-test/sbt-scalafix/semanticdb-enabled/build.sbt +++ b/src/sbt-test/sbt-scalafix/semanticdb-enabled/build.sbt @@ -10,6 +10,6 @@ lazy val scala212 = project lazy val scala213 = project .settings( - scalaVersion := "2.13.14", + scalaVersion := "2.13.15", scalacOptions += "-Wunused" ) From eeeadfaabee0a8dcbc167a3cc592ad8b9601549e Mon Sep 17 00:00:00 2001 From: Brice Jaglin Date: Tue, 23 Apr 2024 23:13:18 +0200 Subject: [PATCH 072/129] drop sbt 1.3.x support --- build.sbt | 6 ++++-- src/main/scala/sbt/internal/sbtscalafix/JLineAccess.scala | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/build.sbt b/build.sbt index c6e8f114..3b4af4a6 100644 --- a/build.sbt +++ b/build.sbt @@ -48,7 +48,7 @@ libraryDependencies ++= List( scalaVersion := "2.12.20" // keep this as low as possible to avoid running into binary incompatibility such as https://github.com/sbt/sbt/issues/5049 -pluginCrossBuild / sbtVersion := "1.3.1" +pluginCrossBuild / sbtVersion := "1.4.0" scriptedSbt := { val jdk = System.getProperty("java.specification.version").toDouble @@ -56,7 +56,9 @@ scriptedSbt := { if (jdk >= 21) "1.9.0" // first release that supports JDK21 else - "1.3.3" // get https://github.com/sbt/sbt/issues/1673 to avoid race conditions + // https://github.com/sbt/sbt/commit/3b9b200 + // 1.4.[0-2] force batch mode which is not compatible with custom build.properties + "1.4.3" } libraryDependencies += compilerPlugin(scalafixSemanticdb) diff --git a/src/main/scala/sbt/internal/sbtscalafix/JLineAccess.scala b/src/main/scala/sbt/internal/sbtscalafix/JLineAccess.scala index 327e6cb2..ff547574 100644 --- a/src/main/scala/sbt/internal/sbtscalafix/JLineAccess.scala +++ b/src/main/scala/sbt/internal/sbtscalafix/JLineAccess.scala @@ -2,5 +2,5 @@ package sbt.internal.sbtscalafix /** Helper class to access sbt's JLine instance */ object JLineAccess { - def terminalWidth: Int = sbt.internal.util.JLine.usingTerminal(_.getWidth) + def terminalWidth: Int = sbt.internal.util.Terminal.get.getWidth } From b238358fb9c52461972b1478e4c74b84aa9d4a96 Mon Sep 17 00:00:00 2001 From: Brice Jaglin Date: Tue, 23 Apr 2024 23:14:14 +0200 Subject: [PATCH 073/129] remove sbt 1.3 workarounds --- src/main/scala/scalafix/sbt/ScalafixEnable.scala | 8 +------- src/main/scala/scalafix/sbt/ScalafixPlugin.scala | 4 +--- 2 files changed, 2 insertions(+), 10 deletions(-) diff --git a/src/main/scala/scalafix/sbt/ScalafixEnable.scala b/src/main/scala/scalafix/sbt/ScalafixEnable.scala index 2f390b4d..8e071a57 100644 --- a/src/main/scala/scalafix/sbt/ScalafixEnable.scala +++ b/src/main/scala/scalafix/sbt/ScalafixEnable.scala @@ -172,13 +172,7 @@ object ScalafixEnable { ) } } - } ++ Seq( - semanticdbEnabled := true, - // support sbt 1.3.[0-3] which does not contain - // https://github.com/sbt/sbt/pull/5202 - (semanticdbCompilerPlugin := semanticdbCompilerPlugin.value - .withRevision((semanticdbVersion).value)) - ) + } :+ (semanticdbEnabled := true) settings <- inScope(ThisScope.copy(project = Select(project.ref)))( scalacOptionsSettings ++ enableSemanticdbPlugin diff --git a/src/main/scala/scalafix/sbt/ScalafixPlugin.scala b/src/main/scala/scalafix/sbt/ScalafixPlugin.scala index cc1b44ba..638a41f9 100644 --- a/src/main/scala/scalafix/sbt/ScalafixPlugin.scala +++ b/src/main/scala/scalafix/sbt/ScalafixPlugin.scala @@ -229,9 +229,7 @@ object ScalafixPlugin extends AutoPlugin { Def.settings( Defaults.configSettings, sourcesInBase := false, - // local copy of https://github.com/sbt/sbt/blob/e4231ac03903e174bc9975ee00d34064a1d1f373/main/src/main/scala/sbt/Keys.scala#L400 - // so that it does not break on sbt version below 1.4.0 - SettingKey[Boolean]("bspEnabled") := false + bspEnabled := false ) ), update := { From f93b28028178798f38ce3acd28bc909cf81b76f6 Mon Sep 17 00:00:00 2001 From: Brice Jaglin Date: Tue, 23 Apr 2024 23:14:37 +0200 Subject: [PATCH 074/129] leverage sbt 1.4 APIs --- .../scala/scalafix/sbt/ScalafixPlugin.scala | 27 +++++++------------ 1 file changed, 10 insertions(+), 17 deletions(-) diff --git a/src/main/scala/scalafix/sbt/ScalafixPlugin.scala b/src/main/scala/scalafix/sbt/ScalafixPlugin.scala index 638a41f9..9a04919e 100644 --- a/src/main/scala/scalafix/sbt/ScalafixPlugin.scala +++ b/src/main/scala/scalafix/sbt/ScalafixPlugin.scala @@ -655,11 +655,11 @@ object ScalafixPlugin extends AutoPlugin { ): Unit = implicitly[JsonWriter[A]].write(obj, builder) } - // we actually don't need to read anything back, see https://github.com/sbt/sbt/pull/5513 + // implicit conversion of collection is only available on JsonFormat implicit val argFormat = liftFormat(argWriter) def diffWithPreviousRuns[T](f: (Boolean, Set[File]) => T): T = { - val tracker = Tracked.inputChanged(streams.cacheDirectory / "args") { + val tracker = Tracked.inputChangedW(streams.cacheDirectory / "args") { (argsChanged: Boolean, _: Seq[Arg.CacheKey]) => val targets = paths.map(_.toFile).toSet @@ -738,21 +738,14 @@ object ScalafixPlugin extends AutoPlugin { shellArgs: ShellArgs, config: ConfigKey ): Def.Initialize[Task[Seq[Path]]] = - Def.taskDyn { - // Dynamic task to avoid redundantly computing `unmanagedSources.value` - if (shellArgs.files.nonEmpty) { - Def.task { - shellArgs.files.map(file(_).toPath) - } - } else { - Def.task { - for { - source <- (config / scalafix / unmanagedSources).value - if source.exists() - if isScalaFile(source) - } yield source.toPath - } - } + Def.taskIf { + if (shellArgs.files.nonEmpty) shellArgs.files.map(file(_).toPath) + else + for { + source <- (config / scalafix / unmanagedSources).value + if source.exists() + if isScalaFile(source) + } yield source.toPath } private[sbt] val relaxScalacOptionsConfigSettings: Seq[Def.Setting[_]] = From 0ccbddd53b803d5e097741c1cf5a3275bb30efa9 Mon Sep 17 00:00:00 2001 From: Brice Jaglin Date: Tue, 23 Apr 2024 23:16:10 +0200 Subject: [PATCH 075/129] run sbt 1.4+ scripted like the others --- src/sbt-test/sbt-1.4/build-lint/project/build.properties | 1 - src/sbt-test/{sbt-1.4 => sbt-scalafix}/build-lint/build.sbt | 0 .../{sbt-1.4 => sbt-scalafix}/build-lint/project/plugins.sbt | 0 src/sbt-test/{sbt-1.4 => sbt-scalafix}/build-lint/test | 0 4 files changed, 1 deletion(-) delete mode 100644 src/sbt-test/sbt-1.4/build-lint/project/build.properties rename src/sbt-test/{sbt-1.4 => sbt-scalafix}/build-lint/build.sbt (100%) rename src/sbt-test/{sbt-1.4 => sbt-scalafix}/build-lint/project/plugins.sbt (100%) rename src/sbt-test/{sbt-1.4 => sbt-scalafix}/build-lint/test (100%) diff --git a/src/sbt-test/sbt-1.4/build-lint/project/build.properties b/src/sbt-test/sbt-1.4/build-lint/project/build.properties deleted file mode 100644 index dbae93bc..00000000 --- a/src/sbt-test/sbt-1.4/build-lint/project/build.properties +++ /dev/null @@ -1 +0,0 @@ -sbt.version=1.4.9 diff --git a/src/sbt-test/sbt-1.4/build-lint/build.sbt b/src/sbt-test/sbt-scalafix/build-lint/build.sbt similarity index 100% rename from src/sbt-test/sbt-1.4/build-lint/build.sbt rename to src/sbt-test/sbt-scalafix/build-lint/build.sbt diff --git a/src/sbt-test/sbt-1.4/build-lint/project/plugins.sbt b/src/sbt-test/sbt-scalafix/build-lint/project/plugins.sbt similarity index 100% rename from src/sbt-test/sbt-1.4/build-lint/project/plugins.sbt rename to src/sbt-test/sbt-scalafix/build-lint/project/plugins.sbt diff --git a/src/sbt-test/sbt-1.4/build-lint/test b/src/sbt-test/sbt-scalafix/build-lint/test similarity index 100% rename from src/sbt-test/sbt-1.4/build-lint/test rename to src/sbt-test/sbt-scalafix/build-lint/test From 8a264aacdf27be213b923ba4e3687005bc1179a1 Mon Sep 17 00:00:00 2001 From: Brice Jaglin Date: Wed, 24 Apr 2024 18:45:25 +0200 Subject: [PATCH 076/129] parallelize scripted scriptedBatchExecution effectively ignores custom build.properties, so this takes a different approach, running one sbt version per execution, spread over JDK versions for simplicity. --- .github/workflows/ci.yml | 14 +++++++++++--- build.sbt | 9 ++++----- .../cross-build-scala3/project/build.properties | 1 - src/sbt-test/sbt-1.5/scala-3/build.sbt | 1 - .../sbt-1.5/scala-3/project/build.properties | 1 - .../scalafixEnable/project/build.properties | 1 - .../sbt-1.5/testkit/project/build.properties | 1 - .../scalafixResolvers/.env | 0 .../scalafixResolvers/build.sbt | 0 .../scalafixResolvers/project/plugins.sbt | 0 .../scalafixResolvers/test | 0 .../cross-build-scala3/.scalafix-2.conf | 0 .../cross-build-scala3/.scalafix-3.conf | 0 .../cross-build-scala3/build.sbt | 0 .../cross-build-scala3/project/plugins.sbt | 0 .../cross-build-scala3/src/main/scala-2/Main.scala | 0 .../src/main/scala-2/Main.scala.expected | 0 .../cross-build-scala3/src/main/scala-3/Main.scala | 0 .../src/main/scala-3/Main.scala.expected | 0 .../cross-build-scala3/test | 0 src/sbt-test/skip-sbt1.4/scala-3/build.sbt | 1 + .../scala-3/project/plugins.sbt | 0 .../src/main/scala/SignificantIndentation.scala | 0 src/sbt-test/{sbt-1.5 => skip-sbt1.4}/scala-3/test | 0 .../scalafixEnable/build.sbt | 2 +- .../scalafixEnable/project/plugins.sbt | 0 .../scala210/src/main/scala/Main.scala | 0 .../scala211/src/main/scala/Main.scala | 0 .../scala212/src/main/scala/Main.scala | 0 .../src/main/scala/SignificantIndentation.scala | 0 .../{sbt-1.5 => skip-sbt1.4}/scalafixEnable/test | 0 .../{sbt-1.5 => skip-sbt1.4}/testkit/build.sbt | 2 +- .../input/src/main/scala-2.13/fix/Source3.scala | 0 .../input/src/main/scala/fix/SemanticBasic.scala | 0 .../output/src/main/scala-2.13/fix/Source3.scala | 0 .../output/src/main/scala/fix/SemanticBasic.scala | 0 .../testkit/project/TargetAxis.scala | 0 .../testkit/project/plugins.sbt | 0 .../resources/META-INF/services/scalafix.v1.Rule | 0 .../rules/src/main/scala/fix/Semantic.scala | 0 src/sbt-test/{sbt-1.5 => skip-sbt1.4}/testkit/test | 0 .../src/test/scala/fix/InputOutputSuite.scala | 0 42 files changed, 18 insertions(+), 15 deletions(-) delete mode 100644 src/sbt-test/sbt-1.5/cross-build-scala3/project/build.properties delete mode 100644 src/sbt-test/sbt-1.5/scala-3/build.sbt delete mode 100644 src/sbt-test/sbt-1.5/scala-3/project/build.properties delete mode 100644 src/sbt-test/sbt-1.5/scalafixEnable/project/build.properties delete mode 100644 src/sbt-test/sbt-1.5/testkit/project/build.properties rename src/sbt-test/{skip-java17 => skip-java17+}/scalafixResolvers/.env (100%) rename src/sbt-test/{skip-java17 => skip-java17+}/scalafixResolvers/build.sbt (100%) rename src/sbt-test/{skip-java17 => skip-java17+}/scalafixResolvers/project/plugins.sbt (100%) rename src/sbt-test/{skip-java17 => skip-java17+}/scalafixResolvers/test (100%) rename src/sbt-test/{sbt-1.5 => skip-sbt1.4}/cross-build-scala3/.scalafix-2.conf (100%) rename src/sbt-test/{sbt-1.5 => skip-sbt1.4}/cross-build-scala3/.scalafix-3.conf (100%) rename src/sbt-test/{sbt-1.5 => skip-sbt1.4}/cross-build-scala3/build.sbt (100%) rename src/sbt-test/{sbt-1.5 => skip-sbt1.4}/cross-build-scala3/project/plugins.sbt (100%) rename src/sbt-test/{sbt-1.5 => skip-sbt1.4}/cross-build-scala3/src/main/scala-2/Main.scala (100%) rename src/sbt-test/{sbt-1.5 => skip-sbt1.4}/cross-build-scala3/src/main/scala-2/Main.scala.expected (100%) rename src/sbt-test/{sbt-1.5 => skip-sbt1.4}/cross-build-scala3/src/main/scala-3/Main.scala (100%) rename src/sbt-test/{sbt-1.5 => skip-sbt1.4}/cross-build-scala3/src/main/scala-3/Main.scala.expected (100%) rename src/sbt-test/{sbt-1.5 => skip-sbt1.4}/cross-build-scala3/test (100%) create mode 100644 src/sbt-test/skip-sbt1.4/scala-3/build.sbt rename src/sbt-test/{sbt-1.5 => skip-sbt1.4}/scala-3/project/plugins.sbt (100%) rename src/sbt-test/{sbt-1.5 => skip-sbt1.4}/scala-3/src/main/scala/SignificantIndentation.scala (100%) rename src/sbt-test/{sbt-1.5 => skip-sbt1.4}/scala-3/test (100%) rename src/sbt-test/{sbt-1.5 => skip-sbt1.4}/scalafixEnable/build.sbt (89%) rename src/sbt-test/{sbt-1.5 => skip-sbt1.4}/scalafixEnable/project/plugins.sbt (100%) rename src/sbt-test/{sbt-1.5 => skip-sbt1.4}/scalafixEnable/scala210/src/main/scala/Main.scala (100%) rename src/sbt-test/{sbt-1.5 => skip-sbt1.4}/scalafixEnable/scala211/src/main/scala/Main.scala (100%) rename src/sbt-test/{sbt-1.5 => skip-sbt1.4}/scalafixEnable/scala212/src/main/scala/Main.scala (100%) rename src/sbt-test/{sbt-1.5 => skip-sbt1.4}/scalafixEnable/scala3/src/main/scala/SignificantIndentation.scala (100%) rename src/sbt-test/{sbt-1.5 => skip-sbt1.4}/scalafixEnable/test (100%) rename src/sbt-test/{sbt-1.5 => skip-sbt1.4}/testkit/build.sbt (98%) rename src/sbt-test/{sbt-1.5 => skip-sbt1.4}/testkit/input/src/main/scala-2.13/fix/Source3.scala (100%) rename src/sbt-test/{sbt-1.5 => skip-sbt1.4}/testkit/input/src/main/scala/fix/SemanticBasic.scala (100%) rename src/sbt-test/{sbt-1.5 => skip-sbt1.4}/testkit/output/src/main/scala-2.13/fix/Source3.scala (100%) rename src/sbt-test/{sbt-1.5 => skip-sbt1.4}/testkit/output/src/main/scala/fix/SemanticBasic.scala (100%) rename src/sbt-test/{sbt-1.5 => skip-sbt1.4}/testkit/project/TargetAxis.scala (100%) rename src/sbt-test/{sbt-1.5 => skip-sbt1.4}/testkit/project/plugins.sbt (100%) rename src/sbt-test/{sbt-1.5 => skip-sbt1.4}/testkit/rules/src/main/resources/META-INF/services/scalafix.v1.Rule (100%) rename src/sbt-test/{sbt-1.5 => skip-sbt1.4}/testkit/rules/src/main/scala/fix/Semantic.scala (100%) rename src/sbt-test/{sbt-1.5 => skip-sbt1.4}/testkit/test (100%) rename src/sbt-test/{sbt-1.5 => skip-sbt1.4}/testkit/tests/src/test/scala/fix/InputOutputSuite.scala (100%) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5f4218b9..ffade04d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -13,6 +13,7 @@ jobs: - uses: coursier/setup-action@v1 with: jvm: temurin:8 + - run: rm -rf src/sbt-test/skip-sbt1.4 - run: sbt test scripted jdk11: name: JDK11 tests @@ -22,6 +23,7 @@ jobs: - uses: coursier/setup-action@v1 with: jvm: temurin:11 + - run: rm -rf src/sbt-test/skip-sbt1.4 - run: sbt test scripted jdk17: name: JDK17 tests @@ -31,7 +33,10 @@ jobs: - uses: coursier/setup-action@v1 with: jvm: temurin:17 - - run: sbt "test; scripted sbt-*/* skip-windows/*" + - run: rm -rf src/sbt-test/skip-java17+ + - run: rm -rf src/sbt-test/skip-sbt1.4 + - run: sbt test scripted + jdk21: name: JDK21 tests runs-on: ubuntu-latest @@ -40,14 +45,17 @@ jobs: - uses: coursier/setup-action@v1 with: jvm: temurin:21 - - run: sbt "test; scripted sbt-scalafix/* skip-windows/*" + - run: rm -rf src/sbt-test/skip-java17+ + - run: sbt test scripted windows: name: Windows tests runs-on: windows-latest steps: - uses: actions/checkout@v4 - uses: coursier/setup-action@v1 - - run: sbt ci-windows + - run: rm -r -fo src\sbt-test\skip-sbt1.4 + - run: rm -r -fo src\sbt-test\skip-windows + - run: sbt test-skip-windows scripted shell: bash checks: name: Scalafmt diff --git a/build.sbt b/build.sbt index 3b4af4a6..7a4ec6e2 100644 --- a/build.sbt +++ b/build.sbt @@ -31,9 +31,8 @@ developers := List( ) ) -commands += Command.command("ci-windows") { s => +commands += Command.command("test-skip-windows") { s => "testOnly -- -l SkipWindows" :: - "scripted sbt-*/*" :: s } @@ -56,9 +55,7 @@ scriptedSbt := { if (jdk >= 21) "1.9.0" // first release that supports JDK21 else - // https://github.com/sbt/sbt/commit/3b9b200 - // 1.4.[0-2] force batch mode which is not compatible with custom build.properties - "1.4.3" + (pluginCrossBuild / sbtVersion).value } libraryDependencies += compilerPlugin(scalafixSemanticdb) @@ -75,6 +72,8 @@ scalacOptions ++= List( enablePlugins(ScriptedPlugin) sbtPlugin := true scriptedBufferLog := false +scriptedBatchExecution := true +scriptedParallelInstances := 2 scriptedLaunchOpts ++= Seq( "-Xmx2048M", s"-Dplugin.version=${version.value}", diff --git a/src/sbt-test/sbt-1.5/cross-build-scala3/project/build.properties b/src/sbt-test/sbt-1.5/cross-build-scala3/project/build.properties deleted file mode 100644 index e64c208f..00000000 --- a/src/sbt-test/sbt-1.5/cross-build-scala3/project/build.properties +++ /dev/null @@ -1 +0,0 @@ -sbt.version=1.5.8 diff --git a/src/sbt-test/sbt-1.5/scala-3/build.sbt b/src/sbt-test/sbt-1.5/scala-3/build.sbt deleted file mode 100644 index f34bf3c7..00000000 --- a/src/sbt-test/sbt-1.5/scala-3/build.sbt +++ /dev/null @@ -1 +0,0 @@ -scalaVersion := "3.0.0-RC3" diff --git a/src/sbt-test/sbt-1.5/scala-3/project/build.properties b/src/sbt-test/sbt-1.5/scala-3/project/build.properties deleted file mode 100644 index e64c208f..00000000 --- a/src/sbt-test/sbt-1.5/scala-3/project/build.properties +++ /dev/null @@ -1 +0,0 @@ -sbt.version=1.5.8 diff --git a/src/sbt-test/sbt-1.5/scalafixEnable/project/build.properties b/src/sbt-test/sbt-1.5/scalafixEnable/project/build.properties deleted file mode 100644 index e64c208f..00000000 --- a/src/sbt-test/sbt-1.5/scalafixEnable/project/build.properties +++ /dev/null @@ -1 +0,0 @@ -sbt.version=1.5.8 diff --git a/src/sbt-test/sbt-1.5/testkit/project/build.properties b/src/sbt-test/sbt-1.5/testkit/project/build.properties deleted file mode 100644 index e64c208f..00000000 --- a/src/sbt-test/sbt-1.5/testkit/project/build.properties +++ /dev/null @@ -1 +0,0 @@ -sbt.version=1.5.8 diff --git a/src/sbt-test/skip-java17/scalafixResolvers/.env b/src/sbt-test/skip-java17+/scalafixResolvers/.env similarity index 100% rename from src/sbt-test/skip-java17/scalafixResolvers/.env rename to src/sbt-test/skip-java17+/scalafixResolvers/.env diff --git a/src/sbt-test/skip-java17/scalafixResolvers/build.sbt b/src/sbt-test/skip-java17+/scalafixResolvers/build.sbt similarity index 100% rename from src/sbt-test/skip-java17/scalafixResolvers/build.sbt rename to src/sbt-test/skip-java17+/scalafixResolvers/build.sbt diff --git a/src/sbt-test/skip-java17/scalafixResolvers/project/plugins.sbt b/src/sbt-test/skip-java17+/scalafixResolvers/project/plugins.sbt similarity index 100% rename from src/sbt-test/skip-java17/scalafixResolvers/project/plugins.sbt rename to src/sbt-test/skip-java17+/scalafixResolvers/project/plugins.sbt diff --git a/src/sbt-test/skip-java17/scalafixResolvers/test b/src/sbt-test/skip-java17+/scalafixResolvers/test similarity index 100% rename from src/sbt-test/skip-java17/scalafixResolvers/test rename to src/sbt-test/skip-java17+/scalafixResolvers/test diff --git a/src/sbt-test/sbt-1.5/cross-build-scala3/.scalafix-2.conf b/src/sbt-test/skip-sbt1.4/cross-build-scala3/.scalafix-2.conf similarity index 100% rename from src/sbt-test/sbt-1.5/cross-build-scala3/.scalafix-2.conf rename to src/sbt-test/skip-sbt1.4/cross-build-scala3/.scalafix-2.conf diff --git a/src/sbt-test/sbt-1.5/cross-build-scala3/.scalafix-3.conf b/src/sbt-test/skip-sbt1.4/cross-build-scala3/.scalafix-3.conf similarity index 100% rename from src/sbt-test/sbt-1.5/cross-build-scala3/.scalafix-3.conf rename to src/sbt-test/skip-sbt1.4/cross-build-scala3/.scalafix-3.conf diff --git a/src/sbt-test/sbt-1.5/cross-build-scala3/build.sbt b/src/sbt-test/skip-sbt1.4/cross-build-scala3/build.sbt similarity index 100% rename from src/sbt-test/sbt-1.5/cross-build-scala3/build.sbt rename to src/sbt-test/skip-sbt1.4/cross-build-scala3/build.sbt diff --git a/src/sbt-test/sbt-1.5/cross-build-scala3/project/plugins.sbt b/src/sbt-test/skip-sbt1.4/cross-build-scala3/project/plugins.sbt similarity index 100% rename from src/sbt-test/sbt-1.5/cross-build-scala3/project/plugins.sbt rename to src/sbt-test/skip-sbt1.4/cross-build-scala3/project/plugins.sbt diff --git a/src/sbt-test/sbt-1.5/cross-build-scala3/src/main/scala-2/Main.scala b/src/sbt-test/skip-sbt1.4/cross-build-scala3/src/main/scala-2/Main.scala similarity index 100% rename from src/sbt-test/sbt-1.5/cross-build-scala3/src/main/scala-2/Main.scala rename to src/sbt-test/skip-sbt1.4/cross-build-scala3/src/main/scala-2/Main.scala diff --git a/src/sbt-test/sbt-1.5/cross-build-scala3/src/main/scala-2/Main.scala.expected b/src/sbt-test/skip-sbt1.4/cross-build-scala3/src/main/scala-2/Main.scala.expected similarity index 100% rename from src/sbt-test/sbt-1.5/cross-build-scala3/src/main/scala-2/Main.scala.expected rename to src/sbt-test/skip-sbt1.4/cross-build-scala3/src/main/scala-2/Main.scala.expected diff --git a/src/sbt-test/sbt-1.5/cross-build-scala3/src/main/scala-3/Main.scala b/src/sbt-test/skip-sbt1.4/cross-build-scala3/src/main/scala-3/Main.scala similarity index 100% rename from src/sbt-test/sbt-1.5/cross-build-scala3/src/main/scala-3/Main.scala rename to src/sbt-test/skip-sbt1.4/cross-build-scala3/src/main/scala-3/Main.scala diff --git a/src/sbt-test/sbt-1.5/cross-build-scala3/src/main/scala-3/Main.scala.expected b/src/sbt-test/skip-sbt1.4/cross-build-scala3/src/main/scala-3/Main.scala.expected similarity index 100% rename from src/sbt-test/sbt-1.5/cross-build-scala3/src/main/scala-3/Main.scala.expected rename to src/sbt-test/skip-sbt1.4/cross-build-scala3/src/main/scala-3/Main.scala.expected diff --git a/src/sbt-test/sbt-1.5/cross-build-scala3/test b/src/sbt-test/skip-sbt1.4/cross-build-scala3/test similarity index 100% rename from src/sbt-test/sbt-1.5/cross-build-scala3/test rename to src/sbt-test/skip-sbt1.4/cross-build-scala3/test diff --git a/src/sbt-test/skip-sbt1.4/scala-3/build.sbt b/src/sbt-test/skip-sbt1.4/scala-3/build.sbt new file mode 100644 index 00000000..5d620df2 --- /dev/null +++ b/src/sbt-test/skip-sbt1.4/scala-3/build.sbt @@ -0,0 +1 @@ +scalaVersion := "3.3.1" diff --git a/src/sbt-test/sbt-1.5/scala-3/project/plugins.sbt b/src/sbt-test/skip-sbt1.4/scala-3/project/plugins.sbt similarity index 100% rename from src/sbt-test/sbt-1.5/scala-3/project/plugins.sbt rename to src/sbt-test/skip-sbt1.4/scala-3/project/plugins.sbt diff --git a/src/sbt-test/sbt-1.5/scala-3/src/main/scala/SignificantIndentation.scala b/src/sbt-test/skip-sbt1.4/scala-3/src/main/scala/SignificantIndentation.scala similarity index 100% rename from src/sbt-test/sbt-1.5/scala-3/src/main/scala/SignificantIndentation.scala rename to src/sbt-test/skip-sbt1.4/scala-3/src/main/scala/SignificantIndentation.scala diff --git a/src/sbt-test/sbt-1.5/scala-3/test b/src/sbt-test/skip-sbt1.4/scala-3/test similarity index 100% rename from src/sbt-test/sbt-1.5/scala-3/test rename to src/sbt-test/skip-sbt1.4/scala-3/test diff --git a/src/sbt-test/sbt-1.5/scalafixEnable/build.sbt b/src/sbt-test/skip-sbt1.4/scalafixEnable/build.sbt similarity index 89% rename from src/sbt-test/sbt-1.5/scalafixEnable/build.sbt rename to src/sbt-test/skip-sbt1.4/scalafixEnable/build.sbt index 93274b51..020de2d3 100644 --- a/src/sbt-test/sbt-1.5/scalafixEnable/build.sbt +++ b/src/sbt-test/skip-sbt1.4/scalafixEnable/build.sbt @@ -21,5 +21,5 @@ lazy val scala212 = project lazy val scala3 = project .in(file("scala3")) .settings( - scalaVersion := "3.0.0-RC3" // built-in support for semanticdb + scalaVersion := "3.3.1" // built-in support for semanticdb ) diff --git a/src/sbt-test/sbt-1.5/scalafixEnable/project/plugins.sbt b/src/sbt-test/skip-sbt1.4/scalafixEnable/project/plugins.sbt similarity index 100% rename from src/sbt-test/sbt-1.5/scalafixEnable/project/plugins.sbt rename to src/sbt-test/skip-sbt1.4/scalafixEnable/project/plugins.sbt diff --git a/src/sbt-test/sbt-1.5/scalafixEnable/scala210/src/main/scala/Main.scala b/src/sbt-test/skip-sbt1.4/scalafixEnable/scala210/src/main/scala/Main.scala similarity index 100% rename from src/sbt-test/sbt-1.5/scalafixEnable/scala210/src/main/scala/Main.scala rename to src/sbt-test/skip-sbt1.4/scalafixEnable/scala210/src/main/scala/Main.scala diff --git a/src/sbt-test/sbt-1.5/scalafixEnable/scala211/src/main/scala/Main.scala b/src/sbt-test/skip-sbt1.4/scalafixEnable/scala211/src/main/scala/Main.scala similarity index 100% rename from src/sbt-test/sbt-1.5/scalafixEnable/scala211/src/main/scala/Main.scala rename to src/sbt-test/skip-sbt1.4/scalafixEnable/scala211/src/main/scala/Main.scala diff --git a/src/sbt-test/sbt-1.5/scalafixEnable/scala212/src/main/scala/Main.scala b/src/sbt-test/skip-sbt1.4/scalafixEnable/scala212/src/main/scala/Main.scala similarity index 100% rename from src/sbt-test/sbt-1.5/scalafixEnable/scala212/src/main/scala/Main.scala rename to src/sbt-test/skip-sbt1.4/scalafixEnable/scala212/src/main/scala/Main.scala diff --git a/src/sbt-test/sbt-1.5/scalafixEnable/scala3/src/main/scala/SignificantIndentation.scala b/src/sbt-test/skip-sbt1.4/scalafixEnable/scala3/src/main/scala/SignificantIndentation.scala similarity index 100% rename from src/sbt-test/sbt-1.5/scalafixEnable/scala3/src/main/scala/SignificantIndentation.scala rename to src/sbt-test/skip-sbt1.4/scalafixEnable/scala3/src/main/scala/SignificantIndentation.scala diff --git a/src/sbt-test/sbt-1.5/scalafixEnable/test b/src/sbt-test/skip-sbt1.4/scalafixEnable/test similarity index 100% rename from src/sbt-test/sbt-1.5/scalafixEnable/test rename to src/sbt-test/skip-sbt1.4/scalafixEnable/test diff --git a/src/sbt-test/sbt-1.5/testkit/build.sbt b/src/sbt-test/skip-sbt1.4/testkit/build.sbt similarity index 98% rename from src/sbt-test/sbt-1.5/testkit/build.sbt rename to src/sbt-test/skip-sbt1.4/testkit/build.sbt index 0b242a25..e080f726 100644 --- a/src/sbt-test/sbt-1.5/testkit/build.sbt +++ b/src/sbt-test/skip-sbt1.4/testkit/build.sbt @@ -1,7 +1,7 @@ lazy val V = _root_.scalafix.sbt.BuildInfo lazy val rulesCrossVersions = Seq(V.scala213, V.scala212) -lazy val scala3Version = "3.0.0" +lazy val scala3Version = "3.3.1" inThisBuild( List( diff --git a/src/sbt-test/sbt-1.5/testkit/input/src/main/scala-2.13/fix/Source3.scala b/src/sbt-test/skip-sbt1.4/testkit/input/src/main/scala-2.13/fix/Source3.scala similarity index 100% rename from src/sbt-test/sbt-1.5/testkit/input/src/main/scala-2.13/fix/Source3.scala rename to src/sbt-test/skip-sbt1.4/testkit/input/src/main/scala-2.13/fix/Source3.scala diff --git a/src/sbt-test/sbt-1.5/testkit/input/src/main/scala/fix/SemanticBasic.scala b/src/sbt-test/skip-sbt1.4/testkit/input/src/main/scala/fix/SemanticBasic.scala similarity index 100% rename from src/sbt-test/sbt-1.5/testkit/input/src/main/scala/fix/SemanticBasic.scala rename to src/sbt-test/skip-sbt1.4/testkit/input/src/main/scala/fix/SemanticBasic.scala diff --git a/src/sbt-test/sbt-1.5/testkit/output/src/main/scala-2.13/fix/Source3.scala b/src/sbt-test/skip-sbt1.4/testkit/output/src/main/scala-2.13/fix/Source3.scala similarity index 100% rename from src/sbt-test/sbt-1.5/testkit/output/src/main/scala-2.13/fix/Source3.scala rename to src/sbt-test/skip-sbt1.4/testkit/output/src/main/scala-2.13/fix/Source3.scala diff --git a/src/sbt-test/sbt-1.5/testkit/output/src/main/scala/fix/SemanticBasic.scala b/src/sbt-test/skip-sbt1.4/testkit/output/src/main/scala/fix/SemanticBasic.scala similarity index 100% rename from src/sbt-test/sbt-1.5/testkit/output/src/main/scala/fix/SemanticBasic.scala rename to src/sbt-test/skip-sbt1.4/testkit/output/src/main/scala/fix/SemanticBasic.scala diff --git a/src/sbt-test/sbt-1.5/testkit/project/TargetAxis.scala b/src/sbt-test/skip-sbt1.4/testkit/project/TargetAxis.scala similarity index 100% rename from src/sbt-test/sbt-1.5/testkit/project/TargetAxis.scala rename to src/sbt-test/skip-sbt1.4/testkit/project/TargetAxis.scala diff --git a/src/sbt-test/sbt-1.5/testkit/project/plugins.sbt b/src/sbt-test/skip-sbt1.4/testkit/project/plugins.sbt similarity index 100% rename from src/sbt-test/sbt-1.5/testkit/project/plugins.sbt rename to src/sbt-test/skip-sbt1.4/testkit/project/plugins.sbt diff --git a/src/sbt-test/sbt-1.5/testkit/rules/src/main/resources/META-INF/services/scalafix.v1.Rule b/src/sbt-test/skip-sbt1.4/testkit/rules/src/main/resources/META-INF/services/scalafix.v1.Rule similarity index 100% rename from src/sbt-test/sbt-1.5/testkit/rules/src/main/resources/META-INF/services/scalafix.v1.Rule rename to src/sbt-test/skip-sbt1.4/testkit/rules/src/main/resources/META-INF/services/scalafix.v1.Rule diff --git a/src/sbt-test/sbt-1.5/testkit/rules/src/main/scala/fix/Semantic.scala b/src/sbt-test/skip-sbt1.4/testkit/rules/src/main/scala/fix/Semantic.scala similarity index 100% rename from src/sbt-test/sbt-1.5/testkit/rules/src/main/scala/fix/Semantic.scala rename to src/sbt-test/skip-sbt1.4/testkit/rules/src/main/scala/fix/Semantic.scala diff --git a/src/sbt-test/sbt-1.5/testkit/test b/src/sbt-test/skip-sbt1.4/testkit/test similarity index 100% rename from src/sbt-test/sbt-1.5/testkit/test rename to src/sbt-test/skip-sbt1.4/testkit/test diff --git a/src/sbt-test/sbt-1.5/testkit/tests/src/test/scala/fix/InputOutputSuite.scala b/src/sbt-test/skip-sbt1.4/testkit/tests/src/test/scala/fix/InputOutputSuite.scala similarity index 100% rename from src/sbt-test/sbt-1.5/testkit/tests/src/test/scala/fix/InputOutputSuite.scala rename to src/sbt-test/skip-sbt1.4/testkit/tests/src/test/scala/fix/InputOutputSuite.scala From eacd7ccc54abaa36ccc475286f7c095d0cd67506 Mon Sep 17 00:00:00 2001 From: Brice Jaglin Date: Fri, 27 Sep 2024 23:32:27 +0200 Subject: [PATCH 077/129] scalafix 0.13.0 --- project/Dependencies.scala | 2 +- .../scala/scalafix/internal/sbt/SbtCompletionsSuite.scala | 4 ++-- src/test/scala/scalafix/internal/sbt/ScalafixAPISuite.scala | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/project/Dependencies.scala b/project/Dependencies.scala index 1145abce..593cc7e6 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -2,7 +2,7 @@ import sbt._ object Dependencies { val x = List(1) // scalafix:ok - def scalafixVersion: String = "0.12.1+81-c6766833-SNAPSHOT" + def scalafixVersion: String = "0.13.0" val all = List( "org.eclipse.jgit" % "org.eclipse.jgit" % "5.13.3.202401111512-r", diff --git a/src/test/scala/scalafix/internal/sbt/SbtCompletionsSuite.scala b/src/test/scala/scalafix/internal/sbt/SbtCompletionsSuite.scala index 3f3d70da..4cd7e2e9 100644 --- a/src/test/scala/scalafix/internal/sbt/SbtCompletionsSuite.scala +++ b/src/test/scala/scalafix/internal/sbt/SbtCompletionsSuite.scala @@ -115,7 +115,7 @@ class SbtCompletionsSuite extends AnyFunSuite { |DisableSyntax | Reports an error for disabled features such as var or XML literals. |ExplicitResultTypes - | Inserts type annotations for inferred public members. Only compatible with Scala 2.x. + | Inserts type annotations for inferred public members. |LeakingImplicitClassVal | Adds 'private' to val parameters of implicit value classes |NoAutoTupling @@ -125,7 +125,7 @@ class SbtCompletionsSuite extends AnyFunSuite { |OrganizeImports | Organize import statements |ProcedureSyntax - | Replaces deprecated procedure syntax with explicit ': Unit =' + | Replaces deprecated Scala 2.x procedure syntax with explicit ': Unit =' |RedundantSyntax | Removes redundant syntax such as `final` modifiers on an object |RemoveUnused diff --git a/src/test/scala/scalafix/internal/sbt/ScalafixAPISuite.scala b/src/test/scala/scalafix/internal/sbt/ScalafixAPISuite.scala index c3a55508..21542cf7 100644 --- a/src/test/scala/scalafix/internal/sbt/ScalafixAPISuite.scala +++ b/src/test/scala/scalafix/internal/sbt/ScalafixAPISuite.scala @@ -36,7 +36,7 @@ class ScalafixAPISuite extends AnyFunSuite { "2.12", Arg.ToolClasspath( Nil, - List("ch.epfl.scala" %% "example-scalafix-rule" % "4.0.0"), + List("ch.epfl.scala" %% "example-scalafix-rule" % "5.0.0"), Seq( Repository.central, MavenRepository.of( From 8f27d868baacc22816da0fa81ab13bff8ac38aae Mon Sep 17 00:00:00 2001 From: Brice Jaglin Date: Sun, 29 Sep 2024 23:57:47 +0200 Subject: [PATCH 078/129] fix Scala 2.11 detection & use same instance across patch releases --- src/main/scala/scalafix/sbt/ScalafixPlugin.scala | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/main/scala/scalafix/sbt/ScalafixPlugin.scala b/src/main/scala/scalafix/sbt/ScalafixPlugin.scala index 9a04919e..6d4bf75b 100644 --- a/src/main/scala/scalafix/sbt/ScalafixPlugin.scala +++ b/src/main/scala/scalafix/sbt/ScalafixPlugin.scala @@ -265,7 +265,8 @@ object ScalafixPlugin extends AutoPlugin { }, ivyConfigurations += ScalafixConfig, scalafixAll := scalafixAllInputTask.evaluated, - (scalafixScalaBinaryVersion: @nowarn) := scalaVersion.value + (scalafixScalaBinaryVersion: @nowarn) := + scalaVersion.value.split('.').take(2).mkString(".") ) override lazy val globalSettings: Seq[Def.Setting[_]] = Seq( @@ -363,7 +364,7 @@ object ScalafixPlugin extends AutoPlugin { val interface = ScalafixInterface( cache = buildScalafixInterfaceCache, - scalafixScalaBinaryVersion = projectScalafixScalaBinaryVersion, + scalafixScalaMajorMinorVersion = projectScalafixScalaBinaryVersion, toolClasspath = toolClasspath, logger = ScalafixInterface.defaultLogger, callback = buildScalafixMainCallback From 2cf21cefddb5c07104ef4a8f485088411b78c8c2 Mon Sep 17 00:00:00 2001 From: Brice Jaglin Date: Mon, 30 Sep 2024 00:08:17 +0200 Subject: [PATCH 079/129] reflect what is actually provided as argument --- .../scalafix/internal/sbt/ScalafixInterface.scala | 12 ++++++------ src/main/scala/scalafix/sbt/ScalafixPlugin.scala | 4 ++-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/main/scala/scalafix/internal/sbt/ScalafixInterface.scala b/src/main/scala/scalafix/internal/sbt/ScalafixInterface.scala index cee229ea..57a27c8a 100644 --- a/src/main/scala/scalafix/internal/sbt/ScalafixInterface.scala +++ b/src/main/scala/scalafix/internal/sbt/ScalafixInterface.scala @@ -126,7 +126,7 @@ object ScalafixInterface { type Cache = BlockingCache[ ( - String, // scalafixScalaBinaryVersion + String, // scalafixScalaMajorMinorVersion Option[Arg.ToolClasspath] ), ( @@ -139,7 +139,7 @@ object ScalafixInterface { def apply( cache: Cache, - scalafixScalaBinaryVersion: String, + scalafixScalaMajorMinorVersion: String, toolClasspath: Arg.ToolClasspath, logger: Logger, callback: ScalafixMainCallback @@ -150,7 +150,7 @@ object ScalafixInterface { // shared as much as possible. val (buildinRulesInterface, _) = cache.compute( ( - scalafixScalaBinaryVersion, + scalafixScalaMajorMinorVersion, None ), { @@ -159,14 +159,14 @@ object ScalafixInterface { None case None => // cache miss, resolve scalafix artifacts and classload them - if (scalafixScalaBinaryVersion == "2.11") + if (scalafixScalaMajorMinorVersion == "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 scalafixArguments = ScalafixAPI .fetchAndClassloadInstance( - scalafixScalaBinaryVersion, + scalafixScalaMajorMinorVersion, toolClasspath.repositories.asJava ) .newArguments() @@ -197,7 +197,7 @@ object ScalafixInterface { val (toolClasspathInterface, _) = cache.compute( ( - scalafixScalaBinaryVersion, + scalafixScalaMajorMinorVersion, Some(toolClasspath) ), { diff --git a/src/main/scala/scalafix/sbt/ScalafixPlugin.scala b/src/main/scala/scalafix/sbt/ScalafixPlugin.scala index 6d4bf75b..efd6d978 100644 --- a/src/main/scala/scalafix/sbt/ScalafixPlugin.scala +++ b/src/main/scala/scalafix/sbt/ScalafixPlugin.scala @@ -327,7 +327,7 @@ object ScalafixPlugin extends AutoPlugin { shell: ShellArgs, projectDepsExternal: Seq[ModuleID], projectDepsInternal: Seq[File], - projectScalafixScalaBinaryVersion: String, + projectScalaMajorMinorVersion: String, projectScalafixDependencies: Seq[ModuleID], buildAllResolvers: Seq[Repository], buildScalafixMainCallback: ScalafixMainCallback, @@ -364,7 +364,7 @@ object ScalafixPlugin extends AutoPlugin { val interface = ScalafixInterface( cache = buildScalafixInterfaceCache, - scalafixScalaMajorMinorVersion = projectScalafixScalaBinaryVersion, + scalafixScalaMajorMinorVersion = projectScalaMajorMinorVersion, toolClasspath = toolClasspath, logger = ScalafixInterface.defaultLogger, callback = buildScalafixMainCallback From 41fd054823b1f9d59d8647c7a0697962316ea6a0 Mon Sep 17 00:00:00 2001 From: "scala-center-steward[bot]" <111975575+scala-center-steward[bot]@users.noreply.github.com> Date: Tue, 1 Oct 2024 00:23:38 +0000 Subject: [PATCH 080/129] Update interface to 1.0.21 --- project/Dependencies.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project/Dependencies.scala b/project/Dependencies.scala index 593cc7e6..85d08c4d 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -7,6 +7,6 @@ object Dependencies { val all = List( "org.eclipse.jgit" % "org.eclipse.jgit" % "5.13.3.202401111512-r", "ch.epfl.scala" % "scalafix-interfaces" % scalafixVersion, - "io.get-coursier" % "interface" % "1.0.20" + "io.get-coursier" % "interface" % "1.0.21" ) } From 29910a94c7b59f998926ab81bb00c01b22bae943 Mon Sep 17 00:00:00 2001 From: "scala-center-steward[bot]" <111975575+scala-center-steward[bot]@users.noreply.github.com> Date: Tue, 1 Oct 2024 00:24:42 +0000 Subject: [PATCH 081/129] Update sbt, scripted-plugin to 1.10.2 --- project/build.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project/build.properties b/project/build.properties index ee4c672c..0b699c30 100644 --- a/project/build.properties +++ b/project/build.properties @@ -1 +1 @@ -sbt.version=1.10.1 +sbt.version=1.10.2 From 847ce8399fe06b265ecaf14641cf8ff0b53aea89 Mon Sep 17 00:00:00 2001 From: Brice Jaglin Date: Fri, 4 Oct 2024 09:28:21 +0200 Subject: [PATCH 082/129] allow eviction of cached Scalafix instances Scalafix instances can be memory-consuming (PrintStream's static 8k BufferedWriter allocations are wasteful and hard to remove for example), so this allow eviction in case of memory pressure. To compensate for the added complexity, the implementation was simplified. * Values are now always updated (even if they haven't changed). This probably does not change much performance-wise, as we are trading throwing an exception (costly) against a SoftReference instanciation and the update in the low-cardinality ConcurrentHashMap. * SAM conversion is used now that sbt 0.13 / Scala 2.11 are no longer supported. --- .../scalafix/internal/sbt/BlockingCache.scala | 36 ++++++++----------- .../internal/sbt/ScalafixInterface.scala | 24 ++++++------- 2 files changed, 25 insertions(+), 35 deletions(-) diff --git a/src/main/scala/scalafix/internal/sbt/BlockingCache.scala b/src/main/scala/scalafix/internal/sbt/BlockingCache.scala index d1d4546e..4edba496 100644 --- a/src/main/scala/scalafix/internal/sbt/BlockingCache.scala +++ b/src/main/scala/scalafix/internal/sbt/BlockingCache.scala @@ -2,32 +2,26 @@ package scalafix.internal.sbt import java.{util => ju} -import scala.util.Try +import java.lang.ref.SoftReference -/** A basic thread-safe cache without any eviction. */ +/** A basic thread-safe cache with arbitrary eviction on GC pressure. */ class BlockingCache[K, V] { - private val underlying = new ju.concurrent.ConcurrentHashMap[K, V] - - private case class SkipUpdate(prev: V) extends Exception + private val underlying = + new ju.concurrent.ConcurrentHashMap[K, SoftReference[V]] // Evaluations of `transform` are guaranteed to be sequential for the same key - def compute(key: K, transform: Option[V] => Option[V]): V = { - Try( - underlying.compute( - key, - new ju.function.BiFunction[K, V, V] { - override def apply(key: K, prev: V): V = { - transform(Option(prev)).getOrElse(throw SkipUpdate(prev)) - } - } - ) - ).fold( - { - case SkipUpdate(prev) => prev - case ex => throw ex - }, - identity + def compute(key: K, transform: Option[V] => V): V = { + // keep the result in a strong reference to avoid eviction + // just after executing wrapped compute() + var result: V = null.asInstanceOf[V] + underlying.compute( + key, + (_, prev: SoftReference[V]) => { + result = transform(Option(prev).flatMap(ref => Option(ref.get))) + new SoftReference(result) + } ) + result } } diff --git a/src/main/scala/scalafix/internal/sbt/ScalafixInterface.scala b/src/main/scala/scalafix/internal/sbt/ScalafixInterface.scala index 57a27c8a..f2ed4605 100644 --- a/src/main/scala/scalafix/internal/sbt/ScalafixInterface.scala +++ b/src/main/scala/scalafix/internal/sbt/ScalafixInterface.scala @@ -154,9 +154,9 @@ object ScalafixInterface { None ), { - case Some(_) => + case Some(v) => // cache hit, don't update - None + v case None => // cache miss, resolve scalafix artifacts and classload them if (scalafixScalaMajorMinorVersion == "2.11") @@ -181,11 +181,9 @@ object ScalafixInterface { ) ) - Some( - ( - new ScalafixInterface(scalafixArguments).withArgs(printStream), - Nil - ) + ( + new ScalafixInterface(scalafixArguments).withArgs(printStream), + Nil ) } ) @@ -201,16 +199,14 @@ object ScalafixInterface { Some(toolClasspath) ), { - case Some((_, oldStamps)) if (currentStamps == oldStamps) => + case Some(v @ (_, oldStamps)) if (currentStamps == oldStamps) => // cache hit, don't update - None + v case _ => // cache miss or stale stamps, resolve custom rules artifacts and classload them - Some( - ( - buildinRulesInterface.withArgs(toolClasspath), - currentStamps - ) + ( + buildinRulesInterface.withArgs(toolClasspath), + currentStamps ) } ) From 2d87f9973a484e8f8915a97007985573eaf63bf0 Mon Sep 17 00:00:00 2001 From: "scala-center-steward[bot]" <111975575+scala-center-steward[bot]@users.noreply.github.com> Date: Tue, 15 Oct 2024 00:21:42 +0000 Subject: [PATCH 083/129] Update sbt-ci-release to 1.8.0 --- project/plugins.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project/plugins.sbt b/project/plugins.sbt index d205d7a6..0963224d 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -1,5 +1,5 @@ resolvers ++= Resolver.sonatypeOssRepos("public") -addSbtPlugin("com.github.sbt" % "sbt-ci-release" % "1.6.1") +addSbtPlugin("com.github.sbt" % "sbt-ci-release" % "1.8.0") libraryDependencies += "org.scala-sbt" %% "scripted-plugin" % sbtVersion.value Compile / unmanagedSourceDirectories ++= { From 2fe9ad4a5d289b40c54bb58915d6501676242199 Mon Sep 17 00:00:00 2001 From: "scala-center-steward[bot]" <111975575+scala-center-steward[bot]@users.noreply.github.com> Date: Fri, 1 Nov 2024 00:21:54 +0000 Subject: [PATCH 084/129] Update sbt-ci-release to 1.9.0 --- project/plugins.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project/plugins.sbt b/project/plugins.sbt index 0963224d..adbea496 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -1,5 +1,5 @@ resolvers ++= Resolver.sonatypeOssRepos("public") -addSbtPlugin("com.github.sbt" % "sbt-ci-release" % "1.8.0") +addSbtPlugin("com.github.sbt" % "sbt-ci-release" % "1.9.0") libraryDependencies += "org.scala-sbt" %% "scripted-plugin" % sbtVersion.value Compile / unmanagedSourceDirectories ++= { From 5314c85822e847779346e46d85aa1b53eaae61d7 Mon Sep 17 00:00:00 2001 From: "scala-center-steward[bot]" <111975575+scala-center-steward[bot]@users.noreply.github.com> Date: Fri, 1 Nov 2024 00:22:03 +0000 Subject: [PATCH 085/129] Update interface to 1.0.22 --- project/Dependencies.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project/Dependencies.scala b/project/Dependencies.scala index 85d08c4d..a1a2bb9c 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -7,6 +7,6 @@ object Dependencies { val all = List( "org.eclipse.jgit" % "org.eclipse.jgit" % "5.13.3.202401111512-r", "ch.epfl.scala" % "scalafix-interfaces" % scalafixVersion, - "io.get-coursier" % "interface" % "1.0.21" + "io.get-coursier" % "interface" % "1.0.22" ) } From 6e2575b4dfbf931f53652d69217c18f89ba67d72 Mon Sep 17 00:00:00 2001 From: "scala-center-steward[bot]" <111975575+scala-center-steward[bot]@users.noreply.github.com> Date: Fri, 1 Nov 2024 00:22:11 +0000 Subject: [PATCH 086/129] Update sbt, scripted-plugin to 1.10.4 --- project/build.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project/build.properties b/project/build.properties index 0b699c30..09feeeed 100644 --- a/project/build.properties +++ b/project/build.properties @@ -1 +1 @@ -sbt.version=1.10.2 +sbt.version=1.10.4 From 2dbe93c6546dd17ac7d06482b640b9b94ef42bb9 Mon Sep 17 00:00:00 2001 From: "scala-center-steward[bot]" <111975575+scala-center-steward[bot]@users.noreply.github.com> Date: Fri, 15 Nov 2024 00:22:02 +0000 Subject: [PATCH 087/129] Update interface to 1.0.23 --- project/Dependencies.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project/Dependencies.scala b/project/Dependencies.scala index a1a2bb9c..8f7b78ac 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -7,6 +7,6 @@ object Dependencies { val all = List( "org.eclipse.jgit" % "org.eclipse.jgit" % "5.13.3.202401111512-r", "ch.epfl.scala" % "scalafix-interfaces" % scalafixVersion, - "io.get-coursier" % "interface" % "1.0.22" + "io.get-coursier" % "interface" % "1.0.23" ) } From 06729c1f7cf4def0f6f723ec83a7c917c0c6b2bd Mon Sep 17 00:00:00 2001 From: "scala-center-steward[bot]" <111975575+scala-center-steward[bot]@users.noreply.github.com> Date: Fri, 15 Nov 2024 00:22:09 +0000 Subject: [PATCH 088/129] Update sbt, scripted-plugin to 1.10.5 --- project/build.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project/build.properties b/project/build.properties index 09feeeed..db1723b0 100644 --- a/project/build.properties +++ b/project/build.properties @@ -1 +1 @@ -sbt.version=1.10.4 +sbt.version=1.10.5 From 22a9fc385c1ac048a26e84873ae1f5a01a7618ec Mon Sep 17 00:00:00 2001 From: "scala-center-steward[bot]" <111975575+scala-center-steward[bot]@users.noreply.github.com> Date: Sun, 1 Dec 2024 00:25:31 +0000 Subject: [PATCH 089/129] Update interface to 1.0.25 --- project/Dependencies.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project/Dependencies.scala b/project/Dependencies.scala index 8f7b78ac..d7bcb0de 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -7,6 +7,6 @@ object Dependencies { val all = List( "org.eclipse.jgit" % "org.eclipse.jgit" % "5.13.3.202401111512-r", "ch.epfl.scala" % "scalafix-interfaces" % scalafixVersion, - "io.get-coursier" % "interface" % "1.0.23" + "io.get-coursier" % "interface" % "1.0.25" ) } From 995d694a06941ac07b5b0be9c6ab41cb5c26f49e Mon Sep 17 00:00:00 2001 From: "scala-center-steward[bot]" <111975575+scala-center-steward[bot]@users.noreply.github.com> Date: Sun, 1 Dec 2024 00:25:37 +0000 Subject: [PATCH 090/129] Update sbt, scripted-plugin to 1.10.6 --- project/build.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project/build.properties b/project/build.properties index db1723b0..e88a0d81 100644 --- a/project/build.properties +++ b/project/build.properties @@ -1 +1 @@ -sbt.version=1.10.5 +sbt.version=1.10.6 From efa9500aa3d95a96706dd2e00e9a529b7fd7cd31 Mon Sep 17 00:00:00 2001 From: "scala-center-steward[bot]" <111975575+scala-center-steward[bot]@users.noreply.github.com> Date: Sun, 15 Dec 2024 00:23:17 +0000 Subject: [PATCH 091/129] Update interface to 1.0.26 --- project/Dependencies.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project/Dependencies.scala b/project/Dependencies.scala index d7bcb0de..90c0f3bb 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -7,6 +7,6 @@ object Dependencies { val all = List( "org.eclipse.jgit" % "org.eclipse.jgit" % "5.13.3.202401111512-r", "ch.epfl.scala" % "scalafix-interfaces" % scalafixVersion, - "io.get-coursier" % "interface" % "1.0.25" + "io.get-coursier" % "interface" % "1.0.26" ) } From ece95244704926cc6ba3322bcd2e3d3e1c0ba709 Mon Sep 17 00:00:00 2001 From: "scala-center-steward[bot]" <111975575+scala-center-steward[bot]@users.noreply.github.com> Date: Wed, 1 Jan 2025 00:29:46 +0000 Subject: [PATCH 092/129] Update sbt-ci-release to 1.9.2 --- project/plugins.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project/plugins.sbt b/project/plugins.sbt index adbea496..b5a62e80 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -1,5 +1,5 @@ resolvers ++= Resolver.sonatypeOssRepos("public") -addSbtPlugin("com.github.sbt" % "sbt-ci-release" % "1.9.0") +addSbtPlugin("com.github.sbt" % "sbt-ci-release" % "1.9.2") libraryDependencies += "org.scala-sbt" %% "scripted-plugin" % sbtVersion.value Compile / unmanagedSourceDirectories ++= { From 93a467f15a4d9a27f4e39f4a8846432817b546eb Mon Sep 17 00:00:00 2001 From: "scala-center-steward[bot]" <111975575+scala-center-steward[bot]@users.noreply.github.com> Date: Wed, 1 Jan 2025 00:29:53 +0000 Subject: [PATCH 093/129] Update sbt, scripted-plugin to 1.10.7 --- project/build.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project/build.properties b/project/build.properties index e88a0d81..73df629a 100644 --- a/project/build.properties +++ b/project/build.properties @@ -1 +1 @@ -sbt.version=1.10.6 +sbt.version=1.10.7 From 94797d415a1f3c56bdd93d0696f99b6c78fae653 Mon Sep 17 00:00:00 2001 From: Brice Jaglin Date: Sat, 11 Jan 2025 21:38:06 +0100 Subject: [PATCH 094/129] ubuntu-latest now points to 24.04 which does not include sbt --- .github/workflows/ci.yml | 4 ++++ .github/workflows/release.yml | 1 + 2 files changed, 5 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ffade04d..0137a2c9 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -13,6 +13,7 @@ jobs: - uses: coursier/setup-action@v1 with: jvm: temurin:8 + - uses: sbt/setup-sbt@v1 - run: rm -rf src/sbt-test/skip-sbt1.4 - run: sbt test scripted jdk11: @@ -23,6 +24,7 @@ jobs: - uses: coursier/setup-action@v1 with: jvm: temurin:11 + - uses: sbt/setup-sbt@v1 - run: rm -rf src/sbt-test/skip-sbt1.4 - run: sbt test scripted jdk17: @@ -33,6 +35,7 @@ jobs: - uses: coursier/setup-action@v1 with: jvm: temurin:17 + - uses: sbt/setup-sbt@v1 - run: rm -rf src/sbt-test/skip-java17+ - run: rm -rf src/sbt-test/skip-sbt1.4 - run: sbt test scripted @@ -45,6 +48,7 @@ jobs: - uses: coursier/setup-action@v1 with: jvm: temurin:21 + - uses: sbt/setup-sbt@v1 - run: rm -rf src/sbt-test/skip-java17+ - run: sbt test scripted windows: diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index bddb3aef..e72af714 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -9,6 +9,7 @@ jobs: steps: - uses: actions/checkout@v4 - uses: coursier/setup-action@v1 + - uses: sbt/setup-sbt@v1 - uses: olafurpg/setup-gpg@v3 - run: git fetch --unshallow - name: Publish ${{ github.ref }} From a878592de81729a10e03952015415b4248425ad8 Mon Sep 17 00:00:00 2001 From: Brice Jaglin Date: Sat, 11 Jan 2025 21:29:13 +0100 Subject: [PATCH 095/129] test current scalafix against 2.13.16 sources --- src/sbt-test/sbt-scalafix/semanticdb-enabled/build.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sbt-test/sbt-scalafix/semanticdb-enabled/build.sbt b/src/sbt-test/sbt-scalafix/semanticdb-enabled/build.sbt index c05f6321..f69b5af6 100644 --- a/src/sbt-test/sbt-scalafix/semanticdb-enabled/build.sbt +++ b/src/sbt-test/sbt-scalafix/semanticdb-enabled/build.sbt @@ -10,6 +10,6 @@ lazy val scala212 = project lazy val scala213 = project .settings( - scalaVersion := "2.13.15", + scalaVersion := "2.13.16", scalacOptions += "-Wunused" ) From 8c27559bf87aaa99efb7c570241d499ab7c963ab Mon Sep 17 00:00:00 2001 From: Brice Jaglin Date: Sat, 11 Jan 2025 21:30:22 +0100 Subject: [PATCH 096/129] sbt 1.3.x is no longer tested/supported --- src/sbt-test/sbt-scalafix/explicit-files/build.sbt | 3 +-- src/sbt-test/sbt-scalafix/semanticdb-enabled/build.sbt | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/sbt-test/sbt-scalafix/explicit-files/build.sbt b/src/sbt-test/sbt-scalafix/explicit-files/build.sbt index 4cd1d044..541217e3 100644 --- a/src/sbt-test/sbt-scalafix/explicit-files/build.sbt +++ b/src/sbt-test/sbt-scalafix/explicit-files/build.sbt @@ -1,7 +1,6 @@ import _root_.scalafix.sbt.{BuildInfo => Versions} -// support sbt 1.3.x, see https://github.com/sbt/sbt/issues/5110 -Global / semanticdbVersion := scalafixSemanticdb.revision +ThisBuild / semanticdbVersion := scalafixSemanticdb.revision inThisBuild( List( diff --git a/src/sbt-test/sbt-scalafix/semanticdb-enabled/build.sbt b/src/sbt-test/sbt-scalafix/semanticdb-enabled/build.sbt index f69b5af6..55f558cc 100644 --- a/src/sbt-test/sbt-scalafix/semanticdb-enabled/build.sbt +++ b/src/sbt-test/sbt-scalafix/semanticdb-enabled/build.sbt @@ -1,5 +1,4 @@ -// support sbt 1.3.x, see https://github.com/sbt/sbt/issues/5110 -Global / semanticdbVersion := scalafixSemanticdb.revision +ThisBuild / semanticdbVersion := scalafixSemanticdb.revision ThisBuild / semanticdbEnabled := true lazy val scala212 = project From b3704d2666fe9b26a62b7cfc9fb5618ff7b66334 Mon Sep 17 00:00:00 2001 From: Brice Jaglin Date: Sat, 11 Jan 2025 23:44:42 +0100 Subject: [PATCH 097/129] coursier/setup-action can bring sbt --- .github/workflows/ci.yml | 10 ++++++---- .github/workflows/release.yml | 3 ++- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 0137a2c9..ef13744d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -12,8 +12,8 @@ jobs: - uses: actions/checkout@v4 - uses: coursier/setup-action@v1 with: + apps: sbt jvm: temurin:8 - - uses: sbt/setup-sbt@v1 - run: rm -rf src/sbt-test/skip-sbt1.4 - run: sbt test scripted jdk11: @@ -23,8 +23,8 @@ jobs: - uses: actions/checkout@v4 - uses: coursier/setup-action@v1 with: + apps: sbt jvm: temurin:11 - - uses: sbt/setup-sbt@v1 - run: rm -rf src/sbt-test/skip-sbt1.4 - run: sbt test scripted jdk17: @@ -34,8 +34,8 @@ jobs: - uses: actions/checkout@v4 - uses: coursier/setup-action@v1 with: + apps: sbt jvm: temurin:17 - - uses: sbt/setup-sbt@v1 - run: rm -rf src/sbt-test/skip-java17+ - run: rm -rf src/sbt-test/skip-sbt1.4 - run: sbt test scripted @@ -47,8 +47,8 @@ jobs: - uses: actions/checkout@v4 - uses: coursier/setup-action@v1 with: + apps: sbt jvm: temurin:21 - - uses: sbt/setup-sbt@v1 - run: rm -rf src/sbt-test/skip-java17+ - run: sbt test scripted windows: @@ -57,6 +57,8 @@ jobs: steps: - uses: actions/checkout@v4 - uses: coursier/setup-action@v1 + with: + apps: sbt - run: rm -r -fo src\sbt-test\skip-sbt1.4 - run: rm -r -fo src\sbt-test\skip-windows - run: sbt test-skip-windows scripted diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index e72af714..e9f0a318 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -9,7 +9,8 @@ jobs: steps: - uses: actions/checkout@v4 - uses: coursier/setup-action@v1 - - uses: sbt/setup-sbt@v1 + with: + apps: sbt - uses: olafurpg/setup-gpg@v3 - run: git fetch --unshallow - name: Publish ${{ github.ref }} From e21e999935e00e139f6c0c12cdbf31dc524c9b45 Mon Sep 17 00:00:00 2001 From: Brice Jaglin Date: Sat, 11 Jan 2025 23:58:00 +0100 Subject: [PATCH 098/129] make sure sbt-scalafix is published with JDK8 bytecode https://github.com/coursier/coursier/blob/976dd72/modules/jvm/src/main/scala/coursier/jvm/JavaHome.scala#L178-L179 Current coursier default is adoptium:11, so this protects any potential regression in case "-target:jvm-1.8" is removed somehow fom the build. --- .github/workflows/release.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index e9f0a318..e5affc43 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -11,6 +11,7 @@ jobs: - uses: coursier/setup-action@v1 with: apps: sbt + jvm: temurin:8 - uses: olafurpg/setup-gpg@v3 - run: git fetch --unshallow - name: Publish ${{ github.ref }} From 78df5713545bdc1906bab56d1f36c16f0d0949bd Mon Sep 17 00:00:00 2001 From: Brice Jaglin Date: Sun, 12 Jan 2025 19:17:37 +0100 Subject: [PATCH 099/129] scalafix 0.14.0 --- project/Dependencies.scala | 2 +- src/test/scala/scalafix/internal/sbt/ScalafixAPISuite.scala | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/project/Dependencies.scala b/project/Dependencies.scala index 90c0f3bb..eabc84fa 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -2,7 +2,7 @@ import sbt._ object Dependencies { val x = List(1) // scalafix:ok - def scalafixVersion: String = "0.13.0" + def scalafixVersion: String = "0.14.0" val all = List( "org.eclipse.jgit" % "org.eclipse.jgit" % "5.13.3.202401111512-r", diff --git a/src/test/scala/scalafix/internal/sbt/ScalafixAPISuite.scala b/src/test/scala/scalafix/internal/sbt/ScalafixAPISuite.scala index 21542cf7..b8742cd0 100644 --- a/src/test/scala/scalafix/internal/sbt/ScalafixAPISuite.scala +++ b/src/test/scala/scalafix/internal/sbt/ScalafixAPISuite.scala @@ -36,7 +36,7 @@ class ScalafixAPISuite extends AnyFunSuite { "2.12", Arg.ToolClasspath( Nil, - List("ch.epfl.scala" %% "example-scalafix-rule" % "5.0.0"), + List("ch.epfl.scala" %% "example-scalafix-rule" % "6.0.0"), Seq( Repository.central, MavenRepository.of( From 511df3cc02ea0e640ad322b629cd2cbe18e02cd1 Mon Sep 17 00:00:00 2001 From: Brice Jaglin Date: Wed, 15 Jan 2025 00:00:34 +0100 Subject: [PATCH 100/129] dirty hack to support non-canonical scalameta version tag On sbt 1.4.0, this prevents "java.lang.IllegalArgumentException: Invalid comparator: >4.12.4.1". On recent sbt versions, "4.12.4.1" is supported, but not parsed the way one would expect, so it's safer to take out the last digit explicitly in all cases, since the intent of that pattern was to indicate that this should be used over 4.12.4. https://github.com/sbt/librarymanagement/pull/378 --- src/main/scala/scalafix/sbt/ScalafixEnable.scala | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/main/scala/scalafix/sbt/ScalafixEnable.scala b/src/main/scala/scalafix/sbt/ScalafixEnable.scala index 8e071a57..cea3d897 100644 --- a/src/main/scala/scalafix/sbt/ScalafixEnable.scala +++ b/src/main/scala/scalafix/sbt/ScalafixEnable.scala @@ -133,8 +133,13 @@ object ScalafixEnable { semanticdbVersion := recommendedSemanticdbV.toString ) case Success(earliestAvailable :: tail) => + val safeRecommendedSemanticdbV = + if (recommendedSemanticdbV.toString == "4.12.4.1") + VersionNumber("4.12.4") + else recommendedSemanticdbV + val futureVersion = - SemanticSelector.apply(s">${recommendedSemanticdbV}") + SemanticSelector.apply(s">${safeRecommendedSemanticdbV}") if (earliestAvailable.matchesSemVer(futureVersion)) { Seq( From 247b17e9dd891219240f788c3a0c90f136d933ac Mon Sep 17 00:00:00 2001 From: "scala-center-steward[bot]" <111975575+scala-center-steward[bot]@users.noreply.github.com> Date: Wed, 15 Jan 2025 00:22:43 +0000 Subject: [PATCH 101/129] Update interface to 1.0.27 --- project/Dependencies.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project/Dependencies.scala b/project/Dependencies.scala index eabc84fa..04defdac 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -7,6 +7,6 @@ object Dependencies { val all = List( "org.eclipse.jgit" % "org.eclipse.jgit" % "5.13.3.202401111512-r", "ch.epfl.scala" % "scalafix-interfaces" % scalafixVersion, - "io.get-coursier" % "interface" % "1.0.26" + "io.get-coursier" % "interface" % "1.0.27" ) } From bf967491d852ccbfb116ffafe049480653e6a41e Mon Sep 17 00:00:00 2001 From: "scala-center-steward[bot]" <111975575+scala-center-steward[bot]@users.noreply.github.com> Date: Wed, 15 Jan 2025 00:22:51 +0000 Subject: [PATCH 102/129] Update scalafmt-core to 3.8.4 --- .scalafmt.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.scalafmt.conf b/.scalafmt.conf index 7dca62d2..873c14c8 100644 --- a/.scalafmt.conf +++ b/.scalafmt.conf @@ -1,4 +1,4 @@ -version = "3.8.3" +version = "3.8.4" project.git=true align.preset=none assumeStandardLibraryStripMargin = true From 79bf920e261b914811108b947d96ac149f4e301e Mon Sep 17 00:00:00 2001 From: "scala-center-steward[bot]" <111975575+scala-center-steward[bot]@users.noreply.github.com> Date: Wed, 15 Jan 2025 00:22:55 +0000 Subject: [PATCH 103/129] Reformat with scalafmt 3.8.4 Executed command: scalafmt --non-interactive --- .../internal/sbt/CoursierRepoResolvers.scala | 3 +-- .../scalafix/internal/sbt/ScalafixInterface.scala | 12 ++++++++---- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/src/main/scala/scalafix/internal/sbt/CoursierRepoResolvers.scala b/src/main/scala/scalafix/internal/sbt/CoursierRepoResolvers.scala index 314e0060..0b5c60ee 100644 --- a/src/main/scala/scalafix/internal/sbt/CoursierRepoResolvers.scala +++ b/src/main/scala/scalafix/internal/sbt/CoursierRepoResolvers.scala @@ -104,8 +104,7 @@ object CoursierRepoResolvers { case r: URLRepository if patternMatchGuard(r.patterns) => parseMavenCompatResolver(log, r.patterns, credentialsByHost) - case raw: RawRepository - if raw.name == "inter-project" => // sbt.RawRepository.equals just compares names anyway + case raw: RawRepository if raw.name == "inter-project" => // sbt.RawRepository.equals just compares names anyway None // Pattern Match resolver-type-specific RawRepositories diff --git a/src/main/scala/scalafix/internal/sbt/ScalafixInterface.scala b/src/main/scala/scalafix/internal/sbt/ScalafixInterface.scala index f2ed4605..6b9f8448 100644 --- a/src/main/scala/scalafix/internal/sbt/ScalafixInterface.scala +++ b/src/main/scala/scalafix/internal/sbt/ScalafixInterface.scala @@ -49,7 +49,8 @@ object Arg { sa.withRules(rules.asJava) } - case class Paths(paths: Seq[Path]) extends Arg { // this one is extracted/stamped directly + case class Paths(paths: Seq[Path]) + extends Arg { // this one is extracted/stamped directly override def apply(sa: ScalafixArguments): ScalafixArguments = sa.withPaths(paths.asJava) } @@ -64,17 +65,20 @@ object Arg { sa.withParsedArguments(args.asJava) } - case class ScalaVersion(version: String) extends Arg { // FIXME: with CacheKey { + case class ScalaVersion(version: String) + extends Arg { // FIXME: with CacheKey { override def apply(sa: ScalafixArguments): ScalafixArguments = sa.withScalaVersion(version) } - case class ScalacOptions(options: Seq[String]) extends Arg { // FIXME: with CacheKey { + case class ScalacOptions(options: Seq[String]) + extends Arg { // FIXME: with CacheKey { override def apply(sa: ScalafixArguments): ScalafixArguments = sa.withScalacOptions(options.asJava) } - case class Classpath(classpath: Seq[Path]) extends Arg { // FIXME: with CacheKey { + case class Classpath(classpath: Seq[Path]) + extends Arg { // FIXME: with CacheKey { override def apply(sa: ScalafixArguments): ScalafixArguments = sa.withClasspath(classpath.asJava) } From 5ca2707c5f4846bc80b5fe99e23617ff4743983e Mon Sep 17 00:00:00 2001 From: "scala-center-steward[bot]" <111975575+scala-center-steward[bot]@users.noreply.github.com> Date: Wed, 15 Jan 2025 00:22:55 +0000 Subject: [PATCH 104/129] Add 'Reformat with scalafmt 3.8.4' to .git-blame-ignore-revs --- .git-blame-ignore-revs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs index 535f3784..5623f7aa 100644 --- a/.git-blame-ignore-revs +++ b/.git-blame-ignore-revs @@ -6,3 +6,6 @@ b7431a3cdd2f4627de48f4f27a361db88949932f # Scala Steward: Reformat with scalafmt 3.8.0 3f1d46f4372c3340624d53469cf236dbb14c0874 + +# Scala Steward: Reformat with scalafmt 3.8.4 +79bf920e261b914811108b947d96ac149f4e301e From 444a0bc7c2dbaecd079714054f8c1b6a5973b61c Mon Sep 17 00:00:00 2001 From: Brice Jaglin Date: Fri, 31 Jan 2025 13:03:16 +0100 Subject: [PATCH 105/129] test on JDK23 Silence "Unknown ansi-escape [0J at index 132" seen with JDK23. --- .github/workflows/ci.yml | 11 +++++++++++ .../scalafix/internal/sbt/ScalafixAPISuite.scala | 2 +- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ef13744d..d38e30c8 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -51,6 +51,17 @@ jobs: jvm: temurin:21 - run: rm -rf src/sbt-test/skip-java17+ - run: sbt test scripted + jdk23: + name: JDK23 tests + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: coursier/setup-action@v1 + with: + apps: sbt + jvm: temurin:23 + - run: rm -rf src/sbt-test/skip-java17+ + - run: sbt test scripted windows: name: Windows tests runs-on: windows-latest diff --git a/src/test/scala/scalafix/internal/sbt/ScalafixAPISuite.scala b/src/test/scala/scalafix/internal/sbt/ScalafixAPISuite.scala index b8742cd0..4f8e96d4 100644 --- a/src/test/scala/scalafix/internal/sbt/ScalafixAPISuite.scala +++ b/src/test/scala/scalafix/internal/sbt/ScalafixAPISuite.scala @@ -78,7 +78,7 @@ class ScalafixAPISuite extends AnyFunSuite { ) ) val obtainedError = mainInterface.run().toList - val out = fansi.Str(baos.toString()).plainText + val out = fansi.Str(baos.toString(), fansi.ErrorMode.Strip).plainText assert(obtainedError == List(ScalafixError.LinterError), out) val obtained = new String(Files.readAllBytes(tmp)) assert(obtained.contains(": Unit = {"), out) From 75cdb081e2188ffeca162efe11c617bf55165c72 Mon Sep 17 00:00:00 2001 From: Brice Jaglin Date: Fri, 31 Jan 2025 22:56:23 +0100 Subject: [PATCH 106/129] ExplicitResultTypes is now available in Scala 3 --- .../skip-sbt1.4/cross-build-scala3/.scalafix-3.conf | 1 - .../cross-build-scala3/{.scalafix-2.conf => .scalafix.conf} | 0 src/sbt-test/skip-sbt1.4/cross-build-scala3/build.sbt | 6 ------ .../cross-build-scala3/src/main/scala-3/Main.scala.expected | 4 ++-- 4 files changed, 2 insertions(+), 9 deletions(-) delete mode 100644 src/sbt-test/skip-sbt1.4/cross-build-scala3/.scalafix-3.conf rename src/sbt-test/skip-sbt1.4/cross-build-scala3/{.scalafix-2.conf => .scalafix.conf} (100%) diff --git a/src/sbt-test/skip-sbt1.4/cross-build-scala3/.scalafix-3.conf b/src/sbt-test/skip-sbt1.4/cross-build-scala3/.scalafix-3.conf deleted file mode 100644 index 21c30ce0..00000000 --- a/src/sbt-test/skip-sbt1.4/cross-build-scala3/.scalafix-3.conf +++ /dev/null @@ -1 +0,0 @@ -rules = [OrganizeImports] diff --git a/src/sbt-test/skip-sbt1.4/cross-build-scala3/.scalafix-2.conf b/src/sbt-test/skip-sbt1.4/cross-build-scala3/.scalafix.conf similarity index 100% rename from src/sbt-test/skip-sbt1.4/cross-build-scala3/.scalafix-2.conf rename to src/sbt-test/skip-sbt1.4/cross-build-scala3/.scalafix.conf diff --git a/src/sbt-test/skip-sbt1.4/cross-build-scala3/build.sbt b/src/sbt-test/skip-sbt1.4/cross-build-scala3/build.sbt index eba0e41b..db4b3ed0 100644 --- a/src/sbt-test/skip-sbt1.4/cross-build-scala3/build.sbt +++ b/src/sbt-test/skip-sbt1.4/cross-build-scala3/build.sbt @@ -18,11 +18,5 @@ lazy val root = project "-Ywarn-unused-import" else "-Wunused:imports" - }, - scalafixConfig := { - if (scalaBinaryVersion.value == "3") - Some(file(".scalafix-3.conf")) - else - Some(file(".scalafix-2.conf")) } ) diff --git a/src/sbt-test/skip-sbt1.4/cross-build-scala3/src/main/scala-3/Main.scala.expected b/src/sbt-test/skip-sbt1.4/cross-build-scala3/src/main/scala-3/Main.scala.expected index cb096903..56c0e6be 100644 --- a/src/sbt-test/skip-sbt1.4/cross-build-scala3/src/main/scala-3/Main.scala.expected +++ b/src/sbt-test/skip-sbt1.4/cross-build-scala3/src/main/scala-3/Main.scala.expected @@ -1,5 +1,5 @@ import scala.Int object Main { - def foo(a: Int) = a + 2.0f -} \ No newline at end of file + def foo(a: Int): Float = a + 2.0f +} From 97cac84e5b58be1bdb01fb5452918030bd7c05ed Mon Sep 17 00:00:00 2001 From: Brice Jaglin Date: Fri, 31 Jan 2025 22:59:03 +0100 Subject: [PATCH 107/129] use either Scala 3 LTS or Next (arbitrarily) in tests --- src/sbt-test/skip-sbt1.4/cross-build-scala3/build.sbt | 2 +- src/sbt-test/skip-sbt1.4/scala-3/build.sbt | 2 +- src/sbt-test/skip-sbt1.4/scalafixEnable/build.sbt | 2 +- src/sbt-test/skip-sbt1.4/testkit/build.sbt | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/sbt-test/skip-sbt1.4/cross-build-scala3/build.sbt b/src/sbt-test/skip-sbt1.4/cross-build-scala3/build.sbt index db4b3ed0..f967a4a2 100644 --- a/src/sbt-test/skip-sbt1.4/cross-build-scala3/build.sbt +++ b/src/sbt-test/skip-sbt1.4/cross-build-scala3/build.sbt @@ -1,6 +1,6 @@ import _root_.scalafix.sbt.{BuildInfo => Versions} -val scala3Version = "3.4.1" +val scala3Version = "3.3.5" ThisBuild / semanticdbEnabled := true ThisBuild / semanticdbVersion := scalafixSemanticdb.revision diff --git a/src/sbt-test/skip-sbt1.4/scala-3/build.sbt b/src/sbt-test/skip-sbt1.4/scala-3/build.sbt index 5d620df2..fa27b244 100644 --- a/src/sbt-test/skip-sbt1.4/scala-3/build.sbt +++ b/src/sbt-test/skip-sbt1.4/scala-3/build.sbt @@ -1 +1 @@ -scalaVersion := "3.3.1" +scalaVersion := "3.3.5" diff --git a/src/sbt-test/skip-sbt1.4/scalafixEnable/build.sbt b/src/sbt-test/skip-sbt1.4/scalafixEnable/build.sbt index 020de2d3..9efcb881 100644 --- a/src/sbt-test/skip-sbt1.4/scalafixEnable/build.sbt +++ b/src/sbt-test/skip-sbt1.4/scalafixEnable/build.sbt @@ -21,5 +21,5 @@ lazy val scala212 = project lazy val scala3 = project .in(file("scala3")) .settings( - scalaVersion := "3.3.1" // built-in support for semanticdb + scalaVersion := "3.6.3" // built-in support for semanticdb ) diff --git a/src/sbt-test/skip-sbt1.4/testkit/build.sbt b/src/sbt-test/skip-sbt1.4/testkit/build.sbt index e080f726..756ebee4 100644 --- a/src/sbt-test/skip-sbt1.4/testkit/build.sbt +++ b/src/sbt-test/skip-sbt1.4/testkit/build.sbt @@ -1,7 +1,7 @@ lazy val V = _root_.scalafix.sbt.BuildInfo lazy val rulesCrossVersions = Seq(V.scala213, V.scala212) -lazy val scala3Version = "3.3.1" +lazy val scala3Version = "3.6.3" inThisBuild( List( From b3ed7485fe38a39734bae9cf27e3f789b3c072d4 Mon Sep 17 00:00:00 2001 From: "scala-center-steward[bot]" <111975575+scala-center-steward[bot]@users.noreply.github.com> Date: Sat, 1 Feb 2025 00:23:05 +0000 Subject: [PATCH 108/129] Update scalafmt-core to 3.8.6 --- .scalafmt.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.scalafmt.conf b/.scalafmt.conf index 873c14c8..f4e94912 100644 --- a/.scalafmt.conf +++ b/.scalafmt.conf @@ -1,4 +1,4 @@ -version = "3.8.4" +version = "3.8.6" project.git=true align.preset=none assumeStandardLibraryStripMargin = true From 71fff9b7a867eb16bbf1f4b5043b678b65e5cd78 Mon Sep 17 00:00:00 2001 From: "scala-center-steward[bot]" <111975575+scala-center-steward[bot]@users.noreply.github.com> Date: Sat, 15 Feb 2025 00:20:37 +0000 Subject: [PATCH 109/129] Update interface to 1.0.28 --- project/Dependencies.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project/Dependencies.scala b/project/Dependencies.scala index 04defdac..99609f08 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -7,6 +7,6 @@ object Dependencies { val all = List( "org.eclipse.jgit" % "org.eclipse.jgit" % "5.13.3.202401111512-r", "ch.epfl.scala" % "scalafix-interfaces" % scalafixVersion, - "io.get-coursier" % "interface" % "1.0.27" + "io.get-coursier" % "interface" % "1.0.28" ) } From 7dd12dda1d6704b0d35a6588bd9885780aab7b93 Mon Sep 17 00:00:00 2001 From: danicheg Date: Thu, 13 Feb 2025 13:13:42 +0300 Subject: [PATCH 110/129] Enhance the error message for the update command --- src/main/scala/scalafix/sbt/ScalafixPlugin.scala | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/main/scala/scalafix/sbt/ScalafixPlugin.scala b/src/main/scala/scalafix/sbt/ScalafixPlugin.scala index efd6d978..c33daed0 100644 --- a/src/main/scala/scalafix/sbt/ScalafixPlugin.scala +++ b/src/main/scala/scalafix/sbt/ScalafixPlugin.scala @@ -250,11 +250,12 @@ object ScalafixPlugin extends AutoPlugin { resolveException.failed.headOption match { case Some(SemanticdbScalac(rev)) => val scalaV = scalaVersion.value - val msg = s"The SemanticDB scalac plugin version ${rev} set up " + - "via `semanticdbVersion` does follow the version recommended " + - "for Scalafix, but is not supported for the outdated Scala " + - s"version ${scalaV}. Please upgrade to a more recent Scala " + - "patch version or uninstall sbt-scalafix." + val msg = + s"The SemanticDB scalac plugin version ${rev} set up " + + "via `semanticdbVersion` does follow the version recommended " + + "for Scalafix, but is not supported for the given Scala " + + s"version ${scalaV}. Please consider upgrading to a more recent version " + + "of sbt-scalafix and/or Scala, or uninstalling sbt-scalafix plugin." throw inc.copy(message = Some(msg)) case _ => } From a7600dd3f9d2a1115246733a7dc1312a7d66bdbd Mon Sep 17 00:00:00 2001 From: danicheg Date: Sun, 16 Feb 2025 22:51:56 +0300 Subject: [PATCH 111/129] Tweak unavailable-semanticdb-scalac test --- .../sbt-scalafix/unavailable-semanticdb-scalac/build.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sbt-test/sbt-scalafix/unavailable-semanticdb-scalac/build.sbt b/src/sbt-test/sbt-scalafix/unavailable-semanticdb-scalac/build.sbt index 622f2dc0..175d9164 100644 --- a/src/sbt-test/sbt-scalafix/unavailable-semanticdb-scalac/build.sbt +++ b/src/sbt-test/sbt-scalafix/unavailable-semanticdb-scalac/build.sbt @@ -19,7 +19,7 @@ checkLogs := { assert( logLines.exists( _.contains( - "Please upgrade to a more recent Scala patch version or uninstall sbt-scalafix" + "Please consider upgrading to a more recent version of sbt-scalafix and/or Scala, or uninstalling sbt-scalafix plugin" ) ) ) From 7d8c8074513a0f70300599c126ec4246a102c355 Mon Sep 17 00:00:00 2001 From: Brice Jaglin Date: Wed, 19 Feb 2025 22:24:25 +0100 Subject: [PATCH 112/129] scalafix 0.14.1 --- project/Dependencies.scala | 2 +- src/main/scala/scalafix/sbt/ScalafixEnable.scala | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/project/Dependencies.scala b/project/Dependencies.scala index 99609f08..f6e5ec25 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -2,7 +2,7 @@ import sbt._ object Dependencies { val x = List(1) // scalafix:ok - def scalafixVersion: String = "0.14.0" + def scalafixVersion: String = "0.14.0+51-953bdc64-SNAPSHOT" val all = List( "org.eclipse.jgit" % "org.eclipse.jgit" % "5.13.3.202401111512-r", diff --git a/src/main/scala/scalafix/sbt/ScalafixEnable.scala b/src/main/scala/scalafix/sbt/ScalafixEnable.scala index cea3d897..d26bb480 100644 --- a/src/main/scala/scalafix/sbt/ScalafixEnable.scala +++ b/src/main/scala/scalafix/sbt/ScalafixEnable.scala @@ -134,8 +134,8 @@ object ScalafixEnable { ) case Success(earliestAvailable :: tail) => val safeRecommendedSemanticdbV = - if (recommendedSemanticdbV.toString == "4.12.4.1") - VersionNumber("4.12.4") + if (recommendedSemanticdbV.toString == "4.13.1.1") + VersionNumber("4.13.1") else recommendedSemanticdbV val futureVersion = From b2007ec576d749337852b1ed013609f713d3884d Mon Sep 17 00:00:00 2001 From: Brice Jaglin Date: Thu, 20 Feb 2025 00:56:23 +0100 Subject: [PATCH 113/129] scalafix 0.14.2 --- project/Dependencies.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project/Dependencies.scala b/project/Dependencies.scala index f6e5ec25..9545dc32 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -2,7 +2,7 @@ import sbt._ object Dependencies { val x = List(1) // scalafix:ok - def scalafixVersion: String = "0.14.0+51-953bdc64-SNAPSHOT" + def scalafixVersion: String = "0.14.2" val all = List( "org.eclipse.jgit" % "org.eclipse.jgit" % "5.13.3.202401111512-r", From 08410efc47e10e5b45c13eb1854a96a217777732 Mon Sep 17 00:00:00 2001 From: "scala-center-steward[bot]" <111975575+scala-center-steward[bot]@users.noreply.github.com> Date: Sat, 1 Mar 2025 00:24:21 +0000 Subject: [PATCH 114/129] Update scalafmt-core to 3.9.2 --- .scalafmt.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.scalafmt.conf b/.scalafmt.conf index f4e94912..d215ed66 100644 --- a/.scalafmt.conf +++ b/.scalafmt.conf @@ -1,4 +1,4 @@ -version = "3.8.6" +version = "3.9.2" project.git=true align.preset=none assumeStandardLibraryStripMargin = true From c4b0d53c3a77d6b54cd206916e1be1aa25edb435 Mon Sep 17 00:00:00 2001 From: "scala-center-steward[bot]" <111975575+scala-center-steward[bot]@users.noreply.github.com> Date: Sat, 15 Mar 2025 00:22:14 +0000 Subject: [PATCH 115/129] Update sbt-ci-release to 1.9.3 --- project/plugins.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project/plugins.sbt b/project/plugins.sbt index b5a62e80..b3981455 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -1,5 +1,5 @@ resolvers ++= Resolver.sonatypeOssRepos("public") -addSbtPlugin("com.github.sbt" % "sbt-ci-release" % "1.9.2") +addSbtPlugin("com.github.sbt" % "sbt-ci-release" % "1.9.3") libraryDependencies += "org.scala-sbt" %% "scripted-plugin" % sbtVersion.value Compile / unmanagedSourceDirectories ++= { From 7ce986542ccb6962553702768eca71337b6fd748 Mon Sep 17 00:00:00 2001 From: "scala-center-steward[bot]" <111975575+scala-center-steward[bot]@users.noreply.github.com> Date: Sat, 15 Mar 2025 00:22:24 +0000 Subject: [PATCH 116/129] Update sbt, scripted-plugin to 1.10.10 --- project/build.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project/build.properties b/project/build.properties index 73df629a..e97b2722 100644 --- a/project/build.properties +++ b/project/build.properties @@ -1 +1 @@ -sbt.version=1.10.7 +sbt.version=1.10.10 From 8b606054b206a9d9cbc4dab54a88976831615e6c Mon Sep 17 00:00:00 2001 From: "scala-center-steward[bot]" <111975575+scala-center-steward[bot]@users.noreply.github.com> Date: Sat, 15 Mar 2025 00:22:33 +0000 Subject: [PATCH 117/129] Update scalafmt-core to 3.9.4 --- .scalafmt.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.scalafmt.conf b/.scalafmt.conf index d215ed66..e08939ac 100644 --- a/.scalafmt.conf +++ b/.scalafmt.conf @@ -1,4 +1,4 @@ -version = "3.9.2" +version = "3.9.4" project.git=true align.preset=none assumeStandardLibraryStripMargin = true From e339403e3cf115fc6875ba4c955b0daad5e8727f Mon Sep 17 00:00:00 2001 From: Brice Jaglin Date: Wed, 12 Mar 2025 21:47:02 +0100 Subject: [PATCH 118/129] cross-build against sbt 2.0.0-M4 --- .github/workflows/ci.yml | 79 ++++------- .scalafix.conf | 22 ++- bin/test-release.sh | 4 + build.sbt | 67 ++++++--- project/Dependencies.scala | 3 +- project/plugins.sbt | 4 +- .../scalafix/internal/sbt/Compat.scala | 30 ++++ .../scalafix/internal/sbt/Compat.scala | 32 +++++ .../scalafix/internal/sbt/BlockingCache.scala | 3 +- .../internal/sbt/CoursierRepoResolvers.scala | 17 ++- .../internal/sbt/DependencyRule.scala | 3 +- .../scalafix/internal/sbt/Implicits.scala | 3 +- .../internal/sbt/JGitCompletions.scala | 9 +- .../internal/sbt/LoggingOutputStream.scala | 6 +- .../internal/sbt/ScalafixCompletions.scala | 10 +- .../internal/sbt/ScalafixInterface.scala | 22 +-- .../internal/sbt/ScalafixLogger.scala | 3 +- .../internal/sbt/SemanticRuleValidator.scala | 6 +- .../scala/scalafix/sbt/ScalafixEnable.scala | 47 +++---- .../scala/scalafix/sbt/ScalafixFailed.scala | 1 + .../scala/scalafix/sbt/ScalafixPlugin.scala | 129 ++++++++++-------- .../scalafix/sbt/ScalafixTestkitPlugin.scala | 33 +++-- src/sbt-test/sbt-scalafix/basic/build.sbt | 8 +- .../basic/project/project/plugins.sbt | 1 - .../sbt-scalafix/build-lint/build.sbt | 5 +- src/sbt-test/sbt-scalafix/concurrency/test | 2 +- .../sbt-scalafix/cross-build/build.sbt | 4 +- .../cross-build/project/project/plugins.sbt | 1 - .../sbt-scalafix/custom-config/build.sbt | 5 +- .../custom-src-directory/build.sbt | 2 + .../dependency/project/project/plugins.sbt | 1 - .../project/project/plugins.sbt | 1 - src/sbt-test/sbt-scalafix/inconfig/build.sbt | 4 +- .../inconfig/project/project/plugins.sbt | 1 - .../sbt-scalafix/local-rules/build.sbt | 4 +- .../local-rules/project/Compat.scala | 6 + .../sbt-scalafix/root-validation/build.sbt | 8 +- .../project/project/plugins.sbt | 1 - .../sbt-scalafix/scalafixEnable/build.sbt | 3 +- .../sbt-scalafix/scalafixOnCompile/build.sbt | 17 +-- .../suppress/project/project/plugins.sbt | 1 - src/sbt-test/sbt-scalafix/wrapper/build.sbt | 5 +- .../scalafixResolvers/project/plugins.sbt | 2 +- .../skip-sbt1.4/testkit/project/plugins.sbt | 16 ++- .../{ => src/main/scala-2}/TargetAxis.scala | 0 .../project/src/main/scala-3/TargetAxis.scala | 45 ++++++ src/sbt-test/skip-windows/caching/build.sbt | 4 +- src/sbt-test/skip-windows/caching/test | 6 +- .../relax-scalacOptions/build.sbt | 15 +- .../relax-scalacOptions/project/plugins.sbt | 0 .../src/main/scala/IgnoreWarning.scala | 0 .../UnusedImportAndProcedureSyntax.scala | 0 .../relax-scalacOptions/test | 3 +- src/test/scala/scalafix/internal/sbt/Fs.scala | 7 +- .../internal/sbt/JGitCompletionsSuite.scala | 2 +- .../sbt/LoggingOutputStreamSuite.scala | 8 +- .../internal/sbt/SbtCompletionsSuite.scala | 36 +++-- .../internal/sbt/ScalafixAPISuite.scala | 17 ++- 58 files changed, 484 insertions(+), 290 deletions(-) create mode 100644 src/main/scala-2.12/scalafix/internal/sbt/Compat.scala create mode 100644 src/main/scala-3/scalafix/internal/sbt/Compat.scala delete mode 100644 src/sbt-test/sbt-scalafix/basic/project/project/plugins.sbt delete mode 100644 src/sbt-test/sbt-scalafix/cross-build/project/project/plugins.sbt delete mode 100644 src/sbt-test/sbt-scalafix/dependency/project/project/plugins.sbt delete mode 100644 src/sbt-test/sbt-scalafix/explicit-files/project/project/plugins.sbt delete mode 100644 src/sbt-test/sbt-scalafix/inconfig/project/project/plugins.sbt create mode 100644 src/sbt-test/sbt-scalafix/local-rules/project/Compat.scala delete mode 100644 src/sbt-test/sbt-scalafix/root-validation/project/project/plugins.sbt delete mode 100644 src/sbt-test/sbt-scalafix/suppress/project/project/plugins.sbt rename src/sbt-test/skip-sbt1.4/testkit/project/{ => src/main/scala-2}/TargetAxis.scala (100%) create mode 100644 src/sbt-test/skip-sbt1.4/testkit/project/src/main/scala-3/TargetAxis.scala rename src/sbt-test/{sbt-scalafix => skip-windows}/relax-scalacOptions/build.sbt (69%) rename src/sbt-test/{sbt-scalafix => skip-windows}/relax-scalacOptions/project/plugins.sbt (100%) rename src/sbt-test/{sbt-scalafix => skip-windows}/relax-scalacOptions/src/main/scala/IgnoreWarning.scala (100%) rename src/sbt-test/{sbt-scalafix => skip-windows}/relax-scalacOptions/src/main/scala/UnusedImportAndProcedureSyntax.scala (100%) rename src/sbt-test/{sbt-scalafix => skip-windows}/relax-scalacOptions/test (93%) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d38e30c8..d418d72d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -5,65 +5,31 @@ on: - main pull_request: jobs: - jdk8: - name: JDK8 tests + ubuntu: + strategy: + fail-fast: false + matrix: + jvm: ["8", "11", "17", "21", "23"] + scala: ["2.12.x", "3.x"] + name: Ubuntu / JDK${{ matrix.jvm }} / Scala ${{ matrix.scala }} runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: coursier/setup-action@v1 with: apps: sbt - jvm: temurin:8 - - run: rm -rf src/sbt-test/skip-sbt1.4 - - run: sbt test scripted - jdk11: - name: JDK11 tests - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - uses: coursier/setup-action@v1 - with: - apps: sbt - jvm: temurin:11 - - run: rm -rf src/sbt-test/skip-sbt1.4 - - run: sbt test scripted - jdk17: - name: JDK17 tests - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - uses: coursier/setup-action@v1 - with: - apps: sbt - jvm: temurin:17 - - run: rm -rf src/sbt-test/skip-java17+ - - run: rm -rf src/sbt-test/skip-sbt1.4 - - run: sbt test scripted - - jdk21: - name: JDK21 tests - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - uses: coursier/setup-action@v1 - with: - apps: sbt - jvm: temurin:21 - - run: rm -rf src/sbt-test/skip-java17+ - - run: sbt test scripted - jdk23: - name: JDK23 tests - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - uses: coursier/setup-action@v1 - with: - apps: sbt - jvm: temurin:23 - - run: rm -rf src/sbt-test/skip-java17+ - - run: sbt test scripted + jvm: temurin:${{ matrix.jvm }} + - if: matrix.jvm == '8' || matrix.jvm == '11' || matrix.jvm == '17' + run: rm -rf src/sbt-test/skip-sbt1.4 + - if: matrix.jvm == '17' || matrix.jvm == '21' || matrix.jvm == '23' + run: rm -rf src/sbt-test/skip-java17+ + - run: sbt ++${{ matrix.scala }} test scripted windows: - name: Windows tests + strategy: + fail-fast: false + matrix: + scala: ["2.12.x", "3.x"] + name: Windows / Scala ${{ matrix.scala }} runs-on: windows-latest steps: - uses: actions/checkout@v4 @@ -72,12 +38,15 @@ jobs: apps: sbt - run: rm -r -fo src\sbt-test\skip-sbt1.4 - run: rm -r -fo src\sbt-test\skip-windows - - run: sbt test-skip-windows scripted + - run: sbt ++${{ matrix.scala }} test-skip-windows scripted shell: bash - checks: - name: Scalafmt + formatting: + name: Scalafmt and Scalafix runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: coursier/setup-action@v1 + with: + apps: sbt - run: ./bin/scalafmt --test + - run: sbt "scalafixAll --check" \ No newline at end of file diff --git a/.scalafix.conf b/.scalafix.conf index b83465d4..16bcef58 100644 --- a/.scalafix.conf +++ b/.scalafix.conf @@ -1,7 +1,19 @@ rules = [ - DisableSyntax -] -DisableSyntax.keywords = [ - var - null + ExplicitResultTypes, + OrganizeImports, + RemoveUnused ] + +OrganizeImports { + groups = [ + "re:javax?\\." + "scala." + "sbt." + "*" + ] + targetDialect = Scala3 +} + +RemoveUnused { + imports = false +} diff --git a/bin/test-release.sh b/bin/test-release.sh index ff2a97c1..45e5c0f8 100755 --- a/bin/test-release.sh +++ b/bin/test-release.sh @@ -6,3 +6,7 @@ version=$1 cs resolve \ --sbt-version 1.0 \ --sbt-plugin "ch.epfl.scala:sbt-scalafix:$version" + +cs resolve \ + --sbt-version 2.0.0-M4 \ + --sbt-plugin "ch.epfl.scala:sbt-scalafix:$version" diff --git a/build.sbt b/build.sbt index 7a4ec6e2..2ad5936d 100644 --- a/build.sbt +++ b/build.sbt @@ -1,13 +1,11 @@ -inThisBuild( - List( - Test / parallelExecution := false, - scalafixDependencies := List( - // Custom rule published to Maven Central https://github.com/scalacenter/example-scalafix-rule - "ch.epfl.scala" %% "example-scalafix-rule" % "1.4.0" - ) - ) +// dogfooding +semanticdbEnabled := true +scalafixDependencies := List( + // Custom rule published to Maven Central https://github.com/scalacenter/example-scalafix-rule + "ch.epfl.scala" %% "example-scalafix-rule" % "1.4.0" ) -onLoadMessage := s"Welcome to sbt-scalafix ${version.value}" + +onLoadMessage := s"Welcome to sbt-scalafix ${version.value} built with Scala ${scalaVersion.value}" moduleName := "sbt-scalafix" // Publish settings @@ -44,35 +42,60 @@ libraryDependencies ++= List( "org.scalatest" %% "scalatest" % "3.2.19" % Test ) -scalaVersion := "2.12.20" +lazy val scala212 = "2.12.20" // bin/test-release.sh +lazy val scala3 = "3.6.4" // bin/test-release.sh + +scalaVersion := scala212 +crossScalaVersions := Seq(scala212, scala3) // keep this as low as possible to avoid running into binary incompatibility such as https://github.com/sbt/sbt/issues/5049 -pluginCrossBuild / sbtVersion := "1.4.0" +pluginCrossBuild / sbtVersion := { + scalaBinaryVersion.value match { + case "2.12" => + "1.4.0" + case _ => + "2.0.0-M4" // bin/test-release.sh + } +} scriptedSbt := { val jdk = System.getProperty("java.specification.version").toDouble if (jdk >= 21) - "1.9.0" // first release that supports JDK21 + Ordering[String].max( + (pluginCrossBuild / sbtVersion).value, + "1.9.0" // first release that supports JDK21 + ) else (pluginCrossBuild / sbtVersion).value } -libraryDependencies += compilerPlugin(scalafixSemanticdb) - -scalacOptions ++= List("-Ywarn-unused", "-Yrangepos") - -scalacOptions ++= List( - "-target:jvm-1.8", - "-Xfatal-warnings", - "-Xlint" -) +scalacOptions ++= { + scalaBinaryVersion.value match { + case "2.12" => + List( + "-Ywarn-unused", + "-Xlint", + "-Xfatal-warnings" + ) + case _ => + List( + "-Wunused:all", + "-Werror" + ) + } +} // Scripted enablePlugins(ScriptedPlugin) sbtPlugin := true scriptedBufferLog := false -scriptedBatchExecution := true +scriptedBatchExecution := { + scalaBinaryVersion.value match { + case "2.12" => true + case _ => false + } +} scriptedParallelInstances := 2 scriptedLaunchOpts ++= Seq( "-Xmx2048M", diff --git a/project/Dependencies.scala b/project/Dependencies.scala index 9545dc32..76b5fb81 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -7,6 +7,7 @@ object Dependencies { val all = List( "org.eclipse.jgit" % "org.eclipse.jgit" % "5.13.3.202401111512-r", "ch.epfl.scala" % "scalafix-interfaces" % scalafixVersion, - "io.get-coursier" % "interface" % "1.0.28" + "io.get-coursier" % "interface" % "1.0.28", + "org.scala-lang.modules" %% "scala-collection-compat" % "2.13.0" ) } diff --git a/project/plugins.sbt b/project/plugins.sbt index b3981455..81f88620 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -1,12 +1,12 @@ resolvers ++= Resolver.sonatypeOssRepos("public") addSbtPlugin("com.github.sbt" % "sbt-ci-release" % "1.9.3") -libraryDependencies += "org.scala-sbt" %% "scripted-plugin" % sbtVersion.value +// dogfooding Compile / unmanagedSourceDirectories ++= { val root = (ThisBuild / baseDirectory).value.getParentFile / "src" / "main" List( root / "scala", - root / "scala-sbt-1.0" + root / "scala-2.12" ) } libraryDependencies ++= Dependencies.all diff --git a/src/main/scala-2.12/scalafix/internal/sbt/Compat.scala b/src/main/scala-2.12/scalafix/internal/sbt/Compat.scala new file mode 100644 index 00000000..d6f441cb --- /dev/null +++ b/src/main/scala-2.12/scalafix/internal/sbt/Compat.scala @@ -0,0 +1,30 @@ +package scalafix.internal.sbt + +import java.io.File +import java.nio.file.Path + +import sbt.Attributed +import sbt.Keys +import sbt.ModuleID + +import xsbti.FileConverter + +object Compat { + + def toPath( + attributed: Attributed[File] + )(implicit conv: FileConverter): Path = + toFile(attributed).toPath() + + def toFile( + attributed: Attributed[File] + )(implicit conv: FileConverter): File = { + val _ = conv // avoid unused warning + attributed.data + } + + def extractModuleID( + attributed: Attributed[File] + ): Option[ModuleID] = + attributed.get(Keys.moduleID.key) +} diff --git a/src/main/scala-3/scalafix/internal/sbt/Compat.scala b/src/main/scala-3/scalafix/internal/sbt/Compat.scala new file mode 100644 index 00000000..159bcadf --- /dev/null +++ b/src/main/scala-3/scalafix/internal/sbt/Compat.scala @@ -0,0 +1,32 @@ +package scalafix.internal.sbt + +import java.io.File +import java.nio.file.Path + +import sbt.Attributed +import sbt.Classpaths +import sbt.Keys +import sbt.ModuleID + +import xsbti.FileConverter +import xsbti.HashedVirtualFileRef + +object Compat { + + def toPath( + attributed: Attributed[HashedVirtualFileRef] + )(using conv: FileConverter): Path = + conv.toPath(attributed.data) + + def toFile( + attributed: Attributed[HashedVirtualFileRef] + )(using conv: FileConverter): File = + toPath(attributed).toFile() + + def extractModuleID( + attributed: Attributed[HashedVirtualFileRef] + ): Option[ModuleID] = + attributed + .get(Keys.moduleIDStr) + .map(Classpaths.moduleIdJsonKeyFormat.read) +} diff --git a/src/main/scala/scalafix/internal/sbt/BlockingCache.scala b/src/main/scala/scalafix/internal/sbt/BlockingCache.scala index 4edba496..d5b4002a 100644 --- a/src/main/scala/scalafix/internal/sbt/BlockingCache.scala +++ b/src/main/scala/scalafix/internal/sbt/BlockingCache.scala @@ -1,8 +1,7 @@ package scalafix.internal.sbt -import java.{util => ju} - import java.lang.ref.SoftReference +import java.util as ju /** A basic thread-safe cache with arbitrary eviction on GC pressure. */ class BlockingCache[K, V] { diff --git a/src/main/scala/scalafix/internal/sbt/CoursierRepoResolvers.scala b/src/main/scala/scalafix/internal/sbt/CoursierRepoResolvers.scala index 0b5c60ee..95584ea2 100644 --- a/src/main/scala/scalafix/internal/sbt/CoursierRepoResolvers.scala +++ b/src/main/scala/scalafix/internal/sbt/CoursierRepoResolvers.scala @@ -1,13 +1,18 @@ package scalafix.internal.sbt -import coursierapi.{Credentials, IvyRepository, MavenRepository, Repository} -import org.apache.ivy.plugins.resolver.IBiblioResolver +import java.net.MalformedURLException +import java.nio.file.Paths + +import scala.jdk.CollectionConverters.* + import sbt.librarymanagement.{Configuration as _, MavenRepository as _, *} import sbt.util.Logger -import java.net.MalformedURLException -import java.nio.file.Paths -import scala.collection.JavaConverters.* +import coursierapi.Credentials +import coursierapi.IvyRepository +import coursierapi.MavenRepository +import coursierapi.Repository +import org.apache.ivy.plugins.resolver.IBiblioResolver // vendor from sbt-coursier/lmcoursier.internal.Resolvers object CoursierRepoResolvers { @@ -122,7 +127,7 @@ object CoursierRepoResolvers { private object IBiblioRepository { - private def stringVector(v: java.util.List[_]): Vector[String] = + private def stringVector(v: java.util.List[?]): Vector[String] = Option(v).map(_.asScala.toVector).getOrElse(Vector.empty).collect { case s: String => s } diff --git a/src/main/scala/scalafix/internal/sbt/DependencyRule.scala b/src/main/scala/scalafix/internal/sbt/DependencyRule.scala index d21599da..d5ce1508 100644 --- a/src/main/scala/scalafix/internal/sbt/DependencyRule.scala +++ b/src/main/scala/scalafix/internal/sbt/DependencyRule.scala @@ -1,8 +1,9 @@ package scalafix.internal.sbt -import sbt.ModuleID import scala.util.matching.Regex +import sbt.ModuleID + case class DependencyRule( ruleName: String, dependency: ModuleID diff --git a/src/main/scala/scalafix/internal/sbt/Implicits.scala b/src/main/scala/scalafix/internal/sbt/Implicits.scala index 5a593e21..72228732 100644 --- a/src/main/scala/scalafix/internal/sbt/Implicits.scala +++ b/src/main/scala/scalafix/internal/sbt/Implicits.scala @@ -1,6 +1,7 @@ package scalafix.internal.sbt -import sbt.librarymanagement._ +import sbt.librarymanagement.* + import scalafix.sbt.InvalidArgument trait Implicits { diff --git a/src/main/scala/scalafix/internal/sbt/JGitCompletions.scala b/src/main/scala/scalafix/internal/sbt/JGitCompletions.scala index a9208029..a5fa3694 100644 --- a/src/main/scala/scalafix/internal/sbt/JGitCompletions.scala +++ b/src/main/scala/scalafix/internal/sbt/JGitCompletions.scala @@ -1,5 +1,10 @@ package scalafix.internal.sbt +import java.nio.file.Path + +import scala.jdk.CollectionConverters.* +import scala.util.Try + import org.eclipse.jgit.api.Git import org.eclipse.jgit.lib.Constants.DOT_GIT import org.eclipse.jgit.lib.RefDatabase @@ -9,10 +14,6 @@ import org.eclipse.jgit.storage.file.FileRepositoryBuilder import org.eclipse.jgit.util.FS import org.eclipse.jgit.util.GitDateFormatter -import java.nio.file.Path -import scala.collection.JavaConverters._ -import scala.util.Try - class JGitCompletion(cwd: Path) { private val isGitRepository = RepositoryCache.FileKey diff --git a/src/main/scala/scalafix/internal/sbt/LoggingOutputStream.scala b/src/main/scala/scalafix/internal/sbt/LoggingOutputStream.scala index d0ecb73c..bf01b166 100644 --- a/src/main/scala/scalafix/internal/sbt/LoggingOutputStream.scala +++ b/src/main/scala/scalafix/internal/sbt/LoggingOutputStream.scala @@ -1,8 +1,10 @@ package scalafix.internal.sbt -import java.io.{ByteArrayOutputStream, OutputStream} +import java.io.ByteArrayOutputStream +import java.io.OutputStream -import sbt.{Level, Logger} +import sbt.Level +import sbt.Logger /** Split an OutputStream into messages and feed them to a given logger at a * specified level. Not thread-safe. diff --git a/src/main/scala/scalafix/internal/sbt/ScalafixCompletions.scala b/src/main/scala/scalafix/internal/sbt/ScalafixCompletions.scala index f2dcf391..3c45c517 100644 --- a/src/main/scala/scalafix/internal/sbt/ScalafixCompletions.scala +++ b/src/main/scala/scalafix/internal/sbt/ScalafixCompletions.scala @@ -1,12 +1,12 @@ package scalafix.internal.sbt -import scalafix.interfaces.ScalafixRule - import java.io.File -import java.nio.file._ +import java.nio.file.* -import sbt.complete._ -import sbt.complete.DefaultParsers._ +import sbt.complete.* +import sbt.complete.DefaultParsers.* + +import scalafix.interfaces.ScalafixRule class ScalafixCompletions( workingDirectory: Path, diff --git a/src/main/scala/scalafix/internal/sbt/ScalafixInterface.scala b/src/main/scala/scalafix/internal/sbt/ScalafixInterface.scala index 6b9f8448..4a77c5e3 100644 --- a/src/main/scala/scalafix/internal/sbt/ScalafixInterface.scala +++ b/src/main/scala/scalafix/internal/sbt/ScalafixInterface.scala @@ -1,15 +1,17 @@ package scalafix.internal.sbt +import java.io.PrintStream import java.nio.file.Path -import java.{util => jutil} -import coursierapi.Repository -import sbt._ +import java.util as jutil + +import scala.jdk.CollectionConverters.* + +import sbt.* import sbt.io.RegularFileFilter -import scalafix.interfaces.{Scalafix => ScalafixAPI, _} -import scalafix.sbt.InvalidArgument -import scala.collection.JavaConverters._ -import java.io.PrintStream +import coursierapi.Repository +import scalafix.interfaces.{Scalafix as ScalafixAPI, *} +import scalafix.sbt.InvalidArgument sealed trait Arg extends (ScalafixArguments => ScalafixArguments) @@ -38,7 +40,7 @@ object Arg { .map(uri => java.nio.file.Paths.get(uri).toFile) .flatMap { case classDirectory if classDirectory.isDirectory => - classDirectory.**(RegularFileFilter).get + classDirectory.**(RegularFileFilter).get() case jar => Seq(jar) } @@ -113,10 +115,10 @@ class ScalafixInterface private ( scalafixArguments.run().toSeq def availableRules(): Seq[ScalafixRule] = - scalafixArguments.availableRules().asScala + scalafixArguments.availableRules().asScala.toSeq def rulesThatWillRun(): Seq[ScalafixRule] = - try scalafixArguments.rulesThatWillRun().asScala + try scalafixArguments.rulesThatWillRun().asScala.toSeq catch { case e: ScalafixException => throw new InvalidArgument(e.getMessage) } diff --git a/src/main/scala/scalafix/internal/sbt/ScalafixLogger.scala b/src/main/scala/scalafix/internal/sbt/ScalafixLogger.scala index 31ac49bc..e465169c 100644 --- a/src/main/scala/scalafix/internal/sbt/ScalafixLogger.scala +++ b/src/main/scala/scalafix/internal/sbt/ScalafixLogger.scala @@ -1,10 +1,11 @@ package scalafix.internal.sbt +import sbt.Logger + import scalafix.interfaces.ScalafixDiagnostic import scalafix.interfaces.ScalafixLintID import scalafix.interfaces.ScalafixMainCallback import scalafix.interfaces.ScalafixSeverity -import sbt.Logger class ScalafixLogger(logger: Logger) extends ScalafixMainCallback { def fullStringID(lintID: ScalafixLintID): String = diff --git a/src/main/scala/scalafix/internal/sbt/SemanticRuleValidator.scala b/src/main/scala/scalafix/internal/sbt/SemanticRuleValidator.scala index a088b278..882fae16 100644 --- a/src/main/scala/scalafix/internal/sbt/SemanticRuleValidator.scala +++ b/src/main/scala/scalafix/internal/sbt/SemanticRuleValidator.scala @@ -2,10 +2,10 @@ package scalafix.internal.sbt import java.nio.file.Path -import sbt.ModuleID - import scala.collection.mutable.ListBuffer +import sbt.ModuleID + class SemanticRuleValidator(ifNotFound: SemanticdbNotFound) { def findErrors( files: Seq[Path], @@ -25,7 +25,7 @@ class SemanticRuleValidator(ifNotFound: SemanticdbNotFound) { invalidArguments.foreach { invalidArgument => errors += invalidArgument.getMessage } - errors + errors.toSeq } } } diff --git a/src/main/scala/scalafix/sbt/ScalafixEnable.scala b/src/main/scala/scalafix/sbt/ScalafixEnable.scala index d26bb480..2a154af2 100644 --- a/src/main/scala/scalafix/sbt/ScalafixEnable.scala +++ b/src/main/scala/scalafix/sbt/ScalafixEnable.scala @@ -1,15 +1,16 @@ package scalafix.sbt -import sbt._ -import sbt.Keys._ -import sbt.VersionNumber.SemVer +import scala.jdk.CollectionConverters.* +import scala.util.* -import ScalafixPlugin.autoImport.scalafixResolvers +import sbt.* +import sbt.Keys.* +import sbt.VersionNumber.SemVer -import collection.JavaConverters._ -import scala.util._ import coursierapi.Repository +import ScalafixPlugin.autoImport.scalafixResolvers + /** Command to automatically enable semanticdb compiler output for shell session */ object ScalafixEnable { @@ -64,7 +65,7 @@ object ScalafixEnable { maybeRecommendedSemanticdbScalacScalaV: Option[VersionNumber] ) - lazy val command = Command.command( + lazy val command: Command = Command.command( "scalafixEnable", briefHelp = "Configure SemanticdbPlugin for scalafix on supported projects.", @@ -96,7 +97,7 @@ object ScalafixEnable { VersionNumber(BuildInfo.scalametaVersion) val compatibleSemanticdbVs = Try( coursierapi.Versions.create - .withRepositories(project.scalafixResolvers0: _*) + .withRepositories(project.scalafixResolvers0*) .withModule(semanticdbScalacModule) .versions() .getMergedListings @@ -160,21 +161,21 @@ object ScalafixEnable { } else { val latestAvailable = tail.lastOption.getOrElse(earliestAvailable) - Seq( - semanticdbVersion := { - val v = latestAvailable.toString - sLog.value.info( - s"Setting semanticdbVersion to $v in project " + - s"${project.ref.project} since the version " + - s"${recommendedSemanticdbV} tracked by scalafix " + - s"${BuildInfo.scalafixVersion} is no longer " + - s"published for scala " + - s"${project.scalaVersion0.toString} - " + - s"consider bumping scala" - ) - v - } - ) + Seq( + semanticdbVersion := { + val v = latestAvailable.toString + sLog.value.info( + s"Setting semanticdbVersion to $v in project " + + s"${project.ref.project} since the version " + + s"${recommendedSemanticdbV} tracked by scalafix " + + s"${BuildInfo.scalafixVersion} is no longer " + + s"published for scala " + + s"${project.scalaVersion0.toString} - " + + s"consider bumping scala" + ) + v + } + ) } } } :+ (semanticdbEnabled := true) diff --git a/src/main/scala/scalafix/sbt/ScalafixFailed.scala b/src/main/scala/scalafix/sbt/ScalafixFailed.scala index 72059cfd..8c269428 100644 --- a/src/main/scala/scalafix/sbt/ScalafixFailed.scala +++ b/src/main/scala/scalafix/sbt/ScalafixFailed.scala @@ -1,6 +1,7 @@ package scalafix.sbt import sbt.FeedbackProvidedException + import scalafix.interfaces.ScalafixError final class InvalidArgument(msg: String) diff --git a/src/main/scala/scalafix/sbt/ScalafixPlugin.scala b/src/main/scala/scalafix/sbt/ScalafixPlugin.scala index c33daed0..d3d62d98 100644 --- a/src/main/scala/scalafix/sbt/ScalafixPlugin.scala +++ b/src/main/scala/scalafix/sbt/ScalafixPlugin.scala @@ -2,30 +2,34 @@ package scalafix.sbt import java.io.PrintStream import java.nio.file.Path -import coursierapi.Repository + +import scala.annotation.nowarn +import scala.jdk.CollectionConverters.* +import scala.util.Try +import scala.util.control.NoStackTrace + +import sbt.* import sbt.KeyRanks.Invisible import sbt.Keys.* -import sbt.* import sbt.internal.sbtscalafix.JLineAccess import sbt.internal.util.complete.Parser -import sbt.plugins.JvmPlugin import sbt.librarymanagement.ResolveException -import scalafix.interfaces.{ScalafixError, ScalafixMainCallback} -import scalafix.internal.sbt.* +import sbt.plugins.JvmPlugin -import scala.annotation.nowarn -import scala.collection.JavaConverters.collectionAsScalaIterableConverter -import scala.util.control.NoStackTrace -import scala.util.Try +import coursierapi.Repository +import scalafix.interfaces.ScalafixError +import scalafix.interfaces.ScalafixMainCallback +import scalafix.internal.sbt.* +import xsbti.FileConverter object ScalafixPlugin extends AutoPlugin { override def trigger: PluginTrigger = allRequirements override def requires: Plugins = JvmPlugin object autoImport { - val Scalafix = Tags.Tag("scalafix") + val Scalafix: Tags.Tag = Tags.Tag("scalafix") - val ScalafixConfig = config("scalafix") + val ScalafixConfig: Configuration = config("scalafix") .describedAs("Dependencies required for rule execution.") val scalafix: InputKey[Unit] = @@ -88,9 +92,10 @@ object ScalafixPlugin extends AutoPlugin { val scalafixSemanticdb: ModuleID = scalafixSemanticdb(BuildInfo.scalametaVersion) def scalafixSemanticdb(scalametaVersion: String): ModuleID = - "org.scalameta" % "semanticdb-scalac" % scalametaVersion cross CrossVersion.full + ("org.scalameta" % "semanticdb-scalac" % scalametaVersion) + .cross(CrossVersion.full) - def scalafixConfigSettings(config: Configuration): Seq[Def.Setting[_]] = + def scalafixConfigSettings(config: Configuration): Seq[Def.Setting[?]] = inConfig(config)( relaxScalacOptionsConfigSettings ++ Seq( scalafix := { @@ -223,7 +228,7 @@ object ScalafixPlugin extends AutoPlugin { override lazy val projectConfigurations: Seq[Configuration] = Seq(ScalafixConfig) - override lazy val projectSettings: Seq[Def.Setting[_]] = Def.settings( + override lazy val projectSettings: Seq[Def.Setting[?]] = Def.settings( Seq(Compile, Test).flatMap(c => inConfig(c)(scalafixConfigSettings(c))), inConfig(ScalafixConfig)( Def.settings( @@ -242,9 +247,9 @@ object ScalafixPlugin extends AutoPlugin { else None } - update.result.value match { - case Value(v) => v - case Inc(inc: Incomplete) => + update.result.value.toEither match { + case Right(v: UpdateReport) => v + case Left(inc: Incomplete) => Incomplete.allExceptions(inc).toList match { case (resolveException: ResolveException) :: Nil => resolveException.failed.headOption match { @@ -265,12 +270,14 @@ object ScalafixPlugin extends AutoPlugin { } }, ivyConfigurations += ScalafixConfig, - scalafixAll := scalafixAllInputTask.evaluated, - (scalafixScalaBinaryVersion: @nowarn) := - scalaVersion.value.split('.').take(2).mkString(".") + scalafixAll := scalafixAllInputTask().evaluated, + (scalafixScalaBinaryVersion := scalaVersion.value + .split('.') + .take(2) + .mkString(".")): @nowarn ) - override lazy val globalSettings: Seq[Def.Setting[_]] = Seq( + override lazy val globalSettings: Seq[Def.Setting[?]] = Seq( scalafixCallback := new ScalafixLogger(ScalafixInterface.defaultLogger), scalafixConfig := None, // let scalafix-cli try to infer $CWD/.scalafix.conf scalafixOnCompile := false, @@ -279,10 +286,13 @@ object ScalafixPlugin extends AutoPlugin { scalafixDependencies := Nil, commands += ScalafixEnable.command, scalafixInterfaceCache := new BlockingCache, - concurrentRestrictions += Tags.exclusiveGroup(Scalafix) + concurrentRestrictions += Tags.exclusiveGroup(Scalafix), + // sbt 2.0.0-M4 rightfully detects the default of semanticdbTargetRoot unused + // as we don't inject SemanticdbPlugin.configurationSettings into the custom config + excludeLintKeys += (ScalafixConfig / semanticdbTargetRoot) ) - override def buildSettings: Seq[Def.Setting[_]] = + override def buildSettings: Seq[Def.Setting[?]] = Seq( scalafixSbtResolversAsCoursierRepositories := { val logger = streams.value.log @@ -322,7 +332,7 @@ object ScalafixPlugin extends AutoPlugin { scalafixJGitCompletion := new JGitCompletion(baseDirectory.value.toPath) ) - lazy val stdoutLogger = ConsoleLogger(System.out) + lazy val stdoutLogger: ConsoleLogger = ConsoleLogger(System.out) private def scalafixArgsFromShell( shell: ShellArgs, @@ -352,7 +362,7 @@ object ScalafixPlugin extends AutoPlugin { val invocationDepsExternal = parsed.map(_.dependency) val projectDepsInternal0 = projectDepsInternal.filter { case directory if directory.isDirectory => - directory.**(AllPassFilter).get.exists(_.isFile) + directory.**(AllPassFilter).get().exists(_.isFile) case file if file.isFile => true case _ => false } @@ -376,19 +386,19 @@ object ScalafixPlugin extends AutoPlugin { } - private def scalafixAllInputTask(): Def.Initialize[InputTask[Unit]] = { - // workaround https://github.com/sbt/sbt/issues/3572 by invoking directly what Def.inputTaskDyn would via macro - InputTask.createDyn(InputTask.initParserAsInput(scalafixParser))( - Def.task(shellArgs => - scalafixAllTask(shellArgs, thisProject.value, resolvedScoped.value) + private def scalafixAllInputTask(): Def.Initialize[InputTask[Unit]] = + Def.inputTaskDyn { + scalafixAllTask( + scalafixParser.parsed, + thisProject.value, + resolvedScoped.value ) - ) - } + } private def scalafixAllTask( shellArgs: ShellArgs, project: ResolvedProject, - scopedKey: ScopedKey[_] + scopedKey: ScopedKey[?] ): Def.Initialize[Task[Unit]] = Def.taskDyn { val configsWithScalafixInputKey = project.settings @@ -420,18 +430,18 @@ object ScalafixPlugin extends AutoPlugin { private def scalafixInputTask( config: Configuration - ): Def.Initialize[InputTask[Unit]] = { - // workaround https://github.com/sbt/sbt/issues/3572 by invoking directly what Def.inputTaskDyn would via macro - InputTask.createDyn(InputTask.initParserAsInput(scalafixParser))( - Def.task(shellArgs => scalafixTask(shellArgs, config)) - ) - } + ): Def.Initialize[InputTask[Unit]] = + Def.inputTaskDyn { + scalafixTask(scalafixParser.parsed, config) + } private def scalafixTask( shellArgs: ShellArgs, config: ConfigKey ): Def.Initialize[Task[Unit]] = { val task = Def.taskDyn { + implicit val conv: FileConverter = fileConverter.value + val errorLogger = new PrintStream( LoggingOutputStream( @@ -439,11 +449,12 @@ object ScalafixPlugin extends AutoPlugin { Level.Error ) ) - val projectDepsInternal = (ScalafixConfig / products).value ++ - (ScalafixConfig / internalDependencyClasspath).value.map(_.data) + val projectDepsInternal = ((ScalafixConfig / products).value ++ + (ScalafixConfig / internalDependencyClasspath).value + .map(Compat.toFile)) val projectDepsExternal = (ScalafixConfig / externalDependencyClasspath).value - .flatMap(_.get(moduleID.key)) + .flatMap(Compat.extractModuleID) val allResolvers = ((ThisBuild / scalafixResolvers).value ++ (ThisBuild / scalafixSbtResolversAsCoursierRepositories).value).distinct @@ -471,7 +482,7 @@ object ScalafixPlugin extends AutoPlugin { val maybeNoCache = if (shell.noCache || !scalafixCaching.value) Seq(Arg.NoCache) else Nil val mainInterface = baseInterface - .withArgs(maybeNoCache: _*) + .withArgs(maybeNoCache*) .withArgs( Arg.PrintStream(errorLogger), Arg.Config(scalafixConf), @@ -513,6 +524,8 @@ object ScalafixPlugin extends AutoPlugin { config: ConfigKey ): Def.Initialize[Task[Unit]] = Def.taskDyn { + implicit val conv: FileConverter = fileConverter.value + val dependencies = (config / allDependencies).value val files = filesToFix(shellArgs, config).value val scalacOpts = (config / compile / scalacOptions).value @@ -523,7 +536,7 @@ object ScalafixPlugin extends AutoPlugin { val task = Def.task { // don't use fullClasspath as it results in a cyclic dependency via compile when scalafixOnCompile := true val classpath = - (config / dependencyClasspath).value.map(_.data.toPath) :+ + (config / dependencyClasspath).value.map(Compat.toPath) :+ (config / classDirectory).value.toPath val semanticInterface = mainArgs.withArgs( Arg.Paths(files), @@ -570,19 +583,18 @@ object ScalafixPlugin extends AutoPlugin { // used to signal that one of the argument cannot be reliably stamped object StampingImpossible extends RuntimeException with NoStackTrace - import sjsonnew._ import sjsonnew.BasicJsonProtocol._ - val argWriter = new JsonWriter[Arg.CacheKey] { + val argWriter = new sjsonnew.JsonWriter[Arg.CacheKey] { override final def write[J]( obj: Arg.CacheKey, - builder: Builder[J] + builder: sjsonnew.Builder[J] ): Unit = stamp(obj)(builder) private def stamp[J]( obj: Arg.CacheKey - )(implicit builder: Builder[J]): Unit = obj match { + )(implicit builder: sjsonnew.Builder[J]): Unit = obj match { case toolClasspath @ Arg.ToolClasspath(_, customDependencies, _) => write(toolClasspath.mutableFiles.map(stampFile).sorted) write(customDependencies.map(_.toString).sorted) @@ -633,7 +645,7 @@ object ScalafixPlugin extends AutoPlugin { } private lazy val checkIfTriggeredSectionExists: Boolean = { - val confInArgs = interface.args + val confInArgs: Option[Path] = interface.args .collect { case Arg.Config(conf) => conf } .flatten .lastOption @@ -652,13 +664,15 @@ object ScalafixPlugin extends AutoPlugin { "" } - private def write[J, A: JsonWriter](obj: A)(implicit - builder: Builder[J] - ): Unit = implicitly[JsonWriter[A]].write(obj, builder) + private def write[J, A](obj: A)(implicit + writer: sjsonnew.JsonWriter[A], + builder: sjsonnew.Builder[J] + ): Unit = writer.write(obj, builder) } // implicit conversion of collection is only available on JsonFormat - implicit val argFormat = liftFormat(argWriter) + implicit val argFormat: sjsonnew.JsonFormat[Arg.CacheKey] = + liftFormat(argWriter) def diffWithPreviousRuns[T](f: (Boolean, Set[File]) => T): T = { val tracker = Tracked.inputChangedW(streams.cacheDirectory / "args") { @@ -673,7 +687,7 @@ object ScalafixPlugin extends AutoPlugin { Tracked.diffInputs( streams.cacheDirectory / "targets-by-rule" / rule, cachingStyle - )(targets) { changeReport: ChangeReport[File] => + )(targets) { (changeReport: ChangeReport[File]) => doForStaleTargets(changeReport.modified -- changeReport.removed) } @@ -697,8 +711,9 @@ object ScalafixPlugin extends AutoPlugin { } } - val ruleTargetDiffs = interface.rulesThatWillRun - .map(rule => diffTargets(rule.name) _) + val ruleTargetDiffs = interface + .rulesThatWillRun() + .map(rule => diffTargets(rule.name)(_)) .toList accumulateAndRunForStaleTargets(ruleTargetDiffs) } @@ -750,7 +765,7 @@ object ScalafixPlugin extends AutoPlugin { } yield source.toPath } - private[sbt] val relaxScalacOptionsConfigSettings: Seq[Def.Setting[_]] = + private[sbt] val relaxScalacOptionsConfigSettings: Seq[Def.Setting[?]] = Seq( compile / scalacOptions := { val options = (compile / scalacOptions).value diff --git a/src/main/scala/scalafix/sbt/ScalafixTestkitPlugin.scala b/src/main/scala/scalafix/sbt/ScalafixTestkitPlugin.scala index 9a5dc63b..b939de25 100644 --- a/src/main/scala/scalafix/sbt/ScalafixTestkitPlugin.scala +++ b/src/main/scala/scalafix/sbt/ScalafixTestkitPlugin.scala @@ -1,34 +1,37 @@ package scalafix.sbt -import sbt.Keys._ -import sbt._ +import java.io.File.pathSeparator + +import sbt.* +import sbt.Keys.* import sbt.plugins.JvmPlugin -import java.io.File.pathSeparator +import scalafix.internal.sbt.Compat +import xsbti.FileConverter object ScalafixTestkitPlugin extends AutoPlugin { override def trigger: PluginTrigger = noTrigger override def requires: Plugins = JvmPlugin object autoImport { - val scalafixTestkitInputClasspath = + val scalafixTestkitInputClasspath: TaskKey[Classpath] = taskKey[Classpath]("Classpath of input project") - val scalafixTestkitInputScalacOptions = + val scalafixTestkitInputScalacOptions: TaskKey[Seq[String]] = taskKey[Seq[String]]( "Scalac compiler flags that were used to compile the input project" ) - val scalafixTestkitInputScalaVersion = + val scalafixTestkitInputScalaVersion: SettingKey[String] = settingKey[String]( "Scala compiler version that was used to compile the input project" ) - val scalafixTestkitInputSourceDirectories = + val scalafixTestkitInputSourceDirectories: TaskKey[Seq[File]] = taskKey[Seq[File]]("Source directories of input project") - val scalafixTestkitOutputSourceDirectories = + val scalafixTestkitOutputSourceDirectories: TaskKey[Seq[File]] = taskKey[Seq[File]]("Source directories of output project") } import autoImport._ - override def buildSettings: Seq[Def.Setting[_]] = + override def buildSettings: Seq[Def.Setting[?]] = List( // This makes it simpler to use sbt-scalafix SNAPSHOTS: such snapshots may bring scalafix-* SNAPSHOTS which is fine in the // meta build as the same resolver (declared in project/plugins.sbt) is used. However, since testkit-enabled projects are @@ -37,18 +40,22 @@ object ScalafixTestkitPlugin extends AutoPlugin { includePluginResolvers := true ) - override def projectSettings: Seq[Def.Setting[_]] = + override def projectSettings: Seq[Def.Setting[?]] = List( - libraryDependencies += "ch.epfl.scala" % "scalafix-testkit" % BuildInfo.scalafixVersion % Test cross CrossVersion.full, + libraryDependencies += + ("ch.epfl.scala" % "scalafix-testkit" % BuildInfo.scalafixVersion % Test) + .cross(CrossVersion.full), scalafixTestkitInputScalacOptions := scalacOptions.value, scalafixTestkitInputScalaVersion := scalaVersion.value, Test / resourceGenerators += Def.task { + implicit val conv: FileConverter = fileConverter.value + val props = new java.util.Properties() val values = Map[String, Seq[File]]( "sourceroot" -> List((ThisBuild / baseDirectory).value), "inputClasspath" -> - scalafixTestkitInputClasspath.value.map(_.data), + scalafixTestkitInputClasspath.value.map(Compat.toFile), "inputSourceDirectories" -> scalafixTestkitInputSourceDirectories.value.distinct, // https://github.com/sbt/sbt/pull/6511 "outputSourceDirectories" -> @@ -69,7 +76,7 @@ object ScalafixTestkitPlugin extends AutoPlugin { (Test / managedResourceDirectories).value.head / "scalafix-testkit.properties" IO.write(props, "Input data for scalafix testkit", out) - List(out) + Seq(out) } ) } diff --git a/src/sbt-test/sbt-scalafix/basic/build.sbt b/src/sbt-test/sbt-scalafix/basic/build.sbt index 3a077a01..ad121b67 100644 --- a/src/sbt-test/sbt-scalafix/basic/build.sbt +++ b/src/sbt-test/sbt-scalafix/basic/build.sbt @@ -17,11 +17,9 @@ inThisBuild( lazy val example = project .settings( Defaults.itSettings, - addCompilerPlugin(scalafixSemanticdb), - scalacOptions ++= List( - "-Yrangepos", - "-Ywarn-unused-import" - ) + semanticdbEnabled := true, + semanticdbVersion := scalafixSemanticdb.revision, + scalacOptions += "-Ywarn-unused-import" ) .settings(scalafixConfigSettings(IntegrationTest): _*) diff --git a/src/sbt-test/sbt-scalafix/basic/project/project/plugins.sbt b/src/sbt-test/sbt-scalafix/basic/project/project/plugins.sbt deleted file mode 100644 index a71e6521..00000000 --- a/src/sbt-test/sbt-scalafix/basic/project/project/plugins.sbt +++ /dev/null @@ -1 +0,0 @@ -addSbtPlugin("io.get-coursier" % "sbt-coursier" % "1.1.0-M7") diff --git a/src/sbt-test/sbt-scalafix/build-lint/build.sbt b/src/sbt-test/sbt-scalafix/build-lint/build.sbt index 4e7833be..ee3c828b 100644 --- a/src/sbt-test/sbt-scalafix/build-lint/build.sbt +++ b/src/sbt-test/sbt-scalafix/build-lint/build.sbt @@ -11,7 +11,10 @@ checkLintWarns := { val includeKeys = (Global / includeLintKeys).value.map(_.scopedKey.key.label) val excludeKeys = - (Global / excludeLintKeys).value.map(_.scopedKey.key.label) + // for some reason watchPersistFileStamps comes up as unused in sbt 2.0.0-M4 + // when LintUnused.lintUnused is invoked (but not at startup) ... + ((Global / excludeLintKeys).value + sbt.nio.Keys.watchPersistFileStamps) + .map(_.scopedKey.key.label) val result = sbt.internal.LintUnused.lintUnused(state, includeKeys, excludeKeys) assert(result.size == 0) diff --git a/src/sbt-test/sbt-scalafix/concurrency/test b/src/sbt-test/sbt-scalafix/concurrency/test index 658742cd..1d985c8c 100644 --- a/src/sbt-test/sbt-scalafix/concurrency/test +++ b/src/sbt-test/sbt-scalafix/concurrency/test @@ -1,5 +1,5 @@ # warm up so that tasks themselves (not their dependencies) run in parallel -> scalafix:compile +> Compile / scalafix / compile > all addHeader scalafixAddFooter > check \ No newline at end of file diff --git a/src/sbt-test/sbt-scalafix/cross-build/build.sbt b/src/sbt-test/sbt-scalafix/cross-build/build.sbt index a8d0e1f8..118103f9 100644 --- a/src/sbt-test/sbt-scalafix/cross-build/build.sbt +++ b/src/sbt-test/sbt-scalafix/cross-build/build.sbt @@ -8,8 +8,8 @@ inThisBuild( ) lazy val scalafixSettings = List( - addCompilerPlugin(scalafixSemanticdb), - scalacOptions += "-Yrangepos" + semanticdbEnabled := true, + semanticdbVersion := scalafixSemanticdb.revision ) lazy val root = project diff --git a/src/sbt-test/sbt-scalafix/cross-build/project/project/plugins.sbt b/src/sbt-test/sbt-scalafix/cross-build/project/project/plugins.sbt deleted file mode 100644 index a71e6521..00000000 --- a/src/sbt-test/sbt-scalafix/cross-build/project/project/plugins.sbt +++ /dev/null @@ -1 +0,0 @@ -addSbtPlugin("io.get-coursier" % "sbt-coursier" % "1.1.0-M7") diff --git a/src/sbt-test/sbt-scalafix/custom-config/build.sbt b/src/sbt-test/sbt-scalafix/custom-config/build.sbt index 532195ea..f097de1b 100644 --- a/src/sbt-test/sbt-scalafix/custom-config/build.sbt +++ b/src/sbt-test/sbt-scalafix/custom-config/build.sbt @@ -1,8 +1,9 @@ val V = _root_.scalafix.sbt.BuildInfo scalaVersion := V.scala212 -addCompilerPlugin(scalafixSemanticdb) -scalacOptions ++= Seq("-Yrangepos", "-Ywarn-unused") +semanticdbEnabled := true +semanticdbVersion := scalafixSemanticdb.revision +scalacOptions += "-Ywarn-unused" Compile / scalafixConfig := Some(file(".compile.scalafix.conf")) Test / scalafixConfig := Some(file(".test.scalafix.conf")) diff --git a/src/sbt-test/sbt-scalafix/custom-src-directory/build.sbt b/src/sbt-test/sbt-scalafix/custom-src-directory/build.sbt index 494a7fa2..f25ab9fd 100644 --- a/src/sbt-test/sbt-scalafix/custom-src-directory/build.sbt +++ b/src/sbt-test/sbt-scalafix/custom-src-directory/build.sbt @@ -1,3 +1,5 @@ +scalaVersion := "2.13.16" + val app = project.settings( Compile / scalaSource := baseDirectory.value ) diff --git a/src/sbt-test/sbt-scalafix/dependency/project/project/plugins.sbt b/src/sbt-test/sbt-scalafix/dependency/project/project/plugins.sbt deleted file mode 100644 index a71e6521..00000000 --- a/src/sbt-test/sbt-scalafix/dependency/project/project/plugins.sbt +++ /dev/null @@ -1 +0,0 @@ -addSbtPlugin("io.get-coursier" % "sbt-coursier" % "1.1.0-M7") diff --git a/src/sbt-test/sbt-scalafix/explicit-files/project/project/plugins.sbt b/src/sbt-test/sbt-scalafix/explicit-files/project/project/plugins.sbt deleted file mode 100644 index a71e6521..00000000 --- a/src/sbt-test/sbt-scalafix/explicit-files/project/project/plugins.sbt +++ /dev/null @@ -1 +0,0 @@ -addSbtPlugin("io.get-coursier" % "sbt-coursier" % "1.1.0-M7") diff --git a/src/sbt-test/sbt-scalafix/inconfig/build.sbt b/src/sbt-test/sbt-scalafix/inconfig/build.sbt index fd6f8a37..1485853f 100644 --- a/src/sbt-test/sbt-scalafix/inconfig/build.sbt +++ b/src/sbt-test/sbt-scalafix/inconfig/build.sbt @@ -17,8 +17,8 @@ inThisBuild( lazy val example = project .settings( Defaults.itSettings, - addCompilerPlugin(scalafixSemanticdb), - scalacOptions += "-Yrangepos" + semanticdbEnabled := true, + semanticdbVersion := scalafixSemanticdb.revision ) .settings(scalafixConfigSettings(IntegrationTest): _*) diff --git a/src/sbt-test/sbt-scalafix/inconfig/project/project/plugins.sbt b/src/sbt-test/sbt-scalafix/inconfig/project/project/plugins.sbt deleted file mode 100644 index a71e6521..00000000 --- a/src/sbt-test/sbt-scalafix/inconfig/project/project/plugins.sbt +++ /dev/null @@ -1 +0,0 @@ -addSbtPlugin("io.get-coursier" % "sbt-coursier" % "1.1.0-M7") diff --git a/src/sbt-test/sbt-scalafix/local-rules/build.sbt b/src/sbt-test/sbt-scalafix/local-rules/build.sbt index 03b7f94a..7b8e3702 100644 --- a/src/sbt-test/sbt-scalafix/local-rules/build.sbt +++ b/src/sbt-test/sbt-scalafix/local-rules/build.sbt @@ -7,7 +7,9 @@ inThisBuild( "ch.epfl.scala" %% "example-scalafix-rule" % "1.4.0" ), resolvers += Resolver.sonatypeRepo("snapshots"), - scalaVersion := "2.13.11" // out of sync with scalafix.sbt.BuildInfo.scala213 on purpose + // out of sync with scalafix.sbt.BuildInfo.scala213 on purpose + scalaVersion := "2.13.11", + Compat.allowUnsafeScalaLibUpgrade := true ) ) diff --git a/src/sbt-test/sbt-scalafix/local-rules/project/Compat.scala b/src/sbt-test/sbt-scalafix/local-rules/project/Compat.scala new file mode 100644 index 00000000..477aab1e --- /dev/null +++ b/src/sbt-test/sbt-scalafix/local-rules/project/Compat.scala @@ -0,0 +1,6 @@ +import sbt._ + +object Compat { + // https://github.com/sbt/sbt/blob/78bffa2/main/src/main/scala/sbt/Keys.scala#L577 for older sbt versions + val allowUnsafeScalaLibUpgrade = settingKey[Boolean]("") +} diff --git a/src/sbt-test/sbt-scalafix/root-validation/build.sbt b/src/sbt-test/sbt-scalafix/root-validation/build.sbt index 0f61111b..18f176d0 100644 --- a/src/sbt-test/sbt-scalafix/root-validation/build.sbt +++ b/src/sbt-test/sbt-scalafix/root-validation/build.sbt @@ -11,9 +11,7 @@ lazy val root = project lazy val lib = project .in(file("lib")) .settings( - addCompilerPlugin(scalafixSemanticdb), - scalacOptions ++= List( - "-Ywarn-unused", - "-Yrangepos" - ) + semanticdbEnabled := true, + semanticdbVersion := scalafixSemanticdb.revision, + scalacOptions += "-Ywarn-unused" ) diff --git a/src/sbt-test/sbt-scalafix/root-validation/project/project/plugins.sbt b/src/sbt-test/sbt-scalafix/root-validation/project/project/plugins.sbt deleted file mode 100644 index a71e6521..00000000 --- a/src/sbt-test/sbt-scalafix/root-validation/project/project/plugins.sbt +++ /dev/null @@ -1 +0,0 @@ -addSbtPlugin("io.get-coursier" % "sbt-coursier" % "1.1.0-M7") diff --git a/src/sbt-test/sbt-scalafix/scalafixEnable/build.sbt b/src/sbt-test/sbt-scalafix/scalafixEnable/build.sbt index 886bbddd..8dbf659e 100644 --- a/src/sbt-test/sbt-scalafix/scalafixEnable/build.sbt +++ b/src/sbt-test/sbt-scalafix/scalafixEnable/build.sbt @@ -1,7 +1,8 @@ val V = _root_.scalafix.sbt.BuildInfo lazy val config = project.settings( - scalafixScalaBinaryVersion := scalaBinaryVersion.value // to support old scalafix-interface + scalafixScalaBinaryVersion := scalaBinaryVersion.value, // to support old scalafix-interface + scalaVersion := "2.13.16" ) lazy val unsupported = project.settings( diff --git a/src/sbt-test/sbt-scalafix/scalafixOnCompile/build.sbt b/src/sbt-test/sbt-scalafix/scalafixOnCompile/build.sbt index 533c85af..8e4f03f7 100644 --- a/src/sbt-test/sbt-scalafix/scalafixOnCompile/build.sbt +++ b/src/sbt-test/sbt-scalafix/scalafixOnCompile/build.sbt @@ -3,26 +3,19 @@ import _root_.scalafix.sbt.{BuildInfo => Versions} inThisBuild( Seq( scalaVersion := Versions.scala212, - scalacOptions ++= List( - "-Yrangepos", - "-Ywarn-unused" - ) + semanticdbEnabled := true, + semanticdbVersion := scalafixSemanticdb.revision, + scalacOptions += "-Ywarn-unused" ) ) + lazy val lint = project - .settings( - addCompilerPlugin(scalafixSemanticdb) - ) lazy val rewrite = project .configs(IntegrationTest) .settings( - Defaults.itSettings, - addCompilerPlugin(scalafixSemanticdb) + Defaults.itSettings ) .settings(scalafixConfigSettings(IntegrationTest): _*) lazy val triggered = project - .settings( - addCompilerPlugin(scalafixSemanticdb) - ) diff --git a/src/sbt-test/sbt-scalafix/suppress/project/project/plugins.sbt b/src/sbt-test/sbt-scalafix/suppress/project/project/plugins.sbt deleted file mode 100644 index a71e6521..00000000 --- a/src/sbt-test/sbt-scalafix/suppress/project/project/plugins.sbt +++ /dev/null @@ -1 +0,0 @@ -addSbtPlugin("io.get-coursier" % "sbt-coursier" % "1.1.0-M7") diff --git a/src/sbt-test/sbt-scalafix/wrapper/build.sbt b/src/sbt-test/sbt-scalafix/wrapper/build.sbt index 6dd16501..3ce63649 100644 --- a/src/sbt-test/sbt-scalafix/wrapper/build.sbt +++ b/src/sbt-test/sbt-scalafix/wrapper/build.sbt @@ -1,5 +1,6 @@ val V = _root_.scalafix.sbt.BuildInfo scalaVersion := V.scala212 -addCompilerPlugin(scalafixSemanticdb) -scalacOptions ++= Seq("-Yrangepos", "-Ywarn-unused") +semanticdbEnabled := true +semanticdbVersion := scalafixSemanticdb.revision +scalacOptions += "-Ywarn-unused" diff --git a/src/sbt-test/skip-java17+/scalafixResolvers/project/plugins.sbt b/src/sbt-test/skip-java17+/scalafixResolvers/project/plugins.sbt index c20e9105..a8c87140 100644 --- a/src/sbt-test/skip-java17+/scalafixResolvers/project/plugins.sbt +++ b/src/sbt-test/skip-java17+/scalafixResolvers/project/plugins.sbt @@ -1,3 +1,3 @@ resolvers += Resolver.sonatypeRepo("public") addSbtPlugin("ch.epfl.scala" % "sbt-scalafix" % sys.props("plugin.version")) -addSbtPlugin("au.com.onegeek" %% "sbt-dotenv" % "2.1.146") +addSbtPlugin("nl.gn0s1s" %% "sbt-dotenv" % "3.1.1") diff --git a/src/sbt-test/skip-sbt1.4/testkit/project/plugins.sbt b/src/sbt-test/skip-sbt1.4/testkit/project/plugins.sbt index c3527a81..e30c72f9 100644 --- a/src/sbt-test/skip-sbt1.4/testkit/project/plugins.sbt +++ b/src/sbt-test/skip-sbt1.4/testkit/project/plugins.sbt @@ -1,3 +1,17 @@ resolvers += Resolver.sonatypeRepo("public") addSbtPlugin("ch.epfl.scala" % "sbt-scalafix" % sys.props("plugin.version")) -addSbtPlugin("com.eed3si9n" % "sbt-projectmatrix" % "0.8.0") + +libraryDependencies ++= { + val sbtV = sbtBinaryVersion.value + val scalaV = scalaBinaryVersion.value + if (sbtVersion.value.startsWith("1.")) + Seq( + Defaults.sbtPluginExtra( + "com.eed3si9n" % "sbt-projectmatrix" % "0.8.0", + sbtV, + scalaV + ) + ) + else + Seq() +} diff --git a/src/sbt-test/skip-sbt1.4/testkit/project/TargetAxis.scala b/src/sbt-test/skip-sbt1.4/testkit/project/src/main/scala-2/TargetAxis.scala similarity index 100% rename from src/sbt-test/skip-sbt1.4/testkit/project/TargetAxis.scala rename to src/sbt-test/skip-sbt1.4/testkit/project/src/main/scala-2/TargetAxis.scala diff --git a/src/sbt-test/skip-sbt1.4/testkit/project/src/main/scala-3/TargetAxis.scala b/src/sbt-test/skip-sbt1.4/testkit/project/src/main/scala-3/TargetAxis.scala new file mode 100644 index 00000000..64313436 --- /dev/null +++ b/src/sbt-test/skip-sbt1.4/testkit/project/src/main/scala-3/TargetAxis.scala @@ -0,0 +1,45 @@ +import sbt._ +import sbt.Keys._ + +/** Use on ProjectMatrix rows to tag an affinity to a custom scalaVersion */ +case class TargetAxis(scalaVersion: String) extends VirtualAxis.WeakAxis { + + private val scalaBinaryVersion = CrossVersion.binaryScalaVersion(scalaVersion) + + override val idSuffix = s"Target${scalaBinaryVersion.replace('.', '_')}" + override val directorySuffix = s"target$scalaBinaryVersion" +} + +object TargetAxis { + + private def targetScalaVersion(virtualAxes: Seq[VirtualAxis]): String = + virtualAxes.collectFirst { case a: TargetAxis => a.scalaVersion }.get + + /** When invoked on a ProjectMatrix with a TargetAxis, lookup the project + * generated by `matrix` with a scalaVersion matching the one defined in that + * and resolve `key`. + */ + def resolve[T]( + matrix: ProjectMatrix, + key: TaskKey[T] + ): Def.Initialize[Task[T]] = + Def.taskDyn { + val sv = targetScalaVersion(virtualAxes.value) + val project = matrix.finder().apply(sv) + Def.task((LocalProject(project.id) / key).value) + } + + /** When invoked on a ProjectMatrix with a TargetAxis, lookup the project + * generated by `matrix` with a scalaVersion matching the one defined in that + * and resolve `key`. + */ + def resolve[T]( + matrix: ProjectMatrix, + key: SettingKey[T] + ): Def.Initialize[T] = + Def.settingDyn { + val sv = targetScalaVersion(virtualAxes.value) + val project = matrix.finder().apply(sv) + Def.setting((LocalProject(project.id) / key).value) + } +} diff --git a/src/sbt-test/skip-windows/caching/build.sbt b/src/sbt-test/skip-windows/caching/build.sbt index bfb4d0ee..6ce417e4 100644 --- a/src/sbt-test/skip-windows/caching/build.sbt +++ b/src/sbt-test/skip-windows/caching/build.sbt @@ -3,8 +3,8 @@ import _root_.scalafix.sbt.{BuildInfo => Versions} inThisBuild( List( scalaVersion := Versions.scala212, - addCompilerPlugin(scalafixSemanticdb), - scalacOptions += "-Yrangepos", + semanticdbEnabled := true, + semanticdbVersion := scalafixSemanticdb.revision, scalacOptions += "-Ywarn-unused", // for RemoveUnused scalafixDependencies += "com.geirsson" %% "example-scalafix-rule" % "1.2.0", resolvers += diff --git a/src/sbt-test/skip-windows/caching/test b/src/sbt-test/skip-windows/caching/test index 6f15cdea..496eea8f 100644 --- a/src/sbt-test/skip-windows/caching/test +++ b/src/sbt-test/skip-windows/caching/test @@ -189,7 +189,7 @@ $ delete .scalafix.conf $ mkdir src/main/scala $ copy-file files/Valid.scala src/main/scala/Valid.scala > scalafix SyntacticRule -> 'set scalafixDependencies in ThisBuild := Seq("com.geirsson" %% "example-scalafix-rule" % "1.3.0")' +> 'set ThisBuild / scalafixDependencies := Seq("com.geirsson" %% "example-scalafix-rule" % "1.3.0")' $ exec chmod 000 src/main/scala/Valid.scala -> scalafix SyntacticRule $ delete src/main/scala @@ -359,13 +359,13 @@ $ delete src/main/scala > set scalafixConfig := None $ mkdir src/main/scala $ copy-file files/Valid.scala src/main/scala/Valid.scala -> set scalafixDependencies in ThisBuild := Nil +> set ThisBuild / scalafixDependencies := Nil > scalafix --check ProcedureSyntax > reload plugins > 'set dependencyOverrides += "ch.epfl.scala" % "scalafix-interfaces" % "0.11.0+134-f4dcc6fa-SNAPSHOT"' // different than above, requires bumping when using new APIs > session save > reload return -> set scalafixDependencies in ThisBuild := Nil +> set ThisBuild / scalafixDependencies := Nil $ exec chmod 000 src/main/scala/Valid.scala -> scalafix --check ProcedureSyntax $ delete src/main/scala \ No newline at end of file diff --git a/src/sbt-test/sbt-scalafix/relax-scalacOptions/build.sbt b/src/sbt-test/skip-windows/relax-scalacOptions/build.sbt similarity index 69% rename from src/sbt-test/sbt-scalafix/relax-scalacOptions/build.sbt rename to src/sbt-test/skip-windows/relax-scalacOptions/build.sbt index 1bfde9f8..91ce2adb 100644 --- a/src/sbt-test/sbt-scalafix/relax-scalacOptions/build.sbt +++ b/src/sbt-test/skip-windows/relax-scalacOptions/build.sbt @@ -1,7 +1,8 @@ val V = _root_.scalafix.sbt.BuildInfo -addCompilerPlugin(scalafixSemanticdb) -scalacOptions ++= Seq("-Yrangepos", "-Ywarn-unused") +semanticdbEnabled := true +semanticdbVersion := scalafixSemanticdb.revision +scalacOptions += "-Ywarn-unused" scalaVersion := V.scala212 Compile / compile / scalacOptions ++= Seq( // generate errors on procedure syntax @@ -25,11 +26,19 @@ TaskKey[Unit]("checkLastCompilationCached") := { val reader = str.readText(streamScopedKey(compileIncScope), None) val lines = IO.readLines(reader) + // in sbt 2.x, zinc may not even be called thanks to the remote cache, so we clear logs + // to silence false positives via `lines.length > 0` in the next invocation + IO.delete((Compile / compileIncremental / streams).value.cacheDirectory) + val cachedCompilationLogEntry = "No changes" - if (lines.forall(line => !line.contains(cachedCompilationLogEntry))) { + if ( + lines.length > 0 && + lines.forall(line => !line.contains(cachedCompilationLogEntry)) + ) { lines.foreach(line => str.log.error(line)) throw new RuntimeException("last compilation was not fully cached") } + lines.foreach(line => str.log.info(line)) } // https://github.com/sbt/sbt/commit/dbb47b3ce822ff7ec25881dadd71a3b29e202273 diff --git a/src/sbt-test/sbt-scalafix/relax-scalacOptions/project/plugins.sbt b/src/sbt-test/skip-windows/relax-scalacOptions/project/plugins.sbt similarity index 100% rename from src/sbt-test/sbt-scalafix/relax-scalacOptions/project/plugins.sbt rename to src/sbt-test/skip-windows/relax-scalacOptions/project/plugins.sbt diff --git a/src/sbt-test/sbt-scalafix/relax-scalacOptions/src/main/scala/IgnoreWarning.scala b/src/sbt-test/skip-windows/relax-scalacOptions/src/main/scala/IgnoreWarning.scala similarity index 100% rename from src/sbt-test/sbt-scalafix/relax-scalacOptions/src/main/scala/IgnoreWarning.scala rename to src/sbt-test/skip-windows/relax-scalacOptions/src/main/scala/IgnoreWarning.scala diff --git a/src/sbt-test/sbt-scalafix/relax-scalacOptions/src/main/scala/UnusedImportAndProcedureSyntax.scala b/src/sbt-test/skip-windows/relax-scalacOptions/src/main/scala/UnusedImportAndProcedureSyntax.scala similarity index 100% rename from src/sbt-test/sbt-scalafix/relax-scalacOptions/src/main/scala/UnusedImportAndProcedureSyntax.scala rename to src/sbt-test/skip-windows/relax-scalacOptions/src/main/scala/UnusedImportAndProcedureSyntax.scala diff --git a/src/sbt-test/sbt-scalafix/relax-scalacOptions/test b/src/sbt-test/skip-windows/relax-scalacOptions/test similarity index 93% rename from src/sbt-test/sbt-scalafix/relax-scalacOptions/test rename to src/sbt-test/skip-windows/relax-scalacOptions/test index 273d23e2..0a8b38e6 100644 --- a/src/sbt-test/sbt-scalafix/relax-scalacOptions/test +++ b/src/sbt-test/skip-windows/relax-scalacOptions/test @@ -6,7 +6,7 @@ > checkLastCompilationCached # ... and indirect scalafix invocation -> clean +> set scalacOptions ++= Seq("just_to_invalidate_any_cache") > Test / scalafix --check RemoveUnused -> checkLastCompilationCached > compile @@ -31,6 +31,7 @@ # confirm that regular compilation succeeds after fixing the last warning > scalafix ProcedureSyntax > compile +-> checkLastCompilationCached # check that regular compilation is cached as usual > compile diff --git a/src/test/scala/scalafix/internal/sbt/Fs.scala b/src/test/scala/scalafix/internal/sbt/Fs.scala index 5be0217b..646cb0b0 100644 --- a/src/test/scala/scalafix/internal/sbt/Fs.scala +++ b/src/test/scala/scalafix/internal/sbt/Fs.scala @@ -1,7 +1,10 @@ package scalafix.internal.sbt -import java.nio.file.{Files, Path, StandardOpenOption} -import scala.collection.JavaConverters._ +import java.nio.file.Files +import java.nio.file.Path +import java.nio.file.StandardOpenOption + +import scala.jdk.CollectionConverters.* class Fs() { val workingDirectory: Path = diff --git a/src/test/scala/scalafix/internal/sbt/JGitCompletionsSuite.scala b/src/test/scala/scalafix/internal/sbt/JGitCompletionsSuite.scala index 54cfe36d..d421ae78 100644 --- a/src/test/scala/scalafix/internal/sbt/JGitCompletionsSuite.scala +++ b/src/test/scala/scalafix/internal/sbt/JGitCompletionsSuite.scala @@ -1,6 +1,6 @@ package scalafix.internal.sbt -import org.eclipse.jgit.api.{Git => JGit} +import org.eclipse.jgit.api.Git as JGit import org.scalatest.funsuite.AnyFunSuite class JGitCompletionsSuite extends AnyFunSuite { diff --git a/src/test/scala/scalafix/internal/sbt/LoggingOutputStreamSuite.scala b/src/test/scala/scalafix/internal/sbt/LoggingOutputStreamSuite.scala index c3a00e28..fca76869 100644 --- a/src/test/scala/scalafix/internal/sbt/LoggingOutputStreamSuite.scala +++ b/src/test/scala/scalafix/internal/sbt/LoggingOutputStreamSuite.scala @@ -2,11 +2,13 @@ package scalafix.internal.sbt import java.io.PrintStream +import scala.collection.mutable + +import sbt.Level +import sbt.Logger + import org.scalatest.funsuite.AnyFunSuite import org.scalatest.matchers.must.Matchers -import sbt.{Level, Logger} - -import scala.collection.mutable class LoggingOutputStreamSuite extends AnyFunSuite with Matchers { diff --git a/src/test/scala/scalafix/internal/sbt/SbtCompletionsSuite.scala b/src/test/scala/scalafix/internal/sbt/SbtCompletionsSuite.scala index 4cd7e2e9..2321e0bb 100644 --- a/src/test/scala/scalafix/internal/sbt/SbtCompletionsSuite.scala +++ b/src/test/scala/scalafix/internal/sbt/SbtCompletionsSuite.scala @@ -1,10 +1,14 @@ package scalafix.internal.sbt -import coursierapi.{MavenRepository, Repository} +import sbt.complete.Parser +import sbt.librarymanagement.ModuleID + +import coursierapi.MavenRepository +import coursierapi.Repository import org.eclipse.jgit.lib.AbbreviatedObjectId import org.scalatest.Tag -import sbt.complete.Parser import org.scalatest.funsuite.AnyFunSuite +import scalafix.interfaces.ScalafixRule class SbtCompletionsSuite extends AnyFunSuite { val fs = new Fs() @@ -23,11 +27,11 @@ class SbtCompletionsSuite extends AnyFunSuite { } git.tag("v0.1.0") - val exampleDependency = { + val exampleDependency: ModuleID = { import sbt._ "ch.epfl.scala" %% "example-scalafix-rule" % "2.0.0-RC1" } - val mainArgs = + val mainArgs: ScalafixInterface = ScalafixInterface( new BlockingCache(), "2.12", @@ -44,9 +48,9 @@ class SbtCompletionsSuite extends AnyFunSuite { ScalafixInterface.defaultLogger, new ScalafixLogger(ScalafixInterface.defaultLogger) ) - val loadedRules = mainArgs.availableRules.toList + val loadedRules: List[ScalafixRule] = mainArgs.availableRules().toList - val defaultParser = new ScalafixCompletions( + val defaultParser: Parser[ShellArgs] = new ScalafixCompletions( workingDirectory = fs.workingDirectory.toAbsolutePath, loadedRules = () => loadedRules, terminalWidth = None, @@ -61,7 +65,7 @@ class SbtCompletionsSuite extends AnyFunSuite { if (name == "all") "" else name - test(name, testTags: _*) { + test(name, testTags*) { val input = " " + option val completions = @@ -86,7 +90,7 @@ class SbtCompletionsSuite extends AnyFunSuite { name: String, testTags: Tag* )(assertArgs: Either[String, ShellArgs] => Unit): Unit = { - test(name, testTags: _*) { + test(name, testTags*) { val input = name val args = Parser.parse(" " + input, parser) assertArgs(args) @@ -220,10 +224,18 @@ class SbtCompletionsSuite extends AnyFunSuite { } checkArgs("--test -f= --rules=Foo", SkipWindows) { args => - assert(args == Left("""Expected non-whitespace character - |--files value(s) must reference existing files or directories in unmanagedSourceDirectories; are you running scalafix on the right project / Configuration? - | --test -f= --rules=Foo - | ^""".stripMargin)) + val sbt1 = + """Expected non-whitespace character + |""".stripMargin + val sbt2 = + """Expected non-whitespace character + |Expected '"' + |""".stripMargin + val tail = + """--files value(s) must reference existing files or directories in unmanagedSourceDirectories; are you running scalafix on the right project / Configuration? + | --test -f= --rules=Foo + | ^""".stripMargin + assert(args == Left(sbt1 + tail) || args == Left(sbt2 + tail)) } checkArgs("--test -f --rules=Foo", SkipWindows) { args => diff --git a/src/test/scala/scalafix/internal/sbt/ScalafixAPISuite.scala b/src/test/scala/scalafix/internal/sbt/ScalafixAPISuite.scala index 4f8e96d4..2cefe6ee 100644 --- a/src/test/scala/scalafix/internal/sbt/ScalafixAPISuite.scala +++ b/src/test/scala/scalafix/internal/sbt/ScalafixAPISuite.scala @@ -1,15 +1,18 @@ package scalafix.internal.sbt -import java.io.{ByteArrayOutputStream, PrintStream} +import java.io.ByteArrayOutputStream +import java.io.PrintStream import java.nio.file.Files -import coursierapi.{MavenRepository, Repository} +import scala.util.Properties + +import sbt.* + +import coursierapi.MavenRepository +import coursierapi.Repository import org.scalactic.source.Position -import sbt._ -import scalafix.interfaces.ScalafixError import org.scalatest.funsuite.AnyFunSuite - -import scala.util.Properties +import scalafix.interfaces.ScalafixError class ScalafixAPISuite extends AnyFunSuite { @@ -17,7 +20,7 @@ class ScalafixAPISuite extends AnyFunSuite { pos: Position ): Unit = { def removeSnapshotInfo(s: String) = - s.replaceAllLiterally( + s.replace( "[info] Using SNAPSHOT artifacts for Scalafix and/or external rules, binary compatibility checks disabled", "" ) From 1a94524c548f7690a4f3718955b22570ae77ba4b Mon Sep 17 00:00:00 2001 From: Brice Jaglin Date: Sat, 22 Mar 2025 21:12:59 +0100 Subject: [PATCH 119/129] cs does not know sbt milestones do not guarantee binary compat --- bin/test-release.sh | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/bin/test-release.sh b/bin/test-release.sh index 45e5c0f8..f948dc9b 100755 --- a/bin/test-release.sh +++ b/bin/test-release.sh @@ -7,6 +7,4 @@ cs resolve \ --sbt-version 1.0 \ --sbt-plugin "ch.epfl.scala:sbt-scalafix:$version" -cs resolve \ - --sbt-version 2.0.0-M4 \ - --sbt-plugin "ch.epfl.scala:sbt-scalafix:$version" +cs resolve "ch.epfl.scala:sbt-scalafix_sbt2.0.0-M4_3:$version" From 3ccaa5b982334f2f8b0aacf4332685b587dc6512 Mon Sep 17 00:00:00 2001 From: Brice Jaglin Date: Fri, 28 Mar 2025 13:30:28 +0100 Subject: [PATCH 120/129] workaround bug on builds handled by sbt 2.0.0-M4 --- build.sbt | 1 + .../SemanticdbCachingWorkaroundPlugin.scala | 32 +++++++++++++++++++ 2 files changed, 33 insertions(+) create mode 100644 src/main/scala-3/scalafix/internal/sbt/SemanticdbCachingWorkaroundPlugin.scala diff --git a/build.sbt b/build.sbt index 2ad5936d..dd58d66a 100644 --- a/build.sbt +++ b/build.sbt @@ -54,6 +54,7 @@ pluginCrossBuild / sbtVersion := { case "2.12" => "1.4.0" case _ => + // remove SemanticdbCachingWorkaroundPlugin when bumping "2.0.0-M4" // bin/test-release.sh } } diff --git a/src/main/scala-3/scalafix/internal/sbt/SemanticdbCachingWorkaroundPlugin.scala b/src/main/scala-3/scalafix/internal/sbt/SemanticdbCachingWorkaroundPlugin.scala new file mode 100644 index 00000000..2bf5d265 --- /dev/null +++ b/src/main/scala-3/scalafix/internal/sbt/SemanticdbCachingWorkaroundPlugin.scala @@ -0,0 +1,32 @@ +import sbt.* +import sbt.Keys.* +import sbt.plugins.JvmPlugin +import sbt.util.CacheImplicits.given + +// https://github.com/sbt/sbt/pull/8086 +object SemanticdbCachingWorkaroundPlugin extends AutoPlugin { + + override def trigger: PluginTrigger = allRequirements + override def requires: Plugins = JvmPlugin + + override lazy val projectSettings: Seq[Def.Setting[?]] = + Seq(Compile, Test).flatMap(c => + inConfig(c)( + compileIncremental := Def.taskIf { + if (semanticdbIncludeInJar.value || !semanticdbEnabled.value) + compileIncremental.value + else compileIncAndCacheSemanticdbTargetRootTask.value + }.value + ) + ) + + private val compileIncAndCacheSemanticdbTargetRootTask = Def.cachedTask { + val prev = compileIncremental.value + val converter = fileConverter.value + val targetRoot = semanticdbTargetRoot.value + + val vfTargetRoot = converter.toVirtualFile(targetRoot.toPath) + Def.declareOutputDirectory(vfTargetRoot) + prev + } +} From 9c86de9fbd194e5b84c3b1903ac9d8a7016a71cc Mon Sep 17 00:00:00 2001 From: "scala-center-steward[bot]" <111975575+scala-center-steward[bot]@users.noreply.github.com> Date: Tue, 1 Apr 2025 00:24:07 +0000 Subject: [PATCH 121/129] Update sbt, scripted-plugin to 1.10.11 --- project/build.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project/build.properties b/project/build.properties index e97b2722..cc68b53f 100644 --- a/project/build.properties +++ b/project/build.properties @@ -1 +1 @@ -sbt.version=1.10.10 +sbt.version=1.10.11 From 1c98afa7d2faa12f906757c9dfb24ae981c6287d Mon Sep 17 00:00:00 2001 From: Brice Jaglin Date: Sat, 12 Apr 2025 10:32:04 +0200 Subject: [PATCH 122/129] fix testing of scalafixDependencies alongside local rules 555d1f3 removed it accidentally --- src/sbt-test/sbt-scalafix/local-rules/build.sbt | 7 +++++-- src/sbt-test/sbt-scalafix/local-rules/test | 2 +- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/sbt-test/sbt-scalafix/local-rules/build.sbt b/src/sbt-test/sbt-scalafix/local-rules/build.sbt index 7b8e3702..b563cceb 100644 --- a/src/sbt-test/sbt-scalafix/local-rules/build.sbt +++ b/src/sbt-test/sbt-scalafix/local-rules/build.sbt @@ -3,8 +3,8 @@ import _root_.scalafix.sbt.{BuildInfo => Versions} inThisBuild( List( scalafixDependencies := List( - // Custom rule cross-published to Maven Central https://github.com/scalacenter/example-scalafix-rule - "ch.epfl.scala" %% "example-scalafix-rule" % "1.4.0" + // CollectHead + "com.github.xuwei-k" %% "scalafix-rules" % "0.6.5" ), resolvers += Resolver.sonatypeRepo("snapshots"), // out of sync with scalafix.sbt.BuildInfo.scala213 on purpose @@ -13,6 +13,7 @@ inThisBuild( ) ) +// LocalSyntacticRule val rules = project .disablePlugins(ScalafixPlugin) .settings( @@ -23,9 +24,11 @@ val rules = project val service = project .dependsOn(rules % ScalafixConfig) .settings( + // SyntacticRule libraryDependencies += "ch.epfl.scala" %% "example-scalafix-rule" % "3.0.0" % ScalafixConfig ) +// SameProjectSyntacticRule val sameproject = project .settings( libraryDependencies += "ch.epfl.scala" %% "scalafix-core" % Versions.scalafixVersion % ScalafixConfig diff --git a/src/sbt-test/sbt-scalafix/local-rules/test b/src/sbt-test/sbt-scalafix/local-rules/test index 15808542..1e072941 100644 --- a/src/sbt-test/sbt-scalafix/local-rules/test +++ b/src/sbt-test/sbt-scalafix/local-rules/test @@ -7,7 +7,7 @@ $ delete rules/src/main/scala/local/NoOp.scala -> service / scalafix LocalSyntacticRule # make sure scalafixDependencies is also honored by running a rule from a remote JAR -> service / scalafix SyntacticRule +> service / scalafix CollectHead # run a rule included from a remote JAR referenced via the Scalafix ivy config > service / scalafix SyntacticRule From 5fe9801937d4290cd1e5c825f6d643f8f9304247 Mon Sep 17 00:00:00 2001 From: Brice Jaglin Date: Sat, 12 Apr 2025 13:24:15 +0200 Subject: [PATCH 123/129] document how local rules can be built with Scala 3 --- .../sbt-scalafix/local-rules/build.sbt | 23 ++++++++++++++++--- .../scala/local/Syntactic.scala} | 0 .../src/{main => test}/scala/local/NoOp.scala | 0 src/sbt-test/sbt-scalafix/local-rules/test | 22 ++++++++++++++---- 4 files changed, 37 insertions(+), 8 deletions(-) rename src/sbt-test/sbt-scalafix/local-rules/rules/src/{test/scala/local/Boom.scala => main/scala/local/Syntactic.scala} (100%) rename src/sbt-test/sbt-scalafix/local-rules/rules/src/{main => test}/scala/local/NoOp.scala (100%) diff --git a/src/sbt-test/sbt-scalafix/local-rules/build.sbt b/src/sbt-test/sbt-scalafix/local-rules/build.sbt index b563cceb..32c996d2 100644 --- a/src/sbt-test/sbt-scalafix/local-rules/build.sbt +++ b/src/sbt-test/sbt-scalafix/local-rules/build.sbt @@ -17,7 +17,9 @@ inThisBuild( val rules = project .disablePlugins(ScalafixPlugin) .settings( - libraryDependencies += "ch.epfl.scala" %% "scalafix-core" % Versions.scalafixVersion, + libraryDependencies += + ("ch.epfl.scala" %% "scalafix-core" % Versions.scalafixVersion) + .cross(CrossVersion.for3Use2_13), libraryDependencies += "joda-time" % "joda-time" % "2.10.6" ) @@ -25,11 +27,26 @@ val service = project .dependsOn(rules % ScalafixConfig) .settings( // SyntacticRule - libraryDependencies += "ch.epfl.scala" %% "example-scalafix-rule" % "3.0.0" % ScalafixConfig + libraryDependencies += + ("ch.epfl.scala" %% "example-scalafix-rule" % "3.0.0") + .cross(CrossVersion.for3Use2_13) % ScalafixConfig ) // SameProjectSyntacticRule val sameproject = project .settings( - libraryDependencies += "ch.epfl.scala" %% "scalafix-core" % Versions.scalafixVersion % ScalafixConfig + libraryDependencies += + ("ch.epfl.scala" %% "scalafix-core" % Versions.scalafixVersion) + .cross(CrossVersion.for3Use2_13) % ScalafixConfig, + // Since sbt 1.10.x (https://github.com/sbt/sbt/pull/7480), scala3-library is not automatically added + // to non-standard configurations, but is needed by the Scala 3 compiler, so it must be added explicitly + // if no dependency brings it implicitly, which is the case here because the only dependency is for3Use2_13. + libraryDependencies ++= { + if (scalaBinaryVersion.value == "3") + Seq( + "org.scala-lang" %% "scala3-library" % scalaVersion.value % ScalafixConfig + ) + else + Nil + } ) diff --git a/src/sbt-test/sbt-scalafix/local-rules/rules/src/test/scala/local/Boom.scala b/src/sbt-test/sbt-scalafix/local-rules/rules/src/main/scala/local/Syntactic.scala similarity index 100% rename from src/sbt-test/sbt-scalafix/local-rules/rules/src/test/scala/local/Boom.scala rename to src/sbt-test/sbt-scalafix/local-rules/rules/src/main/scala/local/Syntactic.scala diff --git a/src/sbt-test/sbt-scalafix/local-rules/rules/src/main/scala/local/NoOp.scala b/src/sbt-test/sbt-scalafix/local-rules/rules/src/test/scala/local/NoOp.scala similarity index 100% rename from src/sbt-test/sbt-scalafix/local-rules/rules/src/main/scala/local/NoOp.scala rename to src/sbt-test/sbt-scalafix/local-rules/rules/src/test/scala/local/NoOp.scala diff --git a/src/sbt-test/sbt-scalafix/local-rules/test b/src/sbt-test/sbt-scalafix/local-rules/test index 1e072941..d883bdbd 100644 --- a/src/sbt-test/sbt-scalafix/local-rules/test +++ b/src/sbt-test/sbt-scalafix/local-rules/test @@ -1,10 +1,12 @@ +# try to run a failing local rule without prior explicit rule compilation +-> service / scalafix LocalSyntacticRule + +# ensure updates to the rule definition is reflected in the next run +$ copy-file rules/src/test/scala/local/NoOp.scala rules/src/main/scala/local/Syntactic.scala > service / scalafix LocalSyntacticRule -# ensure updates to the rule definition (that we make sure compiles first) is reflected in the next run -> rules / Test / compile -$ copy-file rules/src/test/scala/local/Boom.scala rules/src/main/scala/local/Boom.scala -$ delete rules/src/main/scala/local/NoOp.scala --> service / scalafix LocalSyntacticRule +# run a rule defined in ScalafixConfig +> sameproject / scalafix SameProjectSyntacticRule # make sure scalafixDependencies is also honored by running a rule from a remote JAR > service / scalafix CollectHead @@ -12,4 +14,14 @@ $ delete rules/src/main/scala/local/NoOp.scala # run a rule included from a remote JAR referenced via the Scalafix ivy config > service / scalafix SyntacticRule + +# switch all projects to Scala 3 to ... +> set ThisBuild / scalaVersion := "3.6.4" + +# ... test that local rules can be written in Scala 3 ... +> service / scalafix LocalSyntacticRule > sameproject / scalafix SameProjectSyntacticRule + +# ... while still supporting community rules written against Scala 2.13 (until https://github.com/scalacenter/scalafix/issues/2041) +> service / scalafix CollectHead +> service / scalafix SyntacticRule From fd0f76f939a90170476529c55be3d4169a135be2 Mon Sep 17 00:00:00 2001 From: Brice Jaglin Date: Sat, 12 Apr 2025 13:41:06 +0200 Subject: [PATCH 124/129] Scala 3 support was introduced in sbt 1.5 --- src/sbt-test/{sbt-scalafix => skip-sbt1.4}/local-rules/build.sbt | 0 .../local-rules/project/Compat.scala | 0 .../{sbt-scalafix => skip-sbt1.4}/local-rules/project/plugins.sbt | 0 .../rules/src/main/resources/META-INF/services/scalafix.v1.Rule | 0 .../local-rules/rules/src/main/scala/local/Syntactic.scala | 0 .../local-rules/rules/src/test/scala/local/NoOp.scala | 0 .../local-rules/sameproject/src/main/scala/Main.scala | 0 .../src/scalafix/resources/META-INF/services/scalafix.v1.Rule | 0 .../sameproject/src/scalafix/scala/sameproject/NoOp.scala | 0 .../local-rules/service/src/main/scala/Main.scala | 0 src/sbt-test/{sbt-scalafix => skip-sbt1.4}/local-rules/test | 0 11 files changed, 0 insertions(+), 0 deletions(-) rename src/sbt-test/{sbt-scalafix => skip-sbt1.4}/local-rules/build.sbt (100%) rename src/sbt-test/{sbt-scalafix => skip-sbt1.4}/local-rules/project/Compat.scala (100%) rename src/sbt-test/{sbt-scalafix => skip-sbt1.4}/local-rules/project/plugins.sbt (100%) rename src/sbt-test/{sbt-scalafix => skip-sbt1.4}/local-rules/rules/src/main/resources/META-INF/services/scalafix.v1.Rule (100%) rename src/sbt-test/{sbt-scalafix => skip-sbt1.4}/local-rules/rules/src/main/scala/local/Syntactic.scala (100%) rename src/sbt-test/{sbt-scalafix => skip-sbt1.4}/local-rules/rules/src/test/scala/local/NoOp.scala (100%) rename src/sbt-test/{sbt-scalafix => skip-sbt1.4}/local-rules/sameproject/src/main/scala/Main.scala (100%) rename src/sbt-test/{sbt-scalafix => skip-sbt1.4}/local-rules/sameproject/src/scalafix/resources/META-INF/services/scalafix.v1.Rule (100%) rename src/sbt-test/{sbt-scalafix => skip-sbt1.4}/local-rules/sameproject/src/scalafix/scala/sameproject/NoOp.scala (100%) rename src/sbt-test/{sbt-scalafix => skip-sbt1.4}/local-rules/service/src/main/scala/Main.scala (100%) rename src/sbt-test/{sbt-scalafix => skip-sbt1.4}/local-rules/test (100%) diff --git a/src/sbt-test/sbt-scalafix/local-rules/build.sbt b/src/sbt-test/skip-sbt1.4/local-rules/build.sbt similarity index 100% rename from src/sbt-test/sbt-scalafix/local-rules/build.sbt rename to src/sbt-test/skip-sbt1.4/local-rules/build.sbt diff --git a/src/sbt-test/sbt-scalafix/local-rules/project/Compat.scala b/src/sbt-test/skip-sbt1.4/local-rules/project/Compat.scala similarity index 100% rename from src/sbt-test/sbt-scalafix/local-rules/project/Compat.scala rename to src/sbt-test/skip-sbt1.4/local-rules/project/Compat.scala diff --git a/src/sbt-test/sbt-scalafix/local-rules/project/plugins.sbt b/src/sbt-test/skip-sbt1.4/local-rules/project/plugins.sbt similarity index 100% rename from src/sbt-test/sbt-scalafix/local-rules/project/plugins.sbt rename to src/sbt-test/skip-sbt1.4/local-rules/project/plugins.sbt diff --git a/src/sbt-test/sbt-scalafix/local-rules/rules/src/main/resources/META-INF/services/scalafix.v1.Rule b/src/sbt-test/skip-sbt1.4/local-rules/rules/src/main/resources/META-INF/services/scalafix.v1.Rule similarity index 100% rename from src/sbt-test/sbt-scalafix/local-rules/rules/src/main/resources/META-INF/services/scalafix.v1.Rule rename to src/sbt-test/skip-sbt1.4/local-rules/rules/src/main/resources/META-INF/services/scalafix.v1.Rule diff --git a/src/sbt-test/sbt-scalafix/local-rules/rules/src/main/scala/local/Syntactic.scala b/src/sbt-test/skip-sbt1.4/local-rules/rules/src/main/scala/local/Syntactic.scala similarity index 100% rename from src/sbt-test/sbt-scalafix/local-rules/rules/src/main/scala/local/Syntactic.scala rename to src/sbt-test/skip-sbt1.4/local-rules/rules/src/main/scala/local/Syntactic.scala diff --git a/src/sbt-test/sbt-scalafix/local-rules/rules/src/test/scala/local/NoOp.scala b/src/sbt-test/skip-sbt1.4/local-rules/rules/src/test/scala/local/NoOp.scala similarity index 100% rename from src/sbt-test/sbt-scalafix/local-rules/rules/src/test/scala/local/NoOp.scala rename to src/sbt-test/skip-sbt1.4/local-rules/rules/src/test/scala/local/NoOp.scala diff --git a/src/sbt-test/sbt-scalafix/local-rules/sameproject/src/main/scala/Main.scala b/src/sbt-test/skip-sbt1.4/local-rules/sameproject/src/main/scala/Main.scala similarity index 100% rename from src/sbt-test/sbt-scalafix/local-rules/sameproject/src/main/scala/Main.scala rename to src/sbt-test/skip-sbt1.4/local-rules/sameproject/src/main/scala/Main.scala diff --git a/src/sbt-test/sbt-scalafix/local-rules/sameproject/src/scalafix/resources/META-INF/services/scalafix.v1.Rule b/src/sbt-test/skip-sbt1.4/local-rules/sameproject/src/scalafix/resources/META-INF/services/scalafix.v1.Rule similarity index 100% rename from src/sbt-test/sbt-scalafix/local-rules/sameproject/src/scalafix/resources/META-INF/services/scalafix.v1.Rule rename to src/sbt-test/skip-sbt1.4/local-rules/sameproject/src/scalafix/resources/META-INF/services/scalafix.v1.Rule diff --git a/src/sbt-test/sbt-scalafix/local-rules/sameproject/src/scalafix/scala/sameproject/NoOp.scala b/src/sbt-test/skip-sbt1.4/local-rules/sameproject/src/scalafix/scala/sameproject/NoOp.scala similarity index 100% rename from src/sbt-test/sbt-scalafix/local-rules/sameproject/src/scalafix/scala/sameproject/NoOp.scala rename to src/sbt-test/skip-sbt1.4/local-rules/sameproject/src/scalafix/scala/sameproject/NoOp.scala diff --git a/src/sbt-test/sbt-scalafix/local-rules/service/src/main/scala/Main.scala b/src/sbt-test/skip-sbt1.4/local-rules/service/src/main/scala/Main.scala similarity index 100% rename from src/sbt-test/sbt-scalafix/local-rules/service/src/main/scala/Main.scala rename to src/sbt-test/skip-sbt1.4/local-rules/service/src/main/scala/Main.scala diff --git a/src/sbt-test/sbt-scalafix/local-rules/test b/src/sbt-test/skip-sbt1.4/local-rules/test similarity index 100% rename from src/sbt-test/sbt-scalafix/local-rules/test rename to src/sbt-test/skip-sbt1.4/local-rules/test From 5401e6692df381e852a99bd5b4c4e254f1bf773a Mon Sep 17 00:00:00 2001 From: Brice Jaglin Date: Sun, 13 Apr 2025 21:29:39 +0200 Subject: [PATCH 125/129] don't mention scalafix on resolution error if semanticdbVersion is custom --- src/main/scala/scalafix/sbt/ScalafixPlugin.scala | 3 ++- .../sbt-scalafix/unavailable-semanticdb-scalac/test | 6 ++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/src/main/scala/scalafix/sbt/ScalafixPlugin.scala b/src/main/scala/scalafix/sbt/ScalafixPlugin.scala index d3d62d98..51e31765 100644 --- a/src/main/scala/scalafix/sbt/ScalafixPlugin.scala +++ b/src/main/scala/scalafix/sbt/ScalafixPlugin.scala @@ -242,7 +242,8 @@ object ScalafixPlugin extends AutoPlugin { def unapply(id: ModuleID): Option[String] = if ( id.organization == scalafixSemanticdb.organization && - id.name.startsWith(scalafixSemanticdb.name) + id.name.startsWith(scalafixSemanticdb.name) && + id.revision == BuildInfo.scalametaVersion ) Some(id.revision) else None } diff --git a/src/sbt-test/sbt-scalafix/unavailable-semanticdb-scalac/test b/src/sbt-test/sbt-scalafix/unavailable-semanticdb-scalac/test index 7c579208..f909acff 100644 --- a/src/sbt-test/sbt-scalafix/unavailable-semanticdb-scalac/test +++ b/src/sbt-test/sbt-scalafix/unavailable-semanticdb-scalac/test @@ -1,2 +1,8 @@ +# Check if we have an actionable failure -> scalafix > checkLogs + +# Check that we don't output the message if the semanticdbVersion does not come from scalafix +> set ThisBuild / semanticdbVersion := "4.8.5" +-> scalafix +-> checkLogs From e193a592748331baf2384db250c45d4aefb0235f Mon Sep 17 00:00:00 2001 From: Brice Jaglin Date: Tue, 15 Apr 2025 23:34:11 +0200 Subject: [PATCH 126/129] gracefully ignore projects with unsupported binary version - honor skip at project / conf / task levels - rely on that to skip unsupported projects --- .../scala/scalafix/sbt/ScalafixPlugin.scala | 11 ++++- src/sbt-test/sbt-scalafix/skip/.scalafix.conf | 2 + .../sbt-scalafix/skip/project/plugins.sbt | 2 + .../skip/src/main/scala/Null1.scala | 3 ++ .../skip/src/test/scala/Null2.scala | 3 ++ src/sbt-test/sbt-scalafix/skip/test | 41 +++++++++++++++++++ src/sbt-test/skip-sbt1.4/scalafixEnable/test | 5 ++- 7 files changed, 65 insertions(+), 2 deletions(-) create mode 100644 src/sbt-test/sbt-scalafix/skip/.scalafix.conf create mode 100644 src/sbt-test/sbt-scalafix/skip/project/plugins.sbt create mode 100644 src/sbt-test/sbt-scalafix/skip/src/main/scala/Null1.scala create mode 100644 src/sbt-test/sbt-scalafix/skip/src/test/scala/Null2.scala create mode 100644 src/sbt-test/sbt-scalafix/skip/test diff --git a/src/main/scala/scalafix/sbt/ScalafixPlugin.scala b/src/main/scala/scalafix/sbt/ScalafixPlugin.scala index 51e31765..d67bf994 100644 --- a/src/main/scala/scalafix/sbt/ScalafixPlugin.scala +++ b/src/main/scala/scalafix/sbt/ScalafixPlugin.scala @@ -98,6 +98,8 @@ object ScalafixPlugin extends AutoPlugin { def scalafixConfigSettings(config: Configuration): Seq[Def.Setting[?]] = inConfig(config)( relaxScalacOptionsConfigSettings ++ Seq( + config / scalafix / skip := (config / scalafix / skip).value || + Seq("2.10", "2.11").contains(scalaBinaryVersion.value), scalafix := { // force evaluation of keys looked up in the same scope (config) within // dynamic tasks to workaround https://github.com/sbt/sbt/issues/5647 @@ -502,7 +504,14 @@ object ScalafixPlugin extends AutoPlugin { } } } - task.tag(Scalafix) + Def.taskDyn { + if (!(config / scalafix / skip).value) + task.tag(Scalafix) + else + Def.task { + (config / scalafix / streams).value.log.info("Skipping scalafix") + } + } } private def scalafixSyntactic( diff --git a/src/sbt-test/sbt-scalafix/skip/.scalafix.conf b/src/sbt-test/sbt-scalafix/skip/.scalafix.conf new file mode 100644 index 00000000..38073a22 --- /dev/null +++ b/src/sbt-test/sbt-scalafix/skip/.scalafix.conf @@ -0,0 +1,2 @@ +rules = [DisableSyntax] +DisableSyntax.noNulls = true \ No newline at end of file diff --git a/src/sbt-test/sbt-scalafix/skip/project/plugins.sbt b/src/sbt-test/sbt-scalafix/skip/project/plugins.sbt new file mode 100644 index 00000000..2d3b4d3b --- /dev/null +++ b/src/sbt-test/sbt-scalafix/skip/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-scalafix/skip/src/main/scala/Null1.scala b/src/sbt-test/sbt-scalafix/skip/src/main/scala/Null1.scala new file mode 100644 index 00000000..9ee717b0 --- /dev/null +++ b/src/sbt-test/sbt-scalafix/skip/src/main/scala/Null1.scala @@ -0,0 +1,3 @@ +object Null1 { + println(null) +} diff --git a/src/sbt-test/sbt-scalafix/skip/src/test/scala/Null2.scala b/src/sbt-test/sbt-scalafix/skip/src/test/scala/Null2.scala new file mode 100644 index 00000000..b3a573a2 --- /dev/null +++ b/src/sbt-test/sbt-scalafix/skip/src/test/scala/Null2.scala @@ -0,0 +1,3 @@ +object Null2 { + println(null) +} diff --git a/src/sbt-test/sbt-scalafix/skip/test b/src/sbt-test/sbt-scalafix/skip/test new file mode 100644 index 00000000..160d23b5 --- /dev/null +++ b/src/sbt-test/sbt-scalafix/skip/test @@ -0,0 +1,41 @@ +-> scalafix +-> Test / scalafix +-> scalafixAll + +############################## +# Project level +############################## +> set skip := true + +> scalafix +> Test / scalafix +> scalafixAll + +> set skip := false + +############################## +# Task level +############################## +> set scalafix / skip := true + +> scalafix +> Test / scalafix +> scalafixAll + +> set scalafix / skip := false + +############################## +# Config / Task level +############################## +> set Test / scalafix / skip := true + +-> scalafix +> Test / scalafix +-> scalafixAll + +> set Compile / skip := true + +> scalafix +> Test / scalafix +> scalafixAll + diff --git a/src/sbt-test/skip-sbt1.4/scalafixEnable/test b/src/sbt-test/skip-sbt1.4/scalafixEnable/test index f9664229..cb40b128 100644 --- a/src/sbt-test/skip-sbt1.4/scalafixEnable/test +++ b/src/sbt-test/skip-sbt1.4/scalafixEnable/test @@ -13,4 +13,7 @@ # check that we can run a semantic rule against a Scala 3 dialect source file -> scala3 / scalafix --check SemanticRule > scala3 / scalafix SemanticRule -> scala3 / scalafix --check SemanticRule \ No newline at end of file +> scala3 / scalafix --check SemanticRule + +# check that a global, aggregating scalafix is safe as unsupported projects are ignored +> scalafix \ No newline at end of file From 94c8de4417928a9e59b19cc1ef85a9cfff44bbe1 Mon Sep 17 00:00:00 2001 From: Brice Jaglin Date: Wed, 16 Apr 2025 08:56:07 +0200 Subject: [PATCH 127/129] remove redundant explicit config scoping --- src/main/scala/scalafix/sbt/ScalafixPlugin.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/scala/scalafix/sbt/ScalafixPlugin.scala b/src/main/scala/scalafix/sbt/ScalafixPlugin.scala index d67bf994..c4b0e641 100644 --- a/src/main/scala/scalafix/sbt/ScalafixPlugin.scala +++ b/src/main/scala/scalafix/sbt/ScalafixPlugin.scala @@ -98,7 +98,7 @@ object ScalafixPlugin extends AutoPlugin { def scalafixConfigSettings(config: Configuration): Seq[Def.Setting[?]] = inConfig(config)( relaxScalacOptionsConfigSettings ++ Seq( - config / scalafix / skip := (config / scalafix / skip).value || + scalafix / skip := (scalafix / skip).value || Seq("2.10", "2.11").contains(scalaBinaryVersion.value), scalafix := { // force evaluation of keys looked up in the same scope (config) within From 9a94cff23f7351844d09246a00b43e367dea33d3 Mon Sep 17 00:00:00 2001 From: Brice Jaglin Date: Wed, 16 Apr 2025 09:33:06 +0200 Subject: [PATCH 128/129] add debug logs to troubleshoot scalacOptions capturing --- .../scalafix/internal/sbt/ScalafixInterface.scala | 13 +++++++++++-- src/main/scala/scalafix/sbt/ScalafixPlugin.scala | 6 ++++-- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/src/main/scala/scalafix/internal/sbt/ScalafixInterface.scala b/src/main/scala/scalafix/internal/sbt/ScalafixInterface.scala index 4a77c5e3..c3e378a1 100644 --- a/src/main/scala/scalafix/internal/sbt/ScalafixInterface.scala +++ b/src/main/scala/scalafix/internal/sbt/ScalafixInterface.scala @@ -13,7 +13,15 @@ import coursierapi.Repository import scalafix.interfaces.{Scalafix as ScalafixAPI, *} import scalafix.sbt.InvalidArgument -sealed trait Arg extends (ScalafixArguments => ScalafixArguments) +sealed trait Arg extends (ScalafixArguments => ScalafixArguments) { + override def toString: String = + this.getClass.getSimpleName + "(...)" +} + +trait Printable extends Product { + override def toString: String = + this.getClass.getSimpleName + productIterator.mkString("(", ", ", ")") +} object Arg { @@ -74,7 +82,8 @@ object Arg { } case class ScalacOptions(options: Seq[String]) - extends Arg { // FIXME: with CacheKey { + extends Arg + with Printable { // FIXME: with CacheKey { override def apply(sa: ScalafixArguments): ScalafixArguments = sa.withScalacOptions(options.asJava) } diff --git a/src/main/scala/scalafix/sbt/ScalafixPlugin.scala b/src/main/scala/scalafix/sbt/ScalafixPlugin.scala index c4b0e641..ec380d10 100644 --- a/src/main/scala/scalafix/sbt/ScalafixPlugin.scala +++ b/src/main/scala/scalafix/sbt/ScalafixPlugin.scala @@ -733,15 +733,17 @@ object ScalafixPlugin extends AutoPlugin { diffWithPreviousRuns { (cacheKeyArgsChanged, staleTargets) => val errors = if (cacheKeyArgsChanged) { streams.log.info(s"Running scalafix on ${paths.size} Scala sources") + streams.log.debug(s"running ${interface.args}") interface.run() } else { if (staleTargets.nonEmpty) { streams.log.info( s"Running scalafix on ${staleTargets.size} Scala sources (incremental)" ) - interface + val interfaceIncremental = interface .withArgs(Arg.Paths(staleTargets.map(_.toPath).toSeq)) - .run() + streams.log.debug(s"running ${interfaceIncremental.args}") + interfaceIncremental.run() } else { streams.log.debug(s"already ran on ${paths.length} files") Nil From 5bd59f30c806590b0677579a9c670ef1cde7d16d Mon Sep 17 00:00:00 2001 From: Brice Jaglin Date: Thu, 8 May 2025 19:21:02 +0200 Subject: [PATCH 129/129] scalafix 0.14.3 --- project/Dependencies.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project/Dependencies.scala b/project/Dependencies.scala index 76b5fb81..fbc7458a 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -2,7 +2,7 @@ import sbt._ object Dependencies { val x = List(1) // scalafix:ok - def scalafixVersion: String = "0.14.2" + def scalafixVersion: String = "0.14.3" val all = List( "org.eclipse.jgit" % "org.eclipse.jgit" % "5.13.3.202401111512-r",