package cbt
import java.net._
import java.io.{Console=>_,_}
import java.nio.file._
class ToolsTasks(
lib: Lib,
args: Seq[String],
cwd: File,
cache: File,
cbtHome: File,
cbtLastModified: Long
)(implicit classLoaderCache: ClassLoaderCache){
def apply: String = "Available methods: " ++ lib.taskNames(getClass).mkString(" ")
override def toString = lib.usage(this.getClass, super.toString)
private val paths = CbtPaths(cbtHome, cache)
import paths._
implicit val logger: Logger = lib.logger
implicit val transientCache: java.util.Map[AnyRef,AnyRef] = new java.util.HashMap
private def Resolver( urls: URL* ) = MavenResolver(cbtLastModified,mavenCache,urls: _*)
val scaffold = new Scaffold(logger)
def createMain: Unit = scaffold.createMain( cwd )
def createBuild: Unit = scaffold.createBuild( cwd )
def `search-class` = java.awt.Desktop.getDesktop().browse(new URI(
"http://search.maven.org/#search%7Cga%7C1%7Cc%3A%22" ++ URLEncoder.encode(args(1),"UTF-8") ++ "%22"
))
def gui = NailgunLauncher.main(Array(
"0.0",
(cbtHome / "tools" / "gui").getAbsolutePath,
"0",
"run",
cwd.getAbsolutePath,
constants.scalaMajorVersion
))
def resolve = {
ClassPath.flatten(
args(1).split(",").toVector.map{
d =>
val v = d.split(":")
Resolver(mavenCentral, sonatypeSnapshots).bindOne(MavenDependency(v(0),v(1),v(2))).classpath
}
)
}
def dependencyTree = {
args(1).split(",").toVector.map{
d =>
val v = d.split(":")
Resolver(mavenCentral).bindOne(MavenDependency(v(0),v(1),v(2))).dependencyTree
}.mkString("\n\n")
}
def amm = ammonite
def ammonite = {
val version = args.lift(1).getOrElse(constants.scalaVersion)
val ammonite = Resolver(mavenCentral).bindOne(
MavenDependency(
"com.lihaoyi","ammonite-repl_"++constants.scalaVersion,args.lift(1).getOrElse("0.5.8")
)
)
// FIXME: this does not work quite yet, throws NoSuchFileException: /ammonite/repl/frontend/ReplBridge$.class
ammonite.runMain(
"ammonite.repl.Main", args.drop(2)
)
}
def scala = {
val version = args.lift(1).getOrElse(constants.scalaVersion)
val scalac = new ScalaCompilerDependency( cbtLastModified, mavenCache, version )
val _args = Seq("-cp", scalac.classpath.string) ++ args.drop(2)
scalac.runMain(
"scala.tools.nsc.MainGenericRunner", _args
)
}
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)
val scalaDeps = Seq(
Resolver(mavenCentral).bindOne(MavenDependency("org.scala-lang","scala-reflect",scalaVersion)),
Resolver(mavenCentral).bindOne(MavenDependency("org.scala-lang","scala-compiler",scalaVersion))
)
val scalaXml = Dependencies(
Resolver(mavenCentral).bind(
MavenDependency("org.scala-lang.modules","scala-xml_"+scalaMajorVersion,scalaXmlVersion),
MavenDependency("org.scala-lang","scala-library",scalaVersion)
)
)
val zinc = Resolver(mavenCentral).bindOne(MavenDependency("com.typesafe.zinc","zinc",zincVersion))
val sbtVersion =
zinc.dependencies
.collect{ case d @
BoundMavenDependency(
_, _, MavenDependency( "com.typesafe.sbt", "compiler-interface", _, Classifier.sources, _), _, _
) => d
}
.headOption
.getOrElse( throw new Exception(s"cannot find compiler-interface in zinc $zincVersion dependencies: "++zinc.dependencies.toString) )
.mavenDependency
.version
def valName(dep: BoundMavenDependency) = {
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 jarVal(dep: BoundMavenDependency) = "_" + valName(dep) +"Jar"
def transitive(dep: Dependency) = (dep +: lib.transitiveDependencies(dep).reverse).collect{case d: BoundMavenDependency => 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) "rootClassLoader" else ( valName(parents.last) )
val n = valName(d)
s"""
// ${d.groupId}:${d.artifactId}:${d.version}
String[] ${n}ClasspathArray = new String[]{${deps.sortBy(_.jar).map(valName(_)+"File").mkString(", ")}};
ClassLoader $n = loadDependency(
mavenUrl + "${d.basePath(true)}.jar",
${n}File,
"${d.jarSha1}",
classLoaderCache,
$parentString,
${n}ClasspathArray
);"""
}
}
val assignments = codeEach(zinc) ++ codeEach(scalaXml)
val files = scalaDeps ++ transitive(scalaXml) ++ transitive(zinc)
val _scalaVersion = scalaVersion.replace(".","_")
val _scalaXmlVersion = scalaXmlVersion.replace(".","_")
val _zincVersion = zincVersion.replace(".","_")
val _sbtVersion = sbtVersion.replace(".","_")
//{ case (name, dep) => s"$name =\n ${tree(dep, 4)};" }.mkString("\n\n ")
val code = s"""// This file was auto-generated using `cbt tools cbtEarlyDependencies`
package cbt;
import java.io.*;
import java.nio.file.*;
import java.net.*;
import java.security.*;
import java.util.*;
import static cbt.Stage0Lib.*;
import static cbt.NailgunLauncher.*;
public class EarlyDependencies{
public static String scalaVersion = "$scalaVersion";
public static String scalaXmlVersion = "$scalaXmlVersion";
public static String zincVersion = "$zincVersion";
/** ClassLoader for stage1 */
ClassLoader classLoader;
String[] classpathArray;
/** ClassLoader for zinc */
ClassLoader zinc;
String scalaCompiler_File;
String scalaLibrary_File;
String scalaReflect_File;
String sbtInterface_File;
String compilerInterface_File;
public EarlyDependencies(
String mavenCache, String mavenUrl, ClassLoaderCache classLoaderCache, ClassLoader rootClassLoader
) throws Throwable {
${files.map(d => s""" String ${valName(d)}File = mavenCache + "${d.basePath(true)}.jar";""").mkString("\n")}
${scalaDeps.map(d => s""" download(new URL(mavenUrl + "${d.basePath(true)}.jar"), Paths.get(${valName(d)}File), "${d.jarSha1}");""").mkString("\n")}
${assignments.mkString("\n")}
classLoader = scalaXml_${_scalaXmlVersion}_;
classpathArray = scalaXml_${_scalaXmlVersion}_ClasspathArray;
zinc = zinc_${_zincVersion}_;
scalaCompiler_File = scalaCompiler_${_scalaVersion}_File;
scalaLibrary_File = scalaLibrary_${_scalaVersion}_File;
scalaReflect_File = scalaReflect_${_scalaVersion}_File;
sbtInterface_File = sbtInterface_${_sbtVersion}_File;
compilerInterface_File = compilerInterface_${_sbtVersion}_File;
}
}
"""
val file = nailgun ++ ("/" ++ "EarlyDependencies.java")
lib.writeIfChanged( file, code )
println( Console.GREEN ++ "Wrote " ++ file.string ++ Console.RESET )
}
}