Skip to content
This repository has been archived by the owner on Jul 3, 2019. It is now read-only.

Commit

Permalink
registry: make pick-manifest generic for tags and versions, too
Browse files Browse the repository at this point in the history
  • Loading branch information
zkat committed Dec 12, 2016
1 parent ed1a1d2 commit 2e14361
Show file tree
Hide file tree
Showing 3 changed files with 74 additions and 24 deletions.
4 changes: 2 additions & 2 deletions lib/handlers/range/manifest.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
var getFromRegistry = require('../../registry/get')
var optCheck = require('../../util/opt-check')
var pickManifest = require('./pick-manifest')
var pickManifest = require('../../registry/pick-manifest')
var pickRegistry = require('../../registry/pick-registry')
var url = require('url')

Expand All @@ -15,7 +15,7 @@ function manifest (spec, opts, cb) {
getFromRegistry(uri, registry, opts, function (err, metadata) {
if (err) { return cb(err) }
opts.log.silly('metadata', 'got metadata for', spec.name, metadata)
pickManifest(metadata, spec.spec, {
pickManifest(metadata, spec, {
engineFilter: opts.engineFilter,
defaultTag: opts.defaultTag
}, cb)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
var semver = require('semver')

module.exports = pickManifest
function pickManifest (metadata, range, opts, cb) {
function pickManifest (metadata, spec, opts, cb) {
var distTags = metadata['dist-tags'] || {}
var versions = Object.keys(metadata.versions || {})
var err
Expand All @@ -10,28 +10,38 @@ function pickManifest (metadata, range, opts, cb) {
err = new Error('Package has no versions.')
err.code = 'ENOVERSIONS'
err.name = metadata.name
err.range = range
err.spec = spec
return cb(err)
}

if (opts.engineFilter && (opts.engineFilter.node || opts.engineFilter.npm)) {
versions = filterByEngines(metadata, versions, opts.engineFilter)
}

var tagVersion = distTags[opts.defaultTag || 'latest']
var target

if (tagVersion &&
if (spec.type === 'tag') {
target = distTags[spec.spec]
} else if (spec.type === 'version') {
target = spec.spec
} else if (spec.type !== 'range') {
return cb(new Error('Only tag, version, and range are supported'))
}

var tagVersion = distTags[opts.defaultTag || 'latest']

if (!target &&
tagVersion &&
metadata.versions[tagVersion] &&
semver.satisfies(tagVersion, range, true)) {
semver.satisfies(tagVersion, spec.spec, true)) {
target = tagVersion
}

if (!target) {
target = semver.maxSatisfying(versions, range, true)
target = semver.maxSatisfying(versions, spec.spec, true)
}

if (!target && range === '*') {
if (!target && spec.spec === '*') {
// npm hard-codes `latest` here, but it's likely intended
// to be `defaultTag`.
//
Expand All @@ -46,7 +56,7 @@ function pickManifest (metadata, range, opts, cb) {
err = new Error('No matching versions')
err.code = 'ENOENT'
err.name = metadata.name
err.range = range
err.spec = spec
err.versions = versions
err.distTags = distTags
err.defaultTag = opts.defaultTag
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
var test = require('tap').test

var pickManifest = require('../lib/handlers/range/pick-manifest')
var pickManifest = require('../lib/registry/pick-manifest')

function spec (selector, type) {
return { spec: selector, type: type || 'range' }
}

test('basic carat range selection', function (t) {
var metadata = {
Expand All @@ -11,7 +15,7 @@ test('basic carat range selection', function (t) {
'2.0.0': { version: '2.0.0' }
}
}
pickManifest(metadata, '^1.0.0', {}, function (err, manifest) {
pickManifest(metadata, spec('^1.0.0'), {}, function (err, manifest) {
if (err) { throw err }
t.equal(manifest.version, '1.0.2', 'picked the right manifest using ^')
t.end()
Expand All @@ -27,7 +31,7 @@ test('basic tilde range selection', function (t) {
'2.0.0': { version: '2.0.0' }
}
}
pickManifest(metadata, '~1.0.0', {}, function (err, manifest) {
pickManifest(metadata, spec('~1.0.0'), {}, function (err, manifest) {
if (err) { throw err }
t.equal(manifest.version, '1.0.2', 'picked the right manifest using ~')
t.end()
Expand All @@ -43,13 +47,49 @@ test('basic mathematical range selection', function (t) {
'2.0.0': { version: '2.0.0' }
}
}
pickManifest(metadata, '>=1.0.0 <2', {}, function (err, manifest) {
pickManifest(metadata, spec('>=1.0.0 <2'), {}, function (err, manifest) {
if (err) { throw err }
t.equal(manifest.version, '1.0.2', 'picked the right manifest using mathematical range')
t.end()
})
})

test('basic version selection', function (t) {
var metadata = {
versions: {
'1.0.0': { version: '1.0.0' },
'1.0.1': { version: '1.0.1' },
'1.0.2': { version: '1.0.2' },
'2.0.0': { version: '2.0.0' }
}
}
pickManifest(metadata, spec('1.0.0', 'version'), {
}, function (err, manifest) {
if (err) { throw err }
t.equal(manifest.version, '1.0.0', 'picked the right manifest using specific version')
t.end()
})
})

test('basic tag selection', function (t) {
var metadata = {
'dist-tags': {
foo: '1.0.1'
},
versions: {
'1.0.0': { version: '1.0.0' },
'1.0.1': { version: '1.0.1' },
'1.0.2': { version: '1.0.2' },
'2.0.0': { version: '2.0.0' }
}
}
pickManifest(metadata, spec('foo', 'tag'), {}, function (err, manifest) {
if (err) { throw err }
t.equal(manifest.version, '1.0.1', 'picked the right manifest using tag')
t.end()
})
})

test('ENOENT if range does not match anything', function (t) {
var metadata = {
versions: {
Expand All @@ -58,7 +98,7 @@ test('ENOENT if range does not match anything', function (t) {
'2.0.5': { version: '2.0.5' }
}
}
pickManifest(metadata, '^2.1.0', {}, function (err, manifest) {
pickManifest(metadata, spec('^2.1.0'), {}, function (err, manifest) {
t.ok(err, 'got an error')
t.equal(err.code, 'ENOENT', 'useful error code returned.')
t.notOk(manifest, 'no manifest returned.')
Expand All @@ -79,19 +119,19 @@ test('if `defaultTag` matches a given range, use it', function (t) {
}
}
t.plan(3)
pickManifest(metadata, '^1.0.0', {
pickManifest(metadata, spec('^1.0.0'), {
defaultTag: 'foo'
}, function (err, manifest) {
if (err) { throw err }
t.equal(manifest.version, '1.0.1', 'picked the version for foo')
})
pickManifest(metadata, '^2.0.0', {
pickManifest(metadata, spec('^2.0.0'), {
defaultTag: 'foo'
}, function (err, manifest) {
if (err) { throw err }
t.equal(manifest.version, '2.0.0', 'no match, no foo')
})
pickManifest(metadata, '^1.0.0', {}, function (err, manifest) {
pickManifest(metadata, spec('^1.0.0'), {}, function (err, manifest) {
if (err) { throw err }
t.equal(manifest.version, '1.0.0', 'default to `latest`')
})
Expand All @@ -111,13 +151,13 @@ test('* ranges use `defaultTag` if no versions match', function (t) {
}
}
t.plan(2)
pickManifest(metadata, '*', {
pickManifest(metadata, spec('*'), {
defaultTag: 'beta'
}, function (err, manifest) {
if (err) { throw err }
t.equal(manifest.version, '2.0.0-beta.0', 'used defaultTag for all-prerelease splat.')
})
pickManifest(metadata, '*', {}, function (err, manifest) {
pickManifest(metadata, spec('*'), {}, function (err, manifest) {
if (err) { throw err }
t.equal(manifest.version, '1.0.0-pre.0', 'defaulted to `latest`.')
})
Expand Down Expand Up @@ -147,23 +187,23 @@ test('optionally filters by engines', function (t) {
}
}
t.plan(4)
pickManifest(metadata, '^1.0.0', {
pickManifest(metadata, spec('^1.0.0'), {
engineFilter: { node: '2.0.0' }
}, function (err, manifest) {
if (err) { throw err }
t.equal(manifest.version, '1.0.1', 'disqualified non-matching node')
})
pickManifest(metadata, '^2.0.0', {
pickManifest(metadata, spec('^2.0.0'), {
engineFilter: { npm: '2.0.0' }
}, function (err, manifest) {
if (err) { throw err }
t.equal(manifest.version, '2.0.1', 'disqualified non-matching npm')
})
pickManifest(metadata, '^2.0.0', {}, function (err, manifest) {
pickManifest(metadata, spec('^2.0.0'), {}, function (err, manifest) {
if (err) { throw err }
t.equal(manifest.version, '2.0.2', 'no filter, no problem')
})
pickManifest(metadata, '^2.0.0', {
pickManifest(metadata, spec('^2.0.0'), {
engineFilter: {}
}, function (err, manifest) {
if (err) { throw err }
Expand Down

0 comments on commit 2e14361

Please sign in to comment.