diff options
31 files changed, 110 insertions, 25 deletions
diff --git a/compatibility/BuildInterface.java b/compatibility/BuildInterface.java index f061832..ebcfb99 100644 --- a/compatibility/BuildInterface.java +++ b/compatibility/BuildInterface.java @@ -2,9 +2,11 @@ package cbt; import java.io.*; public abstract class BuildInterface implements Dependency{ - public abstract BuildInterface copy(Context context); // needed to configure builds - public abstract String scalaVersion(); // needed to propagate scalaVersion to dependent builds - public abstract String[] crossScalaVersionsArray(); // FIXME: this probably can't use Scala classes public abstract BuildInterface finalBuild(); // needed to propagage through build builds. Maybe we can get rid of this. public abstract File[] triggerLoopFilesArray(); // needed for watching files across composed builds + + // deprecated methods, which clients are still allowed to implement, but not required + public abstract BuildInterface copy(Context context); + public abstract String scalaVersion(); + public abstract String[] crossScalaVersionsArray(); } diff --git a/compatibility/Dependency.java b/compatibility/Dependency.java index 1f719c2..e23faa6 100644 --- a/compatibility/Dependency.java +++ b/compatibility/Dependency.java @@ -13,11 +13,12 @@ public interface Dependency{ // methods that exist for longer which every CBT version in use should have by now, no default values needed public abstract String show(); public abstract Dependency[] dependenciesArray(); - public abstract File[] dependencyClasspathArray(); public abstract File[] exportedClasspathArray(); // deprecated methods @java.lang.Deprecated public abstract boolean needsUpdateCompat(); + @java.lang.Deprecated + public abstract File[] dependencyClasspathArray(); } diff --git a/examples/cross-build-example/build/build.scala b/examples/cross-build-example/build/build.scala new file mode 100644 index 0000000..e1df645 --- /dev/null +++ b/examples/cross-build-example/build/build.scala @@ -0,0 +1,4 @@ +import cbt._ +class Build(val context: Context) extends MultipleScalaVersions{ + override def scalaVersions = Seq("2.10.5","2.11.7") +} diff --git a/examples/cross-build-example/src/Main.scala b/examples/cross-build-example/src/Main.scala new file mode 100644 index 0000000..88a18d3 --- /dev/null +++ b/examples/cross-build-example/src/Main.scala @@ -0,0 +1,3 @@ +object Main extends App { + println("Hello World") +} diff --git a/examples/multi-combined-example/Readme.md b/examples/multi-combined-example/Readme.md new file mode 100644 index 0000000..01302d4 --- /dev/null +++ b/examples/multi-combined-example/Readme.md @@ -0,0 +1 @@ +This is an example how to do a multi-project build with a single build file. diff --git a/examples/multi-combined-example/build/build.scala b/examples/multi-combined-example/build/build.scala new file mode 100644 index 0000000..41c03d6 --- /dev/null +++ b/examples/multi-combined-example/build/build.scala @@ -0,0 +1,44 @@ +import cbt._ +import cbt._ +trait SharedCbtBuild extends BaseBuild{ + override def defaultScalaVersion = "2.10.6" +} + + +class Shared(val context: Context) extends SharedCbtBuild + +class Sub(val context:Context) extends SharedCbtBuild{ + override def dependencies = Seq(new Shared( + context.copy( + projectDirectory = projectDirectory ++ "/../shared" + ) + )) +} + +class Build(val context: Context) extends BaseBuild{ + /* + Currently each sub build nested into the main build needs to be an instance + of a top-level class taking a Context as the sole parameter, similar to the + Build class itself. This restriction may be lifted for more flexibility at + some point, see https://github.com/cvogt/cbt/issues/306 + */ + def sub1 = new Sub( + context.copy( + projectDirectory = projectDirectory ++ "/sub1" + ) + ) + def sub2 = new Sub( + context.copy( + projectDirectory = projectDirectory ++ "/sub2" + ) + ) + + def sub3 = // DON'T DO THIS, anonymous classes are currently not supported here. + new SharedCbtBuild{ + def context = Build.this.context.copy( + projectDirectory = Build.this.projectDirectory ++ "/sub3" + ) + } + + override def dependencies = Seq( sub1, sub2 ) // assembles all projects +} diff --git a/examples/multi-combined-example/shared/SomeSharedClass.scala b/examples/multi-combined-example/shared/SomeSharedClass.scala new file mode 100644 index 0000000..d7d99e4 --- /dev/null +++ b/examples/multi-combined-example/shared/SomeSharedClass.scala @@ -0,0 +1,6 @@ +package cbt.examples.multi_combined +class SomeSharedClass{ + def main(args: Array[String]): Unit = { + println(this.getClass.getSimpleName) + } +} diff --git a/examples/multi-combined-example/sub1/SomeConcreteClass.scala b/examples/multi-combined-example/sub1/SomeConcreteClass.scala new file mode 100644 index 0000000..e55cb12 --- /dev/null +++ b/examples/multi-combined-example/sub1/SomeConcreteClass.scala @@ -0,0 +1,2 @@ +package cbt.examples.multi_combined +object SomeConcreteClass extends SomeSharedClass diff --git a/examples/multi-combined-example/sub2/SomeOtherConcreteClass.scala b/examples/multi-combined-example/sub2/SomeOtherConcreteClass.scala new file mode 100644 index 0000000..399aee6 --- /dev/null +++ b/examples/multi-combined-example/sub2/SomeOtherConcreteClass.scala @@ -0,0 +1,2 @@ +package cbt.examples.multi_combined +object SomeOtherConcreteClass extends SomeSharedClass diff --git a/examples/multi-standalone-example/Readme.md b/examples/multi-standalone-example/Readme.md new file mode 100644 index 0000000..be89598 --- /dev/null +++ b/examples/multi-standalone-example/Readme.md @@ -0,0 +1,3 @@ +This is an example how to build a multi-project build using CBT while keeping each project self-contained with it's own build files. + +Check the multi-combined-example for how to do it with a single build file for all builds together instead. diff --git a/examples/multi-project-example/build/build.scala b/examples/multi-standalone-example/build/build.scala index 9a67488..9a67488 100644 --- a/examples/multi-project-example/build/build.scala +++ b/examples/multi-standalone-example/build/build.scala diff --git a/examples/multi-project-example/build/build/build.scala b/examples/multi-standalone-example/build/build/build.scala index be72a13..be72a13 100644 --- a/examples/multi-project-example/build/build/build.scala +++ b/examples/multi-standalone-example/build/build/build.scala diff --git a/examples/multi-project-example/common/SomeSharedClass.scala b/examples/multi-standalone-example/common/SomeSharedClass.scala index 1f32c5a..1f32c5a 100644 --- a/examples/multi-project-example/common/SomeSharedClass.scala +++ b/examples/multi-standalone-example/common/SomeSharedClass.scala diff --git a/examples/multi-project-example/common/build/build.scala b/examples/multi-standalone-example/common/build/build.scala index 0fbea50..0fbea50 100644 --- a/examples/multi-project-example/common/build/build.scala +++ b/examples/multi-standalone-example/common/build/build.scala diff --git a/examples/multi-project-example/common/build/build/build.scala b/examples/multi-standalone-example/common/build/build/build.scala index efeeb77..efeeb77 100644 --- a/examples/multi-project-example/common/build/build/build.scala +++ b/examples/multi-standalone-example/common/build/build/build.scala diff --git a/examples/multi-project-example/shared-build/SharedCbtBuild.scala b/examples/multi-standalone-example/shared-build/SharedCbtBuild.scala index 38e4cc1..38e4cc1 100644 --- a/examples/multi-project-example/shared-build/SharedCbtBuild.scala +++ b/examples/multi-standalone-example/shared-build/SharedCbtBuild.scala diff --git a/examples/multi-project-example/shared-build/build/build.scala b/examples/multi-standalone-example/shared-build/build/build.scala index 332519e..332519e 100644 --- a/examples/multi-project-example/shared-build/build/build.scala +++ b/examples/multi-standalone-example/shared-build/build/build.scala diff --git a/examples/multi-project-example/sub1/SomeConcreteClass.scala b/examples/multi-standalone-example/sub1/SomeConcreteClass.scala index 2f8f715..2f8f715 100644 --- a/examples/multi-project-example/sub1/SomeConcreteClass.scala +++ b/examples/multi-standalone-example/sub1/SomeConcreteClass.scala diff --git a/examples/multi-project-example/sub1/build/build.scala b/examples/multi-standalone-example/sub1/build/build.scala index 2c39a54..2c39a54 100644 --- a/examples/multi-project-example/sub1/build/build.scala +++ b/examples/multi-standalone-example/sub1/build/build.scala diff --git a/examples/multi-project-example/sub1/build/build/build.scala b/examples/multi-standalone-example/sub1/build/build/build.scala index efeeb77..efeeb77 100644 --- a/examples/multi-project-example/sub1/build/build/build.scala +++ b/examples/multi-standalone-example/sub1/build/build/build.scala diff --git a/examples/multi-project-example/sub2/SomeOtherConcreteClass.scala b/examples/multi-standalone-example/sub2/SomeOtherConcreteClass.scala index 56b0aa3..56b0aa3 100644 --- a/examples/multi-project-example/sub2/SomeOtherConcreteClass.scala +++ b/examples/multi-standalone-example/sub2/SomeOtherConcreteClass.scala diff --git a/examples/multi-project-example/sub2/build/build.scala b/examples/multi-standalone-example/sub2/build/build.scala index 2c39a54..2c39a54 100644 --- a/examples/multi-project-example/sub2/build/build.scala +++ b/examples/multi-standalone-example/sub2/build/build.scala diff --git a/examples/multi-project-example/sub2/build/build/build.scala b/examples/multi-standalone-example/sub2/build/build/build.scala index efeeb77..efeeb77 100644 --- a/examples/multi-project-example/sub2/build/build/build.scala +++ b/examples/multi-standalone-example/sub2/build/build/build.scala diff --git a/plugins/essentials/MultipleScalaVersions.scala b/plugins/essentials/MultipleScalaVersions.scala new file mode 100644 index 0000000..5d896dd --- /dev/null +++ b/plugins/essentials/MultipleScalaVersions.scala @@ -0,0 +1,9 @@ +package cbt + +trait MultipleScalaVersions extends DynamicOverrides{ + def scalaVersions: Seq[String] = Seq(scalaVersion, "2.10.6") + def cross: Seq[MultipleScalaVersions] = + scalaVersions.map{ v => + newBuild[MultipleScalaVersions](context.copy(scalaVersion = Some(v)))("") + } +} diff --git a/stage1/Stage1Lib.scala b/stage1/Stage1Lib.scala index 4f3f592..5a2f05d 100644 --- a/stage1/Stage1Lib.scala +++ b/stage1/Stage1Lib.scala @@ -413,7 +413,7 @@ ${sourceFiles.sorted.mkString(" \\\n")} case d => d } - def classLoaderRecursion( dependency: Dependency, latest: Map[(String,String),Dependency], cache: ClassLoaderCache ): ClassLoader = { + def classLoaderRecursion( dependency: Dependency, latest: Map[(String,String),Dependency], cache: ClassLoaderCache)(implicit transientCache: java.util.Map[AnyRef,AnyRef] ): ClassLoader = { // FIXME: shouldn't we be using KeyLockedLazyCache instead of hashmap directly here? val dependencies = dependency.dependencies val dependencyClassLoader: ClassLoader = { diff --git a/stage1/cbt.scala b/stage1/cbt.scala index 8520be4..a1776b1 100644 --- a/stage1/cbt.scala +++ b/stage1/cbt.scala @@ -44,7 +44,6 @@ object `package`{ // then we wouldn't need this and could provide this method from a // plugin rather than hard-coding trigger files stuff in cbt def triggerLoopFiles: Seq[File] = triggerLoopFilesArray.to - def crossScalaVersions: Seq[String] = crossScalaVersionsArray.to } implicit class ArtifactInfoExtensions(subject: ArtifactInfo){ import subject._ @@ -53,9 +52,10 @@ object `package`{ } implicit class DependencyExtensions(subject: Dependency){ import subject._ - def dependencyClasspath: ClassPath = ClassPath(dependencyClasspathArray.to) + def dependencyClasspath(implicit logger: Logger, transientCache: java.util.Map[AnyRef,AnyRef]): ClassPath + = Dependencies(dependenciesArray.to).classpath def exportedClasspath: ClassPath = ClassPath(exportedClasspathArray.to) - def classpath = exportedClasspath ++ dependencyClasspath + def classpath(implicit logger: Logger, transientCache: java.util.Map[AnyRef,AnyRef]) = exportedClasspath ++ dependencyClasspath def dependencies: Seq[Dependency] = dependenciesArray.to } implicit class ContextExtensions(subject: Context){ diff --git a/stage1/resolver.scala b/stage1/resolver.scala index e6e4588..97cd36a 100644 --- a/stage1/resolver.scala +++ b/stage1/resolver.scala @@ -19,13 +19,15 @@ trait DependencyImplementation extends Dependency{ protected lazy val taskCache = new PerClassCache(transientCache, moduleKey) private[cbt] def targetClasspath: ClassPath - def dependencyClasspathArray: Array[File] = dependencyClasspath.files.toArray def exportedClasspathArray: Array[File] = exportedClasspath.files.toArray def exportedClasspath: ClassPath def dependenciesArray: Array[Dependency] = dependencies.to - @deprecated("this method is replaced by lastModifiedCompat","") + @deprecated("this method was replaced by lastModifiedCompat","") def needsUpdateCompat = true + @deprecated("this method was replaced by dependenciesArray","") + def dependencyClasspathArray = dependencyClasspath.files.toArray + /* //private type BuildCache = KeyLockedLazyCache[Dependency, Future[ClassPath]] diff --git a/stage2/BasicBuild.scala b/stage2/BasicBuild.scala index ed03de2..b7b0854 100644 --- a/stage2/BasicBuild.scala +++ b/stage2/BasicBuild.scala @@ -41,8 +41,6 @@ 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 crossScalaVersions: Seq[String] = Seq(scalaVersion, "2.10.6") - final def crossScalaVersionsArray: Array[String] = crossScalaVersions.to def projectName = "default" // TODO: get rid of this in favor of newBuild. @@ -285,4 +283,7 @@ trait BaseBuild extends BuildInterface with DependencyImplementation with Trigge // a method that can be called only to trigger any side-effects final def `void` = () + + @deprecated("use the MultipleScalaVersions plugin instead","") + final def crossScalaVersionsArray = Array(scalaVersion) } diff --git a/stage2/Lib.scala b/stage2/Lib.scala index 47e1635..fcf2642 100644 --- a/stage2/Lib.scala +++ b/stage2/Lib.scala @@ -181,6 +181,20 @@ final class Lib(val logger: Logger) extends Stage1Lib(logger) with Scaffold{ case code if code.getClass.getSimpleName == "ExitCode" => // FIXME: ExitCode needs to be part of the compatibility interfaces ExitCode(Stage0Lib.get(code,"integer").asInstanceOf[Int]) + case b: BaseBuild => + val context = b.context.copy(args=b.context.args.drop(1)) + val task = b.context.args.lift(0) + new ReflectBuild( b.copy(context=context) ).callNullary( task ) + case Seq(b: BaseBuild, bs @ _*) if bs.forall(_.isInstanceOf[BaseBuild]) => + (b +: bs) + .map( _.asInstanceOf[BaseBuild] ) + .map{ b => + val task = b.context.args.lift(0) + new ReflectBuild( + b.copy( context = b.context.copy(args=b.context.args.drop(1)) ) + ).callNullary( task ) + } + .head case other => println( other.toString ) // no method .toConsole, using to String ExitCode.Success diff --git a/stage2/Stage2.scala b/stage2/Stage2.scala index 0f5b557..25cd0ae 100644 --- a/stage2/Stage2.scala +++ b/stage2/Stage2.scala @@ -12,12 +12,10 @@ object Stage2 extends Stage2Base{ val paths = CbtPaths(args.cbtHome,args.cache) import paths._ val lib = new Lib(args.logger) - logger.stage2(s"Stage2 start") val loop = args.args.lift(0) == Some("loop") - val cross = args.args.lift(0) == Some("cross") - val taskIndex = if (loop || cross) { + val taskIndex = if (loop) { 1 } else { 0 @@ -44,15 +42,7 @@ object Stage2 extends Stage2Base{ val build = first.finalBuild def call(build: BuildInterface): ExitCode = { - if(cross){ - build.crossScalaVersions.map{ - v => new lib.ReflectBuild( - build.copy(context.copy(scalaVersion = Some(v))) - ).callNullary(task) - }.filter(_ != ExitCode.Success).headOption getOrElse ExitCode.Success - } else { - new lib.ReflectBuild(build).callNullary(task) - } + new lib.ReflectBuild(build).callNullary(task) } val res = diff --git a/test/test.scala b/test/test.scala index ecc44ca..ca9d87b 100644 --- a/test/test.scala +++ b/test/test.scala @@ -204,7 +204,8 @@ object Main{ compile("../examples/scalatest-example") compile("../examples/scalajs-react-example/js") compile("../examples/scalajs-react-example/jvm") - compile("../examples/multi-project-example") + compile("../examples/multi-standalone-example") + compile("../examples/multi-combined-example") if(sys.props("java.version").startsWith("1.7")){ System.err.println("\nskipping dotty tests on Java 7") } else { |