mirror of https://github.com/sbt/sbt.git
Cut down launcher jar size a bit
This commit is contained in:
parent
a2758afd43
commit
8daaf9ea17
|
|
@ -35,6 +35,7 @@ object Configuration
|
|||
if(exists) Some(resolved.toURL) else None
|
||||
}
|
||||
val against = resolveAgainst(baseDirectory)
|
||||
// use Iterators so that resolution occurs lazily, for performance
|
||||
val resolving = against.elements.flatMap(e => resolve(e).toList.elements)
|
||||
if(!resolving.hasNext) multiPartError("Could not find configuration file '" + path + "'. Searched:", against)
|
||||
resolving.next()
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
package xsbt.boot
|
||||
|
||||
|
||||
import Pre._
|
||||
import java.lang.Character.isWhitespace
|
||||
import java.io.{BufferedReader, File, FileInputStream, InputStreamReader, Reader, StringReader}
|
||||
|
|
@ -102,7 +103,7 @@ class ConfigurationParser extends NotNull
|
|||
val (crossVersioned, m6) = id(m5, "cross-versioned", "true")
|
||||
val (resources, m7) = ids(m6, "resources", Nil)
|
||||
check(m7, "label")
|
||||
val classpathExtra = toFiles(resources).toArray[File]
|
||||
val classpathExtra = toArray(toFiles(resources))
|
||||
new Application(org, name, rev, main, components, toBoolean(crossVersioned), classpathExtra)
|
||||
}
|
||||
def getRepositories(m: LabelMap): List[Repository] =
|
||||
|
|
|
|||
|
|
@ -92,13 +92,13 @@ class Launch(val bootDirectory: File, repositories: List[Repository], scalaClass
|
|||
lazy val scalaHome = new File(libDirectory, ScalaDirectoryName)
|
||||
def compilerJar = new File(scalaHome,CompilerModuleName + ".jar")
|
||||
def libraryJar = new File(scalaHome, LibraryModuleName + ".jar")
|
||||
override def classpath = Array(compilerJar, libraryJar)
|
||||
override def classpath = array(compilerJar, libraryJar)
|
||||
def baseDirectories = List(scalaHome)
|
||||
def testLoadClasses = TestLoadScalaClasses
|
||||
def target = new UpdateScala(scalaClassifiers)
|
||||
def failLabel = "Scala " + version
|
||||
def lockFile = updateLockFile
|
||||
def extraClasspath = Array[File]()
|
||||
def extraClasspath = array()
|
||||
|
||||
def app(id: xsbti.ApplicationID): xsbti.AppProvider = new AppProvider(id)
|
||||
|
||||
|
|
@ -113,7 +113,7 @@ class Launch(val bootDirectory: File, repositories: List[Repository], scalaClass
|
|||
def target = new UpdateApp(Application(id))
|
||||
def failLabel = id.name + " " + id.version
|
||||
def lockFile = updateLockFile
|
||||
def mainClasspath = classpath ++ extraClasspath
|
||||
def mainClasspath = fullClasspath
|
||||
def extraClasspath = id.classpathExtra
|
||||
|
||||
lazy val mainClass: Class[T] forSome { type T <: xsbti.AppMain } =
|
||||
|
|
|
|||
|
|
@ -28,4 +28,14 @@ object Pre
|
|||
copy(0, list)
|
||||
arr
|
||||
}
|
||||
/* These exist in order to avoid bringing in dependencies on RichInt and ArrayBuffer, among others. */
|
||||
import java.io.File
|
||||
def concat(a: Array[File], b: Array[File]): Array[File] =
|
||||
{
|
||||
val n = new Array[File](a.length + b.length)
|
||||
java.lang.System.arraycopy(a, 0, n, 0, a.length)
|
||||
java.lang.System.arraycopy(b, 0, n, a.length, b.length)
|
||||
n
|
||||
}
|
||||
def array(files: File*): Array[File] = toArray(files.toList)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,7 +16,8 @@ trait Provider extends NotNull
|
|||
def parentLoader: ClassLoader
|
||||
def lockFile: File
|
||||
|
||||
def classpath = Provider.getJars(baseDirectories)
|
||||
def classpath: Array[File] = Provider.getJars(baseDirectories)
|
||||
def fullClasspath:Array[File] = concat(classpath, extraClasspath)
|
||||
|
||||
def retrieveFailed: Nothing = fail("")
|
||||
def retrieveCorrupt(missing: Iterable[String]): Nothing = fail(": missing " + missing.mkString(", "))
|
||||
|
|
@ -47,8 +48,8 @@ trait Provider extends NotNull
|
|||
}
|
||||
def createLoader =
|
||||
{
|
||||
val fullClasspath = classpath ++ extraClasspath
|
||||
(fullClasspath, new URLClassLoader(Provider.toURLs(fullClasspath), parentLoader) )
|
||||
val full = fullClasspath
|
||||
(full, new URLClassLoader(Provider.toURLs(full), parentLoader) )
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -56,7 +57,7 @@ trait Provider extends NotNull
|
|||
object Provider
|
||||
{
|
||||
def getJars(directories: List[File]): Array[File] = toArray(directories.flatMap(directory => wrapNull(directory.listFiles(JarFilter))))
|
||||
def wrapNull(a: Array[File]): Array[File] = if(a == null) Array() else a
|
||||
def wrapNull(a: Array[File]): Array[File] = if(a == null) new Array[File](0) else a
|
||||
|
||||
object JarFilter extends FileFilter
|
||||
{
|
||||
|
|
|
|||
|
|
@ -92,7 +92,7 @@ final class Update(config: UpdateConfiguration)
|
|||
// the actual module id here is not that important
|
||||
val moduleID = new DefaultModuleDescriptor(createID(SbtOrg, "boot-" + target.tpe, "1.0"), "release", null, false)
|
||||
moduleID.setLastModified(System.currentTimeMillis)
|
||||
moduleID.addConfiguration(new IvyConfiguration(DefaultIvyConfiguration, PUBLIC, "", Array(), true, null))
|
||||
moduleID.addConfiguration(new IvyConfiguration(DefaultIvyConfiguration, PUBLIC, "", new Array(0), true, null))
|
||||
// add dependencies based on which target needs updating
|
||||
target match
|
||||
{
|
||||
|
|
|
|||
|
|
@ -4,11 +4,53 @@ import org.scalacheck._
|
|||
import Prop._
|
||||
import java.io.File
|
||||
|
||||
/** These mainly test that things work in the uncontested case and that no OverlappingFileLockExceptions occur.
|
||||
* There is no real locking testing, just the coordination of locking.*/
|
||||
object LocksTest extends Properties("Locks")
|
||||
{
|
||||
property("Lock in nonexisting directory") =
|
||||
property("Lock in nonexisting directory") = spec {
|
||||
FileUtilities.withTemporaryDirectory { dir =>
|
||||
val lockFile = new File(dir, "doesntexist/lock")
|
||||
Locks(lockFile, new java.util.concurrent.Callable[Boolean] { def call = true })
|
||||
Locks(lockFile, callTrue)
|
||||
}
|
||||
}
|
||||
|
||||
property("Uncontested re-entrant lock") = spec {
|
||||
FileUtilities.withTemporaryDirectory { dir =>
|
||||
val lockFile = new File(dir, "lock")
|
||||
Locks(lockFile, callLocked(lockFile)) &&
|
||||
Locks(lockFile, callLocked(lockFile))
|
||||
}
|
||||
}
|
||||
|
||||
property("Uncontested double lock") = spec {
|
||||
FileUtilities.withTemporaryDirectory { dir =>
|
||||
val lockFileA = new File(dir, "lockA")
|
||||
val lockFileB = new File(dir, "lockB")
|
||||
Locks(lockFileA, callLocked(lockFileB)) &&
|
||||
Locks(lockFileB, callLocked(lockFileA))
|
||||
}
|
||||
}
|
||||
|
||||
property("Contested single lock") = spec {
|
||||
FileUtilities.withTemporaryDirectory { dir =>
|
||||
val lockFile = new File(dir, "lock")
|
||||
forkFold(2000){i => Locks(lockFile, callTrue) }
|
||||
}
|
||||
}
|
||||
|
||||
private def spec(f: => Boolean): Prop = Prop { _ => Result(if(f) True else False) }
|
||||
|
||||
private def call[T](impl: => T) = new java.util.concurrent.Callable[T] { def call = impl }
|
||||
private def callLocked(lockFile: File) = call { Locks(lockFile, callTrue) }
|
||||
private lazy val callTrue = call { true }
|
||||
|
||||
private def forkFold(n: Int)(impl: Int => Boolean): Boolean =
|
||||
(true /: forkWait(n)(impl))(_ && _)
|
||||
private def forkWait(n: Int)(impl: Int => Boolean): Iterable[Boolean] =
|
||||
{
|
||||
import scala.concurrent.ops.future
|
||||
val futures = (0 until n).map { i => future { impl(i) } }
|
||||
futures.toList.map(_())
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,6 @@
|
|||
package xsbt.boot
|
||||
|
||||
import java.io.File
|
||||
import org.scalacheck._
|
||||
|
||||
object PreTest extends Properties("Pre")
|
||||
|
|
@ -17,6 +18,11 @@ object PreTest extends Properties("Pre")
|
|||
property("toBoolean") = Prop.forAll( (s: String) => trap(toBoolean(s)) == trap(java.lang.Boolean.parseBoolean(s)) )
|
||||
property("toArray") = Prop.forAll( (list: List[Int]) => list.toArray deepEquals toArray(list) )
|
||||
property("toArray") = Prop.forAll( (list: List[String]) => list.toArray deepEquals toArray(list) )
|
||||
property("concat") = Prop.forAll(genFiles, genFiles) { (a: Array[File], b: Array[File]) => (a ++ b) sameElements concat(a, b) }
|
||||
property("array") = Prop.forAll(genFiles) { (a: Array[File]) => array(a.toList : _*) sameElements Array(a: _*) }
|
||||
|
||||
implicit lazy val arbFile: Arbitrary[File] = Arbitrary { for(i <- Arbitrary.arbitrary[Int] ) yield new File(i.toString) }
|
||||
implicit lazy val genFiles: Gen[Array[File]] = Arbitrary.arbitrary[Array[File]]
|
||||
|
||||
def trap[T](t: => T): Option[T] = try { Some(t) } catch { case e: Exception => None }
|
||||
}
|
||||
Loading…
Reference in New Issue