brew/Library/Homebrew/test/test_keg.rb
Ben Morgan 1795599d88 keg: explicitly create cmake dir under lib
Packages supporting CMake may install configuration files for use
with CMake's find_package command. A recommended location for these
is `<prefix>/lib/cmake` which is not unique across packages. This
may cause issues for Formula using this location when their Keg
is linked.

As with pkg-config, explicitly create the `lib/cmake` folder when
linking a Keg that has installed folders/files to this location.

Also add testcase.

Closes Homebrew/homebrew#38005.

Signed-off-by: Xu Cheng <xucheng@me.com>
2015-03-29 22:01:21 +08:00

266 lines
6.1 KiB
Ruby

require 'testing_env'
require 'keg'
require 'stringio'
class LinkTests < Homebrew::TestCase
include FileUtils
def setup
keg = HOMEBREW_CELLAR.join("foo", "1.0")
keg.join("bin").mkpath
%w{hiworld helloworld goodbye_cruel_world}.each do |file|
touch keg.join("bin", file)
end
@keg = Keg.new(keg)
@dst = HOMEBREW_PREFIX.join("bin", "helloworld")
@nonexistent = Pathname.new("/some/nonexistent/path")
@mode = OpenStruct.new
@old_stdout = $stdout
$stdout = StringIO.new
mkpath HOMEBREW_PREFIX/"bin"
mkpath HOMEBREW_PREFIX/"lib"
end
def teardown
@keg.unlink
@keg.uninstall
$stdout = @old_stdout
rmtree HOMEBREW_PREFIX/"bin"
rmtree HOMEBREW_PREFIX/"lib"
end
def test_linking_keg
assert_equal 3, @keg.link
(HOMEBREW_PREFIX/"bin").children.each { |c| assert_predicate c.readlink, :relative? }
end
def test_unlinking_keg
@keg.link
assert_predicate @dst, :symlink?
assert_equal 4, @keg.unlink
refute_predicate @dst, :symlink?
end
def test_link_dry_run
@mode.dry_run = true
assert_equal 0, @keg.link(@mode)
refute_predicate @keg, :linked?
['hiworld', 'helloworld', 'goodbye_cruel_world'].each do |file|
assert_match "#{HOMEBREW_PREFIX}/bin/#{file}", $stdout.string
end
assert_equal 3, $stdout.string.lines.count
end
def test_linking_fails_when_already_linked
@keg.link
assert_raises(Keg::AlreadyLinkedError) { @keg.link }
end
def test_linking_fails_when_files_exist
touch @dst
assert_raises(Keg::ConflictError) { @keg.link }
end
def test_link_ignores_broken_symlinks_at_target
src = @keg.join("bin", "helloworld")
@dst.make_symlink(@nonexistent)
@keg.link
assert_equal src.relative_path_from(@dst.dirname), @dst.readlink
end
def test_link_overwrite
touch @dst
@mode.overwrite = true
assert_equal 3, @keg.link(@mode)
assert_predicate @keg, :linked?
end
def test_link_overwrite_broken_symlinks
@dst.make_symlink "nowhere"
@mode.overwrite = true
assert_equal 3, @keg.link(@mode)
assert_predicate @keg, :linked?
end
def test_link_overwrite_dryrun
touch @dst
@mode.overwrite = true
@mode.dry_run = true
assert_equal 0, @keg.link(@mode)
refute_predicate @keg, :linked?
assert_equal "#{@dst}\n", $stdout.string
end
def test_unlink_prunes_empty_toplevel_directories
mkpath HOMEBREW_PREFIX/"lib/foo/bar"
mkpath @keg/"lib/foo/bar"
touch @keg/"lib/foo/bar/file1"
@keg.unlink
refute_predicate HOMEBREW_PREFIX/"lib/foo", :directory?
end
def test_unlink_ignores_DS_Store_when_pruning_empty_dirs
mkpath HOMEBREW_PREFIX/"lib/foo/bar"
touch HOMEBREW_PREFIX/"lib/foo/.DS_Store"
mkpath @keg/"lib/foo/bar"
touch @keg/"lib/foo/bar/file1"
@keg.unlink
refute_predicate HOMEBREW_PREFIX/"lib/foo", :directory?
refute_predicate HOMEBREW_PREFIX/"lib/foo/.DS_Store", :exist?
end
def test_linking_creates_opt_link
refute_predicate @keg, :optlinked?
@keg.link
assert_predicate @keg, :optlinked?
end
def test_unlinking_does_not_remove_opt_link
@keg.link
@keg.unlink
assert_predicate @keg, :optlinked?
end
def test_existing_opt_link
@keg.opt_record.make_relative_symlink Pathname.new(@keg)
@keg.optlink
assert_predicate @keg, :optlinked?
end
def test_existing_opt_link_directory
@keg.opt_record.mkpath
@keg.optlink
assert_predicate @keg, :optlinked?
end
def test_existing_opt_link_file
@keg.opt_record.parent.mkpath
@keg.opt_record.write("foo")
@keg.optlink
assert_predicate @keg, :optlinked?
end
def test_linked_keg
refute_predicate @keg, :linked?
@keg.link
assert_predicate @keg, :linked?
@keg.unlink
refute_predicate @keg, :linked?
end
def test_unlink_preserves_broken_symlink_pointing_outside_the_keg
@keg.link
@dst.delete
@dst.make_symlink(@nonexistent)
@keg.unlink
assert_predicate @dst, :symlink?
end
def test_unlink_preserves_broken_symlink_pointing_into_the_keg
@keg.link
@dst.resolved_path.delete
@keg.unlink
assert_predicate @dst, :symlink?
end
def test_unlink_preserves_symlink_pointing_outside_of_keg
@keg.link
@dst.delete
@dst.make_symlink(Pathname.new("/bin/sh"))
@keg.unlink
assert_predicate @dst, :symlink?
end
def test_unlink_preserves_real_file
@keg.link
@dst.delete
touch @dst
@keg.unlink
assert_predicate @dst, :file?
end
def test_unlink_ignores_nonexistent_file
@keg.link
@dst.delete
assert_equal 3, @keg.unlink
end
def test_pkgconfig_is_mkpathed
link = HOMEBREW_PREFIX.join("lib", "pkgconfig")
@keg.join("lib", "pkgconfig").mkpath
@keg.link
assert_predicate link.lstat, :directory?
end
def test_cmake_is_mkpathed
link = HOMEBREW_PREFIX.join("lib", "cmake")
@keg.join("lib", "cmake").mkpath
@keg.link
assert_predicate link.lstat, :directory?
end
def test_symlinks_are_linked_directly
link = HOMEBREW_PREFIX.join("lib", "pkgconfig")
@keg.join("lib", "example").mkpath
@keg.join("lib", "pkgconfig").make_symlink "example"
@keg.link
assert_predicate link.resolved_path, :symlink?
assert_predicate link.lstat, :symlink?
end
def test_links_to_symlinks_are_not_removed
a = HOMEBREW_CELLAR.join("a", "1.0")
b = HOMEBREW_CELLAR.join("b", "1.0")
a.join("lib", "example").mkpath
a.join("lib", "example2").make_symlink "example"
b.join("lib", "example2").mkpath
a = Keg.new(a)
b = Keg.new(b)
a.link
lib = HOMEBREW_PREFIX.join("lib")
assert_equal 2, lib.children.length
assert_raises(Keg::ConflictError) { b.link }
assert_equal 2, lib.children.length
ensure
a.unlink
a.uninstall
b.uninstall
end
def test_removes_broken_symlinks_that_conflict_with_directories
a = HOMEBREW_CELLAR.join("a", "1.0")
a.join("lib", "foo").mkpath
keg = Keg.new(a)
link = HOMEBREW_PREFIX.join("lib", "foo")
link.parent.mkpath
link.make_symlink(@nonexistent)
keg.link
ensure
keg.unlink
keg.uninstall
end
end