Module: RSence::ArgvUtil

Defined in:
lib/rsence/argv/argv_util.rb,
lib/rsence/argv/env_check.rb,
lib/rsence/argv/help_argv.rb,
lib/rsence/argv/save_argv.rb,
lib/rsence/argv/test_port.rb,
lib/rsence/argv/status_argv.rb,
lib/rsence/argv/initenv_argv.rb,
lib/rsence/argv/startup_argv.rb

Instance Method Summary collapse

Instance Method Details

#help(cmd) ⇒ Object

Main parser for the help command



4
5
6
7
8
9
10
11
12
13
# 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_argvObject

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



27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
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
78
79
80
81
82
83
84
85
86
87
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
137
138
139
140
141
142
143
144
145
146
147
148
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
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
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/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
    
      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}" ) }
  puts ERB.new( @strs[:initenv][:congratulations] ).result( binding )
  exit
end

#parse_save_argvObject

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



4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
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
78
79
80
81
82
83
84
85
86
87
88
89
90
# 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_argvObject

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



5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
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
78
79
80
81
82
83
84
85
86
87
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
# 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_argvObject

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.



6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
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
78
79
80
81
82
83
84
85
86
87
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
# 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') ⇒ Object

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



7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# File 'lib/rsence/argv/test_port.rb', line 7

def test_port( port, addr='127.0.0.1' )
  require 'socket'
  begin
    addr = '127.0.0.1' if addr == '0.0.0.0'
    if RUBY_VERSION.to_f >= 1.9
      sock = TCPSocket.open( addr, port )
    else
      begin
        sock = TCPsocket.open( addr, port )
      rescue NameError => e
        warn "TCPsocket not available, trying TCPSocket.."
        sock = TCPSocket.open( addr, port )
      end
    end
    sock.close
    return true
  rescue Errno::ECONNREFUSED
    return false
  rescue => e
    warn e.inspect
    return false
  end
end

#valid_env?(arg, quiet = false) ⇒ Boolean

Tests for a valid environment

Returns:

  • (Boolean)


5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
# 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) ⇒ Object

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



6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# 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