diff --git a/Tests/RunCMake/CMakePresets/RunCMakeTest.cmake b/Tests/RunCMake/CMakePresets/RunCMakeTest.cmake index 6660eaa093..2076ab8762 100644 --- a/Tests/RunCMake/CMakePresets/RunCMakeTest.cmake +++ b/Tests/RunCMake/CMakePresets/RunCMakeTest.cmake @@ -9,8 +9,6 @@ endif() set(RunCMake-check-file check.cmake) -include("${RunCMake_SOURCE_DIR}/validate_schema.cmake") - function(reset_cmake_presets_directory name) set(RunCMake_TEST_SOURCE_DIR "${RunCMake_BINARY_DIR}/${name}") file(REMOVE_RECURSE "${RunCMake_TEST_SOURCE_DIR}") @@ -130,7 +128,9 @@ endfunction() # Test CMakePresets.json errors set(CMakePresets_SCHEMA_EXPECTED_RESULT 1) run_cmake_presets(NoCMakePresets) +set(CMakePresets_SCHEMA_EXPECTED_RESULT 3) run_cmake_presets(Comment) +run_cmake_presets(JSONParseError) set(CMakePresets_SCHEMA_EXPECTED_RESULT 0) run_cmake_presets(NoCommentValid) run_cmake_presets(CommentValid) @@ -142,7 +142,6 @@ run_cmake_presets(NoGraphvizValid) run_cmake_presets(GraphvizValid) set(CMakePresets_SCHEMA_EXPECTED_RESULT 1) run_cmake_presets(GraphvizValidOldSchema) -run_cmake_presets(JSONParseError) run_cmake_presets(InvalidRoot) run_cmake_presets(NoVersion) run_cmake_presets(InvalidVersion) diff --git a/Tests/RunCMake/CMakePresets/check.cmake b/Tests/RunCMake/CMakePresets/check.cmake index 03f96a9554..aff071d98e 100644 --- a/Tests/RunCMake/CMakePresets/check.cmake +++ b/Tests/RunCMake/CMakePresets/check.cmake @@ -1,22 +1,40 @@ -if(Python_EXECUTABLE AND CMake_TEST_JSON_SCHEMA) - if(NOT CMakePresets_SCHEMA_EXPECTED_RESULT) - set(CMakePresets_SCHEMA_EXPECTED_RESULT 0) - endif() - if(EXISTS "${RunCMake_TEST_SOURCE_DIR}/CMakePresets.json") - validate_schema("${RunCMake_TEST_SOURCE_DIR}/CMakePresets.json" "${CMakePresets_SCHEMA_EXPECTED_RESULT}") - endif() - - if(NOT CMakeUserPresets_SCHEMA_EXPECTED_RESULT) - set(CMakeUserPresets_SCHEMA_EXPECTED_RESULT 0) - endif() - if(EXISTS "${RunCMake_TEST_SOURCE_DIR}/CMakeUserPresets.json") - validate_schema("${RunCMake_TEST_SOURCE_DIR}/CMakeUserPresets.json" "${CMakeUserPresets_SCHEMA_EXPECTED_RESULT}") - endif() - - if(NOT CMakePresets_EXTRA_FILES_SCHEMA_EXPECTED_RESULTS) - set(CMakePresets_EXTRA_FILES_SCHEMA_EXPECTED_RESULTS "${_CMakePresets_EXTRA_FILES_SCHEMA_EXPECTED_RESULTS}") - endif() - foreach(_f _r IN ZIP_LISTS _CMakePresets_EXTRA_FILES_OUT CMakePresets_EXTRA_FILES_SCHEMA_EXPECTED_RESULTS) - validate_schema("${_f}" "${_r}") - endforeach() +if(NOT (Python_EXECUTABLE AND CMake_TEST_JSON_SCHEMA)) + return() endif() + +include("${RunCMake_SOURCE_DIR}/../validate_json_schema.cmake") + +if(NOT CMakePresets_SCHEMA_EXPECTED_RESULT) + set(CMakePresets_SCHEMA_EXPECTED_RESULT 0) +endif() + +set(CMakePresets_JSON_SCHEMA "${RunCMake_SOURCE_DIR}/../../../Help/manual/presets/schema.json") + +if(EXISTS "${RunCMake_TEST_SOURCE_DIR}/CMakePresets.json") + validate_json_schema( + "${CMakePresets_JSON_SCHEMA}" + "${RunCMake_TEST_SOURCE_DIR}/CMakePresets.json" + EXPECTED_RESULT "${CMakePresets_SCHEMA_EXPECTED_RESULT}" + ) +endif() + +if(NOT CMakeUserPresets_SCHEMA_EXPECTED_RESULT) + set(CMakeUserPresets_SCHEMA_EXPECTED_RESULT 0) +endif() +if(EXISTS "${RunCMake_TEST_SOURCE_DIR}/CMakeUserPresets.json") + validate_json_schema( + "${CMakePresets_JSON_SCHEMA}" + "${RunCMake_TEST_SOURCE_DIR}/CMakeUserPresets.json" + EXPECTED_RESULT "${CMakeUserPresets_SCHEMA_EXPECTED_RESULT}" + ) +endif() + +if(NOT CMakePresets_EXTRA_FILES_SCHEMA_EXPECTED_RESULTS) + set(CMakePresets_EXTRA_FILES_SCHEMA_EXPECTED_RESULTS "${_CMakePresets_EXTRA_FILES_SCHEMA_EXPECTED_RESULTS}") +endif() +foreach(_f _r IN ZIP_LISTS _CMakePresets_EXTRA_FILES_OUT CMakePresets_EXTRA_FILES_SCHEMA_EXPECTED_RESULTS) + validate_json_schema( + "${CMakePresets_JSON_SCHEMA}" "${_f}" + EXPECTED_RESULT "${_r}" + ) +endforeach() diff --git a/Tests/RunCMake/CMakePresets/validate_schema.cmake b/Tests/RunCMake/CMakePresets/validate_schema.cmake deleted file mode 100644 index 8b4f0b63d3..0000000000 --- a/Tests/RunCMake/CMakePresets/validate_schema.cmake +++ /dev/null @@ -1,17 +0,0 @@ -function(validate_schema file expected_result) - if (NOT CMakePresets_VALIDATE_SCRIPT_PATH) - set(CMakePresets_VALIDATE_SCRIPT_PATH "${RunCMake_SOURCE_DIR}/validate_schema.py") - endif() - - execute_process( - COMMAND "${Python_EXECUTABLE}" "${CMakePresets_VALIDATE_SCRIPT_PATH}" "${file}" - RESULT_VARIABLE _result - ERROR_VARIABLE _error - ) - if(NOT _result STREQUAL expected_result) - string(REPLACE "\n" "\n " _error_p "${_error}") - string(APPEND RunCMake_TEST_FAILED "Expected result of validating ${file}: ${expected_result}\nActual result: ${_result}\nError:\n ${_error_p}") - endif() - - set(RunCMake_TEST_FAILED "${RunCMake_TEST_FAILED}" PARENT_SCOPE) -endfunction() diff --git a/Tests/RunCMake/CMakePresets/validate_schema.py b/Tests/RunCMake/CMakePresets/validate_schema.py deleted file mode 100644 index 2409095f84..0000000000 --- a/Tests/RunCMake/CMakePresets/validate_schema.py +++ /dev/null @@ -1,20 +0,0 @@ -import json -import jsonschema -import os.path -import sys - - -with open(sys.argv[1], "r", encoding="utf-8-sig") as f: - contents = json.load(f) - -schema_file = os.path.join( - os.path.dirname(__file__), - "..", "..", "..", "Help", "manual", "presets", "schema.json") -with open(schema_file, "r", encoding="utf-8") as f: - schema = json.load(f) - -try: - jsonschema.validate(contents, schema) -except (jsonschema.ValidationError, jsonschema.SchemaError) as e: - sys.stderr.write(e.message) - sys.exit(1) diff --git a/Tests/RunCMake/CMakePresetsBuild/check.cmake b/Tests/RunCMake/CMakePresetsBuild/check.cmake index e79c4f12a8..88fe12247a 100644 --- a/Tests/RunCMake/CMakePresetsBuild/check.cmake +++ b/Tests/RunCMake/CMakePresetsBuild/check.cmake @@ -1,3 +1 @@ -set(CMakePresets_VALIDATE_SCRIPT_PATH "${RunCMake_SOURCE_DIR}/../CMakePresets/validate_schema.py") -include("${RunCMake_SOURCE_DIR}/../CMakePresets/validate_schema.cmake") include("${RunCMake_SOURCE_DIR}/../CMakePresets/check.cmake") diff --git a/Tests/RunCMake/CMakePresetsPackage/check.cmake b/Tests/RunCMake/CMakePresetsPackage/check.cmake index e79c4f12a8..88fe12247a 100644 --- a/Tests/RunCMake/CMakePresetsPackage/check.cmake +++ b/Tests/RunCMake/CMakePresetsPackage/check.cmake @@ -1,3 +1 @@ -set(CMakePresets_VALIDATE_SCRIPT_PATH "${RunCMake_SOURCE_DIR}/../CMakePresets/validate_schema.py") -include("${RunCMake_SOURCE_DIR}/../CMakePresets/validate_schema.cmake") include("${RunCMake_SOURCE_DIR}/../CMakePresets/check.cmake") diff --git a/Tests/RunCMake/CMakePresetsTest/check.cmake b/Tests/RunCMake/CMakePresetsTest/check.cmake index e79c4f12a8..88fe12247a 100644 --- a/Tests/RunCMake/CMakePresetsTest/check.cmake +++ b/Tests/RunCMake/CMakePresetsTest/check.cmake @@ -1,3 +1 @@ -set(CMakePresets_VALIDATE_SCRIPT_PATH "${RunCMake_SOURCE_DIR}/../CMakePresets/validate_schema.py") -include("${RunCMake_SOURCE_DIR}/../CMakePresets/validate_schema.cmake") include("${RunCMake_SOURCE_DIR}/../CMakePresets/check.cmake") diff --git a/Tests/RunCMake/CMakePresetsWorkflow/check.cmake b/Tests/RunCMake/CMakePresetsWorkflow/check.cmake index e79c4f12a8..88fe12247a 100644 --- a/Tests/RunCMake/CMakePresetsWorkflow/check.cmake +++ b/Tests/RunCMake/CMakePresetsWorkflow/check.cmake @@ -1,3 +1 @@ -set(CMakePresets_VALIDATE_SCRIPT_PATH "${RunCMake_SOURCE_DIR}/../CMakePresets/validate_schema.py") -include("${RunCMake_SOURCE_DIR}/../CMakePresets/validate_schema.cmake") include("${RunCMake_SOURCE_DIR}/../CMakePresets/check.cmake") diff --git a/Tests/RunCMake/CTestCommandLine/RunCMakeTest.cmake b/Tests/RunCMake/CTestCommandLine/RunCMakeTest.cmake index 829cdd864b..ed407b85f6 100644 --- a/Tests/RunCMake/CTestCommandLine/RunCMakeTest.cmake +++ b/Tests/RunCMake/CTestCommandLine/RunCMakeTest.cmake @@ -512,18 +512,9 @@ function(show_only_json_check_python v) file(WRITE "${json_file}" "${actual_stdout}") set(actual_stdout "" PARENT_SCOPE) - if(CMake_TEST_JSON_SCHEMA) - execute_process( - COMMAND ${Python_EXECUTABLE} "${RunCMake_SOURCE_DIR}/show-only_json_validate_schema.py" "${json_file}" - RESULT_VARIABLE result - OUTPUT_VARIABLE output - ERROR_VARIABLE output - ) - if(NOT result STREQUAL 0) - string(REPLACE "\n" "\n " output "${output}") - string(APPEND RunCMake_TEST_FAILED "Failed to validate version ${v} JSON schema for file: ${file}\nOutput:\n${output}\n") - endif() - endif() + include("${RunCMake_SOURCE_DIR}/../validate_json_schema.cmake") + set(schema_file "${RunCMake_SOURCE_DIR}/../../../Help/manual/ctest/show-only-schema.json") + validate_json_schema("${schema_file}" "${json_file}") execute_process( COMMAND ${Python_EXECUTABLE} "${RunCMake_SOURCE_DIR}/show-only_json-v${v}_check.py" "${json_file}" diff --git a/Tests/RunCMake/CTestCommandLine/show-only_json_validate_schema.py b/Tests/RunCMake/CTestCommandLine/show-only_json_validate_schema.py deleted file mode 100644 index e0a8347273..0000000000 --- a/Tests/RunCMake/CTestCommandLine/show-only_json_validate_schema.py +++ /dev/null @@ -1,16 +0,0 @@ -import json -import jsonschema -import os.path -import sys - - -with open(sys.argv[1], "r", encoding="utf-8-sig") as f: - contents = json.load(f) - -schema_file = os.path.join( - os.path.dirname(__file__), - "..", "..", "..", "Help", "manual", "ctest", "show-only-schema.json") -with open(schema_file, "r", encoding="utf-8") as f: - schema = json.load(f) - -jsonschema.validate(contents, schema) diff --git a/Tests/RunCMake/CommandLine/RunCMakeTest.cmake b/Tests/RunCMake/CommandLine/RunCMakeTest.cmake index 2c587d4f8d..9dd39dce72 100644 --- a/Tests/RunCMake/CommandLine/RunCMakeTest.cmake +++ b/Tests/RunCMake/CommandLine/RunCMakeTest.cmake @@ -14,16 +14,10 @@ function(version_json_check_python v is_json_ready) set(actual_stdout "" PARENT_SCOPE) endif() - execute_process( - COMMAND ${Python_EXECUTABLE} "${RunCMake_SOURCE_DIR}/version_json_validate_schema.py" "${json_file}" - RESULT_VARIABLE result - OUTPUT_VARIABLE output - ERROR_VARIABLE output - ) - if(NOT result STREQUAL 0) - string(REPLACE "\n" "\n " output "${output}") - string(APPEND RunCMake_TEST_FAILED "Failed to validate version ${v} JSON schema for file: ${json_file}\nOutput:\n${output}\n") - endif() + include("${RunCMake_SOURCE_DIR}/../validate_json_schema.cmake") + set(schema_file "${RunCMake_SOURCE_DIR}/../../../Help/manual/cmake/version-schema.json") + validate_json_schema("${schema_file}" "${json_file}") + return(PROPAGATE RunCMake_TEST_FAILED) endfunction() diff --git a/Tests/RunCMake/CommandLine/version_json_validate_schema.py b/Tests/RunCMake/CommandLine/version_json_validate_schema.py deleted file mode 100644 index 53c4bf9c5b..0000000000 --- a/Tests/RunCMake/CommandLine/version_json_validate_schema.py +++ /dev/null @@ -1,16 +0,0 @@ -import json -import jsonschema -import os.path -import sys - - -with open(sys.argv[1], "r", encoding="utf-8-sig") as f: - contents = json.load(f) - -schema_file = os.path.join( - os.path.dirname(__file__), - "..", "..", "..", "Help", "manual", "cmake", "version-schema.json") -with open(schema_file, "r", encoding="utf-8") as f: - schema = json.load(f) - -jsonschema.validate(contents, schema) diff --git a/Tests/RunCMake/FileAPI/RunCMakeTest.cmake b/Tests/RunCMake/FileAPI/RunCMakeTest.cmake index eda669c90c..e9fbf25746 100644 --- a/Tests/RunCMake/FileAPI/RunCMakeTest.cmake +++ b/Tests/RunCMake/FileAPI/RunCMakeTest.cmake @@ -2,31 +2,7 @@ include(RunCMake) cmake_policy(SET CMP0140 NEW) -# Arguments after the first are the files to validate against the schema -function(validate_fileapi_schema schema) - if(NOT ARGN) - # No files to validate against the schema - return() - endif() - list(JOIN ARGN "\n" file_list) - set(file_list_file ${RunCMake_TEST_BINARY_DIR}/check_file_list.txt) - file(WRITE "${file_list_file}" "${file_list}") - execute_process( - COMMAND ${Python_EXECUTABLE} - "${RunCMake_SOURCE_DIR}/fileapi_validate_schema.py" - "${file_list_file}" - "${schema}" - RESULT_VARIABLE result - OUTPUT_VARIABLE output - ERROR_VARIABLE output - ) - if(NOT result STREQUAL 0) - string(REPLACE "\n" "\n " output "${output}") - string(APPEND RunCMake_TEST_FAILED - "Failed to validate files against JSON schema: ${schema}\nOutput:\n${output}\n") - endif() - return(PROPAGATE RunCMake_TEST_FAILED) -endfunction() +include("${RunCMake_SOURCE_DIR}/../validate_json_schema.cmake") # Function called in *-check.cmake scripts to check api files. function(check_api expect) @@ -73,9 +49,13 @@ in directory: endif() endforeach() foreach(schema_type IN LISTS schema_types) - validate_fileapi_schema( - ${schema_dir}/schema_${schema_type}.json - ${schema_type_${schema_type}} + if("${schema_type_${schema_type}}" STREQUAL "") + # No files to validate against the schema + continue() + endif() + validate_json_schema( + "${schema_dir}/schema_${schema_type}.json" + "${schema_type_${schema_type}}" ) endforeach() endif() @@ -95,9 +75,9 @@ function(check_stateful_queries) REPLACE "^(.+)$" "${prefix}-\\1/query.json" OUTPUT_VARIABLE query_json_files ) - validate_fileapi_schema( - ${schema_dir}/schema_stateful_query.json - ${query_json_files} + validate_json_schema( + "${schema_dir}/schema_stateful_query.json" + "${query_json_files}" ) return(PROPAGATE RunCMake_TEST_FAILED) endfunction() diff --git a/Tests/RunCMake/FileAPI/fileapi_validate_schema.py b/Tests/RunCMake/FileAPI/fileapi_validate_schema.py deleted file mode 100644 index 8156a46c67..0000000000 --- a/Tests/RunCMake/FileAPI/fileapi_validate_schema.py +++ /dev/null @@ -1,23 +0,0 @@ -import json -import jsonschema -import sys - - -# First argument is a file containing the list of files to check -with open(sys.argv[1], "r", encoding="utf-8") as file_list: - files_to_check = [line.strip() for line in file_list if line.strip()] - -# Second argument is the schema file -with open(sys.argv[2], "r", encoding="utf-8-sig") as f: - schema = json.load(f) - -# Check each file against the schema -for file_path in files_to_check: - try: - with open(file_path, "r", encoding="utf-8-sig") as f: - contents = json.load(f) - # The following raises an exception if validation fails - jsonschema.validate(contents, schema) - except Exception as e: - print(f"Failed to validate file {file_path}: {e}") - raise diff --git a/Tests/RunCMake/Instrumentation/check-query-dir.cmake b/Tests/RunCMake/Instrumentation/check-query-dir.cmake index b3204791c3..38bbfbbaec 100644 --- a/Tests/RunCMake/Instrumentation/check-query-dir.cmake +++ b/Tests/RunCMake/Instrumentation/check-query-dir.cmake @@ -1,13 +1,14 @@ include(${CMAKE_CURRENT_LIST_DIR}/verify-snippet.cmake) include(${CMAKE_CURRENT_LIST_DIR}/json.cmake) -include(${CMAKE_CURRENT_LIST_DIR}/validate_schema.cmake) +include(${CMAKE_CURRENT_LIST_DIR}/../validate_json_schema.cmake) + +set(schema_file "${CMAKE_CURRENT_LIST_DIR}/../../../Help/manual/instrumentation/query-v1-schema.json") file(GLOB_RECURSE queries LIST_DIRECTORIES false ${v1}/query/*) foreach(query ${queries}) - validate_schema( - "${query}" - "${CMAKE_CURRENT_LIST_DIR}/../../../Help/manual/instrumentation/query-v1-schema.json" - "${schema_validate_result}" + validate_json_schema( + "${schema_file}" "${query}" + EXPECTED_RESULT "${schema_validate_result}" ) if (RunCMake_TEST_FAILED) add_error("${RunCMake_TEST_FAILED}") diff --git a/Tests/RunCMake/Instrumentation/hook.cmake b/Tests/RunCMake/Instrumentation/hook.cmake index c456f2099e..89f2bbbe78 100644 --- a/Tests/RunCMake/Instrumentation/hook.cmake +++ b/Tests/RunCMake/Instrumentation/hook.cmake @@ -1,7 +1,7 @@ cmake_minimum_required(VERSION 3.30) include(${CMAKE_CURRENT_LIST_DIR}/json.cmake) -include(${CMAKE_CURRENT_LIST_DIR}/validate_schema.cmake) +include(${CMAKE_CURRENT_LIST_DIR}/../validate_json_schema.cmake) include(${CMAKE_CURRENT_LIST_DIR}/verify-snippet.cmake) include(${CMAKE_CURRENT_LIST_DIR}/verify-trace.cmake) @@ -53,12 +53,8 @@ function(add_error error) return(PROPAGATE ERROR_MESSAGE) endfunction() -validate_schema( - "${index}" - "${CMAKE_CURRENT_LIST_DIR}/../../../Help/manual/instrumentation/index-v1-schema.json" - # We expect to always generate valid index files. - 0 -) +set(index_schema "${CMAKE_CURRENT_LIST_DIR}/../../../Help/manual/instrumentation/index-v1-schema.json") +validate_json_schema("${index_schema}" "${index}") if (RunCMake_TEST_FAILED) add_error("${RunCMake_TEST_FAILED}") unset(RunCMake_TEST_FAILED) diff --git a/Tests/RunCMake/Instrumentation/validate_schema.cmake b/Tests/RunCMake/Instrumentation/validate_schema.cmake deleted file mode 100644 index 6fc49b7462..0000000000 --- a/Tests/RunCMake/Instrumentation/validate_schema.cmake +++ /dev/null @@ -1,15 +0,0 @@ -function(validate_schema json_file schema_file expected_result) - if (Python_EXECUTABLE AND CMake_TEST_JSON_SCHEMA) - execute_process( - COMMAND ${Python_EXECUTABLE} "${CMAKE_CURRENT_LIST_DIR}/validate_schema.py" "${json_file}" "${schema_file}" - RESULT_VARIABLE result - OUTPUT_VARIABLE output - ERROR_VARIABLE output - ) - if(NOT result MATCHES ${expected_result}) - string(REPLACE "\n" "\n " output "${output}") - string(APPEND RunCMake_TEST_FAILED "Failed to validate version JSON schema for file: ${json_file}\nOutput:\n${output}\nResult: ${result}\nExpected: ${expected_result}") - endif() - return(PROPAGATE RunCMake_TEST_FAILED) - endif() -endfunction() diff --git a/Tests/RunCMake/Instrumentation/validate_schema.py b/Tests/RunCMake/Instrumentation/validate_schema.py deleted file mode 100644 index ffcb2a5d73..0000000000 --- a/Tests/RunCMake/Instrumentation/validate_schema.py +++ /dev/null @@ -1,15 +0,0 @@ -import json -import jsonschema -import sys - -with open(sys.argv[1], "r", encoding="utf-8-sig") as f: - contents = json.load(f) - -with open(sys.argv[2], "r", encoding="utf-8") as f: - schema = json.load(f) - -try: - jsonschema.validate(contents, schema) -except jsonschema.ValidationError as e: - print(e) - sys.exit(1) diff --git a/Tests/RunCMake/Instrumentation/verify-snippet.cmake b/Tests/RunCMake/Instrumentation/verify-snippet.cmake index 839fda1588..fe89acb3a4 100644 --- a/Tests/RunCMake/Instrumentation/verify-snippet.cmake +++ b/Tests/RunCMake/Instrumentation/verify-snippet.cmake @@ -2,7 +2,7 @@ include_guard() include(${CMAKE_CURRENT_LIST_DIR}/json.cmake) -include(${CMAKE_CURRENT_LIST_DIR}/validate_schema.cmake) +include(${CMAKE_CURRENT_LIST_DIR}/../validate_json_schema.cmake) function(snippet_has_fields snippet contents) get_filename_component(filename "${snippet}" NAME) @@ -111,12 +111,8 @@ function(verify_snippet_file snippet contents) json_error("${snippet}" "Role \"${role}\" doesn't match snippet filename") endif() - validate_schema( - "${snippet}" - "${CMAKE_CURRENT_LIST_DIR}/../../../Help/manual/instrumentation/snippet-v1-schema.json" - # We expect to always generate valid snippet files. - 0 - ) + set(snippet_schema "${CMAKE_CURRENT_LIST_DIR}/../../../Help/manual/instrumentation/snippet-v1-schema.json") + validate_json_schema("${snippet_schema}" "${snippet}") if (RunCMake_TEST_FAILED) add_error("${RunCMake_TEST_FAILED}") endif() diff --git a/Tests/RunCMake/validate_json_schema.cmake b/Tests/RunCMake/validate_json_schema.cmake new file mode 100644 index 0000000000..6c3a393d37 --- /dev/null +++ b/Tests/RunCMake/validate_json_schema.cmake @@ -0,0 +1,35 @@ +cmake_policy(SET CMP0140 NEW) + +function(validate_json_schema schema_file input_files) + if (NOT(Python_EXECUTABLE AND CMake_TEST_JSON_SCHEMA)) + return() + endif() + + cmake_parse_arguments(ARG_VS "" "EXPECTED_RESULT" "" ${ARGN}) + + if(NOT ARG_VS_EXPECTED_RESULT) + set(ARG_VS_EXPECTED_RESULT 0) + endif() + + set(_validate_py "${CMAKE_CURRENT_FUNCTION_LIST_DIR}/validate_json_schema.py") + cmake_path(SET _schema NORMALIZE "${schema_file}") + set(_inputs) + foreach(_input IN LISTS input_files) + cmake_path(SET _input NORMALIZE "${_input}") + list(APPEND _inputs "${_input}") + endforeach() + + execute_process( + COMMAND + "${Python_EXECUTABLE}" "${_validate_py}" "${_schema}" + "--input-files" ${_inputs} + # Include "--verbose" here for local debugging as needed. + RESULT_VARIABLE result + ERROR_VARIABLE error + ) + if(NOT result MATCHES "${ARG_VS_EXPECTED_RESULT}") + string(REPLACE "\n" "\n " error "${error}") + string(APPEND RunCMake_TEST_FAILED "Failed to validate version JSON schema for file: ${json_file}\nOutput:\n${error}\nResult: ${result}\nExpected: ${ARG_VS_EXPECTED_RESULT}") + endif() + return(PROPAGATE RunCMake_TEST_FAILED) +endfunction() diff --git a/Tests/RunCMake/validate_json_schema.py b/Tests/RunCMake/validate_json_schema.py new file mode 100644 index 0000000000..7cbad6503b --- /dev/null +++ b/Tests/RunCMake/validate_json_schema.py @@ -0,0 +1,54 @@ +import argparse +import json +import pathlib +import sys + +import jsonschema + + +def main(argv=None) -> int: + parser = argparse.ArgumentParser(description="Validate CMake JSON schemas") + parser.add_argument( + "schema", + type=pathlib.Path, + help="the path to the schema file", + ) + parser.add_argument( + "--input-files", + nargs="+", + type=pathlib.Path, + help="the path to an input file to validate", + ) + parser.add_argument( + "-v", + "--verbose", + action="store_true", + help="enable verbose output", + ) + args = parser.parse_args(argv) + + with open(args.schema, "r", encoding="utf-8") as f: + schema = json.load(f) + + for file in args.input_files: + try: + with open(file, "r", encoding="utf-8-sig") as f: + contents = json.load(f) + jsonschema.validate(contents, schema) + except jsonschema.ValidationError as e: + message = str(e) if args.verbose else str(e.message) + print(f"Failed to validate file {file}: {message}", file=sys.stderr) + return 1 + except jsonschema.SchemaError as e: + message = str(e) if args.verbose else str(e.message) + print(f"Failed to validate schema: {message}", file=sys.stderr) + return 2 + except Exception as e: + print(f"Unknown exception: {e}", file=sys.stderr) + return 3 + + return 0 + + +if __name__ == "__main__": + sys.exit(main(sys.argv[1:]))