mirror of
https://github.com/astral-sh/ruff.git
synced 2025-09-30 13:51:37 +00:00
Implement Display
on formatter structs (#6983)
Feedback from https://github.com/astral-sh/ruff/pull/6948#discussion_r1308260021.
This commit is contained in:
parent
fad23bbe60
commit
8d1610d960
2 changed files with 47 additions and 40 deletions
|
@ -333,7 +333,7 @@ pub struct FormatCommand {
|
||||||
/// files would have been modified, and zero otherwise.
|
/// files would have been modified, and zero otherwise.
|
||||||
#[arg(long)]
|
#[arg(long)]
|
||||||
pub check: bool,
|
pub check: bool,
|
||||||
/// Specify file to write the linter output to (default: stdout).
|
/// Specify file to write the formatter output to (default: stdout).
|
||||||
#[arg(short, long)]
|
#[arg(short, long)]
|
||||||
pub output_file: Option<PathBuf>,
|
pub output_file: Option<PathBuf>,
|
||||||
/// The minimum Python version that should be supported.
|
/// The minimum Python version that should be supported.
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
use std::fmt::{Display, Formatter};
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::io;
|
use std::io;
|
||||||
use std::io::{BufWriter, Write};
|
use std::io::{BufWriter, Write};
|
||||||
|
@ -81,13 +82,13 @@ pub(crate) fn format(
|
||||||
let duration = start.elapsed();
|
let duration = start.elapsed();
|
||||||
debug!("Formatted files in: {:?}", duration);
|
debug!("Formatted files in: {:?}", duration);
|
||||||
|
|
||||||
let summary = FormatResultSummary::from(results);
|
let summary = FormatResultSummary::new(results, mode);
|
||||||
|
|
||||||
// Report on any errors.
|
// Report on any errors.
|
||||||
if !errors.is_empty() {
|
if !errors.is_empty() {
|
||||||
warn!("Encountered {} errors while formatting:", errors.len());
|
warn!("Encountered {} errors while formatting:", errors.len());
|
||||||
for error in &errors {
|
for error in &errors {
|
||||||
error.show_user();
|
warn!("{error}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -101,7 +102,7 @@ pub(crate) fn format(
|
||||||
}
|
}
|
||||||
_ => Box::new(BufWriter::new(io::stdout())),
|
_ => Box::new(BufWriter::new(io::stdout())),
|
||||||
};
|
};
|
||||||
summary.show_user(&mut writer, mode)?;
|
writeln!(writer, "{summary}")?;
|
||||||
}
|
}
|
||||||
|
|
||||||
match mode {
|
match mode {
|
||||||
|
@ -162,8 +163,10 @@ enum FormatResult {
|
||||||
Skipped,
|
Skipped,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Default)]
|
#[derive(Debug)]
|
||||||
struct FormatResultSummary {
|
struct FormatResultSummary {
|
||||||
|
/// The format mode that was used.
|
||||||
|
mode: FormatMode,
|
||||||
/// The number of files that were formatted.
|
/// The number of files that were formatted.
|
||||||
formatted: usize,
|
formatted: usize,
|
||||||
/// The number of files that were unchanged.
|
/// The number of files that were unchanged.
|
||||||
|
@ -172,30 +175,34 @@ struct FormatResultSummary {
|
||||||
skipped: usize,
|
skipped: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<Vec<FormatResult>> for FormatResultSummary {
|
impl FormatResultSummary {
|
||||||
fn from(diagnostics: Vec<FormatResult>) -> Self {
|
fn new(diagnostics: Vec<FormatResult>, mode: FormatMode) -> Self {
|
||||||
let mut path_diagnostics = Self::default();
|
let mut summary = Self {
|
||||||
|
mode,
|
||||||
|
formatted: 0,
|
||||||
|
unchanged: 0,
|
||||||
|
skipped: 0,
|
||||||
|
};
|
||||||
for diagnostic in diagnostics {
|
for diagnostic in diagnostics {
|
||||||
match diagnostic {
|
match diagnostic {
|
||||||
FormatResult::Formatted => path_diagnostics.formatted += 1,
|
FormatResult::Formatted => summary.formatted += 1,
|
||||||
FormatResult::Unchanged => path_diagnostics.unchanged += 1,
|
FormatResult::Unchanged => summary.unchanged += 1,
|
||||||
FormatResult::Skipped => path_diagnostics.skipped += 1,
|
FormatResult::Skipped => summary.skipped += 1,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
path_diagnostics
|
summary
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FormatResultSummary {
|
impl Display for FormatResultSummary {
|
||||||
/// Pretty-print a [`FormatResultSummary`] for user-facing display.
|
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||||
fn show_user(&self, writer: &mut dyn Write, mode: FormatMode) -> Result<(), io::Error> {
|
|
||||||
if self.formatted > 0 && self.unchanged > 0 {
|
if self.formatted > 0 && self.unchanged > 0 {
|
||||||
writeln!(
|
write!(
|
||||||
writer,
|
f,
|
||||||
"{} file{} {}, {} file{} left unchanged",
|
"{} file{} {}, {} file{} left unchanged",
|
||||||
self.formatted,
|
self.formatted,
|
||||||
if self.formatted == 1 { "" } else { "s" },
|
if self.formatted == 1 { "" } else { "s" },
|
||||||
match mode {
|
match self.mode {
|
||||||
FormatMode::Write => "reformatted",
|
FormatMode::Write => "reformatted",
|
||||||
FormatMode::Check => "would be reformatted",
|
FormatMode::Check => "would be reformatted",
|
||||||
},
|
},
|
||||||
|
@ -203,19 +210,19 @@ impl FormatResultSummary {
|
||||||
if self.unchanged == 1 { "" } else { "s" },
|
if self.unchanged == 1 { "" } else { "s" },
|
||||||
)
|
)
|
||||||
} else if self.formatted > 0 {
|
} else if self.formatted > 0 {
|
||||||
writeln!(
|
write!(
|
||||||
writer,
|
f,
|
||||||
"{} file{} {}",
|
"{} file{} {}",
|
||||||
self.formatted,
|
self.formatted,
|
||||||
if self.formatted == 1 { "" } else { "s" },
|
if self.formatted == 1 { "" } else { "s" },
|
||||||
match mode {
|
match self.mode {
|
||||||
FormatMode::Write => "reformatted",
|
FormatMode::Write => "reformatted",
|
||||||
FormatMode::Check => "would be reformatted",
|
FormatMode::Check => "would be reformatted",
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
} else if self.unchanged > 0 {
|
} else if self.unchanged > 0 {
|
||||||
writeln!(
|
write!(
|
||||||
writer,
|
f,
|
||||||
"{} file{} left unchanged",
|
"{} file{} left unchanged",
|
||||||
self.unchanged,
|
self.unchanged,
|
||||||
if self.unchanged == 1 { "" } else { "s" },
|
if self.unchanged == 1 { "" } else { "s" },
|
||||||
|
@ -229,62 +236,62 @@ impl FormatResultSummary {
|
||||||
/// An error that can occur while formatting a set of files.
|
/// An error that can occur while formatting a set of files.
|
||||||
#[derive(Error, Debug)]
|
#[derive(Error, Debug)]
|
||||||
enum FormatterIterationError {
|
enum FormatterIterationError {
|
||||||
#[error("Failed to traverse: {0}")]
|
|
||||||
Ignore(#[from] ignore::Error),
|
Ignore(#[from] ignore::Error),
|
||||||
#[error("Failed to read {0}: {1}")]
|
|
||||||
Read(PathBuf, io::Error),
|
Read(PathBuf, io::Error),
|
||||||
#[error("Failed to write {0}: {1}")]
|
|
||||||
Write(PathBuf, io::Error),
|
Write(PathBuf, io::Error),
|
||||||
#[error("Failed to format {0}: {1}")]
|
|
||||||
FormatModule(PathBuf, FormatModuleError),
|
FormatModule(PathBuf, FormatModuleError),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FormatterIterationError {
|
impl Display for FormatterIterationError {
|
||||||
/// Pretty-print a [`FormatterIterationError`] for user-facing display.
|
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||||
fn show_user(&self) {
|
|
||||||
match self {
|
match self {
|
||||||
Self::Ignore(err) => {
|
Self::Ignore(err) => {
|
||||||
if let ignore::Error::WithPath { path, .. } = err {
|
if let ignore::Error::WithPath { path, .. } = err {
|
||||||
warn!(
|
write!(
|
||||||
|
f,
|
||||||
"{}{}{} {}",
|
"{}{}{} {}",
|
||||||
"Failed to format ".bold(),
|
"Failed to format ".bold(),
|
||||||
fs::relativize_path(path).bold(),
|
fs::relativize_path(path).bold(),
|
||||||
":".bold(),
|
":".bold(),
|
||||||
err.io_error()
|
err.io_error()
|
||||||
.map_or_else(|| err.to_string(), std::string::ToString::to_string)
|
.map_or_else(|| err.to_string(), std::string::ToString::to_string)
|
||||||
);
|
)
|
||||||
} else {
|
} else {
|
||||||
warn!(
|
write!(
|
||||||
|
f,
|
||||||
"{} {}",
|
"{} {}",
|
||||||
"Encountered error:".bold(),
|
"Encountered error:".bold(),
|
||||||
err.io_error()
|
err.io_error()
|
||||||
.map_or_else(|| err.to_string(), std::string::ToString::to_string)
|
.map_or_else(|| err.to_string(), std::string::ToString::to_string)
|
||||||
);
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Self::Read(path, err) => {
|
Self::Read(path, err) => {
|
||||||
warn!(
|
write!(
|
||||||
|
f,
|
||||||
"{}{}{} {err}",
|
"{}{}{} {err}",
|
||||||
"Failed to read ".bold(),
|
"Failed to read ".bold(),
|
||||||
fs::relativize_path(path).bold(),
|
fs::relativize_path(path).bold(),
|
||||||
":".bold()
|
":".bold()
|
||||||
);
|
)
|
||||||
}
|
}
|
||||||
Self::Write(path, err) => {
|
Self::Write(path, err) => {
|
||||||
warn!(
|
write!(
|
||||||
|
f,
|
||||||
"{}{}{} {err}",
|
"{}{}{} {err}",
|
||||||
"Failed to write ".bold(),
|
"Failed to write ".bold(),
|
||||||
fs::relativize_path(path).bold(),
|
fs::relativize_path(path).bold(),
|
||||||
":".bold()
|
":".bold()
|
||||||
);
|
)
|
||||||
}
|
}
|
||||||
Self::FormatModule(path, err) => {
|
Self::FormatModule(path, err) => {
|
||||||
warn!(
|
write!(
|
||||||
|
f,
|
||||||
"{}{}{} {err}",
|
"{}{}{} {err}",
|
||||||
"Failed to format ".bold(),
|
"Failed to format ".bold(),
|
||||||
fs::relativize_path(path).bold(),
|
fs::relativize_path(path).bold(),
|
||||||
":".bold()
|
":".bold()
|
||||||
);
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue