Class: CTioga2::Commands::Command
- Inherits:
-
Object
- Object
- CTioga2::Commands::Command
- 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
-
#arguments ⇒ Object
The compulsory arguments it can take, in the form of an array of CommandArgument.
-
#code ⇒ Object
The code that will be called.
-
#context ⇒ Object
The context of definition [file, line].
-
#documentation_context ⇒ Object
The context of the documentation.
-
#group ⇒ Object
The CommandGroup to which the command belongs.
-
#long_description ⇒ Object
A longer description.
-
#long_option ⇒ Object
Its long command-line option, or nil if it should not be called from the command-line (but you really don’t want that).
-
#name ⇒ Object
The name of the command, ie how to call it in a commands file.
-
#optional_arguments ⇒ Object
Optional arguments to a command, in the form of a Hash ‘option name’ => CommandArgument.
-
#short_description ⇒ Object
A short one-line description of the command.
-
#short_option ⇒ Object
Its short command-line option, or nil if none.
Class Method Summary collapse
-
.document_command(cmd, desc) ⇒ Object
Sets the long documentation of the given command.
- .get_calling_context(id = 2) ⇒ Object
Instance Method Summary collapse
-
#argument_number ⇒ Object
Returns the number of compulsory arguments.
-
#convert_arguments(args) ⇒ Object
Converts the Array of String given into an Array of the type suitable for the #code of the Command.
-
#convert_options(options) ⇒ Object
Converts the Hash of String given into a Hash of the type suitable for the #code of the Command.
-
#describe(short, long = nil, group = nil) ⇒ Object
Sets the descriptions of the command.
-
#has_option?(option) ⇒ Boolean
Whether the Command accepts the named option.
-
#has_options? ⇒ Boolean
Whether the Command accepts any option at all ?.
-
#initialize(n, short, long, args = [], opts = {}, d_short = nil, d_long = nil, group = nil, register = true, &code) ⇒ Command
constructor
Creates a Command, with all attributes set up.
-
#normalize_option_name(opt) ⇒ Object
Returns a lowercase.
-
#option_strings ⇒ Object
Returns a list of three strings: * the short option * the long option with arguments * the description string.
-
#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.
-
#set_code(&code) ⇒ Object
Sets the code to the block given.
-
#target_option_names ⇒ Object
Returns a hash “normalized option names” => ‘real option name’.
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.
104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 |
# File 'lib/ctioga2/commands/commands.rb', line 104 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) @context = Command.get_calling_context # Registers automatically the command if register Commands::Interpreter.register_command(self) end end |
Instance Attribute Details
#arguments ⇒ Object
The compulsory arguments it can take, in the form of an array of CommandArgument
54 55 56 |
# File 'lib/ctioga2/commands/commands.rb', line 54 def arguments @arguments end |
#code ⇒ Object
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.
83 84 85 |
# File 'lib/ctioga2/commands/commands.rb', line 83 def code @code end |
#context ⇒ Object
The context of definition [file, line]
89 90 91 |
# File 'lib/ctioga2/commands/commands.rb', line 89 def context @context end |
#documentation_context ⇒ Object
The context of the documentation
92 93 94 |
# File 'lib/ctioga2/commands/commands.rb', line 92 def documentation_context @documentation_context end |
#group ⇒ Object
The CommandGroup to which the command belongs
86 87 88 |
# File 'lib/ctioga2/commands/commands.rb', line 86 def group @group end |
#long_description ⇒ Object
A longer description. Typically input using a here-document.
64 65 66 |
# File 'lib/ctioga2/commands/commands.rb', line 64 def long_description @long_description end |
#long_option ⇒ Object
Its long command-line option, or nil if it should not be called from the command-line (but you really don’t want that).
50 51 52 |
# File 'lib/ctioga2/commands/commands.rb', line 50 def long_option @long_option end |
#name ⇒ Object
The name of the command, ie how to call it in a commands file
43 44 45 |
# File 'lib/ctioga2/commands/commands.rb', line 43 def name @name end |
#optional_arguments ⇒ Object
Optional arguments to a command, in the form of a Hash ‘option name’ => CommandArgument
58 59 60 |
# File 'lib/ctioga2/commands/commands.rb', line 58 def optional_arguments @optional_arguments end |
#short_description ⇒ Object
A short one-line description of the command
61 62 63 |
# File 'lib/ctioga2/commands/commands.rb', line 61 def short_description @short_description end |
#short_option ⇒ Object
Its short command-line option, or nil if none
46 47 48 |
# File 'lib/ctioga2/commands/commands.rb', line 46 def short_option @short_option end |
Class Method Details
.document_command(cmd, desc) ⇒ Object
Sets the long documentation of the given command
151 152 153 154 155 156 157 |
# File 'lib/ctioga2/commands/commands.rb', line 151 def self.document_command(cmd, desc) tg = Commands::Interpreter.command(cmd) if tg tg.documentation_context = Command.get_calling_context(1) tg.long_description = desc end end |
.get_calling_context(id = 2) ⇒ Object
94 95 96 97 |
# File 'lib/ctioga2/commands/commands.rb', line 94 def self.get_calling_context(id=2) caller[id].gsub(/.*\/ctioga2\//, 'lib/ctioga2/') =~ /(.*):(\d+)/ return [$1, $2.to_i] end |
Instance Method Details
#argument_number ⇒ Object
Returns the number of compulsory arguments
133 134 135 |
# File 'lib/ctioga2/commands/commands.rb', line 133 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.
202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 |
# File 'lib/ctioga2/commands/commands.rb', line 202 def convert_arguments(args) if args.size != @arguments.size if(@arguments.size == 0 && args.size == 1 && args[0] == true) return [] else ar = args.map { |x| "'#{x}'"} raise ArgumentNumberMismatch, "Command #{@name} was called with #{args.size} arguments: #{ar.join(", ")}, 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)
228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 |
# File 'lib/ctioga2/commands/commands.rb', line 228 def () = {} conv = target_option_names() for k,v in kn = normalize_option_name(k) if ! conv.key? kn raise CommandOptionUnkown, "Unkown option #{k} for command #{@name}" end opt = @optional_arguments[conv[kn]] if v.is_a? String v = opt.type.string_to_type(v) end target = opt.option_target || conv[kn] if opt.option_deprecated expl = "" if opt.option_target expl = " -- please use #{opt.option_target} instead" elsif opt.option_deprecated != true # Ie more than plain # true/false expl = " -- #{opt.option_deprecated}" end Log::warn { "Deprecated option #{k}#{expl}" } end [target] = v end return end |
#describe(short, long = nil, group = nil) ⇒ Object
Sets the descriptions of the command. If the long description is ommitted, the short is reused.
139 140 141 142 143 144 145 146 147 148 |
# File 'lib/ctioga2/commands/commands.rb', line 139 def describe(short, long = nil, group = nil) @documentation_context = Command.get_calling_context(1) @short_description = short @long_description = long || short if(group) group = Interpreter::group(group) if group.is_a? String @group = group group.commands << self end end |
#has_option?(option) ⇒ Boolean
Whether the Command accepts the named option.
275 276 277 |
# File 'lib/ctioga2/commands/commands.rb', line 275 def has_option?(option) return target_option_names.key?(normalize_option_name(option)) end |
#has_options? ⇒ Boolean
Whether the Command accepts any option at all ?
280 281 282 |
# File 'lib/ctioga2/commands/commands.rb', line 280 def return !(@optional_arguments.empty?) end |
#normalize_option_name(opt) ⇒ Object
Returns a lowercase
270 271 272 |
# File 'lib/ctioga2/commands/commands.rb', line 270 def normalize_option_name(opt) return opt.gsub(/_/,"-").downcase end |
#option_strings ⇒ Object
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.
165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 |
# File 'lib/ctioga2/commands/commands.rb', line 165 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.
290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 |
# File 'lib/ctioga2/commands/commands.rb', line 290 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 plotmaker_target.interpreter. add_instruction(Instruction.new(self, compulsory_args, optional_args)) args += compulsory_args if 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.
128 129 130 |
# File 'lib/ctioga2/commands/commands.rb', line 128 def set_code(&code) @code = code end |
#target_option_names ⇒ Object
Returns a hash “normalized option names” => ‘real option name’
258 259 260 261 262 263 264 265 266 |
# File 'lib/ctioga2/commands/commands.rb', line 258 def target_option_names return @tg_op_names if @tg_op_names @tg_op_names = {} for k in @optional_arguments.keys @tg_op_names[normalize_option_name(k)] = k end return @tg_op_names end |