From 3c68c20030c5a5c4046f4aa1ef8d13f354556c76 Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Tue, 18 Aug 2009 00:51:08 -0400 Subject: [PATCH] Setup interface project for testing --- ivy/ComponentManager.scala | 45 +++++++++++++++++++++++++++++++++++++ ivy/CustomXmlParser.scala | 2 +- ivy/IvyActions.scala | 24 ++++++++++++++++++++ ivy/IvyConfigurations.scala | 2 ++ ivy/IvyInterface.scala | 15 +++++++++---- ivy/IvyLogger.scala | 2 +- 6 files changed, 84 insertions(+), 6 deletions(-) create mode 100644 ivy/ComponentManager.scala diff --git a/ivy/ComponentManager.scala b/ivy/ComponentManager.scala new file mode 100644 index 000000000..f1d441916 --- /dev/null +++ b/ivy/ComponentManager.scala @@ -0,0 +1,45 @@ +package xsbt + +import java.io.File +import xsbti.Versions + +/** A component manager provides access to the pieces of xsbt that are distributed as components. +* There are two types of components. The first type is compiled subproject jars with their dependencies. +* The second type is a subproject distributed as a source jar so that it can be compiled against a specific +* version of Scala. +* +* The component manager provides services to install and retrieve components to the local repository. +* This is used for source jars so that the compilation need not be repeated for other projects on the same +* machine. +*/ +class ComponentManager(baseDirectory: File, log: IvyLogger) extends NotNull +{ + def location(id: String): File = new File(baseDirectory, id) + def directory(id: String): File = + { + val dir = location(id) + if(!dir.exists) + update(id) + dir + } + private def contents(dir: File): Seq[File] = + { + val fs = dir.listFiles + if(fs == null) Nil else fs + } + def files(id: String): Iterable[File] = + { + val fs = contents(directory(id)) + if(!fs.isEmpty) fs else error("Could not find required component '" + id + "'") + } + def file(id: String): File = + files(id).toList match { + case x :: Nil => x + case xs => error("Expected single file for component '" + id + "', found: " + xs.mkString(", ")) + } + + def update(id: String): Unit = + IvyActions.basicRetrieveLocal(sbtModuleID("manager"), Seq(sbtModuleID(id)), location(id), log) + def sbtModuleID(id: String) = ModuleID("org.scala-tools.sbt", id, Versions.Sbt) + def cache(id: String): Unit = IvyActions.basicPublishLocal(sbtModuleID(id), Nil, files(id), log) +} \ No newline at end of file diff --git a/ivy/CustomXmlParser.scala b/ivy/CustomXmlParser.scala index 6688d8ef7..91ca60a79 100644 --- a/ivy/CustomXmlParser.scala +++ b/ivy/CustomXmlParser.scala @@ -14,7 +14,7 @@ import plugins.repository.Resource import plugins.repository.url.URLResource /** Subclasses the default Ivy file parser in order to provide access to protected methods.*/ -private object CustomXmlParser extends XmlModuleDescriptorParser with NotNull +private[xsbt] object CustomXmlParser extends XmlModuleDescriptorParser with NotNull { import XmlModuleDescriptorParser.Parser class CustomParser(settings: IvySettings) extends Parser(CustomXmlParser, settings) with NotNull diff --git a/ivy/IvyActions.scala b/ivy/IvyActions.scala index ae3fcf6d2..cb7f74b62 100644 --- a/ivy/IvyActions.scala +++ b/ivy/IvyActions.scala @@ -18,6 +18,30 @@ final class UpdateConfiguration(val retrieveDirectory: File, val outputPattern: object IvyActions { + def basicPublishLocal(moduleID: ModuleID, dependencies: Iterable[ModuleID], artifactFiles: Iterable[File], log: IvyLogger) + { + val artifacts = artifactFiles.map(Artifact.defaultArtifact) + val (ivy, local) = basicLocalIvy(log) + val module = new ivy.Module(ModuleConfiguration(moduleID, dependencies, artifacts)) + val srcArtifactPatterns = artifactFiles.map(_.getAbsolutePath) + publish(module, local.name, srcArtifactPatterns, None, None) + } + def basicRetrieveLocal(moduleID: ModuleID, dependencies: Iterable[ModuleID], to: File, log: IvyLogger) + { + val (ivy, local) = basicLocalIvy(log) + val module = new ivy.Module(ModuleConfiguration(moduleID, dependencies, Nil)) + val up = new UpdateConfiguration(to, defaultOutputPattern, false, true) + update(module, up) + } + def defaultOutputPattern = "[artifact]-[revision](-[classifier]).[ext]" + private def basicLocalIvy(log: IvyLogger) = + { + val local = Resolver.defaultLocal + val paths = new IvyPaths(new File("."), None) + val conf = new IvyConfiguration(paths, Seq(local), log) + (new IvySbt(conf), local) + } + /** Clears the Ivy cache, as configured by 'config'. */ def cleanCache(ivy: IvySbt) = ivy.withIvy { _.getSettings.getRepositoryCacheManagers.foreach(_.clean()) } diff --git a/ivy/IvyConfigurations.scala b/ivy/IvyConfigurations.scala index 366917c92..39b7948be 100644 --- a/ivy/IvyConfigurations.scala +++ b/ivy/IvyConfigurations.scala @@ -18,6 +18,8 @@ final class ModuleConfiguration(val module: ModuleID, val dependencies: Iterable } object ModuleConfiguration { + def apply(module: ModuleID, dependencies: Iterable[ModuleID], artifacts: Iterable[Artifact]) = + new ModuleConfiguration(module, dependencies, NodeSeq.Empty, Nil, None, None, artifacts, false) def configurations(explicitConfigurations: Iterable[Configuration], defaultConfiguration: Option[Configuration]) = if(explicitConfigurations.isEmpty) { diff --git a/ivy/IvyInterface.scala b/ivy/IvyInterface.scala index ae89d431b..d31ac00c3 100644 --- a/ivy/IvyInterface.scala +++ b/ivy/IvyInterface.scala @@ -311,15 +311,22 @@ object Artifact def apply(name: String, url: URL): Artifact =Artifact(name, extract(url, defaultType), extract(url, defaultExtension), None, Nil, Some(url)) val defaultExtension = "jar" val defaultType = "jar" - private[this] def extract(url: URL, default: String) = + private[this] def extract(url: URL, default: String): String = extract(url.toString, default) + private[this] def extract(name: String, default: String): String = { - val s = url.toString - val i = s.lastIndexOf('.') + val i = name.lastIndexOf('.') if(i >= 0) - s.substring(i+1) + name.substring(i+1) else default } + def defaultArtifact(file: File) = + { + val name = file.getName + val i = name.lastIndexOf('.') + val base = if(i >= 0) name.substring(0, i) else name + Artifact(name, extract(name, defaultType), extract(name, defaultExtension), None, Nil, Some(file.toURI.toURL)) + } } /* object Credentials diff --git a/ivy/IvyLogger.scala b/ivy/IvyLogger.scala index ff3ad2f19..c58ffd054 100644 --- a/ivy/IvyLogger.scala +++ b/ivy/IvyLogger.scala @@ -5,7 +5,7 @@ package xsbt import org.apache.ivy.util.{Message, MessageLogger} -trait IvyLogger +trait IvyLogger extends NotNull { def info(msg: => String) def debug(msg: => String)