Skip to content

Commit 7f15a3c

Browse files
authored
Merge pull request #1973 from G1ng3r/feature/generate-task-errors
Throw error from bloopGenerate task
2 parents 097725c + 1d52064 commit 7f15a3c

File tree

2 files changed

+32
-18
lines changed
  • frontend/src/test/resources/compiler-plugin-allowlist
  • integrations/sbt-bloop/src/main/scala/bloop/integrations/sbt

2 files changed

+32
-18
lines changed

frontend/src/test/resources/compiler-plugin-allowlist/build.sbt

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,16 @@
11
bloopExportJarClassifiers in Global := Some(Set("sources"))
22
bloopConfigDir in Global := baseDirectory.value / "bloop-config"
33
import _root_.sbtcrossproject.CrossPlugin.autoImport.{crossProject => crossProjects}
4+
import sbt.Value
45

56
scalaVersion in ThisBuild := "2.12.8"
67

78
lazy val `bloop-test-plugin` = project
89
.settings(
910
libraryDependencies += "org.scala-lang" % "scala-compiler" % scalaVersion.value,
1011
publishArtifact in Compile := false,
11-
bloopGenerate in Compile := None,
12-
bloopGenerate in Test := None
12+
bloopGenerate in Compile := Value(None),
13+
bloopGenerate in Test := Value(None)
1314
)
1415

1516
val silencerVersion = "1.3.1"

integrations/sbt-bloop/src/main/scala/bloop/integrations/sbt/SbtBloop.scala

Lines changed: 29 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import sbt.Def
2525
import sbt.File
2626
import sbt.Global
2727
import sbt.Inc
28+
import sbt.Incomplete
2829
import sbt.IntegrationTest
2930
import sbt.KeyRanks
3031
import sbt.Keys
@@ -40,6 +41,7 @@ import sbt.ThisBuild
4041
import sbt.ThisProject
4142
import sbt.Value
4243
import xsbti.compile.CompileOrder
44+
import sbt.Result
4345

4446
object BloopPlugin extends AutoPlugin {
4547
import sbt.plugins.JvmPlugin
@@ -78,8 +80,8 @@ object BloopKeys {
7880
taskKey[Seq[(File, File)]]("Directory where to write the class files")
7981
val bloopInstall: TaskKey[Unit] =
8082
taskKey[Unit]("Generate all bloop configuration files")
81-
val bloopGenerate: TaskKey[Option[File]] =
82-
taskKey[Option[File]]("Generate bloop configuration file for this project")
83+
val bloopGenerate: TaskKey[Result[Option[File]]] =
84+
taskKey[Result[Option[File]]]("Generate bloop configuration file for this project")
8385
val bloopPostGenerate: TaskKey[Unit] =
8486
taskKey[Unit]("Force resource generators for Bloop.")
8587

@@ -866,7 +868,7 @@ object BloopDefaults {
866868
private[bloop] val targetNamesToConfigs =
867869
new ConcurrentHashMap[String, GeneratedProject]()
868870

869-
def bloopGenerate: Def.Initialize[Task[Option[File]]] = Def.taskDyn {
871+
def bloopGenerate: Def.Initialize[Task[Result[Option[File]]]] = Def.taskDyn {
870872
val logger = Keys.streams.value.log
871873
val project = Keys.thisProject.value
872874
val scoped = Keys.resolvedScoped.value
@@ -882,16 +884,16 @@ object BloopDefaults {
882884
}
883885

884886
lazy val generated = Option(targetNamesToConfigs.get(projectName))
885-
if (isMetaBuild && configuration == Test) inlinedTask[Option[File]](None)
886-
else if (!hasConfigSettings) inlinedTask[Option[File]](None)
887+
if (isMetaBuild && configuration == Test) inlinedTask[Result[Option[File]]](Value(None))
888+
else if (!hasConfigSettings) inlinedTask[Result[Option[File]]](Value(None))
887889
else if (generated.isDefined && generated.get.fromSbtUniverseId == currentSbtUniverse) {
888890
Def.task {
889891
// Force source generators on this task manually
890892
Keys.managedSources.value
891893

892894
// Force classpath to force side-effects downstream to fully simulate `bloopGenerate`
893895
val _ = emulateDependencyClasspath.value
894-
generated.map(_.outPath.toFile)
896+
Value(generated.map(_.outPath.toFile))
895897
}
896898
} else
897899
{
@@ -1066,15 +1068,9 @@ object BloopDefaults {
10661068

10671069
logger.debug(s"Bloop wrote the configuration of project '$projectName' to '$outFile'")
10681070
logger.success(s"Generated $userFriendlyConfigPath")
1069-
Some(outFile)
1071+
Option(outFile)
10701072
}
1071-
}.result.map {
1072-
case Inc(cause) =>
1073-
logger.error(s"Couldn't run bloopGenerate for $projectName. Cause:\n$cause")
1074-
None
1075-
case Value(maybeFile) =>
1076-
maybeFile
1077-
}
1073+
}.result
10781074
}
10791075

10801076
/**
@@ -1119,6 +1115,7 @@ object BloopDefaults {
11191115
}
11201116

11211117
def bloopInstall: Def.Initialize[Task[Unit]] = Def.taskDyn {
1118+
val logger = Keys.streams.value.log
11221119
val filter = sbt.ScopeFilter(
11231120
sbt.inAnyProject,
11241121
sbt.inAnyConfiguration,
@@ -1139,9 +1136,25 @@ object BloopDefaults {
11391136
BloopKeys.bloopGenerate
11401137
.all(filter)
11411138
.map(_.toSet)
1139+
.map(_.foldLeft(Set.empty[Option[File]] -> Set.empty[Incomplete]) {
1140+
case ((succ, fail), res) =>
1141+
res match {
1142+
case Inc(incomplete) => succ -> (fail + incomplete)
1143+
case Value(fileOpt) => (succ + fileOpt) -> fail
1144+
}
1145+
})
11421146
// Smart trick to modify state once a task has completed (who said tasks cannot alter state?)
1143-
.apply((t: Task[Set[Option[File]]]) => sbt.SessionVar.transform(t, removeProjects))
1144-
.map(_ => ())
1147+
.apply((t: Task[(Set[Option[File]], Set[Incomplete])]) =>
1148+
sbt.SessionVar
1149+
.transform(t.map { case (files, _) => files }, removeProjects)
1150+
.flatMap(_ => t.map { case (_, fail) => fail })
1151+
)
1152+
.map(fail =>
1153+
if (fail.nonEmpty) {
1154+
logger.error(s"Couldn't run bloopGenerate. Cause: ${fail.mkString("\n")}")
1155+
throw fail.head
1156+
}
1157+
)
11451158
}
11461159

11471160
lazy val bloopConfigDir: Def.Initialize[Option[File]] = Def.setting { None }

0 commit comments

Comments
 (0)