Skip to content

Commit

Permalink
Add CI command alias derived from the sbt-github-actions matrix, reso…
Browse files Browse the repository at this point in the history
…lves #202
  • Loading branch information
DavidGregory084 committed Mar 14, 2022
1 parent bc913e6 commit 450c07e
Showing 1 changed file with 93 additions and 4 deletions.
97 changes: 93 additions & 4 deletions ci/src/main/scala/org/typelevel/sbt/TypelevelCiPlugin.scala
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,11 @@

package org.typelevel.sbt

import sbt._
import com.typesafe.tools.mima.plugin.MimaPlugin
import org.typelevel.sbt.gha.GenerativePlugin
import org.typelevel.sbt.gha.GitHubActionsPlugin
import org.typelevel.sbt.gha.GenerativePlugin.autoImport._
import com.typesafe.tools.mima.plugin.MimaPlugin
import org.typelevel.sbt.gha.GitHubActionsPlugin
import sbt._

object TypelevelCiPlugin extends AutoPlugin {

Expand All @@ -46,12 +46,101 @@ object TypelevelCiPlugin extends AutoPlugin {
cond = Some(primaryJavaCond.value)
)
),
githubWorkflowJavaVersions := Seq(JavaSpec.temurin("8"))
githubWorkflowJavaVersions := Seq(JavaSpec.temurin("8")),
GlobalScope / Keys.onLoad := {
val oses = githubWorkflowOSes.value.toList
val javas = githubWorkflowJavaVersions.value.toList
val scalas = githubWorkflowScalaVersions.value.toList
val additions = githubWorkflowBuildMatrixAdditions.value
val inclusions = githubWorkflowBuildMatrixInclusions.value.toList
val exclusions = githubWorkflowBuildMatrixExclusions.value.toList
val stepPreamble = githubWorkflowBuildSbtStepPreamble.value.toList

(GlobalScope / Keys.onLoad).value.compose { (state: State) =>
addCiAlias(
state,
oses,
javas,
scalas,
additions,
inclusions,
exclusions,
stepPreamble,
githubWorkflowBuild.value
)
}
},
GlobalScope / Keys.onUnload := {
(GlobalScope / Keys.onUnload)
.value
.compose((state: State) => BasicCommands.removeAlias(state, "ci"))
}
)

private val primaryJavaCond = Def.setting {
val java = githubWorkflowJavaVersions.value.head
s"matrix.java == '${java.render}'"
}

private def addCiAlias(
state: State,
oses: List[String],
javaVersions: List[JavaSpec],
scalaVersions: List[String],
matrixAdditions: Map[String, List[String]],
matrixInclusions: List[MatrixInclude],
matrixExclusions: List[MatrixExclude],
sbtStepPreamble: List[String],
workflowSteps: Seq[WorkflowStep]) = {

val buildMatrix = GenerativePlugin.expandMatrix(
// Cannot meaningfully iterate OS or Java version here
oses = oses.take(1),
javas = javaVersions.take(1),
scalas = scalaVersions,
matrixAdds = matrixAdditions,
includes = matrixInclusions,
excludes = matrixExclusions
)

val keys = "os" :: "scala" :: "java" :: matrixAdditions.keys.toList.sorted

val commands = for {
matrixRow <- buildMatrix
matrixValues = keys.zip(matrixRow).toMap
step <- workflowSteps.collect {
case sbt: WorkflowStep.Sbt if matchingCondition(sbt, matrixValues) => sbt
}
command <- sbtStepPreamble ++ step.commands
} yield replaceMatrixVars(command, matrixValues)

val commandAlias = TypelevelKernelPlugin.mkCommand(commands)

BasicCommands.addAlias(
state,
"ci",
commandAlias
)
}

private def matchingCondition(
command: WorkflowStep.Sbt,
matrixValues: Map[String, String]) = {
// For all matrix values
matrixValues.forall {
case (k, v) =>
val renderedCond = s"matrix.$k == '$v'"

command.cond.forall { cond =>
// If the condition starts with this matrix variable, whole condition must be equal
if (cond.startsWith(s"matrix.$k")) cond == renderedCond else true
}
}
}

private def replaceMatrixVars(command: String, matrixValues: Map[String, String]): String =
matrixValues.foldLeft(command) {
case (cmd, (matrixVar, matrixVarValue)) =>
cmd.replaceAll(s"\\$$\\{\\{ matrix.${matrixVar} \\}\\}", matrixVarValue)
}
}

0 comments on commit 450c07e

Please sign in to comment.