homebrew-cask-versions/lib/cask/cli.rb
Paul Hinze 3c9423e8c6 naked pkg support + major container refactor
`Cask::Installer` was already much too complex, so I took this
opportunity to throw a `Cask::Container` abstraction around the
extraction part of the package install step.

It goes like this: a Cask's URL points to a Container of some sort. The
containers we currently support are: dmg, zip, tar, and (new) naked.
Naked refers to a raw file that just needs to be copied in place. This
currently just means a pkg file, but in the future it may expand.

A Container knows how to do two things: identify a path as being its
type (`Container.me?`) and extracting the contents of its container to
the proper destination for a Cask (`Container#extract`).

The first Cask we have that supports the naked pkg type is
`heroku-toolbelt`. (Thanks to @sheerun for the Cask definition.)

Other miscellania batched in with this refactor:

 - switched to an explicit require strategy rather than globbing
 - `Cask::Installer` is instantiated now to match its interface with
   other similar collaorators
 - simplified zip and tar identification to shorter strings rather than
   exact matches of full `file -Izb` output
 - `Cask::SystemCommand` gets explicit output redirection options
 - many rogue backticks replaced to properly use `SystemCommand`
 - fixed misnamed test file `link_checker_spec.rb`
 - remove some extraneous `after` clauses in tests; leaning more on
   `test/support/cleanup.rb` to uninstall for us
 - pkg uninstall `:files` gets a `-rf` to support removing dirs

refs #839 and #1043
2013-09-21 21:59:07 -05:00

117 lines
2.5 KiB
Ruby

class Cask::CLI; end
require 'optparse'
require 'shellwords'
require 'cask/cli/alfred'
require 'cask/cli/audit'
require 'cask/cli/checklinks'
require 'cask/cli/create'
require 'cask/cli/edit'
require 'cask/cli/home'
require 'cask/cli/info'
require 'cask/cli/install'
require 'cask/cli/linkapps'
require 'cask/cli/list'
require 'cask/cli/search'
require 'cask/cli/uninstall'
require 'cask/cli/unlinkapps'
class Cask::CLI
def self.commands
Cask::CLI.constants - ["NullCommand"]
end
def self.lookup_command(command)
if command && Cask::CLI.const_defined?(command.capitalize)
Cask::CLI.const_get(command.capitalize)
else
Cask::CLI::NullCommand.new(command)
end
end
def self.process(arguments)
command, *rest = *arguments
rest = process_options(rest)
Cask.init
lookup_command(command).run(*rest)
end
def self.nice_listing(cask_list)
casks = {}
cask_list.each { |c|
repo, name = c.split "/"
casks[name] ||= []
casks[name].push repo
}
list = []
casks.each { |name,repos|
if repos.length == 1
list.push name
else
repos.each { |r| list.push [r,name].join "/" }
end
}
list.sort
end
def self.parser
@parser ||= OptionParser.new do |opts|
opts.on("--appdir=MANDATORY") do |v|
Cask.appdir = Pathname.new File.expand_path(v)
end
end
end
def self.process_options(args)
all_args = Shellwords.shellsplit(ENV['HOMEBREW_CASK_OPTS'] || "") + args
remaining = []
while !all_args.empty?
begin
head = all_args.shift
remaining.concat(parser.parse([head]))
rescue OptionParser::InvalidOption
remaining << head
retry
end
end
remaining
end
class NullCommand
def initialize(attempted_name)
@attempted_name = attempted_name
end
def run(*args)
purpose
if @attempted_name and @attempted_name != "help"
puts "!! "
puts "!! no command with name: #{@attempted_name}"
puts "!! "
end
usage
end
def purpose
puts <<-PURPOSE.undent
{{ brew-cask }}
brew-cask provides a friendly homebrew-style CLI workflow for the
administration of Mac applications distributed as binaries
PURPOSE
end
def usage
puts "available commands: "
puts Cask::CLI.commands.map {|c| " - #{c.downcase}: #{_help_for(c)}"}.join("\n")
end
def help
''
end
def _help_for(command)
Cask::CLI.lookup_command(command).help
end
end
end