aboutsummaryrefslogtreecommitdiff
path: root/stage2
diff options
context:
space:
mode:
Diffstat (limited to 'stage2')
-rw-r--r--stage2/BasicBuild.scala33
-rw-r--r--stage2/BuildDependency.scala1
-rw-r--r--stage2/Lib.scala56
-rw-r--r--stage2/ToolsTasks.scala2
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