Cask: Use nested classes and modules.

This commit is contained in:
Markus Reiter 2016-09-24 13:52:43 +02:00
parent 687f0fcf72
commit b86c8efb79
146 changed files with 6464 additions and 5987 deletions

View File

@ -86,7 +86,7 @@ Style/BlockDelimiters:
- proc - proc
Style/ClassAndModuleChildren: Style/ClassAndModuleChildren:
EnforcedStyle: compact EnforcedStyle: nested
Style/Documentation: Style/Documentation:
Enabled: false Enabled: false

View File

@ -40,22 +40,22 @@ require "utils"
require "vendor/plist/plist" require "vendor/plist/plist"
module Hbc module Hbc
include Hbc::Locations include Locations
include Hbc::Scopes include Scopes
include Hbc::Options include Options
include Hbc::Utils include Utils
def self.init def self.init
Hbc::Cache.ensure_cache_exists Cache.ensure_cache_exists
Hbc::Cache.migrate_legacy_cache Cache.migrate_legacy_cache
Hbc::Caskroom.migrate_caskroom_from_repo_to_prefix Caskroom.migrate_caskroom_from_repo_to_prefix
Hbc::Caskroom.ensure_caskroom_exists Caskroom.ensure_caskroom_exists
end end
def self.load(query) def self.load(query)
odebug "Loading Cask definitions" odebug "Loading Cask definitions"
cask = Hbc::Source.for_query(query).load cask = Source.for_query(query).load
cask.dumpcask cask.dumpcask
cask cask
end end

View File

@ -1,5 +1,3 @@
module Hbc::Artifact; end
require "hbc/artifact/app" require "hbc/artifact/app"
require "hbc/artifact/artifact" # generic 'artifact' stanza require "hbc/artifact/artifact" # generic 'artifact' stanza
require "hbc/artifact/binary" require "hbc/artifact/binary"
@ -24,34 +22,35 @@ require "hbc/artifact/suite"
require "hbc/artifact/uninstall" require "hbc/artifact/uninstall"
require "hbc/artifact/zap" require "hbc/artifact/zap"
module Hbc::Artifact module Hbc
module Artifact
# NOTE: order is important here, since we want to extract nested containers # NOTE: order is important here, since we want to extract nested containers
# before we handle any other artifacts # before we handle any other artifacts
def self.artifacts def self.artifacts
[ [
Hbc::Artifact::PreflightBlock, PreflightBlock,
Hbc::Artifact::NestedContainer, NestedContainer,
Hbc::Artifact::Installer, Installer,
Hbc::Artifact::App, App,
Hbc::Artifact::Suite, Suite,
Hbc::Artifact::Artifact, # generic 'artifact' stanza Artifact, # generic 'artifact' stanza
Hbc::Artifact::Colorpicker, Colorpicker,
Hbc::Artifact::Pkg, Pkg,
Hbc::Artifact::Prefpane, Prefpane,
Hbc::Artifact::Qlplugin, Qlplugin,
Hbc::Artifact::Font, Font,
Hbc::Artifact::Service, Service,
Hbc::Artifact::StageOnly, StageOnly,
Hbc::Artifact::Binary, Binary,
Hbc::Artifact::InputMethod, InputMethod,
Hbc::Artifact::InternetPlugin, InternetPlugin,
Hbc::Artifact::AudioUnitPlugin, AudioUnitPlugin,
Hbc::Artifact::VstPlugin, VstPlugin,
Hbc::Artifact::Vst3Plugin, Vst3Plugin,
Hbc::Artifact::ScreenSaver, ScreenSaver,
Hbc::Artifact::Uninstall, Uninstall,
Hbc::Artifact::PostflightBlock, PostflightBlock,
Hbc::Artifact::Zap, Zap,
] ]
end end
@ -63,3 +62,4 @@ module Hbc::Artifact
end end
end end
end end
end

View File

@ -1,6 +1,8 @@
require "hbc/artifact/base" require "hbc/artifact/base"
class Hbc::Artifact::AbstractFlightBlock < Hbc::Artifact::Base module Hbc
module Artifact
class AbstractFlightBlock < Base
def self.artifact_dsl_key def self.artifact_dsl_key
super.to_s.sub(%r{_block$}, "").to_sym super.to_s.sub(%r{_block$}, "").to_sym
end end
@ -34,3 +36,5 @@ class Hbc::Artifact::AbstractFlightBlock < Hbc::Artifact::Base
end end
end end
end end
end
end

View File

@ -1,4 +1,8 @@
require "hbc/artifact/moved" require "hbc/artifact/moved"
class Hbc::Artifact::App < Hbc::Artifact::Moved module Hbc
module Artifact
class App < Moved
end
end
end end

View File

@ -1,6 +1,8 @@
require "hbc/artifact/moved" require "hbc/artifact/moved"
class Hbc::Artifact::Artifact < Hbc::Artifact::Moved module Hbc
module Artifact
class Artifact < Moved
def self.artifact_english_name def self.artifact_english_name
"Generic Artifact" "Generic Artifact"
end end
@ -11,10 +13,12 @@ class Hbc::Artifact::Artifact < Hbc::Artifact::Moved
def load_specification(artifact_spec) def load_specification(artifact_spec)
source_string, target_hash = artifact_spec source_string, target_hash = artifact_spec
raise Hbc::CaskInvalidError.new(@cask.token, "no source given for artifact") if source_string.nil? raise CaskInvalidError.new(@cask.token, "no source given for artifact") if source_string.nil?
@source = @cask.staged_path.join(source_string) @source = @cask.staged_path.join(source_string)
raise Hbc::CaskInvalidError.new(@cask.token, "target required for generic artifact #{source_string}") unless target_hash.is_a?(Hash) raise CaskInvalidError.new(@cask.token, "target required for generic artifact #{source_string}") unless target_hash.is_a?(Hash)
target_hash.assert_valid_keys(:target) target_hash.assert_valid_keys(:target)
@target = Pathname.new(target_hash[:target]) @target = Pathname.new(target_hash[:target])
end end
end end
end
end

View File

@ -1,4 +1,8 @@
require "hbc/artifact/moved" require "hbc/artifact/moved"
class Hbc::Artifact::AudioUnitPlugin < Hbc::Artifact::Moved module Hbc
module Artifact
class AudioUnitPlugin < Moved
end
end
end end

View File

@ -1,4 +1,6 @@
class Hbc::Artifact::Base module Hbc
module Artifact
class Base
def self.artifact_name def self.artifact_name
@artifact_name ||= name.sub(%r{^.*:}, "").gsub(%r{(.)([A-Z])}, '\1_\2').downcase @artifact_name ||= name.sub(%r{^.*:}, "").gsub(%r{(.)([A-Z])}, '\1_\2').downcase
end end
@ -71,9 +73,11 @@ class Hbc::Artifact::Base
{} {}
end end
def initialize(cask, command: Hbc::SystemCommand, force: false) def initialize(cask, command: SystemCommand, force: false)
@cask = cask @cask = cask
@command = command @command = command
@force = force @force = force
end end
end end
end
end

View File

@ -1,7 +1,11 @@
require "hbc/artifact/symlinked" require "hbc/artifact/symlinked"
class Hbc::Artifact::Binary < Hbc::Artifact::Symlinked module Hbc
module Artifact
class Binary < Symlinked
def install_phase def install_phase
super unless Hbc.no_binaries super unless Hbc.no_binaries
end end
end end
end
end

View File

@ -1,4 +1,8 @@
require "hbc/artifact/moved" require "hbc/artifact/moved"
class Hbc::Artifact::Colorpicker < Hbc::Artifact::Moved module Hbc
module Artifact
class Colorpicker < Moved
end
end
end end

View File

@ -1,4 +1,8 @@
require "hbc/artifact/moved" require "hbc/artifact/moved"
class Hbc::Artifact::Font < Hbc::Artifact::Moved module Hbc
module Artifact
class Font < Moved
end
end
end end

View File

@ -1,4 +1,8 @@
require "hbc/artifact/moved" require "hbc/artifact/moved"
class Hbc::Artifact::InputMethod < Hbc::Artifact::Moved module Hbc
module Artifact
class InputMethod < Moved
end
end
end end

View File

@ -1,6 +1,8 @@
require "hbc/artifact/base" require "hbc/artifact/base"
class Hbc::Artifact::Installer < Hbc::Artifact::Base module Hbc
module Artifact
class Installer < Base
# TODO: for backward compatibility, removeme # TODO: for backward compatibility, removeme
def install def install
install_phase install_phase
@ -27,7 +29,7 @@ class Hbc::Artifact::Installer < Hbc::Artifact::Base
{ must_succeed: true, sudo: true }, { must_succeed: true, sudo: true },
print_stdout: true) print_stdout: true)
ohai "Running #{self.class.artifact_dsl_key} script #{executable}" ohai "Running #{self.class.artifact_dsl_key} script #{executable}"
raise Hbc::CaskInvalidError.new(@cask, "#{self.class.artifact_dsl_key} missing executable") if executable.nil? raise CaskInvalidError.new(@cask, "#{self.class.artifact_dsl_key} missing executable") if executable.nil?
executable_path = @cask.staged_path.join(executable) executable_path = @cask.staged_path.join(executable)
@command.run("/bin/chmod", args: ["--", "+x", executable_path]) if File.exist?(executable_path) @command.run("/bin/chmod", args: ["--", "+x", executable_path]) if File.exist?(executable_path)
@command.run(executable_path, script_arguments) @command.run(executable_path, script_arguments)
@ -39,3 +41,5 @@ class Hbc::Artifact::Installer < Hbc::Artifact::Base
odebug "Nothing to do. The #{self.class.artifact_dsl_key} artifact has no uninstall phase." odebug "Nothing to do. The #{self.class.artifact_dsl_key} artifact has no uninstall phase."
end end
end end
end
end

View File

@ -1,4 +1,8 @@
require "hbc/artifact/moved" require "hbc/artifact/moved"
class Hbc::Artifact::InternetPlugin < Hbc::Artifact::Moved module Hbc
module Artifact
class InternetPlugin < Moved
end
end
end end

View File

@ -1,6 +1,8 @@
require "hbc/artifact/relocated" require "hbc/artifact/relocated"
class Hbc::Artifact::Moved < Hbc::Artifact::Relocated module Hbc
module Artifact
class Moved < Relocated
def self.english_description def self.english_description
"#{artifact_english_name}s" "#{artifact_english_name}s"
end end
@ -9,7 +11,7 @@ class Hbc::Artifact::Moved < Hbc::Artifact::Relocated
each_artifact do |artifact| each_artifact do |artifact|
load_specification(artifact) load_specification(artifact)
next unless preflight_checks next unless preflight_checks
delete if Hbc::Utils.path_occupied?(target) && force delete if Utils.path_occupied?(target) && force
move move
end end
end end
@ -39,7 +41,7 @@ class Hbc::Artifact::Moved < Hbc::Artifact::Relocated
end end
def preflight_checks def preflight_checks
if Hbc::Utils.path_occupied?(target) if Utils.path_occupied?(target)
if force if force
ohai(warning_target_exists { |s| s << "overwriting." }) ohai(warning_target_exists { |s| s << "overwriting." })
else else
@ -49,7 +51,7 @@ class Hbc::Artifact::Moved < Hbc::Artifact::Relocated
end end
unless source.exist? unless source.exist?
message = "It seems the #{self.class.artifact_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 raise CaskError, message
end end
true true
end end
@ -64,10 +66,10 @@ class Hbc::Artifact::Moved < Hbc::Artifact::Relocated
def delete def delete
ohai "Removing #{self.class.artifact_english_name}: '#{target}'" ohai "Removing #{self.class.artifact_english_name}: '#{target}'"
raise Hbc::CaskError, "Cannot remove undeletable #{self.class.artifact_english_name}" if MacOS.undeletable?(target) raise CaskError, "Cannot remove undeletable #{self.class.artifact_english_name}" if MacOS.undeletable?(target)
if force if force
Hbc::Utils.gain_permissions_remove(target, command: @command) Utils.gain_permissions_remove(target, command: @command)
else else
target.rmtree target.rmtree
end end
@ -86,3 +88,5 @@ class Hbc::Artifact::Moved < Hbc::Artifact::Relocated
"#{warning}#{printable_target}#{target_abv}" "#{warning}#{printable_target}#{target_abv}"
end end
end end
end
end

View File

@ -1,6 +1,8 @@
require "hbc/artifact/base" require "hbc/artifact/base"
class Hbc::Artifact::NestedContainer < Hbc::Artifact::Base module Hbc
module Artifact
class NestedContainer < Base
def install_phase def install_phase
@cask.artifacts[:nested_container].each { |container| extract(container) } @cask.artifacts[:nested_container].each { |container| extract(container) }
end end
@ -11,10 +13,10 @@ class Hbc::Artifact::NestedContainer < Hbc::Artifact::Base
def extract(container_relative_path) def extract(container_relative_path)
source = @cask.staged_path.join(container_relative_path) source = @cask.staged_path.join(container_relative_path)
container = Hbc::Container.for_path(source, @command) container = Container.for_path(source, @command)
unless container unless container
raise Hbc::CaskError, "Aw dang, could not identify nested container at '#{source}'" raise CaskError, "Aw dang, could not identify nested container at '#{source}'"
end end
ohai "Extracting nested container #{source.basename}" ohai "Extracting nested container #{source.basename}"
@ -22,3 +24,5 @@ class Hbc::Artifact::NestedContainer < Hbc::Artifact::Base
FileUtils.remove_entry_secure(source) FileUtils.remove_entry_secure(source)
end end
end end
end
end

View File

@ -1,6 +1,8 @@
require "hbc/artifact/base" require "hbc/artifact/base"
class Hbc::Artifact::Pkg < Hbc::Artifact::Base module Hbc
module Artifact
class Pkg < Base
attr_reader :pkg_relative_path attr_reader :pkg_relative_path
def self.artifact_dsl_key def self.artifact_dsl_key
@ -18,7 +20,7 @@ class Hbc::Artifact::Pkg < Hbc::Artifact::Base
end end
raise if pkg_description.nil? raise if pkg_description.nil?
rescue StandardError rescue StandardError
raise Hbc::CaskInvalidError.new(@cask, "Bad pkg stanza") raise CaskInvalidError.new(@cask, "Bad pkg stanza")
end end
end end
@ -40,7 +42,7 @@ class Hbc::Artifact::Pkg < Hbc::Artifact::Base
ohai "Package installers may write to any location; options such as --appdir are ignored." ohai "Package installers may write to any location; options such as --appdir are ignored."
source = @cask.staged_path.join(pkg_relative_path) source = @cask.staged_path.join(pkg_relative_path)
unless source.exist? unless source.exist?
raise Hbc::CaskError, "pkg source file not found: '#{source}'" raise CaskError, "pkg source file not found: '#{source}'"
end end
args = [ args = [
"-pkg", source, "-pkg", source,
@ -51,3 +53,5 @@ class Hbc::Artifact::Pkg < Hbc::Artifact::Base
@command.run!("/usr/sbin/installer", sudo: true, args: args, print_stdout: true) @command.run!("/usr/sbin/installer", sudo: true, args: args, print_stdout: true)
end end
end end
end
end

View File

@ -1,4 +1,8 @@
require "hbc/artifact/abstract_flight_block" require "hbc/artifact/abstract_flight_block"
class Hbc::Artifact::PostflightBlock < Hbc::Artifact::AbstractFlightBlock module Hbc
module Artifact
class PostflightBlock < AbstractFlightBlock
end
end
end end

View File

@ -1,4 +1,8 @@
require "hbc/artifact/abstract_flight_block" require "hbc/artifact/abstract_flight_block"
class Hbc::Artifact::PreflightBlock < Hbc::Artifact::AbstractFlightBlock module Hbc
module Artifact
class PreflightBlock < AbstractFlightBlock
end
end
end end

View File

@ -1,7 +1,11 @@
require "hbc/artifact/moved" require "hbc/artifact/moved"
class Hbc::Artifact::Prefpane < Hbc::Artifact::Moved module Hbc
module Artifact
class Prefpane < Moved
def self.artifact_english_name def self.artifact_english_name
"Preference Pane" "Preference Pane"
end end
end end
end
end

View File

@ -1,6 +1,8 @@
require "hbc/artifact/moved" require "hbc/artifact/moved"
class Hbc::Artifact::Qlplugin < Hbc::Artifact::Moved module Hbc
module Artifact
class Qlplugin < Moved
def self.artifact_english_name def self.artifact_english_name
"QuickLook Plugin" "QuickLook Plugin"
end end
@ -19,3 +21,5 @@ class Hbc::Artifact::Qlplugin < Hbc::Artifact::Moved
@command.run!("/usr/bin/qlmanage", args: ["-r"]) @command.run!("/usr/bin/qlmanage", args: ["-r"])
end end
end end
end
end

View File

@ -1,6 +1,8 @@
require "hbc/artifact/base" require "hbc/artifact/base"
class Hbc::Artifact::Relocated < Hbc::Artifact::Base module Hbc
module Artifact
class Relocated < Base
def summary def summary
{ {
english_description: self.class.english_description, english_description: self.class.english_description,
@ -40,10 +42,10 @@ class Hbc::Artifact::Relocated < Hbc::Artifact::Base
def load_specification(artifact_spec) def load_specification(artifact_spec)
source_string, target_hash = artifact_spec source_string, target_hash = artifact_spec
raise Hbc::CaskInvalidError if source_string.nil? raise CaskInvalidError if source_string.nil?
@source = @cask.staged_path.join(source_string) @source = @cask.staged_path.join(source_string)
if target_hash if target_hash
raise Hbc::CaskInvalidError unless target_hash.respond_to?(:keys) raise CaskInvalidError unless target_hash.respond_to?(:keys)
target_hash.assert_valid_keys(:target) target_hash.assert_valid_keys(:target)
@target = Hbc.send(self.class.artifact_dirmethod).join(target_hash[:target]) @target = Hbc.send(self.class.artifact_dirmethod).join(target_hash[:target])
else else
@ -51,3 +53,5 @@ class Hbc::Artifact::Relocated < Hbc::Artifact::Base
end end
end end
end end
end
end

View File

@ -1,4 +1,8 @@
require "hbc/artifact/moved" require "hbc/artifact/moved"
class Hbc::Artifact::ScreenSaver < Hbc::Artifact::Moved module Hbc
module Artifact
class ScreenSaver < Moved
end
end
end end

View File

@ -1,4 +1,8 @@
require "hbc/artifact/moved" require "hbc/artifact/moved"
class Hbc::Artifact::Service < Hbc::Artifact::Moved module Hbc
module Artifact
class Service < Moved
end
end
end end

View File

@ -1,6 +1,8 @@
require "hbc/artifact/base" require "hbc/artifact/base"
class Hbc::Artifact::StageOnly < Hbc::Artifact::Base module Hbc
module Artifact
class StageOnly < Base
def self.artifact_dsl_key def self.artifact_dsl_key
:stage_only :stage_only
end end
@ -13,3 +15,5 @@ class Hbc::Artifact::StageOnly < Hbc::Artifact::Base
# do nothing # do nothing
end end
end end
end
end

View File

@ -1,6 +1,8 @@
require "hbc/artifact/moved" require "hbc/artifact/moved"
class Hbc::Artifact::Suite < Hbc::Artifact::Moved module Hbc
module Artifact
class Suite < Moved
def self.artifact_english_name def self.artifact_english_name
"App Suite" "App Suite"
end end
@ -9,3 +11,5 @@ class Hbc::Artifact::Suite < Hbc::Artifact::Moved
:appdir :appdir
end end
end end
end
end

View File

@ -1,6 +1,8 @@
require "hbc/artifact/relocated" require "hbc/artifact/relocated"
class Hbc::Artifact::Symlinked < Hbc::Artifact::Relocated module Hbc
module Artifact
class Symlinked < Relocated
def self.link_type_english_name def self.link_type_english_name
"Symlink" "Symlink"
end end
@ -41,7 +43,7 @@ class Hbc::Artifact::Symlinked < Hbc::Artifact::Relocated
return false return false
end end
unless source.exist? unless source.exist?
raise Hbc::CaskError, "It seems the #{self.class.link_type_english_name.downcase} source is not there: '#{source}'" raise CaskError, "It seems the #{self.class.link_type_english_name.downcase} source is not there: '#{source}'"
end end
true true
end end
@ -63,3 +65,5 @@ class Hbc::Artifact::Symlinked < Hbc::Artifact::Relocated
"#{link_description}#{printable_target} -> #{target.readlink}#{target_readlink_abv}" "#{link_description}#{printable_target} -> #{target.readlink}#{target_readlink_abv}"
end end
end end
end
end

View File

@ -1,4 +1,8 @@
require "hbc/artifact/uninstall_base" require "hbc/artifact/uninstall_base"
class Hbc::Artifact::Uninstall < Hbc::Artifact::UninstallBase module Hbc
module Artifact
class Uninstall < UninstallBase
end
end
end end

View File

@ -2,7 +2,9 @@ require "pathname"
require "hbc/artifact/base" require "hbc/artifact/base"
class Hbc::Artifact::UninstallBase < Hbc::Artifact::Base module Hbc
module Artifact
class UninstallBase < Base
# TODO: 500 is also hardcoded in cask/pkg.rb, but much of # TODO: 500 is also hardcoded in cask/pkg.rb, but much of
# that logic is probably in the wrong location # that logic is probably in the wrong location
@ -135,7 +137,7 @@ class Hbc::Artifact::UninstallBase < Hbc::Artifact::Base
# :signal should come after :quit so it can be used as a backup when :quit fails # :signal should come after :quit so it can be used as a backup when :quit fails
def uninstall_signal(directives) def uninstall_signal(directives)
Array(directives[:signal]).flatten.each_slice(2) do |pair| Array(directives[:signal]).flatten.each_slice(2) do |pair|
raise Hbc::CaskInvalidError.new(@cask, "Each #{stanza} :signal must have 2 elements.") unless pair.length == 2 raise CaskInvalidError.new(@cask, "Each #{stanza} :signal must have 2 elements.") unless pair.length == 2
signal, id = pair signal, id = pair
ohai "Signalling '#{signal}' to application ID '#{id}'" ohai "Signalling '#{signal}' to application ID '#{id}'"
pids = get_unix_pids(id) pids = get_unix_pids(id)
@ -196,7 +198,7 @@ class Hbc::Artifact::UninstallBase < Hbc::Artifact::Base
{ print_stdout: true }, { print_stdout: true },
directive_name) directive_name)
ohai "Running uninstall script #{executable}" ohai "Running uninstall script #{executable}"
raise Hbc::CaskInvalidError.new(@cask, "#{stanza} :#{directive_name} without :executable.") if executable.nil? raise CaskInvalidError.new(@cask, "#{stanza} :#{directive_name} without :executable.") if executable.nil?
executable_path = @cask.staged_path.join(executable) executable_path = @cask.staged_path.join(executable)
@command.run("/bin/chmod", args: ["--", "+x", executable_path]) if File.exist?(executable_path) @command.run("/bin/chmod", args: ["--", "+x", executable_path]) if File.exist?(executable_path)
@command.run(executable_path, script_arguments) @command.run(executable_path, script_arguments)
@ -247,3 +249,5 @@ class Hbc::Artifact::UninstallBase < Hbc::Artifact::Base
end end
end end
end end
end
end

View File

@ -1,4 +1,8 @@
require "hbc/artifact/moved" require "hbc/artifact/moved"
class Hbc::Artifact::Vst3Plugin < Hbc::Artifact::Moved module Hbc
module Artifact
class Vst3Plugin < Moved
end
end
end end

View File

@ -1,4 +1,8 @@
require "hbc/artifact/moved" require "hbc/artifact/moved"
class Hbc::Artifact::VstPlugin < Hbc::Artifact::Moved module Hbc
module Artifact
class VstPlugin < Moved
end
end
end end

View File

@ -1,6 +1,8 @@
require "hbc/artifact/uninstall_base" require "hbc/artifact/uninstall_base"
class Hbc::Artifact::Zap < Hbc::Artifact::UninstallBase module Hbc
module Artifact
class Zap < UninstallBase
def install_phase def install_phase
odebug "Nothing to do. The zap artifact has no install phase." odebug "Nothing to do. The zap artifact has no install phase."
end end
@ -14,3 +16,5 @@ class Hbc::Artifact::Zap < Hbc::Artifact::UninstallBase
dispatch_uninstall_directives(expand_tilde) dispatch_uninstall_directives(expand_tilde)
end end
end end
end
end

View File

@ -2,12 +2,13 @@ require "hbc/checkable"
require "hbc/download" require "hbc/download"
require "digest" require "digest"
class Hbc::Audit module Hbc
include Hbc::Checkable class Audit
include Checkable
attr_reader :cask, :download attr_reader :cask, :download
def initialize(cask, download: false, check_token_conflicts: false, command: Hbc::SystemCommand) def initialize(cask, download: false, check_token_conflicts: false, command: SystemCommand)
@cask = cask @cask = cask
@download = download @download = download
@check_token_conflicts = check_token_conflicts @check_token_conflicts = check_token_conflicts
@ -114,7 +115,7 @@ class Hbc::Audit
def check_appcast_http_code def check_appcast_http_code
odebug "Verifying appcast returns 200 HTTP response code" odebug "Verifying appcast returns 200 HTTP response code"
result = @command.run("/usr/bin/curl", args: ["--compressed", "--location", "--user-agent", Hbc::URL::FAKE_USER_AGENT, "--output", "/dev/null", "--write-out", "%{http_code}", cask.appcast], print_stderr: false) result = @command.run("/usr/bin/curl", args: ["--compressed", "--location", "--user-agent", URL::FAKE_USER_AGENT, "--output", "/dev/null", "--write-out", "%{http_code}", cask.appcast], print_stderr: false)
if result.success? if result.success?
http_code = result.stdout.chomp http_code = result.stdout.chomp
add_warning "unexpected HTTP response code retrieving appcast: #{http_code}" unless http_code == "200" add_warning "unexpected HTTP response code retrieving appcast: #{http_code}" unless http_code == "200"
@ -125,7 +126,7 @@ class Hbc::Audit
def check_appcast_checkpoint_accuracy def check_appcast_checkpoint_accuracy
odebug "Verifying appcast checkpoint is accurate" odebug "Verifying appcast checkpoint is accurate"
result = @command.run("/usr/bin/curl", args: ["--compressed", "--location", "--user-agent", Hbc::URL::FAKE_USER_AGENT, cask.appcast], print_stderr: false) result = @command.run("/usr/bin/curl", args: ["--compressed", "--location", "--user-agent", URL::FAKE_USER_AGENT, cask.appcast], print_stderr: false)
if result.success? if result.success?
processed_appcast_text = result.stdout.gsub(%r{<pubDate>[^<]*</pubDate>}, "") processed_appcast_text = result.stdout.gsub(%r{<pubDate>[^<]*</pubDate>}, "")
# This step is necessary to replicate running `sed` from the command line # This step is necessary to replicate running `sed` from the command line
@ -209,8 +210,9 @@ class Hbc::Audit
return unless download && cask.url return unless download && cask.url
odebug "Auditing download" odebug "Auditing download"
downloaded_path = download.perform downloaded_path = download.perform
Hbc::Verify.all(cask, downloaded_path) Verify.all(cask, downloaded_path)
rescue => e rescue => e
add_error "download not possible: #{e.message}" add_error "download not possible: #{e.message}"
end end
end end
end

View File

@ -1,10 +1,12 @@
class Hbc::Auditor module Hbc
class Auditor
def self.audit(cask, audit_download: false, check_token_conflicts: false) def self.audit(cask, audit_download: false, check_token_conflicts: false)
download = audit_download && Hbc::Download.new(cask) download = audit_download && Download.new(cask)
audit = Hbc::Audit.new(cask, download: download, audit = Audit.new(cask, download: download,
check_token_conflicts: check_token_conflicts) check_token_conflicts: check_token_conflicts)
audit.run! audit.run!
puts audit.summary puts audit.summary
audit.success? audit.success?
end end
end end
end

View File

@ -1,4 +1,5 @@
module Hbc::Cache module Hbc
module Cache
module_function module_function
def ensure_cache_exists def ensure_cache_exists
@ -16,7 +17,7 @@ module Hbc::Cache
file = symlink.readlink file = symlink.readlink
new_name = file.basename new_name = file.basename
.sub(%r{\-((?:(\d|#{Hbc::DSL::Version::DIVIDER_REGEX})*\-\2*)*[^\-]+)$}x, .sub(%r{\-((?:(\d|#{DSL::Version::DIVIDER_REGEX})*\-\2*)*[^\-]+)$}x,
'--\1') '--\1')
renamed_file = Hbc.cache.join(new_name) renamed_file = Hbc.cache.join(new_name)
@ -32,3 +33,4 @@ module Hbc::Cache
FileUtils.remove_entry_secure(Hbc.legacy_cache) FileUtils.remove_entry_secure(Hbc.legacy_cache)
end end
end end
end

View File

@ -2,18 +2,19 @@ require "forwardable"
require "hbc/dsl" require "hbc/dsl"
class Hbc::Cask module Hbc
class Cask
extend Forwardable extend Forwardable
attr_reader :token, :sourcefile_path attr_reader :token, :sourcefile_path
def initialize(token, sourcefile_path: nil, dsl: nil, &block) def initialize(token, sourcefile_path: nil, dsl: nil, &block)
@token = token @token = token
@sourcefile_path = sourcefile_path @sourcefile_path = sourcefile_path
@dsl = dsl || Hbc::DSL.new(@token) @dsl = dsl || DSL.new(@token)
@dsl.instance_eval(&block) if block_given? @dsl.instance_eval(&block) if block_given?
end end
Hbc::DSL::DSL_METHODS.each do |method_name| DSL::DSL_METHODS.each do |method_name|
define_method(method_name) { @dsl.send(method_name) } define_method(method_name) { @dsl.send(method_name) }
end end
@ -31,12 +32,12 @@ class Hbc::Cask
def metadata_path(timestamp = :latest, create = false) def metadata_path(timestamp = :latest, create = false)
return nil unless metadata_versioned_container_path.respond_to?(:join) return nil unless metadata_versioned_container_path.respond_to?(:join)
if create && timestamp == :latest if create && timestamp == :latest
raise Hbc::CaskError, "Cannot create metadata path when timestamp is :latest" raise CaskError, "Cannot create metadata path when timestamp is :latest"
end end
path = if timestamp == :latest path = if timestamp == :latest
Pathname.glob(metadata_versioned_container_path.join("*")).sort.last Pathname.glob(metadata_versioned_container_path.join("*")).sort.last
elsif timestamp == :now elsif timestamp == :now
Hbc::Utils.nowstamp_metadata_path(metadata_versioned_container_path) Utils.nowstamp_metadata_path(metadata_versioned_container_path)
else else
metadata_versioned_container_path.join(timestamp) metadata_versioned_container_path.join(timestamp)
end end
@ -49,10 +50,10 @@ class Hbc::Cask
def metadata_subdir(leaf, timestamp = :latest, create = false) def metadata_subdir(leaf, timestamp = :latest, create = false)
if create && timestamp == :latest if create && timestamp == :latest
raise Hbc::CaskError, "Cannot create metadata subdir when timestamp is :latest" raise CaskError, "Cannot create metadata subdir when timestamp is :latest"
end end
unless leaf.respond_to?(:length) && !leaf.empty? unless leaf.respond_to?(:length) && !leaf.empty?
raise Hbc::CaskError, "Cannot create metadata subdir for empty leaf" raise CaskError, "Cannot create metadata subdir for empty leaf"
end end
parent = metadata_path(timestamp, create) parent = metadata_path(timestamp, create)
return nil unless parent.respond_to?(:join) return nil unless parent.respond_to?(:join)
@ -113,3 +114,4 @@ class Hbc::Cask
end end
end end
end end
end

View File

@ -1,6 +1,7 @@
require "hbc/topological_hash" require "hbc/topological_hash"
class Hbc::CaskDependencies module Hbc
class CaskDependencies
attr_reader :cask, :graph, :sorted attr_reader :cask, :graph, :sorted
def initialize(cask) def initialize(cask)
@ -22,12 +23,13 @@ class Hbc::CaskDependencies
} }
graphed = walk.call({}, @cask.depends_on.cask) graphed = walk.call({}, @cask.depends_on.cask)
Hbc::TopologicalHash[graphed] TopologicalHash[graphed]
end end
def sort def sort
@graph.tsort @graph.tsort
rescue TSort::Cyclic rescue TSort::Cyclic
raise Hbc::CaskCyclicCaskDependencyError, @cask.token raise CaskCyclicCaskDependencyError, @cask.token
end
end end
end end

View File

@ -1,4 +1,5 @@
module Hbc::Caskroom module Hbc
module Caskroom
module_function module_function
def migrate_caskroom_from_repo_to_prefix def migrate_caskroom_from_repo_to_prefix
@ -35,7 +36,8 @@ module Hbc::Caskroom
# sudo in system is rude. # sudo in system is rude.
system "/usr/bin/sudo", "--", "/bin/mkdir", "-p", "--", Hbc.caskroom system "/usr/bin/sudo", "--", "/bin/mkdir", "-p", "--", Hbc.caskroom
unless Hbc.caskroom.parent == toplevel_dir unless Hbc.caskroom.parent == toplevel_dir
system "/usr/bin/sudo", "--", "/usr/sbin/chown", "-R", "--", "#{Hbc::Utils.current_user}:staff", Hbc.caskroom.parent.to_s system "/usr/bin/sudo", "--", "/usr/sbin/chown", "-R", "--", "#{Utils.current_user}:staff", Hbc.caskroom.parent.to_s
end
end end
end end
end end

View File

@ -1,12 +1,14 @@
class Hbc::Caveats module Hbc
class Caveats
def initialize(block) def initialize(block)
@block = block @block = block
end end
def eval_and_print(cask) def eval_and_print(cask)
dsl = Hbc::DSL::Caveats.new(cask) dsl = DSL::Caveats.new(cask)
retval = dsl.instance_eval(&@block) retval = dsl.instance_eval(&@block)
return if retval.nil? return if retval.nil?
puts retval.to_s.sub(%r{[\r\n \t]*\Z}, "\n\n") puts retval.to_s.sub(%r{[\r\n \t]*\Z}, "\n\n")
end end
end end
end

View File

@ -1,4 +1,5 @@
module Hbc::Checkable module Hbc
module Checkable
def errors def errors
Array(@errors) Array(@errors)
end end
@ -49,3 +50,4 @@ module Hbc::Checkable
summary.join("\n") summary.join("\n")
end end
end end
end

View File

@ -1,5 +1,3 @@
class Hbc::CLI; end
require "optparse" require "optparse"
require "shellwords" require "shellwords"
@ -28,7 +26,8 @@ require "hbc/cli/internal_dump"
require "hbc/cli/internal_help" require "hbc/cli/internal_help"
require "hbc/cli/internal_stanza" require "hbc/cli/internal_stanza"
class Hbc::CLI module Hbc
class CLI
ALIASES = { ALIASES = {
"ls" => "list", "ls" => "list",
"homepage" => "home", "homepage" => "home",
@ -72,8 +71,8 @@ class Hbc::CLI
}.freeze }.freeze
def self.command_classes def self.command_classes
@command_classes ||= Hbc::CLI.constants @command_classes ||= self.constants
.map(&Hbc::CLI.method(:const_get)) .map(&method(:const_get))
.select { |sym| sym.respond_to?(:run) } .select { |sym| sym.respond_to?(:run) }
end end
@ -99,21 +98,21 @@ class Hbc::CLI
end end
def self.should_init?(command) def self.should_init?(command)
(command.is_a? Class) && (command < Hbc::CLI::Base) && command.needs_init? (command.is_a? Class) && (command < CLI::Base) && command.needs_init?
end end
def self.run_command(command, *rest) def self.run_command(command, *rest)
if command.respond_to?(:run) if command.respond_to?(:run)
# usual case: built-in command verb # usual case: built-in command verb
command.run(*rest) command.run(*rest)
elsif require? Hbc::Utils.which("brewcask-#{command}.rb").to_s elsif require? Utils.which("brewcask-#{command}.rb").to_s
# external command as Ruby library on PATH, Homebrew-style # external command as Ruby library on PATH, Homebrew-style
elsif command.to_s.include?("/") && require?(command.to_s) elsif command.to_s.include?("/") && require?(command.to_s)
# external command as Ruby library with literal path, useful # external command as Ruby library with literal path, useful
# for development and troubleshooting # for development and troubleshooting
sym = Pathname.new(command.to_s).basename(".rb").to_s.capitalize sym = Pathname.new(command.to_s).basename(".rb").to_s.capitalize
klass = begin klass = begin
Hbc::CLI.const_get(sym) self.const_get(sym)
rescue NameError rescue NameError
nil nil
end end
@ -123,7 +122,7 @@ class Hbc::CLI
# other Ruby libraries must do everything via "require" # other Ruby libraries must do everything via "require"
klass.run(*rest) klass.run(*rest)
end end
elsif Hbc::Utils.which "brewcask-#{command}" elsif Utils.which "brewcask-#{command}"
# arbitrary external executable on PATH, Homebrew-style # arbitrary external executable on PATH, Homebrew-style
exec "brewcask-#{command}", *ARGV[1..-1] exec "brewcask-#{command}", *ARGV[1..-1]
elsif Pathname.new(command.to_s).executable? && elsif Pathname.new(command.to_s).executable? &&
@ -134,7 +133,7 @@ class Hbc::CLI
exec command, *ARGV[1..-1] exec command, *ARGV[1..-1]
else else
# failure # failure
Hbc::CLI::NullCommand.new(command).run NullCommand.new(command).run
end end
end end
@ -145,14 +144,14 @@ class Hbc::CLI
Hbc.default_tap.install unless Hbc.default_tap.installed? Hbc.default_tap.install unless Hbc.default_tap.installed?
Hbc.init if should_init?(command) Hbc.init if should_init?(command)
run_command(command, *rest) run_command(command, *rest)
rescue Hbc::CaskError, Hbc::CaskSha256MismatchError => e rescue CaskError, CaskSha256MismatchError => e
msg = e.message msg = e.message
msg << e.backtrace.join("\n") if Hbc.debug msg << e.backtrace.join("\n") if Hbc.debug
onoe msg onoe msg
exit 1 exit 1
rescue StandardError, ScriptError, NoMemoryError => e rescue StandardError, ScriptError, NoMemoryError => e
msg = e.message msg = e.message
msg << Hbc::Utils.error_message_with_suggestions msg << Utils.error_message_with_suggestions
msg << e.backtrace.join("\n") msg << e.backtrace.join("\n")
onoe msg onoe msg
exit 1 exit 1
@ -216,9 +215,9 @@ class Hbc::CLI
remaining << head remaining << head
retry retry
rescue OptionParser::MissingArgument rescue OptionParser::MissingArgument
raise Hbc::CaskError, "The option '#{head}' requires an argument" raise CaskError, "The option '#{head}' requires an argument"
rescue OptionParser::AmbiguousOption rescue OptionParser::AmbiguousOption
raise Hbc::CaskError, "There is more than one possible option that starts with '#{head}'" raise CaskError, "There is more than one possible option that starts with '#{head}'"
end end
end end
@ -240,7 +239,7 @@ class Hbc::CLI
purpose purpose
usage usage
unless @attempted_verb.to_s.strip.empty? || @attempted_verb == "help" unless @attempted_verb.to_s.strip.empty? || @attempted_verb == "help"
raise Hbc::CaskError, "Unknown command: #{@attempted_verb}" raise CaskError, "Unknown command: #{@attempted_verb}"
end end
end end
end end
@ -254,10 +253,10 @@ class Hbc::CLI
end end
def usage def usage
max_command_len = Hbc::CLI.commands.map(&:length).max max_command_len = CLI.commands.map(&:length).max
puts "Commands:\n\n" puts "Commands:\n\n"
Hbc::CLI.command_classes.each do |klass| CLI.command_classes.each do |klass|
next unless klass.visible next unless klass.visible
puts " #{klass.command_name.ljust(max_command_len)} #{_help_for(klass)}" puts " #{klass.command_name.ljust(max_command_len)} #{_help_for(klass)}"
end end
@ -273,3 +272,4 @@ class Hbc::CLI
end end
end end
end end
end

View File

@ -1,12 +1,14 @@
class Hbc::CLI::Audit < Hbc::CLI::Base module Hbc
class CLI
class Audit < Base
def self.help def self.help
"verifies installability of Casks" "verifies installability of Casks"
end end
def self.run(*args) def self.run(*args)
failed_casks = new(args, Hbc::Auditor).run failed_casks = new(args, Auditor).run
return if failed_casks.empty? return if failed_casks.empty?
raise Hbc::CaskError, "audit failed for casks: #{failed_casks.join(" ")}" raise CaskError, "audit failed for casks: #{failed_casks.join(" ")}"
end end
def initialize(args, auditor) def initialize(args, auditor)
@ -50,3 +52,5 @@ class Hbc::CLI::Audit < Hbc::CLI::Base
true true
end end
end end
end
end

View File

@ -1,4 +1,6 @@
class Hbc::CLI::Base module Hbc
class CLI
class Base
def self.command_name def self.command_name
@command_name ||= name.sub(%r{^.*:}, "").gsub(%r{(.)([A-Z])}, '\1_\2').downcase @command_name ||= name.sub(%r{^.*:}, "").gsub(%r{(.)([A-Z])}, '\1_\2').downcase
end end
@ -19,3 +21,5 @@ class Hbc::CLI::Base
false false
end end
end end
end
end

View File

@ -1,11 +1,13 @@
class Hbc::CLI::Cat < Hbc::CLI::Base module Hbc
class CLI
class Cat < Base
def self.run(*args) def self.run(*args)
cask_tokens = cask_tokens_from(args) cask_tokens = cask_tokens_from(args)
raise Hbc::CaskUnspecifiedError if cask_tokens.empty? raise CaskUnspecifiedError if cask_tokens.empty?
# only respects the first argument # only respects the first argument
cask_token = cask_tokens.first.sub(%r{\.rb$}i, "") cask_token = cask_tokens.first.sub(%r{\.rb$}i, "")
cask_path = Hbc.path(cask_token) cask_path = Hbc.path(cask_token)
raise Hbc::CaskUnavailableError, cask_token.to_s unless cask_path.exist? raise CaskUnavailableError, cask_token.to_s unless cask_path.exist?
puts File.open(cask_path, &:read) puts File.open(cask_path, &:read)
end end
@ -13,3 +15,5 @@ class Hbc::CLI::Cat < Hbc::CLI::Base
"dump raw source of the given Cask to the standard output" "dump raw source of the given Cask to the standard output"
end end
end end
end
end

View File

@ -1,4 +1,6 @@
class Hbc::CLI::Cleanup < Hbc::CLI::Base module Hbc
class CLI
class Cleanup < Base
OUTDATED_DAYS = 10 OUTDATED_DAYS = 10
OUTDATED_TIMESTAMP = Time.now - (60 * 60 * 24 * OUTDATED_DAYS) OUTDATED_TIMESTAMP = Time.now - (60 * 60 * 24 * OUTDATED_DAYS)
@ -60,7 +62,7 @@ class Hbc::CLI::Cleanup < Hbc::CLI::Base
end end
def disk_cleanup_size def disk_cleanup_size
Hbc::Utils.size_in_bytes(cache_files) Utils.size_in_bytes(cache_files)
end end
def remove_cache_files(*tokens) def remove_cache_files(*tokens)
@ -88,7 +90,7 @@ class Hbc::CLI::Cleanup < Hbc::CLI::Base
paths.each do |item| paths.each do |item|
next unless item.exist? next unless item.exist?
processed_files += 1 processed_files += 1
if Hbc::Utils.file_locked?(item) if Utils.file_locked?(item)
puts "skipping: #{item} is locked" puts "skipping: #{item} is locked"
next next
end end
@ -106,3 +108,5 @@ class Hbc::CLI::Cleanup < Hbc::CLI::Base
end end
end end
end end
end
end

View File

@ -1,12 +1,14 @@
class Hbc::CLI::Create < Hbc::CLI::Base module Hbc
class CLI
class Create < Base
def self.run(*args) def self.run(*args)
cask_tokens = cask_tokens_from(args) cask_tokens = cask_tokens_from(args)
raise Hbc::CaskUnspecifiedError if cask_tokens.empty? raise CaskUnspecifiedError if cask_tokens.empty?
cask_token = cask_tokens.first.sub(%r{\.rb$}i, "") cask_token = cask_tokens.first.sub(%r{\.rb$}i, "")
cask_path = Hbc.path(cask_token) cask_path = Hbc.path(cask_token)
odebug "Creating Cask #{cask_token}" odebug "Creating Cask #{cask_token}"
raise Hbc::CaskAlreadyCreatedError, cask_token if cask_path.exist? raise CaskAlreadyCreatedError, cask_token if cask_path.exist?
File.open(cask_path, "w") do |f| File.open(cask_path, "w") do |f|
f.write template(cask_token) f.write template(cask_token)
@ -35,3 +37,5 @@ class Hbc::CLI::Create < Hbc::CLI::Base
"creates the given Cask and opens it in an editor" "creates the given Cask and opens it in an editor"
end end
end end
end
end

View File

@ -1,4 +1,6 @@
class Hbc::CLI::Doctor < Hbc::CLI::Base module Hbc
class CLI
class Doctor < Base
def self.run def self.run
ohai "macOS Release:", render_with_none_as_error(MacOS.full_version) ohai "macOS Release:", render_with_none_as_error(MacOS.full_version)
ohai "Hardware Architecture:", render_with_none_as_error("#{Hardware::CPU.type}-#{Hardware::CPU.bits}") ohai "Hardware Architecture:", render_with_none_as_error("#{Hardware::CPU.type}-#{Hardware::CPU.bits}")
@ -47,7 +49,7 @@ class Hbc::CLI::Doctor < Hbc::CLI::Base
homebrew_origin = notfound_string homebrew_origin = notfound_string
begin begin
Dir.chdir(homebrew_repository) do Dir.chdir(homebrew_repository) do
homebrew_origin = Hbc::SystemCommand.run("/usr/bin/git", homebrew_origin = SystemCommand.run("/usr/bin/git",
args: %w[config --get remote.origin.url], args: %w[config --get remote.origin.url],
print_stderr: false).stdout.strip print_stderr: false).stdout.strip
end end
@ -85,7 +87,7 @@ class Hbc::CLI::Doctor < Hbc::CLI::Base
return @homebrew_constants[name] if @homebrew_constants.key?(name) return @homebrew_constants[name] if @homebrew_constants.key?(name)
@homebrew_constants[name] = notfound_string @homebrew_constants[name] = notfound_string
begin begin
@homebrew_constants[name] = Hbc::SystemCommand.run!(Hbc.homebrew_executable, @homebrew_constants[name] = SystemCommand.run!(Hbc.homebrew_executable,
args: ["--#{name}"], args: ["--#{name}"],
print_stderr: false) print_stderr: false)
.stdout .stdout
@ -189,7 +191,7 @@ class Hbc::CLI::Doctor < Hbc::CLI::Base
end end
def self.render_cached_downloads def self.render_cached_downloads
cleanup = Hbc::CLI::Cleanup.default cleanup = CLI::Cleanup.default
files = cleanup.cache_files files = cleanup.cache_files
count = files.count count = files.count
size = cleanup.disk_cleanup_size size = cleanup.disk_cleanup_size
@ -203,3 +205,5 @@ class Hbc::CLI::Doctor < Hbc::CLI::Base
"checks for configuration issues" "checks for configuration issues"
end end
end end
end
end

View File

@ -1,13 +1,15 @@
class Hbc::CLI::Edit < Hbc::CLI::Base module Hbc
class CLI
class Edit < Base
def self.run(*args) def self.run(*args)
cask_tokens = cask_tokens_from(args) cask_tokens = cask_tokens_from(args)
raise Hbc::CaskUnspecifiedError if cask_tokens.empty? raise CaskUnspecifiedError if cask_tokens.empty?
# only respects the first argument # only respects the first argument
cask_token = cask_tokens.first.sub(%r{\.rb$}i, "") cask_token = cask_tokens.first.sub(%r{\.rb$}i, "")
cask_path = Hbc.path(cask_token) cask_path = Hbc.path(cask_token)
odebug "Opening editor for Cask #{cask_token}" odebug "Opening editor for Cask #{cask_token}"
unless cask_path.exist? unless cask_path.exist?
raise Hbc::CaskUnavailableError, %Q{#{cask_token}, run "brew cask create #{cask_token}" to create a new Cask} raise CaskUnavailableError, %Q{#{cask_token}, run "brew cask create #{cask_token}" to create a new Cask}
end end
exec_editor cask_path exec_editor cask_path
end end
@ -16,3 +18,5 @@ class Hbc::CLI::Edit < Hbc::CLI::Base
"edits the given Cask" "edits the given Cask"
end end
end end
end
end

View File

@ -1,14 +1,16 @@
class Hbc::CLI::Fetch < Hbc::CLI::Base module Hbc
class CLI
class Fetch < Base
def self.run(*args) def self.run(*args)
cask_tokens = cask_tokens_from(args) cask_tokens = cask_tokens_from(args)
raise Hbc::CaskUnspecifiedError if cask_tokens.empty? raise CaskUnspecifiedError if cask_tokens.empty?
force = args.include? "--force" force = args.include? "--force"
cask_tokens.each do |cask_token| cask_tokens.each do |cask_token|
ohai "Downloading external files for Cask #{cask_token}" ohai "Downloading external files for Cask #{cask_token}"
cask = Hbc.load(cask_token) cask = Hbc.load(cask_token)
downloaded_path = Hbc::Download.new(cask, force: force).perform downloaded_path = Download.new(cask, force: force).perform
Hbc::Verify.all(cask, downloaded_path) Verify.all(cask, downloaded_path)
ohai "Success! Downloaded to -> #{downloaded_path}" ohai "Success! Downloaded to -> #{downloaded_path}"
end end
end end
@ -17,3 +19,5 @@ class Hbc::CLI::Fetch < Hbc::CLI::Base
"downloads remote application files to local cache" "downloads remote application files to local cache"
end end
end end
end
end

View File

@ -1,4 +1,6 @@
class Hbc::CLI::Home < Hbc::CLI::Base module Hbc
class CLI
class Home < Base
def self.run(*cask_tokens) def self.run(*cask_tokens)
if cask_tokens.empty? if cask_tokens.empty?
odebug "Opening project homepage" odebug "Opening project homepage"
@ -16,3 +18,5 @@ class Hbc::CLI::Home < Hbc::CLI::Base
"opens the homepage of the given Cask" "opens the homepage of the given Cask"
end end
end end
end
end

View File

@ -1,7 +1,9 @@
class Hbc::CLI::Info < Hbc::CLI::Base module Hbc
class CLI
class Info < Base
def self.run(*args) def self.run(*args)
cask_tokens = cask_tokens_from(args) cask_tokens = cask_tokens_from(args)
raise Hbc::CaskUnspecifiedError if cask_tokens.empty? raise CaskUnspecifiedError if cask_tokens.empty?
cask_tokens.each do |cask_token| cask_tokens.each do |cask_token|
odebug "Getting info for Cask #{cask_token}" odebug "Getting info for Cask #{cask_token}"
cask = Hbc.load(cask_token) cask = Hbc.load(cask_token)
@ -21,7 +23,7 @@ class Hbc::CLI::Info < Hbc::CLI::Base
puts "From: #{formatted_url(github_info(cask))}" if github_info(cask) puts "From: #{formatted_url(github_info(cask))}" if github_info(cask)
name_info(cask) name_info(cask)
artifact_info(cask) artifact_info(cask)
Hbc::Installer.print_caveats(cask) Installer.print_caveats(cask)
end end
def self.formatted_url(url) def self.formatted_url(url)
@ -49,13 +51,13 @@ class Hbc::CLI::Info < Hbc::CLI::Base
end end
def self.github_info(cask) def self.github_info(cask)
user, repo, token = Hbc::QualifiedToken.parse(Hbc.all_tokens.detect { |t| t.split("/").last == cask.token }) user, repo, token = QualifiedToken.parse(Hbc.all_tokens.detect { |t| t.split("/").last == cask.token })
"#{Tap.fetch(user, repo).default_remote}/blob/master/Casks/#{token}.rb" "#{Tap.fetch(user, repo).default_remote}/blob/master/Casks/#{token}.rb"
end end
def self.artifact_info(cask) def self.artifact_info(cask)
ohai "Artifacts" ohai "Artifacts"
Hbc::DSL::ORDINARY_ARTIFACT_TYPES.each do |type| DSL::ORDINARY_ARTIFACT_TYPES.each do |type|
next if cask.artifacts[type].empty? next if cask.artifacts[type].empty?
cask.artifacts[type].each do |artifact| cask.artifacts[type].each do |artifact|
activatable_item = type == :stage_only ? "<none>" : artifact.first activatable_item = type == :stage_only ? "<none>" : artifact.first
@ -64,3 +66,5 @@ class Hbc::CLI::Info < Hbc::CLI::Base
end end
end end
end end
end
end

View File

@ -1,16 +1,17 @@
module Hbc
class Hbc::CLI::Install < Hbc::CLI::Base class CLI
class Install < Base
def self.run(*args) def self.run(*args)
cask_tokens = cask_tokens_from(args) cask_tokens = cask_tokens_from(args)
raise Hbc::CaskUnspecifiedError if cask_tokens.empty? raise CaskUnspecifiedError if cask_tokens.empty?
force = args.include? "--force" force = args.include? "--force"
skip_cask_deps = args.include? "--skip-cask-deps" skip_cask_deps = args.include? "--skip-cask-deps"
require_sha = args.include? "--require-sha" require_sha = args.include? "--require-sha"
retval = install_casks cask_tokens, force, skip_cask_deps, require_sha retval = install_casks cask_tokens, force, skip_cask_deps, require_sha
# retval is ternary: true/false/nil # retval is ternary: true/false/nil
raise Hbc::CaskError, "nothing to install" if retval.nil? raise CaskError, "nothing to install" if retval.nil?
raise Hbc::CaskError, "install incomplete" unless retval raise CaskError, "install incomplete" unless retval
end end
def self.install_casks(cask_tokens, force, skip_cask_deps, require_sha) def self.install_casks(cask_tokens, force, skip_cask_deps, require_sha)
@ -18,20 +19,20 @@ class Hbc::CLI::Install < Hbc::CLI::Base
cask_tokens.each do |cask_token| cask_tokens.each do |cask_token|
begin begin
cask = Hbc.load(cask_token) cask = Hbc.load(cask_token)
Hbc::Installer.new(cask, Installer.new(cask,
force: force, force: force,
skip_cask_deps: skip_cask_deps, skip_cask_deps: skip_cask_deps,
require_sha: require_sha).install require_sha: require_sha).install
count += 1 count += 1
rescue Hbc::CaskAlreadyInstalledError => e rescue CaskAlreadyInstalledError => e
opoo e.message opoo e.message
count += 1 count += 1
rescue Hbc::CaskAutoUpdatesError => e rescue CaskAutoUpdatesError => e
opoo e.message opoo e.message
count += 1 count += 1
rescue Hbc::CaskUnavailableError => e rescue CaskUnavailableError => e
warn_unavailable_with_suggestion cask_token, e warn_unavailable_with_suggestion cask_token, e
rescue Hbc::CaskNoShasumError => e rescue CaskNoShasumError => e
opoo e.message opoo e.message
count += 1 count += 1
end end
@ -40,7 +41,7 @@ class Hbc::CLI::Install < Hbc::CLI::Base
end end
def self.warn_unavailable_with_suggestion(cask_token, e) def self.warn_unavailable_with_suggestion(cask_token, e)
exact_match, partial_matches = Hbc::CLI::Search.search(cask_token) exact_match, partial_matches = Search.search(cask_token)
errmsg = e.message errmsg = e.message
if exact_match if exact_match
errmsg.concat(". Did you mean:\n#{exact_match}") errmsg.concat(". Did you mean:\n#{exact_match}")
@ -58,3 +59,5 @@ class Hbc::CLI::Install < Hbc::CLI::Base
true true
end end
end end
end
end

View File

@ -1,4 +1,6 @@
class Hbc::CLI::InternalAuditModifiedCasks < Hbc::CLI::InternalUseBase module Hbc
class CLI
class InternalAuditModifiedCasks < InternalUseBase
RELEVANT_STANZAS = %i{version sha256 url appcast}.freeze RELEVANT_STANZAS = %i{version sha256 url appcast}.freeze
class << self class << self
@ -92,7 +94,7 @@ class Hbc::CLI::InternalAuditModifiedCasks < Hbc::CLI::InternalUseBase
def audit(cask, cask_file) def audit(cask, cask_file)
audit_download = audit_download?(cask, cask_file) audit_download = audit_download?(cask, cask_file)
check_token_conflicts = added_cask_files.include?(cask_file) check_token_conflicts = added_cask_files.include?(cask_file)
success = Hbc::Auditor.audit(cask, audit_download: audit_download, success = Auditor.audit(cask, audit_download: audit_download,
check_token_conflicts: check_token_conflicts) check_token_conflicts: check_token_conflicts)
failed_casks << cask unless success failed_casks << cask unless success
end end
@ -130,6 +132,8 @@ class Hbc::CLI::InternalAuditModifiedCasks < Hbc::CLI::InternalUseBase
end end
def cleanup def cleanup
Hbc::CLI::Cleanup.run if cleanup? Cleanup.run if cleanup?
end
end
end end
end end

View File

@ -1,9 +1,11 @@
class Hbc::CLI::InternalCheckurl < Hbc::CLI::InternalUseBase module Hbc
class CLI
class InternalCheckurl < InternalUseBase
def self.run(*args) def self.run(*args)
casks_to_check = args.empty? ? Hbc.all : args.map { |arg| Hbc.load(arg) } casks_to_check = args.empty? ? Hbc.all : args.map { |arg| Hbc.load(arg) }
casks_to_check.each do |cask| casks_to_check.each do |cask|
odebug "Checking URL for Cask #{cask}" odebug "Checking URL for Cask #{cask}"
checker = Hbc::UrlChecker.new(cask) checker = UrlChecker.new(cask)
checker.run checker.run
puts checker.summary puts checker.summary
end end
@ -13,3 +15,5 @@ class Hbc::CLI::InternalCheckurl < Hbc::CLI::InternalUseBase
"checks for bad Cask URLs" "checks for bad Cask URLs"
end end
end end
end
end

View File

@ -1,12 +1,14 @@
class Hbc::CLI::InternalDump < Hbc::CLI::InternalUseBase module Hbc
class CLI
class InternalDump < InternalUseBase
def self.run(*arguments) def self.run(*arguments)
cask_tokens = cask_tokens_from(arguments) cask_tokens = cask_tokens_from(arguments)
raise Hbc::CaskUnspecifiedError if cask_tokens.empty? raise CaskUnspecifiedError if cask_tokens.empty?
retval = dump_casks(*cask_tokens) retval = dump_casks(*cask_tokens)
# retval is ternary: true/false/nil # retval is ternary: true/false/nil
raise Hbc::CaskError, "nothing to dump" if retval.nil? raise CaskError, "nothing to dump" if retval.nil?
raise Hbc::CaskError, "dump incomplete" unless retval raise CaskError, "dump incomplete" unless retval
end end
def self.dump_casks(*cask_tokens) def self.dump_casks(*cask_tokens)
@ -28,3 +30,5 @@ class Hbc::CLI::InternalDump < Hbc::CLI::InternalUseBase
"Dump the given Cask in YAML format" "Dump the given Cask in YAML format"
end end
end end
end
end

View File

@ -1,8 +1,10 @@
class Hbc::CLI::InternalHelp < Hbc::CLI::InternalUseBase module Hbc
class CLI
class InternalHelp < InternalUseBase
def self.run(*_ignored) def self.run(*_ignored)
max_command_len = Hbc::CLI.commands.map(&:length).max max_command_len = CLI.commands.map(&:length).max
puts "Unstable Internal-use Commands:\n\n" puts "Unstable Internal-use Commands:\n\n"
Hbc::CLI.command_classes.each do |klass| CLI.command_classes.each do |klass|
next if klass.visible next if klass.visible
puts " #{klass.command_name.ljust(max_command_len)} #{help_for(klass)}" puts " #{klass.command_name.ljust(max_command_len)} #{help_for(klass)}"
end end
@ -17,3 +19,5 @@ class Hbc::CLI::InternalHelp < Hbc::CLI::InternalUseBase
"Print help strings for unstable internal-use commands" "Print help strings for unstable internal-use commands"
end end
end end
end
end

View File

@ -1,4 +1,6 @@
class Hbc::CLI::InternalStanza < Hbc::CLI::InternalUseBase module Hbc
class CLI
class InternalStanza < InternalUseBase
# Syntax # Syntax
# #
# brew cask _stanza <stanza_name> [ --table | --yaml | --inspect | --quiet ] [ <cask_token> ... ] # brew cask _stanza <stanza_name> [ --table | --yaml | --inspect | --quiet ] [ <cask_token> ... ]
@ -61,10 +63,10 @@ class Hbc::CLI::InternalStanza < Hbc::CLI::InternalUseBase
# retval is ternary: true/false/nil # retval is ternary: true/false/nil
if retval.nil? if retval.nil?
exit 1 if quiet exit 1 if quiet
raise Hbc::CaskError, "nothing to print" raise CaskError, "nothing to print"
elsif !retval elsif !retval
exit 1 if quiet exit 1 if quiet
raise Hbc::CaskError, "print incomplete" raise CaskError, "print incomplete"
end end
end end
@ -125,3 +127,5 @@ class Hbc::CLI::InternalStanza < Hbc::CLI::InternalUseBase
"Extract and render a specific stanza for the given Casks" "Extract and render a specific stanza for the given Casks"
end end
end end
end
end

View File

@ -1,4 +1,6 @@
class Hbc::CLI::InternalUseBase < Hbc::CLI::Base module Hbc
class CLI
class InternalUseBase < Base
def self.command_name def self.command_name
super.sub(%r{^internal_}i, "_") super.sub(%r{^internal_}i, "_")
end end
@ -7,3 +9,5 @@ class Hbc::CLI::InternalUseBase < Hbc::CLI::Base
false false
end end
end end
end
end

View File

@ -1,4 +1,6 @@
class Hbc::CLI::List < Hbc::CLI::Base module Hbc
class CLI
class List < Base
def self.run(*arguments) def self.run(*arguments)
@options = {} @options = {}
@options[:one] = true if arguments.delete("-1") @options[:one] = true if arguments.delete("-1")
@ -14,9 +16,9 @@ class Hbc::CLI::List < Hbc::CLI::Base
if retval.nil? && !arguments.any? if retval.nil? && !arguments.any?
opoo "nothing to list" # special case: avoid exit code opoo "nothing to list" # special case: avoid exit code
elsif retval.nil? elsif retval.nil?
raise Hbc::CaskError, "nothing to list" raise CaskError, "nothing to list"
elsif !retval elsif !retval
raise Hbc::CaskError, "listing incomplete" raise CaskError, "listing incomplete"
end end
end end
@ -43,7 +45,7 @@ class Hbc::CLI::List < Hbc::CLI::Base
else else
opoo "#{cask} is not installed" opoo "#{cask} is not installed"
end end
rescue Hbc::CaskUnavailableError => e rescue CaskUnavailableError => e
onoe e onoe e
end end
end end
@ -52,7 +54,7 @@ class Hbc::CLI::List < Hbc::CLI::Base
end end
def self.list_artifacts(cask) def self.list_artifacts(cask)
Hbc::Artifact.for_cask(cask).each do |artifact| Artifact.for_cask(cask).each do |artifact|
summary = artifact.new(cask).summary summary = artifact.new(cask).summary
ohai summary[:english_description], summary[:contents] unless summary.empty? ohai summary[:english_description], summary[:contents] unless summary.empty?
end end
@ -84,3 +86,5 @@ class Hbc::CLI::List < Hbc::CLI::Base
true true
end end
end end
end
end

View File

@ -1,4 +1,6 @@
class Hbc::CLI::Search < Hbc::CLI::Base module Hbc
class CLI
class Search < Base
def self.run(*arguments) def self.run(*arguments)
render_results(*search(*arguments)) render_results(*search(*arguments))
end end
@ -16,7 +18,7 @@ class Hbc::CLI::Search < Hbc::CLI::Base
partial_matches = [] partial_matches = []
search_term = arguments.join(" ") search_term = arguments.join(" ")
search_regexp = extract_regexp arguments.first search_regexp = extract_regexp arguments.first
all_tokens = Hbc::CLI.nice_listing(Hbc.all_tokens) all_tokens = CLI.nice_listing(Hbc.all_tokens)
if search_regexp if search_regexp
search_term = arguments.first search_term = arguments.first
partial_matches = all_tokens.grep(%r{#{search_regexp}}i) partial_matches = all_tokens.grep(%r{#{search_regexp}}i)
@ -53,3 +55,5 @@ class Hbc::CLI::Search < Hbc::CLI::Base
"searches all known Casks" "searches all known Casks"
end end
end end
end
end

View File

@ -1,13 +1,15 @@
require "English" require "English"
class Hbc::CLI::Style < Hbc::CLI::Base module Hbc
class CLI
class Style < Base
def self.help def self.help
"checks Cask style using RuboCop" "checks Cask style using RuboCop"
end end
def self.run(*args) def self.run(*args)
retval = new(args).run retval = new(args).run
raise Hbc::CaskError, "style check failed" unless retval raise CaskError, "style check failed" unless retval
end end
attr_reader :args attr_reader :args
@ -24,11 +26,11 @@ class Hbc::CLI::Style < Hbc::CLI::Base
RUBOCOP_CASK_VERSION = "~> 0.8.3".freeze RUBOCOP_CASK_VERSION = "~> 0.8.3".freeze
def install_rubocop def install_rubocop
Hbc::Utils.capture_stderr do Utils.capture_stderr do
begin begin
Homebrew.install_gem_setup_path! "rubocop-cask", RUBOCOP_CASK_VERSION, "rubocop" Homebrew.install_gem_setup_path! "rubocop-cask", RUBOCOP_CASK_VERSION, "rubocop"
rescue SystemExit rescue SystemExit
raise Hbc::CaskError, $stderr.string.chomp.sub("#{Tty.red}Error#{Tty.reset}: ", "") raise CaskError, $stderr.string.chomp.sub("#{Tty.red}Error#{Tty.reset}: ", "")
end end
end end
end end
@ -67,3 +69,5 @@ class Hbc::CLI::Style < Hbc::CLI::Base
args.any? { |arg| arg =~ %r{--(fix|(auto-?)?correct)} } args.any? { |arg| arg =~ %r{--(fix|(auto-?)?correct)} }
end end
end end
end
end

View File

@ -1,14 +1,16 @@
class Hbc::CLI::Uninstall < Hbc::CLI::Base module Hbc
class CLI
class Uninstall < Base
def self.run(*args) def self.run(*args)
cask_tokens = cask_tokens_from(args) cask_tokens = cask_tokens_from(args)
raise Hbc::CaskUnspecifiedError if cask_tokens.empty? raise CaskUnspecifiedError if cask_tokens.empty?
force = args.include? "--force" force = args.include? "--force"
cask_tokens.each do |cask_token| cask_tokens.each do |cask_token|
odebug "Uninstalling Cask #{cask_token}" odebug "Uninstalling Cask #{cask_token}"
cask = Hbc.load(cask_token) cask = Hbc.load(cask_token)
raise Hbc::CaskNotInstalledError, cask unless cask.installed? || force raise CaskNotInstalledError, cask unless cask.installed? || force
latest_installed_version = cask.timestamped_versions.last latest_installed_version = cask.timestamped_versions.last
@ -21,7 +23,7 @@ class Hbc::CLI::Uninstall < Hbc::CLI::Base
cask = Hbc.load(latest_installed_cask_file) if latest_installed_cask_file.exist? cask = Hbc.load(latest_installed_cask_file) if latest_installed_cask_file.exist?
end end
Hbc::Installer.new(cask, force: force).uninstall Installer.new(cask, force: force).uninstall
next if (versions = cask.versions).empty? next if (versions = cask.versions).empty?
@ -38,3 +40,5 @@ class Hbc::CLI::Uninstall < Hbc::CLI::Base
"uninstalls the given Cask" "uninstalls the given Cask"
end end
end end
end
end

View File

@ -1,6 +1,8 @@
class Hbc::CLI::Update < Hbc::CLI::Base module Hbc
class CLI
class Update < Base
def self.run(*_ignored) def self.run(*_ignored)
result = Hbc::SystemCommand.run(Hbc.homebrew_executable, result = SystemCommand.run(Hbc.homebrew_executable,
args: %w[update]) args: %w[update])
# TODO: separating stderr/stdout is undesirable here. # TODO: separating stderr/stdout is undesirable here.
# Hbc::SystemCommand should have an option for plain # Hbc::SystemCommand should have an option for plain
@ -14,3 +16,5 @@ class Hbc::CLI::Update < Hbc::CLI::Base
"a synonym for 'brew update'" "a synonym for 'brew update'"
end end
end end
end
end

View File

@ -1,11 +1,13 @@
class Hbc::CLI::Zap < Hbc::CLI::Base module Hbc
class CLI
class Zap < Base
def self.run(*args) def self.run(*args)
cask_tokens = cask_tokens_from(args) cask_tokens = cask_tokens_from(args)
raise Hbc::CaskUnspecifiedError if cask_tokens.empty? raise CaskUnspecifiedError if cask_tokens.empty?
cask_tokens.each do |cask_token| cask_tokens.each do |cask_token|
odebug "Zapping Cask #{cask_token}" odebug "Zapping Cask #{cask_token}"
cask = Hbc.load(cask_token) cask = Hbc.load(cask_token)
Hbc::Installer.new(cask).zap Installer.new(cask).zap
end end
end end
@ -13,3 +15,5 @@ class Hbc::CLI::Zap < Hbc::CLI::Base
"zaps all files associated with the given Cask" "zaps all files associated with the given Cask"
end end
end end
end
end

View File

@ -1,5 +1,3 @@
class Hbc::Container; end
require "hbc/container/base" require "hbc/container/base"
require "hbc/container/air" require "hbc/container/air"
require "hbc/container/bzip2" require "hbc/container/bzip2"
@ -22,26 +20,27 @@ require "hbc/container/xip"
require "hbc/container/xz" require "hbc/container/xz"
require "hbc/container/zip" require "hbc/container/zip"
class Hbc::Container module Hbc
class Container
def self.autodetect_containers def self.autodetect_containers
[ [
Hbc::Container::Pkg, Pkg,
Hbc::Container::Ttf, Ttf,
Hbc::Container::Otf, Otf,
Hbc::Container::Air, Air,
Hbc::Container::Cab, Cab,
Hbc::Container::Dmg, Dmg,
Hbc::Container::SevenZip, SevenZip,
Hbc::Container::Sit, Sit,
Hbc::Container::Rar, Rar,
Hbc::Container::Zip, Zip,
Hbc::Container::Xip, # needs to be before xar as this is a cpio inside a gzip inside a xar Xip, # needs to be before xar as this is a cpio inside a gzip inside a xar
Hbc::Container::Xar, # need to be before tar as tar can also list xar Xar, # need to be before tar as tar can also list xar
Hbc::Container::Tar, # or compressed tar (bzip2/gzip/lzma/xz) Tar, # or compressed tar (bzip2/gzip/lzma/xz)
Hbc::Container::Bzip2, # pure bzip2 Bzip2, # pure bzip2
Hbc::Container::Gzip, # pure gzip Gzip, # pure gzip
Hbc::Container::Lzma, # pure lzma Lzma, # pure lzma
Hbc::Container::Xz, # pure xz Xz, # pure xz
] ]
# for explicit use only (never autodetected): # for explicit use only (never autodetected):
# Hbc::Container::Naked # Hbc::Container::Naked
@ -50,7 +49,7 @@ class Hbc::Container
def self.for_path(path, command) def self.for_path(path, command)
odebug "Determining which containers to use based on filetype" odebug "Determining which containers to use based on filetype"
criteria = Hbc::Container::Criteria.new(path, command) criteria = Criteria.new(path, command)
autodetect_containers.find do |c| autodetect_containers.find do |c|
odebug "Checking container class #{c}" odebug "Checking container class #{c}"
c.me?(criteria) c.me?(criteria)
@ -60,9 +59,10 @@ class Hbc::Container
def self.from_type(type) def self.from_type(type)
odebug "Determining which containers to use based on 'container :type'" odebug "Determining which containers to use based on 'container :type'"
begin begin
Hbc::Container.const_get(type.to_s.split("_").map(&:capitalize).join) self.const_get(type.to_s.split("_").map(&:capitalize).join)
rescue NameError rescue NameError
false false
end end
end end
end end
end

View File

@ -1,6 +1,8 @@
require "hbc/container/base" require "hbc/container/base"
class Hbc::Container::Air < Hbc::Container::Base module Hbc
class Container
class Air < Base
INSTALLER_PATHNAME = INSTALLER_PATHNAME =
Pathname("/Applications/Utilities/Adobe AIR Application Installer.app" \ Pathname("/Applications/Utilities/Adobe AIR Application Installer.app" \
"/Contents/MacOS/Adobe AIR Application Installer") "/Contents/MacOS/Adobe AIR Application Installer")
@ -11,7 +13,7 @@ class Hbc::Container::Air < Hbc::Container::Base
def self.installer_cmd def self.installer_cmd
return @installer_cmd ||= INSTALLER_PATHNAME if installer_exist? return @installer_cmd ||= INSTALLER_PATHNAME if installer_exist?
raise Hbc::CaskError, <<-EOS.undent raise CaskError, <<-EOS.undent
Adobe AIR runtime not present, try installing it via Adobe AIR runtime not present, try installing it via
brew cask install adobe-air brew cask install adobe-air
@ -28,6 +30,8 @@ class Hbc::Container::Air < Hbc::Container::Base
args: ["-silent", "-location", @cask.staged_path, Pathname.new(@path).realpath]) args: ["-silent", "-location", @cask.staged_path, Pathname.new(@path).realpath])
return unless install.exit_status == 9 return unless install.exit_status == 9
raise Hbc::CaskError, "Adobe AIR application #{@cask} already exists on the system, and cannot be reinstalled." raise CaskError, "Adobe AIR application #{@cask} already exists on the system, and cannot be reinstalled."
end
end
end end
end end

View File

@ -1,4 +1,6 @@
class Hbc::Container::Base module Hbc
class Container
class Base
def initialize(cask, path, command, nested: false) def initialize(cask, path, command, nested: false)
@cask = cask @cask = cask
@path = path @path = path
@ -25,7 +27,7 @@ class Hbc::Container::Base
end end
def extract_nested_container(source) def extract_nested_container(source)
container = Hbc::Container.for_path(source, @command) container = Container.for_path(source, @command)
return false unless container return false unless container
@ -35,3 +37,5 @@ class Hbc::Container::Base
true true
end end
end end
end
end

View File

@ -2,7 +2,9 @@ require "tmpdir"
require "hbc/container/base" require "hbc/container/base"
class Hbc::Container::Bzip2 < Hbc::Container::Base module Hbc
class Container
class Bzip2 < Base
def self.me?(criteria) def self.me?(criteria)
criteria.magic_number(%r{^BZh}n) criteria.magic_number(%r{^BZh}n)
end end
@ -16,3 +18,5 @@ class Hbc::Container::Bzip2 < Hbc::Container::Base
end end
end end
end end
end
end

View File

@ -2,7 +2,9 @@ require "tmpdir"
require "hbc/container/base" require "hbc/container/base"
class Hbc::Container::Cab < Hbc::Container::Base module Hbc
class Container
class Cab < Base
def self.me?(criteria) def self.me?(criteria)
cabextract = Hbc.homebrew_prefix.join("bin", "cabextract") cabextract = Hbc.homebrew_prefix.join("bin", "cabextract")
@ -15,7 +17,7 @@ class Hbc::Container::Cab < Hbc::Container::Base
cabextract = Hbc.homebrew_prefix.join("bin", "cabextract") cabextract = Hbc.homebrew_prefix.join("bin", "cabextract")
unless cabextract.exist? unless cabextract.exist?
raise Hbc::CaskError, "Expected to find cabextract executable. Cask '#{@cask}' must add: depends_on formula: 'cabextract'" raise CaskError, "Expected to find cabextract executable. Cask '#{@cask}' must add: depends_on formula: 'cabextract'"
end end
Dir.mktmpdir do |unpack_dir| Dir.mktmpdir do |unpack_dir|
@ -24,3 +26,5 @@ class Hbc::Container::Cab < Hbc::Container::Base
end end
end end
end end
end
end

View File

@ -1,4 +1,6 @@
class Hbc::Container::Criteria module Hbc
class Container
class Criteria
attr_reader :path, :command attr_reader :path, :command
def initialize(path, command) def initialize(path, command)
@ -16,3 +18,5 @@ class Hbc::Container::Criteria
@magic_number =~ regex @magic_number =~ regex
end end
end end
end
end

View File

@ -3,7 +3,9 @@ require "tempfile"
require "hbc/container/base" require "hbc/container/base"
class Hbc::Container::Dmg < Hbc::Container::Base module Hbc
class Container
class Dmg < Base
def self.me?(criteria) def self.me?(criteria)
!criteria.command.run("/usr/bin/hdiutil", !criteria.command.run("/usr/bin/hdiutil",
# realpath is a failsafe against unusual filenames # realpath is a failsafe against unusual filenames
@ -46,8 +48,8 @@ class Hbc::Container::Dmg < Hbc::Container::Base
args: ["eject", mountpath], args: ["eject", mountpath],
print_stderr: false) print_stderr: false)
raise Hbc::CaskError, "Failed to eject #{mountpath}" if mountpath.exist? raise CaskError, "Failed to eject #{mountpath}" if mountpath.exist?
rescue Hbc::CaskError => e rescue CaskError => e
raise e if (tries -= 1).zero? raise e if (tries -= 1).zero?
sleep 1 sleep 1
retry retry
@ -120,6 +122,8 @@ class Hbc::Container::Dmg < Hbc::Container::Base
end end
def assert_mounts_found def assert_mounts_found
raise Hbc::CaskError, "No mounts found in '#{@path}'; perhaps it is a bad DMG?" if @mounts.empty? raise CaskError, "No mounts found in '#{@path}'; perhaps it is a bad DMG?" if @mounts.empty?
end
end
end end
end end

View File

@ -2,7 +2,9 @@ require "tmpdir"
require "hbc/container/base" require "hbc/container/base"
class Hbc::Container::GenericUnar < Hbc::Container::Base module Hbc
class Container
class GenericUnar < Base
def self.me?(criteria) def self.me?(criteria)
lsar = Hbc.homebrew_prefix.join("bin", "lsar") lsar = Hbc.homebrew_prefix.join("bin", "lsar")
lsar.exist? && lsar.exist? &&
@ -15,7 +17,7 @@ class Hbc::Container::GenericUnar < Hbc::Container::Base
unar = Hbc.homebrew_prefix.join("bin", "unar") unar = Hbc.homebrew_prefix.join("bin", "unar")
unless unar.exist? unless unar.exist?
raise Hbc::CaskError, "Expected to find unar executable. Cask #{@cask} must add: depends_on formula: 'unar'" raise CaskError, "Expected to find unar executable. Cask #{@cask} must add: depends_on formula: 'unar'"
end end
Dir.mktmpdir do |unpack_dir| Dir.mktmpdir do |unpack_dir|
@ -24,3 +26,5 @@ class Hbc::Container::GenericUnar < Hbc::Container::Base
end end
end end
end end
end
end

View File

@ -2,7 +2,9 @@ require "tmpdir"
require "hbc/container/base" require "hbc/container/base"
class Hbc::Container::Gzip < Hbc::Container::Base module Hbc
class Container
class Gzip < Base
def self.me?(criteria) def self.me?(criteria)
criteria.magic_number(%r{^\037\213}n) criteria.magic_number(%r{^\037\213}n)
end end
@ -16,3 +18,5 @@ class Hbc::Container::Gzip < Hbc::Container::Base
end end
end end
end end
end
end

View File

@ -2,7 +2,9 @@ require "tmpdir"
require "hbc/container/base" require "hbc/container/base"
class Hbc::Container::Lzma < Hbc::Container::Base module Hbc
class Container
class Lzma < Base
def self.me?(criteria) def self.me?(criteria)
criteria.magic_number(%r{^\]\000\000\200\000}n) criteria.magic_number(%r{^\]\000\000\200\000}n)
end end
@ -11,7 +13,7 @@ class Hbc::Container::Lzma < Hbc::Container::Base
unlzma = Hbc.homebrew_prefix.join("bin", "unlzma") unlzma = Hbc.homebrew_prefix.join("bin", "unlzma")
unless unlzma.exist? unless unlzma.exist?
raise Hbc::CaskError, "Expected to find unlzma executable. Cask '#{@cask}' must add: depends_on formula: 'lzma'" raise CaskError, "Expected to find unlzma executable. Cask '#{@cask}' must add: depends_on formula: 'lzma'"
end end
Dir.mktmpdir do |unpack_dir| Dir.mktmpdir do |unpack_dir|
@ -21,3 +23,5 @@ class Hbc::Container::Lzma < Hbc::Container::Base
end end
end end
end end
end
end

View File

@ -1,6 +1,8 @@
require "hbc/container/base" require "hbc/container/base"
class Hbc::Container::Naked < Hbc::Container::Base module Hbc
class Container
class Naked < Base
# Either inherit from this class and override with self.me?(criteria), # Either inherit from this class and override with self.me?(criteria),
# or use this class directly as "container type: :naked", # or use this class directly as "container type: :naked",
# in which case self.me? is not called. # in which case self.me? is not called.
@ -17,3 +19,5 @@ class Hbc::Container::Naked < Hbc::Container::Base
URI.decode(File.basename(@cask.url.path)) URI.decode(File.basename(@cask.url.path))
end end
end end
end
end

View File

@ -1,7 +1,11 @@
require "hbc/container/naked" require "hbc/container/naked"
class Hbc::Container::Otf < Hbc::Container::Naked module Hbc
class Container
class Otf < Naked
def self.me?(criteria) def self.me?(criteria)
criteria.magic_number(%r{^OTTO}n) criteria.magic_number(%r{^OTTO}n)
end end
end end
end
end

View File

@ -1,9 +1,13 @@
require "hbc/container/naked" require "hbc/container/naked"
class Hbc::Container::Pkg < Hbc::Container::Naked module Hbc
class Container
class Pkg < Naked
def self.me?(criteria) def self.me?(criteria)
criteria.extension(%r{m?pkg$}) && criteria.extension(%r{m?pkg$}) &&
(criteria.path.directory? || (criteria.path.directory? ||
criteria.magic_number(%r{^xar!}n)) criteria.magic_number(%r{^xar!}n))
end end
end end
end
end

View File

@ -1,8 +1,12 @@
require "hbc/container/generic_unar" require "hbc/container/generic_unar"
class Hbc::Container::Rar < Hbc::Container::GenericUnar module Hbc
class Container
class Rar < GenericUnar
def self.me?(criteria) def self.me?(criteria)
criteria.magic_number(%r{^Rar!}n) && criteria.magic_number(%r{^Rar!}n) &&
super super
end end
end end
end
end

View File

@ -1,9 +1,13 @@
require "hbc/container/generic_unar" require "hbc/container/generic_unar"
class Hbc::Container::SevenZip < Hbc::Container::GenericUnar module Hbc
class Container
class SevenZip < GenericUnar
def self.me?(criteria) def self.me?(criteria)
# TODO: cover self-extracting archives # TODO: cover self-extracting archives
criteria.magic_number(%r{^7z}n) && criteria.magic_number(%r{^7z}n) &&
super super
end end
end end
end
end

View File

@ -1,8 +1,12 @@
require "hbc/container/generic_unar" require "hbc/container/generic_unar"
class Hbc::Container::Sit < Hbc::Container::GenericUnar module Hbc
class Container
class Sit < GenericUnar
def self.me?(criteria) def self.me?(criteria)
criteria.magic_number(%r{^StuffIt}n) && criteria.magic_number(%r{^StuffIt}n) &&
super super
end end
end end
end
end

View File

@ -2,7 +2,9 @@ require "tmpdir"
require "hbc/container/base" require "hbc/container/base"
class Hbc::Container::Tar < Hbc::Container::Base module Hbc
class Container
class Tar < Base
def self.me?(criteria) def self.me?(criteria)
criteria.magic_number(%r{^.{257}ustar}n) || criteria.magic_number(%r{^.{257}ustar}n) ||
# or compressed tar (bzip2/gzip/lzma/xz) # or compressed tar (bzip2/gzip/lzma/xz)
@ -16,3 +18,5 @@ class Hbc::Container::Tar < Hbc::Container::Base
end end
end end
end end
end
end

View File

@ -1,6 +1,8 @@
require "hbc/container/naked" require "hbc/container/naked"
class Hbc::Container::Ttf < Hbc::Container::Naked module Hbc
class Container
class Ttf < Naked
def self.me?(criteria) def self.me?(criteria)
# TrueType Font # TrueType Font
criteria.magic_number(%r{^\000\001\000\000\000}n) || criteria.magic_number(%r{^\000\001\000\000\000}n) ||
@ -8,3 +10,5 @@ class Hbc::Container::Ttf < Hbc::Container::Naked
criteria.magic_number(%r{^ttcf}n) criteria.magic_number(%r{^ttcf}n)
end end
end end
end
end

View File

@ -2,7 +2,9 @@ require "tmpdir"
require "hbc/container/base" require "hbc/container/base"
class Hbc::Container::Xar < Hbc::Container::Base module Hbc
class Container
class Xar < Base
def self.me?(criteria) def self.me?(criteria)
criteria.magic_number(%r{^xar!}n) criteria.magic_number(%r{^xar!}n)
end end
@ -14,3 +16,5 @@ class Hbc::Container::Xar < Hbc::Container::Base
end end
end end
end end
end
end

View File

@ -1,6 +1,8 @@
require "tmpdir" require "tmpdir"
class Hbc::Container::Xip < Hbc::Container::Base module Hbc
class Container
class Xip < Base
def self.me?(criteria) def self.me?(criteria)
criteria.magic_number(%r{^xar!}n) && criteria.magic_number(%r{^xar!}n) &&
IO.popen(["/usr/bin/xar", "-t", "-f", criteria.path.to_s], err: "/dev/null") { |io| io.read =~ %r{\AContent\nMetadata\n\Z} } IO.popen(["/usr/bin/xar", "-t", "-f", criteria.path.to_s], err: "/dev/null") { |io| io.read =~ %r{\AContent\nMetadata\n\Z} }
@ -23,3 +25,5 @@ class Hbc::Container::Xip < Hbc::Container::Base
end end
end end
end end
end
end

View File

@ -2,7 +2,9 @@ require "tmpdir"
require "hbc/container/base" require "hbc/container/base"
class Hbc::Container::Xz < Hbc::Container::Base module Hbc
class Container
class Xz < Base
def self.me?(criteria) def self.me?(criteria)
criteria.magic_number(%r{^\xFD7zXZ\x00}n) criteria.magic_number(%r{^\xFD7zXZ\x00}n)
end end
@ -11,7 +13,7 @@ class Hbc::Container::Xz < Hbc::Container::Base
unxz = Hbc.homebrew_prefix.join("bin", "unxz") unxz = Hbc.homebrew_prefix.join("bin", "unxz")
unless unxz.exist? unless unxz.exist?
raise Hbc::CaskError, "Expected to find unxz executable. Cask '#{@cask}' must add: depends_on formula: 'xz'" raise CaskError, "Expected to find unxz executable. Cask '#{@cask}' must add: depends_on formula: 'xz'"
end end
Dir.mktmpdir do |unpack_dir| Dir.mktmpdir do |unpack_dir|
@ -21,3 +23,5 @@ class Hbc::Container::Xz < Hbc::Container::Base
end end
end end
end end
end
end

View File

@ -1,6 +1,8 @@
require "hbc/container/base" require "hbc/container/base"
class Hbc::Container::Zip < Hbc::Container::Base module Hbc
class Container
class Zip < Base
def self.me?(criteria) def self.me?(criteria)
criteria.magic_number(%r{^PK(\003\004|\005\006)}n) criteria.magic_number(%r{^PK(\003\004|\005\006)}n)
end end
@ -13,3 +15,5 @@ class Hbc::Container::Zip < Hbc::Container::Base
end end
end end
end end
end
end

View File

@ -1,7 +1,8 @@
require "fileutils" require "fileutils"
require "hbc/verify" require "hbc/verify"
class Hbc::Download module Hbc
class Download
attr_reader :cask attr_reader :cask
def initialize(cask, force: false) def initialize(cask, force: false)
@ -23,11 +24,11 @@ class Hbc::Download
def downloader def downloader
@downloader ||= case cask.url.using @downloader ||= case cask.url.using
when :svn when :svn
Hbc::SubversionDownloadStrategy.new(cask) SubversionDownloadStrategy.new(cask)
when :post when :post
Hbc::CurlPostDownloadStrategy.new(cask) CurlPostDownloadStrategy.new(cask)
else else
Hbc::CurlDownloadStrategy.new(cask) CurlDownloadStrategy.new(cask)
end end
end end
@ -38,6 +39,7 @@ class Hbc::Download
def fetch def fetch
self.downloaded_path = downloader.fetch self.downloaded_path = downloader.fetch
rescue StandardError => e rescue StandardError => e
raise Hbc::CaskError, "Download failed on Cask '#{cask}' with message: #{e}" raise CaskError, "Download failed on Cask '#{cask}' with message: #{e}"
end
end end
end end

View File

@ -6,10 +6,11 @@ require "cgi"
# * Our overridden fetch methods are expected to return # * Our overridden fetch methods are expected to return
# a value: the successfully downloaded file. # a value: the successfully downloaded file.
class Hbc::AbstractDownloadStrategy module Hbc
class AbstractDownloadStrategy
attr_reader :cask, :name, :url, :uri_object, :version attr_reader :cask, :name, :url, :uri_object, :version
def initialize(cask, command = Hbc::SystemCommand) def initialize(cask, command = SystemCommand)
@cask = cask @cask = cask
@command = command @command = command
# TODO: this excess of attributes is a function of integrating # TODO: this excess of attributes is a function of integrating
@ -29,10 +30,10 @@ class Hbc::AbstractDownloadStrategy
def clear_cache; end def clear_cache; end
end end
class Hbc::HbVCSDownloadStrategy < Hbc::AbstractDownloadStrategy class HbVCSDownloadStrategy < AbstractDownloadStrategy
REF_TYPES = [:branch, :revision, :revisions, :tag].freeze REF_TYPES = [:branch, :revision, :revisions, :tag].freeze
def initialize(cask, command = Hbc::SystemCommand) def initialize(cask, command = SystemCommand)
super super
@ref_type, @ref = extract_ref @ref_type, @ref = extract_ref
@clone = Hbc.cache.join(cache_filename) @clone = Hbc.cache.join(cache_filename)
@ -62,7 +63,7 @@ class Hbc::HbVCSDownloadStrategy < Hbc::AbstractDownloadStrategy
end end
end end
class Hbc::CurlDownloadStrategy < Hbc::AbstractDownloadStrategy class CurlDownloadStrategy < AbstractDownloadStrategy
# TODO: should be part of url object # TODO: should be part of url object
def mirrors def mirrors
@mirrors ||= [] @mirrors ||= []
@ -83,7 +84,7 @@ class Hbc::CurlDownloadStrategy < Hbc::AbstractDownloadStrategy
def clear_cache def clear_cache
[cached_location, temporary_path].each do |f| [cached_location, temporary_path].each do |f|
next unless f.exist? next unless f.exist?
raise CurlDownloadStrategyError, "#{f} is in use by another process" if Hbc::Utils.file_locked?(f) raise CurlDownloadStrategyError, "#{f} is in use by another process" if Utils.file_locked?(f)
f.unlink f.unlink
end end
end end
@ -184,7 +185,7 @@ class Hbc::CurlDownloadStrategy < Hbc::AbstractDownloadStrategy
end end
end end
class Hbc::CurlPostDownloadStrategy < Hbc::CurlDownloadStrategy class CurlPostDownloadStrategy < CurlDownloadStrategy
def cask_curl_args def cask_curl_args
super super
default_curl_args.concat(post_args) default_curl_args.concat(post_args)
@ -204,7 +205,7 @@ class Hbc::CurlPostDownloadStrategy < Hbc::CurlDownloadStrategy
end end
end end
class Hbc::SubversionDownloadStrategy < Hbc::HbVCSDownloadStrategy class SubversionDownloadStrategy < HbVCSDownloadStrategy
def cache_tag def cache_tag
# TODO: pass versions as symbols, support :head here # TODO: pass versions as symbols, support :head here
version == "head" ? "svn-HEAD" : "svn" version == "head" ? "svn-HEAD" : "svn"
@ -330,3 +331,4 @@ class Hbc::SubversionDownloadStrategy < Hbc::HbVCSDownloadStrategy
clear_cache clear_cache
end end
end end
end

View File

@ -1,7 +1,5 @@
require "set" require "set"
class Hbc::DSL; end
require "hbc/dsl/appcast" require "hbc/dsl/appcast"
require "hbc/dsl/base" require "hbc/dsl/base"
require "hbc/dsl/caveats" require "hbc/dsl/caveats"
@ -18,7 +16,8 @@ require "hbc/dsl/uninstall_postflight"
require "hbc/dsl/uninstall_preflight" require "hbc/dsl/uninstall_preflight"
require "hbc/dsl/version" require "hbc/dsl/version"
class Hbc::DSL module Hbc
class DSL
ORDINARY_ARTIFACT_TYPES = [ ORDINARY_ARTIFACT_TYPES = [
:app, :app,
:artifact, :artifact,
@ -91,7 +90,7 @@ class Hbc::DSL
def assert_only_one_stanza_allowed(stanza, arg_given) def assert_only_one_stanza_allowed(stanza, arg_given)
return unless instance_variable_defined?("@#{stanza}") && arg_given return unless instance_variable_defined?("@#{stanza}") && arg_given
raise Hbc::CaskInvalidError.new(token, "'#{stanza}' stanza may only appear once") raise CaskInvalidError.new(token, "'#{stanza}' stanza may only appear once")
end end
def homepage(homepage = nil) def homepage(homepage = nil)
@ -104,9 +103,9 @@ class Hbc::DSL
return @url unless url_given return @url unless url_given
assert_only_one_stanza_allowed :url, url_given assert_only_one_stanza_allowed :url, url_given
@url ||= begin @url ||= begin
Hbc::URL.from(*args, &block) URL.from(*args, &block)
rescue StandardError => e rescue StandardError => e
raise Hbc::CaskInvalidError.new(token, "'url' stanza failed with: #{e}") raise CaskInvalidError.new(token, "'url' stanza failed with: #{e}")
end end
end end
@ -114,9 +113,9 @@ class Hbc::DSL
return @appcast if args.empty? return @appcast if args.empty?
assert_only_one_stanza_allowed :appcast, !args.empty? assert_only_one_stanza_allowed :appcast, !args.empty?
@appcast ||= begin @appcast ||= begin
Hbc::DSL::Appcast.new(*args) unless args.empty? DSL::Appcast.new(*args) unless args.empty?
rescue StandardError => e rescue StandardError => e
raise Hbc::CaskInvalidError.new(token, e) raise CaskInvalidError.new(token, e)
end end
end end
@ -124,9 +123,9 @@ class Hbc::DSL
return @gpg if args.empty? return @gpg if args.empty?
assert_only_one_stanza_allowed :gpg, !args.empty? assert_only_one_stanza_allowed :gpg, !args.empty?
@gpg ||= begin @gpg ||= begin
Hbc::DSL::Gpg.new(*args) unless args.empty? DSL::Gpg.new(*args) unless args.empty?
rescue StandardError => e rescue StandardError => e
raise Hbc::CaskInvalidError.new(token, e) raise CaskInvalidError.new(token, e)
end end
end end
@ -135,9 +134,9 @@ class Hbc::DSL
# TODO: remove this constraint, and instead merge multiple container stanzas # TODO: remove this constraint, and instead merge multiple container stanzas
assert_only_one_stanza_allowed :container, !args.empty? assert_only_one_stanza_allowed :container, !args.empty?
@container ||= begin @container ||= begin
Hbc::DSL::Container.new(*args) unless args.empty? DSL::Container.new(*args) unless args.empty?
rescue StandardError => e rescue StandardError => e
raise Hbc::CaskInvalidError.new(token, e) raise CaskInvalidError.new(token, e)
end end
# TODO: remove this backward-compatibility section after removing nested_container # TODO: remove this backward-compatibility section after removing nested_container
if @container && @container.nested if @container && @container.nested
@ -153,8 +152,8 @@ class Hbc::DSL
def version(arg = nil) def version(arg = nil)
return @version if arg.nil? return @version if arg.nil?
assert_only_one_stanza_allowed :version, !arg.nil? assert_only_one_stanza_allowed :version, !arg.nil?
raise Hbc::CaskInvalidError.new(token, "invalid 'version' value: '#{arg.inspect}'") if !arg.is_a?(String) && !SYMBOLIC_VERSIONS.include?(arg) raise CaskInvalidError.new(token, "invalid 'version' value: '#{arg.inspect}'") if !arg.is_a?(String) && !SYMBOLIC_VERSIONS.include?(arg)
@version ||= Hbc::DSL::Version.new(arg) @version ||= DSL::Version.new(arg)
end end
SYMBOLIC_SHA256S = Set.new [ SYMBOLIC_SHA256S = Set.new [
@ -164,7 +163,7 @@ class Hbc::DSL
def sha256(arg = nil) def sha256(arg = nil)
return @sha256 if arg.nil? return @sha256 if arg.nil?
assert_only_one_stanza_allowed :sha256, !arg.nil? assert_only_one_stanza_allowed :sha256, !arg.nil?
raise Hbc::CaskInvalidError.new(token, "invalid 'sha256' value: '#{arg.inspect}'") if !arg.is_a?(String) && !SYMBOLIC_SHA256S.include?(arg) raise CaskInvalidError.new(token, "invalid 'sha256' value: '#{arg.inspect}'") if !arg.is_a?(String) && !SYMBOLIC_SHA256S.include?(arg)
@sha256 ||= arg @sha256 ||= arg
end end
@ -172,20 +171,20 @@ class Hbc::DSL
return @license if arg.nil? return @license if arg.nil?
assert_only_one_stanza_allowed :license, !arg.nil? assert_only_one_stanza_allowed :license, !arg.nil?
@license ||= begin @license ||= begin
Hbc::DSL::License.new(arg) unless arg.nil? DSL::License.new(arg) unless arg.nil?
rescue StandardError => e rescue StandardError => e
raise Hbc::CaskInvalidError.new(token, e) raise CaskInvalidError.new(token, e)
end end
end end
# depends_on uses a load method so that multiple stanzas can be merged # depends_on uses a load method so that multiple stanzas can be merged
def depends_on(*args) def depends_on(*args)
return @depends_on if args.empty? return @depends_on if args.empty?
@depends_on ||= Hbc::DSL::DependsOn.new @depends_on ||= DSL::DependsOn.new
begin begin
@depends_on.load(*args) unless args.empty? @depends_on.load(*args) unless args.empty?
rescue RuntimeError => e rescue RuntimeError => e
raise Hbc::CaskInvalidError.new(token, e) raise CaskInvalidError.new(token, e)
end end
@depends_on @depends_on
end end
@ -195,9 +194,9 @@ class Hbc::DSL
# TODO: remove this constraint, and instead merge multiple conflicts_with stanzas # TODO: remove this constraint, and instead merge multiple conflicts_with stanzas
assert_only_one_stanza_allowed :conflicts_with, !args.empty? assert_only_one_stanza_allowed :conflicts_with, !args.empty?
@conflicts_with ||= begin @conflicts_with ||= begin
Hbc::DSL::ConflictsWith.new(*args) unless args.empty? DSL::ConflictsWith.new(*args) unless args.empty?
rescue StandardError => e rescue StandardError => e
raise Hbc::CaskInvalidError.new(token, e) raise CaskInvalidError.new(token, e)
end end
end end
@ -238,22 +237,22 @@ class Hbc::DSL
ORDINARY_ARTIFACT_TYPES.each do |type| ORDINARY_ARTIFACT_TYPES.each do |type|
define_method(type) do |*args| define_method(type) do |*args|
if type == :stage_only && args != [true] if type == :stage_only && args != [true]
raise Hbc::CaskInvalidError.new(token, "'stage_only' takes a single argument: true") raise CaskInvalidError.new(token, "'stage_only' takes a single argument: true")
end end
artifacts[type] << args artifacts[type] << args
if artifacts.key?(:stage_only) && artifacts.keys.count > 1 && if artifacts.key?(:stage_only) && artifacts.keys.count > 1 &&
!(artifacts.keys & ACTIVATABLE_ARTIFACT_TYPES).empty? !(artifacts.keys & ACTIVATABLE_ARTIFACT_TYPES).empty?
raise Hbc::CaskInvalidError.new(token, "'stage_only' must be the only activatable artifact") raise CaskInvalidError.new(token, "'stage_only' must be the only activatable artifact")
end end
end end
end end
def installer(*args) def installer(*args)
return artifacts[:installer] if args.empty? return artifacts[:installer] if args.empty?
artifacts[:installer] << Hbc::DSL::Installer.new(*args) artifacts[:installer] << DSL::Installer.new(*args)
raise "'stage_only' must be the only activatable artifact" if artifacts.key?(:stage_only) raise "'stage_only' must be the only activatable artifact" if artifacts.key?(:stage_only)
rescue StandardError => e rescue StandardError => e
raise Hbc::CaskInvalidError.new(token, e) raise CaskInvalidError.new(token, e)
end end
SPECIAL_ARTIFACT_TYPES.each do |type| SPECIAL_ARTIFACT_TYPES.each do |type|
@ -270,7 +269,7 @@ class Hbc::DSL
def method_missing(method, *) def method_missing(method, *)
if method if method
Hbc::Utils.method_missing_message(method, token) Utils.method_missing_message(method, token)
nil nil
else else
super super
@ -289,3 +288,4 @@ class Hbc::DSL
Hbc.appdir.sub(%r{\/$}, "") Hbc.appdir.sub(%r{\/$}, "")
end end
end end
end

View File

@ -1,9 +1,11 @@
class Hbc::DSL::Appcast module Hbc
class DSL
class Appcast
attr_reader :parameters, :checkpoint attr_reader :parameters, :checkpoint
def initialize(uri, parameters = {}) def initialize(uri, parameters = {})
@parameters = parameters @parameters = parameters
@uri = Hbc::UnderscoreSupportingURI.parse(uri) @uri = UnderscoreSupportingURI.parse(uri)
@checkpoint = @parameters[:checkpoint] @checkpoint = @parameters[:checkpoint]
end end
@ -15,3 +17,5 @@ class Hbc::DSL::Appcast
@uri.to_s @uri.to_s
end end
end end
end
end

View File

@ -1,7 +1,9 @@
class Hbc::DSL::Base module Hbc
class DSL
class Base
extend Forwardable extend Forwardable
def initialize(cask, command = Hbc::SystemCommand) def initialize(cask, command = SystemCommand)
@cask = cask @cask = cask
@command = command @command = command
end end
@ -16,7 +18,7 @@ class Hbc::DSL::Base
if method if method
underscored_class = self.class.name.gsub(%r{([[:lower:]])([[:upper:]][[:lower:]])}, '\1_\2').downcase underscored_class = self.class.name.gsub(%r{([[:lower:]])([[:upper:]][[:lower:]])}, '\1_\2').downcase
section = underscored_class.downcase.split("::").last section = underscored_class.downcase.split("::").last
Hbc::Utils.method_missing_message(method, @cask.to_s, section) Utils.method_missing_message(method, @cask.to_s, section)
nil nil
else else
super super
@ -27,3 +29,5 @@ class Hbc::DSL::Base
true true
end end
end end
end
end

View File

@ -5,7 +5,9 @@
# ( The return value of the last method in the block is also sent # ( The return value of the last method in the block is also sent
# to the output by the caller, but that feature is only for the # to the output by the caller, but that feature is only for the
# convenience of Cask authors. ) # convenience of Cask authors. )
class Hbc::DSL::Caveats < Hbc::DSL::Base module Hbc
class DSL
class Caveats < Base
def path_environment_variable(path) def path_environment_variable(path)
puts <<-EOS.undent puts <<-EOS.undent
To use #{@cask}, you may need to add the #{path} directory To use #{@cask}, you may need to add the #{path} directory
@ -110,3 +112,5 @@ class Hbc::DSL::Caveats < Hbc::DSL::Base
EOS EOS
end end
end end
end
end

View File

@ -1,4 +1,6 @@
class Hbc::DSL::ConflictsWith module Hbc
class DSL
class ConflictsWith
VALID_KEYS = Set.new [ VALID_KEYS = Set.new [
:formula, :formula,
:cask, :cask,
@ -28,3 +30,5 @@ class Hbc::DSL::ConflictsWith
@pairs.inspect @pairs.inspect
end end
end end
end
end

View File

@ -1,4 +1,6 @@
class Hbc::DSL::Container module Hbc
class DSL
class Container
VALID_KEYS = Set.new [ VALID_KEYS = Set.new [
:type, :type,
:nested, :nested,
@ -24,3 +26,5 @@ class Hbc::DSL::Container
@pairs.inspect @pairs.inspect
end end
end end
end
end

View File

@ -1,6 +1,8 @@
require "rubygems" require "rubygems"
class Hbc::DSL::DependsOn module Hbc
class DSL
class DependsOn
VALID_KEYS = Set.new [ VALID_KEYS = Set.new [
:formula, :formula,
:cask, :cask,
@ -122,3 +124,5 @@ class Hbc::DSL::DependsOn
@pairs.inspect @pairs.inspect
end end
end end
end
end

View File

@ -1,4 +1,6 @@
class Hbc::DSL::Gpg module Hbc
class DSL
class Gpg
KEY_PARAMETERS = Set.new [ KEY_PARAMETERS = Set.new [
:key_id, :key_id,
:key_url, :key_url,
@ -12,11 +14,11 @@ class Hbc::DSL::Gpg
def initialize(signature, parameters = {}) def initialize(signature, parameters = {})
@parameters = parameters @parameters = parameters
@signature = Hbc::UnderscoreSupportingURI.parse(signature) @signature = UnderscoreSupportingURI.parse(signature)
parameters.each do |hkey, hvalue| parameters.each do |hkey, hvalue|
raise "invalid 'gpg' parameter: '#{hkey.inspect}'" unless VALID_PARAMETERS.include?(hkey) raise "invalid 'gpg' parameter: '#{hkey.inspect}'" unless VALID_PARAMETERS.include?(hkey)
writer_method = "#{hkey}=".to_sym writer_method = "#{hkey}=".to_sym
hvalue = Hbc::UnderscoreSupportingURI.parse(hvalue) if hkey == :key_url hvalue = UnderscoreSupportingURI.parse(hvalue) if hkey == :key_url
valid_id?(hvalue) if hkey == :key_id valid_id?(hvalue) if hkey == :key_id
send(writer_method, hvalue) send(writer_method, hvalue)
end end
@ -41,3 +43,5 @@ class Hbc::DSL::Gpg
@signature.to_s @signature.to_s
end end
end end
end
end

View File

@ -1,4 +1,6 @@
class Hbc::DSL::Installer module Hbc
class DSL
class Installer
VALID_KEYS = Set.new [ VALID_KEYS = Set.new [
:manual, :manual,
:script, :script,
@ -7,11 +9,11 @@ class Hbc::DSL::Installer
attr_accessor(*VALID_KEYS) attr_accessor(*VALID_KEYS)
def initialize(*parameters) def initialize(*parameters)
raise Hbc::CaskInvalidError.new(token, "'installer' stanza requires an argument") if parameters.empty? raise CaskInvalidError.new(token, "'installer' stanza requires an argument") if parameters.empty?
parameters = {}.merge(*parameters) parameters = {}.merge(*parameters)
if parameters.key?(:script) && !parameters[:script].respond_to?(:key?) if parameters.key?(:script) && !parameters[:script].respond_to?(:key?)
if parameters.key?(:executable) if parameters.key?(:executable)
raise Hbc::CaskInvalidError.new(token, "'installer' stanza gave arguments for both :script and :executable") raise CaskInvalidError.new(token, "'installer' stanza gave arguments for both :script and :executable")
end end
parameters[:executable] = parameters[:script] parameters[:executable] = parameters[:script]
parameters.delete(:script) parameters.delete(:script)
@ -26,3 +28,5 @@ class Hbc::DSL::Installer
send(writer_method, parameters[key]) send(writer_method, parameters[key])
end end
end end
end
end

View File

@ -1,4 +1,6 @@
class Hbc::DSL::License module Hbc
class DSL
class License
# a generic category can always be given as a license, so # a generic category can always be given as a license, so
# category names should be given as both key and value # category names should be given as both key and value
VALID_LICENSES = { VALID_LICENSES = {
@ -64,3 +66,5 @@ class Hbc::DSL::License
@value.inspect @value.inspect
end end
end end
end
end

View File

@ -1,9 +1,13 @@
require "hbc/staged" require "hbc/staged"
class Hbc::DSL::Postflight < Hbc::DSL::Base module Hbc
include Hbc::Staged class DSL
class Postflight < Base
include Staged
def suppress_move_to_applications(options = {}) def suppress_move_to_applications(options = {})
# TODO: Remove from all casks because it is no longer needed # TODO: Remove from all casks because it is no longer needed
end end
end end
end
end

View File

@ -1,3 +1,7 @@
class Hbc::DSL::Preflight < Hbc::DSL::Base module Hbc
include Hbc::Staged class DSL
class Preflight < Base
include Staged
end
end
end end

Some files were not shown because too many files have changed in this diff Show More