summaryrefslogtreecommitdiffstats
path: root/Source/cmCMakePresetsFileReadJSON.cxx
diff options
context:
space:
mode:
authorKyle Edwards <kyle.edwards@kitware.com>2021-03-10 19:59:14 (GMT)
committerBrad King <brad.king@kitware.com>2021-03-22 19:04:54 (GMT)
commit8bc5c8961e552a15091b7f4d2c205ce90b8f764f (patch)
treeac9fe9a92c01accd1fee2c4914347369546f85ff /Source/cmCMakePresetsFileReadJSON.cxx
parentce6ea7c927b9f80f219a7783ce725bea4c24091f (diff)
downloadCMake-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.cxx205
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);
}