Compare commits
15 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2861044501 | ||
|
|
b565aa5f71 | ||
|
|
7d3227c5c3 | ||
|
|
ea84fbd9a7 | ||
|
|
347372ca71 | ||
|
|
6000124062 | ||
|
|
9b33a07377 | ||
|
|
785bf11300 | ||
|
|
fb91e0b540 | ||
|
|
30c3fcc4fc | ||
|
|
f274935a0c | ||
|
|
e7eda846a2 | ||
|
|
97c1200b79 | ||
|
|
3797fc7bae | ||
|
|
7b512f1e00 |
34
.github/workflows/crates-publish.yml
vendored
Normal file
34
.github/workflows/crates-publish.yml
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
on:
|
||||
release:
|
||||
types: [published, edited]
|
||||
|
||||
name: Check SemVer compliance and publish on release
|
||||
|
||||
jobs:
|
||||
prepare:
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
toolchain: nightly-2022-08-03
|
||||
override: true
|
||||
|
||||
semver:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions-rs/cargo@v1
|
||||
with:
|
||||
command: install
|
||||
args: --git https://github.com/rust-lang/rust-semverver
|
||||
- run: eval "current_version=$(grep -e '^version = .*$' Cargo.toml | cut -d ' ' -f 3)"
|
||||
- run: cargo semver | tee semver_out
|
||||
- run: (head -n 1 semver_out | grep "\-> $current_version") || (echo "versioning mismatch" && return 1)
|
||||
|
||||
publish:
|
||||
steps:
|
||||
- uses: katyo/publish-crates@v1
|
||||
with:
|
||||
dry-run: true
|
||||
check-repo: ${{ github.event_name == 'push' }}
|
||||
registry-token: ${{ secrets.CARGO_REGISTRY_TOKEN }}
|
||||
ignore-unpublished-changes: true
|
||||
59
.github/workflows/release_win_osx.yml
vendored
Normal file
59
.github/workflows/release_win_osx.yml
vendored
Normal file
@@ -0,0 +1,59 @@
|
||||
name: CD Win/MacOS Native
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
release:
|
||||
types: [ created ]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
platform: [ macos-latest, windows-latest ]
|
||||
runs-on: ${{ matrix.platform }}
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
toolchain: stable
|
||||
profile: minimal
|
||||
override: true
|
||||
components: rustfmt, clippy
|
||||
- uses: actions-rs/cargo@v1.0.1
|
||||
name: Run tests
|
||||
with:
|
||||
command: test
|
||||
- uses: actions-rs/cargo@v1.0.1
|
||||
name: Build
|
||||
with:
|
||||
command: build
|
||||
args: --release --all-features
|
||||
- name: Rename Release (Unix)
|
||||
run: |
|
||||
cargo install default-target
|
||||
mkdir assets
|
||||
FILENAME=topgrade-${{github.event.release.tag_name}}-$(default-target)
|
||||
mv target/release/topgrade assets
|
||||
cd assets
|
||||
tar --format=ustar -czf $FILENAME.tar.gz topgrade
|
||||
rm topgrade
|
||||
ls .
|
||||
if: ${{ matrix.platform != 'windows-latest' }}
|
||||
shell: bash
|
||||
- name: Rename Release (Windows)
|
||||
run: |
|
||||
cargo install default-target
|
||||
mkdir assets
|
||||
FILENAME=topgrade-${{github.event.release.tag_name}}-$(default-target)
|
||||
mv target/release/topgrade.exe assets/topgrade.exe
|
||||
cd assets
|
||||
powershell Compress-Archive -Path * -Destination ${FILENAME}.zip
|
||||
rm topgrade.exe
|
||||
ls .
|
||||
if: ${{ matrix.platform == 'windows-latest' }}
|
||||
shell: bash
|
||||
- name: Release
|
||||
uses: softprops/action-gh-release@v1
|
||||
with:
|
||||
files: assets/*
|
||||
12
Cargo.lock
generated
12
Cargo.lock
generated
@@ -715,6 +715,15 @@ version = "0.4.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70"
|
||||
|
||||
[[package]]
|
||||
name = "home"
|
||||
version = "0.5.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "747309b4b440c06d57b0b25f2aee03ee9b5e5397d288c60e21fc709bb98a7408"
|
||||
dependencies = [
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "http"
|
||||
version = "0.2.8"
|
||||
@@ -1900,7 +1909,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "topgrade-rs"
|
||||
version = "9.1.0"
|
||||
version = "10.0.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"cfg-if",
|
||||
@@ -1910,6 +1919,7 @@ dependencies = [
|
||||
"directories",
|
||||
"futures",
|
||||
"glob",
|
||||
"home",
|
||||
"lazy_static",
|
||||
"log",
|
||||
"nix 0.24.2",
|
||||
|
||||
@@ -8,7 +8,7 @@ repository = "https://github.com/topgrade-rs/topgrade"
|
||||
version = "10.0.0"
|
||||
authors = ["Roey Darwish Dror <roey.ghost@gmail.com>", "Thomas Schönauer <t.schoenauer@hgs-wt.at>"]
|
||||
exclude = ["doc/screenshot.gif"]
|
||||
edition = "2018"
|
||||
edition = "2021"
|
||||
|
||||
readme = "README.md"
|
||||
|
||||
@@ -17,6 +17,7 @@ name = "topgrade"
|
||||
path = "src/main.rs"
|
||||
|
||||
[dependencies]
|
||||
home = "0.5"
|
||||
directories = "4.0"
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
toml = "0.5"
|
||||
|
||||
@@ -50,7 +50,7 @@ Open a new Issue describing your problem and if possible with a possible solutio
|
||||
Just let us now what you are missing by opening an issue.
|
||||
For tools please open an Issue describing the tool, which platforms it supports and if possible, give us an example of its usage.
|
||||
### Want to contribute to the code?
|
||||
Just fork the repository and start coding. Please let PRs with bug fixes target the staging branch and PRs with new features target the dev branch.
|
||||
Just fork the repository and start coding.
|
||||
|
||||
## Remote execution
|
||||
You can specify a key called `remote_topgrades` in the configuration file.
|
||||
|
||||
61
build-all.sh
61
build-all.sh
@@ -4,22 +4,70 @@ build_function() {
|
||||
cargo install cross
|
||||
|
||||
|
||||
echo -n "Building x86_64-linux-gnu"
|
||||
cross build --release --target x86_64-unknown-linux-gnu
|
||||
echo -n "Building x86_64-linux-musl"
|
||||
cross build --release --target x86_64-unknown-linux-musl
|
||||
echo -n "Building x86_64-freebsd"
|
||||
cross build --release --target x86_64-unknown-freebsd
|
||||
echo -n "Building aarch64-linux-gnu"
|
||||
cross build --release --target aarch64-unknown-linux-gnu
|
||||
echo -n "Building aarch64-linux-musl"
|
||||
cross build --release --target aarch64-unknown-linux-musl
|
||||
echo -n "Building x86_64-windows-gnu"
|
||||
cross build --release --target x86_64-pc-windows-gnu
|
||||
}
|
||||
|
||||
package_function() {
|
||||
tar -czvf build/topgrade-${ans}-x86_64-linux-gnu.tar.gz target/x86_64-unknown-linux-gnu/release/topgrade
|
||||
tar -czvf build/topgrade-${ans}-x86_64-linux-musl.tar.gz target/x86_64-unknown-linux-musl/release/topgrade
|
||||
tar -czvf build/topgrade-${ans}-x86_64-freebsd.tar.gz target/x86_64-unknown-freebsd/release/topgrade
|
||||
tar -czvf build/topgrade-${ans}-aarch64-linux-gnu.tar.gz target/aarch64-unknown-linux-gnu/release/topgrade
|
||||
tar -czvf build/topgrade-${ans}-aarch64-linux-musl.tar.gz target/aarch64-unknown-linux-musl/release/topgrade
|
||||
tar -czvf build/topgrade-${ans}-x86_64-windows.tar.gz target/x86_64-pc-windows-gnu/release/topgrade.exe
|
||||
|
||||
cd build
|
||||
mkdir x86_64-unknown-linux-gnu/
|
||||
mkdir x86_64-unknown-linux-musl/
|
||||
mkdir x86_64-unknown-freebsd/
|
||||
mkdir x86_64-pc-windows-gnu/
|
||||
mkdir aarch64-unknown-linux-gnu/
|
||||
mkdir aarch64-unknown-linux-musl/
|
||||
|
||||
cp ../target/x86_64-unknown-linux-gnu/release/topgrade x86_64-unknown-linux-gnu/
|
||||
cp ../target/x86_64-unknown-linux-musl/release/topgrade x86_64-unknown-linux-musl/
|
||||
cp ../target/x86_64-unknown-freebsd/release/topgrade x86_64-unknown-freebsd/topgrade
|
||||
cp ../target/aarch64-unknown-linux-gnu/release/topgrade aarch64-unknown-linux-gnu/topgrade
|
||||
cp ../target/aarch64-unknown-linux-musl/release/topgrade aarch64-unknown-linux-musl/topgrade
|
||||
cp ../target/x86_64-pc-windows-gnu/release/topgrade.exe x86_64-pc-windows-gnu/topgrade.exe
|
||||
|
||||
cd x86_64-unknown-linux-gnu/
|
||||
tar -czf ../topgrade-${ans}-x86_64-linux-gnu.tar.gz topgrade
|
||||
cd ..
|
||||
|
||||
cd x86_64-unknown-linux-musl
|
||||
tar -czf ../topgrade-${ans}-x86_64-linux-musl.tar.gz topgrade
|
||||
cd ..
|
||||
|
||||
cd x86_64-unknown-freebsd/
|
||||
tar -czf ../topgrade-${ans}-x86_64-freebsd.tar.gz topgrade
|
||||
cd ..
|
||||
|
||||
cd aarch64-unknown-linux-gnu/
|
||||
tar -czf ../topgrade-${ans}-aarch64-linux-gnu.tar.gz topgrade
|
||||
cd ..
|
||||
|
||||
cd aarch64-unknown-linux-musl/
|
||||
tar -czf ../topgrade-${ans}-aarch64-linux-musl.tar.gz topgrade
|
||||
cd ..
|
||||
|
||||
cd x86_64-pc-windows-gnu/
|
||||
zip -q ../topgrade-${ans}-x86_64-windows.zip topgrade.exe
|
||||
cd ..
|
||||
cd ..
|
||||
|
||||
}
|
||||
|
||||
print_checksums() {
|
||||
|
||||
|
||||
cd build/
|
||||
sha256sum topgrade-${ans}-*
|
||||
cd ../
|
||||
}
|
||||
|
||||
while true; do
|
||||
@@ -34,6 +82,7 @@ mkdir build
|
||||
case $yn in
|
||||
y ) build_function
|
||||
package_function
|
||||
print_checksums
|
||||
break;;
|
||||
n ) echo exiting...;
|
||||
exit;;
|
||||
|
||||
@@ -70,10 +70,12 @@
|
||||
#autoremove = true
|
||||
|
||||
[linux]
|
||||
# Arch Package Manager to use. Allowed values: autodetect, trizen, paru, yay, pikaur, pacman, pamac.
|
||||
# Arch Package Manager to use. Allowed values: autodetect, trizen, aura, paru, yay, pikaur, pacman, pamac.
|
||||
#arch_package_manager = "pacman"
|
||||
# Arguments to pass yay (or paru) when updating packages
|
||||
#yay_arguments = "--nodevel"
|
||||
#aura_aur_arguments = "-kx"
|
||||
#aura_pacman_arguments = ""
|
||||
#show_arch_news = true
|
||||
#trizen_arguments = "--devel"
|
||||
#pikaur_arguments = ""
|
||||
|
||||
@@ -216,12 +216,15 @@ pub enum ArchPackageManager {
|
||||
Pacman,
|
||||
Pikaur,
|
||||
Pamac,
|
||||
Aura,
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Default, Debug)]
|
||||
#[serde(deny_unknown_fields)]
|
||||
pub struct Linux {
|
||||
yay_arguments: Option<String>,
|
||||
aura_aur_arguments: Option<String>,
|
||||
aura_pacman_arguments: Option<String>,
|
||||
arch_package_manager: Option<ArchPackageManager>,
|
||||
show_arch_news: Option<bool>,
|
||||
trizen_arguments: Option<String>,
|
||||
@@ -268,6 +271,8 @@ pub struct ConfigFile {
|
||||
display_time: Option<bool>,
|
||||
assume_yes: Option<bool>,
|
||||
yay_arguments: Option<String>,
|
||||
aura_aur_arguments: Option<String>,
|
||||
aura_pacman_arguments: Option<String>,
|
||||
no_retry: Option<bool>,
|
||||
run_in_tmux: Option<bool>,
|
||||
cleanup: Option<bool>,
|
||||
@@ -764,9 +769,27 @@ impl Config {
|
||||
|
||||
/// Extra yay arguments
|
||||
pub fn yay_arguments(&self) -> &str {
|
||||
get_deprecated!(self.config_file, yay_arguments, linux, yay_arguments)
|
||||
.as_deref()
|
||||
.unwrap_or("--devel")
|
||||
self.config_file
|
||||
.linux
|
||||
.as_ref()
|
||||
.and_then(|s| s.yay_arguments.as_deref())
|
||||
.unwrap_or("")
|
||||
}
|
||||
|
||||
/// Extra aura arguments for AUR and pacman
|
||||
pub fn aura_aur_arguments(&self) -> &str {
|
||||
self.config_file
|
||||
.linux
|
||||
.as_ref()
|
||||
.and_then(|s| s.aura_aur_arguments.as_deref())
|
||||
.unwrap_or("")
|
||||
}
|
||||
pub fn aura_pacman_arguments(&self) -> &str {
|
||||
self.config_file
|
||||
.linux
|
||||
.as_ref()
|
||||
.and_then(|s| s.aura_pacman_arguments.as_deref())
|
||||
.unwrap_or("")
|
||||
}
|
||||
|
||||
/// Extra apt arguments
|
||||
|
||||
@@ -140,7 +140,7 @@ fn run() -> Result<()> {
|
||||
#[cfg(target_os = "linux")]
|
||||
let distribution = linux::Distribution::detect();
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
#[cfg(target_os = r#"linux"#)]
|
||||
{
|
||||
match &distribution {
|
||||
Ok(distribution) => {
|
||||
|
||||
@@ -23,7 +23,7 @@ fn list_containers(crt: &Path) -> Result<Vec<String>> {
|
||||
crt.display()
|
||||
);
|
||||
let output = Command::new(crt)
|
||||
.args(&["image", "ls", "--format", "{{.Repository}}:{{.Tag}}"])
|
||||
.args(["image", "ls", "--format", "{{.Repository}}:{{.Tag}}"])
|
||||
.output()?;
|
||||
let output_str = String::from_utf8(output.stdout)?;
|
||||
|
||||
@@ -95,7 +95,7 @@ pub fn run_containers(ctx: &ExecutionContext) -> Result<()> {
|
||||
if ctx.config().cleanup() {
|
||||
// Remove dangling images
|
||||
debug!("Removing dangling images");
|
||||
if let Err(e) = ctx.run_type().execute(&crt).args(&["image", "prune", "-f"]).check_run() {
|
||||
if let Err(e) = ctx.run_type().execute(&crt).args(["image", "prune", "-f"]).check_run() {
|
||||
error!("Removing dangling images failed: {}", e);
|
||||
success = false;
|
||||
}
|
||||
|
||||
@@ -71,7 +71,7 @@ impl Emacs {
|
||||
command.arg("--force");
|
||||
}
|
||||
|
||||
command.args(&["upgrade"]);
|
||||
command.args(["upgrade"]);
|
||||
|
||||
command.check_run()
|
||||
}
|
||||
@@ -90,7 +90,7 @@ impl Emacs {
|
||||
let mut command = ctx.run_type().execute(&emacs);
|
||||
|
||||
command
|
||||
.args(&["--batch", "--debug-init", "-l"])
|
||||
.args(["--batch", "--debug-init", "-l"])
|
||||
.arg(init_file)
|
||||
.arg("--eval");
|
||||
|
||||
|
||||
@@ -52,7 +52,7 @@ pub fn run_cargo_update(ctx: &ExecutionContext) -> Result<()> {
|
||||
|
||||
ctx.run_type()
|
||||
.execute(cargo_update)
|
||||
.args(&["install-update", "--git", "--all"])
|
||||
.args(["install-update", "--git", "--all"])
|
||||
.check_run()
|
||||
}
|
||||
|
||||
@@ -65,7 +65,7 @@ pub fn run_flutter_upgrade(run_type: RunType) -> Result<()> {
|
||||
|
||||
pub fn run_go(run_type: RunType) -> Result<()> {
|
||||
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 go_global_update = utils::require("go-global-update")
|
||||
@@ -123,7 +123,7 @@ pub fn run_sheldon(ctx: &ExecutionContext) -> Result<()> {
|
||||
|
||||
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<()> {
|
||||
@@ -131,7 +131,7 @@ pub fn run_fossil(run_type: RunType) -> Result<()> {
|
||||
|
||||
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<()> {
|
||||
@@ -139,7 +139,7 @@ pub fn run_micro(run_type: RunType) -> Result<()> {
|
||||
|
||||
print_separator("micro");
|
||||
|
||||
let stdout = run_type.execute(µ).args(&["-plugin", "update"]).string_output()?;
|
||||
let stdout = run_type.execute(µ).args(["-plugin", "update"]).string_output()?;
|
||||
std::io::stdout().write_all(stdout.as_bytes())?;
|
||||
|
||||
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");
|
||||
|
||||
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<()> {
|
||||
@@ -169,7 +169,7 @@ pub fn run_rustup(base_dirs: &BaseDirs, run_type: RunType) -> Result<()> {
|
||||
print_separator("rustup");
|
||||
|
||||
if rustup.canonicalize()?.is_descendant_of(base_dirs.home_dir()) {
|
||||
run_type.execute(&rustup).args(&["self", "update"]).check_run()?;
|
||||
run_type.execute(&rustup).args(["self", "update"]).check_run()?;
|
||||
}
|
||||
|
||||
run_type.execute(&rustup).arg("update").check_run()
|
||||
@@ -181,8 +181,8 @@ pub fn run_choosenim(ctx: &ExecutionContext) -> Result<()> {
|
||||
print_separator("choosenim");
|
||||
let run_type = ctx.run_type();
|
||||
|
||||
run_type.execute(&choosenim).args(&["update", "self"]).check_run()?;
|
||||
run_type.execute(&choosenim).args(&["update", "stable"]).check_run()
|
||||
run_type.execute(&choosenim).args(["update", "self"]).check_run()?;
|
||||
run_type.execute(&choosenim).args(["update", "stable"]).check_run()
|
||||
}
|
||||
|
||||
pub fn run_krew_upgrade(run_type: RunType) -> Result<()> {
|
||||
@@ -190,7 +190,7 @@ pub fn run_krew_upgrade(run_type: RunType) -> Result<()> {
|
||||
|
||||
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<()> {
|
||||
@@ -200,7 +200,7 @@ pub fn run_gcloud_components_update(run_type: RunType) -> Result<()> {
|
||||
|
||||
run_type
|
||||
.execute(&gcloud)
|
||||
.args(&["components", "update", "--quiet"])
|
||||
.args(["components", "update", "--quiet"])
|
||||
.check_run()
|
||||
}
|
||||
|
||||
@@ -209,7 +209,7 @@ pub fn run_jetpack(run_type: RunType) -> Result<()> {
|
||||
|
||||
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<()> {
|
||||
@@ -239,7 +239,7 @@ pub fn run_vcpkg_update(run_type: RunType) -> Result<()> {
|
||||
let vcpkg = utils::require("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<()> {
|
||||
@@ -253,7 +253,7 @@ pub fn run_conda_update(ctx: &ExecutionContext) -> Result<()> {
|
||||
let conda = utils::require("conda")?;
|
||||
|
||||
let output = Command::new("conda")
|
||||
.args(&["config", "--show", "auto_activate_base"])
|
||||
.args(["config", "--show", "auto_activate_base"])
|
||||
.output()?;
|
||||
let string_output = String::from_utf8(output.stdout)?;
|
||||
debug!("Conda output: {}", string_output);
|
||||
@@ -265,14 +265,14 @@ pub fn run_conda_update(ctx: &ExecutionContext) -> Result<()> {
|
||||
|
||||
ctx.run_type()
|
||||
.execute(&conda)
|
||||
.args(&["update", "--all", "-y"])
|
||||
.args(["update", "--all", "-y"])
|
||||
.check_run()
|
||||
}
|
||||
|
||||
pub fn run_pip3_update(run_type: RunType) -> Result<()> {
|
||||
let python3 = utils::require("python3")?;
|
||||
Command::new(&python3)
|
||||
.args(&["-m", "pip"])
|
||||
.args(["-m", "pip"])
|
||||
.check_output()
|
||||
.map_err(|_| SkipStep("pip does not exists".to_string()))?;
|
||||
|
||||
@@ -284,7 +284,7 @@ pub fn run_pip3_update(run_type: RunType) -> Result<()> {
|
||||
|
||||
run_type
|
||||
.execute(&python3)
|
||||
.args(&["-m", "pip", "install", "--upgrade", "--user", "pip"])
|
||||
.args(["-m", "pip", "install", "--upgrade", "--user", "pip"])
|
||||
.check_run()
|
||||
}
|
||||
|
||||
@@ -335,7 +335,7 @@ pub fn run_tlmgr_update(ctx: &ExecutionContext) -> Result<()> {
|
||||
c.arg(&tlmgr);
|
||||
c
|
||||
};
|
||||
command.args(&["update", "--self", "--all"]);
|
||||
command.args(["update", "--self", "--all"]);
|
||||
|
||||
command.check_run()
|
||||
}
|
||||
@@ -377,7 +377,7 @@ pub fn run_custom_command(name: &str, command: &str, ctx: &ExecutionContext) ->
|
||||
pub fn run_composer_update(ctx: &ExecutionContext) -> Result<()> {
|
||||
let composer = utils::require("composer")?;
|
||||
let composer_home = Command::new(&composer)
|
||||
.args(&["global", "config", "--absolute", "--quiet", "home"])
|
||||
.args(["global", "config", "--absolute", "--quiet", "home"])
|
||||
.check_output()
|
||||
.map_err(|e| (SkipStep(format!("Error getting the composer directory: {}", e))))
|
||||
.map(|s| PathBuf::from(s.trim()))?
|
||||
@@ -415,7 +415,7 @@ pub fn run_composer_update(ctx: &ExecutionContext) -> Result<()> {
|
||||
}
|
||||
}
|
||||
|
||||
let output = Command::new(&composer).args(&["global", "update"]).output()?;
|
||||
let output = Command::new(&composer).args(["global", "update"]).output()?;
|
||||
let status = output.status;
|
||||
if !status.success() {
|
||||
return Err(TopgradeError::ProcessFailed(status).into());
|
||||
@@ -436,7 +436,7 @@ pub fn run_composer_update(ctx: &ExecutionContext) -> Result<()> {
|
||||
pub fn run_dotnet_upgrade(ctx: &ExecutionContext) -> Result<()> {
|
||||
let dotnet = utils::require("dotnet")?;
|
||||
|
||||
let output = Command::new(dotnet).args(&["tool", "list", "--global"]).output()?;
|
||||
let output = Command::new(dotnet).args(["tool", "list", "--global"]).output()?;
|
||||
|
||||
if !output.status.success() {
|
||||
return Err(SkipStep(format!("dotnet failed with exit code {:?}", output.status)).into());
|
||||
@@ -459,7 +459,7 @@ pub fn run_dotnet_upgrade(ctx: &ExecutionContext) -> Result<()> {
|
||||
let package_name = package.split_whitespace().next().unwrap();
|
||||
ctx.run_type()
|
||||
.execute("dotnet")
|
||||
.args(&["tool", "update", package_name, "--global"])
|
||||
.args(["tool", "update", package_name, "--global"])
|
||||
.check_run()?;
|
||||
}
|
||||
|
||||
@@ -471,7 +471,7 @@ pub fn run_raco_update(run_type: RunType) -> Result<()> {
|
||||
|
||||
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<()> {
|
||||
@@ -490,7 +490,7 @@ pub fn spicetify_upgrade(ctx: &ExecutionContext) -> Result<()> {
|
||||
|
||||
pub fn run_ghcli_extensions_upgrade(ctx: &ExecutionContext) -> Result<()> {
|
||||
let gh = utils::require("gh")?;
|
||||
let result = Command::new(&gh).args(&["extensions", "list"]).check_output();
|
||||
let result = Command::new(&gh).args(["extensions", "list"]).check_output();
|
||||
if result.is_err() {
|
||||
debug!("GH result {:?}", result);
|
||||
return Err(SkipStep(String::from("GH failed")).into());
|
||||
@@ -499,7 +499,7 @@ pub fn run_ghcli_extensions_upgrade(ctx: &ExecutionContext) -> Result<()> {
|
||||
print_separator("GitHub CLI Extensions");
|
||||
ctx.run_type()
|
||||
.execute(&gh)
|
||||
.args(&["extension", "upgrade", "--all"])
|
||||
.args(["extension", "upgrade", "--all"])
|
||||
.check_run()
|
||||
}
|
||||
|
||||
@@ -510,6 +510,6 @@ pub fn update_julia_packages(ctx: &ExecutionContext) -> Result<()> {
|
||||
|
||||
ctx.run_type()
|
||||
.execute(&julia)
|
||||
.args(&["-e", "using Pkg; Pkg.update()"])
|
||||
.args(["-e", "using Pkg; Pkg.update()"])
|
||||
.check_run()
|
||||
}
|
||||
|
||||
@@ -53,7 +53,7 @@ async fn pull_repository(repo: String, git: &Path, ctx: &ExecutionContext<'_>) -
|
||||
command
|
||||
.stdin(Stdio::null())
|
||||
.current_dir(&repo)
|
||||
.args(&["pull", "--ff-only"]);
|
||||
.args(["pull", "--ff-only"]);
|
||||
|
||||
if let Some(extra_arguments) = ctx.config().git_arguments() {
|
||||
command.args(extra_arguments.split_whitespace());
|
||||
@@ -61,7 +61,7 @@ async fn pull_repository(repo: String, git: &Path, ctx: &ExecutionContext<'_>) -
|
||||
|
||||
let pull_output = command.output().await?;
|
||||
let submodule_output = AsyncCommand::new(git)
|
||||
.args(&["submodule", "update", "--recursive"])
|
||||
.args(["submodule", "update", "--recursive"])
|
||||
.current_dir(&repo)
|
||||
.stdin(Stdio::null())
|
||||
.output()
|
||||
@@ -78,10 +78,10 @@ async fn pull_repository(repo: String, git: &Path, ctx: &ExecutionContext<'_>) -
|
||||
(Some(before), Some(after)) if before != after => {
|
||||
println!("{} {}:", style("Changed").yellow().bold(), &repo);
|
||||
|
||||
Command::new(&git)
|
||||
Command::new(git)
|
||||
.stdin(Stdio::null())
|
||||
.current_dir(&repo)
|
||||
.args(&[
|
||||
.args([
|
||||
"--no-pager",
|
||||
"log",
|
||||
"--no-decorate",
|
||||
@@ -107,7 +107,7 @@ fn get_head_revision(git: &Path, repo: &str) -> Option<String> {
|
||||
Command::new(git)
|
||||
.stdin(Stdio::null())
|
||||
.current_dir(repo)
|
||||
.args(&["rev-parse", "HEAD"])
|
||||
.args(["rev-parse", "HEAD"])
|
||||
.check_output()
|
||||
.map(|output| output.trim().to_string())
|
||||
.map_err(|e| {
|
||||
@@ -122,7 +122,7 @@ fn has_remotes(git: &Path, repo: &str) -> Option<bool> {
|
||||
Command::new(git)
|
||||
.stdin(Stdio::null())
|
||||
.current_dir(repo)
|
||||
.args(&["remote", "show"])
|
||||
.args(["remote", "show"])
|
||||
.check_output()
|
||||
.map(|output| output.lines().count() > 0)
|
||||
.map_err(|e| {
|
||||
@@ -162,10 +162,10 @@ impl Git {
|
||||
};
|
||||
|
||||
if let Some(git) = &self.git {
|
||||
let output = Command::new(&git)
|
||||
let output = Command::new(git)
|
||||
.stdin(Stdio::null())
|
||||
.current_dir(path)
|
||||
.args(&["rev-parse", "--show-toplevel"])
|
||||
.args(["rev-parse", "--show-toplevel"])
|
||||
.check_output()
|
||||
.ok()
|
||||
.map(|output| output.trim().to_string());
|
||||
|
||||
@@ -14,7 +14,7 @@ pub fn upgrade_kak_plug(ctx: &ExecutionContext) -> Result<()> {
|
||||
print_separator("Kakoune");
|
||||
|
||||
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()?;
|
||||
|
||||
|
||||
@@ -43,7 +43,7 @@ impl NPM {
|
||||
|
||||
fn version(&self) -> Result<Version> {
|
||||
let version_str = Command::new(&self.command)
|
||||
.args(&["--version"])
|
||||
.args(["--version"])
|
||||
.check_output()
|
||||
.map(|s| s.trim().to_owned());
|
||||
Version::parse(&version_str?).map_err(|err| err.into())
|
||||
|
||||
@@ -229,6 +229,53 @@ impl ArchPackageManager for Pamac {
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Aura {
|
||||
executable: PathBuf,
|
||||
sudo: PathBuf,
|
||||
}
|
||||
|
||||
impl Aura {
|
||||
fn get(ctx: &ExecutionContext) -> Option<Self> {
|
||||
Some(Self {
|
||||
executable: which("aura")?,
|
||||
sudo: ctx.sudo().to_owned()?,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl ArchPackageManager for Aura {
|
||||
fn upgrade(&self, ctx: &ExecutionContext) -> Result<()> {
|
||||
let sudo = which("sudo").unwrap_or(PathBuf::new());
|
||||
let mut aur_update = ctx.run_type().execute(&sudo);
|
||||
|
||||
if sudo.ends_with("sudo") {
|
||||
aur_update
|
||||
.arg(&self.executable)
|
||||
.arg("-Au")
|
||||
.args(ctx.config().aura_aur_arguments().split_whitespace());
|
||||
if ctx.config().yes(Step::System) {
|
||||
aur_update.arg("--noconfirm");
|
||||
}
|
||||
|
||||
aur_update.check_run()?;
|
||||
} else {
|
||||
println!("Aura requires sudo installed to work with AUR packages")
|
||||
}
|
||||
|
||||
let mut pacman_update = ctx.run_type().execute(&self.sudo);
|
||||
pacman_update
|
||||
.arg(&self.executable)
|
||||
.arg("-Syu")
|
||||
.args(ctx.config().aura_pacman_arguments().split_whitespace());
|
||||
if ctx.config().yes(Step::System) {
|
||||
pacman_update.arg("--noconfirm");
|
||||
}
|
||||
pacman_update.check_run()?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
fn box_package_manager<P: 'static + ArchPackageManager>(package_manager: P) -> Box<dyn ArchPackageManager> {
|
||||
Box::new(package_manager) as Box<dyn ArchPackageManager>
|
||||
}
|
||||
@@ -243,13 +290,15 @@ pub fn get_arch_package_manager(ctx: &ExecutionContext) -> Option<Box<dyn ArchPa
|
||||
.or_else(|| Trizen::get().map(box_package_manager))
|
||||
.or_else(|| Pikaur::get().map(box_package_manager))
|
||||
.or_else(|| Pamac::get().map(box_package_manager))
|
||||
.or_else(|| Pacman::get(ctx).map(box_package_manager)),
|
||||
.or_else(|| Pacman::get(ctx).map(box_package_manager))
|
||||
.or_else(|| Aura::get(ctx).map(box_package_manager)),
|
||||
config::ArchPackageManager::Trizen => Trizen::get().map(box_package_manager),
|
||||
config::ArchPackageManager::Paru => YayParu::get("paru", &pacman).map(box_package_manager),
|
||||
config::ArchPackageManager::Yay => YayParu::get("yay", &pacman).map(box_package_manager),
|
||||
config::ArchPackageManager::Pacman => Pacman::get(ctx).map(box_package_manager),
|
||||
config::ArchPackageManager::Pikaur => Pikaur::get().map(box_package_manager),
|
||||
config::ArchPackageManager::Pamac => Pamac::get().map(box_package_manager),
|
||||
config::ArchPackageManager::Aura => Aura::get(ctx).map(box_package_manager),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -125,7 +125,7 @@ impl Distribution {
|
||||
fn update_bedrock(ctx: &ExecutionContext) -> Result<()> {
|
||||
let sudo = require_option(ctx.sudo().as_ref(), String::from("Sudo required"))?;
|
||||
|
||||
ctx.run_type().execute(sudo).args(&["brl", "update"]);
|
||||
ctx.run_type().execute(sudo).args(["brl", "update"]);
|
||||
|
||||
let output = Command::new("brl").arg("list").output()?;
|
||||
debug!("brl list: {:?} {:?}", output.stdout, output.stderr);
|
||||
@@ -171,7 +171,7 @@ fn upgrade_redhat(ctx: &ExecutionContext) -> Result<()> {
|
||||
};
|
||||
|
||||
if let Some(sudo) = &ctx.sudo() {
|
||||
let mut command = ctx.run_type().execute(&sudo);
|
||||
let mut command = ctx.run_type().execute(sudo);
|
||||
command
|
||||
.arg(which("dnf").unwrap_or_else(|| Path::new("yum").to_path_buf()))
|
||||
.arg(if ctx.config().redhat_distro_sync() {
|
||||
@@ -198,7 +198,7 @@ fn upgrade_redhat(ctx: &ExecutionContext) -> Result<()> {
|
||||
|
||||
fn upgrade_bedrock_strata(ctx: &ExecutionContext) -> Result<()> {
|
||||
if let Some(sudo) = ctx.sudo() {
|
||||
ctx.run_type().execute(&sudo).args(&["brl", "update"]).check_run()?;
|
||||
ctx.run_type().execute(sudo).args(["brl", "update"]).check_run()?;
|
||||
} else {
|
||||
print_warning("No sudo detected. Skipping system upgrade");
|
||||
}
|
||||
@@ -208,11 +208,11 @@ fn upgrade_bedrock_strata(ctx: &ExecutionContext) -> Result<()> {
|
||||
|
||||
fn upgrade_suse(ctx: &ExecutionContext) -> Result<()> {
|
||||
if let Some(sudo) = ctx.sudo() {
|
||||
ctx.run_type().execute(&sudo).args(&["zypper", "refresh"]).check_run()?;
|
||||
ctx.run_type().execute(sudo).args(["zypper", "refresh"]).check_run()?;
|
||||
|
||||
ctx.run_type()
|
||||
.execute(&sudo)
|
||||
.args(&["zypper", "dist-upgrade"])
|
||||
.execute(sudo)
|
||||
.args(["zypper", "dist-upgrade"])
|
||||
.check_run()?;
|
||||
} else {
|
||||
print_warning("No sudo detected. Skipping system upgrade");
|
||||
@@ -223,9 +223,9 @@ fn upgrade_suse(ctx: &ExecutionContext) -> Result<()> {
|
||||
|
||||
fn upgrade_openmandriva(ctx: &ExecutionContext) -> Result<()> {
|
||||
if let Some(sudo) = &ctx.sudo() {
|
||||
let mut command = ctx.run_type().execute(&sudo);
|
||||
let mut command = ctx.run_type().execute(sudo);
|
||||
|
||||
command.arg(which("dnf").unwrap().to_path_buf()).arg("upgrade");
|
||||
command.arg(&which("dnf").unwrap()).arg("upgrade");
|
||||
|
||||
if let Some(args) = ctx.config().dnf_arguments() {
|
||||
command.args(args.split_whitespace());
|
||||
@@ -245,15 +245,15 @@ fn upgrade_openmandriva(ctx: &ExecutionContext) -> Result<()> {
|
||||
|
||||
fn upgrade_void(ctx: &ExecutionContext) -> Result<()> {
|
||||
if let Some(sudo) = ctx.sudo() {
|
||||
let mut command = ctx.run_type().execute(&sudo);
|
||||
command.args(&["xbps-install", "-Su", "xbps"]);
|
||||
let mut command = ctx.run_type().execute(sudo);
|
||||
command.args(["xbps-install", "-Su", "xbps"]);
|
||||
if ctx.config().yes(Step::System) {
|
||||
command.arg("-y");
|
||||
}
|
||||
command.check_run()?;
|
||||
|
||||
let mut command = ctx.run_type().execute(&sudo);
|
||||
command.args(&["xbps-install", "-u"]);
|
||||
let mut command = ctx.run_type().execute(sudo);
|
||||
command.args(["xbps-install", "-u"]);
|
||||
if ctx.config().yes(Step::System) {
|
||||
command.arg("-y");
|
||||
}
|
||||
@@ -270,13 +270,13 @@ fn upgrade_gentoo(ctx: &ExecutionContext) -> Result<()> {
|
||||
|
||||
if let Some(sudo) = &ctx.sudo() {
|
||||
if let Some(layman) = which("layman") {
|
||||
run_type.execute(&sudo).arg(layman).args(&["-s", "ALL"]).check_run()?;
|
||||
run_type.execute(sudo).arg(layman).args(["-s", "ALL"]).check_run()?;
|
||||
}
|
||||
|
||||
println!("Syncing portage");
|
||||
run_type
|
||||
.execute(&sudo)
|
||||
.args(&["emerge", "--sync"])
|
||||
.execute(sudo)
|
||||
.args(["emerge", "--sync"])
|
||||
.args(
|
||||
ctx.config()
|
||||
.emerge_sync_flags()
|
||||
@@ -286,11 +286,11 @@ fn upgrade_gentoo(ctx: &ExecutionContext) -> Result<()> {
|
||||
.check_run()?;
|
||||
|
||||
if let Some(eix_update) = which("eix-update") {
|
||||
run_type.execute(&sudo).arg(eix_update).check_run()?;
|
||||
run_type.execute(sudo).arg(eix_update).check_run()?;
|
||||
}
|
||||
|
||||
run_type
|
||||
.execute(&sudo)
|
||||
.execute(sudo)
|
||||
.arg("emerge")
|
||||
.args(
|
||||
ctx.config()
|
||||
@@ -314,10 +314,10 @@ fn upgrade_debian(ctx: &ExecutionContext) -> Result<()> {
|
||||
|
||||
let is_nala = apt.ends_with("nala");
|
||||
if !is_nala {
|
||||
ctx.run_type().execute(&sudo).arg(&apt).arg("update").check_run()?;
|
||||
ctx.run_type().execute(sudo).arg(&apt).arg("update").check_run()?;
|
||||
}
|
||||
|
||||
let mut command = ctx.run_type().execute(&sudo);
|
||||
let mut command = ctx.run_type().execute(sudo);
|
||||
command.arg(&apt);
|
||||
if is_nala {
|
||||
command.arg("upgrade");
|
||||
@@ -333,9 +333,9 @@ fn upgrade_debian(ctx: &ExecutionContext) -> Result<()> {
|
||||
command.check_run()?;
|
||||
|
||||
if ctx.config().cleanup() {
|
||||
ctx.run_type().execute(&sudo).arg(&apt).arg("clean").check_run()?;
|
||||
ctx.run_type().execute(sudo).arg(&apt).arg("clean").check_run()?;
|
||||
|
||||
let mut command = ctx.run_type().execute(&sudo);
|
||||
let mut command = ctx.run_type().execute(sudo);
|
||||
command.arg(&apt).arg("autoremove");
|
||||
if ctx.config().yes(Step::System) {
|
||||
command.arg("-y");
|
||||
@@ -366,7 +366,7 @@ pub fn run_deb_get(ctx: &ExecutionContext) -> Result<()> {
|
||||
|
||||
fn upgrade_solus(ctx: &ExecutionContext) -> Result<()> {
|
||||
if let Some(sudo) = ctx.sudo() {
|
||||
ctx.run_type().execute(&sudo).args(&["eopkg", "upgrade"]).check_run()?;
|
||||
ctx.run_type().execute(sudo).args(["eopkg", "upgrade"]).check_run()?;
|
||||
} else {
|
||||
print_warning("No sudo detected. Skipping system upgrade");
|
||||
}
|
||||
@@ -396,7 +396,7 @@ pub fn run_pacstall(ctx: &ExecutionContext) -> Result<()> {
|
||||
|
||||
fn upgrade_clearlinux(ctx: &ExecutionContext) -> Result<()> {
|
||||
if let Some(sudo) = &ctx.sudo() {
|
||||
ctx.run_type().execute(&sudo).args(&["swupd", "update"]).check_run()?;
|
||||
ctx.run_type().execute(sudo).args(["swupd", "update"]).check_run()?;
|
||||
} else {
|
||||
print_warning("No sudo detected. Skipping system upgrade");
|
||||
}
|
||||
@@ -406,28 +406,25 @@ fn upgrade_clearlinux(ctx: &ExecutionContext) -> Result<()> {
|
||||
|
||||
fn upgrade_exherbo(ctx: &ExecutionContext) -> Result<()> {
|
||||
if let Some(sudo) = ctx.sudo() {
|
||||
ctx.run_type().execute(&sudo).args(&["cave", "sync"]).check_run()?;
|
||||
ctx.run_type().execute(sudo).args(["cave", "sync"]).check_run()?;
|
||||
|
||||
ctx.run_type()
|
||||
.execute(&sudo)
|
||||
.args(&["cave", "resolve", "world", "-c1", "-Cs", "-km", "-Km", "-x"])
|
||||
.execute(sudo)
|
||||
.args(["cave", "resolve", "world", "-c1", "-Cs", "-km", "-Km", "-x"])
|
||||
.check_run()?;
|
||||
|
||||
if ctx.config().cleanup() {
|
||||
ctx.run_type()
|
||||
.execute(&sudo)
|
||||
.args(&["cave", "purge", "-x"])
|
||||
.check_run()?;
|
||||
ctx.run_type().execute(sudo).args(["cave", "purge", "-x"]).check_run()?;
|
||||
}
|
||||
|
||||
ctx.run_type()
|
||||
.execute(&sudo)
|
||||
.args(&["cave", "fix-linkage", "-x", "--", "-Cs"])
|
||||
.execute(sudo)
|
||||
.args(["cave", "fix-linkage", "-x", "--", "-Cs"])
|
||||
.check_run()?;
|
||||
|
||||
ctx.run_type()
|
||||
.execute(&sudo)
|
||||
.args(&["eclectic", "config", "interactive"])
|
||||
.execute(sudo)
|
||||
.args(["eclectic", "config", "interactive"])
|
||||
.check_run()?;
|
||||
} else {
|
||||
print_warning("No sudo detected. Skipping system upgrade");
|
||||
@@ -439,14 +436,14 @@ fn upgrade_exherbo(ctx: &ExecutionContext) -> Result<()> {
|
||||
fn upgrade_nixos(ctx: &ExecutionContext) -> Result<()> {
|
||||
if let Some(sudo) = ctx.sudo() {
|
||||
ctx.run_type()
|
||||
.execute(&sudo)
|
||||
.args(&["/run/current-system/sw/bin/nixos-rebuild", "switch", "--upgrade"])
|
||||
.execute(sudo)
|
||||
.args(["/run/current-system/sw/bin/nixos-rebuild", "switch", "--upgrade"])
|
||||
.check_run()?;
|
||||
|
||||
if ctx.config().cleanup() {
|
||||
ctx.run_type()
|
||||
.execute(&sudo)
|
||||
.args(&["/run/current-system/sw/bin/nix-collect-garbage", "-d"])
|
||||
.execute(sudo)
|
||||
.args(["/run/current-system/sw/bin/nix-collect-garbage", "-d"])
|
||||
.check_run()?;
|
||||
}
|
||||
} else {
|
||||
@@ -465,8 +462,8 @@ fn upgrade_neon(ctx: &ExecutionContext) -> Result<()> {
|
||||
if let Some(sudo) = &ctx.sudo() {
|
||||
let pkcon = which("pkcon").unwrap();
|
||||
// pkcon ignores update with update and refresh provided together
|
||||
ctx.run_type().execute(&sudo).arg(&pkcon).arg("refresh").check_run()?;
|
||||
let mut exe = ctx.run_type().execute(&sudo);
|
||||
ctx.run_type().execute(sudo).arg(&pkcon).arg("refresh").check_run()?;
|
||||
let mut exe = ctx.run_type().execute(sudo);
|
||||
let cmd = exe.arg(&pkcon).arg("update");
|
||||
if ctx.config().yes(Step::System) {
|
||||
cmd.arg("-y");
|
||||
@@ -492,7 +489,7 @@ pub fn run_needrestart(sudo: Option<&PathBuf>, run_type: RunType) -> Result<()>
|
||||
|
||||
print_separator("Check for needed restarts");
|
||||
|
||||
run_type.execute(&sudo).arg(needrestart).check_run()?;
|
||||
run_type.execute(sudo).arg(needrestart).check_run()?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@@ -552,7 +549,7 @@ pub fn flatpak_update(ctx: &ExecutionContext) -> Result<()> {
|
||||
if yes {
|
||||
update_args.push("-y");
|
||||
}
|
||||
run_type.execute(&sudo).arg(&flatpak).args(&update_args).check_run()?;
|
||||
run_type.execute(sudo).arg(&flatpak).args(&update_args).check_run()?;
|
||||
if cleanup {
|
||||
let mut cleanup_args = vec!["uninstall", "--system", "--unused"];
|
||||
if yes {
|
||||
|
||||
@@ -8,6 +8,7 @@ use crate::utils::{require, PathExt};
|
||||
use crate::Step;
|
||||
use anyhow::Result;
|
||||
use directories::BaseDirs;
|
||||
use home;
|
||||
use ini::Ini;
|
||||
use log::debug;
|
||||
use std::fs;
|
||||
@@ -88,7 +89,19 @@ pub fn run_fisher(base_dirs: &BaseDirs, run_type: RunType) -> Result<()> {
|
||||
|
||||
print_separator("Fisher");
|
||||
|
||||
run_type.execute(&fish).args(&["-c", "fisher update"]).check_run()
|
||||
let version_str = run_type
|
||||
.execute(&fish)
|
||||
.args(["-c", "fisher --version"])
|
||||
.check_output()?;
|
||||
debug!("Fisher version: {}", version_str);
|
||||
|
||||
if version_str.starts_with("fisher version 3.") {
|
||||
// v3 - see https://github.com/topgrade-rs/topgrade/pull/37#issuecomment-1283844506
|
||||
run_type.execute(&fish).args(["-c", "fisher"]).check_run()
|
||||
} else {
|
||||
// v4
|
||||
run_type.execute(&fish).args(["-c", "fisher update"]).check_run()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn run_bashit(ctx: &ExecutionContext) -> Result<()> {
|
||||
@@ -98,7 +111,7 @@ pub fn run_bashit(ctx: &ExecutionContext) -> Result<()> {
|
||||
|
||||
ctx.run_type()
|
||||
.execute("bash")
|
||||
.args(&["-lic", &format!("bash-it update {}", ctx.config().bashit_branch())])
|
||||
.args(["-lic", &format!("bash-it update {}", ctx.config().bashit_branch())])
|
||||
.check_run()
|
||||
}
|
||||
|
||||
@@ -111,7 +124,7 @@ pub fn run_oh_my_fish(ctx: &ExecutionContext) -> Result<()> {
|
||||
|
||||
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<()> {
|
||||
@@ -141,7 +154,7 @@ pub fn run_fish_plug(ctx: &ExecutionContext) -> Result<()> {
|
||||
|
||||
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()
|
||||
}
|
||||
|
||||
#[cfg(not(any(target_os = "android", target_os = "macos")))]
|
||||
@@ -152,7 +165,7 @@ pub fn upgrade_gnome_extensions(ctx: &ExecutionContext) -> Result<()> {
|
||||
"Desktop doest not appear to be gnome".to_string(),
|
||||
)?;
|
||||
let output = Command::new("gdbus")
|
||||
.args(&[
|
||||
.args([
|
||||
"call",
|
||||
"--session",
|
||||
"--dest",
|
||||
@@ -173,7 +186,7 @@ pub fn upgrade_gnome_extensions(ctx: &ExecutionContext) -> Result<()> {
|
||||
|
||||
ctx.run_type()
|
||||
.execute(gdbus)
|
||||
.args(&[
|
||||
.args([
|
||||
"call",
|
||||
"--session",
|
||||
"--dest",
|
||||
@@ -203,7 +216,7 @@ pub fn run_brew_formula(ctx: &ExecutionContext, variant: BrewVariant) -> Result<
|
||||
variant.execute(run_type).arg("update").check_run()?;
|
||||
variant
|
||||
.execute(run_type)
|
||||
.args(&["upgrade", "--ignore-pinned", "--formula"])
|
||||
.args(["upgrade", "--ignore-pinned", "--formula"])
|
||||
.check_run()?;
|
||||
|
||||
if ctx.config().cleanup() {
|
||||
@@ -268,7 +281,7 @@ pub fn run_guix(ctx: &ExecutionContext) -> Result<()> {
|
||||
print_separator("Guix");
|
||||
|
||||
if should_upgrade {
|
||||
return run_type.execute(&guix).args(&["package", "-u"]).check_run();
|
||||
return run_type.execute(&guix).args(["package", "-u"]).check_run();
|
||||
}
|
||||
Err(SkipStep(String::from("Guix Pull Failed, Skipping")).into())
|
||||
}
|
||||
@@ -277,8 +290,14 @@ pub fn run_nix(ctx: &ExecutionContext) -> Result<()> {
|
||||
let nix = require("nix")?;
|
||||
let nix_channel = require("nix-channel")?;
|
||||
let nix_env = require("nix-env")?;
|
||||
let profile_path = match home::home_dir() {
|
||||
Some(home) => Path::new(&home).join(".nix-profile"),
|
||||
None => Path::new("/nix/var/nix/profiles/per-user/default").into(),
|
||||
};
|
||||
debug!("nix profile: {:?}", profile_path);
|
||||
let manifest_json_path = profile_path.join("manifest.json");
|
||||
|
||||
let output = Command::new(&nix_env).args(&["--query", "nix"]).check_output();
|
||||
let output = Command::new(&nix_env).args(["--query", "nix"]).check_output();
|
||||
debug!("nix-env output: {:?}", output);
|
||||
let should_self_upgrade = output.is_ok();
|
||||
|
||||
@@ -317,7 +336,17 @@ pub fn run_nix(ctx: &ExecutionContext) -> Result<()> {
|
||||
}
|
||||
|
||||
run_type.execute(&nix_channel).arg("--update").check_run()?;
|
||||
run_type.execute(&nix_env).arg("--upgrade").check_run()
|
||||
|
||||
if std::path::Path::new(&manifest_json_path).exists() {
|
||||
run_type
|
||||
.execute(&nix)
|
||||
.arg("profile")
|
||||
.arg("upgrade")
|
||||
.arg(".*")
|
||||
.check_run()
|
||||
} else {
|
||||
run_type.execute(&nix_env).arg("--upgrade").check_run()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn run_yadm(ctx: &ExecutionContext) -> Result<()> {
|
||||
@@ -339,7 +368,7 @@ pub fn run_asdf(run_type: RunType) -> Result<()> {
|
||||
return Err(TopgradeError::ProcessFailed(e).into());
|
||||
}
|
||||
}
|
||||
run_type.execute(&asdf).args(&["plugin", "update", "--all"]).check_run()
|
||||
run_type.execute(&asdf).args(["plugin", "update", "--all"]).check_run()
|
||||
}
|
||||
|
||||
pub fn run_home_manager(run_type: RunType) -> Result<()> {
|
||||
@@ -393,30 +422,27 @@ pub fn run_sdkman(base_dirs: &BaseDirs, cleanup: bool, run_type: RunType) -> Res
|
||||
let cmd_selfupdate = format!("source {} && sdk selfupdate", &sdkman_init_path);
|
||||
run_type
|
||||
.execute(&bash)
|
||||
.args(&["-c", cmd_selfupdate.as_str()])
|
||||
.args(["-c", cmd_selfupdate.as_str()])
|
||||
.check_run()?;
|
||||
}
|
||||
|
||||
let cmd_update = format!("source {} && sdk update", &sdkman_init_path);
|
||||
run_type.execute(&bash).args(&["-c", cmd_update.as_str()]).check_run()?;
|
||||
run_type.execute(&bash).args(["-c", cmd_update.as_str()]).check_run()?;
|
||||
|
||||
let cmd_upgrade = format!("source {} && sdk upgrade", &sdkman_init_path);
|
||||
run_type
|
||||
.execute(&bash)
|
||||
.args(&["-c", cmd_upgrade.as_str()])
|
||||
.check_run()?;
|
||||
run_type.execute(&bash).args(["-c", cmd_upgrade.as_str()]).check_run()?;
|
||||
|
||||
if cleanup {
|
||||
let cmd_flush_archives = format!("source {} && sdk flush archives", &sdkman_init_path);
|
||||
run_type
|
||||
.execute(&bash)
|
||||
.args(&["-c", cmd_flush_archives.as_str()])
|
||||
.args(["-c", cmd_flush_archives.as_str()])
|
||||
.check_run()?;
|
||||
|
||||
let cmd_flush_temp = format!("source {} && sdk flush temp", &sdkman_init_path);
|
||||
run_type
|
||||
.execute(&bash)
|
||||
.args(&["-c", cmd_flush_temp.as_str()])
|
||||
.args(["-c", cmd_flush_temp.as_str()])
|
||||
.check_run()?;
|
||||
}
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@ impl Powershell {
|
||||
|
||||
let profile = path.as_ref().and_then(|path| {
|
||||
Command::new(path)
|
||||
.args(&["-NoProfile", "-Command", "Split-Path $profile"])
|
||||
.args(["-NoProfile", "-Command", "Split-Path $profile"])
|
||||
.check_output()
|
||||
.map(|output| PathBuf::from(output.trim()))
|
||||
.and_then(|p| p.require())
|
||||
@@ -78,8 +78,8 @@ impl Powershell {
|
||||
|
||||
println!("Updating modules...");
|
||||
ctx.run_type()
|
||||
.execute(&powershell)
|
||||
.args(&["-NoProfile", "-Command", &cmd.join(" ")])
|
||||
.execute(powershell)
|
||||
.args(["-NoProfile", "-Command", &cmd.join(" ")])
|
||||
.check_run()
|
||||
}
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ pub fn ssh_step(ctx: &ExecutionContext, hostname: &str) -> Result<()> {
|
||||
}
|
||||
|
||||
let env = format!("TOPGRADE_PREFIX={}", hostname);
|
||||
args.extend(&["env", &env, "$SHELL", "-lc", topgrade]);
|
||||
args.extend(["env", &env, "$SHELL", "-lc", topgrade]);
|
||||
|
||||
if ctx.config().run_in_tmux() && !ctx.run_type().dry() {
|
||||
#[cfg(unix)]
|
||||
@@ -42,7 +42,7 @@ pub fn ssh_step(ctx: &ExecutionContext, hostname: &str) -> Result<()> {
|
||||
}
|
||||
|
||||
let env = format!("TOPGRADE_PREFIX={}", hostname);
|
||||
args.extend(&["env", &env, "$SHELL", "-lc", topgrade]);
|
||||
args.extend(["env", &env, "$SHELL", "-lc", topgrade]);
|
||||
|
||||
print_separator(format!("Remote ({})", hostname));
|
||||
println!("Connecting to {}...", hostname);
|
||||
|
||||
@@ -113,7 +113,7 @@ impl<'a> TemporaryPowerOn<'a> {
|
||||
|
||||
ctx.run_type()
|
||||
.execute(vagrant)
|
||||
.args(&[subcommand, &vagrant_box.name])
|
||||
.args([subcommand, &vagrant_box.name])
|
||||
.current_dir(vagrant_box.path.clone())
|
||||
.check_run()?;
|
||||
Ok(TemporaryPowerOn {
|
||||
@@ -140,7 +140,7 @@ impl<'a> Drop for TemporaryPowerOn<'a> {
|
||||
self.ctx
|
||||
.run_type()
|
||||
.execute(self.vagrant)
|
||||
.args(&[subcommand, &self.vagrant_box.name])
|
||||
.args([subcommand, &self.vagrant_box.name])
|
||||
.current_dir(self.vagrant_box.path.clone())
|
||||
.check_run()
|
||||
.ok();
|
||||
@@ -198,7 +198,7 @@ pub fn topgrade_vagrant_box(ctx: &ExecutionContext, vagrant_box: &VagrantBox) ->
|
||||
ctx.run_type()
|
||||
.execute(&vagrant.path)
|
||||
.current_dir(&vagrant_box.path)
|
||||
.args(&["ssh", "-c", &command])
|
||||
.args(["ssh", "-c", &command])
|
||||
.check_run()
|
||||
}
|
||||
|
||||
@@ -207,7 +207,7 @@ pub fn upgrade_vagrant_boxes(ctx: &ExecutionContext) -> Result<()> {
|
||||
print_separator("Vagrant boxes");
|
||||
|
||||
let outdated = Command::new(&vagrant)
|
||||
.args(&["box", "outdated", "--global"])
|
||||
.args(["box", "outdated", "--global"])
|
||||
.check_output()?;
|
||||
|
||||
let re = Regex::new(r"\* '(.*?)' for '(.*?)' is outdated").unwrap();
|
||||
@@ -218,8 +218,8 @@ pub fn upgrade_vagrant_boxes(ctx: &ExecutionContext) -> Result<()> {
|
||||
let _ = ctx
|
||||
.run_type()
|
||||
.execute(&vagrant)
|
||||
.args(&["box", "update", "--box"])
|
||||
.arg(&ele.get(1).unwrap().as_str())
|
||||
.args(["box", "update", "--box"])
|
||||
.arg(ele.get(1).unwrap().as_str())
|
||||
.arg("--provider")
|
||||
.arg(ele.get(2).unwrap().as_str())
|
||||
.check_run();
|
||||
@@ -228,7 +228,7 @@ pub fn upgrade_vagrant_boxes(ctx: &ExecutionContext) -> Result<()> {
|
||||
if !found {
|
||||
println!("No outdated boxes")
|
||||
} else {
|
||||
ctx.run_type().execute(&vagrant).args(&["box", "prune"]).check_run()?;
|
||||
ctx.run_type().execute(&vagrant).args(["box", "prune"]).check_run()?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
||||
@@ -49,7 +49,7 @@ impl Tmux {
|
||||
fn has_session(&self, session_name: &str) -> Result<bool, io::Error> {
|
||||
Ok(self
|
||||
.build()
|
||||
.args(&["has-session", "-t", session_name])
|
||||
.args(["has-session", "-t", session_name])
|
||||
.output()?
|
||||
.status
|
||||
.success())
|
||||
@@ -58,7 +58,7 @@ impl Tmux {
|
||||
fn new_session(&self, session_name: &str) -> Result<bool, io::Error> {
|
||||
Ok(self
|
||||
.build()
|
||||
.args(&["new-session", "-d", "-s", session_name, "-n", "dummy"])
|
||||
.args(["new-session", "-d", "-s", session_name, "-n", "dummy"])
|
||||
.spawn()?
|
||||
.wait()?
|
||||
.success())
|
||||
@@ -66,7 +66,7 @@ impl Tmux {
|
||||
|
||||
fn run_in_session(&self, command: &str) -> Result<()> {
|
||||
self.build()
|
||||
.args(&["new-window", "-t", "topgrade", command])
|
||||
.args(["new-window", "-t", "topgrade", command])
|
||||
.spawn()?
|
||||
.wait()?
|
||||
.check()?;
|
||||
@@ -94,12 +94,12 @@ pub fn run_in_tmux(args: &Option<String>) -> ! {
|
||||
|
||||
tmux.run_in_session(&command).expect("Error running topgrade in tmux");
|
||||
tmux.build()
|
||||
.args(&["kill-window", "-t", "topgrade:dummy"])
|
||||
.args(["kill-window", "-t", "topgrade:dummy"])
|
||||
.output()
|
||||
.expect("Error killing the dummy tmux window");
|
||||
|
||||
if env::var("TMUX").is_err() {
|
||||
let err = tmux.build().args(&["attach", "-t", "topgrade"]).exec();
|
||||
let err = tmux.build().args(["attach", "-t", "topgrade"]).exec();
|
||||
panic!("{:?}", err);
|
||||
} else {
|
||||
println!("Topgrade launched in a new tmux session");
|
||||
@@ -110,7 +110,7 @@ pub fn run_in_tmux(args: &Option<String>) -> ! {
|
||||
pub fn run_command(ctx: &ExecutionContext, command: &str) -> Result<()> {
|
||||
Tmux::new(ctx.config().tmux_arguments())
|
||||
.build()
|
||||
.args(&["new-window", "-a", "-t", "topgrade:1", command])
|
||||
.args(["new-window", "-a", "-t", "topgrade:1", command])
|
||||
.env_remove("TMUX")
|
||||
.spawn()?
|
||||
.wait()?
|
||||
|
||||
@@ -8,7 +8,7 @@ use std::path::Path;
|
||||
use std::{path::PathBuf, process::Command};
|
||||
|
||||
fn list_toolboxes(toolbx: &Path) -> Result<Vec<String>> {
|
||||
let output = Command::new(toolbx).args(&["list", "--containers"]).output()?;
|
||||
let output = Command::new(toolbx).args(["list", "--containers"]).output()?;
|
||||
let output_str = String::from_utf8(output.stdout)?;
|
||||
|
||||
let proc: Vec<String> = output_str
|
||||
|
||||
@@ -45,12 +45,12 @@ fn upgrade(vim: &Path, vimrc: &Path, ctx: &ExecutionContext) -> Result<()> {
|
||||
tempfile.write_all(UPGRADE_VIM.replace('\r', "").as_bytes())?;
|
||||
debug!("Wrote vim script to {:?}", tempfile.path());
|
||||
|
||||
let mut command = ctx.run_type().execute(&vim);
|
||||
let mut command = ctx.run_type().execute(vim);
|
||||
|
||||
command
|
||||
.args(&["-u"])
|
||||
.args(["-u"])
|
||||
.arg(vimrc)
|
||||
.args(&["-U", "NONE", "-V1", "-nNesS"])
|
||||
.args(["-U", "NONE", "-V1", "-nNesS"])
|
||||
.arg(tempfile.path());
|
||||
|
||||
if ctx.config().force_vim_plug_update() {
|
||||
@@ -88,17 +88,17 @@ pub fn upgrade_ultimate_vimrc(ctx: &ExecutionContext) -> Result<()> {
|
||||
ctx.run_type()
|
||||
.execute(&git)
|
||||
.current_dir(&config_dir)
|
||||
.args(&["reset", "--hard"])
|
||||
.args(["reset", "--hard"])
|
||||
.check_run()?;
|
||||
ctx.run_type()
|
||||
.execute(&git)
|
||||
.current_dir(&config_dir)
|
||||
.args(&["clean", "-d", "--force"])
|
||||
.args(["clean", "-d", "--force"])
|
||||
.check_run()?;
|
||||
ctx.run_type()
|
||||
.execute(&git)
|
||||
.current_dir(&config_dir)
|
||||
.args(&["pull", "--rebase"])
|
||||
.args(["pull", "--rebase"])
|
||||
.check_run()?;
|
||||
ctx.run_type()
|
||||
.execute(python)
|
||||
|
||||
@@ -19,7 +19,7 @@ pub fn run_zr(base_dirs: &BaseDirs, run_type: RunType) -> Result<()> {
|
||||
print_separator("zr");
|
||||
|
||||
let cmd = format!("source {} && zr --update", zshrc(base_dirs).display());
|
||||
run_type.execute(zsh).args(&["-l", "-c", cmd.as_str()]).check_run()
|
||||
run_type.execute(zsh).args(["-l", "-c", cmd.as_str()]).check_run()
|
||||
}
|
||||
|
||||
pub fn zshrc(base_dirs: &BaseDirs) -> PathBuf {
|
||||
@@ -47,8 +47,8 @@ pub fn run_antigen(base_dirs: &BaseDirs, run_type: RunType) -> Result<()> {
|
||||
|
||||
print_separator("antigen");
|
||||
|
||||
let cmd = format!("source {} && antigen selfupdate && antigen update", zshrc.display());
|
||||
run_type.execute(zsh).args(&["-l", "-c", cmd.as_str()]).check_run()
|
||||
let cmd = format!("source {} && (antigen selfupdate ; antigen update)", zshrc.display());
|
||||
run_type.execute(zsh).args(["-l", "-c", cmd.as_str()]).check_run()
|
||||
}
|
||||
|
||||
pub fn run_zgenom(base_dirs: &BaseDirs, run_type: RunType) -> Result<()> {
|
||||
@@ -62,7 +62,7 @@ pub fn run_zgenom(base_dirs: &BaseDirs, run_type: RunType) -> Result<()> {
|
||||
print_separator("zgenom");
|
||||
|
||||
let cmd = format!("source {} && zgenom selfupdate && zgenom update", zshrc.display());
|
||||
run_type.execute(zsh).args(&["-l", "-c", cmd.as_str()]).check_run()
|
||||
run_type.execute(zsh).args(["-l", "-c", cmd.as_str()]).check_run()
|
||||
}
|
||||
|
||||
pub fn run_zplug(base_dirs: &BaseDirs, run_type: RunType) -> Result<()> {
|
||||
@@ -76,7 +76,7 @@ pub fn run_zplug(base_dirs: &BaseDirs, run_type: RunType) -> Result<()> {
|
||||
|
||||
print_separator("zplug");
|
||||
|
||||
run_type.execute(zsh).args(&["-i", "-c", "zplug update"]).check_run()
|
||||
run_type.execute(zsh).args(["-i", "-c", "zplug update"]).check_run()
|
||||
}
|
||||
|
||||
pub fn run_zinit(base_dirs: &BaseDirs, run_type: RunType) -> Result<()> {
|
||||
@@ -91,7 +91,7 @@ pub fn run_zinit(base_dirs: &BaseDirs, run_type: RunType) -> Result<()> {
|
||||
print_separator("zinit");
|
||||
|
||||
let cmd = format!("source {} && zinit self-update && zinit update --all", zshrc.display(),);
|
||||
run_type.execute(zsh).args(&["-i", "-c", cmd.as_str()]).check_run()
|
||||
run_type.execute(zsh).args(["-i", "-c", cmd.as_str()]).check_run()
|
||||
}
|
||||
|
||||
pub fn run_zi(base_dirs: &BaseDirs, run_type: RunType) -> Result<()> {
|
||||
@@ -111,7 +111,7 @@ pub fn run_zim(base_dirs: &BaseDirs, run_type: RunType) -> Result<()> {
|
||||
env::var("ZIM_HOME")
|
||||
.or_else(|_| {
|
||||
Command::new("zsh")
|
||||
.args(&["-c", "[[ -n ${ZIM_HOME} ]] && print -n ${ZIM_HOME}"])
|
||||
.args(["-c", "[[ -n ${ZIM_HOME} ]] && print -n ${ZIM_HOME}"])
|
||||
.check_output()
|
||||
})
|
||||
.map(PathBuf::from)
|
||||
@@ -122,7 +122,7 @@ pub fn run_zim(base_dirs: &BaseDirs, run_type: RunType) -> Result<()> {
|
||||
|
||||
run_type
|
||||
.execute(zsh)
|
||||
.args(&["-i", "-c", "zimfw upgrade && zimfw update"])
|
||||
.args(["-i", "-c", "zimfw upgrade && zimfw update"])
|
||||
.check_run()
|
||||
}
|
||||
|
||||
@@ -135,7 +135,7 @@ pub fn run_oh_my_zsh(ctx: &ExecutionContext) -> Result<()> {
|
||||
let custom_dir = env::var::<_>("ZSH_CUSTOM")
|
||||
.or_else(|_| {
|
||||
Command::new("zsh")
|
||||
.args(&["-c", "test $ZSH_CUSTOM && echo -n $ZSH_CUSTOM"])
|
||||
.args(["-c", "test $ZSH_CUSTOM && echo -n $ZSH_CUSTOM"])
|
||||
.check_output()
|
||||
})
|
||||
.map(PathBuf::from)
|
||||
|
||||
@@ -104,7 +104,7 @@ impl Terminal {
|
||||
command.arg("-t");
|
||||
command.arg(format!("{}", timeout.as_millis()));
|
||||
}
|
||||
command.args(&["-a", "Topgrade", "Topgrade"]);
|
||||
command.args(["-a", "Topgrade", "Topgrade"]);
|
||||
command.arg(message.as_ref());
|
||||
command.output().ok();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user