diff options
author | Jan Christopher Vogt <oss.nsp@cvogt.org> | 2017-02-14 00:50:02 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-02-14 00:50:02 -0500 |
commit | 2a1bf81eccf6b91e0dcdd2d7a05664da2049f3a1 (patch) | |
tree | 1e31b9e979453000f53dae752b4a9787d70a151d | |
parent | e0fb6ec75286c695b7e4c5ed9189714d40f9b672 (diff) | |
parent | 69b3380ad301b50e540ef784c5ada1f3560dffab (diff) | |
download | cbt-2a1bf81eccf6b91e0dcdd2d7a05664da2049f3a1.tar.gz cbt-2a1bf81eccf6b91e0dcdd2d7a05664da2049f3a1.tar.bz2 cbt-2a1bf81eccf6b91e0dcdd2d7a05664da2049f3a1.zip |
Merge pull request #345 from cvogt/chris4
Chris4
-rw-r--r-- | compatibility/Context.java | 6 | ||||
-rw-r--r-- | examples/multi-combined-example/build/build.scala | 8 | ||||
-rw-r--r-- | libraries/eval/build/build.scala | 2 | ||||
-rw-r--r-- | plugins/scalajs/ScalaJsBuild.scala | 6 | ||||
-rw-r--r-- | plugins/scalajs/ScalaJsLib.scala | 7 | ||||
-rw-r--r-- | plugins/scalatest/ScalaTest.scala | 17 | ||||
-rw-r--r-- | stage1/ContextImplementation.scala | 4 | ||||
-rw-r--r-- | stage1/MavenRepository.scala | 2 | ||||
-rw-r--r-- | stage1/Stage1.scala | 45 | ||||
-rw-r--r-- | stage1/Stage1Lib.scala | 48 | ||||
-rw-r--r-- | stage1/cbt.scala | 10 | ||||
-rw-r--r-- | stage1/resolver.scala | 70 | ||||
-rw-r--r-- | stage2/BasicBuild.scala | 70 | ||||
-rw-r--r-- | stage2/BuildBuild.scala | 6 | ||||
-rw-r--r-- | stage2/BuildDependency.scala | 5 | ||||
-rw-r--r-- | stage2/GitDependency.scala | 5 | ||||
-rw-r--r-- | stage2/Lib.scala | 13 | ||||
-rw-r--r-- | stage2/PackageJars.scala | 2 | ||||
-rw-r--r-- | stage2/ToolsStage2.scala | 2 | ||||
-rw-r--r-- | stage2/ToolsTasks.scala | 9 | ||||
-rw-r--r-- | stage2/plugins/Dotty.scala | 75 | ||||
-rw-r--r-- | stage2/plugins/Frege.scala | 9 | ||||
-rw-r--r-- | test/test.scala | 1 |
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: _*) { |