cleaner: clean up broken and orphaned symlinks
This commit is contained in:
parent
f55e93d9fc
commit
d19934dcb7
@ -22,28 +22,36 @@ class Cleaner
|
|||||||
f.info.rmtree if f.info.directory? and not f.skip_clean? f.info
|
f.info.rmtree if f.info.directory? and not f.skip_clean? f.info
|
||||||
end
|
end
|
||||||
|
|
||||||
# Remove empty folders.
|
prune
|
||||||
# We want post-order traversal, so use a stack.
|
|
||||||
paths = []
|
|
||||||
f.prefix.find do |path|
|
|
||||||
if path.directory?
|
|
||||||
if f.skip_clean? path
|
|
||||||
Find.prune
|
|
||||||
else
|
|
||||||
paths << path
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def prune
|
||||||
|
dirs = []
|
||||||
|
symlinks = []
|
||||||
|
|
||||||
|
@f.prefix.find do |path|
|
||||||
|
if @f.skip_clean? path
|
||||||
|
Find.prune
|
||||||
|
elsif path.symlink?
|
||||||
|
symlinks << path
|
||||||
|
elsif path.directory?
|
||||||
|
dirs << path
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
paths.reverse_each do |d|
|
dirs.reverse_each do |d|
|
||||||
if d.children.empty? and not f.skip_clean? d
|
if d.children.empty?
|
||||||
puts "rmdir: #{d} (empty)" if ARGV.verbose?
|
puts "rmdir: #{d} (empty)" if ARGV.verbose?
|
||||||
d.rmdir
|
d.rmdir
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
|
||||||
|
|
||||||
private
|
symlinks.reverse_each do |s|
|
||||||
|
s.unlink unless s.resolved_path_exists?
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
# Set permissions for executables and non-executables
|
# Set permissions for executables and non-executables
|
||||||
def clean_file_permissions path
|
def clean_file_permissions path
|
||||||
|
@ -63,22 +63,80 @@ class CleanerTests < Test::Unit::TestCase
|
|||||||
assert subdir.directory?
|
assert subdir.directory?
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_fails_to_remove_symlink_when_target_was_pruned_first
|
def test_removes_symlink_when_target_was_pruned_first
|
||||||
mkpath @f.prefix/'b'
|
dir = @f.prefix/'b'
|
||||||
ln_s 'b', @f.prefix/'a'
|
symlink = @f.prefix/'a'
|
||||||
assert_raises(Errno::ENOENT) { Cleaner.new @f }
|
|
||||||
end
|
|
||||||
|
|
||||||
def test_fails_to_remove_symlink_pointing_to_empty_directory
|
dir.mkpath
|
||||||
mkpath @f.prefix/'b'
|
ln_s dir.basename, symlink
|
||||||
ln_s 'b', @f.prefix/'c'
|
|
||||||
assert_raises(Errno::ENOTDIR) { Cleaner.new @f }
|
|
||||||
end
|
|
||||||
|
|
||||||
def test_fails_to_remove_broken_symlink
|
|
||||||
ln_s 'target', @f.prefix/'symlink'
|
|
||||||
Cleaner.new @f
|
Cleaner.new @f
|
||||||
assert @f.prefix.join('symlink').symlink?, "not a symlink"
|
|
||||||
assert !@f.prefix.join('symlink').exist?, "target exists"
|
assert !dir.exist?
|
||||||
|
assert !symlink.symlink?
|
||||||
|
assert !symlink.exist?
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_removes_symlink_pointing_to_empty_directory
|
||||||
|
dir = @f.prefix/'b'
|
||||||
|
symlink = @f.prefix/'c'
|
||||||
|
|
||||||
|
dir.mkpath
|
||||||
|
ln_s dir.basename, symlink
|
||||||
|
|
||||||
|
Cleaner.new @f
|
||||||
|
|
||||||
|
assert !dir.exist?
|
||||||
|
assert !symlink.symlink?
|
||||||
|
assert !symlink.exist?
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_removes_broken_symlinks
|
||||||
|
symlink = @f.prefix/'symlink'
|
||||||
|
ln_s 'target', symlink
|
||||||
|
|
||||||
|
Cleaner.new @f
|
||||||
|
|
||||||
|
assert !symlink.symlink?
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_skip_clean_broken_symlink
|
||||||
|
@f.class.skip_clean 'symlink'
|
||||||
|
symlink = @f.prefix/'symlink'
|
||||||
|
ln_s 'target', symlink
|
||||||
|
|
||||||
|
Cleaner.new @f
|
||||||
|
|
||||||
|
assert symlink.symlink?
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_skip_clean_symlink_pointing_to_empty_directory
|
||||||
|
@f.class.skip_clean 'c'
|
||||||
|
dir = @f.prefix/'b'
|
||||||
|
symlink = @f.prefix/'c'
|
||||||
|
|
||||||
|
dir.mkpath
|
||||||
|
ln_s dir.basename, symlink
|
||||||
|
|
||||||
|
Cleaner.new @f
|
||||||
|
|
||||||
|
assert !dir.exist?
|
||||||
|
assert symlink.symlink?
|
||||||
|
assert !symlink.exist?
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_skip_clean_symlink_when_target_pruned
|
||||||
|
@f.class.skip_clean 'a'
|
||||||
|
dir = @f.prefix/'b'
|
||||||
|
symlink = @f.prefix/'a'
|
||||||
|
|
||||||
|
dir.mkpath
|
||||||
|
ln_s dir.basename, symlink
|
||||||
|
|
||||||
|
Cleaner.new @f
|
||||||
|
|
||||||
|
assert !dir.exist?
|
||||||
|
assert symlink.symlink?
|
||||||
|
assert !symlink.exist?
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
Loading…
x
Reference in New Issue
Block a user