Merge pull request #2299 from reitermarkus/cask-refactor-artifacts

Refactor artifacts.
This commit is contained in:
Markus Reiter 2017-03-11 09:37:42 +01:00 committed by GitHub
commit 371a830028
7 changed files with 80 additions and 104 deletions

View File

@ -32,10 +32,7 @@ module Hbc
def self.read_script_arguments(arguments, stanza, default_arguments = {}, override_arguments = {}, key = nil)
# TODO: when stanza names are harmonized with class names,
# stanza may not be needed as an explicit argument
description = stanza.to_s
if key
description.concat(" #{key.inspect}")
end
description = key ? "#{stanza} #{key.inspect}" : stanza.to_s
# backward-compatible string value
arguments = { executable: arguments } if arguments.is_a?(String)

View File

@ -7,8 +7,8 @@ module Hbc
super if CLI.binaries?
end
def link(artifact_spec)
super(artifact_spec)
def link
super
FileUtils.chmod "+x", source
end
end

View File

@ -8,61 +8,38 @@ module Hbc
end
def install_phase
each_artifact do |artifact|
load_specification(artifact)
next unless preflight_checks
delete if Utils.path_occupied?(target) && force
move
end
each_artifact(&method(:move))
end
def uninstall_phase
each_artifact do |artifact|
load_specification(artifact)
next unless File.exist?(target)
delete
end
each_artifact(&method(:delete))
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
def move
if Utils.path_occupied?(target)
message = "It seems there is already #{self.class.artifact_english_article} #{self.class.artifact_english_name} at '#{target}'"
raise CaskError, "#{message}." unless force
opoo "#{message}; overwriting."
delete
end
def move
ohai "Moving #{self.class.artifact_english_name} '#{source.basename}' to '#{target}'"
unless source.exist?
raise CaskError, "It seems the #{self.class.artifact_english_name} source '#{source}' is not there."
end
ohai "Moving #{self.class.artifact_english_name} '#{source.basename}' to '#{target}'."
target.dirname.mkpath
FileUtils.move(source, target)
add_altname_metadata target, source.basename.to_s
end
def preflight_checks
if Utils.path_occupied?(target)
raise CaskError, warning_target_exists << "." unless force
opoo(warning_target_exists { |s| s << "overwriting." })
end
unless source.exist?
message = "It seems the #{self.class.artifact_english_name} source is not there: '#{source}'"
raise CaskError, message
end
true
end
def warning_target_exists
message_parts = [
"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 #{self.class.artifact_english_name}: '#{target}'"
raise CaskError, "Cannot remove undeletable #{self.class.artifact_english_name}" if MacOS.undeletable?(target)
ohai "Removing #{self.class.artifact_english_name} '#{target}'."
return unless Utils.path_occupied?(target)
raise CaskError, "Cannot remove undeletable #{self.class.artifact_english_name}." if MacOS.undeletable?(target)
if force
Utils.gain_permissions_remove(target, command: @command)

View File

@ -42,6 +42,14 @@ module Hbc
print_stderr: false)
end
def each_artifact
# the sort is for predictability between Ruby versions
@cask.artifacts[self.class.artifact_dsl_key].sort.each do |artifact|
load_specification(artifact)
yield
end
end
def load_specification(artifact_spec)
source_string, target_hash = artifact_spec
raise CaskInvalidError if source_string.nil?

View File

@ -11,55 +11,48 @@ module Hbc
"#{artifact_english_name} #{link_type_english_name}s"
end
def self.islink?(path)
path.symlink?
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(&method(:link))
each_artifact(&method(:link))
end
def uninstall_phase
@cask.artifacts[self.class.artifact_dsl_key].each(&method(:unlink))
each_artifact(&method(:unlink))
end
def preflight_checks(source, target)
if target.exist? && !self.class.islink?(target)
private
def link
unless source.exist?
raise CaskError, "It seems the #{self.class.link_type_english_name.downcase} source '#{source}' is not there."
end
if target.exist? && !target.symlink?
raise CaskError, "It seems there is already #{self.class.artifact_english_article} #{self.class.artifact_english_name} at '#{target}'; not linking."
end
unless source.exist?
raise CaskError, "It seems the #{self.class.link_type_english_name.downcase} source is not there: '#{source}'"
ohai "Linking #{self.class.artifact_english_name} '#{source.basename}' to '#{target}'."
create_filesystem_link(source, target)
end
true
def unlink
return unless target.symlink?
ohai "Unlinking #{self.class.artifact_english_name} '#{target}'."
target.delete
end
def create_filesystem_link(source, target)
Pathname.new(target).dirname.mkpath
@command.run!("/bin/ln", args: ["-hfs", "--", source, target])
target.dirname.mkpath
@command.run!("/bin/ln", args: ["-h", "-f", "-s", "--", source, target])
add_altname_metadata source, target.basename.to_s
end
def summarize_artifact(artifact_spec)
load_specification artifact_spec
if self.class.islink?(target) && target.exist? && target.readlink.exist?
if target.symlink? && target.exist? && target.readlink.exist?
"#{printable_target} -> #{target.readlink} (#{target.readlink.abv})"
else
string = if self.class.islink?(target)
string = if target.symlink?
"#{printable_target} -> #{target.readlink}"
else
printable_target

View File

@ -7,8 +7,8 @@ describe Hbc::Artifact::App, :cask do
let(:source_path) { cask.staged_path.join("Caffeine.app") }
let(:target_path) { Hbc.appdir.join("Caffeine.app") }
let(:install_phase) { -> { app.install_phase } }
let(:uninstall_phase) { -> { app.uninstall_phase } }
let(:install_phase) { app.install_phase }
let(:uninstall_phase) { app.uninstall_phase }
before(:each) do
InstallHelper.install_without_artifacts(cask)
@ -17,7 +17,7 @@ describe Hbc::Artifact::App, :cask do
describe "install_phase" do
it "installs the given app using the proper target directory" do
shutup do
install_phase.call
install_phase
end
expect(target_path).to be_a_directory
@ -40,7 +40,7 @@ describe Hbc::Artifact::App, :cask do
FileUtils.mv(source_path, appsubdir)
shutup do
install_phase.call
install_phase
end
expect(target_path).to be_a_directory
@ -53,7 +53,7 @@ describe Hbc::Artifact::App, :cask do
FileUtils.cp_r source_path, staged_app_copy
shutup do
install_phase.call
install_phase
end
expect(target_path).to be_a_directory
@ -69,7 +69,7 @@ describe Hbc::Artifact::App, :cask do
end
it "avoids clobbering an existing app" do
expect(install_phase).to raise_error(Hbc::CaskError, "It seems there is already an App at '#{target_path}'.")
expect { install_phase }.to raise_error(Hbc::CaskError, "It seems there is already an App at '#{target_path}'.")
expect(source_path).to be_a_directory
expect(target_path).to be_a_directory
@ -89,17 +89,17 @@ describe Hbc::Artifact::App, :cask do
describe "target is both writable and user-owned" do
it "overwrites the existing app" do
stdout = <<-EOS.undent
==> Removing App: '#{target_path}'
==> Moving App 'Caffeine.app' to '#{target_path}'
==> Removing App '#{target_path}'.
==> Moving App 'Caffeine.app' to '#{target_path}'.
EOS
stderr = <<-EOS.undent
Warning: It seems there is already an App at '#{target_path}'; overwriting.
EOS
expect {
expect(install_phase).to output(stdout).to_stdout
}.to output(stderr).to_stderr
expect { install_phase }
.to output(stdout).to_stdout
.and output(stderr).to_stderr
expect(source_path).not_to exist
expect(target_path).to be_a_directory
@ -124,17 +124,17 @@ describe Hbc::Artifact::App, :cask do
.and_call_original
stdout = <<-EOS.undent
==> Removing App: '#{target_path}'
==> Moving App 'Caffeine.app' to '#{target_path}'
==> Removing App '#{target_path}'.
==> Moving App 'Caffeine.app' to '#{target_path}'.
EOS
stderr = <<-EOS.undent
Warning: It seems there is already an App at '#{target_path}'; overwriting.
EOS
expect {
expect(install_phase).to output(stdout).to_stdout
}.to output(stderr).to_stderr
expect { install_phase }
.to output(stdout).to_stdout
.and output(stderr).to_stderr
expect(source_path).not_to exist
expect(target_path).to be_a_directory
@ -160,7 +160,7 @@ describe Hbc::Artifact::App, :cask do
end
it "leaves the target alone" do
expect(install_phase).to raise_error(Hbc::CaskError, "It seems there is already an App at '#{target_path}'.")
expect { install_phase }.to raise_error(Hbc::CaskError, "It seems there is already an App at '#{target_path}'.")
expect(target_path).to be_a_symlink
end
@ -169,17 +169,17 @@ describe Hbc::Artifact::App, :cask do
it "overwrites the existing app" do
stdout = <<-EOS.undent
==> Removing App: '#{target_path}'
==> Moving App 'Caffeine.app' to '#{target_path}'
==> Removing App '#{target_path}'.
==> Moving App 'Caffeine.app' to '#{target_path}'.
EOS
stderr = <<-EOS.undent
Warning: It seems there is already an App at '#{target_path}'; overwriting.
EOS
expect {
expect(install_phase).to output(stdout).to_stdout
}.to output(stderr).to_stderr
expect { install_phase }
.to output(stdout).to_stdout
.and output(stderr).to_stderr
expect(source_path).not_to exist
expect(target_path).to be_a_directory
@ -193,22 +193,22 @@ describe Hbc::Artifact::App, :cask do
it "gives a warning if the source doesn't exist" do
source_path.rmtree
message = "It seems the App source is not there: '#{source_path}'"
message = "It seems the App source '#{source_path}' is not there."
expect(install_phase).to raise_error(Hbc::CaskError, message)
expect { install_phase }.to raise_error(Hbc::CaskError, message)
end
end
describe "uninstall_phase" do
it "deletes managed apps" do
shutup do
install_phase.call
install_phase
end
expect(target_path).to exist
shutup do
uninstall_phase.call
uninstall_phase
end
expect(target_path).not_to exist
@ -226,7 +226,7 @@ describe Hbc::Artifact::App, :cask do
describe "app is correctly installed" do
it "returns the path to the app" do
shutup do
install_phase.call
install_phase
end
expect(contents).to eq(["#{target_path} (#{target_path.abv})"])

View File

@ -47,6 +47,7 @@ describe Hbc::CLI::Uninstall, :cask do
end
expect(cask).to be_installed
expect(Hbc.appdir.join("MyFancyApp.app")).to exist
expect {
shutup do