aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan Christopher Vogt <oss.nsp@cvogt.org>2017-02-14 00:50:02 -0500
committerGitHub <noreply@github.com>2017-02-14 00:50:02 -0500
commit2a1bf81eccf6b91e0dcdd2d7a05664da2049f3a1 (patch)
tree1e31b9e979453000f53dae752b4a9787d70a151d
parente0fb6ec75286c695b7e4c5ed9189714d40f9b672 (diff)
parent69b3380ad301b50e540ef784c5ada1f3560dffab (diff)
downloadcbt-2a1bf81eccf6b91e0dcdd2d7a05664da2049f3a1.tar.gz
cbt-2a1bf81eccf6b91e0dcdd2d7a05664da2049f3a1.tar.bz2
cbt-2a1bf81eccf6b91e0dcdd2d7a05664da2049f3a1.zip
Merge pull request #345 from cvogt/chris4
Chris4
-rw-r--r--compatibility/Context.java6
-rw-r--r--examples/multi-combined-example/build/build.scala8
-rw-r--r--libraries/eval/build/build.scala2
-rw-r--r--plugins/scalajs/ScalaJsBuild.scala6
-rw-r--r--plugins/scalajs/ScalaJsLib.scala7
-rw-r--r--plugins/scalatest/ScalaTest.scala17
-rw-r--r--stage1/ContextImplementation.scala4
-rw-r--r--stage1/MavenRepository.scala2
-rw-r--r--stage1/Stage1.scala45
-rw-r--r--stage1/Stage1Lib.scala48
-rw-r--r--stage1/cbt.scala10
-rw-r--r--stage1/resolver.scala70
-rw-r--r--stage2/BasicBuild.scala70
-rw-r--r--stage2/BuildBuild.scala6
-rw-r--r--stage2/BuildDependency.scala5
-rw-r--r--stage2/GitDependency.scala5
-rw-r--r--stage2/Lib.scala13
-rw-r--r--stage2/PackageJars.scala2
-rw-r--r--stage2/ToolsStage2.scala2
-rw-r--r--stage2/ToolsTasks.scala9
-rw-r--r--stage2/plugins/Dotty.scala75
-rw-r--r--stage2/plugins/Frege.scala9
-rw-r--r--test/test.scala1
23 files changed, 230 insertions, 192 deletions
diff --git a/compatibility/Context.java b/compatibility/Context.java
index afd0b15..389d401 100644
--- a/compatibility/Context.java
+++ b/compatibility/Context.java
@@ -18,9 +18,11 @@ public interface Context{
public default long start(){
throw new IncompatibleCbtVersionException("You need to define method start.");
};
+ public default File workingDirectory(){
+ return projectDirectory();
+ };
// methods that exist for longer which every CBT version in use should have by now, no default values needed
- public abstract File projectDirectory();
public abstract File cwd(); // REPLACE by something that allows to run cbt on some other directly
public abstract String[] argsArray(); // replace this by https://github.com/cvogt/cbt/issues/172 ?
public abstract String[] enabledLoggersArray();
@@ -40,4 +42,6 @@ public interface Context{
public abstract ConcurrentHashMap<String,Object> permanentKeys();
@java.lang.Deprecated
public abstract ConcurrentHashMap<Object,ClassLoader> permanentClassLoaders();
+ @java.lang.Deprecated
+ public abstract File projectDirectory();
}
diff --git a/examples/multi-combined-example/build/build.scala b/examples/multi-combined-example/build/build.scala
index 41c03d6..7d1ff9f 100644
--- a/examples/multi-combined-example/build/build.scala
+++ b/examples/multi-combined-example/build/build.scala
@@ -10,7 +10,7 @@ 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"
+ workingDirectory = projectDirectory ++ "/../shared"
)
))
}
@@ -24,19 +24,19 @@ class Build(val context: Context) extends BaseBuild{
*/
def sub1 = new Sub(
context.copy(
- projectDirectory = projectDirectory ++ "/sub1"
+ workingDirectory = projectDirectory ++ "/sub1"
)
)
def sub2 = new Sub(
context.copy(
- projectDirectory = projectDirectory ++ "/sub2"
+ workingDirectory = 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"
+ workingDirectory = Build.this.projectDirectory ++ "/sub3"
)
}
diff --git a/libraries/eval/build/build.scala b/libraries/eval/build/build.scala
index 7135d3f..a869ace 100644
--- a/libraries/eval/build/build.scala
+++ b/libraries/eval/build/build.scala
@@ -5,7 +5,7 @@ class Build(val context: Context) extends BaseBuild{
new ScalaCompilerDependency( context.cbtLastModified, context.paths.mavenCache, scalaVersion )
override def test: Option[ExitCode] = Some{
- new BasicBuild(context.copy(projectDirectory = projectDirectory ++ "/test")) with ScalaTest{
+ new BasicBuild(context.copy(workingDirectory = projectDirectory ++ "/test")) with ScalaTest{
override def dependencies = super.dependencies ++ Seq(
DirectoryDependency(projectDirectory++"/..")
)
diff --git a/plugins/scalajs/ScalaJsBuild.scala b/plugins/scalajs/ScalaJsBuild.scala
index 99f8616..1694aea 100644
--- a/plugins/scalajs/ScalaJsBuild.scala
+++ b/plugins/scalajs/ScalaJsBuild.scala
@@ -4,11 +4,7 @@ import java.net.URL
trait ScalaJsBuild extends BaseBuild {
final protected val scalaJsLib = ScalaJsLib(
- scalaJsVersion,
- scalaVersion,
- context.cbtLastModified,
- context.classLoaderCache,
- context.paths.mavenCache
+ scalaJsVersion, scalaVersion, context.cbtLastModified, context.paths.mavenCache
)
import scalaJsLib.{link => _,_}
diff --git a/plugins/scalajs/ScalaJsLib.scala b/plugins/scalajs/ScalaJsLib.scala
index f500039..393ebfe 100644
--- a/plugins/scalajs/ScalaJsLib.scala
+++ b/plugins/scalajs/ScalaJsLib.scala
@@ -2,9 +2,8 @@ package cbt
import java.io.File
case class ScalaJsLib(
- scalaJsVersion: String, scalaVersion: String,
- cbtLastModified: Long, classLoaderCache: ClassLoaderCache, mavenCache: File
-)(implicit logger: Logger, transientCache: java.util.Map[AnyRef,AnyRef]){
+ scalaJsVersion: String, scalaVersion: String, cbtLastModified: Long, mavenCache: File
+)(implicit logger: Logger, transientCache: java.util.Map[AnyRef,AnyRef], classLoaderCache: ClassLoaderCache){
sealed trait ScalaJsOutputMode {
def option: String
def fileSuffix: String
@@ -36,7 +35,7 @@ case class ScalaJsLib(
"--stdlib", s"${scalaJsLibraryDependency.jar.getAbsolutePath}",
"--output", outputPath.string
) ++ scalaJsOptions ++ entriesToLink.map(_.getAbsolutePath),
- scalaJsCliDep.classLoader(classLoaderCache)
+ scalaJsCliDep.classLoader
)
}
diff --git a/plugins/scalatest/ScalaTest.scala b/plugins/scalatest/ScalaTest.scala
index 56405aa..7f805fd 100644
--- a/plugins/scalatest/ScalaTest.scala
+++ b/plugins/scalatest/ScalaTest.scala
@@ -5,9 +5,8 @@ import org.scalatest._
trait ScalaTest extends BaseBuild{
override def run: ExitCode = {
import ScalaTestLib._
- val _classLoader = classLoader(context.classLoaderCache)
- val suiteNames = exportedClasspath.files.map( d => discoverSuites(d, _classLoader) ).flatten
- runSuites( suiteNames.map( loadSuite( _, _classLoader ) ) )
+ val suiteNames = exportedClasspath.files.map( d => discoverSuites(d, classLoader) ).flatten
+ runSuites( suiteNames.map( loadSuite( _, classLoader ) ) )
ExitCode.Success
}
override def dependencies = super.dependencies ++ Resolver( mavenCentral ).bind( ScalaDependency("org.scalatest","scalatest","2.2.4") )
@@ -28,16 +27,16 @@ object ScalaTestLib{
}
}
- def discoverSuites(discoveryPath: File, _classLoader: ClassLoader): Seq[String] = {
- _classLoader
+ def discoverSuites(discoveryPath: File, classLoader: ClassLoader): Seq[String] = {
+ classLoader
.loadClass("org.scalatest.tools.SuiteDiscoveryHelper")
.getMethod("discoverSuiteNames", classOf[List[_]], classOf[ClassLoader], classOf[Option[_]])
- .invoke(null, List(discoveryPath.string ++ "/"), _classLoader, None)
+ .invoke(null, List(discoveryPath.string ++ "/"), classLoader, None)
.asInstanceOf[Set[String]]
.to
}
- def loadSuite(name: String, _classLoader: ClassLoader) = {
- _classLoader.loadClass(name).getConstructor().newInstance().asInstanceOf[Suite]
- }
+ def loadSuite(name: String, classLoader: ClassLoader) = {
+ classLoader.loadClass(name).getConstructor().newInstance().asInstanceOf[Suite]
+ }
}
diff --git a/stage1/ContextImplementation.scala b/stage1/ContextImplementation.scala
index 69094b0..b263ef4 100644
--- a/stage1/ContextImplementation.scala
+++ b/stage1/ContextImplementation.scala
@@ -2,7 +2,7 @@ package cbt
import java.io._
class ContextImplementation(
- override val projectDirectory: File,
+ override val workingDirectory: File,
override val cwd: File,
override val argsArray: Array[String],
override val enabledLoggersArray: Array[String],
@@ -17,6 +17,8 @@ class ContextImplementation(
override val compatibilityTarget: File,
override val parentBuildOrNull: BuildInterface
) extends Context{
+ @deprecated("this method is replaced by workingDirectory","")
+ def projectDirectory = workingDirectory
@deprecated("this method is replaced by cbtLastModified","")
def cbtHasChangedCompat = true
@deprecated("this method is replaced by start","")
diff --git a/stage1/MavenRepository.scala b/stage1/MavenRepository.scala
index a8c9b51..6be537b 100644
--- a/stage1/MavenRepository.scala
+++ b/stage1/MavenRepository.scala
@@ -4,7 +4,7 @@ import java.net._
case class MavenResolver(
cbtLastModified: Long, mavenCache: File, urls: URL*
)(
- implicit logger: Logger, transientCache: java.util.Map[AnyRef,AnyRef]
+ implicit logger: Logger, transientCache: java.util.Map[AnyRef,AnyRef], classLoaderCache: ClassLoaderCache
){
def bind( dependencies: MavenDependency* ): Seq[BoundMavenDependency]
= dependencies.map( BoundMavenDependency(cbtLastModified,mavenCache,_,urls.to) ).to
diff --git a/stage1/Stage1.scala b/stage1/Stage1.scala
index bf6a3d4..60f0ad9 100644
--- a/stage1/Stage1.scala
+++ b/stage1/Stage1.scala
@@ -36,17 +36,16 @@ abstract class Stage2Base{
def run( context: Stage2Args ): ExitCode
}
-case class Stage2Args(
- cwd: File,
- args: Seq[String],
- stage2LastModified: Long,
- logger: Logger,
- classLoaderCache: ClassLoaderCache,
- cache: File,
- cbtHome: File,
- compatibilityTarget: File
+class Stage2Args(
+ val cwd: File,
+ val args: Seq[String],
+ val stage2LastModified: Long,
+ val logger: Logger,
+ val cache: File,
+ val cbtHome: File,
+ val compatibilityTarget: File
)(
- implicit val transientCache: java.util.Map[AnyRef,AnyRef]
+ implicit val transientCache: java.util.Map[AnyRef,AnyRef], val classLoaderCache: ClassLoaderCache
){
val persistentCache = classLoaderCache.hashMap
}
@@ -61,11 +60,10 @@ object Stage1{
val logger = new Logger( context.enabledLoggers, buildStage1.start )
val (cbtLastModified, classLoader) = buildStage2(
buildStage1,
- new ClassLoaderCache( context.persistentCache ),
context.cbtHome,
context.cache,
logger
- )(context.transientCache)
+ )(context.transientCache, new ClassLoaderCache( context.persistentCache ))
classLoader
.loadClass("cbt.Stage2")
@@ -79,8 +77,8 @@ object Stage1{
}
def buildStage2(
- buildStage1: BuildStage1Result, classLoaderCache: ClassLoaderCache, cbtHome: File, cache: File, logger: Logger
- )(implicit transientCache: java.util.Map[AnyRef,AnyRef]): (Long, ClassLoader) = {
+ buildStage1: BuildStage1Result, cbtHome: File, cache: File, logger: Logger
+ )(implicit transientCache: java.util.Map[AnyRef,AnyRef], classLoaderCache: ClassLoaderCache): (Long, ClassLoader) = {
import buildStage1._
@@ -106,9 +104,9 @@ object Stage1{
stage2sourceFiles, stage2Target, stage2StatusFile,
cbtDependencies.stage2Dependency.dependencies,
mavenCache,
- Seq("-deprecation","-feature","-unchecked"), classLoaderCache,
+ Seq("-deprecation","-feature","-unchecked"),
zincVersion = constants.zincVersion, scalaVersion = constants.scalaVersion
- )(transientCache)
+ )
logger.stage1(s"calling CbtDependency.classLoader")
@@ -129,19 +127,19 @@ object Stage1{
"cbt unchanged, expected stage1 classloader to be cached"
)
- val stage2ClassLoader = cbtDependencies.stage2Dependency.classLoader(classLoaderCache)
+ val stage2ClassLoader = cbtDependencies.stage2Dependency.classLoader
{
// a few classloader sanity checks
val compatibilityClassLoader =
- cbtDependencies.compatibilityDependency.classLoader(classLoaderCache)
+ cbtDependencies.compatibilityDependency.classLoader
assert(
classOf[BuildInterface].getClassLoader == compatibilityClassLoader,
classOf[BuildInterface].getClassLoader.toString ++ "\n\nis not the same as\n\n" ++ compatibilityClassLoader.toString
)
//-------------
val stage1ClassLoader =
- cbtDependencies.stage1Dependency.classLoader(classLoaderCache)
+ cbtDependencies.stage1Dependency.classLoader
assert(
classOf[Stage1ArgsParser].getClassLoader == stage1ClassLoader,
classOf[Stage1ArgsParser].getClassLoader.toString ++ "\n\nis not the same as\n\n" ++ stage1ClassLoader.toString
@@ -165,20 +163,19 @@ object Stage1{
): Int = {
val args = Stage1ArgsParser(_args.toVector)
val logger = new Logger(args.enabledLoggers, buildStage1.start)
- implicit val transientCache: java.util.Map[AnyRef,AnyRef] = new java.util.HashMap
logger.stage1(s"Stage1 start")
- val classLoaderCache = new ClassLoaderCache( persistentCache )
+ implicit val transientCache: java.util.Map[AnyRef,AnyRef] = new java.util.HashMap
+ implicit val classLoaderCache = new ClassLoaderCache( persistentCache )
- val (stage2LastModified, classLoader) = buildStage2( buildStage1, classLoaderCache, cbtHome, cache, logger )
+ val (stage2LastModified, classLoader) = buildStage2( buildStage1, cbtHome, cache, logger )
- val stage2Args = Stage2Args(
+ val stage2Args = new Stage2Args(
new File( args.args(0) ),
args.args.drop(1).dropWhile(_ == "direct").toVector,
// launcher changes cause entire nailgun restart, so no need for them here
stage2LastModified = stage2LastModified,
logger = logger,
- classLoaderCache = classLoaderCache,
cache,
cbtHome,
new File(buildStage1.compatibilityClasspath)
diff --git a/stage1/Stage1Lib.scala b/stage1/Stage1Lib.scala
index 5a2f05d..505b298 100644
--- a/stage1/Stage1Lib.scala
+++ b/stage1/Stage1Lib.scala
@@ -156,14 +156,19 @@ class Stage1Lib( logger: Logger ) extends BaseLib{
.collect{
// no $ to avoid inner classes
case path if !path.contains("$") && path.endsWith(".class") =>
- classLoader.loadClass(
- path
- .stripSuffix(".class")
- .stripPrefix(targetDirectory.getPath)
- .stripPrefix(File.separator) // 1 for the slash
- .replace(File.separator, ".")
- )
- }.filter(
+ try{
+ classLoader.loadClass(
+ path
+ .stripSuffix(".class")
+ .stripPrefix(targetDirectory.getPath)
+ .stripPrefix(File.separator) // 1 for the slash
+ .replace(File.separator, ".")
+ )
+ } catch {
+ case e: ClassNotFoundException => null
+ case e: NoClassDefFoundError => null
+ }
+ }.filterNot(_ == null).filter(
_.getDeclaredMethods().exists( m =>
m.getName == "main"
&& m.getParameterTypes.toList == List(arrayClass)
@@ -192,11 +197,10 @@ class Stage1Lib( logger: Logger ) extends BaseLib{
dependencies: Seq[Dependency],
mavenCache: File,
scalacOptions: Seq[String] = Seq(),
- classLoaderCache: ClassLoaderCache,
zincVersion: String,
scalaVersion: String
)(
- implicit transientCache: java.util.Map[AnyRef, AnyRef]
+ implicit transientCache: java.util.Map[AnyRef, AnyRef], classLoaderCache: ClassLoaderCache
): Option[Long] = {
val d = Dependencies(dependencies)
val classpath = d.classpath
@@ -259,7 +263,7 @@ class Stage1Lib( logger: Logger ) extends BaseLib{
dualArgs ++ singleArgs ++ (
if(cp.isEmpty) Nil else Seq("-cp", cp)
) ++ sourceFiles.map(_.toString),
- zinc.classLoader(classLoaderCache)
+ zinc.classLoader
)
} catch {
case scala.util.control.NonFatal(e) =>
@@ -409,33 +413,33 @@ ${sourceFiles.sorted.mkString(" \\\n")}
def actual(current: Dependency, latest: Map[(String,String),Dependency]) = current match {
- case d: ArtifactInfo => latest((d.groupId,d.artifactId))
+ case d: ArtifactInfo =>
+ val key = (d.groupId,d.artifactId)
+ latest.get(key).getOrElse(
+ throw new Exception( s"This should never happend. Could not find $key in \n"++latest.map{case (k,v) => k+" -> "+v}.mkString("\n") )
+ )
case d => d
}
- def classLoaderRecursion( dependency: Dependency, latest: Map[(String,String),Dependency], cache: ClassLoaderCache)(implicit transientCache: java.util.Map[AnyRef,AnyRef] ): ClassLoader = {
+ def classLoaderRecursion( dependency: Dependency, latest: Map[(String,String),Dependency])(implicit transientCache: java.util.Map[AnyRef,AnyRef], cache: ClassLoaderCache): ClassLoader = {
// FIXME: shouldn't we be using KeyLockedLazyCache instead of hashmap directly here?
val dependencies = dependency.dependencies
val dependencyClassLoader: ClassLoader = {
if( dependency.dependencies.isEmpty ){
NailgunLauncher.jdkClassLoader
} else if( dependencies.size == 1 ){
- classLoaderRecursion( dependencies.head, latest, cache )
+ classLoaderRecursion( dependencies.head, latest )
} else{
val lastModified = dependencies.map( _.lastModified ).max
val cp = dependency.dependencyClasspath.string
val cl =
new MultiClassLoader(
- dependencies.map( classLoaderRecursion(_, latest, cache) )
+ dependencies.map( classLoaderRecursion(_, latest) )
)
- if(dependency.isInstanceOf[BuildInterface])
- cl // Don't cache builds right now. We need to fix invalidation first.
- else{
- if( !cache.containsKey( cp, lastModified ) ){
- cache.put( cp, cl, lastModified )
- }
- cache.get( cp, lastModified )
+ if( !cache.containsKey( cp, lastModified ) ){
+ cache.put( cp, cl, lastModified )
}
+ cache.get( cp, lastModified )
}
}
diff --git a/stage1/cbt.scala b/stage1/cbt.scala
index a1776b1..f88ef16 100644
--- a/stage1/cbt.scala
+++ b/stage1/cbt.scala
@@ -52,10 +52,10 @@ object `package`{
}
implicit class DependencyExtensions(subject: Dependency){
import subject._
- def dependencyClasspath(implicit logger: Logger, transientCache: java.util.Map[AnyRef,AnyRef]): ClassPath
+ def dependencyClasspath(implicit logger: Logger, transientCache: java.util.Map[AnyRef,AnyRef], classLoaderCache: ClassLoaderCache): ClassPath
= Dependencies(dependenciesArray.to).classpath
def exportedClasspath: ClassPath = ClassPath(exportedClasspathArray.to)
- def classpath(implicit logger: Logger, transientCache: java.util.Map[AnyRef,AnyRef]) = exportedClasspath ++ dependencyClasspath
+ def classpath(implicit logger: Logger, transientCache: java.util.Map[AnyRef,AnyRef], classLoaderCache: ClassLoaderCache) = exportedClasspath ++ dependencyClasspath
def dependencies: Seq[Dependency] = dependenciesArray.to
}
implicit class ContextExtensions(subject: Context){
@@ -66,7 +66,7 @@ object `package`{
def classLoaderCache: ClassLoaderCache = new ClassLoaderCache( persistentCache )
def cbtDependencies = {
import paths._
- new CbtDependencies(mavenCache, nailgunTarget, stage1Target, stage2Target, compatibilityTarget)(logger, transientCache)
+ new CbtDependencies(mavenCache, nailgunTarget, stage1Target, stage2Target, compatibilityTarget)(logger, transientCache, classLoaderCache)
}
val cbtDependency = cbtDependencies.stage2Dependency
@@ -77,7 +77,7 @@ object `package`{
def cbtLastModified: scala.Long = subject.cbtLastModified
def copy(
- projectDirectory: File = projectDirectory,
+ workingDirectory: File = workingDirectory,
args: Seq[String] = args,
//enabledLoggers: Set[String] = enabledLoggers,
cbtLastModified: Long = cbtLastModified,
@@ -85,7 +85,7 @@ object `package`{
cbtHome: File = cbtHome,
parentBuild: Option[BuildInterface] = None
): Context = new ContextImplementation(
- projectDirectory,
+ workingDirectory,
cwd,
args.to,
enabledLoggers.to,
diff --git a/stage1/resolver.scala b/stage1/resolver.scala
index 97cd36a..e02f931 100644
--- a/stage1/resolver.scala
+++ b/stage1/resolver.scala
@@ -9,6 +9,7 @@ trait DependencyImplementation extends Dependency{
implicit protected def logger: Logger
protected def lib = new Stage1Lib(logger)
implicit protected def transientCache: java.util.Map[AnyRef,AnyRef]
+ implicit protected def classLoaderCache: ClassLoaderCache
/** key used by taskCache to identify different objects that represent the same logical module */
protected def moduleKey: String
@@ -78,23 +79,42 @@ trait DependencyImplementation extends Dependency{
}
*/
- def classLoader( cache: ClassLoaderCache ): ClassLoader = {
- /*
- if( concurrencyEnabled ){
- // trigger concurrent building / downloading dependencies
- exportClasspathConcurrently
+ def runMain( className: String, args: String* ) = lib.runMain( className, args, classLoader )
+
+ def flatClassLoader: Boolean = false
+
+ def mainClasses: Seq[Class[_]] = exportedClasspath.files.flatMap( lib.mainClasses( _, classLoader ) )
+
+ def runClass: Option[String] = lib.runClass( mainClasses ).map( _.getName )
+
+ def run( args: String* ): ExitCode = {
+ runClass.map( runMain( _, args: _* ) ).getOrElse{
+ logger.task( "No main class found for " ++ show )
+ ExitCode.Success
}
- */
- lib.classLoaderRecursion(
- this,
- (this +: transitiveDependencies).collect{
- case d: ArtifactInfo => d
- }.groupBy(
- d => (d.groupId,d.artifactId)
- ).mapValues(_.head),
- cache // FIXME
- )
}
+
+ def classLoader: ClassLoader = {
+ if( flatClassLoader ){
+ new java.net.URLClassLoader(classpath.strings.map(f => new URL("file://" ++ f)).toArray)
+ } else {
+ /*
+ if( concurrencyEnabled ){
+ // trigger concurrent building / downloading dependencies
+ exportClasspathConcurrently
+ }
+ */
+ lib.classLoaderRecursion(
+ this,
+ (this +: transitiveDependencies).collect{
+ case d: ArtifactInfo => d
+ }.groupBy(
+ d => (d.groupId,d.artifactId)
+ ).mapValues(_.head)
+ )
+ }
+ }
+
// FIXME: these probably need to update outdated as well
def classpath : ClassPath = exportedClasspath ++ dependencyClasspath
def dependencyClasspath : ClassPath = ClassPath(
@@ -116,11 +136,11 @@ trait DependencyImplementation extends Dependency{
}
// TODO: all this hard codes the scala version, needs more flexibility
-class ScalaCompilerDependency(cbtLastModified: Long, mavenCache: File, version: String)(implicit logger: Logger, transientCache: java.util.Map[AnyRef,AnyRef]) extends BoundMavenDependency(cbtLastModified, mavenCache, MavenDependency("org.scala-lang","scala-compiler",version, Classifier.none), Seq(mavenCentral))
-class ScalaLibraryDependency (cbtLastModified: Long, mavenCache: File, version: String)(implicit logger: Logger, transientCache: java.util.Map[AnyRef,AnyRef]) extends BoundMavenDependency(cbtLastModified, mavenCache, MavenDependency("org.scala-lang","scala-library",version, Classifier.none), Seq(mavenCentral))
-class ScalaReflectDependency (cbtLastModified: Long, mavenCache: File, version: String)(implicit logger: Logger, transientCache: java.util.Map[AnyRef,AnyRef]) extends BoundMavenDependency(cbtLastModified, mavenCache, MavenDependency("org.scala-lang","scala-reflect",version, Classifier.none), Seq(mavenCentral))
+class ScalaCompilerDependency(cbtLastModified: Long, mavenCache: File, version: String)(implicit logger: Logger, transientCache: java.util.Map[AnyRef,AnyRef], classLoaderCache: ClassLoaderCache) extends BoundMavenDependency(cbtLastModified, mavenCache, MavenDependency("org.scala-lang","scala-compiler",version, Classifier.none), Seq(mavenCentral))
+class ScalaLibraryDependency (cbtLastModified: Long, mavenCache: File, version: String)(implicit logger: Logger, transientCache: java.util.Map[AnyRef,AnyRef], classLoaderCache: ClassLoaderCache) extends BoundMavenDependency(cbtLastModified, mavenCache, MavenDependency("org.scala-lang","scala-library",version, Classifier.none), Seq(mavenCentral))
+class ScalaReflectDependency (cbtLastModified: Long, mavenCache: File, version: String)(implicit logger: Logger, transientCache: java.util.Map[AnyRef,AnyRef], classLoaderCache: ClassLoaderCache) extends BoundMavenDependency(cbtLastModified, mavenCache, MavenDependency("org.scala-lang","scala-reflect",version, Classifier.none), Seq(mavenCentral))
-class ScalaDependencies(cbtLastModified: Long, mavenCache: File, version: String)(implicit logger: Logger, transientCache: java.util.Map[AnyRef,AnyRef]) extends Dependencies(
+class ScalaDependencies(cbtLastModified: Long, mavenCache: File, version: String)(implicit logger: Logger, transientCache: java.util.Map[AnyRef,AnyRef], classLoaderCache: ClassLoaderCache) extends Dependencies(
Seq(
new ScalaCompilerDependency(cbtLastModified, mavenCache, version),
new ScalaLibraryDependency(cbtLastModified, mavenCache, version),
@@ -128,7 +148,7 @@ class ScalaDependencies(cbtLastModified: Long, mavenCache: File, version: String
)
)
-case class BinaryDependency( paths: Seq[File], dependencies: Seq[Dependency] )(implicit val logger: Logger, val transientCache: java.util.Map[AnyRef,AnyRef]) extends DependencyImplementation{
+case class BinaryDependency( paths: Seq[File], dependencies: Seq[Dependency] )(implicit val logger: Logger, val transientCache: java.util.Map[AnyRef,AnyRef], val classLoaderCache: ClassLoaderCache) extends DependencyImplementation{
assert(paths.nonEmpty)
def exportedClasspath = ClassPath(paths)
override def lastModified = paths.map(_.lastModified).maxOption.getOrElse(0) // FIXME: cache this
@@ -137,7 +157,7 @@ case class BinaryDependency( paths: Seq[File], dependencies: Seq[Dependency] )(i
}
/** Allows to easily assemble a bunch of dependencies */
-case class Dependencies( dependencies: Seq[Dependency] )(implicit val logger: Logger, val transientCache: java.util.Map[AnyRef,AnyRef]) extends DependencyImplementation{
+case class Dependencies( dependencies: Seq[Dependency] )(implicit val logger: Logger, val transientCache: java.util.Map[AnyRef,AnyRef], val classLoaderCache: ClassLoaderCache) extends DependencyImplementation{
override def lastModified = dependencies.map(_.lastModified).maxOption.getOrElse(0)
def moduleKey = this.getClass.getName ++ "(" ++ dependencies.map(_.moduleKey).mkString(", ") ++ ")"
def targetClasspath = ClassPath()
@@ -145,14 +165,14 @@ case class Dependencies( dependencies: Seq[Dependency] )(implicit val logger: Lo
override def show: String = this.getClass.getSimpleName + "( " + dependencies.map(_.show).mkString(", ") + " )"
}
-case class PostBuildDependency(target: File, _dependencies: Seq[DependencyImplementation])(implicit val logger: Logger, val transientCache: java.util.Map[AnyRef,AnyRef]) extends DependencyImplementation{
+case class PostBuildDependency(target: File, _dependencies: Seq[DependencyImplementation])(implicit val logger: Logger, val transientCache: java.util.Map[AnyRef,AnyRef], val classLoaderCache: ClassLoaderCache) extends DependencyImplementation{
override final lazy val lastModified = (target++".last-success").lastModified
def moduleKey = target.string
override def targetClasspath = exportedClasspath
override def exportedClasspath = ClassPath( Seq(target) )
override def dependencies = _dependencies
}
-case class CbtDependencies(mavenCache: File, nailgunTarget: File, stage1Target: File, stage2Target: File, compatibilityTarget: File)(implicit logger: Logger, val transientCache: java.util.Map[AnyRef,AnyRef]){
+case class CbtDependencies(mavenCache: File, nailgunTarget: File, stage1Target: File, stage2Target: File, compatibilityTarget: File)(implicit logger: Logger, transientCache: java.util.Map[AnyRef,AnyRef], classLoaderCache: ClassLoaderCache){
val compatibilityDependency = PostBuildDependency(compatibilityTarget, Nil)
val cbtLastModified = (stage2Target++".last-success").lastModified
val stage1Dependency = PostBuildDependency(
@@ -188,7 +208,7 @@ abstract class DependenciesProxy{
class BoundMavenDependencies(
cbtLastModified: Long, mavenCache: File, urls: Seq[URL], mavenDependencies: Seq[MavenDependency]
)(
- implicit logger: Logger, transientCache: java.util.Map[AnyRef,AnyRef]
+ implicit logger: Logger, transientCache: java.util.Map[AnyRef,AnyRef], classLoaderCache: ClassLoaderCache
) extends Dependencies(
mavenDependencies.map( BoundMavenDependency(cbtLastModified,mavenCache,_,urls) )
)
@@ -206,7 +226,7 @@ object MavenDependency{
case class BoundMavenDependency(
cbtLastModified: Long, mavenCache: File, mavenDependency: MavenDependency, repositories: Seq[URL]
)(
- implicit val logger: Logger, val transientCache: java.util.Map[AnyRef,AnyRef]
+ implicit val logger: Logger, val transientCache: java.util.Map[AnyRef,AnyRef], val classLoaderCache: ClassLoaderCache
) extends ArtifactInfo with DependencyImplementation{
def moduleKey = this.getClass.getName ++ "(" ++ mavenDependency.serialize ++ ")"
val MavenDependency( groupId, artifactId, version, classifier ) = mavenDependency
diff --git a/stage2/BasicBuild.scala b/stage2/BasicBuild.scala
index b7b0854..e5b3507 100644
--- a/stage2/BasicBuild.scala
+++ b/stage2/BasicBuild.scala
@@ -9,7 +9,7 @@ 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+")"
+ def moduleKey: String = "BaseBuild("+target.string+")"
implicit def transientCache: java.util.Map[AnyRef,AnyRef] = context.transientCache
// library available to builds
@@ -21,7 +21,7 @@ trait BaseBuild extends BuildInterface with DependencyImplementation with Trigge
// ========== general stuff ==========
def enableConcurrency = false
- final def projectDirectory: File = lib.realpath(context.projectDirectory)
+ def projectDirectory: File = lib.realpath(context.workingDirectory)
assert( projectDirectory.exists, "projectDirectory does not exist: " ++ projectDirectory.string )
assert(
projectDirectory.getName =!= "build" ||
@@ -107,7 +107,7 @@ trait BaseBuild extends BuildInterface with DependencyImplementation with Trigge
) = lib.ScalaDependency( groupId, artifactId, version, classifier, scalaVersion )
final def DirectoryDependency(path: File) = cbt.DirectoryDependency(
- context.copy( projectDirectory = path, args = Seq() )
+ context.copy( workingDirectory = path, args = Seq() )
)
def triggerLoopFiles: Seq[File] = sources ++ transitiveDependencies.collect{ case b: TriggerLoop => b.triggerLoopFiles }.flatten
@@ -125,9 +125,9 @@ trait BaseBuild extends BuildInterface with DependencyImplementation with Trigge
def resourceClasspath: ClassPath = {
val resourcesDirectory = projectDirectory ++ "/resources"
- ClassPath( if(resourcesDirectory.exists) Seq(resourcesDirectory) else Nil )
+ ClassPath(Seq(resourcesDirectory).filter(_.exists))
}
- def exportedClasspath : ClassPath = {
+ def exportedClasspath: ClassPath = {
compile
ClassPath(Seq(compileTarget).filter(_.exists)) ++ resourceClasspath
}
@@ -147,39 +147,11 @@ trait BaseBuild extends BuildInterface with DependencyImplementation with Trigge
lib.compile(
context.cbtLastModified,
sourceFiles, compileTarget, compileStatusFile, compileDependencies,
- context.paths.mavenCache, scalacOptions, context.classLoaderCache,
+ context.paths.mavenCache, scalacOptions,
zincVersion = zincVersion, scalaVersion = scalaVersion
)
}
- def mainClasses: Seq[Class[_]] = exportedClasspath.files.flatMap( lib.mainClasses( _, classLoader(classLoaderCache) ) )
-
- def runClass: Option[String] = lib.runClass( mainClasses ).map( _.getName )
-
- def runMain( className: String, args: String* ) = lib.runMain( className, args, classLoader(context.classLoaderCache) )
-
- def flatClassLoader: Boolean = false
-
- def run: ExitCode = {
- if(flatClassLoader){
- runClass.map(
- lib.runMain(
- _,
- context.args,
- new java.net.URLClassLoader(classpath.strings.map(f => new URL("file://" ++ f)).toArray)
- )
- ).getOrElse{
- logger.task( "No main class found for " ++ projectDirectory.string )
- ExitCode.Success
- }
- } else {
- runClass.map( runMain( _, context.args: _* ) ).getOrElse{
- logger.task( "No main class found for " ++ projectDirectory.string )
- ExitCode.Success
- }
- }
- }
-
def clean: ExitCode = {
lib.clean(
target,
@@ -200,22 +172,24 @@ trait BaseBuild extends BuildInterface with DependencyImplementation with Trigge
}
val scalac = new ScalaCompilerDependency(context.cbtLastModified, context.paths.mavenCache, scalaVersion)
- lib.runMain(
+ runMain(
"scala.tools.nsc.MainGenericRunner",
Seq(
"-bootclasspath",
scalac.classpath.string,
"-classpath",
classpath.string
- ) ++ context.args,
- scalac.classLoader(classLoaderCache)
+ ) ++ context.args : _*
)
}
- def test: Option[ExitCode] =
+ def run: ExitCode = run( context.args: _* )
+
+ def test: Any =
Some(new lib.ReflectBuild(
DirectoryDependency(projectDirectory++"/test").build
).callNullary(Some("run")))
+
def t = test
def rt = recursiveUnsafe(Some("test"))
@@ -257,7 +231,7 @@ trait BaseBuild extends BuildInterface with DependencyImplementation with Trigge
ExitCode.Success
} catch {
case e: Throwable => println(e.getClass); throw e
- }
+ }
}
ExitCode.Success
}
@@ -284,6 +258,24 @@ trait BaseBuild extends BuildInterface with DependencyImplementation with Trigge
// a method that can be called only to trigger any side-effects
final def `void` = ()
+ final override def transitiveDependencies: Seq[Dependency] =
+ taskCache[BaseBuild]( "transitiveDependencies" ).memoize{
+ val res = super.transitiveDependencies
+ val duplicateBuilds = res.collect{
+ case b: BaseBuild => b
+ }.groupBy(
+ b => ( b.projectDirectory, b.moduleKey )
+ ).filter( _._2.size > 1 ).mapValues(_.map(_.getClass))
+ duplicateBuilds.foreach{ case ((projectDirectory, moduleKey), classes) =>
+ assert(
+ classes.distinct.size == 1,
+ "multiple builds found for\nprojectDirectory: $projectDirectory\nmoduleKey: $moduleKey\nbut different classes: " + classes.mkString(", ")
+ )
+ }
+ res
+ }
+
+
@deprecated("use the MultipleScalaVersions plugin instead","")
final def crossScalaVersionsArray = Array(scalaVersion)
}
diff --git a/stage2/BuildBuild.scala b/stage2/BuildBuild.scala
index 1b05214..474599a 100644
--- a/stage2/BuildBuild.scala
+++ b/stage2/BuildBuild.scala
@@ -12,7 +12,7 @@ trait BuildBuildWithoutEssentials extends BaseBuild{
)
protected final val managedContext = context.copy(
- projectDirectory = managedBuildDirectory,
+ workingDirectory = managedBuildDirectory,
parentBuild=Some(this)
)
@@ -57,14 +57,14 @@ trait BuildBuildWithoutEssentials extends BaseBuild{
// Launcher in the checkout with itself and then run it via reflection.
val dep = new GitDependency(base, hash, Some("nailgun_launcher"))
val ctx = managedContext.copy( cbtHome = dep.checkout )
- dep.classLoader(classLoaderCache)
+ dep.classLoader
.loadClass( "cbt.NailgunLauncher" )
.getMethod( "getBuild", classOf[AnyRef] )
.invoke( null, ctx )
}
}.getOrElse{
try{
- classLoader(context.classLoaderCache)
+ classLoader
.loadClass(lib.buildClassName)
.getConstructors.head
.newInstance(managedContext)
diff --git a/stage2/BuildDependency.scala b/stage2/BuildDependency.scala
index 236f958..56069c3 100644
--- a/stage2/BuildDependency.scala
+++ b/stage2/BuildDependency.scala
@@ -16,9 +16,10 @@ 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{
+ def classLoaderCache = context.classLoaderCache
override def toString = show
- override def show = this.getClass.getSimpleName ++ "(" ++ context.projectDirectory.string ++ ")"
- def moduleKey = this.getClass.getName ++ "("+context.projectDirectory.string+")"
+ override def show = this.getClass.getSimpleName ++ "(" ++ context.workingDirectory.string ++ ")"
+ def moduleKey = this.getClass.getName ++ "("+context.workingDirectory.string+")"
lazy val logger = context.logger
override lazy val lib: Lib = new Lib(logger)
def transientCache = context.transientCache
diff --git a/stage2/GitDependency.scala b/stage2/GitDependency.scala
index 059d650..ecd0ee1 100644
--- a/stage2/GitDependency.scala
+++ b/stage2/GitDependency.scala
@@ -15,13 +15,14 @@ case class GitDependency(
)(implicit val logger: Logger, classLoaderCache: ClassLoaderCache, context: Context ) extends DependencyImplementation{
import GitDependency._
override def lib = new Lib(logger)
+ def classLoaderCache = context.classLoaderCache
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 val credentialsFile = context.workingDirectory ++ "/git.login"
private def authenticate(_git: CloneCommand) =
if(!credentialsFile.exists){
@@ -67,7 +68,7 @@ case class GitDependency(
def dependency = taskCache[GitDependency]("dependency").memoize{
DirectoryDependency(
context.copy(
- projectDirectory = checkout ++ subDirectory.map("/" ++ _).getOrElse("")
+ workingDirectory = checkout ++ subDirectory.map("/" ++ _).getOrElse("")
)
)
}
diff --git a/stage2/Lib.scala b/stage2/Lib.scala
index fcf2642..2642ec9 100644
--- a/stage2/Lib.scala
+++ b/stage2/Lib.scala
@@ -31,7 +31,7 @@ final class Lib(val logger: Logger) extends Stage1Lib(logger) with Scaffold{
if(buildDir.exists) findStartDir(buildDir) else directory
}
- val directory = context.projectDirectory
+ val directory = context.workingDirectory
context.logger.composition( context.logger.showInvocation("Build.loadRoot",directory) )
@@ -41,7 +41,7 @@ final class Lib(val logger: Logger) extends Stage1Lib(logger) with Scaffold{
try{
if(useBasicBuild) {
- new BasicBuild( context.copy( projectDirectory = directory) )
+ 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
@@ -50,9 +50,9 @@ final class Lib(val logger: Logger) extends Stage1Lib(logger) with Scaffold{
|| directory == (context.cbtHome ++ "/libraries/eval")
|| directory == (context.cbtHome ++ "/plugins/scalatest")
)
- new cbt.BasicBuild( context.copy( projectDirectory = start ) ) with BuildBuildWithoutEssentials
+ new cbt.BasicBuild( context.copy( workingDirectory = start ) ) with BuildBuildWithoutEssentials
else
- new cbt.BasicBuild( context.copy( projectDirectory = start ) ) with BuildBuild
+ new cbt.BasicBuild( context.copy( workingDirectory = start ) ) with BuildBuild
} catch {
case e:ClassNotFoundException if e.getMessage == "Build" =>
throw new Exception(s"no class Build found in " ++ start.string)
@@ -84,9 +84,8 @@ final class Lib(val logger: Logger) extends Stage1Lib(logger) with Scaffold{
scalaMajorVersion: String,
version: String,
compileArgs: Seq[String],
- classLoaderCache: ClassLoaderCache,
mavenCache: File
- )(implicit transientCache: java.util.Map[AnyRef,AnyRef]): Option[File] = {
+ )(implicit transientCache: java.util.Map[AnyRef,AnyRef], classLoaderCache: ClassLoaderCache): Option[File] = {
if(sourceFiles.isEmpty){
None
} else {
@@ -101,7 +100,7 @@ final class Lib(val logger: Logger) extends Stage1Lib(logger) with Scaffold{
runMain(
"scala.tools.nsc.ScalaDoc",
args,
- new ScalaDependencies(cbtLastModified,mavenCache,scalaVersion).classLoader(classLoaderCache)
+ new ScalaDependencies(cbtLastModified,mavenCache,scalaVersion).classLoader
)
}
lib.jarFile(
diff --git a/stage2/PackageJars.scala b/stage2/PackageJars.scala
index fddbfc6..8ba1798 100644
--- a/stage2/PackageJars.scala
+++ b/stage2/PackageJars.scala
@@ -23,7 +23,7 @@ trait PackageJars extends BaseBuild with ArtifactInfo{
context.cbtLastModified,
scalaVersion, sourceFiles, compileClasspath, docTarget,
jarTarget, artifactId, scalaMajorVersion, version,
- scalacOptions, context.classLoaderCache, context.paths.mavenCache
+ scalacOptions, context.paths.mavenCache
)
}
}
diff --git a/stage2/ToolsStage2.scala b/stage2/ToolsStage2.scala
index 2899173..e1c4a8e 100644
--- a/stage2/ToolsStage2.scala
+++ b/stage2/ToolsStage2.scala
@@ -4,7 +4,7 @@ object ToolsStage2 extends Stage2Base{
def run( _args: Stage2Args ): ExitCode = {
val args = _args.args.dropWhile(Seq("tools","direct") contains _)
val lib = new Lib(_args.logger)
- val toolsTasks = new ToolsTasks(lib, args, _args.cwd, _args.classLoaderCache, _args.cache, _args.cbtHome, _args.stage2LastModified)
+ val toolsTasks = new ToolsTasks(lib, args, _args.cwd, _args.cache, _args.cbtHome, _args.stage2LastModified)(_args.classLoaderCache)
new lib.ReflectObject(toolsTasks){
def usage: String = "Available methods: " ++ lib.taskNames(toolsTasks.getClass).mkString(" ")
}.callNullary(args.lift(0))
diff --git a/stage2/ToolsTasks.scala b/stage2/ToolsTasks.scala
index 6acf72c..25156fb 100644
--- a/stage2/ToolsTasks.scala
+++ b/stage2/ToolsTasks.scala
@@ -6,16 +6,15 @@ class ToolsTasks(
lib: Lib,
args: Seq[String],
cwd: File,
- classLoaderCache: ClassLoaderCache,
cache: File,
cbtHome: File,
cbtLastModified: Long
-){
+)(implicit classLoaderCache: ClassLoaderCache){
private val paths = CbtPaths(cbtHome, cache)
import paths._
- private def Resolver( urls: URL* ) = MavenResolver(cbtLastModified,mavenCache,urls: _*)
implicit val logger: Logger = lib.logger
implicit val transientCache: java.util.Map[AnyRef,AnyRef] = new java.util.HashMap
+ private def Resolver( urls: URL* ) = MavenResolver(cbtLastModified,mavenCache,urls: _*)
def createMain: Unit = lib.createMain( cwd )
def createBuild: Unit = lib.createBuild( cwd )
def gui = NailgunLauncher.main(Array(
@@ -48,7 +47,7 @@ class ToolsTasks(
MavenDependency(
"com.lihaoyi","ammonite-repl_2.11.8",args.lift(1).getOrElse("0.5.8")
)
- ).classLoader(classLoaderCache)
+ ).classLoader
// FIXME: this does not work quite yet, throws NoSuchFileException: /ammonite/repl/frontend/ReplBridge$.class
lib.runMain(
"ammonite.repl.Main", args.drop(2), classLoader
@@ -59,7 +58,7 @@ class ToolsTasks(
val scalac = new ScalaCompilerDependency( cbtLastModified, mavenCache, version )
val _args = Seq("-cp", scalac.classpath.string) ++ args.drop(2)
lib.runMain(
- "scala.tools.nsc.MainGenericRunner", _args, scalac.classLoader(classLoaderCache)
+ "scala.tools.nsc.MainGenericRunner", _args, scalac.classLoader
)
}
def cbtEarlyDependencies = {
diff --git a/stage2/plugins/Dotty.scala b/stage2/plugins/Dotty.scala
index 8a49257..9de2218 100644
--- a/stage2/plugins/Dotty.scala
+++ b/stage2/plugins/Dotty.scala
@@ -9,21 +9,45 @@ trait Dotty extends BaseBuild{
def dottyOptions: Seq[String] = Seq()
override def scalaTarget: File = target ++ s"/dotty-$dottyVersion"
- def dottyDependency: DependencyImplementation =
- Resolver(mavenCentral).bindOne(
- MavenDependency(Dotty.groupId,Dotty.artifactId,Dotty.version)
- )
+ def dottyCompiler: DependencyImplementation = Resolver(mavenCentral).bindOne( Dotty.compilerOnMaven( dottyVersion ) )
+ def dottyLibrary: DependencyImplementation = Resolver(mavenCentral).bindOne( Dotty.libraryOnMaven( dottyVersion ) )
+ // this seems needed for cbt run of dotty produced artifacts
+ override def dependencies: Seq[Dependency] = Seq( dottyLibrary )
private lazy val dottyLib = new DottyLib(
- logger, context.cbtLastModified, context.paths.mavenCache,
- context.classLoaderCache, dottyDependency
+ logger, context.cbtLastModified, context.paths.mavenCache, dottyCompiler
)
+ def compileJavaFirst: Boolean = false
+
+ // this makes sure the scala or java classes compiled first are available on subsequent compile
+ override def compileDependencies: Seq[Dependency]
+ = super.compileDependencies ++ Seq( compileTarget ).filter(_.exists).map( t => BinaryDependency( Seq(t), Nil ) )
+
override def compile: Option[Long] = taskCache[Dotty]("compile").memoize{
- dottyLib.compile(
- sourceFiles, compileTarget, compileStatusFile, compileDependencies, dottyOptions
- )
+ def compileDotty =
+ dottyLib.compile(
+ sourceFiles.filter(_.string.endsWith(".scala")),
+ compileTarget, compileStatusFile, compileDependencies, dottyOptions
+ )
+ def compileJava =
+ lib.compile(
+ context.cbtLastModified,
+ sourceFiles.filter(_.string.endsWith(".java")),
+ compileTarget, compileStatusFile, compileDependencies, context.paths.mavenCache,
+ scalacOptions, zincVersion = zincVersion, scalaVersion = scalaVersion
+ )
+
+ def set(time: Long) = if(compileStatusFile.exists) Files.setLastModifiedTime(compileStatusFile.toPath, FileTime.fromMillis(time) )
+
+ val before = compileStatusFile.lastModified
+ val firstLastModified = if(compileJavaFirst) compileJava else compileDotty
+ set( before )
+ val secondLastModified = if(!compileJavaFirst) compileJava else compileDotty
+ val min = (firstLastModified ++ secondLastModified).reduceOption(_ min _).getOrElse(0l)
+ set( min )
+ Some(min)
}
def doc: ExitCode =
@@ -32,24 +56,24 @@ trait Dotty extends BaseBuild{
)
override def repl = dottyLib.repl(context.args, classpath)
-
- // this seems needed for cbt run of dotty produced artifacts
- override def dependencies: Seq[Dependency] = Seq( dottyDependency )
}
object Dotty{
- val version: String = "0.1.1-20170203-da7d723-NIGHTLY"
val groupId = "ch.epfl.lamp"
- val artifactId = "dotty_2.11"
+ val version: String = "0.1.1-20170203-da7d723-NIGHTLY"
+ val libraryArtifactId = "dotty-library_2.11"
+ val compilerArtifactId = "dotty-compiler_2.11"
+ val interfacesArtifactId = "dotty-interfaces"
+ def compilerOnMaven(version: String) = MavenDependency(groupId,compilerArtifactId,version)
+ def libraryOnMaven(version: String) = MavenDependency(groupId,libraryArtifactId,version)
}
class DottyLib(
logger: Logger,
cbtLastModified: Long,
mavenCache: File,
- classLoaderCache: ClassLoaderCache,
- dependency: DependencyImplementation
-)(implicit transientCache: java.util.Map[AnyRef,AnyRef]){
+ dottyCompiler: DependencyImplementation
+)(implicit transientCache: java.util.Map[AnyRef,AnyRef], classLoaderCache: ClassLoaderCache){
val lib = new Lib(logger)
import lib._
@@ -59,11 +83,11 @@ class DottyLib(
"dotty.tools.dotc.repl.Main",
Seq(
"-bootclasspath",
- dependency.classpath.string,
+ dottyCompiler.classpath.string,
"-classpath",
classpath.string
) ++ args,
- dependency.classLoader(classLoaderCache)
+ dottyCompiler.classLoader
)
}
@@ -79,7 +103,7 @@ class DottyLib(
docTarget.mkdirs
val args = Seq(
// FIXME: can we use compiler dependency here?
- "-bootclasspath", dependency.classpath.string, // FIXME: does this break for builds that don't have scalac dependencies?
+ "-bootclasspath", dottyCompiler.classpath.string, // FIXME: does this break for builds that don't have scalac dependencies?
"-classpath", dependencyClasspath.string, // FIXME: does this break for builds that don't have scalac dependencies?
"-d", docTarget.toString
) ++ compileArgs ++ sourceFiles.map(_.toString)
@@ -88,7 +112,7 @@ class DottyLib(
runMain(
"dotty.tools.dottydoc.DocDriver",
args,
- dependency.classLoader(classLoaderCache),
+ dottyCompiler.classLoader,
fakeInstance = true // this is a hack as Dottydoc's main method is not static
)
}
@@ -121,7 +145,8 @@ class DottyLib(
"-d", compileTarget.toString
)
val singleArgs = dottyOptions.map( "-S" ++ _ )
- val cl = dependency.classLoader(classLoaderCache)
+ val urls = dottyCompiler.classpath.strings.map("file://"+_).map(new java.net.URL(_))
+ val cl = new java.net.URLClassLoader( urls.to )
val code =
try{
System.err.println("Compiling with Dotty to " ++ compileTarget.toString)
@@ -130,7 +155,7 @@ class DottyLib(
lib.runMain(
_class,
dualArgs ++ singleArgs ++ Seq(
- "-bootclasspath", dependency.classpath.string
+ "-bootclasspath", dottyCompiler.classpath.string
) ++ (
if(cp.isEmpty) Nil else Seq("-classpath", cp) // let's put cp last. It so long
) ++ sourceFiles.map(_.toString),
@@ -143,7 +168,7 @@ class DottyLib(
System.err.println(cl)
System.out.println(s"""
java -cp \\
-${dependency.classpath.strings.mkString(":\\\n")} \\
+${dottyCompiler.classpath.strings.mkString(":\\\n")} \\
\\
${_class} \\
\\
@@ -152,7 +177,7 @@ ${dualArgs.grouped(2).map(_.mkString(" ")).mkString(" \\\n")} \\
${singleArgs.mkString(" \\\n")} \\
\\
-bootclasspath \\
-${dependency.classpath.strings.mkString(":\\\n")} \\
+${dottyCompiler.classpath.strings.mkString(":\\\n")} \\
${if(cp.isEmpty) "" else (" -classpath \\\n" ++ classpath.strings.mkString(":\\\n"))} \\
\\
${sourceFiles.sorted.mkString(" \\\n")}
diff --git a/stage2/plugins/Frege.scala b/stage2/plugins/Frege.scala
index b5a4dd0..ae82f6b 100644
--- a/stage2/plugins/Frege.scala
+++ b/stage2/plugins/Frege.scala
@@ -21,7 +21,7 @@ trait Frege extends BaseBuild{
private lazy val fregeLib = new FregeLib(
logger, context.cbtLastModified, context.paths.mavenCache,
- context.classLoaderCache, fregeVersion = fregeVersion, classifier = classifier,
+ fregeVersion = fregeVersion, classifier = classifier,
fregeDependencies = fregeDependencies, fregeTarget = fregeTarget
)
@@ -43,12 +43,11 @@ class FregeLib(
logger: Logger,
cbtLastModified: Long,
mavenCache: File,
- classLoaderCache: ClassLoaderCache,
fregeVersion: String,
classifier: Option[String],
fregeDependencies: Seq[Dependency],
fregeTarget: String
-)(implicit transientCache: java.util.Map[AnyRef,AnyRef]){
+)(implicit transientCache: java.util.Map[AnyRef,AnyRef], classLoaderCache: ClassLoaderCache){
val lib = new Lib(logger)
import lib._
@@ -63,7 +62,7 @@ class FregeLib(
statusFile: File,
dependencies: Seq[Dependency],
fregeOptions: Seq[String]
- ): Option[Long] = {
+ )(implicit classLoaderCache: ClassLoaderCache): Option[Long] = {
val d = Dependencies(dependencies)
val classpath = d.classpath
val cp = classpath.string
@@ -93,7 +92,7 @@ class FregeLib(
lib.runMain(
_class,
dualArgs ++ singleArgs ++ sourceFiles.map(_.toString),
- fregeDependency.classLoader(classLoaderCache)
+ fregeDependency.classLoader
)
}
} catch {
diff --git a/test/test.scala b/test/test.scala
index ca9d87b..7247e6b 100644
--- a/test/test.scala
+++ b/test/test.scala
@@ -105,6 +105,7 @@ object Main{
val mavenCache = cache ++ "/maven"
val cbtLastModified = System.currentTimeMillis
implicit val transientCache: java.util.Map[AnyRef,AnyRef] = new java.util.HashMap
+ implicit val classLoaderCache: ClassLoaderCache = new ClassLoaderCache( new java.util.HashMap )
def Resolver(urls: URL*) = MavenResolver(cbtLastModified, mavenCache, urls: _*)
{