GithubHelp home page GithubHelp logo

sbt-scalafmt's Introduction

scalameta

Build Status

User documentation

Head over to the user docs to learn more about the project and its roadmap.

Tutorial

If you'd like to find out how to use scalameta, see this tutorial.

Team

The current maintainers (people who can merge pull requests) are:

An up-to-date list of contributors is available here: https://github.com/scalameta/scalameta/graphs/contributors.

sbt-scalafmt's People

Contributors

barryoneill avatar bjaglin avatar cb372 avatar cchepelov avatar ckipp01 avatar dependabot[bot] avatar eed3si9n avatar github-brice-jaglin avatar he-pin avatar henricook avatar jatcwang avatar jrudolph avatar kitbellew avatar laughedelic avatar muhammedbehram avatar mzuehlke avatar nigredo-tori avatar olafurpg avatar poslegm avatar scala-steward avatar scalameta-bot avatar scalawilliam avatar slivkamiro avatar tanishiking avatar tgodzik avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

sbt-scalafmt's Issues

Unparsable file falls back to defaults

Setup

addSbtPlugin("com.geirsson" % "sbt-scalafmt" % "1.5.1")

Description

Seems as though #7 has resurfaced; In a project that has a .scalafmt.conf, simply add a bare string to the top of the file, like so:

diff --git a/.scalafmt.conf b/.scalafmt.conf
index 26e120b9..be047b6a 100644
--- a/.scalafmt.conf
+++ b/.scalafmt.conf
@@ -1,14 +1,4 @@
+bogus
 
 style = defaultWithAlign

Compatibility with sbt 1.2.8 and earlier

Hi,

The latest sbt-scalafmt release (2.3.3) doesn't work with sbt 1.2.8 and earlier anymore, because of sbt/sbt#5049:

sbt:scalafmt-test> scalafmtAll
[error] java.lang.NoSuchMethodError: sbt.package$.singleFileJsonFormatter()Lsjsonnew/JsonFormat;
[error] 	at org.scalafmt.sbt.ScalafmtPlugin$ScalafmtAnalysis$.<init>(ScalafmtPlugin.scala:68)
[error] 	at org.scalafmt.sbt.ScalafmtPlugin$ScalafmtAnalysis$.<clinit>(ScalafmtPlugin.scala)
[error] 	at org.scalafmt.sbt.ScalafmtPlugin$.trackSourcesAndConfig(ScalafmtPlugin.scala:259)
...

The simplest fix would be to revert #89.

sbt-scalafmt doesn't configure ScalafmtDynamicDownloader in order for sbt.override.build.repos to be respected

If you try to use sbt-scalafmt in a CI behind a firewall, with only Nexus/Artifactory-like mirror to repo1.maven.org, etc, ScalafmtDynamicDownloader won't be able to resolve scalafmt, because repo1.maven.org is not directly accessible, and the build will fail. Even if you setup sbt with sbt.repository.config and sbt.override.build.repos=true

sbt-scalafmt should configure ScalafmtDynamicDownloader in order for sbt.override.build.repos to be respected.

Can there be more verbose output from `scalafmtCheckAll` ?

Hello,

When running scalafmtCheckAll in sbt, the output is one warning per file:

[warn] .../MyClass.scala isn't formatted properly!
[warn] .../AnotherClass.scala isn't formatted properly!
[warn] .../SomeOtherClass.scala isn't formatted properly!

Is it currently possible to get more verbose output, including human-readable descriptions of each formatting issue?

For example, something like this:

[warn] .../MyClass.scala [48:1] Line is too long (maximum length is 160)
[warn] .../MyClass.scala [52:1] Line is too long (maximum length is 160)
[warn] .../AnotherClass.scala [135:28] Too many arguments in function call on a single line
[warn] .../SomeOtherClass.scala [88:5] Space is required after "if" keyword
...

Allow formatting without a .scalafmt.conf?

The documentation for sharing a scalafmt config between projects suggests:

    SettingKey[Unit]("scalafmtGenerateConfig") :=
      IO.write(
        // writes to file once when build is loaded
        file(".scalafmt.conf"),
        "maxColumn = 100".stripMargin.getBytes("UTF-8")
      )

What about allowing usage of --config-str <value> so a file doesn't need to be written?

Dependency Resolution using sbt plugin for Latest Release

What's the trick to getting the sbt plugin for latest 2.0.0-RC5 to install and resolve dependency? trying to add addSbtPlugin("com.geirsson" % "sbt-scalafmt" % "2.0.0-RC5") to my plugins.sbt and have the following repos but still running into dependency not found issues. Trying this with scala 2.11. Had no issues with 1.6.0-RC4. These are the locations that were attempted:

[warn] 	module not found: com.geirsson#sbt-scalafmt;2.0.0-RC5
[warn] ==== typesafe-ivy-releases: tried
[warn]   https://repo.typesafe.com/typesafe/ivy-releases/com.geirsson/sbt-scalafmt/scala_2.12/sbt_1.0/2.0.0-RC5/ivys/ivy.xml
[warn] ==== sbt-plugin-releases: tried
[warn]   https://repo.scala-sbt.org/scalasbt/sbt-plugin-releases/com.geirsson/sbt-scalafmt/scala_2.12/sbt_1.0/2.0.0-RC5/ivys/ivy.xml
[warn] ==== local: tried
[warn]  ${HOME}/.ivy2/local/com.geirsson/sbt-scalafmt/scala_2.12/sbt_1.0/2.0.0-RC5/ivys/ivy.xml
[warn] ==== public: tried
[warn]   https://repo1.maven.org/maven2/com/geirsson/sbt-scalafmt_2.12_1.0/2.0.0-RC5/sbt-scalafmt-2.0.0-RC5.pom
[warn] ==== local-preloaded-ivy: tried
[warn]   ${HOME}/.sbt/preloaded/com.geirsson/sbt-scalafmt/2.0.0-RC5/ivys/ivy.xml
[warn] ==== local-preloaded: tried
[warn]   file:////${HOME}/.sbt/preloaded/com/geirsson/sbt-scalafmt_2.12_1.0/2.0.0-RC5/sbt-scalafmt-2.0.0-RC5.pom
[warn] ==== intellij-scala-plugin: tried
[warn]  ${HOME}/.IntelliJIdea2019.1/config/plugins/Scala/repo/com.geirsson/sbt-scalafmt/scala_2.12/sbt_1.0/2.0.0-RC5/ivys/ivy.xml

And I'm guessing I need to tell my build.sbt to look here:
https://repo1.maven.org/maven2/org/scalameta/scalafmt-core_2.11/2.0.0-RC5/

my resolver definitions:

  resolvers ++= Seq(
    "Sonatype OSS Snapshots".at(
      "http://oss.sonatype.org/content/repositories/snapshots/"
    ),
    "Sonatype OSS Releases".at(
      "http://oss.sonatype.org/content/repositories/releases/"
    ),
    "Typesafe Repository".at("http://repo.typesafe.com/typesafe/releases/"),
    "Typesafe Snapshots Repository".at(
      "http://repo.typesafe.com/typesafe/snapshots/"
    ),
    "scalaz-bintray".at("http://dl.bintray.com/scalaz/releases"),
    Resolver.sbtPluginRepo(status = "releases")
  ),

Plugin missing for scala 2.11 and 2.13

This plugin is only available for projects using scala 2.12. Others based on 2.11 or 2.13 result in the following resolver error because it isn't available via maven.

I don't see any available sbt-scalafmt plugin for 2.11 or 2.13 on maven, but I'm also not a regular java/scala dev so not sure if this is the right place to look.

[error] Error downloading org.scalameta:sbt-scalafmt;sbtVersion=1.0;scalaVersion=2.13:2.4.0
[error]   Not found
[error]   Not found
[error]   not found: /home/chris/.ivy2/local/org.scalameta/sbt-scalafmt/scala_2.13/sbt_1.0/2.4.0/ivys/ivy.xml
[error]   not found: https://repo1.maven.org/maven2/org/scalameta/sbt-scalafmt_2.13_1.0/2.4.0/sbt-scalafmt-2.4.0.pom
[error] Total time: 1 s, completed Jul 22, 2020 10:21:14 AM

Getting warning message after upgrade to sbt 1.5.0

While upgrading to sbt 1.5.0, I got following warning:
[warn] sbt 0.13 shell syntax is deprecated; use slash syntax instead: my_project / Test / scalafmtCheck

It's only a warning, but it would be nice not to see it.

Automatically run scalafmtSbt on reload

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.

Customize `warnBadFormat` message

Thanks for scalafmt, it's been pretty useful for us!

Following the workflow of one of our teams, we have some specific commands we would like engineers to run before/while formatting their scala codebases; it's been a recurring question what commands are these, and we thought it would be great to be able to configure the message scalafmt outputs when bad formatting is detected.

So, in summary, could we have a plugin option in which we pass a custom message to change

[warn] /data/git-repositories/<path_to_file>.scala isn't formatted properly!

into

[warn] /data/git-repositories/<path_to_file>.scala isn't formatted properly! Run <some_command> to auto-format it.

[2.0.4+] Managed sources from meta builds should not be formatted/checked

Steps to reproduce

Set up a basic project where the meta build has managed sources (in this case, a dummy twirl Scala template)

.scalafmt.conf

version = 2.0.0

project/plugins.sbt

addSbtPlugin("org.scalameta" % "sbt-scalafmt" % "2.0.6")

project/build.sbt

lazy val root = (project in file("."))
  .enablePlugins(SbtTwirl)

project/src/main/twirl/template.scala.txt

project/project/plugins.sbt

addSbtPlugin("com.typesafe.sbt" % "sbt-twirl" % "1.4.2")

Actual

bjaglin@x1:/tmp/sbt-project$ sbt scalafmtSbtCheck
[info] Loading settings for project global-plugins from idea.sbt,build.sbt ...
[info] Loading global plugins from /home/bjaglin/.sbt/1.0/plugins
[info] Loading settings for project sbt-project-build-build from plugins.sbt ...
[info] Loading project definition from /tmp/sbt-project/project/project
[info] Loading settings for project root from plugins.sbt,build.sbt ...
[info] Loading project definition from /tmp/sbt-project/project
[info] Set current project to sbt-project (in build file:/tmp/sbt-project/)
[info] Checking 3 Scala sources...
[info] Checking 1 Scala sources...
[warn] /tmp/sbt-project/project/target/scala-2.12/sbt-1.0/twirl/main/txt/template.template.scala isn't formatted properly!
[error] 1 files must be formatted
[error] (Compile / scalafmtSbtCheck) 1 files must be formatted
[error] Total time: 2 s, completed Sep 30, 2019, 10:23:57 PM

Expected

sbt scalafmtSbtCheck succeeds - managed sources are ignored.

Real-world scenario

Akka-gRPC supports custom code generation from protobuf files.

NoClassDefFoundError scala/reflect/api/TypeCreator

This issue was reported here: sake92/hepek-starter#4

Whole stacktrace sbt:root> last Compile / scalafmt [debug] Change report: [debug] Checked: /home/cameron/.workspace/blog/src/main/scala/templates/Templates.scala, /home/cameron/.workspace/blog/src/main/scala/utils/Imports.scala, /home/cameron/.workspace/blog/src/main/scala/site/About.scala, /home/cameron/.workspace/blog/src/main/scala/site/Blog.scala, /home/cameron/.workspace/blog/src/main/scala/site/Index.scala [debug] Modified: /home/cameron/.workspace/blog/src/main/scala/templates/Templates.scala, /home/cameron/.workspace/blog/src/main/scala/utils/Imports.scala, /home/cameron/.workspace/blog/src/main/scala/site/About.scala, /home/cameron/.workspace/blog/src/main/scala/site/Blog.scala, /home/cameron/.workspace/blog/src/main/scala/site/Index.scala [debug] Unmodified: [debug] Added: /home/cameron/.workspace/blog/src/main/scala/templates/Templates.scala, /home/cameron/.workspace/blog/src/main/scala/utils/Imports.scala, /home/cameron/.workspace/blog/src/main/scala/site/About.scala, /home/cameron/.workspace/blog/src/main/scala/site/Blog.scala, /home/cameron/.workspace/blog/src/main/scala/site/Index.scala [debug] Removed: [info] Formatting 5 Scala sources... [debug] Adding repositories [https://repo1.maven.org/maven2/,file:////home/cameron/.sbt/preloaded/,https://oss.sonatype.org/content/repositories/snapshots] [error] org.scalafmt.sbt.ScalafmtSbtReporter$FailedToFormat: /home/cameron/.workspace/blog/.scalafmt.conf [error] Caused by: java.lang.reflect.InvocationTargetException [error] at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) [error] at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) [error] at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) [error] at java.base/java.lang.reflect.Method.invoke(Method.java:566) [error] at org.scalafmt.dynamic.utils.ReflectUtils$ClassReflectOps$.invokeStatic$extension(ReflectUtils.scala:34) [error] at org.scalafmt.dynamic.ScalafmtReflect.(ScalafmtReflect.scala:31) [error] at org.scalafmt.dynamic.ScalafmtDynamic.$anonfun$resolveClassPath$1(ScalafmtDynamic.scala:188) [error] at scala.util.Try$.apply(Try.scala:213) [error] at org.scalafmt.dynamic.ScalafmtDynamic.resolveClassPath(ScalafmtDynamic.scala:186) [error] at org.scalafmt.dynamic.ScalafmtDynamic.$anonfun$resolveFormatter$3(ScalafmtDynamic.scala:177) [error] at scala.util.Either.flatMap(Either.scala:341) [error] at org.scalafmt.dynamic.ScalafmtDynamic.$anonfun$resolveFormatter$1(ScalafmtDynamic.scala:177) [error] at scala.util.Try$.apply(Try.scala:213) [error] at org.scalafmt.dynamic.utils.ReentrantCache.getOrAddToCache(ReentrantCache.scala:41) [error] at org.scalafmt.dynamic.ScalafmtDynamic.resolveFormatter(ScalafmtDynamic.scala:163) [error] at org.scalafmt.dynamic.ScalafmtDynamic.$anonfun$resolveConfigWithScalafmt$2(ScalafmtDynamic.scala:142) [error] at scala.util.Either.flatMap(Either.scala:341) [error] at org.scalafmt.dynamic.ScalafmtDynamic.resolveConfigWithScalafmt(ScalafmtDynamic.scala:139) [error] at org.scalafmt.dynamic.ScalafmtDynamic.$anonfun$resolveConfig$4(ScalafmtDynamic.scala:125) [error] at scala.util.Try$.apply(Try.scala:213) [error] at org.scalafmt.dynamic.utils.ReentrantCache.getOrAddToCache(ReentrantCache.scala:41) [error] at org.scalafmt.dynamic.ScalafmtDynamic.resolveConfig(ScalafmtDynamic.scala:124) [error] at org.scalafmt.dynamic.ScalafmtDynamic.formatDetailed(ScalafmtDynamic.scala:108) [error] at org.scalafmt.dynamic.ScalafmtDynamic.format(ScalafmtDynamic.scala:70) [error] at org.scalafmt.sbt.ScalafmtPlugin$.$anonfun$withFormattedSources$2(ScalafmtPlugin.scala:122) [error] at scala.collection.TraversableLike.$anonfun$map$1(TraversableLike.scala:238) [error] at scala.collection.Iterator.foreach(Iterator.scala:941) [error] at scala.collection.Iterator.foreach$(Iterator.scala:941) [error] at scala.collection.AbstractIterator.foreach(Iterator.scala:1429) [error] at scala.collection.IterableLike.foreach(IterableLike.scala:74) [error] at scala.collection.IterableLike.foreach$(IterableLike.scala:73) [error] at scala.collection.AbstractIterable.foreach(Iterable.scala:56) [error] at scala.collection.TraversableLike.map(TraversableLike.scala:238) [error] at scala.collection.TraversableLike.map$(TraversableLike.scala:231) [error] at scala.collection.AbstractTraversable.map(Traversable.scala:108) [error] at org.scalafmt.sbt.ScalafmtPlugin$.withFormattedSources(ScalafmtPlugin.scala:116) [error] at org.scalafmt.sbt.ScalafmtPlugin$.formatSources(ScalafmtPlugin.scala:164) [error] at org.scalafmt.sbt.ScalafmtPlugin$.$anonfun$formatSources$1(ScalafmtPlugin.scala:149) [error] at org.scalafmt.sbt.ScalafmtPlugin$.$anonfun$formatSources$1$adapted(ScalafmtPlugin.scala:137) [error] at org.scalafmt.sbt.ScalafmtPlugin$.$anonfun$trackSourcesAndConfig$4(ScalafmtPlugin.scala:269) [error] at sbt.util.Difference.apply(Tracked.scala:323) [error] at sbt.util.Difference.apply(Tracked.scala:298) [error] at org.scalafmt.sbt.ScalafmtPlugin$.$anonfun$trackSourcesAndConfig$3(ScalafmtPlugin.scala:268) [error] at org.scalafmt.sbt.ScalafmtPlugin$.$anonfun$trackSourcesAndConfig$3$adapted(ScalafmtPlugin.scala:263) [error] at sbt.util.Tracked$.$anonfun$inputChanged$1(Tracked.scala:150) [error] at org.scalafmt.sbt.ScalafmtPlugin$.$anonfun$trackSourcesAndConfig$1(ScalafmtPlugin.scala:272) [error] at sbt.util.Tracked$.$anonfun$lastOutput$1(Tracked.scala:69) [error] at org.scalafmt.sbt.ScalafmtPlugin$.trackSourcesAndConfig(ScalafmtPlugin.scala:274) [error] at org.scalafmt.sbt.ScalafmtPlugin$.formatSources(ScalafmtPlugin.scala:137) [error] at org.scalafmt.sbt.ScalafmtPlugin$.$anonfun$scalafmtConfigSettings$1(ScalafmtPlugin.scala:317) [error] at org.scalafmt.sbt.ScalafmtPlugin$.$anonfun$scalafmtConfigSettings$1$adapted(ScalafmtPlugin.scala:310) [error] at scala.Function1.$anonfun$compose$1(Function1.scala:49) [error] at sbt.internal.util.$tilde$greater.$anonfun$$u2219$1(TypeFunctions.scala:62) [error] at sbt.std.Transform$$anon$4.work(Transform.scala:67) [error] at sbt.Execute.$anonfun$submit$2(Execute.scala:281) [error] at sbt.internal.util.ErrorHandling$.wideConvert(ErrorHandling.scala:19) [error] at sbt.Execute.work(Execute.scala:290) [error] at sbt.Execute.$anonfun$submit$1(Execute.scala:281) [error] at sbt.ConcurrentRestrictions$$anon$4.$anonfun$submitValid$1(ConcurrentRestrictions.scala:178) [error] at sbt.CompletionService$$anon$2.call(CompletionService.scala:37) [error] at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264) [error] at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515) [error] at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264) [error] at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128) [error] at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628) [error] at java.base/java.lang.Thread.run(Thread.java:834) [error] Caused by: java.lang.NoClassDefFoundError: scala/reflect/api/TypeCreator [error] at fansi.ColorCategory.$anonfun$Full$1(Fansi.scala:851) [error] at fansi.ColorCategory.$anonfun$Full$1$adapted(Fansi.scala:850) [error] at scala.collection.TraversableLike.$anonfun$map$1(TraversableLike.scala:237) [error] at scala.collection.immutable.Range.foreach(Range.scala:158) [error] at scala.collection.TraversableLike.map(TraversableLike.scala:237) [error] at scala.collection.TraversableLike.map$(TraversableLike.scala:230) [error] at scala.collection.AbstractTraversable.map(Traversable.scala:108) [error] at fansi.ColorCategory.(Fansi.scala:850) [error] at fansi.Color$.(Fansi.scala:717) [error] at fansi.Color$.(Fansi.scala) [error] at fansi.Attr$.(Fansi.scala:623) [error] at fansi.Attr$.(Fansi.scala) [error] at fansi.Str$.(Fansi.scala:373) [error] at fansi.Str$.(Fansi.scala) [error] at org.scalafmt.config.OptIn$.$anonfun$surface$1(OptIn.scala:86) [error] at pprint.TPrint$$anon$2.render(TPrint.scala:21) [error] at org.scalafmt.config.OptIn$.surface$lzycompute(OptIn.scala:86) [error] at org.scalafmt.config.OptIn$.surface(OptIn.scala:86) [error] at org.scalafmt.config.OptIn.(OptIn.scala:82) [error] at org.scalafmt.config.ScalafmtConfig$.apply$default$4(ScalafmtConfig.scala:131) [error] at org.scalafmt.config.ScalafmtConfig$.(ScalafmtConfig.scala:208) [error] at org.scalafmt.config.ScalafmtConfig$.(ScalafmtConfig.scala) [error] at org.scalafmt.Scalafmt$.format$default$2(Scalafmt.scala:87) [error] at org.scalafmt.Scalafmt.format$default$2(Scalafmt.scala) [error] at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) [error] at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) [error] at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) [error] at java.base/java.lang.reflect.Method.invoke(Method.java:566) [error] at org.scalafmt.dynamic.utils.ReflectUtils$ClassReflectOps$.invokeStatic$extension(ReflectUtils.scala:34) [error] at org.scalafmt.dynamic.ScalafmtReflect.(ScalafmtReflect.scala:31) [error] at org.scalafmt.dynamic.ScalafmtDynamic.$anonfun$resolveClassPath$1(ScalafmtDynamic.scala:188) [error] at scala.util.Try$.apply(Try.scala:213) [error] at org.scalafmt.dynamic.ScalafmtDynamic.resolveClassPath(ScalafmtDynamic.scala:186) [error] at org.scalafmt.dynamic.ScalafmtDynamic.$anonfun$resolveFormatter$3(ScalafmtDynamic.scala:177) [error] at scala.util.Either.flatMap(Either.scala:341) [error] at org.scalafmt.dynamic.ScalafmtDynamic.$anonfun$resolveFormatter$1(ScalafmtDynamic.scala:177) [error] at scala.util.Try$.apply(Try.scala:213) [error] at org.scalafmt.dynamic.utils.ReentrantCache.getOrAddToCache(ReentrantCache.scala:41) [error] at org.scalafmt.dynamic.ScalafmtDynamic.resolveFormatter(ScalafmtDynamic.scala:163) [error] at org.scalafmt.dynamic.ScalafmtDynamic.$anonfun$resolveConfigWithScalafmt$2(ScalafmtDynamic.scala:142) [error] at scala.util.Either.flatMap(Either.scala:341) [error] at org.scalafmt.dynamic.ScalafmtDynamic.resolveConfigWithScalafmt(ScalafmtDynamic.scala:139) [error] at org.scalafmt.dynamic.ScalafmtDynamic.$anonfun$resolveConfig$4(ScalafmtDynamic.scala:125) [error] at scala.util.Try$.apply(Try.scala:213) [error] at org.scalafmt.dynamic.utils.ReentrantCache.getOrAddToCache(ReentrantCache.scala:41) [error] at org.scalafmt.dynamic.ScalafmtDynamic.resolveConfig(ScalafmtDynamic.scala:124) [error] at org.scalafmt.dynamic.ScalafmtDynamic.formatDetailed(ScalafmtDynamic.scala:108) [error] at org.scalafmt.dynamic.ScalafmtDynamic.format(ScalafmtDynamic.scala:70) [error] at org.scalafmt.sbt.ScalafmtPlugin$.$anonfun$withFormattedSources$2(ScalafmtPlugin.scala:122) [error] at scala.collection.TraversableLike.$anonfun$map$1(TraversableLike.scala:238) [error] at scala.collection.Iterator.foreach(Iterator.scala:941) [error] at scala.collection.Iterator.foreach$(Iterator.scala:941) [error] at scala.collection.AbstractIterator.foreach(Iterator.scala:1429) [error] at scala.collection.IterableLike.foreach(IterableLike.scala:74) [error] at scala.collection.IterableLike.foreach$(IterableLike.scala:73) [error] at scala.collection.AbstractIterable.foreach(Iterable.scala:56) [error] at scala.collection.TraversableLike.map(TraversableLike.scala:238) [error] at scala.collection.TraversableLike.map$(TraversableLike.scala:231) [error] at scala.collection.AbstractTraversable.map(Traversable.scala:108) [error] at org.scalafmt.sbt.ScalafmtPlugin$.withFormattedSources(ScalafmtPlugin.scala:116) [error] at org.scalafmt.sbt.ScalafmtPlugin$.formatSources(ScalafmtPlugin.scala:164) [error] at org.scalafmt.sbt.ScalafmtPlugin$.$anonfun$formatSources$1(ScalafmtPlugin.scala:149) [error] at org.scalafmt.sbt.ScalafmtPlugin$.$anonfun$formatSources$1$adapted(ScalafmtPlugin.scala:137) [error] at org.scalafmt.sbt.ScalafmtPlugin$.$anonfun$trackSourcesAndConfig$4(ScalafmtPlugin.scala:269) [error] at sbt.util.Difference.apply(Tracked.scala:323) [error] at sbt.util.Difference.apply(Tracked.scala:298) [error] at org.scalafmt.sbt.ScalafmtPlugin$.$anonfun$trackSourcesAndConfig$3(ScalafmtPlugin.scala:268) [error] at org.scalafmt.sbt.ScalafmtPlugin$.$anonfun$trackSourcesAndConfig$3$adapted(ScalafmtPlugin.scala:263) [error] at sbt.util.Tracked$.$anonfun$inputChanged$1(Tracked.scala:150) [error] at org.scalafmt.sbt.ScalafmtPlugin$.$anonfun$trackSourcesAndConfig$1(ScalafmtPlugin.scala:272) [error] at sbt.util.Tracked$.$anonfun$lastOutput$1(Tracked.scala:69) [error] at org.scalafmt.sbt.ScalafmtPlugin$.trackSourcesAndConfig(ScalafmtPlugin.scala:274) [error] at org.scalafmt.sbt.ScalafmtPlugin$.formatSources(ScalafmtPlugin.scala:137) [error] at org.scalafmt.sbt.ScalafmtPlugin$.$anonfun$scalafmtConfigSettings$1(ScalafmtPlugin.scala:317) [error] at org.scalafmt.sbt.ScalafmtPlugin$.$anonfun$scalafmtConfigSettings$1$adapted(ScalafmtPlugin.scala:310) [error] at scala.Function1.$anonfun$compose$1(Function1.scala:49) [error] at sbt.internal.util.$tilde$greater.$anonfun$$u2219$1(TypeFunctions.scala:62) [error] at sbt.std.Transform$$anon$4.work(Transform.scala:67) [error] at sbt.Execute.$anonfun$submit$2(Execute.scala:281) [error] at sbt.internal.util.ErrorHandling$.wideConvert(ErrorHandling.scala:19) [error] at sbt.Execute.work(Execute.scala:290) [error] at sbt.Execute.$anonfun$submit$1(Execute.scala:281) [error] at sbt.ConcurrentRestrictions$$anon$4.$anonfun$submitValid$1(ConcurrentRestrictions.scala:178) [error] at sbt.CompletionService$$anon$2.call(CompletionService.scala:37) [error] at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264) [error] at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515) [error] at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264) [error] at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128) [error] at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628) [error] at java.base/java.lang.Thread.run(Thread.java:834) [error] Caused by: java.lang.ClassNotFoundException: scala.reflect.api.TypeCreator [error] at java.base/java.net.URLClassLoader.findClass(URLClassLoader.java:471) [error] at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:589) [error] at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:522) [error] at fansi.ColorCategory.$anonfun$Full$1(Fansi.scala:851) [error] at fansi.ColorCategory.$anonfun$Full$1$adapted(Fansi.scala:850) [error] at scala.collection.TraversableLike.$anonfun$map$1(TraversableLike.scala:237) [error] at scala.collection.immutable.Range.foreach(Range.scala:158) [error] at scala.collection.TraversableLike.map(TraversableLike.scala:237) [error] at scala.collection.TraversableLike.map$(TraversableLike.scala:230) [error] at scala.collection.AbstractTraversable.map(Traversable.scala:108) [error] at fansi.ColorCategory.(Fansi.scala:850) [error] at fansi.Color$.(Fansi.scala:717) [error] at fansi.Color$.(Fansi.scala) [error] at fansi.Attr$.(Fansi.scala:623) [error] at fansi.Attr$.(Fansi.scala) [error] at fansi.Str$.(Fansi.scala:373) [error] at fansi.Str$.(Fansi.scala) [error] at org.scalafmt.config.OptIn$.$anonfun$surface$1(OptIn.scala:86) [error] at pprint.TPrint$$anon$2.render(TPrint.scala:21) [error] at org.scalafmt.config.OptIn$.surface$lzycompute(OptIn.scala:86) [error] at org.scalafmt.config.OptIn$.surface(OptIn.scala:86) [error] at org.scalafmt.config.OptIn.(OptIn.scala:82) [error] at org.scalafmt.config.ScalafmtConfig$.apply$default$4(ScalafmtConfig.scala:131) [error] at org.scalafmt.config.ScalafmtConfig$.(ScalafmtConfig.scala:208) [error] at org.scalafmt.config.ScalafmtConfig$.(ScalafmtConfig.scala) [error] at org.scalafmt.Scalafmt$.format$default$2(Scalafmt.scala:87) [error] at org.scalafmt.Scalafmt.format$default$2(Scalafmt.scala) [error] at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) [error] at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) [error] at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) [error] at java.base/java.lang.reflect.Method.invoke(Method.java:566) [error] at org.scalafmt.dynamic.utils.ReflectUtils$ClassReflectOps$.invokeStatic$extension(ReflectUtils.scala:34) [error] at org.scalafmt.dynamic.ScalafmtReflect.(ScalafmtReflect.scala:31) [error] at org.scalafmt.dynamic.ScalafmtDynamic.$anonfun$resolveClassPath$1(ScalafmtDynamic.scala:188) [error] at scala.util.Try$.apply(Try.scala:213) [error] at org.scalafmt.dynamic.ScalafmtDynamic.resolveClassPath(ScalafmtDynamic.scala:186) [error] at org.scalafmt.dynamic.ScalafmtDynamic.$anonfun$resolveFormatter$3(ScalafmtDynamic.scala:177) [error] at scala.util.Either.flatMap(Either.scala:341) [error] at org.scalafmt.dynamic.ScalafmtDynamic.$anonfun$resolveFormatter$1(ScalafmtDynamic.scala:177) [error] at scala.util.Try$.apply(Try.scala:213) [error] at org.scalafmt.dynamic.utils.ReentrantCache.getOrAddToCache(ReentrantCache.scala:41) [error] at org.scalafmt.dynamic.ScalafmtDynamic.resolveFormatter(ScalafmtDynamic.scala:163) [error] at org.scalafmt.dynamic.ScalafmtDynamic.$anonfun$resolveConfigWithScalafmt$2(ScalafmtDynamic.scala:142) [error] at scala.util.Either.flatMap(Either.scala:341) [error] at org.scalafmt.dynamic.ScalafmtDynamic.resolveConfigWithScalafmt(ScalafmtDynamic.scala:139) [error] at org.scalafmt.dynamic.ScalafmtDynamic.$anonfun$resolveConfig$4(ScalafmtDynamic.scala:125) [error] at scala.util.Try$.apply(Try.scala:213) [error] at org.scalafmt.dynamic.utils.ReentrantCache.getOrAddToCache(ReentrantCache.scala:41) [error] at org.scalafmt.dynamic.ScalafmtDynamic.resolveConfig(ScalafmtDynamic.scala:124) [error] at org.scalafmt.dynamic.ScalafmtDynamic.formatDetailed(ScalafmtDynamic.scala:108) [error] at org.scalafmt.dynamic.ScalafmtDynamic.format(ScalafmtDynamic.scala:70) [error] at org.scalafmt.sbt.ScalafmtPlugin$.$anonfun$withFormattedSources$2(ScalafmtPlugin.scala:122) [error] at scala.collection.TraversableLike.$anonfun$map$1(TraversableLike.scala:238) [error] at scala.collection.Iterator.foreach(Iterator.scala:941) [error] at scala.collection.Iterator.foreach$(Iterator.scala:941) [error] at scala.collection.AbstractIterator.foreach(Iterator.scala:1429) [error] at scala.collection.IterableLike.foreach(IterableLike.scala:74) [error] at scala.collection.IterableLike.foreach$(IterableLike.scala:73) [error] at scala.collection.AbstractIterable.foreach(Iterable.scala:56) [error] at scala.collection.TraversableLike.map(TraversableLike.scala:238) [error] at scala.collection.TraversableLike.map$(TraversableLike.scala:231) [error] at scala.collection.AbstractTraversable.map(Traversable.scala:108) [error] at org.scalafmt.sbt.ScalafmtPlugin$.withFormattedSources(ScalafmtPlugin.scala:116) [error] at org.scalafmt.sbt.ScalafmtPlugin$.formatSources(ScalafmtPlugin.scala:164) [error] at org.scalafmt.sbt.ScalafmtPlugin$.$anonfun$formatSources$1(ScalafmtPlugin.scala:149) [error] at org.scalafmt.sbt.ScalafmtPlugin$.$anonfun$formatSources$1$adapted(ScalafmtPlugin.scala:137) [error] at org.scalafmt.sbt.ScalafmtPlugin$.$anonfun$trackSourcesAndConfig$4(ScalafmtPlugin.scala:269) [error] at sbt.util.Difference.apply(Tracked.scala:323) [error] at sbt.util.Difference.apply(Tracked.scala:298) [error] at org.scalafmt.sbt.ScalafmtPlugin$.$anonfun$trackSourcesAndConfig$3(ScalafmtPlugin.scala:268) [error] at org.scalafmt.sbt.ScalafmtPlugin$.$anonfun$trackSourcesAndConfig$3$adapted(ScalafmtPlugin.scala:263) [error] at sbt.util.Tracked$.$anonfun$inputChanged$1(Tracked.scala:150) [error] at org.scalafmt.sbt.ScalafmtPlugin$.$anonfun$trackSourcesAndConfig$1(ScalafmtPlugin.scala:272) [error] at sbt.util.Tracked$.$anonfun$lastOutput$1(Tracked.scala:69) [error] at org.scalafmt.sbt.ScalafmtPlugin$.trackSourcesAndConfig(ScalafmtPlugin.scala:274) [error] at org.scalafmt.sbt.ScalafmtPlugin$.formatSources(ScalafmtPlugin.scala:137) [error] at org.scalafmt.sbt.ScalafmtPlugin$.$anonfun$scalafmtConfigSettings$1(ScalafmtPlugin.scala:317) [error] at org.scalafmt.sbt.ScalafmtPlugin$.$anonfun$scalafmtConfigSettings$1$adapted(ScalafmtPlugin.scala:310) [error] at scala.Function1.$anonfun$compose$1(Function1.scala:49) [error] at sbt.internal.util.$tilde$greater.$anonfun$$u2219$1(TypeFunctions.scala:62) [error] at sbt.std.Transform$$anon$4.work(Transform.scala:67) [error] at sbt.Execute.$anonfun$submit$2(Execute.scala:281) [error] at sbt.internal.util.ErrorHandling$.wideConvert(ErrorHandling.scala:19) [error] at sbt.Execute.work(Execute.scala:290) [error] at sbt.Execute.$anonfun$submit$1(Execute.scala:281) [error] at sbt.ConcurrentRestrictions$$anon$4.$anonfun$submitValid$1(ConcurrentRestrictions.scala:178) [error] at sbt.CompletionService$$anon$2.call(CompletionService.scala:37) [error] at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264) [error] at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515) [error] at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264) [error] at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128) [error] at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628) [error] at java.base/java.lang.Thread.run(Thread.java:834) [error] (Compile / scalafmt) org.scalafmt.sbt.ScalafmtSbtReporter$FailedToFormat: /home/cameron/.workspace/blog/.scalafmt.conf

Using `project.git` now causes no files to be formatted

I believe there was a regression introduced with the recent changes to the take into account the project.git setting. I can a reproduction repo here that you can just clone and run sbt scalafmtAll.

What happens

I have a single file that looks like this:

object Main extends App {
  
        println("Hello, World!"         )
}

I have a config that looks like this:

version                                    = 3.2.1
project.git                                = true
runner.dialect                             = scala213

When I run sbt. scalafmtAll it does nothing. There are no changes to the code above.

If I then remove the project.git setting, it formats correctly.

Expectation

I'd expect this to format my file as there seems to be nothing in my git ignore that would prohibit this:

target/
metals.sbt
.metals/
.bloop/
.bsp/

Also note that with this same setup, trigging a format from Metals on the same file does format the file.

Introduce scala-steward

@scala-steward is a bot that creates PRs to update the dependencies, which is tried and trusted by a bunch of scala projects https://github.com/scala-steward-org/repos/blob/master/repos.md
It must be helpful for us to update dependencies 👍

Since sbt-scalafmt doesn't have so many dependencies, I think we can manage the PRs from scala-steward easily. (probably, scalameta/scalafmt needs to organize the dependencies(remove unused dependencies and bump dependencies by hand) before introducing scala-steward)

What do you think about this? @olafurpg @poslegm

scalaFmt is extremely slow

In some way, it's a duplicate of #9. However, even if you take the use case of "format of compile" (which is a valid use case for some users) out of the picture, it's still almost too slow to be usable in bigger projects. E.g. akka recently switched to scalafmt and reformatting the whole project takes ~200s. Just validating the formatting for PR validation adds takes several minutes on our build server.

I did a quick profiling run which shows very weird results. From what I can see, one reason might be that sbt-scalafmt's class loader magic prevents efficient JIT compilation of the formatter itself.

Invalid config errors swallowed

I just ran into a weird situation.

Here is my scalafmt config:

align.ifWhileOpenParen = false
align.openParenCallSite = false
align.openParenDefnSite = false
align.tokens.add = ["*>", "<-"]
continuationIndent.defnSite = 2
continuationIndent.extendSite = 2
danglingParentheses = true
docstrings = ScalaDoc
importSelectors = singleLine
includeCurlyBraceInSelectChains = false
maxColumn = 120
newlines.alwaysBeforeElseAfterCurlyIf = false
newlines.alwaysBeforeTopLevelStatements = true
optIn.selfAnnotationNewline = false
optIn.configStyleArguments = false
rewrite.rules = ["AsciiSortImports", "ExpandImportSelectors", "PreferCurlyFors", "RedundantBraces", "RedundantParens", 'SortImports", "SortModifiers"]
spaces.afterTripleEquals = true
spaces.inImportCurlyBraces = true
version=2.0.1

When I ran sbt scalafmtSbt (other tasks had similar output), I got the following:

λ sbt scalafmtSbt
[info] Loading settings for project global-plugins from sbt-updates.sbt,metals.sbt ...
[info] Loading global plugins from /home/nequi/.sbt/1.0/plugins
[info] Loading settings for project scala-integration-build from plugins.sbt ...
[info] Loading project definition from /home/nequi/dev/scala-integration/project
[warn] There may be incompatibilities among your library dependencies; run 'evicted' to see detailed eviction warnings.
[info] Loading settings for project scala-integration from build.sbt ...
[info] Set current project to Integration Test (in build file:/home/nequi/dev/scala-integration/)
[info] ()
[info] ()
[error] null: /home/nequi/dev/scala-integration/build.sbt
[error] (Compile / scalafmtSbt) null: /home/nequi/dev/scala-integration/build.sbt
[error] Total time: 3 s, completed 6-Sep-2019 11:47:52 AM

So I grabbed the scalafmt CLI via coursier and ran ./scalafmt

The output was a whole lot of these (essentially once per file in the project):

org.scalafmt.cli.FailedToFormat: /home/nequi/dev/scala-integration/#.scalafmt.conf#
Caused by: java.lang.reflect.InvocationTargetException
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.scalafmt.dynamic.utils.ReflectUtils$ClassReflectOps$.invokeStatic$extension(ReflectUtils.scala:34)
	at org.scalafmt.dynamic.ScalafmtReflect.parseConfigFromString(ScalafmtReflect.scala:71)
	at org.scalafmt.dynamic.ScalafmtReflect.parseConfig(ScalafmtReflect.scala:66)
	at org.scalafmt.dynamic.ScalafmtDynamic.$anonfun$parseConfig$1(ScalafmtDynamic.scala:148)
	at scala.util.Try$.apply(Try.scala:213)
	at org.scalafmt.dynamic.ScalafmtDynamic.parseConfig(ScalafmtDynamic.scala:148)
	at org.scalafmt.dynamic.ScalafmtDynamic.$anonfun$resolveConfigWithScalafmt$3(ScalafmtDynamic.scala:140)
	at scala.util.Either.flatMap(Either.scala:341)
	at org.scalafmt.dynamic.ScalafmtDynamic.$anonfun$resolveConfigWithScalafmt$2(ScalafmtDynamic.scala:139)
	at scala.util.Either.flatMap(Either.scala:341)
	at org.scalafmt.dynamic.ScalafmtDynamic.resolveConfigWithScalafmt(ScalafmtDynamic.scala:136)
	at org.scalafmt.dynamic.ScalafmtDynamic.$anonfun$resolveConfig$4(ScalafmtDynamic.scala:122)
	at scala.util.Try$.apply(Try.scala:213)
	at org.scalafmt.dynamic.utils.ReentrantCache.getOrAddToCache(ReentrantCache.scala:41)
	at org.scalafmt.dynamic.ScalafmtDynamic.resolveConfig(ScalafmtDynamic.scala:121)
	at org.scalafmt.dynamic.ScalafmtDynamic.formatDetailed(ScalafmtDynamic.scala:105)
	at org.scalafmt.dynamic.ScalafmtDynamic.format(ScalafmtDynamic.scala:67)
	at org.scalafmt.cli.ScalafmtDynamicRunner$.handleFile(ScalafmtDynamicRunner.scala:96)
	at org.scalafmt.cli.ScalafmtDynamicRunner$.$anonfun$run$4(ScalafmtDynamicRunner.scala:55)
	at org.scalafmt.cli.ScalafmtDynamicRunner$.$anonfun$run$4$adapted(ScalafmtDynamicRunner.scala:49)
	at scala.collection.immutable.List.foreach(List.scala:392)
	at org.scalafmt.cli.ScalafmtDynamicRunner$.$anonfun$run$3(ScalafmtDynamicRunner.scala:49)
	at scala.util.control.Breaks.breakable(Breaks.scala:42)
	at org.scalafmt.cli.ScalafmtDynamicRunner$.run(ScalafmtDynamicRunner.scala:49)
	at org.scalafmt.cli.Cli$.run(Cli.scala:96)
	at org.scalafmt.cli.Cli$.mainWithOptions(Cli.scala:69)
	at org.scalafmt.cli.Cli$.main(Cli.scala:58)
	at org.scalafmt.cli.Cli.main(Cli.scala)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at coursier.bootstrap.launcher.a.a(Unknown Source)
	at coursier.bootstrap.launcher.Launcher.main(Unknown Source)
Caused by: org.scalafmt.Error$InvalidScalafmtConfiguration: Failed to read configuration: java.lang.IllegalArgumentException: Incompatible rewrites: SortImports and ExpandImportSelectors
	at org.scalafmt.config.RewriteSettings.<init>(RewriteSettings.scala:21)
	at org.scalafmt.config.RewriteSettings$$anon$1.$anonfun$read$1(RewriteSettings.scala:15)
	at metaconfig.Configured.map(Configured.scala:18)
	at org.scalafmt.config.RewriteSettings$$anon$1.read(RewriteSettings.scala:15)
	at metaconfig.internal.NoTyposDecoder$$anon$1.read(NoTyposDecoder.scala:20)
	at metaconfig.internal.ConfGet$.getOrElse(ConfGet.scala:25)
	at metaconfig.Conf.getSettingOrElse(Conf.scala:28)
	at org.scalafmt.config.ScalafmtConfig$$anon$1.read(ScalafmtConfig.scala:179)
	at metaconfig.internal.NoTyposDecoder$$anon$1.read(NoTyposDecoder.scala:20)
	at metaconfig.internal.NoTyposDecoder$$anon$1.read(NoTyposDecoder.scala:20)
	at org.scalafmt.config.ScalafmtConfig$$anonfun$configReader$1.applyOrElse(ScalafmtConfig.scala:341)
	at org.scalafmt.config.ScalafmtConfig$$anonfun$configReader$1.applyOrElse(ScalafmtConfig.scala:323)
	at metaconfig.ConfDecoder$$anon$2.read(ConfDecoder.scala:65)
	at metaconfig.ConfDecoder.$anonfun$read$1(ConfDecoder.scala:17)
	at metaconfig.Configured.andThen(Configured.scala:30)
	at metaconfig.ConfDecoder.read(ConfDecoder.scala:17)
	at metaconfig.ConfDecoder.read$(ConfDecoder.scala:16)
	at metaconfig.ConfDecoder$$anon$2.read(ConfDecoder.scala:61)
	at org.scalafmt.config.Config$.$anonfun$fromConf$1(Config.scala:70)
	at metaconfig.Configured.andThen(Configured.scala:30)
	at org.scalafmt.config.Config$.fromConf(Config.scala:55)
	at org.scalafmt.config.Config$.fromHoconString(Config.scala:40)
	at org.scalafmt.config.Config$.fromHoconString(Config.scala:33)
	at org.scalafmt.Scalafmt$.parseHoconConfig(Scalafmt.scala:94)
	at org.scalafmt.Scalafmt.parseHoconConfig(Scalafmt.scala)
	... 38 more

Apparently, SortImports and ExpandImportSelectors are incompatible with one another.
I am surprised that is the case.
But regardless, it seems that the sbt plugin just swallows these errors?

Once I remove SortImports, everything is happy.

updating scalafmtConfig does not invalidate the scalafmt/scalafmtCheck caches

Actual (cold start, 58 sources already formatted)

$ scalafmt
[info] Formatting 58 Scala sources...
[success] Total time: 3 s, completed Aug 5, 2019, 6:32:11 PM
$ set scalafmtConfig := file(".scalafmt2.conf")
[info] Reapplying settings...
$ scalafmt
[success] Total time: 0 s, completed Aug 5, 2019, 6:32:51 PM

Expected (cold start, 58 sources already formatted)

$ scalafmt
[info] Formatting 58 Scala sources...
[success] Total time: 3 s, completed Aug 5, 2019, 6:32:11 PM
$ set scalafmtConfig := file(".scalafmt2.conf")
[info] Reapplying settings...
$ scalafmt
[info] Formatting 58 Scala sources...
[success] Total time: 3 s, completed Aug 5, 2019, 6:32:51 PM

Throw an exception instantly if the specified config file contains invalid config

Currently (1.6.0-RC4), sbt-scalafmt fallback to default config if specified configuration is invalid.

This behavior make it difficult for user to debug a config file (maybe it contains typo, or it contains eliminated field as some version)
I think it's better to throw debuggable error instantly if the specified config is invalid, instead of falling back to default config.

Tasks "scalafmtCheckAll" and "scalafmtAll" take the same amount of time to run

Not sure if this issue has been raised before, apologies if it's a duplicate.

We're currently evaluating Scalafmt for use in our project. The code statistics are as follows, according to sbt-stats:

	[info] Code Statistics for project:
	[info] Files
	[info] - Total:      428 files
	[info] - Scala:      427 files (99.8%)
	[info] - Java:       1 files (0.2%)
	[info] - Total size: 3,791,199 Bytes
	[info] - Avg size:   46,559 Bytes
	[info] - Avg length: 993 lines
	[info] Lines
	[info] - Total:      78,177 lines
	[info] - Code:       66,502 lines (85.1%)
	[info] - Comment:    2,381 lines (3.0%)
	[info] - Blank:      9,294 lines (11.9%)
	[info] - Bracket:    6,396 lines (8.2%)
	[info] Characters
	[info] - Total:      3,315,964 chars
	[info] - Code:       3,178,791 chars (95.9%)
	[info] - Comment:    137,173 chars (4.1%)

We've noticed that "scalafmtCheckAll" and "scalafmtAll" take the same amount of time to run.
In our case, ~33 seconds each (on a modern MacBook Pro).

Based on this we suspect that both tasks do in-memory re-formatting, and the difference is whether the results are written to the source files.

Please let us know if this speculation is correct?
If it is, what would it take to optimize the "scalafmtCheckAll" to literally only check the formatting?

Thanks!

Formatting sbt files formats metals.sbt even though it's in the .gitignore

  • Configuration:
version = "3.0.7"
project.git = true

Problem

I'm not fully sure what changed, but as of the last release it seems that I can't get scalafmt to respect my gitignore settings to not format my metals.sbt settings. I have pretty much the same settings as I've always had, but now I'm always getting those file reported as formated like so:

[warn]   /Users/ckipp/Documents/scala-workspace/metals-minimal-sbt/project/metals.sbt
[warn]   /Users/ckipp/Documents/scala-workspace/metals-minimal-sbt/project/project/metals.sbt
[warn]   /Users/ckipp/Documents/scala-workspace/metals-minimal-sbt/project/project/project/metals.sbt

This happens when I run scalafmtSbt via sbt using the 2.4.3 version of the sbt plugin.

I have a minimal example project set up here that you can just clone and use. Open it with metals, get your metals.sbt files generated, and then run scalafmtSbt and hopefully you'll see the same result as I'm seeing.

Expectation

I'd expect this setting to respect my .gitconfig and not worry about my metals.sbt files.

The reason this is sort of a hassle is that when these are formatted and changed, metals detects that a changed happened in your build file which can cause Metals to prompt you to re-import your project.

Error messages from scalafmt should clearly be marked as such to not be confused with compiler error messages

If I add sbt-scalafmt with an empty .scalafmt.conf to https://github.com/scala/scala3-example-project and run scalafmt I get:

[info] Formatting 13 Scala sources...
[error] /home/smarter/opt/scala3-example-project/src/main/scala/IntersectionTypes.scala:4: error: ; expected but : found
[error] object IntersectionTypes:
[error]                         ^: /home/smarter/opt/scala3-example-project/src/main/scala/IntersectionTypes.scala
[error] (Compile / scalafmt) /home/smarter/opt/scala3-example-project/src/main/scala/IntersectionTypes.scala:4: error: ; expected but : found
[error] object IntersectionTypes:
[error]                         ^: /home/smarter/opt/scala3-example-project/src/main/scala/IntersectionTypes.scala
[error] Total time: 4 s, completed 4 mai 2021 16:19:19

Here it's clear that these errors come from scalafmt since that's the command I ran, but if I also set scalafmtOnCompile := true as some projects do, then these errors will show up in the output of compile and look like compiler errors. I've seen at least one person being confused by that (and I was also confused until I realized the error was probably coming from scalafmt). Therefore, it'd be nice if scalafmt was explicitly written down in each error message from the formatter.

scalafmt invoked again despite successful task execution

Non-formatted sources need 2 task executions for cache to kick-in. The second execution does not update the sources, but we still pay the price of computation for nothing.

Actual (cold start, 58 sources, 23 needs formatting)

$ scalafmt
[info] Formatting 58 Scala sources...
[success] Total time: 3 s, completed Aug 5, 2019, 6:32:11 PM
$ scalafmt
[info] Formatting 23 Scala sources...
[success] Total time: 1 s, completed Aug 5, 2019, 6:32:41 PM
$ scalafmt
[success] Total time: 0 s, completed Aug 5, 2019, 6:32:51 PM

Expected (cold start, 58 sources, 3 needs formatting)

$ scalafmt
[info] Formatting 58 Scala sources...
[success] Total time: 3 s, completed Aug 5, 2019, 6:32:11 PM
$ scalafmt
[success] Total time: 0 s, completed Aug 5, 2019, 6:32:51 PM

Don't format custom package with includePaths

This template is a guideline, not a strict requirement.

  • Version: 3.0.6
  • Integration: Terminal direct
  • Configuration:
version = 3.0.6

Steps

Given code like this:

var name =               "test"

When I run scalafmt like this:

sbt scalafmtall

Problem

Scalafmt formats code like this:

var name =               "test"

Expectation

I would like the formatted output to look like this:

var name = "test"

Notes

My file is not inside src/main, but inside src/it.

I already tried a lot of glob configurations:

project.includePaths = ["glob:**/src/it/scala/djinni/*.scala"]
project.includePaths = ["glob:**/*.scala"]
project.includePaths = ["glob:*.scala"]
project.includePaths = ["glob:**.scala"]

Nothing works.

Our repository:
https://github.com/cross-language-cpp/djinni-generator

Release

There seem to be a number of useful changes merged (notably #13) - perhaps it is time to cut another release?

project.git = true seems to be ignored when using sbt-scalafmt

Setup

addSbtPlugin("com.geirsson" % "sbt-scalafmt" % "1.5.1")

.scalafmt.conf:

project.git = true

style = defaultWithAlign

danglingParentheses        = true
maxColumn                  = 160
project.excludeFilters     = [".*\\.sbt"]
rewrite.rules              = [AsciiSortImports, RedundantBraces, RedundantParens]
spaces.inImportCurlyBraces = true
unindentTopLevelOperators  = true

.gitignore

.DS_Store
target/

modules/sample*/target/
modules/sample*/src/main/scala/*
modules/sample*/src/main/scala/generated/*
!modules/sample*/src/main/scala/App.scala
!modules/sample*/src/main/scala/support
!modules/sample*/src/test/resources/

.idea

despite this, when running scalafmtCheck, I still get files that are explicitly ignored (under modules/sample*/src/main/scala/generated)

Project license

Hi,
my question is about license of the project. While I can see "license name" entry in the ivy xml for jars which refers to Apache2.0 I can not see something like that for the source code (while scalafmt projects has). Is there any particulars purpose in that? Does it mean that binary is under Apache and source code not?

Specify --mode diff when using plugin

Hi, we're using this plugin in our org and recently updated from 1.2.0 to the latest version.
This led to very large scalafmt diffs, and we'd prefer to catch up incrementally over time.
It seems that the scalafmt CLI lets you specify --mode diff which will only apply scalafmt to the files that are diffed against the main/master branch.
Is there a way to specify this flag in the plugin?
If not, I'd be happy to try to contribute the change, but would appreciate some direction.
For example, is the plugin the right place to put this? Maybe it actually belongs in the .scalafmt.conf file, in which case the change should occur in the main scalafmt repo?

scalafmtCheckAll doesn't output anything when added as a dependency

Caveat I'm still learning SBT, but I've got:

    (test in Test) := {
      scalafmtCheckAll.value
      (test in Test).value
    }

in my settings, and I was hoping the command would fail (with relevant output) when running test. But I don't get any output from scalafmt - it seems like it runs in the background but is ignored.

In contrast, if I run scalafmtCheckAll directly from sbt I get the expected errors printed out.

Is there a way I can retain the output and ensure it is displayed somehow?

ScalafmtSbtReporter suppresses real source of error

sbt-scalafmt version: 2.2.1
TL;DR I believe I found a metaconfig issue, but in the meantime, it would be nice to have a plugin setting which disables ScalafmtSbtReporter so you don't have to publish local to figure out what is really going wrong. 🙏 Would happily contribute if you feel this is worthwhile.

What happened

I'm trying to debug an error where sbt scalafmtSbt is failing with a cryptic error on a specific metabuild source file:

java.util.NoSuchElementException: next on empty iterator /Users/rtoomey/workspace/foo/project/Bar.scala

First I reduced my .scalafmt.conf to nothing but

version = 2.2.1

Then I tried poking around Bar.scala to figure out what's upsetting scalafmt, and finally gave up.

When formatting source files, I was used to being about to set runner.debug = true and getting a detailed error. But this time, nothing except next on empty iterator.

Looking at the plugin

Finally, I went back into the source of the plugin itself and found
https://github.com/scalameta/sbt-scalafmt/blob/master/plugin/src/main/scala/org/scalafmt/sbt/ScalafmtPlugin.scala#L102

So I published the plugin locally with

val scalafmtInstance = globalInstance //.withReporter(reporter)

and immediately got that this line in metaconfig is an issue
https://github.com/olafurpg/metaconfig/blob/master/metaconfig-core/shared/src/main/scala/metaconfig/Position.scala#L25

error: /Users/rtoomey/workspace/foo/project/Bar.scala: java.util.NoSuchElementException: next on empty iterator
	at scala.collection.Iterator$$anon$19.next(Iterator.scala:954)
	at scala.collection.Iterator$$anon$19.next(Iterator.scala:952)
	at scala.collection.StringOps$$anon$1.next(StringOps.scala:682)
	at scala.collection.StringOps$$anon$1.next(StringOps.scala:680)
  | => rat metaconfig.Position.pretty(Position.scala:25)
	at metaconfig.ConfError$$anon$8.<init>(ConfError.scala:130)
	at metaconfig.ConfError$.parseError(ConfError.scala:130)
	at metaconfig.typesafeconfig.TypesafeConfig2Class$.gimmeSafeConf(TypesafeConfig2Class.scala:53)
	at metaconfig.typesafeconfig.TypesafeConfig2Class$.gimmeConfFromString(TypesafeConfig2Class.scala:11)
	at metaconfig.typesafeconfig.package$$anon$1.fromInput(package.scala:9)
	at org.scalafmt.config.Config$.fromInput(Config.scala:19)
	at org.scalafmt.config.Config$.fromHoconString(Config.scala:40)
	at org.scalafmt.util.StyleMap.$anonfun$x$1$1(StyleMap.scala:40)
	at scala.collection.ArrayOps$.foreach$extension(ArrayOps.scala:1323)
	at org.scalafmt.util.StyleMap.<init>(StyleMap.scala:37)
	at org.scalafmt.internal.FormatOps.<init>(FormatOps.scala:47)
	at org.scalafmt.Scalafmt$.format(Scalafmt.scala:59)
	at org.scalafmt.Scalafmt.format(Scalafmt.scala)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.scalafmt.dynamic.ScalafmtReflect.format(ScalafmtReflect.scala:102)
	at org.scalafmt.dynamic.ScalafmtDynamic.$anonfun$tryFormat$1(ScalafmtDynamic.scala:213)
	at scala.util.Try$.apply(Try.scala:213)
	at org.scalafmt.dynamic.ScalafmtDynamic.tryFormat(ScalafmtDynamic.scala:201)
	at org.scalafmt.dynamic.ScalafmtDynamic.$anonfun$formatDetailed$1(ScalafmtDynamic.scala:107)
	at scala.util.Either.flatMap(Either.scala:341)
	at org.scalafmt.dynamic.ScalafmtDynamic.formatDetailed(ScalafmtDynamic.scala:106)
	at org.scalafmt.dynamic.ScalafmtDynamic.format(ScalafmtDynamic.scala:68)
	at org.scalafmt.sbt.ScalafmtPlugin$.$anonfun$withFormattedSources$2(ScalafmtPlugin.scala:114)
	at scala.collection.TraversableLike.$anonfun$map$1(TraversableLike.scala:238)
	at scala.collection.Iterator.foreach(Iterator.scala:941)
	at scala.collection.Iterator.foreach$(Iterator.scala:941)
	at scala.collection.AbstractIterator.foreach(Iterator.scala:1429)
	at scala.collection.IterableLike.foreach(IterableLike.scala:74)
	at scala.collection.IterableLike.foreach$(IterableLike.scala:73)
	at scala.collection.AbstractIterable.foreach(Iterable.scala:56)
	at scala.collection.TraversableLike.map(TraversableLike.scala:238)
	at scala.collection.TraversableLike.map$(TraversableLike.scala:231)
	at scala.collection.AbstractTraversable.map(Traversable.scala:108)
	at org.scalafmt.sbt.ScalafmtPlugin$.withFormattedSources(ScalafmtPlugin.scala:107)
	at org.scalafmt.sbt.ScalafmtPlugin$.formatSources(ScalafmtPlugin.scala:153)
	at org.scalafmt.sbt.ScalafmtPlugin$.$anonfun$scalafmtConfigSettings$3(ScalafmtPlugin.scala:319)
	at org.scalafmt.sbt.ScalafmtPlugin$.$anonfun$scalafmtConfigSettings$3$adapted(ScalafmtPlugin.scala:308)
	at scala.Function1.$anonfun$compose$1(Function1.scala:49)
	at sbt.internal.util.$tilde$greater.$anonfun$$u2219$1(TypeFunctions.scala:62)
	at sbt.std.Transform$$anon$4.work(Transform.scala:67)
	at sbt.Execute.$anonfun$submit$2(Execute.scala:281)
	at sbt.internal.util.ErrorHandling$.wideConvert(ErrorHandling.scala:19)
	at sbt.Execute.work(Execute.scala:290)
	at sbt.Execute.$anonfun$submit$1(Execute.scala:281)
	at sbt.ConcurrentRestrictions$$anon$4.$anonfun$submitValid$1(ConcurrentRestrictions.scala:178)
	at sbt.CompletionService$$anon$2.call(CompletionService.scala:37)
	at java.util.concurrent.FutureTask.run(FutureTask.java:266)
	at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
	at java.util.concurrent.FutureTask.run(FutureTask.java:266)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
	at java.lang.Thread.run(Thread.java:748)

Error when no version specified in config

According to docs it should use latest by default. The actual behaviour is an error when this value is missing in config.

[error] missing setting 'version'. To fix this problem, add the following line to .scalafmt.conf: 'version=2.5.2'.: /a/b/c/my-service/.scalafmt.conf

Scalafmt on compile races with scaladoc

This one is tricky to reproduce. I think I've seen it in one of my CI builds (with scalafmt on compile) - the doc task has failed, citing missing types from the same project - but it was gone after I've restarted the build. I'm fairly certain that the reason is as follows.

At the moment, Scalafmt is wired into the compile / compileInputs task, which relies on client / Compile / sources:

sbt:root> inspect tree client/compile/compileInputs
[info] client / Compile / compile / compileInputs = Task[xsbti.compile.Inputs]
...
[info]   +-client / Compile / compile / compileOptions = Task[xsbti.compile.C..
...
[info]   | +-client / Compile / sources = Task[scala.collection.Seq[java.io.F..
...
[info]   +-client / Compile / scalafmtDoFormatOnCompile = Task[Unit]
[info]     +-ThisBuild / scalafmtOnCompile = true

However, the Scaladoc build (the Compile / doc task) directly uses Compile / sources instead:

sbt:root> inspect tree client/doc
[info] client / Compile / doc = Task[java.io.File]
...
[info]   +-client / Compile / sources = Task[scala.collection.Seq[java.io.Fil..

This means that we can have client / Compile / doc and scalafmtDoFormatOnCompile running in parallel. If formatting changes the sources (in my case that was caused by Windows line endings), client / Compile / doc can observe partially regenerated sources, which is problematic.

I suggest we wire formatting directly into Compile / sources instead.

Unable to download Scalafmt sbt plugin in CI

  • Version (of the sbt plugin): 2.4.0
  • Integration: IntelliJ
  • Configuration:
version = 2.7.5
preset = IntelliJ
maxColumn = 120
continuationIndent.callSite = 2
continuationIndent.ctorSite = 4
continuationIndent.defnSite = 2
continuationIndent.extendSite = 4
continuationIndent.withSiteRelativeToExtends = 2
align.preset = more

Steps

Running this command in CI:

sbt clean compile test it:test package

I am unable to download the plugin with the following message:

[warn] 
[warn] 	Note: Some unresolved dependen((redacted))es have extra attributes.  Check that these dependen((redacted))es exist with the requested attributes.
[warn] 		org.scalameta:sbt-scalafmt:2.4.0 (sbtVersion=1.0, scalaVersion=2.12)
[warn] 
[warn] 	Note: Unresolved dependen((redacted))es path:
[error] sbt.librarymanagement.ResolveException: Error downloading org.scalameta:sbt-scalafmt;sbtVersion=1.0;scalaVersion=2.12:2.4.0
[error]   Not found
[error]   Not found
[error]   not found: /root/.ivy2/local/org.scalameta/sbt-scalafmt/scala_2.12/sbt_1.0/2.4.0/ivys/ivy.xml
[error]   not found: ((redacted))/sbt-proxy/org.scalameta/sbt-scalafmt/scala_2.12/sbt_1.0/2.4.0/ivys/ivy.xml
[error]   not found: ((redacted))/libs-release/org/scalameta/sbt-scalafmt_2.12_1.0/2.4.0/sbt-scalafmt-2.4.0.pom
[error] 	at lmcoursier.CoursierDependencyResolution.unresolvedWarningOrThrow(CoursierDependencyResolution.scala:245)
[error] 	at lmcoursier.CoursierDependencyResolution.$anonfun$update$34(CoursierDependencyResolution.scala:214)
[error] 	at scala.util.Either$LeftProjection.map(Either.scala:573)
[error] 	at lmcoursier.CoursierDependencyResolution.update(CoursierDependencyResolution.scala:214)
[error] 	at sbt.librarymanagement.DependencyResolution.update(DependencyResolution.scala:60)
[error] 	at sbt.internal.LibraryManagement$.resolve$1(LibraryManagement.scala:52)
[error] 	at sbt.internal.LibraryManagement$.$anonfun$cachedUpdate$12(LibraryManagement.scala:102)
[error] 	at sbt.util.Tracked$.$anonfun$lastOutput$1(Tracked.scala:69)
[error] 	at sbt.internal.LibraryManagement$.$anonfun$cachedUpdate$20(LibraryManagement.scala:115)
[error] 	at scala.util.control.Exception$Catch.apply(Exception.scala:228)
...

Other important parameters

# scala version in build.sbt
scalaVersion in ThisBuild := "2.13.1"

# plugin version in plugins.sbt
addSbtPlugin("org.scalameta"     % "sbt-scalafmt" % "2.4.0")

# sbt version in build.properties
sbt.version=1.3.6

Notes

I also tried to adjust plugin version to scala version like this, but that didn't help.

addSbtPlugin("org.scalameta"   %% "sbt-scalafmt" % "2.4.0")

scalafmt & scalafmtCheck do not share the same cache

Actual (cold start, 42 sources)

$ scalafmt
[info] Formatting 42 Scala sources...
[success] Total time: 4 s, completed Aug 5, 2019, 6:32:41 PM
$ scalafmtCheck
[info] Checking 42 Scala sources...
[success] Total time: 4 s, completed Aug 5, 2019, 6:35:22 PM
$ scalafmtCheck
[info] Checking 42 Scala sources...
[success] Total time: 4 s, completed Aug 5, 2019, 6:32:41 PM
$ scalafmt
[info] Formatting 42 Scala sources...
[success] Total time: 4 s, completed Aug 5, 2019, 6:35:22 PM

Expected (cold start, 42 sources)

$ scalafmt
[info] Formatting 42 Scala sources...
[success] Total time: 4 s, completed Aug 5, 2019, 6:32:41 PM
$ scalafmtCheck
[success] Total time: 0 s, completed Aug 5, 2019, 6:35:22 PM
$ scalafmtCheck
[info] Checking 42 Scala sources...
[success] Total time: 4 s, completed Aug 5, 2019, 6:32:41 PM
$ scalafmt
[success] Total time: 0 s, completed Aug 5, 2019, 6:35:22 PM

not using available resolvers

Plugin version addSbtPlugin("org.scalameta" % "sbt-scalafmt" % "2.4.0")

When running scalafmtAll command:

[error] (my-application / Compile / scalafmt) failed to resolve Scalafmt version '2.6.2': https://artifactory.my-company-artifactory.com/artifactory/libs-release/com/googlecode/java-diff-utils/diffutils/1.3.0/diffutils-1.3.0.jar: unauthorized: https://artifactory.my-company-artifactory.com/artifactory/libs-release/com/googlecode/java-diff-utils/diffutils/1.3.0/diffutils-1.3.0.jar (Artifactory Realm)
  [error] https://artifactory.my-company-artifactory.com/artifactory/libs-release/org/scalameta/fastparse-utils_2.13/1.0.1/fastparse-utils_2.13-1.0.1.jar: unauthorized: https://artifactory.my-company-artifactory.com/artifactory/libs-release/org/scalameta/fastparse-utils_2.13/1.0.1/fastparse-utils_2.13-1.0.1.jar (Artifactory Realm)
  [error] https://artifactory.my-company-artifactory.com/artifactory/libs-release/org/scalameta/fastparse_2.13/1.0.1/fastparse_2.13-1.0.1.jar: unauthorized: https://artifactory.my-company-artifactory.com/artifactory/libs-release/org/scalameta/fastparse_2.13/1.0.1/fastparse_2.13-1.0.1.jar (Artifactory Realm)

Note: the above has been anonymized.

I talked to our infra team and they say that the scalafmt plugin is not using the available resolvers/creds so it's getting unauthorized and is the only plugin having this issue.

Removed file puts scalafmt off

I've sbt-scalafmt running on compile and work in a ~ test cycle.

When I remove a file scalafmt is missing it so much that it fails:

7. Waiting for source changes in project p... (press enter to interrupt)
[info] Formatting 1 Scala sources...
[error] java.io.FileNotFoundException: /Users/....scala (No such file or directory)
...
[error] 	at org.scalafmt.sbt.ScalafmtPlugin$.$anonfun$withFormattedSources$1(ScalafmtPlugin.scala:92)
...
[error] 	at org.scalafmt.sbt.ScalafmtPlugin$.withFormattedSources(ScalafmtPlugin.scala:91)
[error] 	at org.scalafmt.sbt.ScalafmtPlugin$.formatSources(ScalafmtPlugin.scala:127)

After a clean everything is good again.

SBT plugin fails without .scalafmt.conf

  • Version: sbt-scalafmt:2.4.3
  • Integration: SBT/IntelliJ
  • Configuration: N/A

Without a .scalafmt.conf, the task scalafmtCheckAll fails; an empty file makes it work. I didn't check the other tasks.

[error] File not exists: /my-project/.scalafmt.conf
[error] File not exists: /my-project/.scalafmt.conf
[error] File not exists: /my-project/.scalafmt.conf
[error] File not exists: /my-project/.scalafmt.conf
[error] (test-util / Compile / scalafmtCheck) File not exists: /my-project/.scalafmt.conf
[error] (test-util / Test / scalafmtCheck) File not exists: /my-project/.scalafmt.conf
[error] (Test / scalafmtCheck) File not exists: /my-project/.scalafmt.conf
[error] (Compile / scalafmtCheck) File not exists: /my-project/.scalafmt.conf

`scalafmtOnCompile` takes too long

Right now if we turn this on, it causes a 5-10 second overhead when compiling Cats. I got the impression it's checking all files in the project rather than incremental. Is this true? If so is it something that can be improved?

sometimes scalafmt fails to resolve it's dependencies on our ci server

On our CI server sometimes scalafmt fails to get it's dependencies:

sbt "clean; assembly;"

 [error] failed to resolve Scalafmt version '2.5.2': https://nexus.tegonal.com/repository/maven-public/com/typesafe/config/1.4.0/config-1.4.0.jar: unauthorized: https://nexus.tegonal.com/repository/maven-public/com/typesafe/config/1.4.0/config-1.4.0.jar (Sonatype Nexus Repository Manager)

when we add an update step before the assembly we (so far) never got this error.
sbt "clean; update; assembly;"

(nexus.tegonal.com is our maven proxy which needs an auth token to fetch packages.)

Generate warnings for all unformatted files when running scalafmtCheck

Currently scalafmtCheck generates an error for the first unformatted file found and fails the task. My suggestion is to have an ability to generate warnings for all unformatted files instead.

I think this may allow cleaner integration into development process by hinting the developer to run the formatter without being overly intrusive (as opposed to scalafmtOnCompile).

This behavior may be controlled by options, e.g. existing runner.fatalWarnings or a new flag.

Another good idea is to pair this with incremental formatting.

It is unclear what scalafmt version is supported

Problem

I think it is unclear which scalafmt version in .scalafmt.conf the sbt-scalafmt supports.
E.g. version = 2.0.0-RC7 for addSbtPlugin("org.scalameta" % "sbt-scalafmt" % "2.0.1").

This makes it difficult to implement automatic update sbt-scalafmt in Scala Steward scala-steward-org/scala-steward#625, since a PR to update sbt-scalafmt may be broken if version in .scalafmt.conf is not updated together.

This issus maybe applicable to humans too.
I could not find these version relationship in document...

Expectation

Option 1 (preferreable). Use same version in scalafmt and sbt-scalafmt.

From UX POV, I think this is most straightforward for users and bots like Scala Steward.
However, a caveat is that scalafmt and sbt-scalafmt should release newer version at same time even if no changes in one side.

Option 2. Include scalafmt version in sbt-scalafmt version.

Let's say if scalafmt is 2.1.0, sbt-scalafmt may be 2.0.10-2.1.0.
This may be tricky for Scala Steward and humans, but release timing do not need synchronization.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.