Better handling of classifiers

This commit is contained in:
Alexandre Archambault 2015-12-30 01:34:35 +01:00
parent eaa7874874
commit 0e5118befe
8 changed files with 157 additions and 120 deletions

View File

@ -47,7 +47,10 @@ case class Dependency(
case class Attributes(
`type`: String,
classifier: String
)
) {
def publication(name: String, ext: String): Publication =
Publication(name, `type`, ext, classifier)
}
case class Project(
module: Module,
@ -133,8 +136,11 @@ case class SnapshotVersioning(
case class Publication(
name: String,
`type`: String,
ext: String
)
ext: String,
classifier: String
) {
def attributes: Attributes = Attributes(`type`, classifier)
}
case class Artifact(
url: String,
@ -146,6 +152,10 @@ case class Artifact(
object Artifact {
trait Source {
def artifacts(dependency: Dependency, project: Project): Seq[Artifact]
def artifacts(
dependency: Dependency,
project: Project,
overrideClassifiers: Option[Seq[String]]
): Seq[Artifact]
}
}

View File

@ -746,16 +746,22 @@ case class Resolution(
.getOrElse(Map.empty)
)
def artifacts: Seq[Artifact] =
private def artifacts0(overrideClassifiers: Option[Seq[String]]): Seq[Artifact] =
for {
dep <- minDependencies.toSeq
(source, proj) <- projectCache
.get(dep.moduleVersion)
.toSeq
artifact <- source
.artifacts(dep, proj)
.artifacts(dep, proj, overrideClassifiers)
} yield artifact
def classifiersArtifacts(classifiers: Seq[String]): Seq[Artifact] =
artifacts0(Some(classifiers))
def artifacts: Seq[Artifact] =
artifacts0(None)
def dependencyArtifacts: Seq[(Dependency, Artifact)] =
for {
dep <- minDependencies.toSeq
@ -763,7 +769,7 @@ case class Resolution(
.get(dep.moduleVersion)
.toSeq
artifact <- source
.artifacts(dep, proj)
.artifacts(dep, proj, None)
} yield dep -> artifact
def errors: Seq[(Dependency, Seq[String])] =

View File

@ -165,37 +165,53 @@ case class IvyRepository(
val source: Artifact.Source = new Artifact.Source {
def artifacts(dependency: Dependency, project: Project) =
project
.publications
.collect {
case (conf, p)
if conf == "*" ||
conf == dependency.configuration ||
project.allConfigurations.getOrElse(dependency.configuration, Set.empty).contains(conf) =>
p
}
.flatMap { p =>
substitute(variables(
dependency.module.organization,
dependency.module.name,
dependency.version,
p.`type`,
p.name,
p.ext
)).toList.map(p -> _)
}
.map { case (p, url) =>
Artifact(
url,
Map.empty,
Map.empty,
Attributes(p.`type`, p.ext),
changing = changing.getOrElse(project.version.contains("-SNAPSHOT")) // could be more reliable
)
.withDefaultChecksums
.withDefaultSignature
def artifacts(
dependency: Dependency,
project: Project,
overrideClassifiers: Option[Seq[String]]
) = {
val retained =
overrideClassifiers match {
case None =>
project.publications.collect {
case (conf, p)
if conf == "*" ||
conf == dependency.configuration ||
project.allConfigurations.getOrElse(dependency.configuration, Set.empty).contains(conf) =>
p
}
case Some(classifiers) =>
val classifiersSet = classifiers.toSet
project.publications.collect {
case (_, p) if classifiersSet(p.classifier) =>
p
}
}
val retainedWithUrl = retained.flatMap { p =>
substitute(variables(
dependency.module.organization,
dependency.module.name,
dependency.version,
p.`type`,
p.name,
p.ext
)).toList.map(p -> _)
}
retainedWithUrl.map { case (p, url) =>
Artifact(
url,
Map.empty,
Map.empty,
p.attributes,
changing = changing.getOrElse(project.version.contains("-SNAPSHOT")) // could be more reliable
)
.withDefaultChecksums
.withDefaultSignature
}
}
}

View File

@ -71,7 +71,8 @@ object IvyXml {
val type0 = node.attribute("type").getOrElse("jar")
val ext = node.attribute("ext").getOrElse(type0)
val confs = node.attribute("conf").toOption.fold(Seq("*"))(_.split(','))
confs.map(_ -> Publication(name, type0, ext))
val classifier = node.attribute("classifier").toOption.getOrElse("")
confs.map(_ -> Publication(name, type0, ext, classifier))
}
.groupBy { case (conf, _) => conf }
.map { case (conf, l) => conf -> l.map { case (_, p) => p } }
@ -115,7 +116,7 @@ object IvyXml {
None,
if (publicationsOpt.isEmpty)
// no publications node -> default JAR artifact
Seq("*" -> Publication(module.name, "jar", "jar"))
Seq("*" -> Publication(module.name, "jar", "jar", ""))
else {
// publications node is there -> only its content (if it is empty, no artifacts,
// as per the Ivy manual)

View File

@ -244,7 +244,10 @@ case class MavenRepository(
xml <- \/.fromEither(compatibility.xmlParse(str))
_ <- if (xml.label == "project") \/-(()) else -\/("Project definition not found")
proj <- Pom.project(xml)
} yield proj.copy(configurations = defaultConfigurations)): (String \/ Project)
} yield proj.copy(
configurations = defaultConfigurations,
publications = ???
)): (String \/ Project)
}
}
}

View File

@ -39,86 +39,74 @@ case class MavenSource(
def artifacts(
dependency: Dependency,
project: Project
project: Project,
overrideClassifiers: Option[Seq[String]]
): Seq[Artifact] = {
def ivyLikePath0(subDir: String, baseSuffix: String, ext: String) =
ivyLikePath(
dependency.module.organization,
dependency.module.name,
project.version,
subDir,
baseSuffix,
ext
)
val path =
if (ivyLike)
ivyLikePath0(dependency.attributes.`type` + "s", "", dependency.attributes.`type`)
else {
val versioning =
project
.snapshotVersioning
.flatMap(versioning =>
mavenVersioning(versioning, dependency.attributes.classifier, dependency.attributes.`type`)
)
dependency.module.organization.split('.').toSeq ++ Seq(
dependency.module.name,
def artifactOf(module: Module, publication: Publication) = {
def ivyLikePath0(subDir: String, baseSuffix: String, ext: String) =
ivyLikePath(
module.organization,
module.name,
project.version,
s"${dependency.module.name}-${versioning getOrElse project.version}${Some(dependency.attributes.classifier).filter(_.nonEmpty).map("-"+_).mkString}.${dependency.attributes.`type`}"
subDir,
baseSuffix,
ext
)
val path =
if (ivyLike)
ivyLikePath0(publication.`type` + "s", "", publication.ext)
else {
val versioning =
project
.snapshotVersioning
.flatMap(versioning =>
mavenVersioning(versioning, publication.classifier, publication.`type`)
)
module.organization.split('.').toSeq ++ Seq(
module.name,
project.version,
s"${module.name}-${versioning getOrElse project.version}${Some(publication.classifier).filter(_.nonEmpty).map("-" + _).mkString}.${publication.ext}"
)
}
val changing0 = changing.getOrElse(project.version.contains("-SNAPSHOT"))
var artifact =
Artifact(
root + path.mkString("/"),
Map.empty,
Map.empty,
publication.attributes,
changing = changing0
)
.withDefaultChecksums
if (publication.ext == "jar") {
artifact = artifact.withDefaultSignature
}
val changing0 = changing.getOrElse(project.version.contains("-SNAPSHOT"))
var artifact =
Artifact(
root + path.mkString("/"),
Map.empty,
Map.empty,
dependency.attributes,
changing = changing0
)
.withDefaultChecksums
if (dependency.attributes.`type` == "jar") {
artifact = artifact.withDefaultSignature
// FIXME Snapshot versioning of sources and javadoc is not taken into account here.
// Will be ok if it's the same as the main JAR though.
artifact =
if (ivyLike) {
val srcPath = root + ivyLikePath0("srcs", "-sources", "jar").mkString("/")
val javadocPath = root + ivyLikePath0("docs", "-javadoc", "jar").mkString("/")
artifact
.copy(
extra = artifact.extra ++ Map(
"sources" -> Artifact(
srcPath,
Map.empty,
Map.empty,
Attributes("jar", "src"), // Are these the right attributes?
changing = changing0
)
.withDefaultChecksums
.withDefaultSignature,
"javadoc" -> Artifact(
javadocPath,
Map.empty,
Map.empty,
Attributes("jar", "javadoc"), // Same comment as above
changing = changing0
)
.withDefaultChecksums
.withDefaultSignature
))
} else
artifact
.withJavadocSources
artifact
}
Seq(artifact)
overrideClassifiers match {
case Some(classifiers) =>
val classifiersSet = classifiers.toSet
project.publications.collect {
case (_, p) if classifiersSet(p.classifier) =>
artifactOf(dependency.module, p)
}
case None =>
Seq(
artifactOf(
dependency.module,
dependency.attributes.publication(
dependency.module.name,
dependency.attributes.`type`
)
)
)
}
}
}

View File

@ -3,12 +3,21 @@ package coursier
import scalaz.{ -\/, \/-, Monad, EitherT }
case class InterProjectSource(artifacts: Map[(Module, String), Map[String, Seq[Artifact]]]) extends Artifact.Source {
def artifacts(dependency: Dependency, project: Project): Seq[Artifact] =
artifacts
.get(dependency.moduleVersion)
.toSeq
.flatMap(_.get(dependency.configuration))
.flatten
def artifacts(
dependency: Dependency,
project: Project,
overrideClassifiers: Option[Seq[String]]
): Seq[Artifact] =
overrideClassifiers match {
case None =>
artifacts
.get(dependency.moduleVersion)
.toSeq
.flatMap(_.get(dependency.configuration))
.flatten
case Some(_) =>
Nil
}
}
case class InterProjectRepository(projects: Seq[(Project, Seq[(String, Seq[Artifact])])]) extends Repository {

View File

@ -8,7 +8,11 @@ import scalaz.Scalaz._
class TestRepository(projects: Map[(Module, String), Project]) extends Repository {
val source = new core.Artifact.Source {
def artifacts(dependency: Dependency, project: Project) = ???
def artifacts(
dependency: Dependency,
project: Project,
overrideClassifiers: Option[Seq[String]]
) = ???
}
def find[F[_]](
module: Module,