module RSence::ArgvUtil

Public Instance Methods

help( cmd ) click to toggle source

Main parser for the help command

# File lib/rsence/argv/help_argv.rb, line 4
def help( cmd )
  cmd.to_sym! if cmd.class != Symbol
  puts @strs[:help][:head]
  if @strs[:help].has_key?(cmd)
    puts @strs[:help][cmd]
  else
    puts @strs[:help][:help_main]
  end
  puts @strs[:help][:tail]
end
parse_initenv_argv() click to toggle source

The initenv command and its parser. Asks questions about the environment before doing anything else.

# File lib/rsence/argv/initenv_argv.rb, line 27
def parse_initenv_argv
  init_args
  expect_option  = false
  option_name    = false
  valid_env      = false
  interactive    = true
  create_blank   = false
  if @argv.length >= 2
    @argv[1..-1].each_with_index do |arg,i|
      if expect_option
        if [:port].include?(option_name) and arg.to_i.to_s != arg
          puts ERB.new( @strs[:messages][:invalid_option_expected_number] ).result( binding )
          exit
        else
          @args[option_name] = arg
        end
        expect_option = false
      else
        if arg.start_with?('--')
          if arg == '--port'
            expect_option = true
            option_name = :port
          elsif arg == '--addr'
            expect_option = true
            option_name = :addr
          elsif arg == '--server'
            expect_option = true
            option_name = :server
          elsif arg == '--title'
            expect_option = true
            option_name = :title
          elsif arg == '--database'
            expect_option = true
            option_name = :db
          elsif arg == '--uri-prefix'
            expect_option = true
            option_name = :base_url
          elsif arg == '--blank'
            create_blank = true
          elsif arg == '--non-interactive'
            interactive = false
          else
            invalid_option(arg)
          end
        elsif arg.start_with?('-')
          arg.split('')[1..-1].each do |chr|
            if chr == 'q'
              interactive = false
            end
          end
        else
          @args[:env_path] = File.expand_path(arg)
        end
      end
    end
    if expect_option
      puts ERB.new( @strs[:messages][:no_value_for_option] ).result( binding )
      exit
    end
  end
  if valid_env?(@args[:env_path],true)
    puts @strs[:initenv][:env_already_initialized]
    exit
  end
  conf_file = File.expand_path( File.join( @args[:env_path], 'conf', 'config.yaml' ) )
  if File.exists?(@args[:env_path])
    env_empty = true # true while entries start with a dot
    env_clear = true # true while entries don't contain RSence project files
    env_entries = ['conf', 'db', 'log', 'plugins', 'run', 'README', 'VERSION']
    Dir.entries(@args[:env_path]).each do |entry|
      next if entry.start_with?('.')
      env_empty = false
      if env_entries.include? entry
        env_clear = false
        break
      end
    end
    unless env_clear
      puts ERB.new( @strs[:initenv][:env_not_clear] ).result( binding )
      print @strs[:initenv][:continue_question]
      exit unless yesno
    end
    unless env_empty
      puts ERB.new( @strs[:initenv][:env_not_empty] ).result( binding )
      print @strs[:initenv][:continue_question]
      exit unless yesno
    end
  end

  require 'rsence/default_config'
  default_config = Configuration.new(@args,true).config

  config = {
    :base_url => (@args[:base_url] or default_config[:base_url]),
    :http_server => {
      :port   => (@args[:port] or default_config[:http_server][:port]),
      :bind_address => (@args[:addr] or default_config[:http_server][:bind_address]),
      :rack_require => (@args[:server] or default_config[:http_server][:rack_require])
    },
    :index_html => {
      :title  => (@args[:title] or default_config[:index_html][:title])
    },
    :database => {
      :ses_db => (@args[:db] or default_config[:database][:ses_db])
    }
  }
  Signal.trap 'INT' do
    puts
    puts "Configuration aborted."
    exit
  end
  if interactive
    answers_ok = false
    until answers_ok
      puts ERB.new( @strs[:initenv][:creating_env] ).result( binding )
  
      require 'highline/import'

      say @strs[:initenv][:enter_title]
      str_project_title = @strs[:initenv][:project_title]
      config[:index_html][:title] = ask( str_project_title ) do |q|
        q.default = config[:index_html][:title]
      end
    
      say @strs[:initenv][:enter_db_url]
      str_db_url = @strs[:initenv][:db_url]
      config[:database][:ses_db] = ask(str_db_url) do |q|
        q.default = config[:database][:ses_db]
      end
    
      say @strs[:initenv][:enter_http_port]
      str_http_port = @strs[:initenv][:http_port]
      config[:http_server][:port] = ask(str_http_port) do |q|
        q.default = config[:http_server][:port].to_s
      end

      say @strs[:initenv][:enter_tcp_ip]
      str_tcp_ip = @strs[:initenv][:tcp_ip]
      config[:http_server][:bind_address] = ask(str_tcp_ip) do |q|
        q.default = config[:http_server][:bind_address]
      end
    
      say @strs[:initenv][:enter_root_dir]
      str_root_dir = @strs[:initenv][:root_dir]
      config[:base_url] = ask(str_root_dir) do |q|
        q.default = config[:base_url]
      end

      # possible workaround for highline on some systems:
      config[:index_html][:title] = config[:index_html][:title].to_s
      config[:database][:ses_db] = config[:database][:ses_db].to_s
      config[:http_server][:port] = config[:http_server][:port].to_s.to_i
      config[:http_server][:bind_address] = config[:http_server][:bind_address].to_s
      config[:base_url] = config[:base_url].to_s
    
      test_url = "http://#{config[:http_server][:bind_address]}:#{config[:http_server][:port]}#{config[:base_url]}"
      say ERB.new( @strs[:initenv][:config_summary] ).result( binding )
      print @strs[:initenv][:confirm_config]
      answers_ok = yesno(true)
    end
  else
    test_url = "http://#{config[:http_server][:bind_address]}:#{config[:http_server][:port]}#{config[:base_url]}"
  end

  puts @strs[:initenv][:creating_dirs]
  env_dir = @args[:env_path]
  require 'fileutils'
  FileUtils.mkdir_p( env_dir ) unless File.exists?( env_dir )
  conf_dir = File.expand_path( 'conf', env_dir )
  Dir.mkdir( conf_dir )
  db_dir = File.expand_path( 'db', env_dir )
  Dir.mkdir( db_dir )
  log_dir = File.expand_path( 'log', env_dir )
  Dir.mkdir( log_dir )
  plugins_dir = File.expand_path( 'plugins', env_dir )
  Dir.mkdir( plugins_dir )
  run_dir = File.expand_path( 'run', env_dir )
  Dir.mkdir( run_dir )
  unless create_blank
    print @strs[:initenv][:install_welcome]
    if yesno
      welcome_plugin_dir = File.join( SERVER_PATH, 'setup', 'welcome' )
      welcome_plugin_dst = File.join( plugins_dir, 'welcome' )
      puts ERB.new( @strs[:initenv][:installing_welcome_plugin] ).result( binding )
      FileUtils.cp_r( welcome_plugin_dir, welcome_plugin_dst )
    end
  end
  puts @strs[:initenv][:creating_files]
  conf_file = File.join( conf_dir, 'config.yaml' )
  File.open( conf_file, 'w' ) {|f| f.write( YAML.dump( config ) ) }
  readme_file = File.join( env_dir, 'README' )
  File.open( readme_file, 'w' ) {|f| f.write( ERB.new( @strs[:initenv][:readme] ).result( binding ) ) }
  version_file = File.join( env_dir, 'VERSION' )
  File.open( version_file, 'w' ) {|f| f.write( "RSence Environment Version #{version.to_f}\n" ) }
  [ db_dir, log_dir, run_dir ].each do |ign_prefix|
    gitignore_file = File.join( ign_prefix, '.gitignore' )
    File.open( gitignore_file, 'w' ) {|f| f.write("*\n") }
  end
  puts ERB.new( @strs[:initenv][:congratulations] ).result( binding )
  exit
end
parse_save_argv() click to toggle source

Main argument parser for the save command. Sends the USR1 POSIX signal to the process, if running.

# File lib/rsence/argv/save_argv.rb, line 4
def parse_save_argv
  init_args
  expect_option  = false
  option_name = false
  if @argv.length >= 2
    @argv[1..-1].each_with_index do |arg,i|
      if expect_option
        if option_name == :conf_files
          if not File.exists?( arg ) or not File.file?( arg )
            puts ERB.new( @strs[:messages][:no_such_configuration_file] ).result( binding )
            exit
          else
            @args[:conf_files].push( arg )
          end
        else
          @args[option_name] = arg
        end
        expect_option = false
      else
        if arg.start_with?('--')
          if arg == '--debug'
            set_debug
          elsif arg == '--verbose'
            set_verbose
          elsif arg == '--conf' or arg == '--config'
            expect_option = true
            option_name = :conf_files
          else
            invalid_option(arg)
          end
        elsif arg.start_with?('-')
          arg.split('')[1..-1].each do |chr|
            if chr == 'd'
              set_debug
            elsif chr == 'v'
              set_verbose
            else
              invalid_option(arg,chr)
            end
          end
        elsif valid_env?(arg)
          @args[:env_path] = File.expand_path(arg)
          @args[:conf_files].unshift( File.expand_path( File.join( arg, 'conf', 'config.yaml' ) ) )
        else
          invalid_env( arg )
        end
      end
    end
    if expect_option
      puts ERB.new( @strs[:messages][:no_value_for_option] ).result( binding )
      exit
    end
  end
  if valid_env?(@args[:env_path])
    conf_file = File.expand_path( File.join( @args[:env_path], 'conf', 'config.yaml' ) )
    @args[:conf_files].unshift( conf_file ) unless @args[:conf_files].include?( conf_file )
  else
    invalid_env
  end
  require 'rsence/default_config'
  config = Configuration.new(@args).config
  if RSence.pid_support?
    pid_fn = config[:daemon][:pid_fn]
    if File.exists?( pid_fn )
      pid = File.read( pid_fn ).to_i
      saving_message = @strs[:messages][:saving_message]
      pid_status = RSence::SIGComm.wait_signal_response(
        pid, pid_fn, 'USR2', 30, saving_message, '.', 0.1, true
      )
    else
      warn @strs[:messages][:no_pid_file] if @args[:verbose]
      pid_status = nil
    end
  else
    warn @strs[:messages][:no_pid_support] if @args[:verbose]
    pid_status = nil
  end
  if RSence.pid_support?
    if pid_status == nil
      puts @strs[:messages][:no_pid_unable_to_save]
    elsif pid_status == false
      puts @strs[:messages][:no_process_running]
    else
      puts @strs[:messages][:session_data_saved]
    end
  end
end
parse_startup_argv() click to toggle source

Main argument parser for all ‘start’ -type commands.

# File lib/rsence/argv/startup_argv.rb, line 5
def parse_startup_argv
  init_args
  expect_option  = false
  option_name = false
  if @argv.length >= 2
    @argv[1..-1].each_with_index do |arg,i|
      if expect_option
        if [ :port, :latency, :http_delayed_start ].include?(option_name) and arg.to_i.to_s != arg
          puts ERB.new( @strs[:messages][:invalid_option_expected_number] ).result( binding )
          exit
        elsif option_name == :conf_files
          if not File.exists?( arg ) or not File.file?( arg )
            puts ERB.new( @strs[:messages][:no_such_configuration_file] ).result( binding )
            exit
          else
            @args[:conf_files].push( arg )
          end
        elsif option_name == :http_delayed_start
          @args[:http_delayed_start] = arg.to_i
        else
          arg = arg.to_i if option_name == :latency
          @args[option_name] = arg
        end
        expect_option = false
      else
        if arg.start_with?('--')
          if arg == '--profile'
            true
          elsif arg == '--debug'
            set_debug
          elsif arg == '--verbose'
            set_verbose
          elsif arg == '--log-fg'
            set_log_fg
          elsif arg == '--trace-js'
            @args[:trace_js]   = true
          elsif arg == '--trace-delegate'
            @args[:trace_delegate] = true
          elsif arg == '--port'
            expect_option = true
            option_name = :port
          elsif arg == '--addr' or arg == '--bind'
            expect_option = true
            option_name = :addr
          elsif arg == '--http-delayed-start' or arg == '--delayed-start'
            expect_option = true
            option_name = :http_delayed_start
          elsif arg == '--server'
            expect_option = true
            option_name = :server
          elsif arg == '--conf' or arg == '--config'
            expect_option = true
            option_name = :conf_files
          elsif arg == '--reset-sessions'
            set_reset_ses
          elsif arg == '--auto-update'
            set_autoupdate
          elsif arg == '--latency'
            expect_option = true
            option_name = :latency
          elsif arg == '--say'
            set_say
          elsif arg == '--disable-gzip'
            @args[:client_pkg_no_gzip] = true
          elsif arg == '--disable-obfuscation'
            @args[:client_pkg_no_obfuscation] = true
          elsif arg == '--disable-jsmin'
            @args[:client_pkg_no_whitespace_removal] = true
          elsif arg == '--build-report'
            @args[:suppress_build_messages] = false
          else
            invalid_option(arg)
          end
        elsif arg.start_with?('-')
          arg.split('')[1..-1].each do |chr|
            if chr == 'd'
              set_debug
            elsif chr == 'v'
              set_verbose
            elsif chr == 'f'
              set_log_fg
            elsif chr == 'r'
              set_reset_ses
            elsif chr == 'a'
              set_autoupdate
            elsif chr == 'S'
              set_say
            else
              invalid_option(arg,chr)
            end
          end
        elsif valid_env?(arg)
          @args[:env_path] = File.expand_path(arg)
          @args[:conf_files].push( File.expand_path( File.join( arg, 'conf', 'config.yaml' ) ) )
        else
          invalid_env( arg )
        end
      end
    end
    if expect_option
      puts ERB.new( @strs[:messages][:no_value_for_option] ).result( binding )
      exit
    end
  end
  if valid_env?(@args[:env_path])
    conf_file = File.expand_path( File.join( @args[:env_path], 'conf', 'config.yaml' ) )
    @args[:conf_files].unshift( conf_file ) unless @args[:conf_files].include?( conf_file )
  else
    invalid_env
  end
  @startable = true
end
parse_status_argv() click to toggle source

Main argument parser for the status command, sends the INFO (or PWR on linux) POSIX signal to the process, if running. Checks if the process responds on the port and address it’s configured for.

# File lib/rsence/argv/status_argv.rb, line 6
def parse_status_argv
  init_args
  expect_option  = false
  option_name = false
  if @argv.length >= 2
    @argv[1..-1].each_with_index do |arg,i|
      if expect_option
        if [:port].include?(option_name) and arg.to_i.to_s != arg
          puts ERB.new( @strs[:messages][:invalid_option_expected_number] ).result( binding )
          exit
        elsif option_name == :conf_files
          if not File.exists?( arg ) or not File.file?( arg )
            puts ERB.new( @strs[:messages][:no_such_configuration_file] ).result( binding )
            exit
          else
            @args[:conf_files].push( arg )
          end
        else
          @args[option_name] = arg
        end
        expect_option = false
      else
        if arg.start_with?('--')
          if arg == '--debug'
            set_debug
          elsif arg == '--verbose'
            set_verbose
          elsif arg == '--port'
            expect_option = true
            option_name = :port
          elsif arg == '--addr'
            expect_option = true
            option_name = :addr
          elsif arg == '--conf' or arg == '--config'
            expect_option = true
            option_name = :conf_files
          else
            invalid_option(arg)
          end
        elsif arg.start_with?('-')
          arg.split('')[1..-1].each do |chr|
            if chr == 'd'
              set_debug
            elsif chr == 'v'
              set_verbose
            else
              invalid_option(arg,chr)
            end
          end
        elsif valid_env?(arg)
          @args[:env_path] = File.expand_path(arg)
          @args[:conf_files].unshift( File.expand_path( File.join( arg, 'conf', 'config.yaml' ) ) )
        else
          invalid_env( arg )
        end
      end
    end
    if expect_option
      puts ERB.new( @strs[:messages][:no_value_for_option] ).result( binding )
      exit
    end
  end
  if valid_env?(@args[:env_path])
    conf_file = File.expand_path( File.join( @args[:env_path], 'conf', 'config.yaml' ) )
    @args[:conf_files].unshift( conf_file ) unless @args[:conf_files].include?( conf_file )
  else
    invalid_env
  end
  require 'rsence/default_config'
  require 'socket'
  config = Configuration.new(@args).config
  port = config[:http_server][:port]
  addr = config[:http_server][:bind_address]
  port_status = []
  if addr == '0.0.0.0' and Socket.respond_to?(:ip_address_list)
    Socket.ip_address_list.each do |if_addr|
      if test_port( port, if_addr.ip_address )
        port_status.push( if_addr.ip_address )
      end
    end
  else
    port_status.push( addr )
  end
  addr_descr = port_status.join(":#{port}, ")+":#{port}"
  if RSence.pid_support?
    pid_fn = config[:daemon][:pid_fn]
    if File.exists?( pid_fn )
      pid = File.read( pid_fn ).to_i
      sig_name = RSence.info_signal_name
      pid_status = RSence::SIGComm.wait_signal_response(
        pid, pid_fn, sig_name, 3
      )
    else
      warn @strs[:messages][:no_pid_file] if @args[:verbose]
      pid_status = nil
    end
  else
    warn @strs[:messages][:no_pid_support] if @args[:verbose]
    pid_status = nil
  end
  addr_descr = port_status.join(":#{port} and ")+":#{port}" unless port_status.empty?
  if not RSence.pid_support? or pid_status == nil
    if RSence.pid_support?
      puts @strs[:messages][:no_pid]
    else
      puts @strs[:messages][:no_pid_support]
    end
    unless port_status.empty?
      puts ERB.new( @strs[:messages][:something_responds] ).result( binding )
    end
  elsif pid_status == false
    if port_status.empty?
      puts ERB.new( @strs[:messages][:no_process_running_and_nothing_responds] ).result( binding )
    else
      puts ERB.new( @strs[:messages][:no_process_running_but_something_responds] ).result( binding )
    end
  else
    if port_status.empty?
      puts ERB.new( @strs[:messages][:process_running_but_nothing_responds] ).result( binding )
    else
      addr_descr = port_status.join(":#{port} and ")+":#{port}"
      puts ERB.new( @strs[:messages][:process_running_and_responds] ).result( binding )
    end
  end
end
test_port( port, addr='127.0.0.1' ) click to toggle source

Tests, if the port on addr responds or refuses the connection. Automatically replaces ‘0.0.0.0’ with ‘127.0.0.1’

# File lib/rsence/argv/test_port.rb, line 7
def test_port( port, addr='127.0.0.1' )
  require 'socket'
  require 'timeout'
  begin
    addr = '127.0.0.1' if addr == '0.0.0.0'
    timeout(1) do
      if RUBY_VERSION.to_f >= 1.9
        sock = TCPSocket.open( addr, port )
      else
        begin
          sock = TCPsocket.open( addr, port )
        rescue NameError => e # Rubinius
          warn "TCPsocket not available, trying TCPSocket.."
          sock = TCPSocket.open( addr, port )
        end
      end
      sock.close
    end
    return true
  rescue Timeout::Error
    puts "Address #{addr} port #{port} timed out"
    return false
  rescue Errno::ECONNREFUSED
    return false
  rescue => e
    warn e.inspect
    return false
  end
end
valid_env?( arg, quiet=false ) click to toggle source

Tests for a valid environment

# File lib/rsence/argv/argv_util.rb, line 5
def valid_env?( arg, quiet=false )
  
  # Checks, if the top-level path exists and is a directory
  path = File.expand_path( arg )
  if not File.exists?( path )
    puts ERB.new( @strs[:messages][:no_such_directory] ).result( binding ) unless quiet
    return false
  elsif not File.directory?( path )
    puts ERB.new( @strs[:messages][:not_a_directory] ).result( binding ) unless quiet
    return false
  end
  
  # Checks, if the conf path exists and is a directory
  conf_path = File.join( path, 'conf' )
  if not File.exists?( conf_path )
    puts ERB.new( @strs[:messages][:missing_conf_directory] ).result( binding ) unless quiet
    return false
  elsif not File.directory?( conf_path )
    puts ERB.new( @strs[:messages][:invalid_conf_directory] ).result( binding ) unless quiet
    return false
  end
  
  # Checks, if the conf/config.yaml file exists and is a directory
  conf_file = File.join( path, 'conf', 'config.yaml' )
  if not File.exists?(conf_file)
    puts ERB.new( @strs[:messages][:missing_conf_file] ).result( binding ) unless quiet
    return false
  elsif not File.file?( conf_file )
    puts ERB.new( @strs[:messages][:invalid_conf_file_not_file] ).result( binding ) unless quiet
    return false
  end
  
  # Checks, if the plugins path exists and is a directory
  plugin_path = File.join( path, 'plugins' )
  if not File.exists?( plugin_path )
    warn ERB.new( @strs[:messages][:warn_no_plugin_directory_in_project] ).result( binding ) if @args[:verbose]
  elsif not File.directory?( plugin_path )
    puts ERB.new( @strs[:messages][:plugin_directory_not_a_directory] ).result( binding ) unless quiet
    return false
  end
  
  # Checks (and automatically creates if missing) the run, db and log directories
  ['run','log','db'].each do |dir_name|
    dir_path = File.join( path, dir_name )
    unless File.exists?( dir_path )
      warn ERB.new( @strs[:messages][:warn_no_directory_creating] ).result( binding ) if @args[:verbose]
      Dir.mkdir( dir_path )
    end
  end
  return true
end
yesno(default=false) click to toggle source

asks y/n and returns booleans, the default tells if which one is for just enter

# File lib/rsence/argv/initenv_argv.rb, line 6
def yesno(default=false)
  if default
    question = "Y/n? "
  else
    question = "y/N? "
  end
  print question
  answer = $stdin.gets.strip.downcase[0]
  answer = answer.chr if answer
  if answer == 'n'
    return false
  elsif answer == 'y'
    return true
  elsif answer == nil
    return default
  else
    return nil
  end
end