diff --git a/cli/src/main/scala/coursier/cli/Coursier.scala b/cli/src/main/scala/coursier/cli/Coursier.scala index 8db260448..3403f0632 100644 --- a/cli/src/main/scala/coursier/cli/Coursier.scala +++ b/cli/src/main/scala/coursier/cli/Coursier.scala @@ -97,8 +97,12 @@ case class Coursier(scope: List[String], sys exit 1 } - def repr(dep: Dependency) = - s"${dep.module.organization}:${dep.module.name}:${dep.`type`}:${Some(dep.classifier).filter(_.nonEmpty).map(_+":").mkString}${dep.version}" + def repr(dep: Dependency) = { + val (type0, classifier) = dep.artifacts match { + case maven: Artifacts.Maven => (maven.`type`, maven.classifier) + } + s"${dep.module.organization}:${dep.module.name}:$type0:${Some(classifier).filter(_.nonEmpty).map(_+":").mkString}${dep.version}" + } val trDeps = res.dependencies.toList.sortBy(repr) diff --git a/core-jvm/src/main/scala/coursier/core/Remote.scala b/core-jvm/src/main/scala/coursier/core/Remote.scala index f1c610c71..cfdb54c0f 100644 --- a/core-jvm/src/main/scala/coursier/core/Remote.scala +++ b/core-jvm/src/main/scala/coursier/core/Remote.scala @@ -21,15 +21,18 @@ case class ArtifactDownloader(root: String, cache: File, logger: Option[Artifact def artifact(module: Module, version: String, - classifier: String, - `type`: String, + artifacts: Artifacts, cachePolicy: CachePolicy): EitherT[Task, String, File] = { + val (type0, classifier) = artifacts match { + case maven: Artifacts.Maven => (maven.`type`, maven.classifier) + } + val relPath = module.organization.split('.').toSeq ++ Seq( module.name, version, - s"${module.name}-$version${Some(classifier).filter(_.nonEmpty).map("-"+_).mkString}.${`type`}" + s"${module.name}-$version${Some(classifier).filter(_.nonEmpty).map("-"+_).mkString}.$type0" ) val file = (cache /: relPath)(new File(_, _)) @@ -94,7 +97,7 @@ case class ArtifactDownloader(root: String, cache: File, logger: Option[Artifact def artifact(dependency: Dependency, cachePolicy: CachePolicy = CachePolicy.Default): EitherT[Task, String, File] = - artifact(dependency.module, dependency.version, dependency.classifier, dependency.`type`, cachePolicy = cachePolicy) + artifact(dependency.module, dependency.version, dependency.artifacts, cachePolicy = cachePolicy) } diff --git a/core/src/main/scala/coursier/core/Definitions.scala b/core/src/main/scala/coursier/core/Definitions.scala index 3ecfaf01f..63cb559f2 100644 --- a/core/src/main/scala/coursier/core/Definitions.scala +++ b/core/src/main/scala/coursier/core/Definitions.scala @@ -32,13 +32,19 @@ sealed abstract class Scope(val name: String) case class Dependency(module: Module, version: String, scope: Scope, - `type`: String, - classifier: String, + artifacts: Artifacts, exclusions: Set[(String, String)], optional: Boolean) { def moduleVersion = (module, version) } +sealed trait Artifacts + +object Artifacts { + case class Maven(`type`: String, + classifier: String) extends Artifacts +} + case class Project(module: Module, version: String, dependencies: Seq[Dependency], diff --git a/core/src/main/scala/coursier/core/Resolver.scala b/core/src/main/scala/coursier/core/Resolver.scala index 9ca973cc0..7b901afcd 100644 --- a/core/src/main/scala/coursier/core/Resolver.scala +++ b/core/src/main/scala/coursier/core/Resolver.scala @@ -70,7 +70,9 @@ object Resolver { type DepMgmtKey = (String, String, String) def dependencyManagementKey(dep: Dependency): DepMgmtKey = - (dep.module.organization, dep.module.name, dep.`type`) + dep.artifacts match { + case Artifacts.Maven(type0, _) => (dep.module.organization, dep.module.name, type0) + } def dependencyManagementAdd(m: Map[DepMgmtKey, Dependency], dep: Dependency): Map[DepMgmtKey, Dependency] = { val key = dependencyManagementKey(dep) if (m.contains(key)) m else m + (key -> dep) @@ -119,7 +121,13 @@ object Resolver { name = substituteProps(dep.module.name) ), version = substituteProps(dep.version), - `type` = substituteProps(dep.`type`), + artifacts = dep.artifacts match { + case maven: Artifacts.Maven => + maven.copy( + `type` = substituteProps(maven.`type`), + classifier = substituteProps(maven.classifier) + ) + }, scope = Parse.scope(substituteProps(dep.scope.name)), exclusions = dep.exclusions .map{case (org, name) => (substituteProps(org), substituteProps(name))} diff --git a/core/src/main/scala/coursier/core/Xml.scala b/core/src/main/scala/coursier/core/Xml.scala index 9c7d0426d..0e5175683 100644 --- a/core/src/main/scala/coursier/core/Xml.scala +++ b/core/src/main/scala/coursier/core/Xml.scala @@ -85,8 +85,7 @@ object Xml { mod, version0, scopeOpt getOrElse defaultScope, - typeOpt getOrElse defaultType, - classifierOpt getOrElse defaultClassifier, + Artifacts.Maven(typeOpt getOrElse defaultType, classifierOpt getOrElse defaultClassifier), exclusions.map(mod => (mod.organization, mod.name)).toSet, optional ) diff --git a/core/src/main/scala/coursier/package.scala b/core/src/main/scala/coursier/package.scala index 881ea8139..c258a3ab2 100644 --- a/core/src/main/scala/coursier/package.scala +++ b/core/src/main/scala/coursier/package.scala @@ -8,11 +8,20 @@ package object coursier { def apply(module: Module, version: String, scope: Scope = Scope.Other(""), // Substituted by Resolver with its own default scope (compile) - `type`: String = "jar", - classifier: String = "", + artifacts: Artifacts = Artifacts.Maven(), exclusions: Set[(String, String)] = Set.empty, optional: Boolean = false): Dependency = - core.Dependency(module, version, scope, `type`, classifier, exclusions, optional) + core.Dependency(module, version, scope, artifacts, exclusions, optional) + } + + type Artifacts = core.Artifacts + object Artifacts { + type Maven = core.Artifacts.Maven + object Maven { + def apply(`type`: String = "jar", + classifier: String = ""): Maven = + core.Artifacts.Maven(`type`, classifier) + } } type Project = core.Project diff --git a/core/src/test/scala/coursier/test/CentralTests.scala b/core/src/test/scala/coursier/test/CentralTests.scala index 2d1c3993e..46a3e635f 100644 --- a/core/src/test/scala/coursier/test/CentralTests.scala +++ b/core/src/test/scala/coursier/test/CentralTests.scala @@ -12,8 +12,12 @@ object CentralTests extends TestSuite { repository.mavenCentral ) - def repr(dep: Dependency) = - s"${dep.module.organization}:${dep.module.name}:${dep.`type`}:${Some(dep.classifier).filter(_.nonEmpty).map(_+":").mkString}${dep.version}" + def repr(dep: Dependency) = { + val (type0, classifier) = dep.artifacts match { + case maven: Artifacts.Maven => (maven.`type`, maven.classifier) + } + s"${dep.module.organization}:${dep.module.name}:$type0:${Some(classifier).filter(_.nonEmpty).map(_+":").mkString}${dep.version}" + } def resolutionCheck(module: Module, version: String) = async { diff --git a/core/src/test/scala/coursier/test/PomParsingTests.scala b/core/src/test/scala/coursier/test/PomParsingTests.scala index 733e42f61..a7ddddbde 100644 --- a/core/src/test/scala/coursier/test/PomParsingTests.scala +++ b/core/src/test/scala/coursier/test/PomParsingTests.scala @@ -21,7 +21,7 @@ object PomParsingTests extends TestSuite { """ - val expected = \/-(Dependency(Module("comp", "lib"), "2.1", classifier = "extra")) + val expected = \/-(Dependency(Module("comp", "lib"), "2.1", artifacts = Artifacts.Maven(classifier = "extra"))) val result = Xml.dependency(xmlParse(depNode).right.get) diff --git a/web/src/main/scala/coursier/web/Backend.scala b/web/src/main/scala/coursier/web/Backend.scala index 2c8e50138..0916c2d96 100644 --- a/web/src/main/scala/coursier/web/Backend.scala +++ b/web/src/main/scala/coursier/web/Backend.scala @@ -217,7 +217,11 @@ object App { label ) - def depItem(dep: Dependency) = + def depItem(dep: Dependency) = { + val (type0, classifier) = dep.artifacts match { + case maven: Artifacts.Maven => (maven.`type`, maven.classifier) + } + <.tr( ^.`class` := (if (res.errors.contains(dep.moduleVersion)) "danger" else ""), <.td(dep.module.organization), @@ -225,8 +229,8 @@ object App { <.td(dep.version), <.td(Seq[Seq[TagMod]]( if (dep.scope == Scope.Compile) Seq() else Seq(infoLabel(dep.scope.name)), - if (dep.`type`.isEmpty || dep.`type` == "jar") Seq() else Seq(infoLabel(dep.`type`)), - if (dep.classifier.isEmpty) Seq() else Seq(infoLabel(dep.classifier)), + if (type0.isEmpty || type0 == "jar") Seq() else Seq(infoLabel(type0)), + if (classifier.isEmpty) Seq() else Seq(infoLabel(classifier)), Some(dep.exclusions).filter(_.nonEmpty).map(excls => infoPopOver("Exclusions", excls.toList.sorted.map{case (org, name) => s"$org:$name"}.mkString("; "))).toSeq, if (dep.optional) Seq(infoLabel("optional")) else Seq(), res.errors.get(dep.moduleVersion).map(errs => errorPopOver("Error", errs.mkString("; "))).toSeq @@ -255,6 +259,7 @@ object App { } )) ) + } val sortedDeps = res.dependencies.toList .sortBy(dep => coursier.core.Module.unapply(dep.module).get)