Rename `ConfigProcessor` to `ConfigurationTransformer` (#7536)

This commit is contained in:
Micha Reiser 2023-09-20 16:17:06 +02:00 committed by GitHub
parent b19eec9b2a
commit 83daddbeb7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 59 additions and 53 deletions

View File

@ -12,7 +12,7 @@ use ruff_linter::settings::types::{
};
use ruff_linter::{RuleSelector, RuleSelectorParser};
use ruff_workspace::configuration::{Configuration, RuleSelection};
use ruff_workspace::resolver::ConfigProcessor;
use ruff_workspace::resolver::ConfigurationTransformer;
#[derive(Debug, Parser)]
#[command(
@ -452,7 +452,7 @@ impl From<&LogLevelArgs> for LogLevel {
impl CheckCommand {
/// Partition the CLI into command-line arguments and configuration
/// overrides.
pub fn partition(self) -> (CheckArguments, Overrides) {
pub fn partition(self) -> (CheckArguments, CliOverrides) {
(
CheckArguments {
add_noqa: self.add_noqa,
@ -472,7 +472,7 @@ impl CheckCommand {
stdin_filename: self.stdin_filename,
watch: self.watch,
},
Overrides {
CliOverrides {
dummy_variable_rgx: self.dummy_variable_rgx,
exclude: self.exclude,
extend_exclude: self.extend_exclude,
@ -508,7 +508,7 @@ impl CheckCommand {
impl FormatCommand {
/// Partition the CLI into command-line arguments and configuration
/// overrides.
pub fn partition(self) -> (FormatArguments, Overrides) {
pub fn partition(self) -> (FormatArguments, CliOverrides) {
(
FormatArguments {
check: self.check,
@ -517,7 +517,7 @@ impl FormatCommand {
isolated: self.isolated,
stdin_filename: self.stdin_filename,
},
Overrides {
CliOverrides {
line_length: self.line_length,
respect_gitignore: resolve_bool_arg(
self.respect_gitignore,
@ -526,7 +526,7 @@ impl FormatCommand {
preview: resolve_bool_arg(self.preview, self.no_preview).map(PreviewMode::from),
force_exclude: resolve_bool_arg(self.force_exclude, self.no_force_exclude),
// Unsupported on the formatter CLI, but required on `Overrides`.
..Overrides::default()
..CliOverrides::default()
},
)
}
@ -577,7 +577,7 @@ pub struct FormatArguments {
/// CLI settings that function as configuration overrides.
#[derive(Clone, Default)]
#[allow(clippy::struct_excessive_bools)]
pub struct Overrides {
pub struct CliOverrides {
pub dummy_variable_rgx: Option<Regex>,
pub exclude: Option<Vec<FilePattern>>,
pub extend_exclude: Option<Vec<FilePattern>>,
@ -604,8 +604,8 @@ pub struct Overrides {
pub show_fixes: Option<bool>,
}
impl ConfigProcessor for Overrides {
fn process_config(&self, config: &mut Configuration) {
impl ConfigurationTransformer for CliOverrides {
fn transform(&self, mut config: Configuration) -> Configuration {
if let Some(cache_dir) = &self.cache_dir {
config.cache_dir = Some(cache_dir.clone());
}
@ -671,6 +671,8 @@ impl ConfigProcessor for Overrides {
if let Some(target_version) = &self.target_version {
config.target_version = Some(*target_version);
}
config
}
}

View File

@ -11,14 +11,14 @@ use ruff_linter::warn_user_once;
use ruff_python_ast::{PySourceType, SourceType};
use ruff_workspace::resolver::{python_files_in_path, PyprojectConfig};
use crate::args::Overrides;
use crate::args::CliOverrides;
use crate::diagnostics::LintSource;
/// Add `noqa` directives to a collection of files.
pub(crate) fn add_noqa(
files: &[PathBuf],
pyproject_config: &PyprojectConfig,
overrides: &Overrides,
overrides: &CliOverrides,
) -> Result<usize> {
// Collect all the files to check.
let start = Instant::now();

View File

@ -23,7 +23,7 @@ use ruff_source_file::SourceFileBuilder;
use ruff_text_size::{TextRange, TextSize};
use ruff_workspace::resolver::{python_files_in_path, PyprojectConfig, PyprojectDiscoveryStrategy};
use crate::args::Overrides;
use crate::args::CliOverrides;
use crate::cache::{self, Cache};
use crate::diagnostics::Diagnostics;
use crate::panic::catch_unwind;
@ -32,7 +32,7 @@ use crate::panic::catch_unwind;
pub(crate) fn check(
files: &[PathBuf],
pyproject_config: &PyprojectConfig,
overrides: &Overrides,
overrides: &CliOverrides,
cache: flags::Cache,
noqa: flags::Noqa,
autofix: flags::FixMode,
@ -241,7 +241,7 @@ mod test {
use ruff_linter::settings::{flags, Settings};
use ruff_workspace::resolver::{PyprojectConfig, PyprojectDiscoveryStrategy};
use crate::args::Overrides;
use crate::args::CliOverrides;
use super::check;
@ -277,7 +277,7 @@ mod test {
// Notebooks are not included by default
&[tempdir.path().to_path_buf(), notebook],
&pyproject_config,
&Overrides::default(),
&CliOverrides::default(),
flags::Cache::Disabled,
flags::Noqa::Disabled,
flags::FixMode::Generate,

View File

@ -6,7 +6,7 @@ use ruff_linter::packaging;
use ruff_linter::settings::flags;
use ruff_workspace::resolver::{python_file_at_path, PyprojectConfig};
use crate::args::Overrides;
use crate::args::CliOverrides;
use crate::diagnostics::{lint_stdin, Diagnostics};
use crate::stdin::read_from_stdin;
@ -14,7 +14,7 @@ use crate::stdin::read_from_stdin;
pub(crate) fn check_stdin(
filename: Option<&Path>,
pyproject_config: &PyprojectConfig,
overrides: &Overrides,
overrides: &CliOverrides,
noqa: flags::Noqa,
autofix: flags::FixMode,
) -> Result<Diagnostics> {

View File

@ -22,7 +22,7 @@ use ruff_python_formatter::{format_module, FormatModuleError, PyFormatOptions};
use ruff_source_file::{find_newline, LineEnding};
use ruff_workspace::resolver::python_files_in_path;
use crate::args::{FormatArguments, Overrides};
use crate::args::{CliOverrides, FormatArguments};
use crate::panic::{catch_unwind, PanicError};
use crate::resolve::resolve;
use crate::ExitStatus;
@ -38,7 +38,7 @@ pub(crate) enum FormatMode {
/// Format a set of files, and return the exit status.
pub(crate) fn format(
cli: &FormatArguments,
overrides: &Overrides,
overrides: &CliOverrides,
log_level: LogLevel,
) -> Result<ExitStatus> {
let pyproject_config = resolve(

View File

@ -10,14 +10,14 @@ use ruff_linter::settings::types::PreviewMode;
use ruff_python_formatter::{format_module, PyFormatOptions};
use ruff_workspace::resolver::python_file_at_path;
use crate::args::{FormatArguments, Overrides};
use crate::args::{CliOverrides, FormatArguments};
use crate::commands::format::{FormatCommandError, FormatCommandResult, FormatMode};
use crate::resolve::resolve;
use crate::stdin::read_from_stdin;
use crate::ExitStatus;
/// Run the formatter over a single file, read from `stdin`.
pub(crate) fn format_stdin(cli: &FormatArguments, overrides: &Overrides) -> Result<ExitStatus> {
pub(crate) fn format_stdin(cli: &FormatArguments, overrides: &CliOverrides) -> Result<ExitStatus> {
let pyproject_config = resolve(
cli.isolated,
cli.config.as_deref(),

View File

@ -7,13 +7,13 @@ use itertools::Itertools;
use ruff_linter::warn_user_once;
use ruff_workspace::resolver::{python_files_in_path, PyprojectConfig};
use crate::args::Overrides;
use crate::args::CliOverrides;
/// Show the list of files to be checked based on current settings.
pub(crate) fn show_files(
files: &[PathBuf],
pyproject_config: &PyprojectConfig,
overrides: &Overrides,
overrides: &CliOverrides,
writer: &mut impl Write,
) -> Result<()> {
// Collect all files in the hierarchy.

View File

@ -6,13 +6,13 @@ use itertools::Itertools;
use ruff_workspace::resolver::{python_files_in_path, PyprojectConfig};
use crate::args::Overrides;
use crate::args::CliOverrides;
/// Print the user-facing configuration settings.
pub(crate) fn show_settings(
files: &[PathBuf],
pyproject_config: &PyprojectConfig,
overrides: &Overrides,
overrides: &CliOverrides,
writer: &mut impl Write,
) -> Result<()> {
// Collect all files in the hierarchy.

View File

@ -7,23 +7,23 @@ use path_absolutize::path_dedot;
use ruff_workspace::configuration::Configuration;
use ruff_workspace::pyproject;
use ruff_workspace::resolver::{
resolve_root_settings, ConfigProcessor, PyprojectConfig, PyprojectDiscoveryStrategy, Relativity,
resolve_root_settings, ConfigurationTransformer, PyprojectConfig, PyprojectDiscoveryStrategy,
Relativity,
};
use crate::args::Overrides;
use crate::args::CliOverrides;
/// Resolve the relevant settings strategy and defaults for the current
/// invocation.
pub fn resolve(
isolated: bool,
config: Option<&Path>,
overrides: &Overrides,
overrides: &CliOverrides,
stdin_filename: Option<&Path>,
) -> Result<PyprojectConfig> {
// First priority: if we're running in isolated mode, use the default settings.
if isolated {
let mut config = Configuration::default();
overrides.process_config(&mut config);
let config = overrides.transform(Configuration::default());
let settings = config.into_settings(&path_dedot::CWD)?;
debug!("Isolated mode, not reading any pyproject.toml");
return Ok(PyprojectConfig::new(
@ -91,8 +91,7 @@ pub fn resolve(
// "closest" `pyproject.toml` file for every Python file later on, so these act
// as the "default" settings.)
debug!("Using Ruff default settings");
let mut config = Configuration::default();
overrides.process_config(&mut config);
let config = overrides.transform(Configuration::default());
let settings = config.into_settings(&path_dedot::CWD)?;
Ok(PyprojectConfig::new(
PyprojectDiscoveryStrategy::Hierarchical,

View File

@ -187,8 +187,11 @@ fn is_package_with_cache<'a>(
.or_insert_with(|| is_package(path, namespace_packages))
}
pub trait ConfigProcessor: Sync {
fn process_config(&self, config: &mut Configuration);
/// Applies a transformation to a [`Configuration`].
///
/// Used to override options with the the values provided by the CLI.
pub trait ConfigurationTransformer: Sync {
fn transform(&self, config: Configuration) -> Configuration;
}
/// Recursively resolve a [`Configuration`] from a `pyproject.toml` file at the
@ -200,7 +203,7 @@ pub trait ConfigProcessor: Sync {
fn resolve_configuration(
pyproject: &Path,
relativity: Relativity,
processor: &dyn ConfigProcessor,
transformer: &dyn ConfigurationTransformer,
) -> Result<Configuration> {
let mut seen = FxHashSet::default();
let mut stack = vec![];
@ -242,8 +245,7 @@ fn resolve_configuration(
while let Some(extend) = stack.pop() {
configuration = configuration.combine(extend);
}
processor.process_config(&mut configuration);
Ok(configuration)
Ok(transformer.transform(configuration))
}
/// Extract the project root (scope) and [`Settings`] from a given
@ -251,22 +253,22 @@ fn resolve_configuration(
fn resolve_scoped_settings(
pyproject: &Path,
relativity: Relativity,
processor: &dyn ConfigProcessor,
transformer: &dyn ConfigurationTransformer,
) -> Result<(PathBuf, Settings)> {
let configuration = resolve_configuration(pyproject, relativity, processor)?;
let configuration = resolve_configuration(pyproject, relativity, transformer)?;
let project_root = relativity.resolve(pyproject);
let settings = configuration.into_settings(&project_root)?;
Ok((project_root, settings))
}
/// Extract the [`Settings`] from a given `pyproject.toml` and process the
/// configuration with the given [`ConfigProcessor`].
/// configuration with the given [`ConfigurationTransformer`].
pub fn resolve_root_settings(
pyproject: &Path,
relativity: Relativity,
processor: &dyn ConfigProcessor,
transformer: &dyn ConfigurationTransformer,
) -> Result<Settings> {
let (_project_root, settings) = resolve_scoped_settings(pyproject, relativity, processor)?;
let (_project_root, settings) = resolve_scoped_settings(pyproject, relativity, transformer)?;
Ok(settings)
}
@ -274,7 +276,7 @@ pub fn resolve_root_settings(
pub fn python_files_in_path(
paths: &[PathBuf],
pyproject_config: &PyprojectConfig,
processor: &dyn ConfigProcessor,
transformer: &dyn ConfigurationTransformer,
) -> Result<(Vec<Result<DirEntry, ignore::Error>>, Resolver)> {
// Normalize every path (e.g., convert from relative to absolute).
let mut paths: Vec<PathBuf> = paths.iter().map(fs::normalize_path).unique().collect();
@ -288,7 +290,7 @@ pub fn python_files_in_path(
if seen.insert(ancestor) {
if let Some(pyproject) = settings_toml(ancestor)? {
let (root, settings) =
resolve_scoped_settings(&pyproject, Relativity::Parent, processor)?;
resolve_scoped_settings(&pyproject, Relativity::Parent, transformer)?;
resolver.add(root, settings);
}
}
@ -361,7 +363,7 @@ pub fn python_files_in_path(
Ok(Some(pyproject)) => match resolve_scoped_settings(
&pyproject,
Relativity::Parent,
processor,
transformer,
) {
Ok((root, settings)) => {
resolver.write().unwrap().add(root, settings);
@ -420,7 +422,7 @@ pub fn python_files_in_path(
pub fn python_file_at_path(
path: &Path,
pyproject_config: &PyprojectConfig,
processor: &dyn ConfigProcessor,
transformer: &dyn ConfigurationTransformer,
) -> Result<bool> {
if !pyproject_config.settings.force_exclude {
return Ok(true);
@ -435,7 +437,7 @@ pub fn python_file_at_path(
for ancestor in path.ancestors() {
if let Some(pyproject) = settings_toml(ancestor)? {
let (root, settings) =
resolve_scoped_settings(&pyproject, Relativity::Parent, processor)?;
resolve_scoped_settings(&pyproject, Relativity::Parent, transformer)?;
resolver.add(root, settings);
}
}
@ -508,14 +510,17 @@ mod tests {
use crate::pyproject::find_settings_toml;
use crate::resolver::{
is_file_excluded, match_exclusion, python_files_in_path, resolve_root_settings,
ConfigProcessor, PyprojectConfig, PyprojectDiscoveryStrategy, Relativity, Resolver,
ConfigurationTransformer, PyprojectConfig, PyprojectDiscoveryStrategy, Relativity,
Resolver,
};
use crate::tests::test_resource_path;
struct NoOpProcessor;
struct NoOpTransformer;
impl ConfigProcessor for NoOpProcessor {
fn process_config(&self, _config: &mut Configuration) {}
impl ConfigurationTransformer for NoOpTransformer {
fn transform(&self, config: Configuration) -> Configuration {
config
}
}
#[test]
@ -527,7 +532,7 @@ mod tests {
resolve_root_settings(
&find_settings_toml(&package_root)?.unwrap(),
Relativity::Parent,
&NoOpProcessor,
&NoOpTransformer,
)?,
None,
);
@ -571,7 +576,7 @@ mod tests {
let (paths, _) = python_files_in_path(
&[root.to_path_buf()],
&PyprojectConfig::new(PyprojectDiscoveryStrategy::Fixed, Settings::default(), None),
&NoOpProcessor,
&NoOpTransformer,
)?;
let paths = paths
.iter()