[asdf-install-devel] Relative symlinks to sysfiles
Chaitanya Gupta
mail at chaitanyagupta.com
Mon Dec 24 15:51:18 EST 2007
Hi,
One minor problem I have with asdf-install is that symlinks (usually in
the systems/ directory) to .asd files are absolute, and not relative.
This becomes a pain if you want to shift your Lisp libraries to a
different directory from the one they were installed in - all the
symlinks have to be created again.
So I have attached a small patch which allows one to create relative
symlinks to .asd files (usually in the systems/ directory) -- if
*relative-symlinks* is non-NIL, the symlinks created are relative. The
code is not all that great, but this is the "best, hopefully portable"
solution that I could come up with (will be great if anyone can suggest
improvements). It works on ACL8 and SBCL 1.0.5 on OS X (I cannot test it
on other environments right now, but it should work fine on Linux for
these two implementations, I think).
The patch is in unified diff format (created using darcs diff -u). If
its good enough, I'll create a patch file and send it. Otherwise
suggestions are always welcome.
Thanks,
Chaitanya
-------------- next part --------------
Tue Dec 25 02:04:26 IST 2007 mail at chaitanyagupta.com
* Minor bugfix to relative symlinks to make it work with SBCL.
Tue Dec 25 01:50:33 IST 2007 mail at chaitanyagupta.com
* Added *relative-symlinks* which allows one to create relative symlinks.
diff -rN -u old-asdf-install/asdf-install/port.lisp new-asdf-install/asdf-install/port.lisp
--- old-asdf-install/asdf-install/port.lisp 2007-12-25 02:16:47.000000000 +0530
+++ new-asdf-install/asdf-install/port.lisp 2007-12-25 02:16:47.000000000 +0530
@@ -261,6 +261,10 @@
(format t "~S~%" command)
(shell-command command)))
+(defvar *relative-symlinks* nil
+ "If non-NIL, symlinks to the sysfile from System are relative
+ to System. Otherwise the symlink contains an absolute path.")
+
(defun maybe-symlink-sysfile (system sysfile)
(declare (ignorable system sysfile))
#-(or :win32 :mswindows)
@@ -270,7 +274,50 @@
system)))
(when (probe-file target)
(unlink-file target))
- (symlink-files sysfile target)))
+ (symlink-files (if *relative-symlinks*
+ (compute-relative-path sysfile target)
+ sysfile)
+ target)))
+
+(defun compute-base-path (path1 path2)
+ "Computes the common parent directories between PATH1 and PATH2
+and returns it as a pathname. The common path is calculated only
+if PATH1 and PATH2 are absolute paths and their HOST and DEVICE
+components are equal. If this is not safisfied, then a NULL value
+is returned. The HOST and DEVICE components of the returned
+pathname are the same as that of PATH1 (and PATH2)."
+ (when (and (equal (first (pathname-directory path1)) :absolute)
+ (equal (first (pathname-directory path2)) :absolute)
+ (equal (pathname-host path1) (pathname-host path2))
+ (equal (pathname-device path1) (pathname-device path2)))
+ (make-pathname :host (pathname-host path1)
+ :device (pathname-device path1)
+ :directory (loop
+ for dir1-element in (pathname-directory path1)
+ for dir2-element in (pathname-directory path2)
+ while (equal dir1-element dir2-element)
+ collect dir1-element))))
+
+(defun compute-relative-path (path1 path2)
+ "Tries to compute a relative path to PATH1 from PATH2 if these
+are absolute paths and have the same HOST and DEVICE
+components. If a relative path cannot be calculated, then PATH1
+is returned."
+ (let* ((base-path (or (compute-base-path path1 path2)
+ (return-from compute-relative-path path1)))
+ (enough-path1 (pathname (enough-namestring path1 base-path)))
+ (enough-path2 (pathname (enough-namestring path2 base-path)))
+ (enough-path2-dir (pathname-directory enough-path2))
+ (path2-back-dir (make-pathname
+ :directory (cond
+ ((null enough-path2-dir)
+ nil)
+ ((equal (first enough-path2-dir) :relative)
+ (cons :relative
+ (mapcar (constantly :up) (rest enough-path2-dir))))
+ (t
+ (return-from compute-relative-path path1))))))
+ (merge-pathnames enough-path1 path2-back-dir)))
;;; ---------------------------------------------------------------------------
;;; read-header-line
More information about the asdf-install-devel
mailing list