summaryrefslogtreecommitdiff
path: root/guix/build/union.scm
diff options
context:
space:
mode:
authorMark H Weaver <mhw@netris.org>2018-05-17 01:00:50 -0400
committerMark H Weaver <mhw@netris.org>2018-05-17 01:00:50 -0400
commit539bf8f2c071b53834829259bb3fabf0390c5dc6 (patch)
tree16672732afbf4c3f933e67ac677aa1877f6a7657 /guix/build/union.scm
parent903874328ed5e5ab766e36cee1b1a0989e8b24a9 (diff)
parent2cf8531f360ef390d3ec670cc150b106bab5eff1 (diff)
downloadguix-patches-539bf8f2c071b53834829259bb3fabf0390c5dc6.tar
guix-patches-539bf8f2c071b53834829259bb3fabf0390c5dc6.tar.gz
Merge branch 'master' into core-updates
Diffstat (limited to 'guix/build/union.scm')
-rw-r--r--guix/build/union.scm48
1 files changed, 47 insertions, 1 deletions
diff --git a/guix/build/union.scm b/guix/build/union.scm
index 1179f1234b..24b366af45 100644
--- a/guix/build/union.scm
+++ b/guix/build/union.scm
@@ -27,7 +27,10 @@
#:use-module (rnrs io ports)
#:export (union-build
- warn-about-collision))
+ warn-about-collision
+
+ relative-file-name
+ symlink-relative))
;;; Commentary:
;;;
@@ -174,4 +177,47 @@ returns #f, skip the faulty file altogether."
(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))
+
+(define (symlink-relative old new)
+ "Assuming both OLD and NEW are absolute file names, make NEW a symlink to
+OLD, but using a relative file name."
+ (symlink (relative-file-name (dirname new) old)
+ new))
+
;;; union.scm ends here