Skip to content

Commit

Permalink
Correct semver.intersect impl; Fixes pkgxdev#156
Browse files Browse the repository at this point in the history
  • Loading branch information
mxcl committed Nov 17, 2022
1 parent fdd7fed commit b08f49a
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 7 deletions.
24 changes: 17 additions & 7 deletions src/utils/semver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -237,15 +237,25 @@ export function intersect(a: Range, b: Range): Range {
if (a.set === '*') return b
if (a.eq(b)) return a

if (a.set.length == 1 && b.set.length == 1) {
const [c,d] = [a.set[0], b.set[0]]
const e = c[0].gt(d[0]) ? c[0] : d[0]
const f = c[1].gt(d[1]) ? c[1] : d[1]
a.set = [[e,f]]
return a
// calculate the intersection between two semver.Ranges
const set: [SemVer, SemVer][] = []

for (let i = 0; i < a.set.length; i++) {
for (let j = 0; j < b.set.length; j++) {
const a1 = a.set[i][0]
const a2 = a.set[i][1]
const b1 = b.set[j][0]
const b2 = b.set[j][1]

if (a1.compare(b2) >= 0 || b1.compare(a2) >= 0) {
continue
}

set.push([a1.compare(b1) > 0 ? a1 : b1, a2.compare(b2) < 0 ? a2 : b2])
}
}

throw new Error(`couldn’t intersect ${a} and ${b}`)
return new Range(set.map(([v1, v2]) => `>=${chomp(v1)}<${chomp(v2)}`).join(","))
}


Expand Down
39 changes: 39 additions & 0 deletions tests/unit/semver.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,4 +58,43 @@ Deno.test("semver", async test => {
const e = new semver.Range("~1")
assertEquals(e.toString(), "^1") // indeed: we change the ~ to ^
})

await test.step("intersection", async test => {
await test.step("^3.7…@3.11", () => {
const a = new semver.Range("^3.7")
const b = new semver.Range("3.11.0")

assertEquals(b.toString(), "@3.11.0")

const c = semver.intersect(a, b)
assertEquals(c.toString(), "@3.11.0")
})

await test.step("^3.7…^3.9", () => {
const a = new semver.Range("^3.7")
const b = new semver.Range("^3.9")

assertEquals(b.toString(), "^3.9")

const c = semver.intersect(a, b)
assertEquals(c.toString(), "^3.9")
})

await test.step("^3.7…*", () => {
const a = new semver.Range("^3.7")
const b = new semver.Range("*")

assertEquals(b.toString(), "*")

const c = semver.intersect(a, b)
assertEquals(c.toString(), "^3.7")
})

await test.step("~3.7…~3.8", () => {
const a = new semver.Range("~3.7")
const b = new semver.Range("~3.8")

assertThrows(() => semver.intersect(a, b))
})
})
})

0 comments on commit b08f49a

Please sign in to comment.