Skip to content
Public template

About

GitHub template for Go CLIs: config-driven README banner, diagrams, CLI reference and CI-tested terminal examples

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

docsmith — docs that are generated, tested and never stale

README banners, diagrams, CLI reference and tested examples for Go command-line tools.

CI Drift Go version License: Apache-2.0 Template

docsmith is a GitHub template for Go CLIs whose documentation should build itself. Four small generators under internal/tools/ turn what is already in the repository into the parts of a README that usually go stale: a themed banner, architecture diagrams, a command reference read from the real --help output, and terminal screenshots of examples that CI runs on every push. One file, docsmith.toml, drives all of them, so there is no project-specific code to edit.

How it works

docsmith inputs, generators and outputs
Generator Reads Writes
genbanner [banner] in docsmith.toml banner-dark.svg, banner-light.svg
gendocs <binary> --help, recursively; Go package doc comments the CLI reference and the project tree, between gendocs:cli and gendocs:layout markers
genexamples testdata/examples/*.txtar terminal SVGs rendered with freeze, between gendocs:example:ID markers
gendiagram docs/diagrams/*.toml NAME-dark.svg, NAME-light.svg

Every SVG comes in a dark and a light variant, and the README picks one with <picture> and prefers-color-scheme, so it matches the reader's GitHub theme.

The examples are the part that keeps the docs honest. Each .txtar file is a testscript that runs the real binary and asserts on its output, plus a display.sh section that shows the same commands in the docs. go test runs the script; genexamples renders the display. This one runs in CI with the rest of the tests:

Using this template

  1. Click Use this template on GitHub, or run gh repo create my-cli --template viniciusdc/docsmith --clone.

  2. Rename the module in go.mod and its imports: go mod edit -module github.com/you/my-cli, then replace github.com/viniciusdc/docsmith in cmd/.

  3. Replace cmd/hello and internal/textstat with your CLI. Any cobra binary works.

  4. Edit docsmith.toml: project name, tagline, binary, main, the banner text, colours and motif, and the layout annotations.

  5. Replace testdata/examples/*.txtar with examples of your commands, and docs/diagrams/how-it-works.toml with your own diagram.

  6. Install the tools and regenerate everything:

    make tools      # freeze and golangci-lint
    make generate   # banner, diagrams, CLI reference, layout, examples
  7. Commit the generated files, SVGs included.

Adopting in an existing repo

The generators do not depend on anything else in this repository, so they can be dropped into an existing Go module:

  1. Copy internal/tools/genbanner, gendiagram, gendocs and genexamples, plus docsmith.toml at the root of the module.

  2. Add the dependencies they import:

    go get github.com/BurntSushi/toml github.com/rogpeppe/go-internal/testscript
  3. Set [project].binary and [project].main in docsmith.toml, and point [docs].cli_file and [docs].layout_file at the Markdown files that should receive the generated sections. Leave either empty to skip it.

  4. Add the markers where generated content belongs. Each marker sits on a line of its own; markers inside code blocks, like these, are ignored:

    <!-- gendocs:cli -->
    <!-- /gendocs:cli -->
    
    <!-- gendocs:layout -->
    <!-- /gendocs:layout -->
    
    <!-- gendocs:example:my-example -->
    <!-- /gendocs:example:my-example -->
  5. Copy cmd/hello/script_test.go next to your main package (adjust the binary name and the relative path to the examples directory) so the .txtar examples run under go test.

  6. Merge the docs, banner, diagrams, examples, examples-check and generate targets from the Makefile, and copy .github/workflows/drift.yml.

Required tools: Go, and for rendered examples go install github.com/charmbracelet/freeze@latest. Without freeze, genexamples writes a fenced code block instead of an image.

Writing examples

An example is a .txtar file whose comment area holds # doc: headers and a testscript, followed by the files the script needs and a display.sh:

# doc:id     greet-and-count      marker name and SVG file name
# doc:file   README.md            the file that holds the markers
# doc:tested true                 adds "✓ CI tested" to the footer

exec hello greet Ada --greeting Hi
stdout '^Hi, Ada!$'

-- display.sh --
$ hello greet Ada --greeting Hi
Hi, Ada!

display.sh is a terminal session: lines starting with $ are commands, drawn bright, and everything else is output, drawn muted and verbatim. Set # doc:lang bash (or any language freeze knows) to highlight the snippet as code instead. Rendered SVGs are committed and carry a hash of the snippet they show; genexamples re-renders them when the snippet changes, and genexamples -force re-renders all of them.

Diagrams

A diagram is a TOML file of nodes, edges and optional groups. Nodes are styled source, stage, sink or planned; edges can carry a label and be dashed. Without width/height the layout is computed from the edges; with them, every node gives its own x/y, which is how how-it-works.toml lines each generator up with its output.

Keeping it in sync

.github/workflows/drift.yml regenerates the banner, diagrams, CLI reference, layout and examples on every push and pull request, and fails when the result differs from what is committed. freeze output can differ between machines and freeze versions, so CI does not install it. The rendered example SVGs are checked through the Markdown that embeds them: when an SVG is stale, CI falls back to a code block, the Markdown changes and the check fails. Fix it locally with make generate.

Configuration

Everything lives in docsmith.toml; every key has a default.

Table Keys
[project] name, tagline, binary, main
[banner] title, subtitle, output_dir, motif (blocks or lanes), [banner.dark]/[banner.light] with accent and palette, optional [[banner.rows]] or lanes + [[banner.shifts]]
[diagrams] source_dir, output_dir
[examples] dir, svg_dir, width
[docs] cli_file, layout_file, [docs.layout] with root_files, skip, max_depth and [docs.layout.annotations]

Make targets

make help            # list targets
make test            # unit tests and example scripts
make lint            # golangci-lint
make generate        # banner, diagrams, docs and examples
make examples-check  # what the drift workflow runs for examples

CLI reference

The sample CLI's reference is generated into docs/CLI.md.

Project layout

Makefile          Docs, test and lint targets
cmd/              Executable entry points
  hello/          hello is the sample CLI that ships with the docsmith template
docs/             Generated reference docs and their assets
  diagrams/       Diagram sources (TOML) for gendiagram
docsmith.toml     Configuration for every generator
go.mod            Module definition
internal/         Packages private to this module
  textstat/       textstat counts the lines, words and bytes in a stream of text
  tools/          Documentation generators, run through make
    genbanner/    Generates the README banner SVGs from docsmith.toml
    gendiagram/   Generates architecture diagram SVGs from TOML definitions
    gendocs/      Generates the CLI reference and project layout sections of the docs
    genexamples/  Generates executable documentation snippets

License

docsmith is licensed under the Apache License 2.0. See NOTICE for the fonts embedded in rendered examples.

About

GitHub template for Go CLIs: config-driven README banner, diagrams, CLI reference and CI-tested terminal examples

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages