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`
"-Dunsafe_code",
"-Wclippy::pedantic",
# "-Wclippy::print_stdout",
# "-Wclippy::print_stderr",
# "-Wclippy::dbg_macro",
"-Wclippy::print_stdout",
"-Wclippy::print_stderr",
"-Wclippy::dbg_macro",
"-Wclippy::char_lit_as_u8",
"-Aclippy::collapsible_else_if",
"-Aclippy::collapsible_if",

View file

@ -47,7 +47,11 @@ fn main() -> Result<()> {
// Create Ruff's pyproject.toml section.
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(())
}

View file

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

View file

@ -19,7 +19,11 @@ pub fn linter(format: HelpFormat) {
.join("/"),
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();
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 {
// Notify the user of any parse errors.
eprintln!(
"{}{} {}{}{} {err}",
"error".red().bold(),
":".bold(),
"Failed to parse ".bold(),
fs::relativize_path(path).bold(),
":".bold()
);
#[allow(clippy::print_stderr)]
{
eprintln!(
"{}{} {}{}{} {err}",
"error".red().bold(),
":".bold(),
"Failed to parse ".bold(),
fs::relativize_path(path).bold(),
":".bold()
);
}
// Purge the cache.
cache::del(path, package.as_ref(), settings, autofix.into());
@ -207,12 +210,15 @@ pub fn lint_stdin(
};
if let Some(err) = parse_error {
eprintln!(
"{}{} Failed to parse {}: {err}",
"error".red().bold(),
":".bold(),
path.map_or_else(|| "-".into(), fs::relativize_path).bold()
);
#[allow(clippy::print_stderr)]
{
eprintln!(
"{}{} Failed to parse {}: {err}",
"error".red().bold(),
":".bold(),
path.map_or_else(|| "-".into(), fs::relativize_path).bold()
);
}
}
Ok(Diagnostics { messages, fixed })

View file

@ -53,16 +53,19 @@ fn inner_main() -> Result<ExitCode> {
{
let default_panic_hook = std::panic::take_hook();
std::panic::set_hook(Box::new(move |info| {
eprintln!(
r#"
#[allow(clippy::print_stderr)]
{
eprintln!(
r#"
{}: `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
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);
}));
}
@ -157,7 +160,10 @@ fn check(args: CheckArgs, log_level: LogLevel) -> Result<ExitCode> {
}
let modifications = commands::add_noqa(&cli.files, &pyproject_strategy, &overrides)?;
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);
}
@ -287,7 +293,10 @@ pub fn main() -> ExitCode {
match inner_main() {
Ok(code) => code,
Err(err) => {
eprintln!("{}{} {err:?}", "error".red().bold(), ":".bold());
#[allow(clippy::print_stderr)]
{
eprintln!("{}{} {err:?}", "error".red().bold(), ":".bold());
}
ExitCode::FAILURE
}
}

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -65,11 +65,17 @@ pub fn convert(
let plugins = plugins.unwrap_or_else(|| {
let from_options = plugin::infer_plugins_from_options(flake8);
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);
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()
});

View file

@ -236,14 +236,17 @@ pub fn add_noqa_to_path(path: &Path, settings: &Settings) -> Result<usize> {
// Log any parse errors.
if let Some(err) = error {
eprintln!(
"{}{} {}{}{} {err:?}",
"error".red().bold(),
":".bold(),
"Failed to parse ".bold(),
fs::relativize_path(path).bold(),
":".bold()
);
#[allow(clippy::print_stderr)]
{
eprintln!(
"{}{} {}{}{} {err:?}",
"error".red().bold(),
":".bold(),
"Failed to parse ".bold(),
fs::relativize_path(path).bold(),
":".bold()
);
}
}
// 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
// syntax error. Return the original code.
if parseable && result.error.is_some() {
eprintln!(
r#"
#[allow(clippy::print_stderr)]
{
eprintln!(
r#"
{}: Autofix introduced a syntax error. Reverting all changes.
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!
"#,
"error".red().bold(),
CARGO_PKG_NAME,
CARGO_PKG_REPOSITORY,
fs::relativize_path(path),
);
"error".red().bold(),
CARGO_PKG_NAME,
CARGO_PKG_REPOSITORY,
fs::relativize_path(path),
);
}
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;
}
eprintln!(
r#"
#[allow(clippy::print_stderr)]
{
eprintln!(
r#"
{}: Failed to converge after {} iterations.
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!
"#,
"error".red().bold(),
MAX_ITERATIONS,
CARGO_PKG_NAME,
CARGO_PKG_REPOSITORY,
fs::relativize_path(path),
);
"error".red().bold(),
MAX_ITERATIONS,
CARGO_PKG_NAME,
CARGO_PKG_REPOSITORY,
fs::relativize_path(path),
);
}
}
// 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::operations::locate_cmpops;
use crate::ast::types::Range;
@ -6,11 +14,6 @@ use crate::define_violation;
use crate::fix::Fix;
use crate::registry::Diagnostic;
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)]
pub enum IsCmpop {
@ -75,7 +78,7 @@ pub fn invalid_literal_comparison(
Cmpop::Is => Some("==".to_string()),
Cmpop::IsNot => Some("!=".to_string()),
node => {
eprintln!("Failed to fix invalid comparison: {node:?}");
error!("Failed to fix invalid comparison: {node:?}");
None
}
} {
@ -89,7 +92,7 @@ pub fn invalid_literal_comparison(
));
}
} 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);