Skip to content

pnpm lock parser: peer-dep suffixed keys produce duplicate/incorrect entries #21

@julienp

Description

@julienp

When pnpm resolves a package against different sets of peer dependencies, it records multiple snapshots of the same package using a suffix notation, e.g.:

debug@2.2.0(supports-color@1.2.0):

The parser currently splits on the last @ to extract the version, which lands inside the suffix instead of at the version boundary. The result is a bogus dependency name like debug@2.2.0(supports-color with version 1.2.0).

In npm-land we can also have multiple versions of a package in the lockfile, how should that be represented in the results?

Test program
package main

import (
"fmt"
"os"
"os/exec"
"strings"

"github.com/git-pkgs/manifests"

)

const packageJSON = { "name": "pnpm-issue-repro", "dependencies": { "mocha": "2.5.3", "supports-color": "1.2.0", "debug": "^4.0.0" } }

func main() {
dir, err := os.MkdirTemp("", "pnpm-issue-*")
if err != nil {
panic(err)
}
defer os.RemoveAll(dir)
fmt.Println("working dir:", dir)

if err := os.WriteFile(dir+"/package.json", []byte(packageJSON), 0644); err != nil {
	panic(err)
}

fmt.Println("running pnpm install...")
cmd := exec.Command("pnpm", "install", "--no-frozen-lockfile")
cmd.Dir = dir
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
if err := cmd.Run(); err != nil {
	panic(err)
}

content, err := os.ReadFile(dir + "/pnpm-lock.yaml")
if err != nil {
	panic(err)
}

fmt.Println("\n--- relevant lockfile lines ---")
for _, line := range strings.Split(string(content), "\n") {
	if strings.Contains(line, "debug") {
		fmt.Println(line)
	}
}

fmt.Println("\n--- parse results (via manifests library) ---")
result, err := manifests.Parse("pnpm-lock.yaml", content)
if err != nil {
	panic(err)
}
for _, dep := range result.Dependencies {
	if strings.Contains(dep.Name, "debug") || strings.Contains(dep.Name, "supports-color") {
		fmt.Printf("  name=%-45s version=%s\n", dep.Name, dep.Version)
	}
}

}

--- relevant lockfile lines ---
      debug:
  debug@2.2.0:
  debug@4.4.3:
  debug@2.2.0(supports-color@1.2.0):
  debug@4.4.3(supports-color@1.2.0):
      debug: 2.2.0(supports-color@1.2.0)

--- parse results (via manifests library) ---
  name=debug                                         version=2.2.0
  name=supports-color                                version=1.2.0
  name=debug@2.2.0(supports-color                    version=1.2.0)
  name=debug@4.4.3(supports-color                    version=1.2.0)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions