
On Wed, Sep 26, 2012 at 03:30:50PM +0100, Jon Fairbairn wrote:
I have an application where I want to use relative paths in symlinks (so that rsyncing to a different machine with a different root directory produces something with the same effect).
So I want
makeRelative "/var/www/this_server/foo/bar/" "/var/www/this_server/bob"
to return "../../bob" (which would then be used to create a symlink) so that if I copy the tree below /var/www/this_server to /var/www/that_server (perhaps on a different machine, but copying the symlinks without rewriting them), the symlinks point to the same files.
On posix at least, this would permit isRelative (makeRelative a b) always to be True, which is a pleasant property for it to have.
Is there any reason that System.FilePath.Posix.makeRelative should not do this? I don’t know enough about non-posix filesystems to know whether it even makes sense elsewhere.
Coincidentally, I needed this yesterday, was also surprised to find it missing, and wrote: makeRelativeTo :: FilePath -> FilePath -> FilePath this `makeRelativeTo` that = directory > thisFilename where (thisDirectory, thisFilename) = splitFileName this thatDirectory = dropFileName that directory = joinPath $ f (splitPath thisDirectory) (splitPath thatDirectory) f (x : xs) (y : ys) | x == y = f xs ys f xs ys = replicate (length ys) ".." ++ xs (in my case, I know that both paths are absolute). One thing I wasn't sure of is what to do about different drives on Windows. Perhaps it would actually need to return a Maybe FilePath? Thanks Ian