CMakePresets.json: Add matches condition

This commit is contained in:
Kyle Edwards 2021-03-31 10:24:24 -04:00
parent bd4ebf1e58
commit 5ac8b923f5
11 changed files with 194 additions and 0 deletions

View File

@ -864,6 +864,22 @@ object, it has the following fields:
A required list of strings to search. This field supports macro
expansion, and uses short-circuit evaluation.
``"matches"``
``"notMatches"``
Indicates that the condition searches for a regular expression in a string.
The condition object will have the following additional fields:
``string``
A required string to search. This field supports macro expansion.
``regex``
A required regular expression to search for. This field supports macro
expansion.
``"anyOf"``
``"allOf"``

View File

@ -1108,6 +1108,54 @@
],
"additionalProperties": false
},
{
"type": "object",
"properties": {
"type": {
"type": "string",
"description": "A required string specifying the type of the condition.",
"const": "matches"
},
"string": {
"type": "string",
"description": "A required string to search. This field supports macro expansion."
},
"regex": {
"type": "string",
"description": "A required regular expression to search for. This field supports macro expansion."
}
},
"required": [
"type",
"string",
"regex"
],
"additionalProperties": false
},
{
"type": "object",
"properties": {
"type": {
"type": "string",
"description": "A required string specifying the type of the condition.",
"const": "notMatches"
},
"string": {
"type": "string",
"description": "A required string to search. This field supports macro expansion."
},
"regex": {
"type": "string",
"description": "A required regular expression to search for. This field supports macro expansion."
}
},
"required": [
"type",
"string",
"regex"
],
"additionalProperties": false
},
{
"type": "object",
"properties": {

View File

@ -11,6 +11,8 @@
#include <cm/string_view>
#include "cmsys/RegularExpression.hxx"
#include "cmCMakePresetsFileInternal.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
@ -561,6 +563,24 @@ bool cmCMakePresetsFileInternal::InListCondition::Evaluate(
return true;
}
bool cmCMakePresetsFileInternal::MatchesCondition::Evaluate(
const std::vector<MacroExpander>& expanders, int version,
cm::optional<bool>& out) const
{
std::string str = this->String;
CHECK_EXPAND(out, str, expanders, version);
std::string regexStr = this->Regex;
CHECK_EXPAND(out, regexStr, expanders, version);
cmsys::RegularExpression regex;
if (!regex.compile(regexStr)) {
return false;
}
out = regex.find(str);
return true;
}
bool cmCMakePresetsFileInternal::AnyAllOfCondition::Evaluate(
const std::vector<MacroExpander>& expanders, int version,
cm::optional<bool>& out) const

View File

@ -81,6 +81,16 @@ public:
std::vector<std::string> List;
};
class MatchesCondition : public cmCMakePresetsFile::Condition
{
public:
bool Evaluate(const std::vector<MacroExpander>& expanders, int version,
cm::optional<bool>& out) const override;
std::string String;
std::string Regex;
};
class AnyAllOfCondition : public cmCMakePresetsFile::Condition
{
public:

View File

@ -93,6 +93,16 @@ auto const InListConditionHelper =
.Bind("list"_s, &cmCMakePresetsFileInternal::InListCondition::List,
ConditionStringListHelper, true);
auto const MatchesConditionHelper =
cmJSONObjectHelper<cmCMakePresetsFileInternal::MatchesCondition,
ReadFileResult>(ReadFileResult::READ_OK,
ReadFileResult::INVALID_CONDITION, false)
.Bind<std::string>("type"_s, nullptr, ConditionStringHelper, true)
.Bind("string"_s, &cmCMakePresetsFileInternal::MatchesCondition::String,
ConditionStringHelper, true)
.Bind("regex"_s, &cmCMakePresetsFileInternal::MatchesCondition::Regex,
ConditionStringHelper, true);
ReadFileResult SubConditionHelper(
std::unique_ptr<cmCMakePresetsFile::Condition>& out,
const Json::Value* value);
@ -177,6 +187,16 @@ ReadFileResult ConditionHelper(
return ReadFileResult::READ_OK;
}
if (type == "matches" || type == "notMatches") {
auto c = cm::make_unique<cmCMakePresetsFileInternal::MatchesCondition>();
CHECK_OK(MatchesConditionHelper(*c, value));
out = std::move(c);
if (type == "notMatches") {
out = InvertCondition(std::move(out));
}
return ReadFileResult::READ_OK;
}
if (type == "anyOf" || type == "allOf") {
auto c =
cm::make_unique<cmCMakePresetsFileInternal::AnyAllOfCondition>();

View File

@ -180,6 +180,63 @@
]
}
},
{
"name": "MatchesTrue",
"inherits": "Base",
"condition": {
"type": "matches",
"string": "aaa",
"regex": "^a*$"
}
},
{
"name": "MatchesFalse",
"inherits": "Base",
"condition": {
"type": "matches",
"string": "aab",
"regex": "^a*$"
}
},
{
"name": "MatchesMacroString",
"inherits": "Base",
"condition": {
"type": "matches",
"string": "${presetName}",
"regex": "^Matches"
}
},
{
"name": "MatchesMacroRegex",
"inherits": "Base",
"condition": {
"type": "matches",
"string": "stuff",
"regex": "$env{CONDITION_REGEX}"
},
"environment": {
"CONDITION_REGEX": "^stuf*$"
}
},
{
"name": "NotMatchesTrue",
"inherits": "Base",
"condition": {
"type": "notMatches",
"string": "aab",
"regex": "^a*$"
}
},
{
"name": "NotMatchesFalse",
"inherits": "Base",
"condition": {
"type": "notMatches",
"string": "aaa",
"regex": "^a*$"
}
},
{
"name": "AnyOfTrue1",
"inherits": "Base",

View File

@ -0,0 +1 @@
1

View File

@ -0,0 +1,2 @@
^CMake Error: Could not read presets from [^
]*/Tests/RunCMake/CMakePresets/InvalidRegex: Invalid macro expansion$

View File

@ -0,0 +1,15 @@
{
"version": 3,
"configurePresets": [
{
"name": "InvalidRegex",
"binaryDir": "${sourceDir}/build",
"generator": "@RunCMake_GENERATOR@",
"condition": {
"type": "matches",
"string": "a",
"regex": "+"
}
}
]
}

View File

@ -12,6 +12,10 @@ Available configure presets:
"InListMacroList"
"InListShortCircuit"
"NotInListTrue"
"MatchesTrue"
"MatchesMacroString"
"MatchesMacroRegex"
"NotMatchesTrue"
"AnyOfTrue1"
"AnyOfTrue2"
"AnyOfShortCircuit"

View File

@ -117,6 +117,7 @@ run_cmake_presets(NoSuchMacro)
run_cmake_presets(EnvCycle)
run_cmake_presets(EmptyEnv)
run_cmake_presets(EmptyPenv)
run_cmake_presets(InvalidRegex)
set(CMakePresets_SCHEMA_EXPECTED_RESULT 1)
run_cmake_presets(ConditionFuture)
run_cmake_presets(SubConditionNull)