In the past we reviewed what is static code analysis and made a deep dive into static code analysis tools and now is the time to review Scala static analysis tools.
We also saw in the last couple of months the apparition of a few new ones from Databricks and Paypal or the great Scala Best Practices that we didn’t mention.
Leif Wickland said “If your coding standard isn’t automatically and uniformly applied, you don’t have a coding standard” and I couldn’t agree more. At Codacy we believe that the enforcement of those guidelines should be outsourced to tools, and today we are going to review the main static analysis and linters that exist.
ScalaStyle
Actively developed by Matthew Farwell, Scalastyle is probably the most popular tool. It has an extensive list of checks, a good documentation and is used by all the students of Martin Odersky Class on Coursera.
One of the biggest advantages of Scalastyle is also it’s possibility to adapt to different workflows. Besides the command line, you can run ScalaStyle as a compiler plugin (SBT, Maven and Gradle are supported) or you can integrate it in your IDE (IntelliJ or Eclipse).
ScalaStyle covers issues ranging from code style to best practices.
Here a few examples of ScalaStyle rules:
- Checks that null is not used
- Checks that return is not used
- Checks for boolean expressions that can be simplified
- Checks that functions do not define mutable variables
- Checks that while is not used
- Check the number of lines in a file
- etc.
A full list of the 60 rules can be found here: http://www.scalastyle.org/rules-0.7.0.html
You can also easily add your own custom rules.
ScalaStyle is the way to go if you’re looking for a well-rounded tool to enforce style and best practices.
Visit the scalastyle website, and feel free to integrate it with the flavor of your choice (Maven, Eclipse, SBT, etc).
If you are familiar with SBT, follow the next steps so you can experience its beauty!
Add the following lines to project/plugins.sbt
addSbtPlugin("org.scalastyle" %% "scalastyle-sbt-plugin" % "0.7.0")
resolvers += "sonatype-releases" at https://oss.sonatype.org/content/repositories/releases/"
Create a configuration file
Get the default configuration file configuration.xml, inspect it and feel free to change it as you like. (To know more about the configuration file, visit http://www.scalastyle.org/configuration.html)
For each check you have something like this:
<check level="warning" class="org.scalastyle.file.WhitespaceEndOfLineChecker" enabled="true"/>
A wise man once said "You can't please everyone", and that's why these tools usually have a lot of customization built-in, if you don't like a pattern just change it to enable="false".
Usage
sbt scalastyle
And just like that, you’ll have your results at target/scalastyle-result.xml!
WartRemover
Wartremover is maintained by Brian McKenna. It covers a great list of warts and is well documented. Note that there are several names when referring to the checks in static code analysis. The most common are checks, patterns, and more often than not, a reference to the tool name itself. In WartRemover, the checks are called warts.
Customization is treated as a first-class feature as you can easily extend the tool.
Here are a few examples of the WartRemover warts:
- Avoid usage of Any & Nothing
- Avoid asInstanceOf & isInstanceOf
- Avoid usage of Monads
- Avoid usage of return
- Avoid option.get
- etc.
Once again, follow our instructions to try WartRemover
Add the following lines to project/plugins.sbt
addSbtPlugin("org.brianmckenna" % "sbt-wartremover" % "0.14")
Configuration
In WartRemover the configuration is done in the plugins.sbt, check https://github.com/puffnfresh/wartremover#usage for more details. In this example we show how can you have all Warts enabled except for a couple you would want to disable.
Add to the plugins.sbt:
wartremoverErrors ++= Warts.allBut(Wart.Enumeration, Wart.FinalCaseClass)
For all the available warts, check https://github.com/puffnfresh/wartremover#warts
Usage
sbt compile
This tool is integrated in the SBT compilation process, just compile your code using SBT, and it will show you all the errors/issues!
Abide
Abide was created by Nicolas Voirol and is maintained (less actively than the others) by Typesafe. Abide is a tool that aims to provide users with a simple framework for lint-like rule creation and verification. Abide rules are designed as small, self-contained units of logic which abstract concerns such as traversal and optimization away from the rule writer.
Abide has not yet been released. But it is a really great tool, and would deserve a blog post just to itself. It may be a more complex tool to start, but really worth once you get it right!
If you are interested, check scala-abide at github, and follow their great documentation.
Other great tools
Scapegoat – Scapegoat is maintained by Stephen Samuel, and is another great tool with SBT integration. The configuration and usage is similar to the other tools, and it’s well documented. We recommend you to check the Scapegoat Inspections, and see if they suit your projects.
Linter – Linter is maintained by Matic Potočnik. As the other tools, it supports SBT integration, and you should take a look at the list of implemented checks and their nice code examples of the reported warnings.
Which one should I use?
Ultimately, this is a personal choice depending on the needs of the project you are working on. Quoting Scapegoat’s documentation, “There’s no problems running multiple analysis tools on the same codebase. In fact it could be beneficial as the total set of possible warnings is the union of the inspections of all the enabled tools. The worst case is that the same warnings might be generated by multiple tools”.
So you probably want to combine more than one tool to cover a wide range of possible errors and to ensure that your code remains clean and consistent. However, one of the bigger criteria to choose is their workflow integration. If it disrupts your development process you will probably quickly stop checking the results. So make sure you integrate it where it makes more sense for you: IDE, pre-commit hook, continuous integration tool etc.
Shameless Plug: If you’re looking for a tool that makes it easier to enforce your coding standard, without you having to manually configure everything locally you should take a look at Codacy. We apply several of the above-mentioned tools plus our own rules in a continuous manner to save you time in code reviews and help you merge with confidence. The documentation that we have on every issue makes it also easier to improve your skills and onboard developers faster to the Scala Magic.
Conclusion
You can find several active and well-documented Scala static analysis tools to analyze your code and guide you through your development process. You can enforce strict standards, manage complexity and detect semantic problems, which is undeniably of a great help. If your team is developing in Scala without any of those, you should definitely give it a try. Don’t be scared by the number of issues!! Start small by deactivating a lot of checks and increase slowly over time. Let me know how it goes in the comments and happy scala coding!