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
|
// Copyright Contributors to the DNF5 project.
// Copyright Contributors to the libdnf project.
// SPDX-License-Identifier: GPL-2.0-or-later
//
// This file is part of libdnf: https://github.com/rpm-software-management/libdnf/
//
// Libdnf is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 2 of the License, or
// (at your option) any later version.
//
// Libdnf is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with libdnf. If not, see <https://www.gnu.org/licenses/>.
#include "setvar.hpp"
#include "shared.hpp"
#include <libdnf5/utils/bgettext/bgettext-mark-domain.h>
#include <fstream>
namespace dnf5 {
using namespace libdnf5;
void ConfigManagerSetVarCommand::set_argument_parser() {
auto & ctx = get_context();
auto & parser = ctx.get_argument_parser();
auto & cmd = *get_argument_parser_command();
cmd.set_description("Set variables");
auto vars_vals =
parser.add_new_positional_arg("varvals", cli::ArgumentParser::PositionalArg::AT_LEAST_ONE, nullptr, nullptr);
vars_vals->set_description("List of variables with values. Format: \"variable=value\"");
vars_vals->set_parse_hook_func(
[this, &ctx]([[maybe_unused]] cli::ArgumentParser::PositionalArg * arg, int argc, const char * const argv[]) {
for (int i = 0; i < argc; ++i) {
auto value = argv[i];
const auto * const val = strchr(value + 1, '=');
if (!val) {
throw cli::ArgumentParserError(
M_("{}: Badly formatted argument value \"{}\""), std::string{"varval"}, std::string{value});
}
std::string var_name{value, val};
std::string var_value{val + 1};
check_variable_name(var_name);
// Test that the variable is not read-only.
auto vars = ctx.get_base().get_vars();
if (vars->is_read_only(var_name)) {
throw ConfigManagerError(
M_("Cannot set \"{}\": Variable \"{}\" is read-only"), std::string{value}, var_name);
}
// Save the variable for later writing to a file.
const auto [it, inserted] = setvars.insert({var_name, var_value});
if (!inserted) {
if (it->second != var_value) {
throw ConfigManagerError(
M_("Sets the \"{}\" variable again with a different value: \"{}\" != \"{}\""),
var_name,
it->second,
var_value);
}
}
}
return true;
});
cmd.register_positional_arg(vars_vals);
auto create_missing_dirs_opt = parser.add_new_named_arg("create-missing-dir");
create_missing_dirs_opt->set_long_name("create-missing-dir");
create_missing_dirs_opt->set_description("Allow to create missing directories");
create_missing_dirs_opt->set_has_value(false);
create_missing_dirs_opt->set_parse_hook_func([this](cli::ArgumentParser::NamedArg *, const char *, const char *) {
create_missing_dirs = true;
return true;
});
cmd.register_named_arg(create_missing_dirs_opt);
}
void ConfigManagerSetVarCommand::configure() {
auto & ctx = get_context();
if (!setvars.empty()) {
const auto & vars_dir = get_last_vars_dir_path(ctx.get_base().get_config());
if (vars_dir.empty()) {
throw ConfigManagerError(M_("Missing path to vars directory"));
}
resolve_missing_dir(vars_dir, create_missing_dirs);
for (const auto & [name, value] : setvars) {
const auto filepath = vars_dir / name;
std::ofstream file;
file.exceptions(std::ofstream::failbit | std::ofstream::badbit);
try {
file.open(filepath, std::ios_base::trunc | std::ios_base::binary);
file << value;
} catch (const std::ios_base::failure & e) {
throw ConfigManagerError(
M_("Cannot write variable to file \"{}\": {}"), filepath.native(), std::string{e.what()});
}
set_file_permissions(filepath);
}
}
}
} // namespace dnf5
|