mirror of https://github.com/sbt/sbt.git
Add support for attributes
This commit is contained in:
parent
a3188a9b8a
commit
f52e2ecca4
|
|
@ -158,8 +158,22 @@ class Helper(
|
||||||
}
|
}
|
||||||
|
|
||||||
val moduleVersions = splitDependencies.map{
|
val moduleVersions = splitDependencies.map{
|
||||||
case Seq(org, name, version) =>
|
case Seq(org, namePart, version) =>
|
||||||
(Module(org, name), version)
|
val p = namePart.split(';')
|
||||||
|
val name = p.head
|
||||||
|
val splitAttributes = p.tail.map(_.split("=", 2).toSeq).toSeq
|
||||||
|
val malformedAttributes = splitAttributes.filter(_.length != 2)
|
||||||
|
if (malformedAttributes.nonEmpty) {
|
||||||
|
// FIXME Get these for all dependencies at once
|
||||||
|
Console.err.println(s"Malformed attributes in ${splitDependencies.mkString(":")}")
|
||||||
|
// :(
|
||||||
|
sys.exit(255)
|
||||||
|
}
|
||||||
|
val attributes = splitAttributes.collect {
|
||||||
|
case Seq(k, v) => k -> v
|
||||||
|
}
|
||||||
|
println(s"-> $org:$name:$attributes")
|
||||||
|
(Module(org, name, attributes.toMap), version)
|
||||||
}
|
}
|
||||||
|
|
||||||
val deps = moduleVersions.map{case (mod, ver) =>
|
val deps = moduleVersions.map{case (mod, ver) =>
|
||||||
|
|
|
||||||
|
|
@ -51,7 +51,7 @@ package object compatibility {
|
||||||
.map(l => List.tabulate(l.length)(l.item).map(fromNode))
|
.map(l => List.tabulate(l.length)(l.item).map(fromNode))
|
||||||
.getOrElse(Nil)
|
.getOrElse(Nil)
|
||||||
|
|
||||||
def attributes: Seq[(String, String)] = ???
|
def attributes = ???
|
||||||
|
|
||||||
// `exists` instead of `contains`, for scala 2.10
|
// `exists` instead of `contains`, for scala 2.10
|
||||||
def isText =
|
def isText =
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ package coursier.core
|
||||||
|
|
||||||
import coursier.util.Xml
|
import coursier.util.Xml
|
||||||
|
|
||||||
import scala.xml.{ MetaData, Null }
|
import scala.xml.{ Attribute, MetaData, Null }
|
||||||
|
|
||||||
package object compatibility {
|
package object compatibility {
|
||||||
|
|
||||||
|
|
@ -19,14 +19,20 @@ package object compatibility {
|
||||||
def fromNode(node: scala.xml.Node): Xml.Node =
|
def fromNode(node: scala.xml.Node): Xml.Node =
|
||||||
new Xml.Node {
|
new Xml.Node {
|
||||||
lazy val attributes = {
|
lazy val attributes = {
|
||||||
def helper(m: MetaData): Stream[(String, String)] =
|
def helper(m: MetaData): Stream[(String, String, String)] =
|
||||||
m match {
|
m match {
|
||||||
case Null => Stream.empty
|
case Null => Stream.empty
|
||||||
case attr =>
|
case attr =>
|
||||||
|
val pre = attr match {
|
||||||
|
case a: Attribute => Option(node.getNamespace(a.pre)).getOrElse("")
|
||||||
|
case _ => ""
|
||||||
|
}
|
||||||
|
|
||||||
val value = attr.value.collect {
|
val value = attr.value.collect {
|
||||||
case scala.xml.Text(t) => t
|
case scala.xml.Text(t) => t
|
||||||
}.mkString("")
|
}.mkString("")
|
||||||
(attr.key -> value) #:: helper(m.next)
|
|
||||||
|
(pre, attr.key, value) #:: helper(m.next)
|
||||||
}
|
}
|
||||||
|
|
||||||
helper(node.attributes).toVector
|
helper(node.attributes).toVector
|
||||||
|
|
|
||||||
|
|
@ -8,12 +8,11 @@ package coursier.core
|
||||||
* between them.
|
* between them.
|
||||||
*
|
*
|
||||||
* Using the same terminology as Ivy.
|
* Using the same terminology as Ivy.
|
||||||
*
|
|
||||||
* Ivy attributes would land here, if support for it is added.
|
|
||||||
*/
|
*/
|
||||||
case class Module(
|
case class Module(
|
||||||
organization: String,
|
organization: String,
|
||||||
name: String
|
name: String,
|
||||||
|
attributes: Map[String, String]
|
||||||
) {
|
) {
|
||||||
|
|
||||||
def trim: Module = copy(
|
def trim: Module = copy(
|
||||||
|
|
@ -21,7 +20,14 @@ case class Module(
|
||||||
name = name.trim
|
name = name.trim
|
||||||
)
|
)
|
||||||
|
|
||||||
override def toString = s"$organization:$name"
|
private def attributesStr = attributes.toSeq
|
||||||
|
.sortBy { case (k, _) => k }
|
||||||
|
.map { case (k, v) => s"$k=$v" }
|
||||||
|
.mkString(";")
|
||||||
|
|
||||||
|
override def toString =
|
||||||
|
s"$organization:$name" +
|
||||||
|
(if (attributes.nonEmpty) s";$attributesStr" else "")
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -145,23 +145,22 @@ case class IvyRepository(
|
||||||
// list of variables that should be supported.
|
// list of variables that should be supported.
|
||||||
// Some are missing (branch, conf, originalName).
|
// Some are missing (branch, conf, originalName).
|
||||||
private def variables(
|
private def variables(
|
||||||
org: String,
|
module: Module,
|
||||||
name: String,
|
|
||||||
version: String,
|
version: String,
|
||||||
`type`: String,
|
`type`: String,
|
||||||
artifact: String,
|
artifact: String,
|
||||||
ext: String
|
ext: String
|
||||||
) =
|
) =
|
||||||
Map(
|
Map(
|
||||||
"organization" -> org,
|
"organization" -> module.organization,
|
||||||
"organisation" -> org,
|
"organisation" -> module.organization,
|
||||||
"orgPath" -> org.replace('.', '/'),
|
"orgPath" -> module.organization.replace('.', '/'),
|
||||||
"module" -> name,
|
"module" -> module.name,
|
||||||
"revision" -> version,
|
"revision" -> version,
|
||||||
"type" -> `type`,
|
"type" -> `type`,
|
||||||
"artifact" -> artifact,
|
"artifact" -> artifact,
|
||||||
"ext" -> ext
|
"ext" -> ext
|
||||||
)
|
) ++ module.attributes
|
||||||
|
|
||||||
|
|
||||||
val source: Artifact.Source = new Artifact.Source {
|
val source: Artifact.Source = new Artifact.Source {
|
||||||
|
|
@ -191,8 +190,7 @@ case class IvyRepository(
|
||||||
|
|
||||||
val retainedWithUrl = retained.flatMap { p =>
|
val retainedWithUrl = retained.flatMap { p =>
|
||||||
substitute(variables(
|
substitute(variables(
|
||||||
dependency.module.organization,
|
dependency.module,
|
||||||
dependency.module.name,
|
|
||||||
dependency.version,
|
dependency.version,
|
||||||
p.`type`,
|
p.`type`,
|
||||||
p.name,
|
p.name,
|
||||||
|
|
@ -225,7 +223,9 @@ case class IvyRepository(
|
||||||
|
|
||||||
val eitherArtifact: String \/ Artifact =
|
val eitherArtifact: String \/ Artifact =
|
||||||
for {
|
for {
|
||||||
url <- substitute(variables(module.organization, module.name, version, "ivy", "ivy", "xml"))
|
url <- substitute(
|
||||||
|
variables(module, version, "ivy", "ivy", "xml")
|
||||||
|
)
|
||||||
} yield
|
} yield
|
||||||
Artifact(
|
Artifact(
|
||||||
url,
|
url,
|
||||||
|
|
|
||||||
|
|
@ -7,12 +7,15 @@ import scalaz.{ Node => _, _ }, Scalaz._
|
||||||
|
|
||||||
object IvyXml {
|
object IvyXml {
|
||||||
|
|
||||||
|
val attributesNamespace = "http://ant.apache.org/ivy/extra"
|
||||||
|
|
||||||
private def info(node: Node): String \/ (Module, String) =
|
private def info(node: Node): String \/ (Module, String) =
|
||||||
for {
|
for {
|
||||||
org <- node.attribute("organisation")
|
org <- node.attribute("organisation")
|
||||||
name <- node.attribute("module")
|
name <- node.attribute("module")
|
||||||
version <- node.attribute("revision")
|
version <- node.attribute("revision")
|
||||||
} yield (Module(org, name), version)
|
attr = node.attributesFromNamespace(attributesNamespace)
|
||||||
|
} yield (Module(org, name, attr.toMap), version)
|
||||||
|
|
||||||
// FIXME Errors are ignored here
|
// FIXME Errors are ignored here
|
||||||
private def configurations(node: Node): Seq[(String, Seq[String])] =
|
private def configurations(node: Node): Seq[(String, Seq[String])] =
|
||||||
|
|
@ -53,8 +56,9 @@ object IvyXml {
|
||||||
(fromConf, toConf) <- rawConf.split(',').toSeq.map(_.split("->", 2)).collect {
|
(fromConf, toConf) <- rawConf.split(',').toSeq.map(_.split("->", 2)).collect {
|
||||||
case Array(from, to) => from -> to
|
case Array(from, to) => from -> to
|
||||||
}
|
}
|
||||||
|
attr = node.attributesFromNamespace(attributesNamespace)
|
||||||
} yield fromConf -> Dependency(
|
} yield fromConf -> Dependency(
|
||||||
Module(org, name),
|
Module(org, name, attr.toMap),
|
||||||
version,
|
version,
|
||||||
toConf,
|
toConf,
|
||||||
allConfsExcludes ++ excludes.getOrElse(fromConf, Set.empty),
|
allConfsExcludes ++ excludes.getOrElse(fromConf, Set.empty),
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,7 @@ object Pom {
|
||||||
else e
|
else e
|
||||||
}
|
}
|
||||||
name <- text(node, "artifactId", "Name")
|
name <- text(node, "artifactId", "Name")
|
||||||
} yield Module(organization, name).trim
|
} yield Module(organization, name, Map.empty).trim
|
||||||
}
|
}
|
||||||
|
|
||||||
private def readVersion(node: Node) =
|
private def readVersion(node: Node) =
|
||||||
|
|
@ -307,7 +307,7 @@ object Pom {
|
||||||
.toList
|
.toList
|
||||||
.traverseU(snapshotVersion)
|
.traverseU(snapshotVersion)
|
||||||
} yield SnapshotVersioning(
|
} yield SnapshotVersioning(
|
||||||
Module(organization, name),
|
Module(organization, name, Map.empty),
|
||||||
version,
|
version,
|
||||||
latest,
|
latest,
|
||||||
release,
|
release,
|
||||||
|
|
|
||||||
|
|
@ -42,8 +42,8 @@ package object coursier {
|
||||||
|
|
||||||
type Module = core.Module
|
type Module = core.Module
|
||||||
object Module {
|
object Module {
|
||||||
def apply(organization: String, name: String): Module =
|
def apply(organization: String, name: String, attributes: Map[String, String] = Map.empty): Module =
|
||||||
core.Module(organization, name)
|
core.Module(organization, name, attributes)
|
||||||
}
|
}
|
||||||
|
|
||||||
type ModuleVersion = (core.Module, String)
|
type ModuleVersion = (core.Module, String)
|
||||||
|
|
|
||||||
|
|
@ -7,13 +7,20 @@ object Xml {
|
||||||
/** A representation of an XML node/document, with different implementations on JVM and JS */
|
/** A representation of an XML node/document, with different implementations on JVM and JS */
|
||||||
trait Node {
|
trait Node {
|
||||||
def label: String
|
def label: String
|
||||||
def attributes: Seq[(String, String)]
|
/** Namespace / key / value */
|
||||||
|
def attributes: Seq[(String, String, String)]
|
||||||
def children: Seq[Node]
|
def children: Seq[Node]
|
||||||
def isText: Boolean
|
def isText: Boolean
|
||||||
def textContent: String
|
def textContent: String
|
||||||
def isElement: Boolean
|
def isElement: Boolean
|
||||||
|
|
||||||
lazy val attributesMap = attributes.toMap
|
def attributesFromNamespace(namespace: String): Seq[(String, String)] =
|
||||||
|
attributes.collect {
|
||||||
|
case (`namespace`, k, v) =>
|
||||||
|
k -> v
|
||||||
|
}
|
||||||
|
|
||||||
|
lazy val attributesMap = attributes.map { case (_, k, v) => k -> v }.toMap
|
||||||
def attribute(name: String): String \/ String =
|
def attribute(name: String): String \/ String =
|
||||||
attributesMap.get(name) match {
|
attributesMap.get(name) match {
|
||||||
case None => -\/(s"Missing attribute $name")
|
case None => -\/(s"Missing attribute $name")
|
||||||
|
|
|
||||||
|
|
@ -406,7 +406,10 @@ object App {
|
||||||
}
|
}
|
||||||
|
|
||||||
val sortedDeps = res.minDependencies.toList
|
val sortedDeps = res.minDependencies.toList
|
||||||
.sortBy(dep => coursier.core.Module.unapply(dep.module).get)
|
.sortBy { dep =>
|
||||||
|
val (org, name, _) = coursier.core.Module.unapply(dep.module).get
|
||||||
|
(org, name)
|
||||||
|
}
|
||||||
|
|
||||||
<.table(^.`class` := "table",
|
<.table(^.`class` := "table",
|
||||||
<.thead(
|
<.thead(
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue