From 4509428af99f33b024cf1104087b72fa3268f1cb Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Thu, 19 May 2011 22:04:05 -0400 Subject: [PATCH] locking of boot directory can be disabled by with [boot].lock: true in boot.properties --- compile/src/test/scala/WithCompiler.scala | 2 +- ivy/src/test/scala/ComponentManagerTest.scala | 2 +- launch/ConfigurationParser.scala | 5 +++-- launch/Launch.scala | 14 +++++++------- launch/LaunchConfiguration.scala | 4 ++-- launch/Locks.scala | 3 ++- launch/Provider.scala | 5 +++-- .../src/main/java/xsbti/ComponentProvider.java | 1 + 8 files changed, 20 insertions(+), 16 deletions(-) diff --git a/compile/src/test/scala/WithCompiler.scala b/compile/src/test/scala/WithCompiler.scala index a2e727433..33b74f9d0 100644 --- a/compile/src/test/scala/WithCompiler.scala +++ b/compile/src/test/scala/WithCompiler.scala @@ -11,7 +11,7 @@ object WithCompiler { launcher { (launch, log) => withTemporaryDirectory { componentDirectory => - val manager = new ComponentManager(xsbt.boot.Locks, new boot.ComponentProvider(componentDirectory), log) + val manager = new ComponentManager(xsbt.boot.Locks, new boot.ComponentProvider(componentDirectory, true), log) val compiler = new AnalyzingCompiler(ScalaInstance(scalaVersion, launch), manager, log) compiler.newComponentCompiler(log).clearCache(ComponentCompiler.compilerInterfaceID) define(manager, ComponentCompiler.compilerInterfaceSrcID, getResource("CompilerInterface.scala"), getClassResource(classOf[jline.Completor])) diff --git a/ivy/src/test/scala/ComponentManagerTest.scala b/ivy/src/test/scala/ComponentManagerTest.scala index 537361fcb..923304fde 100644 --- a/ivy/src/test/scala/ComponentManagerTest.scala +++ b/ivy/src/test/scala/ComponentManagerTest.scala @@ -77,5 +77,5 @@ object ComponentManagerTest extends Specification private def writeRandomContent(file: File) = IO.write(file, randomString) private def randomString = "asdf" private def withManager[T](f: ComponentManager => T): T = - TestLogger( logger => withTemporaryDirectory { temp => f(new ComponentManager(xsbt.boot.Locks, new xsbt.boot.ComponentProvider(temp), logger)) } ) + TestLogger( logger => withTemporaryDirectory { temp => f(new ComponentManager(xsbt.boot.Locks, new xsbt.boot.ComponentProvider(temp, true), logger)) } ) } \ No newline at end of file diff --git a/launch/ConfigurationParser.scala b/launch/ConfigurationParser.scala index 9546ae8d9..9d38a3196 100644 --- a/launch/ConfigurationParser.scala +++ b/launch/ConfigurationParser.scala @@ -108,8 +108,9 @@ class ConfigurationParser val (enableQuick, m4) = bool(m3, "quick-option", false) val (promptFill, m5) = bool(m4, "prompt-fill", false) val (promptCreate, m6) = id(m5, "prompt-create", "") - check(m6, "label") - BootSetup(dir, props, search, promptCreate, enableQuick, promptFill) + val (lock, m7) = bool(m6, "lock", true) + check(m7, "label") + BootSetup(dir, lock, props, search, promptCreate, enableQuick, promptFill) } def getLogging(m: LabelMap): Logging = check("label", process(m, "level", getLevel)) def getLevel(m: Option[String]) = m.map(LogLevel.apply).getOrElse(new Logging(LogLevel.Info)) diff --git a/launch/Launch.scala b/launch/Launch.scala index 87803cc26..2166ee002 100644 --- a/launch/Launch.scala +++ b/launch/Launch.scala @@ -76,7 +76,7 @@ object Launch 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 +class Launch private[xsbt](val bootDirectory: File, val lockBoot: Boolean, val ivyOptions: IvyOptions) extends xsbti.Launcher { import ivyOptions.{classifiers, repositories} bootDirectory.mkdirs @@ -85,7 +85,7 @@ class Launch private[xsbt](val bootDirectory: File, val ivyOptions: IvyOptions) 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") + val updateLockFile = if(lockBoot) Some(new File(bootDirectory, "sbt.boot.lock")) else None def globalLock: xsbti.GlobalLock = Locks def ivyHome = ivyOptions.ivyHome.orNull @@ -145,7 +145,7 @@ class Launch private[xsbt](val bootDirectory: File, val ivyOptions: IvyOptions) } def newMain(): xsbti.AppMain = mainClass.newInstance - lazy val components = new ComponentProvider(appHome) + lazy val components = new ComponentProvider(appHome, lockBoot) } } } @@ -156,11 +156,11 @@ object Launcher def apply(bootDirectory: File, ivyOptions: IvyOptions): xsbti.Launcher = apply(bootDirectory, ivyOptions, GetLocks.find) def apply(bootDirectory: File, ivyOptions: IvyOptions, locks: xsbti.GlobalLock): xsbti.Launcher = - new Launch(bootDirectory, ivyOptions) { + new Launch(bootDirectory, true, ivyOptions) { override def globalLock = locks } def apply(explicit: LaunchConfiguration): xsbti.Launcher = - new Launch(explicit.boot.directory, explicit.ivyConfiguration) + new Launch(explicit.boot.directory, explicit.boot.lock, explicit.ivyConfiguration) def defaultAppProvider(baseDirectory: File): xsbti.AppProvider = getAppProvider(baseDirectory, Configuration.configurationOnClasspath) def getAppProvider(baseDirectory: File, configLocation: URL): xsbti.AppProvider = { @@ -172,7 +172,7 @@ object Launcher scalaProvider.app(config.app.toID) } } -class ComponentProvider(baseDirectory: File) extends xsbti.ComponentProvider +class ComponentProvider(baseDirectory: File, lockBoot: Boolean) extends xsbti.ComponentProvider { def componentLocation(id: String): File = new File(baseDirectory, id) def component(id: String) = Provider.wrapNull(componentLocation(id).listFiles).filter(_.isFile) @@ -184,7 +184,7 @@ class ComponentProvider(baseDirectory: File) extends xsbti.ComponentProvider else Copy(files.toList, location) } - def lockFile = ComponentProvider.lockFile(baseDirectory) + def lockFile = if(lockBoot) ComponentProvider.lockFile(baseDirectory) else null // null for the Java interface } object ComponentProvider { diff --git a/launch/LaunchConfiguration.scala b/launch/LaunchConfiguration.scala index 6ae540b48..60af928c5 100644 --- a/launch/LaunchConfiguration.scala +++ b/launch/LaunchConfiguration.scala @@ -93,9 +93,9 @@ 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) +final case class BootSetup(directory: File, lock: Boolean, properties: File, search: Search, promptCreate: String, enableQuick: Boolean, promptFill: Boolean) { - def map(f: File => File) = BootSetup(f(directory), f(properties), search, promptCreate, enableQuick, promptFill) + def map(f: File => File) = BootSetup(f(directory), lock, f(properties), search, promptCreate, enableQuick, promptFill) } final case class AppProperty(name: String)(val quick: Option[PropertyInit], val create: Option[PropertyInit], val fill: Option[PropertyInit]) diff --git a/launch/Locks.scala b/launch/Locks.scala index 3a12581ba..f56b7f771 100644 --- a/launch/Locks.scala +++ b/launch/Locks.scala @@ -24,7 +24,8 @@ object GetLocks object Locks extends xsbti.GlobalLock { private[this] val locks = new Cache[File, Unit, GlobalLock]( (f, _) => new GlobalLock(f)) - def apply[T](file: File, action: Callable[T]): T = + def apply[T](file: File, action: Callable[T]): T = if(file eq null) action.call else apply0(file, action) + private[this] def apply0[T](file: File, action: Callable[T]): T = { val lock = synchronized diff --git a/launch/Provider.scala b/launch/Provider.scala index 0b436e295..27ca3c3f5 100644 --- a/launch/Provider.scala +++ b/launch/Provider.scala @@ -17,7 +17,7 @@ trait Provider def target: UpdateTarget def failLabel: String def parentLoader: ClassLoader - def lockFile: File + def lockFile: Option[File] def classpath: Array[File] = Provider.getJars(baseDirectories) def fullClasspath:Array[File] = concat(classpath, extraClasspath) @@ -29,7 +29,8 @@ trait Provider throw new xsbti.RetrieveException(versionString, "Could not retrieve " + failLabel + extra) private def versionString: String = target match { case _: UpdateScala => configuration.scalaVersion; case a: UpdateApp => Value.get(a.id.version) } - val (jars, loader) = Locks(lockFile, new initialize) + val (jars, loader) = Locks(orNull(lockFile), new initialize) + private[this] def orNull[T >: Null](opt: Option[T]): T = opt match { case None => null; case Some(x) => x } private final class initialize extends Callable[(Array[File], ClassLoader)] { def call = diff --git a/launch/interface/src/main/java/xsbti/ComponentProvider.java b/launch/interface/src/main/java/xsbti/ComponentProvider.java index cac3f9a39..81b49bfa3 100644 --- a/launch/interface/src/main/java/xsbti/ComponentProvider.java +++ b/launch/interface/src/main/java/xsbti/ComponentProvider.java @@ -6,5 +6,6 @@ public interface ComponentProvider { public File[] component(String componentID); public void defineComponent(String componentID, File[] components); + // null if locking disabled public File lockFile(); } \ No newline at end of file