From fbc04dcbc8f1002df6e2cdf132972951c53b54b8 Mon Sep 17 00:00:00 2001 From: Alexandre Archambault Date: Fri, 5 Aug 2016 11:37:29 -0400 Subject: [PATCH] Be fine with modules like a::b:c a::b:c standing for a:b_2.11:c --- .../scala-2.11/coursier/cli/Bootstrap.scala | 5 +- .../main/scala-2.11/coursier/cli/Helper.scala | 10 +- .../scala-2.11/coursier/cli/Options.scala | 11 ++- .../src/main/scala/coursier/util/Parse.scala | 91 +++++++++++++++---- 4 files changed, 87 insertions(+), 30 deletions(-) diff --git a/cli/src/main/scala-2.11/coursier/cli/Bootstrap.scala b/cli/src/main/scala-2.11/coursier/cli/Bootstrap.scala index d07f5a8fe..43849fa8e 100644 --- a/cli/src/main/scala-2.11/coursier/cli/Bootstrap.scala +++ b/cli/src/main/scala-2.11/coursier/cli/Bootstrap.scala @@ -81,7 +81,10 @@ case class Bootstrap( } - val isolatedDeps = options.isolated.isolatedDeps(options.common.defaultArtifactType) + val isolatedDeps = options.isolated.isolatedDeps( + options.common.defaultArtifactType, + options.common.scalaVersion + ) val (_, isolatedArtifactFiles) = options.isolated.targets.foldLeft((Vector.empty[String], Map.empty[String, (Seq[String], Seq[File])])) { diff --git a/cli/src/main/scala-2.11/coursier/cli/Helper.scala b/cli/src/main/scala-2.11/coursier/cli/Helper.scala index 922df15ae..b8d9cdf18 100644 --- a/cli/src/main/scala-2.11/coursier/cli/Helper.scala +++ b/cli/src/main/scala-2.11/coursier/cli/Helper.scala @@ -161,9 +161,9 @@ class Helper( val (modVerCfgErrors, moduleVersionConfigs) = - Parse.moduleVersionConfigs(rawDependencies) + Parse.moduleVersionConfigs(rawDependencies, scalaVersion) val (intransitiveModVerCfgErrors, intransitiveModuleVersionConfigs) = - Parse.moduleVersionConfigs(intransitive) + Parse.moduleVersionConfigs(intransitive, scalaVersion) prematureExitIf(modVerCfgErrors.nonEmpty) { s"Cannot parse dependencies:\n" + modVerCfgErrors.map(" "+_).mkString("\n") @@ -175,7 +175,7 @@ class Helper( } - val (forceVersionErrors, forceVersions0) = Parse.moduleVersions(forceVersion) + val (forceVersionErrors, forceVersions0) = Parse.moduleVersions(forceVersion, scalaVersion) prematureExitIf(forceVersionErrors.nonEmpty) { s"Cannot parse forced versions:\n" + forceVersionErrors.map(" "+_).mkString("\n") @@ -220,7 +220,7 @@ class Helper( grouped.map { case (mod, versions) => mod -> versions.last } } - val (excludeErrors, excludes0) = Parse.modules(exclude) + val (excludeErrors, excludes0) = Parse.modules(exclude, scalaVersion) prematureExitIf(excludeErrors.nonEmpty) { s"Cannot parse excluded modules:\n" + @@ -607,7 +607,7 @@ class Helper( (parentLoader0, files0) else { - val isolatedDeps = isolated.isolatedDeps(common.defaultArtifactType) + val isolatedDeps = isolated.isolatedDeps(common.defaultArtifactType, common.scalaVersion) val (isolatedLoader, filteredFiles0) = isolated.targets.foldLeft((parentLoader0, files0)) { case ((parent, files0), target) => diff --git a/cli/src/main/scala-2.11/coursier/cli/Options.scala b/cli/src/main/scala-2.11/coursier/cli/Options.scala index d084f3e8c..564113d2d 100644 --- a/cli/src/main/scala-2.11/coursier/cli/Options.scala +++ b/cli/src/main/scala-2.11/coursier/cli/Options.scala @@ -48,6 +48,9 @@ case class CommonOptions( @Value("organization:name") @Short("E") exclude: List[String], + @Help("Default scala version") + @Short("e") + scalaVersion: String = scala.util.Properties.versionNumberString, @Help("Add intransitive dependencies") intransitive: List[String], @Help("Classifiers that should be fetched") @@ -137,9 +140,9 @@ case class IsolatedLoaderOptions( target -> dep } - lazy val isolatedModuleVersions = rawIsolated.groupBy { case (t, _) => t }.map { + def isolatedModuleVersions(defaultScalaVersion: String) = rawIsolated.groupBy { case (t, _) => t }.map { case (t, l) => - val (errors, modVers) = Parse.moduleVersions(l.map { case (_, d) => d }) + val (errors, modVers) = Parse.moduleVersions(l.map { case (_, d) => d }, defaultScalaVersion) if (errors.nonEmpty) { errors.foreach(Console.err.println) @@ -149,8 +152,8 @@ case class IsolatedLoaderOptions( t -> modVers } - def isolatedDeps(defaultArtifactType: String) = - isolatedModuleVersions.map { + def isolatedDeps(defaultArtifactType: String, defaultScalaVersion: String) = + isolatedModuleVersions(defaultScalaVersion).map { case (t, l) => t -> l.map { case (mod, ver) => diff --git a/core/shared/src/main/scala/coursier/util/Parse.scala b/core/shared/src/main/scala/coursier/util/Parse.scala index 14a79d052..dd2bb7435 100644 --- a/core/shared/src/main/scala/coursier/util/Parse.scala +++ b/core/shared/src/main/scala/coursier/util/Parse.scala @@ -11,18 +11,37 @@ import scalaz.Scalaz.ToEitherOps object Parse { + private def defaultScalaVersion = scala.util.Properties.versionNumberString + + @deprecated("use the variant accepting a default scala version") + def module(s: String): Either[String, Module] = + module(s, defaultScalaVersion) + /** * Parses a module like * org:name * possibly with attributes, like * org:name;attr1=val1;attr2=val2 + * + * Two semi-columns after the org part is interpreted as a scala module. E.g. if + * `defaultScalaVersion` is `"2.11.x"`, org::name:ver is equivalent to org:name_2.11:ver. */ - def module(s: String): Either[String, Module] = { + def module(s: String, defaultScalaVersion: String): Either[String, Module] = { - val parts = s.split(":", 2) + val parts = s.split(":", 3) - parts match { + val values = parts match { case Array(org, rawName) => + Right((org, rawName, "")) + case Array(org, "", rawName) => + Right((org, rawName, "_" + defaultScalaVersion.split('.').take(2).mkString("."))) + case _ => + Left(s"malformed module: $s") + } + + values.right.flatMap { + case (org, rawName, suffix) => + val splitName = rawName.split(';') if (splitName.tail.exists(!_.contains("="))) @@ -33,11 +52,8 @@ object Parse { case Array(key, value) => key -> value }.toMap - Right(Module(org, name, attributes)) + Right(Module(org, name + suffix, attributes)) } - - case _ => - Left(s"malformed module: $s") } } @@ -55,13 +71,21 @@ object Parse { (errors, values) } + @deprecated("use the variant accepting a default scala version") + def modules(l: Seq[String]): (Seq[String], Seq[Module]) = + modules(l, defaultScalaVersion) + /** * Parses a sequence of coordinates. * * @return Sequence of errors, and sequence of modules/versions */ - def modules(l: Seq[String]): (Seq[String], Seq[Module]) = - valuesAndErrors(module, l) + def modules(l: Seq[String], defaultScalaVersion: String): (Seq[String], Seq[Module]) = + valuesAndErrors(module(_, defaultScalaVersion), l) + + @deprecated("use the variant accepting a default scala version") + def moduleVersion(s: String): Either[String, (Module, String)] = + moduleVersion(s, defaultScalaVersion) /** * Parses coordinates like @@ -69,21 +93,30 @@ object Parse { * possibly with attributes, like * org:name;attr1=val1;attr2=val2:version */ - def moduleVersion(s: String): Either[String, (Module, String)] = { + def moduleVersion(s: String, defaultScalaVersion: String): Either[String, (Module, String)] = { - val parts = s.split(":", 3) + val parts = s.split(":", 4) parts match { case Array(org, rawName, version) => - module(s"$org:$rawName") + module(s"$org:$rawName", defaultScalaVersion) .right .map((_, version)) + case Array(org, "", rawName, version) => + module(s"$org::$rawName", defaultScalaVersion) + .right + .map((_, version)) + case _ => Left(s"Malformed dependency: $s") } } + @deprecated("use the variant accepting a default scala version") + def moduleVersionConfig(s: String): Either[String, (Module, String, Option[String])] = + moduleVersionConfig(s, defaultScalaVersion) + /** * Parses coordinates like * org:name:version @@ -94,18 +127,28 @@ object Parse { * or * org:name;attr1=val1;attr2=val2:version:config */ - def moduleVersionConfig(s: String): Either[String, (Module, String, Option[String])] = { + def moduleVersionConfig(s: String, defaultScalaVersion: String): Either[String, (Module, String, Option[String])] = { - val parts = s.split(":", 4) + val parts = s.split(":", 5) parts match { + case Array(org, "", rawName, version, config) => + module(s"$org::$rawName", defaultScalaVersion) + .right + .map((_, version, Some(config))) + + case Array(org, "", rawName, version) => + module(s"$org::$rawName", defaultScalaVersion) + .right + .map((_, version, None)) + case Array(org, rawName, version, config) => - module(s"$org:$rawName") + module(s"$org:$rawName", defaultScalaVersion) .right .map((_, version, Some(config))) case Array(org, rawName, version) => - module(s"$org:$rawName") + module(s"$org:$rawName", defaultScalaVersion) .right .map((_, version, None)) @@ -114,21 +157,29 @@ object Parse { } } + @deprecated("use the variant accepting a default scala version") + def moduleVersions(l: Seq[String]): (Seq[String], Seq[(Module, String)]) = + moduleVersions(l, defaultScalaVersion) + /** * Parses a sequence of coordinates. * * @return Sequence of errors, and sequence of modules / versions */ - def moduleVersions(l: Seq[String]): (Seq[String], Seq[(Module, String)]) = - valuesAndErrors(moduleVersion, l) + def moduleVersions(l: Seq[String], defaultScalaVersion: String): (Seq[String], Seq[(Module, String)]) = + valuesAndErrors(moduleVersion(_, defaultScalaVersion), l) + + @deprecated("use the variant accepting a default scala version") + def moduleVersionConfigs(l: Seq[String]): (Seq[String], Seq[(Module, String, Option[String])]) = + moduleVersionConfigs(l, defaultScalaVersion) /** * Parses a sequence of coordinates having an optional configuration. * * @return Sequence of errors, and sequence of modules / versions / optional configurations */ - def moduleVersionConfigs(l: Seq[String]): (Seq[String], Seq[(Module, String, Option[String])]) = - valuesAndErrors(moduleVersionConfig, l) + def moduleVersionConfigs(l: Seq[String], defaultScalaVersion: String): (Seq[String], Seq[(Module, String, Option[String])]) = + valuesAndErrors(moduleVersionConfig(_, defaultScalaVersion), l) def repository(s: String): String \/ Repository = if (s == "central")