diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..62da761 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,4 @@ +# Shell scripts must keep LF endings. core.autocrlf=true on Windows would +# otherwise check them out CRLF, which a strict POSIX sh (dash, CI containers) +# rejects at the shebang. +*.sh text eol=lf diff --git a/check-branding.sh b/check-branding.sh new file mode 100644 index 0000000..a5b4253 --- /dev/null +++ b/check-branding.sh @@ -0,0 +1,76 @@ +#!/bin/sh +# check-branding.sh - verify the plugin's branding/identity strings agree everywhere. +# +# Plugin branding is duplicated across the build manifest, the bundler manifest, +# the deploy script and the source. 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. +# +# 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="codename_206" # Cargo package name == bundler.toml table key +DISPLAY="Codename 206" # bundle name -> ".vst3" / ".clap" +PLUGIN_NAME="206 prototype" # Plugin::NAME - what the DAW displays +CLAP_ID="com.mikkeli.codename-206" # CLAP_ID - stable plugin identity +VST3_CLASS_ID="Codename206Maxi!" # VST3_CLASS_ID - stable identity, MUST be 16 bytes + +# Spellings that must no longer appear anywhere in tracked files. Populate this +# with the OLD names after a rename to catch leftovers; keep empty otherwise. +# Space-separated; use a form with no spaces, or quote carefully. +STALE="" + +set -u +cd "$(dirname "$0")" || exit 1 + +pass=0; fail=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; } + +# 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 +} + +printf 'branding check (canonical: %s / "%s")\n\n' "$PKG" "$DISPLAY" + +printf 'build manifests\n' +check "Cargo.toml package name" Cargo.toml "name = \"$PKG\"" +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 "CLAP_ID" src/lib.rs "const CLAP_ID: &'static str = \"$CLAP_ID\"" +check "VST3_CLASS_ID" src/lib.rs "const VST3_CLASS_ID: [u8; 16] = *b\"$VST3_CLASS_ID\"" + +# 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 + +printf '\ndeploy script\n' +check "deploy.ps1 default package" deploy.ps1 "\$Package = \"$PKG\"" +check "deploy.ps1 VST3 bundle" deploy.ps1 "\$vst3Name = \"$DISPLAY.vst3\"" +check "deploy.ps1 CLAP bundle" deploy.ps1 "\$clapName = \"$DISPLAY.clap\"" + +if [ -n "$STALE" ]; then + printf '\nstale spellings\n' + for s in $STALE; do + hits=$(git ls-files 2>/dev/null | while read -r f; do + [ -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 +fi + +printf '\n%d passed, %d failed\n' "$pass" "$fail" +[ "$fail" -eq 0 ] || exit 1