diff --git a/core/shared/src/main/scala/coursier/core/Definitions.scala b/core/shared/src/main/scala/coursier/core/Definitions.scala index 3d85be538..de4604840 100644 --- a/core/shared/src/main/scala/coursier/core/Definitions.scala +++ b/core/shared/src/main/scala/coursier/core/Definitions.scala @@ -69,7 +69,7 @@ case class Project( // Maven-specific parent: Option[(Module, String)], dependencyManagement: Seq[(String, Dependency)], - properties: Map[String, String], + properties: Seq[(String, String)], profiles: Seq[Profile], versions: Option[Versions], snapshotVersioning: Option[SnapshotVersioning], diff --git a/core/shared/src/main/scala/coursier/core/Resolution.scala b/core/shared/src/main/scala/coursier/core/Resolution.scala index ea035dd40..5db05a72d 100644 --- a/core/shared/src/main/scala/coursier/core/Resolution.scala +++ b/core/shared/src/main/scala/coursier/core/Resolution.scala @@ -56,12 +56,6 @@ object Resolution { (dict /: deps)(add) } - def mergeProperties( - dict: Map[String, String], - other: Map[String, String] - ): Map[String, String] = - dict ++ other.filterKeys(!dict.contains(_)) - def addDependencies(deps: Seq[Seq[(String, Dependency)]]): Seq[(String, Dependency)] = { val res = (deps :\ (Set.empty[DepMgmt.Key], Seq.empty[(String, Dependency)])) { @@ -79,6 +73,32 @@ object Resolution { quote("${") + "([a-zA-Z0-9-.]*)" + quote("}") ).r + def substituteProps(s: String, properties: Map[String, String]) = { + val matches = propRegex + .findAllMatchIn(s) + .toList + .reverse + + if (matches.isEmpty) s + else { + val output = + (new StringBuilder(s) /: matches) { (b, m) => + properties + .get(m.group(1)) + .fold(b)(b.replace(m.start, m.end, _)) + } + + output.result() + } + } + + def propertiesMap(props: Seq[(String, String)]): Map[String, String] = + props.foldLeft(Map.empty[String, String]) { + case (acc, (k, v0)) => + val v = substituteProps(v0, acc) + acc + (k -> v) + } + /** * Substitutes `properties` in `dependencies`. */ @@ -87,41 +107,25 @@ object Resolution { properties: Map[String, String] ): Seq[(String, Dependency)] = { - def substituteProps(s: String) = { - val matches = propRegex - .findAllMatchIn(s) - .toList - .reverse - - if (matches.isEmpty) s - else { - val output = - (new StringBuilder(s) /: matches) { (b, m) => - properties - .get(m.group(1)) - .fold(b)(b.replace(m.start, m.end, _)) - } - - output.result() - } - } + def substituteProps0(s: String) = + substituteProps(s, properties) dependencies .map {case (config, dep) => - substituteProps(config) -> dep.copy( + substituteProps0(config) -> dep.copy( module = dep.module.copy( - organization = substituteProps(dep.module.organization), - name = substituteProps(dep.module.name) + organization = substituteProps0(dep.module.organization), + name = substituteProps0(dep.module.name) ), - version = substituteProps(dep.version), + version = substituteProps0(dep.version), attributes = dep.attributes.copy( - `type` = substituteProps(dep.attributes.`type`), - classifier = substituteProps(dep.attributes.classifier) + `type` = substituteProps0(dep.attributes.`type`), + classifier = substituteProps0(dep.attributes.classifier) ), - configuration = substituteProps(dep.configuration), + configuration = substituteProps0(dep.configuration), exclusions = dep.exclusions .map{case (org, name) => - (substituteProps(org), substituteProps(name)) + (substituteProps0(org), substituteProps0(name)) } // FIXME The content of the optional tag may also be a property in // the original POM. Maybe not parse it that earlier? @@ -320,15 +324,14 @@ object Resolution { // 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 - ) + val properties0 = project.properties ++ Seq( + "project.groupId" -> project.module.organization, + "project.artifactId" -> project.module.name, + "project.version" -> project.version ) + val properties = propertiesMap(properties0) + val configurations = withParentConfigurations(from.configuration, project.configurations) withExclusions( @@ -604,11 +607,13 @@ case class Resolution( project: Project ): Set[ModuleVersion] = { - val approxProperties = + val approxProperties0 = project.parent .flatMap(projectCache.get) .map(_._2.properties) - .fold(project.properties)(mergeProperties(project.properties, _)) + .fold(project.properties)(project.properties ++ _) + + val approxProperties = propertiesMap(approxProperties0) val profileDependencies = profiles( @@ -678,11 +683,13 @@ case class Resolution( */ def withDependencyManagement(project: Project): Project = { - val approxProperties = + val approxProperties0 = project.parent .filter(projectCache.contains) - .map(projectCache(_)._2.properties) - .fold(project.properties)(mergeProperties(project.properties, _)) + .map(projectCache(_)._2.properties.toMap) + .fold(project.properties)(project.properties ++ _) + + val approxProperties = propertiesMap(approxProperties0) val profiles0 = profiles( project, @@ -695,7 +702,7 @@ case class Resolution( ) val properties0 = (project.properties /: profiles0) { (acc, p) => - mergeProperties(acc, p.properties) + acc ++ p.properties } val deps = ( @@ -732,7 +739,7 @@ case class Resolution( properties = project.parent .filter(projectCache.contains) .map(projectCache(_)._2.properties) - .fold(properties0)(mergeProperties(properties0, _)) + .fold(properties0)(properties0 ++ _) ) } diff --git a/core/shared/src/main/scala/coursier/ivy/IvyXml.scala b/core/shared/src/main/scala/coursier/ivy/IvyXml.scala index 467c8dd48..dcc1a0a6f 100644 --- a/core/shared/src/main/scala/coursier/ivy/IvyXml.scala +++ b/core/shared/src/main/scala/coursier/ivy/IvyXml.scala @@ -132,7 +132,7 @@ object IvyXml { configurations0.toMap, None, Nil, - Map.empty, + Nil, Nil, None, None, diff --git a/core/shared/src/main/scala/coursier/maven/Pom.scala b/core/shared/src/main/scala/coursier/maven/Pom.scala index 433d90c84..8e357e303 100644 --- a/core/shared/src/main/scala/coursier/maven/Pom.scala +++ b/core/shared/src/main/scala/coursier/maven/Pom.scala @@ -229,7 +229,7 @@ object Pom { Map.empty, parentModuleOpt.map((_, parentVersionOpt.getOrElse(""))), depMgmts, - properties.toMap, + properties, profiles, None, None,