@@ -4,6 +4,23 @@ use std::{
44 process:: { Command , Stdio } ,
55} ;
66
7+ fn is_root_user ( ) -> bool {
8+ #[ cfg( unix) ]
9+ return nix:: unistd:: Uid :: current ( ) . is_root ( ) ;
10+ #[ cfg( not( unix) ) ]
11+ return false ;
12+ }
13+
14+ fn is_sudo_available ( ) -> bool {
15+ Command :: new ( "sudo" )
16+ . arg ( "--version" )
17+ . stdout ( Stdio :: null ( ) )
18+ . stderr ( Stdio :: null ( ) )
19+ . status ( )
20+ . map ( |status| status. success ( ) )
21+ . unwrap_or ( false )
22+ }
23+
724/// Validate sudo access, prompting the user for their password if necessary
825fn validate_sudo_access ( ) -> Result < ( ) > {
926 let needs_password = IsTerminal :: is_terminal ( & std:: io:: stdout ( ) )
@@ -49,12 +66,30 @@ pub fn validated_sudo_command() -> Result<Command> {
4966 Ok ( cmd)
5067}
5168
69+ /// Build a command wrapped with sudo if possible
70+ pub fn build_command_with_sudo ( command_args : & [ & str ] ) -> Result < Command > {
71+ let command_str = command_args. join ( " " ) ;
72+ if is_root_user ( ) {
73+ debug ! ( "Running command without sudo: {command_str}" ) ;
74+ let mut c = Command :: new ( command_args[ 0 ] ) ;
75+ c. args ( & command_args[ 1 ..] ) ;
76+ Ok ( c)
77+ } else if is_sudo_available ( ) {
78+ debug ! ( "Sudo is required for command: {command_str}" ) ;
79+ let mut c = validated_sudo_command ( ) ?;
80+ c. args ( command_args) ;
81+ Ok ( c)
82+ } else {
83+ bail ! ( "Sudo is not available to run the command: {command_str}" ) ;
84+ }
85+ }
86+
5287/// Run a command with sudo after validating sudo access
5388pub fn run_with_sudo ( command_args : & [ & str ] ) -> Result < ( ) > {
5489 let command_str = command_args. join ( " " ) ;
5590 debug ! ( "Running command with sudo: {command_str}" ) ;
56- let output = validated_sudo_command ( ) ?
57- . args ( command_args )
91+ let mut cmd = build_command_with_sudo ( command_args ) ? ;
92+ let output = cmd
5893 . stdout ( Stdio :: piped ( ) )
5994 . output ( )
6095 . map_err ( |_| anyhow ! ( "Failed to execute command with sudo: {command_str}" ) ) ?;
0 commit comments