From 8e9e4b22cd6bbe1d177a8bf5efe3978bd3740c51 Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Fri, 4 Nov 2011 12:19:45 -0400 Subject: [PATCH] checksums configurable in [ivy] section. fixes #235 --- launch/BootConfiguration.scala | 1 + launch/ConfigurationParser.scala | 64 ++++++++++--------- launch/Launch.scala | 9 +-- launch/LaunchConfiguration.scala | 2 +- launch/Update.scala | 6 +- .../src/main/java/xsbti/Launcher.java | 1 + .../input_resources/sbt/sbt.boot.properties | 1 + main/Defaults.scala | 6 +- 8 files changed, 51 insertions(+), 39 deletions(-) diff --git a/launch/BootConfiguration.scala b/launch/BootConfiguration.scala index 718dcb87f..3257df0d2 100644 --- a/launch/BootConfiguration.scala +++ b/launch/BootConfiguration.scala @@ -47,6 +47,7 @@ private object BootConfiguration val ScalaHomeProperty = "scala.home" val UpdateLogName = "update.log" + val DefaultChecksums = "sha1" :: "md5" :: Nil val DefaultIvyConfiguration = "default" diff --git a/launch/ConfigurationParser.scala b/launch/ConfigurationParser.scala index b863e461e..b4e54046f 100644 --- a/launch/ConfigurationParser.scala +++ b/launch/ConfigurationParser.scala @@ -16,7 +16,32 @@ import scala.collection.immutable.List object ConfigurationParser { def trim(s: Array[String]) = s.map(_.trim).toList - def ids(value: String) = trim(value.split(",")).filter(isNonEmpty) + def ids(value: String) = trim(substituteVariables(value).split(",")).filter(isNonEmpty) + + private[this] lazy val VarPattern = Pattern.compile("""\$\{([\w.]+)(\-(.+))?\}""") + def substituteVariables(s: String): String = if(s.indexOf('$') >= 0) substituteVariables0(s) else s + // scala.util.Regex brought in 30kB, so we code it explicitly + def substituteVariables0(s: String): String = + { + val m = VarPattern.matcher(s) + val b = new StringBuffer + while(m.find()) + { + val key = m.group(1) + val defined = System.getProperty(key) + val value = + if(defined ne null) + defined + else + { + val default = m.group(3) + if(default eq null) m.group() else substituteVariables(default) + } + m.appendReplacement(b, quoteReplacement(value)) + } + m.appendTail(b) + b.toString + } implicit val readIDs = ids _ } @@ -43,10 +68,11 @@ class ConfigurationParser val (boot, m4) = processSection(m3, "boot", getBoot) val (logging, m5) = processSection(m4, "log", getLogging) val (properties, m6) = processSection(m5, "app-properties", getAppProperties) - val (ivyHome, m7) = processSection(m6, "ivy", getIvy) + val ((ivyHome, checksums), m7) = processSection(m6, "ivy", getIvy) check(m7, "section") val classifiers = Classifiers(scalaClassifiers, appClassifiers) - new LaunchConfiguration(scalaVersion, IvyOptions(ivyHome, classifiers, repositories), app, boot, logging, properties) + val ivyOptions = IvyOptions(ivyHome, classifiers, repositories, checksums) + new LaunchConfiguration(scalaVersion, ivyOptions, app, boot, logging, properties) } def getScala(m: LabelMap) = { @@ -94,11 +120,13 @@ class ConfigurationParser def file(map: LabelMap, name: String, default: File): (File, LabelMap) = (orElse(getOrNone(map, name).map(toFile), default), map - name) - def getIvy(m: LabelMap): Option[File] = + def getIvy(m: LabelMap): (Option[File], List[String]) = { val (ivyHome, m1) = file(m, "ivy-home", null) // fix this later - check(m1, "label") - if(ivyHome eq null) None else Some(ivyHome) + val (checksums, m2) = ids(m1, "checksums", BootConfiguration.DefaultChecksums) + check(m2, "label") + val home = if(ivyHome eq null) None else Some(ivyHome) + (home, checksums) } def getBoot(m: LabelMap): BootSetup = { @@ -193,30 +221,6 @@ class ConfigurationParser s._1 } - private[this] lazy val VarPattern = Pattern.compile("""\$\{([\w.]+)(\-(.+))?\}""") - def substituteVariables(s: String): String = if(s.indexOf('$') >= 0) substituteVariables0(s) else s - // scala.util.Regex brought in 30kB, so we code it explicitly - def substituteVariables0(s: String): String = - { - val m = VarPattern.matcher(s) - val b = new StringBuffer - while(m.find()) - { - val key = m.group(1) - val defined = System.getProperty(key) - val value = - if(defined ne null) - defined - else - { - val default = m.group(3) - if(default eq null) m.group() else substituteVariables(default) - } - m.appendReplacement(b, quoteReplacement(value)) - } - m.appendTail(b) - b.toString - } } sealed trait Line diff --git a/launch/Launch.scala b/launch/Launch.scala index 0db955cfa..f356483b4 100644 --- a/launch/Launch.scala +++ b/launch/Launch.scala @@ -79,7 +79,7 @@ final class RunConfiguration(val scalaVersion: String, val app: xsbti.Applicatio import BootConfiguration.{appDirectoryName, baseDirectoryName, ScalaDirectoryName, TestLoadScalaClasses} class Launch private[xsbt](val bootDirectory: File, val lockBoot: Boolean, val ivyOptions: IvyOptions) extends xsbti.Launcher { - import ivyOptions.{classifiers, repositories} + import ivyOptions.{checksums => checksumsList, classifiers, repositories} bootDirectory.mkdirs private val scalaProviders = new Cache[String, String, ScalaProvider](new ScalaProvider(_, _)) def getScala(version: String): xsbti.ScalaProvider = getScala(version, "") @@ -91,11 +91,12 @@ class Launch private[xsbt](val bootDirectory: File, val lockBoot: Boolean, val i def globalLock: xsbti.GlobalLock = Locks def ivyHome = ivyOptions.ivyHome.orNull def ivyRepositories = repositories.toArray + def checksums = checksumsList.toArray[String] class JNAProvider extends Provider { lazy val id = new Application("net.java.dev.jna", "jna", new Explicit("3.2.3"), "", Nil, false, array()) - lazy val configuration = new UpdateConfiguration(bootDirectory, ivyOptions.ivyHome, "", repositories) + lazy val configuration = new UpdateConfiguration(bootDirectory, ivyOptions.ivyHome, "", repositories, checksumsList) lazy val libDirectory = new File(bootDirectory, baseDirectoryName("")) def baseDirectories: List[File] = new File(libDirectory, appDirectoryName(id.toID, File.separator)) :: Nil def testLoadClasses: List[String] = "com.sun.jna.Function" :: Nil @@ -111,7 +112,7 @@ class Launch private[xsbt](val bootDirectory: File, val lockBoot: Boolean, val i def launcher: xsbti.Launcher = Launch.this def parentLoader = topLoader - lazy val configuration = new UpdateConfiguration(bootDirectory, ivyOptions.ivyHome, version, repositories) + lazy val configuration = new UpdateConfiguration(bootDirectory, ivyOptions.ivyHome, version, repositories, checksumsList) lazy val libDirectory = new File(configuration.bootDirectory, baseDirectoryName(version)) lazy val scalaHome = new File(libDirectory, ScalaDirectoryName) def compilerJar = new File(scalaHome, CompilerModuleName + ".jar") @@ -154,7 +155,7 @@ class Launch private[xsbt](val bootDirectory: File, val lockBoot: Boolean, val i object Launcher { def apply(bootDirectory: File, repositories: List[xsbti.Repository]): xsbti.Launcher = - apply(bootDirectory, IvyOptions(None, Classifiers(Nil, Nil), repositories)) + apply(bootDirectory, IvyOptions(None, Classifiers(Nil, Nil), repositories, BootConfiguration.DefaultChecksums)) def apply(bootDirectory: File, ivyOptions: IvyOptions): xsbti.Launcher = apply(bootDirectory, ivyOptions, GetLocks.find) def apply(bootDirectory: File, ivyOptions: IvyOptions, locks: xsbti.GlobalLock): xsbti.Launcher = diff --git a/launch/LaunchConfiguration.scala b/launch/LaunchConfiguration.scala index babeae927..9fd186e58 100644 --- a/launch/LaunchConfiguration.scala +++ b/launch/LaunchConfiguration.scala @@ -20,7 +20,7 @@ final case class LaunchConfiguration(scalaVersion: Value[String], ivyConfigurati LaunchConfiguration(new Explicit(newScalaVersion), ivyConfiguration.copy(classifiers = classifiers0), app.withVersion(new Explicit(newAppVersion)), boot, logging, appProperties) def map(f: File => File) = LaunchConfiguration(scalaVersion, ivyConfiguration, app.map(f), boot.map(f), logging, appProperties) } -final case class IvyOptions(ivyHome: Option[File], classifiers: Classifiers, repositories: List[xsbti.Repository]) +final case class IvyOptions(ivyHome: Option[File], classifiers: Classifiers, repositories: List[xsbti.Repository], checksums: List[String]) sealed trait Value[T] final class Explicit[T](val value: T) extends Value[T] { diff --git a/launch/Update.scala b/launch/Update.scala index 1c734bcda..f18d7226d 100644 --- a/launch/Update.scala +++ b/launch/Update.scala @@ -33,12 +33,12 @@ sealed trait UpdateTarget { def tpe: String; def classifiers: List[String] } final class UpdateScala(val classifiers: List[String]) extends UpdateTarget { def tpe = "scala" } final class UpdateApp(val id: Application, val classifiers: List[String]) extends UpdateTarget { def tpe = "app" } -final class UpdateConfiguration(val bootDirectory: File, val ivyHome: Option[File], val scalaVersion: String, val repositories: List[xsbti.Repository]) +final class UpdateConfiguration(val bootDirectory: File, val ivyHome: Option[File], val scalaVersion: String, val repositories: List[xsbti.Repository], val checksums: List[String]) /** Ensures that the Scala and application jars exist for the given versions or else downloads them.*/ final class Update(config: UpdateConfiguration) { - import config.{bootDirectory, ivyHome, repositories, scalaVersion} + import config.{bootDirectory, checksums, ivyHome, repositories, scalaVersion} bootDirectory.mkdirs private def logFile = new File(bootDirectory, UpdateLogName) @@ -65,7 +65,7 @@ final class Update(config: UpdateConfiguration) val settings = new IvySettings ivyHome foreach settings.setDefaultIvyUserDir addResolvers(settings) - settings.setVariable("ivy.checksums", "sha1,md5") + settings.setVariable("ivy.checksums", checksums mkString ",") settings.setDefaultConflictManager(settings.getConflictManager(ConflictManagerName)) settings.setBaseDir(bootDirectory) settings.setVariable("scala", scalaVersion) diff --git a/launch/interface/src/main/java/xsbti/Launcher.java b/launch/interface/src/main/java/xsbti/Launcher.java index f416fa698..92e54ba15 100644 --- a/launch/interface/src/main/java/xsbti/Launcher.java +++ b/launch/interface/src/main/java/xsbti/Launcher.java @@ -13,4 +13,5 @@ public interface Launcher public xsbti.Repository[] ivyRepositories(); // null if none set public File ivyHome(); + public String[] checksums(); } \ No newline at end of file diff --git a/launch/src/main/input_resources/sbt/sbt.boot.properties b/launch/src/main/input_resources/sbt/sbt.boot.properties index 11cef7464..1a1501578 100644 --- a/launch/src/main/input_resources/sbt/sbt.boot.properties +++ b/launch/src/main/input_resources/sbt/sbt.boot.properties @@ -22,3 +22,4 @@ ${{repositories}} [ivy] ivy-home: ${sbt.ivy.home-${user.home}/.ivy2/} + checksums: ${sbt.checksums-sha1,md5} \ No newline at end of file diff --git a/main/Defaults.scala b/main/Defaults.scala index 9cc0d692a..237108158 100644 --- a/main/Defaults.scala +++ b/main/Defaults.scala @@ -102,7 +102,7 @@ object Defaults extends BuildCommon artifactClassifier :== None, artifactClassifier in packageSrc :== Some(SourceClassifier), artifactClassifier in packageDoc :== Some(DocClassifier), - checksums :== IvySbt.DefaultChecksums, + checksums <<= appConfiguration(Classpaths.bootChecksums), pomExtra :== NodeSeq.Empty, pomPostProcess :== idFun, pomAllRepositories :== false, @@ -1039,6 +1039,10 @@ object Classpaths try { Option(app.provider.scalaProvider.launcher.ivyHome) } catch { case _: NoSuchMethodError => None } + def bootChecksums(app: xsbti.AppConfiguration): Seq[String] = + try { app.provider.scalaProvider.launcher.checksums.toSeq } + catch { case _: NoSuchMethodError => IvySbt.DefaultChecksums } + def bootRepositories(app: xsbti.AppConfiguration): Option[Seq[Resolver]] = try { Some(app.provider.scalaProvider.launcher.ivyRepositories.toSeq map bootRepository) } catch { case _: NoSuchMethodError => None }