From 842faf5dd290e34488f07ab4b3c84aa19efd6a76 Mon Sep 17 00:00:00 2001 From: Alexandre Archambault Date: Sun, 28 Jun 2015 14:20:02 +0100 Subject: [PATCH] Formatting / styling --- .../main/scala/coursier/core/Resolution.scala | 229 +++++++++++------- .../coursier/core/ResolutionProcess.scala | 6 +- core/src/main/scala/coursier/package.scala | 70 ++++-- 3 files changed, 200 insertions(+), 105 deletions(-) diff --git a/core/src/main/scala/coursier/core/Resolution.scala b/core/src/main/scala/coursier/core/Resolution.scala index 76ecd779a..6456b40c3 100644 --- a/core/src/main/scala/coursier/core/Resolution.scala +++ b/core/src/main/scala/coursier/core/Resolution.scala @@ -36,25 +36,35 @@ object Resolution { def key(dep: Dependency): Key = (dep.module.organization, dep.module.name, dep.attributes.`type`) - def add(dict: Map[Key, Dependency], dep: Dependency): Map[Key, Dependency] = { + def add( + dict: Map[Key, Dependency], + dep: Dependency + ): Map[Key, Dependency] = { + val key0 = key(dep) + if (dict.contains(key0)) dict else dict + (key0 -> dep) } - def addSeq(dict: Map[Key, Dependency], deps: Seq[Dependency]): Map[Key, Dependency] = + def addSeq( + dict: Map[Key, Dependency], + deps: Seq[Dependency] + ): Map[Key, Dependency] = (dict /: deps)(add) } - def mergeProperties(dict: Map[String, String], other: Map[String, String]): Map[String, String] = { + def mergeProperties( + dict: Map[String, String], + other: Map[String, String] + ): Map[String, String] = dict ++ other.filterKeys(!dict.contains(_)) - } def addDependencies(deps: Seq[Seq[Dependency]]): Seq[Dependency] = { val res = - deps.foldRight((Set.empty[DepMgmt.Key], Seq.empty[Dependency])) { + (deps :\ (Set.empty[DepMgmt.Key], Seq.empty[Dependency])) { case (deps0, (set, acc)) => val deps = deps0 .filter(dep => !set(DepMgmt.key(dep))) @@ -65,7 +75,9 @@ object Resolution { res._2 } - val propRegex = (quote("${") + "([a-zA-Z0-9-.]*)" + quote("}")).r + val propRegex = ( + quote("${") + "([a-zA-Z0-9-.]*)" + quote("}") + ).r /** * Substitutes `properties` in `dependencies`. @@ -108,15 +120,19 @@ object Resolution { ), scope = Parse.scope(substituteProps(dep.scope.name)), exclusions = dep.exclusions - .map{case (org, name) => (substituteProps(org), substituteProps(name))} - // FIXME The content of the optional tag may also be a property in the original POM. - // Maybe not parse it that earlier? + .map{case (org, name) => + (substituteProps(org), substituteProps(name)) + } + // FIXME The content of the optional tag may also be a property in + // the original POM. Maybe not parse it that earlier? ) } } /** - * Merge several version constraints together. Returns `None` in case of conflict. + * Merge several version constraints together. + * + * Returns `None` in case of conflict. */ def mergeVersions(versions: Seq[String]): Option[String] = { val (nonParsedConstraints, parsedConstraints) = @@ -126,30 +142,39 @@ object Resolution { // FIXME Report this in return type, not this way if (nonParsedConstraints.nonEmpty) - Console.err.println(s"Ignoring unparsed versions: ${nonParsedConstraints.map(_._1)}") + Console.err.println( + s"Ignoring unparsed versions: ${nonParsedConstraints.map(_._1)}" + ) - val constraintOpt = - (Option(VersionInterval.zero) /: parsedConstraints.map(_._2.get.interval)) { - case (acc, itv) => acc.flatMap(_.merge(itv)) - } .map(_.constraint) + val intervalOpt = + (Option(VersionInterval.zero) /: parsedConstraints) { + case (acc, (_, someCstr)) => + acc.flatMap(_.merge(someCstr.get.interval)) + } - constraintOpt.map(_.repr) + intervalOpt + .map(_.constraint.repr) } /** - * Merge several dependencies, solving version constraints of duplicated modules. - * Returns the conflicted dependencies, and the (merged) others. + * Merge several dependencies, solving version constraints of duplicated + * modules. + * + * Returns the conflicted dependencies, and the merged others. */ def merge( dependencies: TraversableOnce[Dependency] ): (Seq[Dependency], Seq[Dependency]) = { + val mergedByModVer = dependencies .toList .groupBy(dep => dep.module) .mapValues { deps => if (deps.lengthCompare(1) == 0) \/-(deps) else { - val versions = deps.map(_.version).distinct + val versions = deps + .map(_.version) + .distinct val versionOpt = mergeVersions(versions) versionOpt match { @@ -161,7 +186,9 @@ object Resolution { } } - val merged = mergedByModVer.values.toList + val merged = mergedByModVer + .values + .toList ( merged @@ -174,8 +201,9 @@ object Resolution { } /** - * If one of our dependency has scope `base`, and a transitive dependency of it has scope `transitive`, - * return the scope of the latter for us, if any. If empty, means the transitive dependency + * If one of our dependency has scope `base`, and a transitive + * dependency of it has scope `transitive`, return the scope of + * the latter for us, if any. If empty, means the transitive dependency * should not be considered a dependency for us. * * See https://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html#Dependency_Scope. @@ -185,16 +213,17 @@ object Resolution { transitive: Scope ): Option[Scope] = (base, transitive) match { - case (other, Scope.Compile) => Some(other) - case (Scope.Compile, Scope.Runtime) => Some(Scope.Runtime) - case (other, Scope.Runtime) => Some(other) - case _ => None + case (other, Scope.Compile) => Some(other) + case (Scope.Compile, Scope.Runtime) => Some(Scope.Runtime) + case (other, Scope.Runtime) => Some(other) + case _ => None } /** * Applies `dependencyManagement` to `dependencies`. * - * Fill empty version / scope / exclusions, for dependencies found in `dependencyManagement`. + * Fill empty version / scope / exclusions, for dependencies found in + * `dependencyManagement`. */ def depsWithDependencyManagement( dependencies: Seq[Dependency], @@ -243,31 +272,34 @@ object Resolution { dependencies .filter(dep => filter(dep.module.organization, dep.module.name)) .map(dep => - dep.copy(exclusions = Exclusions.minimize(dep.exclusions ++ exclusions)) + dep.copy( + exclusions = Exclusions.minimize(dep.exclusions ++ exclusions) + ) ) } /** - * Get the dependencies of `project`, knowing that it came from dependency `from` (that is, - * `from.module == project.module`). + * Get the dependencies of `project`, knowing that it came from dependency + * `from` (that is, `from.module == project.module`). * - * Substitute properties, update scopes, apply exclusions, and get extra parameters from - * dependency management along the way. + * Substitute properties, update scopes, apply exclusions, and get extra + * parameters from dependency management along the way. */ def finalDependencies( from: Dependency, project: Project ): Seq[Dependency] = { - // Here, we're substituting properties also in dependencies that come from parents - // or dependency management. This may not be the right thing to do. + // Here, we're substituting properties also in dependencies that + // come from parents or dependency management. This may not be + // the right thing to do. val properties = mergeProperties( project.properties, Map( - "project.groupId" -> project.module.organization, - "project.artifactId" -> project.module.name, - "project.version" -> project.version + "project.groupId" -> project.module.organization, + "project.artifactId" -> project.module.name, + "project.version" -> project.version ) ) @@ -287,32 +319,42 @@ object Resolution { deps .flatMap { trDep => resolveScope(from.scope, trDep.scope) - .map(scope => trDep.copy(scope = scope, optional = trDep.optional || from.optional)) + .map(scope => + trDep.copy( + scope = scope, + optional = trDep.optional || from.optional + ) + ) } } /** - * Default function checking whether a profile is active, given its id, activation conditions, - * and the properties of its project. + * Default function checking whether a profile is active, given + * its id, activation conditions, and the properties of its project. */ def defaultProfileActivation( id: String, activation: Activation, props: Map[String, String] - ): Boolean = { - - if (activation.properties.isEmpty) false - else { - activation.properties.forall { case (name, valueOpt) => - props.get(name).exists{ v => - valueOpt.forall { reqValue => - if (reqValue.startsWith("!")) v != reqValue.drop(1) - else v == reqValue - } + ): Boolean = + if (activation.properties.isEmpty) + false + else + activation + .properties + .forall {case (name, valueOpt) => + props + .get(name) + .exists{ v => + valueOpt + .forall { reqValue => + if (reqValue.startsWith("!")) + v != reqValue.drop(1) + else + v == reqValue + } + } } - } - } - } /** * Default dependency filter used during resolution. @@ -362,7 +404,9 @@ case class Resolution( } /** - * Transitive dependencies of the current dependencies, according to what there currently is in cache. + * Transitive dependencies of the current dependencies, according to + * what there currently is in cache. + * * No attempt is made to solve version conflicts here. */ def transitiveDependencies: Seq[Dependency] = @@ -371,13 +415,15 @@ case class Resolution( .flatMap(finalDependencies0) /** - * The "next" dependency set, made of the current dependencies and their transitive dependencies, - * trying to solve version conflicts. Transitive dependencies are calculated with the current cache. + * The "next" dependency set, made of the current dependencies and their + * transitive dependencies, trying to solve version conflicts. + * Transitive dependencies are calculated with the current cache. * - * May contain dependencies added in previous iterations, but no more required. These are filtered below, see - * `newDependencies`. + * May contain dependencies added in previous iterations, but no more + * required. These are filtered below, see `newDependencies`. * - * Returns a tuple made of the conflicting dependencies, and all the dependencies. + * Returns a tuple made of the conflicting dependencies, and all + * the dependencies. */ def nextDependenciesAndConflicts: (Seq[Dependency], Seq[Dependency]) = merge( @@ -389,8 +435,10 @@ case class Resolution( * The modules we miss some info about. */ def missingFromCache: Set[ModuleVersion] = { - val modules = dependencies.map(_.moduleVersion) - val nextModules = nextDependenciesAndConflicts._2.map(_.moduleVersion) + val modules = dependencies + .map(_.moduleVersion) + val nextModules = nextDependenciesAndConflicts._2 + .map(_.moduleVersion) (modules ++ nextModules) .filterNot(mod => projectCache.contains(mod) || errorCache.contains(mod)) @@ -411,10 +459,12 @@ case class Resolution( missingFromCache.isEmpty && isFixPoint } - private def eraseVersion(dep: Dependency) = dep.copy(version = "") + private def eraseVersion(dep: Dependency) = + dep.copy(version = "") /** - * Returns a map giving the dependencies that brought each of the dependency of the "next" dependency set. + * Returns a map giving the dependencies that brought each of + * the dependency of the "next" dependency set. * * The versions of all the dependencies returned are erased (emptied). */ @@ -481,6 +531,7 @@ case class Resolution( */ def newDependencies: Set[Dependency] = { val remainingDependencies0 = remainingDependencies + nextDependenciesAndConflicts._2 .filter(dep => remainingDependencies0(eraseVersion(dep))) .toSet @@ -496,8 +547,8 @@ case class Resolution( } /** - * If no module info is missing, the next state of the resolution, which can be immediately calculated. - * Else, the current resolution itself. + * If no module info is missing, the next state of the resolution, + * which can be immediately calculated. Else, the current resolution. */ @tailrec final def nextIfNoMissing: Resolution = { @@ -544,12 +595,12 @@ case class Resolution( } /** - * Missing modules in cache, to get the full list of dependencies of `project`, taking - * dependency management / inheritance into account. + * Missing modules in cache, to get the full list of dependencies of + * `project`, taking dependency management / inheritance into account. * - * Note that adding the missing modules to the cache may unveil other missing modules, so - * these modules should be added to the cache, and `dependencyManagementMissing` checked again - * for new missing modules. + * Note that adding the missing modules to the cache may unveil other + * missing modules, so these modules should be added to the cache, and + * `dependencyManagementMissing` checked again for new missing modules. */ def dependencyManagementMissing(project: Project): Set[ModuleVersion] = { @@ -587,9 +638,11 @@ case class Resolution( } /** - * Add dependency management / inheritance related items to `project`, from what's available in cache. - * It is recommended to have fetched what `dependencyManagementMissing` returned prior to calling - * `withDependencyManagement`. + * Add dependency management / inheritance related items to `project`, + * from what's available in cache. + * + * It is recommended to have fetched what `dependencyManagementMissing` + * returned prior to calling this. */ def withDependencyManagement(project: Project): Project = { @@ -613,12 +666,16 @@ case class Resolution( mergeProperties(acc, p.properties) } - val deps = + val deps = ( dependencies0 - .collect{ case dep if dep.scope == Scope.Import && projectCache.contains(dep.moduleVersion) => dep.moduleVersion } ++ - project.parent.filter(projectCache.contains) + .collect { case dep if dep.scope == Scope.Import => + dep.moduleVersion + } ++ + project.parent + ).filter(projectCache.contains) - val projs = deps.map(projectCache(_)._2) + val projs = deps + .map(projectCache(_)._2) val depMgmt = ( project.dependencyManagement +: ( @@ -630,8 +687,11 @@ case class Resolution( val depsSet = deps.toSet project.copy( - dependencies = dependencies0 - .filterNot(dep => dep.scope == Scope.Import && depsSet(dep.moduleVersion)) ++ + dependencies = + dependencies0 + .filterNot(dep => + dep.scope == Scope.Import && depsSet(dep.moduleVersion) + ) ++ project.parent .filter(projectCache.contains) .toSeq @@ -650,13 +710,18 @@ case class Resolution( def artifacts: Seq[Artifact] = for { dep <- minDependencies.toSeq - (source, proj) <- projectCache.get(dep.moduleVersion).toSeq - artifact <- source.artifacts(dep, proj) + (source, proj) <- projectCache + .get(dep.moduleVersion) + .toSeq + artifact <- source + .artifacts(dep, proj) } yield artifact def errors: Seq[(Dependency, Seq[String])] = for { dep <- dependencies.toSeq - err <- errorCache.get(dep.moduleVersion).toSeq + err <- errorCache + .get(dep.moduleVersion) + .toSeq } yield (dep, err) } diff --git a/core/src/main/scala/coursier/core/ResolutionProcess.scala b/core/src/main/scala/coursier/core/ResolutionProcess.scala index f88c45631..5e19adf25 100644 --- a/core/src/main/scala/coursier/core/ResolutionProcess.scala +++ b/core/src/main/scala/coursier/core/ResolutionProcess.scala @@ -122,7 +122,11 @@ object ResolutionProcess { Missing(resolution0.missingFromCache.toSeq, resolution0, apply) } - type FetchResult = Seq[((Module, String), Seq[String] \/ (Artifact.Source, Project))] + type FetchResult = Seq[( + (Module, String), + Seq[String] \/ (Artifact.Source, Project) + )] + type Fetch[F[_]] = Seq[(Module, String)] => F[FetchResult] } diff --git a/core/src/main/scala/coursier/package.scala b/core/src/main/scala/coursier/package.scala index c50456072..dcbeeec53 100644 --- a/core/src/main/scala/coursier/package.scala +++ b/core/src/main/scala/coursier/package.scala @@ -7,19 +7,31 @@ package object coursier { type Dependency = core.Dependency object Dependency { - def apply(module: Module, - version: String, - scope: Scope = Scope.Other(""), // Substituted by Resolver with its own default scope (compile) - attributes: Attributes = Attributes(), - exclusions: Set[(String, String)] = Set.empty, - optional: Boolean = false): Dependency = - core.Dependency(module, version, scope, attributes, exclusions, optional) + def apply( + module: Module, + version: String, + // Substituted by Resolver with its own default scope (compile) + scope: Scope = Scope.Other(""), + attributes: Attributes = Attributes(), + exclusions: Set[(String, String)] = Set.empty, + optional: Boolean = false + ): Dependency = + core.Dependency( + module, + version, + scope, + attributes, + exclusions, + optional + ) } type Attributes = core.Attributes object Attributes { - def apply(`type`: String = "jar", - classifier: String = ""): Attributes = + def apply( + `type`: String = "jar", + classifier: String = "" + ): Attributes = core.Attributes(`type`, classifier) } @@ -46,14 +58,24 @@ package object coursier { type Resolution = core.Resolution object Resolution { val empty = apply() - def apply(rootDependencies: Set[Dependency] = Set.empty, - dependencies: Set[Dependency] = Set.empty, - conflicts: Set[Dependency] = Set.empty, - projectCache: Map[ModuleVersion, (Artifact.Source, Project)] = Map.empty, - errorCache: Map[ModuleVersion, Seq[String]] = Map.empty, - filter: Option[Dependency => Boolean] = None, - profileActivation: Option[(String, core.Activation, Map[String, String]) => Boolean] = None): Resolution = - core.Resolution(rootDependencies, dependencies, conflicts, projectCache, errorCache, filter, profileActivation) + def apply( + rootDependencies: Set[Dependency] = Set.empty, + dependencies: Set[Dependency] = Set.empty, + conflicts: Set[Dependency] = Set.empty, + projectCache: Map[ModuleVersion, (Artifact.Source, Project)] = Map.empty, + errorCache: Map[ModuleVersion, Seq[String]] = Map.empty, + filter: Option[Dependency => Boolean] = None, + profileActivation: Option[(String, core.Activation, Map[String, String]) => Boolean] = None + ): Resolution = + core.Resolution( + rootDependencies, + dependencies, + conflicts, + projectCache, + errorCache, + filter, + profileActivation + ) } type Artifact = core.Artifact @@ -63,18 +85,22 @@ package object coursier { val ResolutionProcess: core.ResolutionProcess.type = core.ResolutionProcess implicit class ResolutionExtensions(val underlying: Resolution) extends AnyVal { + def process: ResolutionProcess = ResolutionProcess(underlying) } - implicit def fetch(repositories: Seq[core.Repository]): ResolutionProcess.Fetch[Task] = { + implicit def fetch( + repositories: Seq[core.Repository] + ): ResolutionProcess.Fetch[Task] = { + modVers => Task.gatherUnordered( modVers - .map(modVer => - Repository.find(repositories, modVer._1, modVer._2) + .map {case (module, version) => + Repository.find(repositories, module, version) .run - .map(modVer -> _) - ) + .map((module, version) -> _) + } ) }