utils: 'wrap-program' produces only one wrapper file.

* guix/build/utils.scm (wrap-program)[wrapper-file-name]
[next-wrapper-number, wrapper-target]: Remove.
[wrapped-file, already-wrapped?]: New variables.
[last-line]: New procedure.
Use it to append to PROG when a wrapper already exists.
* tests/build-utils.scm ("wrap-program, one input, multiple calls"):
Adjust the list of files to delete.
This commit is contained in:
Ludovic Courtès 2016-09-07 23:59:02 +02:00
parent 5c838ec9cd
commit b14a838509
No known key found for this signature in database
GPG Key ID: 090B11993D9AEBB5
2 changed files with 69 additions and 58 deletions

View File

@ -1,5 +1,5 @@
;;; GNU Guix --- Functional package management for GNU ;;; GNU Guix --- Functional package management for GNU
;;; Copyright © 2012, 2013, 2014, 2015 Ludovic Courtès <ludo@gnu.org> ;;; Copyright © 2012, 2013, 2014, 2015, 2016 Ludovic Courtès <ludo@gnu.org>
;;; Copyright © 2013 Andreas Enge <andreas@enge.fr> ;;; Copyright © 2013 Andreas Enge <andreas@enge.fr>
;;; Copyright © 2013 Nikita Karetnikov <nikita@karetnikov.org> ;;; Copyright © 2013 Nikita Karetnikov <nikita@karetnikov.org>
;;; Copyright © 2015 Mark H Weaver <mhw@netris.org> ;;; Copyright © 2015 Mark H Weaver <mhw@netris.org>
@ -944,29 +944,27 @@ This is useful for scripts that expect particular programs to be in $PATH, for
programs that expect particular shared libraries to be in $LD_LIBRARY_PATH, or programs that expect particular shared libraries to be in $LD_LIBRARY_PATH, or
modules in $GUILE_LOAD_PATH, etc. modules in $GUILE_LOAD_PATH, etc.
If PROG has previously been wrapped by wrap-program the wrapper will point to If PROG has previously been wrapped by 'wrap-program', the wrapper is extended
the previous wrapper." with definitions for VARS."
(define (wrapper-file-name number) (define wrapped-file
(format #f "~a/.~a-wrap-~2'0d" (dirname prog) (basename prog) number)) (string-append (dirname prog) "/." (basename prog) "-real"))
(define (next-wrapper-number)
(let ((wrappers (define already-wrapped?
(find-files (dirname prog) (file-exists? wrapped-file))
(string-append "\\." (basename prog) "-wrap-.*"))))
(if (null? wrappers) (define (last-line port)
0 ;; Return the last line read from PORT and leave PORT's cursor right
(string->number (string-take-right (last wrappers) 2))))) ;; before it.
(define (wrapper-target number) (let loop ((previous-line-offset 0)
(if (zero? number) (previous-line "")
(let ((prog-real (string-append (dirname prog) "/." (position (seek port 0 SEEK_CUR)))
(basename prog) "-real"))) (match (read-line port 'concat)
(rename-file prog prog-real) ((? eof-object?)
prog-real) (seek port previous-line-offset SEEK_SET)
(wrapper-file-name number))) previous-line)
((? string? line)
(loop position line (+ (string-length line) position))))))
(let* ((number (next-wrapper-number))
(target (wrapper-target number))
(wrapper (wrapper-file-name (1+ number)))
(prog-tmp (string-append target "-tmp")))
(define (export-variable lst) (define (export-variable lst)
;; Return a string that exports an environment variable. ;; Return a string that exports an environment variable.
(match lst (match lst
@ -989,19 +987,33 @@ the previous wrapper."
(format #f "export ~a=\"$~a${~a:+:}~a\"" (format #f "export ~a=\"$~a${~a:+:}~a\""
var var var (string-join rest ":"))))) var var var (string-join rest ":")))))
(with-output-to-file prog-tmp (if already-wrapped?
(lambda ()
(format #t ;; PROG is already a wrapper: add the new "export VAR=VALUE" lines just
;; before the last line.
(let* ((port (open-file prog "r+"))
(last (last-line port)))
(for-each (lambda (var)
(display (export-variable var) port)
(newline port))
vars)
(display last port)
(close-port port))
;; PROG is not wrapped yet: create a shell script that sets VARS.
(let ((prog-tmp (string-append wrapped-file "-tmp")))
(link prog wrapped-file)
(call-with-output-file prog-tmp
(lambda (port)
(format port
"#!~a~%~a~%exec -a \"$0\" \"~a\" \"$@\"~%" "#!~a~%~a~%exec -a \"$0\" \"~a\" \"$@\"~%"
(which "bash") (which "bash")
(string-join (map export-variable vars) (string-join (map export-variable vars) "\n")
"\n") (canonicalize-path wrapped-file))))
(canonicalize-path target))))
(chmod prog-tmp #o755) (chmod prog-tmp #o755)
(rename-file prog-tmp wrapper) (rename-file prog-tmp prog))))
(symlink wrapper prog-tmp)
(rename-file prog-tmp prog)))
;;; ;;;

View File

@ -118,8 +118,7 @@
(let* ((pipe (open-input-pipe foo)) (let* ((pipe (open-input-pipe foo))
(str (get-string-all pipe))) (str (get-string-all pipe)))
(with-directory-excursion directory (with-directory-excursion directory
(for-each delete-file (for-each delete-file '("foo" ".foo-real")))
'("foo" ".foo-real" ".foo-wrap-01" ".foo-wrap-02")))
(and (zero? (close-pipe pipe)) (and (zero? (close-pipe pipe))
str)))))) str))))))