浏览代码

Merge topic 'presets-schema'

f1a7179520 presets: Add $schema property to JSON schema
f83771dfce presets: Add missing spaces in JSON schema

Acked-by: Kitware Robot <[email protected]>
Merge-request: !8777
Brad King 2 年之前
父节点
当前提交
976659c846

+ 9 - 0
Help/manual/cmake-presets.7.rst

@@ -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:

+ 55 - 32
Help/manual/presets/schema.json

@@ -9,9 +9,9 @@
           "const": 1,
           "description": "A required integer representing the version of the JSON schema."
         },
-        "cmakeMinimumRequired": { "$ref": "#/definitions/cmakeMinimumRequired"},
+        "cmakeMinimumRequired": { "$ref": "#/definitions/cmakeMinimumRequired" },
         "vendor": { "$ref": "#/definitions/vendor" },
-        "configurePresets": { "$ref": "#/definitions/configurePresetsV1"}
+        "configurePresets": { "$ref": "#/definitions/configurePresetsV1" }
       },
       "additionalProperties": false
     },
@@ -21,11 +21,11 @@
           "const": 2,
           "description": "A required integer representing the version of the JSON schema."
         },
-        "cmakeMinimumRequired": { "$ref": "#/definitions/cmakeMinimumRequired"},
+        "cmakeMinimumRequired": { "$ref": "#/definitions/cmakeMinimumRequired" },
         "vendor": { "$ref": "#/definitions/vendor" },
-        "configurePresets": { "$ref": "#/definitions/configurePresetsV1"},
-        "buildPresets": { "$ref": "#/definitions/buildPresetsV2"},
-        "testPresets": { "$ref": "#/definitions/testPresetsV2"}
+        "configurePresets": { "$ref": "#/definitions/configurePresetsV1" },
+        "buildPresets": { "$ref": "#/definitions/buildPresetsV2" },
+        "testPresets": { "$ref": "#/definitions/testPresetsV2" }
       },
       "additionalProperties": false
     },
@@ -35,11 +35,11 @@
           "const": 3,
           "description": "A required integer representing the version of the JSON schema."
         },
-        "cmakeMinimumRequired": { "$ref": "#/definitions/cmakeMinimumRequired"},
+        "cmakeMinimumRequired": { "$ref": "#/definitions/cmakeMinimumRequired" },
         "vendor": { "$ref": "#/definitions/vendor" },
-        "configurePresets": { "$ref": "#/definitions/configurePresetsV3"},
-        "buildPresets": { "$ref": "#/definitions/buildPresetsV3"},
-        "testPresets": { "$ref": "#/definitions/testPresetsV3"}
+        "configurePresets": { "$ref": "#/definitions/configurePresetsV3" },
+        "buildPresets": { "$ref": "#/definitions/buildPresetsV3" },
+        "testPresets": { "$ref": "#/definitions/testPresetsV3" }
       },
       "additionalProperties": false
     },
@@ -49,12 +49,12 @@
           "const": 4,
           "description": "A required integer representing the version of the JSON schema."
         },
-        "cmakeMinimumRequired": { "$ref": "#/definitions/cmakeMinimumRequired"},
+        "cmakeMinimumRequired": { "$ref": "#/definitions/cmakeMinimumRequired" },
         "vendor": { "$ref": "#/definitions/vendor" },
-        "configurePresets": { "$ref": "#/definitions/configurePresetsV3"},
-        "buildPresets": { "$ref": "#/definitions/buildPresetsV4"},
-        "testPresets": { "$ref": "#/definitions/testPresetsV3"},
-        "include": { "$ref": "#/definitions/include"}
+        "configurePresets": { "$ref": "#/definitions/configurePresetsV3" },
+        "buildPresets": { "$ref": "#/definitions/buildPresetsV4" },
+        "testPresets": { "$ref": "#/definitions/testPresetsV3" },
+        "include": { "$ref": "#/definitions/include" }
       },
       "additionalProperties": false
     },
@@ -64,12 +64,12 @@
           "const": 5,
           "description": "A required integer representing the version of the JSON schema."
         },
-        "cmakeMinimumRequired": { "$ref": "#/definitions/cmakeMinimumRequired"},
+        "cmakeMinimumRequired": { "$ref": "#/definitions/cmakeMinimumRequired" },
         "vendor": { "$ref": "#/definitions/vendor" },
-        "configurePresets": { "$ref": "#/definitions/configurePresetsV3"},
-        "buildPresets": { "$ref": "#/definitions/buildPresetsV4"},
-        "testPresets": { "$ref": "#/definitions/testPresetsV5"},
-        "include": { "$ref": "#/definitions/include"}
+        "configurePresets": { "$ref": "#/definitions/configurePresetsV3" },
+        "buildPresets": { "$ref": "#/definitions/buildPresetsV4" },
+        "testPresets": { "$ref": "#/definitions/testPresetsV5" },
+        "include": { "$ref": "#/definitions/include" }
       },
       "additionalProperties": false
     },
@@ -79,14 +79,14 @@
           "const": 6,
           "description": "A required integer representing the version of the JSON schema."
         },
-        "cmakeMinimumRequired": { "$ref": "#/definitions/cmakeMinimumRequired"},
+        "cmakeMinimumRequired": { "$ref": "#/definitions/cmakeMinimumRequired" },
         "vendor": { "$ref": "#/definitions/vendor" },
-        "configurePresets": { "$ref": "#/definitions/configurePresetsV3"},
-        "buildPresets": { "$ref": "#/definitions/buildPresetsV4"},
-        "testPresets": { "$ref": "#/definitions/testPresetsV6"},
-        "packagePresets": { "$ref": "#/definitions/packagePresetsV6"},
+        "configurePresets": { "$ref": "#/definitions/configurePresetsV3" },
+        "buildPresets": { "$ref": "#/definitions/buildPresetsV4" },
+        "testPresets": { "$ref": "#/definitions/testPresetsV6" },
+        "packagePresets": { "$ref": "#/definitions/packagePresetsV6" },
         "workflowPresets": { "$ref": "#/definitions/workflowPresetsV6" },
-        "include": { "$ref": "#/definitions/include"}
+        "include": { "$ref": "#/definitions/include" }
       },
       "additionalProperties": false
     },
@@ -96,14 +96,32 @@
           "const": 7,
           "description": "A required integer representing the version of the JSON schema."
         },
-        "cmakeMinimumRequired": { "$ref": "#/definitions/cmakeMinimumRequired"},
+        "cmakeMinimumRequired": { "$ref": "#/definitions/cmakeMinimumRequired" },
         "vendor": { "$ref": "#/definitions/vendor" },
-        "configurePresets": { "$ref": "#/definitions/configurePresetsV7"},
-        "buildPresets": { "$ref": "#/definitions/buildPresetsV4"},
-        "testPresets": { "$ref": "#/definitions/testPresetsV6"},
-        "packagePresets": { "$ref": "#/definitions/packagePresetsV6"},
+        "configurePresets": { "$ref": "#/definitions/configurePresetsV7" },
+        "buildPresets": { "$ref": "#/definitions/buildPresetsV4" },
+        "testPresets": { "$ref": "#/definitions/testPresetsV6" },
+        "packagePresets": { "$ref": "#/definitions/packagePresetsV6" },
         "workflowPresets": { "$ref": "#/definitions/workflowPresetsV6" },
-        "include": { "$ref": "#/definitions/include"}
+        "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
     }
@@ -112,6 +130,11 @@
     "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.",

+ 5 - 0
Help/release/dev/presets-schema.rst

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

+ 5 - 0
Source/cmCMakePresetsErrors.cxx

@@ -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");
+}
 }

+ 2 - 0
Source/cmCMakePresetsErrors.h

@@ -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);
 }

+ 3 - 0
Source/cmCMakePresetsGraphInternal.h

@@ -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();
 }

+ 17 - 2
Source/cmCMakePresetsGraphReadJSON.cxx

@@ -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;

+ 7 - 0
Tests/RunCMake/CMakePresets/RunCMakeTest.cmake

@@ -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)

+ 1 - 0
Tests/RunCMake/CMakePresets/SchemaNotSupported-result.txt

@@ -0,0 +1 @@
+1

+ 3 - 0
Tests/RunCMake/CMakePresets/SchemaNotSupported-stderr.txt

@@ -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$

+ 4 - 0
Tests/RunCMake/CMakePresets/SchemaNotSupported.json.in

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

+ 1 - 0
Tests/RunCMake/CMakePresets/SchemaSupported-result.txt

@@ -0,0 +1 @@
+0

+ 4 - 0
Tests/RunCMake/CMakePresets/SchemaSupported.json.in

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