From 944ff6c685d19baf8f58d92a9accdd1b95ba493c Mon Sep 17 00:00:00 2001 From: konsti Date: Sun, 2 Nov 2025 19:52:07 +0100 Subject: [PATCH] Log most recently modified file for cache-keys (#16338) For https://github.com/astral-sh/uv/issues/16336. We previously weren't telling the user which file is responsible for rebuilding. --------- Co-authored-by: Charlie Marsh --- Cargo.lock | 1 + crates/uv-cache-info/Cargo.toml | 2 ++ crates/uv-cache-info/src/cache_info.rs | 31 ++++++++++++++++++++------ 3 files changed, 27 insertions(+), 7 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 9be30d92c..d4d285974 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5504,6 +5504,7 @@ dependencies = [ "thiserror 2.0.17", "toml", "tracing", + "uv-fs", "walkdir", ] diff --git a/crates/uv-cache-info/Cargo.toml b/crates/uv-cache-info/Cargo.toml index 83df384be..e616958fd 100644 --- a/crates/uv-cache-info/Cargo.toml +++ b/crates/uv-cache-info/Cargo.toml @@ -16,6 +16,8 @@ doctest = false workspace = true [dependencies] +uv-fs = { workspace = true } + fs-err = { workspace = true } globwalk = { workspace = true } schemars = { workspace = true, optional = true } diff --git a/crates/uv-cache-info/src/cache_info.rs b/crates/uv-cache-info/src/cache_info.rs index d2f836c84..08d07329a 100644 --- a/crates/uv-cache-info/src/cache_info.rs +++ b/crates/uv-cache-info/src/cache_info.rs @@ -1,11 +1,12 @@ use std::borrow::Cow; -use std::cmp::max; use std::collections::BTreeMap; use std::path::{Path, PathBuf}; use serde::Deserialize; use tracing::{debug, warn}; +use uv_fs::Simplified; + use crate::git_info::{Commit, Tags}; use crate::glob::cluster_globs; use crate::timestamp::Timestamp; @@ -63,7 +64,7 @@ impl CacheInfo { pub fn from_directory(directory: &Path) -> Result { let mut commit = None; let mut tags = None; - let mut timestamp = None; + let mut last_changed: Option<(PathBuf, Timestamp)> = None; let mut directories = BTreeMap::new(); let mut env = BTreeMap::new(); @@ -128,7 +129,12 @@ impl CacheInfo { ); continue; } - timestamp = max(timestamp, Some(Timestamp::from_metadata(&metadata))); + let timestamp = Timestamp::from_metadata(&metadata); + if last_changed.as_ref().is_none_or(|(_, prev_timestamp)| { + *prev_timestamp < Timestamp::from_metadata(&metadata) + }) { + last_changed = Some((path, timestamp)); + } } CacheKey::Directory { dir } => { // Treat the path as a directory. @@ -258,14 +264,25 @@ impl CacheInfo { } continue; } - timestamp = max(timestamp, Some(Timestamp::from_metadata(&metadata))); + let timestamp = Timestamp::from_metadata(&metadata); + if last_changed.as_ref().is_none_or(|(_, prev_timestamp)| { + *prev_timestamp < Timestamp::from_metadata(&metadata) + }) { + last_changed = Some((entry.into_path(), timestamp)); + } } } } - debug!( - "Computed cache info: {timestamp:?}, {commit:?}, {tags:?}, {env:?}, {directories:?}" - ); + let timestamp = if let Some((path, timestamp)) = last_changed { + debug!( + "Computed cache info: {timestamp:?}, {commit:?}, {tags:?}, {env:?}, {directories:?}. Most recently modified: {}", + path.user_display() + ); + Some(timestamp) + } else { + None + }; Ok(Self { timestamp,