checksums configurable in [ivy] section. fixes #235

This commit is contained in:
Mark Harrah 2011-11-04 12:19:45 -04:00
parent 66500ea776
commit 8e9e4b22cd
8 changed files with 51 additions and 39 deletions

View File

@ -47,6 +47,7 @@ private object BootConfiguration
val ScalaHomeProperty = "scala.home" val ScalaHomeProperty = "scala.home"
val UpdateLogName = "update.log" val UpdateLogName = "update.log"
val DefaultChecksums = "sha1" :: "md5" :: Nil
val DefaultIvyConfiguration = "default" val DefaultIvyConfiguration = "default"

View File

@ -16,7 +16,32 @@ import scala.collection.immutable.List
object ConfigurationParser object ConfigurationParser
{ {
def trim(s: Array[String]) = s.map(_.trim).toList 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 _ implicit val readIDs = ids _
} }
@ -43,10 +68,11 @@ class ConfigurationParser
val (boot, m4) = processSection(m3, "boot", getBoot) val (boot, m4) = processSection(m3, "boot", getBoot)
val (logging, m5) = processSection(m4, "log", getLogging) val (logging, m5) = processSection(m4, "log", getLogging)
val (properties, m6) = processSection(m5, "app-properties", getAppProperties) 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") check(m7, "section")
val classifiers = Classifiers(scalaClassifiers, appClassifiers) 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) = def getScala(m: LabelMap) =
{ {
@ -94,11 +120,13 @@ class ConfigurationParser
def file(map: LabelMap, name: String, default: File): (File, LabelMap) = def file(map: LabelMap, name: String, default: File): (File, LabelMap) =
(orElse(getOrNone(map, name).map(toFile), default), map - name) (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 val (ivyHome, m1) = file(m, "ivy-home", null) // fix this later
check(m1, "label") val (checksums, m2) = ids(m1, "checksums", BootConfiguration.DefaultChecksums)
if(ivyHome eq null) None else Some(ivyHome) check(m2, "label")
val home = if(ivyHome eq null) None else Some(ivyHome)
(home, checksums)
} }
def getBoot(m: LabelMap): BootSetup = def getBoot(m: LabelMap): BootSetup =
{ {
@ -193,30 +221,6 @@ class ConfigurationParser
s._1 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 sealed trait Line

View File

@ -79,7 +79,7 @@ final class RunConfiguration(val scalaVersion: String, val app: xsbti.Applicatio
import BootConfiguration.{appDirectoryName, baseDirectoryName, ScalaDirectoryName, TestLoadScalaClasses} import BootConfiguration.{appDirectoryName, baseDirectoryName, ScalaDirectoryName, TestLoadScalaClasses}
class Launch private[xsbt](val bootDirectory: File, val lockBoot: Boolean, val ivyOptions: IvyOptions) extends xsbti.Launcher 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 bootDirectory.mkdirs
private val scalaProviders = new Cache[String, String, ScalaProvider](new ScalaProvider(_, _)) private val scalaProviders = new Cache[String, String, ScalaProvider](new ScalaProvider(_, _))
def getScala(version: String): xsbti.ScalaProvider = getScala(version, "") 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 globalLock: xsbti.GlobalLock = Locks
def ivyHome = ivyOptions.ivyHome.orNull def ivyHome = ivyOptions.ivyHome.orNull
def ivyRepositories = repositories.toArray def ivyRepositories = repositories.toArray
def checksums = checksumsList.toArray[String]
class JNAProvider extends Provider class JNAProvider extends Provider
{ {
lazy val id = new Application("net.java.dev.jna", "jna", new Explicit("3.2.3"), "", Nil, false, array()) 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("")) lazy val libDirectory = new File(bootDirectory, baseDirectoryName(""))
def baseDirectories: List[File] = new File(libDirectory, appDirectoryName(id.toID, File.separator)) :: Nil def baseDirectories: List[File] = new File(libDirectory, appDirectoryName(id.toID, File.separator)) :: Nil
def testLoadClasses: List[String] = "com.sun.jna.Function" :: 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 launcher: xsbti.Launcher = Launch.this
def parentLoader = topLoader 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 libDirectory = new File(configuration.bootDirectory, baseDirectoryName(version))
lazy val scalaHome = new File(libDirectory, ScalaDirectoryName) lazy val scalaHome = new File(libDirectory, ScalaDirectoryName)
def compilerJar = new File(scalaHome, CompilerModuleName + ".jar") 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 object Launcher
{ {
def apply(bootDirectory: File, repositories: List[xsbti.Repository]): xsbti.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 = def apply(bootDirectory: File, ivyOptions: IvyOptions): xsbti.Launcher =
apply(bootDirectory, ivyOptions, GetLocks.find) apply(bootDirectory, ivyOptions, GetLocks.find)
def apply(bootDirectory: File, ivyOptions: IvyOptions, locks: xsbti.GlobalLock): xsbti.Launcher = def apply(bootDirectory: File, ivyOptions: IvyOptions, locks: xsbti.GlobalLock): xsbti.Launcher =

View File

@ -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) 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) 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] sealed trait Value[T]
final class Explicit[T](val value: T) extends Value[T] { final class Explicit[T](val value: T) extends Value[T] {

View File

@ -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 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 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.*/ /** Ensures that the Scala and application jars exist for the given versions or else downloads them.*/
final class Update(config: UpdateConfiguration) final class Update(config: UpdateConfiguration)
{ {
import config.{bootDirectory, ivyHome, repositories, scalaVersion} import config.{bootDirectory, checksums, ivyHome, repositories, scalaVersion}
bootDirectory.mkdirs bootDirectory.mkdirs
private def logFile = new File(bootDirectory, UpdateLogName) private def logFile = new File(bootDirectory, UpdateLogName)
@ -65,7 +65,7 @@ final class Update(config: UpdateConfiguration)
val settings = new IvySettings val settings = new IvySettings
ivyHome foreach settings.setDefaultIvyUserDir ivyHome foreach settings.setDefaultIvyUserDir
addResolvers(settings) addResolvers(settings)
settings.setVariable("ivy.checksums", "sha1,md5") settings.setVariable("ivy.checksums", checksums mkString ",")
settings.setDefaultConflictManager(settings.getConflictManager(ConflictManagerName)) settings.setDefaultConflictManager(settings.getConflictManager(ConflictManagerName))
settings.setBaseDir(bootDirectory) settings.setBaseDir(bootDirectory)
settings.setVariable("scala", scalaVersion) settings.setVariable("scala", scalaVersion)

View File

@ -13,4 +13,5 @@ public interface Launcher
public xsbti.Repository[] ivyRepositories(); public xsbti.Repository[] ivyRepositories();
// null if none set // null if none set
public File ivyHome(); public File ivyHome();
public String[] checksums();
} }

View File

@ -22,3 +22,4 @@ ${{repositories}}
[ivy] [ivy]
ivy-home: ${sbt.ivy.home-${user.home}/.ivy2/} ivy-home: ${sbt.ivy.home-${user.home}/.ivy2/}
checksums: ${sbt.checksums-sha1,md5}

View File

@ -102,7 +102,7 @@ object Defaults extends BuildCommon
artifactClassifier :== None, artifactClassifier :== None,
artifactClassifier in packageSrc :== Some(SourceClassifier), artifactClassifier in packageSrc :== Some(SourceClassifier),
artifactClassifier in packageDoc :== Some(DocClassifier), artifactClassifier in packageDoc :== Some(DocClassifier),
checksums :== IvySbt.DefaultChecksums, checksums <<= appConfiguration(Classpaths.bootChecksums),
pomExtra :== NodeSeq.Empty, pomExtra :== NodeSeq.Empty,
pomPostProcess :== idFun, pomPostProcess :== idFun,
pomAllRepositories :== false, pomAllRepositories :== false,
@ -1039,6 +1039,10 @@ object Classpaths
try { Option(app.provider.scalaProvider.launcher.ivyHome) } try { Option(app.provider.scalaProvider.launcher.ivyHome) }
catch { case _: NoSuchMethodError => None } 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]] = def bootRepositories(app: xsbti.AppConfiguration): Option[Seq[Resolver]] =
try { Some(app.provider.scalaProvider.launcher.ivyRepositories.toSeq map bootRepository) } try { Some(app.provider.scalaProvider.launcher.ivyRepositories.toSeq map bootRepository) }
catch { case _: NoSuchMethodError => None } catch { case _: NoSuchMethodError => None }