summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLudovic Courtès <ludo@gnu.org>2017-04-05 15:19:15 +0200
committerLudovic Courtès <ludo@gnu.org>2017-04-05 22:45:41 +0200
commitf37f2b83fa95c1fe2bf01c4b8072cfc23d4c67ec (patch)
treebed6bac6a29ee4575fdbf34604bd380f0d5c2ff7
parent79f912c7106131f4179c727583d33500271361cd (diff)
packages: Add 'package-mapping' and base 'package-input-rewriting' on it.
* guix/packages.scm (package-mapping): New procedure. (package-input-rewriting): Rewrite in terms of 'package-mapping'. * tests/packages.scm ("package-mapping"): New test. * doc/guix.texi (Defining Packages): Document it.
-rw-r--r--doc/guix.texi10
-rw-r--r--guix/packages.scm56
-rw-r--r--tests/packages.scm27
3 files changed, 74 insertions, 19 deletions
diff --git a/doc/guix.texi b/doc/guix.texi
index aa779e38e2e..b2498d039ef 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -2946,6 +2946,16 @@ with @var{libressl}. Then we use it to define a @dfn{variant} of the
2946This is exactly what the @option{--with-input} command-line option does 2946This is exactly what the @option{--with-input} command-line option does
2947(@pxref{Package Transformation Options, @option{--with-input}}). 2947(@pxref{Package Transformation Options, @option{--with-input}}).
2948 2948
2949A more generic procedure to rewrite a package dependency graph is
2950@code{package-mapping}: it supports arbitrary changes to nodes in the
2951graph.
2952
2953@deffn {Scheme Procedure} package-mapping @var{proc} [@var{cut?}]
2954Return a procedure that, given a package, applies @var{proc} to all the packages
2955depended on and returns the resulting package. The procedure stops recursion
2956when @var{cut?} returns true for a given package.
2957@end deffn
2958
2949@menu 2959@menu
2950* package Reference :: The package data type. 2960* package Reference :: The package data type.
2951* origin Reference:: The origin data type. 2961* origin Reference:: The origin data type.
diff --git a/guix/packages.scm b/guix/packages.scm
index b68b3de6d23..44f2c32fb7d 100644
--- a/guix/packages.scm
+++ b/guix/packages.scm
@@ -98,6 +98,7 @@
98 package-transitive-propagated-inputs 98 package-transitive-propagated-inputs
99 package-transitive-native-search-paths 99 package-transitive-native-search-paths
100 package-transitive-supported-systems 100 package-transitive-supported-systems
101 package-mapping
101 package-input-rewriting 102 package-input-rewriting
102 package-source-derivation 103 package-source-derivation
103 package-derivation 104 package-derivation
@@ -741,36 +742,53 @@ dependencies are known to build on SYSTEM."
741 "Return the \"target inputs\" of BAG, recursively." 742 "Return the \"target inputs\" of BAG, recursively."
742 (transitive-inputs (bag-target-inputs bag))) 743 (transitive-inputs (bag-target-inputs bag)))
743 744
744(define* (package-input-rewriting replacements 745(define* (package-mapping proc #:optional (cut? (const #f)))
745 #:optional (rewrite-name identity)) 746 "Return a procedure that, given a package, applies PROC to all the packages
746 "Return a procedure that, when passed a package, replaces its direct and 747depended on and returns the resulting package. The procedure stops recursion
747indirect dependencies (but not its implicit inputs) according to REPLACEMENTS. 748when CUT? returns true for a given package."
748REPLACEMENTS is a list of package pairs; the first element of each pair is the
749package to replace, and the second one is the replacement.
750
751Optionally, REWRITE-NAME is a one-argument procedure that takes the name of a
752package and returns its new name after rewrite."
753 (define (rewrite input) 749 (define (rewrite input)
754 (match input 750 (match input
755 ((label (? package? package) outputs ...) 751 ((label (? package? package) outputs ...)
756 (match (assq-ref replacements package) 752 (let ((proc (if (cut? package) proc replace)))
757 (#f (cons* label (replace package) outputs)) 753 (cons* label (proc package) outputs)))
758 (new (cons* label new outputs))))
759 (_ 754 (_
760 input))) 755 input)))
761 756
762 (define replace 757 (define replace
763 (mlambdaq (p) 758 (mlambdaq (p)
764 ;; Return a variant of P with its inputs rewritten. 759 ;; Return a variant of P with PROC applied to P and its explicit
765 (package 760 ;; dependencies, recursively. Memoize the transformations. Failing to
766 (inherit p) 761 ;; do that, we would build a huge object graph with lots of duplicates,
767 (name (rewrite-name (package-name p))) 762 ;; which in turns prevents us from benefiting from memoization in
768 (inputs (map rewrite (package-inputs p))) 763 ;; 'package-derivation'.
769 (native-inputs (map rewrite (package-native-inputs p))) 764 (let ((p (proc p)))
770 (propagated-inputs (map rewrite (package-propagated-inputs p)))))) 765 (package
766 (inherit p)
767 (location (package-location p))
768 (inputs (map rewrite (package-inputs p)))
769 (native-inputs (map rewrite (package-native-inputs p)))
770 (propagated-inputs (map rewrite (package-propagated-inputs p)))))))
771 771
772 replace) 772 replace)
773 773
774(define* (package-input-rewriting replacements
775 #:optional (rewrite-name identity))
776 "Return a procedure that, when passed a package, replaces its direct and
777indirect dependencies (but not its implicit inputs) according to REPLACEMENTS.
778REPLACEMENTS is a list of package pairs; the first element of each pair is the
779package to replace, and the second one is the replacement.
780
781Optionally, REWRITE-NAME is a one-argument procedure that takes the name of a
782package and returns its new name after rewrite."
783 (define (rewrite p)
784 (match (assq-ref replacements p)
785 (#f (package
786 (inherit p)
787 (name (rewrite-name (package-name p)))))
788 (new new)))
789
790 (package-mapping rewrite (cut assq <> replacements)))
791
774 792
775;;; 793;;;
776;;; Package derivations. 794;;; Package derivations.
diff --git a/tests/packages.scm b/tests/packages.scm
index 51dc1ba2b0c..930374dabfa 100644
--- a/tests/packages.scm
+++ b/tests/packages.scm
@@ -886,6 +886,33 @@
886 (and (build-derivations %store (list drv)) 886 (and (build-derivations %store (list drv))
887 (file-exists? (string-append out "/bin/make"))))))) 887 (file-exists? (string-append out "/bin/make")))))))
888 888
889(test-equal "package-mapping"
890 42
891 (let* ((dep (dummy-package "chbouib"
892 (native-inputs `(("x" ,grep)))))
893 (p0 (dummy-package "example"
894 (inputs `(("foo" ,coreutils)
895 ("bar" ,grep)
896 ("baz" ,dep)))))
897 (transform (lambda (p)
898 (package (inherit p) (source 42))))
899 (rewrite (package-mapping transform))
900 (p1 (rewrite p0)))
901 (and (eq? p1 (rewrite p0))
902 (eqv? 42 (package-source p1))
903 (match (package-inputs p1)
904 ((("foo" dep1) ("bar" dep2) ("baz" dep3))
905 (and (eq? dep1 (rewrite coreutils)) ;memoization
906 (eq? dep2 (rewrite grep))
907 (eq? dep3 (rewrite dep))
908 (eqv? 42
909 (package-source dep1) (package-source dep2)
910 (package-source dep3))
911 (match (package-native-inputs dep3)
912 ((("x" dep))
913 (and (eq? dep (rewrite grep))
914 (package-source dep))))))))))
915
889(test-assert "package-input-rewriting" 916(test-assert "package-input-rewriting"
890 (let* ((dep (dummy-package "chbouib" 917 (let* ((dep (dummy-package "chbouib"
891 (native-inputs `(("x" ,grep))))) 918 (native-inputs `(("x" ,grep)))))