summaryrefslogtreecommitdiff
path: root/gnu/home
diff options
context:
space:
mode:
authorGiacomo Leidi <goodoldpaul@autistici.org>2024-03-06 21:52:42 +0100
committerLudovic Courtès <ludo@gnu.org>2024-03-06 23:25:51 +0100
commit01f685d56016ae529381a73daedccc1949b808ec (patch)
tree61935a2682dcfa69ae4929acd7c896ca6433b4f2 /gnu/home
parent9e3061a163abcae5ccd3823ba3d8f757a0478e40 (diff)
gnu: home: dotfiles: Properly support both plain and Stow directory layouts.
Fixes <https://issues.guix.gnu.org/68848>. The current implementation of the home-dotfiles-service-type contradicts the Guix manual. This patch properly implements both the plain and Stow dotfiles directory layouts. It does so by refactoring home-dotfiles-configuration adding a new packages field to support GNU Stow's users workflow and introducing a new layout field to switch between the two directory layouts. * gnu/home/services/dotfiles (home-dotfiles-configuration): Migrate to (gnu services configuration); [packages]: new field; [layout]: new field; (strip-stow-dotfile): new variable; (strip-plain-dotfile): new variable; (home-dotfiles-configuration->files): use the new fields; [directory-contents]: allow for selecting a subset of application dotfile directories; * doc/guix.texi: document the new layouts. Change-Id: I2e96037608353e360828290f055ec5271cfdfd48 Signed-off-by: Ludovic Courtès <ludo@gnu.org>
Diffstat (limited to 'gnu/home')
-rw-r--r--gnu/home/services/dotfiles.scm115
1 files changed, 88 insertions, 27 deletions
diff --git a/gnu/home/services/dotfiles.scm b/gnu/home/services/dotfiles.scm
index 6a740c42ce4..823bdb03fb4 100644
--- a/gnu/home/services/dotfiles.scm
+++ b/gnu/home/services/dotfiles.scm
@@ -20,17 +20,25 @@
20(define-module (gnu home services dotfiles) 20(define-module (gnu home services dotfiles)
21 #:use-module (gnu home services) 21 #:use-module (gnu home services)
22 #:use-module (gnu services) 22 #:use-module (gnu services)
23 #:use-module (gnu services configuration)
23 #:autoload (guix build utils) (find-files) 24 #:autoload (guix build utils) (find-files)
25 #:use-module (guix diagnostics)
24 #:use-module (guix gexp) 26 #:use-module (guix gexp)
25 #:use-module (guix records) 27 #:use-module (guix i18n)
26 #:use-module ((guix utils) #:select (current-source-directory)) 28 #:use-module ((guix utils) #:select (current-source-directory))
27 #:use-module (srfi srfi-1) 29 #:use-module (srfi srfi-1)
28 #:use-module (ice-9 ftw) 30 #:use-module (ice-9 ftw)
31 #:use-module (ice-9 match)
29 #:use-module (ice-9 regex) 32 #:use-module (ice-9 regex)
30 #:export (home-dotfiles-service-type 33 #:export (home-dotfiles-service-type
34 home-dotfiles-configuration->files
35
31 home-dotfiles-configuration 36 home-dotfiles-configuration
32 home-dotfiles-configuration? 37 home-dotfiles-configuration?
38 home-dotfiles-configuration-fields
39 home-dotfiles-configuration-layout
33 home-dotfiles-configuration-source-directory 40 home-dotfiles-configuration-source-directory
41 home-dotfiles-configuration-packages
34 home-dotfiles-configuration-directories 42 home-dotfiles-configuration-directories
35 home-dotfiles-configuration-excluded)) 43 home-dotfiles-configuration-excluded))
36 44
@@ -40,26 +48,64 @@
40 "\\.git" 48 "\\.git"
41 "\\.gitignore")) 49 "\\.gitignore"))
42 50
43(define-record-type* <home-dotfiles-configuration> 51(define %home-dotfiles-layouts
44 home-dotfiles-configuration make-home-dotfiles-configuration 52 '(plain stow))
45 home-dotfiles-configuration? 53
46 (source-directory home-dotfiles-configuration-source-directory 54(define (sanitize-layout value)
47 (default (current-source-directory)) 55 (if (member value %home-dotfiles-layouts)
48 (innate)) 56 value
49 (directories home-dotfiles-configuration-directories ;list of strings 57 (raise
50 (default '())) 58 (formatted-message
51 (excluded home-dotfiles-configuration-excluded ;list of strings 59 (G_ "layout field of home-dotfiles-configuration should be either 'plain
52 (default %home-dotfiles-excluded))) 60or 'stow, but ~a was found.")
53 61 value))))
54(define (import-dotfiles directory files) 62
63(define list-of-strings?
64 (list-of string?))
65
66(define-maybe list-of-strings)
67
68(define-configuration/no-serialization home-dotfiles-configuration
69 (source-directory
70 (string (current-source-directory))
71 "The path where dotfile directories are resolved. By default dotfile
72directories are resolved relative the source location where
73@code{home-dotfiles-configuration} appears.")
74 (layout
75 (symbol 'plain)
76 "The intended layout of the specified @code{directory}. It can be either
77@code{'stow} or @code{'plain}."
78 (sanitizer sanitize-layout))
79 (directories
80 (list-of-strings '())
81 "The list of dotfiles directories where @code{home-dotfiles-service-type}
82will look for application dotfiles.")
83 (packages
84 (maybe-list-of-strings)
85 "The names of a subset of the GNU Stow package layer directories. When provided
86the @code{home-dotfiles-service-type} will only provision dotfiles from this
87subset of applications. This field will be ignored if @code{layout} is set
88to @code{'plain}.")
89 (excluded
90 (list-of-strings %home-dotfiles-excluded)
91 "The list of file patterns @code{home-dotfiles-service-type} will exclude
92while visiting @code{directory}."))
93
94(define (strip-stow-dotfile file-name directory)
95 (let ((dotfile-name (string-drop file-name (1+ (string-length directory)))))
96 (match (string-split dotfile-name #\/)
97 ((package parts ...)
98 (string-join parts "/")))))
99
100(define (strip-plain-dotfile file-name directory)
101 (string-drop file-name (+ 1 (string-length directory))))
102
103(define (import-dotfiles directory files strip)
55 "Return a list of objects compatible with @code{home-files-service-type}'s 104 "Return a list of objects compatible with @code{home-files-service-type}'s
56value. Each object is a pair where the first element is the relative path 105value. Each object is a pair where the first element is the relative path
57of a file and the second is a gexp representing the file content. Objects are 106of a file and the second is a gexp representing the file content. Objects are
58generated by recursively visiting DIRECTORY and mapping its contents to the 107generated by recursively visiting DIRECTORY and mapping its contents to the
59user's home directory, excluding files that match any of the patterns in EXCLUDED." 108user's home directory, excluding files that match any of the patterns in EXCLUDED."
60 (define (strip file)
61 (string-drop file (+ 1 (string-length directory))))
62
63 (define (format file) 109 (define (format file)
64 ;; Remove from FILE characters that cannot be used in the store. 110 ;; Remove from FILE characters that cannot be used in the store.
65 (string-append 111 (string-append
@@ -73,7 +119,7 @@ user's home directory, excluding files that match any of the patterns in EXCLUDE
73 file))) 119 file)))
74 120
75 (map (lambda (file) 121 (map (lambda (file)
76 (let ((stripped (strip file))) 122 (let ((stripped (strip file directory)))
77 (list stripped 123 (list stripped
78 (local-file file (format stripped) 124 (local-file file (format stripped)
79 #:recursive? #t)))) 125 #:recursive? #t))))
@@ -81,18 +127,25 @@ user's home directory, excluding files that match any of the patterns in EXCLUDE
81 127
82(define (home-dotfiles-configuration->files config) 128(define (home-dotfiles-configuration->files config)
83 "Return a list of objects compatible with @code{home-files-service-type}'s 129 "Return a list of objects compatible with @code{home-files-service-type}'s
84value, generated following GNU Stow's algorithm for each of the 130value, excluding files that match any of the patterns configured."
85directories in CONFIG, excluding files that match any of the patterns configured." 131 (define stow? (eq? (home-dotfiles-configuration-layout config) 'stow))
86 (define excluded 132 (define excluded
87 (home-dotfiles-configuration-excluded config)) 133 (home-dotfiles-configuration-excluded config))
88 (define exclusion-rx 134 (define exclusion-rx
89 (make-regexp (string-append "^.*(" (string-join excluded "|") ")$"))) 135 (make-regexp (string-append "^.*(" (string-join excluded "|") ")$")))
90 136
91 (define (directory-contents directory) 137 (define* (directory-contents directory #:key (packages #f))
92 (find-files directory 138 (define (filter-files directory)
93 (lambda (file stat) 139 (find-files directory
94 (not (regexp-exec exclusion-rx 140 (lambda (file stat)
95 (basename file)))))) 141 (not (regexp-exec exclusion-rx
142 (basename file))))))
143 (if (and stow? packages (maybe-value-set? packages))
144 (append-map filter-files
145 (map (lambda (pkg)
146 (string-append directory "/" pkg))
147 packages))
148 (filter-files directory)))
96 149
97 (define (resolve directory) 150 (define (resolve directory)
98 ;; Resolve DIRECTORY relative to the 'source-directory' field of CONFIG. 151 ;; Resolve DIRECTORY relative to the 'source-directory' field of CONFIG.
@@ -103,15 +156,23 @@ directories in CONFIG, excluding files that match any of the patterns configured
103 156
104 (append-map (lambda (directory) 157 (append-map (lambda (directory)
105 (let* ((directory (resolve directory)) 158 (let* ((directory (resolve directory))
106 (contents (directory-contents directory))) 159 (packages
107 (import-dotfiles directory contents))) 160 (home-dotfiles-configuration-packages config))
161 (contents
162 (directory-contents directory
163 #:packages packages))
164 (strip
165 (if stow? strip-stow-dotfile strip-plain-dotfile)))
166 (import-dotfiles directory contents strip)))
108 (home-dotfiles-configuration-directories config))) 167 (home-dotfiles-configuration-directories config)))
109 168
110(define-public home-dotfiles-service-type 169(define-public home-dotfiles-service-type
111 (service-type (name 'home-dotfiles) 170 (service-type (name 'home-dotfiles)
112 (extensions 171 (extensions
113 (list (service-extension home-files-service-type 172 (list (service-extension home-files-service-type
114 home-dotfiles-configuration->files))) 173 (lambda (config)
174 (when config
175 (home-dotfiles-configuration->files config))))))
115 (default-value (home-dotfiles-configuration)) 176 (default-value (home-dotfiles-configuration))
116 (description "Files that will be put in the user's home directory 177 (description "Files that will be put in the user's home directory
117following GNU Stow's algorithm, and further processed during activation."))) 178following GNU Stow's algorithm, and further processed during activation.")))