From fd6ea2f67fc5fd1aee27ae92d6a16bc0fba1209e Mon Sep 17 00:00:00 2001 From: Kyle Edwards Date: Tue, 21 Dec 2021 14:39:04 -0500 Subject: [PATCH 1/4] Refactor: Rename cmCMakePresetsFile to cmCMakePresetsGraph And change all references to "file" to say "graph" instead. --- Source/CMakeLists.txt | 8 +- Source/QtDialog/CMakeSetupDialog.cxx | 4 +- Source/QtDialog/CMakeSetupDialog.h | 2 +- Source/QtDialog/QCMake.cxx | 22 +- Source/QtDialog/QCMake.h | 12 +- Source/QtDialog/QCMakePreset.h | 2 +- ...resetsFile.cxx => cmCMakePresetsGraph.cxx} | 191 +++++++++--------- ...akePresetsFile.h => cmCMakePresetsGraph.h} | 4 +- ...ternal.h => cmCMakePresetsGraphInternal.h} | 24 +-- ...ON.cxx => cmCMakePresetsGraphReadJSON.cxx} | 94 ++++----- Source/cmCTest.cxx | 34 ++-- Source/cmake.cxx | 42 ++-- Source/cmake.h | 6 +- 13 files changed, 224 insertions(+), 221 deletions(-) rename Source/{cmCMakePresetsFile.cxx => cmCMakePresetsGraph.cxx} (84%) rename Source/{cmCMakePresetsFile.h => cmCMakePresetsGraph.h} (99%) rename Source/{cmCMakePresetsFileInternal.h => cmCMakePresetsGraphInternal.h} (78%) rename Source/{cmCMakePresetsFileReadJSON.cxx => cmCMakePresetsGraphReadJSON.cxx} (92%) diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt index 677fd2fdd6..e0c5ed9203 100644 --- a/Source/CMakeLists.txt +++ b/Source/CMakeLists.txt @@ -161,10 +161,10 @@ set(SRCS cmCLocaleEnvironmentScope.cxx cmCMakePath.h cmCMakePath.cxx - cmCMakePresetsFile.cxx - cmCMakePresetsFile.h - cmCMakePresetsFileInternal.h - cmCMakePresetsFileReadJSON.cxx + cmCMakePresetsGraph.cxx + cmCMakePresetsGraph.h + cmCMakePresetsGraphInternal.h + cmCMakePresetsGraphReadJSON.cxx cmCommandArgumentParserHelper.cxx cmCommonTargetGenerator.cxx cmCommonTargetGenerator.h diff --git a/Source/QtDialog/CMakeSetupDialog.cxx b/Source/QtDialog/CMakeSetupDialog.cxx index 1785571687..f90b781f87 100644 --- a/Source/QtDialog/CMakeSetupDialog.cxx +++ b/Source/QtDialog/CMakeSetupDialog.cxx @@ -730,12 +730,12 @@ void CMakeSetupDialog::updatePreset(const QString& name) } void CMakeSetupDialog::showPresetLoadError( - const QString& dir, cmCMakePresetsFile::ReadFileResult result) + const QString& dir, cmCMakePresetsGraph::ReadFileResult result) { QMessageBox::warning( this, "Error Reading CMake Presets", QString::fromLocal8Bit("Could not read presets from %1: %2") - .arg(dir, cmCMakePresetsFile::ResultToString(result))); + .arg(dir, cmCMakePresetsGraph::ResultToString(result))); } void CMakeSetupDialog::doBinaryBrowse() diff --git a/Source/QtDialog/CMakeSetupDialog.h b/Source/QtDialog/CMakeSetupDialog.h index f0cc9294d8..8aee70de3c 100644 --- a/Source/QtDialog/CMakeSetupDialog.h +++ b/Source/QtDialog/CMakeSetupDialog.h @@ -60,7 +60,7 @@ protected slots: void updatePresets(const QVector& presets); void updatePreset(const QString& name); void showPresetLoadError(const QString& dir, - cmCMakePresetsFile::ReadFileResult result); + cmCMakePresetsGraph::ReadFileResult result); void showProgress(const QString& msg, float percent); void setEnabledState(bool); bool setupFirstConfigure(); diff --git a/Source/QtDialog/QCMake.cxx b/Source/QtDialog/QCMake.cxx index 8ab86564cb..ffb61570b8 100644 --- a/Source/QtDialog/QCMake.cxx +++ b/Source/QtDialog/QCMake.cxx @@ -32,7 +32,7 @@ QCMake::QCMake(QObject* p) qRegisterMetaType(); qRegisterMetaType(); qRegisterMetaType>(); - qRegisterMetaType(); + qRegisterMetaType(); cmSystemTools::DisableRunCommandOutput(); cmSystemTools::SetRunCommandHideConsole(true); @@ -69,9 +69,9 @@ QCMake::QCMake(QObject* p) connect(&this->LoadPresetsTimer, &QTimer::timeout, this, [this]() { this->loadPresets(); if (!this->PresetName.isEmpty() && - this->CMakePresetsFile.ConfigurePresets.find( + this->CMakePresetsGraph.ConfigurePresets.find( std::string(this->PresetName.toLocal8Bit())) == - this->CMakePresetsFile.ConfigurePresets.end()) { + this->CMakePresetsGraph.ConfigurePresets.end()) { this->setPreset(QString{}); } }); @@ -159,7 +159,7 @@ void QCMake::setPreset(const QString& name, bool setBinary) if (!name.isNull()) { std::string presetName(name.toLocal8Bit()); auto const& expandedPreset = - this->CMakePresetsFile.ConfigurePresets[presetName].Expanded; + this->CMakePresetsGraph.ConfigurePresets[presetName].Expanded; if (expandedPreset) { if (setBinary && !expandedPreset->BinaryDir.empty()) { QString binaryDir = @@ -427,7 +427,7 @@ QCMakePropertyList QCMake::properties() const if (!this->PresetName.isNull()) { std::string presetName(this->PresetName.toLocal8Bit()); auto const& p = - this->CMakePresetsFile.ConfigurePresets.at(presetName).Expanded; + this->CMakePresetsGraph.ConfigurePresets.at(presetName).Expanded; if (p) { for (auto const& v : p->CacheVariables) { if (!v.second) { @@ -533,17 +533,17 @@ void QCMake::setUpEnvironment() const void QCMake::loadPresets() { - auto result = this->CMakePresetsFile.ReadProjectPresets( + auto result = this->CMakePresetsGraph.ReadProjectPresets( this->SourceDirectory.toLocal8Bit().data(), true); if (result != this->LastLoadPresetsResult && - result != cmCMakePresetsFile::ReadFileResult::READ_OK) { + result != cmCMakePresetsGraph::ReadFileResult::READ_OK) { emit this->presetLoadError(this->SourceDirectory, result); } this->LastLoadPresetsResult = result; QVector presets; - for (auto const& name : this->CMakePresetsFile.ConfigurePresetOrder) { - auto const& it = this->CMakePresetsFile.ConfigurePresets[name]; + for (auto const& name : this->CMakePresetsGraph.ConfigurePresetOrder) { + auto const& it = this->CMakePresetsGraph.ConfigurePresets[name]; auto const& p = it.Unexpanded; if (p.Hidden) { continue; @@ -556,10 +556,10 @@ void QCMake::loadPresets() preset.generator = QString::fromLocal8Bit(p.Generator.data()); preset.architecture = QString::fromLocal8Bit(p.Architecture.data()); preset.setArchitecture = !p.ArchitectureStrategy || - p.ArchitectureStrategy == cmCMakePresetsFile::ArchToolsetStrategy::Set; + p.ArchitectureStrategy == cmCMakePresetsGraph::ArchToolsetStrategy::Set; preset.toolset = QString::fromLocal8Bit(p.Toolset.data()); preset.setToolset = !p.ToolsetStrategy || - p.ToolsetStrategy == cmCMakePresetsFile::ArchToolsetStrategy::Set; + p.ToolsetStrategy == cmCMakePresetsGraph::ArchToolsetStrategy::Set; preset.enabled = it.Expanded && it.Expanded->ConditionResult && std::find_if(this->AvailableGenerators.begin(), this->AvailableGenerators.end(), diff --git a/Source/QtDialog/QCMake.h b/Source/QtDialog/QCMake.h index a6751b0cae..8a7e4cb8aa 100644 --- a/Source/QtDialog/QCMake.h +++ b/Source/QtDialog/QCMake.h @@ -4,7 +4,7 @@ #include "cmConfigure.h" // IWYU pragma: keep -#include "cmCMakePresetsFile.h" +#include "cmCMakePresetsGraph.h" #include "cmake.h" #ifdef _MSC_VER @@ -60,7 +60,7 @@ using QCMakePropertyList = QList; Q_DECLARE_METATYPE(QCMakeProperty) Q_DECLARE_METATYPE(QCMakePropertyList) Q_DECLARE_METATYPE(QProcessEnvironment) -Q_DECLARE_METATYPE(cmCMakePresetsFile::ReadFileResult) +Q_DECLARE_METATYPE(cmCMakePresetsGraph::ReadFileResult) /// Qt API for CMake library. /// Wrapper like class allows for easier integration with @@ -159,7 +159,7 @@ signals: void presetChanged(const QString& name); /// signal when there's an error reading the presets files void presetLoadError(const QString& dir, - cmCMakePresetsFile::ReadFileResult error); + cmCMakePresetsGraph::ReadFileResult error); /// signal when uninitialized warning changes void warnUninitializedModeChanged(bool value); /// signal for progress events @@ -202,9 +202,9 @@ protected: QString Platform; QString Toolset; std::vector AvailableGenerators; - cmCMakePresetsFile CMakePresetsFile; - cmCMakePresetsFile::ReadFileResult LastLoadPresetsResult = - cmCMakePresetsFile::ReadFileResult::READ_OK; + cmCMakePresetsGraph CMakePresetsGraph; + cmCMakePresetsGraph::ReadFileResult LastLoadPresetsResult = + cmCMakePresetsGraph::ReadFileResult::READ_OK; QString PresetName; QString CMakeExecutable; QAtomicInt InterruptFlag; diff --git a/Source/QtDialog/QCMakePreset.h b/Source/QtDialog/QCMakePreset.h index 1609fcb357..7387655838 100644 --- a/Source/QtDialog/QCMakePreset.h +++ b/Source/QtDialog/QCMakePreset.h @@ -5,7 +5,7 @@ #include #include -#include "cmCMakePresetsFile.h" +#include "cmCMakePresetsGraph.h" class QCMakePreset { diff --git a/Source/cmCMakePresetsFile.cxx b/Source/cmCMakePresetsGraph.cxx similarity index 84% rename from Source/cmCMakePresetsFile.cxx rename to Source/cmCMakePresetsGraph.cxx index 4a0742a0d6..ebc243bd59 100644 --- a/Source/cmCMakePresetsFile.cxx +++ b/Source/cmCMakePresetsGraph.cxx @@ -1,6 +1,6 @@ /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying file Copyright.txt or https://cmake.org/licensing for details. */ -#include "cmCMakePresetsFile.h" +#include "cmCMakePresetsGraph.h" #include #include @@ -13,7 +13,7 @@ #include "cmsys/RegularExpression.hxx" -#include "cmCMakePresetsFileInternal.h" +#include "cmCMakePresetsGraphInternal.h" #include "cmStringAlgorithms.h" #include "cmSystemTools.h" @@ -38,12 +38,12 @@ enum class CycleStatus Verified, }; -using ReadFileResult = cmCMakePresetsFile::ReadFileResult; -using ConfigurePreset = cmCMakePresetsFile::ConfigurePreset; -using BuildPreset = cmCMakePresetsFile::BuildPreset; -using TestPreset = cmCMakePresetsFile::TestPreset; -using ExpandMacroResult = cmCMakePresetsFileInternal::ExpandMacroResult; -using MacroExpander = cmCMakePresetsFileInternal::MacroExpander; +using ReadFileResult = cmCMakePresetsGraph::ReadFileResult; +using ConfigurePreset = cmCMakePresetsGraph::ConfigurePreset; +using BuildPreset = cmCMakePresetsGraph::BuildPreset; +using TestPreset = cmCMakePresetsGraph::TestPreset; +using ExpandMacroResult = cmCMakePresetsGraphInternal::ExpandMacroResult; +using MacroExpander = cmCMakePresetsGraphInternal::MacroExpander; void InheritString(std::string& child, const std::string& parent) { @@ -77,9 +77,10 @@ void InheritVector(std::vector& child, const std::vector& parent) */ template ReadFileResult VisitPreset( - T& preset, std::map>& presets, + T& preset, + std::map>& presets, std::map cycleStatus, - const cmCMakePresetsFile& file) + const cmCMakePresetsGraph& graph) { switch (cycleStatus[preset.Name]) { case CycleStatus::InProgress: @@ -109,7 +110,7 @@ ReadFileResult VisitPreset( return ReadFileResult::USER_PRESET_INHERITANCE; } - auto result = VisitPreset(parentPreset, presets, cycleStatus, file); + auto result = VisitPreset(parentPreset, presets, cycleStatus, graph); if (result != ReadFileResult::READ_OK) { return result; } @@ -129,7 +130,7 @@ ReadFileResult VisitPreset( preset.ConditionEvaluator.reset(); } - CHECK_OK(preset.VisitPresetAfterInherit(file.GetVersion(preset))); + CHECK_OK(preset.VisitPresetAfterInherit(graph.GetVersion(preset))); cycleStatus[preset.Name] = CycleStatus::Verified; return ReadFileResult::READ_OK; @@ -137,8 +138,8 @@ ReadFileResult VisitPreset( template ReadFileResult ComputePresetInheritance( - std::map>& presets, - const cmCMakePresetsFile& file) + std::map>& presets, + const cmCMakePresetsGraph& graph) { std::map cycleStatus; for (auto const& it : presets) { @@ -147,7 +148,7 @@ ReadFileResult ComputePresetInheritance( for (auto& it : presets) { auto& preset = it.second.Unexpanded; - auto result = VisitPreset(preset, presets, cycleStatus, file); + auto result = VisitPreset(preset, presets, cycleStatus, graph); if (result != ReadFileResult::READ_OK) { return result; } @@ -189,17 +190,17 @@ ExpandMacroResult ExpandMacro(std::string& out, const std::vector& macroExpanders, int version); -bool ExpandMacros(const cmCMakePresetsFile& file, +bool ExpandMacros(const cmCMakePresetsGraph& graph, const ConfigurePreset& preset, cm::optional& out, const std::vector& macroExpanders) { std::string binaryDir = preset.BinaryDir; - CHECK_EXPAND(out, binaryDir, macroExpanders, file.GetVersion(preset)); + CHECK_EXPAND(out, binaryDir, macroExpanders, graph.GetVersion(preset)); if (!binaryDir.empty()) { if (!cmSystemTools::FileIsFullPath(binaryDir)) { - binaryDir = cmStrCat(file.SourceDir, '/', binaryDir); + binaryDir = cmStrCat(graph.SourceDir, '/', binaryDir); } out->BinaryDir = cmSystemTools::CollapseFullPath(binaryDir); cmSystemTools::ConvertToUnixSlashes(out->BinaryDir); @@ -207,10 +208,10 @@ bool ExpandMacros(const cmCMakePresetsFile& file, if (!preset.InstallDir.empty()) { std::string installDir = preset.InstallDir; - CHECK_EXPAND(out, installDir, macroExpanders, file.GetVersion(preset)); + CHECK_EXPAND(out, installDir, macroExpanders, graph.GetVersion(preset)); if (!cmSystemTools::FileIsFullPath(installDir)) { - installDir = cmStrCat(file.SourceDir, '/', installDir); + installDir = cmStrCat(graph.SourceDir, '/', installDir); } out->InstallDir = cmSystemTools::CollapseFullPath(installDir); cmSystemTools::ConvertToUnixSlashes(out->InstallDir); @@ -218,89 +219,89 @@ bool ExpandMacros(const cmCMakePresetsFile& file, if (!preset.ToolchainFile.empty()) { std::string toolchain = preset.ToolchainFile; - CHECK_EXPAND(out, toolchain, macroExpanders, file.GetVersion(preset)); + CHECK_EXPAND(out, toolchain, macroExpanders, graph.GetVersion(preset)); out->ToolchainFile = toolchain; } for (auto& variable : out->CacheVariables) { if (variable.second) { CHECK_EXPAND(out, variable.second->Value, macroExpanders, - file.GetVersion(preset)); + graph.GetVersion(preset)); } } return true; } -bool ExpandMacros(const cmCMakePresetsFile& file, const BuildPreset& preset, +bool ExpandMacros(const cmCMakePresetsGraph& graph, const BuildPreset& preset, cm::optional& out, const std::vector& macroExpanders) { for (auto& target : out->Targets) { - CHECK_EXPAND(out, target, macroExpanders, file.GetVersion(preset)); + CHECK_EXPAND(out, target, macroExpanders, graph.GetVersion(preset)); } for (auto& nativeToolOption : out->NativeToolOptions) { CHECK_EXPAND(out, nativeToolOption, macroExpanders, - file.GetVersion(preset)); + graph.GetVersion(preset)); } return true; } -bool ExpandMacros(const cmCMakePresetsFile& file, const TestPreset& preset, +bool ExpandMacros(const cmCMakePresetsGraph& graph, const TestPreset& preset, cm::optional& out, const std::vector& macroExpanders) { for (auto& overwrite : out->OverwriteConfigurationFile) { - CHECK_EXPAND(out, overwrite, macroExpanders, file.GetVersion(preset)); + CHECK_EXPAND(out, overwrite, macroExpanders, graph.GetVersion(preset)); } if (out->Output) { CHECK_EXPAND(out, out->Output->OutputLogFile, macroExpanders, - file.GetVersion(preset)); + graph.GetVersion(preset)); } if (out->Filter) { if (out->Filter->Include) { CHECK_EXPAND(out, out->Filter->Include->Name, macroExpanders, - file.GetVersion(preset)); + graph.GetVersion(preset)); CHECK_EXPAND(out, out->Filter->Include->Label, macroExpanders, - file.GetVersion(preset)); + graph.GetVersion(preset)); if (out->Filter->Include->Index) { CHECK_EXPAND(out, out->Filter->Include->Index->IndexFile, - macroExpanders, file.GetVersion(preset)); + macroExpanders, graph.GetVersion(preset)); } } if (out->Filter->Exclude) { CHECK_EXPAND(out, out->Filter->Exclude->Name, macroExpanders, - file.GetVersion(preset)); + graph.GetVersion(preset)); CHECK_EXPAND(out, out->Filter->Exclude->Label, macroExpanders, - file.GetVersion(preset)); + graph.GetVersion(preset)); if (out->Filter->Exclude->Fixtures) { CHECK_EXPAND(out, out->Filter->Exclude->Fixtures->Any, macroExpanders, - file.GetVersion(preset)); + graph.GetVersion(preset)); CHECK_EXPAND(out, out->Filter->Exclude->Fixtures->Setup, - macroExpanders, file.GetVersion(preset)); + macroExpanders, graph.GetVersion(preset)); CHECK_EXPAND(out, out->Filter->Exclude->Fixtures->Cleanup, - macroExpanders, file.GetVersion(preset)); + macroExpanders, graph.GetVersion(preset)); } } } if (out->Execution) { CHECK_EXPAND(out, out->Execution->ResourceSpecFile, macroExpanders, - file.GetVersion(preset)); + graph.GetVersion(preset)); } return true; } template -bool ExpandMacros(const cmCMakePresetsFile& file, const T& preset, +bool ExpandMacros(const cmCMakePresetsGraph& graph, const T& preset, cm::optional& out) { out.emplace(preset); @@ -313,20 +314,20 @@ bool ExpandMacros(const cmCMakePresetsFile& file, const T& preset, std::vector macroExpanders; MacroExpander defaultMacroExpander = - [&file, &preset](const std::string& macroNamespace, - const std::string& macroName, std::string& macroOut, - int version) -> ExpandMacroResult { + [&graph, &preset](const std::string& macroNamespace, + const std::string& macroName, std::string& macroOut, + int version) -> ExpandMacroResult { if (macroNamespace.empty()) { if (macroName == "sourceDir") { - macroOut += file.SourceDir; + macroOut += graph.SourceDir; return ExpandMacroResult::Ok; } if (macroName == "sourceParentDir") { - macroOut += cmSystemTools::GetParentDirectory(file.SourceDir); + macroOut += cmSystemTools::GetParentDirectory(graph.SourceDir); return ExpandMacroResult::Ok; } if (macroName == "sourceDirName") { - macroOut += cmSystemTools::GetFilenameName(file.SourceDir); + macroOut += cmSystemTools::GetFilenameName(graph.SourceDir); return ExpandMacroResult::Ok; } if (macroName == "presetName") { @@ -336,7 +337,7 @@ bool ExpandMacros(const cmCMakePresetsFile& file, const T& preset, if (macroName == "generator") { // Generator only makes sense if preset is not hidden. if (!preset.Hidden) { - macroOut += file.GetGeneratorForPreset(preset.Name); + macroOut += graph.GetGeneratorForPreset(preset.Name); } return ExpandMacroResult::Ok; } @@ -393,7 +394,7 @@ bool ExpandMacros(const cmCMakePresetsFile& file, const T& preset, for (auto& v : out->Environment) { if (v.second) { switch (VisitEnv(*v.second, envCycles[v.first], macroExpanders, - file.GetVersion(preset))) { + graph.GetVersion(preset))) { case ExpandMacroResult::Error: return false; case ExpandMacroResult::Ignore: @@ -408,7 +409,7 @@ bool ExpandMacros(const cmCMakePresetsFile& file, const T& preset, if (preset.ConditionEvaluator) { cm::optional result; if (!preset.ConditionEvaluator->Evaluate( - macroExpanders, file.GetVersion(preset), result)) { + macroExpanders, graph.GetVersion(preset), result)) { return false; } if (!result) { @@ -418,7 +419,7 @@ bool ExpandMacros(const cmCMakePresetsFile& file, const T& preset, out->ConditionResult = *result; } - return ExpandMacros(file, preset, out, macroExpanders); + return ExpandMacros(graph, preset, out, macroExpanders); } ExpandMacroResult VisitEnv(std::string& value, CycleStatus& status, @@ -541,7 +542,7 @@ ExpandMacroResult ExpandMacro(std::string& out, } } -bool cmCMakePresetsFileInternal::EqualsCondition::Evaluate( +bool cmCMakePresetsGraphInternal::EqualsCondition::Evaluate( const std::vector& expanders, int version, cm::optional& out) const { @@ -555,7 +556,7 @@ bool cmCMakePresetsFileInternal::EqualsCondition::Evaluate( return true; } -bool cmCMakePresetsFileInternal::InListCondition::Evaluate( +bool cmCMakePresetsGraphInternal::InListCondition::Evaluate( const std::vector& expanders, int version, cm::optional& out) const { @@ -574,7 +575,7 @@ bool cmCMakePresetsFileInternal::InListCondition::Evaluate( return true; } -bool cmCMakePresetsFileInternal::MatchesCondition::Evaluate( +bool cmCMakePresetsGraphInternal::MatchesCondition::Evaluate( const std::vector& expanders, int version, cm::optional& out) const { @@ -592,7 +593,7 @@ bool cmCMakePresetsFileInternal::MatchesCondition::Evaluate( return true; } -bool cmCMakePresetsFileInternal::AnyAllOfCondition::Evaluate( +bool cmCMakePresetsGraphInternal::AnyAllOfCondition::Evaluate( const std::vector& expanders, int version, cm::optional& out) const { @@ -618,7 +619,7 @@ bool cmCMakePresetsFileInternal::AnyAllOfCondition::Evaluate( return true; } -bool cmCMakePresetsFileInternal::NotCondition::Evaluate( +bool cmCMakePresetsGraphInternal::NotCondition::Evaluate( const std::vector& expanders, int version, cm::optional& out) const { @@ -633,9 +634,9 @@ bool cmCMakePresetsFileInternal::NotCondition::Evaluate( return true; } -cmCMakePresetsFile::ReadFileResult -cmCMakePresetsFile::ConfigurePreset::VisitPresetInherit( - const cmCMakePresetsFile::Preset& parentPreset) +cmCMakePresetsGraph::ReadFileResult +cmCMakePresetsGraph::ConfigurePreset::VisitPresetInherit( + const cmCMakePresetsGraph::Preset& parentPreset) { auto& preset = *this; const ConfigurePreset& parent = @@ -667,8 +668,8 @@ cmCMakePresetsFile::ConfigurePreset::VisitPresetInherit( return ReadFileResult::READ_OK; } -cmCMakePresetsFile::ReadFileResult -cmCMakePresetsFile::ConfigurePreset::VisitPresetBeforeInherit() +cmCMakePresetsGraph::ReadFileResult +cmCMakePresetsGraph::ConfigurePreset::VisitPresetBeforeInherit() { auto& preset = *this; if (preset.Environment.count("") != 0) { @@ -678,8 +679,8 @@ cmCMakePresetsFile::ConfigurePreset::VisitPresetBeforeInherit() return ReadFileResult::READ_OK; } -cmCMakePresetsFile::ReadFileResult -cmCMakePresetsFile::ConfigurePreset::VisitPresetAfterInherit(int version) +cmCMakePresetsGraph::ReadFileResult +cmCMakePresetsGraph::ConfigurePreset::VisitPresetAfterInherit(int version) { auto& preset = *this; if (!preset.Hidden) { @@ -706,9 +707,9 @@ cmCMakePresetsFile::ConfigurePreset::VisitPresetAfterInherit(int version) return ReadFileResult::READ_OK; } -cmCMakePresetsFile::ReadFileResult -cmCMakePresetsFile::BuildPreset::VisitPresetInherit( - const cmCMakePresetsFile::Preset& parentPreset) +cmCMakePresetsGraph::ReadFileResult +cmCMakePresetsGraph::BuildPreset::VisitPresetInherit( + const cmCMakePresetsGraph::Preset& parentPreset) { auto& preset = *this; const BuildPreset& parent = static_cast(parentPreset); @@ -726,8 +727,8 @@ cmCMakePresetsFile::BuildPreset::VisitPresetInherit( return ReadFileResult::READ_OK; } -cmCMakePresetsFile::ReadFileResult -cmCMakePresetsFile::BuildPreset::VisitPresetAfterInherit(int /* version */) +cmCMakePresetsGraph::ReadFileResult +cmCMakePresetsGraph::BuildPreset::VisitPresetAfterInherit(int /* version */) { auto& preset = *this; if (!preset.Hidden && preset.ConfigurePreset.empty()) { @@ -736,9 +737,9 @@ cmCMakePresetsFile::BuildPreset::VisitPresetAfterInherit(int /* version */) return ReadFileResult::READ_OK; } -cmCMakePresetsFile::ReadFileResult -cmCMakePresetsFile::TestPreset::VisitPresetInherit( - const cmCMakePresetsFile::Preset& parentPreset) +cmCMakePresetsGraph::ReadFileResult +cmCMakePresetsGraph::TestPreset::VisitPresetInherit( + const cmCMakePresetsGraph::Preset& parentPreset) { auto& preset = *this; const TestPreset& parent = static_cast(parentPreset); @@ -836,8 +837,8 @@ cmCMakePresetsFile::TestPreset::VisitPresetInherit( return ReadFileResult::READ_OK; } -cmCMakePresetsFile::ReadFileResult -cmCMakePresetsFile::TestPreset::VisitPresetAfterInherit(int /* version */) +cmCMakePresetsGraph::ReadFileResult +cmCMakePresetsGraph::TestPreset::VisitPresetAfterInherit(int /* version */) { auto& preset = *this; if (!preset.Hidden && preset.ConfigurePreset.empty()) { @@ -846,17 +847,17 @@ cmCMakePresetsFile::TestPreset::VisitPresetAfterInherit(int /* version */) return ReadFileResult::READ_OK; } -std::string cmCMakePresetsFile::GetFilename(const std::string& sourceDir) +std::string cmCMakePresetsGraph::GetFilename(const std::string& sourceDir) { return cmStrCat(sourceDir, "/CMakePresets.json"); } -std::string cmCMakePresetsFile::GetUserFilename(const std::string& sourceDir) +std::string cmCMakePresetsGraph::GetUserFilename(const std::string& sourceDir) { return cmStrCat(sourceDir, "/CMakeUserPresets.json"); } -cmCMakePresetsFile::ReadFileResult cmCMakePresetsFile::ReadProjectPresets( +cmCMakePresetsGraph::ReadFileResult cmCMakePresetsGraph::ReadProjectPresets( const std::string& sourceDir, bool allowNoFiles) { this->SourceDir = sourceDir; @@ -870,8 +871,8 @@ cmCMakePresetsFile::ReadFileResult cmCMakePresetsFile::ReadProjectPresets( return result; } -cmCMakePresetsFile::ReadFileResult -cmCMakePresetsFile::ReadProjectPresetsInternal(bool allowNoFiles) +cmCMakePresetsGraph::ReadFileResult +cmCMakePresetsGraph::ReadProjectPresetsInternal(bool allowNoFiles) { bool haveOneFile = false; @@ -951,7 +952,7 @@ cmCMakePresetsFile::ReadProjectPresetsInternal(bool allowNoFiles) return ReadFileResult::READ_OK; } -const char* cmCMakePresetsFile::ResultToString(ReadFileResult result) +const char* cmCMakePresetsGraph::ResultToString(ReadFileResult result) { switch (result) { case ReadFileResult::READ_OK: @@ -1006,7 +1007,7 @@ const char* cmCMakePresetsFile::ResultToString(ReadFileResult result) return "Unknown error"; } -void cmCMakePresetsFile::ClearPresets() +void cmCMakePresetsGraph::ClearPresets() { this->ConfigurePresets.clear(); this->BuildPresets.clear(); @@ -1017,8 +1018,8 @@ void cmCMakePresetsFile::ClearPresets() this->TestPresetOrder.clear(); } -void cmCMakePresetsFile::PrintPresets( - const std::vector& presets) +void cmCMakePresetsGraph::PrintPresets( + const std::vector& presets) { if (presets.empty()) { return; @@ -1026,8 +1027,8 @@ void cmCMakePresetsFile::PrintPresets( auto longestPresetName = std::max_element(presets.begin(), presets.end(), - [](const cmCMakePresetsFile::Preset* a, - const cmCMakePresetsFile::Preset* b) { + [](const cmCMakePresetsGraph::Preset* a, + const cmCMakePresetsGraph::Preset* b) { return a->Name.length() < b->Name.length(); }); auto longestLength = (*longestPresetName)->Name.length(); @@ -1045,67 +1046,67 @@ void cmCMakePresetsFile::PrintPresets( } } -void cmCMakePresetsFile::PrintConfigurePresetList() const +void cmCMakePresetsGraph::PrintConfigurePresetList() const { PrintConfigurePresetList([](const ConfigurePreset&) { return true; }); } -void cmCMakePresetsFile::PrintConfigurePresetList( +void cmCMakePresetsGraph::PrintConfigurePresetList( const std::function& filter) const { - std::vector presets; + std::vector presets; for (auto const& p : this->ConfigurePresetOrder) { auto const& preset = this->ConfigurePresets.at(p); if (!preset.Unexpanded.Hidden && preset.Expanded && preset.Expanded->ConditionResult && filter(preset.Unexpanded)) { presets.push_back( - static_cast(&preset.Unexpanded)); + static_cast(&preset.Unexpanded)); } } if (!presets.empty()) { std::cout << "Available configure presets:\n\n"; - cmCMakePresetsFile::PrintPresets(presets); + cmCMakePresetsGraph::PrintPresets(presets); } } -void cmCMakePresetsFile::PrintBuildPresetList() const +void cmCMakePresetsGraph::PrintBuildPresetList() const { - std::vector presets; + std::vector presets; for (auto const& p : this->BuildPresetOrder) { auto const& preset = this->BuildPresets.at(p); if (!preset.Unexpanded.Hidden && preset.Expanded && preset.Expanded->ConditionResult) { presets.push_back( - static_cast(&preset.Unexpanded)); + static_cast(&preset.Unexpanded)); } } if (!presets.empty()) { std::cout << "Available build presets:\n\n"; - cmCMakePresetsFile::PrintPresets(presets); + cmCMakePresetsGraph::PrintPresets(presets); } } -void cmCMakePresetsFile::PrintTestPresetList() const +void cmCMakePresetsGraph::PrintTestPresetList() const { - std::vector presets; + std::vector presets; for (auto const& p : this->TestPresetOrder) { auto const& preset = this->TestPresets.at(p); if (!preset.Unexpanded.Hidden && preset.Expanded && preset.Expanded->ConditionResult) { presets.push_back( - static_cast(&preset.Unexpanded)); + static_cast(&preset.Unexpanded)); } } if (!presets.empty()) { std::cout << "Available test presets:\n\n"; - cmCMakePresetsFile::PrintPresets(presets); + cmCMakePresetsGraph::PrintPresets(presets); } } -void cmCMakePresetsFile::PrintAllPresets() const +void cmCMakePresetsGraph::PrintAllPresets() const { this->PrintConfigurePresetList(); std::cout << std::endl; diff --git a/Source/cmCMakePresetsFile.h b/Source/cmCMakePresetsGraph.h similarity index 99% rename from Source/cmCMakePresetsFile.h rename to Source/cmCMakePresetsGraph.h index 769fb4e2a7..937b281ce5 100644 --- a/Source/cmCMakePresetsFile.h +++ b/Source/cmCMakePresetsGraph.h @@ -13,7 +13,7 @@ #include -class cmCMakePresetsFile +class cmCMakePresetsGraph { public: enum class ReadFileResult @@ -363,7 +363,7 @@ public: } static void PrintPresets( - const std::vector& presets); + const std::vector& presets); void PrintConfigurePresetList() const; void PrintConfigurePresetList( const std::function& filter) const; diff --git a/Source/cmCMakePresetsFileInternal.h b/Source/cmCMakePresetsGraphInternal.h similarity index 78% rename from Source/cmCMakePresetsFileInternal.h rename to Source/cmCMakePresetsGraphInternal.h index afb00ced96..b2e679180b 100644 --- a/Source/cmCMakePresetsFileInternal.h +++ b/Source/cmCMakePresetsGraphInternal.h @@ -2,7 +2,7 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include -#include "cmCMakePresetsFile.h" +#include "cmCMakePresetsGraph.h" #define CHECK_OK(expr) \ do { \ @@ -11,7 +11,7 @@ return _result; \ } while (false) -namespace cmCMakePresetsFileInternal { +namespace cmCMakePresetsGraphInternal { enum class ExpandMacroResult { Ok, @@ -23,20 +23,20 @@ using MacroExpander = std::function; } -class cmCMakePresetsFile::Condition +class cmCMakePresetsGraph::Condition { public: virtual ~Condition() = default; virtual bool Evaluate( - const std::vector& expanders, + const std::vector& expanders, int version, cm::optional& out) const = 0; virtual bool IsNull() const { return false; } }; -namespace cmCMakePresetsFileInternal { +namespace cmCMakePresetsGraphInternal { -class NullCondition : public cmCMakePresetsFile::Condition +class NullCondition : public cmCMakePresetsGraph::Condition { bool Evaluate(const std::vector& /*expanders*/, int /*version*/, cm::optional& out) const override @@ -48,7 +48,7 @@ class NullCondition : public cmCMakePresetsFile::Condition bool IsNull() const override { return true; } }; -class ConstCondition : public cmCMakePresetsFile::Condition +class ConstCondition : public cmCMakePresetsGraph::Condition { public: bool Evaluate(const std::vector& /*expanders*/, @@ -61,7 +61,7 @@ public: bool Value; }; -class EqualsCondition : public cmCMakePresetsFile::Condition +class EqualsCondition : public cmCMakePresetsGraph::Condition { public: bool Evaluate(const std::vector& expanders, int version, @@ -71,7 +71,7 @@ public: std::string Rhs; }; -class InListCondition : public cmCMakePresetsFile::Condition +class InListCondition : public cmCMakePresetsGraph::Condition { public: bool Evaluate(const std::vector& expanders, int version, @@ -81,7 +81,7 @@ public: std::vector List; }; -class MatchesCondition : public cmCMakePresetsFile::Condition +class MatchesCondition : public cmCMakePresetsGraph::Condition { public: bool Evaluate(const std::vector& expanders, int version, @@ -91,7 +91,7 @@ public: std::string Regex; }; -class AnyAllOfCondition : public cmCMakePresetsFile::Condition +class AnyAllOfCondition : public cmCMakePresetsGraph::Condition { public: bool Evaluate(const std::vector& expanders, int version, @@ -101,7 +101,7 @@ public: bool StopValue; }; -class NotCondition : public cmCMakePresetsFile::Condition +class NotCondition : public cmCMakePresetsGraph::Condition { public: bool Evaluate(const std::vector& expanders, int version, diff --git a/Source/cmCMakePresetsFileReadJSON.cxx b/Source/cmCMakePresetsGraphReadJSON.cxx similarity index 92% rename from Source/cmCMakePresetsFileReadJSON.cxx rename to Source/cmCMakePresetsGraphReadJSON.cxx index 489551dcf0..8a9e6a0350 100644 --- a/Source/cmCMakePresetsFileReadJSON.cxx +++ b/Source/cmCMakePresetsGraphReadJSON.cxx @@ -15,18 +15,18 @@ #include "cmsys/FStream.hxx" -#include "cmCMakePresetsFile.h" -#include "cmCMakePresetsFileInternal.h" +#include "cmCMakePresetsGraph.h" +#include "cmCMakePresetsGraphInternal.h" #include "cmJSONHelpers.h" #include "cmVersion.h" namespace { -using ReadFileResult = cmCMakePresetsFile::ReadFileResult; -using CacheVariable = cmCMakePresetsFile::CacheVariable; -using ConfigurePreset = cmCMakePresetsFile::ConfigurePreset; -using BuildPreset = cmCMakePresetsFile::BuildPreset; -using TestPreset = cmCMakePresetsFile::TestPreset; -using ArchToolsetStrategy = cmCMakePresetsFile::ArchToolsetStrategy; +using ReadFileResult = cmCMakePresetsGraph::ReadFileResult; +using CacheVariable = cmCMakePresetsGraph::CacheVariable; +using ConfigurePreset = cmCMakePresetsGraph::ConfigurePreset; +using BuildPreset = cmCMakePresetsGraph::BuildPreset; +using TestPreset = cmCMakePresetsGraph::TestPreset; +using ArchToolsetStrategy = cmCMakePresetsGraph::ArchToolsetStrategy; constexpr int MIN_VERSION = 1; constexpr int MAX_VERSION = 3; @@ -41,15 +41,15 @@ struct CMakeVersion struct RootPresets { CMakeVersion CMakeMinimumRequired; - std::vector ConfigurePresets; - std::vector BuildPresets; - std::vector TestPresets; + std::vector ConfigurePresets; + std::vector BuildPresets; + std::vector TestPresets; }; -std::unique_ptr InvertCondition( - std::unique_ptr condition) +std::unique_ptr InvertCondition( + std::unique_ptr condition) { - auto retval = cm::make_unique(); + auto retval = cm::make_unique(); retval->SubCondition = std::move(condition); return retval; } @@ -66,71 +66,72 @@ auto const ConditionStringListHelper = ConditionStringHelper); auto const ConstConditionHelper = - cmJSONObjectHelper(ReadFileResult::READ_OK, ReadFileResult::INVALID_CONDITION, false) .Bind("type"_s, nullptr, ConditionStringHelper, true) - .Bind("value"_s, &cmCMakePresetsFileInternal::ConstCondition::Value, + .Bind("value"_s, &cmCMakePresetsGraphInternal::ConstCondition::Value, ConditionBoolHelper, true); auto const EqualsConditionHelper = - cmJSONObjectHelper(ReadFileResult::READ_OK, ReadFileResult::INVALID_CONDITION, false) .Bind("type"_s, nullptr, ConditionStringHelper, true) - .Bind("lhs"_s, &cmCMakePresetsFileInternal::EqualsCondition::Lhs, + .Bind("lhs"_s, &cmCMakePresetsGraphInternal::EqualsCondition::Lhs, ConditionStringHelper, true) - .Bind("rhs"_s, &cmCMakePresetsFileInternal::EqualsCondition::Rhs, + .Bind("rhs"_s, &cmCMakePresetsGraphInternal::EqualsCondition::Rhs, ConditionStringHelper, true); auto const InListConditionHelper = - cmJSONObjectHelper(ReadFileResult::READ_OK, ReadFileResult::INVALID_CONDITION, false) .Bind("type"_s, nullptr, ConditionStringHelper, true) - .Bind("string"_s, &cmCMakePresetsFileInternal::InListCondition::String, + .Bind("string"_s, &cmCMakePresetsGraphInternal::InListCondition::String, ConditionStringHelper, true) - .Bind("list"_s, &cmCMakePresetsFileInternal::InListCondition::List, + .Bind("list"_s, &cmCMakePresetsGraphInternal::InListCondition::List, ConditionStringListHelper, true); auto const MatchesConditionHelper = - cmJSONObjectHelper(ReadFileResult::READ_OK, ReadFileResult::INVALID_CONDITION, false) .Bind("type"_s, nullptr, ConditionStringHelper, true) - .Bind("string"_s, &cmCMakePresetsFileInternal::MatchesCondition::String, + .Bind("string"_s, &cmCMakePresetsGraphInternal::MatchesCondition::String, ConditionStringHelper, true) - .Bind("regex"_s, &cmCMakePresetsFileInternal::MatchesCondition::Regex, + .Bind("regex"_s, &cmCMakePresetsGraphInternal::MatchesCondition::Regex, ConditionStringHelper, true); ReadFileResult SubConditionHelper( - std::unique_ptr& out, + std::unique_ptr& out, const Json::Value* value); auto const ListConditionVectorHelper = - cmJSONVectorHelper, + cmJSONVectorHelper, ReadFileResult>(ReadFileResult::READ_OK, ReadFileResult::INVALID_CONDITION, SubConditionHelper); auto const AnyAllOfConditionHelper = - cmJSONObjectHelper(ReadFileResult::READ_OK, ReadFileResult::INVALID_CONDITION, false) .Bind("type"_s, nullptr, ConditionStringHelper, true) .Bind("conditions"_s, - &cmCMakePresetsFileInternal::AnyAllOfCondition::Conditions, + &cmCMakePresetsGraphInternal::AnyAllOfCondition::Conditions, ListConditionVectorHelper); auto const NotConditionHelper = - cmJSONObjectHelper( - ReadFileResult::READ_OK, ReadFileResult::INVALID_CONDITION, false) + cmJSONObjectHelper(ReadFileResult::READ_OK, + ReadFileResult::INVALID_CONDITION, false) .Bind("type"_s, nullptr, ConditionStringHelper, true) .Bind("condition"_s, - &cmCMakePresetsFileInternal::NotCondition::SubCondition, + &cmCMakePresetsGraphInternal::NotCondition::SubCondition, SubConditionHelper); ReadFileResult ConditionHelper( - std::unique_ptr& out, + std::unique_ptr& out, const Json::Value* value) { if (!value) { @@ -139,14 +140,14 @@ ReadFileResult ConditionHelper( } if (value->isBool()) { - auto c = cm::make_unique(); + auto c = cm::make_unique(); c->Value = value->asBool(); out = std::move(c); return ReadFileResult::READ_OK; } if (value->isNull()) { - out = cm::make_unique(); + out = cm::make_unique(); return ReadFileResult::READ_OK; } @@ -161,14 +162,14 @@ ReadFileResult ConditionHelper( auto type = (*value)["type"].asString(); if (type == "const") { - auto c = cm::make_unique(); + auto c = cm::make_unique(); CHECK_OK(ConstConditionHelper(*c, value)); out = std::move(c); return ReadFileResult::READ_OK; } if (type == "equals" || type == "notEquals") { - auto c = cm::make_unique(); + auto c = cm::make_unique(); CHECK_OK(EqualsConditionHelper(*c, value)); out = std::move(c); if (type == "notEquals") { @@ -178,7 +179,7 @@ ReadFileResult ConditionHelper( } if (type == "inList" || type == "notInList") { - auto c = cm::make_unique(); + auto c = cm::make_unique(); CHECK_OK(InListConditionHelper(*c, value)); out = std::move(c); if (type == "notInList") { @@ -188,7 +189,8 @@ ReadFileResult ConditionHelper( } if (type == "matches" || type == "notMatches") { - auto c = cm::make_unique(); + auto c = + cm::make_unique(); CHECK_OK(MatchesConditionHelper(*c, value)); out = std::move(c); if (type == "notMatches") { @@ -199,7 +201,7 @@ ReadFileResult ConditionHelper( if (type == "anyOf" || type == "allOf") { auto c = - cm::make_unique(); + cm::make_unique(); c->StopValue = (type == "anyOf"); CHECK_OK(AnyAllOfConditionHelper(*c, value)); out = std::move(c); @@ -207,7 +209,7 @@ ReadFileResult ConditionHelper( } if (type == "not") { - auto c = cm::make_unique(); + auto c = cm::make_unique(); CHECK_OK(NotConditionHelper(*c, value)); out = std::move(c); return ReadFileResult::READ_OK; @@ -218,20 +220,20 @@ ReadFileResult ConditionHelper( } ReadFileResult PresetConditionHelper( - std::shared_ptr& out, + std::shared_ptr& out, const Json::Value* value) { - std::unique_ptr ptr; + std::unique_ptr ptr; auto result = ConditionHelper(ptr, value); out = std::move(ptr); return result; } ReadFileResult SubConditionHelper( - std::unique_ptr& out, + std::unique_ptr& out, const Json::Value* value) { - std::unique_ptr ptr; + std::unique_ptr ptr; auto result = ConditionHelper(ptr, value); if (ptr && ptr->IsNull()) { return ReadFileResult::INVALID_CONDITION; @@ -898,7 +900,7 @@ auto const RootPresetsHelper = VendorHelper(ReadFileResult::INVALID_ROOT), false); } -cmCMakePresetsFile::ReadFileResult cmCMakePresetsFile::ReadJSONFile( +cmCMakePresetsGraph::ReadFileResult cmCMakePresetsGraph::ReadJSONFile( const std::string& filename, bool user) { cmsys::ifstream fin(filename.c_str()); diff --git a/Source/cmCTest.cxx b/Source/cmCTest.cxx index 647dd87247..a1e920e7d3 100644 --- a/Source/cmCTest.cxx +++ b/Source/cmCTest.cxx @@ -38,7 +38,7 @@ # include // IWYU pragma: keep #endif -#include "cmCMakePresetsFile.h" +#include "cmCMakePresetsGraph.h" #include "cmCTestBuildAndTestHandler.h" #include "cmCTestBuildHandler.h" #include "cmCTestConfigureHandler.h" @@ -2327,12 +2327,12 @@ bool cmCTest::SetArgsFromPreset(const std::string& presetName, { const auto workingDirectory = cmSystemTools::GetCurrentWorkingDirectory(); - cmCMakePresetsFile settingsFile; + cmCMakePresetsGraph settingsFile; auto result = settingsFile.ReadProjectPresets(workingDirectory); - if (result != cmCMakePresetsFile::ReadFileResult::READ_OK) { - cmSystemTools::Error(cmStrCat("Could not read presets from ", - workingDirectory, ": ", - cmCMakePresetsFile::ResultToString(result))); + if (result != cmCMakePresetsGraph::ReadFileResult::READ_OK) { + cmSystemTools::Error( + cmStrCat("Could not read presets from ", workingDirectory, ": ", + cmCMakePresetsGraph::ResultToString(result))); return false; } @@ -2422,15 +2422,15 @@ bool cmCTest::SetArgsFromPreset(const std::string& presetName, if (expandedPreset->Output->Verbosity) { const auto& verbosity = *expandedPreset->Output->Verbosity; switch (verbosity) { - case cmCMakePresetsFile::TestPreset::OutputOptions::VerbosityEnum:: + case cmCMakePresetsGraph::TestPreset::OutputOptions::VerbosityEnum:: Extra: this->Impl->ExtraVerbose = true; CM_FALLTHROUGH; - case cmCMakePresetsFile::TestPreset::OutputOptions::VerbosityEnum:: + case cmCMakePresetsGraph::TestPreset::OutputOptions::VerbosityEnum:: Verbose: this->Impl->Verbose = true; break; - case cmCMakePresetsFile::TestPreset::OutputOptions::VerbosityEnum:: + case cmCMakePresetsGraph::TestPreset::OutputOptions::VerbosityEnum:: Default: default: // leave default settings @@ -2548,13 +2548,13 @@ bool cmCTest::SetArgsFromPreset(const std::string& presetName, this->Impl->ShowOnly = true; switch (*expandedPreset->Execution->ShowOnly) { - case cmCMakePresetsFile::TestPreset::ExecutionOptions::ShowOnlyEnum:: + case cmCMakePresetsGraph::TestPreset::ExecutionOptions::ShowOnlyEnum:: JsonV1: this->Impl->Quiet = true; this->Impl->OutputAsJson = true; this->Impl->OutputAsJsonVersion = 1; break; - case cmCMakePresetsFile::TestPreset::ExecutionOptions::ShowOnlyEnum:: + case cmCMakePresetsGraph::TestPreset::ExecutionOptions::ShowOnlyEnum:: Human: // intentional fallthrough (human is the default) default: @@ -2565,15 +2565,15 @@ bool cmCTest::SetArgsFromPreset(const std::string& presetName, if (expandedPreset->Execution->Repeat) { this->Impl->RepeatCount = expandedPreset->Execution->Repeat->Count; switch (expandedPreset->Execution->Repeat->Mode) { - case cmCMakePresetsFile::TestPreset::ExecutionOptions::RepeatOptions:: + case cmCMakePresetsGraph::TestPreset::ExecutionOptions::RepeatOptions:: ModeEnum::UntilFail: this->Impl->RepeatMode = cmCTest::Repeat::UntilFail; break; - case cmCMakePresetsFile::TestPreset::ExecutionOptions::RepeatOptions:: + case cmCMakePresetsGraph::TestPreset::ExecutionOptions::RepeatOptions:: ModeEnum::UntilPass: this->Impl->RepeatMode = cmCTest::Repeat::UntilPass; break; - case cmCMakePresetsFile::TestPreset::ExecutionOptions::RepeatOptions:: + case cmCMakePresetsGraph::TestPreset::ExecutionOptions::RepeatOptions:: ModeEnum::AfterTimeout: this->Impl->RepeatMode = cmCTest::Repeat::AfterTimeout; break; @@ -2599,15 +2599,15 @@ bool cmCTest::SetArgsFromPreset(const std::string& presetName, if (expandedPreset->Execution->NoTestsAction) { switch (*expandedPreset->Execution->NoTestsAction) { - case cmCMakePresetsFile::TestPreset::ExecutionOptions:: + case cmCMakePresetsGraph::TestPreset::ExecutionOptions:: NoTestsActionEnum::Error: this->Impl->NoTestsMode = cmCTest::NoTests::Error; break; - case cmCMakePresetsFile::TestPreset::ExecutionOptions:: + case cmCMakePresetsGraph::TestPreset::ExecutionOptions:: NoTestsActionEnum::Ignore: this->Impl->NoTestsMode = cmCTest::NoTests::Ignore; break; - case cmCMakePresetsFile::TestPreset::ExecutionOptions:: + case cmCMakePresetsGraph::TestPreset::ExecutionOptions:: NoTestsActionEnum::Default: break; default: diff --git a/Source/cmake.cxx b/Source/cmake.cxx index 2a3ef9b15f..c708eb2059 100644 --- a/Source/cmake.cxx +++ b/Source/cmake.cxx @@ -29,7 +29,7 @@ #include "cm_sys_stat.h" #include "cmCMakePath.h" -#include "cmCMakePresetsFile.h" +#include "cmCMakePresetsGraph.h" #include "cmCommandLineArgument.h" #include "cmCommands.h" #include "cmDocumentation.h" @@ -1239,43 +1239,43 @@ void cmake::SetArgs(const std::vector& args) #if !defined(CMAKE_BOOTSTRAP) if (listPresets != ListPresets::None || !presetName.empty()) { - cmCMakePresetsFile settingsFile; - auto result = settingsFile.ReadProjectPresets(this->GetHomeDirectory()); - if (result != cmCMakePresetsFile::ReadFileResult::READ_OK) { + cmCMakePresetsGraph presetsGraph; + auto result = presetsGraph.ReadProjectPresets(this->GetHomeDirectory()); + if (result != cmCMakePresetsGraph::ReadFileResult::READ_OK) { cmSystemTools::Error( cmStrCat("Could not read presets from ", this->GetHomeDirectory(), - ": ", cmCMakePresetsFile::ResultToString(result))); + ": ", cmCMakePresetsGraph::ResultToString(result))); return; } if (listPresets != ListPresets::None) { if (listPresets == ListPresets::Configure) { - this->PrintPresetList(settingsFile); + this->PrintPresetList(presetsGraph); } else if (listPresets == ListPresets::Build) { - settingsFile.PrintBuildPresetList(); + presetsGraph.PrintBuildPresetList(); } else if (listPresets == ListPresets::Test) { - settingsFile.PrintTestPresetList(); + presetsGraph.PrintTestPresetList(); } else if (listPresets == ListPresets::All) { - settingsFile.PrintAllPresets(); + presetsGraph.PrintAllPresets(); } this->SetWorkingMode(WorkingMode::HELP_MODE); return; } - auto preset = settingsFile.ConfigurePresets.find(presetName); - if (preset == settingsFile.ConfigurePresets.end()) { + auto preset = presetsGraph.ConfigurePresets.find(presetName); + if (preset == presetsGraph.ConfigurePresets.end()) { cmSystemTools::Error(cmStrCat("No such preset in ", this->GetHomeDirectory(), ": \"", presetName, '"')); - this->PrintPresetList(settingsFile); + this->PrintPresetList(presetsGraph); return; } if (preset->second.Unexpanded.Hidden) { cmSystemTools::Error(cmStrCat("Cannot use hidden preset in ", this->GetHomeDirectory(), ": \"", presetName, '"')); - this->PrintPresetList(settingsFile); + this->PrintPresetList(presetsGraph); return; } auto const& expandedPreset = preset->second.Expanded; @@ -1319,14 +1319,14 @@ void cmake::SetArgs(const std::vector& args) if (!expandedPreset->ArchitectureStrategy || expandedPreset->ArchitectureStrategy == - cmCMakePresetsFile::ArchToolsetStrategy::Set) { + cmCMakePresetsGraph::ArchToolsetStrategy::Set) { if (!this->GeneratorPlatformSet) { this->SetGeneratorPlatform(expandedPreset->Architecture); } } if (!expandedPreset->ToolsetStrategy || expandedPreset->ToolsetStrategy == - cmCMakePresetsFile::ArchToolsetStrategy::Set) { + cmCMakePresetsGraph::ArchToolsetStrategy::Set) { if (!this->GeneratorToolsetSet) { this->SetGeneratorToolset(expandedPreset->Toolset); } @@ -1707,12 +1707,12 @@ bool cmake::CreateAndSetGlobalGenerator(const std::string& name, } #ifndef CMAKE_BOOTSTRAP -void cmake::PrintPresetList(const cmCMakePresetsFile& file) const +void cmake::PrintPresetList(const cmCMakePresetsGraph& graph) const { std::vector generators; this->GetRegisteredGenerators(generators, false); auto filter = - [&generators](const cmCMakePresetsFile::ConfigurePreset& preset) -> bool { + [&generators](const cmCMakePresetsGraph::ConfigurePreset& preset) -> bool { if (preset.Generator.empty()) { return true; } @@ -1723,7 +1723,7 @@ void cmake::PrintPresetList(const cmCMakePresetsFile& file) const return it != generators.end(); }; - file.PrintConfigurePresetList(filter); + graph.PrintConfigurePresetList(filter); } #endif @@ -3230,12 +3230,12 @@ int cmake::Build(int jobs, std::string dir, std::vector targets, this->SetHomeDirectory(cmSystemTools::GetCurrentWorkingDirectory()); this->SetHomeOutputDirectory(cmSystemTools::GetCurrentWorkingDirectory()); - cmCMakePresetsFile settingsFile; + cmCMakePresetsGraph settingsFile; auto result = settingsFile.ReadProjectPresets(this->GetHomeDirectory()); - if (result != cmCMakePresetsFile::ReadFileResult::READ_OK) { + if (result != cmCMakePresetsGraph::ReadFileResult::READ_OK) { cmSystemTools::Error( cmStrCat("Could not read presets from ", this->GetHomeDirectory(), - ": ", cmCMakePresetsFile::ResultToString(result))); + ": ", cmCMakePresetsGraph::ResultToString(result))); return 1; } diff --git a/Source/cmake.h b/Source/cmake.h index a356e6596c..b13cc963e8 100644 --- a/Source/cmake.h +++ b/Source/cmake.h @@ -31,7 +31,7 @@ # include -# include "cmCMakePresetsFile.h" +# include "cmCMakePresetsGraph.h" #endif class cmExternalMakefileProjectGeneratorFactory; @@ -248,7 +248,7 @@ public: #ifndef CMAKE_BOOTSTRAP //! Print list of configure presets - void PrintPresetList(const cmCMakePresetsFile& file) const; + void PrintPresetList(const cmCMakePresetsGraph& graph) const; #endif //! Return the global generator assigned to this instance of cmake @@ -691,7 +691,7 @@ private: std::string GraphVizFile; InstalledFilesMap InstalledFiles; #ifndef CMAKE_BOOTSTRAP - std::map> + std::map> UnprocessedPresetVariables; std::map> UnprocessedPresetEnvironment; From 84d440caace3f65ef6ddd197098f8d83c0ecef70 Mon Sep 17 00:00:00 2001 From: Kyle Edwards Date: Wed, 5 Jan 2022 13:57:48 -0500 Subject: [PATCH 2/4] Refactor: Split JSON processing into configure, build, and test presets Split up the file so that it won't be too big on some systems. --- Source/CMakeLists.txt | 3 + Source/cmCMakePresetsGraphInternal.h | 51 ++ Source/cmCMakePresetsGraphReadJSON.cxx | 759 +++--------------- ...mCMakePresetsGraphReadJSONBuildPresets.cxx | 75 ++ ...kePresetsGraphReadJSONConfigurePresets.cxx | 228 ++++++ ...cmCMakePresetsGraphReadJSONTestPresets.cxx | 360 +++++++++ 6 files changed, 849 insertions(+), 627 deletions(-) create mode 100644 Source/cmCMakePresetsGraphReadJSONBuildPresets.cxx create mode 100644 Source/cmCMakePresetsGraphReadJSONConfigurePresets.cxx create mode 100644 Source/cmCMakePresetsGraphReadJSONTestPresets.cxx diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt index e0c5ed9203..1933b6ac1c 100644 --- a/Source/CMakeLists.txt +++ b/Source/CMakeLists.txt @@ -165,6 +165,9 @@ set(SRCS cmCMakePresetsGraph.h cmCMakePresetsGraphInternal.h cmCMakePresetsGraphReadJSON.cxx + cmCMakePresetsGraphReadJSONBuildPresets.cxx + cmCMakePresetsGraphReadJSONConfigurePresets.cxx + cmCMakePresetsGraphReadJSONTestPresets.cxx cmCommandArgumentParserHelper.cxx cmCommonTargetGenerator.cxx cmCommonTargetGenerator.h diff --git a/Source/cmCMakePresetsGraphInternal.h b/Source/cmCMakePresetsGraphInternal.h index b2e679180b..f7c73494b6 100644 --- a/Source/cmCMakePresetsGraphInternal.h +++ b/Source/cmCMakePresetsGraphInternal.h @@ -1,8 +1,13 @@ /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying file Copyright.txt or https://cmake.org/licensing for details. */ #include +#include +#include + +#include #include "cmCMakePresetsGraph.h" +#include "cmJSONHelpers.h" #define CHECK_OK(expr) \ do { \ @@ -109,4 +114,50 @@ public: std::unique_ptr SubCondition; }; + +cmCMakePresetsGraph::ReadFileResult PresetStringHelper( + std::string& out, const Json::Value* value); + +cmCMakePresetsGraph::ReadFileResult PresetVectorStringHelper( + std::vector& out, const Json::Value* value); + +cmCMakePresetsGraph::ReadFileResult PresetBoolHelper(bool& out, + const Json::Value* value); + +cmCMakePresetsGraph::ReadFileResult PresetOptionalBoolHelper( + cm::optional& out, const Json::Value* value); + +cmCMakePresetsGraph::ReadFileResult PresetIntHelper(int& out, + const Json::Value* value); + +cmCMakePresetsGraph::ReadFileResult PresetOptionalIntHelper( + cm::optional& out, const Json::Value* value); + +cmCMakePresetsGraph::ReadFileResult PresetVectorIntHelper( + std::vector& out, const Json::Value* value); + +cmCMakePresetsGraph::ReadFileResult ConfigurePresetsHelper( + std::vector& out, + const Json::Value* value); + +cmCMakePresetsGraph::ReadFileResult BuildPresetsHelper( + std::vector& out, + const Json::Value* value); + +cmCMakePresetsGraph::ReadFileResult TestPresetsHelper( + std::vector& out, const Json::Value* value); + +cmJSONHelper VendorHelper( + cmCMakePresetsGraph::ReadFileResult error); + +cmCMakePresetsGraph::ReadFileResult PresetConditionHelper( + std::shared_ptr& out, + const Json::Value* value); + +cmCMakePresetsGraph::ReadFileResult PresetVectorOneOrMoreStringHelper( + std::vector& out, const Json::Value* value); + +cmCMakePresetsGraph::ReadFileResult EnvironmentMapHelper( + std::map>& out, + const Json::Value* value); } diff --git a/Source/cmCMakePresetsGraphReadJSON.cxx b/Source/cmCMakePresetsGraphReadJSON.cxx index 8a9e6a0350..3e002fee26 100644 --- a/Source/cmCMakePresetsGraphReadJSON.cxx +++ b/Source/cmCMakePresetsGraphReadJSON.cxx @@ -219,16 +219,6 @@ ReadFileResult ConditionHelper( return ReadFileResult::INVALID_CONDITION; } -ReadFileResult PresetConditionHelper( - std::shared_ptr& out, - const Json::Value* value) -{ - std::unique_ptr ptr; - auto result = ConditionHelper(ptr, value); - out = std::move(ptr); - return result; -} - ReadFileResult SubConditionHelper( std::unique_ptr& out, const Json::Value* value) @@ -242,6 +232,124 @@ ReadFileResult SubConditionHelper( return result; } +ReadFileResult EnvironmentHelper(cm::optional& out, + const Json::Value* value) +{ + if (!value || value->isNull()) { + out = cm::nullopt; + return ReadFileResult::READ_OK; + } + if (value->isString()) { + out = value->asString(); + return ReadFileResult::READ_OK; + } + return ReadFileResult::INVALID_PRESET; +} + +auto const VersionIntHelper = cmJSONIntHelper( + ReadFileResult::READ_OK, ReadFileResult::INVALID_VERSION); + +auto const VersionHelper = cmJSONRequiredHelper( + ReadFileResult::NO_VERSION, VersionIntHelper); + +auto const RootVersionHelper = + cmJSONObjectHelper(ReadFileResult::READ_OK, + ReadFileResult::INVALID_ROOT) + .Bind("version"_s, VersionHelper, false); + +auto const CMakeVersionUIntHelper = cmJSONUIntHelper( + ReadFileResult::READ_OK, ReadFileResult::INVALID_VERSION); + +auto const CMakeVersionHelper = + cmJSONObjectHelper( + ReadFileResult::READ_OK, ReadFileResult::INVALID_CMAKE_VERSION, false) + .Bind("major"_s, &CMakeVersion::Major, CMakeVersionUIntHelper, false) + .Bind("minor"_s, &CMakeVersion::Minor, CMakeVersionUIntHelper, false) + .Bind("patch"_s, &CMakeVersion::Patch, CMakeVersionUIntHelper, false); + +auto const RootPresetsHelper = + cmJSONObjectHelper( + ReadFileResult::READ_OK, ReadFileResult::INVALID_ROOT, false) + .Bind("version"_s, nullptr, VersionHelper) + .Bind("configurePresets"_s, &RootPresets::ConfigurePresets, + cmCMakePresetsGraphInternal::ConfigurePresetsHelper, false) + .Bind("buildPresets"_s, &RootPresets::BuildPresets, + cmCMakePresetsGraphInternal::BuildPresetsHelper, false) + .Bind("testPresets"_s, &RootPresets::TestPresets, + cmCMakePresetsGraphInternal::TestPresetsHelper, false) + .Bind("cmakeMinimumRequired"_s, &RootPresets::CMakeMinimumRequired, + CMakeVersionHelper, false) + .Bind( + "vendor"_s, nullptr, + cmCMakePresetsGraphInternal::VendorHelper(ReadFileResult::INVALID_ROOT), + false); +} + +namespace cmCMakePresetsGraphInternal { +cmCMakePresetsGraph::ReadFileResult PresetStringHelper( + std::string& out, const Json::Value* value) +{ + static auto const helper = cmJSONStringHelper( + ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET); + + return helper(out, value); +} + +cmCMakePresetsGraph::ReadFileResult PresetVectorStringHelper( + std::vector& out, const Json::Value* value) +{ + static auto const helper = cmJSONVectorHelper( + ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET, + cmCMakePresetsGraphInternal::PresetStringHelper); + + return helper(out, value); +} + +cmCMakePresetsGraph::ReadFileResult PresetBoolHelper(bool& out, + const Json::Value* value) +{ + static auto const helper = cmJSONBoolHelper( + ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET); + + return helper(out, value); +} + +cmCMakePresetsGraph::ReadFileResult PresetOptionalBoolHelper( + cm::optional& out, const Json::Value* value) +{ + static auto const helper = cmJSONOptionalHelper( + ReadFileResult::READ_OK, PresetBoolHelper); + + return helper(out, value); +} + +cmCMakePresetsGraph::ReadFileResult PresetIntHelper(int& out, + const Json::Value* value) +{ + static auto const helper = cmJSONIntHelper( + ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET); + + return helper(out, value); +} + +cmCMakePresetsGraph::ReadFileResult PresetOptionalIntHelper( + cm::optional& out, const Json::Value* value) +{ + static auto const helper = cmJSONOptionalHelper( + ReadFileResult::READ_OK, PresetIntHelper); + + return helper(out, value); +} + +cmCMakePresetsGraph::ReadFileResult PresetVectorIntHelper( + std::vector& out, const Json::Value* value) +{ + static auto const helper = cmJSONVectorHelper( + ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET, PresetIntHelper); + + return helper(out, value); +} + cmJSONHelper VendorHelper(ReadFileResult error) { return [error](std::nullptr_t& /*out*/, @@ -258,100 +366,16 @@ cmJSONHelper VendorHelper(ReadFileResult error) }; } -auto const VersionIntHelper = cmJSONIntHelper( - ReadFileResult::READ_OK, ReadFileResult::INVALID_VERSION); - -auto const VersionHelper = cmJSONRequiredHelper( - ReadFileResult::NO_VERSION, VersionIntHelper); - -auto const RootVersionHelper = - cmJSONObjectHelper(ReadFileResult::READ_OK, - ReadFileResult::INVALID_ROOT) - .Bind("version"_s, VersionHelper, false); - -auto const VariableStringHelper = cmJSONStringHelper( - ReadFileResult::READ_OK, ReadFileResult::INVALID_VARIABLE); - -ReadFileResult VariableValueHelper(std::string& out, const Json::Value* value) +ReadFileResult PresetConditionHelper( + std::shared_ptr& out, + const Json::Value* value) { - if (!value) { - out.clear(); - return ReadFileResult::READ_OK; - } - - if (value->isBool()) { - out = value->asBool() ? "TRUE" : "FALSE"; - return ReadFileResult::READ_OK; - } - - return VariableStringHelper(out, value); + std::unique_ptr ptr; + auto result = ConditionHelper(ptr, value); + out = std::move(ptr); + return result; } -auto const VariableObjectHelper = - cmJSONObjectHelper( - ReadFileResult::READ_OK, ReadFileResult::INVALID_VARIABLE, false) - .Bind("type"_s, &CacheVariable::Type, VariableStringHelper, false) - .Bind("value"_s, &CacheVariable::Value, VariableValueHelper); - -ReadFileResult VariableHelper(cm::optional& out, - const Json::Value* value) -{ - if (value->isBool()) { - out = CacheVariable{ - /*Type=*/"BOOL", - /*Value=*/value->asBool() ? "TRUE" : "FALSE", - }; - return ReadFileResult::READ_OK; - } - if (value->isString()) { - out = CacheVariable{ - /*Type=*/"", - /*Value=*/value->asString(), - }; - return ReadFileResult::READ_OK; - } - if (value->isObject()) { - out.emplace(); - return VariableObjectHelper(*out, value); - } - if (value->isNull()) { - out = cm::nullopt; - return ReadFileResult::READ_OK; - } - return ReadFileResult::INVALID_VARIABLE; -} - -auto const VariablesHelper = - cmJSONMapHelper, ReadFileResult>( - ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET, VariableHelper); - -auto const PresetStringHelper = cmJSONStringHelper( - ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET); - -ReadFileResult EnvironmentHelper(cm::optional& out, - const Json::Value* value) -{ - if (!value || value->isNull()) { - out = cm::nullopt; - return ReadFileResult::READ_OK; - } - if (value->isString()) { - out = value->asString(); - return ReadFileResult::READ_OK; - } - return ReadFileResult::INVALID_PRESET; -} - -auto const EnvironmentMapHelper = - cmJSONMapHelper, ReadFileResult>( - ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET, - EnvironmentHelper); - -auto const PresetVectorStringHelper = - cmJSONVectorHelper( - ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET, - PresetStringHelper); - ReadFileResult PresetVectorOneOrMoreStringHelper(std::vector& out, const Json::Value* value) { @@ -368,536 +392,17 @@ ReadFileResult PresetVectorOneOrMoreStringHelper(std::vector& out, return PresetVectorStringHelper(out, value); } -auto const PresetBoolHelper = cmJSONBoolHelper( - ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET); - -auto const PresetOptionalBoolHelper = - cmJSONOptionalHelper(ReadFileResult::READ_OK, - PresetBoolHelper); - -auto const PresetIntHelper = cmJSONIntHelper( - ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET); - -auto const PresetOptionalIntHelper = cmJSONOptionalHelper( - ReadFileResult::READ_OK, PresetIntHelper); - -auto const PresetVectorIntHelper = cmJSONVectorHelper( - ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET, PresetIntHelper); - -auto const PresetWarningsHelper = - cmJSONObjectHelper( - ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET, false) - .Bind("dev"_s, &ConfigurePreset::WarnDev, PresetOptionalBoolHelper, false) - .Bind("deprecated"_s, &ConfigurePreset::WarnDeprecated, - PresetOptionalBoolHelper, false) - .Bind("uninitialized"_s, &ConfigurePreset::WarnUninitialized, - PresetOptionalBoolHelper, false) - .Bind("unusedCli"_s, &ConfigurePreset::WarnUnusedCli, - PresetOptionalBoolHelper, false) - .Bind("systemVars"_s, &ConfigurePreset::WarnSystemVars, - PresetOptionalBoolHelper, false); - -auto const PresetErrorsHelper = - cmJSONObjectHelper( - ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET, false) - .Bind("dev"_s, &ConfigurePreset::ErrorDev, PresetOptionalBoolHelper, false) - .Bind("deprecated"_s, &ConfigurePreset::ErrorDeprecated, - PresetOptionalBoolHelper, false); - -auto const PresetDebugHelper = - cmJSONObjectHelper( - ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET, false) - .Bind("output"_s, &ConfigurePreset::DebugOutput, PresetOptionalBoolHelper, - false) - .Bind("tryCompile"_s, &ConfigurePreset::DebugTryCompile, - PresetOptionalBoolHelper, false) - .Bind("find"_s, &ConfigurePreset::DebugFind, PresetOptionalBoolHelper, - false); - -ReadFileResult ArchToolsetStrategyHelper( - cm::optional& out, const Json::Value* value) -{ - if (!value) { - out = cm::nullopt; - return ReadFileResult::READ_OK; - } - - if (!value->isString()) { - return ReadFileResult::INVALID_PRESET; - } - - if (value->asString() == "set") { - out = ArchToolsetStrategy::Set; - return ReadFileResult::READ_OK; - } - - if (value->asString() == "external") { - out = ArchToolsetStrategy::External; - return ReadFileResult::READ_OK; - } - - return ReadFileResult::INVALID_PRESET; -} - -std::function -ArchToolsetHelper( - std::string ConfigurePreset::*valueField, - cm::optional ConfigurePreset::*strategyField) -{ - auto const objectHelper = - cmJSONObjectHelper( - ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET, false) - .Bind("value", valueField, PresetStringHelper, false) - .Bind("strategy", strategyField, ArchToolsetStrategyHelper, false); - return [valueField, strategyField, objectHelper]( - ConfigurePreset& out, const Json::Value* value) -> ReadFileResult { - if (!value) { - (out.*valueField).clear(); - out.*strategyField = cm::nullopt; - return ReadFileResult::READ_OK; - } - - if (value->isString()) { - out.*valueField = value->asString(); - out.*strategyField = cm::nullopt; - return ReadFileResult::READ_OK; - } - - if (value->isObject()) { - return objectHelper(out, value); - } - - return ReadFileResult::INVALID_PRESET; - }; -} - -auto const ArchitectureHelper = ArchToolsetHelper( - &ConfigurePreset::Architecture, &ConfigurePreset::ArchitectureStrategy); -auto const ToolsetHelper = ArchToolsetHelper( - &ConfigurePreset::Toolset, &ConfigurePreset::ToolsetStrategy); - -auto const ConfigurePresetHelper = - cmJSONObjectHelper( - ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET, false) - .Bind("name"_s, &ConfigurePreset::Name, PresetStringHelper) - .Bind("inherits"_s, &ConfigurePreset::Inherits, - PresetVectorOneOrMoreStringHelper, false) - .Bind("hidden"_s, &ConfigurePreset::Hidden, PresetBoolHelper, false) - .Bind("vendor"_s, nullptr, - VendorHelper(ReadFileResult::INVALID_PRESET), false) - .Bind("displayName"_s, &ConfigurePreset::DisplayName, PresetStringHelper, - false) - .Bind("description"_s, &ConfigurePreset::Description, PresetStringHelper, - false) - .Bind("generator"_s, &ConfigurePreset::Generator, PresetStringHelper, - false) - .Bind("architecture"_s, ArchitectureHelper, false) - .Bind("toolset"_s, ToolsetHelper, false) - .Bind("toolchainFile"_s, &ConfigurePreset::ToolchainFile, - PresetStringHelper, false) - .Bind("binaryDir"_s, &ConfigurePreset::BinaryDir, PresetStringHelper, - false) - .Bind("installDir"_s, &ConfigurePreset::InstallDir, PresetStringHelper, - false) - .Bind("cmakeExecutable"_s, nullptr, PresetStringHelper, false) - .Bind("cacheVariables"_s, &ConfigurePreset::CacheVariables, - VariablesHelper, false) - .Bind("environment"_s, &ConfigurePreset::Environment, EnvironmentMapHelper, - false) - .Bind("warnings"_s, PresetWarningsHelper, false) - .Bind("errors"_s, PresetErrorsHelper, false) - .Bind("debug"_s, PresetDebugHelper, false) - .Bind("condition"_s, &ConfigurePreset::ConditionEvaluator, - PresetConditionHelper, false); - -auto const BuildPresetHelper = - cmJSONObjectHelper( - ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET, false) - .Bind("name"_s, &BuildPreset::Name, PresetStringHelper) - .Bind("inherits"_s, &BuildPreset::Inherits, - PresetVectorOneOrMoreStringHelper, false) - .Bind("hidden"_s, &BuildPreset::Hidden, PresetBoolHelper, false) - .Bind("vendor"_s, nullptr, - VendorHelper(ReadFileResult::INVALID_PRESET), false) - .Bind("displayName"_s, &BuildPreset::DisplayName, PresetStringHelper, - false) - .Bind("description"_s, &BuildPreset::Description, PresetStringHelper, - false) - .Bind("environment"_s, &BuildPreset::Environment, EnvironmentMapHelper, - false) - .Bind("configurePreset"_s, &BuildPreset::ConfigurePreset, - PresetStringHelper, false) - .Bind("inheritConfigureEnvironment"_s, - &BuildPreset::InheritConfigureEnvironment, PresetOptionalBoolHelper, - false) - .Bind("jobs"_s, &BuildPreset::Jobs, PresetOptionalIntHelper, false) - .Bind("targets"_s, &BuildPreset::Targets, - PresetVectorOneOrMoreStringHelper, false) - .Bind("configuration"_s, &BuildPreset::Configuration, PresetStringHelper, - false) - .Bind("cleanFirst"_s, &BuildPreset::CleanFirst, PresetOptionalBoolHelper, - false) - .Bind("verbose"_s, &BuildPreset::Verbose, PresetOptionalBoolHelper, false) - .Bind("nativeToolOptions"_s, &BuildPreset::NativeToolOptions, - PresetVectorStringHelper, false) - .Bind("condition"_s, &BuildPreset::ConditionEvaluator, - PresetConditionHelper, false); - -ReadFileResult TestPresetOutputVerbosityHelper( - TestPreset::OutputOptions::VerbosityEnum& out, const Json::Value* value) -{ - if (!value) { - out = TestPreset::OutputOptions::VerbosityEnum::Default; - return ReadFileResult::READ_OK; - } - - if (!value->isString()) { - return ReadFileResult::INVALID_PRESET; - } - - if (value->asString() == "default") { - out = TestPreset::OutputOptions::VerbosityEnum::Default; - return ReadFileResult::READ_OK; - } - - if (value->asString() == "verbose") { - out = TestPreset::OutputOptions::VerbosityEnum::Verbose; - return ReadFileResult::READ_OK; - } - - if (value->asString() == "extra") { - out = TestPreset::OutputOptions::VerbosityEnum::Extra; - return ReadFileResult::READ_OK; - } - - return ReadFileResult::INVALID_PRESET; -} - -auto const TestPresetOptionalOutputVerbosityHelper = - cmJSONOptionalHelper(ReadFileResult::READ_OK, - TestPresetOutputVerbosityHelper); - -auto const TestPresetOptionalOutputHelper = - cmJSONOptionalHelper( - ReadFileResult::READ_OK, - cmJSONObjectHelper( - ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET, false) - .Bind("shortProgress"_s, &TestPreset::OutputOptions::ShortProgress, - PresetOptionalBoolHelper, false) - .Bind("verbosity"_s, &TestPreset::OutputOptions::Verbosity, - TestPresetOptionalOutputVerbosityHelper, false) - .Bind("debug"_s, &TestPreset::OutputOptions::Debug, - PresetOptionalBoolHelper, false) - .Bind("outputOnFailure"_s, &TestPreset::OutputOptions::OutputOnFailure, - PresetOptionalBoolHelper, false) - .Bind("quiet"_s, &TestPreset::OutputOptions::Quiet, - PresetOptionalBoolHelper, false) - .Bind("outputLogFile"_s, &TestPreset::OutputOptions::OutputLogFile, - PresetStringHelper, false) - .Bind("labelSummary"_s, &TestPreset::OutputOptions::LabelSummary, - PresetOptionalBoolHelper, false) - .Bind("subprojectSummary"_s, - &TestPreset::OutputOptions::SubprojectSummary, - PresetOptionalBoolHelper, false) - .Bind("maxPassedTestOutputSize"_s, - &TestPreset::OutputOptions::MaxPassedTestOutputSize, - PresetOptionalIntHelper, false) - .Bind("maxFailedTestOutputSize"_s, - &TestPreset::OutputOptions::MaxFailedTestOutputSize, - PresetOptionalIntHelper, false) - .Bind("maxTestNameWidth"_s, &TestPreset::OutputOptions::MaxTestNameWidth, - PresetOptionalIntHelper, false)); - -auto const TestPresetOptionalFilterIncludeIndexObjectHelper = - cmJSONOptionalHelper( - ReadFileResult::READ_OK, - cmJSONObjectHelper(ReadFileResult::READ_OK, - ReadFileResult::INVALID_PRESET) - .Bind("start"_s, &TestPreset::IncludeOptions::IndexOptions::Start, - PresetOptionalIntHelper, false) - .Bind("end"_s, &TestPreset::IncludeOptions::IndexOptions::End, - PresetOptionalIntHelper, false) - .Bind("stride"_s, &TestPreset::IncludeOptions::IndexOptions::Stride, - PresetOptionalIntHelper, false) - .Bind("specificTests"_s, - &TestPreset::IncludeOptions::IndexOptions::SpecificTests, - PresetVectorIntHelper, false)); - -ReadFileResult TestPresetOptionalFilterIncludeIndexHelper( - cm::optional& out, +cmCMakePresetsGraph::ReadFileResult EnvironmentMapHelper( + std::map>& out, const Json::Value* value) { - if (!value) { - out = cm::nullopt; - return ReadFileResult::READ_OK; - } + static auto const helper = + cmJSONMapHelper, ReadFileResult>( + ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET, + EnvironmentHelper); - if (value->isString()) { - out.emplace(); - out->IndexFile = value->asString(); - return ReadFileResult::READ_OK; - } - - if (value->isObject()) { - return TestPresetOptionalFilterIncludeIndexObjectHelper(out, value); - } - - return ReadFileResult::INVALID_PRESET; + return helper(out, value); } - -auto const TestPresetOptionalFilterIncludeHelper = - cmJSONOptionalHelper( - ReadFileResult::READ_OK, - cmJSONObjectHelper( - ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET) - .Bind("name"_s, &TestPreset::IncludeOptions::Name, PresetStringHelper, - false) - .Bind("label"_s, &TestPreset::IncludeOptions::Label, PresetStringHelper, - false) - .Bind("index"_s, &TestPreset::IncludeOptions::Index, - TestPresetOptionalFilterIncludeIndexHelper, false) - .Bind("useUnion"_s, &TestPreset::IncludeOptions::UseUnion, - PresetOptionalBoolHelper, false)); - -auto const TestPresetOptionalFilterExcludeFixturesHelper = - cmJSONOptionalHelper( - ReadFileResult::READ_OK, - cmJSONObjectHelper(ReadFileResult::READ_OK, - ReadFileResult::INVALID_PRESET) - .Bind("any"_s, &TestPreset::ExcludeOptions::FixturesOptions::Any, - PresetStringHelper, false) - .Bind("setup"_s, &TestPreset::ExcludeOptions::FixturesOptions::Setup, - PresetStringHelper, false) - .Bind("cleanup"_s, &TestPreset::ExcludeOptions::FixturesOptions::Cleanup, - PresetStringHelper, false)); - -auto const TestPresetOptionalFilterExcludeHelper = - cmJSONOptionalHelper( - ReadFileResult::READ_OK, - cmJSONObjectHelper( - ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET) - .Bind("name"_s, &TestPreset::ExcludeOptions::Name, PresetStringHelper, - false) - .Bind("label"_s, &TestPreset::ExcludeOptions::Label, PresetStringHelper, - false) - .Bind("fixtures"_s, &TestPreset::ExcludeOptions::Fixtures, - TestPresetOptionalFilterExcludeFixturesHelper, false)); - -ReadFileResult TestPresetExecutionShowOnlyHelper( - TestPreset::ExecutionOptions::ShowOnlyEnum& out, const Json::Value* value) -{ - if (!value || !value->isString()) { - return ReadFileResult::INVALID_PRESET; - } - - if (value->asString() == "human") { - out = TestPreset::ExecutionOptions::ShowOnlyEnum::Human; - return ReadFileResult::READ_OK; - } - - if (value->asString() == "json-v1") { - out = TestPreset::ExecutionOptions::ShowOnlyEnum::JsonV1; - return ReadFileResult::READ_OK; - } - - return ReadFileResult::INVALID_PRESET; -} - -auto const TestPresetOptionalExecutionShowOnlyHelper = - cmJSONOptionalHelper(ReadFileResult::READ_OK, - TestPresetExecutionShowOnlyHelper); - -ReadFileResult TestPresetExecutionModeHelper( - TestPreset::ExecutionOptions::RepeatOptions::ModeEnum& out, - const Json::Value* value) -{ - if (!value) { - return ReadFileResult::READ_OK; - } - - if (!value->isString()) { - return ReadFileResult::INVALID_PRESET; - } - - if (value->asString() == "until-fail") { - out = TestPreset::ExecutionOptions::RepeatOptions::ModeEnum::UntilFail; - return ReadFileResult::READ_OK; - } - - if (value->asString() == "until-pass") { - out = TestPreset::ExecutionOptions::RepeatOptions::ModeEnum::UntilPass; - return ReadFileResult::READ_OK; - } - - if (value->asString() == "after-timeout") { - out = TestPreset::ExecutionOptions::RepeatOptions::ModeEnum::AfterTimeout; - return ReadFileResult::READ_OK; - } - - return ReadFileResult::INVALID_PRESET; -} - -auto const TestPresetOptionalExecutionRepeatHelper = - cmJSONOptionalHelper( - ReadFileResult::READ_OK, - cmJSONObjectHelper(ReadFileResult::READ_OK, - ReadFileResult::INVALID_PRESET) - .Bind("mode"_s, &TestPreset::ExecutionOptions::RepeatOptions::Mode, - TestPresetExecutionModeHelper, true) - .Bind("count"_s, &TestPreset::ExecutionOptions::RepeatOptions::Count, - PresetIntHelper, true)); - -ReadFileResult TestPresetExecutionNoTestsActionHelper( - TestPreset::ExecutionOptions::NoTestsActionEnum& out, - const Json::Value* value) -{ - if (!value) { - out = TestPreset::ExecutionOptions::NoTestsActionEnum::Default; - return ReadFileResult::READ_OK; - } - - if (!value->isString()) { - return ReadFileResult::INVALID_PRESET; - } - - if (value->asString() == "default") { - out = TestPreset::ExecutionOptions::NoTestsActionEnum::Default; - return ReadFileResult::READ_OK; - } - - if (value->asString() == "error") { - out = TestPreset::ExecutionOptions::NoTestsActionEnum::Error; - return ReadFileResult::READ_OK; - } - - if (value->asString() == "ignore") { - out = TestPreset::ExecutionOptions::NoTestsActionEnum::Ignore; - return ReadFileResult::READ_OK; - } - - return ReadFileResult::INVALID_PRESET; -} - -auto const TestPresetOptionalExecutionNoTestsActionHelper = - cmJSONOptionalHelper(ReadFileResult::READ_OK, - TestPresetExecutionNoTestsActionHelper); - -auto const TestPresetExecutionHelper = - cmJSONOptionalHelper( - ReadFileResult::READ_OK, - cmJSONObjectHelper( - ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET) - .Bind("stopOnFailure"_s, &TestPreset::ExecutionOptions::StopOnFailure, - PresetOptionalBoolHelper, false) - .Bind("enableFailover"_s, &TestPreset::ExecutionOptions::EnableFailover, - PresetOptionalBoolHelper, false) - .Bind("jobs"_s, &TestPreset::ExecutionOptions::Jobs, - PresetOptionalIntHelper, false) - .Bind("resourceSpecFile"_s, - &TestPreset::ExecutionOptions::ResourceSpecFile, - PresetStringHelper, false) - .Bind("testLoad"_s, &TestPreset::ExecutionOptions::TestLoad, - PresetOptionalIntHelper, false) - .Bind("showOnly"_s, &TestPreset::ExecutionOptions::ShowOnly, - TestPresetOptionalExecutionShowOnlyHelper, false) - .Bind("repeat"_s, &TestPreset::ExecutionOptions::Repeat, - TestPresetOptionalExecutionRepeatHelper, false) - .Bind("interactiveDebugging"_s, - &TestPreset::ExecutionOptions::InteractiveDebugging, - PresetOptionalBoolHelper, false) - .Bind("scheduleRandom"_s, &TestPreset::ExecutionOptions::ScheduleRandom, - PresetOptionalBoolHelper, false) - .Bind("timeout"_s, &TestPreset::ExecutionOptions::Timeout, - PresetOptionalIntHelper, false) - .Bind("noTestsAction"_s, &TestPreset::ExecutionOptions::NoTestsAction, - TestPresetOptionalExecutionNoTestsActionHelper, false)); - -auto const TestPresetFilterHelper = - cmJSONOptionalHelper( - ReadFileResult::READ_OK, - cmJSONObjectHelper( - ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET) - .Bind("include"_s, &TestPreset::FilterOptions::Include, - TestPresetOptionalFilterIncludeHelper, false) - .Bind("exclude"_s, &TestPreset::FilterOptions::Exclude, - TestPresetOptionalFilterExcludeHelper, false)); - -auto const TestPresetHelper = - cmJSONObjectHelper( - ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET, false) - .Bind("name"_s, &TestPreset::Name, PresetStringHelper) - .Bind("inherits"_s, &TestPreset::Inherits, - PresetVectorOneOrMoreStringHelper, false) - .Bind("hidden"_s, &TestPreset::Hidden, PresetBoolHelper, false) - .Bind("vendor"_s, nullptr, - VendorHelper(ReadFileResult::INVALID_PRESET), false) - .Bind("displayName"_s, &TestPreset::DisplayName, PresetStringHelper, false) - .Bind("description"_s, &TestPreset::Description, PresetStringHelper, false) - .Bind("environment"_s, &TestPreset::Environment, EnvironmentMapHelper, - false) - .Bind("configurePreset"_s, &TestPreset::ConfigurePreset, - PresetStringHelper, false) - .Bind("inheritConfigureEnvironment"_s, - &TestPreset::InheritConfigureEnvironment, PresetOptionalBoolHelper, - false) - .Bind("configuration"_s, &TestPreset::Configuration, PresetStringHelper, - false) - .Bind("overwriteConfigurationFile"_s, - &TestPreset::OverwriteConfigurationFile, PresetVectorStringHelper, - false) - .Bind("output"_s, &TestPreset::Output, TestPresetOptionalOutputHelper, - false) - .Bind("filter"_s, &TestPreset::Filter, TestPresetFilterHelper, false) - .Bind("execution"_s, &TestPreset::Execution, TestPresetExecutionHelper, - false) - .Bind("condition"_s, &TestPreset::ConditionEvaluator, - PresetConditionHelper, false); - -auto const ConfigurePresetsHelper = - cmJSONVectorHelper( - ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESETS, - ConfigurePresetHelper); - -auto const BuildPresetsHelper = - cmJSONVectorHelper( - ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESETS, - BuildPresetHelper); - -auto const TestPresetsHelper = cmJSONVectorHelper( - ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESETS, TestPresetHelper); - -auto const CMakeVersionUIntHelper = cmJSONUIntHelper( - ReadFileResult::READ_OK, ReadFileResult::INVALID_VERSION); - -auto const CMakeVersionHelper = - cmJSONObjectHelper( - ReadFileResult::READ_OK, ReadFileResult::INVALID_CMAKE_VERSION, false) - .Bind("major"_s, &CMakeVersion::Major, CMakeVersionUIntHelper, false) - .Bind("minor"_s, &CMakeVersion::Minor, CMakeVersionUIntHelper, false) - .Bind("patch"_s, &CMakeVersion::Patch, CMakeVersionUIntHelper, false); - -auto const RootPresetsHelper = - cmJSONObjectHelper( - ReadFileResult::READ_OK, ReadFileResult::INVALID_ROOT, false) - .Bind("version"_s, nullptr, VersionHelper) - .Bind("configurePresets"_s, &RootPresets::ConfigurePresets, - ConfigurePresetsHelper, false) - .Bind("buildPresets"_s, &RootPresets::BuildPresets, BuildPresetsHelper, - false) - .Bind("testPresets"_s, &RootPresets::TestPresets, TestPresetsHelper, false) - .Bind("cmakeMinimumRequired"_s, &RootPresets::CMakeMinimumRequired, - CMakeVersionHelper, false) - .Bind("vendor"_s, nullptr, - VendorHelper(ReadFileResult::INVALID_ROOT), false); } cmCMakePresetsGraph::ReadFileResult cmCMakePresetsGraph::ReadJSONFile( diff --git a/Source/cmCMakePresetsGraphReadJSONBuildPresets.cxx b/Source/cmCMakePresetsGraphReadJSONBuildPresets.cxx new file mode 100644 index 0000000000..ef605d15fe --- /dev/null +++ b/Source/cmCMakePresetsGraphReadJSONBuildPresets.cxx @@ -0,0 +1,75 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + +#include "cmCMakePresetsGraph.h" +#include "cmCMakePresetsGraphInternal.h" +#include "cmJSONHelpers.h" + +namespace { +using ReadFileResult = cmCMakePresetsGraph::ReadFileResult; +using BuildPreset = cmCMakePresetsGraph::BuildPreset; + +auto const BuildPresetHelper = + cmJSONObjectHelper( + ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET, false) + .Bind("name"_s, &BuildPreset::Name, + cmCMakePresetsGraphInternal::PresetStringHelper) + .Bind("inherits"_s, &BuildPreset::Inherits, + cmCMakePresetsGraphInternal::PresetVectorOneOrMoreStringHelper, + false) + .Bind("hidden"_s, &BuildPreset::Hidden, + cmCMakePresetsGraphInternal::PresetBoolHelper, false) + .Bind("vendor"_s, nullptr, + cmCMakePresetsGraphInternal::VendorHelper( + ReadFileResult::INVALID_PRESET), + false) + .Bind("displayName"_s, &BuildPreset::DisplayName, + cmCMakePresetsGraphInternal::PresetStringHelper, false) + .Bind("description"_s, &BuildPreset::Description, + cmCMakePresetsGraphInternal::PresetStringHelper, false) + .Bind("environment"_s, &BuildPreset::Environment, + cmCMakePresetsGraphInternal::EnvironmentMapHelper, false) + .Bind("configurePreset"_s, &BuildPreset::ConfigurePreset, + cmCMakePresetsGraphInternal::PresetStringHelper, false) + .Bind("inheritConfigureEnvironment"_s, + &BuildPreset::InheritConfigureEnvironment, + cmCMakePresetsGraphInternal::PresetOptionalBoolHelper, false) + .Bind("jobs"_s, &BuildPreset::Jobs, + cmCMakePresetsGraphInternal::PresetOptionalIntHelper, false) + .Bind("targets"_s, &BuildPreset::Targets, + cmCMakePresetsGraphInternal::PresetVectorOneOrMoreStringHelper, + false) + .Bind("configuration"_s, &BuildPreset::Configuration, + cmCMakePresetsGraphInternal::PresetStringHelper, false) + .Bind("cleanFirst"_s, &BuildPreset::CleanFirst, + cmCMakePresetsGraphInternal::PresetOptionalBoolHelper, false) + .Bind("verbose"_s, &BuildPreset::Verbose, + cmCMakePresetsGraphInternal::PresetOptionalBoolHelper, false) + .Bind("nativeToolOptions"_s, &BuildPreset::NativeToolOptions, + cmCMakePresetsGraphInternal::PresetVectorStringHelper, false) + .Bind("condition"_s, &BuildPreset::ConditionEvaluator, + cmCMakePresetsGraphInternal::PresetConditionHelper, false); +} + +namespace cmCMakePresetsGraphInternal { +ReadFileResult BuildPresetsHelper(std::vector& out, + const Json::Value* value) +{ + static auto const helper = cmJSONVectorHelper( + ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESETS, + BuildPresetHelper); + + return helper(out, value); +} +} diff --git a/Source/cmCMakePresetsGraphReadJSONConfigurePresets.cxx b/Source/cmCMakePresetsGraphReadJSONConfigurePresets.cxx new file mode 100644 index 0000000000..0f44546f4d --- /dev/null +++ b/Source/cmCMakePresetsGraphReadJSONConfigurePresets.cxx @@ -0,0 +1,228 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + +#include "cmCMakePresetsGraph.h" +#include "cmCMakePresetsGraphInternal.h" +#include "cmJSONHelpers.h" + +namespace { +using ReadFileResult = cmCMakePresetsGraph::ReadFileResult; +using CacheVariable = cmCMakePresetsGraph::CacheVariable; +using ConfigurePreset = cmCMakePresetsGraph::ConfigurePreset; +using ArchToolsetStrategy = cmCMakePresetsGraph::ArchToolsetStrategy; + +ReadFileResult ArchToolsetStrategyHelper( + cm::optional& out, const Json::Value* value) +{ + if (!value) { + out = cm::nullopt; + return ReadFileResult::READ_OK; + } + + if (!value->isString()) { + return ReadFileResult::INVALID_PRESET; + } + + if (value->asString() == "set") { + out = ArchToolsetStrategy::Set; + return ReadFileResult::READ_OK; + } + + if (value->asString() == "external") { + out = ArchToolsetStrategy::External; + return ReadFileResult::READ_OK; + } + + return ReadFileResult::INVALID_PRESET; +} + +std::function +ArchToolsetHelper( + std::string ConfigurePreset::*valueField, + cm::optional ConfigurePreset::*strategyField) +{ + auto const objectHelper = + cmJSONObjectHelper( + ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET, false) + .Bind("value", valueField, + cmCMakePresetsGraphInternal::PresetStringHelper, false) + .Bind("strategy", strategyField, ArchToolsetStrategyHelper, false); + return [valueField, strategyField, objectHelper]( + ConfigurePreset& out, const Json::Value* value) -> ReadFileResult { + if (!value) { + (out.*valueField).clear(); + out.*strategyField = cm::nullopt; + return ReadFileResult::READ_OK; + } + + if (value->isString()) { + out.*valueField = value->asString(); + out.*strategyField = cm::nullopt; + return ReadFileResult::READ_OK; + } + + if (value->isObject()) { + return objectHelper(out, value); + } + + return ReadFileResult::INVALID_PRESET; + }; +} + +auto const ArchitectureHelper = ArchToolsetHelper( + &ConfigurePreset::Architecture, &ConfigurePreset::ArchitectureStrategy); +auto const ToolsetHelper = ArchToolsetHelper( + &ConfigurePreset::Toolset, &ConfigurePreset::ToolsetStrategy); + +auto const VariableStringHelper = cmJSONStringHelper( + ReadFileResult::READ_OK, ReadFileResult::INVALID_VARIABLE); + +ReadFileResult VariableValueHelper(std::string& out, const Json::Value* value) +{ + if (!value) { + out.clear(); + return ReadFileResult::READ_OK; + } + + if (value->isBool()) { + out = value->asBool() ? "TRUE" : "FALSE"; + return ReadFileResult::READ_OK; + } + + return VariableStringHelper(out, value); +} + +auto const VariableObjectHelper = + cmJSONObjectHelper( + ReadFileResult::READ_OK, ReadFileResult::INVALID_VARIABLE, false) + .Bind("type"_s, &CacheVariable::Type, VariableStringHelper, false) + .Bind("value"_s, &CacheVariable::Value, VariableValueHelper); + +ReadFileResult VariableHelper(cm::optional& out, + const Json::Value* value) +{ + if (value->isBool()) { + out = CacheVariable{ + /*Type=*/"BOOL", + /*Value=*/value->asBool() ? "TRUE" : "FALSE", + }; + return ReadFileResult::READ_OK; + } + if (value->isString()) { + out = CacheVariable{ + /*Type=*/"", + /*Value=*/value->asString(), + }; + return ReadFileResult::READ_OK; + } + if (value->isObject()) { + out.emplace(); + return VariableObjectHelper(*out, value); + } + if (value->isNull()) { + out = cm::nullopt; + return ReadFileResult::READ_OK; + } + return ReadFileResult::INVALID_VARIABLE; +} + +auto const VariablesHelper = + cmJSONMapHelper, ReadFileResult>( + ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET, VariableHelper); + +auto const PresetWarningsHelper = + cmJSONObjectHelper( + ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET, false) + .Bind("dev"_s, &ConfigurePreset::WarnDev, + cmCMakePresetsGraphInternal::PresetOptionalBoolHelper, false) + .Bind("deprecated"_s, &ConfigurePreset::WarnDeprecated, + cmCMakePresetsGraphInternal::PresetOptionalBoolHelper, false) + .Bind("uninitialized"_s, &ConfigurePreset::WarnUninitialized, + cmCMakePresetsGraphInternal::PresetOptionalBoolHelper, false) + .Bind("unusedCli"_s, &ConfigurePreset::WarnUnusedCli, + cmCMakePresetsGraphInternal::PresetOptionalBoolHelper, false) + .Bind("systemVars"_s, &ConfigurePreset::WarnSystemVars, + cmCMakePresetsGraphInternal::PresetOptionalBoolHelper, false); + +auto const PresetErrorsHelper = + cmJSONObjectHelper( + ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET, false) + .Bind("dev"_s, &ConfigurePreset::ErrorDev, + cmCMakePresetsGraphInternal::PresetOptionalBoolHelper, false) + .Bind("deprecated"_s, &ConfigurePreset::ErrorDeprecated, + cmCMakePresetsGraphInternal::PresetOptionalBoolHelper, false); + +auto const PresetDebugHelper = + cmJSONObjectHelper( + ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET, false) + .Bind("output"_s, &ConfigurePreset::DebugOutput, + cmCMakePresetsGraphInternal::PresetOptionalBoolHelper, false) + .Bind("tryCompile"_s, &ConfigurePreset::DebugTryCompile, + cmCMakePresetsGraphInternal::PresetOptionalBoolHelper, false) + .Bind("find"_s, &ConfigurePreset::DebugFind, + cmCMakePresetsGraphInternal::PresetOptionalBoolHelper, false); + +auto const ConfigurePresetHelper = + cmJSONObjectHelper( + ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET, false) + .Bind("name"_s, &ConfigurePreset::Name, + cmCMakePresetsGraphInternal::PresetStringHelper) + .Bind("inherits"_s, &ConfigurePreset::Inherits, + cmCMakePresetsGraphInternal::PresetVectorOneOrMoreStringHelper, + false) + .Bind("hidden"_s, &ConfigurePreset::Hidden, + cmCMakePresetsGraphInternal::PresetBoolHelper, false) + .Bind("vendor"_s, nullptr, + cmCMakePresetsGraphInternal::VendorHelper( + ReadFileResult::INVALID_PRESET), + false) + .Bind("displayName"_s, &ConfigurePreset::DisplayName, + cmCMakePresetsGraphInternal::PresetStringHelper, false) + .Bind("description"_s, &ConfigurePreset::Description, + cmCMakePresetsGraphInternal::PresetStringHelper, false) + .Bind("generator"_s, &ConfigurePreset::Generator, + cmCMakePresetsGraphInternal::PresetStringHelper, false) + .Bind("architecture"_s, ArchitectureHelper, false) + .Bind("toolset"_s, ToolsetHelper, false) + .Bind("toolchainFile"_s, &ConfigurePreset::ToolchainFile, + cmCMakePresetsGraphInternal::PresetStringHelper, false) + .Bind("binaryDir"_s, &ConfigurePreset::BinaryDir, + cmCMakePresetsGraphInternal::PresetStringHelper, false) + .Bind("installDir"_s, &ConfigurePreset::InstallDir, + cmCMakePresetsGraphInternal::PresetStringHelper, false) + .Bind("cmakeExecutable"_s, nullptr, + cmCMakePresetsGraphInternal::PresetStringHelper, false) + .Bind("cacheVariables"_s, &ConfigurePreset::CacheVariables, + VariablesHelper, false) + .Bind("environment"_s, &ConfigurePreset::Environment, + cmCMakePresetsGraphInternal::EnvironmentMapHelper, false) + .Bind("warnings"_s, PresetWarningsHelper, false) + .Bind("errors"_s, PresetErrorsHelper, false) + .Bind("debug"_s, PresetDebugHelper, false) + .Bind("condition"_s, &ConfigurePreset::ConditionEvaluator, + cmCMakePresetsGraphInternal::PresetConditionHelper, false); +} + +namespace cmCMakePresetsGraphInternal { +ReadFileResult ConfigurePresetsHelper(std::vector& out, + const Json::Value* value) +{ + static auto const helper = + cmJSONVectorHelper( + ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESETS, + ConfigurePresetHelper); + + return helper(out, value); +} +} diff --git a/Source/cmCMakePresetsGraphReadJSONTestPresets.cxx b/Source/cmCMakePresetsGraphReadJSONTestPresets.cxx new file mode 100644 index 0000000000..4d6474a73d --- /dev/null +++ b/Source/cmCMakePresetsGraphReadJSONTestPresets.cxx @@ -0,0 +1,360 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + +#include "cmCMakePresetsGraph.h" +#include "cmCMakePresetsGraphInternal.h" +#include "cmJSONHelpers.h" + +namespace { +using ReadFileResult = cmCMakePresetsGraph::ReadFileResult; +using TestPreset = cmCMakePresetsGraph::TestPreset; + +ReadFileResult TestPresetOutputVerbosityHelper( + TestPreset::OutputOptions::VerbosityEnum& out, const Json::Value* value) +{ + if (!value) { + out = TestPreset::OutputOptions::VerbosityEnum::Default; + return ReadFileResult::READ_OK; + } + + if (!value->isString()) { + return ReadFileResult::INVALID_PRESET; + } + + if (value->asString() == "default") { + out = TestPreset::OutputOptions::VerbosityEnum::Default; + return ReadFileResult::READ_OK; + } + + if (value->asString() == "verbose") { + out = TestPreset::OutputOptions::VerbosityEnum::Verbose; + return ReadFileResult::READ_OK; + } + + if (value->asString() == "extra") { + out = TestPreset::OutputOptions::VerbosityEnum::Extra; + return ReadFileResult::READ_OK; + } + + return ReadFileResult::INVALID_PRESET; +} + +auto const TestPresetOptionalOutputVerbosityHelper = + cmJSONOptionalHelper(ReadFileResult::READ_OK, + TestPresetOutputVerbosityHelper); + +auto const TestPresetOptionalOutputHelper = + cmJSONOptionalHelper( + ReadFileResult::READ_OK, + cmJSONObjectHelper( + ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET, false) + .Bind("shortProgress"_s, &TestPreset::OutputOptions::ShortProgress, + cmCMakePresetsGraphInternal::PresetOptionalBoolHelper, false) + .Bind("verbosity"_s, &TestPreset::OutputOptions::Verbosity, + TestPresetOptionalOutputVerbosityHelper, false) + .Bind("debug"_s, &TestPreset::OutputOptions::Debug, + cmCMakePresetsGraphInternal::PresetOptionalBoolHelper, false) + .Bind("outputOnFailure"_s, &TestPreset::OutputOptions::OutputOnFailure, + cmCMakePresetsGraphInternal::PresetOptionalBoolHelper, false) + .Bind("quiet"_s, &TestPreset::OutputOptions::Quiet, + cmCMakePresetsGraphInternal::PresetOptionalBoolHelper, false) + .Bind("outputLogFile"_s, &TestPreset::OutputOptions::OutputLogFile, + cmCMakePresetsGraphInternal::PresetStringHelper, false) + .Bind("labelSummary"_s, &TestPreset::OutputOptions::LabelSummary, + cmCMakePresetsGraphInternal::PresetOptionalBoolHelper, false) + .Bind("subprojectSummary"_s, + &TestPreset::OutputOptions::SubprojectSummary, + cmCMakePresetsGraphInternal::PresetOptionalBoolHelper, false) + .Bind("maxPassedTestOutputSize"_s, + &TestPreset::OutputOptions::MaxPassedTestOutputSize, + cmCMakePresetsGraphInternal::PresetOptionalIntHelper, false) + .Bind("maxFailedTestOutputSize"_s, + &TestPreset::OutputOptions::MaxFailedTestOutputSize, + cmCMakePresetsGraphInternal::PresetOptionalIntHelper, false) + .Bind("maxTestNameWidth"_s, &TestPreset::OutputOptions::MaxTestNameWidth, + cmCMakePresetsGraphInternal::PresetOptionalIntHelper, false)); + +auto const TestPresetOptionalFilterIncludeIndexObjectHelper = + cmJSONOptionalHelper( + ReadFileResult::READ_OK, + cmJSONObjectHelper(ReadFileResult::READ_OK, + ReadFileResult::INVALID_PRESET) + .Bind("start"_s, &TestPreset::IncludeOptions::IndexOptions::Start, + cmCMakePresetsGraphInternal::PresetOptionalIntHelper, false) + .Bind("end"_s, &TestPreset::IncludeOptions::IndexOptions::End, + cmCMakePresetsGraphInternal::PresetOptionalIntHelper, false) + .Bind("stride"_s, &TestPreset::IncludeOptions::IndexOptions::Stride, + cmCMakePresetsGraphInternal::PresetOptionalIntHelper, false) + .Bind("specificTests"_s, + &TestPreset::IncludeOptions::IndexOptions::SpecificTests, + cmCMakePresetsGraphInternal::PresetVectorIntHelper, false)); + +ReadFileResult TestPresetOptionalFilterIncludeIndexHelper( + cm::optional& out, + const Json::Value* value) +{ + if (!value) { + out = cm::nullopt; + return ReadFileResult::READ_OK; + } + + if (value->isString()) { + out.emplace(); + out->IndexFile = value->asString(); + return ReadFileResult::READ_OK; + } + + if (value->isObject()) { + return TestPresetOptionalFilterIncludeIndexObjectHelper(out, value); + } + + return ReadFileResult::INVALID_PRESET; +} + +auto const TestPresetOptionalFilterIncludeHelper = + cmJSONOptionalHelper( + ReadFileResult::READ_OK, + cmJSONObjectHelper( + ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET) + .Bind("name"_s, &TestPreset::IncludeOptions::Name, + cmCMakePresetsGraphInternal::PresetStringHelper, false) + .Bind("label"_s, &TestPreset::IncludeOptions::Label, + cmCMakePresetsGraphInternal::PresetStringHelper, false) + .Bind("index"_s, &TestPreset::IncludeOptions::Index, + TestPresetOptionalFilterIncludeIndexHelper, false) + .Bind("useUnion"_s, &TestPreset::IncludeOptions::UseUnion, + cmCMakePresetsGraphInternal::PresetOptionalBoolHelper, false)); + +auto const TestPresetOptionalFilterExcludeFixturesHelper = + cmJSONOptionalHelper( + ReadFileResult::READ_OK, + cmJSONObjectHelper(ReadFileResult::READ_OK, + ReadFileResult::INVALID_PRESET) + .Bind("any"_s, &TestPreset::ExcludeOptions::FixturesOptions::Any, + cmCMakePresetsGraphInternal::PresetStringHelper, false) + .Bind("setup"_s, &TestPreset::ExcludeOptions::FixturesOptions::Setup, + cmCMakePresetsGraphInternal::PresetStringHelper, false) + .Bind("cleanup"_s, &TestPreset::ExcludeOptions::FixturesOptions::Cleanup, + cmCMakePresetsGraphInternal::PresetStringHelper, false)); + +auto const TestPresetOptionalFilterExcludeHelper = + cmJSONOptionalHelper( + ReadFileResult::READ_OK, + cmJSONObjectHelper( + ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET) + .Bind("name"_s, &TestPreset::ExcludeOptions::Name, + cmCMakePresetsGraphInternal::PresetStringHelper, false) + .Bind("label"_s, &TestPreset::ExcludeOptions::Label, + cmCMakePresetsGraphInternal::PresetStringHelper, false) + .Bind("fixtures"_s, &TestPreset::ExcludeOptions::Fixtures, + TestPresetOptionalFilterExcludeFixturesHelper, false)); + +ReadFileResult TestPresetExecutionShowOnlyHelper( + TestPreset::ExecutionOptions::ShowOnlyEnum& out, const Json::Value* value) +{ + if (!value || !value->isString()) { + return ReadFileResult::INVALID_PRESET; + } + + if (value->asString() == "human") { + out = TestPreset::ExecutionOptions::ShowOnlyEnum::Human; + return ReadFileResult::READ_OK; + } + + if (value->asString() == "json-v1") { + out = TestPreset::ExecutionOptions::ShowOnlyEnum::JsonV1; + return ReadFileResult::READ_OK; + } + + return ReadFileResult::INVALID_PRESET; +} + +auto const TestPresetOptionalExecutionShowOnlyHelper = + cmJSONOptionalHelper(ReadFileResult::READ_OK, + TestPresetExecutionShowOnlyHelper); + +ReadFileResult TestPresetExecutionModeHelper( + TestPreset::ExecutionOptions::RepeatOptions::ModeEnum& out, + const Json::Value* value) +{ + if (!value) { + return ReadFileResult::READ_OK; + } + + if (!value->isString()) { + return ReadFileResult::INVALID_PRESET; + } + + if (value->asString() == "until-fail") { + out = TestPreset::ExecutionOptions::RepeatOptions::ModeEnum::UntilFail; + return ReadFileResult::READ_OK; + } + + if (value->asString() == "until-pass") { + out = TestPreset::ExecutionOptions::RepeatOptions::ModeEnum::UntilPass; + return ReadFileResult::READ_OK; + } + + if (value->asString() == "after-timeout") { + out = TestPreset::ExecutionOptions::RepeatOptions::ModeEnum::AfterTimeout; + return ReadFileResult::READ_OK; + } + + return ReadFileResult::INVALID_PRESET; +} + +auto const TestPresetOptionalExecutionRepeatHelper = + cmJSONOptionalHelper( + ReadFileResult::READ_OK, + cmJSONObjectHelper(ReadFileResult::READ_OK, + ReadFileResult::INVALID_PRESET) + .Bind("mode"_s, &TestPreset::ExecutionOptions::RepeatOptions::Mode, + TestPresetExecutionModeHelper, true) + .Bind("count"_s, &TestPreset::ExecutionOptions::RepeatOptions::Count, + cmCMakePresetsGraphInternal::PresetIntHelper, true)); + +ReadFileResult TestPresetExecutionNoTestsActionHelper( + TestPreset::ExecutionOptions::NoTestsActionEnum& out, + const Json::Value* value) +{ + if (!value) { + out = TestPreset::ExecutionOptions::NoTestsActionEnum::Default; + return ReadFileResult::READ_OK; + } + + if (!value->isString()) { + return ReadFileResult::INVALID_PRESET; + } + + if (value->asString() == "default") { + out = TestPreset::ExecutionOptions::NoTestsActionEnum::Default; + return ReadFileResult::READ_OK; + } + + if (value->asString() == "error") { + out = TestPreset::ExecutionOptions::NoTestsActionEnum::Error; + return ReadFileResult::READ_OK; + } + + if (value->asString() == "ignore") { + out = TestPreset::ExecutionOptions::NoTestsActionEnum::Ignore; + return ReadFileResult::READ_OK; + } + + return ReadFileResult::INVALID_PRESET; +} + +auto const TestPresetOptionalExecutionNoTestsActionHelper = + cmJSONOptionalHelper(ReadFileResult::READ_OK, + TestPresetExecutionNoTestsActionHelper); + +auto const TestPresetExecutionHelper = + cmJSONOptionalHelper( + ReadFileResult::READ_OK, + cmJSONObjectHelper( + ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET) + .Bind("stopOnFailure"_s, &TestPreset::ExecutionOptions::StopOnFailure, + cmCMakePresetsGraphInternal::PresetOptionalBoolHelper, false) + .Bind("enableFailover"_s, &TestPreset::ExecutionOptions::EnableFailover, + cmCMakePresetsGraphInternal::PresetOptionalBoolHelper, false) + .Bind("jobs"_s, &TestPreset::ExecutionOptions::Jobs, + cmCMakePresetsGraphInternal::PresetOptionalIntHelper, false) + .Bind("resourceSpecFile"_s, + &TestPreset::ExecutionOptions::ResourceSpecFile, + cmCMakePresetsGraphInternal::PresetStringHelper, false) + .Bind("testLoad"_s, &TestPreset::ExecutionOptions::TestLoad, + cmCMakePresetsGraphInternal::PresetOptionalIntHelper, false) + .Bind("showOnly"_s, &TestPreset::ExecutionOptions::ShowOnly, + TestPresetOptionalExecutionShowOnlyHelper, false) + .Bind("repeat"_s, &TestPreset::ExecutionOptions::Repeat, + TestPresetOptionalExecutionRepeatHelper, false) + .Bind("interactiveDebugging"_s, + &TestPreset::ExecutionOptions::InteractiveDebugging, + cmCMakePresetsGraphInternal::PresetOptionalBoolHelper, false) + .Bind("scheduleRandom"_s, &TestPreset::ExecutionOptions::ScheduleRandom, + cmCMakePresetsGraphInternal::PresetOptionalBoolHelper, false) + .Bind("timeout"_s, &TestPreset::ExecutionOptions::Timeout, + cmCMakePresetsGraphInternal::PresetOptionalIntHelper, false) + .Bind("noTestsAction"_s, &TestPreset::ExecutionOptions::NoTestsAction, + TestPresetOptionalExecutionNoTestsActionHelper, false)); + +auto const TestPresetFilterHelper = + cmJSONOptionalHelper( + ReadFileResult::READ_OK, + cmJSONObjectHelper( + ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET) + .Bind("include"_s, &TestPreset::FilterOptions::Include, + TestPresetOptionalFilterIncludeHelper, false) + .Bind("exclude"_s, &TestPreset::FilterOptions::Exclude, + TestPresetOptionalFilterExcludeHelper, false)); + +auto const TestPresetHelper = + cmJSONObjectHelper( + ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET, false) + .Bind("name"_s, &TestPreset::Name, + cmCMakePresetsGraphInternal::PresetStringHelper) + .Bind("inherits"_s, &TestPreset::Inherits, + cmCMakePresetsGraphInternal::PresetVectorOneOrMoreStringHelper, + false) + .Bind("hidden"_s, &TestPreset::Hidden, + cmCMakePresetsGraphInternal::PresetBoolHelper, false) + .Bind("vendor"_s, nullptr, + cmCMakePresetsGraphInternal::VendorHelper( + ReadFileResult::INVALID_PRESET), + false) + .Bind("displayName"_s, &TestPreset::DisplayName, + cmCMakePresetsGraphInternal::PresetStringHelper, false) + .Bind("description"_s, &TestPreset::Description, + cmCMakePresetsGraphInternal::PresetStringHelper, false) + .Bind("environment"_s, &TestPreset::Environment, + cmCMakePresetsGraphInternal::EnvironmentMapHelper, false) + .Bind("configurePreset"_s, &TestPreset::ConfigurePreset, + cmCMakePresetsGraphInternal::PresetStringHelper, false) + .Bind("inheritConfigureEnvironment"_s, + &TestPreset::InheritConfigureEnvironment, + cmCMakePresetsGraphInternal::PresetOptionalBoolHelper, false) + .Bind("configuration"_s, &TestPreset::Configuration, + cmCMakePresetsGraphInternal::PresetStringHelper, false) + .Bind("overwriteConfigurationFile"_s, + &TestPreset::OverwriteConfigurationFile, + cmCMakePresetsGraphInternal::PresetVectorStringHelper, false) + .Bind("output"_s, &TestPreset::Output, TestPresetOptionalOutputHelper, + false) + .Bind("filter"_s, &TestPreset::Filter, TestPresetFilterHelper, false) + .Bind("execution"_s, &TestPreset::Execution, TestPresetExecutionHelper, + false) + .Bind("condition"_s, &TestPreset::ConditionEvaluator, + cmCMakePresetsGraphInternal::PresetConditionHelper, false); +} + +namespace cmCMakePresetsGraphInternal { +cmCMakePresetsGraph::ReadFileResult TestPresetsHelper( + std::vector& out, const Json::Value* value) +{ + static auto const helper = cmJSONVectorHelper( + ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESETS, + TestPresetHelper); + + return helper(out, value); +} +} From a239f23a987a063852c8f29040ef4eaeaebf3b9c Mon Sep 17 00:00:00 2001 From: Kyle Edwards Date: Tue, 21 Dec 2021 17:12:51 -0500 Subject: [PATCH 3/4] Refactor: Generalize file graph in CMakePresets Before this refactoring, presets had a simple flag that marked them as "user" or "not user", and checking the file graph of two files was as simple as checking this flag. This only allowed for two files in the graph. Generalize the code to allow for arbitrarily many files in the graph. --- Source/cmCMakePresetsGraph.cxx | 36 ++++++---- Source/cmCMakePresetsGraph.h | 37 +++++++++-- Source/cmCMakePresetsGraphReadJSON.cxx | 66 ++++++++++++++++--- .../CMakePresets/UserInheritance-stderr.txt | 2 +- 4 files changed, 112 insertions(+), 29 deletions(-) diff --git a/Source/cmCMakePresetsGraph.cxx b/Source/cmCMakePresetsGraph.cxx index ebc243bd59..a8aad12bc4 100644 --- a/Source/cmCMakePresetsGraph.cxx +++ b/Source/cmCMakePresetsGraph.cxx @@ -3,6 +3,7 @@ #include "cmCMakePresetsGraph.h" #include +#include #include #include #include @@ -106,8 +107,8 @@ ReadFileResult VisitPreset( } auto& parentPreset = parent->second.Unexpanded; - if (!preset.User && parentPreset.User) { - return ReadFileResult::USER_PRESET_INHERITANCE; + if (!preset.OriginFile->ReachableFiles.count(parentPreset.OriginFile)) { + return ReadFileResult::PRESET_UNREACHABLE_FROM_FILE; } auto result = VisitPreset(parentPreset, presets, cycleStatus, graph); @@ -876,23 +877,28 @@ cmCMakePresetsGraph::ReadProjectPresetsInternal(bool allowNoFiles) { bool haveOneFile = false; + File* file; std::string filename = GetUserFilename(this->SourceDir); + std::vector inProgressFiles; if (cmSystemTools::FileExists(filename)) { - auto result = this->ReadJSONFile(filename, true); + auto result = this->ReadJSONFile(filename, RootType::User, + ReadReason::Root, inProgressFiles, file); if (result != ReadFileResult::READ_OK) { return result; } haveOneFile = true; - } - - filename = GetFilename(this->SourceDir); - if (cmSystemTools::FileExists(filename)) { - auto result = this->ReadJSONFile(filename, false); - if (result != ReadFileResult::READ_OK) { - return result; + } else { + filename = GetFilename(this->SourceDir); + if (cmSystemTools::FileExists(filename)) { + auto result = this->ReadJSONFile( + filename, RootType::Project, ReadReason::Root, inProgressFiles, file); + if (result != ReadFileResult::READ_OK) { + return result; + } + haveOneFile = true; } - haveOneFile = true; } + assert(inProgressFiles.empty()); if (!haveOneFile) { return allowNoFiles ? ReadFileResult::READ_OK @@ -983,8 +989,8 @@ const char* cmCMakePresetsGraph::ResultToString(ReadFileResult result) return "Duplicate presets"; case ReadFileResult::CYCLIC_PRESET_INHERITANCE: return "Cyclic preset inheritance"; - case ReadFileResult::USER_PRESET_INHERITANCE: - return "Project preset inherits from user preset"; + case ReadFileResult::PRESET_UNREACHABLE_FROM_FILE: + return "Inherited preset is unreachable from preset's file"; case ReadFileResult::INVALID_MACRO_EXPANSION: return "Invalid macro expansion"; case ReadFileResult::BUILD_TEST_PRESETS_UNSUPPORTED: @@ -1002,6 +1008,8 @@ const char* cmCMakePresetsGraph::ResultToString(ReadFileResult result) case ReadFileResult::TOOLCHAIN_FILE_UNSUPPORTED: return "File version must be 3 or higher for toolchainFile preset " "support."; + case ReadFileResult::CYCLIC_INCLUDE: + return "Cyclic include among preset files"; } return "Unknown error"; @@ -1016,6 +1024,8 @@ void cmCMakePresetsGraph::ClearPresets() this->ConfigurePresetOrder.clear(); this->BuildPresetOrder.clear(); this->TestPresetOrder.clear(); + + this->Files.clear(); } void cmCMakePresetsGraph::PrintPresets( diff --git a/Source/cmCMakePresetsGraph.h b/Source/cmCMakePresetsGraph.h index 937b281ce5..c27a611525 100644 --- a/Source/cmCMakePresetsGraph.h +++ b/Source/cmCMakePresetsGraph.h @@ -8,6 +8,7 @@ #include #include #include +#include #include #include @@ -32,7 +33,7 @@ public: INVALID_VARIABLE, DUPLICATE_PRESETS, CYCLIC_PRESET_INHERITANCE, - USER_PRESET_INHERITANCE, + PRESET_UNREACHABLE_FROM_FILE, INVALID_MACRO_EXPANSION, BUILD_TEST_PRESETS_UNSUPPORTED, INVALID_CONFIGURE_PRESET, @@ -40,6 +41,7 @@ public: INVALID_CONDITION, CONDITION_UNSUPPORTED, TOOLCHAIN_FILE_UNSUPPORTED, + CYCLIC_INCLUDE, }; enum class ArchToolsetStrategy @@ -57,6 +59,15 @@ public: class Condition; + class File + { + public: + std::string Filename; + int Version; + + std::unordered_set ReachableFiles; + }; + class Preset { public: @@ -77,7 +88,7 @@ public: std::string Name; std::vector Inherits; bool Hidden; - bool User; + File* OriginFile; std::string DisplayName; std::string Description; @@ -321,12 +332,11 @@ public: std::vector TestPresetOrder; std::string SourceDir; - int Version; - int UserVersion; + std::vector> Files; int GetVersion(const Preset& preset) const { - return preset.User ? this->UserVersion : this->Version; + return preset.OriginFile->Version; } static std::string GetFilename(const std::string& sourceDir); @@ -372,7 +382,22 @@ public: void PrintAllPresets() const; private: + enum class RootType + { + Project, + User, + }; + + enum class ReadReason + { + Root, + Included, + }; + ReadFileResult ReadProjectPresetsInternal(bool allowNoFiles); - ReadFileResult ReadJSONFile(const std::string& filename, bool user); + ReadFileResult ReadJSONFile(const std::string& filename, RootType rootType, + ReadReason readReason, + std::vector& inProgressFiles, + File*& file); void ClearPresets(); }; diff --git a/Source/cmCMakePresetsGraphReadJSON.cxx b/Source/cmCMakePresetsGraphReadJSON.cxx index 3e002fee26..aa5c9d4943 100644 --- a/Source/cmCMakePresetsGraphReadJSON.cxx +++ b/Source/cmCMakePresetsGraphReadJSON.cxx @@ -1,8 +1,10 @@ /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying file Copyright.txt or https://cmake.org/licensing for details. */ +#include #include #include #include +#include #include #include @@ -18,6 +20,8 @@ #include "cmCMakePresetsGraph.h" #include "cmCMakePresetsGraphInternal.h" #include "cmJSONHelpers.h" +#include "cmStringAlgorithms.h" +#include "cmSystemTools.h" #include "cmVersion.h" namespace { @@ -406,8 +410,21 @@ cmCMakePresetsGraph::ReadFileResult EnvironmentMapHelper( } cmCMakePresetsGraph::ReadFileResult cmCMakePresetsGraph::ReadJSONFile( - const std::string& filename, bool user) + const std::string& filename, RootType rootType, ReadReason readReason, + std::vector& inProgressFiles, File*& file) { + for (auto const& f : this->Files) { + if (cmSystemTools::SameFile(filename, f->Filename)) { + file = f.get(); + auto fileIt = + std::find(inProgressFiles.begin(), inProgressFiles.end(), file); + if (fileIt != inProgressFiles.end()) { + return cmCMakePresetsGraph::ReadFileResult::CYCLIC_INCLUDE; + } + return cmCMakePresetsGraph::ReadFileResult::READ_OK; + } + } + cmsys::ifstream fin(filename.c_str()); if (!fin) { return ReadFileResult::FILE_NOT_FOUND; @@ -430,11 +447,6 @@ cmCMakePresetsGraph::ReadFileResult cmCMakePresetsGraph::ReadJSONFile( if (v < MIN_VERSION || v > MAX_VERSION) { return ReadFileResult::UNRECOGNIZED_VERSION; } - if (user) { - this->UserVersion = v; - } else { - this->Version = v; - } // Support for build and test presets added in version 2. if (v < 2 && @@ -460,8 +472,16 @@ cmCMakePresetsGraph::ReadFileResult cmCMakePresetsGraph::ReadJSONFile( return ReadFileResult::UNRECOGNIZED_CMAKE_VERSION; } + auto filePtr = cm::make_unique(); + file = filePtr.get(); + this->Files.emplace_back(std::move(filePtr)); + inProgressFiles.emplace_back(file); + file->Filename = filename; + file->Version = v; + file->ReachableFiles.insert(file); + for (auto& preset : presets.ConfigurePresets) { - preset.User = user; + preset.OriginFile = file; if (preset.Name.empty()) { return ReadFileResult::INVALID_PRESET; } @@ -494,7 +514,7 @@ cmCMakePresetsGraph::ReadFileResult cmCMakePresetsGraph::ReadJSONFile( } for (auto& preset : presets.BuildPresets) { - preset.User = user; + preset.OriginFile = file; if (preset.Name.empty()) { return ReadFileResult::INVALID_PRESET; } @@ -515,7 +535,7 @@ cmCMakePresetsGraph::ReadFileResult cmCMakePresetsGraph::ReadJSONFile( } for (auto& preset : presets.TestPresets) { - preset.User = user; + preset.OriginFile = file; if (preset.Name.empty()) { return ReadFileResult::INVALID_PRESET; } @@ -535,5 +555,33 @@ cmCMakePresetsGraph::ReadFileResult cmCMakePresetsGraph::ReadJSONFile( this->TestPresetOrder.push_back(preset.Name); } + auto const includeFile = [this, &inProgressFiles, file]( + const std::string& include, RootType rootType2, + ReadReason readReason2) -> ReadFileResult { + ReadFileResult r; + File* includedFile; + if ((r = this->ReadJSONFile(include, rootType2, readReason2, + inProgressFiles, includedFile)) != + ReadFileResult::READ_OK) { + return r; + } + + file->ReachableFiles.insert(includedFile->ReachableFiles.begin(), + includedFile->ReachableFiles.end()); + return ReadFileResult::READ_OK; + }; + + if (rootType == RootType::User && readReason == ReadReason::Root) { + auto cmakePresetsFilename = GetFilename(this->SourceDir); + if (cmSystemTools::FileExists(cmakePresetsFilename)) { + if ((result = includeFile(cmakePresetsFilename, RootType::Project, + ReadReason::Root)) != + ReadFileResult::READ_OK) { + return result; + } + } + } + + inProgressFiles.pop_back(); return ReadFileResult::READ_OK; } diff --git a/Tests/RunCMake/CMakePresets/UserInheritance-stderr.txt b/Tests/RunCMake/CMakePresets/UserInheritance-stderr.txt index 213215a41b..5ad8b4b6b6 100644 --- a/Tests/RunCMake/CMakePresets/UserInheritance-stderr.txt +++ b/Tests/RunCMake/CMakePresets/UserInheritance-stderr.txt @@ -1,2 +1,2 @@ ^CMake Error: Could not read presets from [^ -]*/Tests/RunCMake/CMakePresets/UserInheritance: Project preset inherits from user preset$ +]*/Tests/RunCMake/CMakePresets/UserInheritance: Inherited preset is unreachable from preset's file$ From 26a5512c0f952333f089a08b0df84e3efa7fb063 Mon Sep 17 00:00:00 2001 From: Kyle Edwards Date: Wed, 22 Dec 2021 16:49:38 -0500 Subject: [PATCH 4/4] CMakePresets: Add include field Fixes: #21331 --- Help/manual/cmake-presets.7.rst | 28 ++++++++- Help/manual/presets/example.json | 2 +- Help/manual/presets/schema.json | 22 +++++++ Help/release/dev/cmake-presets-include.rst | 6 ++ Source/cmCMakePresetsGraph.cxx | 6 ++ Source/cmCMakePresetsGraph.h | 3 + Source/cmCMakePresetsGraphReadJSON.cxx | 60 ++++++++++++++++++- .../RunCMake/CMakePresets/Include-stdout.txt | 8 +++ Tests/RunCMake/CMakePresets/Include.json.in | 16 +++++ .../CMakePresets/IncludeCommon.json.in | 8 +++ .../CMakePresets/IncludeCycle-result.txt | 1 + .../CMakePresets/IncludeCycle-stderr.txt | 2 + .../CMakePresets/IncludeCycle.json.in | 11 ++++ .../IncludeCycle3Files-result.txt | 1 + .../IncludeCycle3Files-stderr.txt | 2 + .../CMakePresets/IncludeCycle3Files.json.in | 6 ++ .../CMakePresets/IncludeCycle3Files2.json.in | 6 ++ .../CMakePresets/IncludeCycle3Files3.json.in | 6 ++ .../CMakePresets/IncludeCycleUser.json.in | 3 + .../CMakePresets/IncludeNotFound-result.txt | 1 + .../CMakePresets/IncludeNotFound-stderr.txt | 2 + .../CMakePresets/IncludeNotFound.json.in | 11 ++++ .../IncludeOutsideProject-result.txt | 1 + .../IncludeOutsideProject-stderr.txt | 2 + .../IncludeOutsideProject.json.in | 11 ++++ .../IncludeOutsideProjectInclude.json | 3 + .../IncludeOutsideProjectIntermediate.json.in | 6 ++ .../IncludeOutsideProjectUser.json.in | 6 ++ .../RunCMake/CMakePresets/IncludeUser.json.in | 15 +++++ .../CMakePresets/IncludeUserCommon.json.in | 8 +++ .../IncludeUserOutsideProject.cmake | 0 .../IncludeUserOutsideProjectUser.json.in | 11 ++++ .../CMakePresets/IncludeV3-result.txt | 1 + .../CMakePresets/IncludeV3-stderr.txt | 2 + Tests/RunCMake/CMakePresets/IncludeV3.json.in | 4 ++ .../CMakePresets/IncludeV4V3-result.txt | 1 + .../CMakePresets/IncludeV4V3-stderr.txt | 2 + .../RunCMake/CMakePresets/IncludeV4V3.json.in | 6 ++ .../CMakePresets/IncludeV4V3Extra.json.in | 4 ++ .../RunCMake/CMakePresets/RunCMakeTest.cmake | 45 ++++++++++++++ Tests/RunCMake/CMakePresets/check.cmake | 7 +++ .../CMakePresets/subdir/CMakePresets.json.in | 12 ++++ 42 files changed, 351 insertions(+), 7 deletions(-) create mode 100644 Help/release/dev/cmake-presets-include.rst create mode 100644 Tests/RunCMake/CMakePresets/Include-stdout.txt create mode 100644 Tests/RunCMake/CMakePresets/Include.json.in create mode 100644 Tests/RunCMake/CMakePresets/IncludeCommon.json.in create mode 100644 Tests/RunCMake/CMakePresets/IncludeCycle-result.txt create mode 100644 Tests/RunCMake/CMakePresets/IncludeCycle-stderr.txt create mode 100644 Tests/RunCMake/CMakePresets/IncludeCycle.json.in create mode 100644 Tests/RunCMake/CMakePresets/IncludeCycle3Files-result.txt create mode 100644 Tests/RunCMake/CMakePresets/IncludeCycle3Files-stderr.txt create mode 100644 Tests/RunCMake/CMakePresets/IncludeCycle3Files.json.in create mode 100644 Tests/RunCMake/CMakePresets/IncludeCycle3Files2.json.in create mode 100644 Tests/RunCMake/CMakePresets/IncludeCycle3Files3.json.in create mode 100644 Tests/RunCMake/CMakePresets/IncludeCycleUser.json.in create mode 100644 Tests/RunCMake/CMakePresets/IncludeNotFound-result.txt create mode 100644 Tests/RunCMake/CMakePresets/IncludeNotFound-stderr.txt create mode 100644 Tests/RunCMake/CMakePresets/IncludeNotFound.json.in create mode 100644 Tests/RunCMake/CMakePresets/IncludeOutsideProject-result.txt create mode 100644 Tests/RunCMake/CMakePresets/IncludeOutsideProject-stderr.txt create mode 100644 Tests/RunCMake/CMakePresets/IncludeOutsideProject.json.in create mode 100644 Tests/RunCMake/CMakePresets/IncludeOutsideProjectInclude.json create mode 100644 Tests/RunCMake/CMakePresets/IncludeOutsideProjectIntermediate.json.in create mode 100644 Tests/RunCMake/CMakePresets/IncludeOutsideProjectUser.json.in create mode 100644 Tests/RunCMake/CMakePresets/IncludeUser.json.in create mode 100644 Tests/RunCMake/CMakePresets/IncludeUserCommon.json.in create mode 100644 Tests/RunCMake/CMakePresets/IncludeUserOutsideProject.cmake create mode 100644 Tests/RunCMake/CMakePresets/IncludeUserOutsideProjectUser.json.in create mode 100644 Tests/RunCMake/CMakePresets/IncludeV3-result.txt create mode 100644 Tests/RunCMake/CMakePresets/IncludeV3-stderr.txt create mode 100644 Tests/RunCMake/CMakePresets/IncludeV3.json.in create mode 100644 Tests/RunCMake/CMakePresets/IncludeV4V3-result.txt create mode 100644 Tests/RunCMake/CMakePresets/IncludeV4V3-stderr.txt create mode 100644 Tests/RunCMake/CMakePresets/IncludeV4V3.json.in create mode 100644 Tests/RunCMake/CMakePresets/IncludeV4V3Extra.json.in create mode 100644 Tests/RunCMake/CMakePresets/subdir/CMakePresets.json.in diff --git a/Help/manual/cmake-presets.7.rst b/Help/manual/cmake-presets.7.rst index 74e9faea9d..474e1aa6c9 100644 --- a/Help/manual/cmake-presets.7.rst +++ b/Help/manual/cmake-presets.7.rst @@ -12,9 +12,10 @@ Introduction One problem that CMake users often face is sharing settings with other people for common ways to configure a project. This may be done to support CI builds, -or for users who frequently use the same build. CMake supports two files, +or for users who frequently use the same build. CMake supports two main files, ``CMakePresets.json`` and ``CMakeUserPresets.json``, that allow users to -specify common configure options and share them with others. +specify common configure options and share them with others. CMake also +supports files included with the ``include`` field. ``CMakePresets.json`` and ``CMakeUserPresets.json`` live in the project's root directory. They both have exactly the same format, and both are optional @@ -26,6 +27,21 @@ builds. ``CMakePresets.json`` may be checked into a version control system, and is using Git, ``CMakePresets.json`` may be tracked, and ``CMakeUserPresets.json`` should be added to the ``.gitignore``. +``CMakePresets.json`` and ``CMakeUserPresets.json`` can include other files +with the ``include`` field in file version ``4`` and later. Files included by +these files can also include other files. If a preset file contains presets +that inherit from presets in another file, the file must include the other file +either directly or indirectly. Include cycles are not allowed among files (if +``a.json`` includes ``b.json``, ``b.json`` cannot include ``a.json``). However, +a file may be included multiple times from the same file or from different +files. If ``CMakePresets.json`` and ``CMakeUserPresets.json`` are both present, +``CMakeUserPresets.json`` implicitly includes ``CMakePresets.json``, even with +no ``include`` field, in all versions of the format. Files directly or +indirectly included from ``CMakePresets.json`` must be inside the project +directory. This restriction does not apply to ``CMakeUserPresets.json`` and +files that it includes, unless those files are also included by +``CMakePresets.json``. + Format ====== @@ -39,7 +55,7 @@ The root object recognizes the following fields: ``version`` A required integer representing the version of the JSON schema. - The supported versions are ``1``, ``2``, and ``3``. + The supported versions are ``1``, ``2``, ``3``, and ``4``. ``cmakeMinimumRequired`` @@ -82,6 +98,12 @@ The root object recognizes the following fields: An optional array of `Test Preset`_ objects. This is allowed in preset files specifying version ``2`` or above. +``include`` + + An optional array of strings representing files to include. If the filenames + are not absolute, they are considered relative to the current file. + This is allowed in preset files specifying version ``4`` or above. + Configure Preset ^^^^^^^^^^^^^^^^ diff --git a/Help/manual/presets/example.json b/Help/manual/presets/example.json index b08445a471..a7ec10edbe 100644 --- a/Help/manual/presets/example.json +++ b/Help/manual/presets/example.json @@ -1,5 +1,5 @@ { - "version": 3, + "version": 4, "cmakeMinimumRequired": { "major": 3, "minor": 21, diff --git a/Help/manual/presets/schema.json b/Help/manual/presets/schema.json index 7852550dcf..327291d0bc 100644 --- a/Help/manual/presets/schema.json +++ b/Help/manual/presets/schema.json @@ -42,6 +42,21 @@ "testPresets": { "$ref": "#/definitions/testPresetsV3"} }, "additionalProperties": false + }, + { + "properties": { + "version": { + "const": 4, + "description": "A required integer representing the version of the JSON schema." + }, + "cmakeMinimumRequired": { "$ref": "#/definitions/cmakeMinimumRequired"}, + "vendor": { "$ref": "#/definitions/vendor" }, + "configurePresets": { "$ref": "#/definitions/configurePresetsV3"}, + "buildPresets": { "$ref": "#/definitions/buildPresetsV3"}, + "testPresets": { "$ref": "#/definitions/testPresetsV3"}, + "include": { "$ref": "#/definitions/include"} + }, + "additionalProperties": false } ], "required": [ @@ -1235,6 +1250,13 @@ "description": "Null indicates that the condition always evaluates to true and is not inherited." } ] + }, + "include": { + "type": "array", + "description": "An optional array of strings representing files to include. If the filenames are not absolute, they are considered relative to the current file.", + "items": { + "type": "string" + } } } } diff --git a/Help/release/dev/cmake-presets-include.rst b/Help/release/dev/cmake-presets-include.rst new file mode 100644 index 0000000000..51219bde38 --- /dev/null +++ b/Help/release/dev/cmake-presets-include.rst @@ -0,0 +1,6 @@ +cmake-presets-include +--------------------- + +* :manual:`cmake-presets(7)` files now support schema version ``4``. +* :manual:`cmake-presets(7)` files now have an optional ``include`` field, + which allows the files to include other files. diff --git a/Source/cmCMakePresetsGraph.cxx b/Source/cmCMakePresetsGraph.cxx index a8aad12bc4..58dca36821 100644 --- a/Source/cmCMakePresetsGraph.cxx +++ b/Source/cmCMakePresetsGraph.cxx @@ -996,6 +996,10 @@ const char* cmCMakePresetsGraph::ResultToString(ReadFileResult result) case ReadFileResult::BUILD_TEST_PRESETS_UNSUPPORTED: return "File version must be 2 or higher for build and test preset " "support."; + case ReadFileResult::INCLUDE_UNSUPPORTED: + return "File version must be 4 or higher for include support"; + case ReadFileResult::INVALID_INCLUDE: + return "Invalid \"include\" field"; case ReadFileResult::INVALID_CONFIGURE_PRESET: return "Invalid \"configurePreset\" field"; case ReadFileResult::INSTALL_PREFIX_UNSUPPORTED: @@ -1010,6 +1014,8 @@ const char* cmCMakePresetsGraph::ResultToString(ReadFileResult result) "support."; case ReadFileResult::CYCLIC_INCLUDE: return "Cyclic include among preset files"; + case ReadFileResult::INCLUDE_OUTSIDE_PROJECT: + return "File included from outside project directory"; } return "Unknown error"; diff --git a/Source/cmCMakePresetsGraph.h b/Source/cmCMakePresetsGraph.h index c27a611525..02c506f93b 100644 --- a/Source/cmCMakePresetsGraph.h +++ b/Source/cmCMakePresetsGraph.h @@ -36,12 +36,15 @@ public: PRESET_UNREACHABLE_FROM_FILE, INVALID_MACRO_EXPANSION, BUILD_TEST_PRESETS_UNSUPPORTED, + INCLUDE_UNSUPPORTED, + INVALID_INCLUDE, INVALID_CONFIGURE_PRESET, INSTALL_PREFIX_UNSUPPORTED, INVALID_CONDITION, CONDITION_UNSUPPORTED, TOOLCHAIN_FILE_UNSUPPORTED, CYCLIC_INCLUDE, + INCLUDE_OUTSIDE_PROJECT, }; enum class ArchToolsetStrategy diff --git a/Source/cmCMakePresetsGraphReadJSON.cxx b/Source/cmCMakePresetsGraphReadJSON.cxx index aa5c9d4943..ca3412446f 100644 --- a/Source/cmCMakePresetsGraphReadJSON.cxx +++ b/Source/cmCMakePresetsGraphReadJSON.cxx @@ -33,7 +33,7 @@ using TestPreset = cmCMakePresetsGraph::TestPreset; using ArchToolsetStrategy = cmCMakePresetsGraph::ArchToolsetStrategy; constexpr int MIN_VERSION = 1; -constexpr int MAX_VERSION = 3; +constexpr int MAX_VERSION = 4; struct CMakeVersion { @@ -48,6 +48,7 @@ struct RootPresets std::vector ConfigurePresets; std::vector BuildPresets; std::vector TestPresets; + std::vector Include; }; std::unique_ptr InvertCondition( @@ -271,6 +272,13 @@ auto const CMakeVersionHelper = .Bind("minor"_s, &CMakeVersion::Minor, CMakeVersionUIntHelper, false) .Bind("patch"_s, &CMakeVersion::Patch, CMakeVersionUIntHelper, false); +auto const IncludeHelper = cmJSONStringHelper( + ReadFileResult::READ_OK, ReadFileResult::INVALID_INCLUDE); + +auto const IncludeVectorHelper = + cmJSONVectorHelper( + ReadFileResult::READ_OK, ReadFileResult::INVALID_INCLUDE, IncludeHelper); + auto const RootPresetsHelper = cmJSONObjectHelper( ReadFileResult::READ_OK, ReadFileResult::INVALID_ROOT, false) @@ -283,6 +291,7 @@ auto const RootPresetsHelper = cmCMakePresetsGraphInternal::TestPresetsHelper, false) .Bind("cmakeMinimumRequired"_s, &RootPresets::CMakeMinimumRequired, CMakeVersionHelper, false) + .Bind("include"_s, &RootPresets::Include, IncludeVectorHelper, false) .Bind( "vendor"_s, nullptr, cmCMakePresetsGraphInternal::VendorHelper(ReadFileResult::INVALID_ROOT), @@ -413,6 +422,19 @@ cmCMakePresetsGraph::ReadFileResult cmCMakePresetsGraph::ReadJSONFile( const std::string& filename, RootType rootType, ReadReason readReason, std::vector& inProgressFiles, File*& file) { + ReadFileResult result; + + if (rootType == RootType::Project) { + auto normalizedFilename = cmSystemTools::CollapseFullPath(filename); + + auto normalizedProjectDir = + cmSystemTools::CollapseFullPath(this->SourceDir); + if (!cmSystemTools::IsSubDirectory(normalizedFilename, + normalizedProjectDir)) { + return ReadFileResult::INCLUDE_OUTSIDE_PROJECT; + } + } + for (auto const& f : this->Files) { if (cmSystemTools::SameFile(filename, f->Filename)) { file = f.get(); @@ -421,6 +443,22 @@ cmCMakePresetsGraph::ReadFileResult cmCMakePresetsGraph::ReadJSONFile( if (fileIt != inProgressFiles.end()) { return cmCMakePresetsGraph::ReadFileResult::CYCLIC_INCLUDE; } + + // Check files included by this file again to make sure they're in the + // project directory. + if (rootType == RootType::Project) { + for (auto* f2 : file->ReachableFiles) { + if (!cmSystemTools::SameFile(filename, f2->Filename)) { + File* file2; + if ((result = this->ReadJSONFile( + f2->Filename, rootType, ReadReason::Included, + inProgressFiles, file2)) != ReadFileResult::READ_OK) { + return result; + } + } + } + } + return cmCMakePresetsGraph::ReadFileResult::READ_OK; } } @@ -440,8 +478,7 @@ cmCMakePresetsGraph::ReadFileResult cmCMakePresetsGraph::ReadJSONFile( } int v = 0; - auto result = RootVersionHelper(v, &root); - if (result != ReadFileResult::READ_OK) { + if ((result = RootVersionHelper(v, &root)) != ReadFileResult::READ_OK) { return result; } if (v < MIN_VERSION || v > MAX_VERSION) { @@ -454,6 +491,11 @@ cmCMakePresetsGraph::ReadFileResult cmCMakePresetsGraph::ReadJSONFile( return ReadFileResult::BUILD_TEST_PRESETS_UNSUPPORTED; } + // Support for include added in version 4. + if (v < 4 && root.isMember("include")) { + return ReadFileResult::INCLUDE_UNSUPPORTED; + } + RootPresets presets; if ((result = RootPresetsHelper(presets, &root)) != ReadFileResult::READ_OK) { @@ -571,6 +613,18 @@ cmCMakePresetsGraph::ReadFileResult cmCMakePresetsGraph::ReadJSONFile( return ReadFileResult::READ_OK; }; + for (auto include : presets.Include) { + if (!cmSystemTools::FileIsFullPath(include)) { + auto directory = cmSystemTools::GetFilenamePath(filename); + include = cmStrCat(directory, '/', include); + } + + if ((result = includeFile(include, rootType, ReadReason::Included)) != + ReadFileResult::READ_OK) { + return result; + } + } + if (rootType == RootType::User && readReason == ReadReason::Root) { auto cmakePresetsFilename = GetFilename(this->SourceDir); if (cmSystemTools::FileExists(cmakePresetsFilename)) { diff --git a/Tests/RunCMake/CMakePresets/Include-stdout.txt b/Tests/RunCMake/CMakePresets/Include-stdout.txt new file mode 100644 index 0000000000..6ba1170bac --- /dev/null +++ b/Tests/RunCMake/CMakePresets/Include-stdout.txt @@ -0,0 +1,8 @@ +^Not searching for unused variables given on the command line\. +Available configure presets: + + "IncludeUser" + "IncludeUserCommon" + "Include" + "Subdir" + "IncludeCommon"$ diff --git a/Tests/RunCMake/CMakePresets/Include.json.in b/Tests/RunCMake/CMakePresets/Include.json.in new file mode 100644 index 0000000000..3687d3c77c --- /dev/null +++ b/Tests/RunCMake/CMakePresets/Include.json.in @@ -0,0 +1,16 @@ +{ + "version": 4, + "include": [ + "subdir/CMakePresets.json", + "@RunCMake_TEST_SOURCE_DIR@/IncludeCommon.json" + ], + "configurePresets": [ + { + "name": "Include", + "inherits": [ + "IncludeCommon", + "Subdir" + ] + } + ] +} diff --git a/Tests/RunCMake/CMakePresets/IncludeCommon.json.in b/Tests/RunCMake/CMakePresets/IncludeCommon.json.in new file mode 100644 index 0000000000..eeae723f9a --- /dev/null +++ b/Tests/RunCMake/CMakePresets/IncludeCommon.json.in @@ -0,0 +1,8 @@ +{ + "version": 3, + "configurePresets": [ + { + "name": "IncludeCommon" + } + ] +} diff --git a/Tests/RunCMake/CMakePresets/IncludeCycle-result.txt b/Tests/RunCMake/CMakePresets/IncludeCycle-result.txt new file mode 100644 index 0000000000..d00491fd7e --- /dev/null +++ b/Tests/RunCMake/CMakePresets/IncludeCycle-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/CMakePresets/IncludeCycle-stderr.txt b/Tests/RunCMake/CMakePresets/IncludeCycle-stderr.txt new file mode 100644 index 0000000000..3343204ca2 --- /dev/null +++ b/Tests/RunCMake/CMakePresets/IncludeCycle-stderr.txt @@ -0,0 +1,2 @@ +^CMake Error: Could not read presets from [^ +]*/Tests/RunCMake/CMakePresets/IncludeCycle: Cyclic include among preset files$ diff --git a/Tests/RunCMake/CMakePresets/IncludeCycle.json.in b/Tests/RunCMake/CMakePresets/IncludeCycle.json.in new file mode 100644 index 0000000000..b35b6ff608 --- /dev/null +++ b/Tests/RunCMake/CMakePresets/IncludeCycle.json.in @@ -0,0 +1,11 @@ +{ + "version": 4, + "include": [ + "CMakeUserPresets.json" + ], + "configurePresets": [ + { + "name": "IncludeCycle" + } + ] +} diff --git a/Tests/RunCMake/CMakePresets/IncludeCycle3Files-result.txt b/Tests/RunCMake/CMakePresets/IncludeCycle3Files-result.txt new file mode 100644 index 0000000000..d00491fd7e --- /dev/null +++ b/Tests/RunCMake/CMakePresets/IncludeCycle3Files-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/CMakePresets/IncludeCycle3Files-stderr.txt b/Tests/RunCMake/CMakePresets/IncludeCycle3Files-stderr.txt new file mode 100644 index 0000000000..35aea4c9ca --- /dev/null +++ b/Tests/RunCMake/CMakePresets/IncludeCycle3Files-stderr.txt @@ -0,0 +1,2 @@ +^CMake Error: Could not read presets from [^ +]*/Tests/RunCMake/CMakePresets/IncludeCycle3Files: Cyclic include among preset files$ diff --git a/Tests/RunCMake/CMakePresets/IncludeCycle3Files.json.in b/Tests/RunCMake/CMakePresets/IncludeCycle3Files.json.in new file mode 100644 index 0000000000..8174ff0868 --- /dev/null +++ b/Tests/RunCMake/CMakePresets/IncludeCycle3Files.json.in @@ -0,0 +1,6 @@ +{ + "version": 4, + "include": [ + "IncludeCycle3Files2.json" + ] +} diff --git a/Tests/RunCMake/CMakePresets/IncludeCycle3Files2.json.in b/Tests/RunCMake/CMakePresets/IncludeCycle3Files2.json.in new file mode 100644 index 0000000000..952e875af7 --- /dev/null +++ b/Tests/RunCMake/CMakePresets/IncludeCycle3Files2.json.in @@ -0,0 +1,6 @@ +{ + "version": 4, + "include": [ + "IncludeCycle3Files3.json" + ] +} diff --git a/Tests/RunCMake/CMakePresets/IncludeCycle3Files3.json.in b/Tests/RunCMake/CMakePresets/IncludeCycle3Files3.json.in new file mode 100644 index 0000000000..8dbf3ad1ec --- /dev/null +++ b/Tests/RunCMake/CMakePresets/IncludeCycle3Files3.json.in @@ -0,0 +1,6 @@ +{ + "version": 4, + "include": [ + "CMakePresets.json" + ] +} diff --git a/Tests/RunCMake/CMakePresets/IncludeCycleUser.json.in b/Tests/RunCMake/CMakePresets/IncludeCycleUser.json.in new file mode 100644 index 0000000000..cd2f236b29 --- /dev/null +++ b/Tests/RunCMake/CMakePresets/IncludeCycleUser.json.in @@ -0,0 +1,3 @@ +{ + "version": 3 +} diff --git a/Tests/RunCMake/CMakePresets/IncludeNotFound-result.txt b/Tests/RunCMake/CMakePresets/IncludeNotFound-result.txt new file mode 100644 index 0000000000..d00491fd7e --- /dev/null +++ b/Tests/RunCMake/CMakePresets/IncludeNotFound-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/CMakePresets/IncludeNotFound-stderr.txt b/Tests/RunCMake/CMakePresets/IncludeNotFound-stderr.txt new file mode 100644 index 0000000000..7ccabab0f5 --- /dev/null +++ b/Tests/RunCMake/CMakePresets/IncludeNotFound-stderr.txt @@ -0,0 +1,2 @@ +^CMake Error: Could not read presets from [^ +]*/Tests/RunCMake/CMakePresets/IncludeNotFound: File not found$ diff --git a/Tests/RunCMake/CMakePresets/IncludeNotFound.json.in b/Tests/RunCMake/CMakePresets/IncludeNotFound.json.in new file mode 100644 index 0000000000..a72b18388b --- /dev/null +++ b/Tests/RunCMake/CMakePresets/IncludeNotFound.json.in @@ -0,0 +1,11 @@ +{ + "version": 4, + "include": [ + "NotFound.json" + ], + "configurePresets": [ + { + "name": "IncludeNotFound" + } + ] +} diff --git a/Tests/RunCMake/CMakePresets/IncludeOutsideProject-result.txt b/Tests/RunCMake/CMakePresets/IncludeOutsideProject-result.txt new file mode 100644 index 0000000000..d00491fd7e --- /dev/null +++ b/Tests/RunCMake/CMakePresets/IncludeOutsideProject-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/CMakePresets/IncludeOutsideProject-stderr.txt b/Tests/RunCMake/CMakePresets/IncludeOutsideProject-stderr.txt new file mode 100644 index 0000000000..2aa3f59f2c --- /dev/null +++ b/Tests/RunCMake/CMakePresets/IncludeOutsideProject-stderr.txt @@ -0,0 +1,2 @@ +^CMake Error: Could not read presets from [^ +]*/Tests/RunCMake/CMakePresets/IncludeOutsideProject: File included from outside project directory$ diff --git a/Tests/RunCMake/CMakePresets/IncludeOutsideProject.json.in b/Tests/RunCMake/CMakePresets/IncludeOutsideProject.json.in new file mode 100644 index 0000000000..cf1928fd2d --- /dev/null +++ b/Tests/RunCMake/CMakePresets/IncludeOutsideProject.json.in @@ -0,0 +1,11 @@ +{ + "version": 4, + "include": [ + "IncludeOutsideProjectIntermediate.json" + ], + "configurePresets": [ + { + "name": "IncludeOutsideProject" + } + ] +} diff --git a/Tests/RunCMake/CMakePresets/IncludeOutsideProjectInclude.json b/Tests/RunCMake/CMakePresets/IncludeOutsideProjectInclude.json new file mode 100644 index 0000000000..f13e55ca49 --- /dev/null +++ b/Tests/RunCMake/CMakePresets/IncludeOutsideProjectInclude.json @@ -0,0 +1,3 @@ +{ + "version": 4 +} diff --git a/Tests/RunCMake/CMakePresets/IncludeOutsideProjectIntermediate.json.in b/Tests/RunCMake/CMakePresets/IncludeOutsideProjectIntermediate.json.in new file mode 100644 index 0000000000..7c140c6508 --- /dev/null +++ b/Tests/RunCMake/CMakePresets/IncludeOutsideProjectIntermediate.json.in @@ -0,0 +1,6 @@ +{ + "version": 4, + "include": [ + "@RunCMake_SOURCE_DIR@/IncludeOutsideProjectInclude.json" + ] +} diff --git a/Tests/RunCMake/CMakePresets/IncludeOutsideProjectUser.json.in b/Tests/RunCMake/CMakePresets/IncludeOutsideProjectUser.json.in new file mode 100644 index 0000000000..f4f540e691 --- /dev/null +++ b/Tests/RunCMake/CMakePresets/IncludeOutsideProjectUser.json.in @@ -0,0 +1,6 @@ +{ + "version": 4, + "include": [ + "IncludeOutsideProjectIntermediate.json" + ] +} diff --git a/Tests/RunCMake/CMakePresets/IncludeUser.json.in b/Tests/RunCMake/CMakePresets/IncludeUser.json.in new file mode 100644 index 0000000000..46d23fd050 --- /dev/null +++ b/Tests/RunCMake/CMakePresets/IncludeUser.json.in @@ -0,0 +1,15 @@ +{ + "version": 4, + "include": [ + "IncludeUserCommon.json" + ], + "configurePresets": [ + { + "name": "IncludeUser", + "inherits": [ + "Include", + "IncludeUserCommon" + ] + } + ] +} diff --git a/Tests/RunCMake/CMakePresets/IncludeUserCommon.json.in b/Tests/RunCMake/CMakePresets/IncludeUserCommon.json.in new file mode 100644 index 0000000000..5a1bd368ce --- /dev/null +++ b/Tests/RunCMake/CMakePresets/IncludeUserCommon.json.in @@ -0,0 +1,8 @@ +{ + "version": 3, + "configurePresets": [ + { + "name": "IncludeUserCommon" + } + ] +} diff --git a/Tests/RunCMake/CMakePresets/IncludeUserOutsideProject.cmake b/Tests/RunCMake/CMakePresets/IncludeUserOutsideProject.cmake new file mode 100644 index 0000000000..e69de29bb2 diff --git a/Tests/RunCMake/CMakePresets/IncludeUserOutsideProjectUser.json.in b/Tests/RunCMake/CMakePresets/IncludeUserOutsideProjectUser.json.in new file mode 100644 index 0000000000..5b5427aef3 --- /dev/null +++ b/Tests/RunCMake/CMakePresets/IncludeUserOutsideProjectUser.json.in @@ -0,0 +1,11 @@ +{ + "version": 4, + "include": [ + "@RunCMake_SOURCE_DIR@/IncludeOutsideProjectInclude.json" + ], + "configurePresets": [ + { + "name": "IncludeUserOutsideProject" + } + ] +} diff --git a/Tests/RunCMake/CMakePresets/IncludeV3-result.txt b/Tests/RunCMake/CMakePresets/IncludeV3-result.txt new file mode 100644 index 0000000000..d00491fd7e --- /dev/null +++ b/Tests/RunCMake/CMakePresets/IncludeV3-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/CMakePresets/IncludeV3-stderr.txt b/Tests/RunCMake/CMakePresets/IncludeV3-stderr.txt new file mode 100644 index 0000000000..1869b6db5f --- /dev/null +++ b/Tests/RunCMake/CMakePresets/IncludeV3-stderr.txt @@ -0,0 +1,2 @@ +^CMake Error: Could not read presets from [^ +]*/Tests/RunCMake/CMakePresets/IncludeV3: File version must be 4 or higher for include support$ diff --git a/Tests/RunCMake/CMakePresets/IncludeV3.json.in b/Tests/RunCMake/CMakePresets/IncludeV3.json.in new file mode 100644 index 0000000000..b28cad8ce1 --- /dev/null +++ b/Tests/RunCMake/CMakePresets/IncludeV3.json.in @@ -0,0 +1,4 @@ +{ + "version": 3, + "include": [] +} diff --git a/Tests/RunCMake/CMakePresets/IncludeV4V3-result.txt b/Tests/RunCMake/CMakePresets/IncludeV4V3-result.txt new file mode 100644 index 0000000000..d00491fd7e --- /dev/null +++ b/Tests/RunCMake/CMakePresets/IncludeV4V3-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/CMakePresets/IncludeV4V3-stderr.txt b/Tests/RunCMake/CMakePresets/IncludeV4V3-stderr.txt new file mode 100644 index 0000000000..89e3e3ddbf --- /dev/null +++ b/Tests/RunCMake/CMakePresets/IncludeV4V3-stderr.txt @@ -0,0 +1,2 @@ +^CMake Error: Could not read presets from [^ +]*/Tests/RunCMake/CMakePresets/IncludeV4V3: File version must be 4 or higher for include support$ diff --git a/Tests/RunCMake/CMakePresets/IncludeV4V3.json.in b/Tests/RunCMake/CMakePresets/IncludeV4V3.json.in new file mode 100644 index 0000000000..4afa319ece --- /dev/null +++ b/Tests/RunCMake/CMakePresets/IncludeV4V3.json.in @@ -0,0 +1,6 @@ +{ + "version": 4, + "include": [ + "IncludeV4V3Extra.json" + ] +} diff --git a/Tests/RunCMake/CMakePresets/IncludeV4V3Extra.json.in b/Tests/RunCMake/CMakePresets/IncludeV4V3Extra.json.in new file mode 100644 index 0000000000..b28cad8ce1 --- /dev/null +++ b/Tests/RunCMake/CMakePresets/IncludeV4V3Extra.json.in @@ -0,0 +1,4 @@ +{ + "version": 3, + "include": [] +} diff --git a/Tests/RunCMake/CMakePresets/RunCMakeTest.cmake b/Tests/RunCMake/CMakePresets/RunCMakeTest.cmake index c31a645bca..51e786e170 100644 --- a/Tests/RunCMake/CMakePresets/RunCMakeTest.cmake +++ b/Tests/RunCMake/CMakePresets/RunCMakeTest.cmake @@ -44,6 +44,20 @@ function(run_cmake_presets name) configure_file("${CMakeUserPresets_FILE}" "${RunCMake_TEST_SOURCE_DIR}/CMakeUserPresets.json" @ONLY) endif() + set(_CMakePresets_EXTRA_FILES_OUT) + set(_CMakePresets_EXTRA_FILES_SCHEMA_EXPECTED_RESULTS) + foreach(_extra_file IN LISTS CMakePresets_EXTRA_FILES) + cmake_path(RELATIVE_PATH _extra_file + BASE_DIRECTORY "${RunCMake_SOURCE_DIR}" + OUTPUT_VARIABLE _extra_file_relative + ) + string(REGEX REPLACE "\\.in$" "" _extra_file_out_relative "${_extra_file_relative}") + set(_extra_file_out "${RunCMake_TEST_SOURCE_DIR}/${_extra_file_out_relative}") + configure_file("${_extra_file}" "${_extra_file_out}") + list(APPEND _CMakePresets_EXTRA_FILES_OUT "${_extra_file_out}") + list(APPEND _CMakePresets_EXTRA_FILES_SCHEMA_EXPECTED_RESULTS 0) + endforeach() + set(_s_arg -S) if(CMakePresets_NO_S_ARG) set(_s_arg) @@ -319,6 +333,37 @@ run_cmake_presets(OptionalBinaryDirFieldNoS) unset(CMakePresets_SOURCE_ARG) unset(CMakePresets_NO_S_ARG) +# Test include field +set(CMakePresets_SCHEMA_EXPECTED_RESULT 1) +run_cmake_presets(IncludeV3) +set(CMakePresets_SCHEMA_EXPECTED_RESULT 0) +set(CMakePresets_EXTRA_FILES + "${RunCMake_SOURCE_DIR}/IncludeV4V3Extra.json.in" + ) +set(CMakePresets_EXTRA_FILES_SCHEMA_EXPECTED_RESULTS 1) +run_cmake_presets(IncludeV4V3) +unset(CMakePresets_EXTRA_FILES_SCHEMA_EXPECTED_RESULTS) +set(CMakePresets_EXTRA_FILES + "${RunCMake_SOURCE_DIR}/IncludeCommon.json.in" + "${RunCMake_SOURCE_DIR}/IncludeUserCommon.json.in" + "${RunCMake_SOURCE_DIR}/subdir/CMakePresets.json.in" + ) +run_cmake_presets(Include --list-presets) +unset(CMakePresets_EXTRA_FILES) +run_cmake_presets(IncludeNotFound) +run_cmake_presets(IncludeCycle) +set(CMakePresets_EXTRA_FILES + "${RunCMake_SOURCE_DIR}/IncludeCycle3Files2.json.in" + "${RunCMake_SOURCE_DIR}/IncludeCycle3Files3.json.in" + ) +run_cmake_presets(IncludeCycle3Files) +set(CMakePresets_EXTRA_FILES + "${RunCMake_SOURCE_DIR}/IncludeOutsideProjectIntermediate.json.in" + ) +run_cmake_presets(IncludeOutsideProject) +unset(CMakePresets_EXTRA_FILES) +run_cmake_presets(IncludeUserOutsideProject) + # Test the example from the documentation file(READ "${RunCMake_SOURCE_DIR}/../../../Help/manual/presets/example.json" _example) string(REPLACE "\"generator\": \"Ninja\"" "\"generator\": \"@RunCMake_GENERATOR@\"" _example "${_example}") diff --git a/Tests/RunCMake/CMakePresets/check.cmake b/Tests/RunCMake/CMakePresets/check.cmake index bf43c7ea37..cef43f46e3 100644 --- a/Tests/RunCMake/CMakePresets/check.cmake +++ b/Tests/RunCMake/CMakePresets/check.cmake @@ -12,4 +12,11 @@ if(PYTHON_EXECUTABLE AND CMake_TEST_JSON_SCHEMA) if(EXISTS "${RunCMake_TEST_SOURCE_DIR}/CMakeUserPresets.json") validate_schema("${RunCMake_TEST_SOURCE_DIR}/CMakeUserPresets.json" "${CMakeUserPresets_SCHEMA_EXPECTED_RESULT}") endif() + + if(NOT CMakePresets_EXTRA_FILES_SCHEMA_EXPECTED_RESULTS) + set(CMakePresets_EXTRA_FILES_SCHEMA_EXPECTED_RESULTS "${_CMakePresets_EXTRA_FILES_SCHEMA_EXPECTED_RESULTS}") + endif() + foreach(_f _r IN ZIP_LISTS _CMakePresets_EXTRA_FILES_OUT CMakePresets_EXTRA_FILES_SCHEMA_EXPECTED_RESULTS) + validate_schema("${_f}" "${_r}") + endforeach() endif() diff --git a/Tests/RunCMake/CMakePresets/subdir/CMakePresets.json.in b/Tests/RunCMake/CMakePresets/subdir/CMakePresets.json.in new file mode 100644 index 0000000000..deb908414e --- /dev/null +++ b/Tests/RunCMake/CMakePresets/subdir/CMakePresets.json.in @@ -0,0 +1,12 @@ +{ + "version": 4, + "include": [ + "../IncludeCommon.json" + ], + "configurePresets": [ + { + "name": "Subdir", + "inherits": "IncludeCommon" + } + ] +}