mirror of
https://github.com/CachyOS/New-Cli-Installer.git
synced 2025-02-02 22:07:13 +08:00
attempt for wrapped process log
This commit is contained in:
parent
d33c29c516
commit
bba4767fcb
@ -88,16 +88,25 @@ add_executable(${PROJECT_NAME}
|
|||||||
src/config.cpp src/config.hpp
|
src/config.cpp src/config.hpp
|
||||||
src/utils.cpp src/utils.hpp
|
src/utils.cpp src/utils.hpp
|
||||||
src/widgets.cpp src/widgets.hpp
|
src/widgets.cpp src/widgets.hpp
|
||||||
|
src/follow_process_log.hpp src/follow_process_log.cpp
|
||||||
src/tui.cpp src/tui.hpp
|
src/tui.cpp src/tui.hpp
|
||||||
src/main.cpp
|
src/main.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
add_executable(test-exec-interactive
|
add_executable(test-exec-interactive
|
||||||
|
src/config.cpp src/config.hpp
|
||||||
|
src/utils.cpp src/utils.hpp
|
||||||
|
src/tui.cpp src/tui.hpp
|
||||||
|
src/main_test.cpp
|
||||||
|
)
|
||||||
|
|
||||||
|
add_executable(test-process-tailing
|
||||||
src/config.cpp
|
src/config.cpp
|
||||||
src/utils.cpp
|
src/utils.cpp
|
||||||
src/widgets.cpp src/widgets.hpp
|
src/widgets.cpp src/widgets.hpp
|
||||||
|
src/follow_process_log.hpp src/follow_process_log.cpp
|
||||||
src/tui.cpp src/tui.hpp
|
src/tui.cpp src/tui.hpp
|
||||||
src/main_test.cpp
|
src/test_proccess_tailing.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
# Link this 'library' to use the warnings specified in CompilerWarnings.cmake
|
# Link this 'library' to use the warnings specified in CompilerWarnings.cmake
|
||||||
@ -114,6 +123,7 @@ 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(${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)
|
target_link_libraries(test-exec-interactive PRIVATE project_warnings project_options spdlog::spdlog fmt::fmt ftxui::component cpr::cpr PkgConfig::GLIBMM)
|
||||||
|
target_link_libraries(test-process-tailing PRIVATE project_warnings project_options spdlog::spdlog fmt::fmt ftxui::component cpr::cpr PkgConfig::GLIBMM)
|
||||||
|
|
||||||
if(CMAKE_CXX_COMPILER_ID MATCHES ".*Clang")
|
if(CMAKE_CXX_COMPILER_ID MATCHES ".*Clang")
|
||||||
target_link_libraries(${PROJECT_NAME} PRIVATE range-v3::range-v3)
|
target_link_libraries(${PROJECT_NAME} PRIVATE range-v3::range-v3)
|
||||||
|
@ -47,6 +47,7 @@ src_files = files(
|
|||||||
'src/config.cpp', 'src/config.hpp',
|
'src/config.cpp', 'src/config.hpp',
|
||||||
'src/utils.cpp', 'src/utils.hpp',
|
'src/utils.cpp', 'src/utils.hpp',
|
||||||
'src/widgets.cpp', 'src/widgets.hpp',
|
'src/widgets.cpp', 'src/widgets.hpp',
|
||||||
|
'src/follow_process_log.cpp', 'src/follow_process_log.hpp',
|
||||||
'src/tui.cpp', 'src/tui.hpp',
|
'src/tui.cpp', 'src/tui.hpp',
|
||||||
'src/main.cpp',
|
'src/main.cpp',
|
||||||
)
|
)
|
||||||
@ -115,7 +116,7 @@ executable(
|
|||||||
|
|
||||||
executable(
|
executable(
|
||||||
'test-process-tailing',
|
'test-process-tailing',
|
||||||
files('src/config.cpp', 'src/widgets.cpp', 'src/tui.cpp', 'src/utils.cpp', 'src/test_proccess_tailing.cpp'),
|
files('src/config.cpp', 'src/widgets.cpp', 'src/tui.cpp', 'src/utils.cpp', 'src/follow_process_log.cpp','src/test_proccess_tailing.cpp'),
|
||||||
dependencies: [fmt, spdlog, ftxui, cpr, glibmm],
|
dependencies: [fmt, spdlog, ftxui, cpr, glibmm],
|
||||||
include_directories: [include_directories('src')],
|
include_directories: [include_directories('src')],
|
||||||
install: false)
|
install: false)
|
||||||
|
69
src/follow_process_log.cpp
Normal file
69
src/follow_process_log.cpp
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
#include "follow_process_log.hpp"
|
||||||
|
#include "subprocess.h"
|
||||||
|
#include "utils.hpp" // for make_multiline
|
||||||
|
#include "widgets.hpp"
|
||||||
|
|
||||||
|
#include <chrono> // for operator""s, chrono_literals
|
||||||
|
#include <csignal>
|
||||||
|
#include <string> // for string, operator<<, to_string
|
||||||
|
#include <thread>
|
||||||
|
|
||||||
|
#include <ftxui/component/component.hpp> // for Renderer, Button
|
||||||
|
#include <ftxui/component/component_options.hpp> // for ButtonOption, Inpu...
|
||||||
|
#include <ftxui/component/event.hpp>
|
||||||
|
#include <ftxui/component/screen_interactive.hpp> // for ScreenInteractive
|
||||||
|
#include <ftxui/dom/elements.hpp> // for operator|, text, Element, hbox, bold, color, filler, separator, vbox, window, gauge, Fit, size, dim, EQUAL, WIDTH
|
||||||
|
|
||||||
|
using namespace ftxui;
|
||||||
|
|
||||||
|
namespace tui::detail {
|
||||||
|
|
||||||
|
void follow_process_log_widget(const std::vector<std::string>& vec, Decorator boxsize) noexcept {
|
||||||
|
using namespace std::chrono_literals;
|
||||||
|
|
||||||
|
bool running{true};
|
||||||
|
std::string process_log{};
|
||||||
|
subprocess_s child{};
|
||||||
|
auto execute_thread = [&]() {
|
||||||
|
while (running) {
|
||||||
|
utils::exec_follow(vec, process_log, running, child);
|
||||||
|
std::this_thread::sleep_for(0.05s);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
std::jthread t(execute_thread);
|
||||||
|
auto screen = ScreenInteractive::Fullscreen();
|
||||||
|
|
||||||
|
std::jthread refresh_ui([&] {
|
||||||
|
while (running) {
|
||||||
|
std::this_thread::sleep_for(0.05s);
|
||||||
|
screen.PostEvent(Event::Custom);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
auto handle_exit = [&]() {
|
||||||
|
if (child.child != 0) {
|
||||||
|
subprocess_terminate(&child);
|
||||||
|
subprocess_destroy(&child);
|
||||||
|
}
|
||||||
|
if (running) {
|
||||||
|
running = false;
|
||||||
|
refresh_ui.join();
|
||||||
|
t.join();
|
||||||
|
}
|
||||||
|
screen.ExitLoopClosure()();
|
||||||
|
};
|
||||||
|
|
||||||
|
auto button_option = ButtonOption();
|
||||||
|
button_option.border = false;
|
||||||
|
auto button_back = Button("Back", handle_exit, &button_option);
|
||||||
|
auto container = Container::Horizontal({button_back});
|
||||||
|
|
||||||
|
auto renderer = Renderer(container, [&] {
|
||||||
|
return tui::detail::centered_widget(container, "New CLI Installer", tui::detail::multiline_text(utils::make_multiline(process_log)) | boxsize | vscroll_indicator | yframe | flex);
|
||||||
|
});
|
||||||
|
|
||||||
|
screen.Loop(renderer);
|
||||||
|
running = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace tui::detail
|
14
src/follow_process_log.hpp
Normal file
14
src/follow_process_log.hpp
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
#ifndef FOLLOW_PROCESS_LOG_HPP
|
||||||
|
#define FOLLOW_PROCESS_LOG_HPP
|
||||||
|
|
||||||
|
#include <string_view> // for string_view
|
||||||
|
|
||||||
|
#include <ftxui/dom/elements.hpp> // for size, GREATER_THAN
|
||||||
|
|
||||||
|
namespace tui {
|
||||||
|
namespace detail {
|
||||||
|
void follow_process_log_widget(const std::vector<std::string>& vec, ftxui::Decorator boxsize = size(ftxui::HEIGHT, ftxui::GREATER_THAN, 5)) noexcept;
|
||||||
|
} // namespace detail
|
||||||
|
} // namespace tui
|
||||||
|
|
||||||
|
#endif // FOLLOW_PROCESS_LOG_HPP
|
1076
src/subprocess.h
Normal file
1076
src/subprocess.h
Normal file
File diff suppressed because it is too large
Load Diff
@ -1,95 +1,5 @@
|
|||||||
#include <cstdio>
|
#include "follow_process_log.hpp"
|
||||||
#include <thread>
|
|
||||||
|
|
||||||
#include <chrono> // for operator""s, chrono_literals
|
|
||||||
#include <ftxui/component/component.hpp> // for Renderer, Button
|
|
||||||
#include <ftxui/component/component_options.hpp> // for ButtonOption, Inpu...
|
|
||||||
#include <ftxui/component/screen_interactive.hpp> // for ScreenInteractive
|
|
||||||
#include <ftxui/dom/elements.hpp> // for operator|, text, Element, hbox, bold, color, filler, separator, vbox, window, gauge, Fit, size, dim, EQUAL, WIDTH
|
|
||||||
#include <ftxui/screen/screen.hpp> // for Full, Screen
|
|
||||||
#include <iostream> // for cout, endl, ostream
|
|
||||||
#include <list> // for list, operator!=, _List_iterator, _List_iterator<>::_Self
|
|
||||||
#include <memory> // for allocator, shared_ptr, allocator_traits<>::value_type
|
|
||||||
#include <string> // for string, operator<<, to_string
|
|
||||||
#include <thread> // for sleep_for
|
|
||||||
#include <utility> // for move
|
|
||||||
#include <vector> // for vector
|
|
||||||
|
|
||||||
#include <ftxui/component/captured_mouse.hpp>
|
|
||||||
#include <ftxui/component/event.hpp>
|
|
||||||
#include <ftxui/dom/node.hpp> // for Render
|
|
||||||
#include <ftxui/screen/box.hpp> // for ftxui
|
|
||||||
#include <ftxui/screen/color.hpp> // for Color, Color::Green, Color::Red, Color::RedLight
|
|
||||||
|
|
||||||
#include "subprocess.h"
|
|
||||||
#include "utils.hpp"
|
|
||||||
#include "widgets.hpp"
|
|
||||||
|
|
||||||
static bool running{true};
|
|
||||||
static std::string process_log{};
|
|
||||||
|
|
||||||
using namespace std::chrono_literals;
|
|
||||||
|
|
||||||
void execute() {
|
|
||||||
const char* const commandLine[] = {"/sbin/tail", "-f", "/tmp/smth.log", nullptr};
|
|
||||||
struct subprocess_s process;
|
|
||||||
int ret = -1;
|
|
||||||
static char data[1048576 + 1] = {0};
|
|
||||||
unsigned index = 0;
|
|
||||||
unsigned bytes_read = 0;
|
|
||||||
|
|
||||||
if ((ret = subprocess_create(commandLine, subprocess_option_enable_async | subprocess_option_combined_stdout_stderr, &process)) != 0) {
|
|
||||||
std::perror("creation failed");
|
|
||||||
std::cerr << "creation failed with: " << ret << '\n';
|
|
||||||
running = false;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
do {
|
|
||||||
bytes_read = subprocess_read_stdout(&process, data + index,
|
|
||||||
sizeof(data) - 1 - index);
|
|
||||||
|
|
||||||
index += bytes_read;
|
|
||||||
|
|
||||||
process_log = data;
|
|
||||||
} while (bytes_read != 0);
|
|
||||||
|
|
||||||
subprocess_join(&process, &ret);
|
|
||||||
subprocess_destroy(&process);
|
|
||||||
}
|
|
||||||
|
|
||||||
void execute_thread() {
|
|
||||||
while (running) {
|
|
||||||
execute();
|
|
||||||
|
|
||||||
std::this_thread::sleep_for(2s);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
using namespace ftxui;
|
tui::detail::follow_process_log_widget({"/sbin/tail", "-f", "/tmp/smth.log"});
|
||||||
std::jthread t(execute_thread);
|
|
||||||
|
|
||||||
auto screen = ScreenInteractive::Fullscreen();
|
|
||||||
|
|
||||||
std::jthread refresh_ui([&] {
|
|
||||||
while (running) {
|
|
||||||
std::this_thread::sleep_for(0.05s);
|
|
||||||
screen.PostEvent(Event::Custom);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
auto button_option = ButtonOption();
|
|
||||||
button_option.border = false;
|
|
||||||
auto button_back = Button("Back", screen.ExitLoopClosure(), &button_option);
|
|
||||||
auto container = Container::Horizontal({button_back});
|
|
||||||
|
|
||||||
auto renderer = Renderer(container, [&] {
|
|
||||||
return tui::detail::centered_widget(container, "New CLI Installer", tui::detail::multiline_text(utils::make_multiline(process_log)) | vscroll_indicator | yframe | flex);
|
|
||||||
});
|
|
||||||
|
|
||||||
screen.Loop(renderer);
|
|
||||||
running = false;
|
|
||||||
t.join();
|
|
||||||
refresh_ui.join();
|
|
||||||
}
|
}
|
||||||
|
16
src/tui.cpp
16
src/tui.cpp
@ -30,6 +30,10 @@ namespace fs = std::filesystem;
|
|||||||
namespace ranges = std::ranges;
|
namespace ranges = std::ranges;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef NDEVENV
|
||||||
|
#include "follow_process_log.hpp"
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace tui {
|
namespace tui {
|
||||||
|
|
||||||
// Revised to deal with partion sizes now being displayed to the user
|
// Revised to deal with partion sizes now being displayed to the user
|
||||||
@ -418,10 +422,12 @@ void install_cust_pkgs() noexcept {
|
|||||||
const auto& hostcache = std::get<std::int32_t>(config_data["hostcache"]);
|
const auto& hostcache = std::get<std::int32_t>(config_data["hostcache"]);
|
||||||
|
|
||||||
if (hostcache) {
|
if (hostcache) {
|
||||||
utils::exec(fmt::format("pacstrap {} {}", mountpoint, packages));
|
// utils::exec(fmt::format("pacstrap {} {}", mountpoint, packages));
|
||||||
|
detail::follow_process_log_widget({"/sbin/pacstrap", mountpoint, packages});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
utils::exec(fmt::format("pacstrap -c {} {}", mountpoint, packages));
|
// utils::exec(fmt::format("pacstrap -c {} {}", mountpoint, packages));
|
||||||
|
detail::follow_process_log_widget({"/sbin/pacstrap", "-c", mountpoint, packages});
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -454,7 +460,8 @@ void install_systemd_boot() noexcept {
|
|||||||
const auto& uefi_mount = std::get<std::string>(config_data["UEFI_MOUNT"]);
|
const auto& uefi_mount = std::get<std::string>(config_data["UEFI_MOUNT"]);
|
||||||
|
|
||||||
utils::arch_chroot(fmt::format("bootctl --path={} install", uefi_mount));
|
utils::arch_chroot(fmt::format("bootctl --path={} install", uefi_mount));
|
||||||
utils::exec(fmt::format("pacstrap {} systemd-boot-manager", mountpoint));
|
// utils::exec(fmt::format("pacstrap {} systemd-boot-manager", mountpoint));
|
||||||
|
detail::follow_process_log_widget({"/sbin/pacstrap", mountpoint, "systemd-boot-manager"});
|
||||||
utils::arch_chroot("sdboot-manage gen");
|
utils::arch_chroot("sdboot-manage gen");
|
||||||
|
|
||||||
// Check if the volume is removable. If so, dont use autodetect
|
// Check if the volume is removable. If so, dont use autodetect
|
||||||
@ -603,7 +610,8 @@ void install_base() noexcept {
|
|||||||
spdlog::info(fmt::format("Preparing for pkgs to install: \"{}\"", packages));
|
spdlog::info(fmt::format("Preparing for pkgs to install: \"{}\"", packages));
|
||||||
#ifdef NDEVENV
|
#ifdef NDEVENV
|
||||||
// filter_packages
|
// filter_packages
|
||||||
utils::exec(fmt::format("pacstrap {} {} |& tee /tmp/pacstrap.log", mountpoint, packages));
|
// utils::exec(fmt::format("pacstrap {} {} |& tee /tmp/pacstrap.log", mountpoint, packages));
|
||||||
|
detail::follow_process_log_widget({"/sbin/pacstrap", mountpoint, packages});
|
||||||
#endif
|
#endif
|
||||||
std::ofstream{base_installed};
|
std::ofstream{base_installed};
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
#include "utils.hpp"
|
#include "utils.hpp"
|
||||||
#include "config.hpp"
|
#include "config.hpp"
|
||||||
#include "definitions.hpp"
|
#include "definitions.hpp"
|
||||||
|
#include "subprocess.h"
|
||||||
#include "tui.hpp"
|
#include "tui.hpp"
|
||||||
#include "widgets.hpp"
|
#include "widgets.hpp"
|
||||||
|
|
||||||
@ -82,6 +83,43 @@ void arch_chroot(const std::string_view& command) noexcept {
|
|||||||
utils::exec(fmt::format("arch-chroot {} \"{}\"", mountpoint, command));
|
utils::exec(fmt::format("arch-chroot {} \"{}\"", mountpoint, command));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void exec_follow(const std::vector<std::string>& vec, std::string& process_log, bool& running, subprocess_s& child, bool async) noexcept {
|
||||||
|
if (!async) {
|
||||||
|
spdlog::error("Implement me!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
subprocess_s process{};
|
||||||
|
int32_t ret{-1};
|
||||||
|
static std::array<char, 1048576 + 1> data{};
|
||||||
|
uint32_t index{};
|
||||||
|
uint32_t bytes_read{};
|
||||||
|
|
||||||
|
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();
|
||||||
|
|
||||||
|
if ((ret = subprocess_create(command, subprocess_option_enable_async | subprocess_option_combined_stdout_stderr, &process)) != 0) {
|
||||||
|
running = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
child = process;
|
||||||
|
|
||||||
|
do {
|
||||||
|
bytes_read = subprocess_read_stdout(&process, data.data() + index,
|
||||||
|
sizeof(data) - 1 - index);
|
||||||
|
|
||||||
|
index += bytes_read;
|
||||||
|
process_log = data.data();
|
||||||
|
} while (bytes_read != 0);
|
||||||
|
|
||||||
|
subprocess_join(&process, &ret);
|
||||||
|
subprocess_destroy(&process);
|
||||||
|
}
|
||||||
|
|
||||||
void exec(const std::vector<std::string>& vec) noexcept {
|
void exec(const std::vector<std::string>& vec) noexcept {
|
||||||
std::int32_t status{};
|
std::int32_t status{};
|
||||||
auto pid = fork();
|
auto pid = fork();
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
#define UTILS_HPP
|
#define UTILS_HPP
|
||||||
|
|
||||||
#include "definitions.hpp"
|
#include "definitions.hpp"
|
||||||
|
#include "subprocess.h"
|
||||||
|
|
||||||
#include <charconv> // for from_chars
|
#include <charconv> // for from_chars
|
||||||
#include <string> // for string
|
#include <string> // for string
|
||||||
@ -25,6 +26,7 @@ void umount_partitions() noexcept;
|
|||||||
void find_partitions() noexcept;
|
void find_partitions() noexcept;
|
||||||
|
|
||||||
void arch_chroot(const std::string_view& command) noexcept;
|
void arch_chroot(const std::string_view& command) 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;
|
void exec(const std::vector<std::string>& vec) noexcept;
|
||||||
auto exec(const std::string_view& command, const bool& interactive = false) noexcept(false) -> std::string;
|
auto exec(const std::string_view& command, const bool& interactive = false) noexcept(false) -> std::string;
|
||||||
[[nodiscard]] bool check_root() noexcept;
|
[[nodiscard]] bool check_root() noexcept;
|
||||||
|
Loading…
Reference in New Issue
Block a user