Fixes #1275. Fixes pom dynamic revision conversion

Ivy and pom uses slightly different notation for version range and
dynamic revision.
This change fixes the dynamic revisions involving “+”.
First, when a revision like “1.1+” is found, it will now be treated as
“1.+”.
Next, when it finds a revision like “1+” is found, it will be treated
as “+”.
The conversion of “+” is hardcoded to be “[0,)”.
This commit is contained in:
Eugene Yokota 2014-08-16 22:38:35 -04:00
parent 05c77ae1e9
commit 697a28771e
3 changed files with 78 additions and 41 deletions

View File

@ -196,6 +196,7 @@ class MakePom(val log: Logger) {
</dependency>
}
/** Converts Ivy revision ranges to that of Maven POM */
def makeDependencyVersion(revision: String): String = {
def plusRange(s: String, shift: Int = 0) = {
def pow(i: Int): Int = if (i > 0) 10 * pow(i - 1) else 1
@ -209,20 +210,24 @@ class MakePom(val log: Logger) {
}
val startSym = Set(']', '[', '(')
val stopSym = Set(']', '[', ')')
val PlusPattern = """(.+)(\.\d*\+)""".r
try {
if (revision endsWith ".+") {
plusRange(revision.substring(0, revision.length - 2))
} else if (revision endsWith "+") {
val base = revision.take(revision.length - 1)
// This is a heuristic. Maven just doesn't support Ivy's notions of 1+, so
// we assume version ranges never go beyond 5 siginificant digits.
(0 to 5).map(plusRange(base, _)).mkString(",")
} else if (startSym(revision(0)) && stopSym(revision(revision.length - 1))) {
val start = revision(0)
val stop = revision(revision.length - 1)
val mid = revision.substring(1, revision.length - 1)
(if (start == ']') "(" else start) + mid + (if (stop == '[') ")" else stop)
} else revision
revision match {
case PlusPattern(base, tail) => plusRange(base)
// There's no direct translation for a dynamic revision like "1+".
// This is likely the build user misunderstanding the meaning of "+",
// which means pick the latest in the version segment.
// So if someone wanted (1.0 <= x), then it should be "[1.0)" or "1.+".
// Technically speaking, "1+" should convert to "LATEST",
// but that seems to be deprecated now, so picking the minimum version "0".
case rev if rev endsWith "+" => "[0,)"
case rev if startSym(rev(0)) && stopSym(rev(rev.length - 1)) =>
val start = rev(0)
val stop = rev(rev.length - 1)
val mid = rev.substring(1, rev.length - 1)
(if (start == ']') "(" else start) + mid + (if (stop == '[') ")" else stop)
case _ => revision
}
} catch {
case e: NumberFormatException =>
// TODO - if the version doesn't meet our expectations, maybe we just issue a hard

View File

@ -0,0 +1,60 @@
package sbt
import java.io.File
import org.specs2._
// http://ant.apache.org/ivy/history/2.3.0/ivyfile/dependency.html
// http://maven.apache.org/enforcer/enforcer-rules/versionRanges.html
class MakePomSpec extends Specification {
def is = s2"""
This is a specification to check the Ivy revision number conversion to pom.
1.0 should
${convertTo("1.0", "1.0")}
[1.0,2.0] should
${convertTo("[1.0,2.0]", "[1.0,2.0]")}
[1.0,2.0[ should
${convertTo("[1.0,2.0[", "[1.0,2.0)")}
]1.0,2.0] should
${convertTo("]1.0,2.0]", "(1.0,2.0]")}
]1.0,2.0[ should
${convertTo("]1.0,2.0[", "(1.0,2.0)")}
[1.0,) should
${convertTo("[1.0,)", "[1.0,)")}
]1.0,) should
${convertTo("]1.0,)", "(1.0,)")}
(,2.0] should
${convertTo("(,2.0]", "(,2.0]")}
(,2.0[ should
${convertTo("(,2.0[", "(,2.0)")}
1.+ should
${convertTo("1.+", "[1,2)")}
1.2.3.4.+ should
${convertTo("1.2.3.4.+", "[1.2.3.4,1.2.3.5)")}
12.31.42.+ should
${convertTo("12.31.42.+", "[12.31.42,12.31.43)")}
1.1+ should
${convertTo("1.1+", "[1,2)")}
1+ should
${convertTo("1+", "[0,)")}
"""
val mp = new MakePom(ConsoleLogger())
def convertTo(s: String, expected: String) =
mp.makeDependencyVersion(s) must_== expected
}

View File

@ -1,28 +0,0 @@
package sbt
import java.io.File
import org.specs2._
import mutable.Specification
object MakePomTest extends Specification {
val mp = new MakePom(ConsoleLogger())
import mp.{ makeDependencyVersion => v }
"MakePom makeDependencyVersion" should {
"Handle .+ in versions" in {
v("1.+") must_== "[1,2)"
v("1.2.3.4.+") must_== "[1.2.3.4,1.2.3.5)"
v("12.31.42.+") must_== "[12.31.42,12.31.43)"
}
/* TODO - do we care about this case?
* 1+ --> [1,2),[10,20),[100,200),[1000,2000),[10000,20000),[100000,200000)
*/
"Handle ]* bracket in version ranges" in {
v("]1,3]") must_== "(1,3]"
v("]1.1,1.3]") must_== "(1.1,1.3]"
}
"Handle *[ bracket in version ranges" in {
v("[1,3[") must_== "[1,3)"
v("[1.1,1.3[") must_== "[1.1,1.3)"
}
}
}