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
