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.

todo Write a Shortcut command that would simply be a shortcut for other things. Possibly taking arguments ? It could take a description, though that wouldn’t be necessary.

todo Use this Shortcut to write DeprecatedShortcut for old ctioga options.

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.



98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
# File 'lib/ctioga2/commands/commands.rb', line 98

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



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

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.



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

def code
  @code
end

#contextObject

The context of definition [file, line]



91
92
93
# File 'lib/ctioga2/commands/commands.rb', line 91

def context
  @context
end

#groupObject

The CommandGroup to which the command belongs



88
89
90
# File 'lib/ctioga2/commands/commands.rb', line 88

def group
  @group
end

#long_descriptionObject

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



66
67
68
# File 'lib/ctioga2/commands/commands.rb', line 66

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).



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

def long_option
  @long_option
end

#nameObject

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



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

def name
  @name
end

#optional_argumentsObject

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



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

def optional_arguments
  @optional_arguments
end

#short_descriptionObject

A short one-line description of the command



63
64
65
# File 'lib/ctioga2/commands/commands.rb', line 63

def short_description
  @short_description
end

#short_optionObject

Its short command-line option, or nil if none



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

def short_option
  @short_option
end

Instance Method Details

#argument_numberObject

Returns the number of compulsory arguments



128
129
130
# File 'lib/ctioga2/commands/commands.rb', line 128

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.



186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
# File 'lib/ctioga2/commands/commands.rb', line 186

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)



211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
# File 'lib/ctioga2/commands/commands.rb', line 211

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.



134
135
136
137
138
139
140
141
# File 'lib/ctioga2/commands/commands.rb', line 134

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 Several conversions could be used, to facilitate the writing of options:

  • convert everything to lowercase .

  • ignore the difference between _ and - (a bit delicate).

Returns:

  • (Boolean)


234
235
236
# File 'lib/ctioga2/commands/commands.rb', line 234

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

#has_options?Boolean

Whether the Command accepts any option at all ?

Returns:

  • (Boolean)


239
240
241
# File 'lib/ctioga2/commands/commands.rb', line 239

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.



149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
# File 'lib/ctioga2/commands/commands.rb', line 149

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.



249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
# File 'lib/ctioga2/commands/commands.rb', line 249

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.



123
124
125
# File 'lib/ctioga2/commands/commands.rb', line 123

def set_code(&code)
  @code = code
end