From e3e95307483a9199d01e9902004f9a94ae931da2 Mon Sep 17 00:00:00 2001 From: Alexandre Archambault Date: Fri, 15 Oct 2021 15:43:44 +0200 Subject: [PATCH] Pass default dialect to scalafmt So that 'scala fmt .' works fine out-of-the-box for Scala 3 sources. --- .../main/scala/scala/cli/commands/Fmt.scala | 44 ++++++++++++++++--- .../scala/scala/cli/commands/FmtOptions.scala | 21 ++++++++- website/docs/reference/cli-options.md | 6 +++ 3 files changed, 64 insertions(+), 7 deletions(-) diff --git a/modules/cli/src/main/scala/scala/cli/commands/Fmt.scala b/modules/cli/src/main/scala/scala/cli/commands/Fmt.scala index d3dfce7251..9cc5eb2666 100644 --- a/modules/cli/src/main/scala/scala/cli/commands/Fmt.scala +++ b/modules/cli/src/main/scala/scala/cli/commands/Fmt.scala @@ -2,8 +2,8 @@ package scala.cli.commands import caseapp._ -import scala.build.Inputs -import scala.build.internal.Runner +import scala.build.internal.{CustomCodeWrapper, Runner} +import scala.build.{CrossSources, Inputs, Sources} import scala.cli.internal.FetchExternalBinary object Fmt extends ScalaCommand[FmtOptions] { @@ -12,16 +12,16 @@ object Fmt extends ScalaCommand[FmtOptions] { def run(options: FmtOptions, args: RemainingArgs): Unit = { // TODO If no input is given, just pass '.' to scalafmt? - val (sourceFiles, workspace) = + val (sourceFiles, workspace, inputsOpt) = if (args.remaining.isEmpty) - (Seq(os.pwd), os.pwd) + (Seq(os.pwd), os.pwd, None) else { val i = options.shared.inputsOrExit(args) val s = i.sourceFiles().collect { case sc: Inputs.Script => sc.path case sc: Inputs.ScalaFile => sc.path } - (s, i.workspace) + (s, i.workspace, Some(i)) } val logger = options.shared.logger @@ -31,6 +31,35 @@ object Fmt extends ScalaCommand[FmtOptions] { logger.debug("No source files, not formatting anything") else { + def scalaVerOpt = inputsOpt.map { inputs => + val crossSources = + CrossSources.forInputs( + inputs, + Sources.defaultPreprocessors( + options.buildOptions.scriptOptions.codeWrapper.getOrElse(CustomCodeWrapper) + ) + ).orExit(logger) + val sharedOptions = crossSources.sharedOptions(options.buildOptions) + sharedOptions + .scalaParams + .orExit(logger) + .scalaVersion + } + + def dialectOpt = options.dialect.map(_.trim).filter(_.nonEmpty).orElse { + scalaVerOpt.map { + case v if v.startsWith("2.12.") => "Scala212" + case v if v.startsWith("2.13.") => "Scala213" + case v if v.startsWith("3.") => "Scala3" + } + } + + val dialectArgs = + if (options.scalafmtArg.isEmpty && !os.exists(workspace / ".scalafmt.conf")) + dialectOpt.toSeq.flatMap(dialect => Seq("--config-str", s"runner.dialect=$dialect")) + else + Nil + val fmtLauncher = options.scalafmtLauncher.filter(_.nonEmpty) match { case Some(launcher) => os.Path(launcher, os.pwd) @@ -41,7 +70,10 @@ object Fmt extends ScalaCommand[FmtOptions] { logger.debug(s"Using scalafmt launcher $fmtLauncher") - val command = Seq(fmtLauncher.toString) ++ sourceFiles.map(_.toString) + val command = Seq(fmtLauncher.toString) ++ + sourceFiles.map(_.toString) ++ + dialectArgs ++ + options.scalafmtArg Runner.run( "scalafmt", command, diff --git a/modules/cli/src/main/scala/scala/cli/commands/FmtOptions.scala b/modules/cli/src/main/scala/scala/cli/commands/FmtOptions.scala index 84a7d46e08..0c3f43d731 100644 --- a/modules/cli/src/main/scala/scala/cli/commands/FmtOptions.scala +++ b/modules/cli/src/main/scala/scala/cli/commands/FmtOptions.scala @@ -3,6 +3,7 @@ package scala.cli.commands import caseapp._ import scala.build.internal.Constants +import scala.build.options.BuildOptions import scala.cli.internal.FetchExternalBinary import scala.util.Properties @@ -11,19 +12,34 @@ import scala.util.Properties final case class FmtOptions( @Recurse shared: SharedOptions = SharedOptions(), + + @Group("Format") @HelpMessage("Check that sources are well formatted") check: Boolean = false, + @Group("Format") @Hidden osArchSuffix: Option[String] = None, + @Group("Format") @Hidden scalafmtTag: Option[String] = None, + @Group("Format") @Hidden scalafmtGithubOrgName: Option[String] = None, + @Group("Format") @Hidden scalafmtExtension: Option[String] = None, + @Group("Format") + @Hidden + scalafmtLauncher: Option[String] = None, + + @Group("Format") + @Name("F") @Hidden - scalafmtLauncher: Option[String] = None + scalafmtArg: List[String] = Nil, + + @Group("Format") + dialect: Option[String] = None ) { // format: on @@ -38,6 +54,9 @@ final case class FmtOptions( (url, !tag0.startsWith("v")) } + def buildOptions: BuildOptions = + shared.buildOptions(enableJmh = false, jmhVersion = None, ignoreErrors = false) + } object FmtOptions { diff --git a/website/docs/reference/cli-options.md b/website/docs/reference/cli-options.md index 90960ce426..b8de554079 100644 --- a/website/docs/reference/cli-options.md +++ b/website/docs/reference/cli-options.md @@ -280,6 +280,12 @@ Check that sources are well formatted #### `--scalafmt-launcher` +#### `--scalafmt-arg` + +Aliases: `-F` + +#### `--dialect` + ## Help options Available in commands: