Parse Ivy-compatible RawRepository resolvers (#49)

This commit is contained in:
Eric Peters 2019-03-22 03:07:35 -07:00 committed by Alexandre Archambault
parent 28a12368b2
commit 33aa61e8eb
8 changed files with 144 additions and 31 deletions

View File

@ -3,14 +3,15 @@ package coursier.lmcoursier
import coursier.ivy.IvyRepository
import coursier.ivy.IvyXml.{mappings => ivyXmlMappings}
import java.net.MalformedURLException
import coursier.cache.CacheUrl
import coursier.{Attributes, Dependency, Module}
import coursier.core._
import coursier.maven.MavenRepository
import org.apache.ivy.plugins.resolver.IBiblioResolver
import sbt.internal.librarymanagement.mavenint.SbtPomExtraProperties
import sbt.librarymanagement.{Configuration => _, MavenRepository => _, _}
import sbt.util.Logger
import scala.collection.JavaConverters._
object FromSbt {
@ -259,43 +260,86 @@ object FromSbt {
mavenRepositoryOpt("file://" + mavenCompatibleBase, log, authentication)
}
case r: URLRepository
if r.patterns.ivyPatterns.lengthCompare(1) == 0 &&
r.patterns.artifactPatterns.lengthCompare(1) == 0 =>
val mavenCompatibleBaseOpt0 = mavenCompatibleBaseOpt(r.patterns)
mavenCompatibleBaseOpt0 match {
case None =>
val repo = IvyRepository.parse(
r.patterns.artifactPatterns.head,
metadataPatternOpt = Some(r.patterns.ivyPatterns.head),
changing = None,
properties = ivyProperties,
dropInfoAttributes = true,
authentication = authentication
) match {
case Left(err) =>
sys.error(
s"Cannot parse Ivy patterns ${r.patterns.artifactPatterns.head} and ${r.patterns.ivyPatterns.head}: $err"
)
case Right(repo) =>
repo
}
Some(repo)
case Some(mavenCompatibleBase) =>
mavenRepositoryOpt(mavenCompatibleBase, log, authentication)
}
case r: URLRepository if patternMatchGuard(r.patterns) =>
parseMavenCompatResolver(log, ivyProperties, authentication, r.patterns)
case raw: RawRepository if raw.name == "inter-project" => // sbt.RawRepository.equals just compares names anyway
None
// Pattern Match resolver-type-specific RawRepositories
case IBiblioRepository(p) =>
parseMavenCompatResolver(log, ivyProperties, authentication, p)
case other =>
log.warn(s"Unrecognized repository ${other.name}, ignoring it")
None
}
private object IBiblioRepository {
private def stringVector(v: java.util.List[_]): Vector[String] =
Option(v).map(_.asScala.toVector).getOrElse(Vector.empty).collect {
case s: String => s
}
private def patterns(resolver: IBiblioResolver): Patterns = Patterns(
ivyPatterns = stringVector(resolver.getIvyPatterns),
artifactPatterns = stringVector(resolver.getArtifactPatterns),
isMavenCompatible = resolver.isM2compatible,
descriptorOptional = !resolver.isUseMavenMetadata,
skipConsistencyCheck = !resolver.isCheckconsistency
)
def unapply(r: Resolver): Option[Patterns] =
r match {
case raw: RawRepository =>
raw.resolver match {
case b: IBiblioResolver =>
Some(patterns(b))
.filter(patternMatchGuard)
case _ =>
None
}
case _ =>
None
}
}
private def patternMatchGuard(patterns: Patterns): Boolean =
patterns.ivyPatterns.lengthCompare(1) == 0 &&
patterns.artifactPatterns.lengthCompare(1) == 0
private def parseMavenCompatResolver(
log: Logger,
ivyProperties: Map[String, String],
authentication: Option[Authentication],
patterns: Patterns
): Option[Repository] = {
val mavenCompatibleBaseOpt0 = mavenCompatibleBaseOpt(patterns)
mavenCompatibleBaseOpt0 match {
case None =>
val repo = IvyRepository.parse(
patterns.artifactPatterns.head,
metadataPatternOpt = Some(patterns.ivyPatterns.head),
changing = None,
properties = ivyProperties,
dropInfoAttributes = true,
authentication = authentication
) match {
case Left(err) =>
sys.error(
s"Cannot parse Ivy patterns ${patterns.artifactPatterns.head} and ${patterns.ivyPatterns.head}: $err"
)
case Right(repo) =>
repo
}
Some(repo)
case Some(mavenCompatibleBase) =>
mavenRepositoryOpt(mavenCompatibleBase, log, authentication)
}
}
}

View File

@ -0,0 +1,51 @@
scalaVersion := "2.12.8"
resolvers += "Private S3 Snapshots" atS3
"s3://s3-us-west-2.amazonaws.com/bucket-name/snapshots"
resolvers += "Private S3 Releases" atS3
"s3://s3-us-west-2.amazonaws.com/bucket-name/releases"
// TODO: Would need a public s3 bucket to download an artifact
lazy val check = taskKey[Unit]("")
// Checks FromSbt.repository parses the "s3://" urls correctly.
check := {
val s: TaskStreams = streams.value
val sbtResolvers: Seq[sbt.librarymanagement.Resolver] = coursierResolvers.value
// Sanity check to ensure SBT is loading the resolvers properly
assert(sbtResolvers.exists(_.name == "Private S3 Snapshots"))
assert(sbtResolvers.exists(_.name == "Private S3 Releases"))
// Have Coursier SBT Plugin Parse the SBT Resolvers
val parsedCoursierResolvers: Seq[coursier.core.Repository] =
sbtResolvers.flatMap{ sbtResolver: sbt.librarymanagement.Resolver =>
coursier.lmcoursier.FromSbt.repository(
resolver = sbtResolver,
ivyProperties = coursier.lmcoursier.ResolutionParams.defaultIvyProperties(),
log = s.log,
authentication = None,
)
}
// Verify the input resolvers == output resolvers
assert(
sbtResolvers.size == parsedCoursierResolvers.size,
s"SBT resolvers size (${sbtResolvers.size}) did not match " +
s"Coursier resolvers size (${parsedCoursierResolvers.size})"
)
def containsRepo(repo: String): Boolean = {
parsedCoursierResolvers.collectFirst {
case m: coursier.maven.MavenRepository if m.root == repo => true
}.exists{ _ == true }
}
assert(containsRepo("s3://s3-us-west-2.amazonaws.com/bucket-name/snapshots/"),
"Didn't have snapshots s3 repo")
assert(containsRepo("s3://s3-us-west-2.amazonaws.com/bucket-name/releases/"),
"Didn't have releases s3 repo")
}

View File

@ -0,0 +1 @@
sbt.version=1.2.8

View File

@ -0,0 +1 @@
addSbtPlugin("com.frugalmechanic" % "fm-sbt-s3-resolver" % "0.18.0")

View File

@ -0,0 +1 @@
addSbtCoursier

View File

@ -0,0 +1,13 @@
addSbtPlugin {
val name = sys.props.getOrElse(
"plugin.name",
sys.error("plugin.name Java property not set")
)
val version = sys.props.getOrElse(
"plugin.version",
sys.error("plugin.version Java property not set")
)
"io.get-coursier" % name % version
}

View File

@ -0,0 +1 @@
object Foo

View File

@ -0,0 +1 @@
> check