Skip to content

Commit 1545885

Browse files
committed
resolves #394 fix gem requirements resolution
1 parent d8f1358 commit 1545885

File tree

3 files changed

+81
-63
lines changed

3 files changed

+81
-63
lines changed

base-plugin/src/integTest/groovy/com/github/jrubygradle/JRubyPrepareGemsIntegrationSpec.groovy

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,27 @@ class JRubyPrepareGemsIntegrationSpec extends IntegrationSpecification {
7676
new File(projectDir, "gems/rack-1.6.12").exists()
7777
}
7878

79+
@IgnoreIf({ IntegrationSpecification.OFFLINE })
80+
void "Check if selenium-webdriver version gets resolved"() {
81+
setup:
82+
withPreamble """repositories.ruby.gems()
83+
jrubyPrepare.outputDir = '${pathAsUriStr(projectDir)}'.toURI()
84+
"""
85+
86+
withDependencies """
87+
gems 'rubygems:selenium-webdriver:3.142.6'
88+
gems 'rubygems:webdrivers:4.1.3'
89+
"""
90+
91+
when:
92+
build()
93+
94+
then:
95+
// since we need a version range in the setup the
96+
// resolved version here can vary over time
97+
new File(projectDir, "gems/selenium-webdriver-3.142.6").exists()
98+
}
99+
79100
@IgnoreIf({ IntegrationSpecification.OFFLINE })
80101
void "Check that GEM dependencies are locked"() {
81102
setup:

core-plugin/src/main/groovy/com/github/jrubygradle/api/gems/GemVersion.groovy

Lines changed: 42 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,7 @@ class GemVersion implements Comparable<GemVersion> {
177177
gemVersions.first()
178178
} else {
179179
gemVersions[1..-1].inject(gemVersions.first()) { range, value ->
180-
range.union(value)
180+
range.intersect(value)
181181
}
182182
}
183183
}
@@ -300,66 +300,53 @@ class GemVersion implements Comparable<GemVersion> {
300300
* @since 2.0
301301
*/
302302
GemVersion intersect(GemVersion other) {
303-
Boundary newLowBoundary
304-
String newLow
305-
switch (compare(low, other.low)) {
306-
case -1:
307-
newLow = other.low
308-
newLowBoundary = other.lowBoundary
309-
break
310-
case 0:
311-
newLowBoundary = (lowBoundary == EXCLUSIVE || other.lowBoundary == EXCLUSIVE) ? EXCLUSIVE : INCLUSIVE
312-
newLow = low
313-
break
314-
case 1:
315-
newLow = low
316-
newLowBoundary = lowBoundary
303+
Tuple2<String, Boundary> newLowVersionSpec = intersect(low, lowBoundary, other.low, other.lowBoundary, true)
304+
Tuple2<String, Boundary> newHighVersionSpec = intersect(high, highBoundary, other.high, other.highBoundary, false)
305+
GemVersion intersection = new GemVersion(newLowVersionSpec.second, newLowVersionSpec.first, newHighVersionSpec.first, newHighVersionSpec.second)
306+
if (intersection == this) {
307+
// is other a subset of this?
308+
if (compare(this.low, other.low) >= 0 && compare(other.low, this.high) < 0 && compare(this.high, other.high) <= 0) {
309+
return intersection
310+
}
311+
return NO_VERSION
317312
}
318-
319-
Boundary newHighBoundary
320-
String newHigh
321-
322-
if (!high && other.high) {
323-
newHigh = other.high
324-
newHighBoundary = other.highBoundary
325-
} else if (high && !other.high) {
326-
newHigh = high
327-
newHighBoundary = highBoundary
328-
} else if (!high && !other.high) {
329-
newHigh = null
330-
newHighBoundary = highBoundary
331-
} else {
332-
switch (compare(high, other.high)) {
333-
case 1:
334-
newHigh = other.high
335-
newHighBoundary = other.highBoundary
336-
break
337-
case 0:
338-
newHighBoundary = (highBoundary == EXCLUSIVE || other.highBoundary == EXCLUSIVE) ? EXCLUSIVE : INCLUSIVE
339-
newHigh = high
340-
break
341-
case -1:
342-
newHigh = high
343-
newHighBoundary = highBoundary
313+
if (intersection == other) {
314+
// is this a subset of other?
315+
if (compare(other.low, this.low) >= 0 && compare(this.low, other.high) < 0 && compare(other.high, this.high) <= 0) {
316+
return intersection
344317
}
318+
return NO_VERSION
345319
}
346-
return new GemVersion(newLowBoundary, newLow, newHigh, newHighBoundary)
320+
return intersection
347321
}
348322

349-
/** Creates a new GEM version requirement which that the lowest of two requirements and the highest
350-
* of those same requirement
351-
*
352-
* @param other Other GEM to combine with
353-
* @return New GEM version requirement.
354-
*
355-
* @since 2.0
356-
*/
357-
GemVersion union(GemVersion other) {
358-
List<GemVersion> pair = [this, other]
359-
GemVersion min = pair.min()
360-
GemVersion max = pair.max()
323+
Tuple2<String,Boundary> intersect(String version, Boundary boundary, String otherVersion, Boundary otherBoundary, boolean low) {
324+
Boundary newBoundary
325+
String newVersion
326+
if (!version && otherVersion) {
327+
newVersion = otherVersion
328+
newBoundary = otherBoundary
329+
} else if (version && !otherVersion) {
330+
newVersion = version
331+
newBoundary = boundary
332+
} else if (!version && !otherVersion) {
333+
newVersion = null
334+
newBoundary = boundary
335+
} else {
336+
int compareLow = low ? compare(version, otherVersion) : compare(otherVersion, version)
337+
if (compareLow < 0) {
338+
newVersion = otherVersion
339+
newBoundary = otherBoundary
340+
} else if (compareLow > 0) {
341+
newVersion = version
342+
newBoundary = boundary
343+
} else {
344+
newBoundary = (boundary == INCLUSIVE || otherBoundary == INCLUSIVE) ? INCLUSIVE : EXCLUSIVE
345+
newVersion = version
346+
}
347+
}
361348

362-
new GemVersion(min.lowBoundary, min.low, max.high, max.highBoundary)
349+
return new Tuple2(newVersion, newBoundary)
363350
}
364351

365352
/** Allows for versions to be compared and sorted.

core-plugin/src/test/groovy/com/github/jrubygradle/api/gems/GemVersionSpec.groovy

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@
2323
*/
2424
package com.github.jrubygradle.api.gems
2525

26-
import com.github.jrubygradle.api.gems.GemVersion
2726
import spock.lang.Specification
2827
import spock.lang.Unroll
2928

@@ -77,7 +76,7 @@ class GemVersionSpec extends Specification {
7776
}
7877

7978
@Unroll
80-
void "Intersect: #ivyLeft ∩ #ivyRight ⇒ Gem #gemVer"() {
79+
void "intersect: #ivyLeft ∩ #ivyRight ⇒ Gem #gemVer"() {
8180
when:
8281
GemVersion lhs = gemVersionFromGradleIvyRequirement(ivyLeft)
8382
GemVersion rhs = gemVersionFromGradleIvyRequirement(ivyRight)
@@ -87,10 +86,10 @@ class GemVersionSpec extends Specification {
8786

8887
where:
8988
ivyLeft | ivyRight | gemVer
90-
'[1.2.1,1.2.4]' | ']1.2.1,1.2.4[' | ']1.2.1,1.2.4['
89+
'[1.2.1,1.2.4]' | ']1.2.1,1.2.4[' | '[1.2.1,1.2.4]'
9190
'[1.2.0,1.2.4]' | ']1.2.1,1.2.3[' | ']1.2.1,1.2.3['
9291
'[1.2.0,1.2.4]' | '[1.2.1,1.2.3]' | '[1.2.1,1.2.3]'
93-
']1.2.0,1.2.4[' | '[1.2.0,1.2.4]' | ']1.2.0,1.2.4['
92+
']1.2.0,1.2.4[' | '[1.2.0,1.2.4]' | '[1.2.0,1.2.4]'
9493
']1.2.1,1.2.3[' | '[1.2.0,1.2.4]' | ']1.2.1,1.2.3['
9594
'[1.2.1,1.2.3]' | '[1.2.0,1.2.4]' | '[1.2.1,1.2.3]'
9695
'[1.2.10,1.2.14]' | '[1.2.2,1.10.14]' | '[1.2.10,1.2.14]'
@@ -100,17 +99,28 @@ class GemVersionSpec extends Specification {
10099
']2.5.1.1,99999]' | ']2.5.1.1,)' | ']2.5.1.1,99999]'
101100
}
102101

103-
void 'Ivy union of < 3, >= 1.2'() {
104-
expect:
105-
singleGemVersionFromMultipleGemRequirements('< 3,>= 1.2').toString() == '[1.2,3['
102+
@Unroll
103+
void '#gemRequirements (requirements) ⇒ #gemRequirement (requirement)'() {
104+
when:
105+
GemVersion subject = singleGemVersionFromMultipleGemRequirements(gemRequirements)
106+
107+
then:
108+
subject.toString() == gemRequirement
109+
110+
where:
111+
gemRequirements | gemRequirement
112+
'< 3,>= 1.2' | '[1.2,3['
113+
'>= 3.0, < 4.0' | '[3.0,4.0['
114+
'< 4.0, >= 3.0' | '[3.0,4.0['
115+
'~> 2.2, >= 2.2.1' | '[2.2.1,3.0['
106116
}
107117

108118
void "intersects with conflict"() {
109119
given:
110120
GemVersion subject = gemVersionFromGradleIvyRequirement('[1.2.1,1.2.3]')
111121

112122
expect:
113-
subject.intersect('[1.2.4, 1.2.4]').conflict() == true
123+
subject.intersect('[1.2.4, 1.2.4]').conflict()
114124
}
115125

116126
void "finds no conflicts in non-integer version ranges"() {

0 commit comments

Comments
 (0)