Move pyproject_config into Resolver (#9453)

## Summary

Sort of a random PR to make the coupling between `pyproject_config` and
`resolver` more explicit by passing it to the `Resolver`, rather than
threading it through to each individual method.
This commit is contained in:
Charlie Marsh 2024-01-10 17:58:53 -05:00 committed by GitHub
parent 79f4abbb8d
commit 4a3bb67b5f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 144 additions and 149 deletions

View file

@ -27,7 +27,7 @@ use tracing_subscriber::layer::SubscriberExt;
use tracing_subscriber::util::SubscriberInitExt;
use tracing_subscriber::EnvFilter;
use ruff_cli::args::{FormatCommand, LogLevelArgs};
use ruff_cli::args::{CliOverrides, FormatArguments, FormatCommand, LogLevelArgs};
use ruff_cli::resolve::resolve;
use ruff_formatter::{FormatError, LineWidth, PrintError};
use ruff_linter::logging::LogLevel;
@ -38,24 +38,24 @@ use ruff_python_formatter::{
use ruff_python_parser::ParseError;
use ruff_workspace::resolver::{python_files_in_path, PyprojectConfig, ResolvedFile, Resolver};
/// Find files that ruff would check so we can format them. Adapted from `ruff_cli`.
#[allow(clippy::type_complexity)]
fn ruff_check_paths(
dirs: &[PathBuf],
) -> anyhow::Result<(
Vec<Result<ResolvedFile, ignore::Error>>,
Resolver,
PyprojectConfig,
)> {
fn parse_cli(dirs: &[PathBuf]) -> anyhow::Result<(FormatArguments, CliOverrides)> {
let args_matches = FormatCommand::command()
.no_binary_name(true)
.get_matches_from(dirs);
let arguments: FormatCommand = FormatCommand::from_arg_matches(&args_matches)?;
let (cli, overrides) = arguments.partition();
Ok((cli, overrides))
}
/// Find the [`PyprojectConfig`] to use for formatting.
fn find_pyproject_config(
cli: &FormatArguments,
overrides: &CliOverrides,
) -> anyhow::Result<PyprojectConfig> {
let mut pyproject_config = resolve(
cli.isolated,
cli.config.as_deref(),
&overrides,
overrides,
cli.stdin_filename.as_deref(),
)?;
// We don't want to format pyproject.toml
@ -64,11 +64,18 @@ fn ruff_check_paths(
FilePattern::Builtin("*.pyi"),
])
.unwrap();
let (paths, resolver) = python_files_in_path(&cli.files, &pyproject_config, &overrides)?;
if paths.is_empty() {
bail!("no python files in {:?}", dirs)
}
Ok((paths, resolver, pyproject_config))
Ok(pyproject_config)
}
/// Find files that ruff would check so we can format them. Adapted from `ruff_cli`.
#[allow(clippy::type_complexity)]
fn ruff_check_paths<'a>(
pyproject_config: &'a PyprojectConfig,
cli: &FormatArguments,
overrides: &CliOverrides,
) -> anyhow::Result<(Vec<Result<ResolvedFile, ignore::Error>>, Resolver<'a>)> {
let (paths, resolver) = python_files_in_path(&cli.files, pyproject_config, overrides)?;
Ok((paths, resolver))
}
/// Collects statistics over the formatted files to compute the Jaccard index or the similarity
@ -452,11 +459,17 @@ fn format_dev_project(
files[0].display()
);
// TODO(konstin): black excludes
// TODO(konstin): Respect black's excludes.
// Find files to check (or in this case, format twice). Adapted from ruff_cli
// First argument is ignored
let (paths, resolver, pyproject_config) = ruff_check_paths(files)?;
let (cli, overrides) = parse_cli(files)?;
let pyproject_config = find_pyproject_config(&cli, &overrides)?;
let (paths, resolver) = ruff_check_paths(&pyproject_config, &cli, &overrides)?;
if paths.is_empty() {
bail!("No Python files found under the given path(s)");
}
let results = {
let pb_span =
@ -469,14 +482,7 @@ fn format_dev_project(
#[cfg(feature = "singlethreaded")]
let iter = { paths.into_iter() };
iter.map(|path| {
let result = format_dir_entry(
path,
stability_check,
write,
&black_options,
&resolver,
&pyproject_config,
);
let result = format_dir_entry(path, stability_check, write, &black_options, &resolver);
pb_span.pb_inc(1);
result
})
@ -526,14 +532,13 @@ fn format_dev_project(
})
}
/// Error handling in between walkdir and `format_dev_file`
/// Error handling in between walkdir and `format_dev_file`.
fn format_dir_entry(
resolved_file: Result<ResolvedFile, ignore::Error>,
stability_check: bool,
write: bool,
options: &BlackOptions,
resolver: &Resolver,
pyproject_config: &PyprojectConfig,
) -> anyhow::Result<(Result<Statistics, CheckFileError>, PathBuf), Error> {
let resolved_file = resolved_file.context("Iterating the files in the repository failed")?;
// For some reason it does not filter in the beginning
@ -544,7 +549,7 @@ fn format_dir_entry(
let path = resolved_file.into_path();
let mut options = options.to_py_format_options(&path);
let settings = resolver.resolve(&path, pyproject_config);
let settings = resolver.resolve(&path);
// That's a bad way of doing this but it's not worth doing something better for format_dev
if settings.formatter.line_width != LineWidth::default() {
options = options.with_line_width(settings.formatter.line_width);