From cf8b312d1872aec1f38a179eeb981d79bf7faa03 Mon Sep 17 00:00:00 2001 From: Ludovic Courtès Date: Fri, 20 May 2016 22:11:56 +0200 Subject: grafts: Preserve empty directories when grafting. * guix/build/graft.scm (rewrite-directory)[rewrite-leaf]: Add case for 'directory. Pass #:directories? #t to 'find-files'. --- tests/grafts.scm | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) (limited to 'tests/grafts.scm') diff --git a/tests/grafts.scm b/tests/grafts.scm index afed704cde..f8c9eced1d 100644 --- a/tests/grafts.scm +++ b/tests/grafts.scm @@ -127,6 +127,30 @@ (list one two dep) (references %store dep))))))) +(test-assert "graft-derivation, preserve empty directories" + (run-with-store %store + (mlet* %store-monad ((fake (text-file "bash" "Fake bash.")) + (graft -> (graft + (origin %bash) + (replacement fake))) + (drv (gexp->derivation + "to-graft" + #~(begin + (use-modules (guix build utils)) + (mkdir-p (string-append #$output + "/a/b/c/d")) + (symlink #$%bash + (string-append #$output + "/bash"))) + #:modules '((guix build utils)))) + (grafted ((store-lift graft-derivation) drv + (list graft))) + (_ (built-derivations (list grafted))) + (out -> (derivation->output-path grafted))) + (return (and (string=? (readlink (string-append out "/bash")) + fake) + (file-is-directory? (string-append out "/a/b/c/d"))))))) + (test-assert "graft-derivation, no dependencies on grafted output" (run-with-store %store (mlet* %store-monad ((fake (text-file "bash" "Fake bash.")) -- cgit 1.4.1 From ece6864bd04fc2f9ff86fd4ac9cb0712dd71c094 Mon Sep 17 00:00:00 2001 From: Ludovic Courtès Date: Fri, 20 May 2016 22:14:46 +0200 Subject: grafts: Rename files whose name matches a graft. Fixes . Reported by Mark H Weaver . * guix/build/graft.scm (rename-matching-files): New procedure. (rewrite-directory): Use it. * tests/grafts.scm ("graft-derivation, renaming"): New test. --- guix/build/graft.scm | 25 ++++++++++++++++++++++++- tests/grafts.scm | 17 +++++++++++++++++ 2 files changed, 41 insertions(+), 1 deletion(-) (limited to 'tests/grafts.scm') diff --git a/guix/build/graft.scm b/guix/build/graft.scm index e9fce03181..b61982dd64 100644 --- a/guix/build/graft.scm +++ b/guix/build/graft.scm @@ -83,6 +83,28 @@ writing the result to OUTPUT." (put-u8 output (char->integer char)) result))))) +(define (rename-matching-files directory mapping) + "Apply MAPPING to the names of all the files in DIRECTORY, where MAPPING is +a list of store file name pairs." + (let* ((mapping (map (match-lambda + ((source . target) + (cons (basename source) (basename target)))) + mapping)) + (matches (find-files directory + (lambda (file stat) + (assoc-ref mapping (basename file))) + #:directories? #t))) + + ;; XXX: This is not quite correct: if MAPPING contains "foo", and + ;; DIRECTORY contains "bar/foo/foo", we first rename "bar/foo" and then + ;; "bar/foo/foo" no longer exists so we fail. Oh well, surely that's good + ;; enough! + (for-each (lambda (file) + (let ((target (assoc-ref mapping (basename file)))) + (rename-file file + (string-append (dirname file) "/" target)))) + matches))) + (define* (rewrite-directory directory output mapping #:optional (store (%store-directory))) "Copy DIRECTORY to OUTPUT, replacing strings according to MAPPING, a list of @@ -127,6 +149,7 @@ file name pairs." (n-par-for-each (parallel-job-count) rewrite-leaf (find-files directory (const #t) - #:directories? #t))) + #:directories? #t)) + (rename-matching-files output mapping)) ;;; graft.scm ends here diff --git a/tests/grafts.scm b/tests/grafts.scm index f8c9eced1d..8cd048552c 100644 --- a/tests/grafts.scm +++ b/tests/grafts.scm @@ -182,4 +182,21 @@ (and (string=? (readlink one) repl) (string=? (readlink two) one)))))) +(test-assert "graft-derivation, renaming" ; + (let* ((build `(begin + (use-modules (guix build utils)) + (mkdir-p (string-append (assoc-ref %outputs "out") "/" + (assoc-ref %build-inputs "in"))))) + (orig (build-expression->derivation %store "thing-to-graft" build + #:modules '((guix build utils)) + #:inputs `(("in" ,%bash)))) + (repl (add-text-to-store %store "bash" "fake bash")) + (grafted (graft-derivation %store orig + (list (graft + (origin %bash) + (replacement repl)))))) + (and (build-derivations %store (list grafted)) + (let ((out (derivation->output-path grafted))) + (file-is-directory? (string-append out "/" repl)))))) + (test-end) -- cgit 1.4.1