From 88bb1ef7d1a85422ef7f41956715db4cc4ee2639 Mon Sep 17 00:00:00 2001 From: Martin Duhem Date: Fri, 19 Jan 2018 16:02:55 +0100 Subject: [PATCH] Extract classpath options in maven and sbt --- backend/src/main/scala/bloop/Compiler.scala | 7 +++--- .../src/main/scala/bloop/CompilerCache.scala | 11 ++++---- frontend/src/main/scala/bloop/Project.scala | 10 ++++++++ .../main/scala/bloop/engine/tasks/Tasks.scala | 9 +++++-- .../src/test/scala/bloop/engine/DagSpec.scala | 5 +++- .../bloop/tasks/IntegrationTestSuite.scala | 3 +++ .../scala/bloop/tasks/ProjectHelpers.scala | 3 +++ .../bloop/integrations/BloopConfig.scala | 10 ++++++++ .../bloop/integrations/maven/BloopMojo.java | 25 +++++++++++++++++++ .../maven/MojoImplementation.scala | 6 +++-- .../bloop/integrations/sbt/SbtBloop.scala | 10 +++++--- 11 files changed, 83 insertions(+), 16 deletions(-) diff --git a/backend/src/main/scala/bloop/Compiler.scala b/backend/src/main/scala/bloop/Compiler.scala index 1347fe53d4..19b0ca97b4 100644 --- a/backend/src/main/scala/bloop/Compiler.scala +++ b/backend/src/main/scala/bloop/Compiler.scala @@ -11,6 +11,7 @@ import sbt.internal.inc.{FreshCompilerCache, Locate, LoggedReporter, ZincUtil} case class CompileInputs( scalaInstance: ScalaInstance, + classpathOptions: ClasspathOptions, compilerCache: CompilerCache, sourceDirectories: Array[AbsolutePath], classpath: Array[AbsolutePath], @@ -44,8 +45,7 @@ object Compiler { .flatMap(src => Paths.getAll(src, "glob:**.{scala,java}")) .distinct val classesDir = inputs.classesDir.toFile - // TODO(jvican): Figure out why `inputs.scalaInstance.allJars` is required here. - val classpath = inputs.classpath.map(_.toFile) ++ inputs.scalaInstance.allJars + val classpath = inputs.classpath.map(_.toFile) CompileOptions .create() @@ -69,7 +69,8 @@ object Compiler { } val scalaInstance = compileInputs.scalaInstance - val compilers = compileInputs.compilerCache.get(scalaInstance) + val classpathOptions = compileInputs.classpathOptions + val compilers = compileInputs.compilerCache.get((scalaInstance, classpathOptions)) val inputs = getInputs(compilers) val incrementalCompiler = ZincUtil.defaultIncrementalCompiler val compilation = incrementalCompiler.compile(inputs, compileInputs.logger) diff --git a/backend/src/main/scala/bloop/CompilerCache.scala b/backend/src/main/scala/bloop/CompilerCache.scala index ce47391537..c2d1b01cc9 100644 --- a/backend/src/main/scala/bloop/CompilerCache.scala +++ b/backend/src/main/scala/bloop/CompilerCache.scala @@ -15,13 +15,14 @@ class CompilerCache(componentProvider: ComponentProvider, logger: Logger, userResolvers: List[Resolver]) { - private val cache = new ConcurrentHashMap[ScalaInstance, Compilers]() + private type CompilerID = (ScalaInstance, ClasspathOptions) + private val cache = new ConcurrentHashMap[CompilerID, Compilers]() - def get(scalaInstance: ScalaInstance): Compilers = - cache.computeIfAbsent(scalaInstance, newCompilers) + def get(compilerID: CompilerID): Compilers = + cache.computeIfAbsent(compilerID, newCompilers) - private def newCompilers(scalaInstance: ScalaInstance): Compilers = { - val classpathOptions = ClasspathOptions.of(true, false, false, true, false) + private def newCompilers(compilerID: CompilerID): Compilers = { + val (scalaInstance, classpathOptions) = compilerID val compiler = getScalaCompiler(scalaInstance, classpathOptions, componentProvider) ZincUtil.compilers(scalaInstance, classpathOptions, None, compiler) } diff --git a/frontend/src/main/scala/bloop/Project.scala b/frontend/src/main/scala/bloop/Project.scala index aef6c7f904..34d93c3398 100644 --- a/frontend/src/main/scala/bloop/Project.scala +++ b/frontend/src/main/scala/bloop/Project.scala @@ -9,11 +9,14 @@ import bloop.io.{AbsolutePath, Paths} import bloop.io.Timer.timed import bloop.logging.Logger +import xsbti.compile.ClasspathOptions + case class Project(name: String, baseDirectory: AbsolutePath, dependencies: Array[String], scalaInstance: ScalaInstance, rawClasspath: Array[AbsolutePath], + classpathOptions: ClasspathOptions, classesDir: AbsolutePath, scalacOptions: Array[String], javacOptions: Array[String], @@ -86,6 +89,12 @@ object Project { ScalaInstance(scalaOrganization, scalaName, scalaVersion, allScalaJars, logger) val classpath = toPaths(properties.getProperty("classpath")) val classesDir = toPath(properties.getProperty("classesDir")) + val classpathOptions = { + val values = properties.getProperty("classpathOptions").split(",") + val Array(bootLibrary, compiler, extra, autoBoot, filterLibrary) = + values.map(java.lang.Boolean.parseBoolean) + ClasspathOptions.of(bootLibrary, compiler, extra, autoBoot, filterLibrary) + } val scalacOptions = properties.getProperty("scalacOptions").split(";").filterNot(_.isEmpty) val javacOptions = @@ -108,6 +117,7 @@ object Project { dependencies, scalaInstance, classpath, + classpathOptions, classesDir, scalacOptions, javacOptions, diff --git a/frontend/src/main/scala/bloop/engine/tasks/Tasks.scala b/frontend/src/main/scala/bloop/engine/tasks/Tasks.scala index b96dc2461d..c0075f3266 100644 --- a/frontend/src/main/scala/bloop/engine/tasks/Tasks.scala +++ b/frontend/src/main/scala/bloop/engine/tasks/Tasks.scala @@ -45,6 +45,7 @@ object Tasks { val instance = project.scalaInstance val sourceDirs = project.sourceDirectories val classpath = project.classpath + val classpathOptions = project.classpathOptions val classesDir = project.classesDir val target = project.tmp val scalacOptions = project.scalacOptions @@ -52,7 +53,7 @@ object Tasks { val cwd = state.build.origin.getParent val reporter = new Reporter(logger, cwd, identity, config) // FORMAT: OFF - CompileInputs(instance, compilerCache, sourceDirs, classpath, classesDir, target, scalacOptions, javacOptions, result, reporter, logger) + CompileInputs(instance, classpathOptions, compilerCache, sourceDirs, classpath, classesDir, target, scalacOptions, javacOptions, result, reporter, logger) // FORMAT: ON } @@ -135,10 +136,14 @@ object Tasks { def console(state: State, project: Project, config: ReporterConfig, noRoot: Boolean): State = { def runConsole(state: State, project: Project, classpath: Array[AbsolutePath]): Unit = { val scalaInstance = project.scalaInstance + val classpathOptions = project.classpathOptions val classpathFiles = classpath.map(_.underlying.toFile).toSeq state.logger.debug(s"Setting up the console classpath with ${classpathFiles.mkString(", ")}") val loader = ClasspathUtilities.makeLoader(classpathFiles, scalaInstance) - val compiler = state.compilerCache.get(scalaInstance).scalac.asInstanceOf[AnalyzingCompiler] + val compiler = state.compilerCache + .get((scalaInstance, classpathOptions)) + .scalac + .asInstanceOf[AnalyzingCompiler] val ctxLoader = Thread.currentThread().getContextClassLoader() compiler.console(classpathFiles, project.scalacOptions, "", "", state.logger)(Some(loader)) } diff --git a/frontend/src/test/scala/bloop/engine/DagSpec.scala b/frontend/src/test/scala/bloop/engine/DagSpec.scala index ac5a52c328..3baf21e012 100644 --- a/frontend/src/test/scala/bloop/engine/DagSpec.scala +++ b/frontend/src/test/scala/bloop/engine/DagSpec.scala @@ -8,17 +8,20 @@ import bloop.logging.RecordingLogger import bloop.Project import guru.nidi.graphviz.parse.Parser +import xsbti.compile.ClasspathOptionsUtil + @Category(Array(classOf[bloop.FastTests])) class DagSpec { private object TestProjects { private val logger = new RecordingLogger + private val classpathOptions = ClasspathOptionsUtil.boot() private val dummyInstance = bloop.ScalaInstance("bla", "ble", "bli", Array(), logger) private val dummyPath = bloop.io.AbsolutePath("/tmp/non-existing") private val javaEnv = JavaEnv.default(fork = false) // format: OFF def dummyProject(name: String, dependencies: List[String]): Project = - Project(name, dummyPath, dependencies.toArray, dummyInstance, Array(), dummyPath, Array(), + Project(name, dummyPath, dependencies.toArray, dummyInstance, Array(), classpathOptions, dummyPath, Array(), Array(), Array(), Array(), javaEnv, dummyPath, dummyPath) // format: ON diff --git a/frontend/src/test/scala/bloop/tasks/IntegrationTestSuite.scala b/frontend/src/test/scala/bloop/tasks/IntegrationTestSuite.scala index be158c5bf1..52b6b87ed4 100644 --- a/frontend/src/test/scala/bloop/tasks/IntegrationTestSuite.scala +++ b/frontend/src/test/scala/bloop/tasks/IntegrationTestSuite.scala @@ -16,6 +16,8 @@ import bloop.exec.JavaEnv import bloop.Project import bloop.io.AbsolutePath +import xsbti.compile.ClasspathOptionsUtil + object IntegrationTestSuite { val projects = ProjectHelpers.testProjectsIndex.map(_._2).toArray.map(Array.apply(_)) @@ -55,6 +57,7 @@ class IntegrationTestSuite(testDirectory: Path) { dependencies = previousProjects.map(_.name).toArray, scalaInstance = previousProjects.head.scalaInstance, rawClasspath = Array.empty, + classpathOptions = ClasspathOptionsUtil.boot(), classesDir = classesDir, scalacOptions = Array.empty, javacOptions = Array.empty, diff --git a/frontend/src/test/scala/bloop/tasks/ProjectHelpers.scala b/frontend/src/test/scala/bloop/tasks/ProjectHelpers.scala index 2b4f53f972..075eb08b7c 100644 --- a/frontend/src/test/scala/bloop/tasks/ProjectHelpers.scala +++ b/frontend/src/test/scala/bloop/tasks/ProjectHelpers.scala @@ -13,6 +13,8 @@ import bloop.io.AbsolutePath import bloop.internal.build.BuildInfo import bloop.logging.{BloopLogger, ProcessLogger, RecordingLogger} +import xsbti.compile.ClasspathOptionsUtil + object ProjectHelpers { def projectDir(base: Path, name: String) = base.resolve(name) def sourcesDir(base: Path, name: String) = projectDir(base, name).resolve("src") @@ -166,6 +168,7 @@ object ProjectHelpers { dependencies = dependencies.toArray, scalaInstance = scalaInstance, rawClasspath = classpath, + classpathOptions = ClasspathOptionsUtil.boot(), classesDir = AbsolutePath(target), scalacOptions = Array.empty, javacOptions = Array.empty, diff --git a/integrations/core/src/main/scala/bloop/integrations/BloopConfig.scala b/integrations/core/src/main/scala/bloop/integrations/BloopConfig.scala index 5bad9fe024..3e86f0a4f7 100644 --- a/integrations/core/src/main/scala/bloop/integrations/BloopConfig.scala +++ b/integrations/core/src/main/scala/bloop/integrations/BloopConfig.scala @@ -2,6 +2,14 @@ package bloop.integrations import java.io.{File, FileOutputStream} +case class ClasspathOptions(bootLibrary: Boolean, + compiler: Boolean, + extra: Boolean, + autoBoot: Boolean, + filterLibrary: Boolean) { + def toSeq: Seq[Boolean] = Seq(bootLibrary, compiler, extra, autoBoot, filterLibrary) +} + case class BloopConfig( name: String, baseDirectory: File, @@ -10,6 +18,7 @@ case class BloopConfig( scalaName: String, scalaVersion: String, classpath: Seq[File], + classpathOptions: ClasspathOptions, classesDir: File, scalacOptions: Seq[String], javacOptions: Seq[String], @@ -32,6 +41,7 @@ case class BloopConfig( properties.setProperty("scalaName", scalaName) properties.setProperty("scalaVersion", scalaVersion) properties.setProperty("classpath", seqToString(toPaths(classpath))) + properties.setProperty("classpathOptions", seqToString(classpathOptions.toSeq)) properties.setProperty("classesDir", classesDir.getAbsolutePath) properties.setProperty("scalacOptions", seqToString(scalacOptions, ";")) properties.setProperty("javacOptions", seqToString(javacOptions, ";")) diff --git a/integrations/maven-bloop/src/main/java/bloop/integrations/maven/BloopMojo.java b/integrations/maven-bloop/src/main/java/bloop/integrations/maven/BloopMojo.java index fb49e0e305..4059a5e47d 100644 --- a/integrations/maven-bloop/src/main/java/bloop/integrations/maven/BloopMojo.java +++ b/integrations/maven-bloop/src/main/java/bloop/integrations/maven/BloopMojo.java @@ -1,5 +1,7 @@ package bloop.integrations.maven; +import bloop.integrations.ClasspathOptions; + import org.apache.commons.lang3.ArrayUtils; import org.apache.maven.plugin.MavenPluginManager; import org.apache.maven.plugin.MojoExecution; @@ -35,6 +37,21 @@ public class BloopMojo extends ExtendedScalaContinuousCompileMojo { @Parameter(property = "bloop.executionFork", defaultValue = "false") private boolean bloopExecutionFork; + @Parameter(property = "bloop.classpathOptions.bootLibrary", defaultValue = "true") + private boolean classpathOptionsBootLibrary; + + @Parameter(property = "bloop.classpathOptions.compiler", defaultValue = "false") + private boolean classpathOptionsCompiler; + + @Parameter(property = "bloop.classpathOptions.extra", defaultValue = "false") + private boolean classpathOptionsExtra; + + @Parameter(property = "bloop.classpathOptions.autoBoot", defaultValue = "true") + private boolean classpathOptionsAutoBoot; + + @Parameter(property = "bloop.classpathOptions.filterLibrary", defaultValue = "true") + private boolean classpathOptionsFilterLibrary; + @Parameter private AppLauncher[] launchers; @@ -63,6 +80,14 @@ public boolean getExecutionFork() { return bloopExecutionFork; } + public ClasspathOptions getClasspathOptions() { + return new ClasspathOptions(classpathOptionsBootLibrary, + classpathOptionsCompiler, + classpathOptionsExtra, + classpathOptionsAutoBoot, + classpathOptionsFilterLibrary); + } + public String getScalaArtifactID() { return scalaArtifactID; } diff --git a/integrations/maven-bloop/src/main/scala/bloop/integrations/maven/MojoImplementation.scala b/integrations/maven-bloop/src/main/scala/bloop/integrations/maven/MojoImplementation.scala index ec64d9da7a..a3928698b5 100644 --- a/integrations/maven-bloop/src/main/scala/bloop/integrations/maven/MojoImplementation.scala +++ b/integrations/maven-bloop/src/main/scala/bloop/integrations/maven/MojoImplementation.scala @@ -72,6 +72,7 @@ object MojoImplementation { val cp = classpath0.asScala.toList.asInstanceOf[List[String]].map(new File(_)) if (cp.headOption.contains(classesDir)) cp.tail else cp } + val classpathOptions = mojo.getClasspathOptions() val dependencies = project.getProjectReferences().asScala.values.map(_.getArtifactId).toList val allScalaJars = mojo.getAllScalaJars() val tmpDir = new File(classesDir, "tmp-bloop") @@ -81,8 +82,9 @@ object MojoImplementation { // FORMAT: OFF val config = BloopConfig(name, baseDirectory, dependencies, mojo.getScalaOrganization, - mojo.getScalaArtifactID, mojo.getScalaVersion, classpath, classesDir, mojo.getScalacArgs.asScala, - mojo.getJavacArgs().asScala, sourceDirs, testFrameworks, fork, javaHome, javaOptions, allScalaJars, tmpDir + mojo.getScalaArtifactID, mojo.getScalaVersion, classpath, classpathOptions, classesDir, + mojo.getScalacArgs.asScala, mojo.getJavacArgs().asScala, sourceDirs, testFrameworks, fork, + javaHome, javaOptions, allScalaJars, tmpDir ) // FORMAT: ON diff --git a/integrations/sbt-bloop/src/main/scala/bloop/integrations/sbt/SbtBloop.scala b/integrations/sbt-bloop/src/main/scala/bloop/integrations/sbt/SbtBloop.scala index 651a29f314..8f350b15da 100644 --- a/integrations/sbt-bloop/src/main/scala/bloop/integrations/sbt/SbtBloop.scala +++ b/integrations/sbt-bloop/src/main/scala/bloop/integrations/sbt/SbtBloop.scala @@ -1,6 +1,6 @@ package bloop.integrations.sbt -import bloop.integrations.BloopConfig +import bloop.integrations.{BloopConfig, ClasspathOptions} import sbt.{AutoPlugin, Compile, Configuration, Def, File, Keys, ScopeFilter, Test, ThisBuild} object SbtBloop extends AutoPlugin { @@ -78,6 +78,10 @@ object PluginImplementation { val scalaOrg = Keys.ivyScala.value.map(_.scalaOrganization).getOrElse("org.scala-lang") val allScalaJars = Keys.scalaInstance.value.allJars.map(_.getAbsoluteFile) val classpath = PluginDefaults.emulateDependencyClasspath.value.map(_.getAbsoluteFile) + val classpathOptions = { + val cpo = Keys.classpathOptions.value + ClasspathOptions(cpo.bootLibrary, cpo.compiler, cpo.extra, cpo.autoBoot, cpo.filterLibrary) + } val classesDir = Keys.classDirectory.value.getAbsoluteFile val sourceDirs = Keys.sourceDirectories.value val testFrameworks = Keys.testFrameworks.value.map(_.implClassNames) @@ -98,8 +102,8 @@ object PluginImplementation { // format: OFF val config = BloopConfig(projectName, baseDirectory, dependenciesAndAggregates, scalaOrg, - scalaName, scalaVersion, classpath, classesDir, scalacOptions, javacOptions, sourceDirs, - testFrameworks, fork, javaHome, javaOptions, allScalaJars, tmp) + scalaName, scalaVersion, classpath, classpathOptions, classesDir, scalacOptions, + javacOptions, sourceDirs, testFrameworks, fork, javaHome, javaOptions, allScalaJars, tmp) sbt.IO.createDirectory(bloopConfigDir) config.writeTo(outFile) logger.success(s"Bloop wrote the configuration of project '$projectName' to '$outFile'.")