import: hackage: Support updating to a specific version.

* gnu/import/hackage.scm
(hackage-fetch-and-hash, hackage-fetch): Support name and version
argument.
(import-release): New variable, formerly known as latest-release.
Support updating to a specific version.

Signed-off-by: Ludovic Courtès <ludo@gnu.org>
Change-Id: I8f9e3ee99676cedca82f7c8c5ff51baa5a6fc46a
This commit is contained in:
Nicolas Graves 2024-10-29 14:53:51 +01:00 committed by Ludovic Courtès
parent 62b0d90cc7
commit abc3eb3319
No known key found for this signature in database
GPG key ID: 090B11993D9AEBB5

View file

@ -9,6 +9,7 @@
;;; Copyright © 2019 Simon Tournier <zimon.toutoune@gmail.com> ;;; Copyright © 2019 Simon Tournier <zimon.toutoune@gmail.com>
;;; Copyright © 2022 Hartmut Goebel <h.goebel@crazy-compilers.com> ;;; Copyright © 2022 Hartmut Goebel <h.goebel@crazy-compilers.com>
;;; Copyright © 2023-2024 Ludovic Courtès <ludo@gnu.org> ;;; Copyright © 2023-2024 Ludovic Courtès <ludo@gnu.org>
;;; Copyright © 2024 Nicolas Graves <ngraves@ngraves.fr>
;;; ;;;
;;; This file is part of GNU Guix. ;;; This file is part of GNU Guix.
;;; ;;;
@ -136,7 +137,7 @@ format as two values."
(values (read-cabal (canonical-newline-port port)) (values (read-cabal (canonical-newline-port port))
(bytevector->nix-base32-string (get-hash))))) (bytevector->nix-base32-string (get-hash)))))
(define (hackage-fetch-and-hash name-version) (define (hackage-fetch-and-hash name version)
"Fetch the latest Cabal revision for the package NAME-VERSION, and return "Fetch the latest Cabal revision for the package NAME-VERSION, and return
two values: the parsed Cabal file and its hash in nix-base32 format. If the two values: the parsed Cabal file and its hash in nix-base32 format. If the
version part is omitted from the package name, then fetch the latest version part is omitted from the package name, then fetch the latest
@ -144,18 +145,19 @@ version. On failure, both return values will be #f."
(guard (c ((and (http-get-error? c) (guard (c ((and (http-get-error? c)
(= 404 (http-get-error-code c))) (= 404 (http-get-error-code c)))
(values #f #f))) ;"expected" if package is unknown (values #f #f))) ;"expected" if package is unknown
(let* ((name version (package-name->name+version name-version)) (let* ((name new-version (package-name->name+version name))
(url (hackage-cabal-url name version)) (version (or version new-version))
(port _ (http-fetch url)) (url (hackage-cabal-url name version))
(cabal hash (read-cabal-and-hash port))) (port _ (http-fetch url))
(cabal hash (read-cabal-and-hash port)))
(close-port port) (close-port port)
(values cabal hash)))) (values cabal hash))))
(define (hackage-fetch name-version) (define (hackage-fetch name version)
"Return the Cabal file for the package NAME-VERSION, or #f on failure. If "Return the Cabal file for the package NAME-VERSION, or #f on failure. If
the version part is omitted from the package name, then return the latest the version part is omitted from the package name, then return the latest
version." version."
(let ((cabal hash (hackage-fetch-and-hash name-version))) (let ((cabal hash (hackage-fetch-and-hash name version)))
cabal)) cabal))
(define string->license (define string->license
@ -355,7 +357,7 @@ respectively."
(let ((cabal-meta cabal-hash (let ((cabal-meta cabal-hash
(if port (if port
(read-cabal-and-hash port) (read-cabal-and-hash port)
(hackage-fetch-and-hash package-name)))) (hackage-fetch-and-hash package-name #f))))
(if cabal-meta (if cabal-meta
(hackage-module->sexp (eval-cabal cabal-meta cabal-environment) (hackage-module->sexp (eval-cabal cabal-meta cabal-environment)
cabal-hash cabal-hash
@ -377,15 +379,10 @@ respectively."
(let ((hackage-rx (make-regexp "(https?://hackage.haskell.org|mirror://hackage/)"))) (let ((hackage-rx (make-regexp "(https?://hackage.haskell.org|mirror://hackage/)")))
(url-predicate (cut regexp-exec hackage-rx <>)))) (url-predicate (cut regexp-exec hackage-rx <>))))
(define* (latest-release package #:key (version #f)) (define* (import-release package #:key (version #f))
"Return an <upstream-source> for the latest release of PACKAGE." "Return an <upstream-source> for the latest release of PACKAGE."
(when version
(raise
(formatted-message
(G_ "~a updater doesn't support updating to a specific version, sorry.")
"hackage")))
(let* ((hackage-name (package-upstream-name* package)) (let* ((hackage-name (package-upstream-name* package))
(cabal-meta (hackage-fetch hackage-name))) (cabal-meta (hackage-fetch hackage-name version)))
(match cabal-meta (match cabal-meta
(#f (#f
(format (current-error-port) (format (current-error-port)
@ -407,6 +404,6 @@ respectively."
(name 'hackage) (name 'hackage)
(description "Updater for Hackage packages") (description "Updater for Hackage packages")
(pred hackage-package?) (pred hackage-package?)
(import latest-release))) (import import-release)))
;;; cabal.scm ends here ;;; cabal.scm ends here