diff --git a/gucc/CMakeLists.txt b/gucc/CMakeLists.txt index 6f75ff9..75a4e06 100644 --- a/gucc/CMakeLists.txt +++ b/gucc/CMakeLists.txt @@ -20,6 +20,7 @@ add_library(${PROJECT_NAME} SHARED src/zfs.cpp include/gucc/zfs.hpp src/btrfs.cpp include/gucc/btrfs.hpp src/user.cpp include/gucc/user.hpp + src/locale.cpp include/gucc/locale.hpp #src/chwd_profiles.cpp src/chwd_profiles.hpp #src/disk.cpp src/disk.hpp ) diff --git a/gucc/include/gucc/locale.hpp b/gucc/include/gucc/locale.hpp new file mode 100644 index 0000000..02efd48 --- /dev/null +++ b/gucc/include/gucc/locale.hpp @@ -0,0 +1,13 @@ +#ifndef LOCALE_HPP +#define LOCALE_HPP + +#include // for string_view + +namespace gucc::locale { + +// Set system language +auto set_locale(std::string_view locale, std::string_view mountpoint) noexcept -> bool; + +} // namespace gucc::locale + +#endif // LOCALE_HPP diff --git a/gucc/meson.build b/gucc/meson.build index bd64dbb..1b57b0b 100644 --- a/gucc/meson.build +++ b/gucc/meson.build @@ -10,6 +10,7 @@ gucc_lib = library('gucc', 'src/zfs.cpp', 'src/btrfs.cpp', 'src/user.cpp', + 'src/locale.cpp', ], include_directories : [include_directories('include')], dependencies: deps diff --git a/gucc/src/locale.cpp b/gucc/src/locale.cpp new file mode 100644 index 0000000..718bf65 --- /dev/null +++ b/gucc/src/locale.cpp @@ -0,0 +1,56 @@ +#include "gucc/locale.hpp" +#include "gucc/io_utils.hpp" +#include "gucc/string_utils.hpp" + +#include // for ofstream + +#include +#include + +#include + +using namespace std::string_view_literals; + +namespace gucc::locale { + +auto set_locale(std::string_view locale, std::string_view mountpoint) noexcept -> bool { + const auto& locale_config_path = fmt::format(FMT_COMPILE("{}/etc/locale.conf"), mountpoint); + const auto& locale_gen_path = fmt::format(FMT_COMPILE("{}/etc/locale.gen"), mountpoint); + + static constexpr auto LOCALE_CONFIG_PART = R"(LANG="{0}" +LC_NUMERIC="{0}" +LC_TIME="{0}" +LC_MONETARY="{0}" +LC_PAPER="{0}" +LC_NAME="{0}" +LC_ADDRESS="{0}" +LC_TELEPHONE="{0}" +LC_MEASUREMENT="{0}" +LC_IDENTIFICATION="{0}" +LC_MESSAGES="{0}" +)"; + + { + const auto& locale_config_text = fmt::format(LOCALE_CONFIG_PART, locale); + std::ofstream locale_config_file{locale_config_path, std::ios::out | std::ios::trunc}; + if (!locale_config_file.is_open()) { + spdlog::error("Failed to open locale config for writing {}", locale_config_path); + return false; + } + locale_config_file << locale_config_text; + } + + // TODO(vnepogodin): refactor and make backups of locale config and locale gen + utils::exec(fmt::format(FMT_COMPILE("sed -i \"s/#{0}/{0}/\" {1}"), locale, locale_gen_path)); + + // Generate locales + if (!utils::arch_chroot_checked("locale-gen", mountpoint)) { + spdlog::error("Failed to run locale-gen with locale '{}'", locale); + return false; + } + + // NOTE: maybe we should also write into /etc/default/locale if /etc/default exists and is a dir? + return true; +} + +} // namespace gucc::locale diff --git a/src/utils.cpp b/src/utils.cpp index a5e2fbd..b3205e0 100644 --- a/src/utils.cpp +++ b/src/utils.cpp @@ -10,6 +10,7 @@ #include "gucc/file_utils.hpp" #include "gucc/initcpio.hpp" #include "gucc/io_utils.hpp" +#include "gucc/locale.hpp" #include "gucc/luks.hpp" #include "gucc/pacmanconf_repo.hpp" #include "gucc/string_utils.hpp" @@ -388,31 +389,13 @@ void set_hostname(const std::string_view& hostname) noexcept { void set_locale(const std::string_view& locale) noexcept { spdlog::info("Selected locale: {}", locale); #ifdef NDEVENV - auto* config_instance = Config::instance(); - auto& config_data = config_instance->data(); - const auto& mountpoint = std::get(config_data["MOUNTPOINT"]); - const auto& locale_config_path = fmt::format(FMT_COMPILE("{}/etc/locale.conf"), mountpoint); - const auto& locale_gen_path = fmt::format(FMT_COMPILE("{}/etc/locale.gen"), mountpoint); + auto* config_instance = Config::instance(); + auto& config_data = config_instance->data(); + const auto& mountpoint = std::get(config_data["MOUNTPOINT"]); - static constexpr auto locale_config_part = R"(LANG="{0}" -LC_NUMERIC="{0}" -LC_TIME="{0}" -LC_MONETARY="{0}" -LC_PAPER="{0}" -LC_NAME="{0}" -LC_ADDRESS="{0}" -LC_TELEPHONE="{0}" -LC_MEASUREMENT="{0}" -LC_IDENTIFICATION="{0}" -LC_MESSAGES="{0}")"; - - std::ofstream locale_config_file{locale_config_path}; - locale_config_file << fmt::format(locale_config_part, locale); - - gucc::utils::exec(fmt::format(FMT_COMPILE("sed -i \"s/#{0}/{0}/\" {1}"), locale, locale_gen_path)); - - // Generate locales - utils::arch_chroot("locale-gen", false); + if (!gucc::locale::set_locale(locale, mountpoint)) { + spdlog::error("Failed to set locale"); + } #endif }