To develop custom scalafix rules, you will first need to create an sbt project.
Run the following commands to generate a skeleton project:
cd reponame # The project you want to implement rules for. # --rule= should ideally match the GitHub repo name, to make # it possible for users to run `scalafix "github:org/reponame/v1.0"` sbt new scalacenter/scalafix.g8 --rule="reponame" --version="v1.0" cd scalafix sbt tests/test
Note that the
scalafix directory is a self-contained sbt build and can be put into the root directory of your repo. The tests are written using scalafix-testkit.
scalafix-testkit is a module to help you write/run/debug/test scalafix rules.
The scalacenter/scalafix.g8 template boilerplate already setups a project which uses scalafix-testkit.
The anatomy of a scalafix-testkit project is like this
scalafix ├── rules // rule implementations ├── input // code that runs through rule ├── output // expected output from running input on rules └── tests // tiny project where unit tests run
scalafix-testkit features include:
Input code for rules and expected output is written in plain .scala files, with full IDE support.
Input and expected output files are kept in two separate sbt projects. Each project can have its own set of dependencies.
Each individual *.scala file in the input project can have a custom .scalafix.conf configuration provided in a comment at the top of the file.
Test failures are reported as unified diffs from the obtained output of the rule and the expected output in the
Assert that a LintMessage is expected at a particular line by suffixing the line with the comment
// assert: <LintCategory>. For an example, see the NoInfer test suite:
val x = List(1, "")// assert: NoInfer.any
It’s also possible to assert the offset position and the message contents with a multiline comment:
Option(1).get /* assert: Disable.get ^ Option.get is the root of all evils If you must Option.get, wrap the code block with // scalafix:off Option.get ... // scalafix:on Option.get */
- The test can fail if:
- An assert was added but it was not reported by the linter (unreported)
- A lint message was reported but it was not asserted (unexpected)
- An assert was added and a message was reported on that line but it does not match the message exactly. For example the offset can be wrong by a few column or you can have a typo in your assert message.