mirror of https://github.com/sbt/sbt.git
checksums configurable in [ivy] section. fixes #235
This commit is contained in:
parent
66500ea776
commit
8e9e4b22cd
|
|
@ -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"
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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 =
|
||||||
|
|
|
||||||
|
|
@ -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] {
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
@ -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}
|
||||||
|
|
@ -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 }
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue