Subject: [PATCH 3/5] import: opam: Add updater.

From: Julien Lepiller <[email-masked]>
Date: Thu, 20 Dec 2018 12:01:01 +0100

* guix/import/opam.scm (%opam-updater): New variable.
---
 guix/import/opam.scm | 59 ++++++++++++++++++++++++++++++++++++++++----
 1 file changed, 54 insertions(+), 5 deletions(-)

diff --git a/guix/import/opam.scm b/guix/import/opam.scm
index cdf05e7d2..b30d28561 100644
--- a/guix/import/opam.scm
+++ b/guix/import/opam.scm
@@ -27,14 +27,19 @@
   #:use-module (srfi srfi-1)
   #:use-module (srfi srfi-2)
   #:use-module (web uri)
+  #:use-module (guix build-system)
+  #:use-module (guix build-system ocaml)
   #:use-module (guix http-client)
   #:use-module (guix git)
   #:use-module (guix ui)
+  #:use-module (guix packages)
+  #:use-module (guix upstream)
   #:use-module (guix utils)
   #:use-module (guix import utils)
   #:use-module ((guix licenses) #:prefix license:)
   #:export (opam->guix-package
-            opam-recursive-import))
+            opam-recursive-import
+            %opam-updater))
 
 ;; Define a PEG parser for the opam format
 (define-peg-pattern SP none (or " " "\n"))
@@ -205,11 +210,17 @@ path to the repository."
       (list dependency (list 'unquote (string->symbol dependency))))
     (ocaml-names->guix-names lst)))
 
-(define (opam->guix-package name)
+(define (opam-fetch name)
   (and-let* ((repository (get-opam-repository))
              (version (find-latest-version name repository))
-             (file (string-append repository "/packages/" name "/" name "." version "/opam"))
-             (opam-content (get-metadata file))
+             (file (string-append repository "/packages/" name "/" name "." version "/opam")))
+    `(("metadata" ,@(get-metadata file))
+      ("version" . ,version))))
+
+(define (opam->guix-package name)
+  (and-let* ((opam-file (opam-fetch name))
+             (version (assoc-ref opam-file "version"))
+             (opam-content (assoc-ref opam-file "metadata"))
              (url-dict (metadata-ref opam-content "url"))
              (source-url (metadata-ref url-dict "src"))
              (requirements (metadata-ref opam-content "depends"))
@@ -222,7 +233,7 @@ path to the repository."
                  (values
                   `(package
                      (name ,(ocaml-name->guix-name name))
-                     (version ,(metadata-ref opam-content "version"))
+                     (version ,version)
                      (source
                        (origin
                          (method url-fetch)
@@ -246,3 +257,41 @@ path to the repository."
                     #:repo->guix-package (lambda (name repo)
                                            (opam->guix-package name))
                     #:guix-name ocaml-name->guix-name))
+
+(define (guix-package->opam-name package)
+  "Given an OCaml PACKAGE built from OPAM, return the name of the
+package in OPAM."
+  (let ((upstream-name (assoc-ref
+                         (package-properties package)
+                         'upstream-name))
+        (name (package-name package)))
+    (cond
+      (upstream-name upstream-name)
+      ((string-prefix? "ocaml-" name) (substring name 6))
+      (else name))))
+
+(define (opam-package? package)
+  "Return true if PACKAGE is an OCaml package from OPAM"
+  (and
+    (equal? (build-system-name (package-build-system package)) 'ocaml)
+    (not (string-prefix? "ocaml4" (package-name package)))))
+
+(define (latest-release package)
+  "Return an <upstream-source> for the latest release of PACKAGE."
+  (and-let* ((opam-name (guix-package->opam-name package))
+             (opam-file (opam-fetch opam-name))
+             (version (assoc-ref opam-file "version"))
+             (opam-content (assoc-ref opam-file "metadata"))
+             (url-dict (metadata-ref opam-content "url"))
+             (source-url (metadata-ref url-dict "src")))
+    (upstream-source
+      (package (package-name package))
+      (version version)
+      (urls (list source-url)))))
+
+(define %opam-updater
+  (upstream-updater
+    (name 'opam)
+    (description "Updater for OPAM packages")
+    (pred opam-package?)
+    (latest latest-release)))
-- 
2.19.2