Include file permissions in cache key (#3104)

This commit is contained in:
Charlie Marsh 2023-02-21 18:20:06 -05:00 committed by GitHub
parent fd638a2e54
commit 18800c6884
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 17 additions and 27 deletions

View file

@ -11,23 +11,18 @@ use path_absolutize::Absolutize;
use ruff::message::Message; use ruff::message::Message;
use ruff::settings::{flags, AllSettings, Settings}; use ruff::settings::{flags, AllSettings, Settings};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
#[cfg(unix)]
use std::os::unix::fs::PermissionsExt;
const CARGO_PKG_VERSION: &str = env!("CARGO_PKG_VERSION"); const CARGO_PKG_VERSION: &str = env!("CARGO_PKG_VERSION");
#[derive(Serialize, Deserialize)]
struct CacheMetadata {
mtime: i64,
}
#[derive(Serialize)] #[derive(Serialize)]
struct CheckResultRef<'a> { struct CheckResultRef<'a> {
metadata: &'a CacheMetadata,
messages: &'a [Message], messages: &'a [Message],
} }
#[derive(Deserialize)] #[derive(Deserialize)]
struct CheckResult { struct CheckResult {
metadata: CacheMetadata,
messages: Vec<Message>, messages: Vec<Message>,
} }
@ -38,6 +33,7 @@ fn content_dir() -> &'static Path {
fn cache_key<P: AsRef<Path>>( fn cache_key<P: AsRef<Path>>(
path: P, path: P,
package: Option<&P>, package: Option<&P>,
metadata: &fs::Metadata,
settings: &Settings, settings: &Settings,
autofix: flags::Autofix, autofix: flags::Autofix,
) -> u64 { ) -> u64 {
@ -48,6 +44,9 @@ fn cache_key<P: AsRef<Path>>(
.as_ref() .as_ref()
.map(|path| path.as_ref().absolutize().unwrap()) .map(|path| path.as_ref().absolutize().unwrap())
.hash(&mut hasher); .hash(&mut hasher);
FileTime::from_last_modification_time(metadata).hash(&mut hasher);
#[cfg(unix)]
metadata.permissions().mode().hash(&mut hasher);
settings.hash(&mut hasher); settings.hash(&mut hasher);
autofix.hash(&mut hasher); autofix.hash(&mut hasher);
hasher.finish() hasher.finish()
@ -99,23 +98,16 @@ pub fn get<P: AsRef<Path>>(
) -> Option<Vec<Message>> { ) -> Option<Vec<Message>> {
let encoded = read_sync( let encoded = read_sync(
&settings.cli.cache_dir, &settings.cli.cache_dir,
cache_key(path, package, &settings.lib, autofix), cache_key(path, package, metadata, &settings.lib, autofix),
) )
.ok()?; .ok()?;
let (mtime, messages) = match bincode::deserialize::<CheckResult>(&encoded[..]) { match bincode::deserialize::<CheckResult>(&encoded[..]) {
Ok(CheckResult { Ok(CheckResult { messages }) => Some(messages),
metadata: CacheMetadata { mtime },
messages,
}) => (mtime, messages),
Err(e) => { Err(e) => {
error!("Failed to deserialize encoded cache entry: {e:?}"); error!("Failed to deserialize encoded cache entry: {e:?}");
return None; None
} }
};
if FileTime::from_last_modification_time(metadata).unix_seconds() != mtime {
return None;
} }
Some(messages)
} }
/// Set a value in the cache. /// Set a value in the cache.
@ -127,15 +119,10 @@ pub fn set<P: AsRef<Path>>(
autofix: flags::Autofix, autofix: flags::Autofix,
messages: &[Message], messages: &[Message],
) { ) {
let check_result = CheckResultRef { let check_result = CheckResultRef { messages };
metadata: &CacheMetadata {
mtime: FileTime::from_last_modification_time(metadata).unix_seconds(),
},
messages,
};
if let Err(e) = write_sync( if let Err(e) = write_sync(
&settings.cli.cache_dir, &settings.cli.cache_dir,
cache_key(path, package, &settings.lib, autofix), cache_key(path, package, metadata, &settings.lib, autofix),
&bincode::serialize(&check_result).unwrap(), &bincode::serialize(&check_result).unwrap(),
) { ) {
error!("Failed to write to cache: {e:?}"); error!("Failed to write to cache: {e:?}");
@ -146,11 +133,12 @@ pub fn set<P: AsRef<Path>>(
pub fn del<P: AsRef<Path>>( pub fn del<P: AsRef<Path>>(
path: P, path: P,
package: Option<&P>, package: Option<&P>,
metadata: &fs::Metadata,
settings: &AllSettings, settings: &AllSettings,
autofix: flags::Autofix, autofix: flags::Autofix,
) { ) {
drop(del_sync( drop(del_sync(
&settings.cli.cache_dir, &settings.cli.cache_dir,
cache_key(path, package, &settings.lib, autofix), cache_key(path, package, metadata, &settings.lib, autofix),
)); ));
} }

View file

@ -129,7 +129,9 @@ pub fn lint_path(
); );
// Purge the cache. // Purge the cache.
cache::del(path, package.as_ref(), settings, autofix.into()); if let Some(metadata) = metadata {
cache::del(path, package.as_ref(), &metadata, settings, autofix.into());
}
} else { } else {
// Re-populate the cache. // Re-populate the cache.
if let Some(metadata) = metadata { if let Some(metadata) = metadata {