Fix `brew cask alfred` for Yosemite/Alfred 2.4
Closes #5820 References: #6059
This commit is contained in:
parent
3a3e4945c3
commit
0f664ca78a
|
@ -10,8 +10,12 @@ class Cask::CLI::Alfred < Cask::CLI::Base
|
|||
'~/Library/Mobile Documents/',
|
||||
'~/Library/PreferencePanes'
|
||||
]
|
||||
DOMAIN = "com.runningwithcrayons.Alfred-Preferences"
|
||||
KEY = "features.defaultresults.scope"
|
||||
PRIMARY_DOMAIN = 'com.runningwithcrayons.Alfred-Preferences'
|
||||
PRIMARY_SCOPES_KEY = 'features.defaultresults.scope'
|
||||
|
||||
# http://www.alfredforum.com/topic/4810-alfred%E2%80%99s-scope-can-no-longer-be-changed-programatically/?p=29434
|
||||
LOCALPREFS_SCOPES_FILEGLOB = '~/Library/Application Support/Alfred 2/Alfred.alfredpreferences/preferences/local/*/features/defaultresults/prefs.plist'
|
||||
LOCALPREFS_SCOPES_KEY = 'scope'
|
||||
|
||||
def self.run(*args)
|
||||
subcommand = args.first
|
||||
|
@ -23,9 +27,9 @@ class Cask::CLI::Alfred < Cask::CLI::Base
|
|||
end
|
||||
|
||||
case subcommand
|
||||
when "link" then link
|
||||
when "unlink" then unlink
|
||||
when "status" then status
|
||||
when 'link' then link
|
||||
when 'unlink' then unlink
|
||||
when 'status' then status
|
||||
else
|
||||
usage
|
||||
end
|
||||
|
@ -36,34 +40,36 @@ class Cask::CLI::Alfred < Cask::CLI::Base
|
|||
end
|
||||
|
||||
def self.assert_installed
|
||||
if !alfred_installed?
|
||||
opoo "Could not find Alfred 2 preferences, Alfred 2 is probably not installed."
|
||||
unless alfred_2_installed?
|
||||
opoo "Could not find Alfred 2 preferences. Alfred 2 is probably not installed."
|
||||
end
|
||||
alfred_installed?
|
||||
if alfred_localprefs? and localprefs_scopes_files.size < 1
|
||||
raise CaskError.new "Alfred 2.4+ detected, but local preferences file not found. Try running Alfred first."
|
||||
end
|
||||
alfred_2_installed?
|
||||
end
|
||||
|
||||
def self.link
|
||||
return unless assert_installed
|
||||
|
||||
if linked?
|
||||
opoo "Alfred is already linked to homebrew-cask."
|
||||
else
|
||||
odebug 'Linking Alfred scopes'
|
||||
save_alfred_scopes(alfred_scopes << Cask.caskroom)
|
||||
ohai "Successfully linked Alfred to homebrew-cask."
|
||||
opoo "Alfred appears to be already linked. Updating defaults anyway."
|
||||
end
|
||||
odebug 'Linking Alfred scopes'
|
||||
# this silly ternary operation is for precise compat with Ruby 1.8
|
||||
save_alfred_scopes( alfred_scopes.include?(Cask.caskroom.to_s) ? alfred_scopes : alfred_scopes + [ Cask.caskroom.to_s ])
|
||||
ohai "Successfully linked Alfred to homebrew-cask."
|
||||
end
|
||||
|
||||
def self.unlink
|
||||
return unless assert_installed
|
||||
|
||||
if !linked?
|
||||
opoo "Alfred is already unlinked from homebrew-cask."
|
||||
else
|
||||
odebug 'Unlinking Alfred scopes'
|
||||
save_alfred_scopes(alfred_scopes.reject { |x| x == Cask.caskroom.to_s })
|
||||
ohai "Successfully unlinked Alfred from homebrew-cask."
|
||||
unless linked?
|
||||
opoo "Alfred appears to be already unlinked. Updating defaults anyway."
|
||||
end
|
||||
odebug 'Unlinking Alfred scopes'
|
||||
save_alfred_scopes(alfred_scopes.reject { |x| x == Cask.caskroom.to_s })
|
||||
ohai "Successfully unlinked Alfred from homebrew-cask."
|
||||
end
|
||||
|
||||
def self.status
|
||||
|
@ -74,14 +80,38 @@ class Cask::CLI::Alfred < Cask::CLI::Base
|
|||
else
|
||||
ohai "Alfred is not linked to homebrew-cask."
|
||||
end
|
||||
if alfred_localprefs? and localprefs_scopes_files.size > 1
|
||||
opoo "Multiple local preference files detected. 'brew cask alfred status' may be inaccurate."
|
||||
end
|
||||
end
|
||||
|
||||
def self.save_alfred_scopes(scopes)
|
||||
alfred_preference(KEY, "(#{scopes.map { |s| "'#{s}'" }.join(",")})")
|
||||
alfred_preference(PRIMARY_SCOPES_KEY, %Q{(#{scopes.map { |s| "'#{s}'" }.join(',')})})
|
||||
end
|
||||
|
||||
def self.alfred_installed?
|
||||
alfred_preference('version') =~ /^2\.[0-9]/
|
||||
def self.alfred_version
|
||||
begin
|
||||
# reset the version every time when running under the test harness
|
||||
# todo: I don't know the right way to detect that; using const_get
|
||||
Cask.const_get(:FakeSystemCommand)
|
||||
@alfred_version = nil
|
||||
rescue
|
||||
end
|
||||
return @alfred_version if @alfred_version
|
||||
v = alfred_primary_preference('version')
|
||||
@alfred_version = begin
|
||||
Gem::Version.new(v).to_s.to_f
|
||||
rescue
|
||||
0
|
||||
end
|
||||
end
|
||||
|
||||
def self.alfred_2_installed?
|
||||
alfred_version >= 2.0
|
||||
end
|
||||
|
||||
def self.alfred_localprefs?
|
||||
alfred_version >= 2.4
|
||||
end
|
||||
|
||||
def self.linked?
|
||||
|
@ -98,24 +128,53 @@ class Cask::CLI::Alfred < Cask::CLI::Base
|
|||
SCOPE_REGEXP = /^\s*"(.*)",?$/
|
||||
|
||||
def self.alfred_scopes
|
||||
scopes = alfred_preference(KEY).split("\n").map do |line|
|
||||
matchdata = line.match(SCOPE_REGEXP)
|
||||
matchdata ? matchdata.captures.first : nil
|
||||
scopes = alfred_preference(PRIMARY_SCOPES_KEY).split("\n").map do |line|
|
||||
$1 if line.match(SCOPE_REGEXP)
|
||||
end.compact
|
||||
|
||||
scopes.empty? ? DEFAULT_SCOPES : scopes
|
||||
end
|
||||
|
||||
def self.localprefs_scopes_files
|
||||
# local prefs file is used in Alfred 2.4 and above for Yosemite compatibility
|
||||
Pathname.glob(Pathname.new(LOCALPREFS_SCOPES_FILEGLOB).expand_path)
|
||||
end
|
||||
|
||||
def self.alfred_preference(key, value=nil)
|
||||
if value
|
||||
odebug 'Writing Alfred preferences'
|
||||
@system_command.run('/usr/bin/defaults', :args => ['write', DOMAIN, key, %Q(#{value})])
|
||||
if alfred_localprefs? and key == PRIMARY_SCOPES_KEY
|
||||
alfred_file_preference(localprefs_scopes_files, LOCALPREFS_SCOPES_KEY, value)
|
||||
else
|
||||
odebug 'Reading Alfred preferences'
|
||||
@system_command.run('/usr/bin/defaults', :args => ['read', DOMAIN, key])
|
||||
alfred_primary_preference(key, value)
|
||||
end
|
||||
end
|
||||
|
||||
def self.alfred_primary_preference(key, value=nil)
|
||||
if value
|
||||
odebug 'Writing Alfred primary preferences'
|
||||
@system_command.run('/usr/bin/defaults', :args => ['write', PRIMARY_DOMAIN, key, value.to_s])
|
||||
else
|
||||
odebug 'Reading Alfred primary preferences'
|
||||
@system_command.run('/usr/bin/defaults', :args => ['read', PRIMARY_DOMAIN, key])
|
||||
end
|
||||
end
|
||||
|
||||
def self.alfred_file_preference(files, key, value=nil)
|
||||
unless files and files.length > 0
|
||||
raise CaskError.new "Required 'files' argument empty"
|
||||
end
|
||||
Array(files).map do |file|
|
||||
if value
|
||||
odebug 'Writing Alfred local preferences'
|
||||
@system_command.run('/usr/bin/defaults', :args => ['write', file, key, value.to_s])
|
||||
else
|
||||
odebug 'Reading Alfred local preferences'
|
||||
@system_command.run('/usr/bin/defaults', :args => ['read', file, key])
|
||||
end
|
||||
# hack/limitation: if there happen to be multiple local preference
|
||||
# files, we only return the value from the first one.
|
||||
end.first
|
||||
end
|
||||
|
||||
def self.usage
|
||||
ohai 'brew cask alfred', <<-ALFREDHELP.undent
|
||||
manages integration with Alfred; allows applications installed with
|
||||
|
|
|
@ -1,14 +1,43 @@
|
|||
require 'test_helper'
|
||||
|
||||
def fake_alfred_preference(key, response)
|
||||
# slightly different format for read/write
|
||||
scope = (Cask::CLI::Alfred::DEFAULT_SCOPES).map { |s| %Q{"#{s}"} }
|
||||
DEFAULT_READ_SCOPE = %Q{(\n#{scope.join(",\n ")}\n)}
|
||||
scope = (Cask::CLI::Alfred::DEFAULT_SCOPES + [Cask.caskroom.to_s]).map { |s| %Q{"#{s}"} }
|
||||
ALTERED_READ_SCOPE = %Q{(\n#{scope.join(",\n ")}\n)}
|
||||
|
||||
scope = (Cask::CLI::Alfred::DEFAULT_SCOPES).map { |s| %Q{'#{s}'} }
|
||||
DEFAULT_WRITE_SCOPE = %Q{(#{scope.join(',')})}
|
||||
scope = (Cask::CLI::Alfred::DEFAULT_SCOPES + [Cask.caskroom.to_s]).map { |s| %Q{'#{s}'} }
|
||||
ALTERED_WRITE_SCOPE = %Q{(#{scope.join(',')})}
|
||||
|
||||
def fake_alfred_read_primary_preference(key, response)
|
||||
Cask::FakeSystemCommand.stubs_command(['/usr/bin/defaults', 'read', 'com.runningwithcrayons.Alfred-Preferences', key], response)
|
||||
end
|
||||
|
||||
def fake_alfred_write_primary_preference(key, value)
|
||||
Cask::FakeSystemCommand.stubs_command(['/usr/bin/defaults', 'write', 'com.runningwithcrayons.Alfred-Preferences', key, value])
|
||||
end
|
||||
|
||||
def fake_alfred_read_local_preference(key, response)
|
||||
local_files = Pathname.glob(Pathname.new(Cask::CLI::Alfred::LOCALPREFS_SCOPES_FILEGLOB).expand_path)
|
||||
local_files.each do |file|
|
||||
Cask::FakeSystemCommand.stubs_command(['/usr/bin/defaults', 'read', file, key], response)
|
||||
end
|
||||
end
|
||||
|
||||
def fake_alfred_write_local_preference(key, value)
|
||||
local_files = Pathname.glob(Pathname.new(Cask::CLI::Alfred::LOCALPREFS_SCOPES_FILEGLOB).expand_path)
|
||||
local_files.each do |file|
|
||||
Cask::FakeSystemCommand.stubs_command(['/usr/bin/defaults', 'write', file, key, value])
|
||||
end
|
||||
end
|
||||
|
||||
def fake_alfred_installed(installed=true)
|
||||
if installed
|
||||
fake_alfred_preference 'version', '2.0.3'
|
||||
fake_alfred_read_primary_preference 'version', '2.0.3'
|
||||
else
|
||||
fake_alfred_preference 'version', <<-VERSION.undent
|
||||
fake_alfred_read_primary_preference 'version', <<-VERSION.undent
|
||||
2013-05-11 13:32:51.086 defaults[5072:707]
|
||||
The domain/default pair of (com.runningwithcrayons.Alfred-Preferences, version) does not exist
|
||||
VERSION
|
||||
|
@ -19,22 +48,17 @@ describe Cask::CLI::Alfred do
|
|||
describe "status" do
|
||||
it "properly reports when alfred is not installed" do
|
||||
fake_alfred_installed(false)
|
||||
fake_alfred_read_local_preference('scope', DEFAULT_READ_SCOPE)
|
||||
|
||||
TestHelper.must_output(self, lambda {
|
||||
Cask::CLI::Alfred.run('status', Cask::FakeSystemCommand)
|
||||
}, "Warning: Could not find Alfred 2 preferences, Alfred 2 is probably not installed.")
|
||||
}, "Warning: Could not find Alfred 2 preferences. Alfred 2 is probably not installed.")
|
||||
end
|
||||
|
||||
it "properly reports when alfred is installed but unlinked" do
|
||||
fake_alfred_installed(true)
|
||||
|
||||
fake_alfred_preference 'features.defaultresults.scope', <<-SCOPE_RESPONSE.undent
|
||||
(
|
||||
"/Applications",
|
||||
"/Library/PreferencePanes",
|
||||
"/System/Library/PreferencePanes"
|
||||
)
|
||||
SCOPE_RESPONSE
|
||||
fake_alfred_read_primary_preference 'features.defaultresults.scope', DEFAULT_READ_SCOPE
|
||||
|
||||
TestHelper.must_output(self, lambda {
|
||||
Cask::CLI::Alfred.run('status', Cask::FakeSystemCommand)
|
||||
|
@ -48,38 +72,28 @@ describe Cask::CLI::Alfred do
|
|||
|
||||
TestHelper.must_output(self, lambda {
|
||||
Cask::CLI::Alfred.run('link', Cask::FakeSystemCommand)
|
||||
}, "Warning: Could not find Alfred 2 preferences, Alfred 2 is probably not installed.")
|
||||
}, "Warning: Could not find Alfred 2 preferences. Alfred 2 is probably not installed.")
|
||||
end
|
||||
|
||||
it "warns when alfred is already linked" do
|
||||
fake_alfred_installed(true)
|
||||
fake_alfred_preference 'features.defaultresults.scope', <<-SCOPE_RESPONSE.undent
|
||||
(
|
||||
"/Applications",
|
||||
"/Library/PreferencePanes",
|
||||
"#{Cask.caskroom}",
|
||||
"/System/Library/PreferencePanes"
|
||||
)
|
||||
SCOPE_RESPONSE
|
||||
fake_alfred_read_primary_preference 'features.defaultresults.scope', ALTERED_READ_SCOPE
|
||||
fake_alfred_read_local_preference 'scope', ALTERED_READ_SCOPE
|
||||
fake_alfred_write_primary_preference 'features.defaultresults.scope', ALTERED_WRITE_SCOPE
|
||||
fake_alfred_write_local_preference 'scope', ALTERED_WRITE_SCOPE
|
||||
|
||||
# todo: the message text is out of expected order because of mixing STDERR/STDOUT
|
||||
TestHelper.must_output(self, lambda {
|
||||
Cask::CLI::Alfred.run('link', Cask::FakeSystemCommand)
|
||||
}, "Warning: Alfred is already linked to homebrew-cask.")
|
||||
}, "==> Successfully linked Alfred to homebrew-cask.\nWarning: Alfred appears to be already linked. Updating defaults anyway.")
|
||||
end
|
||||
|
||||
it "links when it needs to" do
|
||||
fake_alfred_installed(true)
|
||||
fake_alfred_preference 'features.defaultresults.scope', <<-SCOPE_RESPONSE.undent
|
||||
(
|
||||
"/Applications",
|
||||
"/Library/PreferencePanes",
|
||||
"/System/Library/PreferencePanes"
|
||||
)
|
||||
SCOPE_RESPONSE
|
||||
|
||||
Cask::FakeSystemCommand.stubs_command(
|
||||
['/usr/bin/defaults', 'write', 'com.runningwithcrayons.Alfred-Preferences', 'features.defaultresults.scope', %Q{('/Applications','/Library/PreferencePanes','/System/Library/PreferencePanes','#{Cask.caskroom}')}]
|
||||
)
|
||||
fake_alfred_read_primary_preference 'features.defaultresults.scope', DEFAULT_READ_SCOPE
|
||||
fake_alfred_read_local_preference 'scope', DEFAULT_READ_SCOPE
|
||||
fake_alfred_write_primary_preference 'features.defaultresults.scope', ALTERED_WRITE_SCOPE
|
||||
fake_alfred_write_local_preference 'scope', ALTERED_WRITE_SCOPE
|
||||
|
||||
TestHelper.must_output(self, lambda {
|
||||
Cask::CLI::Alfred.run('link', Cask::FakeSystemCommand)
|
||||
|
@ -88,15 +102,17 @@ describe Cask::CLI::Alfred do
|
|||
|
||||
it "links with default scopes if the preference hasn't been customized" do
|
||||
fake_alfred_installed(true)
|
||||
fake_alfred_preference 'features.defaultresults.scope', <<-SCOPE_RESPONSE.undent
|
||||
fake_alfred_read_primary_preference 'features.defaultresults.scope', <<-SCOPE_RESPONSE.undent
|
||||
2013-05-11 13:32:51.086 defaults[5072:707]
|
||||
The domain/default pair of (com.runningwithcrayons.Alfred-Preferences, features.defaultresults.scope) does not exist
|
||||
SCOPE_RESPONSE
|
||||
fake_alfred_read_local_preference 'scope', <<-SCOPE_RESPONSE.undent
|
||||
2013-05-11 13:32:51.086 defaults[5072:707]
|
||||
The domain/default pair of (<file>, scope) does not exist
|
||||
SCOPE_RESPONSE
|
||||
|
||||
expected_scopes = (Cask::CLI::Alfred::DEFAULT_SCOPES + [Cask.caskroom]).map { |s| "'#{s}'" }
|
||||
Cask::FakeSystemCommand.stubs_command(
|
||||
['/usr/bin/defaults', 'write', 'com.runningwithcrayons.Alfred-Preferences', 'features.defaultresults.scope', %Q{(#{expected_scopes.join(',')})}]
|
||||
)
|
||||
fake_alfred_write_primary_preference 'features.defaultresults.scope', ALTERED_WRITE_SCOPE
|
||||
fake_alfred_write_local_preference 'scope', ALTERED_WRITE_SCOPE
|
||||
|
||||
TestHelper.must_output(self, lambda {
|
||||
Cask::CLI::Alfred.run('link', Cask::FakeSystemCommand)
|
||||
|
@ -110,38 +126,28 @@ describe Cask::CLI::Alfred do
|
|||
|
||||
TestHelper.must_output(self, lambda {
|
||||
Cask::CLI::Alfred.run('unlink', Cask::FakeSystemCommand)
|
||||
}, "Warning: Could not find Alfred 2 preferences, Alfred 2 is probably not installed.")
|
||||
}, "Warning: Could not find Alfred 2 preferences. Alfred 2 is probably not installed.")
|
||||
end
|
||||
|
||||
it "warns when alfred is already unlinked" do
|
||||
fake_alfred_installed(true)
|
||||
fake_alfred_preference 'features.defaultresults.scope', <<-SCOPE_RESPONSE.undent
|
||||
(
|
||||
"/Applications",
|
||||
"/Library/PreferencePanes",
|
||||
"/System/Library/PreferencePanes"
|
||||
)
|
||||
SCOPE_RESPONSE
|
||||
fake_alfred_read_primary_preference 'features.defaultresults.scope', DEFAULT_READ_SCOPE
|
||||
fake_alfred_read_local_preference 'scope', DEFAULT_READ_SCOPE
|
||||
fake_alfred_write_primary_preference 'features.defaultresults.scope', DEFAULT_WRITE_SCOPE
|
||||
fake_alfred_write_local_preference 'scope', DEFAULT_WRITE_SCOPE
|
||||
|
||||
# todo: the message text is out of expected order because of mixing STDERR/STDOUT
|
||||
TestHelper.must_output(self, lambda {
|
||||
Cask::CLI::Alfred.run('unlink', Cask::FakeSystemCommand)
|
||||
}, "Warning: Alfred is already unlinked from homebrew-cask.")
|
||||
}, "==> Successfully unlinked Alfred from homebrew-cask.\nWarning: Alfred appears to be already unlinked. Updating defaults anyway.")
|
||||
end
|
||||
|
||||
it "unlinks when it needs to" do
|
||||
fake_alfred_installed(true)
|
||||
fake_alfred_preference 'features.defaultresults.scope', <<-SCOPE_RESPONSE.undent
|
||||
(
|
||||
"/Applications",
|
||||
"/Library/PreferencePanes",
|
||||
"#{Cask.caskroom}",
|
||||
"/System/Library/PreferencePanes"
|
||||
)
|
||||
SCOPE_RESPONSE
|
||||
|
||||
Cask::FakeSystemCommand.stubs_command(
|
||||
['/usr/bin/defaults', 'write', 'com.runningwithcrayons.Alfred-Preferences', 'features.defaultresults.scope', %Q{('/Applications','/Library/PreferencePanes','/System/Library/PreferencePanes')}]
|
||||
)
|
||||
fake_alfred_read_primary_preference 'features.defaultresults.scope', ALTERED_READ_SCOPE
|
||||
fake_alfred_read_local_preference 'scope', ALTERED_READ_SCOPE
|
||||
fake_alfred_write_primary_preference 'features.defaultresults.scope', DEFAULT_WRITE_SCOPE
|
||||
fake_alfred_write_local_preference 'scope', DEFAULT_WRITE_SCOPE
|
||||
|
||||
TestHelper.must_output(self, lambda {
|
||||
Cask::CLI::Alfred.run('unlink', Cask::FakeSystemCommand)
|
||||
|
|
Loading…
Reference in New Issue