Migrate from failure to anyhow/thiserror (#273)
This commit is contained in:
committed by
GitHub
parent
1ea9b91e11
commit
ba516aa1dd
46
Cargo.lock
generated
46
Cargo.lock
generated
@@ -21,6 +21,11 @@ dependencies = [
|
||||
"winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "anyhow"
|
||||
version = "1.0.25"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "arc-swap"
|
||||
version = "0.4.4"
|
||||
@@ -392,7 +397,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syn 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syn 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"synstructure 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
@@ -996,7 +1001,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syn 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syn 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1382,7 +1387,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syn 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syn 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1489,7 +1494,7 @@ dependencies = [
|
||||
"proc-macro-error 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syn 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syn 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1508,12 +1513,12 @@ dependencies = [
|
||||
"heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syn 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syn 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.8"
|
||||
version = "1.0.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -1528,7 +1533,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syn 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syn 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
@@ -1589,6 +1594,24 @@ dependencies = [
|
||||
"unicode-width 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror"
|
||||
version = "1.0.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"thiserror-impl 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror-impl"
|
||||
version = "1.0.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syn 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thread_local"
|
||||
version = "0.3.6"
|
||||
@@ -1832,11 +1855,10 @@ dependencies = [
|
||||
name = "topgrade"
|
||||
version = "3.5.0"
|
||||
dependencies = [
|
||||
"anyhow 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"chrono 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"console 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"directories 2.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"failure 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"failure_derive 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"glob 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -1850,6 +1872,7 @@ dependencies = [
|
||||
"shellexpand 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"structopt 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"strum 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"thiserror 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tokio 0.1.22 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tokio-process 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"toml 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -2083,6 +2106,7 @@ dependencies = [
|
||||
"checksum adler32 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "5d2e7343e7fc9de883d1b0341e0b13970f764c14101234857d2ddafa1cb1cac2"
|
||||
"checksum aho-corasick 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)" = "58fb5e95d83b38284460a5fda7d6470aa0b8844d283a0b614b8535e880800d2d"
|
||||
"checksum ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b"
|
||||
"checksum anyhow 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)" = "9267dff192e68f3399525901e709a48c1d3982c9c072fa32f2127a0cb0babf14"
|
||||
"checksum arc-swap 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "d7b8a9123b8027467bce0099fe556c628a53c8d83df0507084c31e9ba2e39aff"
|
||||
"checksum arrayref 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "0d382e583f07208808f6b1249e60848879ba3543f57c32277bf52d69c2f0f0ee"
|
||||
"checksum arrayvec 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cff77d8686867eceff3105329d4698d96c2391c176d5d03adc90c7389162b5b8"
|
||||
@@ -2251,7 +2275,7 @@ dependencies = [
|
||||
"checksum structopt-derive 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "ea692d40005b3ceba90a9fe7a78fa8d4b82b0ce627eebbffc329aab850f3410e"
|
||||
"checksum strum 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6138f8f88a16d90134763314e3fc76fa3ed6a7db4725d6acf9a3ef95a3188d22"
|
||||
"checksum strum_macros 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0054a7df764039a6cd8592b9de84be4bec368ff081d203a7d5371cbfa8e65c81"
|
||||
"checksum syn 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)" = "661641ea2aa15845cddeb97dad000d22070bb5c1fb456b96c1cba883ec691e92"
|
||||
"checksum syn 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)" = "dff0acdb207ae2fe6d5976617f887eb1e35a2ba52c13c7234c790960cdad9238"
|
||||
"checksum synstructure 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)" = "67656ea1dc1b41b1451851562ea232ec2e5a80242139f7e679ceccfb5d61f545"
|
||||
"checksum tar 0.4.26 (registry+https://github.com/rust-lang/crates.io-index)" = "b3196bfbffbba3e57481b6ea32249fbaf590396a52505a2615adbb79d9d826d3"
|
||||
"checksum tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "15f2b5fb00ccdf689e0149d1b1b3c03fead81c2b37735d812fa8bddbbf41b6d8"
|
||||
@@ -2259,6 +2283,8 @@ dependencies = [
|
||||
"checksum termcolor 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "96d6098003bde162e4277c70665bd87c326f5a0c3f3fbfb285787fa482d54e6e"
|
||||
"checksum termios 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "72b620c5ea021d75a735c943269bb07d30c9b77d6ac6b236bc8b5c496ef05625"
|
||||
"checksum textwrap 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060"
|
||||
"checksum thiserror 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)" = "6f357d1814b33bc2dc221243f8424104bfe72dbe911d5b71b3816a2dff1c977e"
|
||||
"checksum thiserror-impl 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)" = "eb2e25d25307eb8436894f727aba8f65d07adf02e5b35a13cebed48bd282bfef"
|
||||
"checksum thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c6b53e329000edc2b34dbe8545fd20e55a333362d0a321909685a19bd28c3f1b"
|
||||
"checksum time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)" = "db8dcfca086c1143c9270ac42a2bbd8a7ee477b78ac8e45b19abfb0cbede4b6f"
|
||||
"checksum tokio 0.1.22 (registry+https://github.com/rust-lang/crates.io-index)" = "5a09c0b5bb588872ab2f09afa13ee6e9dac11e10a0ec9e8e3ba39a5a5d530af6"
|
||||
|
||||
@@ -13,8 +13,6 @@ readme = "README.md"
|
||||
|
||||
[dependencies]
|
||||
directories = "2.0.1"
|
||||
failure = "0.1.5"
|
||||
failure_derive = "0.1.5"
|
||||
serde = { version = "1.0.92", features = ["derive"] }
|
||||
toml = "0.5.1"
|
||||
which_crate = { version = "2.0.1", package = "which" }
|
||||
@@ -34,6 +32,8 @@ openssl-probe = { version = "0.1.2", optional = true }
|
||||
pretty_env_logger = "0.3.0"
|
||||
glob = "0.3.0"
|
||||
strum = { version = "0.16.0", features = ["derive"]}
|
||||
thiserror = "1.0.9"
|
||||
anyhow = "1.0.25"
|
||||
|
||||
[target.'cfg(unix)'.dependencies]
|
||||
nix = "0.15.0"
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
use super::error::{Error, ErrorKind};
|
||||
use super::utils::editor;
|
||||
use anyhow::Result;
|
||||
use directories::BaseDirs;
|
||||
use failure::ResultExt;
|
||||
use strum::{EnumIter, EnumString, EnumVariantNames, IntoEnumIterator};
|
||||
|
||||
use log::{debug, LevelFilter};
|
||||
use pretty_env_logger::formatted_timed_builder;
|
||||
use serde::Deserialize;
|
||||
@@ -14,6 +11,7 @@ use std::path::PathBuf;
|
||||
use std::process::Command;
|
||||
use std::{env, fs};
|
||||
use structopt::StructOpt;
|
||||
use strum::{EnumIter, EnumString, EnumVariantNames, IntoEnumIterator};
|
||||
use toml;
|
||||
|
||||
type Commands = BTreeMap<String, String>;
|
||||
@@ -70,20 +68,18 @@ pub struct ConfigFile {
|
||||
}
|
||||
|
||||
impl ConfigFile {
|
||||
fn ensure(base_dirs: &BaseDirs) -> Result<PathBuf, Error> {
|
||||
fn ensure(base_dirs: &BaseDirs) -> Result<PathBuf> {
|
||||
let config_path = base_dirs.config_dir().join("topgrade.toml");
|
||||
if !config_path.exists() {
|
||||
write(&config_path, include_str!("../config.example.toml"))
|
||||
.map_err(|e| {
|
||||
debug!(
|
||||
"Unable to write the example configuration file to {}: {}. Using blank config.",
|
||||
config_path.display(),
|
||||
e
|
||||
);
|
||||
e
|
||||
})
|
||||
.context(ErrorKind::Configuration)?;
|
||||
debug!("No configuration exists");
|
||||
write(&config_path, include_str!("../config.example.toml")).map_err(|e| {
|
||||
debug!(
|
||||
"Unable to write the example configuration file to {}: {}. Using blank config.",
|
||||
config_path.display(),
|
||||
e
|
||||
);
|
||||
e
|
||||
})?;
|
||||
}
|
||||
|
||||
Ok(config_path)
|
||||
@@ -92,22 +88,18 @@ impl ConfigFile {
|
||||
/// Read the configuration file.
|
||||
///
|
||||
/// If the configuration file does not exist the function returns the default ConfigFile.
|
||||
fn read(base_dirs: &BaseDirs) -> Result<ConfigFile, Error> {
|
||||
fn read(base_dirs: &BaseDirs) -> Result<ConfigFile> {
|
||||
let config_path = Self::ensure(base_dirs)?;
|
||||
|
||||
let contents = fs::read_to_string(&config_path)
|
||||
.map_err(|e| {
|
||||
log::error!("Unable to read {}", config_path.display());
|
||||
e
|
||||
})
|
||||
.context(ErrorKind::Configuration)?;
|
||||
let contents = fs::read_to_string(&config_path).map_err(|e| {
|
||||
log::error!("Unable to read {}", config_path.display());
|
||||
e
|
||||
})?;
|
||||
|
||||
let mut result: Self = toml::from_str(&contents)
|
||||
.map_err(|e| {
|
||||
log::error!("Failed to deserialize {}", config_path.display());
|
||||
e
|
||||
})
|
||||
.context(ErrorKind::Configuration)?;
|
||||
let mut result: Self = toml::from_str(&contents).map_err(|e| {
|
||||
log::error!("Failed to deserialize {}", config_path.display());
|
||||
e
|
||||
})?;
|
||||
|
||||
if let Some(ref mut paths) = &mut result.git_repos {
|
||||
for path in paths.iter_mut() {
|
||||
@@ -120,7 +112,7 @@ impl ConfigFile {
|
||||
Ok(result)
|
||||
}
|
||||
|
||||
fn edit(base_dirs: &BaseDirs) -> Result<(), Error> {
|
||||
fn edit(base_dirs: &BaseDirs) -> Result<()> {
|
||||
let config_path = Self::ensure(base_dirs)?;
|
||||
let editor = editor();
|
||||
|
||||
@@ -128,8 +120,7 @@ impl ConfigFile {
|
||||
Command::new(editor)
|
||||
.arg(config_path)
|
||||
.spawn()
|
||||
.and_then(|mut p| p.wait())
|
||||
.context(ErrorKind::Configuration)?;
|
||||
.and_then(|mut p| p.wait())?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
@@ -200,7 +191,7 @@ impl Config {
|
||||
/// Load the configuration.
|
||||
///
|
||||
/// The function parses the command line arguments and reading the configuration file.
|
||||
pub fn load(base_dirs: &BaseDirs, opt: CommandLineArgs) -> Result<Self, Error> {
|
||||
pub fn load(base_dirs: &BaseDirs, opt: CommandLineArgs) -> Result<Self> {
|
||||
let mut builder = formatted_timed_builder();
|
||||
|
||||
if opt.verbose {
|
||||
@@ -210,18 +201,9 @@ impl Config {
|
||||
builder.init();
|
||||
|
||||
let config_file = ConfigFile::read(base_dirs).unwrap_or_else(|e| {
|
||||
use failure::Fail;
|
||||
|
||||
// Inform the user about errors when loading the configuration,
|
||||
// but fallback to the default config to at least attempt to do something
|
||||
log::error!("failed to load configuration: {}", e);
|
||||
|
||||
let mut err = e.cause();
|
||||
while let Some(e) = err {
|
||||
log::error!("{}", e);
|
||||
err = e.cause();
|
||||
}
|
||||
|
||||
ConfigFile::default()
|
||||
});
|
||||
|
||||
@@ -235,7 +217,7 @@ impl Config {
|
||||
}
|
||||
|
||||
/// Launch an editor to edit the configuration
|
||||
pub fn edit(base_dirs: &BaseDirs) -> Result<(), Error> {
|
||||
pub fn edit(base_dirs: &BaseDirs) -> Result<()> {
|
||||
ConfigFile::edit(base_dirs)
|
||||
}
|
||||
|
||||
|
||||
98
src/error.rs
98
src/error.rs
@@ -1,92 +1,28 @@
|
||||
use failure::{Backtrace, Context, Fail};
|
||||
use std::fmt::{self, Display};
|
||||
use std::process::ExitStatus;
|
||||
use thiserror::Error;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Error {
|
||||
inner: Context<ErrorKind>,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Eq, PartialEq, Debug, Fail)]
|
||||
pub enum ErrorKind {
|
||||
#[fail(display = "Error asking the user for retry")]
|
||||
Retry,
|
||||
|
||||
#[fail(display = "Cannot find the user base directories")]
|
||||
NoBaseDirectories,
|
||||
|
||||
#[fail(display = "A step failed")]
|
||||
StepFailed,
|
||||
|
||||
#[fail(display = "Error reading the configuration")]
|
||||
Configuration,
|
||||
|
||||
#[fail(display = "A custom pre-command failed")]
|
||||
PreCommand,
|
||||
|
||||
#[fail(display = "{}", _0)]
|
||||
#[derive(Error, Debug, PartialEq)]
|
||||
pub enum TopgradeError {
|
||||
#[error("{0}")]
|
||||
ProcessFailed(ExitStatus),
|
||||
|
||||
#[fail(display = "Unknown Linux Distribution")]
|
||||
#[error("Unknown Linux Distribution")]
|
||||
#[cfg(target_os = "linux")]
|
||||
UnknownLinuxDistribution,
|
||||
|
||||
#[fail(display = "Process execution failure")]
|
||||
ProcessExecution,
|
||||
|
||||
#[fail(display = "Self-update failure")]
|
||||
#[cfg(feature = "self-update")]
|
||||
SelfUpdate,
|
||||
|
||||
#[fail(display = "A step should be skipped")]
|
||||
SkipStep,
|
||||
|
||||
#[cfg(all(windows, feature = "self-update"))]
|
||||
#[fail(display = "Topgrade Upgraded")]
|
||||
Upgraded(ExitStatus),
|
||||
#[error("A pull action was failed")]
|
||||
PullFailed,
|
||||
}
|
||||
|
||||
impl Fail for Error {
|
||||
fn cause(&self) -> Option<&dyn Fail> {
|
||||
self.inner.cause()
|
||||
}
|
||||
#[derive(Error, Debug)]
|
||||
#[error("A step failed")]
|
||||
pub struct StepFailed;
|
||||
|
||||
fn backtrace(&self) -> Option<&Backtrace> {
|
||||
self.inner.backtrace()
|
||||
}
|
||||
}
|
||||
#[derive(Error, Debug)]
|
||||
#[error("A step should be skipped")]
|
||||
pub struct SkipStep;
|
||||
|
||||
impl Display for Error {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
Display::fmt(&self.inner, f)
|
||||
}
|
||||
}
|
||||
|
||||
impl Error {
|
||||
pub fn kind(&self) -> ErrorKind {
|
||||
*self.inner.get_context()
|
||||
}
|
||||
|
||||
#[cfg(all(windows, feature = "self-update"))]
|
||||
pub fn upgraded(&self) -> bool {
|
||||
if let ErrorKind::Upgraded(_) = self.kind() {
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<ErrorKind> for Error {
|
||||
fn from(kind: ErrorKind) -> Error {
|
||||
Error {
|
||||
inner: Context::new(kind),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Context<ErrorKind>> for Error {
|
||||
fn from(inner: Context<ErrorKind>) -> Error {
|
||||
Error { inner }
|
||||
}
|
||||
}
|
||||
#[cfg(all(windows, feature = "self-update"))]
|
||||
#[derive(Error, Debug)]
|
||||
#[error("Topgrade Upgraded")]
|
||||
pub struct Upgraded(pub ExitStatus);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
//! Utilities for command execution
|
||||
use super::error::{Error, ErrorKind};
|
||||
use super::utils::Check;
|
||||
use failure::ResultExt;
|
||||
use crate::error::TopgradeError;
|
||||
use crate::utils::Check;
|
||||
use anyhow::Result;
|
||||
use log::trace;
|
||||
use std::ffi::{OsStr, OsString};
|
||||
use std::path::Path;
|
||||
@@ -119,9 +119,9 @@ impl Executor {
|
||||
}
|
||||
|
||||
/// See `std::process::Command::spawn`
|
||||
pub fn spawn(&mut self) -> Result<ExecutorChild, Error> {
|
||||
pub fn spawn(&mut self) -> Result<ExecutorChild> {
|
||||
let result = match self {
|
||||
Executor::Wet(c) => c.spawn().context(ErrorKind::ProcessExecution).map(ExecutorChild::Wet)?,
|
||||
Executor::Wet(c) => c.spawn().map(ExecutorChild::Wet)?,
|
||||
Executor::Dry(c) => {
|
||||
c.dry_run();
|
||||
ExecutorChild::Dry
|
||||
@@ -132,9 +132,9 @@ impl Executor {
|
||||
}
|
||||
|
||||
/// See `std::process::Command::output`
|
||||
pub fn output(&mut self) -> Result<ExecutorOutput, Error> {
|
||||
pub fn output(&mut self) -> Result<ExecutorOutput> {
|
||||
match self {
|
||||
Executor::Wet(c) => Ok(ExecutorOutput::Wet(c.output().context(ErrorKind::ProcessExecution)?)),
|
||||
Executor::Wet(c) => Ok(ExecutorOutput::Wet(c.output()?)),
|
||||
Executor::Dry(c) => {
|
||||
c.dry_run();
|
||||
Ok(ExecutorOutput::Dry)
|
||||
@@ -145,7 +145,7 @@ impl Executor {
|
||||
/// A convinence method for `spawn().wait().check()`.
|
||||
/// Returns an error if something went wrong during the execution or if the
|
||||
/// process exited with failure.
|
||||
pub fn check_run(&mut self) -> Result<(), Error> {
|
||||
pub fn check_run(&mut self) -> Result<()> {
|
||||
self.spawn()?.wait()?.check()
|
||||
}
|
||||
}
|
||||
@@ -189,12 +189,9 @@ pub enum ExecutorChild {
|
||||
|
||||
impl ExecutorChild {
|
||||
/// See `std::process::Child::wait`
|
||||
pub fn wait(&mut self) -> Result<ExecutorExitStatus, Error> {
|
||||
pub fn wait(&mut self) -> Result<ExecutorExitStatus> {
|
||||
let result = match self {
|
||||
ExecutorChild::Wet(c) => c
|
||||
.wait()
|
||||
.context(ErrorKind::ProcessExecution)
|
||||
.map(ExecutorExitStatus::Wet)?,
|
||||
ExecutorChild::Wet(c) => c.wait().map(ExecutorExitStatus::Wet)?,
|
||||
ExecutorChild::Dry => ExecutorExitStatus::Dry,
|
||||
};
|
||||
|
||||
@@ -209,7 +206,7 @@ pub enum ExecutorExitStatus {
|
||||
}
|
||||
|
||||
impl Check for ExecutorExitStatus {
|
||||
fn check(self) -> Result<(), Error> {
|
||||
fn check(self) -> Result<()> {
|
||||
match self {
|
||||
ExecutorExitStatus::Wet(e) => e.check(),
|
||||
ExecutorExitStatus::Dry => Ok(()),
|
||||
@@ -220,17 +217,17 @@ impl Check for ExecutorExitStatus {
|
||||
/// Extension methods for `std::process::Command`
|
||||
pub trait CommandExt {
|
||||
/// Run the command, wait for it to complete, check the return code and decode the output as UTF-8.
|
||||
fn check_output(&mut self) -> Result<String, Error>;
|
||||
fn check_output(&mut self) -> Result<String>;
|
||||
}
|
||||
|
||||
impl CommandExt for Command {
|
||||
fn check_output(&mut self) -> Result<String, Error> {
|
||||
let output = self.output().context(ErrorKind::ProcessExecution)?;
|
||||
fn check_output(&mut self) -> Result<String> {
|
||||
let output = self.output()?;
|
||||
trace!("Output of {:?}: {:?}", self, output);
|
||||
let status = output.status;
|
||||
if !status.success() {
|
||||
return Err(ErrorKind::ProcessFailed(status).into());
|
||||
return Err(TopgradeError::ProcessFailed(status).into());
|
||||
}
|
||||
Ok(String::from_utf8(output.stdout).context(ErrorKind::ProcessExecution)?)
|
||||
Ok(String::from_utf8(output.stdout)?)
|
||||
}
|
||||
}
|
||||
|
||||
61
src/main.rs
61
src/main.rs
@@ -11,11 +11,13 @@ mod terminal;
|
||||
mod utils;
|
||||
|
||||
use self::config::{CommandLineArgs, Config, Step};
|
||||
use self::error::{Error, ErrorKind};
|
||||
#[cfg(all(windows, feature = "self-update"))]
|
||||
use self::error::Upgraded;
|
||||
use self::error::{SkipStep, StepFailed};
|
||||
use self::report::Report;
|
||||
use self::steps::*;
|
||||
use self::terminal::*;
|
||||
use failure::{Fail, ResultExt};
|
||||
use anyhow::{anyhow, Result};
|
||||
use log::debug;
|
||||
#[cfg(feature = "self-update")]
|
||||
use openssl_probe;
|
||||
@@ -26,9 +28,9 @@ use std::io;
|
||||
use std::process::exit;
|
||||
use structopt::StructOpt;
|
||||
|
||||
fn execute<'a, F, M>(report: &mut Report<'a>, key: M, func: F, no_retry: bool) -> Result<(), Error>
|
||||
fn execute<'a, F, M>(report: &mut Report<'a>, key: M, func: F, no_retry: bool) -> Result<()>
|
||||
where
|
||||
F: Fn() -> Result<(), Error>,
|
||||
F: Fn() -> Result<()>,
|
||||
M: Into<Cow<'a, str>> + Debug,
|
||||
{
|
||||
debug!("Step {:?}", key);
|
||||
@@ -39,7 +41,7 @@ where
|
||||
report.push_result(Some((key, true)));
|
||||
break;
|
||||
}
|
||||
Err(ref e) if e.kind() == ErrorKind::SkipStep => {
|
||||
Err(e) if e.downcast_ref::<SkipStep>().is_some() => {
|
||||
break;
|
||||
}
|
||||
Err(_) => {
|
||||
@@ -49,7 +51,7 @@ where
|
||||
}
|
||||
|
||||
let should_ask = interrupted || !no_retry;
|
||||
let should_retry = should_ask && should_retry(interrupted).context(ErrorKind::Retry)?;
|
||||
let should_retry = should_ask && should_retry(interrupted)?;
|
||||
|
||||
if !should_retry {
|
||||
report.push_result(Some((key, false)));
|
||||
@@ -62,10 +64,10 @@ where
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn run() -> Result<(), Error> {
|
||||
fn run() -> Result<()> {
|
||||
ctrlc::set_handler();
|
||||
|
||||
let base_dirs = directories::BaseDirs::new().ok_or(ErrorKind::NoBaseDirectories)?;
|
||||
let base_dirs = directories::BaseDirs::new().ok_or_else(|| anyhow!("No base directories"))?;
|
||||
|
||||
let opt = CommandLineArgs::from_args();
|
||||
if opt.edit_config() {
|
||||
@@ -98,29 +100,21 @@ fn run() -> Result<(), Error> {
|
||||
if !run_type.dry() && env::var("TOPGRADE_NO_SELF_UPGRADE").is_err() {
|
||||
let result = self_update::self_update();
|
||||
|
||||
#[cfg(windows)]
|
||||
{
|
||||
let upgraded = match &result {
|
||||
Ok(()) => false,
|
||||
Err(e) => e.upgraded(),
|
||||
};
|
||||
if upgraded {
|
||||
return result;
|
||||
if let Err(e) = &result {
|
||||
#[cfg(windows)]
|
||||
{
|
||||
if e.downcast_ref::<Upgraded>().is_some() {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if let Err(e) = result {
|
||||
print_warning(format!("Self update error: {}", e));
|
||||
if let Some(cause) = e.cause() {
|
||||
print_warning(format!("Caused by: {}", cause));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(commands) = config.pre_commands() {
|
||||
for (name, command) in commands {
|
||||
generic::run_custom_command(&name, &command, run_type).context(ErrorKind::PreCommand)?;
|
||||
generic::run_custom_command(&name, &command, run_type)?;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -661,7 +655,7 @@ fn run() -> Result<(), Error> {
|
||||
if report.data().iter().all(|(_, succeeded)| *succeeded) {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(ErrorKind::StepFailed.into())
|
||||
Err(StepFailed.into())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -673,26 +667,19 @@ fn main() {
|
||||
Err(error) => {
|
||||
#[cfg(all(windows, feature = "self-update"))]
|
||||
{
|
||||
if let ErrorKind::Upgraded(status) = error.kind() {
|
||||
if let Some(Upgraded(status)) = error.downcast_ref::<Upgraded>() {
|
||||
exit(status.code().unwrap());
|
||||
}
|
||||
}
|
||||
|
||||
let should_print = match error.kind() {
|
||||
ErrorKind::StepFailed => false,
|
||||
ErrorKind::Retry => error
|
||||
.cause()
|
||||
.and_then(|cause| cause.downcast_ref::<io::Error>())
|
||||
let skip_print = (error.downcast_ref::<StepFailed>().is_some())
|
||||
|| (error
|
||||
.downcast_ref::<io::Error>()
|
||||
.filter(|io_error| io_error.kind() == io::ErrorKind::Interrupted)
|
||||
.is_none(),
|
||||
_ => true,
|
||||
};
|
||||
.is_some());
|
||||
|
||||
if should_print {
|
||||
if !skip_print {
|
||||
println!("Error: {}", error);
|
||||
if let Some(cause) = error.cause() {
|
||||
println!("Caused by: {}", cause);
|
||||
}
|
||||
}
|
||||
exit(1);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
use super::error::{Error, ErrorKind};
|
||||
use super::terminal::*;
|
||||
use failure::ResultExt;
|
||||
#[cfg(windows)]
|
||||
use crate::error::Upgraded;
|
||||
use anyhow::{bail, Result};
|
||||
use self_update_crate;
|
||||
use self_update_crate::backends::github::{GitHubUpdateStatus, Update};
|
||||
use std::env;
|
||||
@@ -8,7 +9,7 @@ use std::env;
|
||||
use std::os::unix::process::CommandExt;
|
||||
use std::process::Command;
|
||||
|
||||
pub fn self_update() -> Result<(), Error> {
|
||||
pub fn self_update() -> Result<()> {
|
||||
print_separator("Self update");
|
||||
let current_exe = env::current_exe();
|
||||
|
||||
@@ -23,8 +24,7 @@ pub fn self_update() -> Result<(), Error> {
|
||||
.current_version(self_update_crate::cargo_crate_version!())
|
||||
.no_confirm(true)
|
||||
.build()
|
||||
.and_then(Update::update_extended)
|
||||
.context(ErrorKind::SelfUpdate)?;
|
||||
.and_then(Update::update_extended)?;
|
||||
|
||||
if let GitHubUpdateStatus::Updated(release) = &result {
|
||||
println!("\nTopgrade upgraded to {}:\n", release.version());
|
||||
@@ -36,22 +36,19 @@ pub fn self_update() -> Result<(), Error> {
|
||||
{
|
||||
if result.updated() {
|
||||
print_warning("Respawning...");
|
||||
let mut command = Command::new(current_exe.context(ErrorKind::SelfUpdate)?);
|
||||
let mut command = Command::new(current_exe?);
|
||||
command.args(env::args().skip(1)).env("TOPGRADE_NO_SELF_UPGRADE", "");
|
||||
|
||||
#[cfg(unix)]
|
||||
{
|
||||
let err = command.exec();
|
||||
Err(err).context(ErrorKind::SelfUpdate)?
|
||||
bail!(err);
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
{
|
||||
let status = command
|
||||
.spawn()
|
||||
.and_then(|mut c| c.wait())
|
||||
.context(ErrorKind::SelfUpdate)?;
|
||||
return Err(ErrorKind::Upgraded(status).into());
|
||||
let status = command.spawn().and_then(|mut c| c.wait())?;
|
||||
bail!(Upgraded(status));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use crate::error::Error;
|
||||
use crate::executor::RunType;
|
||||
use crate::terminal::print_separator;
|
||||
use crate::utils::{require, require_option, PathExt};
|
||||
use anyhow::Result;
|
||||
use directories::BaseDirs;
|
||||
#[cfg(windows)]
|
||||
use std::env;
|
||||
@@ -35,7 +35,7 @@ impl Emacs {
|
||||
self.directory.as_ref()
|
||||
}
|
||||
|
||||
pub fn upgrade(&self, run_type: RunType) -> Result<(), Error> {
|
||||
pub fn upgrade(&self, run_type: RunType) -> Result<()> {
|
||||
let emacs = require("emacs")?;
|
||||
let init_file = require_option(self.directory.as_ref())?.join("init.el").require()?;
|
||||
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
use crate::error::{Error, ErrorKind};
|
||||
use crate::error::SkipStep;
|
||||
use crate::executor::{CommandExt, RunType};
|
||||
use crate::terminal::{print_separator, shell};
|
||||
use crate::utils::{self, PathExt};
|
||||
use anyhow::Result;
|
||||
use directories::BaseDirs;
|
||||
use failure::ResultExt;
|
||||
use std::env;
|
||||
use std::path::PathBuf;
|
||||
use std::process::Command;
|
||||
|
||||
pub fn run_cargo_update(run_type: RunType) -> Result<(), Error> {
|
||||
pub fn run_cargo_update(run_type: RunType) -> Result<()> {
|
||||
let cargo_update = utils::require("cargo-install-update")?;
|
||||
|
||||
print_separator("Cargo");
|
||||
@@ -19,14 +19,14 @@ pub fn run_cargo_update(run_type: RunType) -> Result<(), Error> {
|
||||
.check_run()
|
||||
}
|
||||
|
||||
pub fn run_flutter_upgrade(run_type: RunType) -> Result<(), Error> {
|
||||
pub fn run_flutter_upgrade(run_type: RunType) -> Result<()> {
|
||||
let flutter = utils::require("flutter")?;
|
||||
|
||||
print_separator("Flutter");
|
||||
run_type.execute(&flutter).arg("upgrade").check_run()
|
||||
}
|
||||
|
||||
pub fn run_go(base_dirs: &BaseDirs, run_type: RunType) -> Result<(), Error> {
|
||||
pub fn run_go(base_dirs: &BaseDirs, run_type: RunType) -> Result<()> {
|
||||
let go = utils::require("go")?;
|
||||
env::var("GOPATH")
|
||||
.unwrap_or_else(|_| base_dirs.home_dir().join("go").to_str().unwrap().to_string())
|
||||
@@ -36,7 +36,7 @@ pub fn run_go(base_dirs: &BaseDirs, run_type: RunType) -> Result<(), Error> {
|
||||
run_type.execute(&go).arg("get").arg("-u").arg("all").check_run()
|
||||
}
|
||||
|
||||
pub fn run_gem(base_dirs: &BaseDirs, run_type: RunType) -> Result<(), Error> {
|
||||
pub fn run_gem(base_dirs: &BaseDirs, run_type: RunType) -> Result<()> {
|
||||
let gem = utils::require("gem")?;
|
||||
base_dirs.home_dir().join(".gem").require()?;
|
||||
|
||||
@@ -51,7 +51,7 @@ pub fn run_gem(base_dirs: &BaseDirs, run_type: RunType) -> Result<(), Error> {
|
||||
target_os = "netbsd",
|
||||
target_os = "dragonfly"
|
||||
)))]
|
||||
pub fn run_apm(run_type: RunType) -> Result<(), Error> {
|
||||
pub fn run_apm(run_type: RunType) -> Result<()> {
|
||||
let apm = utils::require("apm")?;
|
||||
|
||||
print_separator("Atom Package Manager");
|
||||
@@ -59,23 +59,19 @@ pub fn run_apm(run_type: RunType) -> Result<(), Error> {
|
||||
run_type.execute(&apm).args(&["upgrade", "--confirm=false"]).check_run()
|
||||
}
|
||||
|
||||
pub fn run_rustup(base_dirs: &BaseDirs, run_type: RunType) -> Result<(), Error> {
|
||||
pub fn run_rustup(base_dirs: &BaseDirs, run_type: RunType) -> Result<()> {
|
||||
let rustup = utils::require("rustup")?;
|
||||
|
||||
print_separator("rustup");
|
||||
|
||||
if rustup
|
||||
.canonicalize()
|
||||
.context(ErrorKind::StepFailed)?
|
||||
.is_descendant_of(base_dirs.home_dir())
|
||||
{
|
||||
if rustup.canonicalize()?.is_descendant_of(base_dirs.home_dir()) {
|
||||
run_type.execute(&rustup).args(&["self", "update"]).check_run()?;
|
||||
}
|
||||
|
||||
run_type.execute(&rustup).arg("update").check_run()
|
||||
}
|
||||
|
||||
pub fn run_jetpack(run_type: RunType) -> Result<(), Error> {
|
||||
pub fn run_jetpack(run_type: RunType) -> Result<()> {
|
||||
let jetpack = utils::require("jetpack")?;
|
||||
|
||||
print_separator("Jetpack");
|
||||
@@ -83,7 +79,7 @@ pub fn run_jetpack(run_type: RunType) -> Result<(), Error> {
|
||||
run_type.execute(&jetpack).args(&["global", "update"]).check_run()
|
||||
}
|
||||
|
||||
pub fn run_opam_update(run_type: RunType) -> Result<(), Error> {
|
||||
pub fn run_opam_update(run_type: RunType) -> Result<()> {
|
||||
let opam = utils::require("opam")?;
|
||||
|
||||
print_separator("OCaml Package Manager");
|
||||
@@ -92,28 +88,28 @@ pub fn run_opam_update(run_type: RunType) -> Result<(), Error> {
|
||||
run_type.execute(&opam).arg("upgrade").check_run()
|
||||
}
|
||||
|
||||
pub fn run_vcpkg_update(run_type: RunType) -> Result<(), Error> {
|
||||
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()
|
||||
}
|
||||
|
||||
pub fn run_pipx_update(run_type: RunType) -> Result<(), Error> {
|
||||
pub fn run_pipx_update(run_type: RunType) -> Result<()> {
|
||||
let pipx = utils::require("pipx")?;
|
||||
print_separator("pipx");
|
||||
|
||||
run_type.execute(&pipx).arg("upgrade-all").check_run()
|
||||
}
|
||||
|
||||
pub fn run_stack_update(run_type: RunType) -> Result<(), Error> {
|
||||
pub fn run_stack_update(run_type: RunType) -> Result<()> {
|
||||
let stack = utils::require("stack")?;
|
||||
print_separator("stack");
|
||||
|
||||
run_type.execute(&stack).arg("upgrade").check_run()
|
||||
}
|
||||
|
||||
pub fn run_myrepos_update(base_dirs: &BaseDirs, run_type: RunType) -> Result<(), Error> {
|
||||
pub fn run_myrepos_update(base_dirs: &BaseDirs, run_type: RunType) -> Result<()> {
|
||||
let myrepos = utils::require("mr")?;
|
||||
base_dirs.home_dir().join(".mrconfig").require()?;
|
||||
|
||||
@@ -133,22 +129,22 @@ pub fn run_myrepos_update(base_dirs: &BaseDirs, run_type: RunType) -> Result<(),
|
||||
.check_run()
|
||||
}
|
||||
|
||||
pub fn run_custom_command(name: &str, command: &str, run_type: RunType) -> Result<(), Error> {
|
||||
pub fn run_custom_command(name: &str, command: &str, run_type: RunType) -> Result<()> {
|
||||
print_separator(name);
|
||||
run_type.execute(shell()).arg("-c").arg(command).check_run()
|
||||
}
|
||||
|
||||
pub fn run_composer_update(base_dirs: &BaseDirs, run_type: RunType) -> Result<(), Error> {
|
||||
pub fn run_composer_update(base_dirs: &BaseDirs, run_type: RunType) -> Result<()> {
|
||||
let composer = utils::require("composer")?;
|
||||
let composer_home = Command::new(&composer)
|
||||
.args(&["global", "config", "--absolute", "--quiet", "home"])
|
||||
.check_output()
|
||||
.map_err(|_| Error::from(ErrorKind::SkipStep))
|
||||
.map(|s| PathBuf::from(s.trim()))
|
||||
.and_then(PathExt::require)?;
|
||||
.map_err(|_| (SkipStep))
|
||||
.map(|s| PathBuf::from(s.trim()))?
|
||||
.require()?;
|
||||
|
||||
if !composer_home.is_descendant_of(base_dirs.home_dir()) {
|
||||
return Err(ErrorKind::SkipStep.into());
|
||||
return Err(SkipStep.into());
|
||||
}
|
||||
|
||||
print_separator("Composer");
|
||||
@@ -168,14 +164,14 @@ pub fn run_remote_topgrade(
|
||||
ssh_arguments: &Option<String>,
|
||||
run_in_tmux: bool,
|
||||
_tmux_arguments: &Option<String>,
|
||||
) -> Result<(), Error> {
|
||||
) -> Result<()> {
|
||||
let ssh = utils::require("ssh")?;
|
||||
|
||||
if run_in_tmux && !run_type.dry() {
|
||||
#[cfg(unix)]
|
||||
{
|
||||
crate::tmux::run_remote_topgrade(hostname, &ssh, _tmux_arguments)?;
|
||||
Err(ErrorKind::SkipStep.into())
|
||||
Err(SkipStep.into())
|
||||
}
|
||||
|
||||
#[cfg(not(unix))]
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
use crate::error::{Error, ErrorKind};
|
||||
use crate::error::TopgradeError;
|
||||
use crate::executor::{CommandExt, RunType};
|
||||
use crate::terminal::print_separator;
|
||||
use crate::utils::{which, HumanizedPath};
|
||||
use anyhow::Result;
|
||||
use console::style;
|
||||
use futures::future::{join_all, Future};
|
||||
use glob::{glob_with, MatchOptions};
|
||||
@@ -79,7 +80,7 @@ impl Git {
|
||||
repositories: &Repositories,
|
||||
run_type: RunType,
|
||||
extra_arguments: &Option<String>,
|
||||
) -> Result<(), Error> {
|
||||
) -> Result<()> {
|
||||
if repositories.repositories.is_empty() {
|
||||
return Ok(());
|
||||
}
|
||||
@@ -143,7 +144,7 @@ impl Git {
|
||||
println!("{} {}", style("Up-to-date").green().bold(), path);
|
||||
}
|
||||
}
|
||||
Ok(true) as Result<bool, Error>
|
||||
Ok(true) as Result<bool>
|
||||
} else {
|
||||
println!("{} pulling {}", style("Failed").red().bold(), path);
|
||||
if let Ok(text) = std::str::from_utf8(&output.stderr) {
|
||||
@@ -163,7 +164,7 @@ impl Git {
|
||||
let mut runtime = Runtime::new().unwrap();
|
||||
let results: Vec<bool> = runtime.block_on(join_all(futures))?;
|
||||
if results.into_iter().any(|success| !success) {
|
||||
Err(ErrorKind::StepFailed.into())
|
||||
Err(TopgradeError::PullFailed.into())
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
use crate::error::{Error, ErrorKind};
|
||||
use crate::error::SkipStep;
|
||||
use crate::executor::{CommandExt, RunType};
|
||||
use crate::terminal::print_separator;
|
||||
use crate::utils::{require, PathExt};
|
||||
use anyhow::Result;
|
||||
|
||||
use directories::BaseDirs;
|
||||
use std::path::PathBuf;
|
||||
use std::process::Command;
|
||||
@@ -15,32 +17,32 @@ impl NPM {
|
||||
Self { command }
|
||||
}
|
||||
|
||||
fn root(&self) -> Result<PathBuf, Error> {
|
||||
fn root(&self) -> Result<PathBuf> {
|
||||
Command::new(&self.command)
|
||||
.args(&["root", "-g"])
|
||||
.check_output()
|
||||
.map(PathBuf::from)
|
||||
}
|
||||
|
||||
fn upgrade(&self, run_type: RunType) -> Result<(), Error> {
|
||||
fn upgrade(&self, run_type: RunType) -> Result<()> {
|
||||
run_type.execute(&self.command).args(&["update", "-g"]).check_run()?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
pub fn run_npm_upgrade(base_dirs: &BaseDirs, run_type: RunType) -> Result<(), Error> {
|
||||
pub fn run_npm_upgrade(base_dirs: &BaseDirs, run_type: RunType) -> Result<()> {
|
||||
let npm = require("npm").map(NPM::new)?;
|
||||
let npm_root = npm.root()?;
|
||||
if !npm_root.is_descendant_of(base_dirs.home_dir()) {
|
||||
return Err(ErrorKind::SkipStep.into());
|
||||
return Err(SkipStep.into());
|
||||
}
|
||||
|
||||
print_separator("Node Package Manager");
|
||||
npm.upgrade(run_type)
|
||||
}
|
||||
|
||||
pub fn yarn_global_update(run_type: RunType) -> Result<(), Error> {
|
||||
pub fn yarn_global_update(run_type: RunType) -> Result<()> {
|
||||
let yarn = require("yarn")?;
|
||||
|
||||
print_separator("Yarn");
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
use crate::error::{Error, ErrorKind};
|
||||
use crate::error::TopgradeError;
|
||||
use crate::executor::RunType;
|
||||
use crate::terminal::print_separator;
|
||||
use crate::utils::require_option;
|
||||
@@ -6,7 +6,7 @@ use failure::ResultExt;
|
||||
use std::path::PathBuf;
|
||||
use std::process::Command;
|
||||
|
||||
pub fn upgrade_packages(sudo: Option<&PathBuf>, run_type: RunType) -> Result<(), Error> {
|
||||
pub fn upgrade_packages(sudo: Option<&PathBuf>, run_type: RunType) -> Result<()> {
|
||||
let sudo = require_option(sudo)?;
|
||||
print_separator("DrgaonFly BSD Packages");
|
||||
run_type
|
||||
@@ -15,7 +15,7 @@ pub fn upgrade_packages(sudo: Option<&PathBuf>, run_type: RunType) -> Result<(),
|
||||
.check_run()
|
||||
}
|
||||
|
||||
pub fn audit_packages(sudo: &Option<PathBuf>) -> Result<(), Error> {
|
||||
pub fn audit_packages(sudo: &Option<PathBuf>) -> Result<()> {
|
||||
if let Some(sudo) = sudo {
|
||||
println!();
|
||||
Command::new(sudo)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
use crate::error::{Error, ErrorKind};
|
||||
use crate::error::TopgradeError;
|
||||
use crate::executor::RunType;
|
||||
use crate::terminal::print_separator;
|
||||
use crate::utils::require_option;
|
||||
@@ -6,7 +6,7 @@ use failure::ResultExt;
|
||||
use std::path::PathBuf;
|
||||
use std::process::Command;
|
||||
|
||||
pub fn upgrade_freebsd(sudo: Option<&PathBuf>, run_type: RunType) -> Result<(), Error> {
|
||||
pub fn upgrade_freebsd(sudo: Option<&PathBuf>, run_type: RunType) -> Result<()> {
|
||||
let sudo = require_option(sudo)?;
|
||||
print_separator("FreeBSD Update");
|
||||
run_type
|
||||
@@ -15,13 +15,13 @@ pub fn upgrade_freebsd(sudo: Option<&PathBuf>, run_type: RunType) -> Result<(),
|
||||
.check_run()
|
||||
}
|
||||
|
||||
pub fn upgrade_packages(sudo: Option<&PathBuf>, run_type: RunType) -> Result<(), Error> {
|
||||
pub fn upgrade_packages(sudo: Option<&PathBuf>, run_type: RunType) -> Result<()> {
|
||||
let sudo = require_option(sudo)?;
|
||||
print_separator("FreeBSD Packages");
|
||||
run_type.execute(sudo).args(&["/usr/sbin/pkg", "upgrade"]).check_run()
|
||||
}
|
||||
|
||||
pub fn audit_packages(sudo: &Option<PathBuf>) -> Result<(), Error> {
|
||||
pub fn audit_packages(sudo: &Option<PathBuf>) -> Result<()> {
|
||||
if let Some(sudo) = sudo {
|
||||
println!();
|
||||
Command::new(sudo)
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
use crate::config::Config;
|
||||
use crate::error::{Error, ErrorKind};
|
||||
use crate::error::{SkipStep, TopgradeError};
|
||||
use crate::executor::{ExecutorExitStatus, RunType};
|
||||
use crate::terminal::{print_separator, print_warning};
|
||||
use crate::utils::{require, require_option, which, PathExt};
|
||||
use failure::ResultExt;
|
||||
use anyhow::Result;
|
||||
use ini::Ini;
|
||||
use log::debug;
|
||||
use serde::Deserialize;
|
||||
@@ -37,7 +37,7 @@ pub enum Distribution {
|
||||
}
|
||||
|
||||
impl Distribution {
|
||||
fn parse_os_release(os_release: &ini::Ini) -> Result<Self, Error> {
|
||||
fn parse_os_release(os_release: &ini::Ini) -> Result<Self> {
|
||||
let section = os_release.general_section();
|
||||
let id = section.get("ID").map(String::as_str);
|
||||
let id_like: Option<Vec<&str>> = section
|
||||
@@ -65,22 +65,22 @@ impl Distribution {
|
||||
Some("gentoo") => Distribution::Gentoo,
|
||||
Some("exherbo") => Distribution::Exherbo,
|
||||
Some("nixos") => Distribution::NixOS,
|
||||
_ => return Err(ErrorKind::UnknownLinuxDistribution.into()),
|
||||
_ => return Err(TopgradeError::UnknownLinuxDistribution.into()),
|
||||
})
|
||||
}
|
||||
|
||||
pub fn detect() -> Result<Self, Error> {
|
||||
pub fn detect() -> Result<Self> {
|
||||
if PathBuf::from(OS_RELEASE_PATH).exists() {
|
||||
let os_release = Ini::load_from_file(OS_RELEASE_PATH).context(ErrorKind::UnknownLinuxDistribution)?;
|
||||
let os_release = Ini::load_from_file(OS_RELEASE_PATH)?;
|
||||
|
||||
return Self::parse_os_release(&os_release);
|
||||
}
|
||||
|
||||
Err(ErrorKind::UnknownLinuxDistribution.into())
|
||||
Err(TopgradeError::UnknownLinuxDistribution.into())
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn upgrade(self, sudo: &Option<PathBuf>, run_type: RunType, config: &Config) -> Result<(), Error> {
|
||||
pub fn upgrade(self, sudo: &Option<PathBuf>, run_type: RunType, config: &Config) -> Result<()> {
|
||||
print_separator("System update");
|
||||
|
||||
let yes = config.yes();
|
||||
@@ -134,7 +134,7 @@ fn upgrade_arch_linux(
|
||||
run_type: RunType,
|
||||
yes: bool,
|
||||
yay_arguments: &str,
|
||||
) -> Result<(), Error> {
|
||||
) -> Result<()> {
|
||||
let pacman = which("powerpill").unwrap_or_else(|| PathBuf::from("/usr/bin/pacman"));
|
||||
|
||||
let path = {
|
||||
@@ -197,7 +197,7 @@ fn upgrade_arch_linux(
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn upgrade_redhat(sudo: &Option<PathBuf>, run_type: RunType, yes: bool) -> Result<(), Error> {
|
||||
fn upgrade_redhat(sudo: &Option<PathBuf>, run_type: RunType, yes: bool) -> Result<()> {
|
||||
if let Some(sudo) = &sudo {
|
||||
let mut command = run_type.execute(&sudo);
|
||||
command
|
||||
@@ -219,7 +219,7 @@ fn upgrade_redhat(sudo: &Option<PathBuf>, run_type: RunType, yes: bool) -> Resul
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn upgrade_suse(sudo: &Option<PathBuf>, run_type: RunType) -> Result<(), Error> {
|
||||
fn upgrade_suse(sudo: &Option<PathBuf>, run_type: RunType) -> Result<()> {
|
||||
if let Some(sudo) = &sudo {
|
||||
run_type
|
||||
.execute(&sudo)
|
||||
@@ -237,7 +237,7 @@ fn upgrade_suse(sudo: &Option<PathBuf>, run_type: RunType) -> Result<(), Error>
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn upgrade_void(sudo: &Option<PathBuf>, run_type: RunType) -> Result<(), Error> {
|
||||
fn upgrade_void(sudo: &Option<PathBuf>, run_type: RunType) -> Result<()> {
|
||||
if let Some(sudo) = &sudo {
|
||||
for _ in 0..2 {
|
||||
run_type
|
||||
@@ -252,7 +252,7 @@ fn upgrade_void(sudo: &Option<PathBuf>, run_type: RunType) -> Result<(), Error>
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn upgrade_gentoo(sudo: &Option<PathBuf>, run_type: RunType) -> Result<(), Error> {
|
||||
fn upgrade_gentoo(sudo: &Option<PathBuf>, run_type: RunType) -> Result<()> {
|
||||
if let Some(sudo) = &sudo {
|
||||
if let Some(layman) = which("layman") {
|
||||
run_type.execute(&sudo).arg(layman).args(&["-s", "ALL"]).check_run()?;
|
||||
@@ -281,7 +281,7 @@ fn upgrade_gentoo(sudo: &Option<PathBuf>, run_type: RunType) -> Result<(), Error
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn upgrade_debian(sudo: &Option<PathBuf>, cleanup: bool, run_type: RunType, yes: bool) -> Result<(), Error> {
|
||||
fn upgrade_debian(sudo: &Option<PathBuf>, cleanup: bool, run_type: RunType, yes: bool) -> Result<()> {
|
||||
if let Some(sudo) = &sudo {
|
||||
let apt = which("apt-fast").unwrap_or_else(|| PathBuf::from("/usr/bin/apt"));
|
||||
run_type.execute(&sudo).arg(&apt).arg("update").check_run()?;
|
||||
@@ -310,7 +310,7 @@ fn upgrade_debian(sudo: &Option<PathBuf>, cleanup: bool, run_type: RunType, yes:
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn upgrade_solus(sudo: &Option<PathBuf>, run_type: RunType) -> Result<(), Error> {
|
||||
fn upgrade_solus(sudo: &Option<PathBuf>, run_type: RunType) -> Result<()> {
|
||||
if let Some(sudo) = &sudo {
|
||||
run_type
|
||||
.execute(&sudo)
|
||||
@@ -323,7 +323,7 @@ fn upgrade_solus(sudo: &Option<PathBuf>, run_type: RunType) -> Result<(), Error>
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn upgrade_clearlinux(sudo: &Option<PathBuf>, run_type: RunType) -> Result<(), Error> {
|
||||
fn upgrade_clearlinux(sudo: &Option<PathBuf>, run_type: RunType) -> Result<()> {
|
||||
if let Some(sudo) = &sudo {
|
||||
run_type
|
||||
.execute(&sudo)
|
||||
@@ -336,7 +336,7 @@ fn upgrade_clearlinux(sudo: &Option<PathBuf>, run_type: RunType) -> Result<(), E
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn upgrade_exherbo(sudo: &Option<PathBuf>, cleanup: bool, run_type: RunType) -> Result<(), Error> {
|
||||
fn upgrade_exherbo(sudo: &Option<PathBuf>, cleanup: bool, run_type: RunType) -> Result<()> {
|
||||
if let Some(sudo) = &sudo {
|
||||
run_type.execute(&sudo).args(&["/usr/bin/cave", "sync"]).check_run()?;
|
||||
|
||||
@@ -368,7 +368,7 @@ fn upgrade_exherbo(sudo: &Option<PathBuf>, cleanup: bool, run_type: RunType) ->
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn upgrade_nixos(sudo: &Option<PathBuf>, cleanup: bool, run_type: RunType) -> Result<(), Error> {
|
||||
fn upgrade_nixos(sudo: &Option<PathBuf>, cleanup: bool, run_type: RunType) -> Result<()> {
|
||||
if let Some(sudo) = &sudo {
|
||||
run_type
|
||||
.execute(&sudo)
|
||||
@@ -388,7 +388,7 @@ fn upgrade_nixos(sudo: &Option<PathBuf>, cleanup: bool, run_type: RunType) -> Re
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn run_needrestart(sudo: Option<&PathBuf>, run_type: RunType) -> Result<(), Error> {
|
||||
pub fn run_needrestart(sudo: Option<&PathBuf>, run_type: RunType) -> Result<()> {
|
||||
let sudo = require_option(sudo)?;
|
||||
let needrestart = require("needrestart")?;
|
||||
|
||||
@@ -400,7 +400,7 @@ pub fn run_needrestart(sudo: Option<&PathBuf>, run_type: RunType) -> Result<(),
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn run_fwupdmgr(run_type: RunType) -> Result<(), Error> {
|
||||
pub fn run_fwupdmgr(run_type: RunType) -> Result<()> {
|
||||
let fwupdmgr = require("fwupdmgr")?;
|
||||
|
||||
print_separator("Firmware upgrades");
|
||||
@@ -410,7 +410,7 @@ pub fn run_fwupdmgr(run_type: RunType) -> Result<(), Error> {
|
||||
|
||||
if let ExecutorExitStatus::Wet(e) = exit_status {
|
||||
if !(e.success() || e.code().map(|c| c == 2).unwrap_or(false)) {
|
||||
return Err(ErrorKind::ProcessFailed(e).into());
|
||||
return Err(TopgradeError::ProcessFailed(e).into());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -418,7 +418,7 @@ pub fn run_fwupdmgr(run_type: RunType) -> Result<(), Error> {
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn flatpak_update(run_type: RunType) -> Result<(), Error> {
|
||||
pub fn flatpak_update(run_type: RunType) -> Result<()> {
|
||||
let flatpak = require("flatpak")?;
|
||||
print_separator("Flatpak User Packages");
|
||||
|
||||
@@ -433,12 +433,12 @@ pub fn flatpak_update(run_type: RunType) -> Result<(), Error> {
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn run_snap(sudo: Option<&PathBuf>, run_type: RunType) -> Result<(), Error> {
|
||||
pub fn run_snap(sudo: Option<&PathBuf>, run_type: RunType) -> Result<()> {
|
||||
let sudo = require_option(sudo)?;
|
||||
let snap = require("snap")?;
|
||||
|
||||
if !PathBuf::from("/var/snapd.socket").exists() && !PathBuf::from("/run/snapd.socket").exists() {
|
||||
return Err(ErrorKind::SkipStep.into());
|
||||
return Err(SkipStep.into());
|
||||
}
|
||||
print_separator("snap");
|
||||
|
||||
@@ -446,7 +446,7 @@ pub fn run_snap(sudo: Option<&PathBuf>, run_type: RunType) -> Result<(), Error>
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn run_rpi_update(sudo: Option<&PathBuf>, run_type: RunType) -> Result<(), Error> {
|
||||
pub fn run_rpi_update(sudo: Option<&PathBuf>, run_type: RunType) -> Result<()> {
|
||||
let sudo = require_option(sudo)?;
|
||||
let rpi_update = require("rpi-update")?;
|
||||
|
||||
@@ -456,7 +456,7 @@ pub fn run_rpi_update(sudo: Option<&PathBuf>, run_type: RunType) -> Result<(), E
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn run_pihole_update(sudo: Option<&PathBuf>, run_type: RunType) -> Result<(), Error> {
|
||||
pub fn run_pihole_update(sudo: Option<&PathBuf>, run_type: RunType) -> Result<()> {
|
||||
let sudo = require_option(sudo)?;
|
||||
let pihole = require("pihole")?;
|
||||
|
||||
@@ -466,7 +466,7 @@ pub fn run_pihole_update(sudo: Option<&PathBuf>, run_type: RunType) -> Result<()
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn run_etc_update(sudo: Option<&PathBuf>, run_type: RunType) -> Result<(), Error> {
|
||||
pub fn run_etc_update(sudo: Option<&PathBuf>, run_type: RunType) -> Result<()> {
|
||||
let sudo = require_option(sudo)?;
|
||||
let etc_update = require("etc-update")?;
|
||||
print_separator("etc-update");
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
use crate::error::Error;
|
||||
use crate::executor::RunType;
|
||||
use crate::terminal::print_separator;
|
||||
use anyhow::Result;
|
||||
|
||||
#[must_use]
|
||||
pub fn upgrade_macos(run_type: RunType) -> Result<(), Error> {
|
||||
pub fn upgrade_macos(run_type: RunType) -> Result<()> {
|
||||
print_separator("App Store");
|
||||
|
||||
run_type
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
use crate::error::Error;
|
||||
#[cfg(target_os = "linux")]
|
||||
use crate::error::ErrorKind;
|
||||
use crate::error::SkipStep;
|
||||
use crate::executor::{CommandExt, RunType};
|
||||
use crate::terminal::print_separator;
|
||||
use crate::utils::{require, PathExt};
|
||||
use anyhow::Result;
|
||||
use directories::BaseDirs;
|
||||
use std::env;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::process::Command;
|
||||
|
||||
pub fn run_fisher(base_dirs: &BaseDirs, run_type: RunType) -> Result<(), Error> {
|
||||
pub fn run_fisher(base_dirs: &BaseDirs, run_type: RunType) -> Result<()> {
|
||||
let fish = require("fish")?;
|
||||
base_dirs
|
||||
.home_dir()
|
||||
@@ -26,7 +26,7 @@ pub fn run_fisher(base_dirs: &BaseDirs, run_type: RunType) -> Result<(), Error>
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn run_homebrew(cleanup: bool, run_type: RunType) -> Result<(), Error> {
|
||||
pub fn run_homebrew(cleanup: bool, run_type: RunType) -> Result<()> {
|
||||
let brew = require("brew")?;
|
||||
print_separator("Brew");
|
||||
|
||||
@@ -52,7 +52,7 @@ pub fn run_homebrew(cleanup: bool, run_type: RunType) -> Result<(), Error> {
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn run_nix(run_type: RunType) -> Result<(), Error> {
|
||||
pub fn run_nix(run_type: RunType) -> Result<()> {
|
||||
let nix = require("nix")?;
|
||||
let nix_channel = require("nix-channel")?;
|
||||
let nix_env = require("nix-env")?;
|
||||
@@ -65,7 +65,7 @@ pub fn run_nix(run_type: RunType) -> Result<(), Error> {
|
||||
|
||||
if let Ok(Distribution::NixOS) = Distribution::detect() {
|
||||
debug!("Nix on NixOS must be upgraded via 'nixos-rebuild switch', skipping.");
|
||||
return Err(ErrorKind::SkipStep.into());
|
||||
return Err(SkipStep.into());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -74,21 +74,21 @@ pub fn run_nix(run_type: RunType) -> Result<(), Error> {
|
||||
run_type.execute(&nix_env).arg("--upgrade").check_run()
|
||||
}
|
||||
|
||||
pub fn run_home_manager(run_type: RunType) -> Result<(), Error> {
|
||||
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").check_run()
|
||||
}
|
||||
|
||||
pub fn run_pearl(run_type: RunType) -> Result<(), Error> {
|
||||
pub fn run_pearl(run_type: RunType) -> Result<()> {
|
||||
let pearl = require("pearl")?;
|
||||
print_separator("pearl");
|
||||
|
||||
run_type.execute(&pearl).arg("update").check_run()
|
||||
}
|
||||
|
||||
pub fn run_sdkman(base_dirs: &BaseDirs, cleanup: bool, run_type: RunType) -> Result<(), Error> {
|
||||
pub fn run_sdkman(base_dirs: &BaseDirs, cleanup: bool, run_type: RunType) -> Result<()> {
|
||||
let bash = require("bash")?;
|
||||
|
||||
let sdkman_init_path = env::var("SDKMAN_DIR")
|
||||
|
||||
@@ -1,17 +1,18 @@
|
||||
use crate::error::{Error, ErrorKind};
|
||||
use crate::error::SkipStep;
|
||||
use crate::executor::{CommandExt, RunType};
|
||||
use crate::terminal::print_separator;
|
||||
use crate::utils::require;
|
||||
use anyhow::Result;
|
||||
use std::process::Command;
|
||||
|
||||
pub fn run_chocolatey(run_type: RunType) -> Result<(), Error> {
|
||||
pub fn run_chocolatey(run_type: RunType) -> Result<()> {
|
||||
let choco = require("choco")?;
|
||||
|
||||
print_separator("Chocolatey");
|
||||
run_type.execute(&choco).args(&["upgrade", "all"]).check_run()
|
||||
}
|
||||
|
||||
pub fn run_scoop(run_type: RunType) -> Result<(), Error> {
|
||||
pub fn run_scoop(run_type: RunType) -> Result<()> {
|
||||
let scoop = require("scoop")?;
|
||||
|
||||
print_separator("Scoop");
|
||||
@@ -20,12 +21,12 @@ pub fn run_scoop(run_type: RunType) -> Result<(), Error> {
|
||||
run_type.execute(&scoop).args(&["update", "*"]).check_run()
|
||||
}
|
||||
|
||||
pub fn run_wsl_topgrade(run_type: RunType) -> Result<(), Error> {
|
||||
pub fn run_wsl_topgrade(run_type: RunType) -> Result<()> {
|
||||
let wsl = require("wsl")?;
|
||||
let topgrade = Command::new(&wsl)
|
||||
.args(&["bash", "-l", "which", "topgrade"])
|
||||
.check_output()
|
||||
.map_err(|_| ErrorKind::SkipStep)?;
|
||||
.map_err(|_| SkipStep)?;
|
||||
|
||||
run_type
|
||||
.execute(&wsl)
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
use crate::error::Error;
|
||||
#[cfg(windows)]
|
||||
use crate::error::ErrorKind;
|
||||
use crate::error::SkipStep;
|
||||
use crate::executor::{CommandExt, RunType};
|
||||
use crate::terminal::{is_dumb, print_separator};
|
||||
use crate::utils::{require_option, which, PathExt};
|
||||
use anyhow::Result;
|
||||
use std::path::PathBuf;
|
||||
use std::process::Command;
|
||||
|
||||
@@ -53,7 +53,7 @@ impl Powershell {
|
||||
self.profile.as_ref()
|
||||
}
|
||||
|
||||
pub fn update_modules(&self, run_type: RunType) -> Result<(), Error> {
|
||||
pub fn update_modules(&self, run_type: RunType) -> Result<()> {
|
||||
let powershell = require_option(self.path.as_ref())?;
|
||||
|
||||
print_separator("Powershell Modules Update");
|
||||
@@ -65,11 +65,11 @@ impl Powershell {
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
pub fn windows_update(&self, run_type: RunType) -> Result<(), Error> {
|
||||
pub fn windows_update(&self, run_type: RunType) -> Result<()> {
|
||||
let powershell = require_option(self.path.as_ref())?;
|
||||
|
||||
if !Self::has_module(&powershell, "PSWindowsUpdate") {
|
||||
return Err(ErrorKind::SkipStep.into());
|
||||
return Err(SkipStep.into());
|
||||
}
|
||||
print_separator("Windows Update");
|
||||
|
||||
|
||||
@@ -1,16 +1,15 @@
|
||||
use crate::error::{Error, ErrorKind};
|
||||
use crate::executor::RunType;
|
||||
use crate::terminal::print_separator;
|
||||
use crate::utils::{which, Check, PathExt};
|
||||
use anyhow::Result;
|
||||
use directories::BaseDirs;
|
||||
use failure::ResultExt;
|
||||
use std::env;
|
||||
use std::io;
|
||||
use std::os::unix::process::CommandExt;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::process::{exit, Command};
|
||||
|
||||
pub fn run_tpm(base_dirs: &BaseDirs, run_type: RunType) -> Result<(), Error> {
|
||||
pub fn run_tpm(base_dirs: &BaseDirs, run_type: RunType) -> Result<()> {
|
||||
let tpm = base_dirs
|
||||
.home_dir()
|
||||
.join(".tmux/plugins/tpm/bin/update_plugins")
|
||||
@@ -62,13 +61,11 @@ impl Tmux {
|
||||
.success())
|
||||
}
|
||||
|
||||
fn run_in_session(&self, command: &str) -> Result<(), Error> {
|
||||
fn run_in_session(&self, command: &str) -> Result<()> {
|
||||
self.build()
|
||||
.args(&["new-window", "-a", "-t", "topgrade:1", command])
|
||||
.spawn()
|
||||
.context(ErrorKind::ProcessExecution)?
|
||||
.wait()
|
||||
.context(ErrorKind::ProcessExecution)?
|
||||
.spawn()?
|
||||
.wait()?
|
||||
.check()?;
|
||||
|
||||
Ok(())
|
||||
@@ -107,7 +104,7 @@ pub fn run_in_tmux(args: &Option<String>) -> ! {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn run_remote_topgrade(hostname: &str, ssh: &Path, tmux_args: &Option<String>) -> Result<(), Error> {
|
||||
pub fn run_remote_topgrade(hostname: &str, ssh: &Path, tmux_args: &Option<String>) -> Result<()> {
|
||||
let command = format!(
|
||||
"{ssh} -t {hostname} env TOPGRADE_PREFIX={hostname} TOPGRADE_KEEP_END=1 topgrade",
|
||||
ssh = ssh.display(),
|
||||
@@ -117,9 +114,7 @@ pub fn run_remote_topgrade(hostname: &str, ssh: &Path, tmux_args: &Option<String
|
||||
.build()
|
||||
.args(&["new-window", "-a", "-t", "topgrade:1", &command])
|
||||
.env_remove("TMUX")
|
||||
.spawn()
|
||||
.context(ErrorKind::ProcessExecution)?
|
||||
.wait()
|
||||
.context(ErrorKind::ProcessExecution)?
|
||||
.spawn()?
|
||||
.wait()?
|
||||
.check()
|
||||
}
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
use crate::error::{Error, ErrorKind};
|
||||
use crate::error::{SkipStep, TopgradeError};
|
||||
use anyhow::Result;
|
||||
|
||||
use crate::executor::{CommandExt, ExecutorOutput, RunType};
|
||||
use crate::terminal::print_separator;
|
||||
use crate::utils::{require, require_option, PathExt};
|
||||
@@ -74,7 +76,7 @@ fn upgrade(
|
||||
plugin_framework: PluginFramework,
|
||||
run_type: RunType,
|
||||
cleanup: bool,
|
||||
) -> Result<(), Error> {
|
||||
) -> Result<()> {
|
||||
let output = run_type
|
||||
.execute(&vim)
|
||||
.args(&["-N", "-u"])
|
||||
@@ -95,7 +97,7 @@ fn upgrade(
|
||||
if !status.success() {
|
||||
io::stdout().write(&output.stdout).ok();
|
||||
io::stderr().write(&output.stderr).ok();
|
||||
return Err(ErrorKind::ProcessFailed(status).into());
|
||||
return Err(TopgradeError::ProcessFailed(status).into());
|
||||
} else {
|
||||
println!("Plugins upgraded")
|
||||
}
|
||||
@@ -105,12 +107,12 @@ fn upgrade(
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn upgrade_vim(base_dirs: &BaseDirs, run_type: RunType, cleanup: bool) -> Result<(), Error> {
|
||||
pub fn upgrade_vim(base_dirs: &BaseDirs, run_type: RunType, cleanup: bool) -> Result<()> {
|
||||
let vim = require("vim")?;
|
||||
|
||||
let output = Command::new(&vim).arg("--version").check_output()?;
|
||||
if !output.starts_with("VIM") {
|
||||
return Err(ErrorKind::SkipStep.into());
|
||||
return Err(SkipStep.into());
|
||||
}
|
||||
|
||||
let vimrc = require_option(vimrc(&base_dirs))?;
|
||||
@@ -121,7 +123,7 @@ pub fn upgrade_vim(base_dirs: &BaseDirs, run_type: RunType, cleanup: bool) -> Re
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn upgrade_neovim(base_dirs: &BaseDirs, run_type: RunType, cleanup: bool) -> Result<(), Error> {
|
||||
pub fn upgrade_neovim(base_dirs: &BaseDirs, run_type: RunType, cleanup: bool) -> Result<()> {
|
||||
let nvim = require("nvim")?;
|
||||
let nvimrc = require_option(nvimrc(&base_dirs))?;
|
||||
let plugin_framework = require_option(PluginFramework::detect(&nvimrc))?;
|
||||
@@ -130,7 +132,7 @@ pub fn upgrade_neovim(base_dirs: &BaseDirs, run_type: RunType, cleanup: bool) ->
|
||||
upgrade(&nvim, &nvimrc, plugin_framework, run_type, cleanup)
|
||||
}
|
||||
|
||||
pub fn run_voom(_base_dirs: &BaseDirs, run_type: RunType) -> Result<(), Error> {
|
||||
pub fn run_voom(_base_dirs: &BaseDirs, run_type: RunType) -> Result<()> {
|
||||
let voom = require("voom")?;
|
||||
|
||||
print_separator("voom");
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
use crate::error::Error;
|
||||
use crate::executor::RunType;
|
||||
use crate::terminal::print_separator;
|
||||
use crate::utils::{require, PathExt};
|
||||
use anyhow::Result;
|
||||
use directories::BaseDirs;
|
||||
use std::env;
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
pub fn run_zr(base_dirs: &BaseDirs, run_type: RunType) -> Result<(), Error> {
|
||||
pub fn run_zr(base_dirs: &BaseDirs, run_type: RunType) -> Result<()> {
|
||||
let zsh = require("zsh")?;
|
||||
|
||||
env::var("ZR_HOME")
|
||||
@@ -26,7 +26,7 @@ pub fn zshrc(base_dirs: &BaseDirs) -> PathBuf {
|
||||
.unwrap_or_else(|_| base_dirs.home_dir().join(".zshrc"))
|
||||
}
|
||||
|
||||
pub fn run_antigen(base_dirs: &BaseDirs, run_type: RunType) -> Result<(), Error> {
|
||||
pub fn run_antigen(base_dirs: &BaseDirs, run_type: RunType) -> Result<()> {
|
||||
let zsh = require("zsh")?;
|
||||
let zshrc = zshrc(base_dirs).require()?;
|
||||
env::var("ADOTDIR")
|
||||
@@ -40,7 +40,7 @@ pub fn run_antigen(base_dirs: &BaseDirs, run_type: RunType) -> Result<(), Error>
|
||||
run_type.execute(zsh).args(&["-c", cmd.as_str()]).check_run()
|
||||
}
|
||||
|
||||
pub fn run_zplug(base_dirs: &BaseDirs, run_type: RunType) -> Result<(), Error> {
|
||||
pub fn run_zplug(base_dirs: &BaseDirs, run_type: RunType) -> Result<()> {
|
||||
let zsh = require("zsh")?;
|
||||
let zshrc = zshrc(base_dirs).require()?;
|
||||
|
||||
@@ -55,7 +55,7 @@ pub fn run_zplug(base_dirs: &BaseDirs, run_type: RunType) -> Result<(), Error> {
|
||||
run_type.execute(zsh).args(&["-c", cmd.as_str()]).check_run()
|
||||
}
|
||||
|
||||
pub fn run_zplugin(base_dirs: &BaseDirs, run_type: RunType) -> Result<(), Error> {
|
||||
pub fn run_zplugin(base_dirs: &BaseDirs, run_type: RunType) -> Result<()> {
|
||||
let zsh = require("zsh")?;
|
||||
let zshrc = zshrc(base_dirs).require()?;
|
||||
|
||||
@@ -73,7 +73,7 @@ pub fn run_zplugin(base_dirs: &BaseDirs, run_type: RunType) -> Result<(), Error>
|
||||
run_type.execute(zsh).args(&["-c", cmd.as_str()]).check_run()
|
||||
}
|
||||
|
||||
pub fn run_oh_my_zsh(base_dirs: &BaseDirs, run_type: RunType) -> Result<(), Error> {
|
||||
pub fn run_oh_my_zsh(base_dirs: &BaseDirs, run_type: RunType) -> Result<()> {
|
||||
let zsh = require("zsh")?;
|
||||
let zshrc = zshrc(base_dirs).require()?;
|
||||
base_dirs.home_dir().join(".oh-my-zsh").require()?;
|
||||
|
||||
26
src/utils.rs
26
src/utils.rs
@@ -1,4 +1,6 @@
|
||||
use super::error::{Error, ErrorKind};
|
||||
use crate::error::{SkipStep, TopgradeError};
|
||||
use anyhow::Result;
|
||||
|
||||
use log::{debug, error};
|
||||
use std::env;
|
||||
use std::ffi::OsStr;
|
||||
@@ -8,21 +10,21 @@ use std::process::{ExitStatus, Output};
|
||||
use which_crate;
|
||||
|
||||
pub trait Check {
|
||||
fn check(self) -> Result<(), Error>;
|
||||
fn check(self) -> Result<()>;
|
||||
}
|
||||
|
||||
impl Check for ExitStatus {
|
||||
fn check(self) -> Result<(), Error> {
|
||||
fn check(self) -> Result<()> {
|
||||
if self.success() {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(ErrorKind::ProcessFailed(self).into())
|
||||
Err(TopgradeError::ProcessFailed(self).into())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Check for Output {
|
||||
fn check(self) -> Result<(), Error> {
|
||||
fn check(self) -> Result<()> {
|
||||
self.status.check()
|
||||
}
|
||||
}
|
||||
@@ -35,7 +37,7 @@ where
|
||||
fn is_descendant_of(&self, ancestor: &Path) -> bool;
|
||||
|
||||
/// Returns the path if it exists or ErrorKind::SkipStep otherwise
|
||||
fn require(self) -> Result<Self, Error>;
|
||||
fn require(self) -> Result<Self>;
|
||||
}
|
||||
|
||||
impl<T> PathExt for T
|
||||
@@ -54,13 +56,13 @@ where
|
||||
self.as_ref().iter().zip(ancestor.iter()).all(|(a, b)| a == b)
|
||||
}
|
||||
|
||||
fn require(self) -> Result<Self, Error> {
|
||||
fn require(self) -> Result<Self> {
|
||||
if self.as_ref().exists() {
|
||||
debug!("Path {:?} exists", self.as_ref());
|
||||
Ok(self)
|
||||
} else {
|
||||
debug!("Path {:?} doesn't exist", self.as_ref());
|
||||
Err(ErrorKind::SkipStep.into())
|
||||
Err(SkipStep.into())
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -178,7 +180,7 @@ mod tests {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn require<T: AsRef<OsStr> + Debug>(binary_name: T) -> Result<PathBuf, Error> {
|
||||
pub fn require<T: AsRef<OsStr> + Debug>(binary_name: T) -> Result<PathBuf> {
|
||||
match which_crate::which(&binary_name) {
|
||||
Ok(path) => {
|
||||
debug!("Detected {:?} as {:?}", &path, &binary_name);
|
||||
@@ -187,7 +189,7 @@ pub fn require<T: AsRef<OsStr> + Debug>(binary_name: T) -> Result<PathBuf, Error
|
||||
Err(e) => match e.kind() {
|
||||
which_crate::ErrorKind::CannotFindBinaryPath => {
|
||||
debug!("Cannot find {:?}", &binary_name);
|
||||
Err(ErrorKind::SkipStep.into())
|
||||
Err(SkipStep.into())
|
||||
}
|
||||
_ => {
|
||||
panic!("Detecting {:?} failed: {}", &binary_name, e);
|
||||
@@ -197,10 +199,10 @@ pub fn require<T: AsRef<OsStr> + Debug>(binary_name: T) -> Result<PathBuf, Error
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn require_option<T>(option: Option<T>) -> Result<T, Error> {
|
||||
pub fn require_option<T>(option: Option<T>) -> Result<T> {
|
||||
if let Some(value) = option {
|
||||
Ok(value)
|
||||
} else {
|
||||
Err(ErrorKind::SkipStep.into())
|
||||
Err(SkipStep.into())
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user