mirror of
https://github.com/astral-sh/uv.git
synced 2025-08-04 02:48:17 +00:00
Add support for dynamic cache keys (#7136)
## Summary This PR adds a more flexible cache invalidation abstraction for uv, and uses that new abstraction to improve support for dynamic metadata. Specifically, instead of relying solely on a timestamp, we now pass around a `CacheInfo` struct which (as of now) contains `Option<Timestamp>` and `Option<Commit>`. The `CacheInfo` is saved in `dist-info` as `uv_cache.json`, so we can test already-installed distributions for cache validity (along with testing _cached_ distributions for cache validity). Beyond the defaults (`pyproject.toml`, `setup.py`, and `setup.cfg` changes), users can also specify additional cache keys, and it's easy for us to extend support in the future. Right now, cache keys can either be instructions to include the current commit (for `setuptools_scm` and similar) or file paths (for `hatch-requirements-txt` and similar): ```toml [tool.uv] cache-keys = [{ file = "requirements.txt" }, { git = true }] ``` This change should be fully backwards compatible. Closes https://github.com/astral-sh/uv/issues/6964. Closes https://github.com/astral-sh/uv/issues/6255. Closes https://github.com/astral-sh/uv/issues/6860.
This commit is contained in:
parent
9a7262c360
commit
4f2349119c
47 changed files with 1036 additions and 206 deletions
|
@ -13,12 +13,14 @@ license = { workspace = true }
|
|||
workspace = true
|
||||
|
||||
[dependencies]
|
||||
cache-key = { workspace = true }
|
||||
distribution-types = { workspace = true }
|
||||
pep508_rs = { workspace = true, features = ["schemars"] }
|
||||
platform-tags = { workspace = true }
|
||||
pypi-types = { workspace = true }
|
||||
uv-auth = { workspace = true }
|
||||
uv-cache = { workspace = true }
|
||||
uv-cache-info = { workspace = true }
|
||||
uv-normalize = { workspace = true }
|
||||
|
||||
clap = { workspace = true, features = ["derive"], optional = true }
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
use cache_key::CacheKeyHasher;
|
||||
use std::{
|
||||
collections::{btree_map::Entry, BTreeMap},
|
||||
str::FromStr,
|
||||
|
@ -108,6 +109,16 @@ impl FromIterator<ConfigSettingEntry> for ConfigSettings {
|
|||
}
|
||||
|
||||
impl ConfigSettings {
|
||||
/// Returns the number of settings in the configuration.
|
||||
pub fn len(&self) -> usize {
|
||||
self.0.len()
|
||||
}
|
||||
|
||||
/// Returns `true` if the configuration contains no settings.
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.0.is_empty()
|
||||
}
|
||||
|
||||
/// Convert the settings to a string that can be passed directly to a PEP 517 build backend.
|
||||
pub fn escape_for_python(&self) -> String {
|
||||
serde_json::to_string(self).expect("Failed to serialize config settings")
|
||||
|
@ -150,6 +161,18 @@ impl ConfigSettings {
|
|||
}
|
||||
}
|
||||
|
||||
impl cache_key::CacheKey for ConfigSettings {
|
||||
fn cache_key(&self, state: &mut CacheKeyHasher) {
|
||||
for (key, value) in &self.0 {
|
||||
key.cache_key(state);
|
||||
match value {
|
||||
ConfigSettingValue::String(value) => value.cache_key(state),
|
||||
ConfigSettingValue::List(values) => values.cache_key(state),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl serde::Serialize for ConfigSettings {
|
||||
fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
|
||||
use serde::ser::SerializeMap;
|
||||
|
|
|
@ -3,7 +3,8 @@ use pep508_rs::PackageName;
|
|||
|
||||
use pypi_types::Requirement;
|
||||
use rustc_hash::FxHashMap;
|
||||
use uv_cache::{Refresh, Timestamp};
|
||||
use uv_cache::Refresh;
|
||||
use uv_cache_info::Timestamp;
|
||||
|
||||
/// Whether to reinstall packages.
|
||||
#[derive(Debug, Default, Clone, serde::Serialize, serde::Deserialize)]
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue