fix(lockfile): respect lockfile-include-tarball-url=false for non-standard URLs (#10621)

When lockfile-include-tarball-url is explicitly set to false, tarball URLs
are now always excluded from the lockfile. Previously, packages hosted under
non-standard tarball URLs would still have their tarball field written to the
lockfile even when the setting was false, causing flaky and inconsistent
behavior across environments.

The fix makes the option tri-state internally:
- true: always include tarball URLs
- false: never include tarball URLs
- undefined (not set): use the existing heuristic that includes tarball URLs
  only for packages with non-standard registry URLs

close #6667
This commit is contained in:
Varun Chawla
2026-02-25 02:03:32 -08:00
committed by GitHub
parent 107b34f241
commit e73da5e27b
4 changed files with 34 additions and 2 deletions

View File

@@ -0,0 +1,6 @@
---
"@pnpm/resolve-dependencies": patch
"pnpm": patch
---
When `lockfile-include-tarball-url` is set to `false`, tarball URLs are now always excluded from the lockfile. Previously, tarball URLs could still appear for packages hosted under non-standard URLs, making the behavior flaky and inconsistent [#6667](https://github.com/pnpm/pnpm/issues/6667).

View File

@@ -60,7 +60,7 @@ export interface StrictInstallOptions {
preferFrozenLockfile: boolean
saveWorkspaceProtocol: boolean | 'rolling'
lockfileCheck?: (prev: LockfileObject, next: LockfileObject) => void
lockfileIncludeTarballUrl: boolean
lockfileIncludeTarballUrl?: boolean
preferWorkspacePackages: boolean
preserveWorkspaceProtocol: boolean
saveCatalogName?: string
@@ -240,7 +240,6 @@ const defaults = (opts: InstallOptions): StrictInstallOptions => {
registries: DEFAULT_REGISTRIES,
resolutionMode: 'lowest-direct',
saveWorkspaceProtocol: 'rolling',
lockfileIncludeTarballUrl: false,
scriptsPrependNodePath: false,
shamefullyHoist: false,
shellEmulator: false,

View File

@@ -1446,6 +1446,28 @@ test('include tarball URL', async () => {
.toBe(`http://localhost:${REGISTRY_MOCK_PORT}/@pnpm.e2e/pkg-with-1-dep/-/pkg-with-1-dep-100.0.0.tgz`)
})
test('exclude tarball URL when lockfileIncludeTarballUrl is false', async () => {
const project = prepareEmpty()
const opts = testDefaults({ fastUnpack: false, lockfileIncludeTarballUrl: false })
await addDependenciesToPackage({}, ['@pnpm.e2e/pkg-with-1-dep@100.0.0'], opts)
const lockfile = project.readLockfile()
expect((lockfile.packages['@pnpm.e2e/pkg-with-1-dep@100.0.0'].resolution as TarballResolution).tarball)
.toBeUndefined()
})
test('exclude non-standard tarball URL when lockfileIncludeTarballUrl is false', async () => {
const project = prepareEmpty()
await addDependenciesToPackage({}, ['esprima-fb@3001.1.0-dev-harmony-fb'], testDefaults({ fastUnpack: false, lockfileIncludeTarballUrl: false }))
const lockfile = project.readLockfile()
expect((lockfile.packages['esprima-fb@3001.1.0-dev-harmony-fb'].resolution as TarballResolution).tarball)
.toBeUndefined()
})
test('lockfile v6', async () => {
prepareEmpty()

View File

@@ -196,6 +196,11 @@ function toLockfileResolution (
tarball: resolution['tarball'],
}
}
if (lockfileIncludeTarballUrl === false) {
return {
integrity: resolution['integrity'],
}
}
// Sometimes packages are hosted under non-standard tarball URLs.
// For instance, when they are hosted on npm Enterprise. See https://github.com/pnpm/pnpm/issues/867
// Or in other weird cases, like https://github.com/pnpm/pnpm/issues/1072