summary refs log tree commit diff
diff options
context:
space:
mode:
authorLudovic Courtès <ludo@gnu.org>2014-11-05 17:56:39 +0100
committerLudovic Courtès <ludo@gnu.org>2014-11-05 17:56:39 +0100
commit467a3c93db5341864bbe76b68c137ba140616b59 (patch)
tree14d3ced65b370ae249a3b100448692bb8aafd70e
parent63854bcbb16e6b52edf966db428c4a1f049c3af5 (diff)
downloadguix-467a3c93db5341864bbe76b68c137ba140616b59.tar.gz
import: pypi: Gracefully handle non-existent packages.
Fixes <http://bugs.gnu.org/18831>.
Reported by Ian Denhardt <ian@zenhack.net>.

* guix/import/pypi.scm (url-fetch, json-fetch, pypi-fetch): Augment
  docstring to mention #f on failure.
  (pypi->guix-package): Likewise, and actually return #f on failure.
* guix/scripts/import/pypi.scm (guix-import-pypi): Call 'leave' when
  'pypi->guix-package' returns #f.
-rw-r--r--guix/import/pypi.scm28
-rw-r--r--guix/scripts/import/pypi.scm6
2 files changed, 20 insertions, 14 deletions
diff --git a/guix/import/pypi.scm b/guix/import/pypi.scm
index 6480c044c5..88f4a8e896 100644
--- a/guix/import/pypi.scm
+++ b/guix/import/pypi.scm
@@ -89,12 +89,12 @@ recursively apply the procedure to the sub-list."
    (_ #f)))
 
 (define (url-fetch url file-name)
-  "Save the contents of URL to FILE-NAME."
+  "Save the contents of URL to FILE-NAME.  Return #f on failure."
   (parameterize ((current-output-port (current-error-port)))
     (build:url-fetch url file-name)))
 
 (define (json-fetch url)
-  "Return an alist representation of the JSON resource URL."
+  "Return an alist representation of the JSON resource URL, or #f on failure."
   (call-with-temporary-output-file
    (lambda (temp port)
      (and (url-fetch url temp)
@@ -102,7 +102,8 @@ recursively apply the procedure to the sub-list."
            (call-with-input-file temp json->scm))))))
 
 (define (pypi-fetch name)
-  "Return an alist representation of the PyPI metadata for the package NAME."
+  "Return an alist representation of the PyPI metadata for the package NAME,
+or #f on failure."
   (json-fetch (string-append "https://pypi.python.org/pypi/" name "/json")))
 
 (define (latest-source-release pypi-package)
@@ -160,14 +161,15 @@ VERSION, SOURCE-URL, HOME-PAGE, SYNOPSIS, DESCRIPTION, and LICENSE."
 
 (define (pypi->guix-package package-name)
   "Fetch the metadata for PACKAGE-NAME from pypi.python.org, and return the
-`package' s-expression corresponding to that package."
+`package' s-expression corresponding to that package, or #f on failure."
   (let ((package (pypi-fetch package-name)))
-    (let ((name (assoc-ref* package "info" "name"))
-          (version (assoc-ref* package "info" "version"))
-          (release (assoc-ref (latest-source-release package) "url"))
-          (synopsis (assoc-ref* package "info" "summary"))
-          (description (assoc-ref* package "info" "summary"))
-          (home-page (assoc-ref* package "info" "home_page"))
-          (license (string->license (assoc-ref* package "info" "license"))))
-      (make-pypi-sexp name version release home-page synopsis
-                      description license))))
+    (and package
+         (let ((name (assoc-ref* package "info" "name"))
+               (version (assoc-ref* package "info" "version"))
+               (release (assoc-ref (latest-source-release package) "url"))
+               (synopsis (assoc-ref* package "info" "summary"))
+               (description (assoc-ref* package "info" "summary"))
+               (home-page (assoc-ref* package "info" "home_page"))
+               (license (string->license (assoc-ref* package "info" "license"))))
+           (make-pypi-sexp name version release home-page synopsis
+                           description license)))))
diff --git a/guix/scripts/import/pypi.scm b/guix/scripts/import/pypi.scm
index 0aaa23a158..a36065e5cf 100644
--- a/guix/scripts/import/pypi.scm
+++ b/guix/scripts/import/pypi.scm
@@ -80,4 +80,8 @@ Import and convert the PyPI package for PACKAGE-NAME.\n"))
                            (reverse opts))))
     (match args
       ((package-name)
-       (pypi->guix-package package-name)))))
+       (let ((sexp (pypi->guix-package package-name)))
+         (unless sexp
+           (leave (_ "failed to download meta-data for package '~a'~%")
+                  package-name))
+         sexp)))))