From 28de7b25f61c13ef9f2bf6609e937d3b93565d87 Mon Sep 17 00:00:00 2001 From: David Rowland Date: Sun, 7 Jun 2026 17:26:11 +0100 Subject: [PATCH] v2: `Restructure CLI into validate/run-tests/strictness-help subcommands, keeping flat flags as deprecated aliases` --- .github/workflows/build.yaml | 10 +-- CHANGELIST.md | 2 + CLAUDE.md | 46 +++++++++++-- CMakeLists.txt | 3 +- Source/CommandLine.cpp | 33 ++++++---- Source/CommandLineTests.cpp | 106 ++++++++++++++++++++++++++++++ Source/SettingsParser.cpp | 116 +++++++++++++++++++++++++++++++-- Source/SettingsParser.h | 47 +++++++++++-- docs/Adding pluginval to CI.md | 6 +- docs/Command line options.md | 25 ++++--- tests/AddPluginvalTests.cmake | 3 +- tests/windows_tests.bat | 4 +- 12 files changed, 351 insertions(+), 50 deletions(-) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index fa5d16df..02725283 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -104,7 +104,7 @@ jobs: run: | pwd ls -ahl - ${{ matrix.test-binary }} --run-tests + ${{ matrix.test-binary }} run-tests - name: Cache JUCE example plugin binaries id: cache-plugins @@ -127,9 +127,9 @@ jobs: - name: Validate JUCE Plugin examples (VST3) shell: bash run: | - # Paths must be single quoted for bash not to escape the Windows backslash character \ used in absolute paths - ${{ env.APP_DIR }}/${{ matrix.test-binary }} --strictness-level 10 --validate '${{ env.PLUGIN_CACHE_PATH }}/DSPModulePluginDemo_artefacts/Release/VST3/DSPModulePluginDemo.vst3' - ${{ env.APP_DIR }}/${{ matrix.test-binary }} --strictness-level 10 --validate '${{ env.PLUGIN_CACHE_PATH }}/MultiOutSynthPlugin_artefacts/Release/VST3/MultiOutSynthPlugin.vst3' + # Paths must be single quoted for bash not to escape the Windows backslash character \ used in absolute paths + ${{ env.APP_DIR }}/${{ matrix.test-binary }} validate --strictness-level 10 '${{ env.PLUGIN_CACHE_PATH }}/DSPModulePluginDemo_artefacts/Release/VST3/DSPModulePluginDemo.vst3' + ${{ env.APP_DIR }}/${{ matrix.test-binary }} validate --strictness-level 10 '${{ env.PLUGIN_CACHE_PATH }}/MultiOutSynthPlugin_artefacts/Release/VST3/MultiOutSynthPlugin.vst3' - name: Validate JUCE Plugin examples (AU) shell: bash @@ -141,6 +141,8 @@ jobs: mkdir -p ~/Library/Audio/Plug-Ins/Components/ cp -R ${{ env.PLUGIN_CACHE_PATH }}/DSPModulePluginDemo_artefacts/Release/AU/DSPModulePluginDemo.component ~/Library/Audio/Plug-Ins/Components/ killall -9 AudioComponentRegistrar # kick the AU registrar + # Intentionally uses the deprecated "--validate" flat flag to keep the + # backwards-compatible alias covered (this step is continue-on-error). ${{ env.APP_DIR }}/${{ matrix.test-binary }} --strictness-level 10 --validate ~/Library/Audio/Plug-Ins/Components/DSPModulePluginDemo.component - name: Codesign (macOS) diff --git a/CHANGELIST.md b/CHANGELIST.md index 5e5140b5..6afdf839 100644 --- a/CHANGELIST.md +++ b/CHANGELIST.md @@ -1,6 +1,8 @@ # pluginval Change List ### 2.0.0 +- Restructured the command line into subcommands: `pluginval validate [options] ` (the default), `pluginval run-tests` and `pluginval strictness-help [level]`. The plugin path is now a positional argument of `validate` +- **Deprecated:** the flat flags `--validate `, `--run-tests` and `--strictness-help [level]` still work as aliases (with a one-line notice) but will be removed in a future version. `pluginval ` remains a silent shorthand for `validate` - Replaced the hand-rolled command-line parser with CLI11 and a single JSON-based settings pipeline - Added `--config ` to load settings from JSON (repeatable; later files win per key) - Settings precedence is now (lowest to highest): defaults, environment variables, `--config`, command-line options diff --git a/CLAUDE.md b/CLAUDE.md index 4acbea1c..97aa0061 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -193,6 +193,38 @@ VST2_SDK_DIR=/path/to/vst2sdk cmake -B Builds/Debug . ### CLI Settings Pipeline +#### Subcommand dispatch layer + +The command line is structured into subcommands, peeled off by a thin verb +dispatcher in front of the settings pipeline (it does **not** use CLI11-native +subcommands, so the env/config/CLI layering below is untouched): + +- `pluginval validate [options] ` — the default; `` is a + positional argument. `pluginval ` and `pluginval [options] ` + (no verb) also resolve to validate. +- `pluginval run-tests` — runs the internal unit tests. +- `pluginval strictness-help [level]` — lists tests at a strictness level. + +`settings_parser::dispatch()` (in `SettingsParser.cpp`) takes the `tokenise()`d +command line and returns a `DispatchResult { command, validateTokens, +deprecatedAlias, strictnessLevel }`. For `validate` it strips the verb and hands +`validateTokens` to `parseTokens` unchanged. `CommandLine.cpp`'s +`performCommandLine()` switches on `command` and emits a one-line stderr notice +when `deprecatedAlias` is set. + +The old flat flags (`--validate `, `--run-tests`, `--strictness-help`) +are kept as **deprecated aliases** that route to the same commands with +`deprecatedAlias = true` (the bare-path shorthand and the internal child handoff +stay silent). `preprocess()` is now `tokenise()` + `insertImplicitValidate()`. +The child process is launched with the explicit verb: +`validate --config-base64 `. + +Note: `--config` is parsed manually (it is stripped from the tokens fed to the +CLI11 pass) so its greedy CLI11 vector parsing can't swallow the positional +plugin path; it stays registered only so it appears in `--help`. + +#### Settings layering + Command-line parsing centres on one plain settings struct (`PluginvalSettings`) that CLI11 binds to directly. A single instance is filled by successive layers, **lowest to highest precedence: defaults → environment → `--config` → CLI** @@ -360,11 +392,17 @@ ut.logVerboseMessage("Detail message"); // Only with --verbose flag Basic usage: ```bash -./pluginval --strictness-level 5 /path/to/plugin.vst3 +./pluginval validate --strictness-level 5 /path/to/plugin.vst3 ``` -Key options: -- `--validate [path]` - Validate plugin at path +Commands: +- `validate [options] ` - Validate the plugin at the given path/AU id (the default; `./pluginval ` also works) +- `run-tests` - Run the internal unit tests +- `strictness-help [level]` - List the tests that run at a strictness level + +The flat flags `--validate `, `--run-tests` and `--strictness-help [level]` are deprecated aliases. + +Key options (for `validate`): - `--config [file.json]` - Load a full settings set from JSON (overridden by env vars and CLI options) - `--strictness-level [1-10]` - Test thoroughness (default: 5) - `--skip-gui-tests` - Skip GUI tests (for headless CI) @@ -434,7 +472,7 @@ Debug unit tests run automatically in debug builds: Run internal tests via CLI: ```bash -./pluginval --run-tests +./pluginval run-tests ``` ## Release Process diff --git a/CMakeLists.txt b/CMakeLists.txt index 20e02b69..4a7eab78 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -250,8 +250,9 @@ else() # TODO: This doesn't populate the executable in clion add_custom_target(${CMAKE_PROJECT_NAME}_pluginval_cli COMMAND $ - --validate ${artefact} + validate --strictness-level 10 + ${artefact} DEPENDS pluginval ${PLUGINVAL_TARGET} COMMENT "Run pluginval CLI with strict validation") endif() diff --git a/Source/CommandLine.cpp b/Source/CommandLine.cpp index f152d274..282c9b50 100644 --- a/Source/CommandLine.cpp +++ b/Source/CommandLine.cpp @@ -203,38 +203,47 @@ juce::StringArray createCommandLine (juce::String fileOrID, PluginTests::Options } //============================================================================== +static void warnDeprecated (const juce::String& oldForm, const juce::String& newForm) +{ + std::cerr << "!!! WARNING: " << oldForm << " is deprecated; use '" << newForm + << "' instead. It will be removed in a future version." << std::endl; +} + void performCommandLine (CommandLineValidator& validator, const juce::String& commandLine) { hideDockIcon(); auto& app = *juce::JUCEApplication::getInstance(); - const auto tokens = settings_parser::preprocess (commandLine); + const auto routed = settings_parser::dispatch (settings_parser::tokenise (commandLine)); - if (tokens.contains ("--run-tests")) + if (routed.command == settings_parser::Command::runTests) { + if (routed.deprecatedAlias) + warnDeprecated ("--run-tests", "pluginval run-tests"); + runUnitTests(); app.quit(); return; } - if (tokens.contains ("--strictness-help")) + if (routed.command == settings_parser::Command::strictnessHelp) { - int level = 5; - - if (const auto idx = tokens.indexOf ("--strictness-help"); idx >= 0 && idx + 1 < tokens.size()) - if (const auto next = tokens[idx + 1]; ! next.startsWith ("-")) - level = next.getIntValue(); + if (routed.deprecatedAlias) + warnDeprecated ("--strictness-help", "pluginval strictness-help"); - printStrictnessHelp (level); + printStrictnessHelp (routed.strictnessLevel); app.quit(); return; } - // Otherwise this is a validation run (explicit or implicit --validate). - // CLI11 handles --help/--version and parse errors. + // Otherwise this is a validation run (positional plugin, or explicit/implicit + // --validate). CLI11 handles --help/--version and parse errors. + if (routed.deprecatedAlias) + warnDeprecated ("--validate", "pluginval validate "); + try { - const auto result = settings_parser::parseTokens (tokens); + const auto result = settings_parser::parseTokens (routed.validateTokens); if (result.handled) { diff --git a/Source/CommandLineTests.cpp b/Source/CommandLineTests.cpp index e537a296..b19a8106 100644 --- a/Source/CommandLineTests.cpp +++ b/Source/CommandLineTests.cpp @@ -331,6 +331,112 @@ struct CommandLineTests : public juce::UnitTest expectEquals (r.exitCode, 1); } } + + beginTest ("Subcommand: validate with a positional plugin path"); + { + const auto currentDir = juce::File::getCurrentWorkingDirectory(); + + // Plugin path as a positional after the verb. + expectEquals (juce::String (parse ("validate MyPlugin.vst3").validatePath), + currentDir.getChildFile ("MyPlugin.vst3").getFullPathName()); + + // Options before the positional plugin path. + const auto s = parse ("validate --strictness-level 8 MyPlugin.vst3"); + expectEquals (s.strictnessLevel, 8); + expectEquals (juce::String (s.validatePath), currentDir.getChildFile ("MyPlugin.vst3").getFullPathName()); + + // A bare AU component id positional is left untouched. + expectEquals (juce::String (parse ("validate MyPluginID").validatePath), juce::String ("MyPluginID")); + } + + beginTest ("Subcommand: validate with --config before the positional plugin"); + { + juce::TemporaryFile configFile (".json"); + configFile.getFile().replaceWithText (R"({ "strictnessLevel": 2 })"); + + const auto currentDir = juce::File::getCurrentWorkingDirectory(); + const auto cmd = "validate --config " + configFile.getFile().getFullPathName().quoted() + " MyPlugin.vst3"; + + const auto s = parse (cmd); + expectEquals (s.strictnessLevel, 2); // --config didn't swallow the plugin path + expectEquals (juce::String (s.validatePath), currentDir.getChildFile ("MyPlugin.vst3").getFullPathName()); + } + + beginTest ("Subcommand dispatch routing (new verbs do not warn)"); + { + using settings_parser::Command; + + { + const auto d = settings_parser::dispatch (settings_parser::tokenise ("run-tests")); + expect (d.command == Command::runTests); + expect (! d.deprecatedAlias); + } + { + const auto d = settings_parser::dispatch (settings_parser::tokenise ("strictness-help 7")); + expect (d.command == Command::strictnessHelp); + expectEquals (d.strictnessLevel, 7); + expect (! d.deprecatedAlias); + } + { + const auto d = settings_parser::dispatch (settings_parser::tokenise ("strictness-help")); + expect (d.command == Command::strictnessHelp); + expectEquals (d.strictnessLevel, 5); // default level + } + { + const auto d = settings_parser::dispatch (settings_parser::tokenise ("validate MyPlugin.vst3")); + expect (d.command == Command::validate); + expect (! d.deprecatedAlias); + } + } + + beginTest ("Deprecated flat flags still route, flagged as deprecated"); + { + using settings_parser::Command; + + { + const auto d = settings_parser::dispatch (settings_parser::tokenise ("--run-tests")); + expect (d.command == Command::runTests); + expect (d.deprecatedAlias); + } + { + const auto d = settings_parser::dispatch (settings_parser::tokenise ("--strictness-help 9")); + expect (d.command == Command::strictnessHelp); + expectEquals (d.strictnessLevel, 9); + expect (d.deprecatedAlias); + } + { + const auto d = settings_parser::dispatch (settings_parser::tokenise ("--validate x")); + expect (d.command == Command::validate); + expect (d.deprecatedAlias); + } + } + + beginTest ("Bare-path shorthand and child handoff do not warn"); + { + juce::TemporaryFile temp ("path_to_file.vst3"); + expect (temp.getFile().create()); + + // Bare plugin path -> validate, no deprecation warning. + const auto bare = settings_parser::dispatch (settings_parser::tokenise (temp.getFile().getFullPathName())); + expect (bare.command == settings_parser::Command::validate); + expect (! bare.deprecatedAlias); + + // The internal child handoff uses the explicit verb -> no warning. + PluginTests::Options opts; + juce::StringArray childArgs (createCommandLine ("/some/MyPlugin.vst3", opts)); + childArgs.remove (0); // drop the executable path + const auto child = settings_parser::dispatch (childArgs); + expect (child.command == settings_parser::Command::validate); + expect (! child.deprecatedAlias); + } + + beginTest ("Should perform command line recognises subcommands"); + { + expect (shouldPerformCommandLine ("run-tests")); + expect (shouldPerformCommandLine ("strictness-help")); + expect (shouldPerformCommandLine ("validate MyPlugin.vst3")); + expect (shouldPerformCommandLine ("validate MyPluginID")); + } } }; diff --git a/Source/SettingsParser.cpp b/Source/SettingsParser.cpp index 244286aa..e93cb76e 100644 --- a/Source/SettingsParser.cpp +++ b/Source/SettingsParser.cpp @@ -126,9 +126,13 @@ namespace settings_parser juce::String getFooterText() { return juce::SystemStats::getJUCEVersion() + "\n\n" + juce::String ( -R"(Other commands: - --run-tests Run the internal unit tests. - --strictness-help [level] List all tests that run at the given strictness level. +R"(Commands: + validate [options] Validate the plugin at the given path or AU id (the default). + run-tests Run the internal unit tests. + strictness-help [level] List all tests that run at the given strictness level. + +The flat flags --validate , --run-tests and --strictness-help [level] are +deprecated aliases for the commands above and will be removed in a future version. Exit code: 0 if all tests complete successfully @@ -172,6 +176,9 @@ Precedence (lowest to highest): defaults, environment variables, --config, comma "Path to a JSON settings file. Repeatable; later files win per key.")->take_all(); app.add_option ("--validate", s.validatePath, "Validates the plugin at the given path (or AU id)."); + // The new canonical form: "pluginval validate ". Bound to the + // same member as --validate; whichever is supplied sets the path. + app.add_option ("plugin", s.validatePath, "Plugin path or AU id to validate."); app.add_option ("--strictness-level", s.strictnessLevel, "Strictness level 1-10 (default 5)."); app.add_option ("--timeout-ms", s.timeoutMs, "Test timeout in ms (default 30000, -1 to never timeout)."); app.add_option ("--repeat", s.numRepeats, "Number of times to repeat the tests."); @@ -254,7 +261,7 @@ Precedence (lowest to highest): defaults, environment variables, --config, comma } //============================================================================== - juce::StringArray preprocess (const juce::String& commandLineIn) + juce::StringArray tokenise (const juce::String& commandLineIn) { if (commandLineIn.contains ("strictnessLevel")) { @@ -273,6 +280,11 @@ Precedence (lowest to highest): defaults, environment variables, --config, comma for (auto& s : args) s = s.unquoted(); + return args; + } + + void insertImplicitValidate (juce::StringArray& args) + { // If only a plugin path is supplied as the last arg, add an implicit // --validate option for it so the rest of the CLI works. if (args.size() > 0) @@ -286,12 +298,25 @@ Precedence (lowest to highest): defaults, environment variables, --config, comma if (! hasCommand && isPluginArgument (args[args.size() - 1])) args.insert (args.size() - 1, "--validate"); } + } + juce::StringArray preprocess (const juce::String& commandLine) + { + auto args = tokenise (commandLine); + insertImplicitValidate (args); return args; } bool isCommandLine (const juce::StringArray& tokens) { + if (! tokens.isEmpty()) + { + const auto& verb = tokens.getReference (0); + + if (verb == "validate" || verb == "run-tests" || verb == "strictness-help") + return true; + } + return tokens.contains ("--help") || tokens.contains ("-h") || tokens.contains ("--version") || hasOption (tokens, "--validate") @@ -300,6 +325,73 @@ Precedence (lowest to highest): defaults, environment variables, --config, comma || hasOption (tokens, "--config-base64"); } + //============================================================================== + DispatchResult dispatch (const juce::StringArray& tokensIn) + { + DispatchResult result; + + // The optional [level] argument that follows the strictness-help command/flag. + const auto levelAfter = [] (const juce::StringArray& tokens, int idx) + { + if (idx >= 0 && idx + 1 < tokens.size()) + if (const auto& next = tokens.getReference (idx + 1); ! next.startsWith ("-")) + return juce::jlimit (1, 10, next.getIntValue()); + + return 5; + }; + + // 1. Explicit subcommand verbs (the new, non-deprecated syntax). + if (! tokensIn.isEmpty()) + { + const auto& verb = tokensIn.getReference (0); + + if (verb == "validate") + { + result.command = Command::validate; + result.validateTokens = tokensIn; + result.validateTokens.remove (0); // the plugin path is captured by the positional CLI option + return result; + } + + if (verb == "run-tests") + { + result.command = Command::runTests; + return result; + } + + if (verb == "strictness-help") + { + result.command = Command::strictnessHelp; + result.strictnessLevel = levelAfter (tokensIn, 0); + return result; + } + } + + // 2. Deprecated flat command flags. + if (tokensIn.contains ("--run-tests")) + { + result.command = Command::runTests; + result.deprecatedAlias = true; + return result; + } + + if (tokensIn.contains ("--strictness-help")) + { + result.command = Command::strictnessHelp; + result.deprecatedAlias = true; + result.strictnessLevel = levelAfter (tokensIn, tokensIn.indexOf ("--strictness-help")); + return result; + } + + // 3. Default: validate. An explicit --validate flag (but not the bare-path + // shorthand, nor the internal --config-base64 handoff) is a deprecated alias. + result.command = Command::validate; + result.deprecatedAlias = hasOption (tokensIn, "--validate") && ! hasOption (tokensIn, "--config-base64"); + result.validateTokens = tokensIn; + insertImplicitValidate (result.validateTokens); + return result; + } + juce::String resolvePluginPath (const juce::String& raw) { // Resolve relative/home paths against the working directory. Absolute @@ -375,8 +467,18 @@ Precedence (lowest to highest): defaults, environment variables, --config, comma std::vector argv { "pluginval" }; - for (const auto& t : tokens) + // --config is handled manually above; drop it (and its value) here so + // its greedy CLI11 vector parsing can't swallow the positional plugin + // path. It stays registered purely so it appears in --help. + for (int i = 0; i < tokens.size(); ++i) + { + const auto& t = tokens.getReference (i); + + if (t == "--config") { ++i; continue; } // skip the flag and its value + if (t.startsWith ("--config=")) continue; // skip the inline form + argv.push_back (t.toStdString()); + } if (const auto code = runParse (cliApp, argv); code) { @@ -392,7 +494,7 @@ Precedence (lowest to highest): defaults, environment variables, --config, comma PluginvalSettings parse (const juce::String& commandLine, const EnvProvider& env) { - return parseTokens (preprocess (commandLine), env).settings; + return parseTokens (dispatch (tokenise (commandLine)).validateTokens, env).settings; } //============================================================================== @@ -403,7 +505,7 @@ Precedence (lowest to highest): defaults, environment variables, --config, comma const auto b64 = juce::Base64::toBase64 (juce::String (jsonString)); juce::StringArray args (juce::File::getSpecialLocation (juce::File::currentExecutableFile).getFullPathName()); - args.addArray ({ "--config-base64", b64, "--validate", fileOrID }); + args.addArray ({ "validate", "--config-base64", b64, fileOrID }); return args; } } diff --git a/Source/SettingsParser.h b/Source/SettingsParser.h index 3cd6ebc6..15089faa 100644 --- a/Source/SettingsParser.h +++ b/Source/SettingsParser.h @@ -38,14 +38,24 @@ namespace settings_parser juce::String systemEnv (const juce::String& name); //============================================================================== - /** Tokenises + preprocesses a raw command line: rewrites the deprecated - "strictnessLevel", strips the macOS "-NSDocumentRevisionsDebugMode YES" - flag, and inserts an implicit "--validate" when the last argument is a - bare plugin path. Returns argv tokens (without the program name). + /** Tokenises a raw command line: rewrites the deprecated "strictnessLevel", + strips the macOS "-NSDocumentRevisionsDebugMode YES" flag, splits and + unquotes. Returns argv tokens (without the program name) exactly as the + user typed them - it does NOT insert an implicit "--validate". */ + juce::StringArray tokenise (const juce::String& commandLine); + + /** Inserts an implicit "--validate" when the last token is a bare plugin path + (and no command is already present). This is the documented shorthand for + "pluginval ". + */ + void insertImplicitValidate (juce::StringArray& tokens); + + /** Convenience: tokenise + insertImplicitValidate. */ juce::StringArray preprocess (const juce::String& commandLine); - /** True if the tokens contain a recognised command that triggers CLI mode. */ + /** True if the tokens contain a recognised command (subcommand verb or legacy + flag) that triggers CLI mode. */ bool isCommandLine (const juce::StringArray& tokens); /** Resolves a relative/home plugin path against the working directory, @@ -53,6 +63,31 @@ namespace settings_parser */ juce::String resolvePluginPath (const juce::String& raw); + //============================================================================== + /** The subcommand selected on the command line. */ + enum class Command + { + validate, /**< Validate a plugin (the default when no verb is given). */ + runTests, /**< Run the internal unit tests. */ + strictnessHelp /**< List the tests that run at a given strictness level. */ + }; + + /** The outcome of routing tokens to a subcommand. */ + struct DispatchResult + { + Command command = Command::validate; + juce::StringArray validateTokens; /**< Verb-stripped option tokens to feed parseTokens (validate only). */ + bool deprecatedAlias = false; /**< A legacy flat flag (--validate/--run-tests/--strictness-help) was used. */ + int strictnessLevel = 5; /**< The level for the strictnessHelp command. */ + }; + + /** Routes tokenised input to a subcommand, peeling the leading verb. The + validate token-layering in parseTokens is left untouched; the plugin path + is captured by a positional CLI option there. Legacy flat flags map onto + the matching command with deprecatedAlias set. + */ + DispatchResult dispatch (const juce::StringArray& tokens); + //============================================================================== /** The outcome of parsing the option tokens. */ struct ParseResult @@ -70,7 +105,7 @@ namespace settings_parser //============================================================================== /** Serialises options for the child validation process as a base64 JSON - handoff: { exe, --config-base64 , --validate }. + handoff: { exe, validate, --config-base64 , }. */ juce::StringArray createChildProcessCommandLine (const juce::String& fileOrID, const PluginTests::Options&); diff --git a/docs/Adding pluginval to CI.md b/docs/Adding pluginval to CI.md index e7e96de7..3baa06b9 100644 --- a/docs/Adding pluginval to CI.md +++ b/docs/Adding pluginval to CI.md @@ -19,21 +19,21 @@ In these examples the following is assumed: ```sh $ curl -L "https://github.com/Tracktion/pluginval/releases/latest/download/pluginval_macOS.zip" -o pluginval.zip $ unzip pluginval -$ pluginval.app/Contents/MacOS/pluginval --validate-in-process --output-dir "./bin" "" || exit 1 +$ pluginval.app/Contents/MacOS/pluginval validate --output-dir "./bin" "" || exit 1 ``` ##### Linux ```sh $ curl -L "https://github.com/Tracktion/pluginval/releases/latest/download/pluginval_Linux.zip" -o pluginval.zip $ unzip pluginval -$ ./pluginval --validate-in-process --output-dir "./bin" "" || exit 1 +$ ./pluginval validate --output-dir "./bin" "" || exit 1 ``` ##### Windows ```sh > powershell -Command "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; Invoke-WebRequest https://github.com/Tracktion/pluginval/releases/latest/download/pluginval_Windows.zip -OutFile pluginval.zip" > powershell -Command "Expand-Archive pluginval.zip -DestinationPath ." -> pluginval.exe --validate-in-process --output-dir "./bin" "" +> pluginval.exe validate --output-dir "./bin" "" > if %ERRORLEVEL% neq 0 exit /b 1 ``` diff --git a/docs/Command line options.md b/docs/Command line options.md index 4c824692..d87244b8 100644 --- a/docs/Command line options.md +++ b/docs/Command line options.md @@ -2,10 +2,22 @@ Validate plugins to test compatibility with hosts and verify plugin API conformance -pluginval [OPTIONS] +pluginval [OPTIONS] [plugin] -OPTIONS: +COMMANDS: + validate [options] Validate the plugin at the given path or AU id. + This is the default, so "pluginval " and + "pluginval [options] " also work. + run-tests Run the internal unit tests. + strictness-help [level] List all tests that run at the given strictness level. + +The flat flags --validate , --run-tests and --strictness-help [level] +are deprecated aliases for the commands above and will be removed in a future +version. + + +OPTIONS (for the validate command): -h, --help Print this help message and exit --version Display program version information and exit --config TEXT ... Path to a JSON settings file. Repeatable; later files win per @@ -32,19 +44,12 @@ OPTIONS: --rtcheck ENUM:value in {disabled->0,enabled->1,relaxed->2} OR {0,1,2} Real-time safety checks: disabled, enabled or relaxed. -JUCE v8.0.13 - -Other commands: ---run-tests Run the internal unit tests. ---strictness-help [level] List all tests that run at the given strictness level. - Exit code: 0 if all tests complete successfully 1 if there are any errors You can also specify any option as an environment variable by removing the -prefix -dashes, converting internal dashes to underscores and capitalising, e.g. +prefix dashes, converting internal dashes to underscores and capitalising, e.g. "--skip-gui-tests" -> "SKIP_GUI_TESTS=1" "--timeout-ms 30000" -> "TIMEOUT_MS=30000" Precedence (lowest to highest): defaults, environment variables, --config, diff --git a/tests/AddPluginvalTests.cmake b/tests/AddPluginvalTests.cmake index c4850712..133a9775 100644 --- a/tests/AddPluginvalTests.cmake +++ b/tests/AddPluginvalTests.cmake @@ -81,13 +81,14 @@ function (add_pluginval_tests pluginTarget) add_test (NAME "${test_name}" COMMAND "${PLUGINVAL_PROGRAM}" + validate --strictness-level "${PLUGINVAL_STRICTNESS}" --sample-rates "${sample_rates}" --block-sizes "${block_sizes}" --repeat "${PLUGINVAL_REPEATS}" --randomise - --validate "${plugin_artefact}" ${log_dir_arg} + "${plugin_artefact}" ) set_tests_properties ( diff --git a/tests/windows_tests.bat b/tests/windows_tests.bat index 327d4766..e8ac04d7 100755 --- a/tests/windows_tests.bat +++ b/tests/windows_tests.bat @@ -64,11 +64,11 @@ exit /B %ERRORLEVEL% "%MSBUILD_EXE%" %PLUGIN_NAME%.sln /p:VisualStudioVersion=15.0 /m /t:Build /p:Configuration=Release /p:Platform=x64 /p:PreferredToolArchitecture=x64 /p:TreatWarningsAsErrors=true :: Test in process - call "%PLUGINVAL_EXE%" --validate-in-process --strictness-level 5 --validate %PLUGIN_VST3% + call "%PLUGINVAL_EXE%" validate --strictness-level 5 %PLUGIN_VST3% if %ERRORLEVEL% NEQ 0 exit 1 :: Test out of process - :: call "%PLUGINVAL_EXE%" --strictness-level 5 --validate %PLUGIN_VST3% + :: call "%PLUGINVAL_EXE%" validate --strictness-level 5 %PLUGIN_VST3% :: if %ERRORLEVEL% NEQ 0 exit 1 exit /B 0