Add settings hash to cache (#20)

This commit is contained in:
Charlie Marsh 2022-08-20 13:37:21 -04:00 committed by GitHub
parent 4c62e1e22e
commit b63d66fc3e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 48 additions and 31 deletions

View file

@ -95,7 +95,7 @@ fn main() -> Result<()> {
set_up_logging(cli.verbose)?; set_up_logging(cli.verbose)?;
// TODO(charlie): Avoid this cast. // TODO(charlie): Can we avoid this cast?
let paths: Vec<&Path> = cli.files.iter().map(PathBuf::as_path).collect(); let paths: Vec<&Path> = cli.files.iter().map(PathBuf::as_path).collect();
let settings = Settings::from_paths(paths)?; let settings = Settings::from_paths(paths)?;

View file

@ -1,3 +1,5 @@
use std::collections::hash_map::DefaultHasher;
use std::hash::{Hash, Hasher};
use std::os::unix::fs::MetadataExt; use std::os::unix::fs::MetadataExt;
use std::path::Path; use std::path::Path;
@ -6,6 +8,7 @@ use log::error;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use crate::message::Message; use crate::message::Message;
use crate::settings::Settings;
const VERSION: &str = env!("CARGO_PKG_VERSION"); const VERSION: &str = env!("CARGO_PKG_VERSION");
@ -67,20 +70,23 @@ fn cache_dir() -> &'static str {
"./.cache" "./.cache"
} }
fn cache_key(path: &Path) -> String { fn cache_key(path: &Path, settings: &Settings) -> String {
let mut hasher = DefaultHasher::new();
settings.hash(&mut hasher);
format!( format!(
"{}@{}", "{}@{}@{}",
path.canonicalize().unwrap().to_string_lossy(), path.canonicalize().unwrap().to_string_lossy(),
VERSION VERSION,
hasher.finish()
) )
} }
pub fn get(path: &Path, mode: &Mode) -> Option<Vec<Message>> { pub fn get(path: &Path, settings: &Settings, mode: &Mode) -> Option<Vec<Message>> {
if !mode.allow_read() { if !mode.allow_read() {
return None; return None;
}; };
match cacache::read_sync(cache_dir(), cache_key(path)) { match cacache::read_sync(cache_dir(), cache_key(path, settings)) {
Ok(encoded) => match path.metadata() { Ok(encoded) => match path.metadata() {
Ok(m) => match bincode::deserialize::<CheckResult>(&encoded[..]) { Ok(m) => match bincode::deserialize::<CheckResult>(&encoded[..]) {
Ok(CheckResult { metadata, messages }) => { Ok(CheckResult { metadata, messages }) => {
@ -98,7 +104,7 @@ pub fn get(path: &Path, mode: &Mode) -> Option<Vec<Message>> {
None None
} }
pub fn set(path: &Path, messages: &[Message], mode: &Mode) { pub fn set(path: &Path, settings: &Settings, messages: &[Message], mode: &Mode) {
if !mode.allow_write() { if !mode.allow_write() {
return; return;
}; };
@ -113,7 +119,7 @@ pub fn set(path: &Path, messages: &[Message], mode: &Mode) {
}; };
if let Err(e) = cacache::write_sync( if let Err(e) = cacache::write_sync(
cache_dir(), cache_dir(),
cache_key(path), cache_key(path, settings),
bincode::serialize(&check_result).unwrap(), bincode::serialize(&check_result).unwrap(),
) { ) {
error!("Failed to write to cache: {e:?}") error!("Failed to write to cache: {e:?}")

View file

@ -1,4 +1,4 @@
use std::collections::HashSet; use std::collections::BTreeSet;
use rustpython_parser::ast::{Arg, Arguments, Expr, ExprKind, Stmt, StmtKind, Suite}; use rustpython_parser::ast::{Arg, Arguments, Expr, ExprKind, Stmt, StmtKind, Suite};
@ -99,7 +99,7 @@ impl Visitor for Checker<'_> {
} }
// Search for duplicates. // Search for duplicates.
let mut idents: HashSet<String> = HashSet::new(); let mut idents: BTreeSet<String> = BTreeSet::new();
for arg in all_arguments { for arg in all_arguments {
let ident = &arg.node.arg; let ident = &arg.node.arg;
if idents.contains(ident) { if idents.contains(ident) {
@ -130,8 +130,9 @@ pub fn check_ast(python_ast: &Suite, settings: &Settings) -> Vec<Check> {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use std::collections::BTreeSet;
use rustpython_parser::ast::{Alias, Location, Stmt, StmtKind}; use rustpython_parser::ast::{Alias, Location, Stmt, StmtKind};
use std::collections::HashSet;
use crate::check_ast::Checker; use crate::check_ast::Checker;
use crate::checks::CheckKind::ImportStarUsage; use crate::checks::CheckKind::ImportStarUsage;
@ -144,7 +145,7 @@ mod tests {
let settings = Settings { let settings = Settings {
line_length: 88, line_length: 88,
exclude: vec![], exclude: vec![],
select: HashSet::from([CheckCode::F403]), select: BTreeSet::from([CheckCode::F403]),
}; };
let mut checker = Checker::new(&settings); let mut checker = Checker::new(&settings);
checker.visit_stmt(&Stmt { checker.visit_stmt(&Stmt {

View file

@ -1,7 +1,7 @@
use rustpython_parser::ast::Location; use rustpython_parser::ast::Location;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
#[derive(Debug, PartialEq, Eq, Serialize, Deserialize, Hash)] #[derive(Debug, PartialEq, Eq, Serialize, Deserialize, Hash, PartialOrd, Ord)]
pub enum CheckCode { pub enum CheckCode {
F831, F831,
F541, F541,

View file

@ -13,7 +13,7 @@ use crate::{cache, fs};
pub fn check_path(path: &Path, settings: &Settings, mode: &cache::Mode) -> Result<Vec<Message>> { pub fn check_path(path: &Path, settings: &Settings, mode: &cache::Mode) -> Result<Vec<Message>> {
// Check the cache. // Check the cache.
if let Some(messages) = cache::get(path, mode) { if let Some(messages) = cache::get(path, settings, mode) {
debug!("Cache hit for: {}", path.to_string_lossy()); debug!("Cache hit for: {}", path.to_string_lossy());
return Ok(messages); return Ok(messages);
} }
@ -53,14 +53,14 @@ pub fn check_path(path: &Path, settings: &Settings, mode: &cache::Mode) -> Resul
}) })
.filter(|message| !message.is_inline_ignored()) .filter(|message| !message.is_inline_ignored())
.collect(); .collect();
cache::set(path, &messages, mode); cache::set(path, settings, &messages, mode);
Ok(messages) Ok(messages)
} }
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use std::collections::HashSet; use std::collections::BTreeSet;
use std::path::Path; use std::path::Path;
use anyhow::Result; use anyhow::Result;
@ -81,7 +81,7 @@ mod tests {
&settings::Settings { &settings::Settings {
line_length: 88, line_length: 88,
exclude: vec![], exclude: vec![],
select: HashSet::from([CheckCode::F831]), select: BTreeSet::from([CheckCode::F831]),
}, },
&cache::Mode::None, &cache::Mode::None,
)?; )?;
@ -117,7 +117,7 @@ mod tests {
&settings::Settings { &settings::Settings {
line_length: 88, line_length: 88,
exclude: vec![], exclude: vec![],
select: HashSet::from([CheckCode::F541]), select: BTreeSet::from([CheckCode::F541]),
}, },
&cache::Mode::None, &cache::Mode::None,
)?; )?;
@ -153,7 +153,7 @@ mod tests {
&settings::Settings { &settings::Settings {
line_length: 88, line_length: 88,
exclude: vec![], exclude: vec![],
select: HashSet::from([CheckCode::F634]), select: BTreeSet::from([CheckCode::F634]),
}, },
&cache::Mode::None, &cache::Mode::None,
)?; )?;
@ -184,7 +184,7 @@ mod tests {
&settings::Settings { &settings::Settings {
line_length: 88, line_length: 88,
exclude: vec![], exclude: vec![],
select: HashSet::from([CheckCode::F403]), select: BTreeSet::from([CheckCode::F403]),
}, },
&cache::Mode::None, &cache::Mode::None,
)?; )?;
@ -215,7 +215,7 @@ mod tests {
&settings::Settings { &settings::Settings {
line_length: 88, line_length: 88,
exclude: vec![], exclude: vec![],
select: HashSet::from([CheckCode::E501]), select: BTreeSet::from([CheckCode::E501]),
}, },
&cache::Mode::None, &cache::Mode::None,
)?; )?;

View file

@ -1,12 +1,12 @@
use std::collections::HashSet; use std::collections::BTreeSet;
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
use crate::checks::CheckCode;
use anyhow::Result; use anyhow::Result;
use common_path::common_path_all; use common_path::common_path_all;
use log::debug; use log::debug;
use serde::Deserialize; use serde::Deserialize;
use crate::checks::CheckCode;
use crate::fs; use crate::fs;
pub fn load_config<'a>(paths: impl IntoIterator<Item = &'a Path>) -> Result<(PathBuf, Config)> { pub fn load_config<'a>(paths: impl IntoIterator<Item = &'a Path>) -> Result<(PathBuf, Config)> {
@ -32,7 +32,7 @@ pub fn load_config<'a>(paths: impl IntoIterator<Item = &'a Path>) -> Result<(Pat
pub struct Config { pub struct Config {
pub line_length: Option<usize>, pub line_length: Option<usize>,
pub exclude: Option<Vec<PathBuf>>, pub exclude: Option<Vec<PathBuf>>,
pub select: Option<HashSet<CheckCode>>, pub select: Option<BTreeSet<CheckCode>>,
} }
#[derive(Debug, PartialEq, Eq, Deserialize)] #[derive(Debug, PartialEq, Eq, Deserialize)]
@ -85,12 +85,12 @@ fn find_project_root<'a>(sources: impl IntoIterator<Item = &'a Path>) -> Option<
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use std::collections::HashSet; use std::collections::BTreeSet;
use std::path::Path; use std::path::Path;
use crate::checks::CheckCode;
use anyhow::Result; use anyhow::Result;
use crate::checks::CheckCode;
use crate::pyproject::{ use crate::pyproject::{
find_project_root, find_pyproject_toml, parse_pyproject_toml, Config, PyProject, Tools, find_project_root, find_pyproject_toml, parse_pyproject_toml, Config, PyProject, Tools,
}; };
@ -173,7 +173,7 @@ select = ["E501"]
linter: Some(Config { linter: Some(Config {
line_length: None, line_length: None,
exclude: None, exclude: None,
select: Some(HashSet::from([CheckCode::E501])), select: Some(BTreeSet::from([CheckCode::E501])),
}) })
}) })
); );

View file

@ -1,15 +1,25 @@
use std::collections::HashSet; use std::collections::BTreeSet;
use std::hash::{Hash, Hasher};
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
use crate::checks::CheckCode;
use anyhow::Result; use anyhow::Result;
use crate::checks::CheckCode;
use crate::pyproject::load_config; use crate::pyproject::load_config;
pub struct Settings { pub struct Settings {
pub line_length: usize, pub line_length: usize,
pub exclude: Vec<PathBuf>, pub exclude: Vec<PathBuf>,
pub select: HashSet<CheckCode>, pub select: BTreeSet<CheckCode>,
}
impl Hash for Settings {
fn hash<H: Hasher>(&self, state: &mut H) {
self.line_length.hash(state);
for value in self.select.iter() {
value.hash(state);
}
}
} }
impl Settings { impl Settings {
@ -30,7 +40,7 @@ impl Settings {
}) })
.collect(), .collect(),
select: config.select.unwrap_or_else(|| { select: config.select.unwrap_or_else(|| {
HashSet::from([ BTreeSet::from([
CheckCode::F831, CheckCode::F831,
CheckCode::F541, CheckCode::F541,
CheckCode::F634, CheckCode::F634,