Configuration

Per project

Scalafix reads configuration from a file using HOCON syntax. The convention is to keep a file .scalafix.conf into the root directory of your project. Configuration is not needed or is optional for most rules, so you may not need to create a .scalafix.conf.

rules

Configure which rule to run with rules = [ ... ]. Scalafix comes with a small set of built-in rules.

// Built in rules
rules = [
  ExplicitResultTypes
  RemoveUnusedImports
  RemoveXmlLiterals
  ProcedureSyntax
  DottyVolatileLazyVal
  ExplicitUnit
  DottyVarArgPattern
  NoAutoTupling
  NoValInForComprehension
  Sbt1
  NoInfer
  Disable
  DisableSyntax
  DisableUnless
]

You have several options to load custom rules.

class:

If a scalafix rule is already on the classpath, you can classload it with the scala: protocol.

rule = "class:scalafix.internal.rule.ProcedureSyntax"

file:

If a rule is written in a single file on local disk, you can load it with the file: protocol.

rule = "file:readme/MyRule.scala" // from local file

http:

If a rule is written in a single source file on the internet, you can load it with the https: or http: protocol

rule = "https://gist.githubusercontent.com/olafurpg/fc6f43a695ac996bd02000f45ed02e63/raw/f5fe47495c9b6e3ce0960b766ffa75be6d6768b2/DummyRule.scala"

github:

If a rule is written in a single file and you use GitHub, you can use the github: protocol for sharing your rule

rule = "github:typelevel/cats/v1.0.0"
// expands into "https://raw.githubusercontent.com/typelevel/cats/master/scalafix/rules/src/main/scala/fix/Cats_v1_0_0.scala"

replace:

⚠️ Experimental

To replace usage of one class/object/trait/def with another. Note, does not move definitions like “Move” does in an IDE. This only moves use-sites.

rule = "replace:com.company.App/io.company.App"
// From sbt shell: > scalafix replace:from/to

To rename a method

rule = "replace:com.company.App.start/init"

lint

Override the default severity level of a LintMessage with lint

// Assuming 'Foo' is a rule and 'warningID'/'errorID' are LintCategory IDs.
lint.error = [ Foo.warningID ] // promote Foo.warnigID to an error
lint.warning = [ Foo.errorID ] // demote Foo.errorID to a warning
lint.info = [ Foo.errorID ] // demote Foo.errorID to info
lint.ignore = [ Foo.errorID ] // don't report Foo.errorID
lint.explain = true // print out detailed explanation for lint messages.

patches

For simple use-cases, it’s possible to write custom rules directly in .scalafix.conf.

patches.removeGlobalImports = [
  "scala.collection.mutable" // scala.meta.Importee
]
patches.addGlobalImports = [
  "scala.collection.immutable"
]
patches.replaceSymbols = [
  { from = "scala.collection.mutable.ListBuffer"
    to   = "com.geirsson.mutable.CoolBuffer" }
]
// Helper to see which symbols appear in your source files
debug.printSymbols = true

To build custom rules see Rule Authors.

Per source file

It’s possible to supress false positives linter message over source file regions using comments. This provides fine grained control over what to report

There are two alternative way to supress linter messages with a single expression using scalafix:ok or with scalafix:off/on to toogle until the end of file.

Enable or Disable until the end of file


// scalafix:off
foo(null)
1.asInstanceOf[String]
// scalafix:on

Disable for an expression

List(1, "") // scalafix:ok

Selectively disabling rules

Both technique above can selectively disable a list of rules. You can provide the list of rules to be disabled, separated by ,.

// scalafix:off Disable.null, Disable.asInstanceOf
foo(null)
1.asInstanceOf[String]
// scalafix:on
List(1, "") // scalafix:ok NoInfer.any