2020-04-03 12:19:55 +03:00
#![ allow(unused_imports) ]
2022-01-15 06:50:42 +02:00
use std ::path ::PathBuf ;
use std ::process ::Command ;
use std ::{ env , path ::Path } ;
use std ::{ fs , io ::Write } ;
2022-11-11 09:39:29 -05:00
use color_eyre ::eyre ::eyre ;
use color_eyre ::eyre ::Context ;
use color_eyre ::eyre ::Result ;
2022-01-15 06:50:42 +02:00
use directories ::BaseDirs ;
use tempfile ::tempfile_in ;
2023-01-29 19:19:27 +00:00
use tracing ::{ debug , error } ;
2022-01-15 06:50:42 +02:00
2022-11-08 05:54:35 -05:00
use crate ::command ::{ CommandExt , Utf8Output } ;
2020-02-08 22:13:56 +02:00
use crate ::execution_context ::ExecutionContext ;
2022-11-08 05:54:35 -05:00
use crate ::executor ::{ ExecutorOutput , RunType } ;
2019-08-22 21:46:06 +03:00
use crate ::terminal ::{ print_separator , shell } ;
2023-01-29 19:19:27 +00:00
use crate ::utils ::{ self , require , require_option , which , PathExt } ;
2021-02-08 06:31:14 +02:00
use crate ::{
2023-01-29 19:19:27 +00:00
error ::{ SkipStep , StepFailed , TopgradeError } ,
2021-02-08 06:31:14 +02:00
terminal ::print_warning ,
} ;
2018-08-19 14:45:23 +03:00
2021-03-22 09:00:56 +02:00
pub fn run_cargo_update ( ctx : & ExecutionContext ) -> Result < ( ) > {
2021-05-05 13:52:12 +03:00
let cargo_dir = env ::var_os ( " CARGO_HOME " )
. map ( PathBuf ::from )
. unwrap_or_else ( | | ctx . base_dirs ( ) . home_dir ( ) . join ( " .cargo " ) )
. require ( ) ? ;
2021-06-04 14:17:40 +03:00
utils ::require ( " cargo " ) . or_else ( | _ | {
require_option (
cargo_dir . join ( " bin/cargo " ) . if_exists ( ) ,
String ::from ( " No cargo detected " ) ,
)
} ) ? ;
2021-05-05 13:52:12 +03:00
let toml_file = cargo_dir . join ( " .crates.toml " ) . require ( ) ? ;
2021-03-22 09:00:56 +02:00
2021-05-05 13:52:12 +03:00
if fs ::metadata ( & toml_file ) ? . len ( ) = = 0 {
return Err ( SkipStep ( format! ( " {} exists but empty " , & toml_file . display ( ) ) ) . into ( ) ) ;
2021-03-22 09:00:56 +02:00
}
2021-02-13 06:39:06 +02:00
2019-01-13 23:20:32 +02:00
print_separator ( " Cargo " ) ;
2021-06-04 14:17:40 +03:00
let cargo_update = utils ::require ( " cargo-install-update " )
. ok ( )
. or_else ( | | cargo_dir . join ( " bin/cargo-install-update " ) . if_exists ( ) ) ;
let cargo_update = match cargo_update {
Some ( e ) = > e ,
None = > {
let message = String ::from ( " cargo-update isn't installed so Topgrade can't upgrade cargo packages. \n Install cargo-update by running `cargo install cargo-update` " ) ;
print_warning ( & message ) ;
return Err ( SkipStep ( message ) . into ( ) ) ;
2021-02-08 06:31:14 +02:00
}
} ;
2021-03-22 09:00:56 +02:00
ctx . run_type ( )
2019-01-13 23:20:32 +02:00
. execute ( cargo_update )
2022-10-23 11:34:30 +00:00
. args ( [ " install-update " , " --git " , " --all " ] )
2023-03-03 19:58:15 +08:00
. status_checked ( ) ? ;
if ctx . config ( ) . cleanup ( ) {
let cargo_cache = utils ::require ( " cargo-cache " )
. ok ( )
. or_else ( | | cargo_dir . join ( " bin/cargo-cache " ) . if_exists ( ) ) ;
match cargo_cache {
Some ( e ) = > {
ctx . run_type ( ) . execute ( e ) . args ( [ " -a " ] ) . status_checked ( ) ? ;
}
None = > {
let message = String ::from ( " cargo-cache isn't installed so Topgrade can't cleanup cargo packages. \n Install cargo-cache by running `cargo install cargo-cache` " ) ;
print_warning ( message ) ;
}
}
}
Ok ( ( ) )
2018-08-19 14:45:23 +03:00
}
2019-12-11 23:05:38 +02:00
pub fn run_flutter_upgrade ( run_type : RunType ) -> Result < ( ) > {
2019-11-20 13:35:41 +02:00
let flutter = utils ::require ( " flutter " ) ? ;
2019-11-20 14:41:05 +02:00
print_separator ( " Flutter " ) ;
2022-11-08 05:54:35 -05:00
run_type . execute ( flutter ) . arg ( " upgrade " ) . status_checked ( )
2022-11-23 15:23:00 +00:00
}
2019-12-11 23:05:38 +02:00
pub fn run_gem ( base_dirs : & BaseDirs , run_type : RunType ) -> Result < ( ) > {
2019-01-13 23:20:32 +02:00
let gem = utils ::require ( " gem " ) ? ;
base_dirs . home_dir ( ) . join ( " .gem " ) . require ( ) ? ;
2018-09-06 16:46:49 +03:00
2022-11-24 20:21:03 +01:00
print_separator ( " Gems " ) ;
2018-09-06 16:46:49 +03:00
2022-11-03 04:26:20 +08:00
let mut command = run_type . execute ( gem ) ;
2020-08-01 15:13:04 +03:00
command . arg ( " update " ) ;
if env ::var_os ( " RBENV_SHELL " ) . is_none ( ) {
debug! ( " Detected rbenv. Avoiding --user-install " ) ;
command . arg ( " --user-install " ) ;
}
2022-11-08 05:54:35 -05:00
command . status_checked ( )
2018-09-06 16:46:49 +03:00
}
2023-01-29 19:19:27 +00:00
pub fn run_rubygems ( ctx : & ExecutionContext ) -> Result < ( ) > {
ctx . base_dirs ( ) . home_dir ( ) . join ( " .gem " ) . require ( ) ? ;
2023-02-02 21:48:48 +00:00
let gem = require ( " gem " ) ? ;
2022-11-24 20:21:03 +01:00
print_separator ( " RubyGems " ) ;
2023-02-02 21:48:48 +00:00
let gem_path_str = gem . as_os_str ( ) ;
if gem_path_str . to_str ( ) . unwrap ( ) . contains ( " asdf " ) {
ctx . run_type ( )
. execute ( gem )
. args ( [ " update " , " --system " ] )
. status_checked ( ) ? ;
} else if let Some ( sudo ) = & ctx . sudo ( ) {
2023-01-29 19:19:27 +00:00
if ! std ::path ::Path ::new ( " /usr/lib/ruby/vendor_ruby/rubygems/defaults/operating_system.rb " ) . exists ( ) {
ctx . run_type ( )
. execute ( sudo )
. arg ( " -EH " )
2023-02-02 21:48:48 +00:00
. arg ( gem )
2023-01-29 19:19:27 +00:00
. args ( [ " update " , " --system " ] )
. status_checked ( ) ? ;
}
2022-12-15 20:27:27 +00:00
} else {
2023-01-29 19:19:27 +00:00
print_warning ( " No sudo detected. Skipping system upgrade " ) ;
2022-12-15 20:27:27 +00:00
}
2023-01-29 19:19:27 +00:00
Ok ( ( ) )
2022-11-24 20:21:03 +01:00
}
2021-10-25 12:54:27 -06:00
pub fn run_haxelib_update ( ctx : & ExecutionContext ) -> Result < ( ) > {
let haxelib = utils ::require ( " haxelib " ) ? ;
let haxelib_dir =
2022-11-08 05:54:35 -05:00
PathBuf ::from ( std ::str ::from_utf8 ( & Command ::new ( & haxelib ) . arg ( " config " ) . output_checked ( ) ? . stdout ) ? . trim ( ) )
. require ( ) ? ;
2021-10-25 12:54:27 -06:00
let directory_writable = tempfile_in ( & haxelib_dir ) . is_ok ( ) ;
debug! ( " {:?} writable: {} " , haxelib_dir , directory_writable ) ;
print_separator ( " haxelib " ) ;
let mut command = if directory_writable {
ctx . run_type ( ) . execute ( & haxelib )
} else {
let mut c = ctx
. run_type ( )
. execute ( ctx . sudo ( ) . as_ref ( ) . ok_or ( TopgradeError ::SudoRequired ) ? ) ;
c . arg ( & haxelib ) ;
c
} ;
2022-11-08 05:54:35 -05:00
command . arg ( " update " ) . status_checked ( )
2021-10-25 12:54:27 -06:00
}
2020-07-30 06:27:29 +03:00
pub fn run_sheldon ( ctx : & ExecutionContext ) -> Result < ( ) > {
let sheldon = utils ::require ( " sheldon " ) ? ;
print_separator ( " Sheldon " ) ;
2022-11-08 05:54:35 -05:00
ctx . run_type ( )
. execute ( sheldon )
. args ( [ " lock " , " --update " ] )
. status_checked ( )
2020-07-30 06:27:29 +03:00
}
2021-02-17 16:46:29 +02:00
pub fn run_fossil ( run_type : RunType ) -> Result < ( ) > {
let fossil = utils ::require ( " fossil " ) ? ;
print_separator ( " Fossil " ) ;
2022-11-08 05:54:35 -05:00
run_type . execute ( fossil ) . args ( [ " all " , " sync " ] ) . status_checked ( )
2021-02-17 16:46:29 +02:00
}
2021-02-15 20:43:36 +01:00
pub fn run_micro ( run_type : RunType ) -> Result < ( ) > {
let micro = utils ::require ( " micro " ) ? ;
print_separator ( " micro " ) ;
2022-11-08 05:54:35 -05:00
let stdout = run_type
. execute ( micro )
. args ( [ " -plugin " , " update " ] )
. output_checked_utf8 ( ) ?
. stdout ;
2021-09-02 07:27:09 +03:00
std ::io ::stdout ( ) . write_all ( stdout . as_bytes ( ) ) ? ;
2021-02-15 20:43:36 +01:00
if stdout . contains ( " Nothing to install / update " ) | | stdout . contains ( " One or more plugins installed " ) {
Ok ( ( ) )
} else {
2022-11-11 09:39:29 -05:00
Err ( eyre! ( " micro output does not indicate success: {} " , stdout ) )
2021-02-15 20:43:36 +01:00
}
}
2018-10-29 14:32:33 +02:00
#[ cfg(not(any(
target_os = " freebsd " ,
target_os = " openbsd " ,
target_os = " netbsd " ,
target_os = " dragonfly "
) ) ) ]
2019-12-11 23:05:38 +02:00
pub fn run_apm ( run_type : RunType ) -> Result < ( ) > {
2019-01-13 23:20:32 +02:00
let apm = utils ::require ( " apm " ) ? ;
2018-08-19 14:45:23 +03:00
2019-01-13 23:20:32 +02:00
print_separator ( " Atom Package Manager " ) ;
2018-08-19 14:45:23 +03:00
2022-11-08 05:54:35 -05:00
run_type
. execute ( apm )
. args ( [ " upgrade " , " --confirm=false " ] )
. status_checked ( )
2018-08-19 14:45:23 +03:00
}
2023-04-05 15:42:47 +03:00
pub fn run_rustup ( ctx : & ExecutionContext ) -> Result < ( ) > {
2019-01-13 23:20:32 +02:00
let rustup = utils ::require ( " rustup " ) ? ;
2018-08-19 14:45:23 +03:00
2019-01-13 23:20:32 +02:00
print_separator ( " rustup " ) ;
2023-04-05 15:42:47 +03:00
ctx . run_type ( ) . execute ( rustup ) . arg ( " update " ) . status_checked ( )
2018-08-19 14:45:23 +03:00
}
2022-11-24 14:17:58 -05:00
pub fn run_juliaup ( base_dirs : & BaseDirs , run_type : RunType ) -> Result < ( ) > {
let juliaup = utils ::require ( " juliaup " ) ? ;
print_separator ( " juliaup " ) ;
if juliaup . canonicalize ( ) ? . is_descendant_of ( base_dirs . home_dir ( ) ) {
run_type . execute ( & juliaup ) . args ( [ " self " , " update " ] ) . status_checked ( ) ? ;
}
run_type . execute ( & juliaup ) . arg ( " update " ) . status_checked ( )
}
2020-08-28 16:16:23 +03:00
pub fn run_choosenim ( ctx : & ExecutionContext ) -> Result < ( ) > {
let choosenim = utils ::require ( " choosenim " ) ? ;
print_separator ( " choosenim " ) ;
let run_type = ctx . run_type ( ) ;
2022-11-08 05:54:35 -05:00
run_type . execute ( & choosenim ) . args ( [ " update " , " self " ] ) . status_checked ( ) ? ;
run_type . execute ( & choosenim ) . args ( [ " update " , " stable " ] ) . status_checked ( )
2020-08-28 16:16:23 +03:00
}
2020-06-29 05:13:31 +02:00
pub fn run_krew_upgrade ( run_type : RunType ) -> Result < ( ) > {
let krew = utils ::require ( " kubectl-krew " ) ? ;
print_separator ( " Krew " ) ;
2022-11-08 05:54:35 -05:00
run_type . execute ( krew ) . args ( [ " upgrade " ] ) . status_checked ( )
2020-06-29 05:13:31 +02:00
}
2020-11-15 20:07:42 -08:00
pub fn run_gcloud_components_update ( run_type : RunType ) -> Result < ( ) > {
let gcloud = utils ::require ( " gcloud " ) ? ;
2022-11-04 09:48:05 -04:00
if gcloud . starts_with ( " /snap " ) {
Ok ( ( ) )
} else {
print_separator ( " gcloud " ) ;
2020-11-15 20:07:42 -08:00
2022-11-04 09:48:05 -04:00
run_type
. execute ( gcloud )
. args ( [ " components " , " update " , " --quiet " ] )
2022-11-08 05:54:35 -05:00
. status_checked ( )
2022-11-04 09:48:05 -04:00
}
2020-11-15 20:07:42 -08:00
}
2019-12-11 23:05:38 +02:00
pub fn run_jetpack ( run_type : RunType ) -> Result < ( ) > {
2019-01-13 23:20:32 +02:00
let jetpack = utils ::require ( " jetpack " ) ? ;
2018-10-18 16:05:27 +03:00
2019-01-13 23:20:32 +02:00
print_separator ( " Jetpack " ) ;
2018-10-18 16:05:27 +03:00
2022-11-08 05:54:35 -05:00
run_type . execute ( jetpack ) . args ( [ " global " , " update " ] ) . status_checked ( )
2018-10-18 16:05:27 +03:00
}
2020-09-25 01:00:06 +08:00
pub fn run_rtcl ( ctx : & ExecutionContext ) -> Result < ( ) > {
let rupdate = utils ::require ( " rupdate " ) ? ;
print_separator ( " rtcl " ) ;
2022-11-08 05:54:35 -05:00
ctx . run_type ( ) . execute ( rupdate ) . status_checked ( )
2020-09-25 01:00:06 +08:00
}
2022-10-10 20:24:41 +00:00
pub fn run_opam_update ( ctx : & ExecutionContext ) -> Result < ( ) > {
2019-01-13 23:20:32 +02:00
let opam = utils ::require ( " opam " ) ? ;
2018-09-03 13:45:01 +02:00
2019-01-13 23:20:32 +02:00
print_separator ( " OCaml Package Manager " ) ;
2018-09-03 13:45:01 +02:00
2022-11-08 05:54:35 -05:00
ctx . run_type ( ) . execute ( & opam ) . arg ( " update " ) . status_checked ( ) ? ;
ctx . run_type ( ) . execute ( & opam ) . arg ( " upgrade " ) . status_checked ( ) ? ;
2022-10-10 20:24:41 +00:00
if ctx . config ( ) . cleanup ( ) {
2022-11-08 05:54:35 -05:00
ctx . run_type ( ) . execute ( & opam ) . arg ( " clean " ) . status_checked ( ) ? ;
2022-10-10 20:24:41 +00:00
}
Ok ( ( ) )
2018-09-03 13:45:01 +02:00
}
2022-12-15 11:39:25 +00:00
pub fn run_vcpkg_update ( ctx : & ExecutionContext ) -> Result < ( ) > {
2019-01-13 23:20:32 +02:00
let vcpkg = utils ::require ( " vcpkg " ) ? ;
print_separator ( " vcpkg " ) ;
2018-11-10 20:22:26 +02:00
2022-12-15 11:39:25 +00:00
#[ cfg(unix) ]
let is_root_install = ! & vcpkg . starts_with ( " /home " ) ;
#[ cfg(not(unix)) ]
let is_root_install = false ;
let mut command = if is_root_install {
ctx . run_type ( ) . execute ( & vcpkg )
} else {
let mut c = ctx
. run_type ( )
. execute ( ctx . sudo ( ) . as_ref ( ) . ok_or ( TopgradeError ::SudoRequired ) ? ) ;
c . arg ( & vcpkg ) ;
c
} ;
command . args ( [ " upgrade " , " --no-dry-run " ] ) . status_checked ( )
2018-11-10 20:22:26 +02:00
}
2019-12-11 23:05:38 +02:00
pub fn run_pipx_update ( run_type : RunType ) -> Result < ( ) > {
2019-01-13 23:20:32 +02:00
let pipx = utils ::require ( " pipx " ) ? ;
print_separator ( " pipx " ) ;
2018-10-31 13:01:57 +02:00
2022-11-08 05:54:35 -05:00
run_type . execute ( pipx ) . arg ( " upgrade-all " ) . status_checked ( )
2018-10-31 13:01:57 +02:00
}
2022-01-15 06:50:42 +02:00
pub fn run_conda_update ( ctx : & ExecutionContext ) -> Result < ( ) > {
let conda = utils ::require ( " conda " ) ? ;
2022-01-24 22:05:52 +02:00
let output = Command ::new ( " conda " )
2022-10-23 11:34:30 +00:00
. args ( [ " config " , " --show " , " auto_activate_base " ] )
2022-11-08 05:54:35 -05:00
. output_checked_utf8 ( ) ? ;
debug! ( " Conda output: {} " , output . stdout ) ;
if output . stdout . contains ( " False " ) {
2022-01-24 22:05:52 +02:00
return Err ( SkipStep ( " auto_activate_base is set to False " . to_string ( ) ) . into ( ) ) ;
}
2022-01-15 06:50:42 +02:00
print_separator ( " Conda " ) ;
ctx . run_type ( )
2022-11-03 04:26:20 +08:00
. execute ( conda )
2022-10-23 11:34:30 +00:00
. args ( [ " update " , " --all " , " -y " ] )
2022-11-08 05:54:35 -05:00
. status_checked ( )
2022-01-15 06:50:42 +02:00
}
2021-03-02 10:39:49 +01:00
pub fn run_pip3_update ( run_type : RunType ) -> Result < ( ) > {
2022-05-01 20:47:14 +03:00
let python3 = utils ::require ( " python3 " ) ? ;
Command ::new ( & python3 )
2022-10-23 11:34:30 +00:00
. args ( [ " -m " , " pip " ] )
2022-11-08 05:54:35 -05:00
. output_checked_utf8 ( )
2022-05-01 20:47:14 +03:00
. map_err ( | _ | SkipStep ( " pip does not exists " . to_string ( ) ) ) ? ;
2023-02-23 14:01:26 -08:00
let check_externally_managed = " import sysconfig; from os import path; print('Y') if path.isfile(path.join(sysconfig.get_path('stdlib'), 'EXTERNALLY-MANAGED')) else print('N') " ;
Command ::new ( & python3 )
. args ( [ " -c " , check_externally_managed ] )
. output_checked_utf8 ( )
. map_err ( | _ | SkipStep ( " pip may be externally managed " . to_string ( ) ) )
. and_then ( | output | match output . stdout . trim ( ) {
" N " = > Ok ( ( ) ) ,
" Y " = > Err ( SkipStep ( " pip is externally managed " . to_string ( ) ) ) ,
_ = > {
print_warning ( " Unexpected output when checking EXTERNALLY-MANAGED " ) ;
print_warning ( output . stdout . trim ( ) ) ;
Err ( SkipStep ( " pip may be externally managed " . to_string ( ) ) )
}
} ) ? ;
2021-03-02 10:39:49 +01:00
print_separator ( " pip3 " ) ;
2021-06-26 15:04:49 +03:00
if std ::env ::var ( " VIRTUAL_ENV " ) . is_ok ( ) {
print_warning ( " This step is will be skipped when running inside a virtual environment " ) ;
return Err ( SkipStep ( " Does not run inside a virtual environment " . to_string ( ) ) . into ( ) ) ;
}
2021-03-02 10:39:49 +01:00
run_type
2022-05-01 20:47:14 +03:00
. execute ( & python3 )
2022-10-23 11:34:30 +00:00
. args ( [ " -m " , " pip " , " install " , " --upgrade " , " --user " , " pip " ] )
2022-11-08 05:54:35 -05:00
. status_checked ( )
2021-03-02 10:39:49 +01:00
}
2023-01-29 19:19:27 +00:00
pub fn run_pip_review_update ( ctx : & ExecutionContext ) -> Result < ( ) > {
let pip_review = require ( " pip-review " ) ? ;
print_separator ( " pip-review " ) ;
if ! ctx . config ( ) . enable_pip_review ( ) {
print_warning (
" Pip-review is disabled by default. Enable it by setting enable_pip_review=true in the configuration. " ,
) ;
return Err ( SkipStep ( String ::from ( " Pip-review is disabled by default " ) ) . into ( ) ) ;
}
ctx . run_type ( )
. execute ( pip_review )
. arg ( " --auto " )
. status_checked_with_codes ( & [ 1 ] ) ? ;
Ok ( ( ) )
}
pub fn run_pipupgrade_update ( ctx : & ExecutionContext ) -> Result < ( ) > {
let pipupgrade = require ( " pipupgrade " ) ? ;
print_separator ( " Pipupgrade " ) ;
if ! ctx . config ( ) . enable_pip_review ( ) {
print_warning (
" Pipupgrade is disabled by default. Enable it by setting enable_pipupgrade=true in the configuration. " ,
) ;
return Err ( SkipStep ( String ::from ( " Pipupgrade is disabled by default " ) ) . into ( ) ) ;
}
ctx . run_type ( ) . execute ( pipupgrade ) . status_checked ( ) ? ;
Ok ( ( ) )
}
2019-12-11 23:05:38 +02:00
pub fn run_stack_update ( run_type : RunType ) -> Result < ( ) > {
2022-11-03 04:26:20 +08:00
if utils ::require ( " ghcup " ) . is_ok ( ) {
2022-10-30 12:34:14 -04:00
// `ghcup` is present and probably(?) being used to install `stack`.
// Don't upgrade `stack`, let `ghcup` handle it. Per `ghcup install stack`:
// !!! Additionally, you should upgrade stack only through ghcup and not use 'stack upgrade' !!!
return Ok ( ( ) ) ;
}
2019-10-07 19:13:29 +02:00
let stack = utils ::require ( " stack " ) ? ;
print_separator ( " stack " ) ;
2022-11-08 05:54:35 -05:00
run_type . execute ( stack ) . arg ( " upgrade " ) . status_checked ( )
2019-10-07 19:13:29 +02:00
}
2022-10-30 12:34:14 -04:00
pub fn run_ghcup_update ( run_type : RunType ) -> Result < ( ) > {
let ghcup = utils ::require ( " ghcup " ) ? ;
print_separator ( " ghcup " ) ;
2022-11-08 05:54:35 -05:00
run_type . execute ( ghcup ) . arg ( " upgrade " ) . status_checked ( )
2022-10-30 12:34:14 -04:00
}
2020-06-03 22:12:27 +03:00
pub fn run_tlmgr_update ( ctx : & ExecutionContext ) -> Result < ( ) > {
cfg_if ::cfg_if! {
2022-04-23 01:50:17 +05:30
if #[ cfg(any(target_os = " linux " , target_os = " android " )) ] {
2020-06-03 22:12:27 +03:00
if ! ctx . config ( ) . enable_tlmgr_linux ( ) {
2022-04-23 01:50:17 +05:30
return Err ( SkipStep ( String ::from ( " tlmgr must be explicity enabled in the configuration to run in Android/Linux " ) ) . into ( ) ) ;
2020-06-03 22:12:27 +03:00
}
}
}
2019-12-12 20:24:22 +02:00
let tlmgr = utils ::require ( " tlmgr " ) ? ;
let kpsewhich = utils ::require ( " kpsewhich " ) ? ;
let tlmgr_directory = {
let mut d = PathBuf ::from (
2022-11-08 05:54:35 -05:00
& Command ::new ( kpsewhich )
. arg ( " -var-value=SELFAUTOPARENT " )
. output_checked_utf8 ( ) ?
. stdout
. trim ( ) ,
2019-12-12 20:24:22 +02:00
) ;
d . push ( " tlpkg " ) ;
d
}
. require ( ) ? ;
let directory_writable = tempfile_in ( & tlmgr_directory ) . is_ok ( ) ;
debug! ( " {:?} writable: {} " , tlmgr_directory , directory_writable ) ;
print_separator ( " TeX Live package manager " ) ;
let mut command = if directory_writable {
2020-06-03 22:12:27 +03:00
ctx . run_type ( ) . execute ( & tlmgr )
2019-12-12 20:24:22 +02:00
} else {
2020-06-03 22:12:27 +03:00
let mut c = ctx
. run_type ( )
. execute ( ctx . sudo ( ) . as_ref ( ) . ok_or ( TopgradeError ::SudoRequired ) ? ) ;
2019-12-12 20:24:22 +02:00
c . arg ( & tlmgr ) ;
c
} ;
2022-10-23 11:34:30 +00:00
command . args ( [ " update " , " --self " , " --all " ] ) ;
2019-12-12 20:24:22 +02:00
2022-11-08 05:54:35 -05:00
command . status_checked ( )
2019-12-12 20:24:22 +02:00
}
2021-07-19 07:29:34 +02:00
pub fn run_chezmoi_update ( base_dirs : & BaseDirs , run_type : RunType ) -> Result < ( ) > {
let chezmoi = utils ::require ( " chezmoi " ) ? ;
base_dirs . home_dir ( ) . join ( " .local/share/chezmoi " ) . require ( ) ? ;
print_separator ( " chezmoi " ) ;
2022-11-08 05:54:35 -05:00
run_type . execute ( chezmoi ) . arg ( " update " ) . status_checked ( )
2021-07-19 07:29:34 +02:00
}
2019-12-11 23:05:38 +02:00
pub fn run_myrepos_update ( base_dirs : & BaseDirs , run_type : RunType ) -> Result < ( ) > {
2019-05-15 11:33:22 +02:00
let myrepos = utils ::require ( " mr " ) ? ;
base_dirs . home_dir ( ) . join ( " .mrconfig " ) . require ( ) ? ;
print_separator ( " myrepos " ) ;
run_type
. execute ( & myrepos )
. arg ( " --directory " )
. arg ( base_dirs . home_dir ( ) )
. arg ( " checkout " )
2022-11-08 05:54:35 -05:00
. status_checked ( ) ? ;
2019-05-15 11:33:22 +02:00
run_type
. execute ( & myrepos )
. arg ( " --directory " )
. arg ( base_dirs . home_dir ( ) )
. arg ( " update " )
2022-11-08 05:54:35 -05:00
. status_checked ( )
2019-05-15 11:33:22 +02:00
}
2020-02-08 22:13:56 +02:00
pub fn run_custom_command ( name : & str , command : & str , ctx : & ExecutionContext ) -> Result < ( ) > {
2018-12-05 11:34:08 +02:00
print_separator ( name ) ;
2023-03-17 21:58:58 +05:30
let mut exec = ctx . run_type ( ) . execute ( shell ( ) ) ;
#[ cfg(unix) ]
let command = if let Some ( command ) = command . strip_prefix ( " -i " ) {
exec . arg ( " -i " ) ;
command
} else {
command
} ;
exec . arg ( " -c " ) . arg ( command ) . status_checked ( )
2018-08-19 14:45:23 +03:00
}
2018-10-02 13:45:29 +03:00
2020-03-08 21:38:25 +02:00
pub fn run_composer_update ( ctx : & ExecutionContext ) -> Result < ( ) > {
2019-01-13 23:20:32 +02:00
let composer = utils ::require ( " composer " ) ? ;
let composer_home = Command ::new ( & composer )
2022-10-23 11:34:30 +00:00
. args ( [ " global " , " config " , " --absolute " , " --quiet " , " home " ] )
2022-11-08 05:54:35 -05:00
. output_checked_utf8 ( )
2023-01-29 19:19:27 +00:00
. map_err ( | e | ( SkipStep ( format! ( " Error getting the composer directory: {e} " ) ) ) )
2022-11-08 05:54:35 -05:00
. map ( | s | PathBuf ::from ( s . stdout . trim ( ) ) ) ?
2019-12-11 23:05:38 +02:00
. require ( ) ? ;
2019-01-13 23:20:32 +02:00
2020-03-08 21:38:25 +02:00
if ! composer_home . is_descendant_of ( ctx . base_dirs ( ) . home_dir ( ) ) {
2020-08-21 23:04:36 +03:00
return Err ( SkipStep ( format! (
" Composer directory {} isn't a decandent of the user's home directory " ,
composer_home . display ( )
) )
. into ( ) ) ;
2019-01-13 23:20:32 +02:00
}
2018-12-17 10:53:05 +02:00
2019-01-13 23:20:32 +02:00
print_separator ( " Composer " ) ;
2018-12-17 10:53:05 +02:00
2020-03-08 21:38:25 +02:00
if ctx . config ( ) . composer_self_update ( ) {
cfg_if ::cfg_if! {
if #[ cfg(unix) ] {
// If self-update fails without sudo then there's probably an update
let has_update = match ctx . run_type ( ) . execute ( & composer ) . arg ( " self-update " ) . output ( ) ? {
ExecutorOutput ::Wet ( output ) = > ! output . status . success ( ) ,
_ = > false
} ;
if has_update {
ctx . run_type ( )
. execute ( ctx . sudo ( ) . as_ref ( ) . unwrap ( ) )
. arg ( & composer )
. arg ( " self-update " )
2022-11-08 05:54:35 -05:00
. status_checked ( ) ? ;
2020-03-08 21:38:25 +02:00
}
} else {
2022-11-08 05:54:35 -05:00
ctx . run_type ( ) . execute ( & composer ) . arg ( " self-update " ) . status_checked ( ) ? ;
2020-03-08 21:38:25 +02:00
}
}
}
2022-11-08 05:54:35 -05:00
let output = ctx . run_type ( ) . execute ( & composer ) . args ( [ " global " , " update " ] ) . output ( ) ? ;
if let ExecutorOutput ::Wet ( output ) = output {
let output : Utf8Output = output . try_into ( ) ? ;
print! ( " {} \n {} " , output . stdout , output . stderr ) ;
if output . stdout . contains ( " valet " ) | | output . stderr . contains ( " valet " ) {
if let Some ( valet ) = utils ::which ( " valet " ) {
ctx . run_type ( ) . execute ( valet ) . arg ( " install " ) . status_checked ( ) ? ;
}
2020-02-10 21:10:06 +01:00
}
2018-10-02 13:45:29 +03:00
}
2019-01-13 23:20:32 +02:00
Ok ( ( ) )
2018-10-02 13:45:29 +03:00
}
2020-12-26 06:43:45 +02:00
pub fn run_dotnet_upgrade ( ctx : & ExecutionContext ) -> Result < ( ) > {
let dotnet = utils ::require ( " dotnet " ) ? ;
2023-01-29 19:19:27 +00:00
//Skip when the `dotnet tool list` subcommand fails. (This is expected when a dotnet runtime is installed but no SDK.)
let output = match ctx
. run_type ( )
. execute ( & dotnet )
. args ( [ " tool " , " list " , " --global " ] )
. output_checked_utf8 ( )
{
Ok ( output ) = > output ,
Err ( _ ) = > {
return Err ( SkipStep ( String ::from (
" Error running `dotnet tool list`. This is expected when a dotnet runtime is installed but no SDK. " ,
) )
. into ( ) )
2022-12-18 14:12:36 +00:00
}
2023-01-29 19:19:27 +00:00
} ;
2020-12-26 06:43:45 +02:00
2023-01-29 19:19:27 +00:00
if ! output . stdout . starts_with ( " Package Id " ) {
return Err ( SkipStep ( String ::from ( " dotnet did not output packages " ) ) . into ( ) ) ;
}
2020-12-26 06:43:45 +02:00
2023-01-29 19:19:27 +00:00
let mut packages = output . stdout . lines ( ) . skip ( 2 ) . filter ( | line | ! line . is_empty ( ) ) . peekable ( ) ;
2020-12-26 06:43:45 +02:00
2023-01-29 19:19:27 +00:00
if packages . peek ( ) . is_none ( ) {
return Err ( SkipStep ( String ::from ( " No dotnet global tools installed " ) ) . into ( ) ) ;
}
2020-12-26 06:43:45 +02:00
2023-01-29 19:19:27 +00:00
print_separator ( " .NET " ) ;
for package in packages {
let package_name = package . split_whitespace ( ) . next ( ) . unwrap ( ) ;
ctx . run_type ( )
. execute ( & dotnet )
. args ( [ " tool " , " update " , package_name , " --global " ] )
. status_checked ( )
. with_context ( | | format! ( " Failed to update .NET package {package_name} " ) ) ? ;
2022-12-18 14:12:36 +00:00
}
2023-01-29 19:19:27 +00:00
2020-12-26 06:43:45 +02:00
Ok ( ( ) )
}
2021-03-14 13:12:38 +03:00
2022-12-14 09:12:39 +01:00
pub fn run_helix_grammars ( ctx : & ExecutionContext ) -> Result < ( ) > {
utils ::require ( " helix " ) ? ;
print_separator ( " Helix " ) ;
ctx . run_type ( )
. execute ( ctx . sudo ( ) . as_ref ( ) . ok_or ( TopgradeError ::SudoRequired ) ? )
. args ( [ " helix " , " --grammar " , " fetch " ] )
. status_checked ( )
. with_context ( | | " Failed to download helix grammars! " ) ? ;
ctx . run_type ( )
. execute ( ctx . sudo ( ) . as_ref ( ) . ok_or ( TopgradeError ::SudoRequired ) ? )
. args ( [ " helix " , " --grammar " , " build " ] )
. status_checked ( )
. with_context ( | | " Failed to build helix grammars! " ) ? ;
Ok ( ( ) )
}
2021-03-14 13:12:38 +03:00
pub fn run_raco_update ( run_type : RunType ) -> Result < ( ) > {
let raco = utils ::require ( " raco " ) ? ;
print_separator ( " Racket Package Manager " ) ;
2022-11-08 05:54:35 -05:00
run_type . execute ( raco ) . args ( [ " pkg " , " update " , " --all " ] ) . status_checked ( )
2021-03-14 13:12:38 +03:00
}
2021-05-29 01:59:27 -03:00
pub fn bin_update ( ctx : & ExecutionContext ) -> Result < ( ) > {
let bin = utils ::require ( " bin " ) ? ;
print_separator ( " Bin " ) ;
2022-11-08 05:54:35 -05:00
ctx . run_type ( ) . execute ( bin ) . arg ( " update " ) . status_checked ( )
2021-05-29 01:59:27 -03:00
}
2021-11-15 07:09:02 +01:00
pub fn spicetify_upgrade ( ctx : & ExecutionContext ) -> Result < ( ) > {
let spicetify = utils ::require ( " spicetify " ) ? ;
print_separator ( " Spicetify " ) ;
2022-11-08 05:54:35 -05:00
ctx . run_type ( ) . execute ( spicetify ) . arg ( " upgrade " ) . status_checked ( )
2021-11-15 07:09:02 +01:00
}
2022-03-08 00:16:52 +01:00
pub fn run_ghcli_extensions_upgrade ( ctx : & ExecutionContext ) -> Result < ( ) > {
let gh = utils ::require ( " gh " ) ? ;
2022-11-08 05:54:35 -05:00
let result = Command ::new ( & gh ) . args ( [ " extensions " , " list " ] ) . output_checked_utf8 ( ) ;
2022-03-29 03:17:15 +03:00
if result . is_err ( ) {
debug! ( " GH result {:?} " , result ) ;
return Err ( SkipStep ( String ::from ( " GH failed " ) ) . into ( ) ) ;
}
2022-03-08 00:16:52 +01:00
print_separator ( " GitHub CLI Extensions " ) ;
ctx . run_type ( )
. execute ( & gh )
2022-10-23 11:34:30 +00:00
. args ( [ " extension " , " upgrade " , " --all " ] )
2022-11-08 05:54:35 -05:00
. status_checked ( )
2022-03-08 00:16:52 +01:00
}
2022-10-10 18:29:56 +00:00
pub fn update_julia_packages ( ctx : & ExecutionContext ) -> Result < ( ) > {
let julia = utils ::require ( " julia " ) ? ;
print_separator ( " Julia Packages " ) ;
ctx . run_type ( )
2022-11-03 04:26:20 +08:00
. execute ( julia )
2022-10-23 11:34:30 +00:00
. args ( [ " -e " , " using Pkg; Pkg.update() " ] )
2022-11-08 05:54:35 -05:00
. status_checked ( )
2022-10-10 18:29:56 +00:00
}
2022-12-08 22:47:57 +01:00
pub fn run_helm_repo_update ( run_type : RunType ) -> Result < ( ) > {
let helm = utils ::require ( " helm " ) ? ;
print_separator ( " Helm " ) ;
2023-01-29 19:19:27 +00:00
let no_repo = " no repositories found " ;
let mut success = true ;
let mut exec = run_type . execute ( helm ) ;
if let Err ( e ) = exec . arg ( " repo " ) . arg ( " update " ) . status_checked ( ) {
error! ( " Updating repositories failed: {} " , e ) ;
success = match exec . output_checked_utf8 ( ) {
Ok ( s ) = > s . stdout . contains ( no_repo ) | | s . stderr . contains ( no_repo ) ,
Err ( e ) = > match e . downcast_ref ::< TopgradeError > ( ) {
Some ( TopgradeError ::ProcessFailedWithOutput ( _ , _ , stderr ) ) = > stderr . contains ( no_repo ) ,
_ = > false ,
} ,
} ;
}
if success {
Ok ( ( ) )
} else {
Err ( eyre! ( StepFailed ) )
}
2022-12-08 22:47:57 +01:00
}