Skip to content

Commit

Permalink
fix: properly handle directory, file, git and alias specs in overrides
Browse files Browse the repository at this point in the history
  • Loading branch information
nlf authored and lukekarrys committed Dec 17, 2022
1 parent ec09474 commit c52cf6b
Show file tree
Hide file tree
Showing 2 changed files with 136 additions and 1 deletion.
29 changes: 28 additions & 1 deletion workspaces/arborist/lib/override-set.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,36 @@ class OverrideSet {
continue
}

if (semver.intersects(edge.spec, rule.keySpec)) {
// if keySpec is * we found our override
if (rule.keySpec === '*') {
return rule
}

let spec = npa(`${edge.name}@${edge.spec}`)
if (spec.type === 'alias') {
spec = spec.subSpec
}

if (spec.type === 'git') {
if (spec.gitRange && semver.intersects(spec.gitRange, rule.keySpec)) {
return rule
}

continue
}

if (spec.type === 'range' || spec.type === 'version') {
if (semver.intersects(spec.fetchSpec, rule.keySpec)) {
return rule
}

continue
}

// if we got this far, the spec type is one of tag, directory or file
// which means we have no real way to make version comparisons, so we
// just accept the override
return rule
}

return this
Expand Down
108 changes: 108 additions & 0 deletions workspaces/arborist/test/override-set.js
Original file line number Diff line number Diff line change
Expand Up @@ -163,4 +163,112 @@ t.test('constructor', async (t) => {
const barEdgeRule = overrides.getEdgeRule({ name: 'bar', spec: '^1' })
t.equal(barEdgeRule.value, '*', 'when rule is omitted entirely value is *')
})

t.test('version specs work', async (t) => {
const overrides = new OverrideSet({
overrides: {
foo: {
bar: '$bar',
},
'baz@^1.0.0': {
'buzz@^1.0.0': '$buzz',
},
},
})

const fooEdgeRule = overrides.getEdgeRule({ name: 'foo', spec: '^1.0.0' })
const barEdgeRule = fooEdgeRule.getEdgeRule({ name: 'bar', spec: '1.0.0' })
t.equal(barEdgeRule.value, '$bar', 'got a rule back')

const bazEdgeRule = overrides.getEdgeRule({ name: 'baz', spec: '^1.0.0' })
const buzzEdgeRule = bazEdgeRule.getEdgeRule({ name: 'buzz', spec: '1.0.0' })
t.equal(buzzEdgeRule.value, '$buzz', 'got a rule back')
})

t.test('directory specs work', async (t) => {
const overrides = new OverrideSet({
overrides: {
foo: {
bar: '$bar',
},
'baz@^1.0.0': {
'buzz@^1.0.0': '$buzz',
},
},
})

const fooEdgeRule = overrides.getEdgeRule({ name: 'foo', spec: '^1.0.0' })
const barEdgeRule = fooEdgeRule.getEdgeRule({ name: 'bar', spec: 'file:../bar' })
t.equal(barEdgeRule.value, '$bar', 'got a rule back')

const bazEdgeRule = overrides.getEdgeRule({ name: 'baz', spec: '^1.0.0' })
const buzzEdgeRule = bazEdgeRule.getEdgeRule({ name: 'buzz', spec: 'file:../buzz' })
t.equal(buzzEdgeRule.value, '$buzz', 'got a rule back')
})

t.test('file specs work', async (t) => {
const overrides = new OverrideSet({
overrides: {
foo: {
bar: '$bar',
},
'baz@^1.0.0': {
'buzz@^1.0.0': '$buzz',
},
},
})

const fooEdgeRule = overrides.getEdgeRule({ name: 'foo', spec: '^1.0.0' })
const barEdgeRule = fooEdgeRule.getEdgeRule({ name: 'bar', spec: 'file:../bar.tgz' })
t.equal(barEdgeRule.value, '$bar', 'got a rule back')

const bazEdgeRule = overrides.getEdgeRule({ name: 'baz', spec: '^1.0.0' })
const buzzEdgeRule = bazEdgeRule.getEdgeRule({ name: 'buzz', spec: 'file:../buzz.tgz' })
t.equal(buzzEdgeRule.value, '$buzz', 'got a rule back')
})

t.test('alias specs work', async (t) => {
const overrides = new OverrideSet({
overrides: {
foo: {
bar: '$bar',
},
'baz@^1.0.0': {
'buzz@^1.0.0': '$buzz',
},
},
})

const fooEdgeRule = overrides.getEdgeRule({ name: 'foo', spec: '^1.0.0' })
const barEdgeRule = fooEdgeRule.getEdgeRule({ name: 'bar', spec: 'npm:bar2@^1.0.0' })
t.equal(barEdgeRule.value, '$bar', 'got a rule back')

const bazEdgeRule = overrides.getEdgeRule({ name: 'baz', spec: '^1.0.0' })
const buzzEdgeRule = bazEdgeRule.getEdgeRule({ name: 'buzz', spec: 'npm:buzz2@^1.0.0' })
t.equal(buzzEdgeRule.value, '$buzz', 'got a rule back')
})

t.test('git specs work', async (t) => {
const overrides = new OverrideSet({
overrides: {
foo: {
bar: '$bar',
},
'baz@^1.0.0': {
'buzz@^1.0.0': '$buzz',
},
},
})

const fooEdgeRule = overrides.getEdgeRule({ name: 'foo', spec: '^1.0.0' })
const barEdgeRule = fooEdgeRule.getEdgeRule({ name: 'bar', spec: 'github:foo/bar' })
t.equal(barEdgeRule.value, '$bar', 'got a rule back')

const bazEdgeRule = overrides.getEdgeRule({ name: 'baz', spec: '^1.0.0' })
const buzzEdgeRule = bazEdgeRule.getEdgeRule({ name: 'buzz', spec: 'github:baz/buzz#semver:^1.0.0' })
t.equal(buzzEdgeRule.value, '$buzz', 'got a rule back')

const outOfRangeRule = bazEdgeRule.getEdgeRule({ name: 'buzz', spec: 'github:baz/buzz#semver:^2.0.0' })
t.equal(outOfRangeRule.name, 'baz', 'no match - returned parent')
})
})

0 comments on commit c52cf6b

Please sign in to comment.