Add screenplay generate and validate commands - #51
Conversation
Introduces `cratis screenplay generate`, which loads a target project or solution into a Roslyn compilation and hands it to the Cratis.Arc.Screenplay generator to produce a `.play` document. Cratis.Arc.Screenplay is not published yet, so the CLI depends on it only when the CratisArcScreenplayProject MSBuild property points at a local checkout. Without it, the CLI still builds and the command reports CLI0005 instead of generating — this keeps the CLI buildable ahead of the generator's release. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Covers the new generate command end to end: settings resolution and error reporting, target resolution (solution vs. project, ambiguous folders), project candidate narrowing, diagnostic grouping/ordering/ exit-code rules, and document line-ending/encoding handling. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Adds the reference page for `cratis screenplay generate`, covering target resolution, output options, and diagnostics, and links it from the reference index and table of contents. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
A design-time build only runs the Compile target, and PrepareResources — the chain that turns <Generator>MSBuild:Compile</Generator> resx entries into .Designer.cs sources and adds them to @(Compile) — is a sibling of Compile under CoreBuild rather than one of its dependencies. It never ran, so every use of a generated resource class became a compile error and an ordinary application looked like it did not compile at all. Inject a targets file through CustomAfterMicrosoftCommonTargets that puts PrepareResources back in front of CoreCompile, where a real build runs it. MSBuild then generates the sources into the project's own intermediate output folder and adds them itself, so no path is hard coded and the project need never have been built. GeneratedResourceSources is the safety net for when that cannot work — a read-only intermediate output folder, or an MSBuild that stops honouring the hook — reading back any .Designer.cs a previous ordinary build left on disk that the project does not already compile. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The generator has shipped as 20.65.0, so the opt-in scaffold that let the CLI build without it has served its purpose. An ordinary PackageReference replaces the CratisArcScreenplayProject property, the conditional ProjectReference, the CRATIS_ARC_SCREENPLAY define and the Compile Remove that hid ArcScreenplayGeneration. With generation always available there is no gap left to report, so UnavailableScreenplayGeneration and the CLI0005 code it raised are gone and ScreenplayGenerations always creates the real generation. The package depends on exactly Cratis.Screenplay 1.5.2, which the repository already pins, so the two stay aligned. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
A Screenplay document is only worth committing if something checks it, and until now nothing in the CLI did. 'cratis screenplay validate' compiles a .play file, or every .play file beneath a folder, and reports what the compiler found — whatever wrote the document. It is deliberately a sibling of generate rather than a flag on it: the documents worth checking come from prologue and from people writing them by hand just as often as from generation, and a CI gate should not have to regenerate anything to run. ScreenplayValidation is the only place that knows the Cratis.Screenplay compiler exists, mirroring how ArcScreenplayGeneration isolates the generator. Its diagnostics are translated into the shape generate already reports, so both commands read identically. The compiler assigns no codes, so the code is left empty and the writer leaves it out rather than the CLI inventing a taxonomy; the location carries the file and position instead, in the form editors already understand. An empty folder is reported rather than quietly succeeding — a validation that checked nothing is never the answer anyone wanted, and CI is exactly where that would go unnoticed. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The command specs substitute the validation, mirroring how the generate command specs substitute the generation. ScreenplayValidation is specified against the real compiler and real files instead — it is the translation between two libraries, which a substitute would prove nothing about. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Loading a real application produced a 5,362-line document that compiles cleanly under the Screenplay compiler, alongside error diagnostics about constructs the generator could not read. The command threw all of it away and left the user with nothing at all — the one outcome that helps nobody. A document that is very nearly right, plus honest diagnostics saying where it is not, is strictly more useful. With --file the document is now always written and the command still exits non-zero, so a CI gate keeps failing while a person gets something to look at. Writing to standard output is unchanged: whatever consumes 'screenplay generate > MyApp.play' cannot tell a partial document from a complete one, so nothing is written there. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Keeps the Cratis pins in step with the Cratis.Arc.Screenplay 20.65.0 addition; Cratis.Screenplay stays at 1.5.2, which is what the package depends on. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Records the new command, and the change in what an error means for generate — the document is written anyway with --file, and only standard output stays empty. Also states plainly what separates 'cratis screenplay' from 'cratis arc' now that both describe an Arc application: arc talks to a running application over HTTP, screenplay only ever reads files. Fetching a document from a running application is a complementary route that does not exist yet, on either side, and is described as such rather than left as an implication. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
Reviewer context — deliberately kept out of the description. This is agent-authored code that no human has read yet. Please treat the spec suite as a claim to be checked rather than as evidence on its own. The areas I would look at first are What this depends on. The resx fix, and what it is not. A design-time build only runs the #49 also floated replacing Three things a reviewer may want to change
Verification
Known, pre-existing and not introduced here: |
Added
cratis screenplay generateproduces a Cratis Screenplay.playdocument from the source of an Arc application, without running it (Add 'cratis arc screenplay' to fetch a .play file from a running Arc application #44)cratis screenplay validatecompiles.playfiles and reports their diagnostics, exiting non-zero when any are errorsFixed