diff options
author | Kyle Edwards <kyle.edwards@kitware.com> | 2021-03-10 19:59:14 (GMT) |
---|---|---|
committer | Brad King <brad.king@kitware.com> | 2021-03-22 19:04:54 (GMT) |
commit | 8bc5c8961e552a15091b7f4d2c205ce90b8f764f (patch) | |
tree | ac9fe9a92c01accd1fee2c4914347369546f85ff /Source/cmCMakePresetsFileReadJSON.cxx | |
parent | ce6ea7c927b9f80f219a7783ce725bea4c24091f (diff) | |
download | CMake-8bc5c8961e552a15091b7f4d2c205ce90b8f764f.zip CMake-8bc5c8961e552a15091b7f4d2c205ce90b8f764f.tar.gz CMake-8bc5c8961e552a15091b7f4d2c205ce90b8f764f.tar.bz2 |
CMakePresets.json: Add the ability to conditionally disable presets
Diffstat (limited to 'Source/cmCMakePresetsFileReadJSON.cxx')
-rw-r--r-- | Source/cmCMakePresetsFileReadJSON.cxx | 205 |
1 files changed, 202 insertions, 3 deletions
diff --git a/Source/cmCMakePresetsFileReadJSON.cxx b/Source/cmCMakePresetsFileReadJSON.cxx index b71b176..e26e7b4 100644 --- a/Source/cmCMakePresetsFileReadJSON.cxx +++ b/Source/cmCMakePresetsFileReadJSON.cxx @@ -6,6 +6,7 @@ #include <utility> #include <vector> +#include <cm/memory> #include <cm/optional> #include <cmext/string_view> @@ -15,6 +16,7 @@ #include "cmsys/FStream.hxx" #include "cmCMakePresetsFile.h" +#include "cmCMakePresetsFileInternal.h" #include "cmJSONHelpers.h" #include "cmVersion.h" @@ -44,6 +46,180 @@ struct RootPresets std::vector<cmCMakePresetsFile::TestPreset> TestPresets; }; +std::unique_ptr<cmCMakePresetsFileInternal::NotCondition> InvertCondition( + std::unique_ptr<cmCMakePresetsFile::Condition> condition) +{ + auto retval = cm::make_unique<cmCMakePresetsFileInternal::NotCondition>(); + retval->SubCondition = std::move(condition); + return retval; +} + +auto const ConditionStringHelper = cmJSONStringHelper<ReadFileResult>( + ReadFileResult::READ_OK, ReadFileResult::INVALID_CONDITION); + +auto const ConditionBoolHelper = cmJSONBoolHelper<ReadFileResult>( + ReadFileResult::READ_OK, ReadFileResult::INVALID_CONDITION); + +auto const ConditionStringListHelper = + cmJSONVectorHelper<std::string, ReadFileResult>( + ReadFileResult::READ_OK, ReadFileResult::INVALID_CONDITION, + ConditionStringHelper); + +auto const ConstConditionHelper = + cmJSONObjectHelper<cmCMakePresetsFileInternal::ConstCondition, + ReadFileResult>(ReadFileResult::READ_OK, + ReadFileResult::INVALID_CONDITION, false) + .Bind<std::string>("type"_s, nullptr, ConditionStringHelper, true) + .Bind("value"_s, &cmCMakePresetsFileInternal::ConstCondition::Value, + ConditionBoolHelper, true); + +auto const EqualsConditionHelper = + cmJSONObjectHelper<cmCMakePresetsFileInternal::EqualsCondition, + ReadFileResult>(ReadFileResult::READ_OK, + ReadFileResult::INVALID_CONDITION, false) + .Bind<std::string>("type"_s, nullptr, ConditionStringHelper, true) + .Bind("lhs"_s, &cmCMakePresetsFileInternal::EqualsCondition::Lhs, + ConditionStringHelper, true) + .Bind("rhs"_s, &cmCMakePresetsFileInternal::EqualsCondition::Rhs, + ConditionStringHelper, true); + +auto const InListConditionHelper = + cmJSONObjectHelper<cmCMakePresetsFileInternal::InListCondition, + ReadFileResult>(ReadFileResult::READ_OK, + ReadFileResult::INVALID_CONDITION, false) + .Bind<std::string>("type"_s, nullptr, ConditionStringHelper, true) + .Bind("string"_s, &cmCMakePresetsFileInternal::InListCondition::String, + ConditionStringHelper, true) + .Bind("list"_s, &cmCMakePresetsFileInternal::InListCondition::List, + ConditionStringListHelper, true); + +ReadFileResult SubConditionHelper( + std::unique_ptr<cmCMakePresetsFile::Condition>& out, + const Json::Value* value); + +auto const ListConditionVectorHelper = + cmJSONVectorHelper<std::unique_ptr<cmCMakePresetsFile::Condition>, + ReadFileResult>(ReadFileResult::READ_OK, + ReadFileResult::INVALID_CONDITION, + SubConditionHelper); +auto const AnyAllOfConditionHelper = + cmJSONObjectHelper<cmCMakePresetsFileInternal::AnyAllOfCondition, + ReadFileResult>(ReadFileResult::READ_OK, + ReadFileResult::INVALID_CONDITION, false) + .Bind<std::string>("type"_s, nullptr, ConditionStringHelper, true) + .Bind("conditions"_s, + &cmCMakePresetsFileInternal::AnyAllOfCondition::Conditions, + ListConditionVectorHelper); + +auto const NotConditionHelper = + cmJSONObjectHelper<cmCMakePresetsFileInternal::NotCondition, ReadFileResult>( + ReadFileResult::READ_OK, ReadFileResult::INVALID_CONDITION, false) + .Bind<std::string>("type"_s, nullptr, ConditionStringHelper, true) + .Bind("condition"_s, + &cmCMakePresetsFileInternal::NotCondition::SubCondition, + SubConditionHelper); + +ReadFileResult ConditionHelper( + std::unique_ptr<cmCMakePresetsFile::Condition>& out, + const Json::Value* value) +{ + if (!value) { + out.reset(); + return ReadFileResult::READ_OK; + } + + if (value->isBool()) { + auto c = cm::make_unique<cmCMakePresetsFileInternal::ConstCondition>(); + c->Value = value->asBool(); + out = std::move(c); + return ReadFileResult::READ_OK; + } + + if (value->isNull()) { + out = cm::make_unique<cmCMakePresetsFileInternal::NullCondition>(); + return ReadFileResult::READ_OK; + } + + if (value->isObject()) { + if (!value->isMember("type")) { + return ReadFileResult::INVALID_CONDITION; + } + + if (!(*value)["type"].isString()) { + return ReadFileResult::INVALID_CONDITION; + } + auto type = (*value)["type"].asString(); + + if (type == "const") { + auto c = cm::make_unique<cmCMakePresetsFileInternal::ConstCondition>(); + CHECK_OK(ConstConditionHelper(*c, value)); + out = std::move(c); + return ReadFileResult::READ_OK; + } + + if (type == "equals" || type == "notEquals") { + auto c = cm::make_unique<cmCMakePresetsFileInternal::EqualsCondition>(); + CHECK_OK(EqualsConditionHelper(*c, value)); + out = std::move(c); + if (type == "notEquals") { + out = InvertCondition(std::move(out)); + } + return ReadFileResult::READ_OK; + } + + if (type == "inList" || type == "notInList") { + auto c = cm::make_unique<cmCMakePresetsFileInternal::InListCondition>(); + CHECK_OK(InListConditionHelper(*c, value)); + out = std::move(c); + if (type == "notInList") { + out = InvertCondition(std::move(out)); + } + return ReadFileResult::READ_OK; + } + + if (type == "anyOf" || type == "allOf") { + auto c = + cm::make_unique<cmCMakePresetsFileInternal::AnyAllOfCondition>(); + c->StopValue = (type == "anyOf"); + CHECK_OK(AnyAllOfConditionHelper(*c, value)); + out = std::move(c); + return ReadFileResult::READ_OK; + } + + if (type == "not") { + auto c = cm::make_unique<cmCMakePresetsFileInternal::NotCondition>(); + CHECK_OK(NotConditionHelper(*c, value)); + out = std::move(c); + return ReadFileResult::READ_OK; + } + } + + return ReadFileResult::INVALID_CONDITION; +} + +ReadFileResult PresetConditionHelper( + std::shared_ptr<cmCMakePresetsFile::Condition>& out, + const Json::Value* value) +{ + std::unique_ptr<cmCMakePresetsFile::Condition> ptr; + auto result = ConditionHelper(ptr, value); + out = std::move(ptr); + return result; +} + +ReadFileResult SubConditionHelper( + std::unique_ptr<cmCMakePresetsFile::Condition>& out, + const Json::Value* value) +{ + std::unique_ptr<cmCMakePresetsFile::Condition> ptr; + auto result = ConditionHelper(ptr, value); + if (ptr && ptr->IsNull()) { + return ReadFileResult::INVALID_CONDITION; + } + out = std::move(ptr); + return result; +} + cmJSONHelper<std::nullptr_t, ReadFileResult> VendorHelper(ReadFileResult error) { return [error](std::nullptr_t& /*out*/, @@ -306,7 +482,9 @@ auto const ConfigurePresetHelper = false) .Bind("warnings"_s, PresetWarningsHelper, false) .Bind("errors"_s, PresetErrorsHelper, false) - .Bind("debug"_s, PresetDebugHelper, false); + .Bind("debug"_s, PresetDebugHelper, false) + .Bind("condition"_s, &ConfigurePreset::ConditionEvaluator, + PresetConditionHelper, false); auto const BuildPresetHelper = cmJSONObjectHelper<BuildPreset, ReadFileResult>( @@ -335,7 +513,9 @@ auto const BuildPresetHelper = false) .Bind("verbose"_s, &BuildPreset::Verbose, PresetOptionalBoolHelper, false) .Bind("nativeToolOptions"_s, &BuildPreset::NativeToolOptions, - PresetVectorStringHelper, false); + PresetVectorStringHelper, false) + .Bind("condition"_s, &BuildPreset::ConditionEvaluator, + PresetConditionHelper, false); ReadFileResult TestPresetOutputVerbosityHelper( TestPreset::OutputOptions::VerbosityEnum& out, const Json::Value* value) @@ -651,7 +831,9 @@ auto const TestPresetHelper = false) .Bind("filter"_s, &TestPreset::Filter, TestPresetFilterHelper, false) .Bind("execution"_s, &TestPreset::Execution, TestPresetExecutionHelper, - false); + false) + .Bind("condition"_s, &TestPreset::ConditionEvaluator, + PresetConditionHelper, false); auto const ConfigurePresetsHelper = cmJSONVectorHelper<ConfigurePreset, ReadFileResult>( @@ -766,6 +948,11 @@ cmCMakePresetsFile::ReadFileResult cmCMakePresetsFile::ReadJSONFile( return ReadFileResult::INSTALL_PREFIX_UNSUPPORTED; } + // Support for conditions added in version 3. + if (v < 3 && preset.ConditionEvaluator) { + return ReadFileResult::CONDITION_UNSUPPORTED; + } + this->ConfigurePresetOrder.push_back(preset.Name); } @@ -781,6 +968,12 @@ cmCMakePresetsFile::ReadFileResult cmCMakePresetsFile::ReadJSONFile( if (!this->BuildPresets.emplace(preset.Name, presetPair).second) { return ReadFileResult::DUPLICATE_PRESETS; } + + // Support for conditions added in version 3. + if (v < 3 && preset.ConditionEvaluator) { + return ReadFileResult::CONDITION_UNSUPPORTED; + } + this->BuildPresetOrder.push_back(preset.Name); } @@ -796,6 +989,12 @@ cmCMakePresetsFile::ReadFileResult cmCMakePresetsFile::ReadJSONFile( if (!this->TestPresets.emplace(preset.Name, presetPair).second) { return ReadFileResult::DUPLICATE_PRESETS; } + + // Support for conditions added in version 3. + if (v < 3 && preset.ConditionEvaluator) { + return ReadFileResult::CONDITION_UNSUPPORTED; + } + this->TestPresetOrder.push_back(preset.Name); } |