From 988c22c6535aae9901b9944ffa5c7589c65fee92 Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Mon, 11 Apr 2011 00:44:28 -0400 Subject: [PATCH] support reason for retrieving jars in launcher specifically, identify when a Scala version is downloaded for running the application itself --- launch/Cache.scala | 12 ++++++------ launch/ConfigurationParser.scala | 4 ++-- launch/Enumeration.scala | 4 ++-- launch/Find.scala | 2 +- launch/Launch.scala | 13 +++++++------ launch/LaunchConfiguration.scala | 16 ++++++++-------- launch/ListMap.scala | 2 +- launch/Locks.scala | 4 ++-- launch/Provider.scala | 9 +++++---- launch/ResolveValues.scala | 2 +- launch/SimpleReader.scala | 2 +- launch/Update.scala | 16 ++++++++-------- launch/Using.scala | 2 +- .../interface/src/main/java/xsbti/Launcher.java | 1 + 14 files changed, 46 insertions(+), 43 deletions(-) diff --git a/launch/Cache.scala b/launch/Cache.scala index e3d984099..488e5388e 100644 --- a/launch/Cache.scala +++ b/launch/Cache.scala @@ -6,15 +6,15 @@ package xsbt.boot import java.lang.ref.{Reference, SoftReference} import java.util.HashMap -final class Cache[K,V](create: K => V) extends NotNull +final class Cache[K,X,V](create: (K,X) => V) { private[this] val delegate = new HashMap[K,Reference[V]] - def apply(k: K): V = getFromReference(k, delegate.get(k)) - private[this] def getFromReference(k: K, existingRef: Reference[V]) = if(existingRef eq null) newEntry(k) else get(k, existingRef.get) - private[this] def get(k: K, existing: V) = if(existing == null) newEntry(k) else existing - private[this] def newEntry(k: K): V = + def apply(k: K, x: X): V = getFromReference(k, x, delegate.get(k)) + private[this] def getFromReference(k: K, x: X, existingRef: Reference[V]) = if(existingRef eq null) newEntry(k, x) else get(k, x, existingRef.get) + private[this] def get(k: K, x: X, existing: V) = if(existing == null) newEntry(k, x) else existing + private[this] def newEntry(k: K, x: X): V = { - val v = create(k) + val v = create(k, x) Pre.assert(v != null, "Value for key " + k + " was null") delegate.put(k, new SoftReference(v)) v diff --git a/launch/ConfigurationParser.scala b/launch/ConfigurationParser.scala index 34389a9fa..ed84d32c5 100644 --- a/launch/ConfigurationParser.scala +++ b/launch/ConfigurationParser.scala @@ -19,7 +19,7 @@ object ConfigurationParser implicit val readIDs = ids _ } -class ConfigurationParser extends NotNull +class ConfigurationParser { def apply(file: File): LaunchConfiguration = Using(new InputStreamReader(new FileInputStream(file), "UTF-8"))(apply) def apply(s: String): LaunchConfiguration = Using(new StringReader(s))(apply) @@ -191,7 +191,7 @@ class ConfigurationParser extends NotNull } } -sealed trait Line extends NotNull +sealed trait Line final class Labeled(val label: String, val value: Option[String]) extends Line final class Section(val name: String) extends Line object Comment extends Line diff --git a/launch/Enumeration.scala b/launch/Enumeration.scala index cb994f1e9..3e5a6f89d 100644 --- a/launch/Enumeration.scala +++ b/launch/Enumeration.scala @@ -6,7 +6,7 @@ package xsbt.boot import Pre._ import scala.collection.immutable.List -class Enumeration extends NotNull +class Enumeration { def elements: List[Value] = members private lazy val members: List[Value] = @@ -25,6 +25,6 @@ class Enumeration extends NotNull } def value(s: String) = new Value(s, 0) def value(s: String, i: Int) = new Value(s, i) - class Value(override val toString: String, val id: Int) extends NotNull + final class Value(override val toString: String, val id: Int) def toValue(s: String): Value = elements.find(_.toString == s).getOrElse(error("Expected one of " + elements.mkString(",") + " (got: " + s + ")")) } \ No newline at end of file diff --git a/launch/Find.scala b/launch/Find.scala index 459689950..1145b5617 100644 --- a/launch/Find.scala +++ b/launch/Find.scala @@ -9,7 +9,7 @@ import java.net.URI import scala.collection.immutable.List object Find { def apply(config: LaunchConfiguration, currentDirectory: File) = (new Find(config))(currentDirectory) } -class Find(config: LaunchConfiguration) extends NotNull +class Find(config: LaunchConfiguration) { import config.boot.search def apply(currentDirectory: File) = diff --git a/launch/Launch.scala b/launch/Launch.scala index 9b1ce340a..87803cc26 100644 --- a/launch/Launch.scala +++ b/launch/Launch.scala @@ -1,5 +1,5 @@ /* sbt -- Simple Build Tool - * Copyright 2008, 2009, 2010 Mark Harrah + * Copyright 2008, 2009, 2010, 2011 Mark Harrah */ package xsbt.boot @@ -46,7 +46,7 @@ object Launch def run(launcher: xsbti.Launcher)(config: RunConfiguration): xsbti.MainResult = { import config._ - val scalaProvider: xsbti.ScalaProvider = launcher.getScala(scalaVersion) + val scalaProvider: xsbti.ScalaProvider = launcher.getScala(scalaVersion, "(for " + app.name + ")") val appProvider: xsbti.AppProvider = scalaProvider.app(app) val appConfig: xsbti.AppConfiguration = new AppConfiguration(toArray(arguments), workingDirectory, appProvider) @@ -73,15 +73,16 @@ object Launch } } } -final class RunConfiguration(val scalaVersion: String, val app: xsbti.ApplicationID, val workingDirectory: File, val arguments: List[String]) extends NotNull +final class RunConfiguration(val scalaVersion: String, val app: xsbti.ApplicationID, val workingDirectory: File, val arguments: List[String]) import BootConfiguration.{appDirectoryName, baseDirectoryName, ScalaDirectoryName, TestLoadScalaClasses} class Launch private[xsbt](val bootDirectory: File, val ivyOptions: IvyOptions) extends xsbti.Launcher { import ivyOptions.{classifiers, repositories} bootDirectory.mkdirs - private val scalaProviders = new Cache[String, ScalaProvider](new ScalaProvider(_)) - def getScala(version: String): xsbti.ScalaProvider = scalaProviders(version) + private val scalaProviders = new Cache[String, String, ScalaProvider](new ScalaProvider(_, _)) + def getScala(version: String): xsbti.ScalaProvider = getScala(version, "") + def getScala(version: String, reason: String): xsbti.ScalaProvider = scalaProviders(version, reason) lazy val topLoader = (new JNAProvider).loader val updateLockFile = new File(bootDirectory, "sbt.boot.lock") @@ -103,7 +104,7 @@ class Launch private[xsbt](val bootDirectory: File, val ivyOptions: IvyOptions) def lockFile = updateLockFile } - class ScalaProvider(val version: String) extends xsbti.ScalaProvider with Provider + class ScalaProvider(val version: String, override val reason: String) extends xsbti.ScalaProvider with Provider { def launcher: xsbti.Launcher = Launch.this def parentLoader = topLoader diff --git a/launch/LaunchConfiguration.scala b/launch/LaunchConfiguration.scala index 1f5bf7c3f..6ae540b48 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[Repository]) extends NotNull +final case class IvyOptions(ivyHome: Option[File], classifiers: Classifiers, repositories: List[Repository]) sealed trait Value[T] final class Explicit[T](val value: T) extends Value[T] { @@ -43,7 +43,7 @@ object Classifiers { def apply(forScala: List[String], app: List[String]):Classifiers = Classifiers(new Explicit(forScala), new Explicit(app)) } -final case class Application(groupID: String, name: String, version: Value[String], main: String, components: List[String], crossVersioned: Boolean, classpathExtra: Array[File]) extends NotNull +final case class Application(groupID: String, name: String, version: Value[String], main: String, components: List[String], crossVersioned: Boolean, classpathExtra: Array[File]) { def getVersion = Value.get(version) def withVersion(newVersion: Value[String]) = Application(groupID, name, newVersion, main, components, crossVersioned, classpathExtra) @@ -61,7 +61,7 @@ object Application } } -sealed trait Repository extends NotNull +sealed trait Repository object Repository { final case class Maven(id: String, url: URL) extends Repository @@ -82,7 +82,7 @@ object Repository def defaults: List[Repository] = Predefined.elements.map(Predefined.apply).toList } -final case class Search(tpe: Search.Value, paths: List[File]) extends NotNull +final case class Search(tpe: Search.Value, paths: List[File]) object Search extends Enumeration { def none = Search(Current, Nil) @@ -93,17 +93,17 @@ object Search extends Enumeration def apply(s: String, paths: List[File]): Search = Search(toValue(s), paths) } -final case class BootSetup(directory: File, properties: File, search: Search, promptCreate: String, enableQuick: Boolean, promptFill: Boolean) extends NotNull +final case class BootSetup(directory: File, properties: File, search: Search, promptCreate: String, enableQuick: Boolean, promptFill: Boolean) { def map(f: File => File) = BootSetup(f(directory), f(properties), search, promptCreate, enableQuick, promptFill) } -final case class AppProperty(name: String)(val quick: Option[PropertyInit], val create: Option[PropertyInit], val fill: Option[PropertyInit]) extends NotNull +final case class AppProperty(name: String)(val quick: Option[PropertyInit], val create: Option[PropertyInit], val fill: Option[PropertyInit]) -sealed trait PropertyInit extends NotNull +sealed trait PropertyInit final class SetProperty(val value: String) extends PropertyInit final class PromptProperty(val label: String, val default: Option[String]) extends PropertyInit -final class Logging(level: LogLevel.Value) extends NotNull +final class Logging(level: LogLevel.Value) { def log(s: => String, at: LogLevel.Value) = if(level.id <= at.id) stream(at).println("[" + at + "] " + s) def debug(s: => String) = log(s, LogLevel.Debug) diff --git a/launch/ListMap.scala b/launch/ListMap.scala index eac3dfd89..298645fc6 100644 --- a/launch/ListMap.scala +++ b/launch/ListMap.scala @@ -8,7 +8,7 @@ import scala.collection.{Iterable, Iterator} import scala.collection.immutable.List // preserves iteration order -sealed class ListMap[K,V] private(backing: List[(K,V)]) extends Iterable[(K,V)] with NotNull // use Iterable because Traversable.toStream loops +sealed class ListMap[K,V] private(backing: List[(K,V)]) extends Iterable[(K,V)] // use Iterable because Traversable.toStream loops { import ListMap.remove def update(k: K, v: V) = this.+( (k,v) ) diff --git a/launch/Locks.scala b/launch/Locks.scala index 2be63b4e4..3a12581ba 100644 --- a/launch/Locks.scala +++ b/launch/Locks.scala @@ -23,7 +23,7 @@ object GetLocks // gets a file lock by first getting a JVM-wide lock. object Locks extends xsbti.GlobalLock { - private[this] val locks = new Cache[File, GlobalLock](new GlobalLock(_)) + private[this] val locks = new Cache[File, Unit, GlobalLock]( (f, _) => new GlobalLock(f)) def apply[T](file: File, action: Callable[T]): T = { val lock = @@ -31,7 +31,7 @@ object Locks extends xsbti.GlobalLock { file.getParentFile.mkdirs() file.createNewFile() - locks(file.getCanonicalFile) + locks(file.getCanonicalFile, ()) } lock.withLock(action) } diff --git a/launch/Provider.scala b/launch/Provider.scala index 141eb683a..0b436e295 100644 --- a/launch/Provider.scala +++ b/launch/Provider.scala @@ -1,5 +1,5 @@ /* sbt -- Simple Build Tool - * Copyright 2009, 2010 Mark Harrah + * Copyright 2009, 2010, 2011 Mark Harrah */ package xsbt.boot @@ -8,7 +8,7 @@ import java.io.{File, FileFilter} import java.net.{URL, URLClassLoader} import java.util.concurrent.Callable -trait Provider extends NotNull +trait Provider { def configuration: UpdateConfiguration def baseDirectories: List[File] @@ -21,7 +21,8 @@ trait Provider extends NotNull def classpath: Array[File] = Provider.getJars(baseDirectories) def fullClasspath:Array[File] = concat(classpath, extraClasspath) - + + def reason: String = "" def retrieveFailed: Nothing = fail("") def retrieveCorrupt(missing: Iterable[String]): Nothing = fail(": missing " + missing.mkString(", ")) private def fail(extra: String) = @@ -38,7 +39,7 @@ trait Provider extends NotNull (existingJars, existingLoader) else { - val retrieveSuccess = ( new Update(configuration) )(target) + val retrieveSuccess = ( new Update(configuration) )(target, reason) if(retrieveSuccess) { val (newJars, newLoader) = createLoader diff --git a/launch/ResolveValues.scala b/launch/ResolveValues.scala index 5e1d19dc0..98f84ad87 100644 --- a/launch/ResolveValues.scala +++ b/launch/ResolveValues.scala @@ -22,7 +22,7 @@ object ResolveValues } import ResolveValues.{readProperties, trim} -final class ResolveValues(conf: LaunchConfiguration) extends NotNull +final class ResolveValues(conf: LaunchConfiguration) { private def propertiesFile = conf.boot.properties private lazy val properties = readProperties(propertiesFile) diff --git a/launch/SimpleReader.scala b/launch/SimpleReader.scala index 74e2be402..7f1f96c51 100644 --- a/launch/SimpleReader.scala +++ b/launch/SimpleReader.scala @@ -4,7 +4,7 @@ package xsbt.boot import jline.ConsoleReader -abstract class JLine extends NotNull +abstract class JLine { protected[this] val reader: ConsoleReader def readLine(prompt: String) = JLine.withJLine { unsynchronizedReadLine(prompt) } diff --git a/launch/Update.scala b/launch/Update.scala index ba32f294a..6a44c56c9 100644 --- a/launch/Update.scala +++ b/launch/Update.scala @@ -1,5 +1,5 @@ /* sbt -- Simple Build Tool - * Copyright 2009, 2010 Mark Harrah + * Copyright 2009, 2010, 2011 Mark Harrah */ package xsbt.boot @@ -62,16 +62,16 @@ final class Update(config: UpdateConfiguration) private lazy val ivyLockFile = new File(settings.getDefaultIvyUserDir, ".sbt.ivy.lock") /** The main entry point of this class for use by the Update module. It runs Ivy */ - def apply(target: UpdateTarget): Boolean = + def apply(target: UpdateTarget, reason: String): Boolean = { Message.setDefaultLogger(new SbtIvyLogger(logWriter)) - val action = new Callable[Boolean] { def call = lockedApply(target) } + val action = new Callable[Boolean] { def call = lockedApply(target, reason) } Locks(ivyLockFile, action) } - private def lockedApply(target: UpdateTarget) = + private def lockedApply(target: UpdateTarget, reason: String) = { ivy.pushContext() - try { update(target); true } + try { update(target, reason); true } catch { case e: Exception => @@ -87,7 +87,7 @@ final class Update(config: UpdateConfiguration) } } /** Runs update for the specified target (updates either the scala or appliciation jars for building the project) */ - private def update(target: UpdateTarget) + private def update(target: UpdateTarget, reason: String) { import IvyConfiguration.Visibility.PUBLIC // the actual module id here is not that important @@ -100,13 +100,13 @@ final class Update(config: UpdateConfiguration) case u: UpdateScala => addDependency(moduleID, ScalaOrg, CompilerModuleName, scalaVersion, "default;optional", u.classifiers) addDependency(moduleID, ScalaOrg, LibraryModuleName, scalaVersion, "default", u.classifiers) - System.out.println("Getting Scala " + scalaVersion + " ...") + System.out.println("Getting Scala " + scalaVersion + " " + reason + "...") case u: UpdateApp => val app = u.id val resolvedName = if(app.crossVersioned) app.name + "_" + scalaVersion else app.name addDependency(moduleID, app.groupID, resolvedName, app.getVersion, "default(compile)", u.classifiers) excludeScala(moduleID) - System.out.println("Getting " + app.groupID + " " + resolvedName + " " + app.getVersion + " ...") + System.out.println("Getting " + app.groupID + " " + resolvedName + " " + app.getVersion + " " + reason + "...") } update(moduleID, target) } diff --git a/launch/Using.scala b/launch/Using.scala index 045202b0d..e2c728206 100644 --- a/launch/Using.scala +++ b/launch/Using.scala @@ -5,7 +5,7 @@ package xsbt.boot import java.io.{Closeable, File, FileInputStream, FileOutputStream, InputStream, OutputStream} -object Using extends NotNull +object Using { def apply[R <: Closeable,T](create: R)(f: R => T): T = withResource(create)(f) def withResource[R <: Closeable,T](r: R)(f: R => T): T = try { f(r) } finally { r.close() } diff --git a/launch/interface/src/main/java/xsbti/Launcher.java b/launch/interface/src/main/java/xsbti/Launcher.java index 6cd2b0598..a6008fe57 100644 --- a/launch/interface/src/main/java/xsbti/Launcher.java +++ b/launch/interface/src/main/java/xsbti/Launcher.java @@ -6,6 +6,7 @@ public interface Launcher { public static final int InterfaceVersion = 1; public ScalaProvider getScala(String version); + public ScalaProvider getScala(String version, String reason); public ClassLoader topLoader(); public GlobalLock globalLock(); public File bootDirectory();