Documentation
¶
Overview ¶
Package pluginrender turns a plugin's AUTHOR tree into its PUBLISHED form.
Three surfaces, one shape ¶
A plugin exists in three shapes and only the first is written by a person:
author plugins/<name>/ live .go, tests, src/gen/pb published <registry>/<name>/ .go.src, tests, no src/gen/pb consumer <proto_dir>/plugins/<name>/ live .go, NO tests
This package owns the author → published step. `pluginfetch.stripSrcSuffix` owns published → consumer. They are inverses over everything but the tests, and nothing checked that until this package existed: the render lived as a shell loop in the Makefile and the strip lived in Go, so the two halves of one fact were written in two languages by two people at two times.
⚠️ A mismatch between them is not a broken build here. It is a CONSUMER's tree that does not compile — a `.go.src` nobody unpacked, or a `.go` that should have been inert and turns the plugin into a module inside somebody else's build. `pluginrender_test.go` renders and then strips and requires the round trip.
Why the Go files go inert ¶
A live `.go` (let alone a `go.mod`) under `<proto_dir>/plugins/<name>/src` would make the plugin a module inside the consumer's own build, which it is not: its sources are STAGED into a service bundle with their import paths rewritten. The `.src` suffix is how the published form says "data, not code".
Why the tests are published and then dropped ¶
They belong in the public registry: a plugin is the one part of this system somebody outside the team reads, and a plugin whose tests are invisible asks to be trusted on its word.
They do not belong in a consumer's tree. Nothing there runs them — the sources are staged with rewritten import paths, and a staged test would reference symbols the staging never placed. Measured on this repo, tests are +121% on auth's published Go, +89% on payment, +76% on agent: ten thousand lines committed into somebody's repository for code they cannot run.
Index ¶
Constants ¶
const SrcSuffix = ".src"
SrcSuffix marks a Go file carried as data rather than as code.
Named here rather than spelled in each place that appends or strips it: it is the whole contract between the render and the unpack, and a literal in two files is a contract in neither.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Stats ¶
Stats is what a render produced, so a caller can refuse a render that produced nothing rather than reporting success for an empty tree.
func Catalogue ¶
Catalogue renders every plugin under pluginsDir into dest — the whole public registry, as the publish step rsyncs it.
⚠️ RENDERING NOTHING IS NOT A SUCCESS, and that guard is why this function exists rather than a loop at each call site. The shell it replaces was ONE recipe line, so a `cp` that failed inside it set that command's status and the loop carried on — the recipe's result was the LAST command's, and with `plugins/` empty that was a successful `done`. Measured: over an empty tree it printed `cp: cannot stat 'plugins/*//plugin.yaml'` and exited 0, producing a catalogue holding only TESTING.md.
That matters because the publish rsyncs this output into the public registry with `--delete`. The empty catalogue was caught downstream by a zero-guard over published TESTS — which fires because no test was carried, not because no PLUGIN was, and which sits behind a documented skip flag. With that flag set, an empty render would have wiped every plugin from the registry and reported success.