├── dnf
├── plugins
│ ├── CMakeLists.txt
│ ├── swap
│ │ ├── dnf-command-swap.gresource.xml
│ │ ├── swap.plugin
│ │ ├── dnf-command-swap.h
│ │ └── dnf-command-swap.c
│ ├── clean
│ │ ├── dnf-command-clean.gresource.xml
│ │ ├── clean.plugin
│ │ ├── dnf-command-clean.h
│ │ └── dnf-command-clean.c
│ ├── leaves
│ │ ├── dnf-command-leaves.gresource.xml
│ │ ├── leaves.plugin
│ │ ├── dnf-command-leaves.h
│ │ └── dnf-command-leaves.c
│ ├── remove
│ │ ├── dnf-command-remove.gresource.xml
│ │ ├── remove.plugin
│ │ ├── dnf-command-remove.h
│ │ └── dnf-command-remove.c
│ ├── install
│ │ ├── dnf-command-install.gresource.xml
│ │ ├── install.plugin
│ │ ├── dnf-command-install.h
│ │ └── dnf-command-install.c
│ ├── upgrade
│ │ ├── dnf-command-upgrade.gresource.xml
│ │ ├── upgrade.plugin
│ │ ├── dnf-command-upgrade.h
│ │ └── dnf-command-upgrade.c
│ ├── download
│ │ ├── dnf-command-download.gresource.xml
│ │ ├── download.plugin
│ │ ├── dnf-command-download.h
│ │ └── dnf-command-download.c
│ ├── repolist
│ │ ├── dnf-command-repolist.gresource.xml
│ │ ├── repolist.plugin
│ │ ├── dnf-command-repolist.h
│ │ └── dnf-command-repolist.c
│ ├── makecache
│ │ ├── dnf-command-makecache.gresource.xml
│ │ ├── makecache.plugin
│ │ ├── dnf-command-makecache.h
│ │ └── dnf-command-makecache.c
│ ├── reinstall
│ │ ├── dnf-command-reinstall.gresource.xml
│ │ ├── reinstall.plugin
│ │ ├── dnf-command-reinstall.h
│ │ └── dnf-command-reinstall.c
│ ├── repoquery
│ │ ├── dnf-command-repoquery.gresource.xml
│ │ ├── repoquery.plugin
│ │ ├── dnf-command-repoquery.h
│ │ └── dnf-command-repoquery.c
│ ├── distrosync
│ │ ├── dnf-command-distrosync.gresource.xml
│ │ ├── distrosync.plugin
│ │ ├── dnf-command-distrosync.h
│ │ └── dnf-command-distrosync.c
│ ├── module_reset
│ │ ├── dnf-command-module_reset.gresource.xml
│ │ ├── module_reset.plugin
│ │ ├── dnf-command-module_reset.h
│ │ └── dnf-command-module_reset.c
│ ├── module_enable
│ │ ├── dnf-command-module_enable.gresource.xml
│ │ ├── module_enable.plugin
│ │ ├── dnf-command-module_enable.h
│ │ └── dnf-command-module_enable.c
│ └── module_disable
│ │ ├── dnf-command-module_disable.gresource.xml
│ │ ├── module_disable.plugin
│ │ ├── dnf-command-module_disable.h
│ │ └── dnf-command-module_disable.c
├── dnf-utils.h
├── dnf-command.c
├── dnf-command.h
├── meson.build
├── CMakeLists.txt
├── dnf-utils.c
└── dnf-main.c
├── .packit.yaml
├── .tito
├── tito.props
└── packages
│ └── .readme
├── .git-commit-template
├── microdnf.spec
├── CMakeLists.txt
├── cmake
└── GResource.cmake
├── meson.build
├── README.md
└── COPYING
/dnf/plugins/CMakeLists.txt:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/.packit.yaml:
--------------------------------------------------------------------------------
1 | # See the documentation for more information:
2 | # https://packit.dev/docs/configuration
3 |
4 | # To disable default jobs set them as empty
5 | jobs: []
6 |
--------------------------------------------------------------------------------
/.tito/tito.props:
--------------------------------------------------------------------------------
1 | [buildconfig]
2 | builder = tito.builder.Builder
3 | tagger = tito.tagger.VersionTagger
4 | changelog_do_not_remove_cherrypick = 0
5 | changelog_format = %s (%ae)
6 |
--------------------------------------------------------------------------------
/.tito/packages/.readme:
--------------------------------------------------------------------------------
1 | the .tito/packages directory contains metadata files
2 | named after their packages. Each file has the latest tagged
3 | version and the project's relative directory.
4 |
--------------------------------------------------------------------------------
/dnf/plugins/swap/dnf-command-swap.gresource.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | swap.plugin
5 |
6 |
7 |
--------------------------------------------------------------------------------
/dnf/plugins/clean/dnf-command-clean.gresource.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | clean.plugin
5 |
6 |
7 |
--------------------------------------------------------------------------------
/dnf/plugins/leaves/dnf-command-leaves.gresource.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | leaves.plugin
5 |
6 |
7 |
--------------------------------------------------------------------------------
/dnf/plugins/remove/dnf-command-remove.gresource.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | remove.plugin
5 |
6 |
7 |
--------------------------------------------------------------------------------
/dnf/plugins/install/dnf-command-install.gresource.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | install.plugin
5 |
6 |
7 |
--------------------------------------------------------------------------------
/dnf/plugins/upgrade/dnf-command-upgrade.gresource.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | upgrade.plugin
5 |
6 |
7 |
--------------------------------------------------------------------------------
/dnf/plugins/download/dnf-command-download.gresource.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | download.plugin
5 |
6 |
7 |
--------------------------------------------------------------------------------
/dnf/plugins/repolist/dnf-command-repolist.gresource.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | repolist.plugin
5 |
6 |
7 |
--------------------------------------------------------------------------------
/dnf/plugins/makecache/dnf-command-makecache.gresource.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | makecache.plugin
5 |
6 |
7 |
--------------------------------------------------------------------------------
/dnf/plugins/reinstall/dnf-command-reinstall.gresource.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | reinstall.plugin
5 |
6 |
7 |
--------------------------------------------------------------------------------
/dnf/plugins/repoquery/dnf-command-repoquery.gresource.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | repoquery.plugin
5 |
6 |
7 |
--------------------------------------------------------------------------------
/dnf/plugins/distrosync/dnf-command-distrosync.gresource.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | distrosync.plugin
5 |
6 |
7 |
--------------------------------------------------------------------------------
/dnf/plugins/module_reset/dnf-command-module_reset.gresource.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | module_reset.plugin
5 |
6 |
7 |
--------------------------------------------------------------------------------
/dnf/plugins/module_enable/dnf-command-module_enable.gresource.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | module_enable.plugin
5 |
6 |
7 |
--------------------------------------------------------------------------------
/dnf/plugins/module_disable/dnf-command-module_disable.gresource.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | module_disable.plugin
5 |
6 |
7 |
--------------------------------------------------------------------------------
/dnf/plugins/clean/clean.plugin:
--------------------------------------------------------------------------------
1 | [Plugin]
2 | Module = command_clean
3 | Embedded = dnf_command_clean_register_types
4 | Name = clean
5 | Description = Remove cached data
6 | Authors = Jaroslav Rohel
7 | License = GPL-2.0+
8 | Copyright = Copyright © 2017 Jaroslav Rohel
9 | X-Command-Syntax = clean all
10 |
--------------------------------------------------------------------------------
/dnf/plugins/remove/remove.plugin:
--------------------------------------------------------------------------------
1 | [Plugin]
2 | Module = command_remove
3 | Embedded = dnf_command_remove_register_types
4 | Name = remove
5 | Description = Remove packages
6 | Authors = Igor Gnatenko
7 | License = GPL-2.0+
8 | Copyright = Copyright © 2016 Igor Gnatenko
9 | X-Command-Syntax = remove PACKAGE [PACKAGE…]
10 |
--------------------------------------------------------------------------------
/dnf/plugins/makecache/makecache.plugin:
--------------------------------------------------------------------------------
1 | [Plugin]
2 | Module = command_makecache
3 | Embedded = dnf_command_makecache_register_types
4 | Name = makecache
5 | Description = Generate the metadata cache
6 | Authors = Jaroslav Rohel
7 | License = GPL-2.0+
8 | Copyright = Copyright (C) 2021 Red Hat, Inc.
9 | X-Command-Syntax = makecache
10 |
--------------------------------------------------------------------------------
/dnf/plugins/reinstall/reinstall.plugin:
--------------------------------------------------------------------------------
1 | [Plugin]
2 | Module = command_reinstall
3 | Embedded = dnf_command_reinstall_register_types
4 | Name = reinstall
5 | Description = Reinstall packages
6 | Authors = Jaroslav Rohel
7 | License = GPL-2.0+
8 | Copyright = Copyright (C) 2019 Red Hat, Inc.
9 | X-Command-Syntax = reinstall PACKAGE [PACKAGE…]
10 |
--------------------------------------------------------------------------------
/dnf/plugins/download/download.plugin:
--------------------------------------------------------------------------------
1 | [Plugin]
2 | Module = command_download
3 | Embedded = dnf_command_download_register_types
4 | Name = download
5 | Description = Download packages
6 | Authors = Daniel Hams
7 | License = GPL-2.0+
8 | Copyright = Copyright © 2020-2021 Daniel Hams
9 | X-Command-Syntax = download [OPTION…] PACKAGE [PACKAGE…]
10 |
--------------------------------------------------------------------------------
/dnf/plugins/repolist/repolist.plugin:
--------------------------------------------------------------------------------
1 | [Plugin]
2 | Module = command_repolist
3 | Embedded = dnf_command_repolist_register_types
4 | Name = repolist
5 | Description = List repositories
6 | Authors = Jaroslav Rohel
7 | License = GPL-2.0+
8 | Copyright = Copyright (C) 2019 Red Hat, Inc.
9 | X-Command-Syntax = repolist [--all] [--disabled] [--enabled]
10 |
--------------------------------------------------------------------------------
/dnf/plugins/repoquery/repoquery.plugin:
--------------------------------------------------------------------------------
1 | [Plugin]
2 | Module = command_repoquery
3 | Embedded = dnf_command_repoquery_register_types
4 | Name = repoquery
5 | Description = Search for packages matching keyword
6 | Authors = Jaroslav Rohel
7 | License = GPL-2.0+
8 | Copyright = Copyright (C) 2019 Red Hat, Inc.
9 | X-Command-Syntax = repoquery [OPTION…] [KEY…]
10 |
--------------------------------------------------------------------------------
/dnf/plugins/leaves/leaves.plugin:
--------------------------------------------------------------------------------
1 | [Plugin]
2 | Module = command_leaves
3 | Embedded = dnf_command_leaves_register_types
4 | Name = leaves
5 | Description = List installed packages not required by other installed packages
6 | Authors = Emil Renner Berthing
7 | License = GPL-2.0+
8 | Copyright = Copyright (C) 2022 Emil Renner Berthing
9 | X-Command-Syntax = leaves
10 |
--------------------------------------------------------------------------------
/dnf/plugins/swap/swap.plugin:
--------------------------------------------------------------------------------
1 | [Plugin]
2 | Module = command_swap
3 | Embedded = dnf_command_swap_register_types
4 | Name = swap
5 | Description = Removes package and installs another in one transaction
6 | Authors = Jaroslav Rohel
7 | License = GPL-2.0+
8 | Copyright = Copyright (C) 2022 Red Hat, Inc.
9 | X-Command-Syntax = swap PACKAGE_TO_REMOVE PACKAGE_TO_INSTALL
10 |
--------------------------------------------------------------------------------
/dnf/plugins/module_reset/module_reset.plugin:
--------------------------------------------------------------------------------
1 | [Plugin]
2 | Module = command_module_reset
3 | Embedded = dnf_command_module_reset_register_types
4 | Name = module_reset
5 | Description = Reset a module stream
6 | Authors = Jaroslav Mracek
7 | License = GPL-2.0+
8 | Copyright = Copyright (C) 2020 Red Hat, Inc.
9 | X-Command-Syntax = module reset module-spec [module-spec…]
10 |
--------------------------------------------------------------------------------
/dnf/plugins/module_enable/module_enable.plugin:
--------------------------------------------------------------------------------
1 | [Plugin]
2 | Module = command_module_enable
3 | Embedded = dnf_command_module_enable_register_types
4 | Name = module_enable
5 | Description = Enable a module stream
6 | Authors = Jaroslav Rohel
7 | License = GPL-2.0+
8 | Copyright = Copyright (C) 2020 Red Hat, Inc.
9 | X-Command-Syntax = module enable module-spec [module-spec…]
10 |
--------------------------------------------------------------------------------
/dnf/plugins/module_disable/module_disable.plugin:
--------------------------------------------------------------------------------
1 | [Plugin]
2 | Module = command_module_disable
3 | Embedded = dnf_command_module_disable_register_types
4 | Name = module_disable
5 | Description = Disable a module stream
6 | Authors = Jaroslav Mracek
7 | License = GPL-2.0+
8 | Copyright = Copyright (C) 2020 Red Hat, Inc.
9 | X-Command-Syntax = module disable module-spec [module-spec…]
10 |
--------------------------------------------------------------------------------
/dnf/plugins/upgrade/upgrade.plugin:
--------------------------------------------------------------------------------
1 | [Plugin]
2 | Module = command_upgrade
3 | Embedded = dnf_command_upgrade_register_types
4 | Name = upgrade
5 | Description = Upgrade packages
6 | Authors = Igor Gnatenko
7 | License = GPL-2.0+
8 | Copyright = Copyright © 2016 Igor Gnatenko
9 | X-Command-Syntax = upgrade [PACKAGE…]
10 | X-Alias-Name = update
11 | X-Alias-Description = Compatibility alias for the "upgrade" command
12 |
--------------------------------------------------------------------------------
/dnf/plugins/install/install.plugin:
--------------------------------------------------------------------------------
1 | [Plugin]
2 | Module = command_install
3 | Embedded = dnf_command_install_register_types
4 | Name = install
5 | Description = Install packages
6 | Authors = Richard Hughes , Colin Walters , Igor Gnatenko
7 | License = GPL-2.0+
8 | Copyright = Copyright © 2010-2016 Richard Hughes, Colin Walters, Igor Gnatenko
9 | X-Command-Syntax = install PACKAGE [PACKAGE…]
10 |
--------------------------------------------------------------------------------
/dnf/plugins/distrosync/distrosync.plugin:
--------------------------------------------------------------------------------
1 | [Plugin]
2 | Module = command_distro-sync
3 | Embedded = dnf_command_distrosync_register_types
4 | Name = distro-sync
5 | Description = Upgrade/downgrade packages to match versions in repositories
6 | Authors = Neal Gompa
7 | License = GPL-2.0+
8 | Copyright = Copyright © 2021 Neal Gompa
9 | X-Command-Syntax = distro-sync [PACKAGE…]
10 | X-Alias-Name = dsync
11 | X-Alias-Description = Compatibility alias for the "distro-sync" command
12 |
--------------------------------------------------------------------------------
/.git-commit-template:
--------------------------------------------------------------------------------
1 |
2 |
3 | # In addition to regular commit message, you can uncomment and fill in the
4 | # following to include this change in the released RPM package changelog:
5 |
6 | # = changelog =
7 | # msg:
8 | # type:
9 | # resolves:
10 | # related:
11 |
12 | # msg = message to be included in the changelog
13 | # type = one of: bugfix/enhancement/security
14 | # resolves = URLs to bugs or issues resolved by this commit
15 | # related = URLs to any related bugs or issues
16 |
17 |
--------------------------------------------------------------------------------
/dnf/dnf-utils.h:
--------------------------------------------------------------------------------
1 | /* dnf-utils.h
2 | *
3 | * Copyright © 2016 Colin Walters
4 | * Copyright © 2016-2017 Igor Gnatenko
5 | *
6 | * This program is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU General Public License as published by
8 | * the Free Software Foundation, either version 2 of the License, or
9 | * (at your option) any later version.
10 | *
11 | * This program is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU General Public License
17 | * along with this program. If not, see .
18 | */
19 |
20 | #pragma once
21 |
22 | #include
23 | #include
24 |
25 | G_BEGIN_DECLS
26 |
27 | gboolean dnf_utils_print_transaction (DnfContext *ctx);
28 | gboolean dnf_utils_conf_main_get_bool_opt (const gchar *name, enum DnfConfPriority *priority);
29 | gboolean dnf_utils_userconfirm (void);
30 |
31 | G_END_DECLS
32 |
--------------------------------------------------------------------------------
/dnf/plugins/swap/dnf-command-swap.h:
--------------------------------------------------------------------------------
1 | /* dnf-command-swap.h
2 | *
3 | * Copyright (C) 2022 Red Hat, Inc.
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 2 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 |
19 | #pragma once
20 |
21 | #include "dnf-command.h"
22 | #include
23 |
24 | G_BEGIN_DECLS
25 |
26 | #define DNF_TYPE_COMMAND_SWAP dnf_command_swap_get_type ()
27 | G_DECLARE_FINAL_TYPE (DnfCommandSwap, dnf_command_swap, DNF, COMMAND_SWAP, PeasExtensionBase)
28 |
29 | G_MODULE_EXPORT void dnf_command_swap_register_types (PeasObjectModule *module);
30 |
31 | G_END_DECLS
32 |
--------------------------------------------------------------------------------
/dnf/plugins/clean/dnf-command-clean.h:
--------------------------------------------------------------------------------
1 | /* dnf-command-clean.h
2 | *
3 | * Copyright © 2017 Jaroslav Rohel
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 2 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 |
19 | #pragma once
20 |
21 | #include "dnf-command.h"
22 | #include
23 |
24 | G_BEGIN_DECLS
25 |
26 | #define DNF_TYPE_COMMAND_CLEAN dnf_command_clean_get_type ()
27 | G_DECLARE_FINAL_TYPE (DnfCommandClean, dnf_command_clean, DNF, COMMAND_CLEAN, PeasExtensionBase)
28 |
29 | G_MODULE_EXPORT void dnf_command_clean_register_types (PeasObjectModule *module);
30 |
31 | G_END_DECLS
32 |
--------------------------------------------------------------------------------
/dnf/plugins/leaves/dnf-command-leaves.h:
--------------------------------------------------------------------------------
1 | /* dnf-command-leaves.h
2 | *
3 | * Copyright © 2022 Emil Renner Berthing
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 2 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 |
19 | #pragma once
20 |
21 | #include "dnf-command.h"
22 | #include
23 |
24 | G_BEGIN_DECLS
25 |
26 | #define DNF_TYPE_COMMAND_LEAVES dnf_command_leaves_get_type ()
27 | G_DECLARE_FINAL_TYPE (DnfCommandLeaves, dnf_command_leaves, DNF, COMMAND_LEAVES, PeasExtensionBase)
28 |
29 | G_MODULE_EXPORT void dnf_command_leaves_register_types (PeasObjectModule *module);
30 |
31 | G_END_DECLS
32 |
--------------------------------------------------------------------------------
/dnf/plugins/remove/dnf-command-remove.h:
--------------------------------------------------------------------------------
1 | /* dnf-command-remove.h
2 | *
3 | * Copyright © 2016 Igor Gnatenko
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 2 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 |
19 | #pragma once
20 |
21 | #include "dnf-command.h"
22 | #include
23 |
24 | G_BEGIN_DECLS
25 |
26 | #define DNF_TYPE_COMMAND_REMOVE dnf_command_remove_get_type ()
27 | G_DECLARE_FINAL_TYPE (DnfCommandRemove, dnf_command_remove, DNF, COMMAND_REMOVE, PeasExtensionBase)
28 |
29 | G_MODULE_EXPORT void dnf_command_remove_register_types (PeasObjectModule *module);
30 |
31 | G_END_DECLS
32 |
--------------------------------------------------------------------------------
/dnf/plugins/install/dnf-command-install.h:
--------------------------------------------------------------------------------
1 | /* dnf-command-install.h
2 | *
3 | * Copyright © 2016 Igor Gnatenko
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 2 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 |
19 | #pragma once
20 |
21 | #include "dnf-command.h"
22 | #include
23 |
24 | G_BEGIN_DECLS
25 |
26 | #define DNF_TYPE_COMMAND_INSTALL dnf_command_install_get_type ()
27 | G_DECLARE_FINAL_TYPE (DnfCommandInstall, dnf_command_install, DNF, COMMAND_INSTALL, PeasExtensionBase)
28 |
29 | G_MODULE_EXPORT void dnf_command_install_register_types (PeasObjectModule *module);
30 |
31 | G_END_DECLS
32 |
--------------------------------------------------------------------------------
/dnf/plugins/makecache/dnf-command-makecache.h:
--------------------------------------------------------------------------------
1 | /* dnf-command-makecache.h
2 | *
3 | * Copyright (C) 2021 Red Hat, Inc.
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 2 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 |
19 | #pragma once
20 |
21 | #include "dnf-command.h"
22 | #include
23 |
24 | G_BEGIN_DECLS
25 |
26 | #define DNF_TYPE_COMMAND_MAKECACHE dnf_command_makecache_get_type ()
27 | G_DECLARE_FINAL_TYPE (DnfCommandMakecache, dnf_command_makecache, DNF, COMMAND_MAKECACHE, PeasExtensionBase)
28 |
29 | G_MODULE_EXPORT void dnf_command_makecache_register_types (PeasObjectModule *module);
30 |
31 | G_END_DECLS
32 |
--------------------------------------------------------------------------------
/dnf/plugins/upgrade/dnf-command-upgrade.h:
--------------------------------------------------------------------------------
1 | /* dnf-command-upgrade.h
2 | *
3 | * Copyright © 2016 Igor Gnatenko
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 2 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 |
19 | #pragma once
20 |
21 | #include "dnf-command.h"
22 | #include
23 |
24 | G_BEGIN_DECLS
25 |
26 | #define DNF_TYPE_COMMAND_UPGRADE dnf_command_upgrade_get_type ()
27 | G_DECLARE_FINAL_TYPE (DnfCommandUpgrade, dnf_command_upgrade, DNF, COMMAND_UPGRADE, PeasExtensionBase)
28 |
29 | G_MODULE_EXPORT void dnf_command_upgrade_register_types (PeasObjectModule *module);
30 |
31 | G_END_DECLS
32 |
--------------------------------------------------------------------------------
/dnf/plugins/download/dnf-command-download.h:
--------------------------------------------------------------------------------
1 | /* dnf-command-download.h
2 | *
3 | * Copyright © 2020-2021 Daniel Hams
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 2 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 |
19 | #pragma once
20 |
21 | #include "dnf-command.h"
22 | #include
23 |
24 | G_BEGIN_DECLS
25 |
26 | #define DNF_TYPE_COMMAND_DOWNLOAD dnf_command_download_get_type ()
27 | G_DECLARE_FINAL_TYPE (DnfCommandDownload, dnf_command_download, DNF, COMMAND_DOWNLOAD, PeasExtensionBase)
28 |
29 | G_MODULE_EXPORT void dnf_command_download_register_types (PeasObjectModule *module);
30 |
31 | G_END_DECLS
32 |
--------------------------------------------------------------------------------
/dnf/plugins/distrosync/dnf-command-distrosync.h:
--------------------------------------------------------------------------------
1 | /* dnf-command-distrosync.h
2 | *
3 | * Copyright © 2021 Neal Gompa
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 2 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 |
19 | #pragma once
20 |
21 | #include "dnf-command.h"
22 | #include
23 |
24 | G_BEGIN_DECLS
25 |
26 | #define DNF_TYPE_COMMAND_DISTROSYNC dnf_command_distrosync_get_type ()
27 | G_DECLARE_FINAL_TYPE (DnfCommandDistroSync, dnf_command_distrosync, DNF, COMMAND_DISTROSYNC, PeasExtensionBase)
28 |
29 | G_MODULE_EXPORT void dnf_command_distrosync_register_types (PeasObjectModule *module);
30 |
31 | G_END_DECLS
32 |
--------------------------------------------------------------------------------
/dnf/plugins/repolist/dnf-command-repolist.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2019 Red Hat, Inc.
3 | *
4 | * Licensed under the GNU Lesser General Public License Version 2.1
5 | *
6 | * This library is free software; you can redistribute it and/or
7 | * modify it under the terms of the GNU Lesser General Public
8 | * License as published by the Free Software Foundation; either
9 | * version 2.1 of the License, or (at your option) any later version.
10 | *
11 | * This library is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 | * Lesser General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU Lesser General Public
17 | * License along with this library; if not, write to the Free Software
18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 | */
20 |
21 | #pragma once
22 |
23 | #include "dnf-command.h"
24 | #include
25 |
26 | G_BEGIN_DECLS
27 |
28 | #define DNF_TYPE_COMMAND_REPOLIST dnf_command_repolist_get_type ()
29 | G_DECLARE_FINAL_TYPE (DnfCommandRepolist, dnf_command_repolist, DNF, COMMAND_REPOLIST, PeasExtensionBase)
30 |
31 | G_MODULE_EXPORT void dnf_command_repolist_register_types (PeasObjectModule *module);
32 |
33 | G_END_DECLS
34 |
--------------------------------------------------------------------------------
/dnf/plugins/reinstall/dnf-command-reinstall.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2019 Red Hat, Inc.
3 | *
4 | * Licensed under the GNU Lesser General Public License Version 2.1
5 | *
6 | * This library is free software; you can redistribute it and/or
7 | * modify it under the terms of the GNU Lesser General Public
8 | * License as published by the Free Software Foundation; either
9 | * version 2.1 of the License, or (at your option) any later version.
10 | *
11 | * This library is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 | * Lesser General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU Lesser General Public
17 | * License along with this library; if not, write to the Free Software
18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 | */
20 |
21 | #pragma once
22 |
23 | #include "dnf-command.h"
24 | #include
25 |
26 | G_BEGIN_DECLS
27 |
28 | #define DNF_TYPE_COMMAND_REINSTALL dnf_command_reinstall_get_type ()
29 | G_DECLARE_FINAL_TYPE (DnfCommandReinstall, dnf_command_reinstall, DNF, COMMAND_REINSTALL, PeasExtensionBase)
30 |
31 | G_MODULE_EXPORT void dnf_command_reinstall_register_types (PeasObjectModule *module);
32 |
33 | G_END_DECLS
34 |
--------------------------------------------------------------------------------
/dnf/plugins/repoquery/dnf-command-repoquery.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2019 Red Hat, Inc.
3 | *
4 | * Licensed under the GNU Lesser General Public License Version 2.1
5 | *
6 | * This library is free software; you can redistribute it and/or
7 | * modify it under the terms of the GNU Lesser General Public
8 | * License as published by the Free Software Foundation; either
9 | * version 2.1 of the License, or (at your option) any later version.
10 | *
11 | * This library is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 | * Lesser General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU Lesser General Public
17 | * License along with this library; if not, write to the Free Software
18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 | */
20 |
21 | #pragma once
22 |
23 | #include "dnf-command.h"
24 | #include
25 |
26 | G_BEGIN_DECLS
27 |
28 | #define DNF_TYPE_COMMAND_REPOQUERY dnf_command_repoquery_get_type ()
29 | G_DECLARE_FINAL_TYPE (DnfCommandRepoquery, dnf_command_repoquery, DNF, COMMAND_REPOQUERY, PeasExtensionBase)
30 |
31 | G_MODULE_EXPORT void dnf_command_repoquery_register_types (PeasObjectModule *module);
32 |
33 | G_END_DECLS
34 |
--------------------------------------------------------------------------------
/dnf/plugins/module_reset/dnf-command-module_reset.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2020 Red Hat, Inc.
3 | *
4 | * Licensed under the GNU Lesser General Public License Version 2.1
5 | *
6 | * This library is free software; you can redistribute it and/or
7 | * modify it under the terms of the GNU Lesser General Public
8 | * License as published by the Free Software Foundation; either
9 | * version 2.1 of the License, or (at your option) any later version.
10 | *
11 | * This library is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 | * Lesser General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU Lesser General Public
17 | * License along with this library; if not, write to the Free Software
18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 | */
20 |
21 | #pragma once
22 |
23 | #include "dnf-command.h"
24 | #include
25 |
26 | G_BEGIN_DECLS
27 |
28 | #define DNF_TYPE_COMMAND_MODULE_RESET dnf_command_module_reset_get_type ()
29 | G_DECLARE_FINAL_TYPE (DnfCommandModuleReset, dnf_command_module_reset, DNF, COMMAND_MODULE_RESET, PeasExtensionBase)
30 |
31 | G_MODULE_EXPORT void dnf_command_module_reset_register_types (PeasObjectModule *module);
32 |
33 | G_END_DECLS
34 |
--------------------------------------------------------------------------------
/dnf/plugins/module_enable/dnf-command-module_enable.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2020 Red Hat, Inc.
3 | *
4 | * Licensed under the GNU Lesser General Public License Version 2.1
5 | *
6 | * This library is free software; you can redistribute it and/or
7 | * modify it under the terms of the GNU Lesser General Public
8 | * License as published by the Free Software Foundation; either
9 | * version 2.1 of the License, or (at your option) any later version.
10 | *
11 | * This library is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 | * Lesser General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU Lesser General Public
17 | * License along with this library; if not, write to the Free Software
18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 | */
20 |
21 | #pragma once
22 |
23 | #include "dnf-command.h"
24 | #include
25 |
26 | G_BEGIN_DECLS
27 |
28 | #define DNF_TYPE_COMMAND_MODULE_ENABLE dnf_command_module_enable_get_type ()
29 | G_DECLARE_FINAL_TYPE (DnfCommandModuleEnable, dnf_command_module_enable, DNF, COMMAND_MODULE_ENABLE, PeasExtensionBase)
30 |
31 | G_MODULE_EXPORT void dnf_command_module_enable_register_types (PeasObjectModule *module);
32 |
33 | G_END_DECLS
34 |
--------------------------------------------------------------------------------
/dnf/plugins/module_disable/dnf-command-module_disable.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2020 Red Hat, Inc.
3 | *
4 | * Licensed under the GNU Lesser General Public License Version 2.1
5 | *
6 | * This library is free software; you can redistribute it and/or
7 | * modify it under the terms of the GNU Lesser General Public
8 | * License as published by the Free Software Foundation; either
9 | * version 2.1 of the License, or (at your option) any later version.
10 | *
11 | * This library is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 | * Lesser General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU Lesser General Public
17 | * License along with this library; if not, write to the Free Software
18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 | */
20 |
21 | #pragma once
22 |
23 | #include "dnf-command.h"
24 | #include
25 |
26 | G_BEGIN_DECLS
27 |
28 | #define DNF_TYPE_COMMAND_MODULE_DISABLE dnf_command_module_disable_get_type ()
29 | G_DECLARE_FINAL_TYPE (DnfCommandModuleDisable, dnf_command_module_disable, DNF, COMMAND_MODULE_DISABLE, PeasExtensionBase)
30 |
31 | G_MODULE_EXPORT void dnf_command_module_disable_register_types (PeasObjectModule *module);
32 |
33 | G_END_DECLS
34 |
--------------------------------------------------------------------------------
/dnf/dnf-command.c:
--------------------------------------------------------------------------------
1 | /* dnf-command.c
2 | *
3 | * Copyright © 2016 Igor Gnatenko
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 2 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 |
19 | #include "dnf-command.h"
20 |
21 | G_DEFINE_INTERFACE (DnfCommand, dnf_command, G_TYPE_OBJECT)
22 |
23 | static void
24 | dnf_command_default_init (DnfCommandInterface *iface)
25 | {
26 | }
27 |
28 | gboolean
29 | dnf_command_run (DnfCommand *cmd,
30 | int argc,
31 | char *argv[],
32 | GOptionContext *opt_ctx,
33 | DnfContext *ctx,
34 | GError **error)
35 | {
36 | g_return_val_if_fail (DNF_IS_COMMAND (cmd), FALSE);
37 |
38 | DnfCommandInterface *iface = DNF_COMMAND_GET_IFACE (cmd);
39 | g_return_val_if_fail (iface->run, TRUE);
40 | return iface->run (cmd, argc, argv, opt_ctx, ctx, error);
41 | }
42 |
--------------------------------------------------------------------------------
/microdnf.spec:
--------------------------------------------------------------------------------
1 | %global libdnf_version 0.62.0
2 |
3 | Name: microdnf
4 | Version: 3.10.2
5 | Release: 1%{?dist}
6 | Summary: Lightweight implementation of DNF in C
7 |
8 | License: GPL-2.0-or-later
9 | URL: https://github.com/rpm-software-management/microdnf
10 | Source0: %{url}/archive/%{version}/%{name}-%{version}.tar.gz
11 |
12 | BuildRequires: gcc
13 | BuildRequires: meson >= 0.36.0
14 | BuildRequires: pkgconfig(glib-2.0) >= 2.44.0
15 | BuildRequires: pkgconfig(gobject-2.0) >= 2.44.0
16 | BuildRequires: pkgconfig(libpeas-1.0) >= 1.20.0
17 | BuildRequires: (pkgconfig(libdnf) >= %{libdnf_version} with pkgconfig(libdnf) < 5)
18 | BuildRequires: pkgconfig(smartcols)
19 | BuildRequires: help2man
20 |
21 | Requires: libdnf%{?_isa} >= %{libdnf_version}
22 | %if 0%{?rhel} > 8 || 0%{?fedora}
23 | # Ensure DNF package manager configuration skeleton is installed
24 | Requires: /etc/dnf/dnf.conf
25 | %endif
26 |
27 | %description
28 | Micro DNF is a lightweight C implementation of DNF, designed to be used
29 | for doing simple packaging actions when you don't need full-blown DNF and
30 | you want the tiniest useful environments possible.
31 |
32 | That is, you don't want any interpreter stack and you want the most
33 | minimal environment possible so you can build up to exactly what you need.
34 |
35 |
36 | %prep
37 | %autosetup -p1
38 |
39 | %build
40 | %meson
41 | %meson_build
42 |
43 | %install
44 | %meson_install
45 |
46 | %check
47 | %meson_test
48 |
49 | %files
50 | %license COPYING
51 | %doc README.md
52 | %{_mandir}/man8/microdnf.8*
53 | %{_bindir}/%{name}
54 |
55 | %changelog
56 |
--------------------------------------------------------------------------------
/dnf/dnf-command.h:
--------------------------------------------------------------------------------
1 | /* dnf-command.h
2 | *
3 | * Copyright © 2016 Igor Gnatenko
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 2 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 |
19 | #pragma once
20 |
21 | #include
22 | #include
23 |
24 | G_BEGIN_DECLS
25 |
26 | #define DNF_TYPE_COMMAND dnf_command_get_type ()
27 | G_DECLARE_INTERFACE (DnfCommand, dnf_command, DNF, COMMAND, GObject)
28 |
29 | struct _DnfCommandInterface
30 | {
31 | GTypeInterface parent_iface;
32 |
33 | gboolean (*run) (DnfCommand *cmd,
34 | int argc,
35 | char *argv[],
36 | GOptionContext *opt_ctx,
37 | DnfContext *ctx,
38 | GError **error);
39 | };
40 |
41 | gboolean dnf_command_run (DnfCommand *cmd,
42 | int argc,
43 | char *argv[],
44 | GOptionContext *opt_ctx,
45 | DnfContext *ctx,
46 | GError **error);
47 |
48 | G_END_DECLS
49 |
--------------------------------------------------------------------------------
/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required (VERSION 2.8.5)
2 | project (microdnf C)
3 | set (PROJECT_VERSION 3.10.2)
4 |
5 | list (APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake)
6 |
7 | include (CheckCCompilerFlag)
8 | include (GNUInstallDirs)
9 | include (GResource)
10 |
11 | check_c_compiler_flag ("--std=gnu11" SUPPORT_GNU11_STD)
12 | if (NOT SUPPORT_GNU11_STD)
13 | message (FATAL_ERROR "Support for --std=gnu11 is mandatory")
14 | endif ()
15 | set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} --std=gnu11")
16 |
17 | find_package (PkgConfig REQUIRED)
18 | pkg_check_modules (GLIB REQUIRED glib-2.0>=2.44.0)
19 | pkg_check_modules (GOBJECT REQUIRED gobject-2.0>=2.44.0)
20 | pkg_check_modules (PEAS REQUIRED libpeas-1.0>=1.20.0)
21 | pkg_check_modules (LIBDNF REQUIRED libdnf>=0.62.0)
22 | pkg_check_modules (SCOLS REQUIRED smartcols)
23 |
24 | set (PKG_LIBDIR ${CMAKE_INSTALL_FULL_LIBDIR}/dnf)
25 | set (PKG_DATADIR ${CMAKE_INSTALL_FULL_DATADIR}/dnf)
26 | add_definitions (-DPACKAGE_LIBDIR="${PKG_LIBDIR}")
27 | add_definitions (-DPACKAGE_DATADIR="${PKG_DATADIR}")
28 |
29 | find_file (HELP2MAN_EXECUTABLE help2man)
30 | if (NOT HELP2MAN_EXECUTABLE)
31 | message (FATAL_ERROR "unable to find help2man")
32 | endif ()
33 |
34 | set (MANPAGE ${CMAKE_CURRENT_BINARY_DIR}/microdnf.8)
35 | add_custom_command (
36 | DEPENDS microdnf
37 | OUTPUT ${MANPAGE}
38 | COMMAND ${HELP2MAN_EXECUTABLE} $
39 | --version-string=${PROJECT_VERSION}
40 | --no-info
41 | --section=8
42 | --name="Micro DNF"
43 | --output=${MANPAGE}
44 | )
45 | add_custom_target (manpage ALL DEPENDS ${MANPAGE})
46 | install (FILES ${MANPAGE} DESTINATION ${CMAKE_INSTALL_FULL_MANDIR}/man8)
47 |
48 | include_directories (${GLIB_INCLUDE_DIRS})
49 | include_directories (${GOBJECT_INCLUDE_DIRS})
50 | include_directories (${PEAS_INCLUDE_DIRS})
51 | include_directories (${LIBDNF_INCLUDE_DIRS})
52 | include_directories (${SCOLS_INCLUDE_DIRS})
53 |
54 | add_subdirectory (dnf)
55 |
--------------------------------------------------------------------------------
/cmake/GResource.cmake:
--------------------------------------------------------------------------------
1 | find_program (GLIB_COMPILE_RESOURCES_EXECUTABLE glib-compile-resources)
2 | mark_as_advanced (GLIB_COMPILE_RESOURCES_EXECUTABLE)
3 |
4 | include (CMakeParseArguments)
5 |
6 | function (GLIB_COMPILE_RESOURCES output_var input)
7 | cmake_parse_arguments (
8 | ARGS
9 | "MANUAL_REGISTER;INTERNAL"
10 | "C_PREFIX"
11 | "DATA_DIR"
12 | ${ARGN})
13 |
14 | set (in_file ${CMAKE_CURRENT_SOURCE_DIR}/${input})
15 | get_filename_component (WORKING_DIR ${in_file} PATH)
16 | string (REGEX REPLACE "\\.xml" ".c" input ${input})
17 | set (out_file "${CMAKE_CURRENT_BINARY_DIR}/${input}")
18 | get_filename_component (OUTPUT_DIR ${out_file} PATH)
19 | file (MAKE_DIRECTORY ${OUTPUT_DIR})
20 |
21 | execute_process (
22 | COMMAND
23 | ${GLIB_COMPILE_RESOURCES_EXECUTABLE}
24 | --generate-dependencies
25 | ${in_file}
26 | WORKING_DIRECTORY ${WORKING_DIR}
27 | OUTPUT_VARIABLE in_file_dep)
28 | string (REGEX REPLACE "\r?\n$" ";" in_file_dep "${in_file_dep}")
29 | set (in_file_dep_path "")
30 | foreach (dep ${in_file_dep})
31 | list (APPEND in_file_dep_path "${WORKING_DIR}/${dep}")
32 | endforeach ()
33 |
34 | set (additional_args "")
35 | if (ARGS_MANUAL_REGISTER)
36 | list (APPEND additional_args "--manual-register")
37 | endif ()
38 | if (ARGS_INTERNAL)
39 | list (APPEND additional_args "--internal")
40 | endif ()
41 | if (ARGS_C_PREFIX)
42 | list (APPEND additional_args "--c-name=${ARGS_C_PREFIX}")
43 | endif ()
44 | add_custom_command (
45 | OUTPUT ${out_file}
46 | WORKING_DIRECTORY ${WORKING_DIR}
47 | COMMAND
48 | ${GLIB_COMPILE_RESOURCES_EXECUTABLE}
49 | ARGS
50 | "--generate-source"
51 | "--target=${out_file}"
52 | ${additional_args}
53 | ${in_file}
54 | DEPENDS
55 | ${in_file};${in_file_dep_path})
56 | set (${output_var} ${out_file} PARENT_SCOPE)
57 | endfunction ()
58 |
--------------------------------------------------------------------------------
/meson.build:
--------------------------------------------------------------------------------
1 | project('microdnf', 'c',
2 | version : '3.10.2',
3 | license : 'GPL-2.0+',
4 | default_options : [
5 | 'b_asneeded=True',
6 | 'b_lundef=True',
7 | 'c_std=gnu11',
8 | 'warning_level=1',
9 | ],
10 | meson_version : '>=0.36.0')
11 |
12 | cc = meson.get_compiler('c')
13 | test_cflags = [
14 | '-fstrict-aliasing',
15 | '-Wformat=2',
16 | '-Wunused',
17 | '-Wuninitialized',
18 | '-Wstrict-prototypes',
19 | '-Wmissing-prototypes',
20 | '-Werror=implicit',
21 | '-Werror=init-self',
22 | '-Werror=main',
23 | ]
24 | foreach cflag : test_cflags
25 | if cc.has_argument(cflag)
26 | add_project_arguments(cflag, language : 'c')
27 | endif
28 | endforeach
29 |
30 | gnome = import('gnome')
31 |
32 | glib = dependency('glib-2.0', version : '>=2.44.0')
33 | gobject = dependency('gobject-2.0', version : '>=2.44.0')
34 | libpeas = dependency('libpeas-1.0', version : '>=1.20.0')
35 | libdnf = dependency('libdnf', version : '>=0.62.0')
36 | scols = dependency('smartcols')
37 |
38 | pkg_libdir = join_paths(get_option('prefix'), get_option('libdir'), 'dnf')
39 | pkg_datadir = join_paths(get_option('prefix'), get_option('datadir'), 'dnf')
40 | add_project_arguments(
41 | '-DPACKAGE_LIBDIR="@0@"'.format(pkg_libdir),
42 | '-DPACKAGE_DATADIR="@0@"'.format(pkg_datadir),
43 | language : 'c',
44 | )
45 |
46 | subdir('dnf')
47 |
48 | help2man = find_program('help2man', required: true)
49 | if help2man.found()
50 | help2man_opts = [
51 | '--version-string=' + meson.project_version(),
52 | '--no-info',
53 | '--section=8',
54 | '--name=Micro DNF',
55 | ]
56 |
57 | custom_target('microdnf.8',
58 | output: 'microdnf.8',
59 | command: [
60 | help2man, help2man_opts, '--output=@OUTPUT@', microdnf
61 | ],
62 | install: true,
63 | install_dir: get_option('mandir') + '/man8',
64 | )
65 | endif
66 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | microdnf
2 | ========
3 |
4 | A minimal `dnf` for (mostly) Docker containers that uses
5 | [libdnf](https://github.com/rpm-software-management/libdnf)
6 | and hence doesn't require Python.
7 |
8 | This project was inspired by and derived from
9 | https://github.com/cgwalters/micro-yuminst
10 |
11 |
12 | Reporting issues
13 | ================
14 |
15 | * [Red Hat Bugzilla](https://bugzilla.redhat.com/enter_bug.cgi?product=Fedora&component=microdnf) is the preferred way of filing issues. [[backlog](https://bugzilla.redhat.com/buglist.cgi?bug_status=__open__&product=Fedora&component=microdnf)]
16 | * [GitHub issues](https://github.com/rpm-software-management/microdnf/issues/new) are also accepted. [[backlog](https://github.com/rpm-software-management/microdnf/issues)]
17 |
18 |
19 | Contribution
20 | ============
21 |
22 | Here's the most direct way to get your work merged into the project.
23 |
24 | 1. Fork the project
25 | 1. Clone down your fork
26 | 1. Implement your feature or bug fix and commit changes
27 | 1. If the change fixes a bug at [Red Hat bugzilla](https://bugzilla.redhat.com/), or if it is important to the end user, add the following block to the commit message:
28 |
29 | = changelog =
30 | msg: message to be included in the changelog
31 | type: one of: bugfix/enhancement/security (this field is required when message is present)
32 | resolves: URLs to bugs or issues resolved by this commit (can be specified multiple times)
33 | related: URLs to any related bugs or issues (can be specified multiple times)
34 |
35 | * For example::
36 |
37 | = changelog =
38 | msg: Don't print lines with (null) in transaction report
39 | type: bugfix
40 | resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1691353
41 |
42 | * For your convenience, you can also use git commit template by running the following command in the top-level directory of this project:
43 |
44 | git config commit.template ./.git-commit-template
45 |
46 | 1. Push the branch to your fork
47 | 1. Send a pull request for your branch
48 |
49 |
--------------------------------------------------------------------------------
/dnf/plugins/makecache/dnf-command-makecache.c:
--------------------------------------------------------------------------------
1 | /* dnf-command-makecache.c
2 | *
3 | * Copyright (C) 2021 Red Hat, Inc.
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 2 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 |
19 | #include "dnf-command-makecache.h"
20 |
21 | struct _DnfCommandMakecache
22 | {
23 | PeasExtensionBase parent_instance;
24 | };
25 |
26 | static void dnf_command_makecache_iface_init (DnfCommandInterface *iface);
27 |
28 | G_DEFINE_DYNAMIC_TYPE_EXTENDED (DnfCommandMakecache,
29 | dnf_command_makecache,
30 | PEAS_TYPE_EXTENSION_BASE,
31 | 0,
32 | G_IMPLEMENT_INTERFACE (DNF_TYPE_COMMAND,
33 | dnf_command_makecache_iface_init))
34 |
35 | static void
36 | dnf_command_makecache_init (DnfCommandMakecache *self)
37 | {
38 | }
39 |
40 | static gboolean
41 | dnf_command_makecache_run (DnfCommand *cmd,
42 | int argc,
43 | char *argv[],
44 | GOptionContext *opt_ctx,
45 | DnfContext *ctx,
46 | GError **error)
47 | {
48 | const GOptionEntry opts[] = {
49 | { NULL }
50 | };
51 | g_option_context_add_main_entries (opt_ctx, opts, NULL);
52 |
53 | if (!g_option_context_parse (opt_ctx, &argc, &argv, error))
54 | return FALSE;
55 |
56 | if (argc > 1)
57 | {
58 | g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_UNKNOWN_OPTION, "Unknown argument %s", argv[1]);
59 | return FALSE;
60 | }
61 |
62 | DnfState * state = dnf_context_get_state (ctx);
63 | DnfContextSetupSackFlags sack_flags = DNF_CONTEXT_SETUP_SACK_FLAG_SKIP_RPMDB;
64 | if (!dnf_context_setup_sack_with_flags (ctx, state, sack_flags, error)) {
65 | return FALSE;
66 | }
67 |
68 | g_print ("Metadata cache created.\n");
69 |
70 | return TRUE;
71 | }
72 |
73 | static void
74 | dnf_command_makecache_class_init (DnfCommandMakecacheClass *klass)
75 | {
76 | }
77 |
78 | static void
79 | dnf_command_makecache_iface_init (DnfCommandInterface *iface)
80 | {
81 | iface->run = dnf_command_makecache_run;
82 | }
83 |
84 | static void
85 | dnf_command_makecache_class_finalize (DnfCommandMakecacheClass *klass)
86 | {
87 | }
88 |
89 | G_MODULE_EXPORT void
90 | dnf_command_makecache_register_types (PeasObjectModule *module)
91 | {
92 | dnf_command_makecache_register_type (G_TYPE_MODULE (module));
93 |
94 | peas_object_module_register_extension_type (module,
95 | DNF_TYPE_COMMAND,
96 | DNF_TYPE_COMMAND_MAKECACHE);
97 | }
98 |
--------------------------------------------------------------------------------
/dnf/plugins/upgrade/dnf-command-upgrade.c:
--------------------------------------------------------------------------------
1 | /* dnf-command-upgrade.c
2 | *
3 | * Copyright © 2016-2017 Igor Gnatenko
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 2 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 |
19 | #include "dnf-command-upgrade.h"
20 | #include "dnf-utils.h"
21 |
22 | struct _DnfCommandUpgrade
23 | {
24 | PeasExtensionBase parent_instance;
25 | };
26 |
27 | static void dnf_command_upgrade_iface_init (DnfCommandInterface *iface);
28 |
29 | G_DEFINE_DYNAMIC_TYPE_EXTENDED (DnfCommandUpgrade,
30 | dnf_command_upgrade,
31 | PEAS_TYPE_EXTENSION_BASE,
32 | 0,
33 | G_IMPLEMENT_INTERFACE (DNF_TYPE_COMMAND,
34 | dnf_command_upgrade_iface_init))
35 |
36 | static void
37 | dnf_command_upgrade_init (DnfCommandUpgrade *self)
38 | {
39 | }
40 |
41 | static gboolean
42 | dnf_command_upgrade_run (DnfCommand *cmd,
43 | int argc,
44 | char *argv[],
45 | GOptionContext *opt_ctx,
46 | DnfContext *ctx,
47 | GError **error)
48 | {
49 | g_auto(GStrv) pkgs = NULL;
50 | const GOptionEntry opts[] = {
51 | { G_OPTION_REMAINING, '\0', 0, G_OPTION_ARG_STRING_ARRAY, &pkgs, NULL, NULL },
52 | { NULL }
53 | };
54 | g_option_context_add_main_entries (opt_ctx, opts, NULL);
55 |
56 | if (!g_option_context_parse (opt_ctx, &argc, &argv, error))
57 | return FALSE;
58 |
59 | if (pkgs == NULL)
60 | {
61 | if (!dnf_context_update_all (ctx, error))
62 | return FALSE;
63 | }
64 | else
65 | {
66 | /* Upgrade each package */
67 | for (GStrv pkg = pkgs; *pkg != NULL; pkg++)
68 | {
69 | if (!dnf_context_update (ctx, *pkg, error))
70 | return FALSE;
71 | }
72 | }
73 | DnfGoalActions flags = 0;
74 | if (dnf_context_get_best())
75 | {
76 | flags |= DNF_FORCE_BEST;
77 | }
78 | if (!dnf_context_get_install_weak_deps ())
79 | flags |= DNF_IGNORE_WEAK_DEPS;
80 | if (!dnf_goal_depsolve (dnf_context_get_goal (ctx), flags, error))
81 | return FALSE;
82 | if (!dnf_utils_print_transaction (ctx))
83 | return TRUE;
84 | if (!dnf_utils_userconfirm ())
85 | return FALSE;
86 | if (!dnf_context_run (ctx, NULL, error))
87 | return FALSE;
88 | g_print ("Complete.\n");
89 |
90 | return TRUE;
91 | }
92 |
93 | static void
94 | dnf_command_upgrade_class_init (DnfCommandUpgradeClass *klass)
95 | {
96 | }
97 |
98 | static void
99 | dnf_command_upgrade_iface_init (DnfCommandInterface *iface)
100 | {
101 | iface->run = dnf_command_upgrade_run;
102 | }
103 |
104 | static void
105 | dnf_command_upgrade_class_finalize (DnfCommandUpgradeClass *klass)
106 | {
107 | }
108 |
109 | G_MODULE_EXPORT void
110 | dnf_command_upgrade_register_types (PeasObjectModule *module)
111 | {
112 | dnf_command_upgrade_register_type (G_TYPE_MODULE (module));
113 |
114 | peas_object_module_register_extension_type (module,
115 | DNF_TYPE_COMMAND,
116 | DNF_TYPE_COMMAND_UPGRADE);
117 | }
118 |
--------------------------------------------------------------------------------
/dnf/plugins/distrosync/dnf-command-distrosync.c:
--------------------------------------------------------------------------------
1 | /* dnf-command-distrosync.c
2 | *
3 | * Copyright © 2021 Neal Gompa
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 2 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 |
19 | #include "dnf-command-distrosync.h"
20 | #include "dnf-utils.h"
21 |
22 | struct _DnfCommandDistroSync
23 | {
24 | PeasExtensionBase parent_instance;
25 | };
26 |
27 | static void dnf_command_distrosync_iface_init (DnfCommandInterface *iface);
28 |
29 | G_DEFINE_DYNAMIC_TYPE_EXTENDED (DnfCommandDistroSync,
30 | dnf_command_distrosync,
31 | PEAS_TYPE_EXTENSION_BASE,
32 | 0,
33 | G_IMPLEMENT_INTERFACE (DNF_TYPE_COMMAND,
34 | dnf_command_distrosync_iface_init))
35 |
36 | static void
37 | dnf_command_distrosync_init (DnfCommandDistroSync *self)
38 | {
39 | }
40 |
41 | static gboolean
42 | dnf_command_distrosync_run (DnfCommand *cmd,
43 | int argc,
44 | char *argv[],
45 | GOptionContext *opt_ctx,
46 | DnfContext *ctx,
47 | GError **error)
48 | {
49 | g_auto(GStrv) pkgs = NULL;
50 | const GOptionEntry opts[] = {
51 | { G_OPTION_REMAINING, '\0', 0, G_OPTION_ARG_STRING_ARRAY, &pkgs, NULL, NULL },
52 | { NULL }
53 | };
54 | g_option_context_add_main_entries (opt_ctx, opts, NULL);
55 |
56 | if (!g_option_context_parse (opt_ctx, &argc, &argv, error))
57 | return FALSE;
58 |
59 | if (pkgs == NULL)
60 | {
61 | if (!dnf_context_distrosync_all (ctx, error))
62 | return FALSE;
63 | }
64 | else
65 | {
66 | /* Sync each package */
67 | for (GStrv pkg = pkgs; *pkg != NULL; pkg++)
68 | {
69 | if (!dnf_context_distrosync (ctx, *pkg, error))
70 | return FALSE;
71 | }
72 | }
73 | DnfGoalActions flags = 0;
74 | if (dnf_context_get_best())
75 | {
76 | flags |= DNF_FORCE_BEST;
77 | }
78 | if (!dnf_context_get_install_weak_deps ())
79 | flags |= DNF_IGNORE_WEAK_DEPS;
80 | if (!dnf_goal_depsolve (dnf_context_get_goal (ctx), flags, error))
81 | return FALSE;
82 | if (!dnf_utils_print_transaction (ctx))
83 | return TRUE;
84 | if (!dnf_utils_userconfirm ())
85 | return FALSE;
86 | if (!dnf_context_run (ctx, NULL, error))
87 | return FALSE;
88 | g_print ("Complete.\n");
89 |
90 | return TRUE;
91 | }
92 |
93 | static void
94 | dnf_command_distrosync_class_init (DnfCommandDistroSyncClass *klass)
95 | {
96 | }
97 |
98 | static void
99 | dnf_command_distrosync_iface_init (DnfCommandInterface *iface)
100 | {
101 | iface->run = dnf_command_distrosync_run;
102 | }
103 |
104 | static void
105 | dnf_command_distrosync_class_finalize (DnfCommandDistroSyncClass *klass)
106 | {
107 | }
108 |
109 | G_MODULE_EXPORT void
110 | dnf_command_distrosync_register_types (PeasObjectModule *module)
111 | {
112 | dnf_command_distrosync_register_type (G_TYPE_MODULE (module));
113 |
114 | peas_object_module_register_extension_type (module,
115 | DNF_TYPE_COMMAND,
116 | DNF_TYPE_COMMAND_DISTROSYNC);
117 | }
118 |
--------------------------------------------------------------------------------
/dnf/plugins/remove/dnf-command-remove.c:
--------------------------------------------------------------------------------
1 | /* dnf-command-remove.c
2 | *
3 | * Copyright © 2016 Igor Gnatenko
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 2 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 |
19 | #include "dnf-command-remove.h"
20 | #include "dnf-utils.h"
21 |
22 | struct _DnfCommandRemove
23 | {
24 | PeasExtensionBase parent_instance;
25 | };
26 |
27 | static void dnf_command_remove_iface_init (DnfCommandInterface *iface);
28 |
29 | G_DEFINE_DYNAMIC_TYPE_EXTENDED (DnfCommandRemove,
30 | dnf_command_remove,
31 | PEAS_TYPE_EXTENSION_BASE,
32 | 0,
33 | G_IMPLEMENT_INTERFACE (DNF_TYPE_COMMAND,
34 | dnf_command_remove_iface_init))
35 |
36 | static void
37 | dnf_command_remove_init (DnfCommandRemove *self)
38 | {
39 | }
40 |
41 | static void
42 | disable_available_repos (DnfContext *ctx)
43 | {
44 | GPtrArray *repos = dnf_context_get_repos (ctx);
45 | for (guint i = 0; i < repos->len; ++i)
46 | {
47 | DnfRepo * repo = g_ptr_array_index (repos, i);
48 | dnf_repo_set_enabled (repo, DNF_REPO_ENABLED_NONE);
49 | }
50 | }
51 |
52 | static gboolean
53 | dnf_command_remove_run (DnfCommand *cmd,
54 | int argc,
55 | char *argv[],
56 | GOptionContext *opt_ctx,
57 | DnfContext *ctx,
58 | GError **error)
59 | {
60 | g_auto(GStrv) pkgs = NULL;
61 | const GOptionEntry opts[] = {
62 | { G_OPTION_REMAINING, '\0', 0, G_OPTION_ARG_STRING_ARRAY, &pkgs, NULL, NULL },
63 | { NULL }
64 | };
65 | g_option_context_add_main_entries (opt_ctx, opts, NULL);
66 |
67 | if (!g_option_context_parse (opt_ctx, &argc, &argv, error))
68 | return FALSE;
69 |
70 | if (pkgs == NULL)
71 | {
72 | g_set_error_literal (error,
73 | G_IO_ERROR,
74 | G_IO_ERROR_FAILED,
75 | "Packages are not specified");
76 | return FALSE;
77 | }
78 |
79 | disable_available_repos (ctx);
80 |
81 | /* Remove each package */
82 | for (GStrv pkg = pkgs; *pkg != NULL; pkg++)
83 | {
84 | if (!dnf_context_remove (ctx, *pkg, error))
85 | return FALSE;
86 | }
87 | if (!dnf_goal_depsolve (dnf_context_get_goal (ctx), DNF_ERASE, error))
88 | return FALSE;
89 | dnf_utils_print_transaction (ctx);
90 | if (!dnf_utils_userconfirm ())
91 | return FALSE;
92 | if (!dnf_context_run (ctx, NULL, error))
93 | return FALSE;
94 | g_print ("Complete.\n");
95 |
96 | return TRUE;
97 | }
98 |
99 | static void
100 | dnf_command_remove_class_init (DnfCommandRemoveClass *klass)
101 | {
102 | }
103 |
104 | static void
105 | dnf_command_remove_iface_init (DnfCommandInterface *iface)
106 | {
107 | iface->run = dnf_command_remove_run;
108 | }
109 |
110 | static void
111 | dnf_command_remove_class_finalize (DnfCommandRemoveClass *klass)
112 | {
113 | }
114 |
115 | G_MODULE_EXPORT void
116 | dnf_command_remove_register_types (PeasObjectModule *module)
117 | {
118 | dnf_command_remove_register_type (G_TYPE_MODULE (module));
119 |
120 | peas_object_module_register_extension_type (module,
121 | DNF_TYPE_COMMAND,
122 | DNF_TYPE_COMMAND_REMOVE);
123 | }
124 |
--------------------------------------------------------------------------------
/dnf/plugins/install/dnf-command-install.c:
--------------------------------------------------------------------------------
1 | /* dnf-command-install.c
2 | *
3 | * Copyright © 2010-2015 Richard Hughes
4 | * Copyright © 2016 Colin Walters
5 | * Copyright © 2016-2017 Igor Gnatenko
6 | *
7 | * This program is free software: you can redistribute it and/or modify
8 | * it under the terms of the GNU General Public License as published by
9 | * the Free Software Foundation, either version 2 of the License, or
10 | * (at your option) any later version.
11 | *
12 | * This program is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | * GNU General Public License for more details.
16 | *
17 | * You should have received a copy of the GNU General Public License
18 | * along with this program. If not, see .
19 | */
20 |
21 | #include "dnf-command-install.h"
22 | #include "dnf-utils.h"
23 |
24 | struct _DnfCommandInstall
25 | {
26 | PeasExtensionBase parent_instance;
27 | };
28 |
29 | static void dnf_command_install_iface_init (DnfCommandInterface *iface);
30 |
31 | G_DEFINE_DYNAMIC_TYPE_EXTENDED (DnfCommandInstall,
32 | dnf_command_install,
33 | PEAS_TYPE_EXTENSION_BASE,
34 | 0,
35 | G_IMPLEMENT_INTERFACE (DNF_TYPE_COMMAND,
36 | dnf_command_install_iface_init))
37 |
38 | static void
39 | dnf_command_install_init (DnfCommandInstall *self)
40 | {
41 | }
42 |
43 | static gboolean
44 | dnf_command_install_run (DnfCommand *cmd,
45 | int argc,
46 | char *argv[],
47 | GOptionContext *opt_ctx,
48 | DnfContext *ctx,
49 | GError **error)
50 | {
51 | g_auto(GStrv) pkgs = NULL;
52 | const GOptionEntry opts[] = {
53 | { G_OPTION_REMAINING, '\0', 0, G_OPTION_ARG_STRING_ARRAY, &pkgs, NULL, NULL },
54 | { NULL }
55 | };
56 | g_option_context_add_main_entries (opt_ctx, opts, NULL);
57 |
58 | if (!g_option_context_parse (opt_ctx, &argc, &argv, error))
59 | return FALSE;
60 |
61 | if (pkgs == NULL)
62 | {
63 | g_set_error_literal (error,
64 | G_IO_ERROR,
65 | G_IO_ERROR_FAILED,
66 | "Packages are not specified");
67 | return FALSE;
68 | }
69 |
70 | /* Install each package */
71 | for (GStrv pkg = pkgs; *pkg != NULL; pkg++)
72 | {
73 | if (!dnf_context_install (ctx, *pkg, error))
74 | return FALSE;
75 | }
76 | DnfGoalActions flags = DNF_INSTALL;
77 | if (dnf_context_get_best())
78 | {
79 | flags |= DNF_FORCE_BEST;
80 | }
81 | if (!dnf_context_get_install_weak_deps ())
82 | flags |= DNF_IGNORE_WEAK_DEPS;
83 | if (!dnf_goal_depsolve (dnf_context_get_goal (ctx), flags, error))
84 | return FALSE;
85 | if (!dnf_utils_print_transaction (ctx))
86 | return TRUE;
87 | if (!dnf_utils_userconfirm ())
88 | return FALSE;
89 | if (!dnf_context_run (ctx, NULL, error))
90 | return FALSE;
91 | g_print ("Complete.\n");
92 |
93 | return TRUE;
94 | }
95 |
96 | static void
97 | dnf_command_install_class_init (DnfCommandInstallClass *klass)
98 | {
99 | }
100 |
101 | static void
102 | dnf_command_install_iface_init (DnfCommandInterface *iface)
103 | {
104 | iface->run = dnf_command_install_run;
105 | }
106 |
107 | static void
108 | dnf_command_install_class_finalize (DnfCommandInstallClass *klass)
109 | {
110 | }
111 |
112 | G_MODULE_EXPORT void
113 | dnf_command_install_register_types (PeasObjectModule *module)
114 | {
115 | dnf_command_install_register_type (G_TYPE_MODULE (module));
116 |
117 | peas_object_module_register_extension_type (module,
118 | DNF_TYPE_COMMAND,
119 | DNF_TYPE_COMMAND_INSTALL);
120 | }
121 |
--------------------------------------------------------------------------------
/dnf/plugins/module_disable/dnf-command-module_disable.c:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2020 Red Hat, Inc.
3 | *
4 | * Licensed under the GNU Lesser General Public License Version 2.1
5 | *
6 | * This library is free software; you can redistribute it and/or
7 | * modify it under the terms of the GNU Lesser General Public
8 | * License as published by the Free Software Foundation; either
9 | * version 2.1 of the License, or (at your option) any later version.
10 | *
11 | * This library is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 | * Lesser General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU Lesser General Public
17 | * License along with this library; if not, write to the Free Software
18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 | */
20 |
21 | #include "dnf-command-module_disable.h"
22 | #include "dnf-utils.h"
23 |
24 | struct _DnfCommandModuleDisable
25 | {
26 | PeasExtensionBase parent_instance;
27 | };
28 |
29 | static void dnf_command_module_disable_iface_init (DnfCommandInterface *iface);
30 |
31 | G_DEFINE_DYNAMIC_TYPE_EXTENDED (DnfCommandModuleDisable,
32 | dnf_command_module_disable,
33 | PEAS_TYPE_EXTENSION_BASE,
34 | 0,
35 | G_IMPLEMENT_INTERFACE (DNF_TYPE_COMMAND,
36 | dnf_command_module_disable_iface_init))
37 |
38 | static void
39 | dnf_command_module_disable_init (DnfCommandModuleDisable *self)
40 | {
41 | }
42 |
43 | static gboolean
44 | dnf_command_module_disable_run (DnfCommand *cmd,
45 | int argc,
46 | char *argv[],
47 | GOptionContext *opt_ctx,
48 | DnfContext *ctx,
49 | GError **error)
50 | {
51 | g_auto(GStrv) pkgs = NULL;
52 | const GOptionEntry opts[] = {
53 | { G_OPTION_REMAINING, '\0', 0, G_OPTION_ARG_STRING_ARRAY, &pkgs, NULL, NULL },
54 | { NULL }
55 | };
56 | g_option_context_add_main_entries (opt_ctx, opts, NULL);
57 |
58 | if (!g_option_context_parse (opt_ctx, &argc, &argv, error))
59 | return FALSE;
60 |
61 | if (pkgs == NULL)
62 | {
63 | g_set_error_literal (error,
64 | G_IO_ERROR,
65 | G_IO_ERROR_FAILED,
66 | "Modules are not specified");
67 | return FALSE;
68 | }
69 |
70 | if (!dnf_context_module_disable (ctx, (const char **)pkgs, error))
71 | {
72 | return FALSE;
73 | }
74 |
75 | if (!dnf_goal_depsolve (dnf_context_get_goal (ctx), DNF_NONE, error))
76 | {
77 | if (g_error_matches (*error, DNF_ERROR, DNF_ERROR_NO_PACKAGES_TO_UPDATE))
78 | {
79 | g_clear_error (error);
80 | } else {
81 | return FALSE;
82 | }
83 | }
84 | if (!dnf_utils_print_transaction (ctx))
85 | {
86 | return TRUE;
87 | }
88 | if (!dnf_utils_userconfirm ())
89 | {
90 | return FALSE;
91 | }
92 | if (!dnf_context_run (ctx, NULL, error))
93 | {
94 | return FALSE;
95 | }
96 | return TRUE;
97 | }
98 |
99 | static void
100 | dnf_command_module_disable_class_init (DnfCommandModuleDisableClass *klass)
101 | {
102 | }
103 |
104 | static void
105 | dnf_command_module_disable_iface_init (DnfCommandInterface *iface)
106 | {
107 | iface->run = dnf_command_module_disable_run;
108 | }
109 |
110 | static void
111 | dnf_command_module_disable_class_finalize (DnfCommandModuleDisableClass *klass)
112 | {
113 | }
114 |
115 | G_MODULE_EXPORT void
116 | dnf_command_module_disable_register_types (PeasObjectModule *module)
117 | {
118 | dnf_command_module_disable_register_type (G_TYPE_MODULE (module));
119 |
120 | peas_object_module_register_extension_type (module,
121 | DNF_TYPE_COMMAND,
122 | DNF_TYPE_COMMAND_MODULE_DISABLE);
123 | }
124 |
--------------------------------------------------------------------------------
/dnf/plugins/module_reset/dnf-command-module_reset.c:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2020 Red Hat, Inc.
3 | *
4 | * Licensed under the GNU Lesser General Public License Version 2.1
5 | *
6 | * This library is free software; you can redistribute it and/or
7 | * modify it under the terms of the GNU Lesser General Public
8 | * License as published by the Free Software Foundation; either
9 | * version 2.1 of the License, or (at your option) any later version.
10 | *
11 | * This library is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 | * Lesser General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU Lesser General Public
17 | * License along with this library; if not, write to the Free Software
18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 | */
20 |
21 | #include "dnf-command-module_reset.h"
22 | #include "dnf-utils.h"
23 |
24 | struct _DnfCommandModuleReset
25 | {
26 | PeasExtensionBase parent_instance;
27 | };
28 |
29 | static void dnf_command_module_reset_iface_init (DnfCommandInterface *iface);
30 |
31 | G_DEFINE_DYNAMIC_TYPE_EXTENDED (DnfCommandModuleReset,
32 | dnf_command_module_reset,
33 | PEAS_TYPE_EXTENSION_BASE,
34 | 0,
35 | G_IMPLEMENT_INTERFACE (DNF_TYPE_COMMAND,
36 | dnf_command_module_reset_iface_init))
37 |
38 | static void
39 | dnf_command_module_reset_init (DnfCommandModuleReset *self)
40 | {
41 | }
42 |
43 | static gboolean
44 | dnf_command_module_reset_run (DnfCommand *cmd,
45 | int argc,
46 | char *argv[],
47 | GOptionContext *opt_ctx,
48 | DnfContext *ctx,
49 | GError **error)
50 | {
51 | g_auto(GStrv) pkgs = NULL;
52 | const GOptionEntry opts[] = {
53 | { G_OPTION_REMAINING, '\0', 0, G_OPTION_ARG_STRING_ARRAY, &pkgs, NULL, NULL },
54 | { NULL }
55 | };
56 | g_option_context_add_main_entries (opt_ctx, opts, NULL);
57 |
58 | if (!g_option_context_parse (opt_ctx, &argc, &argv, error))
59 | return FALSE;
60 |
61 | if (pkgs == NULL)
62 | {
63 | g_set_error_literal (error,
64 | G_IO_ERROR,
65 | G_IO_ERROR_FAILED,
66 | "Modules are not specified");
67 | return FALSE;
68 | }
69 |
70 | if (!dnf_context_module_reset (ctx, (const char **)pkgs, error))
71 | {
72 | return FALSE;
73 | }
74 | if (!dnf_context_module_switched_check (ctx, error))
75 | {
76 | return FALSE;
77 | }
78 |
79 | if (!dnf_goal_depsolve (dnf_context_get_goal (ctx), DNF_NONE, error))
80 | {
81 | if (g_error_matches (*error, DNF_ERROR, DNF_ERROR_NO_PACKAGES_TO_UPDATE))
82 | {
83 | g_clear_error (error);
84 | } else {
85 | return FALSE;
86 | }
87 | }
88 | if (!dnf_utils_print_transaction (ctx))
89 | {
90 | return TRUE;
91 | }
92 | if (!dnf_utils_userconfirm ())
93 | {
94 | return FALSE;
95 | }
96 | if (!dnf_context_run (ctx, NULL, error))
97 | {
98 | return FALSE;
99 | }
100 | return TRUE;
101 | }
102 |
103 | static void
104 | dnf_command_module_reset_class_init (DnfCommandModuleResetClass *klass)
105 | {
106 | }
107 |
108 | static void
109 | dnf_command_module_reset_iface_init (DnfCommandInterface *iface)
110 | {
111 | iface->run = dnf_command_module_reset_run;
112 | }
113 |
114 | static void
115 | dnf_command_module_reset_class_finalize (DnfCommandModuleResetClass *klass)
116 | {
117 | }
118 |
119 | G_MODULE_EXPORT void
120 | dnf_command_module_reset_register_types (PeasObjectModule *module)
121 | {
122 | dnf_command_module_reset_register_type (G_TYPE_MODULE (module));
123 |
124 | peas_object_module_register_extension_type (module,
125 | DNF_TYPE_COMMAND,
126 | DNF_TYPE_COMMAND_MODULE_RESET);
127 | }
128 |
--------------------------------------------------------------------------------
/dnf/plugins/module_enable/dnf-command-module_enable.c:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2020 Red Hat, Inc.
3 | *
4 | * Licensed under the GNU Lesser General Public License Version 2.1
5 | *
6 | * This library is free software; you can redistribute it and/or
7 | * modify it under the terms of the GNU Lesser General Public
8 | * License as published by the Free Software Foundation; either
9 | * version 2.1 of the License, or (at your option) any later version.
10 | *
11 | * This library is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 | * Lesser General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU Lesser General Public
17 | * License along with this library; if not, write to the Free Software
18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 | */
20 |
21 | #include "dnf-command-module_enable.h"
22 | #include "dnf-utils.h"
23 |
24 | struct _DnfCommandModuleEnable
25 | {
26 | PeasExtensionBase parent_instance;
27 | };
28 |
29 | static void dnf_command_module_enable_iface_init (DnfCommandInterface *iface);
30 |
31 | G_DEFINE_DYNAMIC_TYPE_EXTENDED (DnfCommandModuleEnable,
32 | dnf_command_module_enable,
33 | PEAS_TYPE_EXTENSION_BASE,
34 | 0,
35 | G_IMPLEMENT_INTERFACE (DNF_TYPE_COMMAND,
36 | dnf_command_module_enable_iface_init))
37 |
38 | static void
39 | dnf_command_module_enable_init (DnfCommandModuleEnable *self)
40 | {
41 | }
42 |
43 | static gboolean
44 | dnf_command_module_enable_run (DnfCommand *cmd,
45 | int argc,
46 | char *argv[],
47 | GOptionContext *opt_ctx,
48 | DnfContext *ctx,
49 | GError **error)
50 | {
51 | g_auto(GStrv) pkgs = NULL;
52 | const GOptionEntry opts[] = {
53 | { G_OPTION_REMAINING, '\0', 0, G_OPTION_ARG_STRING_ARRAY, &pkgs, NULL, NULL },
54 | { NULL }
55 | };
56 | g_option_context_add_main_entries (opt_ctx, opts, NULL);
57 |
58 | if (!g_option_context_parse (opt_ctx, &argc, &argv, error))
59 | return FALSE;
60 |
61 | if (pkgs == NULL)
62 | {
63 | g_set_error_literal (error,
64 | G_IO_ERROR,
65 | G_IO_ERROR_FAILED,
66 | "Modules are not specified");
67 | return FALSE;
68 | }
69 |
70 | if (!dnf_context_module_enable (ctx, (const char **)pkgs, error))
71 | {
72 | return FALSE;
73 | }
74 | if (!dnf_context_module_switched_check (ctx, error))
75 | {
76 | return FALSE;
77 | }
78 |
79 | if (!dnf_goal_depsolve (dnf_context_get_goal (ctx), DNF_NONE, error))
80 | {
81 | if (g_error_matches (*error, DNF_ERROR, DNF_ERROR_NO_PACKAGES_TO_UPDATE))
82 | {
83 | g_clear_error (error);
84 | } else {
85 | return FALSE;
86 | }
87 | }
88 | if (!dnf_utils_print_transaction (ctx))
89 | {
90 | return TRUE;
91 | }
92 | if (!dnf_utils_userconfirm ())
93 | {
94 | return FALSE;
95 | }
96 | if (!dnf_context_run (ctx, NULL, error))
97 | {
98 | return FALSE;
99 | }
100 | return TRUE;
101 | }
102 |
103 | static void
104 | dnf_command_module_enable_class_init (DnfCommandModuleEnableClass *klass)
105 | {
106 | }
107 |
108 | static void
109 | dnf_command_module_enable_iface_init (DnfCommandInterface *iface)
110 | {
111 | iface->run = dnf_command_module_enable_run;
112 | }
113 |
114 | static void
115 | dnf_command_module_enable_class_finalize (DnfCommandModuleEnableClass *klass)
116 | {
117 | }
118 |
119 | G_MODULE_EXPORT void
120 | dnf_command_module_enable_register_types (PeasObjectModule *module)
121 | {
122 | dnf_command_module_enable_register_type (G_TYPE_MODULE (module));
123 |
124 | peas_object_module_register_extension_type (module,
125 | DNF_TYPE_COMMAND,
126 | DNF_TYPE_COMMAND_MODULE_ENABLE);
127 | }
128 |
--------------------------------------------------------------------------------
/dnf/plugins/clean/dnf-command-clean.c:
--------------------------------------------------------------------------------
1 | /* dnf-command-clean.c
2 | *
3 | * Copyright © 2017 Jaroslav Rohel
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 2 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 |
19 | #include "dnf-command-clean.h"
20 |
21 | struct _DnfCommandClean
22 | {
23 | PeasExtensionBase parent_instance;
24 | };
25 |
26 | static void dnf_command_clean_iface_init (DnfCommandInterface *iface);
27 |
28 | G_DEFINE_DYNAMIC_TYPE_EXTENDED (DnfCommandClean,
29 | dnf_command_clean,
30 | PEAS_TYPE_EXTENSION_BASE,
31 | 0,
32 | G_IMPLEMENT_INTERFACE (DNF_TYPE_COMMAND,
33 | dnf_command_clean_iface_init))
34 |
35 | static void
36 | dnf_command_clean_init (DnfCommandClean *self)
37 | {
38 | }
39 |
40 | static gboolean
41 | dnf_command_clean_run (DnfCommand *cmd,
42 | int argc,
43 | char *argv[],
44 | GOptionContext *opt_ctx,
45 | DnfContext *ctx,
46 | GError **error)
47 | {
48 | g_auto(GStrv) types = NULL;
49 | const GOptionEntry opts[] = {
50 | { G_OPTION_REMAINING, '\0', 0, G_OPTION_ARG_STRING_ARRAY, &types, NULL, NULL },
51 | { NULL }
52 | };
53 | g_option_context_add_main_entries (opt_ctx, opts, NULL);
54 |
55 | if (!g_option_context_parse (opt_ctx, &argc, &argv, error))
56 | return FALSE;
57 |
58 | if (types == NULL)
59 | {
60 | g_set_error_literal (error,
61 | G_IO_ERROR,
62 | G_IO_ERROR_FAILED,
63 | "Clean requires argument: all");
64 | return FALSE;
65 | }
66 |
67 | if (g_strcmp0 (types[0], "all") != 0)
68 | {
69 | g_set_error (error,
70 | G_IO_ERROR,
71 | G_IO_ERROR_FAILED,
72 | "Invalid clean argument: '%s'", *types);
73 | return FALSE;
74 | }
75 |
76 | if (types[1] != NULL)
77 | {
78 | g_set_error_literal (error,
79 | G_IO_ERROR,
80 | G_IO_ERROR_FAILED,
81 | "Too many arguments. Clean accepts only one argument.");
82 | return FALSE;
83 | }
84 |
85 | /* lock cache */
86 | g_autoptr(DnfLock) lock = dnf_lock_new ();
87 | dnf_lock_set_lock_dir (lock, dnf_context_get_lock_dir (ctx));
88 | guint lock_id = dnf_lock_take (lock,
89 | DNF_LOCK_TYPE_METADATA,
90 | DNF_LOCK_MODE_PROCESS,
91 | error);
92 | if (lock_id == 0)
93 | return FALSE;
94 |
95 | /* Clean cached data */
96 | const gchar *cachedir = dnf_context_get_cache_dir (ctx);
97 | if (!dnf_remove_recursive (cachedir, error))
98 | return FALSE;
99 | const gchar *solvdir = dnf_context_get_solv_dir (ctx);
100 | if (!dnf_remove_recursive (solvdir, error))
101 | return FALSE;
102 |
103 | if (!dnf_lock_release (lock, lock_id, error))
104 | return FALSE;
105 |
106 | g_print ("Complete.\n");
107 |
108 | return TRUE;
109 | }
110 |
111 | static void
112 | dnf_command_clean_class_init (DnfCommandCleanClass *klass)
113 | {
114 | }
115 |
116 | static void
117 | dnf_command_clean_iface_init (DnfCommandInterface *iface)
118 | {
119 | iface->run = dnf_command_clean_run;
120 | }
121 |
122 | static void
123 | dnf_command_clean_class_finalize (DnfCommandCleanClass *klass)
124 | {
125 | }
126 |
127 | G_MODULE_EXPORT void
128 | dnf_command_clean_register_types (PeasObjectModule *module)
129 | {
130 | dnf_command_clean_register_type (G_TYPE_MODULE (module));
131 |
132 | peas_object_module_register_extension_type (module,
133 | DNF_TYPE_COMMAND,
134 | DNF_TYPE_COMMAND_CLEAN);
135 | }
136 |
--------------------------------------------------------------------------------
/dnf/meson.build:
--------------------------------------------------------------------------------
1 | microdnf_srcs = [
2 | 'dnf-main.c',
3 | 'dnf-command.c',
4 | 'dnf-utils.c',
5 |
6 | # install
7 | gnome.compile_resources(
8 | 'dnf-install',
9 | 'plugins/install/dnf-command-install.gresource.xml',
10 | c_name : 'dnf_command_install',
11 | source_dir : 'plugins/install',
12 | ),
13 | 'plugins/install/dnf-command-install.c',
14 |
15 | # reinstall
16 | gnome.compile_resources(
17 | 'dnf-reinstall',
18 | 'plugins/reinstall/dnf-command-reinstall.gresource.xml',
19 | c_name : 'dnf_command_reinstall',
20 | source_dir : 'plugins/reinstall',
21 | ),
22 | 'plugins/reinstall/dnf-command-reinstall.c',
23 |
24 | # remove
25 | gnome.compile_resources(
26 | 'dnf-remove',
27 | 'plugins/remove/dnf-command-remove.gresource.xml',
28 | c_name : 'dnf_command_remove',
29 | source_dir : 'plugins/remove',
30 | ),
31 | 'plugins/remove/dnf-command-remove.c',
32 |
33 | # upgrade
34 | gnome.compile_resources(
35 | 'dnf-upgrade',
36 | 'plugins/upgrade/dnf-command-upgrade.gresource.xml',
37 | c_name : 'dnf_command_upgrade',
38 | source_dir : 'plugins/upgrade',
39 | ),
40 | 'plugins/upgrade/dnf-command-upgrade.c',
41 |
42 | # swap
43 | gnome.compile_resources(
44 | 'dnf-swap',
45 | 'plugins/swap/dnf-command-swap.gresource.xml',
46 | c_name : 'dnf_command_swap',
47 | source_dir : 'plugins/swap',
48 | ),
49 | 'plugins/swap/dnf-command-swap.c',
50 |
51 | # distro-sync
52 | gnome.compile_resources(
53 | 'dnf-distrosync',
54 | 'plugins/distrosync/dnf-command-distrosync.gresource.xml',
55 | c_name : 'dnf_command_distrosync',
56 | source_dir : 'plugins/distrosync',
57 | ),
58 | 'plugins/distrosync/dnf-command-distrosync.c',
59 |
60 | # repolist
61 | gnome.compile_resources(
62 | 'dnf-repolist',
63 | 'plugins/repolist/dnf-command-repolist.gresource.xml',
64 | c_name : 'dnf_command_repolist',
65 | source_dir : 'plugins/repolist',
66 | ),
67 | 'plugins/repolist/dnf-command-repolist.c',
68 |
69 | # repoquery
70 | gnome.compile_resources(
71 | 'dnf-repoquery',
72 | 'plugins/repoquery/dnf-command-repoquery.gresource.xml',
73 | c_name : 'dnf_command_repoquery',
74 | source_dir : 'plugins/repoquery',
75 | ),
76 | 'plugins/repoquery/dnf-command-repoquery.c',
77 |
78 | # leaves
79 | gnome.compile_resources(
80 | 'dnf-leaves',
81 | 'plugins/leaves/dnf-command-leaves.gresource.xml',
82 | c_name : 'dnf_command_leaves',
83 | source_dir : 'plugins/leaves',
84 | ),
85 | 'plugins/leaves/dnf-command-leaves.c',
86 |
87 | # clean
88 | gnome.compile_resources(
89 | 'dnf-clean',
90 | 'plugins/clean/dnf-command-clean.gresource.xml',
91 | c_name : 'dnf_command_clean',
92 | source_dir : 'plugins/clean',
93 | ),
94 | 'plugins/clean/dnf-command-clean.c',
95 |
96 | # download
97 | gnome.compile_resources(
98 | 'dnf-download',
99 | 'plugins/download/dnf-command-download.gresource.xml',
100 | c_name : 'dnf_command_download',
101 | source_dir : 'plugins/download',
102 | ),
103 | 'plugins/download/dnf-command-download.c',
104 |
105 | # makecache
106 | gnome.compile_resources(
107 | 'dnf-makecache',
108 | 'plugins/makecache/dnf-command-makecache.gresource.xml',
109 | c_name : 'dnf_command_makecache',
110 | source_dir : 'plugins/makecache',
111 | ),
112 | 'plugins/makecache/dnf-command-makecache.c',
113 |
114 | # module enable
115 | gnome.compile_resources(
116 | 'dnf-module_enable',
117 | 'plugins/module_enable/dnf-command-module_enable.gresource.xml',
118 | c_name : 'dnf_command_module_enable',
119 | source_dir : 'plugins/module_enable',
120 | ),
121 | 'plugins/module_enable/dnf-command-module_enable.c',
122 |
123 | # module disable
124 | gnome.compile_resources(
125 | 'dnf-module_disable',
126 | 'plugins/module_disable/dnf-command-module_disable.gresource.xml',
127 | c_name : 'dnf_command_module_disable',
128 | source_dir : 'plugins/module_disable',
129 | ),
130 | 'plugins/module_disable/dnf-command-module_disable.c',
131 |
132 | # module reset
133 | gnome.compile_resources(
134 | 'dnf-module_reset',
135 | 'plugins/module_reset/dnf-command-module_reset.gresource.xml',
136 | c_name : 'dnf_command_module_reset',
137 | source_dir : 'plugins/module_reset',
138 | ),
139 | 'plugins/module_reset/dnf-command-module_reset.c',
140 | ]
141 |
142 | microdnf = executable(
143 | 'microdnf',
144 | sources : microdnf_srcs,
145 | dependencies : [
146 | glib,
147 | gobject,
148 | libpeas,
149 | libdnf,
150 | scols,
151 | ],
152 | c_args : [
153 | '-DBUILDDIR="@0@"'.format(meson.current_build_dir()),
154 | '-DSRCDIR="@0@"'.format(meson.current_source_dir()),
155 | ],
156 | install : true
157 | )
158 |
--------------------------------------------------------------------------------
/dnf/plugins/swap/dnf-command-swap.c:
--------------------------------------------------------------------------------
1 | /* dnf-command-swap.c
2 | *
3 | * Copyright (C) 2022 Red Hat, Inc.
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 2 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 |
19 | #include "dnf-command-swap.h"
20 | #include "dnf-utils.h"
21 |
22 | struct _DnfCommandSwap
23 | {
24 | PeasExtensionBase parent_instance;
25 | };
26 |
27 | static void dnf_command_swap_iface_init (DnfCommandInterface *iface);
28 |
29 | G_DEFINE_DYNAMIC_TYPE_EXTENDED (DnfCommandSwap,
30 | dnf_command_swap,
31 | PEAS_TYPE_EXTENSION_BASE,
32 | 0,
33 | G_IMPLEMENT_INTERFACE (DNF_TYPE_COMMAND,
34 | dnf_command_swap_iface_init))
35 |
36 | static void
37 | dnf_command_swap_init (DnfCommandSwap *self)
38 | {
39 | }
40 |
41 | static gboolean
42 | dnf_command_swap_run (DnfCommand *cmd,
43 | int argc,
44 | char *argv[],
45 | GOptionContext *opt_ctx,
46 | DnfContext *ctx,
47 | GError **error)
48 | {
49 | g_auto(GStrv) pkgs = NULL;
50 | const GOptionEntry opts[] = {
51 | { G_OPTION_REMAINING, '\0', 0, G_OPTION_ARG_STRING_ARRAY, &pkgs, NULL, NULL },
52 | { NULL }
53 | };
54 | g_option_context_add_main_entries (opt_ctx, opts, NULL);
55 |
56 | if (!g_option_context_parse (opt_ctx, &argc, &argv, error))
57 | return FALSE;
58 |
59 | if (pkgs == NULL || pkgs[0] == NULL)
60 | {
61 | g_set_error_literal (error,
62 | G_IO_ERROR,
63 | G_IO_ERROR_FAILED,
64 | "Missing arguments. "
65 | "The swap command requires 2 arguments: PACKAGE_TO_REMOVE and PACKAGE_TO_INSTALL.");
66 | return FALSE;
67 | }
68 |
69 | if (pkgs[1] == NULL)
70 | {
71 | g_set_error_literal (error,
72 | G_IO_ERROR,
73 | G_IO_ERROR_FAILED,
74 | "Missing argument. "
75 | "The swap command requires 2 arguments: PACKAGE_TO_REMOVE and PACKAGE_TO_INSTALL.");
76 | return FALSE;
77 | }
78 |
79 | if (pkgs[2] != NULL)
80 | {
81 | g_set_error_literal (error,
82 | G_IO_ERROR,
83 | G_IO_ERROR_FAILED,
84 | "Too many arguments. "
85 | "The swap command requires 2 arguments: PACKAGE_TO_REMOVE and PACKAGE_TO_INSTALL.");
86 | return FALSE;
87 | }
88 |
89 | /* Install new package */
90 | if (!dnf_context_install (ctx, pkgs[1], error))
91 | return FALSE;
92 | /* Remove package */
93 | if (!dnf_context_remove (ctx, pkgs[0], error))
94 | return FALSE;
95 | DnfGoalActions flags = DNF_INSTALL | DNF_ERASE;
96 | if (dnf_context_get_best())
97 | flags |= DNF_FORCE_BEST;
98 | if (!dnf_context_get_install_weak_deps ())
99 | flags |= DNF_IGNORE_WEAK_DEPS;
100 | if (!dnf_goal_depsolve (dnf_context_get_goal (ctx), flags, error))
101 | return FALSE;
102 | if (!dnf_utils_print_transaction (ctx))
103 | return TRUE;
104 | if (!dnf_utils_userconfirm ())
105 | return FALSE;
106 | if (!dnf_context_run (ctx, NULL, error))
107 | return FALSE;
108 | g_print ("Complete.\n");
109 |
110 | return TRUE;
111 | }
112 |
113 | static void
114 | dnf_command_swap_class_init (DnfCommandSwapClass *klass)
115 | {
116 | }
117 |
118 | static void
119 | dnf_command_swap_iface_init (DnfCommandInterface *iface)
120 | {
121 | iface->run = dnf_command_swap_run;
122 | }
123 |
124 | static void
125 | dnf_command_swap_class_finalize (DnfCommandSwapClass *klass)
126 | {
127 | }
128 |
129 | G_MODULE_EXPORT void
130 | dnf_command_swap_register_types (PeasObjectModule *module)
131 | {
132 | dnf_command_swap_register_type (G_TYPE_MODULE (module));
133 |
134 | peas_object_module_register_extension_type (module,
135 | DNF_TYPE_COMMAND,
136 | DNF_TYPE_COMMAND_SWAP);
137 | }
138 |
--------------------------------------------------------------------------------
/dnf/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | set (DNF_SRCS dnf-command.c dnf-utils.c)
2 |
3 | glib_compile_resources (DNF_COMMAND_INSTALL plugins/install/dnf-command-install.gresource.xml
4 | C_PREFIX dnf_command_install
5 | INTERNAL)
6 | list (APPEND DNF_COMMAND_INSTALL "plugins/install/dnf-command-install.c")
7 |
8 | glib_compile_resources (DNF_COMMAND_REINSTALL plugins/reinstall/dnf-command-reinstall.gresource.xml
9 | C_PREFIX dnf_command_reinstall
10 | INTERNAL)
11 | list (APPEND DNF_COMMAND_REINSTALL "plugins/reinstall/dnf-command-reinstall.c")
12 |
13 | glib_compile_resources (DNF_COMMAND_REMOVE plugins/remove/dnf-command-remove.gresource.xml
14 | C_PREFIX dnf_command_remove
15 | INTERNAL)
16 | list (APPEND DNF_COMMAND_REMOVE "plugins/remove/dnf-command-remove.c")
17 |
18 | glib_compile_resources (DNF_COMMAND_UPGRADE plugins/upgrade/dnf-command-upgrade.gresource.xml
19 | C_PREFIX dnf_command_upgrade
20 | INTERNAL)
21 | list (APPEND DNF_COMMAND_UPGRADE "plugins/upgrade/dnf-command-upgrade.c")
22 |
23 | glib_compile_resources (DNF_COMMAND_SWAP plugins/swap/dnf-command-swap.gresource.xml
24 | C_PREFIX dnf_command_swap
25 | INTERNAL)
26 | list (APPEND DNF_COMMAND_SWAP "plugins/swap/dnf-command-swap.c")
27 |
28 | glib_compile_resources (DNF_COMMAND_DISTROSYNC plugins/distrosync/dnf-command-distrosync.gresource.xml
29 | C_PREFIX dnf_command_distrosync
30 | INTERNAL)
31 | list (APPEND DNF_COMMAND_DISTROSYNC "plugins/distrosync/dnf-command-distrosync.c")
32 |
33 | glib_compile_resources (DNF_COMMAND_REPOLIST plugins/repolist/dnf-command-repolist.gresource.xml
34 | C_PREFIX dnf_command_repolist
35 | INTERNAL)
36 | list (APPEND DNF_COMMAND_REPOLIST "plugins/repolist/dnf-command-repolist.c")
37 |
38 | glib_compile_resources (DNF_COMMAND_REPOQUERY plugins/repoquery/dnf-command-repoquery.gresource.xml
39 | C_PREFIX dnf_command_repoquery
40 | INTERNAL)
41 | list (APPEND DNF_COMMAND_REPOQUERY "plugins/repoquery/dnf-command-repoquery.c")
42 |
43 | glib_compile_resources (DNF_COMMAND_LEAVES plugins/leaves/dnf-command-leaves.gresource.xml
44 | C_PREFIX dnf_command_leaves
45 | INTERNAL)
46 | list (APPEND DNF_COMMAND_LEAVES "plugins/leaves/dnf-command-leaves.c")
47 |
48 | glib_compile_resources (DNF_COMMAND_CLEAN plugins/clean/dnf-command-clean.gresource.xml
49 | C_PREFIX dnf_command_clean
50 | INTERNAL)
51 | list (APPEND DNF_COMMAND_CLEAN "plugins/clean/dnf-command-clean.c")
52 |
53 | glib_compile_resources (DNF_COMMAND_DOWNLOAD plugins/download/dnf-command-download.gresource.xml
54 | C_PREFIX dnf_command_download
55 | INTERNAL)
56 | list (APPEND DNF_COMMAND_DOWNLOAD "plugins/download/dnf-command-download.c")
57 |
58 | glib_compile_resources (DNF_COMMAND_MAKECACHE plugins/makecache/dnf-command-makecache.gresource.xml
59 | C_PREFIX dnf_command_makecache
60 | INTERNAL)
61 | list (APPEND DNF_COMMAND_MAKECACHE "plugins/makecache/dnf-command-makecache.c")
62 |
63 | glib_compile_resources (DNF_COMMAND_MODULE_ENABLE plugins/module_enable/dnf-command-module_enable.gresource.xml
64 | C_PREFIX dnf_command_module_enable
65 | INTERNAL)
66 | list (APPEND DNF_COMMAND_MODULE_ENABLE "plugins/module_enable/dnf-command-module_enable.c")
67 |
68 | glib_compile_resources (DNF_COMMAND_MODULE_DISABLE plugins/module_disable/dnf-command-module_disable.gresource.xml
69 | C_PREFIX dnf_command_module_disable
70 | INTERNAL)
71 | list (APPEND DNF_COMMAND_MODULE_DISABLE "plugins/module_disable/dnf-command-module_disable.c")
72 |
73 | glib_compile_resources (DNF_COMMAND_MODULE_RESET plugins/module_reset/dnf-command-module_reset.gresource.xml
74 | C_PREFIX dnf_command_module_reset
75 | INTERNAL)
76 | list (APPEND DNF_COMMAND_MODULE_RESET "plugins/module_reset/dnf-command-module_reset.c")
77 |
78 |
79 | include_directories (${CMAKE_CURRENT_SOURCE_DIR})
80 | add_executable (microdnf dnf-main.c ${DNF_SRCS}
81 | ${DNF_COMMAND_INSTALL}
82 | ${DNF_COMMAND_REINSTALL}
83 | ${DNF_COMMAND_REMOVE}
84 | ${DNF_COMMAND_UPGRADE}
85 | ${DNF_COMMAND_SWAP}
86 | ${DNF_COMMAND_DISTROSYNC}
87 | ${DNF_COMMAND_REPOLIST}
88 | ${DNF_COMMAND_REPOQUERY}
89 | ${DNF_COMMAND_LEAVES}
90 | ${DNF_COMMAND_CLEAN}
91 | ${DNF_COMMAND_DOWNLOAD}
92 | ${DNF_COMMAND_MAKECACHE}
93 | ${DNF_COMMAND_MODULE_ENABLE}
94 | ${DNF_COMMAND_MODULE_DISABLE}
95 | ${DNF_COMMAND_MODULE_RESET})
96 |
97 | target_link_libraries (microdnf
98 | ${GLIB_LIBRARIES}
99 | ${GOBJECT_LIBRARIES}
100 | ${PEAS_LIBRARIES}
101 | ${LIBDNF_LIBRARIES}
102 | ${SCOLS_LIBRARIES})
103 | target_compile_definitions (microdnf
104 | PRIVATE -DBUILDDIR="${CMAKE_CURRENT_BINARY_DIR}"
105 | PRIVATE -DSRCDIR="${CMAKE_CURRENT_SOURCE_DIR}")
106 |
107 | add_subdirectory (plugins)
108 |
109 | install (TARGETS microdnf
110 | RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
111 |
--------------------------------------------------------------------------------
/dnf/plugins/repolist/dnf-command-repolist.c:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2019 Red Hat, Inc.
3 | *
4 | * Licensed under the GNU Lesser General Public License Version 2.1
5 | *
6 | * This library is free software; you can redistribute it and/or
7 | * modify it under the terms of the GNU Lesser General Public
8 | * License as published by the Free Software Foundation; either
9 | * version 2.1 of the License, or (at your option) any later version.
10 | *
11 | * This library is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 | * Lesser General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU Lesser General Public
17 | * License along with this library; if not, write to the Free Software
18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 | */
20 |
21 | #include "dnf-command-repolist.h"
22 |
23 | #include
24 | #include
25 |
26 | struct _DnfCommandRepolist
27 | {
28 | PeasExtensionBase parent_instance;
29 | };
30 |
31 | static void dnf_command_repolist_iface_init (DnfCommandInterface *iface);
32 |
33 | G_DEFINE_DYNAMIC_TYPE_EXTENDED (DnfCommandRepolist,
34 | dnf_command_repolist,
35 | PEAS_TYPE_EXTENSION_BASE,
36 | 0,
37 | G_IMPLEMENT_INTERFACE (DNF_TYPE_COMMAND,
38 | dnf_command_repolist_iface_init))
39 |
40 | static void
41 | dnf_command_repolist_init (DnfCommandRepolist *self)
42 | {
43 | }
44 |
45 | // repository list table columns
46 | enum { COL_REPO_ID, COL_REPO_NAME, COL_REPO_STATUS };
47 |
48 | static struct libscols_table *
49 | create_repolist_table (gboolean with_status)
50 | {
51 | struct libscols_table *table = scols_new_table ();
52 | if (isatty (1))
53 | {
54 | scols_table_enable_colors (table, 1);
55 | scols_table_enable_maxout (table, 1);
56 | }
57 | struct libscols_column *cl = scols_table_new_column (table, "repo id", 0.4, 0);
58 | scols_column_set_cmpfunc(cl, scols_cmpstr_cells, NULL);
59 | scols_table_new_column (table, "repo name", 0.5, SCOLS_FL_TRUNC);
60 | if (with_status)
61 | scols_table_new_column (table, "status", 0.1, SCOLS_FL_RIGHT);
62 | return table;
63 | }
64 |
65 | static void
66 | add_line_into_table (struct libscols_table *table,
67 | gboolean with_status,
68 | const char *id,
69 | const char *descr,
70 | gboolean enabled)
71 | {
72 | struct libscols_line *ln = scols_table_new_line (table, NULL);
73 | scols_line_set_data (ln, COL_REPO_ID, id);
74 | scols_line_set_data (ln, COL_REPO_NAME, descr);
75 | if (with_status)
76 | {
77 | scols_line_set_data (ln, COL_REPO_STATUS, enabled ? "enabled" : "disabled");
78 | struct libscols_cell * cl = scols_line_get_cell (ln, COL_REPO_STATUS);
79 | scols_cell_set_color (cl, enabled ? "green" : "red");
80 | }
81 | }
82 |
83 | static gboolean
84 | dnf_command_repolist_run (DnfCommand *cmd,
85 | int argc,
86 | char *argv[],
87 | GOptionContext *opt_ctx,
88 | DnfContext *ctx,
89 | GError **error)
90 | {
91 | gboolean opt_all = FALSE;
92 | gboolean opt_enabled = FALSE;
93 | gboolean opt_disabled = FALSE;
94 | g_auto(GStrv) opt_repos = NULL;
95 | const GOptionEntry opts[] = {
96 | { "all", '\0', G_OPTION_FLAG_NONE, G_OPTION_ARG_NONE, &opt_all, "show all repos", NULL },
97 | { "disabled", '\0', G_OPTION_FLAG_NONE, G_OPTION_ARG_NONE, &opt_disabled, "show disabled repos", NULL },
98 | { "enabled", '\0', G_OPTION_FLAG_NONE, G_OPTION_ARG_NONE, &opt_enabled, "show enabled repos (default)", NULL },
99 | { G_OPTION_REMAINING, '\0', 0, G_OPTION_ARG_STRING_ARRAY, &opt_repos, NULL, NULL },
100 | { NULL }
101 | };
102 | g_option_context_add_main_entries (opt_ctx, opts, NULL);
103 |
104 | if (!g_option_context_parse (opt_ctx, &argc, &argv, error))
105 | return FALSE;
106 |
107 | if (opt_repos && opt_repos[0])
108 | {
109 | g_set_error (error,
110 | G_OPTION_ERROR,
111 | G_OPTION_ERROR_UNKNOWN_OPTION,
112 | "Unknown argument %s", opt_repos[0]);
113 | return FALSE;
114 | }
115 |
116 | if (!opt_disabled)
117 | opt_enabled = TRUE;
118 |
119 | if (opt_enabled && opt_disabled)
120 | opt_all = TRUE;
121 |
122 | struct libscols_table *table = create_repolist_table (opt_all);
123 |
124 | GPtrArray *repos = dnf_context_get_repos (ctx);
125 | for (guint i = 0; i < repos->len; ++i)
126 | {
127 | DnfRepo * repo = g_ptr_array_index (repos, i);
128 | gboolean enabled = dnf_repo_get_enabled (repo) & DNF_REPO_ENABLED_PACKAGES;
129 | if (opt_all || (opt_enabled && enabled) || (opt_disabled && !enabled))
130 | {
131 | const gchar * id = dnf_repo_get_id (repo);
132 | g_autofree gchar * descr = dnf_repo_get_description (repo);
133 | add_line_into_table (table, opt_all, id, descr, enabled);
134 | }
135 | }
136 |
137 | struct libscols_column *cl = scols_table_get_column (table, COL_REPO_ID);
138 | scols_sort_table (table, cl);
139 | scols_print_table (table);
140 | scols_unref_table (table);
141 |
142 | return TRUE;
143 | }
144 |
145 | static void
146 | dnf_command_repolist_class_init (DnfCommandRepolistClass *klass)
147 | {
148 | }
149 |
150 | static void
151 | dnf_command_repolist_iface_init (DnfCommandInterface *iface)
152 | {
153 | iface->run = dnf_command_repolist_run;
154 | }
155 |
156 | static void
157 | dnf_command_repolist_class_finalize (DnfCommandRepolistClass *klass)
158 | {
159 | }
160 |
161 | G_MODULE_EXPORT void
162 | dnf_command_repolist_register_types (PeasObjectModule *module)
163 | {
164 | dnf_command_repolist_register_type (G_TYPE_MODULE (module));
165 |
166 | peas_object_module_register_extension_type (module,
167 | DNF_TYPE_COMMAND,
168 | DNF_TYPE_COMMAND_REPOLIST);
169 | }
170 |
--------------------------------------------------------------------------------
/dnf/plugins/reinstall/dnf-command-reinstall.c:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2019 Red Hat, Inc.
3 | *
4 | * Licensed under the GNU Lesser General Public License Version 2.1
5 | *
6 | * This library is free software; you can redistribute it and/or
7 | * modify it under the terms of the GNU Lesser General Public
8 | * License as published by the Free Software Foundation; either
9 | * version 2.1 of the License, or (at your option) any later version.
10 | *
11 | * This library is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 | * Lesser General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU Lesser General Public
17 | * License along with this library; if not, write to the Free Software
18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 | */
20 |
21 | #include "dnf-command-reinstall.h"
22 | #include "dnf-utils.h"
23 |
24 | struct _DnfCommandReinstall
25 | {
26 | PeasExtensionBase parent_instance;
27 | };
28 |
29 | static void dnf_command_reinstall_iface_init (DnfCommandInterface *iface);
30 |
31 | G_DEFINE_DYNAMIC_TYPE_EXTENDED (DnfCommandReinstall,
32 | dnf_command_reinstall,
33 | PEAS_TYPE_EXTENSION_BASE,
34 | 0,
35 | G_IMPLEMENT_INTERFACE (DNF_TYPE_COMMAND,
36 | dnf_command_reinstall_iface_init))
37 |
38 | static void
39 | dnf_command_reinstall_init (DnfCommandReinstall *self)
40 | {
41 | }
42 |
43 | static gint
44 | compare_nevra (gconstpointer a, gconstpointer b, gpointer user_data)
45 | {
46 | return g_strcmp0 (a, b);
47 | }
48 |
49 | static void
50 | packageset_free (gpointer pkg_set)
51 | {
52 | dnf_packageset_free (pkg_set);
53 | }
54 |
55 | static gboolean
56 | dnf_command_reinstall_arg (DnfContext *ctx, const char *arg, GError **error)
57 | {
58 | DnfSack *sack = dnf_context_get_sack (ctx);
59 |
60 | g_auto(HySubject) subject = hy_subject_create (arg);
61 | HyNevra out_nevra;
62 | hy_autoquery HyQuery query = hy_subject_get_best_solution (subject, sack, NULL, &out_nevra,
63 | FALSE, TRUE, TRUE, TRUE, TRUE);
64 | if (out_nevra)
65 | hy_nevra_free (out_nevra);
66 |
67 | hy_autoquery HyQuery query_installed = hy_query_clone (query);
68 | hy_query_filter (query_installed, HY_PKG_REPONAME, HY_EQ, HY_SYSTEM_REPO_NAME);
69 | g_autoptr(GPtrArray) installed_pkgs = hy_query_run (query_installed);
70 |
71 | hy_query_filter (query, HY_PKG_REPONAME, HY_NEQ, HY_SYSTEM_REPO_NAME);
72 | g_autoptr(GPtrArray) available_pkgs = hy_query_run (query);
73 |
74 | if (installed_pkgs->len == 0)
75 | {
76 | if (available_pkgs->len == 0)
77 | {
78 | g_print ("No match for argument: %s\n", arg);
79 | }
80 | else
81 | {
82 | g_print ("Package for argument %s available, but not installed.\n", arg);
83 | }
84 | return TRUE;
85 | }
86 |
87 | g_autoptr(GTree) available_nevra2pkg_set = g_tree_new_full (compare_nevra, NULL,
88 | g_free, packageset_free);
89 | for (guint i = 0; i < available_pkgs->len; ++i)
90 | {
91 | DnfPackage *package = available_pkgs->pdata[i];
92 | const char *nevra = dnf_package_get_nevra (package);
93 | DnfPackageSet *pkg_set = g_tree_lookup (available_nevra2pkg_set, nevra);
94 | if (!pkg_set)
95 | {
96 | pkg_set = dnf_packageset_new (sack);
97 | /* dnf_package_get_nevra() returns pointer to temporary buffer -> copy is needed */
98 | g_tree_insert (available_nevra2pkg_set, g_strdup (nevra), pkg_set);
99 | }
100 | dnf_packageset_add (pkg_set, package);
101 | }
102 |
103 | HyGoal goal = dnf_context_get_goal (ctx);
104 | for (guint i = 0; i < installed_pkgs->len; ++i)
105 | {
106 | DnfPackage *package = installed_pkgs->pdata[i];
107 | const char *nevra = dnf_package_get_nevra (package);
108 | DnfPackageSet *available_pkgs = g_tree_lookup (available_nevra2pkg_set, nevra);
109 | if (available_pkgs) {
110 | g_auto(HySelector) selector = hy_selector_create (sack);
111 | hy_selector_pkg_set (selector, available_pkgs);
112 | if (!hy_goal_install_selector (goal, selector, error))
113 | return FALSE;
114 | }
115 | else
116 | g_print ("Installed package %s not available.\n", nevra);
117 | }
118 |
119 | return TRUE;
120 | }
121 |
122 | static gboolean
123 | dnf_command_reinstall_run (DnfCommand *cmd,
124 | int argc,
125 | char *argv[],
126 | GOptionContext *opt_ctx,
127 | DnfContext *ctx,
128 | GError **error)
129 | {
130 | g_auto(GStrv) pkgs = NULL;
131 | const GOptionEntry opts[] = {
132 | { G_OPTION_REMAINING, '\0', 0, G_OPTION_ARG_STRING_ARRAY, &pkgs, NULL, NULL },
133 | { NULL }
134 | };
135 | g_option_context_add_main_entries (opt_ctx, opts, NULL);
136 |
137 | if (!g_option_context_parse (opt_ctx, &argc, &argv, error))
138 | return FALSE;
139 |
140 | if (pkgs == NULL)
141 | {
142 | g_set_error_literal (error,
143 | G_IO_ERROR,
144 | G_IO_ERROR_FAILED,
145 | "Packages are not specified");
146 | return FALSE;
147 | }
148 |
149 | DnfState * state = dnf_context_get_state (ctx);
150 | if (!dnf_context_setup_sack_with_flags (ctx, state, DNF_CONTEXT_SETUP_SACK_FLAG_NONE, error)) {
151 | return FALSE;
152 | }
153 |
154 | for (GStrv pkg = pkgs; *pkg != NULL; pkg++)
155 | {
156 | if (!dnf_command_reinstall_arg (ctx, *pkg, error))
157 | return FALSE;
158 | }
159 |
160 | DnfGoalActions flags = DNF_INSTALL;
161 | if (!dnf_context_get_install_weak_deps ())
162 | flags |= DNF_IGNORE_WEAK_DEPS;
163 | if (!dnf_goal_depsolve (dnf_context_get_goal (ctx), flags, error))
164 | return FALSE;
165 |
166 | DnfTransaction *transaction = dnf_context_get_transaction (ctx);
167 | int tsflags = dnf_transaction_get_flags (transaction);
168 | dnf_transaction_set_flags(transaction, tsflags | DNF_TRANSACTION_FLAG_ALLOW_REINSTALL);
169 |
170 | if (!dnf_utils_print_transaction (ctx))
171 | return TRUE;
172 | if (!dnf_utils_userconfirm ())
173 | return FALSE;
174 | if (!dnf_context_run (ctx, NULL, error))
175 | return FALSE;
176 |
177 | g_print ("Complete.\n");
178 |
179 | return TRUE;
180 | }
181 |
182 | static void
183 | dnf_command_reinstall_class_init (DnfCommandReinstallClass *klass)
184 | {
185 | }
186 |
187 | static void
188 | dnf_command_reinstall_iface_init (DnfCommandInterface *iface)
189 | {
190 | iface->run = dnf_command_reinstall_run;
191 | }
192 |
193 | static void
194 | dnf_command_reinstall_class_finalize (DnfCommandReinstallClass *klass)
195 | {
196 | }
197 |
198 | G_MODULE_EXPORT void
199 | dnf_command_reinstall_register_types (PeasObjectModule *module)
200 | {
201 | dnf_command_reinstall_register_type (G_TYPE_MODULE (module));
202 |
203 | peas_object_module_register_extension_type (module,
204 | DNF_TYPE_COMMAND,
205 | DNF_TYPE_COMMAND_REINSTALL);
206 | }
207 |
--------------------------------------------------------------------------------
/dnf/plugins/repoquery/dnf-command-repoquery.c:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2019 Red Hat, Inc.
3 | *
4 | * Licensed under the GNU Lesser General Public License Version 2.1
5 | *
6 | * This library is free software; you can redistribute it and/or
7 | * modify it under the terms of the GNU Lesser General Public
8 | * License as published by the Free Software Foundation; either
9 | * version 2.1 of the License, or (at your option) any later version.
10 | *
11 | * This library is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 | * Lesser General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU Lesser General Public
17 | * License along with this library; if not, write to the Free Software
18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 | */
20 |
21 | #include "dnf-command-repoquery.h"
22 |
23 | #include
24 |
25 | struct _DnfCommandRepoquery
26 | {
27 | PeasExtensionBase parent_instance;
28 | };
29 |
30 | static void dnf_command_repoquery_iface_init (DnfCommandInterface *iface);
31 |
32 | G_DEFINE_DYNAMIC_TYPE_EXTENDED (DnfCommandRepoquery,
33 | dnf_command_repoquery,
34 | PEAS_TYPE_EXTENSION_BASE,
35 | 0,
36 | G_IMPLEMENT_INTERFACE (DNF_TYPE_COMMAND,
37 | dnf_command_repoquery_iface_init))
38 |
39 | static void
40 | dnf_command_repoquery_init (DnfCommandRepoquery *self)
41 | {
42 | }
43 |
44 | static void
45 | disable_available_repos (DnfContext *ctx)
46 | {
47 | GPtrArray *repos = dnf_context_get_repos (ctx);
48 | for (guint i = 0; i < repos->len; ++i)
49 | {
50 | DnfRepo * repo = g_ptr_array_index (repos, i);
51 | dnf_repo_set_enabled (repo, DNF_REPO_ENABLED_NONE);
52 | }
53 | }
54 |
55 | static gint
56 | gptrarr_dnf_package_cmp (gconstpointer a, gconstpointer b)
57 | {
58 | return dnf_package_cmp(*(DnfPackage**)a, *(DnfPackage**)b);
59 | }
60 |
61 | static void
62 | package_info_add_line (struct libscols_table *table, const char *key, const char *value)
63 | {
64 | struct libscols_line *ln = scols_table_new_line (table, NULL);
65 | scols_line_set_data (ln, 0, key);
66 | scols_line_set_data (ln, 1, value);
67 | }
68 |
69 | static void
70 | print_package_info (DnfPackage *package)
71 | {
72 | struct libscols_table *table = scols_new_table ();
73 | scols_table_enable_noheadings (table, 1);
74 | scols_table_set_column_separator (table, " : ");
75 | scols_table_new_column (table, "key", 5, 0);
76 | struct libscols_column *cl = scols_table_new_column (table, "value", 10, SCOLS_FL_WRAP);
77 | scols_column_set_safechars (cl, "\n");
78 | scols_column_set_wrapfunc (cl, scols_wrapnl_chunksize, scols_wrapnl_nextchunk, NULL);
79 |
80 | package_info_add_line (table, "Name", dnf_package_get_name (package));
81 | guint64 epoch = dnf_package_get_epoch (package);
82 | if (epoch != 0)
83 | {
84 | g_autofree gchar *str_epoch = g_strdup_printf ("%ld", epoch);
85 | package_info_add_line (table, "Epoch", str_epoch);
86 | }
87 | package_info_add_line (table, "Version", dnf_package_get_version (package));
88 | package_info_add_line (table, "Release", dnf_package_get_release (package));
89 | package_info_add_line (table, "Architecture", dnf_package_get_arch (package));
90 | g_autofree gchar *size = g_format_size_full (dnf_package_get_size (package),
91 | G_FORMAT_SIZE_LONG_FORMAT | G_FORMAT_SIZE_IEC_UNITS);
92 | package_info_add_line (table, "Size", size);
93 | package_info_add_line (table, "Source", dnf_package_get_sourcerpm (package));
94 | package_info_add_line (table, "Repository", dnf_package_get_reponame (package));
95 | package_info_add_line (table, "Summary", dnf_package_get_summary (package));
96 | package_info_add_line (table, "URL", dnf_package_get_url (package));
97 | package_info_add_line (table, "License", dnf_package_get_license (package));
98 | package_info_add_line (table, "Description", dnf_package_get_description (package));
99 |
100 | scols_print_table (table);
101 | scols_unref_table (table);
102 | }
103 |
104 | static gboolean
105 | dnf_command_repoquery_run (DnfCommand *cmd,
106 | int argc,
107 | char *argv[],
108 | GOptionContext *opt_ctx,
109 | DnfContext *ctx,
110 | GError **error)
111 | {
112 | gboolean opt_available = FALSE;
113 | gboolean opt_info = FALSE;
114 | gboolean opt_installed = FALSE;
115 | gboolean opt_nevra = FALSE;
116 | g_auto(GStrv) opt_key = NULL;
117 | const GOptionEntry opts[] = {
118 | { "available", '\0', G_OPTION_FLAG_NONE, G_OPTION_ARG_NONE, &opt_available, "display available packages (default)", NULL },
119 | { "info", '\0', G_OPTION_FLAG_NONE, G_OPTION_ARG_NONE, &opt_info, "show detailed information about the packages", NULL },
120 | { "installed", '\0', G_OPTION_FLAG_NONE, G_OPTION_ARG_NONE, &opt_installed, "display installed packages", NULL },
121 | { "nevra", '\0', G_OPTION_FLAG_NONE, G_OPTION_ARG_NONE, &opt_nevra,
122 | "use name-epoch:version-release.architecture format for displaying packages (default)", NULL },
123 | { G_OPTION_REMAINING, '\0', 0, G_OPTION_ARG_STRING_ARRAY, &opt_key, NULL, NULL },
124 | { NULL }
125 | };
126 | g_option_context_add_main_entries (opt_ctx, opts, NULL);
127 |
128 | if (!g_option_context_parse (opt_ctx, &argc, &argv, error))
129 | return FALSE;
130 |
131 | // --available is default (compatibility with YUM/DNF)
132 | if (!opt_available && !opt_installed)
133 | opt_available = TRUE;
134 |
135 | if (opt_available && opt_installed)
136 | opt_available = opt_installed = FALSE;
137 |
138 | if (opt_installed)
139 | disable_available_repos (ctx);
140 |
141 | DnfState * state = dnf_context_get_state (ctx);
142 | DnfContextSetupSackFlags sack_flags = opt_available ? DNF_CONTEXT_SETUP_SACK_FLAG_SKIP_RPMDB
143 | : DNF_CONTEXT_SETUP_SACK_FLAG_NONE;
144 | if (!dnf_context_setup_sack_with_flags (ctx, state, sack_flags, error)) {
145 | return FALSE;
146 | }
147 | DnfSack *sack = dnf_context_get_sack (ctx);
148 |
149 | hy_autoquery HyQuery query = hy_query_create (sack);
150 |
151 | if (opt_key)
152 | {
153 | hy_query_filter_empty (query);
154 | for (char **pkey = opt_key; *pkey; ++pkey)
155 | {
156 | g_auto(HySubject) subject = hy_subject_create (*pkey);
157 | HyNevra out_nevra;
158 | hy_autoquery HyQuery key_query = hy_subject_get_best_solution (subject, sack, NULL,
159 | &out_nevra, TRUE, TRUE, FALSE, TRUE, TRUE);
160 | if (out_nevra)
161 | hy_nevra_free(out_nevra);
162 | hy_query_union (query, key_query);
163 | }
164 | }
165 |
166 | g_autoptr(GPtrArray) pkgs = hy_query_run (query);
167 |
168 | g_ptr_array_sort (pkgs, gptrarr_dnf_package_cmp);
169 |
170 | const char *prev_line = "";
171 | for (guint i = 0; i < pkgs->len; ++i)
172 | {
173 | DnfPackage *package = g_ptr_array_index (pkgs, i);
174 | if (opt_nevra || !opt_info)
175 | {
176 | const char * line = dnf_package_get_nevra (package);
177 | // print nevras without duplicated lines
178 | if (opt_info || strcmp (line, prev_line) != 0)
179 | {
180 | g_print ("%s\n", line);
181 | prev_line = line;
182 | }
183 | }
184 | if (opt_info)
185 | {
186 | print_package_info (package);
187 | g_print ("\n");
188 | }
189 | }
190 |
191 | return TRUE;
192 | }
193 |
194 | static void
195 | dnf_command_repoquery_class_init (DnfCommandRepoqueryClass *klass)
196 | {
197 | }
198 |
199 | static void
200 | dnf_command_repoquery_iface_init (DnfCommandInterface *iface)
201 | {
202 | iface->run = dnf_command_repoquery_run;
203 | }
204 |
205 | static void
206 | dnf_command_repoquery_class_finalize (DnfCommandRepoqueryClass *klass)
207 | {
208 | }
209 |
210 | G_MODULE_EXPORT void
211 | dnf_command_repoquery_register_types (PeasObjectModule *module)
212 | {
213 | dnf_command_repoquery_register_type (G_TYPE_MODULE (module));
214 |
215 | peas_object_module_register_extension_type (module,
216 | DNF_TYPE_COMMAND,
217 | DNF_TYPE_COMMAND_REPOQUERY);
218 | }
219 |
--------------------------------------------------------------------------------
/dnf/dnf-utils.c:
--------------------------------------------------------------------------------
1 | /* dnf-utils.c
2 | *
3 | * Copyright © 2010-2015 Richard Hughes
4 | * Copyright © 2016 Colin Walters
5 | * Copyright © 2016-2017 Igor Gnatenko
6 | * Copyright © 2017-2020 Jaroslav Rohel
7 | *
8 | * This program is free software: you can redistribute it and/or modify
9 | * it under the terms of the GNU General Public License as published by
10 | * the Free Software Foundation, either version 2 of the License, or
11 | * (at your option) any later version.
12 | *
13 | * This program is distributed in the hope that it will be useful,
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 | * GNU General Public License for more details.
17 | *
18 | * You should have received a copy of the GNU General Public License
19 | * along with this program. If not, see .
20 | */
21 |
22 | #include "dnf-utils.h"
23 | #include
24 |
25 |
26 | // transaction details columns
27 | enum { COL_NEVRA, COL_REPO, COL_SIZE };
28 |
29 |
30 | static gint
31 | dnf_package_cmp_cb (DnfPackage **pkg1, DnfPackage **pkg2)
32 | {
33 | return dnf_package_cmp (*pkg1, *pkg2);
34 | }
35 |
36 |
37 | static void
38 | dnf_utils_add_transaction_packages (DnfContext *ctx,
39 | struct libscols_table *tb,
40 | struct libscols_line *parent,
41 | GPtrArray *pkgs)
42 | {
43 | // sort packages by NEVRA
44 | g_ptr_array_sort (pkgs, (GCompareFunc) dnf_package_cmp_cb);
45 |
46 | HyGoal goal = dnf_context_get_goal (ctx);
47 | for (guint i = 0; i < pkgs->len; i++)
48 | {
49 | DnfPackage *pkg = pkgs->pdata[i];
50 |
51 | struct libscols_line *ln = scols_table_new_line (tb, parent);
52 | scols_line_set_data (ln, COL_NEVRA, dnf_package_get_nevra (pkg));
53 | scols_line_set_data (ln, COL_REPO, dnf_package_get_reponame (pkg));
54 | g_autofree gchar *formatted_pkg_size = g_format_size (dnf_package_get_size (pkg));
55 | g_auto(GStrv) formatted_pkg_size_parts = g_strsplit (formatted_pkg_size, "\xC2\xA0", -1);
56 | g_autofree gchar *formatted_pkg_size_simple_spaces = g_strjoinv (" ", formatted_pkg_size_parts);
57 | scols_line_set_data (ln, COL_SIZE, formatted_pkg_size_simple_spaces);
58 |
59 | if (dnf_package_get_action (pkg) != DNF_STATE_ACTION_REMOVE)
60 | {
61 | g_autoptr(GPtrArray) pkgs_replaced = hy_goal_list_obsoleted_by_package (goal, pkg);
62 | g_ptr_array_sort (pkgs_replaced, (GCompareFunc) dnf_package_cmp_cb);
63 | for (guint i = 0; i < pkgs_replaced->len; i++)
64 | {
65 | DnfPackage *pkg = pkgs_replaced->pdata[i];
66 | struct libscols_line *replacing_ln = scols_table_new_line (tb, ln);
67 | g_autofree gchar *replacing_text = g_strconcat ("replacing ", dnf_package_get_nevra (pkg), NULL);
68 | scols_line_set_data (replacing_ln, COL_NEVRA, replacing_text);
69 | }
70 | }
71 | }
72 | }
73 |
74 |
75 | gboolean
76 | dnf_utils_conf_main_get_bool_opt (const gchar *name, enum DnfConfPriority *priority)
77 | {
78 | g_autofree gchar *tmp = dnf_conf_main_get_option (name, priority, NULL);
79 | return tmp != NULL && (*tmp == '1' || *tmp == 'y' || *tmp == 'Y');
80 | }
81 |
82 |
83 | gboolean
84 | dnf_utils_userconfirm (void)
85 | {
86 | gboolean ret;
87 | enum DnfConfPriority priority;
88 |
89 | // "assumeno" takes precedence over "assumeyes"
90 | if (dnf_utils_conf_main_get_bool_opt ("assumeno", &priority))
91 | ret = FALSE;
92 | else if (dnf_utils_conf_main_get_bool_opt ("assumeyes", &priority))
93 | ret = TRUE;
94 | else
95 | {
96 | gboolean defaultyes = dnf_utils_conf_main_get_bool_opt ("defaultyes", &priority);
97 |
98 | const char *msg;
99 | if (defaultyes)
100 | msg = "Is this ok [Y/n]: ";
101 | else
102 | msg = "Is this ok [y/N]: ";
103 |
104 | while (TRUE)
105 | {
106 | g_print ("%s", msg);
107 |
108 | char choice = getchar ();
109 | if (choice == '\n' || choice == '\r')
110 | {
111 | ret = defaultyes;
112 | break;
113 | }
114 |
115 | char second = getchar ();
116 | for (char ch = second; ch != '\n'; ch = getchar ())
117 | ;
118 |
119 | if (second == '\n' || second == '\r')
120 | {
121 | if (choice == 'y' || choice == 'Y')
122 | {
123 | ret = TRUE;
124 | break;
125 | }
126 | if (choice == 'n' || choice == 'N')
127 | {
128 | ret = FALSE;
129 | break;
130 | }
131 | }
132 | }
133 | }
134 |
135 | if (!ret)
136 | g_print ("Operation aborted.\n");
137 |
138 | return ret;
139 | }
140 |
141 | gboolean
142 | dnf_utils_print_transaction (DnfContext *ctx)
143 | {
144 | g_autoptr(GPtrArray) pkgs = dnf_goal_get_packages (dnf_context_get_goal (ctx),
145 | DNF_PACKAGE_INFO_INSTALL,
146 | DNF_PACKAGE_INFO_REINSTALL,
147 | DNF_PACKAGE_INFO_DOWNGRADE,
148 | DNF_PACKAGE_INFO_UPDATE,
149 | DNF_PACKAGE_INFO_REMOVE,
150 | -1);
151 |
152 | if (pkgs->len == 0)
153 | {
154 | g_autofree char * report = dnf_context_get_module_report (ctx);
155 | if (report)
156 | {
157 | g_print ("%s\n", report);
158 | return TRUE;
159 | } else {
160 | g_print ("Nothing to do.\n");
161 | return FALSE;
162 | }
163 | }
164 |
165 | struct libscols_line *ln;
166 |
167 | struct libscols_table *tb = scols_new_table ();
168 | scols_table_new_column (tb, "Package", 0.7, SCOLS_FL_TREE);
169 | scols_table_new_column (tb, "Repository", 0.2, SCOLS_FL_TRUNC);
170 | scols_table_new_column (tb, "Size", 0.1, SCOLS_FL_RIGHT);
171 | scols_table_enable_maxout (tb, 1);
172 | struct libscols_symbols *sb = scols_new_symbols ();
173 | scols_symbols_set_branch (sb, " ");
174 | scols_symbols_set_right (sb, " ");
175 | scols_symbols_set_vertical (sb, " ");
176 | scols_table_set_symbols (tb, sb);
177 |
178 | g_autoptr(GPtrArray) pkgs_install = dnf_goal_get_packages (dnf_context_get_goal (ctx),
179 | DNF_PACKAGE_INFO_INSTALL,
180 | -1);
181 | if (pkgs_install->len != 0)
182 | {
183 | ln = scols_table_new_line (tb, NULL);
184 | scols_line_set_data (ln, COL_NEVRA, "Installing:");
185 | dnf_utils_add_transaction_packages (ctx, tb, ln, pkgs_install);
186 | }
187 |
188 | g_autoptr(GPtrArray) pkgs_reinstall = dnf_goal_get_packages (dnf_context_get_goal (ctx),
189 | DNF_PACKAGE_INFO_REINSTALL,
190 | -1);
191 | if (pkgs_reinstall->len != 0)
192 | {
193 | ln = scols_table_new_line (tb, NULL);
194 | scols_line_set_data (ln, COL_NEVRA, "Reinstalling:");
195 | dnf_utils_add_transaction_packages (ctx, tb, ln, pkgs_reinstall);
196 | }
197 |
198 | g_autoptr(GPtrArray) pkgs_upgrade = dnf_goal_get_packages (dnf_context_get_goal (ctx),
199 | DNF_PACKAGE_INFO_UPDATE,
200 | -1);
201 | if (pkgs_upgrade->len != 0)
202 | {
203 | ln = scols_table_new_line (tb, NULL);
204 | scols_line_set_data (ln, COL_NEVRA, "Upgrading:");
205 | dnf_utils_add_transaction_packages (ctx, tb, ln, pkgs_upgrade);
206 | }
207 |
208 | g_autoptr(GPtrArray) pkgs_obsolete = dnf_goal_get_packages (dnf_context_get_goal (ctx),
209 | DNF_PACKAGE_INFO_OBSOLETE,
210 | -1);
211 |
212 | g_autoptr(GPtrArray) pkgs_remove = dnf_goal_get_packages (dnf_context_get_goal (ctx),
213 | DNF_PACKAGE_INFO_REMOVE,
214 | -1);
215 | if (pkgs_remove->len != 0)
216 | {
217 | ln = scols_table_new_line (tb, NULL);
218 | scols_line_set_data (ln, COL_NEVRA, "Removing:");
219 | dnf_utils_add_transaction_packages (ctx, tb, ln, pkgs_remove);
220 | }
221 |
222 | g_autoptr(GPtrArray) pkgs_downgrade = dnf_goal_get_packages (dnf_context_get_goal (ctx),
223 | DNF_PACKAGE_INFO_DOWNGRADE,
224 | -1);
225 | if (pkgs_downgrade->len != 0)
226 | {
227 | ln = scols_table_new_line (tb, NULL);
228 | scols_line_set_data (ln, COL_NEVRA, "Downgrading:");
229 | dnf_utils_add_transaction_packages (ctx, tb, ln, pkgs_downgrade);
230 | }
231 |
232 | scols_print_table (tb);
233 | scols_unref_symbols (sb);
234 | scols_unref_table (tb);
235 |
236 | g_print ("Transaction Summary:\n");
237 | g_print (" %-15s %4d packages\n", "Installing:", pkgs_install->len);
238 | g_print (" %-15s %4d packages\n", "Reinstalling:", pkgs_reinstall->len);
239 | g_print (" %-15s %4d packages\n", "Upgrading:", pkgs_upgrade->len);
240 | g_print (" %-15s %4d packages\n", "Obsoleting:", pkgs_obsolete->len);
241 | g_print (" %-15s %4d packages\n", "Removing:", pkgs_remove->len);
242 | g_print (" %-15s %4d packages\n", "Downgrading:", pkgs_downgrade->len);
243 |
244 | g_autofree char * report = dnf_context_get_module_report (ctx);
245 | if (report)
246 | {
247 | g_print ("%s\n", report);
248 | }
249 | /* check for test mode */
250 | DnfTransaction *txn = dnf_context_get_transaction (ctx);
251 | if (dnf_transaction_get_flags (txn) & DNF_TRANSACTION_FLAG_TEST)
252 | g_print ("Test mode enabled: Microdnf will only download packages, install gpg keys, and check the transaction.\n");
253 |
254 | return TRUE;
255 | }
256 |
--------------------------------------------------------------------------------
/dnf/plugins/leaves/dnf-command-leaves.c:
--------------------------------------------------------------------------------
1 | /* dnf-command-leaves.c
2 | *
3 | * Copyright © 2022 Emil Renner Berthing
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 2 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 |
19 | #include "dnf-command-leaves.h"
20 |
21 | typedef struct {
22 | guint len;
23 | guint idx[];
24 | } IdxArray;
25 |
26 | static IdxArray *
27 | idx_array_new (guint len)
28 | {
29 | return g_malloc0 (G_STRUCT_OFFSET (IdxArray, idx) + len * sizeof (guint));
30 | }
31 |
32 | static void
33 | idx_array_add (IdxArray *arr, guint idx)
34 | {
35 | arr->idx[arr->len++] = idx;
36 | }
37 |
38 | static gboolean
39 | idx_array_from_set_iter (gpointer key, gpointer value, gpointer user_data)
40 | {
41 | IdxArray *arr = user_data;
42 | idx_array_add (arr, GPOINTER_TO_UINT (key));
43 | return TRUE;
44 | }
45 |
46 | static gint
47 | idx_array_compare_func (gconstpointer a, gconstpointer b, gpointer user_data)
48 | {
49 | guint x = *(const guint *)a;
50 | guint y = *(const guint *)b;
51 |
52 | if (x < y)
53 | return -1;
54 | return x > y;
55 | }
56 |
57 | static IdxArray *
58 | idx_array_copy (const guint *idx, guint len)
59 | {
60 | IdxArray *arr = idx_array_new (len);
61 | arr->len = len;
62 | for (guint i = 0; i < len; i++)
63 | arr->idx[i] = idx[i];
64 | g_qsort_with_data (arr->idx, arr->len, sizeof (*arr->idx), idx_array_compare_func, NULL);
65 | return arr;
66 | }
67 |
68 | static IdxArray *
69 | idx_array_from_set (GHashTable *set)
70 | {
71 | IdxArray *arr = idx_array_new (g_hash_table_size (set));
72 | g_hash_table_foreach_remove (set, idx_array_from_set_iter, arr);
73 | g_qsort_with_data (arr->idx, arr->len, sizeof (*arr->idx), idx_array_compare_func, NULL);
74 | return arr;
75 | }
76 |
77 | static gint
78 | gtree_dnf_package_cmp (gconstpointer a, gconstpointer b)
79 | {
80 | return dnf_package_cmp ((DnfPackage *)a, (DnfPackage *)b);
81 | }
82 |
83 | static void
84 | add_edges (GHashTable *edges, HyQuery query, GTree *pkg2idx, DnfReldepList *deps)
85 | {
86 | const gint ndeps = dnf_reldep_list_count (deps);
87 |
88 | // resolve dependencies and add an edge if there is exactly one package satisfying it
89 | for (gint j = 0; j < ndeps; j++)
90 | {
91 | DnfReldep *dep = dnf_reldep_list_index (deps, j);
92 |
93 | hy_query_filter_reldep (query, HY_PKG_PROVIDES, dep);
94 | g_autoptr(GPtrArray) ppkgs = hy_query_run (query);
95 | hy_query_clear (query);
96 | dnf_reldep_free (dep);
97 |
98 | if (ppkgs->len != 1)
99 | continue;
100 |
101 | const DnfPackage *ppkg = g_ptr_array_index (ppkgs, 0);
102 | GTreeNode *node = g_tree_lookup_node (pkg2idx, ppkg);;
103 | g_assert (node);
104 | g_hash_table_insert (edges, g_tree_node_value (node), NULL);
105 | }
106 |
107 | dnf_reldep_list_free (deps);
108 | }
109 |
110 | static GPtrArray *
111 | build_graph (HyQuery query, const GPtrArray *pkgs, gboolean recommends)
112 | {
113 | // create pkg2idx to map DnfPackages to their index in pkgs
114 | g_autoptr(GTree) pkg2idx = g_tree_new (gtree_dnf_package_cmp);
115 | for (guint i = 0; i < pkgs->len; i++)
116 | {
117 | DnfPackage *pkg = g_ptr_array_index (pkgs, i);
118 | g_tree_insert (pkg2idx, pkg, GUINT_TO_POINTER (i));
119 | }
120 |
121 | GPtrArray *graph = g_ptr_array_new_full (pkgs->len, g_free);
122 | g_autoptr(GHashTable) edges = g_hash_table_new (g_direct_hash, g_direct_equal);
123 |
124 | for (guint i = 0; i < pkgs->len; i++)
125 | {
126 | DnfPackage *pkg = g_ptr_array_index (pkgs, i);
127 | add_edges (edges, query, pkg2idx, dnf_package_get_requires (pkg));
128 | if (recommends)
129 | add_edges (edges, query, pkg2idx, dnf_package_get_recommends (pkg));
130 | g_hash_table_remove (edges, GUINT_TO_POINTER (i)); // remove self-edges
131 | g_ptr_array_add (graph, idx_array_from_set (edges));
132 | }
133 |
134 | return graph;
135 | }
136 |
137 | static GPtrArray *
138 | reverse_graph (const GPtrArray *graph)
139 | {
140 | g_autofree guint *len = g_malloc0 (graph->len * sizeof (*len));
141 |
142 | for (guint i = 0; i < graph->len; i++)
143 | {
144 | const IdxArray *edges = g_ptr_array_index (graph, i);
145 |
146 | for (guint j = 0; j < edges->len; j++)
147 | len[edges->idx[j]]++;
148 | }
149 |
150 | GPtrArray *rgraph = g_ptr_array_new_full (graph->len, g_free);
151 | for (guint i = 0; i < graph->len; i++)
152 | g_ptr_array_add (rgraph, idx_array_new (len[i]));
153 |
154 | for (guint i = 0; i < graph->len; i++)
155 | {
156 | const IdxArray *edges = g_ptr_array_index (graph, i);
157 |
158 | for (guint j = 0; j < edges->len; j++)
159 | {
160 | IdxArray *redges = g_ptr_array_index (rgraph, edges->idx[j]);
161 | idx_array_add (redges, i);
162 | }
163 | }
164 |
165 | return rgraph;
166 | }
167 |
168 | static GPtrArray *
169 | kosaraju (const GPtrArray *graph)
170 | {
171 | const guint N = graph->len;
172 | g_autofree guint *rstack = g_malloc (N * sizeof (*rstack));
173 | g_autofree guint *stack = g_malloc (N * sizeof (*stack));
174 | g_autofree gboolean *tag = g_malloc0 (N * sizeof (*tag));
175 | guint r = N;
176 | guint top = 0;
177 |
178 | // do depth-first searches in the graph and push nodes to rstack
179 | // "on the way up" until all nodes have been pushed.
180 | // tag nodes as they're processed so we don't visit them more than once
181 | for (guint i = 0; i < N; i++)
182 | {
183 | if (tag[i])
184 | continue;
185 |
186 | guint u = i;
187 | guint j = 0;
188 | tag[u] = TRUE;
189 | while (true)
190 | {
191 | const IdxArray *edges = g_ptr_array_index (graph, u);
192 | if (j < edges->len)
193 | {
194 | const guint v = edges->idx[j++];
195 | if (!tag[v])
196 | {
197 | rstack[top] = j;
198 | stack[top++] = u;
199 | u = v;
200 | j = 0;
201 | tag[u] = TRUE;
202 | }
203 | }
204 | else
205 | {
206 | rstack[--r] = u;
207 | if (!top)
208 | break;
209 | u = stack[--top];
210 | j = rstack[top];
211 | }
212 | }
213 | }
214 | g_assert (r == 0);
215 |
216 | // now searches beginning at nodes popped from rstack in the graph with all
217 | // edges reversed will give us the strongly connected components.
218 | // this time all nodes are tagged, so let's remove the tags as we visit each
219 | // node.
220 | // the incoming edges to each component is the union of incoming edges to
221 | // each node in the component minus the incoming edges from component nodes
222 | // themselves.
223 | // if there are no such incoming edges the component is a leaf and we
224 | // add it to the array of leaves.
225 | g_autoptr(GPtrArray) rgraph = reverse_graph (graph);
226 | g_autoptr(GHashTable) sccredges = g_hash_table_new (g_direct_hash, g_direct_equal);
227 | GPtrArray *leaves = g_ptr_array_new_with_free_func (g_free);
228 | for (; r < N; r++)
229 | {
230 | guint u = rstack[r];
231 | if (!tag[u])
232 | continue;
233 |
234 | stack[top++] = u;
235 | tag[u] = FALSE;
236 | guint s = N;
237 | while (top)
238 | {
239 | u = stack[--s] = stack[--top];
240 | const IdxArray *redges = g_ptr_array_index (rgraph, u);
241 | for (guint j = 0; j < redges->len; j++)
242 | {
243 | const guint v = redges->idx[j];
244 | g_hash_table_insert (sccredges, GUINT_TO_POINTER (v), NULL);
245 | if (!tag[v])
246 | continue;
247 |
248 | stack[top++] = v;
249 | tag[v] = FALSE;
250 | }
251 | }
252 |
253 | for (guint i = s; i < N; i++)
254 | g_hash_table_remove (sccredges, GUINT_TO_POINTER (stack[i]));
255 |
256 | if (g_hash_table_size (sccredges) == 0)
257 | g_ptr_array_add (leaves, idx_array_copy (&stack[s], N - s));
258 | else
259 | g_hash_table_remove_all (sccredges);
260 | }
261 |
262 | return leaves;
263 | }
264 |
265 | struct _DnfCommandLeaves
266 | {
267 | PeasExtensionBase parent_instance;
268 | };
269 |
270 | static void dnf_command_leaves_iface_init (DnfCommandInterface *iface);
271 |
272 | G_DEFINE_DYNAMIC_TYPE_EXTENDED (DnfCommandLeaves,
273 | dnf_command_leaves,
274 | PEAS_TYPE_EXTENSION_BASE,
275 | 0,
276 | G_IMPLEMENT_INTERFACE (DNF_TYPE_COMMAND,
277 | dnf_command_leaves_iface_init))
278 |
279 | static void
280 | dnf_command_leaves_init (DnfCommandLeaves *self)
281 | {
282 | }
283 |
284 | static void
285 | disable_available_repos (DnfContext *ctx)
286 | {
287 | const GPtrArray *repos = dnf_context_get_repos (ctx);
288 |
289 | for (guint i = 0; i < repos->len; ++i)
290 | {
291 | DnfRepo *repo = g_ptr_array_index (repos, i);
292 | dnf_repo_set_enabled (repo, DNF_REPO_ENABLED_NONE);
293 | }
294 | }
295 |
296 | static gint
297 | gptrarr_dnf_package_cmp (gconstpointer a, gconstpointer b)
298 | {
299 | DnfPackage *const *x = a;
300 | DnfPackage *const *y = b;
301 | return dnf_package_cmp (*x, *y);
302 | }
303 |
304 | static gint
305 | gptrarr_first_package_cmp (gconstpointer a, gconstpointer b)
306 | {
307 | IdxArray *const *x = a;
308 | IdxArray *const *y = b;
309 | guint i = (*x)->idx[0];
310 | guint j = (*y)->idx[0];
311 |
312 | if (i < j)
313 | return -1;
314 | return i > j;
315 | }
316 |
317 | static gboolean
318 | dnf_command_leaves_run (DnfCommand *cmd,
319 | int argc,
320 | char *argv[],
321 | GOptionContext *opt_ctx,
322 | DnfContext *ctx,
323 | GError **error)
324 | {
325 | if (!g_option_context_parse (opt_ctx, &argc, &argv, error))
326 | return FALSE;
327 |
328 | // only look at installed packages
329 | disable_available_repos (ctx);
330 | if (!dnf_context_setup_sack_with_flags (ctx,
331 | dnf_context_get_state (ctx),
332 | DNF_CONTEXT_SETUP_SACK_FLAG_NONE,
333 | error)) {
334 |
335 | return FALSE;
336 | }
337 |
338 | // get a sorted array of all installed packages
339 | hy_autoquery HyQuery query = hy_query_create (dnf_context_get_sack (ctx));
340 | g_autoptr(GPtrArray) pkgs = hy_query_run (query);
341 | g_ptr_array_sort (pkgs, gptrarr_dnf_package_cmp);
342 |
343 | // build the directed graph of dependencies
344 | g_autoptr(GPtrArray) graph = build_graph (query, pkgs, dnf_context_get_install_weak_deps ());
345 |
346 | // run Kosaraju's algorithm to find strongly connected components
347 | // withhout any incoming edges
348 | g_autoptr(GPtrArray) leaves = kosaraju (graph);
349 | g_ptr_array_sort (leaves, gptrarr_first_package_cmp);
350 |
351 | // print the packages grouped by their components
352 | for (guint i = 0; i < leaves->len; i++)
353 | {
354 | const IdxArray *scc = g_ptr_array_index (leaves, i);
355 | gchar mark = '-';
356 |
357 | for (guint j = 0; j < scc->len; j++)
358 | {
359 | DnfPackage *pkg = g_ptr_array_index (pkgs, scc->idx[j]);
360 | g_print ("%c %s\n", mark, dnf_package_get_nevra (pkg));
361 | mark = ' ';
362 | }
363 | }
364 |
365 | return TRUE;
366 | }
367 |
368 | static void
369 | dnf_command_leaves_class_init (DnfCommandLeavesClass *klass)
370 | {
371 | }
372 |
373 | static void
374 | dnf_command_leaves_iface_init (DnfCommandInterface *iface)
375 | {
376 | iface->run = dnf_command_leaves_run;
377 | }
378 |
379 | static void
380 | dnf_command_leaves_class_finalize (DnfCommandLeavesClass *klass)
381 | {
382 | }
383 |
384 | G_MODULE_EXPORT void
385 | dnf_command_leaves_register_types (PeasObjectModule *module)
386 | {
387 | dnf_command_leaves_register_type (G_TYPE_MODULE (module));
388 |
389 | peas_object_module_register_extension_type (module,
390 | DNF_TYPE_COMMAND,
391 | DNF_TYPE_COMMAND_LEAVES);
392 | }
393 |
--------------------------------------------------------------------------------
/COPYING:
--------------------------------------------------------------------------------
1 | GNU GENERAL PUBLIC LICENSE
2 | Version 2, June 1991
3 |
4 | Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
5 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
6 | Everyone is permitted to copy and distribute verbatim copies
7 | of this license document, but changing it is not allowed.
8 |
9 | Preamble
10 |
11 | The licenses for most software are designed to take away your
12 | freedom to share and change it. By contrast, the GNU General Public
13 | License is intended to guarantee your freedom to share and change free
14 | software--to make sure the software is free for all its users. This
15 | General Public License applies to most of the Free Software
16 | Foundation's software and to any other program whose authors commit to
17 | using it. (Some other Free Software Foundation software is covered by
18 | the GNU Lesser General Public License instead.) You can apply it to
19 | your programs, too.
20 |
21 | When we speak of free software, we are referring to freedom, not
22 | price. Our General Public Licenses are designed to make sure that you
23 | have the freedom to distribute copies of free software (and charge for
24 | this service if you wish), that you receive source code or can get it
25 | if you want it, that you can change the software or use pieces of it
26 | in new free programs; and that you know you can do these things.
27 |
28 | To protect your rights, we need to make restrictions that forbid
29 | anyone to deny you these rights or to ask you to surrender the rights.
30 | These restrictions translate to certain responsibilities for you if you
31 | distribute copies of the software, or if you modify it.
32 |
33 | For example, if you distribute copies of such a program, whether
34 | gratis or for a fee, you must give the recipients all the rights that
35 | you have. You must make sure that they, too, receive or can get the
36 | source code. And you must show them these terms so they know their
37 | rights.
38 |
39 | We protect your rights with two steps: (1) copyright the software, and
40 | (2) offer you this license which gives you legal permission to copy,
41 | distribute and/or modify the software.
42 |
43 | Also, for each author's protection and ours, we want to make certain
44 | that everyone understands that there is no warranty for this free
45 | software. If the software is modified by someone else and passed on, we
46 | want its recipients to know that what they have is not the original, so
47 | that any problems introduced by others will not reflect on the original
48 | authors' reputations.
49 |
50 | Finally, any free program is threatened constantly by software
51 | patents. We wish to avoid the danger that redistributors of a free
52 | program will individually obtain patent licenses, in effect making the
53 | program proprietary. To prevent this, we have made it clear that any
54 | patent must be licensed for everyone's free use or not licensed at all.
55 |
56 | The precise terms and conditions for copying, distribution and
57 | modification follow.
58 |
59 | GNU GENERAL PUBLIC LICENSE
60 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
61 |
62 | 0. This License applies to any program or other work which contains
63 | a notice placed by the copyright holder saying it may be distributed
64 | under the terms of this General Public License. The "Program", below,
65 | refers to any such program or work, and a "work based on the Program"
66 | means either the Program or any derivative work under copyright law:
67 | that is to say, a work containing the Program or a portion of it,
68 | either verbatim or with modifications and/or translated into another
69 | language. (Hereinafter, translation is included without limitation in
70 | the term "modification".) Each licensee is addressed as "you".
71 |
72 | Activities other than copying, distribution and modification are not
73 | covered by this License; they are outside its scope. The act of
74 | running the Program is not restricted, and the output from the Program
75 | is covered only if its contents constitute a work based on the
76 | Program (independent of having been made by running the Program).
77 | Whether that is true depends on what the Program does.
78 |
79 | 1. You may copy and distribute verbatim copies of the Program's
80 | source code as you receive it, in any medium, provided that you
81 | conspicuously and appropriately publish on each copy an appropriate
82 | copyright notice and disclaimer of warranty; keep intact all the
83 | notices that refer to this License and to the absence of any warranty;
84 | and give any other recipients of the Program a copy of this License
85 | along with the Program.
86 |
87 | You may charge a fee for the physical act of transferring a copy, and
88 | you may at your option offer warranty protection in exchange for a fee.
89 |
90 | 2. You may modify your copy or copies of the Program or any portion
91 | of it, thus forming a work based on the Program, and copy and
92 | distribute such modifications or work under the terms of Section 1
93 | above, provided that you also meet all of these conditions:
94 |
95 | a) You must cause the modified files to carry prominent notices
96 | stating that you changed the files and the date of any change.
97 |
98 | b) You must cause any work that you distribute or publish, that in
99 | whole or in part contains or is derived from the Program or any
100 | part thereof, to be licensed as a whole at no charge to all third
101 | parties under the terms of this License.
102 |
103 | c) If the modified program normally reads commands interactively
104 | when run, you must cause it, when started running for such
105 | interactive use in the most ordinary way, to print or display an
106 | announcement including an appropriate copyright notice and a
107 | notice that there is no warranty (or else, saying that you provide
108 | a warranty) and that users may redistribute the program under
109 | these conditions, and telling the user how to view a copy of this
110 | License. (Exception: if the Program itself is interactive but
111 | does not normally print such an announcement, your work based on
112 | the Program is not required to print an announcement.)
113 |
114 | These requirements apply to the modified work as a whole. If
115 | identifiable sections of that work are not derived from the Program,
116 | and can be reasonably considered independent and separate works in
117 | themselves, then this License, and its terms, do not apply to those
118 | sections when you distribute them as separate works. But when you
119 | distribute the same sections as part of a whole which is a work based
120 | on the Program, the distribution of the whole must be on the terms of
121 | this License, whose permissions for other licensees extend to the
122 | entire whole, and thus to each and every part regardless of who wrote it.
123 |
124 | Thus, it is not the intent of this section to claim rights or contest
125 | your rights to work written entirely by you; rather, the intent is to
126 | exercise the right to control the distribution of derivative or
127 | collective works based on the Program.
128 |
129 | In addition, mere aggregation of another work not based on the Program
130 | with the Program (or with a work based on the Program) on a volume of
131 | a storage or distribution medium does not bring the other work under
132 | the scope of this License.
133 |
134 | 3. You may copy and distribute the Program (or a work based on it,
135 | under Section 2) in object code or executable form under the terms of
136 | Sections 1 and 2 above provided that you also do one of the following:
137 |
138 | a) Accompany it with the complete corresponding machine-readable
139 | source code, which must be distributed under the terms of Sections
140 | 1 and 2 above on a medium customarily used for software interchange; or,
141 |
142 | b) Accompany it with a written offer, valid for at least three
143 | years, to give any third party, for a charge no more than your
144 | cost of physically performing source distribution, a complete
145 | machine-readable copy of the corresponding source code, to be
146 | distributed under the terms of Sections 1 and 2 above on a medium
147 | customarily used for software interchange; or,
148 |
149 | c) Accompany it with the information you received as to the offer
150 | to distribute corresponding source code. (This alternative is
151 | allowed only for noncommercial distribution and only if you
152 | received the program in object code or executable form with such
153 | an offer, in accord with Subsection b above.)
154 |
155 | The source code for a work means the preferred form of the work for
156 | making modifications to it. For an executable work, complete source
157 | code means all the source code for all modules it contains, plus any
158 | associated interface definition files, plus the scripts used to
159 | control compilation and installation of the executable. However, as a
160 | special exception, the source code distributed need not include
161 | anything that is normally distributed (in either source or binary
162 | form) with the major components (compiler, kernel, and so on) of the
163 | operating system on which the executable runs, unless that component
164 | itself accompanies the executable.
165 |
166 | If distribution of executable or object code is made by offering
167 | access to copy from a designated place, then offering equivalent
168 | access to copy the source code from the same place counts as
169 | distribution of the source code, even though third parties are not
170 | compelled to copy the source along with the object code.
171 |
172 | 4. You may not copy, modify, sublicense, or distribute the Program
173 | except as expressly provided under this License. Any attempt
174 | otherwise to copy, modify, sublicense or distribute the Program is
175 | void, and will automatically terminate your rights under this License.
176 | However, parties who have received copies, or rights, from you under
177 | this License will not have their licenses terminated so long as such
178 | parties remain in full compliance.
179 |
180 | 5. You are not required to accept this License, since you have not
181 | signed it. However, nothing else grants you permission to modify or
182 | distribute the Program or its derivative works. These actions are
183 | prohibited by law if you do not accept this License. Therefore, by
184 | modifying or distributing the Program (or any work based on the
185 | Program), you indicate your acceptance of this License to do so, and
186 | all its terms and conditions for copying, distributing or modifying
187 | the Program or works based on it.
188 |
189 | 6. Each time you redistribute the Program (or any work based on the
190 | Program), the recipient automatically receives a license from the
191 | original licensor to copy, distribute or modify the Program subject to
192 | these terms and conditions. You may not impose any further
193 | restrictions on the recipients' exercise of the rights granted herein.
194 | You are not responsible for enforcing compliance by third parties to
195 | this License.
196 |
197 | 7. If, as a consequence of a court judgment or allegation of patent
198 | infringement or for any other reason (not limited to patent issues),
199 | conditions are imposed on you (whether by court order, agreement or
200 | otherwise) that contradict the conditions of this License, they do not
201 | excuse you from the conditions of this License. If you cannot
202 | distribute so as to satisfy simultaneously your obligations under this
203 | License and any other pertinent obligations, then as a consequence you
204 | may not distribute the Program at all. For example, if a patent
205 | license would not permit royalty-free redistribution of the Program by
206 | all those who receive copies directly or indirectly through you, then
207 | the only way you could satisfy both it and this License would be to
208 | refrain entirely from distribution of the Program.
209 |
210 | If any portion of this section is held invalid or unenforceable under
211 | any particular circumstance, the balance of the section is intended to
212 | apply and the section as a whole is intended to apply in other
213 | circumstances.
214 |
215 | It is not the purpose of this section to induce you to infringe any
216 | patents or other property right claims or to contest validity of any
217 | such claims; this section has the sole purpose of protecting the
218 | integrity of the free software distribution system, which is
219 | implemented by public license practices. Many people have made
220 | generous contributions to the wide range of software distributed
221 | through that system in reliance on consistent application of that
222 | system; it is up to the author/donor to decide if he or she is willing
223 | to distribute software through any other system and a licensee cannot
224 | impose that choice.
225 |
226 | This section is intended to make thoroughly clear what is believed to
227 | be a consequence of the rest of this License.
228 |
229 | 8. If the distribution and/or use of the Program is restricted in
230 | certain countries either by patents or by copyrighted interfaces, the
231 | original copyright holder who places the Program under this License
232 | may add an explicit geographical distribution limitation excluding
233 | those countries, so that distribution is permitted only in or among
234 | countries not thus excluded. In such case, this License incorporates
235 | the limitation as if written in the body of this License.
236 |
237 | 9. The Free Software Foundation may publish revised and/or new versions
238 | of the General Public License from time to time. Such new versions will
239 | be similar in spirit to the present version, but may differ in detail to
240 | address new problems or concerns.
241 |
242 | Each version is given a distinguishing version number. If the Program
243 | specifies a version number of this License which applies to it and "any
244 | later version", you have the option of following the terms and conditions
245 | either of that version or of any later version published by the Free
246 | Software Foundation. If the Program does not specify a version number of
247 | this License, you may choose any version ever published by the Free Software
248 | Foundation.
249 |
250 | 10. If you wish to incorporate parts of the Program into other free
251 | programs whose distribution conditions are different, write to the author
252 | to ask for permission. For software which is copyrighted by the Free
253 | Software Foundation, write to the Free Software Foundation; we sometimes
254 | make exceptions for this. Our decision will be guided by the two goals
255 | of preserving the free status of all derivatives of our free software and
256 | of promoting the sharing and reuse of software generally.
257 |
258 | NO WARRANTY
259 |
260 | 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
261 | FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
262 | OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
263 | PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
264 | OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
265 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
266 | TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
267 | PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
268 | REPAIR OR CORRECTION.
269 |
270 | 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
271 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
272 | REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
273 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
274 | OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
275 | TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
276 | YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
277 | PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
278 | POSSIBILITY OF SUCH DAMAGES.
279 |
280 | END OF TERMS AND CONDITIONS
281 |
282 | How to Apply These Terms to Your New Programs
283 |
284 | If you develop a new program, and you want it to be of the greatest
285 | possible use to the public, the best way to achieve this is to make it
286 | free software which everyone can redistribute and change under these terms.
287 |
288 | To do so, attach the following notices to the program. It is safest
289 | to attach them to the start of each source file to most effectively
290 | convey the exclusion of warranty; and each file should have at least
291 | the "copyright" line and a pointer to where the full notice is found.
292 |
293 |
294 | Copyright (C)
295 |
296 | This program is free software; you can redistribute it and/or modify
297 | it under the terms of the GNU General Public License as published by
298 | the Free Software Foundation; either version 2 of the License, or
299 | (at your option) any later version.
300 |
301 | This program is distributed in the hope that it will be useful,
302 | but WITHOUT ANY WARRANTY; without even the implied warranty of
303 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
304 | GNU General Public License for more details.
305 |
306 | You should have received a copy of the GNU General Public License along
307 | with this program; if not, write to the Free Software Foundation, Inc.,
308 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
309 |
310 | Also add information on how to contact you by electronic and paper mail.
311 |
312 | If the program is interactive, make it output a short notice like this
313 | when it starts in an interactive mode:
314 |
315 | Gnomovision version 69, Copyright (C) year name of author
316 | Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
317 | This is free software, and you are welcome to redistribute it
318 | under certain conditions; type `show c' for details.
319 |
320 | The hypothetical commands `show w' and `show c' should show the appropriate
321 | parts of the General Public License. Of course, the commands you use may
322 | be called something other than `show w' and `show c'; they could even be
323 | mouse-clicks or menu items--whatever suits your program.
324 |
325 | You should also get your employer (if you work as a programmer) or your
326 | school, if any, to sign a "copyright disclaimer" for the program, if
327 | necessary. Here is a sample; alter the names:
328 |
329 | Yoyodyne, Inc., hereby disclaims all copyright interest in the program
330 | `Gnomovision' (which makes passes at compilers) written by James Hacker.
331 |
332 | , 1 April 1989
333 | Ty Coon, President of Vice
334 |
335 | This General Public License does not permit incorporating your program into
336 | proprietary programs. If your program is a subroutine library, you may
337 | consider it more useful to permit linking proprietary applications with the
338 | library. If this is what you want to do, use the GNU Lesser General
339 | Public License instead of this License.
340 |
--------------------------------------------------------------------------------
/dnf/plugins/download/dnf-command-download.c:
--------------------------------------------------------------------------------
1 | /* dnf-command-download.c
2 | *
3 | * Copyright © 2020-2021 Daniel Hams
4 | * Copyright © 2021 Jaroslav Rohel
5 | *
6 | * This program is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU General Public License as published by
8 | * the Free Software Foundation, either version 2 of the License, or
9 | * (at your option) any later version.
10 | *
11 | * This program is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU General Public License
17 | * along with this program. If not, see .
18 | */
19 |
20 | #include "dnf-command-download.h"
21 | #include "dnf-utils.h"
22 |
23 | /* For MAXPATHLEN */
24 | #include
25 |
26 | struct _DnfCommandDownload
27 | {
28 | PeasExtensionBase parent_instance;
29 | };
30 |
31 | static void dnf_command_download_iface_init (DnfCommandInterface *iface);
32 |
33 | G_DEFINE_DYNAMIC_TYPE_EXTENDED (DnfCommandDownload,
34 | dnf_command_download,
35 | PEAS_TYPE_EXTENSION_BASE,
36 | 0,
37 | G_IMPLEMENT_INTERFACE (DNF_TYPE_COMMAND,
38 | dnf_command_download_iface_init))
39 |
40 | static void
41 | dnf_command_download_init (DnfCommandDownload *self)
42 | {
43 | }
44 |
45 | inline static gboolean
46 | str_ends_with (const gchar * buf, const gchar * val)
47 | {
48 | size_t buf_len = strlen (buf);
49 | size_t val_len = strlen (val);
50 | return buf_len >= val_len && memcmp (buf + buf_len - val_len, val, val_len) == 0;
51 | }
52 |
53 | /* Implements the functionality of the "g_ptr_array_extend_and_steal" function.
54 | * The function was added to glib in version 2.62. We don't want to require a newer glib. */
55 | static void
56 | ptr_array_extend_and_steal (GPtrArray *array_to_extend, GPtrArray *array)
57 | {
58 | guint origin_len = array_to_extend->len;
59 | g_ptr_array_set_size (array_to_extend, origin_len + array->len);
60 | for (guint i = 0; i < array->len; ++i)
61 | {
62 | g_ptr_array_index (array_to_extend, origin_len + i) = g_ptr_array_index (array, i);
63 | }
64 | array->len = 0;
65 | g_ptr_array_unref (array);
66 | }
67 |
68 | static gboolean dnf_command_download_rewriterepotosrc (gchar * repo_buf)
69 | {
70 | if (str_ends_with (repo_buf, "-rpms"))
71 | {
72 | // Add a terminator in the right place before we strcat
73 | repo_buf[strlen (repo_buf) - 5] = '\0';
74 | strcat (repo_buf, "-source-rpms");
75 | return TRUE;
76 | }
77 | else if (!str_ends_with (repo_buf, "-source"))
78 | {
79 | strcat (repo_buf, "-source");
80 | return TRUE;
81 | }
82 | return FALSE;
83 | }
84 |
85 | static gboolean
86 | dnf_command_download_enablesourcerepos (DnfContext *ctx,
87 | DnfRepoLoader *repo_loader,
88 | GError **error)
89 | {
90 | g_autoptr(GError) local_error = NULL;
91 | // A place where we can "extend" the repoid with an extension
92 | gchar tmp_name[MAXPATHLEN];
93 | g_autoptr(GPtrArray) all_repos = dnf_repo_loader_get_repos (repo_loader, error);
94 |
95 | // We have to activate repos in a second loop to avoid breaking the iterator
96 | // on the above repo list. We are "strdup"ing strings into it, so need
97 | // free called on them.
98 | g_autoptr(GPtrArray) repos_to_enable = g_ptr_array_new_full (all_repos->len,
99 | free);
100 | // Look for each enabled repo if there is a corresponding source repo
101 | // that we need to enable.
102 | for (guint i = 0 ; i < all_repos->len; ++i )
103 | {
104 | DnfRepo * repo = g_ptr_array_index (all_repos, i);
105 | const gchar * repo_id = dnf_repo_get_id (repo);
106 | if (dnf_repo_get_enabled (repo))
107 | {
108 | int repo_id_len = strlen (repo_id);
109 | if (repo_id_len >= (MAXPATHLEN - 1 - strlen ("-source-rpms")))
110 | {
111 | // Repo name too long when concatenated
112 | g_set_error (error,
113 | DNF_ERROR,
114 | DNF_ERROR_INTERNAL_ERROR,
115 | "Repository name overflow when -source-rpms added (%1$s)",
116 | repo_id);
117 | return FALSE;
118 | }
119 | strcpy (tmp_name, repo_id);
120 | // Only look for an associated source repo where adding an extension
121 | // makes sense
122 | if (dnf_command_download_rewriterepotosrc (tmp_name))
123 | {
124 | DnfRepo * src_repo = dnf_repo_loader_get_repo_by_id (repo_loader,
125 | tmp_name,
126 | &local_error);
127 | if (local_error != NULL)
128 | {
129 | if (!g_error_matches (local_error, DNF_ERROR, DNF_ERROR_REPO_NOT_FOUND))
130 | {
131 | g_propagate_error (error, local_error);
132 | return FALSE;
133 | }
134 | // Repo not found is not terminal
135 | g_error_free (local_error);
136 | local_error = NULL;
137 | continue;
138 | }
139 | if (!dnf_repo_get_enabled (src_repo))
140 | {
141 | // Repo exists and not enabled, add it to our list to enable
142 | g_ptr_array_add (repos_to_enable, strdup (tmp_name));
143 | }
144 | }
145 | // else repo "source" equiv already enabled or doesn't exist
146 | }
147 | }
148 |
149 | // Repo enable loop
150 | for (guint r = 0 ; r < repos_to_enable->len; ++r)
151 | {
152 | gchar * repo_to_enable_id = g_ptr_array_index (repos_to_enable, r);
153 | if (!dnf_context_repo_enable (ctx, repo_to_enable_id, error))
154 | {
155 | return FALSE;
156 | }
157 | else
158 | {
159 | g_print ("enabling %s repository\n", repo_to_enable_id);
160 | }
161 | }
162 | return TRUE;
163 | }
164 |
165 | static gint
166 | gptrarr_dnf_package_repopkgcmp (gconstpointer a, gconstpointer b)
167 | {
168 | // Sort by repo first, then by package
169 | // so we only need to add repo keys the first time we see a repo
170 | // in the package list
171 | DnfPackage **apkg = (DnfPackage**)a;
172 | DnfPackage **bpkg = (DnfPackage**)b;
173 | const gchar * areponame = dnf_package_get_reponame (*apkg);
174 | const gchar * breponame = dnf_package_get_reponame (*bpkg);
175 | int repocmp = strcmp (areponame, breponame);
176 | if (repocmp == 0)
177 | {
178 | return dnf_package_cmp (*apkg, *bpkg);
179 | }
180 | return repocmp;
181 | }
182 |
183 | /* Compare packages by repository priority and cost */
184 | static gint
185 | dnf_package_repo_prio_cost_cmp (gconstpointer pkg1, gconstpointer pkg2, gpointer repo_loader)
186 | {
187 | const gchar *pkg1_reponame = dnf_package_get_reponame ((DnfPackage*)pkg1);
188 | const gchar *pkg2_reponame = dnf_package_get_reponame ((DnfPackage*)pkg2);
189 | if (strcmp (pkg1_reponame, pkg2_reponame) == 0)
190 | return 0;
191 |
192 | DnfRepo *pkg1_repo = dnf_repo_loader_get_repo_by_id (repo_loader, pkg1_reponame, NULL);
193 | DnfRepo *pkg2_repo = dnf_repo_loader_get_repo_by_id (repo_loader, pkg2_reponame, NULL);
194 |
195 | // A higher value means a lower repository priority.
196 | int result = (pkg2_repo ? hy_repo_get_priority (dnf_repo_get_repo (pkg2_repo)) : INT_MAX) -
197 | (pkg1_repo ? hy_repo_get_priority (dnf_repo_get_repo (pkg1_repo)) : INT_MAX);
198 |
199 | if (result == 0)
200 | result = (pkg1_repo ? hy_repo_get_cost (dnf_repo_get_repo (pkg1_repo)) : INT_MAX) -
201 | (pkg2_repo ? hy_repo_get_cost (dnf_repo_get_repo (pkg2_repo)) : INT_MAX);
202 |
203 | return result;
204 | }
205 |
206 | /* The "pkgs" array can contain multiple packages with the same NEVRA.
207 | * The function selects one (from the cheapest repository with the highest priority) package for each NEVRA. */
208 | static GPtrArray *
209 | select_one_pkg_for_nevra (DnfRepoLoader *repo_loader, GPtrArray *pkgs)
210 | {
211 | g_autoptr(GHashTable) nevra2pkgs = g_hash_table_new (g_str_hash, g_str_equal);
212 | for (guint i = 0 ; i < pkgs->len; ++i)
213 | {
214 | DnfPackage *pkg = g_ptr_array_index (pkgs, i);
215 | const gchar *pkg_nevra = dnf_package_get_nevra (pkg);
216 | g_hash_table_insert (nevra2pkgs, (gpointer)pkg_nevra, g_slist_prepend (g_hash_table_lookup (nevra2pkgs, pkg_nevra), pkg));
217 | }
218 |
219 | g_autoptr(GPtrArray) pkgs_to_download = g_ptr_array_sized_new (g_hash_table_size (nevra2pkgs));
220 | GHashTableIter iter;
221 | GSList *pkgs_list;
222 | g_hash_table_iter_init (&iter, nevra2pkgs);
223 | while (g_hash_table_iter_next (&iter, NULL, (gpointer)&pkgs_list))
224 | {
225 | pkgs_list = g_slist_sort_with_data (pkgs_list, dnf_package_repo_prio_cost_cmp, repo_loader);
226 | g_ptr_array_add (pkgs_to_download, pkgs_list->data);
227 | g_slist_free (pkgs_list);
228 | }
229 |
230 | return g_steal_pointer (&pkgs_to_download);
231 | }
232 |
233 | static gboolean
234 | download_packages (DnfRepoLoader *repo_loader, GPtrArray *pkgs, DnfState *state, GError **error)
235 | {
236 | g_autoptr(GPtrArray) pkgs_to_download = select_one_pkg_for_nevra (repo_loader, pkgs);
237 |
238 | g_ptr_array_sort (pkgs_to_download, gptrarr_dnf_package_repopkgcmp);
239 | rpmKeyring keyring = rpmKeyringNew ();
240 | GError *error_local = NULL;
241 | gchar prev_repo[MAXPATHLEN];
242 | prev_repo[0] = '\0';
243 | for (guint i = 0 ; i < pkgs_to_download->len; ++i)
244 | {
245 | DnfPackage * pkg = g_ptr_array_index (pkgs_to_download, i);
246 | const gchar * pkg_nevra = dnf_package_get_nevra (pkg);
247 |
248 | const gchar * reponame = dnf_package_get_reponame (pkg);
249 | if (strlen (reponame) >= MAXPATHLEN)
250 | {
251 | g_error ("Reponame exceeds max path len (%s)\n", reponame);
252 | return FALSE;
253 | }
254 | DnfRepo * repo = dnf_repo_loader_get_repo_by_id (repo_loader, reponame, error);
255 | if (*error != 0)
256 | {
257 | g_print ("Failed to find repo(%s)\n", reponame);
258 | return FALSE;
259 | }
260 | // Add repo keys to keyring if this is the first time we see the repo
261 | if (prev_repo[0] == '\0' || strcmp (prev_repo, reponame) != 0)
262 | {
263 | g_auto(GStrv) pubkeys = dnf_repo_get_public_keys (repo);
264 | if (*pubkeys)
265 | {
266 | for (char **iter = pubkeys; iter && *iter; iter++)
267 | {
268 | const char *pubkey = *iter;
269 | if (!dnf_keyring_add_public_key (keyring, pubkey, error))
270 | {
271 | return FALSE;
272 | }
273 | }
274 | }
275 | strcpy (prev_repo, reponame);
276 | }
277 | dnf_package_set_repo (pkg, repo);
278 | const gchar *download_path = dnf_package_download (pkg, "./", state, error);
279 | if (*error != 0)
280 | {
281 | g_print ("Failed to download %s\n", pkg_nevra);
282 | return FALSE;
283 | }
284 |
285 | g_print ("Downloaded %s\n", pkg_nevra);
286 |
287 | // Check signature (if set on repo)
288 | if (dnf_repo_get_gpgcheck (repo) &&
289 | !dnf_keyring_check_untrusted_file (keyring, download_path, &error_local))
290 | {
291 | if (!g_error_matches (error_local, DNF_ERROR, DNF_ERROR_GPG_SIGNATURE_INVALID))
292 | {
293 | g_set_error (error,
294 | DNF_ERROR,
295 | DNF_ERROR_FILE_INVALID,
296 | "keyring check failure on %1$s "
297 | "and repo %2$s is GPG enabled: %3$s",
298 | dnf_package_get_nevra (pkg),
299 | dnf_repo_get_id (repo),
300 | error_local->message);
301 | g_error_free (error_local);
302 | return FALSE;
303 | }
304 | g_set_error (error,
305 | DNF_ERROR,
306 | DNF_ERROR_FILE_INVALID,
307 | "package %1$s cannot be verified "
308 | "and repo %2$s is GPG enabled: %3$s",
309 | dnf_package_get_nevra (pkg),
310 | dnf_repo_get_id (repo),
311 | error_local->message);
312 | g_error_free (error_local);
313 | return FALSE;
314 | }
315 | }
316 | return TRUE;
317 | }
318 |
319 | static HyQuery
320 | get_packages_query (DnfContext *ctx, GStrv pkgs_spec, gboolean opt_src, const gchar *opt_archlist)
321 | {
322 | DnfSack *sack = dnf_context_get_sack (ctx);
323 | hy_autoquery HyQuery query = hy_query_create (sack);
324 |
325 | if (pkgs_spec)
326 | {
327 | hy_query_filter_empty (query);
328 | for (char **pkey = pkgs_spec; *pkey; ++pkey)
329 | {
330 | g_auto(HySubject) subject = hy_subject_create (*pkey);
331 | HyNevra out_nevra;
332 | hy_autoquery HyQuery key_query =
333 | hy_subject_get_best_solution (subject, sack, NULL, &out_nevra,
334 | FALSE, TRUE, TRUE, TRUE, opt_src);
335 | if (out_nevra)
336 | {
337 | hy_nevra_free (out_nevra);
338 | }
339 | hy_query_filter (key_query, HY_PKG_REPONAME, HY_NEQ, HY_SYSTEM_REPO_NAME);
340 | hy_query_filter_num (key_query, HY_PKG_LATEST_PER_ARCH_BY_PRIORITY, HY_EQ, 1);
341 | hy_query_union (query, key_query);
342 | }
343 | }
344 | if (opt_src)
345 | {
346 | hy_query_filter (query, HY_PKG_ARCH, HY_EQ, "src");
347 | }
348 |
349 | if (opt_archlist)
350 | {
351 | g_auto(GStrv) archs_array = g_strsplit_set (opt_archlist, ", ", -1);
352 | hy_query_filter_in (query, HY_PKG_ARCH, HY_EQ, (const char**)archs_array);
353 | }
354 |
355 | return g_steal_pointer (&query);
356 | }
357 |
358 | static GPtrArray *
359 | get_packages_deps (DnfContext *ctx, GPtrArray *packages, GError **error)
360 | {
361 | DnfSack *sack = dnf_context_get_sack (ctx);
362 |
363 | g_autoptr(GPtrArray) deps = g_ptr_array_new_with_free_func ((GDestroyNotify)g_object_unref);
364 |
365 | for (guint i = 0; i < packages->len; ++i)
366 | {
367 | DnfPackage * pkg = g_ptr_array_index (packages, i);
368 | HyGoal goal = hy_goal_create (sack);
369 | hy_goal_install (goal, pkg);
370 | if (hy_goal_run_flags (goal, DNF_NONE) == 0)
371 | {
372 | ptr_array_extend_and_steal (deps, hy_goal_list_installs (goal, NULL));
373 | ptr_array_extend_and_steal (deps, hy_goal_list_upgrades (goal, NULL));
374 | }
375 | else
376 | {
377 | g_set_error_literal (error, DNF_ERROR, DNF_ERROR_NO_SOLUTION, "Error in resolve of packages");
378 | hy_goal_free (goal);
379 | return NULL;
380 | }
381 | hy_goal_free (goal);
382 | }
383 |
384 | return g_steal_pointer (&deps);
385 | }
386 |
387 | static gboolean
388 | dnf_command_download_run (DnfCommand *cmd,
389 | int argc,
390 | char *argv[],
391 | GOptionContext *opt_ctx,
392 | DnfContext *ctx,
393 | GError **error)
394 | {
395 | g_auto(GStrv) opt_key = NULL;
396 | g_autofree gchar *opt_archlist = NULL;
397 | gboolean opt_src = FALSE;
398 | gboolean opt_resolve = FALSE;
399 | gboolean opt_alldeps = FALSE;
400 | const GOptionEntry opts[] = {
401 | { "archlist", '\0', G_OPTION_FLAG_NONE, G_OPTION_ARG_STRING, &opt_archlist, "limit the query to packages of given architectures", "ARCH,..."},
402 | { "resolve", '\0', G_OPTION_FLAG_NONE, G_OPTION_ARG_NONE, &opt_resolve, "resolve and download needed dependencies", NULL },
403 | { "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 },
404 | { "source", '\0', G_OPTION_FLAG_NONE, G_OPTION_ARG_NONE, &opt_src, "download source packages", NULL },
405 | { G_OPTION_REMAINING, '\0', 0, G_OPTION_ARG_STRING_ARRAY, &opt_key, NULL, NULL },
406 | { NULL }
407 | };
408 | g_option_context_add_main_entries (opt_ctx, opts, NULL);
409 |
410 | if (!g_option_context_parse (opt_ctx, &argc, &argv, error))
411 | return FALSE;
412 |
413 | if (opt_key == NULL)
414 | {
415 | g_set_error_literal (error,
416 | G_IO_ERROR,
417 | G_IO_ERROR_FAILED,
418 | "Packages are not specified");
419 | return FALSE;
420 | }
421 |
422 | DnfRepoLoader * repo_loader = dnf_context_get_repo_loader (ctx);
423 | // If -source arg was passed, auto-enable the source repositories
424 | if (opt_src && !dnf_command_download_enablesourcerepos (ctx, repo_loader, error))
425 | {
426 | return FALSE;
427 | }
428 |
429 | DnfState * state = dnf_context_get_state (ctx);
430 | DnfContextSetupSackFlags sack_flags = !opt_resolve || opt_alldeps ? DNF_CONTEXT_SETUP_SACK_FLAG_SKIP_RPMDB
431 | : DNF_CONTEXT_SETUP_SACK_FLAG_NONE;
432 | if (!dnf_context_setup_sack_with_flags (ctx, state, sack_flags, error)) {
433 | return FALSE;
434 | }
435 |
436 | hy_autoquery HyQuery query = get_packages_query (ctx, opt_key, opt_src, opt_archlist);
437 |
438 | g_autoptr(GPtrArray) pkgs = hy_query_run (query);
439 |
440 | if (pkgs->len == 0)
441 | {
442 | g_print ("No packages matched.\n");
443 | return FALSE;
444 | }
445 |
446 | if (opt_resolve)
447 | {
448 | GPtrArray *deps = get_packages_deps (ctx, pkgs, error);
449 | if (!deps)
450 | {
451 | return FALSE;
452 | }
453 | ptr_array_extend_and_steal (pkgs, deps);
454 | }
455 |
456 | if (!download_packages (repo_loader, pkgs, state, error))
457 | {
458 | return FALSE;
459 | }
460 |
461 | g_print ("Complete.\n");
462 |
463 | return TRUE;
464 | }
465 |
466 | static void
467 | dnf_command_download_class_init (DnfCommandDownloadClass *klass)
468 | {
469 | }
470 |
471 | static void
472 | dnf_command_download_iface_init (DnfCommandInterface *iface)
473 | {
474 | iface->run = dnf_command_download_run;
475 | }
476 |
477 | static void
478 | dnf_command_download_class_finalize (DnfCommandDownloadClass *klass)
479 | {
480 | }
481 |
482 | G_MODULE_EXPORT void
483 | dnf_command_download_register_types (PeasObjectModule *module)
484 | {
485 | dnf_command_download_register_type (G_TYPE_MODULE (module));
486 |
487 | peas_object_module_register_extension_type (module,
488 | DNF_TYPE_COMMAND,
489 | DNF_TYPE_COMMAND_DOWNLOAD);
490 | }
491 |
--------------------------------------------------------------------------------
/dnf/dnf-main.c:
--------------------------------------------------------------------------------
1 | /* dnf-main.c
2 | *
3 | * Copyright © 2010-2015 Richard Hughes
4 | * Copyright © 2016 Colin Walters
5 | * Copyright © 2016-2017 Igor Gnatenko
6 | * Copyright © 2017-2021 Jaroslav Rohel
7 | *
8 | * This program is free software: you can redistribute it and/or modify
9 | * it under the terms of the GNU General Public License as published by
10 | * the Free Software Foundation, either version 2 of the License, or
11 | * (at your option) any later version.
12 | *
13 | * This program is distributed in the hope that it will be useful,
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 | * GNU General Public License for more details.
17 | *
18 | * You should have received a copy of the GNU General Public License
19 | * along with this program. If not, see .
20 | */
21 |
22 | #include
23 | #include
24 | #include
25 | #include
26 | #include
27 | #include
28 | #include "dnf-command.h"
29 | #include "dnf-utils.h"
30 |
31 | typedef enum { ARG_DEFAULT, ARG_FALSE, ARG_TRUE } BoolArgs;
32 |
33 | static BoolArgs opt_install_weak_deps = ARG_DEFAULT;
34 | static BoolArgs opt_allow_vendor_change = ARG_DEFAULT;
35 | static BoolArgs opt_keepcache = ARG_DEFAULT;
36 | static gboolean opt_no = FALSE;
37 | static gboolean opt_yes = FALSE;
38 | static gboolean opt_nodocs = FALSE;
39 | static gboolean opt_best = FALSE;
40 | static gboolean opt_nobest = FALSE;
41 | static gboolean opt_test = FALSE;
42 | static gboolean opt_refresh = FALSE;
43 | static gboolean show_help = FALSE;
44 | static gboolean dl_pkgs_printed = FALSE;
45 | static GSList *enable_disable_repos = NULL;
46 | static gboolean disable_plugins_loading = FALSE;
47 | static gboolean config_used = FALSE;
48 | static gboolean enable_disable_plugin_used = FALSE;
49 | static gboolean installroot_used = FALSE;
50 | static gboolean cachedir_used = FALSE;
51 | static gboolean reposdir_used = FALSE;
52 | static gboolean varsdir_used = FALSE;
53 |
54 | static gboolean
55 | process_global_option (const gchar *option_name,
56 | const gchar *value,
57 | gpointer data,
58 | GError **error)
59 | {
60 | g_autoptr(GError) local_error = NULL;
61 | DnfContext *ctx = DNF_CONTEXT (data);
62 |
63 | gboolean ret = TRUE;
64 | if (g_strcmp0 (option_name, "--config") == 0)
65 | {
66 | config_used = TRUE;
67 | dnf_context_set_config_file_path (value);
68 | }
69 | else if (g_strcmp0 (option_name, "--disablerepo") == 0)
70 | {
71 | enable_disable_repos = g_slist_append (enable_disable_repos, g_strconcat("d", value, NULL));
72 | }
73 | else if (g_strcmp0 (option_name, "--enablerepo") == 0)
74 | {
75 | enable_disable_repos = g_slist_append (enable_disable_repos, g_strconcat("e", value, NULL));
76 | }
77 | else if (g_strcmp0 (option_name, "--disableplugin") == 0)
78 | {
79 | g_auto(GStrv) patterns = g_strsplit (value, ",", -1);
80 | for (char **it = patterns; *it; ++it)
81 | dnf_context_disable_plugins (*it);
82 | enable_disable_plugin_used = TRUE;
83 | }
84 | else if (g_strcmp0 (option_name, "--enableplugin") == 0)
85 | {
86 | g_auto(GStrv) patterns = g_strsplit (value, ",", -1);
87 | for (char **it = patterns; *it; ++it)
88 | dnf_context_enable_plugins (*it);
89 | enable_disable_plugin_used = TRUE;
90 | }
91 | else if (g_strcmp0 (option_name, "--installroot") == 0)
92 | {
93 | installroot_used = TRUE;
94 | if (value[0] != '/')
95 | {
96 | local_error = g_error_new (G_OPTION_ERROR,
97 | G_OPTION_ERROR_BAD_VALUE,
98 | "Absolute path must be used");
99 | ret = FALSE;
100 | }
101 | else
102 | {
103 | dnf_context_set_install_root (ctx, value);
104 | }
105 | }
106 | else if (g_strcmp0 (option_name, "--releasever") == 0)
107 | {
108 | dnf_context_set_release_ver (ctx, value);
109 | }
110 | else if (g_strcmp0 (option_name, "--setopt") == 0)
111 | {
112 | g_auto(GStrv) setopt = g_strsplit (value, "=", 2);
113 | if (!setopt[0] || !setopt[1])
114 | {
115 | local_error = g_error_new (G_OPTION_ERROR,
116 | G_OPTION_ERROR_BAD_VALUE,
117 | "Missing value in: %s", value);
118 | ret = FALSE;
119 | }
120 | else if (strchr (setopt[0], '.'))
121 | { /* repository option, pass to libdnf */
122 | ret = dnf_conf_add_setopt (setopt[0], DNF_CONF_COMMANDLINE, setopt[1], &local_error);
123 | }
124 | else if (strcmp (setopt[0], "tsflags") == 0)
125 | {
126 | g_auto(GStrv) tsflags = g_strsplit (setopt[1], ",", -1);
127 | for (char **it = tsflags; *it; ++it)
128 | {
129 | if (strcmp (*it, "nodocs") == 0)
130 | opt_nodocs = TRUE;
131 | else if (strcmp (*it, "test") == 0)
132 | opt_test = TRUE;
133 | else
134 | {
135 | local_error = g_error_new (G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE,
136 | "Unknown tsflag: %s", *it);
137 | ret = FALSE;
138 | break;
139 | }
140 | }
141 | }
142 | else if (strcmp (setopt[0], "module_platform_id") == 0)
143 | {
144 | const char *module_platform_id = setopt[1];
145 | if (module_platform_id[0] != '\0')
146 | {
147 | dnf_context_set_platform_module (ctx, module_platform_id);
148 | }
149 | else
150 | {
151 | local_error = g_error_new (G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE,
152 | "Empty value in: %s", value);
153 | ret = FALSE;
154 | }
155 | }
156 | else if (strcmp (setopt[0], "cachedir") == 0)
157 | {
158 | cachedir_used = TRUE;
159 | const char *cachedir = setopt[1];
160 | if (cachedir[0] != '\0')
161 | {
162 | g_autofree gchar *metadatadir = g_build_path ("/", cachedir, "metadata", NULL);
163 | dnf_context_set_cache_dir (ctx, metadatadir);
164 | g_autofree gchar *solvdir = g_build_path ("/", cachedir, "solv", NULL);
165 | dnf_context_set_solv_dir (ctx, solvdir);
166 | g_autofree gchar *lockdir = g_build_path ("/", cachedir, "lock", NULL);
167 | dnf_context_set_lock_dir (ctx, lockdir);
168 | }
169 | else
170 | {
171 | local_error = g_error_new (G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE,
172 | "Empty value in: %s", value);
173 | ret = FALSE;
174 | }
175 | }
176 | else if (strcmp (setopt[0], "install_weak_deps") == 0)
177 | {
178 | const char *setopt_val = setopt[1];
179 | if (setopt_val[0] == '1' && setopt_val[1] == '\0')
180 | opt_install_weak_deps = ARG_TRUE;
181 | else if (setopt_val[0] == '0' && setopt_val[1] == '\0')
182 | opt_install_weak_deps = ARG_FALSE;
183 | else
184 | {
185 | local_error = g_error_new (G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE,
186 | "Invalid boolean value \"%s\" in: %s", setopt[1], value);
187 | ret = FALSE;
188 | }
189 | }
190 | else if (strcmp (setopt[0], "allow_vendor_change") == 0)
191 | {
192 | const char *setopt_val = setopt[1];
193 | if (setopt_val[0] == '1' && setopt_val[1] == '\0')
194 | opt_allow_vendor_change = ARG_TRUE;
195 | else if (setopt_val[0] == '0' && setopt_val[1] == '\0')
196 | opt_allow_vendor_change = ARG_FALSE;
197 | else
198 | {
199 | local_error = g_error_new (G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE,
200 | "Invalid boolean value \"%s\" in: %s", setopt[1], value);
201 | ret = FALSE;
202 | }
203 | }
204 | else if (strcmp (setopt[0], "keepcache") == 0)
205 | {
206 | const char *setopt_val = setopt[1];
207 | if (setopt_val[0] == '1' && setopt_val[1] == '\0')
208 | opt_keepcache = ARG_TRUE;
209 | else if (setopt_val[0] == '0' && setopt_val[1] == '\0')
210 | opt_keepcache = ARG_FALSE;
211 | else
212 | {
213 | local_error = g_error_new (G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE,
214 | "Invalid boolean value \"%s\" in: %s", setopt[1], value);
215 | ret = FALSE;
216 | }
217 | }
218 | else if (strcmp (setopt[0], "reposdir") == 0)
219 | {
220 | reposdir_used = TRUE;
221 | g_auto(GStrv) reposdir = g_strsplit (setopt[1], ",", -1);
222 | dnf_context_set_repos_dir (ctx, (const gchar * const *)reposdir);
223 | }
224 | else if (strcmp (setopt[0], "varsdir") == 0)
225 | {
226 | varsdir_used = TRUE;
227 | g_auto(GStrv) varsdir = g_strsplit (setopt[1], ",", -1);
228 | dnf_context_set_vars_dir (ctx, (const gchar * const *)varsdir);
229 | }
230 | else
231 | {
232 | local_error = g_error_new (G_OPTION_ERROR,
233 | G_OPTION_ERROR_BAD_VALUE,
234 | "Unable to handle: %s", value);
235 | ret = FALSE;
236 | }
237 | }
238 | else
239 | g_assert_not_reached ();
240 |
241 | if (local_error != NULL)
242 | g_set_error (error,
243 | G_OPTION_ERROR,
244 | G_OPTION_ERROR_BAD_VALUE,
245 | "(%s) %s", option_name, local_error->message);
246 |
247 | return ret;
248 | }
249 |
250 | static const GOptionEntry global_opts[] = {
251 | { "assumeno", '\0', G_OPTION_FLAG_NONE, G_OPTION_ARG_NONE, &opt_no, "Automatically answer no for all questions", NULL },
252 | { "assumeyes", 'y', G_OPTION_FLAG_NONE, G_OPTION_ARG_NONE, &opt_yes, "Automatically answer yes for all questions", NULL },
253 | { "best", '\0', G_OPTION_FLAG_NONE, G_OPTION_ARG_NONE, &opt_best, "Try the best available package versions in transactions", NULL },
254 | { "config", '\0', G_OPTION_FLAG_NONE, G_OPTION_ARG_CALLBACK, process_global_option, "Configuration file location", "" },
255 | { "disablerepo", '\0', G_OPTION_FLAG_NONE, G_OPTION_ARG_CALLBACK, process_global_option, "Disable repository by an id", "ID" },
256 | { "disableplugin", '\0', G_OPTION_FLAG_NONE, G_OPTION_ARG_CALLBACK, process_global_option, "Disable plugins by name", "name" },
257 | { "enablerepo", '\0', G_OPTION_FLAG_NONE, G_OPTION_ARG_CALLBACK, process_global_option, "Enable repository by an id", "ID" },
258 | { "enableplugin", '\0', G_OPTION_FLAG_NONE, G_OPTION_ARG_CALLBACK, process_global_option, "Enable plugins by name", "name" },
259 | { "nobest", '\0', G_OPTION_FLAG_NONE, G_OPTION_ARG_NONE, &opt_nobest, "Do not limit the transaction to the best candidates", NULL },
260 | { "installroot", '\0', G_OPTION_FLAG_NONE, G_OPTION_ARG_CALLBACK, process_global_option, "Set install root", "PATH" },
261 | { "nodocs", '\0', G_OPTION_FLAG_NONE, G_OPTION_ARG_NONE, &opt_nodocs, "Install packages without docs", NULL },
262 | { "noplugins", '\0', G_OPTION_FLAG_NONE, G_OPTION_ARG_NONE, &disable_plugins_loading, "Disable loading of plugins", NULL },
263 | { "refresh", '\0', G_OPTION_FLAG_NONE, G_OPTION_ARG_NONE, &opt_refresh, "Set metadata as expired before running the command", NULL },
264 | { "releasever", '\0', G_OPTION_FLAG_NONE, G_OPTION_ARG_CALLBACK, process_global_option, "Override the value of $releasever in config and repo files", "RELEASEVER" },
265 | { "setopt", '\0', G_OPTION_FLAG_NONE, G_OPTION_ARG_CALLBACK, process_global_option,
266 | "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=)", "