diff --git a/build.sbt b/build.sbt
index b153b9aea..3a8a6a881 100644
--- a/build.sbt
+++ b/build.sbt
@@ -15,7 +15,7 @@ inThisBuild(List(
)
))
-val coursierVersion0 = "2.0.0-RC6-16"
+val coursierVersion0 = "2.0.0-RC6-18"
lazy val `lm-coursier` = project
.in(file("modules/lm-coursier"))
diff --git a/modules/lm-coursier/src/main/scala/lmcoursier/CoursierDependencyResolution.scala b/modules/lm-coursier/src/main/scala/lmcoursier/CoursierDependencyResolution.scala
index addf9b9ce..82b00d189 100644
--- a/modules/lm-coursier/src/main/scala/lmcoursier/CoursierDependencyResolution.scala
+++ b/modules/lm-coursier/src/main/scala/lmcoursier/CoursierDependencyResolution.scala
@@ -25,14 +25,6 @@ class CoursierDependencyResolution(conf: CoursierConfiguration) extends Dependen
* sbt-coursier, that was moved to this module.
*/
- private lazy val excludeDependencies = conf
- .excludeDependencies
- .map {
- case (strOrg, strName) =>
- (lmcoursier.definitions.Organization(strOrg), lmcoursier.definitions.ModuleName(strName))
- }
- .toSet
-
def moduleDescriptor(moduleSetting: ModuleDescriptorConfiguration): ModuleDescriptor =
CoursierModuleDescriptor(moduleSetting, conf)
@@ -125,13 +117,14 @@ class CoursierDependencyResolution(conf: CoursierConfiguration) extends Dependen
}
.map {
case (config, dep) =>
- val dep0 = dep.withExclusions(dep.exclusions ++ excludeDependencies)
- (ToCoursier.configuration(config), ToCoursier.dependency(dep0))
+ (ToCoursier.configuration(config), ToCoursier.dependency(dep))
}
- val configGraphs = Inputs.ivyGraphs(
- Inputs.configExtends(module0.configurations)
- ).map(_.map(ToCoursier.configuration))
+ val orderedConfigs = Inputs.orderedConfigurations(Inputs.configExtendsSeq(module0.configurations))
+ .map {
+ case (config, extends0) =>
+ (ToCoursier.configuration(config), extends0.map(ToCoursier.configuration))
+ }
val typelevel = so == Typelevel.typelevelOrg
@@ -143,10 +136,18 @@ class CoursierDependencyResolution(conf: CoursierConfiguration) extends Dependen
.withCredentials(conf.credentials.map(ToCoursier.credentials))
.withFollowHttpToHttpsRedirections(conf.followHttpToHttpsRedirections.getOrElse(true))
+ val excludeDependencies = conf
+ .excludeDependencies
+ .map {
+ case (strOrg, strName) =>
+ (coursier.Organization(strOrg), coursier.ModuleName(strName))
+ }
+ .toSet
+
val resolutionParams = ResolutionParams(
dependencies = dependencies,
fallbackDependencies = conf.fallbackDependencies,
- configGraphs = configGraphs,
+ orderedConfigs = orderedConfigs,
autoScalaLibOpt = if (conf.autoScalaLibrary) Some((so, sv)) else None,
mainRepositories = mainRepositories,
parentProjectCache = Map.empty,
@@ -162,15 +163,16 @@ class CoursierDependencyResolution(conf: CoursierConfiguration) extends Dependen
.withProfiles(conf.mavenProfiles.toSet)
.withForceVersion(conf.forceVersions.map { case (k, v) => (ToCoursier.module(k), v) }.toMap)
.withTypelevel(typelevel)
- .withReconciliation(ToCoursier.reconciliation(conf.reconciliation)),
+ .withReconciliation(ToCoursier.reconciliation(conf.reconciliation))
+ .withExclusions(excludeDependencies),
strictOpt = conf.strict.map(ToCoursier.strict),
missingOk = conf.missingOk,
)
- def artifactsParams(resolutions: Map[Set[Configuration], Resolution]): ArtifactsParams =
+ def artifactsParams(resolutions: Map[Configuration, Resolution]): ArtifactsParams =
ArtifactsParams(
classifiers = classifiers,
- resolutions = resolutions.values.toSeq,
+ resolutions = resolutions.values.toSeq.distinct,
includeSignatures = false,
loggerOpt = loggerOpt,
projectName = projectName,
@@ -193,7 +195,7 @@ class CoursierDependencyResolution(conf: CoursierConfiguration) extends Dependen
}
def updateParams(
- resolutions: Map[Set[Configuration], Resolution],
+ resolutions: Map[Configuration, Resolution],
artifacts: Seq[(Dependency, Publication, Artifact, Option[File])]
) =
UpdateParams(
diff --git a/modules/lm-coursier/src/main/scala/lmcoursier/Inputs.scala b/modules/lm-coursier/src/main/scala/lmcoursier/Inputs.scala
index 23e1a0d86..da55d13b8 100644
--- a/modules/lm-coursier/src/main/scala/lmcoursier/Inputs.scala
+++ b/modules/lm-coursier/src/main/scala/lmcoursier/Inputs.scala
@@ -15,6 +15,11 @@ object Inputs {
Configuration(from.value) -> Configuration(to.value)
}
+ def configExtendsSeq(configurations: Seq[sbt.librarymanagement.Configuration]): Seq[(Configuration, Seq[Configuration])] =
+ configurations
+ .map(cfg => Configuration(cfg.name) -> cfg.extendsConfigs.map(c => Configuration(c.name)))
+
+ @deprecated("Now unused internally, to be removed in the future", "2.0.0-RC6-5")
def configExtends(configurations: Seq[sbt.librarymanagement.Configuration]): Map[Configuration, Seq[Configuration]] =
configurations
.map(cfg => Configuration(cfg.name) -> cfg.extendsConfigs.map(c => Configuration(c.name)))
@@ -25,7 +30,7 @@ object Inputs {
shadedConfig: Option[(String, Configuration)] = None
): Map[Configuration, Set[Configuration]] = {
- val configs0 = configExtends(configurations)
+ val configs0 = configExtendsSeq(configurations).toMap
def allExtends(c: Configuration) = {
// possibly bad complexity
@@ -55,6 +60,29 @@ object Inputs {
}
}
+ def orderedConfigurations(
+ configurations: Seq[(Configuration, Seq[Configuration])]
+ ): Seq[(Configuration, Seq[Configuration])] = {
+
+ val map = configurations.toMap
+
+ def helper(done: Set[Configuration], toAdd: List[Configuration]): Stream[(Configuration, Seq[Configuration])] =
+ toAdd match {
+ case Nil => Stream.empty
+ case config :: rest =>
+ val extends0 = map.getOrElse(config, Nil)
+ val missingExtends = extends0.filterNot(done)
+ if (missingExtends.isEmpty)
+ (config, extends0) #:: helper(done + config, rest)
+ else
+ helper(done, missingExtends.toList ::: toAdd)
+ }
+
+ helper(Set.empty, configurations.map(_._1).toList)
+ .toVector
+ }
+
+ @deprecated("Now unused internally, to be removed in the future", "2.0.0-RC6-5")
def ivyGraphs(configurations: Map[Configuration, Seq[Configuration]]): Seq[Set[Configuration]] = {
// probably bad complexity, but that shouldn't matter given the size of the graphs involved...
@@ -95,12 +123,12 @@ object Inputs {
sets.values.toVector.distinct.map(_.set.toSet)
}
- def exclusions(
+ def exclusionsSeq(
excludeDeps: Seq[InclExclRule],
sv: String,
sbv: String,
log: Logger
- ): Set[(Organization, ModuleName)] = {
+ ): Seq[(Organization, ModuleName)] = {
var anyNonSupportedExclusionRule = false
@@ -116,7 +144,6 @@ object Inputs {
Seq((Organization(rule.organization), ModuleName(name)))
}
}
- .toSet
if (anyNonSupportedExclusionRule)
log.warn("Only supported exclusion rule fields: organization, name")
@@ -124,6 +151,14 @@ object Inputs {
res
}
+ def exclusions(
+ excludeDeps: Seq[InclExclRule],
+ sv: String,
+ sbv: String,
+ log: Logger
+ ): Set[(Organization, ModuleName)] =
+ exclusionsSeq(excludeDeps, sv, sbv, log).toSet
+
def forceVersions(depOverrides: Seq[ModuleID], sv: String, sbv: String): Seq[(Module, String)] =
depOverrides.map(FromSbt.moduleVersion(_, sv, sbv))
diff --git a/modules/sbt-coursier-shared/src/main/scala/coursier/sbtcoursiershared/IvyXml.scala b/modules/lm-coursier/src/main/scala/lmcoursier/IvyXml.scala
similarity index 54%
rename from modules/sbt-coursier-shared/src/main/scala/coursier/sbtcoursiershared/IvyXml.scala
rename to modules/lm-coursier/src/main/scala/lmcoursier/IvyXml.scala
index 5b9d614dd..b55dc1d16 100644
--- a/modules/sbt-coursier-shared/src/main/scala/coursier/sbtcoursiershared/IvyXml.scala
+++ b/modules/lm-coursier/src/main/scala/lmcoursier/IvyXml.scala
@@ -1,21 +1,15 @@
-package coursier.sbtcoursiershared
-
-import java.nio.charset.StandardCharsets.UTF_8
-import java.nio.file.Files
+package lmcoursier
+import lmcoursier.Inputs
import lmcoursier.definitions.{Configuration, Project}
-import org.apache.ivy.core.module.id.ModuleRevisionId
-import sbt.{Def, Setting, Task, TaskKey}
-import sbt.internal.librarymanagement.IvySbt
-import sbt.librarymanagement.PublishConfiguration
-import scala.collection.JavaConverters._
import scala.xml.{Node, PrefixedAttribute}
object IvyXml {
- private[sbtcoursiershared] def rawContent(
+ def apply(
currentProject: Project,
+ exclusions: Seq[(String, String)],
shadedConfigOpt: Option[Configuration]
): String = {
@@ -28,42 +22,15 @@ object IvyXml {
val printer = new scala.xml.PrettyPrinter(Int.MaxValue, 2)
"""""" + '\n' +
- printer.format(content(currentProject, shadedConfigOpt))
+ printer.format(content(currentProject, exclusions, shadedConfigOpt))
}
// These are required for publish to be fine, later on.
- private def writeFiles(
- currentProject: Project,
- shadedConfigOpt: Option[Configuration],
- ivySbt: IvySbt,
- log: sbt.util.Logger
- ): Unit = {
-
- val ivyCacheManager = ivySbt.withIvy(log)(ivy =>
- ivy.getResolutionCacheManager
- )
-
- val ivyModule = ModuleRevisionId.newInstance(
- currentProject.module.organization.value,
- currentProject.module.name.value,
- currentProject.version,
- currentProject.module.attributes.asJava
- )
-
- val cacheIvyFile = ivyCacheManager.getResolvedIvyFileInCache(ivyModule)
- val cacheIvyPropertiesFile = ivyCacheManager.getResolvedIvyPropertiesInCache(ivyModule)
-
- val content0 = rawContent(currentProject, shadedConfigOpt)
- cacheIvyFile.getParentFile.mkdirs()
- log.info(s"Writing Ivy file $cacheIvyFile")
- Files.write(cacheIvyFile.toPath, content0.getBytes(UTF_8))
-
- // Just writing an empty file here... Are these only used?
- cacheIvyPropertiesFile.getParentFile.mkdirs()
- Files.write(cacheIvyPropertiesFile.toPath, Array.emptyByteArray)
- }
-
- private def content(project0: Project, shadedConfigOpt: Option[Configuration]): Node = {
+ private def content(
+ project0: Project,
+ exclusions: Seq[(String, String)],
+ shadedConfigOpt: Option[Configuration]
+ ): Node = {
val filterOutDependencies =
shadedConfigOpt.toSet[Configuration].flatMap { shadedConfig =>
@@ -148,53 +115,17 @@ object IvyXml {
n % moduleAttrs
}
+ val excludeElems = exclusions.toVector.map {
+ case (org, name) =>
+
+ }
+
{infoElem}
{confElems}
{publicationElems}
- {dependencyElems}
+ {dependencyElems}{excludeElems}
}
- private def makeIvyXmlBefore[T](
- task: TaskKey[T],
- shadedConfigOpt: Option[Configuration]
- ): Setting[Task[T]] =
- task := task.dependsOn {
- Def.taskDyn {
- import SbtCoursierShared.autoImport._
- val doGen = coursierGenerateIvyXml.value
- if (doGen)
- Def.task {
- val currentProject = {
- val proj = coursierProject.value
- val publications = coursierPublications.value
- proj.withPublications(publications)
- }
- writeFiles(currentProject, shadedConfigOpt, sbt.Keys.ivySbt.value, sbt.Keys.streams.value.log)
- }
- else
- Def.task(())
- }
- }.value
-
- private lazy val needsIvyXmlLocal = Seq(sbt.Keys.publishLocalConfiguration) ++ getPubConf("makeIvyXmlLocalConfiguration")
- private lazy val needsIvyXml = Seq(sbt.Keys.publishConfiguration) ++ getPubConf("makeIvyXmlConfiguration")
-
- private[this] def getPubConf(method: String): List[TaskKey[PublishConfiguration]] =
- try {
- val cls = sbt.Keys.getClass
- val m = cls.getMethod(method)
- val task = m.invoke(sbt.Keys).asInstanceOf[TaskKey[PublishConfiguration]]
- List(task)
- } catch {
- case _: Throwable => // FIXME Too wide
- Nil
- }
-
- def generateIvyXmlSettings(
- shadedConfigOpt: Option[Configuration] = None
- ): Seq[Setting[_]] =
- (needsIvyXml ++ needsIvyXmlLocal).map(makeIvyXmlBefore(_, shadedConfigOpt))
-
}
diff --git a/modules/lm-coursier/src/main/scala/lmcoursier/internal/ResolutionParams.scala b/modules/lm-coursier/src/main/scala/lmcoursier/internal/ResolutionParams.scala
index ced79bf3c..56a99067a 100644
--- a/modules/lm-coursier/src/main/scala/lmcoursier/internal/ResolutionParams.scala
+++ b/modules/lm-coursier/src/main/scala/lmcoursier/internal/ResolutionParams.scala
@@ -10,11 +10,13 @@ import lmcoursier.FallbackDependency
import lmcoursier.definitions.ToCoursier
import coursier.util.Task
+import scala.collection.mutable
+
// private[coursier]
final case class ResolutionParams(
dependencies: Seq[(Configuration, Dependency)],
fallbackDependencies: Seq[FallbackDependency],
- configGraphs: Seq[Set[Configuration]],
+ orderedConfigs: Seq[(Configuration, Seq[Configuration])],
autoScalaLibOpt: Option[(Organization, String)],
mainRepositories: Seq[Repository],
parentProjectCache: ProjectCache,
@@ -30,6 +32,18 @@ final case class ResolutionParams(
missingOk: Boolean,
) {
+ lazy val allConfigExtends: Map[Configuration, Set[Configuration]] = {
+ val map = new mutable.HashMap[Configuration, Set[Configuration]]
+ for ((config, extends0) <- orderedConfigs) {
+ val allExtends = extends0
+ .iterator
+ // the else of the getOrElse shouldn't be hit (because of the ordering of the configurations)
+ .foldLeft(Set(config))((acc, ext) => acc ++ map.getOrElse(ext, Set(ext)))
+ map += config -> allExtends
+ }
+ map.toMap
+ }
+
val fallbackDependenciesRepositories =
if (fallbackDependencies.isEmpty)
Nil
diff --git a/modules/lm-coursier/src/main/scala/lmcoursier/internal/ResolutionRun.scala b/modules/lm-coursier/src/main/scala/lmcoursier/internal/ResolutionRun.scala
index dc34688e8..f853386af 100644
--- a/modules/lm-coursier/src/main/scala/lmcoursier/internal/ResolutionRun.scala
+++ b/modules/lm-coursier/src/main/scala/lmcoursier/internal/ResolutionRun.scala
@@ -9,6 +9,8 @@ import coursier.maven.MavenRepository
import coursier.params.rule.RuleResolution
import sbt.util.Logger
+import scala.collection.mutable
+
// private[coursier]
object ResolutionRun {
@@ -16,7 +18,8 @@ object ResolutionRun {
params: ResolutionParams,
verbosityLevel: Int,
log: Logger,
- configs: Set[Configuration]
+ configs: Set[Configuration],
+ startingResolutionOpt: Option[Resolution]
): Either[coursier.error.ResolutionError, Resolution] = {
val isScalaToolConfig = configs(Configuration("scala-tool"))
@@ -80,6 +83,8 @@ object ResolutionRun {
ThreadUtil.withFixedThreadPool(params.parallel) { pool =>
Resolve()
+ // re-using various caches from a resolution of a configuration we extend
+ .withInitialResolution(startingResolutionOpt)
.withDependencies(
params.dependencies.collect {
case (config, dep) if configs(config) =>
@@ -126,7 +131,7 @@ object ResolutionRun {
params: ResolutionParams,
verbosityLevel: Int,
log: Logger
- ): Either[coursier.error.ResolutionError, Map[Set[Configuration], Resolution]] = {
+ ): Either[coursier.error.ResolutionError, Map[Configuration, Resolution]] = {
// TODO Warn about possible duplicated modules from source repositories?
@@ -141,13 +146,24 @@ object ResolutionRun {
// Downloads are already parallel, no need to parallelize further, anyway.
val resOrError =
Lock.lock.synchronized {
- params.configGraphs.foldLeft[Either[coursier.error.ResolutionError, Map[Set[Configuration], Resolution]]](Right(Map())) {
- case (acc, config) =>
+ var map = new mutable.HashMap[Configuration, Resolution]
+ val either = params.orderedConfigs.foldLeft[Either[coursier.error.ResolutionError, Unit]](Right(())) {
+ case (acc, (config, extends0)) =>
for {
- m <- acc
- res <- resolution(params, verbosityLevel, log, config)
- } yield m + (config -> res)
+ _ <- acc
+ initRes = {
+ val it = extends0.iterator.flatMap(map.get(_).iterator)
+ if (it.hasNext) Some(it.next())
+ else None
+ }
+ allExtends = params.allConfigExtends.getOrElse(config, Set.empty)
+ res <- resolution(params, verbosityLevel, log, allExtends, initRes)
+ } yield {
+ map += config -> res
+ ()
+ }
}
+ either.map(_ => map.toMap)
}
for (res <- resOrError)
SbtCoursierCache.default.putResolution(params.resolutionKey, res)
diff --git a/modules/lm-coursier/src/main/scala/lmcoursier/internal/SbtCoursierCache.scala b/modules/lm-coursier/src/main/scala/lmcoursier/internal/SbtCoursierCache.scala
index 23f8367c6..a018a565b 100644
--- a/modules/lm-coursier/src/main/scala/lmcoursier/internal/SbtCoursierCache.scala
+++ b/modules/lm-coursier/src/main/scala/lmcoursier/internal/SbtCoursierCache.scala
@@ -12,15 +12,15 @@ class SbtCoursierCache {
import SbtCoursierCache._
- private val resolutionsCache = new ConcurrentHashMap[ResolutionKey, Map[Set[Configuration], Resolution]]
+ private val resolutionsCache = new ConcurrentHashMap[ResolutionKey, Map[Configuration, Resolution]]
// these may actually not need to be cached any more, now that the resolutions
// are cached
private val reportsCache = new ConcurrentHashMap[ReportKey, UpdateReport]
- def resolutionOpt(key: ResolutionKey): Option[Map[Set[Configuration], Resolution]] =
+ def resolutionOpt(key: ResolutionKey): Option[Map[Configuration, Resolution]] =
Option(resolutionsCache.get(key))
- def putResolution(key: ResolutionKey, res: Map[Set[Configuration], Resolution]): Unit =
+ def putResolution(key: ResolutionKey, res: Map[Configuration, Resolution]): Unit =
resolutionsCache.put(key, res)
def reportOpt(key: ReportKey): Option[UpdateReport] =
@@ -53,7 +53,7 @@ object SbtCoursierCache {
final case class ReportKey(
dependencies: Seq[(Configuration, Dependency)],
- resolution: Map[Set[Configuration], Resolution],
+ resolution: Map[Configuration, Resolution],
withClassifiers: Boolean,
sbtClassifiers: Boolean,
includeSignatures: Boolean
diff --git a/modules/lm-coursier/src/main/scala/lmcoursier/internal/SbtUpdateReport.scala b/modules/lm-coursier/src/main/scala/lmcoursier/internal/SbtUpdateReport.scala
index 420b1fb34..17a6e52d8 100644
--- a/modules/lm-coursier/src/main/scala/lmcoursier/internal/SbtUpdateReport.scala
+++ b/modules/lm-coursier/src/main/scala/lmcoursier/internal/SbtUpdateReport.scala
@@ -132,7 +132,6 @@ private[internal] object SbtUpdateReport {
private def moduleReports(
thisModule: (Module, String),
- config: Configuration,
res: Resolution,
interProjectDependencies: Seq[Project],
classifiersOpt: Option[Seq[Classifier]],
@@ -293,9 +292,8 @@ private[internal] object SbtUpdateReport {
def apply(
thisModule: (Module, String),
configDependencies: Map[Configuration, Seq[Dependency]],
- resolutions: Map[Configuration, Resolution],
+ resolutions: Seq[(Configuration, Resolution)],
interProjectDependencies: Vector[Project],
- configs: Map[Configuration, Set[Configuration]],
classifiersOpt: Option[Seq[Classifier]],
artifactFileOpt: (Module, String, Attributes, Artifact) => Option[File],
fullArtifactsOpt: Option[Map[(Dependency, Publication, Artifact), Option[File]]],
@@ -306,18 +304,11 @@ private[internal] object SbtUpdateReport {
missingOk: Boolean
): UpdateReport = {
- val configReports = configs.map {
- case (config, extends0) =>
- val configDeps = extends0
- .toSeq
- .sortBy(_.value)
- .flatMap(configDependencies.getOrElse(_, Nil))
- .distinct
- val subRes = resolutions(config).subset(configDeps)
+ val configReports = resolutions.map {
+ case (config, subRes) =>
val reports = moduleReports(
thisModule,
- config,
subRes,
interProjectDependencies,
classifiersOpt,
diff --git a/modules/lm-coursier/src/main/scala/lmcoursier/internal/UpdateParams.scala b/modules/lm-coursier/src/main/scala/lmcoursier/internal/UpdateParams.scala
index 5a5e641e9..6c3cfe93d 100644
--- a/modules/lm-coursier/src/main/scala/lmcoursier/internal/UpdateParams.scala
+++ b/modules/lm-coursier/src/main/scala/lmcoursier/internal/UpdateParams.scala
@@ -15,7 +15,7 @@ final case class UpdateParams(
configs: Map[Configuration, Set[Configuration]],
dependencies: Seq[(Configuration, Dependency)],
interProjectDependencies: Seq[Project],
- res: Map[Set[Configuration], Resolution],
+ res: Map[Configuration, Resolution],
includeSignatures: Boolean,
sbtBootJarOverrides: Map[(Module, String), File],
classpathOrder: Boolean,
diff --git a/modules/lm-coursier/src/main/scala/lmcoursier/internal/UpdateRun.scala b/modules/lm-coursier/src/main/scala/lmcoursier/internal/UpdateRun.scala
index cdd548b8a..7744dc3e8 100644
--- a/modules/lm-coursier/src/main/scala/lmcoursier/internal/UpdateRun.scala
+++ b/modules/lm-coursier/src/main/scala/lmcoursier/internal/UpdateRun.scala
@@ -57,11 +57,6 @@ object UpdateRun {
log: Logger
): UpdateReport = Lock.lock.synchronized {
- val configResolutions = params.res.flatMap {
- case (configs, r) =>
- configs.iterator.map((_, r))
- }
-
val depsByConfig = grouped(params.dependencies)(
config =>
params.shadedConfigOpt match {
@@ -74,7 +69,7 @@ object UpdateRun {
if (verbosityLevel >= 2) {
val finalDeps = dependenciesWithConfig(
- configResolutions,
+ params.res,
depsByConfig,
params.configs
)
@@ -87,9 +82,8 @@ object UpdateRun {
SbtUpdateReport(
params.thisModule,
depsByConfig,
- configResolutions,
+ params.res.toVector.sortBy(_._1.value), // FIXME Order by config topologically?
params.interProjectDependencies.toVector,
- params.configs,
params.classifiers,
params.artifactFileOpt,
params.fullArtifacts,
diff --git a/modules/lm-coursier/src/test/scala/lmcoursier/IvyXmlTests.scala b/modules/lm-coursier/src/test/scala/lmcoursier/IvyXmlTests.scala
new file mode 100644
index 000000000..ad0ae6818
--- /dev/null
+++ b/modules/lm-coursier/src/test/scala/lmcoursier/IvyXmlTests.scala
@@ -0,0 +1,27 @@
+package lmcoursier
+
+import lmcoursier.definitions.{Configuration, Info, Module, ModuleName, Organization, Project}
+import org.scalatest.{Matchers, PropSpec}
+
+object IvyXmlTests extends PropSpec with Matchers {
+
+ property("no truncation") {
+ val project = Project(
+ Module(Organization("org"), ModuleName("name"), Map()),
+ "ver",
+ Nil,
+ Map(
+ Configuration("foo") -> (1 to 80).map(n => Configuration("bar" + n)) // long list of configurations -> no truncation any way
+ ),
+ Nil,
+ None,
+ Nil,
+ Info("", "", Nil, Nil, None)
+ )
+
+ val content = IvyXml(project, Nil, None)
+
+ assert(!content.contains(""))
+ }
+
+}
diff --git a/modules/sbt-coursier-shared/src/main/scala/coursier/sbtcoursiershared/InputsTasks.scala b/modules/sbt-coursier-shared/src/main/scala/coursier/sbtcoursiershared/InputsTasks.scala
index 3a687c483..97d77d458 100644
--- a/modules/sbt-coursier-shared/src/main/scala/coursier/sbtcoursiershared/InputsTasks.scala
+++ b/modules/sbt-coursier-shared/src/main/scala/coursier/sbtcoursiershared/InputsTasks.scala
@@ -28,32 +28,21 @@ object InputsTasks {
private def coursierProject0(
projId: ModuleID,
dependencies: Seq[ModuleID],
- excludeDeps: Seq[InclExclRule],
configurations: Seq[sbt.librarymanagement.Configuration],
sv: String,
sbv: String,
log: Logger
): Project = {
- val exclusions0 = Inputs.exclusions(excludeDeps, sv, sbv, log)
+ val configMap = Inputs.configExtendsSeq(configurations).toMap
- val configMap = Inputs.configExtends(configurations)
-
- val proj = FromSbt.project(
+ FromSbt.project(
projId,
dependencies,
configMap,
sv,
sbv
)
-
- proj.withDependencies(
- proj.dependencies.map {
- case (config, dep) =>
- val dep0 = dep.withExclusions(dep.exclusions ++ exclusions0)
- (config, dep0)
- }
- )
}
private[sbtcoursiershared] def coursierProjectTask: Def.Initialize[sbt.Task[Project]] =
@@ -68,7 +57,6 @@ object InputsTasks {
coursierProject0(
projectID.in(projectRef).get(state),
allDependenciesTask.value,
- actualExcludeDependencies.in(projectRef).get(state),
// should projectID.configurations be used instead?
ivyConfigurations.in(projectRef).get(state),
scalaVersion.in(projectRef).get(state),
diff --git a/modules/sbt-coursier-shared/src/main/scala/coursier/sbtcoursiershared/IvyXmlGeneration.scala b/modules/sbt-coursier-shared/src/main/scala/coursier/sbtcoursiershared/IvyXmlGeneration.scala
new file mode 100644
index 000000000..35c681662
--- /dev/null
+++ b/modules/sbt-coursier-shared/src/main/scala/coursier/sbtcoursiershared/IvyXmlGeneration.scala
@@ -0,0 +1,99 @@
+package coursier.sbtcoursiershared
+
+import java.nio.charset.StandardCharsets.UTF_8
+import java.nio.file.Files
+
+import lmcoursier.{Inputs, IvyXml}
+import lmcoursier.definitions.{Configuration, Project}
+import org.apache.ivy.core.module.id.ModuleRevisionId
+import sbt.{Def, Setting, Task, TaskKey}
+import sbt.internal.librarymanagement.IvySbt
+import sbt.librarymanagement.{CrossVersion, PublishConfiguration}
+
+import scala.collection.JavaConverters._
+
+object IvyXmlGeneration {
+
+ // These are required for publish to be fine, later on.
+ private def writeFiles(
+ currentProject: Project,
+ exclusions: Seq[(String, String)],
+ shadedConfigOpt: Option[Configuration],
+ ivySbt: IvySbt,
+ log: sbt.util.Logger
+ ): Unit = {
+
+ val ivyCacheManager = ivySbt.withIvy(log)(ivy =>
+ ivy.getResolutionCacheManager
+ )
+
+ val ivyModule = ModuleRevisionId.newInstance(
+ currentProject.module.organization.value,
+ currentProject.module.name.value,
+ currentProject.version,
+ currentProject.module.attributes.asJava
+ )
+
+ val cacheIvyFile = ivyCacheManager.getResolvedIvyFileInCache(ivyModule)
+ val cacheIvyPropertiesFile = ivyCacheManager.getResolvedIvyPropertiesInCache(ivyModule)
+
+ val content0 = IvyXml(currentProject, exclusions, shadedConfigOpt)
+ cacheIvyFile.getParentFile.mkdirs()
+ log.info(s"Writing Ivy file $cacheIvyFile")
+ Files.write(cacheIvyFile.toPath, content0.getBytes(UTF_8))
+
+ // Just writing an empty file here... Are these only used?
+ cacheIvyPropertiesFile.getParentFile.mkdirs()
+ Files.write(cacheIvyPropertiesFile.toPath, Array.emptyByteArray)
+ }
+
+ private def makeIvyXmlBefore[T](
+ task: TaskKey[T],
+ shadedConfigOpt: Option[Configuration]
+ ): Setting[Task[T]] =
+ task := task.dependsOn {
+ Def.taskDyn {
+ import SbtCoursierShared.autoImport._
+ val doGen = coursierGenerateIvyXml.value
+ if (doGen)
+ Def.task {
+ val sv = sbt.Keys.scalaVersion.value
+ val sbv = sbt.Keys.scalaBinaryVersion.value
+ val log = sbt.Keys.streams.value.log
+ val currentProject = {
+ val proj = coursierProject.value
+ val publications = coursierPublications.value
+ proj.withPublications(publications)
+ }
+ val excludeDeps = Inputs.exclusionsSeq(InputsTasks.actualExcludeDependencies.value, sv, sbv, log)
+ .map {
+ case (org, name) =>
+ (org.value, name.value)
+ }
+ writeFiles(currentProject, excludeDeps, shadedConfigOpt, sbt.Keys.ivySbt.value, log)
+ }
+ else
+ Def.task(())
+ }
+ }.value
+
+ private lazy val needsIvyXmlLocal = Seq(sbt.Keys.publishLocalConfiguration) ++ getPubConf("makeIvyXmlLocalConfiguration")
+ private lazy val needsIvyXml = Seq(sbt.Keys.publishConfiguration) ++ getPubConf("makeIvyXmlConfiguration")
+
+ private[this] def getPubConf(method: String): List[TaskKey[PublishConfiguration]] =
+ try {
+ val cls = sbt.Keys.getClass
+ val m = cls.getMethod(method)
+ val task = m.invoke(sbt.Keys).asInstanceOf[TaskKey[PublishConfiguration]]
+ List(task)
+ } catch {
+ case _: Throwable => // FIXME Too wide
+ Nil
+ }
+
+ def generateIvyXmlSettings(
+ shadedConfigOpt: Option[Configuration] = None
+ ): Seq[Setting[_]] =
+ (needsIvyXml ++ needsIvyXmlLocal).map(makeIvyXmlBefore(_, shadedConfigOpt))
+
+}
diff --git a/modules/sbt-coursier-shared/src/main/scala/coursier/sbtcoursiershared/SbtCoursierShared.scala b/modules/sbt-coursier-shared/src/main/scala/coursier/sbtcoursiershared/SbtCoursierShared.scala
index 1f896c1b5..174042d62 100644
--- a/modules/sbt-coursier-shared/src/main/scala/coursier/sbtcoursiershared/SbtCoursierShared.scala
+++ b/modules/sbt-coursier-shared/src/main/scala/coursier/sbtcoursiershared/SbtCoursierShared.scala
@@ -174,7 +174,7 @@ object SbtCoursierShared extends AutoPlugin {
versionReconciliation := Seq.empty
) ++ {
if (pubSettings)
- IvyXml.generateIvyXmlSettings()
+ IvyXmlGeneration.generateIvyXmlSettings()
else
Nil
}
diff --git a/modules/sbt-coursier-shared/src/test/scala/coursier/sbtcoursiershared/IvyXmlTests.scala b/modules/sbt-coursier-shared/src/test/scala/coursier/sbtcoursiershared/IvyXmlTests.scala
deleted file mode 100644
index 6a460e0be..000000000
--- a/modules/sbt-coursier-shared/src/test/scala/coursier/sbtcoursiershared/IvyXmlTests.scala
+++ /dev/null
@@ -1,30 +0,0 @@
-package coursier.sbtcoursiershared
-
-import lmcoursier.definitions.{Configuration, Info, Module, ModuleName, Organization, Project}
-import utest._
-
-object IvyXmlTests extends TestSuite {
-
- val tests = Tests {
- "no truncation" - {
-
- val project = Project(
- Module(Organization("org"), ModuleName("name"), Map()),
- "ver",
- Nil,
- Map(
- Configuration("foo") -> (1 to 80).map(n => Configuration("bar" + n)) // long list of configurations -> no truncation any way
- ),
- Nil,
- None,
- Nil,
- Info("", "", Nil, Nil, None)
- )
-
- val content = IvyXml.rawContent(project, None)
-
- assert(!content.contains(""))
- }
- }
-
-}
diff --git a/modules/sbt-coursier/src/main/scala/coursier/sbtcoursier/ArtifactsTasks.scala b/modules/sbt-coursier/src/main/scala/coursier/sbtcoursier/ArtifactsTasks.scala
index bf2a41121..39e3a24db 100644
--- a/modules/sbt-coursier/src/main/scala/coursier/sbtcoursier/ArtifactsTasks.scala
+++ b/modules/sbt-coursier/src/main/scala/coursier/sbtcoursier/ArtifactsTasks.scala
@@ -24,7 +24,7 @@ object ArtifactsTasks {
val resTask: sbt.Def.Initialize[sbt.Task[Seq[Resolution]]] =
if (withClassifiers && sbtClassifiers)
- Def.task(Seq(coursierSbtClassifiersResolution.value))
+ Def.task(coursierSbtClassifiersResolutions.value.values.toVector)
else
Def.task(coursierResolutions.value.values.toVector)
diff --git a/modules/sbt-coursier/src/main/scala/coursier/sbtcoursier/CoursierPlugin.scala b/modules/sbt-coursier/src/main/scala/coursier/sbtcoursier/CoursierPlugin.scala
index 7ccb8b98e..8cfdfbb14 100644
--- a/modules/sbt-coursier/src/main/scala/coursier/sbtcoursier/CoursierPlugin.scala
+++ b/modules/sbt-coursier/src/main/scala/coursier/sbtcoursier/CoursierPlugin.scala
@@ -30,7 +30,7 @@ object CoursierPlugin extends AutoPlugin {
val coursierParentProjectCache = Keys.coursierParentProjectCache
val coursierResolutions = Keys.coursierResolutions
- val coursierSbtClassifiersResolution = Keys.coursierSbtClassifiersResolution
+ val coursierSbtClassifiersResolutions = Keys.coursierSbtClassifiersResolutions
val coursierDependencyTree = Keys.coursierDependencyTree
val coursierDependencyInverseTree = Keys.coursierDependencyInverseTree
@@ -176,21 +176,18 @@ object CoursierPlugin extends AutoPlugin {
coursierResolutions
.value
- .collectFirst {
- case (configs, res) if configs(config) =>
- res
- }
- .getOrElse {
+ .getOrElse(
+ config,
sys.error(s"Resolution for configuration $config not found")
- }
+ )
},
- coursierSbtClassifiersResolution := (Def.taskDyn {
+ coursierSbtClassifiersResolutions := (Def.taskDyn {
val missingOk = (updateConfiguration in updateSbtClassifiers).value.missingOk
ResolutionTasks.resolutionsTask(
sbtClassifiers = true,
missingOk = missingOk,
)
- }).value.head._2
+ }).value
)
override lazy val buildSettings = super.buildSettings ++ Seq(
diff --git a/modules/sbt-coursier/src/main/scala/coursier/sbtcoursier/DisplayTasks.scala b/modules/sbt-coursier/src/main/scala/coursier/sbtcoursier/DisplayTasks.scala
index d708f2bd8..8f56a12fc 100644
--- a/modules/sbt-coursier/src/main/scala/coursier/sbtcoursier/DisplayTasks.scala
+++ b/modules/sbt-coursier/src/main/scala/coursier/sbtcoursier/DisplayTasks.scala
@@ -13,7 +13,7 @@ import scala.collection.mutable
object DisplayTasks {
- private case class ResolutionResult(configs: Set[Configuration], resolution: Resolution, dependencies: Seq[Dependency])
+ private case class ResolutionResult(config: Configuration, resolution: Resolution, dependencies: Seq[Dependency])
private def coursierResolutionTask(
sbtClassifiers: Boolean = false,
@@ -37,13 +37,9 @@ object DisplayTasks {
val resolutionsTask =
if (sbtClassifiers)
- Def.task {
- val currentProject = currentProjectTask.value
- val classifiersRes = coursierSbtClassifiersResolution.value
- Map(currentProject.configurations.keySet.map(ToCoursier.configuration) -> classifiersRes)
- }
+ coursierSbtClassifiersResolutions
else
- Def.task(coursierResolutions.value)
+ coursierResolutions
Def.task {
@@ -57,19 +53,23 @@ object DisplayTasks {
val resolutions = resolutionsTask.value
for {
- (subGraphConfigs, res) <- resolutions.toSeq
- if subGraphConfigs.exists(includedConfigs)
+ (subGraphConfig, res) <- resolutions.toSeq
+ if includedConfigs(subGraphConfig)
} yield {
- val dependencies0 = currentProject.dependencies.collect {
- case (cfg, dep) if includedConfigs(cfg) && subGraphConfigs(cfg) => dep
- }.sortBy { dep =>
- (dep.module.organization, dep.module.name, dep.version)
- }
+ val dependencies0 = currentProject
+ .dependencies
+ .collect {
+ case (`subGraphConfig`, dep) =>
+ dep
+ }
+ .sortBy { dep =>
+ (dep.module.organization, dep.module.name, dep.version)
+ }
val subRes = res.subset(dependencies0)
- ResolutionResult(subGraphConfigs, subRes, dependencies0)
+ ResolutionResult(subGraphConfig, subRes, dependencies0)
}
}
}
@@ -82,9 +82,9 @@ object DisplayTasks {
val projectName = thisProjectRef.value.project
val resolutions = coursierResolutionTask(sbtClassifiers, ignoreArtifactErrors).value
- for (ResolutionResult(subGraphConfigs, resolution, dependencies) <- resolutions) {
+ for (ResolutionResult(subGraphConfig, resolution, dependencies) <- resolutions) {
streams.value.log.info(
- s"$projectName (configurations ${subGraphConfigs.toVector.sorted.mkString(", ")})" + "\n" +
+ s"$projectName (configuration ${subGraphConfig.value})" + "\n" +
Print.dependencyTree(
resolution,
dependencies,
@@ -110,13 +110,13 @@ object DisplayTasks {
val resolutions = coursierResolutionTask(sbtClassifiers, ignoreArtifactErrors).value
val result = new mutable.StringBuilder
- for (ResolutionResult(subGraphConfigs, resolution, _) <- resolutions) {
+ for (ResolutionResult(subGraphConfig, resolution, _) <- resolutions) {
val roots = resolution
.minDependencies
.filter(f => f.module == module)
.toVector
.sortBy(_.toString) // elements already have the same module, there's not much left for sorting…
- val strToPrint = s"$projectName (configurations ${subGraphConfigs.toVector.sorted.map(_.value).mkString(", ")})" + "\n" +
+ val strToPrint = s"$projectName (configurations ${subGraphConfig.value})" + "\n" +
Print.dependencyTree(
resolution,
roots,
diff --git a/modules/sbt-coursier/src/main/scala/coursier/sbtcoursier/InputsTasks.scala b/modules/sbt-coursier/src/main/scala/coursier/sbtcoursier/InputsTasks.scala
index 8f743a4fc..af1900ab3 100644
--- a/modules/sbt-coursier/src/main/scala/coursier/sbtcoursier/InputsTasks.scala
+++ b/modules/sbt-coursier/src/main/scala/coursier/sbtcoursier/InputsTasks.scala
@@ -26,10 +26,13 @@ object InputsTasks {
}
}
- def ivyGraphsTask: Def.Initialize[sbt.Task[Seq[Set[Configuration]]]] =
+ def ivyGraphsTask: Def.Initialize[sbt.Task[Seq[(Configuration, Seq[Configuration])]]] =
Def.task {
val p = coursierProject.value
- Inputs.ivyGraphs(p.configurations).map(_.map(ToCoursier.configuration))
+ Inputs.orderedConfigurations(p.configurations.toSeq).map {
+ case (config, extends0) =>
+ (ToCoursier.configuration(config), extends0.map(ToCoursier.configuration))
+ }
}
def parentProjectCacheTask: Def.Initialize[sbt.Task[Map[Seq[sbt.librarymanagement.Resolver], Seq[coursier.ProjectCache]]]] =
@@ -53,7 +56,7 @@ object InputsTasks {
n.foldLeft(Map.empty[Seq[Resolver], Seq[ProjectCache]]) {
case (caches, (ref, resolutions)) =>
val mainResOpt = resolutions.collectFirst {
- case (k, v) if k(Configuration.compile) => v
+ case (Configuration.compile, v) => v
}
val r = for {
diff --git a/modules/sbt-coursier/src/main/scala/coursier/sbtcoursier/Keys.scala b/modules/sbt-coursier/src/main/scala/coursier/sbtcoursier/Keys.scala
index 4e4df6ad1..6fe4a8d28 100644
--- a/modules/sbt-coursier/src/main/scala/coursier/sbtcoursier/Keys.scala
+++ b/modules/sbt-coursier/src/main/scala/coursier/sbtcoursier/Keys.scala
@@ -21,7 +21,7 @@ object Keys {
val coursierVerbosity = SettingKey[Int]("coursier-verbosity")
- val coursierConfigGraphs = TaskKey[Seq[Set[Configuration]]]("coursier-config-graphs")
+ val coursierConfigGraphs = TaskKey[Seq[(Configuration, Seq[Configuration])]]("coursier-config-graphs")
val coursierSbtClassifiersModule = TaskKey[GetClassifiersModule]("coursier-sbt-classifiers-module")
@@ -29,11 +29,11 @@ object Keys {
val coursierParentProjectCache = TaskKey[Map[Seq[Resolver], Seq[ProjectCache]]]("coursier-parent-project-cache")
- val coursierResolutions = TaskKey[Map[Set[Configuration], Resolution]]("coursier-resolutions")
+ val coursierResolutions = TaskKey[Map[Configuration, Resolution]]("coursier-resolutions")
private[coursier] val actualCoursierResolution = TaskKey[Resolution]("coursier-resolution")
- val coursierSbtClassifiersResolution = TaskKey[Resolution]("coursier-sbt-classifiers-resolution")
+ val coursierSbtClassifiersResolutions = TaskKey[Map[Configuration, Resolution]]("coursier-sbt-classifiers-resolution")
val coursierDependencyTree = TaskKey[Unit](
"coursier-dependency-tree",
diff --git a/modules/sbt-coursier/src/main/scala/coursier/sbtcoursier/ResolutionTasks.scala b/modules/sbt-coursier/src/main/scala/coursier/sbtcoursier/ResolutionTasks.scala
index ef7e923ba..ee3166fe0 100644
--- a/modules/sbt-coursier/src/main/scala/coursier/sbtcoursier/ResolutionTasks.scala
+++ b/modules/sbt-coursier/src/main/scala/coursier/sbtcoursier/ResolutionTasks.scala
@@ -19,9 +19,9 @@ object ResolutionTasks {
def resolutionsTask(
sbtClassifiers: Boolean = false,
missingOk: Boolean = false,
- ): Def.Initialize[sbt.Task[Map[Set[Configuration], coursier.Resolution]]] = {
+ ): Def.Initialize[sbt.Task[Map[Configuration, coursier.Resolution]]] = {
- val currentProjectTask: sbt.Def.Initialize[sbt.Task[(Project, Seq[FallbackDependency], Seq[Set[Configuration]])]] =
+ val currentProjectTask: sbt.Def.Initialize[sbt.Task[(Project, Seq[FallbackDependency], Seq[(Configuration, Seq[Configuration])])]] =
if (sbtClassifiers)
Def.task {
val sv = scalaVersion.value
@@ -35,7 +35,7 @@ object ResolutionTasks {
sbv
)
- (proj, fallbackDeps, Vector(cm.configurations.map(c => Configuration(c.name)).toSet))
+ (proj, fallbackDeps, cm.configurations.map(c => Configuration(c.name) -> Nil))
}
else
Def.task {
@@ -97,7 +97,7 @@ object ResolutionTasks {
val authenticationByRepositoryId = coursierCredentials.value.mapValues(_.authentication)
- val (currentProject, fallbackDependencies, configGraphs) = currentProjectTask.value
+ val (currentProject, fallbackDependencies, orderedConfigs) = currentProjectTask.value
val autoScalaLib = autoScalaLibrary.value && scalaModuleInfo.value.forall(_.overrideScalaVersion)
@@ -114,6 +114,16 @@ object ResolutionTasks {
.map(_.foldLeft[ProjectCache](Map.empty)(_ ++ _))
.getOrElse(Map.empty)
+ val excludeDeps = Inputs.exclusions(
+ coursier.sbtcoursiershared.InputsTasks.actualExcludeDependencies.value,
+ sv,
+ sbv,
+ log
+ ).map {
+ case (org, name) =>
+ (Organization(org.value), ModuleName(name.value))
+ }
+
val mainRepositories = resolvers
.flatMap { resolver =>
Resolvers.repository(
@@ -132,7 +142,7 @@ object ResolutionTasks {
ResolutionParams(
dependencies = currentProject.dependencies,
fallbackDependencies = fallbackDependencies,
- configGraphs = configGraphs,
+ orderedConfigs = orderedConfigs,
autoScalaLibOpt = if (autoScalaLib) Some((so, sv)) else None,
mainRepositories = mainRepositories,
parentProjectCache = parentProjectCache,
@@ -154,7 +164,8 @@ object ResolutionTasks {
.withProfiles(userEnabledProfiles)
.withForceVersion(userForceVersions.map { case (k, v) => (ToCoursier.module(k), v) }.toMap)
.withTypelevel(typelevel)
- .addReconciliation(versionReconciliations0: _*),
+ .addReconciliation(versionReconciliations0: _*)
+ .withExclusions(excludeDeps),
strictOpt = strictOpt,
missingOk = missingOk,
),
diff --git a/modules/sbt-coursier/src/main/scala/coursier/sbtcoursier/UpdateTasks.scala b/modules/sbt-coursier/src/main/scala/coursier/sbtcoursier/UpdateTasks.scala
index 693cc9df3..0cc24a47a 100644
--- a/modules/sbt-coursier/src/main/scala/coursier/sbtcoursier/UpdateTasks.scala
+++ b/modules/sbt-coursier/src/main/scala/coursier/sbtcoursier/UpdateTasks.scala
@@ -34,13 +34,9 @@ object UpdateTasks {
val resTask =
if (withClassifiers && sbtClassifiers)
- Def.task {
- val cm = coursierSbtClassifiersModule.value
- val classifiersRes = coursierSbtClassifiersResolution.value
- Map(cm.configurations.map(c => Configuration(c.name)).toSet -> classifiersRes)
- }
+ coursierSbtClassifiersResolutions
else
- Def.task(coursierResolutions.value)
+ coursierResolutions
// we should be able to call .value on that one here, its conditions don't originate from other tasks
val artifactFilesOrErrors0Task =
diff --git a/modules/sbt-coursier/src/sbt-test/sbt-coursier/dependency-graph/build.sbt b/modules/sbt-coursier/src/sbt-test/sbt-coursier/dependency-graph/build.sbt
index 671c71f89..54a8ba1e9 100644
--- a/modules/sbt-coursier/src/sbt-test/sbt-coursier/dependency-graph/build.sbt
+++ b/modules/sbt-coursier/src/sbt-test/sbt-coursier/dependency-graph/build.sbt
@@ -12,5 +12,6 @@ import CoursierPlugin.autoImport._
whatDependsOnCheck := {
val result = (coursierWhatDependsOn in Compile).toTask(" log4j:log4j").value
val file = new File("whatDependsOnResult.log")
- assert(IO.read(file).toString == result)
+ val expected = IO.read(file).toString
+ assert(expected == result, s"Expected '$expected', got '$result'")
}
diff --git a/modules/sbt-coursier/src/sbt-test/sbt-coursier/dependency-graph/src/main/scala/Main.scala b/modules/sbt-coursier/src/sbt-test/sbt-coursier/dependency-graph/src/main/scala/Main.scala
deleted file mode 100644
index 032874759..000000000
--- a/modules/sbt-coursier/src/sbt-test/sbt-coursier/dependency-graph/src/main/scala/Main.scala
+++ /dev/null
@@ -1,8 +0,0 @@
-import java.io.File
-import java.nio.file.Files
-
-import org.apache.zookeeper.ZooKeeper
-
-object Main extends App {
- Files.write(new File("output").toPath, classOf[ZooKeeper].getSimpleName.getBytes("UTF-8"))
-}
diff --git a/modules/sbt-coursier/src/sbt-test/sbt-coursier/dependency-graph/whatDependsOnResult.log b/modules/sbt-coursier/src/sbt-test/sbt-coursier/dependency-graph/whatDependsOnResult.log
index e0e5a5377..64d70c9bb 100644
--- a/modules/sbt-coursier/src/sbt-test/sbt-coursier/dependency-graph/whatDependsOnResult.log
+++ b/modules/sbt-coursier/src/sbt-test/sbt-coursier/dependency-graph/whatDependsOnResult.log
@@ -1,4 +1,4 @@
-dependency-graph (configurations compile, compile-internal, optional, provided, runtime, runtime-internal, test, test-internal)
+dependency-graph (configurations compile)
└─ log4j:log4j:1.2.17
├─ org.apache.zookeeper:zookeeper:3.5.0-alpha log4j:log4j:1.2.16 -> 1.2.17
└─ org.slf4j:slf4j-log4j12:1.7.5
diff --git a/modules/sbt-coursier/src/sbt-test/shared-1/all-exclude-dependencies/coursier b/modules/sbt-coursier/src/sbt-test/shared-1/all-exclude-dependencies/coursier
index 6cada6f8b..1153c1797 100755
Binary files a/modules/sbt-coursier/src/sbt-test/shared-1/all-exclude-dependencies/coursier and b/modules/sbt-coursier/src/sbt-test/shared-1/all-exclude-dependencies/coursier differ
diff --git a/modules/sbt-coursier/src/sbt-test/shared-1/all-exclude-dependencies/src/main/scala/Main.scala b/modules/sbt-coursier/src/sbt-test/shared-1/all-exclude-dependencies/src/main/scala/Main.scala
index 1bc056610..89960e16b 100644
--- a/modules/sbt-coursier/src/sbt-test/shared-1/all-exclude-dependencies/src/main/scala/Main.scala
+++ b/modules/sbt-coursier/src/sbt-test/shared-1/all-exclude-dependencies/src/main/scala/Main.scala
@@ -27,6 +27,4 @@ object Main extends App {
!argonautFound,
"Expected not to find classes from argonaut"
)
-
- Files.write(new File("output").toPath, "OK".getBytes("UTF-8"))
}
diff --git a/modules/sbt-coursier/src/sbt-test/shared-1/all-exclude-dependencies/test b/modules/sbt-coursier/src/sbt-test/shared-1/all-exclude-dependencies/test
index 27ecd9d91..731ff86e2 100644
--- a/modules/sbt-coursier/src/sbt-test/shared-1/all-exclude-dependencies/test
+++ b/modules/sbt-coursier/src/sbt-test/shared-1/all-exclude-dependencies/test
@@ -1,5 +1,3 @@
-$ delete output
> run
-$ exists output
> publishLocal
$ exec java -jar coursier launch io.get-coursier.test:sbt-coursier-all-exclude-dependencies_2.12:0.1.0-SNAPSHOT
diff --git a/modules/sbt-coursier/src/sbt-test/shared-1/exclude-dependencies/src/main/scala/Main.scala b/modules/sbt-coursier/src/sbt-test/shared-1/exclude-dependencies/a/src/main/scala/Main.scala
similarity index 91%
rename from modules/sbt-coursier/src/sbt-test/shared-1/exclude-dependencies/src/main/scala/Main.scala
rename to modules/sbt-coursier/src/sbt-test/shared-1/exclude-dependencies/a/src/main/scala/Main.scala
index 1bc056610..89960e16b 100644
--- a/modules/sbt-coursier/src/sbt-test/shared-1/exclude-dependencies/src/main/scala/Main.scala
+++ b/modules/sbt-coursier/src/sbt-test/shared-1/exclude-dependencies/a/src/main/scala/Main.scala
@@ -27,6 +27,4 @@ object Main extends App {
!argonautFound,
"Expected not to find classes from argonaut"
)
-
- Files.write(new File("output").toPath, "OK".getBytes("UTF-8"))
}
diff --git a/modules/sbt-coursier/src/sbt-test/shared-1/exclude-dependencies/b/src/main/scala/Main.scala b/modules/sbt-coursier/src/sbt-test/shared-1/exclude-dependencies/b/src/main/scala/Main.scala
new file mode 100644
index 000000000..89960e16b
--- /dev/null
+++ b/modules/sbt-coursier/src/sbt-test/shared-1/exclude-dependencies/b/src/main/scala/Main.scala
@@ -0,0 +1,30 @@
+import java.io.File
+import java.nio.file.Files
+
+import scala.util.Try
+
+object Main extends App {
+
+ def classFound(clsName: String) = Try(
+ Thread.currentThread()
+ .getContextClassLoader()
+ .loadClass(clsName)
+ ).toOption.nonEmpty
+
+ val shapelessFound = classFound("shapeless.HList")
+ val argonautFound = classFound("argonaut.Json")
+ val argonautShapelessFound = classFound("argonaut.derive.MkEncodeJson")
+
+ assert(
+ argonautShapelessFound,
+ "Expected to find class from argonaut-shapeless"
+ )
+ assert(
+ !shapelessFound,
+ "Expected not to find classes from shapeless"
+ )
+ assert(
+ !argonautFound,
+ "Expected not to find classes from argonaut"
+ )
+}
diff --git a/modules/sbt-coursier/src/sbt-test/shared-1/exclude-dependencies/build.sbt b/modules/sbt-coursier/src/sbt-test/shared-1/exclude-dependencies/build.sbt
index 0ac1493d5..7888e23ca 100644
--- a/modules/sbt-coursier/src/sbt-test/shared-1/exclude-dependencies/build.sbt
+++ b/modules/sbt-coursier/src/sbt-test/shared-1/exclude-dependencies/build.sbt
@@ -1,11 +1,26 @@
-scalaVersion := "2.12.8"
+lazy val a = project
+ .settings(
+ organization := "io.get-coursier.test",
+ name := "sbt-coursier-exclude-dependencies",
+ version := "0.1.0-SNAPSHOT",
+ scalaVersion := "2.12.8",
+ libraryDependencies += "com.github.alexarchambault" %% "argonaut-shapeless_6.2" % "1.2.0-M11",
+ excludeDependencies += sbt.ExclusionRule("com.chuusai", "shapeless_2.12"),
+ excludeDependencies += "io.argonaut" %% "argonaut"
+ )
-organization := "io.get-coursier.test"
-name := "sbt-coursier-exclude-dependencies"
-version := "0.1.0-SNAPSHOT"
-
-libraryDependencies += "com.github.alexarchambault" %% "argonaut-shapeless_6.2" % "1.2.0-M11"
-
-excludeDependencies += sbt.ExclusionRule("com.chuusai", "shapeless_2.12")
-excludeDependencies += "io.argonaut" %% "argonaut"
+lazy val b = project
+ .settings(
+ organization := "io.get-coursier.test",
+ name := "sbt-coursier-exclude-dependencies-2",
+ version := "0.1.0-SNAPSHOT",
+ scalaVersion := "2.12.8",
+ libraryDependencies ++= Seq(
+ "com.github.alexarchambault" %% "argonaut-shapeless_6.2" % "1.2.0-M11",
+ "com.chuusai" %% "shapeless" % "2.3.3",
+ "io.argonaut" %% "argonaut" % "6.2.3"
+ ),
+ excludeDependencies += sbt.ExclusionRule("com.chuusai", "shapeless_2.12"),
+ excludeDependencies += "io.argonaut" %% "argonaut"
+ )
diff --git a/modules/sbt-coursier/src/sbt-test/shared-1/exclude-dependencies/coursier b/modules/sbt-coursier/src/sbt-test/shared-1/exclude-dependencies/coursier
index 6cada6f8b..eb1b55198 100755
Binary files a/modules/sbt-coursier/src/sbt-test/shared-1/exclude-dependencies/coursier and b/modules/sbt-coursier/src/sbt-test/shared-1/exclude-dependencies/coursier differ
diff --git a/modules/sbt-coursier/src/sbt-test/shared-1/exclude-dependencies/test b/modules/sbt-coursier/src/sbt-test/shared-1/exclude-dependencies/test
index fa5d6a196..11d45a4a2 100644
--- a/modules/sbt-coursier/src/sbt-test/shared-1/exclude-dependencies/test
+++ b/modules/sbt-coursier/src/sbt-test/shared-1/exclude-dependencies/test
@@ -1,5 +1,6 @@
-$ delete output
-> run
-$ exists output
-> publishLocal
+> a/run
+> a/publishLocal
$ exec java -jar coursier launch io.get-coursier.test:sbt-coursier-exclude-dependencies_2.12:0.1.0-SNAPSHOT
+> b/run
+> b/publishLocal
+$ exec java -jar coursier launch io.get-coursier.test:sbt-coursier-exclude-dependencies-2_2.12:0.1.0-SNAPSHOT
diff --git a/modules/sbt-coursier/src/sbt-test/shared-2/per-config-resolution/build.sbt b/modules/sbt-coursier/src/sbt-test/shared-2/per-config-resolution/build.sbt
new file mode 100644
index 000000000..f2f2507cf
--- /dev/null
+++ b/modules/sbt-coursier/src/sbt-test/shared-2/per-config-resolution/build.sbt
@@ -0,0 +1,8 @@
+scalaVersion := "2.13.2"
+libraryDependencies ++= Seq(
+ "io.get-coursier" %% "coursier-core" % "2.0.0-RC6",
+ // depends on coursier-core 2.0.0-RC6-16
+ "io.get-coursier" %% "coursier" % "2.0.0-RC6-16" % Test
+)
+mainClass.in(Compile) := Some("Main")
+mainClass.in(Test) := Some("Test")
diff --git a/modules/sbt-coursier/src/sbt-test/shared-2/per-config-resolution/project/plugins.sbt b/modules/sbt-coursier/src/sbt-test/shared-2/per-config-resolution/project/plugins.sbt
new file mode 100644
index 000000000..71a44ffd3
--- /dev/null
+++ b/modules/sbt-coursier/src/sbt-test/shared-2/per-config-resolution/project/plugins.sbt
@@ -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
+}
\ No newline at end of file
diff --git a/modules/sbt-coursier/src/sbt-test/shared-2/per-config-resolution/src/main/scala/Main.scala b/modules/sbt-coursier/src/sbt-test/shared-2/per-config-resolution/src/main/scala/Main.scala
new file mode 100644
index 000000000..370b4e4bf
--- /dev/null
+++ b/modules/sbt-coursier/src/sbt-test/shared-2/per-config-resolution/src/main/scala/Main.scala
@@ -0,0 +1,7 @@
+object Main {
+ def main(args: Array[String]): Unit = {
+ val version = coursier.util.Properties.version
+ val expected = "2.0.0-RC6"
+ assert(version == expected, s"version: $version, expected: $expected")
+ }
+}
diff --git a/modules/sbt-coursier/src/sbt-test/shared-2/per-config-resolution/src/test/scala/Test.scala b/modules/sbt-coursier/src/sbt-test/shared-2/per-config-resolution/src/test/scala/Test.scala
new file mode 100644
index 000000000..9d91a9318
--- /dev/null
+++ b/modules/sbt-coursier/src/sbt-test/shared-2/per-config-resolution/src/test/scala/Test.scala
@@ -0,0 +1,7 @@
+object Test {
+ def main(args: Array[String]): Unit = {
+ val version = coursier.util.Properties.version
+ val expected = "2.0.0-RC6-16"
+ assert(version == expected, s"version: $version, expected: $expected")
+ }
+}
diff --git a/modules/sbt-coursier/src/sbt-test/shared-2/per-config-resolution/test b/modules/sbt-coursier/src/sbt-test/shared-2/per-config-resolution/test
new file mode 100644
index 000000000..e7abb0441
--- /dev/null
+++ b/modules/sbt-coursier/src/sbt-test/shared-2/per-config-resolution/test
@@ -0,0 +1,2 @@
+> run
+> test:run