cleanup to use Path.getFiles and Path.getURLs (reduces jar size by 20k)

This commit is contained in:
Mark Harrah 2010-03-28 18:54:31 -04:00
parent 93302621ec
commit ed73f1f647
15 changed files with 53 additions and 50 deletions

View File

@ -11,8 +11,8 @@ import scala.collection.mutable.{HashSet, ListBuffer}
object ClasspathUtilities
{
def toClasspath(finder: PathFinder): Array[URL] = toClasspath(finder.get)
def toClasspath(paths: Iterable[Path]): Array[URL] = paths.map(_.asURL).toSeq.toArray
def toClasspath(finder: PathFinder): Array[URL] = finder.getURLs
def toClasspath(paths: Iterable[Path]): Array[URL] = Path.getURLs(paths)
def toLoader(finder: PathFinder): ClassLoader = toLoader(finder.get)
def toLoader(finder: PathFinder, parent: ClassLoader): ClassLoader = toLoader(finder.get, parent)
def toLoader(paths: Iterable[Path]): ClassLoader = new URLClassLoader(toClasspath(paths), rootLoader)
@ -55,7 +55,7 @@ object ClasspathUtilities
/** Returns all entries in 'classpath' that correspond to a compiler plugin.*/
private[sbt] def compilerPlugins(classpath: Iterable[Path]): Iterable[File] =
{
val loader = new URLClassLoader(classpath.map(_.asURL).toList.toArray)
val loader = new URLClassLoader(Path.getURLs(classpath))
wrap.Wrappers.toList(loader.getResources("scalac-plugin.xml")).flatMap(asFile(true))
}
/** Converts the given URL to a File. If the URL is for an entry in a jar, the File for the jar is returned. */

View File

@ -17,14 +17,13 @@ sealed abstract class CompilerCore
apply(label, sources, classpath, outputDirectory, scalaOptions, Nil, CompileOrder.Mixed, log)
final def apply(label: String, sources: Iterable[Path], classpath: Iterable[Path], outputDirectory: Path, scalaOptions: Seq[String], javaOptions: Seq[String], order: CompileOrder.Value, log: Logger): Option[String] =
{
def filteredSources(extension: String) = sources.filter(_.asFile.getName.endsWith(extension))
def fileSet(sources: Iterable[Path]) = Set() ++ sources.map(_.asFile)
def filteredSources(extension: String) = sources.filter(_.name.endsWith(extension))
def process(label: String, sources: Iterable[_], act: => Unit) =
() => if(sources.isEmpty) log.debug("No " + label + " sources.") else act
val javaSources = fileSet(filteredSources(".java"))
val scalaSources = fileSet( if(order == CompileOrder.Mixed) sources else filteredSources(".scala") )
val classpathSet = fileSet(classpath)
val javaSources = Path.getFiles(filteredSources(".java"))
val scalaSources = Path.getFiles( if(order == CompileOrder.Mixed) sources else filteredSources(".scala") )
val classpathSet = Path.getFiles(classpath)
val scalaCompile = process("Scala", scalaSources, processScala(scalaSources, classpathSet, outputDirectory.asFile, scalaOptions, log) )
val javaCompile = process("Java", javaSources, processJava(javaSources, classpathSet, outputDirectory.asFile, javaOptions, log))
doCompile(label, sources, outputDirectory, order, log)(javaCompile, scalaCompile)
@ -119,7 +118,7 @@ final class Console(compiler: AnalyzingCompiler) extends NotNull
apply(classpath, "", log)
def apply(classpath: Iterable[Path], initialCommands: String, log: Logger): Option[String] =
{
def console0 = compiler.console(Set() ++ classpath.map(_.asFile), initialCommands, log)
def console0 = compiler.console(Path.getFiles(classpath), initialCommands, log)
JLine.withJLine( Run.executeTrapExit(console0, log) )
}
}

View File

@ -111,7 +111,7 @@ abstract class BasicScalaProject extends ScalaProject with BasicDependencyProjec
* sbt.*/
override final def initializeDirectories()
{
FileUtilities.createDirectories(directoriesToCreate.map(_.asFile), log) match
FileUtilities.createDirectories(directoriesToCreate, log) match
{
case Some(errorMessage) => log.error("Could not initialize directory structure: " + errorMessage)
case None => log.success("Successfully initialized directory structure.")
@ -166,7 +166,7 @@ abstract class BasicScalaProject extends ScalaProject with BasicDependencyProjec
protected def testUnmanagedClasspath = testCompilePath +++ testResourcesOutputPath +++ testDependencies.scalaCompiler +++ runUnmanagedClasspath
/** @deprecated Use `mainDependencies.scalaJars`*/
@deprecated protected final def scalaJars: Iterable[File] = mainDependencies.scalaJars.get.map(_.asFile)
@deprecated protected final def scalaJars: Iterable[File] = mainDependencies.scalaJars.getFiles
/** An analysis of the jar dependencies of the main Scala sources. It is only valid after main source compilation.
* See the LibraryDependencies class for details. */
final def mainDependencies = new LibraryDependencies(this, mainCompileConditional)
@ -379,7 +379,7 @@ abstract class BasicWebScalaProject extends BasicScalaProject with WebScalaProje
def contextPath = jettyContextPath
def classpathName = "test"
def parentLoader = buildScalaInstance.loader
def scanDirectories = p.scanDirectories.map(_.asFile)
def scanDirectories = Path.getFiles(p.scanDirectories).toSeq
def scanInterval = p.scanInterval
def port = jettyPort
def log = p.log
@ -509,17 +509,17 @@ object BasicWebScalaProject
final class LibraryDependencies(project: Project, conditional: CompileConditional) extends NotNull
{
/** Library jars located in unmanaged or managed dependency paths.*/
def libraries: PathFinder = pathFinder(snapshot.libraries)
def libraries: PathFinder = Path.finder(snapshot.libraries)
/** Library jars located outside of the project.*/
def external: PathFinder = pathFinder(snapshot.external)
def external: PathFinder = Path.finder(snapshot.external)
/** The Scala library jar.*/
def scalaLibrary: PathFinder = pathFinder(snapshot.scalaLibrary)
def scalaLibrary: PathFinder = Path.finder(snapshot.scalaLibrary)
/** The Scala compiler jar.*/
def scalaCompiler: PathFinder = pathFinder(snapshot.scalaCompiler)
def scalaCompiler: PathFinder = Path.finder(snapshot.scalaCompiler)
/** All jar dependencies.*/
def all: PathFinder = pathFinder(snapshot.all)
def all: PathFinder = Path.finder(snapshot.all)
/** The Scala library and compiler jars.*/
def scalaJars: PathFinder = pathFinder(snapshot.scalaJars)
def scalaJars: PathFinder = Path.finder(snapshot.scalaJars)
/** Returns an object that has all analyzed dependency information frozen at the time of this method call. */
def snapshot = new Dependencies
@ -538,8 +538,6 @@ final class LibraryDependencies(project: Project, conditional: CompileConditiona
def external = externalNoScala
def libraries = librariesNoScala
}
private def pathFinder(it: => Iterable[File]) = Path.lazyPathFinder(it.map(Path.fromFile))
}
private object LibraryDependencies
{

View File

@ -7,22 +7,22 @@ import java.io.{File, Writer}
object DotGraph
{
private def fToString(roots: Iterable[File]): (File => String) =
(x: File) => sourceToString(roots, x)
def sources(analysis: BasicCompileAnalysis, outputDirectory: Path, sourceRoots: Iterable[Path], log: Logger) =
{
val roots = sourceRoots.toList.map(_.asFile)
val toString = (x: File) => sourceToString(roots, x)
val toString = fToString(Path.getFiles(sourceRoots))
apply(analysis, outputDirectory, toString, toString, log)
}
def packages(analysis: BasicCompileAnalysis, outputDirectory: Path, sourceRoots: Iterable[Path], log: Logger) =
{
val roots = sourceRoots.toList.map(_.asFile)
val packageOnly = (path: String) =>
{
val last = path.lastIndexOf(File.separatorChar)
val packagePath = (if(last > 0) path.substring(0, last) else path).trim
if(packagePath.isEmpty) "" else packagePath.replace(File.separatorChar, '.')
}
val toString = packageOnly compose ((x: File) => sourceToString(roots, x))
val toString = packageOnly compose fToString(Path.getFiles(sourceRoots))
apply(analysis, outputDirectory, toString, toString, log)
}
def apply(analysis: BasicCompileAnalysis, outputDirectory: Path, sourceToString: File => String, externalToString: File => String, log: Logger) =
@ -57,7 +57,7 @@ object DotGraph
generateGraph(BasicAnalysis.ExternalDependenciesFileName, "externalDependencies", analysis.allExternalDependencies,
externalToString, srcToString)
}
def sourceToString(roots: List[File], source: File) =
def sourceToString(roots: Iterable[File], source: File) =
{
val rawName = relativized(roots, source).trim
if(rawName.endsWith(".scala"))
@ -65,7 +65,7 @@ object DotGraph
else
rawName
}
private def relativized(roots: List[File], path: File): String =
private def relativized(roots: Iterable[File], path: File): String =
{
val relativized = roots.flatMap(root => Path.relativize(root, path))
val shortest = (Int.MaxValue /: relativized)(_ min _.length)

View File

@ -325,7 +325,7 @@ object FileUtilities
}
}
/** Creates directories at the given locations.*/
def createDirectories(d: Seq[Path], log: Logger): Option[String] = createDirectories(d.toList.map(_.asFile), log)
def createDirectories(d: Iterable[Path], log: Logger): Option[String] = createDirectories(Path.getFiles(d).toList, log)
/** Creates directories at the given locations.*/
def createDirectories(d: List[File], log: Logger): Option[String] =
d match
@ -595,7 +595,7 @@ object FileUtilities
* If it is true, each file in <code>files</code> is logged at the <code>info</code> level.
* If it is false, the <code>debug</code> level is used.*/
def clean(files: Iterable[Path], quiet: Boolean, log: Logger): Option[String] =
deleteFiles(files.map(_.asFile), quiet, log)
deleteFiles(Path.getFiles(files), quiet, log)
private def deleteFiles(files: Iterable[File], quiet: Boolean, log: Logger): Option[String] =
((None: Option[String]) /: files)( (result, file) => result orElse delete(file, quiet, log))

View File

@ -6,6 +6,7 @@ package sbt
import Path._
import FileUtilities.wrapNull
import java.io.File
import java.net.URL
import scala.collection.mutable.{Set, HashSet}
/** A Path represents a file in a project.
@ -240,6 +241,12 @@ object Path
def fromFile(file: String): Path = fromFile(new File(file))
def fromFile(file: File): Path = new FilePath(file)
def fromFiles(files: Iterable[File]): Iterable[Path] = files.map(fromFile)
// done this way because collection.Set.map returns Iterable that is Set underneath, so no need to create a new set
def mapSet[T](files: Iterable[Path])(f: Path => T): scala.collection.immutable.Set[T] =
files.map(f) match { case s: scala.collection.immutable.Set[T] => s; case x => scala.collection.immutable.Set() ++ x }
def getFiles(files: Iterable[Path]): scala.collection.immutable.Set[File] = mapSet(files)(_.asFile)
def getURLs(files: Iterable[Path]): Array[URL] = files.map(_.asURL).toSeq.toArray
}
/** A path finder constructs a set of paths. The set is evaluated by a call to the <code>get</code>
@ -287,9 +294,11 @@ sealed abstract class PathFinder extends NotNull
}
final def filter(f: Path => Boolean): PathFinder = Path.lazyPathFinder(get.filter(f))
final def flatMap(f: Path => PathFinder): PathFinder = Path.lazyPathFinder(get.flatMap(p => f(p).get))
final def getFiles: scala.collection.Set[File] = Set( get.map(_.asFile).toSeq : _*)
final def getPaths: scala.collection.Set[String] = Set( get.map(_.absolutePath).toSeq : _*)
final def getRelativePaths: scala.collection.Set[String] = Set( get.map(_.relativePath).toSeq : _*)
final def getURLs: Array[URL] = Path.getURLs(get)
final def getFiles: scala.collection.immutable.Set[File] = Path.getFiles(get)
final def getPaths: scala.collection.immutable.Set[String] = strictMap(_.absolutePath)
final def getRelativePaths: scala.collection.immutable.Set[String] = strictMap(_.relativePath)
final def strictMap[T](f: Path => T): scala.collection.immutable.Set[T] = Path.mapSet(get)(f)
private[sbt] def addTo(pathSet: Set[Path])
final def absString = Path.makeString(get)

View File

@ -71,9 +71,8 @@ class Run(instance: xsbt.ScalaInstance) extends ScalaRun
}
def getLoader(classpath: Iterable[Path], log: Logger) =
{
val classpathURLs = classpath.toSeq.map(_.asURL).toArray
log.debug(" Classpath:\n\t" + classpathURLs.mkString("\n\t"))
new URLClassLoader( classpathURLs, instance.loader)
log.debug(" Classpath:\n\t" + classpath.mkString("\n\t"))
ClasspathUtilities.toLoader(classpath, instance.loader)
}
}

View File

@ -326,7 +326,7 @@ trait WebScalaProject extends ScalaProject
packageTask(descendents(stagedWarPath ##, "*") --- ignore, outputWarPath, options)
@deprecated protected def prepareWebappTask(webappContents: PathFinder, warPath: => Path, classpath: PathFinder, extraJars: => Iterable[File]): Task =
prepareWebappTask(webappContents, warPath, classpath, Path.lazyPathFinder(extraJars.map(Path.fromFile)))
prepareWebappTask(webappContents, warPath, classpath, Path.finder(extraJars))
protected def prepareWebappTask(webappContents: PathFinder, warPath: => Path, classpath: PathFinder, extraJars: PathFinder): Task =
prepareWebappTask(webappContents, warPath, classpath, extraJars, Path.emptyPathFinder)
protected def prepareWebappTask(webappContents: PathFinder, warPath: => Path, classpath: PathFinder, extraJars: PathFinder, ignore: PathFinder): Task =
@ -345,7 +345,7 @@ trait WebScalaProject extends ScalaProject
(copy(webappContents.get, warPath, log).right flatMap { copiedWebapp =>
copy(classesAndResources.get, classesTargetDirectory, log).right flatMap { copiedClasses =>
copyFlat(libs, webLibDirectory, log).right flatMap { copiedLibs =>
copyFilesFlat(extraJars.get.map(_.asFile), webLibDirectory, log).right flatMap { copiedExtraLibs =>
copyFilesFlat(extraJars.getFiles, webLibDirectory, log).right flatMap { copiedExtraLibs =>
{
val toRemove = scala.collection.mutable.HashSet(((warPath ** "*") --- ignore).get.toSeq : _*)
toRemove --= copiedWebapp

View File

@ -7,7 +7,7 @@ object SourceModificationWatch
{
def watchUntil(project: Project, pollDelaySec: Int)(terminationCondition: => Boolean)(onSourcesModified: => Unit)
{
def sourceFiles: Iterable[java.io.File] = sourcesFinder.get.map(_.asFile)
def sourceFiles: Iterable[java.io.File] = sourcesFinder.getFiles
def sourcesFinder: PathFinder = (Path.emptyPathFinder /: project.topologicalSort)(_ +++ _.watchPaths)
def loop(lastCallbackCallTime: Long, previousFileCount: Int)
{

View File

@ -227,6 +227,6 @@ object TestFramework
val interfaceFilter = (name: String) => name.startsWith("org.scalatools.testing.")
val notInterfaceFilter = (name: String) => !interfaceFilter(name)
val dual = new xsbt.DualLoader(filterCompilerLoader, notInterfaceFilter, x => true, getClass.getClassLoader, interfaceFilter, x => false)
new URLClassLoader(classpath.map(_.asURL).toSeq.toArray, dual)
ClasspathUtilities.toLoader(classpath, dual)
}
}

View File

@ -32,9 +32,8 @@ class JettyRunner(configuration: JettyConfiguration) extends ExitHook
def runJetty() =
{
val baseLoader = this.getClass.getClassLoader
val classpathURLs = jettyClasspath.get.map(_.asURL).toSeq
val jettyParentLoader = configuration match { case d: DefaultJettyConfiguration => d.parentLoader; case _ => ClassLoader.getSystemClassLoader }
val jettyLoader: ClassLoader = new java.net.URLClassLoader(classpathURLs.toArray, jettyParentLoader)
val jettyLoader: ClassLoader = ClasspathUtilities.toLoader(jettyClasspath, jettyParentLoader)
val jettyFilter = (name: String) => name.startsWith("org.mortbay.") || name.startsWith("org.eclipse.jetty.")
val notJettyFilter = (name: String) => !jettyFilter(name)

View File

@ -95,7 +95,7 @@ trait WebstartScalaProject extends ScalaProject
import FileUtilities._
val jars = (webstartLibraries +++ webstartExtraLibraries).get.filter(ClasspathUtilities.isArchive)
def process(jars: Iterable[Path]) = for(jar <- jars if jar.asFile.getName.endsWith(".jar")) yield relativize(jar)
def process(jars: Iterable[Path]) = for(jar <- jars if jar.name.endsWith(".jar")) yield relativize(jar)
thread(signAndPack(webstartMainJar :: Nil, webstartOutputDirectory)) { mainJars =>
thread(signAndPack(jars.toList, webstartLibDirectory)) { libJars =>
@ -135,7 +135,7 @@ private object WebstartScalaProject
private def packPath(jar: Path) = appendExtension(jar, ".pack")
private def signOnly(jar: Path, signConfiguration: SignConfiguration, targetDirectory: Path, log: Logger) =
{
val targetJar = targetDirectory / jar.asFile.getName
val targetJar = targetDirectory / jar.name
runOption("sign", targetJar from jar, log) {
log.debug("Signing " + jar)
signAndVerify(jar, signConfiguration, targetJar, log)
@ -162,7 +162,7 @@ private object WebstartScalaProject
* See java.util.jar.Pack200 for more information.*/
private def signAndPack200(jar: Path, signConfiguration: SignConfiguration, targetDirectory: Path, log: Logger) =
{
val signedJar = targetDirectory / jar.asFile.getName
val signedJar = targetDirectory / jar.name
val packedJar = packPath(signedJar)
import signConfiguration._
@ -186,7 +186,7 @@ private object WebstartScalaProject
}
private def pack200Only(jar: Path, targetDirectory: Path, log: Logger) =
{
val targetJar = targetDirectory / jar.asFile.getName
val targetJar = targetDirectory / jar.name
val packedJar = packPath(targetJar)
val packResult =
runOption("pack200", packedJar from jar, log)
@ -202,7 +202,7 @@ private object WebstartScalaProject
}
private def copyJar(jar: Path, targetDirectory: Path, log: Logger) =
{
val targetJar = targetDirectory / jar.asFile.getName
val targetJar = targetDirectory / jar.name
runOption("copy jar", targetJar from jar, log)( FileUtilities.copyFile(jar, targetJar, log) ).toLeft(targetJar :: Nil)
}
/** Writes the XML string 'xmlString' to the file 'outputPath'.*/
@ -245,7 +245,7 @@ private object WebstartScalaProject
}
}
private def jarResource(isMain: Boolean)(jar: Path): WebstartJarResource =
new WebstartJarResource(jar.asFile.getName, jar.relativePathString("/"), isMain)
new WebstartJarResource(jar.name, jar.relativePathString("/"), isMain)
private def jarResources(mainJars: Iterable[Path], libraries: Iterable[Path]): Seq[WebstartJarResource] =
mainJars.map(jarResource(true)).toList ::: libraries.map(jarResource(false)).toList

View File

@ -53,7 +53,6 @@ private object LazyJettyRun${jetty.version} extends JettyRun
case c: DefaultJettyConfiguration =>
import c._
configureDefaultConnector(server, port)
def classpathURLs = classpath.get.map(_.asURL).toSeq
val webapp = new WebAppContext(war.absolutePath, contextPath)
def createLoader =
@ -66,7 +65,7 @@ private object LazyJettyRun${jetty.version} extends JettyRun
urls.foreach(super.addURL)
override def addURL(u: URL) = {}
}
new SbtWebAppLoader(classpathURLs)
new SbtWebAppLoader(classpath.getURLs)
}
def setLoader() = webapp.setClassLoader(createLoader)

View File

@ -40,5 +40,5 @@ class ArtifactTest(info: ProjectInfo) extends DefaultProject(info)
def check0 =
try { Class.forName("test.Test", false, loader); None }
catch { case _: ClassNotFoundException | _: NoClassDefFoundError => Some("Dependency not retrieved properly") }
def loader = new java.net.URLClassLoader(compileClasspath.get.map(_.asURL).toSeq.toArray, buildScalaInstance.loader)
def loader = ClasspathUtilities.toLoader(compileClasspath, buildScalaInstance.loader)
}

View File

@ -5,5 +5,5 @@ class TestProject(info: ProjectInfo) extends DefaultProject(info)
lazy val checkFirst = checkTask("First")
lazy val checkSecond = checkTask("Second")
private def checkTask(className: String) = task { doCheck(className); None }
private def doCheck(className: String) = Class.forName(className, false, new URLClassLoader(runClasspath.get.map(_.asURL).toList.toArray))
private def doCheck(className: String) = Class.forName(className, false, new URLClassLoader(runClasspath.getURLs))
}