feat(sudo): print warning if steps were skipped due to missing sudo
This commit is contained in:
@@ -1138,14 +1138,46 @@ _version: 2
|
|||||||
zh_CN: "Topgrade 不应以 root 身份运行,它会在需要时使用 sudo 或等效工具执行命令。"
|
zh_CN: "Topgrade 不应以 root 身份运行,它会在需要时使用 sudo 或等效工具执行命令。"
|
||||||
zh_TW: "Topgrade 不應以 root 身份執行,它會在需要時使用 sudo 或等效工具執行命令。"
|
zh_TW: "Topgrade 不應以 root 身份執行,它會在需要時使用 sudo 或等效工具執行命令。"
|
||||||
de: "Topgrade sollte nicht als Root ausgeführt werden, es führt Befehle mit sudo oder einem Äquivalent aus, wenn erforderlich."
|
de: "Topgrade sollte nicht als Root ausgeführt werden, es führt Befehle mit sudo oder einem Äquivalent aus, wenn erforderlich."
|
||||||
"Require sudo or counterpart but not found, skip":
|
"Could not find sudo":
|
||||||
en: "Require sudo or counterpart but not found, skip"
|
en: "Could not find sudo"
|
||||||
lt: "Reikalingas sudo arba atitikmuo, bet nerasta, praleidžiama"
|
lt: "Nepavyko rasti sudo"
|
||||||
es: "Se requiere sudo o su equivalente pero no ha sido encontrado, omitiendo"
|
es: "No se pudo encontrar sudo"
|
||||||
fr: "Nécessite sudo ou un équivalent mais n'a pas été trouvé, passé"
|
fr: "Impossible de trouver sudo"
|
||||||
zh_CN: "找不到权限管理程序(sudo 等),跳过"
|
zh_CN: "未找到 sudo"
|
||||||
zh_TW: "找不到權限管理程式(sudo 等),略過"
|
zh_TW: "找不到 sudo"
|
||||||
de: "Benötigt sudo oder Äquivalent, aber nicht gefunden, überspringe"
|
de: "Konnte sudo nicht finden"
|
||||||
|
"Skipping step, sudo is required":
|
||||||
|
en: "Skipping step, sudo is required"
|
||||||
|
lt: "Žingsnis praleidžiamas, reikalingas sudo"
|
||||||
|
es: "Omitiendo paso, se requiere sudo"
|
||||||
|
fr: "Étape ignorée, sudo est requis"
|
||||||
|
zh_CN: "跳过步骤,需要 sudo"
|
||||||
|
zh_TW: "跳過步驟,需要 sudo"
|
||||||
|
de: "Schritt wird übersprungen, sudo ist erforderlich"
|
||||||
|
"\nSome steps were skipped as sudo or equivalent could not be found.":
|
||||||
|
en: "\nSome steps were skipped as sudo or equivalent could not be found."
|
||||||
|
lt: "\nKai kurie veiksmai buvo praleisti, nes nepavyko rasti sudo ar atitikmens."
|
||||||
|
es: "\nAlgunos pasos se omitieron porque no se pudo encontrar sudo o equivalente."
|
||||||
|
fr: "\nCertaines étapes ont été ignorées car sudo ou équivalent est introuvable."
|
||||||
|
zh_CN: "\n由于未找到 sudo 或等效工具,某些步骤被跳过。"
|
||||||
|
zh_TW: "\n由於找不到 sudo 或等效工具,某些步驟已跳過。"
|
||||||
|
de: "\nEinige Schritte wurden übersprungen, da sudo oder ein Äquivalent nicht gefunden wurde."
|
||||||
|
"Install one of `sudo`, `doas`, `pkexec`, `run0` or `please` to run these steps.":
|
||||||
|
en: "Install one of `sudo`, `doas`, `pkexec`, `run0` or `please` to run these steps."
|
||||||
|
lt: "Įdiekite vieną iš `sudo`, `doas`, `pkexec`, `run0` arba `please`, kad vykdytumėte šiuos veiksmus."
|
||||||
|
es: "Instale uno de `sudo`, `doas`, `pkexec`, `run0` o `please` para ejecutar estos pasos."
|
||||||
|
fr: "Installez l’un de `sudo`, `doas`, `pkexec`, `run0` ou `please` pour exécuter ces étapes."
|
||||||
|
zh_CN: "请安装 `sudo`、`doas`、`pkexec`、`run0` 或 `please` 之一来运行这些步骤。"
|
||||||
|
zh_TW: "請安裝 `sudo`、`doas`、`pkexec`、`run0` 或 `please` 之一來執行這些步驟。"
|
||||||
|
de: "Installieren Sie `sudo`, `doas`, `pkexec`, `run0` oder `please`, um diese Schritte auszuführen."
|
||||||
|
"Install gsudo or enable Windows Sudo to run these steps.":
|
||||||
|
en: "Install gsudo or enable Windows Sudo to run these steps."
|
||||||
|
lt: "Įdiekite gsudo arba įjunkite Windows Sudo, kad vykdytumėte šiuos veiksmus."
|
||||||
|
es: "Instale gsudo o habilite Windows Sudo para ejecutar estos pasos."
|
||||||
|
fr: "Installez gsudo ou activez Windows Sudo pour exécuter ces étapes."
|
||||||
|
zh_CN: "请安装 gsudo 或启用 Windows Sudo 来运行这些步骤。"
|
||||||
|
zh_TW: "請安裝 gsudo 或啟用 Windows Sudo 來執行這些步驟。"
|
||||||
|
de: "Installieren Sie gsudo oder aktivieren Sie Windows Sudo, um diese Schritte auszuführen."
|
||||||
"{sudo_kind} does not support the {option} option":
|
"{sudo_kind} does not support the {option} option":
|
||||||
en: "%{sudo_kind} does not support the %{option} option"
|
en: "%{sudo_kind} does not support the %{option} option"
|
||||||
lt: "%{sudo_kind} nepalaiko parinkties %{option}"
|
lt: "%{sudo_kind} nepalaiko parinkties %{option}"
|
||||||
|
|||||||
@@ -90,6 +90,15 @@ impl Display for UnsupportedSudo<'_> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Error, Debug)]
|
||||||
|
pub struct MissingSudo();
|
||||||
|
|
||||||
|
impl Display for MissingSudo {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
write!(f, "{}", t!("Could not find sudo"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Error, Debug)]
|
#[derive(Error, Debug)]
|
||||||
pub struct DryRun();
|
pub struct DryRun();
|
||||||
|
|
||||||
|
|||||||
@@ -6,13 +6,14 @@ use std::ffi::OsStr;
|
|||||||
use std::process::Command;
|
use std::process::Command;
|
||||||
use std::sync::{LazyLock, Mutex};
|
use std::sync::{LazyLock, Mutex};
|
||||||
|
|
||||||
use crate::executor::DryCommand;
|
use crate::config::Config;
|
||||||
|
use crate::error::MissingSudo;
|
||||||
|
use crate::executor::{DryCommand, Executor};
|
||||||
use crate::powershell::Powershell;
|
use crate::powershell::Powershell;
|
||||||
#[cfg(target_os = "linux")]
|
#[cfg(target_os = "linux")]
|
||||||
use crate::steps::linux::Distribution;
|
use crate::steps::linux::Distribution;
|
||||||
use crate::sudo::Sudo;
|
use crate::sudo::Sudo;
|
||||||
use crate::utils::require_option;
|
use crate::utils::require_option;
|
||||||
use crate::{config::Config, executor::Executor};
|
|
||||||
|
|
||||||
/// An enum telling whether Topgrade should perform dry runs or actually perform the steps.
|
/// An enum telling whether Topgrade should perform dry runs or actually perform the steps.
|
||||||
#[derive(Clone, Copy, Debug)]
|
#[derive(Clone, Copy, Debug)]
|
||||||
@@ -95,10 +96,11 @@ impl<'a> ExecutionContext<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn require_sudo(&self) -> Result<&Sudo> {
|
pub fn require_sudo(&self) -> Result<&Sudo> {
|
||||||
require_option(
|
if let Some(value) = self.sudo() {
|
||||||
self.sudo.as_ref(),
|
Ok(value)
|
||||||
t!("Require sudo or counterpart but not found, skip").to_string(),
|
} else {
|
||||||
)
|
Err(MissingSudo().into())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn config(&self) -> &Config {
|
pub fn config(&self) -> &Config {
|
||||||
|
|||||||
19
src/main.rs
19
src/main.rs
@@ -25,6 +25,7 @@ use self::config::{CommandLineArgs, Config};
|
|||||||
use self::error::StepFailed;
|
use self::error::StepFailed;
|
||||||
#[cfg(all(windows, feature = "self-update"))]
|
#[cfg(all(windows, feature = "self-update"))]
|
||||||
use self::error::Upgraded;
|
use self::error::Upgraded;
|
||||||
|
use self::runner::StepResult;
|
||||||
#[allow(clippy::wildcard_imports)]
|
#[allow(clippy::wildcard_imports)]
|
||||||
use self::steps::{remote::*, *};
|
use self::steps::{remote::*, *};
|
||||||
use self::sudo::{Sudo, SudoKind};
|
use self::sudo::{Sudo, SudoKind};
|
||||||
@@ -224,12 +225,30 @@ fn run() -> Result<()> {
|
|||||||
if !report.is_empty() {
|
if !report.is_empty() {
|
||||||
print_separator(t!("Summary"));
|
print_separator(t!("Summary"));
|
||||||
|
|
||||||
|
let mut skipped_missing_sudo = false;
|
||||||
|
|
||||||
for (key, result) in report {
|
for (key, result) in report {
|
||||||
if !failed && result.failed() {
|
if !failed && result.failed() {
|
||||||
failed = true;
|
failed = true;
|
||||||
}
|
}
|
||||||
|
if let StepResult::SkippedMissingSudo = result {
|
||||||
|
skipped_missing_sudo = true;
|
||||||
|
}
|
||||||
print_result(key, result);
|
print_result(key, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if skipped_missing_sudo {
|
||||||
|
print_warning(t!(
|
||||||
|
"\nSome steps were skipped as sudo or equivalent could not be found."
|
||||||
|
));
|
||||||
|
|
||||||
|
#[cfg(unix)]
|
||||||
|
print_warning(t!(
|
||||||
|
"Install one of `sudo`, `doas`, `pkexec`, `run0` or `please` to run these steps."
|
||||||
|
));
|
||||||
|
#[cfg(windows)]
|
||||||
|
print_warning(t!("Install gsudo or enable Windows Sudo to run these steps."));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(target_os = "linux")]
|
#[cfg(target_os = "linux")]
|
||||||
|
|||||||
@@ -1,18 +1,20 @@
|
|||||||
use color_eyre::eyre::Result;
|
use color_eyre::eyre::Result;
|
||||||
|
use rust_i18n::t;
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
use std::fmt::Debug;
|
use std::fmt::Debug;
|
||||||
use tracing::debug;
|
use tracing::debug;
|
||||||
|
|
||||||
use crate::ctrlc;
|
use crate::ctrlc;
|
||||||
use crate::error::{DryRun, SkipStep};
|
use crate::error::{DryRun, MissingSudo, SkipStep};
|
||||||
use crate::execution_context::ExecutionContext;
|
use crate::execution_context::ExecutionContext;
|
||||||
use crate::step::Step;
|
use crate::step::Step;
|
||||||
use crate::terminal::{print_error, should_retry};
|
use crate::terminal::{print_error, print_warning, should_retry};
|
||||||
|
|
||||||
pub enum StepResult {
|
pub enum StepResult {
|
||||||
Success,
|
Success,
|
||||||
Failure,
|
Failure,
|
||||||
Ignored,
|
Ignored,
|
||||||
|
SkippedMissingSudo,
|
||||||
Skipped(String),
|
Skipped(String),
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -21,7 +23,7 @@ impl StepResult {
|
|||||||
use StepResult::*;
|
use StepResult::*;
|
||||||
|
|
||||||
match self {
|
match self {
|
||||||
Success | Ignored | Skipped(_) => false,
|
Success | Ignored | Skipped(_) | SkippedMissingSudo => false,
|
||||||
Failure => true,
|
Failure => true,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -74,6 +76,11 @@ impl<'a> Runner<'a> {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
Err(e) if e.downcast_ref::<DryRun>().is_some() => break,
|
Err(e) if e.downcast_ref::<DryRun>().is_some() => break,
|
||||||
|
Err(e) if e.downcast_ref::<MissingSudo>().is_some() => {
|
||||||
|
print_warning(t!("Skipping step, sudo is required"));
|
||||||
|
self.push_result(key, StepResult::SkippedMissingSudo);
|
||||||
|
break;
|
||||||
|
}
|
||||||
Err(e) if e.downcast_ref::<SkipStep>().is_some() => {
|
Err(e) if e.downcast_ref::<SkipStep>().is_some() => {
|
||||||
if self.ctx.config().verbose() || self.ctx.config().show_skipped() {
|
if self.ctx.config().verbose() || self.ctx.config().show_skipped() {
|
||||||
self.push_result(key, StepResult::Skipped(e.to_string()));
|
self.push_result(key, StepResult::Skipped(e.to_string()));
|
||||||
|
|||||||
@@ -173,6 +173,11 @@ impl Terminal {
|
|||||||
StepResult::Success => format!("{}", style(t!("OK")).bold().green()),
|
StepResult::Success => format!("{}", style(t!("OK")).bold().green()),
|
||||||
StepResult::Failure => format!("{}", style(t!("FAILED")).bold().red()),
|
StepResult::Failure => format!("{}", style(t!("FAILED")).bold().red()),
|
||||||
StepResult::Ignored => format!("{}", style(t!("IGNORED")).bold().yellow()),
|
StepResult::Ignored => format!("{}", style(t!("IGNORED")).bold().yellow()),
|
||||||
|
StepResult::SkippedMissingSudo => format!(
|
||||||
|
"{}: {}",
|
||||||
|
style(t!("SKIPPED")).bold().yellow(),
|
||||||
|
t!("Could not find sudo")
|
||||||
|
),
|
||||||
StepResult::Skipped(reason) => format!("{}: {}", style(t!("SKIPPED")).bold().blue(), reason),
|
StepResult::Skipped(reason) => format!("{}: {}", style(t!("SKIPPED")).bold().blue(), reason),
|
||||||
}
|
}
|
||||||
))
|
))
|
||||||
|
|||||||
Reference in New Issue
Block a user