2
votes

I want my scalacSettings to be more strict (more linting) when I issue my own command validate.

What is the best way to achieve that?

A new scope (strict) did work, but it requires to compile the project two times when you issue test. So that's not a option.

1
Did you try something like this scalacSettings in validate ++= Seq(...)? - Ivan Stanislavciuc
validate is not a scope, but a command alias: private def cmdAlias(name: String, commands: List[String]) = addCommandAlias(name, s";${commands.mkString(";")}") cmdAlias("validateCoverage", scalafmtCheckAlias ++ coverageAlias) - Mark
Not sure about aliases in the way you use it. Can you convert validate into a task and try? - Ivan Stanislavciuc
validate is being used when we run a build in CI and should lint strictly. While developing the compile settings are less restrictive and therefore not intrusive. I don't want to be bothered with unused imports compile errors while developing a new feature :-) - Mark

1 Answers

1
votes

SBT custom command allows for temporary modification of build state which can be discarded after command finishes:

def validate: Command = Command.command("validate") { state =>
  import Project._
  val stateWithStrictScalacSettings =
    extract(state).appendWithSession(
      Seq(Compile / scalacOptions ++= Seq(
        "-Ywarn-unused:imports",
        "-Xfatal-warnings",
        "...",
      ))
      ,state
    )

  val (s, _) = extract(stateWithStrictScalacSettings).runTask(Test / test, stateWithStrictScalacSettings)
  s
}

commands ++= Seq(validate)

or more succinctly using :: convenience method for State transformations:

commands += Command.command("validate") { state =>
  """set scalacOptions in Compile := Seq("-Ywarn-unused:imports", "-Xfatal-warnings", "...")""" :: 
  "test" :: state
} 

This way we can use sbt test during development, while our CI hooks into sbt validate which uses stateWithStrictScalacSettings.