Skip to content

Commit e4f7533

Browse files
committed
Refactor sbt project workarounds
1 parent 220b9c6 commit e4f7533

File tree

4 files changed

+119
-65
lines changed

4 files changed

+119
-65
lines changed

build.sbt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -164,10 +164,9 @@ lazy val sbtProject = (project in file("sbt"))
164164
.settings(commonProjectSettings)
165165
.settings(
166166
libraryDependencies ++= {
167-
// Don't add dependencies when the rest of the build is cross building with Scala 2.13
168-
// otherwise it will cause a whole lot of resolution failures.
169-
if ((core / isScala213).value) Nil
170-
else
167+
// Only add dependencies when the build is building with a Scala version that is
168+
// sbt compatible otherwise it will cause a whole lot of resolution failures.
169+
if (spspIsSbtCompatibleScalaVersion.value)
171170
collectionsCompatibilityDependency.value ++ List(
172171
"org.scala-sbt" %% "collections" % sbtVersion.value,
173172
"org.scala-sbt" %% "command" % sbtVersion.value,
@@ -183,6 +182,7 @@ lazy val sbtProject = (project in file("sbt"))
183182
"org.scala-sbt" %% "util-logging" % sbtVersion.value,
184183
"org.scala-sbt" %% "util-position" % sbtVersion.value
185184
)
185+
else Nil
186186
},
187187
name := s"sbt-${(LocalRootProject / name).value}",
188188
scriptedBufferLog := false,

project/ConditionalKeys.scala

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
import sbt.Keys.skip
2+
import sbt.{Def, InputKey, InputTask, Task, TaskKey}
3+
4+
object ConditionalKeys {
5+
6+
def settingDefaultIfSetting[A, B](
7+
setting: Def.Initialize[A],
8+
condition: Def.Initialize[B],
9+
p: B => Boolean,
10+
default: A
11+
): Def.Initialize[A] = Def.setting {
12+
if (p(condition.value)) {
13+
default
14+
} else {
15+
setting.value
16+
}
17+
}
18+
19+
def taskDefaultIfSkipped[A](task: TaskKey[A], default: A): Def.Initialize[Task[A]] =
20+
taskDefaultIfTask[A, Boolean](task, task / skip, identity, default)
21+
22+
def taskDefaultIfSetting[A, B](
23+
task: Def.Initialize[Task[A]],
24+
condition: Def.Initialize[B],
25+
p: B => Boolean,
26+
default: A
27+
): Def.Initialize[Task[A]] = Def.taskIf {
28+
if (p(condition.value)) {
29+
default
30+
} else {
31+
task.value
32+
}
33+
}
34+
35+
def taskDefaultIfTask[A, B](
36+
task: Def.Initialize[Task[A]],
37+
condition: Def.Initialize[Task[B]],
38+
p: B => Boolean,
39+
default: A
40+
): Def.Initialize[Task[A]] = Def.taskIf {
41+
if (p(condition.value)) {
42+
default
43+
} else {
44+
task.value
45+
}
46+
}
47+
48+
def inputDefaultIfSkipped[A](input: InputKey[A], default: A): Def.Initialize[InputTask[A]] =
49+
inputDefaultIfTask[A, Boolean](input, input / skip, identity, default)
50+
51+
def inputDefaultIfTask[A, B](
52+
input: InputKey[A],
53+
condition: Def.Initialize[Task[B]],
54+
p: B => Boolean,
55+
default: A
56+
): Def.Initialize[InputTask[A]] = Def.inputTaskDyn {
57+
val task = input.parsed
58+
Def.taskIf {
59+
if (p(condition.value)) {
60+
default
61+
} else {
62+
task.value
63+
}
64+
}
65+
}
66+
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
import ConditionalKeys._
2+
import explicitdeps.ExplicitDepsPlugin.autoImport._
3+
import sbt.Keys._
4+
import sbt.ScriptedPlugin.autoImport.scripted
5+
import sbt.plugins.SbtPlugin
6+
import sbt.{Def, _}
7+
8+
// This is all the crazy hacks to get cross compiling working with an sub-project that is an sbt plugin.
9+
object SbtPluginSubProjectPlugin extends AutoPlugin {
10+
11+
override def trigger: PluginTrigger = allRequirements
12+
override def requires: Plugins = SbtPlugin
13+
14+
object autoImport {
15+
val spspIsSbtCompatibleScalaVersion = settingKey[Boolean]("Checks if the current Scala version is 2.13")
16+
}
17+
18+
import autoImport._
19+
20+
override def projectSettings: Seq[Def.Setting[_]] =
21+
List(
22+
crossScalaVersions := Nil,
23+
// Remove all library dependencies for Scala 2.13 as they will not resolve when cross building.
24+
libraryDependencies := settingDefaultIfSetting(libraryDependencies, scalaVersion, isScala213, Nil).value,
25+
// Remove all project dependencies for Scala 2.13 as they will not resolve when cross building.
26+
projectDependencies := taskDefaultIfSkipped(projectDependencies, Nil).value,
27+
scripted := inputDefaultIfSkipped(scripted, ()).evaluated,
28+
spspIsSbtCompatibleScalaVersion := isSbtCompatibleScalaVersionSetting.value,
29+
// We can't skip this as it has to run at least once or sbt complains.
30+
update / skip := false,
31+
// Skip everything else otherwise it will just fail.
32+
skip := !spspIsSbtCompatibleScalaVersion.value,
33+
undeclaredCompileDependenciesFilter -= moduleFilter()
34+
)
35+
36+
private def isSbtCompatibleScalaVersionSetting = Def.setting {
37+
if (isScala213(scalaVersion.value))
38+
throw new IllegalStateException("sbt project must not use Scala 2.13. Did you force the version with '+'?")
39+
val versions =
40+
scalaVersion.all(ScopeFilter(inDependencies(ThisProject, transitive = true, includeRoot = false))).value
41+
!versions.exists(isScala213)
42+
}
43+
44+
private def isScala213(version: String) =
45+
CrossVersion.partialVersion(version) match {
46+
case Some((2, n)) if n == 13 => true
47+
case _ => false
48+
}
49+
}

project/SbtSubProjectPluginPlugin.scala

Lines changed: 0 additions & 61 deletions
This file was deleted.

0 commit comments

Comments
 (0)