Class: Climate::Command

Inherits:
Object
  • Object
show all
Extended by:
ParsingMethods
Defined in:
lib/climate/command.rb

Overview

A Command is a unit of work, intended to be invoked from the command line. It should be extended to either do something itself by implementing run, or just be there as a conduit for subcommands to do their work.

See ParsingMethods for details on how to specify options and arguments

Class Attribute Summary collapse

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from ParsingMethods

arg, check_arguments, cli_arguments, cli_options, has_arguments?, has_options?, help_banner, opt, parse, stop_on, trollop_parser

Constructor Details

#initialize(arguments, options = {}) ⇒ Command

Create an instance of this command to be run. You’ll probably want to use run

Parameters:

  • arguments (Array<String>)

    ARGV style arguments to be parsed

  • options (Hash) (defaults to: {})

    a customizable set of options

Options Hash (options):

  • :parent (Command)

    The parent command, made available as #parent

  • :stdout (IO)

    stream to use as stdout, defaulting to ‘$stdout`

  • :stderr (IO)

    stream to use as stderr, defaulting to ‘$stderr`

  • :stdin (IO)

    stream to use as stdin, defaulting to ‘$stdin`



113
114
115
116
117
118
119
120
121
# File 'lib/climate/command.rb', line 113

def initialize(arguments, options={})
  @parent = options[:parent]

  @stdout = options[:stdout] || $stdout
  @stderr = options[:stderr] || $stderr
  @stdin =  options[:stdin]  || $stdin

  @arguments, @options, @leftovers = self.class.parse(arguments)
end

Class Attribute Details

.parentObject

Set the parent of this command



62
63
64
# File 'lib/climate/command.rb', line 62

def parent
  @parent
end

Instance Attribute Details

#argumentsHash

Arguments that were given on the command line

Returns:

  • (Hash)


129
130
131
# File 'lib/climate/command.rb', line 129

def arguments
  @arguments
end

#leftoversArray

Unparsed arguments, usually for subcommands

Returns:

  • (Array)


133
134
135
# File 'lib/climate/command.rb', line 133

def leftovers
  @leftovers
end

#optionsHash

Options that were parsed from the command line

Returns:

  • (Hash)


125
126
127
# File 'lib/climate/command.rb', line 125

def options
  @options
end

#parentCommand

The parent command, or nil if this is not a subcommand

Returns:



137
138
139
# File 'lib/climate/command.rb', line 137

def parent
  @parent
end

#stderrIO

a possibly redirected stream

Returns:

  • (IO)


141
142
143
# File 'lib/climate/command.rb', line 141

def stderr
  @stderr
end

#stdinIO

a possibly redirected stream

Returns:

  • (IO)


141
142
143
# File 'lib/climate/command.rb', line 141

def stdin
  @stdin
end

#stdoutIO

a possibly redirected stream

Returns:

  • (IO)


141
142
143
# File 'lib/climate/command.rb', line 141

def stdout
  @stdout
end

Class Method Details

.add_subcommand(subcommand) ⇒ Object



64
65
66
67
68
69
70
71
72
# File 'lib/climate/command.rb', line 64

def add_subcommand(subcommand)
  if cli_arguments.empty?
    subcommands << subcommand
    subcommand.parent = self
    stop_on(subcommands.map(&:name))
  else
    raise DefinitionError, 'can not mix subcommands with arguments'
  end
end

.ancestors(exclude_self = false) ⇒ Object



33
34
35
36
# File 'lib/climate/command.rb', line 33

def ancestors(exclude_self=false)
  our_list = exclude_self ? [] : [self]
  parent.nil?? our_list : parent.ancestors + our_list
end

.arg(*args) ⇒ Object



74
75
76
77
78
79
80
# File 'lib/climate/command.rb', line 74

def arg(*args)
  if subcommands.empty?
    super(*args)
  else
    raise DefinitionError, 'can not mix subcommands with arguments'
  end
end

.description(string = nil) ⇒ Object

Set the description for this command

Parameters:

  • string (String) (defaults to: nil)

    Description/Banner/Help text



53
54
55
56
57
58
59
# File 'lib/climate/command.rb', line 53

def description(string=nil)
  if string
    @description = string
  else
    @description
  end
end

.has_subcommands?Boolean

Returns:

  • (Boolean)


82
# File 'lib/climate/command.rb', line 82

def has_subcommands? ; not subcommands.empty?   ; end

.name(name = nil) ⇒ Object

Supply a name for this command, or return the existing name



39
40
41
42
# File 'lib/climate/command.rb', line 39

def name(name=nil)
  @name = name if name
  @name
end

.run(arguments, options = {}) ⇒ Object

Create an instance of this command class and run it against the given arguments

Parameters:

  • arguments (Array<String>)

    A list of arguments, ARGV style

  • options (Hash) (defaults to: {})


19
20
21
22
23
24
25
26
27
28
29
30
31
# File 'lib/climate/command.rb', line 19

def run(arguments, options={})
  begin
    instance = new(arguments, options)
  rescue Trollop::HelpNeeded
    raise HelpNeeded.new(self)
  end

  if subcommands.empty?
    instance.run
  else
    find_and_run_subcommand(instance, options)
  end
end

.subcommand_of(parent_class) ⇒ Object

Register this class as being a subcommand of another Climate::Command class

Parameters:

  • parent_class (Command)

    The parent we hang off of

Raises:



46
47
48
49
# File 'lib/climate/command.rb', line 46

def subcommand_of(parent_class)
  raise DefinitionError, 'can not set subcommand before name' unless @name
  parent_class.add_subcommand(self)
end

.subcommandsObject



83
# File 'lib/climate/command.rb', line 83

def subcommands ; @subcommands ||= [] ; end

Instance Method Details

#ancestor(ancestor_class, include_self = true) ⇒ Object



143
144
145
146
147
148
149
150
151
152
# File 'lib/climate/command.rb', line 143

def ancestor(ancestor_class, include_self=true)
  if include_self && self.class == ancestor_class
    self
  elsif parent.nil?
    raise "no ancestor exists: #{ancestor_class}"
    nil
  else
    parent.ancestor(ancestor_class)
  end
end