passenger 5.0.0.beta3 → 5.0.0.rc1
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of passenger might be problematic. Click here for more details.
- checksums.yaml +8 -8
- checksums.yaml.gz.asc +7 -7
- data.tar.gz.asc +7 -7
- data/.editorconfig +11 -5
- data/CHANGELOG +38 -0
- data/CONTRIBUTING.md +1 -4
- data/Gemfile +0 -1
- data/Gemfile.lock +0 -2
- data/Rakefile +33 -33
- data/bin/passenger +1 -1
- data/bin/passenger-config +1 -1
- data/bin/passenger-install-apache2-module +800 -800
- data/bin/passenger-install-nginx-module +592 -592
- data/bin/passenger-memory-stats +127 -127
- data/bin/passenger-status +216 -216
- data/build/agents.rb +127 -127
- data/build/apache2.rb +87 -87
- data/build/basics.rb +60 -60
- data/build/common_library.rb +165 -165
- data/build/cplusplus_support.rb +51 -51
- data/build/cxx_tests.rb +268 -268
- data/build/debian.rb +143 -143
- data/build/documentation.rb +58 -58
- data/build/integration_tests.rb +81 -81
- data/build/misc.rb +132 -132
- data/build/nginx.rb +20 -20
- data/build/node_tests.rb +7 -7
- data/build/oxt_tests.rb +14 -14
- data/build/packaging.rb +570 -570
- data/build/preprocessor.rb +260 -260
- data/build/rake_extensions.rb +71 -71
- data/build/ruby_extension.rb +29 -29
- data/build/ruby_tests.rb +6 -6
- data/build/test_basics.rb +37 -37
- data/debian.template/control.template +3 -5
- data/dev/copy_boost_headers +134 -134
- data/dev/install_scripts_bootstrap_code.rb +25 -25
- data/dev/list_tests +20 -20
- data/dev/ruby_server.rb +223 -223
- data/dev/runner +18 -18
- data/doc/ServerOptimizationGuide.txt.md +55 -2
- data/doc/Users guide Nginx.txt +0 -26
- data/doc/Users guide Standalone.txt +5 -1
- data/doc/users_guide_snippets/tips.txt +9 -0
- data/ext/common/ApplicationPool2/Group.h +23 -11
- data/ext/common/ApplicationPool2/Implementation.cpp +32 -7
- data/ext/common/ApplicationPool2/Pool.h +22 -17
- data/ext/common/ApplicationPool2/SmartSpawner.h +4 -1
- data/ext/common/ApplicationPool2/Spawner.h +1 -1
- data/ext/common/Constants.h +1 -1
- data/ext/common/agents/Base.cpp +35 -20
- data/ext/common/agents/HelperAgent/Main.cpp +8 -1
- data/ext/common/agents/HelperAgent/OptionParser.h +18 -4
- data/ext/common/agents/HelperAgent/RequestHandler.h +2 -83
- data/ext/common/agents/HelperAgent/RequestHandler/ForwardResponse.cpp +54 -1
- data/ext/common/agents/HelperAgent/RequestHandler/InitRequest.cpp +7 -4
- data/ext/common/agents/Main.cpp +1 -1
- data/ext/common/agents/Watchdog/Main.cpp +54 -19
- data/ext/nginx/Configuration.c +7 -0
- data/ext/nginx/ContentHandler.c +9 -1
- data/helper-scripts/backtrace-sanitizer.rb +106 -87
- data/helper-scripts/crash-watch.rb +32 -0
- data/helper-scripts/download_binaries/extconf.rb +38 -38
- data/helper-scripts/meteor-loader.rb +107 -107
- data/helper-scripts/prespawn +101 -101
- data/helper-scripts/rack-loader.rb +96 -96
- data/helper-scripts/rack-preloader.rb +137 -137
- data/lib/phusion_passenger.rb +292 -292
- data/lib/phusion_passenger/abstract_installer.rb +438 -438
- data/lib/phusion_passenger/active_support3_extensions/init.rb +168 -170
- data/lib/phusion_passenger/admin_tools.rb +20 -20
- data/lib/phusion_passenger/admin_tools/instance.rb +178 -178
- data/lib/phusion_passenger/admin_tools/instance_registry.rb +61 -61
- data/lib/phusion_passenger/admin_tools/memory_stats.rb +267 -267
- data/lib/phusion_passenger/apache2/config_options.rb +182 -182
- data/lib/phusion_passenger/common_library.rb +479 -485
- data/lib/phusion_passenger/config/about_command.rb +161 -161
- data/lib/phusion_passenger/config/admin_command_command.rb +129 -129
- data/lib/phusion_passenger/config/agent_compiler.rb +121 -121
- data/lib/phusion_passenger/config/build_native_support_command.rb +43 -43
- data/lib/phusion_passenger/config/command.rb +25 -25
- data/lib/phusion_passenger/config/compile_agent_command.rb +62 -62
- data/lib/phusion_passenger/config/compile_nginx_engine_command.rb +88 -73
- data/lib/phusion_passenger/config/detach_process_command.rb +72 -72
- data/lib/phusion_passenger/config/download_agent_command.rb +246 -227
- data/lib/phusion_passenger/config/download_nginx_engine_command.rb +245 -224
- data/lib/phusion_passenger/config/install_agent_command.rb +144 -132
- data/lib/phusion_passenger/config/install_standalone_runtime_command.rb +205 -185
- data/lib/phusion_passenger/config/installation_utils.rb +204 -204
- data/lib/phusion_passenger/config/list_instances_command.rb +64 -64
- data/lib/phusion_passenger/config/main.rb +152 -152
- data/lib/phusion_passenger/config/nginx_engine_compiler.rb +319 -300
- data/lib/phusion_passenger/config/reopen_logs_command.rb +67 -67
- data/lib/phusion_passenger/config/restart_app_command.rb +155 -155
- data/lib/phusion_passenger/config/system_metrics_command.rb +13 -13
- data/lib/phusion_passenger/config/utils.rb +95 -95
- data/lib/phusion_passenger/config/validate_install_command.rb +198 -198
- data/lib/phusion_passenger/console_text_template.rb +25 -25
- data/lib/phusion_passenger/constants.rb +90 -90
- data/lib/phusion_passenger/debug_logging.rb +106 -106
- data/lib/phusion_passenger/loader_shared_helpers.rb +447 -432
- data/lib/phusion_passenger/message_channel.rb +312 -312
- data/lib/phusion_passenger/message_client.rb +176 -176
- data/lib/phusion_passenger/native_support.rb +369 -369
- data/lib/phusion_passenger/nginx/config_options.rb +297 -297
- data/lib/phusion_passenger/packaging.rb +131 -131
- data/lib/phusion_passenger/platform_info.rb +360 -360
- data/lib/phusion_passenger/platform_info/apache.rb +767 -767
- data/lib/phusion_passenger/platform_info/apache_detector.rb +199 -199
- data/lib/phusion_passenger/platform_info/binary_compatibility.rb +107 -107
- data/lib/phusion_passenger/platform_info/compiler.rb +570 -570
- data/lib/phusion_passenger/platform_info/curl.rb +32 -32
- data/lib/phusion_passenger/platform_info/cxx_portability.rb +188 -188
- data/lib/phusion_passenger/platform_info/depcheck.rb +372 -372
- data/lib/phusion_passenger/platform_info/depcheck_specs/apache2.rb +109 -109
- data/lib/phusion_passenger/platform_info/depcheck_specs/compiler_toolchain.rb +4 -4
- data/lib/phusion_passenger/platform_info/depcheck_specs/gems.rb +10 -34
- data/lib/phusion_passenger/platform_info/depcheck_specs/libs.rb +101 -101
- data/lib/phusion_passenger/platform_info/depcheck_specs/ruby.rb +5 -5
- data/lib/phusion_passenger/platform_info/depcheck_specs/utilities.rb +13 -13
- data/lib/phusion_passenger/platform_info/linux.rb +55 -55
- data/lib/phusion_passenger/platform_info/operating_system.rb +149 -149
- data/lib/phusion_passenger/platform_info/ruby.rb +468 -448
- data/lib/phusion_passenger/platform_info/zlib.rb +9 -9
- data/lib/phusion_passenger/plugin.rb +66 -66
- data/lib/phusion_passenger/preloader_shared_helpers.rb +126 -126
- data/lib/phusion_passenger/public_api.rb +191 -191
- data/lib/phusion_passenger/rack/out_of_band_gc.rb +93 -94
- data/lib/phusion_passenger/rack/thread_handler_extension.rb +231 -227
- data/lib/phusion_passenger/request_handler.rb +567 -577
- data/lib/phusion_passenger/request_handler/thread_handler.rb +379 -381
- data/lib/phusion_passenger/ruby_core_enhancements.rb +86 -86
- data/lib/phusion_passenger/ruby_core_io_enhancements.rb +74 -74
- data/lib/phusion_passenger/simple_benchmarking.rb +25 -25
- data/lib/phusion_passenger/standalone/app_finder.rb +153 -150
- data/lib/phusion_passenger/standalone/command.rb +44 -40
- data/lib/phusion_passenger/standalone/config_utils.rb +53 -53
- data/lib/phusion_passenger/standalone/control_utils.rb +38 -59
- data/lib/phusion_passenger/standalone/main.rb +73 -73
- data/lib/phusion_passenger/standalone/start_command.rb +697 -685
- data/lib/phusion_passenger/standalone/start_command/builtin_engine.rb +193 -155
- data/lib/phusion_passenger/standalone/start_command/nginx_engine.rb +162 -133
- data/lib/phusion_passenger/standalone/status_command.rb +64 -64
- data/lib/phusion_passenger/standalone/stop_command.rb +72 -72
- data/lib/phusion_passenger/standalone/version_command.rb +9 -9
- data/lib/phusion_passenger/union_station/connection.rb +32 -32
- data/lib/phusion_passenger/union_station/core.rb +251 -251
- data/lib/phusion_passenger/union_station/transaction.rb +126 -126
- data/lib/phusion_passenger/utils.rb +199 -167
- data/lib/phusion_passenger/utils/ansi_colors.rb +128 -128
- data/lib/phusion_passenger/utils/download.rb +196 -196
- data/lib/phusion_passenger/utils/file_system_watcher.rb +158 -158
- data/lib/phusion_passenger/utils/hosts_file_parser.rb +101 -101
- data/lib/phusion_passenger/utils/lock.rb +31 -31
- data/lib/phusion_passenger/utils/native_support_utils.rb +31 -31
- data/lib/phusion_passenger/utils/progress_bar.rb +26 -26
- data/lib/phusion_passenger/utils/shellwords.rb +20 -20
- data/lib/phusion_passenger/utils/terminal_choice_menu.rb +206 -206
- data/lib/phusion_passenger/utils/unseekable_socket.rb +272 -272
- data/lib/phusion_passenger/vendor/crash_watch/app.rb +129 -0
- data/lib/phusion_passenger/vendor/crash_watch/gdb_controller.rb +341 -0
- data/lib/phusion_passenger/vendor/crash_watch/version.rb +24 -0
- data/lib/phusion_passenger/vendor/daemon_controller.rb +877 -0
- data/lib/phusion_passenger/vendor/daemon_controller/lock_file.rb +127 -0
- data/lib/phusion_passenger/vendor/daemon_controller/spawn.rb +26 -0
- data/lib/phusion_passenger/vendor/daemon_controller/version.rb +29 -0
- data/packaging/rpm/passenger_spec/passenger.spec.template +0 -1
- data/passenger.gemspec +0 -1
- data/resources/templates/config/nginx_engine_compiler/possible_solutions_for_download_and_extraction_problems.txt.erb +27 -0
- data/resources/templates/standalone/config.erb +19 -15
- data/test/integration_tests/apache2_tests.rb +566 -566
- data/test/integration_tests/downloaded_binaries_tests.rb +126 -125
- data/test/integration_tests/native_packaging_spec.rb +296 -296
- data/test/integration_tests/nginx_tests.rb +393 -393
- data/test/integration_tests/shared/example_webapp_tests.rb +282 -280
- data/test/integration_tests/source_packaging_test.rb +138 -138
- data/test/integration_tests/spec_helper.rb +5 -5
- data/test/integration_tests/standalone_tests.rb +367 -367
- data/test/ruby/debug_logging_spec.rb +133 -133
- data/test/ruby/message_channel_spec.rb +186 -186
- data/test/ruby/rack/loader_spec.rb +28 -28
- data/test/ruby/rack/preloader_spec.rb +34 -34
- data/test/ruby/rails3.0/loader_spec.rb +12 -12
- data/test/ruby/rails3.0/preloader_spec.rb +18 -18
- data/test/ruby/rails3.1/loader_spec.rb +12 -12
- data/test/ruby/rails3.1/preloader_spec.rb +18 -18
- data/test/ruby/rails3.2/loader_spec.rb +12 -12
- data/test/ruby/rails3.2/preloader_spec.rb +18 -18
- data/test/ruby/rails4.0/loader_spec.rb +12 -12
- data/test/ruby/rails4.0/preloader_spec.rb +18 -18
- data/test/ruby/rails4.1/loader_spec.rb +12 -12
- data/test/ruby/rails4.1/preloader_spec.rb +18 -18
- data/test/ruby/request_handler_spec.rb +730 -730
- data/test/ruby/shared/loader_sharedspec.rb +224 -224
- data/test/ruby/shared/rails/union_station_extensions_sharedspec.rb +327 -327
- data/test/ruby/shared/ruby_loader_sharedspec.rb +47 -47
- data/test/ruby/spec_helper.rb +65 -65
- data/test/ruby/standalone/runtime_installer_spec.rb +384 -384
- data/test/ruby/union_station_spec.rb +276 -276
- data/test/ruby/utils/file_system_watcher_spec.rb +220 -220
- data/test/ruby/utils/hosts_file_parser.rb +248 -248
- data/test/ruby/utils/tee_input_spec.rb +215 -215
- data/test/ruby/utils/unseekable_socket_spec.rb +57 -57
- data/test/ruby/utils_spec.rb +21 -21
- data/test/stub/rack/config.ru +87 -87
- data/test/stub/rack/library.rb +8 -8
- data/test/stub/rack/start.rb +30 -30
- data/test/support/apache2_controller.rb +191 -191
- data/test/support/nginx_controller.rb +90 -99
- data/test/support/placebo-preloader.rb +57 -57
- data/test/support/test_helper.rb +435 -435
- metadata +11 -21
- metadata.gz.asc +7 -7
- data/lib/phusion_passenger/standalone/command2.rb +0 -292
- data/lib/phusion_passenger/standalone/start2_command.rb +0 -799
- data/resources/templates/standalone/download_tool_missing.txt.erb +0 -18
- data/resources/templates/standalone/possible_solutions_for_download_and_extraction_problems.txt.erb +0 -17
- data/resources/templates/standalone/run_installer_as_root.txt.erb +0 -8
@@ -22,41 +22,41 @@
|
|
22
22
|
# THE SOFTWARE.
|
23
23
|
|
24
24
|
module PhusionPassenger
|
25
|
-
module Utils
|
25
|
+
module Utils
|
26
26
|
|
27
|
-
class Lock
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
27
|
+
class Lock
|
28
|
+
def initialize(mutex)
|
29
|
+
@mutex = mutex
|
30
|
+
@locked = false
|
31
|
+
end
|
32
32
|
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
33
|
+
def reset(mutex, lock_now = true)
|
34
|
+
unlock if @locked
|
35
|
+
@mutex = mutex
|
36
|
+
lock if lock_now
|
37
|
+
end
|
38
38
|
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
39
|
+
def synchronize
|
40
|
+
lock if !@locked
|
41
|
+
begin
|
42
|
+
yield(self)
|
43
|
+
ensure
|
44
|
+
unlock if @locked
|
45
|
+
end
|
46
|
+
end
|
47
47
|
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
48
|
+
def lock
|
49
|
+
raise if @locked
|
50
|
+
@mutex.lock
|
51
|
+
@locked = true
|
52
|
+
end
|
53
53
|
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
end
|
54
|
+
def unlock
|
55
|
+
raise if !@locked
|
56
|
+
@mutex.unlock
|
57
|
+
@locked = false
|
58
|
+
end
|
59
|
+
end
|
60
60
|
|
61
|
-
end # module Utils
|
61
|
+
end # module Utils
|
62
62
|
end # module PhusionPassenger
|
@@ -24,42 +24,42 @@
|
|
24
24
|
PhusionPassenger.require_passenger_lib 'native_support'
|
25
25
|
|
26
26
|
module PhusionPassenger
|
27
|
-
module Utils
|
27
|
+
module Utils
|
28
28
|
|
29
|
-
# Utility functions that can potentially be accelerated by native_support functions.
|
30
|
-
module NativeSupportUtils
|
31
|
-
|
29
|
+
# Utility functions that can potentially be accelerated by native_support functions.
|
30
|
+
module NativeSupportUtils
|
31
|
+
extend self
|
32
32
|
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
33
|
+
if defined?(PhusionPassenger::NativeSupport)
|
34
|
+
# Split the given string into an hash. Keys and values are obtained by splitting the
|
35
|
+
# string using the null character as the delimitor.
|
36
|
+
def split_by_null_into_hash(data)
|
37
|
+
return PhusionPassenger::NativeSupport.split_by_null_into_hash(data)
|
38
|
+
end
|
39
39
|
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
40
|
+
# Wrapper for getrusage().
|
41
|
+
def process_times
|
42
|
+
return PhusionPassenger::NativeSupport.process_times
|
43
|
+
end
|
44
|
+
else
|
45
|
+
NULL = "\0".freeze
|
46
46
|
|
47
|
-
|
48
|
-
|
47
|
+
class ProcessTimes < Struct.new(:utime, :stime)
|
48
|
+
end
|
49
49
|
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
50
|
+
def split_by_null_into_hash(data)
|
51
|
+
args = data.split(NULL, -1)
|
52
|
+
args.pop
|
53
|
+
return Hash[*args]
|
54
|
+
end
|
55
55
|
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
end
|
56
|
+
def process_times
|
57
|
+
times = Process.times
|
58
|
+
return ProcessTimes.new((times.utime * 1_000_000).to_i,
|
59
|
+
(times.stime * 1_000_000).to_i)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
63
|
|
64
|
-
end # module Utils
|
64
|
+
end # module Utils
|
65
65
|
end # module PhusionPassenger
|
@@ -23,34 +23,34 @@
|
|
23
23
|
|
24
24
|
module PhusionPassenger
|
25
25
|
|
26
|
-
class ProgressBar
|
27
|
-
|
26
|
+
class ProgressBar
|
27
|
+
THROBBLER = ["-", "\\", "|", "/", "-"]
|
28
28
|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
29
|
+
def initialize(output = STDOUT)
|
30
|
+
@output = output
|
31
|
+
@tty = output.tty?
|
32
|
+
@throbbler_index = 0
|
33
|
+
end
|
34
34
|
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
35
|
+
def set(percentage)
|
36
|
+
if @tty
|
37
|
+
width = (percentage * 50).to_i
|
38
|
+
bar = "*" * width
|
39
|
+
space = " " * (50 - width)
|
40
|
+
text = sprintf("[%s%s] %s", bar, space, THROBBLER[@throbbler_index])
|
41
|
+
@throbbler_index = (@throbbler_index + 1) % THROBBLER.size
|
42
|
+
@output.write("#{text}\r")
|
43
|
+
@output.flush
|
44
|
+
else
|
45
|
+
@output.write(".")
|
46
|
+
@output.flush
|
47
|
+
end
|
48
|
+
end
|
49
49
|
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
end
|
50
|
+
def finish
|
51
|
+
@output.write("\n")
|
52
|
+
@output.flush
|
53
|
+
end
|
54
|
+
end
|
55
55
|
|
56
56
|
end # module PhusionPassenger
|
@@ -3,27 +3,27 @@
|
|
3
3
|
require 'shellwords'
|
4
4
|
|
5
5
|
if !Shellwords.respond_to?(:escape)
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
6
|
+
Shellwords.class_eval do
|
7
|
+
def self.escape(str)
|
8
|
+
# An empty argument will be skipped, so return empty quotes.
|
9
|
+
return "''" if str.empty?
|
10
|
+
str = str.dup
|
11
|
+
# Treat multibyte characters as is. It is caller's responsibility
|
12
|
+
# to encode the string in the right encoding for the shell
|
13
|
+
# environment.
|
14
|
+
str.gsub!(/([^A-Za-z0-9_\-.,:\/@\n])/, "\\\\\\1")
|
15
|
+
# A LF cannot be escaped with a backslash because a backslash + LF
|
16
|
+
# combo is regarded as line continuation and simply ignored.
|
17
|
+
str.gsub!(/\n/, "'\n'")
|
18
|
+
return str
|
19
|
+
end
|
20
|
+
end
|
21
21
|
end
|
22
22
|
|
23
23
|
if !Shellwords.respond_to?(:join)
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
24
|
+
Shellwords.class_eval do
|
25
|
+
def self.join(array)
|
26
|
+
array.map { |arg| escape(arg) }.join(' ')
|
27
|
+
end
|
28
|
+
end
|
29
29
|
end
|
@@ -23,210 +23,210 @@
|
|
23
23
|
# THE SOFTWARE.
|
24
24
|
|
25
25
|
module PhusionPassenger
|
26
|
-
module Utils
|
27
|
-
|
28
|
-
class TerminalChoiceMenu
|
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
|
-
private
|
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
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
end
|
230
|
-
|
231
|
-
end # module Utils
|
26
|
+
module Utils
|
27
|
+
|
28
|
+
class TerminalChoiceMenu
|
29
|
+
class Choice
|
30
|
+
attr_reader :name
|
31
|
+
attr_accessor :checked
|
32
|
+
|
33
|
+
alias checked? checked
|
34
|
+
|
35
|
+
def self.create(choice)
|
36
|
+
if choice.is_a?(Choice)
|
37
|
+
return choice
|
38
|
+
else
|
39
|
+
return Choice.new(choice)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def initialize(name, checked = false)
|
44
|
+
@name = name
|
45
|
+
@checked = checked
|
46
|
+
end
|
47
|
+
|
48
|
+
def toggle!
|
49
|
+
@checked = !@checked
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def initialize(choices)
|
54
|
+
@choices = choices.map { |choice| Choice.create(choice) }
|
55
|
+
@pointer = 0
|
56
|
+
@index = index_choices
|
57
|
+
end
|
58
|
+
|
59
|
+
def display_choices
|
60
|
+
display(render_to_string)
|
61
|
+
end
|
62
|
+
|
63
|
+
def query
|
64
|
+
if STDIN.tty?
|
65
|
+
done = false
|
66
|
+
begin
|
67
|
+
raw_no_echo_mode
|
68
|
+
hide_cursor
|
69
|
+
while !done
|
70
|
+
display_choices
|
71
|
+
done = process_input
|
72
|
+
clear_screen if !done
|
73
|
+
end
|
74
|
+
ensure
|
75
|
+
restore_mode
|
76
|
+
show_cursor
|
77
|
+
puts
|
78
|
+
end
|
79
|
+
else
|
80
|
+
display_choices
|
81
|
+
puts
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
def [](name)
|
86
|
+
return @index[name]
|
87
|
+
end
|
88
|
+
|
89
|
+
def selected_choices
|
90
|
+
@choices.find_all{ |c| c.checked? }.map{ |c| c.name }
|
91
|
+
end
|
92
|
+
|
93
|
+
private
|
94
|
+
JRUBY = defined?(RUBY_ENGINE) && RUBY_ENGINE == 'jruby'
|
95
|
+
|
96
|
+
def index_choices
|
97
|
+
index = {}
|
98
|
+
@choices.each do |choice|
|
99
|
+
index[choice.name] = choice
|
100
|
+
end
|
101
|
+
return index
|
102
|
+
end
|
103
|
+
|
104
|
+
def process_input
|
105
|
+
case getchar(STDIN)
|
106
|
+
when "\x1b"
|
107
|
+
process_cursor_move
|
108
|
+
return false
|
109
|
+
when " "
|
110
|
+
process_toggle
|
111
|
+
return false
|
112
|
+
when "!"
|
113
|
+
process_disable_utf8
|
114
|
+
return false
|
115
|
+
when "\r"
|
116
|
+
return true
|
117
|
+
else
|
118
|
+
return false
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
def process_cursor_move
|
123
|
+
if getchar(STDIN) == "["
|
124
|
+
case getchar(STDIN)
|
125
|
+
when "A" # up
|
126
|
+
@pointer = [@pointer - 1, 0].max
|
127
|
+
when "B" # down
|
128
|
+
@pointer = [@pointer + 1, @choices.size - 1].min
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
def process_toggle
|
134
|
+
@choices[@pointer].toggle!
|
135
|
+
end
|
136
|
+
|
137
|
+
def process_disable_utf8
|
138
|
+
ENV['UTF8_MENUS'] = '0'
|
139
|
+
end
|
140
|
+
|
141
|
+
def render_to_string
|
142
|
+
str = ""
|
143
|
+
@choices.each_with_index do |choice, i|
|
144
|
+
pointer = render_pointer(i)
|
145
|
+
checkbox = render_checkbox(choice.checked)
|
146
|
+
str << " #{pointer} #{checkbox} #{choice.name}\r\n"
|
147
|
+
end
|
148
|
+
str.chomp!
|
149
|
+
return str
|
150
|
+
end
|
151
|
+
|
152
|
+
def render_pointer(index)
|
153
|
+
return @pointer == index ? maybe_utf8("‣", ">") : " "
|
154
|
+
end
|
155
|
+
|
156
|
+
def render_checkbox(checked)
|
157
|
+
return checked ? maybe_utf8("⬢", "(*)") : maybe_utf8("⬡", "( )")
|
158
|
+
end
|
159
|
+
|
160
|
+
def display(str)
|
161
|
+
STDOUT.write(str)
|
162
|
+
STDOUT.flush
|
163
|
+
end
|
164
|
+
|
165
|
+
def clear_screen
|
166
|
+
number_of_lines = render_to_string.split("\n").size
|
167
|
+
display("\r")
|
168
|
+
(number_of_lines - 1).times do
|
169
|
+
display(move_up)
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
def maybe_utf8(utf8, plain)
|
174
|
+
if ENV['UTF8_MENUS'] == '0'
|
175
|
+
return plain
|
176
|
+
else
|
177
|
+
return utf8
|
178
|
+
end
|
179
|
+
end
|
180
|
+
|
181
|
+
def hide_cursor
|
182
|
+
display("\x1b[?25l")
|
183
|
+
end
|
184
|
+
|
185
|
+
def show_cursor
|
186
|
+
display("\x1b[?25h")
|
187
|
+
end
|
188
|
+
|
189
|
+
def move_up
|
190
|
+
return "\x1b[0A"
|
191
|
+
end
|
192
|
+
|
193
|
+
def getchar(io)
|
194
|
+
char = io.getc
|
195
|
+
char = char.chr if char.is_a?(Integer)
|
196
|
+
return char
|
197
|
+
end
|
198
|
+
|
199
|
+
if JRUBY
|
200
|
+
require 'java'
|
201
|
+
require 'readline'
|
202
|
+
java_import 'jline.console.ConsoleReader'
|
203
|
+
|
204
|
+
def raw_no_echo_mode
|
205
|
+
input = STDIN.to_inputstream
|
206
|
+
output = STDOUT.to_outputstream
|
207
|
+
@console = ConsoleReader.new(input, output)
|
208
|
+
@console.set_history_enabled(false)
|
209
|
+
@console.set_bell_enabled(true)
|
210
|
+
@console.set_pagination_enabled(false)
|
211
|
+
@terminal_state = @console.getEchoCharacter
|
212
|
+
@console.setEchoCharacter(0)
|
213
|
+
end
|
214
|
+
|
215
|
+
def restore_mode
|
216
|
+
@console.setEchoCharacter(@terminal_state)
|
217
|
+
@console.get_terminal.restore
|
218
|
+
end
|
219
|
+
else
|
220
|
+
def raw_no_echo_mode
|
221
|
+
@terminal_state = `stty -g`
|
222
|
+
system("stty raw -echo -icanon isig")
|
223
|
+
end
|
224
|
+
|
225
|
+
def restore_mode
|
226
|
+
system("stty #{@terminal_state}")
|
227
|
+
end
|
228
|
+
end
|
229
|
+
end
|
230
|
+
|
231
|
+
end # module Utils
|
232
232
|
end # module PhusionPassenger
|