diff options
author | Ludovic Courtès <ludo@gnu.org> | 2017-11-08 13:33:25 +0100 |
---|---|---|
committer | Ludovic Courtès <ludo@gnu.org> | 2017-11-08 22:36:20 +0100 |
commit | c5a4a92f1a796e342b7db4c458f1fdb61ffc8d40 (patch) | |
tree | b7b59ee6fc7d0153120b333c82145a830b83988a | |
parent | 49483f71381ad32cdbe81b1c8ed2cc023329cc18 (diff) | |
download | guix-c5a4a92f1a796e342b7db4c458f1fdb61ffc8d40.tar guix-c5a4a92f1a796e342b7db4c458f1fdb61ffc8d40.tar.gz |
gnu: Improve error reporting of the use-.*modules macros.
Suggested by Julien Lepiller and myglc2
at <https://lists.gnu.org/archive/html/guix-devel/2017-11/msg00106.html>.
* gnu.scm (%try-use-modules): New procedure.
(package-module-hint, service-module-hint): New procedures.
(try-use-modules): New macro.
(use-package-modules, use-service-modules, use-system-modules): Use it.
* tests/guix-system.sh: Test it.
-rw-r--r-- | gnu.scm | 100 | ||||
-rw-r--r-- | po/guix/POTFILES.in | 1 | ||||
-rw-r--r-- | tests/guix-system.sh | 28 |
3 files changed, 125 insertions, 4 deletions
@@ -1,5 +1,5 @@ ;;; GNU Guix --- Functional package management for GNU -;;; Copyright © 2014, 2015, 2016 Ludovic Courtès <ludo@gnu.org> +;;; Copyright © 2014, 2015, 2016, 2017 Ludovic Courtès <ludo@gnu.org> ;;; Copyright © 2015 Joshua S. Grant <jgrant@parenthetical.io> ;;; Copyright © 2017 Mathieu Othacehe <m.othacehe@gmail.com> ;;; @@ -19,6 +19,14 @@ ;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>. (define-module (gnu) + #:use-module (guix i18n) + #:use-module (guix utils) + #:use-module (srfi srfi-34) + #:use-module (srfi srfi-35) + #:use-module (ice-9 match) + #:use-module (guix packages) + #:use-module (gnu packages) + #:use-module (gnu services) #:export (use-package-modules use-service-modules use-system-modules)) @@ -52,13 +60,97 @@ (module-use! i (resolve-interface m)))) %public-modules))) +(define (%try-use-modules modules location make-hint) + "Attempt to load all of MODULES. Report errors as coming from LOCATION, a +<location> record, and use MAKE-HINT to produce a fix hint." + (define (location->string loc) + (match loc + (#f "") + (($ <location> file line column) + (format #f "~a:~a:~a: " file line column)))) + + (for-each (lambda (module) + (catch 'misc-error + (lambda () + (process-use-modules `((,module)))) + (lambda _ + (raise + (apply + make-compound-condition + (condition + (&message + (message (format #f (G_ "module ~a not found") + module)))) + (condition + (&error-location (location location))) + (or (and=> (make-hint module) list) + '())))))) + modules)) + +(define (package-module-hint module) + (define last-name + (match module + ((_ ... last) + (symbol->string last)))) + + (match (find-packages-by-name last-name) + (() + (condition + (&fix-hint + (hint (G_ "\ +You may use @command{guix package --show=foo | grep location} to search +for the location of package @code{foo}. +If you get the line @code{location: gnu/packages/bar.scm:174:2}, +add @code{bar} to the @code{use-package-modules} form."))))) + ((package _ ...) + (condition + (&fix-hint + (hint (format #f (G_ "\ +Try adding @code{(use-package-modules ~a)}.") + (basename (location-file (package-location package)) + ".scm")))))))) + +(define (service-module-hint module) + (define last-name + (match module + ((_ ... last) + last))) + + (match (lookup-service-types last-name) + (() + (condition + (&fix-hint + (hint (format #f (G_ "\ +You may use @command{guix system search ~a} to search for a service +matching @code{~a}. +If you get the line @code{location: gnu/services/foo.scm:188:2}, +add @code{foo} to the @code{use-service-modules} form.") + last-name last-name))))) + ((package _ ...) + (condition + (&fix-hint + (hint (format #f (G_ "\ +Try adding @code{(use-service-modules ~a)}.") + (basename (location-file (service-type-location package)) + ".scm")))))))) + +(define-syntax-rule (try-use-modules hint modules ...) + (eval-when (expand load eval) + (%try-use-modules '(modules ...) + (source-properties->location + (current-source-location)) + hint))) + (define-syntax-rule (use-package-modules module ...) - (use-modules (gnu packages module) ...)) + (try-use-modules package-module-hint + (gnu packages module) ...)) (define-syntax-rule (use-service-modules module ...) - (use-modules (gnu services module) ...)) + (try-use-modules service-module-hint + (gnu services module) ...)) (define-syntax-rule (use-system-modules module ...) - (use-modules (gnu system module) ...)) + (try-use-modules (const #f) ;no hint + (gnu system module) ...)) ;;; gnu.scm ends here diff --git a/po/guix/POTFILES.in b/po/guix/POTFILES.in index e3f767cc67..6510b99e8f 100644 --- a/po/guix/POTFILES.in +++ b/po/guix/POTFILES.in @@ -1,5 +1,6 @@ # List of source files which contain translatable strings. # This should be source files of the various tools, and not package modules. +gnu.scm gnu/packages.scm gnu/services.scm gnu/system.scm diff --git a/tests/guix-system.sh b/tests/guix-system.sh index 31ee637133..1346d8d5a8 100644 --- a/tests/guix-system.sh +++ b/tests/guix-system.sh @@ -68,6 +68,34 @@ else fi +# Reporting of module not found errors. + +cat > "$tmpfile" <<EOF +;; Line 1. +(use-modules (gnu)) + (use-service-modules openssh) +EOF + +if guix system build "$tmpfile" -n 2> "$errorfile" +then false +else + grep "$tmpfile:3:2: .*module .*openssh.*not found" "$errorfile" + grep "Try.*use-service-modules ssh" "$errorfile" +fi + +cat > "$tmpfile" <<EOF +;; Line 1. +(use-modules (gnu)) + (use-package-modules qemu) +EOF + +if guix system build "$tmpfile" -n 2> "$errorfile" +then false +else + grep "$tmpfile:3:2: .*module .*qemu.*not found" "$errorfile" + grep "Try.*use-package-modules virtualization" "$errorfile" +fi + # Reporting of unbound variables. cat > "$tmpfile" <<EOF |