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

Use clap-derive

This commit is contained in:
Jamie Quigley 2022-07-05 23:21:29 +01:00 committed by Kevin Amado
parent c685879cda
commit 529821fb40
4 changed files with 163 additions and 112 deletions

86
Cargo.lock generated
View file

@ -83,13 +83,28 @@ checksum = "9f1fe12880bae935d142c8702d500c63a4e8634b6c3c57ad72bf978fc7b6249a"
dependencies = [
"atty",
"bitflags",
"clap_derive",
"clap_lex",
"indexmap",
"once_cell",
"strsim",
"termcolor",
"textwrap",
]
[[package]]
name = "clap_derive"
version = "3.2.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ed6db9e867166a43a53f7199b5e4d1f522a1e5bd626654be263c999ce59df39a"
dependencies = [
"heck",
"proc-macro-error",
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "clap_lex"
version = "0.2.3"
@ -168,6 +183,12 @@ version = "0.12.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "db0d4cf898abf0081f964436dc980e96670a0f36863e4b83aaacdb65c9d7ccc3"
[[package]]
name = "heck"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2540771e65fc8cb83cd6e8a237f70c319bd5c29f78ed1084ba5d50eeac86f7f9"
[[package]]
name = "hermit-abi"
version = "0.1.19"
@ -263,6 +284,48 @@ version = "6.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "21326818e99cfe6ce1e524c2a805c189a99b5ae555a35d19f9a284b427d86afa"
[[package]]
name = "proc-macro-error"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c"
dependencies = [
"proc-macro-error-attr",
"proc-macro2",
"quote",
"syn",
"version_check",
]
[[package]]
name = "proc-macro-error-attr"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869"
dependencies = [
"proc-macro2",
"quote",
"version_check",
]
[[package]]
name = "proc-macro2"
version = "1.0.40"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dd96a1e8ed2596c337f8eae5f24924ec83f5ad5ab21ea8e455d3566c69fbcaf7"
dependencies = [
"unicode-ident",
]
[[package]]
name = "quote"
version = "1.0.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3bcdf212e9776fbcb2d23ab029360416bb1706b1aea2d1a5ba002727cbcab804"
dependencies = [
"proc-macro2",
]
[[package]]
name = "rayon"
version = "1.5.3"
@ -371,6 +434,17 @@ version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
[[package]]
name = "syn"
version = "1.0.98"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c50aef8a904de4c23c788f104b7dddc7d6f79c647c7c8ce4cc8f73eb0ca773dd"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "termcolor"
version = "1.1.3"
@ -417,6 +491,12 @@ dependencies = [
"unicode-width",
]
[[package]]
name = "unicode-ident"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5bd2fe26506023ed7b5e1e315add59d6f584c621d037f9368fea9cfb988f368c"
[[package]]
name = "unicode-segmentation"
version = "1.9.0"
@ -429,6 +509,12 @@ version = "0.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3ed742d4ea2bd1176e236172c8429aaf54486e7ac098db29ffe6529e0ce50973"
[[package]]
name = "version_check"
version = "0.9.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
[[package]]
name = "walkdir"
version = "2.3.2"

View file

@ -5,7 +5,7 @@ path = "src/main.rs"
[dependencies]
alejandra = { path = "../alejandra" }
atty = "*"
clap = "*"
clap = { version = "3", features = ["derive"] }
indoc = "*"
rayon = "*"
termion = "*"

View file

@ -1,68 +1,45 @@
use clap::Parser;
#[derive(Clone)]
pub(crate) struct FormattedPath {
pub path: String,
pub status: alejandra::format::Status,
}
pub(crate) fn parse(args: Vec<String>) -> clap::ArgMatches {
clap::Command::new("Alejandra")
.about("The Uncompromising Nix Code Formatter.")
.version(alejandra::version::VERSION)
.arg(
clap::Arg::new("include")
.help("Files or directories, or none to format stdin.")
.multiple_values(true),
)
.arg(
clap::Arg::new("exclude")
.short('e')
.help("Files or directories to exclude from formatting.")
.long("exclude")
.multiple_occurrences(true)
.takes_value(true),
)
.arg(
clap::Arg::new("check")
.help(
"Check if the input is already formatted and disable \
writing in-place the modified content.",
)
.long("--check")
.short('c'),
)
.arg(
clap::Arg::new("threads")
.default_value("0")
.help(
"Number of formatting threads to spawn. Defaults to the \
number of logical CPUs.",
)
.long("--threads")
.short('t')
.takes_value(true),
)
.arg(
clap::Arg::new("quiet")
.help("Hide the details, only show error messages.")
.long("--quiet")
.short('q'),
)
.term_width(80)
.after_help(
#[cfg_attr(rustfmt, rustfmt_skip)]
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.
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
"
),
)
.get_matches_from(args)
Your star and feedback is very much appreciated!
https://github.com/kamadorueda/alejandra
"
};
/// The Uncompromising Nix Code Formatter
#[derive(Debug, Parser)]
#[clap(version, after_help = AFTER_HELP, term_width = 80)]
struct Args {
/// Files or directories, or none to format stdin
#[clap(multiple_values = true)]
include: Vec<String>,
/// Files or directories to exclude from formatting
#[clap(long, short, multiple_occurrences = true)]
exclude: Vec<String>,
/// Check if the input is already formatted and disable writing in-place the modified content
#[clap(long, short)]
check: bool,
/// Number of formatting threads to spawn. Defaults to the number of logical CPUs.
#[clap(long, short)]
threads: Option<usize>,
/// Hide the details, only show error messages.
#[clap(long, short)]
quiet: bool,
}
pub(crate) fn stdin(quiet: bool) -> FormattedPath {
@ -99,8 +76,7 @@ pub(crate) fn simple(
paths
.par_iter()
.map(|path| {
let status =
alejandra::format::in_fs(path.clone(), in_place);
let status = alejandra::format::in_fs(path.clone(), in_place);
if let alejandra::format::Status::Changed(changed) = status {
if changed && !quiet {
@ -171,8 +147,7 @@ pub(crate) fn tui(
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);
let status = alejandra::format::in_fs(path.clone(), in_place);
if let Err(error) = sender
.send(Event::FormattedPath(FormattedPath { path, status }))
@ -197,9 +172,7 @@ pub(crate) fn tui(
match event {
Event::FormattedPath(formatted_path) => {
match &formatted_path.status {
alejandra::format::Status::Changed(
changed,
) => {
alejandra::format::Status::Changed(changed) => {
if *changed {
paths_changed += 1;
} else {
@ -304,21 +277,21 @@ pub(crate) fn tui(
.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 "
alejandra::format::Status::Changed(changed) => {
tui::text::Span::styled(
if changed {
if in_place {
"CHANGED "
} else {
"WOULD BE CHANGED "
}
} else {
"WOULD BE CHANGED "
}
} else {
"OK "
},
tui::style::Style::default()
.fg(tui::style::Color::Green),
),
"OK "
},
tui::style::Style::default()
.fg(tui::style::Color::Green),
)
}
alejandra::format::Status::Error(_) => {
tui::text::Span::styled(
"ERROR ",
@ -349,48 +322,39 @@ pub(crate) fn tui(
}
pub fn main() -> std::io::Result<()> {
let matches = crate::cli::parse(std::env::args().collect());
let args = Args::parse();
let in_place = !matches.is_present("check");
let threads = matches.value_of("threads").unwrap();
let threads: usize = threads.parse().unwrap();
let quiet = matches.is_present("quiet");
let in_place = !args.check;
let threads = args.threads.unwrap_or(0);
rayon::ThreadPoolBuilder::new()
.num_threads(threads)
.build_global()
.unwrap();
let formatted_paths = match matches.values_of("include") {
Some(include) => {
let include = include.collect();
let exclude = match matches.values_of("exclude") {
Some(exclude) => exclude.collect(),
None => vec![],
};
let formatted_paths = match &args.include[..] {
&[] => {
vec![crate::cli::stdin(args.quiet)]
}
include => {
let paths = crate::find::nix_files(include, &args.exclude);
let paths: Vec<String> = crate::find::nix_files(include, exclude);
if !quiet
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, quiet)
crate::cli::simple(paths, in_place, args.quiet)
}
}
None => vec![crate::cli::stdin(quiet)],
};
let errors = formatted_paths
.iter()
.filter(|formatted_path| {
matches!(
formatted_path.status,
alejandra::format::Status::Error(_)
)
matches!(formatted_path.status, alejandra::format::Status::Error(_))
})
.count();
@ -420,7 +384,7 @@ pub fn main() -> std::io::Result<()> {
.count();
if changed > 0 {
if !quiet {
if !args.quiet {
eprintln!();
eprintln!(
"Success! {} file{} {}",
@ -437,7 +401,7 @@ pub fn main() -> std::io::Result<()> {
std::process::exit(if in_place { 0 } else { 2 });
}
if !quiet {
if !args.quiet {
eprintln!();
eprintln!("Success! Your code complies the Alejandra style");
}

View file

@ -1,17 +1,18 @@
pub(crate) fn nix_files(include: Vec<&str>, exclude: Vec<&str>) -> Vec<String> {
let include: std::collections::HashSet<String> =
include.iter().flat_map(nix_files_in_path).collect();
let exclude: std::collections::HashSet<String> =
exclude.iter().flat_map(nix_files_in_path).collect();
use std::collections::HashSet;
let mut paths: Vec<String> =
include.difference(&exclude).cloned().collect();
pub(crate) fn nix_files(include: &[String], exclude: &[String]) -> Vec<String> {
let include: HashSet<_> =
include.iter().flat_map(|s| nix_files_in_path(s)).collect();
let exclude: HashSet<_> =
exclude.iter().flat_map(|s| nix_files_in_path(s)).collect();
paths.sort();
let mut paths: Vec<_> = include.difference(&exclude).cloned().collect();
paths.sort_unstable();
paths
}
fn nix_files_in_path(path: &&str) -> std::collections::HashSet<String> {
fn nix_files_in_path(path: &str) -> HashSet<String> {
walkdir::WalkDir::new(path)
.into_iter()
.filter_entry(is_nix_file_or_dir)