1
0
Fork 0
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:
Kyrylo Silin 2013-01-13 16:19:28 +02:00
parent 8f65c584ab
commit c38eb20776
2 changed files with 7 additions and 217 deletions

View file

@ -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

View file

@ -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