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 }