Skip to content

Commit 6675a53

Browse files
Albert Meltzerkitbellew
Albert Meltzer
authored andcommitted
Additional settings for error handling
1 parent f885ba6 commit 6675a53

File tree

6 files changed

+74
-22
lines changed

6 files changed

+74
-22
lines changed

build.sbt

+1-1
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ inThisBuild(
3434
onLoadMessage := s"Welcome to sbt-scalafmt ${version.value}"
3535
skip in publish := true
3636

37-
val scalafmtVersion = "3.2.0"
37+
val scalafmtVersion = "3.2.1"
3838
lazy val plugin = project
3939
.enablePlugins(SbtPlugin)
4040
.settings(
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package org.scalafmt.sbt
2+
3+
private[sbt] class ErrorHandling(
4+
val logOnEachError: Boolean,
5+
val failOnErrors: Boolean,
6+
val detailedErrorEnabled: Boolean
7+
)

plugin/src/main/scala/org/scalafmt/sbt/ScalafmtPlugin.scala

+34-8
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,12 @@ object ScalafmtPlugin extends AutoPlugin {
7171
val scalafmtFilter = settingKey[String](
7272
"File filtering mode when running scalafmt."
7373
)
74+
val scalafmtLogOnEachError = settingKey[Boolean](
75+
"Enables logging on an error."
76+
)
77+
val scalafmtFailOnErrors = settingKey[Boolean](
78+
"Controls whether to fail in case of formatting errors."
79+
)
7480
}
7581

7682
import autoImport._
@@ -127,13 +133,13 @@ object ScalafmtPlugin extends AutoPlugin {
127133
resolvers: Seq[Resolver],
128134
currentProject: ResolvedProject,
129135
filterMode: String,
130-
detailedErrorEnabled: Boolean
136+
errorHandling: ErrorHandling
131137
) {
132138
private val log = taskStreams.log
133139
private val reporter = new ScalafmtSbtReporter(
134140
log,
135141
new OutputStreamWriter(taskStreams.binary()),
136-
detailedErrorEnabled
142+
errorHandling
137143
)
138144

139145
private val scalafmtSession = {
@@ -179,18 +185,28 @@ object ScalafmtPlugin extends AutoPlugin {
179185

180186
private def withFormattedSources[T](sources: Seq[File])(
181187
onFormat: (File, Input, Output) => T
182-
): Seq[Option[T]] =
183-
sources.map { file =>
188+
): Seq[Option[T]] = {
189+
val res = sources.map { file =>
184190
val path = file.toPath.toAbsolutePath
185191
Try(IO.read(file)) match {
186192
case Failure(x) =>
187193
reporter.error(path, "Failed to read", x)
188194
None
189195
case Success(x) =>
190-
val output = scalafmtSession.format(path, x)
191-
Some(onFormat(file, x, output))
196+
val output = scalafmtSession.formatOrError(path, x)
197+
/* no need to report on exception since for all errors
198+
* reporter.error would have been called already */
199+
Option(output.value).map(o => onFormat(file, x, o))
192200
}
193201
}
202+
val bad = res.count(_ eq None)
203+
if (bad != 0) {
204+
val err = s"scalafmt: failed for $bad sources"
205+
if (errorHandling.failOnErrors) throw new MessageOnlyException(err)
206+
log.error(err)
207+
}
208+
res
209+
}
194210

195211
def formatTrackedSources(
196212
cacheStoreFactory: CacheStoreFactory,
@@ -413,7 +429,11 @@ object ScalafmtPlugin extends AutoPlugin {
413429
fullResolvers.value,
414430
thisProject.value,
415431
scalafmtFilter.value,
416-
scalafmtDetailedError.value
432+
new ErrorHandling(
433+
scalafmtLogOnEachError.value,
434+
scalafmtFailOnErrors.value,
435+
scalafmtDetailedError.value
436+
)
417437
)
418438
func(files, session)
419439
}
@@ -453,7 +473,11 @@ object ScalafmtPlugin extends AutoPlugin {
453473
fullResolvers.value,
454474
thisProject.value,
455475
"",
456-
scalafmtDetailedError.value
476+
new ErrorHandling(
477+
scalafmtLogOnEachError.value,
478+
scalafmtFailOnErrors.value,
479+
scalafmtDetailedError.value
480+
)
457481
).formatSources(absFiles)
458482
}
459483
)
@@ -480,6 +504,8 @@ object ScalafmtPlugin extends AutoPlugin {
480504
Seq(
481505
scalafmtFilter := "",
482506
scalafmtOnCompile := false,
507+
scalafmtLogOnEachError := false,
508+
scalafmtFailOnErrors := true,
483509
scalafmtDetailedError := false
484510
)
485511

plugin/src/main/scala/org/scalafmt/sbt/ScalafmtSbtReporter.scala

+19-13
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import org.scalafmt.interfaces.ScalafmtReporter
1212
class ScalafmtSbtReporter(
1313
log: Logger,
1414
out: OutputStreamWriter,
15-
detailedErrorEnabled: Boolean
15+
errorHandling: ErrorHandling
1616
) extends ScalafmtReporter {
1717
import ScalafmtSbtReporter._
1818

@@ -23,25 +23,31 @@ class ScalafmtSbtReporter(
2323
error(file, null, e)
2424

2525
override def error(file: Path, message: String, e: Throwable): Unit = {
26-
def getMessage() = {
26+
def getMessage(toThrow: Boolean) = {
2727
val res = new StringWriter()
28-
res.write("scalafmt: ")
29-
res.write(Option(message).getOrElse("failed"))
28+
if (toThrow) res.write("scalafmt: ")
29+
val nestedMessage = if (e == null) None else Option(e.getMessage)
30+
val messageOpt = Option(message).orElse(nestedMessage)
31+
res.write(messageOpt.getOrElse("failed"))
3032
res.write(" [")
3133
res.write(file.toString)
3234
res.write(']')
33-
if (null != e) {
34-
if (!detailedErrorEnabled)
35-
Option(e.getMessage).foreach { x =>
36-
res.write(" ")
37-
res.write(x)
38-
}
35+
if (null != e && !toThrow) {
36+
if (errorHandling.detailedErrorEnabled)
37+
e.printStackTrace(new PrintWriter(res))
38+
else if (messageOpt ne nestedMessage) nestedMessage.foreach { x =>
39+
res.write(": ")
40+
res.write(x)
41+
}
3942
}
4043
res.toString
4144
}
4245

43-
val cause = if (detailedErrorEnabled) e else null
44-
throw new ScalafmtSbtError(getMessage(), cause)
46+
if (errorHandling.logOnEachError) log.error(getMessage(false))
47+
else if (errorHandling.failOnErrors) {
48+
val cause = if (errorHandling.detailedErrorEnabled) e else null
49+
throw new ScalafmtSbtError(getMessage(true), cause)
50+
}
4551
}
4652

4753
override def excluded(file: Path): Unit =
@@ -57,6 +63,6 @@ class ScalafmtSbtReporter(
5763
object ScalafmtSbtReporter {
5864

5965
private class ScalafmtSbtError(message: String, cause: Throwable)
60-
extends RuntimeException(message, cause)
66+
extends RuntimeException(message, cause, true, cause != null)
6167

6268
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
object Test {
2+
foo(a, b // ) invalid
3+
}

plugin/src/sbt-test/scalafmt-sbt/sbt/test

+10
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,16 @@ $ exec git -C p17 add "src/main/scala/TestBad2.scala"
176176
# now commit it, no longer modified
177177
$ exec git -C p17 commit -m 'added TestBad2.scala'
178178
> p17/scalafmtCheck
179+
# don't filter but fail after all errors
180+
> set p17/scalafmtFilter := ("")
181+
$ copy-file changes/invalid.scala p17/src/main/scala/TestInvalid1.scala
182+
$ copy-file changes/invalid.scala p17/src/main/scala/TestInvalid2.scala
183+
-> p17/scalafmt
184+
# fail after all errors
185+
> set p17/scalafmtLogOnEachError := true
186+
-> p17/scalafmt
187+
> set p17/scalafmtFailOnErrors := false
188+
> p17/scalafmt
179189

180190
$ copy-file changes/target/managed.scala project/target/managed.scala
181191
$ copy-file changes/x/Something.scala project/x/Something.scala

0 commit comments

Comments
 (0)