From 34a8f5252a59595997d1d3ec6dd166f6af82abd1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ale=C5=A1=20Mat=C4=9Bj?= Date: Wed, 29 May 2024 10:01:48 +0200 Subject: [PATCH 1/4] Clean up `repo` header includes --- dnf5-plugins/automatic_plugin/automatic.cpp | 1 + include/libdnf5/repo/repo.hpp | 3 --- libdnf5/repo/repo.cpp | 2 +- libdnf5/repo/repo_sack.cpp | 3 ++- test/libdnf5/repo/test_repo.cpp | 1 + 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/dnf5-plugins/automatic_plugin/automatic.cpp b/dnf5-plugins/automatic_plugin/automatic.cpp index 751d1031d..3f4c4efac 100644 --- a/dnf5-plugins/automatic_plugin/automatic.cpp +++ b/dnf5-plugins/automatic_plugin/automatic.cpp @@ -28,6 +28,7 @@ along with libdnf. If not, see . #include #include #include +#include #include #include #include diff --git a/include/libdnf5/repo/repo.hpp b/include/libdnf5/repo/repo.hpp index a79b0f28a..3de7b59e1 100644 --- a/include/libdnf5/repo/repo.hpp +++ b/include/libdnf5/repo/repo.hpp @@ -26,10 +26,7 @@ along with libdnf. If not, see . #include "repo_callbacks.hpp" #include "libdnf5/base/base_weak.hpp" -#include "libdnf5/common/exception.hpp" -#include "libdnf5/common/weak_ptr.hpp" #include "libdnf5/defs.h" -#include "libdnf5/repo/repo_errors.hpp" #include "libdnf5/repo/repo_weak.hpp" #include "libdnf5/rpm/package.hpp" diff --git a/libdnf5/repo/repo.cpp b/libdnf5/repo/repo.cpp index 6046e3a22..52fd42018 100644 --- a/libdnf5/repo/repo.cpp +++ b/libdnf5/repo/repo.cpp @@ -17,6 +17,7 @@ You should have received a copy of the GNU Lesser General Public License along with libdnf. If not, see . */ +#include "libdnf5/repo/repo_errors.hpp" constexpr const char * REPOID_CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_.:"; #include "repo_cache_private.hpp" @@ -49,7 +50,6 @@ extern "C" { #include #include #include -#include #include diff --git a/libdnf5/repo/repo_sack.cpp b/libdnf5/repo/repo_sack.cpp index 5667697f3..58d38b5a8 100644 --- a/libdnf5/repo/repo_sack.cpp +++ b/libdnf5/repo/repo_sack.cpp @@ -19,11 +19,12 @@ along with libdnf. If not, see . #include "libdnf5/repo/repo_sack.hpp" +#include "libdnf5/repo/repo_errors.hpp" + #include "../module/module_sack_impl.hpp" #include "conf/config.h" #include "repo_cache_private.hpp" #include "repo_downloader.hpp" -#include "rpm/package_sack_impl.hpp" #include "solv/solver.hpp" #include "solv_repo.hpp" #include "utils/auth.hpp" diff --git a/test/libdnf5/repo/test_repo.cpp b/test/libdnf5/repo/test_repo.cpp index 660986aab..82ffe5ee4 100644 --- a/test/libdnf5/repo/test_repo.cpp +++ b/test/libdnf5/repo/test_repo.cpp @@ -23,6 +23,7 @@ along with libdnf. If not, see . #include "utils/string.hpp" #include +#include CPPUNIT_TEST_SUITE_REGISTRATION(RepoTest); From b6b26d6f525f2ba1842d28db1f72b50f68b1854f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ale=C5=A1=20Mat=C4=9Bj?= Date: Wed, 29 May 2024 13:47:18 +0200 Subject: [PATCH 2/4] Remove unused includes in test_modules --- test/libdnf5/module/test_module.cpp | 5 ----- 1 file changed, 5 deletions(-) diff --git a/test/libdnf5/module/test_module.cpp b/test/libdnf5/module/test_module.cpp index 7e5c3ca7d..b7e628ed0 100644 --- a/test/libdnf5/module/test_module.cpp +++ b/test/libdnf5/module/test_module.cpp @@ -26,8 +26,6 @@ along with libdnf. If not, see . #include "module/module_db.hpp" #include "system/state.hpp" -#include "libdnf5/utils/fs/file.hpp" - #include #include #include @@ -37,9 +35,6 @@ along with libdnf. If not, see . #include #include -#include -#include -#include #include CPPUNIT_TEST_SUITE_REGISTRATION(ModuleTest); From 3d29235b97eef2c755343ee48cf1c940e188b3f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ale=C5=A1=20Mat=C4=9Bj?= Date: Fri, 31 May 2024 06:27:11 +0200 Subject: [PATCH 3/4] Add a copr build with disabled modules to verify it works --- .packit.yaml | 62 ++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 53 insertions(+), 9 deletions(-) diff --git a/.packit.yaml b/.packit.yaml index da251069d..eeb469e57 100644 --- a/.packit.yaml +++ b/.packit.yaml @@ -1,17 +1,37 @@ # See the documentation for more information: # https://packit.dev/docs/configuration/ -specfile_path: dnf5.spec +packages: + dnf5: + specfile_path: dnf5.spec -# add or remove files that should be synced -files_to_sync: - - dnf5.spec - - .packit.yaml + # add or remove files that should be synced + files_to_sync: + - dnf5.spec + - .packit.yaml -# name in upstream package repository or registry (e.g. in PyPI) -upstream_package_name: dnf5 -# downstream (Fedora) RPM package name -downstream_package_name: dnf5 + # name in upstream package repository or registry (e.g. in PyPI) + upstream_package_name: dnf5 + # downstream (Fedora) RPM package name + downstream_package_name: dnf5 + + # Test build with disabled modules. + # Use separate package configuration because Packit + # doesn't yet support dependencies between jobs so if we + # had multiple copr_builds it woudn't know which to use + # for tests jobs. + # https://github.com/packit/packit-service/issues/1720 + dnf5-without-modules: + specfile_path: dnf5.spec + + # add or remove files that should be synced + files_to_sync: + - dnf5.spec + - .packit.yaml + + # name in upstream package repository or registry (e.g. in PyPI) + upstream_package_name: dnf5 + downstream_package_name: dnf5 jobs: - job: propose_downstream @@ -19,14 +39,17 @@ jobs: dist_git_branches: - fedora-rawhide copy_upstream_release_description: true + packages: [dnf5] - job: koji_build trigger: commit dist_git_branches: - fedora-all + packages: [dnf5] - job: bodhi_update trigger: commit dist_git_branches: - fedora-all + packages: [dnf5] - job: copr_build trigger: pull_request targets: @@ -35,6 +58,7 @@ jobs: actions: get-current-version: - bash -c 'rpmspec -q --queryformat "%{VERSION}\n" dnf5.spec | head -n1' + packages: [dnf5] - job: copr_build trigger: pull_request targets: @@ -43,6 +67,7 @@ jobs: actions: get-current-version: - bash -c 'rpmspec -q --queryformat "%{VERSION}\n" dnf5.spec | head -n1' + packages: [dnf5] - job: tests trigger: pull_request identifier: "dnf5-tests" @@ -51,6 +76,7 @@ jobs: fmf_url: https://github.com/rpm-software-management/ci-dnf-stack.git fmf_ref: main tmt_plan: "^/plans/integration/behave-dnf5$" + packages: [dnf5] - job: tests trigger: pull_request identifier: "createrepo_c-tests" @@ -59,6 +85,7 @@ jobs: fmf_url: https://github.com/rpm-software-management/ci-dnf-stack.git fmf_ref: main tmt_plan: "^/plans/integration/behave-createrepo_c$" + packages: [dnf5] - job: tests trigger: pull_request identifier: "dnf-tests" @@ -68,6 +95,7 @@ jobs: fmf_url: https://github.com/rpm-software-management/ci-dnf-stack.git fmf_ref: main tmt_plan: "^/plans/integration/behave-dnf$" + packages: [dnf5] - job: tests trigger: pull_request identifier: "dnf5daemon-tests" @@ -76,3 +104,19 @@ jobs: fmf_url: https://github.com/rpm-software-management/ci-dnf-stack.git fmf_ref: main tmt_plan: "^/plans/integration/behave-dnf5daemon$" + packages: [dnf5] + - job: copr_build + identifier: "WITH_MODULEMD=OFF" + trigger: pull_request + branch: 'main' + targets: + - fedora-rawhide-x86_64 + actions: + fix-spec-file: + # disable modulemd in spec to verify the build is passing without it + - sed -i dnf5.spec -e "s/bcond_without modulemd/bcond_with modulemd/" + # fill in Release as if packit would have done it + - bash -c "sed -i -r \"s/Release:(\s*)\S+/Release:\1${PACKIT_RPMSPEC_RELEASE}%{?dist}/\" dnf5.spec" + get-current-version: + - bash -c 'rpmspec -q --queryformat "%{VERSION}\n" dnf5.spec | head -n1' + packages: [dnf5-without-modules] From a0970bea3db749d765ccb6c05e03e49429a6c5f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ale=C5=A1=20Mat=C4=9Bj?= Date: Tue, 25 Jun 2024 10:19:03 +0200 Subject: [PATCH 4/4] Implement conditional compilation `-DWITH_MODULEMD=OFF` When WITH_MODULEMD is turned off module sources are not compiled and module headers are not installed. Public API in non-module headers (base.hpp and goal.hpp) is still available but throws an exception when used. Another option would be to also hide the functions in non-module headers but in order to ensure the headers always match the compiled library (so they don't depend on the user not defining `WITH_MODULEMD`) they would have to be configured via a constant at compile time. For example using cmake to `configure_file` turning them into `.in` files. --- CMakeLists.txt | 6 +++- dnf5/CMakeLists.txt | 8 ++++- dnf5/main.cpp | 4 +++ include/libdnf5-cli/CMakeLists.txt | 12 +++++++ include/libdnf5/CMakeLists.txt | 10 ++++++ include/libdnf5/base/base.hpp | 9 +++--- include/libdnf5/base/goal.hpp | 3 ++ libdnf5-cli/CMakeLists.txt | 11 ++++++- libdnf5/CMakeLists.txt | 18 ++++++++--- libdnf5/base/base.cpp | 19 ++++++++++- libdnf5/base/base_impl.hpp | 6 +++- libdnf5/base/goal.cpp | 39 ++++++++++++++++++++--- libdnf5/base/transaction.cpp | 19 +++++++++-- libdnf5/base/transaction_impl.hpp | 11 ++++++- libdnf5/repo/repo.cpp | 2 +- libdnf5/repo/repo_downloader.cpp | 2 +- libdnf5/repo/repo_sack.cpp | 4 +++ libdnf5/system/state.cpp | 8 +++++ libdnf5/system/state.hpp | 8 +++++ libdnf5/utils/dnf4convert/dnf4convert.cpp | 2 ++ libdnf5/utils/dnf4convert/dnf4convert.hpp | 2 ++ test/libdnf5/module/test_module.cpp | 4 +++ test/libdnf5/module/test_module.hpp | 4 +++ test/libdnf5/system/test_state.cpp | 10 ++++++ test/shared/utils.hpp | 2 ++ 25 files changed, 199 insertions(+), 24 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 2267e3d65..b9d031f42 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,5 @@ message("Running CMake on dnf5...") -cmake_minimum_required(VERSION 3.5) +cmake_minimum_required(VERSION 3.6) include(VERSION.cmake) @@ -119,6 +119,10 @@ if(WITH_TRANSLATIONS) add_custom_target(gettext-potfiles) endif() +# When modules are enabled add WITH_MODULEMD definition for all sub-directories (all components). +if (WITH_MODULEMD) + add_definitions(-DWITH_MODULEMD) +endif() include_directories("${PROJECT_SOURCE_DIR}/include") include_directories("${PROJECT_SOURCE_DIR}/common") diff --git a/dnf5/CMakeLists.txt b/dnf5/CMakeLists.txt index ca9d91302..a73706721 100644 --- a/dnf5/CMakeLists.txt +++ b/dnf5/CMakeLists.txt @@ -20,9 +20,15 @@ add_definitions(-DINSTALL_PREFIX=\"${CMAKE_INSTALL_PREFIX}\") # set SYSCONFIG_DIR, used to find the directory containing the dnf5 configuration add_definitions(-DSYSCONFIG_DIR=\"${CMAKE_INSTALL_FULL_SYSCONFDIR}\") -# use any sources found under the current directory +# use sources found under the current directory file(GLOB_RECURSE DNF5_SOURCES *.cpp) +# exclude module sources if WITH_MODULEMD not defined +if (NOT WITH_MODULEMD) + file(GLOB_RECURSE DNF5_SOURCES_MODULES commands/module/*.cpp) + list(REMOVE_ITEM DNF5_SOURCES ${DNF5_SOURCES_MODULES}) +endif() + include_directories("${PROJECT_SOURCE_DIR}/dnf5/include/") include_directories(.) diff --git a/dnf5/main.cpp b/dnf5/main.cpp index c8bdcf7dc..1dbc1a876 100644 --- a/dnf5/main.cpp +++ b/dnf5/main.cpp @@ -35,7 +35,9 @@ along with libdnf. If not, see . #include "commands/list/list.hpp" #include "commands/makecache/makecache.hpp" #include "commands/mark/mark.hpp" +#ifdef WITH_MODULEMD #include "commands/module/module.hpp" +#endif #include "commands/offline/offline.hpp" #include "commands/provides/provides.hpp" #include "commands/reinstall/reinstall.hpp" @@ -687,7 +689,9 @@ static void add_commands(Context & context) { context.add_and_initialize_command(std::make_unique(context)); context.add_and_initialize_command(std::make_unique(context)); +#ifdef WITH_MODULEMD context.add_and_initialize_command(std::make_unique(context)); +#endif context.add_and_initialize_command(std::make_unique(context)); context.add_and_initialize_command(std::make_unique(context)); context.add_and_initialize_command(std::make_unique(context)); diff --git a/include/libdnf5-cli/CMakeLists.txt b/include/libdnf5-cli/CMakeLists.txt index 45e310d89..c1dd6848e 100644 --- a/include/libdnf5-cli/CMakeLists.txt +++ b/include/libdnf5-cli/CMakeLists.txt @@ -5,6 +5,18 @@ endif() file(GLOB_RECURSE LIBDNF5_CLI_HEADERS *.hpp) +if (NOT WITH_MODULEMD) + file(GLOB_RECURSE LIBDNF5_CLI_HEADERS_MODULES + output/adapters/module.hpp + output/adapters/module_tmpl.hpp + output/interfaces/module.hpp + output/moduleinfo.hpp + output/modulelist.hpp) + + list(REMOVE_ITEM LIBDNF5_CLI_HEADERS ${LIBDNF5_CLI_HEADERS_MODULES}) +endif() + + # preserve relative paths of the header files foreach(abspath ${LIBDNF5_CLI_HEADERS}) # relative path to the header file diff --git a/include/libdnf5/CMakeLists.txt b/include/libdnf5/CMakeLists.txt index 0299ba9d1..c153d6b0e 100644 --- a/include/libdnf5/CMakeLists.txt +++ b/include/libdnf5/CMakeLists.txt @@ -1,5 +1,15 @@ file(GLOB_RECURSE LIBDNF5_HEADERS *.hpp *.h) +if (NOT WITH_MODULEMD) + file(GLOB_RECURSE LIBDNF5_HEADERS_MODULES module/*.hpp) + + # module_sack_weak.hpp is needed for base.hpp API + # its not actually used and it doesn't include any other libdnf5 header + list(FILTER LIBDNF5_HEADERS_MODULES EXCLUDE REGEX .*module_sack_weak.hpp) + + list(REMOVE_ITEM LIBDNF5_HEADERS ${LIBDNF5_HEADERS_MODULES}) +endif() + # preserve relative paths of the header files foreach(abspath ${LIBDNF5_HEADERS}) # relative path to the header file diff --git a/include/libdnf5/base/base.hpp b/include/libdnf5/base/base.hpp index 435defd0c..257a7b480 100644 --- a/include/libdnf5/base/base.hpp +++ b/include/libdnf5/base/base.hpp @@ -28,22 +28,20 @@ along with libdnf. If not, see . #include "libdnf5/conf/vars.hpp" #include "libdnf5/defs.h" #include "libdnf5/logger/log_router.hpp" -#include "libdnf5/module/module_sack.hpp" +#include "libdnf5/module/module_sack_weak.hpp" #include "libdnf5/plugin/plugin_info.hpp" #include "libdnf5/repo/download_callbacks.hpp" #include "libdnf5/repo/repo_sack.hpp" #include "libdnf5/rpm/package_sack.hpp" #include "libdnf5/transaction/transaction_history.hpp" -#include -#include - namespace libdnf5::module { class ModuleDB; +class ModuleSack; -} +} // namespace libdnf5::module namespace libdnf5 { @@ -86,6 +84,7 @@ class LIBDNF_API Base { LogRouterWeakPtr get_logger(); repo::RepoSackWeakPtr get_repo_sack(); rpm::PackageSackWeakPtr get_rpm_package_sack(); + /// Throws libdnf5::AssertionError when used with libdnf5 compiled without modules enabled. module::ModuleSackWeakPtr get_module_sack(); /// Adds a request to enable/disable plugins that match the names (glob patterns) in the list. diff --git a/include/libdnf5/base/goal.hpp b/include/libdnf5/base/goal.hpp index a4a711c0d..a18a5a0ee 100644 --- a/include/libdnf5/base/goal.hpp +++ b/include/libdnf5/base/goal.hpp @@ -39,18 +39,21 @@ class LIBDNF_API Goal { ~Goal(); /// Add module enable request to the goal. + /// Throws libdnf5::AssertionError when used with libdnf5 compiled without modules enabled. /// @param spec A string with module spec to enable. /// @param settings A structure to override default goal settings. // @replaces dnf:dnf/module/module_base.py:method:ModuleBase().enable(self, module_specs) void add_module_enable(const std::string & spec, const libdnf5::GoalJobSettings & settings); /// Add module disable request to the goal. + /// Throws libdnf5::AssertionError when used with libdnf5 compiled without modules enabled. /// @param spec A string with module spec to disable. /// @param settings A structure to override default goal settings. // @replaces dnf:dnf/module/module_base.py:method:ModuleBase().disable(self, module_specs) void add_module_disable(const std::string & spec, const libdnf5::GoalJobSettings & settings); /// Add module reset request to the goal. + /// Throws libdnf5::AssertionError when used with libdnf5 compiled without modules enabled. /// @param spec A string with module spec to reset. /// @param settings A structure to override default goal settings. // @replaces dnf:dnf/module/module_base.py:method:ModuleBase().reset(self, module_specs) diff --git a/libdnf5-cli/CMakeLists.txt b/libdnf5-cli/CMakeLists.txt index 2367fc406..ec9163594 100644 --- a/libdnf5-cli/CMakeLists.txt +++ b/libdnf5-cli/CMakeLists.txt @@ -8,9 +8,18 @@ set(GETTEXT_DOMAIN libdnf5-cli) add_definitions(-DGETTEXT_DOMAIN=\"${GETTEXT_DOMAIN}\") -# use any sources found under the current directory +# use sources found under the current directory file(GLOB_RECURSE LIBDNF5_CLI_SOURCES *.cpp) +# exclude module sources if WITH_MODULEMD not defined +if (NOT WITH_MODULEMD) + file(GLOB_RECURSE LIBDNF5_CLI_SOURCES_MODULES + output/adapters/module.cpp + output/moduleinfo.cpp + output/modulelist.cpp) + + list(REMOVE_ITEM LIBDNF5_CLI_SOURCES ${LIBDNF5_CLI_SOURCES_MODULES}) +endif() # gather all pkg-config requires and write them to a .pc file later list(APPEND LIBDNF5_CLI_PC_REQUIRES) diff --git a/libdnf5/CMakeLists.txt b/libdnf5/CMakeLists.txt index 6bbe04ee9..3795d0f69 100644 --- a/libdnf5/CMakeLists.txt +++ b/libdnf5/CMakeLists.txt @@ -1,6 +1,12 @@ -# use any sources found under the current directory +# use sources found under the current directory file(GLOB_RECURSE LIBDNF5_SOURCES *.cpp *.c) +# exclude module sources if WITH_MODULEMD not defined +if (NOT WITH_MODULEMD) + file(GLOB_RECURSE LIBDNF5_SOURCES_MODULES module/*.cpp) + list(REMOVE_ITEM LIBDNF5_SOURCES ${LIBDNF5_SOURCES_MODULES}) +endif() + # create config header file configure_file("config.h.in" ${CMAKE_CURRENT_SOURCE_DIR}/conf/config.h) @@ -65,10 +71,12 @@ include_directories(${JSONC_INCLUDE_DIRS}) target_link_libraries(libdnf5 PRIVATE ${JSONC_LIBRARIES}) target_link_libraries(libdnf5_static PRIVATE ${JSONC_LIBRARIES}) -pkg_check_modules(LIBMODULEMD REQUIRED modulemd-2.0>=2.11.2) -list(APPEND LIBDNF5_PC_REQUIRES "${LIBMODULEMD_MODULE_NAME}") -target_link_libraries(libdnf5 PRIVATE ${LIBMODULEMD_LIBRARIES}) -target_link_libraries(libdnf5_static PRIVATE ${LIBMODULEMD_LIBRARIES}) +if (WITH_MODULEMD) + pkg_check_modules(LIBMODULEMD REQUIRED modulemd-2.0>=2.11.2) + list(APPEND LIBDNF5_PC_REQUIRES "${LIBMODULEMD_MODULE_NAME}") + target_link_libraries(libdnf5 PRIVATE ${LIBMODULEMD_LIBRARIES}) + target_link_libraries(libdnf5_static PRIVATE ${LIBMODULEMD_LIBRARIES}) +endif() pkg_check_modules(LIBSOLV REQUIRED libsolv>=0.7.25) list(APPEND LIBDNF5_PC_REQUIRES "${LIBSOLV_MODULE_NAME}") diff --git a/libdnf5/base/base.cpp b/libdnf5/base/base.cpp index 4f682d9c9..705979ace 100644 --- a/libdnf5/base/base.cpp +++ b/libdnf5/base/base.cpp @@ -22,7 +22,13 @@ along with libdnf. If not, see . #include "../conf/config_utils.hpp" #include "base_impl.hpp" #include "conf/config.h" + +#ifdef WITH_MODULEMD #include "module/module_sack_impl.hpp" + +#include "libdnf5/module/module_sack.hpp" +#endif + #include "solv/pool.hpp" #include "utils/dnf4convert/dnf4convert.hpp" #include "utils/fs/utils.hpp" @@ -55,9 +61,12 @@ Base::Impl::Impl(const libdnf5::BaseWeakPtr & base, std::vectorget_value("arch").c_str(); pool_setarch(**pool, arch); +#ifdef WITH_MODULEMD p_impl->module_sack.p_impl->set_arch(arch); +#endif pool_set_rootdir(**pool, installroot.get_value().c_str()); p_impl->plugins.post_base_setup(); @@ -303,7 +316,11 @@ transaction::TransactionHistoryWeakPtr Base::get_transaction_history() { return p_impl->transaction_history.get_weak_ptr(); } libdnf5::module::ModuleSackWeakPtr Base::get_module_sack() { +#ifdef WITH_MODULEMD return p_impl->module_sack.get_weak_ptr(); +#else + libdnf_throw_assertion("libdnf5 compiled without module support."); +#endif } VarsWeakPtr Base::get_vars() { diff --git a/libdnf5/base/base_impl.hpp b/libdnf5/base/base_impl.hpp index def8a0289..b706bbb6c 100644 --- a/libdnf5/base/base_impl.hpp +++ b/libdnf5/base/base_impl.hpp @@ -20,12 +20,14 @@ along with libdnf. If not, see . #ifndef LIBDNF5_BASE_BASE_IMPL_HPP #define LIBDNF5_BASE_BASE_IMPL_HPP - #include "../advisory/advisory_sack.hpp" #include "plugin/plugins.hpp" #include "system/state.hpp" #include "libdnf5/base/base.hpp" +#ifdef WITH_MODULEMD +#include "libdnf5/module/module_sack.hpp" +#endif namespace libdnf5 { @@ -90,7 +92,9 @@ class Base::Impl { ConfigMain config; repo::RepoSack repo_sack; rpm::PackageSack rpm_package_sack; +#ifdef WITH_MODULEMD module::ModuleSack module_sack; +#endif std::map variables; transaction::TransactionHistory transaction_history; Vars vars; diff --git a/libdnf5/base/goal.cpp b/libdnf5/base/goal.cpp index 6415d0bdd..29273de4a 100644 --- a/libdnf5/base/goal.cpp +++ b/libdnf5/base/goal.cpp @@ -21,8 +21,10 @@ along with libdnf. If not, see . #include "advisory/advisory_package_private.hpp" #include "base_private.hpp" +#ifdef WITH_MODULEMD #include "module/module_goal_private.hpp" #include "module/module_sack_impl.hpp" +#endif #include "rpm/package_query_impl.hpp" #include "rpm/package_sack_impl.hpp" #include "rpm/package_set_impl.hpp" @@ -38,7 +40,9 @@ along with libdnf. If not, see . #include "libdnf5/common/exception.hpp" #include "libdnf5/comps/environment/query.hpp" #include "libdnf5/comps/group/query.hpp" +#ifdef WITH_MODULEMD #include "libdnf5/module/module_errors.hpp" +#endif #include "libdnf5/rpm/package_query.hpp" #include "libdnf5/rpm/reldep.hpp" #include "libdnf5/utils/bgettext/bgettext-mark-domain.h" @@ -106,7 +110,9 @@ class Goal::Impl { GoalProblem resolve_group_specs(std::vector & specs, base::Transaction & transaction); void add_resolved_group_specs_to_goal(base::Transaction & transaction); void add_resolved_environment_specs_to_goal(base::Transaction & transaction); +#ifdef WITH_MODULEMD GoalProblem add_module_specs_to_goal(base::Transaction & transaction); +#endif GoalProblem add_serialized_transaction_to_goal(base::Transaction & transaction); GoalProblem add_reason_change_specs_to_goal(base::Transaction & transaction); @@ -232,16 +238,31 @@ Goal::~Goal() = default; Goal::Impl::~Impl() = default; -void Goal::add_module_enable(const std::string & spec, const libdnf5::GoalJobSettings & settings) { +void Goal::add_module_enable( + [[maybe_unused]] const std::string & spec, [[maybe_unused]] const libdnf5::GoalJobSettings & settings) { +#ifdef WITH_MODULEMD p_impl->module_specs.push_back(std::make_tuple(GoalAction::ENABLE, spec, settings)); +#else + libdnf_throw_assertion("libdnf5 compiled without module support."); +#endif } -void Goal::add_module_disable(const std::string & spec, const libdnf5::GoalJobSettings & settings) { +void Goal::add_module_disable( + [[maybe_unused]] const std::string & spec, [[maybe_unused]] const libdnf5::GoalJobSettings & settings) { +#ifdef WITH_MODULEMD p_impl->module_specs.push_back(std::make_tuple(GoalAction::DISABLE, spec, settings)); +#else + libdnf_throw_assertion("libdnf5 compiled without module support."); +#endif } -void Goal::add_module_reset(const std::string & spec, const libdnf5::GoalJobSettings & settings) { +void Goal::add_module_reset( + [[maybe_unused]] const std::string & spec, [[maybe_unused]] const libdnf5::GoalJobSettings & settings) { +#ifdef WITH_MODULEMD p_impl->module_specs.push_back(std::make_tuple(GoalAction::RESET, spec, settings)); +#else + libdnf_throw_assertion("libdnf5 compiled without module support."); +#endif } void Goal::add_install(const std::string & spec, const libdnf5::GoalJobSettings & settings) { @@ -602,6 +623,8 @@ GoalProblem Goal::Impl::add_specs_to_goal(base::Transaction & transaction) { return ret; } + +#ifdef WITH_MODULEMD GoalProblem Goal::Impl::add_module_specs_to_goal(base::Transaction & transaction) { auto ret = GoalProblem::NO_PROBLEM; module::ModuleSack & module_sack = *base->get_module_sack(); @@ -656,6 +679,7 @@ GoalProblem Goal::Impl::add_module_specs_to_goal(base::Transaction & transaction } return ret; } +#endif GoalProblem Goal::Impl::add_serialized_transaction_to_goal(base::Transaction & transaction) { if (!serialized_transaction) { @@ -2789,6 +2813,7 @@ base::Transaction Goal::resolve() { sack->p_impl->make_provides_ready(); +#ifdef WITH_MODULEMD module::ModuleSack & module_sack = *p_impl->base->get_module_sack(); ret |= p_impl->add_module_specs_to_goal(transaction); @@ -2828,6 +2853,7 @@ base::Transaction Goal::resolve() { } module_sack.p_impl->enable_dependent_modules(); +#endif // TODO(jmracek) Apply comps second or later @@ -2922,7 +2948,12 @@ base::Transaction Goal::resolve() { libdnf5::Logger::Level::WARNING); } - transaction.p_impl->set_transaction(p_impl->rpm_goal, module_sack, ret); + transaction.p_impl->set_transaction( + p_impl->rpm_goal, +#ifdef WITH_MODULEMD + module_sack, +#endif + ret); return transaction; } diff --git a/libdnf5/base/transaction.cpp b/libdnf5/base/transaction.cpp index 699de29f4..b39d32c86 100644 --- a/libdnf5/base/transaction.cpp +++ b/libdnf5/base/transaction.cpp @@ -21,8 +21,10 @@ along with libdnf. If not, see . #include "rpm/transaction.hpp" #include "base_impl.hpp" +#ifdef WITH_MODULEMD #include "module/module_db.hpp" #include "module/module_sack_impl.hpp" +#endif #include "repo/temp_files_memory.hpp" #include "rpm/package_set_impl.hpp" #include "solv/pool.hpp" @@ -186,11 +188,14 @@ Transaction::Impl::Impl(Transaction & transaction, const Impl & src) packages(src.packages), groups(src.groups), environments(src.environments), +#ifdef WITH_MODULEMD modules(src.modules), module_db(src.module_db), +#endif resolve_logs(src.resolve_logs), transaction_problems(src.transaction_problems), - signature_problems(src.signature_problems) {} + signature_problems(src.signature_problems) { +} Transaction::Impl & Transaction::Impl::operator=(const Impl & other) { base = other.base; @@ -200,8 +205,10 @@ Transaction::Impl & Transaction::Impl::operator=(const Impl & other) { packages = other.packages; groups = other.groups; environments = other.environments; +#ifdef WITH_MODULEMD modules = other.modules; module_db = other.module_db; +#endif resolve_logs = other.resolve_logs; transaction_problems = other.transaction_problems; signature_problems = other.signature_problems; @@ -649,7 +656,11 @@ void Transaction::Impl::process_solver_problems(rpm::solv::GoalPrivate & solved_ } void Transaction::Impl::set_transaction( - rpm::solv::GoalPrivate & solved_goal, module::ModuleSack & module_sack, GoalProblem problems) { + rpm::solv::GoalPrivate & solved_goal, +#ifdef WITH_MODULEMD + module::ModuleSack & module_sack, +#endif + GoalProblem problems) { process_solver_problems(solved_goal); if (!solver_problems.empty()) { add_resolve_log(GoalProblem::SOLVER_ERROR, solver_problems); @@ -734,6 +745,7 @@ void Transaction::Impl::set_transaction( groups.emplace_back(std::move(tsgrp)); } +#ifdef WITH_MODULEMD // Add modules to the transaction module_db = module_sack.p_impl->module_db->get_weak_ptr(); for (auto & [name, stream] : module_db->get_all_newly_enabled_streams()) { @@ -760,6 +772,7 @@ void Transaction::Impl::set_transaction( tsmodule.p_impl->replaces_append(std::string(name_streams.first), std::string(name_streams.second.second)); modules.emplace_back(std::move(tsmodule)); } +#endif // Add reason change actions to the transaction for (auto & [pkg, reason, group_id] : solved_goal.list_reason_changes()) { @@ -1053,6 +1066,7 @@ Transaction::TransactionRunResult Transaction::Impl::_run( auto logger = base->get_logger().get(); +#ifdef WITH_MODULEMD if (!modules.empty()) { module_db->save(); try { @@ -1061,6 +1075,7 @@ Transaction::TransactionRunResult Transaction::Impl::_run( logger->error("Cannot save system state: {}", ex.what()); } } +#endif int pipe_out_from_scriptlets[2]; if (pipe(pipe_out_from_scriptlets) == -1) { diff --git a/libdnf5/base/transaction_impl.hpp b/libdnf5/base/transaction_impl.hpp index 5cc2b656b..caf865c00 100644 --- a/libdnf5/base/transaction_impl.hpp +++ b/libdnf5/base/transaction_impl.hpp @@ -21,7 +21,9 @@ along with libdnf. If not, see . #define LIBDNF5_BASE_TRANSACTION_IMPL_HPP +#ifdef WITH_MODULEMD #include "module/module_db.hpp" +#endif #include "rpm/solv/goal_private.hpp" #include "libdnf5/base/transaction.hpp" @@ -49,7 +51,12 @@ class Transaction::Impl { Impl & operator=(const Impl & other); /// Set transaction according resolved goal and problems to EventLog - void set_transaction(rpm::solv::GoalPrivate & solved_goal, module::ModuleSack & module_sack, GoalProblem problems); + void set_transaction( + rpm::solv::GoalPrivate & solved_goal, +#ifdef WITH_MODULEMD + module::ModuleSack & module_sack, +#endif + GoalProblem problems); TransactionPackage make_transaction_package( Id id, @@ -98,7 +105,9 @@ class Transaction::Impl { std::vector groups; std::vector environments; std::vector modules; +#ifdef WITH_MODULEMD module::ModuleDBWeakPtr module_db; +#endif /// additional_data> std::vector resolve_logs; diff --git a/libdnf5/repo/repo.cpp b/libdnf5/repo/repo.cpp index 52fd42018..fa180f6bb 100644 --- a/libdnf5/repo/repo.cpp +++ b/libdnf5/repo/repo.cpp @@ -433,7 +433,7 @@ void Repo::load_available_repo() { } // Load module metadata -#ifdef MODULEMD +#ifdef WITH_MODULEMD auto & logger = *p_impl->base->get_logger(); std::string ext_fn = p_impl->downloader->get_metadata_path(RepoDownloader::MD_FILENAME_MODULES); diff --git a/libdnf5/repo/repo_downloader.cpp b/libdnf5/repo/repo_downloader.cpp index b5aaebab6..7d84fad5b 100644 --- a/libdnf5/repo/repo_downloader.cpp +++ b/libdnf5/repo/repo_downloader.cpp @@ -474,7 +474,7 @@ void RepoDownloader::common_handle_setup(LibrepoHandle & h) { auto optional_metadata = get_optional_metadata(); dlist.push_back(MD_FILENAME_PRIMARY); -#ifdef MODULEMD +#ifdef WITH_MODULEMD dlist.push_back(MD_FILENAME_MODULES); #endif if (optional_metadata.extract(libdnf5::METADATA_TYPE_FILELISTS)) { diff --git a/libdnf5/repo/repo_sack.cpp b/libdnf5/repo/repo_sack.cpp index 58d38b5a8..9682854f6 100644 --- a/libdnf5/repo/repo_sack.cpp +++ b/libdnf5/repo/repo_sack.cpp @@ -21,7 +21,9 @@ along with libdnf. If not, see . #include "libdnf5/repo/repo_errors.hpp" +#ifdef WITH_MODULEMD #include "../module/module_sack_impl.hpp" +#endif #include "conf/config.h" #include "repo_cache_private.hpp" #include "repo_downloader.hpp" @@ -576,7 +578,9 @@ void RepoSack::Impl::update_and_load_repos(libdnf5::repo::RepoQuery & repos, boo fix_group_missing_xml(); base->get_rpm_package_sack()->load_config_excludes_includes(); +#ifdef WITH_MODULEMD base->get_module_sack()->p_impl->module_filtering(); +#endif repos_updated_and_loaded = true; base->p_impl->get_plugins().repos_loaded(); diff --git a/libdnf5/system/state.cpp b/libdnf5/system/state.cpp index a8500749f..f5a08d17e 100644 --- a/libdnf5/system/state.cpp +++ b/libdnf5/system/state.cpp @@ -155,6 +155,7 @@ struct into { }; +#ifdef WITH_MODULEMD template <> struct from { static libdnf5::system::ModuleState from_toml(const value & v) { @@ -181,6 +182,7 @@ struct into { return res; } }; +#endif template <> @@ -460,6 +462,7 @@ std::set State::get_group_environments(const std::string & id) { return environments; } +#ifdef WITH_MODULEMD const std::map & State::get_module_states() { return module_states; } @@ -483,6 +486,7 @@ void State::set_module_state(const std::string & name, const ModuleState & modul void State::remove_module_state(const std::string & name) { module_states.erase(name); } +#endif std::string State::get_rpmdb_cookie() const { @@ -518,7 +522,9 @@ void State::save() { utils::fs::File(get_group_state_path(), "w").write(toml_format(make_top_value("groups", group_states))); utils::fs::File(get_environment_state_path(), "w") .write(toml_format(make_top_value("environments", environment_states))); +#ifdef WITH_MODULEMD utils::fs::File(get_module_state_path(), "w").write(toml_format(make_top_value("modules", module_states))); +#endif utils::fs::File(get_system_state_path(), "w").write(toml_format(make_top_value("system", system_state))); } @@ -551,7 +557,9 @@ void State::load() { group_states = load_toml_data>(get_group_state_path(), "groups"); environment_states = load_toml_data>(get_environment_state_path(), "environments"); +#ifdef WITH_MODULEMD module_states = load_toml_data>(get_module_state_path(), "modules"); +#endif system_state = load_toml_data(get_system_state_path(), "system"); package_groups_cache.reset(); } diff --git a/libdnf5/system/state.hpp b/libdnf5/system/state.hpp index 49944953e..8730e4c10 100644 --- a/libdnf5/system/state.hpp +++ b/libdnf5/system/state.hpp @@ -60,12 +60,14 @@ class EnvironmentState { std::vector groups; }; +#ifdef WITH_MODULEMD class ModuleState { public: std::string enabled_stream; module::ModuleStatus status{module::ModuleStatus::AVAILABLE}; std::vector installed_profiles{}; }; +#endif class SystemState { public: @@ -208,6 +210,7 @@ class State { /// @since 5.0 std::set get_group_environments(const std::string & id); +#ifdef WITH_MODULEMD /// @return All module states. /// @since 5.0.8 const std::map & get_module_states(); @@ -221,6 +224,7 @@ class State { /// @param name The module name to set the state for. /// @since 5.0.8 void set_module_state(const std::string & name, const ModuleState & module_state); +#endif /// Removes the state for a module name. /// @param name The module name to remove the state for. @@ -248,10 +252,12 @@ class State { /// @since 5.0 bool packages_import_required(); +#ifdef WITH_MODULEMD /// Reset modules states to match given new values. /// @param new_states New values for modules states. /// @since 5.0 void reset_module_states(std::map new_states) { module_states = new_states; } +#endif /// Reset packages system state to match given values. /// @param installed_packages Vector of tuples of currently installed packages @@ -303,7 +309,9 @@ class State { std::map nevra_states; std::map group_states; std::map environment_states; +#ifdef WITH_MODULEMD std::map module_states; +#endif SystemState system_state; std::optional>> package_groups_cache; }; diff --git a/libdnf5/utils/dnf4convert/dnf4convert.cpp b/libdnf5/utils/dnf4convert/dnf4convert.cpp index 56e761739..d2198914e 100644 --- a/libdnf5/utils/dnf4convert/dnf4convert.cpp +++ b/libdnf5/utils/dnf4convert/dnf4convert.cpp @@ -143,6 +143,7 @@ WHERE )**"; +#ifdef WITH_MODULEMD std::map Dnf4Convert::read_module_states() { std::map module_states; @@ -178,6 +179,7 @@ std::map Dnf4Convert::read_module_sta } return module_states; } +#endif bool Dnf4Convert::read_package_states_from_history( diff --git a/libdnf5/utils/dnf4convert/dnf4convert.hpp b/libdnf5/utils/dnf4convert/dnf4convert.hpp index 659cb48b4..7592be637 100644 --- a/libdnf5/utils/dnf4convert/dnf4convert.hpp +++ b/libdnf5/utils/dnf4convert/dnf4convert.hpp @@ -37,10 +37,12 @@ class Dnf4Convert { public: Dnf4Convert(const libdnf5::BaseWeakPtr & base) : base(base) {} +#ifdef WITH_MODULEMD /// Reads modules state from ini files in dnf4 format /// @param path Path where module configuration is stored (e.g. /etc/dnf/modules.c) /// @return The map {module_name -> ModuleState object} std::map read_module_states(); +#endif /// Reads installed packages, groups and environments from dnf4 history database. /// The state is then stored in parameters. diff --git a/test/libdnf5/module/test_module.cpp b/test/libdnf5/module/test_module.cpp index b7e628ed0..853885a6f 100644 --- a/test/libdnf5/module/test_module.cpp +++ b/test/libdnf5/module/test_module.cpp @@ -17,6 +17,8 @@ You should have received a copy of the GNU General Public License along with libdnf. If not, see . */ +#ifdef WITH_MODULEMD + #include "test_module.hpp" @@ -860,3 +862,5 @@ void ModuleTest::test_module_globs() { std::sort(active_module_specs.begin(), active_module_specs.end()); CPPUNIT_ASSERT_EQUAL(expected_active_module_specs, active_module_specs); } + +#endif // WITH_MODULEMD diff --git a/test/libdnf5/module/test_module.hpp b/test/libdnf5/module/test_module.hpp index 1fc026c93..b2d563e8a 100644 --- a/test/libdnf5/module/test_module.hpp +++ b/test/libdnf5/module/test_module.hpp @@ -17,6 +17,8 @@ You should have received a copy of the GNU General Public License along with libdnf. If not, see . */ +#ifdef WITH_MODULEMD + #ifndef LIBDNF5_TEST_MODULE_HPP #define LIBDNF5_TEST_MODULE_HPP @@ -65,3 +67,5 @@ class ModuleTest : public BaseTestCase { }; #endif + +#endif // WITH_MODULEMD diff --git a/test/libdnf5/system/test_state.cpp b/test/libdnf5/system/test_state.cpp index 8b3ce6182..67494f3fd 100644 --- a/test/libdnf5/system/test_state.cpp +++ b/test/libdnf5/system/test_state.cpp @@ -131,6 +131,7 @@ void StateTest::test_state_read() { .userinstalled = false, .packages = {"pkg1", "pkg2"}, .package_types = libdnf5::comps::PackageType::MANDATORY}; CPPUNIT_ASSERT_EQUAL(grp_state_2, state.get_group_state("group-2")); +#ifdef WITH_MODULEMD libdnf5::system::ModuleState module_state_1{ .enabled_stream = "stream-1", .status = libdnf5::module::ModuleStatus::ENABLED, @@ -139,6 +140,7 @@ void StateTest::test_state_read() { libdnf5::system::ModuleState module_state_2{ .enabled_stream = "stream-2", .status = libdnf5::module::ModuleStatus::DISABLED}; CPPUNIT_ASSERT_EQUAL(module_state_2, state.get_module_state("module-2")); +#endif CPPUNIT_ASSERT_EQUAL(std::string("foo"), state.get_rpmdb_cookie()); } @@ -166,6 +168,7 @@ void StateTest::test_state_write() { .packages = {"pkg1", "pkg2"}, .package_types = libdnf5::comps::PackageType::MANDATORY}); +#ifdef WITH_MODULEMD state.set_module_state( "module-1", {.enabled_stream = "stream-1", @@ -173,6 +176,7 @@ void StateTest::test_state_write() { .installed_profiles = {"zigg", "zagg"}}); state.set_module_state( "module-2", {.enabled_stream = "stream-2", .status = libdnf5::module::ModuleStatus::DISABLED}); +#endif state.set_rpmdb_cookie("foo"); @@ -181,14 +185,18 @@ void StateTest::test_state_write() { CPPUNIT_ASSERT_EQUAL(packages_contents, trim(libdnf5::utils::fs::File(path / "packages.toml", "r").read())); CPPUNIT_ASSERT_EQUAL(nevras_contents, trim(libdnf5::utils::fs::File(path / "nevras.toml", "r").read())); CPPUNIT_ASSERT_EQUAL(groups_contents, trim(libdnf5::utils::fs::File(path / "groups.toml", "r").read())); +#ifdef WITH_MODULEMD CPPUNIT_ASSERT_EQUAL(modules_contents, trim(libdnf5::utils::fs::File(path / "modules.toml", "r").read())); +#endif CPPUNIT_ASSERT_EQUAL(system_contents, trim(libdnf5::utils::fs::File(path / "system.toml", "r").read())); // Test removes state.remove_package_na_state("pkg.x86_64"); state.remove_package_nevra_state("pkg-1.2-1.x86_64"); state.remove_group_state("group-1"); +#ifdef WITH_MODULEMD state.remove_module_state("module-1"); +#endif state.save(); @@ -222,6 +230,7 @@ userinstalled = false CPPUNIT_ASSERT_EQUAL( groups_contents_after_remove, trim(libdnf5::utils::fs::File(path / "groups.toml", "r").read())); +#ifdef WITH_MODULEMD const std::string modules_contents_after_remove{R"""(version = "1.0" [modules] module-2 = {enabled_stream="stream-2",installed_profiles=[],state="Disabled"} @@ -229,4 +238,5 @@ module-2 = {enabled_stream="stream-2",installed_profiles=[],state="Disabled"} CPPUNIT_ASSERT_EQUAL( modules_contents_after_remove, trim(libdnf5::utils::fs::File(path / "modules.toml", "r").read())); +#endif } diff --git a/test/shared/utils.hpp b/test/shared/utils.hpp index d81bb8d7b..f473d1b24 100644 --- a/test/shared/utils.hpp +++ b/test/shared/utils.hpp @@ -259,6 +259,7 @@ struct assertion_traits { } }; +#ifdef WITH_MODULEMD template <> struct assertion_traits { inline static bool equal(const libdnf5::system::ModuleState & left, const libdnf5::system::ModuleState & right) { @@ -274,6 +275,7 @@ struct assertion_traits { assertion_traits>::toString(module_state.installed_profiles)); } }; +#endif } // namespace CPPUNIT_NS