module Rubikon::Application::InstanceMethods
This module contains internal instance methods of Application::Base
and its subclasses.
@author Sebastian Staudt @see Application::Base
@since 0.2.0
Attributes
@return [Parameter] The parameter that’s currently executed
@return [Application::Sandbox] The sandbox this application runs in
Public Class Methods
Initialize with default settings
If you really need to override this in your application class, be sure to call super
@see set
# 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.expand_path('~'), File.expand_path('.') ] self.estream = $stderr self.ostream = $stdout end
Public Instance Methods
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.
@param [Array<String>] args The command line arguments that should be
given to the application as options
# 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 #{$!.message}" error " at #{$!.backtrace.join("\n at ")}" if $DEBUG exit 1 end ensure InstanceMethods.instance_method(:reset).bind(self).call end end
Private Instance Methods
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.
@param [String] file The (first) file of the class definition @see DSLMethods#base_file
@see DSLMethods#path
@since 0.4.0
# 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
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
.
@return [Flag] The debug flag
# File lib/rubikon/application/instance_methods.rb, line 163 def debug_flag global_flag :debug do $DEBUG = true end global_flag :d => :debug end
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.
@param [IO] estream The output stream to use @see ColoredIO.add_color_filter
@since 0.6.0
# 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
Prints a help screen for this application
@param [String] info A additional information string to be displayed
right after usage information
@since 0.6.0
# 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
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.
# 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
Executes the hook with the secified name
@param [Symbol] name The name of the hook to execute @since 0.4.0
# File lib/rubikon/application/instance_methods.rb, line 282 def hook(name) @sandbox.instance_eval(&@hooks[name]) unless @hooks[name].nil? end
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.
# 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
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.
@example Access a command’s arguments
command :args, [:one, :two] do puts "One: #{one}, Two: #{two}" end
@since 0.4.0
# 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
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.
@param [IO] ostream The output stream to use @see ColoredIO.add_color_filter
# 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
Parses the command-line arguments given to the application by the user. This distinguishes between commands, global flags and command flags
@param [String] argv The command-line arguments @raise [NoDefaultCommandError] if no command can be found and no
default command exists
@raise [UnknownParameterError] if an unknown parameter is found @raise [UnknownParameterError] if an unknown command is found @return [Array<Parameter>] one All global parameters that have been
supplied
@return [Command] two The command to execute, the parameters of this
command that have been supplied
@return [Array<Parameter>] three All parameters of that command that have
been supplied
# File lib/rubikon/application/instance_methods.rb, line 371 def parse_arguments(argv) argv.extend ArgumentVector argv.expand! 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
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.
@see ColoredIO.remove_color_filter
@see Command#reset
@see HasArguments#reset
@see IO#rewind @see Parameter#reset
@since 0.4.0
# 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
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
.
@return [Flag] The verbose Flag
object
# File lib/rubikon/application/instance_methods.rb, line 424 def verbose_flag global_flag :verbose do $VERBOSE = true end global_flag :v => :verbose end