From 79bdca04e2cc9e13bbfa1cac7619d5e4a56ff0bd Mon Sep 17 00:00:00 2001 From: Eugen Wissner Date: Mon, 17 Apr 2023 15:05:20 +0200 Subject: [PATCH] Remove SBo differ experiment --- CMakeLists.txt | 43 --------- src/command.cpp | 118 ----------------------- src/command.h | 56 ----------- src/component.cpp | 76 --------------- src/component.h | 20 ---- src/config.h | 3 - src/main.cpp | 22 ----- src/package.cpp | 106 --------------------- src/package.h | 50 ---------- src/sbo.cpp | 232 ---------------------------------------------- src/sbo.h | 73 --------------- 11 files changed, 799 deletions(-) delete mode 100644 CMakeLists.txt delete mode 100644 src/command.cpp delete mode 100644 src/command.h delete mode 100644 src/component.cpp delete mode 100644 src/component.h delete mode 100644 src/config.h delete mode 100644 src/main.cpp delete mode 100644 src/package.cpp delete mode 100644 src/package.h delete mode 100644 src/sbo.cpp delete mode 100644 src/sbo.h diff --git a/CMakeLists.txt b/CMakeLists.txt deleted file mode 100644 index cb5e349..0000000 --- a/CMakeLists.txt +++ /dev/null @@ -1,43 +0,0 @@ -cmake_minimum_required(VERSION 3.21) -project(katja - VERSION 1.0 -) - -include(FindBoost) -include(FetchContent) - -set(CMAKE_CXX_STANDARD 17) -set(CMAKE_CXX_STANDARD_REQUIRED True) - -add_executable(katja - src/component.h - src/command.h - src/package.h - src/sbo.h - src/component.cpp - src/command.cpp - src/package.cpp - src/sbo.cpp - src/main.cpp -) -target_include_directories(katja PRIVATE src) - -find_package(Boost 1.78.0 REQUIRED COMPONENTS filesystem) -include_directories(${Boost_INCLUDE_DIRS}) - -FetchContent_Declare(ftxui - GIT_REPOSITORY https://github.com/ArthurSonzogni/ftxui - GIT_TAG v4.0.0 -) -FetchContent_GetProperties(ftxui) -if(NOT ftxui_POPULATED) - FetchContent_Populate(ftxui) - add_subdirectory(${ftxui_SOURCE_DIR} ${ftxui_BINARY_DIR} EXCLUDE_FROM_ALL) -endif() - -target_link_libraries(katja - PRIVATE Boost::filesystem - PRIVATE ftxui::screen - PRIVATE ftxui::dom - PRIVATE ftxui::component -) diff --git a/src/command.cpp b/src/command.cpp deleted file mode 100644 index 9443372..0000000 --- a/src/command.cpp +++ /dev/null @@ -1,118 +0,0 @@ -#include "command.h" -#include -#include "config.h" -#include "sbo.h" -#include -#include -#include "component.h" - -namespace katja -{ - void list::execute() const - { - sbo sbo_repository; - std::unordered_map packages = katja::read_package_database(); - std::vector> table_data; - std::set installed_packages; - std::unordered_map package_database = read_package_database(); - - for (const auto& package : package_database) - { - std::string tag = package.second.tag(); - if (tag.find("_SBo") == std::string::npos) - { - continue; - } - installed_packages.insert(package.first); - } - for (const auto& package : sbo_repository.list(installed_packages)) - { - if (package_database.find(package.first)->second.version() == package.second.version()) - { - continue; - } - table_data.push_back({ - package.second.name(), - package.second.version(), - package.second.tag(), - package.second.architecture(), - "SBo" - }); - } - - auto screen = ftxui::ScreenInteractive::Fullscreen(); - PackageList list_component{ - { "Package name", "Version", "Tag", "Architecture", "Repository" }, - table_data - }; - - screen.Loop(std::make_shared(list_component)); - } - - void help::execute() const - { - std::cout << "Usage:\n" - "\tkatja {list|update|help} [OPTIONS]\n\n"; - } - - void update::execute() const - { - sbo().refresh(); - } - - command_exception::command_exception(const command_exception_t exception_type, - std::vector failed_arguments) noexcept - : m_exception_type(exception_type), m_failed_arguments(failed_arguments) - { - } - - const char *command_exception::what() const noexcept - { - switch (m_exception_type) - { - case command_exception_t::no_command: - return "No command specified."; - case command_exception_t::too_many_arguments: - return "Too many arguments given."; - case command_exception_t::unknown_command: - return "Unknown command."; - } - assert(false); - } - - const std::vector& command_exception::failed_arguments() const noexcept - { - return m_failed_arguments; - } - - std::unique_ptr parse_command_line(int argc, char **argv) - { - if (argc > 2) - { - std::vector failed_arguments; - - for (std::size_t i = 2; i < argc; ++i) - { - failed_arguments.push_back(argv[i]); - } - throw command_exception(command_exception_t::unknown_command); - } - else if (argc < 2) - { - throw command_exception(command_exception_t::no_command); - } - if (strcmp(argv[1], "list") == 0) - { - return std::make_unique(); - } - else if (strcmp(argv[1], "update") == 0) - { - return std::make_unique(); - } - else if (strcmp(argv[1], "help") == 0) - { - return std::make_unique(); - } - throw command_exception(command_exception_t::unknown_command, { argv[1] }); - } -} diff --git a/src/command.h b/src/command.h deleted file mode 100644 index b168f04..0000000 --- a/src/command.h +++ /dev/null @@ -1,56 +0,0 @@ -#pragma once - -#include -#include -#include -#include -#include "package.h" - -namespace katja -{ - class command - { - public: - virtual void execute() const = 0; - }; - - class list final : public command - { - public: - void execute() const override; - }; - - class help final : public command - { - public: - void execute() const override; - }; - - class update final : public command - { - public: - void execute() const override; - }; - - enum class command_exception_t - { - no_command, - too_many_arguments, - unknown_command, - }; - - class command_exception final : public std::exception - { - command_exception_t m_exception_type; - std::vector m_failed_arguments; - - public: - explicit command_exception(const command_exception_t exception_type, - std::vector failed_arguments = {}) noexcept; - - const char *what() const noexcept override; - const std::vector& failed_arguments() const noexcept; - }; - - std::unique_ptr parse_command_line(int argc, char **argv); -} diff --git a/src/component.cpp b/src/component.cpp deleted file mode 100644 index 9247a1d..0000000 --- a/src/component.cpp +++ /dev/null @@ -1,76 +0,0 @@ -#include -#include "component.h" - -namespace katja -{ - PackageList::PackageList(const std::vector& header, const std::vector>& data) - : m_data(data), m_header(header) - { - } - - ftxui::Element PackageList::Render() - { - std::vector> data{ m_header }; - - std::size_t dimy = ftxui::ScreenInteractive::Active()->dimy(); - if (dimy == 0) - { - dimy = ftxui::Terminal::Size().dimy; - } - if (dimy > 4) // 4 = headers and borders. - { - std::size_t row_count = std::min(m_data.size() - top_line, dimy - 4 + top_line); - - std::copy(m_data.cbegin() + top_line, m_data.cbegin() + row_count, std::back_inserter(data)); - } - ftxui::Table table{ data }; - table.SelectAll().Border(ftxui::LIGHT); - - // Add border around the first column. - table.SelectColumn(0).Border(ftxui::LIGHT); - - // Make first row bold with a double border. - table.SelectRow(0).Decorate(ftxui::bold); - table.SelectRow(0).SeparatorVertical(ftxui::LIGHT); - table.SelectRow(0).Border(ftxui::DOUBLE); - - // Align right the "Release date" column. - table.SelectColumn(2).DecorateCells(ftxui::align_right); - - // Select row from the second to the last. - auto content = table.SelectRows(1, -1); - // Alternate in between 3 colors. - content.DecorateCellsAlternateRow(color(ftxui::Color::Blue), 3, 0); - content.DecorateCellsAlternateRow(color(ftxui::Color::Cyan), 3, 1); - content.DecorateCellsAlternateRow(color(ftxui::Color::White), 3, 2); - - return table.Render(); - } - - bool PackageList::OnEvent(ftxui::Event event) - { - if (event == ftxui::Event::Character('q') || event == ftxui::Event::Escape) - { - event.screen_->ExitLoopClosure()(); - } - else if (event == ftxui::Event::Character('j') || event == ftxui::Event::ArrowDown) - { - if (m_data.size() > 0 && top_line < (m_data.size() - 1)) - { - ++top_line; - } - } - else if (event == ftxui::Event::Character('k') || event == ftxui::Event::ArrowUp) - { - if (top_line > 0) - { - --top_line; - } - } - else - { - return false; - } - return true; - } -} diff --git a/src/component.h b/src/component.h deleted file mode 100644 index d1a587a..0000000 --- a/src/component.h +++ /dev/null @@ -1,20 +0,0 @@ -#pragma once - -#include -#include - -namespace katja -{ - class PackageList final : public ftxui::ComponentBase - { - std::vector> m_data; - std::vector m_header; - std::size_t top_line{ 0 }; - - public: - PackageList(const std::vector& header, const std::vector>& data); - - virtual ftxui::Element Render() override; - virtual bool OnEvent(ftxui::Event event) override; - }; -} diff --git a/src/config.h b/src/config.h deleted file mode 100644 index 5be3df7..0000000 --- a/src/config.h +++ /dev/null @@ -1,3 +0,0 @@ -#pragma once - -#define WORKDIR "./var" diff --git a/src/main.cpp b/src/main.cpp deleted file mode 100644 index ef8dfcd..0000000 --- a/src/main.cpp +++ /dev/null @@ -1,22 +0,0 @@ -#include "command.h" - -int main(int argc, char **argv) -{ - std::unique_ptr command; - - try - { - command = katja::parse_command_line(argc, argv); - } - catch (katja::command_exception& e) - { - std::cout << e.what() << std::endl << std::endl; - - katja::help().execute(); - - return EXIT_FAILURE; - } - command->execute(); - - return EXIT_SUCCESS; -} diff --git a/src/package.cpp b/src/package.cpp deleted file mode 100644 index 9fc99e4..0000000 --- a/src/package.cpp +++ /dev/null @@ -1,106 +0,0 @@ -#include "package.h" -#include - -namespace katja -{ - package::package(const std::string& name, const std::string& version, - const std::string& architecture, const std::string& tag) - : m_name(name), m_version(version), m_architecture(architecture), m_tag(tag) - { - } - - const std::string& package::name() const noexcept - { - return m_name; - } - - const std::string& package::version() const noexcept - { - return m_version; - } - - const std::string& package::architecture() const noexcept - { - return m_architecture; - } - - const std::string& package::tag() const noexcept - { - return m_tag; - } - - std::optional package::parse(const std::string& full_name) noexcept - { - std::size_t tag_separator = full_name.find_last_of('-'); - - if (tag_separator == std::string::npos || tag_separator == 0) - { - return std::nullopt; - } - std::size_t architecture_separator = full_name.find_last_of('-', tag_separator - 1); - - if (architecture_separator == std::string::npos || architecture_separator == 0) - { - return std::nullopt; - } - std::size_t version_separator = full_name.find_last_of('-', architecture_separator - 1); - - if (version_separator == std::string::npos || version_separator == 0) - { - return std::nullopt; - } - package parsed_package{ - full_name.substr(0, version_separator), - full_name.substr(version_separator + 1, architecture_separator - version_separator - 1), - full_name.substr(architecture_separator + 1, tag_separator - architecture_separator - 1), - full_name.substr(tag_separator + 1) - }; - return std::make_optional(parsed_package); - } - - std::unordered_map read_package_database() - { - std::unordered_map packages; - - for (const auto& entry : std::filesystem::directory_iterator("/var/lib/pkgtools/packages")) - { - std::optional maybe_package = package::parse(entry.path().filename()); - - if (maybe_package.has_value()) - { - packages.insert_or_assign(maybe_package.value().name(), maybe_package.value()); - } - } - return packages; - } - - package_exception::package_exception(const std::string& package_name, const std::string& reason) noexcept - : m_message(package_name) - { - m_message.reserve(m_message.size() + 2 + reason.size()); - m_message += ": " + reason; - } - - const std::string_view package_exception::package_name() const noexcept - { - std::size_t colon_position = m_message.find(':'); - - if (colon_position == std::string::npos) - { - return std::string_view(m_message); - } - else if (colon_position == 0) - { - return std::string_view(""); - } - else - { - return std::string_view(m_message.c_str(), colon_position - 1); - } - } - - const char *package_exception::what() const noexcept - { - return m_message.c_str(); - } -} diff --git a/src/package.h b/src/package.h deleted file mode 100644 index 109f065..0000000 --- a/src/package.h +++ /dev/null @@ -1,50 +0,0 @@ -#pragma once - -#include -#include -#include -#include -#include - -namespace katja -{ - class package - { - std::string m_name; - std::string m_version; - std::string m_architecture; - std::string m_tag; - - public: - explicit package(const std::string& name, const std::string& version, - const std::string& architecture, const std::string& tag); - - const std::string& name() const noexcept; - const std::string& version() const noexcept; - const std::string& architecture() const noexcept; - const std::string& tag() const noexcept; - - static std::optional parse(const std::string& full_name) noexcept; - }; - - class repository - { - public: - virtual std::unordered_map list(const std::set& package_names) = 0; - virtual void refresh() = 0; - virtual std::forward_list check_dependencies(const std::string& package_name) = 0; - }; - - std::unordered_map read_package_database(); - - class package_exception : public std::exception - { - std::string m_message; - - public: - explicit package_exception(const std::string& package_name, const std::string& reason) noexcept; - - const std::string_view package_name() const noexcept; - const char *what() const noexcept override; - }; -} diff --git a/src/sbo.cpp b/src/sbo.cpp deleted file mode 100644 index 086ba79..0000000 --- a/src/sbo.cpp +++ /dev/null @@ -1,232 +0,0 @@ -#include "config.h" -#include "sbo.h" -#include -#include -#include - -namespace katja -{ - sbo::sbo() - : git_binary(boost::process::search_path("git")) - , cache_path(std::filesystem::path{ WORKDIR } / "sbo/repository") - { - } - - info sbo::parse_info_file( - const std::filesystem::path& package_directory) const - { - std::map> results; - std::filesystem::path info_path = cache_path - / package_directory - / package_directory.filename().replace_extension(".info"); - - if (!std::filesystem::exists(info_path)) - { - throw package_exception(package_directory.filename().string(), "Package doesn't exist."); - } - // Parse the info file. - std::ifstream info_file{ info_path, std::ios::in }; - if (!info_file.is_open()) - { - throw package_exception(package_directory.filename().string(), "Unable to open the .info file."); - } - std::string line; - std::string variable_name; - std::vector variable_values; - - while (std::getline(info_file, line)) - { - std::string::const_iterator current_char = line.cbegin(); - - if (variable_name.empty()) - { - current_char = std::find(current_char, line.cend(), '='); - if (current_char == line.cbegin() || current_char == line.cend()) - { - break; // Expected 'variable name' or '='. - } - ++current_char; - if (current_char == line.cend() || *current_char != '"') - { - break; // Expected '"'. - } - variable_name = std::string(line.cbegin(), current_char - 1); - - variable_values.push_back(""); - } - - for (current_char += 1; current_char != line.end(); ++current_char) - { - if (*current_char == ' ') - { - if (!variable_values.back().empty()) - { - variable_values.push_back(""); - } - } - else if (*current_char == '"') - { - if (variable_values.back().empty()) - { - variable_values.pop_back(); - } - results.insert_or_assign(variable_name, variable_values); - variable_name = ""; - variable_values.clear(); - break; - } - else if (*current_char == '\\') - { - break; - } - else - { - variable_values.back().push_back(*current_char); - } - } - if (current_char == line.cend()) - { - break; // Expected '\' or '"'. - } - } - info _info; - - _info.prgnam = results["PRGNAM"][0]; - _info.version = results["VERSION"][0]; - _info.homepage = results["HOMEPAGE"].size() == 0 ? "" : results["HOMEPAGE"][0]; - _info.download = results["DOWNLOAD"]; - _info.md5sum = results["DOWNLOAD"]; - _info.download_x86_64 = results["DOWNLOAD_X86_64"]; - _info.md5sum_x86_64 = results["MD5SUM_X86_64"]; - _info.requires = results["REQUIRES"]; - _info.maintainer = results["MAINTAINER"][0]; - _info.email = results["EMAIL"][0]; - - return _info; - } - - std::unordered_map sbo::collect_packages() const - { - std::unordered_map results; - - for (const auto& category_directory : std::filesystem::directory_iterator(cache_path)) - { - if (!category_directory.is_directory()) - { - continue; - } - for (const auto& package_directory : std::filesystem::directory_iterator(category_directory.path())) - { - results.insert({ package_directory.path().filename().string(), - category_directory.path().filename() }); - } - } - return results; - } - - std::unordered_map sbo::list(const std::set& package_names) - { - std::string line; - std::unordered_map packages; - boost::process::environment slackbuild_environment; - slackbuild_environment["PRINT_PACKAGE_NAME"] = "y"; - - std::unordered_map package_categories = collect_packages(); - - for (const std::string& package_name : package_names) - { - std::unordered_map::iterator package_category = - package_categories.find(package_name); - - if (package_category == package_categories.cend()) - { - continue; - } - std::filesystem::path package_directory_name{ package_category->first }; - std::filesystem::path slackbuild_cwd = cache_path - / package_category->second / package_directory_name; - - // Execute the SlackBuild to get package information. - std::filesystem::path slackbuild_file_name = - package_directory_name.replace_extension(".SlackBuild"); - boost::process::ipstream slackbuild_output; - - boost::process::child slackbuild_process("/bin/bash", slackbuild_file_name.native(), - slackbuild_environment, - boost::process::start_dir(slackbuild_cwd.native()), - boost::process::std_out > slackbuild_output, - boost::process::std_in.close(), - boost::process::std_err > boost::process::null); - - std::optional maybe_package; - if (slackbuild_process.running() && std::getline(slackbuild_output, line) && !line.empty()) - { - maybe_package = package::parse(std::filesystem::path(line).replace_extension("")); - } - slackbuild_process.terminate(); - - if (maybe_package.has_value()) - { - packages.insert({ maybe_package.value().name(), maybe_package.value() }); - } - } - return packages; - } - - void sbo::refresh() - { - std::filesystem::file_status repository_status = std::filesystem::status(cache_path); - - if (std::filesystem::exists(repository_status) - && !std::filesystem::is_directory(repository_status)) - { - throw std::runtime_error("The working directory path \"" - + cache_path.string() + "\" exists, but it isn't a directory."); - } - else if (!std::filesystem::exists(repository_status)) - { - git("clone", std::filesystem::path(), - "git://git.slackbuilds.org/slackbuilds.git", cache_path.native()); - } - git("remote", cache_path.native(), "update", "--prune"); - git("reset", cache_path.native(), "--hard", "origin/master"); - } - - std::forward_list sbo::check_dependencies(const std::string& package_name) - { - std::unordered_map package_categories = collect_packages(); - ordered_set resolved; - - resolve_dependencies(package_name, package_categories, resolved); - std::forward_list results; - - for (const auto& dependency : resolved.get<1>()) - { - results.push_front(dependency); - } - return results; - } - - void sbo::resolve_dependencies(const std::string& package_name, - const std::unordered_map& package_categories, - ordered_set& resolved) const - { - std::unordered_map::const_iterator package_category = - package_categories.find(package_name); - - if (package_category == package_categories.cend()) - { - throw package_exception(package_name, "Package not found."); - } - info info_file = parse_info_file(package_category->second / package_category->first); - - for (const auto& package_dependency : info_file.requires) - { - if (resolved.find(package_dependency) == resolved.cend()) - { - resolve_dependencies(package_dependency, package_categories, resolved); - } - } - resolved.insert(package_name); - } -} diff --git a/src/sbo.h b/src/sbo.h deleted file mode 100644 index 95a1c53..0000000 --- a/src/sbo.h +++ /dev/null @@ -1,73 +0,0 @@ -#pragma once - -#include "package.h" -#include -#include -#include -#include -#include -#include - -namespace katja -{ - struct info - { - std::string prgnam; - std::string version; - std::string homepage; - std::vector download; - std::vector md5sum; - std::vector download_x86_64; - std::vector md5sum_x86_64; - std::vector requires; - std::string maintainer; - std::string email; - }; - - class sbo : public repository - { - using ordered_set = boost::multi_index_container< - std::string, - boost::multi_index::indexed_by< - boost::multi_index::ordered_unique>, - boost::multi_index::sequenced<> - > - >; - boost::filesystem::path git_binary; - std::filesystem::path cache_path; - - template - void git(const std::string& command, const std::filesystem::path& cwd, const Args&... args) const - { - if (cwd.empty()) - { - boost::process::system(git_binary, command, args...); - } - else - { - boost::process::system(git_binary, "-C", cwd.native(), command, args...); - } - } - - info parse_info_file(const std::filesystem::path& package_directory) const; - - /** - * Returns the list of packages in the repository. - * - * @return A map containing package names as key, and its category - * directory name as value. - */ - std::unordered_map collect_packages() const; - - void resolve_dependencies(const std::string& package_name, - const std::unordered_map& package_categories, - ordered_set& resolved) const; - - public: - explicit sbo(); - - virtual std::unordered_map list(const std::set& package_names) override; - virtual void refresh() override; - virtual std::forward_list check_dependencies(const std::string& package_name) override; - }; -}