diff --git a/resources/test/project/README.md b/resources/test/project/README.md index 978d3d2db6..d9a22fcd1a 100644 --- a/resources/test/project/README.md +++ b/resources/test/project/README.md @@ -64,11 +64,11 @@ Found 9 error(s). 9 potentially fixable with the --fix option. ``` -Running from a parent directory should this "ignore" the `exclude` (hence, `concepts/file.py` gets +Running from a parent directory should "ignore" the `exclude` (hence, `concepts/file.py` gets included in the output): ``` -∴ (cd resources/test/project/examples && cargo run -- --config=docs/pyproject.toml .) +∴ (cd resources/test/project/examples && cargo run -- --config=docs/ruff.toml .) docs/docs/concepts/file.py:5:5: F841 Local variable `x` is assigned to but never used docs/docs/file.py:1:1: I001 Import block is un-sorted or un-formatted docs/docs/file.py:8:5: F841 Local variable `x` is assigned to but never used @@ -90,5 +90,7 @@ Unless we `--force-exclude`: ``` ∴ cargo run resources/test/project/examples/excluded/ --force-exclude +warning: No Python files found under the given path(s) ∴ cargo run resources/test/project/examples/excluded/script.py --force-exclude +warning: No Python files found under the given path(s) ``` diff --git a/src/commands.rs b/src/commands.rs index 545839485c..8e49bdbdf8 100644 --- a/src/commands.rs +++ b/src/commands.rs @@ -46,9 +46,10 @@ pub fn run( if paths.is_empty() { one_time_warning!( - "{}: {}", + "{}{} {}", "warning".yellow().bold(), - "No Python files found under the given path(s)" + ":".bold(), + "No Python files found under the given path(s)".bold() ); return Ok(Diagnostics::default()); } @@ -196,9 +197,10 @@ pub fn add_noqa( if paths.is_empty() { one_time_warning!( - "{}: {}", + "{}{} {}", "warning".yellow().bold(), - "No Python files found under the given path(s)" + ":".bold(), + "No Python files found under the given path(s)".bold() ); return Ok(0); } @@ -270,9 +272,10 @@ pub fn show_files( if paths.is_empty() { one_time_warning!( - "{}: {}", + "{}{} {}", "warning".yellow().bold(), - "No Python files found under the given path(s)" + ":".bold(), + "No Python files found under the given path(s)".bold() ); return Ok(()); } diff --git a/src/main_native.rs b/src/main_native.rs index c7826dbab7..fede80b696 100644 --- a/src/main_native.rs +++ b/src/main_native.rs @@ -32,6 +32,7 @@ use clap::{CommandFactory, Parser}; use colored::Colorize; use notify::{recommended_watcher, RecursiveMode, Watcher}; use path_absolutize::path_dedot; +use ruff::one_time_warning; /// Resolve the relevant settings strategy and defaults for the current /// invocation. @@ -177,24 +178,30 @@ pub(crate) fn inner_main() -> Result { if cache { // `--no-cache` doesn't respect code changes, and so is often confusing during // development. - eprintln!( - "{}: debug build without --no-cache.", - "warning".yellow().bold() + one_time_warning!( + "{}{} {}", + "warning".yellow().bold(), + ":".bold(), + "debug build without --no-cache.".bold() ); } let printer = Printer::new(&format, &log_level, &autofix, &violations); if cli.watch { if !matches!(autofix, fixer::Mode::None) { - eprintln!( - "{}: --fix is not enabled in watch mode.", - "warning".yellow().bold() + one_time_warning!( + "{}{} {}", + "warning".yellow().bold(), + ":".bold(), + "--fix is not enabled in watch mode.".bold() ); } if format != SerializationFormat::Text { - eprintln!( - "{}: --format 'text' is used in watch mode.", - "warning".yellow().bold() + one_time_warning!( + "{}{} {}", + "warning".yellow().bold(), + ":".bold(), + "--format 'text' is used in watch mode.".bold() ); } diff --git a/src/resolver.rs b/src/resolver.rs index af851d6e7d..b66443e805 100644 --- a/src/resolver.rs +++ b/src/resolver.rs @@ -215,19 +215,7 @@ pub fn python_files_in_path( overrides: &Overrides, ) -> Result<(Vec>, Resolver)> { // Normalize every path (e.g., convert from relative to absolute). - let mut paths = paths - .iter() - .map(|path| { - if path.is_file() && !is_python_path(path) { - Err(anyhow::anyhow!( - "`{}` is not supported; Ruff only supports `.py` and `.pyi` files", - path.to_str().unwrap() - )) - } else { - Ok(fs::normalize_path(path)) - } - }) - .collect::>>()?; + let mut paths: Vec = paths.iter().map(fs::normalize_path).collect(); // Search for `pyproject.toml` files in all parent directories. let mut resolver = Resolver::default(); @@ -331,7 +319,12 @@ pub fn python_files_in_path( } } - if result.as_ref().map_or(true, is_python_entry) { + if result.as_ref().map_or(true, |entry| { + // Accept all files that are passed-in directly. + (entry.depth() == 0 && entry.file_type().map_or(false, |ft| ft.is_file())) + // Accept all Python files. + || is_python_entry(entry) + }) { files.lock().unwrap().push(result); } @@ -456,7 +449,7 @@ mod tests { assert!(match_exclusion( file_path, file_basename, - &make_exclusion(exclude,) + &make_exclusion(exclude), )); let path = Path::new("foo/bar").absolutize_from(project_root).unwrap(); @@ -471,7 +464,7 @@ mod tests { assert!(match_exclusion( file_path, file_basename, - &make_exclusion(exclude,) + &make_exclusion(exclude), )); let path = Path::new("foo/bar/baz.py") @@ -488,7 +481,7 @@ mod tests { assert!(match_exclusion( file_path, file_basename, - &make_exclusion(exclude,) + &make_exclusion(exclude), )); let path = Path::new("foo/bar").absolutize_from(project_root).unwrap(); @@ -503,7 +496,7 @@ mod tests { assert!(match_exclusion( file_path, file_basename, - &make_exclusion(exclude,) + &make_exclusion(exclude), )); let path = Path::new("foo/bar/baz.py") @@ -520,7 +513,7 @@ mod tests { assert!(match_exclusion( file_path, file_basename, - &make_exclusion(exclude,) + &make_exclusion(exclude), )); let path = Path::new("foo/bar/baz.py") @@ -537,7 +530,7 @@ mod tests { assert!(match_exclusion( file_path, file_basename, - &make_exclusion(exclude,) + &make_exclusion(exclude), )); let path = Path::new("foo/bar/baz.py") @@ -554,7 +547,7 @@ mod tests { assert!(!match_exclusion( file_path, file_basename, - &make_exclusion(exclude,) + &make_exclusion(exclude), )); Ok(())