GNU bug report logs - #78378
[PATCH 0/2] home: services: Build "files" union allowing dangling symlinks.

Previous Next

Package: guix-patches;

Reported by: Sergey Trofimov <sarg <at> sarg.org.ru>

Date: Sun, 11 May 2025 16:02:02 UTC

Severity: normal

Tags: patch

Done: Maxim Cournoyer <maxim.cournoyer <at> gmail.com>

To reply to this bug, email your comments to 78378 AT debbugs.gnu.org.
There is no need to reopen the bug first.

Toggle the display of automated, internal messages from the tracker.

View this report as an mbox folder, status mbox, maintainer mbox


Report forwarded to andrew <at> trop.in, hako <at> ultrarare.space, janneke <at> gnu.org, ludo <at> gnu.org, tanguy <at> bioneland.org, guix-patches <at> gnu.org:
bug#78378; Package guix-patches. (Sun, 11 May 2025 16:02:02 GMT) Full text and rfc822 format available.

Acknowledgement sent to Sergey Trofimov <sarg <at> sarg.org.ru>:
New bug report received and forwarded. Copy sent to andrew <at> trop.in, hako <at> ultrarare.space, janneke <at> gnu.org, ludo <at> gnu.org, tanguy <at> bioneland.org, guix-patches <at> gnu.org. (Sun, 11 May 2025 16:02:02 GMT) Full text and rfc822 format available.

Message #5 received at submit <at> debbugs.gnu.org (full text, mbox):

From: Sergey Trofimov <sarg <at> sarg.org.ru>
To: guix-patches <at> gnu.org
Cc: Sergey Trofimov <sarg <at> sarg.org.ru>
Subject: [PATCH 0/2] home: services: Build "files" union allowing dangling
 symlinks.
Date: Sun, 11 May 2025 18:00:50 +0200
This patch enables guix home users to create arbitrary symlinks in their home
environment. I.e. a user having "/storage" directory (probably residing on
another disk partition) could symlink e.g. "~/.mail" from
"/storage/data/mail". 

Sergey Trofimov (2):
  gexp: Add symlink-to procedure.
  home: services: Build "files" union allowing dangling symlinks.

 doc/guix.texi         | 11 +++++++++++
 gnu/home/services.scm | 16 +++++++++++++++-
 guix/gexp.scm         |  5 +++++
 tests/guix-home.sh    |  8 +++++++-
 4 files changed, 38 insertions(+), 2 deletions(-)


base-commit: f6363db18636172f959e2709982bbe09b411c3d8
-- 
2.49.0





Information forwarded to guix <at> cbaines.net, gabriel <at> erlikon.ch, dev <at> jpoiret.xyz, ludo <at> gnu.org, othacehe <at> gnu.org, maxim.cournoyer <at> gmail.com, zimon.toutoune <at> gmail.com, me <at> tobias.gr, guix-patches <at> gnu.org:
bug#78378; Package guix-patches. (Sun, 11 May 2025 16:10:02 GMT) Full text and rfc822 format available.

Message #8 received at 78378 <at> debbugs.gnu.org (full text, mbox):

From: Sergey Trofimov <sarg <at> sarg.org.ru>
To: 78378 <at> debbugs.gnu.org
Cc: Sergey Trofimov <sarg <at> sarg.org.ru>
Subject: [PATCH 1/2] gexp: Add symlink-to procedure.
Date: Sun, 11 May 2025 18:08:02 +0200
* guix/gexp.scm (symlink-to): New procedure.
* doc/guix.texi (G-Expressions): Document it.

Change-Id: I7c1ba3a29a4e5350cb4f196185b7171c4750b6b8
---
 doc/guix.texi | 11 +++++++++++
 guix/gexp.scm |  5 +++++
 2 files changed, 16 insertions(+)

diff --git a/doc/guix.texi b/doc/guix.texi
index cbc4dd0fc9..ebc8a5e5d3 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -12689,6 +12689,17 @@ G-Expressions
 This yields an @code{etc} directory containing these two files.
 @end deffn
 
+@deffn {Procedure} symlink-to target
+Return a @code{<computed-file>} that is a symbolic link to target.
+Note, that the target does not need to exist at the build time.  One of
+uses is to put arbitrary symlinks into user's home:
+
+@lisp
+(service home-files-service-type
+  `(("Sync" ,(symlink-to "/storage/Sync"))))
+@end lisp
+@end deffn
+
 @deffn {Procedure} directory-union name things
 Return a directory that is the union of @var{things}, where @var{things} is a list of
 file-like objects denoting directories.  For example:
diff --git a/guix/gexp.scm b/guix/gexp.scm
index 8dd746eee0..ef83c671ec 100644
--- a/guix/gexp.scm
+++ b/guix/gexp.scm
@@ -119,6 +119,7 @@ (define-module (guix gexp)
             file-union
             directory-union
             references-file
+            symlink-to
 
             imported-files
             imported-modules
@@ -2181,6 +2182,10 @@ (define* (file-union name files #:key guile)
                             files)))))
                  #:guile guile))
 
+(define (symlink-to target)
+  "Return an object that is a symlink to TARGET."
+  (computed-file "link" (gexp (symlink (ungexp target) (ungexp output)))))
+
 (define* (directory-union name things
                           #:key (copy? #f) (quiet? #f)
                           (resolve-collision 'resolve-collision/default))
-- 
2.49.0





Information forwarded to andrew <at> trop.in, hako <at> ultrarare.space, janneke <at> gnu.org, ludo <at> gnu.org, tanguy <at> bioneland.org, guix-patches <at> gnu.org:
bug#78378; Package guix-patches. (Sun, 11 May 2025 16:10:02 GMT) Full text and rfc822 format available.

Message #11 received at 78378 <at> debbugs.gnu.org (full text, mbox):

From: Sergey Trofimov <sarg <at> sarg.org.ru>
To: 78378 <at> debbugs.gnu.org
Cc: Sergey Trofimov <sarg <at> sarg.org.ru>
Subject: [PATCH 2/2] home: services: Build "files" union allowing dangling
 symlinks.
Date: Sun, 11 May 2025 18:08:03 +0200
* gnu/home/services.scm (files->files-directory): Build file union
without checking for existence of included items.

* tests/guix-home.sh: Verify symlinking files out of store works.

Change-Id: I94054003f4a6be944252ce7a397cf56f0b979554
---
 gnu/home/services.scm | 16 +++++++++++++++-
 tests/guix-home.sh    |  8 +++++++-
 2 files changed, 22 insertions(+), 2 deletions(-)

diff --git a/gnu/home/services.scm b/gnu/home/services.scm
index 2342dc5e07..55f9365922 100644
--- a/gnu/home/services.scm
+++ b/gnu/home/services.scm
@@ -343,7 +343,21 @@ (define (files->files-directory files)
   ;; leading to a build failure of "files.drv".
   (assert-no-duplicates files)
 
-  (file-union "files" files))
+  ;; Compute the file-union allowing dangling symlinks
+  ;; This enables creating symlinks to locations out of store
+  (computed-file
+   "files"
+   (with-imported-modules '((guix build utils))
+     #~(begin
+         (use-modules (guix build utils)
+                      (ice-9 match))
+         (mkdir #$output)
+         (chdir #$output)
+         (for-each (match-lambda
+                     ((target source)
+                      (mkdir-p (dirname target))
+                      (symlink source target)))
+                   '#$files)))))
 
 ;; Used by symlink-manager
 (define home-files-directory "files")
diff --git a/tests/guix-home.sh b/tests/guix-home.sh
index dbfe7dbd48..b8d90196f1 100644
--- a/tests/guix-home.sh
+++ b/tests/guix-home.sh
@@ -73,7 +73,9 @@ trap 'chmod -Rf +w "$test_directory"; rm -rf "$test_directory"' EXIT
                    (list `(".config/test.conf"
                            ,(plain-file
                              "tmp-file.txt"
-                             "the content of ~/.config/test.conf"))))
+                             "the content of ~/.config/test.conf"))
+
+                         `("symlink" ,(symlink-to "<test_directory>"))))
 
    (service home-bash-service-type
             (home-bash-configuration
@@ -104,6 +106,7 @@ trap 'chmod -Rf +w "$test_directory"; rm -rf "$test_directory"' EXIT
                        "# the content of bashrc-test-config.sh"))))))))
 EOF
 
+    sed -i "s,<test_directory>,$test_directory," home.scm
     echo -n "# dot-bashrc test file for guix home" > "dot-bashrc"
 
     # Check whether the graph commands work as expected.
@@ -126,6 +129,7 @@ EOF
 	guix home container home.scm -- cat '~/.config/test.conf' | \
 	    grep "the content of"
 	guix home container home.scm -- test -h '~/.bashrc'
+	guix home container home.scm -- test -h '~/symlink'
 	test "$(guix home container home.scm -- id -u)" = 1000
 	guix home container home.scm -- test -f '$HOME/sample/home.scm' && false
 	guix home container home.scm --expose="$PWD=$HOME/sample" -- \
@@ -153,6 +157,8 @@ EOF
     test -d "${HOME}/.guix-home"
     test -h "${HOME}/.bash_profile"
     test -h "${HOME}/.bashrc"
+    test -h "${HOME}/symlink"
+    test "$(readlink -f $HOME/symlink)" == "$test_directory"
     grep 'alias run="guix shell"' "$HOME/.bashrc"
     grep "alias path='echo \$PATH'" "$HOME/.bashrc"
     test "$(tail -n 2 "${HOME}/.bashrc")" == "\
-- 
2.49.0





Information forwarded to guix-patches <at> gnu.org:
bug#78378; Package guix-patches. (Mon, 12 May 2025 07:50:02 GMT) Full text and rfc822 format available.

Message #14 received at 78378 <at> debbugs.gnu.org (full text, mbox):

From: Maxim Cournoyer <maxim.cournoyer <at> gmail.com>
To: Sergey Trofimov <sarg <at> sarg.org.ru>
Cc: Josselin Poiret <dev <at> jpoiret.xyz>, Tobias Geerinckx-Rice <me <at> tobias.gr>,
 Simon Tournier <zimon.toutoune <at> gmail.com>, Mathieu Othacehe <othacehe <at> gnu.org>,
 Ludovic Courtès <ludo <at> gnu.org>,
 Gabriel Wicki <gabriel <at> erlikon.ch>, 78378 <at> debbugs.gnu.org,
 Christopher Baines <guix <at> cbaines.net>
Subject: Re: [bug#78378] [PATCH 1/2] gexp: Add symlink-to procedure.
Date: Mon, 12 May 2025 16:49:08 +0900
Sergey Trofimov <sarg <at> sarg.org.ru> writes:

> * guix/gexp.scm (symlink-to): New procedure.
> * doc/guix.texi (G-Expressions): Document it.
>
> Change-Id: I7c1ba3a29a4e5350cb4f196185b7171c4750b6b8

Reviewed-by: Maxim Cournoyer <maxim.cournoyer <at> gmail.com>

-- 
Thanks,
Maxim




Information forwarded to guix-patches <at> gnu.org:
bug#78378; Package guix-patches. (Sun, 18 May 2025 21:04:03 GMT) Full text and rfc822 format available.

Message #17 received at 78378 <at> debbugs.gnu.org (full text, mbox):

From: Ludovic Courtès <ludo <at> gnu.org>
To: Sergey Trofimov <sarg <at> sarg.org.ru>
Cc: Hilton Chain <hako <at> ultrarare.space>,
 Janneke Nieuwenhuizen <janneke <at> gnu.org>,
 Tanguy Le Carrour <tanguy <at> bioneland.org>, 78378 <at> debbugs.gnu.org,
 Andrew Tropin <andrew <at> trop.in>
Subject: Re: [bug#78378] [PATCH 2/2] home: services: Build "files" union
 allowing dangling symlinks.
Date: Sun, 18 May 2025 22:28:30 +0200
Hi Sergey,

Sergey Trofimov <sarg <at> sarg.org.ru> writes:

> * gnu/home/services.scm (files->files-directory): Build file union
> without checking for existence of included items.
>
> * tests/guix-home.sh: Verify symlinking files out of store works.
>
> Change-Id: I94054003f4a6be944252ce7a397cf56f0b979554

[...]

> @@ -343,7 +343,21 @@ (define (files->files-directory files)
>    ;; leading to a build failure of "files.drv".
>    (assert-no-duplicates files)
>  
> -  (file-union "files" files))
> +  ;; Compute the file-union allowing dangling symlinks
> +  ;; This enables creating symlinks to locations out of store
> +  (computed-file
> +   "files"
> +   (with-imported-modules '((guix build utils))
> +     #~(begin
> +         (use-modules (guix build utils)
> +                      (ice-9 match))
> +         (mkdir #$output)
> +         (chdir #$output)
> +         (for-each (match-lambda
> +                     ((target source)
> +                      (mkdir-p (dirname target))
> +                      (symlink source target)))
> +                   '#$files)))))

Instead of more or less duplicating ‘file-union’, how about adding a
#:dangling-symlinks? argument to ‘file-union’ that would default to #f?

When set to #t, the ‘stat’ call would not be emitted.

That would reduce code duplication and make the intent clearer IMO.

Ludo’.




Information forwarded to sarg <at> sarg.org.ru, maxim.cournoyer <at> gmail.com, ludo <at> gnu.org, guix <at> cbaines.net, gabriel <at> erlikon.ch, dev <at> jpoiret.xyz, othacehe <at> gnu.org, zimon.toutoune <at> gmail.com, me <at> tobias.gr, guix-patches <at> gnu.org:
bug#78378; Package guix-patches. (Mon, 19 May 2025 09:51:02 GMT) Full text and rfc822 format available.

Message #20 received at 78378 <at> debbugs.gnu.org (full text, mbox):

From: Sergey Trofimov <sarg <at> sarg.org.ru>
To: 78378 <at> debbugs.gnu.org
Cc: Sergey Trofimov <sarg <at> sarg.org.ru>
Subject: [PATCH v1 1/3] gexp: Allow file-unions with dangling symlinks.
Date: Mon, 19 May 2025 11:50:08 +0200
* guix/gexp.scm (file-union): Add #:dangling-symlinks? parameter.

Change-Id: I09d44ec785fd7141b02dee2d8dc23ccc499aa933
---
 doc/guix.texi | 12 +++++++-----
 guix/gexp.scm | 19 ++++++++++---------
 2 files changed, 17 insertions(+), 14 deletions(-)

diff --git a/doc/guix.texi b/doc/guix.texi
index fd86551787..ef8504bb3e 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -12673,11 +12673,13 @@ G-Expressions
 This is the declarative counterpart of @code{text-file*}.
 @end deffn
 
-@deffn {Procedure} file-union name files
-Return a @code{<computed-file>} that builds a directory containing all of @var{files}.
-Each item in @var{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
-denoting the target file.  Here's an example:
+@deffn {Procedure} file-union name files [#:dangling-symlinks? #f]
+Return a @code{<computed-file>} that builds a directory containing all
+of @var{files}.  Each item in @var{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 denoting the target file.
+@code{#:dangling-symlinks?} controls if gexps must lower to an existing
+file.  Here's an example:
 
 @lisp
 (file-union "etc"
diff --git a/guix/gexp.scm b/guix/gexp.scm
index 8dd746eee0..85d049e26a 100644
--- a/guix/gexp.scm
+++ b/guix/gexp.scm
@@ -2144,7 +2144,7 @@ (define* (mixed-text-file name #:key guile #:rest text)
 
   (computed-file name build #:guile guile))
 
-(define* (file-union name files #:key guile)
+(define* (file-union name files #:key guile (dangling-symlinks? #f))
   "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
 file name to use in the new directory, and the second element is a gexp
@@ -2170,14 +2170,15 @@ (define* (file-union name files #:key guile)
                        (map (match-lambda
                               ((target source)
                                (gexp
-                                (begin
-                                  ;; Stat the source to abort early if it does
-                                  ;; not exist.
-                                  (stat (ungexp source))
-
-                                  (mkdir-p (dirname (ungexp target)))
-                                  (symlink (ungexp source)
-                                           (ungexp target))))))
+                                (let ((source (ungexp source))
+                                      (target (ungexp target)))
+                                  (unless (or (ungexp dangling-symlinks?)
+                                              (stat source #f))
+                                    (error (format #f "~a points to inexistent file or dangling symlink ~a"
+                                                   target source)))
+
+                                  (mkdir-p (dirname target))
+                                  (symlink source target)))))
                             files)))))
                  #:guile guile))
 

base-commit: 450a361532573a02389530a6a80b7821683ed41b
-- 
2.49.0





Information forwarded to sarg <at> sarg.org.ru, maxim.cournoyer <at> gmail.com, ludo <at> gnu.org, guix <at> cbaines.net, gabriel <at> erlikon.ch, dev <at> jpoiret.xyz, othacehe <at> gnu.org, zimon.toutoune <at> gmail.com, me <at> tobias.gr, guix-patches <at> gnu.org:
bug#78378; Package guix-patches. (Mon, 19 May 2025 09:51:02 GMT) Full text and rfc822 format available.

Message #23 received at 78378 <at> debbugs.gnu.org (full text, mbox):

From: Sergey Trofimov <sarg <at> sarg.org.ru>
To: 78378 <at> debbugs.gnu.org
Cc: Sergey Trofimov <sarg <at> sarg.org.ru>
Subject: [PATCH v1 2/3] gexp: Add symlink-to procedure.
Date: Mon, 19 May 2025 11:50:09 +0200
* guix/gexp.scm (symlink-to): New procedure.
* doc/guix.texi (G-Expressions): Document it.

Change-Id: I7c1ba3a29a4e5350cb4f196185b7171c4750b6b8
---
 doc/guix.texi | 11 +++++++++++
 guix/gexp.scm |  5 +++++
 2 files changed, 16 insertions(+)

diff --git a/doc/guix.texi b/doc/guix.texi
index ef8504bb3e..02f472246a 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -12692,6 +12692,17 @@ G-Expressions
 This yields an @code{etc} directory containing these two files.
 @end deffn
 
+@deffn {Procedure} symlink-to target
+Return a @code{<computed-file>} that is a symbolic link to target.
+Note, that the target does not need to exist at the build time.  One of
+uses is to put arbitrary symlinks into user's home:
+
+@lisp
+(service home-files-service-type
+  `(("Sync" ,(symlink-to "/storage/Sync"))))
+@end lisp
+@end deffn
+
 @deffn {Procedure} directory-union name things
 Return a directory that is the union of @var{things}, where @var{things} is a list of
 file-like objects denoting directories.  For example:
diff --git a/guix/gexp.scm b/guix/gexp.scm
index 85d049e26a..5cb5e8e4e4 100644
--- a/guix/gexp.scm
+++ b/guix/gexp.scm
@@ -119,6 +119,7 @@ (define-module (guix gexp)
             file-union
             directory-union
             references-file
+            symlink-to
 
             imported-files
             imported-modules
@@ -2182,6 +2183,10 @@ (define* (file-union name files #:key guile (dangling-symlinks? #f))
                             files)))))
                  #:guile guile))
 
+(define (symlink-to target)
+  "Return an object that is a symlink to TARGET."
+  (computed-file "link" (gexp (symlink (ungexp target) (ungexp output)))))
+
 (define* (directory-union name things
                           #:key (copy? #f) (quiet? #f)
                           (resolve-collision 'resolve-collision/default))
-- 
2.49.0





Information forwarded to sarg <at> sarg.org.ru, maxim.cournoyer <at> gmail.com, ludo <at> gnu.org, andrew <at> trop.in, hako <at> ultrarare.space, janneke <at> gnu.org, tanguy <at> bioneland.org, guix-patches <at> gnu.org:
bug#78378; Package guix-patches. (Mon, 19 May 2025 09:51:03 GMT) Full text and rfc822 format available.

Message #26 received at 78378 <at> debbugs.gnu.org (full text, mbox):

From: Sergey Trofimov <sarg <at> sarg.org.ru>
To: 78378 <at> debbugs.gnu.org
Cc: Sergey Trofimov <sarg <at> sarg.org.ru>
Subject: [PATCH v1 3/3] home: services: Build "files" union allowing dangling
 symlinks.
Date: Mon, 19 May 2025 11:50:10 +0200
* gnu/home/services.scm (files->files-directory): Build file union
without checking for existence of included items.

* tests/guix-home.sh: Verify symlinking files out of store works.

Change-Id: I94054003f4a6be944252ce7a397cf56f0b979554
---
 gnu/home/services.scm | 3 ++-
 tests/guix-home.sh    | 8 +++++++-
 2 files changed, 9 insertions(+), 2 deletions(-)

diff --git a/gnu/home/services.scm b/gnu/home/services.scm
index 2342dc5e07..c09e6cdadd 100644
--- a/gnu/home/services.scm
+++ b/gnu/home/services.scm
@@ -343,7 +343,8 @@ (define (files->files-directory files)
   ;; leading to a build failure of "files.drv".
   (assert-no-duplicates files)
 
-  (file-union "files" files))
+  ;; Allow symlinks to locations out of store
+  (file-union "files" files #:dangling-symlinks? #t))
 
 ;; Used by symlink-manager
 (define home-files-directory "files")
diff --git a/tests/guix-home.sh b/tests/guix-home.sh
index dbfe7dbd48..b8d90196f1 100644
--- a/tests/guix-home.sh
+++ b/tests/guix-home.sh
@@ -73,7 +73,9 @@ trap 'chmod -Rf +w "$test_directory"; rm -rf "$test_directory"' EXIT
                    (list `(".config/test.conf"
                            ,(plain-file
                              "tmp-file.txt"
-                             "the content of ~/.config/test.conf"))))
+                             "the content of ~/.config/test.conf"))
+
+                         `("symlink" ,(symlink-to "<test_directory>"))))
 
    (service home-bash-service-type
             (home-bash-configuration
@@ -104,6 +106,7 @@ trap 'chmod -Rf +w "$test_directory"; rm -rf "$test_directory"' EXIT
                        "# the content of bashrc-test-config.sh"))))))))
 EOF
 
+    sed -i "s,<test_directory>,$test_directory," home.scm
     echo -n "# dot-bashrc test file for guix home" > "dot-bashrc"
 
     # Check whether the graph commands work as expected.
@@ -126,6 +129,7 @@ EOF
 	guix home container home.scm -- cat '~/.config/test.conf' | \
 	    grep "the content of"
 	guix home container home.scm -- test -h '~/.bashrc'
+	guix home container home.scm -- test -h '~/symlink'
 	test "$(guix home container home.scm -- id -u)" = 1000
 	guix home container home.scm -- test -f '$HOME/sample/home.scm' && false
 	guix home container home.scm --expose="$PWD=$HOME/sample" -- \
@@ -153,6 +157,8 @@ EOF
     test -d "${HOME}/.guix-home"
     test -h "${HOME}/.bash_profile"
     test -h "${HOME}/.bashrc"
+    test -h "${HOME}/symlink"
+    test "$(readlink -f $HOME/symlink)" == "$test_directory"
     grep 'alias run="guix shell"' "$HOME/.bashrc"
     grep "alias path='echo \$PATH'" "$HOME/.bashrc"
     test "$(tail -n 2 "${HOME}/.bashrc")" == "\
-- 
2.49.0





Information forwarded to guix-patches <at> gnu.org:
bug#78378; Package guix-patches. (Mon, 19 May 2025 10:01:01 GMT) Full text and rfc822 format available.

Message #29 received at 78378 <at> debbugs.gnu.org (full text, mbox):

From: Sergey Trofimov <sarg <at> sarg.org.ru>
To: Ludovic Courtès <ludo <at> gnu.org>
Cc: Hilton Chain <hako <at> ultrarare.space>,
 Janneke Nieuwenhuizen <janneke <at> gnu.org>,
 Tanguy Le Carrour <tanguy <at> bioneland.org>, 78378 <at> debbugs.gnu.org,
 Andrew Tropin <andrew <at> trop.in>
Subject: Re: [bug#78378] [PATCH 2/2] home: services: Build "files" union
 allowing dangling symlinks.
Date: Mon, 19 May 2025 12:00:30 +0200
Hi Ludovic
Ludovic Courtès <ludo <at> gnu.org> writes:

> Hi Sergey,
>
> Sergey Trofimov <sarg <at> sarg.org.ru> writes:
>
>> * gnu/home/services.scm (files->files-directory): Build file union
>> without checking for existence of included items.
>>
>> * tests/guix-home.sh: Verify symlinking files out of store works.
>>
>> Change-Id: I94054003f4a6be944252ce7a397cf56f0b979554
>
> [...]
>
>> @@ -343,7 +343,21 @@ (define (files->files-directory files)
>>    ;; leading to a build failure of "files.drv".
>>    (assert-no-duplicates files)
>>  
>> -  (file-union "files" files))
>> +  ;; Compute the file-union allowing dangling symlinks
>> +  ;; This enables creating symlinks to locations out of store
>> +  (computed-file
>> +   "files"
>> +   (with-imported-modules '((guix build utils))
>> +     #~(begin
>> +         (use-modules (guix build utils)
>> +                      (ice-9 match))
>> +         (mkdir #$output)
>> +         (chdir #$output)
>> +         (for-each (match-lambda
>> +                     ((target source)
>> +                      (mkdir-p (dirname target))
>> +                      (symlink source target)))
>> +                   '#$files)))))
>
> Instead of more or less duplicating ‘file-union’, how about adding a
> #:dangling-symlinks? argument to ‘file-union’ that would default to #f?
>
> When set to #t, the ‘stat’ call would not be emitted.
>
> That would reduce code duplication and make the intent clearer IMO.
>
> Ludo’.

I've applied your suggestion in v1.




Reply sent to Maxim Cournoyer <maxim.cournoyer <at> gmail.com>:
You have taken responsibility. (Tue, 20 May 2025 23:15:02 GMT) Full text and rfc822 format available.

Notification sent to Sergey Trofimov <sarg <at> sarg.org.ru>:
bug acknowledged by developer. (Tue, 20 May 2025 23:15:03 GMT) Full text and rfc822 format available.

Message #34 received at 78378-done <at> debbugs.gnu.org (full text, mbox):

From: Maxim Cournoyer <maxim.cournoyer <at> gmail.com>
To: Sergey Trofimov <sarg <at> sarg.org.ru>
Cc: Josselin Poiret <dev <at> jpoiret.xyz>, Tobias Geerinckx-Rice <me <at> tobias.gr>,
 Simon Tournier <zimon.toutoune <at> gmail.com>, Mathieu Othacehe <othacehe <at> gnu.org>,
 Ludovic Courtès <ludo <at> gnu.org>,
 Gabriel Wicki <gabriel <at> erlikon.ch>, Christopher Baines <guix <at> cbaines.net>,
 78378-done <at> debbugs.gnu.org
Subject: Re: [bug#78378] [PATCH v1 1/3] gexp: Allow file-unions with
 dangling symlinks.
Date: Wed, 21 May 2025 08:14:25 +0900
Hi Sergey,

I've merged this series with the following small adjustments for 1/3:

--8<---------------cut here---------------start------------->8---
modified   guix/gexp.scm
@@ -2145,7 +2145,7 @@ (define* (mixed-text-file name #:key guile #:rest text)
 
   (computed-file name build #:guile guile))
 
-(define* (file-union name files #:key guile (dangling-symlinks? #f))
+(define* (file-union name files #:key guile dangling-symlinks?)
   "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
 file name to use in the new directory, and the second element is a gexp
@@ -2159,29 +2159,29 @@ (define* (file-union name files #:key guile (dangling-symlinks? #f))
                 (\"libvirt/qemu.conf\" ,(plain-file \"qemu.conf\" \"\"))))
 
 This yields an 'etc' directory containing these two files."
-  (computed-file name
-                 (with-imported-modules '((guix build utils))
-                   (gexp
-                    (begin
-                      (use-modules (guix build utils))
-
-                      (mkdir (ungexp output))
-                      (chdir (ungexp output))
-                      (ungexp-splicing
-                       (map (match-lambda
-                              ((target source)
-                               (gexp
-                                (let ((source (ungexp source))
-                                      (target (ungexp target)))
-                                  (unless (or (ungexp dangling-symlinks?)
-                                              (stat source #f))
-                                    (error (format #f "~a points to inexistent file or dangling symlink ~a"
-                                                   target source)))
-
-                                  (mkdir-p (dirname target))
-                                  (symlink source target)))))
-                            files)))))
-                 #:guile guile))
+  (computed-file
+   name
+   (with-imported-modules '((guix build utils))
+     (gexp
+      (begin
+        (use-modules (guix build utils))
+
+        (mkdir (ungexp output))
+        (chdir (ungexp output))
+        (ungexp-splicing
+         (map (match-lambda
+                ((target source)
+                 (gexp
+                  (let ((source (ungexp source))
+                        (target (ungexp target)))
+                    (unless (or (ungexp dangling-symlinks?)
+                                (stat source #f))
+                      (error (format #f "~a points to inexistent file \
+or dangling symlink ~a" target source)))
+                    (mkdir-p (dirname target))
+                    (symlink source target)))))
+              files)))))
+   #:guile guile))
 
 (define (symlink-to target)
   "Return an object that is a symlink to TARGET."
--8<---------------cut here---------------end--------------->8---

Mostly to meet the max line width of 80 columns.

And for 3/3:

--8<---------------cut here---------------start------------->8---
modified   gnu/home/services.scm
@@ -343,7 +343,7 @@ (define (files->files-directory files)
   ;; leading to a build failure of "files.drv".
   (assert-no-duplicates files)
 
-  ;; Allow symlinks to locations out of store
+  ;; Allow symlinks to locations outside the store.
   (file-union "files" files #:dangling-symlinks? #t))
 
 ;; Used by symlink-manager
--8<---------------cut here---------------end--------------->8---

e.g. adding missing punctuation for a standalone comment.

Pushed with commit 11bc17c409.

-- 
Thanks,
Maxim




This bug report was last modified 28 days ago.

Previous Next


GNU bug tracking system
Copyright (C) 1999 Darren O. Benham, 1997,2003 nCipher Corporation Ltd, 1994-97 Ian Jackson.