From 379cf8c2b4ad49fe3a21e926ffdf543b9e9da8df Mon Sep 17 00:00:00 2001 From: Thomas Vincent Date: Fri, 10 Dec 2021 10:35:53 -0500 Subject: [PATCH] WIP remove export isntall and move to FetchContent --- CMakeLists.txt | 94 +++++++++-------------------------- README.md | 105 ++++++++++++++++++---------------------- example/CMakeLists.txt | 12 +++++ example/README.md | 0 example/stand-alone.cpp | 54 +++++++++++++++++++++ 5 files changed, 135 insertions(+), 130 deletions(-) create mode 100644 example/CMakeLists.txt create mode 100644 example/README.md create mode 100644 example/stand-alone.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 46e8e3f..c01ec49 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,33 +1,22 @@ -cmake_minimum_required(VERSION 3.2) +cmake_minimum_required(VERSION 3.16) -# disable tests and examples if project is not super project -set(JSON_VALIDATOR_IS_TOP_LEVEL OFF) -if(CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_SOURCE_DIR) - # I am top-level project. - set(JSON_VALIDATOR_IS_TOP_LEVEL ON) -endif() - -option(JSON_VALIDATOR_BUILD_TESTS "Build tests" ${JSON_VALIDATOR_IS_TOP_LEVEL}) -option(JSON_VALIDATOR_BUILD_EXAMPLES "Build examples" ${JSON_VALIDATOR_IS_TOP_LEVEL}) -option(JSON_VALIDATOR_INSTALL "Install CMake targets during install step." ${JSON_VALIDATOR_IS_TOP_LEVEL}) -option(JSON_VALIDATOR_HUNTER "Enable Hunter package manager support" OFF) - -if(JSON_VALIDATOR_HUNTER) - include("cmake/HunterGate.cmake") - HunterGate( - URL "https://github.com/cpp-pm/hunter/archive/v0.23.262.tar.gz" - SHA1 "eb51e633e08cdbe2153caf255e9c23968fecb29d" - ) -endif() +option(JSON_VALIDATOR_BUILD_TESTS "Build tests" ON) +option(JSON_VALIDATOR_BUILD_EXAMPLES "Build examples" ON) # the project project(nlohmann_json_schema_validator LANGUAGES CXX) -set(PROJECT_VERSION 2.1.1) +set(PROJECT_VERSION 2.1.2) +include(FetchContent) -if(JSON_VALIDATOR_HUNTER) - hunter_add_package(nlohmann_json) +# find nlohmann_json if not found simply fetch it +find_package(nlohmann_json QUIET) +if(NOT nlohmann_json_FOUND) + FetchContent_Declare(json + GIT_REPOSITORY https://github.com/ArthurSonzogni/nlohmann_json_cmake_fetchcontent + GIT_TAG v3.10.4) + FetchContent_MakeAvailable(json) endif() # the library @@ -52,10 +41,6 @@ set_target_properties(nlohmann_json_schema_validator VERSION ${PROJECT_VERSION} SOVERSION 1) -if(NOT TARGET nlohmann_json::nlohmann_json) - find_package(nlohmann_json REQUIRED) -endif() - target_link_libraries( nlohmann_json_schema_validator PUBLIC nlohmann_json::nlohmann_json) @@ -99,6 +84,9 @@ if (JSON_VALIDATOR_BUILD_EXAMPLES) add_executable(format-json-schema app/format.cpp) target_link_libraries(format-json-schema nlohmann_json_schema_validator) + + install(TARGETS json-schema-validate readme-json-schema format-json-schema + DESTINATION bin) endif() if (JSON_VALIDATOR_BUILD_TESTS) @@ -107,50 +95,14 @@ if (JSON_VALIDATOR_BUILD_TESTS) add_subdirectory(test) endif() -if(JSON_VALIDATOR_INSTALL) - install(TARGETS nlohmann_json_schema_validator - EXPORT ${PROJECT_NAME}Targets - LIBRARY DESTINATION lib - ARCHIVE DESTINATION lib - RUNTIME DESTINATION bin) +# installation +install(TARGETS nlohmann_json_schema_validator + EXPORT ${PROJECT_NAME}Targets + LIBRARY DESTINATION lib + ARCHIVE DESTINATION lib + RUNTIME DESTINATION bin) - install(FILES src/nlohmann/json-schema.hpp - DESTINATION include/nlohmann) +install(FILES src/nlohmann/json-schema.hpp + DESTINATION include/nlohmann) - if (JSON_VALIDATOR_BUILD_EXAMPLES) - install(TARGETS json-schema-validate readme-json-schema format-json-schema - DESTINATION bin) - endif() - # Set Up the Project Targets and Config Files for CMake - - # Set the install path to the cmake config files (Relative, so install works correctly under Hunter as well) - set(INSTALL_CMAKE_DIR "lib/cmake/${PROJECT_NAME}") - set(INSTALL_CMAKEDIR_ROOT share/cmake) - - # Install Targets - install(EXPORT ${PROJECT_NAME}Targets - FILE ${PROJECT_NAME}Targets.cmake - DESTINATION "${INSTALL_CMAKE_DIR}") - - include(CMakePackageConfigHelpers) - write_basic_package_version_file( - ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake - VERSION ${PROJECT_VERSION} - COMPATIBILITY SameMajorVersion - ) - - configure_package_config_file( - ${PROJECT_SOURCE_DIR}/${PROJECT_NAME}Config.cmake.in - ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake - INSTALL_DESTINATION ${INSTALL_CMAKEDIR_ROOT}/${PROJECT_NAME} - ) - - install( - FILES - ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake - ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake - DESTINATION - ${INSTALL_CMAKE_DIR} - ) -endif() diff --git a/README.md b/README.md index c7e69c1..14328f0 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ # JSON schema validator for JSON for Modern C++ -# What is it? +## What is it? This is a C++ library for validating JSON documents based on a [JSON Schema](http://json-schema.org/) which itself should validate with @@ -19,7 +19,7 @@ library, hence the name. External documentation is missing as well. However the API of the validator is rather simple. -# New in version 2 +## New in version 2 Although significant changes have been done for the 2nd version (a complete rewrite) the API is compatible with the 1.0.0 release. Except for @@ -34,7 +34,7 @@ is parsed into compiled C++ objects which are then used during validation. There still optimizations to be done, but validation speed has improved by factor 100 or more. -# Design goals +## Design goals The main goal of this validator is to produce *human-comprehensible* error messages if a JSON-document/instance does not comply to its schema. @@ -49,7 +49,7 @@ a validation error occurs and decide what to do (throwing, counting, collecting) Another goal was to use Niels Lohmann's JSON-library. This is why the validator lives in his namespace. -# Thread-safety +## Thread-safety Instance validation is thread-safe and the same validator-object can be used by different threads: @@ -64,13 +64,37 @@ being called: Validator-object creation however is not thread-safe. A validator has to be created in one (main?) thread once. -# Weaknesses +## Weaknesses Numerical validation uses nlohmann-json's integer, unsigned and floating point types, depending on if the schema type is "integer" or "number". Bignum (i.e. arbitrary precision and range) is not supported at this time. -# Building +## Usage + +To use this project in you own cmake project include it with : + +``` +cmake_minimum_required(VERSION 3.16) +include(FetchContent) + +... + +FetchContent_Declare(json_schema_validator +GIT_REPOSITORY https://github.com/pboettch/json-schema-validator.git +GIT_TAG v2.1.2) +FetchContent_MakeAvailable(json_schema_validator) +``` + +Then later on add a link libraries to your own targets like: + +``` +target_link_libraries(my-target PUBLIC nlohmann_json_schema_validator) +``` + +That's it. + +## Building This library is based on Niels Lohmann's JSON-library and thus has a build-dependency to it. @@ -80,22 +104,28 @@ is required. Various methods using CMake can be used to build this project. -## Build out-of-source +### Build out-of-source Do not run cmake inside the source-dir. Rather create a dedicated build-dir: ```Bash git clone https://github.com/pboettch/json-schema-validator.git cd json-schema-validator -mkdir build +# configure +cmake -B build . + +# build +cmake --build build . + +# install if needed +cmake --build build --target install . + +# run unit, non-regression and test-suite tests cd build -cmake [..] -make -make install # if needed -ctest # run unit, non-regression and test-suite tests +ctest ``` -## Building as shared library +### Building as shared library By default a static library is built. Shared libraries can be generated by using the `BUILD_SHARED_LIBS`-cmake variable: @@ -105,53 +135,10 @@ In your initial call to cmake simply add: cmake [..] -DBUILD_SHARED_LIBS=ON [..] ``` -## nlohmann-json integration +### Note about nlohmann-json integration -As nlohmann-json is a dependency, this library tries find it. - -The cmake-configuration first checks if nlohmann-json is available as a cmake-target. This may be the case, because it is used as a submodule in a super-project which already provides and uses nlohmann-json. -Otherwise, it calls `find_package` for nlohmann-json and requires nlohmann-json to be installed on the system. - -### Building with Hunter package manager - -To enable access to nlohmann json library, Hunter can be used. Just run with `JSON_VALIDATOR_HUNTER=ON` option. No further dependencies needed - -```bash -cmake [..] -DJSON_VALIDATOR_HUNTER=ON [..] -``` - -### Building as a CMake-subdirectory from within another project - -Adding this library as a subdirectory to a parent project is one way of -building it. - -If the parent project already used `find_package()` to find the CMake-package of nlohmann_json or includes it as a submodule likewise. - -### Building directly, finding a CMake-package. (short) - -When nlohmann-json has been installed, it provides files which allows -CMake's `find_package()` to be used. - -This library is using this mechanism if `nlohmann_json::nlohmann_json`-target -does not exist. - -### Install - -Since version 2.1.0 this library can be installed and CMake-package-files will be -created accordingly. If the installation of nlohmann-json and this library -is done into default unix-system-paths CMake will be able to find this -library by simply doing: - -```CMake -find_package(nlohmann_json_schema_validator REQUIRED) -``` - -and - -```CMake -target_link_libraries( [..] nlohmann_json_schema_validator) -``` -to build and link. +As `nlohmann-json` is a dependency, this library tries find it using `find_package`, if it's not found proper version of +`nlohmann-json` will be fetch using cmake `FetchContent`. ## Code diff --git a/example/CMakeLists.txt b/example/CMakeLists.txt new file mode 100644 index 0000000..0aa0af6 --- /dev/null +++ b/example/CMakeLists.txt @@ -0,0 +1,12 @@ +cmake_minimum_required(VERSION 3.16) +include(FetchContent) + +project(stand-alone VERSION 1.0.0 LANGUAGES CXX) + +FetchContent_Declare(json_schema_validator +GIT_REPOSITORY https://github.com/pboettch/json-schema-validator.git +GIT_TAG v2.1.0) +FetchContent_MakeAvailable(json_schema_validator) + +add_executable(stand-alone stand-alone.cpp) +target_link_libraries(stand-alone nlohmann_json_schema_validator) \ No newline at end of file diff --git a/example/README.md b/example/README.md new file mode 100644 index 0000000..e69de29 diff --git a/example/stand-alone.cpp b/example/stand-alone.cpp new file mode 100644 index 0000000..40e6445 --- /dev/null +++ b/example/stand-alone.cpp @@ -0,0 +1,54 @@ +#include + +#include + +using nlohmann::json; +using nlohmann::json_schema::json_validator; + +// The schema is defined based upon a string literal +static json uri_schema = R"( +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "properties": { + "myUri": { + "type":"string", + "format": "uri" + } + } +})"_json; + +// The people are defined with brace initialization +static json good_uri = {{"myUri", "http://hostname.com/"}}; +static json bad_uri = {{"myUri", "http:/hostname.com/"}}; + +static void uri_format_checker(const std::string &format, const std::string &value) +{ + if (format == "uri") { + if (value.find("://") == std::string::npos) + throw std::invalid_argument("URI does not contain :// - invalid"); + } else + throw std::logic_error("Don't know how to validate " + format); +} + +int main() +{ + json_validator validator(nullptr, uri_format_checker); // create validator + + try { + validator.set_root_schema(uri_schema); // insert root-schema + } catch (const std::exception &e) { + std::cerr << "Validation of schema failed, here is why: " << e.what() << "\n"; + return EXIT_FAILURE; + } + + validator.validate(good_uri); + + try { + validator.validate(bad_uri); + } catch (const std::exception &e) { + std::cerr << "Validation expectedly failed, here is why: " << e.what() << "\n"; + } + + return EXIT_SUCCESS; +}