Created
October 8, 2014 15:27
-
-
Save freekh/baea6ec3fce1b138f3e8 to your computer and use it in GitHub Desktop.
Component model tester
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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())) | |
) | |
) | |
) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Results: