Merge pull request #620 from coursier/develop

Various things
This commit is contained in:
Alexandre Archambault 2017-07-23 19:15:39 +02:00 committed by GitHub
commit 56b6f57f96
17 changed files with 269 additions and 63 deletions

View File

@ -74,8 +74,7 @@ object TermDisplay {
val start =
actualFraction match {
case None =>
val elem = if (watching) "." else "?"
s" [ $elem ] "
" [ ] "
case Some(frac) =>
val elem = if (watching) "." else "#"

View File

@ -64,6 +64,9 @@ final case class Attributes(
) {
def publication(name: String, ext: String): Publication =
Publication(name, `type`, ext, classifier)
def isEmpty: Boolean =
`type`.isEmpty && classifier.isEmpty
}
final case class Project(

View File

@ -3,9 +3,8 @@ package core
import scala.annotation.tailrec
import scala.language.higherKinds
import scalaz.{Monad, -\/, \/-}
import scalaz.Scalaz.{ToFunctorOps, ToTraverseOps, vectorInstance}
import scalaz.{-\/, Monad, \/, \/-}
import scalaz.Scalaz.{ToFunctorOps, ToBindOps, ToTraverseOps, vectorInstance}
sealed abstract class ResolutionProcess {
@ -166,7 +165,10 @@ object ResolutionProcess {
Missing(resolution0.missingFromCache.toSeq, resolution0, apply)
}
private def fetchAll[F[_]](modVers: Seq[(Module, String)], fetch: Fetch.Metadata[F])(implicit F: Monad[F]) = {
private[coursier] def fetchAll[F[_]](
modVers: Seq[(Module, String)],
fetch: Fetch.Metadata[F]
)(implicit F: Monad[F]): F[Vector[((Module, String), Seq[String] \/ (Artifact.Source, Project))]] = {
def uniqueModules(modVers: Seq[(Module, String)]): Stream[Seq[(Module, String)]] = {
@ -191,8 +193,11 @@ object ResolutionProcess {
uniqueModules(modVers)
.toVector
.traverse(fetch)
.map(_.flatten)
.foldLeft(F.point(Vector.empty[((Module, String), Seq[String] \/ (Artifact.Source, Project))])) {
(acc, l) =>
for (v <- acc; e <- fetch(l))
yield v ++ e
}
}
}

View File

@ -19,8 +19,9 @@ final case class MavenSource(
overrideClassifiers: Option[Seq[String]]
): Seq[Artifact] = {
val packagingTpeMap = project.packagingOpt
.filter(_ != Pom.relocatedPackaging)
val packagingOpt = project.packagingOpt.filter(_ != Pom.relocatedPackaging)
val packagingTpeMap = packagingOpt
.map { packaging =>
(MavenSource.typeDefaultClassifier(packaging), MavenSource.typeExtension(packaging)) -> packaging
}
@ -67,7 +68,18 @@ final case class MavenSource(
)
}
lazy val defaultPublication = {
lazy val defaultPublications = {
val packagingPublicationOpt = packagingOpt
.filter(_ => dependency.attributes.isEmpty)
.map { packaging =>
Publication(
dependency.module.name,
packaging,
MavenSource.typeExtension(packaging),
MavenSource.typeDefaultClassifier(packaging)
)
}
val type0 = if (dependency.attributes.`type`.isEmpty) "jar" else dependency.attributes.`type`
@ -84,41 +96,41 @@ final case class MavenSource(
MavenSource.classifierExtensionDefaultTypeOpt(classifier, ext).getOrElse(ext)
)
Publication(
dependency.module.name,
tpe,
ext,
classifier
)
val pubs = packagingPublicationOpt.toSeq :+
Publication(
dependency.module.name,
tpe,
ext,
classifier
)
pubs.distinct
}
overrideClassifiers match {
case Some(classifiers) =>
classifiers
.map { classifier =>
if (classifier == dependency.attributes.classifier)
defaultPublication
else {
val ext = "jar"
val tpe = packagingTpeMap.getOrElse(
(classifier, ext),
MavenSource.classifierExtensionDefaultTypeOpt(classifier, ext).getOrElse(ext)
)
overrideClassifiers
.fold(defaultPublications) { classifiers =>
classifiers.flatMap { classifier =>
if (classifier == dependency.attributes.classifier)
defaultPublications
else {
val ext = "jar"
val tpe = packagingTpeMap.getOrElse(
(classifier, ext),
MavenSource.classifierExtensionDefaultTypeOpt(classifier, ext).getOrElse(ext)
)
Seq(
Publication(
dependency.module.name,
tpe,
ext,
classifier
)
}
)
}
.map(artifactWithExtra)
case None =>
Seq(defaultPublication).map(artifactWithExtra)
}
}
}
.map(artifactWithExtra)
}
private val types = Map("sha1" -> "SHA-1", "md5" -> "MD5", "asc" -> "sig")
@ -239,7 +251,7 @@ final case class MavenSource(
else if (dependency.attributes.`type`.nonEmpty)
enrichedPublications.collect {
case p
if p.publication.classifier.isEmpty && (
if (p.publication.classifier.isEmpty || p.publication.classifier == MavenSource.typeDefaultClassifier(dependency.attributes.`type`)) && (
p.publication.`type` == dependency.attributes.`type` ||
(p.publication.ext == dependency.attributes.`type` && project.packagingOpt.toSeq.contains(p.publication.`type`)) // wow
) =>
@ -290,14 +302,14 @@ final case class MavenSource(
}
val defaultPublications = artifactsUnknownPublications(dependency, project, overrideClassifiers)
.map(makeOptional)
if (project.publications.isEmpty)
defaultPublications
else {
val listedPublications = artifactsKnownPublications(dependency, project, overrideClassifiers)
val listedUrls = listedPublications.map(_.url).toSet
val defaultPublications0 = defaultPublications.map(makeOptional)
val defaultPublicationsMap = defaultPublications0
val defaultPublicationsMap = defaultPublications
.map(a => a.url -> a)
.toMap
val listedPublications0 = listedPublications.map { a =>
@ -305,7 +317,7 @@ final case class MavenSource(
.get(a.url)
.fold(a)(merge(a, _))
}
val extraPublications = defaultPublications0
val extraPublications = defaultPublications
.filter(a => !listedUrls(a.url))
listedPublications0 ++ extraPublications

View File

@ -207,6 +207,8 @@ object Parse {
).right
else if (s.startsWith("ivy:"))
IvyRepository.parse(s.stripPrefix("ivy:"))
else if (s == "jitpack")
MavenRepository("https://jitpack.io").right
else
MavenRepository(s).right

View File

@ -103,6 +103,34 @@ object FromSbt {
(module0, version, url, module.isChanging)
}
def sbtClassifiersProject(
cm: GetClassifiersModule,
scalaVersion: String,
scalaBinaryVersion: String
) = {
val p = FromSbt.project(
cm.id,
cm.dependencies,
cm.configurations.map(cfg => cfg.name -> cfg.extendsConfigs.map(_.name)).toMap,
scalaVersion,
scalaBinaryVersion
)
// for w/e reasons, the dependencies sometimes don't land in the right config above
// this is a loose attempt at fixing that
cm.configurations match {
case Seq(cfg) =>
p.copy(
dependencies = p.dependencies.map {
case (_, d) => (cfg.name, d)
}
)
case _ =>
p
}
}
def project(
projectID: ModuleID,
allDependencies: Seq[ModuleID],

View File

@ -550,13 +550,7 @@ object Tasks {
val (currentProject, fallbackDependencies, configGraphs) =
if (sbtClassifiers) {
val proj = FromSbt.project(
cm.id,
cm.dependencies,
cm.configurations.map(cfg => cfg.name -> cfg.extendsConfigs.map(_.name)).toMap,
sv,
sbv
)
val proj = FromSbt.sbtClassifiersProject(cm, sv, sbv)
val fallbackDeps = FromSbt.fallbackDependencies(
cm.dependencies,
@ -1112,13 +1106,7 @@ object Tasks {
val currentProject =
if (sbtClassifiers)
FromSbt.project(
cm.id,
cm.dependencies,
cm.configurations.map(cfg => cfg.name -> cfg.extendsConfigs.map(_.name)).toMap,
sv,
sbv
)
FromSbt.sbtClassifiersProject(cm, sv, sbv)
else
proj.copy(publications = publications)
@ -1155,7 +1143,7 @@ object Tasks {
val configs =
if (withClassifiers && sbtClassifiers)
cm.configurations.map(c => c.name -> Set.empty[String]).toMap
cm.configurations.map(c => c.name -> Set(c.name)).toMap
else
shadedConfigOpt.fold(configs0) {
case (baseConfig, shadedConfig) =>
@ -1277,13 +1265,7 @@ object Tasks {
val currentProject =
if (sbtClassifiers)
FromSbt.project(
cm.id,
cm.dependencies,
cm.configurations.map(cfg => cfg.name -> cfg.extendsConfigs.map(_.name)).toMap,
sv,
sbv
)
FromSbt.sbtClassifiersProject(cm, sv, sbv)
else
proj.copy(publications = publications)

View File

@ -0,0 +1,39 @@
import Compatibility._
scalaVersion := appConfiguration.value.provider.scalaProvider.version
lazy val updateSbtClassifiersCheck = TaskKey[Unit]("updateSbtClassifiersCheck")
updateSbtClassifiersCheck := {
val configReport = updateSbtClassifiers
.value
.configuration(Default)
.getOrElse {
throw new Exception(
"default configuration not found in updateSbtClassifiers report"
)
}
def artifacts(org: String, name: String) = configReport
.modules
.collect {
case moduleReport
if moduleReport.module.organization == org &&
moduleReport.module.name == name =>
moduleReport.artifacts
}
.toSeq
.flatten
def ensureHasArtifact(org: String, name: String) =
assert(
artifacts(org, name).exists(_._2.getName.endsWith("-sources.jar")),
s"$org:$name not found"
)
ensureHasArtifact("org.scala-lang", "scala-library")
ensureHasArtifact("io.get-coursier", "coursier_" + scalaBinaryVersion.value)
ensureHasArtifact("io.get-coursier", "sbt-coursier")
}

View File

@ -0,0 +1,11 @@
{
val pluginVersion = sys.props.getOrElse(
"plugin.version",
throw new RuntimeException(
"""|The system property 'plugin.version' is not defined.
|Specify this property using the scriptedLaunchOpts -D.""".stripMargin
)
)
addSbtPlugin("io.get-coursier" % "sbt-coursier" % pluginVersion)
}

View File

@ -0,0 +1,8 @@
object Compatibility {
implicit class UpdateReportOps(val rep: sbt.UpdateReport) extends AnyVal {
def configuration(conf: sbt.Configuration) =
rep.configuration(conf.name)
}
}

View File

@ -0,0 +1 @@
> updateSbtClassifiersCheck

View File

@ -0,0 +1,72 @@
package coursier.test
import java.util.concurrent.ConcurrentHashMap
import coursier.{Fetch, Module}
import coursier.core.ResolutionProcess
import utest._
import scala.collection.JavaConverters._
import scala.concurrent.duration.DurationInt
import scalaz.{-\/, \/-}
import scalaz.concurrent.Task
object ResolutionProcessTests extends TestSuite {
val tests = TestSuite {
'fetchAll - {
// check that tasks fetching different versions of the same module are spawned sequentially
// rather than all at once
def check(extra: Int): Unit = {
val mod = Module("org", "name")
val modVers = (1 to (9 + extra))
.map(_.toString)
.map((mod, _))
val called = new ConcurrentHashMap[String, Unit]
val fetch: Fetch.Metadata[Task] = {
case Seq((`mod`, "9")) =>
// never calls the callback
Task.async { _ =>
called.put("9", ())
()
}
case Seq(mv @ (`mod`, v)) =>
Task.async { cb =>
called.put(v, ())
cb(\/-(Seq((mv, -\/(Seq("w/e"))))))
}
case _ => sys.error(s"Cannot happen ($modVers)")
}
val res = ResolutionProcess.fetchAll(modVers, fetch)
.timed(1.second)
.attempt
.unsafePerformSync
// must have timed out
assert(res.swap.exists[Throwable] { case _: java.util.concurrent.TimeoutException => true; case _ => false })
val called0 = called.asScala.iterator.map(_._1).toSet
val expectedCalled = (0 to extra)
.map(9 + _)
.map(_.toString)
.toSet
assert(called0 == expectedCalled)
}
* - check(0)
* - check(1)
* - check(3)
}
}
}

@ -1 +1 @@
Subproject commit 93eccec4ffd1719586b6f1e1dddefcbea6722e7d
Subproject commit 6b2578a25220930e60b505b90e636092757d6397

View File

@ -0,0 +1,10 @@
android.arch.core:core:1.0.0-alpha3:compile
android.arch.lifecycle:common:1.0.0-alpha3:compile
android.arch.lifecycle:extensions:1.0.0-alpha3:compile
android.arch.lifecycle:runtime:1.0.0-alpha3:compile
com.android.support:support-annotations:25.3.1:compile
com.android.support:support-compat:25.3.1:compile
com.android.support:support-core-ui:25.3.1:compile
com.android.support:support-core-utils:25.3.1:compile
com.android.support:support-fragment:25.3.1:compile
com.android.support:support-media-compat:25.3.1:compile

View File

@ -569,6 +569,7 @@ abstract class CentralTests extends TestSuite {
val zookeeperTestArtifact = zookeeperTestArtifacts.head
assert(!isActualCentral || !zookeeperTestArtifact.isOptional)
assert(zookeeperTestArtifact.attributes.`type` == "test-jar")
assert(zookeeperTestArtifact.attributes.classifier == "tests")
zookeeperTestArtifact.url.endsWith("-tests.jar")
@ -822,6 +823,33 @@ abstract class CentralTests extends TestSuite {
}
}
}
'packagingTpe - {
val mod = Module("android.arch.lifecycle", "extensions")
val ver = "1.0.0-alpha3"
val extraRepo = MavenRepository("https://maven.google.com")
* - resolutionCheck(mod, ver, extraRepos = Seq(extraRepo))
* - withArtifacts(mod, ver, "*", extraRepos = Seq(extraRepo), transitive = true) { artifacts =>
val urls = artifacts.map(_.url).toSet
val expectedUrls = Set(
"https://maven.google.com/com/android/support/support-fragment/25.3.1/support-fragment-25.3.1.aar",
"https://maven.google.com/android/arch/core/core/1.0.0-alpha3/core-1.0.0-alpha3.aar",
"https://maven.google.com/android/arch/lifecycle/runtime/1.0.0-alpha3/runtime-1.0.0-alpha3.aar",
"https://maven.google.com/android/arch/lifecycle/extensions/1.0.0-alpha3/extensions-1.0.0-alpha3.aar",
"https://maven.google.com/com/android/support/support-compat/25.3.1/support-compat-25.3.1.aar",
"https://maven.google.com/com/android/support/support-media-compat/25.3.1/support-media-compat-25.3.1.aar",
"https://maven.google.com/com/android/support/support-core-ui/25.3.1/support-core-ui-25.3.1.aar",
"https://maven.google.com/com/android/support/support-core-utils/25.3.1/support-core-utils-25.3.1.aar",
"https://maven.google.com/com/android/support/support-annotations/25.3.1/support-annotations-25.3.1.jar",
"https://maven.google.com/android/arch/lifecycle/common/1.0.0-alpha3/common-1.0.0-alpha3.jar"
)
assert(expectedUrls.forall(urls))
}
}
}
}

View File

@ -42,5 +42,10 @@ object ParseTests extends TestSuite {
val res = Parse.repository("typesafe:releases")
assert(res.exists(isMavenRepo))
}
"jitpack" - {
val res = Parse.repository("jitpack")
assert(res.exists(isMavenRepo))
}
}
}