mirror of
https://github.com/astral-sh/ruff
synced 2026-01-24 15:01:00 -05:00
Fix: Structured output Issue Fix (#186)
This commit is contained in:
@@ -10,6 +10,7 @@ pub mod fs;
|
||||
pub mod linter;
|
||||
pub mod logging;
|
||||
pub mod message;
|
||||
pub mod printer;
|
||||
mod pyproject;
|
||||
mod python;
|
||||
pub mod settings;
|
||||
|
||||
71
src/main.rs
71
src/main.rs
@@ -18,6 +18,7 @@ use ::ruff::fs::iter_python_files;
|
||||
use ::ruff::linter::lint_path;
|
||||
use ::ruff::logging::set_up_logging;
|
||||
use ::ruff::message::Message;
|
||||
use ::ruff::printer::{Printer, SerializationFormat};
|
||||
use ::ruff::settings::Settings;
|
||||
use ::ruff::tell_user;
|
||||
|
||||
@@ -60,6 +61,9 @@ struct Cli {
|
||||
/// Like --exclude, but adds additional files and directories on top of the excluded ones.
|
||||
#[clap(long, multiple = true)]
|
||||
extend_exclude: Vec<Pattern>,
|
||||
/// Output formatting of linting messages
|
||||
#[clap(long, arg_enum, default_value_t=SerializationFormat::Text)]
|
||||
format: SerializationFormat,
|
||||
}
|
||||
|
||||
#[cfg(feature = "update-informer")]
|
||||
@@ -142,60 +146,15 @@ fn run_once(
|
||||
Ok(messages)
|
||||
}
|
||||
|
||||
fn report_once(messages: &[Message]) -> Result<()> {
|
||||
let (fixed, outstanding): (Vec<&Message>, Vec<&Message>) =
|
||||
messages.iter().partition(|message| message.fixed);
|
||||
let num_fixable = outstanding
|
||||
.iter()
|
||||
.filter(|message| message.kind.fixable())
|
||||
.count();
|
||||
|
||||
if !outstanding.is_empty() {
|
||||
for message in &outstanding {
|
||||
println!("{}", message);
|
||||
}
|
||||
println!();
|
||||
}
|
||||
|
||||
if !fixed.is_empty() {
|
||||
println!(
|
||||
"Found {} error(s) ({} fixed).",
|
||||
outstanding.len(),
|
||||
fixed.len()
|
||||
);
|
||||
} else {
|
||||
println!("Found {} error(s).", outstanding.len());
|
||||
}
|
||||
|
||||
if num_fixable > 0 {
|
||||
println!("{num_fixable} potentially fixable with the --fix option.");
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn report_continuously(messages: &[Message]) -> Result<()> {
|
||||
tell_user!(
|
||||
"Found {} error(s). Watching for file changes.",
|
||||
messages.len(),
|
||||
);
|
||||
|
||||
if !messages.is_empty() {
|
||||
println!();
|
||||
for message in messages {
|
||||
println!("{}", message);
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn inner_main() -> Result<ExitCode> {
|
||||
let cli = Cli::parse();
|
||||
|
||||
set_up_logging(cli.verbose)?;
|
||||
|
||||
let mut settings = Settings::from_paths(&cli.files);
|
||||
|
||||
let mut printer = Printer::new(cli.format);
|
||||
|
||||
if !cli.select.is_empty() {
|
||||
settings.select(cli.select);
|
||||
}
|
||||
@@ -211,16 +170,20 @@ fn inner_main() -> Result<ExitCode> {
|
||||
|
||||
if cli.watch {
|
||||
if cli.fix {
|
||||
println!("Warning: --fix is not enabled in watch mode.")
|
||||
println!("Warning: --fix is not enabled in watch mode.");
|
||||
}
|
||||
|
||||
if cli.format != SerializationFormat::Text {
|
||||
println!("Warning: --format 'text' is used in watch mode.");
|
||||
}
|
||||
|
||||
// Perform an initial run instantly.
|
||||
clearscreen::clear()?;
|
||||
printer.clear_screen()?;
|
||||
tell_user!("Starting linter in watch mode...\n");
|
||||
|
||||
let messages = run_once(&cli.files, &settings, !cli.no_cache, false)?;
|
||||
if !cli.quiet {
|
||||
report_continuously(&messages)?;
|
||||
printer.write_continuously(&messages)?;
|
||||
}
|
||||
|
||||
// Configure the file watcher.
|
||||
@@ -235,12 +198,12 @@ fn inner_main() -> Result<ExitCode> {
|
||||
Ok(e) => {
|
||||
if let Some(path) = e.path {
|
||||
if path.to_string_lossy().ends_with(".py") {
|
||||
clearscreen::clear()?;
|
||||
printer.clear_screen()?;
|
||||
tell_user!("File change detected...\n");
|
||||
|
||||
let messages = run_once(&cli.files, &settings, !cli.no_cache, false)?;
|
||||
if !cli.quiet {
|
||||
report_continuously(&messages)?;
|
||||
printer.write_continuously(&messages)?;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -251,7 +214,7 @@ fn inner_main() -> Result<ExitCode> {
|
||||
} else {
|
||||
let messages = run_once(&cli.files, &settings, !cli.no_cache, cli.fix)?;
|
||||
if !cli.quiet {
|
||||
report_once(&messages)?;
|
||||
printer.write_once(&messages)?;
|
||||
}
|
||||
|
||||
#[cfg(feature = "update-informer")]
|
||||
|
||||
80
src/printer.rs
Normal file
80
src/printer.rs
Normal file
@@ -0,0 +1,80 @@
|
||||
use colored::Colorize;
|
||||
|
||||
use anyhow::Result;
|
||||
use clap::ValueEnum;
|
||||
|
||||
use crate::message::Message;
|
||||
use crate::tell_user;
|
||||
|
||||
#[derive(Clone, Copy, ValueEnum, PartialEq, Eq, Debug)]
|
||||
pub enum SerializationFormat {
|
||||
Text,
|
||||
Json,
|
||||
}
|
||||
|
||||
pub struct Printer {
|
||||
format: SerializationFormat,
|
||||
}
|
||||
|
||||
impl Printer {
|
||||
pub fn new(format: SerializationFormat) -> Self {
|
||||
Self { format }
|
||||
}
|
||||
|
||||
pub fn write_once(&mut self, messages: &[Message]) -> Result<()> {
|
||||
let (fixed, outstanding): (Vec<&Message>, Vec<&Message>) =
|
||||
messages.iter().partition(|message| message.fixed);
|
||||
let num_fixable = outstanding
|
||||
.iter()
|
||||
.filter(|message| message.kind.fixable())
|
||||
.count();
|
||||
|
||||
match self.format {
|
||||
SerializationFormat::Json => {
|
||||
println!("{}", serde_json::to_string_pretty(&messages)?)
|
||||
}
|
||||
SerializationFormat::Text => {
|
||||
if !fixed.is_empty() {
|
||||
println!(
|
||||
"Found {} error(s) ({} fixed).",
|
||||
outstanding.len(),
|
||||
fixed.len()
|
||||
)
|
||||
} else {
|
||||
println!("Found {} error(s).", outstanding.len())
|
||||
}
|
||||
|
||||
for message in outstanding {
|
||||
println!("{}", message)
|
||||
}
|
||||
|
||||
if num_fixable > 0 {
|
||||
println!("{num_fixable} potentially fixable with the --fix option.")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn write_continuously(&mut self, messages: &[Message]) -> Result<()> {
|
||||
tell_user!(
|
||||
"Found {} error(s). Watching for file changes.",
|
||||
messages.len(),
|
||||
);
|
||||
|
||||
if !messages.is_empty() {
|
||||
println!();
|
||||
for message in messages {
|
||||
println!("{}", message)
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn clear_screen(&mut self) -> Result<()> {
|
||||
clearscreen::clear()?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user