Skip to content

Commit

Permalink
feat: add record default registry option
Browse files Browse the repository at this point in the history
Create shrinkwrap files with resolved urls modified to replace the
configured registry with the default registry,
https://registry.npmjs.org.

The default registry is a magic value meaning the current registry, so
recording resolved with the default registry allows users to switch to a
different registry without removing their lockfile. The path portion of
the acutal resolved url is preserved so this trick only works when the
different registries host tarballs at the same relative paths. It's
faster than the omitLockfileRegistryResolved option because npm doesn't
need to fetch each pacument to resolve the tarball url.
  • Loading branch information
Caleb ツ Everett authored and fritzy committed Jan 19, 2022
1 parent 60a688d commit 8027323
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 13 deletions.
47 changes: 44 additions & 3 deletions workspaces/arborist/lib/override-resolves.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,51 @@
function overrideResolves (resolved, opts = {}) {
const { omitLockfileRegistryResolved = false } = opts
const npa = require('npm-package-arg')

if (omitLockfileRegistryResolved) {
function overrideResolves (node, resolved, opts = {}) {
const {
omitLockfileRegistryResolved = false,
recordDefaultRegistry = false,
} = opts

const isRegistryDependency = node.isRegistryDependency

// omit the resolved url of registry dependencies. this makes installs slower
// because npm must resolve the url for each package version but it allows
// users to use a lockfile across registries that host tarballs at different
// paths.
if (isRegistryDependency && omitLockfileRegistryResolved) {
return undefined
}

// replace the configured registry with the default registry. the default
// registry is a magic value meaning the current registry, so recording
// resolved with the default registry allows users to switch to a
// different registry without removing their lockfile. The path portion
// of the resolved url is preserved so this trick only works when the
// different registries host tarballs at the same relative paths.
if (isRegistryDependency && recordDefaultRegistry) {
const scope = npa(node.packageName).scope
const registry = scope && opts[`${scope}:registry`]
? opts[`${scope}:registry`]
: opts.registry

// normalize registry url - strip trailing slash.
// TODO improve normalization for both the configured registry and resolved
// url. consider port, protocol, more path normalization.
const normalized = registry.endsWith('/')
? registry.slice(0, -1)
: registry

// only replace the host if the resolved url is for the configured
// registry. registries may host tarballs on another server. return
// undefined so npm will re-resolve the url from the current registry when
// it reads the lockfile.
if (resolved.startsWith(normalized)) {
return 'https://registry.npmjs.org' + resolved.slice(normalized.length)
} else {
return undefined
}
}

return resolved
}

Expand Down
11 changes: 3 additions & 8 deletions workspaces/arborist/lib/shrinkwrap.js
Original file line number Diff line number Diff line change
Expand Up @@ -300,13 +300,8 @@ class Shrinkwrap {
})

const resolved = consistentResolve(node.resolved, node.path, path, true)
// hide resolved from registry dependencies.
if (!resolved) {
// no-op
} else if (node.isRegistryDependency) {
meta.resolved = overrideResolves(resolved, options)
} else {
meta.resolved = resolved
if (resolved) {
meta.resolved = overrideResolves(node, resolved, options)
}

if (node.extraneous) {
Expand Down Expand Up @@ -1027,7 +1022,7 @@ class Shrinkwrap {
spec.type !== 'git' &&
spec.type !== 'file' &&
spec.type !== 'remote') {
lock.resolved = overrideResolves(node.resolved, this.resolveOptions)
lock.resolved = overrideResolves(node, node.resolved, this.resolveOptions)
}

if (node.integrity) {
Expand Down
31 changes: 29 additions & 2 deletions workspaces/arborist/test/shrinkwrap.js
Original file line number Diff line number Diff line change
Expand Up @@ -247,7 +247,7 @@ t.only('resolveOptions', async t => {
dependencies: {
registry: '^1.0.0',
'some-other-registry': '^1.0.0',
'@scoped/some-other-registry': '^1.0.0',
'@scope/some-package': '^1.0.0',
tar: url,
},
},
Expand All @@ -271,7 +271,7 @@ t.only('resolveOptions', async t => {
})

const scopedOtherRegistry = new Node({
pkg: { name: '@scope/some-other-registry', version: '1.2.3' },
pkg: { name: '@scope/some-package', version: '1.2.3' },
resolved: someOtherRegistry,
integrity: 'sha512-registry',
parent: root,
Expand Down Expand Up @@ -312,6 +312,33 @@ t.only('resolveOptions', async t => {
t.strictSame(data.dependencies.tar.resolved, undefined)
})

await t.test('recordDefaultRegistry: true', async t => {
const { data } = await getData({
recordDefaultRegistry: true,
registry: 'https://private.registry.org/deadbeef',
'@scope:registry': 'https://someother.registry.org',
})

// unscoped packages that resolve to their configured registry should be
// record the default registry
t.strictSame(data.packages['node_modules/registry'].resolved,
'https://registry.npmjs.org/registry/-/registry-1.2.3.tgz')
t.strictSame(data.dependencies.registry.resolved,
'https://registry.npmjs.org/registry/-/registry-1.2.3.tgz')

// scoped packages that resolve to their configured registry should be
// record the default registry
t.strictSame(data.packages['node_modules/@scope/some-package'].resolved,
'https://registry.npmjs.org/registry/-/registry-1.2.3.tgz')
t.strictSame(data.dependencies['@scope/some-package'].resolved,
'https://registry.npmjs.org/registry/-/registry-1.2.3.tgz')

// packages with resolved urls that don't match the configured registry
// should record undefined so npm resolves their url again.
t.strictSame(data.packages['node_modules/some-other-registry'].resolved, undefined)
t.strictSame(data.dependencies['some-other-registry'].resolved, undefined)
})

t.test('metaFromNode default', async t => {
// test to cover options default.
const { registry } = await getData(undefined)
Expand Down

0 comments on commit 8027323

Please sign in to comment.