diff --git a/ivy/IvyActions.scala b/ivy/IvyActions.scala index 5c4ddf2fb..58a6571c8 100644 --- a/ivy/IvyActions.scala +++ b/ivy/IvyActions.scala @@ -1,6 +1,7 @@ package sbt import java.io.File +import scala.xml.NodeSeq import org.apache.ivy.{core, plugins, util, Ivy} import core.cache.DefaultRepositoryCacheManager @@ -35,15 +36,18 @@ object IvyActions } /** Clears the Ivy cache, as configured by 'config'. */ - def cleanCache(ivy: IvySbt) = ivy.withIvy { _.getSettings.getRepositoryCacheManagers.foreach(_.clean()) } + def cleanCache(ivy: IvySbt) = ivy.withIvy { iv => + iv.getSettings.getResolutionCacheManager.clean() + iv.getSettings.getRepositoryCacheManagers.foreach(_.clean()) + } /** Creates a Maven pom from the given Ivy configuration*/ - def makePom(module: IvySbt#Module, extraDependencies: Iterable[ModuleID], configurations: Option[Iterable[Configuration]], output: File) + def makePom(module: IvySbt#Module, extraDependencies: Iterable[ModuleID], configurations: Option[Iterable[Configuration]], extra: NodeSeq, output: File) { module.withModule { (ivy, md, default) => addLateDependencies(ivy, md, default, extraDependencies) val pomModule = keepConfigurations(md, configurations) - PomModuleDescriptorWriter.write(pomModule, DefaultConfigurationMapping, output) + (new PomWriter).write(pomModule, extra, output) module.logger.info("Wrote " + output.getAbsolutePath) } } @@ -132,21 +136,4 @@ object IvyActions if(resolveReport.hasError) error(Set(resolveReport.getAllProblemMessages.toArray: _*).mkString("\n")) } -} - -private object DefaultConfigurationMapping extends PomModuleDescriptorWriter.ConfigurationScopeMapping(new java.util.HashMap) -{ - override def getScope(confs: Array[String]) = - { - Configurations.defaultMavenConfigurations.find(conf => confs.contains(conf.name)) match - { - case Some(conf) => conf.name - case None => - if(confs.isEmpty || confs(0) == Configurations.Default.name) - null - else - confs(0) - } - } - override def isOptional(confs: Array[String]) = confs.isEmpty || (confs.length == 1 && confs(0) == Configurations.Optional.name) } \ No newline at end of file diff --git a/ivy/IvyCache.scala b/ivy/IvyCache.scala index c23218483..9e7b25b80 100644 --- a/ivy/IvyCache.scala +++ b/ivy/IvyCache.scala @@ -81,7 +81,7 @@ object IvyCache /** A minimal Ivy setup with only a local resolver and the current directory as the base directory.*/ private def basicLocalIvy(lock: Option[xsbti.GlobalLock], log: IvyLogger) = { - val local = Resolver.defaultLocal + val local = Resolver.defaultLocal(None) val paths = new IvyPaths(new File("."), None) val conf = new InlineIvyConfiguration(paths, Seq(local), Nil, lock, log) (new IvySbt(conf), local) diff --git a/ivy/IvyConfigurations.scala b/ivy/IvyConfigurations.scala index dbec791d6..83b272c6a 100644 --- a/ivy/IvyConfigurations.scala +++ b/ivy/IvyConfigurations.scala @@ -7,19 +7,29 @@ import java.io.File import scala.xml.NodeSeq final class IvyPaths(val baseDirectory: File, val cacheDirectory: Option[File]) extends NotNull - +{ + def withBase(newBaseDirectory: File) = new IvyPaths(newBaseDirectory, cacheDirectory) +} sealed trait IvyConfiguration extends NotNull { + type This <: IvyConfiguration def lock: Option[xsbti.GlobalLock] def baseDirectory: File def log: IvyLogger + def withBase(newBaseDirectory: File): This } final class InlineIvyConfiguration(val paths: IvyPaths, val resolvers: Seq[Resolver], val moduleConfigurations: Seq[ModuleConfiguration], val lock: Option[xsbti.GlobalLock], val log: IvyLogger) extends IvyConfiguration { + type This = InlineIvyConfiguration def baseDirectory = paths.baseDirectory + def withBase(newBase: File) = new InlineIvyConfiguration(paths.withBase(newBase), resolvers, moduleConfigurations, lock, log) } final class ExternalIvyConfiguration(val baseDirectory: File, val file: File, val lock: Option[xsbti.GlobalLock], val log: IvyLogger) extends IvyConfiguration +{ + type This = ExternalIvyConfiguration + def withBase(newBase: File) = new ExternalIvyConfiguration(newBase, file, lock, log) +} object IvyConfiguration { diff --git a/ivy/IvyInterface.scala b/ivy/IvyInterface.scala index 213e959e2..66a831e62 100644 --- a/ivy/IvyInterface.scala +++ b/ivy/IvyInterface.scala @@ -167,7 +167,7 @@ object Resolver def withDefaultResolvers(userResolvers: Seq[Resolver], scalaTools: Boolean): Seq[Resolver] = withDefaultResolvers(userResolvers, true, scalaTools) def withDefaultResolvers(userResolvers: Seq[Resolver], mavenCentral: Boolean, scalaTools: Boolean): Seq[Resolver] = - Seq(Resolver.defaultLocal) ++ + Seq(Resolver.defaultLocal(None)) ++ userResolvers ++ single(DefaultMavenRepository, mavenCentral)++ single(ScalaToolsReleases, scalaTools) @@ -266,10 +266,11 @@ object Resolver def userRoot = System.getProperty("user.home") def userMavenRoot = userRoot + "/.m2/repository/" def userIvyRoot = userRoot + "/.ivy2/" + private def userIvyRootFile = new File(userIvyRoot) - def defaultLocal = defaultUserFileRepository("local") - def defaultShared = defaultUserFileRepository("shared") - def defaultUserFileRepository(id: String) = file(id, new File(userIvyRoot, id))(defaultIvyPatterns) + def defaultLocal(ivyHome: Option[File]) = defaultUserFileRepository(ivyHome, "local") + def defaultShared(ivyHome: Option[File]) = defaultUserFileRepository(ivyHome, "shared") + def defaultUserFileRepository(ivyHome: Option[File], id: String) = file(id, new File(ivyHome.getOrElse(userIvyRootFile), id))(defaultIvyPatterns) def defaultIvyPatterns = { val pList = List(localBasePattern) diff --git a/ivy/MakePom.scala b/ivy/MakePom.scala new file mode 100644 index 000000000..06a515672 --- /dev/null +++ b/ivy/MakePom.scala @@ -0,0 +1,104 @@ +// based on Ivy's PomModuleDescriptorWriter, which is Apache Licensed, Version 2.0 +// http://www.apache.org/licenses/LICENSE-2.0 + +package sbt; + +import java.io.{BufferedWriter, File, OutputStreamWriter, FileOutputStream} +import scala.xml.{Node, NodeSeq, XML} + +import org.apache.ivy.{core, Ivy} +import core.module.{descriptor, id} +import descriptor.{DependencyDescriptor, License, ModuleDescriptor} +import id.ModuleRevisionId + +class PomWriter +{ + def encoding = "UTF-8" + def write(module: ModuleDescriptor, extra: NodeSeq, output: File): Unit = write(toPom(module, extra), output) + def write(node: Node, output: File) + { + output.getParentFile.mkdirs() + val out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(output), encoding)) + try { XML.write(out, node, encoding, true, null) } + finally { out.close() } + } + + def toPom(module: ModuleDescriptor, extra: NodeSeq): Node = + ( + 4.0.0 + { makeModuleID(module) } + { extra } + { makeDependencies(module) } + + ) + + def makeModuleID(module: ModuleDescriptor): NodeSeq = + { + val mrid = moduleDescriptor(module) + val a: NodeSeq = + ({ mrid.getOrganisation } + { mrid.getName } + { packaging(mrid) }) + val b: NodeSeq = + ( (description(module.getDescription) ++ + homePage(module.getHomePage) ++ + revision(mrid.getRevision) ++ + licenses(module.getLicenses)) : NodeSeq ) + a ++ b + } + + def description(d: String) = if((d eq null) || d.isEmpty) NodeSeq.Empty else {d} + def licenses(ls: Array[License]) = if(ls == null || ls.isEmpty) NodeSeq.Empty else {ls.map(license)} + def license(l: License) = + + {l.getName} + {l.getUrl} + jar + + def homePage(homePage: String) = if(homePage eq null) NodeSeq.Empty else {homePage} + def revision(version: String) = if(version ne null) {version} else NodeSeq.Empty + def packaging(module: ModuleRevisionId) = "jar"//module.getDefaultArtifact.getExt + + def makeDependencies(module: ModuleDescriptor): NodeSeq = + { + val dependencies = module.getDependencies + if(dependencies.isEmpty) NodeSeq.Empty + else + + { dependencies.map(makeDependency) } + + } + + def makeDependency(dependency: DependencyDescriptor): NodeSeq = + { + val mrid = dependency.getDependencyRevisionId + + {mrid.getOrganisation} + {mrid.getName} + {mrid.getRevision} + { scope(dependency)} + { optional(dependency) } + + } + + def scope(dependency: DependencyDescriptor): NodeSeq = + scope(getScope(dependency.getModuleConfigurations)) + def scope(scope: String): NodeSeq = if(scope ne null) {scope} else NodeSeq.Empty + def optional(dependency: DependencyDescriptor) = + if(isOptional(dependency.getModuleConfigurations)) true else NodeSeq.Empty + def moduleDescriptor(module: ModuleDescriptor) = module.getModuleRevisionId + + def getScope(confs: Array[String]) = + { + Configurations.defaultMavenConfigurations.find(conf => confs.contains(conf.name)) match + { + case Some(conf) => conf.name + case None => + if(confs.isEmpty || confs(0) == Configurations.Default.name) + null + else + confs(0) + } + } + def isOptional(confs: Array[String]) = confs.isEmpty || (confs.length == 1 && confs(0) == Configurations.Optional.name) +}