diff --git a/.github/workflows/verify-data.yml b/.github/workflows/verify-data.yml index 6354ba0..fe98163 100644 --- a/.github/workflows/verify-data.yml +++ b/.github/workflows/verify-data.yml @@ -21,18 +21,31 @@ jobs: yamllint_strict: false yamllint_comment: false - - name: "Set up Python" - uses: actions/setup-python@v5 - with: - python-version: "3.x" - - name: "Install dependencies" + run: sudo apt-get update && sudo apt-get install -y g++-14 libyaml-cpp-dev nlohmann-json3-dev + + - name: "Fetch json-schema-validator" + run: | + rm -rf json-schema-validator + git clone --depth 1 https://github.com/pboettch/json-schema-validator.git json-schema-validator + + - name: "Build YAML validator" run: | - python3 -m pip install --upgrade pip - python3 -m pip install PyYAML jsonschema + g++-14 -std=c++23 -Wall -Wextra \ + $(pkg-config --cflags yaml-cpp) \ + $(pkg-config --cflags nlohmann_json) \ + -Ijson-schema-validator/src \ + -o validate_yaml_file \ + validate_yaml_file.cpp \ + json-schema-validator/src/json-uri.cpp \ + json-schema-validator/src/json-validator.cpp \ + json-schema-validator/src/json-schema-draft7.json.cpp \ + json-schema-validator/src/json-patch.cpp \ + $(pkg-config --libs yaml-cpp) - - name: "Verify features" + - name: "Validate feature files" run: | for file in features_c*.yaml; do - python3 verify_features.py "$file" + echo "Verifying: $file" + ./validate_yaml_file "$file" done diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..4258f92 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +validate_yaml_file diff --git a/validate_yaml_file.cpp b/validate_yaml_file.cpp new file mode 100644 index 0000000..b0d78be --- /dev/null +++ b/validate_yaml_file.cpp @@ -0,0 +1,81 @@ +// Copyright (c) Cem Dervis +// SPDX-License-Identifier: CC0-1.0 +// This file is part of https://cppstat.dev. + +#include +#include +#include +#include + +using json = nlohmann::json; + +json yaml_to_json(const YAML::Node& node) { + if (node.IsNull()) { + return nullptr; + } + else if (node.IsScalar()) { + try { + return node.as(); + } catch (...) { + } + + try { + return node.as(); + } catch (...) { + } + + try { + return node.as(); + } catch (...) { + } + + return node.as(); + } + else if (node.IsSequence()) { + auto arr = json::array(); + + for (const auto& item : node) { + arr.push_back(yaml_to_json(item)); + } + + return arr; + } + else if (node.IsMap()) { + auto obj = json::object(); + + for (const auto& kv : node) { + obj[kv.first.as()] = yaml_to_json(kv.second); + } + + return obj; + } + + return nullptr; +} + +int main(int argc, char* argv[]) { + if (argc < 2) { + std::println(stderr, "Usage: {} ", argv[0]); + return EXIT_FAILURE; + } + + try { + auto schema_yaml = YAML::LoadFile("features.schema.yaml"); + auto schema = yaml_to_json(schema_yaml); + + auto data_yaml = YAML::LoadFile(argv[1]); + auto data = yaml_to_json(data_yaml); + + auto val = nlohmann::json_schema::json_validator(); + val.set_root_schema(schema); + val.validate(data); + + std::println("Verification successful: {}", argv[1]); + + return EXIT_SUCCESS; + } catch (const std::exception& e) { + std::println(stderr, "Verification failed: {}", argv[1]); + std::println(stderr, "Error: {}", e.what()); + return EXIT_FAILURE; + } +} diff --git a/verify_features.py b/verify_features.py deleted file mode 100644 index c58825f..0000000 --- a/verify_features.py +++ /dev/null @@ -1,35 +0,0 @@ -import yaml -import jsonschema -import sys - -def validate_yaml(schema_file, data_file): - try: - with open(schema_file, 'r') as f: - schema = yaml.safe_load(f) - - with open(data_file, 'r') as f: - data = yaml.safe_load(f) - - jsonschema.validate(instance=data, schema=schema) - print(f"Verification successful: {data_file}") - return True - except jsonschema.exceptions.ValidationError as e: - print(f"Verification failed: {data_file}") - print(f"Error: {e.message}") - print(f"Path: {' -> '.join(map(str, e.path))}") - return False - except Exception as e: - print(f"An error occurred: {e}") - return False - -if __name__ == "__main__": - schema_path = "features.schema.yaml" - - if len(sys.argv) < 2: - print("Usage: python3 verify_features.py ") - sys.exit(1) - - data_path = sys.argv[1] - success = validate_yaml(schema_path, data_path) - if not success: - sys.exit(1)