@@ -13,6 +13,10 @@
|
||||
# Do not ask to retry failed steps (default: false)
|
||||
#no_retry = true
|
||||
|
||||
# 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
|
||||
|
||||
# Run inside tmux
|
||||
#run_in_tmux = true
|
||||
|
||||
|
||||
@@ -269,6 +269,7 @@ pub struct Vim {
|
||||
#[serde(deny_unknown_fields)]
|
||||
/// Configuration file
|
||||
pub struct ConfigFile {
|
||||
pre_sudo: Option<bool>,
|
||||
pre_commands: Option<Commands>,
|
||||
post_commands: Option<Commands>,
|
||||
commands: Option<Commands>,
|
||||
@@ -947,6 +948,12 @@ impl Config {
|
||||
.unwrap_or(false)
|
||||
}
|
||||
|
||||
/// 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 {
|
||||
self.config_file.pre_sudo.unwrap_or(false)
|
||||
}
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
pub fn npm_use_sudo(&self) -> bool {
|
||||
self.config_file
|
||||
|
||||
@@ -30,6 +30,7 @@ mod self_renamer;
|
||||
#[cfg(feature = "self-update")]
|
||||
mod self_update;
|
||||
mod steps;
|
||||
mod sudo;
|
||||
mod terminal;
|
||||
mod utils;
|
||||
|
||||
@@ -82,7 +83,7 @@ fn run() -> Result<()> {
|
||||
let git = git::Git::new();
|
||||
let mut git_repos = git::Repositories::new(&git);
|
||||
|
||||
let sudo = utils::sudo();
|
||||
let sudo = sudo::path();
|
||||
let run_type = executor::RunType::new(config.dry_run());
|
||||
|
||||
let ctx = execution_context::ExecutionContext::new(run_type, &sudo, &git, &config, &base_dirs);
|
||||
@@ -119,6 +120,10 @@ fn run() -> Result<()> {
|
||||
}
|
||||
}
|
||||
|
||||
if config.pre_sudo() {
|
||||
sudo::elevate(&ctx, sudo.as_ref())?;
|
||||
}
|
||||
|
||||
let powershell = powershell::Powershell::new();
|
||||
let should_run_powershell = powershell.profile().is_some() && config.should_run(Step::Powershell);
|
||||
|
||||
|
||||
@@ -4,6 +4,8 @@ use std::os::unix::fs::MetadataExt;
|
||||
use std::path::PathBuf;
|
||||
use std::process::Command;
|
||||
|
||||
|
||||
use crate::sudo;
|
||||
use crate::utils::require_option;
|
||||
use color_eyre::eyre::Result;
|
||||
#[cfg(target_os = "linux")]
|
||||
@@ -93,7 +95,7 @@ impl NPM {
|
||||
fn upgrade(&self, run_type: RunType, use_sudo: bool) -> Result<()> {
|
||||
let args = ["update", self.global_location_arg()];
|
||||
if use_sudo {
|
||||
let sudo_option = sudo();
|
||||
let sudo_option = sudo::path();
|
||||
let sudo = require_option(sudo_option, String::from("sudo is not installed"))?;
|
||||
run_type.execute(sudo).arg(&self.command).args(args).status_checked()?;
|
||||
} else {
|
||||
|
||||
34
src/sudo.rs
Normal file
34
src/sudo.rs
Normal file
@@ -0,0 +1,34 @@
|
||||
use std::path::PathBuf;
|
||||
|
||||
use color_eyre::eyre::Context;
|
||||
use color_eyre::eyre::Result;
|
||||
|
||||
use crate::command::CommandExt;
|
||||
use crate::execution_context::ExecutionContext;
|
||||
use crate::terminal::print_separator;
|
||||
use crate::utils::which;
|
||||
|
||||
/// Get the path of the `sudo` utility.
|
||||
///
|
||||
/// Detects `doas`, `sudo`, `gsudo`, or `pkexec`.
|
||||
pub fn path() -> Option<PathBuf> {
|
||||
which("doas")
|
||||
.or_else(|| which("sudo"))
|
||||
.or_else(|| which("gsudo"))
|
||||
.or_else(|| which("pkexec"))
|
||||
}
|
||||
|
||||
/// Elevate permissions with `sudo`.
|
||||
pub fn elevate(ctx: &ExecutionContext, sudo: Option<&PathBuf>) -> Result<()> {
|
||||
if let Some(sudo) = sudo {
|
||||
print_separator("Sudo");
|
||||
ctx.run_type()
|
||||
.execute(sudo)
|
||||
// TODO: Does this work with `doas`, `pkexec`, `gsudo`, GNU `sudo`...?
|
||||
.arg("-v")
|
||||
.status_checked()
|
||||
.wrap_err("Failed to elevate permissions")?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@@ -67,13 +67,6 @@ pub fn which<T: AsRef<OsStr> + Debug>(binary_name: T) -> Option<PathBuf> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn sudo() -> Option<PathBuf> {
|
||||
which("doas")
|
||||
.or_else(|| which("sudo"))
|
||||
.or_else(|| which("gsudo"))
|
||||
.or_else(|| which("pkexec"))
|
||||
}
|
||||
|
||||
pub fn editor() -> Vec<String> {
|
||||
env::var("EDITOR")
|
||||
.unwrap_or_else(|_| String::from(if cfg!(windows) { "notepad" } else { "vi" }))
|
||||
|
||||
Reference in New Issue
Block a user