mirror of
https://github.com/astral-sh/ruff.git
synced 2025-09-29 05:14:52 +00:00
convert errors to diagnostics too
This commit is contained in:
parent
a5ec195c53
commit
4ea16b7dd6
2 changed files with 99 additions and 7 deletions
|
@ -194,18 +194,23 @@ pub(crate) fn format(
|
|||
caches.persist()?;
|
||||
|
||||
// Report on any errors.
|
||||
//
|
||||
// We only convert errors to `Diagnostic`s in `Check` mode with preview enabled, otherwise we
|
||||
// fall back on printing simple messages.
|
||||
if !(preview.is_enabled() && mode.is_check()) {
|
||||
errors.sort_unstable_by(|a, b| a.path().cmp(&b.path()));
|
||||
|
||||
for error in &errors {
|
||||
error!("{error}");
|
||||
}
|
||||
}
|
||||
|
||||
let results = FormatResults::new(results.as_slice(), mode);
|
||||
match mode {
|
||||
FormatMode::Write => {}
|
||||
FormatMode::Check => {
|
||||
if preview.is_enabled() {
|
||||
results.write_changed_preview(&mut stdout().lock(), output_format)?;
|
||||
results.write_changed_preview(&mut stdout().lock(), output_format, &errors)?;
|
||||
} else {
|
||||
results.write_changed(&mut stdout().lock())?;
|
||||
}
|
||||
|
@ -605,14 +610,22 @@ impl<'a> FormatResults<'a> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
/// Write a list of the files that would be changed to the given writer.
|
||||
/// Write a list of the files that would be changed and any errors to the given writer.
|
||||
///
|
||||
/// Errors are reported first in the order they are provided, followed by the remaining
|
||||
/// diagnostics sorted by file name.
|
||||
fn write_changed_preview(
|
||||
&self,
|
||||
f: &mut impl Write,
|
||||
output_format: OutputFormat,
|
||||
errors: &[FormatCommandError],
|
||||
) -> io::Result<()> {
|
||||
let mut notebook_index = FxHashMap::default();
|
||||
let diagnostics: Vec<_> = self.to_diagnostics(&mut notebook_index).collect();
|
||||
let diagnostics: Vec<_> = errors
|
||||
.iter()
|
||||
.map(Diagnostic::from)
|
||||
.chain(self.to_diagnostics(&mut notebook_index))
|
||||
.collect();
|
||||
|
||||
let context = EmitterContext::new(¬ebook_index);
|
||||
let config = DisplayDiagnosticConfig::default();
|
||||
|
@ -852,6 +865,73 @@ impl FormatCommandError {
|
|||
}
|
||||
}
|
||||
|
||||
impl From<&FormatCommandError> for Diagnostic {
|
||||
fn from(error: &FormatCommandError) -> Self {
|
||||
let annotation = error.path().map(|path| {
|
||||
let file = SourceFileBuilder::new(path.to_string_lossy(), "").finish();
|
||||
let span = Span::from(file);
|
||||
Annotation::primary(span)
|
||||
});
|
||||
|
||||
let mut diagnostic = match error {
|
||||
// TODO(brent) also not sure about this one. Most of the ignore::Error variants
|
||||
// do fit pretty well under Io errors, but we could match and be even more
|
||||
// specific if we wanted. We already have a `DiagnosticId::InvalidGlob`, which
|
||||
// could map to Error::Glob, for example.
|
||||
FormatCommandError::Ignore(error) => {
|
||||
Diagnostic::new(DiagnosticId::Io, Severity::Error, error)
|
||||
}
|
||||
// TODO(brent) not sure if this is correct, DisplayParseError includes some
|
||||
// color and other formatting. I think we'd rather have access to the `path` and
|
||||
// underlying ParseError directly, like in other variants here.
|
||||
FormatCommandError::Parse(display_parse_error) => Diagnostic::new(
|
||||
DiagnosticId::InvalidSyntax,
|
||||
Severity::Error,
|
||||
display_parse_error,
|
||||
),
|
||||
FormatCommandError::Panic(_, panic_error) => {
|
||||
Diagnostic::new(DiagnosticId::Panic, Severity::Fatal, panic_error)
|
||||
}
|
||||
|
||||
// I/O errors
|
||||
FormatCommandError::Read(_, source_error)
|
||||
| FormatCommandError::Write(_, source_error) => {
|
||||
Diagnostic::new(DiagnosticId::Io, Severity::Error, source_error)
|
||||
}
|
||||
FormatCommandError::Diff(_, error) => {
|
||||
Diagnostic::new(DiagnosticId::Io, Severity::Error, error)
|
||||
}
|
||||
|
||||
FormatCommandError::Format(_, format_module_error) => match format_module_error {
|
||||
FormatModuleError::ParseError(parse_error) => Diagnostic::new(
|
||||
DiagnosticId::InvalidSyntax,
|
||||
Severity::Error,
|
||||
&parse_error.error,
|
||||
),
|
||||
FormatModuleError::FormatError(format_error) => {
|
||||
Diagnostic::new(DiagnosticId::FormatError, Severity::Error, format_error)
|
||||
}
|
||||
// TODO(brent) this might need a new DiagnosticId, or we could reuse
|
||||
// `FormatError`, which also has an InvalidDocument variant, like PrintError
|
||||
FormatModuleError::PrintError(print_error) => {
|
||||
Diagnostic::new(DiagnosticId::InvalidSyntax, Severity::Error, print_error)
|
||||
}
|
||||
},
|
||||
FormatCommandError::RangeFormatNotebook(_) => Diagnostic::new(
|
||||
DiagnosticId::RangeFormatNotebook,
|
||||
Severity::Error,
|
||||
"Range formatting isn't supported for notebooks.",
|
||||
),
|
||||
};
|
||||
|
||||
if let Some(annotation) = annotation {
|
||||
diagnostic.annotate(annotation);
|
||||
}
|
||||
|
||||
diagnostic
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for FormatCommandError {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
|
|
|
@ -443,7 +443,9 @@ impl Diagnostic {
|
|||
| DiagnosticId::UnnecessaryOverridesSection
|
||||
| DiagnosticId::UselessOverridesSection
|
||||
| DiagnosticId::DeprecatedSetting
|
||||
| DiagnosticId::Unformatted => None,
|
||||
| DiagnosticId::Unformatted
|
||||
| DiagnosticId::RangeFormatNotebook
|
||||
| DiagnosticId::FormatError => None,
|
||||
DiagnosticId::Lint(lint_name) => {
|
||||
Some(format!("{}/rules/{lint_name}", env!("CARGO_PKG_HOMEPAGE")))
|
||||
}
|
||||
|
@ -1026,6 +1028,14 @@ pub enum DiagnosticId {
|
|||
|
||||
/// The code needs to be formatted.
|
||||
Unformatted,
|
||||
|
||||
/// Range formatting isn't supported for notebooks.
|
||||
RangeFormatNotebook,
|
||||
|
||||
/// Something went wrong while formatting.
|
||||
///
|
||||
/// This often indicates a bug in the formatter.
|
||||
FormatError,
|
||||
}
|
||||
|
||||
impl DiagnosticId {
|
||||
|
@ -1066,6 +1076,8 @@ impl DiagnosticId {
|
|||
DiagnosticId::UselessOverridesSection => "useless-overrides-section",
|
||||
DiagnosticId::DeprecatedSetting => "deprecated-setting",
|
||||
DiagnosticId::Unformatted => "unformatted",
|
||||
DiagnosticId::RangeFormatNotebook => "range-format-notebook",
|
||||
DiagnosticId::FormatError => "format-error",
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue