presets: Add $schema property to JSON schema

Many modern code editors have support for JSON Schema.  When you specify
the `$schema` property in a JSON file, the editor can provide features
like auto-completion, error checking, etc., which can improve your
efficiency when writing and modifying the `CMakePresets.json` file.
This commit is contained in:
ChenMoFeiJin
2023-09-07 20:04:02 +08:00
parent f83771dfce
commit f1a7179520
13 changed files with 84 additions and 2 deletions

View File

@@ -41,6 +41,15 @@ The files are a JSON document with an object as the root:
The root object recognizes the following fields:
``$schema``
An optional string that provides a URI to the JSON schema that describes the
structure of this JSON document. This field is used for validation and
autocompletion in editors that support JSON schema. It doesn't affect the
behavior of the document itself. If this field is not specified, the JSON
document will still be valid, but tools that use JSON schema for validation
and autocompletion may not function correctly.
This is allowed in preset files specifying version ``8`` or above.
``version``
A required integer representing the version of the JSON schema.
The supported versions are:

View File

@@ -106,12 +106,35 @@
"include": { "$ref": "#/definitions/include" }
},
"additionalProperties": false
},
{
"properties": {
"$schema": { "$ref": "#/definitions/$schema" },
"version": {
"const": 8,
"description": "A required integer representing the version of the JSON schema."
},
"cmakeMinimumRequired": { "$ref": "#/definitions/cmakeMinimumRequired" },
"vendor": { "$ref": "#/definitions/vendor" },
"configurePresets": { "$ref": "#/definitions/configurePresetsV7" },
"buildPresets": { "$ref": "#/definitions/buildPresetsV4" },
"testPresets": { "$ref": "#/definitions/testPresetsV6" },
"packagePresets": { "$ref": "#/definitions/packagePresetsV6" },
"workflowPresets": { "$ref": "#/definitions/workflowPresetsV6" },
"include": { "$ref": "#/definitions/include" }
},
"additionalProperties": false
}
],
"required": [
"version"
],
"definitions": {
"$schema": {
"type": "string",
"description": "The schema against which to verify this document.",
"format": "uri-reference"
},
"cmakeMinimumRequired": {
"type": "object",
"description": "An optional object representing the minimum version of CMake needed to build this project.",

View File

@@ -0,0 +1,5 @@
presets-schema
--------------
* :manual:`cmake-presets(7)` files now support schema version ``8``.
It adds support for a ``$schema`` field.

View File

@@ -302,4 +302,9 @@ void PRESET_MISSING_FIELD(const std::string& presetName,
state->AddError(cmStrCat("Preset \"", presetName, "\" missing field \"",
missingField, "\""));
}
void SCHEMA_UNSUPPORTED(cmJSONState* state)
{
state->AddError("File version must be 8 or higher for $schema support");
}
}

View File

@@ -113,4 +113,6 @@ JsonErrors::ErrorGenerator INVALID_ROOT_OBJECT(
void PRESET_MISSING_FIELD(const std::string& presetName,
const std::string& missingField, cmJSONState* state);
void SCHEMA_UNSUPPORTED(cmJSONState* state);
}

View File

@@ -2,6 +2,7 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#pragma once
#include <cstddef>
#include <memory>
#include <string>
#include <vector>
@@ -179,4 +180,6 @@ bool PresetVectorOneOrMoreStringHelper(std::vector<std::string>& out,
bool EnvironmentMapHelper(
std::map<std::string, cm::optional<std::string>>& out,
const Json::Value* value, cmJSONState* state);
cmJSONHelper<std::nullptr_t> SchemaHelper();
}

View File

@@ -38,7 +38,7 @@ using MacroExpander = cmCMakePresetsGraphInternal::MacroExpander;
using cmCMakePresetsGraphInternal::ExpandMacros;
constexpr int MIN_VERSION = 1;
constexpr int MAX_VERSION = 7;
constexpr int MAX_VERSION = 8;
struct CMakeVersion
{
@@ -294,7 +294,9 @@ auto const RootPresetsHelper =
.Bind<std::nullptr_t>("vendor"_s, nullptr,
cmCMakePresetsGraphInternal::VendorHelper(
cmCMakePresetsErrors::INVALID_ROOT),
false);
false)
.Bind<std::nullptr_t>("$schema"_s, nullptr,
cmCMakePresetsGraphInternal::SchemaHelper(), false);
}
namespace cmCMakePresetsGraphInternal {
@@ -413,6 +415,13 @@ bool EnvironmentMapHelper(
return helper(out, value, state);
}
cmJSONHelper<std::nullptr_t> SchemaHelper()
{
return [](std::nullptr_t&, const Json::Value*, cmJSONState*) -> bool {
return true;
};
}
}
bool cmCMakePresetsGraph::ReadJSONFile(const std::string& filename,
@@ -488,6 +497,12 @@ bool cmCMakePresetsGraph::ReadJSONFile(const std::string& filename,
return false;
}
// Support for $schema added in version 8.
if (v < 8 && root.isMember("$schema")) {
cmCMakePresetsErrors::SCHEMA_UNSUPPORTED(&this->parseState);
return false;
}
RootPresets presets;
if ((result = RootPresetsHelper(presets, &root, &parseState)) != true) {
return result;

View File

@@ -153,6 +153,13 @@ run_cmake_presets(ConditionFuture)
run_cmake_presets(SubConditionNull)
run_cmake_presets(TraceNotSupported)
set(CMakePresets_NO_PRESET 1)
set(CMakePresets_SCHEMA_EXPECTED_RESULT 0)
run_cmake_presets(SchemaSupported --list-presets)
set(CMakePresets_SCHEMA_EXPECTED_RESULT 1)
run_cmake_presets(SchemaNotSupported --list-presets)
unset(CMakePresets_NO_PRESET)
# Test cmakeMinimumRequired field
run_cmake_presets(MinimumRequiredInvalid)
set(CMakePresets_SCHEMA_EXPECTED_RESULT 0)

View File

@@ -0,0 +1 @@
1

View File

@@ -0,0 +1,3 @@
^CMake Error: Could not read presets from [^
]*/Tests/RunCMake/CMakePresets/SchemaNotSupported:
File version must be 8 or higher for [$]schema support$

View File

@@ -0,0 +1,4 @@
{
"version": 7,
"$schema": "https://example.com/schema.json"
}

View File

@@ -0,0 +1 @@
0

View File

@@ -0,0 +1,4 @@
{
"version": 8,
"$schema": "https://example.com/schema.json"
}