mirror of https://github.com/sbt/sbt.git
Replace scopes with Ivy-like configuration
This commit is contained in:
parent
d3cd484c15
commit
e4dfc862b4
|
|
@ -171,7 +171,7 @@ class Helper(
|
|||
}
|
||||
|
||||
val deps = moduleVersions.map{case (mod, ver) =>
|
||||
Dependency(mod, ver, scope = Scope.Runtime)
|
||||
Dependency(mod, ver, configuration = "runtime")
|
||||
}
|
||||
|
||||
val forceVersions = {
|
||||
|
|
|
|||
|
|
@ -24,8 +24,6 @@ case class Module(
|
|||
override def toString = s"$organization:$name"
|
||||
}
|
||||
|
||||
sealed abstract class Scope(val name: String)
|
||||
|
||||
/**
|
||||
* Dependencies with the same @module will typically see their @version-s merged.
|
||||
*
|
||||
|
|
@ -35,7 +33,7 @@ sealed abstract class Scope(val name: String)
|
|||
case class Dependency(
|
||||
module: Module,
|
||||
version: String,
|
||||
scope: Scope,
|
||||
configuration: String,
|
||||
attributes: Attributes,
|
||||
exclusions: Set[(String, String)],
|
||||
optional: Boolean
|
||||
|
|
@ -51,9 +49,10 @@ case class Attributes(
|
|||
case class Project(
|
||||
module: Module,
|
||||
version: String,
|
||||
dependencies: Seq[Dependency],
|
||||
dependencies: Seq[(String, Dependency)],
|
||||
parent: Option[(Module, String)],
|
||||
dependencyManagement: Seq[Dependency],
|
||||
dependencyManagement: Seq[(String, Dependency)],
|
||||
configurations: Map[String, Seq[String]],
|
||||
properties: Map[String, String],
|
||||
profiles: Seq[Profile],
|
||||
versions: Option[Versions],
|
||||
|
|
@ -62,23 +61,14 @@ case class Project(
|
|||
def moduleVersion = (module, version)
|
||||
}
|
||||
|
||||
object Scope {
|
||||
case object Compile extends Scope("compile")
|
||||
case object Runtime extends Scope("runtime")
|
||||
case object Test extends Scope("test")
|
||||
case object Provided extends Scope("provided")
|
||||
case object Import extends Scope("import")
|
||||
case class Other(override val name: String) extends Scope(name)
|
||||
}
|
||||
|
||||
case class Activation(properties: Seq[(String, Option[String])])
|
||||
|
||||
case class Profile(
|
||||
id: String,
|
||||
activeByDefault: Option[Boolean],
|
||||
activation: Activation,
|
||||
dependencies: Seq[Dependency],
|
||||
dependencyManagement: Seq[Dependency],
|
||||
dependencies: Seq[(String, Dependency)],
|
||||
dependencyManagement: Seq[(String, Dependency)],
|
||||
properties: Map[String, String]
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -2,39 +2,56 @@ package coursier.core
|
|||
|
||||
object Orders {
|
||||
|
||||
/** Minimal ad-hoc partial order */
|
||||
trait PartialOrder[A] {
|
||||
/**
|
||||
* x < y: Some(neg. integer)
|
||||
* x == y: Some(0)
|
||||
* x > y: Some(pos. integer)
|
||||
* x, y not related: None
|
||||
*/
|
||||
def cmp(x: A, y: A): Option[Int]
|
||||
trait PartialOrdering[T] extends scala.math.PartialOrdering[T] {
|
||||
def lteq(x: T, y: T): Boolean =
|
||||
tryCompare(x, y)
|
||||
.exists(_ <= 0)
|
||||
}
|
||||
|
||||
/**
|
||||
* Only relations:
|
||||
* Compile < Runtime < Test
|
||||
*/
|
||||
implicit val mavenScopePartialOrder: PartialOrder[Scope] =
|
||||
new PartialOrder[Scope] {
|
||||
val higher = Map[Scope, Set[Scope]](
|
||||
Scope.Compile -> Set(Scope.Runtime, Scope.Test),
|
||||
Scope.Runtime -> Set(Scope.Test)
|
||||
)
|
||||
def configurationPartialOrder(configurations: Map[String, Seq[String]]): PartialOrdering[String] =
|
||||
new PartialOrdering[String] {
|
||||
def allParents(config: String): Set[String] = {
|
||||
def helper(configs: Set[String], acc: Set[String]): Set[String] =
|
||||
if (configs.isEmpty)
|
||||
acc
|
||||
else if (configs.exists(acc))
|
||||
helper(configs -- acc, acc)
|
||||
else if (configs.exists(!configurations.contains(_))) {
|
||||
val (remaining, notFound) = configs.partition(configurations.contains)
|
||||
helper(remaining, acc ++ notFound)
|
||||
} else {
|
||||
val extraConfigs = configs.flatMap(configurations)
|
||||
helper(extraConfigs, acc ++ configs)
|
||||
}
|
||||
|
||||
def cmp(x: Scope, y: Scope) =
|
||||
if (x == y) Some(0)
|
||||
else if (higher.get(x).exists(_(y))) Some(-1)
|
||||
else if (higher.get(y).exists(_(x))) Some(1)
|
||||
else None
|
||||
helper(Set(config), Set.empty)
|
||||
}
|
||||
|
||||
val allParentsMap = configurations
|
||||
.keys
|
||||
.toList
|
||||
.map(config => config -> (allParents(config) - config))
|
||||
.toMap
|
||||
|
||||
def tryCompare(x: String, y: String) =
|
||||
if (x == y)
|
||||
Some(0)
|
||||
else if (allParentsMap.get(x).exists(_(y)))
|
||||
Some(-1)
|
||||
else if (allParentsMap.get(y).exists(_(x)))
|
||||
Some(1)
|
||||
else
|
||||
None
|
||||
}
|
||||
|
||||
/** Non-optional < optional */
|
||||
implicit val optionalPartialOrder: PartialOrder[Boolean] =
|
||||
new PartialOrder[Boolean] {
|
||||
def cmp(x: Boolean, y: Boolean) =
|
||||
val optionalPartialOrder: PartialOrdering[Boolean] =
|
||||
new PartialOrdering[Boolean] {
|
||||
def tryCompare(x: Boolean, y: Boolean) =
|
||||
Some(
|
||||
if (x == y) 0
|
||||
else if (x) 1
|
||||
|
|
@ -51,8 +68,8 @@ object Orders {
|
|||
*
|
||||
* In particular, no exclusions <= anything <= Set(("*", "*"))
|
||||
*/
|
||||
implicit val exclusionsPartialOrder: PartialOrder[Set[(String, String)]] =
|
||||
new PartialOrder[Set[(String, String)]] {
|
||||
val exclusionsPartialOrder: PartialOrdering[Set[(String, String)]] =
|
||||
new PartialOrdering[Set[(String, String)]] {
|
||||
def boolCmp(a: Boolean, b: Boolean) = (a, b) match {
|
||||
case (true, true) => Some(0)
|
||||
case (true, false) => Some(1)
|
||||
|
|
@ -60,7 +77,7 @@ object Orders {
|
|||
case (false, false) => None
|
||||
}
|
||||
|
||||
def cmp(x: Set[(String, String)], y: Set[(String, String)]) = {
|
||||
def tryCompare(x: Set[(String, String)], y: Set[(String, String)]) = {
|
||||
val (xAll, xExcludeByOrg1, xExcludeByName1, xRemaining0) = Exclusions.partition(x)
|
||||
val (yAll, yExcludeByOrg1, yExcludeByName1, yRemaining0) = Exclusions.partition(y)
|
||||
|
||||
|
|
@ -102,19 +119,22 @@ object Orders {
|
|||
* Assume all dependencies have same `module`, `version`, and `artifact`; see `minDependencies`
|
||||
* if they don't.
|
||||
*/
|
||||
def minDependenciesUnsafe(dependencies: Set[Dependency]): Set[Dependency] = {
|
||||
def minDependenciesUnsafe(
|
||||
dependencies: Set[Dependency],
|
||||
configs: ((Module, String)) => Map[String, Seq[String]]
|
||||
): Set[Dependency] = {
|
||||
val groupedDependencies = dependencies
|
||||
.groupBy(dep => (dep.optional, dep.scope))
|
||||
.groupBy(dep => (dep.optional, dep.configuration))
|
||||
.mapValues(deps => deps.head.copy(exclusions = deps.foldLeft(Exclusions.one)((acc, dep) => Exclusions.meet(acc, dep.exclusions))))
|
||||
.toList
|
||||
|
||||
val remove =
|
||||
for {
|
||||
List(((xOpt, xScope), xDep), ((yOpt, yScope), yDep)) <- groupedDependencies.combinations(2)
|
||||
optCmp <- optionalPartialOrder.cmp(xOpt, yOpt).iterator
|
||||
scopeCmp <- mavenScopePartialOrder.cmp(xScope, yScope).iterator
|
||||
optCmp <- optionalPartialOrder.tryCompare(xOpt, yOpt).iterator
|
||||
scopeCmp <- configurationPartialOrder(configs(xDep.moduleVersion)).tryCompare(xScope, yScope).iterator
|
||||
if optCmp*scopeCmp >= 0
|
||||
exclCmp <- exclusionsPartialOrder.cmp(xDep.exclusions, yDep.exclusions).iterator
|
||||
exclCmp <- exclusionsPartialOrder.tryCompare(xDep.exclusions, yDep.exclusions).iterator
|
||||
if optCmp*exclCmp >= 0
|
||||
if scopeCmp*exclCmp >= 0
|
||||
xIsMin = optCmp < 0 || scopeCmp < 0 || exclCmp < 0
|
||||
|
|
@ -130,10 +150,13 @@ object Orders {
|
|||
*
|
||||
* The returned set brings exactly the same things as `dependencies`, with no redundancy.
|
||||
*/
|
||||
def minDependencies(dependencies: Set[Dependency]): Set[Dependency] = {
|
||||
def minDependencies(
|
||||
dependencies: Set[Dependency],
|
||||
configs: ((Module, String)) => Map[String, Seq[String]]
|
||||
): Set[Dependency] = {
|
||||
dependencies
|
||||
.groupBy(_.copy(scope = Scope.Other(""), exclusions = Set.empty, optional = false))
|
||||
.mapValues(minDependenciesUnsafe)
|
||||
.groupBy(_.copy(configuration = "", exclusions = Set.empty, optional = false))
|
||||
.mapValues(minDependenciesUnsafe(_, configs))
|
||||
.valuesIterator
|
||||
.fold(Set.empty)(_ ++ _)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,15 +4,6 @@ import coursier.core.compatibility._
|
|||
|
||||
object Parse {
|
||||
|
||||
def scope(s: String): Scope = s match {
|
||||
case "compile" => Scope.Compile
|
||||
case "runtime" => Scope.Runtime
|
||||
case "test" => Scope.Test
|
||||
case "provided" => Scope.Provided
|
||||
case "import" => Scope.Import
|
||||
case other => Scope.Other(other)
|
||||
}
|
||||
|
||||
def version(s: String): Option[Version] = {
|
||||
if (s.isEmpty || s.exists(c => c != '.' && c != '-' && c != '_' && !c.letterOrDigit)) None
|
||||
else Some(Version(s))
|
||||
|
|
|
|||
|
|
@ -37,22 +37,22 @@ object Resolution {
|
|||
(dep.module.organization, dep.module.name, dep.attributes.`type`)
|
||||
|
||||
def add(
|
||||
dict: Map[Key, Dependency],
|
||||
dep: Dependency
|
||||
): Map[Key, Dependency] = {
|
||||
dict: Map[Key, (String, Dependency)],
|
||||
item: (String, Dependency)
|
||||
): Map[Key, (String, Dependency)] = {
|
||||
|
||||
val key0 = key(dep)
|
||||
val key0 = key(item._2)
|
||||
|
||||
if (dict.contains(key0))
|
||||
dict
|
||||
else
|
||||
dict + (key0 -> dep)
|
||||
dict + (key0 -> item)
|
||||
}
|
||||
|
||||
def addSeq(
|
||||
dict: Map[Key, Dependency],
|
||||
deps: Seq[Dependency]
|
||||
): Map[Key, Dependency] =
|
||||
dict: Map[Key, (String, Dependency)],
|
||||
deps: Seq[(String, Dependency)]
|
||||
): Map[Key, (String, Dependency)] =
|
||||
(dict /: deps)(add)
|
||||
}
|
||||
|
||||
|
|
@ -62,14 +62,14 @@ object Resolution {
|
|||
): Map[String, String] =
|
||||
dict ++ other.filterKeys(!dict.contains(_))
|
||||
|
||||
def addDependencies(deps: Seq[Seq[Dependency]]): Seq[Dependency] = {
|
||||
def addDependencies(deps: Seq[Seq[(String, Dependency)]]): Seq[(String, Dependency)] = {
|
||||
val res =
|
||||
(deps :\ (Set.empty[DepMgmt.Key], Seq.empty[Dependency])) {
|
||||
(deps :\ (Set.empty[DepMgmt.Key], Seq.empty[(String, Dependency)])) {
|
||||
case (deps0, (set, acc)) =>
|
||||
val deps = deps0
|
||||
.filter(dep => !set(DepMgmt.key(dep)))
|
||||
.filter{case (_, dep) => !set(DepMgmt.key(dep))}
|
||||
|
||||
(set ++ deps.map(DepMgmt.key), acc ++ deps)
|
||||
(set ++ deps.map{case (_, dep) => DepMgmt.key(dep)}, acc ++ deps)
|
||||
}
|
||||
|
||||
res._2
|
||||
|
|
@ -83,9 +83,9 @@ object Resolution {
|
|||
* Substitutes `properties` in `dependencies`.
|
||||
*/
|
||||
def withProperties(
|
||||
dependencies: Seq[Dependency],
|
||||
dependencies: Seq[(String, Dependency)],
|
||||
properties: Map[String, String]
|
||||
): Seq[Dependency] = {
|
||||
): Seq[(String, Dependency)] = {
|
||||
|
||||
def substituteProps(s: String) = {
|
||||
val matches = propRegex
|
||||
|
|
@ -107,8 +107,8 @@ object Resolution {
|
|||
}
|
||||
|
||||
dependencies
|
||||
.map{ dep =>
|
||||
dep.copy(
|
||||
.map {case (config, dep) =>
|
||||
substituteProps(config) -> dep.copy(
|
||||
module = dep.module.copy(
|
||||
organization = substituteProps(dep.module.organization),
|
||||
name = substituteProps(dep.module.name)
|
||||
|
|
@ -118,7 +118,7 @@ object Resolution {
|
|||
`type` = substituteProps(dep.attributes.`type`),
|
||||
classifier = substituteProps(dep.attributes.classifier)
|
||||
),
|
||||
scope = Parse.scope(substituteProps(dep.scope.name)),
|
||||
configuration = substituteProps(dep.configuration),
|
||||
exclusions = dep.exclusions
|
||||
.map{case (org, name) =>
|
||||
(substituteProps(org), substituteProps(name))
|
||||
|
|
@ -209,25 +209,6 @@ object Resolution {
|
|||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* If one of our dependency has scope `base`, and a transitive
|
||||
* dependency of it has scope `transitive`, return the scope of
|
||||
* the latter for us, if any. If empty, means the transitive dependency
|
||||
* should not be considered a dependency for us.
|
||||
*
|
||||
* See https://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html#Dependency_Scope.
|
||||
*/
|
||||
def resolveScope(
|
||||
base: Scope,
|
||||
transitive: Scope
|
||||
): Option[Scope] =
|
||||
(base, transitive) match {
|
||||
case (other, Scope.Compile) => Some(other)
|
||||
case (Scope.Compile, Scope.Runtime) => Some(Scope.Runtime)
|
||||
case (other, Scope.Runtime) => Some(other)
|
||||
case _ => None
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies `dependencyManagement` to `dependencies`.
|
||||
*
|
||||
|
|
@ -235,36 +216,39 @@ object Resolution {
|
|||
* `dependencyManagement`.
|
||||
*/
|
||||
def depsWithDependencyManagement(
|
||||
dependencies: Seq[Dependency],
|
||||
dependencyManagement: Seq[Dependency]
|
||||
): Seq[Dependency] = {
|
||||
dependencies: Seq[(String, Dependency)],
|
||||
dependencyManagement: Seq[(String, Dependency)]
|
||||
): Seq[(String, Dependency)] = {
|
||||
|
||||
// See http://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html#Dependency_Management
|
||||
|
||||
lazy val dict = DepMgmt.addSeq(Map.empty, dependencyManagement)
|
||||
|
||||
dependencies
|
||||
.map { dep0 =>
|
||||
.map {case (config0, dep0) =>
|
||||
var config = config0
|
||||
var dep = dep0
|
||||
|
||||
for (mgmtDep <- dict.get(DepMgmt.key(dep0))) {
|
||||
for ((mgmtConfig, mgmtDep) <- dict.get(DepMgmt.key(dep0))) {
|
||||
if (dep.version.isEmpty)
|
||||
dep = dep.copy(version = mgmtDep.version)
|
||||
if (dep.scope.name.isEmpty)
|
||||
dep = dep.copy(scope = mgmtDep.scope)
|
||||
if (config.isEmpty)
|
||||
config = mgmtConfig
|
||||
|
||||
if (dep.exclusions.isEmpty)
|
||||
dep = dep.copy(exclusions = mgmtDep.exclusions)
|
||||
}
|
||||
|
||||
dep
|
||||
(config, dep)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
def withDefaultScope(dep: Dependency): Dependency =
|
||||
if (dep.scope.name.isEmpty)
|
||||
dep.copy(scope = Scope.Compile)
|
||||
val defaultConfiguration = "compile"
|
||||
|
||||
def withDefaultConfig(dep: Dependency): Dependency =
|
||||
if (dep.configuration.isEmpty)
|
||||
dep.copy(configuration = defaultConfiguration)
|
||||
else
|
||||
dep
|
||||
|
||||
|
|
@ -272,19 +256,37 @@ object Resolution {
|
|||
* Filters `dependencies` with `exclusions`.
|
||||
*/
|
||||
def withExclusions(
|
||||
dependencies: Seq[Dependency],
|
||||
dependencies: Seq[(String, Dependency)],
|
||||
exclusions: Set[(String, String)]
|
||||
): Seq[Dependency] = {
|
||||
): Seq[(String, Dependency)] = {
|
||||
|
||||
val filter = Exclusions(exclusions)
|
||||
|
||||
dependencies
|
||||
.filter(dep => filter(dep.module.organization, dep.module.name))
|
||||
.map(dep =>
|
||||
dep.copy(
|
||||
.filter{case (_, dep) => filter(dep.module.organization, dep.module.name) }
|
||||
.map{case (config, dep) =>
|
||||
config -> dep.copy(
|
||||
exclusions = Exclusions.minimize(dep.exclusions ++ exclusions)
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
def withParentConfigurations(config: String, configurations: Map[String, Seq[String]]): Set[String] = {
|
||||
@tailrec
|
||||
def helper(configs: Set[String], acc: Set[String]): Set[String] =
|
||||
if (configs.isEmpty)
|
||||
acc
|
||||
else if (configs.exists(acc))
|
||||
helper(configs -- acc, acc)
|
||||
else if (configs.exists(!configurations.contains(_))) {
|
||||
val (remaining, notFound) = configs.partition(configurations.contains)
|
||||
helper(remaining, acc ++ notFound)
|
||||
} else {
|
||||
val extraConfigs = configs.flatMap(configurations)
|
||||
helper(extraConfigs, acc ++ configs)
|
||||
}
|
||||
|
||||
helper(Set(config), Set.empty)
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -312,29 +314,33 @@ object Resolution {
|
|||
)
|
||||
)
|
||||
|
||||
val deps =
|
||||
withExclusions(
|
||||
depsWithDependencyManagement(
|
||||
// Important: properties have to be applied to both,
|
||||
// so that dep mgmt can be matched properly
|
||||
// Tested with org.ow2.asm:asm-commons:5.0.2 in CentralTests
|
||||
withProperties(project.dependencies, properties),
|
||||
withProperties(project.dependencyManagement, properties)
|
||||
),
|
||||
from.exclusions
|
||||
)
|
||||
.map(withDefaultScope)
|
||||
val configurations = withParentConfigurations(from.configuration, project.configurations)
|
||||
|
||||
deps
|
||||
.flatMap { trDep =>
|
||||
resolveScope(from.scope, trDep.scope)
|
||||
.map(scope =>
|
||||
trDep.copy(
|
||||
scope = scope,
|
||||
optional = trDep.optional || from.optional
|
||||
)
|
||||
)
|
||||
}
|
||||
withExclusions(
|
||||
depsWithDependencyManagement(
|
||||
// Important: properties have to be applied to both,
|
||||
// so that dep mgmt can be matched properly
|
||||
// Tested with org.ow2.asm:asm-commons:5.0.2 in CentralTests
|
||||
withProperties(project.dependencies, properties),
|
||||
withProperties(project.dependencyManagement, properties)
|
||||
),
|
||||
from.exclusions
|
||||
)
|
||||
.map{
|
||||
case (config, dep) =>
|
||||
(if (config.isEmpty) defaultConfiguration else config) -> {
|
||||
if (dep.configuration.isEmpty)
|
||||
dep.copy(configuration = defaultConfiguration)
|
||||
else
|
||||
dep
|
||||
}
|
||||
}
|
||||
.collect{case (config, dep) if configurations(config) =>
|
||||
if (from.optional)
|
||||
dep.copy(optional = true)
|
||||
else
|
||||
dep
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -438,7 +444,7 @@ case class Resolution(
|
|||
def nextDependenciesAndConflicts: (Seq[Dependency], Seq[Dependency]) =
|
||||
// TODO Provide the modules whose version was forced by dependency overrides too
|
||||
merge(
|
||||
rootDependencies.map(withDefaultScope) ++ dependencies ++ transitiveDependencies,
|
||||
rootDependencies.map(withDefaultConfig) ++ dependencies ++ transitiveDependencies,
|
||||
forceVersions
|
||||
)
|
||||
|
||||
|
|
@ -507,7 +513,7 @@ case class Resolution(
|
|||
*/
|
||||
def remainingDependencies: Set[Dependency] = {
|
||||
val rootDependencies0 = rootDependencies
|
||||
.map(withDefaultScope)
|
||||
.map(withDefaultConfig)
|
||||
.map(eraseVersion)
|
||||
|
||||
@tailrec
|
||||
|
|
@ -599,7 +605,7 @@ case class Resolution(
|
|||
val modules =
|
||||
(project.dependencies ++ profileDependencies)
|
||||
.collect{
|
||||
case dep if dep.scope == Scope.Import => dep.moduleVersion
|
||||
case ("import", dep) => dep.moduleVersion
|
||||
}
|
||||
|
||||
modules.toSet ++ project.parent
|
||||
|
|
@ -679,7 +685,7 @@ case class Resolution(
|
|||
|
||||
val deps = (
|
||||
dependencies0
|
||||
.collect { case dep if dep.scope == Scope.Import =>
|
||||
.collect { case ("import", dep) =>
|
||||
dep.moduleVersion
|
||||
} ++
|
||||
project.parent
|
||||
|
|
@ -693,16 +699,16 @@ case class Resolution(
|
|||
profiles0.map(_.dependencyManagement) ++
|
||||
projs.map(_.dependencyManagement)
|
||||
)
|
||||
).foldLeft(Map.empty[DepMgmt.Key, Dependency])(DepMgmt.addSeq)
|
||||
).foldLeft(Map.empty[DepMgmt.Key, (String, Dependency)])(DepMgmt.addSeq)
|
||||
|
||||
val depsSet = deps.toSet
|
||||
|
||||
project.copy(
|
||||
dependencies =
|
||||
dependencies0
|
||||
.filterNot(dep =>
|
||||
dep.scope == Scope.Import && depsSet(dep.moduleVersion)
|
||||
) ++
|
||||
.filterNot{case (config, dep) =>
|
||||
config == "import" && depsSet(dep.moduleVersion)
|
||||
} ++
|
||||
project.parent
|
||||
.filter(projectCache.contains)
|
||||
.toSeq
|
||||
|
|
@ -716,7 +722,14 @@ case class Resolution(
|
|||
}
|
||||
|
||||
def minDependencies: Set[Dependency] =
|
||||
Orders.minDependencies(dependencies)
|
||||
Orders.minDependencies(
|
||||
dependencies,
|
||||
dep =>
|
||||
projectCache
|
||||
.get(dep)
|
||||
.map(_._2.configurations)
|
||||
.getOrElse(Map.empty)
|
||||
)
|
||||
|
||||
def artifacts: Seq[Artifact] =
|
||||
for {
|
||||
|
|
|
|||
|
|
@ -35,6 +35,12 @@ object MavenRepository {
|
|||
.map(_.value)
|
||||
.filter(_.nonEmpty)
|
||||
|
||||
|
||||
val defaultConfigurations = Map(
|
||||
"runtime" -> Seq("compile"),
|
||||
"test" -> Seq("runtime")
|
||||
)
|
||||
|
||||
}
|
||||
|
||||
case class MavenRepository(
|
||||
|
|
@ -231,7 +237,7 @@ case class MavenRepository(
|
|||
xml <- \/.fromEither(compatibility.xmlParse(str))
|
||||
_ <- if (xml.label == "project") \/-(()) else -\/("Project definition not found")
|
||||
proj <- Pom.project(xml)
|
||||
} yield proj): (String \/ Project)
|
||||
} yield proj.copy(configurations = defaultConfigurations)): (String \/ Project)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -43,16 +43,14 @@ object Pom {
|
|||
private def readVersion(node: Node) =
|
||||
text(node, "version", "Version").getOrElse("").trim
|
||||
|
||||
private val defaultScope = Scope.Other("")
|
||||
private val defaultType = "jar"
|
||||
private val defaultClassifier = ""
|
||||
|
||||
def dependency(node: Node): String \/ Dependency = {
|
||||
def dependency(node: Node): String \/ (String, Dependency) = {
|
||||
for {
|
||||
mod <- module(node)
|
||||
version0 = readVersion(node)
|
||||
scopeOpt = text(node, "scope", "").toOption
|
||||
.map(Parse.scope)
|
||||
typeOpt = text(node, "type", "").toOption
|
||||
classifierOpt = text(node, "classifier", "").toOption
|
||||
xmlExclusions = node.child
|
||||
|
|
@ -64,10 +62,10 @@ object Pom {
|
|||
xmlExclusions.toList.traverseU(module(_))
|
||||
}
|
||||
optional = text(node, "optional", "").toOption.toSeq.contains("true")
|
||||
} yield Dependency(
|
||||
} yield scopeOpt.getOrElse("") -> Dependency(
|
||||
mod,
|
||||
version0,
|
||||
scopeOpt getOrElse defaultScope,
|
||||
"",
|
||||
Attributes(typeOpt getOrElse defaultType, classifierOpt getOrElse defaultClassifier),
|
||||
exclusions.map(mod => (mod.organization, mod.name)).toSet,
|
||||
optional
|
||||
|
|
@ -191,6 +189,7 @@ object Pom {
|
|||
deps,
|
||||
parentModuleOpt.map((_, parentVersionOpt.getOrElse(""))),
|
||||
depMgmts,
|
||||
Map.empty,
|
||||
properties.toMap,
|
||||
profiles,
|
||||
None,
|
||||
|
|
|
|||
|
|
@ -9,8 +9,8 @@ package object coursier {
|
|||
def apply(
|
||||
module: Module,
|
||||
version: String,
|
||||
// Substituted by Resolver with its own default scope (compile)
|
||||
scope: Scope = Scope.Other(""),
|
||||
// Substituted by Resolver with its own default configuration (compile)
|
||||
configuration: String = "",
|
||||
attributes: Attributes = Attributes(),
|
||||
exclusions: Set[(String, String)] = Set.empty,
|
||||
optional: Boolean = false
|
||||
|
|
@ -18,7 +18,7 @@ package object coursier {
|
|||
core.Dependency(
|
||||
module,
|
||||
version,
|
||||
scope,
|
||||
configuration,
|
||||
attributes,
|
||||
exclusions,
|
||||
optional
|
||||
|
|
@ -48,8 +48,6 @@ package object coursier {
|
|||
|
||||
type ModuleVersion = (core.Module, String)
|
||||
|
||||
type Scope = core.Scope
|
||||
val Scope = core.Scope
|
||||
|
||||
type Repository = core.Repository
|
||||
val Repository = core.Repository
|
||||
|
|
|
|||
|
|
@ -44,7 +44,8 @@ object CentralTests extends TestSuite {
|
|||
def resolutionCheck(
|
||||
module: Module,
|
||||
version: String,
|
||||
extraRepo: Option[Repository] = None
|
||||
extraRepo: Option[Repository] = None,
|
||||
configuration: String = ""
|
||||
) =
|
||||
async {
|
||||
val expected =
|
||||
|
|
@ -54,7 +55,7 @@ object CentralTests extends TestSuite {
|
|||
.split('\n')
|
||||
.toSeq
|
||||
|
||||
val dep = Dependency(module, version)
|
||||
val dep = Dependency(module, version, configuration = configuration)
|
||||
val res = await(resolve(Set(dep), extraRepo = extraRepo))
|
||||
|
||||
val result = res
|
||||
|
|
@ -138,6 +139,7 @@ object CentralTests extends TestSuite {
|
|||
resolutionCheck(
|
||||
Module("com.github.fommil", "java-logging"),
|
||||
"1.2-SNAPSHOT",
|
||||
configuration = "runtime",
|
||||
extraRepo = Some(MavenRepository("https://oss.sonatype.org/content/repositories/public/"))
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ object PomParsingTests extends TestSuite {
|
|||
</dependency>
|
||||
"""
|
||||
|
||||
val expected = \/-(Dependency(Module("comp", "lib"), "2.1", attributes = Attributes(classifier = "extra")))
|
||||
val expected = \/-("" -> Dependency(Module("comp", "lib"), "2.1", attributes = Attributes(classifier = "extra")))
|
||||
|
||||
val result = Pom.dependency(xmlParse(depNode).right.get)
|
||||
|
||||
|
|
@ -90,7 +90,7 @@ object PomParsingTests extends TestSuite {
|
|||
None,
|
||||
Profile.Activation(Nil),
|
||||
Seq(
|
||||
Dependency(Module("comp", "lib"), "0.2")),
|
||||
"" -> Dependency(Module("comp", "lib"), "0.2")),
|
||||
Nil,
|
||||
Map.empty
|
||||
))
|
||||
|
|
@ -122,7 +122,7 @@ object PomParsingTests extends TestSuite {
|
|||
Profile.Activation(Nil),
|
||||
Nil,
|
||||
Seq(
|
||||
Dependency(Module("comp", "lib"), "0.2", scope = Scope.Test)),
|
||||
"test" -> Dependency(Module("comp", "lib"), "0.2")),
|
||||
Map.empty
|
||||
))
|
||||
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ package coursier
|
|||
package test
|
||||
|
||||
import coursier.core.Repository
|
||||
import coursier.maven.MavenRepository
|
||||
import utest._
|
||||
import scala.async.Async.{ async, await }
|
||||
|
||||
|
|
@ -27,69 +28,68 @@ object ResolutionTests extends TestSuite {
|
|||
Project(Module("acme", "config"), "1.3.0"),
|
||||
|
||||
Project(Module("acme", "play"), "2.4.0", Seq(
|
||||
Dependency(Module("acme", "play-json"), "2.4.0"))),
|
||||
"" -> Dependency(Module("acme", "play-json"), "2.4.0"))),
|
||||
|
||||
Project(Module("acme", "play-json"), "2.4.0"),
|
||||
|
||||
Project(Module("acme", "play"), "2.4.1",
|
||||
dependencies = Seq(
|
||||
Dependency(Module("acme", "play-json"), "${playJsonVersion}"),
|
||||
Dependency(Module("${project.groupId}", "${configName}"), "1.3.0")),
|
||||
"" -> Dependency(Module("acme", "play-json"), "${playJsonVersion}"),
|
||||
"" -> Dependency(Module("${project.groupId}", "${configName}"), "1.3.0")),
|
||||
properties = Map(
|
||||
"playJsonVersion" -> "2.4.0",
|
||||
"configName" -> "config")),
|
||||
|
||||
Project(Module("acme", "play-extra-no-config"), "2.4.1",
|
||||
Seq(
|
||||
Dependency(Module("acme", "play"), "2.4.1",
|
||||
"" -> Dependency(Module("acme", "play"), "2.4.1",
|
||||
exclusions = Set(("acme", "config"))))),
|
||||
|
||||
Project(Module("acme", "play-extra-no-config-no"), "2.4.1",
|
||||
Seq(
|
||||
Dependency(Module("acme", "play"), "2.4.1",
|
||||
"" -> Dependency(Module("acme", "play"), "2.4.1",
|
||||
exclusions = Set(("*", "config"))))),
|
||||
|
||||
Project(Module("hudsucker", "mail"), "10.0",
|
||||
Seq(
|
||||
Dependency(Module("${project.groupId}", "test-util"), "${project.version}",
|
||||
scope = Scope.Test))),
|
||||
"test" -> Dependency(Module("${project.groupId}", "test-util"), "${project.version}"))),
|
||||
|
||||
Project(Module("hudsucker", "test-util"), "10.0"),
|
||||
|
||||
Project(Module("se.ikea", "parent"), "18.0",
|
||||
dependencyManagement = Seq(
|
||||
Dependency(Module("acme", "play"), "2.4.0",
|
||||
"" -> Dependency(Module("acme", "play"), "2.4.0",
|
||||
exclusions = Set(("acme", "play-json"))))),
|
||||
|
||||
Project(Module("se.ikea", "billy"), "18.0",
|
||||
dependencies = Seq(
|
||||
Dependency(Module("acme", "play"), "")),
|
||||
"" -> Dependency(Module("acme", "play"), "")),
|
||||
parent = Some(Module("se.ikea", "parent"), "18.0")),
|
||||
|
||||
Project(Module("org.gnome", "parent"), "7.0",
|
||||
Seq(
|
||||
Dependency(Module("org.gnu", "glib"), "13.4"))),
|
||||
"" -> Dependency(Module("org.gnu", "glib"), "13.4"))),
|
||||
|
||||
Project(Module("org.gnome", "panel-legacy"), "7.0",
|
||||
dependencies = Seq(
|
||||
Dependency(Module("org.gnome", "desktop"), "${project.version}")),
|
||||
"" -> Dependency(Module("org.gnome", "desktop"), "${project.version}")),
|
||||
parent = Some(Module("org.gnome", "parent"), "7.0")),
|
||||
|
||||
Project(Module("gov.nsa", "secure-pgp"), "10.0",
|
||||
Seq(
|
||||
Dependency(Module("gov.nsa", "crypto"), "536.89"))),
|
||||
"" -> Dependency(Module("gov.nsa", "crypto"), "536.89"))),
|
||||
|
||||
Project(Module("com.mailapp", "mail-client"), "2.1",
|
||||
dependencies = Seq(
|
||||
Dependency(Module("gov.nsa", "secure-pgp"), "10.0",
|
||||
"" -> Dependency(Module("gov.nsa", "secure-pgp"), "10.0",
|
||||
exclusions = Set(("*", "${crypto.name}")))),
|
||||
properties = Map("crypto.name" -> "crypto", "dummy" -> "2")),
|
||||
|
||||
Project(Module("com.thoughtworks.paranamer", "paranamer-parent"), "2.6",
|
||||
dependencies = Seq(
|
||||
Dependency(Module("junit", "junit"), "")),
|
||||
"" -> Dependency(Module("junit", "junit"), "")),
|
||||
dependencyManagement = Seq(
|
||||
Dependency(Module("junit", "junit"), "4.11", scope = Scope.Test))),
|
||||
"test" -> Dependency(Module("junit", "junit"), "4.11"))),
|
||||
|
||||
Project(Module("com.thoughtworks.paranamer", "paranamer"), "2.6",
|
||||
parent = Some(Module("com.thoughtworks.paranamer", "paranamer-parent"), "2.6")),
|
||||
|
|
@ -97,33 +97,33 @@ object ResolutionTests extends TestSuite {
|
|||
Project(Module("com.github.dummy", "libb"), "0.3.3",
|
||||
profiles = Seq(
|
||||
Profile("default", activeByDefault = Some(true), dependencies = Seq(
|
||||
Dependency(Module("org.escalier", "librairie-standard"), "2.11.6"))))),
|
||||
"" -> Dependency(Module("org.escalier", "librairie-standard"), "2.11.6"))))),
|
||||
|
||||
Project(Module("com.github.dummy", "libb"), "0.4.2",
|
||||
dependencies = Seq(
|
||||
Dependency(Module("org.scalaverification", "scala-verification"), "1.12.4")),
|
||||
"" -> Dependency(Module("org.scalaverification", "scala-verification"), "1.12.4")),
|
||||
profiles = Seq(
|
||||
Profile("default", activeByDefault = Some(true), dependencies = Seq(
|
||||
Dependency(Module("org.escalier", "librairie-standard"), "2.11.6"),
|
||||
Dependency(Module("org.scalaverification", "scala-verification"), "1.12.4", scope = Scope.Test))))),
|
||||
"" -> Dependency(Module("org.escalier", "librairie-standard"), "2.11.6"),
|
||||
"test" -> Dependency(Module("org.scalaverification", "scala-verification"), "1.12.4"))))),
|
||||
|
||||
Project(Module("com.github.dummy", "libb"), "0.5.3",
|
||||
properties = Map("special" -> "true"),
|
||||
profiles = Seq(
|
||||
Profile("default", activation = Profile.Activation(properties = Seq("special" -> None)), dependencies = Seq(
|
||||
Dependency(Module("org.escalier", "librairie-standard"), "2.11.6"))))),
|
||||
"" -> Dependency(Module("org.escalier", "librairie-standard"), "2.11.6"))))),
|
||||
|
||||
Project(Module("com.github.dummy", "libb"), "0.5.4",
|
||||
properties = Map("special" -> "true"),
|
||||
profiles = Seq(
|
||||
Profile("default", activation = Profile.Activation(properties = Seq("special" -> Some("true"))), dependencies = Seq(
|
||||
Dependency(Module("org.escalier", "librairie-standard"), "2.11.6"))))),
|
||||
"" -> Dependency(Module("org.escalier", "librairie-standard"), "2.11.6"))))),
|
||||
|
||||
Project(Module("com.github.dummy", "libb"), "0.5.5",
|
||||
properties = Map("special" -> "true"),
|
||||
profiles = Seq(
|
||||
Profile("default", activation = Profile.Activation(properties = Seq("special" -> Some("!false"))), dependencies = Seq(
|
||||
Dependency(Module("org.escalier", "librairie-standard"), "2.11.6"))))),
|
||||
"" -> Dependency(Module("org.escalier", "librairie-standard"), "2.11.6"))))),
|
||||
|
||||
Project(Module("com.github.dummy", "libb-parent"), "0.5.6",
|
||||
properties = Map("special" -> "true")),
|
||||
|
|
@ -133,39 +133,39 @@ object ResolutionTests extends TestSuite {
|
|||
properties = Map("special" -> "true"),
|
||||
profiles = Seq(
|
||||
Profile("default", activation = Profile.Activation(properties = Seq("special" -> Some("!false"))), dependencies = Seq(
|
||||
Dependency(Module("org.escalier", "librairie-standard"), "2.11.6"))))),
|
||||
"" -> Dependency(Module("org.escalier", "librairie-standard"), "2.11.6"))))),
|
||||
|
||||
Project(Module("an-org", "a-name"), "1.0"),
|
||||
|
||||
Project(Module("an-org", "a-name"), "1.2"),
|
||||
|
||||
Project(Module("an-org", "a-lib"), "1.0",
|
||||
Seq(Dependency(Module("an-org", "a-name"), "1.0"))),
|
||||
Seq("" -> Dependency(Module("an-org", "a-name"), "1.0"))),
|
||||
|
||||
Project(Module("an-org", "a-lib"), "1.1"),
|
||||
|
||||
Project(Module("an-org", "a-lib"), "1.2",
|
||||
Seq(Dependency(Module("an-org", "a-name"), "1.2"))),
|
||||
Seq("" -> Dependency(Module("an-org", "a-name"), "1.2"))),
|
||||
|
||||
Project(Module("an-org", "another-lib"), "1.0",
|
||||
Seq(Dependency(Module("an-org", "a-name"), "1.0"))),
|
||||
Seq("" -> Dependency(Module("an-org", "a-name"), "1.0"))),
|
||||
|
||||
// Must bring transitively an-org:a-name, as an optional dependency
|
||||
Project(Module("an-org", "an-app"), "1.0",
|
||||
Seq(
|
||||
Dependency(Module("an-org", "a-lib"), "1.0", exclusions = Set(("an-org", "a-name"))),
|
||||
Dependency(Module("an-org", "another-lib"), "1.0", optional = true))),
|
||||
"" -> Dependency(Module("an-org", "a-lib"), "1.0", exclusions = Set(("an-org", "a-name"))),
|
||||
"" -> Dependency(Module("an-org", "another-lib"), "1.0", optional = true))),
|
||||
|
||||
Project(Module("an-org", "an-app"), "1.1",
|
||||
Seq(
|
||||
Dependency(Module("an-org", "a-lib"), "1.1"))),
|
||||
"" -> Dependency(Module("an-org", "a-lib"), "1.1"))),
|
||||
|
||||
Project(Module("an-org", "an-app"), "1.2",
|
||||
Seq(
|
||||
Dependency(Module("an-org", "a-lib"), "1.2")))
|
||||
"" -> Dependency(Module("an-org", "a-lib"), "1.2")))
|
||||
)
|
||||
|
||||
val projectsMap = projects.map(p => p.moduleVersion -> p).toMap
|
||||
val projectsMap = projects.map(p => p.moduleVersion -> p.copy(configurations = MavenRepository.defaultConfigurations)).toMap
|
||||
val testRepository = new TestRepository(projectsMap)
|
||||
|
||||
val repositories = Seq[Repository](
|
||||
|
|
@ -308,8 +308,7 @@ object ResolutionTests extends TestSuite {
|
|||
async {
|
||||
val dep = Dependency(Module("hudsucker", "mail"), "10.0")
|
||||
val res = await(resolve0(
|
||||
Set(dep),
|
||||
filter = Some(_.scope == Scope.Compile)
|
||||
Set(dep)
|
||||
)).copy(filter = None)
|
||||
|
||||
val expected = Resolution(
|
||||
|
|
@ -331,8 +330,7 @@ object ResolutionTests extends TestSuite {
|
|||
exclusions = Set(("acme", "play-json")))
|
||||
)
|
||||
val res = await(resolve0(
|
||||
Set(dep),
|
||||
filter = Some(_.scope == Scope.Compile)
|
||||
Set(dep)
|
||||
)).copy(filter = None, projectCache = Map.empty)
|
||||
|
||||
val expected = Resolution(
|
||||
|
|
@ -350,8 +348,7 @@ object ResolutionTests extends TestSuite {
|
|||
Dependency(Module("org.gnu", "glib"), "13.4"),
|
||||
Dependency(Module("org.gnome", "desktop"), "7.0"))
|
||||
val res = await(resolve0(
|
||||
Set(dep),
|
||||
filter = Some(_.scope == Scope.Compile)
|
||||
Set(dep)
|
||||
)).copy(filter = None, projectCache = Map.empty, errorCache = Map.empty)
|
||||
|
||||
val expected = Resolution(
|
||||
|
|
@ -368,8 +365,7 @@ object ResolutionTests extends TestSuite {
|
|||
val trDeps = Seq(
|
||||
Dependency(Module("gov.nsa", "secure-pgp"), "10.0", exclusions = Set(("*", "crypto"))))
|
||||
val res = await(resolve0(
|
||||
Set(dep),
|
||||
filter = Some(_.scope == Scope.Compile)
|
||||
Set(dep)
|
||||
)).copy(filter = None, projectCache = Map.empty, errorCache = Map.empty)
|
||||
|
||||
val expected = Resolution(
|
||||
|
|
@ -384,8 +380,7 @@ object ResolutionTests extends TestSuite {
|
|||
async {
|
||||
val dep = Dependency(Module("com.thoughtworks.paranamer", "paranamer"), "2.6")
|
||||
val res = await(resolve0(
|
||||
Set(dep),
|
||||
filter = Some(_.scope == Scope.Compile)
|
||||
Set(dep)
|
||||
)).copy(filter = None, projectCache = Map.empty, errorCache = Map.empty)
|
||||
|
||||
val expected = Resolution(
|
||||
|
|
@ -402,8 +397,7 @@ object ResolutionTests extends TestSuite {
|
|||
val trDeps = Seq(
|
||||
Dependency(Module("org.escalier", "librairie-standard"), "2.11.6"))
|
||||
val res = await(resolve0(
|
||||
Set(dep),
|
||||
filter = Some(_.scope == Scope.Compile)
|
||||
Set(dep)
|
||||
)).copy(filter = None, projectCache = Map.empty, errorCache = Map.empty)
|
||||
|
||||
val expected = Resolution(
|
||||
|
|
@ -422,8 +416,7 @@ object ResolutionTests extends TestSuite {
|
|||
val trDeps = Seq(
|
||||
Dependency(Module("org.escalier", "librairie-standard"), "2.11.6"))
|
||||
val res = await(resolve0(
|
||||
Set(dep),
|
||||
filter = Some(_.scope == Scope.Compile)
|
||||
Set(dep)
|
||||
)).copy(filter = None, projectCache = Map.empty, errorCache = Map.empty)
|
||||
|
||||
val expected = Resolution(
|
||||
|
|
@ -444,8 +437,7 @@ object ResolutionTests extends TestSuite {
|
|||
val trDeps = Seq(
|
||||
Dependency(Module("org.escalier", "librairie-standard"), "2.11.6"))
|
||||
val res = await(resolve0(
|
||||
Set(dep),
|
||||
filter = Some(_.scope == Scope.Compile)
|
||||
Set(dep)
|
||||
)).copy(filter = None, projectCache = Map.empty, errorCache = Map.empty)
|
||||
|
||||
val expected = Resolution(
|
||||
|
|
@ -466,7 +458,7 @@ object ResolutionTests extends TestSuite {
|
|||
Dependency(Module("an-org", "a-name"), "1.0", optional = true))
|
||||
val res = await(resolve0(
|
||||
Set(dep),
|
||||
filter = Some(_.scope == Scope.Compile)
|
||||
filter = Some(_ => true)
|
||||
)).copy(filter = None, projectCache = Map.empty, errorCache = Map.empty)
|
||||
|
||||
val expected = Resolution(
|
||||
|
|
@ -489,7 +481,7 @@ object ResolutionTests extends TestSuite {
|
|||
Dependency(Module("an-org", "a-name"), "1.0", optional = true))
|
||||
val res = await(resolve0(
|
||||
deps,
|
||||
filter = Some(_.scope == Scope.Compile)
|
||||
filter = Some(_ => true)
|
||||
)).copy(filter = None, projectCache = Map.empty, errorCache = Map.empty)
|
||||
|
||||
val expected = Resolution(
|
||||
|
|
@ -511,8 +503,7 @@ object ResolutionTests extends TestSuite {
|
|||
|
||||
val res = await(resolve0(
|
||||
deps,
|
||||
forceVersions = depOverrides,
|
||||
filter = Some(_.scope == Scope.Compile)
|
||||
forceVersions = depOverrides
|
||||
)).copy(filter = None, projectCache = Map.empty, errorCache = Map.empty)
|
||||
|
||||
val expected = Resolution(
|
||||
|
|
@ -536,8 +527,7 @@ object ResolutionTests extends TestSuite {
|
|||
|
||||
val res = await(resolve0(
|
||||
deps,
|
||||
forceVersions = depOverrides,
|
||||
filter = Some(_.scope == Scope.Compile)
|
||||
forceVersions = depOverrides
|
||||
)).copy(filter = None, projectCache = Map.empty, errorCache = Map.empty)
|
||||
|
||||
val expected = Resolution(
|
||||
|
|
@ -563,8 +553,7 @@ object ResolutionTests extends TestSuite {
|
|||
|
||||
val res = await(resolve0(
|
||||
deps,
|
||||
forceVersions = depOverrides,
|
||||
filter = Some(_.scope == Scope.Compile)
|
||||
forceVersions = depOverrides
|
||||
)).copy(filter = None, projectCache = Map.empty, errorCache = Map.empty)
|
||||
|
||||
val expected = Resolution(
|
||||
|
|
@ -585,9 +574,9 @@ object ResolutionTests extends TestSuite {
|
|||
'propertySubstitution{
|
||||
val res =
|
||||
core.Resolution.withProperties(
|
||||
Seq(Dependency(Module("a-company", "a-name"), "${a.property}")),
|
||||
Seq("" -> Dependency(Module("a-company", "a-name"), "${a.property}")),
|
||||
Map("a.property" -> "a-version"))
|
||||
val expected = Seq(Dependency(Module("a-company", "a-name"), "a-version"))
|
||||
val expected = Seq("" -> Dependency(Module("a-company", "a-name"), "a-version"))
|
||||
|
||||
assert(res == expected)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ package coursier
|
|||
package object test {
|
||||
|
||||
implicit class DependencyOps(val underlying: Dependency) extends AnyVal {
|
||||
def withCompileScope: Dependency = underlying.copy(scope = Scope.Compile)
|
||||
def withCompileScope: Dependency = underlying.copy(configuration = "compile")
|
||||
}
|
||||
|
||||
object Profile {
|
||||
|
|
@ -16,8 +16,8 @@ package object test {
|
|||
def apply(id: String,
|
||||
activeByDefault: Option[Boolean] = None,
|
||||
activation: Activation = Activation(),
|
||||
dependencies: Seq[Dependency] = Nil,
|
||||
dependencyManagement: Seq[Dependency] = Nil,
|
||||
dependencies: Seq[(String, Dependency)] = Nil,
|
||||
dependencyManagement: Seq[(String, Dependency)] = Nil,
|
||||
properties: Map[String, String] = Map.empty) =
|
||||
core.Profile(id, activeByDefault, activation, dependencies, dependencyManagement, properties)
|
||||
}
|
||||
|
|
@ -25,13 +25,15 @@ package object test {
|
|||
object Project {
|
||||
def apply(module: Module,
|
||||
version: String,
|
||||
dependencies: Seq[Dependency] = Seq.empty,
|
||||
dependencies: Seq[(String, Dependency)] = Seq.empty,
|
||||
parent: Option[ModuleVersion] = None,
|
||||
dependencyManagement: Seq[Dependency] = Seq.empty,
|
||||
dependencyManagement: Seq[(String, Dependency)] = Seq.empty,
|
||||
configurations: Map[String, Seq[String]] = Map.empty,
|
||||
properties: Map[String, String] = Map.empty,
|
||||
profiles: Seq[Profile] = Seq.empty,
|
||||
versions: Option[core.Versions] = None,
|
||||
snapshotVersioning: Option[core.SnapshotVersioning] = None): Project =
|
||||
core.Project(module, version, dependencies, parent, dependencyManagement, properties, profiles, versions, snapshotVersioning)
|
||||
snapshotVersioning: Option[core.SnapshotVersioning] = None
|
||||
): Project =
|
||||
core.Project(module, version, dependencies, parent, dependencyManagement, configurations, properties, profiles, versions, snapshotVersioning)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,8 +17,7 @@ import scala.scalajs.js
|
|||
import js.Dynamic.{ global => g }
|
||||
|
||||
case class ResolutionOptions(
|
||||
followOptional: Boolean = false,
|
||||
keepTest: Boolean = false
|
||||
followOptional: Boolean = false
|
||||
)
|
||||
|
||||
case class State(
|
||||
|
|
@ -66,7 +65,7 @@ class Backend($: BackendScope[Unit, State]) {
|
|||
Seq(
|
||||
dep.module.organization,
|
||||
dep.module.name,
|
||||
dep.scope.name
|
||||
dep.configuration
|
||||
).mkString(":")
|
||||
|
||||
for {
|
||||
|
|
@ -176,8 +175,7 @@ class Backend($: BackendScope[Unit, State]) {
|
|||
val res = coursier.Resolution(
|
||||
s.modules.toSet,
|
||||
filter = Some(dep =>
|
||||
(s.options.followOptional || !dep.optional) &&
|
||||
(s.options.keepTest || dep.scope != Scope.Test)
|
||||
s.options.followOptional || !dep.optional
|
||||
)
|
||||
)
|
||||
|
||||
|
|
@ -338,14 +336,6 @@ class Backend($: BackendScope[Unit, State]) {
|
|||
)
|
||||
)
|
||||
}
|
||||
def toggleTest(e: ReactEventI) = {
|
||||
$.modState(s =>
|
||||
s.copy(
|
||||
options = s.options
|
||||
.copy(keepTest = !s.options.keepTest)
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -380,7 +370,7 @@ object App {
|
|||
<.td(dep.module.name),
|
||||
<.td(finalVersionOpt.fold(dep.version)(finalVersion => s"$finalVersion (for ${dep.version})")),
|
||||
<.td(Seq[Seq[TagMod]](
|
||||
if (dep.scope == Scope.Compile) Seq() else Seq(infoLabel(dep.scope.name)),
|
||||
if (dep.configuration == "compile") Seq() else Seq(infoLabel(dep.configuration)),
|
||||
if (dep.attributes.`type`.isEmpty || dep.attributes.`type` == "jar") Seq() else Seq(infoLabel(dep.attributes.`type`)),
|
||||
if (dep.attributes.classifier.isEmpty) Seq() else Seq(infoLabel(dep.attributes.classifier)),
|
||||
Some(dep.exclusions).filter(_.nonEmpty).map(excls => infoPopOver("Exclusions", excls.toList.sorted.map{case (org, name) => s"$org:$name"}.mkString("; "))).toSeq,
|
||||
|
|
@ -683,15 +673,6 @@ object App {
|
|||
"Follow optional dependencies"
|
||||
)
|
||||
)
|
||||
),
|
||||
<.div(^.`class` := "checkbox",
|
||||
<.label(
|
||||
<.input(^.`type` := "checkbox",
|
||||
^.onChange ==> backend.options.toggleTest,
|
||||
if (options.keepTest) Seq(^.checked := "checked") else Seq(),
|
||||
"Keep test dependencies"
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue