From 0b4d0e1062367c4282580114a2b90ae7c118788e Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Fri, 15 Apr 2011 18:32:20 -0400 Subject: [PATCH] inject sbt-managed Scala libraries into the UpdateReport --- ivy/IvyScala.scala | 16 +++++++++++----- ivy/ProjectResolver.scala | 3 +++ ivy/UpdateReport.scala | 15 ++++++++++++++- main/Defaults.scala | 20 +++++++++++++++----- 4 files changed, 43 insertions(+), 11 deletions(-) diff --git a/ivy/IvyScala.scala b/ivy/IvyScala.scala index bb2f3dce7..511a3e997 100644 --- a/ivy/IvyScala.scala +++ b/ivy/IvyScala.scala @@ -22,6 +22,11 @@ object ScalaArtifacts import ScalaArtifacts._ final class IvyScala(val scalaVersion: String, val configurations: Iterable[Configuration], val checkExplicit: Boolean, val filterImplicit: Boolean, val overrideScalaVersion: Boolean) +{ + // otherwise, Ivy produces the error: "impossible to get artifacts when data has not been loaded" + // which may be related to sbt's custom conflict manager, to IVY-987, or both + assert(if(overrideScalaVersion) checkExplicit else true, "Explicit Scala version checking cannot be disabled when forcing the Scala version.") +} private object IvyScala { /** Performs checks/adds filters on Scala dependencies (if enabled in IvyScala). */ @@ -50,18 +55,19 @@ private object IvyScala * dependencies matches scalaVersion. */ private def checkDependencies(module: ModuleDescriptor, scalaVersion: String, configurations: Iterable[Configuration]) { - val configSet = configurationSet(configurations) + val configSet = if(configurations.isEmpty) (c: String) => true else configurationSet(configurations) for(dep <- module.getDependencies.toList) { val id = dep.getDependencyRevisionId - if(id.getOrganisation == Organization && id.getRevision != scalaVersion && dep.getModuleConfigurations.exists(configSet.contains)) + if(id.getOrganisation == Organization && id.getRevision != scalaVersion && dep.getModuleConfigurations.exists(configSet)) error("Different Scala version specified in dependency ("+ id.getRevision + ") than in project (" + scalaVersion + ").") } } - private def configurationSet(configurations: Iterable[Configuration]) = HashSet(configurations.map(_.toString).toSeq : _*) + private def configurationSet(configurations: Iterable[Configuration]) = configurations.map(_.toString).toSet + /** Adds exclusions for the scala library and compiler jars so that they are not downloaded. This is - * done because normally these jars are already on the classpath and cannot/should not be overridden. The version - * of Scala to use is done by setting build.scala.versions in the project definition. */ + * done because these jars are provided by the ScalaInstance of the project. The version of Scala to use + * is done by setting scalaVersion in the project definition. */ private def excludeScalaJars(module: DefaultModuleDescriptor, configurations: Iterable[Configuration]) { val configurationNames = diff --git a/ivy/ProjectResolver.scala b/ivy/ProjectResolver.scala index 4d1ae4f37..aee0cb772 100644 --- a/ivy/ProjectResolver.scala +++ b/ivy/ProjectResolver.scala @@ -1,3 +1,6 @@ +/* sbt -- Simple Build Tool + * Copyright 2011 Mark Harrah + */ package sbt import java.io.File diff --git a/ivy/UpdateReport.scala b/ivy/UpdateReport.scala index 76befd5a0..5ecad5d17 100644 --- a/ivy/UpdateReport.scala +++ b/ivy/UpdateReport.scala @@ -101,5 +101,18 @@ object UpdateReport } new UpdateReport(newConfigurations) } + def substitute(f: (String, ModuleID, Seq[(Artifact, File)]) => Seq[(Artifact, File)]): UpdateReport = + { + val newConfigurations = report.configurations.map { confReport => + import confReport._ + val newModules = + modules map { modReport => + val newArtifacts = f(configuration, modReport.module, modReport.artifacts) + new ModuleReport(modReport.module, newArtifacts, Nil) + } + new ConfigurationReport(configuration, newModules) + } + new UpdateReport(newConfigurations) + } } -} \ No newline at end of file +} diff --git a/main/Defaults.scala b/main/Defaults.scala index 2f686d26f..7363c1131 100644 --- a/main/Defaults.scala +++ b/main/Defaults.scala @@ -509,7 +509,7 @@ object Classpaths ivyLoggingLevel in GlobalScope :== UpdateLogging.Quiet, ivyXML in GlobalScope :== NodeSeq.Empty, ivyValidate in GlobalScope :== false, - ivyScala in GlobalScope <<= scalaVersion(v => Some(new IvyScala(v, Nil, false, false, overrideScalaVersion = true))), + ivyScala in GlobalScope <<= scalaVersion(v => Some(new IvyScala(v, Nil, filterImplicit = true, checkExplicit = true, overrideScalaVersion = true))), moduleConfigurations in GlobalScope :== Nil, publishTo in GlobalScope :== None, artifactPath in makePom <<= (crossTarget, projectID, artifact in makePom, artifactName) { @@ -547,8 +547,8 @@ object Classpaths new IvySbt(conf) }, ivyModule <<= (ivySbt, moduleSettings) map { (ivySbt, settings) => new ivySbt.Module(settings) }, - update <<= (ivyModule, updateConfiguration, cacheDirectory, streams) map { (module, config, cacheDirectory, s) => - cachedUpdate(cacheDirectory / "update", module, config, s.log) + update <<= (ivyModule, updateConfiguration, cacheDirectory, scalaInstance, streams) map { (module, config, cacheDirectory, si, s) => + cachedUpdate(cacheDirectory / "update", module, config, Some(si), s.log) }, transitiveClassifiers :== Seq("sources", "javadoc"), updateClassifiers <<= (ivySbt, projectID, update, transitiveClassifiers, updateConfiguration, ivyScala, streams) map { (is, pid, up, classifiers, c, ivyScala, s) => @@ -578,7 +578,7 @@ object Classpaths import Cache._ import CacheIvy.{classpathFormat, /*publishIC,*/ updateIC, updateReportF} - def cachedUpdate(cacheFile: File, module: IvySbt#Module, config: UpdateConfiguration, log: Logger): UpdateReport = + def cachedUpdate(cacheFile: File, module: IvySbt#Module, config: UpdateConfiguration, scalaInstance: Option[ScalaInstance], log: Logger): UpdateReport = { implicit val updateCache = updateIC implicit val updateReport = updateReportF @@ -587,7 +587,7 @@ object Classpaths log.info("Updating...") val r = IvyActions.update(module, config, log) log.info("Done updating.") - r + scalaInstance match { case Some(si) => substituteScalaFiles(si, r); case None => r } } val f = @@ -760,6 +760,16 @@ object Classpaths if(auto) options ++ autoPlugins(report) else options } ) + def substituteScalaFiles(scalaInstance: ScalaInstance, report: UpdateReport): UpdateReport = + report.substitute { (configuration, module, arts) => + import ScalaArtifacts._ + (module.organization, module.name) match + { + case (Organization, LibraryID) => (Artifact(LibraryID), scalaInstance.libraryJar) :: Nil + case (Organization, CompilerID) => (Artifact(CompilerID), scalaInstance.compilerJar) :: Nil + case _ => arts + } + } } trait CompilerPluginExtra