Refactor Artifacts (#22725)
* Use class method for`moved` artifact english name. * Refactor linked artifacts. * Refactor moved artifact.
This commit is contained in:
parent
1d5219f3ff
commit
acf2777b35
|
@ -1,4 +1,6 @@
|
|||
class Hbc::Artifact::Hardlinked < Hbc::Artifact::Symlinked
|
||||
require "hbc/artifact/linked"
|
||||
|
||||
class Hbc::Artifact::Hardlinked < Hbc::Artifact::Linked
|
||||
def self.islink?(path)
|
||||
return false unless path.respond_to?(:stat)
|
||||
path.stat.nlink > 1
|
||||
|
@ -11,7 +13,7 @@ class Hbc::Artifact::Hardlinked < Hbc::Artifact::Symlinked
|
|||
def create_filesystem_link(source, target)
|
||||
Pathname.new(target).dirname.mkpath
|
||||
@command.run!("/bin/ln", args: ["-hf", "--", source, target])
|
||||
add_altname_metadata source, target
|
||||
add_altname_metadata source, target.basename.to_s
|
||||
end
|
||||
|
||||
def summarize_one_link(artifact_spec)
|
||||
|
|
|
@ -0,0 +1,43 @@
|
|||
require "hbc/artifact/relocated"
|
||||
|
||||
class Hbc::Artifact::Linked < Hbc::Artifact::Relocated
|
||||
def summary
|
||||
{
|
||||
english_description: "#{self.class.artifact_english_name} #{self.class.link_type_english_name}s managed by brew-cask:",
|
||||
contents: @cask.artifacts[self.class.artifact_dsl_key].map(&method(:summarize_one_link)) - [nil],
|
||||
}
|
||||
end
|
||||
|
||||
def link(artifact_spec)
|
||||
load_specification artifact_spec
|
||||
return unless preflight_checks(source, target)
|
||||
ohai "#{self.class.link_type_english_name}ing #{self.class.artifact_english_name} '#{source.basename}' to '#{target}'"
|
||||
create_filesystem_link(source, target)
|
||||
end
|
||||
|
||||
def unlink(artifact_spec)
|
||||
load_specification artifact_spec
|
||||
return unless self.class.islink?(target)
|
||||
ohai "Removing #{self.class.artifact_english_name} #{self.class.link_type_english_name.downcase}: '#{target}'"
|
||||
target.delete
|
||||
end
|
||||
|
||||
def install_phase
|
||||
@cask.artifacts[self.class.artifact_dsl_key].each { |artifact| link(artifact) }
|
||||
end
|
||||
|
||||
def uninstall_phase
|
||||
@cask.artifacts[self.class.artifact_dsl_key].each { |artifact| unlink(artifact) }
|
||||
end
|
||||
|
||||
def preflight_checks(source, target)
|
||||
if target.exist? && !self.class.islink?(target)
|
||||
ohai "It seems there is already #{self.class.artifact_english_article} #{self.class.artifact_english_name} at '#{target}'; not linking."
|
||||
return false
|
||||
end
|
||||
unless source.exist?
|
||||
raise Hbc::CaskError, "It seems the #{self.class.link_type_english_name.downcase} source is not there: '#{source}'"
|
||||
end
|
||||
true
|
||||
end
|
||||
end
|
|
@ -1,19 +1,13 @@
|
|||
class Hbc::Artifact::Moved < Hbc::Artifact::Base
|
||||
ALT_NAME_ATTRIBUTE = "com.apple.metadata:kMDItemAlternateNames".freeze
|
||||
|
||||
attr_reader :source, :target
|
||||
|
||||
def english_name
|
||||
self.class.artifact_english_name
|
||||
end
|
||||
require "hbc/artifact/relocated"
|
||||
|
||||
class Hbc::Artifact::Moved < Hbc::Artifact::Relocated
|
||||
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:",
|
||||
english_description: "#{self.class.artifact_english_name}s managed by brew-cask:",
|
||||
contents: contents,
|
||||
}
|
||||
end
|
||||
|
@ -45,22 +39,10 @@ class Hbc::Artifact::Moved < Hbc::Artifact::Base
|
|||
end
|
||||
|
||||
def move
|
||||
ohai "Moving #{english_name} '#{source.basename}' to '#{target}'"
|
||||
ohai "Moving #{self.class.artifact_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
|
||||
add_altname_metadata target, source.basename.to_s
|
||||
end
|
||||
|
||||
def preflight_checks
|
||||
|
@ -73,7 +55,7 @@ class Hbc::Artifact::Moved < Hbc::Artifact::Base
|
|||
end
|
||||
end
|
||||
unless source.exist?
|
||||
message = "It seems the #{english_name} source is not there: '#{source}'"
|
||||
message = "It seems the #{self.class.artifact_english_name} source is not there: '#{source}'"
|
||||
raise Hbc::CaskError, message
|
||||
end
|
||||
true
|
||||
|
@ -81,16 +63,16 @@ class Hbc::Artifact::Moved < Hbc::Artifact::Base
|
|||
|
||||
def warning_target_exists
|
||||
message_parts = [
|
||||
"It seems there is already #{self.class.artifact_english_article} #{english_name} at '#{target}'",
|
||||
"It seems there is already #{self.class.artifact_english_article} #{self.class.artifact_english_name} at '#{target}'",
|
||||
]
|
||||
yield(message_parts) if block_given?
|
||||
message_parts.join("; ")
|
||||
end
|
||||
|
||||
def delete
|
||||
ohai "Removing #{english_name}: '#{target}'"
|
||||
ohai "Removing #{self.class.artifact_english_name}: '#{target}'"
|
||||
if Hbc::MacOS.undeletable?(target)
|
||||
raise Hbc::CaskError, "Cannot remove undeletable #{english_name}"
|
||||
raise Hbc::CaskError, "Cannot remove undeletable #{self.class.artifact_english_name}"
|
||||
elsif force
|
||||
Hbc::Utils.gain_permissions_remove(target, command: @command)
|
||||
else
|
||||
|
@ -104,7 +86,7 @@ class Hbc::Artifact::Moved < Hbc::Artifact::Base
|
|||
printable_target.sub!(%r{^'#{ENV['HOME']}/*}, "~/'")
|
||||
|
||||
unless target.exist?
|
||||
warning = "Missing #{english_name}"
|
||||
warning = "Missing #{self.class.artifact_english_name}"
|
||||
warning = "#{Tty.red.underline}#{warning}#{Tty.reset}: "
|
||||
end
|
||||
|
||||
|
|
|
@ -0,0 +1,40 @@
|
|||
class Hbc::Artifact::Relocated < Hbc::Artifact::Base
|
||||
ALT_NAME_ATTRIBUTE = "com.apple.metadata:kMDItemAlternateNames".freeze
|
||||
|
||||
# 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(file, altname)
|
||||
return if altname.casecmp(file.basename).zero?
|
||||
odebug "Adding #{ALT_NAME_ATTRIBUTE} metadata"
|
||||
altnames = @command.run("/usr/bin/xattr",
|
||||
args: ["-p", ALT_NAME_ATTRIBUTE, file.to_s],
|
||||
print_stderr: false).stdout.sub(%r{\A\((.*)\)\Z}, '\1')
|
||||
odebug "Existing metadata is: '#{altnames}'"
|
||||
altnames.concat(", ") unless altnames.empty?
|
||||
altnames.concat(%Q{"#{altname}"})
|
||||
altnames = "(#{altnames})"
|
||||
|
||||
# Some packges are shipped as u=rx (e.g. Bitcoin Core)
|
||||
@command.run!("/bin/chmod", args: ["--", "u=rwx", file.to_s, file.realpath.to_s])
|
||||
|
||||
@command.run!("/usr/bin/xattr",
|
||||
args: ["-w", ALT_NAME_ATTRIBUTE, altnames, file.to_s],
|
||||
print_stderr: false)
|
||||
end
|
||||
|
||||
attr_reader :source, :target
|
||||
|
||||
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
|
||||
end
|
|
@ -1,4 +1,6 @@
|
|||
class Hbc::Artifact::Symlinked < Hbc::Artifact::Base
|
||||
require "hbc/artifact/linked"
|
||||
|
||||
class Hbc::Artifact::Symlinked < Hbc::Artifact::Linked
|
||||
def self.islink?(path)
|
||||
path.symlink?
|
||||
end
|
||||
|
@ -10,59 +12,7 @@ class Hbc::Artifact::Symlinked < Hbc::Artifact::Base
|
|||
def create_filesystem_link(source, target)
|
||||
Pathname.new(target).dirname.mkpath
|
||||
@command.run!("/bin/ln", args: ["-hfs", "--", source, target])
|
||||
add_altname_metadata source, target
|
||||
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(source, target)
|
||||
attribute = "com.apple.metadata:kMDItemAlternateNames"
|
||||
return if source.basename.to_s.casecmp(target.basename).zero?
|
||||
odebug "Adding #{attribute} metadata"
|
||||
altnames = @command.run("/usr/bin/xattr",
|
||||
args: ["-p", attribute, target],
|
||||
print_stderr: false).stdout.sub(%r{\A\((.*)\)\Z}, '\1')
|
||||
odebug "Existing metadata is: '#{altnames}'"
|
||||
altnames.concat(", ") unless altnames.empty?
|
||||
altnames.concat(%Q{"#{target.basename}"})
|
||||
altnames = "(#{altnames})"
|
||||
|
||||
# Some packges are shipped as u=rx (e.g. Bitcoin Core)
|
||||
@command.run!("/bin/chmod", args: ["--", "u=rwx", source])
|
||||
|
||||
@command.run!("/usr/bin/xattr",
|
||||
args: ["-w", attribute, altnames, target],
|
||||
print_stderr: false)
|
||||
end
|
||||
|
||||
def summary
|
||||
{
|
||||
english_description: "#{self.class.artifact_english_name} #{self.class.link_type_english_name}s managed by brew-cask:",
|
||||
contents: @cask.artifacts[self.class.artifact_dsl_key].map(&method(:summarize_one_link)) - [nil],
|
||||
}
|
||||
end
|
||||
|
||||
attr_reader :source, :target
|
||||
|
||||
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 link(artifact_spec)
|
||||
load_specification artifact_spec
|
||||
return unless preflight_checks(source, target)
|
||||
ohai "#{self.class.link_type_english_name}ing #{self.class.artifact_english_name} '#{source.basename}' to '#{target}'"
|
||||
create_filesystem_link(source, target)
|
||||
add_altname_metadata source, target.basename.to_s
|
||||
end
|
||||
|
||||
def summarize_one_link(artifact_spec)
|
||||
|
@ -72,30 +22,4 @@ class Hbc::Artifact::Symlinked < Hbc::Artifact::Base
|
|||
printable_target = "'#{target}'".sub(%r{^'#{ENV['HOME']}/*}, "~/'")
|
||||
"#{link_description}#{printable_target} -> '#{target.readlink}'"
|
||||
end
|
||||
|
||||
def unlink(artifact_spec)
|
||||
load_specification artifact_spec
|
||||
return unless self.class.islink?(target)
|
||||
ohai "Removing #{self.class.artifact_english_name} #{self.class.link_type_english_name.downcase}: '#{target}'"
|
||||
target.delete
|
||||
end
|
||||
|
||||
def install_phase
|
||||
@cask.artifacts[self.class.artifact_dsl_key].each { |artifact| link(artifact) }
|
||||
end
|
||||
|
||||
def uninstall_phase
|
||||
@cask.artifacts[self.class.artifact_dsl_key].each { |artifact| unlink(artifact) }
|
||||
end
|
||||
|
||||
def preflight_checks(source, target)
|
||||
if target.exist? && !self.class.islink?(target)
|
||||
ohai "It seems there is already #{self.class.artifact_english_article} #{self.class.artifact_english_name} at '#{target}'; not linking."
|
||||
return false
|
||||
end
|
||||
unless source.exist?
|
||||
raise Hbc::CaskError, "It seems the #{self.class.link_type_english_name.downcase} source is not there: '#{source}'"
|
||||
end
|
||||
true
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue