Merge pull request #2654 from reitermarkus/refactor-cli

Refactor `CLI`.
This commit is contained in:
Markus Reiter 2017-05-23 13:27:44 +02:00 committed by GitHub
commit d1f599f1ed
58 changed files with 724 additions and 824 deletions

View File

@ -34,6 +34,9 @@ Metrics/ModuleLength:
- 'cask/lib/hbc/macos.rb'
- 'cask/lib/hbc/utils.rb'
Metrics/ParameterLists:
CountKeywordArgs: false
# so many of these in formulae but none in here
Style/GuardClause:
Enabled: true

View File

@ -54,12 +54,12 @@ module Hbc
Zap,
].freeze
def self.for_cask(cask, command: SystemCommand, force: false)
def self.for_cask(cask, options = {})
odebug "Determining which artifacts are present in Cask #{cask}"
TYPES
.select { |klass| klass.me?(cask) }
.map { |klass| klass.new(cask, command: command, force: force) }
.map { |klass| klass.new(cask, options) }
end
end
end

View File

@ -65,10 +65,19 @@ module Hbc
{}
end
def initialize(cask, command: SystemCommand, force: false)
def verbose?
@verbose
end
def force?
@force
end
def initialize(cask, command: SystemCommand, force: false, verbose: false)
@cask = cask
@command = command
@force = force
@verbose = verbose
end
end
end

View File

@ -3,10 +3,6 @@ require "hbc/artifact/symlinked"
module Hbc
module Artifact
class Binary < Symlinked
def install_phase
super if CLI.binaries?
end
def link
super
return if source.executable?

View File

@ -20,7 +20,7 @@ module Hbc
def move
if Utils.path_occupied?(target)
message = "It seems there is already #{self.class.artifact_english_article} #{self.class.artifact_english_name} at '#{target}'"
raise CaskError, "#{message}." unless force
raise CaskError, "#{message}." unless force?
opoo "#{message}; overwriting."
delete
end

View File

@ -48,7 +48,7 @@ module Hbc
"-pkg", source,
"-target", "/"
]
args << "-verboseR" if CLI.verbose?
args << "-verboseR" if verbose?
args << "-allowUntrusted" if pkg_install_opts :allow_untrusted
with_choices_file do |choices_path|
args << "-applyChoiceChangesXML" << choices_path if choices_path

View File

@ -173,7 +173,7 @@ module Hbc
unless executable_path.exist?
message = "uninstall script #{executable} does not exist"
raise CaskError, "#{message}." unless force
raise CaskError, "#{message}." unless force?
opoo "#{message}, skipping."
return
end

View File

@ -74,8 +74,6 @@ module Hbc
end
def dumpcask
return unless CLI.debug?
odebug "Cask instance dumps in YAML:"
odebug "Cask instance toplevel:", to_yaml
[

View File

@ -2,8 +2,9 @@ require "optparse"
require "shellwords"
require "extend/optparse"
require "hbc/cli/options"
require "hbc/cli/base"
require "hbc/cli/abstract_command"
require "hbc/cli/audit"
require "hbc/cli/cat"
require "hbc/cli/cleanup"
@ -23,7 +24,7 @@ require "hbc/cli/uninstall"
require "hbc/cli/--version"
require "hbc/cli/zap"
require "hbc/cli/internal_use_base"
require "hbc/cli/abstract_internal_command"
require "hbc/cli/internal_audit_modified_casks"
require "hbc/cli/internal_appcast_checkpoint"
require "hbc/cli/internal_checkurl"
@ -44,54 +45,41 @@ module Hbc
"remove" => "uninstall",
"abv" => "info",
"dr" => "doctor",
# aliases from Homebrew that we don't (yet) support
# 'ln' => 'link',
# 'configure' => 'diy',
# '--repo' => '--repository',
# 'environment' => '--env',
# '-c1' => '--config',
}.freeze
OPTIONS = {
"--caskroom=" => :caskroom=,
"--appdir=" => :appdir=,
"--colorpickerdir=" => :colorpickerdir=,
"--prefpanedir=" => :prefpanedir=,
"--qlplugindir=" => :qlplugindir=,
"--dictionarydir=" => :dictionarydir=,
"--fontdir=" => :fontdir=,
"--servicedir=" => :servicedir=,
"--input_methoddir=" => :input_methoddir=,
"--internet_plugindir=" => :internet_plugindir=,
"--audio_unit_plugindir=" => :audio_unit_plugindir=,
"--vst_plugindir=" => :vst_plugindir=,
"--vst3_plugindir=" => :vst3_plugindir=,
"--screen_saverdir=" => :screen_saverdir=,
}.freeze
include Options
FLAGS = {
["--[no-]binaries", :binaries] => true,
["--debug", :debug] => false,
["--verbose", :verbose] => false,
["--outdated", :outdated] => false,
["--help", :help] => false,
}.freeze
option "--caskroom=PATH", ->(value) { Hbc.caskroom = value }
option "--appdir=PATH", ->(value) { Hbc.appdir = value }
option "--colorpickerdir=PATH", ->(value) { Hbc.colorpickerdir = value }
option "--prefpanedir=PATH", ->(value) { Hbc.prefpanedir = value }
option "--qlplugindir=PATH", ->(value) { Hbc.qlplugindir = value }
option "--dictionarydir=PATH", ->(value) { Hbc.dictionarydir = value }
option "--fontdir=PATH", ->(value) { Hbc.fontdir = value }
option "--servicedir=PATH", ->(value) { Hbc.servicedir = value }
option "--input_methoddir=PATH", ->(value) { Hbc.input_methoddir = value }
option "--internet_plugindir=PATH", ->(value) { Hbc.internet_plugindir = value }
option "--audio_unit_plugindir=PATH", ->(value) { Hbc.audio_unit_plugindir = value }
option "--vst_plugindir=PATH", ->(value) { Hbc.vst_plugindir = value }
option "--vst3_plugindir=PATH", ->(value) { Hbc.vst3_plugindir = value }
option "--screen_saverdir=PATH", ->(value) { Hbc.screen_saverdir = value }
option "--binarydir=PATH", ->(*) { opoo(<<-EOS.undent) }
Option --binarydir is obsolete!
Homebrew-Cask now uses the same location as your Homebrew installation for executable links.
EOS
FLAGS.each do |(_, method), default_value|
instance_variable_set(:"@#{method}", default_value)
option "--help", :help, false
define_singleton_method(:"#{method}=") do |arg|
instance_variable_set(:"@#{method}", arg)
end
# handled in OS::Mac
option "--language a,b,c", ->(*) { raise OptionParser::InvalidOption }
define_singleton_method(:"#{method}?") do
instance_variable_get(:"@#{method}")
end
end
# override default handling of --version
option "--version", ->(*) { raise OptionParser::InvalidOption }
def self.command_classes
@command_classes ||= constants.map(&method(:const_get))
.select { |sym| sym.respond_to?(:run) }
.select { |klass| klass.respond_to?(:run) }
.reject(&:abstract?)
.sort_by(&:command_name)
end
@ -99,14 +87,14 @@ module Hbc
@commands ||= command_classes.map(&:command_name)
end
def self.lookup_command(command_string)
def self.lookup_command(command_name)
@lookup ||= Hash[commands.zip(command_classes)]
command_string = ALIASES.fetch(command_string, command_string)
@lookup.fetch(command_string, command_string)
command_name = ALIASES.fetch(command_name, command_name)
@lookup.fetch(command_name, command_name)
end
def self.should_init?(command)
(command.is_a? Class) && (command < CLI::Base) && command.needs_init?
command.is_a?(Class) && !command.abstract? && command.needs_init?
end
def self.run_command(command, *rest)
@ -145,20 +133,28 @@ module Hbc
end
end
def self.process(arguments)
def self.run(*args)
new(*args).run
end
def initialize(*args)
@args = process_options(*args)
end
def run
command_name, *args = *@args
command = help? ? "help" : self.class.lookup_command(command_name)
unless ENV["MACOS_VERSION"].nil?
MacOS.full_version = ENV["MACOS_VERSION"]
end
command_string, *rest = *arguments
rest = process_options(rest)
command = help? ? "help" : lookup_command(command_string)
Hbc.default_tap.install unless Hbc.default_tap.installed?
Hbc.init if should_init?(command)
run_command(command, *rest)
rescue CaskError, CaskSha256MismatchError, ArgumentError => e
Hbc.init if self.class.should_init?(command)
self.class.run_command(command, *args)
rescue CaskError, CaskSha256MismatchError, ArgumentError, OptionParser::InvalidOption => e
msg = e.message
msg << e.backtrace.join("\n") if debug?
msg << e.backtrace.join("\n") if ARGV.debug?
onoe msg
exit 1
rescue StandardError, ScriptError, NoMemoryError => e
@ -188,60 +184,25 @@ module Hbc
list.sort
end
def self.parser
# If you modify these arguments, please update USAGE.md
@parser ||= OptionParser.new do |opts|
opts.on("--language STRING") do
# handled in OS::Mac
end
OPTIONS.each do |option, method|
opts.on("#{option}" "PATH", Pathname) do |path|
Hbc.public_send(method, path)
end
end
opts.on("--binarydir=PATH") do
opoo <<-EOS.undent
Option --binarydir is obsolete!
Homebrew-Cask now uses the same location as your Homebrew installation for executable links.
EOS
end
FLAGS.keys.each do |flag, method|
opts.on(flag) do |bool|
send(:"#{method}=", bool)
end
end
opts.on("--version") do
raise OptionParser::InvalidOption # override default handling of --version
end
end
end
def self.process_options(args)
def process_options(*args)
all_args = Shellwords.shellsplit(ENV["HOMEBREW_CASK_OPTS"] || "") + args
remaining = []
until all_args.empty?
non_options = []
if idx = all_args.index("--")
non_options += all_args.drop(idx)
all_args = all_args.first(idx)
end
remaining = all_args.select do |arg|
begin
head = all_args.shift
remaining.concat(parser.parse([head]))
rescue OptionParser::InvalidOption
remaining << head
retry
rescue OptionParser::MissingArgument
raise ArgumentError, "The option '#{head}' requires an argument."
rescue OptionParser::AmbiguousOption
raise ArgumentError, "There is more than one possible option that starts with '#{head}'."
!process_arguments([arg]).empty?
rescue OptionParser::InvalidOption, OptionParser::MissingArgument, OptionParser::AmbiguousOption
true
end
end
# for compat with Homebrew, not certain if this is desirable
self.verbose = true if ARGV.verbose?
self.debug = true if ARGV.debug?
remaining
remaining + non_options
end
class NullCommand

View File

@ -1,12 +1,17 @@
module Hbc
class CLI
class Version < Base
class Version < AbstractCommand
def self.command_name
"--#{super}"
end
def self.run(*args)
raise ArgumentError, "#{command_name} does not take arguments." unless args.empty?
def initialize(*)
super
return if args.empty?
raise ArgumentError, "#{self.class.command_name} does not take arguments."
end
def run
puts Hbc.full_version
end

View File

@ -0,0 +1,49 @@
require_relative "options"
module Hbc
class CLI
class AbstractCommand
include Options
option "--[no-]binaries", :binaries, true
option "--debug", :debug, false
option "--verbose", :verbose, false
option "--outdated", :outdated_only, false
def self.command_name
@command_name ||= name.sub(/^.*:/, "").gsub(/(.)([A-Z])/, '\1_\2').downcase
end
def self.abstract?
!(name.split("::").last !~ /^Abstract[^a-z]/)
end
def self.visible
true
end
def self.cask_tokens_from(args)
args.reject { |a| a.empty? || a.chars.first == "-" }
end
def self.help
nil
end
def self.needs_init?
false
end
def self.run(*args)
new(*args).run
end
attr_accessor :args
private :args=
def initialize(*args)
@args = process_arguments(*args)
end
end
end
end

View File

@ -1,6 +1,6 @@
module Hbc
class CLI
class InternalUseBase < Base
class AbstractInternalCommand < AbstractCommand
def self.command_name
super.sub(/^internal_/i, "_")
end

View File

@ -1,51 +1,27 @@
module Hbc
class CLI
class Audit < Base
class Audit < AbstractCommand
option "--download", :download, false
option "--token-conflicts", :token_conflicts, false
def self.help
"verifies installability of Casks"
end
def self.run(*args)
failed_casks = new(args, Auditor).run
def run
casks_to_audit = args.empty? ? Hbc.all : args.map(&CaskLoader.public_method(:load))
failed_casks = casks_to_audit.reject do |cask|
audit(cask)
end
return if failed_casks.empty?
raise CaskError, "audit failed for casks: #{failed_casks.join(" ")}"
end
def initialize(args, auditor)
@args = args
@auditor = auditor
end
def run
casks_to_audit.each_with_object([]) do |cask, failed|
failed << cask unless audit(cask)
end
end
def audit(cask)
odebug "Auditing Cask #{cask}"
@auditor.audit(cask, audit_download: audit_download?,
check_token_conflicts: check_token_conflicts?)
end
def audit_download?
@args.include?("--download")
end
def check_token_conflicts?
@args.include?("--token-conflicts")
end
def casks_to_audit
if cask_tokens.empty?
Hbc.all
else
cask_tokens.map { |token| CaskLoader.load(token) }
end
end
def cask_tokens
@cask_tokens ||= self.class.cask_tokens_from(@args)
Auditor.audit(cask, audit_download: download?, check_token_conflicts: token_conflicts?)
end
def self.needs_init?

View File

@ -1,25 +0,0 @@
module Hbc
class CLI
class Base
def self.command_name
@command_name ||= name.sub(/^.*:/, "").gsub(/(.)([A-Z])/, '\1_\2').downcase
end
def self.visible
true
end
def self.cask_tokens_from(args)
args.reject { |a| a.empty? || a.chars.first == "-" }
end
def self.help
nil
end
def self.needs_init?
false
end
end
end
end

View File

@ -1,14 +1,17 @@
module Hbc
class CLI
class Cat < Base
def self.run(*args)
cask_tokens = cask_tokens_from(args)
raise CaskUnspecifiedError if cask_tokens.empty?
# only respects the first argument
cask_token = cask_tokens.first.sub(/\.rb$/i, "")
cask_path = CaskLoader.path(cask_token)
raise CaskUnavailableError, cask_token.to_s unless cask_path.exist?
puts File.open(cask_path, &:read)
class Cat < AbstractCommand
def initialize(*)
super
raise CaskUnspecifiedError if args.empty?
end
def run
args.each do |cask_token|
cask_path = CaskLoader.path(cask_token)
raise CaskUnavailableError, cask_token.to_s unless cask_path.exist?
puts File.open(cask_path, &:read)
end
end
def self.help

View File

@ -1,6 +1,6 @@
module Hbc
class CLI
class Cleanup < Base
class Cleanup < AbstractCommand
OUTDATED_DAYS = 10
OUTDATED_TIMESTAMP = Time.now - (60 * 60 * 24 * OUTDATED_DAYS)
@ -12,30 +12,15 @@ module Hbc
true
end
def self.run(*args)
if args.empty?
default.cleanup!
else
default.cleanup(args)
end
end
attr_reader :cache_location
def self.default
@default ||= new(Hbc.cache, CLI.outdated?)
end
attr_reader :cache_location, :outdated_only
def initialize(cache_location, outdated_only)
def initialize(*args, cache_location: Hbc.cache)
super(*args)
@cache_location = Pathname.new(cache_location)
@outdated_only = outdated_only
end
def cleanup!
remove_cache_files
end
def cleanup(tokens)
remove_cache_files(*tokens)
def run
remove_cache_files(*@args)
end
def cache_files
@ -46,7 +31,7 @@ module Hbc
end
def outdated?(file)
outdated_only && file && file.stat.mtime > OUTDATED_TIMESTAMP
outdated_only? && file && file.stat.mtime > OUTDATED_TIMESTAMP
end
def incomplete?(file)
@ -68,7 +53,7 @@ module Hbc
def remove_cache_files(*tokens)
message = "Removing cached downloads"
message.concat " for #{tokens.join(", ")}" unless tokens.empty?
message.concat " older than #{OUTDATED_DAYS} days old" if outdated_only
message.concat " older than #{OUTDATED_DAYS} days old" if outdated_only?
ohai message
deletable_cache_files = if tokens.empty?

View File

@ -1,17 +1,20 @@
module Hbc
class CLI
class Create < Base
def self.run(*args)
cask_tokens = cask_tokens_from(args)
raise CaskUnspecifiedError if cask_tokens.empty?
cask_token = cask_tokens.first.sub(/\.rb$/i, "")
cask_path = CaskLoader.path(cask_token)
odebug "Creating Cask #{cask_token}"
class Create < AbstractCommand
def initialize(*)
super
raise CaskUnspecifiedError if args.empty?
raise ArgumentError, "Only one Cask can be created at a time." if args.count > 1
end
def run
cask_token = args.first
cask_path = CaskLoader.path(cask_token)
raise CaskAlreadyCreatedError, cask_token if cask_path.exist?
odebug "Creating Cask #{cask_token}"
File.open(cask_path, "w") do |f|
f.write template(cask_token)
f.write self.class.template(cask_token)
end
exec_editor cask_path

View File

@ -1,14 +1,20 @@
module Hbc
class CLI
class Doctor < Base
def self.run
class Doctor < AbstractCommand
def initialize(*)
super
return if args.empty?
raise ArgumentError, "#{self.class.command_name} does not take arguments."
end
def run
ohai "Homebrew-Cask Version", Hbc.full_version
ohai "Homebrew-Cask Install Location", render_install_location
ohai "Homebrew-Cask Staging Location", render_staging_location(Hbc.caskroom)
ohai "Homebrew-Cask Cached Downloads", render_cached_downloads
ohai "Homebrew-Cask Install Location", self.class.render_install_location
ohai "Homebrew-Cask Staging Location", self.class.render_staging_location(Hbc.caskroom)
ohai "Homebrew-Cask Cached Downloads", self.class.render_cached_downloads
ohai "Homebrew-Cask Taps:"
puts render_taps(Hbc.default_tap, *alt_taps)
ohai "Contents of $LOAD_PATH", render_load_path($LOAD_PATH)
puts self.class.render_taps(Hbc.default_tap, *self.class.alt_taps)
ohai "Contents of $LOAD_PATH", self.class.render_load_path($LOAD_PATH)
ohai "Environment Variables"
environment_variables = [
@ -24,7 +30,7 @@ module Hbc
"SHELL",
]
(locale_variables + environment_variables).sort.each(&method(:render_env_var))
(self.class.locale_variables + environment_variables).sort.each(&self.class.method(:render_env_var))
end
def self.locale_variables
@ -45,7 +51,7 @@ module Hbc
end
def self.alt_taps
Tap.select { |t| t.cask_dir && t != Hbc.default_tap }
Tap.select { |t| t.cask_dir.exist? && t != Hbc.default_tap }
end
def self.cask_count_for_tap(tap)
@ -107,7 +113,7 @@ module Hbc
end
def self.render_cached_downloads
cleanup = CLI::Cleanup.default
cleanup = CLI::Cleanup.new
count = cleanup.cache_files.count
size = cleanup.disk_cleanup_size
msg = user_tilde(Hbc.cache.to_s)

View File

@ -1,16 +1,21 @@
module Hbc
class CLI
class Edit < Base
def self.run(*args)
cask_tokens = cask_tokens_from(args)
raise CaskUnspecifiedError if cask_tokens.empty?
# only respects the first argument
cask_token = cask_tokens.first.sub(/\.rb$/i, "")
class Edit < AbstractCommand
def initialize(*)
super
raise CaskUnspecifiedError if args.empty?
raise ArgumentError, "Only one Cask can be created at a time." if args.count > 1
end
def run
cask_token = args.first
cask_path = CaskLoader.path(cask_token)
odebug "Opening editor for Cask #{cask_token}"
unless cask_path.exist?
raise CaskUnavailableError, %Q(#{cask_token}, run "brew cask create #{cask_token}" to create a new Cask)
end
odebug "Opening editor for Cask #{cask_token}"
exec_editor cask_path
end

View File

@ -1,15 +1,18 @@
module Hbc
class CLI
class Fetch < Base
def self.run(*args)
cask_tokens = cask_tokens_from(args)
raise CaskUnspecifiedError if cask_tokens.empty?
force = args.include? "--force"
class Fetch < AbstractCommand
option "--force", :force, false
cask_tokens.each do |cask_token|
def initialize(*)
super
raise CaskUnspecifiedError if args.empty?
end
def run
args.each do |cask_token|
ohai "Downloading external files for Cask #{cask_token}"
cask = CaskLoader.load(cask_token)
downloaded_path = Download.new(cask, force: force).perform
downloaded_path = Download.new(cask, force: force?).perform
Verify.all(cask, downloaded_path)
ohai "Success! Downloaded to -> #{downloaded_path}"
end

View File

@ -1,19 +1,24 @@
module Hbc
class CLI
class Home < Base
def self.run(*cask_tokens)
if cask_tokens.empty?
class Home < AbstractCommand
def run
casks = args.map(&CaskLoader.public_method(:load))
if casks.empty?
odebug "Opening project homepage"
system "/usr/bin/open", "--", "https://caskroom.github.io/"
self.class.open_url "https://caskroom.github.io/"
else
cask_tokens.each do |cask_token|
odebug "Opening homepage for Cask #{cask_token}"
cask = CaskLoader.load(cask_token)
system "/usr/bin/open", "--", cask.homepage
casks.each do |cask|
odebug "Opening homepage for Cask #{cask}"
self.class.open_url cask.homepage
end
end
end
def self.open_url(url)
SystemCommand.run!(OS::PATH_OPEN, args: ["--", url])
end
def self.help
"opens the homepage of the given Cask"
end

View File

@ -1,14 +1,17 @@
module Hbc
class CLI
class Info < Base
def self.run(*args)
cask_tokens = cask_tokens_from(args)
raise CaskUnspecifiedError if cask_tokens.empty?
cask_tokens.each do |cask_token|
class Info < AbstractCommand
def initialize(*)
super
raise CaskUnspecifiedError if args.empty?
end
def run
args.each do |cask_token|
odebug "Getting info for Cask #{cask_token}"
cask = CaskLoader.load(cask_token)
info(cask)
self.class.info(cask)
end
end

View File

@ -1,28 +1,33 @@
module Hbc
class CLI
class Install < Base
def self.run(*args)
cask_tokens = cask_tokens_from(args)
raise CaskUnspecifiedError if cask_tokens.empty?
force = args.include? "--force"
skip_cask_deps = args.include? "--skip-cask-deps"
require_sha = args.include? "--require-sha"
retval = install_casks cask_tokens, force, skip_cask_deps, require_sha
class Install < AbstractCommand
option "--force", :force, false
option "--skip-cask-deps", :skip_cask_deps, false
option "--require-sha", :require_sha, false
def initialize(*)
super
raise CaskUnspecifiedError if args.empty?
end
def run
retval = install_casks
# retval is ternary: true/false/nil
raise CaskError, "nothing to install" if retval.nil?
raise CaskError, "install incomplete" unless retval
end
def self.install_casks(cask_tokens, force, skip_cask_deps, require_sha)
def install_casks
count = 0
cask_tokens.each do |cask_token|
args.each do |cask_token|
begin
cask = CaskLoader.load(cask_token)
Installer.new(cask,
force: force,
skip_cask_deps: skip_cask_deps,
require_sha: require_sha).install
Installer.new(cask, binaries: binaries?,
verbose: verbose?,
force: force?,
skip_cask_deps: skip_cask_deps?,
require_sha: require_sha?).install
count += 1
rescue CaskAlreadyInstalledError => e
opoo e.message
@ -31,7 +36,7 @@ module Hbc
opoo e.message
count += 1
rescue CaskUnavailableError => e
warn_unavailable_with_suggestion cask_token, e
self.class.warn_unavailable_with_suggestion cask_token, e
rescue CaskNoShasumError => e
opoo e.message
count += 1
@ -39,7 +44,8 @@ module Hbc
onoe e.message
end
end
count.zero? ? nil : count == cask_tokens.length
count.zero? ? nil : count == args.length
end
def self.warn_unavailable_with_suggestion(cask_token, e)

View File

@ -1,15 +1,18 @@
module Hbc
class CLI
class InternalAppcastCheckpoint < InternalUseBase
def self.run(*args)
calculate = args.include? "--calculate"
cask_tokens = cask_tokens_from(args)
raise CaskUnspecifiedError if cask_tokens.empty?
class InternalAppcastCheckpoint < AbstractInternalCommand
option "--calculate", :calculate, false
def initialize(*)
super
raise CaskUnspecifiedError if args.empty?
end
def run
if cask_tokens.all? { |t| t =~ %r{^https?://} && t !~ /\.rb$/ }
appcask_checkpoint_for_url(cask_tokens)
self.class.appcask_checkpoint_for_url(cask_tokens)
else
appcask_checkpoint(cask_tokens, calculate)
self.class.appcask_checkpoint(cask_tokens, calculate?)
end
end

View File

@ -1,26 +1,29 @@
module Hbc
class CLI
class InternalAuditModifiedCasks < InternalUseBase
class InternalAuditModifiedCasks < AbstractInternalCommand
RELEVANT_STANZAS = [:version, :sha256, :url, :appcast].freeze
option "--cleanup", :cleanup, false
def self.needs_init?
true
end
def self.run(*args)
commit_range = commit_range(args)
cleanup = args.any? { |a| a =~ /^-+c(leanup)?$/i }
new(commit_range, cleanup: cleanup).run
end
attr_accessor :commit_range
private :commit_range=
def self.commit_range(args)
posargs = args.reject { |a| a.empty? || a.chars.first == "-" }
odie usage unless posargs.size == 1
posargs.first
end
def initialize(*)
super
def self.posargs(args)
args.reject { |a| a.empty? || a.chars.first == "-" }
if args.count != 1
raise ArgumentError, <<-EOS.undent
This command requires exactly one argument.
#{self.class.usage}
EOS
end
@commit_range = args.first
end
def self.help
@ -41,17 +44,6 @@ module Hbc
EOS
end
def initialize(commit_range, cleanup: false)
@commit_range = commit_range
@cleanup = cleanup
end
attr_reader :commit_range
def cleanup?
@cleanup
end
def run
at_exit do
cleanup

View File

@ -1,8 +1,8 @@
module Hbc
class CLI
class InternalCheckurl < InternalUseBase
def self.run(*args)
casks_to_check = args.empty? ? Hbc.all : args.map { |arg| CaskLoader.load(arg) }
class InternalCheckurl < AbstractInternalCommand
def run
casks_to_check = args.empty? ? Hbc.all : args.map(&CaskLoader.public_method(:load))
casks_to_check.each do |cask|
odebug "Checking URL for Cask #{cask}"
checker = UrlChecker.new(cask)

View File

@ -1,20 +1,22 @@
module Hbc
class CLI
class InternalDump < InternalUseBase
def self.run(*arguments)
cask_tokens = cask_tokens_from(arguments)
raise CaskUnspecifiedError if cask_tokens.empty?
retval = dump_casks(*cask_tokens)
class InternalDump < AbstractInternalCommand
def initialize(*)
super
raise CaskUnspecifiedError if args.empty?
end
def run
retval = dump_casks
# retval is ternary: true/false/nil
raise CaskError, "nothing to dump" if retval.nil?
raise CaskError, "dump incomplete" unless retval
end
def self.dump_casks(*cask_tokens)
CLI.debug = true # Yuck. At the moment this is the only way to make dumps visible
def dump_casks
count = 0
cask_tokens.each do |cask_token|
args.each do |cask_token|
begin
cask = CaskLoader.load(cask_token)
count += 1
@ -23,7 +25,7 @@ module Hbc
opoo "#{cask_token} was not found or would not load: #{e}"
end
end
count.zero? ? nil : count == cask_tokens.length
count.zero? ? nil : count == args.length
end
def self.help

View File

@ -1,12 +1,18 @@
module Hbc
class CLI
class InternalHelp < InternalUseBase
def self.run(*_ignored)
class InternalHelp < AbstractInternalCommand
def initialize(*)
super
return if args.empty?
raise ArgumentError, "#{self.class.command_name} does not take arguments."
end
def run
max_command_len = CLI.commands.map(&:length).max
puts "Unstable Internal-use Commands:\n\n"
CLI.command_classes.each do |klass|
next if klass.visible
puts " #{klass.command_name.ljust(max_command_len)} #{help_for(klass)}"
puts " #{klass.command_name.ljust(max_command_len)} #{self.class.help_for(klass)}"
end
puts "\n"
end

View File

@ -1,6 +1,6 @@
module Hbc
class CLI
class InternalStanza < InternalUseBase
class InternalStanza < AbstractInternalCommand
# Syntax
#
# brew cask _stanza <stanza_name> [ --table | --yaml | --inspect | --quiet ] [ <cask_token> ... ]
@ -50,71 +50,82 @@ module Hbc
:uninstall_postflight,
]
def self.run(*args)
option "--table", :table, false
option "--quiet", :quiet, false
option "--yaml", :yaml, false
option "--inspect", :inspect, false
attr_accessor :format
private :format, :format=
attr_accessor :stanza
private :stanza, :stanza=
def initialize(*)
super
raise ArgumentError, "No stanza given." if args.empty?
table = args.include? "--table"
quiet = args.include? "--quiet"
format = :to_yaml if args.include? "--yaml"
format = :inspect if args.include? "--inspect"
cask_tokens = cask_tokens_from(args)
stanza = cask_tokens.shift.to_sym
cask_tokens = Hbc.all_tokens if cask_tokens.empty?
@stanza = args.shift.to_sym
retval = print_stanzas(stanza, format, table, quiet, *cask_tokens)
@format = :to_yaml if yaml?
@format = :inspect if inspect?
end
def run
retval = print_stanzas
# retval is ternary: true/false/nil
if retval.nil?
exit 1 if quiet
exit 1 if quiet?
raise CaskError, "nothing to print"
elsif !retval
exit 1 if quiet
exit 1 if quiet?
raise CaskError, "print incomplete"
end
end
def self.print_stanzas(stanza, format = nil, table = nil, quiet = nil, *cask_tokens)
def print_stanzas
count = 0
if ARTIFACTS.include?(stanza)
artifact_name = stanza
stanza = :artifacts
@stanza = :artifacts
end
cask_tokens = args.empty? ? Hbc.all_tokens : args
cask_tokens.each do |cask_token|
print "#{cask_token}\t" if table
print "#{cask_token}\t" if table?
begin
cask = CaskLoader.load(cask_token)
rescue StandardError
opoo "Cask '#{cask_token}' was not found" unless quiet
opoo "Cask '#{cask_token}' was not found" unless quiet?
puts ""
next
end
unless cask.respond_to?(stanza)
opoo "no such stanza '#{stanza}' on Cask '#{cask_token}'" unless quiet
opoo "no such stanza '#{stanza}' on Cask '#{cask_token}'" unless quiet?
puts ""
next
end
begin
value = cask.send(stanza)
value = cask.send(@stanza)
rescue StandardError
opoo "failure calling '#{stanza}' on Cask '#{cask_token}'" unless quiet
opoo "failure calling '#{stanza}' on Cask '#{cask_token}'" unless quiet?
puts ""
next
end
if artifact_name && !value.key?(artifact_name)
opoo "no such stanza '#{artifact_name}' on Cask '#{cask_token}'" unless quiet
opoo "no such stanza '#{artifact_name}' on Cask '#{cask_token}'" unless quiet?
puts ""
next
end
value = value.fetch(artifact_name).to_a.flatten if artifact_name
if format
puts value.send(format)
if @format
puts value.send(@format)
elsif artifact_name || value.is_a?(Symbol)
puts value.inspect
else

View File

@ -1,19 +1,18 @@
module Hbc
class CLI
class List < Base
def self.run(*arguments)
@options = {}
@options[:one] = true if arguments.delete("-1")
@options[:versions] = true if arguments.delete("--versions")
class List < AbstractCommand
option "-1", :one, false
option "--versions", :versions, false
if arguments.delete("-l")
@options[:one] = true
opoo "Option -l is obsolete! Implying option -1."
end
option "-l", (lambda do |*|
one = true # rubocop:disable Lint/UselessAssignment
opoo "Option -l is obsolete! Implying option -1."
end)
retval = arguments.any? ? list(*arguments) : list_installed
def run
retval = args.any? ? list : list_installed
# retval is ternary: true/false/nil
if retval.nil? && !arguments.any?
if retval.nil? && !args.any?
opoo "nothing to list" # special case: avoid exit code
elsif retval.nil?
raise CaskError, "nothing to list"
@ -22,22 +21,22 @@ module Hbc
end
end
def self.list(*cask_tokens)
def list
count = 0
cask_tokens.each do |cask_token|
args.each do |cask_token|
odebug "Listing files for Cask #{cask_token}"
begin
cask = CaskLoader.load(cask_token)
if cask.installed?
if @options[:one]
if one?
puts cask.token
elsif @options[:versions]
puts format_versioned(cask)
elsif versions?
puts self.class.format_versioned(cask)
else
cask = CaskLoader.load_from_file(cask.installed_caskfile)
list_artifacts(cask)
self.class.list_artifacts(cask)
end
count += 1
@ -49,7 +48,7 @@ module Hbc
end
end
count.zero? ? nil : count == cask_tokens.length
count.zero? ? nil : count == args.length
end
def self.list_artifacts(cask)
@ -59,13 +58,13 @@ module Hbc
end
end
def self.list_installed
def list_installed
installed_casks = Hbc.installed
if @options[:one]
if one?
puts installed_casks.map(&:to_s)
elsif @options[:versions]
puts installed_casks.map(&method(:format_versioned))
elsif versions?
puts installed_casks.map(&self.class.method(:format_versioned))
elsif !installed_casks.empty?
puts Formatter.columns(installed_casks.map(&:to_s))
end

View File

@ -0,0 +1,62 @@
module Hbc
class CLI
module Options
def self.included(klass)
klass.extend(ClassMethods)
end
module ClassMethods
def options
@options ||= {}
return @options unless superclass.respond_to?(:options)
superclass.options.merge(@options)
end
def option(name, method, default_value = nil)
@options ||= {}
@options[name] = method
return if method.respond_to?(:call)
define_method(:"#{method}=") do |value|
instance_variable_set(:"@#{method}", value)
end
if [true, false].include?(default_value)
define_method(:"#{method}?") do
instance_variable_get(:"@#{method}") == true
end
else
define_method(:"#{method}") do
instance_variable_get(:"@#{method}")
end
end
end
end
def process_arguments(*arguments)
parser = OptionParser.new do |opts|
next if self.class.options.nil?
self.class.options.each do |option_name, option_method|
option_type = case option_name.split(/(\ |\=)/).last
when "PATH"
Pathname
when /\w+(,\w+)+/
Array
end
opts.on(option_name, *option_type) do |value|
if option_method.respond_to?(:call)
option_method.call(value)
else
send(:"#{option_method}=", value)
end
end
end
end
parser.parse(*arguments)
end
end
end
end

View File

@ -1,20 +1,20 @@
module Hbc
class CLI
class Outdated < Base
def self.run(*args)
greedy = args.include?("--greedy")
verbose = ($stdout.tty? || CLI.verbose?) && !args.include?("--quiet")
class Outdated < AbstractCommand
option "--greedy", :greedy, false
option "--quiet", :quiet, false
cask_tokens = cask_tokens_from(args)
casks_to_check = if cask_tokens.empty?
Hbc.installed
else
cask_tokens.map { |token| CaskLoader.load(token) }
end
def initialize(*)
super
self.verbose = ($stdout.tty? || verbose?) && !quiet?
end
def run
casks_to_check = args.empty? ? Hbc.installed : args.map(&CaskLoader.public_method(:load))
casks_to_check.each do |cask|
odebug "Checking update info of Cask #{cask}"
list_if_outdated(cask, greedy, verbose)
self.class.list_if_outdated(cask, greedy?, verbose?)
end
end

View File

@ -1,26 +1,29 @@
module Hbc
class CLI
class Reinstall < Install
def self.install_casks(cask_tokens, force, skip_cask_deps, require_sha)
def install_casks
count = 0
cask_tokens.each do |cask_token|
args.each do |cask_token|
begin
cask = CaskLoader.load(cask_token)
Installer.new(cask,
force: force,
skip_cask_deps: skip_cask_deps,
require_sha: require_sha).reinstall
binaries: binaries?,
verbose: verbose?,
force: force?,
skip_cask_deps: skip_cask_deps?,
require_sha: require_sha?).reinstall
count += 1
rescue CaskUnavailableError => e
warn_unavailable_with_suggestion cask_token, e
self.class.warn_unavailable_with_suggestion cask_token, e
rescue CaskNoShasumError => e
opoo e.message
count += 1
end
end
count.zero? ? nil : count == cask_tokens.length
count.zero? ? nil : count == args.length
end
def self.help

View File

@ -1,8 +1,13 @@
module Hbc
class CLI
class Search < Base
def self.run(*arguments)
render_results(*search(*arguments))
class Search < AbstractCommand
def initialize(*args)
@args = args
end
def run
results = self.class.search(*args)
self.class.render_results(*results)
end
def self.extract_regexp(string)

View File

@ -2,25 +2,18 @@ require "English"
module Hbc
class CLI
class Style < Base
class Style < AbstractCommand
def self.help
"checks Cask style using RuboCop"
end
def self.run(*args)
retval = new(args).run
raise CaskError, "style check failed" unless retval
end
attr_reader :args
def initialize(args)
@args = args
end
option "--fix", :fix, false
def run
install_rubocop
system "rubocop", *rubocop_args, "--", *cask_paths
$CHILD_STATUS.success?
raise CaskError, "style check failed" unless $CHILD_STATUS.success?
true
end
def install_rubocop
@ -34,19 +27,15 @@ module Hbc
end
def cask_paths
@cask_paths ||= if cask_tokens.empty?
@cask_paths ||= if args.empty?
Hbc.all_tapped_cask_dirs
elsif cask_tokens.any? { |file| File.exist?(file) }
cask_tokens
elsif args.any? { |file| File.exist?(file) }
args
else
cask_tokens.map { |token| CaskLoader.path(token) }
args.map { |token| CaskLoader.path(token) }
end
end
def cask_tokens
@cask_tokens ||= self.class.cask_tokens_from(args)
end
def rubocop_args
fix? ? autocorrect_args : default_args
end
@ -63,10 +52,6 @@ module Hbc
def autocorrect_args
default_args + ["--auto-correct"]
end
def fix?
args.any? { |arg| arg =~ /--(fix|(auto-?)?correct)/ }
end
end
end
end

View File

@ -1,23 +1,26 @@
module Hbc
class CLI
class Uninstall < Base
def self.run(*args)
cask_tokens = cask_tokens_from(args)
raise CaskUnspecifiedError if cask_tokens.empty?
force = args.include? "--force"
class Uninstall < AbstractCommand
option "--force", :force, false
cask_tokens.each do |cask_token|
def initialize(*)
super
raise CaskUnspecifiedError if args.empty?
end
def run
args.each do |cask_token|
odebug "Uninstalling Cask #{cask_token}"
cask = CaskLoader.load(cask_token)
raise CaskNotInstalledError, cask unless cask.installed? || force
raise CaskNotInstalledError, cask unless cask.installed? || force?
if cask.installed? && !cask.installed_caskfile.nil?
# use the same cask file that was used for installation, if possible
cask = CaskLoader.load_from_file(cask.installed_caskfile) if cask.installed_caskfile.exist?
end
Installer.new(cask, force: force).uninstall
Installer.new(cask, binaries: binaries?, verbose: verbose?, force: force?).uninstall
next if (versions = cask.versions).empty?

View File

@ -1,13 +1,16 @@
module Hbc
class CLI
class Zap < Base
def self.run(*args)
cask_tokens = cask_tokens_from(args)
raise CaskUnspecifiedError if cask_tokens.empty?
cask_tokens.each do |cask_token|
class Zap < AbstractCommand
def initialize(*)
super
raise CaskUnspecifiedError if args.empty?
end
def run
args.each do |cask_token|
odebug "Zapping Cask #{cask_token}"
cask = CaskLoader.load(cask_token)
Installer.new(cask).zap
Installer.new(cask, verbose: verbose?).zap
end
end

View File

@ -14,19 +14,35 @@ module Hbc
include Staged
include Verify
attr_reader :force, :skip_cask_deps
PERSISTENT_METADATA_SUBDIRS = ["gpg"].freeze
def initialize(cask, command: SystemCommand, force: false, skip_cask_deps: false, require_sha: false)
def initialize(cask, command: SystemCommand, force: false, skip_cask_deps: false, binaries: true, verbose: false, require_sha: false)
@cask = cask
@command = command
@force = force
@skip_cask_deps = skip_cask_deps
@binaries = binaries
@verbose = verbose
@require_sha = require_sha
@reinstall = false
end
def skip_cask_deps?
@skip_cask_deps
end
def force?
@force
end
def binaries?
@binaries
end
def verbose?
@verbose
end
def self.print_caveats(cask)
odebug "Printing caveats"
return if cask.caveats.empty?
@ -59,7 +75,7 @@ module Hbc
odebug "Hbc::Installer#fetch"
satisfy_dependencies
verify_has_sha if @require_sha && !@force
verify_has_sha if @require_sha && !force?
download
verify
end
@ -77,7 +93,7 @@ module Hbc
def install
odebug "Hbc::Installer#install"
if @cask.installed? && !force && !@reinstall
if @cask.installed? && !force? && !@reinstall
raise CaskAlreadyInstalledAutoUpdatesError, @cask if @cask.auto_updates
raise CaskAlreadyInstalledError, @cask
end
@ -108,7 +124,7 @@ module Hbc
installed_cask = installed_caskfile.exist? ? CaskLoader.load_from_file(installed_caskfile) : @cask
# Always force uninstallation, ignore method parameter
Installer.new(installed_cask, force: true).uninstall
Installer.new(installed_cask, binaries: binaries?, verbose: verbose?, force: true).uninstall
end
def summary
@ -156,12 +172,17 @@ module Hbc
already_installed_artifacts = []
odebug "Installing artifacts"
artifacts = Artifact.for_cask(@cask, command: @command, force: force)
artifacts = Artifact.for_cask(@cask, command: @command, verbose: verbose?, force: force?)
odebug "#{artifacts.length} artifact/s defined", artifacts
artifacts.each do |artifact|
next unless artifact.respond_to?(:install_phase)
odebug "Installing artifact of class #{artifact.class}"
if artifact.is_a?(Artifact::Binary)
next unless binaries?
end
artifact.install_phase
already_installed_artifacts.unshift(artifact)
end
@ -189,7 +210,7 @@ module Hbc
arch_dependencies
x11_dependencies
formula_dependencies
cask_dependencies unless skip_cask_deps
cask_dependencies unless skip_cask_deps?
puts "complete"
end
@ -254,7 +275,7 @@ module Hbc
if dep.installed?
puts "already installed"
else
Installer.new(dep, force: false, skip_cask_deps: true).install
Installer.new(dep, binaries: binaries?, verbose: verbose?, skip_cask_deps: true, force: false).install
puts "done"
end
end
@ -330,12 +351,12 @@ module Hbc
disable_accessibility_access
uninstall_artifacts
purge_versioned_files
purge_caskroom_path if force
purge_caskroom_path if force?
end
def uninstall_artifacts
odebug "Un-installing artifacts"
artifacts = Artifact.for_cask(@cask, command: @command, force: force)
artifacts = Artifact.for_cask(@cask, command: @command, verbose: verbose?, force: force?)
# Make sure the `uninstall` stanza is run first, as it
# may depend on other artifacts still being installed.

View File

@ -154,7 +154,7 @@ module Hbc
def self._parse_plist(command, output)
raise CaskError, "Empty plist input" unless output =~ /\S/
output.sub!(/\A(.*?)(<\?\s*xml)/m, '\2')
_warn_plist_garbage(command, Regexp.last_match[1]) if CLI.debug?
_warn_plist_garbage(command, Regexp.last_match[1]) if ARGV.debug?
output.sub!(%r{(<\s*/\s*plist\s*>)(.*?)\Z}m, '\1')
_warn_plist_garbage(command, Regexp.last_match[2])
xml = Plist.parse_xml(output)

View File

@ -29,7 +29,7 @@ end
# global methods
def odebug(title, *sput)
return unless Hbc::CLI.debug?
return unless ARGV.debug?
puts Formatter.headline(title, color: :magenta)
puts sput unless sput.empty?
end

View File

@ -5,6 +5,6 @@ module Homebrew
module_function
def cask
Hbc::CLI.process(ARGV)
Hbc::CLI.run(*ARGV)
end
end

View File

@ -1,8 +1,8 @@
require "cask/lib/hbc/cli/base"
require "cask/lib/hbc/cli/abstract_command"
module Hbc
class CLI
class Update < Base
class Update < AbstractCommand
def self.run(*_ignored)
odeprecated "`brew cask update`", "`brew update`", disable_on: Time.utc(2017, 7, 1)
result = SystemCommand.run(HOMEBREW_BREW_FILE, args: ["update"],

View File

@ -16,6 +16,20 @@ describe Hbc::Artifact::Binary, :cask do
FileUtils.rm expected_path if expected_path.exist?
end
context "when --no-binaries is specified" do
let(:cask) {
Hbc::CaskLoader.load_from_file(TEST_FIXTURE_DIR/"cask/Casks/with-binary.rb")
}
it "doesn't link the binary when --no-binaries is specified" do
shutup do
Hbc::Installer.new(cask, binaries: false).install
end
expect(expected_path).not_to exist
end
end
it "links the binary to the proper directory" do
shutup do
Hbc::Artifact::Binary.new(cask).install_phase
@ -70,22 +84,6 @@ describe Hbc::Artifact::Binary, :cask do
expect(File.readlink(expected_path)).not_to eq("/tmp")
end
it "respects --no-binaries flag" do
begin
Hbc::CLI.binaries = false
expect(Hbc::CLI).not_to be_binaries
shutup do
Hbc::Artifact::Binary.new(cask).install_phase
end
expect(expected_path.exist?).to be false
ensure
Hbc::CLI.binaries = true
end
end
it "creates parent directory if it doesn't exist" do
FileUtils.rmdir Hbc.binarydir

View File

@ -1,59 +1,64 @@
describe Hbc::CLI::Audit, :cask do
let(:auditor) { double }
let(:cask) { double }
describe "selection of Casks to audit" do
it "audits all Casks if no tokens are given" do
allow(Hbc).to receive(:all).and_return([cask, cask])
expect(auditor).to receive(:audit).twice
expect(Hbc::Auditor).to receive(:audit).twice.and_return(true)
run_audit([], auditor)
Hbc::CLI::Audit.run
end
it "audits specified Casks if tokens are given" do
cask_token = "nice-app"
expect(Hbc::CaskLoader).to receive(:load).with(cask_token).and_return(cask)
expect(auditor).to receive(:audit).with(cask, audit_download: false, check_token_conflicts: false)
expect(Hbc::Auditor).to receive(:audit)
.with(cask, audit_download: false, check_token_conflicts: false)
.and_return(true)
run_audit([cask_token], auditor)
Hbc::CLI::Audit.run(cask_token)
end
end
describe "rules for downloading a Cask" do
it "does not download the Cask per default" do
allow(Hbc::CaskLoader).to receive(:load).and_return(cask)
expect(auditor).to receive(:audit).with(cask, audit_download: false, check_token_conflicts: false)
expect(Hbc::Auditor).to receive(:audit)
.with(cask, audit_download: false, check_token_conflicts: false)
.and_return(true)
run_audit(["casktoken"], auditor)
Hbc::CLI::Audit.run("casktoken")
end
it "download a Cask if --download flag is set" do
allow(Hbc::CaskLoader).to receive(:load).and_return(cask)
expect(auditor).to receive(:audit).with(cask, audit_download: true, check_token_conflicts: false)
expect(Hbc::Auditor).to receive(:audit)
.with(cask, audit_download: true, check_token_conflicts: false)
.and_return(true)
run_audit(["casktoken", "--download"], auditor)
Hbc::CLI::Audit.run("casktoken", "--download")
end
end
describe "rules for checking token conflicts" do
it "does not check for token conflicts per default" do
allow(Hbc::CaskLoader).to receive(:load).and_return(cask)
expect(auditor).to receive(:audit).with(cask, audit_download: false, check_token_conflicts: false)
expect(Hbc::Auditor).to receive(:audit)
.with(cask, audit_download: false, check_token_conflicts: false)
.and_return(true)
run_audit(["casktoken"], auditor)
Hbc::CLI::Audit.run("casktoken")
end
it "checks for token conflicts if --token-conflicts flag is set" do
allow(Hbc::CaskLoader).to receive(:load).and_return(cask)
expect(auditor).to receive(:audit).with(cask, audit_download: false, check_token_conflicts: true)
expect(Hbc::Auditor).to receive(:audit)
.with(cask, audit_download: false, check_token_conflicts: true)
.and_return(true)
run_audit(["casktoken", "--token-conflicts"], auditor)
Hbc::CLI::Audit.run("casktoken", "--token-conflicts")
end
end
def run_audit(args, auditor)
Hbc::CLI::Audit.new(args, auditor).run
end
end

View File

@ -1,6 +1,6 @@
describe Hbc::CLI::Cat, :cask do
describe "given a basic Cask" do
let(:expected_output) {
let(:basic_cask_content) {
<<-EOS.undent
cask 'basic-cask' do
version '1.2.3'
@ -17,19 +17,19 @@ describe Hbc::CLI::Cat, :cask do
it "displays the Cask file content about the specified Cask" do
expect {
Hbc::CLI::Cat.run("basic-cask")
}.to output(expected_output).to_stdout
}.to output(basic_cask_content).to_stdout
end
it "throws away additional Cask arguments and uses the first" do
it "can display multiple Casks" do
expect {
Hbc::CLI::Cat.run("basic-cask", "local-caffeine")
}.to output(expected_output).to_stdout
Hbc::CLI::Cat.run("basic-cask", "basic-cask")
}.to output(basic_cask_content * 2).to_stdout
end
it "throws away stray options" do
it "fails when option is unknown" do
expect {
Hbc::CLI::Cat.run("--notavalidoption", "basic-cask")
}.to output(expected_output).to_stdout
}.to raise_error(/invalid option/)
end
end
@ -51,7 +51,7 @@ describe Hbc::CLI::Cat, :cask do
it "raises an exception" do
expect {
Hbc::CLI::Cat.run("--notavalidoption")
}.to raise_error(Hbc::CaskUnspecifiedError)
}.to raise_error(/invalid option/)
end
end
end

View File

@ -1,19 +1,24 @@
describe Hbc::CLI::Cleanup, :cask do
let(:cache_location) { Pathname.new(Dir.mktmpdir).realpath }
let(:cleanup_outdated) { false }
let(:outdated_only) { false }
subject { described_class.new(cache_location, cleanup_outdated) }
subject { described_class.new(*cask_tokens, cache_location: cache_location) }
before(:each) do
allow_any_instance_of(described_class).to receive(:outdated_only?).and_return(outdated_only)
end
after do
cache_location.rmtree
end
describe "cleanup" do
it "removes cached downloads of given casks" do
cleaned_up_cached_download = "caffeine"
let(:cask_token) { "caffeine" }
let(:cask_tokens) { [cask_token] }
it "removes cached downloads of given casks" do
cached_downloads = [
cache_location.join("#{cleaned_up_cached_download}--latest.zip"),
cache_location.join("#{cask_token}--latest.zip"),
cache_location.join("transmission--2.61.dmg"),
]
@ -22,9 +27,9 @@ describe Hbc::CLI::Cleanup, :cask do
cleanup_size = cached_downloads[0].disk_usage
expect {
subject.cleanup(cleaned_up_cached_download)
subject.run
}.to output(<<-EOS.undent).to_stdout
==> Removing cached downloads for #{cleaned_up_cached_download}
==> Removing cached downloads for #{cask_token}
#{cached_downloads[0]}
==> This operation has freed approximately #{disk_usage_readable(cleanup_size)} of disk space.
EOS
@ -32,61 +37,42 @@ describe Hbc::CLI::Cleanup, :cask do
expect(cached_downloads[0].exist?).to eq(false)
expect(cached_downloads[1].exist?).to eq(true)
end
end
describe "cleanup!" do
it "removes cached downloads" do
cached_download = cache_location.join("SomeDownload.dmg")
FileUtils.touch(cached_download)
cleanup_size = subject.disk_cleanup_size
context "when no argument is given" do
let(:cask_tokens) { [] }
expect {
subject.cleanup!
}.to output(<<-EOS.undent).to_stdout
==> Removing cached downloads
#{cached_download}
==> This operation has freed approximately #{disk_usage_readable(cleanup_size)} of disk space.
EOS
expect(cached_download.exist?).to eq(false)
end
# TODO: uncomment when unflaky.
# it "does not removed locked files" do
# cached_download = cache_location.join("SomeDownload.dmg")
# FileUtils.touch(cached_download)
# cleanup_size = subject.disk_cleanup_size
#
# File.new(cached_download).flock(File::LOCK_EX)
#
# expect(Hbc::Utils).to be_file_locked(cached_download)
#
# expect {
# subject.cleanup!
# }.to output(<<-EOS.undent).to_stdout
# ==> Removing cached downloads
# skipping: #{cached_download} is locked
# ==> This operation has freed approximately #{disk_usage_readable(cleanup_size)} of disk space.
# EOS
#
# expect(cached_download.exist?).to eq(true)
# end
context "when cleanup_outdated is specified" do
let(:cleanup_outdated) { true }
it "does not remove cache files newer than 10 days old" do
cached_download = cache_location.join("SomeNewDownload.dmg")
it "removes all cached downloads" do
cached_download = cache_location.join("SomeDownload.dmg")
FileUtils.touch(cached_download)
cleanup_size = subject.disk_cleanup_size
expect {
subject.cleanup!
subject.run
}.to output(<<-EOS.undent).to_stdout
==> Removing cached downloads older than 10 days old
Nothing to do
==> Removing cached downloads
#{cached_download}
==> This operation has freed approximately #{disk_usage_readable(cleanup_size)} of disk space.
EOS
expect(cached_download.exist?).to eq(true)
expect(cached_download.exist?).to eq(false)
end
context "and :outdated_only is specified" do
let(:outdated_only) { true }
it "does not remove cache files newer than 10 days old" do
cached_download = cache_location.join("SomeNewDownload.dmg")
FileUtils.touch(cached_download)
expect {
subject.run
}.to output(<<-EOS.undent).to_stdout
==> Removing cached downloads older than 10 days old
Nothing to do
EOS
expect(cached_download.exist?).to eq(true)
end
end
end
end

View File

@ -1,43 +1,26 @@
# monkeypatch for testing
module Hbc
class CLI
class Create
def self.exec_editor(*command)
editor_commands << command
end
def self.reset!
@editor_commands = []
end
def self.editor_commands
@editor_commands ||= []
end
end
end
end
describe Hbc::CLI::Create, :cask do
before(:each) do
Hbc::CLI::Create.reset!
around(:each) do |example|
begin
example.run
ensure
%w[new-cask additional-cask another-cask yet-another-cask local-caff].each do |cask|
FileUtils.rm_f Hbc::CaskLoader.path(cask)
end
end
end
after(:each) do
%w[new-cask additional-cask another-cask yet-another-cask local-caff].each do |cask|
path = Hbc::CaskLoader.path(cask)
path.delete if path.exist?
end
before(:each) do
allow_any_instance_of(described_class).to receive(:exec_editor)
end
it "opens the editor for the specified Cask" do
Hbc::CLI::Create.run("new-cask")
expect(Hbc::CLI::Create.editor_commands).to eq [
[Hbc::CaskLoader.path("new-cask")],
]
command = described_class.new("new-cask")
expect(command).to receive(:exec_editor).with(Hbc::CaskLoader.path("new-cask"))
command.run
end
it "drops a template down for the specified Cask" do
Hbc::CLI::Create.run("new-cask")
described_class.run("new-cask")
template = File.read(Hbc::CaskLoader.path("new-cask"))
expect(template).to eq <<-EOS.undent
cask 'new-cask' do
@ -53,46 +36,43 @@ describe Hbc::CLI::Create, :cask do
EOS
end
it "throws away additional Cask arguments and uses the first" do
Hbc::CLI::Create.run("additional-cask", "another-cask")
expect(Hbc::CLI::Create.editor_commands).to eq [
[Hbc::CaskLoader.path("additional-cask")],
]
end
it "throws away stray options" do
Hbc::CLI::Create.run("--notavalidoption", "yet-another-cask")
expect(Hbc::CLI::Create.editor_commands).to eq [
[Hbc::CaskLoader.path("yet-another-cask")],
]
it "raises an exception when more than one Cask is given" do
expect {
described_class.run("additional-cask", "another-cask")
}.to raise_error(/Only one Cask can be created at a time./)
end
it "raises an exception when the Cask already exists" do
expect {
Hbc::CLI::Create.run("basic-cask")
described_class.run("basic-cask")
}.to raise_error(Hbc::CaskAlreadyCreatedError)
end
it "allows creating Casks that are substrings of existing Casks" do
Hbc::CLI::Create.run("local-caff")
expect(Hbc::CLI::Create.editor_commands).to eq [
[Hbc::CaskLoader.path("local-caff")],
]
command = described_class.new("local-caff")
expect(command).to receive(:exec_editor).with(Hbc::CaskLoader.path("local-caff"))
command.run
end
describe "when no Cask is specified" do
it "raises an exception" do
expect {
Hbc::CLI::Create.run
described_class.run
}.to raise_error(Hbc::CaskUnspecifiedError)
end
end
describe "when no Cask is specified, but an invalid option" do
context "when an invalid option is specified" do
it "raises an exception when no Cask is specified" do
expect {
described_class.run("--notavalidoption")
}.to raise_error(/invalid option/)
end
it "raises an exception" do
expect {
Hbc::CLI::Create.run("--notavalidoption")
}.to raise_error(Hbc::CaskUnspecifiedError)
described_class.run("--notavalidoption", "yet-another-cask")
}.to raise_error(/invalid option/)
end
end
end

View File

@ -1,51 +1,30 @@
# monkeypatch for testing
module Hbc
class CLI
class Edit
def self.exec_editor(*command)
editor_commands << command
end
def self.reset!
@editor_commands = []
end
def self.editor_commands
@editor_commands ||= []
end
end
end
end
describe Hbc::CLI::Edit, :cask do
before(:each) do
Hbc::CLI::Edit.reset!
allow_any_instance_of(described_class).to receive(:exec_editor)
end
it "opens the editor for the specified Cask" do
Hbc::CLI::Edit.run("local-caffeine")
expect(Hbc::CLI::Edit.editor_commands).to eq [
[Hbc::CaskLoader.path("local-caffeine")],
]
command = described_class.new("local-caffeine")
expect(command).to receive(:exec_editor).with(Hbc::CaskLoader.path("local-caffeine"))
command.run
end
it "throws away additional arguments and uses the first" do
Hbc::CLI::Edit.run("local-caffeine", "local-transmission")
expect(Hbc::CLI::Edit.editor_commands).to eq [
[Hbc::CaskLoader.path("local-caffeine")],
]
it "raises an error when given more than one argument" do
expect {
described_class.new("local-caffeine", "local-transmission")
}.to raise_error(/Only one Cask can be created at a time./)
end
it "raises an exception when the Cask doesnt exist" do
expect {
Hbc::CLI::Edit.run("notacask")
described_class.run("notacask")
}.to raise_error(Hbc::CaskUnavailableError)
end
describe "when no Cask is specified" do
it "raises an exception" do
expect {
Hbc::CLI::Edit.run
described_class.run
}.to raise_error(Hbc::CaskUnspecifiedError)
end
end
@ -53,8 +32,8 @@ describe Hbc::CLI::Edit, :cask do
describe "when no Cask is specified, but an invalid option" do
it "raises an exception" do
expect {
Hbc::CLI::Edit.run("--notavalidoption")
}.to raise_error(Hbc::CaskUnspecifiedError)
described_class.run("--notavalidoption")
}.to raise_error(/invalid option/)
end
end
end

View File

@ -69,7 +69,7 @@ describe Hbc::CLI::Fetch, :cask do
it "raises an exception" do
expect {
Hbc::CLI::Fetch.run("--notavalidoption")
}.to raise_error(Hbc::CaskUnspecifiedError)
}.to raise_error(/invalid option/)
end
end
end

View File

@ -1,46 +1,21 @@
# monkeypatch for testing
module Hbc
class CLI
class Home
def self.system(*command)
system_commands << command
end
def self.reset!
@system_commands = []
end
def self.system_commands
@system_commands ||= []
end
end
end
end
describe Hbc::CLI::Home, :cask do
before do
Hbc::CLI::Home.reset!
allow(described_class).to receive(:open_url)
end
it "opens the homepage for the specified Cask" do
Hbc::CLI::Home.run("local-caffeine")
expect(Hbc::CLI::Home.system_commands).to eq [
["/usr/bin/open", "--", "http://example.com/local-caffeine"],
]
expect(described_class).to receive(:open_url).with("http://example.com/local-caffeine")
described_class.run("local-caffeine")
end
it "works for multiple Casks" do
Hbc::CLI::Home.run("local-caffeine", "local-transmission")
expect(Hbc::CLI::Home.system_commands).to eq [
["/usr/bin/open", "--", "http://example.com/local-caffeine"],
["/usr/bin/open", "--", "http://example.com/local-transmission"],
]
expect(described_class).to receive(:open_url).with("http://example.com/local-caffeine")
expect(described_class).to receive(:open_url).with("http://example.com/local-transmission")
described_class.run("local-caffeine", "local-transmission")
end
it "opens the project page when no Cask is specified" do
Hbc::CLI::Home.run
expect(Hbc::CLI::Home.system_commands).to eq [
["/usr/bin/open", "--", "https://caskroom.github.io/"],
]
expect(described_class).to receive(:open_url).with("https://caskroom.github.io/")
described_class.run
end
end

View File

@ -45,7 +45,7 @@ describe Hbc::CLI::Info, :cask do
it "throws away stray options" do
expect {
Hbc::CLI::Info.run("--notavalidoption", "local-caffeine", "local-transmission")
}.to output(expected_output).to_stdout
}.to raise_error(/invalid option/)
end
end
@ -102,7 +102,7 @@ describe Hbc::CLI::Info, :cask do
it "raises an exception" do
expect {
Hbc::CLI::Info.run("--notavalidoption")
}.to raise_error(Hbc::CaskUnspecifiedError)
}.to raise_error(/invalid option/)
end
end
end

View File

@ -40,7 +40,7 @@ describe Hbc::CLI::Install, :cask do
end
expect {
Hbc::CLI::Install.run("local-transmission", "")
Hbc::CLI::Install.run("local-transmission")
}.to output(/Warning: A Cask for local-transmission is already installed./).to_stderr
end
@ -115,7 +115,11 @@ describe Hbc::CLI::Install, :cask do
end
describe "with an invalid option" do
with_options.call(["--notavalidoption"])
it "raises an error" do
expect {
Hbc::CLI::Install.run("--notavalidoption")
}.to raise_error(/invalid option/)
end
end
end
end

View File

@ -1,6 +1,6 @@
describe Hbc::CLI, :cask do
it "supports setting the appdir" do
Hbc::CLI.process_options %w[help --appdir=/some/path/foo]
Hbc::CLI.new.process_options("help", "--appdir=/some/path/foo")
expect(Hbc.appdir).to eq(Pathname.new("/some/path/foo"))
end
@ -8,13 +8,13 @@ describe Hbc::CLI, :cask do
it "supports setting the appdir from ENV" do
ENV["HOMEBREW_CASK_OPTS"] = "--appdir=/some/path/bar"
Hbc::CLI.process_options %w[help]
Hbc::CLI.new.process_options("help")
expect(Hbc.appdir).to eq(Pathname.new("/some/path/bar"))
end
it "supports setting the prefpanedir" do
Hbc::CLI.process_options %w[help --prefpanedir=/some/path/foo]
Hbc::CLI.new.process_options("help", "--prefpanedir=/some/path/foo")
expect(Hbc.prefpanedir).to eq(Pathname.new("/some/path/foo"))
end
@ -22,13 +22,13 @@ describe Hbc::CLI, :cask do
it "supports setting the prefpanedir from ENV" do
ENV["HOMEBREW_CASK_OPTS"] = "--prefpanedir=/some/path/bar"
Hbc::CLI.process_options %w[help]
Hbc::CLI.new.process_options("help")
expect(Hbc.prefpanedir).to eq(Pathname.new("/some/path/bar"))
end
it "supports setting the qlplugindir" do
Hbc::CLI.process_options %w[help --qlplugindir=/some/path/foo]
Hbc::CLI.new.process_options("help", "--qlplugindir=/some/path/foo")
expect(Hbc.qlplugindir).to eq(Pathname.new("/some/path/foo"))
end
@ -36,13 +36,13 @@ describe Hbc::CLI, :cask do
it "supports setting the qlplugindir from ENV" do
ENV["HOMEBREW_CASK_OPTS"] = "--qlplugindir=/some/path/bar"
Hbc::CLI.process_options %w[help]
Hbc::CLI.new.process_options("help")
expect(Hbc.qlplugindir).to eq(Pathname.new("/some/path/bar"))
end
it "supports setting the colorpickerdir" do
Hbc::CLI.process_options %w[help --colorpickerdir=/some/path/foo]
Hbc::CLI.new.process_options("help", "--colorpickerdir=/some/path/foo")
expect(Hbc.colorpickerdir).to eq(Pathname.new("/some/path/foo"))
end
@ -50,13 +50,13 @@ describe Hbc::CLI, :cask do
it "supports setting the colorpickerdir from ENV" do
ENV["HOMEBREW_CASK_OPTS"] = "--colorpickerdir=/some/path/bar"
Hbc::CLI.process_options %w[help]
Hbc::CLI.new.process_options("help")
expect(Hbc.colorpickerdir).to eq(Pathname.new("/some/path/bar"))
end
it "supports setting the dictionarydir" do
Hbc::CLI.process_options %w[help --dictionarydir=/some/path/foo]
Hbc::CLI.new.process_options("help", "--dictionarydir=/some/path/foo")
expect(Hbc.dictionarydir).to eq(Pathname.new("/some/path/foo"))
end
@ -64,13 +64,13 @@ describe Hbc::CLI, :cask do
it "supports setting the dictionarydir from ENV" do
ENV["HOMEBREW_CASK_OPTS"] = "--dictionarydir=/some/path/bar"
Hbc::CLI.process_options %w[help]
Hbc::CLI.new.process_options("help")
expect(Hbc.dictionarydir).to eq(Pathname.new("/some/path/bar"))
end
it "supports setting the fontdir" do
Hbc::CLI.process_options %w[help --fontdir=/some/path/foo]
Hbc::CLI.new.process_options("help", "--fontdir=/some/path/foo")
expect(Hbc.fontdir).to eq(Pathname.new("/some/path/foo"))
end
@ -78,13 +78,13 @@ describe Hbc::CLI, :cask do
it "supports setting the fontdir from ENV" do
ENV["HOMEBREW_CASK_OPTS"] = "--fontdir=/some/path/bar"
Hbc::CLI.process_options %w[help]
Hbc::CLI.new.process_options("help")
expect(Hbc.fontdir).to eq(Pathname.new("/some/path/bar"))
end
it "supports setting the servicedir" do
Hbc::CLI.process_options %w[help --servicedir=/some/path/foo]
Hbc::CLI.new.process_options("help", "--servicedir=/some/path/foo")
expect(Hbc.servicedir).to eq(Pathname.new("/some/path/foo"))
end
@ -92,53 +92,22 @@ describe Hbc::CLI, :cask do
it "supports setting the servicedir from ENV" do
ENV["HOMEBREW_CASK_OPTS"] = "--servicedir=/some/path/bar"
Hbc::CLI.process_options %w[help]
Hbc::CLI.new.process_options("help")
expect(Hbc.servicedir).to eq(Pathname.new("/some/path/bar"))
end
it "allows additional options to be passed through" do
rest = Hbc::CLI.process_options %w[edit foo --create --appdir=/some/path/qux]
rest = Hbc::CLI.new.process_options("edit", "foo", "--create", "--appdir=/some/path/qux")
expect(Hbc.appdir).to eq(Pathname.new("/some/path/qux"))
expect(rest).to eq(%w[edit foo --create])
end
describe "when a mandatory argument is missing" do
it "shows a user-friendly error message" do
expect {
Hbc::CLI.process_options %w[install -f]
}.to raise_error(ArgumentError)
end
end
describe "given an ambiguous option" do
it "shows a user-friendly error message" do
expect {
Hbc::CLI.process_options %w[edit -c]
}.to raise_error(ArgumentError)
end
end
describe "--debug" do
it "sets the Cask debug method to true" do
begin
Hbc::CLI.process_options %w[help --debug]
expect(Hbc::CLI.debug?).to be true
ensure
Hbc::CLI.debug = false
end
end
end
describe "--help" do
it "sets the Cask help method to true" do
begin
Hbc::CLI.process_options %w[foo --help]
expect(Hbc::CLI.help?).to be true
ensure
Hbc::CLI.help = false
end
command = Hbc::CLI.new("foo", "--help")
expect(command.help?).to be true
end
end
end

View File

@ -13,13 +13,13 @@ describe Hbc::CLI::Outdated, :cask do
shutup do
installed.each { |cask| InstallHelper.install_with_caskfile(cask) }
end
allow(Hbc::CLI).to receive(:verbose?).and_return(true)
allow_any_instance_of(described_class).to receive(:verbose?).and_return(true)
end
describe 'without --greedy it ignores the Casks with "vesion latest" or "auto_updates true"' do
it "checks all the installed Casks when no token is provided" do
expect {
Hbc::CLI::Outdated.run
described_class.run
}.to output(<<-EOS.undent).to_stdout
local-caffeine (1.2.2) != 1.2.3
local-transmission (2.60) != 2.61
@ -28,7 +28,7 @@ describe Hbc::CLI::Outdated, :cask do
it "checks only the tokens specified in the command line" do
expect {
Hbc::CLI::Outdated.run("local-caffeine")
described_class.run("local-caffeine")
}.to output(<<-EOS.undent).to_stdout
local-caffeine (1.2.2) != 1.2.3
EOS
@ -36,26 +36,32 @@ describe Hbc::CLI::Outdated, :cask do
it 'ignores "auto_updates" and "latest" Casks even when their tokens are provided in the command line' do
expect {
Hbc::CLI::Outdated.run("local-caffeine", "auto-updates", "version-latest-string")
described_class.run("local-caffeine", "auto-updates", "version-latest-string")
}.to output(<<-EOS.undent).to_stdout
local-caffeine (1.2.2) != 1.2.3
EOS
end
end
it "lists only the names (no versions) of the outdated Casks with --quiet" do
expect {
Hbc::CLI::Outdated.run("--quiet")
}.to output(<<-EOS.undent).to_stdout
local-caffeine
local-transmission
EOS
describe "--quiet overrides --verbose" do
before do
allow_any_instance_of(described_class).to receive(:verbose?).and_call_original
end
it "lists only the names (no versions) of the outdated Casks with --quiet" do
expect {
described_class.run("--verbose", "--quiet")
}.to output(<<-EOS.undent).to_stdout
local-caffeine
local-transmission
EOS
end
end
describe "with --greedy it checks additional Casks" do
it 'includes the Casks with "auto_updates true" or "version latest" with --greedy' do
expect {
Hbc::CLI::Outdated.run("--greedy")
described_class.run("--greedy")
}.to output(<<-EOS.undent).to_stdout
auto-updates (2.57) != 2.61
local-caffeine (1.2.2) != 1.2.3
@ -69,7 +75,7 @@ describe Hbc::CLI::Outdated, :cask do
InstallHelper.install_with_caskfile(cask)
expect {
Hbc::CLI::Outdated.run("--greedy")
described_class.run("--greedy")
}.to output(<<-EOS.undent).to_stdout
local-caffeine (1.2.2) != 1.2.3
local-transmission (2.60) != 2.61

View File

@ -4,37 +4,12 @@ require "rubygems"
describe Hbc::CLI::Style, :cask do
let(:args) { [] }
let(:cli) { described_class.new(args) }
let(:cli) { described_class.new(*args) }
around do |example|
shutup { example.run }
end
describe ".run" do
subject { described_class.run(args) }
before do
allow(described_class).to receive(:new).and_return(cli)
allow(cli).to receive(:run).and_return(retval)
end
context "when rubocop succeeds" do
let(:retval) { true }
it "exits successfully" do
subject
end
end
context "when rubocop fails" do
let(:retval) { false }
it "raises an exception" do
expect { subject }.to raise_error(Hbc::CaskError)
end
end
end
describe "#run" do
subject { cli.run }
@ -53,7 +28,10 @@ describe Hbc::CLI::Style, :cask do
context "when rubocop fails" do
let(:success) { false }
it { is_expected.to be_falsey }
it "raises an error" do
expect { subject }.to raise_error(Hbc::CaskError)
end
end
end
@ -99,7 +77,7 @@ describe Hbc::CLI::Style, :cask do
subject { cli.cask_paths }
before do
allow(cli).to receive(:cask_tokens).and_return(tokens)
allow(cli).to receive(:args).and_return(tokens)
end
context "when no cask tokens are given" do
@ -136,40 +114,6 @@ describe Hbc::CLI::Style, :cask do
end
end
describe "#cask_tokens" do
subject { cli.cask_tokens }
context "when no args are given" do
let(:args) { [] }
it { is_expected.to be_empty }
end
context "when only flags are given" do
let(:args) { ["--fix"] }
it { is_expected.to be_empty }
end
context "when only empty args are given" do
let(:args) { ["", ""] }
it { is_expected.to be_empty }
end
context "when a cask token is given" do
let(:args) { ["adium"] }
it { is_expected.to eq(["adium"]) }
end
context "when multiple cask tokens are given" do
let(:args) { %w[adium dropbox] }
it { is_expected.to eq(%w[adium dropbox]) }
end
context "when cask tokens are given with flags" do
let(:args) { ["adium", "dropbox", "--fix"] }
it { is_expected.to eq(%w[adium dropbox]) }
end
end
describe "#rubocop_args" do
subject { cli.rubocop_args }
@ -203,33 +147,4 @@ describe Hbc::CLI::Style, :cask do
expect(subject).to include("--auto-correct", *default_args)
end
end
describe "#fix?" do
subject { cli.fix? }
context "when --fix is passed as an argument" do
let(:args) { ["adium", "--fix"] }
it { is_expected.to be_truthy }
end
context "when --correct is passed as an argument" do
let(:args) { ["adium", "--correct"] }
it { is_expected.to be_truthy }
end
context "when --auto-correct is passed as an argument" do
let(:args) { ["adium", "--auto-correct"] }
it { is_expected.to be_truthy }
end
context "when --auto-correct is misspelled as --autocorrect" do
let(:args) { ["adium", "--autocorrect"] }
it { is_expected.to be_truthy }
end
context "when no flag equivalent to --fix is passed as an argument" do
let(:args) { ["adium"] }
it { is_expected.to be_falsey }
end
end
end

View File

@ -203,7 +203,7 @@ describe Hbc::CLI::Uninstall, :cask do
it "raises an exception" do
expect {
Hbc::CLI::Uninstall.run("--notavalidoption")
}.to raise_error(Hbc::CaskUnspecifiedError)
}.to raise_error(/invalid option/)
end
end
end

View File

@ -18,8 +18,7 @@ describe Hbc::CLI::Zap, :cask do
expect(transmission).to be_installed
shutup do
Hbc::CLI::Zap.run("--notavalidoption",
"local-caffeine", "local-transmission")
Hbc::CLI::Zap.run("local-caffeine", "local-transmission")
end
expect(caffeine).not_to be_installed
@ -67,7 +66,7 @@ describe Hbc::CLI::Zap, :cask do
it "raises an exception" do
expect {
Hbc::CLI::Zap.run("--notavalidoption")
}.to raise_error(Hbc::CaskUnspecifiedError)
}.to raise_error(/invalid option/)
end
end
end

View File

@ -13,7 +13,7 @@ describe Hbc::CLI, :cask do
])
end
context ".process" do
context "::run" do
let(:noop_command) { double("CLI::Noop") }
before do
@ -30,37 +30,35 @@ describe Hbc::CLI, :cask do
version_command = double("CLI::Version")
allow(described_class).to receive(:lookup_command).with("--version").and_return(version_command)
expect(described_class).to receive(:run_command).with(version_command)
described_class.process(["--version"])
described_class.run("--version")
end
it "prints help output when subcommand receives `--help` flag" do
begin
expect(described_class).to receive(:run_command).with("help")
described_class.process(%w[noop --help])
expect(Hbc::CLI.help?).to eq(true)
ensure
Hbc::CLI.help = false
end
command = Hbc::CLI.new("noop", "--help")
expect(described_class).to receive(:run_command).with("help")
command.run
expect(command.help?).to eq(true)
end
it "respects the env variable when choosing what appdir to create" do
allow(ENV).to receive(:[])
allow(ENV).to receive(:[]).with("HOMEBREW_CASK_OPTS").and_return("--appdir=/custom/appdir")
expect(Hbc).to receive(:appdir=).with(Pathname.new("/custom/appdir"))
described_class.process("noop")
described_class.run("noop")
end
it "respects the env variable when choosing a non-default Caskroom location" do
allow(ENV).to receive(:[])
allow(ENV).to receive(:[]).with("HOMEBREW_CASK_OPTS").and_return("--caskroom=/custom/caskdir")
expect(Hbc).to receive(:caskroom=).with(Pathname.new("/custom/caskdir"))
described_class.process("noop")
described_class.run("noop")
end
it "exits with a status of 1 when something goes wrong" do
allow(described_class).to receive(:lookup_command).and_raise(Hbc::CaskError)
expect(described_class).to receive(:exit).with(1)
described_class.process("noop")
command = Hbc::CLI.new("noop")
expect(command).to receive(:exit).with(1)
command.run
end
end