diff options
Diffstat (limited to 'stage2')
-rw-r--r-- | stage2/AdminStage2.scala | 2 | ||||
-rw-r--r-- | stage2/AdminTasks.scala | 69 | ||||
-rw-r--r-- | stage2/BasicBuild.scala | 38 | ||||
-rw-r--r-- | stage2/BuildBuild.scala | 72 | ||||
-rw-r--r-- | stage2/BuildDependency.scala | 5 | ||||
-rw-r--r-- | stage2/GitDependency.scala | 4 | ||||
-rw-r--r-- | stage2/Lib.scala | 56 | ||||
-rw-r--r-- | stage2/PackageBuild.scala | 10 | ||||
-rw-r--r-- | stage2/SbtDependencyDsl.scala | 2 | ||||
-rw-r--r-- | stage2/Stage2.scala | 36 | ||||
-rw-r--r-- | stage2/mixins.scala | 22 |
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) - ) - } -} |