Add i18n by using rust i18n (#807)

* feat: initial i18n setup

* style: fmt

* feat: i18n support for new steps

* fix: build on Linux

* fix: build on Linux

* refactor: rm unused translation keys

---------

Co-authored-by: Steve Lau <stevelauc@outlook.com>
This commit is contained in:
Florian Nagel
2024-10-03 12:47:35 +02:00
committed by GitHub
parent c33d396489
commit 29c555c394
33 changed files with 1222 additions and 524 deletions

View File

@@ -4,6 +4,7 @@ use std::path::{Path, PathBuf};
use color_eyre::eyre;
use color_eyre::eyre::Result;
use rust_i18n::t;
use walkdir::WalkDir;
use crate::command::CommandExt;
@@ -310,7 +311,7 @@ impl ArchPackageManager for Aura {
} else {
let sudo = crate::utils::require_option(
ctx.sudo().as_ref(),
"Aura(<0.4.6) requires sudo installed to work with AUR packages".into(),
t!("Aura(<0.4.6) requires sudo installed to work with AUR packages").to_string(),
)?;
let mut cmd = ctx.run_type().execute(sudo);
@@ -383,7 +384,7 @@ pub fn show_pacnew() {
.peekable();
if iter.peek().is_some() {
println!("\nPacman backup configuration files found:");
println!("\n{}", t!("Pacman backup configuration files found:"));
for entry in iter {
println!("{}", entry.path().display());

View File

@@ -1,14 +1,14 @@
use crate::command::CommandExt;
use crate::execution_context::ExecutionContext;
use crate::terminal::print_separator;
use crate::utils::{require_option, REQUIRE_SUDO};
use crate::utils::{get_require_sudo_string, require_option};
use crate::Step;
use color_eyre::eyre::Result;
use std::process::Command;
pub fn upgrade_packages(ctx: &ExecutionContext) -> Result<()> {
let sudo = require_option(ctx.sudo().as_ref(), REQUIRE_SUDO.to_string())?;
print_separator("DragonFly BSD Packages");
let sudo = require_option(ctx.sudo().as_ref(), get_require_sudo_string())?;
print_separator(t!("DragonFly BSD Packages"));
let mut cmd = ctx.run_type().execute(sudo);
cmd.args(["/usr/local/sbin/pkg", "upgrade"]);
if ctx.config().yes(Step::System) {
@@ -18,9 +18,9 @@ pub fn upgrade_packages(ctx: &ExecutionContext) -> Result<()> {
}
pub fn audit_packages(ctx: &ExecutionContext) -> Result<()> {
let sudo = require_option(ctx.sudo().as_ref(), REQUIRE_SUDO.to_string())?;
let sudo = require_option(ctx.sudo().as_ref(), get_require_sudo_string())?;
print_separator("DragonFly BSD Audit");
print_separator(t!("DragonFly BSD Audit"));
#[allow(clippy::disallowed_methods)]
if !Command::new(sudo)
@@ -28,7 +28,9 @@ pub fn audit_packages(ctx: &ExecutionContext) -> Result<()> {
.status()?
.success()
{
println!("The package audit was successful, but vulnerable packages still remain on the system");
println!(t!(
"The package audit was successful, but vulnerable packages still remain on the system"
));
}
Ok(())
}

View File

@@ -1,14 +1,15 @@
use crate::command::CommandExt;
use crate::execution_context::ExecutionContext;
use crate::terminal::print_separator;
use crate::utils::{require_option, REQUIRE_SUDO};
use crate::utils::{get_require_sudo_string, require_option};
use crate::Step;
use color_eyre::eyre::Result;
use rust_i18n::t;
use std::process::Command;
pub fn upgrade_freebsd(ctx: &ExecutionContext) -> Result<()> {
let sudo = require_option(ctx.sudo().as_ref(), REQUIRE_SUDO.to_string())?;
print_separator("FreeBSD Update");
let sudo = require_option(ctx.sudo().as_ref(), get_require_sudo_string())?;
print_separator(t!("FreeBSD Update"));
ctx.run_type()
.execute(sudo)
.args(["/usr/sbin/freebsd-update", "fetch", "install"])
@@ -16,8 +17,8 @@ pub fn upgrade_freebsd(ctx: &ExecutionContext) -> Result<()> {
}
pub fn upgrade_packages(ctx: &ExecutionContext) -> Result<()> {
let sudo = require_option(ctx.sudo().as_ref(), REQUIRE_SUDO.to_string())?;
print_separator("FreeBSD Packages");
let sudo = require_option(ctx.sudo().as_ref(), get_require_sudo_string())?;
print_separator(t!("FreeBSD Packages"));
let mut command = ctx.run_type().execute(sudo);
@@ -29,9 +30,9 @@ pub fn upgrade_packages(ctx: &ExecutionContext) -> Result<()> {
}
pub fn audit_packages(ctx: &ExecutionContext) -> Result<()> {
let sudo = require_option(ctx.sudo().as_ref(), REQUIRE_SUDO.to_string())?;
let sudo = require_option(ctx.sudo().as_ref(), get_require_sudo_string())?;
print_separator("FreeBSD Audit");
print_separator(t!("FreeBSD Audit"));
Command::new(sudo)
.args(["/usr/sbin/pkg", "audit", "-Fr"])

View File

@@ -3,6 +3,7 @@ use std::process::Command;
use color_eyre::eyre::Result;
use ini::Ini;
use rust_i18n::t;
use tracing::{debug, warn};
use crate::command::CommandExt;
@@ -11,7 +12,7 @@ use crate::execution_context::ExecutionContext;
use crate::steps::generic::is_wsl;
use crate::steps::os::archlinux;
use crate::terminal::{print_separator, prompt_yesno};
use crate::utils::{require, require_option, which, PathExt, REQUIRE_SUDO};
use crate::utils::{get_require_sudo_string, require, require_option, which, PathExt};
use crate::{Step, HOME_DIR};
static OS_RELEASE_PATH: &str = "/etc/os-release";
@@ -135,7 +136,7 @@ impl Distribution {
}
pub fn upgrade(self, ctx: &ExecutionContext) -> Result<()> {
print_separator("System update");
print_separator(t!("System update"));
match self {
Distribution::Alpine => upgrade_alpine_linux(ctx),
@@ -176,7 +177,7 @@ impl Distribution {
}
fn update_bedrock(ctx: &ExecutionContext) -> Result<()> {
let sudo = require_option(ctx.sudo().as_ref(), REQUIRE_SUDO.to_string())?;
let sudo = require_option(ctx.sudo().as_ref(), get_require_sudo_string())?;
ctx.run_type().execute(sudo).args(["brl", "update"]);
@@ -201,7 +202,7 @@ fn update_bedrock(ctx: &ExecutionContext) -> Result<()> {
fn upgrade_alpine_linux(ctx: &ExecutionContext) -> Result<()> {
let apk = require("apk")?;
let sudo = require_option(ctx.sudo().as_ref(), REQUIRE_SUDO.to_string())?;
let sudo = require_option(ctx.sudo().as_ref(), get_require_sudo_string())?;
ctx.run_type().execute(sudo).arg(&apk).arg("update").status_checked()?;
ctx.run_type().execute(sudo).arg(&apk).arg("upgrade").status_checked()
@@ -209,7 +210,7 @@ fn upgrade_alpine_linux(ctx: &ExecutionContext) -> Result<()> {
fn upgrade_chimera_linux(ctx: &ExecutionContext) -> Result<()> {
let apk = require("apk")?;
let sudo = require_option(ctx.sudo().as_ref(), REQUIRE_SUDO.to_string())?;
let sudo = require_option(ctx.sudo().as_ref(), get_require_sudo_string())?;
ctx.run_type().execute(sudo).arg(&apk).arg("update").status_checked()?;
ctx.run_type().execute(sudo).arg(&apk).arg("upgrade").status_checked()
@@ -217,7 +218,7 @@ fn upgrade_chimera_linux(ctx: &ExecutionContext) -> Result<()> {
fn upgrade_wolfi_linux(ctx: &ExecutionContext) -> Result<()> {
let apk = require("apk")?;
let sudo = require_option(ctx.sudo().as_ref(), REQUIRE_SUDO.to_string())?;
let sudo = require_option(ctx.sudo().as_ref(), get_require_sudo_string())?;
ctx.run_type().execute(sudo).arg(&apk).arg("update").status_checked()?;
ctx.run_type().execute(sudo).arg(&apk).arg("upgrade").status_checked()
@@ -232,7 +233,7 @@ fn upgrade_redhat(ctx: &ExecutionContext) -> Result<()> {
}
};
let sudo = require_option(ctx.sudo().as_ref(), REQUIRE_SUDO.to_string())?;
let sudo = require_option(ctx.sudo().as_ref(), get_require_sudo_string())?;
let mut command = ctx.run_type().execute(sudo);
command
.arg(which("dnf").unwrap_or_else(|| Path::new("yum").to_path_buf()))
@@ -255,7 +256,7 @@ fn upgrade_redhat(ctx: &ExecutionContext) -> Result<()> {
}
fn upgrade_nobara(ctx: &ExecutionContext) -> Result<()> {
let sudo = require_option(ctx.sudo().as_ref(), REQUIRE_SUDO.to_string())?;
let sudo = require_option(ctx.sudo().as_ref(), get_require_sudo_string())?;
let pkg_manager = require("dnf")?;
let mut update_command = ctx.run_type().execute(sudo);
@@ -289,7 +290,7 @@ fn upgrade_nobara(ctx: &ExecutionContext) -> Result<()> {
}
fn upgrade_nilrt(ctx: &ExecutionContext) -> Result<()> {
let sudo = require_option(ctx.sudo().as_ref(), REQUIRE_SUDO.to_string())?;
let sudo = require_option(ctx.sudo().as_ref(), get_require_sudo_string())?;
let opkg = require("opkg")?;
ctx.run_type().execute(sudo).arg(&opkg).arg("update").status_checked()?;
@@ -305,14 +306,14 @@ fn upgrade_fedora_immutable(ctx: &ExecutionContext) -> Result<()> {
}
fn upgrade_bedrock_strata(ctx: &ExecutionContext) -> Result<()> {
let sudo = require_option(ctx.sudo().as_ref(), REQUIRE_SUDO.to_string())?;
let sudo = require_option(ctx.sudo().as_ref(), get_require_sudo_string())?;
ctx.run_type().execute(sudo).args(["brl", "update"]).status_checked()?;
Ok(())
}
fn upgrade_suse(ctx: &ExecutionContext) -> Result<()> {
let sudo = require_option(ctx.sudo().as_ref(), REQUIRE_SUDO.to_string())?;
let sudo = require_option(ctx.sudo().as_ref(), get_require_sudo_string())?;
ctx.run_type()
.execute(sudo)
.args(["zypper", "refresh"])
@@ -335,7 +336,7 @@ fn upgrade_suse(ctx: &ExecutionContext) -> Result<()> {
}
fn upgrade_opensuse_tumbleweed(ctx: &ExecutionContext) -> Result<()> {
let sudo = require_option(ctx.sudo().as_ref(), REQUIRE_SUDO.to_string())?;
let sudo = require_option(ctx.sudo().as_ref(), get_require_sudo_string())?;
ctx.run_type()
.execute(sudo)
.args(["zypper", "refresh"])
@@ -353,7 +354,7 @@ fn upgrade_opensuse_tumbleweed(ctx: &ExecutionContext) -> Result<()> {
}
fn upgrade_suse_micro(ctx: &ExecutionContext) -> Result<()> {
let sudo = require_option(ctx.sudo().as_ref(), REQUIRE_SUDO.to_string())?;
let sudo = require_option(ctx.sudo().as_ref(), get_require_sudo_string())?;
let mut cmd = ctx.run_type().execute(sudo);
cmd.arg("transactional-update");
if ctx.config().yes(Step::System) {
@@ -366,7 +367,7 @@ fn upgrade_suse_micro(ctx: &ExecutionContext) -> Result<()> {
}
fn upgrade_openmandriva(ctx: &ExecutionContext) -> Result<()> {
let sudo = require_option(ctx.sudo().as_ref(), REQUIRE_SUDO.to_string())?;
let sudo = require_option(ctx.sudo().as_ref(), get_require_sudo_string())?;
let mut command = ctx.run_type().execute(sudo);
command.arg(which("dnf").unwrap()).arg("upgrade");
@@ -385,7 +386,7 @@ fn upgrade_openmandriva(ctx: &ExecutionContext) -> Result<()> {
}
fn upgrade_pclinuxos(ctx: &ExecutionContext) -> Result<()> {
let sudo = require_option(ctx.sudo().as_ref(), REQUIRE_SUDO.to_string())?;
let sudo = require_option(ctx.sudo().as_ref(), get_require_sudo_string())?;
let mut command_update = ctx.run_type().execute(sudo);
command_update.arg(which("apt-get").unwrap()).arg("update");
@@ -432,7 +433,7 @@ fn upgrade_vanilla(ctx: &ExecutionContext) -> Result<()> {
}
fn upgrade_void(ctx: &ExecutionContext) -> Result<()> {
let sudo = require_option(ctx.sudo().as_ref(), REQUIRE_SUDO.to_string())?;
let sudo = require_option(ctx.sudo().as_ref(), get_require_sudo_string())?;
let mut command = ctx.run_type().execute(sudo);
command.args(["xbps-install", "-Su", "xbps"]);
if ctx.config().yes(Step::System) {
@@ -453,7 +454,7 @@ fn upgrade_void(ctx: &ExecutionContext) -> Result<()> {
fn upgrade_gentoo(ctx: &ExecutionContext) -> Result<()> {
let run_type = ctx.run_type();
let sudo = require_option(ctx.sudo().as_ref(), REQUIRE_SUDO.to_string())?;
let sudo = require_option(ctx.sudo().as_ref(), get_require_sudo_string())?;
if let Some(layman) = which("layman") {
run_type
.execute(sudo)
@@ -462,7 +463,7 @@ fn upgrade_gentoo(ctx: &ExecutionContext) -> Result<()> {
.status_checked()?;
}
println!("Syncing portage");
println!("{}", t!("Syncing portage"));
if let Some(ego) = which("ego") {
// The Funtoo team doesn't reccomend running both ego sync and emerge --sync
run_type.execute(sudo).arg(ego).arg("sync").status_checked()?;
@@ -528,7 +529,7 @@ fn upgrade_debian(ctx: &ExecutionContext) -> Result<()> {
return Ok(());
}
let sudo = require_option(ctx.sudo().as_ref(), REQUIRE_SUDO.to_string())?;
let sudo = require_option(ctx.sudo().as_ref(), get_require_sudo_string())?;
if !is_nala {
ctx.run_type()
.execute(sudo)
@@ -582,7 +583,7 @@ pub fn run_deb_get(ctx: &ExecutionContext) -> Result<()> {
}
fn upgrade_solus(ctx: &ExecutionContext) -> Result<()> {
let sudo = require_option(ctx.sudo().as_ref(), REQUIRE_SUDO.to_string())?;
let sudo = require_option(ctx.sudo().as_ref(), get_require_sudo_string())?;
let mut cmd = ctx.run_type().execute(sudo);
cmd.arg("eopkg");
if ctx.config().yes(Step::System) {
@@ -691,7 +692,7 @@ pub fn run_packer_nu(ctx: &ExecutionContext) -> Result<()> {
}
fn upgrade_clearlinux(ctx: &ExecutionContext) -> Result<()> {
let sudo = require_option(ctx.sudo().as_ref(), REQUIRE_SUDO.to_string())?;
let sudo = require_option(ctx.sudo().as_ref(), get_require_sudo_string())?;
let mut cmd = ctx.run_type().execute(sudo);
cmd.args(["swupd", "update"]);
if ctx.config().yes(Step::System) {
@@ -703,7 +704,7 @@ fn upgrade_clearlinux(ctx: &ExecutionContext) -> Result<()> {
}
fn upgrade_exherbo(ctx: &ExecutionContext) -> Result<()> {
let sudo = require_option(ctx.sudo().as_ref(), REQUIRE_SUDO.to_string())?;
let sudo = require_option(ctx.sudo().as_ref(), get_require_sudo_string())?;
ctx.run_type().execute(sudo).args(["cave", "sync"]).status_checked()?;
ctx.run_type()
@@ -732,7 +733,7 @@ fn upgrade_exherbo(ctx: &ExecutionContext) -> Result<()> {
}
fn upgrade_nixos(ctx: &ExecutionContext) -> Result<()> {
let sudo = require_option(ctx.sudo().as_ref(), REQUIRE_SUDO.to_string())?;
let sudo = require_option(ctx.sudo().as_ref(), get_require_sudo_string())?;
let mut command = ctx.run_type().execute(sudo);
command.args(["/run/current-system/sw/bin/nixos-rebuild", "switch", "--upgrade"]);
@@ -758,7 +759,7 @@ fn upgrade_neon(ctx: &ExecutionContext) -> Result<()> {
// seems rare
// if that comes up we need to create a Distribution::PackageKit or some such
let sudo = require_option(ctx.sudo().as_ref(), REQUIRE_SUDO.to_string())?;
let sudo = require_option(ctx.sudo().as_ref(), get_require_sudo_string())?;
let pkcon = which("pkcon").unwrap();
// pkcon ignores update with update and refresh provided together
ctx.run_type()
@@ -787,7 +788,7 @@ fn upgrade_neon(ctx: &ExecutionContext) -> Result<()> {
/// alternative
fn should_skip_needrestart() -> Result<()> {
let distribution = Distribution::detect()?;
let msg = "needrestart will be ran by the package manager";
let msg = t!("needrestart will be ran by the package manager");
if distribution.redhat_based() {
return Err(SkipStep(String::from(msg)).into());
@@ -822,12 +823,12 @@ fn should_skip_needrestart() -> Result<()> {
}
pub fn run_needrestart(ctx: &ExecutionContext) -> Result<()> {
let sudo = require_option(ctx.sudo().as_ref(), REQUIRE_SUDO.to_string())?;
let sudo = require_option(ctx.sudo().as_ref(), get_require_sudo_string())?;
let needrestart = require("needrestart")?;
should_skip_needrestart()?;
print_separator("Check for needed restarts");
print_separator(t!("Check for needed restarts"));
ctx.run_type().execute(sudo).arg(needrestart).status_checked()?;
@@ -838,10 +839,10 @@ pub fn run_fwupdmgr(ctx: &ExecutionContext) -> Result<()> {
let fwupdmgr = require("fwupdmgr")?;
if is_wsl()? {
return Err(SkipStep(String::from("Should not run in WSL")).into());
return Err(SkipStep(t!("Should not run in WSL").to_string()).into());
}
print_separator("Firmware upgrades");
print_separator(t!("Firmware upgrades"));
ctx.run_type()
.execute(&fwupdmgr)
@@ -863,7 +864,7 @@ pub fn run_fwupdmgr(ctx: &ExecutionContext) -> Result<()> {
pub fn run_flatpak(ctx: &ExecutionContext) -> Result<()> {
let flatpak = require("flatpak")?;
let sudo = require_option(ctx.sudo().as_ref(), REQUIRE_SUDO.to_string())?;
let sudo = require_option(ctx.sudo().as_ref(), get_require_sudo_string())?;
let cleanup = ctx.config().cleanup();
let yes = ctx.config().yes(Step::Flatpak);
let run_type = ctx.run_type();
@@ -883,7 +884,7 @@ pub fn run_flatpak(ctx: &ExecutionContext) -> Result<()> {
run_type.execute(&flatpak).args(&cleanup_args).status_checked()?;
}
print_separator("Flatpak System Packages");
print_separator(t!("Flatpak System Packages"));
if ctx.config().flatpak_use_sudo() || std::env::var("SSH_CLIENT").is_ok() {
let mut update_args = vec!["update", "--system"];
if yes {
@@ -924,11 +925,11 @@ pub fn run_flatpak(ctx: &ExecutionContext) -> Result<()> {
}
pub fn run_snap(ctx: &ExecutionContext) -> Result<()> {
let sudo = require_option(ctx.sudo().as_ref(), REQUIRE_SUDO.to_string())?;
let sudo = require_option(ctx.sudo().as_ref(), get_require_sudo_string())?;
let snap = require("snap")?;
if !PathBuf::from("/var/snapd.socket").exists() && !PathBuf::from("/run/snapd.socket").exists() {
return Err(SkipStep(String::from("Snapd socket does not exist")).into());
return Err(SkipStep(t!("Snapd socket does not exist").to_string()).into());
}
print_separator("snap");
@@ -936,7 +937,7 @@ pub fn run_snap(ctx: &ExecutionContext) -> Result<()> {
}
pub fn run_pihole_update(ctx: &ExecutionContext) -> Result<()> {
let sudo = require_option(ctx.sudo().as_ref(), REQUIRE_SUDO.to_string())?;
let sudo = require_option(ctx.sudo().as_ref(), get_require_sudo_string())?;
let pihole = require("pihole")?;
Path::new("/opt/pihole/update.sh").require()?;
@@ -970,7 +971,7 @@ pub fn run_distrobox_update(ctx: &ExecutionContext) -> Result<()> {
) {
(r, Some(c)) => {
if c.is_empty() {
return Err(SkipStep("You need to specify at least one container".to_string()).into());
return Err(SkipStep(t!("You need to specify at least one container").to_string()).into());
}
r.args(c)
}
@@ -985,7 +986,7 @@ pub fn run_distrobox_update(ctx: &ExecutionContext) -> Result<()> {
}
pub fn run_dkp_pacman_update(ctx: &ExecutionContext) -> Result<()> {
let sudo = require_option(ctx.sudo().as_ref(), REQUIRE_SUDO.to_string())?;
let sudo = require_option(ctx.sudo().as_ref(), get_require_sudo_string())?;
let dkp_pacman = require("dkp-pacman")?;
print_separator("Devkitpro pacman");
@@ -1008,20 +1009,20 @@ pub fn run_dkp_pacman_update(ctx: &ExecutionContext) -> Result<()> {
}
pub fn run_config_update(ctx: &ExecutionContext) -> Result<()> {
let sudo = require_option(ctx.sudo().as_ref(), REQUIRE_SUDO.to_string())?;
let sudo = require_option(ctx.sudo().as_ref(), get_require_sudo_string())?;
if ctx.config().yes(Step::ConfigUpdate) {
return Err(SkipStep("Skipped in --yes".to_string()).into());
return Err(SkipStep(t!("Skipped in --yes").to_string()).into());
}
if let Ok(etc_update) = require("etc-update") {
print_separator("Configuration update");
print_separator(t!("Configuration update"));
ctx.run_type().execute(sudo).arg(etc_update).status_checked()?;
} else if let Ok(pacdiff) = require("pacdiff") {
if std::env::var("DIFFPROG").is_err() {
require("vim")?;
}
print_separator("Configuration update");
print_separator(t!("Configuration update"));
ctx.execute_elevated(&pacdiff, false)?.status_checked()?;
}
@@ -1045,7 +1046,7 @@ pub fn run_lure_update(ctx: &ExecutionContext) -> Result<()> {
}
pub fn run_waydroid(ctx: &ExecutionContext) -> Result<()> {
let sudo = require_option(ctx.sudo().as_ref(), REQUIRE_SUDO.to_string())?;
let sudo = require_option(ctx.sudo().as_ref(), get_require_sudo_string())?;
let waydroid = require("waydroid")?;
let status = ctx.run_type().execute(&waydroid).arg("status").output_checked_utf8()?;
// example output of `waydroid status`:
@@ -1069,17 +1070,20 @@ pub fn run_waydroid(ctx: &ExecutionContext) -> Result<()> {
.stdout
.lines()
.find(|line| line.contains("Session:"))
.expect("the output of `waydroid status` should contain `Session:`");
.unwrap_or_else(|| panic!("the output of `waydroid status` should contain `Session:`"));
let is_container_running = session.contains("RUNNING");
let assume_yes = ctx.config().yes(Step::Waydroid);
print_separator("Waydroid");
if is_container_running && !assume_yes {
let update_allowed =
prompt_yesno("Going to execute `waydroid upgrade`, which would STOP the running container, is this ok?")?;
let update_allowed = prompt_yesno(&t!(
"Going to execute `waydroid upgrade`, which would STOP the running container, is this ok?"
))?;
if !update_allowed {
return Err(SkipStep("Skip the Waydroid step because the user don't want to proceed".to_string()).into());
return Err(
SkipStep(t!("Skip the Waydroid step because the user don't want to proceed").to_string()).into(),
);
}
}
ctx.run_type()
@@ -1090,7 +1094,7 @@ pub fn run_waydroid(ctx: &ExecutionContext) -> Result<()> {
}
pub fn run_auto_cpufreq(ctx: &ExecutionContext) -> Result<()> {
let sudo = require_option(ctx.sudo().as_ref(), REQUIRE_SUDO.to_string())?;
let sudo = require_option(ctx.sudo().as_ref(), get_require_sudo_string())?;
let auto_cpu_freq = require("auto-cpufreq")?;
print_separator("auto-cpufreq");

View File

@@ -1,9 +1,10 @@
use crate::command::CommandExt;
use crate::execution_context::ExecutionContext;
use crate::terminal::{print_separator, prompt_yesno};
use crate::utils::{require_option, REQUIRE_SUDO};
use crate::utils::{get_require_sudo_string, require_option};
use crate::{utils::require, Step};
use color_eyre::eyre::Result;
use rust_i18n::t;
use std::collections::HashSet;
use std::fs;
use std::process::Command;
@@ -11,7 +12,7 @@ use tracing::debug;
pub fn run_macports(ctx: &ExecutionContext) -> Result<()> {
require("port")?;
let sudo = require_option(ctx.sudo().as_ref(), REQUIRE_SUDO.to_string())?;
let sudo = require_option(ctx.sudo().as_ref(), get_require_sudo_string())?;
print_separator("MacPorts");
ctx.run_type()
@@ -34,25 +35,25 @@ pub fn run_macports(ctx: &ExecutionContext) -> Result<()> {
pub fn run_mas(ctx: &ExecutionContext) -> Result<()> {
let mas = require("mas")?;
print_separator("macOS App Store");
print_separator(t!("macOS App Store"));
ctx.run_type().execute(mas).arg("upgrade").status_checked()
}
pub fn upgrade_macos(ctx: &ExecutionContext) -> Result<()> {
print_separator("macOS system update");
print_separator(t!("macOS system update"));
let should_ask = !(ctx.config().yes(Step::System) || ctx.config().dry_run());
if should_ask {
println!("Finding available software");
println!("{}", t!("Finding available software"));
if system_update_available()? {
let answer = prompt_yesno("A system update is available. Do you wish to install it?")?;
let answer = prompt_yesno(t!("A system update is available. Do you wish to install it?").as_ref())?;
if !answer {
return Ok(());
}
println!();
} else {
println!("No new software available.");
println!("{}", t!("No new software available."));
return Ok(());
}
}
@@ -115,7 +116,7 @@ pub fn update_xcodes(ctx: &ExecutionContext) -> Result<()> {
.collect();
if releases_installed.is_empty() {
println!("No Xcode releases installed.");
println!("{}", t!("No Xcode releases installed."));
return Ok(());
}
@@ -194,7 +195,8 @@ pub fn update_xcodes(ctx: &ExecutionContext) -> Result<()> {
releases_regular_new_installed,
] {
if should_ask && releases_new_installed.len() == 2 {
let answer_uninstall = prompt_yesno("Would you like to move the former Xcode release to the trash?")?;
let answer_uninstall =
prompt_yesno(t!("Would you like to move the former Xcode release to the trash?").as_ref())?;
if answer_uninstall {
let _ = ctx
.run_type()
@@ -221,11 +223,12 @@ pub fn process_xcodes_releases(releases_filtered: Vec<String>, should_ask: bool,
&& !releases_filtered.is_empty()
{
println!(
"New Xcode release detected: {}",
"{} {}",
t!("New Xcode release detected:"),
releases_filtered.last().cloned().unwrap_or_default()
);
if should_ask {
let answer_install = prompt_yesno("Would you like to install it?")?;
let answer_install = prompt_yesno(t!("Would you like to install it?").as_ref())?;
if answer_install {
let _ = ctx
.run_type()

View File

@@ -1,12 +1,12 @@
use crate::command::CommandExt;
use crate::execution_context::ExecutionContext;
use crate::terminal::print_separator;
use crate::utils::{require_option, REQUIRE_SUDO};
use crate::utils::{get_require_sudo_string, require_option};
use color_eyre::eyre::Result;
pub fn upgrade_openbsd(ctx: &ExecutionContext) -> Result<()> {
let sudo = require_option(ctx.sudo().as_ref(), REQUIRE_SUDO.to_string())?;
print_separator("OpenBSD Update");
let sudo = require_option(ctx.sudo().as_ref(), get_require_sudo_string())?;
print_separator(t!("OpenBSD Update"));
ctx.run_type()
.execute(sudo)
.args(["/usr/sbin/sysupgrade", "-n"])
@@ -14,8 +14,8 @@ pub fn upgrade_openbsd(ctx: &ExecutionContext) -> Result<()> {
}
pub fn upgrade_packages(ctx: &ExecutionContext) -> Result<()> {
let sudo = require_option(ctx.sudo().as_ref(), REQUIRE_SUDO.to_string())?;
print_separator("OpenBSD Packages");
let sudo = require_option(ctx.sudo().as_ref(), get_require_sudo_string())?;
print_separator(t!("OpenBSD Packages"));
if ctx.config().cleanup() {
ctx.run_type()

View File

@@ -15,6 +15,7 @@ use home;
use ini::Ini;
#[cfg(target_os = "linux")]
use nix::unistd::Uid;
use rust_i18n::t;
use semver::Version;
use tracing::debug;
@@ -27,7 +28,7 @@ use crate::executor::Executor;
#[cfg(any(target_os = "linux", target_os = "macos"))]
use crate::executor::RunType;
use crate::terminal::print_separator;
use crate::utils::{require, require_option, PathExt, REQUIRE_SUDO};
use crate::utils::{get_require_sudo_string, require, require_option, PathExt};
#[cfg(any(target_os = "linux", target_os = "macos"))]
const INTEL_BREW: &str = "/usr/local/bin/brew";
@@ -101,19 +102,19 @@ pub fn run_fisher(ctx: &ExecutionContext) -> Result<()> {
.args(["-c", "type -t fisher"])
.output_checked_utf8()
.map(|_| ())
.map_err(|_| SkipStep("`fisher` is not defined in `fish`".to_owned()))?;
.map_err(|_| SkipStep(t!("`fisher` is not defined in `fish`").to_string()))?;
Command::new(&fish)
.args(["-c", "echo \"$__fish_config_dir/fish_plugins\""])
.output_checked_utf8()
.and_then(|output| Path::new(&output.stdout.trim()).require().map(|_| ()))
.map_err(|err| SkipStep(format!("`fish_plugins` path doesn't exist: {err}")))?;
.map_err(|err| SkipStep(t!("`fish_plugins` path doesn't exist: {err}", err = err).to_string()))?;
Command::new(&fish)
.args(["-c", "fish_update_completions"])
.output_checked_utf8()
.map(|_| ())
.map_err(|_| SkipStep("`fish_update_completions` is not available".to_owned()))?;
.map_err(|_| SkipStep(t!("`fish_update_completions` is not available").to_string()))?;
print_separator("Fisher");
@@ -180,7 +181,7 @@ pub fn run_oh_my_fish(ctx: &ExecutionContext) -> Result<()> {
pub fn run_pkgin(ctx: &ExecutionContext) -> Result<()> {
let pkgin = require("pkgin")?;
let sudo = require_option(ctx.sudo().as_ref(), REQUIRE_SUDO.to_string())?;
let sudo = require_option(ctx.sudo().as_ref(), get_require_sudo_string())?;
print_separator("Pkgin");
@@ -235,7 +236,7 @@ pub fn upgrade_gnome_extensions(ctx: &ExecutionContext) -> Result<()> {
let gdbus = require("gdbus")?;
require_option(
var("XDG_CURRENT_DESKTOP").ok().filter(|p| p.contains("GNOME")),
"Desktop doest not appear to be gnome".to_string(),
t!("Desktop doest not appear to be gnome").to_string(),
)?;
let output = Command::new("gdbus")
.args([
@@ -252,10 +253,10 @@ pub fn upgrade_gnome_extensions(ctx: &ExecutionContext) -> Result<()> {
debug!("Checking for gnome extensions: {}", output);
if !output.stdout.contains("org.gnome.Shell.Extensions") {
return Err(SkipStep(String::from("Gnome shell extensions are unregistered in DBus")).into());
return Err(SkipStep(t!("Gnome shell extensions are unregistered in DBus").to_string()).into());
}
print_separator("Gnome Shell extensions");
print_separator(t!("Gnome Shell extensions"));
ctx.run_type()
.execute(gdbus)
@@ -297,7 +298,7 @@ pub fn run_brew_formula(ctx: &ExecutionContext, variant: BrewVariant) -> Result<
#[cfg(target_os = "macos")]
{
if variant.is_path() && !BrewVariant::is_macos_custom(binary_name) {
return Err(SkipStep("Not a custom brew for macOS".to_string()).into());
return Err(SkipStep(t!("Not a custom brew for macOS").to_string()).into());
}
}
@@ -310,8 +311,11 @@ pub fn run_brew_formula(ctx: &ExecutionContext, variant: BrewVariant) -> Result<
let user = nix::unistd::User::from_uid(uid)
.expect("failed to call getpwuid()")
.expect("this user should exist");
print_separator(format!("{} (sudo as user '{}')", variant.step_title(), user.name));
let sudo = crate::utils::require_option(ctx.sudo().as_ref(), "sudo is needed to run the update".into())?;
let sudo_as_user = t!("sudo as user '{user}'", user = user.name);
print_separator(format!("{} ({})", variant.step_title(), sudo_as_user));
let sudo = crate::utils::require_option(ctx.sudo().as_ref(), crate::utils::get_require_sudo_string())?;
ctx.run_type()
.execute(sudo)
.current_dir("/tmp") // brew needs a writable current directory
@@ -354,7 +358,7 @@ pub fn run_brew_formula(ctx: &ExecutionContext, variant: BrewVariant) -> Result<
pub fn run_brew_cask(ctx: &ExecutionContext, variant: BrewVariant) -> Result<()> {
let binary_name = require(variant.binary_name())?;
if variant.is_path() && !BrewVariant::is_macos_custom(binary_name) {
return Err(SkipStep("Not a custom brew for macOS".to_string()).into());
return Err(SkipStep(t!("Not a custom brew for macOS").to_string()).into());
}
print_separator(format!("{} - Cask", variant.step_title()));
let run_type = ctx.run_type();
@@ -409,7 +413,7 @@ pub fn run_guix(ctx: &ExecutionContext) -> Result<()> {
if should_upgrade {
return run_type.execute(&guix).args(["package", "-u"]).status_checked();
}
Err(SkipStep(String::from("Guix Pull Failed, Skipping")).into())
Err(SkipStep(t!("Guix Pull Failed, Skipping").to_string()).into())
}
pub fn run_nix(ctx: &ExecutionContext) -> Result<()> {
@@ -429,41 +433,38 @@ pub fn run_nix(ctx: &ExecutionContext) -> Result<()> {
#[cfg(target_os = "macos")]
{
if require("darwin-rebuild").is_ok() {
return Err(SkipStep(String::from(
"Nix-darwin on macOS must be upgraded via darwin-rebuild switch",
))
.into());
return Err(
SkipStep(t!("Nix-darwin on macOS must be upgraded via darwin-rebuild switch").to_string()).into(),
);
}
}
let run_type = ctx.run_type();
run_type.execute(nix_channel).arg("--update").status_checked()?;
let version: Result<Version> = match Command::new(&nix)
.arg("--version")
.output_checked_utf8()?
let mut get_version_cmd = ctx.run_type().execute(&nix);
get_version_cmd.arg("--version");
let get_version_cmd_output = get_version_cmd.output_checked_utf8()?;
let get_version_cmd_first_line_stdout = get_version_cmd_output
.stdout
.lines()
.next()
{
Some(item) => {
let parts: Vec<&str> = item.split_whitespace().collect();
if parts.len() >= 3 {
Version::parse(parts[2]).map_err(|err| err.into())
} else {
Err(SkipStep(String::from("Unexpected version format")).into())
}
}
_ => return Err(SkipStep(String::from("Cannot find nix version")).into()),
.expect("nix --version gives an empty output");
let splitted: Vec<&str> = get_version_cmd_first_line_stdout.split_whitespace().collect();
let version = if splitted.len() >= 3 {
Version::parse(splitted[2]).expect("invalid version")
} else {
panic!("nix --version output format changed, file an issue to Topgrade!")
};
debug!("Nix version: {:?}", version);
let mut packages: Vec<&str> = vec!["--all", "--impure"];
if !matches!(version, Ok(version) if version >= Version::new(2, 21, 0)) {
packages = vec![".*"];
}
// Nix since 2.21.0 uses `--all --impure` rather than `.*` to upgrade all packages
let packages = if version >= Version::new(2, 21, 0) {
vec!["--all", "--impure"]
} else {
vec![".*"]
};
if Path::new(&manifest_json_path).exists() {
run_type
@@ -500,20 +501,16 @@ pub fn run_nix_self_upgrade(ctx: &ExecutionContext) -> Result<()> {
}
if !should_self_upgrade {
return Err(SkipStep(String::from(
"`nix upgrade-nix` can only be used on macOS or non-NixOS Linux",
))
.into());
return Err(SkipStep(t!("`nix upgrade-nix` can only be used on macOS or non-NixOS Linux").to_string()).into());
}
if nix_profile_dir(&nix)?.is_none() {
return Err(SkipStep(String::from(
"`nix upgrade-nix` cannot be run when Nix is installed in a profile",
))
.into());
return Err(
SkipStep(t!("`nix upgrade-nix` cannot be run when Nix is installed in a profile").to_string()).into(),
);
}
print_separator("Nix (self-upgrade)");
print_separator(t!("Nix (self-upgrade)"));
let multi_user = fs::metadata(&nix)?.uid() == 0;
debug!("Multi user nix: {}", multi_user);
@@ -578,7 +575,6 @@ fn nix_profile_dir(nix: &Path) -> Result<Option<PathBuf>> {
}
debug!("Found Nix profile {profile_dir:?}");
let user_env = profile_dir
.canonicalize()
.wrap_err_with(|| format!("Failed to canonicalize {profile_dir:?}"))?;
@@ -675,15 +671,15 @@ pub fn run_pyenv(ctx: &ExecutionContext) -> Result<()> {
.unwrap_or_else(|_| HOME_DIR.join(".pyenv"));
if !pyenv_dir.exists() {
return Err(SkipStep("Pyenv is installed, but $PYENV_ROOT is not set correctly".to_string()).into());
return Err(SkipStep(t!("Pyenv is installed, but $PYENV_ROOT is not set correctly").to_string()).into());
}
if !pyenv_dir.join(".git").exists() {
return Err(SkipStep("pyenv is not a git repository".to_string()).into());
return Err(SkipStep(t!("pyenv is not a git repository").to_string()).into());
}
if !pyenv_dir.join("plugins").join("pyenv-update").exists() {
return Err(SkipStep("pyenv-update plugin is not installed".to_string()).into());
return Err(SkipStep(t!("pyenv-update plugin is not installed").to_string()).into());
}
ctx.run_type().execute(pyenv).arg("update").status_checked()
@@ -755,7 +751,7 @@ pub fn run_sdkman(ctx: &ExecutionContext) -> Result<()> {
pub fn run_bun_packages(ctx: &ExecutionContext) -> Result<()> {
let bun = require("bun")?;
print_separator("Bun Packages");
print_separator(t!("Bun Packages"));
let mut package_json: PathBuf = var("BUN_INSTALL")
.map(PathBuf::from)
@@ -763,7 +759,7 @@ pub fn run_bun_packages(ctx: &ExecutionContext) -> Result<()> {
package_json.push("install/global/package.json");
if !package_json.exists() {
println!("No global packages installed");
println!("{}", t!("No global packages installed"));
return Ok(());
}
@@ -788,7 +784,7 @@ pub fn run_maza(ctx: &ExecutionContext) -> Result<()> {
}
pub fn reboot() -> Result<()> {
print!("Rebooting...");
print!("{}", t!("Rebooting..."));
cfg_if::cfg_if! {
if #[cfg(target_os = "linux")] {

View File

@@ -11,6 +11,7 @@ use crate::terminal::{print_separator, print_warning};
use crate::utils::{require, which};
use crate::{error::SkipStep, steps::git::RepoStep};
use crate::{powershell, Step};
use rust_i18n::t;
pub fn run_chocolatey(ctx: &ExecutionContext) -> Result<()> {
let choco = require("choco")?;
@@ -68,12 +69,12 @@ pub fn run_scoop(ctx: &ExecutionContext) -> Result<()> {
pub fn update_wsl(ctx: &ExecutionContext) -> Result<()> {
if !is_wsl_installed()? {
return Err(SkipStep("WSL not installed".to_string()).into());
return Err(SkipStep(t!("WSL not installed").to_string()).into());
}
let wsl = require("wsl")?;
print_separator("Update WSL");
print_separator(t!("Update WSL"));
let mut wsl_command = ctx.run_type().execute(wsl);
wsl_command.args(["--update"]);
@@ -126,7 +127,7 @@ fn upgrade_wsl_distribution(wsl: &Path, dist: &str, ctx: &ExecutionContext) -> R
let topgrade = Command::new(wsl)
.args(["-d", dist, "bash", "-lc", "which topgrade"])
.output_checked_utf8()
.map_err(|_| SkipStep(String::from("Could not find Topgrade installed in WSL")))?
.map_err(|_| SkipStep(t!("Could not find Topgrade installed in WSL").to_string()))?
.stdout // The normal output from `which topgrade` appends a newline, so we trim it here.
.trim_end()
.to_owned();
@@ -175,7 +176,7 @@ fn upgrade_wsl_distribution(wsl: &Path, dist: &str, ctx: &ExecutionContext) -> R
pub fn run_wsl_topgrade(ctx: &ExecutionContext) -> Result<()> {
if !is_wsl_installed()? {
return Err(SkipStep("WSL not installed".to_string()).into());
return Err(SkipStep(t!("WSL not installed").to_string()).into());
}
let wsl = require("wsl")?;
@@ -198,25 +199,25 @@ pub fn run_wsl_topgrade(ctx: &ExecutionContext) -> Result<()> {
if ran {
Ok(())
} else {
Err(SkipStep(String::from("Could not find Topgrade in any WSL disribution")).into())
Err(SkipStep(t!("Could not find Topgrade in any WSL disribution").to_string()).into())
}
}
pub fn windows_update(ctx: &ExecutionContext) -> Result<()> {
let powershell = powershell::Powershell::windows_powershell();
print_separator("Windows Update");
print_separator(t!("Windows Update"));
if powershell.supports_windows_update() {
println!("The installer will request to run as administrator, expect a prompt.");
powershell.windows_update(ctx)
} else {
print_warning(
"Consider installing PSWindowsUpdate Module as the use of Windows Update via USOClient is not supported.",
);
print_warning(t!(
"Consider installing PSWindowsUpdate as the use of Windows Update via USOClient is not supported."
));
Err(SkipStep("USOClient not supported.".to_string()).into())
Err(SkipStep(t!("USOClient not supported.").to_string()).into())
}
}