Merge pull request #1618 from sbt/wip/mavne-resolution-woes

Fix various issues with maven + Ivy
This commit is contained in:
eugene yokota 2014-09-25 11:30:53 -04:00
commit cba192a291
7 changed files with 111 additions and 7 deletions

View File

@ -9,12 +9,13 @@ import org.apache.ivy.core.module.id.ModuleRevisionId
import org.apache.ivy.core.module.descriptor.DependencyDescriptor
import org.apache.ivy.core.resolve.ResolveData
import org.apache.ivy.core.settings.IvySettings
import org.apache.ivy.plugins.repository.{ RepositoryCopyProgressListener, TransferEvent }
import org.apache.ivy.plugins.resolver.{ BasicResolver, DependencyResolver, IBiblioResolver, RepositoryResolver }
import org.apache.ivy.plugins.resolver.{ AbstractPatternsBasedResolver, AbstractSshBasedResolver, FileSystemResolver, SFTPResolver, SshResolver, URLResolver }
import org.apache.ivy.plugins.repository.url.{ URLRepository => URLRepo }
import org.apache.ivy.plugins.repository.file.{ FileRepository => FileRepo, FileResource }
import java.io.File
import org.apache.ivy.util.ChecksumHelper
import java.io.{ IOException, File }
import org.apache.ivy.util.{ FileUtil, ChecksumHelper }
import org.apache.ivy.core.module.descriptor.{ Artifact => IArtifact }
private[sbt] object ConvertResolver {
@ -216,6 +217,7 @@ private[sbt] object ConvertResolver {
*/
private[this] final class LocalIfFileRepo extends URLRepo {
private[this] val repo = new WarnOnOverwriteFileRepo()
private[this] val progress = new RepositoryCopyProgressListener(this);
override def getResource(source: String) = {
val url = new URL(source)
if (url.getProtocol == IO.FileScheme)
@ -223,6 +225,35 @@ private[sbt] object ConvertResolver {
else
super.getResource(source)
}
override def put(source: File, destination: String, overwrite: Boolean): Unit = {
val url = new URL(destination)
if (url.getProtocol != IO.FileScheme) super.put(source, destination, overwrite)
else {
// Here we duplicate the put method for files so we don't just bail on trying ot use Http handler
val resource = getResource(destination)
if (!overwrite && resource.exists()) {
throw new IOException("destination file exists and overwrite == false");
}
fireTransferInitiated(resource, TransferEvent.REQUEST_PUT);
try {
var totalLength = source.length
if (totalLength > 0) {
progress.setTotalLength(totalLength);
}
FileUtil.copy(source, new java.io.File(url.toURI), progress)
} catch {
case ex: IOException =>
fireTransferError(ex)
throw ex
case ex: RuntimeException =>
fireTransferError(ex)
throw ex
} finally {
progress.setTotalLength(null);
}
}
}
}
private[this] final class WarnOnOverwriteFileRepo extends FileRepo() {

View File

@ -54,7 +54,8 @@ object CustomPomParser {
lazy val registerDefault: Unit = ModuleDescriptorParserRegistry.getInstance.addParser(default)
def defaultTransform(parser: ModuleDescriptorParser, md: ModuleDescriptor): ModuleDescriptor =
if (transformedByThisVersion(md)) md else defaultTransformImpl(parser, md)
if (transformedByThisVersion(md)) md
else defaultTransformImpl(parser, md)
private[this] def transformedByThisVersion(md: ModuleDescriptor): Boolean =
{

View File

@ -7,7 +7,7 @@ import java.util.Date
import org.apache.ivy.core.settings.IvySettings
import org.apache.ivy.core.{ IvyContext, LogOptions }
import org.apache.ivy.core.module.descriptor.{ ModuleDescriptor, DependencyDescriptor, Artifact => IArtifact }
import org.apache.ivy.core.module.descriptor.{ Artifact => IArtifact, DefaultModuleDescriptor, DefaultDependencyDescriptor, ModuleDescriptor, DependencyDescriptor }
import org.apache.ivy.core.resolve.{ ResolvedModuleRevision, ResolveData }
import org.apache.ivy.plugins.latest.LatestStrategy
import org.apache.ivy.plugins.repository.file.{ FileRepository => IFileRepository, FileResource }
@ -94,6 +94,26 @@ class SbtChainResolver(name: String, resolvers: Seq[DependencyResolver], setting
}
else temp map { x => (forcedRevision(x), resolver) }
)
retval match {
case Right(Some((rmr, _))) =>
rmr.getDescriptor.getPublicationDate match {
case null =>
(resolver.findIvyFileRef(dd, data), rmr.getDescriptor) match {
case (null, _) =>
// In this instance, the dependency is specified by a direct URL or some other sort of "non-ivy" file
if (dd.isChanging)
Message.warn(s"Resolving a changing dependency (${rmr.getId}) with no ivy/pom file!, resolution order is undefined!")
case (ivf, dmd: DefaultModuleDescriptor) =>
val lmd = new java.util.Date(ivf.getLastModified)
Message.info(s"Getting null publication date from resolver: ${resolver} for ${rmr.getId}, setting to: ${lmd}")
dmd.setPublicationDate(lmd)
case _ =>
Message.warn(s"Getting null publication date from resolver: ${resolver} for ${rmr.getId}, resolution order is undefined!")
}
case _ => // All other cases ok
}
case _ =>
}
retval
} catch {
case ex: Exception =>
@ -111,7 +131,10 @@ class SbtChainResolver(name: String, resolvers: Seq[DependencyResolver], setting
val sorted =
if (useLatest) (foundRevisions.sortBy {
case (rmr, _) =>
rmr.getDescriptor.getPublicationDate.getTime
rmr.getDescriptor.getPublicationDate match {
case null => 0L
case d => d.getTime
}
}).reverse.headOption map {
case (rmr, resolver) =>
// Now that we know the real latest revision, let's force Ivy to use it

View File

@ -163,8 +163,8 @@ object Act {
}
def resolveTask(task: ParsedAxis[AttributeKey[_]]): Option[AttributeKey[_]] =
task match {
case ParsedGlobal | Omitted => None
case t: ParsedValue[AttributeKey[_]]@unchecked => Some(t.value)
case ParsedGlobal | Omitted => None
case t: ParsedValue[AttributeKey[_]] @unchecked => Some(t.value)
}
def filterStrings(base: Parser[String], valid: Set[String], label: String): Parser[String] =

View File

@ -0,0 +1,15 @@
[1618]: https://github.com/sbt/sbt/pull/1618
[1611]: Https://github.com/sbt/sbt/issues/1611
[@jsuereth]: https://github.com/jsuereth
### Improvements
* You can now publish to maven repositories that are `file` URLs.
### Fixes
* When resolving from maven, and unable to read maven-metadata.xml file (common given the divergence in
Maven 3 and Ivy 2), we attempt to use LastModified timestamp in lieu of "published" timestamp.
[#1618][1618] by [@jsuereth][@jsuereth]
* NPE exception when using ChainResolver and maven repositories [#1611]/[1611] by [@jsuereth][@jsuereth]

View File

@ -0,0 +1,31 @@
lazy val localRemote =
MavenRepository("remote-repo", "file:///tmp/remote-repo")
lazy val common =
project
.settings(
name := "config",
organization := "com.typesafe",
version := "0.4.9-SNAPSHOT",
publishTo := Some(localRemote),
autoScalaLibrary := false,
crossPaths := false
)
lazy val analyze =
project
.dependsOn(common)
.settings(
name := "bad-dependency",
organization := "com.example",
version := "1.0.0-SNAPSHOT",
resolvers += localRemote,
resolvers += Resolver.mavenLocal,
resolvers += Resolver.sonatypeRepo("snapshots"),
fullResolvers := fullResolvers.value.filterNot(_.name == "inter-project")
)

View File

@ -0,0 +1,3 @@
> common/publishM2
> common/publish
> analyze/update