aboutsummaryrefslogtreecommitdiff
path: root/plugins
diff options
context:
space:
mode:
authorChristopher Vogt <oss.nsp@cvogt.org>2016-11-08 00:58:30 -0500
committerChristopher Vogt <oss.nsp@cvogt.org>2016-11-08 00:58:30 -0500
commit47a93993a84c572b4a2cd4562b52ec552f36879a (patch)
treeb21c25f2f4b593101d47dd7ddf178b2624fef10b /plugins
parent8ccefab7f8a09579087626fe75911115e8f6f483 (diff)
downloadcbt-47a93993a84c572b4a2cd4562b52ec552f36879a.tar.gz
cbt-47a93993a84c572b4a2cd4562b52ec552f36879a.tar.bz2
cbt-47a93993a84c572b4a2cd4562b52ec552f36879a.zip
Add support for dynamic re-configuration.
The exact precedence rule of override code vs original code may still need to be tweaked as we go along.
Diffstat (limited to 'plugins')
-rw-r--r--plugins/essentials/CommandLineOverrides.scala25
-rw-r--r--plugins/essentials/DynamicOverrides.scala66
-rw-r--r--plugins/essentials/Readme.md3
-rw-r--r--plugins/essentials/build/build.scala6
4 files changed, 100 insertions, 0 deletions
diff --git a/plugins/essentials/CommandLineOverrides.scala b/plugins/essentials/CommandLineOverrides.scala
new file mode 100644
index 0000000..32b8403
--- /dev/null
+++ b/plugins/essentials/CommandLineOverrides.scala
@@ -0,0 +1,25 @@
+package cbt
+trait CommandLineOverrides extends DynamicOverrides{
+ def `with`: Any = {
+ new lib.ReflectObject(
+ newBuild[DynamicOverrides](
+ context.copy(
+ args = context.args.drop(2)
+ )
+ )( s"""
+ ${context.args.lift(0).getOrElse("")}
+ """ )
+ ){
+ def usage = ""
+ }.callNullary(context.args.lift(1) orElse Some("void"))
+ }
+ def eval = {
+ new lib.ReflectObject(
+ newBuild[CommandLineOverrides](
+ context.copy(
+ args = ( context.args.lift(0).map("println{ "+_+" }") ).toSeq
+ )
+ ){""}
+ ){def usage = ""}.callNullary(Some("with"))
+ }
+}
diff --git a/plugins/essentials/DynamicOverrides.scala b/plugins/essentials/DynamicOverrides.scala
new file mode 100644
index 0000000..0826f12
--- /dev/null
+++ b/plugins/essentials/DynamicOverrides.scala
@@ -0,0 +1,66 @@
+package cbt
+import cbt.eval.Eval
+trait DynamicOverrides extends BaseBuild{
+ private val twitterEval = cached("eval"){
+ new Eval{
+ override lazy val impliedClassPath: List[String] = context.parentBuild.get.classpath.strings.toList//new ScalaCompilerDependency( context.cbtHasChanged, 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
+ def newBuild[T <: DynamicOverrides:scala.reflect.ClassTag]: DynamicOverrides with T = newBuild[T](context)("")
+ def newBuild[T <: DynamicOverrides:scala.reflect.ClassTag](body: String): DynamicOverrides with T = newBuild[T](context)(body)
+ def newBuild[T <: DynamicOverrides:scala.reflect.ClassTag](context: Context)(body: String): DynamicOverrides with T = {
+ val mixinClass = scala.reflect.classTag[T].runtimeClass
+ 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
+ val name = if(mixin == "" && overrides == "" && body == ""){
+ "Build"
+ } else if(overrides == ""){
+ val name = "DynamicBuild" + System.currentTimeMillis
+ val code = s"""
+ class $name(context: _root_.cbt.Context)
+ extends $parent(context)$mixin{
+ $body
+ }
+ """
+ logger.dynamic("Dynamically generated code:\n" ++ code)
+ twitterEval.compile(code)
+ name
+ } else {
+ val name = "DynamicBuild" + System.currentTimeMillis
+ val code = s"""
+ class $name(context: _root_.cbt.Context)
+ extends $parent(context)$mixin{
+ $body
+ }
+ class ${name}Overrides(context: _root_.cbt.Context)
+ extends $name(context){
+ $overrides
+ }
+ """
+ logger.dynamic("Dynamically generated code:\n" ++ code)
+ twitterEval.compile(code)
+ name+"Overrides"
+ }
+
+ val createBuild = twitterEval.apply[Context => T](s"new $name(_: _root_.cbt.Context)",false)
+ createBuild( context ).asInstanceOf[DynamicOverrides with T]
+ }
+}
diff --git a/plugins/essentials/Readme.md b/plugins/essentials/Readme.md
new file mode 100644
index 0000000..76d3756
--- /dev/null
+++ b/plugins/essentials/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/plugins/essentials/build/build.scala b/plugins/essentials/build/build.scala
new file mode 100644
index 0000000..1288367
--- /dev/null
+++ b/plugins/essentials/build/build.scala
@@ -0,0 +1,6 @@
+import cbt._
+class Build(val context: Context) extends Plugin{
+ override def dependencies =
+ super.dependencies :+ // don't forget super.dependencies here for scala-library, etc.
+ DirectoryDependency( context.cbtHome ++ "/libraries/eval" )
+}