nixpkgs-plugin-update: key cached downloads by repo and ref
Namespace cache entries by repository and fetch ref instead of keying them only by commit text. Once tagged fetches are preserved, different repositories can legitimately share the same tag name. Keying the cache by the bare ref lets unrelated plugins collide and reuse the wrong prefetched hash. Use repo URI plus tag/commit so cache hits stay repository-specific.
This commit is contained in:
+24
-12
@@ -840,9 +840,7 @@ class Editor:
|
||||
current_plugins = self.get_current_plugins(config, self.nixpkgs)
|
||||
current_plugin_specs = self.load_plugin_spec(config, input_file)
|
||||
|
||||
cache: Cache = Cache(
|
||||
[plugin for _description, plugin in current_plugins], self.cache_file
|
||||
)
|
||||
cache: Cache = Cache(current_plugins, self.cache_file)
|
||||
current_plugin_map = {
|
||||
plugin.normalized_name: plugin for _description, plugin in current_plugins
|
||||
}
|
||||
@@ -1107,7 +1105,7 @@ def prefetch_plugin(
|
||||
latest_tag,
|
||||
)
|
||||
|
||||
cached_plugin = cache[commit] if cache else None
|
||||
cached_plugin = cache[target_cache_key(p.repo.uri, commit, source_tag)] if cache else None
|
||||
if cached_plugin is not None:
|
||||
log.debug(f"Cache hit for {p.name}!")
|
||||
cached_plugin.name = p.name
|
||||
@@ -1200,13 +1198,27 @@ def get_cache_path(cache_file_name: str) -> Path | None:
|
||||
return Path(xdg_cache, cache_file_name)
|
||||
|
||||
|
||||
def plugin_cache_key(repo_uri: str, plugin: "Plugin") -> str:
|
||||
ref = f"{GIT_TAGS_PREFIX}{plugin.tag}" if plugin.tag is not None else plugin.commit
|
||||
return f"{repo_uri}@{ref}"
|
||||
|
||||
|
||||
def target_cache_key(repo_uri: str, commit: str, source_tag: str | None) -> str:
|
||||
ref = f"{GIT_TAGS_PREFIX}{source_tag}" if source_tag is not None else commit
|
||||
return f"{repo_uri}@{ref}"
|
||||
|
||||
|
||||
class Cache:
|
||||
def __init__(self, initial_plugins: list[Plugin], cache_file_name: str) -> None:
|
||||
def __init__(
|
||||
self,
|
||||
initial_plugins: list[tuple[PluginDesc, Plugin]],
|
||||
cache_file_name: str,
|
||||
) -> None:
|
||||
self.cache_file = get_cache_path(cache_file_name)
|
||||
|
||||
downloads = {}
|
||||
for plugin in initial_plugins:
|
||||
downloads[plugin.commit] = plugin
|
||||
for plugin_desc, plugin in initial_plugins:
|
||||
downloads[plugin_cache_key(plugin_desc.repo.uri, plugin)] = plugin
|
||||
downloads.update(self.load())
|
||||
self.downloads = downloads
|
||||
|
||||
@@ -1217,7 +1229,7 @@ class Cache:
|
||||
downloads: dict[str, Plugin] = {}
|
||||
with open(self.cache_file) as f:
|
||||
data = json.load(f)
|
||||
for attr in data.values():
|
||||
for cache_key, attr in data.items():
|
||||
p = Plugin(
|
||||
attr["name"],
|
||||
attr["commit"],
|
||||
@@ -1227,7 +1239,7 @@ class Cache:
|
||||
last_tag=attr.get("last_tag"),
|
||||
tag=attr.get("tag"),
|
||||
)
|
||||
downloads[attr["commit"]] = p
|
||||
downloads[cache_key] = p
|
||||
return downloads
|
||||
|
||||
def store(self) -> None:
|
||||
@@ -1237,8 +1249,8 @@ class Cache:
|
||||
os.makedirs(self.cache_file.parent, exist_ok=True)
|
||||
with open(self.cache_file, "w+") as f:
|
||||
data = {}
|
||||
for name, attr in self.downloads.items():
|
||||
data[name] = attr.as_json()
|
||||
for cache_key, attr in self.downloads.items():
|
||||
data[cache_key] = attr.as_json()
|
||||
json.dump(data, f, indent=4, sort_keys=True)
|
||||
|
||||
def __getitem__(self, key: str) -> Plugin | None:
|
||||
@@ -1258,7 +1270,7 @@ def prefetch(
|
||||
if current_plugins is not None:
|
||||
current_plugin = current_plugins.get(pluginDesc.name.replace(".", "-"))
|
||||
plugin, redirect = prefetch_plugin(pluginDesc, cache, current_plugin)
|
||||
cache[plugin.commit] = plugin
|
||||
cache[target_cache_key(pluginDesc.repo.uri, plugin.commit, plugin.tag)] = plugin
|
||||
return (pluginDesc, plugin, redirect)
|
||||
except Exception as e:
|
||||
return (pluginDesc, e, None)
|
||||
|
||||
Reference in New Issue
Block a user