Skip to content

Instantly share code, notes, and snippets.

@ptb
Created January 4, 2016 22:12
Show Gist options
  • Save ptb/b2be137344a03fed57aa to your computer and use it in GitHub Desktop.
Save ptb/b2be137344a03fed57aa to your computer and use it in GitHub Desktop.
--- a/usr/local/Library/Taps/caskroom/homebrew-cask/lib/hbc/artifact.rb 2016-01-04 15:06:43.000000000 -0500
+++ b/usr/local/Library/Taps/caskroom/homebrew-cask/lib/hbc/artifact.rb 2016-01-04 16:29:20.000000000 -0500
@@ -4,6 +4,7 @@
require 'hbc/artifact/uninstall_base'
require 'hbc/artifact/symlinked'
require 'hbc/artifact/hardlinked'
+require 'hbc/artifact/moved'
require 'hbc/artifact/app'
require 'hbc/artifact/artifact' # generic 'artifact' stanza
--- a/usr/local/Library/Taps/caskroom/homebrew-cask/lib/hbc/artifact/app.rb 2016-01-04 15:06:43.000000000 -0500
+++ b/usr/local/Library/Taps/caskroom/homebrew-cask/lib/hbc/artifact/app.rb 2016-01-04 16:27:43.000000000 -0500
@@ -1,2 +1,2 @@
-class Hbc::Artifact::App < Hbc::Artifact::Symlinked
+class Hbc::Artifact::App < Hbc::Artifact::Moved
end
--- a/usr/local/Library/Taps/caskroom/homebrew-cask/lib/hbc/artifact/moved.rb 2016-01-04 16:31:44.000000000 -0500
+++ b/usr/local/Library/Taps/caskroom/homebrew-cask/lib/hbc/artifact/moved.rb 2016-01-04 16:31:50.000000000 -0500
@@ -0,0 +1,142 @@
+class Hbc::Artifact::Moved < Hbc::Artifact::Base
+ ALT_NAME_ATTRIBUTE = 'com.apple.metadata:kMDItemAlternateNames'
+
+ attr_reader :source, :target
+
+ def english_name
+ self.class.artifact_english_name
+ end
+
+ def self.link_type_english_name
+ 'Symlink'
+ end
+
+ def summary
+ contents = @cask.artifacts[self.class.artifact_dsl_key].map do |artifact|
+ summarize_artifact(artifact)
+ end - [nil]
+
+ {
+ :english_description => "#{english_name}s managed by brew-cask:",
+ :contents => contents
+ }
+ end
+
+ def install_phase
+ each_artifact do |artifact|
+ load_specification(artifact)
+ next unless preflight_checks
+ add_altname_metadata
+ move
+ end
+ end
+
+ def uninstall_phase
+ each_artifact do |artifact|
+ load_specification(artifact)
+ next unless File.exist?(target)
+ delete
+ end
+ end
+
+ private
+
+ def each_artifact
+ # the sort is for predictability between Ruby versions
+ @cask.artifacts[self.class.artifact_dsl_key].sort.each do |artifact|
+ yield artifact
+ end
+ end
+
+ def move
+ ohai "Moving #{english_name} '#{source.basename}' to '#{target}'"
+ target.dirname.mkpath
+ FileUtils.move(source, target)
+ end
+
+ def load_specification(artifact_spec)
+ source_string, target_hash = artifact_spec
+ raise Hbc::CaskInvalidError if source_string.nil?
+ @source = @cask.staged_path.join(source_string)
+ if target_hash
+ raise Hbc::CaskInvalidError unless target_hash.respond_to?(:keys)
+ target_hash.assert_valid_keys(:target)
+ @target = Hbc.send(self.class.artifact_dirmethod).join(target_hash[:target])
+ else
+ @target = Hbc.send(self.class.artifact_dirmethod).join(source.basename)
+ end
+ end
+
+ def preflight_checks
+ if target.exist?
+ ohai "It seems there is already #{self.class.artifact_english_article} #{english_name} at '#{target}'; not moving."
+ return false
+ end
+ unless source.exist?
+ message = "It seems the #{english_name} source is not there: '#{source}'"
+ raise Hbc::CaskError.new(message)
+ end
+ true
+ end
+
+ # Try to make the asset searchable under the target name. Spotlight
+ # respects this attribute for many filetypes, but ignores it for App
+ # bundles. Alfred 2.2 respects it even for App bundles.
+ def add_altname_metadata
+ return if no_alternative_name?
+
+ ensure_package_writeable
+ altnames = build_altnames
+
+ odebug "Adding #{ALT_NAME_ATTRIBUTE} metadata"
+
+ @command.run!('/usr/bin/xattr',
+ :args => ['-w', ALT_NAME_ATTRIBUTE, altnames, source],
+ :print_stderr => false)
+ end
+
+ def no_alternative_name?
+ source.basename.to_s.casecmp(target.basename) == 0
+ end
+
+ def build_altnames
+ altnames = existing_altname_metadata
+ odebug "Existing metadata is: '#{altnames}'"
+ altnames.concat(', ') if altnames.length > 0
+ altnames.concat(%Q{"#{target.basename}"})
+ "(#{altnames})"
+ end
+
+ def existing_altname_metadata
+ result = @command.run(
+ '/usr/bin/xattr',
+ :args => ['-p', ALT_NAME_ATTRIBUTE, target],
+ :print_stderr => false
+ )
+
+ result.stdout.sub(/\A\((.*)\)\Z/, "#{$1}")
+ end
+
+ def ensure_package_writeable
+ # Some packges are shipped as u=rx (e.g. Bitcoin Core)
+ @command.run!('/bin/chmod', :args => ['u=rwx', source])
+ end
+
+ def delete
+ ohai "Removing #{english_name}: '#{target}'"
+ target.rmtree
+ end
+
+ def summarize_artifact(artifact_spec)
+ load_specification artifact_spec
+ printable_target = "'#{target}'"
+ printable_target.sub!(%r{^'#{ENV['HOME']}/*}, "~/'")
+
+ unless target.exist?
+ warning = "Missing #{english_name}"
+ warning = "#{Tty.red.underline}#{warning}#{Tty.reset}: "
+ end
+
+ "#{warning}#{printable_target}"
+ end
+end
--- a/usr/local/Library/Taps/caskroom/homebrew-cask/lib/hbc/staged.rb 2016-01-04 15:06:43.000000000 -0500
+++ b/usr/local/Library/Taps/caskroom/homebrew-cask/lib/hbc/staged.rb 2016-01-04 16:18:36.000000000 -0500
@@ -3,7 +3,7 @@
index = 0 if index == :first
index = 1 if index == :second
index = -1 if index == :last
- @cask.staged_path.join(@cask.artifacts[:app].to_a.at(index).first, 'Contents', 'Info.plist')
+ Hbc.appdir.join(@cask.artifacts[:app].to_a.at(index).first, 'Contents', 'Info.plist')
end
def plist_exec(cmd)
--- a/usr/local/Library/Taps/caskroom/homebrew-cask/lib/hbc/artifact/symlinked.rb 2016-01-04 16:46:29.000000000 -0500
+++ b/usr/local/Library/Taps/caskroom/homebrew-cask/lib/hbc/artifact/symlinked.rb 2016-01-04 16:47:10.000000000 -0500
@@ -51,7 +51,7 @@
def load_specification(artifact_spec)
source_string, target_hash = artifact_spec
raise Hbc::CaskInvalidError if source_string.nil?
- @source = @cask.staged_path.join(source_string)
+ @source = Hbc.appdir.join(source_string)
if target_hash
raise Hbc::CaskInvalidError unless target_hash.respond_to?(:keys)
target_hash.assert_valid_keys(:target)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment