Skip to content

Commit

Permalink
fix: mismatched pnpm lockfile version resolution (#3611)
Browse files Browse the repository at this point in the history
Fixes #3564

I created a regression when adding support for pnpm `lockfileVersion: 6`
that caused us to not include some indirect dependencies of a workspace.
A package would be missing only if a workspace had a direct dependency
on the package that was also included as an indirect dependency where
the version ranges didn't overlap. See the new test fixture for a basic
version of how this could occur.

Huge thanks to @shawnmcknight for providing a reproduction!
  • Loading branch information
chris-olszewski authored and mehulkar committed Feb 3, 2023
1 parent 68aed07 commit 6f91b4b
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 4 deletions.
6 changes: 2 additions & 4 deletions cli/internal/lockfile/pnpm_lockfile.go
Original file line number Diff line number Diff line change
Expand Up @@ -422,16 +422,14 @@ func (p *PnpmLockfile) resolveSpecifier(workspacePath turbopath.AnchoredUnixPath
if err != nil {
return "", false, err
}
if !ok {
// Verify that the specifier in the importer matches the one given
if !ok || resolution.Specifier != specifier {
// Check if the specifier is already a resolved version
if _, ok := p.Packages[p.formatKey(name, specifier)]; ok {
return specifier, true, nil
}
return "", false, fmt.Errorf("Unable to find resolved version for %s@%s in %s", name, specifier, workspacePath)
}
if resolution.Specifier != specifier {
return "", false, nil
}
return resolution.Version, true, nil
}

Expand Down
16 changes: 16 additions & 0 deletions cli/internal/lockfile/pnpm_lockfile_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -277,3 +277,19 @@ func Test_LockfilePeer(t *testing.T) {
assert.DeepEqual(t, pkg.Version, "13.0.4(react-dom@18.2.0)(react@18.2.0)")
assert.DeepEqual(t, pkg.Key, "/next@13.0.4(react-dom@18.2.0)(react@18.2.0)")
}

func Test_LockfileTopLevelOverride(t *testing.T) {
contents, err := getFixture(t, "pnpm-top-level-dupe.yaml")
if err != nil {
t.Error(err)
}
lockfile, err := DecodePnpmLockfile(contents)
assert.NilError(t, err, "decode lockfile")

pkg, err := lockfile.ResolvePackage(turbopath.AnchoredUnixPath("packages/a"), "ci-info", "3.7.1")
assert.NilError(t, err, "resolve package")

assert.Assert(t, pkg.Found)
assert.DeepEqual(t, pkg.Key, "/ci-info/3.7.1")
assert.DeepEqual(t, pkg.Version, "3.7.1")
}
36 changes: 36 additions & 0 deletions cli/internal/lockfile/testdata/pnpm-top-level-dupe.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
lockfileVersion: 5.4

importers:
packages/a:
specifiers:
ci-info: ^2.0.0
is-ci: ^3.0.1
dependencies:
ci-info: 2.0.0
is-ci: 3.0.1

packages:
/ci-info/2.0.0:
resolution:
{
integrity: sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==,
}
dev: false

/ci-info/3.7.1:
resolution:
{
integrity: sha512-4jYS4MOAaCIStSRwiuxc4B8MYhIe676yO1sYGzARnjXkWpmzZMMYxY6zu8WYWDhSuth5zhrQ1rhNSibyyvv4/w==,
}
engines: { node: ">=8" }
dev: false

/is-ci/3.0.1:
resolution:
{
integrity: sha512-ZYvCgrefwqoQ6yTyYUbQu64HsITZ3NfKX1lzaEYdkTDcfKzzCI/wthRRYKkdjHKFVgNiXKAKm65Zo1pk2as/QQ==,
}
hasBin: true
dependencies:
ci-info: 3.7.1
dev: false

0 comments on commit 6f91b4b

Please sign in to comment.