aboutsummaryrefslogtreecommitdiffstats
path: root/Library/Homebrew
diff options
context:
space:
mode:
authorJack Nagel2014-04-21 09:40:23 -0500
committerJack Nagel2014-04-21 12:43:06 -0500
commit727f2047602a593b57bf4aebc26242fcc63dd4c8 (patch)
tree0cbc241d4982c3621816f57a601c2b6cd475b53a /Library/Homebrew
parentd3ab439b7cdbfa43cdc17b6f8a20458b9bf085c3 (diff)
downloadbrew-727f2047602a593b57bf4aebc26242fcc63dd4c8.tar.bz2
Raise useful errors from make_relative_symlink
Diffstat (limited to 'Library/Homebrew')
-rw-r--r--Library/Homebrew/keg.rb80
-rw-r--r--Library/Homebrew/test/test_keg.rb2
2 files changed, 50 insertions, 32 deletions
diff --git a/Library/Homebrew/keg.rb b/Library/Homebrew/keg.rb
index 8a9779d9b..6c28d964f 100644
--- a/Library/Homebrew/keg.rb
+++ b/Library/Homebrew/keg.rb
@@ -4,6 +4,51 @@ require "formula_lock"
require "ostruct"
class Keg < Pathname
+ class LinkError < RuntimeError
+ attr_reader :keg, :src, :dst
+
+ def initialize(keg, src, dst)
+ @src = src
+ @dst = dst
+ @keg = keg
+ end
+ end
+
+ class ConflictError < LinkError
+ def suggestion
+ conflict = Keg.for(dst)
+ rescue NotAKegError
+ "already exists. You may want to remove it:\n rm #{dst}\n"
+ else
+ <<-EOS.undent
+ is a symlink belonging to #{conflict.fname}. You can unlink it:
+ brew unlink #{conflict.fname}
+ EOS
+ end
+
+ def to_s
+ s = []
+ s << "Could not symlink #{src.relative_path_from(keg)}"
+ s << "Target #{dst}" << suggestion
+ s << <<-EOS.undent
+ To force the link and overwrite all conflicting files:
+ brew link --overwrite #{keg.fname}
+
+ To list all files that would be deleted:
+ brew link --overwrite --dry-run #{keg.fname}
+ EOS
+ s.join("\n")
+ end
+ end
+
+ class DirectoryNotWritableError < LinkError
+ def to_s; <<-EOS.undent
+ Could not symlink #{src.relative_path_from(keg)}
+ #{dst.dirname} is not writable.
+ EOS
+ end
+ end
+
# locale-specific directories have the form language[_territory][.codeset][@modifier]
LOCALEDIR_RX = /(locale|man)\/([a-z]{2}|C|POSIX)(_[A-Z]{2})?(\.[a-zA-Z\-0-9]+(@.+)?)?/
INFOFILE_RX = %r[info/([^.].*?\.info|dir)$]
@@ -252,43 +297,16 @@ class Keg < Pathname
dst.delete if mode.overwrite && (dst.exist? || dst.symlink?)
dst.make_relative_symlink(src)
rescue Errno::EEXIST
- if dst.symlink? && dst.exist?
- raise <<-EOS.undent
- Could not symlink file: #{src}
- Target #{dst} already exists as a symlink to #{dst.readlink}.
- If this file is from another formula, you may need to
- `brew unlink` it. Otherwise, you may want to delete it.
- To force the link and overwrite all other conflicting files, do:
- brew link --overwrite formula_name
-
- To list all files that would be deleted:
- brew link --overwrite --dry-run formula_name
- EOS
- elsif dst.exist?
- raise <<-EOS.undent
- Could not symlink file: #{src}
- Target #{dst} already exists. You may need to delete it.
- To force the link and overwrite all other conflicting files, do:
- brew link --overwrite formula_name
-
- To list all files that would be deleted:
- brew link --overwrite --dry-run formula_name
- EOS
+ if dst.exist?
+ raise ConflictError.new(self, src, dst)
elsif dst.symlink?
dst.unlink
retry
end
rescue Errno::EACCES
- raise <<-EOS.undent
- Could not symlink file: #{src}
- #{dst.dirname} is not writable. You should change its permissions.
- EOS
+ raise DirectoryNotWritableError.new(self, src, dst)
rescue SystemCallError
- raise <<-EOS.undent
- Could not symlink file: #{src}
- #{dst} may already exist.
- #{dst.dirname} may not be writable.
- EOS
+ raise LinkError.new(self, src, dst)
end
# symlinks the contents of self+foo recursively into #{HOMEBREW_PREFIX}/foo
diff --git a/Library/Homebrew/test/test_keg.rb b/Library/Homebrew/test/test_keg.rb
index 4813353e1..0da3a8762 100644
--- a/Library/Homebrew/test/test_keg.rb
+++ b/Library/Homebrew/test/test_keg.rb
@@ -56,7 +56,7 @@ class LinkTests < Test::Unit::TestCase
def test_linking_fails_when_files_exist
touch HOMEBREW_PREFIX/"bin/helloworld"
- assert_raise RuntimeError do
+ assert_raise Keg::ConflictError do
shutup { @keg.link }
end
end