aboutsummaryrefslogtreecommitdiff
path: root/stage2
diff options
context:
space:
mode:
authorChristopher Vogt <oss.nsp@cvogt.org>2017-03-19 21:38:02 -0400
committerChristopher Vogt <oss.nsp@cvogt.org>2017-03-19 21:38:02 -0400
commit8f055d10fb3b5494115ffd8bf46b972d0937e234 (patch)
treee0519bd38f618eaa91303076007383a8f3639484 /stage2
parentff4bc8f6d8077dd8d96064267c31bdace93d892b (diff)
downloadcbt-8f055d10fb3b5494115ffd8bf46b972d0937e234.tar.gz
cbt-8f055d10fb3b5494115ffd8bf46b972d0937e234.tar.bz2
cbt-8f055d10fb3b5494115ffd8bf46b972d0937e234.zip
Get rid of the hacky "essential" plugins separation
Let’s keep move them back into stage2 again instead for reduction of complexity, cbt build speed and convenience of fewer manual dependencies. And for that let cbt just include eval from the start.
Diffstat (limited to 'stage2')
-rw-r--r--stage2/BasicBuild.scala6
-rw-r--r--stage2/BuildBuild.scala13
-rw-r--r--stage2/Lib.scala11
-rw-r--r--stage2/Plugin.scala4
-rw-r--r--stage2/plugins/CommandLineOverrides.scala27
-rw-r--r--stage2/plugins/DynamicOverrides.scala82
-rw-r--r--stage2/plugins/MultipleScalaVersions.scala9
-rw-r--r--stage2/plugins/Readme.md3
-rw-r--r--stage2/plugins/SnapshotVersion.scala7
9 files changed, 137 insertions, 25 deletions
diff --git a/stage2/BasicBuild.scala b/stage2/BasicBuild.scala
index 37b1786..491cdba 100644
--- a/stage2/BasicBuild.scala
+++ b/stage2/BasicBuild.scala
@@ -32,10 +32,10 @@ trait BaseBuild extends BuildInterface with DependencyImplementation with SbtDep
def projectDirectory: File = lib.realpath(context.workingDirectory)
assert( projectDirectory.exists, "projectDirectory does not exist: " ++ projectDirectory.string )
assert(
- projectDirectory.getName =!= lib.buildDirectoryName ||
- {
+ projectDirectory.getName =!= lib.buildDirectoryName
+ || {
def transitiveInterfaces(cls: Class[_]): Vector[Class[_]] = cls.getInterfaces.toVector.flatMap(i => i +: transitiveInterfaces(i))
- transitiveInterfaces(this.getClass).contains(classOf[BuildBuildWithoutEssentials])
+ transitiveInterfaces(this.getClass).contains(classOf[BuildBuild])
},
s"You need to extend ${lib.buildBuildClassName} in: " + projectDirectory + "/" ++ lib.buildDirectoryName
)
diff --git a/stage2/BuildBuild.scala b/stage2/BuildBuild.scala
index 7be4714..375454f 100644
--- a/stage2/BuildBuild.scala
+++ b/stage2/BuildBuild.scala
@@ -3,19 +3,13 @@ import java.nio.file._
import java.io.File
class ConcreteBuildBuild(val context: Context) extends BuildBuild
-class ConcreteBuildBuildWithoutEssentials(val context: Context) extends BuildBuildWithoutEssentials
-trait BuildBuild extends BuildBuildWithoutEssentials{
- override def dependencies =
- super.dependencies :+ plugins.essentials
-}
class plugins(implicit context: Context){
// TODO: move this out of the OO
- private def plugin(dir: String) = DirectoryDependency(
+ private def plugin(dir: String) = cbt.DirectoryDependency(
context.copy(
workingDirectory = context.cbtHome / "plugins" / dir
)
)
- final lazy val essentials = plugin( "essentials" )
final lazy val googleJavaFormat = plugin( "google-java-format" )
final lazy val proguard = plugin( "proguard" )
final lazy val sbtLayout = plugin( "sbt_layout" )
@@ -27,7 +21,8 @@ class plugins(implicit context: Context){
final lazy val uberJar = plugin( "uber-jar" )
final lazy val wartremover = plugin( "wartremover" )
}
-trait BuildBuildWithoutEssentials extends BaseBuild{
+
+trait BuildBuild extends BaseBuild{
object plugins extends plugins
assert(
@@ -44,7 +39,7 @@ trait BuildBuildWithoutEssentials extends BaseBuild{
super.dependencies :+ context.cbtDependency
def managedBuildDirectory: java.io.File = lib.realpath( projectDirectory.parent )
- def managedBuild = taskCache[BuildBuildWithoutEssentials]("managedBuild").memoize{
+ def managedBuild = taskCache[BuildBuild]("managedBuild").memoize{
val managedBuildFile = projectDirectory++("/"++lib.buildFileName)
logger.composition("Loading build at " ++ managedBuildDirectory.toString)
val build = (
diff --git a/stage2/Lib.scala b/stage2/Lib.scala
index 948cbf0..bb59604 100644
--- a/stage2/Lib.scala
+++ b/stage2/Lib.scala
@@ -38,17 +38,8 @@ final class Lib(val logger: Logger) extends Stage1Lib(logger){
val useBasicBuild = directory == start && start.getName != buildDirectoryName
try{
- if(useBasicBuild) {
+ if(useBasicBuild)
new BasicBuild( context.copy( workingDirectory = directory ) )
- } else if(
- // essentials depends on eval, which has a build that depends on scalatest
- // this means in these we can't depend on essentials
- // hopefully we find a better way that this pretty hacky exclusion rule
- directory == (context.cbtHome ++ "/plugins/essentials")
- || directory == (context.cbtHome ++ "/libraries/eval")
- || directory == (context.cbtHome ++ "/plugins/scalatest")
- )
- new cbt.ConcreteBuildBuildWithoutEssentials( context.copy( workingDirectory = start ) )
else
new cbt.ConcreteBuildBuild( context.copy( workingDirectory = start ) )
} catch {
diff --git a/stage2/Plugin.scala b/stage2/Plugin.scala
index ed4a698..43e26fa 100644
--- a/stage2/Plugin.scala
+++ b/stage2/Plugin.scala
@@ -1,7 +1,5 @@
package cbt
trait Plugin extends BaseBuild{
+ override def dependencies = super.dependencies :+ context.cbtDependency
object plugins extends plugins
-
- override def dependencies =
- super.dependencies :+ context.cbtDependency :+ plugins.essentials
}
diff --git a/stage2/plugins/CommandLineOverrides.scala b/stage2/plugins/CommandLineOverrides.scala
new file mode 100644
index 0000000..3ffaf21
--- /dev/null
+++ b/stage2/plugins/CommandLineOverrides.scala
@@ -0,0 +1,27 @@
+package cbt
+trait CommandLineOverrides extends DynamicOverrides{
+ def `with`: Any = {
+ lib.callReflective(
+ newBuild[DynamicOverrides](
+ context.copy(
+ args = context.args.drop(2)
+ )
+ )( s"""
+ ${context.args.lift(0).getOrElse("")}
+ """ ),
+ context.args.lift(1) orElse Some("void"),
+ context
+ )
+ }
+ def eval = {
+ lib.callReflective(
+ newBuild[CommandLineOverrides](
+ context.copy(
+ args = ( context.args.lift(0).map("println{ "+_+" }") ).toSeq
+ )
+ ){""},
+ Some("with"),
+ context
+ )
+ }
+}
diff --git a/stage2/plugins/DynamicOverrides.scala b/stage2/plugins/DynamicOverrides.scala
new file mode 100644
index 0000000..8d67be7
--- /dev/null
+++ b/stage2/plugins/DynamicOverrides.scala
@@ -0,0 +1,82 @@
+package cbt
+import cbt.eval.Eval
+trait DynamicOverrides extends BaseBuild{
+ private val twitterEval = {
+ taskCache[DynamicOverrides]( "eval" ).memoize{
+ new Eval{
+ override lazy val impliedClassPath: List[String] = context.parentBuild.get.classpath.strings.toList//new ScalaCompilerDependency( context.cbtLastModified, context.paths.mavenCache, scalaVersion ).classpath.strings.toList
+ override def classLoader = DynamicOverrides.this.getClass.getClassLoader
+ }
+ }
+ }
+
+ protected [cbt] def overrides: String = ""
+
+ // TODO: add support for Build inner classes
+ import scala.reflect.runtime.universe._
+ def newBuild[T <: DynamicOverrides:TypeTag]: T = newBuild[T](context)("")
+ def newBuild[T <: DynamicOverrides:TypeTag](body: String): T = newBuild[T](context)(body)
+ def newBuild[T <: DynamicOverrides:TypeTag](context: Context)(body: String): T = {
+ val tag = typeTag[T]
+ val mixinClass = tag.mirror.runtimeClass(tag.tpe)
+ assert(mixinClass.getTypeParameters.size == 0)
+ val mixin = if(
+ mixinClass == classOf[Nothing]
+ || mixinClass.getSimpleName == "Build"
+ ) "" else " with "+mixinClass.getName
+ import scala.collection.JavaConverters._
+ val parent = Option(
+ if(this.getClass.getName.startsWith("Evaluator__"))
+ this.getClass.getName.dropWhile(_ != '$').drop(1).stripSuffix("$1")
+ else
+ this.getClass.getName
+ ).getOrElse(
+ throw new Exception( "You cannot have more than one newBuild call on the Stack right now." )
+ )
+ val overrides = "" // currently disables, but can be used to force overrides everywhere
+ if(mixin == "" && overrides == "" && body == ""){
+ // TODO: is it possible for the contructor to have the wrong signature and
+ // thereby produce a pretty hard to understand error message here?
+ this.getClass
+ .getConstructor(classOf[Context])
+ .newInstance(context)
+ .asInstanceOf[T]
+ } else {
+ val baseName = "DynamicBuild" + System.currentTimeMillis
+ val overrideName = baseName+"Overrides"
+ val (finalName, code) = if(overrides == ""){
+ (
+ baseName,
+ s"""
+ class $baseName(context: _root_.cbt.Context)
+ extends $parent(context)$mixin{
+ $body
+ }
+ """
+ )
+ } else {
+ (
+ overrideName,
+ s"""
+ class $baseName(context: _root_.cbt.Context)
+ extends $parent(context)$mixin{
+ $body
+ }
+ class $overrideName(context: _root_.cbt.Context)
+ extends $baseName(context){
+ $overrides
+ }
+ """
+ )
+ }
+ logger.dynamic("Dynamically generated code:\n" ++ code)
+ twitterEval.compile(code)
+ val createBuild = twitterEval.apply[Context => T](s"new $finalName(_: _root_.cbt.Context)",false)
+ createBuild( context ).asInstanceOf[T]
+ }
+ }
+
+ def runFlat: ExitCode = newBuild[DynamicOverrides]{"""
+ override def flatClassLoader = true
+ """}.run
+}
diff --git a/stage2/plugins/MultipleScalaVersions.scala b/stage2/plugins/MultipleScalaVersions.scala
new file mode 100644
index 0000000..5d896dd
--- /dev/null
+++ b/stage2/plugins/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/stage2/plugins/Readme.md b/stage2/plugins/Readme.md
new file mode 100644
index 0000000..76d3756
--- /dev/null
+++ b/stage2/plugins/Readme.md
@@ -0,0 +1,3 @@
+Essential CBT plugins
+
+Not part of CBT's core to keep it slim and so they can have dependencies if needed.
diff --git a/stage2/plugins/SnapshotVersion.scala b/stage2/plugins/SnapshotVersion.scala
new file mode 100644
index 0000000..1f7eb23
--- /dev/null
+++ b/stage2/plugins/SnapshotVersion.scala
@@ -0,0 +1,7 @@
+package cbt
+
+trait SnapshotVersion extends ArtifactInfo with DynamicOverrides{
+ def snapshot = newBuild[SnapshotVersion]{"""
+ override def version = super.version ++ "-SNAPSHOT"
+ """}
+}