Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Automatically run scalafmtSbt on reload #2

Open
olafurpg opened this issue Jun 10, 2018 · 1 comment
Open

Automatically run scalafmtSbt on reload #2

olafurpg opened this issue Jun 10, 2018 · 1 comment
Labels
help wanted Extra attention is needed

Comments

@olafurpg
Copy link
Member

Originally reported by @ches in scalameta/scalafmt#1208

  • Version: 1.6.0-RC1
  • Integration: sbt-scalafmt

Problem

sbt-scalafmt can keep project source formatted with scalafmtOnCompile, but needs a separate step of scalafmtSbt to maintain formatting of the build too.

Through some tricks, neo-sbt-scalafmt made it possible to have automatic formatting of sbt build files when sbt (re)loaded, if scalafmtOnCompile := true was set in the root and the meta build e.g. project/build.sbt.

Expectation

A means of keeping build files in compliance with project standards without need to remember a separate scalafmtSbt, or frustrating contributors with scalafmtSbtCheck failing CI.

Workaround

I haven't played around with onLoad to try to get something working with the current plugin yet, I'll share if something pans out.

Notes

I can understand if sbt-scalafmt maintainers don't feel this is worthwhile and want to close it. It's a nice-to-have after getting used to it with the neo plugin.

@rtoomey-coatue
Copy link

rtoomey-coatue commented Dec 6, 2019

Crude POC using Global / onLoad with sbt 1.3.x - done in my own project as an autoplugin. Has "double pass" behavior if changes are detected:

import sbt.{ Def, _ }
import Keys._
import org.scalafmt.sbt.ScalafmtPlugin

// https://www.scala-sbt.org/1.x/docs/Howto-Startup.html
object ScalafmtOnLoad extends AutoPlugin {
  override def requires = ScalafmtPlugin
  override def trigger  = AllRequirements

  // This prepends the String you would type into the shell
  lazy val startupTransition: State => State = { s: State =>
    "scalafmtSbt" :: s
  }

  override def globalSettings: Seq[Def.Setting[_]] = Seq(
    // onLoad is scoped to Global because there's only one.
    Global / onLoad := {
      val old = (Global / onLoad).value
      // compose the new transition on top of the existing one
      // in case your plugins are using this hook.
      startupTransition.compose(old)
    }
  )
}

Note that I excluded ScalafmtOnLoad.scala using project.excludeFilters out of fear of infinite loop 😊

  1. sbt detects changes, reloads
  2. onLoad fires scalafmtSbt, build files are formatted (i intentionally added a changes that would get reformatted)
  3. sbt detects changes, reloads a second time
  4. this time, no changes detected, loop exits, life goes on, it’s all cool
sbt:foo> 
[info] build source files have changed
[info] modified files: 
[info]   /Users/rtoomey/workspace/foo/build.sbt
[info]   /Users/rtoomey/workspace/foo/project/ScalafmtOnLoad.scala
[info] Reloading sbt...
[info] Loading global plugins from /Users/rtoomey/.sbt/1.0/plugins
[info] Loading settings for project foo-build from plugins.sbt,build.sbt ...
[info] Loading project definition from /Users/rtoomey/workspace/foo/project
[info] Compiling 1 Scala source to /Users/rtoomey/workspace/foo/project/target/scala-2.12/sbt-1.0/classes ...
[info] Loading settings for project root from build.sbt ...
[info] Resolving key references (36593 settings) ...
[info] Set current project to foo (in build file:/Users/rtoomey/workspace/foo/)
[success] Total time: 3 s, completed Dec 6, 2019 12:24:11 PM
[info] build source files have changed
[info] modified files: 
[info]   /Users/rtoomey/workspace/foo/build.sbt
[info] Reloading sbt...
[info] Loading global plugins from /Users/rtoomey/.sbt/1.0/plugins
[info] Loading settings for project foo-build from plugins.sbt,build.sbt ...
[info] Loading project definition from /Users/rtoomey/workspace/foo/project
[info] Loading settings for project root from build.sbt ...
[info] Resolving key references (36593 settings) ...
[info] Set current project to foo (in build file:/Users/rtoomey/workspace/foo/)
[success] Total time: 3 s, completed Dec 6, 2019 12:24:17 PM

Further manual reload command is silent about formatting build files:

sbt:foo> reload
[info] Loading global plugins from /Users/rtoomey/.sbt/1.0/plugins
[info] Loading settings for project foo-build from plugins.sbt,build.sbt ...
[info] Loading project definition from /Users/rtoomey/workspace/foo/project
[info] Loading settings for project root from build.sbt ...
[info] Resolving key references (36593 settings) ...
[info] Set current project to foo (in build file:/Users/rtoomey/workspace/foo/)
[success] Total time: 3 s, completed Dec 6, 2019 12:27:53 PM

Seems to work! 🤞

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
help wanted Extra attention is needed
Projects
None yet
Development

No branches or pull requests

2 participants