Skip to content

feat(update-deps): resolve pnpm catalog specs and expand workspace patterns like pnpm - #15

Merged
pyramation merged 1 commit into
mainfrom
feat/catalog-support
Aug 18, 2026
Merged

feat(update-deps): resolve pnpm catalog specs and expand workspace patterns like pnpm#15
pyramation merged 1 commit into
mainfrom
feat/catalog-support

Conversation

@pyramation

Copy link
Copy Markdown
Contributor

Summary

update-deps compared each manifest spec as a semver range, so "typescript": "catalog:" had nothing to parse and was skipped — silently, with a green nightly job. Any repo that migrated to a pnpm catalog would freeze every cataloged dependency at its catalog version while still reporting success. This teaches update-deps about catalogs and fixes the pattern expander that hid interior-* manifests. Unblocks constructive-io/constructive-planning#1764 (the constructive-db catalog migration, 221 manifests); the point is that a cataloged dep must never silently stop being updated.

Catalogs (src/commands/catalogs.ts, wired into updateDeps):

spec "catalog:" / "catalog:default" -> default catalog (top-level `catalog:`, or `catalogs.default`)
spec "catalog:react18"              -> `catalogs.react18`

The catalog spec is what gets compared, and the bump is written to the catalog entry in pnpm-workspace.yaml, not to the manifest. setCatalogSpec rewrites the single line holding the entry (locating it by indentation), so the rest of the file — comments, quoting style, trailing # ... on the entry line — is byte-identical; constructive-db's catalog is heavily commented. Flow-style catalogs (catalog: { ts: ^5.6.3 }) fall back to a yaml document edit, which still keeps comments but may reformat.

Reporting is deduped per catalog entry, keyed catalog + depName, so a dep cataloged once is reported and bumped once instead of once per consuming manifest:

{ "name": "typescript", "currentVersion": "^5.6.3", "consumer": "catalog:",
  "file": "pnpm-workspace.yaml", "catalog": "default", "outdated": true }

workspace: specs keep being skipped, unchanged.

Choice for manifest-level overrides: a manifest that pins an explicit range instead of using the catalog is bumped in place, and stays an explicit range. It's a deliberate override, and it's still a version we own, so leaving it to drift would recreate the very failure this PR fixes on a per-manifest scale. It takes the normal (unchanged) manifest path; the catalog entry is untouched by it.

No more silent success: the result gains warnings: string[]. A manifest asking for catalog: for a dep with no catalog entry (typo, or a rename) now produces a warning rather than a skip.

Pattern expansion (src/commands/workspacePatterns.ts, shared by updateDeps and updateWorkspace): the old glob was p.replace(/\/?\*\*?$/, '') + '/*/package.json', which appends a level that pnpm doesn't, so a pattern ending in a literal segment matched the wrong depth:

- 'functions/*/pages'       -> 'functions/*/pages/*/package.json'   # manifest invisible
+ 'functions/*/pages'       -> 'functions/*/pages/package.json'
+ 'functions/*/handlers/*'  -> 'functions/*/handlers/*/package.json'
+ '!scratch/*'              -> excluded (pnpm-style negation, new)

That invisibility is what let dependency drift into a constructive-db manifest that makage never rewrote.

Release note for the constructive-db side

This ships in a new makage version — the catalog migration must consume a published makage (or the CI workflow must pin this commit) before it lands, otherwise the migration silently disables updates for everything it touches. makage is published from packages/makage/dist; this PR does not bump the version (releases go through the repo's usual chore(release): publish flow).

Tests

packages/makage/__tests__/catalogs.test.ts (spec parsing, default/named/catalogs.default precedence, single-line surgical rewrite with comments and quoting preserved, flow-style fallback), workspacePatterns.test.ts (pattern→glob mapping plus a real-filesystem expansion of functions/*/handlers/* and functions/*/pages, node_modules and ! exclusions), and a pnpm catalogs block in updateDeps.test.ts (catalog bumped in pnpm-workspace.yaml and deduped across consumers, named catalogs, override bumped in place with the catalog untouched, workspace: still skipped, --dry-run writes nothing, missing catalog entry warns). Also verified end-to-end with the built CLI against a throwaway workspace.

pnpm test (56 passing), pnpm lint, pnpm build all clean.

Link to Devin session: https://app.devin.ai/sessions/7e055fec09f94bd19765ac4c961d5920
Requested by: @pyramation

…tterns like pnpm

Cataloged deps bump their pnpm-workspace.yaml entry (one line rewritten, comments intact), are reported once per catalog entry, and a missing catalog entry now warns instead of passing silently. Workspace patterns expand with pnpm semantics so interior * segments are no longer invisible.
@pyramation pyramation self-assigned this Aug 18, 2026
@devin-ai-integration

Copy link
Copy Markdown
Contributor

🤖 Devin AI Engineer

I'll be helping with this pull request! Here's what you should know:

✅ I will automatically:

  • Address comments on this PR. Add '(aside)' to your comment to have me ignore it.
  • Look at CI failures and help fix them

Note: I can only respond to comments from users who have write access to this repository.

⚙️ Control Options:

  • Disable automatic comment, CI, and merge conflict monitoring

@pyramation
pyramation merged commit a2b6d12 into main Aug 18, 2026
7 checks passed
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.

1 participant