Subject: Re: bug#52808: Guix home should not assume that all targets are dot files

From: Andrew Tropin <[email-masked]>
Date: Tue, 29 Mar 2022 13:24:12 +0300

On 2022-03-20 22:00, Ludovic Courtès wrote:

> I wrote:
>
>> I finally got around to committing it as
>> 6da2a5a5655668f42ec5b26f875ddbc498e132b6.  Thank you!
>
> I hit “close” too quickly: we still need the patch that changes
> ‘home-files-service-type’ and/or symlink-manager.scm to not prepend a
> dot, so reopening!  :-)
>
> Ludo’.

Those patches introduce a breaking change, but the surface and number of
people affected should be small if everyone migrated to
xdg-configuration-files.  It removes the special handling of dot files
in symlink-manager and doesn't add a leading dot automatically.

Please, merge them on April 8.

From 1b556cda9716eba31a8a6dd9d3c263988de26ccf Mon Sep 17 00:00:00 2001
From: Andrew Tropin <[email-masked]>
Date: Tue, 29 Mar 2022 11:28:30 +0300
Subject: [PATCH 1/2] home: symlink-manager: Remove appending of leading dot.

* gnu/home/services.scm (xdg-configuration-files-directory): Add leading dot.
* gnu/home/services.scm (xdg-configuration-files-service-type): Change name.
* gnu/home/services/shells.scm (add-shell-profile-file,
zsh-get-configuration-files, add-zsh-dot-configuration,
add-zsh-xdg-configuration, add-bash-configuration): Add leading dots.
* gnu/home/services/symlink-manager.scm (update-symlinks-script): Remove
leading dot.
---
 gnu/home/services.scm                 |  8 ++++----
 gnu/home/services/shells.scm          | 20 ++++++++++----------
 gnu/home/services/symlink-manager.scm |  2 +-
 gnu/home/services/xdg.scm             |  2 +-
 4 files changed, 16 insertions(+), 16 deletions(-)

diff --git a/gnu/home/services.scm b/gnu/home/services.scm
index 2f441eb968..17acfcdb09 100644
--- a/gnu/home/services.scm
+++ b/gnu/home/services.scm
@@ -285,10 +285,10 @@ (define home-files-service-type
                 (description "Files that will be put in
 @file{~~/.guix-home/files}, and further processed during activation.")))
 
-(define xdg-configuration-files-directory "config")
+(define xdg-configuration-files-directory ".config")
 
 (define (xdg-configuration-files files)
-  "Add config/ prefix to each file-path in FILES."
+  "Add .config/ prefix to each file-path in FILES."
   (map (match-lambda
          ((file-path . rest)
           (cons (string-append xdg-configuration-files-directory "/" file-path)
@@ -296,7 +296,7 @@ (define (xdg-configuration-files files)
          files))
 
 (define home-xdg-configuration-files-service-type
-  (service-type (name 'home-files)
+  (service-type (name 'home-xdg-configuration)
                 (extensions
                  (list (service-extension home-files-service-type
                                           xdg-configuration-files)))
@@ -304,7 +304,7 @@ (define home-xdg-configuration-files-service-type
                 (extend append)
                 (default-value '())
                 (description "Files that will be put in
-@file{~~/.guix-home/files/config}, and further processed during activation.")))
+@file{~~/.guix-home/files/.config}, and further processed during activation.")))
 
 (define %initialize-gettext
   #~(begin
diff --git a/gnu/home/services/shells.scm b/gnu/home/services/shells.scm
index 086fe7d8c4..8389968c96 100644
--- a/gnu/home/services/shells.scm
+++ b/gnu/home/services/shells.scm
@@ -77,7 +77,7 @@ (define-configuration home-shell-profile-configuration
 really know what you do."))
 
 (define (add-shell-profile-file config)
-  `(("profile"
+  `((".profile"
      ,(mixed-text-file
        "shell-profile"
        "\
@@ -211,16 +211,16 @@ (define (zsh-file-by-field config field)
         (zsh-serialize-field config field)))))
 
 (define (zsh-get-configuration-files config)
-  `(("zprofile" ,(zsh-file-by-field config 'zprofile)) ;; Always non-empty
+  `((".zprofile" ,(zsh-file-by-field config 'zprofile)) ;; Always non-empty
     ,@(if (and (zsh-field-not-empty? config 'zshenv)
                (zsh-field-not-empty? config 'environment-variables))
-          `(("zshenv" ,(zsh-file-by-field config 'zshenv))) '())
+          `((".zshenv" ,(zsh-file-by-field config 'zshenv))) '())
     ,@(if (zsh-field-not-empty? config 'zshrc)
-          `(("zshrc" ,(zsh-file-by-field config 'zshrc))) '())
+          `((".zshrc" ,(zsh-file-by-field config 'zshrc))) '())
     ,@(if (zsh-field-not-empty? config 'zlogin)
-          `(("zlogin" ,(zsh-file-by-field config 'zlogin))) '())
+          `((".zlogin" ,(zsh-file-by-field config 'zlogin))) '())
     ,@(if (zsh-field-not-empty? config 'zlogout)
-          `(("zlogout" ,(zsh-file-by-field config 'zlogout))) '())))
+          `((".zlogout" ,(zsh-file-by-field config 'zlogout))) '())))
 
 (define (add-zsh-dot-configuration config)
   (define zshenv-auxiliary-file
@@ -230,14 +230,14 @@ (define zshenv-auxiliary-file
      "[[ -f $ZDOTDIR/.zshenv ]] && source $ZDOTDIR/.zshenv\n"))
 
   (if (home-zsh-configuration-xdg-flavor? config)
-      `(("zshenv" ,zshenv-auxiliary-file))
+      `((".zshenv" ,zshenv-auxiliary-file))
       (zsh-get-configuration-files config)))
 
 (define (add-zsh-xdg-configuration config)
   (if (home-zsh-configuration-xdg-flavor? config)
       (map
        (lambda (lst)
-         (cons (string-append "zsh/." (car lst))
+         (cons (string-append "zsh/" (car lst))
                (cdr lst)))
        (zsh-get-configuration-files config))
       '()))
@@ -430,7 +430,7 @@ (define* (file-if-not-empty field #:optional (extra-content #f))
           (field-obj (car (filter-fields field))))
       (if (or extra-content
               (not (null? ((configuration-field-getter field-obj) config))))
-          `(,(object->snake-case-string file-name)
+          `(,(string-append "." (object->snake-case-string file-name))
             ,(apply mixed-text-file
                     (object->snake-case-string file-name)
                     (append (or extra-content '())
@@ -439,7 +439,7 @@ (define* (file-if-not-empty field #:optional (extra-content #f))
 
   (filter
    (compose not null?)
-   `(("bash_profile"
+   `((".bash_profile"
       ,(mixed-text-file
         "bash_profile"
         "\
diff --git a/gnu/home/services/symlink-manager.scm b/gnu/home/services/symlink-manager.scm
index 80ca73fed8..23ab1e3955 100644
--- a/gnu/home/services/symlink-manager.scm
+++ b/gnu/home/services/symlink-manager.scm
@@ -67,7 +67,7 @@ (define (preprocess-file file)
                            (1+ (string-length home-directory)))
                 (substring file
                            (string-length #$xdg-configuration-files-directory)))
-               (string-append "." file)))
+               file))
 
          (define (target-file file)
            ;; Return the target of FILE, a config file name sans leading dot
diff --git a/gnu/home/services/xdg.scm b/gnu/home/services/xdg.scm
index 361a2a6148..3b504d7d09 100644
--- a/gnu/home/services/xdg.scm
+++ b/gnu/home/services/xdg.scm
@@ -421,7 +421,7 @@ (define (home-xdg-mime-applications-files config)
   (define (add-xdg-desktop-entry-file entry)
     (let ((file (first entry))
           (config (second entry)))
-      (list (format #f "local/share/applications/~a" file)
+      (list (format #f ".local/share/applications/~a" file)
           (apply mixed-text-file
                  (format #f "xdg-desktop-~a-entry" file)
                  config))))
-- 
2.34.0

From 5e1f45fa9ea1aca16843dc85d7d21fd46f3cfcb8 Mon Sep 17 00:00:00 2001
From: Andrew Tropin <[email-masked]>
Date: Tue, 29 Mar 2022 12:47:39 +0300
Subject: [PATCH 2/2] home: Add home-xdg-data-files-service-type.

* gnu/home/services.scm (home-xdg-data-files-service-type): New variable.
* gnu/home/services/symlink-manager.scm (update-symlinks-script): Add a proper
handling for XDG_DATA_HOME value.
* gnu/home/services/xdg.scm (home-xdg-mime-applications-service-type): Use
home-xdg-data-files service.
---
 gnu/home/services.scm                 | 25 +++++++++++++++++++++++++
 gnu/home/services/symlink-manager.scm | 25 ++++++++++++++++++-------
 gnu/home/services/xdg.scm             |  5 +++--
 3 files changed, 46 insertions(+), 9 deletions(-)

diff --git a/gnu/home/services.scm b/gnu/home/services.scm
index 17acfcdb09..49bd6e3555 100644
--- a/gnu/home/services.scm
+++ b/gnu/home/services.scm
@@ -39,6 +39,7 @@ (define-module (gnu home services)
             home-environment-variables-service-type
             home-files-service-type
             home-xdg-configuration-files-service-type
+            home-xdg-data-files-service-type
             home-run-on-first-login-service-type
             home-activation-service-type
             home-run-on-change-service-type
@@ -46,6 +47,7 @@ (define-module (gnu home services)
 
             home-files-directory
             xdg-configuration-files-directory
+            xdg-data-files-directory
 
             fold-home-service-types
             home-provenance
@@ -306,6 +308,29 @@ (define home-xdg-configuration-files-service-type
                 (description "Files that will be put in
 @file{~~/.guix-home/files/.config}, and further processed during activation.")))
 
+(define xdg-data-files-directory ".local/share")
+
+(define (xdg-data-files files)
+  "Add .local/share prefix to each file-path in FILES."
+  (map (match-lambda
+         ((file-path . rest)
+          (cons (string-append xdg-data-files-directory "/" file-path)
+                rest)))
+         files))
+
+(define home-xdg-data-files-service-type
+  (service-type (name 'home-xdg-data)
+                (extensions
+                 (list (service-extension home-files-service-type
+                                          xdg-data-files)))
+                (compose concatenate)
+                (extend append)
+                (default-value '())
+                (description "Files that will be put in
+@file{~~/.guix-home/files/.local/share}, and further processed during
+activation.")))
+
+
 (define %initialize-gettext
   #~(begin
       (bindtextdomain %gettext-domain
diff --git a/gnu/home/services/symlink-manager.scm b/gnu/home/services/symlink-manager.scm
index 23ab1e3955..6d19258ec7 100644
--- a/gnu/home/services/symlink-manager.scm
+++ b/gnu/home/services/symlink-manager.scm
@@ -54,6 +54,10 @@ (define xdg-config-home
            (or (getenv "XDG_CONFIG_HOME")
                (string-append (getenv "HOME") "/.config")))
 
+         (define xdg-data-home
+           (or (getenv "XDG_DATA_HOME")
+               (string-append (getenv "HOME") "/.local/share")))
+
          (define backup-directory
            (string-append home-directory "/" (number->string (current-time))
                           "-guix-home-legacy-configs-backup"))
@@ -61,13 +65,20 @@ (define backup-directory
          (define (preprocess-file file)
            "If file is in XDG-CONFIGURATION-FILES-DIRECTORY use
 subdirectory from XDG_CONFIG_HOME to generate a target path."
-           (if (string-prefix? #$xdg-configuration-files-directory file)
-               (string-append
-                (substring xdg-config-home
-                           (1+ (string-length home-directory)))
-                (substring file
-                           (string-length #$xdg-configuration-files-directory)))
-               file))
+           (cond
+            ((string-prefix? #$xdg-configuration-files-directory file)
+             (string-append
+              (substring xdg-config-home
+                         (1+ (string-length home-directory)))
+              (substring file
+                         (string-length #$xdg-configuration-files-directory))))
+            ((string-prefix? #$xdg-data-files-directory file)
+             (string-append
+              (substring xdg-data-home
+                         (1+ (string-length home-directory)))
+              (substring file
+                         (string-length #$xdg-data-files-directory))))
+            (else file)))
 
          (define (target-file file)
            ;; Return the target of FILE, a config file name sans leading dot
diff --git a/gnu/home/services/xdg.scm b/gnu/home/services/xdg.scm
index 3b504d7d09..71c028c788 100644
--- a/gnu/home/services/xdg.scm
+++ b/gnu/home/services/xdg.scm
@@ -421,7 +421,8 @@ (define (home-xdg-mime-applications-files config)
   (define (add-xdg-desktop-entry-file entry)
     (let ((file (first entry))
           (config (second entry)))
-      (list (format #f ".local/share/applications/~a" file)
+      ;; TODO: Use xdg-data-files instead of home-files here
+      (list (format #f "applications/~a" file)
           (apply mixed-text-file
                  (format #f "xdg-desktop-~a-entry" file)
                  config))))
@@ -468,7 +469,7 @@ (define home-xdg-mime-applications-service-type
   (service-type (name 'home-xdg-mime-applications)
                 (extensions
                  (list (service-extension
-                        home-files-service-type
+                        home-xdg-data-files-service-type
                         home-xdg-mime-applications-files)
                        (service-extension
                         home-xdg-configuration-files-service-type
-- 
2.34.0

-- 
Best regards,
Andrew Tropin