Subject: [PATCH] import: egg: Allow imports of a specific version.
From: Xinglu Chen <[email-masked]>
To: [email-masked]
Date: Mon, 01 Nov 2021 11:55:26 +0100
List-Id: <debbugs-submit.debbugs.gnu.org>

* guix/import/egg.scm (eggs-repository): Change URL.
(egg-metadata): Accept optional #:version keyword argument.
(egg->guix-package): Accept ‘version’ argument.
(egg-recursive-import): Add ‘version’ argument and honor it.
* guix/scripts/import/egg.scm (guix-import-egg): Parse a specification instead
of just a package name.
* doc/guix.texi (Invoking guix import): Document it.
---
 doc/guix.texi               |  8 +++++++-
 guix/import/egg.scm         | 37 ++++++++++++++++++++-----------------
 guix/scripts/import/egg.scm | 34 +++++++++++++++++++---------------
 3 files changed, 46 insertions(+), 33 deletions(-)

diff --git a/doc/guix.texi b/doc/guix.texi
index ea1973f02c..5432612009 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -12166,7 +12166,7 @@
 @cindex egg
 Import metadata for @uref{https://wiki.call-cc.org/eggs, CHICKEN eggs}.
 The information is taken from @file{PACKAGE.egg} files found in the
-@uref{git://code.call-cc.org/eggs-5-latest, eggs-5-latest} Git
+@uref{git://code.call-cc.org/eggs-5-all, eggs-5-all} Git
 repository.  However, it does not provide all the information that we
 need, there is no ``description'' field, and the licenses used are not
 always precise (BSD is often used instead of BSD-N).
@@ -12175,6 +12175,12 @@
 guix import egg sourcehut
 @end example
 
+You can also ask for a specific version
+
+@example
+guix import egg array@@1.0
+@end example
+
 Additional options include:
 @table @code
 @item --recursive
diff --git a/guix/import/egg.scm b/guix/import/egg.scm
index 89e7a9160d..ff9f5a0247 100644
--- a/guix/import/egg.scm
+++ b/guix/import/egg.scm
@@ -51,10 +51,10 @@ (define-module (guix import egg)
 ;;;
 ;;; The following happens under the hood:
 ;;;
-;;; * <git://code.call-cc.org/eggs-5-latest> is a Git repository that contains
-;;;   the latest version of all CHICKEN eggs.  We look clone this repository
-;;;   and retrieve the latest version number, and the PACKAGE.egg file, which
-;;;   contains a list of lists containing metadata about the egg.
+;;; * <git://code.call-cc.org/eggs-5-all> is a Git repository that contains
+;;;   all versions of all CHICKEN eggs.  We look clone this repository and, by
+;;;   default, retrieve the latest version number, and the PACKAGE.egg file,
+;;;   which contains a list of lists containing metadata about the egg.
 ;;;
 ;;; * All the eggs are stored as tarballs at
 ;;;   <https://code.call-cc.org/egg-tarballs/5>, so we grab the tarball for
@@ -96,7 +96,7 @@ (define (egg-name->guix-name name)
 (define (eggs-repository)
   "Update or fetch the latest version of the eggs repository and return the path
 to the repository."
-  (let* ((url "git://code.call-cc.org/eggs-5-latest")
+  (let* ((url "git://code.call-cc.org/eggs-5-all")
          (directory commit _ (update-cached-checkout url)))
     directory))
 
@@ -112,12 +112,13 @@ (define (find-latest-version name)
         (last directory)
         #f)))
 
-(define* (egg-metadata name #:optional file)
-  "Return the package metadata file for the egg NAME, or if FILE is specified,
-return the package metadata in FILE."
+(define* (egg-metadata name #:key (version #f) (file #f))
+  "Return the package metadata file for the egg NAME at version VERSION, or if
+FILE is specified, return the package metadata in FILE."
   (call-with-input-file (or file
                             (string-append (egg-directory name) "/"
-                                           (find-latest-version name)
+                                           (or version
+                                               (find-latest-version name))
                                            "/" name ".egg"))
     read))
 
@@ -173,10 +174,11 @@ (define string->license
 ;;; Egg importer.
 ;;;
 
-(define* (egg->guix-package name #:key (file #f) (source #f))
-  "Import a CHICKEN egg called NAME from either the given .egg FILE, or from
-the latest NAME metadata downloaded from the official repository if FILE is #f.
-Return a <package> record or #f on failure.
+(define* (egg->guix-package name version #:key (file #f) (source #f))
+  "Import a CHICKEN egg called NAME from either the given .egg FILE, or from the
+latest NAME metadata downloaded from the official repository if FILE is #f.
+Return a <package> record or #f on failure.  If VERSION is specified, import
+the particular version from the egg repository.
 
 SOURCE is a ``file-like'' object containing the source code corresponding to
 the egg.  If SOURCE is not specified, the latest tarball for egg NAME will be
@@ -186,8 +188,8 @@ (define* (egg->guix-package name #:key (file #f) (source #f))
 locally.  Note that if FILE and SOURCE are specified, recursive import will
 not work."
   (define egg-content (if file
-                          (egg-metadata name file)
-                          (egg-metadata name)))
+                          (egg-metadata name #:file file)
+                          (egg-metadata name #:version version)))
   (if (not egg-content)
       (values #f '())                    ; egg doesn't exist
       (let* ((version* (or (assoc-ref egg-content 'version)
@@ -326,10 +328,11 @@ (define (maybe-inputs input-type inputs)
 (define egg->guix-package/m                   ;memoized variant
   (memoize egg->guix-package))
 
-(define (egg-recursive-import package-name)
+(define* (egg-recursive-import package-name #:optional version)
   (recursive-import package-name
+                    #:version version
                     #:repo->guix-package (lambda* (name #:key version repo)
-                                           (egg->guix-package/m name))
+                                           (egg->guix-package/m name version))
                     #:guix-name egg-name->guix-name))
 
 
diff --git a/guix/scripts/import/egg.scm b/guix/scripts/import/egg.scm
index 829cdc2ca0..6a9657d12c 100644
--- a/guix/scripts/import/egg.scm
+++ b/guix/scripts/import/egg.scm
@@ -26,6 +26,7 @@ (define-module (guix scripts import egg)
   #:use-module (srfi srfi-1)
   #:use-module (srfi srfi-11)
   #:use-module (srfi srfi-37)
+  #:use-module (srfi srfi-71)
   #:use-module (ice-9 match)
   #:use-module (ice-9 format)
   #:export (guix-import-egg))
@@ -83,21 +84,24 @@ (define (parse-options)
                             (_ #f))
                            (reverse opts))))
     (match args
-      ((package-name)
-       (if (assoc-ref opts 'recursive)
-           ;; Recursive import
-           (map (match-lambda
-                  ((and ('package ('name name) . rest) pkg)
-                   `(define-public ,(string->symbol name)
-                      ,pkg))
-                  (_ #f))
-                (egg-recursive-import package-name))
-           ;; Single import
-           (let ((sexp (egg->guix-package package-name)))
-             (unless sexp
-               (leave (G_ "failed to download meta-data for package '~a'~%")
-                      package-name))
-             sexp)))
+      ((spec)
+       (let ((name version (package-name->name+version spec)))
+         (if (assoc-ref opts 'recursive)
+             ;; Recursive import
+             (map (match-lambda
+                    ((and ('package ('name name) . rest) pkg)
+                     `(define-public ,(string->symbol name)
+                        ,pkg))
+                    (_ #f))
+                  (egg-recursive-import name version))
+             ;; Single import
+             (let ((sexp (egg->guix-package name version)))
+               (unless sexp
+                 (leave (G_ "failed to download meta-data for package '~a'~%")
+                        (if version
+                            (string-append name "@" version)
+                            name)))
+               sexp))))
       (()
        (leave (G_ "too few arguments~%")))
       ((many ...)

base-commit: e1370ea8fa41417bedb437b2fc3a066b19f82c52
-- 
2.33.0