aboutsummaryrefslogtreecommitdiff
path: root/guix
diff options
context:
space:
mode:
Diffstat (limited to 'guix')
-rw-r--r--guix/build-system/gnu.scm51
-rw-r--r--guix/build-system/python.scm89
-rw-r--r--guix/build/bournish.scm11
-rw-r--r--guix/build/r-build-system.scm3
-rw-r--r--guix/combinators.scm18
-rw-r--r--guix/derivations.scm89
-rw-r--r--guix/download.scm43
-rw-r--r--guix/gnu-maintenance.scm111
-rw-r--r--guix/import/cran.scm4
-rw-r--r--guix/import/elpa.scm3
-rw-r--r--guix/import/github.scm5
-rw-r--r--guix/import/pypi.scm6
-rw-r--r--guix/memoization.scm114
-rw-r--r--guix/modules.scm25
-rw-r--r--guix/packages.scm70
-rw-r--r--guix/scripts/build.scm1
-rw-r--r--guix/scripts/copy.scm4
-rw-r--r--guix/scripts/environment.scm3
-rw-r--r--guix/scripts/graph.scm15
-rw-r--r--guix/scripts/lint.scm15
-rw-r--r--guix/serialization.scm12
-rw-r--r--guix/store.scm37
-rw-r--r--guix/utils.scm11
23 files changed, 444 insertions, 296 deletions
diff --git a/guix/build-system/gnu.scm b/guix/build-system/gnu.scm
index f6df183da4..730e638c89 100644
--- a/guix/build-system/gnu.scm
+++ b/guix/build-system/gnu.scm
@@ -1,5 +1,5 @@
;;; GNU Guix --- Functional package management for GNU
-;;; Copyright © 2012, 2013, 2014, 2015, 2016 Ludovic Courtès <ludo@gnu.org>
+;;; Copyright © 2012, 2013, 2014, 2015, 2016, 2017 Ludovic Courtès <ludo@gnu.org>
;;;
;;; This file is part of GNU Guix.
;;;
@@ -19,7 +19,7 @@
(define-module (guix build-system gnu)
#:use-module (guix store)
#:use-module (guix utils)
- #:use-module (guix combinators)
+ #:use-module (guix memoization)
#:use-module (guix derivations)
#:use-module (guix search-paths)
#:use-module (guix build-system)
@@ -84,15 +84,15 @@ builder, or the distro's final Guile when GUILE is #f."
(let loop ((p p))
(define rewritten-input
- (memoize
- (match-lambda
- ((name (? package? p) sub-drv ...)
- ;; XXX: Check whether P's build system knows #:implicit-inputs, for
- ;; things like `cross-pkg-config'.
- (if (eq? (package-build-system p) gnu-build-system)
- (cons* name (loop p) sub-drv)
- (cons* name p sub-drv)))
- (x x))))
+ (mlambda (input)
+ (match input
+ ((name (? package? p) sub-drv ...)
+ ;; XXX: Check whether P's build system knows #:implicit-inputs, for
+ ;; things like `cross-pkg-config'.
+ (if (eq? (package-build-system p) gnu-build-system)
+ (cons* name (loop p) sub-drv)
+ (cons* name p sub-drv)))
+ (x x))))
(package (inherit p)
(location (if (pair? loc) (source-properties->location loc) loc))
@@ -393,22 +393,21 @@ packages that must not be referenced."
;;;
(define standard-cross-packages
- (memoize
- (lambda (target kind)
- "Return the list of name/package tuples to cross-build for TARGET. KIND
+ (mlambda (target kind)
+ "Return the list of name/package tuples to cross-build for TARGET. KIND
is one of `host' or `target'."
- (let* ((cross (resolve-interface '(gnu packages cross-base)))
- (gcc (module-ref cross 'cross-gcc))
- (binutils (module-ref cross 'cross-binutils))
- (libc (module-ref cross 'cross-libc)))
- (case kind
- ((host)
- `(("cross-gcc" ,(gcc target
- (binutils target)
- (libc target)))
- ("cross-binutils" ,(binutils target))))
- ((target)
- `(("cross-libc" ,(libc target)))))))))
+ (let* ((cross (resolve-interface '(gnu packages cross-base)))
+ (gcc (module-ref cross 'cross-gcc))
+ (binutils (module-ref cross 'cross-binutils))
+ (libc (module-ref cross 'cross-libc)))
+ (case kind
+ ((host)
+ `(("cross-gcc" ,(gcc target
+ (binutils target)
+ (libc target)))
+ ("cross-binutils" ,(binutils target))))
+ ((target)
+ `(("cross-libc" ,(libc target))))))))
(define* (gnu-cross-build store name
#:key
diff --git a/guix/build-system/python.scm b/guix/build-system/python.scm
index d4d3d28f2a..17173f121e 100644
--- a/guix/build-system/python.scm
+++ b/guix/build-system/python.scm
@@ -1,5 +1,5 @@
;;; GNU Guix --- Functional package management for GNU
-;;; Copyright © 2013, 2014, 2015, 2016 Ludovic Courtès <ludo@gnu.org>
+;;; Copyright © 2013, 2014, 2015, 2016, 2017 Ludovic Courtès <ludo@gnu.org>
;;; Copyright © 2013 Andreas Enge <andreas@enge.fr>
;;; Copyright © 2013 Nikita Karetnikov <nikita@karetnikov.org>
;;;
@@ -21,7 +21,7 @@
(define-module (guix build-system python)
#:use-module (guix store)
#:use-module (guix utils)
- #:use-module (guix combinators)
+ #:use-module (guix memoization)
#:use-module (guix packages)
#:use-module (guix derivations)
#:use-module (guix search-paths)
@@ -87,49 +87,48 @@ pre-defined variants."
;; Memoize the transformations. Failing to do that, we would build a huge
;; object graph with lots of duplicates, which in turns prevents us from
;; benefiting from memoization in 'package-derivation'.
- (memoize ;FIXME: use 'eq?'
- (lambda (p)
- (let* ((rewrite-if-package
- (lambda (content)
- ;; CONTENT may be a file name, in which case it is returned,
- ;; or a package, which is rewritten with the new PYTHON and
- ;; NEW-PREFIX.
- (if (package? content)
- (transform content)
- content)))
- (rewrite
- (match-lambda
- ((name content . rest)
- (append (list name (rewrite-if-package content)) rest)))))
-
- (cond
- ;; If VARIANT-PROPERTY is present, use that.
- ((and variant-property
- (assoc-ref (package-properties p) variant-property))
- => force)
-
- ;; Otherwise build the new package object graph.
- ((eq? (package-build-system p) python-build-system)
- (package
- (inherit p)
- (location (package-location p))
- (name (let ((name (package-name p)))
- (string-append new-prefix
- (if (string-prefix? old-prefix name)
- (substring name
- (string-length old-prefix))
- name))))
- (arguments
- (let ((python (if (promise? python)
- (force python)
- python)))
- (ensure-keyword-arguments (package-arguments p)
- `(#:python ,python))))
- (inputs (map rewrite (package-inputs p)))
- (propagated-inputs (map rewrite (package-propagated-inputs p)))
- (native-inputs (map rewrite (package-native-inputs p)))))
- (else
- p))))))
+ (mlambdaq (p)
+ (let* ((rewrite-if-package
+ (lambda (content)
+ ;; CONTENT may be a file name, in which case it is returned,
+ ;; or a package, which is rewritten with the new PYTHON and
+ ;; NEW-PREFIX.
+ (if (package? content)
+ (transform content)
+ content)))
+ (rewrite
+ (match-lambda
+ ((name content . rest)
+ (append (list name (rewrite-if-package content)) rest)))))
+
+ (cond
+ ;; If VARIANT-PROPERTY is present, use that.
+ ((and variant-property
+ (assoc-ref (package-properties p) variant-property))
+ => force)
+
+ ;; Otherwise build the new package object graph.
+ ((eq? (package-build-system p) python-build-system)
+ (package
+ (inherit p)
+ (location (package-location p))
+ (name (let ((name (package-name p)))
+ (string-append new-prefix
+ (if (string-prefix? old-prefix name)
+ (substring name
+ (string-length old-prefix))
+ name))))
+ (arguments
+ (let ((python (if (promise? python)
+ (force python)
+ python)))
+ (ensure-keyword-arguments (package-arguments p)
+ `(#:python ,python))))
+ (inputs (map rewrite (package-inputs p)))
+ (propagated-inputs (map rewrite (package-propagated-inputs p)))
+ (native-inputs (map rewrite (package-native-inputs p)))))
+ (else
+ p)))))
transform)
diff --git a/guix/build/bournish.scm b/guix/build/bournish.scm
index 51dad17ba7..e948cd03d3 100644
--- a/guix/build/bournish.scm
+++ b/guix/build/bournish.scm
@@ -1,6 +1,7 @@
;;; GNU Guix --- Functional package management for GNU
;;; Copyright © 2016 Ludovic Courtès <ludo@gnu.org>
;;; Copyright © 2016 Efraim Flashner <efraim@flashner.co.il>
+;;; Copyright © 2017 Ricardo Wurmus <rekado@elephly.net>
;;;
;;; This file is part of GNU Guix.
;;;
@@ -105,6 +106,14 @@ characters."
((@ (guix build utils) dump-port) port (current-output-port))
*unspecified*)))
+(define (rm-command . args)
+ "Emit code for the 'rm' command."
+ (cond ((member "-r" args)
+ `(for-each (@ (guix build utils) delete-file-recursively)
+ (list ,@(delete "-r" args))))
+ (else
+ `(for-each delete-file (list ,@args)))))
+
(define (lines+chars port)
"Return the number of lines and number of chars read from PORT."
(let loop ((lines 0) (chars 0))
@@ -194,7 +203,7 @@ commands such as 'ls' and 'cd'; it lacks globbing, pipes---everything.\n"))
`(("echo" ,(lambda strings `(list ,@strings)))
("cd" ,(lambda (dir) `(chdir ,dir)))
("pwd" ,(lambda () `(getcwd)))
- ("rm" ,(lambda (file) `(delete-file ,file)))
+ ("rm" ,rm-command)
("cp" ,(lambda (source dest) `(copy-file ,source ,dest)))
("help" ,help-command)
("ls" ,ls-command)
diff --git a/guix/build/r-build-system.scm b/guix/build/r-build-system.scm
index 3fc13eb835..24aa73d4f2 100644
--- a/guix/build/r-build-system.scm
+++ b/guix/build/r-build-system.scm
@@ -1,5 +1,5 @@
;;; GNU Guix --- Functional package management for GNU
-;;; Copyright © 2015 Ricardo Wurmus <rekado@elephly.net>
+;;; Copyright © 2015, 2017 Ricardo Wurmus <rekado@elephly.net>
;;;
;;; This file is part of GNU Guix.
;;;
@@ -84,6 +84,7 @@
(params (append configure-flags
(list "--install-tests"
(string-append "--library=" site-library)
+ "--built-timestamp=1970-01-01"
".")))
(site-path (string-append site-library ":"
(generate-site-path inputs))))
diff --git a/guix/combinators.scm b/guix/combinators.scm
index 9e4689ba9c..11cad62ccf 100644
--- a/guix/combinators.scm
+++ b/guix/combinators.scm
@@ -1,5 +1,5 @@
;;; GNU Guix --- Functional package management for GNU
-;;; Copyright © 2012, 2013, 2014, 2015, 2016 Ludovic Courtès <ludo@gnu.org>
+;;; Copyright © 2012, 2013, 2014, 2015, 2016, 2017 Ludovic Courtès <ludo@gnu.org>
;;; Copyright © 2014 Eric Bavier <bavier@member.fsf.org>
;;;
;;; This file is part of GNU Guix.
@@ -20,8 +20,7 @@
(define-module (guix combinators)
#:use-module (ice-9 match)
#:use-module (ice-9 vlist)
- #:export (memoize
- fold2
+ #:export (fold2
fold-tree
fold-tree-leaves
compile-time-value))
@@ -33,19 +32,6 @@
;;;
;;; Code:
-(define (memoize proc)
- "Return a memoizing version of PROC."
- (let ((cache (make-hash-table)))
- (lambda args
- (let ((results (hash-ref cache args)))
- (if results
- (apply values results)
- (let ((results (call-with-values (lambda ()
- (apply proc args))
- list)))
- (hash-set! cache args results)
- (apply values results)))))))
-
(define fold2
(case-lambda
((proc seed1 seed2 lst)
diff --git a/guix/derivations.scm b/guix/derivations.scm
index b712c508e5..47a783f42f 100644
--- a/guix/derivations.scm
+++ b/guix/derivations.scm
@@ -31,6 +31,7 @@
#:use-module (ice-9 vlist)
#:use-module (guix store)
#:use-module (guix utils)
+ #:use-module (guix memoization)
#:use-module (guix combinators)
#:use-module (guix monads)
#:use-module (guix hash)
@@ -556,12 +557,11 @@ that form."
(display ")" port))))
(define derivation->string
- (memoize
- (lambda (drv)
- "Return the external representation of DRV as a string."
- (with-fluids ((%default-port-encoding "UTF-8"))
- (call-with-output-string
- (cut write-derivation drv <>))))))
+ (mlambda (drv)
+ "Return the external representation of DRV as a string."
+ (with-fluids ((%default-port-encoding "UTF-8"))
+ (call-with-output-string
+ (cut write-derivation drv <>)))))
(define* (derivation->output-path drv #:optional (output "out"))
"Return the store path of its output OUTPUT. Raise a
@@ -583,12 +583,14 @@ DRV."
(define derivation-path->output-path
;; This procedure is called frequently, so memoize it.
- (memoize
- (lambda* (path #:optional (output "out"))
- "Read the derivation from PATH (`/gnu/store/xxx.drv'), and return the store
+ (let ((memoized (mlambda (path output)
+ (derivation->output-path (call-with-input-file path
+ read-derivation)
+ output))))
+ (lambda* (path #:optional (output "out"))
+ "Read the derivation from PATH (`/gnu/store/xxx.drv'), and return the store
path of its output OUTPUT."
- (derivation->output-path (call-with-input-file path read-derivation)
- output))))
+ (memoized path output))))
(define (derivation-path->output-paths path)
"Read the derivation from PATH (`/gnu/store/xxx.drv'), and return the
@@ -615,23 +617,21 @@ in SIZE bytes."
(loop (+ 1 i))))))
(define derivation-path->base16-hash
- (memoize
- (lambda (file)
- "Return a string containing the base16 representation of the hash of the
+ (mlambda (file)
+ "Return a string containing the base16 representation of the hash of the
derivation at FILE."
- (call-with-input-file file
- (compose bytevector->base16-string
- derivation-hash
- read-derivation)))))
+ (call-with-input-file file
+ (compose bytevector->base16-string
+ derivation-hash
+ read-derivation))))
(define derivation-hash ; `hashDerivationModulo' in derivations.cc
- (memoize
- (lambda (drv)
+ (mlambda (drv)
"Return the hash of DRV, modulo its fixed-output inputs, as a bytevector."
(match drv
(($ <derivation> ((_ . ($ <derivation-output> path
- (? symbol? hash-algo) (? bytevector? hash)
- (? boolean? recursive?)))))
+ (? symbol? hash-algo) (? bytevector? hash)
+ (? boolean? recursive?)))))
;; A fixed-output derivation.
(sha256
(string->utf8
@@ -641,14 +641,14 @@ derivation at FILE."
":" (bytevector->base16-string hash)
":" path))))
(($ <derivation> outputs inputs sources
- system builder args env-vars)
+ system builder args env-vars)
;; A regular derivation: replace the path of each input with that
;; input's hash; return the hash of serialization of the resulting
;; derivation.
(let* ((inputs (map (match-lambda
- (($ <derivation-input> path sub-drvs)
- (let ((hash (derivation-path->base16-hash path)))
- (make-derivation-input hash sub-drvs))))
+ (($ <derivation-input> path sub-drvs)
+ (let ((hash (derivation-path->base16-hash path)))
+ (make-derivation-input hash sub-drvs))))
inputs))
(drv (make-derivation outputs
(sort (coalesce-duplicate-inputs inputs)
@@ -661,7 +661,7 @@ derivation at FILE."
;; the SHA256 port's `write' method gets called for every single
;; character.
(sha256
- (string->utf8 (derivation->string drv)))))))))
+ (string->utf8 (derivation->string drv))))))))
(define (store-path type hash name) ; makeStorePath
"Return the store path for NAME/HASH/TYPE."
@@ -915,18 +915,17 @@ recursively."
(define rewritten-input
;; Rewrite the given input according to MAPPING, and return an input
;; in the format used in 'derivation' calls.
- (memoize
- (lambda (input loop)
- (match input
- (($ <derivation-input> path (sub-drvs ...))
- (match (vhash-assoc path mapping)
- ((_ . (? derivation? replacement))
- (cons replacement sub-drvs))
- ((_ . replacement)
- (list replacement))
- (#f
- (let* ((drv (loop (call-with-input-file path read-derivation))))
- (cons drv sub-drvs)))))))))
+ (mlambda (input loop)
+ (match input
+ (($ <derivation-input> path (sub-drvs ...))
+ (match (vhash-assoc path mapping)
+ ((_ . (? derivation? replacement))
+ (cons replacement sub-drvs))
+ ((_ . replacement)
+ (list replacement))
+ (#f
+ (let* ((drv (loop (call-with-input-file path read-derivation))))
+ (cons drv sub-drvs))))))))
(let loop ((drv drv))
(let* ((inputs (map (cut rewritten-input <> loop)
@@ -1057,13 +1056,13 @@ system, imported, and appears under FINAL-PATH in the resulting store path."
(define search-path*
;; A memoizing version of 'search-path' so 'imported-modules' does not end
;; up looking for the same files over and over again.
- (memoize (lambda (path file)
- "Search for FILE in PATH and memoize the result. Raise a
+ (mlambda (path file)
+ "Search for FILE in PATH and memoize the result. Raise a
'&file-search-error' condition if it could not be found."
- (or (search-path path file)
- (raise (condition
- (&file-search-error (file file)
- (path path))))))))
+ (or (search-path path file)
+ (raise (condition
+ (&file-search-error (file file)
+ (path path)))))))
(define (module->source-file-name module)
"Return the file name corresponding to MODULE, a Guile module name (a list
diff --git a/guix/download.scm b/guix/download.scm
index e2e5cee777..813f51f489 100644
--- a/guix/download.scm
+++ b/guix/download.scm
@@ -4,6 +4,7 @@
;;; Copyright © 2015 Federico Beffa <beffa@fbengineering.ch>
;;; Copyright © 2016 Alex Griffin <a@ajgrf.com>
;;; Copyright © 2016 David Craven <david@craven.ch>
+;;; Copyright © 2017 Tobias Geerinckx-Rice <me@tobias.gr>
;;;
;;; This file is part of GNU Guix.
;;;
@@ -35,6 +36,7 @@
#:export (%mirrors
url-fetch
url-fetch/tarbomb
+ url-fetch/zipbomb
download-to-store))
;;; Commentary:
@@ -86,6 +88,7 @@
"http://ftp.belnet.be/ftp.gnome.org/"
"http://ftp.linux.org.uk/mirrors/ftp.gnome.org/"
"http://ftp.gnome.org/pub/GNOME/"
+ "https://download.gnome.org/"
"http://mirror.yandex.ru/mirrors/ftp.gnome.org/")
(hackage
"http://hackage.haskell.org/")
@@ -485,17 +488,24 @@ in the store."
(guile (default-guile)))
"Similar to 'url-fetch' but unpack the file from URL in a directory of its
own. This helper makes it easier to deal with \"tar bombs\"."
+ (define file-name
+ (match url
+ ((head _ ...)
+ (basename head))
+ (_
+ (basename url))))
(define gzip
(module-ref (resolve-interface '(gnu packages compression)) 'gzip))
(define tar
(module-ref (resolve-interface '(gnu packages base)) 'tar))
(mlet %store-monad ((drv (url-fetch url hash-algo hash
- (string-append "tarbomb-" name)
+ (string-append "tarbomb-"
+ (or name file-name))
#:system system
#:guile guile)))
;; Take the tar bomb, and simply unpack it as a directory.
- (gexp->derivation name
+ (gexp->derivation (or name file-name)
#~(begin
(mkdir #$output)
(setenv "PATH" (string-append #$gzip "/bin"))
@@ -504,6 +514,35 @@ own. This helper makes it easier to deal with \"tar bombs\"."
"xf" #$drv)))
#:local-build? #t)))
+(define* (url-fetch/zipbomb url hash-algo hash
+ #:optional name
+ #:key (system (%current-system))
+ (guile (default-guile)))
+ "Similar to 'url-fetch' but unpack the zip file at URL in a directory of its
+own. This helper makes it easier to deal with \"zip bombs\"."
+ (define file-name
+ (match url
+ ((head _ ...)
+ (basename head))
+ (_
+ (basename url))))
+ (define unzip
+ (module-ref (resolve-interface '(gnu packages zip)) 'unzip))
+
+ (mlet %store-monad ((drv (url-fetch url hash-algo hash
+ (string-append "zipbomb-"
+ (or name file-name))
+ #:system system
+ #:guile guile)))
+ ;; Take the zip bomb, and simply unpack it as a directory.
+ (gexp->derivation (or name file-name)
+ #~(begin
+ (mkdir #$output)
+ (chdir #$output)
+ (zero? (system* (string-append #$unzip "/bin/unzip")
+ #$drv)))
+ #:local-build? #t)))
+
(define* (download-to-store store url #:optional (name (basename url))
#:key (log (current-error-port)) recursive?
(verify-certificate? #t))
diff --git a/guix/gnu-maintenance.scm b/guix/gnu-maintenance.scm
index 789724c8c0..07e6909641 100644
--- a/guix/gnu-maintenance.scm
+++ b/guix/gnu-maintenance.scm
@@ -30,7 +30,7 @@
#:use-module (guix http-client)
#:use-module (guix ftp-client)
#:use-module (guix utils)
- #:use-module (guix combinators)
+ #:use-module (guix memoization)
#:use-module (guix records)
#:use-module (guix upstream)
#:use-module (guix packages)
@@ -165,43 +165,48 @@ found."
(official-gnu-packages)))
(define gnu-package?
- (memoize
- (let ((official-gnu-packages (memoize official-gnu-packages)))
- (lambda (package)
- "Return true if PACKAGE is a GNU package. This procedure may access the
+ (let ((official-gnu-packages (memoize official-gnu-packages)))
+ (mlambdaq (package)
+ "Return true if PACKAGE is a GNU package. This procedure may access the
network to check in GNU's database."
- (define (mirror-type url)
- (let ((uri (string->uri url)))
- (and (eq? (uri-scheme uri) 'mirror)
- (cond
- ((member (uri-host uri)
- '("gnu" "gnupg" "gcc" "gnome"))
- ;; Definitely GNU.
- 'gnu)
- ((equal? (uri-host uri) "cran")
- ;; Possibly GNU: mirror://cran could be either GNU R itself
- ;; or a non-GNU package.
- #f)
- (else
- ;; Definitely non-GNU.
- 'non-gnu)))))
-
- (define (gnu-home-page? package)
- (and=> (package-home-page package)
- (lambda (url)
- (and=> (uri-host (string->uri url))
- (lambda (host)
- (member host '("www.gnu.org" "gnu.org")))))))
-
- (or (gnu-home-page? package)
- (let ((url (and=> (package-source package) origin-uri))
- (name (package-name package)))
- (case (and (string? url) (mirror-type url))
- ((gnu) #t)
- ((non-gnu) #f)
- (else
- (and (member name (map gnu-package-name (official-gnu-packages)))
- #t)))))))))
+ (define (mirror-type url)
+ (let ((uri (string->uri url)))
+ (and (eq? (uri-scheme uri) 'mirror)
+ (cond
+ ((member (uri-host uri)
+ '("gnu" "gnupg" "gcc" "gnome"))
+ ;; Definitely GNU.
+ 'gnu)
+ ((equal? (uri-host uri) "cran")
+ ;; Possibly GNU: mirror://cran could be either GNU R itself
+ ;; or a non-GNU package.
+ #f)
+ (else
+ ;; Definitely non-GNU.
+ 'non-gnu)))))
+
+ (define (gnu-home-page? package)
+ (letrec-syntax ((>> (syntax-rules ()
+ ((_ value proc)
+ (and=> value proc))
+ ((_ value proc rest ...)
+ (and=> value
+ (lambda (next)
+ (>> (proc next) rest ...)))))))
+ (>> package package-home-page
+ string->uri uri-host
+ (lambda (host)
+ (member host '("www.gnu.org" "gnu.org"))))))
+
+ (or (gnu-home-page? package)
+ (let ((url (and=> (package-source package) origin-uri))
+ (name (package-upstream-name package)))
+ (case (and (string? url) (mirror-type url))
+ ((gnu) #t)
+ ((non-gnu) #f)
+ (else
+ (and (member name (map gnu-package-name (official-gnu-packages)))
+ #t))))))))
;;;
@@ -210,10 +215,11 @@ network to check in GNU's database."
(define (ftp-server/directory package)
"Return the FTP server and directory where PACKAGE's tarball are stored."
- (values (or (assoc-ref (package-properties package) 'ftp-server)
- "ftp.gnu.org")
- (or (assoc-ref (package-properties package) 'ftp-directory)
- (string-append "/gnu/" (package-name package)))))
+ (let ((name (package-upstream-name package)))
+ (values (or (assoc-ref (package-properties package) 'ftp-server)
+ "ftp.gnu.org")
+ (or (assoc-ref (package-properties package) 'ftp-directory)
+ (string-append "/gnu/" name)))))
(define (sans-extension tarball)
"Return TARBALL without its .tar.* or .zip extension."
@@ -423,11 +429,9 @@ hosted on ftp.gnu.org, or not under that name (this is the case for
\"emacs-auctex\", for instance.)"
(let-values (((server directory)
(ftp-server/directory package)))
- (let ((name (or (assoc-ref (package-properties package) 'upstream-name)
- (package-name package))))
- (false-if-ftp-error (latest-release name
- #:server server
- #:directory directory)))))
+ (false-if-ftp-error (latest-release (package-upstream-name package)
+ #:server server
+ #:directory directory))))
(define %package-name-rx
;; Regexp for a package name, e.g., "foo-X.Y". Since TeXmacs uses
@@ -444,8 +448,10 @@ hosted on ftp.gnu.org, or not under that name (this is the case for
(define (pure-gnu-package? package)
"Return true if PACKAGE is a non-Emacs and non-GNOME GNU package. This
excludes AucTeX, for instance, whose releases are now uploaded to
-elpa.gnu.org, and all the GNOME packages."
- (and (not (string-prefix? "emacs-" (package-name package)))
+elpa.gnu.org, and all the GNOME packages; EMMS is included though, because its
+releases are on gnu.org."
+ (and (or (not (string-prefix? "emacs-" (package-name package)))
+ (gnu-hosted? package))
(not (gnome-package? package))
(gnu-package? package)))
@@ -467,6 +473,9 @@ source URLs starts with PREFIX."
(_ #f)))
(_ #f))))
+(define gnu-hosted?
+ (url-prefix-predicate "mirror://gnu/"))
+
(define gnome-package?
(url-prefix-predicate "mirror://gnome/"))
@@ -491,8 +500,7 @@ source URLs starts with PREFIX."
(define upstream-name
;; Some packages like "NetworkManager" have camel-case names.
- (or (assoc-ref (package-properties package) 'upstream-name)
- (package-name package)))
+ (package-upstream-name package))
(false-if-ftp-error
(latest-ftp-release upstream-name
@@ -516,8 +524,7 @@ source URLs starts with PREFIX."
(let ((uri (string->uri (origin-uri (package-source package)))))
(false-if-ftp-error
(latest-ftp-release
- (or (assoc-ref (package-properties package) 'upstream-name)
- (package-name package))
+ (package-upstream-name package)
#:server "mirrors.mit.edu"
#:directory
(string-append "/kde" (dirname (dirname (uri-path uri))))
diff --git a/guix/import/cran.scm b/guix/import/cran.scm
index 463a25514e..40cdea029b 100644
--- a/guix/import/cran.scm
+++ b/guix/import/cran.scm
@@ -1,6 +1,6 @@
;;; GNU Guix --- Functional package management for GNU
;;; Copyright © 2015, 2016 Ricardo Wurmus <rekado@elephly.net>
-;;; Copyright © 2015, 2016 Ludovic Courtès <ludo@gnu.org>
+;;; Copyright © 2015, 2016, 2017 Ludovic Courtès <ludo@gnu.org>
;;;
;;; This file is part of GNU Guix.
;;;
@@ -27,7 +27,7 @@
#:use-module (srfi srfi-41)
#:use-module (ice-9 receive)
#:use-module (web uri)
- #:use-module (guix combinators)
+ #:use-module (guix memoization)
#:use-module (guix http-client)
#:use-module (guix hash)
#:use-module (guix store)
diff --git a/guix/import/elpa.scm b/guix/import/elpa.scm
index 96cf5bbae6..c0b0c415cf 100644
--- a/guix/import/elpa.scm
+++ b/guix/import/elpa.scm
@@ -1,6 +1,6 @@
;;; GNU Guix --- Functional package management for GNU
;;; Copyright © 2015 Federico Beffa <beffa@fbengineering.ch>
-;;; Copyright © 2015, 2016 Ludovic Courtès <ludo@gnu.org>
+;;; Copyright © 2015, 2016, 2017 Ludovic Courtès <ludo@gnu.org>
;;;
;;; This file is part of GNU Guix.
;;;
@@ -35,7 +35,6 @@
#:use-module (guix base32)
#:use-module (guix upstream)
#:use-module (guix packages)
- #:use-module ((guix combinators) #:select (memoize))
#:use-module ((guix utils) #:select (call-with-temporary-output-file))
#:export (elpa->guix-package
%elpa-updater))
diff --git a/guix/import/github.scm b/guix/import/github.scm
index 1e0bb53d9a..b249b39067 100644
--- a/guix/import/github.scm
+++ b/guix/import/github.scm
@@ -49,7 +49,8 @@
"Return the extension of the archive e.g. '.tar.gz' given a URL, or
false if none is recognized"
(find (lambda (x) (string-suffix? x url))
- (list ".tar.gz" ".tar.bz2" ".tar.xz" ".zip" ".tar" ".tgz" ".love")))
+ (list ".tar.gz" ".tar.bz2" ".tar.xz" ".zip" ".tar"
+ ".tgz" ".tbz" ".love")))
(define (updated-github-url old-package new-version)
;; Return a url for the OLD-PACKAGE with NEW-VERSION. If no source url in
@@ -57,7 +58,7 @@ false if none is recognized"
(define (updated-url url)
(if (string-prefix? "https://github.com/" url)
- (let ((ext (find-extension url))
+ (let ((ext (or (find-extension url) ""))
(name (package-name old-package))
(version (package-version old-package))
(prefix (string-append "https://github.com/"
diff --git a/guix/import/pypi.scm b/guix/import/pypi.scm
index 7cce0fc594..ed0d4297a4 100644
--- a/guix/import/pypi.scm
+++ b/guix/import/pypi.scm
@@ -227,10 +227,8 @@ name/variable pairs describing the required inputs of this package."
(sort
(map (lambda (input)
(list input (list 'unquote (string->symbol input))))
- (append '("python-setuptools")
- ;; Argparse has been part of Python since 2.7.
- (remove (cut string=? "python-argparse" <>)
- (guess-requirements source-url wheel-url tarball))))
+ (remove (cut string=? "python-argparse" <>)
+ (guess-requirements source-url wheel-url tarball)))
(lambda args
(match args
(((a _ ...) (b _ ...))
diff --git a/guix/memoization.scm b/guix/memoization.scm
new file mode 100644
index 0000000000..d64f60fe9c
--- /dev/null
+++ b/guix/memoization.scm
@@ -0,0 +1,114 @@
+;;; GNU Guix --- Functional package management for GNU
+;;; Copyright © 2017 Ludovic Courtès <ludo@gnu.org>
+;;;
+;;; 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 memoization)
+ #:export (memoize
+ mlambda
+ mlambdaq))
+
+(define-syntax-rule (call/mv thunk)
+ (call-with-values thunk list))
+(define-syntax-rule (return/mv lst)
+ (apply values lst))
+
+(define-syntax-rule (call/1 thunk)
+ (thunk))
+(define-syntax-rule (return/1 value)
+ value)
+
+(define %nothing ;nothingness
+ (list 'this 'is 'nothing))
+
+(define-syntax define-cache-procedure
+ (syntax-rules ()
+ "Define a procedure NAME that implements a cache using HASH-REF and
+HASH-SET!. Use CALL to invoke the thunk and RETURN to return its value; CALL
+and RETURN are used to distinguish between multiple-value and single-value
+returns."
+ ((_ name hash-ref hash-set! call return)
+ (define (name cache key thunk)
+ "Cache the result of THUNK under KEY in CACHE, or return the
+already-cached result."
+ (let ((results (hash-ref cache key %nothing)))
+ (if (eq? results %nothing)
+ (let ((results (call thunk)))
+ (hash-set! cache key results)
+ (return results))
+ (return results)))))
+ ((_ name hash-ref hash-set!)
+ (define-cache-procedure name hash-ref hash-set!
+ call/mv return/mv))))
+
+(define-cache-procedure cached/mv hash-ref hash-set!)
+(define-cache-procedure cachedq/mv hashq-ref hashq-set!)
+(define-cache-procedure cached hash-ref hash-set! call/1 return/1)
+(define-cache-procedure cachedq hashq-ref hashq-set! call/1 return/1)
+
+(define (memoize proc)
+ "Return a memoizing version of PROC.
+
+This is a generic version of 'mlambda' what works regardless of the arity of
+'proc'. It is more expensive since the argument list is always allocated, and
+the result is returned via (apply values results)."
+ (let ((cache (make-hash-table)))
+ (lambda args
+ (cached/mv cache args
+ (lambda ()
+ (apply proc args))))))
+
+(define-syntax %mlambda
+ (syntax-rules ()
+ "Return a memoizing lambda. This is restricted to procedures that return
+exactly one value."
+ ((_ cached () body ...)
+ ;; The zero-argument case is equivalent to a promise.
+ (let ((result #f) (cached? #f))
+ (lambda ()
+ (unless cached?
+ (set! result (begin body ...))
+ (set! cached? #t))
+ result)))
+
+ ;; Optimize the fixed-arity case such that there's no argument list
+ ;; allocated. XXX: We can't really avoid the closure allocation since
+ ;; Guile 2.0's compiler will always keep it.
+ ((_ cached (arg) body ...) ;one argument
+ (let ((cache (make-hash-table))
+ (proc (lambda (arg) body ...)))
+ (lambda (arg)
+ (cached cache arg (lambda () (proc arg))))))
+ ((_ _ (args ...) body ...) ;two or more arguments
+ (let ((cache (make-hash-table))
+ (proc (lambda (args ...) body ...)))
+ (lambda (args ...)
+ ;; XXX: Always use 'cached', which uses 'equal?', to compare the
+ ;; argument lists.
+ (cached cache (list args ...)
+ (lambda ()
+ (proc args ...))))))))
+
+(define-syntax-rule (mlambda formals body ...)
+ "Define a memoizing lambda. The lambda's arguments are compared with
+'equal?', and BODY is expected to yield a single return value."
+ (%mlambda cached formals body ...))
+
+(define-syntax-rule (mlambdaq formals body ...)
+ "Define a memoizing lambda. If FORMALS lists a single argument, it is
+compared using 'eq?'; otherwise, the argument list is compared using 'equal?'.
+BODY is expected to yield a single return value."
+ (%mlambda cachedq formals body ...))
diff --git a/guix/modules.scm b/guix/modules.scm
index 24f613ff4e..8c63f21a97 100644
--- a/guix/modules.scm
+++ b/guix/modules.scm
@@ -1,5 +1,5 @@
;;; GNU Guix --- Functional package management for GNU
-;;; Copyright © 2016 Ludovic Courtès <ludo@gnu.org>
+;;; Copyright © 2016, 2017 Ludovic Courtès <ludo@gnu.org>
;;;
;;; This file is part of GNU Guix.
;;;
@@ -17,7 +17,7 @@
;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>.
(define-module (guix modules)
- #:use-module ((guix utils) #:select (memoize))
+ #:use-module (guix memoization)
#:use-module (guix sets)
#:use-module (srfi srfi-26)
#:use-module (ice-9 match)
@@ -71,18 +71,17 @@ CLAUSES."
result)))))
(define module-file-dependencies
- (memoize
- (lambda (file)
- "Return the list of the names of modules that the Guile module in FILE
+ (mlambda (file)
+ "Return the list of the names of modules that the Guile module in FILE
depends on."
- (call-with-input-file file
- (lambda (port)
- (match (read port)
- (('define-module name clauses ...)
- (extract-dependencies clauses))
- ;; XXX: R6RS 'library' form is ignored.
- (_
- '())))))))
+ (call-with-input-file file
+ (lambda (port)
+ (match (read port)
+ (('define-module name clauses ...)
+ (extract-dependencies clauses))
+ ;; XXX: R6RS 'library' form is ignored.
+ (_
+ '()))))))
(define (module-name->file-name module)
"Return the file name for MODULE."
diff --git a/guix/packages.scm b/guix/packages.scm
index beb958f156..4bc4b017f4 100644
--- a/guix/packages.scm
+++ b/guix/packages.scm
@@ -1,5 +1,5 @@
;;; GNU Guix --- Functional package management for GNU
-;;; Copyright © 2012, 2013, 2014, 2015, 2016 Ludovic Courtès <ludo@gnu.org>
+;;; Copyright © 2012, 2013, 2014, 2015, 2016, 2017 Ludovic Courtès <ludo@gnu.org>
;;; Copyright © 2014, 2015 Mark H Weaver <mhw@netris.org>
;;; Copyright © 2015 Eric Bavier <bavier@member.fsf.org>
;;; Copyright © 2016 Alex Kost <alezost@gmail.com>
@@ -28,6 +28,7 @@
#:use-module (guix base32)
#:use-module (guix grafts)
#:use-module (guix derivations)
+ #:use-module (guix memoization)
#:use-module (guix build-system)
#:use-module (guix search-paths)
#:use-module (guix gexp)
@@ -62,6 +63,7 @@
package
package?
package-name
+ package-upstream-name
package-version
package-full-name
package-source
@@ -296,6 +298,12 @@ name of its URI."
package)
16)))))
+(define (package-upstream-name package)
+ "Return the upstream name of PACKAGE, which could be different from the name
+it has in Guix."
+ (or (assq-ref (package-properties package) 'upstream-name)
+ (package-name package)))
+
(define (hidden-package p)
"Return a \"hidden\" version of P--i.e., one that 'fold-packages' and thus,
user interfaces, ignores."
@@ -690,38 +698,19 @@ in INPUTS and their transitive propagated inputs."
`(assoc-ref ,alist ,(label input)))
(transitive-inputs inputs)))
-(define-syntax define-memoized/v
- (lambda (form)
- "Define a memoized single-valued unary procedure with docstring.
-The procedure argument is compared to cached keys using `eqv?'."
- (syntax-case form ()
- ((_ (proc arg) docstring body body* ...)
- (string? (syntax->datum #'docstring))
- #'(define proc
- (let ((cache (make-hash-table)))
- (define (proc arg)
- docstring
- (match (hashv-get-handle cache arg)
- ((_ . value)
- value)
- (_
- (let ((result (let () body body* ...)))
- (hashv-set! cache arg result)
- result))))
- proc))))))
-
-(define-memoized/v (package-transitive-supported-systems package)
- "Return the intersection of the systems supported by PACKAGE and those
+(define package-transitive-supported-systems
+ (mlambdaq (package)
+ "Return the intersection of the systems supported by PACKAGE and those
supported by its dependencies."
- (fold (lambda (input systems)
- (match input
- ((label (? package? p) . _)
- (lset-intersection
- string=? systems (package-transitive-supported-systems p)))
- (_
- systems)))
- (package-supported-systems package)
- (bag-direct-inputs (package->bag package))))
+ (fold (lambda (input systems)
+ (match input
+ ((label (? package? p) . _)
+ (lset-intersection
+ string=? systems (package-transitive-supported-systems p)))
+ (_
+ systems)))
+ (package-supported-systems package)
+ (bag-direct-inputs (package->bag package)))))
(define* (supported-package? package #:optional (system (%current-system)))
"Return true if PACKAGE is supported on SYSTEM--i.e., if PACKAGE and all its
@@ -768,14 +757,15 @@ package and returns its new name after rewrite."
(_
input)))
- (define-memoized/v (replace p)
- "Return a variant of P with its inputs rewritten."
- (package
- (inherit p)
- (name (rewrite-name (package-name p)))
- (inputs (map rewrite (package-inputs p)))
- (native-inputs (map rewrite (package-native-inputs p)))
- (propagated-inputs (map rewrite (package-propagated-inputs p)))))
+ (define replace
+ (mlambdaq (p)
+ ;; Return a variant of P with its inputs rewritten.
+ (package
+ (inherit p)
+ (name (rewrite-name (package-name p)))
+ (inputs (map rewrite (package-inputs p)))
+ (native-inputs (map rewrite (package-native-inputs p)))
+ (propagated-inputs (map rewrite (package-propagated-inputs p))))))
replace)
diff --git a/guix/scripts/build.scm b/guix/scripts/build.scm
index d7d71b7ab9..68402fda18 100644
--- a/guix/scripts/build.scm
+++ b/guix/scripts/build.scm
@@ -24,7 +24,6 @@
#:use-module (guix derivations)
#:use-module (guix packages)
#:use-module (guix grafts)
- #:use-module (guix combinators)
;; Use the procedure that destructures "NAME-VERSION" forms.
#:use-module ((guix utils) #:hide (package-name->name+version))
diff --git a/guix/scripts/copy.scm b/guix/scripts/copy.scm
index 9ae204e6c6..624ef73e96 100644
--- a/guix/scripts/copy.scm
+++ b/guix/scripts/copy.scm
@@ -63,8 +63,8 @@ Throw an error on failure."
(match (connect! session)
('ok
- ;; Let the SSH agent authenticate us to the server.
- (match (userauth-agent! session)
+ ;; Use public key authentication, via the SSH agent if it's available.
+ (match (userauth-public-key/auto! session)
('success
session)
(x
diff --git a/guix/scripts/environment.scm b/guix/scripts/environment.scm
index a08367d1b1..8a3a935a10 100644
--- a/guix/scripts/environment.scm
+++ b/guix/scripts/environment.scm
@@ -421,7 +421,8 @@ host file systems to mount inside the container."
;; read-only within the
;; container.
(writable?
- (string=? "/etc/resolv.conf")))))
+ (string=? file
+ "/etc/resolv.conf")))))
%network-configuration-files)
'())
;; Mappings for the union closure of all inputs.
diff --git a/guix/scripts/graph.scm b/guix/scripts/graph.scm
index 79ce503a2e..9804d41929 100644
--- a/guix/scripts/graph.scm
+++ b/guix/scripts/graph.scm
@@ -1,5 +1,5 @@
;;; GNU Guix --- Functional package management for GNU
-;;; Copyright © 2015, 2016 Ludovic Courtès <ludo@gnu.org>
+;;; Copyright © 2015, 2016, 2017 Ludovic Courtès <ludo@gnu.org>
;;;
;;; This file is part of GNU Guix.
;;;
@@ -21,12 +21,12 @@
#:use-module (guix graph)
#:use-module (guix grafts)
#:use-module (guix scripts)
- #:use-module (guix combinators)
#:use-module (guix packages)
#:use-module (guix monads)
#:use-module (guix store)
#:use-module (guix gexp)
#:use-module (guix derivations)
+ #:use-module (guix memoization)
#:use-module ((guix build-system gnu) #:select (standard-packages))
#:use-module (gnu packages)
#:use-module (guix sets)
@@ -191,12 +191,11 @@ Dependencies may include packages, origin, and file names."
%store-monad))))
(define standard-package-set
- (memoize
- (lambda ()
- "Return the set of standard packages provided by GNU-BUILD-SYSTEM."
- (match (standard-packages)
- (((labels packages . output) ...)
- (list->setq packages))))))
+ (mlambda ()
+ "Return the set of standard packages provided by GNU-BUILD-SYSTEM."
+ (match (standard-packages)
+ (((labels packages . output) ...)
+ (list->setq packages)))))
(define (bag-node-edges-sans-bootstrap thing)
"Like 'bag-node-edges', but pretend that the standard packages of
diff --git a/guix/scripts/lint.scm b/guix/scripts/lint.scm
index afc1369ad1..776e7332c5 100644
--- a/guix/scripts/lint.scm
+++ b/guix/scripts/lint.scm
@@ -32,7 +32,7 @@
#:use-module (guix records)
#:use-module (guix ui)
#:use-module (guix utils)
- #:use-module (guix combinators)
+ #:use-module (guix memoization)
#:use-module (guix scripts)
#:use-module (guix gnu-maintenance)
#:use-module (guix monads)
@@ -90,9 +90,9 @@
;; provided MESSAGE.
(let ((loc (or (package-field-location package field)
(package-location package))))
- (format (guix-warning-port) "~a: ~a: ~a~%"
+ (format (guix-warning-port) "~a: ~a@~a: ~a~%"
(location->string loc)
- (package-full-name package)
+ (package-name package) (package-version package)
message)))
(define (call-with-accumulated-warnings thunk)
@@ -559,12 +559,11 @@ patch could not be found."
str)))
(define official-gnu-packages*
- (memoize
- (lambda ()
- "A memoizing version of 'official-gnu-packages' that returns the empty
+ (mlambda ()
+ "A memoizing version of 'official-gnu-packages' that returns the empty
list when something goes wrong, such as a networking issue."
- (let ((gnus (false-if-exception (official-gnu-packages))))
- (or gnus '())))))
+ (let ((gnus (false-if-exception (official-gnu-packages))))
+ (or gnus '()))))
(define (check-gnu-synopsis+description package)
"Make sure that, if PACKAGE is a GNU package, it uses the synopsis and
diff --git a/guix/serialization.scm b/guix/serialization.scm
index 5953b84616..4cab5910f7 100644
--- a/guix/serialization.scm
+++ b/guix/serialization.scm
@@ -1,5 +1,5 @@
;;; GNU Guix --- Functional package management for GNU
-;;; Copyright © 2012, 2013, 2014, 2015, 2016 Ludovic Courtès <ludo@gnu.org>
+;;; Copyright © 2012, 2013, 2014, 2015, 2016, 2017 Ludovic Courtès <ludo@gnu.org>
;;;
;;; This file is part of GNU Guix.
;;;
@@ -30,7 +30,7 @@
#:export (write-int read-int
write-long-long read-long-long
write-padding
- write-string
+ write-bytevector write-string
read-string read-latin1-string read-maybe-utf8-string
write-string-list read-string-list
write-string-pairs
@@ -102,15 +102,17 @@
(or (zero? m)
(put-bytevector p zero 0 (- 8 m)))))))
-(define (write-string s p)
- (let* ((s (string->utf8 s))
- (l (bytevector-length s))
+(define (write-bytevector s p)
+ (let* ((l (bytevector-length s))
(m (modulo l 8))
(b (make-bytevector (+ 8 l (if (zero? m) 0 (- 8 m))))))
(bytevector-u32-set! b 0 l (endianness little))
(bytevector-copy! s 0 b 8 l)
(put-bytevector p b)))
+(define (write-string s p)
+ (write-bytevector (string->utf8 s) p))
+
(define (read-byte-string p)
(let* ((len (read-int p))
(m (modulo len 8))
diff --git a/guix/store.scm b/guix/store.scm
index 7152a5556a..cce460f3ce 100644
--- a/guix/store.scm
+++ b/guix/store.scm
@@ -19,7 +19,7 @@
(define-module (guix store)
#:use-module (guix utils)
#:use-module (guix config)
- #:use-module (guix combinators)
+ #:use-module (guix memoization)
#:use-module (guix serialization)
#:use-module (guix monads)
#:autoload (guix base32) (bytevector->base32-string)
@@ -67,6 +67,7 @@
query-path-hash
hash-part->path
query-path-info
+ add-data-to-store
add-text-to-store
add-to-store
build-things
@@ -266,12 +267,15 @@
(path-info deriver hash refs registration-time nar-size)))
(define-syntax write-arg
- (syntax-rules (integer boolean string string-list string-pairs
+ (syntax-rules (integer boolean bytevector
+ string string-list string-pairs
store-path store-path-list base16)
((_ integer arg p)
(write-int arg p))
((_ boolean arg p)
(write-int (if arg 1 0) p))
+ ((_ bytevector arg p)
+ (write-bytevector arg p))
((_ string arg p)
(write-string arg p))
((_ string-list arg p)
@@ -669,25 +673,31 @@ string). Raise an error if no such path exists."
"Return the info (hash, references, etc.) for PATH."
path-info)
-(define add-text-to-store
+(define add-data-to-store
;; A memoizing version of `add-to-store', to avoid repeated RPCs with
;; the very same arguments during a given session.
(let ((add-text-to-store
- (operation (add-text-to-store (string name) (string text)
+ (operation (add-text-to-store (string name) (bytevector text)
(string-list references))
#f
store-path)))
- (lambda* (server name text #:optional (references '()))
- "Add TEXT under file NAME in the store, and return its store path.
+ (lambda* (server name bytes #:optional (references '()))
+ "Add BYTES under file NAME in the store, and return its store path.
REFERENCES is the list of store paths referred to by the resulting store
path."
- (let ((args `(,text ,name ,references))
- (cache (nix-server-add-text-to-store-cache server)))
+ (let* ((args `(,bytes ,name ,references))
+ (cache (nix-server-add-text-to-store-cache server)))
(or (hash-ref cache args)
- (let ((path (add-text-to-store server name text references)))
+ (let ((path (add-text-to-store server name bytes references)))
(hash-set! cache args path)
path))))))
+(define* (add-text-to-store store name text #:optional (references '()))
+ "Add TEXT under file NAME in the store, and return its store path.
+REFERENCES is the list of store paths referred to by the resulting store
+path."
+ (add-data-to-store store name (string->utf8 text) references))
+
(define true
;; Define it once and for all since we use it as a default value for
;; 'add-to-store' and want to make sure two default values are 'eq?' for the
@@ -1282,11 +1292,10 @@ valid inputs."
(define store-regexp*
;; The substituter makes repeated calls to 'store-path-hash-part', hence
;; this optimization.
- (memoize
- (lambda (store)
- "Return a regexp matching a file in STORE."
- (make-regexp (string-append "^" (regexp-quote store)
- "/([0-9a-df-np-sv-z]{32})-([^/]+)$")))))
+ (mlambda (store)
+ "Return a regexp matching a file in STORE."
+ (make-regexp (string-append "^" (regexp-quote store)
+ "/([0-9a-df-np-sv-z]{32})-([^/]+)$"))))
(define (store-path-package-name path)
"Return the package name part of PATH, a file name in the store."
diff --git a/guix/utils.scm b/guix/utils.scm
index ee06e47fe9..72dc0687a4 100644
--- a/guix/utils.scm
+++ b/guix/utils.scm
@@ -33,7 +33,7 @@
#:use-module (ice-9 binary-ports)
#:autoload (rnrs io ports) (make-custom-binary-input-port)
#:use-module ((rnrs bytevectors) #:select (bytevector-u8-set!))
- #:use-module (guix combinators)
+ #:use-module (guix memoization)
#:use-module ((guix build utils) #:select (dump-port))
#:use-module ((guix build syscalls) #:select (mkdtemp! fdatasync))
#:use-module (ice-9 vlist)
@@ -771,11 +771,10 @@ be determined."
(column location-column)) ; 0-indexed column
(define location
- (memoize
- (lambda (file line column)
- "Return the <location> object for the given FILE, LINE, and COLUMN."
- (and line column file
- (make-location file line column)))))
+ (mlambda (file line column)
+ "Return the <location> object for the given FILE, LINE, and COLUMN."
+ (and line column file
+ (make-location file line column))))
(define (source-properties->location loc)
"Return a location object based on the info in LOC, an alist as returned