gnu: Add r-all.
[jackhill/guix/guix.git] / guix / import / gnome.scm
1 ;;; GNU Guix --- Functional package management for GNU
2 ;;; Copyright © 2017 Ludovic Courtès <ludo@gnu.org>
3 ;;;
4 ;;; This file is part of GNU Guix.
5 ;;;
6 ;;; GNU Guix is free software; you can redistribute it and/or modify it
7 ;;; under the terms of the GNU General Public License as published by
8 ;;; the Free Software Foundation; either version 3 of the License, or (at
9 ;;; your option) any later version.
10 ;;;
11 ;;; GNU Guix is distributed in the hope that it will be useful, but
12 ;;; WITHOUT ANY WARRANTY; without even the implied warranty of
13 ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 ;;; GNU General Public License for more details.
15 ;;;
16 ;;; You should have received a copy of the GNU General Public License
17 ;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>.
18
19 (define-module (guix import gnome)
20 #:use-module (guix upstream)
21 #:use-module (guix utils)
22 #:use-module (guix packages)
23 #:use-module (guix http-client)
24 #:use-module (json)
25 #:use-module (srfi srfi-1)
26 #:use-module (srfi srfi-11)
27 #:use-module (srfi srfi-34)
28 #:use-module (web uri)
29 #:use-module (ice-9 match)
30 #:export (%gnome-updater))
31
32 ;;; Commentary:
33 ;;;
34 ;;; This package provides not an actual importer but simply an updater for
35 ;;; GNOME packages. It grabs package meta-data from 'cache.json' files
36 ;;; available on ftp.gnome.org.
37 ;;;
38 ;;; Code:
39
40 (define (jsonish->upstream-source name jsonish)
41 "Return an <upstream-source> object for package NAME, using JSONISH as the
42 source for metadata."
43 (match jsonish
44 ((version . dictionary)
45 (upstream-source
46 (package name)
47 (version version)
48 (urls (filter-map (lambda (extension)
49 (match (hash-ref dictionary extension)
50 (#f
51 #f)
52 ((? string? relative-url)
53 (string-append "mirror://gnome/sources/"
54 name "/" relative-url))))
55 '("tar.lz" "tar.xz" "tar.bz2" "tar.gz")))))))
56
57 (define (latest-gnome-release package)
58 "Return the latest release of PACKAGE, a GNOME package, or #f if it could
59 not be determined."
60 (define %not-dot
61 (char-set-complement (char-set #\.)))
62
63 (define (even-minor-version? version)
64 (match (string-tokenize version %not-dot)
65 (((= string->number major) (= string->number minor) . rest)
66 (and minor (even? minor)))
67 (_
68 #t))) ;cross fingers
69
70 (define upstream-name
71 ;; Some packages like "NetworkManager" have camel-case names.
72 (package-upstream-name package))
73
74 (guard (c ((http-get-error? c)
75 (if (= 404 (http-get-error-code c))
76 #f
77 (raise c))))
78 (let* ((port (http-fetch/cached
79 (string->uri (string-append
80 "https://ftp.gnome.org/pub/gnome/sources/"
81 upstream-name "/cache.json"))
82
83 ;; ftp.gnome.org supports 'if-Modified-Since', so the local
84 ;; cache can expire early.
85 #:ttl (* 60 10)))
86 (json (json->scm port)))
87 (close-port port)
88 (match json
89 ((4 (? hash-table? releases) _ ...)
90 (let* ((releases (hash-ref releases upstream-name))
91 (latest (hash-fold (lambda (key value result)
92 (cond ((even-minor-version? key)
93 (match result
94 (#f
95 (cons key value))
96 ((newest . _)
97 (if (version>? key newest)
98 (cons key value)
99 result))))
100 (else
101 result)))
102 #f
103 releases)))
104 (and latest
105 (jsonish->upstream-source upstream-name latest))))))))
106
107 (define %gnome-updater
108 (upstream-updater
109 (name 'gnome)
110 (description "Updater for GNOME packages")
111 (pred (url-prefix-predicate "mirror://gnome/"))
112 (latest latest-gnome-release)))