mirror of
https://github.com/CachyOS/New-Cli-Installer.git
synced 2025-01-23 14:32:22 +08:00
👷 gucc: add parser for net/package profiles
This commit is contained in:
parent
2b708b3888
commit
6559b1412b
@ -30,13 +30,14 @@ add_library(${PROJECT_NAME} SHARED
|
||||
src/mtab.cpp include/gucc/mtab.hpp
|
||||
src/umount_partitions.cpp include/gucc/umount_partitions.hpp
|
||||
src/hwclock.cpp include/gucc/hwclock.hpp
|
||||
src/package_profiles.cpp include/gucc/package_profiles.hpp
|
||||
#src/chwd_profiles.cpp src/chwd_profiles.hpp
|
||||
#src/disk.cpp src/disk.hpp
|
||||
)
|
||||
|
||||
add_library(${PROJECT_NAME}::${PROJECT_NAME} ALIAS ${PROJECT_NAME})
|
||||
target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_DIR}/include)
|
||||
target_link_libraries(${PROJECT_NAME} PUBLIC project_warnings project_options spdlog::spdlog fmt::fmt range-v3::range-v3)
|
||||
target_link_libraries(${PROJECT_NAME} PUBLIC project_warnings project_options spdlog::spdlog fmt::fmt range-v3::range-v3 tomlplusplus::tomlplusplus)
|
||||
|
||||
if(COS_INSTALLER_BUILD_TESTS)
|
||||
add_subdirectory(tests)
|
||||
|
37
gucc/include/gucc/package_profiles.hpp
Normal file
37
gucc/include/gucc/package_profiles.hpp
Normal file
@ -0,0 +1,37 @@
|
||||
#ifndef PACKAGE_PROFILES_HPP
|
||||
#define PACKAGE_PROFILES_HPP
|
||||
|
||||
#include <optional> // for optional
|
||||
#include <string> // for string
|
||||
#include <string_view> // for string_view
|
||||
#include <vector> // for vector
|
||||
|
||||
namespace gucc::profile {
|
||||
|
||||
struct BaseProfiles {
|
||||
std::vector<std::string> base_packages{};
|
||||
std::vector<std::string> base_desktop_packages{};
|
||||
};
|
||||
|
||||
struct DesktopProfile {
|
||||
std::string profile_name{};
|
||||
std::vector<std::string> packages{};
|
||||
};
|
||||
|
||||
struct NetProfiles {
|
||||
BaseProfiles base_profiles{};
|
||||
std::vector<DesktopProfile> desktop_profiles{};
|
||||
};
|
||||
|
||||
// Parse base profiles
|
||||
auto parse_base_profiles(std::string_view config_content) noexcept -> std::optional<BaseProfiles>;
|
||||
|
||||
// Parse desktop profiles
|
||||
auto parse_desktop_profiles(std::string_view config_content) noexcept -> std::optional<std::vector<DesktopProfile>>;
|
||||
|
||||
// Parse net profiles
|
||||
auto parse_net_profiles(std::string_view config_content) noexcept -> std::optional<NetProfiles>;
|
||||
|
||||
} // namespace gucc::profile
|
||||
|
||||
#endif // PACKAGE_PROFILES_HPP
|
@ -20,6 +20,7 @@ gucc_lib = library('gucc',
|
||||
'src/mtab.cpp',
|
||||
'src/umount_partitions.cpp',
|
||||
'src/hwclock.cpp',
|
||||
'src/package_profiles.cpp',
|
||||
],
|
||||
include_directories : [include_directories('include')],
|
||||
dependencies: deps
|
||||
|
82
gucc/src/package_profiles.cpp
Normal file
82
gucc/src/package_profiles.cpp
Normal file
@ -0,0 +1,82 @@
|
||||
#include "gucc/package_profiles.hpp"
|
||||
|
||||
#include <spdlog/spdlog.h>
|
||||
|
||||
#define TOML_EXCEPTIONS 0 // disable exceptions
|
||||
#include <toml++/toml.h>
|
||||
|
||||
using namespace std::string_view_literals;
|
||||
|
||||
namespace {
|
||||
|
||||
inline void parse_toml_array(const toml::array* arr, std::vector<std::string>& vec) noexcept {
|
||||
for (const auto& node_el : *arr) {
|
||||
auto elem = node_el.value<std::string_view>().value();
|
||||
vec.emplace_back(elem);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace gucc::profile {
|
||||
|
||||
auto parse_base_profiles(std::string_view config_content) noexcept -> std::optional<BaseProfiles> {
|
||||
toml::parse_result netprof = toml::parse(config_content);
|
||||
if (netprof.failed()) {
|
||||
spdlog::error("Failed to parse profiles: {}", netprof.error().description());
|
||||
return std::nullopt;
|
||||
}
|
||||
const auto& netprof_table = std::move(netprof).table();
|
||||
|
||||
BaseProfiles base_profiles{};
|
||||
parse_toml_array(netprof_table["base-packages"]["packages"].as_array(), base_profiles.base_packages);
|
||||
parse_toml_array(netprof_table["base-packages"]["desktop"]["packages"].as_array(), base_profiles.base_desktop_packages);
|
||||
return std::make_optional<BaseProfiles>(std::move(base_profiles));
|
||||
}
|
||||
|
||||
auto parse_desktop_profiles(std::string_view config_content) noexcept -> std::optional<std::vector<DesktopProfile>> {
|
||||
toml::parse_result netprof = toml::parse(config_content);
|
||||
if (netprof.failed()) {
|
||||
spdlog::error("Failed to parse profiles: {}", netprof.error().description());
|
||||
return std::nullopt;
|
||||
}
|
||||
const auto& netprof_table = std::move(netprof).table();
|
||||
|
||||
std::vector<DesktopProfile> desktop_profiles{};
|
||||
|
||||
auto desktop_table = netprof_table["desktop"].as_table();
|
||||
for (auto&& [key, value] : *desktop_table) {
|
||||
auto value_table = *value.as_table();
|
||||
std::vector<std::string> desktop_profile_packages{};
|
||||
parse_toml_array(value_table["packages"].as_array(), desktop_profile_packages);
|
||||
desktop_profiles.emplace_back(DesktopProfile{.profile_name = std::string{std::string_view{key}}, .packages = std::move(desktop_profile_packages)});
|
||||
}
|
||||
return std::make_optional<std::vector<DesktopProfile>>(std::move(desktop_profiles));
|
||||
}
|
||||
|
||||
auto parse_net_profiles(std::string_view config_content) noexcept -> std::optional<NetProfiles> {
|
||||
toml::parse_result netprof = toml::parse(config_content);
|
||||
if (netprof.failed()) {
|
||||
spdlog::error("Failed to parse profiles: {}", netprof.error().description());
|
||||
return std::nullopt;
|
||||
}
|
||||
const auto& netprof_table = std::move(netprof).table();
|
||||
|
||||
NetProfiles net_profiles{};
|
||||
|
||||
// parse base
|
||||
parse_toml_array(netprof_table["base-packages"]["packages"].as_array(), net_profiles.base_profiles.base_packages);
|
||||
parse_toml_array(netprof_table["base-packages"]["desktop"]["packages"].as_array(), net_profiles.base_profiles.base_desktop_packages);
|
||||
|
||||
// parse desktop
|
||||
auto desktop_table = netprof_table["desktop"].as_table();
|
||||
for (auto&& [key, value] : *desktop_table) {
|
||||
auto value_table = *value.as_table();
|
||||
std::vector<std::string> desktop_profile_packages{};
|
||||
parse_toml_array(value_table["packages"].as_array(), desktop_profile_packages);
|
||||
net_profiles.desktop_profiles.emplace_back(DesktopProfile{.profile_name = std::string{std::string_view{key}}, .packages = std::move(desktop_profile_packages)});
|
||||
}
|
||||
return std::make_optional<NetProfiles>(std::move(net_profiles));
|
||||
}
|
||||
|
||||
} // namespace gucc::profile
|
@ -53,3 +53,11 @@ executable(
|
||||
link_with: [gucc_lib],
|
||||
include_directories: [include_directories('../include')],
|
||||
install: false)
|
||||
|
||||
executable(
|
||||
'test-package_profiles',
|
||||
files('unit-package_profiles.cpp'),
|
||||
dependencies: deps,
|
||||
link_with: [gucc_lib],
|
||||
include_directories: [include_directories('../include')],
|
||||
install: false)
|
||||
|
103
gucc/tests/unit-package_profiles.cpp
Normal file
103
gucc/tests/unit-package_profiles.cpp
Normal file
@ -0,0 +1,103 @@
|
||||
#include "gucc/file_utils.hpp"
|
||||
#include "gucc/package_profiles.hpp"
|
||||
|
||||
#include <cassert>
|
||||
|
||||
#include <filesystem>
|
||||
#include <fstream>
|
||||
#include <string_view>
|
||||
|
||||
#include <fmt/core.h>
|
||||
|
||||
#include <spdlog/sinks/callback_sink.h>
|
||||
#include <spdlog/spdlog.h>
|
||||
|
||||
#if defined(__clang__)
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wold-style-cast"
|
||||
#elif defined(__GNUC__)
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wnull-dereference"
|
||||
#pragma GCC diagnostic ignored "-Wuseless-cast"
|
||||
#pragma GCC diagnostic ignored "-Wold-style-cast"
|
||||
#endif
|
||||
|
||||
#include <range/v3/range/conversion.hpp>
|
||||
#include <range/v3/view/filter.hpp>
|
||||
#include <range/v3/view/join.hpp>
|
||||
#include <range/v3/view/split.hpp>
|
||||
|
||||
#if defined(__clang__)
|
||||
#pragma clang diagnostic pop
|
||||
#elif defined(__GNUC__)
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
namespace fs = std::filesystem;
|
||||
using namespace std::string_view_literals;
|
||||
|
||||
static constexpr auto VALID_PROFILE_TEST = R"(
|
||||
[base-packages]
|
||||
packages = ["a","b"]
|
||||
[base-packages.desktop]
|
||||
packages = ["c","d","f"]
|
||||
[desktop.someprofile-1]
|
||||
packages = ["ca","da","fa"]
|
||||
[desktop.someprofile-2]
|
||||
packages = ["cb","db","fb"]
|
||||
)"sv;
|
||||
|
||||
static constexpr auto INVALID_PROFILE_TEST = R"(
|
||||
[base-packages]
|
||||
pacages = ["a,"b"]
|
||||
[base-packages.desktop
|
||||
package = c","d",f"]
|
||||
[desktop.someprofile-1]
|
||||
pacages = ["ca,"da","fa"
|
||||
[desktop.someprofile-2]
|
||||
packaes = ["cb","db",fb"]
|
||||
)"sv;
|
||||
|
||||
int main() {
|
||||
auto callback_sink = std::make_shared<spdlog::sinks::callback_sink_mt>([](const spdlog::details::log_msg&) {
|
||||
// noop
|
||||
});
|
||||
spdlog::set_default_logger(std::make_shared<spdlog::logger>("default", callback_sink));
|
||||
|
||||
// valid profile
|
||||
{
|
||||
auto base_profs = gucc::profile::parse_base_profiles(VALID_PROFILE_TEST);
|
||||
assert(base_profs);
|
||||
assert((base_profs->base_packages == std::vector<std::string>{"a", "b"}));
|
||||
assert((base_profs->base_desktop_packages == std::vector<std::string>{"c", "d", "f"}));
|
||||
|
||||
auto base_desktop_profs = gucc::profile::parse_desktop_profiles(VALID_PROFILE_TEST);
|
||||
assert(base_desktop_profs);
|
||||
assert(base_desktop_profs->size() == 2);
|
||||
assert(((*base_desktop_profs)[0].profile_name == "someprofile-1"));
|
||||
assert(((*base_desktop_profs)[0].packages == std::vector<std::string>{"ca", "da", "fa"}));
|
||||
assert(((*base_desktop_profs)[1].profile_name == "someprofile-2"));
|
||||
assert(((*base_desktop_profs)[1].packages == std::vector<std::string>{"cb", "db", "fb"}));
|
||||
|
||||
auto net_profs = gucc::profile::parse_net_profiles(VALID_PROFILE_TEST);
|
||||
assert(net_profs);
|
||||
assert((net_profs->base_profiles.base_packages == std::vector<std::string>{"a", "b"}));
|
||||
assert((net_profs->base_profiles.base_desktop_packages == std::vector<std::string>{"c", "d", "f"}));
|
||||
assert(net_profs->desktop_profiles.size() == 2);
|
||||
assert((net_profs->desktop_profiles[0].profile_name == "someprofile-1"));
|
||||
assert((net_profs->desktop_profiles[0].packages == std::vector<std::string>{"ca", "da", "fa"}));
|
||||
assert((net_profs->desktop_profiles[1].profile_name == "someprofile-2"));
|
||||
assert((net_profs->desktop_profiles[1].packages == std::vector<std::string>{"cb", "db", "fb"}));
|
||||
}
|
||||
// invalid profile
|
||||
{
|
||||
auto base_profs = gucc::profile::parse_base_profiles(INVALID_PROFILE_TEST);
|
||||
assert(!base_profs);
|
||||
|
||||
auto base_desktop_profs = gucc::profile::parse_desktop_profiles(INVALID_PROFILE_TEST);
|
||||
assert(!base_desktop_profs);
|
||||
|
||||
auto net_profs = gucc::profile::parse_net_profiles(INVALID_PROFILE_TEST);
|
||||
assert(!net_profs);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user