gexp: Allow file-unions with dangling symlinks.

* guix/gexp.scm (file-union): Add #:dangling-symlinks? parameter.

Change-Id: I09d44ec785fd7141b02dee2d8dc23ccc499aa933
Signed-off-by: Maxim Cournoyer <maxim.cournoyer@gmail.com>
This commit is contained in:
Sergey Trofimov 2025-05-19 11:50:08 +02:00 committed by Maxim Cournoyer
parent 93e74686ea
commit 9b7213fc11
No known key found for this signature in database
GPG key ID: 1260E46482E63562
2 changed files with 30 additions and 27 deletions

View file

@ -12673,11 +12673,13 @@ as in:
This is the declarative counterpart of @code{text-file*}. This is the declarative counterpart of @code{text-file*}.
@end deffn @end deffn
@deffn {Procedure} file-union name files @deffn {Procedure} file-union name files [#:dangling-symlinks? #f]
Return a @code{<computed-file>} that builds a directory containing all of @var{files}. Return a @code{<computed-file>} that builds a directory containing all
Each item in @var{files} must be a two-element list where the first element is the of @var{files}. Each item in @var{files} must be a two-element list
file name to use in the new directory, and the second element is a gexp where the first element is the file name to use in the new directory,
denoting the target file. Here's an example: and the second element is a gexp denoting the target file.
@code{#:dangling-symlinks?} controls if gexps must lower to an existing
file. Here's an example:
@lisp @lisp
(file-union "etc" (file-union "etc"

View file

@ -2144,7 +2144,7 @@ This is the declarative counterpart of 'text-file*'."
(computed-file name build #:guile guile)) (computed-file name build #:guile guile))
(define* (file-union name files #:key guile) (define* (file-union name files #:key guile dangling-symlinks?)
"Return a <computed-file> that builds a directory containing all of FILES. "Return a <computed-file> that builds a directory containing all of FILES.
Each item in FILES must be a two-element list where the first element is the Each item in FILES must be a two-element list where the first element is the
file name to use in the new directory, and the second element is a gexp file name to use in the new directory, and the second element is a gexp
@ -2158,7 +2158,8 @@ denoting the target file. Here's an example:
(\"libvirt/qemu.conf\" ,(plain-file \"qemu.conf\" \"\")))) (\"libvirt/qemu.conf\" ,(plain-file \"qemu.conf\" \"\"))))
This yields an 'etc' directory containing these two files." This yields an 'etc' directory containing these two files."
(computed-file name (computed-file
name
(with-imported-modules '((guix build utils)) (with-imported-modules '((guix build utils))
(gexp (gexp
(begin (begin
@ -2170,14 +2171,14 @@ This yields an 'etc' directory containing these two files."
(map (match-lambda (map (match-lambda
((target source) ((target source)
(gexp (gexp
(begin (let ((source (ungexp source))
;; Stat the source to abort early if it does (target (ungexp target)))
;; not exist. (unless (or (ungexp dangling-symlinks?)
(stat (ungexp source)) (stat source #f))
(error (format #f "~a points to inexistent file \
(mkdir-p (dirname (ungexp target))) or dangling symlink ~a" target source)))
(symlink (ungexp source) (mkdir-p (dirname target))
(ungexp target)))))) (symlink source target)))))
files))))) files)))))
#:guile guile)) #:guile guile))