mirror of https://github.com/sbt/sbt.git
Specify the compiler bridge module in a setting
In order to restore reproducibility of builds, we no longer cascade over the possibly available versions of the compiler bridge sources (a specific version of the bridge sources may not be available one day, but exist on the next day), but rather let the build definition configure which module to use. Fixes sbt/sbt#2196
This commit is contained in:
parent
4f0b1071df
commit
d110e6937b
|
|
@ -31,13 +31,13 @@ object ComponentCompiler {
|
|||
}
|
||||
}
|
||||
|
||||
def interfaceProvider(manager: ComponentManager, ivyConfiguration: IvyConfiguration, bootDirectory: File): CompilerInterfaceProvider = new CompilerInterfaceProvider {
|
||||
def interfaceProvider(manager: ComponentManager, ivyConfiguration: IvyConfiguration, sourcesModule: ModuleID, bootDirectory: File): CompilerInterfaceProvider = new CompilerInterfaceProvider {
|
||||
def apply(scalaInstance: xsbti.compile.ScalaInstance, log: Logger): File =
|
||||
{
|
||||
// this is the instance used to compile the interface component
|
||||
val componentCompiler = new IvyComponentCompiler(new RawCompiler(scalaInstance, ClasspathOptions.auto, log), manager, ivyConfiguration, bootDirectory, log)
|
||||
log.debug("Getting " + compilerInterfaceID + " from component compiler for Scala " + scalaInstance.version)
|
||||
componentCompiler(compilerInterfaceID)
|
||||
val componentCompiler = new IvyComponentCompiler(new RawCompiler(scalaInstance, ClasspathOptions.auto, log), manager, ivyConfiguration, sourcesModule, bootDirectory, log)
|
||||
log.debug("Getting " + sourcesModule + " from component compiler for Scala " + scalaInstance.version)
|
||||
componentCompiler()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -92,12 +92,12 @@ class ComponentCompiler(compiler: RawCompiler, manager: ComponentManager) {
|
|||
}
|
||||
|
||||
/**
|
||||
* Component compiler which is able to find the most specific version available of
|
||||
* the compiler interface sources using Ivy.
|
||||
* Component compiler which is able to to retrieve the compiler bridge sources
|
||||
* `sourceModule` using Ivy.
|
||||
* The compiled classes are cached using the provided component manager according
|
||||
* to the actualVersion field of the RawCompiler.
|
||||
*/
|
||||
private[compiler] class IvyComponentCompiler(compiler: RawCompiler, manager: ComponentManager, ivyConfiguration: IvyConfiguration, bootDirectory: File, log: Logger) {
|
||||
private[compiler] class IvyComponentCompiler(compiler: RawCompiler, manager: ComponentManager, ivyConfiguration: IvyConfiguration, sourcesModule: ModuleID, bootDirectory: File, log: Logger) {
|
||||
import ComponentCompiler._
|
||||
|
||||
private val incrementalCompilerOrg = xsbti.ArtifactInfo.SbtOrganization + ".incrementalcompiler"
|
||||
|
|
@ -105,11 +105,11 @@ private[compiler] class IvyComponentCompiler(compiler: RawCompiler, manager: Com
|
|||
private val modulePrefixTemp = "temp-module-"
|
||||
private val ivySbt: IvySbt = new IvySbt(ivyConfiguration)
|
||||
private val buffered = new BufferedLogger(FullLogger(log))
|
||||
private val retrieveDirectory = new File(s"$bootDirectory/scala-${compiler.scalaInstance.version}/$incrementalCompilerOrg/sbt/$incrementalVersion/compiler-interface-srcs")
|
||||
private val retrieveDirectory = new File(s"$bootDirectory/scala-${compiler.scalaInstance.version}/$incrementalCompilerOrg/sbt/$incrementalVersion/compiler-interface-srcs/${sourcesModule.name}/${sourcesModule.revision}")
|
||||
|
||||
def apply(id: String): File = {
|
||||
val binID = binaryID(id)
|
||||
manager.file(binID)(new IfMissing.Define(true, compileAndInstall(id, binID)))
|
||||
def apply(): File = {
|
||||
val binID = binaryID(sourcesModule.name)
|
||||
manager.file(binID)(new IfMissing.Define(true, compileAndInstall(binID)))
|
||||
}
|
||||
|
||||
private def binaryID(id: String): String = {
|
||||
|
|
@ -117,53 +117,32 @@ private[compiler] class IvyComponentCompiler(compiler: RawCompiler, manager: Com
|
|||
base + "__" + javaVersion
|
||||
}
|
||||
|
||||
private def compileAndInstall(id: String, binID: String): Unit = {
|
||||
def interfaceSources(moduleVersions: Vector[VersionNumber]): Iterable[File] =
|
||||
moduleVersions match {
|
||||
case Vector() =>
|
||||
def getAndDefineDefaultSources() =
|
||||
update(getModule(id))(_.getName endsWith "-sources.jar") map { sourcesJar =>
|
||||
manager.define(id, sourcesJar)
|
||||
sourcesJar
|
||||
} getOrElse (throw new InvalidComponent(s"Couldn't retrieve default sources: module '$id'"))
|
||||
|
||||
buffered.debug(s"Fetching default sources: module '$id'")
|
||||
manager.files(id)(new IfMissing.Fallback(getAndDefineDefaultSources()))
|
||||
|
||||
case version +: rest =>
|
||||
val moduleName = s"${id}_$version"
|
||||
def getAndDefineVersionSpecificSources() =
|
||||
update(getModule(moduleName))(_.getName endsWith "-sources.jar") map { sourcesJar =>
|
||||
manager.define(moduleName, sourcesJar)
|
||||
sourcesJar
|
||||
} getOrElse interfaceSources(rest)
|
||||
|
||||
buffered.debug(s"Fetching version-specific sources: module '$moduleName'")
|
||||
manager.files(moduleName)(new IfMissing.Fallback(getAndDefineVersionSpecificSources()))
|
||||
}
|
||||
private def compileAndInstall(binID: String): Unit =
|
||||
IO.withTemporaryDirectory { binaryDirectory =>
|
||||
|
||||
val targetJar = new File(binaryDirectory, s"$binID.jar")
|
||||
val xsbtiJars = manager.files(xsbtiID)(IfMissing.Fail)
|
||||
|
||||
val sourceModuleVersions = VersionNumber(compiler.scalaInstance.actualVersion).cascadingVersions
|
||||
val sources = buffered bufferQuietly interfaceSources(sourceModuleVersions)
|
||||
AnalyzingCompiler.compileSources(sources, targetJar, xsbtiJars, id, compiler, log)
|
||||
|
||||
manager.define(binID, Seq(targetJar))
|
||||
buffered bufferQuietly {
|
||||
(update(getModule(sourcesModule))(_.getName endsWith "-sources.jar")) match {
|
||||
case Some(sources) =>
|
||||
AnalyzingCompiler.compileSources(sources, targetJar, xsbtiJars, sourcesModule.name, compiler, log)
|
||||
manager.define(binID, Seq(targetJar))
|
||||
|
||||
case None =>
|
||||
throw new InvalidComponent(s"Couldn't retrieve source module: $sourcesModule")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a dummy module that depends on "org.scala-sbt" % `id` % `incrementalVersion`.
|
||||
* Returns a dummy module that depends on `moduleID`.
|
||||
* Note: Sbt's implementation of Ivy requires us to do this, because only the dependencies
|
||||
* of the specified module will be downloaded.
|
||||
*/
|
||||
private def getModule(id: String): ivySbt.Module = {
|
||||
val sha1 = Hash.toHex(Hash(id))
|
||||
val dummyID = ModuleID(sbtOrgTemp, modulePrefixTemp + sha1, incrementalVersion, Some("component"))
|
||||
val moduleID = ModuleID(xsbti.ArtifactInfo.SbtOrganization + ".incrementalcompiler", id, incrementalVersion, Some("component")).sources()
|
||||
private def getModule(moduleID: ModuleID): ivySbt.Module = {
|
||||
val sha1 = Hash.toHex(Hash(moduleID.name))
|
||||
val dummyID = ModuleID(sbtOrgTemp, modulePrefixTemp + sha1, moduleID.revision, moduleID.configurations)
|
||||
getModule(dummyID, Seq(moduleID))
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue