diff options
Diffstat (limited to 'stage2')
-rw-r--r-- | stage2/BasicBuild.scala | 33 | ||||
-rw-r--r-- | stage2/BuildDependency.scala | 1 | ||||
-rw-r--r-- | stage2/Lib.scala | 56 | ||||
-rw-r--r-- | stage2/ToolsTasks.scala | 2 |
4 files changed, 55 insertions, 37 deletions
diff --git a/stage2/BasicBuild.scala b/stage2/BasicBuild.scala index 8d72f9a..3c3cbec 100644 --- a/stage2/BasicBuild.scala +++ b/stage2/BasicBuild.scala @@ -32,7 +32,7 @@ trait BaseBuild extends BuildInterface with DependencyImplementation with Trigge s"You need to extend ${lib.buildBuildClassName} in: " + projectDirectory + "/" ++ lib.buildDirectoryName ) - final def usage: String = lib.usage(this.getClass, show) + final def help: String = lib.usage(this.getClass, show) final def taskNames: String = lib.taskNames(this.getClass).sorted.mkString("\n") @@ -41,7 +41,7 @@ trait BaseBuild extends BuildInterface with DependencyImplementation with Trigge def defaultScalaVersion: String = constants.scalaVersion final def scalaVersion = context.scalaVersion getOrElse defaultScalaVersion final def scalaMajorVersion: String = lib.libMajorVersion(scalaVersion) - def projectName = "default" + def name = projectDirectory.getName // TODO: get rid of this in favor of newBuild. // currently blocked on DynamicOverride being not parts @@ -85,7 +85,7 @@ trait BaseBuild extends BuildInterface with DependencyImplementation with Trigge def sources: Seq[File] = Seq(defaultSourceDirectory) ++ projectDirectory.listFiles.toVector.filter(sourceFileFilter) /** Which file endings to consider being source files. */ - def sourceFileFilter(file: File): Boolean = file.toString.endsWith(".scala") || file.toString.endsWith(".java") + def sourceFileFilter(file: File) = lib.sourceFileFilter(file) /** Absolute path names for all individual files found in sources directly or contained in directories. */ final def sourceFiles: Seq[File] = lib.sourceFiles(sources, sourceFileFilter) @@ -187,16 +187,22 @@ trait BaseBuild extends BuildInterface with DependencyImplementation with Trigge } def run: ExitCode = run( context.args: _* ) - - def test: Any = - lib.callReflective( - DirectoryDependency(projectDirectory++"/test").dependency, - Some("run"), - context - ) - - def t = test - def rt = recursiveUnsafe(Some("test")) + def test: Dependency = { + val testDirectory = projectDirectory / "test" + if( (testDirectory / lib.buildDirectoryName / lib.buildFileName).exists ){ + // FIYME: maybe we can make loadRoot(...).finalBuild an Option some + DirectoryDependency( testDirectory ).dependency + } else { + new BasicBuild( context.copy(workingDirectory = testDirectory) ){ + override def dependencies = Seq( + DirectoryDependency(projectDirectory++"/..") + ) + def apply = run + } + } + } + def t: Any = lib.callReflective( test, Some("run"), context ) + def rt = recursiveUnsafe(Some("test.run")) def recursiveSafe(_run: BuildInterface => Any): ExitCode = { val builds = (this +: transitiveDependencies).collect{ @@ -265,6 +271,7 @@ trait BaseBuild extends BuildInterface with DependencyImplementation with Trigge } override def show = this.getClass.getSimpleName ++ "(" ++ projectDirectory.string ++ ")" + override def toString = show // a method that can be called only to trigger any side-effects final def `void` = () diff --git a/stage2/BuildDependency.scala b/stage2/BuildDependency.scala index 0162791..9a2918a 100644 --- a/stage2/BuildDependency.scala +++ b/stage2/BuildDependency.scala @@ -25,6 +25,7 @@ final case class DirectoryDependency(context: Context, pathToNestedBuild: String def transientCache = context.transientCache private lazy val root = lib.loadRoot( context ) lazy val dependency: Dependency = { + // TODO: move this into finalBuild probably def selectNestedBuild( build: Dependency, names: Seq[String], previous: Seq[String] ): Dependency = { names.headOption.map{ name => if( lib.taskNames(build.getClass).contains(name) ){ diff --git a/stage2/Lib.scala b/stage2/Lib.scala index b6187ce..33bfe1a 100644 --- a/stage2/Lib.scala +++ b/stage2/Lib.scala @@ -140,22 +140,19 @@ final class Lib(val logger: Logger) extends Stage1Lib(logger){ ).flatMap(lib.taskNames).distinct.sorted val thisTasks = lib.taskNames(buildClass) diff baseTasks ( - ( + s"Methods provided by $show\n\n" + ++ ( if( thisTasks.nonEmpty ){ - s"""Methods provided by ${show} - - ${thisTasks.mkString(" ")} - -""" - } else "" - ) ++ s"""Methods provided by CBT (but possibly overwritten) - - ${baseTasks.mkString(" ")}""" - ) ++ "\n" + thisTasks.mkString(" ") ++ "\n\n" + } else "<none>" + ) + ++ s"\n\nMethods provided by CBT (but possibly overwritten)\n\n" + ++ baseTasks.mkString(" ") + "\n" + ) } def callReflective[T <: AnyRef]( obj: T, code: Option[String], context: Context ): ExitCode = { - callInternal( obj, code.toSeq.flatMap(_.split("\\.").map( NameTransformer.encode )), Nil, context ) match { + callInternal( obj, code.toSeq.flatMap(_.split("\\.").map( NameTransformer.encode )), Nil, context ).map { case (obj, code, None) => val s = render(obj) if(s.nonEmpty) @@ -168,7 +165,7 @@ final class Lib(val logger: Logger) extends Stage1Lib(logger){ if(s.nonEmpty) System.err.println(s) code getOrElse ExitCode.Failure - } + }.reduceOption(_ && _).getOrElse( ExitCode.Failure ) } private def render[T]( obj: T ): String = { @@ -177,12 +174,12 @@ final class Lib(val logger: Logger) extends Stage1Lib(logger){ case None => "" case d: Dependency => lib.usage(d.getClass, d.show()) case c: ClassPath => c.string - case t:ToolsStage2.type => "Available methods: " ++ lib.taskNames(t.getClass).mkString(" ") + case ExitCode(int) => System.err.println(int); System.exit(int); ??? case _ => obj.toString } } - private def callInternal[T <: AnyRef]( obj: T, members: Seq[String], previous: Seq[String], context: Context ): (Option[Object], Option[ExitCode], Option[String]) = { + private def callInternal[T <: AnyRef]( obj: T, members: Seq[String], previous: Seq[String], context: Context ): Seq[(Option[Object], Option[ExitCode], Option[String])] = { members.headOption.map{ taskName => logger.lib("Calling task " ++ taskName.toString) taskMethods(obj.getClass).get(taskName).map{ method => @@ -190,12 +187,12 @@ final class Lib(val logger: Logger) extends Stage1Lib(logger){ result match { case code if code.getClass.getSimpleName == "ExitCode" => // FIXME: ExitCode needs to be part of the compatibility interfaces - (None, Some(ExitCode(Stage0Lib.get(code,"integer").asInstanceOf[Int])), None) - case Seq(bs @ _*) if bs.forall(_.isInstanceOf[BaseBuild]) => - bs.map( b => callInternal(b.asInstanceOf[BaseBuild], members.tail, previous :+ taskName, context) ).head + Seq((None, Some(ExitCode(Stage0Lib.get(code,"integer").asInstanceOf[Int])), None)) + case bs: Seq[_] if bs.size > 0 && bs.forall(_.isInstanceOf[BaseBuild]) => + bs.flatMap( b => callInternal(b.asInstanceOf[BaseBuild], members.tail, previous :+ taskName, context) ) case _ => callInternal(result, members.tail, previous :+ taskName, context) } - }.getOrElse( (None, None, None) ) + }.getOrElse( Seq( (None, None, None) ) ) }.getOrElse{ val folder = NameTransformer.decode(taskName) if( context != null && (context.workingDirectory / folder).exists ){ @@ -209,11 +206,19 @@ final class Lib(val logger: Logger) extends Stage1Lib(logger){ newContext ) } else { - ( Some(obj), None, Some("\nMethod not found: " ++ (previous :+ taskName).mkString(".") ++ "\n") ) + Seq( ( Some(obj), None, Some("\nMethod not found: " ++ (previous :+ taskName).mkString(".") ++ "\n") ) ) } } }.getOrElse{ - ( Some(obj), None, None ) + Seq(( + Some( + obj.getClass.getMethods.find(m => m.getName == "apply" && m.getParameterCount == 0).map( + _.invoke(obj) + ).getOrElse( obj ) + ), + None, + None + )) } } @@ -280,10 +285,13 @@ final class Lib(val logger: Logger) extends Stage1Lib(logger){ def dirname(path: File): File = new File(realpath(path).string.stripSuffix("/").split("/").dropRight(1).mkString("/")) def nameAndContents(file: File) = basename(file) -> readAllBytes(file.toPath) - def sourceFiles( sources: Seq[File], sourceFileFilter: File => Boolean ): Seq[File] = { + /** Which file endings to consider being source files. */ + def sourceFileFilter(file: File): Boolean = file.toString.endsWith(".scala") || file.toString.endsWith(".java") + + def sourceFiles( sources: Seq[File], sourceFileFilter: File => Boolean = sourceFileFilter ): Seq[File] = { for { base <- sources.filter(_.exists).map(lib.realpath) - file <- lib.listFilesRecursive(base) if file.isFile && sourceFileFilter(file) + file <- base.listRecursive if file.isFile && sourceFileFilter(file) } yield file } @@ -309,7 +317,7 @@ final class Lib(val logger: Logger) extends Stage1Lib(logger){ try{ val names = for { base <- files.filter(_.exists).map(realpath) - file <- listFilesRecursive(base) if file.isFile + file <- base.listRecursive if file.isFile } yield { val strip = Some( base ).filter(_.isDirectory) ++ stripBaseCanonical val name = strip.foldLeft( file.getCanonicalPath )( diff --git a/stage2/ToolsTasks.scala b/stage2/ToolsTasks.scala index 0cfd501..b5e94d4 100644 --- a/stage2/ToolsTasks.scala +++ b/stage2/ToolsTasks.scala @@ -10,6 +10,8 @@ class ToolsTasks( cbtHome: File, cbtLastModified: Long )(implicit classLoaderCache: ClassLoaderCache){ + def apply: String = "Available methods: " ++ lib.taskNames(getClass).mkString(" ") + private val paths = CbtPaths(cbtHome, cache) import paths._ implicit val logger: Logger = lib.logger |