guix build: Modularize transformation handling.
* guix/scripts/build.scm (options/resolve-packages): Remove. (options->things-to-build, transform-package-source): New procedure. (%transformations): New variable. (options->transformation): New procedure. (options->derivations): Rewrite to use 'options->things-to-build' and 'options->transformation'.
This commit is contained in:
parent
27b91d7851
commit
64ec0e2912
|
@ -383,9 +383,40 @@ must be one of 'package', 'all', or 'transitive'~%")
|
||||||
|
|
||||||
%standard-build-options))
|
%standard-build-options))
|
||||||
|
|
||||||
|
(define (options->things-to-build opts)
|
||||||
|
"Read the arguments from OPTS and return a list of high-level objects to
|
||||||
|
build---packages, gexps, derivations, and so on."
|
||||||
|
(define ensure-list
|
||||||
|
(match-lambda
|
||||||
|
((x ...) x)
|
||||||
|
(x (list x))))
|
||||||
|
|
||||||
|
(append-map (match-lambda
|
||||||
|
(('argument . (? string? spec))
|
||||||
|
(cond ((derivation-path? spec)
|
||||||
|
(list (call-with-input-file spec read-derivation)))
|
||||||
|
((store-path? spec)
|
||||||
|
;; Nothing to do; maybe for --log-file.
|
||||||
|
'())
|
||||||
|
(else
|
||||||
|
(list (specification->package spec)))))
|
||||||
|
(('file . file)
|
||||||
|
(ensure-list (load* file (make-user-module '()))))
|
||||||
|
(('expression . str)
|
||||||
|
(ensure-list (read/eval str)))
|
||||||
|
(('argument . (? derivation? drv))
|
||||||
|
drv)
|
||||||
|
(('argument . (? derivation-path? drv))
|
||||||
|
(list ))
|
||||||
|
(_ '()))
|
||||||
|
opts))
|
||||||
|
|
||||||
(define (options->derivations store opts)
|
(define (options->derivations store opts)
|
||||||
"Given OPTS, the result of 'args-fold', return a list of derivations to
|
"Given OPTS, the result of 'args-fold', return a list of derivations to
|
||||||
build."
|
build."
|
||||||
|
(define transform
|
||||||
|
(options->transformation opts))
|
||||||
|
|
||||||
(define package->derivation
|
(define package->derivation
|
||||||
(match (assoc-ref opts 'target)
|
(match (assoc-ref opts 'target)
|
||||||
(#f package-derivation)
|
(#f package-derivation)
|
||||||
|
@ -393,106 +424,90 @@ build."
|
||||||
(cut package-cross-derivation <> <> triplet <>))))
|
(cut package-cross-derivation <> <> triplet <>))))
|
||||||
|
|
||||||
(define src (assoc-ref opts 'source))
|
(define src (assoc-ref opts 'source))
|
||||||
(define sys (assoc-ref opts 'system))
|
(define system (assoc-ref opts 'system))
|
||||||
(define graft? (assoc-ref opts 'graft?))
|
(define graft? (assoc-ref opts 'graft?))
|
||||||
|
|
||||||
(parameterize ((%graft? graft?))
|
(parameterize ((%graft? graft?))
|
||||||
(let ((opts (options/with-source store
|
(append-map (match-lambda
|
||||||
(options/resolve-packages store opts))))
|
((? package? p)
|
||||||
(concatenate
|
(match src
|
||||||
(filter-map (match-lambda
|
(#f
|
||||||
(('argument . (? package? p))
|
(list (package->derivation store p system)))
|
||||||
(match src
|
(#t
|
||||||
(#f
|
(let ((s (package-source p)))
|
||||||
(list (package->derivation store p sys)))
|
(list (package-source-derivation store s))))
|
||||||
(#t
|
(proc
|
||||||
(let ((s (package-source p)))
|
(map (cut package-source-derivation store <>)
|
||||||
(list (package-source-derivation store s))))
|
(proc p)))))
|
||||||
(proc
|
((? derivation? drv)
|
||||||
(map (cut package-source-derivation store <>)
|
(list drv))
|
||||||
(proc p)))))
|
((? procedure? proc)
|
||||||
(('argument . (? derivation? drv))
|
(list (run-with-store store
|
||||||
(list drv))
|
(mbegin %store-monad
|
||||||
(('argument . (? derivation-path? drv))
|
(set-guile-for-build (default-guile))
|
||||||
(list (call-with-input-file drv read-derivation)))
|
(proc))
|
||||||
(('argument . (? store-path?))
|
#:system system)))
|
||||||
;; Nothing to do; maybe for --log-file.
|
((? gexp? gexp)
|
||||||
#f)
|
(list (run-with-store store
|
||||||
(_ #f))
|
(mbegin %store-monad
|
||||||
opts)))))
|
(set-guile-for-build (default-guile))
|
||||||
|
(gexp->derivation "gexp" gexp
|
||||||
|
#:system system))))))
|
||||||
|
(transform store (options->things-to-build opts)))))
|
||||||
|
|
||||||
(define (options/resolve-packages store opts)
|
(define (transform-package-source sources)
|
||||||
"Return OPTS with package specification strings replaced by actual
|
"Return a transformation procedure that uses replaces package sources with
|
||||||
packages."
|
the matching URIs given in SOURCES."
|
||||||
(define system
|
|
||||||
(or (assoc-ref opts 'system) (%current-system)))
|
|
||||||
|
|
||||||
(define (object->argument obj)
|
|
||||||
(match obj
|
|
||||||
((? package? p)
|
|
||||||
`(argument . ,p))
|
|
||||||
((? procedure? proc)
|
|
||||||
(let ((drv (run-with-store store
|
|
||||||
(mbegin %store-monad
|
|
||||||
(set-guile-for-build (default-guile))
|
|
||||||
(proc))
|
|
||||||
#:system system)))
|
|
||||||
`(argument . ,drv)))
|
|
||||||
((? gexp? gexp)
|
|
||||||
(let ((drv (run-with-store store
|
|
||||||
(mbegin %store-monad
|
|
||||||
(set-guile-for-build (default-guile))
|
|
||||||
(gexp->derivation "gexp" gexp
|
|
||||||
#:system system)))))
|
|
||||||
`(argument . ,drv)))))
|
|
||||||
|
|
||||||
(map (match-lambda
|
|
||||||
(('argument . (? string? spec))
|
|
||||||
(if (store-path? spec)
|
|
||||||
`(argument . ,spec)
|
|
||||||
`(argument . ,(specification->package spec))))
|
|
||||||
(('file . file)
|
|
||||||
(object->argument (load* file (make-user-module '()))))
|
|
||||||
(('expression . str)
|
|
||||||
(object->argument (read/eval str)))
|
|
||||||
(opt opt))
|
|
||||||
opts))
|
|
||||||
|
|
||||||
(define (options/with-source store opts)
|
|
||||||
"Process with 'with-source' options in OPTS, replacing the relevant package
|
|
||||||
arguments with packages that use the specified source."
|
|
||||||
(define new-sources
|
(define new-sources
|
||||||
(filter-map (match-lambda
|
(map (lambda (uri)
|
||||||
(('with-source . uri)
|
(cons (package-name->name+version (basename uri))
|
||||||
(cons (package-name->name+version (basename uri))
|
uri))
|
||||||
uri))
|
sources))
|
||||||
(_ #f))
|
|
||||||
opts))
|
|
||||||
|
|
||||||
(let loop ((opts opts)
|
(lambda (store packages)
|
||||||
(sources new-sources)
|
(let loop ((packages packages)
|
||||||
(result '()))
|
(sources new-sources)
|
||||||
(match opts
|
(result '()))
|
||||||
(()
|
(match packages
|
||||||
(unless (null? sources)
|
(()
|
||||||
(warning (_ "sources do not match any package:~{ ~a~}~%")
|
(unless (null? sources)
|
||||||
(match sources
|
(warning (_ "sources do not match any package:~{ ~a~}~%")
|
||||||
(((name . uri) ...)
|
(match sources
|
||||||
uri))))
|
(((name . uri) ...)
|
||||||
(reverse result))
|
uri))))
|
||||||
((('argument . (? package? p)) tail ...)
|
(reverse result))
|
||||||
(let ((source (assoc-ref sources (package-name p))))
|
(((? package? p) tail ...)
|
||||||
(loop tail
|
(let ((source (assoc-ref sources (package-name p))))
|
||||||
(alist-delete (package-name p) sources)
|
(loop tail
|
||||||
(alist-cons 'argument
|
(alist-delete (package-name p) sources)
|
||||||
(if source
|
(cons (if source
|
||||||
(package-with-source store p source)
|
(package-with-source store p source)
|
||||||
p)
|
p)
|
||||||
result))))
|
result))))
|
||||||
((('with-source . _) tail ...)
|
((thing tail ...)
|
||||||
(loop tail sources result))
|
(loop tail sources result))))))
|
||||||
((head tail ...)
|
|
||||||
(loop tail sources (cons head result))))))
|
(define %transformations
|
||||||
|
;; Transformations that can be applied to things to build. The car is the
|
||||||
|
;; key used in the option alist, and the cdr is the transformation
|
||||||
|
;; procedure; it is called with two arguments: the store, and a list of
|
||||||
|
;; things to build.
|
||||||
|
`((with-source . ,transform-package-source)))
|
||||||
|
|
||||||
|
(define (options->transformation opts)
|
||||||
|
"Return a procedure that, when passed a list of things to build (packages,
|
||||||
|
derivations, etc.), applies the transformations specified by OPTS."
|
||||||
|
(apply compose
|
||||||
|
(map (match-lambda
|
||||||
|
((key . transform)
|
||||||
|
(let ((args (filter-map (match-lambda
|
||||||
|
((k . arg)
|
||||||
|
(and (eq? k key) arg)))
|
||||||
|
opts)))
|
||||||
|
(if (null? args)
|
||||||
|
(lambda (store things) things)
|
||||||
|
(transform args)))))
|
||||||
|
%transformations)))
|
||||||
|
|
||||||
(define (show-build-log store file urls)
|
(define (show-build-log store file urls)
|
||||||
"Show the build log for FILE, falling back to remote logs from URLS if
|
"Show the build log for FILE, falling back to remote logs from URLS if
|
||||||
|
|
Loading…
Reference in New Issue