diff options
author | Marius Bakke <mbakke@fastmail.com> | 2018-08-25 16:44:07 +0200 |
---|---|---|
committer | Marius Bakke <mbakke@fastmail.com> | 2018-08-25 16:44:07 +0200 |
commit | 839167ff9d74fc490b32f6a197591964f73b65e5 (patch) | |
tree | d193bfad7c9ef5597c5cd7d2ea25fd007d01f88a /guix/import/github.scm | |
parent | 27c1df05a866b639a61e16d48b3f2da8fa5eb767 (diff) | |
parent | 030c912616c8ee1595218e304460041bcb4f1ceb (diff) | |
download | guix-patches-839167ff9d74fc490b32f6a197591964f73b65e5.tar guix-patches-839167ff9d74fc490b32f6a197591964f73b65e5.tar.gz |
Merge branch 'staging' into core-updates
Diffstat (limited to 'guix/import/github.scm')
-rw-r--r-- | guix/import/github.scm | 92 |
1 files changed, 66 insertions, 26 deletions
diff --git a/guix/import/github.scm b/guix/import/github.scm index ef226911b9..af9f56e1dc 100644 --- a/guix/import/github.scm +++ b/guix/import/github.scm @@ -1,6 +1,6 @@ ;;; GNU Guix --- Functional package management for GNU ;;; Copyright © 2016 Ben Woodcroft <donttrustben@gmail.com> -;;; Copyright © 2017 Ludovic Courtès <ludo@gnu.org> +;;; Copyright © 2017, 2018 Ludovic Courtès <ludo@gnu.org> ;;; ;;; This file is part of GNU Guix. ;;; @@ -120,41 +120,73 @@ repository separated by a forward slash, from a string URL of the form ;; limit, or #f. (make-parameter (getenv "GUIX_GITHUB_TOKEN"))) +(define (fetch-releases-or-tags url) + "Fetch the list of \"releases\" or, if it's empty, the list of tags for the +repository at URL. Return the corresponding JSON dictionaries (hash tables), +or #f if the information could not be retrieved. + +We look at both /releases and /tags because the \"release\" feature of GitHub +is little used; often, people simply provide a tag. What's confusing is that +tags show up in the \"Releases\" tab of the web UI. For instance, +'https://github.com/aconchillo/guile-json/releases' shows a number of +\"releases\" (really: tags), whereas +'https://api.github.com/repos/aconchillo/guile-json/releases' returns the +empty list." + (define release-url + (string-append "https://api.github.com/repos/" + (github-user-slash-repository url) + "/releases")) + (define tag-url + (string-append "https://api.github.com/repos/" + (github-user-slash-repository url) + "/tags")) + + (define headers + ;; Ask for version 3 of the API as suggested at + ;; <https://developer.github.com/v3/>. + `((Accept . "application/vnd.github.v3+json") + (user-agent . "GNU Guile"))) + + (define (decorate url) + (if (%github-token) + (string-append url "?access_token=" (%github-token)) + url)) + + (match (json-fetch (decorate release-url) #:headers headers) + (() + ;; We got the empty list, presumably because the user didn't use GitHub's + ;; "release" mechanism, but hopefully they did use Git tags. + (json-fetch (decorate tag-url) #:headers headers)) + (x x))) + (define (latest-released-version url package-name) "Return a string of the newest released version name given a string URL like 'https://github.com/arq5x/bedtools2/archive/v2.24.0.tar.gz' and the name of the package e.g. 'bedtools2'. Return #f if there is no releases" - (let* ((token (%github-token)) - (api-url (string-append - "https://api.github.com/repos/" - (github-user-slash-repository url) - "/releases")) - (json (json-fetch - (if token - (string-append api-url "?access_token=" token) - api-url)))) + (let* ((json (fetch-releases-or-tags url))) (if (eq? json #f) - (if token + (if (%github-token) (error "Error downloading release information through the GitHub API when using a GitHub token") (error "Error downloading release information through the GitHub API. This may be fixed by using an access token and setting the environment variable GUIX_GITHUB_TOKEN, for instance one procured from https://github.com/settings/tokens")) - (let ((proper-releases - (filter - (lambda (x) - ;; example pre-release: - ;; https://github.com/wwood/OrfM/releases/tag/v0.5.1 - ;; or an all-prerelease set - ;; https://github.com/powertab/powertabeditor/releases - (not (hash-ref x "prerelease"))) - json))) - (match proper-releases - (() ;empty release list + (let loop ((releases + (filter + (lambda (x) + ;; example pre-release: + ;; https://github.com/wwood/OrfM/releases/tag/v0.5.1 + ;; or an all-prerelease set + ;; https://github.com/powertab/powertabeditor/releases + (not (hash-ref x "prerelease"))) + json))) + (match releases + (() ;empty release list #f) - ((release . rest) ;one or more releases - (let ((tag (hash-ref release "tag_name")) + ((release . rest) ;one or more releases + (let ((tag (or (hash-ref release "tag_name") ;a "release" + (hash-ref release "name"))) ;a tag (name-length (string-length package-name))) ;; some tags include the name of the package e.g. "fdupes-1.51" ;; so remove these @@ -164,8 +196,16 @@ https://github.com/settings/tokens")) (substring tag (+ name-length 1)) ;; some tags start with a "v" e.g. "v0.25.0" ;; where some are just the version number - (if (eq? (string-ref tag 0) #\v) - (substring tag 1) tag))))))))) + (if (string-prefix? "v" tag) + (substring tag 1) + + ;; Finally, reject tags that don't start with a digit: + ;; they may not represent a release. + (if (and (not (string-null? tag)) + (char-set-contains? char-set:digit + (string-ref tag 0))) + tag + (loop rest))))))))))) (define (latest-release pkg) "Return an <upstream-source> for the latest release of PKG." |