Use cross-platform terminal handling (#34)
This commit is contained in:
36
Cargo.lock
generated
36
Cargo.lock
generated
@@ -121,6 +121,15 @@ dependencies = [
|
||||
"quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "kernel32-sys"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lazy_static"
|
||||
version = "1.0.1"
|
||||
@@ -273,6 +282,16 @@ dependencies = [
|
||||
"syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "term_size"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "termcolor"
|
||||
version = "0.3.6"
|
||||
@@ -329,7 +348,8 @@ dependencies = [
|
||||
"serde 1.0.67 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_derive 1.0.67 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"shellexpand 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"term_size 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"termcolor 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"toml 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"which 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
@@ -386,6 +406,11 @@ dependencies = [
|
||||
"libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi"
|
||||
version = "0.2.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "winapi"
|
||||
version = "0.3.5"
|
||||
@@ -395,6 +420,11 @@ dependencies = [
|
||||
"winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi-build"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "winapi-i686-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
@@ -428,6 +458,7 @@ dependencies = [
|
||||
"checksum failure 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "934799b6c1de475a012a02dab0ace1ace43789ee4b99bcfbf1a2e3e8ced5de82"
|
||||
"checksum failure_derive 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c7cdda555bb90c9bb67a3b670a0f42de8e73f5981524123ad8578aafec8ddb8b"
|
||||
"checksum humantime 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0484fda3e7007f2a4a0d9c3a703ca38c71c54c55602ce4660c419fd32e188c9e"
|
||||
"checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d"
|
||||
"checksum lazy_static 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e6412c5e2ad9584b0b8e979393122026cdd6d2a80b933f890dcd694ddbe73739"
|
||||
"checksum libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)" = "b685088df2b950fccadf07a7187c8ef846a959c142338a48f9dc0b94517eb5f1"
|
||||
"checksum log 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6fddaa003a65722a7fb9e26b0ce95921fe4ba590542ced664d8ce2fa26f9f3ac"
|
||||
@@ -449,6 +480,7 @@ dependencies = [
|
||||
"checksum syn 0.14.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c67da57e61ebc7b7b6fff56bb34440ca3a83db037320b0507af4c10368deda7d"
|
||||
"checksum synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a393066ed9010ebaed60b9eafa373d4b1baac186dd7e008555b0f702b51945b6"
|
||||
"checksum synstructure 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3a761d12e6d8dcb4dcf952a7a89b475e3a9d69e4a69307e01a470977642914bd"
|
||||
"checksum term_size 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9e5b9a66db815dcfd2da92db471106457082577c3c278d4138ab3e3b4e189327"
|
||||
"checksum termcolor 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "adc4587ead41bf016f11af03e55a624c06568b5a19db4e90fde573d805074f83"
|
||||
"checksum termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "689a3bdfaab439fd92bc87df5c4c78417d3cbe537487274e9b0b2dce76e92096"
|
||||
"checksum textwrap 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "307686869c93e71f94da64286f9a9524c0f308a9e1c87a583de8e9c9039ad3f6"
|
||||
@@ -463,7 +495,9 @@ dependencies = [
|
||||
"checksum vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "05c78687fb1a80548ae3250346c3db86a80a7cdd77bda190189f2d0a0987c81a"
|
||||
"checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d"
|
||||
"checksum which 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "49c4f580e93079b70ac522e7bdebbe1568c8afa7d8d05ee534ee737ca37d2f51"
|
||||
"checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a"
|
||||
"checksum winapi 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "773ef9dcc5f24b7d850d0ff101e542ff24c3b090a9768e03ff889fdef41f00fd"
|
||||
"checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc"
|
||||
"checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
||||
"checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||
"checksum wincolor 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "eeb06499a3a4d44302791052df005d5232b927ed1a9658146d842165c4de7767"
|
||||
|
||||
@@ -13,10 +13,11 @@ failure = "0.1.1"
|
||||
failure_derive = "0.1.1"
|
||||
serde = "1.0.67"
|
||||
serde_derive = "1.0.67"
|
||||
termion = "1.5.1"
|
||||
toml = "0.4.6"
|
||||
which = "2.0.0"
|
||||
shellexpand = "1.0.0"
|
||||
clap = "2.32.0"
|
||||
log = "0.4.2"
|
||||
env_logger = "0.5.10"
|
||||
term_size = "0.3.1"
|
||||
termcolor = "0.3.6"
|
||||
|
||||
17
src/linux.rs
17
src/linux.rs
@@ -52,7 +52,7 @@ impl Distribution {
|
||||
|
||||
pub fn upgrade_arch_linux(
|
||||
sudo: &Option<PathBuf>,
|
||||
terminal: &Terminal,
|
||||
terminal: &mut Terminal,
|
||||
) -> Result<(), failure::Error> {
|
||||
if let Some(yay) = which("yay") {
|
||||
if let Some(python) = which("python") {
|
||||
@@ -82,7 +82,10 @@ It's dangerous to run yay since Python based AUR packages will be installed in t
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn upgrade_redhat(sudo: &Option<PathBuf>, terminal: &Terminal) -> Result<(), failure::Error> {
|
||||
pub fn upgrade_redhat(
|
||||
sudo: &Option<PathBuf>,
|
||||
terminal: &mut Terminal,
|
||||
) -> Result<(), failure::Error> {
|
||||
if let Some(sudo) = &sudo {
|
||||
Command::new(&sudo)
|
||||
.args(&["yum", "upgrade"])
|
||||
@@ -96,7 +99,10 @@ pub fn upgrade_redhat(sudo: &Option<PathBuf>, terminal: &Terminal) -> Result<(),
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn upgrade_fedora(sudo: &Option<PathBuf>, terminal: &Terminal) -> Result<(), failure::Error> {
|
||||
pub fn upgrade_fedora(
|
||||
sudo: &Option<PathBuf>,
|
||||
terminal: &mut Terminal,
|
||||
) -> Result<(), failure::Error> {
|
||||
if let Some(sudo) = &sudo {
|
||||
Command::new(&sudo)
|
||||
.args(&["dnf", "upgrade"])
|
||||
@@ -110,7 +116,10 @@ pub fn upgrade_fedora(sudo: &Option<PathBuf>, terminal: &Terminal) -> Result<(),
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn upgrade_debian(sudo: &Option<PathBuf>, terminal: &Terminal) -> Result<(), failure::Error> {
|
||||
pub fn upgrade_debian(
|
||||
sudo: &Option<PathBuf>,
|
||||
terminal: &mut Terminal,
|
||||
) -> Result<(), failure::Error> {
|
||||
if let Some(sudo) = &sudo {
|
||||
Command::new(&sudo)
|
||||
.args(&["apt", "update"])
|
||||
|
||||
13
src/main.rs
13
src/main.rs
@@ -3,7 +3,6 @@ extern crate failure;
|
||||
extern crate which;
|
||||
#[macro_use]
|
||||
extern crate failure_derive;
|
||||
extern crate termion;
|
||||
extern crate toml;
|
||||
#[macro_use]
|
||||
extern crate serde_derive;
|
||||
@@ -14,6 +13,8 @@ extern crate shellexpand;
|
||||
#[macro_use]
|
||||
extern crate log;
|
||||
extern crate env_logger;
|
||||
extern crate term_size;
|
||||
extern crate termcolor;
|
||||
|
||||
mod config;
|
||||
mod git;
|
||||
@@ -94,7 +95,7 @@ fn run() -> Result<(), Error> {
|
||||
env_logger::init();
|
||||
let git = Git::new();
|
||||
let mut git_repos = Repositories::new(&git);
|
||||
let terminal = Terminal::new();
|
||||
let mut terminal = Terminal::new();
|
||||
let config = Config::read()?;
|
||||
let mut reports = Report::new();
|
||||
|
||||
@@ -116,11 +117,11 @@ fn run() -> Result<(), Error> {
|
||||
match linux::Distribution::detect() {
|
||||
Ok(distribution) => {
|
||||
match distribution {
|
||||
linux::Distribution::Arch => linux::upgrade_arch_linux(&sudo, &terminal),
|
||||
linux::Distribution::CentOS => linux::upgrade_redhat(&sudo, &terminal),
|
||||
linux::Distribution::Fedora => linux::upgrade_fedora(&sudo, &terminal),
|
||||
linux::Distribution::Arch => linux::upgrade_arch_linux(&sudo, &mut terminal),
|
||||
linux::Distribution::CentOS => linux::upgrade_redhat(&sudo, &mut terminal),
|
||||
linux::Distribution::Fedora => linux::upgrade_fedora(&sudo, &mut terminal),
|
||||
linux::Distribution::Ubuntu | linux::Distribution::Debian => {
|
||||
linux::upgrade_debian(&sudo, &terminal)
|
||||
linux::upgrade_debian(&sudo, &mut terminal)
|
||||
}
|
||||
}.report("System upgrade", &mut reports);
|
||||
}
|
||||
|
||||
@@ -1,79 +1,70 @@
|
||||
use std::cmp::{max, min};
|
||||
use termion;
|
||||
use termion::color;
|
||||
use std::io::Write;
|
||||
use term_size;
|
||||
use termcolor::{Color, ColorChoice, ColorSpec, StandardStream, WriteColor};
|
||||
|
||||
pub struct Terminal {
|
||||
width: Option<u16>,
|
||||
width: Option<usize>,
|
||||
stdout: StandardStream,
|
||||
}
|
||||
|
||||
impl Terminal {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
width: termion::terminal_size().map(|(w, _)| w).ok(),
|
||||
width: term_size::dimensions().map(|(w, _)| w),
|
||||
stdout: StandardStream::stdout(ColorChoice::Auto),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn print_separator<P: AsRef<str>>(&self, message: P) {
|
||||
pub fn print_separator<P: AsRef<str>>(&mut self, message: P) {
|
||||
let message = message.as_ref();
|
||||
match self.width {
|
||||
Some(width) => {
|
||||
println!(
|
||||
"\n{}―― {} {:―^border$}{}",
|
||||
color::Fg(color::LightWhite),
|
||||
let _ = self.stdout
|
||||
.set_color(ColorSpec::new().set_fg(Some(Color::White)).set_bold(true));
|
||||
let _ = write!(
|
||||
&mut self.stdout,
|
||||
"\n―― {} {:―^border$}\n",
|
||||
message,
|
||||
"",
|
||||
color::Fg(color::Reset),
|
||||
border = max(2, min(80, width as usize) - 3 - message.len())
|
||||
);
|
||||
let _ = self.stdout.reset();
|
||||
let _ = self.stdout.flush();
|
||||
}
|
||||
None => {
|
||||
println!("―― {} ――", message);
|
||||
let _ = write!(&mut self.stdout, "―― {} ――\n", message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn print_warning<P: AsRef<str>>(&self, message: P) {
|
||||
pub fn print_warning<P: AsRef<str>>(&mut self, message: P) {
|
||||
let message = message.as_ref();
|
||||
|
||||
match self.width {
|
||||
Some(_) => {
|
||||
println!(
|
||||
"{}{}{}",
|
||||
color::Fg(color::LightYellow),
|
||||
message,
|
||||
color::Fg(color::Reset)
|
||||
);
|
||||
}
|
||||
None => {
|
||||
println!("{}", message);
|
||||
}
|
||||
}
|
||||
let _ = self.stdout
|
||||
.set_color(ColorSpec::new().set_fg(Some(Color::Yellow)).set_bold(true));
|
||||
let _ = write!(&mut self.stdout, "{}", message);
|
||||
let _ = self.stdout.reset();
|
||||
let _ = self.stdout.flush();
|
||||
}
|
||||
|
||||
pub fn print_result<P: AsRef<str>>(&self, key: P, succeeded: bool) {
|
||||
pub fn print_result<P: AsRef<str>>(&mut self, key: P, succeeded: bool) {
|
||||
let key = key.as_ref();
|
||||
let _ = write!(&mut self.stdout, "{}: ", key);
|
||||
|
||||
match self.width {
|
||||
Some(_) => {
|
||||
if succeeded {
|
||||
println!(
|
||||
"{}: {}OK{}",
|
||||
key,
|
||||
color::Fg(color::LightGreen),
|
||||
color::Fg(color::Reset)
|
||||
);
|
||||
} else {
|
||||
println!(
|
||||
"{}: {}FAILED{}",
|
||||
key,
|
||||
color::Fg(color::LightRed),
|
||||
color::Fg(color::Reset)
|
||||
);
|
||||
}
|
||||
}
|
||||
None => {
|
||||
println!("{}: {}", key, if succeeded { "OK" } else { "FAILED" });
|
||||
}
|
||||
}
|
||||
let _ = self.stdout.set_color(
|
||||
ColorSpec::new()
|
||||
.set_fg(Some(if succeeded { Color::Green } else { Color::Red }))
|
||||
.set_bold(true),
|
||||
);
|
||||
|
||||
let _ = write!(
|
||||
&mut self.stdout,
|
||||
"{}",
|
||||
if succeeded { "OK" } else { "FAILED" }
|
||||
);
|
||||
|
||||
let _ = self.stdout.reset();
|
||||
let _ = self.stdout.flush();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user