summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLudovic Courtès <ludo@gnu.org>2021-10-31 00:02:27 +0200
committerLudovic Courtès <ludo@gnu.org>2021-10-31 00:51:06 +0200
commit6f4ca78761471602e3af37ee1a33de446114039f (patch)
tree93183c29a4e162eec4a63990076afc1da4c21420
parent96728c54df365cc48f14a514b63616ff7a6d052b (diff)
downloadguix-patches-6f4ca78761471602e3af37ee1a33de446114039f.tar
guix-patches-6f4ca78761471602e3af37ee1a33de446114039f.tar.gz
home: import: Avoid duplication of 'manifest->code'.
* guix/scripts/home/import.scm (manifest->code): Remove. (manifest+configuration-files->code): New procedure. (import-manifest): Use 'manifest+configuration-files->code' instead of 'manifest->code'. * tests/home-import.scm (eval-test-with-home-environment): Likewise. (match-home-environment-transformations): New procedure. ("manifest->code: No services, package transformations"): New test.
-rw-r--r--guix/scripts/home/import.scm176
-rw-r--r--tests/home-import.scm33
2 files changed, 69 insertions, 140 deletions
diff --git a/guix/scripts/home/import.scm b/guix/scripts/home/import.scm
index 8f6b3b58aa..7a7712dd96 100644
--- a/guix/scripts/home/import.scm
+++ b/guix/scripts/home/import.scm
@@ -1,6 +1,7 @@
;;; GNU Guix --- Functional package management for GNU
;;; Copyright © 2021 Xinglu Chen <public@yoctocell.xyz>
;;; Copyright © 2021 Andrew Tropin <andrew@trop.in>
+;;; Copyright © 2021 Ludovic Courtès <ludo@gnu.org>
;;;
;;; This file is part of GNU Guix.
;;;
@@ -31,7 +32,7 @@
#:export (import-manifest
;; For tests.
- manifest->code))
+ manifest+configuration-files->code))
;;; Commentary:
;;;
@@ -105,146 +106,49 @@ in CONFIGURATION-DIRECTORY."
(map (lambda (proc) (proc configuration-directory)) configurations))
-;; Based on `manifest->code' from (guix profiles)
-;; MAYBE: Upstream it?
-(define* (manifest->code manifest destination-directory
- #: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 ((configurations+modules
- (configurations+modules destination-directory)))
- `(begin
- (use-modules (gnu home)
- (gnu packages)
- (gnu services)
- ,@((compose delete-duplicates concatenate)
- (map cdr configurations+modules)))
- ,(home-environment-template
- #:specs specs
- #:services (map first configurations+modules))))
- `(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 ((configurations+modules
- (configurations+modules destination-directory)))
- `(begin
- (use-modules (guix transformations)
- (gnu home)
- (gnu packages)
- (gnu services)
- ,@((compose delete-duplicates concatenate)
- (map cdr configurations+modules)))
-
- ,@transformations
-
- ,(home-environment-template
- #:packages packages
- #:services (map first configurations+modules))))
- `(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 (manifest+configuration-files->code manifest
+ configuration-directory)
+ "Read MANIFEST and the user's configuration files listed in
+%FILES+CONFIGURATIONS-ALIST, and return a 'home-environment' sexp. Copy the
+user's files to CONFIGURATION-DIRECTORY; the generated sexp refers to them."
+ (match (manifest->code manifest
+ #:entry-package-version
+ manifest-entry-version-prefix)
+ (('begin ('use-modules profile-modules ...)
+ definitions ... ('packages->manifest packages))
+ (match (configurations+modules configuration-directory)
+ (((services . modules) ...)
+ `(begin
+ (use-modules (gnu home)
+ (gnu packages)
+ (gnu services)
+ ,@(delete-duplicates
+ (append profile-modules (concatenate modules))))
+
+ ,@definitions
+
+ (home-environment
+ (packages ,packages)
+ (services (list ,@services)))))))
+ (('begin ('specifications->manifest packages))
+ (match (configurations+modules configuration-directory)
+ (((services . modules) ...)
+ `(begin
+ (use-modules (gnu home)
+ (gnu packages)
+ (gnu services)
+ ,@(delete-duplicates (concatenate modules)))
+
+ (home-environment
+ (packages (map specification->package ,packages))
+ (services (list ,@services)))))))))
(define* (import-manifest
manifest destination-directory
#:optional (port (current-output-port)))
"Write to PORT a <home-environment> corresponding to MANIFEST."
- (match (manifest->code manifest destination-directory
- #:entry-package-version manifest-entry-version-prefix
- #:home-environment? #t)
+ (match (manifest+configuration-files->code manifest
+ destination-directory)
(('begin exp ...)
(format port (G_ "\
;; This \"home-environment\" file can be passed to 'guix home reconfigure'
diff --git a/tests/home-import.scm b/tests/home-import.scm
index dc413d8516..abd3cec43d 100644
--- a/tests/home-import.scm
+++ b/tests/home-import.scm
@@ -87,10 +87,8 @@ corresponding file."
(create-temporary-home files-alist)
(setenv "HOME" %temporary-home-directory)
(mkdir-p %temporary-home-directory)
- (let* ((home-environment (manifest->code manifest %destination-directory
- #:entry-package-version
- manifest-entry-version-prefix
- #:home-environment? #t))
+ (let* ((home-environment (manifest+configuration-files->code
+ manifest %destination-directory))
(result (matcher home-environment)))
(delete-file-recursively %temporary-home-directory)
result))
@@ -108,6 +106,22 @@ corresponding file."
('services
('list)))))
+(define-home-environment-matcher match-home-environment-transformations
+ ('begin
+ ('use-modules
+ ('gnu 'home)
+ ('gnu 'packages)
+ ('gnu 'services)
+ ('guix 'transformations))
+
+ ('define transform ('options->transformation _))
+ ('home-environment
+ ('packages
+ ('list (transform ('specification->package "guile@2.0.9"))
+ ('specification->package "gcc")
+ ('specification->package "glibc@2.19")))
+ ('services ('list)))))
+
(define-home-environment-matcher match-home-environment-no-services-nor-packages
('begin
('use-modules
@@ -141,12 +155,23 @@ corresponding file."
('list ('local-file "/tmp/guix-config/.bashrc"
"bashrc"))))))))))
+
(test-assert "manifest->code: No services"
(eval-test-with-home-environment
'()
(make-manifest (list guile-2.0.9 gcc glibc))
match-home-environment-no-services))
+(test-assert "manifest->code: No services, package transformations"
+ (eval-test-with-home-environment
+ '()
+ (make-manifest (list (manifest-entry
+ (inherit guile-2.0.9)
+ (properties `((transformations
+ . ((foo . "bar"))))))
+ gcc glibc))
+ match-home-environment-transformations))
+
(test-assert "manifest->code: No packages nor services"
(eval-test-with-home-environment
'()