Skip to content

Resolve the composer section's configPath against the file that declared it - #262

Merged
wmadden-electric merged 8 commits into
mainfrom
config-declaring-file-paths
Sep 22, 2026
Merged

wmadden-electric merged 8 commits into
mainfrom
config-declaring-file-paths

Conversation

@wmadden-electric

Copy link
Copy Markdown
Contributor

What changed

The composer config section resolves its configPath against the prisma.config.ts file that declared it, instead of against the directory the command happens to run in.

prisma.config.ts is now a chain rather than a single file: prisma-cli discovers every config file from the command's cwd up to the repo root and merges the sections per key. A composer section written once at the repo root therefore reaches commands run in any subdirectory — and a configPath resolved against the process cwd names a different file in each of them, which is almost never the file the author meant.

The fix follows the pattern engine 0.3.0 defines: the section validator resolves the path-valued key and returns an absolute path, so nothing downstream ever resolves against cwd.

  • packages/0-framework/3-tooling/cli/src/family/section.ts — validate takes the section's provenance as its second argument and runs configPath through the engine's resolveSectionPath. An absolute path passes through unchanged. resolveSectionPath throws when the key is missing from the provenance, which cannot happen for a key just read out of the section, but a section validator must never throw — so even that case becomes a CONFIG.FIELD_INVALID diagnostic rather than an internal error blamed on composer.
  • src/load-config.ts and src/pipeline.ts — configPath is documented and treated as absolute; the resolution against cwd is gone.
  • Engine declarations move to 0.3.0 together (the internal CLI, composer-cli's peer and dev pins, the target extension, and the four examples), which is what check-cli-engine-pin requires.

Tests

  • src/family/__tests__/engine-cli.test.ts gains the real regression test: a two-file chain where the root file is the only one declaring configPath, with the run's cwd two directories below it. Both wrong answers are visible — resolving against cwd, or against the nearest file on the chain, would name /repo/apps/shop/prisma-composer.config.ts instead of /repo/prisma-composer.config.ts.
  • src/family/__tests__/section.test.ts covers the validator directly: relative resolves against the declaring file, absolute passes through, and a provenance missing the key fails with a diagnostic instead of throwing.
  • host-adapter.test.ts asserts the resolved absolute path arrives at the operation, end to end through the real Runtime.
  • Reverting the resolution to path.resolve(configPath) (cwd-based) fails 6 of these tests, including both engine-level ones — the tests fail when the behavior breaks.

What is green, and what is not

Verified locally against a packed @prisma/cli-engine@0.3.0 tarball installed into the workspace:

  • tsc --noEmit across all 78 workspace typecheck tasks — clean.
  • turbo run test across all 66 test tasks — clean, including the local-dev integration suite.
  • @internal/cli on its own: 259 tests pass.
  • biome check on the touched sources — clean.
  • pnpm check:cli-engine-pin — passes at 0.3.0.

CI will be red until @prisma/cli-engine@0.3.0 publishes (it comes from prisma/prisma-cli#233). pnpm install cannot resolve 0.3.0 from the registry, so it fails before any job runs, and pnpm-lock.yaml cannot be regenerated in this PR. The lockfile update belongs to the commit that follows the publish — the same shape as the previous engine bumps.

🤖 Generated with Claude Code

…red it

prisma.config.ts is now a chain rather than a single file: the engine discovers every file from the command's cwd up to the repo root and merges their sections per key. A `composer` section written once at the repo root therefore reaches commands run in any subdirectory — and resolving its `configPath` against the process cwd names a different file in every one of them, which is almost never the file the author meant.

The section validator now resolves `configPath` itself, through the engine's `resolveSectionPath`, against the file whose section declared that key; an absolute path passes through unchanged. Everything downstream — the pipeline and the config loader — receives an absolute path and no longer resolves anything against cwd.

This needs @prisma/cli-engine 0.3.0, whose `ConfigSection.validate` takes the resolved section's provenance as a second argument and whose `LoadedConfig` is the chain rather than one file. Every engine declaration moves to 0.3.0 together, as check-cli-engine-pin requires.

0.3.0 is not published yet (it comes from prisma/prisma-cli#233), so `pnpm install` cannot resolve it and pnpm-lock.yaml cannot be regenerated here. CI stays red until the engine publishes; the lockfile update belongs to the commit that follows the publish.

Signed-off-by: willbot <w.a.madden+machine@gmail.com>
Signed-off-by: Will Madden <madden@prisma.io>
@coderabbitai

coderabbitai Bot commented Aug 25, 2026 •

Copy link
Copy Markdown

Important

  • 🔍 Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Advanced

Run ID: a7252585-f1ce-499b-b844-bcae3e529045


Comment @coderabbitai help to get the list of available commands.

Engine 0.5.0 carries the config chain and the validator provenance API
this branch consumes. Main's pins are taken wholesale (composer 0.21.0
workspace versions, the removed pn-widgets example stays removed).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Signed-off-by: willbot <w.a.madden+machine@gmail.com>
Signed-off-by: Will Madden <madden@prisma.io>
@wmadden-electric
wmadden-electric marked this pull request as ready for review September 21, 2026 14:14
@prisma-gizmo

prisma-gizmo Bot commented Sep 21, 2026 •

Copy link
Copy Markdown

✅ Gizmo reviewed fb670a5 — posted 0 inline comment(s) this pass.

Open findings: none

Change walkthrough

Change walkthrough

This PR makes the composer section's configPath resolve against the prisma.config.ts file that declared it, instead of against the directory a command happens to run in. With config files now forming a chain (discovered from cwd up to the repo root and merged per key), a section written once at the root reaches every subdirectory, so cwd-based resolution named a different file in each one. The resolution moves into the section validator — the pattern engine 0.3.x+ defines — and everything downstream treats the value as absolute.

Section validator — section.ts:53 takes the section's provenance as a second argument and runs configPath through the engine's resolveSectionPath: relative resolves against the declaring file, absolute passes through. Since a section validator must never throw, even the impossible missing-provenance case degrades to a CONFIG.FIELD_INVALID diagnostic. The ComposerSection doc comment now documents the field as absolute-after-validation.

Load path — the delta since the last reviewed commit adds the receiving end of that contract. load-config.ts:308 replaces the silent path.resolve(cwd, request.configPath) with a loud CONFIG.PATH_NOT_ABSOLUTE diagnostic when a relative value arrives, so a caller skipping the validator fails visibly instead of quietly resolving against the process cwd via fs/c12. The diagnostic's shape matches the neighboring FILE_MISSING branch and the code fits the file's CONFIG.* taxonomy. pipeline.ts documents configPath as absolute-only. The --config flag path is unaffected — the family loader resolves that user-typed value against the host cwd by design.

Engine pin — all engine declarations move together from 0.4.0 to 0.5.0 (internal CLI, composer-cli's peer and dev pins, the target extension, and the four examples), which check-cli-engine-pin requires; note the PR description text says 0.3.0 while the diff bumps to 0.5.0. Test fakes also adopt the engine's chain-shaped LoadedConfig (files: [{ path, sections }]). The lockfile update is deferred to the post-publish commit, matching the previous engine bumps' shape.

Tests — the regression test in engine-cli.test.ts builds the actual two-file chain (root declares, cwd two directories down) where both wrong answers are distinguishable; section.test.ts covers the validator's resolution, pass-through, and no-throw contract; host-adapter.test.ts asserts the resolved path end to end through the real Runtime; and load-config.test.ts:181 pins the new absoluteness guard.

@pkg-pr-new

pkg-pr-new Bot commented Sep 21, 2026 •

Copy link
Copy Markdown

Open in StackBlitz

npm i https://pkg.pr.new/@prisma/composer@262
npm i https://pkg.pr.new/@prisma/composer-cli@262
npm i https://pkg.pr.new/@prisma/composer-prisma-cloud@262

commit: fb670a5

@prisma-gizmo prisma-gizmo Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

New findings: 🟡 2 minor · trace

Findings outside the diff

  • 🟡 Minor · consistency pnpm-lock.yaml — pnpm-lock.yaml still pins @prisma/cli-engine 0.4.0, so the tree does not install until the 0.5.0 publish and its lockfile follow-up
    All seven @prisma/cli-engine pins move to 0.5.0 while pnpm-lock.yaml still resolves 0.4.0, so pnpm install (and any --frozen-lockfile CI job) fails until @prisma/cli-engine@0.5.0 publishes — the PR description discloses this and defers the lockfile regeneration to the commit following the publish, matching the repo's prior engine-bump flow. Until that follow-up lands, the merged tree is uninstallable from the registry.
    Recommended fix: Regenerate pnpm-lock.yaml against the published @prisma/cli-engine@0.5.0 in the follow-up commit, as the PR description already plans.

Comment thread packages/0-framework/3-tooling/cli/src/load-config.ts Outdated
The section validator resolves configPath against the declaring file
now; this test predates that and still expected the raw relative path.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Signed-off-by: willbot <w.a.madden+machine@gmail.com>
Signed-off-by: Will Madden <madden@prisma.io>

@prisma-gizmo prisma-gizmo Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

New findings: none · trace

Still open from previous reviews: 🟡 1 minor

path.join(path.sep, ...) builds a rootless path that resolve() prefixes
with the process drive on Windows; building fixtures and expectations
with path.resolve keeps both sides identical on every platform.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Signed-off-by: willbot <w.a.madden+machine@gmail.com>
Signed-off-by: Will Madden <madden@prisma.io>

@prisma-gizmo prisma-gizmo Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

New findings: 🟠 1 major · trace

Still open from previous reviews: 🟡 1 minor

A relative configPath reaching configSource resolves against the
request's cwd rather than the Node process's, and the pass-through test
builds its absolute input with path.resolve like its siblings.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Signed-off-by: willbot <w.a.madden+machine@gmail.com>
Signed-off-by: Will Madden <madden@prisma.io>

@prisma-gizmo prisma-gizmo Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

New findings: 🟡 1 minor · trace

Comment thread packages/0-framework/3-tooling/cli/src/load-config.ts Outdated
wmadden-electric and others added 2 commits September 21, 2026 17:41
The contract says the section validator already resolved it, so the
relative fallback was dead code contradicting the doc one line above.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Signed-off-by: willbot <w.a.madden+machine@gmail.com>
Signed-off-by: Will Madden <madden@prisma.io>

@prisma-gizmo prisma-gizmo Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

New findings: 🟠 1 major · 🟡 1 minor · trace

Findings outside the diff

  • 🟠 Major · correctness packages/0-framework/3-tooling/cli/package.json — PR pins @prisma/cli-engine@0.5.0 but the lockfile cannot be regenerated until that version publishes — CI is red as committed
    Every @prisma/cli-engine declaration moves from 0.4.0 to 0.5.0 (the CLI runtime dep, composer-cli's peer and dev pins, the target extension, and all four examples — all verified consistent, no 0.4.0 stragglers), but pnpm-lock.yaml is not updated in this PR because the registry does not yet have 0.5.0. As committed, pnpm install fails and every CI job is red. The PR description discloses this and defers the lockfile to a follow-up commit, so it is a known, deliberate state — but reviewers should not merge until the engine publishes and the lockfile lands, and the description's version numbers are stale: it repeatedly cites engine 0.3.0 and check:cli-engine-pin "passing at 0.3.0", while the diff pins 0.5.0. Note also the new code depends on 0.5.0 engine API shapes (SectionProvenance as the validator's second argument, LoadedConfig as a files[] chain), so this PR is unbuildable against 0.4.0 even if the pin were reverted.
    Recommended fix: Merge only after @prisma/cli-engine@0.5.0 is published, and include the regenerated pnpm-lock.yaml (or land it as the immediately-following commit before any merge to the default branch). Update the PR description's version references to 0.5.0.

Comment thread packages/0-framework/3-tooling/cli/src/load-config.ts
CONFIG.PATH_NOT_ABSOLUTE names the skipped contract — the section
validator resolves against the declaring file — rather than letting fs
and c12 quietly resolve against the process cwd. Tested.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Signed-off-by: willbot <w.a.madden+machine@gmail.com>
Signed-off-by: Will Madden <madden@prisma.io>

@prisma-gizmo prisma-gizmo Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

New findings: none · trace

@prisma-gizmo prisma-gizmo Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All Gizmo review threads are resolved and the head commit has been reviewed. Approving.

@wmadden-electric
wmadden-electric merged commit 74dc06c into main Sep 22, 2026
25 checks passed
@wmadden-electric
wmadden-electric deleted the config-declaring-file-paths branch September 22, 2026 07:32
wmadden-electric added a commit to prisma/prisma-cli that referenced this pull request Sep 24, 2026
… against its config file

composer 0.22.0 resolves the composer section's relative configPath against the prisma.config.ts that declared it, not against the process cwd (prisma/composer#262). The bin test still expected the cwd-based path.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: willbot <w.a.madden+machine@gmail.com>
Signed-off-by: Will Madden <madden@prisma.io>
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