Skip to content

cratis screenplay validate <folder> compiles each file in isolation, and the alternative changes what a folder means #65

Description

@woksin

ScreenplayValidation.Validate calls IPlayFileCompiler.CompileIn, which compiles every .play file beneath the folder separately — parse plus validate, per file, with no shared context. Screenplay 2.x added CompileFolder, which parses each file, merges them into one ApplicationSyntax, and validates once.

The two disagree about what a folder is, and neither is a strict improvement.

What CompileIn gets wrong

A command in one file that produces an event declared in another reports:

warning PLAY0166: Unknown event

The declaration exists; the compiler just cannot see it from inside a single file. CompileFolder resolves it cleanly.

Worth stating plainly, because it sets the priority: PLAY0166 is a Warning, not an Error. ScreenplayDiagnostics.ExitCodeFor only fails on Error, so this has never failed anyone's build. It is noise, not breakage.

What CompileFolder gets wrong

CompileFolder treats a folder as exactly one application. Two independent documents in one folder, each with its own domain:

error PLAY0172: 'AppTwo.play' (1,1) The folder already declares a domain in
'AppOne.play' — a folder compiles to one application, which can have at most one

That is an Error, so it exits 5. Today that same folder validates clean.

Documentation/reference/screenplay.md documents the current model explicitly — validate takes a folder and "every .play file beneath it is compiled". Switching would make the documented behaviour wrong and turn a passing CI run red on a version upgrade.

It also does not fully fix the split-declaration case it was reached for. A slice split across two files trades one diagnostic for another:

error PLAY0173: Duplicate slice ... already declared in 'Domain.play'

Behaviour, side by side

Folder contents CompileIn (today) CompileFolder
One document, valid clean clean
produces an event declared in a sibling file warning PLAY0166 clean
One slice split across two files warning PLAY0166 error PLAY0173
Two independent documents, each with its own domain clean error PLAY0172, exit 5
Empty folder 0 files, 0 diagnostics 0 files, 0 diagnostics

One incidental difference: CompileFolder populates Diagnostic.Location.Path, where CompileIn leaves it null and the CLI supplies the file itself.

The decision

What should validate <folder> mean?

  1. Many independent documents — the current, documented behaviour. Cross-file references stay unresolvable, so PLAY0166 remains.
  2. One application per folder — what the Screenplay compiler itself asserts. Fixes cross-file references; makes a folder of unrelated plays an error, which is a breaking change to the CLI and needs a major.
  3. Group before compiling — partition files by whether they declare their own domain, then compile each group as a folder. Keeps both behaviours, but the grouping rule would be the CLI's invention rather than the language's, and the two would be free to drift.

This is the same class of question as Cratis/Stage#23: what the intermediate representation is allowed to mean. It wants a language-level answer, not a CLI-local one.

Deliberately left out of the Screenplay 2.x bump, which keeps CompileIn and changes no behaviour.

Metadata

Metadata

Assignees

No one assigned

    Labels

    questionFurther information is requested

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions