From 93c8cfa2a0bbad78929683cdfd3bdbc022411fff Mon Sep 17 00:00:00 2001 From: Vladislav Nepogodin Date: Tue, 21 Dec 2021 03:13:13 +0400 Subject: [PATCH] =?UTF-8?q?=F0=9F=91=B7=20update=20ui?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit fix build with clang --- CMakeLists.txt | 27 ++++++--- cmake/StandardProjectSettings.cmake | 9 +++ src/tui.cpp | 94 ++++++++++++++++++++++++++++- src/utils.cpp | 40 +++++++++--- 4 files changed, 150 insertions(+), 20 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 8c44c92..deb1bf2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -39,14 +39,15 @@ FetchContent_Declare(ftxui GIT_REPOSITORY "https://github.com/arthursonzogni/ftxui.git" GIT_TAG "7e5cd23b4c47972b70b99c39617d6e38f05d1b3a" ) -FetchContent_Declare(spdlog - GIT_REPOSITORY "https://github.com/gabime/spdlog.git" - GIT_TAG "cc30229abb1e22ebe1f8657de4011a53db7bd6ac" -) FetchContent_Declare(fmt GIT_REPOSITORY "https://github.com/fmtlib/fmt.git" GIT_TAG "3a951a66cb0fb53ff5a9d5ce9c77e05ef9d382ce" ) +FetchContent_MakeAvailable(fmt) +FetchContent_Declare(spdlog + GIT_REPOSITORY "https://github.com/gabime/spdlog.git" + GIT_TAG "cc30229abb1e22ebe1f8657de4011a53db7bd6ac" +) FetchContent_Declare(nlohmann_json GIT_REPOSITORY "https://github.com/ArthurSonzogni/nlohmann_json_cmake_fetchcontent.git" GIT_TAG "v3.10.4" @@ -55,17 +56,22 @@ FetchContent_Declare(cpr GIT_REPOSITORY "https://github.com/libcpr/cpr.git" GIT_TAG "beb9e98806bb84bcc130a2cebfbcbbc6ce62b335" ) -FetchContent_MakeAvailable(ftxui spdlog fmt nlohmann_json cpr) +FetchContent_MakeAvailable(ftxui spdlog nlohmann_json cpr) +if(CMAKE_CXX_COMPILER_ID MATCHES ".*Clang") + FetchContent_Declare(range-v3 + GIT_REPOSITORY "https://github.com/ericniebler/range-v3.git" + GIT_TAG "9aa032ccd0eb4bd77f58e5b181168f1038c222c6" + ) + FetchContent_MakeAvailable(range-v3) +endif() ## ## CONFIGURATION ## -option(BUILD_SHARED_LIBS "Enable compilation of shared libraries" OFF) -set(SPDLOG_FMT_EXTERNAL ON CACHE INTERNAL "" FORCE) set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -flto") if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU") - set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -fwhole-program") + set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -fwhole-program") endif() # Link this 'library' to set the c++ standard / compile-time options requested @@ -109,6 +115,11 @@ include_directories(${CMAKE_SOURCE_DIR}/src) target_link_libraries(${PROJECT_NAME} PRIVATE project_warnings project_options spdlog::spdlog fmt::fmt ftxui::screen ftxui::dom ftxui::component nlohmann_json::nlohmann_json cpr::cpr PkgConfig::GLIBMM) target_link_libraries(test-exec-interactive PRIVATE project_warnings project_options spdlog::spdlog fmt::fmt ftxui::component cpr::cpr PkgConfig::GLIBMM) +if(CMAKE_CXX_COMPILER_ID MATCHES ".*Clang") + target_link_libraries(${PROJECT_NAME} PRIVATE range-v3::range-v3) + target_link_libraries(test-exec-interactive PRIVATE range-v3::range-v3) +endif() + option(ENABLE_UNITY "Enable Unity builds of projects" OFF) if(ENABLE_UNITY) # Add for any project you want to apply unity builds for diff --git a/cmake/StandardProjectSettings.cmake b/cmake/StandardProjectSettings.cmake index c11f43a..01bf806 100644 --- a/cmake/StandardProjectSettings.cmake +++ b/cmake/StandardProjectSettings.cmake @@ -14,6 +14,15 @@ if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) "RelWithDebInfo") endif() +set(CMAKE_CXX_EXTENSIONS OFF) + +set(BUILD_SHARED_LIBS OFF CACHE INTERNAL "" FORCE) +set(FTXUI_BUILD_DOCS OFF CACHE INTERNAL "" FORCE) +set(FTXUI_BUILD_EXAMPLES OFF CACHE INTERNAL "" FORCE) +set(FTXUI_ENABLE_INSTALL OFF CACHE INTERNAL "" FORCE) +set(SPDLOG_FMT_EXTERNAL ON CACHE INTERNAL "" FORCE) +set(SPDLOG_DISABLE_DEFAULT_LOGGER ON CACHE INTERNAL "" FORCE) + # Generate compile_commands.json to make it easier to work with clang based tools set(CMAKE_EXPORT_COMPILE_COMMANDS ON) diff --git a/src/tui.cpp b/src/tui.cpp index f9ae4f3..ff888c4 100644 --- a/src/tui.cpp +++ b/src/tui.cpp @@ -22,6 +22,17 @@ using namespace ftxui; namespace fs = std::filesystem; +#if defined(__clang__) +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wold-style-cast" + +#include + +#pragma clang diagnostic pop +#else +namespace ranges = std::ranges; +#endif + namespace tui { // Revised to deal with partion sizes now being displayed to the user @@ -201,6 +212,83 @@ void uefi_bootloader() noexcept { screen.Loop(renderer); } +void install_base() noexcept { + static constexpr auto base_installed = "/mnt/.base_installed"; + if (fs::exists(base_installed)) { + static constexpr auto content = "\nA CachyOS Base has already been installed on this partition.\nProceed anyway?\n"; + const auto& do_reinstall = detail::yesno_widget(content, size(HEIGHT, LESS_THAN, 15) | size(WIDTH, LESS_THAN, 75)); + /* clang-format off */ + if (!do_reinstall) { return; } + /* clang-format on */ + fs::remove(base_installed); + } + // Prep variables + auto* config_instance = Config::instance(); + auto& config_data = config_instance->data(); + const auto& mountpoint = std::get(config_data["MOUNTPOINT"]); + const std::vector available_kernels{"linux-cachyos", "linux", "linux-zen", "linux-lts", "linux-cachyos-cacule", "linux-cachyos-cacule-rdb", "linux-cachyos-bmq", "linux-cachyos-pds", "linux-cachyos-baby", "linux-cachyos-cacule-lts"}; + + // Create the base list of packages + std::vector install_packages{}; + + std::unique_ptr kernels_state{new bool[available_kernels.size()]{false}}; + + auto kernels = Container::Vertical(detail::from_vector_checklist(available_kernels, kernels_state.get())); + + auto screen = ScreenInteractive::Fullscreen(); + auto content = Renderer(kernels, [&] { + return kernels->Render() | center | size(HEIGHT, GREATER_THAN, 10) | size(WIDTH, GREATER_THAN, 40) | vscroll_indicator; + }); + + auto ok_callback = [&] { + const auto& packages = detail::from_checklist_string(available_kernels, kernels_state.get()); + auto ret_status = utils::exec(fmt::format("grep \"linux\" {}", packages), true); + if (ret_status == "0") { + // Check if a kernel is already installed + ret_status = utils::exec(fmt::format("ls {}/boot/*.img >/dev/null 2>&1", mountpoint), true); + if (ret_status != "0") { + static constexpr auto ErrNoKernel = "\nAt least one kernel must be selected.\n"; + detail::msgbox_widget(ErrNoKernel); + return; + } + const auto& cmd = utils::exec(fmt::format("ls {}/boot/*.img | cut -d'-' -f2 | grep -v ucode.img | sort -u", mountpoint)); + detail::msgbox_widget(fmt::format("\nlinux-{} detected\n", cmd)); + std::raise(SIGINT); + } + std::raise(SIGINT); + }; + + ButtonOption button_option{.border = false}; + auto controls_container = detail::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); + }); + + static constexpr auto InstStandBseBody = "\nThe base package group will be installed automatically.\nThe base-devel package group is required to use the Arch User Repository (AUR).\n"; + static constexpr auto UseSpaceBar = "Use [Spacebar] to de/select options listed."; + const auto& kernels_options_body = fmt::format("\n{}{}\n", InstStandBseBody, UseSpaceBar); + auto global = Container::Vertical({ + Renderer([&] { return detail::multiline_text(utils::make_multiline(kernels_options_body)); }), + Renderer([] { return separator(); }), + content, + Renderer([] { return separator(); }), + controls, + }); + + auto renderer = Renderer(global, [&] { + const auto& title = "New CLI Installer | Install Base"; + return detail::centered_interative_multi(title, global); + }); + + screen.Loop(renderer); + + //filter_packages + //utils::exec(fmt::format("pacstrap ${MOUNTPOINT} $(cat /mnt/.base) |& tee /tmp/pacstrap.log")); + + //std::ofstream(base_installed); +} + void bios_bootloader() { } void install_bootloader() { @@ -614,7 +702,7 @@ void make_swap() noexcept { } const auto& partitions = std::get>(config_data["PARTITIONS"]); temp.reserve(partitions.size()); - std::ranges::copy(partitions, std::back_inserter(temp)); + ranges::copy(partitions, std::back_inserter(temp)); std::int32_t selected{}; bool success{}; @@ -954,7 +1042,7 @@ void mount_partitions() noexcept { const auto& partitions = std::get>(config_data["PARTITIONS"]); std::vector temp{"Done -"}; temp.reserve(partitions.size()); - std::ranges::copy(partitions, std::back_inserter(temp)); + ranges::copy(partitions, std::back_inserter(temp)); auto ok_callback = [&] { auto src = temp[static_cast(selected)]; @@ -1083,7 +1171,7 @@ void create_partitions() noexcept { } void install_desktop_system_menu() { } -void install_core_menu() { } +void install_core_menu() { install_base(); } void install_custom_menu() { } void system_rescue_menu() { std::vector menu_entries = { diff --git a/src/utils.cpp b/src/utils.cpp index bb22ca9..e5e74ea 100644 --- a/src/utils.cpp +++ b/src/utils.cpp @@ -12,7 +12,6 @@ #include // for exit, WIFEXITED, WIFSIGNALED #include // for exists, is_directory #include // for basic_istream, cin -#include // for std::views::join #include // for regex_search, match_results<>::_Base_type #include // for operator==, string, basic_string, allocator #include // for mount @@ -21,6 +20,23 @@ #include // for execvp, fork #include // for unordered_map +#if defined(__clang__) +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wold-style-cast" + +#include +#include +#include +#include +#include +#include + +#pragma clang diagnostic pop +#else +#include +namespace ranges = std::ranges; +#endif + #ifdef NDEVENV #include #include @@ -130,32 +146,38 @@ bool prompt_char(const char* prompt, const char* color, char* read) noexcept { auto make_multiline(const std::string_view& str, bool reverse, const std::string_view&& delim) noexcept -> std::vector { static constexpr auto functor = [](auto&& rng) { - return std::string_view(&*rng.begin(), static_cast(std::ranges::distance(rng))); + return std::string_view(&*rng.begin(), static_cast(ranges::distance(rng))); }; static constexpr auto second = [](auto&& rng) { return rng != ""; }; - const auto& view = str - | std::views::split(delim) - | std::views::transform(functor); +#if defined(__clang__) + const auto& splitted_view = str + | ranges::views::split(delim); + const auto& view_res = splitted_view + | ranges::views::transform(functor); +#else + const auto& view_res = str + | ranges::views::split(delim) + | ranges::views::transform(functor); +#endif std::vector lines{}; - std::ranges::for_each(view | std::views::filter(second), [&](auto&& rng) { lines.emplace_back(rng); }); + ranges::for_each(view_res | ranges::views::filter(second), [&](auto&& rng) { lines.emplace_back(rng); }); if (reverse) { - std::ranges::reverse(lines); + ranges::reverse(lines); } return lines; } auto make_multiline(std::vector& multiline, bool reverse, const std::string_view&& delim) noexcept -> std::string { std::string res{}; - // for (const char c : multiline | std::views::join) res += c; for (const auto& line : multiline) { res += line; res += delim.data(); } if (reverse) { - std::ranges::reverse(res); + ranges::reverse(res); } return res;