diff --git a/config.example.toml b/config.example.toml index ef155cb2..4c6bff93 100644 --- a/config.example.toml +++ b/config.example.toml @@ -13,6 +13,9 @@ # Do not ask to retry failed steps (default: false) #no_retry = true +# Sudo command to be used +#sudo_command = "sudo" + # Run `sudo -v` to cache credentials at the start of the run; this avoids a # blocking password prompt in the middle of a possibly-unattended run. #pre_sudo = false diff --git a/src/config.rs b/src/config.rs index 84223e06..de2879f8 100644 --- a/src/config.rs +++ b/src/config.rs @@ -18,6 +18,7 @@ use tracing::debug; use which_crate::which; use crate::command::CommandExt; +use crate::sudo::SudoKind; use super::utils::{editor, hostname}; @@ -293,6 +294,7 @@ pub struct Vim { #[serde(deny_unknown_fields)] /// Configuration file pub struct ConfigFile { + sudo_command: Option, pre_sudo: Option, pre_commands: Option, post_commands: Option, @@ -1017,6 +1019,10 @@ impl Config { .unwrap_or(false) } + pub fn sudo_command(&self) -> Option { + self.config_file.sudo_command + } + /// If `true`, `sudo` should be called after `pre_commands` in order to elevate at the /// start of the session (and not in the middle). pub fn pre_sudo(&self) -> bool { diff --git a/src/main.rs b/src/main.rs index 8d3bc20d..26394893 100644 --- a/src/main.rs +++ b/src/main.rs @@ -107,7 +107,7 @@ For more information about this issue see https://askubuntu.com/questions/110969 let git = git::Git::new(); let mut git_repos = git::Repositories::new(&git); - let sudo = sudo::Sudo::detect(); + let sudo = config.sudo_command().map_or_else(sudo::Sudo::detect, sudo::Sudo::new); let run_type = executor::RunType::new(config.dry_run()); let ctx = execution_context::ExecutionContext::new(run_type, sudo, &git, &config, &base_dirs); diff --git a/src/sudo.rs b/src/sudo.rs index 85b65795..094ac42f 100644 --- a/src/sudo.rs +++ b/src/sudo.rs @@ -4,6 +4,8 @@ use std::path::PathBuf; use color_eyre::eyre::Context; use color_eyre::eyre::Result; +use serde::Deserialize; +use strum::AsRefStr; use crate::command::CommandExt; use crate::execution_context::ExecutionContext; @@ -31,6 +33,11 @@ impl Sudo { .map(|(path, kind)| Self { path, kind }) } + /// Create Sudo from SudoKind, if found in the system + pub fn new(kind: SudoKind) -> Option { + which(kind.as_ref()).map(|path| Self { path, kind }) + } + /// Elevate permissions with `sudo`. /// /// This helps prevent blocking `sudo` prompts from stopping the run in the middle of a @@ -100,8 +107,10 @@ impl Sudo { } } -#[derive(Clone, Copy, Debug)] -enum SudoKind { +#[derive(Clone, Copy, Debug, Deserialize, AsRefStr)] +#[serde(rename_all = "lowercase")] +#[strum(serialize_all = "lowercase")] +pub enum SudoKind { Doas, Please, Sudo,