From 0d0bae13753b99972eb4261ca83f35f96774ebf8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BC=A0=E6=80=9D=E5=AD=A6?= <1357767065@qq.com> Date: Tue, 27 Sep 2022 11:19:32 +0800 Subject: [PATCH] =?UTF-8?q?DNF=E5=8C=85=E7=AE=A1=E7=90=86=E5=B7=A5?= =?UTF-8?q?=E5=85=B7=E8=B5=9B=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- rust-dnf/.gitignore | 3 + rust-dnf/Cargo.toml | 9 + rust-dnf/dnf-command.c | 41 ++ rust-dnf/dnf-command.h | 48 ++ rust-dnf/dnf-main.c | 690 ++++++++++++++++++ rust-dnf/dnf-utils.c | 255 +++++++ rust-dnf/dnf-utils.h | 31 + rust-dnf/plugins/Cargo.toml | 9 + rust-dnf/plugins/clean all/clean.plugin | 9 + .../plugins/clean all/dnf-command-clean.c | 135 ++++ .../clean all/dnf-command-clean.gresource.xml | 6 + .../plugins/clean all/dnf-command-clean.h | 31 + .../plugins/distros-ync/distrosync.plugin | 11 + .../distros-ync/dnf-command-distrosync.c | 117 +++ .../dnf-command-distrosync.gresource.xml | 6 + .../distros-ync/dnf-command-distrosync.h | 31 + rust-dnf/plugins/dnf-command.c | 41 ++ rust-dnf/plugins/dnf-command.h | 48 ++ rust-dnf/plugins/dnf-main.c | 690 ++++++++++++++++++ rust-dnf/plugins/dnf-utils.c | 255 +++++++ rust-dnf/plugins/dnf-utils.h | 31 + .../plugins/install/dnf-command-install.c | 120 +++ .../install/dnf-command-install.gresource.xml | 6 + .../plugins/install/dnf-command-install.h | 31 + rust-dnf/plugins/install/install.plugin | 9 + .../plugins/reinstall/dnf-command-reinstall.c | 197 +++++ .../dnf-command-reinstall.gresource.xml | 6 + .../plugins/reinstall/dnf-command-reinstall.h | 33 + rust-dnf/plugins/reinstall/reinstall.plugin | 9 + rust-dnf/plugins/remove/dnf-command-remove.c | 123 ++++ .../remove/dnf-command-remove.gresource.xml | 6 + rust-dnf/plugins/remove/dnf-command-remove.h | 31 + rust-dnf/plugins/remove/remove.plugin | 9 + .../dnf-command-repolist.gresource.xml | 6 + .../plugins/repolist/dnf-command-repolist.rs | 162 ++++ rust-dnf/plugins/repolist/repolist.plugin | 9 + rust-dnf/src/main.rs | 3 + 37 files changed, 3257 insertions(+) create mode 100644 rust-dnf/.gitignore create mode 100644 rust-dnf/Cargo.toml create mode 100644 rust-dnf/dnf-command.c create mode 100644 rust-dnf/dnf-command.h create mode 100644 rust-dnf/dnf-main.c create mode 100644 rust-dnf/dnf-utils.c create mode 100644 rust-dnf/dnf-utils.h create mode 100644 rust-dnf/plugins/Cargo.toml create mode 100644 rust-dnf/plugins/clean all/clean.plugin create mode 100644 rust-dnf/plugins/clean all/dnf-command-clean.c create mode 100644 rust-dnf/plugins/clean all/dnf-command-clean.gresource.xml create mode 100644 rust-dnf/plugins/clean all/dnf-command-clean.h create mode 100644 rust-dnf/plugins/distros-ync/distrosync.plugin create mode 100644 rust-dnf/plugins/distros-ync/dnf-command-distrosync.c create mode 100644 rust-dnf/plugins/distros-ync/dnf-command-distrosync.gresource.xml create mode 100644 rust-dnf/plugins/distros-ync/dnf-command-distrosync.h create mode 100644 rust-dnf/plugins/dnf-command.c create mode 100644 rust-dnf/plugins/dnf-command.h create mode 100644 rust-dnf/plugins/dnf-main.c create mode 100644 rust-dnf/plugins/dnf-utils.c create mode 100644 rust-dnf/plugins/dnf-utils.h create mode 100644 rust-dnf/plugins/install/dnf-command-install.c create mode 100644 rust-dnf/plugins/install/dnf-command-install.gresource.xml create mode 100644 rust-dnf/plugins/install/dnf-command-install.h create mode 100644 rust-dnf/plugins/install/install.plugin create mode 100644 rust-dnf/plugins/reinstall/dnf-command-reinstall.c create mode 100644 rust-dnf/plugins/reinstall/dnf-command-reinstall.gresource.xml create mode 100644 rust-dnf/plugins/reinstall/dnf-command-reinstall.h create mode 100644 rust-dnf/plugins/reinstall/reinstall.plugin create mode 100644 rust-dnf/plugins/remove/dnf-command-remove.c create mode 100644 rust-dnf/plugins/remove/dnf-command-remove.gresource.xml create mode 100644 rust-dnf/plugins/remove/dnf-command-remove.h create mode 100644 rust-dnf/plugins/remove/remove.plugin create mode 100644 rust-dnf/plugins/repolist/dnf-command-repolist.gresource.xml create mode 100644 rust-dnf/plugins/repolist/dnf-command-repolist.rs create mode 100644 rust-dnf/plugins/repolist/repolist.plugin create mode 100644 rust-dnf/src/main.rs diff --git a/rust-dnf/.gitignore b/rust-dnf/.gitignore new file mode 100644 index 00000000..2f5541fc --- /dev/null +++ b/rust-dnf/.gitignore @@ -0,0 +1,3 @@ +/target +/.git +/.vscode \ No newline at end of file diff --git a/rust-dnf/Cargo.toml b/rust-dnf/Cargo.toml new file mode 100644 index 00000000..f7696c44 --- /dev/null +++ b/rust-dnf/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "rust-dnf" +version = "0.1.0" +edition = "2022" + +[dependencies] +clap = { version = "3.0.14", features = ["derive"] } +filetime = "0.2" +chrono = "0.4.19" \ No newline at end of file diff --git a/rust-dnf/dnf-command.c b/rust-dnf/dnf-command.c new file mode 100644 index 00000000..fa9d02a5 --- /dev/null +++ b/rust-dnf/dnf-command.c @@ -0,0 +1,41 @@ +/* dnf-command.c + * + * Copyright © 2016 Igor Gnatenko + * + * 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 . + */ + +#include "dnf-command.h" + +G_DEFINE_INTERFACE (DnfCommand, dnf_command, G_TYPE_OBJECT) + +static void +dnf_command_default_init (DnfCommandInterface *iface) +{ +} + +gboolean +dnf_command_run (DnfCommand *cmd, + int argc, + char *argv[], + GOptionContext *opt_ctx, + DnfContext *ctx, + GError **error) +{ + g_return_val_if_fail (DNF_IS_COMMAND (cmd), FALSE); + + DnfCommandInterface *iface = DNF_COMMAND_GET_IFACE (cmd); + g_return_val_if_fail (iface->run, TRUE); + return iface->run (cmd, argc, argv, opt_ctx, ctx, error); +} diff --git a/rust-dnf/dnf-command.h b/rust-dnf/dnf-command.h new file mode 100644 index 00000000..16572c47 --- /dev/null +++ b/rust-dnf/dnf-command.h @@ -0,0 +1,48 @@ +/* dnf-command.h + * + * Copyright © 2016 Igor Gnatenko + * + * 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 . + */ + +#pragma once + +#include +#include + +G_BEGIN_DECLS + +#define DNF_TYPE_COMMAND dnf_command_get_type () +G_DECLARE_INTERFACE (DnfCommand, dnf_command, DNF, COMMAND, GObject) + +struct _DnfCommandInterface +{ + GTypeInterface parent_iface; + + gboolean (*run) (DnfCommand *cmd, + int argc, + char *argv[], + GOptionContext *opt_ctx, + DnfContext *ctx, + GError **error); +}; + +gboolean dnf_command_run (DnfCommand *cmd, + int argc, + char *argv[], + GOptionContext *opt_ctx, + DnfContext *ctx, + GError **error); + +G_END_DECLS diff --git a/rust-dnf/dnf-main.c b/rust-dnf/dnf-main.c new file mode 100644 index 00000000..661dfee7 --- /dev/null +++ b/rust-dnf/dnf-main.c @@ -0,0 +1,690 @@ +/* dnf-main.c + * + * Copyright © 2010-2015 Richard Hughes + * Copyright © 2016 Colin Walters + * Copyright © 2016-2017 Igor Gnatenko + * Copyright © 2017-2021 Jaroslav Rohel + * + * 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 . + */ + +#include +#include +#include +#include +#include +#include +#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 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; +static gboolean opt_test = FALSE; +static gboolean opt_refresh = FALSE; +static gboolean show_help = FALSE; +static gboolean dl_pkgs_printed = FALSE; +static GSList *enable_disable_repos = NULL; +static gboolean disable_plugins_loading = FALSE; +static gboolean config_used = FALSE; +static gboolean enable_disable_plugin_used = FALSE; +static gboolean installroot_used = FALSE; +static gboolean cachedir_used = FALSE; +static gboolean reposdir_used = FALSE; +static gboolean varsdir_used = FALSE; + +static gboolean +process_global_option (const gchar *option_name, + const gchar *value, + gpointer data, + GError **error) +{ + g_autoptr(GError) local_error = NULL; + DnfContext *ctx = DNF_CONTEXT (data); + + gboolean ret = TRUE; + if (g_strcmp0 (option_name, "--config") == 0) + { + config_used = TRUE; + dnf_context_set_config_file_path (value); + } + else if (g_strcmp0 (option_name, "--disablerepo") == 0) + { + enable_disable_repos = g_slist_append (enable_disable_repos, g_strconcat("d", value, NULL)); + } + else if (g_strcmp0 (option_name, "--enablerepo") == 0) + { + enable_disable_repos = g_slist_append (enable_disable_repos, g_strconcat("e", value, NULL)); + } + else if (g_strcmp0 (option_name, "--disableplugin") == 0) + { + g_auto(GStrv) patterns = g_strsplit (value, ",", -1); + for (char **it = patterns; *it; ++it) + dnf_context_disable_plugins (*it); + enable_disable_plugin_used = TRUE; + } + else if (g_strcmp0 (option_name, "--enableplugin") == 0) + { + g_auto(GStrv) patterns = g_strsplit (value, ",", -1); + for (char **it = patterns; *it; ++it) + dnf_context_enable_plugins (*it); + enable_disable_plugin_used = TRUE; + } + else if (g_strcmp0 (option_name, "--installroot") == 0) + { + installroot_used = TRUE; + if (value[0] != '/') + { + local_error = g_error_new (G_OPTION_ERROR, + G_OPTION_ERROR_BAD_VALUE, + "Absolute path must be used"); + ret = FALSE; + } + else + { + dnf_context_set_install_root (ctx, value); + } + } + else if (g_strcmp0 (option_name, "--releasever") == 0) + { + dnf_context_set_release_ver (ctx, value); + } + else if (g_strcmp0 (option_name, "--setopt") == 0) + { + g_auto(GStrv) setopt = g_strsplit (value, "=", 2); + if (!setopt[0] || !setopt[1]) + { + local_error = g_error_new (G_OPTION_ERROR, + G_OPTION_ERROR_BAD_VALUE, + "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); + for (char **it = tsflags; *it; ++it) + { + if (strcmp (*it, "nodocs") == 0) + opt_nodocs = TRUE; + else if (strcmp (*it, "test") == 0) + opt_test = TRUE; + else + { + local_error = g_error_new (G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE, + "Unknown tsflag: %s", *it); + ret = FALSE; + break; + } + } + } + else if (strcmp (setopt[0], "module_platform_id") == 0) + { + const char *module_platform_id = setopt[1]; + if (module_platform_id[0] != '\0') + { + dnf_context_set_platform_module (ctx, module_platform_id); + } + else + { + local_error = g_error_new (G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE, + "Empty value in: %s", value); + ret = FALSE; + } + } + else if (strcmp (setopt[0], "cachedir") == 0) + { + cachedir_used = TRUE; + const char *cachedir = setopt[1]; + if (cachedir[0] != '\0') + { + g_autofree gchar *metadatadir = g_build_path ("/", cachedir, "metadata", NULL); + dnf_context_set_cache_dir (ctx, metadatadir); + g_autofree gchar *solvdir = g_build_path ("/", cachedir, "solv", NULL); + dnf_context_set_solv_dir (ctx, solvdir); + g_autofree gchar *lockdir = g_build_path ("/", cachedir, "lock", NULL); + dnf_context_set_lock_dir (ctx, lockdir); + } + else + { + local_error = g_error_new (G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE, + "Empty value in: %s", value); + ret = FALSE; + } + } + else if (strcmp (setopt[0], "install_weak_deps") == 0) + { + const char *setopt_val = setopt[1]; + if (setopt_val[0] == '1' && setopt_val[1] == '\0') + opt_install_weak_deps = ARG_TRUE; + else if (setopt_val[0] == '0' && setopt_val[1] == '\0') + opt_install_weak_deps = 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], "allow_vendor_change") == 0) + { + const char *setopt_val = setopt[1]; + if (setopt_val[0] == '1' && setopt_val[1] == '\0') + opt_allow_vendor_change = ARG_TRUE; + else if (setopt_val[0] == '0' && setopt_val[1] == '\0') + opt_allow_vendor_change = 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], "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; + g_auto(GStrv) reposdir = g_strsplit (setopt[1], ",", -1); + dnf_context_set_repos_dir (ctx, (const gchar * const *)reposdir); + } + else if (strcmp (setopt[0], "varsdir") == 0) + { + varsdir_used = TRUE; + g_auto(GStrv) varsdir = g_strsplit (setopt[1], ",", -1); + dnf_context_set_vars_dir (ctx, (const gchar * const *)varsdir); + } + else + { + local_error = g_error_new (G_OPTION_ERROR, + G_OPTION_ERROR_BAD_VALUE, + "Unable to handle: %s", value); + ret = FALSE; + } + } + else + g_assert_not_reached (); + + if (local_error != NULL) + g_set_error (error, + G_OPTION_ERROR, + G_OPTION_ERROR_BAD_VALUE, + "(%s) %s", option_name, local_error->message); + + return ret; +} + +static const GOptionEntry global_opts[] = { + { "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", "" }, + { "disablerepo", '\0', G_OPTION_FLAG_NONE, G_OPTION_ARG_CALLBACK, process_global_option, "Disable repository by an id", "ID" }, + { "disableplugin", '\0', G_OPTION_FLAG_NONE, G_OPTION_ARG_CALLBACK, process_global_option, "Disable plugins by name", "name" }, + { "enablerepo", '\0', G_OPTION_FLAG_NONE, G_OPTION_ARG_CALLBACK, process_global_option, "Enable repository by an id", "ID" }, + { "enableplugin", '\0', G_OPTION_FLAG_NONE, G_OPTION_ARG_CALLBACK, process_global_option, "Enable plugins by name", "name" }, + { "nobest", '\0', G_OPTION_FLAG_NONE, G_OPTION_ARG_NONE, &opt_nobest, "Do not limit the transaction to the best candidates", NULL }, + { "installroot", '\0', G_OPTION_FLAG_NONE, G_OPTION_ARG_CALLBACK, process_global_option, "Set install root", "PATH" }, + { "nodocs", '\0', G_OPTION_FLAG_NONE, G_OPTION_ARG_NONE, &opt_nodocs, "Install packages without docs", NULL }, + { "noplugins", '\0', G_OPTION_FLAG_NONE, G_OPTION_ARG_NONE, &disable_plugins_loading, "Disable loading of plugins", NULL }, + { "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, keepcache=0/1, module_platform_id=, cachedir=, reposdir=,,..., tsflags=nodocs/test, varsdir=,,..., repo_id.option_name=)", "