diff --git a/.github/workflows/website-build.yml b/.github/workflows/website-build.yml index 5f0082f4b..7c8b82417 100644 --- a/.github/workflows/website-build.yml +++ b/.github/workflows/website-build.yml @@ -36,6 +36,5 @@ jobs: -DSOURCEMETA_CORE_HTML:BOOL=OFF -DSOURCEMETA_CORE_EXTENSION_ALTERSCHEMA:BOOL=OFF -DSOURCEMETA_CORE_EXTENSION_EDITORSCHEMA:BOOL=OFF - -DSOURCEMETA_CORE_EXTENSION_BUILD:BOOL=OFF -DSOURCEMETA_CORE_DOCS:BOOL=ON - run: cmake --build ./build --config Release --target doxygen diff --git a/.github/workflows/website-deploy.yml b/.github/workflows/website-deploy.yml index b4eef22c5..136f5ce1b 100644 --- a/.github/workflows/website-deploy.yml +++ b/.github/workflows/website-deploy.yml @@ -46,7 +46,6 @@ jobs: -DSOURCEMETA_CORE_HTML:BOOL=OFF -DSOURCEMETA_CORE_EXTENSION_ALTERSCHEMA:BOOL=OFF -DSOURCEMETA_CORE_EXTENSION_EDITORSCHEMA:BOOL=OFF - -DSOURCEMETA_CORE_EXTENSION_BUILD:BOOL=OFF -DSOURCEMETA_CORE_DOCS:BOOL=ON - run: cmake --build ./build --config Release --target doxygen - name: Setup Pages diff --git a/CMakeLists.txt b/CMakeLists.txt index 4e80b1e8d..bb9d77ad4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -24,7 +24,6 @@ option(SOURCEMETA_CORE_YAML "Build the Sourcemeta Core YAML library" ON) option(SOURCEMETA_CORE_HTML "Build the Sourcemeta Core HTML library" ON) option(SOURCEMETA_CORE_EXTENSION_ALTERSCHEMA "Build the Sourcemeta Core AlterSchema library" ON) option(SOURCEMETA_CORE_EXTENSION_EDITORSCHEMA "Build the Sourcemeta Core EditorSchema library" ON) -option(SOURCEMETA_CORE_EXTENSION_BUILD "Build the Sourcemeta Core Build library" ON) option(SOURCEMETA_CORE_TESTS "Build the Sourcemeta Core tests" OFF) option(SOURCEMETA_CORE_BENCHMARK "Build the Sourcemeta Core benchmarks" OFF) option(SOURCEMETA_CORE_DOCS "Build the Sourcemeta Core docs" OFF) @@ -144,10 +143,6 @@ if(SOURCEMETA_CORE_EXTENSION_EDITORSCHEMA) add_subdirectory(src/extension/editorschema) endif() -if(SOURCEMETA_CORE_EXTENSION_BUILD) - add_subdirectory(src/extension/build) -endif() - if(SOURCEMETA_CORE_ADDRESS_SANITIZER) sourcemeta_sanitizer(TYPE address) elseif(SOURCEMETA_CORE_UNDEFINED_SANITIZER) @@ -259,10 +254,6 @@ if(SOURCEMETA_CORE_TESTS) add_subdirectory(test/editorschema) endif() - if(SOURCEMETA_CORE_EXTENSION_BUILD) - add_subdirectory(test/build) - endif() - if(PROJECT_IS_TOP_LEVEL) # Otherwise we need the child project to link # against the sanitizers too. diff --git a/config.cmake.in b/config.cmake.in index 7e5e6717c..9c5babb64 100644 --- a/config.cmake.in +++ b/config.cmake.in @@ -24,7 +24,6 @@ if(NOT SOURCEMETA_CORE_COMPONENTS) list(APPEND SOURCEMETA_CORE_COMPONENTS alterschema) list(APPEND SOURCEMETA_CORE_COMPONENTS editorschema) list(APPEND SOURCEMETA_CORE_COMPONENTS options) - list(APPEND SOURCEMETA_CORE_COMPONENTS build) endif() include(CMakeFindDependencyMacro) @@ -116,9 +115,6 @@ foreach(component ${SOURCEMETA_CORE_COMPONENTS}) include("${CMAKE_CURRENT_LIST_DIR}/sourcemeta_core_editorschema.cmake") elseif(component STREQUAL "options") include("${CMAKE_CURRENT_LIST_DIR}/sourcemeta_core_options.cmake") - elseif(component STREQUAL "build") - include("${CMAKE_CURRENT_LIST_DIR}/sourcemeta_core_io.cmake") - include("${CMAKE_CURRENT_LIST_DIR}/sourcemeta_core_build.cmake") else() message(FATAL_ERROR "Unknown Sourcemeta Core component: ${component}") endif() diff --git a/src/extension/build/CMakeLists.txt b/src/extension/build/CMakeLists.txt deleted file mode 100644 index aa6c9fbe2..000000000 --- a/src/extension/build/CMakeLists.txt +++ /dev/null @@ -1,8 +0,0 @@ -sourcemeta_library(NAMESPACE sourcemeta PROJECT core NAME build - PRIVATE_HEADERS types.h adapter_filesystem.h SOURCES adapter_filesystem.cc) - -if(SOURCEMETA_CORE_INSTALL) - sourcemeta_library_install(NAMESPACE sourcemeta PROJECT core NAME build) -endif() - -target_link_libraries(sourcemeta_core_build PRIVATE sourcemeta::core::io) diff --git a/src/extension/build/adapter_filesystem.cc b/src/extension/build/adapter_filesystem.cc deleted file mode 100644 index d14636c40..000000000 --- a/src/extension/build/adapter_filesystem.cc +++ /dev/null @@ -1,114 +0,0 @@ -#include - -#include - -#include // assert -#include // std::ofstream -#include // std::unique_lock - -namespace sourcemeta::core { - -BuildAdapterFilesystem::BuildAdapterFilesystem(std::string dependency_extension) - : extension{std::move(dependency_extension)} { - assert(!this->extension.empty()); - assert(this->extension.starts_with(".")); -} - -auto BuildAdapterFilesystem::dependencies_path(const node_type &path) const - -> node_type { - assert(path.is_absolute()); - return path.string() + this->extension; -} - -auto BuildAdapterFilesystem::read_dependencies(const node_type &path) const - -> std::optional> { - assert(path.is_absolute()); - const auto deps_path{this->dependencies_path(path)}; - if (std::filesystem::exists(deps_path)) { - auto stream{sourcemeta::core::read_file(deps_path)}; - assert(stream.is_open()); - - BuildDependencies deps; - std::string line; - while (std::getline(stream, line)) { - // Prevent CRLF on Windows - if (!line.empty() && line.back() == '\r') { - line.pop_back(); - } - - if (!line.empty()) { - deps.emplace_back(line); - } - } - - if (deps.empty()) { - return std::nullopt; - } else { - return deps; - } - } else { - return std::nullopt; - } -} - -auto BuildAdapterFilesystem::write_dependencies( - const node_type &path, const BuildDependencies &dependencies) - -> void { - assert(path.is_absolute()); - assert(std::filesystem::exists(path)); - // Try to make sure as much as we can that any write operation made to disk - flush(path); - this->refresh(path); - const auto deps_path{this->dependencies_path(path)}; - std::filesystem::create_directories(deps_path.parent_path()); - std::ofstream deps_stream{deps_path}; - assert(!deps_stream.fail()); - for (const auto &node : dependencies) { - deps_stream << node.string() << "\n"; - } - - deps_stream.flush(); - deps_stream.close(); - flush(deps_path); -} - -auto BuildAdapterFilesystem::refresh(const node_type &path) -> void { - // We prefer our own computed marks so that we don't have to rely - // too much on file-system specific non-sense - const auto value{std::filesystem::file_time_type::clock::now()}; - // Because builds are typically ran in parallel - std::unique_lock lock{this->mutex}; - this->marks.insert_or_assign(path, value); -} - -auto BuildAdapterFilesystem::mark(const node_type &path) - -> std::optional { - assert(path.is_absolute()); - - { - // Because a read operation while a write operation is taking place is - // undefined behaviour - std::shared_lock lock{this->mutex}; - const auto match{this->marks.find(path)}; - if (match != this->marks.end()) { - return match->second; - } - } - - try { - // Keep in mind that depending on the OS, filesystem, and even standard - // library implementation, this value might not be very reliable. In fact, - // in many cases it can be outdated. Therefore, we never cache this value - return std::filesystem::last_write_time(path); - } catch (const std::filesystem::filesystem_error &) { - return std::nullopt; - } -} - -auto BuildAdapterFilesystem::is_newer_than(const mark_type left, - const mark_type right) const - -> bool { - return left > right; -} - -} // namespace sourcemeta::core diff --git a/src/extension/build/include/sourcemeta/core/build.h b/src/extension/build/include/sourcemeta/core/build.h deleted file mode 100644 index a5afa63a6..000000000 --- a/src/extension/build/include/sourcemeta/core/build.h +++ /dev/null @@ -1,106 +0,0 @@ -#ifndef SOURCEMETA_CORE_BUILD_H_ -#define SOURCEMETA_CORE_BUILD_H_ - -// NOLINTBEGIN(misc-include-cleaner) -#include -#include -// NOLINTEND(misc-include-cleaner) - -#include // std::ranges::none_of -#include // assert - -/// @defgroup build Build -/// @brief A simple and minimalistic Make-style build system -/// -/// This functionality is included as follows: -/// -/// ```cpp -/// #include -/// ``` - -namespace sourcemeta::core { - -/// @ingroup build -/// -/// Run a handler given a destination node, a set of dependency nodes, and a -/// context value. The semantics of how nodes are retrieved, stored, and checked -/// for freshness depends on the adapter struct passed into the builder. If a -/// node is considered fresh given its static or dynamic dependencies, the -/// actual handler is never executed. -/// -/// Here is an example using the `BuildAdapterFilesystem` pre-built -/// opinionated adapter: -/// -/// ```c++ -/// #include -/// -/// auto HANDLER_COPY( -/// const std::filesystem::path &destination, -/// const sourcemeta::core::BuildDependencies -/// &dependencies, -/// // You may invoke this callback to register a dynamic dependency -/// const sourcemeta::core::BuildDynamicCallback &, -/// const std::filesystem::copy_options &options) -> void { -/// std::filesystem::create_directories(destination.parent_path()); -/// std::filesystem::copy_file(dependencies.front(), destination, options); -/// } -/// -/// sourcemeta::core::BuildAdapterFilesystem adapter; -/// -/// // The file will be generated -/// sourcemeta::core::build( -/// adapter, HANDLER_COPY, -/// "/tmp/destination.txt", {"/tmp/dependency.txt"}, -/// std::filesystem::copy_options::overwrite_existing); -/// -/// // The second time will result in a cache hit -/// sourcemeta::core::build( -/// adapter, HANDLER_COPY, -/// "/tmp/destination.txt", {"/tmp/dependency.txt"}, -/// std::filesystem::copy_options::overwrite_existing); -/// ``` -template -auto build(Adapter &adapter, - const BuildHandler &handler, - const typename Adapter::node_type &destination, - const BuildDependencies &dependencies, - const Context &context) -> bool { - const auto destination_mark{adapter.mark(destination)}; - const auto destination_dependencies{adapter.read_dependencies(destination)}; - if (destination_mark.has_value() && destination_dependencies.has_value() && - std::ranges::none_of( - destination_dependencies.value(), - [&adapter, &destination_mark](const auto &dependency) { - const auto dependency_mark = adapter.mark(dependency); - return !dependency_mark.has_value() || - adapter.is_newer_than(dependency_mark.value(), - destination_mark.value()); - })) { - return false; - } - - BuildDependencies deps; - for (const auto &dependency : dependencies) { - assert(adapter.mark(dependency).has_value()); - deps.emplace_back(dependency); - } - - handler( - destination, dependencies, - // This callback is used for build handlers to dynamically populate - // dependencies. This is very powerful for defining handlers where - // the actual list of dependencies is only known while or after - // processing the handler - [&](const auto &new_dependency) { - assert(adapter.mark(new_dependency).has_value()); - deps.emplace_back(new_dependency); - }, - context); - - adapter.write_dependencies(destination, deps); - return true; -} - -} // namespace sourcemeta::core - -#endif // SOURCEMETA_CORE_OPTIONS_H_ diff --git a/src/extension/build/include/sourcemeta/core/build_adapter_filesystem.h b/src/extension/build/include/sourcemeta/core/build_adapter_filesystem.h deleted file mode 100644 index a71fa6c2a..000000000 --- a/src/extension/build/include/sourcemeta/core/build_adapter_filesystem.h +++ /dev/null @@ -1,58 +0,0 @@ -#ifndef SOURCEMETA_CORE_BUILD_ADAPTER_FILESYSTEM_H_ -#define SOURCEMETA_CORE_BUILD_ADAPTER_FILESYSTEM_H_ - -#ifndef SOURCEMETA_CORE_BUILD_EXPORT -#include -#endif - -// NOLINTBEGIN(misc-include-cleaner) -#include -// NOLINTEND(misc-include-cleaner) - -#include // std::filesystem -#include // std::optional -#include // std::shared_mutex -#include // std::string -#include // std::unordered_map - -namespace sourcemeta::core { - -/// @ingroup build -class SOURCEMETA_CORE_BUILD_EXPORT BuildAdapterFilesystem { -public: - using node_type = std::filesystem::path; - using mark_type = std::filesystem::file_time_type; - - BuildAdapterFilesystem() = default; - BuildAdapterFilesystem(std::string dependency_extension); - - [[nodiscard]] auto dependencies_path(const node_type &path) const - -> node_type; - [[nodiscard]] auto read_dependencies(const node_type &path) const - -> std::optional>; - auto write_dependencies(const node_type &path, - const BuildDependencies &dependencies) - -> void; - auto refresh(const node_type &path) -> void; - [[nodiscard]] auto mark(const node_type &path) -> std::optional; - [[nodiscard]] auto is_newer_than(const mark_type left, - const mark_type right) const -> bool; - -private: -// 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 - std::string extension{".deps"}; - std::unordered_map marks; - std::shared_mutex mutex; -#if defined(_MSC_VER) -#pragma warning(default : 4251 4275) -#endif -}; - -} // namespace sourcemeta::core - -#endif // SOURCEMETA_CORE_OPTIONS_H_ diff --git a/src/extension/build/include/sourcemeta/core/build_types.h b/src/extension/build/include/sourcemeta/core/build_types.h deleted file mode 100644 index f789974c1..000000000 --- a/src/extension/build/include/sourcemeta/core/build_types.h +++ /dev/null @@ -1,26 +0,0 @@ -#ifndef SOURCEMETA_CORE_BUILD_TYPES_H_ -#define SOURCEMETA_CORE_BUILD_TYPES_H_ - -#include // std::function -#include // std::vector - -namespace sourcemeta::core { - -/// @ingroup build -template -using BuildDynamicCallback = std::function; - -/// @ingroup build -/// Dependencies are encoded using an ordered sequence type -template using BuildDependencies = std::vector; - -/// @ingroup build -template -using BuildHandler = - std::function &, - const BuildDynamicCallback &, - const Context &)>; - -} // namespace sourcemeta::core - -#endif // SOURCEMETA_CORE_OPTIONS_H_ diff --git a/test/build/CMakeLists.txt b/test/build/CMakeLists.txt deleted file mode 100644 index e97cc3363..000000000 --- a/test/build/CMakeLists.txt +++ /dev/null @@ -1,12 +0,0 @@ -sourcemeta_googletest(NAMESPACE sourcemeta PROJECT core NAME build - SOURCES - build_test_utils.h - build_adapter_filesystem_test.cc - build_adapter_filesystem_e2e_test.cc) - -target_link_libraries(sourcemeta_core_build_unit PRIVATE sourcemeta::core::build) - -target_compile_definitions(sourcemeta_core_build_unit - PRIVATE TEST_DIRECTORY="${CMAKE_CURRENT_SOURCE_DIR}") -target_compile_definitions(sourcemeta_core_build_unit - PRIVATE BINARY_DIRECTORY="${CMAKE_CURRENT_BINARY_DIR}") diff --git a/test/build/build_adapter_filesystem_e2e_test.cc b/test/build/build_adapter_filesystem_e2e_test.cc deleted file mode 100644 index 1ddd318cd..000000000 --- a/test/build/build_adapter_filesystem_e2e_test.cc +++ /dev/null @@ -1,163 +0,0 @@ -#include - -#include - -#include -#include - -#include "build_test_utils.h" - -auto read_uint64_t(const std::filesystem::path &path) -> std::uint64_t { - return std::stoull(READ_FILE(path)); -} - -auto write_uint64_t(const std::filesystem::path &path, - const std::uint64_t input) -> void { - WRITE_FILE(path, std::to_string(input)); -} - -template -auto HANDLER_MULTIPLY( - const typename Adapter::node_type &destination, - const sourcemeta::core::BuildDependencies - &dependencies, - const sourcemeta::core::BuildDynamicCallback &, - const Context &value) -> void { - assert(dependencies.size() == 1); - write_uint64_t(destination, read_uint64_t(dependencies.front()) * value); -} - -template -auto HANDLER_MIRROR_CONTEXT_NODE( - const typename Adapter::node_type &destination, - const sourcemeta::core::BuildDependencies &, - const sourcemeta::core::BuildDynamicCallback - &callback, - const Context &context) -> void { - const auto input{read_uint64_t(context)}; - callback(context); - write_uint64_t(destination, input); -} - -template -auto HANDLER_MIRROR_CONTEXT_NODE_WITHOUT_CALLBACK( - const typename Adapter::node_type &destination, - const sourcemeta::core::BuildDependencies &, - const sourcemeta::core::BuildDynamicCallback &, - const Context &context) -> void { - const auto input{read_uint64_t(context)}; - write_uint64_t(destination, input); -} - -TEST(Build_Adapter_Filesystem_e2e, simple_cache_miss_hit) { - using Adapter = sourcemeta::core::BuildAdapterFilesystem; - using Context = std::uint64_t; - Adapter adapter; - - const auto base_path{std::filesystem::path{BINARY_DIRECTORY} / - "simple_cache_miss_hit"}; - write_uint64_t(base_path / "initial.txt", 8); - EXPECT_EQ(read_uint64_t(base_path / "initial.txt"), 8); - adapter.refresh(base_path / "initial.txt"); - - // Create first.txt from initial.txt (cache miss) - const auto result_1 = sourcemeta::core::build( - adapter, HANDLER_MULTIPLY, base_path / "first.txt", - {base_path / "initial.txt"}, 2); - EXPECT_TRUE(result_1); - EXPECT_EQ(read_uint64_t(base_path / "first.txt"), 16); - - // Create second.txt from first.txt (cache miss) - const auto result_2 = sourcemeta::core::build( - adapter, HANDLER_MULTIPLY, base_path / "second.txt", - {base_path / "first.txt"}, 3); - EXPECT_TRUE(result_2); - EXPECT_EQ(read_uint64_t(base_path / "second.txt"), 48); - - // Create first.txt from initial.txt (cache hit) - const auto result_3 = sourcemeta::core::build( - adapter, HANDLER_MULTIPLY, base_path / "first.txt", - {base_path / "initial.txt"}, 2); - EXPECT_FALSE(result_3); - EXPECT_EQ(read_uint64_t(base_path / "first.txt"), 16); - - // Create second.txt from first.txt (cache hit) - const auto result_4 = sourcemeta::core::build( - adapter, HANDLER_MULTIPLY, base_path / "second.txt", - {base_path / "first.txt"}, 3); - EXPECT_FALSE(result_4); - EXPECT_EQ(read_uint64_t(base_path / "second.txt"), 48); - - // Update initial.txt - write_uint64_t(base_path / "initial.txt", 7); - EXPECT_EQ(read_uint64_t(base_path / "initial.txt"), 7); - adapter.refresh(base_path / "initial.txt"); - - // Create first.txt from initial.txt (cache miss) - const auto result_5 = sourcemeta::core::build( - adapter, HANDLER_MULTIPLY, base_path / "first.txt", - {base_path / "initial.txt"}, 2); - EXPECT_TRUE(result_5); - EXPECT_EQ(read_uint64_t(base_path / "first.txt"), 14); - - // Create second.txt from first.txt (cache miss) - const auto result_6 = sourcemeta::core::build( - adapter, HANDLER_MULTIPLY, base_path / "second.txt", - {base_path / "first.txt"}, 3); - EXPECT_TRUE(result_6); - EXPECT_EQ(read_uint64_t(base_path / "second.txt"), 42); -} - -TEST(Build_Adapter_Filesystem_e2e, dynamic_dependency) { - using Adapter = sourcemeta::core::BuildAdapterFilesystem; - using Context = Adapter::node_type; - Adapter adapter; - - const auto base_path{std::filesystem::path{BINARY_DIRECTORY} / - "dynamic_dependency"}; - write_uint64_t(base_path / "initial.txt", 8); - EXPECT_EQ(read_uint64_t(base_path / "initial.txt"), 8); - adapter.refresh(base_path / "initial.txt"); - - // Create copy.txt from initial.txt (cache miss) - const auto result_1 = sourcemeta::core::build( - adapter, HANDLER_MIRROR_CONTEXT_NODE, - base_path / "copy.txt", {}, base_path / "initial.txt"); - EXPECT_TRUE(result_1); - EXPECT_EQ(read_uint64_t(base_path / "copy.txt"), 8); - - // Create copy.txt from initial.txt (cache hit) - const auto result_2 = sourcemeta::core::build( - adapter, HANDLER_MIRROR_CONTEXT_NODE, - base_path / "copy.txt", {}, base_path / "initial.txt"); - // As the context was dynamically registered - EXPECT_FALSE(result_2); - EXPECT_EQ(read_uint64_t(base_path / "copy.txt"), 8); -} - -TEST(Build_Adapter_Filesystem_e2e, missing_dynamic_dependency) { - using Adapter = sourcemeta::core::BuildAdapterFilesystem; - using Context = Adapter::node_type; - Adapter adapter; - - const auto base_path{std::filesystem::path{BINARY_DIRECTORY} / - "missing_dynamic_dependency"}; - write_uint64_t(base_path / "initial.txt", 8); - EXPECT_EQ(read_uint64_t(base_path / "initial.txt"), 8); - adapter.refresh(base_path / "initial.txt"); - - // Create copy.txt from initial.txt (cache miss) - const auto result_1 = sourcemeta::core::build( - adapter, HANDLER_MIRROR_CONTEXT_NODE_WITHOUT_CALLBACK, - base_path / "copy.txt", {}, base_path / "initial.txt"); - EXPECT_TRUE(result_1); - EXPECT_EQ(read_uint64_t(base_path / "copy.txt"), 8); - - // Create copy.txt from initial.txt (cache miss) - const auto result_2 = sourcemeta::core::build( - adapter, HANDLER_MIRROR_CONTEXT_NODE_WITHOUT_CALLBACK, - base_path / "copy.txt", {}, base_path / "initial.txt"); - // As the context was NOT dynamically registered - EXPECT_TRUE(result_2); - EXPECT_EQ(read_uint64_t(base_path / "copy.txt"), 8); -} diff --git a/test/build/build_adapter_filesystem_test.cc b/test/build/build_adapter_filesystem_test.cc deleted file mode 100644 index 7540eabf3..000000000 --- a/test/build/build_adapter_filesystem_test.cc +++ /dev/null @@ -1,152 +0,0 @@ -#include - -#include - -#include - -#include "build_test_utils.h" - -TEST(Build_Adapter_Filesystem, dependencies_path) { - sourcemeta::core::BuildAdapterFilesystem adapter; - const auto result{adapter.dependencies_path("/foo/bar.baz")}; - EXPECT_EQ(result, "/foo/bar.baz.deps"); -} - -TEST(Build_Adapter_Filesystem, dependencies_path_with_custom_extension) { - sourcemeta::core::BuildAdapterFilesystem adapter{".custom-deps"}; - const auto result{adapter.dependencies_path("/foo/bar.baz")}; - EXPECT_EQ(result, "/foo/bar.baz.custom-deps"); -} - -TEST(Build_Adapter_Filesystem, read_dependencies_stub_1) { - const std::filesystem::path stub{std::filesystem::path{TEST_DIRECTORY} / - "deps_stub_1.json"}; - sourcemeta::core::BuildAdapterFilesystem adapter; - const auto dependencies{adapter.read_dependencies(stub)}; - EXPECT_TRUE(dependencies.has_value()); - EXPECT_EQ(dependencies.value().size(), 2); - auto iterator{dependencies.value().cbegin()}; - EXPECT_EQ(iterator->string(), "/foo/bar"); - std::advance(iterator, 1); - EXPECT_EQ(iterator->string(), "/test"); -} - -TEST(Build_Adapter_Filesystem, read_dependencies_not_exists) { - const std::filesystem::path stub{std::filesystem::path{TEST_DIRECTORY} / - "unknown"}; - sourcemeta::core::BuildAdapterFilesystem adapter; - const auto dependencies{adapter.read_dependencies(stub)}; - EXPECT_FALSE(dependencies.has_value()); -} - -TEST(Build_Adapter_Filesystem, write_dependencies_1) { - sourcemeta::core::BuildDependencies< - sourcemeta::core::BuildAdapterFilesystem::node_type> - dependencies; - dependencies.emplace_back("/foo/bar"); - dependencies.emplace_back("/baz"); - dependencies.emplace_back("/test"); - - const auto node{std::filesystem::path{BINARY_DIRECTORY} / - "write_dependencies_1"}; - - WRITE_FILE(node, "test"); - - sourcemeta::core::BuildAdapterFilesystem adapter; - adapter.write_dependencies(node, dependencies); - const auto back{adapter.read_dependencies(node)}; - EXPECT_TRUE(back.has_value()); - EXPECT_EQ(back.value().size(), 3); - - auto iterator{back.value().cbegin()}; - EXPECT_EQ(iterator->string(), "/foo/bar"); - std::advance(iterator, 1); - EXPECT_EQ(iterator->string(), "/baz"); - std::advance(iterator, 1); - EXPECT_EQ(iterator->string(), "/test"); -} - -TEST(Build_Adapter_Filesystem, mark_stub_1) { - const std::filesystem::path stub{std::filesystem::path{TEST_DIRECTORY} / - "deps_stub_1.json.deps"}; - sourcemeta::core::BuildAdapterFilesystem adapter; - const auto mark{adapter.mark(stub)}; - EXPECT_TRUE(mark.has_value()); -} - -TEST(Build_Adapter_Filesystem, mark_stub_not_exists) { - const std::filesystem::path stub{std::filesystem::path{TEST_DIRECTORY} / - "unknown"}; - sourcemeta::core::BuildAdapterFilesystem adapter; - const auto mark{adapter.mark(stub)}; - EXPECT_FALSE(mark.has_value()); -} - -TEST(Build_Adapter_Filesystem, is_newer_than_same_with_refresh) { - const std::filesystem::path file{std::filesystem::path{BINARY_DIRECTORY} / - "is_newer_than_same"}; - sourcemeta::core::BuildAdapterFilesystem adapter; - WRITE_FILE(file, "test"); - adapter.refresh(file); - const auto mark{adapter.mark(file)}; - EXPECT_TRUE(mark.has_value()); - EXPECT_FALSE(adapter.is_newer_than(mark.value(), mark.value())); -} - -TEST(Build_Adapter_Filesystem, is_newer_than_same_without_refresh) { - const std::filesystem::path file{std::filesystem::path{BINARY_DIRECTORY} / - "is_newer_than_same"}; - WRITE_FILE(file, "test"); - sourcemeta::core::BuildAdapterFilesystem adapter; - const auto mark{adapter.mark(file)}; - EXPECT_TRUE(mark.has_value()); - EXPECT_FALSE(adapter.is_newer_than(mark.value(), mark.value())); -} - -TEST(Build_Adapter_Filesystem, is_newer_than) { - const std::filesystem::path file_1{std::filesystem::path{BINARY_DIRECTORY} / - "is_newer_than" / "1.txt"}; - const std::filesystem::path file_2{std::filesystem::path{BINARY_DIRECTORY} / - "is_newer_than" / "2.txt"}; - - sourcemeta::core::BuildAdapterFilesystem adapter; - - WRITE_FILE(file_1, "test_1"); - adapter.refresh(file_1); - WRITE_FILE(file_2, "test_2"); - adapter.refresh(file_2); - - const auto mark_1{adapter.mark(file_1)}; - const auto mark_2{adapter.mark(file_2)}; - - EXPECT_TRUE(mark_1.has_value()); - EXPECT_TRUE(mark_2.has_value()); - - EXPECT_FALSE(adapter.is_newer_than(mark_1.value(), mark_2.value())); - EXPECT_TRUE(adapter.is_newer_than(mark_2.value(), mark_1.value())); -} - -TEST(Build_Adapter_Filesystem, is_newer_than_with_update) { - const std::filesystem::path file_1{std::filesystem::path{BINARY_DIRECTORY} / - "is_newer_than_with_update" / "1.txt"}; - const std::filesystem::path file_2{std::filesystem::path{BINARY_DIRECTORY} / - "is_newer_than_with_update" / "2.txt"}; - - sourcemeta::core::BuildAdapterFilesystem adapter; - - WRITE_FILE(file_1, "test_1"); - adapter.refresh(file_1); - WRITE_FILE(file_2, "test_2"); - adapter.refresh(file_2); - WRITE_FILE(file_1, "test_3"); - adapter.refresh(file_1); - - const auto mark_1{adapter.mark(file_1)}; - const auto mark_2{adapter.mark(file_2)}; - - EXPECT_TRUE(mark_1.has_value()); - EXPECT_TRUE(mark_2.has_value()); - - EXPECT_TRUE(adapter.is_newer_than(mark_1.value(), mark_2.value())); - EXPECT_FALSE(adapter.is_newer_than(mark_2.value(), mark_1.value())); -} diff --git a/test/build/build_test_utils.h b/test/build/build_test_utils.h deleted file mode 100644 index a24072c2a..000000000 --- a/test/build/build_test_utils.h +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef SOURCEMETA_CORE_BUILD_TEST_UTILSH_ -#define SOURCEMETA_CORE_BUILD_TEST_UTILSH_ - -#include -#include -#include - -inline auto READ_FILE(const std::filesystem::path &path) -> std::string { - std::ifstream stream{path}; - std::ostringstream buffer; - buffer << stream.rdbuf(); - return buffer.str(); -} - -inline auto WRITE_FILE(const std::filesystem::path &path, - const std::string &contents) -> void { - std::filesystem::create_directories(path.parent_path()); - std::ofstream stream{path}; - assert(!stream.fail()); - stream << contents; - stream.flush(); - stream.close(); -} - -#endif diff --git a/test/build/deps_stub_1.json.deps b/test/build/deps_stub_1.json.deps deleted file mode 100644 index c9d771195..000000000 --- a/test/build/deps_stub_1.json.deps +++ /dev/null @@ -1,2 +0,0 @@ -/foo/bar -/test diff --git a/test/packaging/find_package/CMakeLists.txt b/test/packaging/find_package/CMakeLists.txt index ff2246fcc..9f65a6d59 100644 --- a/test/packaging/find_package/CMakeLists.txt +++ b/test/packaging/find_package/CMakeLists.txt @@ -23,4 +23,3 @@ target_link_libraries(core_hello PRIVATE sourcemeta::core::html) target_link_libraries(core_hello PRIVATE sourcemeta::core::alterschema) target_link_libraries(core_hello PRIVATE sourcemeta::core::editorschema) target_link_libraries(core_hello PRIVATE sourcemeta::core::options) -target_link_libraries(core_hello PRIVATE sourcemeta::core::build) diff --git a/test/packaging/find_package/hello.cc b/test/packaging/find_package/hello.cc index ecabe3932..1b96457bb 100644 --- a/test/packaging/find_package/hello.cc +++ b/test/packaging/find_package/hello.cc @@ -1,5 +1,4 @@ #include -#include #include #include #include