Igor Gnatenko b45d89c
From 8e5accccf8e5015cf87f589d0b8afb750cbf7a09 Mon Sep 17 00:00:00 2001
Igor Gnatenko b45d89c
From: Jaroslav Rohel <jrohel@redhat.com>
Igor Gnatenko b45d89c
Date: Thu, 17 Aug 2017 11:59:08 +0200
Igor Gnatenko b45d89c
Subject: [PATCH 1/4] Enablement for includepkgs option
Igor Gnatenko b45d89c
Igor Gnatenko b45d89c
Added support for enable/disable includes per repository.
Igor Gnatenko b45d89c
Added functions for removing and reseting of includes and excludes.
Igor Gnatenko b45d89c
Added functions for getting includes and excludes.
Igor Gnatenko b45d89c
Igor Gnatenko b45d89c
Expose all functions to Python.
Igor Gnatenko b45d89c
Igor Gnatenko b45d89c
(cherry picked from commit a02664647bda14402b47416ce22c2b004a46193d)
Igor Gnatenko b45d89c
---
Igor Gnatenko b45d89c
 VERSION.cmake            |   2 +-
Igor Gnatenko b45d89c
 libdnf.spec              |   2 +-
Igor Gnatenko b45d89c
 libdnf/dnf-sack.c        | 263 ++++++++++++++++++++++++++++++++++++++++-------
Igor Gnatenko b45d89c
 libdnf/dnf-sack.h        |  14 +++
Igor Gnatenko b45d89c
 libdnf/hy-repo-private.h |   1 +
Igor Gnatenko b45d89c
 libdnf/hy-repo.c         |  12 +++
Igor Gnatenko b45d89c
 libdnf/hy-repo.h         |   2 +
Igor Gnatenko b45d89c
 python/hawkey/sack-py.c  | 147 ++++++++++++++++++++++++++
Igor Gnatenko b45d89c
 8 files changed, 402 insertions(+), 41 deletions(-)
Igor Gnatenko b45d89c
Igor Gnatenko b45d89c
diff --git a/VERSION.cmake b/VERSION.cmake
Igor Gnatenko b45d89c
index f6e00e3..286c29c 100644
Igor Gnatenko b45d89c
--- a/VERSION.cmake
Igor Gnatenko b45d89c
+++ b/VERSION.cmake
Igor Gnatenko b45d89c
@@ -1,4 +1,4 @@
Igor Gnatenko b45d89c
 set (LIBDNF_MAJOR_VERSION 0)
Igor Gnatenko b45d89c
 set (LIBDNF_MINOR_VERSION 9)
Igor Gnatenko b45d89c
-set (LIBDNF_MICRO_VERSION 3)
Igor Gnatenko b45d89c
+set (LIBDNF_MICRO_VERSION 4)
Igor Gnatenko b45d89c
 set (LIBDNF_VERSION ${LIBDNF_MAJOR_VERSION}.${LIBDNF_MINOR_VERSION}.${LIBDNF_MICRO_VERSION})
Igor Gnatenko b45d89c
diff --git a/libdnf.spec b/libdnf.spec
Igor Gnatenko b45d89c
index 71af7bb..2e7e09d 100644
Igor Gnatenko b45d89c
--- a/libdnf.spec
Igor Gnatenko b45d89c
+++ b/libdnf.spec
Igor Gnatenko b45d89c
@@ -21,7 +21,7 @@
Igor Gnatenko b45d89c
     %{nil}
Igor Gnatenko b45d89c
 
Igor Gnatenko b45d89c
 Name:           libdnf
Igor Gnatenko b45d89c
-Version:        0.9.3
Igor Gnatenko b45d89c
+Version:        0.9.4
Igor Gnatenko b45d89c
 Release:        1%{?dist}
Igor Gnatenko b45d89c
 Summary:        Library providing simplified C and Python API to libsolv
Igor Gnatenko b45d89c
 License:        LGPLv2+
Igor Gnatenko b45d89c
diff --git a/libdnf/dnf-sack.c b/libdnf/dnf-sack.c
Igor Gnatenko b45d89c
index 0c6e95c..086293d 100644
Igor Gnatenko b45d89c
--- a/libdnf/dnf-sack.c
Igor Gnatenko b45d89c
+++ b/libdnf/dnf-sack.c
Igor Gnatenko b45d89c
@@ -282,21 +282,40 @@ dnf_sack_recompute_considered(DnfSack *sack)
Igor Gnatenko b45d89c
     if (priv->considered_uptodate)
Igor Gnatenko b45d89c
         return;
Igor Gnatenko b45d89c
     if (!pool->considered) {
Igor Gnatenko b45d89c
-        if (!priv->repo_excludes && !priv->pkg_excludes)
Igor Gnatenko b45d89c
+        if (!priv->repo_excludes && !priv->pkg_excludes && !priv->pkg_includes)
Igor Gnatenko b45d89c
             return;
Igor Gnatenko b45d89c
         pool->considered = g_malloc0(sizeof(Map));
Igor Gnatenko b45d89c
         map_init(pool->considered, pool->nsolvables);
Igor Gnatenko b45d89c
     } else
Igor Gnatenko b45d89c
         map_grow(pool->considered, pool->nsolvables);
Igor Gnatenko b45d89c
 
Igor Gnatenko b45d89c
-    // considered = (all - repo_excludes - pkg_excludes) and pkg_includes
Igor Gnatenko b45d89c
+    // considered = (all - repo_excludes - pkg_excludes) and
Igor Gnatenko b45d89c
+    //              (pkg_includes + all_from_repos_not_using_includes)
Igor Gnatenko b45d89c
     map_setall(pool->considered);
Igor Gnatenko b45d89c
     if (priv->repo_excludes)
Igor Gnatenko b45d89c
         map_subtract(pool->considered, priv->repo_excludes);
Igor Gnatenko b45d89c
     if (priv->pkg_excludes)
Igor Gnatenko b45d89c
         map_subtract(pool->considered, priv->pkg_excludes);
Igor Gnatenko b45d89c
-    if (priv->pkg_includes)
Igor Gnatenko b45d89c
-        map_and(pool->considered, priv->pkg_includes);
Igor Gnatenko b45d89c
+    if (priv->pkg_includes) {
Igor Gnatenko b45d89c
+        Map pkg_includes_tmp;
Igor Gnatenko b45d89c
+        map_init_clone(&pkg_includes_tmp, priv->pkg_includes);
Igor Gnatenko b45d89c
+
Igor Gnatenko b45d89c
+        // Add all solvables from repositories which do not use "includes"
Igor Gnatenko b45d89c
+        Id repoid;
Igor Gnatenko b45d89c
+        Repo *repo;
Igor Gnatenko b45d89c
+        FOR_REPOS(repoid, repo) {
Igor Gnatenko b45d89c
+            HyRepo hyrepo = repo->appdata;
Igor Gnatenko b45d89c
+            if (!hy_repo_get_use_includes(hyrepo)) {
Igor Gnatenko b45d89c
+                Id solvableid;
Igor Gnatenko b45d89c
+                Solvable *solvable;
Igor Gnatenko b45d89c
+                FOR_REPO_SOLVABLES(repo, solvableid, solvable)
Igor Gnatenko b45d89c
+                    MAPSET(&pkg_includes_tmp, solvableid);
Igor Gnatenko b45d89c
+            }
Igor Gnatenko b45d89c
+        }
Igor Gnatenko b45d89c
+
Igor Gnatenko b45d89c
+        map_and(pool->considered, &pkg_includes_tmp);
Igor Gnatenko b45d89c
+        map_free(&pkg_includes_tmp);
Igor Gnatenko b45d89c
+    }
Igor Gnatenko b45d89c
     pool_createwhatprovides(priv->pool);
Igor Gnatenko b45d89c
     priv->considered_uptodate = TRUE;
Igor Gnatenko b45d89c
 }
Igor Gnatenko b45d89c
@@ -1156,6 +1175,23 @@ dnf_sack_count(DnfSack *sack)
Igor Gnatenko b45d89c
     return cnt;
Igor Gnatenko b45d89c
 }
Igor Gnatenko b45d89c
 
Igor Gnatenko b45d89c
+static void
Igor Gnatenko b45d89c
+dnf_sack_add_excludes_or_includes(DnfSack *sack, Map **dest, DnfPackageSet *pkgset)
Igor Gnatenko b45d89c
+{
Igor Gnatenko b45d89c
+    Map *destmap = *dest;
Igor Gnatenko b45d89c
+    if (destmap == NULL) {
Igor Gnatenko b45d89c
+        destmap = g_malloc0(sizeof(Map));
Igor Gnatenko b45d89c
+        Pool *pool = dnf_sack_get_pool(sack);
Igor Gnatenko b45d89c
+        map_init(destmap, pool->nsolvables);
Igor Gnatenko b45d89c
+        *dest = destmap;
Igor Gnatenko b45d89c
+    }
Igor Gnatenko b45d89c
+
Igor Gnatenko b45d89c
+    Map *pkgmap = dnf_packageset_get_map(pkgset);
Igor Gnatenko b45d89c
+    map_or(destmap, pkgmap);
Igor Gnatenko b45d89c
+    DnfSackPrivate *priv = GET_PRIVATE(sack);
Igor Gnatenko b45d89c
+    priv->considered_uptodate = FALSE;
Igor Gnatenko b45d89c
+}
Igor Gnatenko b45d89c
+
Igor Gnatenko b45d89c
 /**
Igor Gnatenko b45d89c
  * dnf_sack_add_excludes:
Igor Gnatenko b45d89c
  * @sack: a #DnfSack instance.
Igor Gnatenko b45d89c
@@ -1169,17 +1205,7 @@ void
Igor Gnatenko b45d89c
 dnf_sack_add_excludes(DnfSack *sack, DnfPackageSet *pset)
Igor Gnatenko b45d89c
 {
Igor Gnatenko b45d89c
     DnfSackPrivate *priv = GET_PRIVATE(sack);
Igor Gnatenko b45d89c
-    Pool *pool = dnf_sack_get_pool(sack);
Igor Gnatenko b45d89c
-    Map *excl = priv->pkg_excludes;
Igor Gnatenko b45d89c
-    Map *nexcl = dnf_packageset_get_map(pset);
Igor Gnatenko b45d89c
-
Igor Gnatenko b45d89c
-    if (excl == NULL) {
Igor Gnatenko b45d89c
-        excl = g_malloc0(sizeof(Map));
Igor Gnatenko b45d89c
-        map_init(excl, pool->nsolvables);
Igor Gnatenko b45d89c
-        priv->pkg_excludes = excl;
Igor Gnatenko b45d89c
-    }
Igor Gnatenko b45d89c
-    map_or(excl, nexcl);
Igor Gnatenko b45d89c
-    priv->considered_uptodate = FALSE;
Igor Gnatenko b45d89c
+    dnf_sack_add_excludes_or_includes(sack, &priv->pkg_excludes, pset);
Igor Gnatenko b45d89c
 }
Igor Gnatenko b45d89c
 
Igor Gnatenko b45d89c
 /**
Igor Gnatenko b45d89c
@@ -1195,17 +1221,65 @@ void
Igor Gnatenko b45d89c
 dnf_sack_add_includes(DnfSack *sack, DnfPackageSet *pset)
Igor Gnatenko b45d89c
 {
Igor Gnatenko b45d89c
     DnfSackPrivate *priv = GET_PRIVATE(sack);
Igor Gnatenko b45d89c
-    Pool *pool = dnf_sack_get_pool(sack);
Igor Gnatenko b45d89c
-    Map *incl = priv->pkg_includes;
Igor Gnatenko b45d89c
-    Map *nincl = dnf_packageset_get_map(pset);
Igor Gnatenko b45d89c
+    dnf_sack_add_excludes_or_includes(sack, &priv->pkg_includes, pset);
Igor Gnatenko b45d89c
+}
Igor Gnatenko b45d89c
+
Igor Gnatenko b45d89c
+static void
Igor Gnatenko b45d89c
+dnf_sack_remove_excludes_or_includes(DnfSack *sack, Map *from, DnfPackageSet *pkgset)
Igor Gnatenko b45d89c
+{
Igor Gnatenko b45d89c
+    if (from == NULL)
Igor Gnatenko b45d89c
+        return;
Igor Gnatenko b45d89c
+    Map *pkgmap = dnf_packageset_get_map(pkgset);
Igor Gnatenko b45d89c
+    map_subtract(from, pkgmap);
Igor Gnatenko b45d89c
+    DnfSackPrivate *priv = GET_PRIVATE(sack);
Igor Gnatenko b45d89c
+    priv->considered_uptodate = FALSE;
Igor Gnatenko b45d89c
+}
Igor Gnatenko b45d89c
+
Igor Gnatenko b45d89c
+/**
Igor Gnatenko b45d89c
+ * dnf_sack_remove_excludes:
Igor Gnatenko b45d89c
+ * @sack: a #DnfSack instance.
Igor Gnatenko b45d89c
+ * @pset: a #DnfPackageSet or %NULL.
Igor Gnatenko b45d89c
+ *
Igor Gnatenko b45d89c
+ * Removes excludes from the sack.
Igor Gnatenko b45d89c
+ *
Igor Gnatenko b45d89c
+ * Since: 0.9.4
Igor Gnatenko b45d89c
+ */
Igor Gnatenko b45d89c
+void
Igor Gnatenko b45d89c
+dnf_sack_remove_excludes(DnfSack *sack, DnfPackageSet *pset)
Igor Gnatenko b45d89c
+{
Igor Gnatenko b45d89c
+    DnfSackPrivate *priv = GET_PRIVATE(sack);
Igor Gnatenko b45d89c
+    dnf_sack_remove_excludes_or_includes(sack, priv->pkg_excludes, pset);
Igor Gnatenko b45d89c
+}
Igor Gnatenko b45d89c
 
Igor Gnatenko b45d89c
-    if (incl == NULL) {
Igor Gnatenko b45d89c
-        incl = g_malloc0(sizeof(Map));
Igor Gnatenko b45d89c
-        map_init(incl, pool->nsolvables);
Igor Gnatenko b45d89c
-        priv->pkg_includes = incl;
Igor Gnatenko b45d89c
+/**
Igor Gnatenko b45d89c
+ * dnf_sack_remove_includes:
Igor Gnatenko b45d89c
+ * @sack: a #DnfSack instance.
Igor Gnatenko b45d89c
+ * @pset: a #DnfPackageSet or %NULL.
Igor Gnatenko b45d89c
+ *
Igor Gnatenko b45d89c
+ * Removes includes from the sack.
Igor Gnatenko b45d89c
+ *
Igor Gnatenko b45d89c
+ * Since: 0.9.4
Igor Gnatenko b45d89c
+ */
Igor Gnatenko b45d89c
+void
Igor Gnatenko b45d89c
+dnf_sack_remove_includes(DnfSack *sack, DnfPackageSet *pset)
Igor Gnatenko b45d89c
+{
Igor Gnatenko b45d89c
+    DnfSackPrivate *priv = GET_PRIVATE(sack);
Igor Gnatenko b45d89c
+    dnf_sack_remove_excludes_or_includes(sack, priv->pkg_includes, pset);
Igor Gnatenko b45d89c
+}
Igor Gnatenko b45d89c
+
Igor Gnatenko b45d89c
+static void
Igor Gnatenko b45d89c
+dnf_sack_set_excludes_or_includes(DnfSack *sack, Map **dest, DnfPackageSet *pkgset)
Igor Gnatenko b45d89c
+{
Igor Gnatenko b45d89c
+    if (*dest == NULL && pkgset == NULL)
Igor Gnatenko b45d89c
+        return;
Igor Gnatenko b45d89c
+
Igor Gnatenko b45d89c
+    *dest = free_map_fully(*dest);
Igor Gnatenko b45d89c
+    if (pkgset) {
Igor Gnatenko b45d89c
+        *dest = g_malloc0(sizeof(Map));
Igor Gnatenko b45d89c
+        Map *pkgmap = dnf_packageset_get_map(pkgset);
Igor Gnatenko b45d89c
+        map_init_clone(*dest, pkgmap);
Igor Gnatenko b45d89c
     }
Igor Gnatenko b45d89c
-    assert(incl->size >= nincl->size);
Igor Gnatenko b45d89c
-    map_or(incl, nincl);
Igor Gnatenko b45d89c
+    DnfSackPrivate *priv = GET_PRIVATE(sack);
Igor Gnatenko b45d89c
     priv->considered_uptodate = FALSE;
Igor Gnatenko b45d89c
 }
Igor Gnatenko b45d89c
 
Igor Gnatenko b45d89c
@@ -1222,15 +1296,7 @@ void
Igor Gnatenko b45d89c
 dnf_sack_set_excludes(DnfSack *sack, DnfPackageSet *pset)
Igor Gnatenko b45d89c
 {
Igor Gnatenko b45d89c
     DnfSackPrivate *priv = GET_PRIVATE(sack);
Igor Gnatenko b45d89c
-    priv->pkg_excludes = free_map_fully(priv->pkg_excludes);
Igor Gnatenko b45d89c
-
Igor Gnatenko b45d89c
-    if (pset) {
Igor Gnatenko b45d89c
-        Map *nexcl = dnf_packageset_get_map(pset);
Igor Gnatenko b45d89c
-
Igor Gnatenko b45d89c
-        priv->pkg_excludes = g_malloc0(sizeof(Map));
Igor Gnatenko b45d89c
-        map_init_clone(priv->pkg_excludes, nexcl);
Igor Gnatenko b45d89c
-    }
Igor Gnatenko b45d89c
-    priv->considered_uptodate = FALSE;
Igor Gnatenko b45d89c
+    dnf_sack_set_excludes_or_includes(sack, &priv->pkg_excludes, pset);
Igor Gnatenko b45d89c
 }
Igor Gnatenko b45d89c
 
Igor Gnatenko b45d89c
 /**
Igor Gnatenko b45d89c
@@ -1246,14 +1312,133 @@ void
Igor Gnatenko b45d89c
 dnf_sack_set_includes(DnfSack *sack, DnfPackageSet *pset)
Igor Gnatenko b45d89c
 {
Igor Gnatenko b45d89c
     DnfSackPrivate *priv = GET_PRIVATE(sack);
Igor Gnatenko b45d89c
-    priv->pkg_includes = free_map_fully(priv->pkg_includes);
Igor Gnatenko b45d89c
+    dnf_sack_set_excludes_or_includes(sack, &priv->pkg_includes, pset);
Igor Gnatenko b45d89c
+}
Igor Gnatenko b45d89c
+
Igor Gnatenko b45d89c
+/**
Igor Gnatenko b45d89c
+ * dnf_sack_reset_excludes:
Igor Gnatenko b45d89c
+ * @sack: a #DnfSack instance.
Igor Gnatenko b45d89c
+ *
Igor Gnatenko b45d89c
+ * Reset excludes (remove excludes map from memory).
Igor Gnatenko b45d89c
+ *
Igor Gnatenko b45d89c
+ * Since: 0.9.4
Igor Gnatenko b45d89c
+ */
Igor Gnatenko b45d89c
+void
Igor Gnatenko b45d89c
+dnf_sack_reset_excludes(DnfSack *sack)
Igor Gnatenko b45d89c
+{
Igor Gnatenko b45d89c
+    dnf_sack_set_excludes(sack, NULL);
Igor Gnatenko b45d89c
+}
Igor Gnatenko b45d89c
+
Igor Gnatenko b45d89c
+/**
Igor Gnatenko b45d89c
+ * dnf_sack_reset_includes:
Igor Gnatenko b45d89c
+ * @sack: a #DnfSack instance.
Igor Gnatenko b45d89c
+ *
Igor Gnatenko b45d89c
+ * Reset includes (remove includes map from memory).
Igor Gnatenko b45d89c
+ *
Igor Gnatenko b45d89c
+ * Since: 0.9.4
Igor Gnatenko b45d89c
+ */
Igor Gnatenko b45d89c
+void
Igor Gnatenko b45d89c
+dnf_sack_reset_includes(DnfSack *sack)
Igor Gnatenko b45d89c
+{
Igor Gnatenko b45d89c
+    dnf_sack_set_includes(sack, NULL);
Igor Gnatenko b45d89c
+}
Igor Gnatenko b45d89c
+
Igor Gnatenko b45d89c
+/**
Igor Gnatenko b45d89c
+ * dnf_sack_get_excludes:
Igor Gnatenko b45d89c
+ * @sack: a #DnfSack instance.
Igor Gnatenko b45d89c
+ * @pset: a #DnfPackageSet or %NULL.
Igor Gnatenko b45d89c
+ *
Igor Gnatenko b45d89c
+ * Gets sack excludes.
Igor Gnatenko b45d89c
+ *
Igor Gnatenko b45d89c
+ * Since: 0.9.4
Igor Gnatenko b45d89c
+ */
Igor Gnatenko b45d89c
+DnfPackageSet *
Igor Gnatenko b45d89c
+dnf_sack_get_excludes(DnfSack *sack)
Igor Gnatenko b45d89c
+{
Igor Gnatenko b45d89c
+    DnfSackPrivate *priv = GET_PRIVATE(sack);
Igor Gnatenko b45d89c
+    Map *excl = priv->pkg_excludes;
Igor Gnatenko b45d89c
+    return excl ? dnf_packageset_from_bitmap(sack, excl) : NULL;
Igor Gnatenko b45d89c
+}
Igor Gnatenko b45d89c
+
Igor Gnatenko b45d89c
+/**
Igor Gnatenko b45d89c
+ * dnf_sack_get_includes:
Igor Gnatenko b45d89c
+ * @sack: a #DnfSack instance.
Igor Gnatenko b45d89c
+ *
Igor Gnatenko b45d89c
+ * Gets sack includes.
Igor Gnatenko b45d89c
+ *
Igor Gnatenko b45d89c
+ * Since: 0.9.4
Igor Gnatenko b45d89c
+ */
Igor Gnatenko b45d89c
+DnfPackageSet *
Igor Gnatenko b45d89c
+dnf_sack_get_includes(DnfSack *sack)
Igor Gnatenko b45d89c
+{
Igor Gnatenko b45d89c
+    DnfSackPrivate *priv = GET_PRIVATE(sack);
Igor Gnatenko b45d89c
+    Map *incl = priv->pkg_includes;
Igor Gnatenko b45d89c
+    return incl ? dnf_packageset_from_bitmap(sack, incl) : NULL;
Igor Gnatenko b45d89c
+}
Igor Gnatenko b45d89c
 
Igor Gnatenko b45d89c
-    if (pset) {
Igor Gnatenko b45d89c
-        Map *nincl = dnf_packageset_get_map(pset);
Igor Gnatenko b45d89c
-        priv->pkg_includes = g_malloc0(sizeof(Map));
Igor Gnatenko b45d89c
-        map_init_clone(priv->pkg_includes, nincl);
Igor Gnatenko b45d89c
+/**
Igor Gnatenko b45d89c
+ * dnf_sack_set_use_includes:
Igor Gnatenko b45d89c
+ * @sack: a #DnfSack instance.
Igor Gnatenko b45d89c
+ * @repo_name: a name of repo or %NULL for all repos.
Igor Gnatenko b45d89c
+ * @enabled: a use includes for a repo or all repos.
Igor Gnatenko b45d89c
+ *
Igor Gnatenko b45d89c
+ * Enable/disable usage of includes for repo/all-repos.
Igor Gnatenko b45d89c
+ *
Igor Gnatenko b45d89c
+ * Returns: FALSE if error occured (unknown reponame) else TRUE.
Igor Gnatenko b45d89c
+ *
Igor Gnatenko b45d89c
+ * Since: 0.9.4
Igor Gnatenko b45d89c
+ */
Igor Gnatenko b45d89c
+gboolean
Igor Gnatenko b45d89c
+dnf_sack_set_use_includes(DnfSack *sack, const char *reponame, gboolean enabled)
Igor Gnatenko b45d89c
+{
Igor Gnatenko b45d89c
+    DnfSackPrivate *priv = GET_PRIVATE(sack);
Igor Gnatenko b45d89c
+    Pool *pool = dnf_sack_get_pool(sack);
Igor Gnatenko b45d89c
+
Igor Gnatenko b45d89c
+    if (reponame) {
Igor Gnatenko b45d89c
+        HyRepo hyrepo = hrepo_by_name(sack, reponame);
Igor Gnatenko b45d89c
+        if (!hyrepo)
Igor Gnatenko b45d89c
+            return FALSE;
Igor Gnatenko b45d89c
+        if (hy_repo_get_use_includes(hyrepo) != enabled)
Igor Gnatenko b45d89c
+        {
Igor Gnatenko b45d89c
+            hy_repo_set_use_includes(hyrepo, enabled);
Igor Gnatenko b45d89c
+            priv->considered_uptodate = FALSE;
Igor Gnatenko b45d89c
+        }
Igor Gnatenko b45d89c
+    } else {
Igor Gnatenko b45d89c
+        Id repoid;
Igor Gnatenko b45d89c
+        Repo *repo;
Igor Gnatenko b45d89c
+        FOR_REPOS(repoid, repo) {
Igor Gnatenko b45d89c
+            HyRepo hyrepo = pool->repos[repoid]->appdata;
Igor Gnatenko b45d89c
+            if (hy_repo_get_use_includes(hyrepo) != enabled)
Igor Gnatenko b45d89c
+            {
Igor Gnatenko b45d89c
+                hy_repo_set_use_includes(hyrepo, enabled);
Igor Gnatenko b45d89c
+                priv->considered_uptodate = FALSE;
Igor Gnatenko b45d89c
+            }
Igor Gnatenko b45d89c
+        }
Igor Gnatenko b45d89c
     }
Igor Gnatenko b45d89c
-    priv->considered_uptodate = FALSE;
Igor Gnatenko b45d89c
+    return TRUE;
Igor Gnatenko b45d89c
+}
Igor Gnatenko b45d89c
+
Igor Gnatenko b45d89c
+/**
Igor Gnatenko b45d89c
+ * dnf_sack_get_use_includes:
Igor Gnatenko b45d89c
+ * @sack: a #DnfSack instance.
Igor Gnatenko b45d89c
+ * @repo_name: a name of repo or %NULL for all repos.
Igor Gnatenko b45d89c
+ * @enabled: a returned state of includes for repo
Igor Gnatenko b45d89c
+ *
Igor Gnatenko b45d89c
+ * Enable/disable usage of includes for repo/all-repos.
Igor Gnatenko b45d89c
+ *
Igor Gnatenko b45d89c
+ * Returns: FALSE if error occured (unknown reponame) else TRUE.
Igor Gnatenko b45d89c
+ *
Igor Gnatenko b45d89c
+ * Since: 0.9.4
Igor Gnatenko b45d89c
+ */
Igor Gnatenko b45d89c
+gboolean
Igor Gnatenko b45d89c
+dnf_sack_get_use_includes(DnfSack *sack, const char *reponame, gboolean *enabled)
Igor Gnatenko b45d89c
+{
Igor Gnatenko b45d89c
+    assert(reponame);
Igor Gnatenko b45d89c
+    HyRepo hyrepo = hrepo_by_name(sack, reponame);
Igor Gnatenko b45d89c
+    if (!hyrepo)
Igor Gnatenko b45d89c
+        return FALSE;
Igor Gnatenko b45d89c
+    *enabled = hy_repo_get_use_includes(hyrepo);
Igor Gnatenko b45d89c
+    return TRUE;
Igor Gnatenko b45d89c
 }
Igor Gnatenko b45d89c
 
Igor Gnatenko b45d89c
 /**
Igor Gnatenko b45d89c
diff --git a/libdnf/dnf-sack.h b/libdnf/dnf-sack.h
Igor Gnatenko b45d89c
index eeb5805..2e2b079 100644
Igor Gnatenko b45d89c
--- a/libdnf/dnf-sack.h
Igor Gnatenko b45d89c
+++ b/libdnf/dnf-sack.h
Igor Gnatenko b45d89c
@@ -120,10 +120,24 @@ void         dnf_sack_add_excludes          (DnfSack        *sack,
Igor Gnatenko b45d89c
                                              DnfPackageSet  *pset);
Igor Gnatenko b45d89c
 void         dnf_sack_add_includes          (DnfSack        *sack,
Igor Gnatenko b45d89c
                                              DnfPackageSet  *pset);
Igor Gnatenko b45d89c
+void         dnf_sack_remove_excludes       (DnfSack        *sack,
Igor Gnatenko b45d89c
+                                             DnfPackageSet  *pset);
Igor Gnatenko b45d89c
+void         dnf_sack_remove_includes       (DnfSack        *sack,
Igor Gnatenko b45d89c
+                                             DnfPackageSet  *pset);
Igor Gnatenko b45d89c
 void         dnf_sack_set_excludes          (DnfSack        *sack,
Igor Gnatenko b45d89c
                                              DnfPackageSet  *pset);
Igor Gnatenko b45d89c
 void         dnf_sack_set_includes          (DnfSack        *sack,
Igor Gnatenko b45d89c
                                              DnfPackageSet  *pset);
Igor Gnatenko b45d89c
+void         dnf_sack_reset_excludes        (DnfSack        *sack);
Igor Gnatenko b45d89c
+void         dnf_sack_reset_includes        (DnfSack        *sack);
Igor Gnatenko b45d89c
+DnfPackageSet *dnf_sack_get_includes        (DnfSack        *sack);
Igor Gnatenko b45d89c
+DnfPackageSet *dnf_sack_get_excludes        (DnfSack        *sack);
Igor Gnatenko b45d89c
+gboolean     dnf_sack_set_use_includes      (DnfSack        *sack,
Igor Gnatenko b45d89c
+                                             const char     *reponame,
Igor Gnatenko b45d89c
+                                             gboolean        enabled);
Igor Gnatenko b45d89c
+gboolean     dnf_sack_get_use_includes      (DnfSack        *sack,
Igor Gnatenko b45d89c
+                                             const char     *reponame,
Igor Gnatenko b45d89c
+                                             gboolean       *enabled);
Igor Gnatenko b45d89c
 int          dnf_sack_repo_enabled          (DnfSack        *sack,
Igor Gnatenko b45d89c
                                              const char     *reponame,
Igor Gnatenko b45d89c
                                              int             enabled);
Igor Gnatenko b45d89c
diff --git a/libdnf/hy-repo-private.h b/libdnf/hy-repo-private.h
Igor Gnatenko b45d89c
index 756b13a..1abf4be 100644
Igor Gnatenko b45d89c
--- a/libdnf/hy-repo-private.h
Igor Gnatenko b45d89c
+++ b/libdnf/hy-repo-private.h
Igor Gnatenko b45d89c
@@ -60,6 +60,7 @@ struct _HyRepo {
Igor Gnatenko b45d89c
     int main_nsolvables;
Igor Gnatenko b45d89c
     int main_nrepodata;
Igor Gnatenko b45d89c
     int main_end;
Igor Gnatenko b45d89c
+    gboolean use_includes; 
Igor Gnatenko b45d89c
 };
Igor Gnatenko b45d89c
 
Igor Gnatenko b45d89c
 enum _hy_repo_repodata {
Igor Gnatenko b45d89c
diff --git a/libdnf/hy-repo.c b/libdnf/hy-repo.c
Igor Gnatenko b45d89c
index 22a7694..e816ea8 100644
Igor Gnatenko b45d89c
--- a/libdnf/hy-repo.c
Igor Gnatenko b45d89c
+++ b/libdnf/hy-repo.c
Igor Gnatenko b45d89c
@@ -143,6 +143,12 @@ hy_repo_get_priority(HyRepo repo)
Igor Gnatenko b45d89c
     return repo->priority;
Igor Gnatenko b45d89c
 }
Igor Gnatenko b45d89c
 
Igor Gnatenko b45d89c
+gboolean
Igor Gnatenko b45d89c
+hy_repo_get_use_includes(HyRepo repo)
Igor Gnatenko b45d89c
+{
Igor Gnatenko b45d89c
+  return repo->use_includes;
Igor Gnatenko b45d89c
+}
Igor Gnatenko b45d89c
+
Igor Gnatenko b45d89c
 guint
Igor Gnatenko b45d89c
 hy_repo_get_n_solvables(HyRepo repo)
Igor Gnatenko b45d89c
 {
Igor Gnatenko b45d89c
@@ -165,6 +171,12 @@ hy_repo_set_priority(HyRepo repo, int value)
Igor Gnatenko b45d89c
         repo->libsolv_repo->priority = -value;
Igor Gnatenko b45d89c
 }
Igor Gnatenko b45d89c
 
Igor Gnatenko b45d89c
+void
Igor Gnatenko b45d89c
+hy_repo_set_use_includes(HyRepo repo, gboolean enabled)
Igor Gnatenko b45d89c
+{
Igor Gnatenko b45d89c
+    repo->use_includes = enabled;
Igor Gnatenko b45d89c
+}
Igor Gnatenko b45d89c
+
Igor Gnatenko b45d89c
 void
Igor Gnatenko b45d89c
 hy_repo_set_string(HyRepo repo, int which, const char *str_val)
Igor Gnatenko b45d89c
 {
Igor Gnatenko b45d89c
diff --git a/libdnf/hy-repo.h b/libdnf/hy-repo.h
Igor Gnatenko b45d89c
index 3c19d09..d40a79b 100644
Igor Gnatenko b45d89c
--- a/libdnf/hy-repo.h
Igor Gnatenko b45d89c
+++ b/libdnf/hy-repo.h
Igor Gnatenko b45d89c
@@ -40,9 +40,11 @@ enum _hy_repo_param_e {
Igor Gnatenko b45d89c
 HyRepo hy_repo_create(const char *name);
Igor Gnatenko b45d89c
 int hy_repo_get_cost(HyRepo repo);
Igor Gnatenko b45d89c
 int hy_repo_get_priority(HyRepo repo);
Igor Gnatenko b45d89c
+gboolean hy_repo_get_use_includes(HyRepo repo);
Igor Gnatenko b45d89c
 guint hy_repo_get_n_solvables(HyRepo repo);
Igor Gnatenko b45d89c
 void hy_repo_set_cost(HyRepo repo, int value);
Igor Gnatenko b45d89c
 void hy_repo_set_priority(HyRepo repo, int value);
Igor Gnatenko b45d89c
+void hy_repo_set_use_includes(HyRepo repo, gboolean enabled);
Igor Gnatenko b45d89c
 void hy_repo_set_string(HyRepo repo, int which, const char *str_val);
Igor Gnatenko b45d89c
 const char *hy_repo_get_string(HyRepo repo, int which);
Igor Gnatenko b45d89c
 void hy_repo_free(HyRepo repo);
Igor Gnatenko b45d89c
diff --git a/python/hawkey/sack-py.c b/python/hawkey/sack-py.c
Igor Gnatenko b45d89c
index d70e65f..bb14c69 100644
Igor Gnatenko b45d89c
--- a/python/hawkey/sack-py.c
Igor Gnatenko b45d89c
+++ b/python/hawkey/sack-py.c
Igor Gnatenko b45d89c
@@ -446,6 +446,133 @@ add_includes(_SackObject *self, PyObject *seq)
Igor Gnatenko b45d89c
     Py_RETURN_NONE;
Igor Gnatenko b45d89c
 }
Igor Gnatenko b45d89c
 
Igor Gnatenko b45d89c
+static PyObject *
Igor Gnatenko b45d89c
+remove_excludes(_SackObject *self, PyObject *seq)
Igor Gnatenko b45d89c
+{
Igor Gnatenko b45d89c
+    DnfSack *sack = self->sack;
Igor Gnatenko b45d89c
+    DnfPackageSet *pset = pyseq_to_packageset(seq, sack);
Igor Gnatenko b45d89c
+    if (pset == NULL)
Igor Gnatenko b45d89c
+        return NULL;
Igor Gnatenko b45d89c
+    dnf_sack_remove_excludes(sack, pset);
Igor Gnatenko b45d89c
+    g_object_unref(pset);
Igor Gnatenko b45d89c
+    Py_RETURN_NONE;
Igor Gnatenko b45d89c
+}
Igor Gnatenko b45d89c
+
Igor Gnatenko b45d89c
+static PyObject *
Igor Gnatenko b45d89c
+remove_includes(_SackObject *self, PyObject *seq)
Igor Gnatenko b45d89c
+{
Igor Gnatenko b45d89c
+    DnfSack *sack = self->sack;
Igor Gnatenko b45d89c
+    DnfPackageSet *pset = pyseq_to_packageset(seq, sack);
Igor Gnatenko b45d89c
+    if (pset == NULL)
Igor Gnatenko b45d89c
+        return NULL;
Igor Gnatenko b45d89c
+    dnf_sack_remove_includes(sack, pset);
Igor Gnatenko b45d89c
+    g_object_unref(pset);
Igor Gnatenko b45d89c
+    Py_RETURN_NONE;
Igor Gnatenko b45d89c
+}
Igor Gnatenko b45d89c
+
Igor Gnatenko b45d89c
+static PyObject *
Igor Gnatenko b45d89c
+set_excludes(_SackObject *self, PyObject *seq)
Igor Gnatenko b45d89c
+{
Igor Gnatenko b45d89c
+    DnfSack *sack = self->sack;
Igor Gnatenko b45d89c
+    DnfPackageSet *pset = pyseq_to_packageset(seq, sack);
Igor Gnatenko b45d89c
+    if (pset == NULL)
Igor Gnatenko b45d89c
+        return NULL;
Igor Gnatenko b45d89c
+    dnf_sack_set_excludes(sack, pset);
Igor Gnatenko b45d89c
+    g_object_unref(pset);
Igor Gnatenko b45d89c
+    Py_RETURN_NONE;
Igor Gnatenko b45d89c
+}
Igor Gnatenko b45d89c
+
Igor Gnatenko b45d89c
+static PyObject *
Igor Gnatenko b45d89c
+set_includes(_SackObject *self, PyObject *seq)
Igor Gnatenko b45d89c
+{
Igor Gnatenko b45d89c
+    DnfSack *sack = self->sack;
Igor Gnatenko b45d89c
+    DnfPackageSet *pset = pyseq_to_packageset(seq, sack);
Igor Gnatenko b45d89c
+    if (pset == NULL)
Igor Gnatenko b45d89c
+        return NULL;
Igor Gnatenko b45d89c
+    dnf_sack_set_includes(sack, pset);
Igor Gnatenko b45d89c
+    g_object_unref(pset);
Igor Gnatenko b45d89c
+    Py_RETURN_NONE;
Igor Gnatenko b45d89c
+}
Igor Gnatenko b45d89c
+
Igor Gnatenko b45d89c
+static PyObject *
Igor Gnatenko b45d89c
+reset_excludes(_SackObject *self)
Igor Gnatenko b45d89c
+{
Igor Gnatenko b45d89c
+    DnfSack *sack = self->sack;
Igor Gnatenko b45d89c
+    dnf_sack_reset_excludes(sack);
Igor Gnatenko b45d89c
+    Py_RETURN_NONE;
Igor Gnatenko b45d89c
+}
Igor Gnatenko b45d89c
+
Igor Gnatenko b45d89c
+static PyObject *
Igor Gnatenko b45d89c
+reset_includes(_SackObject *self)
Igor Gnatenko b45d89c
+{
Igor Gnatenko b45d89c
+    DnfSack *sack = self->sack;
Igor Gnatenko b45d89c
+    dnf_sack_reset_includes(sack);
Igor Gnatenko b45d89c
+    Py_RETURN_NONE;
Igor Gnatenko b45d89c
+}
Igor Gnatenko b45d89c
+
Igor Gnatenko b45d89c
+static PyObject *
Igor Gnatenko b45d89c
+get_excludes(_SackObject *self)
Igor Gnatenko b45d89c
+{
Igor Gnatenko b45d89c
+    DnfSack *sack = self->sack;
Igor Gnatenko b45d89c
+    DnfPackageSet *pset = dnf_sack_get_excludes(sack);
Igor Gnatenko b45d89c
+    if (!pset)
Igor Gnatenko b45d89c
+        return PyList_New(0);
Igor Gnatenko b45d89c
+    return packageset_to_pylist(pset, (PyObject *)self);
Igor Gnatenko b45d89c
+}
Igor Gnatenko b45d89c
+
Igor Gnatenko b45d89c
+static PyObject *
Igor Gnatenko b45d89c
+get_includes(_SackObject *self)
Igor Gnatenko b45d89c
+{
Igor Gnatenko b45d89c
+    DnfSack *sack = self->sack;
Igor Gnatenko b45d89c
+    DnfPackageSet *pset = dnf_sack_get_includes(sack);
Igor Gnatenko b45d89c
+    if (!pset)
Igor Gnatenko b45d89c
+        return PyList_New(0);
Igor Gnatenko b45d89c
+    return packageset_to_pylist(pset, (PyObject *)self);
Igor Gnatenko b45d89c
+}
Igor Gnatenko b45d89c
+
Igor Gnatenko b45d89c
+static PyObject *
Igor Gnatenko b45d89c
+set_use_includes(_SackObject *self, PyObject *args)
Igor Gnatenko b45d89c
+{
Igor Gnatenko b45d89c
+    PyObject *py_enabled;
Igor Gnatenko b45d89c
+    const char *creponame = NULL;
Igor Gnatenko b45d89c
+    if (!PyArg_ParseTuple(args, "O!|z", &PyBool_Type, &py_enabled, &creponame))
Igor Gnatenko b45d89c
+        return NULL;
Igor Gnatenko b45d89c
+
Igor Gnatenko b45d89c
+    gboolean enabled = PyObject_IsTrue(py_enabled);
Igor Gnatenko b45d89c
+    if (!dnf_sack_set_use_includes(self->sack, creponame, enabled)) {
Igor Gnatenko b45d89c
+        PyErr_SetString(PyExc_ValueError, "Can't set use_includes for repo with given name.");
Igor Gnatenko b45d89c
+        return NULL;
Igor Gnatenko b45d89c
+    }
Igor Gnatenko b45d89c
+
Igor Gnatenko b45d89c
+    Py_RETURN_NONE;
Igor Gnatenko b45d89c
+}
Igor Gnatenko b45d89c
+
Igor Gnatenko b45d89c
+static PyObject *
Igor Gnatenko b45d89c
+get_use_includes(_SackObject *self, PyObject *reponame)
Igor Gnatenko b45d89c
+{
Igor Gnatenko b45d89c
+    DnfSack *sack = self->sack;
Igor Gnatenko b45d89c
+
Igor Gnatenko b45d89c
+    PyObject *tmp_py_str = NULL;
Igor Gnatenko b45d89c
+    const char *creponame = pycomp_get_string(reponame, &tmp_py_str);
Igor Gnatenko b45d89c
+    if (creponame == NULL) {
Igor Gnatenko b45d89c
+        Py_XDECREF(tmp_py_str);
Igor Gnatenko b45d89c
+        return NULL;
Igor Gnatenko b45d89c
+    }
Igor Gnatenko b45d89c
+
Igor Gnatenko b45d89c
+    gboolean enabled;
Igor Gnatenko b45d89c
+    if (!dnf_sack_get_use_includes(sack, creponame, &enabled)) {
Igor Gnatenko b45d89c
+        Py_XDECREF(tmp_py_str);
Igor Gnatenko b45d89c
+        PyErr_SetString(PyExc_ValueError, "Can't found repo with given name.");
Igor Gnatenko b45d89c
+        return NULL;
Igor Gnatenko b45d89c
+    }
Igor Gnatenko b45d89c
+
Igor Gnatenko b45d89c
+    Py_XDECREF(tmp_py_str);
Igor Gnatenko b45d89c
+    if (enabled)
Igor Gnatenko b45d89c
+        Py_RETURN_TRUE;
Igor Gnatenko b45d89c
+    else
Igor Gnatenko b45d89c
+        Py_RETURN_FALSE;
Igor Gnatenko b45d89c
+}
Igor Gnatenko b45d89c
+
Igor Gnatenko b45d89c
 static PyObject *
Igor Gnatenko b45d89c
 disable_repo(_SackObject *self, PyObject *reponame)
Igor Gnatenko b45d89c
 {
Igor Gnatenko b45d89c
@@ -569,6 +696,26 @@ PyMethodDef sack_methods[] = {
Igor Gnatenko b45d89c
      NULL},
Igor Gnatenko b45d89c
     {"add_includes", (PyCFunction)add_includes, METH_O,
Igor Gnatenko b45d89c
      NULL},
Igor Gnatenko b45d89c
+    {"remove_excludes", (PyCFunction)remove_excludes, METH_O,
Igor Gnatenko b45d89c
+     NULL},
Igor Gnatenko b45d89c
+    {"remove_includes", (PyCFunction)remove_includes, METH_O,
Igor Gnatenko b45d89c
+     NULL},
Igor Gnatenko b45d89c
+    {"set_excludes", (PyCFunction)set_excludes, METH_O,
Igor Gnatenko b45d89c
+     NULL},
Igor Gnatenko b45d89c
+    {"set_includes", (PyCFunction)set_includes, METH_O,
Igor Gnatenko b45d89c
+     NULL},
Igor Gnatenko b45d89c
+    {"reset_excludes", (PyCFunction)reset_excludes, METH_NOARGS,
Igor Gnatenko b45d89c
+     NULL},
Igor Gnatenko b45d89c
+    {"reset_includes", (PyCFunction)reset_includes, METH_NOARGS,
Igor Gnatenko b45d89c
+     NULL},
Igor Gnatenko b45d89c
+    {"get_excludes", (PyCFunction)get_excludes, METH_NOARGS,
Igor Gnatenko b45d89c
+     NULL},
Igor Gnatenko b45d89c
+    {"get_includes", (PyCFunction)get_includes, METH_NOARGS,
Igor Gnatenko b45d89c
+     NULL},
Igor Gnatenko b45d89c
+    {"set_use_includes", (PyCFunction)set_use_includes, METH_VARARGS,
Igor Gnatenko b45d89c
+     NULL},
Igor Gnatenko b45d89c
+    {"get_use_includes", (PyCFunction)get_use_includes, METH_O,
Igor Gnatenko b45d89c
+     NULL},
Igor Gnatenko b45d89c
     {"disable_repo", (PyCFunction)disable_repo, METH_O,
Igor Gnatenko b45d89c
      NULL},
Igor Gnatenko b45d89c
     {"enable_repo", (PyCFunction)enable_repo, METH_O,
Igor Gnatenko b45d89c
-- 
Igor Gnatenko b45d89c
2.14.1
Igor Gnatenko b45d89c