Class: Cri::Command

Inherits:
Object
  • Object
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)

Class Method Summary (collapse)

Instance Method Summary (collapse)

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:



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:



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:



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:



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:



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:

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:



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:



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:



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:



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