1
Fork 0
mirror of https://github.com/RGBCube/alejandra synced 2025-07-30 12:07:46 +00:00

feat: minimalist cli

This commit is contained in:
Kevin Amado 2022-08-05 12:44:30 -06:00
parent 0bf80d7d6f
commit e420f7c386
3 changed files with 192 additions and 455 deletions

268
Cargo.lock generated
View file

@ -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"

View file

@ -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 <kamadorueda@gmail.com>"]

View file

@ -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<usize>,
/// physical CPUs.
#[clap(long, short, value_parser = clap::value_parser!(u8).range(1..))]
threads: Option<u8>,
/// 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 = "<anonymous file on stdin>".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<String>,
in_place: bool,
quiet: bool,
threads: usize,
) -> Vec<FormattedPath> {
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<RemoteHandle<FormattedPath>> = 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<String>,
in_place: bool,
) -> std::io::Result<Vec<FormattedPath>> {
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::<Vec<tui::text::Spans>>(),
)
.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::<Vec<&str>>();
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() {}