summaryrefslogtreecommitdiff
path: root/guix/import/utils.scm
diff options
context:
space:
mode:
authorOleg Pykhalov <go.wigust@gmail.com>2018-06-08 13:46:43 +0300
committerOleg Pykhalov <go.wigust@gmail.com>2018-06-08 14:58:33 +0300
commitae9e5d6602544390fa5da0a87450405ebba012fd (patch)
treeb5ad93d8cac6f4ec639aa7744c0a660189568f06 /guix/import/utils.scm
parent0b2fd1600fa719ab537f4fa57fc021d233a752e8 (diff)
downloadguix-patches-ae9e5d6602544390fa5da0a87450405ebba012fd.tar
guix-patches-ae9e5d6602544390fa5da0a87450405ebba012fd.tar.gz
import: utils: Add recursive-import.
* guix/import/cran.scm (cran-guix-name, cran-recursive-import): New procedures. (recursive-import): Remove procedure. * guix/import/utils.scm (guix-name, recursive-import): New procedures. * guix/scripts/import/cran.scm (guix-import-cran): Use 'cran-recursive-import' procedure.
Diffstat (limited to 'guix/import/utils.scm')
-rw-r--r--guix/import/utils.scm77
1 files changed, 76 insertions, 1 deletions
diff --git a/guix/import/utils.scm b/guix/import/utils.scm
index efc6169077..df85904c6f 100644
--- a/guix/import/utils.scm
+++ b/guix/import/utils.scm
@@ -3,6 +3,7 @@
;;; Copyright © 2016 Jelle Licht <jlicht@fsfe.org>
;;; Copyright © 2016 David Craven <david@craven.ch>
;;; Copyright © 2017 Ricardo Wurmus <rekado@elephly.net>
+;;; Copyright © 2018 Oleg Pykhalov <go.wigust@gmail.com>
;;;
;;; This file is part of GNU Guix.
;;;
@@ -39,6 +40,8 @@
#:use-module (ice-9 regex)
#:use-module (srfi srfi-1)
#:use-module (srfi srfi-11)
+ #:use-module (srfi srfi-26)
+ #:use-module (srfi srfi-41)
#:export (factorize-uri
hash-table->alist
@@ -61,7 +64,11 @@
alist->package
read-lines
- chunk-lines))
+ chunk-lines
+
+ guix-name
+
+ recursive-import))
(define (factorize-uri uri version)
"Factorize URI, a package tarball URI as a string, such that any occurrences
@@ -357,3 +364,71 @@ separated by PRED."
(if (null? after)
(reverse res)
(loop (cdr after) res))))))
+
+(define (guix-name prefix name)
+ "Return a Guix package name for a given package name."
+ (string-append prefix (string-map (match-lambda
+ (#\_ #\-)
+ (#\. #\-)
+ (chr (char-downcase chr)))
+ name)))
+
+(define* (recursive-import package-name repo
+ #:key repo->guix-package guix-name
+ #:allow-other-keys)
+ "Generate a stream of package expressions for PACKAGE-NAME and all its
+dependencies."
+ (receive (package . dependencies)
+ (repo->guix-package package-name repo)
+ (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)
+ (repo->guix-package (next state) repo))
+
+ ;; predicate
+ (negate done?)
+
+ ;; generator: update the queue
+ (lambda (state)
+ (receive (package . dependencies)
+ (repo->guix-package package-name repo)
+ (if package
+ (update state (filter (cut unknown? <>
+ (cons (next state)
+ (imported state)))
+ (car dependencies)))
+ ;; TODO: Try the other archives before giving up
+ (update state (imported state)))))
+
+ ;; initial state
+ (make-state (filter unknown? (car dependencies))
+ (list package-name))))))))