@@ -13,6 +13,10 @@
|
|||||||
# Do not ask to retry failed steps (default: false)
|
# Do not ask to retry failed steps (default: false)
|
||||||
#no_retry = true
|
#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 inside tmux
|
||||||
#run_in_tmux = true
|
#run_in_tmux = true
|
||||||
|
|
||||||
|
|||||||
@@ -269,6 +269,7 @@ pub struct Vim {
|
|||||||
#[serde(deny_unknown_fields)]
|
#[serde(deny_unknown_fields)]
|
||||||
/// Configuration file
|
/// Configuration file
|
||||||
pub struct ConfigFile {
|
pub struct ConfigFile {
|
||||||
|
pre_sudo: Option<bool>,
|
||||||
pre_commands: Option<Commands>,
|
pre_commands: Option<Commands>,
|
||||||
post_commands: Option<Commands>,
|
post_commands: Option<Commands>,
|
||||||
commands: Option<Commands>,
|
commands: Option<Commands>,
|
||||||
@@ -947,6 +948,12 @@ impl Config {
|
|||||||
.unwrap_or(false)
|
.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")]
|
#[cfg(target_os = "linux")]
|
||||||
pub fn npm_use_sudo(&self) -> bool {
|
pub fn npm_use_sudo(&self) -> bool {
|
||||||
self.config_file
|
self.config_file
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ mod self_renamer;
|
|||||||
#[cfg(feature = "self-update")]
|
#[cfg(feature = "self-update")]
|
||||||
mod self_update;
|
mod self_update;
|
||||||
mod steps;
|
mod steps;
|
||||||
|
mod sudo;
|
||||||
mod terminal;
|
mod terminal;
|
||||||
mod utils;
|
mod utils;
|
||||||
|
|
||||||
@@ -82,7 +83,7 @@ fn run() -> Result<()> {
|
|||||||
let git = git::Git::new();
|
let git = git::Git::new();
|
||||||
let mut git_repos = git::Repositories::new(&git);
|
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 run_type = executor::RunType::new(config.dry_run());
|
||||||
|
|
||||||
let ctx = execution_context::ExecutionContext::new(run_type, &sudo, &git, &config, &base_dirs);
|
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 powershell = powershell::Powershell::new();
|
||||||
let should_run_powershell = powershell.profile().is_some() && config.should_run(Step::Powershell);
|
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::path::PathBuf;
|
||||||
use std::process::Command;
|
use std::process::Command;
|
||||||
|
|
||||||
|
|
||||||
|
use crate::sudo;
|
||||||
use crate::utils::require_option;
|
use crate::utils::require_option;
|
||||||
use color_eyre::eyre::Result;
|
use color_eyre::eyre::Result;
|
||||||
#[cfg(target_os = "linux")]
|
#[cfg(target_os = "linux")]
|
||||||
@@ -93,7 +95,7 @@ impl NPM {
|
|||||||
fn upgrade(&self, run_type: RunType, use_sudo: bool) -> Result<()> {
|
fn upgrade(&self, run_type: RunType, use_sudo: bool) -> Result<()> {
|
||||||
let args = ["update", self.global_location_arg()];
|
let args = ["update", self.global_location_arg()];
|
||||||
if use_sudo {
|
if use_sudo {
|
||||||
let sudo_option = sudo();
|
let sudo_option = sudo::path();
|
||||||
let sudo = require_option(sudo_option, String::from("sudo is not installed"))?;
|
let sudo = require_option(sudo_option, String::from("sudo is not installed"))?;
|
||||||
run_type.execute(sudo).arg(&self.command).args(args).status_checked()?;
|
run_type.execute(sudo).arg(&self.command).args(args).status_checked()?;
|
||||||
} else {
|
} 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> {
|
pub fn editor() -> Vec<String> {
|
||||||
env::var("EDITOR")
|
env::var("EDITOR")
|
||||||
.unwrap_or_else(|_| String::from(if cfg!(windows) { "notepad" } else { "vi" }))
|
.unwrap_or_else(|_| String::from(if cfg!(windows) { "notepad" } else { "vi" }))
|
||||||
|
|||||||
Reference in New Issue
Block a user