GNU bug report logs - #50296
[PATCH 0/2] Add 'guix home' command.

Previous Next

Package: guix-patches;

Reported by: Andrew Tropin <andrew <at> trop.in>

Date: Tue, 31 Aug 2021 09:31:01 UTC

Severity: normal

Tags: patch

Done: Oleg Pykhalov <go.wigust <at> gmail.com>

Bug is archived. No further changes may be made.

To add a comment to this bug, you must first unarchive it, by sending
a message to control AT debbugs.gnu.org, with unarchive 50296 in the body.
You can then email your comments to 50296 AT debbugs.gnu.org in the normal way.

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

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


Report forwarded to guix-patches <at> gnu.org:
bug#50296; Package guix-patches. (Tue, 31 Aug 2021 09:31:01 GMT) Full text and rfc822 format available.

Acknowledgement sent to Andrew Tropin <andrew <at> trop.in>:
New bug report received and forwarded. Copy sent to guix-patches <at> gnu.org. (Tue, 31 Aug 2021 09:31:01 GMT) Full text and rfc822 format available.

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

From: Andrew Tropin <andrew <at> trop.in>
To: guix-patches <at> gnu.org
Subject: [PATCH 0/2] Add 'guix home' command.
Date: Tue, 31 Aug 2021 12:28:12 +0300
[Message part 1 (text/plain, inline)]
Command and subbcommands allowing to manage home environment with guix.

Andrew Tropin (2):
  scripts: Add 'guix home'.
  scripts: home: Add import subcommand.

 Makefile.am                  |   3 +
 guix/scripts/home.scm        | 512 +++++++++++++++++++++++++++++++++++
 guix/scripts/home/import.scm | 241 +++++++++++++++++
 3 files changed, 756 insertions(+)
 create mode 100644 guix/scripts/home.scm
 create mode 100644 guix/scripts/home/import.scm

-- 
2.33.0

[signature.asc (application/pgp-signature, inline)]

Information forwarded to guix-patches <at> gnu.org:
bug#50296; Package guix-patches. (Tue, 31 Aug 2021 09:41:01 GMT) Full text and rfc822 format available.

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

From: Andrew Tropin <andrew <at> trop.in>
To: 50296 <at> debbugs.gnu.org
Subject: [PATCH 1/2] scripts: Add 'guix home'.
Date: Tue, 31 Aug 2021 12:40:08 +0300
[Message part 1 (text/plain, inline)]
* guix/scripts/home.scm: New file.
* Makefile.am (MODULES): Add it.
---
 Makefile.am           |   2 +
 guix/scripts/home.scm | 512 ++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 514 insertions(+)
 create mode 100644 guix/scripts/home.scm

diff --git a/Makefile.am b/Makefile.am
index 327d3f9961..d44360c034 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -15,6 +15,7 @@
 # Copyright © 2018 Alex Vong <alexvong1995 <at> gmail.com>
 # Copyright © 2019 Efraim Flashner <efraim <at> flashner.co.il>
 # Copyright © 2021 Chris Marusich <cmmarusich <at> gmail.com>
+# Copyright © 2021 Andrew Tropin <andrew <at> trop.in>
 #
 # This file is part of GNU Guix.
 #
@@ -294,6 +295,7 @@ MODULES =					\
   guix/scripts/system.scm			\
   guix/scripts/system/search.scm		\
   guix/scripts/system/reconfigure.scm		\
+  guix/scripts/home.scm			\
   guix/scripts/lint.scm				\
   guix/scripts/challenge.scm			\
   guix/scripts/import/crate.scm			\
diff --git a/guix/scripts/home.scm b/guix/scripts/home.scm
new file mode 100644
index 0000000000..9eb5c0c917
--- /dev/null
+++ b/guix/scripts/home.scm
@@ -0,0 +1,512 @@
+;;; GNU Guix --- Functional package management for GNU
+;;; Copyright © 2021 Andrew Tropin <andrew <at> trop.in>
+;;; Copyright © 2021 Xinglu Chen <public <at> yoctocell.xyz>
+;;;
+;;; This file is part of GNU Guix.
+;;;
+;;; GNU Guix is free software; you can redistribute it and/or modify it
+;;; under the terms of the GNU General Public License as published by
+;;; the Free Software Foundation; either version 3 of the License, or (at
+;;; your option) any later version.
+;;;
+;;; GNU Guix is distributed in the hope that it will be useful, but
+;;; WITHOUT ANY WARRANTY; without even the implied warranty of
+;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;;; GNU General Public License for more details.
+;;;
+;;; You should have received a copy of the GNU General Public License
+;;; along with GNU Guix.  If not, see <http://www.gnu.org/licenses/>.
+
+(define-module (guix scripts home)
+  #:use-module (gnu packages admin)
+  #:use-module ((gnu services) #:hide (delete))
+  #:use-module (gnu packages)
+  #:use-module (gnu home)
+  #:use-module (gnu home-services)
+  #:use-module (guix channels)
+  #:use-module (guix derivations)
+  #:use-module (guix ui)
+  #:use-module (guix grafts)
+  #:use-module (guix packages)
+  #:use-module (guix profiles)
+  #:use-module (guix store)
+  #:use-module (guix utils)
+  #:use-module (guix scripts)
+  #:use-module (guix scripts package)
+  #:use-module (guix scripts build)
+  #:use-module (guix scripts system search)
+  #:autoload   (guix scripts pull) (channel-commit-hyperlink)
+  ;; #:use-module (guix scripts home import)
+  #:use-module ((guix status) #:select (with-status-verbosity))
+  #:use-module (guix gexp)
+  #:use-module (guix monads)
+  #:use-module (srfi srfi-1)
+  #:use-module (srfi srfi-26)
+  #:use-module (srfi srfi-35)
+  #:use-module (srfi srfi-37)
+  #:use-module (ice-9 match)
+  #:export (guix-home))
+
+
+;;;
+;;; Options.
+;;;
+
+(define %user-module
+  (make-user-module '((gnu home))))
+
+(define %guix-home
+  (string-append %profile-directory "/guix-home"))
+
+(define (show-help)
+  (display (G_ "Usage: guix home [OPTION ...] ACTION [ARG ...] [FILE]
+Build the home environment declared in FILE according to ACTION.
+Some ACTIONS support additional ARGS.\n"))
+    (newline)
+  (display (G_ "The valid values for ACTION are:\n"))
+  (newline)
+  (display (G_ "\
+   search             search for existing service types\n"))
+  (display (G_ "\
+   reconfigure        switch to a new home environment configuration\n"))
+  (display (G_ "\
+   roll-back          switch to the previous home environment configuration\n"))
+  (display (G_ "\
+   describe           describe the current home environment\n"))
+  (display (G_ "\
+   list-generations   list the home environment generations\n"))
+  (display (G_ "\
+   switch-generation  switch to an existing home environment configuration\n"))
+  (display (G_ "\
+   delete-generations delete old home environment generations\n"))
+  (display (G_ "\
+   build              build the home environment without installing anything\n"))
+  (display (G_ "\
+   import             generates a home environment definition from dotfiles\n"))
+
+  (show-build-options-help)
+  (display (G_ "
+  -v, --verbosity=LEVEL  use the given verbosity LEVEL"))
+  (newline)
+  (display (G_ "
+  -h, --help             display this help and exit"))
+  (display (G_ "
+  -V, --version          display version information and exit"))
+  (newline)
+  (show-bug-report-information))
+
+(define (verbosity-level opts)
+  "Return the verbosity level based on OPTS, the alist of parsed options."
+  (or (assoc-ref opts 'verbosity)
+      (if (eq? (assoc-ref opts 'action) 'build)
+          2 1)))
+
+(define %options
+  ;; Specification of the command-line options.
+  (cons* (option '(#\h "help") #f #f
+                 (lambda args
+                   (show-help)
+                   (exit 0)))
+         (option '(#\V "version") #f #f
+                 (lambda args
+                   (show-version-and-exit "guix show")))
+         (option '(#\v "verbosity") #t #f
+                 (lambda (opt name arg result)
+                   (let ((level (string->number* arg)))
+                     (alist-cons 'verbosity level
+                                 (alist-delete 'verbosity result)))))
+         %standard-build-options))
+
+(define %default-options
+  `((build-mode . ,(build-mode normal))
+    (graft? . #t)
+    (substitutes? . #t)
+    (offload? . #t)
+    (print-build-trace? . #t)
+    (print-extended-build-trace? . #t)
+    (multiplexed-build-output? . #t)
+    (verbosity . 3)
+    (debug . 0)))
+
+
+;;;
+;;; Actions.
+;;;
+
+(define* (perform-action action he
+                         #:key
+                         dry-run?
+                         derivations-only?
+                         use-substitutes?)
+  "Perform ACTION for home environment. "
+
+  (define println
+    (cut format #t "~a~%" <>))
+
+  (mlet* %store-monad
+      ((he-drv   (home-environment-derivation he))
+       (drvs     (mapm/accumulate-builds lower-object (list he-drv)))
+       (%        (if derivations-only?
+                     (return
+                      (for-each (compose println derivation-file-name) drvs))
+                     (built-derivations drvs)))
+
+       (he-out-path -> (derivation->output-path he-drv)))
+    (if (or dry-run? derivations-only?)
+        (return #f)
+        (begin
+          (for-each (compose println derivation->output-path) drvs)
+
+          (case action
+            ((reconfigure)
+             (let* ((number (generation-number %guix-home))
+                    (generation (generation-file-name
+                                 %guix-home (+ 1 number))))
+
+               (switch-symlinks generation he-out-path)
+               (switch-symlinks %guix-home generation)
+               (setenv "GUIX_NEW_HOME" he-out-path)
+               (primitive-load (string-append he-out-path "/activate"))
+               (setenv "GUIX_NEW_HOME" #f)
+               (return he-out-path)))
+            (else
+             (newline)
+             (return he-out-path)))))))
+
+(define (process-action action args opts)
+  "Process ACTION, a sub-command, with the arguments are listed in ARGS.
+ACTION must be one of the sub-commands that takes a home environment
+declaration as an argument (a file name.)  OPTS is the raw alist of options
+resulting from command-line parsing."
+  (define (ensure-home-environment file-or-exp obj)
+    (unless (home-environment? obj)
+      (leave (G_ "'~a' does not return a home environment ~%")
+             file-or-exp))
+    obj)
+
+  (let* ((file   (match args
+                   (() #f)
+                   ((x . _) x)))
+         (expr   (assoc-ref opts 'expression))
+         (system (assoc-ref opts 'system))
+
+         (transform   (lambda (obj)
+                        (home-environment-with-provenance obj file)))
+
+         (home-environment
+          (transform
+           (ensure-home-environment
+            (or file expr)
+            (cond
+             ((and expr file)
+              (leave
+               (G_ "both file and expression cannot be specified~%")))
+             (expr
+              (read/eval expr))
+             (file
+              (load* file %user-module
+                     #:on-error (assoc-ref opts 'on-error)))
+             (else
+              (leave (G_ "no configuration specified~%")))))))
+
+         (dry?        (assoc-ref opts 'dry-run?)))
+
+    (with-store store
+      (set-build-options-from-command-line store opts)
+      (with-build-handler (build-notifier #:use-substitutes?
+                                          (assoc-ref opts 'substitutes?)
+                                          #:verbosity
+                                          (verbosity-level opts)
+                                          #:dry-run?
+                                          (assoc-ref opts 'dry-run?))
+
+        (run-with-store store
+          (mbegin %store-monad
+            (set-guile-for-build (default-guile))
+
+            (case action
+              (else
+               (perform-action action home-environment
+                               #:dry-run? dry?
+                               #:derivations-only? (assoc-ref opts 'derivations-only?)
+                               #:use-substitutes? (assoc-ref opts 'substitutes?))
+               ))))))
+    (warn-about-disk-space)))
+
+
+(define (process-command command args opts)
+  "Process COMMAND, one of the 'guix home' sub-commands.  ARGS is its
+argument list and OPTS is the option alist."
+  (define-syntax-rule (with-store* store exp ...)
+    (with-store store
+      (set-build-options-from-command-line store opts)
+      exp ...))
+  (case command
+    ;; The following commands do not need to use the store, and they do not need
+    ;; an home environment file.
+    ((search)
+     (apply search args))
+    ((import)
+     (let* ((profiles (delete-duplicates
+                      (match (filter-map (match-lambda
+                                           (('profile . p) p)
+                                           (_              #f))
+                                         opts)
+                        (() (list %current-profile))
+                        (lst (reverse lst)))))
+           (manifest (concatenate-manifests
+                      (map profile-manifest profiles))))
+       (import-manifest manifest (current-output-port))))
+    ((describe)
+     (match (generation-number %guix-home)
+       (0
+        (error (G_ "no home environment generation, nothing to describe~%")))
+       (generation
+        (display-home-environment-generation generation))))
+    ((list-generations)
+     (let ((pattern (match args
+                      (() #f)
+                      ((pattern) pattern)
+                      (x (leave (G_ "wrong number of arguments~%"))))))
+       (list-generations pattern)))
+    ((switch-generation)
+     (let ((pattern (match args
+                      ((pattern) pattern)
+                      (x (leave (G_ "wrong number of arguments~%"))))))
+       (with-store* store
+                    (switch-to-home-environment-generation store pattern))))
+    ((roll-back)
+     (let ((pattern (match args
+                      (() "")
+                      (x (leave (G_ "wrong number of arguments~%"))))))
+       (with-store* store
+                    (roll-back-home-environment store))))
+    ((delete-generations)
+     (let ((pattern (match args
+                      (() #f)
+                      ((pattern) pattern)
+                      (x (leave (G_ "wrong number of arguments~%"))))))
+       (with-store*
+        store
+        (delete-matching-generations store %guix-home pattern))))
+    (else (process-action command args opts))))
+
+(define-command (guix-home . args)
+  (synopsis "build and deploy home environments")
+
+  (define (parse-sub-command arg result)
+    ;; Parse sub-command ARG and augment RESULT accordingly.
+    (if (assoc-ref result 'action)
+        (alist-cons 'argument arg result)
+        (let ((action (string->symbol arg)))
+          (case action
+            ((build
+              reconfigure
+              extension-graph shepherd-graph
+              list-generations describe
+              delete-generations roll-back
+              switch-generation search
+              import)
+             (alist-cons 'action action result))
+            (else (leave (G_ "~a: unknown action~%") action))))))
+
+  (define (match-pair car)
+    ;; Return a procedure that matches a pair with CAR.
+    (match-lambda
+      ((head . tail)
+       (and (eq? car head) tail))
+      (_ #f)))
+
+  (define (option-arguments opts)
+    ;; Extract the plain arguments from OPTS.
+    (let* ((args   (reverse (filter-map (match-pair 'argument) opts)))
+           (count  (length args))
+           (action (assoc-ref opts 'action))
+           (expr   (assoc-ref opts 'expression)))
+      (define (fail)
+        (leave (G_ "wrong number of arguments for action '~a'~%")
+               action))
+
+      (unless action
+        (format (current-error-port)
+                (G_ "guix home: missing command name~%"))
+        (format (current-error-port)
+                (G_ "Try 'guix home --help' for more information.~%"))
+        (exit 1))
+
+      (case action
+        ((build reconfigure)
+         (unless (or (= count 1)
+                     (and expr (= count 0)))
+           (fail)))
+        ((init)
+         (unless (= count 2)
+           (fail))))
+      args))
+
+  (with-error-handling
+    (let* ((opts     (parse-command-line args %options
+                                         (list %default-options)
+                                         #:argument-handler
+                                         parse-sub-command))
+           (args     (option-arguments opts))
+           (command  (assoc-ref opts 'action)))
+      (parameterize ((%graft? (assoc-ref opts 'graft?)))
+        (with-status-verbosity (verbosity-level opts)
+          (process-command command args opts))))))
+
+
+;;;
+;;; Searching.
+;;;
+
+(define service-type-name*
+  (compose symbol->string service-type-name))
+
+(define (service-type-description-string type)
+  "Return the rendered and localised description of TYPE, a service type."
+  (and=> (service-type-description type)
+         (compose texi->plain-text P_)))
+
+(define %service-type-metrics
+  ;; Metrics used to estimate the relevance of a search result.
+  `((,service-type-name* . 3)
+    (,service-type-description-string . 2)
+    (,(lambda (type)
+        (match (and=> (service-type-location type) location-file)
+          ((? string? file)
+           (basename file ".scm"))
+          (#f
+           "")))
+     . 1)))
+
+(define (find-service-types regexps)
+  "Return a list of service type/score pairs: service types whose name or
+description matches REGEXPS sorted by relevance, and their score."
+  (let ((matches (fold-home-service-types
+                  (lambda (type result)
+                    (match (relevance type regexps
+                                      %service-type-metrics)
+                      ((? zero?)
+                       result)
+                      (score
+                       (cons (cons type score) result))))
+                  '())))
+    (sort matches
+          (lambda (m1 m2)
+            (match m1
+              ((type1 . score1)
+               (match m2
+                 ((type2 . score2)
+                  (if (= score1 score2)
+                      (string>? (service-type-name* type1)
+                                (service-type-name* type2))
+                      (> score1 score2))))))))))
+
+(define (search . args)
+  (with-error-handling
+    (let* ((regexps (map (cut make-regexp* <> regexp/icase) args))
+           (matches (find-service-types regexps)))
+      (leave-on-EPIPE
+       (display-search-results matches (current-output-port)
+                               #:print service-type->recutils
+                               #:command "guix home search")))))
+
+
+;;;
+;;; Generations.
+;;;
+
+(define* (display-home-environment-generation
+          number
+          #:optional (profile %guix-home))
+  "Display a summary of home-environment generation NUMBER in a
+human-readable format."
+  (define (display-channel channel)
+    (format #t     "    ~a:~%" (channel-name channel))
+    (format #t (G_ "      repository URL: ~a~%") (channel-url channel))
+    (when (channel-branch channel)
+      (format #t (G_ "      branch: ~a~%") (channel-branch channel)))
+    (format #t (G_ "      commit: ~a~%")
+            (if (supports-hyperlinks?)
+                (channel-commit-hyperlink channel)
+                (channel-commit channel))))
+
+  (unless (zero? number)
+    (let* ((generation  (generation-file-name profile number)))
+      (define-values (channels config-file)
+        ;; The function will work for home environments too, we just
+        ;; need to keep provenance file.
+        (system-provenance generation))
+
+      (display-generation profile number)
+      (format #t (G_ "  file name: ~a~%") generation)
+      (format #t (G_ "  canonical file name: ~a~%") (readlink* generation))
+      ;; TRANSLATORS: Please preserve the two-space indentation.
+
+      (unless (null? channels)
+        ;; TRANSLATORS: Here "channel" is the same terminology as used in
+        ;; "guix describe" and "guix pull --channels".
+        (format #t (G_ "  channels:~%"))
+        (for-each display-channel channels))
+      (when config-file
+        (format #t (G_ "  configuration file: ~a~%")
+                (if (supports-hyperlinks?)
+                    (file-hyperlink config-file)
+                    config-file))))))
+
+(define* (list-generations pattern #:optional (profile %guix-home))
+  "Display in a human-readable format all the home environment
+generations matching PATTERN, a string.  When PATTERN is #f, display
+all the home environment generations."
+  (cond ((not (file-exists? profile))             ; XXX: race condition
+         (raise (condition (&profile-not-found-error
+                            (profile profile)))))
+        ((not pattern)
+         (for-each display-home-environment-generation (profile-generations profile)))
+        ((matching-generations pattern profile)
+         =>
+         (lambda (numbers)
+           (if (null-list? numbers)
+               (exit 1)
+               (leave-on-EPIPE
+                (for-each display-home-environment-generation numbers)))))))
+
+
+;;;
+;;; Switch generations.
+;;;
+
+;; TODO: Make it public in (guix scripts system)
+(define-syntax-rule (unless-file-not-found exp)
+  (catch 'system-error
+    (lambda ()
+      exp)
+    (lambda args
+      (if (= ENOENT (system-error-errno args))
+          #f
+          (apply throw args)))))
+
+(define (switch-to-home-environment-generation store spec)
+  "Switch the home-environment profile to the generation specified by
+SPEC.  STORE is an open connection to the store."
+  (let* ((number (relative-generation-spec->number %guix-home spec))
+         (generation (generation-file-name %guix-home number))
+         (activate (string-append generation "/activate")))
+    (if number
+        (begin
+          (setenv "GUIX_NEW_HOME" (readlink generation))
+          (switch-to-generation* %guix-home number)
+          (unless-file-not-found (primitive-load activate))
+          (setenv "GUIX_NEW_HOME" #f))
+        (leave (G_ "cannot switch to home environment generation '~a'~%") spec))))
+
+
+;;;
+;;; Roll-back.
+;;;
+
+(define (roll-back-home-environment store)
+  "Roll back the home-environment profile to its previous generation.
+STORE is an open connection to the store."
+  (switch-to-home-environment-generation store "-1"))
-- 
2.33.0

[signature.asc (application/pgp-signature, inline)]

Information forwarded to guix-patches <at> gnu.org:
bug#50296; Package guix-patches. (Tue, 31 Aug 2021 09:42:02 GMT) Full text and rfc822 format available.

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

From: Andrew Tropin <andrew <at> trop.in>
To: 50296 <at> debbugs.gnu.org
Subject: [PATCH 2/2] scripts: home: Add import subcommand.
Date: Tue, 31 Aug 2021 12:40:58 +0300
[Message part 1 (text/plain, inline)]
* guix/scripts/home/import.scm: New file.
* Makefile.am (MODULES): Add it.
---
 Makefile.am                  |   1 +
 guix/scripts/home.scm        |   2 +-
 guix/scripts/home/import.scm | 241 +++++++++++++++++++++++++++++++++++
 3 files changed, 243 insertions(+), 1 deletion(-)
 create mode 100644 guix/scripts/home/import.scm

diff --git a/Makefile.am b/Makefile.am
index d44360c034..c27dcf9a38 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -296,6 +296,7 @@ MODULES =					\
   guix/scripts/system/search.scm		\
   guix/scripts/system/reconfigure.scm		\
   guix/scripts/home.scm			\
+  guix/scripts/home/import.scm			\
   guix/scripts/lint.scm				\
   guix/scripts/challenge.scm			\
   guix/scripts/import/crate.scm			\
diff --git a/guix/scripts/home.scm b/guix/scripts/home.scm
index 9eb5c0c917..75df6d707d 100644
--- a/guix/scripts/home.scm
+++ b/guix/scripts/home.scm
@@ -36,7 +36,7 @@
   #:use-module (guix scripts build)
   #:use-module (guix scripts system search)
   #:autoload   (guix scripts pull) (channel-commit-hyperlink)
-  ;; #:use-module (guix scripts home import)
+  #:use-module (guix scripts home import)
   #:use-module ((guix status) #:select (with-status-verbosity))
   #:use-module (guix gexp)
   #:use-module (guix monads)
diff --git a/guix/scripts/home/import.scm b/guix/scripts/home/import.scm
new file mode 100644
index 0000000000..39f45dbeac
--- /dev/null
+++ b/guix/scripts/home/import.scm
@@ -0,0 +1,241 @@
+;;; GNU Guix --- Functional package management for GNU
+;;; Copyright © 2021 Xinglu Chen <public <at> yoctocell.xyz>
+;;; Copyright © 2021 Andrew Tropin <andrew <at> trop.in>
+;;;
+;;; This file is part of GNU Guix.
+;;;
+;;; GNU Guix is free software; you can redistribute it and/or modify it
+;;; under the terms of the GNU General Public License as published by
+;;; the Free Software Foundation; either version 3 of the License, or (at
+;;; your option) any later version.
+;;;
+;;; GNU Guix is distributed in the hope that it will be useful, but
+;;; WITHOUT ANY WARRANTY; without even the implied warranty of
+;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;;; GNU General Public License for more details.
+;;;
+;;; You should have received a copy of the GNU General Public License
+;;; along with GNU Guix.  If not, see <http://www.gnu.org/licenses/>.
+
+(define-module (guix scripts home import)
+  #:use-module (guix profiles)
+  #:use-module (guix ui)
+  #:use-module (ice-9 match)
+  #:use-module (ice-9 pretty-print)
+  #:use-module (srfi srfi-1)
+  #:export (import-manifest))
+
+;;; Commentary:
+;;;
+;;; This module provides utilities for generating home service
+;;; configurations from existing "dotfiles".
+;;;
+;;; Code:
+
+
+(define (generate-bash-module+configuration)
+  (let ((rc (string-append (getenv "HOME") "/.bashrc"))
+        (profile (string-append (getenv "HOME") "/.bash_profile"))
+        (logout (string-append (getenv "HOME") "/.bash_logout")))
+    `((gnu home-services bash)
+      (service home-bash-service-type
+                 (home-bash-configuration
+                  ,@(if (file-exists? rc)
+                        `((bashrc
+                           (list (slurp-file-gexp (local-file ,rc)))))
+                        '())
+                  ,@(if (file-exists? profile)
+                        `((bash-profile
+                           (list (slurp-file-gexp
+                                  (local-file ,profile)))))
+                        '())
+                  ,@(if (file-exists? logout)
+                        `((bash-logout
+                           (list (slurp-file-gexp
+                                  (local-file ,logout)))))
+                        '()))))))
+
+
+(define %files-configurations-alist
+  `((".bashrc" . ,generate-bash-module+configuration)
+    (".bash_profile" . ,generate-bash-module+configuration)
+    (".bash_logout" . ,generate-bash-module+configuration)))
+
+(define (modules+configurations)
+  (let ((configurations (delete-duplicates
+                         (filter-map (match-lambda
+                                ((file . proc)
+                                 (if (file-exists?
+                                      (string-append (getenv "HOME") "/" file))
+                                     proc
+                                     #f)))
+                                     %files-configurations-alist)
+                         (lambda (x y)
+                           (equal? (procedure-name x) (procedure-name y))))))
+    (map (lambda (proc) (proc)) configurations)))
+
+;; Based on `manifest->code' from (guix profiles)
+;; MAYBE: Upstream it?
+(define* (manifest->code manifest
+                         #:key
+                         (entry-package-version (const ""))
+                         (home-environment? #f))
+  "Return an sexp representing code to build an approximate version of
+MANIFEST; the code is wrapped in a top-level 'begin' form.  If
+HOME-ENVIRONMENT? is #t, return an <home-environment> definition.
+Call ENTRY-PACKAGE-VERSION to determine the version number to use in
+the spec for a given entry; it can be set to 'manifest-entry-version'
+for fully-specified version numbers, or to some other procedure to
+disambiguate versions for packages for which several versions are
+available."
+  (define (entry-transformations entry)
+    ;; Return the transformations that apply to ENTRY.
+    (assoc-ref (manifest-entry-properties entry) 'transformations))
+
+  (define transformation-procedures
+    ;; List of transformation options/procedure name pairs.
+    (let loop ((entries (manifest-entries manifest))
+               (counter 1)
+               (result  '()))
+      (match entries
+        (() result)
+        ((entry . tail)
+         (match (entry-transformations entry)
+           (#f
+            (loop tail counter result))
+           (options
+            (if (assoc-ref result options)
+                (loop tail counter result)
+                (loop tail (+ 1 counter)
+                      (alist-cons options
+                                  (string->symbol
+                                   (format #f "transform~a" counter))
+                                  result)))))))))
+
+  (define (qualified-name entry)
+    ;; Return the name of ENTRY possibly with "@" followed by a version.
+    (match (entry-package-version entry)
+      (""      (manifest-entry-name entry))
+      (version (string-append (manifest-entry-name entry)
+                              "@" version))))
+
+  (if (null? transformation-procedures)
+      (let ((specs (map (lambda (entry)
+                          (match (manifest-entry-output entry)
+                            ("out"  (qualified-name entry))
+                            (output (string-append (qualified-name entry)
+                                                   ":" output))))
+                        (manifest-entries manifest))))
+        (if home-environment?
+            (let ((modules+configurations (modules+configurations)))
+              `(begin
+               (use-modules (gnu home)
+                            (gnu packages)
+                            ,@(map first modules+configurations))
+               ,(home-environment-template
+                 #:specs specs
+                 #:services (map second modules+configurations))))
+            `(begin
+               (use-modules (gnu packages))
+
+               (specifications->manifest
+                (list ,@specs)))))
+      (let* ((transform (lambda (options exp)
+                         (if (not options)
+                             exp
+                             (let ((proc (assoc-ref transformation-procedures
+                                                    options)))
+                               `(,proc ,exp)))))
+            (packages (map (lambda (entry)
+                                   (define options
+                                     (entry-transformations entry))
+
+                                   (define name
+                                     (qualified-name entry))
+
+                                   (match (manifest-entry-output entry)
+                                     ("out"
+                                      (transform options
+                                                 `(specification->package ,name)))
+                                     (output
+                                      `(list ,(transform
+                                               options
+                                               `(specification->package ,name))
+                                             ,output))))
+                           (manifest-entries manifest)))
+            (transformations (map (match-lambda
+                         ((options . name)
+                          `(define ,name
+                             (options->transformation ',options))))
+                       transformation-procedures)))
+        (if home-environment?
+            (let ((modules+configurations (modules+configurations)))
+              `(begin
+                 (use-modules (guix transformations)
+                              (gnu home)
+                              (gnu packages)
+                              ,@(map first modules+configurations))
+
+                 ,@transformations
+
+                 ,(home-environment-template
+                   #:packages packages
+                   #:services (map second modules+configurations))))
+            `(begin
+               (use-modules (guix transformations)
+                            (gnu packages))
+
+                ,@transformations
+
+                (packages->manifest
+                 (list ,@packages)))))))
+
+(define* (home-environment-template #:key (packages #f) (specs #f) services)
+  "Return an S-exp containing a <home-environment> declaration
+containing PACKAGES, or SPECS (package specifications), and SERVICES."
+  `(home-environment
+     (packages
+      ,@(if packages
+            `((list ,@packages))
+            `((map specification->package
+                   (list ,@specs)))))
+     (services (list ,@services))))
+
+(define* (import-manifest
+          manifest
+          #:optional (port (current-output-port)))
+  "Write to PORT a <home-environment> corresponding to MANIFEST."
+  (define (version-spec entry)
+    (let ((name (manifest-entry-name entry)))
+      (match (map package-version (find-packages-by-name name))
+        ((_)
+         ;; A single version of NAME is available, so do not specify the
+         ;; version number, even if the available version doesn't match ENTRY.
+         "")
+        (versions
+         ;; If ENTRY uses the latest version, don't specify any version.
+         ;; Otherwise return the shortest unique version prefix.  Note that
+         ;; this is based on the currently available packages, which could
+         ;; differ from the packages available in the revision that was used
+         ;; to build MANIFEST.
+         (let ((current (manifest-entry-version entry)))
+           (if (every (cut version>? current <>)
+                      (delete current versions))
+               ""
+               (version-unique-prefix (manifest-entry-version entry)
+                                      versions)))))))
+
+  (match (manifest->code manifest
+                         #:entry-package-version version-spec
+                         #:home-environment? #t)
+    (('begin exp ...)
+     (format port (G_ "\
+;; This \"home-environment\" file can be passed to 'guix home reconfigure'
+;; to reproduce the content of your profile.  This is \"symbolic\": it only
+;; specifies package names.  To reproduce the exact same profile, you also
+;; need to capture the channels being used, as returned by \"guix describe\".
+;; See the \"Replicating Guix\" section in the manual.\n"))
+     (for-each (lambda (exp)
+                 (newline port)
+                 (pretty-print exp port))
+               exp))))
-- 
2.33.0

[signature.asc (application/pgp-signature, inline)]

Reply sent to Oleg Pykhalov <go.wigust <at> gmail.com>:
You have taken responsibility. (Tue, 31 Aug 2021 11:14:02 GMT) Full text and rfc822 format available.

Notification sent to Andrew Tropin <andrew <at> trop.in>:
bug acknowledged by developer. (Tue, 31 Aug 2021 11:14:02 GMT) Full text and rfc822 format available.

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

From: Oleg Pykhalov <go.wigust <at> gmail.com>
To: Andrew Tropin <andrew <at> trop.in>
Cc: 50296-done <at> debbugs.gnu.org
Subject: Re: [bug#50296] [PATCH 0/2] Add 'guix home' command.
Date: Tue, 31 Aug 2021 14:13:04 +0300
[Message part 1 (text/plain, inline)]
Hi Andrew,

Andrew Tropin <andrew <at> trop.in> writes:

> Command and subbcommands allowing to manage home environment with guix.
>
> Andrew Tropin (2):
>   scripts: Add 'guix home'.
>   scripts: home: Add import subcommand.
>
>  Makefile.am                  |   3 +
>  guix/scripts/home.scm        | 512 +++++++++++++++++++++++++++++++++++
>  guix/scripts/home/import.scm | 241 +++++++++++++++++
>  3 files changed, 756 insertions(+)
>  create mode 100644 guix/scripts/home.scm
>  create mode 100644 guix/scripts/home/import.scm

I applied your patches and also fixed a typo in
gnu/home-services/xdg.scm file, which I noticed during Geiser entering
(guix scripts home) module about missing ‘home-services-utils’, which
should be ‘home-services utils’.

Pushed to wip-guix-home.

Also, I tried to use guix home for the first time as documented at site
[1], and got an error:
--8<---------------cut here---------------start------------->8---
(string-append #f "/" "profile/share/fonts")
In procedure string-append: Wrong type (expecting string): #f
--8<---------------cut here---------------end--------------->8---

[1] https://guix-home.trop.in/Declaring-the-Home-Environment.html


The following text in the message is only about the error.

oleg <at> guixsd ~/src/guix-wip-guix-home$ mkdir /tmp/guix

oleg <at> guixsd ~/src/guix-wip-guix-home$ guix pull --url=file:///home/oleg/src/guix-wip-guix-home --branch=wip-guix-home -p /tmp/guix/guix

~/.local/share/chezmoi/dotfiles/guixsd/home.scm:
--8<---------------cut here---------------start------------->8---
(use-modules (gnu home)
	     (gnu home-services)
	     ;; (gnu home-services ssh)
	     (gnu home-services shells)
	     ;; (gnu home-services files)
	     (gnu services)
	     (gnu packages admin)
             (guix gexp)

             (ice-9 rdelim))

(define %home
  (and=> (getenv "HOME")
         (lambda (home)
           home)))

(define .bash_profile
  (string-append %home "/.local/share/chezmoi/dot_bash_profile"))

(home-environment

 ;; (packages (list htop))

 (services
  (list

   (service home-bash-service-type
            (home-bash-configuration
             (guix-defaults? #t)
             (bash-profile
              (list
               (with-input-from-file .bash_profile read-string)))))

   ;; XXX: missing home-files-service-type
   ;; (simple-service 'test-config
   ;;                 home-files-service-type
   ;;                 (list `("config/test.conf"
   ;;                         ,(plain-file "tmp-file.txt"
   ;;                                      "the content of ~/.config/test.conf"))))
   
   ;; XXX: missing home-ssh-configuration
   ;; (service home-ssh-service-type
   ;;          (home-ssh-configuration
   ;;           (extra-config
   ;;            (list
   ;;             (ssh-host "savannah"
   ;;      		 '((compression . #f)))))))

   )))
--8<---------------cut here---------------end--------------->8---

My first guix home reconfigure launch:
--8<---------------cut here---------------start------------->8---
oleg <at> guixsd ~/src/guix-wip-guix-home$ /tmp/guix/guix/bin/guix home reconfigure ~/.local/share/chezmoi/dotfiles/guixsd/home.scm
/gnu/store/xl4igqm0jjy7gfbganz9061ivdgzfpdk-home
New symlinks to home-environment will be created soon.
All conflicting files will go to /home/oleg/1630407324-guix-home-legacy-configs-backup.

Skipping   /home/oleg/.config (directory already exists)... done
Creating   /home/oleg/.config/fontconfig... done
Symlinking /home/oleg/.config/fontconfig/fonts.conf -> /gnu/store/phj2z2iiqdhryfy7mqral0b9qz3hlva6-fonts.conf... done
Backing up /home/oleg/.bashrc... done
Symlinking /home/oleg/.bashrc -> /gnu/store/513j2xkszmcmv7fiawh59mr0i1fmin55-bashrc... done
Symlinking /home/oleg/.profile -> /gnu/store/fxbppk3pqzdi3zzy0xl5vg1ir6c5jzq5-shell-profile... done
Backing up /home/oleg/.bash_profile... done
Symlinking /home/oleg/.bash_profile -> /gnu/store/2c3yva8vj5ikb0gspmjvzw0r9g9i1cxc-bash_profile... done
 done
Finished updating symlinks.

Backtrace:
In guix/ui.scm:
   2185:7 19 (run-guix . _)
  2148:10 18 (run-guix-command _ . _)
In ice-9/boot-9.scm:
  1752:10 17 (with-exception-handler _ _ #:unwind? _ # _)
In guix/status.scm:
    820:3 16 (_)
    800:4 15 (call-with-status-report _ _)
In guix/scripts/home.scm:
    214:4 14 (_)
In ice-9/boot-9.scm:
  1752:10 13 (with-exception-handler _ _ #:unwind? _ # _)
In guix/store.scm:
   658:37 12 (thunk)
   1320:8 11 (call-with-build-handler _ _)
   1320:8 10 (call-with-build-handler #<procedure 7f5d757319c0 at g…> …)
  2108:24  9 (run-with-store #<store-connection 256.99 7f5d77fb3550> …)
In guix/scripts/home.scm:
   169:15  8 (_ _)
In unknown file:
           7 (primitive-load "/gnu/store/xl4igqm0jjy7gfbganz9061ivdg…")
In ice-9/eval.scm:
    619:8  6 (_ #(#(#(#(#(#(#(#(#(#(#<…> …) …) …) …) …) …) …) …) …) …))
   626:19  5 (_ #(#(#(#(#(#(#(#(#(#(#<…> …) …) …) …) …) …) …) …) …) …))
In srfi/srfi-1.scm:
   586:17  4 (map1 (("profile/share/fonts" (system* "/gnu/stor…" …))))
In ice-9/eval.scm:
   293:34  3 (_ #(#(#<directory (guile-user) 7f5d87ca3c80> #<va…>) #))
In unknown file:
           2 (string-append #f "/" "profile/share/fonts")
In ice-9/boot-9.scm:
  1685:16  1 (raise-exception _ #:continuable? _)
  1685:16  0 (raise-exception _ #:continuable? _)

ice-9/boot-9.scm:1685:16: In procedure raise-exception:
In procedure string-append: Wrong type (expecting string): #f
--8<---------------cut here---------------end--------------->8---

I skipped the error and tried to configure Bash more:
--8<---------------cut here---------------start------------->8---
(define .bashrc
  (string-append %home "/.local/share/chezmoi/dot_bashrc"))

;; ...

            (home-bash-configuration
             ;; ...
             (bashrc
              (list
               (with-input-from-file .bashrc read-string))))
--8<---------------cut here---------------end--------------->8---

Another launch, no errors this time:
--8<---------------cut here---------------start------------->8---
oleg <at> guixsd ~/src/guix-wip-guix-home$ /tmp/guix/guix/bin/guix home reconfigure ~/.local/share/chezmoi/dotfiles/guixsd/home.scm
substitute: updating substitutes from 'https://ci.guix.gnu.org'... 100.0%
substitute: updating substitutes from 'https://bordeaux.guix.gnu.org'... 100.0%
The following derivations will be built:
   /gnu/store/fn1hzpyic1k32pamyf45vwa0x3lw046g-home.drv
   /gnu/store/akdwz30lx0widqvyqmnkya45cb78f74d-files.drv
   /gnu/store/xcvi7n1l0fvsm099x2vyg6xci0qkayzp-bashrc.drv
   /gnu/store/pm1gw2xakkqj0zxsbbq0jnwgv3v95ajj-provenance.drv
building /gnu/store/pm1gw2xakkqj0zxsbbq0jnwgv3v95ajj-provenance.drv...
successfully built /gnu/store/pm1gw2xakkqj0zxsbbq0jnwgv3v95ajj-provenance.drv
building /gnu/store/xcvi7n1l0fvsm099x2vyg6xci0qkayzp-bashrc.drv...
successfully built /gnu/store/xcvi7n1l0fvsm099x2vyg6xci0qkayzp-bashrc.drv
building /gnu/store/akdwz30lx0widqvyqmnkya45cb78f74d-files.drv...
successfully built /gnu/store/akdwz30lx0widqvyqmnkya45cb78f74d-files.drv
building /gnu/store/fn1hzpyic1k32pamyf45vwa0x3lw046g-home.drv...
successfully built /gnu/store/fn1hzpyic1k32pamyf45vwa0x3lw046g-home.drv
/gnu/store/1y84hzz1m1c3jw03n2g8hn9wwyxngab3-home
Cleaning up symlinks from previous home-environment.

Removing /home/oleg/.config/fontconfig/fonts.conf... done
Removing /home/oleg/.config/fontconfig... done
Skipping /home/oleg/.config (not an empty directory)... done
Removing /home/oleg/.bashrc... done
Removing /home/oleg/.profile... done
Removing /home/oleg/.bash_profile... done
Cleanup finished.

New symlinks to home-environment will be created soon.
All conflicting files will go to /home/oleg/1630407412-guix-home-legacy-configs-backup.

Skipping   /home/oleg/.config (directory already exists)... done
Creating   /home/oleg/.config/fontconfig... done
Symlinking /home/oleg/.config/fontconfig/fonts.conf -> /gnu/store/phj2z2iiqdhryfy7mqral0b9qz3hlva6-fonts.conf... done
Symlinking /home/oleg/.bashrc -> /gnu/store/lf51wflmvx91m2jx8hx3j34qs9x1k153-bashrc... done
Symlinking /home/oleg/.profile -> /gnu/store/fxbppk3pqzdi3zzy0xl5vg1ir6c5jzq5-shell-profile... done
Symlinking /home/oleg/.bash_profile -> /gnu/store/2c3yva8vj5ikb0gspmjvzw0r9g9i1cxc-bash_profile... done
 done
Finished updating symlinks.

Comparing /gnu/store/xl4igqm0jjy7gfbganz9061ivdgzfpdk-home/profile/share/fonts and
          /gnu/store/1y84hzz1m1c3jw03n2g8hn9wwyxngab3-home/profile/share/fonts... done (same)
Evaling on-change gexps.

On-change gexps evaluation finished.
--8<---------------cut here---------------end--------------->8---

Oleg.
[signature.asc (application/pgp-signature, inline)]

Information forwarded to guix-patches <at> gnu.org:
bug#50296; Package guix-patches. (Tue, 31 Aug 2021 11:19:01 GMT) Full text and rfc822 format available.

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

From: zimoun <zimon.toutoune <at> gmail.com>
To: Andrew Tropin <andrew <at> trop.in>, 50296 <at> debbugs.gnu.org
Subject: Re: [bug#50296] [PATCH 0/2] Add 'guix home' command.
Date: Tue, 31 Aug 2021 12:46:59 +0200
Hi Andrew,

On Tue, 31 Aug 2021 at 12:28, Andrew Tropin <andrew <at> trop.in> wrote:
> Command and subbcommands allowing to manage home environment with guix.
>
> Andrew Tropin (2):
>   scripts: Add 'guix home'.
>   scripts: home: Add import subcommand.

Raghav recently asked [1] an interesting question about consistency of
command line commands, i.e., compare for instance:

  guix system roll-back
  guix pull --roll-back
  guix package --roll-back

I do not have an opinion but is it a conscientious or discussed choice
for subcommands? 


All the best,
simon


1: <https://yhetil.org/guix/fdb27bc6-875e-d0e7-8d8e-4c21331b06c4 <at> raghavgururajan.name>





Information forwarded to guix-patches <at> gnu.org:
bug#50296; Package guix-patches. (Tue, 31 Aug 2021 11:19:01 GMT) Full text and rfc822 format available.

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

From: zimoun <zimon.toutoune <at> gmail.com>
To: Andrew Tropin <andrew <at> trop.in>, 50296 <at> debbugs.gnu.org
Subject: Re: [bug#50296] [PATCH 1/2] scripts: Add 'guix home'.
Date: Tue, 31 Aug 2021 12:53:51 +0200
Hi,

On Tue, 31 Aug 2021 at 12:40, Andrew Tropin <andrew <at> trop.in> wrote:

> +(define-command (guix-home . args)
> +  (synopsis "build and deploy home environments")
> +
> +  (define (parse-sub-command arg result)
> +    ;; Parse sub-command ARG and augment RESULT accordingly.
> +    (if (assoc-ref result 'action)
> +        (alist-cons 'argument arg result)
> +        (let ((action (string->symbol arg)))
> +          (case action
> +            ((build
> +              reconfigure
> +              extension-graph shepherd-graph
> +              list-generations describe
> +              delete-generations roll-back
> +              switch-generation search
> +              import)
> +             (alist-cons 'action action result))
> +            (else (leave (G_ "~a: unknown action~%") action))))))

For parsing the actions, I would define elsewhere the list.  Then if the
action is unknown, you could use ’string-closest’ and so return an hint
if there is a typo.

Other said, this

  guix home recnfigure

would return

  guix home: error: recnfigure: unknown action
  hint: Did you mean `reconfigure'?

WDYT?

Cheers,
simon




Information forwarded to guix-patches <at> gnu.org:
bug#50296; Package guix-patches. (Tue, 31 Aug 2021 11:47:02 GMT) Full text and rfc822 format available.

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

From: Andrew Tropin <andrew <at> trop.in>
To: Oleg Pykhalov <go.wigust <at> gmail.com>
Cc: 50296-done <at> debbugs.gnu.org
Subject: Re: [bug#50296] [PATCH 0/2] Add 'guix home' command.
Date: Tue, 31 Aug 2021 14:46:11 +0300
[Message part 1 (text/plain, inline)]
On 2021-08-31 14:13, Oleg Pykhalov wrote:

> Hi Andrew,
>
> Andrew Tropin <andrew <at> trop.in> writes:
>
>> Command and subbcommands allowing to manage home environment with guix.
>>
>> Andrew Tropin (2):
>>   scripts: Add 'guix home'.
>>   scripts: home: Add import subcommand.
>>
>>  Makefile.am                  |   3 +
>>  guix/scripts/home.scm        | 512 +++++++++++++++++++++++++++++++++++
>>  guix/scripts/home/import.scm | 241 +++++++++++++++++
>>  3 files changed, 756 insertions(+)
>>  create mode 100644 guix/scripts/home.scm
>>  create mode 100644 guix/scripts/home/import.scm
>
> I applied your patches and also fixed a typo in
> gnu/home-services/xdg.scm file, which I noticed during Geiser entering
> (guix scripts home) module about missing ‘home-services-utils’, which
> should be ‘home-services utils’.
>

In rde we have home-services-utils, during recent refactoring I took
parts of it and split into home-services utils and home-services
configure modules.  For some reason I missed that xdg still uses it and
I didn't get rid of this import, I'll update xdg module and send patches
for it, thank you for noticing the issue.

> 
> Pushed to wip-guix-home.
>
> Also, I tried to use guix home for the first time as documented at site
> [1], and got an error:
> --8<---------------cut here---------------start------------->8---
> (string-append #f "/" "profile/share/fonts")
> In procedure string-append: Wrong type (expecting string): #f
> --8<---------------cut here---------------end--------------->8---
>
> [1] https://guix-home.trop.in/Declaring-the-Home-Environment.html
>
>
> The following text in the message is only about the error.
>
> oleg <at> guixsd ~/src/guix-wip-guix-home$ mkdir /tmp/guix
>
> oleg <at> guixsd ~/src/guix-wip-guix-home$ guix pull --url=file:///home/oleg/src/guix-wip-guix-home --branch=wip-guix-home -p /tmp/guix/guix
>
> ~/.local/share/chezmoi/dotfiles/guixsd/home.scm:
> --8<---------------cut here---------------start------------->8---
> (use-modules (gnu home)
> 	     (gnu home-services)
> 	     ;; (gnu home-services ssh)
> 	     (gnu home-services shells)
> 	     ;; (gnu home-services files)
> 	     (gnu services)
> 	     (gnu packages admin)
>              (guix gexp)
>
>              (ice-9 rdelim))
>
> (define %home
>   (and=> (getenv "HOME")
>          (lambda (home)
>            home)))
>
> (define .bash_profile
>   (string-append %home "/.local/share/chezmoi/dot_bash_profile"))
>
> (home-environment
>
>  ;; (packages (list htop))
>
>  (services
>   (list
>
>    (service home-bash-service-type
>             (home-bash-configuration
>              (guix-defaults? #t)
>              (bash-profile
>               (list
>                (with-input-from-file .bash_profile read-string)))))
>
>    ;; XXX: missing home-files-service-type
>    ;; (simple-service 'test-config
>    ;;                 home-files-service-type
>    ;;                 (list `("config/test.conf"
>    ;;                         ,(plain-file "tmp-file.txt"
>    ;;                                      "the content of ~/.config/test.conf"))))
>    
>    ;; XXX: missing home-ssh-configuration
>    ;; (service home-ssh-service-type
>    ;;          (home-ssh-configuration
>    ;;           (extra-config
>    ;;            (list
>    ;;             (ssh-host "savannah"
>    ;;      		 '((compression . #f)))))))
>
>    )))
> --8<---------------cut here---------------end--------------->8---
>
> My first guix home reconfigure launch:
> --8<---------------cut here---------------start------------->8---
> oleg <at> guixsd ~/src/guix-wip-guix-home$ /tmp/guix/guix/bin/guix home reconfigure ~/.local/share/chezmoi/dotfiles/guixsd/home.scm
> /gnu/store/xl4igqm0jjy7gfbganz9061ivdgzfpdk-home
> New symlinks to home-environment will be created soon.
> All conflicting files will go to /home/oleg/1630407324-guix-home-legacy-configs-backup.
>
> Skipping   /home/oleg/.config (directory already exists)... done
> Creating   /home/oleg/.config/fontconfig... done
> Symlinking /home/oleg/.config/fontconfig/fonts.conf -> /gnu/store/phj2z2iiqdhryfy7mqral0b9qz3hlva6-fonts.conf... done
> Backing up /home/oleg/.bashrc... done
> Symlinking /home/oleg/.bashrc -> /gnu/store/513j2xkszmcmv7fiawh59mr0i1fmin55-bashrc... done
> Symlinking /home/oleg/.profile -> /gnu/store/fxbppk3pqzdi3zzy0xl5vg1ir6c5jzq5-shell-profile... done
> Backing up /home/oleg/.bash_profile... done
> Symlinking /home/oleg/.bash_profile -> /gnu/store/2c3yva8vj5ikb0gspmjvzw0r9g9i1cxc-bash_profile... done
>  done
> Finished updating symlinks.
>
> Backtrace:
> In guix/ui.scm:
>    2185:7 19 (run-guix . _)
>   2148:10 18 (run-guix-command _ . _)
> In ice-9/boot-9.scm:
>   1752:10 17 (with-exception-handler _ _ #:unwind? _ # _)
> In guix/status.scm:
>     820:3 16 (_)
>     800:4 15 (call-with-status-report _ _)
> In guix/scripts/home.scm:
>     214:4 14 (_)
> In ice-9/boot-9.scm:
>   1752:10 13 (with-exception-handler _ _ #:unwind? _ # _)
> In guix/store.scm:
>    658:37 12 (thunk)
>    1320:8 11 (call-with-build-handler _ _)
>    1320:8 10 (call-with-build-handler #<procedure 7f5d757319c0 at g…> …)
>   2108:24  9 (run-with-store #<store-connection 256.99 7f5d77fb3550> …)
> In guix/scripts/home.scm:
>    169:15  8 (_ _)
> In unknown file:
>            7 (primitive-load "/gnu/store/xl4igqm0jjy7gfbganz9061ivdg…")
> In ice-9/eval.scm:
>     619:8  6 (_ #(#(#(#(#(#(#(#(#(#(#<…> …) …) …) …) …) …) …) …) …) …))
>    626:19  5 (_ #(#(#(#(#(#(#(#(#(#(#<…> …) …) …) …) …) …) …) …) …) …))
> In srfi/srfi-1.scm:
>    586:17  4 (map1 (("profile/share/fonts" (system* "/gnu/stor…" …))))
> In ice-9/eval.scm:
>    293:34  3 (_ #(#(#<directory (guile-user) 7f5d87ca3c80> #<va…>) #))
> In unknown file:
>            2 (string-append #f "/" "profile/share/fonts")
> In ice-9/boot-9.scm:
>   1685:16  1 (raise-exception _ #:continuable? _)
>   1685:16  0 (raise-exception _ #:continuable? _)
>
> ice-9/boot-9.scm:1685:16: In procedure raise-exception:
> In procedure string-append: Wrong type (expecting string): #f

run-on-change service doesn't handle the case, where the previous
generation doesn't exists.  Fix should be pretty simple, will send a
patch once it done.  Thank you for catching this)

> --8<---------------cut here---------------end--------------->8---
>
> I skipped the error and tried to configure Bash more:
> --8<---------------cut here---------------start------------->8---
> (define .bashrc
>   (string-append %home "/.local/share/chezmoi/dot_bashrc"))
>
> ;; ...
>
>             (home-bash-configuration
>              ;; ...
>              (bashrc
>               (list
>                (with-input-from-file .bashrc read-string))))
> --8<---------------cut here---------------end--------------->8---
>
> Another launch, no errors this time:
> --8<---------------cut here---------------start------------->8---
> oleg <at> guixsd ~/src/guix-wip-guix-home$ /tmp/guix/guix/bin/guix home reconfigure ~/.local/share/chezmoi/dotfiles/guixsd/home.scm
> substitute: updating substitutes from 'https://ci.guix.gnu.org'... 100.0%
> substitute: updating substitutes from 'https://bordeaux.guix.gnu.org'... 100.0%
> The following derivations will be built:
>    /gnu/store/fn1hzpyic1k32pamyf45vwa0x3lw046g-home.drv
>    /gnu/store/akdwz30lx0widqvyqmnkya45cb78f74d-files.drv
>    /gnu/store/xcvi7n1l0fvsm099x2vyg6xci0qkayzp-bashrc.drv
>    /gnu/store/pm1gw2xakkqj0zxsbbq0jnwgv3v95ajj-provenance.drv
> building /gnu/store/pm1gw2xakkqj0zxsbbq0jnwgv3v95ajj-provenance.drv...
> successfully built /gnu/store/pm1gw2xakkqj0zxsbbq0jnwgv3v95ajj-provenance.drv
> building /gnu/store/xcvi7n1l0fvsm099x2vyg6xci0qkayzp-bashrc.drv...
> successfully built /gnu/store/xcvi7n1l0fvsm099x2vyg6xci0qkayzp-bashrc.drv
> building /gnu/store/akdwz30lx0widqvyqmnkya45cb78f74d-files.drv...
> successfully built /gnu/store/akdwz30lx0widqvyqmnkya45cb78f74d-files.drv
> building /gnu/store/fn1hzpyic1k32pamyf45vwa0x3lw046g-home.drv...
> successfully built /gnu/store/fn1hzpyic1k32pamyf45vwa0x3lw046g-home.drv
> /gnu/store/1y84hzz1m1c3jw03n2g8hn9wwyxngab3-home
> Cleaning up symlinks from previous home-environment.
>
> Removing /home/oleg/.config/fontconfig/fonts.conf... done
> Removing /home/oleg/.config/fontconfig... done
> Skipping /home/oleg/.config (not an empty directory)... done
> Removing /home/oleg/.bashrc... done
> Removing /home/oleg/.profile... done
> Removing /home/oleg/.bash_profile... done
> Cleanup finished.
>
> New symlinks to home-environment will be created soon.
> All conflicting files will go to /home/oleg/1630407412-guix-home-legacy-configs-backup.
>
> Skipping   /home/oleg/.config (directory already exists)... done
> Creating   /home/oleg/.config/fontconfig... done
> Symlinking /home/oleg/.config/fontconfig/fonts.conf -> /gnu/store/phj2z2iiqdhryfy7mqral0b9qz3hlva6-fonts.conf... done
> Symlinking /home/oleg/.bashrc -> /gnu/store/lf51wflmvx91m2jx8hx3j34qs9x1k153-bashrc... done
> Symlinking /home/oleg/.profile -> /gnu/store/fxbppk3pqzdi3zzy0xl5vg1ir6c5jzq5-shell-profile... done
> Symlinking /home/oleg/.bash_profile -> /gnu/store/2c3yva8vj5ikb0gspmjvzw0r9g9i1cxc-bash_profile... done
>  done
> Finished updating symlinks.
>
> Comparing /gnu/store/xl4igqm0jjy7gfbganz9061ivdgzfpdk-home/profile/share/fonts and
>           /gnu/store/1y84hzz1m1c3jw03n2g8hn9wwyxngab3-home/profile/share/fonts... done (same)
> Evaling on-change gexps.
>
> On-change gexps evaluation finished.
> --8<---------------cut here---------------end--------------->8---
>
> Oleg.
[signature.asc (application/pgp-signature, inline)]

Information forwarded to guix-patches <at> gnu.org:
bug#50296; Package guix-patches. (Tue, 31 Aug 2021 12:04:02 GMT) Full text and rfc822 format available.

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

From: Andrew Tropin <andrew <at> trop.in>
To: zimoun <zimon.toutoune <at> gmail.com>, 50296 <at> debbugs.gnu.org
Subject: Re: [bug#50296] [PATCH 0/2] Add 'guix home' command.
Date: Tue, 31 Aug 2021 15:03:26 +0300
[Message part 1 (text/plain, inline)]
On 2021-08-31 12:46, zimoun wrote:

> Hi Andrew,
>
> On Tue, 31 Aug 2021 at 12:28, Andrew Tropin <andrew <at> trop.in> wrote:
>> Command and subbcommands allowing to manage home environment with guix.
>>
>> Andrew Tropin (2):
>>   scripts: Add 'guix home'.
>>   scripts: home: Add import subcommand.
>
> Raghav recently asked [1] an interesting question about consistency of
> command line commands, i.e., compare for instance:
>
>   guix system roll-back
>   guix pull --roll-back
>   guix package --roll-back
>
> I do not have an opinion but is it a conscientious or discussed choice
> for subcommands? 
>

Yeah, I also mentioned this inconsistency, but I decided to stick to the
'guix system' approach and use subcommands.  I'm not sure, which one is
better, I would like to have pull, package and system to work the same
way, but it seems that such refactoring will berak people setups.
Anyway, I will be keeping the "compatibility" with 'guix system', so if
we decide to change its interface, 'guix home's interface will be
changed too.

>
>
> All the best,
> simon
>
>
> 1: <https://yhetil.org/guix/fdb27bc6-875e-d0e7-8d8e-4c21331b06c4 <at> raghavgururajan.name>
[signature.asc (application/pgp-signature, inline)]

Information forwarded to guix-patches <at> gnu.org:
bug#50296; Package guix-patches. (Tue, 31 Aug 2021 12:13:02 GMT) Full text and rfc822 format available.

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

From: Andrew Tropin <andrew <at> trop.in>
To: zimoun <zimon.toutoune <at> gmail.com>, 50296 <at> debbugs.gnu.org
Subject: Re: [bug#50296] [PATCH 1/2] scripts: Add 'guix home'.
Date: Tue, 31 Aug 2021 15:12:26 +0300
[Message part 1 (text/plain, inline)]
On 2021-08-31 12:53, zimoun wrote:

> Hi,
>
> On Tue, 31 Aug 2021 at 12:40, Andrew Tropin <andrew <at> trop.in> wrote:
>
>> +(define-command (guix-home . args)
>> +  (synopsis "build and deploy home environments")
>> +
>> +  (define (parse-sub-command arg result)
>> +    ;; Parse sub-command ARG and augment RESULT accordingly.
>> +    (if (assoc-ref result 'action)
>> +        (alist-cons 'argument arg result)
>> +        (let ((action (string->symbol arg)))
>> +          (case action
>> +            ((build
>> +              reconfigure
>> +              extension-graph shepherd-graph
>> +              list-generations describe
>> +              delete-generations roll-back
>> +              switch-generation search
>> +              import)
>> +             (alist-cons 'action action result))
>> +            (else (leave (G_ "~a: unknown action~%") action))))))
>
> For parsing the actions, I would define elsewhere the list.  Then if the
> action is unknown, you could use ’string-closest’ and so return an hint
> if there is a typo.
>
> Other said, this
>
>   guix home recnfigure
>
> would return
>
>   guix home: error: recnfigure: unknown action
>   hint: Did you mean `reconfigure'?
>
> WDYT?
>

Sounds good, the same "issue" exists for guix system subcommands, it
would be cool to have such functionality, but I would like to have those
changes to both guix system and guix home after wip-guix-home merged,
because backporting changes to rde is a little tedious.

Also, it seems related to subcommands/--arguments discussion and maybe
better to talk about it in a separate thread.

> 
> Cheers, simon
[signature.asc (application/pgp-signature, inline)]

Information forwarded to guix-patches <at> gnu.org:
bug#50296; Package guix-patches. (Tue, 31 Aug 2021 12:48:02 GMT) Full text and rfc822 format available.

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

From: Andrew Tropin <andrew <at> trop.in>
To: Oleg Pykhalov <go.wigust <at> gmail.com>
Cc: 50296-done <at> debbugs.gnu.org
Subject: Re: [bug#50296] [PATCH 0/2] Add 'guix home' command.
Date: Tue, 31 Aug 2021 15:47:03 +0300
[Message part 1 (text/plain, inline)]
On 2021-08-31 14:46, Andrew Tropin wrote:

> On 2021-08-31 14:13, Oleg Pykhalov wrote:
>
>> Hi Andrew,
>>
>> Andrew Tropin <andrew <at> trop.in> writes:
>>
>>> Command and subbcommands allowing to manage home environment with guix.
>>>
>>> Andrew Tropin (2):
>>>   scripts: Add 'guix home'.
>>>   scripts: home: Add import subcommand.
>>>
>>>  Makefile.am                  |   3 +
>>>  guix/scripts/home.scm        | 512 +++++++++++++++++++++++++++++++++++
>>>  guix/scripts/home/import.scm | 241 +++++++++++++++++
>>>  3 files changed, 756 insertions(+)
>>>  create mode 100644 guix/scripts/home.scm
>>>  create mode 100644 guix/scripts/home/import.scm
>>
>> I applied your patches and also fixed a typo in
>> gnu/home-services/xdg.scm file, which I noticed during Geiser entering
>> (guix scripts home) module about missing ‘home-services-utils’, which
>> should be ‘home-services utils’.
>>
>
> In rde we have home-services-utils, during recent refactoring I took
> parts of it and split into home-services utils and home-services
> configure modules.  For some reason I missed that xdg still uses it and
> I didn't get rid of this import, I'll update xdg module and send patches
> for it, thank you for noticing the issue.
>

The functions from home-services-utils used by xdg now in home-services
utils:
[0002-home-services-configuration-Add-generic-serialize-al.patch (text/x-patch, inline)]
From efd3ea79905c12e2c1c594fa6b54cf62d741f92f Mon Sep 17 00:00:00 2001
From: Andrew Tropin <andrew <at> trop.in>
Date: Tue, 31 Aug 2021 15:40:07 +0300
Subject: [PATCH 2/2] home-services: configuration: Add
 generic-serialize-alist.

* gnu/home-services/configuration.scm (generic-serialize-alist)
(generic-serialize-alist-entry): New variables.
---
 gnu/home-services/configuration.scm | 28 +++++++++++++++++++++++++++-
 1 file changed, 27 insertions(+), 1 deletion(-)

diff --git a/gnu/home-services/configuration.scm b/gnu/home-services/configuration.scm
index 039877b5c1..3698006c37 100644
--- a/gnu/home-services/configuration.scm
+++ b/gnu/home-services/configuration.scm
@@ -1,5 +1,6 @@
 ;;; GNU Guix --- Functional package management for GNU
 ;;; Copyright © 2021 Andrew Tropin <andrew <at> trop.in>
+;;; Copyright © 2021 Xinglu Chen <public <at> yoctocell.xyz>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -20,6 +21,8 @@
   #:use-module (gnu services configuration)
   #:use-module (guix gexp)
   #:use-module (srfi srfi-1)
+  #:use-module (ice-9 curried-definitions)
+  #:use-module (ice-9 match)
 
   #:export (filter-configuration-fields
 
@@ -31,7 +34,9 @@
             string-or-gexp?
 	    serialize-string-or-gexp
 	    text-config?
-            serialize-text-config))
+            serialize-text-config
+            generic-serialize-alist-entry
+            generic-serialize-alist))
 
 (define* (filter-configuration-fields configuration-fields fields
 				      #:optional negate?)
@@ -79,3 +84,24 @@ the list result in @code{#t} when applying PRED? on them."
   (and (list? config) (every string-or-gexp? config)))
 (define (serialize-text-config field-name val)
   #~(string-append #$@(interpose val "\n" 'suffix)))
+
+(define ((generic-serialize-alist-entry serialize-field) entry)
+  "Apply the SERIALIZE-FIELD procedure on the field and value of ENTRY."
+  (match entry
+    ((field . val) (serialize-field field val))))
+
+(define (generic-serialize-alist combine serialize-field fields)
+  "Generate a configuration from an association list FIELDS.
+
+SERIALIZE-FIELD is a procedure that takes two arguments, it will be
+applied on the fields and values of FIELDS using the
+@code{generic-serialize-alist-entry} procedure.
+
+COMBINE is a procedure that takes one or more arguments and combines
+all the alist entries into one value, @code{string-append} or
+@code{append} are usually good candidates for this.
+
+See the @code{serialize-alist} procedure in `@code{(gnu home-services
+version-control}' for an example usage.)}"
+  (apply combine
+         (map (generic-serialize-alist-entry serialize-field) fields)))
-- 
2.33.0

[Message part 3 (text/plain, inline)]
>
>> 
>> Pushed to wip-guix-home.
>>
>> Also, I tried to use guix home for the first time as documented at site
>> [1], and got an error:
>> --8<---------------cut here---------------start------------->8---
>> (string-append #f "/" "profile/share/fonts")
>> In procedure string-append: Wrong type (expecting string): #f
>> --8<---------------cut here---------------end--------------->8---
>>
>> [1] https://guix-home.trop.in/Declaring-the-Home-Environment.html
>>
>>
>> The following text in the message is only about the error.
>>
>> oleg <at> guixsd ~/src/guix-wip-guix-home$ mkdir /tmp/guix
>>
>> oleg <at> guixsd ~/src/guix-wip-guix-home$ guix pull --url=file:///home/oleg/src/guix-wip-guix-home --branch=wip-guix-home -p /tmp/guix/guix
>>
>> ~/.local/share/chezmoi/dotfiles/guixsd/home.scm:
>> --8<---------------cut here---------------start------------->8---
>> (use-modules (gnu home)
>> 	     (gnu home-services)
>> 	     ;; (gnu home-services ssh)
>> 	     (gnu home-services shells)
>> 	     ;; (gnu home-services files)
>> 	     (gnu services)
>> 	     (gnu packages admin)
>>              (guix gexp)
>>
>>              (ice-9 rdelim))
>>
>> (define %home
>>   (and=> (getenv "HOME")
>>          (lambda (home)
>>            home)))
>>
>> (define .bash_profile
>>   (string-append %home "/.local/share/chezmoi/dot_bash_profile"))
>>
>> (home-environment
>>
>>  ;; (packages (list htop))
>>
>>  (services
>>   (list
>>
>>    (service home-bash-service-type
>>             (home-bash-configuration
>>              (guix-defaults? #t)
>>              (bash-profile
>>               (list
>>                (with-input-from-file .bash_profile read-string)))))
>>
>>    ;; XXX: missing home-files-service-type
>>    ;; (simple-service 'test-config
>>    ;;                 home-files-service-type
>>    ;;                 (list `("config/test.conf"
>>    ;;                         ,(plain-file "tmp-file.txt"
>>    ;;                                      "the content of ~/.config/test.conf"))))
>>    
>>    ;; XXX: missing home-ssh-configuration
>>    ;; (service home-ssh-service-type
>>    ;;          (home-ssh-configuration
>>    ;;           (extra-config
>>    ;;            (list
>>    ;;             (ssh-host "savannah"
>>    ;;      		 '((compression . #f)))))))
>>
>>    )))
>> --8<---------------cut here---------------end--------------->8---
>>
>> My first guix home reconfigure launch:
>> --8<---------------cut here---------------start------------->8---
>> oleg <at> guixsd ~/src/guix-wip-guix-home$ /tmp/guix/guix/bin/guix home reconfigure ~/.local/share/chezmoi/dotfiles/guixsd/home.scm
>> /gnu/store/xl4igqm0jjy7gfbganz9061ivdgzfpdk-home
>> New symlinks to home-environment will be created soon.
>> All conflicting files will go to /home/oleg/1630407324-guix-home-legacy-configs-backup.
>>
>> Skipping   /home/oleg/.config (directory already exists)... done
>> Creating   /home/oleg/.config/fontconfig... done
>> Symlinking /home/oleg/.config/fontconfig/fonts.conf -> /gnu/store/phj2z2iiqdhryfy7mqral0b9qz3hlva6-fonts.conf... done
>> Backing up /home/oleg/.bashrc... done
>> Symlinking /home/oleg/.bashrc -> /gnu/store/513j2xkszmcmv7fiawh59mr0i1fmin55-bashrc... done
>> Symlinking /home/oleg/.profile -> /gnu/store/fxbppk3pqzdi3zzy0xl5vg1ir6c5jzq5-shell-profile... done
>> Backing up /home/oleg/.bash_profile... done
>> Symlinking /home/oleg/.bash_profile -> /gnu/store/2c3yva8vj5ikb0gspmjvzw0r9g9i1cxc-bash_profile... done
>>  done
>> Finished updating symlinks.
>>
>> Backtrace:
>> In guix/ui.scm:
>>    2185:7 19 (run-guix . _)
>>   2148:10 18 (run-guix-command _ . _)
>> In ice-9/boot-9.scm:
>>   1752:10 17 (with-exception-handler _ _ #:unwind? _ # _)
>> In guix/status.scm:
>>     820:3 16 (_)
>>     800:4 15 (call-with-status-report _ _)
>> In guix/scripts/home.scm:
>>     214:4 14 (_)
>> In ice-9/boot-9.scm:
>>   1752:10 13 (with-exception-handler _ _ #:unwind? _ # _)
>> In guix/store.scm:
>>    658:37 12 (thunk)
>>    1320:8 11 (call-with-build-handler _ _)
>>    1320:8 10 (call-with-build-handler #<procedure 7f5d757319c0 at g…> …)
>>   2108:24  9 (run-with-store #<store-connection 256.99 7f5d77fb3550> …)
>> In guix/scripts/home.scm:
>>    169:15  8 (_ _)
>> In unknown file:
>>            7 (primitive-load "/gnu/store/xl4igqm0jjy7gfbganz9061ivdg…")
>> In ice-9/eval.scm:
>>     619:8  6 (_ #(#(#(#(#(#(#(#(#(#(#<…> …) …) …) …) …) …) …) …) …) …))
>>    626:19  5 (_ #(#(#(#(#(#(#(#(#(#(#<…> …) …) …) …) …) …) …) …) …) …))
>> In srfi/srfi-1.scm:
>>    586:17  4 (map1 (("profile/share/fonts" (system* "/gnu/stor…" …))))
>> In ice-9/eval.scm:
>>    293:34  3 (_ #(#(#<directory (guile-user) 7f5d87ca3c80> #<va…>) #))
>> In unknown file:
>>            2 (string-append #f "/" "profile/share/fonts")
>> In ice-9/boot-9.scm:
>>   1685:16  1 (raise-exception _ #:continuable? _)
>>   1685:16  0 (raise-exception _ #:continuable? _)
>>
>> ice-9/boot-9.scm:1685:16: In procedure raise-exception:
>> In procedure string-append: Wrong type (expecting string): #f
>
> run-on-change service doesn't handle the case, where the previous
> generation doesn't exists.  Fix should be pretty simple, will send a
> patch once it done.  Thank you for catching this)
>

The fix:
[0001-home-services-run-on-change-Handle-first-generation-.patch (text/x-patch, inline)]
From a07541380d412b33c504e5811776062af4e38582 Mon Sep 17 00:00:00 2001
From: Andrew Tropin <andrew <at> trop.in>
Date: Tue, 31 Aug 2021 15:24:25 +0300
Subject: [PATCH 1/2] home-services: run-on-change: Handle first generation
 case.

---
 gnu/home-services.scm | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/gnu/home-services.scm b/gnu/home-services.scm
index 2a773496f0..5608c65175 100644
--- a/gnu/home-services.scm
+++ b/gnu/home-services.scm
@@ -448,13 +448,14 @@ with one gexp, but many times, and all gexps must be idempotent.")))
              (if any-changes? (cadr x) "")))
          '#$pattern-gexp-tuples))
 
-      (if #$eval-gexps?
+      (if (and #$eval-gexps? (getenv "GUIX_OLD_HOME"))
           (begin
             (display "Evaling on-change gexps.\n\n")
             (for-each primitive-eval expressions-to-eval)
             (display "On-change gexps evaluation finished.\n\n"))
           (display "\
-On-change gexps won't evaluated, disabled by service configuration.\n"))))
+On-change gexps won't evaluated, disabled by service configuration or
+there are no previos generations.\n"))))
 
 (define home-run-on-change-service-type
   (service-type (name 'home-run-on-change)
-- 
2.33.0

[Message part 5 (text/plain, inline)]
>
>> --8<---------------cut here---------------end--------------->8---
>>
>> I skipped the error and tried to configure Bash more:
>> --8<---------------cut here---------------start------------->8---
>> (define .bashrc
>>   (string-append %home "/.local/share/chezmoi/dot_bashrc"))
>>
>> ;; ...
>>
>>             (home-bash-configuration
>>              ;; ...
>>              (bashrc
>>               (list
>>                (with-input-from-file .bashrc read-string))))
>> --8<---------------cut here---------------end--------------->8---
>>
>> Another launch, no errors this time:
>> --8<---------------cut here---------------start------------->8---
>> oleg <at> guixsd ~/src/guix-wip-guix-home$ /tmp/guix/guix/bin/guix home reconfigure ~/.local/share/chezmoi/dotfiles/guixsd/home.scm
>> substitute: updating substitutes from 'https://ci.guix.gnu.org'... 100.0%
>> substitute: updating substitutes from 'https://bordeaux.guix.gnu.org'... 100.0%
>> The following derivations will be built:
>>    /gnu/store/fn1hzpyic1k32pamyf45vwa0x3lw046g-home.drv
>>    /gnu/store/akdwz30lx0widqvyqmnkya45cb78f74d-files.drv
>>    /gnu/store/xcvi7n1l0fvsm099x2vyg6xci0qkayzp-bashrc.drv
>>    /gnu/store/pm1gw2xakkqj0zxsbbq0jnwgv3v95ajj-provenance.drv
>> building /gnu/store/pm1gw2xakkqj0zxsbbq0jnwgv3v95ajj-provenance.drv...
>> successfully built /gnu/store/pm1gw2xakkqj0zxsbbq0jnwgv3v95ajj-provenance.drv
>> building /gnu/store/xcvi7n1l0fvsm099x2vyg6xci0qkayzp-bashrc.drv...
>> successfully built /gnu/store/xcvi7n1l0fvsm099x2vyg6xci0qkayzp-bashrc.drv
>> building /gnu/store/akdwz30lx0widqvyqmnkya45cb78f74d-files.drv...
>> successfully built /gnu/store/akdwz30lx0widqvyqmnkya45cb78f74d-files.drv
>> building /gnu/store/fn1hzpyic1k32pamyf45vwa0x3lw046g-home.drv...
>> successfully built /gnu/store/fn1hzpyic1k32pamyf45vwa0x3lw046g-home.drv
>> /gnu/store/1y84hzz1m1c3jw03n2g8hn9wwyxngab3-home
>> Cleaning up symlinks from previous home-environment.
>>
>> Removing /home/oleg/.config/fontconfig/fonts.conf... done
>> Removing /home/oleg/.config/fontconfig... done
>> Skipping /home/oleg/.config (not an empty directory)... done
>> Removing /home/oleg/.bashrc... done
>> Removing /home/oleg/.profile... done
>> Removing /home/oleg/.bash_profile... done
>> Cleanup finished.
>>
>> New symlinks to home-environment will be created soon.
>> All conflicting files will go to /home/oleg/1630407412-guix-home-legacy-configs-backup.
>>
>> Skipping   /home/oleg/.config (directory already exists)... done
>> Creating   /home/oleg/.config/fontconfig... done
>> Symlinking /home/oleg/.config/fontconfig/fonts.conf -> /gnu/store/phj2z2iiqdhryfy7mqral0b9qz3hlva6-fonts.conf... done
>> Symlinking /home/oleg/.bashrc -> /gnu/store/lf51wflmvx91m2jx8hx3j34qs9x1k153-bashrc... done
>> Symlinking /home/oleg/.profile -> /gnu/store/fxbppk3pqzdi3zzy0xl5vg1ir6c5jzq5-shell-profile... done
>> Symlinking /home/oleg/.bash_profile -> /gnu/store/2c3yva8vj5ikb0gspmjvzw0r9g9i1cxc-bash_profile... done
>>  done
>> Finished updating symlinks.
>>
>> Comparing /gnu/store/xl4igqm0jjy7gfbganz9061ivdgzfpdk-home/profile/share/fonts and
>>           /gnu/store/1y84hzz1m1c3jw03n2g8hn9wwyxngab3-home/profile/share/fonts... done (same)
>> Evaling on-change gexps.
>>
>> On-change gexps evaluation finished.
>> --8<---------------cut here---------------end--------------->8---
>>
>> Oleg.
[signature.asc (application/pgp-signature, inline)]

Information forwarded to guix-patches <at> gnu.org:
bug#50296; Package guix-patches. (Tue, 31 Aug 2021 13:11:02 GMT) Full text and rfc822 format available.

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

From: zimoun <zimon.toutoune <at> gmail.com>
To: Andrew Tropin <andrew <at> trop.in>
Cc: 50296 <at> debbugs.gnu.org
Subject: Re: [bug#50296] [PATCH 1/2] scripts: Add 'guix home'.
Date: Tue, 31 Aug 2021 15:09:47 +0200
Hi,

On Tue, 31 Aug 2021 at 14:12, Andrew Tropin <andrew <at> trop.in> wrote:
> On 2021-08-31 12:53, zimoun wrote:
> > On Tue, 31 Aug 2021 at 12:40, Andrew Tropin <andrew <at> trop.in> wrote:
> >
> >> +(define-command (guix-home . args)
> >> +  (synopsis "build and deploy home environments")
> >> +
> >> +  (define (parse-sub-command arg result)
> >> +    ;; Parse sub-command ARG and augment RESULT accordingly.
> >> +    (if (assoc-ref result 'action)
> >> +        (alist-cons 'argument arg result)
> >> +        (let ((action (string->symbol arg)))
> >> +          (case action
> >> +            ((build
> >> +              reconfigure
> >> +              extension-graph shepherd-graph
> >> +              list-generations describe
> >> +              delete-generations roll-back
> >> +              switch-generation search
> >> +              import)
> >> +             (alist-cons 'action action result))
> >> +            (else (leave (G_ "~a: unknown action~%") action))))))
> >
> > For parsing the actions, I would define elsewhere the list.  Then if the
> > action is unknown, you could use ’string-closest’ and so return an hint
> > if there is a typo.

[...]

> Sounds good, the same "issue" exists for guix system subcommands, it
> would be cool to have such functionality, but I would like to have those
> changes to both guix system and guix home after wip-guix-home merged,
> because backporting changes to rde is a little tedious.

Your point is to hint both "guix system" and "guix home" in the same
time because they share the same pattern.  Right?

> Also, it seems related to subcommands/--arguments discussion and maybe
> better to talk about it in a separate thread.

Yes, and from my understanding, your answer is keep consistency with
"guix system". :-)

Cheers,
simon




Information forwarded to guix-patches <at> gnu.org:
bug#50296; Package guix-patches. (Tue, 31 Aug 2021 14:25:02 GMT) Full text and rfc822 format available.

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

From: Oleg Pykhalov <go.wigust <at> gmail.com>
To: Andrew Tropin <andrew <at> trop.in>
Cc: 50296-done <at> debbugs.gnu.org
Subject: Re: [bug#50296] [PATCH 0/2] Add 'guix home' command.
Date: Tue, 31 Aug 2021 17:23:39 +0300
[Message part 1 (text/plain, inline)]
Andrew Tropin <andrew <at> trop.in> writes:

[…]

> The functions from home-services-utils used by xdg now in home-services
> utils:
>
> From efd3ea79905c12e2c1c594fa6b54cf62d741f92f Mon Sep 17 00:00:00 2001
> From: Andrew Tropin <andrew <at> trop.in>
> Date: Tue, 31 Aug 2021 15:40:07 +0300
> Subject: [PATCH 2/2] home-services: configuration: Add
>  generic-serialize-alist.
>
> * gnu/home-services/configuration.scm (generic-serialize-alist)
> (generic-serialize-alist-entry): New variables.

As you said, no variables, but functions ;-)

Also, we could join those functions in Git commit message with comma.

Applied with changes above.

[…]

>> run-on-change service doesn't handle the case, where the previous
>> generation doesn't exists.  Fix should be pretty simple, will send a
>> patch once it done.  Thank you for catching this)
>>
>
> The fix:
>
> From a07541380d412b33c504e5811776062af4e38582 Mon Sep 17 00:00:00 2001
> From: Andrew Tropin <andrew <at> trop.in>
> Date: Tue, 31 Aug 2021 15:24:25 +0300
> Subject: [PATCH 1/2] home-services: run-on-change: Handle first generation
>  case.
>
> ---
>  gnu/home-services.scm | 5 +++--
>  1 file changed, 3 insertions(+), 2 deletions(-)

[…]

Added Git changelog-like line.

Applied.

Pushed to wip-guix-home as 0c7bb26435513a61814d98af1c790e43a74afb6e.

Oleg.
[signature.asc (application/pgp-signature, inline)]

Information forwarded to guix-patches <at> gnu.org:
bug#50296; Package guix-patches. (Wed, 01 Sep 2021 05:21:02 GMT) Full text and rfc822 format available.

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

From: Andrew Tropin <andrew <at> trop.in>
To: zimoun <zimon.toutoune <at> gmail.com>
Cc: 50296 <at> debbugs.gnu.org
Subject: Re: [bug#50296] [PATCH 1/2] scripts: Add 'guix home'.
Date: Wed, 01 Sep 2021 08:20:17 +0300
[Message part 1 (text/plain, inline)]
On 2021-08-31 15:09, zimoun wrote:

> Hi,
>
> On Tue, 31 Aug 2021 at 14:12, Andrew Tropin <andrew <at> trop.in> wrote:
>> On 2021-08-31 12:53, zimoun wrote:
>> > On Tue, 31 Aug 2021 at 12:40, Andrew Tropin <andrew <at> trop.in> wrote:
>> >
>> >> +(define-command (guix-home . args)
>> >> +  (synopsis "build and deploy home environments")
>> >> +
>> >> +  (define (parse-sub-command arg result)
>> >> +    ;; Parse sub-command ARG and augment RESULT accordingly.
>> >> +    (if (assoc-ref result 'action)
>> >> +        (alist-cons 'argument arg result)
>> >> +        (let ((action (string->symbol arg)))
>> >> +          (case action
>> >> +            ((build
>> >> +              reconfigure
>> >> +              extension-graph shepherd-graph
>> >> +              list-generations describe
>> >> +              delete-generations roll-back
>> >> +              switch-generation search
>> >> +              import)
>> >> +             (alist-cons 'action action result))
>> >> +            (else (leave (G_ "~a: unknown action~%") action))))))
>> >
>> > For parsing the actions, I would define elsewhere the list.  Then if the
>> > action is unknown, you could use ’string-closest’ and so return an hint
>> > if there is a typo.
>
> [...]
>
>> Sounds good, the same "issue" exists for guix system subcommands, it
>> would be cool to have such functionality, but I would like to have those
>> changes to both guix system and guix home after wip-guix-home merged,
>> because backporting changes to rde is a little tedious.
>
> Your point is to hint both "guix system" and "guix home" in the same
> time because they share the same pattern.  Right?
>
>> Also, it seems related to subcommands/--arguments discussion and maybe
>> better to talk about it in a separate thread.
>
> Yes, and from my understanding, your answer is keep consistency with
> "guix system". :-)
>
> Cheers,
> simon

Yep, corret (:

[signature.asc (application/pgp-signature, inline)]

Information forwarded to guix-patches <at> gnu.org:
bug#50296; Package guix-patches. (Wed, 01 Sep 2021 05:37:01 GMT) Full text and rfc822 format available.

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

From: Andrew Tropin <andrew <at> trop.in>
To: Oleg Pykhalov <go.wigust <at> gmail.com>
Cc: 50296-done <at> debbugs.gnu.org
Subject: Re: [bug#50296] [PATCH 0/2] Add 'guix home' command.
Date: Wed, 01 Sep 2021 08:36:21 +0300
[Message part 1 (text/plain, inline)]
On 2021-08-31 17:23, Oleg Pykhalov wrote:

> Andrew Tropin <andrew <at> trop.in> writes:
>
> […]
>
>> The functions from home-services-utils used by xdg now in home-services
>> utils:
>>
>> From efd3ea79905c12e2c1c594fa6b54cf62d741f92f Mon Sep 17 00:00:00 2001
>> From: Andrew Tropin <andrew <at> trop.in>
>> Date: Tue, 31 Aug 2021 15:40:07 +0300
>> Subject: [PATCH 2/2] home-services: configuration: Add
>>  generic-serialize-alist.
>>
>> * gnu/home-services/configuration.scm (generic-serialize-alist)
>> (generic-serialize-alist-entry): New variables.
>
> As you said, no variables, but functions ;-)
>
> Also, we could join those functions in Git commit message with comma.
>
> Applied with changes above.
>
> […]
>
>>> run-on-change service doesn't handle the case, where the previous
>>> generation doesn't exists.  Fix should be pretty simple, will send a
>>> patch once it done.  Thank you for catching this)
>>>
>>
>> The fix:
>>
>> From a07541380d412b33c504e5811776062af4e38582 Mon Sep 17 00:00:00 2001
>> From: Andrew Tropin <andrew <at> trop.in>
>> Date: Tue, 31 Aug 2021 15:24:25 +0300
>> Subject: [PATCH 1/2] home-services: run-on-change: Handle first generation
>>  case.
>>
>> ---
>>  gnu/home-services.scm | 5 +++--
>>  1 file changed, 3 insertions(+), 2 deletions(-)
>
> […]
>
> Added Git changelog-like line.
>
> Applied.
>
> Pushed to wip-guix-home as 0c7bb26435513a61814d98af1c790e43a74afb6e.
>
> Oleg.


Cool, seems now we have a working copy of guix home in wip-guix-home,
I'll start cleaning up the documentation and prepare it for merging.

Thank you for your help with all that stuff)
[signature.asc (application/pgp-signature, inline)]

Information forwarded to guix-patches <at> gnu.org:
bug#50296; Package guix-patches. (Thu, 09 Sep 2021 06:11:01 GMT) Full text and rfc822 format available.

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

From: Andrew Tropin <andrew <at> trop.in>
To: Oleg Pykhalov <go.wigust <at> gmail.com>
Cc: 50296-done <at> debbugs.gnu.org
Subject: Re: [bug#50296] [PATCH 0/2] Add 'guix home' command.
Date: Thu, 09 Sep 2021 09:10:16 +0300
[Message part 1 (text/plain, inline)]
On 2021-08-31 17:23, Oleg Pykhalov wrote:

> Andrew Tropin <andrew <at> trop.in> writes:
>
> […]
>
>> The functions from home-services-utils used by xdg now in home-services
>> utils:
>>
>> From efd3ea79905c12e2c1c594fa6b54cf62d741f92f Mon Sep 17 00:00:00 2001
>> From: Andrew Tropin <andrew <at> trop.in>
>> Date: Tue, 31 Aug 2021 15:40:07 +0300
>> Subject: [PATCH 2/2] home-services: configuration: Add
>>  generic-serialize-alist.
>>
>> * gnu/home-services/configuration.scm (generic-serialize-alist)
>> (generic-serialize-alist-entry): New variables.
>
> As you said, no variables, but functions ;-)
>
> Also, we could join those functions in Git commit message with comma.
>
> Applied with changes above.
>
> […]
>
>>> run-on-change service doesn't handle the case, where the previous
>>> generation doesn't exists.  Fix should be pretty simple, will send a
>>> patch once it done.  Thank you for catching this)
>>>
>>
>> The fix:
>>
>> From a07541380d412b33c504e5811776062af4e38582 Mon Sep 17 00:00:00 2001
>> From: Andrew Tropin <andrew <at> trop.in>
>> Date: Tue, 31 Aug 2021 15:24:25 +0300
>> Subject: [PATCH 1/2] home-services: run-on-change: Handle first generation
>>  case.
>>
>> ---
>>  gnu/home-services.scm | 5 +++--
>>  1 file changed, 3 insertions(+), 2 deletions(-)
>
> […]
>
> Added Git changelog-like line.
>
> Applied.
>
> Pushed to wip-guix-home as 0c7bb26435513a61814d98af1c790e43a74afb6e.
>
> Oleg.

I did a little better solution for the first generation case for
on-change service.  Added it as fixup commit, so it's necessary to
rebase with --autosquash to get it melded in the right place.  Can you
also rebase the whole branch on the latest master and recreate it,
please?  I'll test it and will be preparing for merge.  Probably will
send a few more patches, but they should be minor.

[0001-fixup-home-services-run-on-change-Handle-first-gener.patch (text/x-patch, inline)]
From 6f3ec7f6bb4a6f495c4b7f38fce7cb31d179097b Mon Sep 17 00:00:00 2001
From: Andrew Tropin <andrew <at> trop.in>
Date: Wed, 8 Sep 2021 08:15:35 +0300
Subject: [PATCH] fixup! home-services: run-on-change: Handle first generation
 case.

---
 gnu/home-services.scm | 11 +++++++----
 1 file changed, 7 insertions(+), 4 deletions(-)

diff --git a/gnu/home-services.scm b/gnu/home-services.scm
index 5608c65175..9f1e986616 100644
--- a/gnu/home-services.scm
+++ b/gnu/home-services.scm
@@ -439,7 +439,10 @@ with one gexp, but many times, and all gexps must be idempotent.")))
       (define expressions-to-eval
         (map
          (lambda (x)
-           (let* ((file1 (string-append (getenv "GUIX_OLD_HOME") "/" (car x)))
+           (let* ((file1 (string-append
+                          (or (getenv "GUIX_OLD_HOME")
+                              "/gnu/store/non-existing-generation")
+                          "/" (car x)))
                   (file2 (string-append (getenv "GUIX_NEW_HOME") "/" (car x)))
                   (_ (format #t "Comparing ~a and\n~10t~a..." file1 file2))
                   (any-changes? (something-changed? file1 file2))
@@ -448,14 +451,14 @@ with one gexp, but many times, and all gexps must be idempotent.")))
              (if any-changes? (cadr x) "")))
          '#$pattern-gexp-tuples))
 
-      (if (and #$eval-gexps? (getenv "GUIX_OLD_HOME"))
+      (if #$eval-gexps?
           (begin
             (display "Evaling on-change gexps.\n\n")
             (for-each primitive-eval expressions-to-eval)
             (display "On-change gexps evaluation finished.\n\n"))
           (display "\
-On-change gexps won't evaluated, disabled by service configuration or
-there are no previos generations.\n"))))
+On-change gexps won't be evaluated, disabled by service
+configuration.\n"))))
 
 (define home-run-on-change-service-type
   (service-type (name 'home-run-on-change)
-- 
2.33.0

[signature.asc (application/pgp-signature, inline)]

Information forwarded to guix-patches <at> gnu.org:
bug#50296; Package guix-patches. (Thu, 09 Sep 2021 17:47:01 GMT) Full text and rfc822 format available.

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

From: Oleg Pykhalov <go.wigust <at> gmail.com>
To: Andrew Tropin <andrew <at> trop.in>
Cc: 50296-done <at> debbugs.gnu.org
Subject: Re: [bug#50296] [PATCH 0/2] Add 'guix home' command.
Date: Thu, 09 Sep 2021 20:45:55 +0300
[Message part 1 (text/plain, inline)]
Andrew Tropin <andrew <at> trop.in> writes:

[…]

> I did a little better solution for the first generation case for
> on-change service.  Added it as fixup commit, so it's necessary to
> rebase with --autosquash to get it melded in the right place.  Can you
> also rebase the whole branch on the latest master and recreate it,
> please?  I'll test it and will be preparing for merge.  Probably will
> send a few more patches, but they should be minor.
>
> From 6f3ec7f6bb4a6f495c4b7f38fce7cb31d179097b Mon Sep 17 00:00:00 2001
> From: Andrew Tropin <andrew <at> trop.in>
> Date: Wed, 8 Sep 2021 08:15:35 +0300
> Subject: [PATCH] fixup! home-services: run-on-change: Handle first generation
>  case.
>
> ---
>  gnu/home-services.scm | 11 +++++++----
>  1 file changed, 7 insertions(+), 4 deletions(-)

I did what you asked, but please, don't depend on recreating the branch
next time.  Otherwise we will wait for other contributers decision about
this approach.  Every branch recreation guix-commits mailing list
receives a batch of messages, which could annoy subscribers.

Thanks,
Oleg.

[signature.asc (application/pgp-signature, inline)]

Information forwarded to guix-patches <at> gnu.org:
bug#50296; Package guix-patches. (Fri, 10 Sep 2021 05:32:02 GMT) Full text and rfc822 format available.

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

From: Andrew Tropin <andrew <at> trop.in>
To: Oleg Pykhalov <go.wigust <at> gmail.com>
Cc: 50296-done <at> debbugs.gnu.org
Subject: Re: [bug#50296] [PATCH 0/2] Add 'guix home' command.
Date: Fri, 10 Sep 2021 08:31:37 +0300
[Message part 1 (text/plain, inline)]
On 2021-09-09 20:45, Oleg Pykhalov wrote:

> Andrew Tropin <andrew <at> trop.in> writes:
>
> […]
>
>> I did a little better solution for the first generation case for
>> on-change service.  Added it as fixup commit, so it's necessary to
>> rebase with --autosquash to get it melded in the right place.  Can you
>> also rebase the whole branch on the latest master and recreate it,
>> please?  I'll test it and will be preparing for merge.  Probably will
>> send a few more patches, but they should be minor.
>>
>> From 6f3ec7f6bb4a6f495c4b7f38fce7cb31d179097b Mon Sep 17 00:00:00 2001
>> From: Andrew Tropin <andrew <at> trop.in>
>> Date: Wed, 8 Sep 2021 08:15:35 +0300
>> Subject: [PATCH] fixup! home-services: run-on-change: Handle first generation
>>  case.
>>
>> ---
>>  gnu/home-services.scm | 11 +++++++----
>>  1 file changed, 7 insertions(+), 4 deletions(-)
>
> I did what you asked, but please, don't depend on recreating the branch
> next time.  Otherwise we will wait for other contributers decision about
> this approach.  Every branch recreation guix-commits mailing list
> receives a batch of messages, which could annoy subscribers.
>
> Thanks,
> Oleg.

Thank you!

Didn't think about guix-commits ML, ok, will try to avoid this next
time)
[signature.asc (application/pgp-signature, inline)]

bug archived. Request was from Debbugs Internal Request <help-debbugs <at> gnu.org> to internal_control <at> debbugs.gnu.org. (Fri, 08 Oct 2021 11:24:04 GMT) Full text and rfc822 format available.

This bug report was last modified 2 years and 172 days ago.

Previous Next


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