From 40e1904615b061a6b1e5a505ce8fcf30afbbe4e2 Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Thu, 14 Apr 2011 07:32:42 -0400 Subject: [PATCH] direct Artifact->File map, removing source patterns build and publish main sources and docs by default control built-in artifacts with 'publish-artifact' // disable publishing docs publishArtifact in (Compile,packageDoc) := false // enable publishing test jar, docs, and sources publishArtifact in Test := true --- ivy/ArtifactName.scala | 17 --------------- ivy/Ivy.scala | 18 ++++++++++------ ivy/IvyActions.scala | 48 ++++++++++++++++++++++++++++-------------- ivy/IvyInterface.scala | 6 ++++++ 4 files changed, 49 insertions(+), 40 deletions(-) delete mode 100644 ivy/ArtifactName.scala diff --git a/ivy/ArtifactName.scala b/ivy/ArtifactName.scala deleted file mode 100644 index beb2b5cac..000000000 --- a/ivy/ArtifactName.scala +++ /dev/null @@ -1,17 +0,0 @@ -/* sbt -- Simple Build Tool - * Copyright 2011 Mark Harrah - */ -package sbt - -final case class ArtifactName(base: String, version: String, config: String, tpe: String, ext: String, cross: String) -object ArtifactName -{ - def show(name: ArtifactName) = - { - import name._ - val confStr = if(config.isEmpty || config == "compile") "" else "-" + config - val tpeStr = if(tpe.isEmpty) "" else "-" + tpe - val addCross = if(cross.isEmpty) "" else "_" + cross - base + addCross + "-" + version + confStr + tpeStr + "." + ext - } -} \ No newline at end of file diff --git a/ivy/Ivy.scala b/ivy/Ivy.scala index 22d52a6a6..261706f20 100644 --- a/ivy/Ivy.scala +++ b/ivy/Ivy.scala @@ -12,7 +12,7 @@ import java.util.{Collection, Collections} import org.apache.ivy.{core, plugins, util, Ivy} import core.IvyPatternHelper import core.cache.{CacheMetadataOptions, DefaultRepositoryCacheManager} -import core.module.descriptor.{DefaultArtifact, DefaultDependencyArtifactDescriptor, MDArtifact} +import core.module.descriptor.{Artifact => IArtifact, DefaultArtifact, DefaultDependencyArtifactDescriptor, MDArtifact} import core.module.descriptor.{DefaultDependencyDescriptor, DefaultModuleDescriptor, DependencyDescriptor, ModuleDescriptor} import core.module.id.{ArtifactId,ModuleId, ModuleRevisionId} import core.resolve.IvyNode @@ -290,7 +290,7 @@ private object IvySbt private def toIvyArtifact(moduleID: ModuleDescriptor, a: Artifact, configurations: Iterable[String]): MDArtifact = { - val artifact = new MDArtifact(moduleID, a.name, a.`type`, a.extension, null, extra(a)) + val artifact = new MDArtifact(moduleID, a.name, a.`type`, a.extension, null, extra(a, false)) configurations.foreach(artifact.addConfiguration) artifact } @@ -301,7 +301,7 @@ private object IvySbt } private[sbt] def javaMap(m: Map[String,String], unqualify: Boolean = false) = { - val map = m map { case (k, v) => (k.stripPrefix("e:"), v) } + val map = if(unqualify) m map { case (k, v) => (k.stripPrefix("e:"), v) } else m if(map.isEmpty) null else scala.collection.JavaConversions.asJavaMap(map) } @@ -372,10 +372,14 @@ private object IvySbt } } /** This method is used to add inline artifacts to the provided module. */ - def addArtifacts(moduleID: DefaultModuleDescriptor, artifacts: Iterable[Artifact]) + def addArtifacts(moduleID: DefaultModuleDescriptor, artifacts: Iterable[Artifact]): Unit = + for(art <- mapArtifacts(moduleID, artifacts.toSeq); c <- art.getConfigurations) + moduleID.addArtifact(c, art) + + def mapArtifacts(moduleID: ModuleDescriptor, artifacts: Seq[Artifact]): Seq[IArtifact] = { lazy val allConfigurations = moduleID.getPublicConfigurationsNames - for(artifact <- artifacts) + for(artifact <- artifacts) yield { val configurationStrings: Iterable[String] = { @@ -385,10 +389,10 @@ private object IvySbt else artifactConfigurations.map(_.name) } - val ivyArtifact = toIvyArtifact(moduleID, artifact, configurationStrings) - configurationStrings.foreach(configuration => moduleID.addArtifact(configuration, ivyArtifact)) + toIvyArtifact(moduleID, artifact, configurationStrings) } } + /** This code converts the given ModuleDescriptor to a DefaultModuleDescriptor by casting or generating an error. * Ivy 2.0.0 always produces a DefaultModuleDescriptor. */ private def toDefaultModuleDescriptor(md: ModuleDescriptor) = diff --git a/ivy/IvyActions.scala b/ivy/IvyActions.scala index a8ede1d3c..e3105e254 100644 --- a/ivy/IvyActions.scala +++ b/ivy/IvyActions.scala @@ -11,7 +11,7 @@ import core.cache.DefaultRepositoryCacheManager import core.{IvyPatternHelper,LogOptions} import core.deliver.DeliverOptions import core.install.InstallOptions -import core.module.descriptor.{DefaultArtifact, DefaultDependencyArtifactDescriptor, MDArtifact} +import core.module.descriptor.{Artifact => IArtifact, DefaultArtifact, DefaultDependencyArtifactDescriptor, MDArtifact} import core.module.descriptor.{DefaultDependencyDescriptor, DefaultModuleDescriptor, DependencyDescriptor, ModuleDescriptor} import core.module.id.{ArtifactId,ModuleId, ModuleRevisionId} import core.publish.PublishOptions @@ -19,9 +19,10 @@ import core.report.{ArtifactDownloadReport,ResolveReport} import core.resolve.ResolveOptions import core.retrieve.RetrieveOptions import plugins.parser.m2.{PomModuleDescriptorParser,PomModuleDescriptorWriter} +import plugins.resolver.DependencyResolver -final class PublishPatterns(val deliverIvyPattern: String, val srcArtifactPatterns: Seq[String], val publishIvy: Boolean) -final class PublishConfiguration(val patterns: PublishPatterns, val status: String, val resolverName: String, val configurations: Option[Seq[Configuration]], val logging: UpdateLogging.Value) +final class DeliverConfiguration(val deliverIvyPattern: String, val status: String, val configurations: Option[Seq[Configuration]], val logging: UpdateLogging.Value) +final class PublishConfiguration(val ivyFile: Option[File], val resolverName: String, val artifacts: Map[Artifact, File], val logging: UpdateLogging.Value) final class UpdateConfiguration(val retrieve: Option[RetrieveConfiguration], val missingOk: Boolean, val logging: UpdateLogging.Value) final class RetrieveConfiguration(val retrieveDirectory: File, val outputPattern: String) @@ -69,34 +70,36 @@ object IvyActions } } - def deliver(module: IvySbt#Module, configuration: PublishConfiguration, log: Logger) + def deliver(module: IvySbt#Module, configuration: DeliverConfiguration, log: Logger): File = { import configuration._ - import patterns._ module.withModule(log) { case (ivy, md, default) => - resolve(logging)(ivy, md, default) // todo: set download = false for resolve val revID = md.getModuleRevisionId val options = DeliverOptions.newInstance(ivy.getSettings).setStatus(status) options.setConfs(IvySbt.getConfigurations(md, configurations)) - ivy.deliver(revID, revID.getRevision, patterns.deliverIvyPattern, options) + ivy.deliver(revID, revID.getRevision, deliverIvyPattern, options) + deliveredFile(ivy, deliverIvyPattern, md) } } + def deliveredFile(ivy: Ivy, pattern: String, md: ModuleDescriptor): File = + ivy.getSettings.resolveFile(IvyPatternHelper.substitute(pattern, md.getResolvedModuleRevisionId)) - // todo: map configurations, extra dependencies def publish(module: IvySbt#Module, configuration: PublishConfiguration, log: Logger) { import configuration._ - import patterns._ module.withModule(log) { case (ivy, md, default) => - val revID = md.getModuleRevisionId - val patterns = new java.util.ArrayList[String] - srcArtifactPatterns.foreach(pattern => patterns.add(pattern)) - val options = (new PublishOptions).setOverwrite(true) - if(publishIvy) options.setSrcIvyPattern(deliverIvyPattern) - options.setConfs(IvySbt.getConfigurations(md, configurations)) - ivy.publish(revID, patterns, resolverName, options) + val resolver = ivy.getSettings.getResolver(resolverName) + val ivyArtifact = ivyFile map { file => (MDArtifact.newIvyArtifact(md), file) } + val as = mapArtifacts(md, artifacts) ++ ivyArtifact.toList + publish(md, as, resolver, overwrite = true) } } + def mapArtifacts(module: ModuleDescriptor, artifacts: Map[Artifact, File]): Seq[(IArtifact, File)] = + { + val seqa = artifacts.keys.toSeq + val zipped = seqa zip IvySbt.mapArtifacts(module, seqa) + zipped map { case (a, ivyA) => (ivyA, artifacts(a)) } + } /** Resolves and retrieves dependencies. 'ivyConfig' is used to produce an Ivy file and configuration. * 'updateConfig' configures the actual resolution and retrieval process. */ def update(module: IvySbt#Module, configuration: UpdateConfiguration, log: Logger): UpdateReport = @@ -177,5 +180,18 @@ object IvyActions case DownloadOnly => LOG_DOWNLOAD_ONLY case Full => LOG_DEFAULT } + + def publish(module: ModuleDescriptor, artifacts: Iterable[(IArtifact, File)], resolver: DependencyResolver, overwrite: Boolean): Unit = + try { + resolver.beginPublishTransaction(module.getModuleRevisionId(), overwrite); + for( (artifact, file) <- artifacts) if(file.exists) + resolver.publish(artifact, file, overwrite) + resolver.commitPublishTransaction() + } catch { + case e => + try { resolver.abortPublishTransaction() } + finally { throw e } + } + } final class ResolveException(messages: Seq[String]) extends RuntimeException(messages.mkString("\n")) \ No newline at end of file diff --git a/ivy/IvyInterface.scala b/ivy/IvyInterface.scala index e3383766c..79e1fc4ac 100644 --- a/ivy/IvyInterface.scala +++ b/ivy/IvyInterface.scala @@ -359,6 +359,12 @@ object Artifact val base = if(i >= 0) name.substring(0, i) else name Artifact(base, extract(name, defaultType), extract(name, defaultExtension), None, Nil, Some(file.toURI.toURL)) } + def artifactName(module: ModuleID, artifact: Artifact): String = + { + import artifact._ + val classifierStr = classifier match { case None => ""; case Some(c) => "-" + c } + artifact.name + "-" + module.revision + classifierStr + "." + artifact.extension + } } final case class ModuleConfiguration(organization: String, name: String, revision: String, resolver: Resolver) object ModuleConfiguration