mirror of
https://git.in.rschanz.org/ryan77627/guix.git
synced 2024-11-07 15:36:20 -05:00
gexp: Implement 'imported-modules' & co. using 'gexp->derivation'.
* guix/derivations.scm (imported-files): Keep private. (%imported-modules, %compiled-modules, build-expression->derivation): Mark as deprecated. (imported-modules, compiled-modules): Remove. * guix/gexp.scm (%mkdir-p-definition): New variable. (imported-files, search-path*, imported-modules, compiled-modules): New procedures. * tests/derivations.scm ("imported-files"): Remove. * tests/gexp.scm ("imported-files", "gexp->derivation #:modules"): New tests.
This commit is contained in:
parent
57a516d3ec
commit
aa72d9afdf
4 changed files with 195 additions and 33 deletions
|
@ -96,11 +96,8 @@ (define-module (guix derivations)
|
||||||
|
|
||||||
build-derivations
|
build-derivations
|
||||||
built-derivations
|
built-derivations
|
||||||
imported-modules
|
|
||||||
compiled-modules
|
|
||||||
|
|
||||||
build-expression->derivation
|
build-expression->derivation)
|
||||||
imported-files)
|
|
||||||
|
|
||||||
;; Re-export it from here for backward compatibility.
|
;; Re-export it from here for backward compatibility.
|
||||||
#:re-export (%guile-for-build))
|
#:re-export (%guile-for-build))
|
||||||
|
@ -942,7 +939,7 @@ (define (parent-directories file-name)
|
||||||
(remove (cut string=? <> ".")
|
(remove (cut string=? <> ".")
|
||||||
(string-tokenize (dirname file-name) not-slash))))))
|
(string-tokenize (dirname file-name) not-slash))))))
|
||||||
|
|
||||||
(define* (imported-files store files
|
(define* (imported-files store files ;deprecated
|
||||||
#:key (name "file-import")
|
#:key (name "file-import")
|
||||||
(system (%current-system))
|
(system (%current-system))
|
||||||
(guile (%guile-for-build)))
|
(guile (%guile-for-build)))
|
||||||
|
@ -982,7 +979,7 @@ (define search-path*
|
||||||
;; up looking for the same files over and over again.
|
;; up looking for the same files over and over again.
|
||||||
(memoize search-path))
|
(memoize search-path))
|
||||||
|
|
||||||
(define* (%imported-modules store modules
|
(define* (%imported-modules store modules ;deprecated
|
||||||
#:key (name "module-import")
|
#:key (name "module-import")
|
||||||
(system (%current-system))
|
(system (%current-system))
|
||||||
(guile (%guile-for-build))
|
(guile (%guile-for-build))
|
||||||
|
@ -1001,7 +998,7 @@ (define* (%imported-modules store modules
|
||||||
(imported-files store files #:name name #:system system
|
(imported-files store files #:name name #:system system
|
||||||
#:guile guile)))
|
#:guile guile)))
|
||||||
|
|
||||||
(define* (%compiled-modules store modules
|
(define* (%compiled-modules store modules ;deprecated
|
||||||
#:key (name "module-import-compiled")
|
#:key (name "module-import-compiled")
|
||||||
(system (%current-system))
|
(system (%current-system))
|
||||||
(guile (%guile-for-build))
|
(guile (%guile-for-build))
|
||||||
|
@ -1124,7 +1121,7 @@ (define add-label
|
||||||
#:outputs output-names
|
#:outputs output-names
|
||||||
#:local-build? #t)))))
|
#:local-build? #t)))))
|
||||||
|
|
||||||
(define* (build-expression->derivation store name exp
|
(define* (build-expression->derivation store name exp ;deprecated
|
||||||
#:key
|
#:key
|
||||||
(system (%current-system))
|
(system (%current-system))
|
||||||
(inputs '())
|
(inputs '())
|
||||||
|
@ -1290,9 +1287,3 @@ (define %build-inputs
|
||||||
|
|
||||||
(define built-derivations
|
(define built-derivations
|
||||||
(store-lift build-derivations))
|
(store-lift build-derivations))
|
||||||
|
|
||||||
(define imported-modules
|
|
||||||
(store-lift %imported-modules))
|
|
||||||
|
|
||||||
(define compiled-modules
|
|
||||||
(store-lift %compiled-modules))
|
|
||||||
|
|
158
guix/gexp.scm
158
guix/gexp.scm
|
@ -21,6 +21,7 @@ (define-module (guix gexp)
|
||||||
#:use-module (guix monads)
|
#:use-module (guix monads)
|
||||||
#:use-module (guix derivations)
|
#:use-module (guix derivations)
|
||||||
#:use-module (guix packages)
|
#:use-module (guix packages)
|
||||||
|
#:use-module (guix utils)
|
||||||
#:use-module (srfi srfi-1)
|
#:use-module (srfi srfi-1)
|
||||||
#:use-module (srfi srfi-9)
|
#:use-module (srfi srfi-9)
|
||||||
#:use-module (srfi srfi-9 gnu)
|
#:use-module (srfi srfi-9 gnu)
|
||||||
|
@ -31,7 +32,10 @@ (define-module (guix gexp)
|
||||||
gexp->derivation
|
gexp->derivation
|
||||||
gexp->file
|
gexp->file
|
||||||
gexp->script
|
gexp->script
|
||||||
text-file*))
|
text-file*
|
||||||
|
imported-files
|
||||||
|
imported-modules
|
||||||
|
compiled-modules))
|
||||||
|
|
||||||
;;; Commentary:
|
;;; Commentary:
|
||||||
;;;
|
;;;
|
||||||
|
@ -500,6 +504,157 @@ (define (substitute-references exp substs)
|
||||||
(lambda #,formals
|
(lambda #,formals
|
||||||
#,sexp)))))))
|
#,sexp)))))))
|
||||||
|
|
||||||
|
|
||||||
|
;;;
|
||||||
|
;;; Module handling.
|
||||||
|
;;;
|
||||||
|
|
||||||
|
(define %mkdir-p-definition
|
||||||
|
;; The code for 'mkdir-p' is copied from (guix build utils). We use it in
|
||||||
|
;; derivations that cannot use the #:modules argument of 'gexp->derivation'
|
||||||
|
;; precisely because they implement that functionality.
|
||||||
|
(gexp
|
||||||
|
(define (mkdir-p dir)
|
||||||
|
(define absolute?
|
||||||
|
(string-prefix? "/" dir))
|
||||||
|
|
||||||
|
(define not-slash
|
||||||
|
(char-set-complement (char-set #\/)))
|
||||||
|
|
||||||
|
(let loop ((components (string-tokenize dir not-slash))
|
||||||
|
(root (if absolute? "" ".")))
|
||||||
|
(match components
|
||||||
|
((head tail ...)
|
||||||
|
(let ((path (string-append root "/" head)))
|
||||||
|
(catch 'system-error
|
||||||
|
(lambda ()
|
||||||
|
(mkdir path)
|
||||||
|
(loop tail path))
|
||||||
|
(lambda args
|
||||||
|
(if (= EEXIST (system-error-errno args))
|
||||||
|
(loop tail path)
|
||||||
|
(apply throw args))))))
|
||||||
|
(() #t))))))
|
||||||
|
|
||||||
|
(define* (imported-files files
|
||||||
|
#:key (name "file-import")
|
||||||
|
(system (%current-system))
|
||||||
|
(guile (%guile-for-build)))
|
||||||
|
"Return a derivation that imports FILES into STORE. FILES must be a list
|
||||||
|
of (FINAL-PATH . FILE-NAME) pairs; each FILE-NAME is read from the file
|
||||||
|
system, imported, and appears under FINAL-PATH in the resulting store path."
|
||||||
|
(define file-pair
|
||||||
|
(match-lambda
|
||||||
|
((final-path . file-name)
|
||||||
|
(mlet %store-monad ((file (interned-file file-name
|
||||||
|
(basename final-path))))
|
||||||
|
(return (list final-path file))))))
|
||||||
|
|
||||||
|
(mlet %store-monad ((files (sequence %store-monad
|
||||||
|
(map file-pair files))))
|
||||||
|
(define build
|
||||||
|
(gexp
|
||||||
|
(begin
|
||||||
|
(use-modules (ice-9 match))
|
||||||
|
|
||||||
|
(ungexp %mkdir-p-definition)
|
||||||
|
|
||||||
|
(mkdir (ungexp output)) (chdir (ungexp output))
|
||||||
|
(for-each (match-lambda
|
||||||
|
((final-path store-path)
|
||||||
|
(mkdir-p (dirname final-path))
|
||||||
|
(symlink store-path final-path)))
|
||||||
|
'(ungexp files)))))
|
||||||
|
|
||||||
|
;; TODO: Pass FILES as an environment variable so that BUILD remains
|
||||||
|
;; exactly the same regardless of FILES: less disk space, and fewer
|
||||||
|
;; 'add-to-store' RPCs.
|
||||||
|
(gexp->derivation name build
|
||||||
|
#:system system
|
||||||
|
#:guile-for-build guile
|
||||||
|
#:local-build? #t)))
|
||||||
|
|
||||||
|
(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 search-path))
|
||||||
|
|
||||||
|
(define* (imported-modules modules
|
||||||
|
#:key (name "module-import")
|
||||||
|
(system (%current-system))
|
||||||
|
(guile (%guile-for-build))
|
||||||
|
(module-path %load-path))
|
||||||
|
"Return a derivation that contains the source files of MODULES, a list of
|
||||||
|
module names such as `(ice-9 q)'. All of MODULES must be in the MODULE-PATH
|
||||||
|
search path."
|
||||||
|
;; TODO: Determine the closure of MODULES, build the `.go' files,
|
||||||
|
;; canonicalize the source files through read/write, etc.
|
||||||
|
(let ((files (map (lambda (m)
|
||||||
|
(let ((f (string-append
|
||||||
|
(string-join (map symbol->string m) "/")
|
||||||
|
".scm")))
|
||||||
|
(cons f (search-path* module-path f))))
|
||||||
|
modules)))
|
||||||
|
(imported-files files #:name name #:system system
|
||||||
|
#:guile guile)))
|
||||||
|
|
||||||
|
(define* (compiled-modules modules
|
||||||
|
#:key (name "module-import-compiled")
|
||||||
|
(system (%current-system))
|
||||||
|
(guile (%guile-for-build))
|
||||||
|
(module-path %load-path))
|
||||||
|
"Return a derivation that builds a tree containing the `.go' files
|
||||||
|
corresponding to MODULES. All the MODULES are built in a context where
|
||||||
|
they can refer to each other."
|
||||||
|
(mlet %store-monad ((modules (imported-modules modules
|
||||||
|
#:system system
|
||||||
|
#:guile guile
|
||||||
|
#:module-path
|
||||||
|
module-path)))
|
||||||
|
(define build
|
||||||
|
(gexp
|
||||||
|
(begin
|
||||||
|
(use-modules (ice-9 ftw)
|
||||||
|
(ice-9 match)
|
||||||
|
(srfi srfi-26)
|
||||||
|
(system base compile))
|
||||||
|
|
||||||
|
(ungexp %mkdir-p-definition)
|
||||||
|
|
||||||
|
(define (regular? file)
|
||||||
|
(not (member file '("." ".."))))
|
||||||
|
|
||||||
|
(define (process-directory directory output)
|
||||||
|
(let ((entries (map (cut string-append directory "/" <>)
|
||||||
|
(scandir directory regular?))))
|
||||||
|
(for-each (lambda (entry)
|
||||||
|
(if (file-is-directory? entry)
|
||||||
|
(let ((output (string-append output "/"
|
||||||
|
(basename entry))))
|
||||||
|
(mkdir-p output)
|
||||||
|
(process-directory entry output))
|
||||||
|
(let* ((base (string-drop-right
|
||||||
|
(basename entry)
|
||||||
|
4)) ;.scm
|
||||||
|
(output (string-append output "/" base
|
||||||
|
".go")))
|
||||||
|
(compile-file entry
|
||||||
|
#:output-file output
|
||||||
|
#:opts
|
||||||
|
%auto-compilation-options))))
|
||||||
|
entries)))
|
||||||
|
|
||||||
|
(set! %load-path (cons (ungexp modules) %load-path))
|
||||||
|
(mkdir (ungexp output))
|
||||||
|
(chdir (ungexp modules))
|
||||||
|
(process-directory "." (ungexp output)))))
|
||||||
|
|
||||||
|
;; TODO: Pass MODULES as an environment variable.
|
||||||
|
(gexp->derivation name build
|
||||||
|
#:system system
|
||||||
|
#:guile-for-build guile
|
||||||
|
#:local-build? #t)))
|
||||||
|
|
||||||
|
|
||||||
;;;
|
;;;
|
||||||
;;; Convenience procedures.
|
;;; Convenience procedures.
|
||||||
|
@ -562,7 +717,6 @@ (define builder
|
||||||
|
|
||||||
(gexp->derivation name builder))
|
(gexp->derivation name builder))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
;;;
|
;;;
|
||||||
;;; Syntactic sugar.
|
;;; Syntactic sugar.
|
||||||
|
|
|
@ -670,23 +670,6 @@ (define %coreutils
|
||||||
(let ((p (derivation->output-path drv)))
|
(let ((p (derivation->output-path drv)))
|
||||||
(string-contains (call-with-input-file p read-line) "GNU")))))
|
(string-contains (call-with-input-file p read-line) "GNU")))))
|
||||||
|
|
||||||
(test-assert "imported-files"
|
|
||||||
(let* ((files `(("x" . ,(search-path %load-path "ice-9/q.scm"))
|
|
||||||
("a/b/c" . ,(search-path %load-path
|
|
||||||
"guix/derivations.scm"))
|
|
||||||
("p/q" . ,(search-path %load-path "guix.scm"))
|
|
||||||
("p/z" . ,(search-path %load-path "guix/store.scm"))))
|
|
||||||
(drv (imported-files %store files)))
|
|
||||||
(and (build-derivations %store (list drv))
|
|
||||||
(let ((dir (derivation->output-path drv)))
|
|
||||||
(every (match-lambda
|
|
||||||
((path . source)
|
|
||||||
(equal? (call-with-input-file (string-append dir "/" path)
|
|
||||||
get-bytevector-all)
|
|
||||||
(call-with-input-file source
|
|
||||||
get-bytevector-all))))
|
|
||||||
files)))))
|
|
||||||
|
|
||||||
(test-assert "build-expression->derivation with modules"
|
(test-assert "build-expression->derivation with modules"
|
||||||
(let* ((builder `(begin
|
(let* ((builder `(begin
|
||||||
(use-modules (guix build utils))
|
(use-modules (guix build utils))
|
||||||
|
|
|
@ -360,6 +360,40 @@ (define (match-input thing)
|
||||||
(string=? (readlink (string-append out "/" two "/one"))
|
(string=? (readlink (string-append out "/" two "/one"))
|
||||||
one)))))))
|
one)))))))
|
||||||
|
|
||||||
|
(test-assertm "imported-files"
|
||||||
|
(mlet* %store-monad
|
||||||
|
((files -> `(("x" . ,(search-path %load-path "ice-9/q.scm"))
|
||||||
|
("a/b/c" . ,(search-path %load-path
|
||||||
|
"guix/derivations.scm"))
|
||||||
|
("p/q" . ,(search-path %load-path "guix.scm"))
|
||||||
|
("p/z" . ,(search-path %load-path "guix/store.scm"))))
|
||||||
|
(drv (imported-files files)))
|
||||||
|
(mbegin %store-monad
|
||||||
|
(built-derivations (list drv))
|
||||||
|
(let ((dir (derivation->output-path drv)))
|
||||||
|
(return
|
||||||
|
(every (match-lambda
|
||||||
|
((path . source)
|
||||||
|
(equal? (call-with-input-file (string-append dir "/" path)
|
||||||
|
get-bytevector-all)
|
||||||
|
(call-with-input-file source
|
||||||
|
get-bytevector-all))))
|
||||||
|
files))))))
|
||||||
|
|
||||||
|
(test-assertm "gexp->derivation #:modules"
|
||||||
|
(mlet* %store-monad
|
||||||
|
((build -> #~(begin
|
||||||
|
(use-modules (guix build utils))
|
||||||
|
(mkdir-p (string-append #$output "/guile/guix/nix"))
|
||||||
|
#t))
|
||||||
|
(drv (gexp->derivation "test-with-modules" build
|
||||||
|
#:modules '((guix build utils)))))
|
||||||
|
(mbegin %store-monad
|
||||||
|
(built-derivations (list drv))
|
||||||
|
(let* ((p (derivation->output-path drv))
|
||||||
|
(s (stat (string-append p "/guile/guix/nix"))))
|
||||||
|
(return (eq? (stat:type s) 'directory))))))
|
||||||
|
|
||||||
(test-assertm "gexp->derivation #:references-graphs"
|
(test-assertm "gexp->derivation #:references-graphs"
|
||||||
(mlet* %store-monad
|
(mlet* %store-monad
|
||||||
((one (text-file "one" "hello, world"))
|
((one (text-file "one" "hello, world"))
|
||||||
|
|
Loading…
Reference in a new issue