diff --git a/lib/cask/app_linker.rb b/lib/cask/app_linker.rb index d8ac5b5b4..26f092b9c 100644 --- a/lib/cask/app_linker.rb +++ b/lib/cask/app_linker.rb @@ -5,33 +5,29 @@ class Cask end def link - @cask.linkable_apps.each do |app| - link_app(app) - end + @cask.linkable_apps.each { |app| link_app(app) } end def unlink - @cask.linkable_apps.each do |app| - unlink_app(app) - end + @cask.linkable_apps.each { |app| unlink_app(app) } end def unlink_app(app) app_path = Cask.appdir.join(app.basename) - app_path.delete if app_path.exist? - end - - def remove_app_extension(path) - Pathname(path.to_s.sub(/\.app$/, '')) + if app_path.exist? && app_path.symlink? + ohai "Removing link: #{app_path}" + app_path.delete + end end def link_app(app) app_path = Cask.appdir.join(app.basename) - if app_path.directory? + if app_path.directory? && !app_path.symlink? ohai "It seems there is already an app at #{app_path}; not linking." return end - `ln -s "#{app}" "#{app_path}"` + ohai "Linking #{app.basename} to #{app_path}" + system %Q(ln -hfs "#{app}" "#{app_path}") end end end diff --git a/lib/cask/dsl.rb b/lib/cask/dsl.rb index 631748d9c..fd9f51e7a 100644 --- a/lib/cask/dsl.rb +++ b/lib/cask/dsl.rb @@ -1,4 +1,5 @@ require 'formula_support' +require 'set' module Cask::DSL def self.included(base) @@ -29,7 +30,7 @@ module Cask::DSL end def linkables - @linkables ||= Hash.new([]) + @linkables ||= Hash.new(Set.new) end def link(type, *files) diff --git a/test/cask/app_linker_test.rb b/test/cask/app_linker_test.rb index 7b756d663..92e75b49d 100644 --- a/test/cask/app_linker_test.rb +++ b/test/cask/app_linker_test.rb @@ -13,7 +13,9 @@ describe Cask::AppLinker do end it "works with an application in the root directory" do - Cask::AppLinker.new(@caffeine).link + shutup do + Cask::AppLinker.new(@caffeine).link + end TestHelper.valid_alias?(Cask.appdir/'Caffeine.app').must_equal true end @@ -23,7 +25,9 @@ describe Cask::AppLinker do FileUtils.mv @app, appsubdir appinsubdir = appsubdir/'Caffeine.app' - Cask::AppLinker.new(@caffeine).link + shutup do + Cask::AppLinker.new(@caffeine).link + end TestHelper.valid_alias?(Cask.appdir/'Caffeine.app').must_equal true end @@ -31,7 +35,9 @@ describe Cask::AppLinker do it "only uses linkables when they are specified" do FileUtils.cp_r @app, @app.sub('Caffeine.app', 'CaffeineAgain.app') - Cask::AppLinker.new(@caffeine).link + shutup do + Cask::AppLinker.new(@caffeine).link + end TestHelper.valid_alias?(Cask.appdir/'Caffeine.app').must_equal true TestHelper.valid_alias?(Cask.appdir/'CaffeineAgain.app').must_equal false @@ -40,11 +46,21 @@ describe Cask::AppLinker do it "avoids clobbering an existing app by linking over it" do (Cask.appdir/'Caffeine.app').mkpath - shutup do + TestHelper.must_output(self, lambda { Cask::AppLinker.new(@caffeine).link - end + }, "==> It seems there is already an app at #{Cask.appdir.join('Caffeine.app')}; not linking.") + + (Cask.appdir/'Caffeine.app').wont_be :symlink? + end + + it "happily clobbers an existing symlink" do + (Cask.appdir/'Caffeine.app').make_symlink('/tmp') + + TestHelper.must_output(self, lambda { + Cask::AppLinker.new(@caffeine).link + }, "==> Linking Caffeine.app to #{Cask.appdir.join('Caffeine.app')}") - (Cask.appdir/'Caffeine.app').directory?.must_equal true + File.readlink(Cask.appdir/'Caffeine.app').wont_equal '/tmp' end end end diff --git a/test/cask/dsl_test.rb b/test/cask/dsl_test.rb index 3d0eb7fd7..edd540278 100644 --- a/test/cask/dsl_test.rb +++ b/test/cask/dsl_test.rb @@ -57,6 +57,6 @@ describe Cask::DSL do end instance = CaskWithLinkables.new - instance.linkables[:app].must_equal %w[Foo.app Bar.app] + Array(instance.linkables[:app]).must_equal %w[Foo.app Bar.app] end end diff --git a/test/cli/linkapps_test.rb b/test/cli/linkapps_test.rb index 56d85f0ea..27797dbed 100644 --- a/test/cli/linkapps_test.rb +++ b/test/cli/linkapps_test.rb @@ -12,14 +12,18 @@ describe Cask::CLI::Linkapps do end it "only links casks mentioned when arguments are provided" do - Cask::CLI::Linkapps.run('local-transmission') + shutup do + Cask::CLI::Linkapps.run('local-transmission') + end TestHelper.valid_alias?(Cask.appdir/"Transmission.app").must_equal true TestHelper.valid_alias?(Cask.appdir/"Caffeine.app").wont_equal true end it "links all installed casks when no arguments supplied" do - Cask::CLI::Linkapps.run + shutup do + Cask::CLI::Linkapps.run + end TestHelper.valid_alias?(Cask.appdir/"Transmission.app").must_equal true TestHelper.valid_alias?(Cask.appdir/"Caffeine.app").must_equal true diff --git a/test/cli/uninstall_test.rb b/test/cli/uninstall_test.rb index 3f99de20b..a60ca5a4c 100644 --- a/test/cli/uninstall_test.rb +++ b/test/cli/uninstall_test.rb @@ -27,7 +27,9 @@ describe Cask::CLI::Uninstall do caffeine.must_be :installed? transmission.must_be :installed? - Cask::CLI::Uninstall.run('local-caffeine', 'local-transmission') + shutup do + Cask::CLI::Uninstall.run('local-caffeine', 'local-transmission') + end caffeine.wont_be :installed? Cask.appdir.join('Transmission.app').wont_be :symlink? diff --git a/test/cli/unlinkapps_test.rb b/test/cli/unlinkapps_test.rb index 3c8dab3e6..80c7e8a51 100644 --- a/test/cli/unlinkapps_test.rb +++ b/test/cli/unlinkapps_test.rb @@ -9,14 +9,18 @@ describe Cask::CLI::Unlinkapps do end it "only unlinks casks mentioned when arguments are provided" do - Cask::CLI::Unlinkapps.run('local-transmission') + shutup do + Cask::CLI::Unlinkapps.run('local-transmission') + end (Cask.appdir/"Transmission.app").wont_be :symlink? (Cask.appdir/"Caffeine.app").must_be :symlink? end it "unlinks all installed casks when no arguments supplied" do - Cask::CLI::Unlinkapps.run + shutup do + Cask::CLI::Unlinkapps.run + end (Cask.appdir/"Transmission.app").wont_be :symlink? (Cask.appdir/"Caffeine.app").wont_be :symlink?