From 1585d52ddc742527ad7acc6a811ae5745e5db1b4 Mon Sep 17 00:00:00 2001 From: phinze Date: Thu, 4 Apr 2013 22:49:43 -0600 Subject: [PATCH] linkapps 2.0 --- .gitignore | 1 + .ruby-version | 1 - Casks/adium.rb | 2 ++ Casks/firefox.rb | 2 ++ Casks/google-chrome.rb | 2 ++ Casks/skitch.rb | 2 ++ Casks/steam.rb | 2 ++ Casks/vlc.rb | 2 ++ lib/cask.rb | 9 ++++- lib/cask/actions.rb | 19 ----------- lib/cask/app_linker.rb | 37 ++++++++++++++++++++ lib/cask/cli/linkapps.rb | 2 +- lib/cask/dsl.rb | 10 ++++++ test/cask/actions_test.rb | 42 ----------------------- test/cask/app_linker_test.rb | 50 ++++++++++++++++++++++++++++ test/cask/cli_test.rb | 15 +++++++++ test/cask/dsl_test.rb | 11 ++++++ test/cli/linkapps_test.rb | 32 ++++++++---------- test/cli/list_test.rb | 16 --------- test/cli/options_test.rb | 1 - test/support/Casks/local-caffeine.rb | 2 ++ test/support/fake_appdir.rb | 11 +++--- test/test_helper.rb | 8 +++++ 23 files changed, 173 insertions(+), 106 deletions(-) create mode 100644 .gitignore delete mode 100644 .ruby-version delete mode 100644 lib/cask/actions.rb create mode 100644 lib/cask/app_linker.rb delete mode 100644 test/cask/actions_test.rb create mode 100644 test/cask/app_linker_test.rb create mode 100644 test/cask/cli_test.rb diff --git a/.gitignore b/.gitignore new file mode 100644 index 000000000..eaa6e54c0 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.ruby-version diff --git a/.ruby-version b/.ruby-version deleted file mode 100644 index 4ff999b2c..000000000 --- a/.ruby-version +++ /dev/null @@ -1 +0,0 @@ -1.8.7-p358 diff --git a/Casks/adium.rb b/Casks/adium.rb index e6432f8d3..8bfb3745e 100644 --- a/Casks/adium.rb +++ b/Casks/adium.rb @@ -3,4 +3,6 @@ class Adium < Cask homepage 'http://www.adium.im/' version '1.5.4' sha1 '4aff5c040143fb8a8176662c1881815c41874bd0' + + link :app, 'Adium.app' end diff --git a/Casks/firefox.rb b/Casks/firefox.rb index 60522802e..9560ea491 100644 --- a/Casks/firefox.rb +++ b/Casks/firefox.rb @@ -3,4 +3,6 @@ class Firefox < Cask homepage 'http://www.mozilla.org/en-US/firefox/' version '19.0.2' sha1 'b2b64726b2552b9f28c36e8219ff3246a6a15ea4' + + link :app, 'Firefox.app' end diff --git a/Casks/google-chrome.rb b/Casks/google-chrome.rb index 187968833..52dfac8ec 100644 --- a/Casks/google-chrome.rb +++ b/Casks/google-chrome.rb @@ -3,4 +3,6 @@ class GoogleChrome < Cask homepage 'https://www.google.com/chrome/' version 'stable-channel' no_checksum + + link :app, 'Google Chrome.app' end diff --git a/Casks/skitch.rb b/Casks/skitch.rb index b93372930..887d65cd5 100644 --- a/Casks/skitch.rb +++ b/Casks/skitch.rb @@ -3,4 +3,6 @@ class Skitch < Cask homepage 'http://evernote.com/skitch/' version '2.0.5' sha1 '64d61e76eb8bd2540f84b5d21ee1ac5f93c74a61' + + link :app, 'Skitch.app' end diff --git a/Casks/steam.rb b/Casks/steam.rb index d5109ba0c..e359d5ec1 100644 --- a/Casks/steam.rb +++ b/Casks/steam.rb @@ -3,4 +3,6 @@ class Steam < Cask homepage 'http://store.steampowered.com/about/' version 'stable' no_checksum + + link :app, 'Steam.app' end diff --git a/Casks/vlc.rb b/Casks/vlc.rb index fbae9783d..ad7994419 100644 --- a/Casks/vlc.rb +++ b/Casks/vlc.rb @@ -3,4 +3,6 @@ class Vlc < Cask url 'http://downloads.sourceforge.net/project/vlc/2.0.5/macosx/vlc-2.0.5.dmg' version '2.0.5' sha1 'f2d3b240d012f9de6b5f1042a43dccca2c90a0e4' + + link :app, 'VLC.app' end diff --git a/lib/cask.rb b/lib/cask.rb index c41c70a8d..01f1d650a 100644 --- a/lib/cask.rb +++ b/lib/cask.rb @@ -10,7 +10,6 @@ rubyfiles.each do |file| end class Cask - include Cask::Actions include Cask::DSL include Cask::Scopes @@ -85,6 +84,14 @@ class Cask destination_path.exist? end + def linkable_apps + if linkables.has_key? :app + linkables[:app].map { |app| Pathname.glob("#{destination_path}/**/#{app}").first } + else + Pathname.glob("#{destination_path}/**/*.app") + end + end + def to_s @title end diff --git a/lib/cask/actions.rb b/lib/cask/actions.rb deleted file mode 100644 index 1de53bad8..000000000 --- a/lib/cask/actions.rb +++ /dev/null @@ -1,19 +0,0 @@ -module Cask::Actions - def linkapps - Pathname.glob("#{destination_path}/**/*.app").each do |app| - destination = Cask.appdir.join(app.basename) - target = destination_path.join(app) - if destination.symlink? - # destination exists but is symlink; removing and relinking - ohai "[#{self}] linking #{File.basename(destination)}" - destination.delete - destination.make_symlink(target) - elsif destination.directory? || destination.file? - ohai "[#{self}] NOT linking #{File.basename(destination)} - already exists" - else - ohai "[#{self}] linking #{File.basename(destination)}" - destination.make_symlink(target) - end - end - end -end diff --git a/lib/cask/app_linker.rb b/lib/cask/app_linker.rb new file mode 100644 index 000000000..029702a09 --- /dev/null +++ b/lib/cask/app_linker.rb @@ -0,0 +1,37 @@ +class Cask + class AppLinker + def initialize(cask) + @cask = cask + end + + def link + @cask.linkable_apps.each do |app| + link_app(app) + end + end + + def unlink + @cask.linkable_apps.each do |app| + unlink_app(app) + end + 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$/, '')) + end + + def link_app(app) + app_path = Cask.appdir.join(app.basename) + if app_path.directory? + ohai "It seems there is already an app at #{app_path}; not linking." + return + end + `ln -s #{app} #{app_path}` + end + end +end diff --git a/lib/cask/cli/linkapps.rb b/lib/cask/cli/linkapps.rb index 0b7ff9035..4d7b1dcbd 100644 --- a/lib/cask/cli/linkapps.rb +++ b/lib/cask/cli/linkapps.rb @@ -2,7 +2,7 @@ class Cask::CLI::Linkapps def self.run(*args) casks_to_link = args.empty? ? Cask.installed : args casks_to_link.each do |cask_name| - Cask.load(cask_name).linkapps + Cask::AppLinker.new(Cask.load(cask_name)).link end end diff --git a/lib/cask/dsl.rb b/lib/cask/dsl.rb index de29abb96..631748d9c 100644 --- a/lib/cask/dsl.rb +++ b/lib/cask/dsl.rb @@ -13,6 +13,8 @@ module Cask::DSL def sums; self.class.sums || []; end + def linkables; self.class.linkables || {}; end + module ClassMethods def homepage(homepage=nil) @homepage ||= homepage @@ -26,6 +28,14 @@ module Cask::DSL @version ||= version end + def linkables + @linkables ||= Hash.new([]) + end + + def link(type, *files) + linkables[type] += files + end + attr_reader :sums def md5(md5=nil) diff --git a/test/cask/actions_test.rb b/test/cask/actions_test.rb deleted file mode 100644 index 3c4a84996..000000000 --- a/test/cask/actions_test.rb +++ /dev/null @@ -1,42 +0,0 @@ -require 'test_helper' - -describe Cask::Actions do - describe 'linkapps' do - before do - @caffeine = Cask.load('local-caffeine') - shutup { Cask::Installer.install(@caffeine) } - @app = @caffeine.destination_path/'Caffeine.app' - end - - after do - Cask::Installer.uninstall(@caffeine) - end - - it "works with an application in the root directory" do - shutup do - @caffeine.linkapps - end - - expected_symlink = Cask.appdir/'Caffeine.app' - expected_symlink.must_be :exist? - expected_symlink.must_be :symlink? - expected_symlink.readlink.must_equal @app - end - - it "works with an application in a subdir" do - appsubdir = @caffeine.destination_path/'subdir' - appsubdir.mkpath - FileUtils.mv @app, appsubdir - appinsubdir = appsubdir/'Caffeine.app' - - shutup do - @caffeine.linkapps - end - - expected_symlink = Cask.appdir/'Caffeine.app' - expected_symlink.must_be :exist? - expected_symlink.must_be :symlink? - expected_symlink.readlink.must_equal appinsubdir - end - end -end diff --git a/test/cask/app_linker_test.rb b/test/cask/app_linker_test.rb new file mode 100644 index 000000000..7b756d663 --- /dev/null +++ b/test/cask/app_linker_test.rb @@ -0,0 +1,50 @@ +require 'test_helper' + +describe Cask::AppLinker do + describe 'linkapps' do + before do + @caffeine = Cask.load('local-caffeine') + shutup { Cask::Installer.install(@caffeine) } + @app = @caffeine.destination_path/'Caffeine.app' + end + + after do + Cask::Installer.uninstall(@caffeine) + end + + it "works with an application in the root directory" do + Cask::AppLinker.new(@caffeine).link + TestHelper.valid_alias?(Cask.appdir/'Caffeine.app').must_equal true + end + + it "works with an application in a subdir" do + appsubdir = @caffeine.destination_path/'subdir' + appsubdir.mkpath + FileUtils.mv @app, appsubdir + appinsubdir = appsubdir/'Caffeine.app' + + Cask::AppLinker.new(@caffeine).link + + TestHelper.valid_alias?(Cask.appdir/'Caffeine.app').must_equal true + end + + it "only uses linkables when they are specified" do + FileUtils.cp_r @app, @app.sub('Caffeine.app', 'CaffeineAgain.app') + + Cask::AppLinker.new(@caffeine).link + + TestHelper.valid_alias?(Cask.appdir/'Caffeine.app').must_equal true + TestHelper.valid_alias?(Cask.appdir/'CaffeineAgain.app').must_equal false + end + + it "avoids clobbering an existing app by linking over it" do + (Cask.appdir/'Caffeine.app').mkpath + + shutup do + Cask::AppLinker.new(@caffeine).link + end + + (Cask.appdir/'Caffeine.app').directory?.must_equal true + end + end +end diff --git a/test/cask/cli_test.rb b/test/cask/cli_test.rb new file mode 100644 index 000000000..23eaf0cf9 --- /dev/null +++ b/test/cask/cli_test.rb @@ -0,0 +1,15 @@ +require 'test_helper' + +describe Cask::CLI do + it "lists the taps for casks that show up in two taps" do + Cask::CLI.nice_listing(%w[ + phinze-cask/adium + phinze-cask/google-chrome + passcod-cask/adium + ]).must_equal(%w[ + google-chrome + passcod-cask/adium + phinze-cask/adium + ]) + end +end diff --git a/test/cask/dsl_test.rb b/test/cask/dsl_test.rb index 1b93ad425..fce04ba4e 100644 --- a/test/cask/dsl_test.rb +++ b/test/cask/dsl_test.rb @@ -48,4 +48,15 @@ describe Cask::DSL do flunk("Wanted unexpected method to simply warn, but got exception #{e}") end end + + it "allows you to specify linkables" do + CaskWithLinkables = Class.new(Cask) + CaskWithLinkables.class_eval do + link :app, 'Foo.app' + link :app, 'Bar.app' + end + + instance = CaskWithLinkables.new + 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 adcea0855..56d85f0ea 100644 --- a/test/cli/linkapps_test.rb +++ b/test/cli/linkapps_test.rb @@ -1,33 +1,27 @@ require 'test_helper' describe Cask::CLI::Linkapps do - it "only links casks mentioned when arguments are provided" do - caffeine = Cask.load('local-caffeine') - transmission = Cask.load('local-transmission') - + before do shutup do + caffeine = Cask.load('local-caffeine') + transmission = Cask.load('local-transmission') + Cask::Installer.install caffeine Cask::Installer.install transmission - - Cask::CLI::Linkapps.run('local-transmission') end - - (Cask.appdir/"Transmission.app").must_be :symlink? - (Cask.appdir/"Caffeine.app").wont_be :symlink? end - it "links all installed casks when no arguments supplied" do - caffeine = Cask.load('local-caffeine') - transmission = Cask.load('local-transmission') + it "only links casks mentioned when arguments are provided" do + Cask::CLI::Linkapps.run('local-transmission') - shutup do - Cask::Installer.install caffeine - Cask::Installer.install transmission + TestHelper.valid_alias?(Cask.appdir/"Transmission.app").must_equal true + TestHelper.valid_alias?(Cask.appdir/"Caffeine.app").wont_equal true + end - Cask::CLI::Linkapps.run - end + it "links all installed casks when no arguments supplied" do + Cask::CLI::Linkapps.run - (Cask.appdir/"Transmission.app").must_be :symlink? - (Cask.appdir/"Caffeine.app").must_be :symlink? + TestHelper.valid_alias?(Cask.appdir/"Transmission.app").must_equal true + TestHelper.valid_alias?(Cask.appdir/"Caffeine.app").must_equal true end end diff --git a/test/cli/list_test.rb b/test/cli/list_test.rb index ad51b9118..2d8339a50 100644 --- a/test/cli/list_test.rb +++ b/test/cli/list_test.rb @@ -13,20 +13,4 @@ describe Cask::CLI::List do local-transmission OUTPUT end - - it "lists the taps for casks that show up in two taps" do - skip("need to move this implementation to an easier to test location") - Cask.stubs(:installed).returns(%w[ - phinze-cask/adium - phinze-cask/google-chrome - passcod-cask/adium - ]) - lambda { - Cask::CLI::List.run - }.must_output <<-OUTPUT.gsub(/^ */, '') - google-chrome - passcod-cask/adium - phinze-cask/adium - OUTPUT - end end diff --git a/test/cli/options_test.rb b/test/cli/options_test.rb index 0727fbc07..1758cf371 100644 --- a/test/cli/options_test.rb +++ b/test/cli/options_test.rb @@ -24,6 +24,5 @@ describe Cask::CLI do after do ENV['HOMEBREW_CASK_OPTS'] = nil - Cask.appdir = CANNED_APPDIR end end diff --git a/test/support/Casks/local-caffeine.rb b/test/support/Casks/local-caffeine.rb index 45921ca81..a1dafcf54 100644 --- a/test/support/Casks/local-caffeine.rb +++ b/test/support/Casks/local-caffeine.rb @@ -3,5 +3,7 @@ class LocalCaffeine < Cask homepage 'http://example.com/local-caffeine' version '1.2.3' sha1 'd2fbdad1619934313026fc831e6c6e3dd97ac030' + + link :app, 'Caffeine.app' end diff --git a/test/support/fake_appdir.rb b/test/support/fake_appdir.rb index 92a207a56..c1b510926 100644 --- a/test/support/fake_appdir.rb +++ b/test/support/fake_appdir.rb @@ -1,16 +1,15 @@ -# wire in a fake appdir for linkapps -CANNED_APPDIR = (HOMEBREW_REPOSITORY/"Applications") -Cask.appdir = CANNED_APPDIR - +# wire in a fake appdir per-test module FakeAppdirHooks def before_setup super - CANNED_APPDIR.mkdir + @canned_appdir = HOMEBREW_REPOSITORY/"Applications-#{Time.now.to_i}-#{rand(1024)}" + @canned_appdir.mkpath + Cask.appdir = @canned_appdir end def after_teardown super - FileUtils.rm_rf(CANNED_APPDIR) + @canned_appdir.rmtree end end diff --git a/test/test_helper.rb b/test/test_helper.rb index 4dbfbc145..62cce03c0 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -28,6 +28,9 @@ require 'cask' # look for casks in testcasks by default Cask.default_tap = 'phinze-testcasks' +# silence some extraneous UI messages for tests +ENV['QUIET_TESTS'] = '1' + class TestHelper # helper for test casks to reference local files easily def self.local_binary(name) @@ -54,6 +57,11 @@ class TestHelper (out+err).chomp.must_equal expected.gsub(/^ */, '') end + + def self.valid_alias?(candidate) + return false unless candidate.symlink? + candidate.readlink.exist? + end end require 'support/fake_fetcher'