guix_mirror_bot pushed a commit to branch master
in repository guix.
commit 90f7702c22aedfb9cf01017222345a43c8a124ea
Author: Ludovic Courtès <[email protected]>
AuthorDate: Tue Oct 6 15:12:56 2026 +0200
shell: Support caching when both a file and package specs are given.
This fixes an annoyance whereby, for instance, ‘guix shell -Df guix.scm’
would
benefit from caching, but ‘guix shell -Df guix.scm shepherd’ would not.
* guix/scripts/shell.scm (profile-file-cache-key): Remove.
(profile-spec-cache-key): Rename to…
(profile-cache-key): … this. Update docstring.
(profile-cached-gc-root): Replace ‘file’ argument of ‘loop’ with ‘mtime’.
Allow for both files (‘manifest.scm’, ‘guix.scm’, etc.) and
package specs.
Fixes: guile/guile#291
Reported-by: Olivier Dion <[email protected]>
Signed-off-by: Ludovic Courtès <[email protected]>
---
guix/scripts/shell.scm | 59 ++++++++++++++++----------------------------------
1 file changed, 19 insertions(+), 40 deletions(-)
diff --git a/guix/scripts/shell.scm b/guix/scripts/shell.scm
index 1966264298d..32d46fee55d 100644
--- a/guix/scripts/shell.scm
+++ b/guix/scripts/shell.scm
@@ -347,28 +347,11 @@ performed--e.g., because the package cache is not
authoritative."
(((= channel-commit commits) ...)
(string-join commits)))))
-(define (profile-file-cache-key file system graft?)
- "Return the cache key for the profile corresponding to FILE, a 'guix.scm' or
-'manifest.scm' file, or #f if we lack channel information. GRAFT? is used
-to distinguish cache keys of profiles without grafts."
- (match (profile-cache-primary-key)
- (#f #f)
- (primary-key
- (let ((stat (stat file)))
- (bytevector->base32-string
- ;; Since FILE is not canonicalized, only include the device/inode
- ;; numbers. XXX: In some rare cases involving Btrfs and NFS, this can
- ;; be insufficient: <https://lwn.net/Articles/866582/>.
- (sha256 (string->utf8
- (string-append primary-key ":" system ":"
- (if graft? "" "ungrafted:")
- (number->string (stat:dev stat)) ":"
- (number->string (stat:ino stat))))))))))
-
-(define (profile-spec-cache-key specs system graft?)
+(define (profile-cache-key specs system graft?)
"Return the cache key corresponding to SPECS built for SYSTEM, where SPECS
-is a list of package specs. Return #f if caching is not possible. GRAFT? is
used
-to distinguish cache keys of profiles without grafts."
+is a list of package specs or sexps denoting other elements such as the name
+of files to load. Return #f if caching is not possible. GRAFT? is used to
+distinguish cache keys of profiles without grafts."
(match (profile-cache-primary-key)
(#f #f)
(primary-key
@@ -393,26 +376,21 @@ return #f and #f."
;; process it backwards so the last occurrence "wins".
(let loop ((opts (reverse opts))
(system (%current-system))
- (file #f)
+ (mtime 0)
(specs '()))
(match opts
(()
- (if file
- (values (and=> (profile-file-cache-key file system graft?)
key->file)
- (stat:mtime (stat file)))
- (values (and=> (profile-spec-cache-key specs system graft?)
key->file)
- 0)))
+ (values (and=> (profile-cache-key specs system graft?) key->file)
+ mtime))
(((and spec ('package . _)) . rest)
- (if (not file)
- (loop rest system file (cons spec specs))
- (values #f #f)))
+ (loop rest system mtime (cons spec specs)))
((('nesting? . #t) . rest)
- (loop rest system file (append specs '("nested guix"))))
+ (loop rest system mtime (append specs '("nested guix"))))
((('load . ('package candidate)) . rest)
;; This is 'guix shell -D -f guix.scm'.
- (if (and (not file) (null? specs))
- (loop rest system candidate specs)
- (values #f #f)))
+ (loop rest system
+ (max mtime (stat:mtime (stat candidate)))
+ (cons `(file ,candidate) specs)))
((('load . ('ad-hoc-package candidate)) . rest)
;; When running 'guix shell -f guix.scm', one typically expects
;; 'guix.scm' to be evaluated every time because it may contain
@@ -420,9 +398,9 @@ return #f and #f."
;; caching.
(values #f #f))
((('manifest . candidate) . rest)
- (if (and (not file) (null? specs))
- (loop rest system candidate specs)
- (values #f #f)))
+ (loop rest system
+ (max mtime (stat:mtime (stat candidate)))
+ (cons `(manifest ,candidate) specs)))
((('expression . _) . _)
;; Arbitrary expressions might be non-deterministic or otherwise depend
;; on external state so do not cache when they're used.
@@ -432,7 +410,7 @@ return #f and #f."
;; least depending on external state (with-source, with-commit, etc.).
;; Cache only those that are known to be "cacheable".
(if (cacheable-transformation-option-key? key)
- (loop rest system file (cons (first opts) specs))
+ (loop rest system mtime (cons (first opts) specs))
(values #f #f)))
((('profile . _) . _)
;; If the user already specified a profile, there's nothing more to
@@ -444,8 +422,9 @@ return #f and #f."
;; expanded list of inputs.
(values #f #f))
((('system . system) . rest)
- (loop rest system file specs))
- ((_ . rest) (loop rest system file specs)))))
+ (loop rest system mtime specs))
+ ((_ . rest)
+ (loop rest system mtime specs)))))
;;;