Skip to content

Commit

Permalink
modules: Add module info command
Browse files Browse the repository at this point in the history
  • Loading branch information
pkratoch committed Dec 5, 2023
1 parent 6f2ab62 commit c90efda
Show file tree
Hide file tree
Showing 7 changed files with 171 additions and 13 deletions.
2 changes: 1 addition & 1 deletion dnf5/commands/module/module.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ void ModuleCommand::register_subcommands() {
query_commands_group->set_header("Query Commands:");
cmd.register_group(query_commands_group);
register_subcommand(std::make_unique<ModuleListCommand>(get_context()), query_commands_group);
// register_subcommand(std::make_unique<ModuleInfoCommand>(get_context()), query_commands_group);
register_subcommand(std::make_unique<ModuleInfoCommand>(get_context()), query_commands_group);
// register_subcommand(std::make_unique<ModuleProvidesCommand>(get_context()), query_commands_group);

// stream management commands
Expand Down
10 changes: 5 additions & 5 deletions dnf5/commands/module/module_info.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,13 @@ along with libdnf. If not, see <https://www.gnu.org/licenses/>.

#include "module_info.hpp"

#include <libdnf5-cli/output/moduleinfo.hpp>
#include <libdnf5/module/module_query.hpp>

namespace dnf5 {

void ModuleInfoCommand::set_argument_parser() {
auto & cmd = *get_argument_parser_command();
cmd.set_description("Print details about module streams");
void ModuleInfoCommand::print(const libdnf5::module::ModuleQuery & query) {
libdnf5::cli::output::print_moduleinfo_table(query.list());
}

void ModuleInfoCommand::run() {}

} // namespace dnf5
12 changes: 8 additions & 4 deletions dnf5/commands/module/module_info.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,19 @@ along with libdnf. If not, see <https://www.gnu.org/licenses/>.
#ifndef DNF5_COMMANDS_MODULE_MODULE_INFO_HPP
#define DNF5_COMMANDS_MODULE_MODULE_INFO_HPP

#include "module_list.hpp"

#include <dnf5/context.hpp>
#include <libdnf5/module/module_query.hpp>

namespace dnf5 {

class ModuleInfoCommand : public Command {
class ModuleInfoCommand : public ModuleListCommand {
public:
explicit ModuleInfoCommand(Context & context) : Command(context, "info") {}
void set_argument_parser() override;
void run() override;
explicit ModuleInfoCommand(Context & context) : ModuleListCommand(context, "info") {}

private:
void print(const libdnf5::module::ModuleQuery & query) override;
};

} // namespace dnf5
Expand Down
26 changes: 24 additions & 2 deletions dnf5/commands/module/module_list.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ along with libdnf. If not, see <https://www.gnu.org/licenses/>.

#include <libdnf5-cli/output/modulelist.hpp>
#include <libdnf5/module/module_query.hpp>
#include <libdnf5/utils/bgettext/bgettext-lib.h>

#include <iostream>

namespace dnf5 {

Expand All @@ -44,15 +47,22 @@ void ModuleListCommand::configure() {
void ModuleListCommand::run() {
libdnf5::module::ModuleQuery query(get_context().base, true);
auto module_specs_str = module_specs->get_value();
std::set<std::string> unmatched_module_spec;

if (module_specs_str.size() > 0) {
for (const auto & module_spec : module_specs_str) {
bool module_spec_matched = false;
for (const auto & nsvcap : libdnf5::module::Nsvcap::parse(module_spec)) {
libdnf5::module::ModuleQuery nsvcap_query(get_context().base, false);
nsvcap_query.filter_nsvca(nsvcap, libdnf5::sack::QueryCmp::GLOB);
if (!nsvcap_query.empty()) {
query |= nsvcap_query;
module_spec_matched = true;
}
}
if (!module_spec_matched) {
unmatched_module_spec.insert(module_spec);
}
}
} else {
query = libdnf5::module::ModuleQuery(get_context().base, false);
Expand All @@ -64,8 +74,20 @@ void ModuleListCommand::run() {
query.filter_disabled();
}

output::print_modulelist_table(query.list());
output::print_modulelist_table_hint();
print(query);
if (!query.empty()) {
output::print_modulelist_table_hint();
}

if (!unmatched_module_spec.empty()) {
for (auto const & module_spec : unmatched_module_spec) {
std::cerr << libdnf5::utils::sformat(_("No matches found for \"{}\"."), module_spec) << std::endl;
}
}
}

void ModuleListCommand::print(const libdnf5::module::ModuleQuery & query) {
libdnf5::cli::output::print_modulelist_table(query.list());
}

} // namespace dnf5
6 changes: 6 additions & 0 deletions dnf5/commands/module/module_list.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ along with libdnf. If not, see <https://www.gnu.org/licenses/>.
#include "arguments.hpp"

#include <dnf5/context.hpp>
#include <libdnf5/module/module_query.hpp>

namespace dnf5 {

Expand All @@ -33,10 +34,15 @@ class ModuleListCommand : public Command {
void configure() override;
void run() override;

protected:
ModuleListCommand(Context & context, const std::string & name) : Command(context, name) {}

private:
std::unique_ptr<ModuleEnabledOption> enabled{nullptr};
std::unique_ptr<ModuleDisabledOption> disabled{nullptr};
std::unique_ptr<ModuleSpecArguments> module_specs{nullptr};

virtual void print(const libdnf5::module::ModuleQuery & query);
};

} // namespace dnf5
Expand Down
123 changes: 123 additions & 0 deletions include/libdnf5-cli/output/moduleinfo.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
/*
Copyright Contributors to the libdnf project.
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 Lesser General Public License as published by
the Free Software Foundation, either version 2.1 of the License, or
(at your option) any later version.
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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with libdnf. If not, see <https://www.gnu.org/licenses/>.
*/


#ifndef LIBDNF_CLI_OUTPUT_MODULEINFO_HPP
#define LIBDNF_CLI_OUTPUT_MODULEINFO_HPP

#include "key_value_table.hpp"
#include "utils/string.hpp"

#include "libdnf5-cli/tty.hpp"

#include <libdnf5/module/module_item.hpp>
#include <libdnf5/module/module_sack.hpp>
#include <libsmartcols/libsmartcols.h>

#include <set>
#include <string>

namespace libdnf5::cli::output {


class ModuleInfo : public KeyValueTable {
public:
template <typename ModuleItem>
void add_module_item(ModuleItem & module_item);

private:
void add_multiline_value(const char * key, const std::vector<std::string> & multiline_value);
};


void ModuleInfo::add_multiline_value(const char * key, const std::vector<std::string> & values) {
if (values.empty()) {
add_line(key, "");
return;
}
auto it = values.begin();
// put the first item at the same line as description
add_line(key, it->c_str());
it++;

// put the remaining items on separate lines
for (; it != values.end(); it++) {
add_line("", it->c_str());
}
}

std::vector<std::string> dependency_strings(std::vector<module::ModuleDependency> dependencies) {
std::vector<std::string> dependency_strings;
for (module::ModuleDependency & dependency : dependencies) {
dependency_strings.push_back(dependency.to_string());
}
return dependency_strings;
}

template <typename ModuleItem>
void ModuleInfo::add_module_item(ModuleItem & module_item) {
std::vector<std::string> profile_names;
for (const module::ModuleProfile & profile : module_item.get_profiles()) {
profile_names.push_back(profile.get_name() + (profile.is_default() ? " [d]" : ""));
}

std::vector<std::string> dependency_strings;
for (module::ModuleDependency & dependency : module_item.get_module_dependencies()) {
dependency_strings.push_back(dependency.to_string());
}

// Get stream string (append [d] and [e] or [x] if needed)
const module::ModuleStatus & status = module_item.get_status();
std::string stream_string = module_item.is_default() ? "[d]" : "";
if (status == module::ModuleStatus::ENABLED) {
stream_string.append("[e]");
} else if (status == module::ModuleStatus::DISABLED) {
stream_string.append("[x]");
}
stream_string = stream_string.empty() ? module_item.get_stream() : module_item.get_stream() + " " + stream_string;

add_line("Name", module_item.get_name());
add_line("Stream", stream_string);
add_line("Version", module_item.get_version_str());
add_line("Context", module_item.get_context());
add_line("Architecture", module_item.get_arch());
add_line("Profiles", utils::string::join(profile_names, ", "));
add_line("Default profiles", utils::string::join(module_item.get_default_profiles(), ", "));
add_line("Repo", module_item.get_repo_id());
add_line("Summary", module_item.get_summary());
add_line("Description", module_item.get_description());
add_multiline_value("Requires", dependency_strings);
add_multiline_value("Artifacts", module_item.get_artifacts());
}


template <class Query>
void print_moduleinfo_table(Query & module_list) {
for (auto & module_item : module_list) {
libdnf5::cli::output::ModuleInfo module_info;
module_info.add_module_item(module_item);
module_info.print();
std::cout << std::endl;
}
}


} // namespace libdnf5::cli::output

#endif // LIBDNF_CLI_OUTPUT_MODULEINFO_HPP
5 changes: 4 additions & 1 deletion include/libdnf5-cli/output/modulelist.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ namespace libdnf5::cli::output {
enum { COL_MODULE_NAME, COL_MODULE_STREAM, COL_MODULE_PROFILES, COL_MODULE_SUMMARY };


const std::string MODULELIST_TABLE_HINT = _("\nHint: [d]efault, [e]nabled, [x]disabled, [i]nstalled");
const std::string MODULELIST_TABLE_HINT = _("Hint: [d]efault, [e]nabled, [x]disabled, [i]nstalled");


static struct libscols_table * create_modulelist_table() {
Expand Down Expand Up @@ -108,6 +108,9 @@ void print_modulelist_table(Query & module_list) {
}
scols_sort_table(table, scols_table_get_column(table, COL_MODULE_NAME));
scols_print_table(table);
if (!module_list.empty()) {
std::cout << std::endl;
}
scols_unref_table(table);
}

Expand Down

0 comments on commit c90efda

Please sign in to comment.