From 47e0d38a3b7d304ba00629a0fd4f78879b288211 Mon Sep 17 00:00:00 2001 From: Alexandre Archambault Date: Mon, 25 Jul 2016 00:18:59 +0200 Subject: [PATCH 1/4] Add support for Maven profiles from the SBT plugin --- .../scala-2.10/coursier/CoursierPlugin.scala | 2 ++ .../src/main/scala-2.10/coursier/Keys.scala | 2 ++ .../src/main/scala-2.10/coursier/Tasks.scala | 2 ++ .../sbt-test/sbt-coursier/profiles/build.sbt | 12 ++++++++++++ .../src/sbt-test/sbt-coursier/profiles/output | 1 + .../sbt-coursier/profiles/project/plugins.sbt | 11 +++++++++++ .../profiles/src/main/scala/Main.scala | 19 +++++++++++++++++++ .../src/sbt-test/sbt-coursier/profiles/test | 3 +++ 8 files changed, 52 insertions(+) create mode 100644 plugin/src/sbt-test/sbt-coursier/profiles/build.sbt create mode 100644 plugin/src/sbt-test/sbt-coursier/profiles/output create mode 100644 plugin/src/sbt-test/sbt-coursier/profiles/project/plugins.sbt create mode 100644 plugin/src/sbt-test/sbt-coursier/profiles/src/main/scala/Main.scala create mode 100644 plugin/src/sbt-test/sbt-coursier/profiles/test diff --git a/plugin/src/main/scala-2.10/coursier/CoursierPlugin.scala b/plugin/src/main/scala-2.10/coursier/CoursierPlugin.scala index 745848d75..1b5f320cc 100644 --- a/plugin/src/main/scala-2.10/coursier/CoursierPlugin.scala +++ b/plugin/src/main/scala-2.10/coursier/CoursierPlugin.scala @@ -18,6 +18,7 @@ object CoursierPlugin extends AutoPlugin { val coursierCachePolicies = Keys.coursierCachePolicies val coursierTtl = Keys.coursierTtl val coursierVerbosity = Keys.coursierVerbosity + val mavenProfiles = Keys.mavenProfiles val coursierSourceRepositories = Keys.coursierSourceRepositories val coursierResolvers = Keys.coursierResolvers val coursierSbtResolvers = Keys.coursierSbtResolvers @@ -64,6 +65,7 @@ object CoursierPlugin extends AutoPlugin { coursierCachePolicies := CachePolicy.default, coursierTtl := Cache.defaultTtl, coursierVerbosity := Settings.defaultVerbosityLevel, + mavenProfiles := Set.empty, coursierSourceRepositories := Nil, coursierResolvers <<= Tasks.coursierResolversTask, coursierSbtResolvers <<= externalResolvers in updateSbtClassifiers, diff --git a/plugin/src/main/scala-2.10/coursier/Keys.scala b/plugin/src/main/scala-2.10/coursier/Keys.scala index 49d89be75..bb9b267d0 100644 --- a/plugin/src/main/scala-2.10/coursier/Keys.scala +++ b/plugin/src/main/scala-2.10/coursier/Keys.scala @@ -20,6 +20,8 @@ object Keys { val coursierVerbosity = SettingKey[Int]("coursier-verbosity") + val mavenProfiles = SettingKey[Set[String]]("maven-profiles") + val coursierSourceRepositories = SettingKey[Seq[File]]("coursier-source-repositories") val coursierResolvers = TaskKey[Seq[Resolver]]("coursier-resolvers") val coursierSbtResolvers = TaskKey[Seq[Resolver]]("coursier-sbt-resolvers") diff --git a/plugin/src/main/scala-2.10/coursier/Tasks.scala b/plugin/src/main/scala-2.10/coursier/Tasks.scala index d563814fd..ac5cf7627 100644 --- a/plugin/src/main/scala-2.10/coursier/Tasks.scala +++ b/plugin/src/main/scala-2.10/coursier/Tasks.scala @@ -374,6 +374,7 @@ object Tasks { val verbosityLevel = coursierVerbosity.value + val userEnabledProfiles = mavenProfiles.value val startRes = Resolution( currentProject.dependencies.map { @@ -381,6 +382,7 @@ object Tasks { dep.copy(exclusions = dep.exclusions ++ exclusions) }.toSet, filter = Some(dep => !dep.optional), + profileActivation = Some(core.Resolution.userProfileActivation(userEnabledProfiles)), forceVersions = // order matters here userForceVersions ++ diff --git a/plugin/src/sbt-test/sbt-coursier/profiles/build.sbt b/plugin/src/sbt-test/sbt-coursier/profiles/build.sbt new file mode 100644 index 000000000..b0209d82c --- /dev/null +++ b/plugin/src/sbt-test/sbt-coursier/profiles/build.sbt @@ -0,0 +1,12 @@ +scalaVersion := "2.11.8" + +libraryDependencies += "org.apache.spark" %% "spark-sql" % "1.6.2" + +mavenProfiles += "hadoop-2.6" + +coursierCachePolicies := { + if (sys.props("os.name").startsWith("Windows")) + coursierCachePolicies.value + else + Seq(coursier.CachePolicy.ForceDownload) +} diff --git a/plugin/src/sbt-test/sbt-coursier/profiles/output b/plugin/src/sbt-test/sbt-coursier/profiles/output new file mode 100644 index 000000000..a0aba9318 --- /dev/null +++ b/plugin/src/sbt-test/sbt-coursier/profiles/output @@ -0,0 +1 @@ +OK \ No newline at end of file diff --git a/plugin/src/sbt-test/sbt-coursier/profiles/project/plugins.sbt b/plugin/src/sbt-test/sbt-coursier/profiles/project/plugins.sbt new file mode 100644 index 000000000..152225a9e --- /dev/null +++ b/plugin/src/sbt-test/sbt-coursier/profiles/project/plugins.sbt @@ -0,0 +1,11 @@ +{ + val pluginVersion = sys.props.getOrElse( + "plugin.version", + throw new RuntimeException( + """|The system property 'plugin.version' is not defined. + |Specify this property using the scriptedLaunchOpts -D.""".stripMargin + ) + ) + + addSbtPlugin("io.get-coursier" % "sbt-coursier" % pluginVersion) +} diff --git a/plugin/src/sbt-test/sbt-coursier/profiles/src/main/scala/Main.scala b/plugin/src/sbt-test/sbt-coursier/profiles/src/main/scala/Main.scala new file mode 100644 index 000000000..9ac86fe34 --- /dev/null +++ b/plugin/src/sbt-test/sbt-coursier/profiles/src/main/scala/Main.scala @@ -0,0 +1,19 @@ +import java.io.File +import java.nio.file.Files + +object Main extends App { + val p = new java.util.Properties + p.load( + Thread.currentThread() + .getContextClassLoader + .getResource("common-version-info.properties") + .openStream() + ) + + val hadoopVersion = p.getProperty("version") + Console.err.println(s"Found hadoop version $hadoopVersion") + + assert(hadoopVersion == "2.6.0") + + Files.write(new File("output").toPath, "OK".getBytes("UTF-8")) +} diff --git a/plugin/src/sbt-test/sbt-coursier/profiles/test b/plugin/src/sbt-test/sbt-coursier/profiles/test new file mode 100644 index 000000000..2182f57b0 --- /dev/null +++ b/plugin/src/sbt-test/sbt-coursier/profiles/test @@ -0,0 +1,3 @@ +$ delete output +> run +$ exists output From c41dabdef9fc8df40cc597ff32e36f7fc7b18c03 Mon Sep 17 00:00:00 2001 From: Alexandre Archambault Date: Mon, 25 Jul 2016 00:19:01 +0200 Subject: [PATCH 2/4] Fix default cache TTL --- cache/src/main/scala/coursier/Cache.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cache/src/main/scala/coursier/Cache.scala b/cache/src/main/scala/coursier/Cache.scala index 86585b08f..e176d5d27 100644 --- a/cache/src/main/scala/coursier/Cache.scala +++ b/cache/src/main/scala/coursier/Cache.scala @@ -909,7 +909,7 @@ object Cache { val fromEnv = sys.env.get("COURSIER_TTL").flatMap(fromString) def fromProps = sys.props.get("coursier.ttl").flatMap(fromString) - def default = 24.days + def default = 24.hours fromEnv .orElse(fromProps) From f46581288f093168e3bc13478d783af318085cb2 Mon Sep 17 00:00:00 2001 From: Alexandre Archambault Date: Mon, 25 Jul 2016 00:19:03 +0200 Subject: [PATCH 3/4] Enable TTL for changing artifacts by default --- cache/src/main/scala/coursier/CachePolicy.scala | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/cache/src/main/scala/coursier/CachePolicy.scala b/cache/src/main/scala/coursier/CachePolicy.scala index da83b4e6a..a9ec3445e 100644 --- a/cache/src/main/scala/coursier/CachePolicy.scala +++ b/cache/src/main/scala/coursier/CachePolicy.scala @@ -13,6 +13,8 @@ object CachePolicy { * * If no local file is found, *don't* try download it. Updates are only checked for files already * in cache. + * + * Follows the TTL parameter (assumes no update is needed if the last one is recent enough). */ case object LocalUpdateChanging extends CachePolicy @@ -22,6 +24,8 @@ object CachePolicy { * If no local file is found, *don't* try download it. Updates are only checked for files already * in cache. * + * Follows the TTL parameter (assumes no update is needed if the last one is recent enough). + * * Unlike `LocalUpdateChanging`, all found local files are checked for updates, not just the * changing ones. */ @@ -31,12 +35,16 @@ object CachePolicy { * Pick local files, and download the missing ones. * * For changing ones, check for updates, and download those if any. + * + * Follows the TTL parameter (assumes no update is needed if the last one is recent enough). */ case object UpdateChanging extends CachePolicy /** * Pick local files, download the missing ones, check for updates and download those if any. * + * Follows the TTL parameter (assumes no update is needed if the last one is recent enough). + * * Unlike `UpdateChanging`, all found local files are checked for updates, not just the changing * ones. */ @@ -58,7 +66,11 @@ object CachePolicy { private val baseDefault = Seq( + // first, try to update changing artifacts that were previously downloaded (follows TTL) + CachePolicy.LocalUpdateChanging, + // then, use what's available locally CachePolicy.LocalOnly, + // lastly, try to download what's missing CachePolicy.FetchMissing ) From 4d73166fbc33cd921be9599615240d63c9525c98 Mon Sep 17 00:00:00 2001 From: Alexandre Archambault Date: Mon, 25 Jul 2016 00:19:06 +0200 Subject: [PATCH 4/4] Minor refacto --- .../main/scala/coursier/core/Resolution.scala | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) diff --git a/core/shared/src/main/scala/coursier/core/Resolution.scala b/core/shared/src/main/scala/coursier/core/Resolution.scala index f2ee7e0ec..66cf5169b 100644 --- a/core/shared/src/main/scala/coursier/core/Resolution.scala +++ b/core/shared/src/main/scala/coursier/core/Resolution.scala @@ -948,20 +948,13 @@ final case class Resolution( private def artifacts0( overrideClassifiers: Option[Seq[String]], keepAttributes: Boolean - ): Seq[Artifact] = { - val res = for { - dep <- minDependencies.toSeq - (source, proj) <- projectCache - .get(dep.moduleVersion) - .toSeq - artifact <- source - .artifacts(dep, proj, overrideClassifiers) - } yield (if (keepAttributes) artifact else artifact.copy(attributes = Attributes("", ""))) + ): Seq[Artifact] = + dependencyArtifacts0(overrideClassifiers).map { + case (_, artifact) => + if (keepAttributes) artifact else artifact.copy(attributes = Attributes("", "")) + }.distinct - res.distinct - } - - // temporary hack :-| + // keepAttributes to false is a temporary hack :-| // if one wants the attributes field of artifacts not to be cleared, call dependencyArtifacts def classifiersArtifacts(classifiers: Seq[String]): Seq[Artifact] =