-
-
Notifications
You must be signed in to change notification settings - Fork 358
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
Scalafmt support #308
Scalafmt support #308
Changes from 5 commits
3fe5913
73f04d9
ac36673
0da6bcd
34587b9
fef9051
c6be48d
bfbbb6d
a58982e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
package mill.scalalib.scalafmt | ||
|
||
import ammonite.ops._ | ||
import mill._ | ||
import mill.define.{Command, Sources} | ||
import mill.scalalib._ | ||
|
||
trait ScalafmtModule extends ScalaModule { | ||
|
||
def reformat(): Command[Unit] = T.command { | ||
ScalafmtWorkerModule | ||
.worker() | ||
.reformat( | ||
filesToFormat(sources()), | ||
scalafmtConfig().head, | ||
scalafmtDeps().map(_.path) | ||
) | ||
} | ||
|
||
def scalafmtVersion: T[String] = "1.5.1" | ||
|
||
def scalafmtConfig: Sources = T.sources(pwd / ".scalafmt.conf") | ||
|
||
def scalafmtDeps: T[Agg[PathRef]] = T { | ||
Lib.resolveDependencies( | ||
scalaWorker.repositories, | ||
Lib.depToDependency(_, "2.12.4"), | ||
Seq(ivy"com.geirsson::scalafmt-cli:${scalafmtVersion()}") | ||
) | ||
} | ||
|
||
private def filesToFormat(sources: Seq[PathRef]) = { | ||
for { | ||
pathRef <- sources if exists(pathRef.path) | ||
file <- ls.rec(pathRef.path) if file.isFile && file.ext == "scala" | ||
} yield PathRef(file) | ||
} | ||
|
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
package mill.scalalib.scalafmt | ||
|
||
import ammonite.ops.{Path, exists} | ||
import mill._ | ||
import mill.define.{Discover, ExternalModule, Worker} | ||
import mill.modules.Jvm | ||
import mill.util.Ctx | ||
|
||
import scala.collection.mutable | ||
|
||
object ScalafmtWorkerModule extends ExternalModule { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It wasn't immediately clear that worker must live in a separate module to be a single one in a build.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @rockjam being an If you want to let people run ScalaFmt without needing to extend anything, you could make a task in the As for being separate Mill submodules, we only needed to put things like |
||
def worker: Worker[ScalafmtWorker] = T.worker { new ScalafmtWorker() } | ||
|
||
lazy val millDiscover = Discover[this.type] | ||
} | ||
|
||
private[scalafmt] class ScalafmtWorker { | ||
private val reformatted: mutable.Map[Path, Int] = mutable.Map.empty | ||
private var configSig: Int = 0 | ||
|
||
def reformat(input: Seq[PathRef], | ||
scalafmtConfig: PathRef, | ||
scalafmtClasspath: Agg[Path])(implicit ctx: Ctx): Unit = { | ||
val toFormat = | ||
if (scalafmtConfig.sig != configSig) input | ||
else | ||
input.filterNot(ref => reformatted.get(ref.path).contains(ref.sig)) | ||
|
||
if (toFormat.nonEmpty) { | ||
ctx.log.info(s"Formatting ${toFormat.size} Scala sources") | ||
reformatAction(toFormat.map(_.path), | ||
scalafmtConfig.path, | ||
scalafmtClasspath) | ||
reformatted ++= toFormat.map { ref => | ||
val updRef = PathRef(ref.path) | ||
updRef.path -> updRef.sig | ||
} | ||
configSig = scalafmtConfig.sig | ||
} else { | ||
ctx.log.info(s"Everything is formatted already") | ||
} | ||
} | ||
|
||
private val cliFlags = Seq("--non-interactive", "--quiet") | ||
|
||
private def reformatAction(toFormat: Seq[Path], | ||
config: Path, | ||
classpath: Agg[Path])(implicit ctx: Ctx) = { | ||
val configFlags = | ||
if (exists(config)) Seq("--config", config.toString) else Seq.empty | ||
Jvm.subprocess( | ||
"org.scalafmt.cli.Cli", | ||
classpath, | ||
mainArgs = toFormat.map(_.toString) ++ configFlags ++ cliFlags | ||
) | ||
} | ||
|
||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don't we have an alternative for
Sources
for a single file?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think so; we could add one if it comes up repeatedly, but for now just picking the first item in the
Agg[PathRef]
may be fine