Skip to content
This repository was archived by the owner on Jul 7, 2022. It is now read-only.

Commit 923e0b6

Browse files
committed
Filter manifests on valid Scala versions
Fixes a bug found in Metals where the metals project which is not cross-compiled depends on mtags which is cross-compiled
1 parent bbc7143 commit 923e0b6

File tree

4 files changed

+56
-21
lines changed

4 files changed

+56
-21
lines changed

src/main/scala/ch/epfl/scala/GithubDependencyGraphPlugin.scala

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@ import scala.util.Properties
66
import ch.epfl.scala.githubapi._
77
import sbt.Scoped.richTaskSeq
88
import sbt._
9-
import sbt.plugins.IvyPlugin
9+
import sbt.internal.util.complete.Parser
10+
import sbt.internal.util.complete.Parsers
11+
import sbt.plugins.JvmPlugin
1012
import sjsonnew.shaded.scalajson.ast.unsafe.JString
1113

1214
object GithubDependencyGraphPlugin extends AutoPlugin {
@@ -26,18 +28,18 @@ object GithubDependencyGraphPlugin extends AutoPlugin {
2628
val githubManifestsKey: AttributeKey[Map[String, githubapi.Manifest]] = AttributeKey("githubDependencyManifests")
2729
val githubProjectsKey: AttributeKey[Seq[ProjectRef]] = AttributeKey("githubProjectRefs")
2830
val githubDependencyManifest: TaskKey[githubapi.Manifest] = taskKey("The dependency manifest of the project")
29-
val githubStoreDependencyManifests: TaskKey[StateTransform] =
30-
taskKey("Store the dependency manifests of all projects in the attribute map.")
31+
val githubStoreDependencyManifests: InputKey[StateTransform] =
32+
inputKey("Store the dependency manifests of all projects of a Scala version in the attribute map.")
3133
.withRank(KeyRanks.DTask)
3234
}
3335

3436
import autoImport._
3537

3638
override def trigger = allRequirements
37-
override def requires: Plugins = IvyPlugin
39+
override def requires: Plugins = JvmPlugin
3840

3941
override def globalSettings: Seq[Setting[_]] = Def.settings(
40-
githubStoreDependencyManifests := storeManifestsTask.value,
42+
githubStoreDependencyManifests := storeManifestsTask.evaluated,
4143
Keys.commands ++= SubmitDependencyGraph.commands
4244
)
4345

@@ -46,12 +48,27 @@ object GithubDependencyGraphPlugin extends AutoPlugin {
4648
githubDependencyManifest / Keys.aggregate := false
4749
)
4850

49-
private def storeManifestsTask: Def.Initialize[Task[StateTransform]] = Def.taskDyn {
50-
val projectRefs = Keys.state.value
51+
private val scalaVersionParser = {
52+
import Parsers._
53+
import Parser._
54+
val validOpChars = Set('.', '-', '+')
55+
identifier(
56+
charClass(alphanum, "alphanum"),
57+
charClass(c => alphanum(c) || validOpChars.contains(c), "version character")
58+
)
59+
}
60+
61+
private def storeManifestsTask: Def.Initialize[InputTask[StateTransform]] = Def.inputTaskDyn {
62+
val scalaVersionInput = (Parsers.Space ~> scalaVersionParser).parsed
63+
val state = Keys.state.value
64+
65+
val projectRefs = state
5166
.get(githubProjectsKey)
5267
.getOrElse(
5368
throw new MessageOnlyException(s"The ${githubProjectsKey.label} attribute is not initialized")
5469
)
70+
.filter(ref => state.setting(ref / Keys.scalaVersion) == scalaVersionInput)
71+
5572
Def.task {
5673
val manifests: Map[String, Manifest] = projectRefs
5774
.map(ref => (ref / githubDependencyManifest).?)

src/main/scala/ch/epfl/scala/SubmitDependencyGraph.scala

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -45,14 +45,14 @@ object SubmitDependencyGraph {
4545

4646
private def submit(state: State, input: SubmitInput): State = {
4747
checkGithubEnv() // fail fast if the Github CI environment is incomplete
48-
val projectRefs = getProjectRefs(state, input)
48+
val projectRefs = getScalaProjectRefs(state, input)
4949
val scalaVersions = getScalaVersions(state, input, projectRefs)
5050
val initState = state
5151
.put(githubManifestsKey, Map.empty[String, Manifest])
5252
.put(githubProjectsKey, projectRefs)
5353

5454
val storeAllManifests = scalaVersions.flatMap { scalaVersion =>
55-
Seq(s"++$scalaVersion", githubStoreDependencyManifests.key.label)
55+
Seq(s"++$scalaVersion", s"${githubStoreDependencyManifests.key} $scalaVersion")
5656
}
5757
val commands = storeAllManifests :+ SubmitInternal
5858
commands.toList ::: initState
@@ -89,12 +89,15 @@ object SubmitDependencyGraph {
8989
}
9090
}
9191

92-
private def getProjectRefs(state: State, input: SubmitInput): Seq[ProjectRef] = {
92+
// project refs that have a Scala version, filtered according to input.projects
93+
private def getScalaProjectRefs(state: State, input: SubmitInput): Seq[ProjectRef] = {
9394
val loadedBuild = state.setting(Keys.loadedBuild)
94-
val allProjectRefs = loadedBuild.allProjectRefs.map(_._1)
95+
val allScalaProjectRefs = loadedBuild.allProjectRefs
96+
.map(_._1)
97+
.filter(ref => state.getSetting(ref / Keys.scalaVersion).isDefined)
9598
val projectFilter = input.projects.toSet
96-
if (projectFilter.isEmpty) allProjectRefs
97-
else allProjectRefs.filter(ref => projectFilter.contains(ref.project))
99+
if (projectFilter.isEmpty) allScalaProjectRefs
100+
else allScalaProjectRefs.filter(ref => projectFilter.contains(ref.project))
98101
}
99102

100103
private def getScalaVersions(state: State, input: SubmitInput, projectRefs: Seq[ProjectRef]): Seq[String] = {

src/sbt-test/dependency-graph/ci-submit/build.sbt

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,31 +7,42 @@ inThisBuild(
77
Seq(
88
organization := "ch.epfl.scala",
99
version := "1.2.0-SNAPSHOT",
10-
useCoursier := true,
11-
scalaVersion := "2.12.15",
10+
scalaVersion := "2.13.8"
11+
)
12+
)
13+
14+
val a = project
15+
.in(file("a"))
16+
.settings(
17+
scalaVersion := "2.13.8",
1218
crossScalaVersions := Seq(
1319
"2.12.16",
1420
"2.13.8",
1521
"3.1.3"
1622
)
1723
)
18-
)
19-
20-
val a = project.in(file("a"))
2124

25+
// b is not cross-compiled
26+
// but we should still be able to resolve the manifests of the build on 2.12.16 and 3.1.3
27+
// this pattern is taken from scalameta/metals where metals, not cross-compiled, depends on mtags
28+
// which is cross-compiled
2229
val b = project
2330
.in(file("b"))
2431
.settings(
25-
libraryDependencies += "org.typelevel" %% "cats-core" % "2.8.0"
32+
scalaVersion := "2.13.8"
2633
)
34+
.dependsOn(a)
2735

28-
Global / checkManifests := {
36+
checkManifests := {
37+
val logger = streams.value.log
2938
val expectedSize: Int = (Space ~> NatBasic).parsed
3039
val manifests = state.value.get(githubManifestsKey).getOrElse {
3140
throw new MessageOnlyException(s"Not found ${githubManifestsKey.label} attribute")
3241
}
42+
logger.info(s"found ${manifests.size} manifests")
3343
assert(
3444
manifests.size == expectedSize,
3545
s"expected $expectedSize manifests, found ${manifests.size}"
3646
)
3747
}
48+
checkManifests / aggregate := false
Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
> 'githubSubmitDependencyGraph {}'
2-
> checkManifests 9
2+
> checkManifests 5
33
> 'githubSubmitDependencyGraph {"projects":[], "scalaVersions":["2.13.8"]}'
44
> checkManifests 3
5+
> 'githubSubmitDependencyGraph {"projects":[], "scalaVersions":["2.12.16", "2.13.8"]}'
6+
> checkManifests 4
7+
> 'githubSubmitDependencyGraph {"projects":["a", "b"], "scalaVersions":[]}'
8+
> checkManifests 4
59
> 'githubSubmitDependencyGraph {"projects":["a"], "scalaVersions":["2.12.16", "3.1.3"]}'
610
> checkManifests 2

0 commit comments

Comments
 (0)