summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLudovic Courtès <ludo@gnu.org>2016-02-22 16:29:44 +0100
committerLudovic Courtès <ludo@gnu.org>2016-02-22 22:11:37 +0100
commit7adf9b8469f3f043e61d1c9614aea8abb63fb727 (patch)
tree38e06768a990ef6954a0ae7e11c8aa3aec723aab
parent3297deedd1fcfd98641b01b477fad182f70cad61 (diff)
derivations: Move grafts to (guix grafts).
* guix/derivations.scm (<graft>, graft-derivation, %graft?) (set-grafting): Move to... * guix/grafts.scm: ... here. New file. * guix/gexp.scm, guix/packages.scm, tests/packages.scm, guix/scripts/build.scm: Use it. * Makefile.am (MODULES): Add it. (SCM_TESTS): Add tests/grafts.scm. * tests/derivations.scm ("graft-derivation"): Move to... * tests/grafts.scm: ... here. New file.
-rw-r--r--Makefile.am2
-rw-r--r--guix/derivations.scm98
-rw-r--r--guix/gexp.scm3
-rw-r--r--guix/grafts.scm127
-rw-r--r--guix/packages.scm3
-rw-r--r--guix/scripts/build.scm1
-rw-r--r--tests/derivations.scm34
-rw-r--r--tests/grafts.scm81
-rw-r--r--tests/packages.scm3
9 files changed, 217 insertions, 135 deletions
diff --git a/Makefile.am b/Makefile.am
index 9beeb9d564b..01d7fbecb7b 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -49,6 +49,7 @@ MODULES = \
49 guix/serialization.scm \ 49 guix/serialization.scm \
50 guix/nar.scm \ 50 guix/nar.scm \
51 guix/derivations.scm \ 51 guix/derivations.scm \
52 guix/grafts.scm \
52 guix/gnu-maintenance.scm \ 53 guix/gnu-maintenance.scm \
53 guix/upstream.scm \ 54 guix/upstream.scm \
54 guix/licenses.scm \ 55 guix/licenses.scm \
@@ -220,6 +221,7 @@ SCM_TESTS = \
220 tests/substitute.scm \ 221 tests/substitute.scm \
221 tests/builders.scm \ 222 tests/builders.scm \
222 tests/derivations.scm \ 223 tests/derivations.scm \
224 tests/grafts.scm \
223 tests/ui.scm \ 225 tests/ui.scm \
224 tests/records.scm \ 226 tests/records.scm \
225 tests/utils.scm \ 227 tests/utils.scm \
diff --git a/guix/derivations.scm b/guix/derivations.scm
index 5db739a97d3..11647740093 100644
--- a/guix/derivations.scm
+++ b/guix/derivations.scm
@@ -85,21 +85,11 @@
85 derivation-path->output-paths 85 derivation-path->output-paths
86 derivation 86 derivation
87 87
88 graft
89 graft?
90 graft-origin
91 graft-replacement
92 graft-origin-output
93 graft-replacement-output
94 graft-derivation
95
96 map-derivation 88 map-derivation
97 89
98 build-derivations 90 build-derivations
99 built-derivations 91 built-derivations
100 92
101 %graft?
102 set-grafting
103 93
104 build-expression->derivation) 94 build-expression->derivation)
105 95
@@ -1111,81 +1101,6 @@ they can refer to each other."
1111 #:guile-for-build guile 1101 #:guile-for-build guile
1112 #:local-build? #t))) 1102 #:local-build? #t)))
1113 1103
1114(define-record-type* <graft> graft make-graft
1115 graft?
1116 (origin graft-origin) ;derivation | store item
1117 (origin-output graft-origin-output ;string | #f
1118 (default "out"))
1119 (replacement graft-replacement) ;derivation | store item
1120 (replacement-output graft-replacement-output ;string | #f
1121 (default "out")))
1122
1123(define* (graft-derivation store name drv grafts
1124 #:key (guile (%guile-for-build))
1125 (system (%current-system)))
1126 "Return a derivation called NAME, based on DRV but with all the GRAFTS
1127applied."
1128 ;; XXX: Someday rewrite using gexps.
1129 (define mapping
1130 ;; List of store item pairs.
1131 (map (match-lambda
1132 (($ <graft> source source-output target target-output)
1133 (cons (if (derivation? source)
1134 (derivation->output-path source source-output)
1135 source)
1136 (if (derivation? target)
1137 (derivation->output-path target target-output)
1138 target))))
1139 grafts))
1140
1141 (define outputs
1142 (match (derivation-outputs drv)
1143 (((names . outputs) ...)
1144 (map derivation-output-path outputs))))
1145
1146 (define output-names
1147 (match (derivation-outputs drv)
1148 (((names . outputs) ...)
1149 names)))
1150
1151 (define build
1152 `(begin
1153 (use-modules (guix build graft)
1154 (guix build utils)
1155 (ice-9 match))
1156
1157 (let ((mapping ',mapping))
1158 (for-each (lambda (input output)
1159 (format #t "grafting '~a' -> '~a'...~%" input output)
1160 (force-output)
1161 (rewrite-directory input output
1162 `((,input . ,output)
1163 ,@mapping)))
1164 ',outputs
1165 (match %outputs
1166 (((names . files) ...)
1167 files))))))
1168
1169 (define add-label
1170 (cut cons "x" <>))
1171
1172 (match grafts
1173 ((($ <graft> sources source-outputs targets target-outputs) ...)
1174 (let ((sources (zip sources source-outputs))
1175 (targets (zip targets target-outputs)))
1176 (build-expression->derivation store name build
1177 #:system system
1178 #:guile-for-build guile
1179 #:modules '((guix build graft)
1180 (guix build utils))
1181 #:inputs `(,@(map (lambda (out)
1182 `("x" ,drv ,out))
1183 output-names)
1184 ,@(append (map add-label sources)
1185 (map add-label targets)))
1186 #:outputs output-names
1187 #:local-build? #t)))))
1188
1189(define* (build-expression->derivation store name exp ;deprecated 1104(define* (build-expression->derivation store name exp ;deprecated
1190 #:key 1105 #:key
1191 (system (%current-system)) 1106 (system (%current-system))
@@ -1353,16 +1268,3 @@ ALLOWED-REFERENCES, LOCAL-BUILD?, and SUBSTITUTABLE?."
1353 1268
1354(define built-derivations 1269(define built-derivations
1355 (store-lift build-derivations)) 1270 (store-lift build-derivations))
1356
1357;; The following might feel more at home in (guix packages) but since (guix
1358;; gexp), which is a lower level, needs them, we put them here.
1359
1360(define %graft?
1361 ;; Whether to honor package grafts by default.
1362 (make-parameter #t))
1363
1364(define (set-grafting enable?)
1365 "This monadic procedure enables grafting when ENABLE? is true, and disables
1366it otherwise. It returns the previous setting."
1367 (lambda (store)
1368 (values (%graft? enable?) store)))
diff --git a/guix/gexp.scm b/guix/gexp.scm
index 35adc179a1d..87bc316f97a 100644
--- a/guix/gexp.scm
+++ b/guix/gexp.scm
@@ -1,5 +1,5 @@
1;;; GNU Guix --- Functional package management for GNU 1;;; GNU Guix --- Functional package management for GNU
2;;; Copyright © 2014, 2015 Ludovic Courtès <ludo@gnu.org> 2;;; Copyright © 2014, 2015, 2016 Ludovic Courtès <ludo@gnu.org>
3;;; 3;;;
4;;; This file is part of GNU Guix. 4;;; This file is part of GNU Guix.
5;;; 5;;;
@@ -20,6 +20,7 @@
20 #:use-module (guix store) 20 #:use-module (guix store)
21 #:use-module (guix monads) 21 #:use-module (guix monads)
22 #:use-module (guix derivations) 22 #:use-module (guix derivations)
23 #:use-module (guix grafts)
23 #:use-module (guix utils) 24 #:use-module (guix utils)
24 #:use-module (srfi srfi-1) 25 #:use-module (srfi srfi-1)
25 #:use-module (srfi srfi-9) 26 #:use-module (srfi srfi-9)
diff --git a/guix/grafts.scm b/guix/grafts.scm
new file mode 100644
index 00000000000..6b78a784e7f
--- /dev/null
+++ b/guix/grafts.scm
@@ -0,0 +1,127 @@
1;;; GNU Guix --- Functional package management for GNU
2;;; Copyright © 2014, 2015, 2016 Ludovic Courtès <ludo@gnu.org>
3;;;
4;;; This file is part of GNU Guix.
5;;;
6;;; GNU Guix is free software; you can redistribute it and/or modify it
7;;; under the terms of the GNU General Public License as published by
8;;; the Free Software Foundation; either version 3 of the License, or (at
9;;; your option) any later version.
10;;;
11;;; GNU Guix is distributed in the hope that it will be useful, but
12;;; WITHOUT ANY WARRANTY; without even the implied warranty of
13;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14;;; GNU General Public License for more details.
15;;;
16;;; You should have received a copy of the GNU General Public License
17;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>.
18
19(define-module (guix grafts)
20 #:use-module (guix records)
21 #:use-module (guix derivations)
22 #:use-module ((guix utils) #:select (%current-system))
23 #:use-module (srfi srfi-1)
24 #:use-module (srfi srfi-26)
25 #:use-module (ice-9 match)
26 #:export (graft?
27 graft
28 graft-origin
29 graft-replacement
30 graft-origin-output
31 graft-replacement-output
32
33 graft-derivation
34
35 %graft?
36 set-grafting))
37
38(define-record-type* <graft> graft make-graft
39 graft?
40 (origin graft-origin) ;derivation | store item
41 (origin-output graft-origin-output ;string | #f
42 (default "out"))
43 (replacement graft-replacement) ;derivation | store item
44 (replacement-output graft-replacement-output ;string | #f
45 (default "out")))
46
47(define* (graft-derivation store name drv grafts
48 #:key (guile (%guile-for-build))
49 (system (%current-system)))
50 "Return a derivation called NAME, based on DRV but with all the GRAFTS
51applied."
52 ;; XXX: Someday rewrite using gexps.
53 (define mapping
54 ;; List of store item pairs.
55 (map (match-lambda
56 (($ <graft> source source-output target target-output)
57 (cons (if (derivation? source)
58 (derivation->output-path source source-output)
59 source)
60 (if (derivation? target)
61 (derivation->output-path target target-output)
62 target))))
63 grafts))
64
65 (define outputs
66 (match (derivation-outputs drv)
67 (((names . outputs) ...)
68 (map derivation-output-path outputs))))
69
70 (define output-names
71 (match (derivation-outputs drv)
72 (((names . outputs) ...)
73 names)))
74
75 (define build
76 `(begin
77 (use-modules (guix build graft)
78 (guix build utils)
79 (ice-9 match))
80
81 (let ((mapping ',mapping))
82 (for-each (lambda (input output)
83 (format #t "grafting '~a' -> '~a'...~%" input output)
84 (force-output)
85 (rewrite-directory input output
86 `((,input . ,output)
87 ,@mapping)))
88 ',outputs
89 (match %outputs
90 (((names . files) ...)
91 files))))))
92
93 (define add-label
94 (cut cons "x" <>))
95
96 (match grafts
97 ((($ <graft> sources source-outputs targets target-outputs) ...)
98 (let ((sources (zip sources source-outputs))
99 (targets (zip targets target-outputs)))
100 (build-expression->derivation store name build
101 #:system system
102 #:guile-for-build guile
103 #:modules '((guix build graft)
104 (guix build utils))
105 #:inputs `(,@(map (lambda (out)
106 `("x" ,drv ,out))
107 output-names)
108 ,@(append (map add-label sources)
109 (map add-label targets)))
110 #:outputs output-names
111 #:local-build? #t)))))
112
113
114;; The following might feel more at home in (guix packages) but since (guix
115;; gexp), which is a lower level, needs them, we put them here.
116
117(define %graft?
118 ;; Whether to honor package grafts by default.
119 (make-parameter #t))
120
121(define (set-grafting enable?)
122 "This monadic procedure enables grafting when ENABLE? is true, and disables
123it otherwise. It returns the previous setting."
124 (lambda (store)
125 (values (%graft? enable?) store)))
126
127;;; grafts.scm ends here
diff --git a/guix/packages.scm b/guix/packages.scm
index 6ec168c2040..93bfbc4683a 100644
--- a/guix/packages.scm
+++ b/guix/packages.scm
@@ -1,5 +1,5 @@
1;;; GNU Guix --- Functional package management for GNU 1;;; GNU Guix --- Functional package management for GNU
2;;; Copyright © 2012, 2013, 2014, 2015 Ludovic Courtès <ludo@gnu.org> 2;;; Copyright © 2012, 2013, 2014, 2015, 2016 Ludovic Courtès <ludo@gnu.org>
3;;; Copyright © 2014, 2015 Mark H Weaver <mhw@netris.org> 3;;; Copyright © 2014, 2015 Mark H Weaver <mhw@netris.org>
4;;; Copyright © 2015 Eric Bavier <bavier@member.fsf.org> 4;;; Copyright © 2015 Eric Bavier <bavier@member.fsf.org>
5;;; 5;;;
@@ -25,6 +25,7 @@
25 #:use-module (guix monads) 25 #:use-module (guix monads)
26 #:use-module (guix gexp) 26 #:use-module (guix gexp)
27 #:use-module (guix base32) 27 #:use-module (guix base32)
28 #:use-module (guix grafts)
28 #:use-module (guix derivations) 29 #:use-module (guix derivations)
29 #:use-module (guix build-system) 30 #:use-module (guix build-system)
30 #:use-module (guix search-paths) 31 #:use-module (guix search-paths)
diff --git a/guix/scripts/build.scm b/guix/scripts/build.scm
index aa9c105f581..8725ddad88e 100644
--- a/guix/scripts/build.scm
+++ b/guix/scripts/build.scm
@@ -23,6 +23,7 @@
23 #:use-module (guix store) 23 #:use-module (guix store)
24 #:use-module (guix derivations) 24 #:use-module (guix derivations)
25 #:use-module (guix packages) 25 #:use-module (guix packages)
26 #:use-module (guix grafts)
26 #:use-module (guix utils) 27 #:use-module (guix utils)
27 #:use-module (guix monads) 28 #:use-module (guix monads)
28 #:use-module (guix gexp) 29 #:use-module (guix gexp)
diff --git a/tests/derivations.scm b/tests/derivations.scm
index db96e26ab1a..9b53019cc57 100644
--- a/tests/derivations.scm
+++ b/tests/derivations.scm
@@ -929,40 +929,6 @@
929 ((p2 . _) 929 ((p2 . _)
930 (string<? p1 p2))))))))))))) 930 (string<? p1 p2)))))))))))))
931 931
932
933(test-assert "graft-derivation"
934 (let* ((build `(begin
935 (mkdir %output)
936 (chdir %output)
937 (symlink %output "self")
938 (call-with-output-file "text"
939 (lambda (output)
940 (format output "foo/~a/bar" ,%mkdir)))
941 (symlink ,%bash "sh")))
942 (orig (build-expression->derivation %store "graft" build
943 #:inputs `(("a" ,%bash)
944 ("b" ,%mkdir))))
945 (one (add-text-to-store %store "bash" "fake bash"))
946 (two (build-expression->derivation %store "mkdir"
947 '(call-with-output-file %output
948 (lambda (port)
949 (display "fake mkdir" port)))))
950 (graft (graft-derivation %store "graft" orig
951 (list (graft
952 (origin %bash)
953 (replacement one))
954 (graft
955 (origin %mkdir)
956 (replacement two))))))
957 (and (build-derivations %store (list graft))
958 (let ((two (derivation->output-path two))
959 (graft (derivation->output-path graft)))
960 (and (string=? (format #f "foo/~a/bar" two)
961 (call-with-input-file (string-append graft "/text")
962 get-string-all))
963 (string=? (readlink (string-append graft "/sh")) one)
964 (string=? (readlink (string-append graft "/self")) graft))))))
965
966(test-equal "map-derivation" 932(test-equal "map-derivation"
967 "hello" 933 "hello"
968 (let* ((joke (package-derivation %store guile-1.8)) 934 (let* ((joke (package-derivation %store guile-1.8))
diff --git a/tests/grafts.scm b/tests/grafts.scm
new file mode 100644
index 00000000000..c11403be19e
--- /dev/null
+++ b/tests/grafts.scm
@@ -0,0 +1,81 @@
1;;; GNU Guix --- Functional package management for GNU
2;;; Copyright © 2014, 2015, 2016 Ludovic Courtès <ludo@gnu.org>
3;;;
4;;; This file is part of GNU Guix.
5;;;
6;;; GNU Guix is free software; you can redistribute it and/or modify it
7;;; under the terms of the GNU General Public License as published by
8;;; the Free Software Foundation; either version 3 of the License, or (at
9;;; your option) any later version.
10;;;
11;;; GNU Guix is distributed in the hope that it will be useful, but
12;;; WITHOUT ANY WARRANTY; without even the implied warranty of
13;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14;;; GNU General Public License for more details.
15;;;
16;;; You should have received a copy of the GNU General Public License
17;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>.
18
19(define-module (test-grafts)
20 #:use-module (guix derivations)
21 #:use-module (guix store)
22 #:use-module (guix utils)
23 #:use-module (guix grafts)
24 #:use-module (guix tests)
25 #:use-module ((gnu packages) #:select (search-bootstrap-binary))
26 #:use-module (srfi srfi-64)
27 #:use-module (rnrs io ports))
28
29(define %store
30 (open-connection-for-tests))
31
32(define (bootstrap-binary name)
33 (let ((bin (search-bootstrap-binary name (%current-system))))
34 (and %store
35 (add-to-store %store name #t "sha256" bin))))
36
37(define %bash
38 (bootstrap-binary "bash"))
39(define %mkdir
40 (bootstrap-binary "mkdir"))
41
42
43(test-begin "grafts")
44
45(test-assert "graft-derivation"
46 (let* ((build `(begin
47 (mkdir %output)
48 (chdir %output)
49 (symlink %output "self")
50 (call-with-output-file "text"
51 (lambda (output)
52 (format output "foo/~a/bar" ,%mkdir)))
53 (symlink ,%bash "sh")))
54 (orig (build-expression->derivation %store "graft" build
55 #:inputs `(("a" ,%bash)
56 ("b" ,%mkdir))))
57 (one (add-text-to-store %store "bash" "fake bash"))
58 (two (build-expression->derivation %store "mkdir"
59 '(call-with-output-file %output
60 (lambda (port)
61 (display "fake mkdir" port)))))
62 (graft (graft-derivation %store "graft" orig
63 (list (graft
64 (origin %bash)
65 (replacement one))
66 (graft
67 (origin %mkdir)
68 (replacement two))))))
69 (and (build-derivations %store (list graft))
70 (let ((two (derivation->output-path two))
71 (graft (derivation->output-path graft)))
72 (and (string=? (format #f "foo/~a/bar" two)
73 (call-with-input-file (string-append graft "/text")
74 get-string-all))
75 (string=? (readlink (string-append graft "/sh")) one)
76 (string=? (readlink (string-append graft "/self")) graft))))))
77
78(test-end)
79
80
81(exit (= (test-runner-fail-count (test-runner-current)) 0))
diff --git a/tests/packages.scm b/tests/packages.scm
index 9d37fb68d67..68ab3f897b1 100644
--- a/tests/packages.scm
+++ b/tests/packages.scm
@@ -1,5 +1,5 @@
1;;; GNU Guix --- Functional package management for GNU 1;;; GNU Guix --- Functional package management for GNU
2;;; Copyright © 2012, 2013, 2014, 2015 Ludovic Courtès <ludo@gnu.org> 2;;; Copyright © 2012, 2013, 2014, 2015, 2016 Ludovic Courtès <ludo@gnu.org>
3;;; 3;;;
4;;; This file is part of GNU Guix. 4;;; This file is part of GNU Guix.
5;;; 5;;;
@@ -29,6 +29,7 @@
29 #:use-module (guix hash) 29 #:use-module (guix hash)
30 #:use-module (guix derivations) 30 #:use-module (guix derivations)
31 #:use-module (guix packages) 31 #:use-module (guix packages)
32 #:use-module (guix grafts)
32 #:use-module (guix search-paths) 33 #:use-module (guix search-paths)
33 #:use-module (guix build-system) 34 #:use-module (guix build-system)
34 #:use-module (guix build-system trivial) 35 #:use-module (guix build-system trivial)