tindzk / seed

Build tool for Scala projects
https://tindzk.github.io/seed/
Apache License 2.0
238 stars 13 forks source link

Find a way to have scalafix working #101

Closed vascorsd closed 2 years ago

vascorsd commented 4 years ago

I've spent too many hours already trying to be able to call and use scalafix directly from the command line as any sane cli application should be able to. At this point I'm convinced it's almost impossible to simply use that tool without some kind of integration in the build tool. I'd like to be proven wrong if that's possible. So it would be nice to see if it's possible or not to have it working with seed, documentation, examples or needed additions to the tool for it to work.

I have an example project here - https://github.com/vascorsd/ineninaru

The pains points I've found are the following at least:

Some examples runs:

scalafix-jvm --scala-version "2.13.2" --auto-classpath --stdout --check --verbose --tool-classpath ".scalafix-rules/https/repo1.maven.org/maven2/com/github/vovapolu/scaluzzi_2.12/0.1.7/scaluzzi_2.12-0.1.7.jar:.scalafix-rules/https/repo1.maven.org/maven2/com/github/liancheng/organize-imports_2.12/0.2.1/organize-imports_2.12-0.2.1.jar:.scalafix-rules/https/repo1.maven.org/maven2/org/scala-lang/scala-library/2.12.11/scala-library-2.12.11.jar:.scalafix-rules/https/repo1.maven.org/maven2/ch/epfl/scala/scalafix-core_2.12/0.9.15/scalafix-core_2.12-0.9.15.jar:.scalafix-rules/https/repo1.maven.org/maven2/org/scalameta/scalameta_2.12/4.3.8/scalameta_2.12-4.3.8.jar:.scalafix-rules/https/repo1.maven.org/maven2/com/googlecode/java-diff-utils/diffutils/1.3.0/diffutils-1.3.0.jar:.scalafix-rules/https/repo1.maven.org/maven2/com/geirsson/metaconfig-typesafe-config_2.12/0.9.10/metaconfig-typesafe-config_2.12-0.9.10.jar:.scalafix-rules/https/repo1.maven.org/maven2/org/scalameta/parsers_2.12/4.3.8/parsers_2.12-4.3.8.jar:.scalafix-rules/https/repo1.maven.org/maven2/org/scala-lang/scalap/2.12.11/scalap-2.12.11.jar:.scalafix-rules/https/repo1.maven.org/maven2/com/geirsson/metaconfig-core_2.12/0.9.10/metaconfig-core_2.12-0.9.10.jar:.scalafix-rules/https/repo1.maven.org/maven2/com/typesafe/config/1.2.1/config-1.2.1.jar:.scalafix-rules/https/repo1.maven.org/maven2/org/scalameta/trees_2.12/4.3.8/trees_2.12-4.3.8.jar:.scalafix-rules/https/repo1.maven.org/maven2/org/scala-lang/scala-compiler/2.12.11/scala-compiler-2.12.11.jar:.scalafix-rules/https/repo1.maven.org/maven2/org/typelevel/paiges-core_2.12/0.3.0/paiges-core_2.12-0.3.0.jar:.scalafix-rules/https/repo1.maven.org/maven2/org/scala-lang/modules/scala-collection-compat_2.12/2.1.2/scala-collection-compat_2.12-2.1.2.jar:.scalafix-rules/https/repo1.maven.org/maven2/com/lihaoyi/pprint_2.12/0.5.9/pprint_2.12-0.5.9.jar:.scalafix-rules/https/repo1.maven.org/maven2/org/scalameta/common_2.12/4.3.8/common_2.12-4.3.8.jar:.scalafix-rules/https/repo1.maven.org/maven2/com/thesamet/scalapb/scalapb-runtime_2.12/0.9.7/scalapb-runtime_2.12-0.9.7.jar:.scalafix-rules/https/repo1.maven.org/maven2/org/scalameta/fastparse_2.12/1.0.1/fastparse_2.12-1.0.1.jar:.scalafix-rules/https/repo1.maven.org/maven2/org/scala-lang/scala-reflect/2.12.11/scala-reflect-2.12.11.jar:.scalafix-rules/https/repo1.maven.org/maven2/org/scala-lang/modules/scala-xml_2.12/1.0.6/scala-xml_2.12-1.0.6.jar:.scalafix-rules/https/repo1.maven.org/maven2/com/lihaoyi/fansi_2.12/0.2.9/fansi_2.12-0.2.9.jar:.scalafix-rules/https/repo1.maven.org/maven2/com/lihaoyi/sourcecode_2.12/0.2.1/sourcecode_2.12-0.2.1.jar:.scalafix-rules/https/repo1.maven.org/maven2/com/thesamet/scalapb/lenses_2.12/0.9.7/lenses_2.12-0.9.7.jar:.scalafix-rules/https/repo1.maven.org/maven2/com/google/protobuf/protobuf-java/3.8.0/protobuf-java-3.8.0.jar:.scalafix-rules/https/repo1.maven.org/maven2/com/lihaoyi/fastparse_2.12/2.1.3/fastparse_2.12-2.1.3.jar:.scalafix-rules/https/repo1.maven.org/maven2/org/scalameta/fastparse-utils_2.12/1.0.1/fastparse-utils_2.12-1.0.1.jar" --scalac-options '-feature -Wunused'
error: The Scala compiler option "-Ywarn-unused" is required to use OrganizeImports with "OrganizeImports.removeUnused" set to true. To fix this problem, update your build to use at least one Scala compiler option that starts with -Ywarn-unused or -Wunused (2.13 only)
scalafix-jvm --scala-version "2.13.2" --auto-classpath --stdout --check --verbose --tool-classpath ".scalafix-rules/https/repo1.maven.org/maven2/com/github/vovapolu/scaluzzi_2.12/0.1.7/scaluzzi_2.12-0.1.7.jar:.scalafix-rules/https/repo1.maven.org/maven2/com/github/liancheng/organize-imports_2.12/0.2.1/organize-imports_2.12-0.2.1.jar:.scalafix-rules/https/repo1.maven.org/maven2/org/scala-lang/scala-library/2.12.11/scala-library-2.12.11.jar:.scalafix-rules/https/repo1.maven.org/maven2/ch/epfl/scala/scalafix-core_2.12/0.9.15/scalafix-core_2.12-0.9.15.jar:.scalafix-rules/https/repo1.maven.org/maven2/org/scalameta/scalameta_2.12/4.3.8/scalameta_2.12-4.3.8.jar:.scalafix-rules/https/repo1.maven.org/maven2/com/googlecode/java-diff-utils/diffutils/1.3.0/diffutils-1.3.0.jar:.scalafix-rules/https/repo1.maven.org/maven2/com/geirsson/metaconfig-typesafe-config_2.12/0.9.10/metaconfig-typesafe-config_2.12-0.9.10.jar:.scalafix-rules/https/repo1.maven.org/maven2/org/scalameta/parsers_2.12/4.3.8/parsers_2.12-4.3.8.jar:.scalafix-rules/https/repo1.maven.org/maven2/org/scala-lang/scalap/2.12.11/scalap-2.12.11.jar:.scalafix-rules/https/repo1.maven.org/maven2/com/geirsson/metaconfig-core_2.12/0.9.10/metaconfig-core_2.12-0.9.10.jar:.scalafix-rules/https/repo1.maven.org/maven2/com/typesafe/config/1.2.1/config-1.2.1.jar:.scalafix-rules/https/repo1.maven.org/maven2/org/scalameta/trees_2.12/4.3.8/trees_2.12-4.3.8.jar:.scalafix-rules/https/repo1.maven.org/maven2/org/scala-lang/scala-compiler/2.12.11/scala-compiler-2.12.11.jar:.scalafix-rules/https/repo1.maven.org/maven2/org/typelevel/paiges-core_2.12/0.3.0/paiges-core_2.12-0.3.0.jar:.scalafix-rules/https/repo1.maven.org/maven2/org/scala-lang/modules/scala-collection-compat_2.12/2.1.2/scala-collection-compat_2.12-2.1.2.jar:.scalafix-rules/https/repo1.maven.org/maven2/com/lihaoyi/pprint_2.12/0.5.9/pprint_2.12-0.5.9.jar:.scalafix-rules/https/repo1.maven.org/maven2/org/scalameta/common_2.12/4.3.8/common_2.12-4.3.8.jar:.scalafix-rules/https/repo1.maven.org/maven2/com/thesamet/scalapb/scalapb-runtime_2.12/0.9.7/scalapb-runtime_2.12-0.9.7.jar:.scalafix-rules/https/repo1.maven.org/maven2/org/scalameta/fastparse_2.12/1.0.1/fastparse_2.12-1.0.1.jar:.scalafix-rules/https/repo1.maven.org/maven2/org/scala-lang/scala-reflect/2.12.11/scala-reflect-2.12.11.jar:.scalafix-rules/https/repo1.maven.org/maven2/org/scala-lang/modules/scala-xml_2.12/1.0.6/scala-xml_2.12-1.0.6.jar:.scalafix-rules/https/repo1.maven.org/maven2/com/lihaoyi/fansi_2.12/0.2.9/fansi_2.12-0.2.9.jar:.scalafix-rules/https/repo1.maven.org/maven2/com/lihaoyi/sourcecode_2.12/0.2.1/sourcecode_2.12-0.2.1.jar:.scalafix-rules/https/repo1.maven.org/maven2/com/thesamet/scalapb/lenses_2.12/0.9.7/lenses_2.12-0.9.7.jar:.scalafix-rules/https/repo1.maven.org/maven2/com/google/protobuf/protobuf-java/3.8.0/protobuf-java-3.8.0.jar:.scalafix-rules/https/repo1.maven.org/maven2/com/lihaoyi/fastparse_2.12/2.1.3/fastparse_2.12-2.1.3.jar:.scalafix-rules/https/repo1.maven.org/maven2/org/scalameta/fastparse-utils_2.12/1.0.1/fastparse-utils_2.12-1.0.1.jar" --scalac-options "-feature" --scalac-options "-Wunused"
info: Processing (0/4) /home/diaz/dev/personal/scala/ineninaru/src/server/configuration/Configuration.scala
error: error while loading Object, Missing dependency 'object scala.native in compiler mirror', required by /modules/java.base/java/lang/Object.class
error: SemanticDB not found: src/server/configuration/Configuration.scala
info: Processing (1/4) /home/diaz/dev/personal/scala/ineninaru/src/server/IneninaruServer.scala
error: SemanticDB not found: src/server/IneninaruServer.scala
info: Processing (2/4) /home/diaz/dev/personal/scala/ineninaru/src/client/IneninaruClient.scala
error: SemanticDB not found: src/client/IneninaruClient.scala
info: Processing (3/4) /home/diaz/dev/personal/scala/ineninaru/src/protocol/proto.scala
error: SemanticDB not found: src/protocol/proto.scala
tindzk commented 4 years ago

Thanks for providing the test project! I checked out your repository to /tmp/ineninaru. When I change the build.toml as follows, the plug-in creates the SemanticDB files which scalafix complained about:

diff --git a/build.toml b/build.toml
index 8333d6e..4582a76 100644
--- a/build.toml
+++ b/build.toml
@@ -29,8 +29,11 @@ scalaOptions = [
     "-Xlint:private-shadow",
     "-Xlint:type-parameter-shadow",

-#    "-P:semanticdb:sourceroot:.",
-#    "-P:semanticdb:targetroot:./build/semanticdb",
+    "-P:semanticdb:synthetics:on",
+    "-P:semanticdb:failures:warning",
+    "-P:semanticdb:sourceroot:/tmp/ineninaru/",
+    "-P:semanticdb:targetroot:/tmp/ineninaru/build/semanticdb",
+    "-Xplugin-require:semanticdb"
 ]
 testFrameworks = ["utest.runner.Framework"]

I got the settings from here. You were using relative paths. Since the Bloop server runs from a different folder, the current working directory does not point to your project. Ideally, SemanticDB should report an error if it did not find any Scala files.

With the following steps:

seed bloop

bloop compile client server

coursier bootstrap ch.epfl.scala:scalafix-cli_2.12.11:0.9.15 -f --main scalafix.cli.Cli -o scalafix

TOOL_CLASSPATH="$(
  coursier fetch --cache .scalafix-rules \
    com.github.vovapolu:scaluzzi_2.12:0.1.7 \
    com.github.liancheng:organize-imports_2.12:0.2.1 \
    -p
)"

./scalafix --tool-classpath "$TOOL_CLASSPATH" \
  --scalac-options "-Ywarn-unused" \
  --auto-classpath \
  --check \
  --verbose \
  --stdout

The final output was:

info: Processing (0/4) /tmp/ineninaru/src/server/configuration/Configuration.scala
--- /tmp/ineninaru/src/server/configuration/Configuration.scala
+++ <expected fix>
@@ -1,7 +1,7 @@
 package configuration

-import ciris._
 import cats.implicits._
+import ciris._

 final case class Configuration private (
     serverHost: String,
info: Processing (1/4) /tmp/ineninaru/src/server/IneninaruServer.scala
/tmp/ineninaru/src/server/IneninaruServer.scala:15:39: error: [Disable.getMessage] Untrusted third party library must be called from IO, or blessed in scalafix.conf
        .tapError(err => putStrLn(err.getMessage))
                                      ^^^^^^^^^^
/tmp/ineninaru/src/server/IneninaruServer.scala:11:6: error: [Disable.Any] Any is disabled and it got inferred as `*(CanFail.canFail[Any])`
    (for {
     ^
/tmp/ineninaru/src/server/IneninaruServer.scala:13:7: error: [Disable.Any] Any is disabled and it got inferred as `*(CanFail.canFail[Any]).flatMap[Console, Throwable, Unit]({() => *.map[Unit]({() => *})})`
      conf <- Configuration.definition
      ^
/tmp/ineninaru/src/server/IneninaruServer.scala:13:15: error: [Disable.Any] Any is disabled and it got inferred as `*(catz.taskConcurrentInstance[Any], catz.zioContextShift[Any, Throwable])`
      conf <- Configuration.definition
              ^
/tmp/ineninaru/src/server/IneninaruServer.scala:13:15: error: [Disable.Any] Any is disabled and it got inferred as `*(catz.taskConcurrentInstance[Any], catz.zioContextShift[Any, Throwable])`
      conf <- Configuration.definition
              ^
info: Processing (2/4) /tmp/ineninaru/src/protocol/proto.scala
--- /tmp/ineninaru/src/protocol/proto.scala
+++ <expected fix>
@@ -1,3 +1,3 @@
 package ineninaru

-case class HiMome(say: String)
+final case class HiMome(say: String)
info: Processing (3/4) /tmp/ineninaru/src/client/IneninaruClient.scala