Class: CTioga2::Commands::Command

Inherits:
Object
  • Object
show all
Defined in:
lib/ctioga2/commands/commands.rb

Overview

One of the commands that can be used.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(n, short, long, args = [], opts = {}, d_short = nil, d_long = nil, group = nil, register = true, &code) ⇒ Command

Creates a Command, with all attributes set up. The code can be set using #set_code.

Single and double dashes are stripped from the beginning of the short and long options respectively.



91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
# File 'lib/ctioga2/commands/commands.rb', line 91

def initialize(n, short, long, args = [], opts = {}, 
               d_short = nil, d_long = nil, group = nil,
               register = true, &code)
  @name = n
  @short_option = short && short.gsub(/^-/,'')
  @long_option = long && long.gsub(/^--/,'')
  @arguments = args
  @optional_arguments = opts
  if(@short_option and ! @long_option)
    raise "A long option must always be present if a short one is"
  end
  @code = code
  self.describe(d_short, d_long, group)

  caller[1].gsub(/.*\/ctioga2\//, 'lib/ctioga2/') =~ /(.*):(\d+)/
  @context = [$1, $2.to_i]

  # Registers automatically the command
  if register
    Commands::Interpreter.register_command(self)
  end

end

Instance Attribute Details

#argumentsObject

The compulsory arguments it can take, in the form of an array of CommandArgument



49
50
51
# File 'lib/ctioga2/commands/commands.rb', line 49

def arguments
  @arguments
end

#codeObject

The code that will be called. It must be a Proc object, or any objects that answers a #call method.

The corresponding block will be called with the following arguments:

  • first, the PlotMaker instance where the command will be running

  • second, as many arguments as there are #arguments.

  • third, if #optional_arguments is non-empty, a hash containing the values of the optional arguments. It will be an empty hash if no optional arguments are given in the command). It will be empty if the command is called as an option in the command-line.

Few rules for writing the code:

  • code should avoid as much as possible to rely on closures.

  • the CommandArgument framework will make sure the arguments are given with the appropriate type or raise an exception. Don’t bother.



78
79
80
# File 'lib/ctioga2/commands/commands.rb', line 78

def code
  @code
end

#contextObject

The context of definition [file, line]



84
85
86
# File 'lib/ctioga2/commands/commands.rb', line 84

def context
  @context
end

#groupObject

The CommandGroup to which the command belongs



81
82
83
# File 'lib/ctioga2/commands/commands.rb', line 81

def group
  @group
end

#long_descriptionObject

A longer description. Typically input using a here-document.



59
60
61
# File 'lib/ctioga2/commands/commands.rb', line 59

def long_description
  @long_description
end

#long_optionObject

Its long command-line option, or nil if it should not be called from the command-line (but you really don’t want that).



45
46
47
# File 'lib/ctioga2/commands/commands.rb', line 45

def long_option
  @long_option
end

#nameObject

The name of the command, ie how to call it in a commands file



38
39
40
# File 'lib/ctioga2/commands/commands.rb', line 38

def name
  @name
end

#optional_argumentsObject

Optional arguments to a command, in the form of a Hash ‘option name’ => CommandArgument



53
54
55
# File 'lib/ctioga2/commands/commands.rb', line 53

def optional_arguments
  @optional_arguments
end

#short_descriptionObject

A short one-line description of the command



56
57
58
# File 'lib/ctioga2/commands/commands.rb', line 56

def short_description
  @short_description
end

#short_optionObject

Its short command-line option, or nil if none



41
42
43
# File 'lib/ctioga2/commands/commands.rb', line 41

def short_option
  @short_option
end

Instance Method Details

#argument_numberObject

Returns the number of compulsory arguments



121
122
123
# File 'lib/ctioga2/commands/commands.rb', line 121

def argument_number
  return @arguments.size
end

#convert_arguments(args) ⇒ Object

Converts the Array of String given into an Array of the type suitable for the #code of the Command. This deals only with compulsory arguments. Returns the array.

Any object which is not a String is left as is (useful for instance for the OptionParser with boolean options)

As a special case, if the command takes no arguments and the arguments is [true], no exception is raised, and the correct number of arguments is returned.



179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
# File 'lib/ctioga2/commands/commands.rb', line 179

def convert_arguments(args)
  if args.size != @arguments.size
    if(@arguments.size == 0 && args.size == 1 && args[0] == true)
      return []
    else
      raise ArgumentNumberMismatch, "Command #{@name} was called with #{args.size} arguments, but it takes #{@arguments.size}"
    end
  end
  retval = []
  @arguments.each_index do |i|
    if ! args[i].is_a? String
      retval << args[i]
    else
      retval << @arguments[i].type.string_to_type(args[i])
    end
  end
  return retval
end

#convert_options(options) ⇒ Object

Converts the Hash of String given into a Hash of the type suitable for the #code of the Command. Only optional arguments are taken into account.

Any object which is not a String is left as is (useful for instance for the OptionParser with boolean options)



204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
# File 'lib/ctioga2/commands/commands.rb', line 204

def convert_options(options)
  target_options = {}
  for k,v in options
    if ! @optional_arguments.key? k
      raise CommandOptionUnkown, "Unkown option #{k} for command #{@name}"
    end
    if v.is_a? String
      target_options[k] = @optional_arguments[k].type.
        string_to_type(v)
    else
      target_options[k] = v
    end
  end
  return target_options
end

#describe(short, long = nil, group = nil) ⇒ Object

Sets the descriptions of the command. If the long description is ommitted, the short is reused.



127
128
129
130
131
132
133
134
# File 'lib/ctioga2/commands/commands.rb', line 127

def describe(short, long = nil, group = nil)
  @short_description = short
  @long_description = long || short
  if(group)
    @group = group
    group.commands << self
  end
end

#has_option?(option) ⇒ Boolean

Whether the Command accepts the named option.

TODO: maybe convert everything to lowercase ?????

Returns:

  • (Boolean)


223
224
225
# File 'lib/ctioga2/commands/commands.rb', line 223

def has_option?(option)
  return @optional_arguments.key? option
end

#has_options?Boolean

Whether the Command accepts any option at all ?

Returns:

  • (Boolean)


228
229
230
# File 'lib/ctioga2/commands/commands.rb', line 228

def has_options?
  return !(@optional_arguments.empty?)
end

#option_stringsObject

Returns a list of three strings:

  • the short option

  • the long option with arguments

  • the description string

Returns nil if the long option is not defined.



142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
# File 'lib/ctioga2/commands/commands.rb', line 142

def option_strings
  if ! @long_option
    return nil
  end
  retval = []
  # Short option
  retval << ( @short_option ? "-#{@short_option}" : nil)
  # Long option + arguments
  if @arguments.size > 0
    retval << @arguments.first.type.
      option_parser_long_option(@long_option, 
                                @arguments.first.displayed_name) + 
      if @arguments.size > 1
        " " + 
          @arguments[1..-1].map do |t|
        t.displayed_name.upcase
      end.join(" ")
      else
        ""
      end
  else
    retval << "--#{@long_option}"
  end
  retval << @short_description
  return retval
end

#run_command(plotmaker_target, compulsory_args, optional_args = nil) ⇒ Object

Runs the command with the given plotmaker_target, the compulsory arguments and the optional ones. Any mismatch in the number of things will result in an Exception.

The arguments will not be processed further.



238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
# File 'lib/ctioga2/commands/commands.rb', line 238

def run_command(plotmaker_target, compulsory_args, 
                optional_args = nil)
  args = [plotmaker_target]
  if compulsory_args.size != @arguments.size
    raise ArgumentNumberMismatch, "Command #{@name} was called with #{args.size} arguments, but it takes #{@arguments.size}"
  end
  args += compulsory_args
  if has_options?
    if optional_args
      args << optional_args
    else
      args << {}
    end
  end
  @code.call(*args)
end

#set_code(&code) ⇒ Object

Sets the code to the block given.



116
117
118
# File 'lib/ctioga2/commands/commands.rb', line 116

def set_code(&code)
  @code = code
end