Class List Method List File List

# Class: Cri::Command

Inherits:
  Object
  - Object
  - Cri::Command
  show all
Defined in:
  lib/cri/command.rb

## Overview

Cri::Command represents a command that can be executed on the commandline. It is also used for the commandline tool itself.

## Defined Under Namespace

Classes: OptionParserPartitioningDelegate

## Instance Attribute Summary (collapse)

- - (Array<String>) aliases

  A list of aliases for this command that can be used to invoke this command.

- - (Proc) block

  The block that should be executed when invoking this command (ignored for commands with subcommands).

- - (Set<Cri::Command>) commands (also: #subcommands)

  This command’s subcommands.

- - (String) description

  The long description (“description”).

- - (Boolean) hidden (also: #hidden?)

  True if the command is hidden (e.g. because it is deprecated), false otherwise.

- - (String) name

  The name.

- - (Array<Hash>) option_definitions

  The list of option definitions.

- - (String) summary

  The short description (“summary”).

- - (Cri::Command?) supercommand

  This command’s supercommand, or nil if the command has no supercommand.

- - (String) usage

  The usage, without the “usage:” prefix and without the supercommands’ names.

## Class Method Summary (collapse)

- + (Cri::Command) define(string = nil, filename = nil, &block)

  Creates a new command using the DSL.

- + (Cri::Command) new_basic_help

  Returns a new command that implements showing help.

- + (Cri::Command) new_basic_root

  Returns a new command that has support for the `-h`/`--help` option and also has a `help` subcommand.

## Instance Method Summary (collapse)

- - (-1, ...) <=>(other)

  Compares this command's name to the other given command's name.

- - (void) add_command(command)

  Adds the given command as a subcommand to the current command.

- - (Cri::Command) command_named(name)

  Returns the command with the given name.

- - (Array<Cri::Command>) commands_named(name)

  Returns the commands that could be referred to with the given name.

- - (Cri::Command) define_command(name = nil, &block)

  Defines a new subcommand for the current command using the DSL.

- - (Hash) global_option_definitions

  The option definitions for the command itself and all its ancestors.

- - (String) help(params = {})

  The help text for this command.

- - (Command) initialize constructor

  A new instance of Command.

- - (Cri::Command) modify(&block)

  Modifies the command using the DSL.

- - (void) run(opts_and_args, parent_opts = {})

  Runs the command with the given commandline arguments, possibly invoking subcommands and passing on the options and arguments.

- - (void) run_this(opts_and_args, parent_opts = {})

  Runs the actual command with the given commandline arguments, not invoking any subcommands.

## Constructor Details

### - (`Command`) initialize

Returns a new instance of Command

    125
    126
    127
    128
    129

    # File 'lib/cri/command.rb', line 125

    def initialize
      @aliases            = Set.new
      @commands           = Set.new
      @option_definitions = Set.new
    end

## Instance Attribute Details

### - (`Array<String>`) aliases

Returns A list of aliases for this command that can be used to invoke this command

Returns:

- (`Array<String>`) —

  A list of aliases for this command that can be used to invoke this command

    57
    58
    59

    # File 'lib/cri/command.rb', line 57

    def aliases
      @aliases
    end

### - (`Proc`) block

Returns The block that should be executed when invoking this command (ignored for commands with subcommands)

Returns:

- (`Proc`) —

  The block that should be executed when invoking this command (ignored for commands with subcommands)

    79
    80
    81

    # File 'lib/cri/command.rb', line 79

    def block
      @block
    end

### - (`Set<Cri::Command>`) commands Also known as: subcommands

Returns This command’s subcommands

Returns:

- (`Set<Cri::Command>`) —

  This command’s subcommands

    49
    50
    51

    # File 'lib/cri/command.rb', line 49

    def commands
      @commands
    end

### - (`String`) description

Returns The long description (“description”)

Returns:

- (`String`) —

  The long description (“description”)

    63
    64
    65

    # File 'lib/cri/command.rb', line 63

    def description
      @description
    end

### - (`Boolean`) hidden Also known as: hidden?

Returns true if the command is hidden (e.g. because it is deprecated), false otherwise

Returns:

- (`Boolean`) —

  true if the command is hidden (e.g. because it is deprecated), false otherwise

    71
    72
    73

    # File 'lib/cri/command.rb', line 71

    def hidden
      @hidden
    end

### - (`String`) name

Returns The name

Returns:

- (`String`) —

  The name

    53
    54
    55

    # File 'lib/cri/command.rb', line 53

    def name
      @name
    end

### - (`Array<Hash>`) option_definitions

Returns The list of option definitions

Returns:

- (`Array<Hash>`) —

  The list of option definitions

    75
    76
    77

    # File 'lib/cri/command.rb', line 75

    def option_definitions
      @option_definitions
    end

### - (`String`) summary

Returns The short description (“summary”)

Returns:

- (`String`) —

  The short description (“summary”)

    60
    61
    62

    # File 'lib/cri/command.rb', line 60

    def summary
      @summary
    end

### - (`Cri::Command`?) supercommand

Returns This command’s supercommand, or nil if the command has no supercommand

Returns:

- (`Cri::Command`, `nil`) —

  This command’s supercommand, or nil if the command has no supercommand

    46
    47
    48

    # File 'lib/cri/command.rb', line 46

    def supercommand
      @supercommand
    end

### - (`String`) usage

Returns The usage, without the “usage:” prefix and without the supercommands’ names.

Returns:

- (`String`) —

  The usage, without the “usage:” prefix and without the supercommands’ names.

    67
    68
    69

    # File 'lib/cri/command.rb', line 67

    def usage
      @usage
    end

## Class Method Details

### + (`Cri::Command`) define(string = nil, filename = nil, &block)

Creates a new command using the DSL. If a string is given, the command will be defined using the string; if a block is given, the block will be used instead.

If the block has one parameter, the block will be executed in the same context with the command DSL as its parameter. If the block has no parameters, the block will be executed in the context of the DSL.

Parameters:

- string (`String`, `nil`) (defaults to: `nil`) —

  The command definition as a string

- filename (`String`, `nil`) (defaults to: `nil`) —

  The filename corresponding to the string parameter (only useful if a string is given)

Returns:

- (`Cri::Command`) —

  The newly defined command

    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105

    # File 'lib/cri/command.rb', line 94

    def self.define(string = nil, filename = nil, &block)
      dsl = Cri::CommandDSL.new
      if string
        args = filename ? [string, filename] : [string]
        dsl.instance_eval(*args)
      elsif [-1, 0].include? block.arity
        dsl.instance_eval(&block)
      else
        block.call(dsl)
      end
      dsl.command
    end

### + (`Cri::Command`) new_basic_help

Returns a new command that implements showing help.

Returns:

- (`Cri::Command`) —

  A basic help command

    120
    121
    122
    123

    # File 'lib/cri/command.rb', line 120

    def self.new_basic_help
      filename = File.dirname(__FILE__) + '/commands/basic_help.rb'
      define(File.read(filename))
    end

### + (`Cri::Command`) new_basic_root

Returns a new command that has support for the `-h`/`--help` option and also has a `help` subcommand. It is intended to be modified (adding name, summary, description, other subcommands, …)

Returns:

- (`Cri::Command`) —

  A basic root command

    112
    113
    114
    115

    # File 'lib/cri/command.rb', line 112

    def self.new_basic_root
      filename = File.dirname(__FILE__) + '/commands/basic_root.rb'
      define(File.read(filename))
    end

## Instance Method Details

### - (`-1`, ...) <=>(other)

Compares this command's name to the other given command's name.

Parameters:

- other (`Cri::Command`) —

  The command to compare with

Returns:

- (`-1`, `0`, `1`) —

  The result of the comparison between names

See Also:

- Object<=>

    315
    316
    317

    # File 'lib/cri/command.rb', line 315

    def <=>(other)
      name <=> other.name
    end

### - (`void`) add_command(command)

This method returns an undefined value.

Adds the given command as a subcommand to the current command.

Parameters:

- command (`Cri::Command`) —

  The command to add as a subcommand

    162
    163
    164
    165

    # File 'lib/cri/command.rb', line 162

    def add_command(command)
      @commands << command
      command.supercommand = self
    end

### - (`Cri::Command`) command_named(name)

Returns the command with the given name. This method will display error messages and exit in case of an error (unknown or ambiguous command).

The name can be a full command name, a partial command name (e.g. “com” for “commit”) or an aliased command name (e.g. “ci” for “commit”).

Parameters:

- name (`String`) —

  The full, partial or aliases name of the command

Returns:

- (`Cri::Command`) —

  The command with the given name

    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230

    # File 'lib/cri/command.rb', line 217

    def command_named(name)
      commands = commands_named(name)

      if commands.size < 1
        $stderr.puts "#{self.name}: unknown command '#{name}'\n"
        exit 1
      elsif commands.size > 1
        $stderr.puts "#{self.name}: '#{name}' is ambiguous:"
        $stderr.puts "  #{commands.map { |c| c.name }.sort.join(' ') }"
        exit 1
      else
        commands[0]
      end
    end

### - (`Array<Cri::Command>`) commands_named(name)

Returns the commands that could be referred to with the given name. If the result contains more than one command, the name is ambiguous.

Parameters:

- name (`String`) —

  The full, partial or aliases name of the command

Returns:

- (`Array<Cri::Command>`) —

  A list of commands matching the given name

    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206

    # File 'lib/cri/command.rb', line 195

    def commands_named(name)
      # Find by exact name or alias
      @commands.each do |cmd|
        found = cmd.name == name || cmd.aliases.include?(name)
        return [cmd] if found
      end

      # Find by approximation
      @commands.select do |cmd|
        cmd.name[0, name.length] == name
      end
    end

### - (`Cri::Command`) define_command(name = nil, &block)

Defines a new subcommand for the current command using the DSL.

Parameters:

- name (`String`, `nil`) (defaults to: `nil`) —

  The name of the subcommand, or nil if no name should be set (yet)

Returns:

- (`Cri::Command`) —

  The subcommand

    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187

    # File 'lib/cri/command.rb', line 173

    def define_command(name = nil, &block)
      # Execute DSL
      dsl = Cri::CommandDSL.new
      dsl.name name unless name.nil?
      if [-1, 0].include? block.arity
        dsl.instance_eval(&block)
      else
        block.call(dsl)
      end

      # Create command
      cmd = dsl.command
      add_command(cmd)
      cmd
    end

### - (`Hash`) global_option_definitions

Returns The option definitions for the command itself and all its ancestors

Returns:

- (`Hash`) —

  The option definitions for the command itself and all its ancestors

    150
    151
    152
    153
    154
    155

    # File 'lib/cri/command.rb', line 150

    def global_option_definitions
      res = Set.new
      res.merge(option_definitions)
      res.merge(supercommand.global_option_definitions) if supercommand
      res
    end

### - (`String`) help(params = {})

Returns The help text for this command

Parameters:

- params (`Hash`) (defaults to: `{}`) —

  a customizable set of options

Options Hash (`params`):

- :verbose (`Boolean`) —

  true if the help output should be verbose, false otherwise.

- :io (`IO`) — default: `$stdout` —

  the IO the help text is intended for. This influences the decision to enable/disable colored output.

Returns:

- (`String`) —

  The help text for this command

    304
    305
    306

    # File 'lib/cri/command.rb', line 304

    def help(params = {})
      HelpRenderer.new(self, params).render
    end

### - (`Cri::Command`) modify(&block)

Modifies the command using the DSL.

If the block has one parameter, the block will be executed in the same context with the command DSL as its parameter. If the block has no parameters, the block will be executed in the context of the DSL.

Returns:

- (`Cri::Command`) —

  The command itself

    138
    139
    140
    141
    142
    143
    144
    145
    146

    # File 'lib/cri/command.rb', line 138

    def modify(&block)
      dsl = Cri::CommandDSL.new(self)
      if [-1, 0].include? block.arity
        dsl.instance_eval(&block)
      else
        block.call(dsl)
      end
      self
    end

### - (`void`) run(opts_and_args, parent_opts = {})

This method returns an undefined value.

Runs the command with the given commandline arguments, possibly invoking subcommands and passing on the options and arguments.

Parameters:

- opts_and_args (`Array<String>`) —

  A list of unparsed arguments

- parent_opts (`Hash`) (defaults to: `{}`) —

  A hash of options already handled by the supercommand

    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262

    # File 'lib/cri/command.rb', line 241

    def run(opts_and_args, parent_opts = {})
      # Parse up to command name
      stuff = partition(opts_and_args)
      opts_before_subcmd, subcmd_name, opts_and_args_after_subcmd = *stuff

      if subcommands.empty? || (subcmd_name.nil? && !block.nil?)
        run_this(opts_and_args, parent_opts)
      else
        # Handle options
        handle_options(opts_before_subcmd)

        # Get command
        if subcmd_name.nil?
          $stderr.puts "#{name}: no command given"
          exit 1
        end
        subcommand = command_named(subcmd_name)

        # Run
        subcommand.run(opts_and_args_after_subcmd, opts_before_subcmd)
      end
    end

### - (`void`) run_this(opts_and_args, parent_opts = {})

This method returns an undefined value.

Runs the actual command with the given commandline arguments, not invoking any subcommands. If the command does not have an execution block, an error ir raised.

Parameters:

- opts_and_args (`Array<String>`) —

  A list of unparsed arguments

- parent_opts (`Hash`) (defaults to: `{}`) —

  A hash of options already handled by the supercommand

Raises:

- (`NotImplementedError`) —

  if the command does not have an execution block

    277
    278
    279
    280
    281
    282
    283
    284
    285
    286
    287
    288
    289
    290
    291
    292
    293
    294
    295

    # File 'lib/cri/command.rb', line 277

    def run_this(opts_and_args, parent_opts = {})
      # Parse
      parser = Cri::OptionParser.new(
        opts_and_args, global_option_definitions)
      handle_parser_errors_while { parser.run }
      local_opts  = parser.options
      global_opts = parent_opts.merge(parser.options)
      args = parser.arguments

      # Handle options
      handle_options(local_opts)

      # Execute
      if block.nil?
        fail NotImplementedError,
             "No implementation available for '#{name}'"
      end
      block.call(global_opts, args, self)
    end