From 2e4a95a6c27b466e7a10da02e9ff5fe7f71e4d0d Mon Sep 17 00:00:00 2001 From: Micha Reiser Date: Wed, 20 Sep 2023 13:26:02 +0200 Subject: [PATCH] Move `Settings` and `ResolverSettings` to `ruff_workspace` --- Cargo.lock | 1 + crates/ruff_benchmark/benches/linter.rs | 9 +- crates/ruff_cli/src/cache.rs | 5 +- crates/ruff_cli/src/commands/check.rs | 3 +- crates/ruff_cli/src/diagnostics.rs | 5 +- crates/ruff_cli/src/lib.rs | 3 +- crates/ruff_dev/src/format_dev.rs | 2 +- crates/ruff_linter/src/settings/mod.rs | 108 +-------------------- crates/ruff_linter/src/settings/types.rs | 5 +- crates/ruff_wasm/src/lib.rs | 3 +- crates/ruff_workspace/Cargo.toml | 1 + crates/ruff_workspace/src/configuration.rs | 16 +-- crates/ruff_workspace/src/lib.rs | 3 + crates/ruff_workspace/src/resolver.rs | 4 +- crates/ruff_workspace/src/settings.rs | 101 +++++++++++++++++++ 15 files changed, 143 insertions(+), 126 deletions(-) create mode 100644 crates/ruff_workspace/src/settings.rs diff --git a/Cargo.lock b/Cargo.lock index 414a958cf379de..f7637c4036f2e4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2522,6 +2522,7 @@ dependencies = [ "ignore", "itertools 0.11.0", "log", + "once_cell", "path-absolutize", "pep440_rs", "regex", diff --git a/crates/ruff_benchmark/benches/linter.rs b/crates/ruff_benchmark/benches/linter.rs index 4fbaace240aa6e..b90f5153cb2897 100644 --- a/crates/ruff_benchmark/benches/linter.rs +++ b/crates/ruff_benchmark/benches/linter.rs @@ -4,7 +4,8 @@ use ruff_benchmark::criterion::{ use ruff_benchmark::{TestCase, TestFile, TestFileDownloadError}; use ruff_linter::linter::lint_only; use ruff_linter::settings::rule_table::RuleTable; -use ruff_linter::settings::{flags, LinterSettings, Settings}; +use ruff_linter::settings::types::PythonVersion; +use ruff_linter::settings::{flags, LinterSettings}; use ruff_linter::source_kind::SourceKind; use ruff_linter::{registry::Rule, RuleSelector}; use ruff_python_ast::PySourceType; @@ -85,7 +86,11 @@ fn benchmark_all_rules(criterion: &mut Criterion) { rules.disable(Rule::ShebangMissingExecutableFile); rules.disable(Rule::ShebangNotExecutable); - let settings = LinterSettings::for_rules(rules); + let settings = LinterSettings { + rules, + target_version: PythonVersion::latest(), + ..LinterSettings::default() + }; let group = criterion.benchmark_group("linter/all-rules"); benchmark_linter(group, &settings); diff --git a/crates/ruff_cli/src/cache.rs b/crates/ruff_cli/src/cache.rs index c721bffcf2de78..3a2b851451f6ea 100644 --- a/crates/ruff_cli/src/cache.rs +++ b/crates/ruff_cli/src/cache.rs @@ -14,12 +14,12 @@ use serde::{Deserialize, Serialize}; use ruff_cache::{CacheKey, CacheKeyHasher}; use ruff_diagnostics::{DiagnosticKind, Fix}; use ruff_linter::message::Message; -use ruff_linter::settings::Settings; use ruff_linter::warn_user; use ruff_notebook::NotebookIndex; use ruff_python_ast::imports::ImportMap; use ruff_source_file::SourceFileBuilder; use ruff_text_size::{TextRange, TextSize}; +use ruff_workspace::Settings; use crate::diagnostics::Diagnostics; @@ -347,7 +347,7 @@ mod tests { use itertools::Itertools; use ruff_cache::CACHE_DIR_NAME; - use ruff_linter::settings::{flags, Settings}; + use ruff_linter::settings::flags; use crate::cache::RelativePathBuf; use crate::cache::{self, Cache, FileCache}; @@ -358,6 +358,7 @@ mod tests { use anyhow::Result; use ruff_python_ast::imports::ImportMap; + use ruff_workspace::Settings; use test_case::test_case; #[test_case("../ruff_linter/resources/test/fixtures", "ruff_tests/cache_same_results_ruff_linter"; "ruff_linter_fixtures")] diff --git a/crates/ruff_cli/src/commands/check.rs b/crates/ruff_cli/src/commands/check.rs index 4d0cc43b833ed6..1176477c145542 100644 --- a/crates/ruff_cli/src/commands/check.rs +++ b/crates/ruff_cli/src/commands/check.rs @@ -238,8 +238,9 @@ mod test { use ruff_linter::message::{Emitter, EmitterContext, TextEmitter}; use ruff_linter::registry::Rule; - use ruff_linter::settings::{flags, LinterSettings, Settings}; + use ruff_linter::settings::{flags, LinterSettings}; use ruff_workspace::resolver::{PyprojectConfig, PyprojectDiscoveryStrategy}; + use ruff_workspace::Settings; use crate::args::Overrides; diff --git a/crates/ruff_cli/src/diagnostics.rs b/crates/ruff_cli/src/diagnostics.rs index 59d77ee7e25d7c..13de795a86b8b5 100644 --- a/crates/ruff_cli/src/diagnostics.rs +++ b/crates/ruff_cli/src/diagnostics.rs @@ -21,8 +21,8 @@ use ruff_linter::linter::{lint_fix, lint_only, FixTable, FixerResult, LinterResu use ruff_linter::logging::DisplayParseError; use ruff_linter::message::Message; use ruff_linter::pyproject_toml::lint_pyproject_toml; -use ruff_linter::registry::{AsRule}; -use ruff_linter::settings::{flags, LinterSettings, Settings}; +use ruff_linter::registry::AsRule; +use ruff_linter::settings::{flags, LinterSettings}; use ruff_linter::source_kind::SourceKind; use ruff_linter::{fs, IOError, SyntaxError}; use ruff_macros::CacheKey; @@ -31,6 +31,7 @@ use ruff_python_ast::imports::ImportMap; use ruff_python_ast::{PySourceType, SourceType, TomlSourceType}; use ruff_source_file::{LineIndex, SourceCode, SourceFileBuilder}; use ruff_text_size::{TextRange, TextSize}; +use ruff_workspace::Settings; use crate::cache::Cache; diff --git a/crates/ruff_cli/src/lib.rs b/crates/ruff_cli/src/lib.rs index 83840db4a400a7..cdb8682126839f 100644 --- a/crates/ruff_cli/src/lib.rs +++ b/crates/ruff_cli/src/lib.rs @@ -10,9 +10,10 @@ use log::warn; use notify::{recommended_watcher, RecursiveMode, Watcher}; use ruff_linter::logging::{set_up_logging, LogLevel}; +use ruff_linter::settings::flags; use ruff_linter::settings::types::SerializationFormat; -use ruff_linter::settings::{flags, Settings}; use ruff_linter::{fs, warn_user_once}; +use ruff_workspace::Settings; use crate::args::{Args, CheckCommand, Command, FormatCommand}; use crate::printer::{Flags as PrinterFlags, Printer}; diff --git a/crates/ruff_dev/src/format_dev.rs b/crates/ruff_dev/src/format_dev.rs index 916403041c62e7..19ef98200d54de 100644 --- a/crates/ruff_dev/src/format_dev.rs +++ b/crates/ruff_dev/src/format_dev.rs @@ -60,7 +60,7 @@ fn ruff_check_paths( cli.stdin_filename.as_deref(), )?; // We don't want to format pyproject.toml - pyproject_config.settings.resolver.include = FilePatternSet::try_from_vec(vec![ + pyproject_config.settings.resolver.include = FilePatternSet::try_from_iter([ FilePattern::Builtin("*.py"), FilePattern::Builtin("*.pyi"), ]) diff --git a/crates/ruff_linter/src/settings/mod.rs b/crates/ruff_linter/src/settings/mod.rs index 776add05abe89e..6ced3e3be0608e 100644 --- a/crates/ruff_linter/src/settings/mod.rs +++ b/crates/ruff_linter/src/settings/mod.rs @@ -10,7 +10,6 @@ use globset::{Glob, GlobMatcher}; use once_cell::sync::Lazy; use path_absolutize::path_dedot; use regex::Regex; -use ruff_cache::cache_dir; use rustc_hash::FxHashSet; use crate::codes::RuleCodePrefix; @@ -24,9 +23,7 @@ use crate::rules::{ flake8_tidy_imports, flake8_type_checking, flake8_unused_arguments, isort, mccabe, pep8_naming, pycodestyle, pydocstyle, pyflakes, pylint, pyupgrade, }; -use crate::settings::types::{ - FilePattern, FilePatternSet, PerFileIgnore, PythonVersion, SerializationFormat, -}; +use crate::settings::types::{PerFileIgnore, PythonVersion}; use crate::{codes, RuleSelector}; use super::line_width::{LineLength, TabSize}; @@ -38,69 +35,6 @@ pub mod flags; pub mod rule_table; pub mod types; -pub static EXCLUDE: Lazy> = Lazy::new(|| { - vec![ - FilePattern::Builtin(".bzr"), - FilePattern::Builtin(".direnv"), - FilePattern::Builtin(".eggs"), - FilePattern::Builtin(".git"), - FilePattern::Builtin(".git-rewrite"), - FilePattern::Builtin(".hg"), - FilePattern::Builtin(".ipynb_checkpoints"), - FilePattern::Builtin(".mypy_cache"), - FilePattern::Builtin(".nox"), - FilePattern::Builtin(".pants.d"), - FilePattern::Builtin(".pyenv"), - FilePattern::Builtin(".pytest_cache"), - FilePattern::Builtin(".pytype"), - FilePattern::Builtin(".ruff_cache"), - FilePattern::Builtin(".svn"), - FilePattern::Builtin(".tox"), - FilePattern::Builtin(".venv"), - FilePattern::Builtin(".vscode"), - FilePattern::Builtin("__pypackages__"), - FilePattern::Builtin("_build"), - FilePattern::Builtin("buck-out"), - FilePattern::Builtin("build"), - FilePattern::Builtin("dist"), - FilePattern::Builtin("node_modules"), - FilePattern::Builtin("venv"), - ] -}); - -pub static INCLUDE: Lazy> = Lazy::new(|| { - vec![ - FilePattern::Builtin("*.py"), - FilePattern::Builtin("*.pyi"), - FilePattern::Builtin("**/pyproject.toml"), - ] -}); - -#[derive(Debug, CacheKey)] -pub struct ResolverSettings { - pub exclude: FilePatternSet, - pub extend_exclude: FilePatternSet, - pub force_exclude: bool, - pub include: FilePatternSet, - pub extend_include: FilePatternSet, - pub respect_gitignore: bool, - pub project_root: PathBuf, -} - -impl ResolverSettings { - fn with_project_root(project_root: &Path) -> Self { - Self { - project_root: project_root.to_path_buf(), - exclude: FilePatternSet::try_from_vec(EXCLUDE.clone()).unwrap(), - extend_exclude: FilePatternSet::default(), - extend_include: FilePatternSet::default(), - force_exclude: false, - respect_gitignore: true, - include: FilePatternSet::try_from_vec(INCLUDE.clone()).unwrap(), - } - } -} - #[derive(Debug, CacheKey)] pub struct LinterSettings { pub project_root: PathBuf, @@ -181,7 +115,7 @@ impl LinterSettings { } } - pub fn with_project_root(project_root: &Path) -> Self { + pub fn new(project_root: &Path) -> Self { Self { target_version: PythonVersion::default(), project_root: project_root.to_path_buf(), @@ -246,30 +180,10 @@ impl LinterSettings { impl Default for LinterSettings { fn default() -> Self { - Self::with_project_root(path_dedot::CWD.as_path()) + Self::new(path_dedot::CWD.as_path()) } } -#[derive(Debug, CacheKey)] -#[allow(clippy::struct_excessive_bools)] -pub struct Settings { - #[cache_key(ignore)] - pub cache_dir: PathBuf, - #[cache_key(ignore)] - pub fix: bool, - #[cache_key(ignore)] - pub fix_only: bool, - #[cache_key(ignore)] - pub format: SerializationFormat, - #[cache_key(ignore)] - pub show_fixes: bool, - #[cache_key(ignore)] - pub show_source: bool, - - pub resolver: ResolverSettings, - pub linter: LinterSettings, -} - /// Given a list of patterns, create a `GlobSet`. pub fn resolve_per_file_ignores( per_file_ignores: Vec, @@ -288,19 +202,3 @@ pub fn resolve_per_file_ignores( }) .collect() } - -impl Default for Settings { - fn default() -> Self { - let project_root = path_dedot::CWD.as_path(); - Self { - cache_dir: cache_dir(project_root), - fix: false, - fix_only: false, - format: SerializationFormat::default(), - show_fixes: false, - show_source: false, - linter: LinterSettings::with_project_root(project_root), - resolver: ResolverSettings::with_project_root(project_root), - } - } -} diff --git a/crates/ruff_linter/src/settings/types.rs b/crates/ruff_linter/src/settings/types.rs index 9d3cbe0a00a2d4..2971ca30fced63 100644 --- a/crates/ruff_linter/src/settings/types.rs +++ b/crates/ruff_linter/src/settings/types.rs @@ -152,7 +152,10 @@ pub struct FilePatternSet { } impl FilePatternSet { - pub fn try_from_vec(patterns: Vec) -> Result { + pub fn try_from_iter(patterns: I) -> Result + where + I: IntoIterator, + { let mut builder = GlobSetBuilder::new(); let mut hasher = CacheKeyHasher::new(); diff --git a/crates/ruff_wasm/src/lib.rs b/crates/ruff_wasm/src/lib.rs index bbf82baa781d92..feef6f7a49a576 100644 --- a/crates/ruff_wasm/src/lib.rs +++ b/crates/ruff_wasm/src/lib.rs @@ -11,7 +11,7 @@ use ruff_linter::line_width::{LineLength, TabSize}; use ruff_linter::linter::{check_path, LinterResult}; use ruff_linter::registry::AsRule; use ruff_linter::settings::types::{PreviewMode, PythonVersion}; -use ruff_linter::settings::{flags, Settings, DUMMY_VARIABLE_RGX, PREFIXES}; +use ruff_linter::settings::{flags, DUMMY_VARIABLE_RGX, PREFIXES}; use ruff_linter::source_kind::SourceKind; use ruff_python_ast::{Mod, PySourceType}; use ruff_python_codegen::Stylist; @@ -24,6 +24,7 @@ use ruff_source_file::{Locator, SourceLocation}; use ruff_text_size::Ranged; use ruff_workspace::configuration::Configuration; use ruff_workspace::options::Options; +use ruff_workspace::Settings; #[wasm_bindgen(typescript_custom_section)] const TYPES: &'static str = r#" diff --git a/crates/ruff_workspace/Cargo.toml b/crates/ruff_workspace/Cargo.toml index 3240b491242e9a..27261610d6f9aa 100644 --- a/crates/ruff_workspace/Cargo.toml +++ b/crates/ruff_workspace/Cargo.toml @@ -34,6 +34,7 @@ serde = { workspace = true} shellexpand = { workspace = true } strum = { workspace = true } toml = { workspace = true } +once_cell = { version = "1.18.0", features = [] } [dev-dependencies] tempfile = "3.6.0" diff --git a/crates/ruff_workspace/src/configuration.rs b/crates/ruff_workspace/src/configuration.rs index 24be871ae32c33..3217f835b9cdbe 100644 --- a/crates/ruff_workspace/src/configuration.rs +++ b/crates/ruff_workspace/src/configuration.rs @@ -14,6 +14,7 @@ use crate::options::{ Flake8UnusedArgumentsOptions, IsortOptions, McCabeOptions, Options, Pep8NamingOptions, PyUpgradeOptions, PycodestyleOptions, PydocstyleOptions, PyflakesOptions, PylintOptions, }; +use crate::settings::{ResolverSettings, Settings, EXCLUDE, INCLUDE}; use anyhow::{anyhow, Result}; use glob::{glob, GlobError, Paths, PatternError}; use regex::Regex; @@ -28,8 +29,7 @@ use ruff_linter::settings::types::{ Version, }; use ruff_linter::settings::{ - resolve_per_file_ignores, LinterSettings, ResolverSettings, Settings, - DUMMY_VARIABLE_RGX, EXCLUDE, INCLUDE, PREFIXES, TASK_TAGS, + resolve_per_file_ignores, LinterSettings, DUMMY_VARIABLE_RGX, PREFIXES, TASK_TAGS, }; use ruff_linter::{ fs, warn_user, warn_user_once, warn_user_once_by_id, RuleSelector, RUFF_PKG_VERSION, @@ -137,14 +137,14 @@ impl Configuration { show_source: self.show_source.unwrap_or(false), resolver: ResolverSettings { - exclude: FilePatternSet::try_from_vec( - self.exclude.unwrap_or_else(|| EXCLUDE.clone()), + exclude: FilePatternSet::try_from_iter( + self.exclude.unwrap_or_else(|| EXCLUDE.to_vec()), )?, - extend_exclude: FilePatternSet::try_from_vec(self.extend_exclude)?, - extend_include: FilePatternSet::try_from_vec(self.extend_include)?, + extend_exclude: FilePatternSet::try_from_iter(self.extend_exclude)?, + extend_include: FilePatternSet::try_from_iter(self.extend_include)?, force_exclude: self.force_exclude.unwrap_or(false), - include: FilePatternSet::try_from_vec( - self.include.unwrap_or_else(|| INCLUDE.clone()), + include: FilePatternSet::try_from_iter( + self.include.unwrap_or_else(|| INCLUDE.to_vec()), )?, respect_gitignore: self.respect_gitignore.unwrap_or(true), project_root: project_root.to_path_buf(), diff --git a/crates/ruff_workspace/src/lib.rs b/crates/ruff_workspace/src/lib.rs index cc464ffd496e42..a18e151a3538da 100644 --- a/crates/ruff_workspace/src/lib.rs +++ b/crates/ruff_workspace/src/lib.rs @@ -4,6 +4,9 @@ pub mod pyproject; pub mod resolver; pub mod options_base; +mod settings; + +pub use settings::Settings; #[cfg(test)] mod tests { diff --git a/crates/ruff_workspace/src/resolver.rs b/crates/ruff_workspace/src/resolver.rs index ad44d1edf65bc7..04c8ad827f4990 100644 --- a/crates/ruff_workspace/src/resolver.rs +++ b/crates/ruff_workspace/src/resolver.rs @@ -15,11 +15,11 @@ use rustc_hash::{FxHashMap, FxHashSet}; use ruff_linter::fs; use ruff_linter::packaging::is_package; -use ruff_linter::settings::Settings; use crate::configuration::Configuration; use crate::pyproject; use crate::pyproject::settings_toml; +use crate::settings::Settings; /// The configuration information from a `pyproject.toml` file. pub struct PyprojectConfig { @@ -502,7 +502,6 @@ mod tests { use tempfile::TempDir; use ruff_linter::settings::types::FilePattern; - use ruff_linter::settings::Settings; use crate::configuration::Configuration; use crate::pyproject::find_settings_toml; @@ -510,6 +509,7 @@ mod tests { is_file_excluded, match_exclusion, python_files_in_path, resolve_root_settings, ConfigProcessor, PyprojectConfig, PyprojectDiscoveryStrategy, Relativity, Resolver, }; + use crate::settings::Settings; use crate::tests::test_resource_path; struct NoOpProcessor; diff --git a/crates/ruff_workspace/src/settings.rs b/crates/ruff_workspace/src/settings.rs new file mode 100644 index 00000000000000..be2e56d698dc5c --- /dev/null +++ b/crates/ruff_workspace/src/settings.rs @@ -0,0 +1,101 @@ +use path_absolutize::path_dedot; +use ruff_cache::cache_dir; +use ruff_linter::settings::types::{FilePattern, FilePatternSet, SerializationFormat}; +use ruff_linter::settings::LinterSettings; +use ruff_macros::CacheKey; +use std::path::{Path, PathBuf}; + +#[derive(Debug, CacheKey)] +#[allow(clippy::struct_excessive_bools)] +pub struct Settings { + #[cache_key(ignore)] + pub cache_dir: PathBuf, + #[cache_key(ignore)] + pub fix: bool, + #[cache_key(ignore)] + pub fix_only: bool, + #[cache_key(ignore)] + pub format: SerializationFormat, + #[cache_key(ignore)] + pub show_fixes: bool, + #[cache_key(ignore)] + pub show_source: bool, + + pub resolver: ResolverSettings, + pub linter: LinterSettings, +} + +impl Default for Settings { + fn default() -> Self { + let project_root = path_dedot::CWD.as_path(); + Self { + cache_dir: cache_dir(project_root), + fix: false, + fix_only: false, + format: SerializationFormat::default(), + show_fixes: false, + show_source: false, + linter: LinterSettings::new(project_root), + resolver: ResolverSettings::new(project_root), + } + } +} + +#[derive(Debug, CacheKey)] +pub struct ResolverSettings { + pub exclude: FilePatternSet, + pub extend_exclude: FilePatternSet, + pub force_exclude: bool, + pub include: FilePatternSet, + pub extend_include: FilePatternSet, + pub respect_gitignore: bool, + pub project_root: PathBuf, +} + +pub(crate) static EXCLUDE: &[FilePattern] = &[ + FilePattern::Builtin(".bzr"), + FilePattern::Builtin(".direnv"), + FilePattern::Builtin(".eggs"), + FilePattern::Builtin(".git"), + FilePattern::Builtin(".git-rewrite"), + FilePattern::Builtin(".hg"), + FilePattern::Builtin(".ipynb_checkpoints"), + FilePattern::Builtin(".mypy_cache"), + FilePattern::Builtin(".nox"), + FilePattern::Builtin(".pants.d"), + FilePattern::Builtin(".pyenv"), + FilePattern::Builtin(".pytest_cache"), + FilePattern::Builtin(".pytype"), + FilePattern::Builtin(".ruff_cache"), + FilePattern::Builtin(".svn"), + FilePattern::Builtin(".tox"), + FilePattern::Builtin(".venv"), + FilePattern::Builtin(".vscode"), + FilePattern::Builtin("__pypackages__"), + FilePattern::Builtin("_build"), + FilePattern::Builtin("buck-out"), + FilePattern::Builtin("build"), + FilePattern::Builtin("dist"), + FilePattern::Builtin("node_modules"), + FilePattern::Builtin("venv"), +]; + +pub(crate) static INCLUDE: &[FilePattern] = &[ + FilePattern::Builtin("*.py"), + FilePattern::Builtin("*.pyi"), + FilePattern::Builtin("**/pyproject.toml"), +]; + +impl ResolverSettings { + fn new(project_root: &Path) -> Self { + Self { + project_root: project_root.to_path_buf(), + exclude: FilePatternSet::try_from_iter(EXCLUDE.iter().cloned()).unwrap(), + extend_exclude: FilePatternSet::default(), + extend_include: FilePatternSet::default(), + force_exclude: false, + respect_gitignore: true, + include: FilePatternSet::try_from_iter(INCLUDE.iter().cloned()).unwrap(), + } + } +}