diff --git a/.travis.yml b/.travis.yml index c7d814a1c..e19d1e1fe 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,7 +5,7 @@ git: depth: false # https://stackoverflow.com/a/51727114/3714539 before_install: - mkdir .bin - - curl -Lo .bin/sbt https://raw.githubusercontent.com/coursier/sbt-extras/77c93346a2b52cf35cc72382125cfdbb25a00197/sbt + - curl -Lo .bin/sbt https://github.com/coursier/sbt-extras/raw/5fb3c11d689d5aad1ead8c2ecf02e1177e5d6a88/sbt - chmod +x .bin/sbt - export PATH="$(pwd)/.bin:$PATH" - export TRAVIS_SCALA_VERSION=2.12.8 diff --git a/appveyor.yml b/appveyor.yml index 5c52755c0..f4786bc9b 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -3,8 +3,8 @@ version: '{build}' os: Windows Server 2012 install: - cmd: mkdir C:\sbt - - cmd: curl -Lo C:\sbt\sbt https://github.com/coursier/sbt-launcher/releases/download/v1.2.5/csbt - - cmd: curl -Lo C:\sbt\sbt.bat https://github.com/coursier/sbt-launcher/releases/download/v1.2.5/csbt.bat + - cmd: curl -Lo C:\sbt\sbt https://github.com/coursier/sbt-launcher/releases/download/v1.2.9/csbt + - cmd: curl -Lo C:\sbt\sbt.bat https://github.com/coursier/sbt-launcher/releases/download/v1.2.9/csbt.bat - cmd: SET JAVA_HOME=C:\Program Files\Java\jdk1.8.0 - cmd: SET PATH=C:\sbt;%JAVA_HOME%\bin;%PATH% - cmd: SET JAVA_OPTS=-Xmx4g -Xss2m diff --git a/build.sbt b/build.sbt index a32062f56..266635dac 100644 --- a/build.sbt +++ b/build.sbt @@ -15,13 +15,15 @@ inThisBuild(List( ) )) +val coursierVersion0 = "1.1.0-M14-2" + lazy val `lm-coursier` = project .in(file("modules/lm-coursier")) - .enablePlugins(ContrabandPlugin) .settings( shared, + Mima.settings, libraryDependencies ++= Seq( - "io.get-coursier" %% "coursier" % "1.1.0-M14-2", + "io.get-coursier" %% "coursier" % coursierVersion0, // We depend on librarymanagement-ivy rather than just // librarymanagement-core to handle the ModuleDescriptor passed // to DependencyResolutionInterface.update, which is an @@ -29,16 +31,32 @@ lazy val `lm-coursier` = project // is ignored). "org.scala-sbt" %% "librarymanagement-ivy" % "1.2.4", "org.scalatest" %% "scalatest" % "3.0.7" % Test + ) + ) + +lazy val `lm-coursier-shaded` = project + .in(file("modules/lm-coursier/target/shaded-module")) + .enablePlugins(ShadingPlugin) + .settings( + shared, + unmanagedSourceDirectories.in(Compile) := unmanagedSourceDirectories.in(Compile).in(`lm-coursier`).value, + shading, + shadingNamespace := "lmcoursier.internal.shaded", + shadeNamespaces ++= Set( + "coursier", + "shapeless", + "argonaut" ), - managedSourceDirectories in Compile += - baseDirectory.value / "src" / "main" / "contraband-scala", - sourceManaged in (Compile, generateContrabands) := baseDirectory.value / "src" / "main" / "contraband-scala", - contrabandFormatsForType in generateContrabands in Compile := DatatypeConfig.getFormats + libraryDependencies ++= Seq( + "io.get-coursier" %% "coursier" % coursierVersion0 % "shaded", + "org.scala-lang.modules" %% "scala-xml" % "1.1.1", // depending on that one so that it doesn't get shaded + "org.scala-sbt" %% "librarymanagement-ivy" % "1.2.4", + "org.scalatest" %% "scalatest" % "3.0.7" % Test + ) ) lazy val `sbt-coursier-shared` = project .in(file("modules/sbt-coursier-shared")) - .enablePlugins(ScriptedPlugin) .dependsOn(`lm-coursier`) .settings( plugin, @@ -47,10 +65,19 @@ lazy val `sbt-coursier-shared` = project testFrameworks += new TestFramework("utest.runner.Framework") ) +lazy val `sbt-coursier-shared-shaded` = project + .in(file("modules/sbt-coursier-shared/target/shaded-module")) + .dependsOn(`lm-coursier-shaded`) + .settings( + plugin, + generatePropertyFile, + unmanagedSourceDirectories.in(Compile) := unmanagedSourceDirectories.in(Compile).in(`sbt-coursier-shared`).value + ) + lazy val `sbt-lm-coursier` = project .in(file("modules/sbt-lm-coursier")) .enablePlugins(ScriptedPlugin) - .dependsOn(`sbt-coursier-shared`) + .dependsOn(`sbt-coursier-shared-shaded`) .settings( plugin, sbtTestDirectory := sbtTestDirectory.in(`sbt-coursier`).value, @@ -59,8 +86,8 @@ lazy val `sbt-lm-coursier` = project // TODO Get those automatically // (but shouldn't scripted itself handle that…?) - publishLocal.in(`lm-coursier`).value - publishLocal.in(`sbt-coursier-shared`).value + publishLocal.in(`lm-coursier-shaded`).value + publishLocal.in(`sbt-coursier-shared-shaded`).value } ) @@ -125,8 +152,10 @@ lazy val `sbt-coursier-root` = project .in(file(".")) .aggregate( `lm-coursier`, + `lm-coursier-shaded`, `sbt-coursier`, `sbt-coursier-shared`, + `sbt-coursier-shared-shaded`, `sbt-lm-coursier`, `sbt-pgp-coursier`, `sbt-shading` diff --git a/modules/lm-coursier/src/main/contraband-scala/coursier/lmcoursier/CoursierConfiguration.scala b/modules/lm-coursier/src/main/contraband-scala/coursier/lmcoursier/CoursierConfiguration.scala deleted file mode 100644 index e466689ac..000000000 --- a/modules/lm-coursier/src/main/contraband-scala/coursier/lmcoursier/CoursierConfiguration.scala +++ /dev/null @@ -1,135 +0,0 @@ -/** - * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. - */ - -// DO NOT EDIT MANUALLY -package coursier.lmcoursier -final class CoursierConfiguration private ( - val log: Option[xsbti.Logger], - val resolvers: Vector[sbt.librarymanagement.Resolver], - val reorderResolvers: Boolean, - val parallelDownloads: Int, - val maxIterations: Int, - val sbtScalaOrganization: Option[String], - val sbtScalaVersion: Option[String], - val sbtScalaJars: Vector[java.io.File], - val interProjectDependencies: Vector[coursier.core.Project], - val excludeDependencies: Vector[(String, String)], - val fallbackDependencies: Vector[coursier.lmcoursier.FallbackDependency], - val autoScalaLibrary: Boolean, - val hasClassifiers: Boolean, - val classifiers: Vector[String], - val mavenProfiles: Vector[String], - val scalaOrganization: Option[String], - val scalaVersion: Option[String], - val authenticationByRepositoryId: Vector[(String, coursier.core.Authentication)], - val credentials: Seq[coursier.credentials.Credentials], - val logger: Option[coursier.cache.CacheLogger], - val cache: Option[java.io.File]) extends Serializable { - - private def this() = this(None, sbt.librarymanagement.Resolver.defaults, true, 6, 100, None, None, Vector.empty, Vector.empty, Vector.empty, Vector.empty, true, false, Vector.empty, Vector.empty, None, None, Vector.empty, Vector.empty, None, None) - - override def equals(o: Any): Boolean = o match { - case x: CoursierConfiguration => (this.log == x.log) && (this.resolvers == x.resolvers) && (this.reorderResolvers == x.reorderResolvers) && (this.parallelDownloads == x.parallelDownloads) && (this.maxIterations == x.maxIterations) && (this.sbtScalaOrganization == x.sbtScalaOrganization) && (this.sbtScalaVersion == x.sbtScalaVersion) && (this.sbtScalaJars == x.sbtScalaJars) && (this.interProjectDependencies == x.interProjectDependencies) && (this.excludeDependencies == x.excludeDependencies) && (this.fallbackDependencies == x.fallbackDependencies) && (this.autoScalaLibrary == x.autoScalaLibrary) && (this.hasClassifiers == x.hasClassifiers) && (this.classifiers == x.classifiers) && (this.mavenProfiles == x.mavenProfiles) && (this.scalaOrganization == x.scalaOrganization) && (this.scalaVersion == x.scalaVersion) && (this.authenticationByRepositoryId == x.authenticationByRepositoryId) && (this.credentials == x.credentials) && (this.logger == x.logger) && (this.cache == x.cache) - case _ => false - } - override def hashCode: Int = { - 37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (17 + "coursier.lmcoursier.CoursierConfiguration".##) + log.##) + resolvers.##) + reorderResolvers.##) + parallelDownloads.##) + maxIterations.##) + sbtScalaOrganization.##) + sbtScalaVersion.##) + sbtScalaJars.##) + interProjectDependencies.##) + excludeDependencies.##) + fallbackDependencies.##) + autoScalaLibrary.##) + hasClassifiers.##) + classifiers.##) + mavenProfiles.##) + scalaOrganization.##) + scalaVersion.##) + authenticationByRepositoryId.##) + credentials.##) + logger.##) + cache.##) - } - override def toString: String = { - "CoursierConfiguration(" + log + ", " + resolvers + ", " + reorderResolvers + ", " + parallelDownloads + ", " + maxIterations + ", " + sbtScalaOrganization + ", " + sbtScalaVersion + ", " + sbtScalaJars + ", " + interProjectDependencies + ", " + excludeDependencies + ", " + fallbackDependencies + ", " + autoScalaLibrary + ", " + hasClassifiers + ", " + classifiers + ", " + mavenProfiles + ", " + scalaOrganization + ", " + scalaVersion + ", " + authenticationByRepositoryId + ", " + credentials + ", " + logger + ", " + cache + ")" - } - private[this] def copy(log: Option[xsbti.Logger] = log, resolvers: Vector[sbt.librarymanagement.Resolver] = resolvers, reorderResolvers: Boolean = reorderResolvers, parallelDownloads: Int = parallelDownloads, maxIterations: Int = maxIterations, sbtScalaOrganization: Option[String] = sbtScalaOrganization, sbtScalaVersion: Option[String] = sbtScalaVersion, sbtScalaJars: Vector[java.io.File] = sbtScalaJars, interProjectDependencies: Vector[coursier.core.Project] = interProjectDependencies, excludeDependencies: Vector[(String, String)] = excludeDependencies, fallbackDependencies: Vector[coursier.lmcoursier.FallbackDependency] = fallbackDependencies, autoScalaLibrary: Boolean = autoScalaLibrary, hasClassifiers: Boolean = hasClassifiers, classifiers: Vector[String] = classifiers, mavenProfiles: Vector[String] = mavenProfiles, scalaOrganization: Option[String] = scalaOrganization, scalaVersion: Option[String] = scalaVersion, authenticationByRepositoryId: Vector[(String, coursier.core.Authentication)] = authenticationByRepositoryId, credentials: Seq[coursier.credentials.Credentials] = credentials, logger: Option[coursier.cache.CacheLogger] = logger, cache: Option[java.io.File] = cache): CoursierConfiguration = { - new CoursierConfiguration(log, resolvers, reorderResolvers, parallelDownloads, maxIterations, sbtScalaOrganization, sbtScalaVersion, sbtScalaJars, interProjectDependencies, excludeDependencies, fallbackDependencies, autoScalaLibrary, hasClassifiers, classifiers, mavenProfiles, scalaOrganization, scalaVersion, authenticationByRepositoryId, credentials, logger, cache) - } - def withLog(log: Option[xsbti.Logger]): CoursierConfiguration = { - copy(log = log) - } - def withLog(log: xsbti.Logger): CoursierConfiguration = { - copy(log = Option(log)) - } - def withResolvers(resolvers: Vector[sbt.librarymanagement.Resolver]): CoursierConfiguration = { - copy(resolvers = resolvers) - } - def withReorderResolvers(reorderResolvers: Boolean): CoursierConfiguration = { - copy(reorderResolvers = reorderResolvers) - } - def withParallelDownloads(parallelDownloads: Int): CoursierConfiguration = { - copy(parallelDownloads = parallelDownloads) - } - def withMaxIterations(maxIterations: Int): CoursierConfiguration = { - copy(maxIterations = maxIterations) - } - def withSbtScalaOrganization(sbtScalaOrganization: Option[String]): CoursierConfiguration = { - copy(sbtScalaOrganization = sbtScalaOrganization) - } - def withSbtScalaOrganization(sbtScalaOrganization: String): CoursierConfiguration = { - copy(sbtScalaOrganization = Option(sbtScalaOrganization)) - } - def withSbtScalaVersion(sbtScalaVersion: Option[String]): CoursierConfiguration = { - copy(sbtScalaVersion = sbtScalaVersion) - } - def withSbtScalaVersion(sbtScalaVersion: String): CoursierConfiguration = { - copy(sbtScalaVersion = Option(sbtScalaVersion)) - } - def withSbtScalaJars(sbtScalaJars: Vector[java.io.File]): CoursierConfiguration = { - copy(sbtScalaJars = sbtScalaJars) - } - def withInterProjectDependencies(interProjectDependencies: Vector[coursier.core.Project]): CoursierConfiguration = { - copy(interProjectDependencies = interProjectDependencies) - } - def withExcludeDependencies(excludeDependencies: Vector[(String, String)]): CoursierConfiguration = { - copy(excludeDependencies = excludeDependencies) - } - def withFallbackDependencies(fallbackDependencies: Vector[coursier.lmcoursier.FallbackDependency]): CoursierConfiguration = { - copy(fallbackDependencies = fallbackDependencies) - } - def withAutoScalaLibrary(autoScalaLibrary: Boolean): CoursierConfiguration = { - copy(autoScalaLibrary = autoScalaLibrary) - } - def withHasClassifiers(hasClassifiers: Boolean): CoursierConfiguration = { - copy(hasClassifiers = hasClassifiers) - } - def withClassifiers(classifiers: Vector[String]): CoursierConfiguration = { - copy(classifiers = classifiers) - } - def withMavenProfiles(mavenProfiles: Vector[String]): CoursierConfiguration = { - copy(mavenProfiles = mavenProfiles) - } - def withScalaOrganization(scalaOrganization: Option[String]): CoursierConfiguration = { - copy(scalaOrganization = scalaOrganization) - } - def withScalaOrganization(scalaOrganization: String): CoursierConfiguration = { - copy(scalaOrganization = Option(scalaOrganization)) - } - def withScalaVersion(scalaVersion: Option[String]): CoursierConfiguration = { - copy(scalaVersion = scalaVersion) - } - def withScalaVersion(scalaVersion: String): CoursierConfiguration = { - copy(scalaVersion = Option(scalaVersion)) - } - def withAuthenticationByRepositoryId(authenticationByRepositoryId: Vector[(String, coursier.core.Authentication)]): CoursierConfiguration = { - copy(authenticationByRepositoryId = authenticationByRepositoryId) - } - def withCredentials(credentials: Seq[coursier.credentials.Credentials]): CoursierConfiguration = { - copy(credentials = credentials) - } - def withLogger(logger: Option[coursier.cache.CacheLogger]): CoursierConfiguration = { - copy(logger = logger) - } - def withLogger(logger: coursier.cache.CacheLogger): CoursierConfiguration = { - copy(logger = Option(logger)) - } - def withCache(cache: Option[java.io.File]): CoursierConfiguration = { - copy(cache = cache) - } - def withCache(cache: java.io.File): CoursierConfiguration = { - copy(cache = Option(cache)) - } -} -object CoursierConfiguration { - - def apply(): CoursierConfiguration = new CoursierConfiguration() - def apply(log: Option[xsbti.Logger], resolvers: Vector[sbt.librarymanagement.Resolver], reorderResolvers: Boolean, parallelDownloads: Int, maxIterations: Int, sbtScalaOrganization: Option[String], sbtScalaVersion: Option[String], sbtScalaJars: Vector[java.io.File], interProjectDependencies: Vector[coursier.core.Project], excludeDependencies: Vector[(String, String)], fallbackDependencies: Vector[coursier.lmcoursier.FallbackDependency], autoScalaLibrary: Boolean, hasClassifiers: Boolean, classifiers: Vector[String], mavenProfiles: Vector[String], scalaOrganization: Option[String], scalaVersion: Option[String], authenticationByRepositoryId: Vector[(String, coursier.core.Authentication)], credentials: Seq[coursier.credentials.Credentials], logger: Option[coursier.cache.CacheLogger], cache: Option[java.io.File]): CoursierConfiguration = new CoursierConfiguration(log, resolvers, reorderResolvers, parallelDownloads, maxIterations, sbtScalaOrganization, sbtScalaVersion, sbtScalaJars, interProjectDependencies, excludeDependencies, fallbackDependencies, autoScalaLibrary, hasClassifiers, classifiers, mavenProfiles, scalaOrganization, scalaVersion, authenticationByRepositoryId, credentials, logger, cache) - def apply(log: xsbti.Logger, resolvers: Vector[sbt.librarymanagement.Resolver], reorderResolvers: Boolean, parallelDownloads: Int, maxIterations: Int, sbtScalaOrganization: String, sbtScalaVersion: String, sbtScalaJars: Vector[java.io.File], interProjectDependencies: Vector[coursier.core.Project], excludeDependencies: Vector[(String, String)], fallbackDependencies: Vector[coursier.lmcoursier.FallbackDependency], autoScalaLibrary: Boolean, hasClassifiers: Boolean, classifiers: Vector[String], mavenProfiles: Vector[String], scalaOrganization: String, scalaVersion: String, authenticationByRepositoryId: Vector[(String, coursier.core.Authentication)], credentials: Seq[coursier.credentials.Credentials], logger: coursier.cache.CacheLogger, cache: java.io.File): CoursierConfiguration = new CoursierConfiguration(Option(log), resolvers, reorderResolvers, parallelDownloads, maxIterations, Option(sbtScalaOrganization), Option(sbtScalaVersion), sbtScalaJars, interProjectDependencies, excludeDependencies, fallbackDependencies, autoScalaLibrary, hasClassifiers, classifiers, mavenProfiles, Option(scalaOrganization), Option(scalaVersion), authenticationByRepositoryId, credentials, Option(logger), Option(cache)) -} diff --git a/modules/lm-coursier/src/main/contraband/lm-coursier.json b/modules/lm-coursier/src/main/contraband/lm-coursier.json deleted file mode 100644 index 7e46fe61c..000000000 --- a/modules/lm-coursier/src/main/contraband/lm-coursier.json +++ /dev/null @@ -1,139 +0,0 @@ -{ - "codecNamespace": "coursier.lmcoursier", - "types": [ - { - "name": "CoursierConfiguration", - "namespace": "coursier.lmcoursier", - "target": "Scala", - "type": "record", - "fields": [ - { - "name": "log", - "type": "xsbti.Logger?", - "default": "None", - "since": "0.0.1" - }, - { - "name": "resolvers", - "type": "sbt.librarymanagement.Resolver*", - "default": "sbt.librarymanagement.Resolver.defaults", - "since": "0.0.1" - }, - { - "name": "reorderResolvers", - "type": "Boolean", - "default": "true", - "since": "0.0.1" - }, - { - "name": "parallelDownloads", - "type": "Int", - "default": "6", - "since": "0.0.1" - }, - { - "name": "maxIterations", - "type": "Int", - "default": "100", - "since": "0.0.1" - }, - { - "name": "sbtScalaOrganization", - "type": "String?", - "default": "None", - "since": "0.0.1" - }, - { - "name": "sbtScalaVersion", - "type": "String?", - "default": "None", - "since": "0.0.1" - }, - { - "name": "sbtScalaJars", - "type": "java.io.File*", - "default": "Vector.empty", - "since": "0.0.1" - }, - { - "name": "interProjectDependencies", - "type": "coursier.core.Project*", - "default": "Vector.empty", - "since": "0.0.1" - }, - { - "name": "excludeDependencies", - "type": "(String, String)*", - "default": "Vector.empty", - "since": "0.0.1" - }, - { - "name": "fallbackDependencies", - "type": "coursier.lmcoursier.FallbackDependency*", - "default": "Vector.empty", - "since": "0.0.1" - }, - { - "name": "autoScalaLibrary", - "type": "Boolean", - "default": "true", - "since": "0.0.1" - }, - { - "name": "hasClassifiers", - "type": "Boolean", - "default": "false", - "since": "0.0.1" - }, - { - "name": "classifiers", - "type": "String*", - "default": "Vector.empty", - "since": "0.0.1" - }, - { - "name": "mavenProfiles", - "type": "String*", - "default": "Vector.empty", - "since": "0.0.1" - }, - { - "name": "scalaOrganization", - "type": "String?", - "default": "None", - "since": "0.0.1" - }, - { - "name": "scalaVersion", - "type": "String?", - "default": "None", - "since": "0.0.1" - }, - { - "name": "authenticationByRepositoryId", - "type": "(String, coursier.core.Authentication)*", - "default": "Vector.empty", - "since": "0.0.1" - }, - { - "name": "credentials", - "type": "Seq[coursier.credentials.Credentials]", - "default": "Vector.empty", - "since": "0.0.1" - }, - { - "name": "logger", - "type": "coursier.cache.CacheLogger?", - "default": "None", - "since": "0.0.1" - }, - { - "name": "cache", - "type": "java.io.File?", - "default": "None", - "since": "0.0.1" - } - ] - } - ] -} diff --git a/modules/lm-coursier/src/main/scala/coursier/lmcoursier/CoursierModuleSettings.scala b/modules/lm-coursier/src/main/scala/coursier/lmcoursier/CoursierModuleSettings.scala deleted file mode 100644 index a4d45fb3f..000000000 --- a/modules/lm-coursier/src/main/scala/coursier/lmcoursier/CoursierModuleSettings.scala +++ /dev/null @@ -1,5 +0,0 @@ -package coursier.lmcoursier - -import sbt.librarymanagement.ModuleSettings - -case class CoursierModuleSettings() extends ModuleSettings diff --git a/modules/lm-coursier/src/main/scala/coursier/lmcoursier/Resolvers.scala b/modules/lm-coursier/src/main/scala/coursier/lmcoursier/Resolvers.scala deleted file mode 100644 index ff65c2688..000000000 --- a/modules/lm-coursier/src/main/scala/coursier/lmcoursier/Resolvers.scala +++ /dev/null @@ -1,51 +0,0 @@ -package coursier.lmcoursier - -import sbt.librarymanagement.{ MavenRepository, Resolver, URLRepository } - -object Resolvers { - - private val slowReposBase = Seq( - "https://repo.typesafe.com/", - "https://repo.scala-sbt.org/", - "http://repo.typesafe.com/", - "http://repo.scala-sbt.org/" - ) - - private val fastReposBase = Seq( - "http://repo1.maven.org/", - "https://repo1.maven.org/" - ) - - private def url(res: Resolver): Option[String] = - res match { - case m: MavenRepository => - Some(m.root) - case u: URLRepository => - u.patterns.artifactPatterns.headOption - .orElse(u.patterns.ivyPatterns.headOption) - case _ => - None - } - - private def filterResolvers(bases: Seq[String], - resolvers: Seq[(Resolver, Option[String])]): Seq[Resolver] = - resolvers - .filter(tuple => tuple._2.exists(url => bases.exists(base => url.startsWith(base)))) - .map(_._1) - - def reorder(resolvers: Seq[Resolver]): Seq[Resolver] = { - - val byUrl = resolvers.map(r => (r, url(r))) - - val fast = filterResolvers(fastReposBase, byUrl) - val slow = filterResolvers(slowReposBase, byUrl) - val rest = resolvers.diff(fast).diff(slow) - - val reordered = fast ++ rest ++ slow - assert(reordered.size == resolvers.size, - "Reordered resolvers should be the same size as the unordered ones.") - - reordered - } - -} diff --git a/modules/lm-coursier/src/main/scala/lmcoursier/CoursierConfiguration.scala b/modules/lm-coursier/src/main/scala/lmcoursier/CoursierConfiguration.scala new file mode 100644 index 000000000..c7a08440c --- /dev/null +++ b/modules/lm-coursier/src/main/scala/lmcoursier/CoursierConfiguration.scala @@ -0,0 +1,131 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package lmcoursier +final class CoursierConfiguration private ( + val log: Option[xsbti.Logger], + val resolvers: Vector[sbt.librarymanagement.Resolver], + val parallelDownloads: Int, + val maxIterations: Int, + val sbtScalaOrganization: Option[String], + val sbtScalaVersion: Option[String], + val sbtScalaJars: Vector[java.io.File], + val interProjectDependencies: Vector[lmcoursier.definitions.Project], + val excludeDependencies: Vector[(String, String)], + val fallbackDependencies: Vector[lmcoursier.FallbackDependency], + val autoScalaLibrary: Boolean, + val hasClassifiers: Boolean, + val classifiers: Vector[String], + val mavenProfiles: Vector[String], + val scalaOrganization: Option[String], + val scalaVersion: Option[String], + val authenticationByRepositoryId: Vector[(String, lmcoursier.definitions.Authentication)], + val credentials: Seq[lmcoursier.credentials.Credentials], + val logger: Option[lmcoursier.definitions.CacheLogger], + val cache: Option[java.io.File]) extends Serializable { + + private def this() = this(None, sbt.librarymanagement.Resolver.defaults, 6, 100, None, None, Vector.empty, Vector.empty, Vector.empty, Vector.empty, true, false, Vector.empty, Vector.empty, None, None, Vector.empty, Vector.empty, None, None) + + override def equals(o: Any): Boolean = o match { + case x: CoursierConfiguration => (this.log == x.log) && (this.resolvers == x.resolvers) && (this.parallelDownloads == x.parallelDownloads) && (this.maxIterations == x.maxIterations) && (this.sbtScalaOrganization == x.sbtScalaOrganization) && (this.sbtScalaVersion == x.sbtScalaVersion) && (this.sbtScalaJars == x.sbtScalaJars) && (this.interProjectDependencies == x.interProjectDependencies) && (this.excludeDependencies == x.excludeDependencies) && (this.fallbackDependencies == x.fallbackDependencies) && (this.autoScalaLibrary == x.autoScalaLibrary) && (this.hasClassifiers == x.hasClassifiers) && (this.classifiers == x.classifiers) && (this.mavenProfiles == x.mavenProfiles) && (this.scalaOrganization == x.scalaOrganization) && (this.scalaVersion == x.scalaVersion) && (this.authenticationByRepositoryId == x.authenticationByRepositoryId) && (this.credentials == x.credentials) && (this.logger == x.logger) && (this.cache == x.cache) + case _ => false + } + override def hashCode: Int = { + 37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (17 + "lmcoursier.CoursierConfiguration".##) + log.##) + resolvers.##) + parallelDownloads.##) + maxIterations.##) + sbtScalaOrganization.##) + sbtScalaVersion.##) + sbtScalaJars.##) + interProjectDependencies.##) + excludeDependencies.##) + fallbackDependencies.##) + autoScalaLibrary.##) + hasClassifiers.##) + classifiers.##) + mavenProfiles.##) + scalaOrganization.##) + scalaVersion.##) + authenticationByRepositoryId.##) + credentials.##) + logger.##) + cache.##) + } + override def toString: String = { + "CoursierConfiguration(" + log + ", " + resolvers + ", " + parallelDownloads + ", " + maxIterations + ", " + sbtScalaOrganization + ", " + sbtScalaVersion + ", " + sbtScalaJars + ", " + interProjectDependencies + ", " + excludeDependencies + ", " + fallbackDependencies + ", " + autoScalaLibrary + ", " + hasClassifiers + ", " + classifiers + ", " + mavenProfiles + ", " + scalaOrganization + ", " + scalaVersion + ", " + authenticationByRepositoryId + ", " + credentials + ", " + logger + ", " + cache + ")" + } + private[this] def copy(log: Option[xsbti.Logger] = log, resolvers: Vector[sbt.librarymanagement.Resolver] = resolvers, parallelDownloads: Int = parallelDownloads, maxIterations: Int = maxIterations, sbtScalaOrganization: Option[String] = sbtScalaOrganization, sbtScalaVersion: Option[String] = sbtScalaVersion, sbtScalaJars: Vector[java.io.File] = sbtScalaJars, interProjectDependencies: Vector[lmcoursier.definitions.Project] = interProjectDependencies, excludeDependencies: Vector[(String, String)] = excludeDependencies, fallbackDependencies: Vector[lmcoursier.FallbackDependency] = fallbackDependencies, autoScalaLibrary: Boolean = autoScalaLibrary, hasClassifiers: Boolean = hasClassifiers, classifiers: Vector[String] = classifiers, mavenProfiles: Vector[String] = mavenProfiles, scalaOrganization: Option[String] = scalaOrganization, scalaVersion: Option[String] = scalaVersion, authenticationByRepositoryId: Vector[(String, lmcoursier.definitions.Authentication)] = authenticationByRepositoryId, credentials: Seq[lmcoursier.credentials.Credentials] = credentials, logger: Option[lmcoursier.definitions.CacheLogger] = logger, cache: Option[java.io.File] = cache): CoursierConfiguration = { + new CoursierConfiguration(log, resolvers, parallelDownloads, maxIterations, sbtScalaOrganization, sbtScalaVersion, sbtScalaJars, interProjectDependencies, excludeDependencies, fallbackDependencies, autoScalaLibrary, hasClassifiers, classifiers, mavenProfiles, scalaOrganization, scalaVersion, authenticationByRepositoryId, credentials, logger, cache) + } + def withLog(log: Option[xsbti.Logger]): CoursierConfiguration = { + copy(log = log) + } + def withLog(log: xsbti.Logger): CoursierConfiguration = { + copy(log = Option(log)) + } + def withResolvers(resolvers: Vector[sbt.librarymanagement.Resolver]): CoursierConfiguration = { + copy(resolvers = resolvers) + } + def withParallelDownloads(parallelDownloads: Int): CoursierConfiguration = { + copy(parallelDownloads = parallelDownloads) + } + def withMaxIterations(maxIterations: Int): CoursierConfiguration = { + copy(maxIterations = maxIterations) + } + def withSbtScalaOrganization(sbtScalaOrganization: Option[String]): CoursierConfiguration = { + copy(sbtScalaOrganization = sbtScalaOrganization) + } + def withSbtScalaOrganization(sbtScalaOrganization: String): CoursierConfiguration = { + copy(sbtScalaOrganization = Option(sbtScalaOrganization)) + } + def withSbtScalaVersion(sbtScalaVersion: Option[String]): CoursierConfiguration = { + copy(sbtScalaVersion = sbtScalaVersion) + } + def withSbtScalaVersion(sbtScalaVersion: String): CoursierConfiguration = { + copy(sbtScalaVersion = Option(sbtScalaVersion)) + } + def withSbtScalaJars(sbtScalaJars: Vector[java.io.File]): CoursierConfiguration = { + copy(sbtScalaJars = sbtScalaJars) + } + def withInterProjectDependencies(interProjectDependencies: Vector[lmcoursier.definitions.Project]): CoursierConfiguration = { + copy(interProjectDependencies = interProjectDependencies) + } + def withExcludeDependencies(excludeDependencies: Vector[(String, String)]): CoursierConfiguration = { + copy(excludeDependencies = excludeDependencies) + } + def withFallbackDependencies(fallbackDependencies: Vector[lmcoursier.FallbackDependency]): CoursierConfiguration = { + copy(fallbackDependencies = fallbackDependencies) + } + def withAutoScalaLibrary(autoScalaLibrary: Boolean): CoursierConfiguration = { + copy(autoScalaLibrary = autoScalaLibrary) + } + def withHasClassifiers(hasClassifiers: Boolean): CoursierConfiguration = { + copy(hasClassifiers = hasClassifiers) + } + def withClassifiers(classifiers: Vector[String]): CoursierConfiguration = { + copy(classifiers = classifiers) + } + def withMavenProfiles(mavenProfiles: Vector[String]): CoursierConfiguration = { + copy(mavenProfiles = mavenProfiles) + } + def withScalaOrganization(scalaOrganization: Option[String]): CoursierConfiguration = { + copy(scalaOrganization = scalaOrganization) + } + def withScalaOrganization(scalaOrganization: String): CoursierConfiguration = { + copy(scalaOrganization = Option(scalaOrganization)) + } + def withScalaVersion(scalaVersion: Option[String]): CoursierConfiguration = { + copy(scalaVersion = scalaVersion) + } + def withScalaVersion(scalaVersion: String): CoursierConfiguration = { + copy(scalaVersion = Option(scalaVersion)) + } + def withAuthenticationByRepositoryId(authenticationByRepositoryId: Vector[(String, lmcoursier.definitions.Authentication)]): CoursierConfiguration = { + copy(authenticationByRepositoryId = authenticationByRepositoryId) + } + def withCredentials(credentials: Seq[lmcoursier.credentials.Credentials]): CoursierConfiguration = { + copy(credentials = credentials) + } + def withLogger(logger: Option[lmcoursier.definitions.CacheLogger]): CoursierConfiguration = { + copy(logger = logger) + } + def withLogger(logger: lmcoursier.definitions.CacheLogger): CoursierConfiguration = { + copy(logger = Option(logger)) + } + def withCache(cache: Option[java.io.File]): CoursierConfiguration = { + copy(cache = cache) + } + def withCache(cache: java.io.File): CoursierConfiguration = { + copy(cache = Option(cache)) + } +} +object CoursierConfiguration { + + def apply(): CoursierConfiguration = new CoursierConfiguration() + def apply(log: Option[xsbti.Logger], resolvers: Vector[sbt.librarymanagement.Resolver], parallelDownloads: Int, maxIterations: Int, sbtScalaOrganization: Option[String], sbtScalaVersion: Option[String], sbtScalaJars: Vector[java.io.File], interProjectDependencies: Vector[lmcoursier.definitions.Project], excludeDependencies: Vector[(String, String)], fallbackDependencies: Vector[lmcoursier.FallbackDependency], autoScalaLibrary: Boolean, hasClassifiers: Boolean, classifiers: Vector[String], mavenProfiles: Vector[String], scalaOrganization: Option[String], scalaVersion: Option[String], authenticationByRepositoryId: Vector[(String, lmcoursier.definitions.Authentication)], credentials: Seq[lmcoursier.credentials.Credentials], logger: Option[lmcoursier.definitions.CacheLogger], cache: Option[java.io.File]): CoursierConfiguration = new CoursierConfiguration(log, resolvers, parallelDownloads, maxIterations, sbtScalaOrganization, sbtScalaVersion, sbtScalaJars, interProjectDependencies, excludeDependencies, fallbackDependencies, autoScalaLibrary, hasClassifiers, classifiers, mavenProfiles, scalaOrganization, scalaVersion, authenticationByRepositoryId, credentials, logger, cache) + def apply(log: xsbti.Logger, resolvers: Vector[sbt.librarymanagement.Resolver], parallelDownloads: Int, maxIterations: Int, sbtScalaOrganization: String, sbtScalaVersion: String, sbtScalaJars: Vector[java.io.File], interProjectDependencies: Vector[lmcoursier.definitions.Project], excludeDependencies: Vector[(String, String)], fallbackDependencies: Vector[lmcoursier.FallbackDependency], autoScalaLibrary: Boolean, hasClassifiers: Boolean, classifiers: Vector[String], mavenProfiles: Vector[String], scalaOrganization: String, scalaVersion: String, authenticationByRepositoryId: Vector[(String, lmcoursier.definitions.Authentication)], credentials: Seq[lmcoursier.credentials.Credentials], logger: lmcoursier.definitions.CacheLogger, cache: java.io.File): CoursierConfiguration = new CoursierConfiguration(Option(log), resolvers, parallelDownloads, maxIterations, Option(sbtScalaOrganization), Option(sbtScalaVersion), sbtScalaJars, interProjectDependencies, excludeDependencies, fallbackDependencies, autoScalaLibrary, hasClassifiers, classifiers, mavenProfiles, Option(scalaOrganization), Option(scalaVersion), authenticationByRepositoryId, credentials, Option(logger), Option(cache)) +} diff --git a/modules/lm-coursier/src/main/scala/coursier/lmcoursier/CoursierDependencyResolution.scala b/modules/lm-coursier/src/main/scala/lmcoursier/CoursierDependencyResolution.scala similarity index 85% rename from modules/lm-coursier/src/main/scala/coursier/lmcoursier/CoursierDependencyResolution.scala rename to modules/lm-coursier/src/main/scala/lmcoursier/CoursierDependencyResolution.scala index 6835bf97b..b8a327682 100644 --- a/modules/lm-coursier/src/main/scala/coursier/lmcoursier/CoursierDependencyResolution.scala +++ b/modules/lm-coursier/src/main/scala/lmcoursier/CoursierDependencyResolution.scala @@ -1,11 +1,13 @@ -package coursier.lmcoursier +package lmcoursier import java.io.File import _root_.coursier.{Artifact, Organization, Resolution, organizationString} -import _root_.coursier.core.{Classifier, Configuration, ModuleName} -import coursier.cache.{CacheDefaults, FileCache} +import _root_.coursier.core.{Classifier, Configuration} +import coursier.cache.CacheDefaults import coursier.internal.Typelevel +import lmcoursier.definitions.ToCoursier +import lmcoursier.internal.{ArtifactsParams, ArtifactsRun, CoursierModuleDescriptor, InterProjectRepository, ResolutionParams, ResolutionRun, Resolvers, SbtBootJars, UpdateParams, UpdateRun} import sbt.internal.librarymanagement.IvySbt import sbt.librarymanagement._ import sbt.util.Logger @@ -18,21 +20,15 @@ class CoursierDependencyResolution(conf: CoursierConfiguration) extends Dependen * sbt-coursier, that was moved to this module. */ - lazy val resolvers = - if (conf.reorderResolvers) - ResolutionParams.reorderResolvers(conf.resolvers) - else - conf.resolvers - private lazy val excludeDependencies = conf .excludeDependencies .map { case (strOrg, strName) => - (Organization(strOrg), ModuleName(strName)) + (lmcoursier.definitions.Organization(strOrg), lmcoursier.definitions.ModuleName(strName)) } .toSet - def moduleDescriptor(moduleSetting: ModuleDescriptorConfiguration): CoursierModuleDescriptor = + def moduleDescriptor(moduleSetting: ModuleDescriptorConfiguration): ModuleDescriptor = CoursierModuleDescriptor(moduleSetting, conf) def update( @@ -72,7 +68,7 @@ class CoursierDependencyResolution(conf: CoursierConfiguration) extends Dependen val verbosityLevel = 0 val ttl = CacheDefaults.ttl - val loggerOpt = conf.logger + val loggerOpt = conf.logger.map(ToCoursier.cacheLogger) val cache = conf.cache.getOrElse(CacheDefaults.location) val cachePolicies = CacheDefaults.cachePolicies val checksums = CacheDefaults.checksums @@ -88,17 +84,18 @@ class CoursierDependencyResolution(conf: CoursierConfiguration) extends Dependen val authenticationByRepositoryId = conf.authenticationByRepositoryId.toMap - val mainRepositories = resolvers + val mainRepositories = conf + .resolvers .flatMap { resolver => - FromSbt.repository( + Resolvers.repository( resolver, ivyProperties, log, - authenticationByRepositoryId.get(resolver.name) + authenticationByRepositoryId.get(resolver.name).map(ToCoursier.authentication) ) } - val interProjectRepo = InterProjectRepository(conf.interProjectDependencies) + val interProjectRepo = InterProjectRepository(conf.interProjectDependencies.map(ToCoursier.project)) val dependencies = module0 .dependencies @@ -112,12 +109,12 @@ class CoursierDependencyResolution(conf: CoursierConfiguration) extends Dependen val dep0 = dep.copy( exclusions = dep.exclusions ++ excludeDependencies ) - (config, dep0) + (ToCoursier.configuration(config), ToCoursier.dependency(dep0)) } val configGraphs = Inputs.ivyGraphs( Inputs.configExtends(module0.configurations) - ) + ).map(_.map(ToCoursier.configuration)) val typelevel = so == Typelevel.typelevelOrg @@ -126,7 +123,7 @@ class CoursierDependencyResolution(conf: CoursierConfiguration) extends Dependen .withCachePolicies(cachePolicies) .withTtl(ttl) .withChecksums(checksums) - .withCredentials(conf.credentials) + .withCredentials(conf.credentials.map(ToCoursier.credentials)) val resolutionParams = ResolutionParams( dependencies = dependencies, @@ -135,7 +132,7 @@ class CoursierDependencyResolution(conf: CoursierConfiguration) extends Dependen autoScalaLibOpt = if (conf.autoScalaLibrary) Some((so, sv)) else None, mainRepositories = mainRepositories, parentProjectCache = Map.empty, - interProjectDependencies = conf.interProjectDependencies, + interProjectDependencies = conf.interProjectDependencies.map(ToCoursier.project), internalRepositories = Seq(interProjectRepo), sbtClassifiers = false, projectName = projectName, @@ -149,7 +146,7 @@ class CoursierDependencyResolution(conf: CoursierConfiguration) extends Dependen .withTypelevel(typelevel) ) - def artifactsParams(resolutions: Map[Set[Configuration], Resolution]) = + def artifactsParams(resolutions: Map[Set[Configuration], Resolution]): ArtifactsParams = ArtifactsParams( classifiers = classifiers, resolutions = resolutions.values.toSeq, @@ -167,7 +164,10 @@ class CoursierDependencyResolution(conf: CoursierConfiguration) extends Dependen conf.sbtScalaJars ) - val configs = Inputs.coursierConfigurations(module0.configurations) + val configs = Inputs.coursierConfigurations(module0.configurations).map { + case (k, l) => + ToCoursier.configuration(k) -> l.map(ToCoursier.configuration) + } def updateParams( resolutions: Map[Set[Configuration], Resolution], @@ -239,4 +239,7 @@ class CoursierDependencyResolution(conf: CoursierConfiguration) extends Dependen object CoursierDependencyResolution { def apply(configuration: CoursierConfiguration): DependencyResolution = DependencyResolution(new CoursierDependencyResolution(configuration)) + + def defaultCacheLocation: File = + CacheDefaults.location } diff --git a/modules/lm-coursier/src/main/scala/coursier/lmcoursier/FallbackDependency.scala b/modules/lm-coursier/src/main/scala/lmcoursier/FallbackDependency.scala similarity index 76% rename from modules/lm-coursier/src/main/scala/coursier/lmcoursier/FallbackDependency.scala rename to modules/lm-coursier/src/main/scala/lmcoursier/FallbackDependency.scala index 5e9476cd6..8247c7f59 100644 --- a/modules/lm-coursier/src/main/scala/coursier/lmcoursier/FallbackDependency.scala +++ b/modules/lm-coursier/src/main/scala/lmcoursier/FallbackDependency.scala @@ -1,8 +1,8 @@ -package coursier.lmcoursier +package lmcoursier import java.net.URL -import coursier.core.Module +import lmcoursier.definitions.Module // FIXME Handle that via the contraband thing? final case class FallbackDependency( diff --git a/modules/lm-coursier/src/main/scala/lmcoursier/FromSbt.scala b/modules/lm-coursier/src/main/scala/lmcoursier/FromSbt.scala new file mode 100644 index 000000000..e1d465dcc --- /dev/null +++ b/modules/lm-coursier/src/main/scala/lmcoursier/FromSbt.scala @@ -0,0 +1,146 @@ +package lmcoursier + +import coursier.ivy.IvyXml.{mappings => ivyXmlMappings} + +import lmcoursier.definitions.{Attributes, Classifier, Configuration, Dependency, Info, Module, ModuleName, Organization, Project, Type} +import sbt.internal.librarymanagement.mavenint.SbtPomExtraProperties +import sbt.librarymanagement.{Configuration => _, MavenRepository => _, _} + +object FromSbt { + + private def sbtModuleIdName( + moduleId: ModuleID, + scalaVersion: => String, + scalaBinaryVersion: => String, + optionalCrossVer: Boolean = false + ): String = { + val name0 = moduleId.name + val updatedName = CrossVersion(moduleId.crossVersion, scalaVersion, scalaBinaryVersion) + .fold(name0)(_(name0)) + if (!optionalCrossVer || updatedName.length <= name0.length) + updatedName + else { + val suffix = updatedName.substring(name0.length) + if (name0.endsWith(suffix)) + name0 + else + updatedName + } + } + + private def attributes(attr: Map[String, String]): Map[String, String] = + attr.map { case (k, v) => + k.stripPrefix("e:") -> v + }.filter { case (k, _) => + !k.startsWith(SbtPomExtraProperties.POM_INFO_KEY_PREFIX) + } + + private def moduleVersion( + module: ModuleID, + scalaVersion: String, + scalaBinaryVersion: String, + optionalCrossVer: Boolean + ): (Module, String) = { + + val fullName = sbtModuleIdName(module, scalaVersion, scalaBinaryVersion, optionalCrossVer) + + val module0 = Module(Organization(module.organization), ModuleName(fullName), attributes(module.extraDependencyAttributes)) + val version = module.revision + + (module0, version) + } + + def moduleVersion( + module: ModuleID, + scalaVersion: String, + scalaBinaryVersion: String + ): (Module, String) = + moduleVersion(module, scalaVersion, scalaBinaryVersion, optionalCrossVer = false) + + def dependencies( + module: ModuleID, + scalaVersion: String, + scalaBinaryVersion: String, + optionalCrossVer: Boolean = false + ): Seq[(Configuration, Dependency)] = { + + // TODO Warn about unsupported properties in `module` + + val (module0, version) = moduleVersion(module, scalaVersion, scalaBinaryVersion, optionalCrossVer) + + val dep = Dependency( + module0, + version, + Configuration(""), + exclusions = module.exclusions.map { rule => + // FIXME Other `rule` fields are ignored here + (Organization(rule.organization), ModuleName(rule.name)) + }.toSet, + Attributes(Type(""), Classifier("")), + optional = false, + transitive = module.isTransitive + ) + + val mapping = module.configurations.getOrElse("compile") + val allMappings = ivyXmlMappings(mapping).map { + case (from, to) => + (Configuration(from.value), Configuration(to.value)) + } + + val attributes = + if (module.explicitArtifacts.isEmpty) + Seq(Attributes(Type(""), Classifier(""))) + else + module.explicitArtifacts.map { a => + Attributes( + `type` = Type(a.`type`), + classifier = a.classifier.fold(Classifier(""))(Classifier(_)) + ) + } + + for { + (from, to) <- allMappings + attr <- attributes + } yield from -> dep.copy(configuration = to, attributes = attr) + } + + def fallbackDependencies( + allDependencies: Seq[ModuleID], + scalaVersion: String, + scalaBinaryVersion: String + ): Seq[FallbackDependency] = + for { + module <- allDependencies + artifact <- module.explicitArtifacts + url <- artifact.url.toSeq + } yield { + val (module0, version) = moduleVersion(module, scalaVersion, scalaBinaryVersion) + FallbackDependency(module0, version, url, module.isChanging) + } + + def project( + projectID: ModuleID, + allDependencies: Seq[ModuleID], + ivyConfigurations: Map[Configuration, Seq[Configuration]], + scalaVersion: String, + scalaBinaryVersion: String + ): Project = { + + val deps = allDependencies.flatMap(dependencies(_, scalaVersion, scalaBinaryVersion)) + + Project( + Module( + Organization(projectID.organization), + ModuleName(sbtModuleIdName(projectID, scalaVersion, scalaBinaryVersion)), + attributes(projectID.extraDependencyAttributes) + ), + projectID.revision, + deps, + ivyConfigurations, + Nil, + None, + Nil, + Info("", "", Nil, Nil, None) + ) + } +} diff --git a/modules/lm-coursier/src/main/scala/coursier/lmcoursier/Inputs.scala b/modules/lm-coursier/src/main/scala/lmcoursier/Inputs.scala similarity index 55% rename from modules/lm-coursier/src/main/scala/coursier/lmcoursier/Inputs.scala rename to modules/lm-coursier/src/main/scala/lmcoursier/Inputs.scala index c2853737b..32c3af41a 100644 --- a/modules/lm-coursier/src/main/scala/coursier/lmcoursier/Inputs.scala +++ b/modules/lm-coursier/src/main/scala/lmcoursier/Inputs.scala @@ -1,17 +1,20 @@ -package coursier.lmcoursier +package lmcoursier -import coursier.cache.CacheUrl -import coursier.core._ -import coursier.ivy.IvyRepository -import coursier.maven.MavenRepository -import sbt.librarymanagement.{InclExclRule, ModuleID} +import coursier.ivy.IvyXml.{mappings => initialIvyXmlMappings} +import lmcoursier.definitions.{Configuration, ModuleName, Organization} +import sbt.librarymanagement.{CrossVersion, InclExclRule} import sbt.util.Logger import scala.collection.mutable -import scala.util.Try object Inputs { + def ivyXmlMappings(mapping: String): Seq[(Configuration, Configuration)] = + initialIvyXmlMappings(mapping).map { + case (from, to) => + Configuration(from.value) -> Configuration(to.value) + } + def configExtends(configurations: Seq[sbt.librarymanagement.Configuration]): Map[Configuration, Seq[Configuration]] = configurations .map(cfg => Configuration(cfg.name) -> cfg.extendsConfigs.map(c => Configuration(c.name))) @@ -22,7 +25,7 @@ object Inputs { shadedConfig: Option[(String, Configuration)] = None ): Map[Configuration, Set[Configuration]] = { - val configs0 = Inputs.configExtends(configurations) + val configs0 = configExtends(configurations) def allExtends(c: Configuration) = { // possibly bad complexity @@ -43,11 +46,11 @@ object Inputs { } map ++ shadedConfig.toSeq.flatMap { - case (baseConfig, shadedConfig) => + case (baseConfig, shadedConfig0) => val baseConfig0 = Configuration(baseConfig) Seq( - baseConfig0 -> (map.getOrElse(baseConfig0, Set(baseConfig0)) + shadedConfig), - shadedConfig -> map.getOrElse(shadedConfig, Set(shadedConfig)) + baseConfig0 -> (map.getOrElse(baseConfig0, Set(baseConfig0)) + shadedConfig0), + shadedConfig0 -> map.getOrElse(shadedConfig0, Set(shadedConfig0)) ) } } @@ -107,10 +110,11 @@ object Inputs { log.warn(s"Unsupported exclusion rule $rule") anyNonSupportedExclusionRule = true Nil - } else - Seq( - (Organization(rule.organization), ModuleName(FromSbt.sbtCrossVersionName(rule.name, rule.crossVersion, sv, sbv))) - ) + } else { + val name = CrossVersion(rule.crossVersion, sv, sbv) + .fold(rule.name)(_(rule.name)) + Seq((Organization(rule.organization), ModuleName(name))) + } } .toSet @@ -120,67 +124,4 @@ object Inputs { res } - def coursierProject( - projId: ModuleID, - dependencies: Seq[ModuleID], - excludeDeps: Seq[InclExclRule], - configurations: Seq[sbt.librarymanagement.Configuration], - sv: String, - sbv: String, - log: Logger - ): Project = { - - val exclusions0 = exclusions(excludeDeps, sv, sbv, log) - - val configMap = configExtends(configurations) - - val proj = FromSbt.project( - projId, - dependencies, - configMap, - sv, - sbv - ) - - proj.copy( - dependencies = proj.dependencies.map { - case (config, dep) => - (config, dep.copy(exclusions = dep.exclusions ++ exclusions0)) - } - ) - } - - def withAuthenticationByHost(repo: Repository, credentials: Map[String, Authentication]): Repository = { - - def httpHost(s: String) = - if (s.startsWith("http://") || s.startsWith("https://")) - Try(CacheUrl.url(s).getHost).toOption - else - None - - repo match { - case m: MavenRepository => - if (m.authentication.isEmpty) - httpHost(m.root).flatMap(credentials.get).fold(m) { auth => - m.copy(authentication = Some(auth)) - } - else - m - case i: IvyRepository => - if (i.authentication.isEmpty) { - val base = i.pattern.chunks.takeWhile { - case _: coursier.ivy.Pattern.Chunk.Const => true - case _ => false - }.map(_.string).mkString - - httpHost(base).flatMap(credentials.get).fold(i) { auth => - i.copy(authentication = Some(auth)) - } - } else - i - case _ => - repo - } - } - } diff --git a/modules/lm-coursier/src/main/scala/lmcoursier/credentials/Credentials.scala b/modules/lm-coursier/src/main/scala/lmcoursier/credentials/Credentials.scala new file mode 100644 index 000000000..47df861d8 --- /dev/null +++ b/modules/lm-coursier/src/main/scala/lmcoursier/credentials/Credentials.scala @@ -0,0 +1,23 @@ +package lmcoursier.credentials + +import java.io.File + +abstract class Credentials extends Serializable { + // calling this may incur I/O + def get(): Seq[DirectCredentials] +} + +object Credentials { + + def apply(): DirectCredentials = DirectCredentials() + def apply(host: String, username: String, password: String): DirectCredentials = DirectCredentials(host, username, password) + def apply(host: String, username: String, password: String, realm: Option[String]): DirectCredentials = DirectCredentials(host, username, password, realm) + def apply(host: String, username: String, password: String, realm: String): DirectCredentials = DirectCredentials(host, username, password, Option(realm)) + def apply(host: String, username: String, password: String, realm: Option[String], optional: Boolean): DirectCredentials = DirectCredentials(host, username, password, realm, optional) + def apply(host: String, username: String, password: String, realm: String, optional: Boolean): DirectCredentials = DirectCredentials(host, username, password, Option(realm), optional) + + def apply(f: File): FileCredentials = + FileCredentials(f.getAbsolutePath) + def apply(f: File, optional: Boolean): FileCredentials = + FileCredentials(f.getAbsolutePath, optional) +} diff --git a/modules/lm-coursier/src/main/scala/lmcoursier/credentials/DirectCredentials.scala b/modules/lm-coursier/src/main/scala/lmcoursier/credentials/DirectCredentials.scala new file mode 100644 index 000000000..916b340a5 --- /dev/null +++ b/modules/lm-coursier/src/main/scala/lmcoursier/credentials/DirectCredentials.scala @@ -0,0 +1,100 @@ +package lmcoursier.credentials + +import java.net.URI + +import coursier.core.Authentication + +final class DirectCredentials private( + val host: String, + val username: String, + val password: String, + val realm: Option[String], + val optional: Boolean, + val matchHost: Boolean, + val httpsOnly: Boolean +) extends Credentials { + + private def this() = this("", "", "", None, true, false, true) + private def this(host: String, username: String, password: String) = this(host, username, password, None, true, false, true) + private def this(host: String, username: String, password: String, realm: Option[String]) = this(host, username, password, realm, true, false, true) + private def this(host: String, username: String, password: String, realm: Option[String], optional: Boolean) = this(host, username, password, realm, optional, false, true) + + override def equals(o: Any): Boolean = o match { + case x: DirectCredentials => (this.host == x.host) && (this.username == x.username) && (this.password == x.password) && (this.realm == x.realm) && (this.optional == x.optional) && (this.matchHost == x.matchHost) && (this.httpsOnly == x.httpsOnly) + case _ => false + } + override def hashCode: Int = { + 37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (17 + "lmcoursier.credentials.DirectCredentials".##) + host.##) + username.##) + password.##) + realm.##) + optional.##) + matchHost.##) + httpsOnly.##) + } + override def toString: String = { + "Credentials(" + host + ", " + username + ", " + "****" + ", " + realm + ", " + optional + ", " + matchHost + ", " + httpsOnly + ")" + } + private[this] def copy(host: String = host, username: String = username, password: String = password, realm: Option[String] = realm, optional: Boolean = optional, matchHost: Boolean = matchHost, httpsOnly: Boolean = httpsOnly): DirectCredentials = { + new DirectCredentials(host, username, password, realm, optional, matchHost, httpsOnly) + } + def withHost(host: String): DirectCredentials = { + copy(host = host) + } + def withUsername(username: String): DirectCredentials = { + copy(username = username) + } + def withPassword(password: String): DirectCredentials = { + copy(password = password) + } + def withRealm(realm: Option[String]): DirectCredentials = { + copy(realm = realm) + } + def withRealm(realm: String): DirectCredentials = { + copy(realm = Option(realm)) + } + def withOptional(optional: Boolean): DirectCredentials = { + copy(optional = optional) + } + def withMatchHost(matchHost: Boolean): DirectCredentials = + copy(matchHost = matchHost) + def withHttpsOnly(httpsOnly: Boolean): DirectCredentials = + copy(httpsOnly = httpsOnly) + + def autoMatches(url: String, realm0: Option[String]): Boolean = + matchHost && { + val uri = new URI(url) + val schemeOpt = Option(uri.getScheme) + val hostOpt = Option(uri.getHost) + ((schemeOpt.contains("http") && !httpsOnly) || schemeOpt.contains("https")) && + hostOpt.contains(host) && + realm.forall(realm0.contains) + } + + def matches(url: String, user: String): Boolean = { + val uri = new URI(url) + val schemeOpt = Option(uri.getScheme) + val hostOpt = Option(uri.getHost) + val userInfoOpt = Option(uri.getUserInfo) + // !matchHost && // ? + userInfoOpt.isEmpty && + ((schemeOpt.contains("http") && !httpsOnly) || schemeOpt.contains("https")) && + hostOpt.contains(host) && + user == username + } + + def authentication: Authentication = + Authentication( + username, + password, + realmOpt = realm, + optional = optional + ) + + def get(): Seq[DirectCredentials] = + Seq(this) + +} +object DirectCredentials { + + def apply(): DirectCredentials = new DirectCredentials() + def apply(host: String, username: String, password: String): DirectCredentials = new DirectCredentials(host, username, password) + def apply(host: String, username: String, password: String, realm: Option[String]): DirectCredentials = new DirectCredentials(host, username, password, realm) + def apply(host: String, username: String, password: String, realm: String): DirectCredentials = new DirectCredentials(host, username, password, Option(realm)) + def apply(host: String, username: String, password: String, realm: Option[String], optional: Boolean): DirectCredentials = new DirectCredentials(host, username, password, realm, optional) + def apply(host: String, username: String, password: String, realm: String, optional: Boolean): DirectCredentials = new DirectCredentials(host, username, password, Option(realm), optional) +} diff --git a/modules/lm-coursier/src/main/scala/lmcoursier/credentials/FileCredentials.scala b/modules/lm-coursier/src/main/scala/lmcoursier/credentials/FileCredentials.scala new file mode 100644 index 000000000..ab4d8e100 --- /dev/null +++ b/modules/lm-coursier/src/main/scala/lmcoursier/credentials/FileCredentials.scala @@ -0,0 +1,92 @@ +package lmcoursier.credentials + +import java.io.{File, FileInputStream} +import java.util.Properties + +import scala.collection.JavaConverters._ + +final class FileCredentials private( + val path: String, + val optional: Boolean +) extends Credentials { + + private def this(path: String) = this(path, true) + + override def equals(o: Any): Boolean = o match { + case x: FileCredentials => (this.path == x.path) && (this.optional == x.optional) + case _ => false + } + override def hashCode: Int = { + 37 * (37 * (37 * (17 + "lmcoursier.credentials.CredentialFile".##) + path.##) + optional.##) + } + override def toString: String = { + "CredentialFile(" + path + ", " + optional + ")" + } + private[this] def copy(path: String = path, optional: Boolean = optional): FileCredentials = { + new FileCredentials(path, optional) + } + def withPath(path: String): FileCredentials = { + copy(path = path) + } + def withOptional(optional: Boolean): FileCredentials = { + copy(optional = optional) + } + + def get(): Seq[DirectCredentials] = { + + val f = new File(path) + + if (f.isFile) { + + val props = new Properties + + var fis: FileInputStream = null + try { + fis = new FileInputStream(f) + props.load(fis) + } finally { + if (fis != null) + fis.close() + } + + val userProps = props + .propertyNames() + .asScala + .map(_.asInstanceOf[String]) + .filter(_.endsWith(".username")) + .toVector + + userProps.map { userProp => + val prefix = userProp.stripSuffix(".username") + + val user = props.getProperty(userProp) + val password = Option(props.getProperty(s"$prefix.password")).getOrElse { + throw new Exception(s"Property $prefix.password not found in $path") + } + + val host = Option(props.getProperty(s"$prefix.host")).getOrElse { + throw new Exception(s"Property $prefix.host not found in $path") + } + + val realmOpt = Option(props.getProperty(s"$prefix.realm")) // filter if empty? + + val matchHost = Option(props.getProperty(s"$prefix.auto")).fold(false)(_.toBoolean) + val httpsOnly = Option(props.getProperty(s"$prefix.https-only")).fold(true)(_.toBoolean) + + DirectCredentials(host, user, password) + .withRealm(realmOpt) + .withMatchHost(matchHost) + .withHttpsOnly(httpsOnly) + } + + } else if (optional) + Nil + else + throw new Exception(s"Credential file $path not found") + } +} +object FileCredentials { + + def apply(path: String): FileCredentials = new FileCredentials(path) + def apply(path: String, optional: Boolean): FileCredentials = new FileCredentials(path, optional) +} diff --git a/modules/lm-coursier/src/main/scala/lmcoursier/definitions/Attributes.scala b/modules/lm-coursier/src/main/scala/lmcoursier/definitions/Attributes.scala new file mode 100644 index 000000000..2daf0c1d1 --- /dev/null +++ b/modules/lm-coursier/src/main/scala/lmcoursier/definitions/Attributes.scala @@ -0,0 +1,35 @@ +package lmcoursier.definitions + +final class Attributes private ( + val `type`: Type, + val classifier: Classifier +) { + + override def equals(obj: Any): Boolean = + obj match { + case other: Attributes => + `type` == other.`type` && classifier == other.classifier + case _ => false + } + override def hashCode(): Int = + 37 * (37 * (37 * (17 + "lmcoursier.definitions.Attributes".##) + `type`.##) + classifier.##) + override def toString: String = + s"Attributes(${`type`}, $classifier)" + + private def copy( + `type`: Type = `type`, + classifier: Classifier = classifier + ): Attributes = + new Attributes(`type`, classifier) + + def withType(`type`: Type): Attributes = + copy(`type` = `type`) + def withClassifier(classifier: Classifier): Attributes = + copy(classifier = classifier) + +} + +object Attributes { + def apply(`type`: Type, classifier: Classifier): Attributes = + new Attributes(`type`, classifier) +} diff --git a/modules/lm-coursier/src/main/scala/lmcoursier/definitions/Authentication.scala b/modules/lm-coursier/src/main/scala/lmcoursier/definitions/Authentication.scala new file mode 100644 index 000000000..a03103abd --- /dev/null +++ b/modules/lm-coursier/src/main/scala/lmcoursier/definitions/Authentication.scala @@ -0,0 +1,11 @@ +package lmcoursier.definitions + +final case class Authentication( + user: String, + password: String, + optional: Boolean = false, + realmOpt: Option[String] = None +) { + override def toString: String = + s"Authentication($user, *******, $optional, $realmOpt)" +} diff --git a/modules/lm-coursier/src/main/scala/lmcoursier/definitions/CacheLogger.scala b/modules/lm-coursier/src/main/scala/lmcoursier/definitions/CacheLogger.scala new file mode 100644 index 000000000..8e9a5e265 --- /dev/null +++ b/modules/lm-coursier/src/main/scala/lmcoursier/definitions/CacheLogger.scala @@ -0,0 +1,29 @@ +package lmcoursier.definitions + +abstract class CacheLogger { + def foundLocally(url: String): Unit = {} + + def downloadingArtifact(url: String): Unit = {} + + def downloadProgress(url: String, downloaded: Long): Unit = {} + + def downloadedArtifact(url: String, success: Boolean): Unit = {} + def checkingUpdates(url: String, currentTimeOpt: Option[Long]): Unit = {} + def checkingUpdatesResult(url: String, currentTimeOpt: Option[Long], remoteTimeOpt: Option[Long]): Unit = {} + + def downloadLength(url: String, totalLength: Long, alreadyDownloaded: Long, watching: Boolean): Unit = {} + + def gettingLength(url: String): Unit = {} + def gettingLengthResult(url: String, length: Option[Long]): Unit = {} + + def removedCorruptFile(url: String, reason: Option[String]): Unit = {} + + // sizeHint: estimated # of artifacts to be downloaded (doesn't include side stuff like checksums) + def init(sizeHint: Option[Int] = None): Unit = {} + def stop(): Unit = {} +} + +object CacheLogger { + def nop: CacheLogger = + new CacheLogger {} +} diff --git a/modules/lm-coursier/src/main/scala/lmcoursier/definitions/Classifier.scala b/modules/lm-coursier/src/main/scala/lmcoursier/definitions/Classifier.scala new file mode 100644 index 000000000..d3720859a --- /dev/null +++ b/modules/lm-coursier/src/main/scala/lmcoursier/definitions/Classifier.scala @@ -0,0 +1,3 @@ +package lmcoursier.definitions + +final case class Classifier(value: String) extends AnyVal diff --git a/modules/lm-coursier/src/main/scala/lmcoursier/definitions/Configuration.scala b/modules/lm-coursier/src/main/scala/lmcoursier/definitions/Configuration.scala new file mode 100644 index 000000000..378605c85 --- /dev/null +++ b/modules/lm-coursier/src/main/scala/lmcoursier/definitions/Configuration.scala @@ -0,0 +1,3 @@ +package lmcoursier.definitions + +final case class Configuration(value: String) extends AnyVal diff --git a/modules/lm-coursier/src/main/scala/lmcoursier/definitions/Dependency.scala b/modules/lm-coursier/src/main/scala/lmcoursier/definitions/Dependency.scala new file mode 100644 index 000000000..21a35b6dd --- /dev/null +++ b/modules/lm-coursier/src/main/scala/lmcoursier/definitions/Dependency.scala @@ -0,0 +1,14 @@ +package lmcoursier.definitions + +final case class Dependency( + module: Module, + version: String, + configuration: Configuration, + exclusions: Set[(Organization, ModuleName)], + + // Maven-specific + attributes: Attributes, + optional: Boolean, + + transitive: Boolean +) diff --git a/modules/lm-coursier/src/main/scala/lmcoursier/definitions/Extension.scala b/modules/lm-coursier/src/main/scala/lmcoursier/definitions/Extension.scala new file mode 100644 index 000000000..1730c5810 --- /dev/null +++ b/modules/lm-coursier/src/main/scala/lmcoursier/definitions/Extension.scala @@ -0,0 +1,3 @@ +package lmcoursier.definitions + +final case class Extension(value: String) extends AnyVal diff --git a/modules/lm-coursier/src/main/scala/lmcoursier/definitions/Info.scala b/modules/lm-coursier/src/main/scala/lmcoursier/definitions/Info.scala new file mode 100644 index 000000000..a6d2897d0 --- /dev/null +++ b/modules/lm-coursier/src/main/scala/lmcoursier/definitions/Info.scala @@ -0,0 +1,26 @@ +package lmcoursier.definitions + +final case class Info( + description: String, + homePage: String, + licenses: Seq[(String, Option[String])], + developers: Seq[Info.Developer], + publication: Option[Info.DateTime] +) + +object Info { + final case class Developer( + id: String, + name: String, + url: String + ) + + final case class DateTime( + year: Int, + month: Int, + day: Int, + hour: Int, + minute: Int, + second: Int + ) +} diff --git a/modules/lm-coursier/src/main/scala/lmcoursier/definitions/Module.scala b/modules/lm-coursier/src/main/scala/lmcoursier/definitions/Module.scala new file mode 100644 index 000000000..09ec6b6ea --- /dev/null +++ b/modules/lm-coursier/src/main/scala/lmcoursier/definitions/Module.scala @@ -0,0 +1,7 @@ +package lmcoursier.definitions + +final case class Module( + organization: Organization, + name: ModuleName, + attributes: Map[String, String] +) diff --git a/modules/lm-coursier/src/main/scala/lmcoursier/definitions/ModuleName.scala b/modules/lm-coursier/src/main/scala/lmcoursier/definitions/ModuleName.scala new file mode 100644 index 000000000..c29d972cf --- /dev/null +++ b/modules/lm-coursier/src/main/scala/lmcoursier/definitions/ModuleName.scala @@ -0,0 +1,3 @@ +package lmcoursier.definitions + +final case class ModuleName(value: String) extends AnyVal diff --git a/modules/lm-coursier/src/main/scala/lmcoursier/definitions/Organization.scala b/modules/lm-coursier/src/main/scala/lmcoursier/definitions/Organization.scala new file mode 100644 index 000000000..9ef788eb7 --- /dev/null +++ b/modules/lm-coursier/src/main/scala/lmcoursier/definitions/Organization.scala @@ -0,0 +1,3 @@ +package lmcoursier.definitions + +final case class Organization(value: String) extends AnyVal diff --git a/modules/lm-coursier/src/main/scala/lmcoursier/definitions/Project.scala b/modules/lm-coursier/src/main/scala/lmcoursier/definitions/Project.scala new file mode 100644 index 000000000..68af2a012 --- /dev/null +++ b/modules/lm-coursier/src/main/scala/lmcoursier/definitions/Project.scala @@ -0,0 +1,12 @@ +package lmcoursier.definitions + +final case class Project( + module: Module, + version: String, + dependencies: Seq[(Configuration, Dependency)], + configurations: Map[Configuration, Seq[Configuration]], + properties: Seq[(String, String)], + packagingOpt: Option[Type], + publications: Seq[(Configuration, Publication)], + info: Info +) diff --git a/modules/lm-coursier/src/main/scala/lmcoursier/definitions/Publication.scala b/modules/lm-coursier/src/main/scala/lmcoursier/definitions/Publication.scala new file mode 100644 index 000000000..0f1b938f8 --- /dev/null +++ b/modules/lm-coursier/src/main/scala/lmcoursier/definitions/Publication.scala @@ -0,0 +1,8 @@ +package lmcoursier.definitions + +final case class Publication( + name: String, + `type`: Type, + ext: Extension, + classifier: Classifier +) diff --git a/modules/lm-coursier/src/main/scala/lmcoursier/definitions/ToCoursier.scala b/modules/lm-coursier/src/main/scala/lmcoursier/definitions/ToCoursier.scala new file mode 100644 index 000000000..3221c01c4 --- /dev/null +++ b/modules/lm-coursier/src/main/scala/lmcoursier/definitions/ToCoursier.scala @@ -0,0 +1,148 @@ +package lmcoursier.definitions + +import lmcoursier.credentials.{Credentials, DirectCredentials, FileCredentials} + +// TODO Make private[lmcoursier] +// private[coursier] +object ToCoursier { + + def configuration(configuration: Configuration): coursier.core.Configuration = + coursier.core.Configuration(configuration.value) + + private def attributes(attributes: Attributes): coursier.core.Attributes = + coursier.core.Attributes( + coursier.core.Type(attributes.`type`.value), + coursier.core.Classifier(attributes.classifier.value) + ) + + def publication(publication: Publication): coursier.core.Publication = + coursier.core.Publication( + publication.name, + coursier.core.Type(publication.`type`.value), + coursier.core.Extension(publication.ext.value), + coursier.core.Classifier(publication.classifier.value) + ) + + def authentication(authentication: Authentication): coursier.core.Authentication = + coursier.core.Authentication( + authentication.user, + authentication.password, + authentication.optional, + authentication.realmOpt + ) + + def module(module: Module): coursier.core.Module = + coursier.core.Module( + coursier.core.Organization(module.organization.value), + coursier.core.ModuleName(module.name.value), + module.attributes + ) + + def dependency(dependency: Dependency): coursier.core.Dependency = + coursier.core.Dependency( + module(dependency.module), + dependency.version, + configuration(dependency.configuration), + dependency.exclusions.map { + case (org, name) => + (coursier.core.Organization(org.value), coursier.core.ModuleName(name.value)) + }, + attributes(dependency.attributes), + dependency.optional, + dependency.transitive + ) + + def project(project: Project): coursier.core.Project = + coursier.core.Project( + module(project.module), + project.version, + project.dependencies.map { + case (conf, dep) => + configuration(conf) -> dependency(dep) + }, + project.configurations.map { + case (k, l) => + configuration(k) -> l.map(configuration) + }, + None, + Nil, + project.properties, + Nil, + None, + None, + project.packagingOpt.map(t => coursier.core.Type(t.value)), + relocated = false, + None, + project.publications.map { + case (conf, pub) => + configuration(conf) -> publication(pub) + }, + coursier.core.Info( + project.info.description, + project.info.homePage, + project.info.licenses, + project.info.developers.map { dev => + coursier.core.Info.Developer( + dev.id, + dev.name, + dev.url + ) + }, + project.info.publication.map { dt => + coursier.core.Versions.DateTime( + dt.year, + dt.month, + dt.day, + dt.hour, + dt.minute, + dt.second + ) + } + ) + ) + + def credentials(credentials: Credentials): coursier.credentials.Credentials = + credentials match { + case d: DirectCredentials => + coursier.credentials.DirectCredentials() + .withHost(d.host) + .withUsername(d.username) + .withPassword(d.password) + .withRealm(d.realm) + .withOptional(d.optional) + .withMatchHost(d.matchHost) + .withHttpsOnly(d.httpsOnly) + case f: FileCredentials => + coursier.credentials.FileCredentials(f.path) + .withOptional(f.optional) + } + + def cacheLogger(logger: CacheLogger): coursier.cache.CacheLogger = + new coursier.cache.CacheLogger { + override def foundLocally(url: String): Unit = + logger.foundLocally(url) + override def downloadingArtifact(url: String): Unit = + logger.downloadingArtifact(url) + override def downloadProgress(url: String, downloaded: Long): Unit = + logger.downloadProgress(url, downloaded) + override def downloadedArtifact(url: String, success: Boolean): Unit = + logger.downloadedArtifact(url, success) + override def checkingUpdates(url: String, currentTimeOpt: Option[Long]): Unit = + logger.checkingUpdates(url, currentTimeOpt) + override def checkingUpdatesResult(url: String, currentTimeOpt: Option[Long], remoteTimeOpt: Option[Long]): Unit = + logger.checkingUpdatesResult(url, currentTimeOpt, remoteTimeOpt) + override def downloadLength(url: String, totalLength: Long, alreadyDownloaded: Long, watching: Boolean): Unit = + logger.downloadLength(url, totalLength, alreadyDownloaded, watching) + override def gettingLength(url: String): Unit = + logger.gettingLength(url) + override def gettingLengthResult(url: String, length: Option[Long]): Unit = + logger.gettingLengthResult(url, length) + override def removedCorruptFile(url: String, reason: Option[String]): Unit = + logger.removedCorruptFile(url, reason) + override def init(sizeHint: Option[Int] = None): Unit = + logger.init(sizeHint) + override def stop(): Unit = + logger.stop() + } + +} diff --git a/modules/lm-coursier/src/main/scala/lmcoursier/definitions/Type.scala b/modules/lm-coursier/src/main/scala/lmcoursier/definitions/Type.scala new file mode 100644 index 000000000..1e6d8e8a8 --- /dev/null +++ b/modules/lm-coursier/src/main/scala/lmcoursier/definitions/Type.scala @@ -0,0 +1,3 @@ +package lmcoursier.definitions + +final case class Type(value: String) extends AnyVal diff --git a/modules/lm-coursier/src/main/scala/coursier/lmcoursier/ArtifactsParams.scala b/modules/lm-coursier/src/main/scala/lmcoursier/internal/ArtifactsParams.scala similarity index 88% rename from modules/lm-coursier/src/main/scala/coursier/lmcoursier/ArtifactsParams.scala rename to modules/lm-coursier/src/main/scala/lmcoursier/internal/ArtifactsParams.scala index 055524408..d4a64e419 100644 --- a/modules/lm-coursier/src/main/scala/coursier/lmcoursier/ArtifactsParams.scala +++ b/modules/lm-coursier/src/main/scala/lmcoursier/internal/ArtifactsParams.scala @@ -1,9 +1,10 @@ -package coursier.lmcoursier +package lmcoursier.internal import coursier.cache.{CacheLogger, FileCache} import coursier.core.{Classifier, Resolution} import coursier.util.Task +// private[coursier] final case class ArtifactsParams( classifiers: Option[Seq[Classifier]], resolutions: Seq[Resolution], diff --git a/modules/lm-coursier/src/main/scala/coursier/lmcoursier/ArtifactsRun.scala b/modules/lm-coursier/src/main/scala/lmcoursier/internal/ArtifactsRun.scala similarity index 93% rename from modules/lm-coursier/src/main/scala/coursier/lmcoursier/ArtifactsRun.scala rename to modules/lm-coursier/src/main/scala/lmcoursier/internal/ArtifactsRun.scala index 18ceebfc9..32a3b8a86 100644 --- a/modules/lm-coursier/src/main/scala/coursier/lmcoursier/ArtifactsRun.scala +++ b/modules/lm-coursier/src/main/scala/lmcoursier/internal/ArtifactsRun.scala @@ -1,13 +1,14 @@ -package coursier.lmcoursier +package lmcoursier.internal import java.io.File import coursier.Artifact +import coursier.cache.internal.ThreadUtil import coursier.cache.loggers.{FallbackRefreshDisplay, ProgressBarRefreshDisplay, RefreshLogger} import coursier.core.Type -import coursier.util.Sync import sbt.util.Logger +// private[coursier] object ArtifactsRun { def artifacts( @@ -28,7 +29,7 @@ object ArtifactsRun { else "" - Sync.withFixedThreadPool(params.parallel) { pool => + ThreadUtil.withFixedThreadPool(params.parallel) { pool => coursier.Artifacts() .withResolutions(params.resolutions) diff --git a/modules/lm-coursier/src/main/scala/coursier/lmcoursier/CoursierModuleDescriptor.scala b/modules/lm-coursier/src/main/scala/lmcoursier/internal/CoursierModuleDescriptor.scala similarity index 76% rename from modules/lm-coursier/src/main/scala/coursier/lmcoursier/CoursierModuleDescriptor.scala rename to modules/lm-coursier/src/main/scala/lmcoursier/internal/CoursierModuleDescriptor.scala index f30bf9732..0644119d6 100644 --- a/modules/lm-coursier/src/main/scala/coursier/lmcoursier/CoursierModuleDescriptor.scala +++ b/modules/lm-coursier/src/main/scala/lmcoursier/internal/CoursierModuleDescriptor.scala @@ -1,8 +1,9 @@ -package coursier.lmcoursier +package lmcoursier.internal +import lmcoursier.CoursierConfiguration import sbt.librarymanagement._ -final case class CoursierModuleDescriptor( +private[lmcoursier] final case class CoursierModuleDescriptor( descriptor: ModuleDescriptorConfiguration, conf: CoursierConfiguration ) extends ModuleDescriptor { diff --git a/modules/lm-coursier/src/main/scala/lmcoursier/internal/CoursierModuleSettings.scala b/modules/lm-coursier/src/main/scala/lmcoursier/internal/CoursierModuleSettings.scala new file mode 100644 index 000000000..badad3183 --- /dev/null +++ b/modules/lm-coursier/src/main/scala/lmcoursier/internal/CoursierModuleSettings.scala @@ -0,0 +1,5 @@ +package lmcoursier.internal + +import sbt.librarymanagement.ModuleSettings + +private[lmcoursier] case class CoursierModuleSettings() extends ModuleSettings diff --git a/modules/lm-coursier/src/main/scala/coursier/lmcoursier/InterProjectRepository.scala b/modules/lm-coursier/src/main/scala/lmcoursier/internal/InterProjectRepository.scala similarity index 93% rename from modules/lm-coursier/src/main/scala/coursier/lmcoursier/InterProjectRepository.scala rename to modules/lm-coursier/src/main/scala/lmcoursier/internal/InterProjectRepository.scala index 153821df5..fbb3ad218 100644 --- a/modules/lm-coursier/src/main/scala/coursier/lmcoursier/InterProjectRepository.scala +++ b/modules/lm-coursier/src/main/scala/lmcoursier/internal/InterProjectRepository.scala @@ -1,8 +1,9 @@ -package coursier.lmcoursier +package lmcoursier.internal import coursier.core._ import coursier.util.{EitherT, Monad} +// private[coursier] final case class InterProjectRepository(projects: Seq[Project]) extends Repository { private val map = projects diff --git a/modules/lm-coursier/src/main/scala/coursier/lmcoursier/Lock.scala b/modules/lm-coursier/src/main/scala/lmcoursier/internal/Lock.scala similarity index 78% rename from modules/lm-coursier/src/main/scala/coursier/lmcoursier/Lock.scala rename to modules/lm-coursier/src/main/scala/lmcoursier/internal/Lock.scala index fd5e96ed3..6100302ed 100644 --- a/modules/lm-coursier/src/main/scala/coursier/lmcoursier/Lock.scala +++ b/modules/lm-coursier/src/main/scala/lmcoursier/internal/Lock.scala @@ -1,6 +1,6 @@ -package coursier.lmcoursier +package lmcoursier.internal -object Lock { +private[lmcoursier] object Lock { // Wrap blocks downloading stuff (resolution / artifact downloads) in lock.synchronized. // Downloads are already parallel, no need to parallelize further, and this results in diff --git a/modules/lm-coursier/src/main/scala/coursier/lmcoursier/ResolutionParams.scala b/modules/lm-coursier/src/main/scala/lmcoursier/internal/ResolutionParams.scala similarity index 67% rename from modules/lm-coursier/src/main/scala/coursier/lmcoursier/ResolutionParams.scala rename to modules/lm-coursier/src/main/scala/lmcoursier/internal/ResolutionParams.scala index 66de7a12e..69e807d79 100644 --- a/modules/lm-coursier/src/main/scala/coursier/lmcoursier/ResolutionParams.scala +++ b/modules/lm-coursier/src/main/scala/lmcoursier/internal/ResolutionParams.scala @@ -1,13 +1,15 @@ -package coursier.lmcoursier +package lmcoursier.internal import java.io.File import coursier.cache.{CacheLogger, FileCache} import coursier.ProjectCache import coursier.core._ +import lmcoursier.FallbackDependency +import lmcoursier.definitions.ToCoursier import coursier.util.{InMemoryRepository, Task} -import sbt.librarymanagement.{Resolver, URLRepository} +// private[coursier] final case class ResolutionParams( dependencies: Seq[(Configuration, Dependency)], fallbackDependencies: Seq[FallbackDependency], @@ -31,7 +33,7 @@ final case class ResolutionParams( else { val map = fallbackDependencies.map { case FallbackDependency(mod, ver, url, changing) => - (mod, ver) -> ((url, changing)) + (ToCoursier.module(mod), ver) -> ((url, changing)) }.toMap Seq( @@ -67,6 +69,7 @@ final case class ResolutionParams( } +// private[coursier] object ResolutionParams { private lazy val m = { @@ -99,40 +102,4 @@ object ResolutionParams { ) ++ sys.props } - private val slowReposBase = Seq( - "https://repo.typesafe.com/", - "https://repo.scala-sbt.org/", - "http://repo.typesafe.com/", - "http://repo.scala-sbt.org/" - ) - - private val fastReposBase = Seq( - "http://repo1.maven.org/", - "https://repo1.maven.org/" - ) - - private def url(res: Resolver): Option[String] = - res match { - case m: sbt.librarymanagement.MavenRepository => - Some(m.root) - case u: URLRepository => - u.patterns.artifactPatterns.headOption - .orElse(u.patterns.ivyPatterns.headOption) - case _ => - None - } - - private def fastRepo(res: Resolver): Boolean = - url(res).exists(u => fastReposBase.exists(u.startsWith)) - - private def slowRepo(res: Resolver): Boolean = - url(res).exists(u => slowReposBase.exists(u.startsWith)) - - def reorderResolvers(resolvers: Seq[Resolver]): Seq[Resolver] = - if (resolvers.exists(fastRepo) && resolvers.exists(slowRepo)) { - val (slow, other) = resolvers.partition(slowRepo) - other ++ slow - } else - resolvers - } diff --git a/modules/lm-coursier/src/main/scala/coursier/lmcoursier/ResolutionRun.scala b/modules/lm-coursier/src/main/scala/lmcoursier/internal/ResolutionRun.scala similarity index 95% rename from modules/lm-coursier/src/main/scala/coursier/lmcoursier/ResolutionRun.scala rename to modules/lm-coursier/src/main/scala/lmcoursier/internal/ResolutionRun.scala index 15bbc7d9a..4a7edf6f2 100644 --- a/modules/lm-coursier/src/main/scala/coursier/lmcoursier/ResolutionRun.scala +++ b/modules/lm-coursier/src/main/scala/lmcoursier/internal/ResolutionRun.scala @@ -1,16 +1,17 @@ -package coursier.lmcoursier +package lmcoursier.internal +import coursier.cache.internal.ThreadUtil import coursier.{Resolution, Resolve} import coursier.cache.loggers.{FallbackRefreshDisplay, ProgressBarRefreshDisplay, RefreshLogger} import coursier.core._ import coursier.ivy.IvyRepository import coursier.maven.MavenRepository -import coursier.util.Sync import sbt.util.Logger +// private[coursier] object ResolutionRun { - def resolution( + private def resolution( params: ResolutionParams, verbosityLevel: Int, log: Logger, @@ -63,7 +64,7 @@ object ResolutionRun { if (verbosityLevel >= 2) log.info(initialMessage) - Sync.withFixedThreadPool(params.parallel) { pool => + ThreadUtil.withFixedThreadPool(params.parallel) { pool => Resolve() .withDependencies( diff --git a/modules/lm-coursier/src/main/scala/coursier/lmcoursier/FromSbt.scala b/modules/lm-coursier/src/main/scala/lmcoursier/internal/Resolvers.scala similarity index 53% rename from modules/lm-coursier/src/main/scala/coursier/lmcoursier/FromSbt.scala rename to modules/lm-coursier/src/main/scala/lmcoursier/internal/Resolvers.scala index 0dcbd5f82..f1cd08cb7 100644 --- a/modules/lm-coursier/src/main/scala/coursier/lmcoursier/FromSbt.scala +++ b/modules/lm-coursier/src/main/scala/lmcoursier/internal/Resolvers.scala @@ -1,185 +1,18 @@ -package coursier.lmcoursier +package lmcoursier.internal import coursier.ivy.IvyRepository -import coursier.ivy.IvyXml.{mappings => ivyXmlMappings} import java.net.MalformedURLException + import coursier.cache.CacheUrl -import coursier.{Attributes, Dependency, Module} -import coursier.core._ +import coursier.core.{Authentication, Repository} import coursier.maven.MavenRepository import org.apache.ivy.plugins.resolver.IBiblioResolver -import sbt.internal.librarymanagement.mavenint.SbtPomExtraProperties import sbt.librarymanagement.{Configuration => _, MavenRepository => _, _} import sbt.util.Logger + import scala.collection.JavaConverters._ -object FromSbt { - - def sbtModuleIdName( - moduleId: ModuleID, - scalaVersion: => String, - scalaBinaryVersion: => String, - optionalCrossVer: Boolean = false - ): String = { - val name0 = moduleId.name - val updatedName = sbtCrossVersionName(name0, moduleId.crossVersion, scalaVersion, scalaBinaryVersion) - if (!optionalCrossVer || updatedName.length <= name0.length) - updatedName - else { - val suffix = updatedName.substring(name0.length) - if (name0.endsWith(suffix)) - name0 - else - updatedName - } - } - - def sbtCrossVersionName( - name: String, - crossVersion: CrossVersion, - scalaVersion: => String, - scalaBinaryVersion: => String - ): String = - CrossVersion(crossVersion, scalaVersion, scalaBinaryVersion) - .fold(name)(_(name)) - - def attributes(attr: Map[String, String]): Map[String, String] = - attr.map { case (k, v) => - k.stripPrefix("e:") -> v - }.filter { case (k, _) => - !k.startsWith(SbtPomExtraProperties.POM_INFO_KEY_PREFIX) - } - - def moduleVersion( - module: ModuleID, - scalaVersion: String, - scalaBinaryVersion: String, - optionalCrossVer: Boolean = false - ): (Module, String) = { - - val fullName = sbtModuleIdName(module, scalaVersion, scalaBinaryVersion, optionalCrossVer) - - val module0 = Module(Organization(module.organization), ModuleName(fullName), FromSbt.attributes(module.extraDependencyAttributes)) - val version = module.revision - - (module0, version) - } - - def dependencies( - module: ModuleID, - scalaVersion: String, - scalaBinaryVersion: String, - optionalCrossVer: Boolean = false - ): Seq[(Configuration, Dependency)] = { - - // TODO Warn about unsupported properties in `module` - - val (module0, version) = moduleVersion(module, scalaVersion, scalaBinaryVersion, optionalCrossVer) - - val dep = Dependency( - module0, - version, - exclusions = module.exclusions.map { rule => - // FIXME Other `rule` fields are ignored here - (Organization(rule.organization), ModuleName(rule.name)) - }.toSet, - transitive = module.isTransitive - ) - - val mapping = module.configurations.getOrElse("compile") - val allMappings = ivyXmlMappings(mapping) - - val attributes = - if (module.explicitArtifacts.isEmpty) - Seq(Attributes(Type.empty, Classifier.empty)) - else - module.explicitArtifacts.map { a => - Attributes( - `type` = Type(a.`type`), - classifier = a.classifier.fold(Classifier.empty)(Classifier(_)) - ) - } - - for { - (from, to) <- allMappings - attr <- attributes - } yield from -> dep.copy(configuration = to, attributes = attr) - } - - def fallbackDependencies( - allDependencies: Seq[ModuleID], - scalaVersion: String, - scalaBinaryVersion: String - ): Seq[FallbackDependency] = - for { - module <- allDependencies - artifact <- module.explicitArtifacts - url <- artifact.url.toSeq - } yield { - val (module0, version) = moduleVersion(module, scalaVersion, scalaBinaryVersion) - FallbackDependency(module0, version, url, module.isChanging) - } - - def sbtClassifiersProject( - cm: GetClassifiersModule, - scalaVersion: String, - scalaBinaryVersion: String - ) = { - - val p = FromSbt.project( - cm.id, - cm.dependencies, - cm.configurations.map(cfg => Configuration(cfg.name) -> cfg.extendsConfigs.map(c => Configuration(c.name))).toMap, - scalaVersion, - scalaBinaryVersion - ) - - // for w/e reasons, the dependencies sometimes don't land in the right config above - // this is a loose attempt at fixing that - cm.configurations match { - case Seq(cfg) => - p.copy( - dependencies = p.dependencies.map { - case (_, d) => (Configuration(cfg.name), d) - } - ) - case _ => - p - } - } - - def project( - projectID: ModuleID, - allDependencies: Seq[ModuleID], - ivyConfigurations: Map[Configuration, Seq[Configuration]], - scalaVersion: String, - scalaBinaryVersion: String - ): Project = { - - val deps = allDependencies.flatMap(dependencies(_, scalaVersion, scalaBinaryVersion)) - - Project( - Module( - Organization(projectID.organization), - ModuleName(sbtModuleIdName(projectID, scalaVersion, scalaBinaryVersion)), - FromSbt.attributes(projectID.extraDependencyAttributes) - ), - projectID.revision, - deps, - ivyConfigurations, - None, - Nil, - Nil, - Nil, - None, - None, - None, - relocated = false, - None, - Nil, - Info.empty - ) - } +object Resolvers { private def mavenCompatibleBaseOpt(patterns: Patterns): Option[String] = if (patterns.isMavenCompatible) { diff --git a/modules/lm-coursier/src/main/scala/coursier/lmcoursier/SbtBootJars.scala b/modules/lm-coursier/src/main/scala/lmcoursier/internal/SbtBootJars.scala similarity index 90% rename from modules/lm-coursier/src/main/scala/coursier/lmcoursier/SbtBootJars.scala rename to modules/lm-coursier/src/main/scala/lmcoursier/internal/SbtBootJars.scala index ea9be1d6f..4e1db9cff 100644 --- a/modules/lm-coursier/src/main/scala/coursier/lmcoursier/SbtBootJars.scala +++ b/modules/lm-coursier/src/main/scala/lmcoursier/internal/SbtBootJars.scala @@ -1,9 +1,10 @@ -package coursier.lmcoursier +package lmcoursier.internal import java.io.File import coursier.core.{Module, ModuleName, Organization} +// private[coursier] object SbtBootJars { def apply( scalaOrg: Organization, diff --git a/modules/lm-coursier/src/main/scala/coursier/lmcoursier/SbtCoursierCache.scala b/modules/lm-coursier/src/main/scala/lmcoursier/internal/SbtCoursierCache.scala similarity index 92% rename from modules/lm-coursier/src/main/scala/coursier/lmcoursier/SbtCoursierCache.scala rename to modules/lm-coursier/src/main/scala/lmcoursier/internal/SbtCoursierCache.scala index d3b26ec6b..c4191bb35 100644 --- a/modules/lm-coursier/src/main/scala/coursier/lmcoursier/SbtCoursierCache.scala +++ b/modules/lm-coursier/src/main/scala/lmcoursier/internal/SbtCoursierCache.scala @@ -1,10 +1,11 @@ -package coursier.lmcoursier +package lmcoursier.internal import java.util.concurrent.ConcurrentHashMap import coursier.core._ import sbt.librarymanagement.UpdateReport +// private[coursier] class SbtCoursierCache { import SbtCoursierCache._ @@ -35,6 +36,7 @@ class SbtCoursierCache { } +// private[coursier] object SbtCoursierCache { final case class ResolutionKey( @@ -53,6 +55,7 @@ object SbtCoursierCache { ) - private[coursier] val default = new SbtCoursierCache + // private[coursier] + val default = new SbtCoursierCache } diff --git a/modules/lm-coursier/src/main/scala/coursier/lmcoursier/ToSbt.scala b/modules/lm-coursier/src/main/scala/lmcoursier/internal/SbtUpdateReport.scala similarity index 88% rename from modules/lm-coursier/src/main/scala/coursier/lmcoursier/ToSbt.scala rename to modules/lm-coursier/src/main/scala/lmcoursier/internal/SbtUpdateReport.scala index 53143405e..e94012091 100644 --- a/modules/lm-coursier/src/main/scala/coursier/lmcoursier/ToSbt.scala +++ b/modules/lm-coursier/src/main/scala/lmcoursier/internal/SbtUpdateReport.scala @@ -1,4 +1,4 @@ -package coursier.lmcoursier +package lmcoursier.internal import java.io.File import java.net.URL @@ -11,7 +11,7 @@ import coursier.maven.MavenAttributes import sbt.librarymanagement.{Artifact => _, Configuration => _, _} import sbt.util.Logger -object ToSbt { +private[internal] object SbtUpdateReport { private def caching[K, V](f: K => V): K => V = { @@ -27,7 +27,7 @@ object ToSbt { } } - val moduleId = caching[(Dependency, String, Map[String, String]), ModuleID] { + private val moduleId = caching[(Dependency, String, Map[String, String]), ModuleID] { case (dependency, version, extraProperties) => sbt.librarymanagement.ModuleID( dependency.module.organization.value, @@ -52,7 +52,7 @@ object ToSbt { ) } - val artifact = caching[(Module, Map[String, String], Attributes, Artifact), sbt.librarymanagement.Artifact] { + private val artifact = caching[(Module, Map[String, String], Attributes, Artifact), sbt.librarymanagement.Artifact] { case (module, extraProperties, attr, artifact) => sbt.librarymanagement.Artifact(module.name.value) // FIXME Get these two from publications @@ -69,16 +69,16 @@ object ToSbt { .withExtraAttributes(module.attributes ++ extraProperties) } - val moduleReport = caching[(Dependency, Seq[(Dependency, Project)], Project, Seq[(Attributes, Artifact, Option[File])]), ModuleReport] { + private val moduleReport = caching[(Dependency, Seq[(Dependency, Project)], Project, Seq[(Attributes, Artifact, Option[File])]), ModuleReport] { case (dependency, dependees, project, artifacts) => val sbtArtifacts = artifacts.collect { - case (attr, artifact, Some(file)) => - (ToSbt.artifact(dependency.module, project.properties.toMap, attr, artifact), file) + case (attr, artifact0, Some(file)) => + (artifact(dependency.module, project.properties.toMap, attr, artifact0), file) } val sbtMissingArtifacts = artifacts.collect { - case (attr, artifact, None) => - ToSbt.artifact(dependency.module, project.properties.toMap, attr, artifact) + case (attr, artifact0, None) => + artifact(dependency.module, project.properties.toMap, attr, artifact0) } val publicationDate = project.info.publication.map { dt => @@ -88,7 +88,7 @@ object ToSbt { val callers = dependees.map { case (dependee, dependeeProj) => Caller( - ToSbt.moduleId(dependee, dependeeProj.version, dependeeProj.properties.toMap), + moduleId(dependee, dependeeProj.version, dependeeProj.properties.toMap), dependeeProj.configurations.keys.toVector.map(c => ConfigRef(c.value)), dependee.module.attributes ++ dependeeProj.properties, // FIXME Set better values here @@ -100,7 +100,7 @@ object ToSbt { } ModuleReport( - ToSbt.moduleId(dependency, project.version, project.properties.toMap), + moduleId(dependency, project.version, project.properties.toMap), sbtArtifacts.toVector, sbtMissingArtifacts.toVector ) @@ -121,7 +121,7 @@ object ToSbt { .withCallers(callers.toVector) } - def moduleReports( + private def moduleReports( res: Resolution, classifiersOpt: Option[Seq[Classifier]], artifactFileOpt: (Module, String, Attributes, Artifact) => Option[File], @@ -196,7 +196,7 @@ object ToSbt { (dependee, dependeeProj) } - ToSbt.moduleReport( + moduleReport( dep, dependees, proj, @@ -205,7 +205,7 @@ object ToSbt { } } - def updateReport( + def apply( configDependencies: Map[Configuration, Seq[Dependency]], resolutions: Map[Configuration, Resolution], configs: Map[Configuration, Set[Configuration]], @@ -225,7 +225,7 @@ object ToSbt { .distinct val subRes = resolutions(config).subset(configDeps) - val reports = ToSbt.moduleReports( + val reports = moduleReports( subRes, classifiersOpt, artifactFileOpt, @@ -240,7 +240,7 @@ object ToSbt { // appears first in the update report, see https://github.com/coursier/coursier/issues/650 val dep = subRes.rootDependencies.head val (_, proj) = subRes.projectCache(dep.moduleVersion) - val mod = ToSbt.moduleId(dep, proj.version, proj.properties.toMap) + val mod = moduleId(dep, proj.version, proj.properties.toMap) val (main, other) = reports.partition { r => r.module.organization == mod.organization && r.module.name == mod.name && diff --git a/modules/lm-coursier/src/main/scala/coursier/lmcoursier/UpdateParams.scala b/modules/lm-coursier/src/main/scala/lmcoursier/internal/UpdateParams.scala similarity index 95% rename from modules/lm-coursier/src/main/scala/coursier/lmcoursier/UpdateParams.scala rename to modules/lm-coursier/src/main/scala/lmcoursier/internal/UpdateParams.scala index 84f7f9332..0b3b98fad 100644 --- a/modules/lm-coursier/src/main/scala/coursier/lmcoursier/UpdateParams.scala +++ b/modules/lm-coursier/src/main/scala/lmcoursier/internal/UpdateParams.scala @@ -1,9 +1,10 @@ -package coursier.lmcoursier +package lmcoursier.internal import java.io.File import coursier.core._ +// private[coursier] final case class UpdateParams( shadedConfigOpt: Option[(String, Configuration)], artifacts: Map[Artifact, File], diff --git a/modules/lm-coursier/src/main/scala/coursier/lmcoursier/UpdateRun.scala b/modules/lm-coursier/src/main/scala/lmcoursier/internal/UpdateRun.scala similarity index 96% rename from modules/lm-coursier/src/main/scala/coursier/lmcoursier/UpdateRun.scala rename to modules/lm-coursier/src/main/scala/lmcoursier/internal/UpdateRun.scala index 61a3d4179..9965ad8ff 100644 --- a/modules/lm-coursier/src/main/scala/coursier/lmcoursier/UpdateRun.scala +++ b/modules/lm-coursier/src/main/scala/lmcoursier/internal/UpdateRun.scala @@ -1,4 +1,4 @@ -package coursier.lmcoursier +package lmcoursier.internal import coursier.core.Resolution.ModuleVersion import coursier.core._ @@ -6,6 +6,7 @@ import coursier.util.Print import sbt.librarymanagement.UpdateReport import sbt.util.Logger +// private[coursier] object UpdateRun { // Move back to coursier.util (in core module) after 1.0? @@ -54,7 +55,7 @@ object UpdateRun { params: UpdateParams, verbosityLevel: Int, log: Logger - ): UpdateReport = { + ): UpdateReport = Lock.lock.synchronized { val configResolutions = params.res.flatMap { case (configs, r) => @@ -83,7 +84,7 @@ object UpdateRun { log.info(repr.split('\n').map(" " + _).mkString("\n")) } - ToSbt.updateReport( + SbtUpdateReport( depsByConfig, configResolutions, params.configs, diff --git a/modules/lm-coursier/src/test/scala/coursier/lmcoursier/ResolutionSpec.scala b/modules/lm-coursier/src/test/scala/lmcoursier/ResolutionSpec.scala similarity index 93% rename from modules/lm-coursier/src/test/scala/coursier/lmcoursier/ResolutionSpec.scala rename to modules/lm-coursier/src/test/scala/lmcoursier/ResolutionSpec.scala index d034e7c11..e858a46b1 100644 --- a/modules/lm-coursier/src/test/scala/coursier/lmcoursier/ResolutionSpec.scala +++ b/modules/lm-coursier/src/test/scala/lmcoursier/ResolutionSpec.scala @@ -1,4 +1,4 @@ -package coursier.lmcoursier +package lmcoursier import org.scalatest.{Matchers, PropSpec} import sbt.internal.librarymanagement.cross.CrossVersionUtil @@ -152,15 +152,4 @@ final class ResolutionSpec extends PropSpec with Matchers { resolution should be('right) } - - property("reorder fast and slow resolvers") { - val resolvers = Vector( - JavaNet2Repository, - Resolver.sbtPluginRepo("releases"), - DefaultMavenRepository - ) - val engine = new CoursierDependencyResolution(CoursierConfiguration().withResolvers(resolvers)) - engine.resolvers.last.name should be("sbt-plugin-releases") - engine.resolvers should have size resolvers.length - } } diff --git a/modules/sbt-coursier-shared/src/main/scala/coursier/Credentials.scala b/modules/sbt-coursier-shared/src/main/scala/coursier/Credentials.scala index 70223ec26..877efec55 100644 --- a/modules/sbt-coursier-shared/src/main/scala/coursier/Credentials.scala +++ b/modules/sbt-coursier-shared/src/main/scala/coursier/Credentials.scala @@ -3,7 +3,7 @@ package coursier import java.io.{File, FileInputStream} import java.util.Properties -import coursier.core.Authentication +import lmcoursier.definitions.Authentication @deprecated("Use coursierExtraCredentials rather than coursierCredentials", "1.1.0-M14") sealed abstract class Credentials extends Product with Serializable { diff --git a/modules/sbt-coursier-shared/src/main/scala/coursier/sbtcoursiershared/ArtifactsTasks.scala b/modules/sbt-coursier-shared/src/main/scala/coursier/sbtcoursiershared/ArtifactsTasks.scala index 94b39faac..e6cee8dce 100644 --- a/modules/sbt-coursier-shared/src/main/scala/coursier/sbtcoursiershared/ArtifactsTasks.scala +++ b/modules/sbt-coursier-shared/src/main/scala/coursier/sbtcoursiershared/ArtifactsTasks.scala @@ -1,13 +1,12 @@ package coursier.sbtcoursiershared -import coursier.core._ -import coursier.lmcoursier._ +import lmcoursier.definitions.{Classifier, Configuration, Extension, Publication, Type} import coursier.sbtcoursiershared.Structure._ import sbt.librarymanagement.{Artifact => _, Configuration => _, _} import sbt.Def import sbt.Keys._ -object ArtifactsTasks { +private[sbtcoursiershared] object ArtifactsTasks { def coursierPublicationsTask( configsMap: (sbt.librarymanagement.Configuration, Configuration)* @@ -97,18 +96,14 @@ object ArtifactsTasks { def artifactPublication(artifact: sbt.Artifact) = { - val name = FromSbt.sbtCrossVersionName( - artifact.name, - projId.crossVersion, - sv, - sbv - ) + val name = CrossVersion(projId.crossVersion, sv, sbv) + .fold(artifact.name)(_(artifact.name)) Publication( name, Type(artifact.`type`), Extension(artifact.extension), - artifact.classifier.fold(Classifier.empty)(Classifier(_)) + artifact.classifier.fold(Classifier(""))(Classifier(_)) ) } 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 49bacf29a..e0744df52 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 @@ -1,18 +1,61 @@ package coursier.sbtcoursiershared -import coursier.core._ -import coursier.credentials.DirectCredentials -import coursier.lmcoursier._ +import lmcoursier.definitions.{Attributes, Classifier, Configuration, Dependency, Info, Module, ModuleName, Organization, Project, Type} +import lmcoursier.{FallbackDependency, FromSbt, Inputs} import coursier.sbtcoursiershared.SbtCoursierShared.autoImport._ import coursier.sbtcoursiershared.Structure._ -import sbt.Def +import lmcoursier.credentials.DirectCredentials +import sbt.{Def, SettingKey} import sbt.Keys._ +import sbt.librarymanagement.{InclExclRule, ModuleID} +import sbt.util.Logger import scala.collection.JavaConverters._ +import scala.language.reflectiveCalls object InputsTasks { - def coursierProjectTask: Def.Initialize[sbt.Task[Project]] = + lazy val actualExcludeDependencies = + try { + sbt.Keys + .asInstanceOf[{ def allExcludeDependencies: SettingKey[scala.Seq[InclExclRule]] }] + .allExcludeDependencies + } catch { + case _: NoSuchMethodException => + excludeDependencies + } + + 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.configExtends(configurations) + + val proj = FromSbt.project( + projId, + dependencies, + configMap, + sv, + sbv + ) + + proj.copy( + dependencies = proj.dependencies.map { + case (config, dep) => + (config, dep.copy(exclusions = dep.exclusions ++ exclusions0)) + } + ) + } + + private[sbtcoursiershared] def coursierProjectTask: Def.Initialize[sbt.Task[Project]] = Def.taskDyn { val state = sbt.Keys.state.value @@ -21,10 +64,10 @@ object InputsTasks { val allDependenciesTask = allDependencies.in(projectRef).get(state) Def.task { - Inputs.coursierProject( + coursierProject0( projectID.in(projectRef).get(state), allDependenciesTask.value, - excludeDependencies.in(projectRef).get(state), + actualExcludeDependencies.in(projectRef).get(state), // should projectID.configurations be used instead? ivyConfigurations.in(projectRef).get(state), scalaVersion.in(projectRef).get(state), @@ -63,7 +106,7 @@ object InputsTasks { val configurations = desc .getModuleConfigurations .toVector - .flatMap(s => coursier.ivy.IvyXml.mappings(s)) + .flatMap(Inputs.ivyXmlMappings) def dependency(conf: Configuration, attr: Attributes) = Dependency( module, @@ -80,13 +123,13 @@ object InputsTasks { val artifacts = desc.getAllDependencyArtifacts val m = artifacts.toVector.flatMap { art => - val attr = Attributes(Type(art.getType), Classifier.empty) + val attr = Attributes(Type(art.getType), Classifier("")) art.getConfigurations.map(Configuration(_)).toVector.map { conf => conf -> attr } }.toMap - c => m.getOrElse(c, Attributes.empty) + c => m.getOrElse(c, Attributes(Type(""), Classifier(""))) } configurations.map { @@ -95,7 +138,7 @@ object InputsTasks { } } - def coursierInterProjectDependenciesTask: Def.Initialize[sbt.Task[Seq[Project]]] = + private[sbtcoursiershared] def coursierInterProjectDependenciesTask: Def.Initialize[sbt.Task[Seq[Project]]] = Def.taskDyn { val state = sbt.Keys.state.value @@ -141,17 +184,10 @@ object InputsTasks { v.getModuleRevisionId.getRevision, deps, configurations, - None, - Nil, - Nil, Nil, None, - None, - None, - relocated = false, - None, Nil, - Info.empty + Info("", "", Nil, Nil, None) ) } @@ -159,7 +195,7 @@ object InputsTasks { } } - def coursierFallbackDependenciesTask: Def.Initialize[sbt.Task[Seq[FallbackDependency]]] = + private[sbtcoursiershared] def coursierFallbackDependenciesTask: Def.Initialize[sbt.Task[Seq[FallbackDependency]]] = Def.taskDyn { val state = sbt.Keys.state.value diff --git a/modules/sbt-coursier-shared/src/main/scala/coursier/sbtcoursiershared/IvyXml.scala b/modules/sbt-coursier-shared/src/main/scala/coursier/sbtcoursiershared/IvyXml.scala index 95dd98c62..dcb6c90b3 100644 --- a/modules/sbt-coursier-shared/src/main/scala/coursier/sbtcoursiershared/IvyXml.scala +++ b/modules/sbt-coursier-shared/src/main/scala/coursier/sbtcoursiershared/IvyXml.scala @@ -3,7 +3,7 @@ package coursier.sbtcoursiershared import java.nio.charset.StandardCharsets.UTF_8 import java.nio.file.Files -import coursier.core.{Configuration, Project} +import lmcoursier.definitions.{Configuration, Project} import org.apache.ivy.core.module.id.ModuleRevisionId import sbt.{Def, Setting, Task, TaskKey} import sbt.internal.librarymanagement.IvySbt @@ -14,7 +14,7 @@ import scala.xml.{Node, PrefixedAttribute} object IvyXml { - def rawContent( + private[sbtcoursiershared] def rawContent( currentProject: Project, shadedConfigOpt: Option[Configuration] ): String = { @@ -32,7 +32,7 @@ object IvyXml { } // These are required for publish to be fine, later on. - def writeFiles( + private def writeFiles( currentProject: Project, shadedConfigOpt: Option[Configuration], ivySbt: IvySbt, @@ -63,13 +63,13 @@ object IvyXml { Files.write(cacheIvyPropertiesFile.toPath, Array.emptyByteArray) } - def content(project0: Project, shadedConfigOpt: Option[Configuration]): Node = { + private def content(project0: Project, shadedConfigOpt: Option[Configuration]): Node = { val filterOutDependencies = shadedConfigOpt.toSet[Configuration].flatMap { shadedConfig => project0 .dependencies - .collect { case (`shadedConfig`, dep) => dep } + .collect { case (conf, dep) if conf.value == shadedConfig.value => dep } } val project: Project = project0.copy( @@ -104,8 +104,8 @@ object IvyXml { } % infoAttrs val confElems = project.configurations.toVector.collect { - case (name, extends0) if !shadedConfigOpt.contains(name) => - val extends1 = shadedConfigOpt.fold(extends0)(c => extends0.filter(_ != c)) + case (name, extends0) if !shadedConfigOpt.exists(_.value == name.value) => + val extends1 = shadedConfigOpt.fold(extends0)(c => extends0.filter(_.value != c.value)) val n = if (extends1.nonEmpty) n % .attributes @@ -122,7 +122,7 @@ object IvyXml { case (pub, configs) => val n = - if (pub.classifier.nonEmpty) + if (pub.classifier.value.nonEmpty) n % .attributes else n @@ -155,7 +155,7 @@ object IvyXml { } - def makeIvyXmlBefore[T]( + private def makeIvyXmlBefore[T]( task: TaskKey[T], shadedConfigOpt: Option[Configuration] ): Setting[Task[T]] = @@ -170,7 +170,7 @@ object IvyXml { val publications = coursierPublications.value proj.copy(publications = publications) } - IvyXml.writeFiles(currentProject, shadedConfigOpt, sbt.Keys.ivySbt.value, sbt.Keys.streams.value.log) + writeFiles(currentProject, shadedConfigOpt, sbt.Keys.ivySbt.value, sbt.Keys.streams.value.log) } else Def.task(()) @@ -194,6 +194,6 @@ object IvyXml { def generateIvyXmlSettings( shadedConfigOpt: Option[Configuration] = None ): Seq[Setting[_]] = - (needsIvyXml ++ needsIvyXmlLocal).map(IvyXml.makeIvyXmlBefore(_, shadedConfigOpt)) + (needsIvyXml ++ needsIvyXmlLocal).map(makeIvyXmlBefore(_, shadedConfigOpt)) } diff --git a/modules/sbt-coursier-shared/src/main/scala/coursier/sbtcoursiershared/RepositoriesTasks.scala b/modules/sbt-coursier-shared/src/main/scala/coursier/sbtcoursiershared/RepositoriesTasks.scala index 1abb9c9de..df950b336 100644 --- a/modules/sbt-coursier-shared/src/main/scala/coursier/sbtcoursiershared/RepositoriesTasks.scala +++ b/modules/sbt-coursier-shared/src/main/scala/coursier/sbtcoursiershared/RepositoriesTasks.scala @@ -1,13 +1,52 @@ package coursier.sbtcoursiershared -import coursier.lmcoursier._ import coursier.sbtcoursiershared.SbtCoursierShared.autoImport._ import coursier.sbtcoursiershared.Structure._ import sbt.{Classpaths, Def} import sbt.Keys._ -import sbt.librarymanagement.Resolver +import sbt.librarymanagement.{Resolver, URLRepository} -object RepositoriesTasks { +private[sbtcoursiershared] object RepositoriesTasks { + + private object Resolvers { + + private val slowReposBase = Seq( + "https://repo.typesafe.com/", + "https://repo.scala-sbt.org/", + "http://repo.typesafe.com/", + "http://repo.scala-sbt.org/" + ) + + private val fastReposBase = Seq( + "http://repo1.maven.org/", + "https://repo1.maven.org/" + ) + + private def url(res: Resolver): Option[String] = + res match { + case m: sbt.librarymanagement.MavenRepository => + Some(m.root) + case u: URLRepository => + u.patterns.artifactPatterns.headOption + .orElse(u.patterns.ivyPatterns.headOption) + case _ => + None + } + + private def fastRepo(res: Resolver): Boolean = + url(res).exists(u => fastReposBase.exists(u.startsWith)) + + private def slowRepo(res: Resolver): Boolean = + url(res).exists(u => slowReposBase.exists(u.startsWith)) + + def reorderResolvers(resolvers: Seq[Resolver]): Seq[Resolver] = + if (resolvers.exists(fastRepo) && resolvers.exists(slowRepo)) { + val (slow, other) = resolvers.partition(slowRepo) + other ++ slow + } else + resolvers + + } private def resultTask(bootResOpt: Option[Seq[Resolver]], overrideFlag: Boolean): Def.Initialize[sbt.Task[Seq[Resolver]]] = bootResOpt.filter(_ => overrideFlag) match { @@ -41,7 +80,7 @@ object RepositoriesTasks { val result0 = if (reorderResolvers) - ResolutionParams.reorderResolvers(result) + Resolvers.reorderResolvers(result) else result 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 c148091d3..e273af4d3 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 @@ -2,11 +2,11 @@ package coursier.sbtcoursiershared import java.io.File -import coursier.cache.{CacheDefaults, CacheLogger} import coursier.{Credentials => LegacyCredentials} -import coursier.core.{Configuration, Project, Publication} -import coursier.credentials.Credentials -import coursier.lmcoursier.{FallbackDependency, SbtCoursierCache} +import lmcoursier.credentials.Credentials +import lmcoursier.{CoursierDependencyResolution, FallbackDependency} +import lmcoursier.definitions.{CacheLogger, Configuration, Project, Publication} +import lmcoursier.internal.SbtCoursierCache import sbt.{AutoPlugin, Classpaths, Compile, Setting, TaskKey, Test, settingKey, taskKey} import sbt.Keys._ import sbt.librarymanagement.{Resolver, URLRepository} @@ -64,7 +64,7 @@ object SbtCoursierShared extends AutoPlugin { coursierReorderResolvers := true, coursierKeepPreloaded := false, coursierLogger := None, - coursierCache := CacheDefaults.location + coursierCache := CoursierDependencyResolution.defaultCacheLocation ) private val pluginIvySnapshotsBase = Resolver.SbtRepositoryRoot.stripSuffix("/") + "/ivy-snapshots" 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 index 35e7da556..6a460e0be 100644 --- a/modules/sbt-coursier-shared/src/test/scala/coursier/sbtcoursiershared/IvyXmlTests.scala +++ b/modules/sbt-coursier-shared/src/test/scala/coursier/sbtcoursiershared/IvyXmlTests.scala @@ -1,7 +1,6 @@ package coursier.sbtcoursiershared -import coursier.core.Configuration -import coursier.{Info, Module, Project, moduleNameString, organizationString} +import lmcoursier.definitions.{Configuration, Info, Module, ModuleName, Organization, Project} import utest._ object IvyXmlTests extends TestSuite { @@ -10,23 +9,16 @@ object IvyXmlTests extends TestSuite { "no truncation" - { val project = Project( - Module(org"org", name"name"), + 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 ), - None, - Nil, - Nil, Nil, None, - None, - None, - relocated = false, - None, Nil, - Info.empty + Info("", "", Nil, Nil, None) ) val content = IvyXml.rawContent(project, None) 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 c62f90fa0..32250daf3 100644 --- a/modules/sbt-coursier/src/main/scala/coursier/sbtcoursier/ArtifactsTasks.scala +++ b/modules/sbt-coursier/src/main/scala/coursier/sbtcoursier/ArtifactsTasks.scala @@ -5,10 +5,11 @@ import java.io.File import coursier.Artifact import coursier.cache.FileCache import coursier.core._ -import coursier.lmcoursier._ +import lmcoursier.internal.{ArtifactsParams, ArtifactsRun} import coursier.sbtcoursier.Keys._ import coursier.sbtcoursiershared.InputsTasks.credentialsTask import coursier.sbtcoursiershared.SbtCoursierShared.autoImport.{coursierCache, coursierLogger} +import lmcoursier.definitions.ToCoursier import sbt.Def import sbt.Keys._ @@ -45,8 +46,8 @@ object ArtifactsTasks { val cachePolicies = coursierCachePolicies.value val ttl = coursierTtl.value val cache = coursierCache.value - val createLogger = coursierLogger.value - val credentials = credentialsTask.value + val createLogger = coursierLogger.value.map(ToCoursier.cacheLogger) + val credentials = credentialsTask.value.map(ToCoursier.credentials) val log = streams.value.log 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 e76f84d8c..953fa2df0 100644 --- a/modules/sbt-coursier/src/main/scala/coursier/sbtcoursier/CoursierPlugin.scala +++ b/modules/sbt-coursier/src/main/scala/coursier/sbtcoursier/CoursierPlugin.scala @@ -1,6 +1,6 @@ package coursier.sbtcoursier -import coursier.cache.{CacheDefaults, CachePolicy} +import coursier.cache.CacheDefaults import coursier.core.{Configuration, ResolutionProcess} import coursier.sbtcoursiershared.SbtCoursierShared import sbt.{Cache => _, Configuration => _, _} 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 2ff2b5256..29bd26a59 100644 --- a/modules/sbt-coursier/src/main/scala/coursier/sbtcoursier/DisplayTasks.scala +++ b/modules/sbt-coursier/src/main/scala/coursier/sbtcoursier/DisplayTasks.scala @@ -1,7 +1,7 @@ package coursier.sbtcoursier import coursier.core._ -import coursier.lmcoursier._ +import lmcoursier.definitions.ToCoursier import coursier.parse.ModuleParser import coursier.sbtcoursier.Keys._ import coursier.sbtcoursiershared.SbtCoursierShared.autoImport._ @@ -26,7 +26,7 @@ object DisplayTasks { val sv = scalaVersion.value val sbv = scalaBinaryVersion.value val cm = coursierSbtClassifiersModule.value - FromSbt.sbtClassifiersProject(cm, sv, sbv) + SbtCoursierFromSbt.sbtClassifiersProject(cm, sv, sbv) } else Def.task { @@ -40,14 +40,14 @@ object DisplayTasks { Def.task { val currentProject = currentProjectTask.value val classifiersRes = coursierSbtClassifiersResolution.value - Map(currentProject.configurations.keySet -> classifiersRes) + Map(currentProject.configurations.keySet.map(ToCoursier.configuration) -> classifiersRes) } else Def.task(coursierResolutions.value) Def.task { - val currentProject = currentProjectTask.value + val currentProject = ToCoursier.project(currentProjectTask.value) val config = Configuration(configuration.value.name) val configs = coursierConfigurations.value 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 f9f6c54d8..8f743a4fc 100644 --- a/modules/sbt-coursier/src/main/scala/coursier/sbtcoursier/InputsTasks.scala +++ b/modules/sbt-coursier/src/main/scala/coursier/sbtcoursier/InputsTasks.scala @@ -2,7 +2,8 @@ package coursier.sbtcoursier import coursier.ProjectCache import coursier.core._ -import coursier.lmcoursier._ +import lmcoursier._ +import lmcoursier.definitions.ToCoursier import coursier.sbtcoursier.Keys._ import coursier.sbtcoursiershared.SbtCoursierShared.autoImport._ import coursier.sbtcoursiershared.Structure._ @@ -16,13 +17,19 @@ object InputsTasks { shadedConfig: Option[(String, Configuration)] ): Def.Initialize[sbt.Task[Map[Configuration, Set[Configuration]]]] = Def.task { - Inputs.coursierConfigurations(ivyConfigurations.value, shadedConfig) + Inputs.coursierConfigurations(ivyConfigurations.value, shadedConfig.map { + case (from, to) => + (from, lmcoursier.definitions.Configuration(to.value)) + }).map { + case (k, v) => + ToCoursier.configuration(k) -> v.map(ToCoursier.configuration) + } } def ivyGraphsTask: Def.Initialize[sbt.Task[Seq[Set[Configuration]]]] = Def.task { val p = coursierProject.value - Inputs.ivyGraphs(p.configurations) + Inputs.ivyGraphs(p.configurations).map(_.map(ToCoursier.configuration)) } def parentProjectCacheTask: Def.Initialize[sbt.Task[Map[Seq[sbt.librarymanagement.Resolver], Seq[coursier.ProjectCache]]]] = 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 45a13eb85..51ffd8546 100644 --- a/modules/sbt-coursier/src/main/scala/coursier/sbtcoursier/ResolutionTasks.scala +++ b/modules/sbt-coursier/src/main/scala/coursier/sbtcoursier/ResolutionTasks.scala @@ -4,7 +4,9 @@ import coursier.ProjectCache import coursier.cache.FileCache import coursier.core._ import coursier.internal.Typelevel -import coursier.lmcoursier._ +import lmcoursier.definitions.ToCoursier +import lmcoursier.{FallbackDependency, FromSbt} +import lmcoursier.internal.{InterProjectRepository, ResolutionParams, ResolutionRun, Resolvers} import coursier.sbtcoursier.Keys._ import coursier.sbtcoursiershared.InputsTasks.credentialsTask import coursier.sbtcoursiershared.SbtCoursierShared.autoImport._ @@ -23,7 +25,7 @@ object ResolutionTasks { val sv = scalaVersion.value val sbv = scalaBinaryVersion.value val cm = coursierSbtClassifiersModule.value - val proj = FromSbt.sbtClassifiersProject(cm, sv, sbv) + val proj = ToCoursier.project(SbtCoursierFromSbt.sbtClassifiersProject(cm, sv, sbv)) val fallbackDeps = FromSbt.fallbackDependencies( cm.dependencies, @@ -36,7 +38,8 @@ object ResolutionTasks { else Def.task { val baseConfigGraphs = coursierConfigGraphs.value - (coursierProject.value.copy(publications = coursierPublications.value), coursierFallbackDependencies.value, baseConfigGraphs) + val publications = coursierPublications.value + (ToCoursier.project(coursierProject.value.copy(publications = publications)), coursierFallbackDependencies.value, baseConfigGraphs) } val resolversTask = @@ -51,7 +54,7 @@ object ResolutionTasks { val sv = scalaVersion.value val sbv = scalaBinaryVersion.value - val interProjectDependencies = coursierInterProjectDependencies.value + val interProjectDependencies = coursierInterProjectDependencies.value.map(ToCoursier.project) val parallelDownloads = coursierParallelDownloads.value val checksums = coursierChecksums.value @@ -59,7 +62,7 @@ object ResolutionTasks { val cachePolicies = coursierCachePolicies.value val ttl = coursierTtl.value val cache = coursierCache.value - val createLogger = coursierLogger.value + val createLogger = coursierLogger.value.map(ToCoursier.cacheLogger) val log = streams.value.log @@ -69,6 +72,10 @@ object ResolutionTasks { val userForceVersions = dependencyOverrides .value .map(FromSbt.moduleVersion(_, sv, sbv)) + .map { + case (k, v) => + ToCoursier.module(k) -> v + } .toMap val verbosityLevel = coursierVerbosity.value @@ -91,7 +98,7 @@ object ResolutionTasks { // TODO Warn about possible duplicated modules from source repositories? - val credentials = credentialsTask.value + val credentials = credentialsTask.value.map(ToCoursier.credentials) val parentProjectCache: ProjectCache = coursierParentProjectCache.value .get(resolvers) @@ -100,11 +107,18 @@ object ResolutionTasks { val mainRepositories = resolvers .flatMap { resolver => - FromSbt.repository( + Resolvers.repository( resolver, ivyProperties, log, - authenticationByRepositoryId.get(resolver.name) + authenticationByRepositoryId.get(resolver.name).map { a => + Authentication( + a.user, + a.password, + a.optional, + a.realmOpt + ) + } ) } diff --git a/modules/sbt-coursier/src/main/scala/coursier/sbtcoursier/SbtCoursierFromSbt.scala b/modules/sbt-coursier/src/main/scala/coursier/sbtcoursier/SbtCoursierFromSbt.scala new file mode 100644 index 000000000..e9768f57a --- /dev/null +++ b/modules/sbt-coursier/src/main/scala/coursier/sbtcoursier/SbtCoursierFromSbt.scala @@ -0,0 +1,37 @@ +package coursier.sbtcoursier + +import lmcoursier.FromSbt +import lmcoursier.definitions.Configuration +import sbt.librarymanagement.GetClassifiersModule + +object SbtCoursierFromSbt { + + def sbtClassifiersProject( + cm: GetClassifiersModule, + scalaVersion: String, + scalaBinaryVersion: String + ) = { + + val p = FromSbt.project( + cm.id, + cm.dependencies, + cm.configurations.map(cfg => Configuration(cfg.name) -> cfg.extendsConfigs.map(c => Configuration(c.name))).toMap, + scalaVersion, + scalaBinaryVersion + ) + + // for w/e reasons, the dependencies sometimes don't land in the right config above + // this is a loose attempt at fixing that + cm.configurations match { + case Seq(cfg) => + p.copy( + dependencies = p.dependencies.map { + case (_, d) => (Configuration(cfg.name), d) + } + ) + case _ => + p + } + } + +} 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 7ae6e983a..2c0e8df3f 100644 --- a/modules/sbt-coursier/src/main/scala/coursier/sbtcoursier/UpdateTasks.scala +++ b/modules/sbt-coursier/src/main/scala/coursier/sbtcoursier/UpdateTasks.scala @@ -1,7 +1,8 @@ package coursier.sbtcoursier import coursier.core._ -import coursier.lmcoursier._ +import lmcoursier.definitions.ToCoursier +import lmcoursier.internal.{SbtBootJars, SbtCoursierCache, UpdateParams, UpdateRun} import coursier.sbtcoursier.Keys._ import coursier.sbtcoursiershared.SbtCoursierShared.autoImport._ import sbt.Def @@ -22,13 +23,12 @@ object UpdateTasks { Def.task { val sv = scalaVersion.value val sbv = scalaBinaryVersion.value - FromSbt.sbtClassifiersProject(coursierSbtClassifiersModule.value, sv, sbv) + SbtCoursierFromSbt.sbtClassifiersProject(coursierSbtClassifiersModule.value, sv, sbv) } else Def.task { val proj = coursierProject.value val publications = coursierPublications.value - proj.copy(publications = publications) } @@ -103,7 +103,7 @@ object UpdateTasks { val verbosityLevel = coursierVerbosity.value - val dependencies = currentProjectTask.value.dependencies + val dependencies = ToCoursier.project(currentProjectTask.value).dependencies val res = resTask.value val key = SbtCoursierCache.ReportKey( @@ -134,10 +134,7 @@ object UpdateTasks { sbtBootJarOverrides ) - val rep = - Lock.lock.synchronized { - UpdateRun.update(params, verbosityLevel, log) - } + val rep = UpdateRun.update(params, verbosityLevel, log) SbtCoursierCache.default.putReport(key, rep) rep } diff --git a/modules/sbt-coursier/src/sbt-test/shared-2/s3/build.sbt b/modules/sbt-coursier/src/sbt-test/sbt-coursier/s3/build.sbt similarity index 93% rename from modules/sbt-coursier/src/sbt-test/shared-2/s3/build.sbt rename to modules/sbt-coursier/src/sbt-test/sbt-coursier/s3/build.sbt index fcb2f81c7..77b86764a 100644 --- a/modules/sbt-coursier/src/sbt-test/shared-2/s3/build.sbt +++ b/modules/sbt-coursier/src/sbt-test/sbt-coursier/s3/build.sbt @@ -23,9 +23,9 @@ check := { // Have Coursier SBT Plugin Parse the SBT Resolvers val parsedCoursierResolvers: Seq[coursier.core.Repository] = sbtResolvers.flatMap{ sbtResolver: sbt.librarymanagement.Resolver => - coursier.lmcoursier.FromSbt.repository( + lmcoursier.internal.Resolvers.repository( resolver = sbtResolver, - ivyProperties = coursier.lmcoursier.ResolutionParams.defaultIvyProperties(), + ivyProperties = lmcoursier.internal.ResolutionParams.defaultIvyProperties(), log = s.log, authentication = None, ) diff --git a/modules/sbt-coursier/src/sbt-test/shared-2/s3/project/build.properties b/modules/sbt-coursier/src/sbt-test/sbt-coursier/s3/project/build.properties similarity index 100% rename from modules/sbt-coursier/src/sbt-test/shared-2/s3/project/build.properties rename to modules/sbt-coursier/src/sbt-test/sbt-coursier/s3/project/build.properties diff --git a/modules/sbt-coursier/src/sbt-test/shared-2/s3/project/extra.sbt b/modules/sbt-coursier/src/sbt-test/sbt-coursier/s3/project/extra.sbt similarity index 100% rename from modules/sbt-coursier/src/sbt-test/shared-2/s3/project/extra.sbt rename to modules/sbt-coursier/src/sbt-test/sbt-coursier/s3/project/extra.sbt diff --git a/modules/sbt-coursier/src/sbt-test/shared-2/s3/project/plugins.sbt b/modules/sbt-coursier/src/sbt-test/sbt-coursier/s3/project/plugins.sbt similarity index 100% rename from modules/sbt-coursier/src/sbt-test/shared-2/s3/project/plugins.sbt rename to modules/sbt-coursier/src/sbt-test/sbt-coursier/s3/project/plugins.sbt diff --git a/modules/sbt-coursier/src/sbt-test/shared-2/s3/project/project/plugins.sbt b/modules/sbt-coursier/src/sbt-test/sbt-coursier/s3/project/project/plugins.sbt similarity index 100% rename from modules/sbt-coursier/src/sbt-test/shared-2/s3/project/project/plugins.sbt rename to modules/sbt-coursier/src/sbt-test/sbt-coursier/s3/project/project/plugins.sbt diff --git a/modules/sbt-coursier/src/sbt-test/shared-2/s3/src/main/scala/Foo.scala b/modules/sbt-coursier/src/sbt-test/sbt-coursier/s3/src/main/scala/Foo.scala similarity index 100% rename from modules/sbt-coursier/src/sbt-test/shared-2/s3/src/main/scala/Foo.scala rename to modules/sbt-coursier/src/sbt-test/sbt-coursier/s3/src/main/scala/Foo.scala diff --git a/modules/sbt-coursier/src/sbt-test/shared-2/s3/test b/modules/sbt-coursier/src/sbt-test/sbt-coursier/s3/test similarity index 100% rename from modules/sbt-coursier/src/sbt-test/shared-2/s3/test rename to modules/sbt-coursier/src/sbt-test/sbt-coursier/s3/test diff --git a/modules/sbt-coursier/src/sbt-test/shared-1/all-exclude-dependencies/build.sbt b/modules/sbt-coursier/src/sbt-test/shared-1/all-exclude-dependencies/build.sbt new file mode 100644 index 000000000..8c2b3c509 --- /dev/null +++ b/modules/sbt-coursier/src/sbt-test/shared-1/all-exclude-dependencies/build.sbt @@ -0,0 +1,11 @@ + +scalaVersion := "2.11.8" + +organization := "io.get-coursier.test" +name := "sbt-coursier-all-exclude-dependencies" +version := "0.1.0-SNAPSHOT" + +libraryDependencies += "com.github.alexarchambault" %% "argonaut-shapeless_6.1" % "1.0.0-RC1" + +allExcludeDependencies += sbt.ExclusionRule("com.chuusai", "shapeless_2.11") +allExcludeDependencies += "io.argonaut" %% "argonaut" 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 new file mode 100755 index 000000000..6cada6f8b Binary files /dev/null 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/project/build.properties b/modules/sbt-coursier/src/sbt-test/shared-1/all-exclude-dependencies/project/build.properties new file mode 100644 index 000000000..3149e6ba1 --- /dev/null +++ b/modules/sbt-coursier/src/sbt-test/shared-1/all-exclude-dependencies/project/build.properties @@ -0,0 +1 @@ +sbt.version=1.3.0-M2 diff --git a/modules/sbt-coursier/src/sbt-test/shared-1/all-exclude-dependencies/project/plugins.sbt b/modules/sbt-coursier/src/sbt-test/shared-1/all-exclude-dependencies/project/plugins.sbt new file mode 100644 index 000000000..71a44ffd3 --- /dev/null +++ b/modules/sbt-coursier/src/sbt-test/shared-1/all-exclude-dependencies/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-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 new file mode 100644 index 000000000..1bc056610 --- /dev/null +++ b/modules/sbt-coursier/src/sbt-test/shared-1/all-exclude-dependencies/src/main/scala/Main.scala @@ -0,0 +1,32 @@ +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" + ) + + 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 new file mode 100644 index 000000000..21084fb8e --- /dev/null +++ b/modules/sbt-coursier/src/sbt-test/shared-1/all-exclude-dependencies/test @@ -0,0 +1,5 @@ +$ delete output +> run +$ exists output +> publishLocal +$ exec java -jar coursier launch io.get-coursier.test:sbt-coursier-all-exclude-dependencies_2.11:0.1.0-SNAPSHOT diff --git a/modules/sbt-coursier/src/sbt-test/shared-1/clean/project/Helper.scala b/modules/sbt-coursier/src/sbt-test/shared-1/clean/project/Helper.scala index b567f06bf..308434a75 100644 --- a/modules/sbt-coursier/src/sbt-test/shared-1/clean/project/Helper.scala +++ b/modules/sbt-coursier/src/sbt-test/shared-1/clean/project/Helper.scala @@ -3,6 +3,6 @@ package coursier object Helper { def checkEmpty(): Boolean = - coursier.lmcoursier.SbtCoursierCache.default.isEmpty + lmcoursier.internal.SbtCoursierCache.default.isEmpty } diff --git a/modules/sbt-coursier/src/sbt-test/shared-1/credentials-from-file/build.sbt b/modules/sbt-coursier/src/sbt-test/shared-1/credentials-from-file/build.sbt index d69b7f7dc..4f809c617 100644 --- a/modules/sbt-coursier/src/sbt-test/shared-1/credentials-from-file/build.sbt +++ b/modules/sbt-coursier/src/sbt-test/shared-1/credentials-from-file/build.sbt @@ -14,7 +14,7 @@ coursierExtraCredentials += { """.stripMargin val dest = baseDirectory.in(ThisBuild).value / "project" / "target" / "cred" Files.write(dest.toPath, content.getBytes("UTF-8")) - coursier.credentials.Credentials(dest) + lmcoursier.credentials.Credentials(dest) } libraryDependencies += "com.abc" % "test" % "0.1" diff --git a/modules/sbt-coursier/src/sbt-test/shared-1/credentials-global/global/build.sbt b/modules/sbt-coursier/src/sbt-test/shared-1/credentials-global/global/build.sbt index 59c5f99be..ee97bd987 100644 --- a/modules/sbt-coursier/src/sbt-test/shared-1/credentials-global/global/build.sbt +++ b/modules/sbt-coursier/src/sbt-test/shared-1/credentials-global/global/build.sbt @@ -1,4 +1,4 @@ -coursierExtraCredentials += coursier.credentials.Credentials( +coursierExtraCredentials += lmcoursier.credentials.Credentials( uri(sys.env("TEST_REPOSITORY")).getHost, sys.env("TEST_REPOSITORY_USER"), sys.env("TEST_REPOSITORY_PASSWORD") diff --git a/modules/sbt-coursier/src/sbt-test/shared-1/credentials/build.sbt b/modules/sbt-coursier/src/sbt-test/shared-1/credentials/build.sbt index 4f1076d20..00f8aaec5 100644 --- a/modules/sbt-coursier/src/sbt-test/shared-1/credentials/build.sbt +++ b/modules/sbt-coursier/src/sbt-test/shared-1/credentials/build.sbt @@ -2,7 +2,7 @@ scalaVersion := "2.11.8" resolvers += "authenticated" at sys.env("TEST_REPOSITORY") -coursierExtraCredentials += coursier.credentials.Credentials( +coursierExtraCredentials += lmcoursier.credentials.Credentials( uri(sys.env("TEST_REPOSITORY")).getHost, sys.env("TEST_REPOSITORY_USER"), sys.env("TEST_REPOSITORY_PASSWORD") diff --git a/modules/sbt-coursier/src/sbt-test/shared-1/logger/build.sbt b/modules/sbt-coursier/src/sbt-test/shared-1/logger/build.sbt index a9c823b68..6271170aa 100644 --- a/modules/sbt-coursier/src/sbt-test/shared-1/logger/build.sbt +++ b/modules/sbt-coursier/src/sbt-test/shared-1/logger/build.sbt @@ -14,7 +14,7 @@ coursierLogger := { } val cacheFile = coursierCache.value - val logger = new coursier.cache.CacheLogger { + val logger = new lmcoursier.definitions.CacheLogger { override def init(sizeHint: Option[Int]): Unit = { logStream = new java.io.PrintStream( new java.io.FileOutputStream(logFile.value, true) diff --git a/modules/sbt-coursier/src/sbt-test/shared-2/update-sbt-classifiers/build.sbt b/modules/sbt-coursier/src/sbt-test/shared-2/update-sbt-classifiers/build.sbt index 0c59d622c..2dac5446b 100644 --- a/modules/sbt-coursier/src/sbt-test/shared-2/update-sbt-classifiers/build.sbt +++ b/modules/sbt-coursier/src/sbt-test/shared-2/update-sbt-classifiers/build.sbt @@ -32,13 +32,19 @@ updateSbtClassifiersCheck := { .toSeq .flatten - def ensureHasArtifact(org: String, name: String) = + def ensureHasArtifact(orgName: (String, String)*) = assert( - artifacts(org, name).exists(_._2.getName.endsWith("-sources.jar")), - s"$org:$name not found" + orgName.exists { + case (org, name) => + artifacts(org, name).exists(_._2.getName.endsWith("-sources.jar")) + }, + s"Any of $orgName not found" ) - ensureHasArtifact("org.scala-lang", "scala-library") - ensureHasArtifact("io.get-coursier", "coursier-core_" + scalaBinaryVersion.value) - ensureHasArtifact("io.get-coursier", "lm-coursier_" + scalaBinaryVersion.value) + ensureHasArtifact("org.scala-lang" -> "scala-library") + ensureHasArtifact("org.scala-lang.modules" -> s"scala-xml_${scalaBinaryVersion.value}") + ensureHasArtifact( + "io.get-coursier" -> s"lm-coursier_${scalaBinaryVersion.value}", + "io.get-coursier" -> s"lm-coursier-shaded_${scalaBinaryVersion.value}" + ) } diff --git a/modules/sbt-lm-coursier/src/main/scala/coursier/sbtlmcoursier/LmCoursierPlugin.scala b/modules/sbt-lm-coursier/src/main/scala/coursier/sbtlmcoursier/LmCoursierPlugin.scala index 1a16c37e4..995d86c1b 100644 --- a/modules/sbt-lm-coursier/src/main/scala/coursier/sbtlmcoursier/LmCoursierPlugin.scala +++ b/modules/sbt-lm-coursier/src/main/scala/coursier/sbtlmcoursier/LmCoursierPlugin.scala @@ -1,15 +1,17 @@ package coursier.sbtlmcoursier -import coursier.core.Classifier -import coursier.lmcoursier.{CoursierConfiguration, CoursierDependencyResolution, Inputs} +import lmcoursier.definitions.Authentication +import lmcoursier.{CoursierConfiguration, CoursierDependencyResolution, Inputs} import coursier.sbtcoursiershared.InputsTasks.credentialsTask -import coursier.sbtcoursiershared.SbtCoursierShared +import coursier.sbtcoursiershared.{InputsTasks, SbtCoursierShared} import sbt.{AutoPlugin, Classpaths, Def, Setting, Task, taskKey} import sbt.Project.inTask import sbt.KeyRanks.DTask -import sbt.Keys.{appConfiguration, autoScalaLibrary, classpathTypes, dependencyResolution, excludeDependencies, scalaBinaryVersion, scalaModuleInfo, scalaOrganization, scalaVersion, streams, updateClassifiers, updateSbtClassifiers} +import sbt.Keys.{appConfiguration, autoScalaLibrary, classpathTypes, dependencyResolution, scalaBinaryVersion, scalaModuleInfo, scalaOrganization, scalaVersion, streams, updateClassifiers, updateSbtClassifiers} import sbt.librarymanagement.DependencyResolution +import scala.language.reflectiveCalls + object LmCoursierPlugin extends AutoPlugin { import SbtCoursierShared.autoImport._ @@ -67,9 +69,9 @@ object LmCoursierPlugin extends AutoPlugin { coursierSbtResolvers else coursierRecursiveResolvers - val classifiersTask: sbt.Def.Initialize[sbt.Task[Option[Seq[Classifier]]]] = + val classifiersTask: sbt.Def.Initialize[sbt.Task[Option[Seq[String]]]] = if (withClassifiers && !sbtClassifiers) - Def.task(Some(sbt.Keys.transitiveClassifiers.value.map(Classifier(_)))) + Def.task(Some(sbt.Keys.transitiveClassifiers.value)) else Def.task(None) Def.task { @@ -78,7 +80,7 @@ object LmCoursierPlugin extends AutoPlugin { val scalaVer = scalaVersion.value val interProjectDependencies = coursierInterProjectDependencies.value val excludeDeps = Inputs.exclusions( - excludeDependencies.value, + InputsTasks.actualExcludeDependencies.value, scalaVer, scalaBinaryVersion.value, streams.value.log @@ -87,7 +89,10 @@ object LmCoursierPlugin extends AutoPlugin { val autoScalaLib = autoScalaLibrary.value && scalaModuleInfo.value.forall(_.overrideScalaVersion) val profiles = mavenProfiles.value - val authenticationByRepositoryId = coursierCredentials.value.mapValues(_.authentication) + val authenticationByRepositoryId = coursierCredentials.value.mapValues { c => + val a = c.authentication + Authentication(a.user, a.password, a.optional, a.realmOpt) + } val credentials = credentialsTask.value val createLogger = coursierLogger.value @@ -108,17 +113,17 @@ object LmCoursierPlugin extends AutoPlugin { .withExcludeDependencies( excludeDeps .toVector - .sorted .map { case (o, n) => (o.value, n.value) } + .sorted ) .withAutoScalaLibrary(autoScalaLib) .withSbtScalaJars(sbtBootJars.toVector) .withSbtScalaVersion(sbtScalaVersion) .withSbtScalaOrganization(sbtScalaOrganization) - .withClassifiers(classifiers.toVector.flatten.map(_.value)) + .withClassifiers(classifiers.toVector.flatten) .withHasClassifiers(classifiers.nonEmpty) .withMavenProfiles(profiles.toVector.sorted) .withScalaOrganization(scalaOrg) diff --git a/modules/sbt-shading/src/main/scala/coursier/ShadingPlugin.scala b/modules/sbt-shading/src/main/scala/coursier/ShadingPlugin.scala index f7412dff3..a4a960401 100644 --- a/modules/sbt-shading/src/main/scala/coursier/ShadingPlugin.scala +++ b/modules/sbt-shading/src/main/scala/coursier/ShadingPlugin.scala @@ -4,6 +4,7 @@ import java.io.File import coursier.core.Configuration import coursier.ivy.IvyXml.{mappings => ivyXmlMappings} +import lmcoursier.definitions.{ToCoursier, Configuration => DConfiguration} import coursier.sbtcoursier.{CoursierPlugin, InputsTasks, Keys} import coursier.sbtcoursiershared.{IvyXml, SbtCoursierShared} import sbt.Keys._ @@ -25,7 +26,7 @@ object ShadingPlugin extends AutoPlugin { transitive = true ) - private val baseDependencyConfiguration = Configuration.compile + private val baseDependencyConfiguration = Configuration("compile") val Shaded = sbt.Configuration.of( id = "Shaded", name = "shaded", @@ -101,8 +102,8 @@ object ShadingPlugin extends AutoPlugin { CoursierPlugin.coursierSettings( Some(baseDependencyConfiguration.value -> Configuration(Shaded.name)) ) ++ - IvyXml.generateIvyXmlSettings(Some(Configuration(Shaded.name))) ++ - Seq(SbtCoursierShared.publicationsSetting(Seq(Shading -> Configuration.compile))) ++ + IvyXml.generateIvyXmlSettings(Some(lmcoursier.definitions.Configuration(Shaded.name))) ++ + Seq(SbtCoursierShared.publicationsSetting(Seq(Shading -> DConfiguration("compile")))) ++ CoursierPlugin.treeSettings ++ Seq( configuration := baseSbtConfiguration, // wuw @@ -120,7 +121,7 @@ object ShadingPlugin extends AutoPlugin { unmanagedSourceDirectories := (unmanagedSourceDirectories in Compile).value, toShadeJars := { coursier.Shading.toShadeJars( - coursierProject.in(baseSbtConfiguration).value, + ToCoursier.project(coursierProject.in(baseSbtConfiguration).value), coursierResolutions .in(baseSbtConfiguration) .value diff --git a/project/DatatypeConfig.scala b/project/DatatypeConfig.scala deleted file mode 100644 index 3ddb5261d..000000000 --- a/project/DatatypeConfig.scala +++ /dev/null @@ -1,75 +0,0 @@ -// from https://github.com/sbt/librarymanagement/blob/4a0a6c77bc24f9db139698cab0a6da78d0893a88/project/DatatypeConfig.scala - -import sbt.contraband.ast._ -import sbt.contraband.CodecCodeGen - -object DatatypeConfig { - - /** Extract the only type parameter from a TpeRef */ - def oneArg(tpe: Type): Type = { - val pat = s"""${tpe.removeTypeParameters.name}[<\\[](.+?)[>\\]]""".r - val pat(arg0) = tpe.name - NamedType(arg0 split '.' toList) - } - - /** Extract the two type parameters from a TpeRef */ - def twoArgs(tpe: Type): List[Type] = { - val pat = s"""${tpe.removeTypeParameters.name}[<\\[](.+?), (.+?)[>\\]]""".r - val pat(arg0, arg1) = tpe.name - NamedType(arg0 split '.' toList) :: NamedType(arg1 split '.' toList) :: Nil - } - - /** Codecs that were manually written. */ - val myCodecs: PartialFunction[String, Type => List[String]] = { - case "scala.xml.NodeSeq" => { _ => - "sbt.internal.librarymanagement.formats.NodeSeqFormat" :: Nil - } - - case "org.apache.ivy.plugins.resolver.DependencyResolver" => { _ => - "sbt.internal.librarymanagement.formats.DependencyResolverFormat" :: Nil - } - - case "xsbti.GlobalLock" => { _ => - "sbt.internal.librarymanagement.formats.GlobalLockFormat" :: Nil - } - case "xsbti.Logger" => { _ => - "sbt.internal.librarymanagement.formats.LoggerFormat" :: Nil - } - - case "sbt.librarymanagement.ivy.UpdateOptions" => { _ => - "sbt.librarymanagement.ivy.formats.UpdateOptionsFormat" :: Nil - } - - case "sbt.librarymanagement.LogicalClock" => { _ => - "sbt.internal.librarymanagement.formats.LogicalClockFormats" :: Nil - } - - // TODO: These are handled by BasicJsonProtocol, and sbt-datatype should handle them by default, imo - case "Option" | "Set" | "scala.Vector" => { tpe => - getFormats(oneArg(tpe)) - } - case "Map" | "Tuple2" | "scala.Tuple2" => { tpe => - twoArgs(tpe).flatMap(getFormats) - } - case "Int" | "Long" => { _ => - Nil - } - } - - /** Types for which we don't include the format -- they're just aliases to InclExclRule */ - val excluded = Set("sbt.librarymanagement.InclusionRule", "sbt.librarymanagement.ExclusionRule") - - /** Returns the list of formats required to encode the given `TpeRef`. */ - val getFormats: Type => List[String] = - CodecCodeGen.extensibleFormatsForType { - case NamedType(List("sbt", "internal", "librarymanagement", "RetrieveConfiguration"), _) => - "sbt.librarymanagement.RetrieveConfigurationFormats" :: Nil - case tpe: Type if myCodecs isDefinedAt tpe.removeTypeParameters.name => - myCodecs(tpe.removeTypeParameters.name)(tpe) - case tpe: Type if excluded contains tpe.removeTypeParameters.name => - Nil - case other => - CodecCodeGen.formatsForType(other) - } - -} diff --git a/project/Mima.scala b/project/Mima.scala new file mode 100644 index 000000000..bdb5dfb02 --- /dev/null +++ b/project/Mima.scala @@ -0,0 +1,33 @@ + +import com.typesafe.tools.mima.plugin.MimaPlugin +import sbt._ +import sbt.Keys._ +import sys.process._ + +object Mima { + + private def stable(ver: String): Boolean = + ver.exists(c => c != '0' && c != '.') && + ver + .replace("-RC", "-") + .forall(c => c == '.' || c == '-' || c.isDigit) + + def binaryCompatibilityVersions: Set[String] = + Seq("git", "tag", "--merged", "HEAD^", "--contains", "736d5c11") + .!! + .linesIterator + .map(_.trim) + .filter(_.startsWith("v")) + .map(_.stripPrefix("v")) + .filter(stable) + .toSet + + def settings: Seq[Setting[_]] = Seq( + MimaPlugin.autoImport.mimaPreviousArtifacts := { + binaryCompatibilityVersions.map { ver => + (organization.value % moduleName.value % ver).cross(crossVersion.value) + } + } + ) + +} diff --git a/project/plugins.sbt b/project/plugins.sbt index d3eef4933..23e1b8f36 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -1,7 +1,6 @@ plugins_( "com.geirsson" % "sbt-ci-release" % "1.2.1", - "org.scala-sbt" % "sbt-contraband" % "0.4.3", "io.get-coursier" % "sbt-coursier" % sbtCoursierVersion, "com.typesafe" % "sbt-mima-plugin" % "0.3.0", "com.jsuereth" % "sbt-pgp" % "1.1.2", diff --git a/scripts/travis.sh b/scripts/travis.sh index 55382af60..f8f58288c 100755 --- a/scripts/travis.sh +++ b/scripts/travis.sh @@ -14,8 +14,10 @@ sbtShading() { } runLmCoursierTests() { + # publishing locally to ensure shading runs fine ./metadata/scripts/with-test-repo.sh sbt \ ++$TRAVIS_SCALA_VERSION \ + lm-coursier-shaded/publishLocal \ lm-coursier/test \ "sbt-lm-coursier/scripted shared-$TEST_GROUP/*" }