Three changes that only make sense together.
**tools/**. check-branding.sh, brand-plugin.sh and branding.conf were
accumulating in the repo root, and a deploy.sh/bat/ps1 set would land
there too. They now live in tools/ and resolve the repo root explicitly
rather than assuming their own directory is it, so they behave the same
however they are invoked.
**One name drives the rest.** branding.conf now derives the package name,
the Rust types and the display name from PLUGIN_NAME, each overridable.
Derivation-by-default removes a class of drift; the override matters
because the derivation is sometimes invalid — "206 Prototype" derives to
"206_prototype", which cargo rejects outright — and because PLUGIN_NAME is
cosmetic while the package name is structural. A display tweak should not
silently rename the crate, its bundle lookup, the CI command and the
lockfile. This template overrides three of them, which a real plugin
normally will not: its names are the template's own rather than derived
from a product name.
An overridden PKG that no longer matches the derivation is reported at
info level, never failed. The override is usually deliberate; a display
rename that forgot the package looks identical from here, and is not.
**The site table is data.** branding-sites.tsv lists every place a name
must appear and in what form; check-branding.sh iterates it instead of
carrying 29 check calls in shell. The scripts are now identical across
every plugin built from this template, with only the table and conf
differing — which matters because the template and codename-206 had
already diverged by two checks, so every sync was a shell merge.
brand-plugin.sh regenerates the rows it owns and preserves the rest, so a
hand-added row for a file this template does not ship survives a rename.
Custom rows are value-substituted like any other tracked file, so they
track the rename rather than going stale — the first cut excluded the
whole table from substitution and got that wrong.
brand-plugin.sh also gained an interactive mode: run it with no arguments
and it prompts for each value with the current one as the default, so
Enter keeps it and a run that answers nothing changes nothing. It only
engages when there is a terminal to ask at, so CI gets the usage message
and exit 2 rather than a hang.
Verified by applying a full rename to a sandboxed copy: 8 files rewritten,
29 owned rows regenerated, 1 custom row preserved and substituted, checker
green at 48/0/7, and the result compiles as bari_206.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WHt4DykxXaQnyaJfyS8KCn
Adds the minimal check a plugin repo actually needs: does it still build,
and do the identity strings still agree.
Both feature sets are built rather than just the default, because the
`vst3` cfg gates are exactly the kind of thing that rots — a default build
never compiles the Vst3Plugin impl, so a break there would otherwise
surface only when someone tried to ship a VST3. The bundle step is
included for the same reason: `cargo build` never exercises the xtask
bundler, and bundler.toml drifting from the crate name is invisible until
you try to produce an artifact.
The branding check runs first because it needs no toolchain and finishes
in under a second, so a half-landed rename fails before a build is spent
on it.
Performance testing is deliberately absent. Realtime cost is only
meaningful against an audio deadline, and `Plugin::process()` cannot be
called from a test at all: `ProcessContext` requires a `&Transport`, whose
constructor and fields are `pub(crate)` to nih_plug, so no external crate
can implement the trait. A static lint for locks in the audio path was
considered and dropped — `lock` and `borrow` are ordinary identifiers, not
reserved words, so a substring search matches every occurrence of "block"
in DSP code while missing `println!`, `recv()` and `Condvar::wait()`,
which are the likelier offenders. `assert_process_allocs` remains the real
guarantee, and it only fires in a debug build inside a host.
Verified by running the exact step sequence as the gitea-runner user under
the service's environment.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WHt4DykxXaQnyaJfyS8KCn