Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 17 additions & 9 deletions crates/ruff/src/commands/add_noqa.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use ruff_linter::source_kind::SourceKind;
use ruff_linter::warn_user_once;
use ruff_python_ast::{PySourceType, SourceType};
use ruff_workspace::resolver::{
PyprojectConfig, ResolvedFile, match_exclusion, python_files_in_path,
PyprojectConfig, ResolvedFile, match_exclusion, project_files_in_path,
};

use crate::args::ConfigArguments;
Expand All @@ -25,10 +25,22 @@ pub(crate) fn add_noqa(
) -> Result<usize> {
// Collect all the files to check.
let start = Instant::now();
let (paths, resolver) = python_files_in_path(files, pyproject_config, config_arguments)?;
let (mut paths, resolver) = project_files_in_path(files, pyproject_config, config_arguments)?;
let duration = start.elapsed();
debug!("Identified files to lint in: {duration:?}");

// Filter out paths for file types not supported for linting
paths.retain(|path| {
if let Ok(ResolvedFile::Root(path) | ResolvedFile::Nested(path)) = path {
matches!(
SourceType::from(path),
SourceType::Python(PySourceType::Python | PySourceType::Stub)
)
} else {
true
}
});

if paths.is_empty() {
warn_user_once!("No Python files found under the given path(s)");
return Ok(0);
Expand All @@ -48,11 +60,7 @@ pub(crate) fn add_noqa(
.par_iter()
.flatten()
.filter_map(|resolved_file| {
let SourceType::Python(source_type @ (PySourceType::Python | PySourceType::Stub)) =
SourceType::from(resolved_file.path())
else {
return None;
};
let source_type = SourceType::from(resolved_file.path());
let path = resolved_file.path();
let package = resolved_file
.path()
Expand All @@ -69,7 +77,7 @@ pub(crate) fn add_noqa(
{
return None;
}
let source_kind = match SourceKind::from_path(path, SourceType::Python(source_type)) {
let source_kind = match SourceKind::from_path(path, source_type) {
Ok(Some(source_kind)) => source_kind,
Ok(None) => return None,
Err(e) => {
Expand All @@ -81,7 +89,7 @@ pub(crate) fn add_noqa(
path,
package,
&source_kind,
source_type,
source_type.expect_python(),
&settings.linter,
reason,
) {
Expand Down
34 changes: 14 additions & 20 deletions crates/ruff/src/commands/analyze_graph.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use ruff_linter::package::PackageRoot;
use ruff_linter::source_kind::SourceKind;
use ruff_linter::{warn_user, warn_user_once};
use ruff_python_ast::SourceType;
use ruff_workspace::resolver::{ResolvedFile, match_exclusion, python_files_in_path};
use ruff_workspace::resolver::{ResolvedFile, match_exclusion, project_files_in_path};
use rustc_hash::{FxBuildHasher, FxHashMap};
use std::io::Write;
use std::path::{Path, PathBuf};
Expand All @@ -35,7 +35,16 @@ pub(crate) fn analyze_graph(

// Find all Python files.
let files = resolve_default_files(args.files, false);
let (paths, resolver) = python_files_in_path(&files, &pyproject_config, config_arguments)?;
let (mut paths, resolver) = project_files_in_path(&files, &pyproject_config, config_arguments)?;

// Filter to only Python files
paths.retain(|path| {
if let Ok(ResolvedFile::Root(path) | ResolvedFile::Nested(path)) = path {
matches!(SourceType::from(path), SourceType::Python(_))
} else {
true
}
});

if paths.is_empty() {
warn_user_once!("No Python files found under the given path(s)");
Expand Down Expand Up @@ -124,6 +133,7 @@ pub(crate) fn analyze_graph(
let string_imports = settings.analyze.string_imports;
let include_dependencies = settings.analyze.include_dependencies.get(path).cloned();
let type_checking_imports = settings.analyze.type_checking_imports;
let source_type = settings.analyze.extension.get_source_type(path);

// Skip excluded files.
if (settings.file_resolver.force_exclude || !resolved_file.is_root())
Expand All @@ -136,19 +146,6 @@ pub(crate) fn analyze_graph(
continue;
}

// Ignore non-Python files.
let source_type = match settings.analyze.extension.get_source_type(path) {
SourceType::Python(source_type) => source_type,
SourceType::Toml(_) => {
debug!("Ignoring TOML file: {}", path.display());
continue;
}
SourceType::Markdown => {
debug!("Ignoring Markdown file: {}", path.display());
continue;
}
};

// Convert to system paths.
let Ok(package) = package.map(SystemPathBuf::from_path_buf).transpose() else {
warn!("Failed to convert package to system path");
Expand All @@ -165,10 +162,7 @@ pub(crate) fn analyze_graph(
let result = inner_result.clone();
scope.spawn(move |_| {
// Extract source code (handles both .py and .ipynb files)
let source_kind = match SourceKind::from_path(
path.as_std_path(),
SourceType::Python(source_type),
) {
let source_kind = match SourceKind::from_path(path.as_std_path(), source_type) {
Ok(Some(source_kind)) => source_kind,
Ok(None) => {
debug!("Skipping non-Python notebook: {path}");
Expand All @@ -186,7 +180,7 @@ pub(crate) fn analyze_graph(
let mut imports = ModuleImports::detect(
&db,
source_code,
source_type,
source_type.expect_python(),
&path,
package.as_deref(),
string_imports,
Expand Down
17 changes: 15 additions & 2 deletions crates/ruff/src/commands/check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ use log::{debug, warn};
#[cfg(not(target_family = "wasm"))]
use rayon::prelude::*;
use ruff_linter::message::create_panic_diagnostic;
use ruff_python_ast::{SourceType, TomlSourceType};
use rustc_hash::FxHashMap;

use ruff_db::diagnostic::Diagnostic;
Expand All @@ -22,7 +23,7 @@ use ruff_linter::{IOError, Violation, fs, warn_user_once};
use ruff_source_file::SourceFileBuilder;
use ruff_text_size::TextRange;
use ruff_workspace::resolver::{
PyprojectConfig, ResolvedFile, match_exclusion, python_files_in_path,
PyprojectConfig, ResolvedFile, match_exclusion, project_files_in_path,
};

use crate::args::ConfigArguments;
Expand All @@ -41,9 +42,21 @@ pub(crate) fn check(
) -> Result<Diagnostics> {
// Collect all the Python files to check.
let start = Instant::now();
let (paths, resolver) = python_files_in_path(files, pyproject_config, config_arguments)?;
let (mut paths, resolver) = project_files_in_path(files, pyproject_config, config_arguments)?;
debug!("Identified files to lint in: {:?}", start.elapsed());

// Filter out paths for file types not supported for linting
paths.retain(|path| {
if let Ok(ResolvedFile::Root(path) | ResolvedFile::Nested(path)) = path {
matches!(
SourceType::from(path),
SourceType::Python(_) | SourceType::Toml(TomlSourceType::Pyproject)
)
} else {
true
}
});

if paths.is_empty() {
warn_user_once!("No Python files found under the given path(s)");
return Ok(Diagnostics::default());
Expand Down
4 changes: 2 additions & 2 deletions crates/ruff/src/commands/check_stdin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use ruff_db::diagnostic::Diagnostic;
use ruff_linter::package::PackageRoot;
use ruff_linter::packaging;
use ruff_linter::settings::flags;
use ruff_workspace::resolver::{PyprojectConfig, Resolver, match_exclusion, python_file_at_path};
use ruff_workspace::resolver::{PyprojectConfig, Resolver, match_exclusion, project_file_at_path};

use crate::args::ConfigArguments;
use crate::diagnostics::{Diagnostics, lint_stdin};
Expand All @@ -23,7 +23,7 @@ pub(crate) fn check_stdin(

if resolver.force_exclude() {
if let Some(filename) = filename {
if !python_file_at_path(filename, &mut resolver, overrides)? {
if !project_file_at_path(filename, &mut resolver, overrides)? {
if fix_mode.is_apply() {
parrot_stdin()?;
}
Expand Down
4 changes: 2 additions & 2 deletions crates/ruff/src/commands/format.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ use ruff_source_file::{LineIndex, LineRanges, OneIndexed, SourceFileBuilder};
use ruff_text_size::{TextLen, TextRange, TextSize};
use ruff_workspace::FormatterSettings;
use ruff_workspace::resolver::{
PyprojectConfig, ResolvedFile, Resolver, match_exclusion, python_files_in_path,
PyprojectConfig, ResolvedFile, Resolver, match_exclusion, project_files_in_path,
};

use crate::args::{ConfigArguments, FormatArguments, FormatRange};
Expand Down Expand Up @@ -75,7 +75,7 @@ pub(crate) fn format(
) -> Result<ExitStatus> {
let mode = FormatMode::from_cli(&cli);
let files = resolve_default_files(cli.files, false);
let (paths, resolver) = python_files_in_path(&files, pyproject_config, config_arguments)?;
let (paths, resolver) = project_files_in_path(&files, pyproject_config, config_arguments)?;

let output_format = pyproject_config.settings.output_format;
let preview = pyproject_config.settings.formatter.preview;
Expand Down
4 changes: 2 additions & 2 deletions crates/ruff/src/commands/format_stdin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use log::error;
use ruff_linter::source_kind::{SourceError, SourceKind};
use ruff_python_ast::SourceType;
use ruff_workspace::FormatterSettings;
use ruff_workspace::resolver::{PyprojectConfig, Resolver, match_exclusion, python_file_at_path};
use ruff_workspace::resolver::{PyprojectConfig, Resolver, match_exclusion, project_file_at_path};

use crate::ExitStatus;
use crate::args::{ConfigArguments, FormatArguments, FormatRange};
Expand All @@ -30,7 +30,7 @@ pub(crate) fn format_stdin(

if resolver.force_exclude() {
if let Some(filename) = cli.stdin_filename.as_deref() {
if !python_file_at_path(filename, &mut resolver, config_arguments)? {
if !project_file_at_path(filename, &mut resolver, config_arguments)? {
if mode.is_write() {
parrot_stdin()?;
}
Expand Down
17 changes: 15 additions & 2 deletions crates/ruff/src/commands/show_files.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ use anyhow::Result;
use itertools::Itertools;

use ruff_linter::warn_user_once;
use ruff_workspace::resolver::{PyprojectConfig, ResolvedFile, python_files_in_path};
use ruff_python_ast::{SourceType, TomlSourceType};
use ruff_workspace::resolver::{PyprojectConfig, ResolvedFile, project_files_in_path};

use crate::args::ConfigArguments;

Expand All @@ -17,7 +18,19 @@ pub(crate) fn show_files(
writer: &mut impl Write,
) -> Result<()> {
// Collect all files in the hierarchy.
let (paths, _resolver) = python_files_in_path(files, pyproject_config, config_arguments)?;
let (mut paths, _resolver) = project_files_in_path(files, pyproject_config, config_arguments)?;

// Filter out paths for file types not supported for linting
paths.retain(|path| {
if let Ok(ResolvedFile::Root(path) | ResolvedFile::Nested(path)) = path {
matches!(
SourceType::from(path),
SourceType::Python(_) | SourceType::Toml(TomlSourceType::Pyproject)
)
} else {
true
}
});

if paths.is_empty() {
warn_user_once!("No Python files found under the given path(s)");
Expand Down
4 changes: 2 additions & 2 deletions crates/ruff/src/commands/show_settings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use std::path::PathBuf;
use anyhow::{Result, bail};
use itertools::Itertools;

use ruff_workspace::resolver::{PyprojectConfig, ResolvedFile, python_files_in_path};
use ruff_workspace::resolver::{PyprojectConfig, ResolvedFile, project_files_in_path};

use crate::args::ConfigArguments;

Expand All @@ -16,7 +16,7 @@ pub(crate) fn show_settings(
writer: &mut impl Write,
) -> Result<()> {
// Collect all files in the hierarchy.
let (paths, resolver) = python_files_in_path(files, pyproject_config, config_arguments)?;
let (paths, resolver) = project_files_in_path(files, pyproject_config, config_arguments)?;

// Print the list of files.
let Some(path) = paths
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ file_resolver.include = [
"*.pyw",
"*.ipynb",
"**/pyproject.toml",
"*.md",
]
file_resolver.extend_include = []
file_resolver.respect_gitignore = true
Expand Down
4 changes: 2 additions & 2 deletions crates/ruff_dev/src/format_dev.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ use ruff_python_formatter::{
FormatModuleError, MagicTrailingComma, PreviewMode, PyFormatOptions, format_module_source,
};
use ruff_python_parser::ParseError;
use ruff_workspace::resolver::{PyprojectConfig, ResolvedFile, Resolver, python_files_in_path};
use ruff_workspace::resolver::{PyprojectConfig, ResolvedFile, Resolver, project_files_in_path};

fn parse_cli(dirs: &[PathBuf]) -> anyhow::Result<(FormatArguments, ConfigArguments)> {
let args_matches = FormatCommand::command()
Expand Down Expand Up @@ -68,7 +68,7 @@ fn ruff_check_paths<'a>(
cli: &FormatArguments,
config_arguments: &ConfigArguments,
) -> anyhow::Result<(Vec<Result<ResolvedFile, ignore::Error>>, Resolver<'a>)> {
let (paths, resolver) = python_files_in_path(&cli.files, pyproject_config, config_arguments)?;
let (paths, resolver) = project_files_in_path(&cli.files, pyproject_config, config_arguments)?;
Ok((paths, resolver))
}

Expand Down
2 changes: 1 addition & 1 deletion crates/ruff_workspace/src/options.rs
Original file line number Diff line number Diff line change
Expand Up @@ -262,7 +262,7 @@ pub struct Options {
///
/// For more information on the glob syntax, refer to the [`globset` documentation](https://docs.rs/globset/latest/globset/#syntax).
#[option(
default = r#"["*.py", "*.pyi", "*.pyw", "*.ipynb", "**/pyproject.toml"]"#,
default = r#"["*.py", "*.pyi", "*.pyw", "*.ipynb", "*.md", "**/pyproject.toml"]"#,
value_type = "list[str]",
example = r#"
include = ["*.py"]
Expand Down
12 changes: 6 additions & 6 deletions crates/ruff_workspace/src/resolver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -432,8 +432,8 @@ impl From<ConfigurationOrigin> for Relativity {
}
}

/// Find all Python (`.py`, `.pyi`, `.pyw`, and `.ipynb` files) in a set of paths.
pub fn python_files_in_path<'a>(
/// Find all project files in a set of paths, following configured include/exclude settings.
pub fn project_files_in_path<'a>(
paths: &[PathBuf],
pyproject_config: &'a PyprojectConfig,
transformer: &(dyn ConfigurationTransformer + Sync),
Expand Down Expand Up @@ -504,7 +504,7 @@ pub fn python_files_in_path<'a>(

let walker = builder.build_parallel();

// Run the `WalkParallel` to collect all Python files.
// Run the `WalkParallel` to collect all files.
let state = WalkPythonFilesState::new(resolver);
let mut visitor = PythonFilesVisitorBuilder::new(transformer, &state);
walker.visit(&mut visitor);
Expand Down Expand Up @@ -762,7 +762,7 @@ impl ResolvedFile {
}

/// Return `true` if the Python file at [`Path`] is _not_ excluded.
pub fn python_file_at_path(
pub fn project_file_at_path(
path: &Path,
resolver: &mut Resolver,
transformer: &dyn ConfigurationTransformer,
Expand Down Expand Up @@ -962,7 +962,7 @@ mod tests {
use crate::pyproject::find_settings_toml;
use crate::resolver::{
ConfigurationOrigin, ConfigurationTransformer, PyprojectConfig, PyprojectDiscoveryStrategy,
ResolvedFile, Resolver, is_file_excluded, match_exclusion, python_files_in_path,
ResolvedFile, Resolver, is_file_excluded, match_exclusion, project_files_in_path,
resolve_root_settings,
};
use crate::settings::Settings;
Expand Down Expand Up @@ -1024,7 +1024,7 @@ mod tests {
File::create(&file2)?;
create_dir(dir2)?;

let (paths, _) = python_files_in_path(
let (paths, _) = project_files_in_path(
&[root.to_path_buf()],
&PyprojectConfig::new(PyprojectDiscoveryStrategy::Fixed, Settings::default(), None),
&NoOpTransformer,
Expand Down
1 change: 1 addition & 0 deletions crates/ruff_workspace/src/settings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,7 @@ pub(crate) static INCLUDE_PREVIEW: &[FilePattern] = &[
FilePattern::Builtin("*.pyw"),
FilePattern::Builtin("*.ipynb"),
FilePattern::Builtin("**/pyproject.toml"),
FilePattern::Builtin("*.md"),
];

impl FileResolverSettings {
Expand Down
Loading