mirror of
https://github.com/pry/pry.git
synced 2022-11-09 12:35:05 -05:00
Remove old subcommands cruft
* use a plain old Slop instance instead of `Options`; * remove `ClassCommand::Options` and its tests; * add clearer subcommand example (for `Command#subcommand` method); * refactor `ClassCommand#slop`; * refactor `ClassCommand#complete`. Slop v3.4.0 has introduced full-featured subcommands. There is no need in Pry specific code anymore.
This commit is contained in:
parent
8f65c584ab
commit
c38eb20776
2 changed files with 7 additions and 217 deletions
|
@ -542,140 +542,6 @@ class Pry
|
|||
alias_method :line, :source_line
|
||||
end
|
||||
|
||||
# The class that couples together subcommands and top-level options (that
|
||||
# are known as "default" options). The explicitly defined instance methods
|
||||
# of this class provide the coupling with default options of a
|
||||
# Slop::Commands instance. An instance of this class delegates all remaining
|
||||
# methods to an instance of Slop::Commands class.
|
||||
#
|
||||
# @example
|
||||
# # Define Slop commands.
|
||||
# commands = Slop::Commands.new do |cmd|
|
||||
# cmd.on :action do
|
||||
# on :f, :force, "Use force"
|
||||
# end
|
||||
#
|
||||
# cmd.default do
|
||||
# on :v, :verbose, "Verbose mode"
|
||||
# end
|
||||
# end
|
||||
#
|
||||
# # Pass Slop commands as an argument to Options class.
|
||||
# opts = Options.new(Slop::Commands.new)
|
||||
# opts.default
|
||||
# # => #<Slop ...>
|
||||
#
|
||||
# # Parse subcommands.
|
||||
# opts.parse %'action --force'
|
||||
# opts[:action].present?(:force)
|
||||
# # => true
|
||||
# opts.present?(:force)
|
||||
# # => false
|
||||
#
|
||||
# # Parse default options.
|
||||
# opts.parse %'--verbose'
|
||||
# opts.verbose?
|
||||
# # => true
|
||||
# opts[:action].present?(:verbose)
|
||||
# # => false
|
||||
# opts.verbose
|
||||
# # => NoMethodError
|
||||
class Options < SimpleDelegator
|
||||
|
||||
# @param [Slop::Commands] opts The subcommands and options.
|
||||
# @raise [ArgumentError] if the +opts+ isn't a kind of Slop::Commands.
|
||||
# instance.
|
||||
def initialize(opts)
|
||||
unless opts.kind_of?(Slop::Commands)
|
||||
raise ArgumentError, "Expected an instance of Slop::Command, not #{opts.class} one"
|
||||
end
|
||||
super
|
||||
end
|
||||
|
||||
# Fetch the instance of Slop tied to a command or fetch an options
|
||||
# argument value.
|
||||
#
|
||||
# If the +key+ doesn't correspond to any of the subcommands, the method
|
||||
# tries to find the same +key+ in the list of default options.
|
||||
#
|
||||
# @example
|
||||
# # A subcommand example.
|
||||
# opts = Options.new(commands)
|
||||
# opts.parse %w'download video.ogv'
|
||||
#
|
||||
# opts[:download]
|
||||
# # => #<Slop ...>
|
||||
#
|
||||
# # A default option example.
|
||||
# opts = Options.new(commands)
|
||||
# opts.parse %w'--host=localhost download video.ogv'
|
||||
# opts[:host]
|
||||
# # => true
|
||||
#
|
||||
# @param [String, Symbol] key The subcommand name or the default option.
|
||||
# @return [Slop, Boolean, nil] Either instance of Slop tied to the
|
||||
# command, if any; or `true`, if the default option has the given +key+;
|
||||
# or nil, if can't find the +key+.
|
||||
# @note The method never returns `false`.
|
||||
def [](key)
|
||||
self.get(key) || default.get(key)
|
||||
end
|
||||
|
||||
# Check for default options presence.
|
||||
#
|
||||
# @param [String, Symbol] keys The list of keys to check.
|
||||
# @return [Boolean] Whether all of the +keys+ are present in the parsed
|
||||
# arguments.
|
||||
def present?(*keys)
|
||||
default.present?(*keys)
|
||||
end
|
||||
|
||||
# Check for a command presence.
|
||||
#
|
||||
# @example
|
||||
# opts.parse %w'install'
|
||||
# opts.command?(:install)
|
||||
# # => true
|
||||
# opts.command?(:list)
|
||||
# # => false
|
||||
#
|
||||
# @param [Symbol, String] name The name of the command to be checked
|
||||
# @return [Boolean] `true` if the given +name+ is present in the parsed
|
||||
# arguments
|
||||
def command?(name)
|
||||
__getobj__.present?(name)
|
||||
end
|
||||
|
||||
# Convenience method for {#present?}.
|
||||
#
|
||||
# @example
|
||||
# opts.parse %w'--verbose'
|
||||
# opts.verbose?
|
||||
# # => true
|
||||
# opts.terse?
|
||||
# # => false
|
||||
#
|
||||
# @return [Boolean, void] On condition of +method_name+ ends with a
|
||||
# question mark returns `true`, if the _default option_ is present (and
|
||||
# `false`, if not). Otherwise, calls `super`.
|
||||
def method_missing(method_name, *args, &block)
|
||||
name = method_name.to_s
|
||||
if name.end_with?("?")
|
||||
present?(name.chop)
|
||||
else
|
||||
super
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
# @return [Slop] The instance of Slop representing default options.
|
||||
def default
|
||||
__getobj__[:default]
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
attr_accessor :opts
|
||||
attr_accessor :args
|
||||
|
||||
|
@ -688,7 +554,7 @@ class Pry
|
|||
def call(*args)
|
||||
setup
|
||||
|
||||
self.opts = Options.new(slop)
|
||||
self.opts = slop
|
||||
self.args = self.opts.parse!(args)
|
||||
|
||||
if opts.present?(:help)
|
||||
|
@ -707,14 +573,11 @@ class Pry
|
|||
# Return an instance of Slop::Commands that can parse either subcommands
|
||||
# or the options that this command accepts.
|
||||
def slop
|
||||
Slop::Commands.new do |cmd|
|
||||
subcommands(cmd)
|
||||
|
||||
cmd.default do |opt|
|
||||
opt.banner(unindent(self.class.banner))
|
||||
options(opt)
|
||||
opt.on(:h, :help, "Show this message.")
|
||||
end
|
||||
Slop.parse do |opt|
|
||||
opt.banner(unindent(self.class.banner))
|
||||
subcommands(opt)
|
||||
options(opt)
|
||||
opt.on :h, :help, 'Show this message.'
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -722,7 +585,7 @@ class Pry
|
|||
# @param [String] search The line typed so far
|
||||
# @return [Array<String>] the words to complete
|
||||
def complete(search)
|
||||
slop[:default].map do |opt|
|
||||
slop.map do |opt|
|
||||
[opt.long && "--#{opt.long} " || opt.short && "-#{opt.short}"]
|
||||
end.flatten(1).compact + super
|
||||
end
|
||||
|
|
|
@ -167,79 +167,6 @@ describe "Pry::Command" do
|
|||
end
|
||||
end
|
||||
|
||||
describe Pry::ClassCommand::Options do
|
||||
before do
|
||||
Options = Pry::ClassCommand::Options
|
||||
|
||||
commands = Slop::Commands.new do |cmd|
|
||||
cmd.on :boom do
|
||||
on :v, :verbose, "Verbose boom!"
|
||||
end
|
||||
|
||||
cmd.default do
|
||||
on :n, :nothing, "Do nothing"
|
||||
end
|
||||
end
|
||||
|
||||
@opts = Options.new(commands)
|
||||
end
|
||||
|
||||
describe '#new arguments' do
|
||||
it 'should accept objects that are kind of Slop::Commands as an argument' do
|
||||
class MyCommands < Slop::Commands
|
||||
end
|
||||
|
||||
lambda { Options.new(MyCommands.new) }.should.not.raise ArgumentError
|
||||
end
|
||||
|
||||
it 'should raise ArgumentError if the argument is not kind of Slop::Commands' do
|
||||
lambda { Options.new(Array.new) }.should.raise ArgumentError
|
||||
end
|
||||
end
|
||||
|
||||
describe '#[] method' do
|
||||
it 'should fetch commands' do
|
||||
@opts[:boom].should.be.kind_of Slop
|
||||
end
|
||||
|
||||
it 'should parse default options, if cannot fetch a command' do
|
||||
@opts.parse %w'--nothing'
|
||||
|
||||
@opts[:nothing].should == true
|
||||
@opts[:nothing].should == @opts[:default][:nothing]
|
||||
end
|
||||
|
||||
it 'should return nil if cannot find neither a command nor a default option' do
|
||||
@opts.parse %w'--something'
|
||||
|
||||
@opts[:something].should == nil
|
||||
@opts[:something].should == @opts[:default][:something]
|
||||
end
|
||||
end
|
||||
|
||||
it 'should forward implicitly defined methods to Slop::Commands' do
|
||||
opts = Options.new(Slop::Commands.new)
|
||||
opts.global { on "--something" }
|
||||
opts.parse %w'--something'
|
||||
|
||||
opts[:global][:something].should == true
|
||||
end
|
||||
|
||||
it 'should check for a default options presence' do
|
||||
@opts.parse %w'--nothing'
|
||||
|
||||
@opts.present?(:nothing).should == true
|
||||
@opts.present?(:anything).should == false
|
||||
end
|
||||
|
||||
it "should call #present? on NoMethodError, if the caller's name ends with '?'" do
|
||||
@opts.parse %w'--nothing'
|
||||
|
||||
@opts.nothing?.should == true
|
||||
@opts.anything?.should == false
|
||||
end
|
||||
end
|
||||
|
||||
describe 'classy api' do
|
||||
|
||||
it 'should call setup, then subcommands, then options, then process' do
|
||||
|
|
Loading…
Reference in a new issue