-
Notifications
You must be signed in to change notification settings - Fork 81
/
server.rb
184 lines (168 loc) · 6.92 KB
/
server.rb
1
2
3
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
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
# coding: utf-8
require 'socket'
require 'timeout'
require 'childprocess'
require 'jasmine'
require 'guard/compat/plugin'
module Guard
class Jasmine < Plugin
# Start and stop a Jasmine test server for requesting the specs
# from PhantomJS.
#
module Server
class << self
attr_accessor :process, :cmd
# Start the internal test server for getting the Jasmine runner.
#
# @param [Hash] options the server options
# @option options [String] server the server to use
# @option options [Number] port the server port
# @option options [String] server_env the Rails environment
# @option options [Number] server_timeout the server start timeout
# @option options [String] spec_dir the spec directory
# @option options [String] rackup_config custom rackup config to use (i.e. spec/dummy/config.ru for mountable engines)
#
def start(options)
port = options[:port]
case options[:server]
when :webrick, :mongrel, :thin, :puma
start_rack_server(options[:server], port, options)
when :unicorn
start_unicorn_server(port, options)
when :jasmine_gem
start_rake_server(port, 'jasmine', options)
when :none # noop
else
start_rake_server(port, options[:server], options)
end
wait_for_server(port, options[:server_timeout]) unless options[:server] == :none
end
# Stop the server thread.
#
def stop
return unless process
Compat::UI.info 'Guard::Jasmine stops server.'
process.stop(5)
end
# A port was not specified, therefore we attempt to detect the best port to use
# @param [Hash] options the server options
# @option options [Symbol] server the rack server to use
# @return [Integer] port number
def choose_server_port(options)
if options[:server] == :jasmine_gem
::Jasmine.config.port(:server)
else
::Guard::Jasmine.find_free_server_port
end
end
# Detect the server to use
#
# @param [String] spec_dir the spec directory
# @return [Symbol] the server strategy
#
def detect_server(spec_dir)
if spec_dir && File.exist?(File.join(spec_dir, 'support', 'jasmine.yml'))
:jasmine_gem
elsif File.exist?('config.ru')
%w(unicorn thin mongrel puma).each do |server|
begin
require server
return server.to_sym
rescue LoadError
# Ignore missing server and try next
end
end
:webrick
else
:none
end
end
private
# Start the Rack server of the current project. This
# will simply start a server that uses the `config.ru`
# in the current directory.
#
# @param [Symbol] server the server name
# @param [Integer] port the server port
# @param [Hash] options the server options
# @option options [Symbol] server the rack server to use
# @option options [String] server_env the Rails environment
# @option options [String] rackup_config custom rackup config to use (i.e. spec/dummy/config.ru for mountable engines)
#
def start_rack_server(server, port, options)
coverage = options[:coverage] ? 'on' : 'off'
Compat::UI.info "Guard::Jasmine starts #{server} spec server on port #{port} in #{options[:server_env]} environment (coverage #{coverage})."
execute(options, ['rackup', '-E', options[:server_env].to_s, '-p', port.to_s, '-s', server.to_s, options[:rackup_config]])
end
# Start the Rack server of the current project. This
# will simply start a server that uses the `config.ru`
# in the current directory.
#
# @param [Hash] options the server options
# @option options [String] server_env the Rails environment
# @option options [Number] port the server port
#
def start_unicorn_server(port, options)
coverage = options[:coverage] ? 'on' : 'off'
Compat::UI.info "Guard::Jasmine starts Unicorn spec server on port #{port} in #{options[:server_env]} environment (coverage #{coverage})."
execute(options, ['unicorn_rails', '-E', options[:server_env].to_s, '-p', port.to_s])
end
# Start the Jasmine gem server of the current project.
#
# @param [Number] port the server port
# @param [String] task the rake task name
# @option options [Symbol] server the rack server to use
#
def start_rake_server(port, task, options)
Compat::UI.info "Guard::Jasmine starts Jasmine Gem test server on port #{port}."
execute(options, ['rake', task])
end
# Builds a child process with the given command and arguments
# @param [Array<string>] array of arguments to send to ChildProcess
def execute(options, cmd)
if RUBY_PLATFORM == "java"
cmd.unshift("jruby", "-S")
else
cmd.unshift("ruby", "-S")
end
self.cmd = cmd
puts "Starting server using: #{cmd.join(' ')}" if options[:debug]
self.process = ChildProcess.build(*cmd.compact)
process.environment['COVERAGE'] = options[:coverage].to_s
process.environment['IGNORE_INSTRUMENTATION'] = options[:ignore_instrumentation].to_s
process.io.inherit! if options[:verbose]
process.start
rescue => e
Compat::UI.error "Cannot start server using command #{cmd.join(' ')}."
Compat::UI.error "Error was: #{e.message}"
end
# Wait until the Jasmine test server is running.
#
# @param [Number] port the server port
# @param [Number] timeout the server wait timeout
#
def wait_for_server(port, timeout)
Timeout.timeout(timeout) do
loop do
begin
::TCPSocket.new('localhost', port).close
break
rescue Errno::ECONNREFUSED, Errno::EHOSTUNREACH
# Ignore, server still not available
end
sleep 0.1
end
end
rescue Timeout::Error
Compat::UI.warning "Timeout while waiting for the server to startup"
Compat::UI.warning "Most likely there is a configuration error that's preventing the server from starting"
Compat::UI.warning "You may need to increase the `:server_timeout` option."
Compat::UI.warning "The commandline that was used to start the server was:"
Compat::UI.warning cmd.join(' ')
Compat::UI.warning "You should attempt to run that and see if any errors occur"
throw :task_has_failed
end
end
end
end
end