Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package microdnf for openSUSE:Factory 
checked in at 2021-02-07 15:16:33
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/microdnf (Old)
 and      /work/SRC/openSUSE:Factory/.microdnf.new.28504 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "microdnf"

Sun Feb  7 15:16:33 2021 rev:4 rq:868793 version:3.7.0

Changes:
--------
--- /work/SRC/openSUSE:Factory/microdnf/microdnf.changes        2020-12-09 
22:11:00.903042328 +0100
+++ /work/SRC/openSUSE:Factory/.microdnf.new.28504/microdnf.changes     
2021-02-07 15:18:07.445678112 +0100
@@ -1,0 +2,11 @@
+Wed Feb  3 02:27:10 UTC 2021 - Neal Gompa <[email protected]>
+
+- Update to 3.7.0
+  + Add support for command aliases
+  + Rename "update" to "upgrade" command
+  + Add "update" alias to "upgrade" command
+  + Add "download" command
+  + Add support for user confirmation
+  + Default to user confirmation like DNF
+
+-------------------------------------------------------------------

Old:
----
  microdnf-3.6.0.tar.gz

New:
----
  microdnf-3.7.0.tar.gz

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

Other differences:
------------------
++++++ microdnf.spec ++++++
--- /var/tmp/diff_new_pack.uDI2s9/_old  2021-02-07 15:18:08.037679099 +0100
+++ /var/tmp/diff_new_pack.uDI2s9/_new  2021-02-07 15:18:08.045679112 +0100
@@ -1,7 +1,7 @@
 #
 # spec file for package microdnf
 #
-# Copyright (c) 2020 Neal Gompa <[email protected]>.
+# Copyright (c) 2020-2021 Neal Gompa <[email protected]>.
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -18,7 +18,7 @@
 %global libdnf_version 0.55.2
 
 Name:           microdnf
-Version:        3.6.0
+Version:        3.7.0
 Release:        0
 Summary:        Lightweight implementation of DNF in C
 Group:          System/Packages

++++++ microdnf-3.6.0.tar.gz -> microdnf-3.7.0.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/microdnf-3.6.0/CMakeLists.txt 
new/microdnf-3.7.0/CMakeLists.txt
--- old/microdnf-3.6.0/CMakeLists.txt   2020-12-06 16:32:58.000000000 +0100
+++ new/microdnf-3.7.0/CMakeLists.txt   2021-02-03 03:25:30.000000000 +0100
@@ -1,6 +1,6 @@
 cmake_minimum_required (VERSION 2.8.5)
 project (microdnf C)
-set (PROJECT_VERSION 3.6.0)
+set (PROJECT_VERSION 3.7.0)
 
 list (APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake)
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/microdnf-3.6.0/bors.toml new/microdnf-3.7.0/bors.toml
--- old/microdnf-3.6.0/bors.toml        1970-01-01 01:00:00.000000000 +0100
+++ new/microdnf-3.7.0/bors.toml        2021-02-03 03:25:30.000000000 +0100
@@ -0,0 +1,2 @@
+status = ["DNF CI"]
+timeout_sec = 10800  # 3 hours
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/microdnf-3.6.0/dnf/CMakeLists.txt 
new/microdnf-3.7.0/dnf/CMakeLists.txt
--- old/microdnf-3.6.0/dnf/CMakeLists.txt       2020-12-06 16:32:58.000000000 
+0100
+++ new/microdnf-3.7.0/dnf/CMakeLists.txt       2021-02-03 03:25:30.000000000 
+0100
@@ -15,10 +15,10 @@
                         INTERNAL)
 list (APPEND DNF_COMMAND_REMOVE "plugins/remove/dnf-command-remove.c")
 
-glib_compile_resources (DNF_COMMAND_UPDATE 
plugins/update/dnf-command-update.gresource.xml
-                        C_PREFIX dnf_command_update
+glib_compile_resources (DNF_COMMAND_UPGRADE 
plugins/upgrade/dnf-command-upgrade.gresource.xml
+                        C_PREFIX dnf_command_upgrade
                         INTERNAL)
-list (APPEND DNF_COMMAND_UPDATE "plugins/update/dnf-command-update.c")
+list (APPEND DNF_COMMAND_UPGRADE "plugins/upgrade/dnf-command-upgrade.c")
 
 glib_compile_resources (DNF_COMMAND_REPOLIST 
plugins/repolist/dnf-command-repolist.gresource.xml
                         C_PREFIX dnf_command_repolist
@@ -35,6 +35,11 @@
                         INTERNAL)
 list (APPEND DNF_COMMAND_CLEAN "plugins/clean/dnf-command-clean.c")
 
+glib_compile_resources (DNF_COMMAND_DOWNLOAD 
plugins/download/dnf-command-download.gresource.xml
+                        C_PREFIX dnf_command_download
+                        INTERNAL)
+list (APPEND DNF_COMMAND_DOWNLOAD "plugins/download/dnf-command-download.c")
+
 glib_compile_resources (DNF_COMMAND_MODULE_ENABLE 
plugins/module_enable/dnf-command-module_enable.gresource.xml
                         C_PREFIX dnf_command_module_enable
                         INTERNAL)
@@ -56,10 +61,11 @@
                 ${DNF_COMMAND_INSTALL}
                 ${DNF_COMMAND_REINSTALL}
                 ${DNF_COMMAND_REMOVE}
-                ${DNF_COMMAND_UPDATE}
+                ${DNF_COMMAND_UPGRADE}
                 ${DNF_COMMAND_REPOLIST}
                 ${DNF_COMMAND_REPOQUERY}
                 ${DNF_COMMAND_CLEAN}
+                ${DNF_COMMAND_DOWNLOAD}
                 ${DNF_COMMAND_MODULE_ENABLE}
                 ${DNF_COMMAND_MODULE_DISABLE}
                 ${DNF_COMMAND_MODULE_RESET})
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/microdnf-3.6.0/dnf/dnf-main.c 
new/microdnf-3.7.0/dnf/dnf-main.c
--- old/microdnf-3.6.0/dnf/dnf-main.c   2020-12-06 16:32:58.000000000 +0100
+++ new/microdnf-3.7.0/dnf/dnf-main.c   2021-02-03 03:25:30.000000000 +0100
@@ -3,7 +3,7 @@
  * Copyright ?? 2010-2015 Richard Hughes <[email protected]>
  * Copyright ?? 2016 Colin Walters <[email protected]>
  * Copyright ?? 2016-2017 Igor Gnatenko <[email protected]>
- * Copyright ?? 2017-2020 Jaroslav Rohel <[email protected]>
+ * Copyright ?? 2017-2021 Jaroslav Rohel <[email protected]>
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -26,12 +26,15 @@
 #include <libpeas/peas.h>
 #include <libdnf/libdnf.h>
 #include "dnf-command.h"
+#include "dnf-utils.h"
 
 typedef enum { ARG_DEFAULT, ARG_FALSE, ARG_TRUE } BoolArgs;
 
 static BoolArgs opt_install_weak_deps = ARG_DEFAULT;
 static BoolArgs opt_allow_vendor_change = ARG_DEFAULT;
-static gboolean opt_yes = TRUE;
+static BoolArgs opt_keepcache = ARG_DEFAULT;
+static gboolean opt_no = FALSE;
+static gboolean opt_yes = FALSE;
 static gboolean opt_nodocs = FALSE;
 static gboolean opt_best = FALSE;
 static gboolean opt_nobest = FALSE;
@@ -114,6 +117,10 @@
                                      "Missing value in: %s", value);
           ret = FALSE;
         }
+      else if (strchr (setopt[0], '.'))
+        { /* repository option, pass to libdnf */
+          ret = dnf_conf_add_setopt (setopt[0], DNF_CONF_COMMANDLINE, 
setopt[1], &local_error);
+        }
       else if (strcmp (setopt[0], "tsflags") == 0)
         {
           g_auto(GStrv) tsflags = g_strsplit (setopt[1], ",", -1);
@@ -194,6 +201,20 @@
               ret = FALSE;
             }
         }
+      else if (strcmp (setopt[0], "keepcache") == 0)
+        {
+          const char *setopt_val = setopt[1];
+          if (setopt_val[0] == '1' && setopt_val[1] == '\0')
+            opt_keepcache = ARG_TRUE;
+          else if (setopt_val[0] == '0' && setopt_val[1] == '\0')
+            opt_keepcache = ARG_FALSE;
+          else
+            {
+              local_error = g_error_new (G_OPTION_ERROR, 
G_OPTION_ERROR_BAD_VALUE,
+                                         "Invalid boolean value \"%s\" in: 
%s", setopt[1], value);
+              ret = FALSE;
+            }
+        }
       else if (strcmp (setopt[0], "reposdir") == 0)
         {
           reposdir_used = TRUE;
@@ -227,7 +248,8 @@
 }
 
 static const GOptionEntry global_opts[] = {
-  { "assumeyes", 'y', G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_NONE, &opt_yes, "Does 
nothing, we always assume yes", NULL },
+  { "assumeno", '\0', G_OPTION_FLAG_NONE, G_OPTION_ARG_NONE, &opt_no, 
"Automatically answer no for all questions", NULL },
+  { "assumeyes", 'y', G_OPTION_FLAG_NONE, G_OPTION_ARG_NONE, &opt_yes, 
"Automatically answer yes for all questions", NULL },
   { "best", '\0', G_OPTION_FLAG_NONE, G_OPTION_ARG_NONE, &opt_best, "Try the 
best available package versions in transactions", NULL },
   { "config", '\0', G_OPTION_FLAG_NONE, G_OPTION_ARG_CALLBACK, 
process_global_option, "Configuration file location", "<config file>" },
   { "disablerepo", '\0', G_OPTION_FLAG_NONE, G_OPTION_ARG_CALLBACK, 
process_global_option, "Disable repository by an id", "ID" },
@@ -241,7 +263,7 @@
   { "refresh", '\0', G_OPTION_FLAG_NONE, G_OPTION_ARG_NONE, &opt_refresh, "Set 
metadata as expired before running the command", NULL },
   { "releasever", '\0', G_OPTION_FLAG_NONE, G_OPTION_ARG_CALLBACK, 
process_global_option, "Override the value of $releasever in config and repo 
files", "RELEASEVER" },
   { "setopt", '\0', G_OPTION_FLAG_NONE, G_OPTION_ARG_CALLBACK, 
process_global_option,
-    "Override a configuration option (install_weak_deps=0/1, 
allow_vendor_change=0/1, module_platform_id=<name:stream>, cachedir=<path>, 
reposdir=<path1>,<path2>,..., tsflags=nodocs/test, 
varsdir=<path1>,<path2>,...)", "<option>=<value>" },
+    "Override a configuration option (install_weak_deps=0/1, 
allow_vendor_change=0/1, keepcache=0/1, module_platform_id=<name:stream>, 
cachedir=<path>, reposdir=<path1>,<path2>,..., tsflags=nodocs/test, 
varsdir=<path1>,<path2>,..., repo_id.option_name=<value>)", "<option>=<value>" 
},
   { NULL }
 };
 
@@ -257,7 +279,6 @@
 #undef CACHEDIR
   dnf_context_set_check_disk_space (ctx, FALSE);
   dnf_context_set_check_transaction (ctx, TRUE);
-  dnf_context_set_keep_cache (ctx, FALSE);
 
   /* Sets a maximum cache age in seconds. It is an upper limit.
    * The lower value between this value and "metadata_expire" value from 
repo/global
@@ -373,6 +394,8 @@
   g_autoptr(GOptionContext) subcmd_opt_ctx = NULL;
   g_autofree gchar *subcmd_opt_param = NULL;
   GSList *cmds_with_subcmds = NULL;  /* list of commands with subcommands */
+  /* dictionary of aliases for commands */
+  g_autoptr(GHashTable) cmds_aliases = g_hash_table_new_full (g_str_hash, 
g_str_equal, g_free, g_free);
 
   setlocale (LC_ALL, "");
 
@@ -412,6 +435,7 @@
       if (peas_engine_provides_extension (engine, info, DNF_TYPE_COMMAND))
         {
           g_autofree gchar *command_name = g_strdup (peas_plugin_info_get_name 
(info));
+          g_autofree gchar *command_alias_name = g_strdup 
(peas_plugin_info_get_external_data (info, "Alias-Name"));
 
           /* Plugins with a '_' character in command name implement 
subcommands.
              E.g. the "command_module_enable" plugin implements the "enable" 
subcommand of the "module" command. */
@@ -424,11 +448,21 @@
                   break;
                 }
             }
+
+          /* Add command alias to the dictionary. */
+          if (command_alias_name)
+              g_hash_table_insert (cmds_aliases, g_strdup 
(command_alias_name), g_strdup (command_name));
+
           /*
            * At least 2 spaces between the command and its description are 
needed
            * so that help2man formats it correctly.
            */
           g_string_append_printf (cmd_summary, "\n  %-16s     %s", 
command_name, peas_plugin_info_get_description (info));
+
+          /* If command has an alias with a description, add it to the help. */
+          const gchar *command_alias_description = 
peas_plugin_info_get_external_data (info, "Alias-Description");
+          if (command_alias_name && command_alias_description)
+            g_string_append_printf (cmd_summary, "\n  %-16s     %s", 
command_alias_name, command_alias_description);
         }
     }
   g_option_context_set_summary (opt_ctx, cmd_summary->str);
@@ -531,6 +565,11 @@
       else if (opt_allow_vendor_change == ARG_FALSE)
         dnf_context_set_allow_vendor_change (FALSE);
 
+      if (opt_keepcache == ARG_TRUE)
+        dnf_context_set_keep_cache (ctx, TRUE);
+      else if (opt_keepcache == ARG_FALSE)
+        dnf_context_set_keep_cache (ctx, FALSE);
+
       if (opt_best && opt_nobest)
         {
           error = g_error_new_literal(G_OPTION_ERROR,
@@ -546,6 +585,16 @@
         {
           dnf_context_set_best(FALSE);
         }
+
+      if (opt_no)
+        {
+          dnf_conf_main_set_option ("assumeno", DNF_CONF_COMMANDLINE, "1", 
NULL);
+        }
+
+      if (opt_yes)
+        {
+          dnf_conf_main_set_option ("assumeyes", DNF_CONF_COMMANDLINE, "1", 
NULL);
+        }
     }
 
   const gchar *cmd_name = get_command (&argc, argv);
@@ -572,15 +621,17 @@
    * Command name (cmd_name) can not contain '_' character. It is reserved for 
subcomands. */
   if (cmd_name != NULL && strchr(cmd_name, '_') == NULL)
     {
-      with_subcmds = g_slist_find_custom (cmds_with_subcmds, cmd_name, 
compare_strings) != NULL;
-      g_autofree gchar *mod_name = g_strdup_printf ("command_%s", cmd_name);
+      const gchar *original_cmd_name = g_hash_table_lookup (cmds_aliases, 
cmd_name);
+      const gchar *search_cmd_name = original_cmd_name ? original_cmd_name : 
cmd_name;
+      with_subcmds = g_slist_find_custom (cmds_with_subcmds, search_cmd_name, 
compare_strings) != NULL;
+      g_autofree gchar *mod_name = g_strdup_printf ("command_%s", 
search_cmd_name);
       plug = peas_engine_get_plugin_info (engine, mod_name);
       if (plug == NULL && with_subcmds)
         {
           subcmd_name = get_command (&argc, argv);
           if (subcmd_name != NULL)
             {
-              g_autofree gchar *submod_name = g_strdup_printf 
("command_%s_%s", cmd_name, subcmd_name);
+              g_autofree gchar *submod_name = g_strdup_printf 
("command_%s_%s", search_cmd_name, subcmd_name);
               plug = peas_engine_get_plugin_info (engine, submod_name);
             }
         }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/microdnf-3.6.0/dnf/dnf-utils.c 
new/microdnf-3.7.0/dnf/dnf-utils.c
--- old/microdnf-3.6.0/dnf/dnf-utils.c  2020-12-06 16:32:58.000000000 +0100
+++ new/microdnf-3.7.0/dnf/dnf-utils.c  2021-02-03 03:25:30.000000000 +0100
@@ -71,6 +71,72 @@
 
 
 gboolean
+dnf_utils_conf_main_get_bool_opt (const gchar *name, enum DnfConfPriority 
*priority)
+{
+    g_autofree gchar *tmp = dnf_conf_main_get_option (name, priority, NULL);
+    return tmp != NULL && (*tmp == '1' || *tmp == 'y' || *tmp == 'Y');
+}
+
+
+gboolean
+dnf_utils_userconfirm (void)
+{
+  gboolean ret;
+  enum DnfConfPriority priority;
+
+  // "assumeno" takes precedence over "assumeyes"
+  if (dnf_utils_conf_main_get_bool_opt ("assumeno", &priority))
+    ret = FALSE;
+  else if (dnf_utils_conf_main_get_bool_opt ("assumeyes", &priority))
+    ret = TRUE;
+  else
+    {
+      gboolean defaultyes = dnf_utils_conf_main_get_bool_opt ("defaultyes", 
&priority);
+
+      const char *msg;
+      if (defaultyes)
+        msg = "Is this ok [Y/n]: ";
+      else
+        msg = "Is this ok [y/N]: ";
+
+      while (TRUE)
+        {
+          g_print ("%s", msg);
+
+          char choice = getchar ();
+          if (choice == '\n' || choice == '\r')
+            {
+              ret = defaultyes;
+              break;
+            }
+
+          char second = getchar ();
+          for (char ch = second; ch != '\n'; ch = getchar ())
+            ;
+
+          if (second == '\n' || second == '\r')
+            {
+              if (choice == 'y' || choice == 'Y')
+                {
+                  ret = TRUE;
+                  break;
+                }
+              if (choice == 'n' || choice == 'N')
+                {
+                  ret = FALSE;
+                  break;
+                }
+            }
+        }
+    }
+
+    if (!ret)
+      g_print ("Operation aborted.\n");
+
+    return ret;
+}
+
+gboolean
 dnf_utils_print_transaction (DnfContext *ctx)
 {
   g_autoptr(GPtrArray) pkgs = dnf_goal_get_packages (dnf_context_get_goal 
(ctx),
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/microdnf-3.6.0/dnf/dnf-utils.h 
new/microdnf-3.7.0/dnf/dnf-utils.h
--- old/microdnf-3.6.0/dnf/dnf-utils.h  2020-12-06 16:32:58.000000000 +0100
+++ new/microdnf-3.7.0/dnf/dnf-utils.h  2021-02-03 03:25:30.000000000 +0100
@@ -25,5 +25,7 @@
 G_BEGIN_DECLS
 
 gboolean dnf_utils_print_transaction (DnfContext *ctx);
+gboolean dnf_utils_conf_main_get_bool_opt (const gchar *name, enum 
DnfConfPriority *priority);
+gboolean dnf_utils_userconfirm (void);
 
 G_END_DECLS
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/microdnf-3.6.0/dnf/meson.build 
new/microdnf-3.7.0/dnf/meson.build
--- old/microdnf-3.6.0/dnf/meson.build  2020-12-06 16:32:58.000000000 +0100
+++ new/microdnf-3.7.0/dnf/meson.build  2021-02-03 03:25:30.000000000 +0100
@@ -30,14 +30,14 @@
   ),
   'plugins/remove/dnf-command-remove.c',
 
-  # update
+  # upgrade
   gnome.compile_resources(
-    'dnf-update',
-    'plugins/update/dnf-command-update.gresource.xml',
-    c_name : 'dnf_command_update',
-    source_dir : 'plugins/update',
+    'dnf-upgrade',
+    'plugins/upgrade/dnf-command-upgrade.gresource.xml',
+    c_name : 'dnf_command_upgrade',
+    source_dir : 'plugins/upgrade',
   ),
-  'plugins/update/dnf-command-update.c',
+  'plugins/upgrade/dnf-command-upgrade.c',
 
   # repolist
   gnome.compile_resources(
@@ -66,6 +66,15 @@
   ),
   'plugins/clean/dnf-command-clean.c',
 
+  # download
+  gnome.compile_resources(
+    'dnf-download',
+    'plugins/download/dnf-command-download.gresource.xml',
+    c_name : 'dnf_command_download',
+    source_dir : 'plugins/download',
+  ),
+  'plugins/download/dnf-command-download.c',
+
   # module enable
   gnome.compile_resources(
     'dnf-module_enable',
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/microdnf-3.6.0/dnf/plugins/download/dnf-command-download.c 
new/microdnf-3.7.0/dnf/plugins/download/dnf-command-download.c
--- old/microdnf-3.6.0/dnf/plugins/download/dnf-command-download.c      
1970-01-01 01:00:00.000000000 +0100
+++ new/microdnf-3.7.0/dnf/plugins/download/dnf-command-download.c      
2021-02-03 03:25:30.000000000 +0100
@@ -0,0 +1,473 @@
+/* dnf-command-download.c
+ *
+ * Copyright ?? 2020-2021 Daniel Hams <[email protected]>
+ * Copyright ?? 2021 Jaroslav Rohel <[email protected]>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "dnf-command-download.h"
+#include "dnf-utils.h"
+
+/* For MAXPATHLEN */
+#include <sys/param.h>
+
+struct _DnfCommandDownload
+{
+  PeasExtensionBase parent_instance;
+};
+
+static void dnf_command_download_iface_init (DnfCommandInterface *iface);
+
+G_DEFINE_DYNAMIC_TYPE_EXTENDED (DnfCommandDownload,
+                                dnf_command_download,
+                                PEAS_TYPE_EXTENSION_BASE,
+                                0,
+                                G_IMPLEMENT_INTERFACE (DNF_TYPE_COMMAND,
+                                                       
dnf_command_download_iface_init))
+
+static void
+dnf_command_download_init (DnfCommandDownload *self)
+{
+}
+
+inline static gboolean
+str_ends_with (const gchar * buf, const gchar * val)
+{
+  size_t buf_len = strlen (buf);
+  size_t val_len = strlen (val);
+  return buf_len >= val_len && memcmp (buf + buf_len - val_len, val, val_len) 
== 0;
+}
+
+static gboolean dnf_command_download_rewriterepotosrc (gchar * repo_buf)
+{
+  if (str_ends_with (repo_buf, "-rpms"))
+    {
+      // Add a terminator in the right place before we strcat
+      repo_buf[strlen (repo_buf) - 5] = '\0';
+      strcat (repo_buf, "-source-rpms");
+      return TRUE;
+    }
+  else if (!str_ends_with (repo_buf, "-source"))
+    {
+      strcat (repo_buf, "-source");
+      return TRUE;
+    }
+  return FALSE;
+}
+
+static gboolean
+dnf_command_download_enablesourcerepos (DnfContext *ctx,
+                                        DnfRepoLoader *repo_loader,
+                                        GError **error)
+{
+  g_autoptr(GError) local_error = NULL;
+  // A place where we can "extend" the repoid with an extension
+  gchar tmp_name[MAXPATHLEN];
+  g_autoptr(GPtrArray) all_repos = dnf_repo_loader_get_repos (repo_loader, 
error);
+
+  // We have to activate repos in a second loop to avoid breaking the iterator
+  // on the above repo list. We are "strdup"ing strings into it, so need
+  // free called on them.
+  g_autoptr(GPtrArray) repos_to_enable = g_ptr_array_new_full (all_repos->len,
+                                                               free);
+  // Look for each enabled repo if there is a corresponding source repo
+  // that we need to enable.
+  for (guint i = 0 ; i < all_repos->len; ++i )
+    {
+      DnfRepo * repo = g_ptr_array_index (all_repos, i);
+      const gchar * repo_id = dnf_repo_get_id (repo);
+      if (dnf_repo_get_enabled (repo))
+        {
+          int repo_id_len = strlen (repo_id);
+          if (repo_id_len >= (MAXPATHLEN - 1 - strlen ("-source-rpms")))
+            {
+              // Repo name too long when concatenated
+              g_set_error (error,
+                           DNF_ERROR,
+                           DNF_ERROR_INTERNAL_ERROR,
+                           "Repository name overflow when -source-rpms added 
(%1$s)",
+                           repo_id);
+              return FALSE;
+            }
+          strcpy (tmp_name, repo_id);
+          // Only look for an associated source repo where adding an extension
+          // makes sense
+          if (dnf_command_download_rewriterepotosrc (tmp_name))
+            {
+              DnfRepo * src_repo = dnf_repo_loader_get_repo_by_id (repo_loader,
+                                                                   tmp_name,
+                                                                   
&local_error);
+              if (local_error != NULL)
+                {
+                  if (!g_error_matches (local_error, DNF_ERROR, 
DNF_ERROR_REPO_NOT_FOUND))
+                    {
+                      g_propagate_error (error, local_error);
+                      return FALSE;
+                    }
+                  // Repo not found is not terminal
+                  g_error_free (local_error);
+                  local_error = NULL;
+                  continue;
+                }
+              if (!dnf_repo_get_enabled (src_repo))
+                {
+                  // Repo exists and not enabled, add it to our list to enable
+                  g_ptr_array_add (repos_to_enable, strdup (tmp_name));
+                }
+            }
+          // else repo "source" equiv already enabled or doesn't exist
+        }
+    }
+
+  // Repo enable loop
+  for (guint r = 0 ; r < repos_to_enable->len; ++r)
+    {
+      gchar * repo_to_enable_id = g_ptr_array_index (repos_to_enable, r);
+      if (!dnf_context_repo_enable (ctx, repo_to_enable_id, error))
+        {
+          return FALSE;
+        }
+      else
+        {
+          g_print ("enabling %s repository\n", repo_to_enable_id);
+        }
+    }
+  return TRUE;
+}
+
+static gint
+gptrarr_dnf_package_repopkgcmp (gconstpointer a, gconstpointer b)
+{
+  // Sort by repo first, then by package
+  // so we only need to add repo keys the first time we see a repo
+  // in the package list
+  DnfPackage **apkg = (DnfPackage**)a;
+  DnfPackage **bpkg = (DnfPackage**)b;
+  const gchar * areponame = dnf_package_get_reponame (*apkg);
+  const gchar * breponame = dnf_package_get_reponame (*bpkg);
+  int repocmp = strcmp (areponame, breponame);
+  if (repocmp == 0)
+    {
+      return dnf_package_cmp (*apkg, *bpkg);
+    }
+  return repocmp;
+}
+
+/* Compare packages by repository priority and cost */
+static gint
+dnf_package_repo_prio_cost_cmp (gconstpointer pkg1, gconstpointer pkg2, 
gpointer repo_loader)
+{
+  const gchar *pkg1_reponame = dnf_package_get_reponame ((DnfPackage*)pkg1);
+  const gchar *pkg2_reponame = dnf_package_get_reponame ((DnfPackage*)pkg2);
+  if (strcmp (pkg1_reponame, pkg2_reponame) == 0)
+    return 0;
+
+  DnfRepo *pkg1_repo = dnf_repo_loader_get_repo_by_id (repo_loader, 
pkg1_reponame, NULL);
+  DnfRepo *pkg2_repo = dnf_repo_loader_get_repo_by_id (repo_loader, 
pkg2_reponame, NULL);
+
+  // A higher value means a lower repository priority.
+  int result = (pkg2_repo ? hy_repo_get_priority (dnf_repo_get_repo 
(pkg2_repo)) : INT_MAX) -
+               (pkg1_repo ? hy_repo_get_priority (dnf_repo_get_repo 
(pkg1_repo)) : INT_MAX);
+
+  if (result == 0)
+    result = (pkg1_repo ? hy_repo_get_cost (dnf_repo_get_repo (pkg1_repo)) : 
INT_MAX) -
+             (pkg2_repo ? hy_repo_get_cost (dnf_repo_get_repo (pkg2_repo)) : 
INT_MAX);
+
+  return result;
+}
+
+/* The "pkgs" array can contain multiple packages with the same NEVRA.
+ * The function selects one (from the cheapest repository with the highest 
priority) package for each NEVRA. */
+static GPtrArray *
+select_one_pkg_for_nevra (DnfRepoLoader *repo_loader, GPtrArray *pkgs)
+{
+  g_autoptr(GHashTable) nevra2pkgs = g_hash_table_new (g_str_hash, 
g_str_equal);
+  for (guint i = 0 ; i < pkgs->len; ++i)
+    {
+      DnfPackage *pkg = g_ptr_array_index (pkgs, i);
+      const gchar *pkg_nevra = dnf_package_get_nevra (pkg);
+      g_hash_table_insert (nevra2pkgs, (gpointer)pkg_nevra, g_slist_prepend 
(g_hash_table_lookup (nevra2pkgs, pkg_nevra), pkg));
+    }
+
+  g_autoptr(GPtrArray) pkgs_to_download = g_ptr_array_sized_new 
(g_hash_table_size (nevra2pkgs));
+  GHashTableIter iter;
+  GSList *pkgs_list;
+  g_hash_table_iter_init (&iter, nevra2pkgs);
+  while (g_hash_table_iter_next (&iter, NULL, (gpointer)&pkgs_list))
+    {
+      pkgs_list = g_slist_sort_with_data (pkgs_list, 
dnf_package_repo_prio_cost_cmp, repo_loader);
+      g_ptr_array_add (pkgs_to_download, pkgs_list->data);
+      g_slist_free (pkgs_list);
+    }
+
+  return g_steal_pointer (&pkgs_to_download);
+}
+
+static gboolean
+download_packages (DnfRepoLoader *repo_loader, GPtrArray *pkgs, DnfState 
*state, GError **error)
+{
+  g_autoptr(GPtrArray) pkgs_to_download = select_one_pkg_for_nevra 
(repo_loader, pkgs);
+
+  g_ptr_array_sort (pkgs_to_download, gptrarr_dnf_package_repopkgcmp);
+  rpmKeyring keyring = rpmKeyringNew ();
+  GError *error_local = NULL;
+  gchar prev_repo[MAXPATHLEN];
+  prev_repo[0] = '\0';
+  for (guint i = 0 ; i < pkgs_to_download->len; ++i)
+    {
+      DnfPackage * pkg = g_ptr_array_index (pkgs_to_download, i);
+      const gchar * pkg_nevra = dnf_package_get_nevra (pkg);
+
+      const gchar * reponame = dnf_package_get_reponame (pkg);
+      if (strlen (reponame) >= MAXPATHLEN)
+        {
+          g_error ("Reponame exceeds max path len (%s)\n", reponame);
+          return FALSE;
+        }
+      DnfRepo * repo = dnf_repo_loader_get_repo_by_id (repo_loader, reponame, 
error);
+      if (*error != 0)
+        {
+          g_print ("Failed to find repo(%s)\n", reponame);
+          return FALSE;
+        }
+      // Add repo keys to keyring if this is the first time we see the repo
+      if (prev_repo[0] == '\0' || strcmp (prev_repo, reponame) != 0)
+        {
+          g_auto(GStrv) pubkeys = dnf_repo_get_public_keys (repo);
+          if (*pubkeys)
+            {
+              for (char **iter = pubkeys; iter && *iter; iter++)
+                {
+                  const char *pubkey = *iter;
+                  if (!dnf_keyring_add_public_key (keyring, pubkey, error))
+                    {
+                      return FALSE;
+                    }
+                }
+            }
+          strcpy (prev_repo, reponame);
+        }
+      dnf_package_set_repo (pkg, repo);
+      const gchar *download_path = dnf_package_download (pkg, "./", state, 
error);
+      if (*error != 0)
+        {
+          g_print ("Failed to download %s\n", pkg_nevra);
+          return FALSE;
+        }
+
+      g_print ("Downloaded %s\n", pkg_nevra);
+
+      // Check signature (if set on repo)
+      if (dnf_repo_get_gpgcheck (repo) &&
+          !dnf_keyring_check_untrusted_file (keyring, download_path, 
&error_local))
+        {
+          if (!g_error_matches (error_local, DNF_ERROR, 
DNF_ERROR_GPG_SIGNATURE_INVALID))
+            {
+              g_set_error (error,
+                           DNF_ERROR,
+                           DNF_ERROR_FILE_INVALID,
+                           "keyring check failure on %1$s "
+                           "and repo %2$s is GPG enabled: %3$s",
+                           dnf_package_get_nevra (pkg),
+                           dnf_repo_get_id (repo),
+                           error_local->message);
+              g_error_free (error_local);
+              return FALSE;
+            }
+          g_set_error (error,
+                       DNF_ERROR,
+                       DNF_ERROR_FILE_INVALID,
+                       "package %1$s cannot be verified "
+                       "and repo %2$s is GPG enabled: %3$s",
+                       dnf_package_get_nevra (pkg),
+                       dnf_repo_get_id (repo),
+                       error_local->message);
+          g_error_free (error_local);
+          return FALSE;
+        }
+    }
+  return TRUE;
+}
+
+static HyQuery
+get_packages_query (DnfContext *ctx, GStrv pkgs_spec, gboolean opt_src, const 
gchar *opt_archlist)
+{
+  DnfSack *sack = dnf_context_get_sack (ctx);
+  hy_autoquery HyQuery query = hy_query_create (sack);
+
+  if (pkgs_spec)
+    {
+      hy_query_filter_empty (query);
+      for (char **pkey = pkgs_spec; *pkey; ++pkey)
+        {
+          g_auto(HySubject) subject = hy_subject_create (*pkey);
+          HyNevra out_nevra;
+          hy_autoquery HyQuery key_query =
+            hy_subject_get_best_solution (subject, sack, NULL, &out_nevra,
+                                          FALSE, TRUE, TRUE, TRUE, opt_src);
+          if (out_nevra)
+            {
+              hy_nevra_free (out_nevra);
+            }
+          hy_query_filter (key_query, HY_PKG_REPONAME, HY_NEQ, 
HY_SYSTEM_REPO_NAME);
+          hy_query_filter_num (key_query, HY_PKG_LATEST_PER_ARCH_BY_PRIORITY, 
HY_EQ, 1);
+          hy_query_union (query, key_query);
+        }
+    }
+  if (opt_src)
+    {
+      hy_query_filter (query, HY_PKG_ARCH, HY_EQ, "src");
+    }
+
+  if (opt_archlist)
+    {
+      g_auto(GStrv) archs_array = g_strsplit_set (opt_archlist, ", ", -1);
+      hy_query_filter_in (query, HY_PKG_ARCH, HY_EQ, (const 
char**)archs_array);
+    }
+
+  return g_steal_pointer (&query);
+}
+
+static GPtrArray *
+get_packages_deps (DnfContext *ctx, GPtrArray *packages, GError **error)
+{
+  DnfSack *sack = dnf_context_get_sack (ctx);
+
+  g_autoptr(GPtrArray) deps = g_ptr_array_new_with_free_func 
((GDestroyNotify)g_object_unref);
+
+  for (guint i = 0; i < packages->len; ++i)
+    {
+      DnfPackage * pkg = g_ptr_array_index (packages, i);
+      HyGoal goal = hy_goal_create (sack);
+      hy_goal_install (goal, pkg);
+      if (hy_goal_run_flags (goal, DNF_NONE) == 0)
+        {
+          g_ptr_array_extend_and_steal (deps, hy_goal_list_installs (goal, 
NULL));
+          g_ptr_array_extend_and_steal (deps, hy_goal_list_upgrades (goal, 
NULL));
+        }
+      else
+        {
+          g_set_error_literal (error, DNF_ERROR, DNF_ERROR_NO_SOLUTION, "Error 
in resolve of packages");
+          hy_goal_free (goal);
+          return NULL;
+        }
+      hy_goal_free (goal);
+    }
+
+  return g_steal_pointer (&deps);
+}
+
+static gboolean
+dnf_command_download_run (DnfCommand      *cmd,
+                          int              argc,
+                          char            *argv[],
+                          GOptionContext  *opt_ctx,
+                          DnfContext      *ctx,
+                          GError         **error)
+{
+  g_auto(GStrv) opt_key = NULL;
+  g_autofree gchar *opt_archlist = NULL;
+  gboolean opt_src = FALSE;
+  gboolean opt_resolve = FALSE;
+  gboolean opt_alldeps = FALSE;
+  const GOptionEntry opts[] = {
+    { "archlist", '\0', G_OPTION_FLAG_NONE, G_OPTION_ARG_STRING, 
&opt_archlist, "limit the query to packages of given architectures", 
"ARCH,..."},
+    { "resolve", '\0', G_OPTION_FLAG_NONE, G_OPTION_ARG_NONE, &opt_resolve, 
"resolve and download needed dependencies", NULL },
+    { "alldeps", '\0', G_OPTION_FLAG_NONE, G_OPTION_ARG_NONE, &opt_alldeps, 
"when running with --resolve, download all dependencies (do not exclude already 
installed ones)", NULL },
+    { "source", '\0', G_OPTION_FLAG_NONE, G_OPTION_ARG_NONE, &opt_src, 
"download source packages", NULL },
+    { G_OPTION_REMAINING, '\0', 0, G_OPTION_ARG_STRING_ARRAY, &opt_key, NULL, 
NULL },
+    { NULL }
+  };
+  g_option_context_add_main_entries (opt_ctx, opts, NULL);
+
+  if (!g_option_context_parse (opt_ctx, &argc, &argv, error))
+    return FALSE;
+
+  if (opt_key == NULL)
+    {
+      g_set_error_literal (error,
+                           G_IO_ERROR,
+                           G_IO_ERROR_FAILED,
+                           "Packages are not specified");
+      return FALSE;
+    }
+
+  DnfRepoLoader * repo_loader = dnf_context_get_repo_loader (ctx);
+  // If -source arg was passed, auto-enable the source repositories
+  if (opt_src && !dnf_command_download_enablesourcerepos (ctx, repo_loader, 
error))
+    {
+      return FALSE;
+    }
+
+  DnfState * state = dnf_context_get_state (ctx);
+  DnfContextSetupSackFlags sack_flags = !opt_resolve || opt_alldeps ? 
DNF_CONTEXT_SETUP_SACK_FLAG_SKIP_RPMDB
+                                                                    : 
DNF_CONTEXT_SETUP_SACK_FLAG_NONE;
+  dnf_context_setup_sack_with_flags (ctx, state, sack_flags, error);
+
+  hy_autoquery HyQuery query = get_packages_query (ctx, opt_key, opt_src, 
opt_archlist);
+
+  g_autoptr(GPtrArray) pkgs = hy_query_run (query);
+
+  if (pkgs->len == 0)
+    {
+      g_print ("No packages matched.\n");
+      return FALSE;
+    }
+
+  if (opt_resolve)
+    {
+      GPtrArray *deps = get_packages_deps (ctx, pkgs, error);
+      if (!deps)
+        {
+          return FALSE;
+        }
+      g_ptr_array_extend_and_steal (pkgs, deps);
+    }
+
+  if (!download_packages (repo_loader, pkgs, state, error))
+    {
+      return FALSE;
+    }
+
+  g_print ("Complete.\n");
+
+  return TRUE;
+}
+
+static void
+dnf_command_download_class_init (DnfCommandDownloadClass *klass)
+{
+}
+
+static void
+dnf_command_download_iface_init (DnfCommandInterface *iface)
+{
+  iface->run = dnf_command_download_run;
+}
+
+static void
+dnf_command_download_class_finalize (DnfCommandDownloadClass *klass)
+{
+}
+
+G_MODULE_EXPORT void
+dnf_command_download_register_types (PeasObjectModule *module)
+{
+  dnf_command_download_register_type (G_TYPE_MODULE (module));
+
+  peas_object_module_register_extension_type (module,
+                                              DNF_TYPE_COMMAND,
+                                              DNF_TYPE_COMMAND_DOWNLOAD);
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/microdnf-3.6.0/dnf/plugins/download/dnf-command-download.gresource.xml 
new/microdnf-3.7.0/dnf/plugins/download/dnf-command-download.gresource.xml
--- old/microdnf-3.6.0/dnf/plugins/download/dnf-command-download.gresource.xml  
1970-01-01 01:00:00.000000000 +0100
+++ new/microdnf-3.7.0/dnf/plugins/download/dnf-command-download.gresource.xml  
2021-02-03 03:25:30.000000000 +0100
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<gresources>
+  <gresource prefix="/org/fedoraproject/dnf/plugins/download">
+    <file>download.plugin</file>
+  </gresource>
+</gresources>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/microdnf-3.6.0/dnf/plugins/download/dnf-command-download.h 
new/microdnf-3.7.0/dnf/plugins/download/dnf-command-download.h
--- old/microdnf-3.6.0/dnf/plugins/download/dnf-command-download.h      
1970-01-01 01:00:00.000000000 +0100
+++ new/microdnf-3.7.0/dnf/plugins/download/dnf-command-download.h      
2021-02-03 03:25:30.000000000 +0100
@@ -0,0 +1,31 @@
+/* dnf-command-download.h
+ *
+ * Copyright ?? 2020-2021 Daniel Hams <[email protected]>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#pragma once
+
+#include "dnf-command.h"
+#include <libpeas/peas.h>
+
+G_BEGIN_DECLS
+
+#define DNF_TYPE_COMMAND_DOWNLOAD dnf_command_download_get_type ()
+G_DECLARE_FINAL_TYPE (DnfCommandDownload, dnf_command_download, DNF, 
COMMAND_DOWNLOAD, PeasExtensionBase)
+
+G_MODULE_EXPORT void dnf_command_download_register_types (PeasObjectModule 
*module);
+
+G_END_DECLS
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/microdnf-3.6.0/dnf/plugins/download/download.plugin 
new/microdnf-3.7.0/dnf/plugins/download/download.plugin
--- old/microdnf-3.6.0/dnf/plugins/download/download.plugin     1970-01-01 
01:00:00.000000000 +0100
+++ new/microdnf-3.7.0/dnf/plugins/download/download.plugin     2021-02-03 
03:25:30.000000000 +0100
@@ -0,0 +1,9 @@
+[Plugin]
+Module = command_download
+Embedded = dnf_command_download_register_types
+Name = download
+Description = Download packages
+Authors = Daniel Hams <[email protected]>
+License = GPL-2.0+
+Copyright = Copyright ?? 2020-2021 Daniel Hams
+X-Command-Syntax = download [OPTION???] PACKAGE [PACKAGE???]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/microdnf-3.6.0/dnf/plugins/install/dnf-command-install.c 
new/microdnf-3.7.0/dnf/plugins/install/dnf-command-install.c
--- old/microdnf-3.6.0/dnf/plugins/install/dnf-command-install.c        
2020-12-06 16:32:58.000000000 +0100
+++ new/microdnf-3.7.0/dnf/plugins/install/dnf-command-install.c        
2021-02-03 03:25:30.000000000 +0100
@@ -84,6 +84,8 @@
     return FALSE;
   if (!dnf_utils_print_transaction (ctx))
     return TRUE;
+  if (!dnf_utils_userconfirm ())
+    return FALSE;
   if (!dnf_context_run (ctx, NULL, error))
     return FALSE;
   g_print ("Complete.\n");
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/microdnf-3.6.0/dnf/plugins/module_disable/dnf-command-module_disable.c 
new/microdnf-3.7.0/dnf/plugins/module_disable/dnf-command-module_disable.c
--- old/microdnf-3.6.0/dnf/plugins/module_disable/dnf-command-module_disable.c  
2020-12-06 16:32:58.000000000 +0100
+++ new/microdnf-3.7.0/dnf/plugins/module_disable/dnf-command-module_disable.c  
2021-02-03 03:25:30.000000000 +0100
@@ -85,6 +85,10 @@
     {
       return TRUE;
     }
+  if (!dnf_utils_userconfirm ())
+    {
+      return FALSE;
+    }
   if (!dnf_context_run (ctx, NULL, error))
     {
       return FALSE;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/microdnf-3.6.0/dnf/plugins/module_enable/dnf-command-module_enable.c 
new/microdnf-3.7.0/dnf/plugins/module_enable/dnf-command-module_enable.c
--- old/microdnf-3.6.0/dnf/plugins/module_enable/dnf-command-module_enable.c    
2020-12-06 16:32:58.000000000 +0100
+++ new/microdnf-3.7.0/dnf/plugins/module_enable/dnf-command-module_enable.c    
2021-02-03 03:25:30.000000000 +0100
@@ -89,6 +89,10 @@
     {
       return TRUE;
     }
+  if (!dnf_utils_userconfirm ())
+    {
+      return FALSE;
+    }
   if (!dnf_context_run (ctx, NULL, error))
     {
       return FALSE;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/microdnf-3.6.0/dnf/plugins/module_reset/dnf-command-module_reset.c 
new/microdnf-3.7.0/dnf/plugins/module_reset/dnf-command-module_reset.c
--- old/microdnf-3.6.0/dnf/plugins/module_reset/dnf-command-module_reset.c      
2020-12-06 16:32:58.000000000 +0100
+++ new/microdnf-3.7.0/dnf/plugins/module_reset/dnf-command-module_reset.c      
2021-02-03 03:25:30.000000000 +0100
@@ -89,6 +89,10 @@
     {
       return TRUE;
     }
+  if (!dnf_utils_userconfirm ())
+    {
+      return FALSE;
+    }
   if (!dnf_context_run (ctx, NULL, error))
     {
       return FALSE;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/microdnf-3.6.0/dnf/plugins/reinstall/dnf-command-reinstall.c 
new/microdnf-3.7.0/dnf/plugins/reinstall/dnf-command-reinstall.c
--- old/microdnf-3.6.0/dnf/plugins/reinstall/dnf-command-reinstall.c    
2020-12-06 16:32:58.000000000 +0100
+++ new/microdnf-3.7.0/dnf/plugins/reinstall/dnf-command-reinstall.c    
2021-02-03 03:25:30.000000000 +0100
@@ -160,7 +160,8 @@
 
   if (!dnf_utils_print_transaction (ctx))
     return TRUE;
-
+  if (!dnf_utils_userconfirm ())
+    return FALSE;
   if (!dnf_context_run (ctx, NULL, error))
     return FALSE;
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/microdnf-3.6.0/dnf/plugins/remove/dnf-command-remove.c 
new/microdnf-3.7.0/dnf/plugins/remove/dnf-command-remove.c
--- old/microdnf-3.6.0/dnf/plugins/remove/dnf-command-remove.c  2020-12-06 
16:32:58.000000000 +0100
+++ new/microdnf-3.7.0/dnf/plugins/remove/dnf-command-remove.c  2021-02-03 
03:25:30.000000000 +0100
@@ -87,6 +87,8 @@
   if (!dnf_goal_depsolve (dnf_context_get_goal (ctx), DNF_ERASE, error))
     return FALSE;
   dnf_utils_print_transaction (ctx);
+  if (!dnf_utils_userconfirm ())
+    return FALSE;
   if (!dnf_context_run (ctx, NULL, error))
     return FALSE;
   g_print ("Complete.\n");
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/microdnf-3.6.0/dnf/plugins/update/dnf-command-update.c 
new/microdnf-3.7.0/dnf/plugins/update/dnf-command-update.c
--- old/microdnf-3.6.0/dnf/plugins/update/dnf-command-update.c  2020-12-06 
16:32:58.000000000 +0100
+++ new/microdnf-3.7.0/dnf/plugins/update/dnf-command-update.c  1970-01-01 
01:00:00.000000000 +0100
@@ -1,115 +0,0 @@
-/* dnf-command-update.c
- *
- * Copyright ?? 2016-2017 Igor Gnatenko <[email protected]>
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "dnf-command-update.h"
-#include "dnf-utils.h"
-
-struct _DnfCommandUpdate
-{
-  PeasExtensionBase parent_instance;
-};
-
-static void dnf_command_update_iface_init (DnfCommandInterface *iface);
-
-G_DEFINE_DYNAMIC_TYPE_EXTENDED (DnfCommandUpdate,
-                                dnf_command_update,
-                                PEAS_TYPE_EXTENSION_BASE,
-                                0,
-                                G_IMPLEMENT_INTERFACE (DNF_TYPE_COMMAND,
-                                                       
dnf_command_update_iface_init))
-
-static void
-dnf_command_update_init (DnfCommandUpdate *self)
-{
-}
-
-static gboolean
-dnf_command_update_run (DnfCommand      *cmd,
-                        int              argc,
-                        char            *argv[],
-                        GOptionContext  *opt_ctx,
-                        DnfContext      *ctx,
-                        GError         **error)
-{
-  g_auto(GStrv) pkgs = NULL;
-  const GOptionEntry opts[] = {
-    { G_OPTION_REMAINING, '\0', 0, G_OPTION_ARG_STRING_ARRAY, &pkgs, NULL, 
NULL },
-    { NULL }
-  };
-  g_option_context_add_main_entries (opt_ctx, opts, NULL);
-
-  if (!g_option_context_parse (opt_ctx, &argc, &argv, error))
-    return FALSE;
-
-  if (pkgs == NULL)
-    {
-      if (!dnf_context_update_all (ctx, error))
-        return FALSE;
-    }
-  else
-    {
-      /* Update each package */
-      for (GStrv pkg = pkgs; *pkg != NULL; pkg++)
-        {
-          if (!dnf_context_update (ctx, *pkg, error))
-            return FALSE;
-        }
-    }
-  DnfGoalActions flags = 0;
-  if (dnf_context_get_best())
-    {
-      flags |= DNF_FORCE_BEST;
-    }
-  if (!dnf_context_get_install_weak_deps ())
-    flags |= DNF_IGNORE_WEAK_DEPS;  
-  if (!dnf_goal_depsolve (dnf_context_get_goal (ctx), flags, error))
-    return FALSE;
-  if (!dnf_utils_print_transaction (ctx))
-    return TRUE;
-  if (!dnf_context_run (ctx, NULL, error))
-    return FALSE;
-  g_print ("Complete.\n");
-
-  return TRUE;
-}
-
-static void
-dnf_command_update_class_init (DnfCommandUpdateClass *klass)
-{
-}
-
-static void
-dnf_command_update_iface_init (DnfCommandInterface *iface)
-{
-  iface->run = dnf_command_update_run;
-}
-
-static void
-dnf_command_update_class_finalize (DnfCommandUpdateClass *klass)
-{
-}
-
-G_MODULE_EXPORT void
-dnf_command_update_register_types (PeasObjectModule *module)
-{
-  dnf_command_update_register_type (G_TYPE_MODULE (module));
-
-  peas_object_module_register_extension_type (module,
-                                              DNF_TYPE_COMMAND,
-                                              DNF_TYPE_COMMAND_UPDATE);
-}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/microdnf-3.6.0/dnf/plugins/update/dnf-command-update.gresource.xml 
new/microdnf-3.7.0/dnf/plugins/update/dnf-command-update.gresource.xml
--- old/microdnf-3.6.0/dnf/plugins/update/dnf-command-update.gresource.xml      
2020-12-06 16:32:58.000000000 +0100
+++ new/microdnf-3.7.0/dnf/plugins/update/dnf-command-update.gresource.xml      
1970-01-01 01:00:00.000000000 +0100
@@ -1,6 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<gresources>
-  <gresource prefix="/org/fedoraproject/dnf/plugins/update">
-    <file>update.plugin</file>
-  </gresource>
-</gresources>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/microdnf-3.6.0/dnf/plugins/update/dnf-command-update.h 
new/microdnf-3.7.0/dnf/plugins/update/dnf-command-update.h
--- old/microdnf-3.6.0/dnf/plugins/update/dnf-command-update.h  2020-12-06 
16:32:58.000000000 +0100
+++ new/microdnf-3.7.0/dnf/plugins/update/dnf-command-update.h  1970-01-01 
01:00:00.000000000 +0100
@@ -1,31 +0,0 @@
-/* dnf-command-update.h
- *
- * Copyright ?? 2016 Igor Gnatenko <[email protected]>
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#pragma once
-
-#include "dnf-command.h"
-#include <libpeas/peas.h>
-
-G_BEGIN_DECLS
-
-#define DNF_TYPE_COMMAND_UPDATE dnf_command_update_get_type ()
-G_DECLARE_FINAL_TYPE (DnfCommandUpdate, dnf_command_update, DNF, 
COMMAND_UPDATE, PeasExtensionBase)
-
-G_MODULE_EXPORT void dnf_command_update_register_types (PeasObjectModule 
*module);
-
-G_END_DECLS
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/microdnf-3.6.0/dnf/plugins/update/update.plugin 
new/microdnf-3.7.0/dnf/plugins/update/update.plugin
--- old/microdnf-3.6.0/dnf/plugins/update/update.plugin 2020-12-06 
16:32:58.000000000 +0100
+++ new/microdnf-3.7.0/dnf/plugins/update/update.plugin 1970-01-01 
01:00:00.000000000 +0100
@@ -1,9 +0,0 @@
-[Plugin]
-Module = command_update
-Embedded = dnf_command_update_register_types
-Name = update
-Description = Update packages
-Authors = Igor Gnatenko <[email protected]>
-License = GPL-2.0+
-Copyright = Copyright ?? 2016 Igor Gnatenko
-X-Command-Syntax = update [PACKAGE???]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/microdnf-3.6.0/dnf/plugins/upgrade/dnf-command-upgrade.c 
new/microdnf-3.7.0/dnf/plugins/upgrade/dnf-command-upgrade.c
--- old/microdnf-3.6.0/dnf/plugins/upgrade/dnf-command-upgrade.c        
1970-01-01 01:00:00.000000000 +0100
+++ new/microdnf-3.7.0/dnf/plugins/upgrade/dnf-command-upgrade.c        
2021-02-03 03:25:30.000000000 +0100
@@ -0,0 +1,117 @@
+/* dnf-command-upgrade.c
+ *
+ * Copyright ?? 2016-2017 Igor Gnatenko <[email protected]>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "dnf-command-upgrade.h"
+#include "dnf-utils.h"
+
+struct _DnfCommandUpgrade
+{
+  PeasExtensionBase parent_instance;
+};
+
+static void dnf_command_upgrade_iface_init (DnfCommandInterface *iface);
+
+G_DEFINE_DYNAMIC_TYPE_EXTENDED (DnfCommandUpgrade,
+                                dnf_command_upgrade,
+                                PEAS_TYPE_EXTENSION_BASE,
+                                0,
+                                G_IMPLEMENT_INTERFACE (DNF_TYPE_COMMAND,
+                                                       
dnf_command_upgrade_iface_init))
+
+static void
+dnf_command_upgrade_init (DnfCommandUpgrade *self)
+{
+}
+
+static gboolean
+dnf_command_upgrade_run (DnfCommand      *cmd,
+                         int              argc,
+                         char            *argv[],
+                         GOptionContext  *opt_ctx,
+                         DnfContext      *ctx,
+                         GError         **error)
+{
+  g_auto(GStrv) pkgs = NULL;
+  const GOptionEntry opts[] = {
+    { G_OPTION_REMAINING, '\0', 0, G_OPTION_ARG_STRING_ARRAY, &pkgs, NULL, 
NULL },
+    { NULL }
+  };
+  g_option_context_add_main_entries (opt_ctx, opts, NULL);
+
+  if (!g_option_context_parse (opt_ctx, &argc, &argv, error))
+    return FALSE;
+
+  if (pkgs == NULL)
+    {
+      if (!dnf_context_update_all (ctx, error))
+        return FALSE;
+    }
+  else
+    {
+      /* Upgrade each package */
+      for (GStrv pkg = pkgs; *pkg != NULL; pkg++)
+        {
+          if (!dnf_context_update (ctx, *pkg, error))
+            return FALSE;
+        }
+    }
+  DnfGoalActions flags = 0;
+  if (dnf_context_get_best())
+    {
+      flags |= DNF_FORCE_BEST;
+    }
+  if (!dnf_context_get_install_weak_deps ())
+    flags |= DNF_IGNORE_WEAK_DEPS;  
+  if (!dnf_goal_depsolve (dnf_context_get_goal (ctx), flags, error))
+    return FALSE;
+  if (!dnf_utils_print_transaction (ctx))
+    return TRUE;
+  if (!dnf_utils_userconfirm ())
+    return FALSE;
+  if (!dnf_context_run (ctx, NULL, error))
+    return FALSE;
+  g_print ("Complete.\n");
+
+  return TRUE;
+}
+
+static void
+dnf_command_upgrade_class_init (DnfCommandUpgradeClass *klass)
+{
+}
+
+static void
+dnf_command_upgrade_iface_init (DnfCommandInterface *iface)
+{
+  iface->run = dnf_command_upgrade_run;
+}
+
+static void
+dnf_command_upgrade_class_finalize (DnfCommandUpgradeClass *klass)
+{
+}
+
+G_MODULE_EXPORT void
+dnf_command_upgrade_register_types (PeasObjectModule *module)
+{
+  dnf_command_upgrade_register_type (G_TYPE_MODULE (module));
+
+  peas_object_module_register_extension_type (module,
+                                              DNF_TYPE_COMMAND,
+                                              DNF_TYPE_COMMAND_UPGRADE);
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/microdnf-3.6.0/dnf/plugins/upgrade/dnf-command-upgrade.gresource.xml 
new/microdnf-3.7.0/dnf/plugins/upgrade/dnf-command-upgrade.gresource.xml
--- old/microdnf-3.6.0/dnf/plugins/upgrade/dnf-command-upgrade.gresource.xml    
1970-01-01 01:00:00.000000000 +0100
+++ new/microdnf-3.7.0/dnf/plugins/upgrade/dnf-command-upgrade.gresource.xml    
2021-02-03 03:25:30.000000000 +0100
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<gresources>
+  <gresource prefix="/org/fedoraproject/dnf/plugins/upgrade">
+    <file>upgrade.plugin</file>
+  </gresource>
+</gresources>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/microdnf-3.6.0/dnf/plugins/upgrade/dnf-command-upgrade.h 
new/microdnf-3.7.0/dnf/plugins/upgrade/dnf-command-upgrade.h
--- old/microdnf-3.6.0/dnf/plugins/upgrade/dnf-command-upgrade.h        
1970-01-01 01:00:00.000000000 +0100
+++ new/microdnf-3.7.0/dnf/plugins/upgrade/dnf-command-upgrade.h        
2021-02-03 03:25:30.000000000 +0100
@@ -0,0 +1,31 @@
+/* dnf-command-upgrade.h
+ *
+ * Copyright ?? 2016 Igor Gnatenko <[email protected]>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#pragma once
+
+#include "dnf-command.h"
+#include <libpeas/peas.h>
+
+G_BEGIN_DECLS
+
+#define DNF_TYPE_COMMAND_UPGRADE dnf_command_upgrade_get_type ()
+G_DECLARE_FINAL_TYPE (DnfCommandUpgrade, dnf_command_upgrade, DNF, 
COMMAND_UPGRADE, PeasExtensionBase)
+
+G_MODULE_EXPORT void dnf_command_upgrade_register_types (PeasObjectModule 
*module);
+
+G_END_DECLS
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/microdnf-3.6.0/dnf/plugins/upgrade/upgrade.plugin 
new/microdnf-3.7.0/dnf/plugins/upgrade/upgrade.plugin
--- old/microdnf-3.6.0/dnf/plugins/upgrade/upgrade.plugin       1970-01-01 
01:00:00.000000000 +0100
+++ new/microdnf-3.7.0/dnf/plugins/upgrade/upgrade.plugin       2021-02-03 
03:25:30.000000000 +0100
@@ -0,0 +1,11 @@
+[Plugin]
+Module = command_upgrade
+Embedded = dnf_command_upgrade_register_types
+Name = upgrade
+Description = Upgrade packages
+Authors = Igor Gnatenko <[email protected]>
+License = GPL-2.0+
+Copyright = Copyright ?? 2016 Igor Gnatenko
+X-Command-Syntax = upgrade [PACKAGE???]
+X-Alias-Name = update
+X-Alias-Description = Compatibility alias for the "upgrade" command
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/microdnf-3.6.0/meson.build 
new/microdnf-3.7.0/meson.build
--- old/microdnf-3.6.0/meson.build      2020-12-06 16:32:58.000000000 +0100
+++ new/microdnf-3.7.0/meson.build      2021-02-03 03:25:30.000000000 +0100
@@ -1,5 +1,5 @@
 project('microdnf', 'c',
-        version : '3.6.0',
+        version : '3.7.0',
         license : 'GPL-2.0+',
         default_options : [
           'b_asneeded=True',
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/microdnf-3.6.0/microdnf.spec 
new/microdnf-3.7.0/microdnf.spec
--- old/microdnf-3.6.0/microdnf.spec    2020-12-06 16:32:58.000000000 +0100
+++ new/microdnf-3.7.0/microdnf.spec    2021-02-03 03:25:30.000000000 +0100
@@ -1,7 +1,7 @@
-%global libdnf_version 0.55.2
+%global libdnf_version 0.56.0
 
 Name:           microdnf
-Version:        3.6.0
+Version:        3.7.0
 Release:        1%{?dist}
 Summary:        Lightweight implementation of DNF in C
 
@@ -19,8 +19,10 @@
 BuildRequires:  help2man
 
 Requires:       libdnf%{?_isa} >= %{libdnf_version}
+%if 0%{?rhel} > 8 || 0%{?fedora}
 # Ensure DNF package manager configuration skeleton is installed
 Requires:       dnf-data
+%endif
 
 %description
 Micro DNF is a lightweight C implementation of DNF, designed to be used

Reply via email to