home.diff
1 | diff --git a/README.md b/README.md |
2 | index 6bd9d93..0a0e610 100644 |
3 | --- a/README.md |
4 | +++ b/README.md |
5 | @@ -41,21 +41,25 @@ section of this project: |
6 | |
7 | ### Making some room in your home directory |
8 | |
9 | -It is recommended to use this in a new install, when your home directory is |
10 | -still pretty empty. Since your home directory will be made into a Guix profile, |
11 | -you first want to create a new directory for your user data, for instance as |
12 | -root: |
13 | +Your home directory will be completely taken over by Guix. In particular, when |
14 | +using the home manager, your home directory is entirely read-only. A read-only |
15 | +home directory is not very useful though, so users of the home manager will have |
16 | +to use a separate directory for their documents, caches and states. This is |
17 | +typically `/data/alice` for user alice. |
18 | + |
19 | +It is not required to set up that directory beforehand, but if you do, you will |
20 | +not be able to use the home manager until you have completely wiped-out your |
21 | +home directory (i.e. transfered it to the new directory). If the directory |
22 | +does not yet exist, your current home directory is automatically renamed to |
23 | +that directory, and the home manager starts working. |
24 | + |
25 | +Basically, you will run (as root): |
26 | |
27 | ```bash |
28 | -mkdir -p /data/alice |
29 | -chown alice: /data/alice |
30 | +mkdir /data |
31 | +mv /home/alice /data/alice |
32 | ``` |
33 | |
34 | -if your user is named alice. Then, move all your data over to that directory. |
35 | -Do not transfer your configuration, it will be useless. That transfering of data |
36 | -is the reason why it's simpler to start with an empty home: there is no data to |
37 | -transfer ;) |
38 | - |
39 | Once that is done, some parts of your home directory will still have to be |
40 | read-write. This is mostly `~/.cache`, `~/.local` but also `~/.guix-profile` and |
41 | `~/.config/guix`. Inside your new data directory, create them like this, as your |
42 | @@ -66,6 +70,13 @@ cd /data/alice |
43 | mkdir-p .local/share .cache .config |
44 | ``` |
45 | |
46 | +Since you have moved your entire home directory, make sure you can still access |
47 | +your own copy of guix and your user profile by (temporarily) setting your |
48 | +`$PATH` (make sure it starts with `/data/alice/.config/guix/current/bin`) and |
49 | +by sourcing the profile with `export GUIX_PROFILE=/data/alice/.guix-profile; |
50 | +source $GUIX_PROFILE/etc/profile`. You might also need to run `hash -r` |
51 | +(no output) for bash to clear all its memorized binary locations. |
52 | + |
53 | ### Creating the first home generation |
54 | |
55 | To create your first home configuration, you must create a configuration file. |
56 | @@ -74,8 +85,8 @@ For instance, create `/data/alice/.config/guix/home.scm`: |
57 | ```scheme |
58 | (use-modules (home)) |
59 | |
60 | -(home "/data/alice" |
61 | - '()) |
62 | +(home |
63 | + (data-directory "/data/alice")) |
64 | ``` |
65 | |
66 | This will generate a completely empty home, except for essential configurations, |
67 | @@ -87,23 +98,7 @@ To build your first generation of your home environment, run as your regular |
68 | user: |
69 | |
70 | ```bash |
71 | -guix package -p /var/guix/profiles/per-user/alice/home \ |
72 | - -f /data/alice/.config/guix/home.scm |
73 | -``` |
74 | - |
75 | -Still as your regular user, copy your `~/.config/guix` to your data directory. |
76 | -This will ensure you can still use Guix after you switch to the managed home |
77 | -profile: |
78 | - |
79 | -```bash |
80 | -cp -ar ~/.config/guix /data/alice/.config/ |
81 | -``` |
82 | - |
83 | -Finaly, switch to the managed home profile as root: |
84 | - |
85 | -```bash |
86 | -mv /home/alice{,.bak} # keep a backup in case something goes wrong |
87 | -ln -sv /var/guix/profiles/per-user/alice/home /home/alice |
88 | +guix home reconfigure /data/alice/.config/guix/home.scm |
89 | ``` |
90 | |
91 | That's it! |
92 | @@ -121,4 +116,4 @@ over the world! |
93 | |
94 | If you are less into code, we welcome contributions in the form of documentation, |
95 | translation, issues, reviews, tips and tricks. Do not hesitate to get in touch if |
96 | -you have an idea or want to help in any way! |
97 | \ No newline at end of file |
98 | +you have an idea or want to help in any way! |
99 | diff --git a/doc/README.md b/doc/README.md |
100 | index 1ade3a5..384294a 100644 |
101 | --- a/doc/README.md |
102 | +++ b/doc/README.md |
103 | @@ -36,12 +36,14 @@ with "-home", you know that you can use it in the list of configurations, like |
104 | this: |
105 | |
106 | ```scheme |
107 | -(home "/data/alice" |
108 | - (list (something-home ...) |
109 | - (something-else-home ...) |
110 | - (other-stuff-home ...) |
111 | - (yet-another-config-home ...) |
112 | - ...)) |
113 | +(home |
114 | + (data-directory "/data/alice") |
115 | + (configurations |
116 | + (list (something-home ...) |
117 | + (something-else-home ...) |
118 | + (other-stuff-home ...) |
119 | + (yet-another-config-home ...) |
120 | + ...))) |
121 | ``` |
122 | |
123 | #### Desktop and Window Managers |
124 | @@ -69,4 +71,4 @@ Unfortunately, that means you cannot configure pulseaudio through Guix. You can |
125 | also add a similar line to your desktop or window manager's configuration to |
126 | instruct it to start pulseaudio. However, pulseaudio sometimes crashes for non |
127 | obvious reasons, and no graphical program will be able to restart it automatically |
128 | -with a proper configuration. |
129 | \ No newline at end of file |
130 | +with a proper configuration. |
131 | diff --git a/doc/general.md b/doc/general.md |
132 | index f6abd1b..23fd91f 100644 |
133 | --- a/doc/general.md |
134 | +++ b/doc/general.md |
135 | @@ -66,8 +66,8 @@ Build-side Utilities |
136 | The `(home build utils)` extends the utilities provided by `(guix build utils)` |
137 | with the following procedure: |
138 | |
139 | -**Scheme Procedure**: (home-file outputs path ...) |
140 | +**Scheme Procedure**: (home-file output path ...) |
141 | |
142 | -Return the complete path to the output of a package being defined by adding |
143 | -"/" between each component of _path_. _outputs_ is the content of `%build-output` |
144 | -in the package definition. This is not very useful for end users. |
145 | +Return the complete path to the output of a gexp being defined by adding |
146 | +"/" between each component of _path_. _output_ is the content of `#$output` |
147 | +in the package definition. |
148 | diff --git a/doc/install.md b/doc/install.md |
149 | index 16b8149..bda7456 100644 |
150 | --- a/doc/install.md |
151 | +++ b/doc/install.md |
152 | @@ -28,21 +28,25 @@ Usage |
153 | |
154 | ### Making some room in your home directory |
155 | |
156 | -It is recommended to use this in a new install, when your home directory is |
157 | -still pretty empty. Since your home directory will be made into a Guix profile, |
158 | -you first want to create a new directory for your user data, for instance as |
159 | -root: |
160 | +Your home directory will be completely taken over by Guix. In particular, when |
161 | +using the home manager, your home directory is entirely read-only. A read-only |
162 | +home directory is not very useful though, so users of the home manager will have |
163 | +to use a separate directory for their documents, caches and states. This is |
164 | +typically `/data/alice` for user alice. |
165 | + |
166 | +It is not required to set up that directory beforehand, but if you do, you will |
167 | +not be able to use the home manager until you have completely wiped-out your |
168 | +home directory (i.e. transfered it to the new directory). If the directory |
169 | +does not yet exist, your current home directory is automatically renamed to |
170 | +that directory, and the home manager starts working. |
171 | + |
172 | +Basically, you will run (as root): |
173 | |
174 | ```bash |
175 | -mkdir -p /data/alice |
176 | -chown alice: /data/alice |
177 | +mkdir /data |
178 | +mv /home/alice /data/alice |
179 | ``` |
180 | |
181 | -if your user is named alice. Then, move all your data over to that directory. |
182 | -Do not transfer your configuration, it will be useless. That transfering of data |
183 | -is the reason why it's simpler to start with an empty home: there is no data to |
184 | -transfer ;) |
185 | - |
186 | Once that is done, some parts of your home directory will still have to be |
187 | read-write. This is mostly `~/.cache`, `~/.local` but also `~/.guix-profile` and |
188 | `~/.config/guix`. Inside your new data directory, create them like this, as your |
189 | @@ -53,6 +57,13 @@ cd /data/alice |
190 | mkdir-p .local/share .cache .config |
191 | ``` |
192 | |
193 | +Since you have moved your entire home directory, make sure you can still access |
194 | +your own copy of guix and your user profile by (temporarily) setting your |
195 | +`$PATH` (make sure it starts with `/data/alice/.config/guix/current/bin`) and |
196 | +by sourcing the profile with `export GUIX_PROFILE=/data/alice/.guix-profile; |
197 | +source $GUIX_PROFILE/etc/profile`. You might also need to run `hash -r` |
198 | +(no output) for bash to clear all its memorized binary locations. |
199 | + |
200 | ### Creating the first home generation |
201 | |
202 | To create your first home configuration, you must create a configuration file. |
203 | @@ -61,8 +72,8 @@ For instance, create `/data/alice/.config/guix/home.scm`: |
204 | ```scheme |
205 | (use-modules (home)) |
206 | |
207 | -(home "/data/alice" |
208 | - '()) |
209 | +(home |
210 | + (data-directory "/data/alice")) |
211 | ``` |
212 | |
213 | This will generate a completely empty home, except for essential configurations, |
214 | @@ -74,23 +85,7 @@ To build your first generation of your home environment, run as your regular |
215 | user: |
216 | |
217 | ```bash |
218 | -guix package -p /var/guix/profiles/per-user/alice/home \ |
219 | - -f /data/alice/.config/guix/home.scm |
220 | +guix home reconfigure /data/alice/.config/guix/home.scm |
221 | ``` |
222 | |
223 | -Still as your regular user, copy your `~/.config/guix` to your data directory. |
224 | -This will ensure you can still use Guix after you switch to the managed home |
225 | -profile: |
226 | - |
227 | -```bash |
228 | -cp -ar ~/.config/guix /data/alice/.config/ |
229 | -``` |
230 | - |
231 | -Finaly, switch to the managed home profile as root: |
232 | - |
233 | -```bash |
234 | -mv /home/alice{,.bak} # keep a backup in case something goes wrong |
235 | -ln -sv /var/guix/profiles/per-user/alice/home /home/alice |
236 | -``` |
237 | - |
238 | -That's it! |
239 | \ No newline at end of file |
240 | +That's it! |
241 | diff --git a/guix/scripts/home.scm b/guix/scripts/home.scm |
242 | index d4b54ea..76a7fe5 100644 |
243 | --- a/guix/scripts/home.scm |
244 | +++ b/guix/scripts/home.scm |
245 | @@ -17,9 +17,21 @@ |
246 | ;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>. |
247 | |
248 | (define-module (guix scripts home) |
249 | + #:use-module (guix derivations) |
250 | + #:use-module (guix grafts) |
251 | + #:use-module (guix monads) |
252 | + #:use-module (guix packages) |
253 | + #:use-module (guix profiles) |
254 | #:use-module (guix scripts) |
255 | + #:use-module (guix scripts build) |
256 | + #:use-module (guix status) |
257 | + #:use-module (guix store) |
258 | #:use-module (guix ui) |
259 | #:use-module (guix utils) |
260 | + #:use-module (home) |
261 | + #:use-module (ice-9 match) |
262 | + #:use-module (srfi srfi-1) |
263 | + #:use-module (srfi srfi-26) |
264 | #:use-module (srfi srfi-37) |
265 | #:export (guix-home)) |
266 | |
267 | @@ -37,8 +49,16 @@ |
268 | (show-version-and-exit "guix edit"))))) |
269 | |
270 | (define (show-help) |
271 | - (display (G_ "Usage: guix home CONFIG |
272 | -Manage a user home environment according to CONFIG\n")) |
273 | + (display (G_ "Usage: guix home [OPTION ...] ACTION [ARG ...] [FILE] |
274 | +Manage a user home environment according to FILE and ACTION. Some actions |
275 | +support additional ARGs.\n")) |
276 | + (display (G_ "The valid values for ACTION are:\n")) |
277 | + (newline) |
278 | + (display (G_ "\ |
279 | + reconfigure switch to or create a new home configuration\n")) |
280 | + (display (G_ "\ |
281 | + build build the home configuration without installing anything\n")) |
282 | + (show-build-options-help) |
283 | (display (G_ " |
284 | -h, --help display this help and exit")) |
285 | (display (G_ " |
286 | @@ -46,19 +66,276 @@ Manage a user home environment according to CONFIG\n")) |
287 | (newline) |
288 | (show-bug-report-information)) |
289 | |
290 | +(define %options |
291 | + ;; Specifications of the command-line options. |
292 | + (cons* (option '(#\h "help") #f #f |
293 | + (lambda args |
294 | + (show-help) |
295 | + (exit 0))) |
296 | + (option '(#\V "version") #f #f |
297 | + (lambda args |
298 | + (show-version-and-exit "guix system"))) |
299 | + (option '(#\e "expression") #t #f |
300 | + (lambda (opt name arg result) |
301 | + (alist-cons 'expression arg result))) |
302 | + (option '(#\d "derivation") #f #f |
303 | + (lambda (opt name arg result) |
304 | + (alist-cons 'derivations-only? #t result))) |
305 | + (option '("on-error") #t #f |
306 | + (lambda (opt name arg result) |
307 | + (alist-cons 'on-error (string->symbol arg) |
308 | + result))) |
309 | + (option '(#\t "file-system-type") #t #f |
310 | + (lambda (opt name arg result) |
311 | + (alist-cons 'file-system-type arg |
312 | + result))) |
313 | + (option '("image-size") #t #f |
314 | + (lambda (opt name arg result) |
315 | + (alist-cons 'image-size (size->number arg) |
316 | + result))) |
317 | + (option '(#\N "network") #f #f |
318 | + (lambda (opt name arg result) |
319 | + (alist-cons 'container-shared-network? #t result))) |
320 | + (option '("no-bootloader" "no-grub") #f #f |
321 | + (lambda (opt name arg result) |
322 | + (alist-cons 'install-bootloader? #f result))) |
323 | + (option '("full-boot") #f #f |
324 | + (lambda (opt name arg result) |
325 | + (alist-cons 'full-boot? #t result))) |
326 | + (option '("skip-checks") #f #f |
327 | + (lambda (opt name arg result) |
328 | + (alist-cons 'skip-safety-checks? #t result))) |
329 | + |
330 | + (option '("share") #t #f |
331 | + (lambda (opt name arg result) |
332 | + (alist-cons 'file-system-mapping |
333 | + (specification->file-system-mapping arg #t) |
334 | + result))) |
335 | + (option '("expose") #t #f |
336 | + (lambda (opt name arg result) |
337 | + (alist-cons 'file-system-mapping |
338 | + (specification->file-system-mapping arg #f) |
339 | + result))) |
340 | + |
341 | + (option '(#\n "dry-run") #f #f |
342 | + (lambda (opt name arg result) |
343 | + (alist-cons 'dry-run? #t (alist-cons 'graft? #f result)))) |
344 | + (option '(#\v "verbosity") #t #f |
345 | + (lambda (opt name arg result) |
346 | + (let ((level (string->number* arg))) |
347 | + (alist-cons 'verbosity level |
348 | + (alist-delete 'verbosity result))))) |
349 | + (option '(#\s "system") #t #f |
350 | + (lambda (opt name arg result) |
351 | + (alist-cons 'system arg |
352 | + (alist-delete 'system result eq?)))) |
353 | + (option '(#\r "root") #t #f |
354 | + (lambda (opt name arg result) |
355 | + (alist-cons 'gc-root arg result))) |
356 | + %standard-build-options)) |
357 | + |
358 | (define %default-options |
359 | - `((system . ,(%current-system)))) |
360 | + ;; Alist of default option values. |
361 | + `((system . ,(%current-system)) |
362 | + (substitutes? . #t) |
363 | + (build-hook? . #t) |
364 | + (print-build-trace? . #t) |
365 | + (print-extended-build-trace? . #t) |
366 | + (multiplexed-build-output? . #t) |
367 | + (graft? . #t) |
368 | + (debug . 0) |
369 | + (verbosity . #f) ;default |
370 | + (file-system-type . "ext4") |
371 | + (image-size . guess) |
372 | + (install-bootloader? . #t))) |
373 | + |
374 | +;;; |
375 | +;;; Profiles |
376 | +;;; |
377 | + |
378 | +(define %user-module |
379 | + ;; Module in which the machine description file is loaded. |
380 | + (make-user-module '())) |
381 | + |
382 | +(define %home (getenv "HOME")) |
383 | + |
384 | +(define %current-home |
385 | + (string-append %profile-directory "/home")) |
386 | + |
387 | +(define (ensure-home-profile data-directory) |
388 | + "Ensures $HOME is a symlink to the profile. If it is not yet the case, move |
389 | +it to the @var{data-directory} directory, unless it already exists, in which case |
390 | +report an error." |
391 | + (ensure-profile-directory) |
392 | + |
393 | + (when %home %current-home |
394 | + (let ((home (false-if-exception (lstat %home)))) |
395 | + (if home |
396 | + (if (false-if-exception (lstat data-directory)) |
397 | + (rename-file %home data-directory) |
398 | + (leav (G_ "Your $HOME directory (~a) is not a symlink to a profile, |
399 | +and it cannot be moved as ~a already exists on the filesystem.~%") |
400 | + %home data-directory)) |
401 | + (symlink %current-home %home))))) |
402 | |
403 | ;;; |
404 | ;;; Entry point. |
405 | ;;; |
406 | |
407 | +(define* (perform-action action home |
408 | + #:key |
409 | + dry-run? derivations-only? |
410 | + use-substitutes?) |
411 | + "Perform ACTION for HOME. When DERIVATIONS-ONLY? is true, print the |
412 | +derivation file name(s) without building anything." |
413 | + (define println |
414 | + (cut format #t "~a~%" <>)) |
415 | + |
416 | + (when (eq? action 'reconfigure) |
417 | + (ensure-home-profile (home-data-directory home)) |
418 | + (maybe-suggest-running-guix-pull)) |
419 | + |
420 | + (with-store store |
421 | + (let* ((drv (run-with-store store (home->derivation home))) |
422 | + (profile (derivation->output-path drv))) |
423 | + (show-what-to-build store (list drv) |
424 | + #:use-substitutes? use-substitutes? |
425 | + #:dry-run? dry-run?) |
426 | + |
427 | + (unless (or dry-run? derivations-only?) |
428 | + (begin |
429 | + (build-derivations store (list drv)) |
430 | + (case action |
431 | + ((reconfigure) |
432 | + (newline) |
433 | + (format #t (G_ "activating home...~%")) |
434 | + (let ((number (generation-number %current-home)) |
435 | + (generation (generation-file-name %current-home number))) |
436 | + (switch-symlinks generation profile) |
437 | + (switch-symlinks %current-home generation))) |
438 | + (else |
439 | + (display profile) |
440 | + (newline)))))))) |
441 | + |
442 | +(define (process-action action args opts) |
443 | + "Process ACTION, a sub-command, with the arguments are listed in ARGS. |
444 | +ACTION must be one of the sub-commands that takes an operating system |
445 | +declaration as an argument (a file name.) OPTS is the raw alist of options |
446 | +resulting from command-line parsing." |
447 | + (define (ensure-home-configuration file-or-exp obj) |
448 | + (unless (home? obj) |
449 | + (leave (G_ "'~a' does not return a home configuration~%") |
450 | + file-or-exp)) |
451 | + obj) |
452 | + |
453 | + (let* ((file (match args |
454 | + (() #f) |
455 | + ((x . _) x))) |
456 | + (expr (assoc-ref opts 'expression)) |
457 | + (system (assoc-ref opts 'system)) |
458 | + (home (ensure-home-configuration |
459 | + (or file expr) |
460 | + (cond |
461 | + ((and expr file) |
462 | + (leave |
463 | + (G_ "both file and expression cannot be specified~%"))) |
464 | + (expr |
465 | + (read/eval expr)) |
466 | + (file |
467 | + (load* file %user-module |
468 | + #:on-error (assoc-ref opts 'on-error))) |
469 | + (else |
470 | + (leave (G_ "no configuration specified~%")))))) |
471 | + |
472 | + (dry? (assoc-ref opts 'dry-run?))) |
473 | + |
474 | + (with-store store |
475 | + (set-build-options-from-command-line store opts) |
476 | + |
477 | + (set-guile-for-build (default-guile)) |
478 | + |
479 | + (case action |
480 | + (else |
481 | + (unless (eq? action 'build) |
482 | + (warn-about-old-distro #:suggested-command |
483 | + "guix home reconfigure")) |
484 | + |
485 | + (perform-action action home |
486 | + #:dry-run? dry? |
487 | + #:derivations-only? (assoc-ref opts |
488 | + 'derivations-only?) |
489 | + #:use-substitutes? (assoc-ref opts 'substitutes?))))) |
490 | + (warn-about-disk-space))) |
491 | + |
492 | +(define (resolve-subcommand name) |
493 | + (let ((module (resolve-interface |
494 | + `(guix scripts home ,(string->symbol name)))) |
495 | + (proc (string->symbol (string-append "guix-home-" name)))) |
496 | + (module-ref module proc))) |
497 | + |
498 | +(define (process-command command args opts) |
499 | + "Process COMMAND, one of the 'guix system' sub-commands. ARGS is its |
500 | +argument list and OPTS is the option alist." |
501 | + (case command |
502 | + ;; The following commands do not need to use the store, and they do not need |
503 | + ;; an operating system configuration file. |
504 | + ;; The following commands need to use the store, but they do not need an |
505 | + ;; operating system configuration file. |
506 | + ;; The following commands need to use the store, and they also |
507 | + ;; need an operating system configuration file. |
508 | + (else (process-action command args opts)))) |
509 | + |
510 | (define (guix-home . args) |
511 | + (define (parse-sub-command arg result) |
512 | + ;; Parse sub-command ARG and augment RESULT accordingly. |
513 | + (if (assoc-ref result 'action) |
514 | + (alist-cons 'argument arg result) |
515 | + (let ((action (string->symbol arg))) |
516 | + (case action |
517 | + ((build reconfigure) |
518 | + (alist-cons 'action action result)) |
519 | + (else (leave (G_ "~a: unknown action~%") action)))))) |
520 | + |
521 | + (define (match-pair car) |
522 | + ;; Return a procedure that matches a pair with CAR. |
523 | + (match-lambda |
524 | + ((head . tail) |
525 | + (and (eq? car head) tail)) |
526 | + (_ #f))) |
527 | + |
528 | + (define (option-arguments opts) |
529 | + ;; Extract the plain arguments from OPTS. |
530 | + (let* ((args (reverse (filter-map (match-pair 'argument) opts))) |
531 | + (count (length args)) |
532 | + (action (assoc-ref opts 'action)) |
533 | + (expr (assoc-ref opts 'expression))) |
534 | + (define (fail) |
535 | + (leave (G_ "wrong number of arguments for action '~a'~%") |
536 | + action)) |
537 | + |
538 | + (unless action |
539 | + (format (current-error-port) |
540 | + (G_ "guix home: missing command name~%")) |
541 | + (format (current-error-port) |
542 | + (G_ "Try 'guix home --help' for more information.~%")) |
543 | + (exit 1)) |
544 | + |
545 | + (case action |
546 | + ((build reconfigure) |
547 | + (unless (= count 1) |
548 | + (fail)))) |
549 | + args)) |
550 | + |
551 | (with-error-handling |
552 | (let* ((opts (parse-command-line args %options |
553 | (list %default-options) |
554 | - #:build-options? #f))) |
555 | - (format #t "Guix Home Test~%"))) |
556 | - #t) |
557 | + #:argument-handler |
558 | + parse-sub-command)) |
559 | + (args (option-arguments opts)) |
560 | + (command (assoc-ref opts 'action))) |
561 | + (parameterize ((%graft? (assoc-ref opts 'graft?))) |
562 | + (with-status-verbosity (or (assoc-ref opts 'verbosity) |
563 | + (if (eq? command 'build) 2 1)) |
564 | + (process-command command args opts)))))) |
565 | |
566 | ;;; home.scm ends here |
567 | diff --git a/home.scm b/home.scm |
568 | index 0a3c03a..99ff98f 100644 |
569 | --- a/home.scm |
570 | +++ b/home.scm |
571 | @@ -22,56 +22,71 @@ |
572 | #:use-module (guix gexp) |
573 | #:use-module (guix licenses) |
574 | #:use-module (guix packages) |
575 | + #:use-module (guix records) |
576 | + #:use-module (ice-9 match) |
577 | #:use-module (home build utils) |
578 | - #:export (home |
579 | - use-home-modules)) |
580 | + #:export (use-home-modules |
581 | + home |
582 | + home? |
583 | + home-data-directory |
584 | + home-guix-symlink |
585 | + home-guix-config-symlink |
586 | + home-local-symlink |
587 | + home-cache-symlink |
588 | + home->derivation)) |
589 | |
590 | (define-syntax use-home-modules |
591 | (syntax-rules () |
592 | ((_ modules ...) |
593 | (use-modules (home modules) ...)))) |
594 | |
595 | -(define* (home basedir inputs #:key |
596 | - (guix-symlink (string-append basedir "/.guix-profile")) |
597 | - (guix-config-symlink (string-append basedir "/.config/guix")) |
598 | - (local-symlink (string-append basedir "/.local")) |
599 | - (cache-symlink (string-append basedir "/.cache"))) |
600 | - (define union |
601 | - (computed-file "home" |
602 | +(define-record-type* <home> home |
603 | + make-home |
604 | + home? |
605 | + (data-directory home-data-directory) |
606 | + (guix-symlink home-guix-symlink (thunked) |
607 | + (default (string-append |
608 | + (home-data-directory this-record) |
609 | + "/.guix-profile"))) |
610 | + (guix-config-symlink home-guix-config-symlink (thunked) |
611 | + (default (string-append |
612 | + (home-data-directory this-record) |
613 | + "/.config/guix"))) |
614 | + (local-symlink home-local-symlink (thunked) |
615 | + (default (string-append |
616 | + (home-data-directory this-record) |
617 | + "/.local"))) |
618 | + (cache-symlink home-cache-symlink (thunked) |
619 | + (default (string-append |
620 | + (home-data-directory this-record) |
621 | + "/.cache"))) |
622 | + (configurations home-configurations |
623 | + (default '()))) |
624 | + |
625 | +(define (home->derivation home) |
626 | + (define builder |
627 | + (with-imported-modules |
628 | + '((guix build utils) (home build utils)) |
629 | #~(begin |
630 | - (use-modules (guix build union)) |
631 | - (union-build #$output '#$inputs)) |
632 | - #:options |
633 | - '(#:local-build? #t |
634 | - #:modules ((guix build union))))) |
635 | - (package |
636 | - (name "guix-home") |
637 | - (version "0") |
638 | - (source #f) |
639 | - (build-system trivial-build-system) |
640 | - (arguments |
641 | - `(#:modules ((guix build utils) (home build utils)) |
642 | - #:builder |
643 | - (begin |
644 | - (use-modules (guix build utils) (home build utils)) |
645 | - (mkdir-p (home-file %outputs ".config")) |
646 | - ;; For guix |
647 | - (symlink ,guix-config-symlink (home-file %outputs ".config/guix")) |
648 | - (symlink ,guix-symlink (home-file %outputs ".guix-profile")) |
649 | - ;; symlink writeable directories |
650 | - (symlink ,local-symlink (home-file %outputs ".local")) |
651 | - (symlink ,cache-symlink (home-file %outputs ".cache")) |
652 | - ;; rest of the files |
653 | - (with-directory-excursion (assoc-ref %build-inputs "union") |
654 | - (for-each |
655 | - (lambda (f) |
656 | - (mkdir-p (home-file %outputs (dirname f))) |
657 | - (symlink (string-append (assoc-ref %build-inputs "union") "/" f) |
658 | - (home-file %outputs f))) |
659 | - (find-files "." ".*")))))) |
660 | - (inputs |
661 | - `(("union" ,union))) |
662 | - (home-page "") |
663 | - (synopsis "") |
664 | - (description "") |
665 | - (license gpl3+))) |
666 | \ No newline at end of file |
667 | + (use-modules (guix build utils) (home build utils)) |
668 | + (mkdir-p (home-file #$output ".config")) |
669 | + ;; For guix |
670 | + (symlink #$(home-guix-config-symlink home) (home-file #$output ".config/guix")) |
671 | + (symlink #$(home-guix-symlink home) (home-file #$output ".guix-profile")) |
672 | + ;; symlink writeable directories |
673 | + (symlink #$(home-local-symlink home) (home-file #$output ".local")) |
674 | + (symlink #$(home-cache-symlink home) (home-file #$output ".cache")) |
675 | + ;; rest of the files |
676 | + (for-each |
677 | + (lambda (config) |
678 | + (with-directory-excursion config |
679 | + (for-each |
680 | + (lambda (f) |
681 | + (mkdir-p (home-file #$output (dirname f))) |
682 | + (symlink (home-file config f) |
683 | + (home-file #$output f))) |
684 | + (find-files "." ".")))) |
685 | + (list #$@(home-configurations home)))))) |
686 | + (gexp->derivation "home" builder |
687 | + #:substitutable? #f |
688 | + #:local-build? #t)) |
689 | diff --git a/home/build/utils.scm b/home/build/utils.scm |
690 | index 19b66a9..832af28 100644 |
691 | --- a/home/build/utils.scm |
692 | +++ b/home/build/utils.scm |
693 | @@ -18,5 +18,5 @@ |
694 | (define-module (home build utils) |
695 | #:export (home-file)) |
696 | |
697 | -(define (home-file outputs . path) |
698 | - (apply string-append (assoc-ref outputs "out") "/" path)) |
699 | \ No newline at end of file |
700 | +(define (home-file output . path) |
701 | + (apply string-append output "/" path)) |
702 |