Open johnynek opened 6 years ago
http://eed3si9n.com/stricter-scala-with-xlint-xfatal-warnings-and-scalafix
@ianoc can you add some comments to what you did? Did you just set up the plugin and some scalac options? Any gotchas? Any particularly great use cases?
Boy this would be nice to have. I don't suppose anyone is going to work on it?
@ianoc has done this. He might explain how. Scalafix is a plug-in and we have scalac plugin support.
The source I could find is pretty old at this point: https://github.com/ianoc/bazel-scalafix
If I understand it right, it uses a wrapper script to run scalafix, that is:
bazel query
This approach seems to be a bit fragile in some places e.g. the detection of source files etc. applies some heuristics.
I don't know if this gets easier now that the SemanticDB support is in place, but it might be. We'd need to look into it a bit more closely.
After taking a quick look at the cli args of scalafix, it seems to me that collecting the classpath is still being required besides having SemanticDB.
I'm thinking if putting a Bazel aspect on _scalac
or some other attribute would be a good idea here, then using that aspect to build a minimal scalafix wrapper script. Then, most of the implementation would go into the aspect, which would just collect all params for scalafix then invoke it. I think the most complex part is the classpath, but we have code in this repo to put that together for scalac; hence it could be reused here as well I guess.
https://eed3si9n.com/automate-refactoring-with-bazel-and-scalafix/
This could be helpful.
Yeah thanks, I was also thinking about having a custom shim to forward args in a file (there will be a "few" if I add all jars, etc). But, if I could, I'd try to avoid having a custom rule, and a separate target for each lib to fix.
So far I managed to write an aspect that fetches all dependent jars, source files to fix and the semantic db target root. I think I could puzzle the rest together in a few days.
I have a version working in our own repo, but I'd like to contribute this back to rules_scala
if there's interest. However, there are a few things to be cleared before I could do so (rough edges):
ctx.actions.run
). This has implications, like a fake "output", as scalafix rewrites the original sources. It uses command-line aspects to do it, so it needs an output group etc. to function. Would it be better to print out the args instead to a file directly then executing scalafix from a wrapper script rather than from within bazel?Also I noted when I turn on semanticdb on the toolchain I get tons of output on each bazel build like:
DT:bazel-out/darwin_arm64-fastbuild/bin/external/io_bazel_rules_scala_scala_library/io_bazel_rules_scala_scala_library.stamp/scala-library-2.12.18-stamped.jar
https://github.com/scalacenter/scalafix
Scalafix is being mentioned in almost every discussion about scala 3, and often about scala 2.14 (and perhaps scala 2.13).
Scala 3 is going to allow a ton of changes which will probably be impossible to migrate by hand large code bases, or you must use scalafix. To get out in front of this, we should show how to do that.
@ianoc has run scalafix with rules_scala at Stripe, and it seems to be just a compiler plugin, so it may be pretty easy, but we should document an example and consider special support to make it easier.
One problem is that it does not totally fit the bazel model since it rewrites the source. Normally baze,l contemplates rules as functions on source to outputs, not updaters to source. Code formatting is another example of this. It could be possible bazel needs to have a new kind of rule: source rewrite, which expects sources to be input and output.