🧹 gucc: move IO into gucc

This commit is contained in:
Vladislav Nepogodin 2024-06-26 16:54:04 +04:00
parent 795b8b183e
commit 62312c02e7
No known key found for this signature in database
GPG Key ID: B62C3D10C54D5DA9
13 changed files with 433 additions and 387 deletions

View File

@ -10,6 +10,7 @@ project(gucc
add_library(${PROJECT_NAME} SHARED add_library(${PROJECT_NAME} SHARED
#src/utils.cpp src/utils.hpp #src/utils.cpp src/utils.hpp
src/io_utils.cpp include/gucc/io_utils.hpp
src/string_utils.cpp include/gucc/string_utils.hpp src/string_utils.cpp include/gucc/string_utils.hpp
src/file_utils.cpp include/gucc/file_utils.hpp src/file_utils.cpp include/gucc/file_utils.hpp
src/cpu.cpp include/gucc/cpu.hpp src/cpu.cpp include/gucc/cpu.hpp

View File

@ -0,0 +1,16 @@
#ifndef IO_UTILS_HPP
#define IO_UTILS_HPP
#include <string> // for string
#include <string_view> // for string_view
#include <vector> // for vector
namespace gucc::utils {
auto safe_getenv(const char* env_name) noexcept -> std::string_view;
void exec(const std::vector<std::string>& vec) noexcept;
auto exec(std::string_view command, bool interactive = false) noexcept -> std::string;
} // namespace gucc::utils
#endif // IO_UTILS_HPP

91
gucc/src/io_utils.cpp Normal file
View File

@ -0,0 +1,91 @@
#include "gucc/io_utils.hpp"
#include <sys/wait.h> // for waitpid
#include <unistd.h> // for execvp, fork
#include <cstdint> // for int32_t
#include <cstdio> // for feof, fgets, pclose, popen
#include <cstdlib> // for WIFEXITED, WIFSIGNALED
#include <algorithm> // for transform
#include <fstream> // for ofstream
#include <fmt/ranges.h>
#include <spdlog/spdlog.h>
using namespace std::string_view_literals;
namespace gucc::utils {
auto safe_getenv(const char* env_name) noexcept -> std::string_view {
const char* const raw_val = getenv(env_name);
return raw_val != nullptr ? std::string_view{raw_val} : std::string_view{};
}
void exec(const std::vector<std::string>& vec) noexcept {
const bool log_exec_cmds = utils::safe_getenv("LOG_EXEC_CMDS") == "1"sv;
const bool dirty_cmd_run = utils::safe_getenv("DIRTY_CMD_RUN") == "1"sv;
if (log_exec_cmds && spdlog::default_logger_raw() != nullptr) {
spdlog::debug("[exec] cmd := {}", vec);
}
if (dirty_cmd_run) {
return;
}
std::int32_t status{};
auto pid = fork();
if (pid == 0) {
std::vector<char*> args;
std::transform(vec.cbegin(), vec.cend(), std::back_inserter(args),
[=](const std::string& arg) -> char* { return const_cast<char*>(arg.data()); });
args.push_back(nullptr);
char** command = args.data();
execvp(command[0], command);
} else {
do {
waitpid(pid, &status, 0);
} while ((!WIFEXITED(status)) && (!WIFSIGNALED(status)));
}
}
// https://github.com/sheredom/subprocess.h
// https://gist.github.com/konstantint/d49ab683b978b3d74172
// https://github.com/arun11299/cpp-subprocess/blob/master/subprocess.hpp#L1218
// https://stackoverflow.com/questions/11342868/c-interface-for-interactive-bash
// https://github.com/hniksic/rust-subprocess
auto exec(std::string_view command, bool interactive) noexcept -> std::string {
const bool log_exec_cmds = utils::safe_getenv("LOG_EXEC_CMDS") == "1"sv;
if (log_exec_cmds && spdlog::default_logger_raw() != nullptr) {
spdlog::debug("[exec] cmd := '{}'", command);
}
if (interactive) {
const auto& ret_code = system(command.data());
return std::to_string(ret_code);
}
const std::unique_ptr<FILE, decltype(&pclose)> pipe(popen(command.data(), "r"), pclose);
if (!pipe) {
spdlog::error("popen failed! '{}'", command);
return "-1";
}
std::string result{};
std::array<char, 128> buffer{};
while (!feof(pipe.get())) {
if (fgets(buffer.data(), buffer.size(), pipe.get()) != nullptr) {
result += buffer.data();
}
}
if (result.ends_with('\n')) {
result.pop_back();
}
return result;
}
} // namespace gucc::utils

View File

@ -2,6 +2,7 @@
#include "utils.hpp" #include "utils.hpp"
// import gucc // import gucc
#include "gucc/io_utils.hpp"
#include "gucc/string_utils.hpp" #include "gucc/string_utils.hpp"
#include <algorithm> // for any_of, sort, for_each #include <algorithm> // for any_of, sort, for_each
@ -64,7 +65,7 @@ auto get_available_profile_names(std::string_view profile_type) noexcept -> std:
if (!all_profile_names.has_value()) { return {}; } if (!all_profile_names.has_value()) { return {}; }
/* clang-format on */ /* clang-format on */
const auto& available_profile_names = gucc::utils::make_multiline(utils::exec("chwd --list -d | grep Name | awk '{print $4}'")); const auto& available_profile_names = gucc::utils::make_multiline(gucc::utils::exec("chwd --list -d | grep Name | awk '{print $4}'"));
std::vector<std::string> filtered_profile_names{}; std::vector<std::string> filtered_profile_names{};
const auto& functor = [available_profile_names](auto&& profile_name) { return ranges::any_of(available_profile_names, [profile_name](auto&& available_profile) { return available_profile == profile_name; }); }; const auto& functor = [available_profile_names](auto&& profile_name) { return ranges::any_of(available_profile_names, [profile_name](auto&& available_profile) { return available_profile == profile_name; }); };

View File

@ -4,6 +4,7 @@
#include "widgets.hpp" #include "widgets.hpp"
// import gucc // import gucc
#include "gucc/io_utils.hpp"
#include "gucc/string_utils.hpp" #include "gucc/string_utils.hpp"
#include <fmt/compile.h> #include <fmt/compile.h>
@ -114,7 +115,7 @@ bool luks_open() noexcept {
detail::follow_process_log_widget({"/bin/sh", "-c", fmt::format(FMT_COMPILE("echo \"{}\" | cryptsetup open --type luks {} {}"), luks_password, partition, luks_root_name)}); detail::follow_process_log_widget({"/bin/sh", "-c", fmt::format(FMT_COMPILE("echo \"{}\" | cryptsetup open --type luks {} {}"), luks_password, partition, luks_root_name)});
#endif #endif
const auto& devlist = utils::exec(fmt::format(FMT_COMPILE("lsblk -o NAME,TYPE,FSTYPE,SIZE,MOUNTPOINT {} | grep \"crypt\\|NAME\\|MODEL\\|TYPE\\|FSTYPE\\|SIZE\""), partition)); const auto& devlist = gucc::utils::exec(fmt::format(FMT_COMPILE("lsblk -o NAME,TYPE,FSTYPE,SIZE,MOUNTPOINT {} | grep \"crypt\\|NAME\\|MODEL\\|TYPE\\|FSTYPE\\|SIZE\""), partition));
detail::msgbox_widget(devlist); detail::msgbox_widget(devlist);
return true; return true;
@ -125,7 +126,7 @@ bool luks_setup() noexcept {
auto& config_data = config_instance->data(); auto& config_data = config_instance->data();
#ifdef NDEVENV #ifdef NDEVENV
utils::exec("modprobe -a dm-mod dm_crypt"); gucc::utils::exec("modprobe -a dm-mod dm_crypt");
#endif #endif
config_data["INCLUDE_PART"] = "part\\|lvm"; config_data["INCLUDE_PART"] = "part\\|lvm";
utils::umount_partitions(); utils::umount_partitions();
@ -187,7 +188,7 @@ void luks_express() noexcept {
void luks_show() noexcept { void luks_show() noexcept {
static constexpr auto luks_success = "Done!"; static constexpr auto luks_success = "Done!";
const auto& lsblk = utils::exec(R"(lsblk -o NAME,TYPE,FSTYPE,SIZE | grep "part\|crypt\|NAME\|TYPE\|FSTYPE\|SIZE")"); const auto& lsblk = gucc::utils::exec(R"(lsblk -o NAME,TYPE,FSTYPE,SIZE | grep "part\|crypt\|NAME\|TYPE\|FSTYPE\|SIZE")");
const auto& content = fmt::format(FMT_COMPILE("\n{}\n \n{}"), luks_success, lsblk); const auto& content = fmt::format(FMT_COMPILE("\n{}\n \n{}"), luks_success, lsblk);
detail::msgbox_widget(content, size(HEIGHT, GREATER_THAN, 5)); detail::msgbox_widget(content, size(HEIGHT, GREATER_THAN, 5));
} }

View File

@ -4,6 +4,7 @@
#include "widgets.hpp" #include "widgets.hpp"
// import gucc // import gucc
#include "gucc/io_utils.hpp"
#include "gucc/string_utils.hpp" #include "gucc/string_utils.hpp"
#include <filesystem> // for exists, is_directory #include <filesystem> // for exists, is_directory
@ -28,8 +29,8 @@ void btrfs_create_subvols([[maybe_unused]] const disk_part& disk, const std::str
#ifdef NDEVENV #ifdef NDEVENV
// save mount options and name of the root partition // save mount options and name of the root partition
utils::exec("mount | grep \"on /mnt \" | grep -Po '(?<=\\().*(?=\\))' > /tmp/.root_mount_options"sv); gucc::utils::exec("mount | grep \"on /mnt \" | grep -Po '(?<=\\().*(?=\\))' > /tmp/.root_mount_options"sv);
// utils::exec("lsblk -lno MOUNTPOINT,NAME | awk '/^\\/mnt / {print $2}' > /tmp/.root_partition"sv); // gucc::utils::exec("lsblk -lno MOUNTPOINT,NAME | awk '/^\\/mnt / {print $2}' > /tmp/.root_partition"sv);
if (mode == "manual"sv) { if (mode == "manual"sv) {
// Create subvolumes manually // Create subvolumes manually
@ -42,13 +43,13 @@ void btrfs_create_subvols([[maybe_unused]] const disk_part& disk, const std::str
fs::current_path("/mnt"); fs::current_path("/mnt");
auto subvol_list = gucc::utils::make_multiline(subvols, false, ' '); auto subvol_list = gucc::utils::make_multiline(subvols, false, ' ');
for (const auto& subvol : subvol_list) { for (const auto& subvol : subvol_list) {
utils::exec(fmt::format(FMT_COMPILE("btrfs subvolume create {} 2>>/tmp/cachyos-install.log"), subvol), true); gucc::utils::exec(fmt::format(FMT_COMPILE("btrfs subvolume create {} 2>>/tmp/cachyos-install.log"), subvol), true);
} }
fs::current_path(saved_path); fs::current_path(saved_path);
// Mount subvolumes // Mount subvolumes
umount("/mnt"); umount("/mnt");
// Mount the first subvolume as / // Mount the first subvolume as /
utils::exec(fmt::format(FMT_COMPILE("mount -o {},subvol=\"{}\" \"{}\" /mnt"), disk.mount_opts, subvol_list[0], disk.root)); gucc::utils::exec(fmt::format(FMT_COMPILE("mount -o {},subvol=\"{}\" \"{}\" /mnt"), disk.mount_opts, subvol_list[0], disk.root));
// Remove the first subvolume from the subvolume list // Remove the first subvolume from the subvolume list
subvol_list.erase(subvol_list.begin()); subvol_list.erase(subvol_list.begin());
@ -62,7 +63,7 @@ void btrfs_create_subvols([[maybe_unused]] const disk_part& disk, const std::str
const auto& mountp_formatted = fmt::format(FMT_COMPILE("/mnt{}"), mountp); const auto& mountp_formatted = fmt::format(FMT_COMPILE("/mnt{}"), mountp);
fs::create_directories(mountp_formatted); fs::create_directories(mountp_formatted);
utils::exec(fmt::format(FMT_COMPILE("mount -o {},subvol=\"{}\" \"{}\" \"{}\""), disk.mount_opts, subvol, disk.root, mountp_formatted)); gucc::utils::exec(fmt::format(FMT_COMPILE("mount -o {},subvol=\"{}\" \"{}\" \"{}\""), disk.mount_opts, subvol, disk.root, mountp_formatted));
} }
return; return;
} }
@ -77,18 +78,18 @@ void btrfs_create_subvols([[maybe_unused]] const disk_part& disk, const std::str
// Create subvolumes automatically // Create subvolumes automatically
const auto& saved_path = fs::current_path(); const auto& saved_path = fs::current_path();
fs::current_path("/mnt"); fs::current_path("/mnt");
utils::exec("btrfs subvolume create @ 2>>/tmp/cachyos-install.log"sv, true); gucc::utils::exec("btrfs subvolume create @ 2>>/tmp/cachyos-install.log"sv, true);
utils::exec("btrfs subvolume create @home 2>>/tmp/cachyos-install.log"sv, true); gucc::utils::exec("btrfs subvolume create @home 2>>/tmp/cachyos-install.log"sv, true);
utils::exec("btrfs subvolume create @cache 2>>/tmp/cachyos-install.log"sv, true); gucc::utils::exec("btrfs subvolume create @cache 2>>/tmp/cachyos-install.log"sv, true);
// utils::exec("btrfs subvolume create @snapshots 2>>/tmp/cachyos-install.log"sv, true); // gucc::utils::exec("btrfs subvolume create @snapshots 2>>/tmp/cachyos-install.log"sv, true);
fs::current_path(saved_path); fs::current_path(saved_path);
// Mount subvolumes // Mount subvolumes
umount("/mnt"); umount("/mnt");
utils::exec(fmt::format(FMT_COMPILE("mount -o {},subvol=@ \"{}\" /mnt"), disk.mount_opts, disk.root)); gucc::utils::exec(fmt::format(FMT_COMPILE("mount -o {},subvol=@ \"{}\" /mnt"), disk.mount_opts, disk.root));
fs::create_directories("/mnt/home"); fs::create_directories("/mnt/home");
fs::create_directories("/mnt/var/cache"); fs::create_directories("/mnt/var/cache");
utils::exec(fmt::format(FMT_COMPILE("mount -o {},subvol=@home \"{}\" /mnt/home"), disk.mount_opts, disk.root)); gucc::utils::exec(fmt::format(FMT_COMPILE("mount -o {},subvol=@home \"{}\" /mnt/home"), disk.mount_opts, disk.root));
utils::exec(fmt::format(FMT_COMPILE("mount -o {},subvol=@cache \"{}\" /mnt/var/cache"), disk.mount_opts, disk.root)); gucc::utils::exec(fmt::format(FMT_COMPILE("mount -o {},subvol=@cache \"{}\" /mnt/var/cache"), disk.mount_opts, disk.root));
#else #else
spdlog::info("Do we ignore note? {}", ignore_note); spdlog::info("Do we ignore note? {}", ignore_note);
#endif #endif
@ -96,21 +97,21 @@ void btrfs_create_subvols([[maybe_unused]] const disk_part& disk, const std::str
void mount_existing_subvols(const disk_part& disk) noexcept { void mount_existing_subvols(const disk_part& disk) noexcept {
// Set mount options // Set mount options
const auto& format_name = utils::exec(fmt::format(FMT_COMPILE("echo {} | rev | cut -d/ -f1 | rev"), disk.part)); const auto& format_name = gucc::utils::exec(fmt::format(FMT_COMPILE("echo {} | rev | cut -d/ -f1 | rev"), disk.part));
const auto& format_device = utils::exec(fmt::format(FMT_COMPILE("lsblk -i | tac | sed -r 's/^[^[:alnum:]]+//' | sed -n -e \"/{}/,/disk/p\" | {}"), format_name, "awk '/disk/ {print $1}'"sv)); const auto& format_device = gucc::utils::exec(fmt::format(FMT_COMPILE("lsblk -i | tac | sed -r 's/^[^[:alnum:]]+//' | sed -n -e \"/{}/,/disk/p\" | {}"), format_name, "awk '/disk/ {print $1}'"sv));
std::string fs_opts{}; std::string fs_opts{};
if (utils::exec(fmt::format(FMT_COMPILE("cat /sys/block/{}/queue/rotational)"), format_device), true) == "1"sv) { if (gucc::utils::exec(fmt::format(FMT_COMPILE("cat /sys/block/{}/queue/rotational)"), format_device), true) == "1"sv) {
fs_opts = "autodefrag,compress=zlib,noatime,nossd,commit=120"sv; fs_opts = "autodefrag,compress=zlib,noatime,nossd,commit=120"sv;
} else { } else {
fs_opts = "compress=lzo,noatime,space_cache,ssd,commit=120"sv; fs_opts = "compress=lzo,noatime,space_cache,ssd,commit=120"sv;
} }
#ifdef NDEVENV #ifdef NDEVENV
utils::exec("btrfs subvolume list /mnt 2>/dev/null | cut -d\" \" -f9 > /tmp/.subvols"sv, true); gucc::utils::exec("btrfs subvolume list /mnt 2>/dev/null | cut -d\" \" -f9 > /tmp/.subvols"sv, true);
umount("/mnt"); umount("/mnt");
// Mount subvolumes one by one // Mount subvolumes one by one
for (const auto& subvol : gucc::utils::make_multiline(utils::exec("cat /tmp/.subvols"sv))) { for (const auto& subvol : gucc::utils::make_multiline(gucc::utils::exec("cat /tmp/.subvols"sv))) {
// Ask for mountpoint // Ask for mountpoint
const auto& content = fmt::format(FMT_COMPILE("\nInput mountpoint of\nthe subvolume {}\nas it would appear\nin installed system\n(without prepending /mnt).\n"), subvol); const auto& content = fmt::format(FMT_COMPILE("\nInput mountpoint of\nthe subvolume {}\nas it would appear\nin installed system\n(without prepending /mnt).\n"), subvol);
std::string mountpoint{"/"}; std::string mountpoint{"/"};
@ -122,18 +123,18 @@ void mount_existing_subvols(const disk_part& disk) noexcept {
fs::create_directories(mount_dir); fs::create_directories(mount_dir);
} }
// Mount the subvolume // Mount the subvolume
utils::exec(fmt::format(FMT_COMPILE("mount -o \"{},subvol={}\" \"{}\" \"{}\""), fs_opts, subvol, disk.root, mount_dir)); gucc::utils::exec(fmt::format(FMT_COMPILE("mount -o \"{},subvol={}\" \"{}\" \"{}\""), fs_opts, subvol, disk.root, mount_dir));
} }
#endif #endif
} }
std::vector<std::string> lvm_show_vg() noexcept { std::vector<std::string> lvm_show_vg() noexcept {
const auto& vg_list = gucc::utils::make_multiline(utils::exec("lvs --noheadings | awk '{print $2}' | uniq"sv)); const auto& vg_list = gucc::utils::make_multiline(gucc::utils::exec("lvs --noheadings | awk '{print $2}' | uniq"sv));
std::vector<std::string> res{}; std::vector<std::string> res{};
res.reserve(vg_list.size()); res.reserve(vg_list.size());
for (const auto& vg : vg_list) { for (const auto& vg : vg_list) {
const auto& temp = utils::exec(fmt::format(FMT_COMPILE("vgdisplay {} | grep -i \"vg size\" | {}"), vg, "awk '{print $3$4}'"sv)); const auto& temp = gucc::utils::exec(fmt::format(FMT_COMPILE("vgdisplay {} | grep -i \"vg size\" | {}"), vg, "awk '{print $3$4}'"sv));
res.push_back(temp); res.push_back(temp);
} }
@ -157,7 +158,7 @@ bool zfs_auto_pres(const std::string_view& partition, const std::string_view& zf
#ifdef NDEVENV #ifdef NDEVENV
// set the rootfs // set the rootfs
utils::exec(fmt::format(FMT_COMPILE("zpool set bootfs={0}/ROOT/cos/root {0} 2>>/tmp/cachyos-install.log"), zfs_zpool_name), true); gucc::utils::exec(fmt::format(FMT_COMPILE("zpool set bootfs={0}/ROOT/cos/root {0} 2>>/tmp/cachyos-install.log"), zfs_zpool_name), true);
#endif #endif
return true; return true;
} }
@ -175,15 +176,15 @@ bool zfs_create_zpool(const std::string_view& partition, const std::string_view&
std::int32_t ret_code{}; std::int32_t ret_code{};
// Find the UUID of the partition // Find the UUID of the partition
const auto& partuuid = utils::exec(fmt::format(FMT_COMPILE("lsblk -lno PATH,PARTUUID | grep \"^{}\" | {}"), partition, "awk '{print $2}'"sv), false); const auto& partuuid = gucc::utils::exec(fmt::format(FMT_COMPILE("lsblk -lno PATH,PARTUUID | grep \"^{}\" | {}"), partition, "awk '{print $2}'"sv), false);
// See if the partition has a partuuid, if not use the device name // See if the partition has a partuuid, if not use the device name
const auto& zfs_zpool_cmd = fmt::format(FMT_COMPILE("zpool create {} {}"), zpool_options, pool_name); const auto& zfs_zpool_cmd = fmt::format(FMT_COMPILE("zpool create {} {}"), zpool_options, pool_name);
if (!partuuid.empty()) { if (!partuuid.empty()) {
ret_code = utils::to_int(utils::exec(fmt::format(FMT_COMPILE("{} {} 2>>/tmp/cachyos-install.log"), zfs_zpool_cmd, partuuid), true)); ret_code = utils::to_int(gucc::utils::exec(fmt::format(FMT_COMPILE("{} {} 2>>/tmp/cachyos-install.log"), zfs_zpool_cmd, partuuid), true));
spdlog::info("Creating zpool {} on device {} using partuuid {}", pool_name, partition, partuuid); spdlog::info("Creating zpool {} on device {} using partuuid {}", pool_name, partition, partuuid);
} else { } else {
ret_code = utils::to_int(utils::exec(fmt::format(FMT_COMPILE("{} {} 2>>/tmp/cachyos-install.log"), zfs_zpool_cmd, partition), true)); ret_code = utils::to_int(gucc::utils::exec(fmt::format(FMT_COMPILE("{} {} 2>>/tmp/cachyos-install.log"), zfs_zpool_cmd, partition), true));
spdlog::info("Creating zpool {} on device {}", pool_name, partition); spdlog::info("Creating zpool {} on device {}", pool_name, partition);
} }
@ -200,8 +201,8 @@ bool zfs_create_zpool(const std::string_view& partition, const std::string_view&
#ifdef NDEVENV #ifdef NDEVENV
// Since zfs manages mountpoints, we export it and then import with a root of MOUNTPOINT // Since zfs manages mountpoints, we export it and then import with a root of MOUNTPOINT
const auto& mountpoint = std::get<std::string>(config_data["MOUNTPOINT"]); const auto& mountpoint = std::get<std::string>(config_data["MOUNTPOINT"]);
utils::exec(fmt::format(FMT_COMPILE("zpool export {} 2>>/tmp/cachyos-install.log"), pool_name), true); gucc::utils::exec(fmt::format(FMT_COMPILE("zpool export {} 2>>/tmp/cachyos-install.log"), pool_name), true);
utils::exec(fmt::format(FMT_COMPILE("zpool import -R {} {} 2>>/tmp/cachyos-install.log"), mountpoint, pool_name), true); gucc::utils::exec(fmt::format(FMT_COMPILE("zpool import -R {} {} 2>>/tmp/cachyos-install.log"), mountpoint, pool_name), true);
#endif #endif
return true; return true;
@ -210,7 +211,7 @@ bool zfs_create_zpool(const std::string_view& partition, const std::string_view&
// Creates a zfs volume // Creates a zfs volume
void zfs_create_zvol(const std::string_view& zsize, const std::string_view& zpath) noexcept { void zfs_create_zvol(const std::string_view& zsize, const std::string_view& zpath) noexcept {
#ifdef NDEVENV #ifdef NDEVENV
utils::exec(fmt::format(FMT_COMPILE("zfs create -V {}M {} 2>>/tmp/cachyos-install.log"), zsize, zpath), true); gucc::utils::exec(fmt::format(FMT_COMPILE("zfs create -V {}M {} 2>>/tmp/cachyos-install.log"), zsize, zpath), true);
#else #else
spdlog::debug("zfs create -V {}M {}", zsize, zpath); spdlog::debug("zfs create -V {}M {}", zsize, zpath);
#endif #endif
@ -219,7 +220,7 @@ void zfs_create_zvol(const std::string_view& zsize, const std::string_view& zpat
// Creates a zfs filesystem, the first parameter is the ZFS path and the second is the mount path // Creates a zfs filesystem, the first parameter is the ZFS path and the second is the mount path
void zfs_create_dataset(const std::string_view& zpath, const std::string_view& zmount) noexcept { void zfs_create_dataset(const std::string_view& zpath, const std::string_view& zmount) noexcept {
#ifdef NDEVENV #ifdef NDEVENV
utils::exec(fmt::format(FMT_COMPILE("zfs create -o mountpoint={} {} 2>>/tmp/cachyos-install.log"), zmount, zpath), true); gucc::utils::exec(fmt::format(FMT_COMPILE("zfs create -o mountpoint={} {} 2>>/tmp/cachyos-install.log"), zmount, zpath), true);
#else #else
spdlog::debug("zfs create -o mountpoint={} {}", zmount, zpath); spdlog::debug("zfs create -o mountpoint={} {}", zmount, zpath);
#endif #endif
@ -227,7 +228,7 @@ void zfs_create_dataset(const std::string_view& zpath, const std::string_view& z
void zfs_destroy_dataset(const std::string_view& zdataset) noexcept { void zfs_destroy_dataset(const std::string_view& zdataset) noexcept {
#ifdef NDEVENV #ifdef NDEVENV
utils::exec(fmt::format(FMT_COMPILE("zfs destroy -r {} 2>>/tmp/cachyos-install.log"), zdataset), true); gucc::utils::exec(fmt::format(FMT_COMPILE("zfs destroy -r {} 2>>/tmp/cachyos-install.log"), zdataset), true);
#else #else
spdlog::debug("zfs destroy -r {}", zdataset); spdlog::debug("zfs destroy -r {}", zdataset);
#endif #endif
@ -236,7 +237,7 @@ void zfs_destroy_dataset(const std::string_view& zdataset) noexcept {
// returns a list of imported zpools // returns a list of imported zpools
std::string zfs_list_pools() noexcept { std::string zfs_list_pools() noexcept {
#ifdef NDEVENV #ifdef NDEVENV
return utils::exec("zfs list -H -o name 2>/dev/null | grep \"/\""sv); return gucc::utils::exec("zfs list -H -o name 2>/dev/null | grep \"/\""sv);
#else #else
return "vol0\nvol1\n"; return "vol0\nvol1\n";
#endif #endif
@ -246,12 +247,12 @@ std::string zfs_list_pools() noexcept {
std::string zfs_list_devs() noexcept { std::string zfs_list_devs() noexcept {
std::string list_of_devices{}; std::string list_of_devices{};
// get a list of devices with zpools on them // get a list of devices with zpools on them
const auto& devices = gucc::utils::make_multiline(utils::exec("zpool status -PL 2>/dev/null | awk '{print $1}' | grep \"^/\""sv)); const auto& devices = gucc::utils::make_multiline(gucc::utils::exec("zpool status -PL 2>/dev/null | awk '{print $1}' | grep \"^/\""sv));
for (const auto& device : devices) { for (const auto& device : devices) {
// add the device // add the device
list_of_devices += fmt::format(FMT_COMPILE("{}\n"), device); list_of_devices += fmt::format(FMT_COMPILE("{}\n"), device);
// now let's add any other forms of those devices // now let's add any other forms of those devices
list_of_devices += utils::exec(fmt::format(FMT_COMPILE("find -L /dev/ -xtype l -samefile {} 2>/dev/null"), device)); list_of_devices += gucc::utils::exec(fmt::format(FMT_COMPILE("find -L /dev/ -xtype l -samefile {} 2>/dev/null"), device));
} }
return list_of_devices; return list_of_devices;
} }
@ -259,12 +260,12 @@ std::string zfs_list_devs() noexcept {
std::string zfs_list_datasets(const std::string_view& type) noexcept { std::string zfs_list_datasets(const std::string_view& type) noexcept {
#ifdef NDEVENV #ifdef NDEVENV
if (type == "zvol"sv) { if (type == "zvol"sv) {
return utils::exec("zfs list -Ht volume -o name,volsize 2>/dev/null"sv); return gucc::utils::exec("zfs list -Ht volume -o name,volsize 2>/dev/null"sv);
} else if (type == "legacy"sv) { } else if (type == "legacy"sv) {
return utils::exec("zfs list -Ht filesystem -o name,mountpoint 2>/dev/null | grep \"^.*/.*legacy$\" | awk '{print $1}'"sv); return gucc::utils::exec("zfs list -Ht filesystem -o name,mountpoint 2>/dev/null | grep \"^.*/.*legacy$\" | awk '{print $1}'"sv);
} }
return utils::exec("zfs list -H -o name 2>/dev/null | grep \"/\""sv); return gucc::utils::exec("zfs list -H -o name 2>/dev/null | grep \"/\""sv);
#else #else
spdlog::debug("type := {}", type); spdlog::debug("type := {}", type);
return "zpcachyos"; return "zpcachyos";
@ -273,7 +274,7 @@ std::string zfs_list_datasets(const std::string_view& type) noexcept {
void zfs_set_property(const std::string_view& property, const std::string_view& dataset) noexcept { void zfs_set_property(const std::string_view& property, const std::string_view& dataset) noexcept {
#ifdef NDEVENV #ifdef NDEVENV
utils::exec(fmt::format(FMT_COMPILE("zfs set {} {} 2>>/tmp/cachyos-install.log"), property, dataset), true); gucc::utils::exec(fmt::format(FMT_COMPILE("zfs set {} {} 2>>/tmp/cachyos-install.log"), property, dataset), true);
#else #else
spdlog::debug("zfs set {} {}", property, dataset); spdlog::debug("zfs set {} {}", property, dataset);
#endif #endif
@ -290,7 +291,7 @@ void select_filesystem(const std::string_view& file_sys) noexcept {
config_data["FILESYSTEM"] = "mkfs.btrfs -f"; config_data["FILESYSTEM"] = "mkfs.btrfs -f";
config_data["fs_opts"] = std::vector<std::string>{"autodefrag", "compress=zlib", "compress=lzo", "compress=zstd", "compress=no", "compress-force=zlib", "compress-force=lzo", "compress-force=zstd", "discard", "noacl", "noatime", "nodatasum", "nospace_cache", "recovery", "skip_balance", "space_cache", "nossd", "ssd", "ssd_spread", "commit=120"}; config_data["fs_opts"] = std::vector<std::string>{"autodefrag", "compress=zlib", "compress=lzo", "compress=zstd", "compress=no", "compress-force=zlib", "compress-force=lzo", "compress-force=zstd", "discard", "noacl", "noatime", "nodatasum", "nospace_cache", "recovery", "skip_balance", "space_cache", "nossd", "ssd", "ssd_spread", "commit=120"};
#ifdef NDEVENV #ifdef NDEVENV
utils::exec("modprobe btrfs"sv); gucc::utils::exec("modprobe btrfs"sv);
#endif #endif
} else if (file_sys == "ext4"sv) { } else if (file_sys == "ext4"sv) {
config_data["FILESYSTEM"] = "mkfs.ext4 -q"; config_data["FILESYSTEM"] = "mkfs.ext4 -q";
@ -299,7 +300,7 @@ void select_filesystem(const std::string_view& file_sys) noexcept {
config_data["FILESYSTEM"] = "mkfs.f2fs -q"; config_data["FILESYSTEM"] = "mkfs.f2fs -q";
config_data["fs_opts"] = std::vector<std::string>{"data_flush", "disable_roll_forward", "disable_ext_identify", "discard", "fastboot", "flush_merge", "inline_xattr", "inline_data", "inline_dentry", "no_heap", "noacl", "nobarrier", "noextent_cache", "noinline_data", "norecovery"}; config_data["fs_opts"] = std::vector<std::string>{"data_flush", "disable_roll_forward", "disable_ext_identify", "discard", "fastboot", "flush_merge", "inline_xattr", "inline_data", "inline_dentry", "no_heap", "noacl", "nobarrier", "noextent_cache", "noinline_data", "norecovery"};
#ifdef NDEVENV #ifdef NDEVENV
utils::exec("modprobe f2fs"sv); gucc::utils::exec("modprobe f2fs"sv);
#endif #endif
} else if (file_sys == "xfs"sv) { } else if (file_sys == "xfs"sv) {
config_data["FILESYSTEM"] = "mkfs.xfs -f"; config_data["FILESYSTEM"] = "mkfs.xfs -f";

View File

@ -3,6 +3,9 @@
#include "tui.hpp" // for init #include "tui.hpp" // for init
#include "utils.hpp" // for exec, check_root, clear_sc... #include "utils.hpp" // for exec, check_root, clear_sc...
// import gucc
#include "gucc/io_utils.hpp"
#include <chrono> // for seconds #include <chrono> // for seconds
#include <regex> // for regex_search, match_result... #include <regex> // for regex_search, match_result...
#include <thread> // for sleep_for #include <thread> // for sleep_for
@ -13,10 +16,10 @@
#include <spdlog/spdlog.h> // for set_default_logger, set_level #include <spdlog/spdlog.h> // for set_default_logger, set_level
int main() { int main() {
const auto& tty = utils::exec("tty"); const auto& tty = gucc::utils::exec("tty");
const std::regex tty_regex("/dev/tty[0-9]*"); const std::regex tty_regex("/dev/tty[0-9]*");
if (std::regex_search(tty, tty_regex)) { if (std::regex_search(tty, tty_regex)) {
utils::exec("setterm -blank 0 -powersave off"); gucc::utils::exec("setterm -blank 0 -powersave off");
} }
// Check if installer has enough permissions. // Check if installer has enough permissions.

View File

@ -3,6 +3,9 @@
#include "utils.hpp" #include "utils.hpp"
#include "widgets.hpp" #include "widgets.hpp"
// import gucc
#include "gucc/io_utils.hpp"
/* clang-format off */ /* clang-format off */
#include <filesystem> // for exists, is_directory #include <filesystem> // for exists, is_directory
#include <ftxui/component/component.hpp> // for Renderer, Button #include <ftxui/component/component.hpp> // for Renderer, Button
@ -37,7 +40,7 @@ void edit_mkinitcpio(ScreenInteractive& screen) noexcept {
const std::string& mountpoint = "/"; const std::string& mountpoint = "/";
#endif #endif
utils::exec(fmt::format(FMT_COMPILE("vim \"{}/etc/mkinitcpio.conf\""), mountpoint), true); gucc::utils::exec(fmt::format(FMT_COMPILE("vim \"{}/etc/mkinitcpio.conf\""), mountpoint), true);
screen.Resume(); screen.Resume();
static constexpr auto content = "\nRun mkinitcpio?\n"sv; static constexpr auto content = "\nRun mkinitcpio?\n"sv;
@ -57,7 +60,7 @@ void edit_grub(ScreenInteractive& screen) noexcept {
const std::string& mountpoint = "/"; const std::string& mountpoint = "/";
#endif #endif
utils::exec(fmt::format(FMT_COMPILE("vim \"{}/etc/default/grub\""), mountpoint), true); gucc::utils::exec(fmt::format(FMT_COMPILE("vim \"{}/etc/default/grub\""), mountpoint), true);
screen.Resume(); screen.Resume();
static constexpr auto content = "\nUpdate GRUB?\n"sv; static constexpr auto content = "\nUpdate GRUB?\n"sv;
@ -74,7 +77,7 @@ namespace tui {
// Revised to deal with partition sizes now being displayed to the user // Revised to deal with partition sizes now being displayed to the user
bool confirm_mount([[maybe_unused]] const std::string_view& part_user, bool quite) { bool confirm_mount([[maybe_unused]] const std::string_view& part_user, bool quite) {
#ifdef NDEVENV #ifdef NDEVENV
const auto& ret_status = utils::exec(fmt::format(FMT_COMPILE("mount | grep {}"), part_user), true); const auto& ret_status = gucc::utils::exec(fmt::format(FMT_COMPILE("mount | grep {}"), part_user), true);
if (!quite && (ret_status != "0"sv)) { if (!quite && (ret_status != "0"sv)) {
detail::infobox_widget("\nMount Failed!\n"sv); detail::infobox_widget("\nMount Failed!\n"sv);
std::this_thread::sleep_for(std::chrono::seconds(2)); std::this_thread::sleep_for(std::chrono::seconds(2));
@ -142,7 +145,7 @@ void edit_configs() noexcept {
bool is_custom = false, std::function<void()>&& cust_func = []() {}) { bool is_custom = false, std::function<void()>&& cust_func = []() {}) {
const auto& append_function = [&functions](const std::string& filename) { const auto& append_function = [&functions](const std::string& filename) {
/* clang-format off */ /* clang-format off */
functions.emplace_back([filename]{ utils::exec(fmt::format(FMT_COMPILE("vim {}"), filename), true); }); functions.emplace_back([filename]{ gucc::utils::exec(fmt::format(FMT_COMPILE("vim {}"), filename), true); });
/* clang-format on */ /* clang-format on */
}; };
/* clang-format off */ /* clang-format off */
@ -215,12 +218,12 @@ void edit_configs() noexcept {
} }
void edit_pacman_conf() noexcept { void edit_pacman_conf() noexcept {
utils::exec("vim /etc/pacman.conf"sv, true); gucc::utils::exec("vim /etc/pacman.conf"sv, true);
#ifdef NDEVENV #ifdef NDEVENV
// NOTE: don't care now, Will change in future.. // NOTE: don't care now, Will change in future..
detail::infobox_widget("\nUpdating database ...\n"sv); detail::infobox_widget("\nUpdating database ...\n"sv);
utils::exec("pacman -Syy"sv, true); gucc::utils::exec("pacman -Syy"sv, true);
#endif #endif
} }
@ -247,16 +250,16 @@ void logs_menu() noexcept {
screen.Suspend(); screen.Suspend();
switch (selected) { switch (selected) {
case 0: case 0:
utils::exec(fmt::format(FMT_COMPILE("arch-chroot {} dmesg | fzf --reverse --header=\"Exit by pressing esc\" --prompt=\"Type to filter log entries > \""), mountpoint), true); gucc::utils::exec(fmt::format(FMT_COMPILE("arch-chroot {} dmesg | fzf --reverse --header=\"Exit by pressing esc\" --prompt=\"Type to filter log entries > \""), mountpoint), true);
break; break;
case 1: case 1:
utils::exec(fmt::format(FMT_COMPILE("fzf --reverse --header=\"Exit by pressing esc\" --prompt=\"Type to filter log entries > \" < {}/var/log/pacman.log"), mountpoint), true); gucc::utils::exec(fmt::format(FMT_COMPILE("fzf --reverse --header=\"Exit by pressing esc\" --prompt=\"Type to filter log entries > \" < {}/var/log/pacman.log"), mountpoint), true);
break; break;
case 2: case 2:
utils::exec(fmt::format(FMT_COMPILE("fzf --reverse --header=\"Exit by pressing esc\" --prompt=\"Type to filter log entries > \" < {}/var/log/Xorg.0.log"), mountpoint), true); gucc::utils::exec(fmt::format(FMT_COMPILE("fzf --reverse --header=\"Exit by pressing esc\" --prompt=\"Type to filter log entries > \" < {}/var/log/Xorg.0.log"), mountpoint), true);
break; break;
case 3: case 3:
utils::exec(fmt::format(FMT_COMPILE("arch-chroot {} journalctl | fzf --reverse --header=\"Exit by pressing esc\" --prompt=\"Type to filter log entries > \""), mountpoint), true); gucc::utils::exec(fmt::format(FMT_COMPILE("arch-chroot {} journalctl | fzf --reverse --header=\"Exit by pressing esc\" --prompt=\"Type to filter log entries > \""), mountpoint), true);
break; break;
default: default:
screen.Resume(); screen.Resume();

View File

@ -6,6 +6,7 @@
#include "widgets.hpp" #include "widgets.hpp"
// import gucc // import gucc
#include "gucc/io_utils.hpp"
#include "gucc/string_utils.hpp" #include "gucc/string_utils.hpp"
/* clang-format off */ /* clang-format off */
@ -128,10 +129,10 @@ void make_esp(const std::string& part_name, std::string_view bootloader_name, bo
config_data["UEFI_PART"] = partition; config_data["UEFI_PART"] = partition;
// If it is already a fat/vfat partition... // If it is already a fat/vfat partition...
const auto& ret_status = utils::exec(fmt::format(FMT_COMPILE("fsck -N {} | grep fat &>/dev/null"), partition), true); const auto& ret_status = gucc::utils::exec(fmt::format(FMT_COMPILE("fsck -N {} | grep fat &>/dev/null"), partition), true);
if (ret_status != "0" && reformat_part) { if (ret_status != "0" && reformat_part) {
#ifdef NDEVENV #ifdef NDEVENV
utils::exec(fmt::format(FMT_COMPILE("mkfs.vfat -F32 {} &>/dev/null"), partition)); gucc::utils::exec(fmt::format(FMT_COMPILE("mkfs.vfat -F32 {} &>/dev/null"), partition));
#endif #endif
spdlog::debug("Formating boot partition with fat/vfat!"); spdlog::debug("Formating boot partition with fat/vfat!");
} }
@ -140,8 +141,8 @@ void make_esp(const std::string& part_name, std::string_view bootloader_name, bo
const auto& mountpoint_info = std::get<std::string>(config_data["MOUNTPOINT"]); const auto& mountpoint_info = std::get<std::string>(config_data["MOUNTPOINT"]);
const auto& path_formatted = fmt::format(FMT_COMPILE("{}{}"), mountpoint_info, uefi_mount); const auto& path_formatted = fmt::format(FMT_COMPILE("{}{}"), mountpoint_info, uefi_mount);
utils::exec(fmt::format(FMT_COMPILE("mkdir -p {}"), path_formatted)); gucc::utils::exec(fmt::format(FMT_COMPILE("mkdir -p {}"), path_formatted));
utils::exec(fmt::format(FMT_COMPILE("mount {} {}"), partition, path_formatted)); gucc::utils::exec(fmt::format(FMT_COMPILE("mount {} {}"), partition, path_formatted));
#endif #endif
} }
@ -188,7 +189,7 @@ auto make_partitions_prepared(std::string_view bootloader, std::string_view root
if (root_fs == "btrfs"sv) { if (root_fs == "btrfs"sv) {
// Check if there are subvolumes already on the btrfs partition // Check if there are subvolumes already on the btrfs partition
const auto& subvolumes = fmt::format(FMT_COMPILE("btrfs subvolume list \"{}\" 2>/dev/null"), part_mountpoint); const auto& subvolumes = fmt::format(FMT_COMPILE("btrfs subvolume list \"{}\" 2>/dev/null"), part_mountpoint);
const auto& subvolumes_count = utils::exec(fmt::format(FMT_COMPILE("{} | wc -l"), subvolumes)); const auto& subvolumes_count = gucc::utils::exec(fmt::format(FMT_COMPILE("{} | wc -l"), subvolumes));
const auto& lines_count = utils::to_int(subvolumes_count.data()); const auto& lines_count = utils::to_int(subvolumes_count.data());
if (lines_count > 1) { if (lines_count > 1) {
// Pre-existing subvolumes and user wants to mount them // Pre-existing subvolumes and user wants to mount them
@ -212,7 +213,7 @@ auto make_partitions_prepared(std::string_view bootloader, std::string_view root
// 2 = separate lvm boot. For Grub configuration // 2 = separate lvm boot. For Grub configuration
if (part_mountpoint == "/boot"sv) { if (part_mountpoint == "/boot"sv) {
const auto& cmd = fmt::format(FMT_COMPILE("lsblk -lno TYPE {} | grep \"lvm\""), part_name); const auto& cmd = fmt::format(FMT_COMPILE("lsblk -lno TYPE {} | grep \"lvm\""), part_name);
const auto& cmd_out = utils::exec(cmd); const auto& cmd_out = gucc::utils::exec(cmd);
config_data["LVM_SEP_BOOT"] = 1; config_data["LVM_SEP_BOOT"] = 1;
if (!cmd_out.empty()) { if (!cmd_out.empty()) {
config_data["LVM_SEP_BOOT"] = 2; config_data["LVM_SEP_BOOT"] = 2;
@ -342,7 +343,7 @@ void menu_simple() noexcept {
utils::umount_partitions(); utils::umount_partitions();
// We need to remount the zfs filesystems that have defined mountpoints already // We need to remount the zfs filesystems that have defined mountpoints already
utils::exec("zfs mount -aO &>/dev/null"); gucc::utils::exec("zfs mount -aO &>/dev/null");
// Get list of available partitions // Get list of available partitions
utils::find_partitions(); utils::find_partitions();
@ -388,7 +389,7 @@ void menu_simple() noexcept {
/*if (utils::get_mountpoint_fs(mountpoint) == "btrfs") { /*if (utils::get_mountpoint_fs(mountpoint) == "btrfs") {
// Check if there are subvolumes already on the btrfs partition // Check if there are subvolumes already on the btrfs partition
const auto& subvolumes = fmt::format(FMT_COMPILE("btrfs subvolume list \"{}\" 2>/dev/null"), mountpoint); const auto& subvolumes = fmt::format(FMT_COMPILE("btrfs subvolume list \"{}\" 2>/dev/null"), mountpoint);
const auto& subvolumes_count = utils::exec(fmt::format(FMT_COMPILE("{} | wc -l"), subvolumes)); const auto& subvolumes_count = gucc::utils::exec(fmt::format(FMT_COMPILE("{} | wc -l"), subvolumes));
const auto& lines_count = utils::to_int(subvolumes_count.data()); const auto& lines_count = utils::to_int(subvolumes_count.data());
if (lines_count > 1) { if (lines_count > 1) {
// Pre-existing subvolumes and user wants to mount them // Pre-existing subvolumes and user wants to mount them
@ -473,7 +474,7 @@ void menu_simple() noexcept {
// so that output will be synchronized. // so that output will be synchronized.
auto logger = spdlog::get("cachyos_logger"); auto logger = spdlog::get("cachyos_logger");
logger->flush(); logger->flush();
utils::exec(fmt::format(FMT_COMPILE("{} &>>/tmp/cachyos-install.log"), post_install), true); gucc::utils::exec(fmt::format(FMT_COMPILE("{} &>>/tmp/cachyos-install.log"), post_install), true);
} }
tui::exit_done(); tui::exit_done();

View File

@ -10,6 +10,7 @@
#include "widgets.hpp" #include "widgets.hpp"
// import gucc // import gucc
#include "gucc/io_utils.hpp"
#include "gucc/string_utils.hpp" #include "gucc/string_utils.hpp"
#include <fmt/compile.h> #include <fmt/compile.h>
@ -175,7 +176,7 @@ void set_hostname() noexcept {
// Set system language // Set system language
void set_locale() noexcept { void set_locale() noexcept {
const auto& locales = gucc::utils::make_multiline(utils::exec("cat /etc/locale.gen | grep -v \"# \" | sed 's/#//g' | awk '/UTF-8/ {print $1}'")); const auto& locales = gucc::utils::make_multiline(gucc::utils::exec("cat /etc/locale.gen | grep -v \"# \" | sed 's/#//g' | awk '/UTF-8/ {print $1}'"));
// System language // System language
std::string locale{}; std::string locale{};
@ -209,7 +210,7 @@ void set_xkbmap() noexcept {
std::string xkbmap_choice{}; std::string xkbmap_choice{};
auto ok_callback = [&] { auto ok_callback = [&] {
const auto& keymap = xkbmap_list[static_cast<std::size_t>(selected)]; const auto& keymap = xkbmap_list[static_cast<std::size_t>(selected)];
xkbmap_choice = utils::exec(fmt::format(FMT_COMPILE("echo \"{}\" | sed 's/_.*//'"), keymap)); xkbmap_choice = gucc::utils::exec(fmt::format(FMT_COMPILE("echo \"{}\" | sed 's/_.*//'"), keymap));
success = true; success = true;
screen.ExitLoopClosure()(); screen.ExitLoopClosure()();
}; };
@ -238,7 +239,7 @@ void select_keymap() noexcept {
if (!keep_default) { return; } if (!keep_default) { return; }
/* clang-format on */ /* clang-format on */
const auto& keymaps = gucc::utils::make_multiline(utils::exec(R"(ls -R /usr/share/kbd/keymaps | grep "map.gz" | sed 's/\.map\.gz//g' | sort)")); const auto& keymaps = gucc::utils::make_multiline(gucc::utils::exec(R"(ls -R /usr/share/kbd/keymaps | grep "map.gz" | sed 's/\.map\.gz//g' | sort)"));
auto screen = ScreenInteractive::Fullscreen(); auto screen = ScreenInteractive::Fullscreen();
std::int32_t selected{226}; std::int32_t selected{226};
@ -257,7 +258,7 @@ bool set_timezone() noexcept {
std::string zone{}; std::string zone{};
{ {
auto screen = ScreenInteractive::Fullscreen(); auto screen = ScreenInteractive::Fullscreen();
const auto& cmd = utils::exec(R"(cat /usr/share/zoneinfo/zone.tab | awk '{print $3}' | grep "/" | sed "s/\/.*//g" | sort -ud)"); const auto& cmd = gucc::utils::exec(R"(cat /usr/share/zoneinfo/zone.tab | awk '{print $3}' | grep "/" | sed "s/\/.*//g" | sort -ud)");
const auto& zone_list = gucc::utils::make_multiline(cmd); const auto& zone_list = gucc::utils::make_multiline(cmd);
std::int32_t selected{}; std::int32_t selected{};
@ -277,7 +278,7 @@ bool set_timezone() noexcept {
std::string subzone{}; std::string subzone{};
{ {
auto screen = ScreenInteractive::Fullscreen(); auto screen = ScreenInteractive::Fullscreen();
const auto& cmd = utils::exec(fmt::format(FMT_COMPILE("cat /usr/share/zoneinfo/zone.tab | {1} | grep \"{0}/\" | sed \"s/{0}\\///g\" | sort -ud"), zone, "awk '{print $3}'")); const auto& cmd = gucc::utils::exec(fmt::format(FMT_COMPILE("cat /usr/share/zoneinfo/zone.tab | {1} | grep \"{0}/\" | sed \"s/{0}\\///g\" | sort -ud"), zone, "awk '{print $3}'"));
const auto& city_list = gucc::utils::make_multiline(cmd); const auto& city_list = gucc::utils::make_multiline(cmd);
std::int32_t selected{}; std::int32_t selected{};
@ -465,9 +466,9 @@ void chroot_interactive() noexcept {
const auto& mountpoint = std::get<std::string>(config_data["MOUNTPOINT"]); const auto& mountpoint = std::get<std::string>(config_data["MOUNTPOINT"]);
const auto& cmd_formatted = fmt::format(FMT_COMPILE("arch-chroot {} bash"), mountpoint); const auto& cmd_formatted = fmt::format(FMT_COMPILE("arch-chroot {} bash"), mountpoint);
utils::exec(cmd_formatted, true); gucc::utils::exec(cmd_formatted, true);
#else #else
utils::exec("bash", true); gucc::utils::exec("bash", true);
#endif #endif
} }
@ -479,7 +480,7 @@ void install_grub_uefi() noexcept {
/* clang-format on */ /* clang-format on */
std::string bootid{"cachyos"}; std::string bootid{"cachyos"};
auto ret_status = utils::exec("efibootmgr | cut -d\\ -f2 | grep -q -o cachyos", true); auto ret_status = gucc::utils::exec("efibootmgr | cut -d\\ -f2 | grep -q -o cachyos", true);
if (ret_status == "0"sv) { if (ret_status == "0"sv) {
static constexpr auto bootid_content = "\nInput the name identify your grub installation. Choosing an existing name overwrites it.\n"sv; static constexpr auto bootid_content = "\nInput the name identify your grub installation. Choosing an existing name overwrites it.\n"sv;
if (!detail::inputbox_widget(bootid, bootid_content, size(ftxui::HEIGHT, ftxui::LESS_THAN, 9) | size(ftxui::WIDTH, ftxui::LESS_THAN, 30))) { if (!detail::inputbox_widget(bootid, bootid_content, size(ftxui::HEIGHT, ftxui::LESS_THAN, 9) | size(ftxui::WIDTH, ftxui::LESS_THAN, 30))) {
@ -544,7 +545,7 @@ void uefi_bootloader() noexcept {
static constexpr auto efi_path = "/sys/firmware/efi/"sv; static constexpr auto efi_path = "/sys/firmware/efi/"sv;
if (fs::exists(efi_path) && fs::is_directory(efi_path)) { if (fs::exists(efi_path) && fs::is_directory(efi_path)) {
// Mount efivarfs if it is not already mounted // Mount efivarfs if it is not already mounted
const auto& mount_out = utils::exec("mount | grep /sys/firmware/efi/efivars"); const auto& mount_out = gucc::utils::exec("mount | grep /sys/firmware/efi/efivars");
if (mount_out.empty() && (mount("efivarfs", "/sys/firmware/efi/efivars", "efivarfs", 0, "") != 0)) { if (mount_out.empty() && (mount("efivarfs", "/sys/firmware/efi/efivars", "efivarfs", 0, "") != 0)) {
perror("utils::uefi_bootloader"); perror("utils::uefi_bootloader");
exit(1); exit(1);
@ -608,16 +609,16 @@ void install_base() noexcept {
std::string packages{}; std::string packages{};
auto ok_callback = [&] { auto ok_callback = [&] {
packages = detail::from_checklist_string(available_kernels, kernels_state.get()); packages = detail::from_checklist_string(available_kernels, kernels_state.get());
auto ret_status = utils::exec(fmt::format(FMT_COMPILE("echo \"{}\" | grep \"linux\""), packages), true); auto ret_status = gucc::utils::exec(fmt::format(FMT_COMPILE("echo \"{}\" | grep \"linux\""), packages), true);
if (ret_status != "0") { if (ret_status != "0") {
// Check if a kernel is already installed // Check if a kernel is already installed
ret_status = utils::exec(fmt::format(FMT_COMPILE("ls {}/boot/*.img >/dev/null 2>&1"), mountpoint), true); ret_status = gucc::utils::exec(fmt::format(FMT_COMPILE("ls {}/boot/*.img >/dev/null 2>&1"), mountpoint), true);
if (ret_status != "0") { if (ret_status != "0") {
static constexpr auto ErrNoKernel = "\nAt least one kernel must be selected.\n"sv; static constexpr auto ErrNoKernel = "\nAt least one kernel must be selected.\n"sv;
detail::msgbox_widget(ErrNoKernel); detail::msgbox_widget(ErrNoKernel);
return; return;
} }
const auto& cmd = utils::exec(fmt::format(FMT_COMPILE("ls {}/boot/*.img | cut -d'-' -f2 | grep -v ucode.img | sort -u"), mountpoint)); const auto& cmd = gucc::utils::exec(fmt::format(FMT_COMPILE("ls {}/boot/*.img | cut -d'-' -f2 | grep -v ucode.img | sort -u"), mountpoint));
detail::msgbox_widget(fmt::format(FMT_COMPILE("\nlinux-{} detected\n"), cmd)); detail::msgbox_widget(fmt::format(FMT_COMPILE("\nlinux-{} detected\n"), cmd));
screen.ExitLoopClosure()(); screen.ExitLoopClosure()();
} }
@ -766,14 +767,14 @@ void bios_bootloader() {
void enable_autologin() { void enable_autologin() {
// Detect display manager // Detect display manager
const auto& dm = utils::exec("file /mnt/etc/systemd/system/display-manager.service 2>/dev/null | awk -F'/' '{print $NF}' | cut -d. -f1"); const auto& dm = gucc::utils::exec("file /mnt/etc/systemd/system/display-manager.service 2>/dev/null | awk -F'/' '{print $NF}' | cut -d. -f1");
const auto& content = fmt::format(FMT_COMPILE("\nThis option enables autologin using {}.\n\nProceed?\n"), dm); const auto& content = fmt::format(FMT_COMPILE("\nThis option enables autologin using {}.\n\nProceed?\n"), dm);
/* clang-format off */ /* clang-format off */
if (!detail::yesno_widget(content, size(HEIGHT, LESS_THAN, 15) | size(WIDTH, LESS_THAN, 75))) { return; } if (!detail::yesno_widget(content, size(HEIGHT, LESS_THAN, 15) | size(WIDTH, LESS_THAN, 75))) { return; }
if (utils::exec("echo /mnt/home/* | xargs -n1 | wc -l") != "1") { return; } if (gucc::utils::exec("echo /mnt/home/* | xargs -n1 | wc -l") != "1") { return; }
/* clang-format on */ /* clang-format on */
const auto& autologin_user = utils::exec("echo /mnt/home/* | cut -d/ -f4"); const auto& autologin_user = gucc::utils::exec("echo /mnt/home/* | cut -d/ -f4");
utils::enable_autologin(dm, autologin_user); utils::enable_autologin(dm, autologin_user);
} }
@ -859,13 +860,13 @@ void auto_partition() noexcept {
utils::auto_partition(); utils::auto_partition();
// Show created partitions // Show created partitions
const auto& disk_list = utils::exec(fmt::format(FMT_COMPILE("lsblk {} -o NAME,TYPE,FSTYPE,SIZE"), device_info)); const auto& disk_list = gucc::utils::exec(fmt::format(FMT_COMPILE("lsblk {} -o NAME,TYPE,FSTYPE,SIZE"), device_info));
detail::msgbox_widget(disk_list, size(HEIGHT, GREATER_THAN, 5)); detail::msgbox_widget(disk_list, size(HEIGHT, GREATER_THAN, 5));
} }
// Simple code to show devices / partitions. // Simple code to show devices / partitions.
void show_devices() noexcept { void show_devices() noexcept {
const auto& lsblk = utils::exec(R"(lsblk -o NAME,MODEL,TYPE,FSTYPE,SIZE,MOUNTPOINT | grep "disk\|part\|lvm\|crypt\|NAME\|MODEL\|TYPE\|FSTYPE\|SIZE\|MOUNTPOINT")"); const auto& lsblk = gucc::utils::exec(R"(lsblk -o NAME,MODEL,TYPE,FSTYPE,SIZE,MOUNTPOINT | grep "disk\|part\|lvm\|crypt\|NAME\|MODEL\|TYPE\|FSTYPE\|SIZE\|MOUNTPOINT")");
detail::msgbox_widget(lsblk, size(HEIGHT, GREATER_THAN, 5)); detail::msgbox_widget(lsblk, size(HEIGHT, GREATER_THAN, 5));
} }
@ -883,7 +884,7 @@ void refresh_pacman_keys() noexcept {
bool select_device() noexcept { bool select_device() noexcept {
auto* config_instance = Config::instance(); auto* config_instance = Config::instance();
auto& config_data = config_instance->data(); auto& config_data = config_instance->data();
auto devices = utils::exec(R"(lsblk -lno NAME,SIZE,TYPE | grep 'disk' | awk '{print "/dev/" $1 " " $2}' | sort -u)"); auto devices = gucc::utils::exec(R"(lsblk -lno NAME,SIZE,TYPE | grep 'disk' | awk '{print "/dev/" $1 " " $2}' | sort -u)");
const auto& devices_list = gucc::utils::make_multiline(devices); const auto& devices_list = gucc::utils::make_multiline(devices);
auto screen = ScreenInteractive::Fullscreen(); auto screen = ScreenInteractive::Fullscreen();
@ -942,7 +943,7 @@ bool select_filesystem() noexcept {
const auto& do_mount = detail::yesno_widget(content, size(HEIGHT, LESS_THAN, 15) | size(WIDTH, LESS_THAN, 75)); const auto& do_mount = detail::yesno_widget(content, size(HEIGHT, LESS_THAN, 15) | size(WIDTH, LESS_THAN, 75));
if (do_mount) { if (do_mount) {
#ifdef NDEVENV #ifdef NDEVENV
utils::exec(fmt::format(FMT_COMPILE("{} {}"), file_sys, partition)); gucc::utils::exec(fmt::format(FMT_COMPILE("{} {}"), file_sys, partition));
#endif #endif
spdlog::info("mount.{} {}", partition, file_sys); spdlog::info("mount.{} {}", partition, file_sys);
} }
@ -959,10 +960,10 @@ void mount_opts(bool force) noexcept {
const auto& file_sys = std::get<std::string>(config_data["FILESYSTEM"]); const auto& file_sys = std::get<std::string>(config_data["FILESYSTEM"]);
const auto& fs_opts = std::get<std::vector<std::string>>(config_data["fs_opts"]); const auto& fs_opts = std::get<std::vector<std::string>>(config_data["fs_opts"]);
const auto& partition = std::get<std::string>(config_data["PARTITION"]); const auto& partition = std::get<std::string>(config_data["PARTITION"]);
const auto& format_name = utils::exec(fmt::format(FMT_COMPILE("echo {} | rev | cut -d/ -f1 | rev"), partition)); const auto& format_name = gucc::utils::exec(fmt::format(FMT_COMPILE("echo {} | rev | cut -d/ -f1 | rev"), partition));
const auto& format_device = utils::exec(fmt::format(FMT_COMPILE("lsblk -i | tac | sed -r 's/^[^[:alnum:]]+//' | sed -n -e \"/{}/,/disk/p\" | {}"), format_name, "awk '/disk/ {print $1}'")); const auto& format_device = gucc::utils::exec(fmt::format(FMT_COMPILE("lsblk -i | tac | sed -r 's/^[^[:alnum:]]+//' | sed -n -e \"/{}/,/disk/p\" | {}"), format_name, "awk '/disk/ {print $1}'"));
const auto& rotational_queue = (utils::exec(fmt::format(FMT_COMPILE("cat /sys/block/{}/queue/rotational"), format_device)) == "1"sv); const auto& rotational_queue = (gucc::utils::exec(fmt::format(FMT_COMPILE("cat /sys/block/{}/queue/rotational"), format_device)) == "1"sv);
std::unique_ptr<bool[]> fs_opts_state{new bool[fs_opts.size()]{false}}; std::unique_ptr<bool[]> fs_opts_state{new bool[fs_opts.size()]{false}};
for (size_t i = 0; i < fs_opts.size(); ++i) { for (size_t i = 0; i < fs_opts.size(); ++i) {
@ -988,8 +989,8 @@ void mount_opts(bool force) noexcept {
// Now clean up the file // Now clean up the file
auto cleaup_mount_opts = [](auto& opts_info) { auto cleaup_mount_opts = [](auto& opts_info) {
opts_info = utils::exec(fmt::format(FMT_COMPILE("echo \"{}\" | sed 's/ /,/g'"), opts_info)); opts_info = gucc::utils::exec(fmt::format(FMT_COMPILE("echo \"{}\" | sed 's/ /,/g'"), opts_info));
opts_info = utils::exec(fmt::format(FMT_COMPILE("echo \"{}\" | sed '$s/,$//'"), opts_info)); opts_info = gucc::utils::exec(fmt::format(FMT_COMPILE("echo \"{}\" | sed '$s/,$//'"), opts_info));
}; };
if (force) { if (force) {
@ -1004,7 +1005,7 @@ void mount_opts(bool force) noexcept {
screen.ExitLoopClosure()(); screen.ExitLoopClosure()();
}; };
const auto& file_sys_formatted = utils::exec(fmt::format(FMT_COMPILE("echo {} | sed \"s/.*\\.//g;s/-.*//g\""), file_sys)); const auto& file_sys_formatted = gucc::utils::exec(fmt::format(FMT_COMPILE("echo {} | sed \"s/.*\\.//g;s/-.*//g\""), file_sys));
const auto& fs_title = fmt::format(FMT_COMPILE("New CLI Installer | {}"), file_sys_formatted); const auto& fs_title = fmt::format(FMT_COMPILE("New CLI Installer | {}"), file_sys_formatted);
auto content_size = size(HEIGHT, GREATER_THAN, 10) | size(WIDTH, GREATER_THAN, 40) | vscroll_indicator | yframe | flex; auto content_size = size(HEIGHT, GREATER_THAN, 10) | size(WIDTH, GREATER_THAN, 40) | vscroll_indicator | yframe | flex;
@ -1052,11 +1053,11 @@ bool mount_current_partition(bool force) noexcept {
const auto& mount_opts_info = std::get<std::string>(config_data["MOUNT_OPTS"]); const auto& mount_opts_info = std::get<std::string>(config_data["MOUNT_OPTS"]);
if (!mount_opts_info.empty()) { if (!mount_opts_info.empty()) {
// check_for_error "mount ${PARTITION} $(cat ${MOUNT_OPTS})" // check_for_error "mount ${PARTITION} $(cat ${MOUNT_OPTS})"
const auto& mount_status = utils::exec(fmt::format(FMT_COMPILE("mount -o {} {} {}{}"), mount_opts_info, partition, mountpoint, mount_dev)); const auto& mount_status = gucc::utils::exec(fmt::format(FMT_COMPILE("mount -o {} {} {}{}"), mount_opts_info, partition, mountpoint, mount_dev));
spdlog::info("{}", mount_status); spdlog::info("{}", mount_status);
} else { } else {
// check_for_error "mount ${PARTITION}" // check_for_error "mount ${PARTITION}"
const auto& mount_status = utils::exec(fmt::format(FMT_COMPILE("mount {} {}{}"), partition, mountpoint, mount_dev)); const auto& mount_status = gucc::utils::exec(fmt::format(FMT_COMPILE("mount {} {}{}"), partition, mountpoint, mount_dev));
spdlog::info("{}", mount_status); spdlog::info("{}", mount_status);
} }
#endif #endif
@ -1066,15 +1067,15 @@ bool mount_current_partition(bool force) noexcept {
/* clang-format on */ /* clang-format on */
// Identify if mounted partition is type "crypt" (LUKS on LVM, or LUKS alone) // Identify if mounted partition is type "crypt" (LUKS on LVM, or LUKS alone)
if (!utils::exec(fmt::format(FMT_COMPILE("lsblk -lno TYPE {} | grep \"crypt\""), partition)).empty()) { if (!gucc::utils::exec(fmt::format(FMT_COMPILE("lsblk -lno TYPE {} | grep \"crypt\""), partition)).empty()) {
// cryptname for bootloader configuration either way // cryptname for bootloader configuration either way
config_data["LUKS"] = 1; config_data["LUKS"] = 1;
auto& luks_name = std::get<std::string>(config_data["LUKS_NAME"]); auto& luks_name = std::get<std::string>(config_data["LUKS_NAME"]);
const auto& luks_dev = std::get<std::string>(config_data["LUKS_DEV"]); const auto& luks_dev = std::get<std::string>(config_data["LUKS_DEV"]);
luks_name = utils::exec(fmt::format(FMT_COMPILE("echo {} | sed \"s~^/dev/mapper/~~g\""), partition)); luks_name = gucc::utils::exec(fmt::format(FMT_COMPILE("echo {} | sed \"s~^/dev/mapper/~~g\""), partition));
const auto& check_cryptparts = [&](const auto cryptparts, auto functor) { const auto& check_cryptparts = [&](const auto cryptparts, auto functor) {
for (const auto& cryptpart : cryptparts) { for (const auto& cryptpart : cryptparts) {
if (!utils::exec(fmt::format(FMT_COMPILE("lsblk -lno NAME {} | grep \"{}\""), cryptpart, luks_name)).empty()) { if (!gucc::utils::exec(fmt::format(FMT_COMPILE("lsblk -lno NAME {} | grep \"{}\""), cryptpart, luks_name)).empty()) {
functor(cryptpart); functor(cryptpart);
return true; return true;
} }
@ -1083,7 +1084,7 @@ bool mount_current_partition(bool force) noexcept {
}; };
// Check if LUKS on LVM (parent = lvm /dev/mapper/...) // Check if LUKS on LVM (parent = lvm /dev/mapper/...)
auto cryptparts = gucc::utils::make_multiline(utils::exec(R"(lsblk -lno NAME,FSTYPE,TYPE | grep "lvm" | grep -i "crypto_luks" | uniq | awk '{print "/dev/mapper/"$1}')")); auto cryptparts = gucc::utils::make_multiline(gucc::utils::exec(R"(lsblk -lno NAME,FSTYPE,TYPE | grep "lvm" | grep -i "crypto_luks" | uniq | awk '{print "/dev/mapper/"$1}')"));
auto check_functor = [&](const auto cryptpart) { auto check_functor = [&](const auto cryptpart) {
config_data["LUKS_DEV"] = fmt::format(FMT_COMPILE("{} cryptdevice={}:{}"), luks_dev, cryptpart, luks_name); config_data["LUKS_DEV"] = fmt::format(FMT_COMPILE("{} cryptdevice={}:{}"), luks_dev, cryptpart, luks_name);
config_data["LVM"] = 1; config_data["LVM"] = 1;
@ -1093,16 +1094,16 @@ bool mount_current_partition(bool force) noexcept {
} }
// Check if LVM on LUKS // Check if LVM on LUKS
cryptparts = gucc::utils::make_multiline(utils::exec(R"(lsblk -lno NAME,FSTYPE,TYPE | grep " crypt$" | grep -i "LVM2_member" | uniq | awk '{print "/dev/mapper/"$1}')")); cryptparts = gucc::utils::make_multiline(gucc::utils::exec(R"(lsblk -lno NAME,FSTYPE,TYPE | grep " crypt$" | grep -i "LVM2_member" | uniq | awk '{print "/dev/mapper/"$1}')"));
if (check_cryptparts(cryptparts, check_functor)) { if (check_cryptparts(cryptparts, check_functor)) {
return true; return true;
} }
// Check if LUKS alone (parent = part /dev/...) // Check if LUKS alone (parent = part /dev/...)
cryptparts = gucc::utils::make_multiline(utils::exec(R"(lsblk -lno NAME,FSTYPE,TYPE | grep "part" | grep -i "crypto_luks" | uniq | awk '{print "/dev/"$1}')")); cryptparts = gucc::utils::make_multiline(gucc::utils::exec(R"(lsblk -lno NAME,FSTYPE,TYPE | grep "part" | grep -i "crypto_luks" | uniq | awk '{print "/dev/"$1}')"));
const auto& check_func_dev = [&](const auto cryptpart) { const auto& check_func_dev = [&](const auto cryptpart) {
auto& luks_uuid = std::get<std::string>(config_data["LUKS_UUID"]); auto& luks_uuid = std::get<std::string>(config_data["LUKS_UUID"]);
luks_uuid = utils::exec(fmt::format(FMT_COMPILE("lsblk -lno UUID,TYPE,FSTYPE {} | grep \"part\" | grep -i \"crypto_luks\" | {}"), cryptpart, "awk '{print $1}'")); luks_uuid = gucc::utils::exec(fmt::format(FMT_COMPILE("lsblk -lno UUID,TYPE,FSTYPE {} | grep \"part\" | grep -i \"crypto_luks\" | {}"), cryptpart, "awk '{print $1}'"));
config_data["LUKS_DEV"] = fmt::format(FMT_COMPILE("{} cryptdevice=UUID={}:{}"), luks_dev, luks_uuid, luks_name); config_data["LUKS_DEV"] = fmt::format(FMT_COMPILE("{} cryptdevice=UUID={}:{}"), luks_dev, luks_uuid, luks_name);
}; };
if (check_cryptparts(cryptparts, check_func_dev)) { if (check_cryptparts(cryptparts, check_func_dev)) {
@ -1186,13 +1187,13 @@ void make_swap() noexcept {
/* clang-format on */ /* clang-format on */
if (partition == sel_swap_file) { if (partition == sel_swap_file) {
const auto& total_memory = utils::exec("grep MemTotal /proc/meminfo | awk '{print $2/1024}' | sed 's/\\..*//'"); const auto& total_memory = gucc::utils::exec("grep MemTotal /proc/meminfo | awk '{print $2/1024}' | sed 's/\\..*//'");
std::string value{fmt::format(FMT_COMPILE("{}M"), total_memory)}; std::string value{fmt::format(FMT_COMPILE("{}M"), total_memory)};
if (!detail::inputbox_widget(value, "\nM = MB, G = GB\n", size(ftxui::HEIGHT, ftxui::LESS_THAN, 9) | size(ftxui::WIDTH, ftxui::LESS_THAN, 30))) { if (!detail::inputbox_widget(value, "\nM = MB, G = GB\n", size(ftxui::HEIGHT, ftxui::LESS_THAN, 9) | size(ftxui::WIDTH, ftxui::LESS_THAN, 30))) {
return; return;
} }
while (utils::exec(fmt::format(FMT_COMPILE("echo \"{}\" | grep \"M\\|G\""), value)).empty()) { while (gucc::utils::exec(fmt::format(FMT_COMPILE("echo \"{}\" | grep \"M\\|G\""), value)).empty()) {
detail::msgbox_widget(fmt::format(FMT_COMPILE("\n{} Error: M = MB, G = GB\n"), sel_swap_file)); detail::msgbox_widget(fmt::format(FMT_COMPILE("\n{} Error: M = MB, G = GB\n"), sel_swap_file));
value = fmt::format(FMT_COMPILE("{}M"), total_memory); value = fmt::format(FMT_COMPILE("{}M"), total_memory);
if (!detail::inputbox_widget(value, "\nM = MB, G = GB\n", size(ftxui::HEIGHT, ftxui::LESS_THAN, 9) | size(ftxui::WIDTH, ftxui::LESS_THAN, 30))) { if (!detail::inputbox_widget(value, "\nM = MB, G = GB\n", size(ftxui::HEIGHT, ftxui::LESS_THAN, 9) | size(ftxui::WIDTH, ftxui::LESS_THAN, 30))) {
@ -1202,10 +1203,10 @@ void make_swap() noexcept {
#ifdef NDEVENV #ifdef NDEVENV
const auto& swapfile_path = fmt::format(FMT_COMPILE("{}/swapfile"), mountpoint_info); const auto& swapfile_path = fmt::format(FMT_COMPILE("{}/swapfile"), mountpoint_info);
utils::exec(fmt::format(FMT_COMPILE("fallocate -l {} {} 2>>/tmp/cachyos-install.log &>/dev/null"), value, swapfile_path)); gucc::utils::exec(fmt::format(FMT_COMPILE("fallocate -l {} {} 2>>/tmp/cachyos-install.log &>/dev/null"), value, swapfile_path));
utils::exec(fmt::format(FMT_COMPILE("chmod 600 {} 2>>/tmp/cachyos-install.log"), swapfile_path)); gucc::utils::exec(fmt::format(FMT_COMPILE("chmod 600 {} 2>>/tmp/cachyos-install.log"), swapfile_path));
utils::exec(fmt::format(FMT_COMPILE("mkswap {} 2>>/tmp/cachyos-install.log &>/dev/null"), swapfile_path)); gucc::utils::exec(fmt::format(FMT_COMPILE("mkswap {} 2>>/tmp/cachyos-install.log &>/dev/null"), swapfile_path));
utils::exec(fmt::format(FMT_COMPILE("swapon {} 2>>/tmp/cachyos-install.log &>/dev/null"), swapfile_path)); gucc::utils::exec(fmt::format(FMT_COMPILE("swapon {} 2>>/tmp/cachyos-install.log &>/dev/null"), swapfile_path));
#endif #endif
return; return;
} }
@ -1214,7 +1215,7 @@ void make_swap() noexcept {
auto& number_partitions = std::get<std::int32_t>(config_data["NUMBER_PARTITIONS"]); auto& number_partitions = std::get<std::int32_t>(config_data["NUMBER_PARTITIONS"]);
// Warn user if creating a new swap // Warn user if creating a new swap
const auto& swap_part = utils::exec(fmt::format(FMT_COMPILE("lsblk -o FSTYPE \"{}\" | grep -i \"swap\""), partition)); const auto& swap_part = gucc::utils::exec(fmt::format(FMT_COMPILE("lsblk -o FSTYPE \"{}\" | grep -i \"swap\""), partition));
if (swap_part != "swap") { if (swap_part != "swap") {
const auto& do_swap = detail::yesno_widget(fmt::format(FMT_COMPILE("\nmkswap {}\n"), partition), size(HEIGHT, LESS_THAN, 15) | size(WIDTH, LESS_THAN, 75)); const auto& do_swap = detail::yesno_widget(fmt::format(FMT_COMPILE("\nmkswap {}\n"), partition), size(HEIGHT, LESS_THAN, 15) | size(WIDTH, LESS_THAN, 75));
/* clang-format off */ /* clang-format off */
@ -1222,14 +1223,14 @@ void make_swap() noexcept {
/* clang-format on */ /* clang-format on */
#ifdef NDEVENV #ifdef NDEVENV
utils::exec(fmt::format(FMT_COMPILE("mkswap {} &>/dev/null"), partition)); gucc::utils::exec(fmt::format(FMT_COMPILE("mkswap {} &>/dev/null"), partition));
#endif #endif
spdlog::info("mkswap.{}", partition); spdlog::info("mkswap.{}", partition);
} }
#ifdef NDEVENV #ifdef NDEVENV
// Whether existing to newly created, activate swap // Whether existing to newly created, activate swap
utils::exec(fmt::format(FMT_COMPILE("swapon {} &>/dev/null"), partition)); gucc::utils::exec(fmt::format(FMT_COMPILE("swapon {} &>/dev/null"), partition));
#endif #endif
// Since a partition was used, remove that partition from the list // Since a partition was used, remove that partition from the list
@ -1276,7 +1277,7 @@ void lvm_del_vg() noexcept {
#ifdef NDEVENV #ifdef NDEVENV
// if confirmation given, delete // if confirmation given, delete
utils::exec(fmt::format(FMT_COMPILE("vgremove -f {} 2>/dev/null"), sel_vg), true); gucc::utils::exec(fmt::format(FMT_COMPILE("vgremove -f {} 2>/dev/null"), sel_vg), true);
#endif #endif
} }
@ -1397,7 +1398,7 @@ bool zfs_create_zpool(bool do_create_zpool = true) noexcept {
} }
bool zfs_import_pool() noexcept { bool zfs_import_pool() noexcept {
const auto& zlist = gucc::utils::make_multiline(utils::exec("zpool import 2>/dev/null | grep \"^[[:space:]]*pool\" | awk -F : '{print $2}' | awk '{$1=$1};1'")); const auto& zlist = gucc::utils::make_multiline(gucc::utils::exec("zpool import 2>/dev/null | grep \"^[[:space:]]*pool\" | awk -F : '{print $2}' | awk '{$1=$1};1'"));
if (zlist.empty()) { if (zlist.empty()) {
// no available datasets // no available datasets
detail::infobox_widget("\nNo pools available\"\n"sv); detail::infobox_widget("\nNo pools available\"\n"sv);
@ -1428,7 +1429,7 @@ bool zfs_import_pool() noexcept {
#ifdef NDEVENV #ifdef NDEVENV
const auto& mountpoint = std::get<std::string>(config_data["MOUNTPOINT"]); const auto& mountpoint = std::get<std::string>(config_data["MOUNTPOINT"]);
utils::exec(fmt::format(FMT_COMPILE("zpool import -R {} {} 2>>/tmp/cachyos-install.log"), mountpoint, zfs_zpool_name), true); gucc::utils::exec(fmt::format(FMT_COMPILE("zpool import -R {} {} 2>>/tmp/cachyos-install.log"), mountpoint, zfs_zpool_name), true);
#endif #endif
config_data["ZFS"] = 1; config_data["ZFS"] = 1;
@ -1691,7 +1692,7 @@ void zfs_menu_manual() noexcept {
void zfs_menu() noexcept { void zfs_menu() noexcept {
#ifdef NDEVENV #ifdef NDEVENV
// check for zfs support // check for zfs support
if (utils::exec("modprobe zfs 2>>/tmp/cachyos-install.log &>/dev/null", true) != "0"sv) { if (gucc::utils::exec("modprobe zfs 2>>/tmp/cachyos-install.log &>/dev/null", true) != "0"sv) {
detail::infobox_widget("\nThe kernel modules to support ZFS could not be found\n"sv); detail::infobox_widget("\nThe kernel modules to support ZFS could not be found\n"sv);
std::this_thread::sleep_for(std::chrono::seconds(3)); std::this_thread::sleep_for(std::chrono::seconds(3));
return; return;
@ -1763,7 +1764,7 @@ void make_esp() noexcept {
config_data["UEFI_PART"] = partition; config_data["UEFI_PART"] = partition;
// If it is already a fat/vfat partition... // If it is already a fat/vfat partition...
const auto& ret_status = utils::exec(fmt::format(FMT_COMPILE("fsck -N {} | grep fat"), partition), true); const auto& ret_status = gucc::utils::exec(fmt::format(FMT_COMPILE("fsck -N {} | grep fat"), partition), true);
bool do_boot_partition{}; bool do_boot_partition{};
if (ret_status != "0") { if (ret_status != "0") {
const auto& content = fmt::format(FMT_COMPILE("\nThe UEFI partition {} has already been formatted.\n \nReformat? Doing so will erase ALL data already on that partition.\n"), partition); const auto& content = fmt::format(FMT_COMPILE("\nThe UEFI partition {} has already been formatted.\n \nReformat? Doing so will erase ALL data already on that partition.\n"), partition);
@ -1771,7 +1772,7 @@ void make_esp() noexcept {
} }
if (do_boot_partition) { if (do_boot_partition) {
#ifdef NDEVENV #ifdef NDEVENV
utils::exec(fmt::format(FMT_COMPILE("mkfs.vfat -F32 {} &>/dev/null"), partition)); gucc::utils::exec(fmt::format(FMT_COMPILE("mkfs.vfat -F32 {} &>/dev/null"), partition));
#endif #endif
spdlog::debug("Formating boot partition with fat/vfat!"); spdlog::debug("Formating boot partition with fat/vfat!");
} }
@ -1804,8 +1805,8 @@ void make_esp() noexcept {
uefi_mount = answer; uefi_mount = answer;
const auto& path_formatted = fmt::format(FMT_COMPILE("{}{}"), mountpoint_info, uefi_mount); const auto& path_formatted = fmt::format(FMT_COMPILE("{}{}"), mountpoint_info, uefi_mount);
#ifdef NDEVENV #ifdef NDEVENV
utils::exec(fmt::format(FMT_COMPILE("mkdir -p {}"), path_formatted)); gucc::utils::exec(fmt::format(FMT_COMPILE("mkdir -p {}"), path_formatted));
utils::exec(fmt::format(FMT_COMPILE("mount {} {}"), partition, path_formatted)); gucc::utils::exec(fmt::format(FMT_COMPILE("mount {} {}"), partition, path_formatted));
#endif #endif
confirm_mount(path_formatted); confirm_mount(path_formatted);
} }
@ -1825,7 +1826,7 @@ void mount_partitions() noexcept {
utils::umount_partitions(); utils::umount_partitions();
// We need to remount the zfs filesystems that have defined mountpoints already // We need to remount the zfs filesystems that have defined mountpoints already
utils::exec("zfs mount -aO &>/dev/null"); gucc::utils::exec("zfs mount -aO &>/dev/null");
// Get list of available partitions // Get list of available partitions
utils::find_partitions(); utils::find_partitions();
@ -1896,10 +1897,10 @@ void mount_partitions() noexcept {
if (utils::get_mountpoint_fs(mountpoint_info) == "btrfs") { if (utils::get_mountpoint_fs(mountpoint_info) == "btrfs") {
// Check if there are subvolumes already on the btrfs partition // Check if there are subvolumes already on the btrfs partition
const auto& subvolumes = fmt::format(FMT_COMPILE("btrfs subvolume list \"{}\" 2>/dev/null"), mountpoint_info); const auto& subvolumes = fmt::format(FMT_COMPILE("btrfs subvolume list \"{}\" 2>/dev/null"), mountpoint_info);
const auto& subvolumes_count = utils::exec(fmt::format(FMT_COMPILE("{} | wc -l"), subvolumes)); const auto& subvolumes_count = gucc::utils::exec(fmt::format(FMT_COMPILE("{} | wc -l"), subvolumes));
const auto& lines_count = utils::to_int(subvolumes_count); const auto& lines_count = utils::to_int(subvolumes_count);
if (lines_count > 1) { if (lines_count > 1) {
const auto& subvolumes_formated = utils::exec(fmt::format(FMT_COMPILE("{} | cut -d\" \" -f9"), subvolumes)); const auto& subvolumes_formated = gucc::utils::exec(fmt::format(FMT_COMPILE("{} | cut -d\" \" -f9"), subvolumes));
const auto& existing_subvolumes = detail::yesno_widget(fmt::format(FMT_COMPILE("\nFound subvolumes {}\n \nWould you like to mount them?\n "), subvolumes_formated), size(HEIGHT, LESS_THAN, 15) | size(WIDTH, LESS_THAN, 75)); const auto& existing_subvolumes = detail::yesno_widget(fmt::format(FMT_COMPILE("\nFound subvolumes {}\n \nWould you like to mount them?\n "), subvolumes_formated), size(HEIGHT, LESS_THAN, 15) | size(WIDTH, LESS_THAN, 75));
// Pre-existing subvolumes and user wants to mount them // Pre-existing subvolumes and user wants to mount them
/* clang-format off */ /* clang-format off */
@ -2008,7 +2009,7 @@ void mount_partitions() noexcept {
// 2 = separate lvm boot. For Grub configuration // 2 = separate lvm boot. For Grub configuration
if (mount_dev == "/boot") { if (mount_dev == "/boot") {
const auto& cmd = fmt::format(FMT_COMPILE("lsblk -lno TYPE {} | grep \"lvm\""), partition); const auto& cmd = fmt::format(FMT_COMPILE("lsblk -lno TYPE {} | grep \"lvm\""), partition);
const auto& cmd_out = utils::exec(cmd); const auto& cmd_out = gucc::utils::exec(cmd);
config_data["LVM_SEP_BOOT"] = 1; config_data["LVM_SEP_BOOT"] = 1;
if (!cmd_out.empty()) { if (!cmd_out.empty()) {
config_data["LVM_SEP_BOOT"] = 2; config_data["LVM_SEP_BOOT"] = 2;
@ -2035,7 +2036,7 @@ void configure_mirrorlist() noexcept {
break; break;
case 1: case 1:
screen.Suspend(); screen.Suspend();
utils::exec("cachyos-rate-mirrors"sv, true); gucc::utils::exec("cachyos-rate-mirrors"sv, true);
screen.Resume(); screen.Resume();
break; break;
default: default:
@ -2072,7 +2073,7 @@ void create_partitions() noexcept {
if (selected_entry != optwipe && selected_entry != optauto) { if (selected_entry != optwipe && selected_entry != optauto) {
screen.Suspend(); screen.Suspend();
#ifdef NDEVENV #ifdef NDEVENV
utils::exec(fmt::format(FMT_COMPILE("{} {}"), selected_entry, std::get<std::string>(config_data["DEVICE"])), true); gucc::utils::exec(fmt::format(FMT_COMPILE("{} {}"), selected_entry, std::get<std::string>(config_data["DEVICE"])), true);
#else #else
spdlog::debug("to be executed: {}", fmt::format(FMT_COMPILE("{} {}"), selected_entry, std::get<std::string>(config_data["DEVICE"]))); spdlog::debug("to be executed: {}", fmt::format(FMT_COMPILE("{} {}"), selected_entry, std::get<std::string>(config_data["DEVICE"])));
#endif #endif

File diff suppressed because it is too large Load Diff

View File

@ -59,10 +59,6 @@ void recheck_luks() noexcept;
void arch_chroot(const std::string_view& command, bool follow = true) noexcept; void arch_chroot(const std::string_view& command, bool follow = true) noexcept;
void exec_follow(const std::vector<std::string>& vec, std::string& process_log, bool& running, subprocess_s& child, bool async = true) noexcept; void exec_follow(const std::vector<std::string>& vec, std::string& process_log, bool& running, subprocess_s& child, bool async = true) noexcept;
void exec(const std::vector<std::string>& vec) noexcept;
auto exec(const std::string_view& command, const bool& interactive = false) noexcept -> std::string;
[[nodiscard]] auto read_whole_file(const std::string_view& filepath) noexcept -> std::string;
bool write_to_file(const std::string_view& data, const std::string_view& filepath) noexcept;
void dump_to_log(const std::string& data) noexcept; void dump_to_log(const std::string& data) noexcept;
void dump_settings_to_log() noexcept; void dump_settings_to_log() noexcept;
[[nodiscard]] bool check_root() noexcept; [[nodiscard]] bool check_root() noexcept;

View File

@ -1,8 +1,11 @@
#include "definitions.hpp" #include "definitions.hpp"
#include "utils.hpp" #include "utils.hpp"
// import gucc
#include "gucc/io_utils.hpp"
int main() { int main() {
output_inter("\n\n------ TEST BASH LAUNCH BEGIN ------\n\n"); output_inter("\n\n------ TEST BASH LAUNCH BEGIN ------\n\n");
utils::exec("bash", true); gucc::utils::exec("bash", true);
output_inter("\n\n------ TEST BASH LAUNCH END ------\n\n"); output_inter("\n\n------ TEST BASH LAUNCH END ------\n\n");
} }