mirror of
https://git.in.rschanz.org/ryan77627/guix.git
synced 2025-01-11 13:49:23 -05:00
import: cran: Allow imports of a specific version.
* guix/import/cran.scm (download): Handle the case where URL is a list. (fetch-description-from-tarball): New procedure. (fetch-description): Add #:version parameter. Honor it when REPOSITORY is 'cran. Use 'fetch-description-from-tarball' when REPOSITORY is 'bioconductor. (description->package): SOURCE-URL may now be a list. (cran->guix-package): Pass VERSION to 'fetch-description'. (cran-recursive-import): Add #:version parameter. * guix/scripts/import/cran.scm (guix-import-cran): Expect a spec rather than a mere package name. * doc/guix.texi (Invoking guix import): Document it.
This commit is contained in:
parent
b20cd80ff1
commit
450e1dd52e
3 changed files with 83 additions and 47 deletions
|
@ -11833,6 +11833,12 @@ The command command below imports metadata for the Cairo R package:
|
||||||
guix import cran Cairo
|
guix import cran Cairo
|
||||||
@end example
|
@end example
|
||||||
|
|
||||||
|
You can also ask for a specific version:
|
||||||
|
|
||||||
|
@example
|
||||||
|
guix import cran rasterVis@@0.50.3
|
||||||
|
@end example
|
||||||
|
|
||||||
When @option{--recursive} is added, the importer will traverse the
|
When @option{--recursive} is added, the importer will traverse the
|
||||||
dependency graph of the given upstream package recursively and generate
|
dependency graph of the given upstream package recursively and generate
|
||||||
package expressions for all those packages that are not yet in Guix.
|
package expressions for all those packages that are not yet in Guix.
|
||||||
|
|
|
@ -229,26 +229,61 @@ (define download
|
||||||
(let ((store-directory
|
(let ((store-directory
|
||||||
(add-to-store store (basename url) #t "sha256" dir)))
|
(add-to-store store (basename url) #t "sha256" dir)))
|
||||||
(values store-directory changeset)))))))
|
(values store-directory changeset)))))))
|
||||||
(else (download-to-store store url)))))))
|
(else
|
||||||
|
(match url
|
||||||
|
((? string?)
|
||||||
|
(download-to-store store url))
|
||||||
|
((urls ...)
|
||||||
|
;; Try all the URLs. A use case where this is useful is when one
|
||||||
|
;; of the URLs is the /Archive CRAN URL.
|
||||||
|
(any (cut download-to-store store <>) urls)))))))))
|
||||||
|
|
||||||
(define (fetch-description repository name)
|
(define (fetch-description-from-tarball url)
|
||||||
|
"Fetch the tarball at URL, extra its 'DESCRIPTION' file, parse it, and
|
||||||
|
return the resulting alist."
|
||||||
|
(match (download url)
|
||||||
|
(#f #f)
|
||||||
|
(tarball
|
||||||
|
(call-with-temporary-directory
|
||||||
|
(lambda (dir)
|
||||||
|
(parameterize ((current-error-port (%make-void-port "rw+"))
|
||||||
|
(current-output-port (%make-void-port "rw+")))
|
||||||
|
(and (zero? (system* "tar" "--wildcards" "-x"
|
||||||
|
"--strip-components=1"
|
||||||
|
"-C" dir
|
||||||
|
"-f" tarball "*/DESCRIPTION"))
|
||||||
|
(description->alist
|
||||||
|
(call-with-input-file (string-append dir "/DESCRIPTION")
|
||||||
|
read-string)))))))))
|
||||||
|
|
||||||
|
(define* (fetch-description repository name #:optional version)
|
||||||
"Return an alist of the contents of the DESCRIPTION file for the R package
|
"Return an alist of the contents of the DESCRIPTION file for the R package
|
||||||
NAME in the given REPOSITORY, or #f in case of failure. NAME is
|
NAME at VERSION in the given REPOSITORY, or #f in case of failure. NAME is
|
||||||
case-sensitive."
|
case-sensitive."
|
||||||
(case repository
|
(case repository
|
||||||
((cran)
|
((cran)
|
||||||
(let ((url (string-append %cran-url name "/DESCRIPTION")))
|
(guard (c ((http-get-error? c)
|
||||||
(guard (c ((http-get-error? c)
|
(warning (G_ "failed to retrieve package information \
|
||||||
(warning (G_ "failed to retrieve package information \
|
|
||||||
from ~a: ~a (~a)~%")
|
from ~a: ~a (~a)~%")
|
||||||
(uri->string (http-get-error-uri c))
|
(uri->string (http-get-error-uri c))
|
||||||
(http-get-error-code c)
|
(http-get-error-code c)
|
||||||
(http-get-error-reason c))
|
(http-get-error-reason c))
|
||||||
#f))
|
#f))
|
||||||
(let* ((port (http-fetch url))
|
;; When VERSION is true, we have to download the tarball to get at its
|
||||||
(result (description->alist (read-string port))))
|
;; 'DESCRIPTION' file; only the latest one is directly accessible over
|
||||||
(close-port port)
|
;; HTTP.
|
||||||
result))))
|
(if version
|
||||||
|
(let ((urls (list (string-append "mirror://cran/src/contrib/"
|
||||||
|
name "_" version ".tar.gz")
|
||||||
|
(string-append "mirror://cran/src/contrib/Archive/"
|
||||||
|
name "/"
|
||||||
|
name "_" version ".tar.gz"))))
|
||||||
|
(fetch-description-from-tarball urls))
|
||||||
|
(let* ((url (string-append %cran-url name "/DESCRIPTION"))
|
||||||
|
(port (http-fetch url))
|
||||||
|
(result (description->alist (read-string port))))
|
||||||
|
(close-port port)
|
||||||
|
result))))
|
||||||
((bioconductor)
|
((bioconductor)
|
||||||
;; Currently, the bioconductor project does not offer a way to access a
|
;; Currently, the bioconductor project does not offer a way to access a
|
||||||
;; package's DESCRIPTION file over HTTP, so we determine the version,
|
;; package's DESCRIPTION file over HTTP, so we determine the version,
|
||||||
|
@ -257,22 +292,13 @@ (define (fetch-description repository name)
|
||||||
(and (latest-bioconductor-package-version name) #t)
|
(and (latest-bioconductor-package-version name) #t)
|
||||||
(and (latest-bioconductor-package-version name 'annotation) 'annotation)
|
(and (latest-bioconductor-package-version name 'annotation) 'annotation)
|
||||||
(and (latest-bioconductor-package-version name 'experiment) 'experiment)))
|
(and (latest-bioconductor-package-version name 'experiment) 'experiment)))
|
||||||
|
;; TODO: Honor VERSION.
|
||||||
(version (latest-bioconductor-package-version name type))
|
(version (latest-bioconductor-package-version name type))
|
||||||
(url (car (bioconductor-uri name version type)))
|
(url (car (bioconductor-uri name version type)))
|
||||||
(tarball (download url)))
|
(meta (fetch-description-from-tarball url)))
|
||||||
(call-with-temporary-directory
|
(if (boolean? type)
|
||||||
(lambda (dir)
|
meta
|
||||||
(parameterize ((current-error-port (%make-void-port "rw+"))
|
(cons `(bioconductor-type . ,type) meta))))
|
||||||
(current-output-port (%make-void-port "rw+")))
|
|
||||||
(and (zero? (system* "tar" "--wildcards" "-x"
|
|
||||||
"--strip-components=1"
|
|
||||||
"-C" dir
|
|
||||||
"-f" tarball "*/DESCRIPTION"))
|
|
||||||
(and=> (description->alist (with-input-from-file
|
|
||||||
(string-append dir "/DESCRIPTION") read-string))
|
|
||||||
(lambda (meta)
|
|
||||||
(if (boolean? type) meta
|
|
||||||
(cons `(bioconductor-type . ,type) meta))))))))))
|
|
||||||
((git)
|
((git)
|
||||||
(and (string-prefix? "http" name)
|
(and (string-prefix? "http" name)
|
||||||
;; Download the git repository at "NAME"
|
;; Download the git repository at "NAME"
|
||||||
|
@ -485,7 +511,7 @@ (define (description->package repository meta)
|
||||||
((bioconductor)
|
((bioconductor)
|
||||||
(list (assoc-ref meta 'bioconductor-type)))
|
(list (assoc-ref meta 'bioconductor-type)))
|
||||||
(else '())))
|
(else '())))
|
||||||
((url rest ...) url)
|
((urls ...) urls)
|
||||||
((? string? url) url)
|
((? string? url) url)
|
||||||
(_ #f)))))
|
(_ #f)))))
|
||||||
(git? (assoc-ref meta 'git))
|
(git? (assoc-ref meta 'git))
|
||||||
|
@ -592,7 +618,7 @@ (define cran->guix-package
|
||||||
(lambda* (package-name #:key (repo 'cran) version)
|
(lambda* (package-name #:key (repo 'cran) version)
|
||||||
"Fetch the metadata for PACKAGE-NAME from REPO and return the `package'
|
"Fetch the metadata for PACKAGE-NAME from REPO and return the `package'
|
||||||
s-expression corresponding to that package, or #f on failure."
|
s-expression corresponding to that package, or #f on failure."
|
||||||
(let ((description (fetch-description repo package-name)))
|
(let ((description (fetch-description repo package-name version)))
|
||||||
(if description
|
(if description
|
||||||
(description->package repo description)
|
(description->package repo description)
|
||||||
(case repo
|
(case repo
|
||||||
|
@ -610,8 +636,9 @@ (define cran->guix-package
|
||||||
(&message
|
(&message
|
||||||
(message "couldn't find meta-data for R package")))))))))))
|
(message "couldn't find meta-data for R package")))))))))))
|
||||||
|
|
||||||
(define* (cran-recursive-import package-name #:key (repo 'cran))
|
(define* (cran-recursive-import package-name #:key (repo 'cran) version)
|
||||||
(recursive-import package-name
|
(recursive-import package-name
|
||||||
|
#:version version
|
||||||
#:repo repo
|
#:repo repo
|
||||||
#:repo->guix-package cran->guix-package
|
#:repo->guix-package cran->guix-package
|
||||||
#:guix-name cran-guix-name))
|
#:guix-name cran-guix-name))
|
||||||
|
|
|
@ -27,8 +27,8 @@ (define-module (guix scripts import cran)
|
||||||
#:use-module (guix import utils)
|
#:use-module (guix import utils)
|
||||||
#:use-module (guix scripts import)
|
#:use-module (guix scripts import)
|
||||||
#:use-module (srfi srfi-1)
|
#:use-module (srfi srfi-1)
|
||||||
#:use-module (srfi srfi-11)
|
|
||||||
#:use-module (srfi srfi-37)
|
#:use-module (srfi srfi-37)
|
||||||
|
#:use-module (srfi srfi-71)
|
||||||
#:use-module (ice-9 match)
|
#:use-module (ice-9 match)
|
||||||
#:use-module (ice-9 format)
|
#:use-module (ice-9 format)
|
||||||
#:export (guix-import-cran))
|
#:export (guix-import-cran))
|
||||||
|
@ -98,21 +98,24 @@ (define (parse-options)
|
||||||
(reverse opts))))
|
(reverse opts))))
|
||||||
(parameterize ((%input-style (assoc-ref opts 'style)))
|
(parameterize ((%input-style (assoc-ref opts 'style)))
|
||||||
(match args
|
(match args
|
||||||
((package-name)
|
((spec)
|
||||||
(if (assoc-ref opts 'recursive)
|
(let ((name version (package-name->name+version spec)))
|
||||||
;; Recursive import
|
(if (assoc-ref opts 'recursive)
|
||||||
(with-error-handling
|
;; Recursive import
|
||||||
(map package->definition
|
(with-error-handling
|
||||||
(filter identity
|
(map package->definition
|
||||||
(cran-recursive-import package-name
|
(filter identity
|
||||||
#:repo (or (assoc-ref opts 'repo) 'cran)))))
|
(cran-recursive-import name
|
||||||
;; Single import
|
#:version version
|
||||||
(let ((sexp (cran->guix-package package-name
|
#:repo (or (assoc-ref opts 'repo) 'cran)))))
|
||||||
#:repo (or (assoc-ref opts 'repo) 'cran))))
|
;; Single import
|
||||||
(unless sexp
|
(let ((sexp (cran->guix-package name
|
||||||
(leave (G_ "failed to download description for package '~a'~%")
|
#:version version
|
||||||
package-name))
|
#:repo (or (assoc-ref opts 'repo) 'cran))))
|
||||||
sexp)))
|
(unless sexp
|
||||||
|
(leave (G_ "failed to download description for package '~a'~%")
|
||||||
|
name))
|
||||||
|
sexp))))
|
||||||
(()
|
(()
|
||||||
(leave (G_ "too few arguments~%")))
|
(leave (G_ "too few arguments~%")))
|
||||||
((many ...)
|
((many ...)
|
||||||
|
|
Loading…
Reference in a new issue