summaryrefslogtreecommitdiff
path: root/guix/utils.scm
diff options
context:
space:
mode:
Diffstat (limited to 'guix/utils.scm')
-rw-r--r--guix/utils.scm41
1 files changed, 38 insertions, 3 deletions
diff --git a/guix/utils.scm b/guix/utils.scm
index d7b197fa44..812617dd61 100644
--- a/guix/utils.scm
+++ b/guix/utils.scm
@@ -35,8 +35,10 @@
#:use-module (rnrs io ports) ;need 'port-position' etc.
#:use-module ((rnrs bytevectors) #:select (bytevector-u8-set!))
#:use-module (guix memoization)
- #:use-module ((guix build utils) #:select (dump-port mkdir-p delete-file-recursively))
- #:use-module ((guix build syscalls) #:select (mkdtemp! fdatasync))
+ #:use-module ((guix build utils)
+ #:select (dump-port mkdir-p delete-file-recursively
+ executable-file?))
+ #:use-module ((guix build syscalls) #:select (mkdtemp! fdatasync scandir*))
#:use-module (ice-9 format)
#:use-module (ice-9 regex)
#:use-module (ice-9 match)
@@ -109,7 +111,8 @@
call-with-decompressed-port
compressed-output-port
call-with-compressed-output-port
- canonical-newline-port))
+ canonical-newline-port
+ reset-timestamps))
;;;
@@ -843,6 +846,38 @@ a location object."
fix-hint?
(hint condition-fix-hint)) ;string
+(define* (reset-timestamps file #:key preserve-permissions?)
+ "Reset the modification time on FILE and on all the files it contains, if
+it's a directory. Canonicalize file permissions unless PRESERVE-PERMISSIONS?
+is true."
+ ;; Note: We're resetting to one second after the Epoch like 'guix-daemon'
+ ;; has always done.
+ (let loop ((file file)
+ (type (stat:type (lstat file))))
+ (case type
+ ((directory)
+ (unless preserve-permissions?
+ (chmod file #o555))
+ (utime file 1 1 0 0)
+ (let ((parent file))
+ (for-each (match-lambda
+ (("." . _) #f)
+ ((".." . _) #f)
+ ((file . properties)
+ (let ((file (string-append parent "/" file)))
+ (loop file
+ (match (assoc-ref properties 'type)
+ ((or 'unknown #f)
+ (stat:type (lstat file)))
+ (type type))))))
+ (scandir* parent))))
+ ((symlink)
+ (utime file 1 1 0 0 AT_SYMLINK_NOFOLLOW))
+ (else
+ (unless preserve-permissions?
+ (chmod file (if (executable-file? file) #o555 #o444)))
+ (utime file 1 1 0 0)))))
+
;;; Local Variables:
;;; eval: (put 'call-with-progress-reporter 'scheme-indent-function 1)
;;; End: