emacs-bug-tracker
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[debbugs-tracker] bug#31399: closed ([PATCH] import: elpa: Implement rec


From: GNU bug Tracking System
Subject: [debbugs-tracker] bug#31399: closed ([PATCH] import: elpa: Implement recursive import.)
Date: Fri, 08 Jun 2018 12:09:02 +0000

Your message dated Fri, 08 Jun 2018 15:08:13 +0300
with message-id <address@hidden>
and subject line Re: [bug#31399] [PATCH] import: elpa: Implement recursive 
import.
has caused the debbugs.gnu.org bug report #31399,
regarding [PATCH] import: elpa: Implement recursive import.
to be marked as done.

(If you believe you have received this mail in error, please contact
address@hidden)


-- 
31399: http://debbugs.gnu.org/cgi/bugreport.cgi?bug=31399
GNU Bug Tracking System
Contact address@hidden with problems
--- Begin Message --- Subject: [PATCH] import: elpa: Implement recursive import. Date: Thu, 10 May 2018 11:37:14 +0300
Hello Guix,

I stole recursive importer from ‘cran’ and made it for ‘elpa’, the patch
is attached.  I don't like it and want to share the code with ‘cran’
importer, but I don't know how to do it without increasing complexity.

From 5c5023c5f343d673e96517b822b5e884ff20f714 Mon Sep 17 00:00:00 2001
From: Oleg Pykhalov <address@hidden>
Date: Thu, 10 May 2018 10:07:49 +0300
Subject: [PATCH] import: elpa: Implement recursive import.

* guix/import/elpa.scm (guix-name, recursive-import): New procedures.
* guix/scripts/import/elpa.scm (%options): Add 'recursive-import'.
(guix-import-elpa): Add this.
(show-help): Document this.
* doc/guix.texi (Invoking guix import): Document this.
---
 doc/guix.texi                |  6 +++
 guix/import/elpa.scm         | 81 +++++++++++++++++++++++++++++++++++-
 guix/scripts/import/elpa.scm | 22 ++++++++--
 3 files changed, 104 insertions(+), 5 deletions(-)

diff --git a/doc/guix.texi b/doc/guix.texi
index 8b9f8721b..40d3a4c73 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -6481,6 +6481,12 @@ signatures,, emacs, The GNU Emacs Manual}).
 @uref{http://melpa.org/packages, MELPA}, selected by the @code{melpa}
 identifier.
 @end itemize
+
address@hidden --recursive
address@hidden -r
+Traverse the dependency graph of the given upstream package recursively
+and generate package expressions for all those packages that are not yet
+in Guix.
 @end table
 
 @item crate
diff --git a/guix/import/elpa.scm b/guix/import/elpa.scm
index 43e9eb60c..78a69dcc0 100644
--- a/guix/import/elpa.scm
+++ b/guix/import/elpa.scm
@@ -26,6 +26,8 @@
   #:use-module (srfi srfi-9 gnu)
   #:use-module (srfi srfi-11)
   #:use-module (srfi srfi-26)
+  #:use-module (srfi srfi-41)
+  #:use-module (gnu packages)
   #:use-module ((guix download) #:select (download-to-store))
   #:use-module (guix import utils)
   #:use-module (guix http-client)
@@ -37,7 +39,8 @@
   #:use-module (guix packages)
   #:use-module ((guix utils) #:select (call-with-temporary-output-file))
   #:export (elpa->guix-package
-            %elpa-updater))
+            %elpa-updater
+            recursive-import))
 
 (define (elpa-dependencies->names deps)
   "Convert DEPS, a list of symbol/version pairs à la ELPA, to a list of
@@ -289,4 +292,80 @@ type '<elpa-package>'."
    (pred package-from-gnu.org?)
    (latest latest-release)))
 
+(define (guix-name name)
+  "Return a Guix package name for a given Emacs package name."
+  (string-append "emacs-" (string-map (match-lambda
+                                        (#\_ #\-)
+                                        (#\. #\-)
+                                        (chr (char-downcase chr)))
+                                      name)))
+
+(define* (recursive-import package-name #:optional (repo 'gnu))
+  "Generate a stream of package expressions for PACKAGE-NAME and all its
+dependencies."
+  (define (propagated-inputs package)
+    "Return a list of package names in propagated inputs from PACKAGE."
+    (and=> (match package
+             ((package fields ...) (assq 'propagated-inputs fields))
+             (#f #f))
+           (match-lambda
+               ((propagated-inputs (qp ((package-name package) ...)))
+                (map (cut string-drop <> (string-length "emacs-"))
+                     package-name))
+             (#f #f))))
+  (let* ((package (elpa->guix-package package-name repo))
+         (dependencies (propagated-inputs package)))
+    (if (not package)
+        stream-null
+
+        ;; Generate a lazy stream of package expressions for all unknown
+        ;; dependencies in the graph.
+        (let* ((make-state (lambda (queue done)
+                             (cons queue done)))
+               (next       (match-lambda
+                             (((next . rest) . done) next)))
+               (imported   (match-lambda
+                             ((queue . done) done)))
+               (done?      (match-lambda
+                             ((queue . done)
+                              (zero? (length queue)))))
+               (unknown?   (lambda* (dependency #:optional (done '()))
+                             (and (not (member dependency
+                                               done))
+                                  (null? (find-packages-by-name
+                                          (guix-name dependency))))))
+               (update     (lambda (state new-queue)
+                             (match state
+                               (((head . tail) . done)
+                                (make-state (lset-difference
+                                             equal?
+                                             (lset-union equal? new-queue tail)
+                                             done)
+                                            (cons head done)))))))
+          (stream-cons
+           package
+           (stream-unfold
+            ;; map: produce a stream element
+            (lambda (state)
+              (elpa->guix-package (next state) repo))
+
+            ;; predicate
+            (negate done?)
+
+            ;; generator: update the queue
+            (lambda (state)
+              (let* ((package (elpa->guix-package (next state) repo))
+                     (dependencies (propagated-inputs package)))
+                (if package
+                    (update state (filter (cut unknown? <>
+                                               (cons (next state)
+                                                     (imported state)))
+                                          dependencies))
+                    ;; TODO: Try the other archives before giving up
+                    (update state (imported state)))))
+
+            ;; initial state
+            (make-state (filter unknown? dependencies)
+                        (list package-name))))))))
+
 ;;; elpa.scm ends here
diff --git a/guix/scripts/import/elpa.scm b/guix/scripts/import/elpa.scm
index 34eb16485..c49c3ac9e 100644
--- a/guix/scripts/import/elpa.scm
+++ b/guix/scripts/import/elpa.scm
@@ -25,6 +25,7 @@
   #:use-module (srfi srfi-1)
   #:use-module (srfi srfi-11)
   #:use-module (srfi srfi-37)
+  #:use-module (srfi srfi-41)
   #:use-module (ice-9 match)
   #:use-module (ice-9 format)
   #:export (guix-import-elpa))
@@ -45,6 +46,8 @@ Import the latest package named PACKAGE-NAME from an ELPA 
repository.\n"))
   (display (G_ "
   -h, --help                     display this help and exit"))
   (display (G_ "
+  -r, --recursive                generate package expressions for all Emacs 
packages that are not yet in Guix"))
+  (display (G_ "
   -V, --version                  display version information and exit"))
   (newline)
   (show-bug-report-information))
@@ -62,6 +65,9 @@ Import the latest package named PACKAGE-NAME from an ELPA 
repository.\n"))
                  (lambda (opt name arg result)
                    (alist-cons 'repo (string->symbol arg)
                                (alist-delete 'repo result))))
+         (option '(#\r "recursive") #f #f
+                 (lambda (opt name arg result)
+                   (alist-cons 'recursive #t result)))
          %standard-import-options))
 

@@ -87,10 +93,18 @@ Import the latest package named PACKAGE-NAME from an ELPA 
repository.\n"))
                            (reverse opts))))
     (match args
       ((package-name)
-       (let ((sexp (elpa->guix-package package-name (assoc-ref opts 'repo))))
-         (unless sexp
-           (leave (G_ "failed to download package '~a'~%") package-name))
-         sexp))
+       (if (assoc-ref opts 'recursive)
+           (map (match-lambda
+                  ((and ('package ('name name) . rest) pkg)
+                   `(define-public ,(string->symbol name)
+                      ,pkg))
+                  (_ #f))
+                (reverse (stream->list (recursive-import package-name
+                                                         (or (assoc-ref opts 
'repo) 'cran)))))
+           (let ((sexp (elpa->guix-package package-name (assoc-ref opts 
'repo))))
+             (unless sexp
+               (leave (G_ "failed to download package '~a'~%") package-name))
+             sexp)))
       (()
        (leave (G_ "too few arguments~%")))
       ((many ...)
-- 
2.17.0

Oleg.

Attachment: signature.asc
Description: PGP signature


--- End Message ---
--- Begin Message --- Subject: Re: [bug#31399] [PATCH] import: elpa: Implement recursive import. Date: Fri, 08 Jun 2018 15:08:13 +0300 User-agent: Gnus/5.13 (Gnus v5.13) Emacs/26.1 (gnu/linux)
Hello Ludovic, Guix,

Apologies for a delay.

address@hidden (Ludovic Courtès) writes:

[…]

> I’d find it clearer to have a first patch that moves code from cran.scm
> to utils.scm, and a second patch containing the ELPA changes.  No big
> deal though.

OK, splitted the patch.  Also removed unused srfi-41.

> Please double-check that tests/{elpa,cran}.scm still pass, but if they
> do, I think you can go ahead and push.

I tested both commits separately.  Pushed as:

- 74032da3a2ef3e99e89dd58701414004f5a6c061
- ae9e5d6602544390fa5da0a87450405ebba012fd

While I've tested, ‘test-tmp/db/’ directory was missing in my Guix Git
repository (‘test-tmp’ directory was present), tests failed until I
manually created by invoking ‘mkdir test-tmp/db’.  I've tried to remove
‘test-tmp’, invoke ‘./configure --localstatedir=/var --prefix=’ and
‘make’, but it produced only ‘test-tmp’ directory.

[…]

For the record.

I did some manually tests by commenting package and dependency package
recipes in Guix package collection, then invoked import:

- ‘r-circlize’ which depends ‘r-shape’
--8<---------------cut here---------------start------------->8---
./pre-inst-env env GUIX_PACKAGE_PATH= guix import cran -r circlize
--8<---------------cut here---------------end--------------->8---

- ‘emacs-xelb’ which depends on ‘emacs-exwm’
--8<---------------cut here---------------start------------->8---
./pre-inst-env env GUIX_PACKAGE_PATH= guix import elpa -r exwm
--8<---------------cut here---------------end--------------->8---

- ‘emacs-ace-window’ which depends on ‘emacs-avy’
--8<---------------cut here---------------start------------->8---
./pre-inst-env env GUIX_PACKAGE_PATH= guix import elpa -a melpa -r ace-window
--8<---------------cut here---------------end--------------->8---

Thanks,
Oleg.

Attachment: signature.asc
Description: PGP signature


--- End Message ---

reply via email to

[Prev in Thread] Current Thread [Next in Thread]