Skip to content

Commit 91e6f42

Browse files
drowaudioclaude
andauthored
2.0.0: Rewrite CLI parsing onto CLI11 + a JSON settings pipeline (#175)
* Bump pluginval to C++23 and add magic_args + nlohmann/json via CPM Prepares for the CLI parser refactor onto magic_args + a JSON-merge settings pipeline. - target_compile_features: cxx_std_20 -> cxx_std_23 (magic_args requires C++23) - CPMAddPackage magic_args v0.2.1 (header-only INTERFACE: magic_args::magic_args) - CPMAddPackage nlohmann/json 3.12.0 (nlohmann_json::nlohmann_json) - link both into the pluginval target Verified: clean build + link under C++23 with juce_recommended_warning_flags on JUCE 8.0.13 (macOS/AppleClang); binary runs. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * Replace hand-rolled CLI parser with a JSON-merge settings pipeline Introduces a single parser-agnostic settings struct and a layered JSON pipeline that replaces the bespoke juce::ArgumentList parser. Pipeline: each input layer (--config file, environment, CLI) becomes a sparse nlohmann::json object; layers are merged with merge_patch in precedence order (defaults < config < env < CLI, CLI wins) and deserialised in one step into PluginvalSettings, which converts to the existing PluginTests::Options at the JUCE boundary. - PluginvalSettings.h: unified std-typed struct + toPluginTestOptions() + fromPluginTestOptions(); NLOHMANN_DEFINE_TYPE..._WITH_DEFAULT so missing keys fall back to defaults; RealtimeCheck enum<->string mapping. - SettingsSerializer.{h,cpp}: JSON load/save + the comma-list, hex-seed and disabled-tests(file-or-list) coercions shared by the CLI/env layers. - SettingsParser.{h,cpp}: preprocess (deprecation rewrite, macOS flag strip, implicit --validate), magic_args parse of the flat options into the sparse CLI layer, env layer, merge, and the child-process handoff. - Child process round-trip now uses an authoritative base64 JSON arg (--config-base64) instead of per-flag re-serialisation, avoiding quote/tokenisation hazards. Round-trip asserted in tests. - CommandLine.{h,cpp}: thin adapter; old manual parsers/env-merge/help text deleted. magic_args drives --help (auto usage + env-var trailer). - New --config <file.json> option; precedence covered by tests. - CommandLineTests.cpp rewritten against the new pipeline (defaults, parser, hex seed, comma lists, rtcheck, path resolution, implicit validate, env precedence, config precedence, round-trip). - CMake: macOS deployment target 10.11 -> 13.3 (std::format in magic_args requires libc++ floating-point to_chars, available on 13.3+); add new sources. All --run-tests pass. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * Regenerate CLI docs and update architecture notes - docs/Command line options.md regenerated from magic_args --help output - CLAUDE.md: document the JSON-merge settings pipeline, new source files, magic_args + nlohmann/json deps, C++23, and the macOS 13.3 deployment target Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * Swap magic_args for CLI11: bind options directly to the settings struct Addresses review feedback that the magic_args version duplicated the settings into a parallel PluginvalCliArgs struct plus manual CLI->JSON and ENV->JSON bridges (5-6 edit sites per new option), and forced cxx_std_23 + a macOS 13.3 deployment target (std::format). CLI11 binds each option directly to a PluginvalSettings member, with the environment variable on the same line via ->envname(). Adding an option is now three edits: a struct member, a nlohmann macro entry, and one add_option(...) line. No parallel struct, no cliArgsToJson, no envLayer. - SettingsParser: rewritten on CLI11; comma lists via ->delimiter(','), enum via CheckedTransformer, hex/int seed via a small callback. --config seeds the struct before parse so precedence stays defaults<config<env<CLI. --help/--version handled by CLI11 (auto usage + footer). - SettingsSerializer: dropped the comma/JSON-array coercions; kept the hex seed + disabled-tests(file-or-list) helpers and JSON load/save. - Child-process base64 JSON handoff (--config-base64) unchanged. - CommandLineTests: env tests now use setenv/unsetenv (CLI11 reads the real environment); all other cases unchanged. All --run-tests pass. - CMake: magic_args -> CLI11 2.6.2; revert cxx_std_23 -> cxx_std_20 and CMAKE_OSX_DEPLOYMENT_TARGET 13.3 -> 10.11. - Docs/CLAUDE.md updated. Verified: full build (validator ON, C++20, macOS 10.11), --run-tests pass, real --validate SUCCESS, --config precedence covered by tests. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * Fix CI failures from the CLI11 refactor Three regressions surfaced by CI (develop is green): - Linux build: std::int64_t (== long on LP64) vs juce::int64 (== long long) made expectEquals template deduction fail. Cast the settings int64 fields to juce::int64 in CommandLineTests. (macOS compiled because there the two types are identical.) - "Pluginval as Dependency" Verify: verify_pluginval runs `pluginval --help | grep "JUCE v<version>"`. CLI11's auto help didn't print the JUCE version; add it to the help footer. - Windows --run-tests exit 127: runUnitTests() called the [[noreturn]] juce::ConsoleApplication::fail(), which throws; outside a ConsoleApplication command handler that throw was uncaught -> std::terminate. Set the application return value directly instead. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * Fix Linux X11 macro clash; print unit-test failures to stdout - Linux build: include <CLI/CLI.hpp> before the JUCE headers. JUCE pulls in X11 on Linux (JUCE_GUI_BASICS_INCLUDE_XHEADERS), whose `#define Success 0` clashed with CLI11's CLI::ExitCodes::Success enumerator. macOS/Windows don't use X11, so only Linux was affected. - runUnitTests now prints each failed test (name + messages) to stdout. juce::UnitTestRunner logs via juce::Logger, which on a GUI app (Windows) doesn't reach the console, so CI couldn't show which tests failed. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * Fix Windows test: compare raw parsed paths, not juce::File-normalised "Command line parser" asserted opts.dataFile/outputDir.getFullPathName() against Unix-style literals; on Windows juce::File normalises those to the current drive (e.g. "D:\path\to\file"), failing the comparison. Assert the raw parsed settings strings instead, which are identical on all platforms. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * Revise precedence to defaults < env < config < CLI Reworks the layering so a --config file (deliberate, per-invocation) ranks above ambient environment variables, and makes --config repeatable. - Environment layer: env-var names are now derived from the registered CLI11 options (--strictness-level -> STRICTNESS_LEVEL) instead of CLI11's ->envname(), so there is no hand-maintained env table and env support is automatic for every option. A synthetic "--name=value" argv is built from the environment and parsed by CLI11, reusing all its coercion (comma lists, enum transformer, hex-seed callback). Flags accept --flag=1/0. - --config: repeatable; each JSON file is merge_patch-ed in command-line order (later files win per key). Applied between the env and CLI layers, so it beats env and loses to explicit CLI options. (Inline JSON dropped for now to avoid command-line re-tokenisation hazards; file paths only.) - The env layer reads through an injectable EnvProvider again, so the unit tests no longer mutate the real process environment (also removes the Windows _putenv_s fragility). - Tests updated for the new precedence + a repeatable-config test. - Help footer, docs and CLAUDE.md updated. Verified end-to-end: env(6) -> 6; env(6)+config(2) -> 2; +CLI(9) -> 9. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * Add 2.0.0 changelist, harden --config-base64, add subcommands handoff - CHANGELIST.md: 2.0.0 entry summarising the CLI11/JSON parser rewrite, --config, the new precedence, and the breaking changes (VERSION not bumped). - --config-base64 (internal parent->child handoff) now errors if combined with any option other than --validate, instead of silently ignoring it. Test added. - SUBCOMMANDS_HANDOFF.md: handoff doc for the deferred subcommand restructure (validate/run-tests/strictness-help with deprecated flat-flag aliases). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * Audit CLAUDE.md: remove non-existent --validate-in-process CLI flag - --validate-in-process is not a CLI option (launchInProcess is GUI/internal only); the new strict parser would now error on it. Removed from the options list and corrected the process-model notes (GUI uses child processes; the CLI --validate runs in-process with signal-handler crash reporting). - Note the staged 2.0.0 CHANGELIST entry vs the un-bumped VERSION. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * Compile EditorTests and ExtremeTests (were present but not built) Source/tests/EditorTests.cpp and Source/tests/ExtremeTests.cpp were never added to SourceFiles, so their self-registering PluginTest instances were never compiled in and the tests never ran. Add them to the build. Re-enables: "Editor stress" (L6), "Editor DPI Awareness" (L3, Windows only), "Allocations during process" (L9), "Process called with a larger than prepared block size". Verified they compile and pass a real strictness-10 validation. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * Fix Windows-only compile error in EditorDPITest Qualify juce::ScopedDPIAwarenessDisabler. The EditorDPITest block is guarded by #if JUCE_WINDOWS && JUCE_WIN_PER_MONITOR_DPI_AWARE, so this latent bug only surfaced now that EditorTests.cpp is compiled (and only on Windows). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
1 parent 4c5adc2 commit 91e6f42

14 files changed

Lines changed: 1282 additions & 655 deletions

CHANGELIST.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,16 @@
11
# pluginval Change List
22

3+
### 2.0.0
4+
- Replaced the hand-rolled command-line parser with CLI11 and a single JSON-based settings pipeline
5+
- Added `--config <file.json>` to load settings from JSON (repeatable; later files win per key)
6+
- Settings precedence is now (lowest to highest): defaults, environment variables, `--config`, command-line options
7+
- Environment variable support is now automatic for every option (including `DISABLED_TESTS`)
8+
- **Breaking:** unrecognised options now produce an error instead of being ignored
9+
- **Breaking:** invalid option values now error instead of silently falling back (e.g. `--rtcheck banana`, `--strictness-level abc`)
10+
- **Breaking:** falsey flag environment variables now mean off (e.g. `SKIP_GUI_TESTS=0` no longer enables skipping)
11+
- `--help` output is now generated by CLI11
12+
- Enabled the editor stress and extreme (real-time allocation / oversized block) tests that were present in the source tree but had not been compiled into the build
13+
314
### 1.0.5
415
- Added drag-and-drop of plug-in files onto the main window, with two drop zones to either validate the plug-in or add it to the plugin list [#170]
516
- Added static linking to the Windows runtime so it should run on more Windows systems (particularly non-dev machines)

CLAUDE.md

Lines changed: 45 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
**pluginval** is a cross-platform audio plugin validator and tester application developed by Tracktion Corporation. It tests VST, VST3, AU (Audio Unit), LV2, and LADSPA plugins for compatibility and stability with host applications.
66

7-
- **Version**: 1.0.4 (see `VERSION` file)
7+
- **Version**: 1.0.4 (see `VERSION` file; a 2.0.0 entry is staged in `CHANGELIST.md` but `VERSION` is not yet bumped)
88
- **License**: GPLv3
99
- **Framework**: Built on JUCE (v8.0.x)
1010
- **Language**: C++20
@@ -80,7 +80,10 @@ pluginval/
8080
│ ├── MainComponent.cpp/h # GUI main window component
8181
│ ├── Validator.cpp/h # Core validation orchestration
8282
│ ├── PluginTests.cpp/h # Test framework and base classes
83-
│ ├── CommandLine.cpp/h # CLI argument parsing
83+
│ ├── CommandLine.cpp/h # Thin CLI adapter (delegates to SettingsParser)
84+
│ ├── PluginvalSettings.h # Unified settings struct + JSON mapping + toPluginTestOptions()
85+
│ ├── SettingsParser.cpp/h # CLI/env/config -> merged JSON -> settings; child-process handoff
86+
│ ├── SettingsSerializer.cpp/h # JSON load/save + value coercions (comma lists, hex seed)
8487
│ ├── CrashHandler.cpp/h # Crash reporting utilities
8588
│ ├── TestUtilities.cpp/h # Helper functions for tests
8689
│ ├── RTCheck.h # Real-time safety checking macros
@@ -188,6 +191,41 @@ VST2_SDK_DIR=/path/to/vst2sdk cmake -B Builds/Debug .
188191
- Auto-registers via static instance pattern
189192
- Defines requirements (thread, GUI needs)
190193

194+
### CLI Settings Pipeline
195+
196+
Command-line parsing centres on one plain settings struct (`PluginvalSettings`)
197+
that CLI11 binds to directly. A single instance is filled by successive layers,
198+
**lowest to highest precedence: defaults → environment → `--config` → CLI**
199+
(in `SettingsParser::parseTokens`):
200+
201+
1. **preprocess** the raw command line — rewrite the deprecated `strictnessLevel`,
202+
strip the macOS `-NSDocumentRevisionsDebugMode YES` flag, and insert an
203+
implicit `--validate` when the last argument is a bare plugin path.
204+
2. **Environment layer.** Env-var names are *derived* from the registered
205+
options (`--strictness-level``STRICTNESS_LEVEL`), so there is no separate
206+
env table. A synthetic `--name=value` argv is built from the environment and
207+
parsed by CLI11, reusing all its coercion.
208+
3. **`--config` layer.** Repeatable; each JSON file is `merge_patch`-ed in
209+
command-line order (later files win per key). Beats the environment.
210+
4. **CLI layer.** The real arguments are parsed last and beat everything;
211+
CLI11 only overwrites a member when its option was actually provided.
212+
213+
`configureApp()` registers every option (bound to the struct) and is used for
214+
both the env pass and the CLI pass. Comma lists use `->delimiter(',')`, the enum
215+
uses a `CheckedTransformer`, and the hex/int seed is a small callback.
216+
`PluginvalSettings::toPluginTestOptions()` converts to the JUCE-flavoured
217+
`PluginTests::Options` at the boundary.
218+
219+
Adding a new option is three edits: a struct member, an entry in the nlohmann
220+
macro list, and one `add_option(...)` line — its environment variable then works
221+
automatically. `SettingsSerializer` handles JSON load/save plus the two
222+
remaining conversions (hex seed, disabled-tests file).
223+
224+
The child validation process receives a fully-resolved, **authoritative**
225+
settings set via a base64-encoded JSON argument (`--config-base64`), avoiding
226+
per-flag re-serialisation and command-line quoting hazards. `--help`/`--version`
227+
are handled by CLI11 (auto usage + a footer with the env-var/commands notes).
228+
191229
### Test Framework
192230

193231
Tests are self-registering. To find all tests, look for static instances:
@@ -327,9 +365,9 @@ Basic usage:
327365

328366
Key options:
329367
- `--validate [path]` - Validate plugin at path
368+
- `--config [file.json]` - Load a full settings set from JSON (overridden by env vars and CLI options)
330369
- `--strictness-level [1-10]` - Test thoroughness (default: 5)
331370
- `--skip-gui-tests` - Skip GUI tests (for headless CI)
332-
- `--validate-in-process` - Don't use child process (for debugging)
333371
- `--timeout-ms [ms]` - Test timeout (default: 30000, -1 for none)
334372
- `--verbose` - Enable verbose logging
335373
- `--output-dir [dir]` - Directory for log files
@@ -374,6 +412,8 @@ add_pluginval_tests(MyPluginTarget
374412
### External
375413
- **JUCE** (v8.0.x) - Audio application framework (git submodule)
376414
- **magic_enum** (v0.9.7) - Enum reflection (fetched via CPM)
415+
- **CLI11** (v2.6.2) - CLI argument parsing, header-only (fetched via CPM)
416+
- **nlohmann/json** (3.12.0) - JSON settings layering/serialisation (fetched via CPM)
377417
- **rtcheck** (optional, macOS) - Real-time safety checking (fetched via CPM)
378418
- **VST3 SDK** (v3.7.x) - Steinberg VST3 SDK for embedded validator (fetched via CPM, optional)
379419
@@ -439,6 +479,6 @@ Run internal tests via CLI:
439479

440480
- Always test changes on multiple platforms when possible
441481
- VST3 plugins have specific threading requirements - use the `*OnMessageThreadIfVST3` helpers
442-
- Child process validation is the default and recommended for production use
443-
- In-process validation (`--validate-in-process`) is useful for debugging but a crashing plugin will crash pluginval
482+
- The GUI runs each validation in a separate child process for crash isolation (the default)
483+
- The CLI `--validate` path runs in-process; a crashing plugin will terminate pluginval, and the signal handler reports it as a failure rather than a pass
444484
- Real-time safety checking is only available on macOS currently (uses rtcheck library)

CMakeLists.txt

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,8 @@ option(JUCE_ENABLE_MODULE_SOURCE_GROUPS "Enable Module Source Groups" ON)
6161

6262
include(cmake/CPM.cmake)
6363
CPMAddPackage("gh:Neargye/magic_enum#v0.9.7")
64+
CPMAddPackage("gh:CLIUtils/CLI11@2.6.2")
65+
CPMAddPackage("gh:nlohmann/json@3.12.0")
6466

6567
if(PLUGINVAL_ENABLE_RTCHECK)
6668
CPMAddPackage("gh:Tracktion/rtcheck#main")
@@ -120,16 +122,23 @@ set(SourceFiles
120122
Source/CrashHandler.h
121123
Source/MainComponent.h
122124
Source/PluginTests.h
125+
Source/PluginvalSettings.h
126+
Source/SettingsParser.h
127+
Source/SettingsSerializer.h
123128
Source/TestUtilities.h
124129
Source/Validator.h
125130
Source/CommandLine.cpp
126131
Source/CrashHandler.cpp
127132
Source/Main.cpp
128133
Source/MainComponent.cpp
129134
Source/PluginTests.cpp
135+
Source/SettingsParser.cpp
136+
Source/SettingsSerializer.cpp
130137
Source/tests/BasicTests.cpp
131138
Source/tests/LocaleTest.cpp
132139
Source/tests/BusTests.cpp
140+
Source/tests/EditorTests.cpp
141+
Source/tests/ExtremeTests.cpp
133142
Source/tests/ParameterFuzzTests.cpp
134143
Source/TestUtilities.cpp
135144
Source/Validator.cpp)
@@ -176,7 +185,9 @@ target_link_libraries(pluginval PRIVATE
176185
juce::juce_audio_processors
177186
juce::juce_audio_utils
178187
juce::juce_recommended_warning_flags
179-
magic_enum)
188+
magic_enum
189+
CLI11::CLI11
190+
nlohmann_json::nlohmann_json)
180191

181192
if (${CMAKE_SYSTEM_NAME} MATCHES "Linux")
182193
target_link_libraries(pluginval PRIVATE

SUBCOMMANDS_HANDOFF.md

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
# HANDOFF: Restructure pluginval's CLI into subcommands
2+
3+
## Goal
4+
Turn the current "mode" flags into proper subcommands, each with its own
5+
argument set, while keeping the old flat flags working as **deprecated aliases
6+
for one release**:
7+
8+
| New (target) | Old (keep as deprecated alias) |
9+
|---|---|
10+
| `pluginval validate [options] <plugin>` (the **default**) | `pluginval --validate <plugin>` / `pluginval <plugin>` |
11+
| `pluginval run-tests` | `pluginval --run-tests` |
12+
| `pluginval strictness-help [level]` | `pluginval --strictness-help [level]` |
13+
| `pluginval --version` / `pluginval --help` | (unchanged) |
14+
15+
All settings options (`--strictness-level`, `--config`, `--rtcheck`, …),
16+
environment variables, and the JSON precedence pipeline belong to the `validate`
17+
subcommand and are otherwise unchanged.
18+
19+
This was deliberately deferred from the CLI11 refactor PR (#174). The pipeline
20+
and `PluginvalSettings` were designed to be reused unchanged.
21+
22+
## Read these first (don't trust this summary — verify against the files)
23+
- `Source/SettingsParser.cpp/.h` — the parser. Key pieces to reuse:
24+
- `preprocess()` — deprecation rewrite, macOS flag strip, implicit `--validate`, tokenise.
25+
- `parseTokens(tokens, env)` — env → `--config` → CLI layering into one `PluginvalSettings`. **This is the `validate` body.**
26+
- `configureApp(app, s)` — registers every option on a `CLI::App`, used for both the env and CLI passes.
27+
- `createChildProcessCommandLine()` — the parent→child base64 handoff (`--config-base64 <b64> --validate <path>`).
28+
- `isCommandLine(tokens)` — what makes `shouldPerformCommandLine` return true.
29+
- `Source/CommandLine.cpp``performCommandLine()` is the dispatcher today:
30+
token-scans for `--run-tests` / `--strictness-help`, otherwise runs `parseTokens` for validate; `--help`/`--version` go through CLI11. Also `runUnitTests()`, `printStrictnessHelp()`.
31+
- `Source/Main.cpp` — calls `shouldPerformCommandLine()` then `performCommandLine()` with `getCommandLineParameters()` (a single `juce::String`).
32+
- `Source/CommandLineTests.cpp` — the test contract.
33+
34+
## Recommended approach: a thin `argv[1]` verb dispatcher (not CLI11 subcommands)
35+
The existing `parseTokens` pipeline (env/config/CLI layering via two `CLI::App`
36+
passes) is the hard part and already works. Rather than re-express it inside
37+
CLI11's native `add_subcommand` machinery (which complicates the env/config
38+
layering because the options live on the subcommand), peel the verb off the
39+
front and route:
40+
41+
1. In a new `dispatch()` step (in `SettingsParser` or `CommandLine.cpp`):
42+
- Tokenise the command line (reuse `preprocess` minus the implicit-validate step, or add a pre-step).
43+
- Look at the first non-option token:
44+
- `validate` → strip it, run the existing validate pipeline on the rest.
45+
- `run-tests``runUnitTests()`.
46+
- `strictness-help``printStrictnessHelp(level)`.
47+
- otherwise → **default to validate** (this preserves `pluginval <plugin>` and `pluginval --strictness-level 5 <plugin>`).
48+
2. Each verb keeps its own small set of expected args. `validate` reuses
49+
`configureApp`/`parseTokens` verbatim. `run-tests` takes none.
50+
`strictness-help` takes an optional level.
51+
52+
This keeps `parseTokens` and the precedence layering untouched — the subcommand
53+
work is purely a routing layer in front of it.
54+
55+
(If you prefer CLI11-native subcommands instead: put `configureApp` options on a
56+
`validate` subcommand, and make `buildEnvArgv`/the env pass target that
57+
subcommand's options. Doable, but more invasive for no functional gain here.)
58+
59+
## Deprecated-alias behaviour (one release)
60+
Keep the old flat forms working, but print a one-line notice to stderr pointing
61+
at the new syntax, e.g.:
62+
- `pluginval --validate x` → run validate; warn `"--validate is deprecated; use 'pluginval validate x'"`.
63+
- `pluginval --run-tests` → warn `"use 'pluginval run-tests'"`.
64+
- `pluginval --strictness-help` → warn `"use 'pluginval strictness-help'"`.
65+
- `pluginval <plugin>` (bare path) → **no warning** (still the documented shorthand for `validate`).
66+
67+
Gate the warnings behind detection of the old flag so the new subcommand form is
68+
silent. Remove the aliases in the release after next; note it in `CHANGELIST.md`.
69+
70+
## Files to touch
71+
- `Source/SettingsParser.{h,cpp}` — add the verb dispatch + a `Command` result (validate/run-tests/strictness-help/help/version), or expose a `dispatch()` that returns which verb + the remaining tokens. Keep `parseTokens` as the validate body.
72+
- `Source/CommandLine.cpp``performCommandLine()` routes on the verb; emit the deprecation notices for old flat flags. `shouldPerformCommandLine()` must also recognise the bare verbs (`validate`/`run-tests`/`strictness-help`) in addition to the old flags.
73+
- `Source/CommandLineTests.cpp` — add tests: each subcommand; default-to-validate; bare-path shorthand; every deprecated alias still works (and warns); `run-tests`/`strictness-help` arg handling.
74+
- `docs/Command line options.md` — regenerate (`pluginval --help`); CLI11 can show per-subcommand help if you go native, otherwise hand-format the verb list.
75+
- `CHANGELIST.md` — note the subcommand syntax + the deprecation.
76+
- `CLAUDE.md` — update the "CLI Settings Pipeline" section to mention the verb layer.
77+
78+
## Gotchas / decisions to make
79+
- **Child-process handoff.** `createChildProcessCommandLine()` emits `--config-base64 <b64> --validate <path>`. Decide whether the child invocation becomes `validate --config-base64 …` or stays flat. Simplest: keep it flat and have the dispatcher treat a leading `--config-base64`/`--validate` as the (deprecated, unwarned-for-internal) validate path. Note `--config-base64` is now hardened to reject being combined with non-`--validate` options — keep that working under whichever form you choose.
80+
- **`shouldPerformCommandLine`** is what flips pluginval into CLI (vs GUI) mode in `Main.cpp`. It must return true for `pluginval run-tests` etc., not just the old flags.
81+
- **`--help` scope.** With the dispatcher, `pluginval --help` is the top-level help (list verbs + the validate options). Consider `pluginval validate --help` for the full option list. CLI11-native subcommands give this for free.
82+
- **Implicit validate** currently lives in `preprocess`. With an explicit `validate` verb, make sure `pluginval <plugin>` (no verb) still resolves to validate, and `pluginval validate <plugin>` doesn't double-insert `--validate`.
83+
- **Reconcile** a positional plugin path under `validate` (e.g. `pluginval validate <plugin>`) with the existing `--validate <plugin>` option — pick one canonical form (recommend the positional for the new syntax, mapping it onto `s.validatePath`).
84+
85+
## Verify
86+
- `pluginval run-tests` passes the full unit suite (it must, it's how CI runs tests).
87+
- `pluginval validate --strictness-level 10 <plugin>` and `pluginval <plugin>` both validate.
88+
- Every deprecated alias produces identical behaviour to before (plus a notice).
89+
- CI matrix green (Linux/macOS/Windows build + dependency). Remember `.github/workflows/build.yaml` uses `--run-tests` and `--strictness-level 10 --validate …`; update those to the new syntax **and** keep an alias test, or the deprecation will fire in CI.

0 commit comments

Comments
 (0)