Module: Rubikon::Application::InstanceMethods
- Included in:
- Base
- Defined in:
- lib/rubikon/application/instance_methods.rb
Overview
This module contains internal instance methods of Application::Base
and its subclasses.
Instance Attribute Summary collapse
-
#current_param ⇒ Parameter
The parameter that’s currently executed.
-
#sandbox ⇒ Application::Sandbox
readonly
The sandbox this application runs in.
Instance Method Summary collapse
-
#base_file=(file) ⇒ Object
private
Sets the (first) file this application has been defined in.
-
#debug_flag ⇒ Flag
private
Defines a global Flag for enabling debug output.
-
#estream=(estream) ⇒ Object
private
Sets the error output stream of the application.
-
#help(info = nil) ⇒ Object
private
Prints a help screen for this application.
-
#help_command ⇒ Object
private
Defines a command for displaying a help screen.
-
#hidden_output(&block) ⇒ Object
private
Hide output inside the given block and print it after the block has finished.
-
#hook(name) ⇒ Object
private
Executes the hook with the secified name.
-
#init ⇒ Object
private
This method is called once for each application and is used to initialize anything that needs to be ready before the application is run, but after the application is setup, i.e.
-
#initialize ⇒ Object
Initialize with default settings.
-
#method_missing(name, *args, &block) ⇒ Object
private
This is used to determine the receiver of a method call inside the application code.
-
#ostream=(ostream) ⇒ Object
private
Sets the output stream of the application.
-
#parse_arguments(argv) ⇒ Array<Parameter>, Command
private
Parses the command-line arguments given to the application by the user.
-
#reset ⇒ Object
private
Resets this application to its initial state.
-
#run(args = ARGV) ⇒ Object
Run this application.
-
#verbose_flag ⇒ Flag
private
Defines a global Flag for enabling verbose output.
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(name, *args, &block) ⇒ Object (private)
This is used to determine the receiver of a method call inside the application code.
This is used to have a convenient way to access e.g. paramter arguments.
This will delegate a method call to the currently executed parameter if the receiving object exists and responds to the desired method. Currently executed means the application’s execution is inside a parameter’s code block at the moment, i.e. a call to a missing method inside a parameter’s code block will trigger this behavior.
332 333 334 335 336 337 338 339 340 |
# File 'lib/rubikon/application/instance_methods.rb', line 332 def method_missing(name, *args, &block) receiver = @current_param || @current_command if receiver.nil? || (!receiver.respond_to?(name) && !receiver.public_methods(false).include?(name)) super else receiver.send(name, *args, &block) end end |
Instance Attribute Details
#current_param ⇒ Parameter
Returns The parameter that’s currently executed.
33 34 35 |
# File 'lib/rubikon/application/instance_methods.rb', line 33 def current_param @current_param end |
#sandbox ⇒ Application::Sandbox (readonly)
Returns The sandbox this application runs in.
36 37 38 |
# File 'lib/rubikon/application/instance_methods.rb', line 36 def sandbox @sandbox end |
Instance Method Details
#base_file=(file) ⇒ Object (private)
Sets the (first) file this application has been defined in.
This also sets the path of the application used to load external command code and the default banner for the help screen.
149 150 151 152 153 154 |
# File 'lib/rubikon/application/instance_methods.rb', line 149 def base_file=(file) @base_file = file @path = File.dirname(file) @settings[:help_banner] ||= "Usage: #{Pathname.new(file).relative_path_from(Pathname.new(Dir.getwd))}" end |
#debug_flag ⇒ Flag (private)
Defines a global Flag for enabling debug output
This will define a Flag --debug
(with alias -d
) to enable debug output. Using it sets Ruby’s global variable $DEBUG
to true
.
163 164 165 166 167 168 |
# File 'lib/rubikon/application/instance_methods.rb', line 163 def debug_flag global_flag :debug do $DEBUG = true end global_flag :d => :debug end |
#estream=(estream) ⇒ Object (private)
Sets the error output stream of the application
If colors are enabled, this checks if the stream supports the color_filter
method and enables the ColoredIO
if not.
178 179 180 181 182 183 |
# File 'lib/rubikon/application/instance_methods.rb', line 178 def estream=(estream) if !estream.respond_to?(:color_filter) ColoredIO.add_color_filter(estream, @settings[:colors]) end @settings[:estream] = estream end |
#help(info = nil) ⇒ Object (private)
Prints a help screen for this application
190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 |
# File 'lib/rubikon/application/instance_methods.rb', line 190 def help(info = nil) help = {} @commands.each_value do |command| help[command.name.to_s] = command.description end help.delete('__default') if @commands.key? :__default puts " [command] [args]\n\n" else puts " command [args]\n\n" end puts "#{info}\n\n" unless info.nil? puts 'Commands:' max_command_length = help.keys.max_by { |a| a.size }.size help.sort_by { |name, description| name }.each do |name, description| puts " #{name.ljust(max_command_length)} #{description}" end if @commands.key?(:__default) && @commands[:__default].description != '<hidden>' put "\nYou can also call this application without a command:" puts @commands[:__default].help(false) + "\n" end end |
#help_command ⇒ Object (private)
Defines a command for displaying a help screen
This takes any defined commands and it’s corresponding options and descriptions and displays them in a user-friendly manner.
222 223 224 225 226 227 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 256 257 258 |
# File 'lib/rubikon/application/instance_methods.rb', line 222 def help_command commands = @commands global_parameters = @global_parameters settings = @settings command :help, 'Show help for the application or a single command', :cmd => :optional do put settings[:help_banner] global_params = '' global_parameters.values.uniq.sort_by { |a| a.name.to_s }.each do |param| global_params << ' [' ([param.name] + param.aliases).each_with_index do |name, index| name = name.to_s global_params << '|' if index > 0 global_params << '-' if name.size > 1 global_params << "-#{name}" end global_params << ' ...' if param.is_a?(Option) global_params << ']' end put global_params app_help = lambda { |info| @__app__.instance_eval { help(info) } } unless cmd.nil? name = cmd.to_sym if commands.key? name puts commands[name].help else app_help.call("The command \"#{cmd}\" is undefined. The following commands are available:") end else app_help.call(nil) end end end |
#hidden_output(&block) ⇒ Object (private)
Hide output inside the given block and print it after the block has finished
If the block needs to print to the real IO stream, it can access it using its first parameter.
268 269 270 271 272 273 274 275 276 |
# File 'lib/rubikon/application/instance_methods.rb', line 268 def hidden_output(&block) current_ostream = ostream self.ostream = StringIO.new block.call(current_ostream) current_ostream << ostream.string self.ostream = current_ostream end |
#hook(name) ⇒ Object (private)
Executes the hook with the secified name
282 283 284 |
# File 'lib/rubikon/application/instance_methods.rb', line 282 def hook(name) @sandbox.instance_eval(&@hooks[name]) unless @hooks[name].nil? end |
#init ⇒ Object (private)
This method is called once for each application and is used to initialize anything that needs to be ready before the application is run, but after the application is setup, i.e. after the user has defined the application class.
290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 |
# File 'lib/rubikon/application/instance_methods.rb', line 290 def init return if @initialized hook = InstanceMethods.instance_method(:hook).bind(self) @current_command = nil @current_param = nil @current_global_param = nil hook.call(:pre_init) InstanceMethods.instance_method(:debug_flag).bind(self).call InstanceMethods.instance_method(:help_command).bind(self).call InstanceMethods.instance_method(:verbose_flag).bind(self).call if @settings[:help_as_default] && @commands.key?(:help) && !@commands.key?(:__default) default :help end @initialized = true hook.call(:post_init) end |
#initialize ⇒ Object
Initialize with default settings
If you really need to override this in your application class, be sure to call super
44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 |
# File 'lib/rubikon/application/instance_methods.rb', line 44 def initialize @commands = {} @current_command = nil @current_param = nil @default_config = {} @global_parameters = {} @hooks = {} @initialized = false @parameters = [] @sandbox = Sandbox.new(self) @settings = { :autohelp => true, :autorun => true, :colors => true, :config_file => "#{self.class.to_s.downcase}.yml", :help_as_default => true, :istream => $stdin, :name => self.class.to_s, :raise_errors => false } if RUBY_PLATFORM.downcase =~ /mswin(?!ce)|mingw|bccwin/ global_config_path = ENV['ALLUSERSPROFILE'] else global_config_path = '/etc' end @settings[:config_paths] = [ global_config_path, File.('~'), File.('.') ] self.estream = $stderr self.ostream = $stdout end |
#ostream=(ostream) ⇒ Object (private)
Sets the output stream of the application
If colors are enabled, this checks if the stream supports the color_filter
method and enables the ColoredIO
if not.
349 350 351 352 353 354 |
# File 'lib/rubikon/application/instance_methods.rb', line 349 def ostream=(ostream) if !ostream.respond_to?(:color_filter) ColoredIO.add_color_filter(ostream, @settings[:colors]) end @settings[:ostream] = ostream end |
#parse_arguments(argv) ⇒ Array<Parameter>, Command (private)
Parses the command-line arguments given to the application by the user. This distinguishes between commands, global flags and command flags
371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 |
# File 'lib/rubikon/application/instance_methods.rb', line 371 def parse_arguments(argv) argv.extend ArgumentVector argv. command, command_index = argv.command! @commands raise NoDefaultCommandError if command.nil? command_params = argv.params! command.params, command_index global_params = argv.params! @global_parameters argv.scoped_args! command unless argv.empty? first = argv.first if first.start_with? '-' raise UnknownParameterError.new(first) else raise UnknownCommandError.new(first) end end return global_params, command, command_params end |
#reset ⇒ Object (private)
Resets this application to its initial state
This rewinds the output stream, removes the color features from the and resets all commands and global parameters.
407 408 409 410 411 412 413 414 415 |
# File 'lib/rubikon/application/instance_methods.rb', line 407 def reset [estream, ostream].each do |stream| stream.rewind if stream.is_a? StringIO || !stream.stat.chardev? ColoredIO.remove_color_filter(estream) end (@commands.values + @global_parameters.values).uniq.each do |param| param.send :reset end end |
#run(args = ARGV) ⇒ Object
Run this application
Calling this method explicitly is not required when you want to create a simple application (having one main class inheriting from Rubikon::Application). But it’s useful for testing or if you want to have some sort of sub-applications.
88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 |
# File 'lib/rubikon/application/instance_methods.rb', line 88 def run(args = ARGV) hook = InstanceMethods.instance_method(:hook).bind(self) begin InstanceMethods.instance_method(:init).bind(self).call global_params, command, command_params = InstanceMethods. instance_method(:parse_arguments).bind(self).call(args) @config_factory = Config::Factory.new(@settings[:config_file], @settings[:config_paths], @settings[:config_format]) @config = @default_config.merge @config_factory.config global_params.each do |param| @current_param = param param.send :active! @current_param = nil end @current_command = command hook.call(:pre_execute) command_params.each do |param| @current_param = param param.send :active! @current_param = nil end result = command.send(:run) hook.call(:post_execute) @current_command = nil result rescue Interrupt error "\nInterrupted... exiting." rescue raise $! if @settings[:raise_errors] if @settings[:autohelp] && @commands.key?(:help) && $!.is_a?(UnknownCommandError) call :help, $!.command else error "r{Error:}\n #{$!.}" error " at #{$!.backtrace.join("\n at ")}" if $DEBUG exit 1 end ensure InstanceMethods.instance_method(:reset).bind(self).call end end |
#verbose_flag ⇒ Flag (private)
Defines a global Flag for enabling verbose output
This will define a Flag --verbose
and -v
to enable verbose output. Using it sets Ruby’s global variable $VERBOSE
to true
.
424 425 426 427 428 429 |
# File 'lib/rubikon/application/instance_methods.rb', line 424 def verbose_flag global_flag :verbose do $VERBOSE = true end global_flag :v => :verbose end |