diff --git a/Cargo.lock b/Cargo.lock index 4d4663c6..69a1431c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -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" diff --git a/Cargo.toml b/Cargo.toml index d224c323..63ebb1ea 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -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" diff --git a/src/linux.rs b/src/linux.rs index 5adfb176..23e77a91 100644 --- a/src/linux.rs +++ b/src/linux.rs @@ -52,7 +52,7 @@ impl Distribution { pub fn upgrade_arch_linux( sudo: &Option, - 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, terminal: &Terminal) -> Result<(), failure::Error> { +pub fn upgrade_redhat( + sudo: &Option, + 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, terminal: &Terminal) -> Result<(), Ok(()) } -pub fn upgrade_fedora(sudo: &Option, terminal: &Terminal) -> Result<(), failure::Error> { +pub fn upgrade_fedora( + sudo: &Option, + 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, terminal: &Terminal) -> Result<(), Ok(()) } -pub fn upgrade_debian(sudo: &Option, terminal: &Terminal) -> Result<(), failure::Error> { +pub fn upgrade_debian( + sudo: &Option, + terminal: &mut Terminal, +) -> Result<(), failure::Error> { if let Some(sudo) = &sudo { Command::new(&sudo) .args(&["apt", "update"]) diff --git a/src/main.rs b/src/main.rs index ee8279b7..aa0f50bc 100644 --- a/src/main.rs +++ b/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); } diff --git a/src/terminal.rs b/src/terminal.rs index 1eb157f6..99383583 100644 --- a/src/terminal.rs +++ b/src/terminal.rs @@ -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, + width: Option, + 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>(&self, message: P) { + pub fn print_separator>(&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>(&self, message: P) { + pub fn print_warning>(&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>(&self, key: P, succeeded: bool) { + pub fn print_result>(&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(); } }