oop_rails_server 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: b764225db8990e99a3727eec3d2252c3c9b857d9
4
+ data.tar.gz: 2ba96b68047a98c91fa77f39a050870cff565f59
5
+ SHA512:
6
+ metadata.gz: 86b2cfed985bf6457e069d085bb97e00a01cc52e3ae4d4331d737ba7d982a41e668797c0c926bf174061de04d7e80ea50d7e7846639ad4ce0be6ca0b8ebb8375
7
+ data.tar.gz: 02c1ed8ee642d24224e90e358576fb8184922f06797a029b357052bd5856dc5ea4f4d72e25400610c414593ea12758ca5535618512226cc1a569a1ac8c4beba6
data/.gitignore ADDED
@@ -0,0 +1,14 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ *.bundle
11
+ *.so
12
+ *.o
13
+ *.a
14
+ mkmf.log
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in oop_rails_server.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Andrew Geweke
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,31 @@
1
+ # OopRailsServer
2
+
3
+ TODO: Write a gem description
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ ```ruby
10
+ gem 'oop_rails_server'
11
+ ```
12
+
13
+ And then execute:
14
+
15
+ $ bundle
16
+
17
+ Or install it yourself as:
18
+
19
+ $ gem install oop_rails_server
20
+
21
+ ## Usage
22
+
23
+ TODO: Write usage instructions here
24
+
25
+ ## Contributing
26
+
27
+ 1. Fork it ( https://github.com/[my-github-username]/oop_rails_server/fork )
28
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
29
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
30
+ 4. Push to the branch (`git push origin my-new-feature`)
31
+ 5. Create a new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ require "bundler/gem_tasks"
2
+
@@ -0,0 +1,163 @@
1
+ require 'active_support'
2
+ require 'json'
3
+ require 'oop_rails_server/rails_server'
4
+
5
+ module OopRailsServer
6
+ module Helpers
7
+ extend ActiveSupport::Concern
8
+
9
+ attr_reader :rails_server
10
+
11
+
12
+ def full_path(subpath)
13
+ "#{rails_template_name}/#{subpath}"
14
+ end
15
+
16
+ def get(subpath, options = { })
17
+ rails_server.get(full_path(subpath), options)
18
+ end
19
+
20
+ def get_response(subpath, options = { })
21
+ rails_server.get_response(full_path(subpath), options)
22
+ end
23
+
24
+ def get_success(subpath, options = { })
25
+ data = get(subpath, options)
26
+ data.should match(/rails_spec_application/i) unless options[:no_layout]
27
+ data
28
+ end
29
+
30
+ def expect_match(subpath, *args)
31
+ options = args.extract_options!
32
+ regexes = args
33
+
34
+ data = get_success(subpath, options)
35
+ regexes.each do |regex|
36
+ data.should match(regex)
37
+ end
38
+
39
+ data
40
+ end
41
+
42
+ def expect_exception(subpath, class_name, message)
43
+ data = get(subpath)
44
+
45
+ json = begin
46
+ JSON.parse(data)
47
+ rescue => e
48
+ raise %{Expected a JSON response from '#{subpath}' (because we expected an exception),
49
+ but we couldn't parse it as JSON; when we tried, we got:
50
+
51
+ (#{e.class.name}) #{e.message}
52
+
53
+ The data is:
54
+
55
+ #{data.inspect}}
56
+ end
57
+
58
+ json['exception'].should be
59
+ json['exception']['class'].should == class_name.to_s
60
+ json['exception']['message'].should match(message)
61
+ end
62
+
63
+ def rails_template_name
64
+ rails_server.name
65
+ end
66
+
67
+ def rails_server_project_root
68
+ raise %{You must override #rails_server_project_root in this class (#{self.class.name}) to use OopRailsServer::Helpers;
69
+ it should return the fully-qualified path to the root of your project (gem, application, or whatever).}
70
+ end
71
+
72
+ def rails_server_templates_root
73
+ @rails_server_templates_root ||= File.join(rails_server_project_root, "spec/rails/templates")
74
+ end
75
+
76
+ def rails_server_runtime_base_directory
77
+ @rails_server_runtime_base_directory ||= File.join(rails_server_project_root, "tmp/spec/rails")
78
+ end
79
+
80
+ def rails_server_additional_gemfile_lines
81
+ [
82
+ "gem 'fortitude', :path => '#{rails_server_project_root}'"
83
+ ]
84
+ end
85
+
86
+ def rails_server_default_version
87
+ ENV['FORTITUDE_SPECS_RAILS_VERSION']
88
+ end
89
+
90
+ def rails_servers
91
+ @rails_servers ||= { }
92
+ end
93
+
94
+ def rails_server
95
+ if rails_servers.size == 1
96
+ rails_servers[rails_servers.keys.first]
97
+ elsif rails_servers.size == 0
98
+ raise "No Rails servers have been started!"
99
+ else
100
+ raise "Multiple Rails servers have been started; you must specify which one you want: #{rails_servers.keys.join(", ")}"
101
+ end
102
+ end
103
+
104
+ def start_rails_server!(options = { })
105
+ templates = Array(options[:templates] || options[:name] || [ ])
106
+ raise "You must specify a template" unless templates.length >= 1
107
+
108
+ name = options[:name]
109
+ name ||= templates[0] if templates.length == 1
110
+ name = name.to_s.strip
111
+ raise "You must specify a name" unless name && name.to_s.strip.length > 0
112
+
113
+ server = rails_servers[name]
114
+ server ||= begin
115
+ templates = [ 'base' ] + templates unless options[:skip_base_template]
116
+
117
+ template_paths = templates.map do |t|
118
+ File.join(rails_server_templates_root, t.to_s)
119
+ end
120
+
121
+ additional_gemfile_lines = Array(rails_server_additional_gemfile_lines || [ ])
122
+ additional_gemfile_lines += Array(options[:additional_gemfile_lines] || [ ])
123
+
124
+ server = ::OopRailsServer::RailsServer.new(
125
+ :name => name, :template_paths => template_paths,
126
+ :runtime_base_directory => rails_server_runtime_base_directory,
127
+ :rails_version => (options[:rails_version] || rails_server_default_version),
128
+ :rails_env => options[:rails_env], :additional_gemfile_lines => additional_gemfile_lines)
129
+
130
+ rails_servers[name] = server
131
+
132
+ server
133
+ end
134
+
135
+ server.start!
136
+ end
137
+
138
+ def stop_rails_servers!
139
+ exceptions = [ ]
140
+ rails_servers.each do |name, server|
141
+ begin
142
+ server.stop!
143
+ rescue => e
144
+ exceptions << [ name, e ]
145
+ end
146
+ end
147
+
148
+ raise "Unable to stop all Rails servers! Got:\n#{exceptions.join("\n")}" if exceptions.length > 0
149
+ end
150
+
151
+ module ClassMethods
152
+ def uses_rails_with_template(template_name, options = { })
153
+ before :all do
154
+ start_rails_server!({ :templates => [ template_name ] }.merge(options))
155
+ end
156
+
157
+ after :all do
158
+ stop_rails_servers!
159
+ end
160
+ end
161
+ end
162
+ end
163
+ end
@@ -0,0 +1,378 @@
1
+ require 'fileutils'
2
+ require 'find'
3
+ require 'net/http'
4
+ require 'uri'
5
+
6
+ module OopRailsServer
7
+ class RailsServer
8
+ attr_reader :rails_root, :rails_version, :name
9
+
10
+ def initialize(options)
11
+ options.assert_valid_keys(
12
+ :name, :template_paths, :runtime_base_directory,
13
+ :rails_version, :rails_env, :additional_gemfile_lines
14
+ )
15
+
16
+ @name = options[:name] || raise(ArgumentError, "You must specify a name for the Rails server")
17
+
18
+ @template_paths = options[:template_paths] || raise(ArgumentError, "You must specify one or more template paths")
19
+ @template_paths = Array(@template_paths).map { |t| File.expand_path(t) }
20
+
21
+ @runtime_base_directory = options[:runtime_base_directory] || raise(ArgumentError, "You must specify a runtime_base_directory")
22
+ @runtime_base_directory = File.expand_path(@runtime_base_directory)
23
+
24
+ @rails_version = options[:rails_version] || :default
25
+ @rails_env = (options[:rails_env] || 'production').to_s
26
+
27
+ @additional_gemfile_lines = Array(options[:additional_gemfile_lines] || [ ])
28
+
29
+
30
+ @rails_root = File.join(@runtime_base_directory, rails_version.to_s, name.to_s)
31
+ @port = 20_000 + rand(10_000)
32
+ @server_pid = nil
33
+ end
34
+
35
+ def start!
36
+ do_start! unless server_pid
37
+ end
38
+
39
+ def stop!
40
+ stop_server! if server_pid
41
+ end
42
+
43
+ def get(path, options = { })
44
+ get_response(path, options).body.strip
45
+ end
46
+
47
+ def uri_for(path)
48
+ uri_string = "http://localhost:#{@port}/#{path}"
49
+ URI.parse(uri_string)
50
+ end
51
+
52
+ def get_response(path, options = { })
53
+ uri = uri_for(path)
54
+ data = Net::HTTP.get_response(uri)
55
+ unless data.code.to_s == '200' || options[:ignore_status_code]
56
+ raise "'#{uri}' returned #{data.code.inspect}, not 200; body was: #{data.body.strip}"
57
+ end
58
+ data
59
+ end
60
+
61
+ private
62
+ attr_reader :template_paths, :runtime_base_directory, :rails_env, :additional_gemfile_lines, :port, :server_pid
63
+
64
+ def do_start!
65
+ Bundler.with_clean_env do
66
+ with_rails_env do
67
+ setup_directories!
68
+
69
+ in_rails_root_parent do
70
+ splat_bootstrap_gemfile!
71
+ rails_new!
72
+ update_gemfile!
73
+ end
74
+
75
+ in_rails_root do
76
+ run_bundle_install!(:primary)
77
+ splat_template_files!
78
+ start_server!
79
+ verify_server!
80
+ end
81
+ end
82
+ end
83
+ end
84
+
85
+ def with_rails_env
86
+ old_rails_env = ENV['RAILS_ENV']
87
+ begin
88
+ ENV['RAILS_ENV'] = rails_env
89
+ yield
90
+ ensure
91
+ ENV['RAILS_ENV'] = old_rails_env
92
+ end
93
+ end
94
+
95
+
96
+ def setup_directories!
97
+ return if @directories_setup
98
+
99
+ template_paths.each do |template_path|
100
+ raise Errno::ENOENT, "You must specify template paths that exist; this doesn't: '#{template_path}'" unless File.directory?(template_path)
101
+ end
102
+ FileUtils.rm_rf(rails_root) if File.exist?(rails_root)
103
+ FileUtils.mkdir_p(rails_root)
104
+
105
+ @directories_setup = true
106
+ end
107
+
108
+ def in_rails_root(&block)
109
+ Dir.chdir(rails_root, &block)
110
+ end
111
+
112
+ def in_rails_root_parent(&block)
113
+ Dir.chdir(File.dirname(rails_root), &block)
114
+ end
115
+
116
+ def splat_bootstrap_gemfile!
117
+ File.open("Gemfile", "w") do |f|
118
+ rails_version_spec = if rails_version == :default then "" else ", \"= #{rails_version}\"" end
119
+ f << <<-EOS
120
+ source 'https://rubygems.org'
121
+
122
+ gem 'rails'#{rails_version_spec}
123
+ EOS
124
+ end
125
+
126
+ run_bundle_install!(:bootstrap)
127
+ end
128
+
129
+ def rails_new!
130
+ # This is a little trick to specify the exact version of Rails you want to create it with...
131
+ # http://stackoverflow.com/questions/379141/specifying-rails-version-to-use-when-creating-a-new-application
132
+ rails_version_spec = rails_version == :default ? "" : "_#{rails_version}_"
133
+ cmd = "bundle exec rails #{rails_version_spec} new #{File.basename(rails_root)} -d sqlite3 -f -B"
134
+ safe_system(cmd, "creating a new Rails installation for '#{name}'")
135
+ end
136
+
137
+ def update_gemfile!
138
+ gemfile = File.join(rails_root, 'Gemfile')
139
+ gemfile_contents = File.read(gemfile)
140
+
141
+ # Since Rails 3.0.20 was released, a new version of the I18n gem, 0.5.2, was released that moves a constant
142
+ # into a different namespace. (See https://github.com/mislav/will_paginate/issues/347 for more details.)
143
+ # So, if we're running Rails 3.0.x, we lock the 'i18n' gem to an earlier version.
144
+ gemfile_contents << "\ngem 'i18n', '= 0.5.0'\n" if rails_version && rails_version =~ /^3\.0\./
145
+
146
+ # Apparently execjs released a version 2.2.0 that will happily install on Ruby 1.8.7, but which contains some
147
+ # new-style hash syntax. As a result, we pin the version backwards in this one specific case.
148
+ gemfile_contents << "\ngem 'execjs', '~> 2.0.0'\n" if RUBY_VERSION =~ /^1\.8\./
149
+
150
+ gemfile_contents << additional_gemfile_lines.join("\n")
151
+
152
+ File.open(gemfile, 'w') { |f| f << gemfile_contents }
153
+ end
154
+
155
+ def with_env(new_env)
156
+ old_env = { }
157
+ new_env.keys.each { |k| old_env[k] = ENV[k] }
158
+
159
+ begin
160
+ set_env(new_env)
161
+ yield
162
+ ensure
163
+ set_env(old_env)
164
+ end
165
+ end
166
+
167
+ def set_env(new_env)
168
+ new_env.each do |k,v|
169
+ if v
170
+ ENV[k] = v
171
+ else
172
+ ENV.delete(k)
173
+ end
174
+ end
175
+ end
176
+
177
+ def splat_template_files!
178
+ @template_paths.each do |template_path|
179
+ Find.find(template_path) do |file|
180
+ next unless File.file?(file)
181
+
182
+ if file[0..(template_path.length)] == "#{template_path}/"
183
+ subpath = file[(template_path.length + 1)..-1]
184
+ else
185
+ raise "#{file} isn't under #{template_path}?!?"
186
+ end
187
+ dest_file = File.join(rails_root, subpath)
188
+
189
+ FileUtils.mkdir_p(File.dirname(dest_file))
190
+ FileUtils.cp(file, dest_file)
191
+ end
192
+ end
193
+ end
194
+
195
+ def start_server!
196
+ output = File.join(rails_root, 'log', 'rails-server.out')
197
+ cmd = "rails server -p #{port} > '#{output}'"
198
+ safe_system(cmd, "starting 'rails server' on port #{port}", :background => true)
199
+
200
+ server_pid_file = File.join(rails_root, 'tmp', 'pids', 'server.pid')
201
+
202
+ start_time = Time.now
203
+ while Time.now < start_time + 15
204
+ if File.exist?(server_pid_file)
205
+ server_pid = File.read(server_pid_file).strip
206
+ if server_pid =~ /^(\d{1,10})$/i
207
+ @server_pid = Integer(server_pid)
208
+ break
209
+ end
210
+ end
211
+ sleep 0.1
212
+ end
213
+ end
214
+
215
+ def verify_server!
216
+ server_verify_url = "http://localhost:#{port}/working/rails_is_working"
217
+ uri = URI.parse(server_verify_url)
218
+
219
+ data = nil
220
+ start_time = Time.now
221
+ while (! data)
222
+ begin
223
+ data = Net::HTTP.get_response(uri)
224
+ rescue Errno::ECONNREFUSED, EOFError
225
+ raise if Time.now > (start_time + 20)
226
+ # keep waiting
227
+ sleep 0.1
228
+ end
229
+ end
230
+
231
+ unless data.code.to_s == '200'
232
+ raise "'#{server_verify_url}' returned #{data.code.inspect}, not 200"
233
+ end
234
+ result = data.body.strip
235
+
236
+ unless result =~ /^Rails\s+version\s*:\s*(\d+\.\d+\.\d+)$/
237
+ raise "'#{server_verify_url}' returned: #{result.inspect}"
238
+ end
239
+ actual_version = $1
240
+
241
+ if rails_version != :default && (actual_version != rails_version)
242
+ raise "We seem to have spawned the wrong version of Rails; wanted: #{rails_version.inspect} but got: #{actual_version.inspect}"
243
+ end
244
+
245
+ say "Successfully spawned a server running Rails #{actual_version} on port #{port}."
246
+ end
247
+
248
+ def is_alive?(pid)
249
+ cmd = "ps -o pid #{pid}"
250
+ results = `#{cmd}`
251
+ results.split(/[\r\n]+/).each do |line|
252
+ line = line.strip.downcase
253
+ next if line == 'pid'
254
+ if line =~ /^\d+$/i
255
+ return true if Integer(line) == pid
256
+ else
257
+ raise "Unexpected output from '#{cmd}': #{results}"
258
+ end
259
+ end
260
+
261
+ false
262
+ end
263
+
264
+ def stop_server!
265
+ # We do this because under 1.8.7 SIGTERM doesn't seem to work, and it's actually fine to slaughter this
266
+ # process mercilessly -- we don't need anything it has at this point, anyway.
267
+ Process.kill("KILL", server_pid)
268
+
269
+ start_time = Time.now
270
+
271
+ while true
272
+ if is_alive?(server_pid)
273
+ raise "Unable to kill server at PID #{server_pid}!" if (Time.now - start_time) > 20
274
+ say "Waiting for server at PID #{server_pid} to die."
275
+ sleep 0.1
276
+ else
277
+ break
278
+ end
279
+ end
280
+
281
+ say "Successfully terminated Rails server at PID #{server_pid}."
282
+
283
+ @server_pid = nil
284
+ end
285
+
286
+ class CommandFailedError < StandardError
287
+ attr_reader :directory, :command, :result, :output
288
+
289
+ def initialize(directory, command, result, output)
290
+ @directory = directory
291
+ @command = command
292
+ @result = result
293
+ @output = output
294
+
295
+ super(%{Command failed: in directory '#{directory}', we tried to run:
296
+ % #{command}
297
+ but got result: #{result.inspect}
298
+ and output:
299
+ #{output}})
300
+ end
301
+ end
302
+
303
+ def attempt_bundle_install_cmd!(name, use_local)
304
+ cmd = "bundle install"
305
+ cmd << " --local" if use_local
306
+
307
+ description = "running 'bundle install' for #{name.inspect}"
308
+ description << " (with remote fetching allowed)" if (! use_local)
309
+
310
+ attempts = 0
311
+ while true
312
+ begin
313
+ safe_system(cmd, description)
314
+ break
315
+ rescue CommandFailedError => cfe
316
+ # Sigh. Travis CI sometimes fails this with the following exception:
317
+ #
318
+ # Gem::RemoteFetcher::FetchError: Errno::ETIMEDOUT: Connection timed out - connect(2)
319
+ #
320
+ # So, we catch the command failure, look to see if this is the problem, and, if so, retry
321
+ raise if (! is_travis_remote_fetcher_error?(cfe)) || attempts >= 5
322
+ attempts += 1
323
+ end
324
+ end
325
+ end
326
+
327
+ def is_travis_remote_fetcher_error?(command_failed_error)
328
+ command_failed_error.output =~ /Gem::RemoteFetcher::FetchError.*connect/i
329
+ end
330
+
331
+ def is_remote_flag_required_error?(command_failed_error)
332
+ command_failed_error.output =~ /could\s+not\s+find.*in\s+the\s+gems\s+available\s+on\s+this\s+machine/i
333
+ end
334
+
335
+ def do_bundle_install!(name, allow_remote)
336
+ begin
337
+ attempt_bundle_install_cmd!(name, true)
338
+ rescue CommandFailedError => cfe
339
+ if is_remote_flag_required_error?(cfe) && allow_remote
340
+ attempt_bundle_install_cmd!(name, false)
341
+ else
342
+ raise
343
+ end
344
+ end
345
+ end
346
+
347
+ def run_bundle_install!(name)
348
+ @bundle_installs_run ||= { }
349
+ do_bundle_install!(name, ! @bundle_installs_run[name])
350
+ @bundle_installs_run[name] ||= true
351
+ end
352
+
353
+ def say(s, newline = true)
354
+ if newline
355
+ $stdout.puts s
356
+ else
357
+ $stdout << s
358
+ end
359
+ $stdout.flush
360
+ end
361
+
362
+ def safe_system(cmd, notice = nil, options = { })
363
+ say("#{notice}...", false) if notice
364
+
365
+ total_cmd = if options[:background]
366
+ "#{cmd} 2>&1 &"
367
+ else
368
+ "#{cmd} 2>&1"
369
+ end
370
+
371
+ output = `#{total_cmd}`
372
+ raise CommandFailedError.new(Dir.pwd, total_cmd, $?, output) unless $?.success?
373
+ say "OK" if notice
374
+
375
+ output
376
+ end
377
+ end
378
+ end
@@ -0,0 +1,3 @@
1
+ module OopRailsServer
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,3 @@
1
+ require "oop_rails_server/version"
2
+ require "oop_rails_server/rails_server"
3
+ require "oop_rails_server/helpers"
@@ -0,0 +1,22 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'oop_rails_server/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "oop_rails_server"
8
+ spec.version = OopRailsServer::VERSION
9
+ spec.authors = ["Andrew Geweke"]
10
+ spec.email = ["andrew@geweke.org"]
11
+ spec.summary = %q{Reliably runs a Rails server in a separate process, for use in tests, utilities, etc.}
12
+ spec.homepage = "https://github.com/ageweke/oop_rails_server"
13
+ spec.license = "MIT"
14
+
15
+ spec.files = `git ls-files -z`.split("\x0")
16
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
17
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
18
+ spec.require_paths = ["lib"]
19
+
20
+ spec.add_development_dependency "bundler", "~> 1.6"
21
+ spec.add_development_dependency "rake", "~> 10.0"
22
+ end
metadata ADDED
@@ -0,0 +1,83 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: oop_rails_server
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Andrew Geweke
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-11-05 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.6'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.6'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ description:
42
+ email:
43
+ - andrew@geweke.org
44
+ executables: []
45
+ extensions: []
46
+ extra_rdoc_files: []
47
+ files:
48
+ - ".gitignore"
49
+ - Gemfile
50
+ - LICENSE.txt
51
+ - README.md
52
+ - Rakefile
53
+ - lib/oop_rails_server.rb
54
+ - lib/oop_rails_server/helpers.rb
55
+ - lib/oop_rails_server/rails_server.rb
56
+ - lib/oop_rails_server/version.rb
57
+ - oop_rails_server.gemspec
58
+ homepage: https://github.com/ageweke/oop_rails_server
59
+ licenses:
60
+ - MIT
61
+ metadata: {}
62
+ post_install_message:
63
+ rdoc_options: []
64
+ require_paths:
65
+ - lib
66
+ required_ruby_version: !ruby/object:Gem::Requirement
67
+ requirements:
68
+ - - ">="
69
+ - !ruby/object:Gem::Version
70
+ version: '0'
71
+ required_rubygems_version: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ requirements: []
77
+ rubyforge_project:
78
+ rubygems_version: 2.2.2
79
+ signing_key:
80
+ specification_version: 4
81
+ summary: Reliably runs a Rails server in a separate process, for use in tests, utilities,
82
+ etc.
83
+ test_files: []