summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/guix.texi2
-rw-r--r--guix/import/pypi.scm50
-rw-r--r--guix/scripts/refresh.scm4
3 files changed, 54 insertions, 2 deletions
diff --git a/doc/guix.texi b/doc/guix.texi
index 996192c0ea..23f9c3c0a9 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -4291,6 +4291,8 @@ the updater for GNU packages;
the updater for @uref{http://elpa.gnu.org/, ELPA} packages;
@item cran
the updater fro @uref{http://cran.r-project.org/, CRAN} packages.
+@item pypi
+the updater fro @uref{https://pypi.python.org, PyPI} packages.
@end table
For instance, the following commands only checks for updates of Emacs
diff --git a/guix/import/pypi.scm b/guix/import/pypi.scm
index 647ef615e0..f1988a7186 100644
--- a/guix/import/pypi.scm
+++ b/guix/import/pypi.scm
@@ -30,12 +30,16 @@
#:use-module (guix ui)
#:use-module (guix utils)
#:use-module (guix import utils)
+ #:use-module ((guix download) #:prefix download:)
#:use-module (guix import json)
#:use-module (guix packages)
+ #:use-module (guix upstream)
#:use-module (guix licenses)
#:use-module (guix build-system python)
+ #:use-module (gnu packages)
#:use-module (gnu packages python)
- #:export (pypi->guix-package))
+ #:export (pypi->guix-package
+ %pypi-updater))
(define (pypi-fetch name)
"Return an alist representation of the PyPI metadata for the package NAME,
@@ -60,6 +64,16 @@ package."
(snake-case name)
(string-append "python-" (snake-case name))))
+(define (guix-package->pypi-name package)
+ "Given a Python PACKAGE built from pypi.python.org, return the name of the
+package on PyPI."
+ (let ((source-url (and=> (package-source package) origin-uri)))
+ ;; The URL has the form:
+ ;; 'https://pypi.python.org/packages/source/' +
+ ;; first letter of the package name +
+ ;; '/' + package name + '/' + ...
+ (substring source-url 42 (string-rindex source-url #\/))))
+
(define (maybe-inputs package-inputs)
"Given a list of PACKAGE-INPUTS, tries to generate the 'inputs' field of a
package definition."
@@ -190,3 +204,37 @@ VERSION, SOURCE-URL, HOME-PAGE, SYNOPSIS, DESCRIPTION, and LICENSE."
(license (string->license (assoc-ref* package "info" "license"))))
(make-pypi-sexp name version release home-page synopsis
description license)))))
+
+(define (pypi-package? package)
+ "Return true if PACKAGE is a Python package from PyPI."
+
+ (define (pypi-url? url)
+ (string-prefix? "https://pypi.python.org/" url))
+
+ (let ((source-url (and=> (package-source package) origin-uri))
+ (fetch-method (and=> (package-source package) origin-method)))
+ (and (eq? fetch-method download:url-fetch)
+ (match source-url
+ ((? string?)
+ (pypi-url? source-url))
+ ((source-url ...)
+ (any pypi-url? source-url))))))
+
+(define (latest-release guix-package)
+ "Return an <upstream-source> for the latest release of GUIX-PACKAGE."
+ (let* ((pypi-name (guix-package->pypi-name
+ (specification->package guix-package)))
+ (metadata (pypi-fetch pypi-name))
+ (version (assoc-ref* metadata "info" "version"))
+ (url (assoc-ref (latest-source-release metadata) "url")))
+ (upstream-source
+ (package guix-package)
+ (version version)
+ (urls (list url)))))
+
+(define %pypi-updater
+ (upstream-updater
+ (name 'pypi)
+ (description "Updater for PyPI packages")
+ (pred pypi-package?)
+ (latest latest-release)))
diff --git a/guix/scripts/refresh.scm b/guix/scripts/refresh.scm
index 0df4121d0a..3984a0bde1 100644
--- a/guix/scripts/refresh.scm
+++ b/guix/scripts/refresh.scm
@@ -30,6 +30,7 @@
#:use-module ((guix gnu-maintenance) #:select (%gnu-updater))
#:use-module (guix import elpa)
#:use-module (guix import cran)
+ #:use-module (guix import pypi)
#:use-module (guix gnupg)
#:use-module (gnu packages)
#:use-module ((gnu packages commencement) #:select (%final-inputs))
@@ -152,7 +153,8 @@ specified with `--select'.\n"))
;; List of "updaters" used by default. They are consulted in this order.
(list %gnu-updater
%elpa-updater
- %cran-updater))
+ %cran-updater
+ %pypi-updater))
(define (lookup-updater name)
"Return the updater called NAME."