From bab020d7ca50e4153cf24832d119389a37fa8f63 Mon Sep 17 00:00:00 2001 From: Cyril Roelandt Date: Tue, 3 Nov 2015 22:38:49 +0100 Subject: [PATCH] import: pypi: add updater * guix/import/pypi.scm (guix-package->pypi-name, latest-release): New procedures. (%pypi-updater): New variable. * guix/scripts/refresh.scm (%updaters): Add %PYPI-UPDATER. * doc/guix.texi (Invoking guix refresh): Mention PyPI --- doc/guix.texi | 2 ++ guix/import/pypi.scm | 50 +++++++++++++++++++++++++++++++++++++++- guix/scripts/refresh.scm | 4 +++- 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 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."