Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package libdnf for openSUSE:Factory checked 
in at 2021-11-06 18:13:19
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/libdnf (Old)
 and      /work/SRC/openSUSE:Factory/.libdnf.new.1890 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "libdnf"

Sat Nov  6 18:13:19 2021 rev:27 rq:929010 version:0.65.0

Changes:
--------
--- /work/SRC/openSUSE:Factory/libdnf/libdnf.changes    2021-08-31 
19:55:05.629907559 +0200
+++ /work/SRC/openSUSE:Factory/.libdnf.new.1890/libdnf.changes  2021-11-06 
18:13:35.516746005 +0100
@@ -1,0 +2,12 @@
+Wed Nov  3 11:11:08 UTC 2021 - Neal Gompa <ngomp...@gmail.com>
+
+- Update to 0.65.0
+  + Add support for excluding packages to be installed as weak dependencies
+  + Add support for autodetecting packages to be excluded from being installed 
as weak dependencies
+  + Turn off strict validation of modulemd documents (rh#2004853, rh#2007166, 
rh#2007167)
+  + Implement logic for demodularization of modular rpms (rh#1805260)
+  + DnfContext: fix handling of default module profiles
+  + ModuleMetadata: gracefully handle modules with no defaults
+  + Remove failovermethod config option (rh#1961083)
+
+-------------------------------------------------------------------

Old:
----
  libdnf-0.63.1.tar.gz

New:
----
  libdnf-0.65.0.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ libdnf.spec ++++++
--- /var/tmp/diff_new_pack.TZot2J/_old  2021-11-06 18:13:37.604747099 +0100
+++ /var/tmp/diff_new_pack.TZot2J/_new  2021-11-06 18:13:37.604747099 +0100
@@ -2,7 +2,7 @@
 # spec file for package libdnf
 #
 # Copyright (c) 2019 SUSE LINUX GmbH, Nuernberg, Germany.
-# Copyright (c) 2020-2021 Neal Gompa <ngomp...@gmail.com>.
+# Copyright (c) 2021 Neal Gompa <ngomp...@gmail.com>.
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -17,9 +17,9 @@
 #
 
 
-%global libsolv_version 0.7.17
-%global libmodulemd_version 2.12.0
-%global librepo_version 1.13.0
+%global libsolv_version 0.7.20
+%global libmodulemd_version 2.13.0
+%global librepo_version 1.13.1
 %global dnf_conflict 4.3.0
 %global swig_version 3.0.12
 
@@ -34,7 +34,7 @@
 %define devname %{name}-devel
 
 Name:           libdnf
-Version:        0.63.1
+Version:        0.65.0
 Release:        0
 Summary:        Library providing C and Python APIs atop libsolv
 License:        LGPL-2.1-or-later

++++++ libdnf-0.63.1.tar.gz -> libdnf-0.65.0.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libdnf-0.63.1/VERSION.cmake 
new/libdnf-0.65.0/VERSION.cmake
--- old/libdnf-0.63.1/VERSION.cmake     2021-06-14 15:09:48.000000000 +0200
+++ new/libdnf-0.65.0/VERSION.cmake     2021-10-21 08:19:17.000000000 +0200
@@ -1,6 +1,6 @@
 set (DEFAULT_LIBDNF_MAJOR_VERSION 0)
-set (DEFAULT_LIBDNF_MINOR_VERSION 63)
-set (DEFAULT_LIBDNF_MICRO_VERSION 1)
+set (DEFAULT_LIBDNF_MINOR_VERSION 65)
+set (DEFAULT_LIBDNF_MICRO_VERSION 0)
 
 if(DEFINED LIBDNF_MAJOR_VERSION)
   if(NOT ${DEFAULT_LIBDNF_MAJOR_VERSION} STREQUAL ${LIBDNF_MAJOR_VERSION})
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libdnf-0.63.1/docs/release_notes.rst 
new/libdnf-0.65.0/docs/release_notes.rst
--- old/libdnf-0.63.1/docs/release_notes.rst    2021-06-14 15:09:48.000000000 
+0200
+++ new/libdnf-0.65.0/docs/release_notes.rst    2021-10-21 08:19:17.000000000 
+0200
@@ -20,6 +20,37 @@
 ######################
 
 ====================
+0.65.0 Release Notes
+====================
+
+- New features:
+  - Add support for excluding packages to be installed as weak dependencies
+  - Add support for autodetecting packages to be excluded from being installed 
as weak dependencies
+
+- Bug fixes:
+  - Turn off strict validation of modulemd documents 
(RhBug:2004853,2007166,2007167)
+
+Bugs fixed in 0.65.0:
+
+* :rhbug:`2004853`
+* :rhbug:`2007166`
+* :rhbug:`2007167`
+
+====================
+0.64.0 Release Notes
+====================
+
+- Implement logic for demodularization of modular rpms (RhBug:1805260)
+- DnfContext: fix handling of default module profiles
+- ModuleMetadata: gracefully handle modules with no defaults
+- Remove failovermethod config option (RhBug:1961083)
+
+Bugs fixed in 0.64.0:
+
+* :rhbug:`1961083`
+* :rhbug:`1805260`
+
+====================
 0.63.1 Release Notes
 ====================
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libdnf-0.63.1/libdnf/conf/ConfigMain.cpp 
new/libdnf-0.65.0/libdnf/conf/ConfigMain.cpp
--- old/libdnf-0.63.1/libdnf/conf/ConfigMain.cpp        2021-06-14 
15:09:48.000000000 +0200
+++ new/libdnf-0.65.0/libdnf/conf/ConfigMain.cpp        2021-10-21 
08:19:17.000000000 +0200
@@ -298,6 +298,8 @@
     OptionBool fastestmirror{false};
     OptionStringList excludepkgs{std::vector<std::string>{}};
     OptionStringList includepkgs{std::vector<std::string>{}};
+    OptionStringList exclude_from_weak{std::vector<std::string>{}};
+    OptionBool exclude_from_weak_autodetect{true};
     OptionString proxy{""};
     OptionString proxy_username{nullptr};
     OptionString proxy_password{nullptr};
@@ -475,7 +477,13 @@
             optionTListAppend(includepkgs, priority, value);
         }, nullptr, true
     );
+    owner.optBinds().add("exclude_from_weak", exclude_from_weak,
+        [&](Option::Priority priority, const std::string & value){
+            optionTListAppend(exclude_from_weak, priority, value);
+        }, nullptr, true
+    );
 
+    owner.optBinds().add("exclude_from_weak_autodetect", 
exclude_from_weak_autodetect);
     owner.optBinds().add("proxy", proxy);
     owner.optBinds().add("proxy_username", proxy_username);
     owner.optBinds().add("proxy_password", proxy_password);
@@ -601,6 +609,8 @@
 OptionBool & ConfigMain::fastestmirror() { return pImpl->fastestmirror; }
 OptionStringList & ConfigMain::excludepkgs() { return pImpl->excludepkgs; }
 OptionStringList & ConfigMain::includepkgs() { return pImpl->includepkgs; }
+OptionStringList & ConfigMain::exclude_from_weak() { return 
pImpl->exclude_from_weak; }
+OptionBool & ConfigMain::exclude_from_weak_autodetect() { return 
pImpl->exclude_from_weak_autodetect; }
 OptionString & ConfigMain::proxy() { return pImpl->proxy; }
 OptionString & ConfigMain::proxy_username() { return pImpl->proxy_username; }
 OptionString & ConfigMain::proxy_password() { return pImpl->proxy_password; }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libdnf-0.63.1/libdnf/conf/ConfigMain.hpp 
new/libdnf-0.65.0/libdnf/conf/ConfigMain.hpp
--- old/libdnf-0.63.1/libdnf/conf/ConfigMain.hpp        2021-06-14 
15:09:48.000000000 +0200
+++ new/libdnf-0.65.0/libdnf/conf/ConfigMain.hpp        2021-10-21 
08:19:17.000000000 +0200
@@ -137,6 +137,8 @@
     OptionBool & fastestmirror();
     OptionStringList & excludepkgs();
     OptionStringList & includepkgs();
+    OptionStringList & exclude_from_weak();
+    OptionBool & exclude_from_weak_autodetect();
     OptionString & proxy();
     OptionString & proxy_username();
     OptionString & proxy_password();
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libdnf-0.63.1/libdnf/conf/ConfigRepo.cpp 
new/libdnf-0.65.0/libdnf/conf/ConfigRepo.cpp
--- old/libdnf-0.63.1/libdnf/conf/ConfigRepo.cpp        2021-06-14 
15:09:48.000000000 +0200
+++ new/libdnf-0.65.0/libdnf/conf/ConfigRepo.cpp        2021-10-21 
08:19:17.000000000 +0200
@@ -79,7 +79,6 @@
     OptionString enabled_metadata{""};
     OptionChild<OptionString> user_agent{mainConfig.user_agent()};
     OptionChild<OptionBool> countme{mainConfig.countme()};
-    OptionEnum<std::string> failovermethod{"priority", {"priority", 
"roundrobin"}};
     OptionChild<OptionBool> sslverifystatus{mainConfig.sslverifystatus()};
 };
 
@@ -230,7 +229,6 @@
 OptionString & ConfigRepo::enabled_metadata() { return 
pImpl->enabled_metadata; }
 OptionChild<OptionString> & ConfigRepo::user_agent() { return 
pImpl->user_agent; }
 OptionChild<OptionBool> & ConfigRepo::countme() { return pImpl->countme; }
-OptionEnum<std::string> & ConfigRepo::failovermethod() { return 
pImpl->failovermethod; }
 OptionChild<OptionBool> & ConfigRepo::sslverifystatus() { return 
pImpl->sslverifystatus; }
 
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libdnf-0.63.1/libdnf/conf/ConfigRepo.hpp 
new/libdnf-0.65.0/libdnf/conf/ConfigRepo.hpp
--- old/libdnf-0.63.1/libdnf/conf/ConfigRepo.hpp        2021-06-14 
15:09:48.000000000 +0200
+++ new/libdnf-0.65.0/libdnf/conf/ConfigRepo.hpp        2021-10-21 
08:19:17.000000000 +0200
@@ -95,7 +95,6 @@
     OptionChild<OptionString> & user_agent();
     OptionChild<OptionBool> & countme();
     // yum compatibility options
-    OptionEnum<std::string> & failovermethod();
     OptionChild<OptionBool> & sslverifystatus();
 
 private:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libdnf-0.63.1/libdnf/config.h 
new/libdnf-0.65.0/libdnf/config.h
--- old/libdnf-0.63.1/libdnf/config.h   2021-06-14 15:09:48.000000000 +0200
+++ new/libdnf-0.65.0/libdnf/config.h   2021-10-21 08:19:17.000000000 +0200
@@ -18,16 +18,12 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
-#ifdef __APPLE__
-#include <stdint.h>
-#else
-#include <bits/wordsize.h>
-#endif
+#include <limits.h>
 
-#if __WORDSIZE == 32
-#include "config-32.h"
-#elif __WORDSIZE == 64
+#if (ULONG_MAX == 0xffffffffffffffff)
 #include "config-64.h"
+#elif (ULONG_MAX == 0xffffffff)
+#include "config-32.h"
 #else
 #error "Unknown word size"
 #endif
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libdnf-0.63.1/libdnf/dnf-context.cpp 
new/libdnf-0.65.0/libdnf/dnf-context.cpp
--- old/libdnf-0.63.1/libdnf/dnf-context.cpp    2021-06-14 15:09:48.000000000 
+0200
+++ new/libdnf-0.65.0/libdnf/dnf-context.cpp    2021-10-21 08:19:17.000000000 
+0200
@@ -3075,6 +3075,10 @@
     return ret;
 }
 
+/* This is subtly different from the C++ version above: it passes NULL as the
+ * modular container to `dnf_sack_filter_modules_v2` which has the effect of
+ * throwing away all transient modular changes and reloading from disk. This is
+ * used by dnf_context_reset_all_modules(). */
 static gboolean
 recompute_modular_filtering(DnfContext * context, DnfSack * sack, GError ** 
error)
 {
@@ -3098,6 +3102,7 @@
     return TRUE;
 }
 
+/* See header docstring; you likely want dnf_context_module_reset instead. */
 gboolean
 dnf_context_reset_modules(DnfContext * context, DnfSack * sack, const char ** 
module_names, GError ** error) try
 {
@@ -3525,7 +3530,15 @@
                             throw std::runtime_error(tfm::format(_("No profile 
found matching '%s'"), nsvcap_obj->getProfile().c_str()));
                         }
                     } else {
-                        profiles.push_back(latest->getDefaultProfile());
+                        // This queries the distro-level modulemd-defaults.
+                        auto default_profiles = 
container->getDefaultProfiles(latest->getName(), latest->getStream());
+                        for (auto & profileName : default_profiles) {
+                            auto matching = latest->getProfiles(profileName);
+                            profiles.insert(profiles.begin(), 
matching.begin(), matching.end());
+                        }
+                        if (profiles.empty()) {
+                            throw std::runtime_error("No default profile found 
for " + latest->getFullIdentifier());
+                        }
                     }
 
                     g_autoptr(GPtrArray) pkgnames = 
g_ptr_array_new_with_free_func (g_free);
@@ -3665,6 +3678,59 @@
 } CATCH_TO_GERROR(FALSE)
 
 gboolean
+dnf_context_module_disable_all(DnfContext * context, GError ** error) try
+{
+    DnfContextPrivate *priv = GET_PRIVATE (context);
+
+    /* create sack and add sources */
+    if (priv->sack == nullptr) {
+        dnf_state_reset (priv->state);
+        if (!dnf_context_setup_sack(context, priv->state, error)) {
+            return FALSE;
+        }
+    }
+
+    DnfSack * sack = priv->sack;
+    auto container = dnf_sack_get_module_container(sack);
+    if (!container) {
+        return TRUE;
+    }
+
+    auto all_modules = container->getModulePackages();
+    for (auto & module: all_modules) {
+        container->disable(module->getName());
+    }
+
+    std::vector<const char *> hotfixRepos;
+    // don't filter RPMs from repos with the 'module_hotfixes' flag set
+    for (unsigned int i = 0; i < priv->repos->len; i++) {
+        auto repo = static_cast<DnfRepo *>(g_ptr_array_index(priv->repos, i));
+        if (dnf_repo_get_module_hotfixes(repo)) {
+            hotfixRepos.push_back(dnf_repo_get_id(repo));
+        }
+    }
+    hotfixRepos.push_back(nullptr);
+
+    std::vector<std::tuple<libdnf::ModulePackageContainer::ModuleErrorType, 
std::string, std::string>> messages;
+    auto solver_error = recompute_modular_filtering(container, sack, 
hotfixRepos);
+    if (!solver_error.empty()) {
+        messages.insert(
+            messages.end(),std::make_move_iterator(solver_error.begin()), 
std::make_move_iterator(solver_error.end()));
+    }
+
+    auto errors = report_problems(messages);
+    if (!errors.empty()) {
+        std::string final_errmsg (_("Problems appeared for module disable 
request:"));
+        for (const auto &errmsg : errors) {
+            final_errmsg += "\n  - " + errmsg;
+        }
+        g_set_error_literal(error, DNF_ERROR, DNF_ERROR_FAILED, 
final_errmsg.c_str());
+        return FALSE;
+    }
+    return TRUE;
+} CATCH_TO_GERROR(FALSE)
+
+gboolean
 dnf_context_module_reset(DnfContext * context, const char ** module_specs, 
GError ** error) try
 {
     return context_modules_reset_or_disable(context, module_specs, error, 
true);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libdnf-0.63.1/libdnf/dnf-context.h 
new/libdnf-0.65.0/libdnf/dnf-context.h
--- old/libdnf-0.63.1/libdnf/dnf-context.h      2021-06-14 15:09:48.000000000 
+0200
+++ new/libdnf-0.65.0/libdnf/dnf-context.h      2021-10-21 08:19:17.000000000 
+0200
@@ -280,13 +280,41 @@
                                                          DnfPluginError 
*error);
 /// String must be dealocated by g_free()
 gchar *          dnf_context_get_module_report          (DnfContext * context);
+
+/**
+ * dnf_context_reset_modules:
+ * @context: DnfContext
+ * @sack: DnfSack
+ * @module_names: Names of modules to reset
+ * @error: Error
+ *
+ * Reset modules, commit modular changes, and recalculate module filtration.
+ * Note you likely want to use dnf_context_module_reset instead which matches
+ * the behaviour of other modular APIs to not commit modular changes to disk
+ * until dnf_context_run(). Returns FALSE when an error is set.
+ *
+ * Since: 0.38.1
+ **/
 gboolean         dnf_context_reset_modules              (DnfContext * context,
                                                          DnfSack * sack,
                                                          const char ** 
module_names,
                                                          GError ** error);
+
+/**
+ * dnf_context_reset_all_modules:
+ * @context: DnfContext
+ * @sack: DnfSack
+ * @error: Error
+ *
+ * Reset all modules and recalculate module filtration.
+ * Returns FALSE when an error is set.
+ *
+ * Since: 0.46.2
+ **/
 gboolean         dnf_context_reset_all_modules          (DnfContext * context,
                                                          DnfSack * sack,
                                                          GError ** error);
+
 /**
  * dnf_context_module_enable:
  * @context: DnfContext
@@ -325,7 +353,7 @@
  * @module_specs: Module specs that should be enabled
  * @error: Error
  *
- * Disable mudules, recalculate module filtration, but do not commit modular 
changes.
+ * Disable modules, recalculate module filtration, but do not commit modular 
changes.
  * To commit modular changes it requires to call dnf_context_run()
  * Returns FALSE when an error is set.
  *
@@ -334,6 +362,22 @@
 gboolean         dnf_context_module_disable             (DnfContext * context,
                                                          const char ** 
module_specs,
                                                          GError ** error);
+
+/**
+ * dnf_context_module_disable_all:
+ * @context: DnfContext
+ * @module_specs: Module specs that should be enabled
+ * @error: Error
+ *
+ * Disable all modules, recalculate module filtration, but do not commit 
modular
+ * changes.  To commit modular changes it requires to call dnf_context_run()
+ * Returns FALSE when an error is set.
+ *
+ * Since: 0.64.0
+ **/
+gboolean         dnf_context_module_disable_all         (DnfContext * context,
+                                                         GError ** error);
+
 /**
  * dnf_context_module_reset:
  * @context: DnfContext
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libdnf-0.63.1/libdnf/dnf-goal.cpp 
new/libdnf-0.65.0/libdnf/dnf-goal.cpp
--- old/libdnf-0.63.1/libdnf/dnf-goal.cpp       2021-06-14 15:09:48.000000000 
+0200
+++ new/libdnf-0.65.0/libdnf/dnf-goal.cpp       2021-10-21 08:19:17.000000000 
+0200
@@ -48,6 +48,26 @@
 
 #include <vector>
 
+static void set_excludes_from_weak_to_goal(HyGoal goal)
+{
+    DnfSack * sack = hy_goal_get_sack(goal);
+
+    goal->reset_exclude_from_weak();
+
+    const auto & exclude_from_weak_autodetect = 
libdnf::getGlobalMainConfig().exclude_from_weak_autodetect().getValue();
+    if (exclude_from_weak_autodetect) {
+        goal->exclude_from_weak_autodetect();
+    }
+
+    const auto & exclude_from_weak = 
libdnf::getGlobalMainConfig().exclude_from_weak().getValue();
+
+    for (auto & exclude : exclude_from_weak) {
+        libdnf::Query query(sack);
+        auto ret = query.filterSubject(exclude.c_str(), nullptr, false, true, 
false, false);
+        goal->add_exclude_from_weak(*query.getResultPset());
+    }
+}
+
 /**
  * dnf_goal_depsolve:
  * @goal: a #HyGoal.
@@ -80,6 +100,8 @@
     auto pkgset = *query.runSet();
     goal->addProtected(pkgset);
 
+    set_excludes_from_weak_to_goal(goal);
+
     rc = hy_goal_run_flags(goal, flags);
     if (rc) {
         string = g_string_new(_("Could not depsolve transaction; "));
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libdnf-0.63.1/libdnf/dnf-reldep.cpp 
new/libdnf-0.65.0/libdnf/dnf-reldep.cpp
--- old/libdnf-0.63.1/libdnf/dnf-reldep.cpp     2021-06-14 15:09:48.000000000 
+0200
+++ new/libdnf-0.65.0/libdnf/dnf-reldep.cpp     2021-10-21 08:19:17.000000000 
+0200
@@ -60,6 +60,24 @@
     return reldep->getId();
 }
 
+const char *
+dnf_reldep_get_name(DnfReldep * reldep)
+{
+    return reldep->getName();
+}
+
+const char *
+dnf_reldep_get_relation(DnfReldep * reldep)
+{
+    return reldep->getRelation();
+}
+
+const char *
+dnf_reldep_get_version(DnfReldep * reldep)
+{
+    return reldep->getVersion();
+}
+
 void dnf_reldep_free(DnfReldep *reldep)
 {
     delete reldep;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libdnf-0.63.1/libdnf/dnf-reldep.h 
new/libdnf-0.65.0/libdnf/dnf-reldep.h
--- old/libdnf-0.63.1/libdnf/dnf-reldep.h       2021-06-14 15:09:48.000000000 
+0200
+++ new/libdnf-0.65.0/libdnf/dnf-reldep.h       2021-10-21 08:19:17.000000000 
+0200
@@ -31,6 +31,9 @@
 DnfReldep *dnf_reldep_new(DnfSack *sack, const char *name, int cmp_type, const 
char *evr);
 const char *dnf_reldep_to_string(DnfReldep *reldep);
 Id dnf_reldep_get_id(DnfReldep *reldep);
+const char * dnf_reldep_get_name(DnfReldep * reldep);
+const char * dnf_reldep_get_relation(DnfReldep * reldep);
+const char * dnf_reldep_get_version(DnfReldep * reldep);
 void dnf_reldep_free(DnfReldep *reldep);
 
 #ifdef __cplusplus
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libdnf-0.63.1/libdnf/dnf-repo.cpp 
new/libdnf-0.65.0/libdnf/dnf-repo.cpp
--- old/libdnf-0.63.1/libdnf/dnf-repo.cpp       2021-06-14 15:09:48.000000000 
+0200
+++ new/libdnf-0.65.0/libdnf/dnf-repo.cpp       2021-10-21 08:19:17.000000000 
+0200
@@ -1966,9 +1966,12 @@
     g_free(updatedata.last_mirror_failure_message);
     g_free(updatedata.last_mirror_url);
     dnf_state_release_locks(state);
-    lr_handle_setopt(priv->repo_handle, NULL, LRO_PROGRESSCB, NULL);
-    lr_handle_setopt(priv->repo_handle, NULL, LRO_HMFCB, NULL);
-    lr_handle_setopt(priv->repo_handle, NULL, LRO_PROGRESSDATA, 0xdeadbeef);
+    if (!lr_handle_setopt(priv->repo_handle, NULL, LRO_PROGRESSCB, NULL))
+            g_debug("Failed to reset LRO_PROGRESSCB to NULL");
+    if (!lr_handle_setopt(priv->repo_handle, NULL, LRO_HMFCB, NULL))
+            g_debug("Failed to reset LRO_HMFCB to NULL");
+    if (!lr_handle_setopt(priv->repo_handle, NULL, LRO_PROGRESSDATA, 
0xdeadbeef))
+            g_debug("Failed to set LRO_PROGRESSDATA to 0xdeadbeef");
     return ret;
 } CATCH_TO_GERROR(FALSE)
 
@@ -2296,8 +2299,10 @@
 
     ret = TRUE;
 out:
-    lr_handle_setopt(priv->repo_handle, NULL, LRO_PROGRESSCB, NULL);
-    lr_handle_setopt(priv->repo_handle, NULL, LRO_PROGRESSDATA, 0xdeadbeef);
+    if (!lr_handle_setopt(priv->repo_handle, NULL, LRO_PROGRESSCB, NULL))
+            g_debug("Failed to reset LRO_PROGRESSCB to NULL");
+    if (!lr_handle_setopt(priv->repo_handle, NULL, LRO_PROGRESSDATA, 
0xdeadbeef))
+            g_debug("Failed to set LRO_PROGRESSDATA to 0xdeadbeef");
     g_free(global_data.last_mirror_failure_message);
     g_free(global_data.last_mirror_url);
     g_slist_free_full(package_targets, (GDestroyNotify)lr_packagetarget_free);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libdnf-0.63.1/libdnf/dnf-sack.cpp 
new/libdnf-0.65.0/libdnf/dnf-sack.cpp
--- old/libdnf-0.63.1/libdnf/dnf-sack.cpp       2021-06-14 15:09:48.000000000 
+0200
+++ new/libdnf-0.65.0/libdnf/dnf-sack.cpp       2021-10-21 08:19:17.000000000 
+0200
@@ -2308,47 +2308,107 @@
     }
 }
 
-static std::tuple<std::vector<std::string>, std::vector<std::string>>
-collectNevraForInclusionExclusion(libdnf::ModulePackageContainer 
&modulePackageContainer)
+/// @return std::map<name:stream.arch, std::vector<std::string>>
+static std::map<std::string, std::vector<std::string>> getDemodularizedRpms(
+    libdnf::ModulePackageContainer & moduleContainer, const 
std::vector<libdnf::ModulePackage *> & allPackages)
 {
+    std::map<std::string, std::vector<std::string>> ret;
+    auto latest = moduleContainer.getLatestModules(allPackages, true);
+    for (auto modulePackage : latest) {
+        auto demodularized = modulePackage->getDemodularizedRpms();
+        if (demodularized.empty()) {
+            continue;
+        }
+        std::string packageID{modulePackage->getNameStream()};
+        packageID.append(".");
+        packageID.append(modulePackage->getArch());
+        auto & data = ret[packageID];
+        data.insert(data.end(), demodularized.begin(), demodularized.end());
+    }
+    return ret;
+}
+
+/// Return <includeNEVRAs>, <excludeNEVRAs>, <names>, <srcNames>, <name 
dependency container>
+static std::tuple<std::vector<std::string>, std::vector<std::string>, 
std::vector<std::string>, std::vector<std::string>, libdnf::DependencyContainer>
+collectNevraForInclusionExclusion(DnfSack *sack, 
libdnf::ModulePackageContainer &modulePackageContainer)
+{
+    auto allPackages = modulePackageContainer.getModulePackages();
+    auto demodularizedNames = getDemodularizedRpms(modulePackageContainer, 
allPackages);
+
     std::vector<std::string> includeNEVRAs;
     std::vector<std::string> excludeNEVRAs;
+    std::vector<std::string> names;
+    std::vector<std::string> srcNames;
+    libdnf::DependencyContainer nameDependencies{sack};
+    libdnf::Nevra nevra;
     // TODO: turn into std::vector<const char *> to prevent unnecessary 
conversion?
-    for (const auto &module : modulePackageContainer.getModulePackages()) {
+    for (const auto & module : allPackages) {
         auto artifacts = module->getArtifacts();
         // TODO use Goal::listInstalls() to not requires filtering out Platform
         if (modulePackageContainer.isModuleActive(module->getId())) {
+            std::string packageID{module->getNameStream()};
+            packageID.append(".");
+            packageID.append(module->getArch());
+            auto it = demodularizedNames.find(packageID);
+            if (it == demodularizedNames.end()) {
+                for (const auto &rpm : artifacts) {
+                    if (nevra.parse(rpm.c_str(), HY_FORM_NEVRA)) {
+                        auto arch = nevra.getArch();
+                        // source packages do not provide anything and must 
not cause excluding binary packages
+                        if (arch == "src" || arch == "nosrc") {
+                            srcNames.push_back(nevra.getName());
+                        } else {
+                            names.push_back(nevra.getName());
+                            
nameDependencies.addReldep(nevra.getName().c_str());
+                        }
+                    }
+                }
+            } else {
+                for (const auto &rpm : artifacts) {
+                    if (nevra.parse(rpm.c_str(), HY_FORM_NEVRA)) {
+                        bool found = false;
+                        for ( auto & demodularized : it->second) {
+                            if (nevra.getName() == demodularized) {
+                                found = true;
+                                break;
+                            }
+                        }
+                        if (found) {
+                            continue;
+                        }
+                        auto arch = nevra.getArch();
+                        // source packages do not provide anything and must 
not cause excluding binary packages
+                        if (arch == "src" || arch == "nosrc") {
+                            srcNames.push_back(nevra.getName());
+                        } else {
+                            names.push_back(nevra.getName());
+                            
nameDependencies.addReldep(nevra.getName().c_str());
+                        }
+                    }
+                }
+            }
             copy(std::begin(artifacts), std::end(artifacts), 
std::back_inserter(includeNEVRAs));
         } else {
             copy(std::begin(artifacts), std::end(artifacts), 
std::back_inserter(excludeNEVRAs));
         }
     }
 
-    return std::tuple<std::vector<std::string>,
-    std::vector<std::string>>{includeNEVRAs, excludeNEVRAs};
+    return std::make_tuple(std::move(includeNEVRAs), std::move(excludeNEVRAs), 
std::move(names), std::move(srcNames),
+                           std::move(nameDependencies));
 }
 
-static void
-setModuleExcludes(DnfSack *sack, const char ** hotfixRepos,
-    const std::vector<std::string> &includeNEVRAs, const 
std::vector<std::string> &excludeNEVRAs)
+void
+setModuleExcludes(DnfSack * sack, const char ** hotfixRepos, 
libdnf::ModulePackageContainer & modulePackageContainer)
 {
     dnf_sack_set_module_excludes(sack, nullptr);
-    std::vector<std::string> names;
-    std::vector<std::string> srcNames;
-    libdnf::DependencyContainer nameDependencies{sack};
-    libdnf::Nevra nevra;
-    for (const auto &rpm : includeNEVRAs) {
-        if (nevra.parse(rpm.c_str(), HY_FORM_NEVRA)) {
-            auto arch = nevra.getArch();
-            // source packages do not provide anything and must not cause 
excluding binary packages
-            if (arch == "src" || arch == "nosrc") {
-                srcNames.push_back(nevra.getName());
-            } else {
-                names.push_back(nevra.getName());
-                nameDependencies.addReldep(nevra.getName().c_str());
-            }
-        }
-    }
+
+    auto data = collectNevraForInclusionExclusion(sack, 
modulePackageContainer);
+
+    auto & includeNEVRAs = std::get<0>(data);
+    auto & excludeNEVRAs = std::get<1>(data);
+    auto & names = std::get<2>(data);
+    auto & srcNames = std::get<3>(data);
+    auto & nameDependencies = std::get<4>(data);
 
     std::vector<const char *> namesCString(names.size() + 1);
     std::vector<const char *> srcNamesCString(srcNames.size() + 1);
@@ -2471,9 +2531,8 @@
         moduleContainer->applyObsoletes();
     }
     auto ret = moduleContainer->resolveActiveModulePackages(debugSolver);
-    auto nevraTuple = collectNevraForInclusionExclusion(*moduleContainer);
 
-    setModuleExcludes(sack, hotfixRepos, std::get<0>(nevraTuple), 
std::get<1>(nevraTuple));
+    setModuleExcludes(sack, hotfixRepos, *moduleContainer);
     return ret;
 }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libdnf-0.63.1/libdnf/dnf-transaction.cpp 
new/libdnf-0.65.0/libdnf/dnf-transaction.cpp
--- old/libdnf-0.63.1/libdnf/dnf-transaction.cpp        2021-06-14 
15:09:48.000000000 +0200
+++ new/libdnf-0.65.0/libdnf/dnf-transaction.cpp        2021-10-21 
08:19:17.000000000 +0200
@@ -1523,8 +1523,6 @@
 
     /* this section done */
     ret = dnf_state_done(state, error);
-    if (!ret)
-        goto out;
 out:
     dnf_transaction_reset(transaction);
     dnf_state_release_locks(state);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libdnf-0.63.1/libdnf/goal/Goal-private.hpp 
new/libdnf-0.65.0/libdnf/goal/Goal-private.hpp
--- old/libdnf-0.63.1/libdnf/goal/Goal-private.hpp      2021-06-14 
15:09:48.000000000 +0200
+++ new/libdnf-0.65.0/libdnf/goal/Goal-private.hpp      2021-10-21 
08:19:17.000000000 +0200
@@ -23,6 +23,7 @@
 
 #include "Goal.hpp"
 #include "IdQueue.hpp"
+#include "../sack/packageset.hpp"
 
 namespace libdnf {
 
@@ -37,6 +38,7 @@
 
     DnfSack *sack;
     Queue staging;
+    PackageSet exclude_from_weak;
     Solver *solv{nullptr};
     ::Transaction *trans{nullptr};
     DnfGoalActions actions{DNF_NONE};
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libdnf-0.63.1/libdnf/goal/Goal.cpp 
new/libdnf-0.65.0/libdnf/goal/Goal.cpp
--- old/libdnf-0.63.1/libdnf/goal/Goal.cpp      2021-06-14 15:09:48.000000000 
+0200
+++ new/libdnf-0.65.0/libdnf/goal/Goal.cpp      2021-10-21 08:19:17.000000000 
+0200
@@ -635,7 +635,7 @@
 Goal::Goal(const Goal & goal_src) : pImpl(new Impl(*goal_src.pImpl)) {}
 
 Goal::Impl::Impl(const Goal::Impl & goal_src)
-: sack(goal_src.sack)
+: sack(goal_src.sack), exclude_from_weak(goal_src.exclude_from_weak)
 {
     queue_init_clone(&staging, const_cast<Queue *>(&goal_src.staging));
 
@@ -649,7 +649,7 @@
 }
 
 Goal::Impl::Impl(DnfSack *sack)
-: sack(sack)
+: sack(sack), exclude_from_weak(sack)
 {
     queue_init(&staging);
 }
@@ -794,6 +794,92 @@
 }
 
 void
+Goal::add_exclude_from_weak(const DnfPackageSet & pset)
+{
+    pImpl->exclude_from_weak += pset;
+}
+
+void
+Goal::add_exclude_from_weak(DnfPackage *pkg)
+{
+    // ensure that the map has a corrent size before set to prevent memory 
corruption
+    map_grow(pImpl->exclude_from_weak.getMap(), 
dnf_sack_get_pool(pImpl->sack)->nsolvables);
+    pImpl->exclude_from_weak.set(pkg);
+}
+
+void
+Goal::reset_exclude_from_weak()
+{
+    pImpl->exclude_from_weak.clear();
+}
+
+void
+Goal::exclude_from_weak_autodetect()
+{
+    Query installed_query(pImpl->sack, Query::ExcludeFlags::IGNORE_EXCLUDES);
+    installed_query.installed();
+    if (installed_query.empty()) {
+        return;
+    }
+    Query base_query(pImpl->sack);
+    base_query.apply();
+    auto * installed_pset = installed_query.getResultPset();
+    Id installed_id = -1;
+
+    std::vector<const char *> installed_names;
+    installed_names.reserve(installed_pset->size() + 1);
+
+    // Iterate over installed packages to detect unmet weak deps
+    while ((installed_id = installed_pset->next(installed_id)) != -1) {
+        g_autoptr(DnfPackage) pkg = dnf_package_new(pImpl->sack, installed_id);
+        installed_names.push_back(dnf_package_get_name(pkg));
+        std::unique_ptr<libdnf::DependencyContainer> 
recommends(dnf_package_get_recommends(pkg));
+        for (int i = 0; i < recommends->count(); ++i) {
+            Query query(base_query);
+            std::unique_ptr<libdnf::Dependency> dep(recommends->getPtr(i));
+            const char * version = dep->getVersion();
+            //  There can be installed provider in different version or 
upgraded packed can recommend a different version
+            //  Ignore version and search only by reldep name
+            if (version && strlen(version) > 0) {
+                query.addFilter(HY_PKG_PROVIDES, HY_EQ, dep->getName());
+            } else {
+                query.addFilter(HY_PKG_PROVIDES, dep.get());
+            }
+            // No providers of recommend => continue
+            if (query.empty()) {
+                continue;
+            }
+            Query test_installed(query);
+            test_installed.installed();
+            // when there is not installed any provider of recommend, exclude 
it
+            if (test_installed.empty()) {
+                add_exclude_from_weak(*query.getResultPset());
+            }
+        }
+    }
+
+    // Invesigate supplements of only available packages with a different name 
to installed packages
+    installed_names.push_back(nullptr);
+    base_query.addFilter(HY_PKG_NAME, HY_NEQ, installed_names.data());
+    auto * available_pset = base_query.getResultPset();
+    *available_pset -= *installed_pset;
+    Id available_id = -1;
+    while ((available_id = available_pset->next(available_id)) != -1) {
+        g_autoptr(DnfPackage) pkg = dnf_package_new(pImpl->sack, available_id);
+        std::unique_ptr<libdnf::DependencyContainer> 
supplements(dnf_package_get_supplements(pkg));
+        if (supplements->count() == 0) {
+            continue;
+        }
+        Query query(installed_query);
+        query.addFilter(HY_PKG_PROVIDES, supplements.get());
+        // When supplemented package already installed, exclude_from_weak 
available package
+        if (!query.empty()) {
+            add_exclude_from_weak(pkg);
+        }
+    }
+}
+
+void
 Goal::disfavor(DnfPackage *pkg)
 {
     queue_push2(&pImpl->staging, SOLVER_SOLVABLE|SOLVER_DISFAVOR, 
dnf_package_get_id(pkg));
@@ -1261,6 +1347,12 @@
             elements[i] |= SOLVER_FORCEBEST;
     }
 
+    // Add weak excludes to the job
+    Id id = -1;
+    while ((id = exclude_from_weak.next(id)) != -1) {
+        job->pushBack(SOLVER_SOLVABLE|SOLVER_EXCLUDEFROMWEAK, id);
+    }
+
     /* turn off implicit obsoletes for installonly packages */
     for (int i = 0; i < (int) dnf_sack_get_installonly(sack)->count; i++)
         job->pushBack(SOLVER_MULTIVERSION|SOLVER_SOLVABLE_PROVIDES,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libdnf-0.63.1/libdnf/goal/Goal.hpp 
new/libdnf-0.65.0/libdnf/goal/Goal.hpp
--- old/libdnf-0.63.1/libdnf/goal/Goal.hpp      2021-06-14 15:09:48.000000000 
+0200
+++ new/libdnf-0.65.0/libdnf/goal/Goal.hpp      2021-10-21 08:19:17.000000000 
+0200
@@ -76,6 +76,10 @@
     void install(DnfPackage *new_pkg, bool optional);
     void lock(DnfPackage *new_pkg);
     void favor(DnfPackage *new_pkg);
+    void add_exclude_from_weak(const DnfPackageSet & pset);
+    void add_exclude_from_weak(DnfPackage *pkg);
+    void reset_exclude_from_weak();
+    void exclude_from_weak_autodetect();
     void disfavor(DnfPackage *new_pkg);
 
     /**
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libdnf-0.63.1/libdnf/module/ModulePackage.cpp 
new/libdnf-0.65.0/libdnf/module/ModulePackage.cpp
--- old/libdnf-0.63.1/libdnf/module/ModulePackage.cpp   2021-06-14 
15:09:48.000000000 +0200
+++ new/libdnf-0.65.0/libdnf/module/ModulePackage.cpp   2021-10-21 
08:19:17.000000000 +0200
@@ -418,6 +418,24 @@
     return result_rpms;
 }
 
+/**
+ * @brief Return sorted list of RPM names that are demodularized.
+ *
+ * @return std::vector<std::string>
+ */
+std::vector<std::string> ModulePackage::getDemodularizedRpms() const
+{
+    std::vector<std::string> result_rpms;
+    char ** rpms = 
modulemd_module_stream_v2_get_demodularized_rpms((ModulemdModuleStreamV2 *) 
mdStream);
+
+    for (char **iter = rpms; iter && *iter; iter++) {
+        result_rpms.emplace_back(std::string(*iter));
+    }
+
+    g_strfreev(rpms);
+    return result_rpms;
+}
+
 std::vector<ModuleProfile>
 ModulePackage::getProfiles(const std::string &name) const
 {
@@ -442,6 +460,19 @@
     return result_profiles;
 }
 
+/* @brief Return default profiles as defined in the modulemd itself.
+ *
+ * Note this is probably not the function you want. You likely want to use
+ * ModulePackageContainer::getDefaultProfiles() instead, which sources the
+ * distro-level modulemd-defaults.
+ *
+ * Also, this function returns the first default profile, but instead we want 
it
+ * to return all default profiles. So supporting this properly in the future
+ * would require a new ModulePackage::getDefaultProfiles() which returns an
+ * std::vec<ModuleProfile> instead.
+ *
+ * @return ModuleProfile
+ */
 ModuleProfile
 ModulePackage::getDefaultProfile() const
 {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libdnf-0.63.1/libdnf/module/ModulePackage.hpp 
new/libdnf-0.65.0/libdnf/module/ModulePackage.hpp
--- old/libdnf-0.63.1/libdnf/module/ModulePackage.hpp   2021-06-14 
15:09:48.000000000 +0200
+++ new/libdnf-0.65.0/libdnf/module/ModulePackage.hpp   2021-10-21 
08:19:17.000000000 +0200
@@ -59,6 +59,10 @@
     std::string getDescription() const;
 
     std::vector<std::string> getArtifacts() const;
+
+    /// Return sorted list of RPM names that are demodularized.
+    std::vector<std::string> getDemodularizedRpms() const;
+
     bool operator==(const ModulePackage &r) const;
     /**
     * @brief Return profiles matched by name (which is possibly a globby 
pattern).
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/libdnf-0.63.1/libdnf/module/ModulePackageContainer.cpp 
new/libdnf-0.65.0/libdnf/module/ModulePackageContainer.cpp
--- old/libdnf-0.63.1/libdnf/module/ModulePackageContainer.cpp  2021-06-14 
15:09:48.000000000 +0200
+++ new/libdnf-0.65.0/libdnf/module/ModulePackageContainer.cpp  2021-10-21 
08:19:17.000000000 +0200
@@ -859,7 +859,7 @@
             if (!latest) {
                 latest = module;
             } else {
-                if (module->getVersion() > latest->getVersion()) {
+                if (module->getVersionNum() > latest->getVersionNum()) {
                     latest = module;
                 }
             }
@@ -1051,13 +1051,15 @@
     if (modulePackages.empty()) {
         return {};
     }
-    auto & packageFirst = modulePackages[0];
+
     std::vector<std::vector<std::vector<ModulePackage *>>> output;
     auto sack = pImpl->moduleSack;
     std::sort(modulePackages.begin(), modulePackages.end(),
               [sack](const ModulePackage * first, const ModulePackage * second)
               {return modulePackageLatestPerRepoSorter(sack, first, second);});
     auto vectorSize = modulePackages.size();
+
+    auto & packageFirst = modulePackages[0];
     output.push_back(
         std::vector<std::vector<ModulePackage *>>{std::vector<ModulePackage *> 
{packageFirst}});
     int repoIndex = 0;
@@ -1099,6 +1101,35 @@
     return output;
 }
 
+std::vector<ModulePackage *>
+ModulePackageContainer::getLatestModules(const std::vector<ModulePackage *> 
modulePackages, bool activeOnly)
+{
+    // Because modular sovables uses as name combination of module 
$name:$stream:$context, we can use to get the lates
+    // Query
+    std::vector<ModulePackage *> latestModules;
+    Query query(pImpl->moduleSack, Query::ExcludeFlags::IGNORE_EXCLUDES);
+    if (activeOnly) {
+        // When no active module return
+        if (!pImpl->activatedModules) {
+            return latestModules;
+        }
+        query.addFilter(HY_PKG, HY_EQ, pImpl->activatedModules.get());
+    }
+
+    PackageSet inputModulePackages(pImpl->moduleSack);
+    for (auto modulePackage : modulePackages) {
+        inputModulePackages.set(modulePackage->getId());
+    }
+    query.addFilter(HY_PKG, HY_EQ, &inputModulePackages);
+    query.addFilter(HY_PKG_LATEST_PER_ARCH, HY_EQ, 1);
+    auto set = query.runSet();
+
+    Id moduleId = -1;
+    while ((moduleId = set->next(moduleId)) != -1) {
+        latestModules.push_back(pImpl->modules.at(moduleId).get());
+    }
+    return latestModules;
+}
 
 std::pair<std::vector<std::vector<std::string>>, 
ModulePackageContainer::ModuleErrorType>
 ModulePackageContainer::resolveActiveModulePackages(bool debugSolver)
@@ -1753,8 +1784,6 @@
     if (pImpl->activatedModules) {
         std::vector<ModulePackage *> latest = 
pImpl->getLatestActiveEnabledModules();
 
-        auto begin = fileNames.begin();
-        auto end = fileNames.end();
         if (g_mkdir_with_parents(pImpl->persistDir.c_str(), 0755) == -1) {
             const char * errTxt = strerror(errno);
             auto logger(Log::getLogger());
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/libdnf-0.63.1/libdnf/module/ModulePackageContainer.hpp 
new/libdnf-0.65.0/libdnf/module/ModulePackageContainer.hpp
--- old/libdnf-0.63.1/libdnf/module/ModulePackageContainer.hpp  2021-06-14 
15:09:48.000000000 +0200
+++ new/libdnf-0.65.0/libdnf/module/ModulePackageContainer.hpp  2021-10-21 
08:19:17.000000000 +0200
@@ -134,6 +134,16 @@
     std::vector<ModulePackage *> getModulePackages();
     std::vector<std::vector<std::vector<ModulePackage *>>> 
getLatestModulesPerRepo(
         ModuleState moduleFilter, std::vector<ModulePackage *> modulePackages);
+
+    /**
+    * @brief Return all latest ModulePackages for each module Name, stream, 
context and architecture. In case of
+    * multiple latest packages, all will be returned. When activeOnly is true, 
it returns only the latest active
+    * packages.
+    *
+    * @return std::vector<ModulePackage *>
+    */
+    std::vector<ModulePackage *> getLatestModules(const 
std::vector<ModulePackage *> modulePackages, bool activeOnly);
+
     ModulePackage * getLatestModule(std::vector<ModulePackage *> 
modulePackages, bool activeOnly);
 
     std::vector<ModulePackage *> requiresModuleEnablement(const 
libdnf::PackageSet & packages);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/libdnf-0.63.1/libdnf/module/modulemd/ModuleMetadata.cpp 
new/libdnf-0.65.0/libdnf/module/modulemd/ModuleMetadata.cpp
--- old/libdnf-0.63.1/libdnf/module/modulemd/ModuleMetadata.cpp 2021-06-14 
15:09:48.000000000 +0200
+++ new/libdnf-0.65.0/libdnf/module/modulemd/ModuleMetadata.cpp 2021-10-21 
08:19:17.000000000 +0200
@@ -78,7 +78,7 @@
     g_autoptr(GPtrArray) failures = NULL;
 
     ModulemdModuleIndex * mi = modulemd_module_index_new();
-    gboolean success = modulemd_module_index_update_from_string(mi, 
yaml.c_str(), TRUE, &failures, &error);
+    gboolean success = modulemd_module_index_update_from_string(mi, 
yaml.c_str(), FALSE, &failures, &error);
     if(!success){
         ModuleMetadata::reportFailures(failures);
     }
@@ -181,6 +181,8 @@
 
     ModulemdModule * myModule = 
modulemd_module_index_get_module(resultingModuleIndex, moduleName.c_str());
     ModulemdDefaultsV1 * myDefaults = (ModulemdDefaultsV1 *) 
modulemd_module_get_defaults(myModule);
+    if (!myDefaults)
+        return output;
 
     char ** list = 
modulemd_defaults_v1_get_default_profiles_for_stream_as_strv(myDefaults, 
moduleStream.c_str(), NULL);
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libdnf-0.63.1/libdnf/repo/Repo.cpp 
new/libdnf-0.65.0/libdnf/repo/Repo.cpp
--- old/libdnf-0.63.1/libdnf/repo/Repo.cpp      2021-06-14 15:09:48.000000000 
+0200
+++ new/libdnf-0.65.0/libdnf/repo/Repo.cpp      2021-10-21 08:19:17.000000000 
+0200
@@ -704,7 +704,11 @@
 
     // set GPG home dir
     char tmpdir[] = "/tmp/tmpdir.XXXXXX";
-    mkdtemp(tmpdir);
+    if (!mkdtemp(tmpdir)) {
+        const char * errTxt = strerror(errno);
+        throw RepoError(tfm::format(_("Cannot create repo temporary directory 
\"%s\": %s"),
+                                      tmpdir, errTxt));
+    }
     Finalizer tmpDirRemover([&tmpdir](){
         dnf_remove_recursive(tmpdir, NULL);
     });
@@ -894,8 +898,14 @@
             }
 
             struct stat sb;
-            if (stat(gpgDir.c_str(), &sb) != 0 || !S_ISDIR(sb.st_mode))
-                mkdir(gpgDir.c_str(), 0777);
+            if (stat(gpgDir.c_str(), &sb) != 0 || !S_ISDIR(sb.st_mode)) {
+                int res = mkdir(gpgDir.c_str(), 0777);
+                if (res != 0 && errno != EEXIST) {
+                    auto msg = tfm::format(_("Failed to create directory 
\"%s\": %d - %s"),
+                                           gpgDir, errno, strerror(errno));
+                    throw RepoError(msg);
+                }
+            }
 
             gpgme_ctx_t ctx;
             gpgme_new(&ctx);
@@ -1147,7 +1157,11 @@
 {
     auto logger(Log::getLogger());
     char tmpdir[] = "/tmp/tmpdir.XXXXXX";
-    mkdtemp(tmpdir);
+    if (!mkdtemp(tmpdir)) {
+        const char * errTxt = strerror(errno);
+        throw RepoError(tfm::format(_("Cannot create repo temporary directory 
\"%s\": %s"),
+                                      tmpdir, errTxt));
+    }
     Finalizer tmpDirRemover([&tmpdir](){
         dnf_remove_recursive(tmpdir, NULL);
     });
@@ -1217,7 +1231,11 @@
     auto logger(Log::getLogger());
     LrYumRepo *yum_repo;
     char tmpdir[] = "/tmp/tmpdir.XXXXXX";
-    mkdtemp(tmpdir);
+    if (!mkdtemp(tmpdir)) {
+        const char * errTxt = strerror(errno);
+        throw RepoError(tfm::format(_("Cannot create repo temporary directory 
\"%s\": %s"),
+                                      tmpdir, errTxt));
+    }
     Finalizer tmpDirRemover([&tmpdir](){
         dnf_remove_recursive(tmpdir, NULL);
     });
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/libdnf-0.63.1/libdnf/repo/solvable/DependencyContainer.cpp 
new/libdnf-0.65.0/libdnf/repo/solvable/DependencyContainer.cpp
--- old/libdnf-0.63.1/libdnf/repo/solvable/DependencyContainer.cpp      
2021-06-14 15:09:48.000000000 +0200
+++ new/libdnf-0.65.0/libdnf/repo/solvable/DependencyContainer.cpp      
2021-10-21 08:19:17.000000000 +0200
@@ -32,9 +32,15 @@
 DependencyContainer::DependencyContainer(const DependencyContainer &src)
         : sack(src.sack)
 {
-    queue_init_clone(&this->queue, &queue);
+    queue_init_clone(&queue, &src.queue);
 }
 
+DependencyContainer::DependencyContainer(DependencyContainer &&src)
+        : sack(src.sack)
+{
+    queue_init(&queue);
+    std::swap(queue, src.queue);
+}
 
 DependencyContainer::DependencyContainer(DnfSack *sack)
         : sack(sack)
@@ -57,10 +63,22 @@
     queue_free(&queue);
 }
 
+DependencyContainer &DependencyContainer::operator=(const DependencyContainer 
&src)
+{
+    if (this != &src) {
+        sack = src.sack;
+        queue_free(&queue);
+        queue_init_clone(&queue, &src.queue);
+    }
+    return *this;
+}
+
 DependencyContainer &DependencyContainer::operator=(DependencyContainer &&src) 
noexcept
 {
-    sack = src.sack;
-    queue_init_clone(&queue, &src.queue);
+    if (this != &src) {
+        sack = src.sack;
+        std::swap(queue, src.queue);
+    }
     return *this;
 }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/libdnf-0.63.1/libdnf/repo/solvable/DependencyContainer.hpp 
new/libdnf-0.65.0/libdnf/repo/solvable/DependencyContainer.hpp
--- old/libdnf-0.63.1/libdnf/repo/solvable/DependencyContainer.hpp      
2021-06-14 15:09:48.000000000 +0200
+++ new/libdnf-0.65.0/libdnf/repo/solvable/DependencyContainer.hpp      
2021-10-21 08:19:17.000000000 +0200
@@ -34,11 +34,13 @@
 {
 public:
     DependencyContainer(const DependencyContainer &src);
+    DependencyContainer(DependencyContainer &&src);
     explicit DependencyContainer(DnfSack *sack);
     DependencyContainer(DnfSack *sack, const Queue &queue);
     DependencyContainer(DnfSack *sack, Queue &&queue);
     ~DependencyContainer();
 
+    DependencyContainer &operator=(const DependencyContainer &src);
     DependencyContainer &operator=(DependencyContainer &&src) noexcept;
     bool operator==(const DependencyContainer &r) const;
     bool operator!=(const DependencyContainer &r) const;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libdnf-0.63.1/libdnf/sack/query.hpp 
new/libdnf-0.65.0/libdnf/sack/query.hpp
--- old/libdnf-0.63.1/libdnf/sack/query.hpp     2021-06-14 15:09:48.000000000 
+0200
+++ new/libdnf-0.65.0/libdnf/sack/query.hpp     2021-10-21 08:19:17.000000000 
+0200
@@ -26,6 +26,7 @@
 #include "../hy-types.h"
 #include "../hy-query.h"
 #include "../hy-subject.h"
+#include "../nevra.hpp"
 #include "../repo/solvable/Dependency.hpp"
 #include "../repo/solvable/DependencyContainer.hpp"
 #include "../transaction/Swdb.hpp"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libdnf-0.63.1/libdnf/utils/crypto/sha1.cpp 
new/libdnf-0.65.0/libdnf/utils/crypto/sha1.cpp
--- old/libdnf-0.63.1/libdnf/utils/crypto/sha1.cpp      2021-06-14 
15:09:48.000000000 +0200
+++ new/libdnf-0.65.0/libdnf/utils/crypto/sha1.cpp      2021-10-21 
08:19:17.000000000 +0200
@@ -8,14 +8,15 @@
 
 SHA1Hash::SHA1Hash()
 {
-    SHA1_Init(&ctx);
+    md_ctx = EVP_MD_CTX_new();
+    EVP_DigestInit_ex(md_ctx, EVP_sha1(), NULL);
 }
 
 
 void
 SHA1Hash::update(const char * data)
 {
-    SHA1_Update(&ctx, (unsigned char *)data, strlen(data));
+    EVP_DigestUpdate(md_ctx, data, strlen(data));
 }
 
 
@@ -23,12 +24,13 @@
 SHA1Hash::hexdigest()
 {
     unsigned char md[digestLength];
-    SHA1_Final(md, &ctx);
+    EVP_DigestFinal_ex(md_ctx, md, NULL);
 
     std::stringstream ss;
     for(int i=0; i<digestLength; i++) {
         ss << std::setfill('0') << std::setw(2) << std::hex << 
static_cast<int>(md[i]);
     }
 
+    EVP_MD_CTX_free(md_ctx);
     return ss.str();
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libdnf-0.63.1/libdnf/utils/crypto/sha1.hpp 
new/libdnf-0.65.0/libdnf/utils/crypto/sha1.hpp
--- old/libdnf-0.63.1/libdnf/utils/crypto/sha1.hpp      2021-06-14 
15:09:48.000000000 +0200
+++ new/libdnf-0.65.0/libdnf/utils/crypto/sha1.hpp      2021-10-21 
08:19:17.000000000 +0200
@@ -1,5 +1,6 @@
 #include <string>
 #include <openssl/sha.h>
+#include <openssl/evp.h>
 
 
 /*
@@ -20,5 +21,5 @@
     static constexpr int digestLength = SHA_DIGEST_LENGTH;
 
 private:
-    SHA_CTX ctx;
+    EVP_MD_CTX *md_ctx;
 };
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libdnf-0.63.1/libdnf/utils/filesystem.cpp 
new/libdnf-0.65.0/libdnf/utils/filesystem.cpp
--- old/libdnf-0.63.1/libdnf/utils/filesystem.cpp       2021-06-14 
15:09:48.000000000 +0200
+++ new/libdnf-0.65.0/libdnf/utils/filesystem.cpp       2021-10-21 
08:19:17.000000000 +0200
@@ -24,6 +24,8 @@
 #include <cerrno>
 #include <cstring>
 
+#include "bgettext/bgettext-lib.h"
+#include "tinyformat/tinyformat.hpp"
 #include "filesystem.hpp"
 #include "../error.hpp"
 
@@ -72,7 +74,12 @@
         previous = position;
         // create directory if necessary
         if (!pathExists(directory.c_str())) {
-            mkdir(directory.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
+            int res = mkdir(directory.c_str(), S_IRWXU | S_IRWXG | S_IROTH | 
S_IXOTH);
+            if (res != 0 && errno != EEXIST) {
+                auto msg = tfm::format(_("Failed to create directory \"%s\": 
%d - %s"),
+                                       directory, errno, strerror(errno));
+                throw Error(msg);
+            }
         }
     }
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libdnf-0.63.1/libdnf/utils/os-release.cpp 
new/libdnf-0.65.0/libdnf/utils/os-release.cpp
--- old/libdnf-0.63.1/libdnf/utils/os-release.cpp       2021-06-14 
15:09:48.000000000 +0200
+++ new/libdnf-0.65.0/libdnf/utils/os-release.cpp       2021-10-21 
08:19:17.000000000 +0200
@@ -80,12 +80,10 @@
 
 static void initLibRpm()
 {
-    static bool libRpmInitiated{false};
-    if (libRpmInitiated) return;
-    if (rpmReadConfigFiles(NULL, NULL) != 0) {
-        throw std::runtime_error("failed to read rpm config files\n");
-    }
-    libRpmInitiated = true;
+    // call dnf_context_globals_init to ensure this only happens once
+    g_autoptr(GError) local_error = NULL;
+    if (!dnf_context_globals_init(&local_error))
+        throw std::runtime_error(local_error->message);
 }
 
 static std::string getBaseArch()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libdnf-0.63.1/libdnf/utils/utils.cpp 
new/libdnf-0.65.0/libdnf/utils/utils.cpp
--- old/libdnf-0.63.1/libdnf/utils/utils.cpp    2021-06-14 15:09:48.000000000 
+0200
+++ new/libdnf-0.65.0/libdnf/utils/utils.cpp    2021-10-21 08:19:17.000000000 
+0200
@@ -301,7 +301,7 @@
     fclose(inFile);
 }
 
-void checksum(const char * type, const char * inPath, const char * 
checksum_valid, bool * valid_out, gchar ** calculated_out)
+static void checksum(const char * type, const char * inPath, const char * 
checksum_valid, bool * valid_out, gchar ** calculated_out)
 {
     GError * errP{nullptr};
     gboolean valid;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libdnf-0.63.1/libdnf.spec 
new/libdnf-0.65.0/libdnf.spec
--- old/libdnf-0.63.1/libdnf.spec       2021-06-14 15:09:48.000000000 +0200
+++ new/libdnf-0.65.0/libdnf.spec       2021-10-21 08:19:17.000000000 +0200
@@ -1,11 +1,11 @@
-%global libsolv_version 0.7.17
-%global libmodulemd_version 2.11.2-2
+%global libsolv_version 0.7.20
+%global libmodulemd_version 2.13.0
 %global librepo_version 1.13.1
 %global dnf_conflict 4.3.0
 %global swig_version 3.0.12
 %global libdnf_major_version 0
-%global libdnf_minor_version 63
-%global libdnf_micro_version 1
+%global libdnf_minor_version 65
+%global libdnf_micro_version 0
 
 %define __cmake_in_source_build 1
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libdnf-0.63.1/po/CMakeLists.txt 
new/libdnf-0.65.0/po/CMakeLists.txt
--- old/libdnf-0.63.1/po/CMakeLists.txt 2021-06-14 15:09:48.000000000 +0200
+++ new/libdnf-0.65.0/po/CMakeLists.txt 2021-10-21 08:19:17.000000000 +0200
@@ -38,6 +38,14 @@
         )
 endif()
 
+add_custom_target(gettext-pot
+    COMMENT "Generating fresh dnf.pot file from sources"
+
+    COMMAND find . -iname '*.[ch]' -o -iname '*.[ch]pp' |
+        xargs xgettext -F --from-code=UTF-8 --keyword=_ --keyword=M_ 
--keyword=P_:1,2 --keyword=MP_:1,2 --keyword=C_:1c,2 --keyword=MC_:1c,2 
--keyword=CP_:1c,2,3 --keyword=MCP_:1c,2,3 -c 
--output=${CMAKE_CURRENT_SOURCE_DIR}/${PROJECT_NAME}.pot
+
+    WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
+    )
 
 IF (GETTEXT_FOUND)
     # this process unfortunately reformats .po files so copy them
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libdnf-0.63.1/python/hawkey/goal-py.cpp 
new/libdnf-0.65.0/python/hawkey/goal-py.cpp
--- old/libdnf-0.63.1/python/hawkey/goal-py.cpp 2021-06-14 15:09:48.000000000 
+0200
+++ new/libdnf-0.65.0/python/hawkey/goal-py.cpp 2021-10-21 08:19:17.000000000 
+0200
@@ -376,6 +376,33 @@
 } CATCH_TO_PYTHON
 
 static PyObject *
+add_exclude_from_weak(_GoalObject *self, PyObject *seq) try
+{
+    HyGoal goal = self->goal;
+    auto pset = pyseq_to_packageset(seq, hy_goal_get_sack(goal));
+    if (!pset)
+        return NULL;
+    goal->add_exclude_from_weak(*(pset.get()));
+    Py_RETURN_NONE;
+} CATCH_TO_PYTHON
+
+static PyObject *
+reset_exclude_from_weak(_GoalObject *self, PyObject *unused) try
+{
+    HyGoal goal = self->goal;
+    goal->reset_exclude_from_weak();
+    Py_RETURN_NONE;
+} CATCH_TO_PYTHON
+
+static PyObject *
+exclude_from_weak_autodetect(_GoalObject *self, PyObject *unused) try
+{
+    HyGoal goal = self->goal;
+    goal->exclude_from_weak_autodetect();
+    Py_RETURN_NONE;
+} CATCH_TO_PYTHON
+
+static PyObject *
 run(_GoalObject *self, PyObject *args, PyObject *kwds) try
 {
     int flags = 0;
@@ -597,6 +624,9 @@
      NULL},
     {"add_protected", (PyCFunction)add_protected, METH_O,
      NULL},
+    {"add_exclude_from_weak", (PyCFunction)add_exclude_from_weak, METH_O, 
NULL},
+    {"reset_exclude_from_weak", (PyCFunction)reset_exclude_from_weak, 
METH_NOARGS, NULL},
+    {"exclude_from_weak_autodetect", 
(PyCFunction)exclude_from_weak_autodetect, METH_NOARGS, NULL},
     {"distupgrade_all",        (PyCFunction)distupgrade_all,        
METH_NOARGS,        NULL},
     {"distupgrade",                (PyCFunction)distupgrade,
      METH_VARARGS | METH_KEYWORDS, NULL},
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libdnf-0.63.1/python/hawkey/reldep-py.cpp 
new/libdnf-0.65.0/python/hawkey/reldep-py.cpp
--- old/libdnf-0.63.1/python/hawkey/reldep-py.cpp       2021-06-14 
15:09:48.000000000 +0200
+++ new/libdnf-0.65.0/python/hawkey/reldep-py.cpp       2021-10-21 
08:19:17.000000000 +0200
@@ -220,6 +220,26 @@
     return result;
 } CATCH_TO_PYTHON
 
+static PyObject *
+get_str(_ReldepObject *self, void *closure) try
+{
+    const char *(*func)(DnfReldep*);
+    const char *cstr;
+
+    func = (const char *(*)(DnfReldep*))closure;
+    cstr = func(self->reldep);
+    if (cstr == NULL)
+        Py_RETURN_NONE;
+    return PyUnicode_FromString(cstr);
+} CATCH_TO_PYTHON
+
+static PyGetSetDef reldep_getsetters[] = {
+    {(char*)"name", (getter)get_str, NULL, NULL, (void *)dnf_reldep_get_name},
+    {(char*)"relation", (getter)get_str, NULL, NULL, (void 
*)dnf_reldep_get_relation},
+    {(char*)"version", (getter)get_str, NULL, NULL, (void 
*)dnf_reldep_get_version},
+    {NULL}                        /* sentinel */
+};
+
 PyTypeObject reldep_Type = {
     PyVarObject_HEAD_INIT(NULL, 0)
     "_hawkey.Reldep",                /*tp_name*/
@@ -250,7 +270,7 @@
     0,                                 /* tp_iternext */
     0,                                /* tp_methods */
     0,                                /* tp_members */
-    0,                                /* tp_getset */
+    reldep_getsetters,                /* tp_getset */
     0,                                /* tp_base */
     0,                                /* tp_dict */
     0,                                /* tp_descr_get */
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libdnf-0.63.1/tests/hawkey/test_iutil.cpp 
new/libdnf-0.65.0/tests/hawkey/test_iutil.cpp
--- old/libdnf-0.63.1/tests/hawkey/test_iutil.cpp       2021-06-14 
15:09:48.000000000 +0200
+++ new/libdnf-0.65.0/tests/hawkey/test_iutil.cpp       2021-10-21 
08:19:17.000000000 +0200
@@ -79,11 +79,13 @@
     /* the taken checksum are not zeros anymore */
     fail_if(checksum_cmp(cs1, cs2) == 0);
     fail_if(checksum_cmp(cs1_sum, cs2_sum) == 0);
+    fp = NULL;
 
     /* append something */
     fail_if((fp = fopen(new_file, "a")) == NULL);
     fail_unless(fwrite("X", 1, 1, fp) == 1);
     fclose(fp);
+    fp = NULL;
 
     /* take the second checksums */
     fail_if((fp = fopen(new_file, "r")) == NULL);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libdnf-0.63.1/tests/libdnf/module/ContextTest.cpp 
new/libdnf-0.65.0/tests/libdnf/module/ContextTest.cpp
--- old/libdnf-0.63.1/tests/libdnf/module/ContextTest.cpp       2021-06-14 
15:09:48.000000000 +0200
+++ new/libdnf-0.65.0/tests/libdnf/module/ContextTest.cpp       2021-10-21 
08:19:17.000000000 +0200
@@ -146,13 +146,6 @@
     g_assert(strstr(error->message, "Unable to resolve argument 
'httpd:nonexistent'"));
     g_clear_pointer(&error, g_error_free);
 
-    // try to install without default profile
-    module_specs[0] = "httpd";
-    g_assert(!dnf_context_module_install(context, module_specs, &error));
-    g_assert(error);
-    g_assert(strstr(error->message, "No default profile found"));
-    g_clear_pointer(&error, g_error_free);
-
     // try to install non-existent profile
     module_specs[0] = "httpd:2.4/nonexistent";
     g_assert(!dnf_context_module_install(context, module_specs, &error));
@@ -160,7 +153,22 @@
     g_assert(strstr(error->message, "No profile found matching 
'nonexistent'"));
     g_clear_pointer(&error, g_error_free);
 
-    module_specs[0] = "httpd:2.4/default";
+    // disable all modules
+    g_assert(dnf_context_module_disable_all(context, &error));
+    g_assert_no_error(error);
+
+    // installing a modular package should fail
+    g_assert(!dnf_context_install(context, "httpd-2.4.25-8.x86_64", &error));
+    g_assert(error);
+    g_assert(strstr(error->message, "No package matches 
'httpd-2.4.25-8.x86_64'"));
+    g_clear_pointer(&error, g_error_free);
+
+    // reset all modules
+    g_assert(dnf_context_reset_all_modules(context, sack, &error));
+    g_assert_no_error(error);
+
+    // enable and install default profile from modulemd-defaults
+    module_specs[0] = "httpd:2.4";
     g_assert(dnf_context_module_install(context, module_specs, &error));
     g_assert_no_error(error);
     HyGoal goal = dnf_context_get_goal(context);
@@ -170,6 +178,13 @@
     g_assert(pkgs);
     g_assert(pkglist_has_nevra(pkgs, "httpd-2.4.25-8.x86_64"));
     g_assert(pkglist_has_nevra(pkgs, "libnghttp2-1.21.1-1.x86_64"));
+
+    // Verify we can install the default stream from modulemd-defaults.
+    // This would fail with EnableMultipleStreamsException if it didn't match
+    // the 2.4 stream since we enabled the 2.4 stream just above.
+    module_specs[0] = "httpd";
+    g_assert(dnf_context_module_install(context, module_specs, &error));
+    g_assert_no_error(error);
 }
 
 void ContextTest::sackHas(DnfSack * sack, libdnf::ModulePackage * pkg) const
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/libdnf-0.63.1/tests/libdnf/module/ModulePackageContainerTest.cpp 
new/libdnf-0.65.0/tests/libdnf/module/ModulePackageContainerTest.cpp
--- old/libdnf-0.63.1/tests/libdnf/module/ModulePackageContainerTest.cpp        
2021-06-14 15:09:48.000000000 +0200
+++ new/libdnf-0.65.0/tests/libdnf/module/ModulePackageContainerTest.cpp        
2021-10-21 08:19:17.000000000 +0200
@@ -17,7 +17,7 @@
     char *retptr = mkdtemp(tmpdir);
     CPPUNIT_ASSERT(retptr);
     char * etc_target = g_strjoin(NULL, tmpdir, "/etc", NULL);
-    dnf_copy_recursive(TESTDATADIR "/modules/etc", etc_target, &error);
+    CPPUNIT_ASSERT(dnf_copy_recursive(TESTDATADIR "/modules/etc", etc_target, 
&error));
     g_assert_no_error(error);
     g_free(etc_target);
 

Reply via email to