diff options
Diffstat (limited to 'src/sbo.cpp')
| -rw-r--r-- | src/sbo.cpp | 232 |
1 files changed, 0 insertions, 232 deletions
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 <algorithm> -#include <fstream> -#include <vector> - -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<std::string, std::vector<std::string>> 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<std::string> 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<std::string, std::filesystem::path> sbo::collect_packages() const - { - std::unordered_map<std::string, std::filesystem::path> 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<std::string, package> sbo::list(const std::set<std::string>& package_names) - { - std::string line; - std::unordered_map<std::string, package> packages; - boost::process::environment slackbuild_environment; - slackbuild_environment["PRINT_PACKAGE_NAME"] = "y"; - - std::unordered_map<std::string, std::filesystem::path> package_categories = collect_packages(); - - for (const std::string& package_name : package_names) - { - std::unordered_map<std::string, std::filesystem::path>::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<package> 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<std::string> sbo::check_dependencies(const std::string& package_name) - { - std::unordered_map<std::string, std::filesystem::path> package_categories = collect_packages(); - ordered_set resolved; - - resolve_dependencies(package_name, package_categories, resolved); - std::forward_list<std::string> 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<std::string, std::filesystem::path>& package_categories, - ordered_set& resolved) const - { - std::unordered_map<std::string, std::filesystem::path>::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); - } -} |
