Revert "10.2.0 release " (#215)

Revert "10.2.0 release  (#213)"

This reverts commit 13076fcef6.
This commit is contained in:
Thomas Schönauer
2022-11-23 15:23:00 +00:00
committed by GitHub
parent 13076fcef6
commit bd34a3bcd4
43 changed files with 887 additions and 1579 deletions

View File

@@ -1,15 +1,12 @@
use std::path::Path;
use std::process::Command;
use anyhow::Result;
use color_eyre::eyre::eyre;
use color_eyre::eyre::Context;
use color_eyre::eyre::Result;
use tracing::{debug, error, warn};
use crate::command::CommandExt;
use crate::error::{self, TopgradeError};
use crate::executor::CommandExt;
use crate::terminal::print_separator;
use crate::{execution_context::ExecutionContext, utils::require};
use log::{debug, error, warn};
use std::path::Path;
use std::process::Command;
// A string found in the output of docker for containers that weren't found in
// the docker registry. We use this to gracefully handle and skip containers
@@ -27,10 +24,11 @@ fn list_containers(crt: &Path) -> Result<Vec<String>> {
);
let output = Command::new(crt)
.args(["image", "ls", "--format", "{{.Repository}}:{{.Tag}}"])
.output_checked_with_utf8(|_| Ok(()))?;
.output()?;
let output_str = String::from_utf8(output.stdout)?;
let mut retval = vec![];
for line in output.stdout.lines() {
for line in output_str.lines() {
if line.starts_with("localhost") {
// Don't know how to update self-built containers
debug!("Skipping self-built container '{}'", line);
@@ -62,7 +60,7 @@ pub fn run_containers(ctx: &ExecutionContext) -> Result<()> {
print_separator("Containers");
let mut success = true;
let containers = list_containers(&crt).context("Failed to list Docker containers")?;
let containers = list_containers(&crt)?;
debug!("Containers to inspect: {:?}", containers);
for container in containers.iter() {
@@ -70,7 +68,7 @@ pub fn run_containers(ctx: &ExecutionContext) -> Result<()> {
let args = vec!["pull", &container[..]];
let mut exec = ctx.run_type().execute(&crt);
if let Err(e) = exec.args(&args).status_checked() {
if let Err(e) = exec.args(&args).check_run() {
error!("Pulling container '{}' failed: {}", container, e);
// Find out if this is 'skippable'
@@ -79,10 +77,10 @@ pub fn run_containers(ctx: &ExecutionContext) -> Result<()> {
// practical consequence that all containers, whether self-built, created by
// docker-compose or pulled from the docker hub, look exactly the same to us. We can
// only find out what went wrong by manually parsing the output of the command...
if match exec.output_checked_utf8() {
Ok(s) => s.stdout.contains(NONEXISTENT_REPO) || s.stderr.contains(NONEXISTENT_REPO),
if match exec.check_output() {
Ok(s) => s.contains(NONEXISTENT_REPO),
Err(e) => match e.downcast_ref::<TopgradeError>() {
Some(TopgradeError::ProcessFailedWithOutput(_, _, stderr)) => stderr.contains(NONEXISTENT_REPO),
Some(TopgradeError::ProcessFailedWithOutput(_, stderr)) => stderr.contains(NONEXISTENT_REPO),
_ => false,
},
} {
@@ -97,12 +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"])
.status_checked()
{
if let Err(e) = ctx.run_type().execute(&crt).args(["image", "prune", "-f"]).check_run() {
error!("Removing dangling images failed: {}", e);
success = false;
}
@@ -111,6 +104,6 @@ pub fn run_containers(ctx: &ExecutionContext) -> Result<()> {
if success {
Ok(())
} else {
Err(eyre!(error::StepFailed))
Err(anyhow::anyhow!(error::StepFailed))
}
}

View File

@@ -2,10 +2,9 @@
use std::env;
use std::path::{Path, PathBuf};
use color_eyre::eyre::Result;
use anyhow::Result;
use directories::BaseDirs;
use crate::command::CommandExt;
use crate::execution_context::ExecutionContext;
use crate::terminal::print_separator;
use crate::utils::{require, require_option, PathExt};
@@ -74,7 +73,7 @@ impl Emacs {
command.args(["upgrade"]);
command.status_checked()
command.check_run()
}
pub fn upgrade(&self, ctx: &ExecutionContext) -> Result<()> {
@@ -106,6 +105,6 @@ impl Emacs {
#[cfg(not(unix))]
command.arg(EMACS_UPGRADE);
command.status_checked()
command.check_run()
}
}

View File

@@ -5,16 +5,13 @@ use std::process::Command;
use std::{env, path::Path};
use std::{fs, io::Write};
use color_eyre::eyre::eyre;
use color_eyre::eyre::Context;
use color_eyre::eyre::Result;
use anyhow::Result;
use directories::BaseDirs;
use log::debug;
use tempfile::tempfile_in;
use tracing::debug;
use crate::command::{CommandExt, Utf8Output};
use crate::execution_context::ExecutionContext;
use crate::executor::{ExecutorOutput, RunType};
use crate::executor::{CommandExt, ExecutorOutput, RunType};
use crate::terminal::{print_separator, shell};
use crate::utils::{self, require_option, PathExt};
use crate::{
@@ -56,14 +53,28 @@ pub fn run_cargo_update(ctx: &ExecutionContext) -> Result<()> {
ctx.run_type()
.execute(cargo_update)
.args(["install-update", "--git", "--all"])
.status_checked()
.check_run()
}
pub fn run_flutter_upgrade(run_type: RunType) -> Result<()> {
let flutter = utils::require("flutter")?;
print_separator("Flutter");
run_type.execute(flutter).arg("upgrade").status_checked()
run_type.execute(flutter).arg("upgrade").check_run()
}
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 gopath = go_output.trim();
let go_global_update = utils::require("go-global-update")
.unwrap_or_else(|_| PathBuf::from(gopath).join("bin/go-global-update"))
.require()?;
print_separator("Go");
run_type.execute(go_global_update).check_run()
}
pub fn run_gem(base_dirs: &BaseDirs, run_type: RunType) -> Result<()> {
@@ -80,15 +91,14 @@ pub fn run_gem(base_dirs: &BaseDirs, run_type: RunType) -> Result<()> {
command.arg("--user-install");
}
command.status_checked()
command.check_run()
}
pub fn run_haxelib_update(ctx: &ExecutionContext) -> Result<()> {
let haxelib = utils::require("haxelib")?;
let haxelib_dir =
PathBuf::from(std::str::from_utf8(&Command::new(&haxelib).arg("config").output_checked()?.stdout)?.trim())
.require()?;
PathBuf::from(std::str::from_utf8(&Command::new(&haxelib).arg("config").output()?.stdout)?.trim()).require()?;
let directory_writable = tempfile_in(&haxelib_dir).is_ok();
debug!("{:?} writable: {}", haxelib_dir, directory_writable);
@@ -105,7 +115,7 @@ pub fn run_haxelib_update(ctx: &ExecutionContext) -> Result<()> {
c
};
command.arg("update").status_checked()
command.arg("update").check_run()
}
pub fn run_sheldon(ctx: &ExecutionContext) -> Result<()> {
@@ -113,10 +123,7 @@ pub fn run_sheldon(ctx: &ExecutionContext) -> Result<()> {
print_separator("Sheldon");
ctx.run_type()
.execute(sheldon)
.args(["lock", "--update"])
.status_checked()
ctx.run_type().execute(sheldon).args(["lock", "--update"]).check_run()
}
pub fn run_fossil(run_type: RunType) -> Result<()> {
@@ -124,7 +131,7 @@ pub fn run_fossil(run_type: RunType) -> Result<()> {
print_separator("Fossil");
run_type.execute(fossil).args(["all", "sync"]).status_checked()
run_type.execute(fossil).args(["all", "sync"]).check_run()
}
pub fn run_micro(run_type: RunType) -> Result<()> {
@@ -132,17 +139,13 @@ pub fn run_micro(run_type: RunType) -> Result<()> {
print_separator("micro");
let stdout = run_type
.execute(micro)
.args(["-plugin", "update"])
.output_checked_utf8()?
.stdout;
let stdout = run_type.execute(micro).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") {
Ok(())
} else {
Err(eyre!("micro output does not indicate success: {}", stdout))
Err(anyhow::anyhow!("micro output does not indicate success: {}", stdout))
}
}
@@ -157,10 +160,7 @@ pub fn run_apm(run_type: RunType) -> Result<()> {
print_separator("Atom Package Manager");
run_type
.execute(apm)
.args(["upgrade", "--confirm=false"])
.status_checked()
run_type.execute(apm).args(["upgrade", "--confirm=false"]).check_run()
}
pub fn run_rustup(base_dirs: &BaseDirs, run_type: RunType) -> Result<()> {
@@ -169,10 +169,10 @@ 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"]).status_checked()?;
run_type.execute(&rustup).args(["self", "update"]).check_run()?;
}
run_type.execute(&rustup).arg("update").status_checked()
run_type.execute(&rustup).arg("update").check_run()
}
pub fn run_choosenim(ctx: &ExecutionContext) -> Result<()> {
@@ -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"]).status_checked()?;
run_type.execute(&choosenim).args(["update", "stable"]).status_checked()
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"]).status_checked()
run_type.execute(krew).args(["upgrade"]).check_run()
}
pub fn run_gcloud_components_update(run_type: RunType) -> Result<()> {
@@ -204,7 +204,7 @@ pub fn run_gcloud_components_update(run_type: RunType) -> Result<()> {
run_type
.execute(gcloud)
.args(["components", "update", "--quiet"])
.status_checked()
.check_run()
}
}
@@ -213,7 +213,7 @@ pub fn run_jetpack(run_type: RunType) -> Result<()> {
print_separator("Jetpack");
run_type.execute(jetpack).args(["global", "update"]).status_checked()
run_type.execute(jetpack).args(["global", "update"]).check_run()
}
pub fn run_rtcl(ctx: &ExecutionContext) -> Result<()> {
@@ -221,7 +221,7 @@ pub fn run_rtcl(ctx: &ExecutionContext) -> Result<()> {
print_separator("rtcl");
ctx.run_type().execute(rupdate).status_checked()
ctx.run_type().execute(rupdate).check_run()
}
pub fn run_opam_update(ctx: &ExecutionContext) -> Result<()> {
@@ -229,11 +229,11 @@ pub fn run_opam_update(ctx: &ExecutionContext) -> Result<()> {
print_separator("OCaml Package Manager");
ctx.run_type().execute(&opam).arg("update").status_checked()?;
ctx.run_type().execute(&opam).arg("upgrade").status_checked()?;
ctx.run_type().execute(&opam).arg("update").check_run()?;
ctx.run_type().execute(&opam).arg("upgrade").check_run()?;
if ctx.config().cleanup() {
ctx.run_type().execute(&opam).arg("clean").status_checked()?;
ctx.run_type().execute(&opam).arg("clean").check_run()?;
}
Ok(())
@@ -243,17 +243,14 @@ 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"])
.status_checked()
run_type.execute(vcpkg).args(["upgrade", "--no-dry-run"]).check_run()
}
pub fn run_pipx_update(run_type: RunType) -> Result<()> {
let pipx = utils::require("pipx")?;
print_separator("pipx");
run_type.execute(pipx).arg("upgrade-all").status_checked()
run_type.execute(pipx).arg("upgrade-all").check_run()
}
pub fn run_conda_update(ctx: &ExecutionContext) -> Result<()> {
@@ -261,9 +258,10 @@ pub fn run_conda_update(ctx: &ExecutionContext) -> Result<()> {
let output = Command::new("conda")
.args(["config", "--show", "auto_activate_base"])
.output_checked_utf8()?;
debug!("Conda output: {}", output.stdout);
if output.stdout.contains("False") {
.output()?;
let string_output = String::from_utf8(output.stdout)?;
debug!("Conda output: {}", string_output);
if string_output.contains("False") {
return Err(SkipStep("auto_activate_base is set to False".to_string()).into());
}
@@ -272,14 +270,14 @@ pub fn run_conda_update(ctx: &ExecutionContext) -> Result<()> {
ctx.run_type()
.execute(conda)
.args(["update", "--all", "-y"])
.status_checked()
.check_run()
}
pub fn run_pip3_update(run_type: RunType) -> Result<()> {
let python3 = utils::require("python3")?;
Command::new(&python3)
.args(["-m", "pip"])
.output_checked_utf8()
.check_output()
.map_err(|_| SkipStep("pip does not exists".to_string()))?;
print_separator("pip3");
@@ -291,7 +289,7 @@ pub fn run_pip3_update(run_type: RunType) -> Result<()> {
run_type
.execute(&python3)
.args(["-m", "pip", "install", "--upgrade", "--user", "pip"])
.status_checked()
.check_run()
}
pub fn run_stack_update(run_type: RunType) -> Result<()> {
@@ -305,14 +303,14 @@ pub fn run_stack_update(run_type: RunType) -> Result<()> {
let stack = utils::require("stack")?;
print_separator("stack");
run_type.execute(stack).arg("upgrade").status_checked()
run_type.execute(stack).arg("upgrade").check_run()
}
pub fn run_ghcup_update(run_type: RunType) -> Result<()> {
let ghcup = utils::require("ghcup")?;
print_separator("ghcup");
run_type.execute(ghcup).arg("upgrade").status_checked()
run_type.execute(ghcup).arg("upgrade").check_run()
}
pub fn run_tlmgr_update(ctx: &ExecutionContext) -> Result<()> {
@@ -328,11 +326,13 @@ pub fn run_tlmgr_update(ctx: &ExecutionContext) -> Result<()> {
let kpsewhich = utils::require("kpsewhich")?;
let tlmgr_directory = {
let mut d = PathBuf::from(
&Command::new(kpsewhich)
.arg("-var-value=SELFAUTOPARENT")
.output_checked_utf8()?
.stdout
.trim(),
std::str::from_utf8(
&Command::new(kpsewhich)
.arg("-var-value=SELFAUTOPARENT")
.output()?
.stdout,
)?
.trim(),
);
d.push("tlpkg");
d
@@ -355,7 +355,7 @@ pub fn run_tlmgr_update(ctx: &ExecutionContext) -> Result<()> {
};
command.args(["update", "--self", "--all"]);
command.status_checked()
command.check_run()
}
pub fn run_chezmoi_update(base_dirs: &BaseDirs, run_type: RunType) -> Result<()> {
@@ -364,7 +364,7 @@ pub fn run_chezmoi_update(base_dirs: &BaseDirs, run_type: RunType) -> Result<()>
print_separator("chezmoi");
run_type.execute(chezmoi).arg("update").status_checked()
run_type.execute(chezmoi).arg("update").check_run()
}
pub fn run_myrepos_update(base_dirs: &BaseDirs, run_type: RunType) -> Result<()> {
@@ -378,27 +378,27 @@ pub fn run_myrepos_update(base_dirs: &BaseDirs, run_type: RunType) -> Result<()>
.arg("--directory")
.arg(base_dirs.home_dir())
.arg("checkout")
.status_checked()?;
.check_run()?;
run_type
.execute(&myrepos)
.arg("--directory")
.arg(base_dirs.home_dir())
.arg("update")
.status_checked()
.check_run()
}
pub fn run_custom_command(name: &str, command: &str, ctx: &ExecutionContext) -> Result<()> {
print_separator(name);
ctx.run_type().execute(shell()).arg("-c").arg(command).status_checked()
ctx.run_type().execute(shell()).arg("-c").arg(command).check_run()
}
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"])
.output_checked_utf8()
.check_output()
.map_err(|e| (SkipStep(format!("Error getting the composer directory: {}", e))))
.map(|s| PathBuf::from(s.stdout.trim()))?
.map(|s| PathBuf::from(s.trim()))?
.require()?;
if !composer_home.is_descendant_of(ctx.base_dirs().home_dir()) {
@@ -425,22 +425,26 @@ pub fn run_composer_update(ctx: &ExecutionContext) -> Result<()> {
.execute(ctx.sudo().as_ref().unwrap())
.arg(&composer)
.arg("self-update")
.status_checked()?;
.check_run()?;
}
} else {
ctx.run_type().execute(&composer).arg("self-update").status_checked()?;
ctx.run_type().execute(&composer).arg("self-update").check_run()?;
}
}
}
let output = ctx.run_type().execute(&composer).args(["global", "update"]).output()?;
if let ExecutorOutput::Wet(output) = output {
let output: Utf8Output = output.try_into()?;
print!("{}\n{}", output.stdout, output.stderr);
if output.stdout.contains("valet") || output.stderr.contains("valet") {
if let Some(valet) = utils::which("valet") {
ctx.run_type().execute(valet).arg("install").status_checked()?;
}
let output = Command::new(&composer).args(["global", "update"]).output()?;
let status = output.status;
if !status.success() {
return Err(TopgradeError::ProcessFailed(status).into());
}
let stdout = String::from_utf8(output.stdout)?;
let stderr = String::from_utf8(output.stderr)?;
print!("{}\n{}", stdout, stderr);
if stdout.contains("valet") || stderr.contains("valet") {
if let Some(valet) = utils::which("valet") {
ctx.run_type().execute(valet).arg("install").check_run()?;
}
}
@@ -450,15 +454,18 @@ 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_checked_utf8()?;
let output = Command::new(dotnet).args(["tool", "list", "--global"]).output()?;
if !output.stdout.starts_with("Package Id") {
if !output.status.success() {
return Err(SkipStep(format!("dotnet failed with exit code {:?}", output.status)).into());
}
let output = String::from_utf8(output.stdout)?;
if !output.starts_with("Package Id") {
return Err(SkipStep(String::from("dotnet did not output packages")).into());
}
let mut packages = output.stdout.lines().skip(2).filter(|line| !line.is_empty()).peekable();
let mut packages = output.split('\n').skip(2).filter(|line| !line.is_empty()).peekable();
if packages.peek().is_none() {
return Err(SkipStep(String::from("No dotnet global tools installed")).into());
@@ -471,8 +478,7 @@ pub fn run_dotnet_upgrade(ctx: &ExecutionContext) -> Result<()> {
ctx.run_type()
.execute("dotnet")
.args(["tool", "update", package_name, "--global"])
.status_checked()
.with_context(|| format!("Failed to update .NET package {package_name}"))?;
.check_run()?;
}
Ok(())
@@ -483,26 +489,26 @@ pub fn run_raco_update(run_type: RunType) -> Result<()> {
print_separator("Racket Package Manager");
run_type.execute(raco).args(["pkg", "update", "--all"]).status_checked()
run_type.execute(raco).args(["pkg", "update", "--all"]).check_run()
}
pub fn bin_update(ctx: &ExecutionContext) -> Result<()> {
let bin = utils::require("bin")?;
print_separator("Bin");
ctx.run_type().execute(bin).arg("update").status_checked()
ctx.run_type().execute(bin).arg("update").check_run()
}
pub fn spicetify_upgrade(ctx: &ExecutionContext) -> Result<()> {
let spicetify = utils::require("spicetify")?;
print_separator("Spicetify");
ctx.run_type().execute(spicetify).arg("upgrade").status_checked()
ctx.run_type().execute(spicetify).arg("upgrade").check_run()
}
pub fn run_ghcli_extensions_upgrade(ctx: &ExecutionContext) -> Result<()> {
let gh = utils::require("gh")?;
let result = Command::new(&gh).args(["extensions", "list"]).output_checked_utf8();
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());
@@ -512,7 +518,7 @@ pub fn run_ghcli_extensions_upgrade(ctx: &ExecutionContext) -> Result<()> {
ctx.run_type()
.execute(&gh)
.args(["extension", "upgrade", "--all"])
.status_checked()
.check_run()
}
pub fn update_julia_packages(ctx: &ExecutionContext) -> Result<()> {
@@ -523,5 +529,5 @@ pub fn update_julia_packages(ctx: &ExecutionContext) -> Result<()> {
ctx.run_type()
.execute(julia)
.args(["-e", "using Pkg; Pkg.update()"])
.status_checked()
.check_run()
}

View File

@@ -3,18 +3,17 @@ use std::io;
use std::path::{Path, PathBuf};
use std::process::{Command, Output, Stdio};
use color_eyre::eyre::{eyre, Result};
use anyhow::{anyhow, Result};
use console::style;
use futures::stream::{iter, FuturesUnordered};
use futures::StreamExt;
use glob::{glob_with, MatchOptions};
use log::{debug, error};
use tokio::process::Command as AsyncCommand;
use tokio::runtime;
use tracing::{debug, error};
use crate::command::CommandExt;
use crate::execution_context::ExecutionContext;
use crate::executor::RunType;
use crate::executor::{CommandExt, RunType};
use crate::terminal::print_separator;
use crate::utils::{which, PathExt};
use crate::{error::SkipStep, terminal::print_warning};
@@ -34,10 +33,10 @@ pub struct Repositories<'a> {
bad_patterns: Vec<String>,
}
fn output_checked_utf8(output: Output) -> Result<()> {
fn check_output(output: Output) -> Result<()> {
if !(output.status.success()) {
let stderr = String::from_utf8(output.stderr).unwrap();
Err(eyre!(stderr))
Err(anyhow!(stderr))
} else {
Ok(())
}
@@ -67,7 +66,7 @@ async fn pull_repository(repo: String, git: &Path, ctx: &ExecutionContext<'_>) -
.stdin(Stdio::null())
.output()
.await?;
let result = output_checked_utf8(pull_output).and_then(|_| output_checked_utf8(submodule_output));
let result = check_output(pull_output).and_then(|_| check_output(submodule_output));
if let Err(message) = &result {
println!("{} pulling {}", style("Failed").red().bold(), &repo);
@@ -89,7 +88,10 @@ async fn pull_repository(repo: String, git: &Path, ctx: &ExecutionContext<'_>) -
"--oneline",
&format!("{}..{}", before, after),
])
.status_checked()?;
.spawn()
.unwrap()
.wait()
.unwrap();
println!();
}
_ => {
@@ -106,8 +108,8 @@ fn get_head_revision(git: &Path, repo: &str) -> Option<String> {
.stdin(Stdio::null())
.current_dir(repo)
.args(["rev-parse", "HEAD"])
.output_checked_utf8()
.map(|output| output.stdout.trim().to_string())
.check_output()
.map(|output| output.trim().to_string())
.map_err(|e| {
error!("Error getting revision for {}: {}", repo, e);
@@ -121,8 +123,8 @@ fn has_remotes(git: &Path, repo: &str) -> Option<bool> {
.stdin(Stdio::null())
.current_dir(repo)
.args(["remote", "show"])
.output_checked_utf8()
.map(|output| output.stdout.lines().count() > 0)
.check_output()
.map(|output| output.lines().count() > 0)
.map_err(|e| {
error!("Error getting remotes for {}: {}", repo, e);
e
@@ -164,9 +166,9 @@ impl Git {
.stdin(Stdio::null())
.current_dir(path)
.args(["rev-parse", "--show-toplevel"])
.output_checked_utf8()
.check_output()
.ok()
.map(|output| output.stdout.trim().to_string());
.map(|output| output.trim().to_string());
return output;
}
}

View File

@@ -1,45 +0,0 @@
use std::path::PathBuf;
use std::process::Command;
use color_eyre::eyre::Result;
use crate::command::CommandExt;
use crate::executor::RunType;
use crate::terminal::print_separator;
use crate::utils;
use crate::utils::PathExt;
/// <https://github.com/Gelio/go-global-update>
pub fn run_go_global_update(run_type: RunType) -> Result<()> {
let go_global_update = require_go_bin("go-global-update")?;
print_separator("go-global-update");
run_type.execute(go_global_update).status_checked()
}
/// <https://github.com/nao1215/gup>
pub fn run_go_gup(run_type: RunType) -> Result<()> {
let gup = require_go_bin("gup")?;
print_separator("gup");
run_type.execute(gup).arg("update").status_checked()
}
/// Get the path of a Go binary.
fn require_go_bin(name: &str) -> Result<PathBuf> {
utils::require(name).or_else(|_| {
let go = utils::require("go")?;
// TODO: Does this work? `go help gopath` says that:
// > The GOPATH environment variable lists places to look for Go code.
// > On Unix, the value is a colon-separated string.
// > On Windows, the value is a semicolon-separated string.
// > On Plan 9, the value is a list.
// Should we also fallback to the env variable?
let gopath_output = Command::new(go).args(["env", "GOPATH"]).output_checked_utf8()?;
let gopath = gopath_output.stdout.trim();
PathBuf::from(gopath).join("bin").join(name).require()
})
}

View File

@@ -1,8 +1,10 @@
use crate::error::TopgradeError;
use crate::terminal::print_separator;
use crate::utils::require;
use color_eyre::eyre::Result;
use anyhow::Result;
use crate::execution_context::ExecutionContext;
use crate::executor::ExecutorOutput;
const UPGRADE_KAK: &str = include_str!("upgrade.kak");
@@ -11,13 +13,19 @@ pub fn upgrade_kak_plug(ctx: &ExecutionContext) -> Result<()> {
print_separator("Kakoune");
// TODO: Why supress output for this command?
ctx.run_type()
.execute(kak)
.args(["-ui", "dummy", "-e", UPGRADE_KAK])
.output()?;
let mut command = ctx.run_type().execute(kak);
command.args(["-ui", "dummy", "-e", UPGRADE_KAK]);
println!("Plugins upgraded");
let output = command.output()?;
if let ExecutorOutput::Wet(output) = output {
let status = output.status;
if !status.success() {
return Err(TopgradeError::ProcessFailed(status).into());
} else {
println!("Plugins upgraded")
}
}
Ok(())
}

View File

@@ -2,7 +2,6 @@ pub mod containers;
pub mod emacs;
pub mod generic;
pub mod git;
pub mod go;
pub mod kakoune;
pub mod node;
pub mod os;

View File

@@ -1,20 +1,20 @@
#![allow(unused_imports)]
use std::fmt::Display;
#[cfg(target_os = "linux")]
use std::os::unix::fs::MetadataExt;
#[cfg(unix)]
use std::os::unix::prelude::MetadataExt;
use std::path::PathBuf;
use std::process::Command;
use crate::utils::require_option;
use color_eyre::eyre::Result;
#[cfg(target_os = "linux")]
use anyhow::Result;
use directories::BaseDirs;
use log::debug;
#[cfg(unix)]
use nix::unistd::Uid;
use semver::Version;
use tracing::debug;
use crate::command::CommandExt;
use crate::executor::RunType;
use crate::executor::{CommandExt, RunType};
use crate::terminal::print_separator;
use crate::utils::sudo;
use crate::utils::{require, PathExt};
use crate::{error::SkipStep, execution_context::ExecutionContext};
@@ -24,6 +24,13 @@ enum NPMVariant {
}
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",
@@ -78,26 +85,25 @@ impl NPM {
let args = ["root", self.global_location_arg()];
Command::new(&self.command)
.args(args)
.output_checked_utf8()
.map(|s| PathBuf::from(s.stdout.trim()))
.check_output()
.map(|s| PathBuf::from(s.trim()))
}
fn version(&self) -> Result<Version> {
let version_str = Command::new(&self.command)
.args(["--version"])
.output_checked_utf8()
.map(|s| s.stdout.trim().to_owned());
.check_output()
.map(|s| s.trim().to_owned());
Version::parse(&version_str?).map_err(|err| err.into())
}
fn upgrade(&self, run_type: RunType, use_sudo: bool) -> Result<()> {
print_separator(self.variant.long_name());
let args = ["update", self.global_location_arg()];
if use_sudo {
let sudo_option = sudo();
let sudo = require_option(sudo_option, String::from("sudo is not installed"))?;
run_type.execute(sudo).arg(&self.command).args(args).status_checked()?;
run_type.execute("sudo").args(args).check_run()?;
} else {
run_type.execute(&self.command).args(args).status_checked()?;
run_type.execute(&self.command).args(args).check_run()?;
}
Ok(())
@@ -136,9 +142,9 @@ impl Yarn {
//
// 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"]).output_checked_utf8();
let version = Command::new(&self.command).args(["--version"]).check_output();
matches!(version, Ok(ver) if ver.stdout.starts_with('1') || ver.stdout.starts_with('0'))
matches!(version, Ok(ver) if ver.starts_with('1') || ver.starts_with('0'))
}
#[cfg(target_os = "linux")]
@@ -146,11 +152,12 @@ impl Yarn {
let args = ["global", "dir"];
Command::new(&self.command)
.args(args)
.output_checked_utf8()
.map(|s| PathBuf::from(s.stdout.trim()))
.check_output()
.map(|s| PathBuf::from(s.trim()))
}
fn upgrade(&self, run_type: RunType, use_sudo: bool) -> Result<()> {
print_separator("Yarn Package Manager");
let args = ["global", "upgrade"];
if use_sudo {
@@ -158,9 +165,9 @@ impl Yarn {
.execute("sudo")
.arg(self.yarn.as_ref().unwrap_or(&self.command))
.args(args)
.status_checked()?;
.check_run()?;
} else {
run_type.execute(&self.command).args(args).status_checked()?;
run_type.execute(&self.command).args(args).check_run()?;
}
Ok(())
@@ -211,8 +218,6 @@ fn should_use_sudo_yarn(yarn: &Yarn, ctx: &ExecutionContext) -> Result<bool> {
pub fn run_npm_upgrade(ctx: &ExecutionContext) -> Result<()> {
let npm = require("npm").map(|b| NPM::new(b, NPMVariant::Npm))?;
print_separator("Node Package Manager");
#[cfg(target_os = "linux")]
{
npm.upgrade(ctx.run_type(), should_use_sudo(&npm, ctx)?)
@@ -227,8 +232,6 @@ 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))?;
print_separator("Node Package Manager");
#[cfg(target_os = "linux")]
{
pnpm.upgrade(ctx.run_type(), should_use_sudo(&pnpm, ctx)?)
@@ -248,8 +251,6 @@ pub fn run_yarn_upgrade(ctx: &ExecutionContext) -> Result<()> {
return Ok(());
}
print_separator("Yarn Package Manager");
#[cfg(target_os = "linux")]
{
yarn.upgrade(ctx.run_type(), should_use_sudo_yarn(&yarn, ctx)?)
@@ -271,5 +272,5 @@ pub fn deno_upgrade(ctx: &ExecutionContext) -> Result<()> {
}
print_separator("Deno");
ctx.run_type().execute(&deno).arg("upgrade").status_checked()
ctx.run_type().execute(&deno).arg("upgrade").check_run()
}

View File

@@ -1,10 +1,8 @@
use crate::command::CommandExt;
use crate::execution_context::ExecutionContext;
use crate::terminal::print_separator;
use crate::utils::require;
use crate::utils::which;
use crate::Step;
use color_eyre::eyre::Result;
use anyhow::Result;
pub fn upgrade_packages(ctx: &ExecutionContext) -> Result<()> {
//let pkg = require("pkg")?;
@@ -12,7 +10,7 @@ pub fn upgrade_packages(ctx: &ExecutionContext) -> Result<()> {
print_separator("Termux Packages");
let is_nala = pkg.ends_with("nala");
let is_nala = pkg.end_with("nala");
let mut command = ctx.run_type().execute(&pkg);
command.arg("upgrade");
@@ -20,18 +18,20 @@ pub fn upgrade_packages(ctx: &ExecutionContext) -> Result<()> {
if ctx.config().yes(Step::System) {
command.arg("-y");
}
command.status_checked()?;
command.check_run()?;
if !is_nala && ctx.config().cleanup() {
ctx.run_type().execute(&pkg).arg("clean").status_checked()?;
if !is_nala {
if ctx.config().cleanup() {
ctx.run_type().execute(&pkg).arg("clean").check_run()?;
let apt = require("apt")?;
let mut command = ctx.run_type().execute(&apt);
command.arg("autoremove");
if ctx.config().yes(Step::System) {
command.arg("-y");
let apt = require("apt")?;
let mut command = ctx.run_type().execute(&apt);
command.arg("autoremove");
if ctx.config().yes(Step::System) {
command.arg("-y");
}
command.check_run()?;
}
command.status_checked()?;
}
Ok(())

View File

@@ -3,11 +3,9 @@ use std::ffi::OsString;
use std::path::{Path, PathBuf};
use std::process::Command;
use color_eyre::eyre;
use color_eyre::eyre::Result;
use anyhow::Result;
use walkdir::WalkDir;
use crate::command::CommandExt;
use crate::error::TopgradeError;
use crate::execution_context::ExecutionContext;
use crate::utils::which;
@@ -31,7 +29,11 @@ pub struct YayParu {
impl ArchPackageManager for YayParu {
fn upgrade(&self, ctx: &ExecutionContext) -> Result<()> {
if ctx.config().show_arch_news() {
Command::new(&self.executable).arg("-Pw").status_checked()?;
Command::new(&self.executable)
.arg("-Pw")
.spawn()
.and_then(|mut p| p.wait())
.ok();
}
let mut command = ctx.run_type().execute(&self.executable);
@@ -46,7 +48,7 @@ impl ArchPackageManager for YayParu {
if ctx.config().yes(Step::System) {
command.arg("--noconfirm");
}
command.status_checked()?;
command.check_run()?;
if ctx.config().cleanup() {
let mut command = ctx.run_type().execute(&self.executable);
@@ -54,7 +56,7 @@ impl ArchPackageManager for YayParu {
if ctx.config().yes(Step::System) {
command.arg("--noconfirm");
}
command.status_checked()?;
command.check_run()?;
}
Ok(())
@@ -86,7 +88,7 @@ impl ArchPackageManager for Trizen {
if ctx.config().yes(Step::System) {
command.arg("--noconfirm");
}
command.status_checked()?;
command.check_run()?;
if ctx.config().cleanup() {
let mut command = ctx.run_type().execute(&self.executable);
@@ -94,7 +96,7 @@ impl ArchPackageManager for Trizen {
if ctx.config().yes(Step::System) {
command.arg("--noconfirm");
}
command.status_checked()?;
command.check_run()?;
}
Ok(())
@@ -124,7 +126,7 @@ impl ArchPackageManager for Pacman {
if ctx.config().yes(Step::System) {
command.arg("--noconfirm");
}
command.status_checked()?;
command.check_run()?;
if ctx.config().cleanup() {
let mut command = ctx.run_type().execute(&self.sudo);
@@ -132,7 +134,7 @@ impl ArchPackageManager for Pacman {
if ctx.config().yes(Step::System) {
command.arg("--noconfirm");
}
command.status_checked()?;
command.check_run()?;
}
Ok(())
@@ -173,7 +175,7 @@ impl ArchPackageManager for Pikaur {
command.arg("--noconfirm");
}
command.status_checked()?;
command.check_run()?;
if ctx.config().cleanup() {
let mut command = ctx.run_type().execute(&self.executable);
@@ -181,7 +183,7 @@ impl ArchPackageManager for Pikaur {
if ctx.config().yes(Step::System) {
command.arg("--noconfirm");
}
command.status_checked()?;
command.check_run()?;
}
Ok(())
@@ -212,7 +214,7 @@ impl ArchPackageManager for Pamac {
command.arg("--no-confirm");
}
command.status_checked()?;
command.check_run()?;
if ctx.config().cleanup() {
let mut command = ctx.run_type().execute(&self.executable);
@@ -220,7 +222,7 @@ impl ArchPackageManager for Pamac {
if ctx.config().yes(Step::System) {
command.arg("--no-confirm");
}
command.status_checked()?;
command.check_run()?;
}
Ok(())
@@ -255,7 +257,7 @@ impl ArchPackageManager for Aura {
aur_update.arg("--noconfirm");
}
aur_update.status_checked()?;
aur_update.check_run()?;
} else {
println!("Aura requires sudo installed to work with AUR packages")
}
@@ -268,7 +270,7 @@ impl ArchPackageManager for Aura {
if ctx.config().yes(Step::System) {
pacman_update.arg("--noconfirm");
}
pacman_update.status_checked()?;
pacman_update.check_run()?;
Ok(())
}
@@ -302,7 +304,7 @@ pub fn get_arch_package_manager(ctx: &ExecutionContext) -> Option<Box<dyn ArchPa
pub fn upgrade_arch_linux(ctx: &ExecutionContext) -> Result<()> {
let package_manager =
get_arch_package_manager(ctx).ok_or_else(|| eyre::Report::from(TopgradeError::FailedGettingPackageManager))?;
get_arch_package_manager(ctx).ok_or_else(|| anyhow::Error::from(TopgradeError::FailedGettingPackageManager))?;
package_manager.upgrade(ctx)
}

View File

@@ -1,26 +1,26 @@
use crate::command::CommandExt;
use crate::executor::RunType;
use crate::terminal::print_separator;
use crate::utils::require_option;
use color_eyre::eyre::Result;
use anyhow::Result;
use std::path::PathBuf;
use std::process::Command;
pub fn upgrade_packages(sudo: Option<&PathBuf>, run_type: RunType) -> Result<()> {
let sudo = require_option(sudo, String::from("No sudo detected"))?;
print_separator("DragonFly BSD Packages");
print_separator("DrgaonFly BSD Packages");
run_type
.execute(sudo)
.args(["/usr/local/sbin/pkg", "upgrade"])
.status_checked()
.args(&["/usr/local/sbin/pkg", "upgrade"])
.check_run()
}
pub fn audit_packages(sudo: &Option<PathBuf>) -> Result<()> {
if let Some(sudo) = sudo {
println!();
Command::new(sudo)
.args(["/usr/local/sbin/pkg", "audit", "-Fr"])
.status_checked()?;
.args(&["/usr/local/sbin/pkg", "audit", "-Fr"])
.spawn()?
.wait()?;
}
Ok(())
}

View File

@@ -1,10 +1,7 @@
use crate::command::CommandExt;
use crate::execution_context::ExecutionContext;
use crate::executor::RunType;
use crate::terminal::print_separator;
use crate::utils::require_option;
use crate::Step;
use color_eyre::eyre::Result;
use anyhow::Result;
use std::path::PathBuf;
use std::process::Command;
@@ -13,29 +10,23 @@ pub fn upgrade_freebsd(sudo: Option<&PathBuf>, run_type: RunType) -> Result<()>
print_separator("FreeBSD Update");
run_type
.execute(sudo)
.args(["/usr/sbin/freebsd-update", "fetch", "install"])
.status_checked()
.args(&["/usr/sbin/freebsd-update", "fetch", "install"])
.check_run()
}
pub fn upgrade_packages(ctx: &ExecutionContext, sudo: Option<&PathBuf>, run_type: RunType) -> Result<()> {
pub fn upgrade_packages(sudo: Option<&PathBuf>, run_type: RunType) -> Result<()> {
let sudo = require_option(sudo, String::from("No sudo detected"))?;
print_separator("FreeBSD Packages");
let mut command = run_type.execute(sudo);
command.args(["/usr/sbin/pkg", "upgrade"]);
if ctx.config().yes(Step::System) {
command.arg("-y");
}
command.status_checked()
run_type.execute(sudo).args(&["/usr/sbin/pkg", "upgrade"]).check_run()
}
pub fn audit_packages(sudo: &Option<PathBuf>) -> Result<()> {
if let Some(sudo) = sudo {
println!();
Command::new(sudo)
.args(["/usr/sbin/pkg", "audit", "-Fr"])
.status_checked()?;
.args(&["/usr/sbin/pkg", "audit", "-Fr"])
.spawn()?
.wait()?;
}
Ok(())
}

View File

@@ -1,14 +1,13 @@
use std::path::{Path, PathBuf};
use std::process::Command;
use color_eyre::eyre::Result;
use anyhow::Result;
use ini::Ini;
use tracing::{debug, warn};
use log::{debug, warn};
use crate::command::CommandExt;
use crate::error::{SkipStep, TopgradeError};
use crate::execution_context::ExecutionContext;
use crate::executor::RunType;
use crate::executor::{CommandExt, RunType};
use crate::steps::os::archlinux;
use crate::terminal::{print_separator, print_warning};
use crate::utils::{require, require_option, which, PathExt};
@@ -128,10 +127,11 @@ fn update_bedrock(ctx: &ExecutionContext) -> Result<()> {
ctx.run_type().execute(sudo).args(["brl", "update"]);
let output = Command::new("brl").arg("list").output_checked_utf8()?;
let output = Command::new("brl").arg("list").output()?;
debug!("brl list: {:?} {:?}", output.stdout, output.stderr);
for distribution in output.stdout.trim().lines() {
let parsed_output = String::from_utf8(output.stdout).unwrap();
for distribution in parsed_output.trim().split('\n') {
debug!("Bedrock distribution {}", distribution);
match distribution {
"arch" => archlinux::upgrade_arch_linux(ctx)?,
@@ -148,7 +148,7 @@ fn update_bedrock(ctx: &ExecutionContext) -> Result<()> {
}
fn is_wsl() -> Result<bool> {
let output = Command::new("uname").arg("-r").output_checked_utf8()?.stdout;
let output = Command::new("uname").arg("-r").check_output()?;
debug!("Uname output: {}", output);
Ok(output.contains("microsoft"))
}
@@ -157,8 +157,8 @@ fn upgrade_alpine_linux(ctx: &ExecutionContext) -> Result<()> {
let apk = require("apk")?;
let sudo = ctx.sudo().as_ref().unwrap();
ctx.run_type().execute(sudo).arg(&apk).arg("update").status_checked()?;
ctx.run_type().execute(sudo).arg(&apk).arg("upgrade").status_checked()
ctx.run_type().execute(sudo).arg(&apk).arg("update").check_run()?;
ctx.run_type().execute(sudo).arg(&apk).arg("upgrade").check_run()
}
fn upgrade_redhat(ctx: &ExecutionContext) -> Result<()> {
@@ -166,7 +166,7 @@ fn upgrade_redhat(ctx: &ExecutionContext) -> Result<()> {
if ctx.config().rpm_ostree() {
let mut command = ctx.run_type().execute(ostree);
command.arg("upgrade");
return command.status_checked();
return command.check_run();
}
};
@@ -188,7 +188,7 @@ fn upgrade_redhat(ctx: &ExecutionContext) -> Result<()> {
command.arg("-y");
}
command.status_checked()?;
command.check_run()?;
} else {
print_warning("No sudo detected. Skipping system upgrade");
}
@@ -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"]).status_checked()?;
ctx.run_type().execute(sudo).args(["brl", "update"]).check_run()?;
} else {
print_warning("No sudo detected. Skipping system upgrade");
}
@@ -208,15 +208,12 @@ 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"])
.status_checked()?;
ctx.run_type().execute(sudo).args(["zypper", "refresh"]).check_run()?;
ctx.run_type()
.execute(sudo)
.args(["zypper", "dist-upgrade"])
.status_checked()?;
.check_run()?;
} else {
print_warning("No sudo detected. Skipping system upgrade");
}
@@ -238,7 +235,7 @@ fn upgrade_openmandriva(ctx: &ExecutionContext) -> Result<()> {
command.arg("-y");
}
command.status_checked()?;
command.check_run()?;
} else {
print_warning("No sudo detected. Skipping system upgrade");
}
@@ -253,14 +250,14 @@ fn upgrade_void(ctx: &ExecutionContext) -> Result<()> {
if ctx.config().yes(Step::System) {
command.arg("-y");
}
command.status_checked()?;
command.check_run()?;
let mut command = ctx.run_type().execute(sudo);
command.args(["xbps-install", "-u"]);
if ctx.config().yes(Step::System) {
command.arg("-y");
}
command.status_checked()?;
command.check_run()?;
} else {
print_warning("No sudo detected. Skipping system upgrade");
}
@@ -273,11 +270,7 @@ 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"])
.status_checked()?;
run_type.execute(sudo).arg(layman).args(["-s", "ALL"]).check_run()?;
}
println!("Syncing portage");
@@ -290,10 +283,10 @@ fn upgrade_gentoo(ctx: &ExecutionContext) -> Result<()> {
.map(|s| s.split_whitespace().collect())
.unwrap_or_else(|| vec!["-q"]),
)
.status_checked()?;
.check_run()?;
if let Some(eix_update) = which("eix-update") {
run_type.execute(sudo).arg(eix_update).status_checked()?;
run_type.execute(sudo).arg(eix_update).check_run()?;
}
run_type
@@ -305,7 +298,7 @@ fn upgrade_gentoo(ctx: &ExecutionContext) -> Result<()> {
.map(|s| s.split_whitespace().collect())
.unwrap_or_else(|| vec!["-uDNa", "--with-bdeps=y", "world"]),
)
.status_checked()?;
.check_run()?;
} else {
print_warning("No sudo detected. Skipping system upgrade");
}
@@ -321,7 +314,7 @@ 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").status_checked()?;
ctx.run_type().execute(sudo).arg(&apt).arg("update").check_run()?;
}
let mut command = ctx.run_type().execute(sudo);
@@ -337,17 +330,17 @@ fn upgrade_debian(ctx: &ExecutionContext) -> Result<()> {
if let Some(args) = ctx.config().apt_arguments() {
command.args(args.split_whitespace());
}
command.status_checked()?;
command.check_run()?;
if ctx.config().cleanup() {
ctx.run_type().execute(sudo).arg(&apt).arg("clean").status_checked()?;
ctx.run_type().execute(sudo).arg(&apt).arg("clean").check_run()?;
let mut command = ctx.run_type().execute(sudo);
command.arg(&apt).arg("autoremove");
if ctx.config().yes(Step::System) {
command.arg("-y");
}
command.status_checked()?;
command.check_run()?;
}
} else {
print_warning("No sudo detected. Skipping system upgrade");
@@ -361,11 +354,11 @@ pub fn run_deb_get(ctx: &ExecutionContext) -> Result<()> {
print_separator("deb-get");
ctx.execute_elevated(&deb_get, false)?.arg("update").status_checked()?;
ctx.execute_elevated(&deb_get, false)?.arg("upgrade").status_checked()?;
ctx.execute_elevated(&deb_get, false)?.arg("update").check_run()?;
ctx.execute_elevated(&deb_get, false)?.arg("upgrade").check_run()?;
if ctx.config().cleanup() {
ctx.execute_elevated(&deb_get, false)?.arg("clean").status_checked()?;
ctx.execute_elevated(&deb_get, false)?.arg("clean").check_run()?;
}
Ok(())
@@ -373,10 +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"])
.status_checked()?;
ctx.run_type().execute(sudo).args(["eopkg", "upgrade"]).check_run()?;
} else {
print_warning("No sudo detected. Skipping system upgrade");
}
@@ -389,10 +379,10 @@ pub fn run_pacdef(ctx: &ExecutionContext) -> Result<()> {
print_separator("pacdef");
ctx.run_type().execute(&pacdef).arg("sync").status_checked()?;
ctx.run_type().execute(&pacdef).arg("sync").check_run()?;
println!();
ctx.run_type().execute(&pacdef).arg("review").status_checked()
ctx.run_type().execute(&pacdef).arg("review").check_run()
}
pub fn run_pacstall(ctx: &ExecutionContext) -> Result<()> {
@@ -400,16 +390,13 @@ pub fn run_pacstall(ctx: &ExecutionContext) -> Result<()> {
print_separator("Pacstall");
ctx.run_type().execute(&pacstall).arg("-U").status_checked()?;
ctx.run_type().execute(pacstall).arg("-Up").status_checked()
ctx.run_type().execute(&pacstall).arg("-U").check_run()?;
ctx.run_type().execute(pacstall).arg("-Up").check_run()
}
fn upgrade_clearlinux(ctx: &ExecutionContext) -> Result<()> {
if let Some(sudo) = &ctx.sudo() {
ctx.run_type()
.execute(sudo)
.args(["swupd", "update"])
.status_checked()?;
ctx.run_type().execute(sudo).args(["swupd", "update"]).check_run()?;
} else {
print_warning("No sudo detected. Skipping system upgrade");
}
@@ -419,29 +406,26 @@ 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"]).status_checked()?;
ctx.run_type().execute(sudo).args(["cave", "sync"]).check_run()?;
ctx.run_type()
.execute(sudo)
.args(["cave", "resolve", "world", "-c1", "-Cs", "-km", "-Km", "-x"])
.status_checked()?;
.check_run()?;
if ctx.config().cleanup() {
ctx.run_type()
.execute(sudo)
.args(["cave", "purge", "-x"])
.status_checked()?;
ctx.run_type().execute(sudo).args(["cave", "purge", "-x"]).check_run()?;
}
ctx.run_type()
.execute(sudo)
.args(["cave", "fix-linkage", "-x", "--", "-Cs"])
.status_checked()?;
.check_run()?;
ctx.run_type()
.execute(sudo)
.args(["eclectic", "config", "interactive"])
.status_checked()?;
.check_run()?;
} else {
print_warning("No sudo detected. Skipping system upgrade");
}
@@ -454,13 +438,13 @@ fn upgrade_nixos(ctx: &ExecutionContext) -> Result<()> {
ctx.run_type()
.execute(sudo)
.args(["/run/current-system/sw/bin/nixos-rebuild", "switch", "--upgrade"])
.status_checked()?;
.check_run()?;
if ctx.config().cleanup() {
ctx.run_type()
.execute(sudo)
.args(["/run/current-system/sw/bin/nix-collect-garbage", "-d"])
.status_checked()?;
.check_run()?;
}
} else {
print_warning("No sudo detected. Skipping system upgrade");
@@ -478,11 +462,7 @@ 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")
.status_checked()?;
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) {
@@ -492,7 +472,7 @@ fn upgrade_neon(ctx: &ExecutionContext) -> Result<()> {
cmd.arg("--autoremove");
}
// from pkcon man, exit code 5 is 'Nothing useful was done.'
cmd.status_checked_with_codes(&[5])?;
cmd.check_run_with_codes(&[5])?;
}
Ok(())
@@ -509,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).status_checked()?;
run_type.execute(sudo).arg(needrestart).check_run()?;
Ok(())
}
@@ -526,7 +506,7 @@ pub fn run_fwupdmgr(ctx: &ExecutionContext) -> Result<()> {
ctx.run_type()
.execute(&fwupdmgr)
.arg("refresh")
.status_checked_with_codes(&[2])?;
.check_run_with_codes(&[2])?;
let mut updmgr = ctx.run_type().execute(&fwupdmgr);
@@ -538,7 +518,7 @@ pub fn run_fwupdmgr(ctx: &ExecutionContext) -> Result<()> {
} else {
updmgr.arg("get-updates");
}
updmgr.status_checked_with_codes(&[2])
updmgr.check_run_with_codes(&[2])
}
pub fn flatpak_update(ctx: &ExecutionContext) -> Result<()> {
@@ -553,14 +533,14 @@ pub fn flatpak_update(ctx: &ExecutionContext) -> Result<()> {
if yes {
update_args.push("-y");
}
run_type.execute(&flatpak).args(&update_args).status_checked()?;
run_type.execute(&flatpak).args(&update_args).check_run()?;
if cleanup {
let mut cleanup_args = vec!["uninstall", "--user", "--unused"];
if yes {
cleanup_args.push("-y");
}
run_type.execute(&flatpak).args(&cleanup_args).status_checked()?;
run_type.execute(&flatpak).args(&cleanup_args).check_run()?;
}
print_separator("Flatpak System Packages");
@@ -569,34 +549,26 @@ pub fn flatpak_update(ctx: &ExecutionContext) -> Result<()> {
if yes {
update_args.push("-y");
}
run_type
.execute(sudo)
.arg(&flatpak)
.args(&update_args)
.status_checked()?;
run_type.execute(sudo).arg(&flatpak).args(&update_args).check_run()?;
if cleanup {
let mut cleanup_args = vec!["uninstall", "--system", "--unused"];
if yes {
cleanup_args.push("-y");
}
run_type
.execute(sudo)
.arg(flatpak)
.args(&cleanup_args)
.status_checked()?;
run_type.execute(sudo).arg(flatpak).args(&cleanup_args).check_run()?;
}
} else {
let mut update_args = vec!["update", "--system"];
if yes {
update_args.push("-y");
}
run_type.execute(&flatpak).args(&update_args).status_checked()?;
run_type.execute(&flatpak).args(&update_args).check_run()?;
if cleanup {
let mut cleanup_args = vec!["uninstall", "--system", "--unused"];
if yes {
cleanup_args.push("-y");
}
run_type.execute(flatpak).args(&cleanup_args).status_checked()?;
run_type.execute(flatpak).args(&cleanup_args).check_run()?;
}
}
@@ -612,7 +584,7 @@ pub fn run_snap(sudo: Option<&PathBuf>, run_type: RunType) -> Result<()> {
}
print_separator("snap");
run_type.execute(sudo).arg(snap).arg("refresh").status_checked()
run_type.execute(sudo).arg(snap).arg("refresh").check_run()
}
pub fn run_pihole_update(sudo: Option<&PathBuf>, run_type: RunType) -> Result<()> {
@@ -622,7 +594,7 @@ pub fn run_pihole_update(sudo: Option<&PathBuf>, run_type: RunType) -> Result<()
print_separator("pihole");
run_type.execute(sudo).arg(pihole).arg("-up").status_checked()
run_type.execute(sudo).arg(pihole).arg("-up").check_run()
}
pub fn run_protonup_update(ctx: &ExecutionContext) -> Result<()> {
@@ -630,7 +602,7 @@ pub fn run_protonup_update(ctx: &ExecutionContext) -> Result<()> {
print_separator("protonup");
ctx.run_type().execute(protonup).status_checked()?;
ctx.run_type().execute(protonup).check_run()?;
Ok(())
}
@@ -656,7 +628,8 @@ pub fn run_distrobox_update(ctx: &ExecutionContext) -> Result<()> {
(r, true) => r.arg("--root"),
(r, false) => r,
}
.status_checked()
.check_run()?;
Ok(())
}
pub fn run_config_update(ctx: &ExecutionContext) -> Result<()> {
@@ -667,14 +640,14 @@ pub fn run_config_update(ctx: &ExecutionContext) -> Result<()> {
if let Ok(etc_update) = require("etc-update") {
print_separator("Configuration update");
ctx.run_type().execute(sudo).arg(etc_update).status_checked()?;
ctx.run_type().execute(sudo).arg(etc_update).check_run()?;
} else if let Ok(pacdiff) = require("pacdiff") {
if std::env::var("DIFFPROG").is_err() {
require("vim")?;
}
print_separator("Configuration update");
ctx.execute_elevated(&pacdiff, false)?.status_checked()?;
ctx.execute_elevated(&pacdiff, false)?.check_run()?;
}
Ok(())

View File

@@ -1,30 +1,26 @@
use crate::command::CommandExt;
use crate::execution_context::ExecutionContext;
use crate::executor::RunType;
use crate::executor::{CommandExt, RunType};
use crate::terminal::{print_separator, prompt_yesno};
use crate::{utils::require, Step};
use color_eyre::eyre::Result;
use crate::{error::TopgradeError, utils::require, Step};
use anyhow::Result;
use log::debug;
use std::fs;
use std::process::Command;
use tracing::debug;
pub fn run_macports(ctx: &ExecutionContext) -> Result<()> {
require("port")?;
let sudo = ctx.sudo().as_ref().unwrap();
print_separator("MacPorts");
ctx.run_type()
.execute(sudo)
.args(["port", "selfupdate"])
.status_checked()?;
ctx.run_type().execute(sudo).args(["port", "selfupdate"]).check_run()?;
ctx.run_type()
.execute(sudo)
.args(["port", "-u", "upgrade", "outdated"])
.status_checked()?;
.check_run()?;
if ctx.config().cleanup() {
ctx.run_type()
.execute(sudo)
.args(["port", "-N", "reclaim"])
.status_checked()?;
.check_run()?;
}
Ok(())
@@ -34,7 +30,7 @@ pub fn run_mas(run_type: RunType) -> Result<()> {
let mas = require("mas")?;
print_separator("macOS App Store");
run_type.execute(mas).arg("upgrade").status_checked()
run_type.execute(mas).arg("upgrade").check_run()
}
pub fn upgrade_macos(ctx: &ExecutionContext) -> Result<()> {
@@ -62,15 +58,20 @@ pub fn upgrade_macos(ctx: &ExecutionContext) -> Result<()> {
command.arg("--no-scan");
}
command.status_checked()
command.check_run()
}
fn system_update_available() -> Result<bool> {
let output = Command::new("softwareupdate").arg("--list").output_checked_utf8()?;
let output = Command::new("softwareupdate").arg("--list").output()?;
debug!("{:?}", output);
Ok(!output.stderr.contains("No new software available"))
let status = output.status;
if !status.success() {
return Err(TopgradeError::ProcessFailed(status).into());
}
let string_output = String::from_utf8(output.stderr)?;
debug!("{:?}", string_output);
Ok(!string_output.contains("No new software available"))
}
pub fn run_sparkle(ctx: &ExecutionContext) -> Result<()> {
@@ -82,12 +83,12 @@ pub fn run_sparkle(ctx: &ExecutionContext) -> Result<()> {
let probe = Command::new(&sparkle)
.args(["--probe", "--application"])
.arg(application.path())
.output_checked_utf8();
.check_output();
if probe.is_ok() {
let mut command = ctx.run_type().execute(&sparkle);
command.args(["bundle", "--check-immediately", "--application"]);
command.arg(application.path());
command.status_checked()?;
command.spawn()?.wait()?;
}
}
Ok(())

View File

@@ -1,23 +1,17 @@
use crate::executor::RunType;
use crate::terminal::print_separator;
use crate::utils::require_option;
use color_eyre::eyre::Result;
use anyhow::Result;
use std::path::PathBuf;
pub fn upgrade_openbsd(sudo: Option<&PathBuf>, run_type: RunType) -> Result<()> {
let sudo = require_option(sudo, String::from("No sudo detected"))?;
print_separator("OpenBSD Update");
run_type
.execute(sudo)
.args(&["/usr/sbin/sysupgrade", "-n"])
.status_checked()
run_type.execute(sudo).args(&["/usr/sbin/sysupgrade", "-n"]).check_run()
}
pub fn upgrade_packages(sudo: Option<&PathBuf>, run_type: RunType) -> Result<()> {
let sudo = require_option(sudo, String::from("No sudo detected"))?;
print_separator("OpenBSD Packages");
run_type
.execute(sudo)
.args(&["/usr/sbin/pkg_add", "-u"])
.status_checked()
run_type.execute(sudo).args(&["/usr/sbin/pkg_add", "-u"]).check_run()
}

View File

@@ -1,43 +1,33 @@
use crate::error::{SkipStep, TopgradeError};
use crate::execution_context::ExecutionContext;
use crate::executor::{CommandExt, Executor, ExecutorExitStatus, RunType};
use crate::terminal::print_separator;
#[cfg(not(target_os = "macos"))]
use crate::utils::require_option;
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;
use std::os::unix::fs::MetadataExt;
use std::path::PathBuf;
use std::process::Command;
use std::{env, path::Path};
use crate::command::CommandExt;
use crate::Step;
use color_eyre::eyre::Result;
use directories::BaseDirs;
use home;
use ini::Ini;
use tracing::debug;
use crate::error::SkipStep;
use crate::execution_context::ExecutionContext;
#[cfg(any(target_os = "linux", target_os = "macos"))]
use crate::executor::Executor;
use crate::executor::RunType;
use crate::terminal::print_separator;
#[cfg(not(any(target_os = "android", target_os = "macos")))]
use crate::utils::require_option;
use crate::utils::{require, PathExt};
#[cfg(any(target_os = "linux", target_os = "macos"))]
const INTEL_BREW: &str = "/usr/local/bin/brew";
#[cfg(any(target_os = "linux", target_os = "macos"))]
const ARM_BREW: &str = "/opt/homebrew/bin/brew";
#[derive(Copy, Clone, Debug)]
#[allow(dead_code)]
#[cfg(any(target_os = "linux", target_os = "macos"))]
pub enum BrewVariant {
Path,
MacIntel,
MacArm,
}
#[cfg(any(target_os = "linux", target_os = "macos"))]
impl BrewVariant {
fn binary_name(self) -> &'static str {
match self {
@@ -87,36 +77,30 @@ impl BrewVariant {
}
}
pub fn run_fisher(run_type: RunType) -> Result<()> {
pub fn run_fisher(base_dirs: &BaseDirs, run_type: RunType) -> Result<()> {
let fish = require("fish")?;
Command::new(&fish)
.args(["-c", "type -t fisher"])
.output_checked_utf8()
.map(|_| ())
.map_err(|_| SkipStep("`fisher` is not defined in `fish`".to_owned()))?;
Command::new(&fish)
.args(["-c", "echo \"$__fish_config_dir/fish_plugins\""])
.output_checked_utf8()
.and_then(|output| Path::new(&output.stdout.trim()).require().map(|_| ()))
.map_err(|err| SkipStep(format!("`fish_plugins` path doesn't exist: {err}")))?;
if env::var("fisher_path").is_err() {
base_dirs
.home_dir()
.join(".config/fish/functions/fisher.fish")
.require()?;
}
print_separator("Fisher");
let version_str = run_type
.execute(&fish)
.args(["-c", "fisher --version"])
.output_checked_utf8()?
.stdout;
.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"]).status_checked()
run_type.execute(&fish).args(["-c", "fisher"]).check_run()
} else {
// v4
run_type.execute(&fish).args(["-c", "fisher update"]).status_checked()
run_type.execute(&fish).args(["-c", "fisher update"]).check_run()
}
}
@@ -128,7 +112,7 @@ pub fn run_bashit(ctx: &ExecutionContext) -> Result<()> {
ctx.run_type()
.execute("bash")
.args(["-lic", &format!("bash-it update {}", ctx.config().bashit_branch())])
.status_checked()
.check_run()
}
pub fn run_oh_my_fish(ctx: &ExecutionContext) -> Result<()> {
@@ -140,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"]).status_checked()
ctx.run_type().execute(fish).args(["-c", "omf update"]).check_run()
}
pub fn run_pkgin(ctx: &ExecutionContext) -> Result<()> {
@@ -151,14 +135,14 @@ pub fn run_pkgin(ctx: &ExecutionContext) -> Result<()> {
if ctx.config().yes(Step::Pkgin) {
command.arg("-y");
}
command.status_checked()?;
command.check_run()?;
let mut command = ctx.run_type().execute(ctx.sudo().as_ref().unwrap());
command.arg(&pkgin).arg("upgrade");
if ctx.config().yes(Step::Pkgin) {
command.arg("-y");
}
command.status_checked()
command.check_run()
}
pub fn run_fish_plug(ctx: &ExecutionContext) -> Result<()> {
@@ -170,10 +154,7 @@ pub fn run_fish_plug(ctx: &ExecutionContext) -> Result<()> {
print_separator("fish-plug");
ctx.run_type()
.execute(fish)
.args(["-c", "plug update"])
.status_checked()
ctx.run_type().execute(fish).args(["-c", "plug update"]).check_run()
}
/// Upgrades `fundle` and `fundle` plugins.
@@ -190,7 +171,7 @@ pub fn run_fundle(ctx: &ExecutionContext) -> Result<()> {
ctx.run_type()
.execute(fish)
.args(["-c", "fundle self-update && fundle update"])
.status_checked()
.check_run()
}
#[cfg(not(any(target_os = "android", target_os = "macos")))]
@@ -211,10 +192,10 @@ pub fn upgrade_gnome_extensions(ctx: &ExecutionContext) -> Result<()> {
"--method",
"org.freedesktop.DBus.ListActivatableNames",
])
.output_checked_utf8()?;
.check_output()?;
debug!("Checking for gnome extensions: {}", output);
if !output.stdout.contains("org.gnome.Shell.Extensions") {
if !output.contains("org.gnome.Shell.Extensions") {
return Err(SkipStep(String::from("Gnome shell extensions are unregistered in DBus")).into());
}
@@ -232,10 +213,9 @@ pub fn upgrade_gnome_extensions(ctx: &ExecutionContext) -> Result<()> {
"--method",
"org.gnome.Shell.Extensions.CheckForUpdates",
])
.status_checked()
.check_run()
}
#[cfg(any(target_os = "linux", target_os = "macos"))]
pub fn run_brew_formula(ctx: &ExecutionContext, variant: BrewVariant) -> Result<()> {
#[allow(unused_variables)]
let binary_name = require(variant.binary_name())?;
@@ -250,18 +230,18 @@ pub fn run_brew_formula(ctx: &ExecutionContext, variant: BrewVariant) -> Result<
print_separator(variant.step_title());
let run_type = ctx.run_type();
variant.execute(run_type).arg("update").status_checked()?;
variant.execute(run_type).arg("update").check_run()?;
variant
.execute(run_type)
.args(["upgrade", "--ignore-pinned", "--formula"])
.status_checked()?;
.check_run()?;
if ctx.config().cleanup() {
variant.execute(run_type).arg("cleanup").status_checked()?;
variant.execute(run_type).arg("cleanup").check_run()?;
}
if ctx.config().brew_autoremove() {
variant.execute(run_type).arg("autoremove").status_checked()?;
variant.execute(run_type).arg("autoremove").check_run()?;
}
Ok(())
@@ -279,8 +259,8 @@ pub fn run_brew_cask(ctx: &ExecutionContext, variant: BrewVariant) -> Result<()>
let cask_upgrade_exists = variant
.execute(RunType::Wet)
.args(["--repository", "buo/cask-upgrade"])
.output_checked_utf8()
.map(|p| Path::new(p.stdout.trim()).exists())?;
.check_output()
.map(|p| Path::new(p.trim()).exists())?;
let mut brew_args = vec![];
@@ -296,10 +276,10 @@ pub fn run_brew_cask(ctx: &ExecutionContext, variant: BrewVariant) -> Result<()>
}
}
variant.execute(run_type).args(&brew_args).status_checked()?;
variant.execute(run_type).args(&brew_args).check_run()?;
if ctx.config().cleanup() {
variant.execute(run_type).arg("cleanup").status_checked()?;
variant.execute(run_type).arg("cleanup").check_run()?;
}
Ok(())
@@ -310,7 +290,7 @@ pub fn run_guix(ctx: &ExecutionContext) -> Result<()> {
let run_type = ctx.run_type();
let output = Command::new(&guix).arg("pull").output_checked_utf8();
let output = Command::new(&guix).arg("pull").check_output();
debug!("guix pull output: {:?}", output);
let should_upgrade = output.is_ok();
debug!("Can Upgrade Guix: {:?}", should_upgrade);
@@ -318,7 +298,7 @@ pub fn run_guix(ctx: &ExecutionContext) -> Result<()> {
print_separator("Guix");
if should_upgrade {
return run_type.execute(&guix).args(["package", "-u"]).status_checked();
return run_type.execute(&guix).args(["package", "-u"]).check_run();
}
Err(SkipStep(String::from("Guix Pull Failed, Skipping")).into())
}
@@ -334,7 +314,7 @@ pub fn run_nix(ctx: &ExecutionContext) -> Result<()> {
debug!("nix profile: {:?}", profile_path);
let manifest_json_path = profile_path.join("manifest.json");
let output = Command::new(&nix_env).args(["--query", "nix"]).output_checked_utf8();
let output = Command::new(&nix_env).args(["--query", "nix"]).check_output();
debug!("nix-env output: {:?}", output);
let should_self_upgrade = output.is_ok();
@@ -366,13 +346,13 @@ pub fn run_nix(ctx: &ExecutionContext) -> Result<()> {
if should_self_upgrade {
if multi_user {
ctx.execute_elevated(&nix, true)?.arg("upgrade-nix").status_checked()?;
ctx.execute_elevated(&nix, true)?.arg("upgrade-nix").check_run()?;
} else {
run_type.execute(&nix).arg("upgrade-nix").status_checked()?;
run_type.execute(&nix).arg("upgrade-nix").check_run()?;
}
}
run_type.execute(nix_channel).arg("--update").status_checked()?;
run_type.execute(nix_channel).arg("--update").check_run()?;
if std::path::Path::new(&manifest_json_path).exists() {
run_type
@@ -380,9 +360,9 @@ pub fn run_nix(ctx: &ExecutionContext) -> Result<()> {
.arg("profile")
.arg("upgrade")
.arg(".*")
.status_checked()
.check_run()
} else {
run_type.execute(&nix_env).arg("--upgrade").status_checked()
run_type.execute(&nix_env).arg("--upgrade").check_run()
}
}
@@ -391,40 +371,42 @@ pub fn run_yadm(ctx: &ExecutionContext) -> Result<()> {
print_separator("yadm");
ctx.run_type().execute(yadm).arg("pull").status_checked()
ctx.run_type().execute(yadm).arg("pull").check_run()
}
pub fn run_asdf(run_type: RunType) -> Result<()> {
let asdf = require("asdf")?;
print_separator("asdf");
run_type.execute(&asdf).arg("update").status_checked_with_codes(&[42])?;
let exit_status = run_type.execute(&asdf).arg("update").spawn()?.wait()?;
run_type
.execute(&asdf)
.args(["plugin", "update", "--all"])
.status_checked()
if let ExecutorExitStatus::Wet(e) = exit_status {
if !(e.success() || e.code().map(|c| c == 42).unwrap_or(false)) {
return Err(TopgradeError::ProcessFailed(e).into());
}
}
run_type.execute(&asdf).args(["plugin", "update", "--all"]).check_run()
}
pub fn run_home_manager(run_type: RunType) -> Result<()> {
let home_manager = require("home-manager")?;
print_separator("home-manager");
run_type.execute(home_manager).arg("switch").status_checked()
run_type.execute(home_manager).arg("switch").check_run()
}
pub fn run_tldr(run_type: RunType) -> Result<()> {
let tldr = require("tldr")?;
print_separator("TLDR");
run_type.execute(tldr).arg("--update").status_checked()
run_type.execute(tldr).arg("--update").check_run()
}
pub fn run_pearl(run_type: RunType) -> Result<()> {
let pearl = require("pearl")?;
print_separator("pearl");
run_type.execute(pearl).arg("update").status_checked()
run_type.execute(pearl).arg("update").check_run()
}
pub fn run_sdkman(base_dirs: &BaseDirs, cleanup: bool, run_type: RunType) -> Result<()> {
@@ -458,33 +440,27 @@ pub fn run_sdkman(base_dirs: &BaseDirs, cleanup: bool, run_type: RunType) -> Res
run_type
.execute(&bash)
.args(["-c", cmd_selfupdate.as_str()])
.status_checked()?;
.check_run()?;
}
let cmd_update = format!("source {} && sdk update", &sdkman_init_path);
run_type
.execute(&bash)
.args(["-c", cmd_update.as_str()])
.status_checked()?;
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()])
.status_checked()?;
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()])
.status_checked()?;
.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()])
.status_checked()?;
.check_run()?;
}
Ok(())
@@ -495,7 +471,7 @@ pub fn run_bun(ctx: &ExecutionContext) -> Result<()> {
print_separator("Bun");
ctx.run_type().execute(bun).arg("upgrade").status_checked()
ctx.run_type().execute(bun).arg("upgrade").check_run()
}
/// Update dotfiles with `rcm(7)`.
@@ -505,10 +481,10 @@ pub fn run_rcm(ctx: &ExecutionContext) -> Result<()> {
let rcup = require("rcup")?;
print_separator("rcm");
ctx.run_type().execute(rcup).arg("-v").status_checked()
ctx.run_type().execute(rcup).arg("-v").check_run()
}
pub fn reboot() -> Result<()> {
pub fn reboot() {
print!("Rebooting...");
Command::new("sudo").arg("reboot").status_checked()
Command::new("sudo").arg("reboot").spawn().unwrap().wait().unwrap();
}

View File

@@ -2,12 +2,11 @@ use std::convert::TryFrom;
use std::path::Path;
use std::{ffi::OsStr, process::Command};
use color_eyre::eyre::Result;
use tracing::debug;
use anyhow::Result;
use log::debug;
use crate::command::CommandExt;
use crate::execution_context::ExecutionContext;
use crate::executor::RunType;
use crate::executor::{CommandExt, RunType};
use crate::terminal::{print_separator, print_warning};
use crate::utils::require;
use crate::{error::SkipStep, steps::git::Repositories};
@@ -35,7 +34,7 @@ pub fn run_chocolatey(ctx: &ExecutionContext) -> Result<()> {
command.arg("--yes");
}
command.status_checked()
command.check_run()
}
pub fn run_winget(ctx: &ExecutionContext) -> Result<()> {
@@ -48,10 +47,7 @@ pub fn run_winget(ctx: &ExecutionContext) -> Result<()> {
return Err(SkipStep(String::from("Winget is disabled by default")).into());
}
ctx.run_type()
.execute(&winget)
.args(["upgrade", "--all"])
.status_checked()
ctx.run_type().execute(&winget).args(["upgrade", "--all"]).check_run()
}
pub fn run_scoop(cleanup: bool, run_type: RunType) -> Result<()> {
@@ -59,18 +55,18 @@ pub fn run_scoop(cleanup: bool, run_type: RunType) -> Result<()> {
print_separator("Scoop");
run_type.execute(&scoop).args(["update"]).status_checked()?;
run_type.execute(&scoop).args(["update", "*"]).status_checked()?;
run_type.execute(&scoop).args(["update"]).check_run()?;
run_type.execute(&scoop).args(["update", "*"]).check_run()?;
if cleanup {
run_type.execute(&scoop).args(["cleanup", "*"]).status_checked()?;
run_type.execute(&scoop).args(["cleanup", "*"]).check_run()?;
}
Ok(())
}
fn get_wsl_distributions(wsl: &Path) -> Result<Vec<String>> {
let output = Command::new(wsl).args(["--list", "-q"]).output_checked_utf8()?.stdout;
let output = Command::new(wsl).args(["--list", "-q"]).check_output()?;
Ok(output
.lines()
.filter(|s| !s.is_empty())
@@ -81,7 +77,7 @@ fn get_wsl_distributions(wsl: &Path) -> Result<Vec<String>> {
fn upgrade_wsl_distribution(wsl: &Path, dist: &str, ctx: &ExecutionContext) -> Result<()> {
let topgrade = Command::new(wsl)
.args(["-d", dist, "bash", "-lc", "which topgrade"])
.output_checked_utf8()
.check_output()
.map_err(|_| SkipStep(String::from("Could not find Topgrade installed in WSL")))?;
let mut command = ctx.run_type().execute(wsl);
@@ -93,7 +89,7 @@ fn upgrade_wsl_distribution(wsl: &Path, dist: &str, ctx: &ExecutionContext) -> R
command.arg("-y");
}
command.status_checked()
command.check_run()
}
pub fn run_wsl_topgrade(ctx: &ExecutionContext) -> Result<()> {
@@ -133,17 +129,12 @@ pub fn windows_update(ctx: &ExecutionContext) -> Result<()> {
print_separator("Windows Update");
println!("Running Windows Update. Check the control panel for progress.");
ctx.run_type()
.execute(&usoclient)
.arg("ScanInstallWait")
.status_checked()?;
ctx.run_type().execute(&usoclient).arg("StartInstall").status_checked()
ctx.run_type().execute(&usoclient).arg("ScanInstallWait").check_run()?;
ctx.run_type().execute(&usoclient).arg("StartInstall").check_run()
}
pub fn reboot() -> Result<()> {
// If this works, it won't return, but if it doesn't work, it may return a useful error
// message.
Command::new("shutdown").args(["/R", "/T", "0"]).status_checked()
pub fn reboot() {
Command::new("shutdown").args(["/R", "/T", "0"]).spawn().ok();
}
pub fn insert_startup_scripts(ctx: &ExecutionContext, git_repos: &mut Repositories) -> Result<()> {

View File

@@ -3,10 +3,10 @@ use std::path::Path;
use std::path::PathBuf;
use std::process::Command;
use color_eyre::eyre::Result;
use anyhow::Result;
use crate::command::CommandExt;
use crate::execution_context::ExecutionContext;
use crate::executor::CommandExt;
use crate::terminal::{is_dumb, print_separator};
use crate::utils::{require_option, which, PathExt};
use crate::Step;
@@ -27,8 +27,8 @@ impl Powershell {
let profile = path.as_ref().and_then(|path| {
Command::new(path)
.args(["-NoProfile", "-Command", "Split-Path $profile"])
.output_checked_utf8()
.map(|output| PathBuf::from(output.stdout.trim()))
.check_output()
.map(|output| PathBuf::from(output.trim()))
.and_then(|p| p.require())
.ok()
});
@@ -52,8 +52,8 @@ impl Powershell {
"-Command",
&format!("Get-Module -ListAvailable {}", command),
])
.output_checked_utf8()
.map(|result| !result.stdout.is_empty())
.check_output()
.map(|result| !result.is_empty())
.unwrap_or(false)
}
@@ -81,7 +81,7 @@ impl Powershell {
.execute(powershell)
// This probably doesn't need `shell_words::join`.
.args(["-NoProfile", "-Command", &cmd.join(" ")])
.status_checked()
.check_run()
}
#[cfg(windows)]
@@ -119,6 +119,6 @@ impl Powershell {
}
),
])
.status_checked()
.check_run()
}
}

View File

@@ -1,8 +1,6 @@
use color_eyre::eyre::Result;
use anyhow::Result;
use crate::{
command::CommandExt, error::SkipStep, execution_context::ExecutionContext, terminal::print_separator, utils,
};
use crate::{error::SkipStep, execution_context::ExecutionContext, terminal::print_separator, utils};
fn prepare_async_ssh_command(args: &mut Vec<&str>) {
args.insert(0, "ssh");
@@ -26,7 +24,7 @@ pub fn ssh_step(ctx: &ExecutionContext, hostname: &str) -> Result<()> {
#[cfg(unix)]
{
prepare_async_ssh_command(&mut args);
crate::tmux::run_command(ctx, hostname, &shell_words::join(args))?;
crate::tmux::run_command(ctx, &shell_words::join(args))?;
Err(SkipStep(String::from("Remote Topgrade launched in Tmux")).into())
}
@@ -49,6 +47,6 @@ pub fn ssh_step(ctx: &ExecutionContext, hostname: &str) -> Result<()> {
print_separator(format!("Remote ({})", hostname));
println!("Connecting to {}...", hostname);
ctx.run_type().execute(ssh).args(&args).status_checked()
ctx.run_type().execute(ssh).args(&args).check_run()
}
}

View File

@@ -2,13 +2,13 @@ use std::path::{Path, PathBuf};
use std::process::Command;
use std::{fmt::Display, rc::Rc, str::FromStr};
use color_eyre::eyre::Result;
use anyhow::Result;
use log::{debug, error};
use regex::Regex;
use strum::EnumString;
use tracing::{debug, error};
use crate::command::CommandExt;
use crate::execution_context::ExecutionContext;
use crate::executor::CommandExt;
use crate::terminal::print_separator;
use crate::{error::SkipStep, utils, Step};
@@ -61,11 +61,10 @@ impl Vagrant {
let output = Command::new(&self.path)
.arg("status")
.current_dir(directory)
.output_checked_utf8()?;
.check_output()?;
debug!("Vagrant output in {}: {}", directory, output);
let boxes = output
.stdout
.split('\n')
.skip(2)
.take_while(|line| !(line.is_empty() || line.starts_with('\r')))
@@ -116,7 +115,7 @@ impl<'a> TemporaryPowerOn<'a> {
.execute(vagrant)
.args([subcommand, &vagrant_box.name])
.current_dir(vagrant_box.path.clone())
.status_checked()?;
.check_run()?;
Ok(TemporaryPowerOn {
vagrant,
vagrant_box,
@@ -143,7 +142,7 @@ impl<'a> Drop for TemporaryPowerOn<'a> {
.execute(self.vagrant)
.args([subcommand, &self.vagrant_box.name])
.current_dir(self.vagrant_box.path.clone())
.status_checked()
.check_run()
.ok();
}
}
@@ -200,7 +199,7 @@ pub fn topgrade_vagrant_box(ctx: &ExecutionContext, vagrant_box: &VagrantBox) ->
.execute(&vagrant.path)
.current_dir(&vagrant_box.path)
.args(["ssh", "-c", &command])
.status_checked()
.check_run()
}
pub fn upgrade_vagrant_boxes(ctx: &ExecutionContext) -> Result<()> {
@@ -209,12 +208,12 @@ pub fn upgrade_vagrant_boxes(ctx: &ExecutionContext) -> Result<()> {
let outdated = Command::new(&vagrant)
.args(["box", "outdated", "--global"])
.output_checked_utf8()?;
.check_output()?;
let re = Regex::new(r"\* '(.*?)' for '(.*?)' is outdated").unwrap();
let mut found = false;
for ele in re.captures_iter(&outdated.stdout) {
for ele in re.captures_iter(&outdated) {
found = true;
let _ = ctx
.run_type()
@@ -223,16 +222,13 @@ pub fn upgrade_vagrant_boxes(ctx: &ExecutionContext) -> Result<()> {
.arg(ele.get(1).unwrap().as_str())
.arg("--provider")
.arg(ele.get(2).unwrap().as_str())
.status_checked();
.check_run();
}
if !found {
println!("No outdated boxes")
} else {
ctx.run_type()
.execute(&vagrant)
.args(["box", "prune"])
.status_checked()?;
ctx.run_type().execute(&vagrant).args(["box", "prune"]).check_run()?;
}
Ok(())

View File

@@ -1,22 +1,16 @@
use std::env;
use std::path::PathBuf;
use std::process::Command;
use color_eyre::eyre::eyre;
use color_eyre::eyre::Context;
use color_eyre::eyre::Result;
use directories::BaseDirs;
use crate::command::CommandExt;
use crate::executor::RunType;
use crate::terminal::print_separator;
use crate::{
execution_context::ExecutionContext,
utils::{which, PathExt},
utils::{which, Check, PathExt},
};
#[cfg(unix)]
use std::os::unix::process::CommandExt as _;
use anyhow::Result;
use directories::BaseDirs;
use std::env;
use std::io;
use std::os::unix::process::CommandExt;
use std::path::PathBuf;
use std::process::{exit, Command};
pub fn run_tpm(base_dirs: &BaseDirs, run_type: RunType) -> Result<()> {
let tpm = base_dirs
@@ -26,7 +20,7 @@ pub fn run_tpm(base_dirs: &BaseDirs, run_type: RunType) -> Result<()> {
print_separator("tmux plugins");
run_type.execute(tpm).arg("all").status_checked()
run_type.execute(tpm).arg("all").check_run()
}
struct Tmux {
@@ -50,130 +44,73 @@ impl Tmux {
command
}
fn has_session(&self, session_name: &str) -> Result<bool> {
fn has_session(&self, session_name: &str) -> Result<bool, io::Error> {
Ok(self
.build()
.args(["has-session", "-t", session_name])
.output_checked_with(|_| Ok(()))?
.output()?
.status
.success())
}
/// Create a new tmux session with the given name, running the given command.
/// The command is passed to `sh` (see "shell-command arguments are sh(1) commands" in the
/// `tmux(1)` man page).
fn new_session(&self, session_name: &str, window_name: &str, command: &str) -> Result<()> {
let _ = self
fn new_session(&self, session_name: &str) -> Result<bool, io::Error> {
Ok(self
.build()
// `-d`: initial size comes from the global `default-size` option (instead
// of passing `-x` and `-y` arguments.
// (What do those even do?)
// `-s`: session name
// `-n`: window name (always `topgrade`)
.args(["new-session", "-d", "-s", session_name, "-n", window_name, command])
.output_checked()?;
.args(["new-session", "-d", "-s", session_name, "-n", "dummy"])
.spawn()?
.wait()?
.success())
}
fn run_in_session(&self, command: &str) -> Result<()> {
self.build()
.args(["new-window", "-t", "topgrade", command])
.spawn()?
.wait()?
.check()?;
Ok(())
}
/// Like [`new_session`] but it appends a digit to the session name (if necessary) to
/// avoid duplicate session names.
///
/// The session name is returned.
fn new_unique_session(&self, session_name: &str, window_name: &str, command: &str) -> Result<String> {
let mut session = session_name.to_owned();
for i in 1.. {
if !self
.has_session(&session)
.context("Error determining if a tmux session exists")?
{
self.new_session(&session, window_name, command)
.context("Error running Topgrade in tmux")?;
return Ok(session);
}
session = format!("{session_name}-{i}");
}
unreachable!()
}
/// Create a new window in the given tmux session, running the given command.
fn new_window(&self, session_name: &str, window_name: &str, command: &str) -> Result<()> {
self.build()
// `-d`: initial size comes from the global `default-size` option (instead
// of passing `-x` and `-y` arguments.
// (What do those even do?)
// `-s`: session name
// `-n`: window name
.args([
"new-window",
"-a",
"-t",
&format!("{session_name}:{window_name}"),
"-n",
window_name,
command,
])
.env_remove("TMUX")
.status_checked()
}
fn window_indices(&self, session_name: &str) -> Result<Vec<usize>> {
self.build()
.args(["list-windows", "-F", "#{window_index}", "-t", session_name])
.output_checked_utf8()?
.stdout
.lines()
.map(|l| l.parse())
.collect::<Result<Vec<usize>, _>>()
.context("Failed to compute tmux windows")
}
}
pub fn run_in_tmux(args: Vec<String>) -> Result<()> {
pub fn run_in_tmux(args: Vec<String>) -> ! {
let command = {
let mut command = vec![
String::from("env"),
String::from("TOPGRADE_KEEP_END=1"),
String::from("TOPGRADE_INSIDE_TMUX=1"),
];
// TODO: Should we use `topgrade` instead of the first argument here, which may be
// a local path?
command.extend(env::args());
shell_words::join(command)
};
let tmux = Tmux::new(args);
// Find an unused session and run `topgrade` in it with the current command's arguments.
let session_name = "topgrade";
let window_name = "topgrade";
let session = tmux.new_unique_session(session_name, window_name, &command)?;
if !tmux.has_session("topgrade").expect("Error detecting a tmux session") {
tmux.new_session("topgrade").expect("Error creating a tmux session");
}
tmux.run_in_session(&command).expect("Error running Topgrade in tmux");
tmux.build()
.args(["kill-window", "-t", "topgrade:dummy"])
.output()
.expect("Error killing the dummy tmux window");
// Only attach to the newly-created session if we're not currently in a tmux session.
if env::var("TMUX").is_err() {
let err = tmux.build().args(["attach-session", "-t", &session]).exec();
Err(eyre!("{err}")).context("Failed to `execvp(3)` tmux")
let err = tmux.build().args(["attach", "-t", "topgrade"]).exec();
panic!("{:?}", err);
} else {
println!("Topgrade launched in a new tmux session");
Ok(())
exit(0);
}
}
pub fn run_command(ctx: &ExecutionContext, window_name: &str, command: &str) -> Result<()> {
let tmux = Tmux::new(ctx.config().tmux_arguments()?);
match ctx.get_tmux_session() {
Some(session_name) => {
let indices = tmux.window_indices(&session_name)?;
let last_window = indices
.iter()
.last()
.ok_or_else(|| eyre!("tmux session {session_name} has no windows"))?;
tmux.new_window(&session_name, &format!("{last_window}"), command)?;
}
None => {
let name = tmux.new_unique_session("topgrade", window_name, command)?;
ctx.set_tmux_session(name);
}
}
Ok(())
pub fn run_command(ctx: &ExecutionContext, command: &str) -> Result<()> {
Tmux::new(ctx.config().tmux_arguments()?)
.build()
.args(["new-window", "-a", "-t", "topgrade:1", command])
.env_remove("TMUX")
.spawn()?
.wait()?
.check()
}

View File

@@ -1,20 +1,17 @@
use color_eyre::eyre::Result;
use anyhow::Result;
use crate::command::CommandExt;
use crate::config::Step;
use crate::terminal::print_separator;
use crate::{execution_context::ExecutionContext, utils::require};
use log::debug;
use std::path::Path;
use std::{path::PathBuf, process::Command};
use tracing::debug;
fn list_toolboxes(toolbx: &Path) -> Result<Vec<String>> {
let output = Command::new(toolbx)
.args(["list", "--containers"])
.output_checked_utf8()?;
let output = Command::new(toolbx).args(["list", "--containers"]).output()?;
let output_str = String::from_utf8(output.stdout)?;
let proc: Vec<String> = output
.stdout
let proc: Vec<String> = output_str
.lines()
// Skip the first line since that contains only status information
.skip(1)
@@ -57,7 +54,7 @@ pub fn run_toolbx(ctx: &ExecutionContext) -> Result<()> {
args.push("--yes");
}
ctx.run_type().execute(&toolbx).args(&args).status_checked()?;
let _output = ctx.run_type().execute(&toolbx).args(&args).check_run();
}
Ok(())

View File

@@ -38,14 +38,6 @@ if exists(":CocUpdateSync")
CocUpdateSync
endif
" TODO: Should this be after `PackerSync`?
" Not sure how to sequence this after Packer without doing something weird
" with that `PackerComplete` autocommand.
if exists(":TSUpdate")
echo "TreeSitter Update"
TSUpdate
endif
if exists(':PackerSync')
echo "Packer"
autocmd User PackerComplete quitall

View File

@@ -1,20 +1,19 @@
use crate::command::CommandExt;
use crate::error::{SkipStep, TopgradeError};
use color_eyre::eyre::Result;
use anyhow::Result;
use crate::executor::{Executor, ExecutorOutput, RunType};
use crate::executor::{CommandExt, Executor, ExecutorOutput, RunType};
use crate::terminal::print_separator;
use crate::{
execution_context::ExecutionContext,
utils::{require, PathExt},
};
use directories::BaseDirs;
use log::debug;
use std::path::PathBuf;
use std::{
io::{self, Write},
process::Command,
};
use tracing::debug;
const UPGRADE_VIM: &str = include_str!("upgrade.vim");
@@ -64,7 +63,7 @@ fn upgrade(command: &mut Executor, ctx: &ExecutionContext) -> Result<()> {
}
if !status.success() {
return Err(TopgradeError::ProcessFailed(command.get_program(), status).into());
return Err(TopgradeError::ProcessFailed(status).into());
} else {
println!("Plugins upgraded")
}
@@ -85,22 +84,22 @@ pub fn upgrade_ultimate_vimrc(ctx: &ExecutionContext) -> Result<()> {
.execute(&git)
.current_dir(&config_dir)
.args(["reset", "--hard"])
.status_checked()?;
.check_run()?;
ctx.run_type()
.execute(&git)
.current_dir(&config_dir)
.args(["clean", "-d", "--force"])
.status_checked()?;
.check_run()?;
ctx.run_type()
.execute(&git)
.current_dir(&config_dir)
.args(["pull", "--rebase"])
.status_checked()?;
.check_run()?;
ctx.run_type()
.execute(python)
.current_dir(config_dir)
.arg(update_plugins)
.status_checked()?;
.check_run()?;
Ok(())
}
@@ -108,8 +107,8 @@ pub fn upgrade_ultimate_vimrc(ctx: &ExecutionContext) -> Result<()> {
pub fn upgrade_vim(base_dirs: &BaseDirs, ctx: &ExecutionContext) -> Result<()> {
let vim = require("vim")?;
let output = Command::new(&vim).arg("--version").output_checked_utf8()?;
if !output.stdout.starts_with("VIM") {
let output = Command::new(&vim).arg("--version").check_output()?;
if !output.starts_with("VIM") {
return Err(SkipStep(String::from("vim binary might be actually nvim")).into());
}
@@ -148,5 +147,5 @@ pub fn run_voom(_base_dirs: &BaseDirs, run_type: RunType) -> Result<()> {
print_separator("voom");
run_type.execute(voom).arg("update").status_checked()
run_type.execute(voom).arg("update").check_run()
}

View File

@@ -1,18 +1,15 @@
use std::env;
use std::path::{Path, PathBuf};
use std::process::Command;
use color_eyre::eyre::Result;
use directories::BaseDirs;
use tracing::debug;
use walkdir::WalkDir;
use crate::command::CommandExt;
use crate::execution_context::ExecutionContext;
use crate::executor::RunType;
use crate::executor::{CommandExt, RunType};
use crate::git::Repositories;
use crate::terminal::print_separator;
use crate::utils::{require, PathExt};
use anyhow::Result;
use directories::BaseDirs;
use log::debug;
use std::env;
use std::path::{Path, PathBuf};
use std::process::Command;
use walkdir::WalkDir;
pub fn run_zr(base_dirs: &BaseDirs, run_type: RunType) -> Result<()> {
let zsh = require("zsh")?;
@@ -22,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()]).status_checked()
run_type.execute(zsh).args(["-l", "-c", cmd.as_str()]).check_run()
}
pub fn zshrc(base_dirs: &BaseDirs) -> PathBuf {
@@ -37,7 +34,7 @@ pub fn run_antibody(run_type: RunType) -> Result<()> {
print_separator("antibody");
run_type.execute(antibody).arg("update").status_checked()
run_type.execute(antibody).arg("update").check_run()
}
pub fn run_antigen(base_dirs: &BaseDirs, run_type: RunType) -> Result<()> {
@@ -51,7 +48,7 @@ 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()]).status_checked()
run_type.execute(zsh).args(["-l", "-c", cmd.as_str()]).check_run()
}
pub fn run_zgenom(base_dirs: &BaseDirs, run_type: RunType) -> Result<()> {
@@ -65,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()]).status_checked()
run_type.execute(zsh).args(["-l", "-c", cmd.as_str()]).check_run()
}
pub fn run_zplug(base_dirs: &BaseDirs, run_type: RunType) -> Result<()> {
@@ -79,10 +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"])
.status_checked()
run_type.execute(zsh).args(["-i", "-c", "zplug update"]).check_run()
}
pub fn run_zinit(base_dirs: &BaseDirs, run_type: RunType) -> Result<()> {
@@ -97,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()]).status_checked()
run_type.execute(zsh).args(["-i", "-c", cmd.as_str()]).check_run()
}
pub fn run_zi(base_dirs: &BaseDirs, run_type: RunType) -> Result<()> {
@@ -109,7 +103,7 @@ pub fn run_zi(base_dirs: &BaseDirs, run_type: RunType) -> Result<()> {
print_separator("zi");
let cmd = format!("source {} && zi self-update && zi update --all", zshrc.display(),);
run_type.execute(zsh).args(["-i", "-c", &cmd]).status_checked()
run_type.execute(zsh).args(["-i", "-c", &cmd]).check_run()
}
pub fn run_zim(base_dirs: &BaseDirs, run_type: RunType) -> Result<()> {
@@ -117,10 +111,8 @@ pub fn run_zim(base_dirs: &BaseDirs, run_type: RunType) -> Result<()> {
env::var("ZIM_HOME")
.or_else(|_| {
Command::new("zsh")
// TODO: Should these be quoted?
.args(["-c", "[[ -n ${ZIM_HOME} ]] && print -n ${ZIM_HOME}"])
.output_checked_utf8()
.map(|o| o.stdout)
.check_output()
})
.map(PathBuf::from)
.unwrap_or_else(|_| base_dirs.home_dir().join(".zim"))
@@ -131,7 +123,7 @@ pub fn run_zim(base_dirs: &BaseDirs, run_type: RunType) -> Result<()> {
run_type
.execute(zsh)
.args(["-i", "-c", "zimfw upgrade && zimfw update"])
.status_checked()
.check_run()
}
pub fn run_oh_my_zsh(ctx: &ExecutionContext) -> Result<()> {
@@ -143,10 +135,8 @@ pub fn run_oh_my_zsh(ctx: &ExecutionContext) -> Result<()> {
let custom_dir = env::var::<_>("ZSH_CUSTOM")
.or_else(|_| {
Command::new("zsh")
// TODO: Should these be quoted?
.args(["-c", "test $ZSH_CUSTOM && echo -n $ZSH_CUSTOM"])
.output_checked_utf8()
.map(|o| o.stdout)
.check_output()
})
.map(PathBuf::from)
.unwrap_or_else(|e| {
@@ -178,5 +168,5 @@ pub fn run_oh_my_zsh(ctx: &ExecutionContext) -> Result<()> {
.execute("zsh")
.env("ZSH", &oh_my_zsh)
.arg(&oh_my_zsh.join("tools/upgrade.sh"))
.status_checked_with_codes(&[80])
.check_run_with_codes(&[80])
}