diff --git a/Cargo.lock b/Cargo.lock index b71706e..c584d36 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -16,12 +16,9 @@ name = "alejandra_cli" version = "2.0.0" dependencies = [ "alejandra", - "atty", "clap", - "indoc", - "rayon", - "termion", - "tui", + "futures", + "num_cpus", "walkdir", ] @@ -48,12 +45,6 @@ version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" -[[package]] -name = "cassowary" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df8670b8c7b9dae1793364eafadf7239c40d669904660c5960d74cfd80b46a53" - [[package]] name = "cbitset" version = "0.2.0" @@ -69,17 +60,11 @@ version = "1.0.73" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2fff2a6927b3bb87f9595d67196a70493f627687a71d87a0d692242c33f58c11" -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" - [[package]] name = "clap" -version = "3.2.10" +version = "3.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69c5a7f9997be616e47f0577ee38c91decb33392c5be4866494f34cdf329a9aa" +checksum = "a3dbbb6653e7c55cc8595ad3e1f7be8f32aba4eb7ff7f0fd1163d4f3d137c0a9" dependencies = [ "atty", "bitflags", @@ -94,9 +79,9 @@ dependencies = [ [[package]] name = "clap_derive" -version = "3.2.7" +version = "3.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "759bf187376e1afa7b85b959e6a664a3e7a95203415dba952ad19139e798f902" +checksum = "9ba52acd3b0a5c33aeada5cdaa3267cdc7c594a98731d4268cdc1532f4264cb4" dependencies = [ "heck", "proc-macro-error", @@ -121,55 +106,82 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "328b822bdcba4d4e402be8d9adb6eebf269f969f8eadef977a553ff3c4fbcb58" [[package]] -name = "crossbeam-channel" -version = "0.5.5" +name = "futures" +version = "0.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c02a4d71819009c192cf4872265391563fd6a84c81ff2c0f2a7026ca4c1d85c" +checksum = "f73fe65f54d1e12b726f517d3e2135ca3125a437b6d998caf1962961f7172d9e" dependencies = [ - "cfg-if", - "crossbeam-utils", + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", ] [[package]] -name = "crossbeam-deque" -version = "0.8.1" +name = "futures-channel" +version = "0.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6455c0ca19f0d2fbf751b908d5c55c1f5cbc65e03c4225427254b46890bdde1e" +checksum = "c3083ce4b914124575708913bca19bfe887522d6e2e6d0952943f5eac4a74010" dependencies = [ - "cfg-if", - "crossbeam-epoch", - "crossbeam-utils", + "futures-core", + "futures-sink", ] [[package]] -name = "crossbeam-epoch" -version = "0.9.9" +name = "futures-core" +version = "0.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07db9d94cbd326813772c968ccd25999e5f8ae22f4f8d1b11effa37ef6ce281d" +checksum = "0c09fd04b7e4073ac7156a9539b57a484a8ea920f79c7c675d05d289ab6110d3" + +[[package]] +name = "futures-executor" +version = "0.3.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9420b90cfa29e327d0429f19be13e7ddb68fa1cccb09d65e5706b8c7a749b8a6" dependencies = [ - "autocfg", - "cfg-if", - "crossbeam-utils", - "memoffset", - "once_cell", - "scopeguard", + "futures-core", + "futures-task", + "futures-util", + "num_cpus", ] [[package]] -name = "crossbeam-utils" -version = "0.8.10" +name = "futures-io" +version = "0.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d82ee10ce34d7bc12c2122495e7593a9c41347ecdd64185af4ecf72cb1a7f83" -dependencies = [ - "cfg-if", - "once_cell", -] +checksum = "fc4045962a5a5e935ee2fdedaa4e08284547402885ab326734432bed5d12966b" [[package]] -name = "either" -version = "1.7.0" +name = "futures-sink" +version = "0.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f107b87b6afc2a64fd13cac55fe06d6c8859f12d4b14cbcdd2c67d0976781be" +checksum = "21163e139fa306126e6eedaf49ecdb4588f939600f0b1e770f4205ee4b7fa868" + +[[package]] +name = "futures-task" +version = "0.3.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57c66a976bf5909d801bbef33416c41372779507e7a6b3a5e25e4749c58f776a" + +[[package]] +name = "futures-util" +version = "0.3.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8b7abd5d659d9b90c8cba917f6ec750a74e2dc23902ef9cd4cc8c8b22e6036a" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite", + "pin-utils", + "slab", +] [[package]] name = "hashbrown" @@ -179,9 +191,9 @@ checksum = "d7afe4a420e3fe79967a00898cc1f4db7c8a49a9333a29f8a4bd76a253d5cd04" [[package]] name = "hashbrown" -version = "0.12.2" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "607c8a29735385251a339424dd462993c0fed8fa09d378f259377df08c126022" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" [[package]] name = "heck" @@ -205,20 +217,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "10a35a97730320ffe8e2d410b5d3b69279b98d2c14bdb8b70ea89ecf7888d41e" dependencies = [ "autocfg", - "hashbrown 0.12.2", + "hashbrown 0.12.3", ] -[[package]] -name = "indoc" -version = "1.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05a0bd019339e5d968b37855180087b7b9d512c5046fbd244cf8c95687927d6e" - [[package]] name = "libc" -version = "0.2.126" +version = "0.2.127" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "349d5a591cd28b49e1d1037471617a32ddcda5731b99419008085f72d5a53836" +checksum = "505e71a4706fa491e9b1b55f51b95d4037d0821ee40131190475f692b35b009b" [[package]] name = "libmimalloc-sys" @@ -229,6 +235,12 @@ dependencies = [ "cc", ] +[[package]] +name = "memchr" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" + [[package]] name = "memoffset" version = "0.6.5" @@ -266,12 +278,6 @@ dependencies = [ "libc", ] -[[package]] -name = "numtoa" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8f8bdf33df195859076e54ab11ee78a1b208382d3a26ec40d142ffc1ecc49ef" - [[package]] name = "once_cell" version = "1.13.0" @@ -280,9 +286,21 @@ checksum = "18a6dbe30758c9f83eb00cbea4ac95966305f5a7772f3f42ebfc7fc7eddbd8e1" [[package]] name = "os_str_bytes" -version = "6.1.0" +version = "6.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21326818e99cfe6ce1e524c2a805c189a99b5ae555a35d19f9a284b427d86afa" +checksum = "648001efe5d5c0102d8cea768e348da85d90af8ba91f0bea908f157951493cd4" + +[[package]] +name = "pin-project-lite" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] name = "proc-macro-error" @@ -310,64 +328,22 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.40" +version = "1.0.43" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd96a1e8ed2596c337f8eae5f24924ec83f5ad5ab21ea8e455d3566c69fbcaf7" +checksum = "0a2ca2c61bc9f3d74d2886294ab7b9853abd9c1ad903a3ac7815c58989bb7bab" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.20" +version = "1.0.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3bcdf212e9776fbcb2d23ab029360416bb1706b1aea2d1a5ba002727cbcab804" +checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179" dependencies = [ "proc-macro2", ] -[[package]] -name = "rayon" -version = "1.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd99e5772ead8baa5215278c9b15bf92087709e9c1b2d1f97cdb5a183c933a7d" -dependencies = [ - "autocfg", - "crossbeam-deque", - "either", - "rayon-core", -] - -[[package]] -name = "rayon-core" -version = "1.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "258bcdb5ac6dad48491bb2992db6b7cf74878b0384908af124823d118c99683f" -dependencies = [ - "crossbeam-channel", - "crossbeam-deque", - "crossbeam-utils", - "num_cpus", -] - -[[package]] -name = "redox_syscall" -version = "0.2.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62f25bc4c7e55e0b0b7a1d43fb893f4fa1361d0abe38b9ce4f323c2adfe6ef42" -dependencies = [ - "bitflags", -] - -[[package]] -name = "redox_termios" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8440d8acb4fd3d277125b4bd01a6f38aee8d814b3b5fc09b3f2b825d37d3fe8f" -dependencies = [ - "redox_syscall", -] - [[package]] name = "rnix" version = "0.10.2" @@ -408,16 +384,19 @@ dependencies = [ ] [[package]] -name = "scopeguard" -version = "1.1.0" +name = "serde" +version = "1.0.142" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" +checksum = "e590c437916fb6b221e1d00df6e3294f3fccd70ca7e92541c475d6ed6ef5fee2" [[package]] -name = "serde" -version = "1.0.139" +name = "slab" +version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0171ebb889e45aa68b44aee0859b3eede84c6f5f5c228e6f140c0b2a0a46cad6" +checksum = "4614a76b2a8be0058caa9dbbaf66d988527d86d003c11a94fbd335d7661edcef" +dependencies = [ + "autocfg", +] [[package]] name = "smol_str" @@ -436,9 +415,9 @@ checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" [[package]] name = "syn" -version = "1.0.98" +version = "1.0.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c50aef8a904de4c23c788f104b7dddc7d6f79c647c7c8ce4cc8f73eb0ca773dd" +checksum = "58dbef6ec655055e20b86b15a8cc6d439cca19b667537ac6a1369572d151ab13" dependencies = [ "proc-macro2", "quote", @@ -454,18 +433,6 @@ dependencies = [ "winapi-util", ] -[[package]] -name = "termion" -version = "1.5.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "077185e2eac69c3f8379a4298e1e07cd36beb962290d4a51199acf0fdc10607e" -dependencies = [ - "libc", - "numtoa", - "redox_syscall", - "redox_termios", -] - [[package]] name = "text-size" version = "1.1.0" @@ -478,36 +445,11 @@ version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b1141d4d61095b28419e22cb0bbf02755f5e54e0526f97f1e3d1d160e60885fb" -[[package]] -name = "tui" -version = "0.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96fe69244ec2af261bced1d9046a6fee6c8c2a6b0228e59e5ba39bc8ba4ed729" -dependencies = [ - "bitflags", - "cassowary", - "termion", - "unicode-segmentation", - "unicode-width", -] - [[package]] name = "unicode-ident" -version = "1.0.1" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5bd2fe26506023ed7b5e1e315add59d6f584c621d037f9368fea9cfb988f368c" - -[[package]] -name = "unicode-segmentation" -version = "1.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e8820f5d777f6224dc4be3632222971ac30164d4a258d595640799554ebfd99" - -[[package]] -name = "unicode-width" -version = "0.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ed742d4ea2bd1176e236172c8429aaf54486e7ac098db29ffe6529e0ce50973" +checksum = "c4f5b37a154999a8f3f98cc23a628d850e154479cd94decf3414696e12e31aaf" [[package]] name = "version_check" diff --git a/src/alejandra_cli/Cargo.toml b/src/alejandra_cli/Cargo.toml index 484d604..8c32f9b 100644 --- a/src/alejandra_cli/Cargo.toml +++ b/src/alejandra_cli/Cargo.toml @@ -4,13 +4,18 @@ path = "src/main.rs" [dependencies] alejandra = { path = "../alejandra" } -atty = "*" -clap = { version = "3", features = ["derive"] } -indoc = "*" -rayon = "*" -termion = "*" -tui = { version = "*", default-features = false, features = ["termion"] } -walkdir = { version = "*" } +clap = { version = "*", default_features = false, features = [ + "color", + "derive", + "std", + "strsim" +] } +futures = { version = "*", default_features = false, features = [ + "executor", + "thread-pool" +] } +num_cpus = { version = "*", default_features = false, features = [] } +walkdir = { version = "*", default_features = false, features = [] } [package] authors = ["Kevin Amado "] diff --git a/src/alejandra_cli/src/cli.rs b/src/alejandra_cli/src/cli.rs index b87ae15..7ac80a6 100644 --- a/src/alejandra_cli/src/cli.rs +++ b/src/alejandra_cli/src/cli.rs @@ -1,4 +1,9 @@ +use std::io::Read; + use clap::Parser; +use futures::future::RemoteHandle; +use futures::stream::FuturesUnordered; +use futures::task::SpawnExt; #[derive(Clone)] pub(crate) struct FormattedPath { @@ -6,16 +11,12 @@ pub(crate) struct FormattedPath { pub status: alejandra::format::Status, } -const AFTER_HELP: &str = indoc::indoc! {" - The program will exit with status code: - 1, if any error occurs. - 2, if --check was used and any file was changed. - 0, otherwise. - - Your star and feedback is very much appreciated! - https://github.com/kamadorueda/alejandra - " -}; +const AFTER_HELP: &str = concat!( + "Alejandra will exit with status code:\n", + " 1, if any error occurs.\n", + " 2, if --check was used and any file requires formatting.\n", + " 0, otherwise.", +); /// The Uncompromising Nix Code Formatter. #[derive(Debug, Parser)] @@ -41,9 +42,9 @@ struct Args { check: bool, /// Number of formatting threads to spawn. Defaults to the number of - /// logical CPUs. - #[clap(long, short)] - threads: Option, + /// physical CPUs. + #[clap(long, short, value_parser = clap::value_parser!(u8).range(1..))] + threads: Option, /// Hide the details, only show error messages. #[clap(long, short)] @@ -51,13 +52,13 @@ struct Args { } pub(crate) fn stdin(quiet: bool) -> FormattedPath { - use std::io::Read; - let mut before = String::new(); let path = "".to_string(); if !quiet { - eprintln!("Formatting stdin, run with --help to see all options."); + eprintln!("Formatting stdin."); + eprintln!("Use --help to see all command line options."); + eprintln!("use --quiet to suppress this and all messages."); } std::io::stdin().read_to_string(&mut before).unwrap(); @@ -65,7 +66,7 @@ pub(crate) fn stdin(quiet: bool) -> FormattedPath { let (status, data) = alejandra::format::in_memory(path.clone(), before.clone()); - print!("{}", data); + print!("{data}"); FormattedPath { path, status } } @@ -74,275 +75,65 @@ pub(crate) fn simple( paths: Vec, in_place: bool, quiet: bool, + threads: usize, ) -> Vec { - use rayon::prelude::*; + let paths_len = paths.len(); if !quiet { - eprintln!("Processing: {} files", paths.len()); + eprintln!( + "{} {paths_len} file{} using {threads} thread{}", + if in_place { "Formatting" } else { "Checking formatting in" }, + if paths_len == 1 { "" } else { "s" }, + if threads == 1 { "" } else { "s" }, + ); + eprintln!(); } - paths - .par_iter() - .map(|path| { - let status = alejandra::format::in_fs(path.clone(), in_place); + let pool = futures::executor::ThreadPoolBuilder::new() + .pool_size(threads) + .create() + .expect("Unable to instantiate a new thread pool"); - if let alejandra::format::Status::Changed(changed) = status { - if changed && !quiet { - if in_place { - eprintln!("Changed: {}", &path); - } else { - eprintln!("Would be changed: {}", &path); + let futures: FuturesUnordered> = paths + .into_iter() + .map(|path| { + pool.spawn_with_handle(async move { + let status = alejandra::format::in_fs(path.clone(), in_place); + + if let alejandra::format::Status::Changed(changed) = status { + if changed && !quiet { + println!( + "{}: {path}", + if in_place { + "Changed" + } else { + "Requires formatting" + }, + ); } } - } - FormattedPath { path: path.clone(), status } + FormattedPath { path: path.clone(), status } + }) + .expect("Unable to spawn formatting task") }) - .collect() -} + .collect(); -pub(crate) fn tui( - paths: Vec, - in_place: bool, -) -> std::io::Result> { - use rayon::prelude::*; - use termion::input::TermRead; - use termion::raw::IntoRawMode; - - enum Event { - FormattedPath(FormattedPath), - FormattingFinished, - Input(termion::event::Key), - Tick, - } - - let paths_to_format = paths.len(); - let mut formatted_paths = std::collections::LinkedList::new(); - - let stdout = std::io::stderr().into_raw_mode()?; - let backend = tui::backend::TermionBackend::new(stdout); - let mut terminal = tui::Terminal::new(backend)?; - terminal.clear()?; - - let (sender, receiver) = std::sync::mpsc::channel(); - - // Listen to user input - let sender_keys = sender.clone(); - std::thread::spawn(move || { - let stdin = std::io::stdin(); - for key in stdin.keys().flatten() { - if let Err(error) = sender_keys.send(Event::Input(key)) { - eprintln!("{}", error); - return; - } - } - }); - - // Listen to the clock - let sender_clock = sender.clone(); - std::thread::spawn(move || { - loop { - if let Err(error) = sender_clock.send(Event::Tick) { - eprintln!("{}", error); - break; - } - std::thread::sleep(std::time::Duration::from_millis(250)); - } - }); - - // Listen to the processed items - let sender_paths = sender.clone(); - let sender_finished = sender; - std::thread::spawn(move || { - paths.into_par_iter().for_each_with(sender_paths, |sender, path| { - let status = alejandra::format::in_fs(path.clone(), in_place); - - if let Err(error) = sender - .send(Event::FormattedPath(FormattedPath { path, status })) - { - eprintln!("{}", error); - } - }); - - if let Err(error) = sender_finished.send(Event::FormattingFinished) { - eprintln!("{}", error); - } - }); - - let mut finished = false; - let mut paths_with_errors: usize = 0; - let mut paths_changed: usize = 0; - let mut paths_unchanged: usize = 0; - - while !finished { - loop { - if let Ok(event) = receiver.try_recv() { - match event { - Event::FormattedPath(formatted_path) => { - match &formatted_path.status { - alejandra::format::Status::Changed(changed) => { - if *changed { - paths_changed += 1; - } else { - paths_unchanged += 1; - } - }, - alejandra::format::Status::Error(_) => { - paths_with_errors += 1; - }, - }; - - formatted_paths.push_back(formatted_path); - }, - Event::FormattingFinished => { - finished = true; - }, - Event::Input(key) => { - if let termion::event::Key::Ctrl('c') = key { - return Err(std::io::ErrorKind::Interrupted.into()); - } - }, - Event::Tick => { - break; - }, - } - } - } - - terminal.draw(|frame| { - let sizes = tui::layout::Layout::default() - .constraints([ - tui::layout::Constraint::Length(3), - tui::layout::Constraint::Length(3), - tui::layout::Constraint::Max(8), - tui::layout::Constraint::Length(0), - ]) - .split(frame.size()); - let size = tui::layout::Rect::new(0, 0, 0, 0) - .union(sizes[0]) - .union(sizes[1]) - .union(sizes[2]); - - let header = tui::widgets::Paragraph::new(vec![ - tui::text::Spans::from(vec![ - tui::text::Span::styled( - "Alejandra", - tui::style::Style::default() - .fg(tui::style::Color::Green), - ), - tui::text::Span::raw(" "), - tui::text::Span::raw(alejandra::version::VERSION), - ]), - tui::text::Spans::from(vec![tui::text::Span::raw( - "The Uncompromising Nix Code Formatter", - )]), - ]) - .alignment(tui::layout::Alignment::Center) - .style( - tui::style::Style::default() - .bg(tui::style::Color::Black) - .fg(tui::style::Color::White), - ); - - let progress = tui::widgets::Gauge::default() - .block( - tui::widgets::Block::default() - .borders(tui::widgets::Borders::ALL) - .title(format!( - " Formatting ({} {}, {} unchanged, {} errors) ", - paths_changed, - if in_place { - "changed" - } else { - "would be changed" - }, - paths_unchanged, - paths_with_errors - )), - ) - .gauge_style( - tui::style::Style::default() - .fg(tui::style::Color::Green) - .bg(tui::style::Color::Black) - .add_modifier(tui::style::Modifier::ITALIC), - ) - .percent(if paths_to_format == 0 { - 100 - } else { - 100 * (paths_changed + paths_unchanged + paths_with_errors) - / paths_to_format - } as u16) - .style( - tui::style::Style::default() - .bg(tui::style::Color::Black) - .fg(tui::style::Color::White), - ); - let logger = tui::widgets::Paragraph::new( - formatted_paths - .iter() - .rev() - .take(8) - .map(|formatted_path| { - tui::text::Spans::from(vec![ - match formatted_path.status { - alejandra::format::Status::Changed(changed) => { - tui::text::Span::styled( - if changed { - if in_place { - "CHANGED " - } else { - "WOULD BE CHANGED " - } - } else { - "OK " - }, - tui::style::Style::default() - .fg(tui::style::Color::Green), - ) - }, - alejandra::format::Status::Error(_) => { - tui::text::Span::styled( - "ERROR ", - tui::style::Style::default() - .fg(tui::style::Color::Red), - ) - }, - }, - tui::text::Span::raw(formatted_path.path.clone()), - ]) - }) - .collect::>(), - ) - .style( - tui::style::Style::default() - .bg(tui::style::Color::Black) - .fg(tui::style::Color::White), - ); - - frame.render_widget(header, sizes[0]); - frame.render_widget(progress, sizes[1]); - frame.render_widget(logger, sizes[2]); - frame.set_cursor(size.width, size.height); - })?; - } - - Ok(formatted_paths.iter().cloned().collect()) + futures::executor::block_on_stream(futures).collect() } pub fn main() -> std::io::Result<()> { let args = Args::parse(); let in_place = !args.check; - let threads = args.threads.unwrap_or(0); - - rayon::ThreadPoolBuilder::new() - .num_threads(threads) - .build_global() - .unwrap(); let include: Vec<&str> = args.include.iter().map(String::as_str).collect::>(); + let threads = args + .threads + .map_or_else(num_cpus::get_physical, |threads| threads as usize); + let formatted_paths = match &include[..] { &[] | &["-"] => { vec![crate::cli::stdin(args.quiet)] @@ -350,15 +141,7 @@ pub fn main() -> std::io::Result<()> { include => { let paths = crate::find::nix_files(include, &args.exclude); - if !args.quiet - && atty::is(atty::Stream::Stderr) - && atty::is(atty::Stream::Stdin) - && atty::is(atty::Stream::Stdout) - { - crate::cli::tui(paths, in_place)? - } else { - crate::cli::simple(paths, in_place, args.quiet) - } + crate::cli::simple(paths, in_place, args.quiet, threads) }, }; @@ -372,15 +155,14 @@ pub fn main() -> std::io::Result<()> { if errors > 0 { eprintln!(); eprintln!( - "Failed! We encountered {} error{} at:", - errors, - if errors >= 2 { "s" } else { "" } + "Failed! {errors} error{} found at:", + if errors == 1 { "" } else { "s" } ); for formatted_path in formatted_paths { if let alejandra::format::Status::Error(error) = formatted_path.status { - eprintln!(" {}: {}", formatted_path.path, &error); + eprintln!("- {}: {error}", formatted_path.path); } } std::process::exit(1); @@ -400,24 +182,32 @@ pub fn main() -> std::io::Result<()> { if !args.quiet { eprintln!(); eprintln!( - "Success! {} file{} {}", - changed, - if changed >= 2 { "s" } else { "" }, - if in_place { - if changed >= 2 { "were changed" } else { "was changed" } + "{}! {changed} file{} {}", + if in_place { "Success" } else { "Alert" }, + if changed == 1 { "" } else { "s" }, + if changed == 1 { + if in_place { "was changed" } else { "requires formatting" } + } else if in_place { + "were changed" } else { - "would be changed" + "require formatting" } ); } + if in_place { + ads(); + } std::process::exit(if in_place { 0 } else { 2 }); } if !args.quiet { eprintln!(); - eprintln!("Success! Your code complies the Alejandra style"); + eprintln!("Congratulations! Your code complies the Alejandra style"); + ads(); } std::process::exit(0); } + +fn ads() {}