union: Add 'relative-file-name'.
* guix/build/union.scm (%not-slash): New variable. (relative-file-name): New procedure. * tests/union.scm (test-relative-file-name): New macro and tests.
This commit is contained in:
parent
8584965b79
commit
dac1c97d13
|
@ -27,7 +27,9 @@
|
||||||
#:use-module (rnrs io ports)
|
#:use-module (rnrs io ports)
|
||||||
#:export (union-build
|
#:export (union-build
|
||||||
|
|
||||||
warn-about-collision))
|
warn-about-collision
|
||||||
|
|
||||||
|
relative-file-name))
|
||||||
|
|
||||||
;;; Commentary:
|
;;; Commentary:
|
||||||
;;;
|
;;;
|
||||||
|
@ -174,4 +176,41 @@ returns #f, skip the faulty file altogether."
|
||||||
|
|
||||||
(union-of-directories output (delete-duplicates inputs)))
|
(union-of-directories output (delete-duplicates inputs)))
|
||||||
|
|
||||||
|
|
||||||
|
;;;
|
||||||
|
;;; Relative symlinks.
|
||||||
|
;;;
|
||||||
|
|
||||||
|
(define %not-slash
|
||||||
|
(char-set-complement (char-set #\/)))
|
||||||
|
|
||||||
|
(define (relative-file-name reference file)
|
||||||
|
"Given REFERENCE and FILE, both of which are absolute file names, return the
|
||||||
|
file name of FILE relative to REFERENCE.
|
||||||
|
|
||||||
|
(relative-file-name \"/gnu/store/foo\" \"/gnu/store/bin/bar\")
|
||||||
|
=> \"../bin/bar\"
|
||||||
|
|
||||||
|
Note that this is from a purely lexical standpoint; conversely, \"..\" is
|
||||||
|
*not* resolved lexically on POSIX in the presence of symlinks."
|
||||||
|
(if (and (string-prefix? "/" file) (string-prefix? "/" reference))
|
||||||
|
(let loop ((reference (string-tokenize reference %not-slash))
|
||||||
|
(file (string-tokenize file %not-slash)))
|
||||||
|
(define (finish)
|
||||||
|
(string-join (append (make-list (length reference) "..") file)
|
||||||
|
"/"))
|
||||||
|
|
||||||
|
(match reference
|
||||||
|
(()
|
||||||
|
(finish))
|
||||||
|
((head . tail)
|
||||||
|
(match file
|
||||||
|
(()
|
||||||
|
(finish))
|
||||||
|
((head* . tail*)
|
||||||
|
(if (string=? head head*)
|
||||||
|
(loop tail tail*)
|
||||||
|
(finish)))))))
|
||||||
|
file))
|
||||||
|
|
||||||
;;; union.scm ends here
|
;;; union.scm ends here
|
||||||
|
|
|
@ -184,4 +184,22 @@
|
||||||
(file-is-directory? "bin")
|
(file-is-directory? "bin")
|
||||||
(eq? 'symlink (stat:type (lstat "bin/guile"))))))))
|
(eq? 'symlink (stat:type (lstat "bin/guile"))))))))
|
||||||
|
|
||||||
|
(letrec-syntax ((test-relative-file-name
|
||||||
|
(syntax-rules (=>)
|
||||||
|
((_ (reference file => expected) rest ...)
|
||||||
|
(begin
|
||||||
|
(test-equal (string-append "relative-file-name "
|
||||||
|
reference " " file)
|
||||||
|
expected
|
||||||
|
(relative-file-name reference file))
|
||||||
|
(test-relative-file-name rest ...)))
|
||||||
|
((_)
|
||||||
|
#t))))
|
||||||
|
(test-relative-file-name
|
||||||
|
("/a/b" "/a/c/d" => "../c/d")
|
||||||
|
("/a/b" "/a/b" => "")
|
||||||
|
("/a/b" "/a" => "..")
|
||||||
|
("/a/b" "/a/b/c/d" => "c/d")
|
||||||
|
("/a/b/c" "/a/d/e/f" => "../../d/e/f")))
|
||||||
|
|
||||||
(test-end)
|
(test-end)
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
;;; GNU Guix --- Functional package management for GNU
|
;;; GNU Guix --- Functional package management for GNU
|
||||||
;;; Copyright © 2012, 2013, 2014, 2015, 2016, 2017 Ludovic Courtès <ludo@gnu.org>
|
;;; Copyright © 2012, 2013, 2014, 2015, 2016, 2017, 2018 Ludovic Courtès <ludo@gnu.org>
|
||||||
;;; Copyright © 2014 Eric Bavier <bavier@member.fsf.org>
|
;;; Copyright © 2014 Eric Bavier <bavier@member.fsf.org>
|
||||||
;;; Copyright © 2016 Mathieu Lirzin <mthl@gnu.org>
|
;;; Copyright © 2016 Mathieu Lirzin <mthl@gnu.org>
|
||||||
;;;
|
;;;
|
||||||
|
|
Loading…
Reference in New Issue