Skip to content

S12: the command-line guide, a page per command, every example run - #42

Merged
david-Darkcollective merged 4 commits into
developfrom
docs/command-line-guide
Oct 10, 2026
Merged

david-Darkcollective merged 4 commits into
developfrom
docs/command-line-guide

Conversation

@david-Darkcollective

Copy link
Copy Markdown
Member

Fixes #16. Part of #17.

What

The command-line section of the Relix programming guide, in docs/guide/command-line, laid out the way the engine's manuals are: a README.md index of chapters and pages, plus index.json as the machine-readable index.

  • Hand-written pages: the command and where its script comes from; binding inputs (-i, its formats, standard input, headings, unbounded inputs, -a parameters); output formats; the catalog (discovery, the overlay, trust, relixrc); secrets and profiles; pipelines with jq, awk, find and xargs.
  • One page per command (commands/*.md), generated by CommandPages from the same picocli model as --help and the man pages. Each is followed by that command's hand-written examples from docs/command-examples/. Run ./gradlew commandPages to regenerate them. Subcommands such as catalog trust are sections of their parent's page, each with its own anchor, and index.json lists those anchors.
  • relix-<version>-docs.zip (./gradlew docsArchive), which the release workflow now attaches to each GitHub Release.

How it stays true

  • GuideExamplesTest runs all 116 examples over a fixture ~/shop (src/test/resources/docs-fixture) and compares stdout and the exit status. An example exits 0 unless it ends ; echo "exit $?", which prints the status for the page to show.
    • A plain relix … runs in the test JVM. Anything else runs through bash, with a relix shim that treats a stage's streams as a terminal when they are the example's own (fds 8/9). A piped example therefore prints exactly what a reader would see.
    • The examples are skipped on Windows; Linux and macOS run them all.
  • GuideStructureTest checks four things:
    • the command pages and index.json match the model (stale → ./gradlew commandPages);
    • every page is in the index;
    • every docs/command-examples file names a command;
    • no link to a page or heading is broken. Links into the engine's manuals are checked against the pinned engine's unpacked docs.
  • Mutation probe, as the issue asks. Each of these failed the build:
    • a changed output row, a changed exit status, and a failing command shown without its status;
    • a dropped output block, a changed bash-pipeline output, and an unrun bash block;
    • a link to a missing page, a missing heading, and a missing engine page;
    • a page left out of the index, a hand-edited generated page, and a changed example not regenerated;
    • the table renderer's footer changed, and the harness made to forget an example's exit status.

The site renders this section in the programming guide at guide/command-line/ and links it from llms.txt; that is a separate PR in DarkCollective/relix. Until releases attach the archive, the site pins a commit of this repository.

Found along the way (not changed here)

  • When several ${VAR}s of one declaration are missing, the engine's error names an arbitrary one, and which one changes between JVM runs. The secrets page's example has only one missing.
  • In a table, catalog files and catalog ls cut paths to 30 characters, so the pages use -o tsv for them.

docs/guide/command-line is the command-line section of the Relix
programming guide, laid out as the engine's manuals are: a README.md
index of chapters, and index.json as the machine-readable index.

Hand-written pages cover the command and where scripts come from, input
binding (-i, formats, standard input, headings, unbounded inputs, -a),
output formats, the catalog (discovery, the overlay, trust, relixrc),
secrets and profiles, and pipelines with jq, awk, find and xargs.

The command reference, commands/*.md, is generated by CommandPages from
the picocli model --help and the man pages come from, followed by each
command's hand-written examples in docs/command-examples. ./gradlew
commandPages rewrites them; GuideStructureTest fails while they are
stale, while the index misses a page, or while a link to a page or a
heading, here or in the engine's manuals, is broken.

GuideExamplesTest runs every shell block over a copy of the fixture under
src/test/resources/docs-fixture, the ~/shop the pages describe, and
compares standard output and the exit status. A plain relix command runs
in the test's JVM; anything else runs through bash, with a relix shim
that treats a stage's streams as a terminal when they are the example's
own, as a reader's would be. The guard was probed by mutation: a changed
row, a changed or unshown exit status, a dropped output block, a broken
link or heading, an unlisted page, a stale command page, an unrun bash
block, a change to the table renderer and a change to the harness itself
each fail it.

./gradlew docsArchive builds relix-<version>-docs.zip, which the release
workflow attaches to each GitHub Release for the site to render.

Fixes #16
… own

The site renders these chapters after the engine's programming guide's,
so each says it is about the command line.
…dings

On Linux the JVM decodes its arguments by the locale, so under LC_ALL=C
`relix doc σ` looked up '??'. A reader's terminal is UTF-8.

On Windows, text=auto checked the generated command pages out with CRLF
endings, which then differed from the generator's output; they keep LF,
as the .relix files the tests compare do.
picocli wraps the usage synopsis with the platform's line separator, so on
Windows the generated pages held CRLF and never matched the checked-in
ones.
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