diff --git a/modules/lm-coursier/src/main/scala/lmcoursier/CoursierConfiguration.scala b/modules/lm-coursier/src/main/scala/lmcoursier/CoursierConfiguration.scala index b9d91aa81..c7a08440c 100644 --- a/modules/lm-coursier/src/main/scala/lmcoursier/CoursierConfiguration.scala +++ b/modules/lm-coursier/src/main/scala/lmcoursier/CoursierConfiguration.scala @@ -22,8 +22,8 @@ final class CoursierConfiguration private ( val scalaOrganization: Option[String], val scalaVersion: Option[String], val authenticationByRepositoryId: Vector[(String, lmcoursier.definitions.Authentication)], - val credentials: Seq[coursier.credentials.Credentials], - val logger: Option[coursier.cache.CacheLogger], + 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) @@ -38,7 +38,7 @@ final class CoursierConfiguration private ( 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[coursier.credentials.Credentials] = credentials, logger: Option[coursier.cache.CacheLogger] = logger, cache: Option[java.io.File] = cache): CoursierConfiguration = { + 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 = { @@ -107,13 +107,13 @@ final class CoursierConfiguration private ( def withAuthenticationByRepositoryId(authenticationByRepositoryId: Vector[(String, lmcoursier.definitions.Authentication)]): CoursierConfiguration = { copy(authenticationByRepositoryId = authenticationByRepositoryId) } - def withCredentials(credentials: Seq[coursier.credentials.Credentials]): CoursierConfiguration = { + def withCredentials(credentials: Seq[lmcoursier.credentials.Credentials]): CoursierConfiguration = { copy(credentials = credentials) } - def withLogger(logger: Option[coursier.cache.CacheLogger]): CoursierConfiguration = { + def withLogger(logger: Option[lmcoursier.definitions.CacheLogger]): CoursierConfiguration = { copy(logger = logger) } - def withLogger(logger: coursier.cache.CacheLogger): CoursierConfiguration = { + def withLogger(logger: lmcoursier.definitions.CacheLogger): CoursierConfiguration = { copy(logger = Option(logger)) } def withCache(cache: Option[java.io.File]): CoursierConfiguration = { @@ -126,6 +126,6 @@ final class CoursierConfiguration private ( 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[coursier.credentials.Credentials], logger: Option[coursier.cache.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[coursier.credentials.Credentials], logger: coursier.cache.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)) + 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/lmcoursier/CoursierDependencyResolution.scala b/modules/lm-coursier/src/main/scala/lmcoursier/CoursierDependencyResolution.scala index 185d9a19e..b8a327682 100644 --- a/modules/lm-coursier/src/main/scala/lmcoursier/CoursierDependencyResolution.scala +++ b/modules/lm-coursier/src/main/scala/lmcoursier/CoursierDependencyResolution.scala @@ -68,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 @@ -123,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, @@ -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/lmcoursier/FromSbt.scala b/modules/lm-coursier/src/main/scala/lmcoursier/FromSbt.scala index 26a707045..e1d465dcc 100644 --- a/modules/lm-coursier/src/main/scala/lmcoursier/FromSbt.scala +++ b/modules/lm-coursier/src/main/scala/lmcoursier/FromSbt.scala @@ -82,7 +82,6 @@ object FromSbt { ) val mapping = module.configurations.getOrElse("compile") - // FIXME Don't call this from here val allMappings = ivyXmlMappings(mapping).map { case (from, to) => (Configuration(from.value), Configuration(to.value)) diff --git a/modules/lm-coursier/src/main/scala/lmcoursier/Inputs.scala b/modules/lm-coursier/src/main/scala/lmcoursier/Inputs.scala index 55ba14c6b..32c3af41a 100644 --- a/modules/lm-coursier/src/main/scala/lmcoursier/Inputs.scala +++ b/modules/lm-coursier/src/main/scala/lmcoursier/Inputs.scala @@ -1,5 +1,6 @@ package lmcoursier +import coursier.ivy.IvyXml.{mappings => initialIvyXmlMappings} import lmcoursier.definitions.{Configuration, ModuleName, Organization} import sbt.librarymanagement.{CrossVersion, InclExclRule} import sbt.util.Logger @@ -8,6 +9,12 @@ import scala.collection.mutable 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))) 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/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/ToCoursier.scala b/modules/lm-coursier/src/main/scala/lmcoursier/definitions/ToCoursier.scala index a1c353b83..3221c01c4 100644 --- a/modules/lm-coursier/src/main/scala/lmcoursier/definitions/ToCoursier.scala +++ b/modules/lm-coursier/src/main/scala/lmcoursier/definitions/ToCoursier.scala @@ -1,5 +1,7 @@ package lmcoursier.definitions +import lmcoursier.credentials.{Credentials, DirectCredentials, FileCredentials} + // TODO Make private[lmcoursier] // private[coursier] object ToCoursier { @@ -99,4 +101,48 @@ object ToCoursier { ) ) + 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/sbt-coursier-shared/src/main/scala/coursier/sbtcoursiershared/InputsTasks.scala b/modules/sbt-coursier-shared/src/main/scala/coursier/sbtcoursiershared/InputsTasks.scala index 6968b2970..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,10 +1,10 @@ package coursier.sbtcoursiershared -import coursier.credentials.DirectCredentials 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 lmcoursier.credentials.DirectCredentials import sbt.{Def, SettingKey} import sbt.Keys._ import sbt.librarymanagement.{InclExclRule, ModuleID} @@ -106,13 +106,7 @@ object InputsTasks { val configurations = desc .getModuleConfigurations .toVector - .flatMap { s => - // FIXME Don't call this from here - coursier.ivy.IvyXml.mappings(s).map { - case (from, to) => - (Configuration(from.value), Configuration(to.value)) - } - } + .flatMap(Inputs.ivyXmlMappings) def dependency(conf: Configuration, attr: Attributes) = Dependency( module, 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 ec002533d..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,10 @@ package coursier.sbtcoursiershared import java.io.File -import coursier.cache.{CacheDefaults, CacheLogger} import coursier.{Credentials => LegacyCredentials} -import coursier.credentials.Credentials -import lmcoursier.FallbackDependency -import lmcoursier.definitions.{Configuration, Project, Publication} +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._ @@ -65,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/src/main/scala/coursier/sbtcoursier/ArtifactsTasks.scala b/modules/sbt-coursier/src/main/scala/coursier/sbtcoursier/ArtifactsTasks.scala index 4865d6330..32250daf3 100644 --- a/modules/sbt-coursier/src/main/scala/coursier/sbtcoursier/ArtifactsTasks.scala +++ b/modules/sbt-coursier/src/main/scala/coursier/sbtcoursier/ArtifactsTasks.scala @@ -9,6 +9,7 @@ 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/ResolutionTasks.scala b/modules/sbt-coursier/src/main/scala/coursier/sbtcoursier/ResolutionTasks.scala index 1588560e6..51ffd8546 100644 --- a/modules/sbt-coursier/src/main/scala/coursier/sbtcoursier/ResolutionTasks.scala +++ b/modules/sbt-coursier/src/main/scala/coursier/sbtcoursier/ResolutionTasks.scala @@ -62,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 @@ -98,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) 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)