summaryrefslogtreecommitdiff
path: root/cli
diff options
context:
space:
mode:
Diffstat (limited to 'cli')
-rw-r--r--cli/command_line.cpp72
-rw-r--r--cli/configuration.cpp18
-rw-r--r--cli/main.cpp43
3 files changed, 105 insertions, 28 deletions
diff --git a/cli/command_line.cpp b/cli/command_line.cpp
index ff6c928..3e92a20 100644
--- a/cli/command_line.cpp
+++ b/cli/command_line.cpp
@@ -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();
+ }
+ }
}
diff --git a/cli/configuration.cpp b/cli/configuration.cpp
index 4ca36c1..e927c92 100644
--- a/cli/configuration.cpp
+++ b/cli/configuration.cpp
@@ -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();
diff --git a/cli/main.cpp b/cli/main.cpp
index da0d1b8..4964498 100644
--- a/cli/main.cpp
+++ b/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;
}