Repository navigation
story(layout): a worked example whose project ships definitions files and no copybook - #427
Merged
Merged
Conversation
… and no copybook (#410) example/receivables is an accounts-receivable extract described by the definitions file cpybkc init wrote from a vendor copybook the project does not carry, and by init's layout scaffold answered. The copybook is a fixture at testdata/vendor/ARTRANS. example/regenerate_test.go regenerates it like every example, runs init over the fixture and holds the definitions file and the record forms to what init writes, and carries out the README's moves between copybook, file and block, requiring the same --emit-ir descriptor after each. #409's equality suite now inlines an example's definitions files as well as its copybooks. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
🟢 Approval recommended
The changes align with the stated acceptance criteria and add thorough tests/docs; only a minor test-helper diagnostic-message clarity nit was found.
No open issues 🎉
7 files not reviewed
example/receivables/receivables/codec.go: Generated fileexample/receivables/receivables/doc.go: Generated fileexample/receivables/receivables/file.go: Generated fileexample/receivables/receivables/file_test.go: Generated fileexample/receivables/receivables/literals.go: Generated fileexample/receivables/receivables/records.go: Generated fileexample/receivables/receivables/records_test.go: Generated file
What changed in this PR
Adds a new worked example project (example/receivables/) that intentionally ships only a layout plus definitions file(s) (no .cpy copybook), backed by a vendor-style fixture copybook in testdata/vendor/, and extends the existing test/equality machinery so the example is regenerated and checked byte-for-byte against what cpybkc init produces.
Changes:
- Add the
example/receivables/worked example (layout, definitions file, generated Go + graph outputs, and a detailed README covering migration/drift and file↔block moves). - Extend
example/regenerate_test.gowith two new tests that (1) re-runinitand require the committed definitions/layout record forms to match and (2) verify--emit-irstability across copybook/file/block moves. - Update
internal/project/equality_test.goso the “inline conversion” step can inline definitions-file sources as well as copybook sources, enabling#409’s suite to cover the new example shape.
| File | Description |
|---|---|
testdata/vendor/ARTRANS |
Adds vendor-style fixture copybook used by the receivables example tests/README. |
README.md |
Updates top-level docs to include and describe the new “no copybook” receivables example and adjusts counts/text accordingly. |
internal/project/equality_test.go |
Updates inlining/conversion test helpers to handle layouts that reference definitions files (not just copybooks). |
example/regenerate_test.go |
Adds dedicated tests asserting receivables matches init output and that copybook/file/block sources resolve identically. |
example/receivables/receivables/records.go |
Generated record structs for the receivables example. |
example/receivables/receivables/records_test.go |
Generated per-record roundtrip tests for the receivables example. |
example/receivables/receivables/literals.go |
Generated literal caching/re-expression support for discrimination under alternate encodings. |
example/receivables/receivables/file.go |
Generated Reader/Writer implementing the automaton for the receivables file shape. |
example/receivables/receivables/file_test.go |
Generated end-to-end file-path tests (reader/writer roundtrips) for the automaton. |
example/receivables/receivables/doc.go |
Generated package stub file. |
example/receivables/receivables/codec.go |
Generated Encoding() and per-record marshal/unmarshal implementations. |
example/receivables/receivables.sexpr |
New receivables layout: records bind to ARTRANS.sexpr, with renames/discriminators/sequence defined. |
example/receivables/README.md |
New example README documenting init transcription, drift procedure, and file↔block moves with --emit-ir checks. |
example/receivables/graph/graph.md |
Generated mermaid automaton + resolved item tables for the receivables layout. |
example/receivables/cpybkc.json |
Manifest for the new example (go + graph generators). |
example/receivables/cpybkc.gen.json |
Generated-file inventory for pruning/regeneration checks. |
example/receivables/ARTRANS.sexpr |
Definitions file committed as the cpybkc init transcription target for the vendor copybook. |
example/README.md |
Adds receivables to the examples index and documents the new special-case assertions for it. |
docs/layout/SPEC.md |
References the new worked example in the layout spec mapping/index. |
Review effort: Lite
6 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #410
A new worked example,
example/receivables/. It is an accounts-receivable transaction extract (recfm FB,lrecl 80), and it regenerates from a layout and one definitions file. There is no copybook anywhere in the project. Its vendor-style source copybook is a fixture outsideexample/, attestdata/vendor/ARTRANS.Acceptance criteria
A new example directory holds
cpybkc.json,receivables.sexpr(a layout naming definitions files),ARTRANS.sexpr(the definitions file), the generatedreceivables/andgraph/, andcpybkc.gen.json. It holds no.cpy. The source copybook istestdata/vendor/ARTRANS, written the way a vendor ships one: an extensionless member, sequence numbers in columns 1–6, a release stamp in 73–80 and a do-not-modify banner.example/regenerate_test.goregenerates it byte for byte. This needs no new code, because the existing walks pick it up. There are two new tests:TestTheReceivablesDefinitionsFileIsWhatInitWritesrunscpybkc init --copybook ../../testdata/vendor/ARTRANSfrom inside the example. It requires exactly the example's definitions files, byte for byte. It also requires everyrecordform in the example's layout to be one that init's scaffold writes, character for character.TestTheReceivablesLayoutResolvesAlikeFromItsCopybookAFileAndABlocknames the fixture copybook in place of the file and requires the same--emit-irdescriptor. It also carries out the README's file-to-block move and its block-to-file move as written, and requires the same descriptor after each. The move back must give the committed layout and file again, less the file's header comment.The fixture carries 88-levels (including a multi-value one),
VALUE(a77,88s,FILLER VALUE SPACES),SIGN LEADING SEPARATEandSIGN TRAILING SEPARATE,SYNCon two binary items (slack at offsets 13 and 22), and a77-level. Its REDEFINES has three alternatives overARD-BODY, so one definitions file serves five records, three of them one01-level.example/receivables/README.mdwalks through these procedures, using the example's own files:cpybkc initwrites a definitions file per copybook beside the layout it scaffolds #403's copybook-to-file migration;diff -ufrom a hypothetical release 3.2;Each move shows the
--emit-irbefore and after,cmp'd, and identical. No inline variant is committed. To make story(resolve): a record whose definitions are written in a block in the layout resolves to the descriptor its copybook gives, with every fault pointing into the layout #409's suite actually build one for this example,internal/project/equality_test.go'sinlinenow converts definitions-file sources into blocks as well as copybook sources.converttreats a layout naming only definitions files as converted already, and still refuses a layout naming neither.example/README.mdgains areceivables/row naming it as exactly whatcpybkc initwrites, andTestTheIndexNamesEveryExamplepasses. The "one manifest per example" prose names it. Its "what is asserted" section describes the two new tests.README.md: the worked-examples line ("a layout, the copybooks it names") is reworded, and so is "All four projects", which is now five. The tour gains areceivables/paragraph, and A manifest does not list copybooks points at the example.Judgment calls
ART-DETAIL-REC-ARD-INVOICE). The layoutrenames them for the generated code, so "the example is exactly whatinitwrites" holds for the record forms as well as the definitions file, and the test checks both. The scaffold'sART-DETAIL-REC-ARD-BODYrecord is left out, because a real extract never carries the base description of a redefined run. Narrowing to the data is the layout's job, and the definitions file does not change.../../testdata/vendor/ARTRANS, the path as typed from the example directory. The README's drift command is that same command, so against an unchanged copybook the diff is empty.receivables.sexpr, notartrans.sexpr. A layout name equal to a derived definitions-file name (case-folded) is a usage error.Found along the way, not fixed here
cpybkc-gen-goacceptsreceiver=r, but then generates code that does not compile: the receiver collides with ther *codec.Readerparameter ofUnmarshalCOBOL.wpresumably collides with*codec.Writerthe same way.isReceiverNameaccepts both. This example usesreceiver=a. The bug probably deserves its own story.Verification
dagger call cifrom an ordinary clone (a worktree cannot run dagger): passed.go test ./example/... ./internal/project/...: passed. Both new tests were mutation-checked: an editedARTRANS.sexprfails both.🤖 Generated with Claude Code