👷 update deps and ui.

Also refactor code
This commit is contained in:
Vladislav Nepogodin 2021-12-15 03:19:58 +04:00
parent bb77f2bbc1
commit 61750d6e53
No known key found for this signature in database
GPG Key ID: B62C3D10C54D5DA9
6 changed files with 177 additions and 24 deletions

View File

@ -37,7 +37,7 @@ pkg_check_modules(
FetchContent_Declare(ftxui
GIT_REPOSITORY "https://github.com/arthursonzogni/ftxui.git"
GIT_TAG "602392c43d8bc2272c6548ae75b8802ab7ad0b2a"
GIT_TAG "7e5cd23b4c47972b70b99c39617d6e38f05d1b3a"
)
FetchContent_MakeAvailable(ftxui)

View File

@ -9,6 +9,7 @@
#include <algorithm> // for transform
#include <filesystem> // for exists, is_directory
#include <memory> // for __shared_ptr_access
#include <regex> // for regex_search, match_results<>::_Base_type
#include <string> // for basic_string
#include <ftxui/component/captured_mouse.hpp> // for ftxui
#include <ftxui/component/component.hpp> // for Renderer, Button
@ -432,7 +433,101 @@ bool mount_current_partition() noexcept {
return true;
}
void make_swap() noexcept { }
void make_swap() noexcept {
static constexpr auto SelSwpNone = "None";
static constexpr auto SelSwpFile = "Swapfile";
auto* config_instance = Config::instance();
auto& config_data = config_instance->data();
const auto& mountpoint_info = std::get<std::string>(config_data["MOUNTPOINT"]);
{
std::vector<std::string> temp{"None -"};
const auto& root_filesystem = utils::exec(fmt::format("findmnt -ln -o FSTYPE \"{}\"", mountpoint_info));
if (!(root_filesystem == "zfs" || root_filesystem == "btrfs")) {
temp.push_back("Swapfile -");
}
const auto& partitions = std::get<std::vector<std::string>>(config_data["PARTITIONS"]);
temp.reserve(partitions.size());
std::ranges::copy(partitions, std::back_inserter(temp));
std::int32_t selected{};
bool success{};
auto ok_callback = [&] {
auto src = temp[static_cast<std::size_t>(selected)];
const auto& lines = utils::make_multiline(src, false, " ");
config_data["ANSWER"] = lines[0];
success = true;
std::raise(SIGINT);
};
/* clang-format off */
detail::menu_widget(temp, ok_callback, &selected);
if (!success) { return; }
/* clang-format on */
}
const auto& answer = std::get<std::string>(config_data["ANSWER"]);
auto& partition = std::get<std::string>(config_data["PARTITION"]);
/* clang-format off */
if (answer == SelSwpNone) { return; }
partition = answer;
/* clang-format on */
if (partition == SelSwpFile) {
const auto& total_memory = utils::exec("grep MemTotal /proc/meminfo | awk \'{print $2/1024}\' | sed \'s/\\..*//\'");
std::string value{fmt::format("{}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))) {
return;
}
while (utils::exec(fmt::format("echo \"{}\" | grep \"M\\|G\"", value)) == "") {
detail::msgbox_widget(fmt::format("\n{} Error: M = MB, G = GB\n", SelSwpFile));
value = fmt::format("{}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))) {
return;
}
}
#ifdef NDEVENV
const auto& swapfile_path = fmt::format("{}/swapfile", mountpoint_info);
utils::exec(fmt::format("fallocate -l {} {}", value, swapfile_path));
utils::exec(fmt::format("chmod 600 {}", swapfile_path));
utils::exec(fmt::format("mkswap {}", swapfile_path));
utils::exec(fmt::format("swapon {}", swapfile_path));
#endif
return;
}
auto& partitions = std::get<std::vector<std::string>>(config_data["PARTITIONS"]);
auto& number_partitions = std::get<std::int32_t>(config_data["NUMBER_PARTITIONS"]);
// Warn user if creating a new swap
const auto& swap_part = utils::exec(fmt::format("lsblk -o FSTYPE \"{}\" | grep -i \"swap\"", partition));
if (swap_part != "swap") {
const auto& do_swap = detail::yesno_widget(fmt::format("\nmkswap {}\n", partition), size(HEIGHT, LESS_THAN, 15) | size(WIDTH, LESS_THAN, 75));
/* clang-format off */
if (!do_swap) { return; }
/* clang-format on */
#ifdef NDEVENV
utils::exec(fmt::format("mkswap {} >/dev/null", partition));
#endif
spdlog::info("mkswap.{}", partition);
}
#ifdef NDEVENV
// Whether existing to newly created, activate swap
utils::exec(fmt::format("swapon {} >/dev/null", partition));
#endif
// TODO: reimplement natively
// Since a partition was used, remove that partition from the list
const auto& str = utils::make_multiline(partitions);
const auto& cmd = fmt::format("echo \"{0}\" | sed \"s~{1} [0-9]*[G-M]~~\" | sed \"s~{1} [0-9]*\\.[0-9]*[G-M]~~\" | sed \"s~{1}$\' -\'~~\"", str, partition);
const auto& res_text = utils::exec(cmd);
partitions = utils::make_multiline(res_text);
number_partitions -= 1;
}
void mount_partitions() noexcept {
auto* config_instance = Config::instance();
@ -554,17 +649,35 @@ void mount_partitions() noexcept {
// All other partitions
const auto& number_partitions = std::get<std::int32_t>(config_data["NUMBER_PARTITIONS"]);
const auto& system_info = std::get<std::string>(config_data["SYSTEM"]);
const auto& partition = std::get<std::string>(config_data["PARTITION"]);
while (number_partitions > 0) {
// DIALOG " $_PrepMntPart " --menu "\n$_ExtPartBody\n " 0 0 12 "$_Done" $"-" ${PARTITIONS} 2>${ANSWER} || return 0
// PARTITION=$(cat ${ANSWER})
{
std::int32_t selected{};
bool success{};
const auto& partitions = std::get<std::vector<std::string>>(config_data["PARTITIONS"]);
std::vector<std::string> temp{"Done -"};
temp.reserve(partitions.size());
std::ranges::copy(partitions, std::back_inserter(temp));
// if [[ $PARTITION == $_Done ]]; then
// make_esp
// get_cryptroot
// get_cryptboot
// echo "$LUKS_DEV" > /tmp/.luks_dev
// return 0;
// else
auto ok_callback = [&] {
auto src = temp[static_cast<std::size_t>(selected)];
const auto& lines = utils::make_multiline(src, false, " ");
config_data["PARTITION"] = lines[0];
success = true;
std::raise(SIGINT);
};
/* clang-format off */
detail::menu_widget(temp, ok_callback, &selected);
if (!success) { return; }
/* clang-format on */
}
if (partition == "Done") {
// make_esp();
// get_cryptroot();
// get_cryptboot();
return;
}
config_data["MOUNT"] = "";
tui::select_filesystem();
@ -572,23 +685,28 @@ void mount_partitions() noexcept {
// Ask user for mountpoint. Don't give /boot as an example for UEFI systems!
std::string_view mnt_examples = "/boot\n/home\n/var";
if (system_info == "UEFI") { mnt_examples = "/home\n/var"; }
std::string value{"/"};
static constexpr auto ExtPartBody1 = "Specify partition mountpoint. Ensure\nthe name begins with a forward slash (/).\nExamples include:";
if (!detail::inputbox_widget(value, fmt::format("\n{}\n{}\n", ExtPartBody1, mnt_examples))) { return; }
/* clang-format on */
// DIALOG " $_PrepMntPart $PARTITION " --inputbox "\n$_ExtPartBody1$MNT_EXAMPLES\n " 0 0 "/" 2>${ANSWER} || return 0
// MOUNT=$(cat ${ANSWER})
auto& mount_dev = std::get<std::string>(config_data["MOUNT"]);
mount_dev = std::move(value);
spdlog::info("\nmount_dev: {}\nexpression: {}\n", mount_dev, ((mount_dev.size() <= 1) || (mount_dev[0] != '/') || std::regex_match(mount_dev, std::regex{"\\s+|\\'"})));
// loop while the mountpoint specified is incorrect (is only '/', is blank, or has spaces).
/*while [[ ${MOUNT:0:1} != "/" ]] || [[ ${#MOUNT} -le 1 ]] || [[ $MOUNT =~ \ |\' ]]; do
while ((mount_dev.size() <= 1) || (mount_dev[0] != '/') || std::regex_match(mount_dev, std::regex{"\\s+|\\'"})) {
// Warn user about naming convention
DIALOG " $_ErrTitle " --msgbox "\n$_ExtErrBody\n " 0 0
detail::msgbox_widget("\nPartition cannot be mounted due to a problem with the mountpoint name.\nA name must be given after a forward slash.\n");
// Ask user for mountpoint again
DIALOG " $_PrepMntPart $PARTITON " --inputbox "\n$_ExtPartBody1$MNT_EXAMPLES\n " 0 0 "/" 2>${ANSWER} || return 0
MOUNT=$(cat ${ANSWER})
done*/
value = "/";
if (!detail::inputbox_widget(value, fmt::format("\n{}\n{}\n", ExtPartBody1, mnt_examples))) {
return;
}
mount_dev = std::move(value);
}
// Create directory and mount.
tui::mount_current_partition();
// delete_partition_in_list "$PARTITION"
// Determine if a seperate /boot is used.
// 0 = no seperate boot,
@ -602,7 +720,6 @@ void mount_partitions() noexcept {
config_data["LVM_SEP_BOOT"] = 2;
}
}
//}
}
}

View File

@ -144,6 +144,42 @@ void msgbox_widget(const std::string_view& content, Decorator boxsize) noexcept
screen.Loop(renderer);
}
bool inputbox_widget(std::string& value, const std::string_view& content, Decorator boxsize) noexcept {
auto screen = ScreenInteractive::Fullscreen();
bool success{};
auto ok_callback = [&] {
success = true;
std::raise(SIGINT);
};
InputOption input_option{.on_enter = ok_callback};
auto input_value = Input(&value, "", input_option);
auto content_container = Renderer([&] {
return multiline_text(utils::make_multiline(content)) | hcenter | boxsize;
});
ButtonOption button_option{.border = false};
auto controls_container = controls_widget({"OK", "Cancel"}, {ok_callback, screen.ExitLoopClosure()}, &button_option);
auto controls = Renderer(controls_container, [&] {
return controls_container->Render() | hcenter | size(HEIGHT, LESS_THAN, 3) | size(WIDTH, GREATER_THAN, 25);
});
auto global = Container::Vertical({
content_container,
Renderer([] { return separator(); }),
input_value,
Renderer([] { return separator(); }),
controls,
});
auto renderer = Renderer(global, [&] {
return centered_interative_multi("New CLI Installer", global);
});
screen.Loop(renderer);
return success;
}
void infobox_widget(const std::string_view& content, Decorator boxsize) noexcept {
auto screen = Screen::Create(
Dimension::Full(), // Width
@ -180,7 +216,6 @@ bool yesno_widget(const std::string_view& content, Decorator boxsize) noexcept {
});
screen.Loop(renderer);
return success;
}
@ -214,7 +249,6 @@ bool yesno_widget(ftxui::Component& container, Decorator boxsize) noexcept {
});
screen.Loop(renderer);
return success;
}

View File

@ -18,6 +18,7 @@ namespace detail {
auto from_checklist_string(const std::vector<std::string>& opts, bool* opts_state) noexcept -> std::string;
auto from_checklist_vector(const std::vector<std::string>& opts, bool* opts_state) noexcept -> std::vector<std::string>;
void msgbox_widget(const std::string_view& content, ftxui::Decorator boxsize = size(ftxui::HEIGHT, ftxui::GREATER_THAN, 5)) noexcept;
bool inputbox_widget(std::string& value, const std::string_view& content, ftxui::Decorator boxsize = size(ftxui::HEIGHT, ftxui::GREATER_THAN, 5)) noexcept;
void infobox_widget(const std::string_view& content, ftxui::Decorator boxsize = size(ftxui::HEIGHT, ftxui::GREATER_THAN, 5)) noexcept;
bool yesno_widget(const std::string_view& content, ftxui::Decorator boxsize = size(ftxui::HEIGHT, ftxui::GREATER_THAN, 5)) noexcept;
bool yesno_widget(ftxui::Component& container, ftxui::Decorator boxsize = size(ftxui::HEIGHT, ftxui::GREATER_THAN, 5)) noexcept;

View File

@ -1,6 +1,6 @@
[wrap-git]
url = https://github.com/arthursonzogni/ftxui.git
revision = 602392c43d8bc2272c6548ae75b8802ab7ad0b2a
revision = 7e5cd23b4c47972b70b99c39617d6e38f05d1b3a
patch_directory = ftxui

View File

@ -48,6 +48,7 @@ ftxui_dom_lib = static_library('ftxui_dom',
'src/ftxui/dom/flexbox_config.cpp',
'src/ftxui/dom/flexbox_helper.cpp',
'src/ftxui/dom/flexbox_helper.hpp',
'src/ftxui/dom/focus.cpp',
'src/ftxui/dom/frame.cpp',
'src/ftxui/dom/gauge.cpp',
'src/ftxui/dom/graph.cpp',