Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/website-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ jobs:
-DBLAZE_OUTPUT:BOOL=OFF
-DBLAZE_LINTER:BOOL=OFF
-DBLAZE_TEST:BOOL=OFF
-DBLAZE_CONFIGURATION:BOOL=OFF
-DBLAZE_TESTS:BOOL=OFF
-DBLAZE_DOCS:BOOL=ON
- run: cmake --build ./build --config Release --target doxygen
1 change: 1 addition & 0 deletions .github/workflows/website-deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ jobs:
-DBLAZE_OUTPUT:BOOL=OFF
-DBLAZE_LINTER:BOOL=OFF
-DBLAZE_TEST:BOOL=OFF
-DBLAZE_CONFIGURATION:BOOL=OFF
-DBLAZE_TESTS:BOOL=OFF
-DBLAZE_DOCS:BOOL=ON
- run: cmake --build ./build --config Release --target doxygen
Expand Down
9 changes: 9 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ option(BLAZE_EVALUATOR "Build the Blaze evaluator library" ON)
option(BLAZE_OUTPUT "Build the Blaze output formats library" ON)
option(BLAZE_LINTER "Build the Blaze linter rule library" ON)
option(BLAZE_TEST "Build the Blaze test runner library" ON)
option(BLAZE_CONFIGURATION "Build the Blaze configuration file library" ON)
option(BLAZE_TESTS "Build the Blaze tests" OFF)
option(BLAZE_BENCHMARK "Build the Blaze benchmarks" OFF)
option(BLAZE_CONTRIB "Build the Blaze contrib programs" OFF)
Expand Down Expand Up @@ -62,6 +63,10 @@ if(BLAZE_TEST)
add_subdirectory(src/test)
endif()

if(BLAZE_CONFIGURATION)
add_subdirectory(src/configuration)
endif()

if(BLAZE_CONTRIB)
add_subdirectory(contrib)
endif()
Expand Down Expand Up @@ -109,6 +114,10 @@ if(BLAZE_TESTS)
add_subdirectory(test/test)
endif()

if(BLAZE_CONFIGURATION)
add_subdirectory(test/configuration)
endif()

if(PROJECT_IS_TOP_LEVEL)
# Otherwise we need the child project to link
# against the sanitizers too.
Expand Down
3 changes: 3 additions & 0 deletions config.cmake.in
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ if(NOT BLAZE_COMPONENTS)
list(APPEND BLAZE_COMPONENTS output)
list(APPEND BLAZE_COMPONENTS linter)
list(APPEND BLAZE_COMPONENTS test)
list(APPEND BLAZE_COMPONENTS configuration)
endif()

include(CMakeFindDependencyMacro)
Expand All @@ -32,6 +33,8 @@ foreach(component ${BLAZE_COMPONENTS})
elseif(component STREQUAL "output")
include("${CMAKE_CURRENT_LIST_DIR}/sourcemeta_blaze_evaluator.cmake")
include("${CMAKE_CURRENT_LIST_DIR}/sourcemeta_blaze_output.cmake")
elseif(component STREQUAL "configuration")
include("${CMAKE_CURRENT_LIST_DIR}/sourcemeta_blaze_configuration.cmake")
else()
message(FATAL_ERROR "Unknown Blaze component: ${component}")
endif()
Expand Down
11 changes: 11 additions & 0 deletions src/configuration/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
sourcemeta_library(NAMESPACE sourcemeta PROJECT blaze NAME configuration
PRIVATE_HEADERS error.h SOURCES parse.cc configuration.cc)

if(BLAZE_INSTALL)
sourcemeta_library_install(NAMESPACE sourcemeta PROJECT blaze NAME configuration)
endif()

target_link_libraries(sourcemeta_blaze_configuration PUBLIC sourcemeta::core::json)
target_link_libraries(sourcemeta_blaze_configuration PUBLIC sourcemeta::core::jsonpointer)
target_link_libraries(sourcemeta_blaze_configuration PRIVATE sourcemeta::core::uri)
target_link_libraries(sourcemeta_blaze_configuration PRIVATE sourcemeta::core::io)
53 changes: 53 additions & 0 deletions src/configuration/configuration.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
#include <sourcemeta/blaze/configuration.h>
#include <sourcemeta/core/io.h>

#include <algorithm> // std::ranges::any_of
#include <cassert> // assert
#include <string> // std::string

namespace sourcemeta::blaze {

auto Configuration::find(const std::filesystem::path &path)
-> std::optional<std::filesystem::path> {
const auto canonical{sourcemeta::core::weakly_canonical(path)};
assert(canonical.is_absolute());
auto current = std::filesystem::is_directory(canonical)
? canonical
: canonical.parent_path();

while (!current.empty()) {
auto candidate = current / "jsonschema.json";
if (std::filesystem::exists(candidate) &&
std::filesystem::is_regular_file(candidate)) {
return candidate;
}

auto parent = current.parent_path();
if (parent == current) {
break;
} else {
current = parent;
}
}

return std::nullopt;
}

auto Configuration::applies_to(const std::filesystem::path &path) const
-> bool {
if (this->extension.empty()) {
return true;
}

const std::string filename{path.filename().string()};
return std::ranges::any_of(this->extension,
[&path, &filename](const auto &suffix) {
if (suffix.empty()) {
return path.extension().empty();
}

return filename.ends_with(suffix);
});
}

} // namespace sourcemeta::blaze
81 changes: 81 additions & 0 deletions src/configuration/include/sourcemeta/blaze/configuration.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
#ifndef SOURCEMETA_BLAZE_CONFIGURATION_H_
#define SOURCEMETA_BLAZE_CONFIGURATION_H_

/// @defgroup configuration Configuration
/// @brief A configuration manifest for JSON Schema projects
///
/// This functionality is included as follows:
///
/// ```cpp
/// #include <sourcemeta/blaze/configuration.h>
/// ```

#ifndef SOURCEMETA_BLAZE_CONFIGURATION_EXPORT
#include <sourcemeta/blaze/configuration_export.h>
#endif

// NOLINTBEGIN(misc-include-cleaner)
#include <sourcemeta/blaze/configuration_error.h>
// NOLINTEND(misc-include-cleaner)

#include <sourcemeta/core/json.h>

#include <filesystem> // std::filesystem
#include <optional> // std::optional
#include <unordered_map> // std::unordered_map
#include <unordered_set> // std::unordered_set

namespace sourcemeta::blaze {

// Exporting symbols that depends on the standard C++ library is considered
// safe.
// https://learn.microsoft.com/en-us/cpp/error-messages/compiler-warnings/compiler-warning-level-2-c4275?view=msvc-170&redirectedfrom=MSDN
#if defined(_MSC_VER)
#pragma warning(disable : 4251 4275)
#endif

/// @ingroup configuration
/// A configuration file format for JSON Schema projects
struct SOURCEMETA_BLAZE_CONFIGURATION_EXPORT Configuration {
std::optional<sourcemeta::core::JSON::String> title;
std::optional<sourcemeta::core::JSON::String> description;
std::optional<sourcemeta::core::JSON::String> email;
std::optional<sourcemeta::core::JSON::String> github;
std::optional<sourcemeta::core::JSON::String> website;
std::filesystem::path absolute_path;
sourcemeta::core::JSON::String base;
std::optional<sourcemeta::core::JSON::String> default_dialect;
std::unordered_set<sourcemeta::core::JSON::String> extension;
std::unordered_map<sourcemeta::core::JSON::String,
sourcemeta::core::JSON::String>
resolve;
sourcemeta::core::JSON extra = sourcemeta::core::JSON::make_object();

/// Check if the given path represents a schema described by this
/// configuration
[[nodiscard]]
auto applies_to(const std::filesystem::path &path) const -> bool;

/// Parse a configuration file from its contents
[[nodiscard]]
static auto from_json(const sourcemeta::core::JSON &value,
const std::filesystem::path &base_path)
-> Configuration;

/// Read and parse a configuration file from disk
[[nodiscard]]
static auto read_json(const std::filesystem::path &path) -> Configuration;

/// A nearest ancestor configuration lookup
[[nodiscard]]
static auto find(const std::filesystem::path &path)
-> std::optional<std::filesystem::path>;
};

#if defined(_MSC_VER)
#pragma warning(default : 4251 4275)
Copy link

@cubic-dev-ai cubic-dev-ai bot Feb 5, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P3: Using #pragma warning(default : ...) resets warnings to the compiler defaults, which may override a user's global build settings (e.g., if they explicitly disabled these warnings). Use #pragma warning(push) and #pragma warning(pop) to restore the previous state safely.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At src/configuration/include/sourcemeta/blaze/configuration.h, line 76:

<comment>Using `#pragma warning(default : ...)` resets warnings to the compiler defaults, which may override a user's global build settings (e.g., if they explicitly disabled these warnings). Use `#pragma warning(push)` and `#pragma warning(pop)` to restore the previous state safely.</comment>

<file context>
@@ -0,0 +1,81 @@
+};
+
+#if defined(_MSC_VER)
+#pragma warning(default : 4251 4275)
+#endif
+
</file context>
Fix with Cubic

#endif

} // namespace sourcemeta::blaze

#endif
57 changes: 57 additions & 0 deletions src/configuration/include/sourcemeta/blaze/configuration_error.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
#ifndef SOURCEMETA_BLAZE_CONFIGURATION_ERROR_H_
#define SOURCEMETA_BLAZE_CONFIGURATION_ERROR_H_

#ifndef SOURCEMETA_BLAZE_CONFIGURATION_EXPORT
#include <sourcemeta/blaze/configuration_export.h>
#endif

#include <sourcemeta/core/jsonpointer.h>

#include <exception> // std::exception
#include <string> // std::string
#include <string_view> // std::string_view
#include <utility> // std::move

namespace sourcemeta::blaze {

// Exporting symbols that depends on the standard C++ library is considered
// safe.
// https://learn.microsoft.com/en-us/cpp/error-messages/compiler-warnings/compiler-warning-level-2-c4275?view=msvc-170&redirectedfrom=MSDN
#if defined(_MSC_VER)
#pragma warning(disable : 4251 4275)
#endif

/// @ingroup configuration
class SOURCEMETA_BLAZE_CONFIGURATION_EXPORT ConfigurationParseError
: public std::exception {
public:
ConfigurationParseError(const char *message,
sourcemeta::core::Pointer location)
: message_{message}, location_{std::move(location)} {}
ConfigurationParseError(std::string message,
sourcemeta::core::Pointer location) = delete;
ConfigurationParseError(std::string &&message,
sourcemeta::core::Pointer location) = delete;
ConfigurationParseError(std::string_view message,
sourcemeta::core::Pointer location) = delete;

[[nodiscard]] auto what() const noexcept -> const char * override {
return this->message_;
}

[[nodiscard]] auto location() const noexcept -> const auto & {
return this->location_;
}

private:
const char *message_;
sourcemeta::core::Pointer location_;
};

#if defined(_MSC_VER)
#pragma warning(default : 4251 4275)
#endif

} // namespace sourcemeta::blaze

#endif
Loading