👷 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 FetchContent_Declare(ftxui
GIT_REPOSITORY "https://github.com/arthursonzogni/ftxui.git" GIT_REPOSITORY "https://github.com/arthursonzogni/ftxui.git"
GIT_TAG "602392c43d8bc2272c6548ae75b8802ab7ad0b2a" GIT_TAG "7e5cd23b4c47972b70b99c39617d6e38f05d1b3a"
) )
FetchContent_MakeAvailable(ftxui) FetchContent_MakeAvailable(ftxui)

View File

@ -9,6 +9,7 @@
#include <algorithm> // for transform #include <algorithm> // for transform
#include <filesystem> // for exists, is_directory #include <filesystem> // for exists, is_directory
#include <memory> // for __shared_ptr_access #include <memory> // for __shared_ptr_access
#include <regex> // for regex_search, match_results<>::_Base_type
#include <string> // for basic_string #include <string> // for basic_string
#include <ftxui/component/captured_mouse.hpp> // for ftxui #include <ftxui/component/captured_mouse.hpp> // for ftxui
#include <ftxui/component/component.hpp> // for Renderer, Button #include <ftxui/component/component.hpp> // for Renderer, Button
@ -432,7 +433,101 @@ bool mount_current_partition() noexcept {
return true; 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 { void mount_partitions() noexcept {
auto* config_instance = Config::instance(); auto* config_instance = Config::instance();
@ -554,17 +649,35 @@ void mount_partitions() noexcept {
// All other partitions // All other partitions
const auto& number_partitions = std::get<std::int32_t>(config_data["NUMBER_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& system_info = std::get<std::string>(config_data["SYSTEM"]);
const auto& partition = std::get<std::string>(config_data["PARTITION"]);
while (number_partitions > 0) { 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 auto ok_callback = [&] {
// make_esp auto src = temp[static_cast<std::size_t>(selected)];
// get_cryptroot const auto& lines = utils::make_multiline(src, false, " ");
// get_cryptboot config_data["PARTITION"] = lines[0];
// echo "$LUKS_DEV" > /tmp/.luks_dev success = true;
// return 0; std::raise(SIGINT);
// else };
/* 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"] = ""; config_data["MOUNT"] = "";
tui::select_filesystem(); 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! // Ask user for mountpoint. Don't give /boot as an example for UEFI systems!
std::string_view mnt_examples = "/boot\n/home\n/var"; std::string_view mnt_examples = "/boot\n/home\n/var";
if (system_info == "UEFI") { mnt_examples = "/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 */ /* 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"]); 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). // 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 // 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 // Ask user for mountpoint again
DIALOG " $_PrepMntPart $PARTITON " --inputbox "\n$_ExtPartBody1$MNT_EXAMPLES\n " 0 0 "/" 2>${ANSWER} || return 0 value = "/";
MOUNT=$(cat ${ANSWER}) if (!detail::inputbox_widget(value, fmt::format("\n{}\n{}\n", ExtPartBody1, mnt_examples))) {
done*/ return;
}
mount_dev = std::move(value);
}
// Create directory and mount. // Create directory and mount.
tui::mount_current_partition(); tui::mount_current_partition();
// delete_partition_in_list "$PARTITION"
// Determine if a seperate /boot is used. // Determine if a seperate /boot is used.
// 0 = no seperate boot, // 0 = no seperate boot,
@ -602,7 +720,6 @@ void mount_partitions() noexcept {
config_data["LVM_SEP_BOOT"] = 2; 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); 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 { void infobox_widget(const std::string_view& content, Decorator boxsize) noexcept {
auto screen = Screen::Create( auto screen = Screen::Create(
Dimension::Full(), // Width Dimension::Full(), // Width
@ -180,7 +216,6 @@ bool yesno_widget(const std::string_view& content, Decorator boxsize) noexcept {
}); });
screen.Loop(renderer); screen.Loop(renderer);
return success; return success;
} }
@ -214,7 +249,6 @@ bool yesno_widget(ftxui::Component& container, Decorator boxsize) noexcept {
}); });
screen.Loop(renderer); screen.Loop(renderer);
return success; 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_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>; 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; 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; 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(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; 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] [wrap-git]
url = https://github.com/arthursonzogni/ftxui.git url = https://github.com/arthursonzogni/ftxui.git
revision = 602392c43d8bc2272c6548ae75b8802ab7ad0b2a revision = 7e5cd23b4c47972b70b99c39617d6e38f05d1b3a
patch_directory = ftxui 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_config.cpp',
'src/ftxui/dom/flexbox_helper.cpp', 'src/ftxui/dom/flexbox_helper.cpp',
'src/ftxui/dom/flexbox_helper.hpp', 'src/ftxui/dom/flexbox_helper.hpp',
'src/ftxui/dom/focus.cpp',
'src/ftxui/dom/frame.cpp', 'src/ftxui/dom/frame.cpp',
'src/ftxui/dom/gauge.cpp', 'src/ftxui/dom/gauge.cpp',
'src/ftxui/dom/graph.cpp', 'src/ftxui/dom/graph.cpp',