install_symlink_p: Fix when dest includes a symlink

install_symlink_p does not work as intended when dst includes a symlink in its path.
relative_path_from requires that both src and dst be real paths without symlinks.

From https://ruby-doc.org/stdlib-2.3.7/libdoc/pathname/rdoc/Pathname.html#method-i-relative_path_from
This method doesn't access the filesystem. It assumes no symlinks.
This commit is contained in:
Shaun Jackman 2019-02-22 13:18:47 -08:00
parent db42dd0420
commit 5cb458d687
2 changed files with 12 additions and 3 deletions

View File

@ -135,10 +135,11 @@ class Pathname
end
def install_symlink_p(src, new_basename)
src = Pathname(src).expand_path(self)
dst = join(new_basename)
mkpath
FileUtils.ln_sf(src.relative_path_from(dst.parent), dst)
dstdir = realpath
src = Pathname(src).expand_path(dstdir)
src = src.dirname.realpath/src.basename if src.dirname.exist?
FileUtils.ln_sf(src.relative_path_from(dstdir), dstdir/new_basename)
end
private :install_symlink_p

View File

@ -245,6 +245,14 @@ describe Pathname do
dst.install_symlink "foo" => "bar"
expect((dst/"bar").readlink).to eq(described_class.new("foo"))
end
it "can install relative symlinks in a symlinked directory" do
mkdir_p dst/"1/2"
dst.install_symlink "1/2" => "12"
expect((dst/"12").readlink).to eq(described_class.new("1/2"))
(dst/"12").install_symlink dst/"foo"
expect((dst/"12/foo").readlink).to eq(described_class.new("../../foo"))
end
end
describe InstallRenamed do