aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG.md1
-rw-r--r--projectile.el10
-rw-r--r--test/projectile-test.el26
3 files changed, 36 insertions, 1 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index bed2f14..9f0cd36 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -42,6 +42,7 @@
* Fix `projectile--other-extension-files` sort comparator ignoring its second argument, producing undefined ordering; replaced with a stable partition.
* Fix `projectile-toggle-project-read-only` operating on the wrong buffer after `add-dir-local-variable` by wrapping in `save-selected-window`.
* Fix `projectile-cache-current-file` calling `projectile-project-root` twice instead of reusing the already-resolved value.
+* Fix `projectile-load-project-cache` not recording a cache time, which combined with `projectile-files-cache-expire` made the TTL check immediately re-evict freshly loaded data — every call ended up re-reading the cache file from disk and the data was never reindexed. The cache file's mtime is now used to seed `projectile-projects-cache-time`.
* Fix `projectile-load-project-cache` storing nil in cache on corrupt/empty cache files, preventing future reload attempts.
* Fix `projectile--cmake-command-presets` using `mapcar` instead of `mapcan`, producing nested lists for included presets.
* Fix `projectile--eat` ignoring the `new-process` argument when generating buffer names.
diff --git a/projectile.el b/projectile.el
index c4c0154..977860e 100644
--- a/projectile.el
+++ b/projectile.el
@@ -1221,6 +1221,16 @@ The cache is created both in memory and on the hard drive."
(when (file-exists-p cache-file)
(when-let* ((data (projectile-unserialize cache-file)))
(puthash project-root data projectile-projects-cache)
+ ;; Seed the cache time from the file's mtime so the TTL check in
+ ;; `projectile-project-files' can decide whether the loaded data is
+ ;; already stale, and so the in-memory entry isn't evicted on the
+ ;; next call just because no time was recorded.
+ (puthash project-root
+ (time-convert
+ (file-attribute-modification-time
+ (file-attributes cache-file))
+ 'integer)
+ projectile-projects-cache-time)
data))))
;;;###autoload
diff --git a/test/projectile-test.el b/test/projectile-test.el
index 52c3b98..e21effb 100644
--- a/test/projectile-test.el
+++ b/test/projectile-test.el
@@ -3300,7 +3300,31 @@ projectile-process-current-project-buffers-current to have similar behaviour"
(spy-on 'file-exists-p :and-return-value t)
(spy-on 'projectile-unserialize :and-return-value nil)
(projectile-load-project-cache "/project/")
- (expect (gethash "/project/" projectile-projects-cache) :to-be nil))))
+ (expect (gethash "/project/" projectile-projects-cache) :to-be nil)))
+ (it "records a cache time so TTL checks don't immediately evict the loaded data"
+ ;; Without this, `projectile-files-cache-expire' combined with persistent
+ ;; caching would re-read the cache file from disk on every call (and never
+ ;; reindex), because the TTL check evicts entries that have no recorded time.
+ (projectile-test-with-sandbox
+ (projectile-test-with-files
+ ("project/")
+ (let ((cache-file (expand-file-name "project/.projectile-cache.eld"))
+ (projectile-projects-cache (make-hash-table :test 'equal))
+ (projectile-projects-cache-time (make-hash-table :test 'equal)))
+ (with-temp-file cache-file
+ (insert (prin1-to-string '("file1.el" "file2.el"))))
+ (spy-on 'projectile-project-cache-file :and-return-value cache-file)
+ (projectile-load-project-cache "/project/")
+ (expect (gethash "/project/" projectile-projects-cache)
+ :to-equal '("file1.el" "file2.el"))
+ (expect (gethash "/project/" projectile-projects-cache-time)
+ :to-be-truthy)
+ (expect (gethash "/project/" projectile-projects-cache-time)
+ :to-equal
+ (time-convert
+ (file-attribute-modification-time
+ (file-attributes cache-file))
+ 'integer)))))))
(describe "projectile-project-buffer-p"
(it "uses the truename cache when provided"