Compare commits

...

16 Commits

Author SHA1 Message Date
Mikkeli Matlock ce410b0047 Merge branch 'fix/gitattributes-stray-cr' 2026-09-14 01:41:39 +09:00
Mikkeli Matlock 5212b7806b fix: remove a stray CR byte from .gitattributes
The previous commit wrote a literal carriage-return byte into a comment, where
the text was meant to show the two characters backslash-r. Git's content sniffing
treats a lone CR as a sign of binary data, so .gitattributes itself was classed
-text (git ls-files --eol reported i/-text): the one file in the template that
the new LF policy could not normalise, and one every repo created from it would
have inherited.

The rules themselves were never affected - the byte sat inside a comment.

The comment now says "a trailing CR byte" in words. .gitattributes reports
i/lf w/lf, and `git add --renormalize .` stages nothing else.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LU1NRL7fAaZTtFMTTPn2b1
2026-09-14 01:41:39 +09:00
Mikkeli Matlock 09d98bef06 Merge branch 'chore/lf-line-endings' 2026-09-14 01:39:17 +09:00
Mikkeli Matlock 3abbb06073 chore: pin LF line endings in .gitattributes
The branding toolkit reads tools/branding-sites.tsv line by line with `read`.
On Windows, Git for Windows' default core.autocrlf=true checks that file out as
CRLF, so every row's last field - the pattern - gains a trailing \r and matches
nothing. In a child repo this made check-branding.sh report all 29 of its sites
as missing on Windows while the same commit passed on the Linux CI runner, and
brand-plugin.sh uses that same field as its sed search pattern. Only *.sh was
pinned to LF, which protected the scripts but not their data.

This is the template, so the fix belongs here: every repo created from it
inherits the policy instead of rediscovering the bug.

    * text=auto eol=lf       LF in the repo and every working tree, every OS
    *.sh text eol=lf         kept explicit: a CRLF shebang is a hard failure
    *.bat/*.cmd eol=crlf     the one exception; cmd.exe misparses LF batch files

An attribute beats core.autocrlf, so a fresh clone gets LF however its machine
is configured. Verified in a throwaway repo under autocrlf=true.

No blob changes: every committed blob was already LF, and
`git add --renormalize .` stages nothing but this file. Working tree
re-checked-out to match (14 files CRLF -> LF). Checker 38 passed / 0 failed.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LU1NRL7fAaZTtFMTTPn2b1
2026-09-14 01:39:17 +09:00
mikkeli 8630ba0c5b Merge branch 'ci/validate-workflow-changes'
CI / Build (push) Successful in 34s
Include the workflow file in both path filters so CI changes are self-validating.
2026-09-04 19:33:12 +09:00
mikkeli fad8e21b2b ci: let a workflow change validate itself
Adds .github/workflows/** to both path filters. A broken step, a moved
script path or a wrong runner label now fails on the commit that caused
it, instead of surfacing later against an unrelated source change and
looking like that change's fault.

This session produced exactly that bug: after the branding tools moved
under tools/, the workflow still ran `sh check-branding.sh` at the old
path, and it was caught by reading the file rather than by CI.

The limit is worth stating: this validates the job body, not the trigger
block. Break `on:` and the symptom is silence, which is indistinguishable
from success.

Workflow edits are rare enough that the extra builds cost nothing, and CI
config is the definition of how the project is built and verified — it
belongs on the source side of "source code edits only", not with the docs.

kolmekivi additionally gains the pull_request path filter the other two
already had.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WHt4DykxXaQnyaJfyS8KCn
2026-09-04 19:33:12 +09:00
mikkeli f8aa3ee888 Merge branch 'ci/tighten-triggers'
Apply the same source-path filter to pull_request that push already had.
2026-09-04 19:26:35 +09:00
mikkeli 24c6ee0655 ci: path-filter the pull_request trigger too
The push trigger was already restricted to master and to source paths,
but pull_request carried only a branch filter — so a PR touching nothing
but the README would have run a full build. A branch filter constrains
where a workflow fires, not what fires it.

Both filters now list the same six paths. A docs-only change runs nothing,
on either trigger.

Note that .github/workflows/** is deliberately absent from both lists, so
editing this file does not run it. That is the intended trade: fewer
pointless builds, at the cost of a broken workflow surfacing on the next
source change rather than immediately.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WHt4DykxXaQnyaJfyS8KCn
2026-09-04 19:26:35 +09:00
mikkeli de2dbbc218 Merge branch 'chore/homepage'
CI / Build (push) Successful in 31s
Point the placeholder homepage at the org wiki rather than a nonexistent GitHub URL.
2026-09-04 16:14:32 +09:00
mikkeli 1dc836dca5 chore: point the placeholder homepage at the org wiki
The Cargo homepage feeds Plugin::URL, which hosts can show to users, so
the placeholder should be somewhere reachable rather than a github.com URL
that never existed.

This retires YOUR-USERNAME and YOUR-PLUGIN-NAME as canonical values, which
is the self-arming STALE mechanism working as designed: both were skipped
while they were part of HOMEPAGE and became live checks the moment they
were not. Both pass, since the whole URL was replaced.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WHt4DykxXaQnyaJfyS8KCn
2026-09-04 16:14:32 +09:00
mikkeli 7b7ba69082 Merge branch 'chore/deny-future-incompat'
CI / Build (push) Successful in 28s
Inherit the future-incompatible guard in every plugin built from this template.
2026-09-03 08:25:56 +09:00
mikkeli 689891d01b chore: deny future-incompatible warnings
Carried back from Bari 206, where sixteen deferred hard errors had
accumulated unnoticed because nothing distinguished them from style
warnings in the build log.

Future-incompatibility warnings are rustc saying this code stops compiling
on some later release. Denying the group makes that a build failure the
day it appears rather than a surprise during an unrelated toolchain bump.
Every plugin cloned from this template inherits the guard.

Clippy and style lints stay warnings; only the future_incompatible group
is denied.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WHt4DykxXaQnyaJfyS8KCn
2026-09-03 08:25:56 +09:00
mikkeli a09b28d5fa Merge branch 'fix/narrow-patterns'
CI / Build (push) Successful in 26s
Match the narrowest distinctive fragment so rustfmt line-wrapping cannot break a
site check, and leave STALE alone when nothing was retired.
2026-09-02 16:37:59 +09:00
mikkeli 62ac2e9d6c fix: match the narrowest distinctive fragment, and stop padding STALE
Integrating into Bari 206 turned up a pattern that cannot match correctly
formatted source. Its CLAP_DESCRIPTION is long enough that rustfmt wraps
the assignment:

    const CLAP_DESCRIPTION: Option<&'static str> =
        Some("Multiband compressor/limiter (...)");

A site pattern spanning `const ... = Some("...")` never matches that, and
the fix is general rather than specific to this field: a site pattern
should be the narrowest fragment that is still distinctive, so formatting
decisions above it cannot break the check. Some("...") is unique enough
and lives on one line whatever rustfmt does with the rest.

Also stops appending a bare newline to STALE when nothing was retired,
which a no-op regeneration does on every run.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WHt4DykxXaQnyaJfyS8KCn
2026-09-02 16:37:59 +09:00
mikkeli 4a7dad95b3 Merge branch 'feat/author-field'
Separate cargo AUTHOR from Plugin::VENDOR and rewrite known sites from the table
before falling back to value substitution.
2026-09-02 16:36:34 +09:00
mikkeli 454e80bcd5 fix: separate cargo AUTHOR from Plugin::VENDOR, and rewrite sites precisely
Integrating this toolkit into Bari 206 surfaced two things the template
could not express, both of which would have produced wrong output.

**AUTHOR.** Cargo's authors entry names whoever wrote the plugin; VENDOR
is the organisation that ships it. Bari 206 separates them - "Mikkeli
Matlock" authored it, "Novoyuuparosk" vends it - while this template only
happened to work because its two placeholders were identical. AUTHOR is
now its own value defaulting to VENDOR, pinned in branding.conf only when
it actually differs so the file keeps showing that it derives.

**Site-directed rewriting.** That default is exactly what broke the
rename: with AUTHOR defaulting to VENDOR, both fields hold the same old
string, and a global value substitution cannot tell which occurrence
belongs to which. Renaming the vendor put the org name in the authors
field.

The site table already holds the old resolved literal for every site it
owns, and regeneration produces the new one, so rewriting by that pair is
unambiguous. brand-plugin.sh now does that first and falls back to value
substitution for everything the table does not enumerate - doc comments,
use sites in other modules, prose. The order matters and is load-bearing:
run the global pass first and it consumes the old literals, leaving the
precise pass nothing to match.

Verified on the ambiguous case: renaming with a distinct author now puts
the person in Cargo.toml's authors and the org in Plugin::VENDOR, where
the previous implementation put the org in both.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WHt4DykxXaQnyaJfyS8KCn
2026-09-02 16:36:34 +09:00
10 changed files with 196 additions and 95 deletions
+19 -3
View File
@@ -1,4 +1,20 @@
# Shell scripts must keep LF endings. core.autocrlf=true on Windows would # Line endings: LF in the repository and in every working tree, on every OS.
# otherwise check them out CRLF, which a strict POSIX sh (dash, CI containers) #
# rejects at the shebang. # This file is the policy, not each machine's git config. Git for Windows installs
# with core.autocrlf=true, which checks text out as CRLF; an attribute here beats
# that setting, so a fresh clone gets LF regardless of how its machine is set up.
#
# It matters beyond tidiness. tools/branding-sites.tsv is read line by line with
# `read`, and under CRLF every row's last field gained a trailing CR byte - so the
# branding checker reported all 29 sites as missing on Windows while passing on the
# Linux CI runner. text=auto leaves genuinely binary files alone.
* text=auto eol=lf
# Shell scripts are pinned explicitly as well: a strict POSIX sh (dash, CI
# containers) rejects a CRLF shebang outright rather than misbehaving quietly.
*.sh text eol=lf *.sh text eol=lf
# The exception. cmd.exe misparses LF-only batch files around labels and long
# lines, so these alone are checked out CRLF. The repository copy is still LF.
*.bat text eol=crlf
*.cmd text eol=crlf
+17 -1
View File
@@ -10,8 +10,24 @@ on:
- 'Cargo.lock' - 'Cargo.lock'
- 'bundler.toml' - 'bundler.toml'
- 'tools/**' - 'tools/**'
# This workflow validates itself: a broken step, a moved script path or a
# wrong runner label then fails loudly on the commit that caused it, rather
# than surfacing later against an unrelated source change. Note the limit -
# it checks the job body, not the trigger block above. Break `on:` and the
# symptom is silence, which looks like success.
- '.github/workflows/**'
# Mirrors the push filter. Without it a PR touching only the README would run a
# full build - the branch filter alone constrains where, not what.
pull_request: pull_request:
branches: [ master ] branches: [ master ]
paths:
- 'src/**'
- 'xtask/**'
- 'Cargo.toml'
- 'Cargo.lock'
- 'bundler.toml'
- 'tools/**'
- '.github/workflows/**'
workflow_dispatch: workflow_dispatch:
# Target the self-hosted Rust/audio runner registered to the `musiikki` org. # Target the self-hosted Rust/audio runner registered to the `musiikki` org.
@@ -58,4 +74,4 @@ jobs:
# not exercise — the bundle step is where bundler.toml and the crate name # not exercise — the bundle step is where bundler.toml and the crate name
# have to agree. # have to agree.
- name: Bundle - name: Bundle
run: cargo xtask bundle nih_plug_template --release --features vst3 run: cargo xtask bundle plugin_name --release --features vst3
Generated
+8 -8
View File
@@ -1102,14 +1102,6 @@ dependencies = [
"serde", "serde",
] ]
[[package]]
name = "nih_plug_template"
version = "0.1.0"
dependencies = [
"nih_plug",
"nih_plug_egui",
]
[[package]] [[package]]
name = "nih_plug_xtask" name = "nih_plug_xtask"
version = "0.1.0" version = "0.1.0"
@@ -1502,6 +1494,14 @@ version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b4596b6d070b27117e987119b4dac604f3c58cfb0b191112e24771b2faeac1a6" checksum = "b4596b6d070b27117e987119b4dac604f3c58cfb0b191112e24771b2faeac1a6"
[[package]]
name = "plugin_name"
version = "0.1.0"
dependencies = [
"nih_plug",
"nih_plug_egui",
]
[[package]] [[package]]
name = "polling" name = "polling"
version = "3.11.0" version = "3.11.0"
+11 -3
View File
@@ -1,9 +1,9 @@
[package] [package]
name = "nih_plug_template" name = "plugin_name"
version = "0.1.0" version = "0.1.0"
edition = "2021" edition = "2021"
authors = ["Your Name <your@email.com>"] authors = ["Your Name <your@email.com>"]
homepage = "https://github.com/YOUR-USERNAME/YOUR-PLUGIN-NAME" homepage = "https://wiki.novoyuuparosk.org"
description = "A minimal NIH-plug audio plugin" description = "A minimal NIH-plug audio plugin"
license = "GPL-3.0-or-later" license = "GPL-3.0-or-later"
@@ -15,7 +15,7 @@ members = ["xtask"]
# longer raises a licensing question — the gate now just keeps the default build # longer raises a licensing question — the gate now just keeps the default build
# light, since `vst3-sys` and its macro machinery are a sizeable dependency a # light, since `vst3-sys` and its macro machinery are a sizeable dependency a
# CLAP-only plugin never needs. Flip `default` to ["vst3"] if you always want it: # CLAP-only plugin never needs. Flip `default` to ["vst3"] if you always want it:
# cargo xtask bundle nih_plug_template --release --features vst3 # cargo xtask bundle plugin_name --release --features vst3
default = [] default = []
vst3 = ["nih_plug/vst3"] vst3 = ["nih_plug/vst3"]
@@ -23,6 +23,14 @@ vst3 = ["nih_plug/vst3"]
# `cdylib` is the plugin binary; `lib` (rlib) lets `cargo test` link the unit tests. # `cdylib` is the plugin binary; `lib` (rlib) lets `cargo test` link the unit tests.
crate-type = ["cdylib", "lib"] crate-type = ["cdylib", "lib"]
# Future-incompatibility warnings are deferred hard errors: rustc is telling you
# this code stops compiling on some later release. Denying the group turns that
# into a build failure the day it appears, rather than accumulating unnoticed
# until a toolchain bump breaks the build on a day you did not choose. Style and
# clippy lints are deliberately untouched - they stay warnings.
[lints.rust]
future_incompatible = { level = "deny", priority = -1 }
[dependencies] [dependencies]
# Pinned to the same commit as musiikki/codename-206. # Pinned to the same commit as musiikki/codename-206.
# Update the `rev` when you want to update NIH-plug. # Update the `rev` when you want to update NIH-plug.
+2 -2
View File
@@ -75,10 +75,10 @@ after if you do.
# No VST3 SDK needed — NIH-plug bundles its own bindings. # No VST3 SDK needed — NIH-plug bundles its own bindings.
# Build + bundle the CLAP (default) # Build + bundle the CLAP (default)
cargo xtask bundle nih_plug_template --release cargo xtask bundle plugin_name --release
# Add the VST3 as well — see the licensing note below before you do this # Add the VST3 as well — see the licensing note below before you do this
cargo xtask bundle nih_plug_template --release --features vst3 cargo xtask bundle plugin_name --release --features vst3
``` ```
**Output:** `target/bundled/<name>.clap` (and `<name>.vst3` with `--features vst3`), where **Output:** `target/bundled/<name>.clap` (and `<name>.vst3` with `--features vst3`), where
+1 -1
View File
@@ -3,5 +3,5 @@
# [package_name] # [package_name]
# name = "Human Readable Bundle Name" # defaults to <package_name> # name = "Human Readable Bundle Name" # defaults to <package_name>
[nih_plug_template] [plugin_name]
name = "Plugin Name" name = "Plugin Name"
+9 -9
View File
@@ -10,7 +10,7 @@ use std::sync::Arc;
// ────────────────────────────────────────────── // ──────────────────────────────────────────────
#[derive(Params)] #[derive(Params)]
struct PluginParams { struct PluginNameParams {
/// Editor window size, persisted with the plugin state. /// Editor window size, persisted with the plugin state.
#[persist = "editor-state"] #[persist = "editor-state"]
editor_state: Arc<EguiState>, editor_state: Arc<EguiState>,
@@ -21,7 +21,7 @@ struct PluginParams {
gain: FloatParam, gain: FloatParam,
} }
impl Default for PluginParams { impl Default for PluginNameParams {
fn default() -> Self { fn default() -> Self {
Self { Self {
editor_state: EguiState::from_size(320, 160), editor_state: EguiState::from_size(320, 160),
@@ -47,11 +47,11 @@ impl Default for PluginParams {
// ────────────────────────────────────────────── // ──────────────────────────────────────────────
#[derive(Default)] #[derive(Default)]
struct MyPlugin { struct PluginName {
params: Arc<PluginParams>, params: Arc<PluginNameParams>,
} }
impl Plugin for MyPlugin { impl Plugin for PluginName {
// TODO: Replace these placeholder values with your plugin's metadata. // TODO: Replace these placeholder values with your plugin's metadata.
const NAME: &'static str = "Plugin Name"; const NAME: &'static str = "Plugin Name";
const VENDOR: &'static str = "Your Name"; const VENDOR: &'static str = "Your Name";
@@ -124,7 +124,7 @@ impl Plugin for MyPlugin {
} }
} }
impl ClapPlugin for MyPlugin { impl ClapPlugin for PluginName {
// TODO: Replace with a unique CLAP ID in reverse-DNS form, e.g. "com.acme.fuzzbox" // TODO: Replace with a unique CLAP ID in reverse-DNS form, e.g. "com.acme.fuzzbox"
const CLAP_ID: &'static str = "com.your-domain.plugin-name"; const CLAP_ID: &'static str = "com.your-domain.plugin-name";
const CLAP_DESCRIPTION: Option<&'static str> = Some("Your plugin description"); const CLAP_DESCRIPTION: Option<&'static str> = Some("Your plugin description");
@@ -134,13 +134,13 @@ impl ClapPlugin for MyPlugin {
} }
#[cfg(feature = "vst3")] #[cfg(feature = "vst3")]
impl Vst3Plugin for MyPlugin { impl Vst3Plugin for PluginName {
// TODO: Replace with a unique 16-byte Class ID. // TODO: Replace with a unique 16-byte Class ID.
// Must be exactly 16 bytes — padded with '!' if shorter. // Must be exactly 16 bytes — padded with '!' if shorter.
const VST3_CLASS_ID: [u8; 16] = *b"Unique16CharId!!"; const VST3_CLASS_ID: [u8; 16] = *b"Unique16CharId!!";
const VST3_SUBCATEGORIES: &'static [Vst3SubCategory] = &[Vst3SubCategory::Fx]; const VST3_SUBCATEGORIES: &'static [Vst3SubCategory] = &[Vst3SubCategory::Fx];
} }
nih_export_clap!(MyPlugin); nih_export_clap!(PluginName);
#[cfg(feature = "vst3")] #[cfg(feature = "vst3")]
nih_export_vst3!(MyPlugin); nih_export_vst3!(PluginName);
+91 -39
View File
@@ -30,13 +30,13 @@ cd "$(dirname "$0")/.." || exit 1
. ./tools/branding.conf . ./tools/branding.conf
OLD_PKG="$PKG"; OLD_DISPLAY="$DISPLAY"; OLD_PLUGIN_NAME="$PLUGIN_NAME" OLD_PKG="$PKG"; OLD_DISPLAY="$DISPLAY"; OLD_PLUGIN_NAME="$PLUGIN_NAME"
OLD_VENDOR="$VENDOR"; OLD_EMAIL="$EMAIL"; OLD_HOMEPAGE="$HOMEPAGE" OLD_VENDOR="$VENDOR"; OLD_EMAIL="$EMAIL"; OLD_HOMEPAGE="$HOMEPAGE"; OLD_AUTHOR="$AUTHOR"
OLD_DESCRIPTION="$DESCRIPTION"; OLD_CLAP_DESCRIPTION="$CLAP_DESCRIPTION" OLD_DESCRIPTION="$DESCRIPTION"; OLD_CLAP_DESCRIPTION="$CLAP_DESCRIPTION"
OLD_CLAP_ID="$CLAP_ID"; OLD_VST3="$VST3_CLASS_ID" OLD_CLAP_ID="$CLAP_ID"; OLD_VST3="$VST3_CLASS_ID"
OLD_STRUCT="$STRUCT"; OLD_PARAMS_STRUCT="$PARAMS_STRUCT" OLD_STRUCT="$STRUCT"; OLD_PARAMS_STRUCT="$PARAMS_STRUCT"
new_display=""; new_pkg=""; new_vendor=""; new_email=""; new_homepage="" new_display=""; new_pkg=""; new_vendor=""; new_email=""; new_homepage=""
new_description=""; new_clap_description=""; new_struct="" new_description=""; new_clap_description=""; new_struct=""; new_author=""
new_clap_id=""; new_vst3=""; apply=0; allow_identity=0 new_clap_id=""; new_vst3=""; apply=0; allow_identity=0
while [ $# -gt 0 ]; do while [ $# -gt 0 ]; do
@@ -44,6 +44,7 @@ while [ $# -gt 0 ]; do
--display) new_display="${2:?}"; shift 2 ;; --display) new_display="${2:?}"; shift 2 ;;
--pkg) new_pkg="${2:?}"; shift 2 ;; --pkg) new_pkg="${2:?}"; shift 2 ;;
--vendor) new_vendor="${2:?}"; shift 2 ;; --vendor) new_vendor="${2:?}"; shift 2 ;;
--author) new_author="${2:?}"; shift 2 ;;
--email) new_email="${2:?}"; shift 2 ;; --email) new_email="${2:?}"; shift 2 ;;
--homepage) new_homepage="${2:?}"; shift 2 ;; --homepage) new_homepage="${2:?}"; shift 2 ;;
--description) new_description="${2:?}"; shift 2 ;; --description) new_description="${2:?}"; shift 2 ;;
@@ -72,7 +73,8 @@ ask() { # ask VARNAME PROMPT CURRENT
if [ -z "$new_display" ] && [ -t 0 ] && [ -c /dev/tty ]; then if [ -z "$new_display" ] && [ -t 0 ] && [ -c /dev/tty ]; then
printf 'branding this plugin - Enter keeps the current value, "-" clears an optional one\n\n' printf 'branding this plugin - Enter keeps the current value, "-" clears an optional one\n\n'
ask new_display "display name " "$OLD_DISPLAY" ask new_display "display name " "$OLD_DISPLAY"
ask new_vendor "vendor " "$OLD_VENDOR" ask new_vendor "vendor (org) " "$OLD_VENDOR"
ask new_author "cargo author " "$OLD_AUTHOR"
ask new_email "email " "$OLD_EMAIL" ask new_email "email " "$OLD_EMAIL"
ask new_homepage "homepage " "$OLD_HOMEPAGE" ask new_homepage "homepage " "$OLD_HOMEPAGE"
ask new_description "cargo description" "$OLD_DESCRIPTION" ask new_description "cargo description" "$OLD_DESCRIPTION"
@@ -99,6 +101,7 @@ derive_struct() {
[ -n "$new_struct" ] || new_struct=$(derive_struct "$new_display") [ -n "$new_struct" ] || new_struct=$(derive_struct "$new_display")
new_params_struct="${new_struct}Params" new_params_struct="${new_struct}Params"
[ -n "$new_vendor" ] || new_vendor="$OLD_VENDOR" [ -n "$new_vendor" ] || new_vendor="$OLD_VENDOR"
[ -n "$new_author" ] || new_author="$OLD_AUTHOR"
[ -n "$new_email" ] || new_email="$OLD_EMAIL" [ -n "$new_email" ] || new_email="$OLD_EMAIL"
[ -n "$new_homepage" ] || new_homepage="$OLD_HOMEPAGE" [ -n "$new_homepage" ] || new_homepage="$OLD_HOMEPAGE"
[ -n "$new_description" ] || new_description="$OLD_DESCRIPTION" [ -n "$new_description" ] || new_description="$OLD_DESCRIPTION"
@@ -158,6 +161,7 @@ row "package" "$OLD_PKG" "$new_pkg"
row "display" "$OLD_DISPLAY" "$new_display" row "display" "$OLD_DISPLAY" "$new_display"
row "Plugin::NAME" "$OLD_PLUGIN_NAME" "$new_display" row "Plugin::NAME" "$OLD_PLUGIN_NAME" "$new_display"
row "vendor" "$OLD_VENDOR" "$new_vendor" row "vendor" "$OLD_VENDOR" "$new_vendor"
row "cargo author" "$OLD_AUTHOR" "$new_author"
row "email" "$OLD_EMAIL" "$new_email" row "email" "$OLD_EMAIL" "$new_email"
row "homepage" "$OLD_HOMEPAGE" "$new_homepage" row "homepage" "$OLD_HOMEPAGE" "$new_homepage"
row "description" "$OLD_DESCRIPTION" "$new_description" row "description" "$OLD_DESCRIPTION" "$new_description"
@@ -183,12 +187,78 @@ if [ "$apply" -eq 0 ]; then
fi fi
# --- apply ------------------------------------------------------------------ # --- apply ------------------------------------------------------------------
# Three scratch files, one trap: the regenerated site table, the rows carried
# through from the old one, and the value-substitution pairs.
gen="$(mktemp)"; keep="$(mktemp)"; subst_file="$(mktemp)"
trap 'rm -f "$gen" "$keep" "$subst_file"' EXIT
T="$(printf '\t')"
{
printf 'req%spkg.cargo%sCargo.toml%sname = "%s"\n' "$T" "$T" "$T" "$new_pkg"
printf 'req%spkg.bundler%sbundler.toml%s[%s]\n' "$T" "$T" "$T" "$new_pkg"
printf 'opt%spkg.lock%sCargo.lock%sname = "%s"\n' "$T" "$T" "$T" "$new_pkg"
printf 'opt%spkg.ci%s.github/workflows/ci.yaml%scargo xtask bundle %s\n' "$T" "$T" "$T" "$new_pkg"
printf 'opt%spkg.readme%sREADME.md%scargo xtask bundle %s\n' "$T" "$T" "$T" "$new_pkg"
printf 'req%sdisplay.bundler%sbundler.toml%sname = "%s"\n' "$T" "$T" "$T" "$new_display"
printf 'opt%sdisplay.notice%sNOTICE%s%s\n' "$T" "$T" "$T" "$new_display"
printf 'req%sname.plugin%s%s%sconst NAME: &'"'"'static str = "%s"\n' "$T" "$T" "$LIB_FILE" "$T" "$new_display"
printf 'req%svendor.plugin%s%s%sconst VENDOR: &'"'"'static str = "%s"\n' "$T" "$T" "$LIB_FILE" "$T" "$new_vendor"
printf 'req%semail.plugin%s%s%sconst EMAIL: &'"'"'static str = "%s"\n' "$T" "$T" "$LIB_FILE" "$T" "$new_email"
printf 'req%sauthors.cargo%sCargo.toml%sauthors = ["%s <%s>"]\n' "$T" "$T" "$T" "$new_author" "$new_email"
printf 'req%shomepage.cargo%sCargo.toml%shomepage = "%s"\n' "$T" "$T" "$T" "$new_homepage"
printf 'req%surl.plugin%s%s%sconst URL: &'"'"'static str = env!("CARGO_PKG_HOMEPAGE")\n' "$T" "$T" "$LIB_FILE" "$T"
printf 'req%sdescription.cargo%sCargo.toml%sdescription = "%s"\n' "$T" "$T" "$T" "$new_description"
# Narrowest distinctive fragment, not the whole statement: rustfmt wraps a long
# CLAP_DESCRIPTION onto its own line, and a pattern spanning the assignment
# would then never match a correctly formatted file.
printf 'req%sdescription.clap%s%s%sSome("%s")\n' "$T" "$T" "$LIB_FILE" "$T" "$new_clap_description"
printf 'req%sclapid.plugin%s%s%sconst CLAP_ID: &'"'"'static str = "%s"\n' "$T" "$T" "$LIB_FILE" "$T" "$new_clap_id"
printf 'req%svst3id.plugin%s%s%sconst VST3_CLASS_ID: [u8; 16] = *b"%s"\n' "$T" "$T" "$LIB_FILE" "$T" "$new_vst3"
printf 'req%sstruct.def%s%s%sstruct %s {\n' "$T" "$T" "$LIB_FILE" "$T" "$new_struct"
printf 'req%sstruct.plugin%s%s%simpl Plugin for %s {\n' "$T" "$T" "$LIB_FILE" "$T" "$new_struct"
printf 'req%sstruct.clap%s%s%simpl ClapPlugin for %s {\n' "$T" "$T" "$LIB_FILE" "$T" "$new_struct"
printf 'req%sstruct.vst3%s%s%simpl Vst3Plugin for %s {\n' "$T" "$T" "$LIB_FILE" "$T" "$new_struct"
printf 'req%sstruct.exportclap%s%s%snih_export_clap!(%s);\n' "$T" "$T" "$LIB_FILE" "$T" "$new_struct"
printf 'req%sstruct.exportvst3%s%s%snih_export_vst3!(%s);\n' "$T" "$T" "$LIB_FILE" "$T" "$new_struct"
printf 'req%sparams.def%s%s%sstruct %s {\n' "$T" "$T" "$PARAMS_FILE" "$T" "$new_params_struct"
printf 'req%sparams.default%s%s%simpl Default for %s {\n' "$T" "$T" "$PARAMS_FILE" "$T" "$new_params_struct"
printf 'req%sparams.field%s%s%sparams: Arc<%s>,\n' "$T" "$T" "$LIB_FILE" "$T" "$new_params_struct"
printf 'opt%sdeploy.pkg%sdeploy.ps1%s$Package = "%s"\n' "$T" "$T" "$T" "$new_pkg"
printf 'opt%sdeploy.vst3%sdeploy.ps1%s$vst3Name = "%s.vst3"\n' "$T" "$T" "$T" "$new_display"
printf 'opt%sdeploy.clap%sdeploy.ps1%s$clapName = "%s.clap"\n' "$T" "$T" "$T" "$new_display"
} > "$gen"
# Pass 1 - site-directed. Each owned row in the existing table carries the OLD
# resolved literal for its site; the regenerated row carries the new one. Rewriting
# by that pair is unambiguous, which plain value substitution is not: AUTHOR
# defaults to VENDOR, so both fields can hold the same old string and a global
# replace cannot tell which occurrence belongs to which. This must run BEFORE
# pass 2, or the global replace consumes the old literals first and leaves the
# precise rewrite with nothing to match.
sites="tools/branding-sites.tsv"
T="$(printf '\t')"
if [ -f "$sites" ]; then
while IFS="$T" read -r ok_ oo_ of_ op_; do
case "$ok_" in ''|\#*) continue ;; esac
np_=$(awk -F"$T" -v o="$oo_" '$2==o {print $4; exit}' "$gen")
[ -n "$np_" ] || continue
[ "$np_" != "$op_" ] || continue
[ -f "$of_" ] || continue
esc_o=$(printf '%s' "$op_" | sed 's/[][\.*^$/|&]/\\&/g')
esc_n=$(printf '%s' "$np_" | sed 's/[\\/&|]/\\&/g')
tmp_=$(mktemp)
sed "s|$esc_o|$esc_n|g" "$of_" > "$tmp_" && cat "$tmp_" > "$of_"
rm -f "$tmp_"
done < "$sites"
printf ' pass 1: rewrote known sites from the table\n'
fi
# Pass 2 - value substitution, for everything the table does not enumerate:
# doc comments, use sites in other modules, prose in the README.
# Longest values first: a shorter spelling can be a substring of a longer one # Longest values first: a shorter spelling can be a substring of a longer one
# (the package name inside a URL, say), and replacing it first would corrupt the # (the package name inside a URL, say), and replacing it first would corrupt the
# longer match. branding.conf is excluded and rewritten wholesale below, so its # longer match. branding.conf is excluded and rewritten wholesale below, so its
# STALE list is never rewritten into meaninglessness. # STALE list is never rewritten into meaninglessness.
subst_file="$(mktemp)"
trap 'rm -f "$subst_file"' EXIT
{ {
printf '%s\t%s\n' "$OLD_CLAP_ID" "$new_clap_id" printf '%s\t%s\n' "$OLD_CLAP_ID" "$new_clap_id"
printf '%s\t%s\n' "$OLD_HOMEPAGE" "$new_homepage" printf '%s\t%s\n' "$OLD_HOMEPAGE" "$new_homepage"
@@ -200,6 +270,7 @@ trap 'rm -f "$subst_file"' EXIT
printf '%s\t%s\n' "$OLD_DISPLAY" "$new_display" printf '%s\t%s\n' "$OLD_DISPLAY" "$new_display"
printf '%s\t%s\n' "$OLD_STRUCT" "$new_struct" printf '%s\t%s\n' "$OLD_STRUCT" "$new_struct"
printf '%s\t%s\n' "$OLD_EMAIL" "$new_email" printf '%s\t%s\n' "$OLD_EMAIL" "$new_email"
printf '%s\t%s\n' "$OLD_AUTHOR" "$new_author"
printf '%s\t%s\n' "$OLD_VENDOR" "$new_vendor" printf '%s\t%s\n' "$OLD_VENDOR" "$new_vendor"
printf '%s\t%s\n' "$OLD_PKG" "$new_pkg" printf '%s\t%s\n' "$OLD_PKG" "$new_pkg"
} | awk -F'\t' '$1 != $2 { print length($1)"\t"$0 }' | sort -rn | cut -f2- > "$subst_file" } | awk -F'\t' '$1 != $2 { print length($1)"\t"$0 }' | sort -rn | cut -f2- > "$subst_file"
@@ -233,6 +304,8 @@ sed -e "s|^PKG=.*|PKG=\"$new_pkg\"|" \
-e "s|^DISPLAY=.*|DISPLAY=\"$new_display\"|" \ -e "s|^DISPLAY=.*|DISPLAY=\"$new_display\"|" \
-e "s|^PLUGIN_NAME=.*|PLUGIN_NAME=\"$new_display\"|" \ -e "s|^PLUGIN_NAME=.*|PLUGIN_NAME=\"$new_display\"|" \
-e "s|^VENDOR=.*|VENDOR=\"$new_vendor\"|" \ -e "s|^VENDOR=.*|VENDOR=\"$new_vendor\"|" \
-e "s|^# *AUTHOR=.*|AUTHOR=\"$new_author\"|" \
-e "s|^AUTHOR=.*|AUTHOR=\"$new_author\"|" \
-e "s|^EMAIL=.*|EMAIL=\"$new_email\"|" \ -e "s|^EMAIL=.*|EMAIL=\"$new_email\"|" \
-e "s|^HOMEPAGE=.*|HOMEPAGE=\"$new_homepage\"|" \ -e "s|^HOMEPAGE=.*|HOMEPAGE=\"$new_homepage\"|" \
-e "s|^DESCRIPTION=.*|DESCRIPTION=\"$new_description\"|" \ -e "s|^DESCRIPTION=.*|DESCRIPTION=\"$new_description\"|" \
@@ -242,8 +315,21 @@ sed -e "s|^PKG=.*|PKG=\"$new_pkg\"|" \
-e "s|^STRUCT=.*|STRUCT=\"$new_struct\"|" \ -e "s|^STRUCT=.*|STRUCT=\"$new_struct\"|" \
-e "s|^PARAMS_STRUCT=.*|PARAMS_STRUCT=\"$new_params_struct\"|" \ -e "s|^PARAMS_STRUCT=.*|PARAMS_STRUCT=\"$new_params_struct\"|" \
tools/branding.conf > tools/branding.conf.new tools/branding.conf > tools/branding.conf.new
if [ -n "$retired" ]; then
{ sed '$ s/"$//' tools/branding.conf.new; printf '%s"\n' "$retired"; } > tools/branding.conf { sed '$ s/"$//' tools/branding.conf.new; printf '%s"\n' "$retired"; } > tools/branding.conf
else
# Nothing retired (a no-op rename, or a regeneration): leave STALE untouched
# rather than appending a blank line to it on every run.
cat tools/branding.conf.new > tools/branding.conf
fi
rm -f tools/branding.conf.new rm -f tools/branding.conf.new
if [ "$new_author" = "$new_vendor" ]; then
# Identical to VENDOR, so re-comment it: the conf should keep showing that this
# value derives rather than pinning a duplicate that then has to be maintained.
tmp_c=$(mktemp)
sed "s|^AUTHOR=.*|# AUTHOR=\"$new_author\"|" tools/branding.conf > "$tmp_c" && cat "$tmp_c" > tools/branding.conf
rm -f "$tmp_c"
fi
printf ' rewrote tools/branding.conf (retired spellings appended to STALE)\n' printf ' rewrote tools/branding.conf (retired spellings appended to STALE)\n'
# Regenerate the site table. Rows whose owner this script recognises are # Regenerate the site table. Rows whose owner this script recognises are
@@ -251,40 +337,6 @@ printf ' rewrote tools/branding.conf (retired spellings appended to STALE)\n'
# custom, or added by hand for a file this template does not ship - is carried # custom, or added by hand for a file this template does not ship - is carried
# through untouched. Clobbering those silently is how a tool stops being trusted. # through untouched. Clobbering those silently is how a tool stops being trusted.
sites="tools/branding-sites.tsv" sites="tools/branding-sites.tsv"
gen="$(mktemp)"; keep="$(mktemp)"
trap 'rm -f "$subst_file" "$gen" "$keep"' EXIT
T="$(printf '\t')"
{
printf 'req%spkg.cargo%sCargo.toml%sname = "%s"\n' "$T" "$T" "$T" "$new_pkg"
printf 'req%spkg.bundler%sbundler.toml%s[%s]\n' "$T" "$T" "$T" "$new_pkg"
printf 'opt%spkg.lock%sCargo.lock%sname = "%s"\n' "$T" "$T" "$T" "$new_pkg"
printf 'opt%spkg.ci%s.github/workflows/ci.yaml%scargo xtask bundle %s\n' "$T" "$T" "$T" "$new_pkg"
printf 'opt%spkg.readme%sREADME.md%scargo xtask bundle %s\n' "$T" "$T" "$T" "$new_pkg"
printf 'req%sdisplay.bundler%sbundler.toml%sname = "%s"\n' "$T" "$T" "$T" "$new_display"
printf 'opt%sdisplay.notice%sNOTICE%s%s\n' "$T" "$T" "$T" "$new_display"
printf 'req%sname.plugin%s%s%sconst NAME: &'"'"'static str = "%s"\n' "$T" "$T" "$LIB_FILE" "$T" "$new_display"
printf 'req%svendor.plugin%s%s%sconst VENDOR: &'"'"'static str = "%s"\n' "$T" "$T" "$LIB_FILE" "$T" "$new_vendor"
printf 'req%semail.plugin%s%s%sconst EMAIL: &'"'"'static str = "%s"\n' "$T" "$T" "$LIB_FILE" "$T" "$new_email"
printf 'req%sauthors.cargo%sCargo.toml%sauthors = ["%s <%s>"]\n' "$T" "$T" "$T" "$new_vendor" "$new_email"
printf 'req%shomepage.cargo%sCargo.toml%shomepage = "%s"\n' "$T" "$T" "$T" "$new_homepage"
printf 'req%surl.plugin%s%s%sconst URL: &'"'"'static str = env!("CARGO_PKG_HOMEPAGE")\n' "$T" "$T" "$LIB_FILE" "$T"
printf 'req%sdescription.cargo%sCargo.toml%sdescription = "%s"\n' "$T" "$T" "$T" "$new_description"
printf 'req%sdescription.clap%s%s%sconst CLAP_DESCRIPTION: Option<&'"'"'static str> = Some("%s")\n' "$T" "$T" "$LIB_FILE" "$T" "$new_clap_description"
printf 'req%sclapid.plugin%s%s%sconst CLAP_ID: &'"'"'static str = "%s"\n' "$T" "$T" "$LIB_FILE" "$T" "$new_clap_id"
printf 'req%svst3id.plugin%s%s%sconst VST3_CLASS_ID: [u8; 16] = *b"%s"\n' "$T" "$T" "$LIB_FILE" "$T" "$new_vst3"
printf 'req%sstruct.def%s%s%sstruct %s {\n' "$T" "$T" "$LIB_FILE" "$T" "$new_struct"
printf 'req%sstruct.plugin%s%s%simpl Plugin for %s {\n' "$T" "$T" "$LIB_FILE" "$T" "$new_struct"
printf 'req%sstruct.clap%s%s%simpl ClapPlugin for %s {\n' "$T" "$T" "$LIB_FILE" "$T" "$new_struct"
printf 'req%sstruct.vst3%s%s%simpl Vst3Plugin for %s {\n' "$T" "$T" "$LIB_FILE" "$T" "$new_struct"
printf 'req%sstruct.exportclap%s%s%snih_export_clap!(%s);\n' "$T" "$T" "$LIB_FILE" "$T" "$new_struct"
printf 'req%sstruct.exportvst3%s%s%snih_export_vst3!(%s);\n' "$T" "$T" "$LIB_FILE" "$T" "$new_struct"
printf 'req%sparams.def%s%s%sstruct %s {\n' "$T" "$T" "$PARAMS_FILE" "$T" "$new_params_struct"
printf 'req%sparams.default%s%s%simpl Default for %s {\n' "$T" "$T" "$PARAMS_FILE" "$T" "$new_params_struct"
printf 'req%sparams.field%s%s%sparams: Arc<%s>,\n' "$T" "$T" "$LIB_FILE" "$T" "$new_params_struct"
printf 'opt%sdeploy.pkg%sdeploy.ps1%s$Package = "%s"\n' "$T" "$T" "$T" "$new_pkg"
printf 'opt%sdeploy.vst3%sdeploy.ps1%s$vst3Name = "%s.vst3"\n' "$T" "$T" "$T" "$new_display"
printf 'opt%sdeploy.clap%sdeploy.ps1%s$clapName = "%s.clap"\n' "$T" "$T" "$T" "$new_display"
} > "$gen"
owned=$(cut -f2 "$gen") owned=$(cut -f2 "$gen")
if [ -f "$sites" ]; then if [ -f "$sites" ]; then
+17 -17
View File
@@ -14,32 +14,32 @@
# with owner "custom" - no shell to change, and it survives the next rename. # with owner "custom" - no shell to change, and it survives the next rename.
# #
#kind owner file pattern #kind owner file pattern
req pkg.cargo Cargo.toml name = "nih_plug_template" req pkg.cargo Cargo.toml name = "plugin_name"
req pkg.bundler bundler.toml [nih_plug_template] req pkg.bundler bundler.toml [plugin_name]
opt pkg.lock Cargo.lock name = "nih_plug_template" opt pkg.lock Cargo.lock name = "plugin_name"
opt pkg.ci .github/workflows/ci.yaml cargo xtask bundle nih_plug_template opt pkg.ci .github/workflows/ci.yaml cargo xtask bundle plugin_name
opt pkg.readme README.md cargo xtask bundle nih_plug_template opt pkg.readme README.md cargo xtask bundle plugin_name
req display.bundler bundler.toml name = "Plugin Name" req display.bundler bundler.toml name = "Plugin Name"
opt display.notice NOTICE Plugin Name opt display.notice NOTICE Plugin Name
req name.plugin src/lib.rs const NAME: &'static str = "Plugin Name" req name.plugin src/lib.rs const NAME: &'static str = "Plugin Name"
req vendor.plugin src/lib.rs const VENDOR: &'static str = "Your Name" req vendor.plugin src/lib.rs const VENDOR: &'static str = "Your Name"
req email.plugin src/lib.rs const EMAIL: &'static str = "your@email.com" req email.plugin src/lib.rs const EMAIL: &'static str = "your@email.com"
req authors.cargo Cargo.toml authors = ["Your Name <your@email.com>"] req authors.cargo Cargo.toml authors = ["Your Name <your@email.com>"]
req homepage.cargo Cargo.toml homepage = "https://github.com/YOUR-USERNAME/YOUR-PLUGIN-NAME" req homepage.cargo Cargo.toml homepage = "https://wiki.novoyuuparosk.org"
req url.plugin src/lib.rs const URL: &'static str = env!("CARGO_PKG_HOMEPAGE") req url.plugin src/lib.rs const URL: &'static str = env!("CARGO_PKG_HOMEPAGE")
req description.cargo Cargo.toml description = "A minimal NIH-plug audio plugin" req description.cargo Cargo.toml description = "A minimal NIH-plug audio plugin"
req description.clap src/lib.rs const CLAP_DESCRIPTION: Option<&'static str> = Some("Your plugin description") req description.clap src/lib.rs Some("Your plugin description")
req clapid.plugin src/lib.rs const CLAP_ID: &'static str = "com.your-domain.plugin-name" req clapid.plugin src/lib.rs const CLAP_ID: &'static str = "com.your-domain.plugin-name"
req vst3id.plugin src/lib.rs const VST3_CLASS_ID: [u8; 16] = *b"Unique16CharId!!" req vst3id.plugin src/lib.rs const VST3_CLASS_ID: [u8; 16] = *b"Unique16CharId!!"
req struct.def src/lib.rs struct MyPlugin { req struct.def src/lib.rs struct PluginName {
req struct.plugin src/lib.rs impl Plugin for MyPlugin { req struct.plugin src/lib.rs impl Plugin for PluginName {
req struct.clap src/lib.rs impl ClapPlugin for MyPlugin { req struct.clap src/lib.rs impl ClapPlugin for PluginName {
req struct.vst3 src/lib.rs impl Vst3Plugin for MyPlugin { req struct.vst3 src/lib.rs impl Vst3Plugin for PluginName {
req struct.exportclap src/lib.rs nih_export_clap!(MyPlugin); req struct.exportclap src/lib.rs nih_export_clap!(PluginName);
req struct.exportvst3 src/lib.rs nih_export_vst3!(MyPlugin); req struct.exportvst3 src/lib.rs nih_export_vst3!(PluginName);
req params.def src/lib.rs struct PluginParams { req params.def src/lib.rs struct PluginNameParams {
req params.default src/lib.rs impl Default for PluginParams { req params.default src/lib.rs impl Default for PluginNameParams {
req params.field src/lib.rs params: Arc<PluginParams>, req params.field src/lib.rs params: Arc<PluginNameParams>,
opt deploy.pkg deploy.ps1 $Package = "nih_plug_template" opt deploy.pkg deploy.ps1 $Package = "plugin_name"
opt deploy.vst3 deploy.ps1 $vst3Name = "Plugin Name.vst3" opt deploy.vst3 deploy.ps1 $vst3Name = "Plugin Name.vst3"
opt deploy.clap deploy.ps1 $clapName = "Plugin Name.clap" opt deploy.clap deploy.ps1 $clapName = "Plugin Name.clap"
Can't render this file because it contains an unexpected character in line 7 and column 64.
+20 -11
View File
@@ -23,11 +23,15 @@ _derive_struct() {
} }
# --- the names --------------------------------------------------------------- # --- the names ---------------------------------------------------------------
PLUGIN_NAME="Plugin Name" # the one name everything else derives from PLUGIN_NAME="Plugin Name"
VENDOR="Your Name" # Plugin::VENDOR - the org, not the person VENDOR="Your Name"
EMAIL="your@email.com" # Plugin::EMAIL EMAIL="your@email.com"
HOMEPAGE="https://github.com/YOUR-USERNAME/YOUR-PLUGIN-NAME" # -> Plugin::URL # Cargo's authors entry names whoever wrote it, which is not always the vendor:
DESCRIPTION="A minimal NIH-plug audio plugin" # Cargo description # an org ships the plugin, a person authored it. Defaults to VENDOR when the two
# are the same, which is the common case for a one-person project.
# AUTHOR="Your Name"
HOMEPAGE="https://wiki.novoyuuparosk.org"
DESCRIPTION="A minimal NIH-plug audio plugin"
# What the plugin does *now*. No codename, no "prototype", no "v2 rewrite" - # What the plugin does *now*. No codename, no "prototype", no "v2 rewrite" -
# hosts show this to users who never knew any of that. check-branding.sh # hosts show this to users who never knew any of that. check-branding.sh
@@ -39,8 +43,8 @@ CLAP_DESCRIPTION="Your plugin description"
# existing session silently loses the plugin: the track comes up empty, with no # existing session silently loses the plugin: the track comes up empty, with no
# error. Choose once before the first release, then never again. # error. Choose once before the first release, then never again.
# brand-plugin.sh refuses to move them without --allow-identity-change. # brand-plugin.sh refuses to move them without --allow-identity-change.
CLAP_ID="com.your-domain.plugin-name" # reverse-DNS, lowercase, no spaces CLAP_ID="com.your-domain.plugin-name"
VST3_CLASS_ID="Unique16CharId!!" # MUST be exactly 16 bytes VST3_CLASS_ID="Unique16CharId!!"
# --- fixed at repo creation -------------------------------------------------- # --- fixed at repo creation --------------------------------------------------
# The repository's own name. Deliberately NOT renamed when the plugin is: the # The repository's own name. Deliberately NOT renamed when the plugin is: the
@@ -62,10 +66,11 @@ PARAMS_FILE="src/lib.rs"
# its package and type names are the template's own rather than derived from a # its package and type names are the template's own rather than derived from a
# product name. Delete these three lines after renaming and the derivations # product name. Delete these three lines after renaming and the derivations
# from PLUGIN_NAME take over. # from PLUGIN_NAME take over.
PKG="nih_plug_template" PKG="plugin_name"
STRUCT="MyPlugin" STRUCT="PluginName"
PARAMS_STRUCT="PluginParams" PARAMS_STRUCT="PluginNameParams"
# DISPLAY="Plugin Name" # defaults to PLUGIN_NAME # DISPLAY="Plugin Name" # defaults to PLUGIN_NAME
: "${AUTHOR:=$VENDOR}"
: "${DISPLAY:=$PLUGIN_NAME}" : "${DISPLAY:=$PLUGIN_NAME}"
: "${PKG:=$(_derive_pkg "$PLUGIN_NAME")}" : "${PKG:=$(_derive_pkg "$PLUGIN_NAME")}"
: "${STRUCT:=$(_derive_struct "$PLUGIN_NAME")}" : "${STRUCT:=$(_derive_struct "$PLUGIN_NAME")}"
@@ -87,4 +92,8 @@ com.your-domain.plugin-name
Unique16CharId!! Unique16CharId!!
YOUR-USERNAME YOUR-USERNAME
YOUR-PLUGIN-NAME YOUR-PLUGIN-NAME
your-domain" your-domain
https://github.com/YOUR-USERNAME/YOUR-PLUGIN-NAME
nih_plug_template
PluginParams
MyPlugin"