aboutsummaryrefslogtreecommitdiff
path: root/stage2
diff options
context:
space:
mode:
Diffstat (limited to 'stage2')
-rw-r--r--stage2/AdminStage2.scala2
-rw-r--r--stage2/AdminTasks.scala69
-rw-r--r--stage2/BasicBuild.scala38
-rw-r--r--stage2/BuildBuild.scala72
-rw-r--r--stage2/BuildDependency.scala5
-rw-r--r--stage2/GitDependency.scala4
-rw-r--r--stage2/Lib.scala56
-rw-r--r--stage2/PackageBuild.scala10
-rw-r--r--stage2/SbtDependencyDsl.scala2
-rw-r--r--stage2/Stage2.scala36
-rw-r--r--stage2/mixins.scala22
11 files changed, 197 insertions, 119 deletions
diff --git a/stage2/AdminStage2.scala b/stage2/AdminStage2.scala
index 9d7dcb2..f4e61d0 100644
--- a/stage2/AdminStage2.scala
+++ b/stage2/AdminStage2.scala
@@ -4,7 +4,7 @@ object AdminStage2 extends Stage2Base{
def run( _args: Stage2Args ): Unit = {
val args = _args.args.dropWhile(Seq("admin","direct") contains _)
val lib = new Lib(_args.logger)
- val adminTasks = new AdminTasks(lib, args, _args.cwd, _args.classLoaderCache)
+ val adminTasks = new AdminTasks(lib, args, _args.cwd, _args.classLoaderCache, _args.cache, _args.cbtHome, _args.cbtHasChanged)
new lib.ReflectObject(adminTasks){
def usage: String = "Available methods: " ++ lib.taskNames(adminTasks.getClass).mkString(" ")
}.callNullary(args.lift(0))
diff --git a/stage2/AdminTasks.scala b/stage2/AdminTasks.scala
index f189805..9086470 100644
--- a/stage2/AdminTasks.scala
+++ b/stage2/AdminTasks.scala
@@ -2,14 +2,25 @@ package cbt
import scala.collection.immutable.Seq
import java.io.{Console=>_,_}
import java.nio.file._
-class AdminTasks(lib: Lib, args: Seq[String], cwd: File, classLoaderCache: ClassLoaderCache){
+class AdminTasks(
+ lib: Lib,
+ args: Seq[String],
+ cwd: File,
+ classLoaderCache: ClassLoaderCache,
+ cache: File,
+ cbtHome: File,
+ cbtHasChanged: Boolean
+){
+ private val paths = Paths(cbtHome, cache)
+ import paths._
+ private val mavenCentral = MavenResolver(cbtHasChanged,mavenCache,MavenResolver.central)
implicit val logger: Logger = lib.logger
def resolve = {
ClassPath.flatten(
args(1).split(",").toVector.map{
d =>
val v = d.split(":")
- MavenRepository.central.resolveOne(MavenDependency(v(0),v(1),v(2))).classpath
+ mavenCentral.resolveOne(MavenDependency(v(0),v(1),v(2))).classpath
}
)
}
@@ -17,14 +28,14 @@ class AdminTasks(lib: Lib, args: Seq[String], cwd: File, classLoaderCache: Class
args(1).split(",").toVector.map{
d =>
val v = d.split(":")
- MavenRepository.central.resolveOne(MavenDependency(v(0),v(1),v(2))).dependencyTree
+ mavenCentral.resolveOne(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 scalac = new ScalaCompilerDependency( version )
- val d = MavenRepository.central.resolveOne(
+ val scalac = new ScalaCompilerDependency( cbtHasChanged,mavenCache, version )
+ val d = mavenCentral.resolveOne(
MavenDependency(
"com.lihaoyi","ammonite-repl_2.11.7",args.lift(1).getOrElse("0.5.7")
)
@@ -36,7 +47,7 @@ class AdminTasks(lib: Lib, args: Seq[String], cwd: File, classLoaderCache: Class
}
def scala = {
val version = args.lift(1).getOrElse(constants.scalaVersion)
- val scalac = new ScalaCompilerDependency( version )
+ val scalac = new ScalaCompilerDependency( cbtHasChanged, mavenCache, version )
lib.runMain(
"scala.tools.nsc.MainGenericRunner", Seq("-cp", scalac.classpath.string), scalac.classLoader(classLoaderCache)
)
@@ -49,16 +60,16 @@ class AdminTasks(lib: Lib, args: Seq[String], cwd: File, classLoaderCache: Class
val scalaXmlVersion = args.lift(2).getOrElse(constants.scalaXmlVersion)
val zincVersion = args.lift(3).getOrElse(constants.zincVersion)
val scalaDeps = Seq(
- MavenRepository.central.resolveOne(MavenDependency("org.scala-lang","scala-reflect",scalaVersion)),
- MavenRepository.central.resolveOne(MavenDependency("org.scala-lang","scala-compiler",scalaVersion))
+ mavenCentral.resolveOne(MavenDependency("org.scala-lang","scala-reflect",scalaVersion)),
+ mavenCentral.resolveOne(MavenDependency("org.scala-lang","scala-compiler",scalaVersion))
)
val scalaXml = Dependencies(
- MavenRepository.central.resolveOne(MavenDependency("org.scala-lang.modules","scala-xml_"+scalaMajorVersion,scalaXmlVersion)),
- MavenRepository.central.resolveOne(MavenDependency("org.scala-lang","scala-library",scalaVersion))
+ mavenCentral.resolveOne(MavenDependency("org.scala-lang.modules","scala-xml_"+scalaMajorVersion,scalaXmlVersion)),
+ mavenCentral.resolveOne(MavenDependency("org.scala-lang","scala-library",scalaVersion))
)
- val zinc = MavenRepository.central.resolveOne(MavenDependency("com.typesafe.zinc","zinc",zincVersion))
+ val zinc = mavenCentral.resolveOne(MavenDependency("com.typesafe.zinc","zinc",zincVersion))
def valName(dep: BoundMavenDependency) = {
val words = dep.artifactId.split("_").head.split("-")
@@ -66,24 +77,28 @@ class AdminTasks(lib: Lib, args: Seq[String], cwd: File, classLoaderCache: Class
}
def jarVal(dep: BoundMavenDependency) = "_" + valName(dep) +"Jar"
- def transitive(dep: Dependency) = (dep +: dep.transitiveDependencies.reverse).collect{case d: BoundMavenDependency => d}
+ 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) "" else ( ", " ++ valName(parents.last) )
+ val parentString = if(parents.isEmpty) "rootClassLoader" 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(", ")}
- );"""
+ download(new URL(mavenUrl + "${d.basePath}.jar"), Paths.get(${n}File), "${d.jarSha1}");
+
+ String[] ${n}ClasspathArray = new String[]{${deps.sortBy(_.jar).map(valName(_)+"File").mkString(", ")}};
+ String ${n}Classpath = classpath( ${n}ClasspathArray );
+ ClassLoader $n =
+ classLoaderCache.contains( ${n}Classpath )
+ ? classLoaderCache.get( ${n}Classpath )
+ : classLoaderCache.put( classLoader( ${n}File, $parentString ), ${n}Classpath );"""
}
}
val assignments = codeEach(zinc) ++ codeEach(scalaXml)
+ val files = scalaDeps ++ transitive(scalaXml) ++ transitive(zinc)
//{ 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;
@@ -97,23 +112,29 @@ import static cbt.NailgunLauncher.*;
class EarlyDependencies{
/** ClassLoader for stage1 */
- ClassLoader stage1;
+ ClassLoader classLoader;
+ String[] classpathArray;
/** ClassLoader for zinc */
ClassLoader zinc;
-${(scalaDeps ++ transitive(scalaXml) ++ transitive(zinc)).map(d => s""" String ${valName(d)}File = MAVEN_CACHE + "${d.basePath}.jar";""").mkString("\n")}
+${files.map(d => s""" String ${valName(d)}File;""").mkString("\n")}
+
+ public EarlyDependencies(
+ String mavenCache, String mavenUrl, ClassLoaderCache2<ClassLoader> classLoaderCache, ClassLoader rootClassLoader
+ ) throws Exception {
+${files.map(d => s""" ${valName(d)}File = mavenCache + "${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")}
+${scalaDeps.map(d => s""" download(new URL(mavenUrl + "${d.basePath}.jar"), Paths.get(${valName(d)}File), "${d.jarSha1}");""").mkString("\n")}
${assignments.mkString("\n")}
- stage1 = scalaXml_${scalaXmlVersion.replace(".","_")}_;
+ classLoader = scalaXml_${scalaXmlVersion.replace(".","_")}_;
+ classpathArray = scalaXml_${scalaXmlVersion.replace(".","_")}_ClasspathArray;
zinc = zinc_${zincVersion.replace(".","_")}_;
}
}
"""
- val file = paths.nailgun ++ ("/" ++ "EarlyDependencies.java")
+ val file = nailgun ++ ("/" ++ "EarlyDependencies.java")
Files.write( file.toPath, code.getBytes )
println( Console.GREEN ++ "Wrote " ++ file.string ++ Console.RESET )
}
diff --git a/stage2/BasicBuild.scala b/stage2/BasicBuild.scala
index 65db8a4..757e347 100644
--- a/stage2/BasicBuild.scala
+++ b/stage2/BasicBuild.scala
@@ -1,5 +1,4 @@
package cbt
-import cbt.paths._
import java.io._
import java.net._
@@ -22,21 +21,19 @@ trait Recommended extends BasicBuild{
"-language:existentials"
)
}
-class BasicBuild( context: Context ) extends Build( context )
-class Build(val context: Context) extends Dependency with TriggerLoop with SbtDependencyDsl{
+class BasicBuild(val context: Context) extends DependencyImplementation with BuildInterface with TriggerLoop with SbtDependencyDsl{
// library available to builds
- implicit final val logger: Logger = context.logger
- implicit final val classLoaderCache: ClassLoaderCache = context.classLoaderCache
- implicit final val _context = context
- override final protected val lib: Lib = new Lib(logger)
+ implicit protected final val logger: Logger = context.logger
+ implicit protected final val classLoaderCache: ClassLoaderCache = context.classLoaderCache
+ implicit protected final val _context = context
+ override protected final val lib: Lib = new Lib(logger)
// ========== general stuff ==========
- override def canBeCached = false
def enableConcurrency = false
final def projectDirectory: File = lib.realpath(context.projectDirectory)
assert( projectDirectory.exists, "projectDirectory does not exist: " ++ projectDirectory.string )
- final def usage: String = lib.usage(this.getClass, context)
+ final def usage: String = lib.usage(this.getClass, show)
// ========== meta data ==========
@@ -44,11 +41,15 @@ class Build(val context: Context) extends Dependency with TriggerLoop with SbtDe
final def scalaVersion = context.scalaVersion getOrElse defaultScalaVersion
final def scalaMajorVersion: String = lib.scalaMajorVersion(scalaVersion)
def crossScalaVersions: Seq[String] = Seq(scalaVersion, "2.10.6")
- def copy(context: Context) = lib.copy(this.getClass, context).asInstanceOf[Build]
+ final def crossScalaVersionsArray: Array[String] = crossScalaVersions.to
+
+ // TODO: this should probably provide a nice error message if class has constructor signature
+ def copy(context: Context): BuildInterface = lib.copy(this.getClass, context).asInstanceOf[BuildInterface]
def zincVersion = "0.3.9"
def dependencies: Seq[Dependency] = Seq(
- MavenRepository.central.resolve(
+ // FIXME: this should probably be removed
+ MavenResolver(context.cbtHasChanged, context.paths.mavenCache, MavenResolver.central).resolve(
"org.scala-lang" % "scala-library" % scalaVersion
)
)
@@ -108,13 +109,10 @@ class Build(val context: Context) extends Dependency with TriggerLoop with SbtDe
.flatMap(_.listFiles)
.filter(_.toString.endsWith(".jar"))
- //def cacheJar = false
override def dependencyClasspath : ClassPath = ClassPath(localJars) ++ super.dependencyClasspath
- override def dependencyJars : Seq[File] = localJars ++ super.dependencyJars
def exportedClasspath : ClassPath = ClassPath(compile.toSeq:_*)
def targetClasspath = ClassPath(Seq(compileTarget))
- def exportedJars: Seq[File] = Seq()
// ========== compile, run, test ==========
/** scalac options used for zinc and scaladoc */
@@ -124,15 +122,17 @@ class Build(val context: Context) extends Dependency with TriggerLoop with SbtDe
def needsUpdate: Boolean = needsUpdateCache(
context.cbtHasChanged
|| lib.needsUpdate( sourceFiles, compileStatusFile )
- || transitiveDependencies.exists(_.needsUpdate)
+ || transitiveDependencies.filterNot(_ == context.parentBuild).exists(_.needsUpdate)
)
private object compileCache extends Cache[Option[File]]
def compile: Option[File] = compileCache{
lib.compile(
- needsUpdate,
- sourceFiles, compileTarget, compileStatusFile, dependencyClasspath, scalacOptions,
- context.classLoaderCache, zincVersion = zincVersion, scalaVersion = scalaVersion
+ context.cbtHasChanged,
+ needsUpdate || context.parentBuild.map(_.needsUpdate).getOrElse(false),
+ sourceFiles, compileTarget, compileStatusFile, dependencyClasspath,
+ context.paths.mavenCache, scalacOptions, context.classLoaderCache,
+ zincVersion = zincVersion, scalaVersion = scalaVersion
)
}
@@ -155,6 +155,6 @@ class Build(val context: Context) extends Dependency with TriggerLoop with SbtDe
*/
// ========== cbt internals ==========
- private[cbt] def finalBuild = this
+ def finalBuild: BuildInterface = this
override def show = this.getClass.getSimpleName ++ "(" ++ projectDirectory.string ++ ")"
}
diff --git a/stage2/BuildBuild.scala b/stage2/BuildBuild.scala
index c52c3c6..bab8d88 100644
--- a/stage2/BuildBuild.scala
+++ b/stage2/BuildBuild.scala
@@ -1,25 +1,63 @@
package cbt
import java.io.File
+import java.nio.file._
import scala.collection.immutable.Seq
-class BuildBuild(context: Context) extends Build(context){
- override def dependencies = Seq( CbtDependency()(context.logger) ) ++ super.dependencies
+class BuildBuild(context: Context) extends BasicBuild(context){
+ override def dependencies =
+ super.dependencies :+ context.cbtDependency
def managedBuildDirectory: File = lib.realpath( projectDirectory.parent )
- val managedBuild = try{
- val managedContext = context.copy( projectDirectory = managedBuildDirectory )
- val cl = classLoader(context.classLoaderCache)
- logger.composition("Loading build at "+managedContext.projectDirectory)
- cl
- .loadClass(lib.buildClassName)
- .getConstructor(classOf[Context])
- .newInstance(managedContext)
- .asInstanceOf[Build]
- } catch {
- case e: ClassNotFoundException if e.getMessage == lib.buildClassName =>
- throw new Exception("You need to remove the directory or define a class Build in: "+context.projectDirectory)
- case e: Exception =>
- throw new Exception("during build: "+context.projectDirectory, e)
+ private object managedBuildCache extends Cache[BuildInterface]
+ def managedBuild = managedBuildCache{
+ try{
+ val managedContext = context.copy(
+ projectDirectory = managedBuildDirectory,
+ parentBuild=Some(this)
+ )
+ val managedBuildFile = projectDirectory++"/build.scala"
+ logger.composition("Loading build at "++managedContext.projectDirectory.toString)
+ (
+ if(managedBuildFile.exists){
+ val contents = new String(Files.readAllBytes(managedBuildFile.toPath))
+ val cbtUrl = ("cbt:"++GitDependency.GitUrl.regex++"#[a-z0-9A-Z]+").r
+ cbtUrl
+ .findFirstIn(contents)
+ .flatMap{
+ url =>
+ val Array(base,hash) = url.drop(4).split("#")
+ if(context.cbtHome.string.contains(hash))
+ None
+ else Some{
+ val checkoutDirectory = new GitDependency(base, hash).checkout
+ val build = new BasicBuild( context.copy( projectDirectory = checkoutDirectory ++ "/nailgun_launcher" ) )
+ val cl = build
+ .classLoader(classLoaderCache)
+ // Note: cbt can't use an old version of itself for building,
+ // otherwise we'd have to recursively build all versions since
+ // the beginning. Instead CBT always needs to build the pure Java
+ // Launcher in the checkout with itself and then run it via reflection.
+ cl
+ .loadClass( "cbt.NailgunLauncher" )
+ .getMethod( "getBuild", classOf[AnyRef] )
+ .invoke( null, managedContext.copy(cbtHome=checkoutDirectory) )
+ }
+ }.getOrElse{
+ classLoader(context.classLoaderCache)
+ .loadClass(lib.buildClassName)
+ .getConstructors.head
+ .newInstance(managedContext)
+ }
+ } else {
+ new BasicBuild(managedContext)
+ }
+ ).asInstanceOf[BuildInterface]
+ } catch {
+ case e: ClassNotFoundException if e.getMessage == lib.buildClassName =>
+ throw new Exception("You need to remove the directory or define a class Build in: "+context.projectDirectory)
+ case e: Exception =>
+ throw new Exception("during build: "+context.projectDirectory, e)
+ }
}
override def triggerLoopFiles = super.triggerLoopFiles ++ managedBuild.triggerLoopFiles
- override def finalBuild = if( context.projectDirectory == context.cwd ) this else managedBuild.finalBuild
+ override def finalBuild: BuildInterface = if( context.projectDirectory == context.cwd ) this else managedBuild.finalBuild
}
diff --git a/stage2/BuildDependency.scala b/stage2/BuildDependency.scala
index 8965cee..f6b6911 100644
--- a/stage2/BuildDependency.scala
+++ b/stage2/BuildDependency.scala
@@ -11,7 +11,8 @@ sealed abstract class ProjectProxy extends Ha{
def dependencies = Seq(delegate)
}
*/
-trait TriggerLoop extends Dependency{
+trait TriggerLoop extends DependencyImplementation{
+ final def triggerLoopFilesArray = triggerLoopFiles.toArray
def triggerLoopFiles: Seq[File]
}
/** You likely want to use the factory method in the BasicBuild class instead of this. */
@@ -21,9 +22,7 @@ case class BuildDependency(context: Context) extends TriggerLoop{
final override lazy val lib: Lib = new Lib(logger)
private val root = lib.loadRoot( context.copy(args=Seq()) )
lazy val build = root.finalBuild
- override def canBeCached = build.canBeCached
def exportedClasspath = ClassPath(Seq())
- def exportedJars = Seq()
def dependencies = Seq(build)
def triggerLoopFiles = root.triggerLoopFiles
override final val needsUpdate = build.needsUpdate
diff --git a/stage2/GitDependency.scala b/stage2/GitDependency.scala
index 333d81c..174f9ff 100644
--- a/stage2/GitDependency.scala
+++ b/stage2/GitDependency.scala
@@ -10,11 +10,10 @@ object GitDependency{
}
case class GitDependency(
url: String, ref: String // example: git://github.com/cvogt/cbt.git#<some-hash>
-)(implicit val logger: Logger, classLoaderCache: ClassLoaderCache, context: Context ) extends Dependency{
+)(implicit val logger: Logger, classLoaderCache: ClassLoaderCache, context: Context ) extends DependencyImplementation{
import GitDependency._
override def lib = new Lib(logger)
- override def canBeCached = dependency.canBeCached
// TODO: add support for authentication via ssh and/or https
// See http://www.codeaffine.com/2014/12/09/jgit-authentication/
private val GitUrl( _, domain, path ) = url
@@ -47,7 +46,6 @@ case class GitDependency(
def dependencies = Seq(dependency)
def exportedClasspath = ClassPath(Seq())
- def exportedJars = Seq()
private[cbt] def targetClasspath = exportedClasspath
def needsUpdate: Boolean = false
}
diff --git a/stage2/Lib.scala b/stage2/Lib.scala
index d7456e1..1b19a5e 100644
--- a/stage2/Lib.scala
+++ b/stage2/Lib.scala
@@ -1,5 +1,4 @@
package cbt
-import cbt.paths._
import java.io._
import java.net._
@@ -30,7 +29,7 @@ final class Lib(logger: Logger) extends Stage1Lib(logger) with Scaffold{
.newInstance(context)
/** Loads Build for given Context */
- def loadDynamic(context: Context, default: Context => Build = new Build(_)): Build = {
+ def loadDynamic(context: Context, default: Context => BuildInterface = new BasicBuild(_)): BuildInterface = {
context.logger.composition( context.logger.showInvocation("Build.loadDynamic",context) )
loadRoot(context, default).finalBuild
}
@@ -38,7 +37,7 @@ final class Lib(logger: Logger) extends Stage1Lib(logger) with Scaffold{
Loads whatever Build needs to be executed first in order to eventually build the build for the given context.
This can either the Build itself, of if exists a BuildBuild or a BuildBuild for a BuildBuild and so on.
*/
- def loadRoot(context: Context, default: Context => Build = new Build(_)): Build = {
+ def loadRoot(context: Context, default: Context => BuildInterface = new BasicBuild(_)): BuildInterface = {
context.logger.composition( context.logger.showInvocation("Build.loadRoot",context.projectDirectory) )
def findStartDir(projectDirectory: File): File = {
val buildDir = realpath( projectDirectory ++ "/build" )
@@ -73,6 +72,7 @@ final class Lib(logger: Logger) extends Stage1Lib(logger) with Scaffold{
}
def docJar(
+ cbtHasChanged: Boolean,
scalaVersion: String,
sourceFiles: Seq[File],
dependencyClasspath: ClassPath,
@@ -82,7 +82,8 @@ final class Lib(logger: Logger) extends Stage1Lib(logger) with Scaffold{
scalaMajorVersion: String,
version: String,
compileArgs: Seq[String],
- classLoaderCache: ClassLoaderCache
+ classLoaderCache: ClassLoaderCache,
+ mavenCache: File
): Option[File] = {
if(sourceFiles.isEmpty){
None
@@ -98,7 +99,7 @@ final class Lib(logger: Logger) extends Stage1Lib(logger) with Scaffold{
runMain(
"scala.tools.nsc.ScalaDoc",
args,
- ScalaDependencies(scalaVersion)(logger).classLoader(classLoaderCache)
+ ScalaDependencies(cbtHasChanged,mavenCache,scalaVersion)(logger).classLoader(classLoaderCache)
)
}
lib.jarFile(
@@ -116,10 +117,13 @@ final class Lib(logger: Logger) extends Stage1Lib(logger) with Scaffold{
val loggerArg = if(loggers != "") Some("-Dlog="++loggers) else None
logger.lib(s"invoke testDefault( $context )")
- val exitCode: ExitCode = loadDynamic(
- context.copy( projectDirectory = context.projectDirectory ++ "/test", args = loggerArg.toVector ++ context.args ),
- new BasicBuild(_) with mixins.Test
- ).run.asInstanceOf[ExitCode] // FIXME
+ val exitCode: ExitCode =
+ new ReflectBuild(
+ loadDynamic(
+ context.copy( projectDirectory = context.projectDirectory ++ "/test", args = loggerArg.toVector ++ context.args ),
+ new BasicBuild(_) with mixins.Test
+ )
+ ).callNullary( Some("run") )
logger.lib(s"return testDefault( $context )")
Some(exitCode)
} else None
@@ -147,13 +151,18 @@ final class Lib(logger: Logger) extends Stage1Lib(logger) with Scaffold{
def taskNames(cls: Class[_]): Seq[String] = tasks(cls).keys.toVector.sorted
- def usage(buildClass: Class[_], context: Context): String = {
- val baseTasks = lib.taskNames(classOf[Build])
+ def usage(buildClass: Class[_], show: String): String = {
+ val baseTasks = Seq(
+ classOf[BasicBuild],
+ classOf[PackageBuild],
+ classOf[PublishBuild],
+ classOf[Recommended]
+ ).flatMap(lib.taskNames).distinct.sorted
val thisTasks = lib.taskNames(buildClass) diff baseTasks
(
(
if( thisTasks.nonEmpty ){
- s"""Methods provided by Build ${context.projectDirectory}
+ s"""Methods provided by Build ${show}
${thisTasks.mkString(" ")}
@@ -165,12 +174,13 @@ final class Lib(logger: Logger) extends Stage1Lib(logger) with Scaffold{
) ++ "\n"
}
- class ReflectBuild[T:scala.reflect.ClassTag](build: Build) extends ReflectObject(build){
- def usage = lib.usage(build.getClass, build.context)
+ class ReflectBuild[T:scala.reflect.ClassTag](build: BuildInterface) extends ReflectObject(build){
+ def usage = lib.usage(build.getClass, build.show)
}
- abstract class ReflectObject[T:scala.reflect.ClassTag](obj: T){
+ abstract class ReflectObject[T](obj: T){
def usage: String
- def callNullary( taskName: Option[String] ): Unit = {
+ def callNullary( taskName: Option[String] ): ExitCode = {
+ logger.lib("Calling task " ++ taskName.toString)
val ts = tasks(obj.getClass)
taskName.map( NameTransformer.encode ).flatMap(ts.get).map{ method =>
val result: Option[Any] = Option(method.invoke(obj)) // null in case of Unit
@@ -183,26 +193,30 @@ final class Lib(logger: Logger) extends Stage1Lib(logger) with Scaffold{
scala.util.Try( value.getClass.getDeclaredMethod("toConsole") ) match {
case scala.util.Success(toConsole) =>
println(toConsole.invoke(value))
+ ExitCode.Success
case scala.util.Failure(e) if Option(e.getMessage).getOrElse("") contains "toConsole" =>
value match {
- case ExitCode(code) => System.exit(code)
- case other => println( other.toString ) // no method .toConsole, using to String
+ case code:ExitCode =>
+ code
+ case other =>
+ println( other.toString ) // no method .toConsole, using to String
+ ExitCode.Success
}
case scala.util.Failure(e) =>
throw e
}
- }.getOrElse("")
+ }.getOrElse(ExitCode.Success)
}.getOrElse{
taskName.foreach{ n =>
System.err.println(s"Method not found: $n")
System.err.println("")
}
System.err.println(usage)
- taskName.foreach{ _ =>
+ taskName.map{ _ =>
ExitCode.Failure
- }
+ }.getOrElse( ExitCode.Success )
}
}
}
diff --git a/stage2/PackageBuild.scala b/stage2/PackageBuild.scala
index d24bf38..869af0e 100644
--- a/stage2/PackageBuild.scala
+++ b/stage2/PackageBuild.scala
@@ -20,9 +20,11 @@ abstract class PackageBuild(context: Context) extends BasicBuild(context) with A
private object cacheDocBasicBuild extends Cache[Option[File]]
def docJar: Option[File] = cacheDocBasicBuild{
- lib.docJar( scalaVersion, sourceFiles, dependencyClasspath, apiTarget, jarTarget, artifactId, scalaMajorVersion, version, scalacOptions, context.classLoaderCache )
+ lib.docJar(
+ context.cbtHasChanged,
+ scalaVersion, sourceFiles, dependencyClasspath, apiTarget,
+ jarTarget, artifactId, scalaMajorVersion, version,
+ scalacOptions, context.classLoaderCache, context.paths.mavenCache
+ )
}
-
- override def jars = jar.toVector ++ dependencyJars
- override def exportedJars: Seq[File] = jar.toVector
}
diff --git a/stage2/SbtDependencyDsl.scala b/stage2/SbtDependencyDsl.scala
index 1ecf72c..d8c0786 100644
--- a/stage2/SbtDependencyDsl.scala
+++ b/stage2/SbtDependencyDsl.scala
@@ -1,5 +1,5 @@
package cbt
-trait SbtDependencyDsl{ self: Build =>
+trait SbtDependencyDsl{ self: BasicBuild =>
/** SBT-like dependency builder DSL for syntax compatibility */
class DependencyBuilder2( groupId: String, artifactId: String, scalaVersion: Option[String] ){
def %(version: String) = scalaVersion.map(
diff --git a/stage2/Stage2.scala b/stage2/Stage2.scala
index fa41d79..5316e78 100644
--- a/stage2/Stage2.scala
+++ b/stage2/Stage2.scala
@@ -4,12 +4,23 @@ import java.io._
import scala.collection.immutable.Seq
-import cbt.paths._
object Stage2 extends Stage2Base{
+ def getBuild(__context: java.lang.Object, _cbtChanged: java.lang.Boolean) = {
+ val cl1 = __context.getClass.getClassLoader
+ val cl2 = classOf[Context].getClassLoader
+ val _context = __context.asInstanceOf[Context]
+ val context = _context.copy(
+ cbtHasChanged = _context.cbtHasChanged || _cbtChanged
+ )
+ val first = new Lib(context.logger).loadRoot( context )
+ first.finalBuild
+ }
+
def run( args: Stage2Args ): Unit = {
import args.logger
-
+ val paths = Paths(args.cbtHome,args.cache)
+ import paths._
val lib = new Lib(args.logger)
logger.stage2(s"Stage2 start")
@@ -24,11 +35,26 @@ object Stage2 extends Stage2Base{
}
val task = args.args.lift( taskIndex )
- val context = Context( args.cwd, args.cwd, args.args.drop( taskIndex ), logger, args.cbtHasChanged, args.classLoaderCache )
+ val context: Context = ContextImplementation(
+ args.cwd,
+ args.cwd,
+ args.args.drop( taskIndex ).toArray,
+ logger.enabledLoggers.toArray,
+ logger.start,
+ args.cbtHasChanged,
+ null,
+ null,
+ args.permanentKeys,
+ args.permanentClassLoaders,
+ args.cache,
+ args.cbtHome,
+ compatibilityTarget,
+ null
+ )
val first = lib.loadRoot( context )
val build = first.finalBuild
- def call(build: Build) = {
+ def call(build: BuildInterface) = {
if(cross){
build.crossScalaVersions.foreach{
v => new lib.ReflectBuild(
@@ -57,7 +83,7 @@ object Stage2 extends Stage2Base{
case file if triggerFiles.exists(file.toString startsWith _.toString) =>
val build = lib.loadDynamic(context)
- logger.loop(s"Re-running $task for " ++ build.projectDirectory.toString)
+ logger.loop(s"Re-running $task for " ++ build.show)
call(build)
}
} else {
diff --git a/stage2/mixins.scala b/stage2/mixins.scala
index fcffd97..1383324 100644
--- a/stage2/mixins.scala
+++ b/stage2/mixins.scala
@@ -2,31 +2,11 @@ package cbt
package mixins
import scala.collection.immutable.Seq
import java.io._
-trait Test extends Build{
+trait Test extends BasicBuild{
lazy val testedBuild = BuildDependency( projectDirectory.parent )
override def dependencies = Seq( testedBuild ) ++ super.dependencies
override def defaultScalaVersion = testedBuild.build.scalaVersion
}
-trait Sbt extends Build{
- override def sources = Seq( projectDirectory ++ "/src/main/scala" )
-}
trait SbtTest extends Test{
override def sources = Vector( projectDirectory.parent ++ "/src/test/scala" )
}
-trait ScalaTest extends Build with Test{
- def scalaTestVersion: String
-
- override def dependencies = super.dependencies :+ MavenRepository.central.resolve(
- "org.scalatest" %% "scalatest" % scalaTestVersion
- )
-
- override def run: ExitCode = {
- val discoveryPath = compile.toString++"/"
- context.logger.lib("discoveryPath: " ++ discoveryPath)
- lib.runMain(
- "org.scalatest.tools.Runner",
- Seq("-R", discoveryPath, "-oF") ++ context.args.drop(1),
- classLoader(context.classLoaderCache)
- )
- }
-}