Skip to content

Commit

Permalink
Accept build.scala and Build.scala
Browse files Browse the repository at this point in the history
  • Loading branch information
tim-zh committed Oct 10, 2016
1 parent f691119 commit 174ceef
Showing 1 changed file with 52 additions and 43 deletions.
95 changes: 52 additions & 43 deletions stage2/BuildBuild.scala
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
package cbt
import java.io.File
import java.nio.file._

trait BuildBuild extends BaseBuild{
Expand All @@ -20,62 +21,70 @@ trait BuildBuild extends BaseBuild{

override def dependencies =
super.dependencies :+ context.cbtDependency
def managedBuildDirectory: java.io.File = lib.realpath( projectDirectory.parent )
def managedBuildDirectory: File = lib.realpath( projectDirectory.parent )
private object managedBuildCache extends Cache[BuildInterface]
def managedBuild = managedBuildCache{
val managedBuildFile = projectDirectory++"/Build.scala"
logger.composition("Loading build at "++managedContext.projectDirectory.toString)
val build = (
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{
// 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.
val dep = new GitDependency(base, hash, Some("nailgun_launcher"))
val ctx = managedContext.copy( cbtHome = dep.checkout )
dep.classLoader(classLoaderCache)
.loadClass( "cbt.NailgunLauncher" )
.getMethod( "getBuild", classOf[AnyRef] )
.invoke( null, ctx )
}
}.getOrElse{
try{
classLoader(context.classLoaderCache)
.loadClass(lib.buildClassName)
.getConstructors.head
.newInstance(managedContext)
} catch {
case e: ClassNotFoundException if e.getMessage == lib.buildClassName =>
throw new Exception("You need to define a class Build in Build.scala in: "+context.projectDirectory)
}
}
} else if( projectDirectory.listFiles.exists( _.getName.endsWith(".scala") ) ){
throw new Exception(
"No file Build.scala (upper case) found in " ++ projectDirectory.getPath
)
} else if( projectDirectory.getParentFile.getName == "build" ){
new BasicBuild( managedContext ) with BuildBuild
val build = if (managedBuildFile.exists) {
managedBuildFrom(managedBuildFile)
} else if (projectDirectory.listFiles.exists(_.getName.endsWith(".scala"))) {
System.err.println("No file Build.scala (upper case) found in " ++ projectDirectory.getPath)
val backupBuildFile = projectDirectory ++ "/build.scala"
if (backupBuildFile.exists) {
System.err.println("Trying build.scala in " ++ projectDirectory.getPath)
managedBuildFrom(backupBuildFile)
} else {
new BasicBuild( managedContext )
throw new Exception("No file Build.scala (upper case) found in " ++ projectDirectory.getPath)
}
)
} else if (projectDirectory.getParentFile.getName == "build") {
new BasicBuild(managedContext) with BuildBuild
} else {
new BasicBuild(managedContext)
}
try{
build.asInstanceOf[BuildInterface]
} catch {
case e: ClassCastException if e.getMessage.contains("Build cannot be cast to cbt.BuildInterface") =>
throw new Exception("Your Build class needs to extend BaseBuild in: "+context.projectDirectory, e)
}
}

private def managedBuildFrom(file: File): BuildInterface = {
val contents = new String(Files.readAllBytes(file.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 {
// 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.
val dep = new GitDependency(base, hash, Some("nailgun_launcher"))
val ctx = managedContext.copy(cbtHome = dep.checkout)
dep.classLoader(classLoaderCache)
.loadClass("cbt.NailgunLauncher")
.getMethod("getBuild", classOf[AnyRef])
.invoke(null, ctx)
.asInstanceOf[BuildInterface]
}
} getOrElse {
try
classLoader(context.classLoaderCache)
.loadClass(lib.buildClassName)
.getConstructors.head
.newInstance(managedContext)
catch {
case e: ClassNotFoundException if e.getMessage == lib.buildClassName =>
throw new Exception("You need to define a class Build in Build.scala in: " + context.projectDirectory)
}
}.asInstanceOf[BuildInterface]
}

override def triggerLoopFiles = super.triggerLoopFiles ++ managedBuild.triggerLoopFiles
override def finalBuild: BuildInterface = if( context.projectDirectory == context.cwd ) this else managedBuild.finalBuild
}

0 comments on commit 174ceef

Please sign in to comment.