Browse Source

linkapps 2.0

phinze 12 years ago
parent
commit
1585d52ddc
  1. 1
      .gitignore
  2. 1
      .ruby-version
  3. 2
      Casks/adium.rb
  4. 2
      Casks/firefox.rb
  5. 2
      Casks/google-chrome.rb
  6. 2
      Casks/skitch.rb
  7. 2
      Casks/steam.rb
  8. 2
      Casks/vlc.rb
  9. 9
      lib/cask.rb
  10. 19
      lib/cask/actions.rb
  11. 37
      lib/cask/app_linker.rb
  12. 2
      lib/cask/cli/linkapps.rb
  13. 10
      lib/cask/dsl.rb
  14. 42
      test/cask/actions_test.rb
  15. 50
      test/cask/app_linker_test.rb
  16. 15
      test/cask/cli_test.rb
  17. 11
      test/cask/dsl_test.rb
  18. 32
      test/cli/linkapps_test.rb
  19. 16
      test/cli/list_test.rb
  20. 1
      test/cli/options_test.rb
  21. 2
      test/support/Casks/local-caffeine.rb
  22. 11
      test/support/fake_appdir.rb
  23. 8
      test/test_helper.rb

1
.gitignore

@ -0,0 +1 @@
.ruby-version

1
.ruby-version

@ -1 +0,0 @@
1.8.7-p358

2
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

2
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

2
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

2
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

2
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

2
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

9
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

19
lib/cask/actions.rb

@ -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

37
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

2
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

10
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)

42
test/cask/actions_test.rb

@ -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

50
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

15
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

11
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

32
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

16
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

1
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

2
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

11
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

8
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'

Loading…
Cancel
Save