mirror of
https://github.com/RGBCube/alejandra
synced 2025-07-30 12:07:46 +00:00
Use clap-derive
This commit is contained in:
parent
c685879cda
commit
529821fb40
4 changed files with 163 additions and 112 deletions
86
Cargo.lock
generated
86
Cargo.lock
generated
|
@ -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"
|
||||
|
|
|
@ -5,7 +5,7 @@ path = "src/main.rs"
|
|||
[dependencies]
|
||||
alejandra = { path = "../alejandra" }
|
||||
atty = "*"
|
||||
clap = "*"
|
||||
clap = { version = "3", features = ["derive"] }
|
||||
indoc = "*"
|
||||
rayon = "*"
|
||||
termion = "*"
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue