Class: Climate::Command

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

Overview

require this file to monkey patch Command to have old <= 0.4 Command.name method that was removed to fix https://github.com/playlouder/climate/issues/6

Class Attribute Summary collapse

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from ParsingMethods

arg, cli_arguments, cli_options, conflicting_options, conflicts, dependent_options, depends, has_argument?, has_arguments?, has_multi_argument?, has_options?, has_required_argument?, opt, parse, parse_arguments, stop_on, trollop_parser

Constructor Details

#initialize(argv, 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



156
157
158
159
160
161
162
163
164
165
166
167
# File 'lib/climate/command.rb', line 156

def initialize(argv, options={})
  @argv = argv.clone
  @parent = options[:parent]

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

  if ! self.class.parsing_disabled
    @arguments, @options, @leftovers = self.class.parse(argv)
  end
end

Class Attribute Details

.parentObject

Set the parent of this command



101
102
103
# File 'lib/climate/command.rb', line 101

def parent
  @parent
end

.parsing_disabledObject

Returns true if parsing is disabled



98
99
100
# File 'lib/climate/command.rb', line 98

def parsing_disabled
  @parsing_disabled
end

Instance Attribute Details

#argumentsHash

Arguments that were given on the command line

Returns:

  • (Hash)


180
181
182
# File 'lib/climate/command.rb', line 180

def arguments
  @arguments
end

#argvArray

The original list of unparsed argv style arguments that were given to the command

Returns:

  • (Array)


172
173
174
# File 'lib/climate/command.rb', line 172

def argv
  @argv
end

#leftoversArray

Unparsed arguments, usually for subcommands

Returns:

  • (Array)


184
185
186
# File 'lib/climate/command.rb', line 184

def leftovers
  @leftovers
end

#optionsHash

Options that were parsed from the command line

Returns:

  • (Hash)


176
177
178
# File 'lib/climate/command.rb', line 176

def options
  @options
end

#parentCommand

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

Returns:



188
189
190
# File 'lib/climate/command.rb', line 188

def parent
  @parent
end

#stderrIO

a possibly redirected stream

Returns:

  • (IO)


192
193
194
# File 'lib/climate/command.rb', line 192

def stderr
  @stderr
end

#stdinIO

a possibly redirected stream

Returns:

  • (IO)


192
193
194
# File 'lib/climate/command.rb', line 192

def stdin
  @stdin
end

#stdoutIO

a possibly redirected stream

Returns:

  • (IO)


192
193
194
# File 'lib/climate/command.rb', line 192

def stdout
  @stdout
end

Class Method Details

.add_subcommand(subcommand) ⇒ Object



103
104
105
106
107
108
109
110
111
# File 'lib/climate/command.rb', line 103

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

.ancestors(exclude_self = false) ⇒ Object



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

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

.arg(*args) ⇒ Object



117
118
119
120
121
122
123
# File 'lib/climate/command.rb', line 117

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

.class_nameObject

because we've extended Class.name, we expose the original method under another name. Can be removed once we move away from Command.name method FIXME: surely there is a saner way of doing this?



14
15
16
# File 'lib/climate/command_compat.rb', line 14

def self.class_name
  Class.method(:name).unbind.bind(self).call
end

.command_nameObject

Return the name of the command



66
67
68
# File 'lib/climate/command.rb', line 66

def command_name
  @name
end

.description(string = nil) ⇒ Object

Set the description for this command

Parameters:

  • string (String) (defaults to: nil)

    Description/Banner/Help text



83
84
85
86
87
88
89
# File 'lib/climate/command.rb', line 83

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

.disable_parsingObject

Call this during class definition time if you don't want any of the usual command line parsing to happen



93
94
95
# File 'lib/climate/command.rb', line 93

def disable_parsing
  @parsing_disabled = true
end

.has_subcommand?(subcommand) ⇒ Boolean

Returns:

  • (Boolean)


113
114
115
# File 'lib/climate/command.rb', line 113

def has_subcommand?(subcommand)
  subcommands.include?(subcommand)
end

.has_subcommands?Boolean

Returns:

  • (Boolean)


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

def has_subcommands? ; not subcommands.empty?   ; end

.name(name = nil) ⇒ Object



5
6
7
8
# File 'lib/climate/command_compat.rb', line 5

def self.name(name=nil)
  set_name(name) if name
  command_name
end

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

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

Parameters:

  • argv (Array<String>)

    A list of arguments, ARGV style

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


34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
# File 'lib/climate/command.rb', line 34

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

  if subcommands.empty?
    begin
      instance.run
    rescue Climate::CommandError => e
      # make it easier on users
      e.command_class = self if e.command_class.nil?
      raise
    end
  else
    find_and_run_subcommand(instance, options)
  end
end

.set_name(command_name) ⇒ Object

Set the name of this command, use if you don't want to use the class function to define your command



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

def set_name(command_name)
  @name = command_name
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:



72
73
74
75
# File 'lib/climate/command.rb', line 72

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

.subcommand_of?(parent_class) ⇒ Boolean

Returns:

  • (Boolean)


77
78
79
# File 'lib/climate/command.rb', line 77

def subcommand_of?(parent_class)
  parent_class.has_subcommand?(self)
end

.subcommandsObject



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

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

Instance Method Details

#ancestor(ancestor_class, include_self = true) ⇒ Object



194
195
196
197
198
199
200
201
202
203
# File 'lib/climate/command.rb', line 194

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

#exit(status) ⇒ Object



211
212
213
# File 'lib/climate/command.rb', line 211

def exit(status)
  raise Climate::ExitException.new(nil, status)
end

#runObject

Run the command, must be implemented by all commands that are not parent commands (leaf commands)

Raises:

  • (NotImplementedError)


207
208
209
# File 'lib/climate/command.rb', line 207

def run
  raise NotImplementedError, "Leaf commands must implement a run method"
end