Move more command line parsing into a module
Some checks failed
Test / build (push) Failing after 13s
Some checks failed
Test / build (push) Failing after 13s
This commit is contained in:
@@ -30,6 +30,25 @@ namespace katja
|
||||
const std::vector<std::string> arguments;
|
||||
};
|
||||
|
||||
export struct search_command
|
||||
{
|
||||
const std::string needle;
|
||||
};
|
||||
|
||||
export struct updates_command
|
||||
{
|
||||
};
|
||||
|
||||
export struct help_command
|
||||
{
|
||||
};
|
||||
|
||||
export using subcommand = std::variant<
|
||||
search_command,
|
||||
updates_command,
|
||||
help_command
|
||||
>;
|
||||
|
||||
export class invalid_command_error : public std::runtime_error
|
||||
{
|
||||
const std::string command;
|
||||
@@ -40,13 +59,26 @@ namespace katja
|
||||
{
|
||||
}
|
||||
|
||||
invalid_command_error(const std::string& invalid_command)
|
||||
explicit invalid_command_error(const std::string& invalid_command)
|
||||
: command{ invalid_command },
|
||||
std::runtime_error("Unknown command given on the command line.")
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
export class command_line_error : public std::runtime_error
|
||||
{
|
||||
boost::program_options::options_description description;
|
||||
|
||||
public:
|
||||
command_line_error(const std::string& message,
|
||||
boost::program_options::options_description&& description)
|
||||
: description(std::move(description)),
|
||||
std::runtime_error(message)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
export command_line parse_command_line(int argc, const char **argv)
|
||||
{
|
||||
if (argc == 1)
|
||||
@@ -70,4 +102,42 @@ namespace katja
|
||||
}
|
||||
throw invalid_command_error(argv[1]);
|
||||
}
|
||||
|
||||
search_command parse_search_command(const std::vector<std::string>& arguments)
|
||||
{
|
||||
boost::program_options::options_description search_description("Search packages");
|
||||
search_description
|
||||
.add_options()("name", "Find packages by name");
|
||||
|
||||
boost::program_options::positional_options_description positional_arguments;
|
||||
positional_arguments.add("name", 1);
|
||||
|
||||
boost::program_options::variables_map option_map;
|
||||
auto command_parser = boost::program_options::command_line_parser(arguments)
|
||||
.options(search_description).positional(positional_arguments);
|
||||
boost::program_options::store(command_parser.run(), option_map);
|
||||
boost::program_options::notify(option_map);
|
||||
|
||||
if (!option_map.count("name"))
|
||||
{
|
||||
throw command_line_error("Search string wasn't specified.",
|
||||
std::move(search_description));
|
||||
}
|
||||
return search_command{ option_map["name"].as<std::string>() };
|
||||
}
|
||||
|
||||
export subcommand parse_subcommand(const command_line& subcommand_line)
|
||||
{
|
||||
switch (subcommand_line.type)
|
||||
{
|
||||
case command::updates:
|
||||
return updates_command();
|
||||
case command::search:
|
||||
return parse_search_command(subcommand_line.arguments);
|
||||
case command::help:
|
||||
return help_command();
|
||||
default:
|
||||
std::unreachable();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,7 +26,13 @@ export namespace katja
|
||||
class configuration
|
||||
{
|
||||
public:
|
||||
using repositories_t = std::forward_list<std::pair<std::string, repository_configuration>>;
|
||||
using value_type = std::pair<std::string, repository_configuration>;
|
||||
using reference_type = value_type&;
|
||||
using const_reference_type = const value_type&;
|
||||
|
||||
using repositories_t = std::forward_list<value_type>;
|
||||
using size_type = repositories_t::size_type;
|
||||
using difference_type = repositories_t::difference_type;
|
||||
|
||||
private:
|
||||
repositories_t repositories;
|
||||
@@ -47,6 +53,16 @@ export namespace katja
|
||||
return this->repositories.end();
|
||||
}
|
||||
|
||||
repositories_t::const_iterator begin() const
|
||||
{
|
||||
return this->repositories.begin();
|
||||
}
|
||||
|
||||
repositories_t::const_iterator end() const
|
||||
{
|
||||
return this->repositories.end();
|
||||
}
|
||||
|
||||
repositories_t::const_iterator cbegin()
|
||||
{
|
||||
return this->repositories.cbegin();
|
||||
|
||||
43
cli/main.cpp
43
cli/main.cpp
@@ -6,6 +6,7 @@
|
||||
#include <filesystem>
|
||||
#include <memory>
|
||||
#include <iostream>
|
||||
#include <variant>
|
||||
|
||||
#include <boost/program_options.hpp>
|
||||
|
||||
@@ -36,14 +37,13 @@ static void search_names(std::shared_ptr<katja::repository> repository, const st
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, const char **argv)
|
||||
static void handle_subcommand(const katja::configuration& configuration,
|
||||
const katja::subcommand& command)
|
||||
{
|
||||
katja::configuration configuration = katja::read_configuration("katja.toml");
|
||||
katja::package_database installed_database = katja::read_installed_database();
|
||||
|
||||
katja::command_line command_line = katja::parse_command_line(argc, argv);
|
||||
if (command_line.type == katja::command::updates)
|
||||
if (std::holds_alternative<katja::updates_command>(command))
|
||||
{
|
||||
katja::package_database installed_database = katja::read_installed_database();
|
||||
|
||||
for (const auto& [repository_name, repository_configuration] : configuration)
|
||||
{
|
||||
std::filesystem::path slackbuild_repository{ repository_configuration.path };
|
||||
@@ -52,34 +52,25 @@ int main(int argc, const char **argv)
|
||||
get_updates(repository, std::move(installed_database));
|
||||
}
|
||||
}
|
||||
else if (command_line.type == katja::command::search)
|
||||
else if (std::holds_alternative<katja::search_command>(command))
|
||||
{
|
||||
boost::program_options::options_description search_description("Search packages");
|
||||
search_description
|
||||
.add_options()("name", "Find packages by name");
|
||||
|
||||
boost::program_options::positional_options_description positional_arguments;
|
||||
positional_arguments.add("name", 1);
|
||||
|
||||
boost::program_options::variables_map option_map;
|
||||
auto command_parser = boost::program_options::command_line_parser(command_line.arguments)
|
||||
.options(search_description).positional(positional_arguments);
|
||||
boost::program_options::store(command_parser.run(), option_map);
|
||||
boost::program_options::notify(option_map);
|
||||
|
||||
if (!option_map.count("name"))
|
||||
{
|
||||
std::cerr << search_description;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
for (const auto& [repository_name, repository_configuration] : configuration)
|
||||
{
|
||||
std::filesystem::path slackbuild_repository{ repository_configuration.path };
|
||||
auto repository = std::make_shared<katja::sbo_repository>(slackbuild_repository);
|
||||
|
||||
search_names(repository, option_map["name"].as<std::string>());
|
||||
search_names(repository, std::get<katja::search_command>(command).needle);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, const char **argv)
|
||||
{
|
||||
katja::configuration configuration = katja::read_configuration("katja.toml");
|
||||
katja::command_line command_line = katja::parse_command_line(argc, argv);
|
||||
katja::subcommand subcommand = katja::parse_subcommand(command_line);
|
||||
|
||||
handle_subcommand(configuration, subcommand);
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user