Skip to content

Commit

Permalink
Change Resolver to store Settings instead of AllSettings
Browse files Browse the repository at this point in the history
  • Loading branch information
MichaReiser committed Sep 19, 2023
1 parent 297ec2c commit 5b14236
Show file tree
Hide file tree
Showing 9 changed files with 113 additions and 65 deletions.
15 changes: 11 additions & 4 deletions crates/ruff/src/settings/defaults.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
use std::collections::HashSet;

use once_cell::sync::Lazy;
use path_absolutize::path_dedot;
use regex::Regex;
use rustc_hash::FxHashSet;
use std::collections::HashSet;

use super::types::{FilePattern, PreviewMode, PythonVersion};
use super::Settings;
use ruff_cache::cache_dir;

use crate::codes::{self, RuleCodePrefix};
use crate::line_width::{LineLength, TabSize};
use crate::registry::Linter;
Expand All @@ -19,6 +20,9 @@ use crate::rules::{
};
use crate::settings::types::FilePatternSet;

use super::types::{FilePattern, PreviewMode, PythonVersion};
use super::Settings;

pub const PREFIXES: &[RuleSelector] = &[
RuleSelector::Prefix {
prefix: RuleCodePrefix::Pycodestyle(codes::Pycodestyle::E),
Expand Down Expand Up @@ -72,7 +76,10 @@ pub static INCLUDE: Lazy<Vec<FilePattern>> = Lazy::new(|| {

impl Default for Settings {
fn default() -> Self {
let project_root = path_dedot::CWD.clone();
Self {
cache_dir: cache_dir(&project_root),

rules: PREFIXES
.iter()
.flat_map(|selector| selector.rules(PreviewMode::default()))
Expand All @@ -92,7 +99,7 @@ impl Default for Settings {
namespace_packages: vec![],
preview: PreviewMode::default(),
per_file_ignores: vec![],
project_root: path_dedot::CWD.clone(),
project_root,
respect_gitignore: true,
src: vec![path_dedot::CWD.clone()],
tab_size: TabSize::default(),
Expand Down
4 changes: 3 additions & 1 deletion crates/ruff/src/settings/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@ pub struct AllSettings {
#[allow(clippy::struct_excessive_bools)]
/// Settings that are not used by this library and only here so that `ruff_cli` can use them.
pub struct CliSettings {
pub cache_dir: PathBuf,
pub fix: bool,
pub fix_only: bool,
pub format: SerializationFormat,
Expand All @@ -52,6 +51,9 @@ pub struct CliSettings {
#[derive(Debug, CacheKey)]
#[allow(clippy::struct_excessive_bools)]
pub struct Settings {
#[cache_key(ignore)]
pub cache_dir: PathBuf,

pub rules: RuleTable,
pub per_file_ignores: Vec<(GlobMatcher, GlobMatcher, RuleSet)>,

Expand Down
39 changes: 18 additions & 21 deletions crates/ruff_cli/src/cache.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,21 +59,18 @@ pub(crate) struct Cache {
impl Cache {
/// Open or create a new cache.
///
/// `cache_dir` is considered the root directory of the cache, which can be
/// local to the project, global or otherwise set by the user.
///
/// `package_root` is the path to root of the package that is contained
/// within this cache and must be canonicalized (to avoid considering `./`
/// and `../project` being different).
///
/// Finally `settings` is used to ensure we don't open a cache for different
/// settings.
pub(crate) fn open(cache_dir: &Path, package_root: PathBuf, settings: &Settings) -> Cache {
/// settings and stores the `cache_dir` in which the cache should be opened.
pub(crate) fn open(package_root: PathBuf, settings: &Settings) -> Cache {
debug_assert!(package_root.is_absolute(), "package root not canonicalized");

let mut buf = itoa::Buffer::new();
let key = Path::new(buf.format(cache_key(&package_root, settings)));
let path = PathBuf::from_iter([cache_dir, Path::new("content"), key]);
let path = PathBuf::from_iter([&settings.cache_dir, Path::new("content"), key]);

let file = match File::open(&path) {
Ok(file) => file,
Expand Down Expand Up @@ -349,7 +346,7 @@ mod tests {
use std::time::SystemTime;

use itertools::Itertools;
use ruff::settings::{flags, AllSettings, Settings};
use ruff::settings::{flags, Settings};
use ruff_cache::CACHE_DIR_NAME;

use crate::cache::RelativePathBuf;
Expand All @@ -371,10 +368,13 @@ mod tests {
let _ = fs::remove_dir_all(&cache_dir);
cache::init(&cache_dir).unwrap();

let settings = Settings::default();
let settings = Settings {
cache_dir,
..Settings::default()
};

let package_root = fs::canonicalize(package_root).unwrap();
let cache = Cache::open(&cache_dir, package_root.clone(), &settings);
let cache = Cache::open(package_root.clone(), &settings);
assert_eq!(cache.new_files.lock().unwrap().len(), 0);

let mut paths = Vec::new();
Expand Down Expand Up @@ -426,7 +426,7 @@ mod tests {

cache.store().unwrap();

let cache = Cache::open(&cache_dir, package_root.clone(), &settings);
let cache = Cache::open(package_root.clone(), &settings);
assert_ne!(cache.package.files.len(), 0);

parse_errors.sort();
Expand Down Expand Up @@ -651,9 +651,8 @@ mod tests {
}

struct TestCache {
cache_dir: PathBuf,
package_root: PathBuf,
settings: AllSettings,
settings: Settings,
}

impl TestCache {
Expand All @@ -672,10 +671,12 @@ mod tests {
cache::init(&cache_dir).unwrap();
fs::create_dir(package_root.clone()).unwrap();

let settings = AllSettings::default();
let settings = Settings {
cache_dir,
..Settings::default()
};

Self {
cache_dir,
package_root,
settings,
}
Expand All @@ -695,11 +696,7 @@ mod tests {
}

fn open(&self) -> Cache {
Cache::open(
&self.cache_dir,
self.package_root.clone(),
&self.settings.lib,
)
Cache::open(self.package_root.clone(), &self.settings)
}

fn lint_file_with_cache(
Expand All @@ -710,7 +707,7 @@ mod tests {
lint_path(
&self.package_root.join(path),
Some(&self.package_root),
&self.settings.lib,
&self.settings,
Some(cache),
flags::Noqa::Enabled,
flags::FixMode::Generate,
Expand All @@ -720,7 +717,7 @@ mod tests {

impl Drop for TestCache {
fn drop(&mut self) {
let _ = fs::remove_dir_all(&self.cache_dir);
let _ = fs::remove_dir_all(&self.settings.cache_dir);
}
}
}
14 changes: 5 additions & 9 deletions crates/ruff_cli/src/commands/check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,13 +58,13 @@ pub(crate) fn check(

match pyproject_config.strategy {
PyprojectDiscoveryStrategy::Fixed => {
init_cache(&pyproject_config.settings.cli.cache_dir);
init_cache(&pyproject_config.settings.lib.cache_dir);
}
PyprojectDiscoveryStrategy::Hierarchical => {
for settings in
std::iter::once(&pyproject_config.settings).chain(resolver.settings())
std::iter::once(&pyproject_config.settings.lib).chain(resolver.settings())
{
init_cache(&settings.cli.cache_dir);
init_cache(&settings.cache_dir);
}
}
}
Expand All @@ -88,12 +88,8 @@ pub(crate) fn check(
.unique()
.par_bridge()
.map(|cache_root| {
let settings = resolver.resolve_all(cache_root, pyproject_config);
let cache = Cache::open(
&settings.cli.cache_dir,
cache_root.to_path_buf(),
&settings.lib,
);
let settings = resolver.resolve(cache_root, pyproject_config);
let cache = Cache::open(cache_root.to_path_buf(), settings);
(cache_root, cache)
})
.collect::<HashMap<&Path, Cache>>()
Expand Down
1 change: 0 additions & 1 deletion crates/ruff_cli/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,6 @@ pub fn check(args: CheckCommand, log_level: LogLevel) -> Result<ExitStatus> {
format,
show_fixes,
show_source,
..
} = pyproject_config.settings.cli;

// Autofix rules are as follows:
Expand Down
60 changes: 55 additions & 5 deletions crates/ruff_macros/src/cache_key.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
use proc_macro2::TokenStream;
use proc_macro2::{Ident, TokenStream};
use quote::{format_ident, quote};
use syn::parse::{Parse, ParseStream};
use syn::spanned::Spanned;
use syn::{Data, DeriveInput, Error, Fields};
use syn::{Data, DeriveInput, Error, Field, Fields, Token};

pub(crate) fn derive_cache_key(item: &DeriveInput) -> syn::Result<TokenStream> {
let fields = match &item.data {
Expand Down Expand Up @@ -65,7 +66,15 @@ pub(crate) fn derive_cache_key(item: &DeriveInput) -> syn::Result<TokenStream> {
}

Data::Struct(item_struct) => {
let fields = item_struct.fields.iter().enumerate().map(|(i, field)| {
let mut fields = Vec::with_capacity(item_struct.fields.len());

for (i, field) in item_struct.fields.iter().enumerate() {
if let Some(cache_field_attribute) = cache_key_field_attribute(field)? {
if cache_field_attribute.ignore {
continue;
}
}

let field_attr = match &field.ident {
Some(ident) => quote!(self.#ident),
None => {
Expand All @@ -74,8 +83,8 @@ pub(crate) fn derive_cache_key(item: &DeriveInput) -> syn::Result<TokenStream> {
}
};

quote!(#field_attr.cache_key(key);)
});
fields.push(quote!(#field_attr.cache_key(key);));
}

quote! {#(#fields)*}
}
Expand All @@ -101,3 +110,44 @@ pub(crate) fn derive_cache_key(item: &DeriveInput) -> syn::Result<TokenStream> {
}
))
}

fn cache_key_field_attribute(field: &Field) -> syn::Result<Option<CacheKeyFieldAttributes>> {
if let Some(attribute) = field
.attrs
.iter()
.find(|attribute| attribute.path().is_ident("cache_key"))
{
attribute.parse_args::<CacheKeyFieldAttributes>().map(Some)
} else {
Ok(None)
}
}

#[derive(Debug, Default)]
struct CacheKeyFieldAttributes {
ignore: bool,
}

impl Parse for CacheKeyFieldAttributes {
fn parse(input: ParseStream) -> syn::Result<Self> {
let mut attributes = CacheKeyFieldAttributes::default();

let args = input.parse_terminated(Ident::parse, Token![,])?;

for arg in args {
match arg.to_string().as_str() {
"ignore" => {
attributes.ignore = true;
}
name => {
return Err(Error::new(
arg.span(),
format!("Unknown `cache_field` argument {name}"),
))
}
}
}

Ok(attributes)
}
}
6 changes: 5 additions & 1 deletion crates/ruff_macros/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,11 @@ pub fn derive_combine_options(input: TokenStream) -> TokenStream {
.into()
}

#[proc_macro_derive(CacheKey)]
/// Generates a [`CacheKey`] implementation for the attributed type.
///
/// Struct fields can be attributed with the [`cache_key`] field-attribute that supports:
/// * `ignore`: Ignore the attributed field in the cache key
#[proc_macro_derive(CacheKey, attributes(cache_key))]
pub fn cache_key(input: TokenStream) -> TokenStream {
let item = parse_macro_input!(input as DeriveInput);

Expand Down
9 changes: 5 additions & 4 deletions crates/ruff_workspace/src/configuration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -109,10 +109,6 @@ impl Configuration {
pub fn into_all_settings(self, project_root: &Path) -> Result<AllSettings> {
Ok(AllSettings {
cli: CliSettings {
cache_dir: self
.cache_dir
.clone()
.unwrap_or_else(|| cache_dir(project_root)),
fix: self.fix.unwrap_or(false),
fix_only: self.fix_only.unwrap_or(false),
format: self.format.unwrap_or_default(),
Expand All @@ -135,6 +131,11 @@ impl Configuration {
}

Ok(Settings {
cache_dir: self
.cache_dir
.clone()
.unwrap_or_else(|| cache_dir(project_root)),

rules: self.as_rule_table(),
allowed_confusables: self
.allowed_confusables
Expand Down
Loading

0 comments on commit 5b14236

Please sign in to comment.