Skip to content

fix: detect version upgrades by purl and repair default CLI invocation#10

Open
dmchaledev wants to merge 1 commit into
mainfrom
claude/magical-ptolemy-WSwYl
Open

fix: detect version upgrades by purl and repair default CLI invocation#10
dmchaledev wants to merge 1 commit into
mainfrom
claude/magical-ptolemy-WSwYl

Conversation

@dmchaledev
Copy link
Copy Markdown
Contributor

Summary

Two correctness bugs broke the package's headline behavior. Both are small and self-contained.

1. Upgrade detection was effectively dead (the marquee feature)

The README promises the tool "Highlights added, removed, upgraded dependencies", but components were keyed by their full purl, which embeds the version (e.g. pkg:npm/lodash@4.17.21). The same package at two versions therefore never matched, so every version bump was reported as a remove + add instead of an upgrade.

Since real CycloneDX/SPDX SBOMs almost always carry versioned purls, the upgraded / isMajorBump output was dead for any realistic input — it only worked for components with no purl.

Before (old.jsonnew.json, lodash 4.17.204.17.21):

+ Added:   express@4.18.2
- Removed: lodash@4.17.20   ← wrong
+ Added:   lodash@4.17.21   ← wrong
↑ Upgraded: (none)          ← should list lodash

After:

↑ Upgraded Components:
  ~ lodash: 4.17.20 → 4.17.21

Components are now keyed by their version-stripped purl (falling back to name), so upgrades are detected correctly, including for scoped packages (pkg:npm/%40babel/core@…).

2. The documented default CLI command crashed

The very first example in the README — npx @hailbytes/sbom-diff old.json new.json — crashed:

Error: Unsupported format: old.json

When no --format flag was present, the fallback args[args.indexOf('--format') + 1] resolved to args[-1 + 1] = args[0] (the old file path), which was then used as the report format. Parsing now only reads the flag's value when the flag is actually present, and an invalid --format produces a friendly error instead of an unhandled throw.

Changes

  • src/diff.ts — key components by version-stripped purl via new componentKey / stripPurlVersion helpers.
  • src/cli.ts — only consume --format's value when the flag is present; validate the format and emit a clear error otherwise.
  • src/__tests__/diff.test.ts — replaced the test that previously enshrined the broken add/remove behavior with one asserting real upgrade detection; added scoped-package coverage.

Verification

  • npm test — 21 passed
  • npm run build and npm run lint — clean
  • Manually re-ran the default and --format CLI invocations (see before/after above).

Generated by Claude Code

Two correctness bugs broke the package's headline behavior:

- Upgrade detection: components were keyed by their full purl, which
  embeds the version (e.g. "pkg:npm/lodash@4.17.21"). The same package at
  two versions therefore never matched, so every version bump was reported
  as a remove + add instead of an upgrade — making the advertised
  "upgraded dependencies" output dead for any real SBOM (purls are
  normally versioned). Components are now keyed by their version-stripped
  purl (falling back to name), so upgrades are detected correctly,
  including for scoped packages.

- CLI: the documented default command `sbom-diff old.json new.json`
  crashed with "Unsupported format: old.json". When no --format flag was
  present, the fallback `args[args.indexOf('--format') + 1]` resolved to
  `args[0]` (the old path). Parsing now only reads the flag's value when
  the flag is present, and an invalid --format produces a friendly error
  instead of an unhandled throw.

Updated the diff test that previously enshrined the broken behavior, and
added coverage for purl-based and scoped-package upgrade detection.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants