From 69581a3529b8d86150e74d92558e9411fdd49399 Mon Sep 17 00:00:00 2001 From: Jim Myhrberg Date: Sun, 13 Apr 2025 13:52:57 +0100 Subject: [PATCH] chore(cached-eval): improve caching mechanism - Include mtime of source file in cache key calculation. - Use SHA1 instead of MD5 to generate cache key. - Add flush-cached-eval helper function to clear all caches. --- zshenv | 57 ++++++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 54 insertions(+), 3 deletions(-) diff --git a/zshenv b/zshenv index bd79378..13230bf 100644 --- a/zshenv +++ b/zshenv @@ -82,12 +82,41 @@ source-if-exists() { fi } +# mtime returns the modification time of a file in seconds since epoch. +# +# Supports macOS and Linux. +# +# Arguments: +# +# $1 - file: The path to the file to get the modification time of. +# +# Returns: +# The modification time of the file in seconds since epoch. +mtime() { + local file="$1" + + if [ -f "$file" ]; then + case "$(uname)" in + Darwin) + stat -f "%m" "$file" + ;; + Linux) + stat -c "%Y" "$file" + ;; + esac + fi +} + # cached-eval executes a command with arguments and caches the output. On # subsequent calls, if the source file has not changed, the output is sourced # from the cache instead of re-executing the command. This optimizes performance # for commands that are costly to execute but result in the same output unless # their source files change. # +# The cache key is calculated from the source file path, its modification time, +# and the command to execute. If any of those change, the command is re-executed +# and the cache is updated to a new cache file. +# # Arguments: # # $1 - source_file: The path to the source file that the command depends on. @@ -108,15 +137,17 @@ cached-eval() { shift 1 local script="$@" - local cache_dir="${ZSH_CACHED_EVAL_DIR:-$HOME/.local/share/zsh/cached-eval}" if [[ ! -f "$source_file" ]]; then echo "cached-eval: Source file not found: $source_file" >&2 return 1 fi - local md5_cmd="$(command-path md5 || command-path md5sum)" - local cache_hash="$(echo -n "${source_file}:${script}" | "$md5_cmd" | awk '{print $1}')" + local cache_dir="${ZSH_CACHED_EVAL_DIR:-$HOME/.local/share/zsh/cached-eval}" + local hash_cmd="$(command-path shasum || command-path sha1sum)" + local mtime="$(mtime "$source_file")" + local cache_hash="$(echo -n "${source_file}:${mtime}:${script}" | \ + "$hash_cmd" | awk '{print $1}')" local cache_file="${cache_dir}/${cache_hash}.cache.zsh" if [ -z "$cache_hash" ]; then @@ -134,6 +165,26 @@ cached-eval() { source "$cache_file" } +flush-cached-eval() { + local cache_dir="${ZSH_CACHED_EVAL_DIR:-$HOME/.local/share/zsh/cached-eval}" + + if [[ ! -d "$cache_dir" ]]; then + echo "cached-eval: Cache directory not found: $cache_dir" >&2 + return 1 + fi + + local cache_files=("$cache_dir"/*.cache.zsh) + if [[ "${#cache_files[@]}" -eq 0 ]]; then + echo "cached-eval: No cache files found in: $cache_dir" >&2 + return 1 + fi + + for cache_file in "${cache_files[@]}"; do + echo "cached-eval: Flushing cache file: $cache_file" >&2 + rm -f "$cache_file" + done +} + # ============================================================================== # System Environment Setup # ==============================================================================