Skip to content

feat: more levels of --quiet #341

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Aug 9, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@

- [Visual Studio Code](https://marketplace.visualstudio.com/items?itemName=kamadorueda.alejandra)
- [Neovim](./integrations/neovim/README.md)
- [Vim](./integrations/vim/README.md)
- [GNU Emacs](./integrations/gnu-emacs/README.md)
- [Doom Emacs](./integrations/doom-emacs/README.md)
- [Pre-commit](./integrations/pre-commit/README.md)
Expand Down
4 changes: 3 additions & 1 deletion integrations/neovim/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@

In order to use Alejandra with
[Neovim](https://neovim.io/)
please use any of the following plugins:
please use the `:%!alejandra -qq` command
to format the current buffer,
or use any of the following plugins:

- [Neoformat](https://github.com/sbdchd/neoformat)
- [null-ls.nvim](https://github.com/jose-elias-alvarez/null-ls.nvim)
6 changes: 6 additions & 0 deletions integrations/vim/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# Vim integration

In order to use Alejandra with
[Vim](https://www.vim.org/)
please use the `:%!alejandra -qq` command
to format the current buffer.
106 changes: 59 additions & 47 deletions src/alejandra_cli/src/cli.rs
Original file line number Diff line number Diff line change
@@ -1,35 +1,30 @@
use std::io::Read;

use clap::value_parser;
use clap::ArgAction;
use clap::Parser;
use futures::future::RemoteHandle;
use futures::stream::FuturesUnordered;
use futures::task::SpawnExt;

use crate::ads::random_ad;

#[derive(Clone)]
pub(crate) struct FormattedPath {
pub path: String,
pub status: alejandra::format::Status,
}

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.",
);
use crate::verbosity::Verbosity;

/// The Uncompromising Nix Code Formatter.
#[derive(Debug, Parser)]
#[clap(
name="Alejandra",

after_help = AFTER_HELP,
after_help = 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.",
),
term_width = 80,
version,
)]
struct Args {
struct CLIArgs {
/// Files or directories, or a single "-" (or leave empty) to format stdin.
#[clap(multiple_values = true)]
include: Vec<String>,
Expand All @@ -45,25 +40,34 @@ struct Args {

/// Number of formatting threads to spawn. Defaults to the number of
/// physical CPUs.
#[clap(long, short, value_parser = clap::value_parser!(u8).range(1..))]
#[clap(long, short, value_parser = value_parser!(u8).range(1..))]
threads: Option<u8>,

/// Hide the details, only show error messages.
#[clap(long, short)]
quiet: bool,
/// Use once to hide informational messages,
/// twice to hide error messages.
#[clap(long, short, action = ArgAction::Count)]
quiet: u8,
}

#[derive(Clone)]
struct FormattedPath {
pub path: String,
pub status: alejandra::format::Status,
}

pub(crate) fn stdin(quiet: bool) -> FormattedPath {
fn format_stdin(verbosity: Verbosity) -> FormattedPath {
let mut before = String::new();
let path = "<anonymous file on stdin>".to_string();

if !quiet {
if verbosity.allows_info() {
eprintln!("Formatting stdin.");
eprintln!("Use --help to see all command line options.");
eprintln!("use --quiet to suppress this and all messages.");
eprintln!("use --quiet to suppress this and other messages.");
}

std::io::stdin().read_to_string(&mut before).unwrap();
std::io::stdin()
.read_to_string(&mut before)
.expect("Unable to read stdin.");

let (status, data) =
alejandra::format::in_memory(path.clone(), before.clone());
Expand All @@ -73,15 +77,15 @@ pub(crate) fn stdin(quiet: bool) -> FormattedPath {
FormattedPath { path, status }
}

pub(crate) fn simple(
fn format_paths(
paths: Vec<String>,
in_place: bool,
quiet: bool,
verbosity: Verbosity,
threads: usize,
) -> Vec<FormattedPath> {
let paths_len = paths.len();

if !quiet {
if verbosity.allows_info() {
eprintln!(
"{} {paths_len} file{} using {threads} thread{}.",
"Checking style in",
Expand All @@ -94,7 +98,7 @@ pub(crate) fn simple(
let pool = futures::executor::ThreadPoolBuilder::new()
.pool_size(threads)
.create()
.expect("Unable to instantiate a new thread pool");
.expect("Unable to instantiate a new thread pool.");

let futures: FuturesUnordered<RemoteHandle<FormattedPath>> = paths
.into_iter()
Expand All @@ -103,7 +107,7 @@ pub(crate) fn simple(
let status = alejandra::format::in_fs(path.clone(), in_place);

if let alejandra::format::Status::Changed(changed) = status {
if changed && !quiet {
if changed && verbosity.allows_info() {
println!(
"{}: {path}",
if in_place {
Expand All @@ -117,33 +121,38 @@ pub(crate) fn simple(

FormattedPath { path: path.clone(), status }
})
.expect("Unable to spawn formatting task")
.expect("Unable to spawn formatting task.")
})
.collect();

futures::executor::block_on_stream(futures).collect()
}

pub fn main() -> std::io::Result<()> {
let args = Args::parse();
let args = CLIArgs::parse();

let in_place = !args.check;

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 threads =
args.threads.map_or_else(num_cpus::get_physical, Into::<usize>::into);

let verbosity = match args.quiet {
0 => Verbosity::Everything,
1 => Verbosity::NoInfo,
_ => Verbosity::NoErrors,
};

let formatted_paths = match &include[..] {
&[] | &["-"] => {
vec![crate::cli::stdin(args.quiet)]
vec![crate::cli::format_stdin(verbosity)]
},
include => {
let paths = crate::find::nix_files(include, &args.exclude);

crate::cli::simple(paths, in_place, args.quiet, threads)
crate::cli::format_paths(paths, in_place, verbosity, threads)
},
};

Expand All @@ -155,18 +164,21 @@ pub fn main() -> std::io::Result<()> {
.count();

if errors > 0 {
eprintln!();
eprintln!(
"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!("- {}: {error}", formatted_path.path);
if verbosity.allows_errors() {
eprintln!();
eprintln!(
"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!("- {}: {error}", formatted_path.path);
}
}
}

std::process::exit(1);
}

Expand All @@ -181,7 +193,7 @@ pub fn main() -> std::io::Result<()> {
.count();

if changed > 0 {
if !args.quiet {
if verbosity.allows_info() {
eprintln!();
eprintln!(
"{}! {changed} file{} {}.",
Expand All @@ -204,7 +216,7 @@ pub fn main() -> std::io::Result<()> {
std::process::exit(if in_place { 0 } else { 2 });
}

if !args.quiet {
if verbosity.allows_info() {
eprintln!();
eprintln!("Congratulations! Your code complies the Alejandra style.");
eprintln!();
Expand Down
5 changes: 3 additions & 2 deletions src/alejandra_cli/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
pub mod ads;
mod ads;
pub mod cli;
pub mod find;
mod find;
mod verbosity;
16 changes: 16 additions & 0 deletions src/alejandra_cli/src/verbosity.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#[derive(Clone, Copy)]
pub(crate) enum Verbosity {
Everything,
NoInfo,
NoErrors,
}

impl Verbosity {
pub(crate) fn allows_info(&self) -> bool {
matches!(self, Verbosity::Everything)
}

pub(crate) fn allows_errors(&self) -> bool {
self.allows_info() || matches!(self, Verbosity::NoInfo)
}
}