Compare commits
17 Commits
v10.1.0-rc
...
v10.1.0-cd
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9233846479 | ||
|
|
94bdb8c3fd | ||
|
|
632fcb5b77 | ||
|
|
55ba2d30c1 | ||
|
|
ff66611ec0 | ||
|
|
edc3dd6b0b | ||
|
|
623a11cf21 | ||
|
|
7a83f38ca8 | ||
|
|
9a19b547c6 | ||
|
|
aae5c3b631 | ||
|
|
3be75bf399 | ||
|
|
a7c2262537 | ||
|
|
16a7d5f00b | ||
|
|
be0984cdf3 | ||
|
|
fb13543e44 | ||
|
|
c406fe2775 | ||
|
|
ce0c0c4314 |
5
.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
5
.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
blank_issues_enabled: false
|
||||||
|
contact_links:
|
||||||
|
- name: GitHub Discussions
|
||||||
|
url: https://github.com/topgrade-rs/topgrade/discussions
|
||||||
|
about: Please ask and answer questions here.
|
||||||
2
.github/workflows/release-cross.yml
vendored
2
.github/workflows/release-cross.yml
vendored
@@ -19,7 +19,7 @@ jobs:
|
|||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
- uses: actions-rs/toolchain@v1
|
- uses: actions-rs/toolchain@v1
|
||||||
with:
|
with:
|
||||||
toolchain: 1.57.0
|
toolchain: stable
|
||||||
profile: minimal
|
profile: minimal
|
||||||
default: true
|
default: true
|
||||||
override: true
|
override: true
|
||||||
|
|||||||
2
.github/workflows/release.yml
vendored
2
.github/workflows/release.yml
vendored
@@ -19,7 +19,7 @@ jobs:
|
|||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
- uses: actions-rs/toolchain@v1
|
- uses: actions-rs/toolchain@v1
|
||||||
with:
|
with:
|
||||||
toolchain: 1.57.0
|
toolchain: stable
|
||||||
profile: minimal
|
profile: minimal
|
||||||
override: true
|
override: true
|
||||||
components: rustfmt, clippy
|
components: rustfmt, clippy
|
||||||
|
|||||||
75
Cargo.lock
generated
75
Cargo.lock
generated
@@ -225,16 +225,16 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "clap"
|
name = "clap"
|
||||||
version = "3.2.22"
|
version = "3.1.18"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "86447ad904c7fb335a790c9d7fe3d0d971dc523b8ccd1561a520de9a85302750"
|
checksum = "d2dbdf4bdacb33466e854ce889eee8dfd5729abf7ccd7664d0a2d60cd384440b"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"atty",
|
"atty",
|
||||||
"bitflags",
|
"bitflags",
|
||||||
"clap_derive",
|
"clap_derive",
|
||||||
"clap_lex",
|
"clap_lex",
|
||||||
"indexmap",
|
"indexmap",
|
||||||
"once_cell",
|
"lazy_static",
|
||||||
"strsim",
|
"strsim",
|
||||||
"termcolor",
|
"termcolor",
|
||||||
"textwrap",
|
"textwrap",
|
||||||
@@ -242,9 +242,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "clap_derive"
|
name = "clap_derive"
|
||||||
version = "3.2.18"
|
version = "3.1.18"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ea0c8bce528c4be4da13ea6fead8965e95b6073585a2f05204bd8f4119f82a65"
|
checksum = "25320346e922cffe59c0bbc5410c8d8784509efb321488971081313cb1e1a33c"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"heck 0.4.0",
|
"heck 0.4.0",
|
||||||
"proc-macro-error",
|
"proc-macro-error",
|
||||||
@@ -660,9 +660,9 @@ checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "h2"
|
name = "h2"
|
||||||
version = "0.3.15"
|
version = "0.3.12"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5f9f29bc9dda355256b2916cf526ab02ce0aeaaaf2bad60d65ef3f12f11dd0f4"
|
checksum = "62eeb471aa3e3c9197aa4bfeabfe02982f6dc96f750486c0bb0009ac58b26d2b"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bytes",
|
"bytes",
|
||||||
"fnv",
|
"fnv",
|
||||||
@@ -985,14 +985,24 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "mio"
|
name = "mio"
|
||||||
version = "0.8.5"
|
version = "0.7.14"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e5d732bc30207a6423068df043e3d02e0735b155ad7ce1a6f76fe2baa5b158de"
|
checksum = "8067b404fe97c70829f082dec8bcf4f71225d7eaea1d8645349cb76fa06205cc"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
"log",
|
"log",
|
||||||
"wasi 0.11.0+wasi-snapshot-preview1",
|
"miow",
|
||||||
"windows-sys",
|
"ntapi",
|
||||||
|
"winapi",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "miow"
|
||||||
|
version = "0.3.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b9f1c5b025cda876f66ef43a113f91ebc9f4ccef34843000e0adf6ebbab84e21"
|
||||||
|
dependencies = [
|
||||||
|
"winapi",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -1034,6 +1044,15 @@ dependencies = [
|
|||||||
"zvariant_derive",
|
"zvariant_derive",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ntapi"
|
||||||
|
version = "0.3.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c28774a7fd2fbb4f0babd8237ce554b73af68021b5f695a3cebd6c59bac0980f"
|
||||||
|
dependencies = [
|
||||||
|
"winapi",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "num-integer"
|
name = "num-integer"
|
||||||
version = "0.1.45"
|
version = "0.1.45"
|
||||||
@@ -1358,9 +1377,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "regex"
|
name = "regex"
|
||||||
version = "1.6.0"
|
version = "1.5.6"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "4c4eb3267174b8c6c2f654116623910a0fef09c4753f8dd83db29c48a0df988b"
|
checksum = "d83f127d94bdbcda4c8cc2e50f6f84f4b611f69c902699ca385a39c3a75f9ff1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"aho-corasick",
|
"aho-corasick",
|
||||||
"memchr",
|
"memchr",
|
||||||
@@ -1606,6 +1625,12 @@ version = "1.0.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ae1a47186c03a32177042e55dbc5fd5aee900b8e0069a8d70fba96a9375cd012"
|
checksum = "ae1a47186c03a32177042e55dbc5fd5aee900b8e0069a8d70fba96a9375cd012"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "shell-words"
|
||||||
|
version = "1.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "24188a676b6ae68c3b2cb3a01be17fbf7240ce009799bb56d5b1409051e78fde"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "shellexpand"
|
name = "shellexpand"
|
||||||
version = "2.1.2"
|
version = "2.1.2"
|
||||||
@@ -1755,13 +1780,13 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tempfile"
|
name = "tempfile"
|
||||||
version = "3.3.0"
|
version = "3.2.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5cdb1ef4eaeeaddc8fbd371e5017057064af0911902ef36b39801f67cc6d79e4"
|
checksum = "dac1c663cfc93810f88aed9b8941d48cabf856a1b111c29a40439018d870eb22"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
"fastrand",
|
|
||||||
"libc",
|
"libc",
|
||||||
|
"rand",
|
||||||
"redox_syscall",
|
"redox_syscall",
|
||||||
"remove_dir_all",
|
"remove_dir_all",
|
||||||
"winapi",
|
"winapi",
|
||||||
@@ -1869,9 +1894,9 @@ checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tokio"
|
name = "tokio"
|
||||||
version = "1.21.2"
|
version = "1.5.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a9e03c497dc955702ba729190dc4aac6f2a0ce97f913e5b1b5912fc5039d9099"
|
checksum = "cd3b82e6e823a9ee7d7f64b08f8ac3d5f08ac988f23157194bd32af3f2f92767"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"autocfg",
|
"autocfg",
|
||||||
"bytes",
|
"bytes",
|
||||||
@@ -1879,9 +1904,9 @@ dependencies = [
|
|||||||
"memchr",
|
"memchr",
|
||||||
"mio",
|
"mio",
|
||||||
"num_cpus",
|
"num_cpus",
|
||||||
|
"once_cell",
|
||||||
"pin-project-lite",
|
"pin-project-lite",
|
||||||
"signal-hook-registry",
|
"signal-hook-registry",
|
||||||
"socket2",
|
|
||||||
"winapi",
|
"winapi",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -1898,16 +1923,16 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tokio-util"
|
name = "tokio-util"
|
||||||
version = "0.7.4"
|
version = "0.6.9"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "0bb2e075f03b3d66d8d8785356224ba688d2906a371015e225beeb65ca92c740"
|
checksum = "9e99e1983e5d376cd8eb4b66604d2e99e79f5bd988c3055891dcd8c9e2604cc0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bytes",
|
"bytes",
|
||||||
"futures-core",
|
"futures-core",
|
||||||
"futures-sink",
|
"futures-sink",
|
||||||
|
"log",
|
||||||
"pin-project-lite",
|
"pin-project-lite",
|
||||||
"tokio",
|
"tokio",
|
||||||
"tracing",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -1943,6 +1968,7 @@ dependencies = [
|
|||||||
"self_update",
|
"self_update",
|
||||||
"semver",
|
"semver",
|
||||||
"serde",
|
"serde",
|
||||||
|
"shell-words",
|
||||||
"shellexpand",
|
"shellexpand",
|
||||||
"strum 0.24.1",
|
"strum 0.24.1",
|
||||||
"sys-info",
|
"sys-info",
|
||||||
@@ -2210,13 +2236,12 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "which"
|
name = "which"
|
||||||
version = "4.3.0"
|
version = "4.1.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1c831fbbee9e129a8cf93e7747a82da9d95ba8e16621cae60ec2cdc849bacb7b"
|
checksum = "b55551e42cbdf2ce2bedd2203d0cc08dba002c27510f86dab6d0ce304cba3dfe"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"either",
|
"either",
|
||||||
"libc",
|
"libc",
|
||||||
"once_cell",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|||||||
61
Cargo.toml
61
Cargo.toml
@@ -20,43 +20,44 @@ path = "src/main.rs"
|
|||||||
##name = "topgrade_lib"
|
##name = "topgrade_lib"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
home = "0.5"
|
home = "~0.5"
|
||||||
directories = "4.0"
|
directories = "~4.0"
|
||||||
serde = { version = "1.0", features = ["derive"] }
|
serde = { version = "~1.0", features = ["derive"] }
|
||||||
toml = "0.5"
|
toml = "0.5"
|
||||||
which_crate = { version = "4.1", package = "which" }
|
which_crate = { version = "~4.1", package = "which" }
|
||||||
shellexpand = "2.1"
|
shellexpand = "~2.1"
|
||||||
clap = { version = "3.1", features = ["cargo", "derive"] }
|
clap = { version = "~3.1", features = ["cargo", "derive"] }
|
||||||
log = "0.4"
|
log = "~0.4"
|
||||||
walkdir = "2.3"
|
walkdir = "~2.3"
|
||||||
console = "0.15"
|
console = "~0.15"
|
||||||
lazy_static = "1.4"
|
lazy_static = "~1.4"
|
||||||
chrono = "0.4"
|
chrono = "~0.4"
|
||||||
pretty_env_logger = "0.4"
|
pretty_env_logger = "~0.4"
|
||||||
glob = "0.3"
|
glob = "~0.3"
|
||||||
strum = { version = "0.24", features = ["derive"] }
|
strum = { version = "~0.24", features = ["derive"] }
|
||||||
thiserror = "1.0"
|
thiserror = "~1.0"
|
||||||
anyhow = "1.0"
|
anyhow = "~1.0"
|
||||||
tempfile = "3.2"
|
tempfile = "~3.2"
|
||||||
cfg-if = "1.0"
|
cfg-if = "~1.0"
|
||||||
tokio = { version = "1.5", features = ["process", "rt-multi-thread"] }
|
tokio = { version = "~1.5", features = ["process", "rt-multi-thread"] }
|
||||||
futures = "0.3"
|
futures = "~0.3"
|
||||||
regex = "1.5"
|
regex = "~1.5"
|
||||||
sys-info = "0.9"
|
sys-info = "~0.9"
|
||||||
semver = "1.0"
|
semver = "~1.0"
|
||||||
|
shell-words = "~1.1"
|
||||||
|
|
||||||
[target.'cfg(target_os = "macos")'.dependencies]
|
[target.'cfg(target_os = "macos")'.dependencies]
|
||||||
notify-rust = "4.5"
|
notify-rust = "~4.5"
|
||||||
|
|
||||||
[target.'cfg(unix)'.dependencies]
|
[target.'cfg(unix)'.dependencies]
|
||||||
nix = "0.24"
|
nix = "~0.24"
|
||||||
rust-ini = "0.18"
|
rust-ini = "~0.18"
|
||||||
self_update_crate = { version = "0.30", default-features = false, optional = true, package = "self_update", features = ["archive-tar", "compression-flate2", "rustls"] }
|
self_update_crate = { version = "~0.30", default-features = false, optional = true, package = "self_update", features = ["archive-tar", "compression-flate2", "rustls"] }
|
||||||
|
|
||||||
[target.'cfg(windows)'.dependencies]
|
[target.'cfg(windows)'.dependencies]
|
||||||
self_update_crate = { version = "0.30", default-features = false, optional = true, package = "self_update", features = ["archive-zip", "compression-zip-deflate", "rustls"] }
|
self_update_crate = { version = "~0.30", default-features = false, optional = true, package = "self_update", features = ["archive-zip", "compression-zip-deflate", "rustls"] }
|
||||||
winapi = "0.3"
|
winapi = "~0.3"
|
||||||
parselnk = "0.1"
|
parselnk = "~0.1"
|
||||||
|
|
||||||
[profile.release]
|
[profile.release]
|
||||||
lto = true
|
lto = true
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ You can visit the documentation at [topgrade-rs.github.io](https://topgrade-rs.g
|
|||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
Just run `topgrade`.
|
Just run `topgrade`.
|
||||||
See [the wiki](https://github.com/r-darwish/topgrade/wiki/Step-list) for the list of things Topgrade supports.
|
See [the documentation](https://topgrade-rs.github.io/) for the list of things Topgrade supports.
|
||||||
|
|
||||||
## Customization
|
## Customization
|
||||||
|
|
||||||
@@ -84,6 +84,6 @@ To limit the execution only to specific hosts use the `--remote-host-limit` para
|
|||||||
|
|
||||||
## ToDo
|
## ToDo
|
||||||
|
|
||||||
- Add a proper testing framework to the code base.
|
- [ ] Add a proper testing framework to the code base.
|
||||||
- Add unit tests for package managers.
|
- [ ] Add unit tests for package managers.
|
||||||
- Split up code into more maintainable parts, eg. putting every linux package manager in a own submodule of linux.rs.
|
- [ ] Split up code into more maintainable parts, eg. putting every linux package manager in a own submodule of linux.rs.
|
||||||
|
|||||||
@@ -1,16 +1,16 @@
|
|||||||
#![allow(dead_code)]
|
#![allow(dead_code)]
|
||||||
use std::collections::BTreeMap;
|
use anyhow::Context;
|
||||||
use std::fs::write;
|
|
||||||
use std::path::PathBuf;
|
|
||||||
use std::process::Command;
|
|
||||||
use std::{env, fs};
|
|
||||||
|
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use clap::{ArgEnum, Parser};
|
use clap::{ArgEnum, Parser};
|
||||||
use directories::BaseDirs;
|
use directories::BaseDirs;
|
||||||
use log::debug;
|
use log::debug;
|
||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
|
use std::collections::BTreeMap;
|
||||||
|
use std::fs::write;
|
||||||
|
use std::path::PathBuf;
|
||||||
|
use std::process::Command;
|
||||||
|
use std::{env, fs};
|
||||||
use strum::{EnumIter, EnumString, EnumVariantNames, IntoEnumIterator};
|
use strum::{EnumIter, EnumString, EnumVariantNames, IntoEnumIterator};
|
||||||
use sys_info::hostname;
|
use sys_info::hostname;
|
||||||
use which_crate::which;
|
use which_crate::which;
|
||||||
@@ -626,8 +626,16 @@ impl Config {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Extra Tmux arguments
|
/// Extra Tmux arguments
|
||||||
pub fn tmux_arguments(&self) -> &Option<String> {
|
pub fn tmux_arguments(&self) -> anyhow::Result<Vec<String>> {
|
||||||
&self.config_file.tmux_arguments
|
let args = &self.config_file.tmux_arguments.as_deref().unwrap_or_default();
|
||||||
|
shell_words::split(args)
|
||||||
|
// The only time the parse failed is in case of a missing close quote.
|
||||||
|
// The error message looks like this:
|
||||||
|
// Error: Failed to parse `tmux_arguments`: `'foo`
|
||||||
|
//
|
||||||
|
// Caused by:
|
||||||
|
// missing closing quote
|
||||||
|
.with_context(|| format!("Failed to parse `tmux_arguments`: `{args}`"))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Prompt for a key before exiting
|
/// Prompt for a key before exiting
|
||||||
|
|||||||
@@ -1,10 +1,7 @@
|
|||||||
use lazy_static::lazy_static;
|
|
||||||
use std::sync::atomic::{AtomicBool, Ordering};
|
use std::sync::atomic::{AtomicBool, Ordering};
|
||||||
|
|
||||||
lazy_static! {
|
|
||||||
/// A global variable telling whether the application has been interrupted.
|
/// A global variable telling whether the application has been interrupted.
|
||||||
static ref INTERRUPTED: AtomicBool = AtomicBool::new(false);
|
static INTERRUPTED: AtomicBool = AtomicBool::new(false);
|
||||||
}
|
|
||||||
|
|
||||||
/// Tells whether the program has been interrupted
|
/// Tells whether the program has been interrupted
|
||||||
pub fn interrupted() -> bool {
|
pub fn interrupted() -> bool {
|
||||||
|
|||||||
@@ -194,11 +194,12 @@ impl DryCommand {
|
|||||||
print!(
|
print!(
|
||||||
"Dry running: {} {}",
|
"Dry running: {} {}",
|
||||||
self.program.to_string_lossy(),
|
self.program.to_string_lossy(),
|
||||||
|
shell_words::join(
|
||||||
self.args
|
self.args
|
||||||
.iter()
|
.iter()
|
||||||
.map(|a| String::from(a.to_string_lossy()))
|
.map(|a| String::from(a.to_string_lossy()))
|
||||||
.collect::<Vec<String>>()
|
.collect::<Vec<String>>()
|
||||||
.join(" ")
|
)
|
||||||
);
|
);
|
||||||
match &self.directory {
|
match &self.directory {
|
||||||
Some(dir) => println!(" in {}", dir.to_string_lossy()),
|
Some(dir) => println!(" in {}", dir.to_string_lossy()),
|
||||||
|
|||||||
@@ -79,7 +79,7 @@ fn run() -> Result<()> {
|
|||||||
if config.run_in_tmux() && env::var("TOPGRADE_INSIDE_TMUX").is_err() {
|
if config.run_in_tmux() && env::var("TOPGRADE_INSIDE_TMUX").is_err() {
|
||||||
#[cfg(unix)]
|
#[cfg(unix)]
|
||||||
{
|
{
|
||||||
tmux::run_in_tmux(config.tmux_arguments());
|
tmux::run_in_tmux(config.tmux_arguments()?);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -351,6 +351,7 @@ fn run() -> Result<()> {
|
|||||||
runner.execute(Step::Kakoune, "Kakoune", || kakoune::upgrade_kak_plug(&ctx))?;
|
runner.execute(Step::Kakoune, "Kakoune", || kakoune::upgrade_kak_plug(&ctx))?;
|
||||||
runner.execute(Step::Node, "npm", || node::run_npm_upgrade(&ctx))?;
|
runner.execute(Step::Node, "npm", || node::run_npm_upgrade(&ctx))?;
|
||||||
runner.execute(Step::Node, "yarn", || node::run_yarn_upgrade(&ctx))?;
|
runner.execute(Step::Node, "yarn", || node::run_yarn_upgrade(&ctx))?;
|
||||||
|
runner.execute(Step::Node, "pnpm", || node::run_pnpm_upgrade(&ctx))?;
|
||||||
runner.execute(Step::Containers, "Containers", || containers::run_containers(&ctx))?;
|
runner.execute(Step::Containers, "Containers", || containers::run_containers(&ctx))?;
|
||||||
runner.execute(Step::Deno, "deno", || node::deno_upgrade(&ctx))?;
|
runner.execute(Step::Deno, "deno", || node::deno_upgrade(&ctx))?;
|
||||||
runner.execute(Step::Composer, "composer", || generic::run_composer_update(&ctx))?;
|
runner.execute(Step::Composer, "composer", || generic::run_composer_update(&ctx))?;
|
||||||
@@ -523,7 +524,10 @@ fn main() {
|
|||||||
.is_some());
|
.is_some());
|
||||||
|
|
||||||
if !skip_print {
|
if !skip_print {
|
||||||
println!("Error: {}", error);
|
// The `Debug` implementation of `anyhow::Result` prints a multi-line
|
||||||
|
// error message that includes all the 'causes' added with
|
||||||
|
// `.with_context(...)` calls.
|
||||||
|
println!("Error: {:?}", error);
|
||||||
}
|
}
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -87,7 +87,7 @@ impl Emacs {
|
|||||||
|
|
||||||
print_separator("Emacs");
|
print_separator("Emacs");
|
||||||
|
|
||||||
let mut command = ctx.run_type().execute(&emacs);
|
let mut command = ctx.run_type().execute(emacs);
|
||||||
|
|
||||||
command
|
command
|
||||||
.args(["--batch", "--debug-init", "-l"])
|
.args(["--batch", "--debug-init", "-l"])
|
||||||
|
|||||||
@@ -60,12 +60,12 @@ pub fn run_flutter_upgrade(run_type: RunType) -> Result<()> {
|
|||||||
let flutter = utils::require("flutter")?;
|
let flutter = utils::require("flutter")?;
|
||||||
|
|
||||||
print_separator("Flutter");
|
print_separator("Flutter");
|
||||||
run_type.execute(&flutter).arg("upgrade").check_run()
|
run_type.execute(flutter).arg("upgrade").check_run()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn run_go(run_type: RunType) -> Result<()> {
|
pub fn run_go(run_type: RunType) -> Result<()> {
|
||||||
let go = utils::require("go")?;
|
let go = utils::require("go")?;
|
||||||
let go_output = run_type.execute(&go).args(["env", "GOPATH"]).check_output()?;
|
let go_output = run_type.execute(go).args(["env", "GOPATH"]).check_output()?;
|
||||||
let gopath = go_output.trim();
|
let gopath = go_output.trim();
|
||||||
|
|
||||||
let go_global_update = utils::require("go-global-update")
|
let go_global_update = utils::require("go-global-update")
|
||||||
@@ -74,7 +74,7 @@ pub fn run_go(run_type: RunType) -> Result<()> {
|
|||||||
|
|
||||||
print_separator("Go");
|
print_separator("Go");
|
||||||
|
|
||||||
run_type.execute(&go_global_update).check_run()
|
run_type.execute(go_global_update).check_run()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn run_gem(base_dirs: &BaseDirs, run_type: RunType) -> Result<()> {
|
pub fn run_gem(base_dirs: &BaseDirs, run_type: RunType) -> Result<()> {
|
||||||
@@ -83,7 +83,7 @@ pub fn run_gem(base_dirs: &BaseDirs, run_type: RunType) -> Result<()> {
|
|||||||
|
|
||||||
print_separator("RubyGems");
|
print_separator("RubyGems");
|
||||||
|
|
||||||
let mut command = run_type.execute(&gem);
|
let mut command = run_type.execute(gem);
|
||||||
command.arg("update");
|
command.arg("update");
|
||||||
|
|
||||||
if env::var_os("RBENV_SHELL").is_none() {
|
if env::var_os("RBENV_SHELL").is_none() {
|
||||||
@@ -123,7 +123,7 @@ pub fn run_sheldon(ctx: &ExecutionContext) -> Result<()> {
|
|||||||
|
|
||||||
print_separator("Sheldon");
|
print_separator("Sheldon");
|
||||||
|
|
||||||
ctx.run_type().execute(&sheldon).args(["lock", "--update"]).check_run()
|
ctx.run_type().execute(sheldon).args(["lock", "--update"]).check_run()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn run_fossil(run_type: RunType) -> Result<()> {
|
pub fn run_fossil(run_type: RunType) -> Result<()> {
|
||||||
@@ -131,7 +131,7 @@ pub fn run_fossil(run_type: RunType) -> Result<()> {
|
|||||||
|
|
||||||
print_separator("Fossil");
|
print_separator("Fossil");
|
||||||
|
|
||||||
run_type.execute(&fossil).args(["all", "sync"]).check_run()
|
run_type.execute(fossil).args(["all", "sync"]).check_run()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn run_micro(run_type: RunType) -> Result<()> {
|
pub fn run_micro(run_type: RunType) -> Result<()> {
|
||||||
@@ -139,7 +139,7 @@ pub fn run_micro(run_type: RunType) -> Result<()> {
|
|||||||
|
|
||||||
print_separator("micro");
|
print_separator("micro");
|
||||||
|
|
||||||
let stdout = run_type.execute(µ).args(["-plugin", "update"]).string_output()?;
|
let stdout = run_type.execute(micro).args(["-plugin", "update"]).string_output()?;
|
||||||
std::io::stdout().write_all(stdout.as_bytes())?;
|
std::io::stdout().write_all(stdout.as_bytes())?;
|
||||||
|
|
||||||
if stdout.contains("Nothing to install / update") || stdout.contains("One or more plugins installed") {
|
if stdout.contains("Nothing to install / update") || stdout.contains("One or more plugins installed") {
|
||||||
@@ -160,7 +160,7 @@ pub fn run_apm(run_type: RunType) -> Result<()> {
|
|||||||
|
|
||||||
print_separator("Atom Package Manager");
|
print_separator("Atom Package Manager");
|
||||||
|
|
||||||
run_type.execute(&apm).args(["upgrade", "--confirm=false"]).check_run()
|
run_type.execute(apm).args(["upgrade", "--confirm=false"]).check_run()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn run_rustup(base_dirs: &BaseDirs, run_type: RunType) -> Result<()> {
|
pub fn run_rustup(base_dirs: &BaseDirs, run_type: RunType) -> Result<()> {
|
||||||
@@ -190,7 +190,7 @@ pub fn run_krew_upgrade(run_type: RunType) -> Result<()> {
|
|||||||
|
|
||||||
print_separator("Krew");
|
print_separator("Krew");
|
||||||
|
|
||||||
run_type.execute(&krew).args(["upgrade"]).check_run()
|
run_type.execute(krew).args(["upgrade"]).check_run()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn run_gcloud_components_update(run_type: RunType) -> Result<()> {
|
pub fn run_gcloud_components_update(run_type: RunType) -> Result<()> {
|
||||||
@@ -199,7 +199,7 @@ pub fn run_gcloud_components_update(run_type: RunType) -> Result<()> {
|
|||||||
print_separator("gcloud");
|
print_separator("gcloud");
|
||||||
|
|
||||||
run_type
|
run_type
|
||||||
.execute(&gcloud)
|
.execute(gcloud)
|
||||||
.args(["components", "update", "--quiet"])
|
.args(["components", "update", "--quiet"])
|
||||||
.check_run()
|
.check_run()
|
||||||
}
|
}
|
||||||
@@ -209,7 +209,7 @@ pub fn run_jetpack(run_type: RunType) -> Result<()> {
|
|||||||
|
|
||||||
print_separator("Jetpack");
|
print_separator("Jetpack");
|
||||||
|
|
||||||
run_type.execute(&jetpack).args(["global", "update"]).check_run()
|
run_type.execute(jetpack).args(["global", "update"]).check_run()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn run_rtcl(ctx: &ExecutionContext) -> Result<()> {
|
pub fn run_rtcl(ctx: &ExecutionContext) -> Result<()> {
|
||||||
@@ -217,7 +217,7 @@ pub fn run_rtcl(ctx: &ExecutionContext) -> Result<()> {
|
|||||||
|
|
||||||
print_separator("rtcl");
|
print_separator("rtcl");
|
||||||
|
|
||||||
ctx.run_type().execute(&rupdate).check_run()
|
ctx.run_type().execute(rupdate).check_run()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn run_opam_update(ctx: &ExecutionContext) -> Result<()> {
|
pub fn run_opam_update(ctx: &ExecutionContext) -> Result<()> {
|
||||||
@@ -239,14 +239,14 @@ pub fn run_vcpkg_update(run_type: RunType) -> Result<()> {
|
|||||||
let vcpkg = utils::require("vcpkg")?;
|
let vcpkg = utils::require("vcpkg")?;
|
||||||
print_separator("vcpkg");
|
print_separator("vcpkg");
|
||||||
|
|
||||||
run_type.execute(&vcpkg).args(["upgrade", "--no-dry-run"]).check_run()
|
run_type.execute(vcpkg).args(["upgrade", "--no-dry-run"]).check_run()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn run_pipx_update(run_type: RunType) -> Result<()> {
|
pub fn run_pipx_update(run_type: RunType) -> Result<()> {
|
||||||
let pipx = utils::require("pipx")?;
|
let pipx = utils::require("pipx")?;
|
||||||
print_separator("pipx");
|
print_separator("pipx");
|
||||||
|
|
||||||
run_type.execute(&pipx).arg("upgrade-all").check_run()
|
run_type.execute(pipx).arg("upgrade-all").check_run()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn run_conda_update(ctx: &ExecutionContext) -> Result<()> {
|
pub fn run_conda_update(ctx: &ExecutionContext) -> Result<()> {
|
||||||
@@ -264,7 +264,7 @@ pub fn run_conda_update(ctx: &ExecutionContext) -> Result<()> {
|
|||||||
print_separator("Conda");
|
print_separator("Conda");
|
||||||
|
|
||||||
ctx.run_type()
|
ctx.run_type()
|
||||||
.execute(&conda)
|
.execute(conda)
|
||||||
.args(["update", "--all", "-y"])
|
.args(["update", "--all", "-y"])
|
||||||
.check_run()
|
.check_run()
|
||||||
}
|
}
|
||||||
@@ -289,7 +289,7 @@ pub fn run_pip3_update(run_type: RunType) -> Result<()> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn run_stack_update(run_type: RunType) -> Result<()> {
|
pub fn run_stack_update(run_type: RunType) -> Result<()> {
|
||||||
if let Ok(_) = utils::require("ghcup") {
|
if utils::require("ghcup").is_ok() {
|
||||||
// `ghcup` is present and probably(?) being used to install `stack`.
|
// `ghcup` is present and probably(?) being used to install `stack`.
|
||||||
// Don't upgrade `stack`, let `ghcup` handle it. Per `ghcup 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' !!!
|
// !!! Additionally, you should upgrade stack only through ghcup and not use 'stack upgrade' !!!
|
||||||
@@ -299,14 +299,14 @@ pub fn run_stack_update(run_type: RunType) -> Result<()> {
|
|||||||
let stack = utils::require("stack")?;
|
let stack = utils::require("stack")?;
|
||||||
print_separator("stack");
|
print_separator("stack");
|
||||||
|
|
||||||
run_type.execute(&stack).arg("upgrade").check_run()
|
run_type.execute(stack).arg("upgrade").check_run()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn run_ghcup_update(run_type: RunType) -> Result<()> {
|
pub fn run_ghcup_update(run_type: RunType) -> Result<()> {
|
||||||
let ghcup = utils::require("ghcup")?;
|
let ghcup = utils::require("ghcup")?;
|
||||||
print_separator("ghcup");
|
print_separator("ghcup");
|
||||||
|
|
||||||
run_type.execute(&ghcup).arg("upgrade").check_run()
|
run_type.execute(ghcup).arg("upgrade").check_run()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn run_tlmgr_update(ctx: &ExecutionContext) -> Result<()> {
|
pub fn run_tlmgr_update(ctx: &ExecutionContext) -> Result<()> {
|
||||||
@@ -323,7 +323,7 @@ pub fn run_tlmgr_update(ctx: &ExecutionContext) -> Result<()> {
|
|||||||
let tlmgr_directory = {
|
let tlmgr_directory = {
|
||||||
let mut d = PathBuf::from(
|
let mut d = PathBuf::from(
|
||||||
std::str::from_utf8(
|
std::str::from_utf8(
|
||||||
&Command::new(&kpsewhich)
|
&Command::new(kpsewhich)
|
||||||
.arg("-var-value=SELFAUTOPARENT")
|
.arg("-var-value=SELFAUTOPARENT")
|
||||||
.output()?
|
.output()?
|
||||||
.stdout,
|
.stdout,
|
||||||
@@ -360,7 +360,7 @@ pub fn run_chezmoi_update(base_dirs: &BaseDirs, run_type: RunType) -> Result<()>
|
|||||||
|
|
||||||
print_separator("chezmoi");
|
print_separator("chezmoi");
|
||||||
|
|
||||||
run_type.execute(&chezmoi).arg("update").check_run()
|
run_type.execute(chezmoi).arg("update").check_run()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn run_myrepos_update(base_dirs: &BaseDirs, run_type: RunType) -> Result<()> {
|
pub fn run_myrepos_update(base_dirs: &BaseDirs, run_type: RunType) -> Result<()> {
|
||||||
@@ -440,7 +440,7 @@ pub fn run_composer_update(ctx: &ExecutionContext) -> Result<()> {
|
|||||||
|
|
||||||
if stdout.contains("valet") || stderr.contains("valet") {
|
if stdout.contains("valet") || stderr.contains("valet") {
|
||||||
if let Some(valet) = utils::which("valet") {
|
if let Some(valet) = utils::which("valet") {
|
||||||
ctx.run_type().execute(&valet).arg("install").check_run()?;
|
ctx.run_type().execute(valet).arg("install").check_run()?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -485,21 +485,21 @@ pub fn run_raco_update(run_type: RunType) -> Result<()> {
|
|||||||
|
|
||||||
print_separator("Racket Package Manager");
|
print_separator("Racket Package Manager");
|
||||||
|
|
||||||
run_type.execute(&raco).args(["pkg", "update", "--all"]).check_run()
|
run_type.execute(raco).args(["pkg", "update", "--all"]).check_run()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn bin_update(ctx: &ExecutionContext) -> Result<()> {
|
pub fn bin_update(ctx: &ExecutionContext) -> Result<()> {
|
||||||
let bin = utils::require("bin")?;
|
let bin = utils::require("bin")?;
|
||||||
|
|
||||||
print_separator("Bin");
|
print_separator("Bin");
|
||||||
ctx.run_type().execute(&bin).arg("update").check_run()
|
ctx.run_type().execute(bin).arg("update").check_run()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn spicetify_upgrade(ctx: &ExecutionContext) -> Result<()> {
|
pub fn spicetify_upgrade(ctx: &ExecutionContext) -> Result<()> {
|
||||||
let spicetify = utils::require("spicetify")?;
|
let spicetify = utils::require("spicetify")?;
|
||||||
|
|
||||||
print_separator("Spicetify");
|
print_separator("Spicetify");
|
||||||
ctx.run_type().execute(&spicetify).arg("upgrade").check_run()
|
ctx.run_type().execute(spicetify).arg("upgrade").check_run()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn run_ghcli_extensions_upgrade(ctx: &ExecutionContext) -> Result<()> {
|
pub fn run_ghcli_extensions_upgrade(ctx: &ExecutionContext) -> Result<()> {
|
||||||
@@ -523,7 +523,7 @@ pub fn update_julia_packages(ctx: &ExecutionContext) -> Result<()> {
|
|||||||
print_separator("Julia Packages");
|
print_separator("Julia Packages");
|
||||||
|
|
||||||
ctx.run_type()
|
ctx.run_type()
|
||||||
.execute(&julia)
|
.execute(julia)
|
||||||
.args(["-e", "using Pkg; Pkg.update()"])
|
.args(["-e", "using Pkg; Pkg.update()"])
|
||||||
.check_run()
|
.check_run()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ pub fn upgrade_kak_plug(ctx: &ExecutionContext) -> Result<()> {
|
|||||||
|
|
||||||
print_separator("Kakoune");
|
print_separator("Kakoune");
|
||||||
|
|
||||||
let mut command = ctx.run_type().execute(&kak);
|
let mut command = ctx.run_type().execute(kak);
|
||||||
command.args(["-ui", "dummy", "-e", UPGRADE_KAK]);
|
command.args(["-ui", "dummy", "-e", UPGRADE_KAK]);
|
||||||
|
|
||||||
let output = command.output()?;
|
let output = command.output()?;
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
#![allow(unused_imports)]
|
#![allow(unused_imports)]
|
||||||
|
|
||||||
|
use std::fmt::Display;
|
||||||
#[cfg(unix)]
|
#[cfg(unix)]
|
||||||
use std::os::unix::prelude::MetadataExt;
|
use std::os::unix::prelude::MetadataExt;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
@@ -17,24 +18,71 @@ use crate::terminal::print_separator;
|
|||||||
use crate::utils::{require, PathExt};
|
use crate::utils::{require, PathExt};
|
||||||
use crate::{error::SkipStep, execution_context::ExecutionContext};
|
use crate::{error::SkipStep, execution_context::ExecutionContext};
|
||||||
|
|
||||||
|
enum NPMVariant {
|
||||||
|
Npm,
|
||||||
|
Pnpm,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl NPMVariant {
|
||||||
|
const fn long_name(&self) -> &str {
|
||||||
|
match self {
|
||||||
|
NPMVariant::Npm => "Node Package Manager",
|
||||||
|
NPMVariant::Pnpm => "PNPM",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const fn short_name(&self) -> &str {
|
||||||
|
match self {
|
||||||
|
NPMVariant::Npm => "npm",
|
||||||
|
NPMVariant::Pnpm => "pnpm",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const fn is_npm(&self) -> bool {
|
||||||
|
matches!(self, NPMVariant::Npm)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Display for NPMVariant {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
f.write_str(self.short_name())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[allow(clippy::upper_case_acronyms)]
|
#[allow(clippy::upper_case_acronyms)]
|
||||||
struct NPM {
|
struct NPM {
|
||||||
command: PathBuf,
|
command: PathBuf,
|
||||||
|
variant: NPMVariant,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl NPM {
|
impl NPM {
|
||||||
fn new(command: PathBuf) -> Self {
|
fn new(command: PathBuf, variant: NPMVariant) -> Self {
|
||||||
Self { command }
|
Self { command, variant }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Is the “NPM” version larger than 8.11.0?
|
||||||
|
fn is_npm_8(&self) -> bool {
|
||||||
|
let v = self.version();
|
||||||
|
|
||||||
|
self.variant.is_npm() && matches!(v, Ok(v) if v >= Version::new(8, 11, 0))
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get the most suitable “global location” argument
|
||||||
|
/// of this NPM instance.
|
||||||
|
///
|
||||||
|
/// If the “NPM” version is larger than 8.11.0, we use
|
||||||
|
/// `--location=global`; otherwise, use `-g`.
|
||||||
|
fn global_location_arg(&self) -> &str {
|
||||||
|
if self.is_npm_8() {
|
||||||
|
"--location=global"
|
||||||
|
} else {
|
||||||
|
"-g"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(target_os = "linux")]
|
#[cfg(target_os = "linux")]
|
||||||
fn root(&self) -> Result<PathBuf> {
|
fn root(&self) -> Result<PathBuf> {
|
||||||
let version = self.version()?;
|
let args = ["root", self.global_location_arg()];
|
||||||
let args = if version < Version::new(8, 11, 0) {
|
|
||||||
["root", "-g"]
|
|
||||||
} else {
|
|
||||||
["root", "--location=global"]
|
|
||||||
};
|
|
||||||
Command::new(&self.command)
|
Command::new(&self.command)
|
||||||
.args(args)
|
.args(args)
|
||||||
.check_output()
|
.check_output()
|
||||||
@@ -50,13 +98,8 @@ impl NPM {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn upgrade(&self, run_type: RunType, use_sudo: bool) -> Result<()> {
|
fn upgrade(&self, run_type: RunType, use_sudo: bool) -> Result<()> {
|
||||||
print_separator("Node Package Manager");
|
print_separator(self.variant.long_name());
|
||||||
let version = self.version()?;
|
let args = ["update", self.global_location_arg()];
|
||||||
let args = if version < Version::new(8, 11, 0) {
|
|
||||||
["update", "-g"]
|
|
||||||
} else {
|
|
||||||
["update", "--location=global"]
|
|
||||||
};
|
|
||||||
if use_sudo {
|
if use_sudo {
|
||||||
run_type.execute("sudo").args(args).check_run()?;
|
run_type.execute("sudo").args(args).check_run()?;
|
||||||
} else {
|
} else {
|
||||||
@@ -70,7 +113,7 @@ impl NPM {
|
|||||||
pub fn should_use_sudo(&self) -> Result<bool> {
|
pub fn should_use_sudo(&self) -> Result<bool> {
|
||||||
let npm_root = self.root()?;
|
let npm_root = self.root()?;
|
||||||
if !npm_root.exists() {
|
if !npm_root.exists() {
|
||||||
return Err(SkipStep(format!("NPM root at {} doesn't exist", npm_root.display(),)).into());
|
return Err(SkipStep(format!("{} root at {} doesn't exist", self.variant, npm_root.display())).into());
|
||||||
}
|
}
|
||||||
|
|
||||||
let metadata = std::fs::metadata(&npm_root)?;
|
let metadata = std::fs::metadata(&npm_root)?;
|
||||||
@@ -93,6 +136,17 @@ impl Yarn {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn has_global_subcmd(&self) -> bool {
|
||||||
|
// Get the version of Yarn. After Yarn 2.x (berry),
|
||||||
|
// “yarn global” has been replaced with “yarn dlx”.
|
||||||
|
//
|
||||||
|
// As “yarn dlx” don't need to “upgrade”, we
|
||||||
|
// ignore the whole task if Yarn is 2.x or above.
|
||||||
|
let version = Command::new(&self.command).args(["--version"]).check_output();
|
||||||
|
|
||||||
|
matches!(version, Ok(ver) if ver.starts_with('1') || ver.starts_with('0'))
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(target_os = "linux")]
|
#[cfg(target_os = "linux")]
|
||||||
fn root(&self) -> Result<PathBuf> {
|
fn root(&self) -> Result<PathBuf> {
|
||||||
let args = ["global", "dir"];
|
let args = ["global", "dir"];
|
||||||
@@ -123,7 +177,7 @@ impl Yarn {
|
|||||||
pub fn should_use_sudo(&self) -> Result<bool> {
|
pub fn should_use_sudo(&self) -> Result<bool> {
|
||||||
let yarn_root = self.root()?;
|
let yarn_root = self.root()?;
|
||||||
if !yarn_root.exists() {
|
if !yarn_root.exists() {
|
||||||
return Err(SkipStep(format!("NPM root at {} doesn't exist", yarn_root.display(),)).into());
|
return Err(SkipStep(format!("Yarn root at {} doesn't exist", yarn_root.display(),)).into());
|
||||||
}
|
}
|
||||||
|
|
||||||
let metadata = std::fs::metadata(&yarn_root)?;
|
let metadata = std::fs::metadata(&yarn_root)?;
|
||||||
@@ -162,7 +216,7 @@ fn should_use_sudo_yarn(yarn: &Yarn, ctx: &ExecutionContext) -> Result<bool> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn run_npm_upgrade(ctx: &ExecutionContext) -> Result<()> {
|
pub fn run_npm_upgrade(ctx: &ExecutionContext) -> Result<()> {
|
||||||
let npm = require("pnpm").or_else(|_| require("npm")).map(NPM::new)?;
|
let npm = require("npm").map(|b| NPM::new(b, NPMVariant::Npm))?;
|
||||||
|
|
||||||
#[cfg(target_os = "linux")]
|
#[cfg(target_os = "linux")]
|
||||||
{
|
{
|
||||||
@@ -175,9 +229,28 @@ pub fn run_npm_upgrade(ctx: &ExecutionContext) -> Result<()> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn run_pnpm_upgrade(ctx: &ExecutionContext) -> Result<()> {
|
||||||
|
let pnpm = require("pnpm").map(|b| NPM::new(b, NPMVariant::Pnpm))?;
|
||||||
|
|
||||||
|
#[cfg(target_os = "linux")]
|
||||||
|
{
|
||||||
|
pnpm.upgrade(ctx.run_type(), should_use_sudo(&pnpm, ctx)?)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(target_os = "linux"))]
|
||||||
|
{
|
||||||
|
pnpm.upgrade(ctx.run_type(), false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn run_yarn_upgrade(ctx: &ExecutionContext) -> Result<()> {
|
pub fn run_yarn_upgrade(ctx: &ExecutionContext) -> Result<()> {
|
||||||
let yarn = require("yarn").map(Yarn::new)?;
|
let yarn = require("yarn").map(Yarn::new)?;
|
||||||
|
|
||||||
|
if !yarn.has_global_subcmd() {
|
||||||
|
debug!("Yarn is 2.x or above, skipping global upgrade");
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(target_os = "linux")]
|
#[cfg(target_os = "linux")]
|
||||||
{
|
{
|
||||||
yarn.upgrade(ctx.run_type(), should_use_sudo_yarn(&yarn, ctx)?)
|
yarn.upgrade(ctx.run_type(), should_use_sudo_yarn(&yarn, ctx)?)
|
||||||
|
|||||||
@@ -11,15 +11,15 @@ pub fn run_macports(ctx: &ExecutionContext) -> Result<()> {
|
|||||||
require("port")?;
|
require("port")?;
|
||||||
let sudo = ctx.sudo().as_ref().unwrap();
|
let sudo = ctx.sudo().as_ref().unwrap();
|
||||||
print_separator("MacPorts");
|
print_separator("MacPorts");
|
||||||
ctx.run_type().execute(sudo).args(&["port", "selfupdate"]).check_run()?;
|
ctx.run_type().execute(sudo).args(["port", "selfupdate"]).check_run()?;
|
||||||
ctx.run_type()
|
ctx.run_type()
|
||||||
.execute(sudo)
|
.execute(sudo)
|
||||||
.args(&["port", "-u", "upgrade", "outdated"])
|
.args(["port", "-u", "upgrade", "outdated"])
|
||||||
.check_run()?;
|
.check_run()?;
|
||||||
if ctx.config().cleanup() {
|
if ctx.config().cleanup() {
|
||||||
ctx.run_type()
|
ctx.run_type()
|
||||||
.execute(sudo)
|
.execute(sudo)
|
||||||
.args(&["port", "-N", "reclaim"])
|
.args(["port", "-N", "reclaim"])
|
||||||
.check_run()?;
|
.check_run()?;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -52,7 +52,7 @@ pub fn upgrade_macos(ctx: &ExecutionContext) -> Result<()> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let mut command = ctx.run_type().execute("softwareupdate");
|
let mut command = ctx.run_type().execute("softwareupdate");
|
||||||
command.args(&["--install", "--all"]);
|
command.args(["--install", "--all"]);
|
||||||
|
|
||||||
if should_ask {
|
if should_ask {
|
||||||
command.arg("--no-scan");
|
command.arg("--no-scan");
|
||||||
@@ -81,12 +81,12 @@ pub fn run_sparkle(ctx: &ExecutionContext) -> Result<()> {
|
|||||||
|
|
||||||
for application in (fs::read_dir("/Applications")?).flatten() {
|
for application in (fs::read_dir("/Applications")?).flatten() {
|
||||||
let probe = Command::new(&sparkle)
|
let probe = Command::new(&sparkle)
|
||||||
.args(&["--probe", "--application"])
|
.args(["--probe", "--application"])
|
||||||
.arg(application.path())
|
.arg(application.path())
|
||||||
.check_output();
|
.check_output();
|
||||||
if probe.is_ok() {
|
if probe.is_ok() {
|
||||||
let mut command = ctx.run_type().execute(&sparkle);
|
let mut command = ctx.run_type().execute(&sparkle);
|
||||||
command.args(&["bundle", "--check-immediately", "--application"]);
|
command.args(["bundle", "--check-immediately", "--application"]);
|
||||||
command.arg(application.path());
|
command.arg(application.path());
|
||||||
command.spawn()?.wait()?;
|
command.spawn()?.wait()?;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
PRETTY_NAME="Debian GNU/Linux 8 (jessie)"
|
PRETTY_NAME="Debian GNU/Linux 11 (bullseye)"
|
||||||
NAME="Debian GNU/Linux"
|
NAME="Debian GNU/Linux"
|
||||||
VERSION_ID="8"
|
VERSION_ID="11"
|
||||||
VERSION="8 (jessie)"
|
VERSION="11 (bullseye)"
|
||||||
|
VERSION_CODENAME=bullseye
|
||||||
ID=debian
|
ID=debian
|
||||||
HOME_URL="http://www.debian.org/"
|
HOME_URL="https://www.debian.org/"
|
||||||
SUPPORT_URL="http://www.debian.org/support"
|
SUPPORT_URL="https://www.debian.org/support"
|
||||||
BUG_REPORT_URL="https://bugs.debian.org/"
|
BUG_REPORT_URL="https://bugs.debian.org/"
|
||||||
|
|||||||
@@ -124,7 +124,7 @@ pub fn run_oh_my_fish(ctx: &ExecutionContext) -> Result<()> {
|
|||||||
|
|
||||||
print_separator("oh-my-fish");
|
print_separator("oh-my-fish");
|
||||||
|
|
||||||
ctx.run_type().execute(&fish).args(["-c", "omf update"]).check_run()
|
ctx.run_type().execute(fish).args(["-c", "omf update"]).check_run()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn run_pkgin(ctx: &ExecutionContext) -> Result<()> {
|
pub fn run_pkgin(ctx: &ExecutionContext) -> Result<()> {
|
||||||
@@ -154,7 +154,7 @@ pub fn run_fish_plug(ctx: &ExecutionContext) -> Result<()> {
|
|||||||
|
|
||||||
print_separator("fish-plug");
|
print_separator("fish-plug");
|
||||||
|
|
||||||
ctx.run_type().execute(&fish).args(["-c", "plug update"]).check_run()
|
ctx.run_type().execute(fish).args(["-c", "plug update"]).check_run()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Upgrades `fundle` and `fundle` plugins.
|
/// Upgrades `fundle` and `fundle` plugins.
|
||||||
@@ -258,19 +258,19 @@ pub fn run_brew_cask(ctx: &ExecutionContext, variant: BrewVariant) -> Result<()>
|
|||||||
|
|
||||||
let cask_upgrade_exists = variant
|
let cask_upgrade_exists = variant
|
||||||
.execute(RunType::Wet)
|
.execute(RunType::Wet)
|
||||||
.args(&["--repository", "buo/cask-upgrade"])
|
.args(["--repository", "buo/cask-upgrade"])
|
||||||
.check_output()
|
.check_output()
|
||||||
.map(|p| Path::new(p.trim()).exists())?;
|
.map(|p| Path::new(p.trim()).exists())?;
|
||||||
|
|
||||||
let mut brew_args = vec![];
|
let mut brew_args = vec![];
|
||||||
|
|
||||||
if cask_upgrade_exists {
|
if cask_upgrade_exists {
|
||||||
brew_args.extend(&["cu", "-y"]);
|
brew_args.extend(["cu", "-y"]);
|
||||||
if ctx.config().brew_cask_greedy() {
|
if ctx.config().brew_cask_greedy() {
|
||||||
brew_args.push("-a");
|
brew_args.push("-a");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
brew_args.extend(&["upgrade", "--cask"]);
|
brew_args.extend(["upgrade", "--cask"]);
|
||||||
if ctx.config().brew_cask_greedy() {
|
if ctx.config().brew_cask_greedy() {
|
||||||
brew_args.push("--greedy");
|
brew_args.push("--greedy");
|
||||||
}
|
}
|
||||||
@@ -352,7 +352,7 @@ pub fn run_nix(ctx: &ExecutionContext) -> Result<()> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
run_type.execute(&nix_channel).arg("--update").check_run()?;
|
run_type.execute(nix_channel).arg("--update").check_run()?;
|
||||||
|
|
||||||
if std::path::Path::new(&manifest_json_path).exists() {
|
if std::path::Path::new(&manifest_json_path).exists() {
|
||||||
run_type
|
run_type
|
||||||
@@ -371,7 +371,7 @@ pub fn run_yadm(ctx: &ExecutionContext) -> Result<()> {
|
|||||||
|
|
||||||
print_separator("yadm");
|
print_separator("yadm");
|
||||||
|
|
||||||
ctx.run_type().execute(&yadm).arg("pull").check_run()
|
ctx.run_type().execute(yadm).arg("pull").check_run()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn run_asdf(run_type: RunType) -> Result<()> {
|
pub fn run_asdf(run_type: RunType) -> Result<()> {
|
||||||
@@ -392,21 +392,21 @@ pub fn run_home_manager(run_type: RunType) -> Result<()> {
|
|||||||
let home_manager = require("home-manager")?;
|
let home_manager = require("home-manager")?;
|
||||||
|
|
||||||
print_separator("home-manager");
|
print_separator("home-manager");
|
||||||
run_type.execute(&home_manager).arg("switch").check_run()
|
run_type.execute(home_manager).arg("switch").check_run()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn run_tldr(run_type: RunType) -> Result<()> {
|
pub fn run_tldr(run_type: RunType) -> Result<()> {
|
||||||
let tldr = require("tldr")?;
|
let tldr = require("tldr")?;
|
||||||
|
|
||||||
print_separator("TLDR");
|
print_separator("TLDR");
|
||||||
run_type.execute(&tldr).arg("--update").check_run()
|
run_type.execute(tldr).arg("--update").check_run()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn run_pearl(run_type: RunType) -> Result<()> {
|
pub fn run_pearl(run_type: RunType) -> Result<()> {
|
||||||
let pearl = require("pearl")?;
|
let pearl = require("pearl")?;
|
||||||
print_separator("pearl");
|
print_separator("pearl");
|
||||||
|
|
||||||
run_type.execute(&pearl).arg("update").check_run()
|
run_type.execute(pearl).arg("update").check_run()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn run_sdkman(base_dirs: &BaseDirs, cleanup: bool, run_type: RunType) -> Result<()> {
|
pub fn run_sdkman(base_dirs: &BaseDirs, cleanup: bool, run_type: RunType) -> Result<()> {
|
||||||
@@ -471,7 +471,7 @@ pub fn run_bun(ctx: &ExecutionContext) -> Result<()> {
|
|||||||
|
|
||||||
print_separator("Bun");
|
print_separator("Bun");
|
||||||
|
|
||||||
ctx.run_type().execute(&bun).arg("upgrade").check_run()
|
ctx.run_type().execute(bun).arg("upgrade").check_run()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Update dotfiles with `rcm(7)`.
|
/// Update dotfiles with `rcm(7)`.
|
||||||
|
|||||||
@@ -79,6 +79,7 @@ impl Powershell {
|
|||||||
println!("Updating modules...");
|
println!("Updating modules...");
|
||||||
ctx.run_type()
|
ctx.run_type()
|
||||||
.execute(powershell)
|
.execute(powershell)
|
||||||
|
// This probably doesn't need `shell_words::join`.
|
||||||
.args(["-NoProfile", "-Command", &cmd.join(" ")])
|
.args(["-NoProfile", "-Command", &cmd.join(" ")])
|
||||||
.check_run()
|
.check_run()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ pub fn ssh_step(ctx: &ExecutionContext, hostname: &str) -> Result<()> {
|
|||||||
#[cfg(unix)]
|
#[cfg(unix)]
|
||||||
{
|
{
|
||||||
prepare_async_ssh_command(&mut args);
|
prepare_async_ssh_command(&mut args);
|
||||||
crate::tmux::run_command(ctx, &args.join(" "))?;
|
crate::tmux::run_command(ctx, &shell_words::join(args))?;
|
||||||
Err(SkipStep(String::from("Remote Topgrade launched in Tmux")).into())
|
Err(SkipStep(String::from("Remote Topgrade launched in Tmux")).into())
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -47,6 +47,6 @@ pub fn ssh_step(ctx: &ExecutionContext, hostname: &str) -> Result<()> {
|
|||||||
print_separator(format!("Remote ({})", hostname));
|
print_separator(format!("Remote ({})", hostname));
|
||||||
println!("Connecting to {}...", hostname);
|
println!("Connecting to {}...", hostname);
|
||||||
|
|
||||||
ctx.run_type().execute(&ssh).args(&args).check_run()
|
ctx.run_type().execute(ssh).args(&args).check_run()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ pub fn run_tpm(base_dirs: &BaseDirs, run_type: RunType) -> Result<()> {
|
|||||||
|
|
||||||
print_separator("tmux plugins");
|
print_separator("tmux plugins");
|
||||||
|
|
||||||
run_type.execute(&tpm).arg("all").check_run()
|
run_type.execute(tpm).arg("all").check_run()
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Tmux {
|
struct Tmux {
|
||||||
@@ -29,12 +29,10 @@ struct Tmux {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Tmux {
|
impl Tmux {
|
||||||
fn new(args: &Option<String>) -> Self {
|
fn new(args: Vec<String>) -> Self {
|
||||||
Self {
|
Self {
|
||||||
tmux: which("tmux").expect("Could not find tmux"),
|
tmux: which("tmux").expect("Could not find tmux"),
|
||||||
args: args
|
args: if args.is_empty() { None } else { Some(args) },
|
||||||
.as_ref()
|
|
||||||
.map(|args| args.split_whitespace().map(String::from).collect()),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -75,7 +73,7 @@ impl Tmux {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn run_in_tmux(args: &Option<String>) -> ! {
|
pub fn run_in_tmux(args: Vec<String>) -> ! {
|
||||||
let command = {
|
let command = {
|
||||||
let mut command = vec![
|
let mut command = vec![
|
||||||
String::from("env"),
|
String::from("env"),
|
||||||
@@ -83,10 +81,10 @@ pub fn run_in_tmux(args: &Option<String>) -> ! {
|
|||||||
String::from("TOPGRADE_INSIDE_TMUX=1"),
|
String::from("TOPGRADE_INSIDE_TMUX=1"),
|
||||||
];
|
];
|
||||||
command.extend(env::args());
|
command.extend(env::args());
|
||||||
command.join(" ")
|
shell_words::join(command)
|
||||||
};
|
};
|
||||||
|
|
||||||
let tmux = Tmux::new(args);
|
let tmux = Tmux::new(args.clone());
|
||||||
|
|
||||||
if !tmux.has_session("topgrade").expect("Error detecting a tmux session") {
|
if !tmux.has_session("topgrade").expect("Error detecting a tmux session") {
|
||||||
tmux.new_session("topgrade").expect("Error creating a tmux session");
|
tmux.new_session("topgrade").expect("Error creating a tmux session");
|
||||||
@@ -108,7 +106,7 @@ pub fn run_in_tmux(args: &Option<String>) -> ! {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn run_command(ctx: &ExecutionContext, command: &str) -> Result<()> {
|
pub fn run_command(ctx: &ExecutionContext, command: &str) -> Result<()> {
|
||||||
Tmux::new(ctx.config().tmux_arguments())
|
Tmux::new(ctx.config().tmux_arguments()?)
|
||||||
.build()
|
.build()
|
||||||
.args(["new-window", "-a", "-t", "topgrade:1", command])
|
.args(["new-window", "-a", "-t", "topgrade:1", command])
|
||||||
.env_remove("TMUX")
|
.env_remove("TMUX")
|
||||||
|
|||||||
@@ -118,9 +118,9 @@ pub fn upgrade_vim(base_dirs: &BaseDirs, ctx: &ExecutionContext) -> Result<()> {
|
|||||||
upgrade(
|
upgrade(
|
||||||
ctx.run_type()
|
ctx.run_type()
|
||||||
.execute(&vim)
|
.execute(&vim)
|
||||||
.args(&["-u"])
|
.args(["-u"])
|
||||||
.arg(vimrc)
|
.arg(vimrc)
|
||||||
.args(&["-U", "NONE", "-V1", "-nNesS"])
|
.args(["-U", "NONE", "-V1", "-nNesS"])
|
||||||
.arg(upgrade_script()?.path()),
|
.arg(upgrade_script()?.path()),
|
||||||
ctx,
|
ctx,
|
||||||
)
|
)
|
||||||
@@ -133,10 +133,10 @@ pub fn upgrade_neovim(base_dirs: &BaseDirs, ctx: &ExecutionContext) -> Result<()
|
|||||||
print_separator("Neovim");
|
print_separator("Neovim");
|
||||||
upgrade(
|
upgrade(
|
||||||
ctx.run_type()
|
ctx.run_type()
|
||||||
.execute(&nvim)
|
.execute(nvim)
|
||||||
.args(&["-u"])
|
.args(["-u"])
|
||||||
.arg(nvimrc)
|
.arg(nvimrc)
|
||||||
.args(&["--headless", "-V1", "-nS"])
|
.args(["--headless", "-V1", "-nS"])
|
||||||
.arg(upgrade_script()?.path()),
|
.arg(upgrade_script()?.path()),
|
||||||
ctx,
|
ctx,
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -223,7 +223,7 @@ impl Terminal {
|
|||||||
self.term.set_title("Topgrade - Awaiting user");
|
self.term.set_title("Topgrade - Awaiting user");
|
||||||
}
|
}
|
||||||
|
|
||||||
self.notify_desktop(&format!("{} failed", step_name), None);
|
self.notify_desktop(format!("{} failed", step_name), None);
|
||||||
|
|
||||||
self.term
|
self.term
|
||||||
.write_fmt(format_args!(
|
.write_fmt(format_args!(
|
||||||
|
|||||||
Reference in New Issue
Block a user