Port ref set|delete|list and format onto the engine - #29980
Port ref set|delete|list and format onto the engine#29980wmadden-electric wants to merge 3 commits into
Conversation
Four more ORM commands become engine result commands, mounted in the `orm` family and in the prisma-next bin tree under a new `ref` group. The commander versions stay: this adds the engine definitions beside them. Rendering follows the migration commands already on the engine. `ref set` and `ref delete` each report one summary block; `ref list` builds a `table` the engine sizes, gaining an Invariants column only when a ref carries any, and saying "No refs defined" when the project has none; `format` reports the one summary block the contract asks for. Spans carry a tone — ref names `ref`, contract hashes `identifier` — and no handler writes an escape sequence, so NO_COLOR strips the paint without moving a column. None of the four supplies a `stdout` presentation: their lines are for a reader, not for another program, so human mode writes nothing to stdout where the commander shell wrote the payload there. The handlers call the existing control-API operations with `(config, cwd)` from the context. `executeFormat` took a `cwd` and ignored it, so a relative `contract.source.inputs[0]` resolved against the process directory; it now resolves against the passed one. In production the config loader already hands over absolute paths, so this only shows up under a harness that supplies a cwd per run — which is what the new tests do. Errors return `notOk(normalizeError(...))` at the handler boundary, so every settled envelope carries typed `nextActions` and no `fix` prose. No error code changes: all nine the four commands can raise are already in the error reference. Coverage moves onto `createTestCli`, asserting envelopes, presented data and exit codes rather than output bytes, including the rendered ref table and the fact that `ref delete` removes a ref without prompting. `test/commands/ref.test.ts` is deleted rather than kept: it drove the operation layer through a module mock plus a dynamic import, which under `isolate: false` left the operation module bound to a stubbed `writeRef` for every later file. Its cases are all present in the new suites, except the injected write failure, which is `@internal/migration-tools`' own atomicity contract and tested there. 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>
The journey helpers `runRef` and `runFormat` now go through `runOnEngine`, so every journey step that sets, lists or deletes a ref — and the format journey — exercises the ported commands rather than the commander ones, and reports the engine result (events, stream frames, the presented result) alongside the exit code. `runFormatWithConfig` is gone: `runOnEngine` reads the journey context, so a caller no longer threads a directory and a config path by hand. The journey shell declares the `ref` group, which the engine requires before it will mount `ref set|list|delete`. Assertions move with the channels. The format journey reads "Nothing to format" off stderr, where human prose now goes, and checks stdout stayed empty; its refusal case pins the dotted code on the errored envelope instead of only a non-zero exit. The ref pointer e2e drops its console-capture wrapper for the harness, reading the drawn table off stderr and the refused hash off the envelope. 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>
|
|
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Path: .coderabbit.yml Review profile: CHILL Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
prisma-next
@prisma/orm-extension-arktype-json
@prisma/orm-extension-middleware-cache
@prisma/orm-extension-paradedb
@prisma/orm-extension-pgvector
@prisma/orm-extension-postgis
@prisma/orm-extension-supabase
@prisma/orm-family-mongo
@prisma/orm-family-sql
@prisma/orm-framework
@prisma/orm-mongo
@prisma/orm-postgres
@prisma/orm-sqlite
@prisma/orm-target-mongo
@prisma/orm-target-postgres
@prisma/orm-target-sqlite
@prisma/orm-toolchain
commit: |
size-limit report 📦
|
…ref-format Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io> # Conflicts: # packages/1-framework/3-tooling/cli/src/orm/cli.ts
Stacked on #29978. Review that first; this diff is the four commands and their tests.
What this looks like in practice
ref list, through the engine binary againstexamples/prisma-8-demo. The commander printed one line per ref; the engine renders a self-sizing table, and theInvariantscolumn appears only when some ref carries any:Ref names render green, hashes cyan, and with
NO_COLOR=1every escape is stripped and the column widths still hold.The decision
Four more commands ported as engine result commands —
ref set,ref delete,ref list,format— following the templatemigration listset. Still additive: the commander CLI keeps working and keeps owning theprisma-nextbinary.The one judgement call worth surfacing: these commands now write nothing to stdout in human mode. Two contract rules disagreed. The earlier one named
ref set|delete|listamong the commands whose payload lines move to thestdoutpresentation; the later one — written after the design discussion that established what the machine channel is for — saysstdoutcarries only lines another program parses, and a command supplies it only where it has such lines.Set ref "x" → <hash>is a rendering for a reader, not a document. The later rule wins, so those lines are human output on stderr, and the same reasoning applies toformat's success line. Recorded in the findings file so the divergence entry quotes the rule that was applied rather than the one it superseded.Divergences from the commander CLI
--configis no longer declared by any of the four (it is the engine's shared flag);--format prettyis--format human.--jsonis the engine's result frame ({"kind":"result","envelope":{…}}) rather than the bare document. The documents themselves are unchanged insideenvelope.result. The contract predicted "pretty-printed"; the engine frames compactly instead, which is engine-owned and identical for every ported command — recorded so the divergence file words it correctly.ref listrenders a table instead of onename → hash [invariants: …]line per ref. The empty case keeps its wording as an info summary.formatloses its styled header card; the success line keeps its wording and gains the engine's ✔.format --quietnow renders it.nextActionsand a docs URL instead offixprose. Exit codes unchanged; no error codes added or changed.refcommand — the inventory records that none prints one today, so none was invented.Reviewer notes
A module mock in the package's own suite silently broke the ported tests, in both directions.
test/commands/ref.test.tsmocked@internal/migration-tools/refsand then dynamically imported the operation module under that mock. Withisolate: falsethe operation stayed cached bound to the stubbedwriteRef, so engine-levelref setwrote nothing — and the reverse file ordering defeated the old file's mock instead. That file only ever drove the operation layer, so its coverage moved wholesale ontocreateTestCliand the file is deleted. One case did not move: awriteRefrejection proving the temp-file-and-rename is atomic, which is@internal/migration-tools' own contract and belongs in its package.This is the second time in this port that
isolate: falseplus a module mock has produced a test passing for the wrong reason. Worth remembering as a class.Verification
pnpm build,pnpm --filter @internal/cli test(133 files, 1589 tests),pnpm typecheck,pnpm lint,pnpm lint:deps,check:error-reference(277 codes, unchanged), plus the six journey files covering these commands and the ref-pointer integration suite. Each command was run through the built binary against a real example project and diffed against the commander CLI, piped and through a pty, with colour and withNO_COLOR=1. Both CLIs'formatproduce an identical rewrite of the demo'scontract.prisma.🤖 Generated with Claude Code