From f36a5b88d86ab5b90bd9af5a06d92742dc3aca80 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Thu, 8 Jan 2015 18:02:59 -0500 Subject: [PATCH 1/4] Turn Aether integration into sbt-maven-resolver --- build.sbt | 13 ++++- ivy/src/main/scala/sbt/ConvertResolver.scala | 51 +++++++++---------- ivy/src/main/scala/sbt/Ivy.scala | 3 +- ivy/src/main/scala/sbt/MakePom.scala | 3 +- ivy/src/main/scala/sbt/UpdateOptions.scala | 27 +++++----- .../sbt/ivyint/CustomMavenResolver.scala | 11 ++++ .../scala/sbt/ivyint/SbtChainResolver.scala | 2 +- .../resolver/MavenRepositoryResolver.scala | 7 ++- .../MavenRepositorySystemFactory.scala | 0 .../internal/SbtArtifactDescriptorReader.java | 0 .../internal/SbtExtraProperties.java | 0 .../internal/SbtRepositoryLayout.scala | 0 .../scala/sbt/MavenResolverConverter.scala | 13 +++++ .../sbt/plugins/MavenResolverPlugin.scala | 13 +++++ .../dependency-management/mvn-local/build.sbt | 5 +- .../mvn-local/project/plugin.sbt | 2 + 16 files changed, 101 insertions(+), 49 deletions(-) create mode 100644 ivy/src/main/scala/sbt/ivyint/CustomMavenResolver.scala rename {ivy => sbt-maven-resolver}/src/main/scala/org/apache/ivy/plugins/resolver/MavenRepositoryResolver.scala (99%) rename {ivy => sbt-maven-resolver}/src/main/scala/org/apache/ivy/plugins/resolver/MavenRepositorySystemFactory.scala (100%) rename {ivy => sbt-maven-resolver}/src/main/scala/org/apache/maven/repository/internal/SbtArtifactDescriptorReader.java (100%) rename {ivy => sbt-maven-resolver}/src/main/scala/org/apache/maven/repository/internal/SbtExtraProperties.java (100%) rename {ivy => sbt-maven-resolver}/src/main/scala/org/apache/maven/repository/internal/SbtRepositoryLayout.scala (100%) create mode 100644 sbt-maven-resolver/src/main/scala/sbt/MavenResolverConverter.scala create mode 100644 sbt-maven-resolver/src/main/scala/sbt/plugins/MavenResolverPlugin.scala create mode 100644 sbt/src/sbt-test/dependency-management/mvn-local/project/plugin.sbt diff --git a/build.sbt b/build.sbt index 1faa99e75..e2e301bb5 100644 --- a/build.sbt +++ b/build.sbt @@ -215,7 +215,7 @@ lazy val ivyProj = (project in file("ivy")). settings(baseSettings: _*). settings( name := "Ivy", - libraryDependencies ++= Seq(ivy, jsch, json4sNative, jawnParser, jawnJson4s) ++ aetherLibs, + libraryDependencies ++= Seq(ivy, jsch, json4sNative, jawnParser, jawnJson4s), testExclusive) // Runner for uniform test interface @@ -412,6 +412,15 @@ lazy val sbtProj = (project in sbtPath). normalizedName := "sbt" ) +lazy val mavenResolverPluginProj = (project in file("sbt-maven-resolver")). + dependsOn(sbtProj). + settings(baseSettings: _*). + settings( + name := "sbt-maven-resolver", + libraryDependencies ++= aetherLibs, + sbtPlugin := true + ) + def scriptedTask: Initialize[InputTask[Unit]] = InputTask(scriptedSource(dir => (s: State) => scriptedParser(dir))) { result => (proguard in Proguard, fullClasspath in scriptedSbtProj in Test, scalaInstance in scriptedSbtProj, publishAll, scriptedSource, result) map { (launcher, scriptedSbtClasspath, scriptedSbtInstance, _, sourcePath, args) => @@ -435,7 +444,7 @@ def allProjects = Seq(launchInterfaceProj, launchProj, testSamples, interfacePro compileInterfaceProj, compileIncrementalProj, compilePersistProj, compilerProj, compilerIntegrationProj, compilerIvyProj, scriptedBaseProj, scriptedSbtProj, scriptedPluginProj, - actionsProj, commandProj, mainSettingsProj, mainProj, sbtProj) + actionsProj, commandProj, mainSettingsProj, mainProj, sbtProj, mavenResolverPluginProj) def projectsWithMyProvided = allProjects.map(p => p.copy(configurations = (p.configurations.filter(_ != Provided)) :+ myProvided)) lazy val nonRoots = projectsWithMyProvided.map(p => LocalProject(p.id)) diff --git a/ivy/src/main/scala/sbt/ConvertResolver.scala b/ivy/src/main/scala/sbt/ConvertResolver.scala index 9c7545eb9..26abec09c 100644 --- a/ivy/src/main/scala/sbt/ConvertResolver.scala +++ b/ivy/src/main/scala/sbt/ConvertResolver.scala @@ -19,6 +19,8 @@ import org.apache.ivy.util.{ FileUtil, ChecksumHelper } import org.apache.ivy.core.module.descriptor.{ Artifact => IArtifact } private[sbt] object ConvertResolver { + import UpdateOptions.ResolverConverter + /** * This class contains all the reflective lookups used in the * checksum-friendly URL publishing shim. @@ -94,37 +96,34 @@ private[sbt] object ConvertResolver { } } - private[sbt] val USE_AETHER_PROPERTY = "sbt.use.aether" - private def isUseAetherForResolution(settings: IvySettings): Boolean = - settings.getVariable(USE_AETHER_PROPERTY) == "true" + /** Converts the given sbt resolver into an Ivy resolver. */ + @deprecated("0.13.8", "Use the variant with updateOptions") + def apply(r: Resolver, settings: IvySettings, log: Logger): DependencyResolver = + apply(r, settings, UpdateOptions(), log) - /** Converts the given sbt resolver into an Ivy resolver..*/ - def apply(r: Resolver, settings: IvySettings, log: Logger) = - { + /** Converts the given sbt resolver into an Ivy resolver. */ + def apply(r: Resolver, settings: IvySettings, updateOptions: UpdateOptions, log: Logger): DependencyResolver = + (updateOptions.resolverConverter orElse defaultConvert)((r, settings, log)) + + /** The default implementation of converter. */ + lazy val defaultConvert: ResolverConverter = { + case (r, settings, log) => r match { case repo: MavenRepository => { - if (isUseAetherForResolution(settings)) { - repo match { - case cache: MavenCache => new org.apache.ivy.plugins.resolver.MavenCacheRepositoryResolver(cache, settings) - case _ => new org.apache.ivy.plugins.resolver.MavenRemoteRepositoryResolver(repo, settings) + val pattern = Collections.singletonList(Resolver.resolvePattern(repo.root, Resolver.mavenStyleBasePattern)) + final class PluginCapableResolver extends IBiblioResolver with ChecksumFriendlyURLResolver with DescriptorRequired { + def setPatterns() { + // done this way for access to protected methods. + setArtifactPatterns(pattern) + setIvyPatterns(pattern) } - } else { - val pattern = Collections.singletonList(Resolver.resolvePattern(repo.root, Resolver.mavenStyleBasePattern)) - final class PluginCapableResolver extends IBiblioResolver with ChecksumFriendlyURLResolver with DescriptorRequired { - def setPatterns() { - // done this way for access to protected methods. - setArtifactPatterns(pattern) - setIvyPatterns(pattern) - } - } - val resolver = new PluginCapableResolver - resolver.setRepository(new LocalIfFileRepo) - initializeMavenStyle(resolver, repo.name, repo.root) - resolver.setPatterns() // has to be done after initializeMavenStyle, which calls methods that overwrite the patterns - resolver } - + val resolver = new PluginCapableResolver + resolver.setRepository(new LocalIfFileRepo) + initializeMavenStyle(resolver, repo.name, repo.root) + resolver.setPatterns() // has to be done after initializeMavenStyle, which calls methods that overwrite the patterns + resolver } // TODO: HTTP repository is no longer recommended. #1541 // Remove `JavaNet1Repository` when we bump up the API. @@ -176,7 +175,7 @@ private[sbt] object ConvertResolver { case repo: ChainedResolver => IvySbt.resolverChain(repo.name, repo.resolvers, false, settings, log) case repo: RawRepository => repo.resolver } - } + } private sealed trait DescriptorRequired extends BasicResolver { override def getDependency(dd: DependencyDescriptor, data: ResolveData) = diff --git a/ivy/src/main/scala/sbt/Ivy.scala b/ivy/src/main/scala/sbt/Ivy.scala index d2d0388ee..be86d1131 100644 --- a/ivy/src/main/scala/sbt/Ivy.scala +++ b/ivy/src/main/scala/sbt/Ivy.scala @@ -73,7 +73,6 @@ final class IvySbt(val configuration: IvyConfiguration) { is.setBaseDir(baseDirectory) is.setCircularDependencyStrategy(configuration.updateOptions.circularDependencyLevel.ivyStrategy) CustomPomParser.registerDefault - is.setVariable(ConvertResolver.USE_AETHER_PROPERTY, s"${configuration.updateOptions.aetherResolution}") configuration match { case e: ExternalIvyConfiguration => @@ -289,7 +288,7 @@ private[sbt] object IvySbt { def resolverChain(name: String, resolvers: Seq[Resolver], localOnly: Boolean, settings: IvySettings, log: Logger): DependencyResolver = resolverChain(name, resolvers, localOnly, settings, UpdateOptions(), log) def resolverChain(name: String, resolvers: Seq[Resolver], localOnly: Boolean, settings: IvySettings, updateOptions: UpdateOptions, log: Logger): DependencyResolver = { - def mapResolvers(rs: Seq[Resolver]) = rs.map(r => ConvertResolver(r, settings, log)) + def mapResolvers(rs: Seq[Resolver]) = rs.map(r => ConvertResolver(r, settings, updateOptions, log)) val (projectResolvers, rest) = resolvers.partition(_.name == "inter-project") if (projectResolvers.isEmpty) new ivyint.SbtChainResolver(name, mapResolvers(rest), settings, updateOptions, log) else { diff --git a/ivy/src/main/scala/sbt/MakePom.scala b/ivy/src/main/scala/sbt/MakePom.scala index 13ca70f1b..fc15a3cd9 100644 --- a/ivy/src/main/scala/sbt/MakePom.scala +++ b/ivy/src/main/scala/sbt/MakePom.scala @@ -20,6 +20,7 @@ import org.apache.ivy.Ivy import org.apache.ivy.core.settings.IvySettings import org.apache.ivy.core.module.descriptor.{ DependencyArtifactDescriptor, DependencyDescriptor, License, ModuleDescriptor, ExcludeRule } import org.apache.ivy.plugins.resolver.{ ChainResolver, DependencyResolver, IBiblioResolver } +import ivyint.CustomRemoteMavenResolver class MakePom(val log: Logger) { @deprecated("Use `write(Ivy, ModuleDescriptor, ModuleInfo, Option[Iterable[Configuration]], Set[String], NodeSeq, XNode => XNode, MavenRepository => Boolean, Boolean, File)` instead", "0.11.2") @@ -333,7 +334,7 @@ class MakePom(val log: Logger) { val repositories = if (includeAll) allResolvers(settings) else resolvers(settings.getDefaultResolver) val mavenRepositories = repositories.flatMap { - case m: org.apache.ivy.plugins.resolver.MavenRemoteRepositoryResolver if m.repo.root != DefaultMavenRepository.root => + case m: CustomRemoteMavenResolver if m.repo.root != DefaultMavenRepository.root => MavenRepository(m.repo.name, m.repo.root) :: Nil case m: IBiblioResolver if m.isM2compatible && m.getRoot != DefaultMavenRepository.root => MavenRepository(m.getName, m.getRoot) :: Nil diff --git a/ivy/src/main/scala/sbt/UpdateOptions.scala b/ivy/src/main/scala/sbt/UpdateOptions.scala index e13fed72f..3a710026c 100644 --- a/ivy/src/main/scala/sbt/UpdateOptions.scala +++ b/ivy/src/main/scala/sbt/UpdateOptions.scala @@ -1,6 +1,8 @@ package sbt import java.io.File +import org.apache.ivy.plugins.resolver.DependencyResolver +import org.apache.ivy.core.settings.IvySettings /** * Represents configurable options for update task. @@ -18,13 +20,8 @@ final class UpdateOptions private[sbt] ( val consolidatedResolution: Boolean, /** If set to true, use cached resolution. */ val cachedResolution: Boolean, - /** If set to true, use aether for resolving maven artifacts. */ - val aetherResolution: Boolean) { - - /** Enables Aether for dependency resolution. */ - def withAetherResolution(aetherResolution: Boolean): UpdateOptions = - copy(aetherResolution = aetherResolution) - + /** Extention point for an alternative resolver converter. */ + val resolverConverter: UpdateOptions.ResolverConverter) { def withCircularDependencyLevel(circularDependencyLevel: CircularDependencyLevel): UpdateOptions = copy(circularDependencyLevel = circularDependencyLevel) def withLatestSnapshots(latestSnapshots: Boolean): UpdateOptions = @@ -36,24 +33,28 @@ final class UpdateOptions private[sbt] ( def withCachedResolution(cachedResoluton: Boolean): UpdateOptions = copy(cachedResolution = cachedResoluton, consolidatedResolution = cachedResolution) + /** Extention point for an alternative resolver converter. */ + def withResolverConverter(resolverConverter: UpdateOptions.ResolverConverter): UpdateOptions = + copy(resolverConverter = resolverConverter) private[sbt] def copy( circularDependencyLevel: CircularDependencyLevel = this.circularDependencyLevel, latestSnapshots: Boolean = this.latestSnapshots, consolidatedResolution: Boolean = this.consolidatedResolution, cachedResolution: Boolean = this.cachedResolution, - aetherResolution: Boolean = this.aetherResolution): UpdateOptions = + resolverConverter: UpdateOptions.ResolverConverter = this.resolverConverter): UpdateOptions = new UpdateOptions(circularDependencyLevel, latestSnapshots, consolidatedResolution, cachedResolution, - aetherResolution) + resolverConverter) override def equals(o: Any): Boolean = o match { case o: UpdateOptions => this.circularDependencyLevel == o.circularDependencyLevel && this.latestSnapshots == o.latestSnapshots && - this.cachedResolution == o.cachedResolution + this.cachedResolution == o.cachedResolution && + this.resolverConverter == o.resolverConverter case _ => false } @@ -63,17 +64,19 @@ final class UpdateOptions private[sbt] ( hash = hash * 31 + this.circularDependencyLevel.## hash = hash * 31 + this.latestSnapshots.## hash = hash * 31 + this.cachedResolution.## + hash = hash * 31 + this.resolverConverter.## hash } } object UpdateOptions { + type ResolverConverter = PartialFunction[(Resolver, IvySettings, Logger), DependencyResolver] + def apply(): UpdateOptions = new UpdateOptions( circularDependencyLevel = CircularDependencyLevel.Warn, latestSnapshots = false, consolidatedResolution = false, cachedResolution = false, - // TODO - Disable this before release, but make sure test suite passes with it on. - aetherResolution = true) + resolverConverter = PartialFunction.empty) } diff --git a/ivy/src/main/scala/sbt/ivyint/CustomMavenResolver.scala b/ivy/src/main/scala/sbt/ivyint/CustomMavenResolver.scala new file mode 100644 index 000000000..e3e41148e --- /dev/null +++ b/ivy/src/main/scala/sbt/ivyint/CustomMavenResolver.scala @@ -0,0 +1,11 @@ +package sbt +package ivyint + +import org.apache.ivy.plugins.resolver.DependencyResolver + +// These are placeholder traits for sbt-aether-resolver +trait CustomMavenResolver extends DependencyResolver { +} +trait CustomRemoteMavenResolver extends CustomMavenResolver { + def repo: MavenRepository +} diff --git a/ivy/src/main/scala/sbt/ivyint/SbtChainResolver.scala b/ivy/src/main/scala/sbt/ivyint/SbtChainResolver.scala index 13c2642ec..08c8f00e7 100644 --- a/ivy/src/main/scala/sbt/ivyint/SbtChainResolver.scala +++ b/ivy/src/main/scala/sbt/ivyint/SbtChainResolver.scala @@ -184,7 +184,7 @@ private[sbt] case class SbtChainResolver( val artifactOpt = findFirstArtifactRef(rmr.getDescriptor, dd, data, resolver) artifactOpt match { case None if resolver.getName == "inter-project" => // do nothing - case None if resolver.isInstanceOf[AbstractMavenRepositoryResolver] => + case None if resolver.isInstanceOf[CustomMavenResolver] => // do nothing for now.... // We want to see if the maven caching is sufficient and we do not need to duplicate within the ivy cache... case None => throw new RuntimeException(s"\t${resolver.getName}: no ivy file nor artifact found for $rmr") diff --git a/ivy/src/main/scala/org/apache/ivy/plugins/resolver/MavenRepositoryResolver.scala b/sbt-maven-resolver/src/main/scala/org/apache/ivy/plugins/resolver/MavenRepositoryResolver.scala similarity index 99% rename from ivy/src/main/scala/org/apache/ivy/plugins/resolver/MavenRepositoryResolver.scala rename to sbt-maven-resolver/src/main/scala/org/apache/ivy/plugins/resolver/MavenRepositoryResolver.scala index 6ff019c6a..a5336ad3b 100644 --- a/ivy/src/main/scala/org/apache/ivy/plugins/resolver/MavenRepositoryResolver.scala +++ b/sbt-maven-resolver/src/main/scala/org/apache/ivy/plugins/resolver/MavenRepositoryResolver.scala @@ -30,6 +30,7 @@ import org.eclipse.aether.deployment.{ DeployRequest => AetherDeployRequest } import org.eclipse.aether.installation.{ InstallRequest => AetherInstallRequest } import org.apache.ivy.core.cache.{ ModuleDescriptorWriter, ArtifactOrigin } import sbt.{ MavenCache, MavenRepository } +import sbt.ivyint.{ CustomMavenResolver, CustomRemoteMavenResolver } import scala.collection.JavaConverters._ object MavenRepositoryResolver { @@ -60,7 +61,8 @@ object MavenRepositoryResolver { * Note: This creates its *own* local cache directory for cache metadata. using its name. * */ -class MavenRemoteRepositoryResolver(val repo: MavenRepository, settings: IvySettings) extends AbstractMavenRepositoryResolver(settings) { +class MavenRemoteRepositoryResolver(val repo: MavenRepository, settings: IvySettings) + extends AbstractMavenRepositoryResolver(settings) with CustomRemoteMavenResolver { setName(repo.name) override def toString = s"${repo.name}: ${repo.root}" protected val system = MavenRepositorySystemFactory.newRepositorySystemImpl @@ -136,7 +138,8 @@ class MavenRemoteRepositoryResolver(val repo: MavenRepository, settings: IvySett * * Note: This should never hit somethign remote, as it just looks in the maven cache for things already resolved. */ -class MavenCacheRepositoryResolver(val repo: MavenCache, settings: IvySettings) extends AbstractMavenRepositoryResolver(settings) { +class MavenCacheRepositoryResolver(val repo: MavenCache, settings: IvySettings) + extends AbstractMavenRepositoryResolver(settings) with CustomMavenResolver { setName(repo.name) protected val system = MavenRepositorySystemFactory.newRepositorySystemImpl sbt.IO.createDirectory(repo.rootFile) diff --git a/ivy/src/main/scala/org/apache/ivy/plugins/resolver/MavenRepositorySystemFactory.scala b/sbt-maven-resolver/src/main/scala/org/apache/ivy/plugins/resolver/MavenRepositorySystemFactory.scala similarity index 100% rename from ivy/src/main/scala/org/apache/ivy/plugins/resolver/MavenRepositorySystemFactory.scala rename to sbt-maven-resolver/src/main/scala/org/apache/ivy/plugins/resolver/MavenRepositorySystemFactory.scala diff --git a/ivy/src/main/scala/org/apache/maven/repository/internal/SbtArtifactDescriptorReader.java b/sbt-maven-resolver/src/main/scala/org/apache/maven/repository/internal/SbtArtifactDescriptorReader.java similarity index 100% rename from ivy/src/main/scala/org/apache/maven/repository/internal/SbtArtifactDescriptorReader.java rename to sbt-maven-resolver/src/main/scala/org/apache/maven/repository/internal/SbtArtifactDescriptorReader.java diff --git a/ivy/src/main/scala/org/apache/maven/repository/internal/SbtExtraProperties.java b/sbt-maven-resolver/src/main/scala/org/apache/maven/repository/internal/SbtExtraProperties.java similarity index 100% rename from ivy/src/main/scala/org/apache/maven/repository/internal/SbtExtraProperties.java rename to sbt-maven-resolver/src/main/scala/org/apache/maven/repository/internal/SbtExtraProperties.java diff --git a/ivy/src/main/scala/org/apache/maven/repository/internal/SbtRepositoryLayout.scala b/sbt-maven-resolver/src/main/scala/org/apache/maven/repository/internal/SbtRepositoryLayout.scala similarity index 100% rename from ivy/src/main/scala/org/apache/maven/repository/internal/SbtRepositoryLayout.scala rename to sbt-maven-resolver/src/main/scala/org/apache/maven/repository/internal/SbtRepositoryLayout.scala diff --git a/sbt-maven-resolver/src/main/scala/sbt/MavenResolverConverter.scala b/sbt-maven-resolver/src/main/scala/sbt/MavenResolverConverter.scala new file mode 100644 index 000000000..7f527c813 --- /dev/null +++ b/sbt-maven-resolver/src/main/scala/sbt/MavenResolverConverter.scala @@ -0,0 +1,13 @@ +package sbt + +import UpdateOptions.ResolverConverter +import org.apache.ivy.plugins.resolver.{ MavenCacheRepositoryResolver, MavenRemoteRepositoryResolver } + +object MavenResolverConverter { + val converter: ResolverConverter = { + case (cache: MavenCache, settings, log) => + new MavenCacheRepositoryResolver(cache, settings) + case (repo: MavenRepository, settings, log) => + new MavenRemoteRepositoryResolver(repo, settings) + } +} diff --git a/sbt-maven-resolver/src/main/scala/sbt/plugins/MavenResolverPlugin.scala b/sbt-maven-resolver/src/main/scala/sbt/plugins/MavenResolverPlugin.scala new file mode 100644 index 000000000..df166e568 --- /dev/null +++ b/sbt-maven-resolver/src/main/scala/sbt/plugins/MavenResolverPlugin.scala @@ -0,0 +1,13 @@ +package sbt +package plugins + +import Keys._ + +object MavenResolverPlugin extends AutoPlugin { + override def requires = IvyPlugin + override def trigger = allRequirements + + override lazy val projectSettings: Seq[Setting[_]] = Seq( + updateOptions := updateOptions.value.withResolverConverter(MavenResolverConverter.converter) + ) +} diff --git a/sbt/src/sbt-test/dependency-management/mvn-local/build.sbt b/sbt/src/sbt-test/dependency-management/mvn-local/build.sbt index 65715e00d..10b0d8003 100644 --- a/sbt/src/sbt-test/dependency-management/mvn-local/build.sbt +++ b/sbt/src/sbt-test/dependency-management/mvn-local/build.sbt @@ -14,14 +14,13 @@ lazy val main = project. libraryDependencies += (projectID in library).value, fullResolvers := fullResolvers.value.filterNot(_.name == "inter-project"), // TODO - should this not be needed? - updateOptions := updateOptions.value.withLatestSnapshots(true).withAetherResolution(true) + updateOptions := updateOptions.value.withLatestSnapshots(true) ) lazy val library = project. settings(commonSettings: _*). settings( - uniqueName, - updateOptions := updateOptions.value.withAetherResolution(true) + uniqueName ) def uniqueName = diff --git a/sbt/src/sbt-test/dependency-management/mvn-local/project/plugin.sbt b/sbt/src/sbt-test/dependency-management/mvn-local/project/plugin.sbt new file mode 100644 index 000000000..1ae548913 --- /dev/null +++ b/sbt/src/sbt-test/dependency-management/mvn-local/project/plugin.sbt @@ -0,0 +1,2 @@ +libraryDependencies += Defaults.sbtPluginExtra("org.scala-sbt" % "sbt-maven-resolver" % sbtVersion.value, + sbtBinaryVersion.value, scalaBinaryVersion.value) From 7580fe5afcd0fb28dc3bf7a7e1fd82f0bdd4540c Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Fri, 9 Jan 2015 01:20:59 -0500 Subject: [PATCH 2/4] Updated notes --- notes/0.13.8/aether-resolvers.markdown | 36 +++++++++++++------------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/notes/0.13.8/aether-resolvers.markdown b/notes/0.13.8/aether-resolvers.markdown index 5becc7e85..d30ad3bf5 100644 --- a/notes/0.13.8/aether-resolvers.markdown +++ b/notes/0.13.8/aether-resolvers.markdown @@ -9,36 +9,36 @@ ### Improvements -### Aether Resolution +### Maven resolver plugin -sbt 0.13.8 adds the ability to use Eclipse Aether to resolve maven dependencies. This is designed to work within Ivy -so that both Aether + Ivy dependencies cohesively depend on each other. +sbt 0.13.8 adds an extention point in the dependency resolution to customize Maven resolvers. +This allows us to write sbt-maven-resolver auto plugin, which internally uses Eclipse Aether +to resolve Maven dependencies instead of Apache Ivy. -The key called `updateOptions` has been expanded to enable Aether resolutions via the following setting: +To enable this plugin, add the following to `project/maven.sbt` (or `project/plugin.sbt` the file name doesn't matter): - updateOptions := updateOptions.value.withAetherResolution(true) + libraryDependencies += Defaults.sbtPluginExtra("org.scala-sbt" % "sbt-maven-resolver" % sbtVersion.value, + sbtBinaryVersion.value, scalaBinaryVersion.value) -This will create a new `~/.ivy2/maven-cache` directory which contains the Aether cache of files. You may notice some -file will be re-downloaded for the new cache layout. Additionally, sbt will now be able to fully construct +This will create a new `~/.ivy2/maven-cache` directory, which contains the Aether cache of files. +You may notice some file will be re-downloaded for the new cache layout. +Additionally, sbt will now be able to fully construct `maven-metadata.xml` files when publishing to remote repositories or when publishing to the local `~/.m2/repository`. This should help erase many of the deficiencies encountered when using Maven and sbt together. -Note: The setting must be places on EVERY subproject within a build if you wish to fully use Aether for all projects. +**Notes and known limitations**: -Known limitations: - -* The current implementation does not support ivy-style version numbers, such as "2.10.+" or "latest.snapshot". This +- sbt-maven-resolver requires sbt 0.13.8 and above. +- The current implementation does not support Ivy-style dynamic revisions, such as "2.10.+" or "latest.snapshot". This is a fixable situation, but the version range query and Ivy -> Maven version range translation code has not been migrated. - - ### Bug fixes -- sbt doens't honor Maven's uniqueVersions (use aether resolver to fix). [#1322][1322] by [@jsuereth][@jsuereth] -- sbt doens't see new SNAPSHOT dependency versions in local maven repos (use withLatestSnapshots + aether resolver to fix) [#321][321] by [@jsuereth][@jsuereth] -- Property in pom's version field results to wrong dependency resolution (use aether resolver to fix). [#647][647] by [@jsuereth][@jsuereth] -- Maven local resolver with parent POM (use aether resolver). [#1616][1616] by [@jsuereth][@jsuereth] +- sbt doens't honor Maven's uniqueVersions (use sbt-maven-resolver to fix). [#1322][1322] by [@jsuereth][@jsuereth] +- sbt doens't see new SNAPSHOT dependency versions in local maven repos (use withLatestSnapshots + sbt-maven-resolver to fix) [#321][321] by [@jsuereth][@jsuereth] +- Property in pom's version field results to wrong dependency resolution (use sbt-maven-resolver to fix). [#647][647] by [@jsuereth][@jsuereth] +- Maven local resolver with parent POM (use sbt-maven-resolver). [#1616][1616] by [@jsuereth][@jsuereth] // Possibly fixed, need verification. - 1676 - SNAPSHOT dependency not updated ??? -- 679 - Incorrect Maven Snapshot file resolution ???? \ No newline at end of file +- 679 - Incorrect Maven Snapshot file resolution ???? From 406c80ddd6af4c135e6e4bd7c1d3f0340f434a89 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Sat, 10 Jan 2015 22:55:50 -0500 Subject: [PATCH 3/4] Adjust tests. --- build.sbt | 2 +- .../src/main/java/sbt}/SbtExtraProperties.java | 4 +--- ivy/src/main/scala/sbt/CustomPomParser.scala | 2 +- ivy/src/main/scala/sbt/ModuleID.scala | 2 -- main/src/main/scala/sbt/APIMappings.scala | 2 -- main/src/main/scala/sbt/Defaults.scala | 2 +- .../apache/ivy/plugins/resolver/MavenRepositoryResolver.scala | 4 ++-- .../repository/internal/SbtArtifactDescriptorReader.java | 1 + .../maven/repository/internal/SbtRepositoryLayout.scala | 1 + .../src/test/scala/MavenResolutionSpec.scala | 2 +- .../plugin.sbt => cache-classifiers/project/maven.sbt} | 0 .../dependency-management/mvn-local/project/maven.sbt | 2 ++ .../dependency-management/pom-advanced/project/maven.sbt | 2 ++ sbt/src/sbt-test/dependency-management/t468/project/maven.sbt | 2 ++ 14 files changed, 15 insertions(+), 13 deletions(-) rename {sbt-maven-resolver/src/main/scala/org/apache/maven/repository/internal => ivy/src/main/java/sbt}/SbtExtraProperties.java (94%) rename {ivy => sbt-maven-resolver}/src/test/scala/MavenResolutionSpec.scala (99%) rename sbt/src/sbt-test/dependency-management/{mvn-local/project/plugin.sbt => cache-classifiers/project/maven.sbt} (100%) create mode 100644 sbt/src/sbt-test/dependency-management/mvn-local/project/maven.sbt create mode 100644 sbt/src/sbt-test/dependency-management/pom-advanced/project/maven.sbt create mode 100644 sbt/src/sbt-test/dependency-management/t468/project/maven.sbt diff --git a/build.sbt b/build.sbt index e2e301bb5..7e16726bd 100644 --- a/build.sbt +++ b/build.sbt @@ -413,7 +413,7 @@ lazy val sbtProj = (project in sbtPath). ) lazy val mavenResolverPluginProj = (project in file("sbt-maven-resolver")). - dependsOn(sbtProj). + dependsOn(sbtProj, ivyProj % "test->test"). settings(baseSettings: _*). settings( name := "sbt-maven-resolver", diff --git a/sbt-maven-resolver/src/main/scala/org/apache/maven/repository/internal/SbtExtraProperties.java b/ivy/src/main/java/sbt/SbtExtraProperties.java similarity index 94% rename from sbt-maven-resolver/src/main/scala/org/apache/maven/repository/internal/SbtExtraProperties.java rename to ivy/src/main/java/sbt/SbtExtraProperties.java index 5570d4fac..bcc9b8189 100644 --- a/sbt-maven-resolver/src/main/scala/org/apache/maven/repository/internal/SbtExtraProperties.java +++ b/ivy/src/main/java/sbt/SbtExtraProperties.java @@ -1,6 +1,4 @@ -package org.apache.maven.repository.internal; - - +package sbt; /** * Extra properties we dump from Aether into the properties list. diff --git a/ivy/src/main/scala/sbt/CustomPomParser.scala b/ivy/src/main/scala/sbt/CustomPomParser.scala index d931cefe6..c9e660833 100644 --- a/ivy/src/main/scala/sbt/CustomPomParser.scala +++ b/ivy/src/main/scala/sbt/CustomPomParser.scala @@ -13,7 +13,7 @@ import java.io.{ File, InputStream } import java.net.URL import java.util.regex.Pattern -import org.apache.maven.repository.internal.{ SbtExtraProperties, PomExtraDependencyAttributes } +import org.apache.maven.repository.internal.{ PomExtraDependencyAttributes } @deprecated("0.13.8", "We now use an Aether-based pom parser.") final class CustomPomParser(delegate: ModuleDescriptorParser, transform: (ModuleDescriptorParser, ModuleDescriptor) => ModuleDescriptor) extends ModuleDescriptorParser { diff --git a/ivy/src/main/scala/sbt/ModuleID.scala b/ivy/src/main/scala/sbt/ModuleID.scala index bf734f5f7..4b244df44 100644 --- a/ivy/src/main/scala/sbt/ModuleID.scala +++ b/ivy/src/main/scala/sbt/ModuleID.scala @@ -5,8 +5,6 @@ package sbt import java.net.URL -import org.apache.maven.repository.internal.SbtExtraProperties - final case class ModuleID(organization: String, name: String, revision: String, configurations: Option[String] = None, isChanging: Boolean = false, isTransitive: Boolean = true, isForce: Boolean = false, explicitArtifacts: Seq[Artifact] = Nil, exclusions: Seq[ExclusionRule] = Nil, extraAttributes: Map[String, String] = Map.empty, crossVersion: CrossVersion = CrossVersion.Disabled) { override def toString: String = organization + ":" + name + ":" + revision + diff --git a/main/src/main/scala/sbt/APIMappings.scala b/main/src/main/scala/sbt/APIMappings.scala index 59895a83e..40d26709d 100644 --- a/main/src/main/scala/sbt/APIMappings.scala +++ b/main/src/main/scala/sbt/APIMappings.scala @@ -3,8 +3,6 @@ package sbt import java.io.File import java.net.{ MalformedURLException, URL } -import org.apache.maven.repository.internal.SbtExtraProperties - private[sbt] object APIMappings { def extract(cp: Seq[Attributed[File]], log: Logger): Seq[(File, URL)] = cp.flatMap(entry => extractFromEntry(entry, log)) diff --git a/main/src/main/scala/sbt/Defaults.scala b/main/src/main/scala/sbt/Defaults.scala index 45a92572f..21b1ae7bf 100755 --- a/main/src/main/scala/sbt/Defaults.scala +++ b/main/src/main/scala/sbt/Defaults.scala @@ -5,7 +5,7 @@ package sbt import Attributed.data import Scope.{ fillTaskAxis, GlobalScope, ThisScope } -import org.apache.maven.repository.internal.{ SbtExtraProperties, PomExtraDependencyAttributes } +import org.apache.maven.repository.internal.PomExtraDependencyAttributes import sbt.Compiler.InputsWithPrevious import xsbt.api.Discovery import xsbti.compile.CompileOrder diff --git a/sbt-maven-resolver/src/main/scala/org/apache/ivy/plugins/resolver/MavenRepositoryResolver.scala b/sbt-maven-resolver/src/main/scala/org/apache/ivy/plugins/resolver/MavenRepositoryResolver.scala index a5336ad3b..183b7f839 100644 --- a/sbt-maven-resolver/src/main/scala/org/apache/ivy/plugins/resolver/MavenRepositoryResolver.scala +++ b/sbt-maven-resolver/src/main/scala/org/apache/ivy/plugins/resolver/MavenRepositoryResolver.scala @@ -15,7 +15,7 @@ import org.apache.ivy.plugins.parser.xml.XmlModuleDescriptorWriter import org.apache.ivy.plugins.resolver.MavenRepositoryResolver.JarPackaging import org.apache.ivy.plugins.resolver.util.ResolvedResource import org.apache.ivy.util.Message -import org.apache.maven.repository.internal.{ PomExtraDependencyAttributes, SbtRepositoryLayout, SbtExtraProperties } +import org.apache.maven.repository.internal.{ PomExtraDependencyAttributes, SbtRepositoryLayout } import org.eclipse.aether.{ RepositorySystemSession, RepositorySystem } import org.eclipse.aether.artifact.{ DefaultArtifact => AetherArtifact } import org.eclipse.aether.metadata.{ Metadata, DefaultMetadata } @@ -29,7 +29,7 @@ import org.eclipse.aether.resolution.{ import org.eclipse.aether.deployment.{ DeployRequest => AetherDeployRequest } import org.eclipse.aether.installation.{ InstallRequest => AetherInstallRequest } import org.apache.ivy.core.cache.{ ModuleDescriptorWriter, ArtifactOrigin } -import sbt.{ MavenCache, MavenRepository } +import sbt.{ MavenCache, MavenRepository, SbtExtraProperties } import sbt.ivyint.{ CustomMavenResolver, CustomRemoteMavenResolver } import scala.collection.JavaConverters._ diff --git a/sbt-maven-resolver/src/main/scala/org/apache/maven/repository/internal/SbtArtifactDescriptorReader.java b/sbt-maven-resolver/src/main/scala/org/apache/maven/repository/internal/SbtArtifactDescriptorReader.java index c816145e9..7e45ed94c 100644 --- a/sbt-maven-resolver/src/main/scala/org/apache/maven/repository/internal/SbtArtifactDescriptorReader.java +++ b/sbt-maven-resolver/src/main/scala/org/apache/maven/repository/internal/SbtArtifactDescriptorReader.java @@ -81,6 +81,7 @@ import org.eclipse.aether.spi.log.Logger; import org.eclipse.aether.spi.log.LoggerFactory; import org.eclipse.aether.spi.log.NullLoggerFactory; import org.eclipse.aether.transfer.ArtifactNotFoundException; +import sbt.SbtExtraProperties; /** * A hacked version of maven's default artifact descriptor reader which we use in place of the standard aether adapter. diff --git a/sbt-maven-resolver/src/main/scala/org/apache/maven/repository/internal/SbtRepositoryLayout.scala b/sbt-maven-resolver/src/main/scala/org/apache/maven/repository/internal/SbtRepositoryLayout.scala index 23fe7630a..412ba690f 100644 --- a/sbt-maven-resolver/src/main/scala/org/apache/maven/repository/internal/SbtRepositoryLayout.scala +++ b/sbt-maven-resolver/src/main/scala/org/apache/maven/repository/internal/SbtRepositoryLayout.scala @@ -9,6 +9,7 @@ import org.eclipse.aether.metadata.Metadata import org.eclipse.aether.spi.connector.layout.RepositoryLayout.Checksum import org.eclipse.aether.artifact.Artifact import java.net.URI +import sbt.SbtExtraProperties import scala.util.matching.Regex diff --git a/ivy/src/test/scala/MavenResolutionSpec.scala b/sbt-maven-resolver/src/test/scala/MavenResolutionSpec.scala similarity index 99% rename from ivy/src/test/scala/MavenResolutionSpec.scala rename to sbt-maven-resolver/src/test/scala/MavenResolutionSpec.scala index 8015e78a8..1013fc80b 100644 --- a/ivy/src/test/scala/MavenResolutionSpec.scala +++ b/sbt-maven-resolver/src/test/scala/MavenResolutionSpec.scala @@ -55,7 +55,7 @@ class MavenResolutionSpec extends BaseIvySpecification { import ShowLines._ - def defaultUpdateOptions = UpdateOptions().withAetherResolution(true) + def defaultUpdateOptions = UpdateOptions().withResolverConverter(MavenResolverConverter.converter) def resolveMajorConflicts = { val m = module(ModuleID("com.example", "foo", "0.1.0", Some("compile")), diff --git a/sbt/src/sbt-test/dependency-management/mvn-local/project/plugin.sbt b/sbt/src/sbt-test/dependency-management/cache-classifiers/project/maven.sbt similarity index 100% rename from sbt/src/sbt-test/dependency-management/mvn-local/project/plugin.sbt rename to sbt/src/sbt-test/dependency-management/cache-classifiers/project/maven.sbt diff --git a/sbt/src/sbt-test/dependency-management/mvn-local/project/maven.sbt b/sbt/src/sbt-test/dependency-management/mvn-local/project/maven.sbt new file mode 100644 index 000000000..1ae548913 --- /dev/null +++ b/sbt/src/sbt-test/dependency-management/mvn-local/project/maven.sbt @@ -0,0 +1,2 @@ +libraryDependencies += Defaults.sbtPluginExtra("org.scala-sbt" % "sbt-maven-resolver" % sbtVersion.value, + sbtBinaryVersion.value, scalaBinaryVersion.value) diff --git a/sbt/src/sbt-test/dependency-management/pom-advanced/project/maven.sbt b/sbt/src/sbt-test/dependency-management/pom-advanced/project/maven.sbt new file mode 100644 index 000000000..1ae548913 --- /dev/null +++ b/sbt/src/sbt-test/dependency-management/pom-advanced/project/maven.sbt @@ -0,0 +1,2 @@ +libraryDependencies += Defaults.sbtPluginExtra("org.scala-sbt" % "sbt-maven-resolver" % sbtVersion.value, + sbtBinaryVersion.value, scalaBinaryVersion.value) diff --git a/sbt/src/sbt-test/dependency-management/t468/project/maven.sbt b/sbt/src/sbt-test/dependency-management/t468/project/maven.sbt new file mode 100644 index 000000000..1ae548913 --- /dev/null +++ b/sbt/src/sbt-test/dependency-management/t468/project/maven.sbt @@ -0,0 +1,2 @@ +libraryDependencies += Defaults.sbtPluginExtra("org.scala-sbt" % "sbt-maven-resolver" % sbtVersion.value, + sbtBinaryVersion.value, scalaBinaryVersion.value) From a6f954d1b17a650d272430d540366d98dc7be27d Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Sat, 10 Jan 2015 23:06:07 -0500 Subject: [PATCH 4/4] Moved Java source to src/main/java --- .../maven/repository/internal/SbtArtifactDescriptorReader.java | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename sbt-maven-resolver/src/main/{scala => java}/org/apache/maven/repository/internal/SbtArtifactDescriptorReader.java (100%) diff --git a/sbt-maven-resolver/src/main/scala/org/apache/maven/repository/internal/SbtArtifactDescriptorReader.java b/sbt-maven-resolver/src/main/java/org/apache/maven/repository/internal/SbtArtifactDescriptorReader.java similarity index 100% rename from sbt-maven-resolver/src/main/scala/org/apache/maven/repository/internal/SbtArtifactDescriptorReader.java rename to sbt-maven-resolver/src/main/java/org/apache/maven/repository/internal/SbtArtifactDescriptorReader.java