# class Gem::Command

Base class for all `Gem` commands. When creating a new gem command, define initialize, `execute`, `arguments`, `defaults_str`, `description` and `usage` (as appropriate). See the above mentioned methods for details.

A very good example to look at is `Gem::Commands::ContentsCommand`

### Attributes

command[R]

The name of the command.

defaults[RW]

The default options for the command.

options[R]

The options for the command.

program_name[RW]

The name of the command for command-line invocation.

summary[RW]

A short description of the command.

### Public Class Methods

add_common_option(*args, &handler) click to toggle source

    # File lib/rubygems/command.rb, line 67
    def self.add_common_option(*args, &handler)
      Gem::Command.common_options << [args, handler]
    end

add_specific_extra_args(cmd,args) click to toggle source

Add a list of extra arguments for the given command. `args` may be an array or a string to be split on white space.

    # File lib/rubygems/command.rb, line 96
    def self.add_specific_extra_args(cmd,args)
      args = args.split(/\s+/) if args.kind_of? String
      specific_extra_args_hash[cmd] = args
    end

build_args() click to toggle source

Arguments used when building gems

    # File lib/rubygems/command.rb, line 55
    def self.build_args
      @build_args ||= []
    end

build_args=(value) click to toggle source

    # File lib/rubygems/command.rb, line 59
    def self.build_args=(value)
      @build_args = value
    end

common_options() click to toggle source

    # File lib/rubygems/command.rb, line 63
    def self.common_options
      @common_options ||= []
    end

extra_args() click to toggle source

    # File lib/rubygems/command.rb, line 71
    def self.extra_args
      @extra_args ||= []
    end

extra_args=(value) click to toggle source

    # File lib/rubygems/command.rb, line 75
    def self.extra_args=(value)
      case value
      when Array
        @extra_args = value
      when String
        @extra_args = value.split(" ")
      end
    end

new(command, summary=nil, defaults={}) click to toggle source

Initializes a generic gem command named `command`. `summary` is a short description displayed in ‘gem help commands`. `defaults` are the default options. Defaults should be mirrored in `defaults_str`, unless there are none.

When defining a new command subclass, use `add_option` to add command-line switches.

Unhandled arguments (gem names, files, etc.) are left in `options[:args]`.

    # File lib/rubygems/command.rb, line 122
    def initialize(command, summary=nil, defaults={})
      @command = command
      @summary = summary
      @program_name = "gem #{command}"
      @defaults = defaults
      @options = defaults.dup
      @option_groups = Hash.new {|h,k| h[k] = [] }
      @deprecated_options = { command => {} }
      @parser = nil
      @when_invoked = nil
    end

specific_extra_args(cmd) click to toggle source

Return an array of extra arguments for the command. The extra arguments come from the gem configuration file read at program startup.

    # File lib/rubygems/command.rb, line 88
    def self.specific_extra_args(cmd)
      specific_extra_args_hash[cmd]
    end

specific_extra_args_hash() click to toggle source

Accessor for the specific extra args hash (self initializing).

    # File lib/rubygems/command.rb, line 104
    def self.specific_extra_args_hash
      @specific_extra_args_hash ||= Hash.new do |h,k|
        h[k] = Array.new
      end
    end

### Public Instance Methods

add_extra_args(args) click to toggle source

Adds extra args from ~/.gemrc

    # File lib/rubygems/command.rb, line 456
    def add_extra_args(args)
      result = []

      s_extra = Gem::Command.specific_extra_args(@command)
      extra = Gem::Command.extra_args + s_extra

      until extra.empty? do
        ex = []
        ex << extra.shift
        ex << extra.shift if extra.first.to_s =~ /^[^-]/ # rubocop:disable Performance/StartWith
        result << ex if handles?(ex)
      end

      result.flatten!
      result.concat(args)
      result
    end

add_option(*opts) { |value, options| ... } click to toggle source

Add a command-line option and handler to the command.

See Gem::OptionParser#make_switch for an explanation of `opts`.

`handler` will be called with two values, the value of the argument and the options hash.

If the first argument of `add_option` is a `Symbol`, it’s used to group options in output. See ‘gem help list` for an example.

    # File lib/rubygems/command.rb, line 360
    def add_option(*opts, &handler) # :yields: value, options
      group_name = Symbol === opts.first ? opts.shift : :options

      raise "Do not pass an empty string in opts" if opts.include?("")

      @option_groups[group_name] << [opts, handler]
    end

arguments() click to toggle source

Override to provide details of the arguments a command takes. It should return a left-justified string, one argument per line.

For example:

    def usage
      "#{program_name} FILE [FILE ...]"
    end

    def arguments
      "FILE          name of file to find"
    end

    # File lib/rubygems/command.rb, line 260
    def arguments
      ""
    end

begins?(long, short) click to toggle source

True if `long` begins with the characters from `short`.

    # File lib/rubygems/command.rb, line 137
    def begins?(long, short)
      return false if short.nil?
      long[0, short.length] == short
    end

check_deprecated_options(options) click to toggle source

    # File lib/rubygems/command.rb, line 399
    def check_deprecated_options(options)
      options.each do |option|
        if option_is_deprecated?(option)
          deprecation = @deprecated_options[command][option]
          version_to_expire = deprecation["rg_version_to_expire"]

          deprecate_option_msg = if version_to_expire
            "The \"#{option}\" option has been deprecated and will be removed in Rubygems #{version_to_expire}."
          else
            "The \"#{option}\" option has been deprecated and will be removed in future versions of Rubygems."
          end

          extra_msg = deprecation["extra_msg"]

          deprecate_option_msg += " #{extra_msg}" if extra_msg

          alert_warning(deprecate_option_msg)
        end
      end
    end

defaults_str() click to toggle source

Override to display the default values of the command options. (similar to `arguments`, but displays the default values).

For example:

    def defaults_str
      --no-gems-first --no-all
    end

    # File lib/rubygems/command.rb, line 274
    def defaults_str
      ""
    end

deprecate_option(name, version: nil, extra_msg: nil) click to toggle source

Mark a command-line option as deprecated, and optionally specify a deprecation horizon.

Note that with the current implementation, every version of the option needs to be explicitly deprecated, so to deprecate an option defined as

    add_option('-t', '--[no-]test', 'Set test mode') do |value, options|
      # ... stuff ...
    end

you would need to explicitly add a call to ‘deprecate_option` for every version of the option you want to deprecate, like

    deprecate_option('-t')
    deprecate_option('--test')
    deprecate_option('--no-test')

    # File lib/rubygems/command.rb, line 395
    def deprecate_option(name, version: nil, extra_msg: nil)
      @deprecated_options[command].merge!({ name => { "rg_version_to_expire" => version, "extra_msg" => extra_msg } })
    end

deprecated?() click to toggle source

    # File lib/rubygems/command.rb, line 474
    def deprecated?
      false
    end

description() click to toggle source

Override to display a longer description of what this command does.

    # File lib/rubygems/command.rb, line 281
    def description
      nil
    end

execute() click to toggle source

Override to provide command handling.

`options` will be filled in with your parsed options, unparsed options will be left in `options[:args]`.

See also: `get_all_gem_names`, `get_one_gem_name`, `get_one_optional_argument`

    # File lib/rubygems/command.rb, line 151
    def execute
      raise Gem::Exception, "generic command has no actions"
    end

get_all_gem_names() click to toggle source

Get all gem names from the command line.

    # File lib/rubygems/command.rb, line 187
    def get_all_gem_names
      args = options[:args]

      if args.nil? || args.empty?
        raise Gem::CommandLineError,
              "Please specify at least one gem name (e.g. gem build GEMNAME)"
      end

      args.select {|arg| arg !~ /^-/ }
    end

get_all_gem_names_and_versions() click to toggle source

Get all [gem, version] from the command line.

An argument in the form gem:ver is pull apart into the gen name and version, respectively.

    # File lib/rubygems/command.rb, line 203
    def get_all_gem_names_and_versions
      get_all_gem_names.map do |name|
        extract_gem_name_and_version(name)
      end
    end

get_one_gem_name() click to toggle source

Get a single gem name from the command line. Fail if there is no gem name or if there is more than one gem name given.

    # File lib/rubygems/command.rb, line 221
    def get_one_gem_name
      args = options[:args]

      if args.nil? || args.empty?
        raise Gem::CommandLineError,
              "Please specify a gem name on the command line (e.g. gem build GEMNAME)"
      end

      if args.size > 1
        raise Gem::CommandLineError,
              "Too many gem names (#{args.join(', ')}); please specify only one"
      end

      args.first
    end

get_one_optional_argument() click to toggle source

Get a single optional argument from the command line. If more than one argument is given, return only the first. Return nil if none are given.

    # File lib/rubygems/command.rb, line 241
    def get_one_optional_argument
      args = options[:args] || []
      args.first
    end

handle_options(args) click to toggle source

Handle the given list of arguments by parsing them and recording the results.

    # File lib/rubygems/command.rb, line 445
    def handle_options(args)
      args = add_extra_args(args)
      check_deprecated_options(args)
      @options = Marshal.load Marshal.dump @defaults # deep copy
      parser.parse!(args)
      @options[:args] = args
    end

handles?(args) click to toggle source

True if the command handles the given argument list.

    # File lib/rubygems/command.rb, line 432
    def handles?(args)
      begin
        parser.parse!(args.dup)
        return true
      rescue
        return false
      end
    end

invoke(*args) click to toggle source

Invoke the command with the given list of arguments.

    # File lib/rubygems/command.rb, line 305
    def invoke(*args)
      invoke_with_build_args args, nil
    end

invoke_with_build_args(args, build_args) click to toggle source

Invoke the command with the given list of normal arguments and additional build arguments.

    # File lib/rubygems/command.rb, line 313
    def invoke_with_build_args(args, build_args)
      handle_options args

      options[:build_args] = build_args

      if options[:silent]
        old_ui = self.ui
        self.ui = ui = Gem::SilentUI.new
      end

      if options[:help]
        show_help
      elsif @when_invoked
        @when_invoked.call options
      else
        execute
      end
    ensure
      if ui
        self.ui = old_ui
        ui.close
      end
    end

merge_options(new_options) click to toggle source

Merge a set of command options with the set of default options (without modifying the default option hash).

    # File lib/rubygems/command.rb, line 424
    def merge_options(new_options)
      @options = @defaults.clone
      new_options.each {|k,v| @options[k] = v }
    end

remove_option(name) click to toggle source

Remove previously defined command-line argument `name`.

    # File lib/rubygems/command.rb, line 371
    def remove_option(name)
      @option_groups.each do |_, option_list|
        option_list.reject! {|args, _| args.any? {|x| x.is_a?(String) && x =~ /^#{name}/ } }
      end
    end

show_help() click to toggle source

Display the help message for the command.

    # File lib/rubygems/command.rb, line 297
    def show_help
      parser.program_name = usage
      say parser
    end

show_lookup_failure(gem_name, version, errors, suppress_suggestions = false, required_by = nil) click to toggle source

Display to the user that a gem couldn’t be found and reasons why

    # File lib/rubygems/command.rb, line 159
    def show_lookup_failure(gem_name, version, errors, suppress_suggestions = false, required_by = nil)
      gem = "'#{gem_name}' (#{version})"
      msg = String.new "Could not find a valid gem #{gem}"

      if errors && !errors.empty?
        msg << ", here is why:\n"
        errors.each {|x| msg << "          #{x.wordy}\n" }
      else
        if required_by && gem != required_by
          msg << " (required by #{required_by}) in any repository"
        else
          msg << " in any repository"
        end
      end

      alert_error msg

      unless suppress_suggestions
        suggestions = Gem::SpecFetcher.fetcher.suggest_gems_from_name(gem_name, :latest, 10)
        unless suggestions.empty?
          alert_error "Possible alternatives: #{suggestions.join(", ")}"
        end
      end
    end

usage() click to toggle source

Override to display the usage for an individual gem command.

The text “[options]” is automatically appended to the usage text.

    # File lib/rubygems/command.rb, line 290
    def usage
      program_name
    end

when_invoked(&block) click to toggle source

Call the given block when invoked.

Normal command invocations just executes the `execute` method of the command. Specifying an invocation block allows the test methods to override the normal action of a command to determine that it has been invoked correctly.

    # File lib/rubygems/command.rb, line 345
    def when_invoked(&block)
      @when_invoked = block
    end

### Private Instance Methods

add_parser_run_info(title, content) click to toggle source

Adds a section with `title` and `content` to the parser help view. Used for adding command arguments and default arguments.

    # File lib/rubygems/command.rb, line 515
    def add_parser_run_info(title, content)
      return if content.empty?

      @parser.separator nil
      @parser.separator "  #{title}:"
      content.split(/\n/).each do |line|
        @parser.separator "    #{line}"
      end
    end

configure_options(header, option_list) click to toggle source

    # File lib/rubygems/command.rb, line 561
    def configure_options(header, option_list)
      return if option_list.nil? || option_list.empty?

      header = header.to_s.empty? ? "" : "#{header} "
      @parser.separator "  #{header}Options:"

      option_list.each do |args, handler|
        @parser.on(*args) do |value|
          handler.call(value, @options)
        end
      end

      @parser.separator ""
    end

create_option_parser() click to toggle source

Creates an option parser and fills it in with the help info for the command.

    # File lib/rubygems/command.rb, line 547
    def create_option_parser
      @parser = Gem::OptionParser.new

      add_parser_options

      @parser.separator nil
      configure_options "Common", Gem::Command.common_options

      add_parser_run_info "Arguments", arguments
      add_parser_summary
      add_parser_description
      add_parser_run_info "Defaults", defaults_str
    end

option_is_deprecated?(option) click to toggle source

    # File lib/rubygems/command.rb, line 480
    def option_is_deprecated?(option)
      @deprecated_options[command].has_key?(option)
    end

parser() click to toggle source

Create on demand parser.

    # File lib/rubygems/command.rb, line 538
    def parser
      create_option_parser if @parser.nil?
      @parser
    end

wrap(text, width) click to toggle source

Wraps `text` to `width`

    # File lib/rubygems/command.rb, line 579
    def wrap(text, width) # :doc:
      text.gsub(/(.{1,#{width}})( +|$\n?)|(.{1,#{width}})/, "\\1\\3\n")
    end