diff --git a/.github/workflows/build_test.yml b/.github/workflows/build_test.yml index 33c0cbdea..5b6953c07 100644 --- a/.github/workflows/build_test.yml +++ b/.github/workflows/build_test.yml @@ -122,16 +122,7 @@ jobs: install build/test/odr_test build/test/Release/odr_test.exe - build/_deps/odr.js-src - if-no-files-found: error - include-hidden-files: true - - # TODO this is only needed because of data files from dependencies; there should be a better solution - - name: upload conan directory to github - uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7 - with: - name: conan-${{ matrix.host_profile }} - path: ${{ env.CONAN_HOME }} + build/data if-no-files-found: error include-hidden-files: true @@ -226,7 +217,7 @@ jobs: with: python-version: 3.14 - name: install python dependencies - run: pip install htmlcmp==1.2.1 + run: pip install htmlcmp==1.2.4 - name: download binaries uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8 @@ -234,12 +225,6 @@ jobs: name: bin-${{ matrix.host_profile }} path: . - - name: download conan directory - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8 - with: - name: conan-${{ matrix.host_profile }} - path: ${{ env.CONAN_HOME }} - - name: fix artifact permissions if: runner.os != 'Windows' run: chmod +x build/test/odr_test diff --git a/CMakeLists.txt b/CMakeLists.txt index 339c3ddfa..bf466c6b1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -17,6 +17,9 @@ option(ODR_CLANG_TIDY "Run clang-tidy static analysis" OFF) option(WITH_PDF2HTMLEX "Build with pdf2htmlEX" ON) option(WITH_WVWARE "Build with wvWare" ON) option(WITH_LIBMAGIC "Build with libmagic" ON) +option(ODR_BUNDLE_ASSETS "Bundle assets during build and install" ON) + +include(GNUInstallDirs) # TODO defining global compiler flags seems to be bad practice with conan # TODO consider using conan profiles @@ -54,10 +57,6 @@ FetchContent_Declare(odr.js ) FetchContent_MakeAvailable(odr.js) -set(ODR_DATA_PATH "${odr.js_SOURCE_DIR}") - -configure_file("src/odr/internal/project_info.cpp.in" "src/odr/internal/project_info.cpp") - set(PRE_CONFIGURE_FILE "src/odr/internal/git_info.cpp.in") set(POST_CONFIGURE_FILE "${CMAKE_CURRENT_BINARY_DIR}/src/odr/internal/git_info.cpp") if (EXISTS "${PROJECT_SOURCE_DIR}/.git") @@ -213,6 +212,10 @@ target_link_libraries(odr argon2::argon2 ) +set(ODR_BUILD_ODR_DATA_PATH "${CMAKE_CURRENT_BINARY_DIR}/data") +file(COPY "${odr.js_SOURCE_DIR}/" DESTINATION "${ODR_BUILD_ODR_DATA_PATH}") +set(ODR_INSTALL_ODR_DATA_PATH "${CMAKE_INSTALL_DATADIR}") + if (WITH_PDF2HTMLEX) find_package(pdf2htmlEX REQUIRED) find_package(poppler REQUIRED) @@ -230,6 +233,28 @@ if (WITH_PDF2HTMLEX) PRIVATE ODR_WITH_PDF2HTMLEX ) + + if (ODR_BUNDLE_ASSETS) + set(ODR_BUILD_FONTCONFIG_DATA_PATH "${ODR_BUILD_ODR_DATA_PATH}/fontconfig") + set(ODR_BUILD_POPPLER_DATA_PATH "${ODR_BUILD_ODR_DATA_PATH}/poppler") + set(ODR_BUILD_PDF2HTMLEX_DATA_PATH "${ODR_BUILD_ODR_DATA_PATH}/pdf2htmlex") + + file(COPY "${FONTCONFIG_DATA_PATH}/" DESTINATION "${ODR_BUILD_FONTCONFIG_DATA_PATH}") + file(COPY "${POPPLER_DATA_PATH}/" DESTINATION "${ODR_BUILD_POPPLER_DATA_PATH}") + file(COPY "${PDF2HTMLEX_DATA_PATH}/" DESTINATION "${ODR_BUILD_PDF2HTMLEX_DATA_PATH}") + + set(ODR_INSTALL_FONTCONFIG_DATA_PATH "${ODR_INSTALL_ODR_DATA_PATH}/fontconfig") + set(ODR_INSTALL_POPPLER_DATA_PATH "${ODR_INSTALL_ODR_DATA_PATH}/poppler") + set(ODR_INSTALL_PDF2HTMLEX_DATA_PATH "${ODR_INSTALL_ODR_DATA_PATH}/pdf2htmlex") + else () + set(ODR_BUILD_FONTCONFIG_DATA_PATH "${FONTCONFIG_DATA_PATH}") + set(ODR_BUILD_POPPLER_DATA_PATH "${POPPLER_DATA_PATH}") + set(ODR_BUILD_PDF2HTMLEX_DATA_PATH "${PDF2HTMLEX_DATA_PATH}") + + set(ODR_INSTALL_FONTCONFIG_DATA_PATH "${FONTCONFIG_DATA_PATH}") + set(ODR_INSTALL_POPPLER_DATA_PATH "${POPPLER_DATA_PATH}") + set(ODR_INSTALL_PDF2HTMLEX_DATA_PATH "${PDF2HTMLEX_DATA_PATH}") + endif () endif () if (WITH_WVWARE) find_package(wvware REQUIRED) @@ -261,8 +286,22 @@ if (WITH_LIBMAGIC) PRIVATE ODR_WITH_LIBMAGIC ) + + if (ODR_BUNDLE_ASSETS) + set(ODR_BUILD_LIBMAGIC_DATABASE_PATH "${ODR_BUILD_ODR_DATA_PATH}/magic.mgc") + + file(COPY_FILE "${LIBMAGIC_DATABASE_PATH}" "${ODR_BUILD_LIBMAGIC_DATABASE_PATH}") + + set(ODR_INSTALL_LIBMAGIC_DATABASE_PATH "${ODR_INSTALL_ODR_DATA_PATH}/magic.mgc") + else () + set(ODR_BUILD_LIBMAGIC_DATABASE_PATH "${LIBMAGIC_DATABASE_PATH}") + + set(ODR_INSTALL_LIBMAGIC_DATABASE_PATH "${LIBMAGIC_DATABASE_PATH}") + endif () endif () +configure_file("src/odr/internal/project_info.cpp.in" "src/odr/internal/project_info.cpp") + if (EXISTS "${PROJECT_SOURCE_DIR}/.git") add_dependencies(odr check_git) endif () @@ -279,8 +318,6 @@ if (ODR_CLANG_TIDY) add_subdirectory("static_analysis/clang-tidy") endif () -include(GNUInstallDirs) - install( DIRECTORY src/ "${CMAKE_CURRENT_BINARY_DIR}/src/" DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}" @@ -294,6 +331,6 @@ install( ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}" ) install( - DIRECTORY "${ODR_DATA_PATH}/" - DESTINATION "${CMAKE_INSTALL_DATADIR}" + DIRECTORY "${ODR_BUILD_ODR_DATA_PATH}/" + DESTINATION "${ODR_INSTALL_ODR_DATA_PATH}" ) diff --git a/src/odr/global_params.hpp b/src/odr/global_params.hpp index 17e44dcb8..66c081790 100644 --- a/src/odr/global_params.hpp +++ b/src/odr/global_params.hpp @@ -4,7 +4,7 @@ namespace odr { -class GlobalParams { +class GlobalParams final { public: static const std::string &odr_core_data_path(); static const std::string &fontconfig_data_path(); diff --git a/src/odr/internal/git_info.cpp.in b/src/odr/internal/git_info.cpp.in index ffe20a793..198bf4f8c 100644 --- a/src/odr/internal/git_info.cpp.in +++ b/src/odr/internal/git_info.cpp.in @@ -6,4 +6,4 @@ const char *git_info::commit_hash() noexcept { return "@GIT_HEAD_SHA1@"; } bool git_info::is_dirty() noexcept { return @GIT_IS_DIRTY@; } -} +} // namespace odr::internal diff --git a/src/odr/internal/project_info.cpp.in b/src/odr/internal/project_info.cpp.in index ec761e147..7c9d0ca48 100644 --- a/src/odr/internal/project_info.cpp.in +++ b/src/odr/internal/project_info.cpp.in @@ -2,58 +2,60 @@ namespace odr::internal { -const char *project_info::version() noexcept { return "${CMAKE_PROJECT_VERSION}"; } +const char *project_info::version() noexcept { + return "${CMAKE_PROJECT_VERSION}"; +} bool project_info::is_debug() noexcept { #ifdef NDEBUG - return false; + return false; #else - return true; + return true; #endif } bool project_info::has_wvware() noexcept { #ifdef ODR_WITH_WVWARE - return true; + return true; #else - return false; + return false; #endif } -bool project_info::has_pdf2htmlex() noexcept{ +bool project_info::has_pdf2htmlex() noexcept { #ifdef ODR_WITH_PDF2HTMLEX - return true; + return true; #else - return false; + return false; #endif } -bool project_info::has_libmagic() noexcept{ +bool project_info::has_libmagic() noexcept { #ifdef ODR_WITH_LIBMAGIC - return true; + return true; #else - return false; + return false; #endif } const char *project_info::odr_data_path() noexcept { - return "${ODR_DATA_PATH}"; + return "${ODR_INSTALL_ODR_DATA_PATH}"; } const char *project_info::fontconfig_data_path() noexcept { - return "${FONTCONFIG_DATA_PATH}"; + return "${ODR_INSTALL_FONTCONFIG_DATA_PATH}"; } const char *project_info::poppler_data_path() noexcept { - return "${POPPLER_DATA_PATH}"; + return "${ODR_INSTALL_POPPLER_DATA_PATH}"; } -const char *project_info::pdf2htmlex_data_path() noexcept{ - return "${PDF2HTMLEX_DATA_PATH}"; +const char *project_info::pdf2htmlex_data_path() noexcept { + return "${ODR_INSTALL_PDF2HTMLEX_DATA_PATH}"; } -const char *project_info::libmagic_database_path() noexcept{ - return "${LIBMAGIC_DATABASE_PATH}"; +const char *project_info::libmagic_database_path() noexcept { + return "${ODR_INSTALL_LIBMAGIC_DATABASE_PATH}"; } } // namespace odr::internal diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index dbbbc1f2f..7ef040114 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -2,14 +2,15 @@ find_package(GTest REQUIRED) include(GoogleTest REQUIRED) -set(ODR_RESOURCE_DIRECTORY "${odr.js_SOURCE_DIR}") set(ODR_TEST_DATA_DIRECTORY "${CMAKE_CURRENT_LIST_DIR}/data") -configure_file("src/test_constants.cpp.in" "src/test_constants.cpp") +configure_file("src/test_info.cpp.in" "src/test_info.cpp") enable_testing() add_executable(odr_test + "src/test_main.cpp" + "src/test_util.cpp" - "${CMAKE_CURRENT_BINARY_DIR}/src/test_constants.cpp" + "${CMAKE_CURRENT_BINARY_DIR}/src/test_info.cpp" "src/document_path_test.cpp" "src/document_test.cpp" @@ -61,7 +62,6 @@ target_link_libraries(odr_test vincentlaucsb-csv-parser::vincentlaucsb-csv-parser uchardet::uchardet GTest::gtest - GTest::gtest_main odr ) diff --git a/test/src/html_output_test.cpp b/test/src/html_output_test.cpp index 98f1489f8..7517ad257 100644 --- a/test/src/html_output_test.cpp +++ b/test/src/html_output_test.cpp @@ -5,6 +5,7 @@ #include #include +#include #include #include @@ -158,7 +159,7 @@ TEST_P(HtmlOutputTests, html_meta) { const std::string resource_path = Path(output_path_prefix).parent().join(RelPath("resources")).string(); - std::filesystem::copy(TestData::resource_directory(), resource_path, + std::filesystem::copy(info::odr_data_path(), resource_path, fs::copy_options::recursive | fs::copy_options::overwrite_existing); diff --git a/test/src/test_constants.cpp.in b/test/src/test_constants.cpp.in deleted file mode 100644 index 9c5113a8f..000000000 --- a/test/src/test_constants.cpp.in +++ /dev/null @@ -1,9 +0,0 @@ -#include - -namespace odr::test { - -std::string TestData::resource_directory() { return "${ODR_RESOURCE_DIRECTORY}"; } - -std::string TestData::data_directory() { return "${ODR_TEST_DATA_DIRECTORY}"; } - -} // namespace odr::test diff --git a/test/src/test_info.cpp.in b/test/src/test_info.cpp.in new file mode 100644 index 000000000..44274ef79 --- /dev/null +++ b/test/src/test_info.cpp.in @@ -0,0 +1,27 @@ +#include + +namespace odr::test { + +const char *info::odr_data_path() noexcept { + return "${ODR_BUILD_ODR_DATA_PATH}"; +} + +const char *info::fontconfig_data_path() noexcept { + return "${ODR_BUILD_FONTCONFIG_DATA_PATH}"; +} + +const char *info::poppler_data_path() noexcept { + return "${ODR_BUILD_POPPLER_DATA_PATH}"; +} + +const char *info::pdf2htmlex_data_path() noexcept { + return "${ODR_BUILD_PDF2HTMLEX_DATA_PATH}"; +} + +const char *info::libmagic_database_path() noexcept { + return "${ODR_BUILD_LIBMAGIC_DATABASE_PATH}"; +} + +const char *info::odr_test_data_path() noexcept { return "${ODR_TEST_DATA_DIRECTORY}"; } + +} // namespace odr::test diff --git a/test/src/test_info.hpp b/test/src/test_info.hpp new file mode 100644 index 000000000..d2f8b198f --- /dev/null +++ b/test/src/test_info.hpp @@ -0,0 +1,13 @@ +#pragma once + +namespace odr::test::info { + +const char *odr_data_path() noexcept; +const char *fontconfig_data_path() noexcept; +const char *poppler_data_path() noexcept; +const char *pdf2htmlex_data_path() noexcept; +const char *libmagic_database_path() noexcept; + +const char *odr_test_data_path() noexcept; + +} // namespace odr::test::info diff --git a/test/src/test_main.cpp b/test/src/test_main.cpp new file mode 100644 index 000000000..8c05e1f81 --- /dev/null +++ b/test/src/test_main.cpp @@ -0,0 +1,11 @@ +#include + +#include + +int main(int argc, char **argv) { + ::testing::InitGoogleTest(&argc, argv); + + odr::test::set_global_params(); + + return RUN_ALL_TESTS(); +} diff --git a/test/src/test_util.cpp b/test/src/test_util.cpp index 22b8a6efd..ec5e37d04 100644 --- a/test/src/test_util.cpp +++ b/test/src/test_util.cpp @@ -1,4 +1,9 @@ +#include + +#include + #include +#include #include #include @@ -8,13 +13,24 @@ #include #include #include -#include #include using namespace odr; using namespace odr::internal; namespace fs = std::filesystem; +namespace odr { + +void test::set_global_params() { + GlobalParams::set_odr_core_data_path(info::odr_data_path()); + GlobalParams::set_fontconfig_data_path(info::fontconfig_data_path()); + GlobalParams::set_poppler_data_path(info::poppler_data_path()); + GlobalParams::set_pdf2htmlex_data_path(info::pdf2htmlex_data_path()); + GlobalParams::set_libmagic_database_path(info::libmagic_database_path()); +} + +} // namespace odr + namespace odr::test { namespace { @@ -97,7 +113,7 @@ std::vector get_test_files(const std::string &root_path, std::vector get_test_files() { std::vector result; - for (const std::string root = TestData::data_input_directory(); + for (const std::string root = TestData::test_input_directory(); const auto &e : fs::directory_iterator(root)) { const auto files = get_test_files(root, e.path().string()); result.insert(std::end(result), std::begin(files), std::end(files)); @@ -118,8 +134,8 @@ TestFile::TestFile(std::string absolute_path, std::string short_path, short_path{std::move(short_path)}, type{type}, password{std::move(password)} {} -std::string TestData::data_input_directory() { - return Path(data_directory()).join(RelPath("input")).string(); +std::string TestData::test_input_directory() { + return Path(info::odr_test_data_path()).join(RelPath("input")).string(); } TestData &TestData::instance_() { @@ -151,11 +167,11 @@ std::string TestData::test_file_path(const std::string &short_path) { TestData::TestData() : m_test_files{get_test_files()} {} -std::vector TestData::test_files_(const FileType fileType) const { +std::vector TestData::test_files_(const FileType file_type) const { std::vector result; result.reserve(m_test_files.size()); for (auto &&file : m_test_files) { - if (file.type == fileType) { + if (file.type == file_type) { result.push_back(file); } } diff --git a/test/src/test_util.hpp b/test/src/test_util.hpp index ca92e16e1..dee638ab8 100644 --- a/test/src/test_util.hpp +++ b/test/src/test_util.hpp @@ -7,6 +7,8 @@ namespace odr::test { +void set_global_params(); + struct TestFile { std::string absolute_path; std::string short_path; @@ -20,9 +22,7 @@ struct TestFile { class TestData { public: - static std::string resource_directory(); - static std::string data_directory(); - static std::string data_input_directory(); + static std::string test_input_directory(); static std::vector test_files(); static std::vector test_files(FileType); @@ -38,8 +38,9 @@ class TestData { private: TestData(); - static TestData &instance_(); - [[nodiscard]] std::vector test_files_(FileType) const; + [[nodiscard]] static TestData &instance_(); + + [[nodiscard]] std::vector test_files_(FileType file_type) const; std::vector m_test_files; };