Files
codename-206/check-branding.sh
T
Mikkeli Matlock 37f34e1175 rename: Codename 206 -> Bari 206
Retires the working codename now rather than at 1.0, because the two identity
constants a DAW uses to recognise a plugin across sessions can only be changed
for free while nothing has saved a project with it. Verified: zero references
to the plugin across all 69 FL project backups, under any identity string.

Derived spellings:
    Cargo package     codename_206        -> bari_206
    bundle / DAW name Codename 206 |
                      206 prototype       -> Bari 206      (unified; drops "prototype")
    Rust types        Codename206(Params) -> Bari206(Params)
    CLAP_ID           com.mikkeli.codename-206
                                          -> org.novoyuuparosk.bari-206
    VST3_CLASS_ID     Codename206Maxi!    -> Bari206Multiband

CLAP_ID moves to reverse-DNS on a domain actually controlled, and stops
disagreeing with a VENDOR that was already Novoyuuparosk. VST3_CLASS_ID stays
exactly 16 bytes and drops "Maxi", which sat close to Image-Line's Maximus and
Maximizer in the same product category.

Author identity converges on Mikkeli Matlock <mikkeli@novoyuuparosk.org>;
Cargo authors had been carrying a personal gmail address while Plugin::EMAIL
already used the org one. VENDOR stays Novoyuuparosk, which is the org rather
than the person, and copyright stays with the person.

Deliberately unchanged: the repo, its remote, the local directory and the
homepage URL all keep "codename-206". Renaming those buys nothing and costs a
Gitea rename, a remote rewrite and a directory move, so the bare "codename-206"
is current branding rather than residue - and is the one spelling the STALE
list must not contain.

Driven by check-branding.sh rather than by grep: setting the canonical block
listed all 26 sites, including .github/workflows/ci.yaml, which no explicit
check covered. That gap is now closed by a positive check on the CI bundle
command, so a future rename fails in seconds instead of after a full compile.
STALE now carries both the retired and the new spellings, so the next rename
is self-checking too.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LU1NRL7fAaZTtFMTTPn2b1
2026-08-31 22:55:41 +09:00

218 lines
10 KiB
Bash

#!/bin/sh
# SPDX-License-Identifier: GPL-3.0-or-later
# check-branding.sh - verify the plugin's branding/identity strings agree everywhere.
#
# Plugin branding is duplicated across the build manifest, the bundler manifest,
# the source, the docs and the deploy script. Nothing makes them agree, so a
# rename drifts silently: the bundle builds under one name and the deploy script
# looks for another. This asserts they match, and that the identity constants
# are legal.
#
# Kept in sync with musiikki/nih-plug-template's copy - fixes belong there
# first, then come back here. The differences are structural, not stylistic:
# this repo keeps its params in src/params.rs and wraps CLAP_DESCRIPTION.
#
# Usage: sh check-branding.sh (exit 0 = consistent, 1 = drift found)
#
# ---------------------------------------------------------------------------
# CANONICAL IDENTITY - the single source of truth. Edit these to rename, then
# run this script; every failure it prints is a place still holding the old name.
# ---------------------------------------------------------------------------
PKG="bari_206" # Cargo package name == bundler.toml table key
DISPLAY="Bari 206" # bundle name -> "<DISPLAY>.vst3" / "<DISPLAY>.clap"
PLUGIN_NAME="Bari 206" # Plugin::NAME - what the DAW displays
VENDOR="Novoyuuparosk" # Plugin::VENDOR - the org, not the person
EMAIL="mikkeli@novoyuuparosk.org" # Plugin::EMAIL
HOMEPAGE="https://github.com/mikkeli/codename-206" # Cargo homepage -> Plugin::URL
CLAP_ID="org.novoyuuparosk.bari-206" # CLAP_ID - stable plugin identity
VST3_CLASS_ID="Bari206Multiband" # VST3_CLASS_ID - stable identity, MUST be 16 bytes
DESCRIPTION="A VST3/CLAP multiband compressor/limiter with a custom gain-curve display"
CLAP_DESCRIPTION="Multiband compressor/limiter (stage 3: 3-band + 'All' channel)"
# Rust type names. Cosmetic - they never reach a host - but a rename that leaves
# half of them behind is the residue that says nobody read the file.
STRUCT="Bari206" # the Plugin impl target (src/lib.rs)
PARAMS_STRUCT="Bari206Params" # the Params impl target (src/params.rs)
# Old spellings retired by the "Codename 206" -> "Bari 206" rename, plus the new
# ones so the NEXT rename is self-checking too. Each entry is skipped while it is
# still one of the canonical values above and arms the moment it stops being one.
#
# Deliberately NOT listed: the bare "codename-206". The repo, its remote and the
# homepage URL all keep that name on purpose, so it is current branding, not
# residue. The retired CLAP ID is listed in full instead, which cannot collide
# with the homepage.
STALE="codename_206
Codename 206
Codename206
Codename206Params
Codename206Maxi!
206 prototype
com.mikkeli.codename-206
bari_206
Bari 206
Bari206
Bari206Params
Bari206Multiband
org.novoyuuparosk.bari-206"
set -u
cd "$(dirname "$0")" || exit 1
pass=0; fail=0; skip=0
ok() { pass=$((pass+1)); printf ' ok %s\n' "$1"; }
bad() { fail=$((fail+1)); printf ' FAIL %s\n' "$1"; [ $# -gt 1 ] && printf ' %s\n' "$2"; return 0; }
note() { skip=$((skip+1)); printf ' skip %s\n' "$1"; }
# Reported for awareness only - never counted, never fails the run.
info() { printf ' -- %s\n' "$1"; }
# has FILE PATTERN -> fixed-string search
has() { grep -qF "$2" "$1" 2>/dev/null; }
check() { # check LABEL FILE LITERAL
if [ ! -f "$2" ]; then bad "$1" "missing file: $2"; return; fi
if has "$2" "$3"; then ok "$1"; else bad "$1" "$2 does not contain: $3"; fi
}
# Same as check, but a missing file is "not applicable yet" rather than drift.
# The template ships without a deploy script; this starts checking once you add one.
opt_check() { # opt_check LABEL FILE LITERAL
if [ ! -f "$2" ]; then note "$1 ($2 not present)"; return; fi
if has "$2" "$3"; then ok "$1"; else bad "$1" "$2 does not contain: $3"; fi
}
printf 'branding check (canonical: %s / "%s")\n\n' "$PKG" "$DISPLAY"
printf 'build manifests\n'
check "Cargo.toml package name" Cargo.toml "name = \"$PKG\""
check "Cargo.toml homepage" Cargo.toml "homepage = \"$HOMEPAGE\""
check "Cargo.toml description" Cargo.toml "description = \"$DESCRIPTION\""
check "bundler.toml table key" bundler.toml "[$PKG]"
check "bundler.toml display name" bundler.toml "name = \"$DISPLAY\""
printf '\nsource identity (src/lib.rs)\n'
check "Plugin::NAME" src/lib.rs "const NAME: &'static str = \"$PLUGIN_NAME\""
check "Plugin::VENDOR" src/lib.rs "const VENDOR: &'static str = \"$VENDOR\""
check "Plugin::EMAIL" src/lib.rs "const EMAIL: &'static str = \"$EMAIL\""
check "CLAP_ID" src/lib.rs "const CLAP_ID: &'static str = \"$CLAP_ID\""
# CLAP_DESCRIPTION wraps onto a second line here, so the const name and its
# value are never on one line. Match the value alone.
check "CLAP_DESCRIPTION" src/lib.rs "Some(\"$CLAP_DESCRIPTION\")"
check "VST3_CLASS_ID" src/lib.rs "const VST3_CLASS_ID: [u8; 16] = *b\"$VST3_CLASS_ID\""
# Plugin::URL is env!("CARGO_PKG_HOMEPAGE"), so the manifest is the only place
# it is spelled. Assert the indirection is still in place rather than hardcoded.
check "Plugin::URL from manifest" src/lib.rs "const URL: &'static str = env!(\"CARGO_PKG_HOMEPAGE\")"
# VST3 class IDs are a fixed 16-byte array. A shorter or longer literal is a
# compile error, but it is far clearer to say so here than to read rustc on it.
n=$(printf '%s' "$VST3_CLASS_ID" | wc -c | tr -d ' ')
if [ "$n" -eq 16 ]; then ok "VST3_CLASS_ID is 16 bytes"
else bad "VST3_CLASS_ID is 16 bytes" "got $n bytes: \"$VST3_CLASS_ID\""; fi
# CLAP IDs are reverse-DNS by convention and are compared verbatim by hosts, so
# a stray space or capital is a silent identity change between machines.
case "$CLAP_ID" in
*\ *|*[A-Z]*) bad "CLAP_ID is reverse-DNS safe" "no spaces or capitals allowed: \"$CLAP_ID\"" ;;
*.*) ok "CLAP_ID is reverse-DNS safe" ;;
*) bad "CLAP_ID is reverse-DNS safe" "expected dotted reverse-DNS, got: \"$CLAP_ID\"" ;;
esac
printf '\nstructural names (src/lib.rs)\n'
# Every site the type names appear. A rename that misses one is a compile error
# rather than silent drift, but naming the site is faster than reading rustc,
# and the Vst3Plugin impl sits behind a cfg so a default build never reports it.
check "struct $STRUCT" src/lib.rs "struct $STRUCT {"
check "impl Plugin" src/lib.rs "impl Plugin for $STRUCT {"
check "impl ClapPlugin" src/lib.rs "impl ClapPlugin for $STRUCT {"
check "impl Vst3Plugin" src/lib.rs "impl Vst3Plugin for $STRUCT {"
check "nih_export_clap!" src/lib.rs "nih_export_clap!($STRUCT);"
check "nih_export_vst3!" src/lib.rs "nih_export_vst3!($STRUCT);"
check "struct $PARAMS_STRUCT" src/params.rs "struct $PARAMS_STRUCT {"
check "impl Default for params" src/params.rs "impl Default for $PARAMS_STRUCT {"
check "params field type" src/lib.rs "params: Arc<$PARAMS_STRUCT>,"
printf '\ndocs\n'
opt_check "README bundle command" README.md "cargo xtask bundle $PKG"
printf '\nci\n'
# CI bundles by package name, so a rename that misses this file breaks the build
# rather than drifting quietly - but it breaks after a full compile, which is a slow
# way to learn about a typo. Checking it here costs nothing and fails in seconds.
opt_check "CI bundle command" .github/workflows/ci.yaml "cargo xtask bundle $PKG"
printf '\ndeploy script\n'
opt_check "deploy.ps1 default package" deploy.ps1 "\$Package = \"$PKG\""
opt_check "deploy.ps1 VST3 bundle" deploy.ps1 "\$vst3Name = \"$DISPLAY.vst3\""
opt_check "deploy.ps1 CLAP bundle" deploy.ps1 "\$clapName = \"$DISPLAY.clap\""
printf '\nstale spellings\n'
# File list for the scan below. Prefer git, so build output and any vendored
# tree stay out of it. Fall back to find when this is not a checkout - an
# exported tarball, or a CI step that fetched without git metadata - because
# `git ls-files` there returns nothing, and an empty list would report every
# stale spelling as absent. A check that passes hardest when it can see least
# is worse than no check.
if git rev-parse --is-inside-work-tree >/dev/null 2>&1; then
file_list() { git ls-files; }
scan_source="git"
else
file_list() { find . -path ./.git -prune -o -path ./target -prune -o -type f -print | sed 's|^\./||'; }
scan_source="find (not a git checkout)"
fi
info "scanning tracked files via $scan_source"
# Every canonical spelling concatenated, for the substring test below.
CANONICAL_BLOB="$PKG
$DESCRIPTION
$CLAP_DESCRIPTION
$STRUCT
$PARAMS_STRUCT
$DISPLAY
$PLUGIN_NAME
$VENDOR
$EMAIL
$HOMEPAGE
$CLAP_ID
$VST3_CLASS_ID"
# Fed by here-doc rather than a pipe on purpose: a piped `while` runs in a
# subshell, and the pass/fail counters it increments would be discarded.
while IFS= read -r s; do
[ -n "$s" ] || continue
# Still part of a canonical value? Then it is current branding, not a leftover.
# This is what lets the list ship pre-seeded: entries arm themselves as you
# rename. Substring, not equality, because placeholders nest - "your-domain"
# lives inside the canonical CLAP_ID, and "YOUR-USERNAME" inside the homepage.
# Over-skipping is the safe direction: a false FAIL on a name you still use
# would train you to ignore this section.
case "$CANONICAL_BLOB" in
*"$s"*) note "\"$s\" (still canonical)"; continue ;;
esac
# This script names every placeholder by definition, so it can never be a hit.
hits=$(file_list 2>/dev/null | while read -r f; do
[ "$f" = "check-branding.sh" ] || { [ -f "$f" ] && grep -lF "$s" "$f" 2>/dev/null; }
done)
if [ -z "$hits" ]; then ok "no occurrences of \"$s\""
else bad "no occurrences of \"$s\"" "still present in: $(echo "$hits" | tr '\n' ' ')"; fi
done <<STALE_LIST
$STALE
STALE_LIST
# Template scaffolding, not drift: TODOs are legitimate while you are still
# building. Reported so a finished plugin does not quietly ship with them.
# `grep -c` prints 0 AND exits 1 when there are no matches, so `|| echo 0`
# would append a second zero and make the count unparseable. Swallow the
# status instead, and default an empty result (missing file) to zero.
todos=$(grep -c 'TODO' src/lib.rs 2>/dev/null || :)
[ -n "$todos" ] || todos=0
printf '\nscaffolding\n'
if [ "$todos" -eq 0 ]; then ok "no TODO markers left in src/lib.rs"
else info "$todos TODO marker(s) still in src/lib.rs (not a failure)"; fi
printf '\n%d passed, %d failed' "$pass" "$fail"
[ "$skip" -gt 0 ] && printf ', %d skipped' "$skip"
printf '\n'
[ "$fail" -eq 0 ] || exit 1