9.1.0 Release (#27)
This commit is contained in:
24
.github/workflows/build-and-test.yml
vendored
Normal file
24
.github/workflows/build-and-test.yml
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
name: Cargo Build & Test
|
||||
|
||||
on:
|
||||
push:
|
||||
pull_request:
|
||||
|
||||
env:
|
||||
CARGO_TERM_COLOR: always
|
||||
|
||||
jobs:
|
||||
build_and_test:
|
||||
name: Rust project - latest
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
toolchain:
|
||||
- stable
|
||||
- beta
|
||||
- nightly
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- run: rustup update ${{ matrix.toolchain }} && rustup default ${{ matrix.toolchain }}
|
||||
- run: cargo build --verbose
|
||||
- run: cargo test --verbose
|
||||
24
.github/workflows/rust-ubuntu.yml
vendored
Normal file
24
.github/workflows/rust-ubuntu.yml
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
name: Rust
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ "master", "dev" ]
|
||||
pull_request:
|
||||
branches: [ "master", "dev" ]
|
||||
|
||||
env:
|
||||
CARGO_TERM_COLOR: always
|
||||
|
||||
jobs:
|
||||
build:
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: Build
|
||||
run: cargo build --verbose
|
||||
- name: Fmt
|
||||
run: cargo fmt --check --all
|
||||
- name: Run tests
|
||||
run: cargo test --verbose
|
||||
60
Cargo.toml
60
Cargo.toml
@@ -1,54 +1,54 @@
|
||||
[package]
|
||||
name = "topgrade-rs"
|
||||
description = "Upgrade all the things"
|
||||
description = "Upgrade all the things, successor of topgrade"
|
||||
categories = ["os"]
|
||||
keywords = ["upgrade", "update"]
|
||||
license-file = "LICENSE"
|
||||
repository = "https://github.com/topgrade-rs/topgrade"
|
||||
version = "9.0.1"
|
||||
authors = ["Thomas Schönauer<t.schoenauer@hgs-wt.at>"]
|
||||
version = "9.1.0"
|
||||
authors = ["Roey Darwish Dror <roey.ghost@gmail.com>", "Thomas Schönauer <t.schoenauer@hgs-wt.at>"]
|
||||
exclude = ["doc/screenshot.gif"]
|
||||
edition = "2018"
|
||||
|
||||
readme = "README.md"
|
||||
|
||||
[dependencies]
|
||||
directories = "4.0.1"
|
||||
serde = { version = "1.0.125", features = ["derive"] }
|
||||
toml = "0.5.8"
|
||||
which_crate = { version = "4.1.0", package = "which" }
|
||||
shellexpand = "2.1.0"
|
||||
directories = "4.0"
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
toml = "0.5"
|
||||
which_crate = { version = "4.1", package = "which" }
|
||||
shellexpand = "2.1"
|
||||
clap = { version = "3.1", features = ["cargo", "derive"] }
|
||||
log = "0.4.14"
|
||||
walkdir = "2.3.2"
|
||||
console = "0.15.0"
|
||||
lazy_static = "1.4.0"
|
||||
chrono = "0.4.19"
|
||||
pretty_env_logger = "0.4.0"
|
||||
glob = "0.3.0"
|
||||
strum = { version = "0.24.0", features = ["derive"] }
|
||||
thiserror = "1.0.24"
|
||||
anyhow = "1.0.40"
|
||||
tempfile = "3.2.0"
|
||||
cfg-if = "1.0.0"
|
||||
tokio = { version = "1.5.0", features = ["process", "rt-multi-thread"] }
|
||||
futures = "0.3.14"
|
||||
regex = "1.5.3"
|
||||
log = "0.4"
|
||||
walkdir = "2.3"
|
||||
console = "0.15"
|
||||
lazy_static = "1.4"
|
||||
chrono = "0.4"
|
||||
pretty_env_logger = "0.4"
|
||||
glob = "0.3"
|
||||
strum = { version = "0.24", features = ["derive"] }
|
||||
thiserror = "1.0"
|
||||
anyhow = "1.0"
|
||||
tempfile = "3.2"
|
||||
cfg-if = "1.0"
|
||||
tokio = { version = "1.5", features = ["process", "rt-multi-thread"] }
|
||||
futures = "0.3"
|
||||
regex = "1.5"
|
||||
sys-info = "0.9"
|
||||
semver = "1.0"
|
||||
|
||||
[target.'cfg(target_os = "macos")'.dependencies]
|
||||
notify-rust = "4.5.0"
|
||||
notify-rust = "4.5"
|
||||
|
||||
[target.'cfg(unix)'.dependencies]
|
||||
nix = "0.24.1"
|
||||
rust-ini = "0.18.0"
|
||||
self_update_crate = { version = "0.30.0", default-features = false, optional = true, package = "self_update", features = ["archive-tar", "compression-flate2", "rustls"] }
|
||||
nix = "0.24"
|
||||
rust-ini = "0.18"
|
||||
self_update_crate = { version = "0.30", default-features = false, optional = true, package = "self_update", features = ["archive-tar", "compression-flate2", "rustls"] }
|
||||
|
||||
[target.'cfg(windows)'.dependencies]
|
||||
self_update_crate = { version = "0.30.0", default-features = false, optional = true, package = "self_update", features = ["archive-zip", "compression-zip-deflate", "rustls"] }
|
||||
winapi = "0.3.9"
|
||||
parselnk = "0.1.0"
|
||||
self_update_crate = { version = "0.30", default-features = false, optional = true, package = "self_update", features = ["archive-zip", "compression-zip-deflate", "rustls"] }
|
||||
winapi = "0.3"
|
||||
parselnk = "0.1"
|
||||
|
||||
[profile.release]
|
||||
lto = true
|
||||
|
||||
14
README.md
14
README.md
@@ -1,14 +1,17 @@
|
||||

|
||||
|
||||
[](https://travis-ci.org/r-darwish/topgrade)
|
||||
[](https://ci.appveyor.com/project/r-darwish/topgrade)
|
||||
<!---
|
||||

|
||||
[](https://crates.io/crates/topgrade)
|
||||
[](https://aur.archlinux.org/packages/topgrade/)
|
||||

|
||||
 -->
|
||||
--->
|
||||
|
||||

|
||||
|
||||
## Fork
|
||||
This is a fork of [topgrade by r-darwish](https://github.com/r-darwish/topgrade) to keep it maintained.
|
||||
|
||||
|
||||
Keeping your system up to date usually involves invoking multiple package managers.
|
||||
This results in big, non-portable shell one-liners saved in your shell.
|
||||
To remedy this, _topgrade_ detects which tools you use and runs the appropriate commands to update them.
|
||||
@@ -23,6 +26,9 @@ The compiled binaries contain a self-upgrading feature.
|
||||
|
||||
Topgrade requires Rust 1.51 or above.
|
||||
|
||||
## Documentation[WIP]
|
||||
You can visit the documentation at [topgrade-rs.github.io](https://topgrade-rs.github.io/) .
|
||||
|
||||
## Usage
|
||||
Just run `topgrade`.
|
||||
See [the wiki](https://github.com/r-darwish/topgrade/wiki/Step-list) for the list of things Topgrade supports.
|
||||
|
||||
@@ -37,6 +37,9 @@
|
||||
# Cleanup temporary or old files
|
||||
#cleanup = true
|
||||
|
||||
# Skip sending a notification at the end of a run
|
||||
#skip_notify = true
|
||||
|
||||
[git]
|
||||
#max_concurrency = 5
|
||||
# Additional git repositories to pull
|
||||
@@ -64,6 +67,7 @@
|
||||
|
||||
[brew]
|
||||
#greedy_cask = true
|
||||
#autoremove = true
|
||||
|
||||
[linux]
|
||||
# Arch Package Manager to use. Allowed values: autodetect, trizen, paru, yay, pikaur, pacman, pamac.
|
||||
@@ -87,7 +91,7 @@
|
||||
|
||||
# Causes Topgrade to rename itself during the run to allow package managers
|
||||
# to upgrade it. Use this only if you installed Topgrade by using a package
|
||||
# manager such as Scoop to Cargo
|
||||
# manager such as Scoop or Cargo
|
||||
#self_rename = true
|
||||
|
||||
[npm]
|
||||
|
||||
@@ -62,7 +62,7 @@ macro_rules! get_deprecated {
|
||||
|
||||
type Commands = BTreeMap<String, String>;
|
||||
|
||||
#[derive(ArgEnum, EnumString, EnumVariantNames, Debug, Clone, PartialEq, Deserialize, EnumIter, Copy)]
|
||||
#[derive(ArgEnum, EnumString, EnumVariantNames, Debug, Clone, PartialEq, Eq, Deserialize, EnumIter, Copy)]
|
||||
#[clap(rename_all = "snake_case")]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
#[strum(serialize_all = "snake_case")]
|
||||
@@ -71,6 +71,7 @@ pub enum Step {
|
||||
Atom,
|
||||
BrewCask,
|
||||
BrewFormula,
|
||||
Bun,
|
||||
Bin,
|
||||
Cargo,
|
||||
Chezmoi,
|
||||
@@ -94,10 +95,12 @@ pub enum Step {
|
||||
GithubCliExtensions,
|
||||
GitRepos,
|
||||
Go,
|
||||
Guix,
|
||||
Haxelib,
|
||||
GnomeShellExtensions,
|
||||
HomeManager,
|
||||
Jetpack,
|
||||
Julia,
|
||||
Kakoune,
|
||||
Krew,
|
||||
Macports,
|
||||
@@ -107,6 +110,7 @@ pub enum Step {
|
||||
Nix,
|
||||
Node,
|
||||
Opam,
|
||||
Pacdef,
|
||||
Pacstall,
|
||||
Pearl,
|
||||
Pipx,
|
||||
@@ -114,6 +118,7 @@ pub enum Step {
|
||||
Pkg,
|
||||
Pkgin,
|
||||
Powershell,
|
||||
Protonup,
|
||||
Raco,
|
||||
Remotes,
|
||||
Restarts,
|
||||
@@ -166,6 +171,13 @@ pub struct Windows {
|
||||
enable_winget: Option<bool>,
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Default, Debug)]
|
||||
#[serde(deny_unknown_fields)]
|
||||
#[allow(clippy::upper_case_acronyms)]
|
||||
pub struct Yarn {
|
||||
use_sudo: Option<bool>,
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Default, Debug)]
|
||||
#[serde(deny_unknown_fields)]
|
||||
#[allow(clippy::upper_case_acronyms)]
|
||||
@@ -191,6 +203,7 @@ pub struct Flatpak {
|
||||
#[serde(deny_unknown_fields)]
|
||||
pub struct Brew {
|
||||
greedy_cask: Option<bool>,
|
||||
autoremove: Option<bool>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, Clone, Copy)]
|
||||
@@ -260,6 +273,7 @@ pub struct ConfigFile {
|
||||
cleanup: Option<bool>,
|
||||
notify_each_step: Option<bool>,
|
||||
accept_all_windows_updates: Option<bool>,
|
||||
skip_notify: Option<bool>,
|
||||
bashit_branch: Option<String>,
|
||||
only: Option<Vec<Step>>,
|
||||
composer: Option<Composer>,
|
||||
@@ -268,6 +282,7 @@ pub struct ConfigFile {
|
||||
git: Option<Git>,
|
||||
windows: Option<Windows>,
|
||||
npm: Option<NPM>,
|
||||
yarn: Option<Yarn>,
|
||||
vim: Option<Vim>,
|
||||
firmware: Option<Firmware>,
|
||||
vagrant: Option<Vagrant>,
|
||||
@@ -415,6 +430,10 @@ pub struct CommandLineArgs {
|
||||
#[clap(short = 'k', long = "keep")]
|
||||
keep_at_end: bool,
|
||||
|
||||
/// Skip sending a notification at the end of a run
|
||||
#[clap(long = "skip-notify")]
|
||||
skip_notify: bool,
|
||||
|
||||
/// Say yes to package manager's prompt
|
||||
#[clap(short = 'y', long = "yes", arg_enum, multiple_values = true, min_values = 0)]
|
||||
yes: Option<Vec<Step>>,
|
||||
@@ -600,6 +619,15 @@ impl Config {
|
||||
self.opt.keep_at_end || env::var("TOPGRADE_KEEP_END").is_ok()
|
||||
}
|
||||
|
||||
/// Skip sending a notification at the end of a run
|
||||
pub fn skip_notify(&self) -> bool {
|
||||
if let Some(yes) = self.config_file.skip_notify {
|
||||
return yes;
|
||||
}
|
||||
|
||||
self.opt.skip_notify
|
||||
}
|
||||
|
||||
/// Whether to set the terminal title
|
||||
pub fn set_title(&self) -> bool {
|
||||
self.config_file.set_title.unwrap_or(true)
|
||||
@@ -656,6 +684,15 @@ impl Config {
|
||||
.unwrap_or(false)
|
||||
}
|
||||
|
||||
/// Whether Brew should autoremove
|
||||
pub fn brew_autoremove(&self) -> bool {
|
||||
self.config_file
|
||||
.brew
|
||||
.as_ref()
|
||||
.and_then(|c| c.autoremove)
|
||||
.unwrap_or(false)
|
||||
}
|
||||
|
||||
/// Whether Composer should update itself
|
||||
pub fn composer_self_update(&self) -> bool {
|
||||
self.config_file
|
||||
@@ -839,6 +876,14 @@ impl Config {
|
||||
.and_then(|npm| npm.use_sudo)
|
||||
.unwrap_or(false)
|
||||
}
|
||||
#[cfg(target_os = "linux")]
|
||||
pub fn yarn_use_sudo(&self) -> bool {
|
||||
self.config_file
|
||||
.yarn
|
||||
.as_ref()
|
||||
.and_then(|yarn| yarn.use_sudo)
|
||||
.unwrap_or(false)
|
||||
}
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
pub fn firmware_upgrade(&self) -> bool {
|
||||
|
||||
@@ -2,7 +2,7 @@ use std::process::ExitStatus;
|
||||
|
||||
use thiserror::Error;
|
||||
|
||||
#[derive(Error, Debug, PartialEq)]
|
||||
#[derive(Error, Debug, PartialEq, Eq)]
|
||||
pub enum TopgradeError {
|
||||
#[error("{0}")]
|
||||
ProcessFailed(ExitStatus),
|
||||
|
||||
27
src/main.rs
27
src/main.rs
@@ -191,9 +191,12 @@ fn run() -> Result<()> {
|
||||
{
|
||||
runner.execute(Step::Yadm, "yadm", || unix::run_yadm(&ctx))?;
|
||||
runner.execute(Step::Nix, "nix", || unix::run_nix(&ctx))?;
|
||||
runner.execute(Step::Guix, "guix", || unix::run_guix(&ctx))?;
|
||||
|
||||
runner.execute(Step::HomeManager, "home-manager", || unix::run_home_manager(run_type))?;
|
||||
runner.execute(Step::Asdf, "asdf", || unix::run_asdf(run_type))?;
|
||||
runner.execute(Step::Pkgin, "pkgin", || unix::run_pkgin(&ctx))?;
|
||||
runner.execute(Step::Bun, "bun", || unix::run_bun(&ctx))?;
|
||||
}
|
||||
|
||||
#[cfg(target_os = "dragonfly")]
|
||||
@@ -315,7 +318,7 @@ fn run() -> Result<()> {
|
||||
runner.execute(Step::Flutter, "Flutter", || generic::run_flutter_upgrade(run_type))?;
|
||||
runner.execute(Step::Go, "Go", || generic::run_go(run_type))?;
|
||||
runner.execute(Step::Emacs, "Emacs", || emacs.upgrade(&ctx))?;
|
||||
runner.execute(Step::Opam, "opam", || generic::run_opam_update(run_type))?;
|
||||
runner.execute(Step::Opam, "opam", || generic::run_opam_update(&ctx))?;
|
||||
runner.execute(Step::Vcpkg, "vcpkg", || generic::run_vcpkg_update(run_type))?;
|
||||
runner.execute(Step::Pipx, "pipx", || generic::run_pipx_update(run_type))?;
|
||||
runner.execute(Step::Conda, "conda", || generic::run_conda_update(&ctx))?;
|
||||
@@ -335,11 +338,13 @@ fn run() -> Result<()> {
|
||||
runner.execute(Step::Vim, "voom", || vim::run_voom(&base_dirs, run_type))?;
|
||||
runner.execute(Step::Kakoune, "Kakoune", || kakoune::upgrade_kak_plug(&ctx))?;
|
||||
runner.execute(Step::Node, "npm", || node::run_npm_upgrade(&ctx))?;
|
||||
runner.execute(Step::Node, "yarn", || node::run_yarn_upgrade(&ctx))?;
|
||||
runner.execute(Step::Containers, "Containers", || containers::run_containers(&ctx))?;
|
||||
runner.execute(Step::Deno, "deno", || node::deno_upgrade(&ctx))?;
|
||||
runner.execute(Step::Composer, "composer", || generic::run_composer_update(&ctx))?;
|
||||
runner.execute(Step::Krew, "krew", || generic::run_krew_upgrade(run_type))?;
|
||||
runner.execute(Step::Gem, "gem", || generic::run_gem(&base_dirs, run_type))?;
|
||||
runner.execute(Step::Julia, "julia", || generic::update_julia_packages(&ctx))?;
|
||||
runner.execute(Step::Haxelib, "haxelib", || generic::run_haxelib_update(&ctx))?;
|
||||
runner.execute(Step::Sheldon, "sheldon", || generic::run_sheldon(&ctx))?;
|
||||
runner.execute(Step::Rtcl, "rtcl", || generic::run_rtcl(&ctx))?;
|
||||
@@ -361,6 +366,8 @@ fn run() -> Result<()> {
|
||||
runner.execute(Step::Flatpak, "Flatpak", || linux::flatpak_update(&ctx))?;
|
||||
runner.execute(Step::Snap, "snap", || linux::run_snap(sudo.as_ref(), run_type))?;
|
||||
runner.execute(Step::Pacstall, "pacstall", || linux::run_pacstall(&ctx))?;
|
||||
runner.execute(Step::Pacdef, "pacdef", || linux::run_pacdef(&ctx))?;
|
||||
runner.execute(Step::Protonup, "protonup", || linux::run_protonup_update(&ctx))?;
|
||||
}
|
||||
|
||||
if let Some(commands) = config.commands() {
|
||||
@@ -460,13 +467,17 @@ fn run() -> Result<()> {
|
||||
}
|
||||
|
||||
let failed = post_command_failed || runner.report().data().iter().any(|(_, result)| result.failed());
|
||||
terminal::notify_desktop(
|
||||
format!(
|
||||
"Topgrade finished {}",
|
||||
if failed { "with errors" } else { "successfully" }
|
||||
),
|
||||
None,
|
||||
);
|
||||
|
||||
if !config.skip_notify() {
|
||||
terminal::notify_desktop(
|
||||
format!(
|
||||
"Topgrade finished {}",
|
||||
if failed { "with errors" } else { "successfully" }
|
||||
),
|
||||
None,
|
||||
);
|
||||
}
|
||||
|
||||
if failed {
|
||||
Err(StepFailed.into())
|
||||
} else {
|
||||
|
||||
0
src/steps/bun.rs
Normal file
0
src/steps/bun.rs
Normal file
@@ -67,25 +67,24 @@ impl Emacs {
|
||||
print_separator("Doom Emacs");
|
||||
|
||||
let mut command = ctx.run_type().execute(doom);
|
||||
command.args(&["-y", "upgrade"]);
|
||||
|
||||
if ctx.config().yes(Step::Emacs) {
|
||||
command.arg("--force");
|
||||
}
|
||||
|
||||
command.args(&["upgrade"]);
|
||||
|
||||
command.check_run()
|
||||
}
|
||||
|
||||
pub fn upgrade(&self, ctx: &ExecutionContext) -> Result<()> {
|
||||
let emacs = require("emacs")?;
|
||||
if let Some(doom) = &self.doom {
|
||||
Emacs::update_doom(doom, ctx)?;
|
||||
}
|
||||
let init_file = require_option(self.directory.as_ref(), String::from("Emacs directory does not exist"))?
|
||||
.join("init.el")
|
||||
.require()?;
|
||||
|
||||
if let Some(doom) = &self.doom {
|
||||
return Emacs::update_doom(doom, ctx);
|
||||
}
|
||||
|
||||
print_separator("Emacs");
|
||||
|
||||
let mut command = ctx.run_type().execute(&emacs);
|
||||
|
||||
@@ -220,13 +220,19 @@ pub fn run_rtcl(ctx: &ExecutionContext) -> Result<()> {
|
||||
ctx.run_type().execute(&rupdate).check_run()
|
||||
}
|
||||
|
||||
pub fn run_opam_update(run_type: RunType) -> Result<()> {
|
||||
pub fn run_opam_update(ctx: &ExecutionContext) -> Result<()> {
|
||||
let opam = utils::require("opam")?;
|
||||
|
||||
print_separator("OCaml Package Manager");
|
||||
|
||||
run_type.execute(&opam).arg("update").check_run()?;
|
||||
run_type.execute(&opam).arg("upgrade").check_run()
|
||||
ctx.run_type().execute(&opam).arg("update").check_run()?;
|
||||
ctx.run_type().execute(&opam).arg("upgrade").check_run()?;
|
||||
|
||||
if ctx.config().cleanup() {
|
||||
ctx.run_type().execute(&opam).arg("clean").check_run()?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn run_vcpkg_update(run_type: RunType) -> Result<()> {
|
||||
@@ -496,3 +502,14 @@ pub fn run_ghcli_extensions_upgrade(ctx: &ExecutionContext) -> Result<()> {
|
||||
.args(&["extension", "upgrade", "--all"])
|
||||
.check_run()
|
||||
}
|
||||
|
||||
pub fn update_julia_packages(ctx: &ExecutionContext) -> Result<()> {
|
||||
let julia = utils::require("julia")?;
|
||||
|
||||
print_separator("Julia Packages");
|
||||
|
||||
ctx.run_type()
|
||||
.execute(&julia)
|
||||
.args(&["-e", "using Pkg; Pkg.update()"])
|
||||
.check_run()
|
||||
}
|
||||
|
||||
@@ -20,15 +20,11 @@ use crate::{error::SkipStep, execution_context::ExecutionContext};
|
||||
#[allow(clippy::upper_case_acronyms)]
|
||||
struct NPM {
|
||||
command: PathBuf,
|
||||
pnpm: Option<PathBuf>,
|
||||
}
|
||||
|
||||
impl NPM {
|
||||
fn new(command: PathBuf) -> Self {
|
||||
Self {
|
||||
command,
|
||||
pnpm: require("pnpm").ok(),
|
||||
}
|
||||
Self { command }
|
||||
}
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
@@ -56,17 +52,13 @@ impl NPM {
|
||||
fn upgrade(&self, run_type: RunType, use_sudo: bool) -> Result<()> {
|
||||
print_separator("Node Package Manager");
|
||||
let version = self.version()?;
|
||||
let args = if version < Version::new(8, 11, 0) || self.pnpm.is_some() {
|
||||
let args = if version < Version::new(8, 11, 0) {
|
||||
["update", "-g"]
|
||||
} else {
|
||||
["update", "--location=global"]
|
||||
};
|
||||
if use_sudo {
|
||||
run_type
|
||||
.execute("sudo")
|
||||
.arg(self.pnpm.as_ref().unwrap_or(&self.command))
|
||||
.args(args)
|
||||
.check_run()?;
|
||||
run_type.execute("sudo").args(args).check_run()?;
|
||||
} else {
|
||||
run_type.execute(&self.command).args(args).check_run()?;
|
||||
}
|
||||
@@ -88,6 +80,59 @@ impl NPM {
|
||||
}
|
||||
}
|
||||
|
||||
struct Yarn {
|
||||
command: PathBuf,
|
||||
yarn: Option<PathBuf>,
|
||||
}
|
||||
|
||||
impl Yarn {
|
||||
fn new(command: PathBuf) -> Self {
|
||||
Self {
|
||||
command,
|
||||
yarn: require("yarn").ok(),
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
fn root(&self) -> Result<PathBuf> {
|
||||
let args = ["global", "dir"];
|
||||
Command::new(&self.command)
|
||||
.args(args)
|
||||
.check_output()
|
||||
.map(|s| PathBuf::from(s.trim()))
|
||||
}
|
||||
|
||||
fn upgrade(&self, run_type: RunType, use_sudo: bool) -> Result<()> {
|
||||
print_separator("Yarn Package Manager");
|
||||
let args = ["global", "upgrade"];
|
||||
|
||||
if use_sudo {
|
||||
run_type
|
||||
.execute("sudo")
|
||||
.arg(self.yarn.as_ref().unwrap_or(&self.command))
|
||||
.args(args)
|
||||
.check_run()?;
|
||||
} else {
|
||||
run_type.execute(&self.command).args(args).check_run()?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
pub fn should_use_sudo(&self) -> Result<bool> {
|
||||
let yarn_root = self.root()?;
|
||||
if !yarn_root.exists() {
|
||||
return Err(SkipStep(format!("NPM root at {} doesn't exist", yarn_root.display(),)).into());
|
||||
}
|
||||
|
||||
let metadata = std::fs::metadata(&yarn_root)?;
|
||||
let uid = Uid::effective();
|
||||
|
||||
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()? {
|
||||
@@ -102,8 +147,22 @@ fn should_use_sudo(npm: &NPM, ctx: &ExecutionContext) -> Result<bool> {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
fn should_use_sudo_yarn(yarn: &Yarn, ctx: &ExecutionContext) -> Result<bool> {
|
||||
if yarn.should_use_sudo()? {
|
||||
if ctx.config().yarn_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())
|
||||
}
|
||||
} else {
|
||||
Ok(false)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn run_npm_upgrade(ctx: &ExecutionContext) -> Result<()> {
|
||||
let npm = require("npm").map(NPM::new)?;
|
||||
let npm = require("pnpm").or_else(|_| require("npm")).map(NPM::new)?;
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
{
|
||||
@@ -116,6 +175,20 @@ pub fn run_npm_upgrade(ctx: &ExecutionContext) -> Result<()> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn run_yarn_upgrade(ctx: &ExecutionContext) -> Result<()> {
|
||||
let yarn = require("yarn").map(Yarn::new)?;
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
{
|
||||
yarn.upgrade(ctx.run_type(), should_use_sudo_yarn(&yarn, ctx)?)
|
||||
}
|
||||
|
||||
#[cfg(not(target_os = "linux"))]
|
||||
{
|
||||
yarn.upgrade(ctx.run_type(), false)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn deno_upgrade(ctx: &ExecutionContext) -> Result<()> {
|
||||
let deno = require("deno")?;
|
||||
let deno_dir = ctx.base_dirs().home_dir().join(".deno");
|
||||
|
||||
@@ -26,6 +26,7 @@ pub enum Distribution {
|
||||
Fedora,
|
||||
Debian,
|
||||
Gentoo,
|
||||
OpenMandriva,
|
||||
Suse,
|
||||
Void,
|
||||
Solus,
|
||||
@@ -44,7 +45,7 @@ impl Distribution {
|
||||
Some("alpine") => Distribution::Alpine,
|
||||
Some("centos") | Some("rhel") | Some("ol") => Distribution::CentOS,
|
||||
Some("clear-linux-os") => Distribution::ClearLinux,
|
||||
Some("fedora") => Distribution::Fedora,
|
||||
Some("fedora") | Some("nobara") => Distribution::Fedora,
|
||||
Some("void") => Distribution::Void,
|
||||
Some("debian") | Some("pureos") => Distribution::Debian,
|
||||
Some("arch") | Some("anarchy") | Some("manjaro-arm") | Some("garuda") | Some("artix") => Distribution::Arch,
|
||||
@@ -53,6 +54,7 @@ impl Distribution {
|
||||
Some("exherbo") => Distribution::Exherbo,
|
||||
Some("nixos") => Distribution::NixOS,
|
||||
Some("neon") => Distribution::KDENeon,
|
||||
Some("openmandriva") => Distribution::OpenMandriva,
|
||||
_ => {
|
||||
if let Some(id_like) = id_like {
|
||||
if id_like.contains(&"debian") || id_like.contains(&"ubuntu") {
|
||||
@@ -105,6 +107,7 @@ impl Distribution {
|
||||
Distribution::NixOS => upgrade_nixos(ctx),
|
||||
Distribution::KDENeon => upgrade_neon(ctx),
|
||||
Distribution::Bedrock => update_bedrock(ctx),
|
||||
Distribution::OpenMandriva => upgrade_openmandriva(ctx),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -218,6 +221,28 @@ fn upgrade_suse(ctx: &ExecutionContext) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn upgrade_openmandriva(ctx: &ExecutionContext) -> Result<()> {
|
||||
if let Some(sudo) = &ctx.sudo() {
|
||||
let mut command = ctx.run_type().execute(&sudo);
|
||||
|
||||
command.arg(which("dnf").unwrap().to_path_buf()).arg("upgrade");
|
||||
|
||||
if let Some(args) = ctx.config().dnf_arguments() {
|
||||
command.args(args.split_whitespace());
|
||||
}
|
||||
|
||||
if ctx.config().yes(Step::System) {
|
||||
command.arg("-y");
|
||||
}
|
||||
|
||||
command.check_run()?;
|
||||
} else {
|
||||
print_warning("No sudo detected. Skipping system upgrade");
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn upgrade_void(ctx: &ExecutionContext) -> Result<()> {
|
||||
if let Some(sudo) = ctx.sudo() {
|
||||
let mut command = ctx.run_type().execute(&sudo);
|
||||
@@ -349,6 +374,17 @@ fn upgrade_solus(ctx: &ExecutionContext) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn run_pacdef(ctx: &ExecutionContext) -> Result<()> {
|
||||
let pacdef = require("pacdef")?;
|
||||
|
||||
print_separator("pacdef");
|
||||
|
||||
ctx.run_type().execute(&pacdef).arg("sync").check_run()?;
|
||||
|
||||
println!();
|
||||
ctx.run_type().execute(&pacdef).arg("review").check_run()
|
||||
}
|
||||
|
||||
pub fn run_pacstall(ctx: &ExecutionContext) -> Result<()> {
|
||||
let pacstall = require("pacstall")?;
|
||||
|
||||
@@ -492,44 +528,50 @@ pub fn flatpak_update(ctx: &ExecutionContext) -> Result<()> {
|
||||
let flatpak = require("flatpak")?;
|
||||
let sudo = require_option(ctx.sudo().as_ref(), String::from("sudo is not installed"))?;
|
||||
let cleanup = ctx.config().cleanup();
|
||||
let yes = ctx.config().yes(Step::Flatpak);
|
||||
let run_type = ctx.run_type();
|
||||
print_separator("Flatpak User Packages");
|
||||
|
||||
run_type
|
||||
.execute(&flatpak)
|
||||
.args(&["update", "--user", "-y"])
|
||||
.check_run()?;
|
||||
let mut update_args = vec!["update", "--user"];
|
||||
if yes {
|
||||
update_args.push("-y");
|
||||
}
|
||||
run_type.execute(&flatpak).args(&update_args).check_run()?;
|
||||
|
||||
if cleanup {
|
||||
run_type
|
||||
.execute(&flatpak)
|
||||
.args(&["uninstall", "--user", "--unused"])
|
||||
.check_run()?;
|
||||
let mut cleanup_args = vec!["uninstall", "--user", "--unused"];
|
||||
if yes {
|
||||
cleanup_args.push("-y");
|
||||
}
|
||||
run_type.execute(&flatpak).args(&cleanup_args).check_run()?;
|
||||
}
|
||||
|
||||
print_separator("Flatpak System Packages");
|
||||
if ctx.config().flatpak_use_sudo() || std::env::var("SSH_CLIENT").is_ok() {
|
||||
run_type
|
||||
.execute(&sudo)
|
||||
.arg(&flatpak)
|
||||
.args(&["update", "--system", "-y"])
|
||||
.check_run()?;
|
||||
let mut update_args = vec!["update", "--system"];
|
||||
if yes {
|
||||
update_args.push("-y");
|
||||
}
|
||||
run_type.execute(&sudo).arg(&flatpak).args(&update_args).check_run()?;
|
||||
if cleanup {
|
||||
run_type
|
||||
.execute(sudo)
|
||||
.arg(flatpak)
|
||||
.args(&["uninstall", "--system", "--unused"])
|
||||
.check_run()?;
|
||||
let mut cleanup_args = vec!["uninstall", "--system", "--unused"];
|
||||
if yes {
|
||||
cleanup_args.push("-y");
|
||||
}
|
||||
run_type.execute(sudo).arg(flatpak).args(&cleanup_args).check_run()?;
|
||||
}
|
||||
} else {
|
||||
run_type
|
||||
.execute(&flatpak)
|
||||
.args(&["update", "--system", "-y"])
|
||||
.check_run()?;
|
||||
let mut update_args = vec!["update", "--system"];
|
||||
if yes {
|
||||
update_args.push("-y");
|
||||
}
|
||||
run_type.execute(&flatpak).args(&update_args).check_run()?;
|
||||
if cleanup {
|
||||
run_type
|
||||
.execute(flatpak)
|
||||
.args(&["uninstall", "--system", "--unused"])
|
||||
.check_run()?;
|
||||
let mut cleanup_args = vec!["uninstall", "--system", "--unused"];
|
||||
if yes {
|
||||
cleanup_args.push("-y");
|
||||
}
|
||||
run_type.execute(flatpak).args(&cleanup_args).check_run()?;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -558,6 +600,15 @@ pub fn run_pihole_update(sudo: Option<&PathBuf>, run_type: RunType) -> Result<()
|
||||
run_type.execute(sudo).arg(pihole).arg("-up").check_run()
|
||||
}
|
||||
|
||||
pub fn run_protonup_update(ctx: &ExecutionContext) -> Result<()> {
|
||||
let protonup = require("protonup")?;
|
||||
|
||||
print_separator("protonup");
|
||||
|
||||
ctx.run_type().execute(protonup).check_run()?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn run_config_update(ctx: &ExecutionContext) -> Result<()> {
|
||||
let sudo = require_option(ctx.sudo().as_ref(), String::from("sudo is not installed"))?;
|
||||
if ctx.config().yes(Step::ConfigUpdate) {
|
||||
|
||||
@@ -210,6 +210,10 @@ pub fn run_brew_formula(ctx: &ExecutionContext, variant: BrewVariant) -> Result<
|
||||
variant.execute(run_type).arg("cleanup").check_run()?;
|
||||
}
|
||||
|
||||
if ctx.config().brew_autoremove() {
|
||||
variant.execute(run_type).arg("autoremove").check_run()?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -251,6 +255,24 @@ pub fn run_brew_cask(ctx: &ExecutionContext, variant: BrewVariant) -> Result<()>
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn run_guix(ctx: &ExecutionContext) -> Result<()> {
|
||||
let guix = require("guix")?;
|
||||
|
||||
let run_type = ctx.run_type();
|
||||
|
||||
let output = Command::new(&guix).arg("pull").check_output();
|
||||
debug!("guix pull output: {:?}", output);
|
||||
let should_upgrade = output.is_ok();
|
||||
debug!("Can Upgrade Guix: {:?}", should_upgrade);
|
||||
|
||||
print_separator("Guix");
|
||||
|
||||
if should_upgrade {
|
||||
return run_type.execute(&guix).args(&["package", "-u"]).check_run();
|
||||
}
|
||||
Err(SkipStep(String::from("Guix Pull Failed, Skipping")).into())
|
||||
}
|
||||
|
||||
pub fn run_nix(ctx: &ExecutionContext) -> Result<()> {
|
||||
let nix = require("nix")?;
|
||||
let nix_channel = require("nix-channel")?;
|
||||
@@ -274,6 +296,16 @@ pub fn run_nix(ctx: &ExecutionContext) -> Result<()> {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
{
|
||||
if let Ok(..) = require("darwin-rebuild") {
|
||||
return Err(SkipStep(String::from(
|
||||
"Nix-darwin on macOS must be upgraded via darwin-rebuild switch",
|
||||
))
|
||||
.into());
|
||||
}
|
||||
}
|
||||
|
||||
let run_type = ctx.run_type();
|
||||
|
||||
if should_self_upgrade {
|
||||
@@ -391,6 +423,14 @@ pub fn run_sdkman(base_dirs: &BaseDirs, cleanup: bool, run_type: RunType) -> Res
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn run_bun(ctx: &ExecutionContext) -> Result<()> {
|
||||
let bun = require("bun")?;
|
||||
|
||||
print_separator("Bun");
|
||||
|
||||
ctx.run_type().execute(&bun).arg("upgrade").check_run()
|
||||
}
|
||||
|
||||
pub fn reboot() {
|
||||
print!("Rebooting...");
|
||||
Command::new("sudo").arg("reboot").spawn().unwrap().wait().unwrap();
|
||||
|
||||
Reference in New Issue
Block a user