Skip to content

Make main! optional under roc test - #10830

Draft
rtfeldman wants to merge 1 commit into
mainfrom
roc-test-no-main-required
Draft

Make main! optional under roc test#10830
rtfeldman wants to merge 1 commit into
mainfrom
roc-test-no-main-required

Conversation

@rtfeldman

Copy link
Copy Markdown
Contributor

It is common to have a .roc file that exists purely for tests — a bunch of top-level expects meant to be run with roc test foo.roc, which is how Exercism programs are laid out, for example. Until now such a file still had to define main! = |_| Ok({}), even though nothing ever calls it. Beyond being a papercut, that carries a real hazard: the file looks runnable, so a CI script that says roc foo.roc or roc build foo.roc by mistake can appear to succeed without ever having run the tests. roc test now requires no entrypoint at all: a headerless file that is neither a type module nor a default app is compiled as a plain module, and its expects run as usual.

The main! requirement only ever came from canonicalization. A headerless file starts out as a candidate type module; if it has a valid one-argument main! it becomes a default app, and otherwise validateForChecking demands either a nominal type matching the file name or a main!, reporting default_app_missing_main or type_module_missing_matching_type. Nothing in the roc test pipeline itself wants a main! — the expects are collected as compile-time roots on their own — so the diagnostic was the entire obstacle, and it made roc test exit non-zero even while printing that every test passed.

The fix reuses the validation that --main entry modules already got, where a headerless file that resolves to neither shape simply becomes a plain module with its top-level types exposed. That mode was selected by a validate_as_explicit_roots bool threaded from BuildEnv through the coordinator to canonicalizeModuleWithSiblings; it is now an explicit Can.Validation enum (.checking / .explicit_roots) owning the dispatch, which also lets the playground drop its private duplicate of the same two-case enum. roc test sets it on the build's root module via the new BuildEnv.setRootValidation.

roc check, roc build, and roc <file> are deliberately untouched and still reject an entrypoint-less file, so the mistaken-CI-invocation case stays loud. Type modules, module-header files, apps with a platform, and default apps with a real main! all behave exactly as before under roc test.

`roc test` runs only the top-level `expect`s in a file, so the root file
needs no entrypoint. A headerless file that is neither a type module nor
a default app is now compiled as a plain module under `roc test` instead
of being rejected for having no `main!`.

The root module of a `roc test` build gets the same validation that
`--main` entry modules already used, threaded through as an explicit
`Can.Validation` mode rather than a bool.
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