aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--compatibility/Dependency.java1
-rw-r--r--plugins/essentials/DynamicOverrides.scala10
-rw-r--r--plugins/scalajs/ScalaJsLib.scala2
-rw-r--r--stage1/Cache.scala14
-rw-r--r--stage1/ContextImplementation.scala32
-rw-r--r--stage1/MavenRepository.scala10
-rw-r--r--stage1/Stage1.scala15
-rw-r--r--stage1/Stage1Lib.scala25
-rw-r--r--stage1/cbt.scala4
-rw-r--r--stage1/logger.scala2
-rw-r--r--stage1/resolver.scala102
-rw-r--r--stage2/BasicBuild.scala29
-rw-r--r--stage2/BuildBuild.scala3
-rw-r--r--stage2/BuildDependency.scala3
-rw-r--r--stage2/GitDependency.scala10
-rw-r--r--stage2/Lib.scala4
-rw-r--r--stage2/PackageJars.scala9
-rw-r--r--stage2/Stage2.scala4
-rw-r--r--stage2/ToolsTasks.scala1
-rw-r--r--stage2/plugins/Dotty.scala5
-rw-r--r--test/test.scala5
21 files changed, 148 insertions, 142 deletions
diff --git a/compatibility/Dependency.java b/compatibility/Dependency.java
index d491174..efb9214 100644
--- a/compatibility/Dependency.java
+++ b/compatibility/Dependency.java
@@ -3,6 +3,7 @@ import java.io.*;
public interface Dependency{
public abstract String show();
+ public abstract String moduleKey();
public abstract Boolean needsUpdateCompat();
public abstract Dependency[] dependenciesArray();
public abstract File[] dependencyClasspathArray();
diff --git a/plugins/essentials/DynamicOverrides.scala b/plugins/essentials/DynamicOverrides.scala
index 4a3fe9e..1050f98 100644
--- a/plugins/essentials/DynamicOverrides.scala
+++ b/plugins/essentials/DynamicOverrides.scala
@@ -1,10 +1,12 @@
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
+ 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
+ }
}
}
diff --git a/plugins/scalajs/ScalaJsLib.scala b/plugins/scalajs/ScalaJsLib.scala
index 0355850..12c1c85 100644
--- a/plugins/scalajs/ScalaJsLib.scala
+++ b/plugins/scalajs/ScalaJsLib.scala
@@ -4,7 +4,7 @@ import java.io.File
case class ScalaJsLib(
scalaJsVersion: String, scalaVersion: String,
cbtHasChanged: Boolean, classLoaderCache: ClassLoaderCache, mavenCache: File
-)(implicit logger: Logger){
+)(implicit logger: Logger, transientCache: java.util.Map[AnyRef,AnyRef]){
sealed trait ScalaJsOutputMode {
def option: String
def fileSuffix: String
diff --git a/stage1/Cache.scala b/stage1/Cache.scala
deleted file mode 100644
index a8036e5..0000000
--- a/stage1/Cache.scala
+++ /dev/null
@@ -1,14 +0,0 @@
-package cbt
-/**
-Caches exactly one value.
-Is there a less boiler-platy way to achieve this, that doesn't
-require creating an instance for each thing you want to cache?
-*/
-class Cache[T]{
- private var value: Option[T] = None
- def apply(value: => T) = this.synchronized{
- if(!this.value.isDefined)
- this.value = Some(value)
- this.value.get
- }
-}
diff --git a/stage1/ContextImplementation.scala b/stage1/ContextImplementation.scala
index 3b610c0..30db597 100644
--- a/stage1/ContextImplementation.scala
+++ b/stage1/ContextImplementation.scala
@@ -2,19 +2,19 @@ package cbt
import java.io._
import java.lang._
-case class ContextImplementation(
- projectDirectory: File,
- cwd: File,
- argsArray: Array[String],
- enabledLoggersArray: Array[String],
- startCompat: Long,
- cbtHasChangedCompat: Boolean,
- scalaVersionOrNull: String,
- persistentCache: java.util.Map[AnyRef,AnyRef],
- transientCache: java.util.Map[AnyRef,AnyRef],
- cache: File,
- cbtHome: File,
- cbtRootHome: File,
- compatibilityTarget: File,
- parentBuildOrNull: BuildInterface
-) extends Context \ No newline at end of file
+class ContextImplementation(
+ val projectDirectory: File,
+ val cwd: File,
+ val argsArray: Array[String],
+ val enabledLoggersArray: Array[String],
+ val startCompat: Long,
+ val cbtHasChangedCompat: Boolean,
+ val scalaVersionOrNull: String,
+ val persistentCache: java.util.Map[AnyRef,AnyRef],
+ val transientCache: java.util.Map[AnyRef,AnyRef],
+ val cache: File,
+ val cbtHome: File,
+ val cbtRootHome: File,
+ val compatibilityTarget: File,
+ val parentBuildOrNull: BuildInterface
+) extends Context
diff --git a/stage1/MavenRepository.scala b/stage1/MavenRepository.scala
index 4184d2d..2ac7064 100644
--- a/stage1/MavenRepository.scala
+++ b/stage1/MavenRepository.scala
@@ -1,9 +1,13 @@
package cbt
import java.io._
import java.net._
-case class MavenResolver( cbtHasChanged: Boolean, mavenCache: File, urls: URL* ){
- def bind( dependencies: MavenDependency* )(implicit logger: Logger): Seq[BoundMavenDependency]
+case class MavenResolver(
+ cbtHasChanged: Boolean, mavenCache: File, urls: URL*
+)(
+ implicit logger: Logger, transientCache: java.util.Map[AnyRef,AnyRef]
+){
+ def bind( dependencies: MavenDependency* ): Seq[BoundMavenDependency]
= dependencies.map( BoundMavenDependency(cbtHasChanged,mavenCache,_,urls.to) ).to
- def bindOne( dependency: MavenDependency )(implicit logger: Logger): BoundMavenDependency
+ def bindOne( dependency: MavenDependency ): BoundMavenDependency
= BoundMavenDependency( cbtHasChanged, mavenCache, dependency, urls.to )
}
diff --git a/stage1/Stage1.scala b/stage1/Stage1.scala
index f0540b4..27c6402 100644
--- a/stage1/Stage1.scala
+++ b/stage1/Stage1.scala
@@ -44,6 +44,8 @@ case class Stage2Args(
cache: File,
cbtHome: File,
compatibilityTarget: File
+)(
+ implicit val transientCache: java.util.Map[AnyRef,AnyRef]
){
val ClassLoaderCache( logger, persistentCache ) = classLoaderCache
}
@@ -60,7 +62,7 @@ object Stage1{
ClassLoaderCache( logger, context.persistentCache ),
context.cbtHome,
context.cache
- )
+ )( context.transientCache )
classLoader
.loadClass("cbt.Stage2")
@@ -75,7 +77,7 @@ object Stage1{
def buildStage2(
buildStage1: BuildStage1Result, classLoaderCache: ClassLoaderCache, cbtHome: File, cache: File
- ): (Boolean, ClassLoader) = {
+ )(implicit transientCache: java.util.Map[AnyRef,AnyRef]): (Boolean, ClassLoader) = {
import classLoaderCache.logger
val lib = new Stage1Lib(logger)
@@ -86,12 +88,12 @@ object Stage1{
val stage2sourceFiles = (
stage2.listFiles ++ (stage2 ++ "/plugins").listFiles
).toVector.filter(_.isFile).filter(_.toString.endsWith(".scala"))
-
+
val cbtHasChanged = buildStage1.changed || lib.needsUpdate(stage2sourceFiles, stage2StatusFile)
val cls = this.getClass.getClassLoader.loadClass("cbt.NailgunLauncher")
-
- val cbtDependency = CbtDependency(cbtHasChanged, mavenCache, nailgunTarget, stage1Target, stage2Target, new File(buildStage1.compatibilityClasspath))
+
+ val cbtDependency = new CbtDependency(cbtHasChanged, mavenCache, nailgunTarget, stage1Target, stage2Target, new File(buildStage1.compatibilityClasspath))
logger.stage1("Compiling stage2 if necessary")
compile(
@@ -102,7 +104,7 @@ object Stage1{
mavenCache,
Seq("-deprecation","-feature","-unchecked"), classLoaderCache,
zincVersion = constants.zincVersion, scalaVersion = constants.scalaVersion
- )
+ )(transientCache)
logger.stage1(s"calling CbtDependency.classLoader")
if( cbtHasChanged && classLoaderCache.cache.containsKey( cbtDependency.classpath.string ) ) {
@@ -163,6 +165,7 @@ object Stage1{
): Int = {
val args = Stage1ArgsParser(_args.toVector)
val logger = new Logger(args.enabledLoggers, start)
+ implicit val transientCache: java.util.Map[AnyRef,AnyRef] = new java.util.HashMap
logger.stage1(s"Stage1 start")
val classLoaderCache = ClassLoaderCache( logger, persistentCache )
diff --git a/stage1/Stage1Lib.scala b/stage1/Stage1Lib.scala
index 296581c..f0bb588 100644
--- a/stage1/Stage1Lib.scala
+++ b/stage1/Stage1Lib.scala
@@ -200,8 +200,9 @@ class Stage1Lib( val logger: Logger ) extends BaseLib{
classLoaderCache: ClassLoaderCache,
zincVersion: String,
scalaVersion: String
+ )(
+ implicit transientCache: java.util.Map[AnyRef, AnyRef]
): Option[File] = {
-
val classpath = Dependencies(dependencies).classpath
val cp = classpath.string
if(classpath.files.isEmpty)
@@ -447,4 +448,26 @@ class Stage1Lib( val logger: Logger ) extends BaseLib{
else
cache.cache.get( a.classpath.string, cl ).asInstanceOf[ClassLoader]
}
+
+}
+
+import scala.reflect._
+import scala.language.existentials
+case class PerClassCache(cache: java.util.Map[AnyRef,AnyRef], moduleKey: String)(implicit logger: Logger){
+ def apply[D <: Dependency: ClassTag](key: AnyRef): MethodCache[D] = new MethodCache[D](key)
+ case class MethodCache[D <: Dependency: ClassTag](key: AnyRef){
+ def memoize[T <: AnyRef](task: => T): T = {
+ val fullKey = (classTag[D].runtimeClass, moduleKey, key)
+ logger.transientCache("fetching key"+fullKey)
+ if( cache.containsKey(fullKey) ){
+ logger.transientCache("found key"+fullKey)
+ cache.get(fullKey).asInstanceOf[T]
+ } else{
+ val value = task
+ logger.transientCache("put key"+fullKey)
+ cache.put( fullKey, value )
+ value
+ }
+ }
+ }
}
diff --git a/stage1/cbt.scala b/stage1/cbt.scala
index 22242d7..01c9303 100644
--- a/stage1/cbt.scala
+++ b/stage1/cbt.scala
@@ -62,7 +62,7 @@ object `package`{
def classLoaderCache: ClassLoaderCache = new ClassLoaderCache( logger, persistentCache )
def cbtDependency = {
import paths._
- CbtDependency(cbtHasChanged, mavenCache, nailgunTarget, stage1Target, stage2Target, compatibilityTarget)
+ new CbtDependency(cbtHasChanged, mavenCache, nailgunTarget, stage1Target, stage2Target, compatibilityTarget)(logger, transientCache)
}
def args: Seq[String] = argsArray.to
def enabledLoggers: Set[String] = enabledLoggersArray.to
@@ -79,7 +79,7 @@ object `package`{
scalaVersion: Option[String] = scalaVersion,
cbtHome: File = cbtHome,
parentBuild: Option[BuildInterface] = None
- ): Context = ContextImplementation(
+ ): Context = new ContextImplementation(
projectDirectory,
cwd,
args.to,
diff --git a/stage1/logger.scala b/stage1/logger.scala
index effdc35..8c8431a 100644
--- a/stage1/logger.scala
+++ b/stage1/logger.scala
@@ -41,6 +41,7 @@ case class Logger(enabledLoggers: Set[String], start: Long) {
final def git(msg: => String) = log(names.git, msg)
final def pom(msg: => String) = log(names.pom, msg)
final def dynamic(msg: => String) = log(names.dynamic, msg)
+ final def transientCache(msg: => String) = log(names.transientCache, msg)
private object names{
val stage1 = "stage1"
@@ -54,6 +55,7 @@ case class Logger(enabledLoggers: Set[String], start: Long) {
val pom = "pom"
val git = "git"
val dynamic = "dynamic"
+ val transientCache = "transientCache"
}
private def logUnguarded(name: String, msg: => String) = {
diff --git a/stage1/resolver.scala b/stage1/resolver.scala
index f4af73e..8e46135 100644
--- a/stage1/resolver.scala
+++ b/stage1/resolver.scala
@@ -8,6 +8,15 @@ import scala.xml._
trait DependencyImplementation extends Dependency{
implicit protected def logger: Logger
protected def lib = new Stage1Lib(logger)
+ implicit protected def transientCache: java.util.Map[AnyRef,AnyRef]
+
+ /** key used by taskCache to identify different objects that represent the same logical module */
+ protected def moduleKey: String
+ /**
+ caches given value in context keyed with given key and projectDirectory
+ the context is fresh on every complete run of cbt
+ */
+ protected lazy val taskCache = new PerClassCache(transientCache, moduleKey)
/**
CAREFUL: this is never allowed to return true for the same dependency more than
@@ -101,11 +110,11 @@ trait DependencyImplementation extends Dependency{
)
def dependencies: Seq[Dependency]
- private object transitiveDependenciesCache extends Cache[Seq[Dependency]]
/** return dependencies in order of linearized dependence. this is a bit tricky. */
- def transitiveDependencies: Seq[Dependency] = transitiveDependenciesCache{
- lib.transitiveDependencies(this)
- }
+ def transitiveDependencies: Seq[Dependency] =
+ taskCache[DependencyImplementation]( "transitiveDependencies" ).memoize{
+ lib.transitiveDependencies(this)
+ }
override def show: String = this.getClass.getSimpleName
// ========== debug ==========
@@ -113,65 +122,63 @@ trait DependencyImplementation extends Dependency{
}
// TODO: all this hard codes the scala version, needs more flexibility
-class ScalaCompilerDependency(cbtHasChanged: Boolean, mavenCache: File, version: String)(implicit logger: Logger) extends BoundMavenDependency(cbtHasChanged, mavenCache, MavenDependency("org.scala-lang","scala-compiler",version, Classifier.none), Seq(mavenCentral))
-class ScalaLibraryDependency (cbtHasChanged: Boolean, mavenCache: File, version: String)(implicit logger: Logger) extends BoundMavenDependency(cbtHasChanged, mavenCache, MavenDependency("org.scala-lang","scala-library",version, Classifier.none), Seq(mavenCentral))
-class ScalaReflectDependency (cbtHasChanged: Boolean, mavenCache: File, version: String)(implicit logger: Logger) extends BoundMavenDependency(cbtHasChanged, mavenCache, MavenDependency("org.scala-lang","scala-reflect",version, Classifier.none), Seq(mavenCentral))
+class ScalaCompilerDependency(cbtHasChanged: Boolean, mavenCache: File, version: String)(implicit logger: Logger, transientCache: java.util.Map[AnyRef,AnyRef]) extends BoundMavenDependency(cbtHasChanged, mavenCache, MavenDependency("org.scala-lang","scala-compiler",version, Classifier.none), Seq(mavenCentral))
+class ScalaLibraryDependency (cbtHasChanged: Boolean, mavenCache: File, version: String)(implicit logger: Logger, transientCache: java.util.Map[AnyRef,AnyRef]) extends BoundMavenDependency(cbtHasChanged, mavenCache, MavenDependency("org.scala-lang","scala-library",version, Classifier.none), Seq(mavenCentral))
+class ScalaReflectDependency (cbtHasChanged: Boolean, mavenCache: File, version: String)(implicit logger: Logger, transientCache: java.util.Map[AnyRef,AnyRef]) extends BoundMavenDependency(cbtHasChanged, mavenCache, MavenDependency("org.scala-lang","scala-reflect",version, Classifier.none), Seq(mavenCentral))
-case class ScalaDependencies(cbtHasChanged: Boolean, mavenCache: File, version: String)(implicit val logger: Logger) extends DependencyImplementation{ sd =>
- override final val needsUpdate = false
- def targetClasspath = ClassPath()
- def exportedClasspath = ClassPath()
- def dependencies = Seq(
+class ScalaDependencies(cbtHasChanged: Boolean, mavenCache: File, version: String)(implicit logger: Logger, transientCache: java.util.Map[AnyRef,AnyRef]) extends Dependencies(
+ Seq(
new ScalaCompilerDependency(cbtHasChanged, mavenCache, version),
new ScalaLibraryDependency(cbtHasChanged, mavenCache, version),
new ScalaReflectDependency(cbtHasChanged, mavenCache, version)
)
-}
+)
-case class BinaryDependency( paths: Seq[File], dependencies: Seq[Dependency] )(implicit val logger: Logger) extends DependencyImplementation{
+case class BinaryDependency( paths: Seq[File], dependencies: Seq[Dependency] )(implicit val logger: Logger, val transientCache: java.util.Map[AnyRef,AnyRef]) extends DependencyImplementation{
+ assert(paths.nonEmpty)
def exportedClasspath = ClassPath(paths)
override def needsUpdate = false
def targetClasspath = exportedClasspath
+ def moduleKey = this.getClass.getName ++ "(" ++ paths.mkString(", ") ++ ")"
}
/** Allows to easily assemble a bunch of dependencies */
-case class Dependencies( dependencies: Seq[Dependency] )(implicit val logger: Logger) extends DependencyImplementation{
+case class Dependencies( dependencies: Seq[Dependency] )(implicit val logger: Logger, val transientCache: java.util.Map[AnyRef,AnyRef]) extends DependencyImplementation{
override def needsUpdate = dependencies.exists(_.needsUpdate)
override def exportedClasspath = ClassPath()
override def targetClasspath = ClassPath()
+ def moduleKey = this.getClass.getName ++ "(" ++ dependencies.map(_.moduleKey).mkString(", ") ++ ")"
}
-case class Stage1Dependency(cbtHasChanged: Boolean, mavenCache: File, nailgunTarget: File, stage1Target: File, compatibilityTarget: File)(implicit val logger: Logger) extends DependencyImplementation{
- override def needsUpdate = false
- override def targetClasspath = exportedClasspath
- override def exportedClasspath = ClassPath( Seq(nailgunTarget, stage1Target) )
- val compatibilityDependency = CompatibilityDependency(cbtHasChanged, compatibilityTarget)
- override def dependencies = Seq(
- compatibilityDependency
+class Stage1Dependency(cbtHasChanged: Boolean, mavenCache: File, nailgunTarget: File, stage1Target: File, compatibilityTarget: File)(implicit logger: Logger, transientCache: java.util.Map[AnyRef,AnyRef]) extends BinaryDependency(
+ Seq(nailgunTarget, stage1Target),
+ Seq(
+ new CompatibilityDependency(cbtHasChanged, compatibilityTarget)
) ++
MavenResolver(cbtHasChanged,mavenCache,mavenCentral).bind(
MavenDependency("org.scala-lang","scala-library",constants.scalaVersion),
MavenDependency("org.scala-lang.modules","scala-xml_"+constants.scalaMajorVersion,constants.scalaXmlVersion)
)
+){
+ val compatibilityDependency = new CompatibilityDependency(cbtHasChanged, compatibilityTarget)
+
}
-case class CompatibilityDependency(cbtHasChanged: Boolean, compatibilityTarget: File)(implicit val logger: Logger) extends DependencyImplementation{
- override def needsUpdate = false
- override def targetClasspath = exportedClasspath
- override def exportedClasspath = ClassPath( Seq(compatibilityTarget) )
- override def dependencies = Seq()
-}
-case class CbtDependency(cbtHasChanged: Boolean, mavenCache: File, nailgunTarget: File, stage1Target: File, stage2Target: File, compatibilityTarget: File)(implicit val logger: Logger) extends DependencyImplementation{
- override def needsUpdate = false
- override def targetClasspath = exportedClasspath
- override def exportedClasspath = ClassPath( Seq( stage2Target ) )
- val stage1Dependency = Stage1Dependency(cbtHasChanged, mavenCache, nailgunTarget, stage1Target, compatibilityTarget)
- override def dependencies = Seq(
- stage1Dependency
+
+class CompatibilityDependency(cbtHasChanged: Boolean, compatibilityTarget: File)(implicit logger: Logger, transientCache: java.util.Map[AnyRef,AnyRef]) extends BinaryDependency(
+ Seq(compatibilityTarget), Nil
+)
+
+class CbtDependency(cbtHasChanged: Boolean, mavenCache: File, nailgunTarget: File, stage1Target: File, stage2Target: File, compatibilityTarget: File)(implicit logger: Logger, transientCache: java.util.Map[AnyRef,AnyRef]) extends BinaryDependency(
+ Seq( stage2Target ),
+ Seq(
+ new Stage1Dependency(cbtHasChanged, mavenCache, nailgunTarget, stage1Target, compatibilityTarget)
) ++
MavenResolver(cbtHasChanged, mavenCache,mavenCentral).bind(
MavenDependency("net.incongru.watchservice","barbary-watchservice","1.0"),
MavenDependency("org.eclipse.jgit", "org.eclipse.jgit", "4.2.0.201601211800-r")
)
+){
+ val stage1Dependency = new Stage1Dependency(cbtHasChanged, mavenCache, nailgunTarget, stage1Target, compatibilityTarget)
}
case class Classifier(name: Option[String])
@@ -185,7 +192,9 @@ abstract class DependenciesProxy{
}
class BoundMavenDependencies(
cbtHasChanged: Boolean, mavenCache: File, urls: Seq[URL], mavenDependencies: Seq[MavenDependency]
-)(implicit logger: Logger) extends Dependencies(
+)(
+ implicit logger: Logger, transientCache: java.util.Map[AnyRef,AnyRef]
+) extends Dependencies(
mavenDependencies.map( BoundMavenDependency(cbtHasChanged,mavenCache,_,urls) )
)
case class MavenDependency(
@@ -201,7 +210,10 @@ object MavenDependency{
// FIXME: take MavenResolver instead of mavenCache and repositories separately
case class BoundMavenDependency(
cbtHasChanged: Boolean, mavenCache: File, mavenDependency: MavenDependency, repositories: Seq[URL]
-)(implicit val logger: Logger) extends ArtifactInfo with DependencyImplementation{
+)(
+ implicit val logger: Logger, val transientCache: java.util.Map[AnyRef,AnyRef]
+) extends ArtifactInfo with DependencyImplementation{
+ def moduleKey = this.getClass.getName ++ "(" ++ mavenDependency.serialize ++ ")"
val MavenDependency( groupId, artifactId, version, classifier ) = mavenDependency
assert(
Option(groupId).collect{
@@ -251,17 +263,11 @@ case class BoundMavenDependency(
StandardCharsets.UTF_8
).mkString("\n").split(" ").head.trim
}
-
- private object jarSha1Cache extends Cache[String]
- def jarSha1: String = jarSha1Cache{ resolveHash("jar", true) }
-
- private object pomSha1Cache extends Cache[String]
- def pomSha1: String = pomSha1Cache{ resolveHash("pom", false) }
- private object jarCache extends Cache[File]
- def jar: File = jarCache{ resolve("jar", Some(jarSha1), true) }
- private object pomCache extends Cache[File]
- def pom: File = pomCache{ resolve("pom", Some(pomSha1), false) }
+ def jarSha1: String = taskCache[BoundMavenDependency]("jarSha1").memoize{ resolveHash("jar", true) }
+ def pomSha1: String = taskCache[BoundMavenDependency]("pomSha1").memoize{ resolveHash("pom", false) }
+ def jar: File = taskCache[BoundMavenDependency]("jar").memoize{ resolve("jar", Some(jarSha1), true) }
+ def pom: File = taskCache[BoundMavenDependency]("pom").memoize{ resolve("pom", Some(pomSha1), false) }
private def pomXml = XML.loadFile(pom.string)
// ========== pom traversal ==========
@@ -278,7 +284,7 @@ case class BoundMavenDependency(
(parent \ "version").text
),
repositories
- )(logger)
+ )
}.flatMap(_.transitivePom) :+ this
}
diff --git a/stage2/BasicBuild.scala b/stage2/BasicBuild.scala
index 8b4a3a5..2fd34c7 100644
--- a/stage2/BasicBuild.scala
+++ b/stage2/BasicBuild.scala
@@ -9,6 +9,8 @@ trait BaseBuild extends BuildInterface with DependencyImplementation with Trigge
// will create new instances given the context, which means operations in the
// overrides will happen multiple times and if they are not idempotent stuff likely breaks
def context: Context
+ def moduleKey: String = "BaseBuild("+projectDirectory.string+")"
+ implicit def transientCache: java.util.Map[AnyRef,AnyRef] = context.transientCache
// library available to builds
implicit protected final val logger: Logger = context.logger
@@ -59,7 +61,7 @@ trait BaseBuild extends BuildInterface with DependencyImplementation with Trigge
// FIXME: this should probably be removed
Resolver( mavenCentral ).bind(
"org.scala-lang" % "scala-library" % scalaVersion
- ) :+ BinaryDependency(localJars, Nil)
+ ) ++ ( if(localJars.nonEmpty) Seq( BinaryDependency(localJars, Nil) ) else Nil )
// ========== paths ==========
final private val defaultSourceDirectory = projectDirectory ++ "/src"
@@ -135,15 +137,13 @@ trait BaseBuild extends BuildInterface with DependencyImplementation with Trigge
"-unchecked"
)
- private object needsUpdateCache extends Cache[Boolean]
- def needsUpdate: Boolean = needsUpdateCache(
+ def needsUpdate: Boolean = taskCache[BaseBuild]("needsUpdate").memoize[java.lang.Boolean](
context.cbtHasChanged
|| lib.needsUpdate( sourceFiles, compileStatusFile )
|| transitiveDependencies.filterNot(_ == context.parentBuild).exists(_.needsUpdate)
)
- private object compileCache extends Cache[Option[File]]
- def compile: Option[File] = compileCache{
+ def compile: Option[File] = taskCache[BaseBuild]("compile").memoize{
lib.compile(
context.cbtHasChanged,
needsUpdate || context.parentBuild.map(_.needsUpdate).getOrElse(false),
@@ -153,7 +153,6 @@ trait BaseBuild extends BuildInterface with DependencyImplementation with Trigge
)
}
-
def mainClasses: Seq[Class[_]] = compile.toSeq.flatMap( lib.mainClasses( _, classLoader(classLoaderCache) ) )
def runClass: Option[String] = lib.runClass( mainClasses ).map( _.getName )
@@ -264,24 +263,6 @@ trait BaseBuild extends BuildInterface with DependencyImplementation with Trigge
def finalBuild: BuildInterface = this
override def show = this.getClass.getSimpleName ++ "(" ++ projectDirectory.string ++ ")"
- // TODO: allow people not provide the method name, maybe via macro
- // TODO: pull this out into lib
- /**
- caches given value in context keyed with given key and projectDirectory
- the context is fresh on every complete run of cbt
- */
- def cached[T <: AnyRef](name: String)(task: => T): T = {
- val cache = context.transientCache
- val key = (projectDirectory,name)
- if( cache.containsKey(key) ){
- cache.get(key).asInstanceOf[T]
- } else{
- val value = task
- cache.put( key, value )
- value
- }
- }
-
// a method that can be called only to trigger any side-effects
final def `void` = ()
}
diff --git a/stage2/BuildBuild.scala b/stage2/BuildBuild.scala
index cf515bb..1b05214 100644
--- a/stage2/BuildBuild.scala
+++ b/stage2/BuildBuild.scala
@@ -32,8 +32,7 @@ trait BuildBuildWithoutEssentials extends BaseBuild{
override def dependencies =
super.dependencies :+ context.cbtDependency
def managedBuildDirectory: java.io.File = lib.realpath( projectDirectory.parent )
- private object managedBuildCache extends Cache[BuildInterface]
- def managedBuild = managedBuildCache{
+ def managedBuild = taskCache[BuildBuildWithoutEssentials]("managedBuild").memoize{
val managedBuildFile = projectDirectory++"/build.scala"
logger.composition("Loading build at " ++ managedBuildDirectory.toString)
val build = (
diff --git a/stage2/BuildDependency.scala b/stage2/BuildDependency.scala
index 197a7a1..4b4fdc1 100644
--- a/stage2/BuildDependency.scala
+++ b/stage2/BuildDependency.scala
@@ -16,9 +16,12 @@ trait TriggerLoop extends DependencyImplementation{
}
/** You likely want to use the factory method in the BasicBuild class instead of this. */
final case class DirectoryDependency(context: Context) extends TriggerLoop{
+ override def toString = show
override def show = this.getClass.getSimpleName ++ "(" ++ context.projectDirectory.string ++ ")"
+ def moduleKey = this.getClass.getName ++ "("+context.projectDirectory.string+")"
lazy val logger = context.logger
override lazy val lib: Lib = new Lib(logger)
+ def transientCache = context.transientCache
private lazy val root = lib.loadRoot( context.copy(args=Seq()) )
lazy val build = root.finalBuild
def exportedClasspath = ClassPath()
diff --git a/stage2/GitDependency.scala b/stage2/GitDependency.scala
index 650fd09..e27eff9 100644
--- a/stage2/GitDependency.scala
+++ b/stage2/GitDependency.scala
@@ -15,15 +15,14 @@ case class GitDependency(
)(implicit val logger: Logger, classLoaderCache: ClassLoaderCache, context: Context ) extends DependencyImplementation{
import GitDependency._
override def lib = new Lib(logger)
-
+ def moduleKey = this.getClass.getName ++ "(" ++ url ++ subDirectory.map("/" ++ _).getOrElse("") ++ "#" ++ ref ++ ")"
+ def transientCache = context.transientCache
// TODO: add support for authentication via ssh and/or https
// See http://www.codeaffine.com/2014/12/09/jgit-authentication/
private val GitUrl( _, domain, path ) = url
private val credentialsFile = context.projectDirectory ++ "/git.login"
- private object checkoutCache extends Cache[File]
-
private def authenticate(_git: CloneCommand) =
if(!credentialsFile.exists){
_git
@@ -36,7 +35,7 @@ case class GitDependency(
_git.setCredentialsProvider( new UsernamePasswordCredentialsProvider(user, password) )
}
- def checkout: File = checkoutCache{
+ def checkout: File = taskCache[GitDependency]("checkout").memoize{
val checkoutDirectory = context.cache ++ s"/git/$domain/$path/$ref"
val _git = if(checkoutDirectory.exists){
logger.git(s"Found existing checkout of $url#$ref in $checkoutDirectory")
@@ -65,8 +64,7 @@ case class GitDependency(
assert( actualRef == ref, s"actual ref '$actualRef' does not match expected ref '$ref'")
checkoutDirectory
}
- private object dependencyCache extends Cache[DependencyImplementation]
- def dependency = dependencyCache{
+ def dependency = taskCache[GitDependency]("dependency").memoize{
DirectoryDependency(
context.copy(
projectDirectory = checkout ++ subDirectory.map("/" ++ _).getOrElse("")
diff --git a/stage2/Lib.scala b/stage2/Lib.scala
index 769cd97..c570ca3 100644
--- a/stage2/Lib.scala
+++ b/stage2/Lib.scala
@@ -86,7 +86,7 @@ final class Lib(logger: Logger) extends Stage1Lib(logger) with Scaffold{
compileArgs: Seq[String],
classLoaderCache: ClassLoaderCache,
mavenCache: File
- ): Option[File] = {
+ )(implicit transientCache: java.util.Map[AnyRef,AnyRef]): Option[File] = {
if(sourceFiles.isEmpty){
None
} else {
@@ -101,7 +101,7 @@ final class Lib(logger: Logger) extends Stage1Lib(logger) with Scaffold{
runMain(
"scala.tools.nsc.ScalaDoc",
args,
- ScalaDependencies(cbtHasChanged,mavenCache,scalaVersion)(logger).classLoader(classLoaderCache)
+ new ScalaDependencies(cbtHasChanged,mavenCache,scalaVersion).classLoader(classLoaderCache)
)
}
lib.jarFile(
diff --git a/stage2/PackageJars.scala b/stage2/PackageJars.scala
index ff89284..3ecceb2 100644
--- a/stage2/PackageJars.scala
+++ b/stage2/PackageJars.scala
@@ -10,18 +10,15 @@ trait PackageJars extends BaseBuild with ArtifactInfo{
Seq(() => jar, () => docJar, () => srcJar)
)( _() ).flatten
- private object cacheJarBasicBuild extends Cache[Option[File]]
- def jar: Option[File] = cacheJarBasicBuild{
+ def jar: Option[File] = taskCache[PackageJars]("jar").memoize{
compile.flatMap( lib.jar( artifactId, scalaMajorVersion, version, _, jarTarget ) )
}
- private object cacheSrcJarBasicBuild extends Cache[Option[File]]
- def srcJar: Option[File] = cacheSrcJarBasicBuild{
+ def srcJar: Option[File] = taskCache[PackageJars]("srcJar").memoize{
lib.srcJar( sourceFiles, artifactId, scalaMajorVersion, version, scalaTarget )
}
- private object cacheDocBasicBuild extends Cache[Option[File]]
- def docJar: Option[File] = cacheDocBasicBuild{
+ def docJar: Option[File] = taskCache[PackageJars]("docJar").memoize{
lib.docJar(
context.cbtHasChanged,
scalaVersion, sourceFiles, compileClasspath, docTarget,
diff --git a/stage2/Stage2.scala b/stage2/Stage2.scala
index ab7b4fe..2884ddb 100644
--- a/stage2/Stage2.scala
+++ b/stage2/Stage2.scala
@@ -24,7 +24,7 @@ object Stage2 extends Stage2Base{
}
val task = args.args.lift( taskIndex )
- val context: Context = ContextImplementation(
+ val context: Context = new ContextImplementation(
args.cwd,
args.cwd,
args.args.drop( taskIndex +1 ).toArray,
@@ -33,7 +33,7 @@ object Stage2 extends Stage2Base{
args.cbtHasChanged,
null,
args.persistentCache,
- new HashMap,
+ args.transientCache,
args.cache,
args.cbtHome,
args.cbtHome,
diff --git a/stage2/ToolsTasks.scala b/stage2/ToolsTasks.scala
index b92cb7a..839780a 100644
--- a/stage2/ToolsTasks.scala
+++ b/stage2/ToolsTasks.scala
@@ -15,6 +15,7 @@ class ToolsTasks(
import paths._
private def Resolver( urls: URL* ) = MavenResolver(cbtHasChanged,mavenCache,urls: _*)
implicit val logger: Logger = lib.logger
+ implicit val transientCache: java.util.Map[AnyRef,AnyRef] = new java.util.HashMap
def createMain: Unit = lib.createMain( cwd )
def createBuild: Unit = lib.createBuild( cwd )
def gui = NailgunLauncher.main(Array(
diff --git a/stage2/plugins/Dotty.scala b/stage2/plugins/Dotty.scala
index 8671fb6..fe949a3 100644
--- a/stage2/plugins/Dotty.scala
+++ b/stage2/plugins/Dotty.scala
@@ -14,8 +14,7 @@ trait Dotty extends BaseBuild{
context.classLoaderCache, dottyVersion = dottyVersion
)
- private object compileCache extends Cache[Option[File]]
- override def compile: Option[File] = compileCache{
+ override def compile: Option[File] = taskCache[Dotty]("compile").memoize{
dottyLib.compile(
needsUpdate || context.parentBuild.map(_.needsUpdate).getOrElse(false),
sourceFiles, compileTarget, compileStatusFile, compileClasspath,
@@ -41,7 +40,7 @@ class DottyLib(
mavenCache: File,
classLoaderCache: ClassLoaderCache,
dottyVersion: String
-){
+)(implicit transientCache: java.util.Map[AnyRef,AnyRef]){
val lib = new Lib(logger)
import lib._
diff --git a/test/test.scala b/test/test.scala
index ae6c301..332b61e 100644
--- a/test/test.scala
+++ b/test/test.scala
@@ -104,10 +104,11 @@ object Main{
val cache = cbtHome ++ "/cache"
val mavenCache = cache ++ "/maven"
val cbtHasChanged = true
- def Resolver(urls: URL*) = MavenResolver(cbtHasChanged, mavenCache, urls: _*)
+ implicit val transientCache: java.util.Map[AnyRef,AnyRef] = new java.util.HashMap
+ def Resolver(urls: URL*) = MavenResolver(cbtLastModified, mavenCache, urls: _*)
{
- val noContext = ContextImplementation(
+ val noContext = new ContextImplementation(
cbtHome ++ "/test/nothing",
cbtHome,
Array(),