# frozen_string_literal: true class Pry # A super-class of Commands with structure. # # This class implements the bare-minimum functionality that a command should # have, namely a --help switch, and then delegates actual processing to its # subclasses. # # Create subclasses using {Pry::CommandSet#create_command}, and override the # `options(opt)` method to set up an instance of Pry::Slop, and the `process` # method to actually run the command. If necessary, you can also override # `setup` which will be called before `options`, for example to require any # gems your command needs to run, or to set up state. class ClassCommand < Command class << self # Ensure that subclasses inherit the options, description and # match from a ClassCommand super class. def inherited(klass) klass.match match klass.description description klass.command_options options end def source source_object.source end def doc new.help end def source_location source_object.source_location end def source_file source_object.source_file end alias file source_file def source_line source_object.source_line end alias line source_line private # The object used to extract the source for the command. # # This should be a `Pry::Method(block)` for a command made with `create_command` # and a `Pry::WrappedModule(self)` for a command that's a standard class. # @return [Pry::WrappedModule, Pry::Method] def source_object @source_object ||= if name =~ /^[A-Z]/ Pry::WrappedModule(self) else Pry::Method(block) end end end attr_accessor :opts attr_accessor :args # Set up `opts` and `args`, and then call `process`. # # This method will display help if necessary. # # @param [Array] args The arguments passed # @return [Object] The return value of `process` or VOID_VALUE def call(*args) setup self.opts = slop self.args = opts.parse!(args) if opts.present?(:help) output.puts slop.help void else process(*normalize_method_args(method(:process), args)) end end # Return the help generated by Pry::Slop for this command. def help slop.help end # Return an instance of Pry::Slop that can parse either subcommands or the # options that this command accepts. def slop Pry::Slop.new do |opt| opt.banner(unindent(self.class.banner)) subcommands(opt) options(opt) opt.on :h, :help, 'Show this message.' end end # Generate shell completions # @param [String] search The line typed so far # @return [Array] the words to complete def complete(search) slop.flat_map do |opt| [opt.long && "--#{opt.long} " || opt.short && "-#{opt.short}"] end.compact + super end # A method called just before `options(opt)` as part of `call`. # # This method can be used to set up any context your command needs to run, # for example requiring gems, or setting default values for options. # # @example # def setup # require 'gist' # @action = :method # end def setup; end # A method to setup Pry::Slop commands so it can parse the subcommands your # command expects. If you need to set up default values, use `setup` # instead. # # @example A minimal example # def subcommands(cmd) # cmd.command :download do |opt| # description 'Downloads a content from a server' # # opt.on :verbose, 'Use verbose output' # # run do |options, arguments| # ContentDownloader.download(options, arguments) # end # end # end # # @example Define the invokation block anywhere you want # def subcommands(cmd) # cmd.command :download do |opt| # description 'Downloads a content from a server' # # opt.on :verbose, 'Use verbose output' # end # end # # def process # # Perform calculations... # opts.fetch_command(:download).run do |options, arguments| # ContentDownloader.download(options, arguments) # end # # More calculations... # end def subcommands(cmd); end # A method to setup Pry::Slop so it can parse the options your command expects. # # @note Please don't do anything side-effecty in the main part of this # method, as it may be called by Pry at any time for introspection reasons. # If you need to set up default values, use `setup` instead. # # @example # def options(opt) # opt.banner "Gists methods or classes" # opt.on(:c, :class, "gist a class") do # @action = :class # end # end def options(opt); end # The actual body of your command should go here. # # The `opts` mehod can be called to get the options that Pry::Slop has passed, # and `args` gives the remaining, unparsed arguments. # # The return value of this method is discarded unless the command was # created with `:keep_retval => true`, in which case it is returned to the # repl. # # @example # def process # if opts.present?(:class) # gist_class # else # gist_method # end # end def process raise CommandError, "command '#{command_name}' not implemented" end end end