Better error handling (fixes #15)
This commit is contained in:
14
src/git.rs
14
src/git.rs
@@ -1,3 +1,4 @@
|
||||
use super::Check;
|
||||
use failure::Error;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::process::Command;
|
||||
@@ -38,17 +39,18 @@ impl Git {
|
||||
None
|
||||
}
|
||||
|
||||
pub fn pull<P: AsRef<Path>>(&self, path: P) -> Result<Option<bool>, Error> {
|
||||
pub fn pull<P: AsRef<Path>>(&self, path: P) -> Result<Option<()>, Error> {
|
||||
if let Some(git) = &self.git {
|
||||
if let Ok(mut command) = Command::new(&git)
|
||||
Command::new(&git)
|
||||
.arg("pull")
|
||||
.arg("--rebase")
|
||||
.arg("--autostash")
|
||||
.current_dir(path)
|
||||
.spawn()
|
||||
{
|
||||
return Ok(Some(command.wait()?.success()));
|
||||
}
|
||||
.spawn()?
|
||||
.wait()?
|
||||
.check()?;
|
||||
|
||||
return Ok(Some(()));
|
||||
}
|
||||
|
||||
Ok(None)
|
||||
|
||||
158
src/main.rs
158
src/main.rs
@@ -7,6 +7,7 @@ extern crate termion;
|
||||
|
||||
mod git;
|
||||
mod report;
|
||||
mod steps;
|
||||
mod terminal;
|
||||
|
||||
use failure::Error;
|
||||
@@ -16,7 +17,8 @@ use report::{Report, Reporter};
|
||||
use std::collections::HashSet;
|
||||
use std::env::home_dir;
|
||||
use std::path::PathBuf;
|
||||
use std::process::{Command, ExitStatus};
|
||||
use std::process::ExitStatus;
|
||||
use steps::*;
|
||||
use terminal::Terminal;
|
||||
use which::which;
|
||||
|
||||
@@ -38,8 +40,6 @@ impl Check for ExitStatus {
|
||||
}
|
||||
}
|
||||
|
||||
const EMACS_UPGRADE: &str = include_str!("emacs.el");
|
||||
|
||||
fn home_path(p: &str) -> PathBuf {
|
||||
let mut path = home_dir().unwrap();
|
||||
path.push(p);
|
||||
@@ -88,79 +88,45 @@ fn main() -> Result<(), Error> {
|
||||
|
||||
if cfg!(unix) {
|
||||
if let Ok(zsh) = which("zsh") {
|
||||
terminal.print_separator("zplug");
|
||||
if home_path(".zplug").exists() {
|
||||
Command::new(&zsh)
|
||||
.args(&["-c", "source ~/.zshrc && zplug update"])
|
||||
.spawn()?
|
||||
.wait()?
|
||||
.report("zplug", &mut reports);
|
||||
terminal.print_separator("zplug");
|
||||
run_zplug(&zsh).report("zplug", &mut reports);
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(tpm) = tpm() {
|
||||
terminal.print_separator("tmux plugins");
|
||||
Command::new(&tpm)
|
||||
.arg("all")
|
||||
.spawn()?
|
||||
.wait()?
|
||||
.report("tmux", &mut reports);
|
||||
run_tpm(&tpm).report("tmux", &mut reports);
|
||||
}
|
||||
}
|
||||
|
||||
let cargo_upgrade = home_path(".cargo/bin/cargo-install-update");
|
||||
if cargo_upgrade.exists() {
|
||||
terminal.print_separator("Cargo");
|
||||
Command::new(&cargo_upgrade)
|
||||
.args(&["install-update", "--all"])
|
||||
.spawn()?
|
||||
.wait()?
|
||||
.report("Cargo", &mut reports);
|
||||
run_cargo_update(&cargo_upgrade).report("Cargo", &mut reports);
|
||||
}
|
||||
|
||||
if let Ok(emacs) = which("emacs") {
|
||||
if home_path(".emacs.d").exists() {
|
||||
let init_file = home_path(".emacs.d/init.el");
|
||||
if init_file.exists() {
|
||||
terminal.print_separator("Emacs");
|
||||
Command::new(&emacs)
|
||||
.args(&[
|
||||
"--batch",
|
||||
"-l",
|
||||
home_path(".emacs.d/init.el").to_str().unwrap(),
|
||||
"--eval",
|
||||
EMACS_UPGRADE,
|
||||
])
|
||||
.spawn()?
|
||||
.wait()?
|
||||
.report("Emacs", &mut reports);
|
||||
run_emacs(&emacs, &home_path(".emacs.d/init.el")).report("Emacs", &mut reports);
|
||||
}
|
||||
}
|
||||
|
||||
if let Ok(gem) = which("gem") {
|
||||
terminal.print_separator("RubyGems");
|
||||
Command::new(&gem)
|
||||
.args(&["update"])
|
||||
.spawn()?
|
||||
.wait()?
|
||||
.report("RubyGems", &mut reports);
|
||||
run_gem(&gem).report("RubyGems", &mut reports);
|
||||
}
|
||||
|
||||
if let Ok(npm) = which("npm") {
|
||||
terminal.print_separator("Node Package Manager");
|
||||
Command::new(&npm)
|
||||
.args(&["update", "-g"])
|
||||
.spawn()?
|
||||
.wait()?
|
||||
.report("Node Package Manager", &mut reports);
|
||||
run_npm(&npm).report("Node Package Manager", &mut reports);
|
||||
}
|
||||
|
||||
if let Ok(apm) = which("apm") {
|
||||
terminal.print_separator("Atom Package Manager");
|
||||
Command::new(&apm)
|
||||
.args(&["upgrade", "--confirm=false"])
|
||||
.spawn()?
|
||||
.wait()
|
||||
.map_err(Error::from)?
|
||||
.report("Atom Package Manager", &mut reports);
|
||||
run_apm(&apm).report("Atom Package Manager", &mut reports);
|
||||
}
|
||||
|
||||
if cfg!(target_os = "linux") {
|
||||
@@ -168,87 +134,29 @@ fn main() -> Result<(), Error> {
|
||||
|
||||
terminal.print_separator("System update");
|
||||
match os_type::current_platform().os_type {
|
||||
OSType::Arch => {
|
||||
if let Ok(yay) = which("yay") {
|
||||
Command::new(yay)
|
||||
.spawn()?
|
||||
.wait()?
|
||||
.report("System upgrade", &mut reports);
|
||||
} else {
|
||||
if let Ok(sudo) = &sudo {
|
||||
Command::new(&sudo)
|
||||
.args(&["pacman", "-Syu"])
|
||||
.spawn()?
|
||||
.wait()?
|
||||
.report("System upgrade", &mut reports);
|
||||
} else {
|
||||
terminal.print_warning("No sudo or yay detected. Skipping system upgrade");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
OSType::CentOS | OSType::Redhat => {
|
||||
if let Ok(sudo) = &sudo {
|
||||
Command::new(&sudo)
|
||||
.args(&["yum", "upgrade"])
|
||||
.spawn()?
|
||||
.wait()?
|
||||
.report("System upgrade", &mut reports);;
|
||||
}
|
||||
}
|
||||
|
||||
OSType::Ubuntu | OSType::Debian => {
|
||||
if let Ok(sudo) = &sudo {
|
||||
Command::new(&sudo)
|
||||
.args(&["apt", "update"])
|
||||
.spawn()?
|
||||
.wait()?
|
||||
.check()
|
||||
.and_then(|()| {
|
||||
Command::new(&sudo)
|
||||
.args(&["apt", "dist-upgrade"])
|
||||
.spawn()?
|
||||
.wait()
|
||||
.map_err(Error::from)
|
||||
})?
|
||||
.report("System upgrade", &mut reports);;
|
||||
}
|
||||
}
|
||||
|
||||
OSType::Arch => Some(upgrade_arch_linux(&sudo, &terminal)),
|
||||
OSType::CentOS | OSType::Redhat => Some(upgrade_redhat(&sudo, &terminal)),
|
||||
OSType::Ubuntu | OSType::Debian => Some(upgrade_debian(&sudo, &terminal)),
|
||||
OSType::Unknown => {
|
||||
terminal.print_warning(
|
||||
"Could not detect your Linux distribution. Do you have lsb-release installed?",
|
||||
);
|
||||
|
||||
None
|
||||
}
|
||||
|
||||
_ => (),
|
||||
}
|
||||
_ => None,
|
||||
}.report("System upgrade", &mut reports);
|
||||
|
||||
if let Ok(fwupdmgr) = which("fwupdmgr") {
|
||||
terminal.print_separator("Firmware upgrades");
|
||||
Command::new(&fwupdmgr)
|
||||
.arg("refresh")
|
||||
.spawn()?
|
||||
.wait()?
|
||||
.check()
|
||||
.and_then(|()| {
|
||||
Command::new(&fwupdmgr)
|
||||
.arg("get-updates")
|
||||
.spawn()?
|
||||
.wait()
|
||||
.map_err(Error::from)
|
||||
})?
|
||||
.report("Firmware upgrade", &mut reports);
|
||||
run_fwupdmgr(&fwupdmgr).report("Firmware upgrade", &mut reports);
|
||||
}
|
||||
|
||||
if let Ok(sudo) = &sudo {
|
||||
if let Ok(needrestart) = which("needrestart") {
|
||||
if let Ok(_) = which("needrestart") {
|
||||
terminal.print_separator("Check for needed restarts");
|
||||
Command::new(&sudo)
|
||||
.arg(&needrestart)
|
||||
.spawn()?
|
||||
.wait()?
|
||||
.report("Restarts", &mut reports);
|
||||
run_needrestart(&sudo).report("Restarts", &mut reports);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -256,27 +164,11 @@ fn main() -> Result<(), Error> {
|
||||
if cfg!(target_os = "macos") {
|
||||
if let Ok(brew) = which("brew") {
|
||||
terminal.print_separator("Homebrew");
|
||||
Command::new(&brew)
|
||||
.arg("update")
|
||||
.spawn()?
|
||||
.wait()?
|
||||
.check()
|
||||
.and_then(|()| {
|
||||
Command::new(&brew)
|
||||
.arg("upgrade")
|
||||
.spawn()?
|
||||
.wait()
|
||||
.map_err(Error::from)
|
||||
})?
|
||||
.report("Homebrew", &mut reports);
|
||||
run_homebrew(&brew).report("Homebrew", &mut reports);
|
||||
}
|
||||
|
||||
terminal.print_separator("System update");
|
||||
Command::new("softwareupdate")
|
||||
.args(&["--install", "--all"])
|
||||
.spawn()?
|
||||
.wait()?
|
||||
.report("System upgrade", &mut reports);;
|
||||
upgrade_macos().report("System upgrade", &mut reports);;
|
||||
}
|
||||
|
||||
let mut reports: Vec<_> = reports.into_iter().collect();
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
use std::borrow::Cow;
|
||||
use std::collections::HashMap;
|
||||
use std::process::ExitStatus;
|
||||
|
||||
pub type Report = HashMap<String, bool>;
|
||||
|
||||
@@ -8,9 +7,30 @@ pub trait Reporter {
|
||||
fn report<'a, M: Into<Cow<'a, str>>>(&self, key: M, report: &mut Report);
|
||||
}
|
||||
|
||||
impl Reporter for ExitStatus {
|
||||
impl<T, E> Reporter for Result<T, E>
|
||||
where
|
||||
T: Reporter,
|
||||
{
|
||||
fn report<'a, M: Into<Cow<'a, str>>>(&self, key: M, report: &mut Report) {
|
||||
report.insert(key.into().into_owned(), self.success());
|
||||
match self {
|
||||
Err(_) => {
|
||||
report.insert(key.into().into_owned(), false);
|
||||
}
|
||||
Ok(item) => {
|
||||
item.report(key, report);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Reporter for Option<T>
|
||||
where
|
||||
T: Reporter,
|
||||
{
|
||||
fn report<'a, M: Into<Cow<'a, str>>>(&self, key: M, report: &mut Report) {
|
||||
if let Some(item) = self {
|
||||
item.report(key, report);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,3 +39,9 @@ impl Reporter for bool {
|
||||
report.insert(key.into().into_owned(), *self);
|
||||
}
|
||||
}
|
||||
|
||||
impl Reporter for () {
|
||||
fn report<'a, M: Into<Cow<'a, str>>>(&self, key: M, report: &mut Report) {
|
||||
report.insert(key.into().into_owned(), true);
|
||||
}
|
||||
}
|
||||
|
||||
192
src/steps.rs
Normal file
192
src/steps.rs
Normal file
@@ -0,0 +1,192 @@
|
||||
use super::terminal::Terminal;
|
||||
use super::{which, Check};
|
||||
use failure;
|
||||
use std::path::PathBuf;
|
||||
use std::process::Command;
|
||||
|
||||
const EMACS_UPGRADE: &str = include_str!("emacs.el");
|
||||
|
||||
pub fn run_zplug(zsh: &PathBuf) -> Result<(), failure::Error> {
|
||||
Command::new(zsh)
|
||||
.args(&["-c", "source ~/.zshrc && zplug update"])
|
||||
.spawn()?
|
||||
.wait()?
|
||||
.check()?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn run_tpm(tpm: &PathBuf) -> Result<(), failure::Error> {
|
||||
Command::new(&tpm).arg("all").spawn()?.wait()?.check()?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn run_cargo_update(cargo_update: &PathBuf) -> Result<(), failure::Error> {
|
||||
Command::new(&cargo_update)
|
||||
.args(&["install-update", "--all"])
|
||||
.spawn()?
|
||||
.wait()?
|
||||
.check()?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn run_emacs(emacs: &PathBuf, init: &PathBuf) -> Result<(), failure::Error> {
|
||||
Command::new(&emacs)
|
||||
.args(&[
|
||||
"--batch",
|
||||
"-l",
|
||||
init.to_str().unwrap(),
|
||||
"--eval",
|
||||
EMACS_UPGRADE,
|
||||
])
|
||||
.spawn()?
|
||||
.wait()?
|
||||
.check()?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn run_gem(gem: &PathBuf) -> Result<(), failure::Error> {
|
||||
Command::new(&gem)
|
||||
.args(&["update"])
|
||||
.spawn()?
|
||||
.wait()?
|
||||
.check()?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn run_npm(npm: &PathBuf) -> Result<(), failure::Error> {
|
||||
Command::new(&npm)
|
||||
.args(&["update", "-g"])
|
||||
.spawn()?
|
||||
.wait()?
|
||||
.check()?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn run_apm(apm: &PathBuf) -> Result<(), failure::Error> {
|
||||
Command::new(&apm)
|
||||
.args(&["upgrade", "--confirm=false"])
|
||||
.spawn()?
|
||||
.wait()?
|
||||
.check()?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn run_needrestart(sudo: &PathBuf) -> Result<(), failure::Error> {
|
||||
Command::new(&sudo)
|
||||
.arg("needrestart")
|
||||
.spawn()?
|
||||
.wait()?
|
||||
.check()?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn run_fwupdmgr(fwupdmgr: &PathBuf) -> Result<(), failure::Error> {
|
||||
Command::new(&fwupdmgr)
|
||||
.arg("refresh")
|
||||
.spawn()?
|
||||
.wait()?
|
||||
.check()?;
|
||||
|
||||
Command::new(&fwupdmgr)
|
||||
.arg("get-updates")
|
||||
.spawn()?
|
||||
.wait()?
|
||||
.check()?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn upgrade_macos() -> Result<(), failure::Error> {
|
||||
Command::new("softwareupdate")
|
||||
.args(&["--install", "--all"])
|
||||
.spawn()?
|
||||
.wait()?
|
||||
.check()?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn run_homebrew(homebrew: &PathBuf) -> Result<(), failure::Error> {
|
||||
Command::new(&homebrew)
|
||||
.arg("update")
|
||||
.spawn()?
|
||||
.wait()?
|
||||
.check()?;
|
||||
|
||||
Command::new(&homebrew)
|
||||
.arg("upgrade")
|
||||
.spawn()?
|
||||
.wait()?
|
||||
.check()?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn upgrade_arch_linux(
|
||||
sudo: &Result<PathBuf, which::Error>,
|
||||
terminal: &Terminal,
|
||||
) -> Result<(), failure::Error> {
|
||||
if let Ok(yay) = which("yay") {
|
||||
Command::new(yay).spawn()?.wait()?.check()?;
|
||||
} else {
|
||||
if let Ok(sudo) = &sudo {
|
||||
Command::new(&sudo)
|
||||
.args(&["pacman", "-Syu"])
|
||||
.spawn()?
|
||||
.wait()?
|
||||
.check()?;
|
||||
} else {
|
||||
terminal.print_warning("No sudo or yay detected. Skipping system upgrade");
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn upgrade_redhat(
|
||||
sudo: &Result<PathBuf, which::Error>,
|
||||
terminal: &Terminal,
|
||||
) -> Result<(), failure::Error> {
|
||||
if let Ok(sudo) = &sudo {
|
||||
Command::new(&sudo)
|
||||
.args(&["yum", "upgrade"])
|
||||
.spawn()?
|
||||
.wait()?
|
||||
.check()?;
|
||||
} else {
|
||||
terminal.print_warning("No sudo detected. Skipping system upgrade");
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn upgrade_debian(
|
||||
sudo: &Result<PathBuf, which::Error>,
|
||||
terminal: &Terminal,
|
||||
) -> Result<(), failure::Error> {
|
||||
if let Ok(sudo) = &sudo {
|
||||
Command::new(&sudo)
|
||||
.args(&["apt", "update"])
|
||||
.spawn()?
|
||||
.wait()?
|
||||
.check()?;
|
||||
|
||||
Command::new(&sudo)
|
||||
.args(&["apt", "upgrade"])
|
||||
.spawn()?
|
||||
.wait()?
|
||||
.check()?;
|
||||
} else {
|
||||
terminal.print_warning("No sudo detected. Skipping system upgrade");
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
Reference in New Issue
Block a user