diff --git a/plugin/src/main/scala-2.10/coursier/CoursierPlugin.scala b/plugin/src/main/scala-2.10/coursier/CoursierPlugin.scala index dc5f07b30..01db819d8 100644 --- a/plugin/src/main/scala-2.10/coursier/CoursierPlugin.scala +++ b/plugin/src/main/scala-2.10/coursier/CoursierPlugin.scala @@ -16,7 +16,7 @@ object CoursierPlugin extends AutoPlugin { val coursierMaxIterations = Keys.coursierMaxIterations val coursierChecksums = Keys.coursierChecksums val coursierArtifactsChecksums = Keys.coursierArtifactsChecksums - val coursierCachePolicy = Keys.coursierCachePolicy + val coursierCachePolicies = Keys.coursierCachePolicies val coursierVerbosity = Keys.coursierVerbosity val coursierResolvers = Keys.coursierResolvers val coursierSbtResolvers = Keys.coursierSbtResolvers @@ -35,8 +35,8 @@ object CoursierPlugin extends AutoPlugin { coursierMaxIterations := 50, coursierChecksums := Seq(Some("SHA-1"), None), coursierArtifactsChecksums := Seq(None), - coursierCachePolicy := CachePolicy.FetchMissing, - coursierVerbosity := 0, + coursierCachePolicies := Settings.defaultCachePolicies, + coursierVerbosity := Settings.defaultVerbosityLevel, coursierResolvers <<= Tasks.coursierResolversTask, coursierSbtResolvers <<= externalResolvers in updateSbtClassifiers, coursierCache := Cache.default, diff --git a/plugin/src/main/scala-2.10/coursier/Keys.scala b/plugin/src/main/scala-2.10/coursier/Keys.scala index d870f320d..0af9153d9 100644 --- a/plugin/src/main/scala-2.10/coursier/Keys.scala +++ b/plugin/src/main/scala-2.10/coursier/Keys.scala @@ -9,7 +9,7 @@ object Keys { val coursierMaxIterations = SettingKey[Int]("coursier-max-iterations", "") val coursierChecksums = SettingKey[Seq[Option[String]]]("coursier-checksums", "") val coursierArtifactsChecksums = SettingKey[Seq[Option[String]]]("coursier-artifacts-checksums", "") - val coursierCachePolicy = SettingKey[CachePolicy]("coursier-cache-policy", "") + val coursierCachePolicies = SettingKey[Seq[CachePolicy]]("coursier-cache-policies", "") val coursierVerbosity = SettingKey[Int]("coursier-verbosity", "") diff --git a/plugin/src/main/scala-2.10/coursier/Settings.scala b/plugin/src/main/scala-2.10/coursier/Settings.scala new file mode 100644 index 000000000..2a63999be --- /dev/null +++ b/plugin/src/main/scala-2.10/coursier/Settings.scala @@ -0,0 +1,81 @@ +package coursier + +import scala.util.{Failure, Success, Try} + +object Settings { + + private val baseDefaultVerbosityLevel = 0 + + def defaultVerbosityLevel: Int = { + + def fromOption(value: Option[String], description: String): Option[Int] = + value.filter(_.nonEmpty).flatMap { + str => + Try(str.toInt) match { + case Success(level) => Some(level) + case Failure(ex) => + Console.err.println( + s"Warning: unrecognized $description value (should be an integer), ignoring it." + ) + None + } + } + + val fromEnv = fromOption( + sys.env.get("COURSIER_VERBOSITY"), + "COURSIER_VERBOSITY environment variable" + ) + + def fromProps = fromOption( + sys.props.get("coursier.verbosity"), + "Java property coursier.verbosity" + ) + + fromEnv + .orElse(fromProps) + .getOrElse(baseDefaultVerbosityLevel) + } + + + private val baseDefaultCachePolicies = Seq( + CachePolicy.LocalOnly, + CachePolicy.FetchMissing + ) + + def defaultCachePolicies: Seq[CachePolicy] = { + + def fromOption(value: Option[String], description: String): Option[Seq[CachePolicy]] = + value.filter(_.nonEmpty).flatMap { + str => + CacheParse.cachePolicies(str) match { + case scalaz.Success(Seq()) => + Console.err.println( + s"Warning: no mode found in $description, ignoring it." + ) + None + case scalaz.Success(policies) => + Some(policies) + case scalaz.Failure(errors) => + Console.err.println( + s"Warning: unrecognized mode in $description, ignoring it." + ) + None + } + } + + val fromEnv = fromOption( + sys.env.get("COURSIER_MODE"), + "COURSIER_MODE environment variable" + ) + + def fromProps = fromOption( + sys.props.get("coursier.mode"), + "Java property coursier.mode" + ) + + fromEnv + .orElse(fromProps) + .getOrElse(baseDefaultCachePolicies) + } + +} diff --git a/plugin/src/main/scala-2.10/coursier/Tasks.scala b/plugin/src/main/scala-2.10/coursier/Tasks.scala index 7f8d3a425..0d62f6404 100644 --- a/plugin/src/main/scala-2.10/coursier/Tasks.scala +++ b/plugin/src/main/scala-2.10/coursier/Tasks.scala @@ -216,7 +216,7 @@ object Tasks { val checksums = coursierChecksums.value val artifactsChecksums = coursierArtifactsChecksums.value val maxIterations = coursierMaxIterations.value - val cachePolicy = coursierCachePolicy.value + val cachePolicies = coursierCachePolicies.value val cache = coursierCache.value val sv = scalaVersion.value // is this always defined? (e.g. for Java only projects?) @@ -227,7 +227,7 @@ object Tasks { else coursierResolvers.value - val verbosity = coursierVerbosity.value + val verbosityLevel = coursierVerbosity.value val startRes = Resolution( @@ -252,7 +252,7 @@ object Tasks { Files.write(cacheIvyPropertiesFile.toPath, "".getBytes("UTF-8")) } - if (verbosity >= 2) { + if (verbosityLevel >= 2) { println("InterProjectRepository") for (p <- projects) println(s" ${p.module}:${p.version}") @@ -283,8 +283,10 @@ object Tasks { val fetch = Fetch.from( repositories, - Cache.fetch(cache, CachePolicy.LocalOnly, checksums = checksums, logger = Some(resLogger), pool = pool), - Cache.fetch(cache, cachePolicy, checksums = checksums, logger = Some(resLogger), pool = pool) + Cache.fetch(cache, cachePolicies.head, checksums = checksums, logger = Some(resLogger), pool = pool), + cachePolicies.tail.map(p => + Cache.fetch(cache, p, checksums = checksums, logger = Some(resLogger), pool = pool) + ): _* ) def depsRepr(deps: Seq[(String, Dependency)]) = @@ -297,7 +299,7 @@ object Tasks { s"${dep.module}:${dep.version}:${dep.configuration}" }.sorted.distinct - if (verbosity >= 1) { + if (verbosityLevel >= 1) { val repoReprs = repositories.map { case r: IvyRepository => s"ivy:${r.pattern}" @@ -313,9 +315,9 @@ object Tasks { errPrintln(s"Repositories:\n${repoReprs.map(" "+_).mkString("\n")}") } - if (verbosity >= 0) + if (verbosityLevel >= 0) errPrintln(s"Resolving ${currentProject.module.organization}:${currentProject.module.name}:${currentProject.version}") - if (verbosity >= 1) + if (verbosityLevel >= 1) for (depRepr <- depsRepr(currentProject.dependencies)) errPrintln(s" $depRepr") @@ -374,9 +376,9 @@ object Tasks { } } - if (verbosity >= 0) + if (verbosityLevel >= 0) errPrintln("Resolution done") - if (verbosity >= 1) { + if (verbosityLevel >= 1) { val finalDeps = Config.dependenciesWithConfig( res, depsByConfig.map { case (k, l) => k -> l.toSet }, @@ -408,10 +410,23 @@ object Tasks { val artifactsLogger = createLogger() val artifactFileOrErrorTasks = allArtifacts.toVector.map { a => - Cache.file(a, cache, cachePolicy, checksums = artifactsChecksums, logger = Some(artifactsLogger), pool = pool).run.map((a, _)) + def f(p: CachePolicy) = + Cache.file( + a, + cache, + p, + checksums = artifactsChecksums, + logger = Some(artifactsLogger), + pool = pool + ) + + cachePolicies.tail + .foldLeft(f(cachePolicies.head))(_ orElse f(_)) + .run + .map((a, _)) } - if (verbosity >= 0) + if (verbosityLevel >= 0) errPrintln(s"Fetching artifacts") artifactsLogger.init() @@ -425,7 +440,7 @@ object Tasks { artifactsLogger.stop() - if (verbosity >= 0) + if (verbosityLevel >= 0) errPrintln(s"Fetching artifacts: done") def artifactFileOpt(artifact: Artifact) = {