diff --git a/src/main/scala/scalafix/sbt/ScalafixPlugin.scala b/src/main/scala/scalafix/sbt/ScalafixPlugin.scala index e118d5d2..c3fb00ef 100644 --- a/src/main/scala/scalafix/sbt/ScalafixPlugin.scala +++ b/src/main/scala/scalafix/sbt/ScalafixPlugin.scala @@ -23,7 +23,6 @@ object ScalafixPlugin extends AutoPlugin { override def requires: Plugins = JvmPlugin object autoImport { - @deprecated("not used internally, use your own tag", "0.9.17") val Scalafix = Tags.Tag("scalafix") val ScalafixConfig = config("scalafix") @@ -207,7 +206,8 @@ object ScalafixPlugin extends AutoPlugin { scalafixInterfaceCache := new BlockingCache[ ToolClasspath, ScalafixInterface - ] + ], + concurrentRestrictions += Tags.exclusiveGroup(Scalafix) ) override def buildSettings: Seq[Def.Setting[_]] = @@ -324,8 +324,8 @@ object ScalafixPlugin extends AutoPlugin { private def scalafixTask( shellArgs: ShellArgs, config: ConfigKey - ): Def.Initialize[Task[Unit]] = - Def.taskDyn { + ): Def.Initialize[Task[Unit]] = { + val task = Def.taskDyn { val errorLogger = new PrintStream( LoggingOutputStream( @@ -375,6 +375,9 @@ object ScalafixPlugin extends AutoPlugin { } } } + task.tag(Scalafix) + } + private def scalafixHelp: Def.Initialize[Task[Unit]] = Def.task { scalafixInterfaceProvider diff --git a/src/sbt-test/sbt-scalafix/concurrency/build.sbt b/src/sbt-test/sbt-scalafix/concurrency/build.sbt new file mode 100644 index 00000000..70da10b8 --- /dev/null +++ b/src/sbt-test/sbt-scalafix/concurrency/build.sbt @@ -0,0 +1,33 @@ +val V = _root_.scalafix.sbt.BuildInfo + +scalaVersion := V.scala212 +libraryDependencies += "ch.epfl.scala" %% "scalafix-core" % V.scalafixVersion % ScalafixConfig + +// make it possible to run scalafix in parallel with other tasks via the `all` command +// (work around "Cannot mix input tasks with plain tasks/settings") +val scalafixAddFooter = taskKey[Unit]("task wrapping scalafix") + +val addHeader = taskKey[Unit]("") + +val check = taskKey[Unit]("") + +inConfig(Compile)( + Seq( + scalafixAddFooter := scalafix.toTask(" --rules=class:fix.AddFooter").value, + addHeader := { + unmanagedSources.value.foreach { file => + val content = IO.read(file) + // artificial delay between read/parsing and write/patching to exercise concurrency + Thread.sleep(10000) + IO.write(file, s"// HEADER\n$content") + } + }, + check := { + unmanagedSources.value.foreach { file => + val content = IO.read(file) + assert(content.contains("FOOTER"), s"missing footer in\n<<<$content>>>") + assert(content.contains("HEADER"), s"missing header in\n<<<$content>>>") + } + } + ) +) diff --git a/src/sbt-test/sbt-scalafix/concurrency/project/plugins.sbt b/src/sbt-test/sbt-scalafix/concurrency/project/plugins.sbt new file mode 100644 index 00000000..2d3b4d3b --- /dev/null +++ b/src/sbt-test/sbt-scalafix/concurrency/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/concurrency/src/main/scala/example/Example.scala b/src/sbt-test/sbt-scalafix/concurrency/src/main/scala/example/Example.scala new file mode 100644 index 00000000..9786491f --- /dev/null +++ b/src/sbt-test/sbt-scalafix/concurrency/src/main/scala/example/Example.scala @@ -0,0 +1 @@ +object Example diff --git a/src/sbt-test/sbt-scalafix/concurrency/src/scalafix/scala/fix/AddFooter.scala b/src/sbt-test/sbt-scalafix/concurrency/src/scalafix/scala/fix/AddFooter.scala new file mode 100644 index 00000000..720c3361 --- /dev/null +++ b/src/sbt-test/sbt-scalafix/concurrency/src/scalafix/scala/fix/AddFooter.scala @@ -0,0 +1,11 @@ +package fix + +import scalafix.v1._ + +class AddFooter extends SyntacticRule("AddFooter") { + override def fix(implicit doc: SyntacticDocument): Patch = { + // artificial delay between read/parsing and write/patching to exercise concurrency + Thread.sleep(1000) + Patch.addRight(doc.tree, "\n// FOOTER\n") + } +} diff --git a/src/sbt-test/sbt-scalafix/concurrency/test b/src/sbt-test/sbt-scalafix/concurrency/test new file mode 100644 index 00000000..658742cd --- /dev/null +++ b/src/sbt-test/sbt-scalafix/concurrency/test @@ -0,0 +1,5 @@ +# warm up so that tasks themselves (not their dependencies) run in parallel +> scalafix:compile + +> all addHeader scalafixAddFooter +> check \ No newline at end of file