1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144
|
// Copyright Contributors to the DNF5 project.
// SPDX-License-Identifier: LGPL-2.1-or-later
#include "manifest.hpp"
#include <libdnf5/rpm/package_query.hpp>
#include <libdnf5/utils/bgettext/bgettext-lib.h>
#include <libdnf5/utils/bgettext/bgettext-mark-domain.h>
#include <libpkgmanifest/input/parser.hpp>
#include <libpkgmanifest/manifest/manifest.hpp>
#include <libpkgmanifest/manifest/serializer.hpp>
#include <utils/string.hpp>
#include <regex>
using namespace libdnf5::cli;
namespace dnf5 {
void ManifestResolveCommand::set_argument_parser() {
ManifestSubcommand::set_argument_parser();
auto & ctx = get_context();
auto & parser = ctx.get_argument_parser();
auto & cmd = *get_argument_parser_command();
cmd.set_description(_("Generate a new manifest file using the provided input file"));
input_path_option = dynamic_cast<libdnf5::OptionPath *>(
parser.add_init_value(std::make_unique<libdnf5::OptionPath>(DEFAULT_INPUT_FILENAME)));
auto * input_arg = parser.add_new_named_arg("input");
input_arg->set_long_name("input");
input_arg->set_description(_("Input file path"));
input_arg->set_has_value(true);
input_arg->link_value(input_path_option);
cmd.register_named_arg(input_arg);
use_system_option =
dynamic_cast<libdnf5::OptionBool *>(parser.add_init_value(std::make_unique<libdnf5::OptionBool>(false)));
auto * use_system_arg = parser.add_new_named_arg("use-system");
use_system_arg->set_long_name("use-system");
use_system_arg->set_description(_("Use installed packages for resolving dependencies"));
use_system_arg->set_const_value("true");
use_system_arg->link_value(use_system_option);
cmd.register_named_arg(use_system_arg);
use_host_repos_option =
dynamic_cast<libdnf5::OptionBool *>(parser.add_init_value(std::make_unique<libdnf5::OptionBool>(false)));
auto * use_host_repos_arg = parser.add_new_named_arg("use-host-repos");
use_host_repos_arg->set_long_name("use-host-repos");
use_host_repos_arg->set_description(_("Use host repositories for resolving dependencies"));
use_host_repos_arg->set_const_value("true");
use_host_repos_arg->link_value(use_host_repos_option);
cmd.register_named_arg(use_host_repos_arg);
per_arch_option =
dynamic_cast<libdnf5::OptionBool *>(parser.add_init_value(std::make_unique<libdnf5::OptionBool>(false)));
auto * per_arch_arg = parser.add_new_named_arg("per-arch");
per_arch_arg->set_long_name("per-arch");
per_arch_arg->set_description(_("Separate packages by basearch into individual manifest files"));
per_arch_arg->set_const_value("true");
per_arch_arg->link_value(per_arch_option);
cmd.register_named_arg(per_arch_arg);
srpm_option =
dynamic_cast<libdnf5::OptionBool *>(parser.add_init_value(std::make_unique<libdnf5::OptionBool>(false)));
auto * srpm_arg = parser.add_new_named_arg("srpm");
srpm_arg->set_long_name("srpm");
srpm_arg->set_description(_("Include source packages in consideration"));
srpm_arg->set_const_value("true");
srpm_arg->link_value(srpm_option);
cmd.register_named_arg(srpm_arg);
}
void ManifestResolveCommand::configure() {
auto & ctx = get_context();
input = libpkgmanifest::input::Parser().parse_prototype(input_path_option->get_value());
arches = input->get_archs();
ctx.set_load_available_repos(Context::LoadAvailableRepos::NONE);
}
void ManifestResolveCommand::populate_manifest(
libpkgmanifest::manifest::Manifest & manifest, const std::string & arch, const bool multiarch) {
auto & ctx = get_context();
auto private_base = create_base_for_arch(arch);
auto base = private_base->get_weak_ptr();
// Load repositories
auto repo_sack = base->get_repo_sack();
create_repos(*base, input->get_repositories());
if (use_host_repos_option->get_value()) {
load_host_repos(ctx, *base);
}
if (srpm_option->get_value()) {
repo_sack->enable_source_repos();
}
set_repo_callbacks(*base);
get_context().print_info(libdnf5::utils::sformat(_("Updating and loading repositories for arch {}:"), arch));
if (use_system_option->get_value()) {
repo_sack->load_repos();
} else {
repo_sack->load_repos(libdnf5::repo::Repo::Type::AVAILABLE);
}
get_context().print_info(_("Repositories loaded."));
// Resolve packages
libdnf5::Goal goal{base};
goal.set_allow_erasing(input->get_options().get_allow_erasing());
for (const auto & spec : input->get_packages().get_installs()) {
goal.add_rpm_install(spec);
}
for (const auto & spec : input->get_packages().get_reinstalls()) {
goal.add_rpm_reinstall(spec);
}
// Populate manifest
const auto & resolved_pkgs = resolve_goal(goal, *base, srpm_option->get_value());
add_pkgs_to_manifest(manifest, *base, resolved_pkgs, arch, multiarch);
}
void ManifestResolveCommand::run() {
libpkgmanifest::manifest::Serializer serializer;
if (per_arch_option->get_value()) {
for (const auto & arch : arches) {
libpkgmanifest::manifest::Manifest manifest;
populate_manifest(manifest, arch, false);
std::string path{manifest_path_option->get_value()};
path = std::regex_replace(path, std::regex("\\.yaml$"), fmt::format(".{}.yaml", arch));
serializer.serialize(manifest, path);
}
} else {
libpkgmanifest::manifest::Manifest manifest;
for (const auto & arch : arches) {
populate_manifest(manifest, arch, arches.size() > 1);
}
serializer.serialize(manifest, manifest_path_option->get_value());
}
}
} // namespace dnf5
|