From 8a4578311e4d11c06bfb4fe04e5bf414b94d24e8 Mon Sep 17 00:00:00 2001 From: Christopher Vogt Date: Wed, 30 Mar 2016 21:21:05 -0400 Subject: Typed passing of values from Stage1 to Stage2 (thing can still be cleaned up) --- nailgun_launcher/NailgunLauncher.java | 10 +++-- stage1/Stage1.scala | 77 +++++++++++++++++++++++------------ stage2/AdminStage2.scala | 11 +++-- stage2/AdminTasks.scala | 2 +- stage2/Stage2.scala | 26 ++++++------ test/test.scala | 12 +++--- 6 files changed, 81 insertions(+), 57 deletions(-) diff --git a/nailgun_launcher/NailgunLauncher.java b/nailgun_launcher/NailgunLauncher.java index c213518..3290bdb 100644 --- a/nailgun_launcher/NailgunLauncher.java +++ b/nailgun_launcher/NailgunLauncher.java @@ -97,10 +97,12 @@ public class NailgunLauncher{ } try{ - stage1classLoader - .loadClass("cbt.Stage1") - .getMethod("main", String[].class, ClassLoader.class) - .invoke( null, (Object) args, stage1classLoader); + Integer exitCode = + (Integer) stage1classLoader + .loadClass("cbt.Stage1") + .getMethod("run", String[].class, ClassLoader.class, Boolean.class) + .invoke( null, (Object) args, stage1classLoader, stage1SourcesChanged); + System.exit(exitCode); }catch(Exception e){ System.err.println(stage1classLoader); throw e; diff --git a/stage1/Stage1.scala b/stage1/Stage1.scala index 36921be..32da3ed 100644 --- a/stage1/Stage1.scala +++ b/stage1/Stage1.scala @@ -8,66 +8,75 @@ import scala.collection.JavaConverters._ import paths._ -class Init(args: Array[String]) { +final case class Stage1ArgsParser(_args: Seq[String]) { /** * Raw parameters including their `-D` flag. **/ - val propsRaw: Seq[String] = args.toVector.filter(_.startsWith("-D")) + val propsRaw: Seq[String] = _args.toVector.filter(_.startsWith("-D")) /** * All arguments that weren't `-D` property declarations. **/ - val argsV: Seq[String] = args.toVector diff propsRaw + val args: Seq[String] = _args.toVector diff propsRaw /** * Parsed properties, as a map of keys to values. **/ - lazy val props = propsRaw + val props = propsRaw .map(_.drop(2).split("=")).map({ case Array(key, value) => key -> value }).toMap ++ System.getProperties.asScala - val logger = new Logger(props.get("log")) + val enabledLoggers = props.get("log") + + val admin = _args contains "admin" } -object Stage1{ +abstract class Stage2Base{ + def run( context: Stage2Args ): Unit +} + +case class Stage2Args( + cwd: File, + args: Seq[String], + cbtHasChanged: Boolean, + logger: Logger +) + +object Stage1{ protected def newerThan( a: File, b: File ) ={ a.lastModified > b.lastModified } - def main(args: Array[String], classLoader: ClassLoader): Unit = { - val mainClass = if(args contains "admin") "cbt.AdminStage2" else "cbt.Stage2" - val init = new Init(args) - val lib = new Stage1Lib(init.logger) - import lib._ - - logger.stage1(s"[$now] Stage1 start") - logger.stage1("Stage1: after creating lib") + def run(_args: Array[String], classLoader: ClassLoader, stage1SourcesChanged: java.lang.Boolean): Int = { + val args = Stage1ArgsParser(_args.toVector) + val logger = new Logger(args.enabledLoggers) + logger.stage1(s"Stage1 start") - val cwd = args(0) + val lib = new Stage1Lib(logger) + import lib._ - val src = stage2.listFiles.toVector.filter(_.isFile).filter(_.toString.endsWith(".scala")) + val sourceFiles = stage2.listFiles.toVector.filter(_.isFile).filter(_.toString.endsWith(".scala")) val changeIndicator = stage2Target ++ "/cbt/Build.class" - - val classLoaderCache = new ClassLoaderCache(logger) val deps = Dependencies( JavaDependency("net.incongru.watchservice","barbary-watchservice","1.0"), JavaDependency("org.eclipse.jgit", "org.eclipse.jgit", "4.2.0.201601211800-r") ) - val scalaXml = JavaDependency("org.scala-lang.modules","scala-xml_"+constants.scalaMajorVersion,constants.scalaXmlVersion) + val classLoaderCache = new ClassLoaderCache(logger) + val stage2SourcesChanged = sourceFiles.exists(newerThan(_, changeIndicator)) logger.stage1("before conditionally running zinc to recompile CBT") - if( src.exists(newerThan(_, changeIndicator)) ) { + if( stage2SourcesChanged ) { + val scalaXml = JavaDependency("org.scala-lang.modules","scala-xml_"+constants.scalaMajorVersion,constants.scalaXmlVersion) logger.stage1("cbt.lib has changed. Recompiling.") - zinc( true, src, stage2Target, nailgunTarget +: stage1Target +: Dependencies(deps, scalaXml).classpath, classLoaderCache, Seq("-deprecation") )( zincVersion = "0.3.9", scalaVersion = constants.scalaVersion ) + zinc( true, sourceFiles, stage2Target, nailgunTarget +: stage1Target +: Dependencies(deps, scalaXml).classpath, classLoaderCache, Seq("-deprecation") )( zincVersion = "0.3.9", scalaVersion = constants.scalaVersion ) } logger.stage1(s"[$now] calling CbtDependency.classLoader") - val cp = stage2Target val cl = classLoaderCache.transient.get( (stage2Target +: deps.classpath).string, cbt.URLClassLoader( @@ -80,10 +89,26 @@ object Stage1{ ) logger.stage1(s"[$now] Run Stage2") - val ExitCode(exitCode) = /*trapExitCode*/{ // this - runMain( mainClass, cwd +: args.drop(1).toVector, cl ) - } + val exitCode = ( + cl.loadClass( + if(args.admin) "cbt.AdminStage2" else "cbt.Stage2" + ) + .getMethod( "run", classOf[Stage2Args] ) + .invoke( + null, + Stage2Args( + new File( args.args(0) ), + args.args.drop(1).toVector, + // launcher changes cause entire nailgun restart, so no need for them here + cbtHasChanged = stage1SourcesChanged || stage2SourcesChanged, + logger + ) + ) match { + case code: ExitCode => code + case _ => ExitCode.Success + } + ).integer logger.stage1(s"[$now] Stage1 end") - System.exit(exitCode) + return exitCode; } } diff --git a/stage2/AdminStage2.scala b/stage2/AdminStage2.scala index cd35cfe..883b5ed 100644 --- a/stage2/AdminStage2.scala +++ b/stage2/AdminStage2.scala @@ -1,11 +1,10 @@ package cbt import java.io._ -object AdminStage2{ - def main(_args: Array[String]) = { - val args = _args.drop(1).dropWhile(Seq("admin","direct") contains _) - val init = new Init(args) - val lib = new Lib(init.logger) - val adminTasks = new AdminTasks(lib, args, new File(_args(0))) +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) 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 eb1cd1e..069b712 100644 --- a/stage2/AdminTasks.scala +++ b/stage2/AdminTasks.scala @@ -2,7 +2,7 @@ package cbt import scala.collection.immutable.Seq import java.io.{Console=>_,_} import java.nio.file._ -class AdminTasks(lib: Lib, args: Array[String], cwd: File){ +class AdminTasks(lib: Lib, args: Seq[String], cwd: File){ implicit val logger: Logger = lib.logger def resolve = { ClassPath.flatten( diff --git a/stage2/Stage2.scala b/stage2/Stage2.scala index 75be3c7..e893a06 100644 --- a/stage2/Stage2.scala +++ b/stage2/Stage2.scala @@ -8,26 +8,24 @@ import scala.collection.immutable.Seq import cbt.paths._ +object Stage2 extends Stage2Base{ + def run( args: Stage2Args ): Unit = { + import args.logger -object Stage2{ - def main(args: Array[String]): Unit = { - val init = new Init(args) - import init._ + val lib = new Lib(args.logger) - val lib = new Lib(init.logger) - - init.logger.stage2(s"[$now] Stage2 start") - val loop = argsV.lift(1) == Some("loop") - val direct = argsV.lift(1) == Some("direct") + logger.stage2(s"[$now] Stage2 start") + val loop = args.args.lift(0) == Some("loop") + val direct = args.args.lift(0) == Some("direct") val taskIndex = if (loop || direct) { - 2 - } else { 1 + } else { + 0 } - val task = argsV.lift( taskIndex ) + val task = args.args.lift( taskIndex ) - val context = Context( new File(argsV(0)), argsV.drop( taskIndex + 1 ), logger, new ClassLoaderCache(logger) ) + val context = Context( args.cwd, args.args.drop( taskIndex ), logger, /*args.cbtHasChanged,*/ new ClassLoaderCache(logger) ) val first = lib.loadRoot( context ) val build = first.finalBuild @@ -56,6 +54,6 @@ object Stage2{ new lib.ReflectBuild(build).callNullary(task) } - init.logger.stage2(s"[$now] Stage2 end") + logger.stage2(s"[$now] Stage2 end") } } diff --git a/test/test.scala b/test/test.scala index e623d34..7261287 100644 --- a/test/test.scala +++ b/test/test.scala @@ -4,9 +4,9 @@ import scala.collection.immutable.Seq // micro framework object Main{ - def main(args: Array[String]): Unit = { - val init = new Init(args) - implicit val logger: Logger = init.logger + def main(_args: Array[String]): Unit = { + val args = new Stage1ArgsParser(_args.toVector) + implicit val logger: Logger = new Logger(args.enabledLoggers) var successes = 0 var failures = 0 @@ -24,9 +24,9 @@ object Main{ }.get } - def runCbt(path: String, args: Seq[String])(implicit logger: Logger): Result = { + def runCbt(path: String, _args: Seq[String])(implicit logger: Logger): Result = { import java.io._ - val allArgs: Seq[String] = ((cbtHome.string ++ "/cbt") +: "direct" +: (args ++ init.propsRaw)) + val allArgs: Seq[String] = ((cbtHome.string ++ "/cbt") +: "direct" +: (_args ++ args.propsRaw)) logger.test(allArgs.toString) val pb = new ProcessBuilder( allArgs :_* ) pb.directory(cbtHome ++ ("/test/" ++ path)) @@ -61,7 +61,7 @@ object Main{ // assert(res.err == "", res.err) // FIXME: enable this } - logger.test( "Running tests " ++ args.toList.toString ) + logger.test( "Running tests " ++ _args.toList.toString ) usage("nothing") compile("nothing") -- cgit v1.2.3