packages: 'package-mapping' can recurse on implicit inputs.
* guix/packages.scm (build-system-with-package-mapping): New procedure. (package-mapping): Add #:deep? and honor it. * tests/packages.scm ("package-mapping"): Compare the direct inputs of the bag of P0 and that of P1. ("package-mapping, deep"): New test.
This commit is contained in:
parent
f458cfbcc5
commit
ff39361c80
3 changed files with 88 additions and 18 deletions
|
@ -6296,10 +6296,11 @@ A more generic procedure to rewrite a package dependency graph is
|
||||||
@code{package-mapping}: it supports arbitrary changes to nodes in the
|
@code{package-mapping}: it supports arbitrary changes to nodes in the
|
||||||
graph.
|
graph.
|
||||||
|
|
||||||
@deffn {Scheme Procedure} package-mapping @var{proc} [@var{cut?}]
|
@deffn {Scheme Procedure} package-mapping @var{proc} [@var{cut?}] [#:deep? #f]
|
||||||
Return a procedure that, given a package, applies @var{proc} to all the packages
|
Return a procedure that, given a package, applies @var{proc} to all the packages
|
||||||
depended on and returns the resulting package. The procedure stops recursion
|
depended on and returns the resulting package. The procedure stops recursion
|
||||||
when @var{cut?} returns true for a given package.
|
when @var{cut?} returns true for a given package. When @var{deep?} is true, @var{proc} is
|
||||||
|
applied to implicit inputs as well.
|
||||||
@end deffn
|
@end deffn
|
||||||
|
|
||||||
@menu
|
@menu
|
||||||
|
|
|
@ -968,10 +968,31 @@ packages they depend on, recursively."
|
||||||
(vhash-consq package #t visited)
|
(vhash-consq package #t visited)
|
||||||
(fold set-insert closure dependencies))))))))
|
(fold set-insert closure dependencies))))))))
|
||||||
|
|
||||||
(define* (package-mapping proc #:optional (cut? (const #f)))
|
(define (build-system-with-package-mapping bs rewrite)
|
||||||
|
"Return a variant of BS, a build system, that rewrites a bag's inputs by
|
||||||
|
passing them through REWRITE, a procedure that takes an input tuplet and
|
||||||
|
returns a \"rewritten\" input tuplet."
|
||||||
|
(define lower
|
||||||
|
(build-system-lower bs))
|
||||||
|
|
||||||
|
(define (lower* . args)
|
||||||
|
(let ((lowered (apply lower args)))
|
||||||
|
(bag
|
||||||
|
(inherit lowered)
|
||||||
|
(build-inputs (map rewrite (bag-build-inputs lowered)))
|
||||||
|
(host-inputs (map rewrite (bag-host-inputs lowered)))
|
||||||
|
(target-inputs (map rewrite (bag-target-inputs lowered))))))
|
||||||
|
|
||||||
|
(build-system
|
||||||
|
(inherit bs)
|
||||||
|
(lower lower*)))
|
||||||
|
|
||||||
|
(define* (package-mapping proc #:optional (cut? (const #f))
|
||||||
|
#:key deep?)
|
||||||
"Return a procedure that, given a package, applies PROC to all the packages
|
"Return a procedure that, given a package, applies PROC to all the packages
|
||||||
depended on and returns the resulting package. The procedure stops recursion
|
depended on and returns the resulting package. The procedure stops recursion
|
||||||
when CUT? returns true for a given package."
|
when CUT? returns true for a given package. When DEEP? is true, PROC is
|
||||||
|
applied to implicit inputs as well."
|
||||||
(define (rewrite input)
|
(define (rewrite input)
|
||||||
(match input
|
(match input
|
||||||
((label (? package? package) outputs ...)
|
((label (? package? package) outputs ...)
|
||||||
|
@ -980,21 +1001,35 @@ when CUT? returns true for a given package."
|
||||||
(_
|
(_
|
||||||
input)))
|
input)))
|
||||||
|
|
||||||
|
(define mapping-property
|
||||||
|
;; Property indicating whether the package has already been processed.
|
||||||
|
(gensym " package-mapping-done"))
|
||||||
|
|
||||||
(define replace
|
(define replace
|
||||||
(mlambdaq (p)
|
(mlambdaq (p)
|
||||||
|
;; If P is the result of a previous call, return it.
|
||||||
|
(if (assq-ref (package-properties p) mapping-property)
|
||||||
|
p
|
||||||
|
|
||||||
;; Return a variant of P with PROC applied to P and its explicit
|
;; Return a variant of P with PROC applied to P and its explicit
|
||||||
;; dependencies, recursively. Memoize the transformations. Failing to
|
;; dependencies, recursively. Memoize the transformations. Failing
|
||||||
;; do that, we would build a huge object graph with lots of duplicates,
|
;; to do that, we would build a huge object graph with lots of
|
||||||
;; which in turns prevents us from benefiting from memoization in
|
;; duplicates, which in turns prevents us from benefiting from
|
||||||
;; 'package-derivation'.
|
;; memoization in 'package-derivation'.
|
||||||
(let ((p (proc p)))
|
(let ((p (proc p)))
|
||||||
(package
|
(package
|
||||||
(inherit p)
|
(inherit p)
|
||||||
(location (package-location p))
|
(location (package-location p))
|
||||||
|
(build-system (if deep?
|
||||||
|
(build-system-with-package-mapping
|
||||||
|
(package-build-system p) rewrite)
|
||||||
|
(package-build-system p)))
|
||||||
(inputs (map rewrite (package-inputs p)))
|
(inputs (map rewrite (package-inputs p)))
|
||||||
(native-inputs (map rewrite (package-native-inputs p)))
|
(native-inputs (map rewrite (package-native-inputs p)))
|
||||||
(propagated-inputs (map rewrite (package-propagated-inputs p)))
|
(propagated-inputs (map rewrite (package-propagated-inputs p)))
|
||||||
(replacement (and=> (package-replacement p) proc))))))
|
(replacement (and=> (package-replacement p) proc))
|
||||||
|
(properties `((,mapping-property . #t)
|
||||||
|
,@(package-properties p))))))))
|
||||||
|
|
||||||
replace)
|
replace)
|
||||||
|
|
||||||
|
|
|
@ -1172,15 +1172,24 @@
|
||||||
(let* ((dep (dummy-package "chbouib"
|
(let* ((dep (dummy-package "chbouib"
|
||||||
(native-inputs `(("x" ,grep)))))
|
(native-inputs `(("x" ,grep)))))
|
||||||
(p0 (dummy-package "example"
|
(p0 (dummy-package "example"
|
||||||
|
(source 77)
|
||||||
(inputs `(("foo" ,coreutils)
|
(inputs `(("foo" ,coreutils)
|
||||||
("bar" ,grep)
|
("bar" ,grep)
|
||||||
("baz" ,dep)))))
|
("baz" ,dep)))))
|
||||||
(transform (lambda (p)
|
(transform (lambda (p)
|
||||||
(package (inherit p) (source 42))))
|
(package (inherit p) (source 42))))
|
||||||
(rewrite (package-mapping transform))
|
(rewrite (package-mapping transform))
|
||||||
(p1 (rewrite p0)))
|
(p1 (rewrite p0))
|
||||||
|
(bag0 (package->bag p0))
|
||||||
|
(bag1 (package->bag p1)))
|
||||||
(and (eq? p1 (rewrite p0))
|
(and (eq? p1 (rewrite p0))
|
||||||
(eqv? 42 (package-source p1))
|
(eqv? 42 (package-source p1))
|
||||||
|
|
||||||
|
;; Implicit inputs should be left unchanged (skip "source", "foo",
|
||||||
|
;; "bar", and "baz" in this comparison).
|
||||||
|
(equal? (drop (bag-direct-inputs bag0) 4)
|
||||||
|
(drop (bag-direct-inputs bag1) 4))
|
||||||
|
|
||||||
(match (package-inputs p1)
|
(match (package-inputs p1)
|
||||||
((("foo" dep1) ("bar" dep2) ("baz" dep3))
|
((("foo" dep1) ("bar" dep2) ("baz" dep3))
|
||||||
(and (eq? dep1 (rewrite coreutils)) ;memoization
|
(and (eq? dep1 (rewrite coreutils)) ;memoization
|
||||||
|
@ -1194,6 +1203,31 @@
|
||||||
(and (eq? dep (rewrite grep))
|
(and (eq? dep (rewrite grep))
|
||||||
(package-source dep))))))))))
|
(package-source dep))))))))))
|
||||||
|
|
||||||
|
(test-equal "package-mapping, deep"
|
||||||
|
'(42)
|
||||||
|
(let* ((p0 (dummy-package "example"
|
||||||
|
(inputs `(("foo" ,coreutils)
|
||||||
|
("bar" ,grep)))))
|
||||||
|
(transform (lambda (p)
|
||||||
|
(package (inherit p) (source 42))))
|
||||||
|
(rewrite (package-mapping transform #:deep? #t))
|
||||||
|
(p1 (rewrite p0))
|
||||||
|
(bag (package->bag p1)))
|
||||||
|
(and (eq? p1 (rewrite p0))
|
||||||
|
(match (bag-direct-inputs bag)
|
||||||
|
((("source" 42) ("foo" dep1) ("bar" dep2) rest ..1)
|
||||||
|
(and (eq? dep1 (rewrite coreutils)) ;memoization
|
||||||
|
(eq? dep2 (rewrite grep))
|
||||||
|
(= 42 (package-source dep1))
|
||||||
|
(= 42 (package-source dep2))
|
||||||
|
|
||||||
|
;; Check that implicit inputs of P0 also got rewritten.
|
||||||
|
(delete-duplicates
|
||||||
|
(map (match-lambda
|
||||||
|
((_ package . _)
|
||||||
|
(package-source package)))
|
||||||
|
rest))))))))
|
||||||
|
|
||||||
(test-assert "package-input-rewriting"
|
(test-assert "package-input-rewriting"
|
||||||
(let* ((dep (dummy-package "chbouib"
|
(let* ((dep (dummy-package "chbouib"
|
||||||
(native-inputs `(("x" ,grep)))))
|
(native-inputs `(("x" ,grep)))))
|
||||||
|
|
Reference in a new issue