Blame SOURCES/0001-Add-module-enable-disable-reset-command.patch

1c6b90
From fa7e624c50dbfc0e47c0466e47f2f6acd20a6dff Mon Sep 17 00:00:00 2001
1c6b90
From: Jaroslav Rohel <jrohel@redhat.com>
1c6b90
Date: Fri, 30 Oct 2020 13:45:17 +0100
1c6b90
Subject: [PATCH 1/5] Add subcommands support
1c6b90
1c6b90
Plugins with a '_' character in command name will  implement subcommands.
1c6b90
Needed for modularity subcommands.
1c6b90
E.g. the "command_module_enable" plugin will implement the "enable"
1c6b90
subcommand of the "module" command.
1c6b90
---
1c6b90
 dnf/dnf-main.c | 96 +++++++++++++++++++++++++++++++++++++++-----------
1c6b90
 1 file changed, 76 insertions(+), 20 deletions(-)
1c6b90
1c6b90
diff --git a/dnf/dnf-main.c b/dnf/dnf-main.c
1c6b90
index b6a5a69..6cb8c0e 100644
1c6b90
--- a/dnf/dnf-main.c
1c6b90
+++ b/dnf/dnf-main.c
1c6b90
@@ -305,6 +305,33 @@ new_global_opt_group (DnfContext *ctx)
1c6b90
   return opt_grp;
1c6b90
 }
1c6b90
 
1c6b90
+/*
1c6b90
+ * The first non-option is the command/subcommand.
1c6b90
+ * Get it and remove it from arguments.
1c6b90
+ */
1c6b90
+static const gchar *
1c6b90
+get_command (int *argc,
1c6b90
+             char *argv[])
1c6b90
+{
1c6b90
+  const gchar *cmd_name = NULL;
1c6b90
+  for (gint in = 1; in < *argc; in++)
1c6b90
+    {
1c6b90
+      if (cmd_name != NULL)
1c6b90
+        argv[in-1] = argv[in];
1c6b90
+      else if (argv[in][0] != '-')
1c6b90
+        cmd_name = argv[in];
1c6b90
+    }
1c6b90
+  if (cmd_name != NULL) --*argc;
1c6b90
+  return cmd_name;
1c6b90
+}
1c6b90
+
1c6b90
+static gint
1c6b90
+compare_strings (gconstpointer a,
1c6b90
+                 gconstpointer b)
1c6b90
+{
1c6b90
+  return strcmp (a, b);
1c6b90
+}
1c6b90
+
1c6b90
 int
1c6b90
 main (int   argc,
1c6b90
       char *argv[])
1c6b90
@@ -316,6 +343,7 @@ main (int   argc,
1c6b90
   g_autoptr(GOptionContext) opt_ctx = g_option_context_new ("COMMAND");
1c6b90
   g_autoptr(GOptionContext) subcmd_opt_ctx = NULL;
1c6b90
   g_autofree gchar *subcmd_opt_param = NULL;
1c6b90
+  GSList *cmds_with_subcmds = NULL;  /* list of commands with subcommands */
1c6b90
 
1c6b90
   setlocale (LC_ALL, "");
1c6b90
 
1c6b90
@@ -353,11 +381,26 @@ main (int   argc,
1c6b90
       if (!peas_engine_load_plugin (engine, info))
1c6b90
         continue;
1c6b90
       if (peas_engine_provides_extension (engine, info, DNF_TYPE_COMMAND))
1c6b90
-        /*
1c6b90
-         * At least 2 spaces between the command and its description are needed
1c6b90
-         * so that help2man formats it correctly.
1c6b90
-         */
1c6b90
-        g_string_append_printf (cmd_summary, "\n  %-16s     %s", peas_plugin_info_get_name (info), peas_plugin_info_get_description (info));
1c6b90
+        {
1c6b90
+          g_autofree gchar *command_name = g_strdup (peas_plugin_info_get_name (info));
1c6b90
+
1c6b90
+          /* Plugins with a '_' character in command name implement subcommands.
1c6b90
+             E.g. the "command_module_enable" plugin implements the "enable" subcommand of the "module" command. */
1c6b90
+          for (gchar *ptr = command_name; *ptr != '\0'; ++ptr)
1c6b90
+            {
1c6b90
+              if (*ptr == '_')
1c6b90
+                {
1c6b90
+                  *ptr = ' ';
1c6b90
+                  cmds_with_subcmds = g_slist_append (cmds_with_subcmds, g_strndup (command_name, ptr - command_name));
1c6b90
+                  break;
1c6b90
+                }
1c6b90
+            }
1c6b90
+          /*
1c6b90
+           * At least 2 spaces between the command and its description are needed
1c6b90
+           * so that help2man formats it correctly.
1c6b90
+           */
1c6b90
+          g_string_append_printf (cmd_summary, "\n  %-16s     %s", command_name, peas_plugin_info_get_description (info));
1c6b90
+        }
1c6b90
     }
1c6b90
   g_option_context_set_summary (opt_ctx, cmd_summary->str);
1c6b90
   g_string_free (cmd_summary, TRUE);
1c6b90
@@ -471,19 +514,7 @@ main (int   argc,
1c6b90
         }
1c6b90
     }
1c6b90
 
1c6b90
-  /*
1c6b90
-   * The first non-option is the command.
1c6b90
-   * Get it and remove it from arguments.
1c6b90
-   */
1c6b90
-  const gchar *cmd_name = NULL;
1c6b90
-  for (gint in = 1; in < argc; in++)
1c6b90
-    {
1c6b90
-      if (cmd_name != NULL)
1c6b90
-        argv[in-1] = argv[in];
1c6b90
-      else if (argv[in][0] != '-')
1c6b90
-        cmd_name = argv[in];
1c6b90
-    }
1c6b90
-  if (cmd_name != NULL) --argc;
1c6b90
+  const gchar *cmd_name = get_command (&argc, argv);
1c6b90
 
1c6b90
   g_option_context_set_help_enabled (opt_ctx, TRUE);
1c6b90
 
1c6b90
@@ -500,10 +531,25 @@ main (int   argc,
1c6b90
 
1c6b90
   PeasPluginInfo *plug = NULL;
1c6b90
   PeasExtension *exten = NULL;
1c6b90
-  if (cmd_name != NULL)
1c6b90
+  const gchar *subcmd_name = NULL;
1c6b90
+  gboolean with_subcmds = FALSE;
1c6b90
+
1c6b90
+  /* Find the plugin that implements the command cmd_name or its subcommand.
1c6b90
+   * Command name (cmd_name) can not contain '_' character. It is reserved for subcomands. */
1c6b90
+  if (cmd_name != NULL && strchr(cmd_name, '_') == NULL)
1c6b90
     {
1c6b90
+      with_subcmds = g_slist_find_custom (cmds_with_subcmds, cmd_name, compare_strings) != NULL;
1c6b90
       g_autofree gchar *mod_name = g_strdup_printf ("command_%s", cmd_name);
1c6b90
       plug = peas_engine_get_plugin_info (engine, mod_name);
1c6b90
+      if (plug == NULL && with_subcmds)
1c6b90
+        {
1c6b90
+          subcmd_name = get_command (&argc, argv);
1c6b90
+          if (subcmd_name != NULL)
1c6b90
+            {
1c6b90
+              g_autofree gchar *submod_name = g_strdup_printf ("command_%s_%s", cmd_name, subcmd_name);
1c6b90
+              plug = peas_engine_get_plugin_info (engine, submod_name);
1c6b90
+            }
1c6b90
+        }
1c6b90
       if (plug != NULL)
1c6b90
         exten = peas_extension_set_get_extension (cmd_exts, plug);
1c6b90
     }
1c6b90
@@ -513,10 +559,18 @@ main (int   argc,
1c6b90
         error = g_error_new_literal (G_IO_ERROR,
1c6b90
                                      G_IO_ERROR_FAILED,
1c6b90
                                      "No command specified");
1c6b90
-      else
1c6b90
+      else if (!with_subcmds)
1c6b90
         error = g_error_new (G_IO_ERROR,
1c6b90
                              G_IO_ERROR_FAILED,
1c6b90
                              "Unknown command: '%s'", cmd_name);
1c6b90
+      else if (subcmd_name)
1c6b90
+        error = g_error_new (G_IO_ERROR,
1c6b90
+                             G_IO_ERROR_FAILED,
1c6b90
+                             "Unknown subcommand: '%s'", subcmd_name);
1c6b90
+      else
1c6b90
+        error = g_error_new (G_IO_ERROR,
1c6b90
+                             G_IO_ERROR_FAILED,
1c6b90
+                             "Missing subcommand for command: '%s'", cmd_name);
1c6b90
 
1c6b90
       g_autofree gchar *help = g_option_context_get_help (opt_ctx, TRUE, NULL);
1c6b90
       g_printerr ("This is microdnf, which implements subset of `dnf'.\n"
1c6b90
@@ -533,6 +587,8 @@ main (int   argc,
1c6b90
     goto out;
1c6b90
 
1c6b90
 out:
1c6b90
+  g_slist_free_full(cmds_with_subcmds, g_free);
1c6b90
+
1c6b90
   if (error != NULL)
1c6b90
     {
1c6b90
       const gchar *prefix = "";
1c6b90
-- 
1c6b90
2.26.2
1c6b90
1c6b90
1c6b90
From 88a2b95ebdc424091b93c381623bdb458a368b48 Mon Sep 17 00:00:00 2001
1c6b90
From: Jaroslav Rohel <jrohel@redhat.com>
1c6b90
Date: Fri, 30 Oct 2020 14:16:34 +0100
1c6b90
Subject: [PATCH 2/5] Add "module enable" command
1c6b90
1c6b90
---
1c6b90
 dnf/CMakeLists.txt                            |  9 +-
1c6b90
 dnf/meson.build                               |  9 ++
1c6b90
 .../module_enable/dnf-command-module_enable.c | 97 +++++++++++++++++++
1c6b90
 .../dnf-command-module_enable.gresource.xml   |  6 ++
1c6b90
 .../module_enable/dnf-command-module_enable.h | 33 +++++++
1c6b90
 .../module_enable/module_enable.plugin        |  9 ++
1c6b90
 microdnf.spec                                 |  2 +-
1c6b90
 7 files changed, 163 insertions(+), 2 deletions(-)
1c6b90
 create mode 100644 dnf/plugins/module_enable/dnf-command-module_enable.c
1c6b90
 create mode 100644 dnf/plugins/module_enable/dnf-command-module_enable.gresource.xml
1c6b90
 create mode 100644 dnf/plugins/module_enable/dnf-command-module_enable.h
1c6b90
 create mode 100644 dnf/plugins/module_enable/module_enable.plugin
1c6b90
1c6b90
diff --git a/dnf/CMakeLists.txt b/dnf/CMakeLists.txt
1c6b90
index 0705390..b673ce4 100644
1c6b90
--- a/dnf/CMakeLists.txt
1c6b90
+++ b/dnf/CMakeLists.txt
1c6b90
@@ -35,6 +35,12 @@ glib_compile_resources (DNF_COMMAND_CLEAN plugins/clean/dnf-command-clean.gresou
1c6b90
                         INTERNAL)
1c6b90
 list (APPEND DNF_COMMAND_CLEAN "plugins/clean/dnf-command-clean.c")
1c6b90
 
1c6b90
+glib_compile_resources (DNF_COMMAND_MODULE_ENABLE plugins/module_enable/dnf-command-module_enable.gresource.xml
1c6b90
+                        C_PREFIX dnf_command_module_enable
1c6b90
+                        INTERNAL)
1c6b90
+list (APPEND DNF_COMMAND_MODULE_ENABLE "plugins/module_enable/dnf-command-module_enable.c")
1c6b90
+
1c6b90
+
1c6b90
 include_directories (${CMAKE_CURRENT_SOURCE_DIR})
1c6b90
 add_executable (microdnf dnf-main.c ${DNF_SRCS}
1c6b90
                 ${DNF_COMMAND_INSTALL}
1c6b90
@@ -43,7 +49,8 @@ add_executable (microdnf dnf-main.c ${DNF_SRCS}
1c6b90
                 ${DNF_COMMAND_UPDATE}
1c6b90
                 ${DNF_COMMAND_REPOLIST}
1c6b90
                 ${DNF_COMMAND_REPOQUERY}
1c6b90
-                ${DNF_COMMAND_CLEAN})
1c6b90
+                ${DNF_COMMAND_CLEAN}
1c6b90
+                ${DNF_COMMAND_MODULE_ENABLE})
1c6b90
 
1c6b90
 target_link_libraries (microdnf
1c6b90
                        ${GLIB_LIBRARIES}
1c6b90
diff --git a/dnf/meson.build b/dnf/meson.build
1c6b90
index 12e11ac..d617453 100644
1c6b90
--- a/dnf/meson.build
1c6b90
+++ b/dnf/meson.build
1c6b90
@@ -65,6 +65,15 @@ microdnf_srcs = [
1c6b90
     source_dir : 'plugins/clean',
1c6b90
   ),
1c6b90
   'plugins/clean/dnf-command-clean.c',
1c6b90
+
1c6b90
+  # module enable
1c6b90
+  gnome.compile_resources(
1c6b90
+    'dnf-module_enable',
1c6b90
+    'plugins/module_enable/dnf-command-module_enable.gresource.xml',
1c6b90
+    c_name : 'dnf_command_module_enable',
1c6b90
+    source_dir : 'plugins/module_enable',
1c6b90
+  ),
1c6b90
+  'plugins/module_enable/dnf-command-module_enable.c',
1c6b90
 ]
1c6b90
 
1c6b90
 microdnf = executable(
1c6b90
diff --git a/dnf/plugins/module_enable/dnf-command-module_enable.c b/dnf/plugins/module_enable/dnf-command-module_enable.c
1c6b90
new file mode 100644
1c6b90
index 0000000..3081042
1c6b90
--- /dev/null
1c6b90
+++ b/dnf/plugins/module_enable/dnf-command-module_enable.c
1c6b90
@@ -0,0 +1,97 @@
1c6b90
+/*
1c6b90
+ * Copyright (C) 2020 Red Hat, Inc.
1c6b90
+ *
1c6b90
+ * Licensed under the GNU Lesser General Public License Version 2.1
1c6b90
+ *
1c6b90
+ * This library is free software; you can redistribute it and/or
1c6b90
+ * modify it under the terms of the GNU Lesser General Public
1c6b90
+ * License as published by the Free Software Foundation; either
1c6b90
+ * version 2.1 of the License, or (at your option) any later version.
1c6b90
+ *
1c6b90
+ * This library is distributed in the hope that it will be useful,
1c6b90
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1c6b90
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1c6b90
+ * Lesser General Public License for more details.
1c6b90
+ *
1c6b90
+ * You should have received a copy of the GNU Lesser General Public
1c6b90
+ * License along with this library; if not, write to the Free Software
1c6b90
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
1c6b90
+ */
1c6b90
+
1c6b90
+#include "dnf-command-module_enable.h"
1c6b90
+#include "dnf-utils.h"
1c6b90
+
1c6b90
+struct _DnfCommandModuleEnable
1c6b90
+{
1c6b90
+  PeasExtensionBase parent_instance;
1c6b90
+};
1c6b90
+
1c6b90
+static void dnf_command_module_enable_iface_init (DnfCommandInterface *iface);
1c6b90
+
1c6b90
+G_DEFINE_DYNAMIC_TYPE_EXTENDED (DnfCommandModuleEnable,
1c6b90
+                                dnf_command_module_enable,
1c6b90
+                                PEAS_TYPE_EXTENSION_BASE,
1c6b90
+                                0,
1c6b90
+                                G_IMPLEMENT_INTERFACE (DNF_TYPE_COMMAND,
1c6b90
+                                                       dnf_command_module_enable_iface_init))
1c6b90
+
1c6b90
+static void
1c6b90
+dnf_command_module_enable_init (DnfCommandModuleEnable *self)
1c6b90
+{
1c6b90
+}
1c6b90
+
1c6b90
+static gboolean
1c6b90
+dnf_command_module_enable_run (DnfCommand      *cmd,
1c6b90
+                               int              argc,
1c6b90
+                               char            *argv[],
1c6b90
+                               GOptionContext  *opt_ctx,
1c6b90
+                               DnfContext      *ctx,
1c6b90
+                               GError         **error)
1c6b90
+{
1c6b90
+  g_auto(GStrv) pkgs = NULL;
1c6b90
+  const GOptionEntry opts[] = {
1c6b90
+    { G_OPTION_REMAINING, '\0', 0, G_OPTION_ARG_STRING_ARRAY, &pkgs, NULL, NULL },
1c6b90
+    { NULL }
1c6b90
+  };
1c6b90
+  g_option_context_add_main_entries (opt_ctx, opts, NULL);
1c6b90
+
1c6b90
+  if (!g_option_context_parse (opt_ctx, &argc, &argv, error))
1c6b90
+    return FALSE;
1c6b90
+
1c6b90
+  if (pkgs == NULL)
1c6b90
+    {
1c6b90
+      g_set_error_literal (error,
1c6b90
+                           G_IO_ERROR,
1c6b90
+                           G_IO_ERROR_FAILED,
1c6b90
+                           "Modules are not specified");
1c6b90
+      return FALSE;
1c6b90
+    }
1c6b90
+
1c6b90
+    return dnf_context_enable_modules (ctx, (const char **)pkgs, error);
1c6b90
+}
1c6b90
+
1c6b90
+static void
1c6b90
+dnf_command_module_enable_class_init (DnfCommandModuleEnableClass *klass)
1c6b90
+{
1c6b90
+}
1c6b90
+
1c6b90
+static void
1c6b90
+dnf_command_module_enable_iface_init (DnfCommandInterface *iface)
1c6b90
+{
1c6b90
+  iface->run = dnf_command_module_enable_run;
1c6b90
+}
1c6b90
+
1c6b90
+static void
1c6b90
+dnf_command_module_enable_class_finalize (DnfCommandModuleEnableClass *klass)
1c6b90
+{
1c6b90
+}
1c6b90
+
1c6b90
+G_MODULE_EXPORT void
1c6b90
+dnf_command_module_enable_register_types (PeasObjectModule *module)
1c6b90
+{
1c6b90
+  dnf_command_module_enable_register_type (G_TYPE_MODULE (module));
1c6b90
+
1c6b90
+  peas_object_module_register_extension_type (module,
1c6b90
+                                              DNF_TYPE_COMMAND,
1c6b90
+                                              DNF_TYPE_COMMAND_MODULE_ENABLE);
1c6b90
+}
1c6b90
diff --git a/dnf/plugins/module_enable/dnf-command-module_enable.gresource.xml b/dnf/plugins/module_enable/dnf-command-module_enable.gresource.xml
1c6b90
new file mode 100644
1c6b90
index 0000000..4b99047
1c6b90
--- /dev/null
1c6b90
+++ b/dnf/plugins/module_enable/dnf-command-module_enable.gresource.xml
1c6b90
@@ -0,0 +1,6 @@
1c6b90
+
1c6b90
+<gresources>
1c6b90
+  <gresource prefix="/org/fedoraproject/dnf/plugins/module_enable">
1c6b90
+    <file>module_enable.plugin</file>
1c6b90
+  </gresource>
1c6b90
+</gresources>
1c6b90
diff --git a/dnf/plugins/module_enable/dnf-command-module_enable.h b/dnf/plugins/module_enable/dnf-command-module_enable.h
1c6b90
new file mode 100644
1c6b90
index 0000000..d489331
1c6b90
--- /dev/null
1c6b90
+++ b/dnf/plugins/module_enable/dnf-command-module_enable.h
1c6b90
@@ -0,0 +1,33 @@
1c6b90
+/*
1c6b90
+ * Copyright (C) 2020 Red Hat, Inc.
1c6b90
+ *
1c6b90
+ * Licensed under the GNU Lesser General Public License Version 2.1
1c6b90
+ *
1c6b90
+ * This library is free software; you can redistribute it and/or
1c6b90
+ * modify it under the terms of the GNU Lesser General Public
1c6b90
+ * License as published by the Free Software Foundation; either
1c6b90
+ * version 2.1 of the License, or (at your option) any later version.
1c6b90
+ *
1c6b90
+ * This library is distributed in the hope that it will be useful,
1c6b90
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1c6b90
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1c6b90
+ * Lesser General Public License for more details.
1c6b90
+ *
1c6b90
+ * You should have received a copy of the GNU Lesser General Public
1c6b90
+ * License along with this library; if not, write to the Free Software
1c6b90
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
1c6b90
+ */
1c6b90
+
1c6b90
+#pragma once
1c6b90
+
1c6b90
+#include "dnf-command.h"
1c6b90
+#include <libpeas/peas.h>
1c6b90
+
1c6b90
+G_BEGIN_DECLS
1c6b90
+
1c6b90
+#define DNF_TYPE_COMMAND_MODULE_ENABLE dnf_command_module_enable_get_type ()
1c6b90
+G_DECLARE_FINAL_TYPE (DnfCommandModuleEnable, dnf_command_module_enable, DNF, COMMAND_MODULE_ENABLE, PeasExtensionBase)
1c6b90
+
1c6b90
+G_MODULE_EXPORT void dnf_command_module_enable_register_types (PeasObjectModule *module);
1c6b90
+
1c6b90
+G_END_DECLS
1c6b90
diff --git a/dnf/plugins/module_enable/module_enable.plugin b/dnf/plugins/module_enable/module_enable.plugin
1c6b90
new file mode 100644
1c6b90
index 0000000..91da9fb
1c6b90
--- /dev/null
1c6b90
+++ b/dnf/plugins/module_enable/module_enable.plugin
1c6b90
@@ -0,0 +1,9 @@
1c6b90
+[Plugin]
1c6b90
+Module = command_module_enable
1c6b90
+Embedded = dnf_command_module_enable_register_types
1c6b90
+Name = module_enable
1c6b90
+Description = Enable a module stream
1c6b90
+Authors = Jaroslav Rohel <jrohel@redhat.com>
1c6b90
+License = GPL-3.0+
1c6b90
+Copyright = Copyright (C) 2020 Red Hat, Inc.
1c6b90
+X-Command-Syntax = module enable module-spec [module-spec…]
1c6b90
diff --git a/microdnf.spec b/microdnf.spec
1c6b90
index db8e35e..3648e46 100644
1c6b90
--- a/microdnf.spec
1c6b90
+++ b/microdnf.spec
1c6b90
@@ -1,4 +1,4 @@
1c6b90
-%global libdnf_version 0.43.1
1c6b90
+%global libdnf_version 0.55.0
1c6b90
 
1c6b90
 Name:           microdnf
1c6b90
 Version:        3.4.0
1c6b90
-- 
1c6b90
2.26.2
1c6b90
1c6b90
1c6b90
From 7cc7bb7202cb79d6bb6daa63e32109134c273627 Mon Sep 17 00:00:00 2001
1c6b90
From: Jaroslav Mracek <jmracek@redhat.com>
1c6b90
Date: Fri, 23 Oct 2020 16:04:48 +0200
1c6b90
Subject: [PATCH 3/5] Add reports of module changes
1c6b90
1c6b90
---
1c6b90
 dnf/dnf-utils.c | 16 ++++++++++++++--
1c6b90
 1 file changed, 14 insertions(+), 2 deletions(-)
1c6b90
1c6b90
diff --git a/dnf/dnf-utils.c b/dnf/dnf-utils.c
1c6b90
index c58f519..5984f22 100644
1c6b90
--- a/dnf/dnf-utils.c
1c6b90
+++ b/dnf/dnf-utils.c
1c6b90
@@ -68,8 +68,15 @@ dnf_utils_print_transaction (DnfContext *ctx)
1c6b90
 
1c6b90
   if (pkgs->len == 0)
1c6b90
     {
1c6b90
-      g_print ("Nothing to do.\n");
1c6b90
-      return FALSE;
1c6b90
+      g_autofree char * report = dnf_context_get_module_report (ctx);
1c6b90
+      if (report)
1c6b90
+        {
1c6b90
+          g_print ("%s\n", report);
1c6b90
+          return TRUE;
1c6b90
+        } else {
1c6b90
+          g_print ("Nothing to do.\n");
1c6b90
+          return FALSE;
1c6b90
+        }
1c6b90
     }
1c6b90
 
1c6b90
   struct libscols_line *ln;
1c6b90
@@ -147,6 +154,11 @@ dnf_utils_print_transaction (DnfContext *ctx)
1c6b90
   g_print (" %-15s %4d packages\n", "Removing:", pkgs_remove->len);
1c6b90
   g_print (" %-15s %4d packages\n", "Downgrading:", pkgs_downgrade->len);
1c6b90
 
1c6b90
+  g_autofree char * report = dnf_context_get_module_report (ctx);
1c6b90
+  if (report)
1c6b90
+    {
1c6b90
+      g_print ("%s\n", report);
1c6b90
+    }
1c6b90
   /* check for test mode */
1c6b90
   DnfTransaction *txn = dnf_context_get_transaction (ctx);
1c6b90
   if (dnf_transaction_get_flags (txn) & DNF_TRANSACTION_FLAG_TEST)
1c6b90
-- 
1c6b90
2.26.2
1c6b90
1c6b90
1c6b90
From 6c4dceac5012231923187c3bbb16de4bda23789c Mon Sep 17 00:00:00 2001
1c6b90
From: Jaroslav Mracek <jmracek@redhat.com>
1c6b90
Date: Mon, 2 Nov 2020 12:05:01 +0100
1c6b90
Subject: [PATCH 4/5] Allow to commit module changes and report module switch
1c6b90
 as an error
1c6b90
1c6b90
---
1c6b90
 .../module_enable/dnf-command-module_enable.c | 28 ++++++++++++++++++-
1c6b90
 1 file changed, 27 insertions(+), 1 deletion(-)
1c6b90
1c6b90
diff --git a/dnf/plugins/module_enable/dnf-command-module_enable.c b/dnf/plugins/module_enable/dnf-command-module_enable.c
1c6b90
index 3081042..a5a4701 100644
1c6b90
--- a/dnf/plugins/module_enable/dnf-command-module_enable.c
1c6b90
+++ b/dnf/plugins/module_enable/dnf-command-module_enable.c
1c6b90
@@ -67,7 +67,33 @@ dnf_command_module_enable_run (DnfCommand      *cmd,
1c6b90
       return FALSE;
1c6b90
     }
1c6b90
 
1c6b90
-    return dnf_context_enable_modules (ctx, (const char **)pkgs, error);
1c6b90
+  if (!dnf_context_module_enable (ctx, (const char **)pkgs, error))
1c6b90
+    {
1c6b90
+      return FALSE;
1c6b90
+    }
1c6b90
+  if (!dnf_context_module_switched_check (ctx, error))
1c6b90
+    {
1c6b90
+      return FALSE;
1c6b90
+    }
1c6b90
+
1c6b90
+  if (!dnf_goal_depsolve (dnf_context_get_goal (ctx), DNF_NONE, error))
1c6b90
+    {
1c6b90
+      if (g_error_matches (*error, DNF_ERROR, DNF_ERROR_NO_PACKAGES_TO_UPDATE))
1c6b90
+        {
1c6b90
+          g_clear_error (error);
1c6b90
+        } else {
1c6b90
+          return FALSE;
1c6b90
+        }
1c6b90
+    }
1c6b90
+  if (!dnf_utils_print_transaction (ctx))
1c6b90
+    {
1c6b90
+      return TRUE;
1c6b90
+    }
1c6b90
+  if (!dnf_context_run (ctx, NULL, error))
1c6b90
+    {
1c6b90
+      return FALSE;
1c6b90
+    }
1c6b90
+  return TRUE;
1c6b90
 }
1c6b90
 
1c6b90
 static void
1c6b90
-- 
1c6b90
2.26.2
1c6b90
1c6b90
1c6b90
From 6c86306c9c0725c73c3d4ec704f932e372e09585 Mon Sep 17 00:00:00 2001
1c6b90
From: Jaroslav Mracek <jmracek@redhat.com>
1c6b90
Date: Mon, 2 Nov 2020 15:17:29 +0100
1c6b90
Subject: [PATCH 5/5] Add module enable and disable commands
1c6b90
1c6b90
---
1c6b90
 dnf/CMakeLists.txt                            |  14 +-
1c6b90
 dnf/meson.build                               |  18 +++
1c6b90
 .../dnf-command-module_disable.c              | 119 +++++++++++++++++
1c6b90
 .../dnf-command-module_disable.gresource.xml  |   6 +
1c6b90
 .../dnf-command-module_disable.h              |  33 +++++
1c6b90
 .../module_disable/module_disable.plugin      |   9 ++
1c6b90
 .../module_reset/dnf-command-module_reset.c   | 123 ++++++++++++++++++
1c6b90
 .../dnf-command-module_reset.gresource.xml    |   6 +
1c6b90
 .../module_reset/dnf-command-module_reset.h   |  33 +++++
1c6b90
 dnf/plugins/module_reset/module_reset.plugin  |   9 ++
1c6b90
 10 files changed, 369 insertions(+), 1 deletion(-)
1c6b90
 create mode 100644 dnf/plugins/module_disable/dnf-command-module_disable.c
1c6b90
 create mode 100644 dnf/plugins/module_disable/dnf-command-module_disable.gresource.xml
1c6b90
 create mode 100644 dnf/plugins/module_disable/dnf-command-module_disable.h
1c6b90
 create mode 100644 dnf/plugins/module_disable/module_disable.plugin
1c6b90
 create mode 100644 dnf/plugins/module_reset/dnf-command-module_reset.c
1c6b90
 create mode 100644 dnf/plugins/module_reset/dnf-command-module_reset.gresource.xml
1c6b90
 create mode 100644 dnf/plugins/module_reset/dnf-command-module_reset.h
1c6b90
 create mode 100644 dnf/plugins/module_reset/module_reset.plugin
1c6b90
1c6b90
diff --git a/dnf/CMakeLists.txt b/dnf/CMakeLists.txt
1c6b90
index b673ce4..1d640be 100644
1c6b90
--- a/dnf/CMakeLists.txt
1c6b90
+++ b/dnf/CMakeLists.txt
1c6b90
@@ -40,6 +40,16 @@ glib_compile_resources (DNF_COMMAND_MODULE_ENABLE plugins/module_enable/dnf-comm
1c6b90
                         INTERNAL)
1c6b90
 list (APPEND DNF_COMMAND_MODULE_ENABLE "plugins/module_enable/dnf-command-module_enable.c")
1c6b90
 
1c6b90
+glib_compile_resources (DNF_COMMAND_MODULE_DISABLE plugins/module_disable/dnf-command-module_disable.gresource.xml
1c6b90
+                        C_PREFIX dnf_command_module_disable
1c6b90
+                        INTERNAL)
1c6b90
+list (APPEND DNF_COMMAND_MODULE_DISABLE "plugins/module_disable/dnf-command-module_disable.c")
1c6b90
+
1c6b90
+glib_compile_resources (DNF_COMMAND_MODULE_RESET plugins/module_reset/dnf-command-module_reset.gresource.xml
1c6b90
+                        C_PREFIX dnf_command_module_reset
1c6b90
+                        INTERNAL)
1c6b90
+list (APPEND DNF_COMMAND_MODULE_RESET "plugins/module_reset/dnf-command-module_reset.c")
1c6b90
+
1c6b90
 
1c6b90
 include_directories (${CMAKE_CURRENT_SOURCE_DIR})
1c6b90
 add_executable (microdnf dnf-main.c ${DNF_SRCS}
1c6b90
@@ -50,7 +60,9 @@ add_executable (microdnf dnf-main.c ${DNF_SRCS}
1c6b90
                 ${DNF_COMMAND_REPOLIST}
1c6b90
                 ${DNF_COMMAND_REPOQUERY}
1c6b90
                 ${DNF_COMMAND_CLEAN}
1c6b90
-                ${DNF_COMMAND_MODULE_ENABLE})
1c6b90
+                ${DNF_COMMAND_MODULE_ENABLE}
1c6b90
+                ${DNF_COMMAND_MODULE_DISABLE}
1c6b90
+                ${DNF_COMMAND_MODULE_RESET})
1c6b90
 
1c6b90
 target_link_libraries (microdnf
1c6b90
                        ${GLIB_LIBRARIES}
1c6b90
diff --git a/dnf/meson.build b/dnf/meson.build
1c6b90
index d617453..b456202 100644
1c6b90
--- a/dnf/meson.build
1c6b90
+++ b/dnf/meson.build
1c6b90
@@ -74,6 +74,24 @@ microdnf_srcs = [
1c6b90
     source_dir : 'plugins/module_enable',
1c6b90
   ),
1c6b90
   'plugins/module_enable/dnf-command-module_enable.c',
1c6b90
+
1c6b90
+  # module disable
1c6b90
+  gnome.compile_resources(
1c6b90
+    'dnf-module_disable',
1c6b90
+    'plugins/module_disable/dnf-command-module_disable.gresource.xml',
1c6b90
+    c_name : 'dnf_command_module_disable',
1c6b90
+    source_dir : 'plugins/module_disable',
1c6b90
+  ),
1c6b90
+  'plugins/module_disable/dnf-command-module_disable.c',
1c6b90
+
1c6b90
+  # module reset
1c6b90
+  gnome.compile_resources(
1c6b90
+    'dnf-module_reset',
1c6b90
+    'plugins/module_reset/dnf-command-module_reset.gresource.xml',
1c6b90
+    c_name : 'dnf_command_module_reset',
1c6b90
+    source_dir : 'plugins/module_reset',
1c6b90
+  ),
1c6b90
+  'plugins/module_reset/dnf-command-module_reset.c',
1c6b90
 ]
1c6b90
 
1c6b90
 microdnf = executable(
1c6b90
diff --git a/dnf/plugins/module_disable/dnf-command-module_disable.c b/dnf/plugins/module_disable/dnf-command-module_disable.c
1c6b90
new file mode 100644
1c6b90
index 0000000..eedb77c
1c6b90
--- /dev/null
1c6b90
+++ b/dnf/plugins/module_disable/dnf-command-module_disable.c
1c6b90
@@ -0,0 +1,119 @@
1c6b90
+/*
1c6b90
+ * Copyright (C) 2020 Red Hat, Inc.
1c6b90
+ *
1c6b90
+ * Licensed under the GNU Lesser General Public License Version 2.1
1c6b90
+ *
1c6b90
+ * This library is free software; you can redistribute it and/or
1c6b90
+ * modify it under the terms of the GNU Lesser General Public
1c6b90
+ * License as published by the Free Software Foundation; either
1c6b90
+ * version 2.1 of the License, or (at your option) any later version.
1c6b90
+ *
1c6b90
+ * This library is distributed in the hope that it will be useful,
1c6b90
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1c6b90
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1c6b90
+ * Lesser General Public License for more details.
1c6b90
+ *
1c6b90
+ * You should have received a copy of the GNU Lesser General Public
1c6b90
+ * License along with this library; if not, write to the Free Software
1c6b90
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
1c6b90
+ */
1c6b90
+
1c6b90
+#include "dnf-command-module_disable.h"
1c6b90
+#include "dnf-utils.h"
1c6b90
+
1c6b90
+struct _DnfCommandModuleDisable
1c6b90
+{
1c6b90
+  PeasExtensionBase parent_instance;
1c6b90
+};
1c6b90
+
1c6b90
+static void dnf_command_module_disable_iface_init (DnfCommandInterface *iface);
1c6b90
+
1c6b90
+G_DEFINE_DYNAMIC_TYPE_EXTENDED (DnfCommandModuleDisable,
1c6b90
+                                dnf_command_module_disable,
1c6b90
+                                PEAS_TYPE_EXTENSION_BASE,
1c6b90
+                                0,
1c6b90
+                                G_IMPLEMENT_INTERFACE (DNF_TYPE_COMMAND,
1c6b90
+                                                       dnf_command_module_disable_iface_init))
1c6b90
+
1c6b90
+static void
1c6b90
+dnf_command_module_disable_init (DnfCommandModuleDisable *self)
1c6b90
+{
1c6b90
+}
1c6b90
+
1c6b90
+static gboolean
1c6b90
+dnf_command_module_disable_run (DnfCommand      *cmd,
1c6b90
+                               int              argc,
1c6b90
+                               char            *argv[],
1c6b90
+                               GOptionContext  *opt_ctx,
1c6b90
+                               DnfContext      *ctx,
1c6b90
+                               GError         **error)
1c6b90
+{
1c6b90
+  g_auto(GStrv) pkgs = NULL;
1c6b90
+  const GOptionEntry opts[] = {
1c6b90
+    { G_OPTION_REMAINING, '\0', 0, G_OPTION_ARG_STRING_ARRAY, &pkgs, NULL, NULL },
1c6b90
+    { NULL }
1c6b90
+  };
1c6b90
+  g_option_context_add_main_entries (opt_ctx, opts, NULL);
1c6b90
+
1c6b90
+  if (!g_option_context_parse (opt_ctx, &argc, &argv, error))
1c6b90
+    return FALSE;
1c6b90
+
1c6b90
+  if (pkgs == NULL)
1c6b90
+    {
1c6b90
+      g_set_error_literal (error,
1c6b90
+                           G_IO_ERROR,
1c6b90
+                           G_IO_ERROR_FAILED,
1c6b90
+                           "Modules are not specified");
1c6b90
+      return FALSE;
1c6b90
+    }
1c6b90
+
1c6b90
+  if (!dnf_context_module_disable (ctx, (const char **)pkgs, error))
1c6b90
+    {
1c6b90
+      return FALSE;
1c6b90
+    }
1c6b90
+
1c6b90
+  if (!dnf_goal_depsolve (dnf_context_get_goal (ctx), DNF_NONE, error))
1c6b90
+    {
1c6b90
+      if (g_error_matches (*error, DNF_ERROR, DNF_ERROR_NO_PACKAGES_TO_UPDATE))
1c6b90
+        {
1c6b90
+          g_clear_error (error);
1c6b90
+        } else {
1c6b90
+          return FALSE;
1c6b90
+        }
1c6b90
+    }
1c6b90
+  if (!dnf_utils_print_transaction (ctx))
1c6b90
+    {
1c6b90
+      return TRUE;
1c6b90
+    }
1c6b90
+  if (!dnf_context_run (ctx, NULL, error))
1c6b90
+    {
1c6b90
+      return FALSE;
1c6b90
+    }
1c6b90
+  return TRUE;
1c6b90
+}
1c6b90
+
1c6b90
+static void
1c6b90
+dnf_command_module_disable_class_init (DnfCommandModuleDisableClass *klass)
1c6b90
+{
1c6b90
+}
1c6b90
+
1c6b90
+static void
1c6b90
+dnf_command_module_disable_iface_init (DnfCommandInterface *iface)
1c6b90
+{
1c6b90
+  iface->run = dnf_command_module_disable_run;
1c6b90
+}
1c6b90
+
1c6b90
+static void
1c6b90
+dnf_command_module_disable_class_finalize (DnfCommandModuleDisableClass *klass)
1c6b90
+{
1c6b90
+}
1c6b90
+
1c6b90
+G_MODULE_EXPORT void
1c6b90
+dnf_command_module_disable_register_types (PeasObjectModule *module)
1c6b90
+{
1c6b90
+  dnf_command_module_disable_register_type (G_TYPE_MODULE (module));
1c6b90
+
1c6b90
+  peas_object_module_register_extension_type (module,
1c6b90
+                                              DNF_TYPE_COMMAND,
1c6b90
+                                              DNF_TYPE_COMMAND_MODULE_DISABLE);
1c6b90
+}
1c6b90
diff --git a/dnf/plugins/module_disable/dnf-command-module_disable.gresource.xml b/dnf/plugins/module_disable/dnf-command-module_disable.gresource.xml
1c6b90
new file mode 100644
1c6b90
index 0000000..50a1295
1c6b90
--- /dev/null
1c6b90
+++ b/dnf/plugins/module_disable/dnf-command-module_disable.gresource.xml
1c6b90
@@ -0,0 +1,6 @@
1c6b90
+
1c6b90
+<gresources>
1c6b90
+  <gresource prefix="/org/fedoraproject/dnf/plugins/module_disable">
1c6b90
+    <file>module_disable.plugin</file>
1c6b90
+  </gresource>
1c6b90
+</gresources>
1c6b90
diff --git a/dnf/plugins/module_disable/dnf-command-module_disable.h b/dnf/plugins/module_disable/dnf-command-module_disable.h
1c6b90
new file mode 100644
1c6b90
index 0000000..55f1786
1c6b90
--- /dev/null
1c6b90
+++ b/dnf/plugins/module_disable/dnf-command-module_disable.h
1c6b90
@@ -0,0 +1,33 @@
1c6b90
+/*
1c6b90
+ * Copyright (C) 2020 Red Hat, Inc.
1c6b90
+ *
1c6b90
+ * Licensed under the GNU Lesser General Public License Version 2.1
1c6b90
+ *
1c6b90
+ * This library is free software; you can redistribute it and/or
1c6b90
+ * modify it under the terms of the GNU Lesser General Public
1c6b90
+ * License as published by the Free Software Foundation; either
1c6b90
+ * version 2.1 of the License, or (at your option) any later version.
1c6b90
+ *
1c6b90
+ * This library is distributed in the hope that it will be useful,
1c6b90
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1c6b90
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1c6b90
+ * Lesser General Public License for more details.
1c6b90
+ *
1c6b90
+ * You should have received a copy of the GNU Lesser General Public
1c6b90
+ * License along with this library; if not, write to the Free Software
1c6b90
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
1c6b90
+ */
1c6b90
+
1c6b90
+#pragma once
1c6b90
+
1c6b90
+#include "dnf-command.h"
1c6b90
+#include <libpeas/peas.h>
1c6b90
+
1c6b90
+G_BEGIN_DECLS
1c6b90
+
1c6b90
+#define DNF_TYPE_COMMAND_MODULE_DISABLE dnf_command_module_disable_get_type ()
1c6b90
+G_DECLARE_FINAL_TYPE (DnfCommandModuleDisable, dnf_command_module_disable, DNF, COMMAND_MODULE_DISABLE, PeasExtensionBase)
1c6b90
+
1c6b90
+G_MODULE_EXPORT void dnf_command_module_disable_register_types (PeasObjectModule *module);
1c6b90
+
1c6b90
+G_END_DECLS
1c6b90
diff --git a/dnf/plugins/module_disable/module_disable.plugin b/dnf/plugins/module_disable/module_disable.plugin
1c6b90
new file mode 100644
1c6b90
index 0000000..fc1d912
1c6b90
--- /dev/null
1c6b90
+++ b/dnf/plugins/module_disable/module_disable.plugin
1c6b90
@@ -0,0 +1,9 @@
1c6b90
+[Plugin]
1c6b90
+Module = command_module_disable
1c6b90
+Embedded = dnf_command_module_disable_register_types
1c6b90
+Name = module_disable
1c6b90
+Description = Disable a module stream
1c6b90
+Authors = Jaroslav Mracek <jmracek@redhat.com>
1c6b90
+License = GPL-3.0+
1c6b90
+Copyright = Copyright (C) 2020 Red Hat, Inc.
1c6b90
+X-Command-Syntax = module disable module-spec [module-spec…]
1c6b90
diff --git a/dnf/plugins/module_reset/dnf-command-module_reset.c b/dnf/plugins/module_reset/dnf-command-module_reset.c
1c6b90
new file mode 100644
1c6b90
index 0000000..912c53e
1c6b90
--- /dev/null
1c6b90
+++ b/dnf/plugins/module_reset/dnf-command-module_reset.c
1c6b90
@@ -0,0 +1,123 @@
1c6b90
+/*
1c6b90
+ * Copyright (C) 2020 Red Hat, Inc.
1c6b90
+ *
1c6b90
+ * Licensed under the GNU Lesser General Public License Version 2.1
1c6b90
+ *
1c6b90
+ * This library is free software; you can redistribute it and/or
1c6b90
+ * modify it under the terms of the GNU Lesser General Public
1c6b90
+ * License as published by the Free Software Foundation; either
1c6b90
+ * version 2.1 of the License, or (at your option) any later version.
1c6b90
+ *
1c6b90
+ * This library is distributed in the hope that it will be useful,
1c6b90
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1c6b90
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1c6b90
+ * Lesser General Public License for more details.
1c6b90
+ *
1c6b90
+ * You should have received a copy of the GNU Lesser General Public
1c6b90
+ * License along with this library; if not, write to the Free Software
1c6b90
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
1c6b90
+ */
1c6b90
+
1c6b90
+#include "dnf-command-module_reset.h"
1c6b90
+#include "dnf-utils.h"
1c6b90
+
1c6b90
+struct _DnfCommandModuleReset
1c6b90
+{
1c6b90
+  PeasExtensionBase parent_instance;
1c6b90
+};
1c6b90
+
1c6b90
+static void dnf_command_module_reset_iface_init (DnfCommandInterface *iface);
1c6b90
+
1c6b90
+G_DEFINE_DYNAMIC_TYPE_EXTENDED (DnfCommandModuleReset,
1c6b90
+                                dnf_command_module_reset,
1c6b90
+                                PEAS_TYPE_EXTENSION_BASE,
1c6b90
+                                0,
1c6b90
+                                G_IMPLEMENT_INTERFACE (DNF_TYPE_COMMAND,
1c6b90
+                                                       dnf_command_module_reset_iface_init))
1c6b90
+
1c6b90
+static void
1c6b90
+dnf_command_module_reset_init (DnfCommandModuleReset *self)
1c6b90
+{
1c6b90
+}
1c6b90
+
1c6b90
+static gboolean
1c6b90
+dnf_command_module_reset_run (DnfCommand      *cmd,
1c6b90
+                               int              argc,
1c6b90
+                               char            *argv[],
1c6b90
+                               GOptionContext  *opt_ctx,
1c6b90
+                               DnfContext      *ctx,
1c6b90
+                               GError         **error)
1c6b90
+{
1c6b90
+  g_auto(GStrv) pkgs = NULL;
1c6b90
+  const GOptionEntry opts[] = {
1c6b90
+    { G_OPTION_REMAINING, '\0', 0, G_OPTION_ARG_STRING_ARRAY, &pkgs, NULL, NULL },
1c6b90
+    { NULL }
1c6b90
+  };
1c6b90
+  g_option_context_add_main_entries (opt_ctx, opts, NULL);
1c6b90
+
1c6b90
+  if (!g_option_context_parse (opt_ctx, &argc, &argv, error))
1c6b90
+    return FALSE;
1c6b90
+
1c6b90
+  if (pkgs == NULL)
1c6b90
+    {
1c6b90
+      g_set_error_literal (error,
1c6b90
+                           G_IO_ERROR,
1c6b90
+                           G_IO_ERROR_FAILED,
1c6b90
+                           "Modules are not specified");
1c6b90
+      return FALSE;
1c6b90
+    }
1c6b90
+
1c6b90
+  if (!dnf_context_module_reset (ctx, (const char **)pkgs, error))
1c6b90
+    {
1c6b90
+      return FALSE;
1c6b90
+    }
1c6b90
+  if (!dnf_context_module_switched_check (ctx, error))
1c6b90
+    {
1c6b90
+      return FALSE;
1c6b90
+    }
1c6b90
+
1c6b90
+  if (!dnf_goal_depsolve (dnf_context_get_goal (ctx), DNF_NONE, error))
1c6b90
+    {
1c6b90
+      if (g_error_matches (*error, DNF_ERROR, DNF_ERROR_NO_PACKAGES_TO_UPDATE))
1c6b90
+        {
1c6b90
+          g_clear_error (error);
1c6b90
+        } else {
1c6b90
+          return FALSE;
1c6b90
+        }
1c6b90
+    }
1c6b90
+  if (!dnf_utils_print_transaction (ctx))
1c6b90
+    {
1c6b90
+      return TRUE;
1c6b90
+    }
1c6b90
+  if (!dnf_context_run (ctx, NULL, error))
1c6b90
+    {
1c6b90
+      return FALSE;
1c6b90
+    }
1c6b90
+  return TRUE;
1c6b90
+}
1c6b90
+
1c6b90
+static void
1c6b90
+dnf_command_module_reset_class_init (DnfCommandModuleResetClass *klass)
1c6b90
+{
1c6b90
+}
1c6b90
+
1c6b90
+static void
1c6b90
+dnf_command_module_reset_iface_init (DnfCommandInterface *iface)
1c6b90
+{
1c6b90
+  iface->run = dnf_command_module_reset_run;
1c6b90
+}
1c6b90
+
1c6b90
+static void
1c6b90
+dnf_command_module_reset_class_finalize (DnfCommandModuleResetClass *klass)
1c6b90
+{
1c6b90
+}
1c6b90
+
1c6b90
+G_MODULE_EXPORT void
1c6b90
+dnf_command_module_reset_register_types (PeasObjectModule *module)
1c6b90
+{
1c6b90
+  dnf_command_module_reset_register_type (G_TYPE_MODULE (module));
1c6b90
+
1c6b90
+  peas_object_module_register_extension_type (module,
1c6b90
+                                              DNF_TYPE_COMMAND,
1c6b90
+                                              DNF_TYPE_COMMAND_MODULE_RESET);
1c6b90
+}
1c6b90
diff --git a/dnf/plugins/module_reset/dnf-command-module_reset.gresource.xml b/dnf/plugins/module_reset/dnf-command-module_reset.gresource.xml
1c6b90
new file mode 100644
1c6b90
index 0000000..27e3b15
1c6b90
--- /dev/null
1c6b90
+++ b/dnf/plugins/module_reset/dnf-command-module_reset.gresource.xml
1c6b90
@@ -0,0 +1,6 @@
1c6b90
+
1c6b90
+<gresources>
1c6b90
+  <gresource prefix="/org/fedoraproject/dnf/plugins/module_reset">
1c6b90
+    <file>module_reset.plugin</file>
1c6b90
+  </gresource>
1c6b90
+</gresources>
1c6b90
diff --git a/dnf/plugins/module_reset/dnf-command-module_reset.h b/dnf/plugins/module_reset/dnf-command-module_reset.h
1c6b90
new file mode 100644
1c6b90
index 0000000..65dcd47
1c6b90
--- /dev/null
1c6b90
+++ b/dnf/plugins/module_reset/dnf-command-module_reset.h
1c6b90
@@ -0,0 +1,33 @@
1c6b90
+/*
1c6b90
+ * Copyright (C) 2020 Red Hat, Inc.
1c6b90
+ *
1c6b90
+ * Licensed under the GNU Lesser General Public License Version 2.1
1c6b90
+ *
1c6b90
+ * This library is free software; you can redistribute it and/or
1c6b90
+ * modify it under the terms of the GNU Lesser General Public
1c6b90
+ * License as published by the Free Software Foundation; either
1c6b90
+ * version 2.1 of the License, or (at your option) any later version.
1c6b90
+ *
1c6b90
+ * This library is distributed in the hope that it will be useful,
1c6b90
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1c6b90
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1c6b90
+ * Lesser General Public License for more details.
1c6b90
+ *
1c6b90
+ * You should have received a copy of the GNU Lesser General Public
1c6b90
+ * License along with this library; if not, write to the Free Software
1c6b90
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
1c6b90
+ */
1c6b90
+
1c6b90
+#pragma once
1c6b90
+
1c6b90
+#include "dnf-command.h"
1c6b90
+#include <libpeas/peas.h>
1c6b90
+
1c6b90
+G_BEGIN_DECLS
1c6b90
+
1c6b90
+#define DNF_TYPE_COMMAND_MODULE_RESET dnf_command_module_reset_get_type ()
1c6b90
+G_DECLARE_FINAL_TYPE (DnfCommandModuleReset, dnf_command_module_reset, DNF, COMMAND_MODULE_RESET, PeasExtensionBase)
1c6b90
+
1c6b90
+G_MODULE_EXPORT void dnf_command_module_reset_register_types (PeasObjectModule *module);
1c6b90
+
1c6b90
+G_END_DECLS
1c6b90
diff --git a/dnf/plugins/module_reset/module_reset.plugin b/dnf/plugins/module_reset/module_reset.plugin
1c6b90
new file mode 100644
1c6b90
index 0000000..c680f08
1c6b90
--- /dev/null
1c6b90
+++ b/dnf/plugins/module_reset/module_reset.plugin
1c6b90
@@ -0,0 +1,9 @@
1c6b90
+[Plugin]
1c6b90
+Module = command_module_reset
1c6b90
+Embedded = dnf_command_module_reset_register_types
1c6b90
+Name = module_reset
1c6b90
+Description = Reset a module stream
1c6b90
+Authors = Jaroslav Mracek <jmracek@redhat.com>
1c6b90
+License = GPL-3.0+
1c6b90
+Copyright = Copyright (C) 2020 Red Hat, Inc.
1c6b90
+X-Command-Syntax = module reset module-spec [module-spec…]
1c6b90
-- 
1c6b90
2.26.2
1c6b90