diff options
author | Christopher Vogt <oss.nsp@cvogt.org> | 2016-03-26 16:20:50 -0400 |
---|---|---|
committer | Christopher Vogt <oss.nsp@cvogt.org> | 2016-03-28 11:53:52 -0400 |
commit | bd75b5af0161013b26e2feda9cfcc1e152926071 (patch) | |
tree | 6fef7506f432f780fa64bca5afd5f944790be196 /stage2/AdminTasks.scala | |
parent | 2c20a0dddc70a5eee207fb1c588bfd53eaaa7841 (diff) | |
download | cbt-bd75b5af0161013b26e2feda9cfcc1e152926071.tar.gz cbt-bd75b5af0161013b26e2feda9cfcc1e152926071.tar.bz2 cbt-bd75b5af0161013b26e2feda9cfcc1e152926071.zip |
Early classloading improvements
- Changed launcher to already load zinc
- use code generation to generate necessary dependencies
- changed resolver to linearize dependency DAG in a way that guarantees that every transitive dependee of a node in the DAG is a transitive dependee of that node in the linear sequence
- move exit code trapping code into java so it can be used for zinc early
There seems to be a bug in this version, where CBT crashes about half of the time with a "object is not an instance of declaring class" Exception during running the task from the build object via reflection.
Diffstat (limited to 'stage2/AdminTasks.scala')
-rw-r--r-- | stage2/AdminTasks.scala | 96 |
1 files changed, 93 insertions, 3 deletions
diff --git a/stage2/AdminTasks.scala b/stage2/AdminTasks.scala index f825cc1..47fcce3 100644 --- a/stage2/AdminTasks.scala +++ b/stage2/AdminTasks.scala @@ -1,6 +1,7 @@ package cbt import scala.collection.immutable.Seq -import java.io._ +import java.io.{Console=>_,_} +import java.nio.file._ class AdminTasks(lib: Lib, args: Array[String], cwd: File){ implicit val logger: Logger = lib.logger def resolve = { @@ -8,7 +9,7 @@ class AdminTasks(lib: Lib, args: Array[String], cwd: File){ args(1).split(",").toVector.map{ d => val v = d.split(":") - new JavaDependency(v(0),v(1),v(2))(lib.logger).classpath + new JavaDependency(v(0),v(1),v(2)).classpath } ) } @@ -16,7 +17,7 @@ class AdminTasks(lib: Lib, args: Array[String], cwd: File){ args(1).split(",").toVector.map{ d => val v = d.split(":") - new JavaDependency(v(0),v(1),v(2))(lib.logger).dependencyTree + new JavaDependency(v(0),v(1),v(2)).dependencyTree }.mkString("\n\n") } def amm = ammonite @@ -39,4 +40,93 @@ class AdminTasks(lib: Lib, args: Array[String], cwd: File){ ) } def scaffoldBasicBuild: Unit = lib.scaffoldBasicBuild( cwd ) + def cbtEarlyDependencies = { + val scalaVersion = args.lift(1).getOrElse(constants.scalaVersion) + val scalaMajorVersion = scalaVersion.split("\\.").take(2).mkString(".") + val scalaXmlVersion = args.lift(2).getOrElse(constants.scalaXmlVersion) + val zincVersion = args.lift(3).getOrElse(constants.zincVersion) + /* + def tree(d: JavaDependency, indent: Int): String ={ + val dependencies = { + if( d.dependencies.nonEmpty ){ + d.dependencies.map{ + case d: JavaDependency => tree(d,indent + 1) + }.mkString(",\n" ++ ( " " * indent ),",\n" ++ ( " " * indent ), "") + } else "" + } + ( + s"""new EarlyDependency( "${d.groupId}", "${d.artifactId}", "${d.version}", "${d.jarSha1}"$dependencies)""" + ) + }*/ + val scalaDeps = Seq( + JavaDependency("org.scala-lang","scala-reflect",scalaVersion), + JavaDependency("org.scala-lang","scala-compiler",scalaVersion) + ) + + val scalaXml = Dependencies( + JavaDependency("org.scala-lang.modules","scala-xml_"+scalaMajorVersion,scalaXmlVersion), + JavaDependency("org.scala-lang","scala-library",scalaVersion) + ) + + val zinc = JavaDependency("com.typesafe.zinc","zinc",zincVersion) + println(zinc.dependencyTree) + + def valName(dep: JavaDependency) = { + val words = dep.artifactId.split("_").head.split("-") + words(0) ++ words.drop(1).map(s => s(0).toString.toUpperCase ++ s.drop(1)).mkString ++ "_" ++ dep.version.replace(".","_") ++ "_" + } + + def vals(d: JavaDependency) = s""" """ + + def jarVal(dep: JavaDependency) = "_" + valName(dep) +"Jar" + def transitive(dep: Dependency) = (dep +: dep.transitiveDependencies.reverse).collect{case d: JavaDependency => d} + def codeEach(dep: Dependency) = { + transitive(dep).tails.map(_.reverse).toVector.reverse.drop(1).map{ + deps => + val d = deps.last + val parents = deps.dropRight(1) + val parentString = if(parents.isEmpty) "" else ( ", " ++ valName(parents.last) ) + val n = valName(d) + s""" + // ${d.groupId}:${d.artifactId}:${d.version} + download(new URL(MAVEN_URL + "${d.basePath}.jar"), Paths.get(${n}File), "${d.jarSha1}"); + ClassLoader $n = cachePut( + classLoader( ${n}File$parentString ), + ${deps.sortBy(_.jar).map(valName(_)+"File").mkString(", ")} + );""" + } + } + val assignments = codeEach(zinc) ++ codeEach(scalaXml) + //{ case (name, dep) => s"$name =\n ${tree(dep, 4)};" }.mkString("\n\n ") + val code = s"""// This file was auto-generated using `cbt admin cbtEarlyDependencies` +package cbt; +import java.io.*; +import java.nio.file.*; +import java.net.*; +import java.security.*; +import static cbt.NailgunLauncher.*; + +class EarlyDependencies{ + + /** ClassLoader for stage1 */ + ClassLoader stage1; + /** ClassLoader for zinc */ + ClassLoader zinc; + +${(scalaDeps ++ transitive(scalaXml) ++ transitive(zinc)).map(d => s""" String ${valName(d)}File = MAVEN_CACHE + "${d.basePath}.jar";""").mkString("\n")} + + public EarlyDependencies() throws MalformedURLException, IOException, NoSuchAlgorithmException{ +${scalaDeps.map(d => s""" download(new URL(MAVEN_URL + "${d.basePath}.jar"), Paths.get(${valName(d)}File), "${d.jarSha1}");""").mkString("\n")} +${assignments.mkString("\n")} + + stage1 = scalaXml_${scalaXmlVersion.replace(".","_")}_; + + zinc = zinc_${zincVersion.replace(".","_")}_; + } +} +""" + val file = paths.nailgun ++ ("/" ++ "EarlyDependencies.java") + Files.write( file.toPath, code.getBytes ) + println( Console.GREEN ++ "Wrote " ++ file.string ++ Console.RESET ) + } } |