Skip to content

Instantly share code, notes, and snippets.

@freekh
Created October 8, 2014 15:27
Show Gist options
  • Save freekh/baea6ec3fce1b138f3e8 to your computer and use it in GitHub Desktop.
Save freekh/baea6ec3fce1b138f3e8 to your computer and use it in GitHub Desktop.
Component model tester
package adept.gradle
import adept.artifact.models.{ArtifactAttribute, ArtifactHash}
import adept.hash.Hasher
import adept.resolution.models._
import org.scalatest.{FunSuite, Matchers}
import _root_.java.io.File
//DSL helpers
object Methods {
def platform(ids: (String, String)*): Dimension = {
new Dimension {
override val varies = true
override def toRequirements: Set[Requirement] = ids.map { case (name, version) =>
//lookup real platform (jvm platform and get requirements for there)
Requirement(Id(name + "/platform"), Set(Constraint("binary-version", Set(version))), Set.empty)
}.toSet
}
}
def sources(sourceTypes: SourceType*): Sources = {
sourceTypes.map(_.toSources).reduce(_ ++ _)
}
def requires(c: ComponentSpec*): Dimension = {
new Dimension {
override val varies = false
override def toRequirements: Set[Requirement] = c.flatMap(_.toRequirements).toSet
}
}
}
class GradleTests extends FunSuite with Matchers {
import adept.test.ResolverUtils._
import Methods._
test("basic deps") {
val myLib = ComponentSpec("myLib")
val myLib2 = ComponentSpec("myLib2")
val specs = Set(myLib, myLib2)
val compilers = Set(
JavaCompiler("java/compiler", location = new File("/Library/Java/JavaVirtualMachines/jdk1.7.0_25.jdk/Contents/Home/bin/javac")),
JavaCompiler("java/compiler", location = new File("/Library/Java/JavaVirtualMachines/jdk1.8.0_11.jdk/Contents/Home/bin/javac"))
).flatMap(_.toVariants)
val platforms = Set(JvmPlatform("java/platform", 7), JvmPlatform("java/platform", 8)).flatMap(_.toVariants)
{
val components = collection.mutable.Set.empty[Component]
//SNIPPET... (CLOSEST SCALA DSL I COULD DO IN 10 MINS, NOT REALLY IMPORTANT)
myLib(JvmLibrary)(
platform("java" -> "6"),
sources (
java()
)
).register(components)
myLib2(JvmLibrary)(
platform("java" -> "7", "java" -> "8"),
requires(
myLib
)
).register(components)
//...SNIPPET
val allVariants = components.flatMap(_.toVariants) ++ compilers ++ platforms
val variantsLoader = getMemoryLoader(allVariants.toSet) //cached
val componentVariants = components.flatMap(_.toVariants)
val variations = componentVariants.toSeq
.combinations(componentVariants.size) //all combinations (of all component variations)
.filter(_.map(_.id).toSet.size == components.size) //keep only combinations that are composed of different components (not optimal)
variations.foreach { variants =>
val requirements = variants.flatMap(_.requirements)
println(resolve(requirements.toSet, variantsLoader))
}
}
}
}
//Base types:
trait Provided {
def toVariants: Set[Variant]
}
trait Required {
def toRequirements: Set[Requirement]
}
trait Dimension extends Required {
val varies: Boolean
}
trait Platform extends Provided {
val name: String
}
trait Compiler extends Provided
// Components:
trait Component extends Provided {
def register(container: collection.mutable.Set[Component]): Unit = {
container += this
}
}
case class ComponentSpec(name: String) extends Required {
def apply[T <: Component](c: ComponentType[T])(dims: Dimension*): T = {
c.newInstance(name, dims.toSet)
}
def toRequirements = Set(
Requirement(Id(name), Set.empty, Set.empty)
)
}
trait ComponentType[T <: Component] {
def newInstance(name: String, dims: Set[Dimension]): T
}
case class JvmComponent(name: String, dims: Set[Dimension]) extends Component {
def toVariants = {
val varyingDims = dims.filter(_.varies)
if (varyingDims.isEmpty) {
Set(Variant(Id(name), requirements = dims.flatMap(_.toRequirements)))
} else {
for {
varyingDim <- varyingDims if varyingDim.varies
others = (dims -- varyingDims)
varyingReq <- varyingDim.toRequirements
} yield {
Variant(Id(name), requirements = others.flatMap(_.toRequirements) + varyingReq)
}
}
}
}
case object JvmLibrary extends ComponentType[JvmComponent] {
def newInstance(name: String, dims: Set[Dimension]) = {
new JvmComponent(name, dims)
}
}
//Platform:
case class JvmPlatform(override val name: String, jvmVersion: Int) extends Platform {
private val binaryVersions = (1 to jvmVersion).reverse.map(_.toString).toSet
override def toVariants: Set[Variant] = Set(
Variant(Id(name), attributes = Set(Attribute("binary-version", binaryVersions), Attribute("jvm-version", Set(jvmVersion.toString))))
)
}
// Sources:
trait SourceType {
val srcDir: String
def toSources: Sources
}
case class java(override val srcDir: String = "src/main/java") extends SourceType {
def toSources: Sources = Sources(Set("java/compiler"))
}
case class scala(override val srcDir: String = "src/main/scala") extends SourceType {
def toSources: Sources = Sources(Set("scala/compiler"))
}
case class Sources(names: Set[String]) extends Dimension {
override def toRequirements: Set[Requirement] = names.map { name =>
Requirement(Id(name), constraints = Set.empty, exclusions = Set.empty)
}
override val varies = false
def ++(other: Sources) = Sources(this.names ++ other.names)
}
//Compilers:
case class JavaCompiler(name: String, location: File) extends Compiler {
import collection.JavaConverters._
def toVariants: Set[Variant] = {
val hash = Hasher.hash(location.getAbsolutePath.getBytes) //bogus
val version = {
import _root_.scala.sys.process._
val buffer = new StringBuffer()
val cmd = Seq(location.getAbsolutePath, "-version")
val lines = cmd lines_! ProcessLogger(buffer append _)
(lines, buffer)
buffer.toString
}
val JavacVersionPattern = """javac 1\.(\d+)\..*?""".r
val (binaryVersion, binaryVersions) = version match {
case JavacVersionPattern(binaryVersion) => binaryVersion -> (1 to binaryVersion.toInt).reverse.map(_.toString)
}
val JavacFullVersionPattern = """javac (1\.\d+\..*?)""".r
val JavacFullVersionPattern(fullVersion) = version
Set(
Variant(Id(name),
attributes = Set(
Attribute("binary-version", binaryVersions.toSet),
Attribute("full-version", Set(fullVersion))
),
requirements = Set(
Requirement(Id("java/platform"), constraints = Set(Constraint("jvm-version", Set(binaryVersion))), Set.empty)
),
artifacts = Set(
ArtifactRef(new ArtifactHash(hash), Set(new ArtifactAttribute("type", Set("compiler").asJava), new ArtifactAttribute("input-type", Set("java").asJava)), Some(location.getName()))
)
)
)
}
}
@freekh
Copy link
Author

freekh commented Oct 8, 2014

Results:


/Library/Java/JavaVirtualMachines/jdk1.8.0_05.jdk/Contents/Home/bin/java "-Dspecs2.ex=basic deps" -Didea.launcher.port=7533 "-Didea.launcher.bin.path=/Applications/IntelliJ IDEA 13 CE.app/bin" -Dfile.encoding=UTF-8 -classpath "/Users/freekh/Library/Application Support/IdeaIC13/Scala/lib/scala-plugin-runners.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_05.jdk/Contents/Home/lib/ant-javafx.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_05.jdk/Contents/Home/lib/dt.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_05.jdk/Contents/Home/lib/javafx-mx.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_05.jdk/Contents/Home/lib/jconsole.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_05.jdk/Contents/Home/lib/sa-jdi.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_05.jdk/Contents/Home/lib/tools.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_05.jdk/Contents/Home/jre/lib/charsets.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_05.jdk/Contents/Home/jre/lib/deploy.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_05.jdk/Contents/Home/jre/lib/htmlconverter.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_05.jdk/Contents/Home/jre/lib/javaws.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_05.jdk/Contents/Home/jre/lib/jce.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_05.jdk/Contents/Home/jre/lib/jfr.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_05.jdk/Contents/Home/jre/lib/jfxswt.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_05.jdk/Contents/Home/jre/lib/jsse.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_05.jdk/Contents/Home/jre/lib/management-agent.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_05.jdk/Contents/Home/jre/lib/plugin.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_05.jdk/Contents/Home/jre/lib/resources.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_05.jdk/Contents/Home/jre/lib/rt.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_05.jdk/Contents/Home/jre/lib/ext/cldrdata.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_05.jdk/Contents/Home/jre/lib/ext/dnsns.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_05.jdk/Contents/Home/jre/lib/ext/jfxrt.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_05.jdk/Contents/Home/jre/lib/ext/localedata.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_05.jdk/Contents/Home/jre/lib/ext/nashorn.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_05.jdk/Contents/Home/jre/lib/ext/sunec.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_05.jdk/Contents/Home/jre/lib/ext/sunjce_provider.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_05.jdk/Contents/Home/jre/lib/ext/sunpkcs11.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_05.jdk/Contents/Home/jre/lib/ext/zipfs.jar:/Users/freekh/Projects/adepthub-ext/adept/adept-core/target/scala-2.10/test-classes:/Users/freekh/Projects/adepthub-ext/adept/adept-core/target/scala-2.10/classes:/Users/freekh/Projects/adepthub-ext/adept/adept-lockfile/target/scala-2.10/test-classes:/Users/freekh/Projects/adepthub-ext/adept/adept-lockfile/target/scala-2.10/classes:/Users/freekh/.ivy2/cache/com.fasterxml.jackson.core/jackson-core/jars/jackson-core-2.4.0.jar:/Users/freekh/Library/Caches/IdeaIC13/SBT/boot/scala-2.10.4/lib/scala-library.jar:/Users/freekh/.ivy2/cache/org.scala-lang/scala-library/jars/scala-library-2.10.4.jar:/Users/freekh/.ivy2/cache/org.scala-lang/scala-reflect/jars/scala-reflect-2.10.0.jar:/Users/freekh/.ivy2/cache/org.scalatest/scalatest_2.10/jars/scalatest_2.10-2.0.jar:/Users/freekh/.ivy2/cache/com.googlecode.javaewah/JavaEWAH/jars/JavaEWAH-0.5.6.jar:/Users/freekh/.ivy2/cache/com.jcraft/jsch/jars/jsch-0.1.46.jar:/Users/freekh/.ivy2/cache/javax.transaction/jta/jars/jta-1.1.jar:/Users/freekh/.ivy2/cache/net.sf.ehcache/ehcache-core/jars/ehcache-core-2.6.6.jar:/Users/freekh/.ivy2/cache/org.eclipse.jgit/org.eclipse.jgit/jars/org.eclipse.jgit-3.1.0.201310021548-r.jar:/Users/freekh/.ivy2/cache/org.slf4j/slf4j-api/jars/slf4j-api-1.6.1.jar:/Applications/IntelliJ IDEA 13 CE.app/lib/idea_rt.jar" com.intellij.rt.execution.application.AppMain org.jetbrains.plugins.scala.testingSupport.scalaTest.ScalaTestRunner -s adept.gradle.GradleTests -testName "basic deps" -showProgressMessages true -C org.jetbrains.plugins.scala.testingSupport.scalaTest.ScalaTestReporter
Testing started at 17:18 ...
ResolvedResult(
  resolved: Set(myLib, java/platform)
  resolved-variants: Map(myLib -> myLib [], java/platform -> java/platform [binary-version=(8,4,5,6,1,2,7,3),jvm-version=(8)])
  implicit-variants: Map(java/compiler -> java/compiler [binary-version=(8,4,5,6,1,2,7,3),full-version=(1.8.0_11)])
  excluded: Set()
  constraints: Map(myLib -> Set(), java/compiler -> Set(), java/platform -> Set(Constraint(binary-version,Set(6)), Constraint(jvm-version,Set(8)), Constraint(binary-version,Set(8))))
)[
 - java/compiler [binary-version=(8,4,5,6,1,2,7,3),full-version=(1.8.0_11)]
  - java/platform <defined>
 - java/platform [binary-version=(8,4,5,6,1,2,7,3),jvm-version=(8)]
 - myLib []
  - java/compiler <defined>
  - java/platform <defined>
]
UnderconstrainedResult(
  resolved: Set(myLib)
  under-constrained: Set(java/compiler, java/platform)
  resolved-variants: Map(myLib -> myLib [])
  implicit-variants: Map()
  excluded: Set()
  constraints: Map(java/compiler -> Set(), java/platform -> Set(Constraint(binary-version,Set(7)), Constraint(binary-version,Set(6))), myLib -> Set())
)[
 ? java/compiler
 ? java/platform
 - myLib []
  - java/compiler <defined>
  - java/platform <defined>
]

Process finished with exit code 0

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment