mill icon indicating copy to clipboard operation
mill copied to clipboard

scalafmtConfig is eagerly resolved causing reformatAll to fail

Open asarkar opened this issue 7 months ago • 1 comments

scalafmtConfig defined in the ScalafmtModule when overridden has no effect. tasks like reformatAll continue to use the default location, and hence, fail.

[5/5, 1 failed] ========================== mill.scalalib.scalafmt.ScalafmtModule/reformatAll ==========================
1 tasks failed
mill.scalalib.scalafmt.ScalafmtModule.reformatAll None of the specified `scalafmtConfig` locations exist. Searched in: /path/to/workspace/.scalafmt.conf, /path/to/workspace/out/mill/scalalib/scalafmt/ScalafmtModule/scalafmtConfig.dest/.scalafmt.conf

/path/to/workspace is a placeholder for the project workspace for privacy reasons.

Looking in the source code, the path is resolved in the method resolvedScalafmtConfig; perhaps this is happening too early?

build.mill

import build_.{versions => v}
// more imports elided

trait LintModule extends ScalafmtModule with ScalafixModule {
  override def scalafixConfig: T[Option[Path]] = Task { Some(Task.workspace / "conf" / "scalafix.conf") }
  override def scalafmtConfig: T[Seq[PathRef]] = Task.Sources(Task.workspace / "conf" / "scalafmt.conf")
}

object `package` extends RootModule with LintModule {
  override def scalaVersion: T[String] = v.scalaVersion

  override def scalacOptions: T[Seq[String]] = Seq(...) // elided

  override def ivyDeps: T[Agg[Dep]] = Agg(...) // elided

  object test extends ScalaTests with TestModule.ScalaTest with LintModule {
    override def ivyDeps: T[Agg[Dep]] = Agg(
      ivy"org.scalatest::scalatest:${v.scalatestVersion}"
    )
  }
}

asarkar avatar May 22 '25 14:05 asarkar

The default-provided external module mill.scalalib.scalafmt.ScalafmtModule isn't reading all the customizations you made in your local modules.

I was going to suggest, that all you need is to extend from mill.scalalib.scalafmt.ScalafmtModule, to format your project with custom settings but with a single command, but it looks like this isn't going to work, since this module isn't prepared for that.

Ideally, all tasks in the external module (which is a Scala object and can't be inherited) are defined in a intermediate trait, which you then can inherit to customize locally. It doesn't look that complicated, so feel free to open a pull request.

lefou avatar Jun 05 '25 07:06 lefou