presets: Factor out command line arguments

Create a separate hierarchy of classes to manage command-line arguments
for CMake presets to facilitate shared definitions across our programs.
diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt
index e7a0aef..a5910ef 100644
--- a/Source/CMakeLists.txt
+++ b/Source/CMakeLists.txt
@@ -125,6 +125,7 @@
   cmCLocaleEnvironmentScope.cxx
   cmCMakePath.h
   cmCMakePath.cxx
+  cmCMakePresetsArgs.h
   cmCMakePresetsErrors.cxx
   cmCMakePresetsErrors.h
   cmCMakePresetsGraph.cxx
diff --git a/Source/CPack/cpack.cxx b/Source/CPack/cpack.cxx
index a7ed74b..85bec08 100644
--- a/Source/CPack/cpack.cxx
+++ b/Source/CPack/cpack.cxx
@@ -19,6 +19,7 @@
 
 #include "cmsys/Encoding.hxx"
 
+#include "cmCMakePresetsArgs.h"
 #include "cmCMakePresetsGraph.h"
 #include "cmCPackGenerator.h"
 #include "cmCPackGeneratorFactory.h"
@@ -130,8 +131,7 @@
   std::string cpackProjectVendor;
   std::string cpackConfigFile;
 
-  std::string preset;
-  bool listPresets = false;
+  cmCMakePresetsArgs presetsArgs;
 
   std::map<std::string, std::string> definitions;
 
@@ -201,9 +201,9 @@
                      CommandArgument::setToValue(cpackProjectVendor) },
     CommandArgument{ "--preset", "No preset specified for --preset",
                      CommandArgument::Values::One,
-                     CommandArgument::setToValue(preset) },
+                     CommandArgument::setToValue(presetsArgs.PresetName) },
     CommandArgument{ "--list-presets", CommandArgument::Values::Zero,
-                     CommandArgument::setToTrue(listPresets) },
+                     CommandArgument::setToTrue(presetsArgs.ListPresets) },
     CommandArgument{ "-D", CommandArgument::Values::One,
                      CommandArgument::RequiresSeparator::No,
                      [&log, &definitions](std::string const& arg, cmake*,
@@ -249,7 +249,7 @@
   generators.SetLogger(&log);
 
   // Set up presets
-  if (!preset.empty() || listPresets) {
+  if (presetsArgs.HasPresetsArg()) {
     auto const workingDirectory = cmSystemTools::GetLogicalWorkingDirectory();
 
     auto const presetGeneratorsPresent =
@@ -271,13 +271,13 @@
       return 1;
     }
 
-    if (listPresets) {
+    if (presetsArgs.ListPresets) {
       presetsGraph.PrintPackagePresetList(presetGeneratorsPresent);
       return 0;
     }
 
-    auto resolveResult =
-      presetsGraph.ResolvePreset(preset, presetsGraph.PackagePresets);
+    auto resolveResult = presetsGraph.ResolvePreset(
+      presetsArgs.PresetName, presetsGraph.PackagePresets);
     auto resolveError = cmCMakePresetsGraph::FormatPresetError<
       cmCMakePresetsGraph::PackagePreset>(resolveResult.StatusCode,
                                           resolveResult.ErrorPresetName,
diff --git a/Source/cmCMakePresetsArgs.h b/Source/cmCMakePresetsArgs.h
new file mode 100644
index 0000000..e501eba
--- /dev/null
+++ b/Source/cmCMakePresetsArgs.h
@@ -0,0 +1,77 @@
+/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
+   file LICENSE.rst or https://cmake.org/licensing for details.  */
+#pragma once
+
+#include <string>
+
+class cmCMakePresetsArgsBase
+{
+public:
+  virtual ~cmCMakePresetsArgsBase() = default;
+
+  virtual bool HasPresetsArg() const { return !this->PresetName.empty(); };
+  virtual void Clear() { this->PresetName.clear(); }
+
+  std::string PresetName;
+
+protected:
+  cmCMakePresetsArgsBase() = default;
+};
+
+class cmCMakePresetsArgs : public cmCMakePresetsArgsBase
+{
+public:
+  bool HasPresetsArg() const override
+  {
+    return this->cmCMakePresetsArgsBase::HasPresetsArg() || this->ListPresets;
+  }
+
+  void Clear() override
+  {
+    this->cmCMakePresetsArgsBase::Clear();
+    this->ListPresets = false;
+  }
+
+  bool ListPresets = false;
+};
+
+class cmCMakePresetsConfigureArgs : public cmCMakePresetsArgsBase
+{
+public:
+  enum class ListPresetsOption
+  {
+    None,
+    Configure,
+    Build,
+    Test,
+    Package,
+    Workflow,
+    All,
+  };
+
+  bool HasPresetsArg() const override
+  {
+    return this->cmCMakePresetsArgsBase::HasPresetsArg() ||
+      this->ListPresets != ListPresetsOption::None;
+  }
+
+  void Clear() override
+  {
+    this->cmCMakePresetsArgsBase::Clear();
+    this->ListPresets = ListPresetsOption::None;
+  }
+
+  ListPresetsOption ListPresets = ListPresetsOption::None;
+};
+
+class cmCMakePresetsWorkflowArgs : public cmCMakePresetsArgs
+{
+public:
+  void Clear() override
+  {
+    this->cmCMakePresetsArgs::Clear();
+    this->Fresh = false;
+  }
+
+  bool Fresh = false;
+};
diff --git a/Source/cmCTest.cxx b/Source/cmCTest.cxx
index e57bd9d..27f6819 100644
--- a/Source/cmCTest.cxx
+++ b/Source/cmCTest.cxx
@@ -42,6 +42,7 @@
 
 #include "cm_parse_date.h"
 
+#include "cmCMakePresetsArgs.h"
 #include "cmCMakePresetsGraph.h"
 #include "cmCTestBuildAndTest.h"
 #include "cmCTestScriptHandler.h"
@@ -1501,8 +1502,7 @@
   return false;
 }
 
-bool cmCTest::SetArgsFromPreset(std::string const& presetName,
-                                bool listPresets)
+bool cmCTest::SetArgsFromPreset(cmCMakePresetsArgs const& args)
 {
   auto const workingDirectory = cmSystemTools::GetLogicalWorkingDirectory();
 
@@ -1515,13 +1515,13 @@
     return false;
   }
 
-  if (listPresets) {
+  if (args.ListPresets) {
     settingsFile.PrintTestPresetList();
     return true;
   }
 
   auto resolveResult =
-    settingsFile.ResolvePreset(presetName, settingsFile.TestPresets);
+    settingsFile.ResolvePreset(args.PresetName, settingsFile.TestPresets);
   auto resolveError =
     cmCMakePresetsGraph::FormatPresetError<cmCMakePresetsGraph::TestPreset>(
       resolveResult.StatusCode, resolveResult.ErrorPresetName,
@@ -1801,8 +1801,7 @@
   bool processSteps = false;
   bool SRArgumentSpecified = false;
   std::vector<std::pair<std::string, bool>> runScripts;
-  bool listPresets = false;
-  std::string presetName;
+  cmCMakePresetsArgs presetsArgs;
 
   // copy the command line
   cm::append(this->Impl->InitialCommandLineArguments, args);
@@ -1990,14 +1989,14 @@
 
   auto const presetArguments = std::vector<CommandArgument>{
     CommandArgument{ "--list-presets", CommandArgument::Values::Zero,
-                     [&listPresets](std::string const&) -> bool {
-                       listPresets = true;
+                     [&presetsArgs](std::string const&) -> bool {
+                       presetsArgs.ListPresets = true;
                        return true;
                      } },
     CommandArgument{ "--preset", "'--preset' requires an argument",
                      CommandArgument::Values::One,
-                     [&presetName](std::string const& presetArg) -> bool {
-                       presetName = presetArg;
+                     [&presetsArgs](std::string const& presetArg) -> bool {
+                       presetsArgs.PresetName = presetArg;
                        return true;
                      } }
   };
@@ -2490,9 +2489,9 @@
     }
   }
 
-  if (listPresets || !presetName.empty()) {
-    bool success = this->SetArgsFromPreset(presetName, listPresets);
-    if (listPresets) {
+  if (presetsArgs.HasPresetsArg()) {
+    bool success = this->SetArgsFromPreset(presetsArgs);
+    if (presetsArgs.ListPresets) {
       return static_cast<int>(!success);
     }
     if (!success) {
diff --git a/Source/cmCTest.h b/Source/cmCTest.h
index 46c88b7..8dce347 100644
--- a/Source/cmCTest.h
+++ b/Source/cmCTest.h
@@ -20,6 +20,7 @@
 #include "cmProcessOutput.h"
 
 class cmake;
+class cmCMakePresetsArgs;
 class cmGeneratedFileStream;
 class cmInstrumentation;
 class cmMakefile;
@@ -452,7 +453,7 @@
   bool AddVariableDefinition(std::string const& arg);
 
   /** set command line arguments read from a test preset */
-  bool SetArgsFromPreset(std::string const& presetName, bool listPresets);
+  bool SetArgsFromPreset(cmCMakePresetsArgs const& args);
 
   /** returns true iff the console supports progress output */
   static bool ProgressOutputSupportedByConsole();
diff --git a/Source/cmake.cxx b/Source/cmake.cxx
index a51374f..b08f2d3 100644
--- a/Source/cmake.cxx
+++ b/Source/cmake.cxx
@@ -86,6 +86,7 @@
 #  include <cm3p/curl/curl.h>
 #  include <cm3p/json/writer.h>
 
+#  include "cmCMakePresetsArgs.h"
 #  include "cmConfigureLog.h"
 #  include "cmFileAPI.h"
 #  include "cmGraphVizWriter.h"
@@ -1014,9 +1015,9 @@
 #if !defined(CMAKE_BOOTSTRAP)
   std::string profilingFormat;
   std::string profilingOutput;
-  std::string presetName;
 
-  ListPresets listPresets = ListPresets::None;
+  cmCMakePresetsConfigureArgs presetsArgs;
+  using ListPresets = cmCMakePresetsConfigureArgs::ListPresetsOption;
 #endif
 
   auto EmptyStringArgLambda = [](std::string const&, cmake* state) -> bool {
@@ -1429,24 +1430,24 @@
   arguments.emplace_back("--preset", "No preset specified for --preset",
                          CommandArgument::Values::One,
                          [&](std::string const& value, cmake*) -> bool {
-                           presetName = value;
+                           presetsArgs.PresetName = value;
                            return true;
                          });
   arguments.emplace_back(
     "--list-presets", CommandArgument::Values::ZeroOrOne,
     [&](std::string const& value, cmake*) -> bool {
       if (value.empty() || value == "configure") {
-        listPresets = ListPresets::Configure;
+        presetsArgs.ListPresets = ListPresets::Configure;
       } else if (value == "build") {
-        listPresets = ListPresets::Build;
+        presetsArgs.ListPresets = ListPresets::Build;
       } else if (value == "test") {
-        listPresets = ListPresets::Test;
+        presetsArgs.ListPresets = ListPresets::Test;
       } else if (value == "package") {
-        listPresets = ListPresets::Package;
+        presetsArgs.ListPresets = ListPresets::Package;
       } else if (value == "workflow") {
-        listPresets = ListPresets::Workflow;
+        presetsArgs.ListPresets = ListPresets::Workflow;
       } else if (value == "all") {
-        listPresets = ListPresets::All;
+        presetsArgs.ListPresets = ListPresets::All;
       } else {
         cmSystemTools::Error(
           "Invalid value specified for --list-presets.\n"
@@ -1573,7 +1574,7 @@
 #ifdef CMAKE_BOOTSTRAP
     false;
 #else
-    !presetName.empty();
+    !presetsArgs.PresetName.empty();
 #endif
 
   if (this->State->GetRole() == cmState::Role::Project && !haveSourceDir &&
@@ -1593,8 +1594,8 @@
   }
 
 #if !defined(CMAKE_BOOTSTRAP)
-  if (listPresets != ListPresets::None || !presetName.empty()) {
-    this->SetArgsFromPreset(presetName, listPresets, haveBArg);
+  if (presetsArgs.HasPresetsArg()) {
+    this->SetArgsFromPreset(presetsArgs, haveBArg);
   }
 #endif
 }
@@ -2009,9 +2010,11 @@
 }
 
 #ifndef CMAKE_BOOTSTRAP
-bool cmake::SetArgsFromPreset(std::string const& presetName,
-                              ListPresets listPresets, bool haveBinaryDirArg)
+bool cmake::SetArgsFromPreset(cmCMakePresetsConfigureArgs const& args,
+                              bool haveBinaryDirArg)
 {
+  using ListPresets = cmCMakePresetsConfigureArgs::ListPresetsOption;
+
   cmCMakePresetsGraph presetsGraph;
   auto result = presetsGraph.ReadProjectPresets(this->GetHomeDirectory());
   if (result != true) {
@@ -2022,19 +2025,28 @@
     return false;
   }
 
-  if (listPresets != ListPresets::None) {
-    if (listPresets == ListPresets::Configure) {
-      this->PrintPresetList(presetsGraph);
-    } else if (listPresets == ListPresets::Build) {
-      presetsGraph.PrintBuildPresetList();
-    } else if (listPresets == ListPresets::Test) {
-      presetsGraph.PrintTestPresetList();
-    } else if (listPresets == ListPresets::Package) {
-      presetsGraph.PrintPackagePresetList();
-    } else if (listPresets == ListPresets::Workflow) {
-      presetsGraph.PrintWorkflowPresetList();
-    } else if (listPresets == ListPresets::All) {
-      presetsGraph.PrintAllPresets();
+  if (args.ListPresets != ListPresets::None) {
+    switch (args.ListPresets) {
+      case ListPresets::Configure:
+        this->PrintPresetList(presetsGraph);
+        break;
+      case ListPresets::Build:
+        presetsGraph.PrintBuildPresetList();
+        break;
+      case ListPresets::Test:
+        presetsGraph.PrintTestPresetList();
+        break;
+      case ListPresets::Package:
+        presetsGraph.PrintPackagePresetList();
+        break;
+      case ListPresets::Workflow:
+        presetsGraph.PrintWorkflowPresetList();
+        break;
+      case ListPresets::All:
+        presetsGraph.PrintAllPresets();
+        break;
+      default:
+        break;
     }
 
     this->State->SetRoleToHelpForListPresets();
@@ -2042,7 +2054,7 @@
   }
 
   auto resolveResult =
-    presetsGraph.ResolvePreset(presetName, presetsGraph.ConfigurePresets);
+    presetsGraph.ResolvePreset(args.PresetName, presetsGraph.ConfigurePresets);
   using ConfigurePreset = cmCMakePresetsGraph::ConfigurePreset;
   using S = cmCMakePresetsGraph::PresetResolveStatus;
   auto resolveError = cmCMakePresetsGraph::FormatPresetError<ConfigurePreset>(
@@ -3897,13 +3909,14 @@
 
 int cmake::Build(cmBuildArgs buildArgs, std::vector<std::string> targets,
                  std::vector<std::string> nativeOptions,
-                 cmBuildOptions& buildOptions, std::string const& presetName,
-                 bool listPresets, std::vector<std::string> const& args)
+                 cmBuildOptions& buildOptions,
+                 cmCMakePresetsArgs const& presetsArgs,
+                 std::vector<std::string> const& args)
 {
   buildArgs.timeout = cmDuration::zero();
 
 #if !defined(CMAKE_BOOTSTRAP)
-  if (!presetName.empty() || listPresets) {
+  if (presetsArgs.HasPresetsArg()) {
     // If the binary directory was specified, use it to find
     // the source directory so we can locate the presets file.
     if (!buildArgs.binaryDir.empty() &&
@@ -3924,13 +3937,13 @@
       return 1;
     }
 
-    if (listPresets) {
+    if (presetsArgs.ListPresets) {
       settingsFile.PrintBuildPresetList();
       return 0;
     }
 
-    auto resolveResult =
-      settingsFile.ResolvePreset(presetName, settingsFile.BuildPresets);
+    auto resolveResult = settingsFile.ResolvePreset(presetsArgs.PresetName,
+                                                    settingsFile.BuildPresets);
     auto resolveError =
       cmCMakePresetsGraph::FormatPresetError<cmCMakePresetsGraph::BuildPreset>(
         resolveResult.StatusCode, resolveResult.ErrorPresetName,
@@ -4261,8 +4274,7 @@
 }
 #endif
 
-int cmake::Workflow(std::string const& presetName,
-                    WorkflowListPresets listPresets, WorkflowFresh fresh)
+int cmake::Workflow(cmCMakePresetsWorkflowArgs const& args)
 {
   int exitStatus = 0;
 #ifndef CMAKE_BOOTSTRAP
@@ -4278,24 +4290,24 @@
     return 1;
   }
 
-  if (listPresets == WorkflowListPresets::Yes) {
+  if (args.ListPresets) {
     settingsFile.PrintWorkflowPresetList();
     return 0;
   }
 
-  auto presetPair = settingsFile.WorkflowPresets.find(presetName);
+  auto presetPair = settingsFile.WorkflowPresets.find(args.PresetName);
   if (presetPair == settingsFile.WorkflowPresets.end()) {
     cmSystemTools::Error(cmStrCat("No such workflow preset in ",
-                                  this->GetHomeDirectory(), ": \"", presetName,
-                                  '"'));
+                                  this->GetHomeDirectory(), ": \"",
+                                  args.PresetName, '"'));
     settingsFile.PrintWorkflowPresetList();
     return 1;
   }
 
   if (presetPair->second.Unexpanded.Hidden) {
     cmSystemTools::Error(cmStrCat("Cannot use hidden workflow preset in ",
-                                  this->GetHomeDirectory(), ": \"", presetName,
-                                  '"'));
+                                  this->GetHomeDirectory(), ": \"",
+                                  args.PresetName, '"'));
     settingsFile.PrintWorkflowPresetList();
     return 1;
   }
@@ -4303,15 +4315,16 @@
   auto const& expandedPreset = presetPair->second.Expanded;
   if (!expandedPreset) {
     cmSystemTools::Error(cmStrCat("Could not evaluate workflow preset \"",
-                                  presetName, "\": Invalid macro expansion"));
+                                  args.PresetName,
+                                  "\": Invalid macro expansion"));
     settingsFile.PrintWorkflowPresetList();
     return 1;
   }
 
   if (!expandedPreset->ConditionResult) {
     cmSystemTools::Error(cmStrCat("Cannot use disabled workflow preset in ",
-                                  this->GetHomeDirectory(), ": \"", presetName,
-                                  '"'));
+                                  this->GetHomeDirectory(), ": \"",
+                                  args.PresetName, '"'));
     settingsFile.PrintWorkflowPresetList();
     return 1;
   }
@@ -4347,13 +4360,14 @@
         if (!configurePreset) {
           return 1;
         }
-        std::vector<std::string> args{ cmSystemTools::GetCMakeCommand(),
-                                       "--preset", step.PresetName };
-        if (fresh == WorkflowFresh::Yes) {
-          args.emplace_back("--fresh");
+        std::vector<std::string> configureCmdArgs{
+          cmSystemTools::GetCMakeCommand(), "--preset", step.PresetName
+        };
+        if (args.Fresh) {
+          configureCmdArgs.emplace_back("--fresh");
         }
         steps.emplace_back(stepNumber, "configure"_s, step.PresetName,
-                           buildWorkflowStep(args));
+                           buildWorkflowStep(configureCmdArgs));
       } break;
       case cmCMakePresetsGraph::WorkflowPreset::WorkflowStep::Type::Build: {
         auto const* buildPreset = this->FindPresetForWorkflow(
diff --git a/Source/cmake.h b/Source/cmake.h
index c2a0f05..900cbb4 100644
--- a/Source/cmake.h
+++ b/Source/cmake.h
@@ -48,6 +48,9 @@
 #endif
 
 class cmExternalMakefileProjectGeneratorFactory;
+class cmCMakePresetsArgs;
+class cmCMakePresetsConfigureArgs;
+class cmCMakePresetsWorkflowArgs;
 class cmFileAPI;
 class cmInstrumentation;
 class cmFileTimeCache;
@@ -254,19 +257,8 @@
   bool CreateAndSetGlobalGenerator(std::string const& name);
 
 #ifndef CMAKE_BOOTSTRAP
-  enum class ListPresets
-  {
-    None,
-    Configure,
-    Build,
-    Test,
-    Package,
-    Workflow,
-    All,
-  };
-
-  bool SetArgsFromPreset(std::string const& presetName,
-                         ListPresets listPresets, bool haveBinaryDirArg);
+  bool SetArgsFromPreset(cmCMakePresetsConfigureArgs const& args,
+                         bool haveBinaryDirArg);
 
   void PrintPresetList(cmCMakePresetsGraph const& graph) const;
 #endif
@@ -627,8 +619,9 @@
   //! run the --build option
   int Build(cmBuildArgs buildArgs, std::vector<std::string> targets,
             std::vector<std::string> nativeOptions,
-            cmBuildOptions& buildOptions, std::string const& presetName,
-            bool listPresets, std::vector<std::string> const& args);
+            cmBuildOptions& buildOptions,
+            cmCMakePresetsArgs const& presetsArgs,
+            std::vector<std::string> const& args);
 
   enum class DryRun
   {
@@ -640,18 +633,7 @@
   bool Open(std::string const& dir, DryRun dryRun);
 
   //! run the --workflow option
-  enum class WorkflowListPresets
-  {
-    No,
-    Yes,
-  };
-  enum class WorkflowFresh
-  {
-    No,
-    Yes,
-  };
-  int Workflow(std::string const& presetName, WorkflowListPresets listPresets,
-               WorkflowFresh fresh);
+  int Workflow(cmCMakePresetsWorkflowArgs const& args);
 
   void UnwatchUnusedCli(std::string const& var);
   void WatchUnusedCli(std::string const& var);
diff --git a/Source/cmakemain.cxx b/Source/cmakemain.cxx
index 7b325ee..6c41883 100644
--- a/Source/cmakemain.cxx
+++ b/Source/cmakemain.cxx
@@ -44,6 +44,7 @@
 #include "cmcmd.h"
 
 #ifndef CMAKE_BOOTSTRAP
+#  include "cmCMakePresetsArgs.h"
 #  include "cmDocumentation.h"
 #endif
 
@@ -474,8 +475,7 @@
   bool foundNonClean = false;
   PackageResolveMode resolveMode = PackageResolveMode::Default;
   buildArgs.verbose = cmSystemTools::HasEnv("VERBOSE");
-  std::string presetName;
-  bool listPresets = false;
+  cmCMakePresetsArgs presetsArgs;
 
   auto jLambda = extract_job_number_lambda_builder(buildArgs.binaryDir,
                                                    buildArgs.jobs, "-j");
@@ -523,9 +523,9 @@
   std::vector<CommandArgument> arguments = {
     CommandArgument{ "--preset", "No preset specified for --preset",
                      CommandArgument::Values::One,
-                     CommandArgument::setToValue(presetName) },
+                     CommandArgument::setToValue(presetsArgs.PresetName) },
     CommandArgument{ "--list-presets", CommandArgument::Values::Zero,
-                     CommandArgument::setToTrue(listPresets) },
+                     CommandArgument::setToTrue(presetsArgs.ListPresets) },
     CommandArgument{ "-j", CommandArgument::Values::ZeroOrOne,
                      CommandArgument::RequiresSeparator::No, jLambda },
     CommandArgument{ "--parallel", CommandArgument::Values::ZeroOrOne,
@@ -622,7 +622,7 @@
     }
   }
 
-  if (buildArgs.binaryDir.empty() && presetName.empty() && !listPresets) {
+  if (buildArgs.binaryDir.empty() && !presetsArgs.HasPresetsArg()) {
     /* clang-format off */
     std::cerr <<
       "Usage: cmake --build <dir>            "
@@ -672,7 +672,7 @@
   std::vector<std::string> cmd;
   cm::append(cmd, av, av + ac);
   return cm.Build(buildArgs, std::move(targets), std::move(nativeOptions),
-                  buildOptions, presetName, listPresets, cmd);
+                  buildOptions, presetsArgs, cmd);
 #endif
 }
 
@@ -980,11 +980,7 @@
   std::cerr << "This cmake does not support --workflow\n";
   return -1;
 #else
-  using WorkflowListPresets = cmake::WorkflowListPresets;
-  using WorkflowFresh = cmake::WorkflowFresh;
-  std::string presetName;
-  auto listPresets = WorkflowListPresets::No;
-  auto fresh = WorkflowFresh::No;
+  cmCMakePresetsWorkflowArgs presetsArgs;
 
   using CommandArgument =
     cmCommandLineArgument<bool(std::string const& value)>;
@@ -992,17 +988,11 @@
   std::vector<CommandArgument> arguments = {
     CommandArgument{ "--preset", "No preset specified for --preset",
                      CommandArgument::Values::One,
-                     CommandArgument::setToValue(presetName) },
+                     CommandArgument::setToValue(presetsArgs.PresetName) },
     CommandArgument{ "--list-presets", CommandArgument::Values::Zero,
-                     [&listPresets](std::string const&) -> bool {
-                       listPresets = WorkflowListPresets::Yes;
-                       return true;
-                     } },
+                     CommandArgument::setToTrue(presetsArgs.ListPresets) },
     CommandArgument{ "--fresh", CommandArgument::Values::Zero,
-                     [&fresh](std::string const&) -> bool {
-                       fresh = WorkflowFresh::Yes;
-                       return true;
-                     } },
+                     CommandArgument::setToTrue(presetsArgs.Fresh) }
   };
 
   std::vector<std::string> inputArgs;
@@ -1029,15 +1019,14 @@
     }
     if (!(matched && parsed)) {
       if (!matched) {
-        presetName.clear();
-        listPresets = WorkflowListPresets::No;
+        presetsArgs.Clear();
         std::cerr << "Unknown argument " << arg << std::endl;
       }
       break;
     }
   }
 
-  if (presetName.empty() && listPresets == WorkflowListPresets::No) {
+  if (!presetsArgs.HasPresetsArg()) {
     /* clang-format off */
     std::cerr <<
       "Usage: cmake --workflow <options>\n"
@@ -1060,7 +1049,7 @@
     cmakemainProgressCallback(msg, prog, &cm);
   });
 
-  return cm.Workflow(presetName, listPresets, fresh);
+  return cm.Workflow(presetsArgs);
 #endif
 }