Message ID | 197cab14424f4d28ece9e80981d2a4e142dc4791.1633861021.git.public@yoctocell.xyz |
---|---|
State | Accepted |
Headers | show |
Series | Fixes to ‘guix home import’ | expand |
Context | Check | Description |
---|---|---|
cbaines/comparison | success | View comparision |
cbaines/git branch | success | View Git branch |
cbaines/applying patch | success | View Laminar job |
cbaines/issue | success | View issue |
cbaines/comparison | success | View comparision |
cbaines/git branch | success | View Git branch |
cbaines/applying patch | success | View Laminar job |
cbaines/issue | success | View issue |
cbaines/comparison | success | View comparision |
cbaines/git branch | success | View Git branch |
cbaines/applying patch | success | View Laminar job |
cbaines/issue | success | View issue |
cbaines/comparison | success | View comparision |
cbaines/git branch | success | View Git branch |
cbaines/applying patch | success | View Laminar job |
cbaines/issue | success | View issue |
cbaines/comparison | success | View comparision |
cbaines/git branch | success | View Git branch |
cbaines/applying patch | success | View Laminar job |
cbaines/comparison | success | View comparision |
cbaines/git branch | success | View Git branch |
cbaines/issue | success | View issue |
cbaines/applying patch | success | View Laminar job |
cbaines/issue | success | View issue |
Hi, Xinglu Chen <public@yoctocell.xyz> writes: […] > +;; Helpers for checking and generating home environments. > + > +(%destination-directory "/tmp/guix-config") > +(mkdir-p (%destination-directory)) > + > +(define %temporary-home-directory "/tmp/guix-home-import-test") Better use temporary directory like in tests/opam.scm. --8<---------------cut here---------------start------------->8--- (define-module ... #:use-module ((guix build syscalls) #:select (mkdtemp!)) ...) (mkdtemp! "/tmp/guix-home-import-test.XXXXXX") --8<---------------cut here---------------end--------------->8--- > + > +(define-syntax-rule (define-home-environment-matcher name pattern) > + (define (name obj) > + (match obj > + (pattern #t) > + (x (pk 'fail x #f))))) > + > +(define (create-temporary-home files-alist) > + "Create a temporary home directory in '%temporary-home-directory'. > +FILES-ALIST is an association list of files and the content of the > +corresponding file." > + (define (create-file file content) > + (let ((absolute-path (string-append %temporary-home-directory "/" file))) > + (unless (file-exists? absolute-path) > + (mkdir-p (pk (dirname absolute-path)))) > + (call-with-output-file (pk absolute-path) > + (cut display content <>)))) Do we need those 'pk' calls? […] > +(define-home-environment-matcher match-home-environment-bash-service > + ('begin > + ('use-modules > + ('gnu 'home) > + ('gnu 'packages) > + ('gnu 'home 'services 'shells)) > + ('home-environment > + ('packages > + ('map 'specification->package > + ('list))) > + ('services > + ('list ('service > + 'home-bash-service-type > + ('home-bash-configuration > + ('bashrc > + ('list ('local-file "/tmp/guix-config/.bashrc")))))))))) We should use '%temporary-home-directory' if we use 'mkdtemp!'. > + > +(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 packages nor services" > + (eval-test-with-home-environment > + '() > + (make-manifest '()) > + match-home-environment-no-services-nor-packages)) > + > +(test-assert "manifest->code: Bash service" > + (eval-test-with-home-environment > + '((".bashrc" . "echo 'hello guix'")) > + (make-manifest '()) > + match-home-environment-bash-service)) > + > +(test-end "home-import") I tried to use 'guix home import /tmp/foo', where '/tmp/foo' is an empty directory. Then a pasted the generated code to '/tmp/foo/home.scm' file. --8<---------------cut here---------------start------------->8--- oleg@guixsd ~/src/guix [env]$ ./pre-inst-env guix home build /tmp/foo/home.scm /tmp/foo/home.scm:487:11: error: service: unbound variable hint: Did you forget `(use-modules (gnu services))'? --8<---------------cut here---------------end--------------->8--- OK, added missing (use-modules (gnu services)). --8<---------------cut here---------------start------------->8--- oleg@guixsd ~/src/guix [env]$ ./pre-inst-env guix home build /tmp/foo/home.scm /tmp/foo/home.scm:491:29: error: local-file: unbound variable hint: Did you forget `(use-modules (guix gexp))'? --8<---------------cut here---------------end--------------->8--- OK, added missing (use-modules (guix gexp)) --8<---------------cut here---------------start------------->8--- oleg@guixsd ~/src/guix [env]$ oleg@guixsd ~/src/guix [env]$ ./pre-inst-env guix home build /tmp/foo/home.scm guix home: error: invalid name: `.bashrc' --8<---------------cut here---------------end--------------->8--- Now, I need to rename .bashrc to dot-bashrc and .bash_profile to dot-bash_profile. Maybe we should save all dot file with a 'dot-' prefix by default? Oleg.
Hi Xinglu and all! It all LGTM, except for the issues that Oleg reports. Xinglu, could you send one last version of this patch series addressing Oleg’s comments? Thanks, Ludo’.
Hello! It’s been a month already. Oleg, perhaps you could make those final modifications on behalf on Xinglu so we can move forward? We’re almost there! Thanks, Ludo’. Ludovic Courtès <ludo@gnu.org> skribis: > Hi Xinglu and all! > > It all LGTM, except for the issues that Oleg reports. > > Xinglu, could you send one last version of this patch series addressing > Oleg’s comments? > > Thanks, > Ludo’.
On Mon, Oct 11 2021, Oleg Pykhalov wrote: > Hi, > > Xinglu Chen <public@yoctocell.xyz> writes: > > […] > >> +;; Helpers for checking and generating home environments. >> + >> +(%destination-directory "/tmp/guix-config") >> +(mkdir-p (%destination-directory)) >> + >> +(define %temporary-home-directory "/tmp/guix-home-import-test") > > Better use temporary directory like in tests/opam.scm. > > --8<---------------cut here---------------start------------->8--- > (define-module ... > #:use-module ((guix build syscalls) #:select (mkdtemp!)) > ...) > > (mkdtemp! "/tmp/guix-home-import-test.XXXXXX") > --8<---------------cut here---------------end--------------->8--- Good idea. Out of curiosity: is there any difference between ‘mkdtemp!’ and ‘mkdtemp’ that’s part of Guile? >> + >> +(define-syntax-rule (define-home-environment-matcher name pattern) >> + (define (name obj) >> + (match obj >> + (pattern #t) >> + (x (pk 'fail x #f))))) >> + >> +(define (create-temporary-home files-alist) >> + "Create a temporary home directory in '%temporary-home-directory'. >> +FILES-ALIST is an association list of files and the content of the >> +corresponding file." >> + (define (create-file file content) >> + (let ((absolute-path (string-append %temporary-home-directory "/" file))) >> + (unless (file-exists? absolute-path) >> + (mkdir-p (pk (dirname absolute-path)))) >> + (call-with-output-file (pk absolute-path) >> + (cut display content <>)))) > > Do we need those 'pk' calls? Nope, just some leftover stuff that I forgot to remove… >> +(define-home-environment-matcher match-home-environment-bash-service >> + ('begin >> + ('use-modules >> + ('gnu 'home) >> + ('gnu 'packages) >> + ('gnu 'home 'services 'shells)) >> + ('home-environment >> + ('packages >> + ('map 'specification->package >> + ('list))) >> + ('services >> + ('list ('service >> + 'home-bash-service-type >> + ('home-bash-configuration >> + ('bashrc >> + ('list ('local-file "/tmp/guix-config/.bashrc")))))))))) > > We should use '%temporary-home-directory' if we use 'mkdtemp!'. I don’t think so, the ‘bashrc’ file will be copied _from_ ‘%temporary-home-directory’ to ‘%destination-directory’, so this should be ‘%destination-directory’. >> + >> +(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 packages nor services" >> + (eval-test-with-home-environment >> + '() >> + (make-manifest '()) >> + match-home-environment-no-services-nor-packages)) >> + >> +(test-assert "manifest->code: Bash service" >> + (eval-test-with-home-environment >> + '((".bashrc" . "echo 'hello guix'")) >> + (make-manifest '()) >> + match-home-environment-bash-service)) >> + >> +(test-end "home-import") > > I tried to use 'guix home import /tmp/foo', where '/tmp/foo' is an empty > directory. Then a pasted the generated code to '/tmp/foo/home.scm' > file. > > --8<---------------cut here---------------start------------->8--- > oleg@guixsd ~/src/guix [env]$ ./pre-inst-env guix home build /tmp/foo/home.scm > /tmp/foo/home.scm:487:11: error: service: unbound variable > hint: Did you forget `(use-modules (gnu services))'? > --8<---------------cut here---------------end--------------->8--- > > OK, added missing (use-modules (gnu services)). > > --8<---------------cut here---------------start------------->8--- > oleg@guixsd ~/src/guix [env]$ ./pre-inst-env guix home build /tmp/foo/home.scm > /tmp/foo/home.scm:491:29: error: local-file: unbound variable > hint: Did you forget `(use-modules (guix gexp))'? > --8<---------------cut here---------------end--------------->8--- > > OK, added missing (use-modules (guix gexp)) > > --8<---------------cut here---------------start------------->8--- > oleg@guixsd ~/src/guix [env]$ > oleg@guixsd ~/src/guix [env]$ ./pre-inst-env guix home build /tmp/foo/home.scm > guix home: error: invalid name: `.bashrc' > --8<---------------cut here---------------end--------------->8--- > > Now, I need to rename .bashrc to dot-bashrc and .bash_profile to > dot-bash_profile. Maybe we should save all dot file with a 'dot-' > prefix by default? Ah, thanks for catching this! I think it would be better to call ‘local-file’ with the optional ‘name’ argument like this: (local-file "/some/path/.bashrc" "bashrc") That also means that the “/some/path/” part won’t end up as part of the /gnu/store/… file name.
Hi, Xinglu Chen <public@yoctocell.xyz> skribis: > On Mon, Oct 11 2021, Oleg Pykhalov wrote: > >> Hi, >> >> Xinglu Chen <public@yoctocell.xyz> writes: >> >> […] >> >>> +;; Helpers for checking and generating home environments. >>> + >>> +(%destination-directory "/tmp/guix-config") >>> +(mkdir-p (%destination-directory)) >>> + >>> +(define %temporary-home-directory "/tmp/guix-home-import-test") >> >> Better use temporary directory like in tests/opam.scm. >> >> --8<---------------cut here---------------start------------->8--- >> (define-module ... >> #:use-module ((guix build syscalls) #:select (mkdtemp!)) >> ...) >> >> (mkdtemp! "/tmp/guix-home-import-test.XXXXXX") >> --8<---------------cut here---------------end--------------->8--- > > Good idea. Out of curiosity: is there any difference between ‘mkdtemp!’ > and ‘mkdtemp’ that’s part of Guile? ‘mkdtemp’ is new in Guile 3.0.6 but Guix can be built with an older version. Ludo’.
diff --git a/Makefile.am b/Makefile.am index 635147efc1..f93199e561 100644 --- a/Makefile.am +++ b/Makefile.am @@ -474,6 +474,7 @@ SCM_TESTS = \ tests/graph.scm \ tests/gremlin.scm \ tests/hackage.scm \ + tests/home-import.scm \ tests/import-git.scm \ tests/import-utils.scm \ tests/inferior.scm \ diff --git a/guix/scripts/home/import.scm b/guix/scripts/home/import.scm index b892ae3dfa..c68cfb9e78 100644 --- a/guix/scripts/home/import.scm +++ b/guix/scripts/home/import.scm @@ -28,7 +28,10 @@ (define-module (guix scripts home import) #:use-module (srfi srfi-1) #:use-module (srfi srfi-26) #:export (import-manifest - %destination-directory)) + %destination-directory + + ;; For tests. + manifest->code)) ;;; Commentary: ;;; diff --git a/tests/home-import.scm b/tests/home-import.scm new file mode 100644 index 0000000000..8d141bba0f --- /dev/null +++ b/tests/home-import.scm @@ -0,0 +1,174 @@ +;;; GNU Guix --- Functional package management for GNU +;;; Copyright © 2021 Xinglu Chen <public@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 (test-home-import) + #:use-module (guix scripts home import) + #:use-module (guix utils) + #:use-module (guix build utils) + #:use-module (guix packages) + #:use-module (ice-9 match) + #:use-module ((guix profiles) #:hide (manifest->code)) + #:use-module (gnu packages) + #:use-module (srfi srfi-1) + #:use-module (srfi srfi-26) + #:use-module (srfi srfi-64)) + +;; Test the (guix scripts home import) tools. + +(test-begin "home-import") + +;; Example manifest entries. + +(define guile-2.0.9 + (manifest-entry + (name "guile") + (version "2.0.9") + (item "/gnu/store/..."))) + +(define glibc + (manifest-entry + (name "glibc") + (version "2.19") + (item "/gnu/store/..."))) + +(define gcc + (manifest-entry + (name "gcc") + (version "10.3.0") + (item "/gnu/store/..."))) + +;; Helpers for checking and generating home environments. + +(%destination-directory "/tmp/guix-config") +(mkdir-p (%destination-directory)) + +(define %temporary-home-directory "/tmp/guix-home-import-test") + +(define-syntax-rule (define-home-environment-matcher name pattern) + (define (name obj) + (match obj + (pattern #t) + (x (pk 'fail x #f))))) + +(define (create-temporary-home files-alist) + "Create a temporary home directory in '%temporary-home-directory'. +FILES-ALIST is an association list of files and the content of the +corresponding file." + (define (create-file file content) + (let ((absolute-path (string-append %temporary-home-directory "/" file))) + (unless (file-exists? absolute-path) + (mkdir-p (pk (dirname absolute-path)))) + (call-with-output-file (pk absolute-path) + (cut display content <>)))) + + (for-each (match-lambda + ((file . content) (create-file file content))) + (pk files-alist))) + +;; Copied from (guix profiles) +(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))))))) + +(define (eval-test-with-home-environment files-alist manifest matcher) + (create-temporary-home files-alist) + (setenv "HOME" %temporary-home-directory) + (mkdir-p %temporary-home-directory) + (let* ((home-environment (manifest->code manifest + #:entry-package-version version-spec + #:home-environment? #t)) + (result (matcher home-environment))) + (delete-file-recursively %temporary-home-directory) + result)) + +(define-home-environment-matcher match-home-environment-no-services + ('begin + ('use-modules + ('gnu 'home) + ('gnu 'packages)) + ('home-environment + ('packages + ('map 'specification->package + ('list "guile@2.0.9" "gcc" "glibc@2.19"))) + ('services + ('list))))) + +(define-home-environment-matcher match-home-environment-no-services-nor-packages + ('begin + ('use-modules + ('gnu 'home) + ('gnu 'packages)) + ('home-environment + ('packages + ('map 'specification->package + ('list))) + ('services + ('list))))) + +(define-home-environment-matcher match-home-environment-bash-service + ('begin + ('use-modules + ('gnu 'home) + ('gnu 'packages) + ('gnu 'home 'services 'shells)) + ('home-environment + ('packages + ('map 'specification->package + ('list))) + ('services + ('list ('service + 'home-bash-service-type + ('home-bash-configuration + ('bashrc + ('list ('local-file "/tmp/guix-config/.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 packages nor services" + (eval-test-with-home-environment + '() + (make-manifest '()) + match-home-environment-no-services-nor-packages)) + +(test-assert "manifest->code: Bash service" + (eval-test-with-home-environment + '((".bashrc" . "echo 'hello guix'")) + (make-manifest '()) + match-home-environment-bash-service)) + +(test-end "home-import")