2020-01-28 16:27:43 +02:00
#![ allow(unused_imports) ]
2020-04-03 11:47:51 +03:00
2019-01-01 22:22:07 +02:00
use crate ::executor ::{ CommandExt , RunType } ;
2018-12-15 21:52:21 +02:00
use crate ::terminal ::print_separator ;
2019-03-10 21:48:49 +02:00
use crate ::utils ::{ require , PathExt } ;
2020-10-01 15:59:06 -04:00
use crate ::{ error ::SkipStep , execution_context ::ExecutionContext } ;
2019-12-11 23:05:38 +02:00
use anyhow ::Result ;
2018-08-19 14:45:23 +03:00
use directories ::BaseDirs ;
2021-01-14 09:49:18 +02:00
use log ::debug ;
#[ cfg(unix) ]
use nix ::unistd ::Uid ;
#[ cfg(unix) ]
use std ::os ::unix ::prelude ::MetadataExt ;
2018-08-19 14:45:23 +03:00
use std ::path ::PathBuf ;
use std ::process ::Command ;
2021-04-06 09:52:34 +03:00
#[ allow(clippy::upper_case_acronyms) ]
2018-08-19 14:45:23 +03:00
struct NPM {
command : PathBuf ,
}
impl NPM {
fn new ( command : PathBuf ) -> Self {
Self { command }
}
2021-01-14 09:49:18 +02:00
#[ cfg(target_os = " linux " ) ]
2019-12-11 23:05:38 +02:00
fn root ( & self ) -> Result < PathBuf > {
2019-01-01 22:22:07 +02:00
Command ::new ( & self . command )
2021-09-04 20:01:19 +02:00
. args ( [ " root " , " -g " ] )
2019-01-01 22:22:07 +02:00
. check_output ( )
2021-01-15 06:59:13 +02:00
. map ( | s | PathBuf ::from ( s . trim ( ) ) )
2018-08-19 14:45:23 +03:00
}
2021-06-09 10:52:48 +03:00
fn upgrade ( & self , run_type : RunType , use_sudo : bool ) -> Result < ( ) > {
if use_sudo {
run_type
. execute ( " sudo " )
. arg ( & self . command )
2021-09-04 20:01:19 +02:00
. args ( [ " update " , " -g " ] )
2021-06-09 10:52:48 +03:00
. check_run ( ) ? ;
} else {
2021-09-04 20:01:19 +02:00
run_type . execute ( & self . command ) . args ( [ " update " , " -g " ] ) . check_run ( ) ? ;
2021-06-09 10:52:48 +03:00
}
2018-08-19 14:45:23 +03:00
Ok ( ( ) )
}
2020-01-28 16:27:43 +02:00
2021-01-14 09:49:18 +02:00
#[ cfg(target_os = " linux " ) ]
2021-10-25 22:27:35 +03:00
pub fn should_use_sudo ( & self ) -> Result < bool > {
let npm_root = self . root ( ) ? ;
2021-01-15 06:59:13 +02:00
if ! npm_root . exists ( ) {
return Err ( SkipStep ( format! ( " NPM root at {} doesn't exist " , npm_root . display ( ) , ) ) . into ( ) ) ;
}
2021-01-14 09:49:18 +02:00
let metadata = std ::fs ::metadata ( & npm_root ) ? ;
let uid = Uid ::effective ( ) ;
2021-10-25 22:27:35 +03:00
Ok ( metadata . uid ( ) ! = uid . as_raw ( ) & & metadata . uid ( ) = = 0 )
}
}
#[ cfg(target_os = " linux " ) ]
fn should_use_sudo ( npm : & NPM , ctx : & ExecutionContext ) -> Result < bool > {
if npm . should_use_sudo ( ) ? {
if ctx . config ( ) . npm_use_sudo ( ) {
Ok ( true )
} else {
Err ( SkipStep ( " NPM root is owned by another user which is not the current user. Set use_sudo = true under the NPM section in your configuration to run NPM as sudo " . to_string ( ) )
. into ( ) )
2020-01-28 16:27:43 +02:00
}
2021-10-25 22:27:35 +03:00
} else {
Ok ( false )
2018-08-19 14:45:23 +03:00
}
2021-10-25 22:27:35 +03:00
}
pub fn run_npm_upgrade ( ctx : & ExecutionContext ) -> Result < ( ) > {
let npm = require ( " npm " ) . map ( NPM ::new ) ? ;
2018-08-19 14:45:23 +03:00
2019-03-10 21:48:49 +02:00
print_separator ( " Node Package Manager " ) ;
2021-10-25 22:27:35 +03:00
#[ cfg(target_os = " linux " ) ]
{
npm . upgrade ( ctx . run_type ( ) , should_use_sudo ( & npm , ctx ) ? )
}
#[ cfg(not(target_os = " linux " )) ]
{
npm . upgrade ( ctx . run_type ( ) , false )
}
2019-03-10 21:48:49 +02:00
}
2018-08-19 14:45:23 +03:00
2021-10-25 22:27:35 +03:00
pub fn pnpm_global_update ( ctx : & ExecutionContext ) -> Result < ( ) > {
2021-06-27 14:48:46 +02:00
let pnpm = require ( " pnpm " ) ? ;
print_separator ( " Performant Node Package Manager " ) ;
2021-10-25 22:27:35 +03:00
#[ cfg(target_os = " linux " ) ]
if should_use_sudo ( & require ( " npm " ) . map ( NPM ::new ) ? , ctx ) ? {
ctx . run_type ( )
. execute ( " sudo " )
. arg ( pnpm )
. args ( [ " update " , " -g " ] )
. check_run ( )
} else {
ctx . run_type ( ) . execute ( & pnpm ) . args ( [ " update " , " -g " ] ) . check_run ( )
}
#[ cfg(not(target_os = " linux " )) ]
ctx . run_type ( ) . execute ( & pnpm ) . args ( [ " update " , " -g " ] ) . check_run ( )
2021-06-27 14:48:46 +02:00
}
2020-10-01 15:59:06 -04:00
pub fn deno_upgrade ( ctx : & ExecutionContext ) -> Result < ( ) > {
let deno = require ( " deno " ) ? ;
2021-09-02 18:53:48 +02:00
let deno_dir = ctx . base_dirs ( ) . home_dir ( ) . join ( " .deno " ) ;
if ! deno . canonicalize ( ) ? . is_descendant_of ( & deno_dir ) {
let skip_reason = SkipStep ( " Deno installed outside of .deno directory " . to_string ( ) ) ;
return Err ( skip_reason . into ( ) ) ;
}
2020-10-01 15:59:06 -04:00
print_separator ( " Deno " ) ;
ctx . run_type ( ) . execute ( & deno ) . arg ( " upgrade " ) . check_run ( )
}