unofficial mirror of guix-devel@gnu.org 
 help / color / mirror / code / Atom feed
* [PATCH] Add Bioconductor importer and updater.
@ 2015-12-17 11:34 Ricardo Wurmus
  2015-12-21 16:00 ` Ricardo Wurmus
  0 siblings, 1 reply; 9+ messages in thread
From: Ricardo Wurmus @ 2015-12-17 11:34 UTC (permalink / raw)
  To: guix-devel@gnu.org

[-- Attachment #1: Type: text/plain, Size: 892 bytes --]

Hi Guix,

Bioconductor is a large, popular repository of R packages for
bioinformatics.  It has coordinated, versioned releases (latest stable
release is 3.2).

The attached patches generalise the existing procedures used by the CRAN
importer, so that with only little effort importers for other R
repositories are possible.  The last patch adds an importer for the
Bioconductor repository.

Imported package expressions now also contain a package property
“r-repository”, which is either the symbol “cran” or the symbol
“bioconductor”.  This is also checked in the predicates “cran-package?”
and “bioconductor-package?” used by the updaters.

The first two patches in this series are actually unrelated: the first
fixes an annoying bug in the CRAN importer; the second corrects an
outdated claim in the CRAN importer’s documentation.

~~ Ricardo


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-import-Drop-empty-list-items.patch --]
[-- Type: text/x-patch, Size: 1382 bytes --]

From 770a92ed51641ea2da7893c4d70206fd19f0513b Mon Sep 17 00:00:00 2001
From: Ricardo Wurmus <ricardo.wurmus@mdc-berlin.de>
Date: Wed, 16 Dec 2015 14:29:38 +0100
Subject: [PATCH 1/6] import: Drop empty list items.

* guix/import/cran.scm (listify): Remove empty strings from result list.
---
 guix/import/cran.scm | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/guix/import/cran.scm b/guix/import/cran.scm
index 845ecb5..45c679c 100644
--- a/guix/import/cran.scm
+++ b/guix/import/cran.scm
@@ -128,9 +128,12 @@ empty list when the FIELD cannot be found."
                                     #f "( *\\([^\\)]+\\)) *"
                                     value 'pre 'post)
                                    #\,)))
-          ;; When there is whitespace inside of items it is probably because
-          ;; this was not an actual list to begin with.
-          (remove (cut string-any char-set:whitespace <>)
+          (remove (lambda (item)
+                    (or (string-null? item)
+                        ;; When there is whitespace inside of items it is
+                        ;; probably because this was not an actual list to
+                        ;; begin with.
+                        (string-any char-set:whitespace item)))
                   (map string-trim-both items))))))
 
 (define (beautify-description description)
-- 
2.1.0


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #3: 0002-doc-Fix-outdated-claim-about-CRAN-importer.patch --]
[-- Type: text/x-patch, Size: 972 bytes --]

From ee6f9d5855528870cf861f5cdd07dd6e654f3736 Mon Sep 17 00:00:00 2001
From: Ricardo Wurmus <ricardo.wurmus@mdc-berlin.de>
Date: Thu, 17 Dec 2015 12:23:35 +0100
Subject: [PATCH 2/6] doc: Fix outdated claim about CRAN importer.

* doc/guix.texi: The CRAN importer no longer extracts information from
  the HTML package description but from the package's DESCRIPTION file.
---
 doc/guix.texi | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/doc/guix.texi b/doc/guix.texi
index f63e366..05a94dc 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -4205,7 +4205,7 @@ Import meta-data from @uref{http://cran.r-project.org/, CRAN}, the
 central repository for the @uref{http://r-project.org, GNU@tie{}R
 statistical and graphical environment}.
 
-Information is extracted from the HTML package description.
+Information is extracted from the package's DESCRIPTION file.
 
 The command command below imports meta-data for the @code{Cairo}
 R package:
-- 
2.1.0


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #4: 0003-build-Add-bioconductor-uri-procedure.patch --]
[-- Type: text/x-patch, Size: 1365 bytes --]

From 9fd0e0fea086a07a1219fb2bca9cb739d4373251 Mon Sep 17 00:00:00 2001
From: Ricardo Wurmus <ricardo.wurmus@mdc-berlin.de>
Date: Wed, 16 Dec 2015 14:02:29 +0100
Subject: [PATCH 3/6] build: Add bioconductor-uri procedure.

* guix/build-system/r.scm (bioconductor-uri): New procedure.
---
 guix/build-system/r.scm | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/guix/build-system/r.scm b/guix/build-system/r.scm
index da06cb1..a8ca354 100644
--- a/guix/build-system/r.scm
+++ b/guix/build-system/r.scm
@@ -29,7 +29,8 @@
   #:export (%r-build-system-modules
             r-build
             r-build-system
-            cran-uri))
+            cran-uri
+            bioconductor-uri))
 
 ;; Commentary:
 ;;
@@ -46,6 +47,12 @@ available via the first URI, the second URI points to the archived version."
         (string-append "mirror://cran/src/contrib/Archive/"
                        name "/" name "_" version ".tar.gz")))
 
+(define (bioconductor-uri name version)
+  "Return a URI string for the R package archive on Bioconductor for the
+release corresponding to NAME and VERSION."
+  (string-append "http://bioconductor.org/packages/release/bioc/src/contrib/"
+                 name "_" version ".tar.gz"))
+
 (define %r-build-system-modules
   ;; Build-side modules imported by default.
   `((guix build r-build-system)
-- 
2.1.0


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #5: 0004-import-Add-package-upstream-name-procedure.patch --]
[-- Type: text/x-patch, Size: 2626 bytes --]

From 04b9cb226f90b772f24a766fb632d8238e211366 Mon Sep 17 00:00:00 2001
From: Ricardo Wurmus <ricardo.wurmus@mdc-berlin.de>
Date: Wed, 16 Dec 2015 14:22:17 +0100
Subject: [PATCH 4/6] import: Add package->upstream-name procedure.

* guix/import/cran.scm (package->upstream-name): New procedure.
---
 guix/import/cran.scm | 40 +++++++++++++++++++++++-----------------
 1 file changed, 23 insertions(+), 17 deletions(-)

diff --git a/guix/import/cran.scm b/guix/import/cran.scm
index 45c679c..bf46d17 100644
--- a/guix/import/cran.scm
+++ b/guix/import/cran.scm
@@ -204,27 +204,33 @@ which was derived from the R package's DESCRIPTION file."
 ;;; Updater.
 ;;;
 
+(define (package->upstream-name package)
+  "Return the upstream name of the PACKAGE."
+  (let* ((properties (package-properties package))
+         (upstream-name (and=> properties
+                               (cut assoc-ref <> 'upstream-name))))
+    (if upstream-name
+        upstream-name
+        (match (package-source package)
+          ((? origin? origin)
+           (match (origin-uri origin)
+             ((url rest ...)
+              (let ((end   (string-rindex url #\_))
+                    (start (string-rindex url #\/)))
+                ;; The URL ends on
+                ;; (string-append "/" name "_" version ".tar.gz")
+                (substring url start end)))
+             (_ #f)))
+          (_ #f)))))
+
 (define (latest-release package)
   "Return an <upstream-source> for the latest release of PACKAGE."
 
-  (define (package->cran-name package)
-    (match (package-source package)
-      ((? origin? origin)
-       (match (origin-uri origin)
-         ((url rest ...)
-          (let ((end   (string-rindex url #\_))
-                (start (string-rindex url #\/)))
-            ;; The URL ends on
-            ;; (string-append "/" name "_" version ".tar.gz")
-            (substring url start end)))
-         (_ #f)))
-    (_ #f)))
-
-  (define cran-name
-    (package->cran-name (specification->package package)))
+  (define upstream-name
+    (package->upstream-name (specification->package package)))
 
   (define meta
-    (cran-fetch cran-name))
+    (cran-fetch upstream-name))
 
   (and meta
        (let ((version (assoc-ref meta "Version")))
@@ -232,7 +238,7 @@ which was derived from the R package's DESCRIPTION file."
          (upstream-source
           (package package)
           (version version)
-          (urls (cran-uri cran-name version))))))
+          (urls (cran-uri upstream-name version))))))
 
 (define (cran-package? package)
   "Return true if PACKAGE is an R package from CRAN."
-- 
2.1.0


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #6: 0005-import-Rename-cran-fetch-to-fetch-description.patch --]
[-- Type: text/x-patch, Size: 1909 bytes --]

From 79a8349296fb46d24caf3b4f35ae347b0f5aadee Mon Sep 17 00:00:00 2001
From: Ricardo Wurmus <ricardo.wurmus@mdc-berlin.de>
Date: Wed, 16 Dec 2015 14:28:43 +0100
Subject: [PATCH 5/6] import: Rename "cran-fetch" to "fetch-description".

* guix/import/cran.scm (cran-fetch): Rename procedure ...
(fetch-description): ... to this.
---
 guix/import/cran.scm | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/guix/import/cran.scm b/guix/import/cran.scm
index bf46d17..fc27090 100644
--- a/guix/import/cran.scm
+++ b/guix/import/cran.scm
@@ -109,11 +109,11 @@ package definition."
 
 (define %cran-url "http://cran.r-project.org/web/packages/")
 
-(define (cran-fetch name)
+(define (fetch-description base-url name)
   "Return an alist of the contents of the DESCRIPTION file for the R package
 NAME, or #f on failure.  NAME is case-sensitive."
   ;; This API always returns the latest release of the module.
-  (let ((url (string-append %cran-url name "/DESCRIPTION")))
+  (let ((url (string-append base-url name "/DESCRIPTION")))
     (description->alist (read-string (http-fetch url)))))
 
 (define (listify meta field)
@@ -196,7 +196,7 @@ which was derived from the R package's DESCRIPTION file."
 (define (cran->guix-package package-name)
   "Fetch the metadata for PACKAGE-NAME from cran.r-project.org, and return the
 `package' s-expression corresponding to that package, or #f on failure."
-  (let ((module-meta (cran-fetch package-name)))
+  (let ((module-meta (fetch-description %cran-url package-name)))
     (and=> module-meta description->package)))
 
 \f
@@ -230,7 +230,7 @@ which was derived from the R package's DESCRIPTION file."
     (package->upstream-name (specification->package package)))
 
   (define meta
-    (cran-fetch upstream-name))
+    (fetch-description %cran-url upstream-name))
 
   (and meta
        (let ((version (assoc-ref meta "Version")))
-- 
2.1.0


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #7: 0006-import-Add-Bioconductor-importer-and-updater.patch --]
[-- Type: text/x-patch, Size: 11877 bytes --]

From 3af383f041762778cb61d48f5e00b9656d616704 Mon Sep 17 00:00:00 2001
From: Ricardo Wurmus <ricardo.wurmus@mdc-berlin.de>
Date: Wed, 16 Dec 2015 14:45:28 +0100
Subject: [PATCH 6/6] import: Add Bioconductor importer and updater.

* guix/import/cran.scm (bioconductor->guix-package,
%bioconductor-updater, latest-bioconductor-release,
bioconductor-package?): New procedures.
(%bioconductor-url, %bioconductor-svn-url): New variables.
(description->package): Update signature to distinguish between packages
from different repositories.
(latest-release): Rename procedure ...
(latest-cran-release): ... to this.
(cran-package?): Do not assume all R packages are available on CRAN.
* tests/cran.scm: Update tests.
* guix/scripts/import.scm (importers): Add "bioconductor" importers.
* guix/scripts/refresh.scm (%updaters): Add "%bioconductor-updater".
* doc/guix.texi: Document Bioconductor importer and updater.
---
 doc/guix.texi            | 18 ++++++++++
 guix/import/cran.scm     | 93 +++++++++++++++++++++++++++++++++++++++---------
 guix/scripts/import.scm  |  3 +-
 guix/scripts/refresh.scm |  1 +
 tests/cran.scm           |  5 +--
 5 files changed, 101 insertions(+), 19 deletions(-)

diff --git a/doc/guix.texi b/doc/guix.texi
index 05a94dc..44f9daf 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -4214,6 +4214,22 @@ R package:
 guix import cran Cairo
 @end example
 
+@item bioconductor
+@cindex Bioconductor
+Import meta-data from @uref{http://www.bioconductor.org/, Bioconductor},
+a repository of R packages for for the analysis and comprehension of
+high-throughput genomic data in bioinformatics.
+
+Information is extracted from a package's DESCRIPTION file published on
+the web interface of the Bioconductor SVN repository.
+
+The command command below imports meta-data for the @code{GenomicRanges}
+R package:
+
+@example
+guix import bioconductor GenomicRanges
+@end example
+
 @item nix
 Import meta-data from a local copy of the source of the
 @uref{http://nixos.org/nixpkgs/, Nixpkgs distribution}@footnote{This
@@ -4412,6 +4428,8 @@ the updater for GNOME packages;
 the updater for @uref{http://elpa.gnu.org/, ELPA} packages;
 @item cran
 the updater for @uref{http://cran.r-project.org/, CRAN} packages;
+@item bioconductor
+the updater for @uref{http://www.bioconductor.org/, Bioconductor} packages;
 @item pypi
 the updater for @uref{https://pypi.python.org, PyPI} packages.
 @end table
diff --git a/guix/import/cran.scm b/guix/import/cran.scm
index fc27090..35b18b1 100644
--- a/guix/import/cran.scm
+++ b/guix/import/cran.scm
@@ -29,12 +29,14 @@
   #:use-module (guix base32)
   #:use-module ((guix download) #:select (download-to-store))
   #:use-module (guix import utils)
-  #:use-module ((guix build-system r) #:select (cran-uri))
+  #:use-module ((guix build-system r) #:select (cran-uri bioconductor-uri))
   #:use-module (guix upstream)
   #:use-module (guix packages)
   #:use-module (gnu packages)
   #:export (cran->guix-package
-            %cran-updater))
+            bioconductor->guix-package
+            %cran-updater
+            %bioconductor-updater))
 
 ;;; Commentary:
 ;;;
@@ -108,6 +110,15 @@ package definition."
      `((,type (,'quasiquote ,(format-inputs package-inputs)))))))
 
 (define %cran-url "http://cran.r-project.org/web/packages/")
+(define %bioconductor-url "http://bioconductor.org/packages/")
+
+;; The latest Bioconductor release is 3.2.  Bioconductor packages should be
+;; updated together.
+(define %bioconductor-svn-url
+  (string-append "https://readonly:readonly@"
+                 "hedgehog.fhcrc.org/bioconductor/branches/RELEASE_3_2/"
+                 "madman/Rpacks/"))
+
 
 (define (fetch-description base-url name)
   "Return an alist of the contents of the DESCRIPTION file for the R package
@@ -147,24 +158,31 @@ into a proper sentence and by using two spaces between sentences."
     (regexp-substitute/global #f "\\. \\b"
                               cleaned 'pre ".  " 'post)))
 
-(define (description->package meta)
-  "Return the `package' s-expression for a CRAN package from the alist META,
-which was derived from the R package's DESCRIPTION file."
+(define (description->package repository meta)
+  "Return the `package' s-expression for an R package published on REPOSITORY
+from the alist META, which was derived from the R package's DESCRIPTION file."
   (define (guix-name name)
     (if (string-prefix? "r-" name)
         (string-downcase name)
         (string-append "r-" (string-downcase name))))
 
-  (let* ((name       (assoc-ref meta "Package"))
+  (let* ((base-url   (case repository
+                       ((cran)         %cran-url)
+                       ((bioconductor) %bioconductor-url)))
+         (uri-helper (case repository
+                       ((cran)         cran-uri)
+                       ((bioconductor) bioconductor-uri)))
+         (name       (assoc-ref meta "Package"))
          (synopsis   (assoc-ref meta "Title"))
          (version    (assoc-ref meta "Version"))
          (license    (string->license (assoc-ref meta "License")))
          ;; Some packages have multiple home pages.  Some have none.
          (home-page  (match (listify meta "URL")
                        ((url rest ...) url)
-                       (_ (string-append %cran-url name))))
-         (source-url (match (cran-uri name version)
+                       (_ (string-append base-url name))))
+         (source-url (match (uri-helper name version)
                        ((url rest ...) url)
+                       ((? string? url) url)
                        (_ #f)))
          (tarball    (with-store store (download-to-store store source-url)))
          (sysdepends (map string-downcase (listify meta "SystemRequirements")))
@@ -178,16 +196,17 @@ which was derived from the R package's DESCRIPTION file."
        (version ,version)
        (source (origin
                  (method url-fetch)
-                 (uri (cran-uri ,name version))
+                 (uri (,(procedure-name uri-helper) ,name version))
                  (sha256
                   (base32
                    ,(bytevector->nix-base32-string (file-sha256 tarball))))))
-       (properties ,`(,'quasiquote ((,'upstream-name . ,name))))
+       (properties ,`(,'quasiquote ((,'upstream-name . ,name)
+                                    (,'r-repository  . ,repository))))
        (build-system r-build-system)
        ,@(maybe-inputs sysdepends)
        ,@(maybe-inputs propagate 'propagated-inputs)
        (home-page ,(if (string-null? home-page)
-                       (string-append %cran-url name)
+                       (string-append base-url name)
                        home-page))
        (synopsis ,synopsis)
        (description ,(beautify-description (assoc-ref meta "Description")))
@@ -197,7 +216,13 @@ which was derived from the R package's DESCRIPTION file."
   "Fetch the metadata for PACKAGE-NAME from cran.r-project.org, and return the
 `package' s-expression corresponding to that package, or #f on failure."
   (let ((module-meta (fetch-description %cran-url package-name)))
-    (and=> module-meta description->package)))
+    (and=> module-meta (cut description->package 'cran <>))))
+
+(define (bioconductor->guix-package package-name)
+  "Fetch the metadata for PACKAGE-NAME from bioconductor.org, and return the
+`package' s-expression corresponding to that package, or #f on failure."
+  (let ((module-meta (fetch-description %bioconductor-svn-url package-name)))
+    (and=> module-meta (cut description->package 'bioconductor <>))))
 
 \f
 ;;;
@@ -223,7 +248,7 @@ which was derived from the R package's DESCRIPTION file."
              (_ #f)))
           (_ #f)))))
 
-(define (latest-release package)
+(define (latest-cran-release package)
   "Return an <upstream-source> for the latest release of PACKAGE."
 
   (define upstream-name
@@ -240,16 +265,52 @@ which was derived from the R package's DESCRIPTION file."
           (version version)
           (urls (cran-uri upstream-name version))))))
 
+(define (latest-bioconductor-release package)
+  "Return an <upstream-source> for the latest release of PACKAGE."
+
+  (define upstream-name
+    (package->upstream-name (specification->package package)))
+
+  (define meta
+    (fetch-description %bioconductor-svn-url upstream-name))
+
+  (and meta
+       (let ((version (assoc-ref meta "Version")))
+         ;; Bioconductor does not provide signatures.
+         (upstream-source
+          (package package)
+          (version version)
+          (urls (bioconductor-uri upstream-name version))))))
+
 (define (cran-package? package)
   "Return true if PACKAGE is an R package from CRAN."
-  ;; Assume all R packages are available on CRAN.
-  (string-prefix? "r-" (package-name package)))
+  ;; Assume all R packages are available on CRAN, unless otherwise indicated
+  ;; by the r-repository property.
+  (let ((properties (package-properties package)))
+    (and (string-prefix? "r-" (package-name package))
+         (or (not properties)
+             (not (assoc-ref properties 'r-repository))
+             (eqv? 'cran (assoc-ref properties 'r-repository))))))
+
+(define (bioconductor-package? package)
+  "Return true if PACKAGE is an R package from Bioconductor."
+  (let ((properties (package-properties package)))
+    (and (string-prefix? "r-" (package-name package))
+         properties
+         (eqv? 'bioconductor (assoc-ref properties 'r-repository)))))
 
 (define %cran-updater
   (upstream-updater
    (name 'cran)
    (description "Updater for CRAN packages")
    (pred cran-package?)
-   (latest latest-release)))
+   (latest latest-cran-release)))
+
+(define %bioconductor-updater
+  (upstream-updater
+   (name 'bioconductor)
+   (description "Updater for Bioconductor packages")
+   (pred bioconductor-package?)
+   (latest latest-bioconductor-release)))
 
 ;;; cran.scm ends here
diff --git a/guix/scripts/import.scm b/guix/scripts/import.scm
index 7b29794..5810ef8 100644
--- a/guix/scripts/import.scm
+++ b/guix/scripts/import.scm
@@ -73,7 +73,8 @@ rather than \\n."
 ;;; Entry point.
 ;;;
 
-(define importers '("gnu" "nix" "pypi" "cpan" "hackage" "elpa" "gem" "cran"))
+(define importers '("gnu" "nix" "pypi" "cpan" "hackage" "elpa" "gem" "cran"
+                    "bioconductor"))
 
 (define (resolve-importer name)
   (let ((module (resolve-interface
diff --git a/guix/scripts/refresh.scm b/guix/scripts/refresh.scm
index a5834d1..f9e3f31 100644
--- a/guix/scripts/refresh.scm
+++ b/guix/scripts/refresh.scm
@@ -195,6 +195,7 @@ unavailable optional dependencies such as Guile-JSON."
                  %gnome-updater
                  %elpa-updater
                  %cran-updater
+                 %bioconductor-updater
                  ((guix import pypi) => %pypi-updater)))
 
 (define (lookup-updater name)
diff --git a/tests/cran.scm b/tests/cran.scm
index 0a4a2fd..72df2b3 100644
--- a/tests/cran.scm
+++ b/tests/cran.scm
@@ -107,7 +107,7 @@ Date/Publication: 2015-07-14 14:15:16
                   ("mirror://cran/src/contrib/My-Example_1.2.3.tar.gz"
                    "source")
                   (_ (error "Unexpected URL: " url))))))))
-    (match ((@@ (guix import cran) description->package) description-alist)
+    (match ((@@ (guix import cran) description->package) 'cran description-alist)
       (('package
          ('name "r-my-example")
          ('version "1.2.3")
@@ -117,7 +117,8 @@ Date/Publication: 2015-07-14 14:15:16
                     ('sha256
                      ('base32
                       (? string? hash)))))
-         ('properties ('quasiquote (('upstream-name . "My-Example"))))
+         ('properties ('quasiquote (('upstream-name . "My-Example")
+                                    ('r-repository  . 'cran))))
          ('build-system 'r-build-system)
          ('inputs
           ('quasiquote
-- 
2.1.0


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Re: [PATCH] Add Bioconductor importer and updater.
  2015-12-17 11:34 [PATCH] Add Bioconductor importer and updater Ricardo Wurmus
@ 2015-12-21 16:00 ` Ricardo Wurmus
  2015-12-22 22:01   ` Ludovic Courtès
  0 siblings, 1 reply; 9+ messages in thread
From: Ricardo Wurmus @ 2015-12-21 16:00 UTC (permalink / raw)
  To: guix-devel@gnu.org

[-- Attachment #1: Type: text/plain, Size: 471 bytes --]


Ricardo Wurmus <ricardo.wurmus@mdc-berlin.de> writes:

> The first two patches in this series are actually unrelated: the first
> fixes an annoying bug in the CRAN importer; the second corrects an
> outdated claim in the CRAN importer’s documentation.

I pushed the first two patches already.

Attached is a replacement for

  0006-import-Add-Bioconductor-importer-and-updater.patch

because I forgot to add the new importer script file.

~~ Ricardo


[-- Attachment #2: 0001-import-Add-Bioconductor-importer-and-updater.patch --]
[-- Type: text/x-patch, Size: 15780 bytes --]

From 8829683fffc03dec7f2faecea75cdd7831ce1741 Mon Sep 17 00:00:00 2001
From: Ricardo Wurmus <ricardo.wurmus@mdc-berlin.de>
Date: Wed, 16 Dec 2015 14:45:28 +0100
Subject: [PATCH] import: Add Bioconductor importer and updater.

* guix/import/cran.scm (bioconductor->guix-package,
%bioconductor-updater, latest-bioconductor-release,
bioconductor-package?): New procedures.
(%bioconductor-url, %bioconductor-svn-url): New variables.
(description->package): Update signature to distinguish between packages
from different repositories.
(latest-release): Rename procedure ...
(latest-cran-release): ... to this.
(cran-package?): Do not assume all R packages are available on CRAN.
* tests/cran.scm: Update tests.
* guix/scripts/import/bioconductor.scm: New file.
* guix/scripts/import.scm (importers): Add "bioconductor" importers.
* guix/scripts/refresh.scm (%updaters): Add "%bioconductor-updater".
* doc/guix.texi: Document Bioconductor importer and updater.
---
 doc/guix.texi                        | 18 +++++++
 guix/import/cran.scm                 | 93 +++++++++++++++++++++++++++++-------
 guix/scripts/import.scm              |  3 +-
 guix/scripts/import/bioconductor.scm | 92 +++++++++++++++++++++++++++++++++++
 guix/scripts/refresh.scm             |  1 +
 tests/cran.scm                       |  5 +-
 6 files changed, 193 insertions(+), 19 deletions(-)
 create mode 100644 guix/scripts/import/bioconductor.scm

diff --git a/doc/guix.texi b/doc/guix.texi
index e12bc9f..ef60f04 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -4215,6 +4215,22 @@ R package:
 guix import cran Cairo
 @end example
 
+@item bioconductor
+@cindex Bioconductor
+Import meta-data from @uref{http://www.bioconductor.org/, Bioconductor},
+a repository of R packages for for the analysis and comprehension of
+high-throughput genomic data in bioinformatics.
+
+Information is extracted from a package's DESCRIPTION file published on
+the web interface of the Bioconductor SVN repository.
+
+The command command below imports meta-data for the @code{GenomicRanges}
+R package:
+
+@example
+guix import bioconductor GenomicRanges
+@end example
+
 @item nix
 Import meta-data from a local copy of the source of the
 @uref{http://nixos.org/nixpkgs/, Nixpkgs distribution}@footnote{This
@@ -4413,6 +4429,8 @@ the updater for GNOME packages;
 the updater for @uref{http://elpa.gnu.org/, ELPA} packages;
 @item cran
 the updater for @uref{http://cran.r-project.org/, CRAN} packages;
+@item bioconductor
+the updater for @uref{http://www.bioconductor.org/, Bioconductor} packages;
 @item pypi
 the updater for @uref{https://pypi.python.org, PyPI} packages.
 @end table
diff --git a/guix/import/cran.scm b/guix/import/cran.scm
index fc27090..35b18b1 100644
--- a/guix/import/cran.scm
+++ b/guix/import/cran.scm
@@ -29,12 +29,14 @@
   #:use-module (guix base32)
   #:use-module ((guix download) #:select (download-to-store))
   #:use-module (guix import utils)
-  #:use-module ((guix build-system r) #:select (cran-uri))
+  #:use-module ((guix build-system r) #:select (cran-uri bioconductor-uri))
   #:use-module (guix upstream)
   #:use-module (guix packages)
   #:use-module (gnu packages)
   #:export (cran->guix-package
-            %cran-updater))
+            bioconductor->guix-package
+            %cran-updater
+            %bioconductor-updater))
 
 ;;; Commentary:
 ;;;
@@ -108,6 +110,15 @@ package definition."
      `((,type (,'quasiquote ,(format-inputs package-inputs)))))))
 
 (define %cran-url "http://cran.r-project.org/web/packages/")
+(define %bioconductor-url "http://bioconductor.org/packages/")
+
+;; The latest Bioconductor release is 3.2.  Bioconductor packages should be
+;; updated together.
+(define %bioconductor-svn-url
+  (string-append "https://readonly:readonly@"
+                 "hedgehog.fhcrc.org/bioconductor/branches/RELEASE_3_2/"
+                 "madman/Rpacks/"))
+
 
 (define (fetch-description base-url name)
   "Return an alist of the contents of the DESCRIPTION file for the R package
@@ -147,24 +158,31 @@ into a proper sentence and by using two spaces between sentences."
     (regexp-substitute/global #f "\\. \\b"
                               cleaned 'pre ".  " 'post)))
 
-(define (description->package meta)
-  "Return the `package' s-expression for a CRAN package from the alist META,
-which was derived from the R package's DESCRIPTION file."
+(define (description->package repository meta)
+  "Return the `package' s-expression for an R package published on REPOSITORY
+from the alist META, which was derived from the R package's DESCRIPTION file."
   (define (guix-name name)
     (if (string-prefix? "r-" name)
         (string-downcase name)
         (string-append "r-" (string-downcase name))))
 
-  (let* ((name       (assoc-ref meta "Package"))
+  (let* ((base-url   (case repository
+                       ((cran)         %cran-url)
+                       ((bioconductor) %bioconductor-url)))
+         (uri-helper (case repository
+                       ((cran)         cran-uri)
+                       ((bioconductor) bioconductor-uri)))
+         (name       (assoc-ref meta "Package"))
          (synopsis   (assoc-ref meta "Title"))
          (version    (assoc-ref meta "Version"))
          (license    (string->license (assoc-ref meta "License")))
          ;; Some packages have multiple home pages.  Some have none.
          (home-page  (match (listify meta "URL")
                        ((url rest ...) url)
-                       (_ (string-append %cran-url name))))
-         (source-url (match (cran-uri name version)
+                       (_ (string-append base-url name))))
+         (source-url (match (uri-helper name version)
                        ((url rest ...) url)
+                       ((? string? url) url)
                        (_ #f)))
          (tarball    (with-store store (download-to-store store source-url)))
          (sysdepends (map string-downcase (listify meta "SystemRequirements")))
@@ -178,16 +196,17 @@ which was derived from the R package's DESCRIPTION file."
        (version ,version)
        (source (origin
                  (method url-fetch)
-                 (uri (cran-uri ,name version))
+                 (uri (,(procedure-name uri-helper) ,name version))
                  (sha256
                   (base32
                    ,(bytevector->nix-base32-string (file-sha256 tarball))))))
-       (properties ,`(,'quasiquote ((,'upstream-name . ,name))))
+       (properties ,`(,'quasiquote ((,'upstream-name . ,name)
+                                    (,'r-repository  . ,repository))))
        (build-system r-build-system)
        ,@(maybe-inputs sysdepends)
        ,@(maybe-inputs propagate 'propagated-inputs)
        (home-page ,(if (string-null? home-page)
-                       (string-append %cran-url name)
+                       (string-append base-url name)
                        home-page))
        (synopsis ,synopsis)
        (description ,(beautify-description (assoc-ref meta "Description")))
@@ -197,7 +216,13 @@ which was derived from the R package's DESCRIPTION file."
   "Fetch the metadata for PACKAGE-NAME from cran.r-project.org, and return the
 `package' s-expression corresponding to that package, or #f on failure."
   (let ((module-meta (fetch-description %cran-url package-name)))
-    (and=> module-meta description->package)))
+    (and=> module-meta (cut description->package 'cran <>))))
+
+(define (bioconductor->guix-package package-name)
+  "Fetch the metadata for PACKAGE-NAME from bioconductor.org, and return the
+`package' s-expression corresponding to that package, or #f on failure."
+  (let ((module-meta (fetch-description %bioconductor-svn-url package-name)))
+    (and=> module-meta (cut description->package 'bioconductor <>))))
 
 \f
 ;;;
@@ -223,7 +248,7 @@ which was derived from the R package's DESCRIPTION file."
              (_ #f)))
           (_ #f)))))
 
-(define (latest-release package)
+(define (latest-cran-release package)
   "Return an <upstream-source> for the latest release of PACKAGE."
 
   (define upstream-name
@@ -240,16 +265,52 @@ which was derived from the R package's DESCRIPTION file."
           (version version)
           (urls (cran-uri upstream-name version))))))
 
+(define (latest-bioconductor-release package)
+  "Return an <upstream-source> for the latest release of PACKAGE."
+
+  (define upstream-name
+    (package->upstream-name (specification->package package)))
+
+  (define meta
+    (fetch-description %bioconductor-svn-url upstream-name))
+
+  (and meta
+       (let ((version (assoc-ref meta "Version")))
+         ;; Bioconductor does not provide signatures.
+         (upstream-source
+          (package package)
+          (version version)
+          (urls (bioconductor-uri upstream-name version))))))
+
 (define (cran-package? package)
   "Return true if PACKAGE is an R package from CRAN."
-  ;; Assume all R packages are available on CRAN.
-  (string-prefix? "r-" (package-name package)))
+  ;; Assume all R packages are available on CRAN, unless otherwise indicated
+  ;; by the r-repository property.
+  (let ((properties (package-properties package)))
+    (and (string-prefix? "r-" (package-name package))
+         (or (not properties)
+             (not (assoc-ref properties 'r-repository))
+             (eqv? 'cran (assoc-ref properties 'r-repository))))))
+
+(define (bioconductor-package? package)
+  "Return true if PACKAGE is an R package from Bioconductor."
+  (let ((properties (package-properties package)))
+    (and (string-prefix? "r-" (package-name package))
+         properties
+         (eqv? 'bioconductor (assoc-ref properties 'r-repository)))))
 
 (define %cran-updater
   (upstream-updater
    (name 'cran)
    (description "Updater for CRAN packages")
    (pred cran-package?)
-   (latest latest-release)))
+   (latest latest-cran-release)))
+
+(define %bioconductor-updater
+  (upstream-updater
+   (name 'bioconductor)
+   (description "Updater for Bioconductor packages")
+   (pred bioconductor-package?)
+   (latest latest-bioconductor-release)))
 
 ;;; cran.scm ends here
diff --git a/guix/scripts/import.scm b/guix/scripts/import.scm
index 7b29794..5810ef8 100644
--- a/guix/scripts/import.scm
+++ b/guix/scripts/import.scm
@@ -73,7 +73,8 @@ rather than \\n."
 ;;; Entry point.
 ;;;
 
-(define importers '("gnu" "nix" "pypi" "cpan" "hackage" "elpa" "gem" "cran"))
+(define importers '("gnu" "nix" "pypi" "cpan" "hackage" "elpa" "gem" "cran"
+                    "bioconductor"))
 
 (define (resolve-importer name)
   (let ((module (resolve-interface
diff --git a/guix/scripts/import/bioconductor.scm b/guix/scripts/import/bioconductor.scm
new file mode 100644
index 0000000..41b32e0
--- /dev/null
+++ b/guix/scripts/import/bioconductor.scm
@@ -0,0 +1,92 @@
+;;; GNU Guix --- Functional package management for GNU
+;;; Copyright © 2015 Ricardo Wurmus <rekado@elephly.net>
+;;;
+;;; This file is part of GNU Guix.
+;;;
+;;; GNU Guix is free software; you can redistribute it and/or modify it
+;;; under the terms of the GNU General Public License as published by
+;;; the Free Software Foundation; either version 3 of the License, or (at
+;;; your option) any later version.
+;;;
+;;; GNU Guix is distributed in the hope that it will be useful, but
+;;; WITHOUT ANY WARRANTY; without even the implied warranty of
+;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;;; GNU General Public License for more details.
+;;;
+;;; You should have received a copy of the GNU General Public License
+;;; along with GNU Guix.  If not, see <http://www.gnu.org/licenses/>.
+
+(define-module (guix scripts import bioconductor)
+  #:use-module (guix ui)
+  #:use-module (guix utils)
+  #:use-module (guix scripts)
+  #:use-module (guix import cran)
+  #:use-module (guix scripts import)
+  #:use-module (srfi srfi-1)
+  #:use-module (srfi srfi-11)
+  #:use-module (srfi srfi-37)
+  #:use-module (ice-9 match)
+  #:use-module (ice-9 format)
+  #:export (guix-import-bioconductor))
+
+\f
+;;;
+;;; Command-line options.
+;;;
+
+(define %default-options
+  '())
+
+(define (show-help)
+  (display (_ "Usage: guix import bioconductor PACKAGE-NAME
+Import and convert the Bioconductor package for PACKAGE-NAME.\n"))
+  (display (_ "
+  -h, --help             display this help and exit"))
+  (display (_ "
+  -V, --version          display version information and exit"))
+  (newline)
+  (show-bug-report-information))
+
+(define %options
+  ;; Specification of the command-line options.
+  (cons* (option '(#\h "help") #f #f
+                 (lambda args
+                   (show-help)
+                   (exit 0)))
+         (option '(#\V "version") #f #f
+                 (lambda args
+                   (show-version-and-exit "guix import bioconductor")))
+         %standard-import-options))
+
+\f
+;;;
+;;; Entry point.
+;;;
+
+(define (guix-import-bioconductor . args)
+  (define (parse-options)
+    ;; Return the alist of option values.
+    (args-fold* args %options
+                (lambda (opt name arg result)
+                  (leave (_ "~A: unrecognized option~%") name))
+                (lambda (arg result)
+                  (alist-cons 'argument arg result))
+                %default-options))
+
+  (let* ((opts (parse-options))
+         (args (filter-map (match-lambda
+                            (('argument . value)
+                             value)
+                            (_ #f))
+                           (reverse opts))))
+    (match args
+      ((package-name)
+       (let ((sexp (bioconductor->guix-package package-name)))
+         (unless sexp
+           (leave (_ "failed to download description for package '~a'~%")
+                  package-name))
+         sexp))
+      (()
+       (leave (_ "too few arguments~%")))
+      ((many ...)
+       (leave (_ "too many arguments~%"))))))
diff --git a/guix/scripts/refresh.scm b/guix/scripts/refresh.scm
index a5834d1..f9e3f31 100644
--- a/guix/scripts/refresh.scm
+++ b/guix/scripts/refresh.scm
@@ -195,6 +195,7 @@ unavailable optional dependencies such as Guile-JSON."
                  %gnome-updater
                  %elpa-updater
                  %cran-updater
+                 %bioconductor-updater
                  ((guix import pypi) => %pypi-updater)))
 
 (define (lookup-updater name)
diff --git a/tests/cran.scm b/tests/cran.scm
index 0a4a2fd..72df2b3 100644
--- a/tests/cran.scm
+++ b/tests/cran.scm
@@ -107,7 +107,7 @@ Date/Publication: 2015-07-14 14:15:16
                   ("mirror://cran/src/contrib/My-Example_1.2.3.tar.gz"
                    "source")
                   (_ (error "Unexpected URL: " url))))))))
-    (match ((@@ (guix import cran) description->package) description-alist)
+    (match ((@@ (guix import cran) description->package) 'cran description-alist)
       (('package
          ('name "r-my-example")
          ('version "1.2.3")
@@ -117,7 +117,8 @@ Date/Publication: 2015-07-14 14:15:16
                     ('sha256
                      ('base32
                       (? string? hash)))))
-         ('properties ('quasiquote (('upstream-name . "My-Example"))))
+         ('properties ('quasiquote (('upstream-name . "My-Example")
+                                    ('r-repository  . 'cran))))
          ('build-system 'r-build-system)
          ('inputs
           ('quasiquote
-- 
2.1.0


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Re: [PATCH] Add Bioconductor importer and updater.
  2015-12-21 16:00 ` Ricardo Wurmus
@ 2015-12-22 22:01   ` Ludovic Courtès
  2016-01-06 15:02     ` Ricardo Wurmus
  0 siblings, 1 reply; 9+ messages in thread
From: Ludovic Courtès @ 2015-12-22 22:01 UTC (permalink / raw)
  To: Ricardo Wurmus; +Cc: guix-devel@gnu.org

Ricardo Wurmus <ricardo.wurmus@mdc-berlin.de> skribis:

> From 8829683fffc03dec7f2faecea75cdd7831ce1741 Mon Sep 17 00:00:00 2001
> From: Ricardo Wurmus <ricardo.wurmus@mdc-berlin.de>
> Date: Wed, 16 Dec 2015 14:45:28 +0100
> Subject: [PATCH] import: Add Bioconductor importer and updater.
>
> * guix/import/cran.scm (bioconductor->guix-package,
> %bioconductor-updater, latest-bioconductor-release,
> bioconductor-package?): New procedures.
> (%bioconductor-url, %bioconductor-svn-url): New variables.
> (description->package): Update signature to distinguish between packages
> from different repositories.
> (latest-release): Rename procedure ...
> (latest-cran-release): ... to this.
> (cran-package?): Do not assume all R packages are available on CRAN.
> * tests/cran.scm: Update tests.
> * guix/scripts/import/bioconductor.scm: New file.
> * guix/scripts/import.scm (importers): Add "bioconductor" importers.
> * guix/scripts/refresh.scm (%updaters): Add "%bioconductor-updater".
> * doc/guix.texi: Document Bioconductor importer and updater.

[...]

>  @item cran
>  the updater for @uref{http://cran.r-project.org/, CRAN} packages;
> +@item bioconductor
> +the updater for @uref{http://www.bioconductor.org/, Bioconductor} packages;

“R packages”

> -       (properties ,`(,'quasiquote ((,'upstream-name . ,name))))
> +       (properties ,`(,'quasiquote ((,'upstream-name . ,name)
> +                                    (,'r-repository  . ,repository))))

What about adding ‘upstream-name’ only when the upstream name is
different from the Guix name minus “r-”?

Regarding ‘r-repository’, I guess it can be inferred from the source
URL?

The risk with properties is that they are missing from current packages,
they are easily forgotten (since there’s no expansion-time check for
these), and forgetting them would lead to packages being silently
ignored by ‘guix refresh’.

>  (define (cran-package? package)
>    "Return true if PACKAGE is an R package from CRAN."
> -  ;; Assume all R packages are available on CRAN.
> -  (string-prefix? "r-" (package-name package)))
> +  ;; Assume all R packages are available on CRAN, unless otherwise indicated
> +  ;; by the r-repository property.
> +  (let ((properties (package-properties package)))
> +    (and (string-prefix? "r-" (package-name package))
> +         (or (not properties)
> +             (not (assoc-ref properties 'r-repository))
> +             (eqv? 'cran (assoc-ref properties 'r-repository))))))

We could check whether the source URL starts with “mirror://cran”, no?
And forget about the ‘r-repository’ property?

> +(define (bioconductor-package? package)
> +  "Return true if PACKAGE is an R package from Bioconductor."
> +  (let ((properties (package-properties package)))
> +    (and (string-prefix? "r-" (package-name package))
> +         properties
> +         (eqv? 'bioconductor (assoc-ref properties 'r-repository)))))

Likewise, should we check based on the URL?

> +++ b/guix/scripts/import/bioconductor.scm

I was wondering whether this should be a separate script or not.  A
precedent would be the ELPA importer, which takes a repository name as
an argument.  We could have done the same with the CRAN importer here.

WDYT?

The rest LGTM.

Thank you!

Ludo’.

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH] Add Bioconductor importer and updater.
  2015-12-22 22:01   ` Ludovic Courtès
@ 2016-01-06 15:02     ` Ricardo Wurmus
  2016-01-06 16:49       ` Ricardo Wurmus
  2016-01-07 18:08       ` Ludovic Courtès
  0 siblings, 2 replies; 9+ messages in thread
From: Ricardo Wurmus @ 2016-01-06 15:02 UTC (permalink / raw)
  To: Ludovic Courtès; +Cc: guix-devel@gnu.org


Ludovic Courtès <ludo@gnu.org> writes:

> Ricardo Wurmus <ricardo.wurmus@mdc-berlin.de> skribis:
>
>> From 8829683fffc03dec7f2faecea75cdd7831ce1741 Mon Sep 17 00:00:00 2001
>> From: Ricardo Wurmus <ricardo.wurmus@mdc-berlin.de>
>> Date: Wed, 16 Dec 2015 14:45:28 +0100
>> Subject: [PATCH] import: Add Bioconductor importer and updater.
>>
>> * guix/import/cran.scm (bioconductor->guix-package,
>> %bioconductor-updater, latest-bioconductor-release,
>> bioconductor-package?): New procedures.
>> (%bioconductor-url, %bioconductor-svn-url): New variables.
>> (description->package): Update signature to distinguish between packages
>> from different repositories.
>> (latest-release): Rename procedure ...
>> (latest-cran-release): ... to this.
>> (cran-package?): Do not assume all R packages are available on CRAN.
>> * tests/cran.scm: Update tests.
>> * guix/scripts/import/bioconductor.scm: New file.
>> * guix/scripts/import.scm (importers): Add "bioconductor" importers.
>> * guix/scripts/refresh.scm (%updaters): Add "%bioconductor-updater".
>> * doc/guix.texi: Document Bioconductor importer and updater.
>
> [...]
>
>>  @item cran
>>  the updater for @uref{http://cran.r-project.org/, CRAN} packages;
>> +@item bioconductor
>> +the updater for @uref{http://www.bioconductor.org/, Bioconductor} packages;
>
> “R packages”

Okay.

>> -       (properties ,`(,'quasiquote ((,'upstream-name . ,name))))
>> +       (properties ,`(,'quasiquote ((,'upstream-name . ,name)
>> +                                    (,'r-repository  . ,repository))))
>
> What about adding ‘upstream-name’ only when the upstream name is
> different from the Guix name minus “r-”?

Good idea.

> Regarding ‘r-repository’, I guess it can be inferred from the source
> URL?

[...]

> We could check whether the source URL starts with “mirror://cran”, no?
> And forget about the ‘r-repository’ property?

I think so.  I’ve just updated the patches.

>> +++ b/guix/scripts/import/bioconductor.scm
>
> I was wondering whether this should be a separate script or not.  A
> precedent would be the ELPA importer, which takes a repository name as
> an argument.  We could have done the same with the CRAN importer here.

I would prefer not to have a separate script, because there’s so much
duplication.  I’ll look at the ELPA importer for inspiration.

Should the CRAN importer have its name changed, though?

~~ Ricardo

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH] Add Bioconductor importer and updater.
  2016-01-06 15:02     ` Ricardo Wurmus
@ 2016-01-06 16:49       ` Ricardo Wurmus
  2016-01-10 20:20         ` Ludovic Courtès
  2016-01-07 18:08       ` Ludovic Courtès
  1 sibling, 1 reply; 9+ messages in thread
From: Ricardo Wurmus @ 2016-01-06 16:49 UTC (permalink / raw)
  To: Ludovic Courtès; +Cc: guix-devel@gnu.org

[-- Attachment #1: Type: text/plain, Size: 936 bytes --]


Ricardo Wurmus <ricardo.wurmus@mdc-berlin.de> writes:

>> We could check whether the source URL starts with “mirror://cran”, no?
>> And forget about the ‘r-repository’ property?
>
> I think so.  I’ve just updated the patches.
>
>>> +++ b/guix/scripts/import/bioconductor.scm
>>
>> I was wondering whether this should be a separate script or not.  A
>> precedent would be the ELPA importer, which takes a repository name as
>> an argument.  We could have done the same with the CRAN importer here.
>
> I would prefer not to have a separate script, because there’s so much
> duplication.  I’ll look at the ELPA importer for inspiration.

Attached is a new patch (only the last one of the series) which adds
“--archive=bioconductor” as an option to the CRAN importer in addition
to the other requested changes (removal of “r-repository”, etc).  I also
changed the documentation.

~~ Ricardo


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-import-Add-Bioconductor-importer-and-updater.patch --]
[-- Type: text/x-patch, Size: 12922 bytes --]

From 616e5ca0d7d76718172b7f0373a10744e3df7731 Mon Sep 17 00:00:00 2001
From: Ricardo Wurmus <ricardo.wurmus@mdc-berlin.de>
Date: Wed, 16 Dec 2015 14:45:28 +0100
Subject: [PATCH] import: Add Bioconductor importer and updater.

* guix/import/cran.scm (%bioconductor-updater,
latest-bioconductor-release, bioconductor-package?): New procedures.
(cran->guix-package): Support repositories other than CRAN.
(%bioconductor-url, %bioconductor-svn-url): New variables.
(description->package): Update signature to distinguish between packages
from different repositories.
(latest-release): Rename procedure ...
(latest-cran-release): ... to this.
(cran-package?): Do not assume all R packages are available on CRAN.
* tests/cran.scm: Update tests.
* guix/scripts/import/cran.scm: Add "--archive" option and default to
CRAN.
* guix/scripts/refresh.scm (%updaters): Add "%bioconductor-updater".
* doc/guix.texi: Document Bioconductor importer and updater.
---
 doc/guix.texi                |  18 ++++++++
 guix/import/cran.scm         | 103 ++++++++++++++++++++++++++++++++++---------
 guix/scripts/import/cran.scm |   9 +++-
 guix/scripts/refresh.scm     |   1 +
 tests/cran.scm               |   2 +-
 5 files changed, 111 insertions(+), 22 deletions(-)

diff --git a/doc/guix.texi b/doc/guix.texi
index c252f63..05e59fb 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -4237,6 +4237,7 @@ guix import cpan Acme::Boolean
 
 @item cran
 @cindex CRAN
+@cindex Bioconductor
 Import meta-data from @uref{http://cran.r-project.org/, CRAN}, the
 central repository for the @uref{http://r-project.org, GNU@tie{}R
 statistical and graphical environment}.
@@ -4250,6 +4251,21 @@ R package:
 guix import cran Cairo
 @end example
 
+When @code{--archive=bioconductor} is added, meta-data is imported from
+@uref{http://www.bioconductor.org/, Bioconductor}, a repository of R
+packages for for the analysis and comprehension of high-throughput
+genomic data in bioinformatics.
+
+Information is extracted from a package's DESCRIPTION file published on
+the web interface of the Bioconductor SVN repository.
+
+The command command below imports meta-data for the @code{GenomicRanges}
+R package:
+
+@example
+guix import cran --archive=bioconductor GenomicRanges
+@end example
+
 @item nix
 Import meta-data from a local copy of the source of the
 @uref{http://nixos.org/nixpkgs/, Nixpkgs distribution}@footnote{This
@@ -4448,6 +4464,8 @@ the updater for GNOME packages;
 the updater for @uref{http://elpa.gnu.org/, ELPA} packages;
 @item cran
 the updater for @uref{http://cran.r-project.org/, CRAN} packages;
+@item bioconductor
+the updater for @uref{http://www.bioconductor.org/, Bioconductor} R packages;
 @item pypi
 the updater for @uref{https://pypi.python.org, PyPI} packages.
 @end table
diff --git a/guix/import/cran.scm b/guix/import/cran.scm
index fc27090..de01ccc 100644
--- a/guix/import/cran.scm
+++ b/guix/import/cran.scm
@@ -29,12 +29,14 @@
   #:use-module (guix base32)
   #:use-module ((guix download) #:select (download-to-store))
   #:use-module (guix import utils)
-  #:use-module ((guix build-system r) #:select (cran-uri))
+  #:use-module ((guix build-system r) #:select (cran-uri bioconductor-uri))
   #:use-module (guix upstream)
   #:use-module (guix packages)
   #:use-module (gnu packages)
   #:export (cran->guix-package
-            %cran-updater))
+            bioconductor->guix-package
+            %cran-updater
+            %bioconductor-updater))
 
 ;;; Commentary:
 ;;;
@@ -108,6 +110,15 @@ package definition."
      `((,type (,'quasiquote ,(format-inputs package-inputs)))))))
 
 (define %cran-url "http://cran.r-project.org/web/packages/")
+(define %bioconductor-url "http://bioconductor.org/packages/")
+
+;; The latest Bioconductor release is 3.2.  Bioconductor packages should be
+;; updated together.
+(define %bioconductor-svn-url
+  (string-append "https://readonly:readonly@"
+                 "hedgehog.fhcrc.org/bioconductor/branches/RELEASE_3_2/"
+                 "madman/Rpacks/"))
+
 
 (define (fetch-description base-url name)
   "Return an alist of the contents of the DESCRIPTION file for the R package
@@ -147,24 +158,31 @@ into a proper sentence and by using two spaces between sentences."
     (regexp-substitute/global #f "\\. \\b"
                               cleaned 'pre ".  " 'post)))
 
-(define (description->package meta)
-  "Return the `package' s-expression for a CRAN package from the alist META,
-which was derived from the R package's DESCRIPTION file."
+(define (description->package repository meta)
+  "Return the `package' s-expression for an R package published on REPOSITORY
+from the alist META, which was derived from the R package's DESCRIPTION file."
   (define (guix-name name)
     (if (string-prefix? "r-" name)
         (string-downcase name)
         (string-append "r-" (string-downcase name))))
 
-  (let* ((name       (assoc-ref meta "Package"))
+  (let* ((base-url   (case repository
+                       ((cran)         %cran-url)
+                       ((bioconductor) %bioconductor-url)))
+         (uri-helper (case repository
+                       ((cran)         cran-uri)
+                       ((bioconductor) bioconductor-uri)))
+         (name       (assoc-ref meta "Package"))
          (synopsis   (assoc-ref meta "Title"))
          (version    (assoc-ref meta "Version"))
          (license    (string->license (assoc-ref meta "License")))
          ;; Some packages have multiple home pages.  Some have none.
          (home-page  (match (listify meta "URL")
                        ((url rest ...) url)
-                       (_ (string-append %cran-url name))))
-         (source-url (match (cran-uri name version)
+                       (_ (string-append base-url name))))
+         (source-url (match (uri-helper name version)
                        ((url rest ...) url)
+                       ((? string? url) url)
                        (_ #f)))
          (tarball    (with-store store (download-to-store store source-url)))
          (sysdepends (map string-downcase (listify meta "SystemRequirements")))
@@ -178,26 +196,32 @@ which was derived from the R package's DESCRIPTION file."
        (version ,version)
        (source (origin
                  (method url-fetch)
-                 (uri (cran-uri ,name version))
+                 (uri (,(procedure-name uri-helper) ,name version))
                  (sha256
                   (base32
                    ,(bytevector->nix-base32-string (file-sha256 tarball))))))
-       (properties ,`(,'quasiquote ((,'upstream-name . ,name))))
+       ,@(if (not (equal? (string-append "r-" name)
+                          (guix-name name)))
+             `((properties ,`(,'quasiquote ((,'upstream-name . ,name)))))
+             '())
        (build-system r-build-system)
        ,@(maybe-inputs sysdepends)
        ,@(maybe-inputs propagate 'propagated-inputs)
        (home-page ,(if (string-null? home-page)
-                       (string-append %cran-url name)
+                       (string-append base-url name)
                        home-page))
        (synopsis ,synopsis)
        (description ,(beautify-description (assoc-ref meta "Description")))
        (license ,license))))
 
-(define (cran->guix-package package-name)
-  "Fetch the metadata for PACKAGE-NAME from cran.r-project.org, and return the
-`package' s-expression corresponding to that package, or #f on failure."
-  (let ((module-meta (fetch-description %cran-url package-name)))
-    (and=> module-meta description->package)))
+(define* (cran->guix-package package-name #:optional (repo 'cran))
+  "Fetch the metadata for PACKAGE-NAME from REPO and return the `package'
+s-expression corresponding to that package, or #f on failure."
+  (let* ((url (case repo
+                ((cran)         %cran-url)
+                ((bioconductor) %bioconductor-svn-url)))
+         (module-meta (fetch-description url package-name)))
+    (and=> module-meta (cut description->package repo <>))))
 
 \f
 ;;;
@@ -223,7 +247,7 @@ which was derived from the R package's DESCRIPTION file."
              (_ #f)))
           (_ #f)))))
 
-(define (latest-release package)
+(define (latest-cran-release package)
   "Return an <upstream-source> for the latest release of PACKAGE."
 
   (define upstream-name
@@ -240,16 +264,55 @@ which was derived from the R package's DESCRIPTION file."
           (version version)
           (urls (cran-uri upstream-name version))))))
 
+(define (latest-bioconductor-release package)
+  "Return an <upstream-source> for the latest release of PACKAGE."
+
+  (define upstream-name
+    (package->upstream-name (specification->package package)))
+
+  (define meta
+    (fetch-description %bioconductor-svn-url upstream-name))
+
+  (and meta
+       (let ((version (assoc-ref meta "Version")))
+         ;; Bioconductor does not provide signatures.
+         (upstream-source
+          (package package)
+          (version version)
+          (urls (bioconductor-uri upstream-name version))))))
+
 (define (cran-package? package)
   "Return true if PACKAGE is an R package from CRAN."
-  ;; Assume all R packages are available on CRAN.
-  (string-prefix? "r-" (package-name package)))
+  (and (string-prefix? "r-" (package-name package))
+       (match (and=> (package-source package) origin-uri)
+         ((? string? uri)
+          (string-prefix? "mirror://cran" uri))
+         ((? list? uris)
+          (any (cut string-prefix? "mirror://cran" <>) uris))
+         (_ #f))))
+
+(define (bioconductor-package? package)
+  "Return true if PACKAGE is an R package from Bioconductor."
+  (and (string-prefix? "r-" (package-name package))
+       (match (and=> (package-source package) origin-uri)
+         ((? string? uri)
+          (string-prefix? "http://bioconductor.org" uri))
+         ((? list? uris)
+          (any (cut string-prefix? "http://bioconductor.org" <>) uris))
+         (_ #f))))
 
 (define %cran-updater
   (upstream-updater
    (name 'cran)
    (description "Updater for CRAN packages")
    (pred cran-package?)
-   (latest latest-release)))
+   (latest latest-cran-release)))
+
+(define %bioconductor-updater
+  (upstream-updater
+   (name 'bioconductor)
+   (description "Updater for Bioconductor packages")
+   (pred bioconductor-package?)
+   (latest latest-bioconductor-release)))
 
 ;;; cran.scm ends here
diff --git a/guix/scripts/import/cran.scm b/guix/scripts/import/cran.scm
index 8d001ac..ace1123 100644
--- a/guix/scripts/import/cran.scm
+++ b/guix/scripts/import/cran.scm
@@ -42,6 +42,8 @@
   (display (_ "Usage: guix import cran PACKAGE-NAME
 Import and convert the CRAN package for PACKAGE-NAME.\n"))
   (display (_ "
+  -a, --archive=ARCHIVE  specify the archive repository"))
+  (display (_ "
   -h, --help             display this help and exit"))
   (display (_ "
   -V, --version          display version information and exit"))
@@ -57,6 +59,10 @@ Import and convert the CRAN package for PACKAGE-NAME.\n"))
          (option '(#\V "version") #f #f
                  (lambda args
                    (show-version-and-exit "guix import cran")))
+         (option '(#\a "archive") #t #f
+                 (lambda (opt name arg result)
+                   (alist-cons 'repo (string->symbol arg)
+                               (alist-delete 'repo result))))
          %standard-import-options))
 
 \f
@@ -82,7 +88,8 @@ Import and convert the CRAN package for PACKAGE-NAME.\n"))
                            (reverse opts))))
     (match args
       ((package-name)
-       (let ((sexp (cran->guix-package package-name)))
+       (let ((sexp (cran->guix-package package-name
+                                       (or (assoc-ref opts 'repo) 'cran))))
          (unless sexp
            (leave (_ "failed to download description for package '~a'~%")
                   package-name))
diff --git a/guix/scripts/refresh.scm b/guix/scripts/refresh.scm
index a5834d1..f9e3f31 100644
--- a/guix/scripts/refresh.scm
+++ b/guix/scripts/refresh.scm
@@ -195,6 +195,7 @@ unavailable optional dependencies such as Guile-JSON."
                  %gnome-updater
                  %elpa-updater
                  %cran-updater
+                 %bioconductor-updater
                  ((guix import pypi) => %pypi-updater)))
 
 (define (lookup-updater name)
diff --git a/tests/cran.scm b/tests/cran.scm
index 0a4a2fd..e4f2235 100644
--- a/tests/cran.scm
+++ b/tests/cran.scm
@@ -107,7 +107,7 @@ Date/Publication: 2015-07-14 14:15:16
                   ("mirror://cran/src/contrib/My-Example_1.2.3.tar.gz"
                    "source")
                   (_ (error "Unexpected URL: " url))))))))
-    (match ((@@ (guix import cran) description->package) description-alist)
+    (match ((@@ (guix import cran) description->package) 'cran description-alist)
       (('package
          ('name "r-my-example")
          ('version "1.2.3")
-- 
2.1.0


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Re: [PATCH] Add Bioconductor importer and updater.
  2016-01-06 15:02     ` Ricardo Wurmus
  2016-01-06 16:49       ` Ricardo Wurmus
@ 2016-01-07 18:08       ` Ludovic Courtès
  2016-01-07 18:29         ` Ricardo Wurmus
  1 sibling, 1 reply; 9+ messages in thread
From: Ludovic Courtès @ 2016-01-07 18:08 UTC (permalink / raw)
  To: Ricardo Wurmus; +Cc: guix-devel@gnu.org

Ricardo Wurmus <ricardo.wurmus@mdc-berlin.de> skribis:

> Ludovic Courtès <ludo@gnu.org> writes:

>> I was wondering whether this should be a separate script or not.  A
>> precedent would be the ELPA importer, which takes a repository name as
>> an argument.  We could have done the same with the CRAN importer here.
>
> I would prefer not to have a separate script, because there’s so much
> duplication.  I’ll look at the ELPA importer for inspiration.
>
> Should the CRAN importer have its name changed, though?

I think it’s fine to call it CRAN, even if it supports other
repositories.  The CRAN and ELPA importers support the CRAN/ELPA
repository formats, not just the same-named repositories.

Ludo’.

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH] Add Bioconductor importer and updater.
  2016-01-07 18:08       ` Ludovic Courtès
@ 2016-01-07 18:29         ` Ricardo Wurmus
  0 siblings, 0 replies; 9+ messages in thread
From: Ricardo Wurmus @ 2016-01-07 18:29 UTC (permalink / raw)
  To: Ludovic Courtès; +Cc: guix-devel@gnu.org


Ludovic Courtès <ludo@gnu.org> writes:

> Ricardo Wurmus <ricardo.wurmus@mdc-berlin.de> skribis:
>
>> Ludovic Courtès <ludo@gnu.org> writes:
>
>>> I was wondering whether this should be a separate script or not.  A
>>> precedent would be the ELPA importer, which takes a repository name as
>>> an argument.  We could have done the same with the CRAN importer here.
>>
>> I would prefer not to have a separate script, because there’s so much
>> duplication.  I’ll look at the ELPA importer for inspiration.
>>
>> Should the CRAN importer have its name changed, though?
>
> I think it’s fine to call it CRAN, even if it supports other
> repositories.  The CRAN and ELPA importers support the CRAN/ELPA
> repository formats, not just the same-named repositories.

Okay, this makes sense.  Well, I think it’s ready for merging then.
Unless there are further comments I should consider I’ll push this by
the end of this week.

Thank you!

~~ Ricardo

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH] Add Bioconductor importer and updater.
  2016-01-06 16:49       ` Ricardo Wurmus
@ 2016-01-10 20:20         ` Ludovic Courtès
  2016-01-20 11:43           ` Ricardo Wurmus
  0 siblings, 1 reply; 9+ messages in thread
From: Ludovic Courtès @ 2016-01-10 20:20 UTC (permalink / raw)
  To: Ricardo Wurmus; +Cc: guix-devel@gnu.org

Ricardo Wurmus <ricardo.wurmus@mdc-berlin.de> skribis:

> From 616e5ca0d7d76718172b7f0373a10744e3df7731 Mon Sep 17 00:00:00 2001
> From: Ricardo Wurmus <ricardo.wurmus@mdc-berlin.de>
> Date: Wed, 16 Dec 2015 14:45:28 +0100
> Subject: [PATCH] import: Add Bioconductor importer and updater.
>
> * guix/import/cran.scm (%bioconductor-updater,
> latest-bioconductor-release, bioconductor-package?): New procedures.
> (cran->guix-package): Support repositories other than CRAN.
> (%bioconductor-url, %bioconductor-svn-url): New variables.
> (description->package): Update signature to distinguish between packages
> from different repositories.
> (latest-release): Rename procedure ...
> (latest-cran-release): ... to this.
> (cran-package?): Do not assume all R packages are available on CRAN.
> * tests/cran.scm: Update tests.
> * guix/scripts/import/cran.scm: Add "--archive" option and default to
> CRAN.
> * guix/scripts/refresh.scm (%updaters): Add "%bioconductor-updater".
> * doc/guix.texi: Document Bioconductor importer and updater.

[...]

> +Information is extracted from a package's DESCRIPTION file published on

@file{DESCRIPTION}

Apart from that, OK to push!

Thank you!

Ludo’.

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH] Add Bioconductor importer and updater.
  2016-01-10 20:20         ` Ludovic Courtès
@ 2016-01-20 11:43           ` Ricardo Wurmus
  0 siblings, 0 replies; 9+ messages in thread
From: Ricardo Wurmus @ 2016-01-20 11:43 UTC (permalink / raw)
  To: Ludovic Courtès; +Cc: guix-devel@gnu.org


Ludovic Courtès <ludo@gnu.org> writes:

> Ricardo Wurmus <ricardo.wurmus@mdc-berlin.de> skribis:
>
>> From 616e5ca0d7d76718172b7f0373a10744e3df7731 Mon Sep 17 00:00:00 2001
>> From: Ricardo Wurmus <ricardo.wurmus@mdc-berlin.de>
>> Date: Wed, 16 Dec 2015 14:45:28 +0100
>> Subject: [PATCH] import: Add Bioconductor importer and updater.
>>
>> * guix/import/cran.scm (%bioconductor-updater,
>> latest-bioconductor-release, bioconductor-package?): New procedures.
>> (cran->guix-package): Support repositories other than CRAN.
>> (%bioconductor-url, %bioconductor-svn-url): New variables.
>> (description->package): Update signature to distinguish between packages
>> from different repositories.
>> (latest-release): Rename procedure ...
>> (latest-cran-release): ... to this.
>> (cran-package?): Do not assume all R packages are available on CRAN.
>> * tests/cran.scm: Update tests.
>> * guix/scripts/import/cran.scm: Add "--archive" option and default to
>> CRAN.
>> * guix/scripts/refresh.scm (%updaters): Add "%bioconductor-updater".
>> * doc/guix.texi: Document Bioconductor importer and updater.
>
> [...]
>
>> +Information is extracted from a package's DESCRIPTION file published on
>
> @file{DESCRIPTION}
>
> Apart from that, OK to push!

Fixed that and pushed.  Thank you for the review and your patience!

~~ Ricardo

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2016-01-20 11:43 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-12-17 11:34 [PATCH] Add Bioconductor importer and updater Ricardo Wurmus
2015-12-21 16:00 ` Ricardo Wurmus
2015-12-22 22:01   ` Ludovic Courtès
2016-01-06 15:02     ` Ricardo Wurmus
2016-01-06 16:49       ` Ricardo Wurmus
2016-01-10 20:20         ` Ludovic Courtès
2016-01-20 11:43           ` Ricardo Wurmus
2016-01-07 18:08       ` Ludovic Courtès
2016-01-07 18:29         ` Ricardo Wurmus

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/guix.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).