From 79136b54a2800d40260b473564e300b9716d2d80 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BC=A0=E6=80=9D=E5=AD=A6?= <“zhang_sx@hisuntech.com”> Date: Wed, 24 Aug 2022 11:44:41 +0800 Subject: [PATCH 1/3] =?UTF-8?q?feat:=20=E5=88=9D=E5=A7=8B=E5=8C=96rust-dnf?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- rust-dnf/.gitignore | 3 +++ rust-dnf/Cargo.toml | 11 +++++++++++ rust-dnf/src/main.rs | 3 +++ 3 files changed, 17 insertions(+) create mode 100644 rust-dnf/.gitignore create mode 100644 rust-dnf/Cargo.toml 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..b005ecec --- /dev/null +++ b/rust-dnf/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "rdiff" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[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/src/main.rs b/rust-dnf/src/main.rs new file mode 100644 index 00000000..e7a11a96 --- /dev/null +++ b/rust-dnf/src/main.rs @@ -0,0 +1,3 @@ +fn main() { + println!("Hello, world!"); +} -- Gitee From 4ee2c88b1bff9d88f2b0f4e35747595fa85bdd38 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BC=A0=E6=80=9D=E5=AD=A6?= <“zhang_sx@hisuntech.com”> Date: Wed, 24 Aug 2022 15:03:38 +0800 Subject: [PATCH 2/3] =?UTF-8?q?feat:clean=20all=E3=80=81distro-sync?= =?UTF-8?q?=E3=80=81install=E3=80=81reinstall=E3=80=81remove=E3=80=81repol?= =?UTF-8?q?ist?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- rust-dnf/Cargo.toml | 6 +- 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 +++ .../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 + 25 files changed, 1114 insertions(+), 4 deletions(-) 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/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 diff --git a/rust-dnf/Cargo.toml b/rust-dnf/Cargo.toml index b005ecec..f7696c44 100644 --- a/rust-dnf/Cargo.toml +++ b/rust-dnf/Cargo.toml @@ -1,9 +1,7 @@ [package] -name = "rdiff" +name = "rust-dnf" version = "0.1.0" -edition = "2021" - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html +edition = "2022" [dependencies] clap = { version = "3.0.14", features = ["derive"] } diff --git a/rust-dnf/plugins/Cargo.toml b/rust-dnf/plugins/Cargo.toml new file mode 100644 index 00000000..f273200f --- /dev/null +++ b/rust-dnf/plugins/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "plugins" +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/plugins/clean all/clean.plugin b/rust-dnf/plugins/clean all/clean.plugin new file mode 100644 index 00000000..5d9b872a --- /dev/null +++ b/rust-dnf/plugins/clean all/clean.plugin @@ -0,0 +1,9 @@ +[Plugin] +Module = command_clean +Embedded = dnf_command_clean_register_types +Name = clean +Description = Remove cached data +Authors = Jaroslav Rohel +License = GPL-2.0+ +Copyright = Copyright © 2017 Jaroslav Rohel +X-Command-Syntax = clean all diff --git a/rust-dnf/plugins/clean all/dnf-command-clean.c b/rust-dnf/plugins/clean all/dnf-command-clean.c new file mode 100644 index 00000000..0f15ec3a --- /dev/null +++ b/rust-dnf/plugins/clean all/dnf-command-clean.c @@ -0,0 +1,135 @@ +/* dnf-command-clean.c + * + * Copyright © 2017 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 "dnf-command-clean.h" + +struct _DnfCommandClean +{ + PeasExtensionBase parent_instance; +}; + +static void dnf_command_clean_iface_init (DnfCommandInterface *iface); + +G_DEFINE_DYNAMIC_TYPE_EXTENDED (DnfCommandClean, + dnf_command_clean, + PEAS_TYPE_EXTENSION_BASE, + 0, + G_IMPLEMENT_INTERFACE (DNF_TYPE_COMMAND, + dnf_command_clean_iface_init)) + +static void +dnf_command_clean_init (DnfCommandClean *self) +{ +} + +static gboolean +dnf_command_clean_run (DnfCommand *cmd, + int argc, + char *argv[], + GOptionContext *opt_ctx, + DnfContext *ctx, + GError **error) +{ + g_auto(GStrv) types = NULL; + const GOptionEntry opts[] = { + { G_OPTION_REMAINING, '\0', 0, G_OPTION_ARG_STRING_ARRAY, &types, 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 (types == NULL) + { + g_set_error_literal (error, + G_IO_ERROR, + G_IO_ERROR_FAILED, + "Clean requires argument: all"); + return FALSE; + } + + if (g_strcmp0 (types[0], "all") != 0) + { + g_set_error (error, + G_IO_ERROR, + G_IO_ERROR_FAILED, + "Invalid clean argument: '%s'", *types); + return FALSE; + } + + if (types[1] != NULL) + { + g_set_error_literal (error, + G_IO_ERROR, + G_IO_ERROR_FAILED, + "Too many arguments. Clean accepts only one argument."); + return FALSE; + } + + /* lock cache */ + g_autoptr(DnfLock) lock = dnf_lock_new (); + dnf_lock_set_lock_dir (lock, dnf_context_get_lock_dir (ctx)); + guint lock_id = dnf_lock_take (lock, + DNF_LOCK_TYPE_METADATA, + DNF_LOCK_MODE_PROCESS, + error); + if (lock_id == 0) + return FALSE; + + /* Clean cached data */ + const gchar *cachedir = dnf_context_get_cache_dir (ctx); + if (!dnf_remove_recursive (cachedir, error)) + return FALSE; + const gchar *solvdir = dnf_context_get_solv_dir (ctx); + if (!dnf_remove_recursive (solvdir, error)) + return FALSE; + + if (!dnf_lock_release (lock, lock_id, error)) + return FALSE; + + g_print ("Complete.\n"); + + return TRUE; +} + +static void +dnf_command_clean_class_init (DnfCommandCleanClass *klass) +{ +} + +static void +dnf_command_clean_iface_init (DnfCommandInterface *iface) +{ + iface->run = dnf_command_clean_run; +} + +static void +dnf_command_clean_class_finalize (DnfCommandCleanClass *klass) +{ +} + +G_MODULE_EXPORT void +dnf_command_clean_register_types (PeasObjectModule *module) +{ + dnf_command_clean_register_type (G_TYPE_MODULE (module)); + + peas_object_module_register_extension_type (module, + DNF_TYPE_COMMAND, + DNF_TYPE_COMMAND_CLEAN); +} diff --git a/rust-dnf/plugins/clean all/dnf-command-clean.gresource.xml b/rust-dnf/plugins/clean all/dnf-command-clean.gresource.xml new file mode 100644 index 00000000..07e649d6 --- /dev/null +++ b/rust-dnf/plugins/clean all/dnf-command-clean.gresource.xml @@ -0,0 +1,6 @@ + + + + clean.plugin + + diff --git a/rust-dnf/plugins/clean all/dnf-command-clean.h b/rust-dnf/plugins/clean all/dnf-command-clean.h new file mode 100644 index 00000000..ed9a2ebe --- /dev/null +++ b/rust-dnf/plugins/clean all/dnf-command-clean.h @@ -0,0 +1,31 @@ +/* dnf-command-clean.h + * + * Copyright © 2017 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 . + */ + +#pragma once + +#include "dnf-command.h" +#include + +G_BEGIN_DECLS + +#define DNF_TYPE_COMMAND_CLEAN dnf_command_clean_get_type () +G_DECLARE_FINAL_TYPE (DnfCommandClean, dnf_command_clean, DNF, COMMAND_CLEAN, PeasExtensionBase) + +G_MODULE_EXPORT void dnf_command_clean_register_types (PeasObjectModule *module); + +G_END_DECLS diff --git a/rust-dnf/plugins/distros-ync/distrosync.plugin b/rust-dnf/plugins/distros-ync/distrosync.plugin new file mode 100644 index 00000000..aa5a5672 --- /dev/null +++ b/rust-dnf/plugins/distros-ync/distrosync.plugin @@ -0,0 +1,11 @@ +[Plugin] +Module = command_distro-sync +Embedded = dnf_command_distrosync_register_types +Name = distro-sync +Description = Upgrade/downgrade packages to match versions in repositories +Authors = Neal Gompa +License = GPL-2.0+ +Copyright = Copyright © 2021 Neal Gompa +X-Command-Syntax = distro-sync [PACKAGE…] +X-Alias-Name = dsync +X-Alias-Description = Compatibility alias for the "distro-sync" command diff --git a/rust-dnf/plugins/distros-ync/dnf-command-distrosync.c b/rust-dnf/plugins/distros-ync/dnf-command-distrosync.c new file mode 100644 index 00000000..1aa536a2 --- /dev/null +++ b/rust-dnf/plugins/distros-ync/dnf-command-distrosync.c @@ -0,0 +1,117 @@ +/* dnf-command-distrosync.c + * + * Copyright © 2021 Neal Gompa + * + * 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-distrosync.h" +#include "dnf-utils.h" + +struct _DnfCommandDistroSync +{ + PeasExtensionBase parent_instance; +}; + +static void dnf_command_distrosync_iface_init (DnfCommandInterface *iface); + +G_DEFINE_DYNAMIC_TYPE_EXTENDED (DnfCommandDistroSync, + dnf_command_distrosync, + PEAS_TYPE_EXTENSION_BASE, + 0, + G_IMPLEMENT_INTERFACE (DNF_TYPE_COMMAND, + dnf_command_distrosync_iface_init)) + +static void +dnf_command_distrosync_init (DnfCommandDistroSync *self) +{ +} + +static gboolean +dnf_command_distrosync_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_distrosync_all (ctx, error)) + return FALSE; + } + else + { + /* Sync each package */ + for (GStrv pkg = pkgs; *pkg != NULL; pkg++) + { + if (!dnf_context_distrosync (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_distrosync_class_init (DnfCommandDistroSyncClass *klass) +{ +} + +static void +dnf_command_distrosync_iface_init (DnfCommandInterface *iface) +{ + iface->run = dnf_command_distrosync_run; +} + +static void +dnf_command_distrosync_class_finalize (DnfCommandDistroSyncClass *klass) +{ +} + +G_MODULE_EXPORT void +dnf_command_distrosync_register_types (PeasObjectModule *module) +{ + dnf_command_distrosync_register_type (G_TYPE_MODULE (module)); + + peas_object_module_register_extension_type (module, + DNF_TYPE_COMMAND, + DNF_TYPE_COMMAND_DISTROSYNC); +} diff --git a/rust-dnf/plugins/distros-ync/dnf-command-distrosync.gresource.xml b/rust-dnf/plugins/distros-ync/dnf-command-distrosync.gresource.xml new file mode 100644 index 00000000..61b94156 --- /dev/null +++ b/rust-dnf/plugins/distros-ync/dnf-command-distrosync.gresource.xml @@ -0,0 +1,6 @@ + + + + distrosync.plugin + + diff --git a/rust-dnf/plugins/distros-ync/dnf-command-distrosync.h b/rust-dnf/plugins/distros-ync/dnf-command-distrosync.h new file mode 100644 index 00000000..711e7059 --- /dev/null +++ b/rust-dnf/plugins/distros-ync/dnf-command-distrosync.h @@ -0,0 +1,31 @@ +/* dnf-command-distrosync.h + * + * Copyright © 2021 Neal Gompa + * + * 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 "dnf-command.h" +#include + +G_BEGIN_DECLS + +#define DNF_TYPE_COMMAND_DISTROSYNC dnf_command_distrosync_get_type () +G_DECLARE_FINAL_TYPE (DnfCommandDistroSync, dnf_command_distrosync, DNF, COMMAND_DISTROSYNC, PeasExtensionBase) + +G_MODULE_EXPORT void dnf_command_distrosync_register_types (PeasObjectModule *module); + +G_END_DECLS diff --git a/rust-dnf/plugins/install/dnf-command-install.c b/rust-dnf/plugins/install/dnf-command-install.c new file mode 100644 index 00000000..edb561b9 --- /dev/null +++ b/rust-dnf/plugins/install/dnf-command-install.c @@ -0,0 +1,120 @@ +/* dnf-command-install.c + * + * Copyright © 2010-2015 Richard Hughes + * Copyright © 2016 Colin Walters + * Copyright © 2016-2017 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-install.h" +#include "dnf-utils.h" + +struct _DnfCommandInstall +{ + PeasExtensionBase parent_instance; +}; + +static void dnf_command_install_iface_init (DnfCommandInterface *iface); + +G_DEFINE_DYNAMIC_TYPE_EXTENDED (DnfCommandInstall, + dnf_command_install, + PEAS_TYPE_EXTENSION_BASE, + 0, + G_IMPLEMENT_INTERFACE (DNF_TYPE_COMMAND, + dnf_command_install_iface_init)) + +static void +dnf_command_install_init (DnfCommandInstall *self) +{ +} + +static gboolean +dnf_command_install_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) + { + g_set_error_literal (error, + G_IO_ERROR, + G_IO_ERROR_FAILED, + "Packages are not specified"); + return FALSE; + } + + /* Install each package */ + for (GStrv pkg = pkgs; *pkg != NULL; pkg++) + { + if (!dnf_context_install (ctx, *pkg, error)) + return FALSE; + } + DnfGoalActions flags = DNF_INSTALL; + 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_install_class_init (DnfCommandInstallClass *klass) +{ +} + +static void +dnf_command_install_iface_init (DnfCommandInterface *iface) +{ + iface->run = dnf_command_install_run; +} + +static void +dnf_command_install_class_finalize (DnfCommandInstallClass *klass) +{ +} + +G_MODULE_EXPORT void +dnf_command_install_register_types (PeasObjectModule *module) +{ + dnf_command_install_register_type (G_TYPE_MODULE (module)); + + peas_object_module_register_extension_type (module, + DNF_TYPE_COMMAND, + DNF_TYPE_COMMAND_INSTALL); +} diff --git a/rust-dnf/plugins/install/dnf-command-install.gresource.xml b/rust-dnf/plugins/install/dnf-command-install.gresource.xml new file mode 100644 index 00000000..843ec5c8 --- /dev/null +++ b/rust-dnf/plugins/install/dnf-command-install.gresource.xml @@ -0,0 +1,6 @@ + + + + install.plugin + + diff --git a/rust-dnf/plugins/install/dnf-command-install.h b/rust-dnf/plugins/install/dnf-command-install.h new file mode 100644 index 00000000..aac63f5d --- /dev/null +++ b/rust-dnf/plugins/install/dnf-command-install.h @@ -0,0 +1,31 @@ +/* dnf-command-install.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 "dnf-command.h" +#include + +G_BEGIN_DECLS + +#define DNF_TYPE_COMMAND_INSTALL dnf_command_install_get_type () +G_DECLARE_FINAL_TYPE (DnfCommandInstall, dnf_command_install, DNF, COMMAND_INSTALL, PeasExtensionBase) + +G_MODULE_EXPORT void dnf_command_install_register_types (PeasObjectModule *module); + +G_END_DECLS diff --git a/rust-dnf/plugins/install/install.plugin b/rust-dnf/plugins/install/install.plugin new file mode 100644 index 00000000..45dd84b5 --- /dev/null +++ b/rust-dnf/plugins/install/install.plugin @@ -0,0 +1,9 @@ +[Plugin] +Module = command_install +Embedded = dnf_command_install_register_types +Name = install +Description = Install packages +Authors = Richard Hughes , Colin Walters , Igor Gnatenko +License = GPL-2.0+ +Copyright = Copyright © 2010-2016 Richard Hughes, Colin Walters, Igor Gnatenko +X-Command-Syntax = install PACKAGE [PACKAGE…] diff --git a/rust-dnf/plugins/reinstall/dnf-command-reinstall.c b/rust-dnf/plugins/reinstall/dnf-command-reinstall.c new file mode 100644 index 00000000..0985de4b --- /dev/null +++ b/rust-dnf/plugins/reinstall/dnf-command-reinstall.c @@ -0,0 +1,197 @@ +/* + * Copyright (C) 2019 Red Hat, Inc. + * + * Licensed under the GNU Lesser General Public License Version 2.1 + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "dnf-command-reinstall.h" +#include "dnf-utils.h" + +struct _DnfCommandReinstall +{ + PeasExtensionBase parent_instance; +}; + +static void dnf_command_reinstall_iface_init (DnfCommandInterface *iface); + +G_DEFINE_DYNAMIC_TYPE_EXTENDED (DnfCommandReinstall, + dnf_command_reinstall, + PEAS_TYPE_EXTENSION_BASE, + 0, + G_IMPLEMENT_INTERFACE (DNF_TYPE_COMMAND, + dnf_command_reinstall_iface_init)) + +static void +dnf_command_reinstall_init (DnfCommandReinstall *self) +{ +} + +static gint +compare_nevra (gconstpointer a, gconstpointer b, gpointer user_data) +{ + return g_strcmp0 (a, b); +} + +static void +packageset_free (gpointer pkg_set) +{ + dnf_packageset_free (pkg_set); +} + +static gboolean +dnf_command_reinstall_arg (DnfContext *ctx, const char *arg, GError **error) +{ + DnfSack *sack = dnf_context_get_sack (ctx); + + g_auto(HySubject) subject = hy_subject_create (arg); + HyNevra out_nevra; + hy_autoquery HyQuery query = hy_subject_get_best_solution (subject, sack, NULL, &out_nevra, + FALSE, TRUE, TRUE, TRUE, TRUE); + if (out_nevra) + hy_nevra_free (out_nevra); + + hy_autoquery HyQuery query_installed = hy_query_clone (query); + hy_query_filter (query_installed, HY_PKG_REPONAME, HY_EQ, HY_SYSTEM_REPO_NAME); + g_autoptr(GPtrArray) installed_pkgs = hy_query_run (query_installed); + + if (installed_pkgs->len == 0) + { + g_print ("No match for argument: %s\n", arg); + return TRUE; + } + + hy_query_filter (query, HY_PKG_REPONAME, HY_NEQ, HY_SYSTEM_REPO_NAME); + g_autoptr(GPtrArray) available_pkgs = hy_query_run (query); + + g_autoptr(GTree) available_nevra2pkg_set = g_tree_new_full (compare_nevra, NULL, + g_free, packageset_free); + for (guint i = 0; i < available_pkgs->len; ++i) + { + DnfPackage *package = available_pkgs->pdata[i]; + const char *nevra = dnf_package_get_nevra (package); + DnfPackageSet *pkg_set = g_tree_lookup (available_nevra2pkg_set, nevra); + if (!pkg_set) + { + pkg_set = dnf_packageset_new (sack); + /* dnf_package_get_nevra() returns pointer to temporary buffer -> copy is needed */ + g_tree_insert (available_nevra2pkg_set, g_strdup (nevra), pkg_set); + } + dnf_packageset_add (pkg_set, package); + } + + HyGoal goal = dnf_context_get_goal (ctx); + for (guint i = 0; i < installed_pkgs->len; ++i) + { + DnfPackage *package = installed_pkgs->pdata[i]; + const char *nevra = dnf_package_get_nevra (package); + DnfPackageSet *available_pkgs = g_tree_lookup (available_nevra2pkg_set, nevra); + if (available_pkgs) { + g_auto(HySelector) selector = hy_selector_create (sack); + hy_selector_pkg_set (selector, available_pkgs); + if (!hy_goal_install_selector (goal, selector, error)) + return FALSE; + } + else + g_print ("Installed package %s not available.\n", nevra); + } + + return TRUE; +} + +static gboolean +dnf_command_reinstall_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) + { + g_set_error_literal (error, + G_IO_ERROR, + G_IO_ERROR_FAILED, + "Packages are not specified"); + return FALSE; + } + + DnfState * state = dnf_context_get_state (ctx); + dnf_context_setup_sack_with_flags (ctx, state, DNF_CONTEXT_SETUP_SACK_FLAG_NONE, error); + + for (GStrv pkg = pkgs; *pkg != NULL; pkg++) + { + if (!dnf_command_reinstall_arg (ctx, *pkg, error)) + return FALSE; + } + + DnfGoalActions flags = DNF_INSTALL; + 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; + + DnfTransaction *transaction = dnf_context_get_transaction (ctx); + int tsflags = dnf_transaction_get_flags (transaction); + dnf_transaction_set_flags(transaction, tsflags | DNF_TRANSACTION_FLAG_ALLOW_REINSTALL); + + 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_reinstall_class_init (DnfCommandReinstallClass *klass) +{ +} + +static void +dnf_command_reinstall_iface_init (DnfCommandInterface *iface) +{ + iface->run = dnf_command_reinstall_run; +} + +static void +dnf_command_reinstall_class_finalize (DnfCommandReinstallClass *klass) +{ +} + +G_MODULE_EXPORT void +dnf_command_reinstall_register_types (PeasObjectModule *module) +{ + dnf_command_reinstall_register_type (G_TYPE_MODULE (module)); + + peas_object_module_register_extension_type (module, + DNF_TYPE_COMMAND, + DNF_TYPE_COMMAND_REINSTALL); +} diff --git a/rust-dnf/plugins/reinstall/dnf-command-reinstall.gresource.xml b/rust-dnf/plugins/reinstall/dnf-command-reinstall.gresource.xml new file mode 100644 index 00000000..82248cf1 --- /dev/null +++ b/rust-dnf/plugins/reinstall/dnf-command-reinstall.gresource.xml @@ -0,0 +1,6 @@ + + + + reinstall.plugin + + diff --git a/rust-dnf/plugins/reinstall/dnf-command-reinstall.h b/rust-dnf/plugins/reinstall/dnf-command-reinstall.h new file mode 100644 index 00000000..c187ccac --- /dev/null +++ b/rust-dnf/plugins/reinstall/dnf-command-reinstall.h @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2019 Red Hat, Inc. + * + * Licensed under the GNU Lesser General Public License Version 2.1 + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#pragma once + +#include "dnf-command.h" +#include + +G_BEGIN_DECLS + +#define DNF_TYPE_COMMAND_REINSTALL dnf_command_reinstall_get_type () +G_DECLARE_FINAL_TYPE (DnfCommandReinstall, dnf_command_reinstall, DNF, COMMAND_REINSTALL, PeasExtensionBase) + +G_MODULE_EXPORT void dnf_command_reinstall_register_types (PeasObjectModule *module); + +G_END_DECLS diff --git a/rust-dnf/plugins/reinstall/reinstall.plugin b/rust-dnf/plugins/reinstall/reinstall.plugin new file mode 100644 index 00000000..4a459770 --- /dev/null +++ b/rust-dnf/plugins/reinstall/reinstall.plugin @@ -0,0 +1,9 @@ +[Plugin] +Module = command_reinstall +Embedded = dnf_command_reinstall_register_types +Name = reinstall +Description = Reinstall packages +Authors = Jaroslav Rohel +License = GPL-2.0+ +Copyright = Copyright (C) 2019 Red Hat, Inc. +X-Command-Syntax = reinstall PACKAGE [PACKAGE…] diff --git a/rust-dnf/plugins/remove/dnf-command-remove.c b/rust-dnf/plugins/remove/dnf-command-remove.c new file mode 100644 index 00000000..4ac17ee8 --- /dev/null +++ b/rust-dnf/plugins/remove/dnf-command-remove.c @@ -0,0 +1,123 @@ +/* dnf-command-remove.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-remove.h" +#include "dnf-utils.h" + +struct _DnfCommandRemove +{ + PeasExtensionBase parent_instance; +}; + +static void dnf_command_remove_iface_init (DnfCommandInterface *iface); + +G_DEFINE_DYNAMIC_TYPE_EXTENDED (DnfCommandRemove, + dnf_command_remove, + PEAS_TYPE_EXTENSION_BASE, + 0, + G_IMPLEMENT_INTERFACE (DNF_TYPE_COMMAND, + dnf_command_remove_iface_init)) + +static void +dnf_command_remove_init (DnfCommandRemove *self) +{ +} + +static void +disable_available_repos (DnfContext *ctx) +{ + GPtrArray *repos = dnf_context_get_repos (ctx); + for (guint i = 0; i < repos->len; ++i) + { + DnfRepo * repo = g_ptr_array_index (repos, i); + dnf_repo_set_enabled (repo, DNF_REPO_ENABLED_NONE); + } +} + +static gboolean +dnf_command_remove_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) + { + g_set_error_literal (error, + G_IO_ERROR, + G_IO_ERROR_FAILED, + "Packages are not specified"); + return FALSE; + } + + disable_available_repos (ctx); + + /* Remove each package */ + for (GStrv pkg = pkgs; *pkg != NULL; pkg++) + { + if (!dnf_context_remove (ctx, *pkg, error)) + return FALSE; + } + 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"); + + return TRUE; +} + +static void +dnf_command_remove_class_init (DnfCommandRemoveClass *klass) +{ +} + +static void +dnf_command_remove_iface_init (DnfCommandInterface *iface) +{ + iface->run = dnf_command_remove_run; +} + +static void +dnf_command_remove_class_finalize (DnfCommandRemoveClass *klass) +{ +} + +G_MODULE_EXPORT void +dnf_command_remove_register_types (PeasObjectModule *module) +{ + dnf_command_remove_register_type (G_TYPE_MODULE (module)); + + peas_object_module_register_extension_type (module, + DNF_TYPE_COMMAND, + DNF_TYPE_COMMAND_REMOVE); +} diff --git a/rust-dnf/plugins/remove/dnf-command-remove.gresource.xml b/rust-dnf/plugins/remove/dnf-command-remove.gresource.xml new file mode 100644 index 00000000..315f550c --- /dev/null +++ b/rust-dnf/plugins/remove/dnf-command-remove.gresource.xml @@ -0,0 +1,6 @@ + + + + remove.plugin + + diff --git a/rust-dnf/plugins/remove/dnf-command-remove.h b/rust-dnf/plugins/remove/dnf-command-remove.h new file mode 100644 index 00000000..00419872 --- /dev/null +++ b/rust-dnf/plugins/remove/dnf-command-remove.h @@ -0,0 +1,31 @@ +/* dnf-command-remove.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 "dnf-command.h" +#include + +G_BEGIN_DECLS + +#define DNF_TYPE_COMMAND_REMOVE dnf_command_remove_get_type () +G_DECLARE_FINAL_TYPE (DnfCommandRemove, dnf_command_remove, DNF, COMMAND_REMOVE, PeasExtensionBase) + +G_MODULE_EXPORT void dnf_command_remove_register_types (PeasObjectModule *module); + +G_END_DECLS diff --git a/rust-dnf/plugins/remove/remove.plugin b/rust-dnf/plugins/remove/remove.plugin new file mode 100644 index 00000000..db4748a6 --- /dev/null +++ b/rust-dnf/plugins/remove/remove.plugin @@ -0,0 +1,9 @@ +[Plugin] +Module = command_remove +Embedded = dnf_command_remove_register_types +Name = remove +Description = Remove packages +Authors = Igor Gnatenko +License = GPL-2.0+ +Copyright = Copyright © 2016 Igor Gnatenko +X-Command-Syntax = remove PACKAGE [PACKAGE…] diff --git a/rust-dnf/plugins/repolist/dnf-command-repolist.gresource.xml b/rust-dnf/plugins/repolist/dnf-command-repolist.gresource.xml new file mode 100644 index 00000000..0d12b8b8 --- /dev/null +++ b/rust-dnf/plugins/repolist/dnf-command-repolist.gresource.xml @@ -0,0 +1,6 @@ + + + + repolist.plugin + + diff --git a/rust-dnf/plugins/repolist/dnf-command-repolist.rs b/rust-dnf/plugins/repolist/dnf-command-repolist.rs new file mode 100644 index 00000000..b4753980 --- /dev/null +++ b/rust-dnf/plugins/repolist/dnf-command-repolist.rs @@ -0,0 +1,162 @@ +#pragma once + +#include "dnf-command.h" +#include + +G_BEGIN_DECLS + +#define DNF_TYPE_COMMAND_REPOLIST dnf_command_repolist_get_type () +G_DECLARE_FINAL_TYPE (DnfCommandRepolist, dnf_command_repolist, DNF, COMMAND_REPOLIST, PeasExtensionBase) + +G_MODULE_EXPORT void dnf_command_repolist_register_types (PeasObjectModule *module); + +G_END_DECLS + + +#include +#include + +struct _DnfCommandRepolist +{ + PeasExtensionBase parent_instance; +}; + +static void dnf_command_repolist_iface_init (DnfCommandInterface *iface); + +G_DEFINE_DYNAMIC_TYPE_EXTENDED (DnfCommandRepolist, + dnf_command_repolist, + PEAS_TYPE_EXTENSION_BASE, + 0, + G_IMPLEMENT_INTERFACE (DNF_TYPE_COMMAND, + dnf_command_repolist_iface_init)) + +static void +dnf_command_repolist_init (DnfCommandRepolist *self) +{ +} + +// repository list table columns +enum { COL_REPO_ID, COL_REPO_NAME, COL_REPO_STATUS }; + +static struct libscols_table * +create_repolist_table (gboolean with_status) +{ + struct libscols_table *table = scols_new_table (); + if (isatty (1)) + { + scols_table_enable_colors (table, 1); + scols_table_enable_maxout (table, 1); + } + struct libscols_column *cl = scols_table_new_column (table, "repo id", 0.4, 0); + scols_column_set_cmpfunc(cl, scols_cmpstr_cells, NULL); + scols_table_new_column (table, "repo name", 0.5, SCOLS_FL_TRUNC); + if (with_status) + scols_table_new_column (table, "status", 0.1, SCOLS_FL_RIGHT); + return table; +} + +static void +add_line_into_table (struct libscols_table *table, + gboolean with_status, + const char *id, + const char *descr, + gboolean enabled) +{ + struct libscols_line *ln = scols_table_new_line (table, NULL); + scols_line_set_data (ln, COL_REPO_ID, id); + scols_line_set_data (ln, COL_REPO_NAME, descr); + if (with_status) + { + scols_line_set_data (ln, COL_REPO_STATUS, enabled ? "enabled" : "disabled"); + struct libscols_cell * cl = scols_line_get_cell (ln, COL_REPO_STATUS); + scols_cell_set_color (cl, enabled ? "green" : "red"); + } +} + +static gboolean +dnf_command_repolist_run (DnfCommand *cmd, + int argc, + char *argv[], + GOptionContext *opt_ctx, + DnfContext *ctx, + GError **error) +{ + gboolean opt_all = FALSE; + gboolean opt_enabled = FALSE; + gboolean opt_disabled = FALSE; + g_auto(GStrv) opt_repos = NULL; + const GOptionEntry opts[] = { + { "all", '\0', G_OPTION_FLAG_NONE, G_OPTION_ARG_NONE, &opt_all, "show all repos", NULL }, + { "disabled", '\0', G_OPTION_FLAG_NONE, G_OPTION_ARG_NONE, &opt_disabled, "show disabled repos", NULL }, + { "enabled", '\0', G_OPTION_FLAG_NONE, G_OPTION_ARG_NONE, &opt_enabled, "show enabled repos (default)", NULL }, + { G_OPTION_REMAINING, '\0', 0, G_OPTION_ARG_STRING_ARRAY, &opt_repos, 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_repos && opt_repos[0]) + { + g_set_error (error, + G_OPTION_ERROR, + G_OPTION_ERROR_UNKNOWN_OPTION, + "Unknown argument %s", opt_repos[0]); + return FALSE; + } + + if (!opt_disabled) + opt_enabled = TRUE; + + if (opt_enabled && opt_disabled) + opt_all = TRUE; + + struct libscols_table *table = create_repolist_table (opt_all); + + GPtrArray *repos = dnf_context_get_repos (ctx); + for (guint i = 0; i < repos->len; ++i) + { + DnfRepo * repo = g_ptr_array_index (repos, i); + gboolean enabled = dnf_repo_get_enabled (repo) & DNF_REPO_ENABLED_PACKAGES; + if (opt_all || (opt_enabled && enabled) || (opt_disabled && !enabled)) + { + const gchar * id = dnf_repo_get_id (repo); + g_autofree gchar * descr = dnf_repo_get_description (repo); + add_line_into_table (table, opt_all, id, descr, enabled); + } + } + + struct libscols_column *cl = scols_table_get_column (table, COL_REPO_ID); + scols_sort_table (table, cl); + scols_print_table (table); + scols_unref_table (table); + + return TRUE; +} + +static void +dnf_command_repolist_class_init (DnfCommandRepolistClass *klass) +{ +} + +static void +dnf_command_repolist_iface_init (DnfCommandInterface *iface) +{ + iface->run = dnf_command_repolist_run; +} + +static void +dnf_command_repolist_class_finalize (DnfCommandRepolistClass *klass) +{ +} + +G_MODULE_EXPORT void +dnf_command_repolist_register_types (PeasObjectModule *module) +{ + dnf_command_repolist_register_type (G_TYPE_MODULE (module)); + + peas_object_module_register_extension_type (module, + DNF_TYPE_COMMAND, + DNF_TYPE_COMMAND_REPOLIST); +} diff --git a/rust-dnf/plugins/repolist/repolist.plugin b/rust-dnf/plugins/repolist/repolist.plugin new file mode 100644 index 00000000..28bb0a39 --- /dev/null +++ b/rust-dnf/plugins/repolist/repolist.plugin @@ -0,0 +1,9 @@ +[Plugin] +Module = command_repolist +Embedded = dnf_command_repolist_register_types +Name = repolist +Description = List repositories +Authors = Jaroslav Rohel +License = GPL-2.0+ +Copyright = Copyright (C) 2019 Red Hat, Inc. +X-Command-Syntax = repolist [--all] [--disabled] [--enabled] -- Gitee From 0913391e6c058d2afbee5573ce058d81711d20de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BC=A0=E6=80=9D=E5=AD=A6?= <“zhang_sx@hisuntech.com”> Date: Wed, 24 Aug 2022 15:06:24 +0800 Subject: [PATCH 3/3] =?UTF-8?q?feat:=E5=A4=96=E9=83=A8util=E3=80=81command?= =?UTF-8?q?=E3=80=81main?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 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/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 ++ 10 files changed, 2130 insertions(+) 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/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 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=)", "