Add print_stdout and print_stderr to Clippy enforcement (#2542)

This commit is contained in:
Charlie Marsh 2023-02-03 11:13:44 -05:00 committed by GitHub
parent d05ea4dbac
commit 924e35b1c3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
18 changed files with 145 additions and 74 deletions

View file

@ -9,9 +9,9 @@ rustflags = [
# `https://github.com/EmbarkStudios/rust-ecosystem/issues/22#issuecomment-947011395` # `https://github.com/EmbarkStudios/rust-ecosystem/issues/22#issuecomment-947011395`
"-Dunsafe_code", "-Dunsafe_code",
"-Wclippy::pedantic", "-Wclippy::pedantic",
# "-Wclippy::print_stdout", "-Wclippy::print_stdout",
# "-Wclippy::print_stderr", "-Wclippy::print_stderr",
# "-Wclippy::dbg_macro", "-Wclippy::dbg_macro",
"-Wclippy::char_lit_as_u8", "-Wclippy::char_lit_as_u8",
"-Aclippy::collapsible_else_if", "-Aclippy::collapsible_else_if",
"-Aclippy::collapsible_if", "-Aclippy::collapsible_if",

View file

@ -47,7 +47,11 @@ fn main() -> Result<()> {
// Create Ruff's pyproject.toml section. // Create Ruff's pyproject.toml section.
let pyproject = flake8_to_ruff::convert(&config, &external_config, args.plugin)?; let pyproject = flake8_to_ruff::convert(&config, &external_config, args.plugin)?;
println!("{}", toml::to_string_pretty(&pyproject)?);
#[allow(clippy::print_stdout)]
{
println!("{}", toml::to_string_pretty(&pyproject)?);
}
Ok(()) Ok(())
} }

View file

@ -1,5 +1,6 @@
use std::fs::remove_dir_all; use std::fs::remove_dir_all;
use std::io::{self, Read}; use std::io::Write;
use std::io::{self, BufWriter, Read};
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
use std::time::Instant; use std::time::Instant;
@ -11,6 +12,9 @@ use log::{debug, error};
use path_absolutize::path_dedot; use path_absolutize::path_dedot;
#[cfg(not(target_family = "wasm"))] #[cfg(not(target_family = "wasm"))]
use rayon::prelude::*; use rayon::prelude::*;
use serde::Serialize;
use walkdir::WalkDir;
use ruff::cache::CACHE_DIR_NAME; use ruff::cache::CACHE_DIR_NAME;
use ruff::linter::add_noqa_to_path; use ruff::linter::add_noqa_to_path;
use ruff::logging::LogLevel; use ruff::logging::LogLevel;
@ -19,8 +23,6 @@ use ruff::registry::{Linter, Rule, RuleNamespace};
use ruff::resolver::PyprojectDiscovery; use ruff::resolver::PyprojectDiscovery;
use ruff::settings::flags; use ruff::settings::flags;
use ruff::{fix, fs, packaging, resolver, warn_user_once, AutofixAvailability, IOError}; use ruff::{fix, fs, packaging, resolver, warn_user_once, AutofixAvailability, IOError};
use serde::Serialize;
use walkdir::WalkDir;
use crate::args::{HelpFormat, Overrides}; use crate::args::{HelpFormat, Overrides};
use crate::cache; use crate::cache;
@ -230,8 +232,10 @@ pub fn show_settings(
}; };
let path = entry.path(); let path = entry.path();
let settings = resolver.resolve(path, pyproject_strategy); let settings = resolver.resolve(path, pyproject_strategy);
println!("Resolved settings for: {path:?}");
println!("{settings:#?}"); let mut stdout = BufWriter::new(io::stdout().lock());
write!(stdout, "Resolved settings for: {path:?}")?;
write!(stdout, "{settings:#?}")?;
Ok(()) Ok(())
} }
@ -251,12 +255,13 @@ pub fn show_files(
} }
// Print the list of files. // Print the list of files.
let mut stdout = BufWriter::new(io::stdout().lock());
for entry in paths for entry in paths
.iter() .iter()
.flatten() .flatten()
.sorted_by(|a, b| a.path().cmp(b.path())) .sorted_by(|a, b| a.path().cmp(b.path()))
{ {
println!("{}", entry.path().to_string_lossy()); writeln!(stdout, "{}", entry.path().to_string_lossy())?;
} }
Ok(()) Ok(())
@ -272,34 +277,39 @@ struct Explanation<'a> {
/// Explain a `Rule` to the user. /// Explain a `Rule` to the user.
pub fn rule(rule: &Rule, format: HelpFormat) -> Result<()> { pub fn rule(rule: &Rule, format: HelpFormat) -> Result<()> {
let (linter, _) = Linter::parse_code(rule.code()).unwrap(); let (linter, _) = Linter::parse_code(rule.code()).unwrap();
let mut stdout = BufWriter::new(io::stdout().lock());
match format { match format {
HelpFormat::Text => { HelpFormat::Text => {
println!("{}\n", rule.as_ref()); writeln!(stdout, "{}\n", rule.as_ref())?;
println!("Code: {} ({})\n", rule.code(), linter.name()); writeln!(stdout, "Code: {} ({})\n", rule.code(), linter.name())?;
if let Some(autofix) = rule.autofixable() { if let Some(autofix) = rule.autofixable() {
println!( writeln!(
stdout,
"{}", "{}",
match autofix.available { match autofix.available {
AutofixAvailability::Sometimes => "Autofix is sometimes available.\n", AutofixAvailability::Sometimes => "Autofix is sometimes available.\n",
AutofixAvailability::Always => "Autofix is always available.\n", AutofixAvailability::Always => "Autofix is always available.\n",
} }
); )?;
} }
println!("Message formats:\n");
writeln!(stdout, "Message formats:\n")?;
for format in rule.message_formats() { for format in rule.message_formats() {
println!("* {format}"); writeln!(stdout, "* {format}")?;
} }
} }
HelpFormat::Json => { HelpFormat::Json => {
println!( writeln!(
stdout,
"{}", "{}",
serde_json::to_string_pretty(&Explanation { serde_json::to_string_pretty(&Explanation {
code: rule.code(), code: rule.code(),
linter: linter.name(), linter: linter.name(),
summary: rule.message_formats()[0], summary: rule.message_formats()[0],
})? })?
); )?;
} }
}; };
Ok(()) Ok(())
@ -307,6 +317,7 @@ pub fn rule(rule: &Rule, format: HelpFormat) -> Result<()> {
/// Clear any caches in the current directory or any subdirectories. /// Clear any caches in the current directory or any subdirectories.
pub fn clean(level: LogLevel) -> Result<()> { pub fn clean(level: LogLevel) -> Result<()> {
let mut stderr = BufWriter::new(io::stderr().lock());
for entry in WalkDir::new(&*path_dedot::CWD) for entry in WalkDir::new(&*path_dedot::CWD)
.into_iter() .into_iter()
.filter_map(Result::ok) .filter_map(Result::ok)
@ -315,7 +326,11 @@ pub fn clean(level: LogLevel) -> Result<()> {
let cache = entry.path().join(CACHE_DIR_NAME); let cache = entry.path().join(CACHE_DIR_NAME);
if cache.is_dir() { if cache.is_dir() {
if level >= LogLevel::Default { if level >= LogLevel::Default {
eprintln!("Removing cache at: {}", fs::relativize_path(&cache).bold()); writeln!(
stderr,
"Removing cache at: {}",
fs::relativize_path(&cache).bold()
)?;
} }
remove_dir_all(&cache)?; remove_dir_all(&cache)?;
} }

View file

@ -19,7 +19,11 @@ pub fn linter(format: HelpFormat) {
.join("/"), .join("/"),
prefix => prefix.to_string(), prefix => prefix.to_string(),
}; };
println!("{:>4} {}", prefix, linter.name());
#[allow(clippy::print_stdout)]
{
println!("{:>4} {}", prefix, linter.name());
}
} }
} }
@ -39,7 +43,10 @@ pub fn linter(format: HelpFormat) {
}) })
.collect(); .collect();
println!("{}", serde_json::to_string_pretty(&linters).unwrap()); #[allow(clippy::print_stdout)]
{
println!("{}", serde_json::to_string_pretty(&linters).unwrap());
}
} }
} }
} }

View file

@ -105,14 +105,17 @@ pub fn lint_path(
if let Some(err) = parse_error { if let Some(err) = parse_error {
// Notify the user of any parse errors. // Notify the user of any parse errors.
eprintln!( #[allow(clippy::print_stderr)]
"{}{} {}{}{} {err}", {
"error".red().bold(), eprintln!(
":".bold(), "{}{} {}{}{} {err}",
"Failed to parse ".bold(), "error".red().bold(),
fs::relativize_path(path).bold(), ":".bold(),
":".bold() "Failed to parse ".bold(),
); fs::relativize_path(path).bold(),
":".bold()
);
}
// Purge the cache. // Purge the cache.
cache::del(path, package.as_ref(), settings, autofix.into()); cache::del(path, package.as_ref(), settings, autofix.into());
@ -207,12 +210,15 @@ pub fn lint_stdin(
}; };
if let Some(err) = parse_error { if let Some(err) = parse_error {
eprintln!( #[allow(clippy::print_stderr)]
"{}{} Failed to parse {}: {err}", {
"error".red().bold(), eprintln!(
":".bold(), "{}{} Failed to parse {}: {err}",
path.map_or_else(|| "-".into(), fs::relativize_path).bold() "error".red().bold(),
); ":".bold(),
path.map_or_else(|| "-".into(), fs::relativize_path).bold()
);
}
} }
Ok(Diagnostics { messages, fixed }) Ok(Diagnostics { messages, fixed })

View file

@ -53,16 +53,19 @@ fn inner_main() -> Result<ExitCode> {
{ {
let default_panic_hook = std::panic::take_hook(); let default_panic_hook = std::panic::take_hook();
std::panic::set_hook(Box::new(move |info| { std::panic::set_hook(Box::new(move |info| {
eprintln!( #[allow(clippy::print_stderr)]
r#" {
eprintln!(
r#"
{}: `ruff` crashed. This indicates a bug in `ruff`. If you could open an issue at: {}: `ruff` crashed. This indicates a bug in `ruff`. If you could open an issue at:
https://github.com/charliermarsh/ruff/issues/new?title=%5BPanic%5D https://github.com/charliermarsh/ruff/issues/new?title=%5BPanic%5D
quoting the executed command, along with the relevant file contents and `pyproject.toml` settings, we'd be very appreciative! quoting the executed command, along with the relevant file contents and `pyproject.toml` settings, we'd be very appreciative!
"#, "#,
"error".red().bold(), "error".red().bold(),
); );
}
default_panic_hook(info); default_panic_hook(info);
})); }));
} }
@ -157,7 +160,10 @@ fn check(args: CheckArgs, log_level: LogLevel) -> Result<ExitCode> {
} }
let modifications = commands::add_noqa(&cli.files, &pyproject_strategy, &overrides)?; let modifications = commands::add_noqa(&cli.files, &pyproject_strategy, &overrides)?;
if modifications > 0 && log_level >= LogLevel::Default { if modifications > 0 && log_level >= LogLevel::Default {
eprintln!("Added {modifications} noqa directives."); #[allow(clippy::print_stderr)]
{
eprintln!("Added {modifications} noqa directives.");
}
} }
return Ok(ExitCode::SUCCESS); return Ok(ExitCode::SUCCESS);
} }
@ -287,7 +293,10 @@ pub fn main() -> ExitCode {
match inner_main() { match inner_main() {
Ok(code) => code, Ok(code) => code,
Err(err) => { Err(err) => {
eprintln!("{}{} {err:?}", "error".red().bold(), ":".bold()); #[allow(clippy::print_stderr)]
{
eprintln!("{}{} {err:?}", "error".red().bold(), ":".bold());
}
ExitCode::FAILURE ExitCode::FAILURE
} }
} }

View file

@ -68,7 +68,10 @@ pub fn check_for_updates() -> Result<()> {
pkg_name = CARGO_PKG_NAME.green() pkg_name = CARGO_PKG_NAME.green()
); );
println!("\n{msg}\n{cmd}"); #[allow(clippy::print_stdout)]
{
println!("\n{msg}\n{cmd}");
}
} }
Ok(()) Ok(())

View file

@ -1,4 +1,5 @@
//! Generate CLI help. //! Generate CLI help.
#![allow(clippy::print_stdout, clippy::print_stderr)]
use crate::utils::replace_readme_section; use crate::utils::replace_readme_section;
use anyhow::Result; use anyhow::Result;

View file

@ -1,3 +1,5 @@
#![allow(clippy::print_stdout, clippy::print_stderr)]
use std::fs; use std::fs;
use std::path::PathBuf; use std::path::PathBuf;

View file

@ -1,4 +1,5 @@
//! Generate a Markdown-compatible listing of configuration options. //! Generate a Markdown-compatible listing of configuration options.
#![allow(clippy::print_stdout, clippy::print_stderr)]
use anyhow::Result; use anyhow::Result;
use itertools::Itertools; use itertools::Itertools;

View file

@ -1,4 +1,5 @@
//! Generate a Markdown-compatible table of supported lint rules. //! Generate a Markdown-compatible table of supported lint rules.
#![allow(clippy::print_stdout, clippy::print_stderr)]
use anyhow::Result; use anyhow::Result;
use itertools::Itertools; use itertools::Itertools;

View file

@ -1,4 +1,5 @@
//! Print the AST for a given Python file. //! Print the AST for a given Python file.
#![allow(clippy::print_stdout, clippy::print_stderr)]
use std::fs; use std::fs;
use std::path::PathBuf; use std::path::PathBuf;

View file

@ -1,4 +1,5 @@
//! Print the `LibCST` CST for a given Python file. //! Print the `LibCST` CST for a given Python file.
#![allow(clippy::print_stdout, clippy::print_stderr)]
use std::fs; use std::fs;
use std::path::PathBuf; use std::path::PathBuf;

View file

@ -1,4 +1,5 @@
//! Print the token stream for a given Python file. //! Print the token stream for a given Python file.
#![allow(clippy::print_stdout, clippy::print_stderr)]
use std::fs; use std::fs;
use std::path::PathBuf; use std::path::PathBuf;

View file

@ -1,4 +1,5 @@
//! Run round-trip source code generation on a given Python file. //! Run round-trip source code generation on a given Python file.
#![allow(clippy::print_stdout, clippy::print_stderr)]
use std::fs; use std::fs;
use std::path::PathBuf; use std::path::PathBuf;

View file

@ -65,11 +65,17 @@ pub fn convert(
let plugins = plugins.unwrap_or_else(|| { let plugins = plugins.unwrap_or_else(|| {
let from_options = plugin::infer_plugins_from_options(flake8); let from_options = plugin::infer_plugins_from_options(flake8);
if !from_options.is_empty() { if !from_options.is_empty() {
eprintln!("Inferred plugins from settings: {from_options:#?}"); #[allow(clippy::print_stderr)]
{
eprintln!("Inferred plugins from settings: {from_options:#?}");
}
} }
let from_codes = plugin::infer_plugins_from_codes(&referenced_codes); let from_codes = plugin::infer_plugins_from_codes(&referenced_codes);
if !from_codes.is_empty() { if !from_codes.is_empty() {
eprintln!("Inferred plugins from referenced codes: {from_codes:#?}"); #[allow(clippy::print_stderr)]
{
eprintln!("Inferred plugins from referenced codes: {from_codes:#?}");
}
} }
from_options.into_iter().chain(from_codes).collect() from_options.into_iter().chain(from_codes).collect()
}); });

View file

@ -236,14 +236,17 @@ pub fn add_noqa_to_path(path: &Path, settings: &Settings) -> Result<usize> {
// Log any parse errors. // Log any parse errors.
if let Some(err) = error { if let Some(err) = error {
eprintln!( #[allow(clippy::print_stderr)]
"{}{} {}{}{} {err:?}", {
"error".red().bold(), eprintln!(
":".bold(), "{}{} {}{}{} {err:?}",
"Failed to parse ".bold(), "error".red().bold(),
fs::relativize_path(path).bold(), ":".bold(),
":".bold() "Failed to parse ".bold(),
); fs::relativize_path(path).bold(),
":".bold()
);
}
} }
// Add any missing `# noqa` pragmas. // Add any missing `# noqa` pragmas.
@ -372,8 +375,10 @@ pub fn lint_fix<'a>(
// longer parseable on a subsequent pass, then we've introduced a // longer parseable on a subsequent pass, then we've introduced a
// syntax error. Return the original code. // syntax error. Return the original code.
if parseable && result.error.is_some() { if parseable && result.error.is_some() {
eprintln!( #[allow(clippy::print_stderr)]
r#" {
eprintln!(
r#"
{}: Autofix introduced a syntax error. Reverting all changes. {}: Autofix introduced a syntax error. Reverting all changes.
This indicates a bug in `{}`. If you could open an issue at: This indicates a bug in `{}`. If you could open an issue at:
@ -382,11 +387,12 @@ This indicates a bug in `{}`. If you could open an issue at:
...quoting the contents of `{}`, along with the `pyproject.toml` settings and executed command, we'd be very appreciative! ...quoting the contents of `{}`, along with the `pyproject.toml` settings and executed command, we'd be very appreciative!
"#, "#,
"error".red().bold(), "error".red().bold(),
CARGO_PKG_NAME, CARGO_PKG_NAME,
CARGO_PKG_REPOSITORY, CARGO_PKG_REPOSITORY,
fs::relativize_path(path), fs::relativize_path(path),
); );
}
return Err(anyhow!("Autofix introduced a syntax error")); return Err(anyhow!("Autofix introduced a syntax error"));
} }
} }
@ -407,8 +413,10 @@ This indicates a bug in `{}`. If you could open an issue at:
continue; continue;
} }
eprintln!( #[allow(clippy::print_stderr)]
r#" {
eprintln!(
r#"
{}: Failed to converge after {} iterations. {}: Failed to converge after {} iterations.
This indicates a bug in `{}`. If you could open an issue at: This indicates a bug in `{}`. If you could open an issue at:
@ -417,12 +425,13 @@ This indicates a bug in `{}`. If you could open an issue at:
...quoting the contents of `{}`, along with the `pyproject.toml` settings and executed command, we'd be very appreciative! ...quoting the contents of `{}`, along with the `pyproject.toml` settings and executed command, we'd be very appreciative!
"#, "#,
"error".red().bold(), "error".red().bold(),
MAX_ITERATIONS, MAX_ITERATIONS,
CARGO_PKG_NAME, CARGO_PKG_NAME,
CARGO_PKG_REPOSITORY, CARGO_PKG_REPOSITORY,
fs::relativize_path(path), fs::relativize_path(path),
); );
}
} }
// Convert to messages. // Convert to messages.

View file

@ -1,3 +1,11 @@
use itertools::izip;
use log::error;
use once_cell::unsync::Lazy;
use rustpython_ast::{Cmpop, Expr};
use serde::{Deserialize, Serialize};
use ruff_macros::derive_message_formats;
use crate::ast::helpers; use crate::ast::helpers;
use crate::ast::operations::locate_cmpops; use crate::ast::operations::locate_cmpops;
use crate::ast::types::Range; use crate::ast::types::Range;
@ -6,11 +14,6 @@ use crate::define_violation;
use crate::fix::Fix; use crate::fix::Fix;
use crate::registry::Diagnostic; use crate::registry::Diagnostic;
use crate::violation::AlwaysAutofixableViolation; use crate::violation::AlwaysAutofixableViolation;
use itertools::izip;
use once_cell::unsync::Lazy;
use ruff_macros::derive_message_formats;
use rustpython_ast::{Cmpop, Expr};
use serde::{Deserialize, Serialize};
#[derive(Debug, PartialEq, Eq, Serialize, Deserialize)] #[derive(Debug, PartialEq, Eq, Serialize, Deserialize)]
pub enum IsCmpop { pub enum IsCmpop {
@ -75,7 +78,7 @@ pub fn invalid_literal_comparison(
Cmpop::Is => Some("==".to_string()), Cmpop::Is => Some("==".to_string()),
Cmpop::IsNot => Some("!=".to_string()), Cmpop::IsNot => Some("!=".to_string()),
node => { node => {
eprintln!("Failed to fix invalid comparison: {node:?}"); error!("Failed to fix invalid comparison: {node:?}");
None None
} }
} { } {
@ -89,7 +92,7 @@ pub fn invalid_literal_comparison(
)); ));
} }
} else { } else {
eprintln!("Failed to fix invalid comparison due to missing op"); error!("Failed to fix invalid comparison due to missing op");
} }
} }
checker.diagnostics.push(diagnostic); checker.diagnostics.push(diagnostic);