gexp: ‘local-file’ expands its argument only once.

Fixes a bug whereby (local-file (in-vicinity (getcwd) "xyz")) would
point to different files depending on the current working directory at
the time it is lowered.

* guix/gexp.scm (local-file): Expand FILE only once.
* tests/gexp.scm ("local-file, capture at the right time"): New test.

Change-Id: I2cc23296de3799e68f7d8b7be6061be3043e1176
This commit is contained in:
Ludovic Courtès 2025-04-05 23:22:47 +02:00
parent 649b52b0d4
commit 21221710f2
No known key found for this signature in database
GPG key ID: 090B11993D9AEBB5
2 changed files with 30 additions and 11 deletions

View file

@ -520,24 +520,27 @@ appears."
((_ (assume-source-relative-file-name file) rest ...)
;; FILE is not a literal, but the user requested we look it up
;; relative to the current source directory.
#'(%local-file file
(delay (absolute-file-name file (current-source-directory)))
rest ...))
#'(let ((f file))
(%local-file f
(delay (absolute-file-name f (current-source-directory)))
rest ...)))
((_ (assume-valid-file-name file) rest ...)
;; FILE is not a literal, so resolve it relative to the current
;; directory. Since the user declared FILE is valid, do not pass
;; #:literal? #f so that we do not warn about it later on.
#'(%local-file file
(delay (absolute-file-name file (getcwd)))
rest ...))
#'(let ((f file))
(%local-file f
(delay (absolute-file-name f (getcwd)))
rest ...)))
((_ file rest ...)
;; Resolve FILE relative to the current directory.
(with-syntax ((location (datum->syntax s (syntax-source s))))
#`(%local-file file
(delay (absolute-file-name file (getcwd)))
rest ...
#:location 'location
#:literal? #f))) ;warn if FILE is relative
#`(let ((f file))
(%local-file f
(delay (absolute-file-name f (getcwd)))
rest ...
#:location 'location
#:literal? #f)))) ;warn if FILE is relative
((_)
#'(syntax-error "missing file name"))
(id