mirror of
https://github.com/pry/pry.git
synced 2022-11-09 12:35:05 -05:00
objectify existing commands
This commit is contained in:
parent
42c37777bf
commit
fd4506f88c
3 changed files with 55 additions and 63 deletions
|
@ -168,21 +168,18 @@ class Pry
|
||||||
def execute_command(target, command, options, *args)
|
def execute_command(target, command, options, *args)
|
||||||
ret = nil
|
ret = nil
|
||||||
|
|
||||||
if command.callable.is_a?(Proc)
|
# allocate, setup and then call initialize so that authors
|
||||||
context = CommandContext.new
|
# can do their own setup in initialize.
|
||||||
else
|
context = command.allocate
|
||||||
|
|
||||||
# in the case of non-procs the callable *is* the context
|
|
||||||
context = command.callable
|
|
||||||
end
|
|
||||||
|
|
||||||
# set some useful methods to be used by the action blocks
|
|
||||||
setup_context(target, command, context, options)
|
setup_context(target, command, context, options)
|
||||||
|
context.extend commands.helper_module
|
||||||
|
context.send(:initialize)
|
||||||
|
|
||||||
catch(:command_done) do
|
catch(:command_done) do
|
||||||
ret = commands.run_command(context, command.name, *args)
|
ret = context.call(*args)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# FIXME: wtf?
|
||||||
options[:val].replace("")
|
options[:val].replace("")
|
||||||
|
|
||||||
ret
|
ret
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
require 'pry/command_context'
|
||||||
class Pry
|
class Pry
|
||||||
class NoCommandError < StandardError
|
class NoCommandError < StandardError
|
||||||
def initialize(name, owner)
|
def initialize(name, owner)
|
||||||
|
@ -8,27 +9,52 @@ class Pry
|
||||||
# This class is used to create sets of commands. Commands can be imported from
|
# This class is used to create sets of commands. Commands can be imported from
|
||||||
# different sets, aliased, removed, etc.
|
# different sets, aliased, removed, etc.
|
||||||
class CommandSet
|
class CommandSet
|
||||||
class Command < Struct.new(:name, :description, :options, :callable)
|
class Command < Pry::CommandContext
|
||||||
|
|
||||||
def call(context, *args)
|
class << self
|
||||||
|
attr_accessor :name
|
||||||
|
attr_accessor :description
|
||||||
|
attr_accessor :options
|
||||||
|
attr_accessor :block
|
||||||
|
end
|
||||||
|
|
||||||
if stub_block = options[:stub_info]
|
%w(name description options block).each do |attribute|
|
||||||
context.instance_eval(&stub_block)
|
define_method(attribute) { self.class.send(attribute) }
|
||||||
else
|
end
|
||||||
if callable.is_a?(Proc)
|
|
||||||
ret = context.instance_exec(*correct_arg_arity(callable.arity, args), &callable)
|
|
||||||
else
|
|
||||||
|
|
||||||
# in the case of non-procs the callable *is* the context
|
class << self
|
||||||
ret = callable.call(*correct_arg_arity(callable.method(:call).arity, args))
|
def inspect
|
||||||
end
|
"#<class(Pry::Command #{name.inspect}>"
|
||||||
|
|
||||||
if options[:keep_retval]
|
|
||||||
ret
|
|
||||||
else
|
|
||||||
Pry::CommandContext::VOID_VALUE
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def subclass(name, description, options, &block)
|
||||||
|
klass = Class.new(self)
|
||||||
|
klass.name = name
|
||||||
|
klass.description = description
|
||||||
|
klass.options = options
|
||||||
|
klass.block = block
|
||||||
|
klass
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
class StubCommand < Command
|
||||||
|
def call(*args)
|
||||||
|
gems_needed = Array(options[:requires_gem])
|
||||||
|
gems_not_installed = gems_needed.select { |g| !gem_installed?(g) }
|
||||||
|
output.puts "\nThe command '#{name}' is #{Helpers::Text.bold("unavailable")} because it requires the following gems to be installed: #{(gems_not_installed.join(", "))}"
|
||||||
|
output.puts "-"
|
||||||
|
output.puts "Type `install-command #{name}` to install the required gems and activate this command."
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
class BlockCommand < Command
|
||||||
|
def call(*args)
|
||||||
|
if options[:argument_required] && args.empty?
|
||||||
|
raise CommandError, "The command '#{command.name}' requires an argument."
|
||||||
|
end
|
||||||
|
|
||||||
|
instance_exec(*correct_arg_arity(block.arity, args), &block)
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
@ -118,7 +144,6 @@ class Pry
|
||||||
# # pry(main)> help number
|
# # pry(main)> help number
|
||||||
# # number-N regex command
|
# # number-N regex command
|
||||||
def command(name, description="No description.", options={}, &block)
|
def command(name, description="No description.", options={}, &block)
|
||||||
|
|
||||||
options = {
|
options = {
|
||||||
:requires_gem => [],
|
:requires_gem => [],
|
||||||
:keep_retval => false,
|
:keep_retval => false,
|
||||||
|
@ -129,18 +154,11 @@ class Pry
|
||||||
:use_prefix => true
|
:use_prefix => true
|
||||||
}.merge!(options)
|
}.merge!(options)
|
||||||
|
|
||||||
unless command_dependencies_met? options
|
if command_dependencies_met? options
|
||||||
gems_needed = Array(options[:requires_gem])
|
commands[name] = BlockCommand.subclass(name, description, options, &block)
|
||||||
gems_not_installed = gems_needed.select { |g| !gem_installed?(g) }
|
else
|
||||||
|
commands[name] = StubCommand.subclass(name, description, options)
|
||||||
options[:stub_info] = proc do
|
|
||||||
output.puts "\nThe command '#{name}' is #{Helpers::Text.bold("unavailable")} because it requires the following gems to be installed: #{(gems_not_installed.join(", "))}"
|
|
||||||
output.puts "-"
|
|
||||||
output.puts "Type `install-command #{name}` to install the required gems and activate this command."
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
commands[name] = Command.new(name, description, options, options[:definition] ? options.delete(:definition) : block)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# Execute a block of code before a command is invoked. The block also
|
# Execute a block of code before a command is invoked. The block also
|
||||||
|
@ -278,29 +296,6 @@ class Pry
|
||||||
commands.delete(cmd.name)
|
commands.delete(cmd.name)
|
||||||
end
|
end
|
||||||
|
|
||||||
# Runs a command.
|
|
||||||
# @param [Object] context Object which will be used as self during the
|
|
||||||
# command.
|
|
||||||
# @param [String] name Name of the command to be run
|
|
||||||
# @param [Array<Object>] args Arguments passed to the command
|
|
||||||
# @raise [NoCommandError] If the command is not defined in this set
|
|
||||||
def run_command(context, command_name, *args)
|
|
||||||
command = commands[command_name]
|
|
||||||
|
|
||||||
|
|
||||||
context.extend helper_module
|
|
||||||
|
|
||||||
if command.nil?
|
|
||||||
raise NoCommandError.new(command_name, self)
|
|
||||||
end
|
|
||||||
|
|
||||||
if command.options[:argument_required] && args.empty?
|
|
||||||
puts "The command '#{command.name}' requires an argument."
|
|
||||||
else
|
|
||||||
command.call context, *args
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
# Sets or gets the description for a command (replacing the old
|
# Sets or gets the description for a command (replacing the old
|
||||||
# description). Returns current description if no description
|
# description). Returns current description if no description
|
||||||
# parameter provided.
|
# parameter provided.
|
||||||
|
|
|
@ -69,7 +69,7 @@ class Pry
|
||||||
end
|
end
|
||||||
|
|
||||||
if find_command(command_name)
|
if find_command(command_name)
|
||||||
block = Pry::Method.new(find_command(command_name).callable)
|
block = Pry::Method.new(find_command(command_name).block)
|
||||||
|
|
||||||
next unless block.source
|
next unless block.source
|
||||||
set_file_and_dir_locals(block.source_file)
|
set_file_and_dir_locals(block.source_file)
|
||||||
|
|
Loading…
Add table
Reference in a new issue