engineyard-serverside 1.4.3.nodestack → 1.4.7.pre
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/lib/core-ext/README.md +3 -0
- data/lib/core-ext/string.rb +9 -0
- data/lib/engineyard-serverside.rb +3 -1
- data/lib/engineyard-serverside/cli.rb +3 -2
- data/lib/engineyard-serverside/configuration.rb +1 -1
- data/lib/engineyard-serverside/deploy.rb +117 -23
- data/lib/engineyard-serverside/lockfile_parser.rb +3 -3
- data/lib/engineyard-serverside/logged_output.rb +0 -5
- data/lib/engineyard-serverside/task.rb +1 -0
- data/lib/engineyard-serverside/version.rb +1 -1
- data/lib/vendor/ruby_1.8.6_openssl.patch +7 -0
- data/spec/custom_deploy_spec.rb +14 -7
- data/spec/fixtures/gemfiles/activerecord_jdbcmysql/Gemfile +5 -0
- data/spec/fixtures/gemfiles/activerecord_jdbcmysql/Gemfile.lock +29 -0
- data/spec/fixtures/gemfiles/activerecord_jdbcpostgresql/Gemfile +5 -0
- data/spec/fixtures/gemfiles/activerecord_jdbcpostgresql/Gemfile.lock +29 -0
- data/spec/fixtures/gemfiles/activerecord_mysql/Gemfile +5 -0
- data/spec/fixtures/gemfiles/activerecord_mysql/Gemfile.lock +25 -0
- data/spec/fixtures/gemfiles/activerecord_mysql2/Gemfile +5 -0
- data/spec/fixtures/gemfiles/activerecord_mysql2/Gemfile.lock +25 -0
- data/spec/fixtures/gemfiles/activerecord_pg/Gemfile +5 -0
- data/spec/fixtures/gemfiles/activerecord_pg/Gemfile.lock +25 -0
- data/spec/fixtures/gemfiles/activerecord_sqlite3/Gemfile +5 -0
- data/spec/fixtures/gemfiles/activerecord_sqlite3/Gemfile.lock +25 -0
- data/spec/fixtures/gemfiles/diy_database_yml/Gemfile +5 -0
- data/spec/fixtures/gemfiles/diy_database_yml/Gemfile.lock +25 -0
- data/spec/fixtures/gemfiles/diy_database_yml/config/database.yml +7 -0
- data/spec/generate_configs_spec.rb +228 -0
- data/spec/lib/full_test_deploy.rb +86 -0
- data/spec/real_deploy_spec.rb +42 -121
- data/spec/spec_helper.rb +62 -1
- metadata +75 -9
- data/spec/fixtures/gitrepo/bar +0 -0
@@ -0,0 +1,9 @@
|
|
1
|
+
# methods for String that aren't available in ruby 1.8.6 (used by ey_resin)
|
2
|
+
# versions here are just workarounds
|
3
|
+
# FIXME remove this module when ey_resin (and .rvmrc) updated to ruby 1.8.7 or 1.9.2
|
4
|
+
module ModernString
|
5
|
+
def start_with?(prefix)
|
6
|
+
self.index(prefix) == 0
|
7
|
+
end
|
8
|
+
end
|
9
|
+
String.send(:include, ModernString)
|
@@ -4,6 +4,8 @@ $LOAD_PATH.unshift File.expand_path('vendor/escape/lib', File.dirname(__FILE__))
|
|
4
4
|
$LOAD_PATH.unshift File.expand_path('vendor/json_pure/lib', File.dirname(__FILE__))
|
5
5
|
$LOAD_PATH.unshift File.expand_path('vendor/dataflow', File.dirname(__FILE__))
|
6
6
|
|
7
|
+
require 'core-ext/string' if RUBY_VERSION == '1.8.6'
|
8
|
+
|
7
9
|
require 'escape'
|
8
10
|
require 'json'
|
9
11
|
require 'dataflow'
|
@@ -34,7 +36,7 @@ module EY
|
|
34
36
|
{}.to_json
|
35
37
|
end
|
36
38
|
end
|
37
|
-
|
39
|
+
|
38
40
|
RemoteFailure = Class.new StandardError
|
39
41
|
|
40
42
|
private
|
@@ -1,5 +1,6 @@
|
|
1
1
|
require 'thor'
|
2
2
|
require 'pathname'
|
3
|
+
require 'tmpdir'
|
3
4
|
|
4
5
|
module EY
|
5
6
|
module Serverside
|
@@ -214,9 +215,9 @@ module EY
|
|
214
215
|
def propagate
|
215
216
|
config = EY::Serverside::Deploy::Configuration.new
|
216
217
|
gem_filename = "engineyard-serverside-#{EY::Serverside::VERSION}.gem"
|
217
|
-
local_gem_file = File.join(Gem.dir, 'cache', gem_filename)
|
218
|
+
local_gem_file = File.join(::Gem.dir, 'cache', gem_filename)
|
218
219
|
remote_gem_file = File.join(Dir.tmpdir, gem_filename)
|
219
|
-
gem_binary = File.join(Gem.default_bindir, 'gem')
|
220
|
+
gem_binary = File.join(::Gem.default_bindir, 'gem')
|
220
221
|
|
221
222
|
barrier(*(EY::Serverside::Server.all.find_all do |server|
|
222
223
|
!server.local? # of course this machine has it
|
@@ -119,7 +119,7 @@ module EY
|
|
119
119
|
end
|
120
120
|
|
121
121
|
def framework_envs
|
122
|
-
"RAILS_ENV=#{environment} RACK_ENV=#{environment}
|
122
|
+
"RAILS_ENV=#{environment} RACK_ENV=#{environment} MERB_ENV=#{environment}"
|
123
123
|
end
|
124
124
|
|
125
125
|
def current_path
|
@@ -27,6 +27,7 @@ module EY
|
|
27
27
|
create_revision_file
|
28
28
|
run_with_callbacks(:bundle)
|
29
29
|
symlink_configs
|
30
|
+
generate_configs
|
30
31
|
conditionally_enable_maintenance_page
|
31
32
|
run_with_callbacks(:migrate)
|
32
33
|
callback(:before_symlink)
|
@@ -136,8 +137,9 @@ module EY
|
|
136
137
|
bundler_installer = if File.exist?(lockfile)
|
137
138
|
get_bundler_installer(lockfile)
|
138
139
|
else
|
139
|
-
|
140
|
-
|
140
|
+
missing_lock_version = EY::Serverside::LockfileParser::Parse10::DEFAULT
|
141
|
+
warn_about_missing_lockfile missing_lock_version
|
142
|
+
bundler_10_installer missing_lock_version
|
141
143
|
end
|
142
144
|
|
143
145
|
sudo "#{$0} _#{EY::Serverside::VERSION}_ install_bundler #{bundler_installer.version}"
|
@@ -164,15 +166,6 @@ module EY
|
|
164
166
|
|
165
167
|
run "mkdir -p #{bundled_gems_path} && ruby -v > #{ruby_version_file} && uname -m > #{system_version_file}"
|
166
168
|
end
|
167
|
-
if File.exist?("#{c.release_path}/package.json")
|
168
|
-
unless `which npm` =~ /npm/
|
169
|
-
error "~> package.json detected, BUT npm not installed"
|
170
|
-
else
|
171
|
-
info "~> package.json detected, installing npm packages"
|
172
|
-
|
173
|
-
run "cd #{c.release_path} && npm install"
|
174
|
-
end
|
175
|
-
end
|
176
169
|
end
|
177
170
|
|
178
171
|
# task
|
@@ -227,6 +220,7 @@ module EY
|
|
227
220
|
run create_revision_file_command
|
228
221
|
end
|
229
222
|
|
223
|
+
# symlink to shared path; may be overridden by #generate_configs
|
230
224
|
def symlink_configs(release_to_link=c.release_path)
|
231
225
|
info "~> Symlinking configs"
|
232
226
|
[ "chmod -R g+w #{release_to_link}",
|
@@ -237,8 +231,8 @@ module EY
|
|
237
231
|
"mkdir -p #{release_to_link}/config",
|
238
232
|
"ln -nfs #{c.shared_path}/system #{release_to_link}/public/system",
|
239
233
|
"ln -nfs #{c.shared_path}/pids #{release_to_link}/tmp/pids",
|
240
|
-
"find #{c.shared_path}/config -type f -exec ln -s {} #{release_to_link}/config \\;",
|
241
|
-
|
234
|
+
"find #{c.shared_path}/config ! -name 'database.yml*' -type f -exec ln -s {} #{release_to_link}/config \\;",
|
235
|
+
# database.yml generated or symlink created in #generate_database_yml
|
242
236
|
"ln -nfs #{c.shared_path}/config/mongrel_cluster.yml #{release_to_link}/config/mongrel_cluster.yml",
|
243
237
|
].each do |cmd|
|
244
238
|
run cmd
|
@@ -248,6 +242,84 @@ module EY
|
|
248
242
|
run "if [ -f \"#{c.shared_path}/config/newrelic.yml\" ]; then ln -nfs #{c.shared_path}/config/newrelic.yml #{release_to_link}/config/newrelic.yml; fi"
|
249
243
|
end
|
250
244
|
|
245
|
+
def generate_configs(release_to_link=c.release_path)
|
246
|
+
generate_database_yml(release_to_link)
|
247
|
+
end
|
248
|
+
|
249
|
+
# Do nothing if there is no Gemfile.lock to determine what ORM gems are being used
|
250
|
+
# (falls back to using the symlinked shared/database.yml file)
|
251
|
+
def generate_database_yml(release_to_link)
|
252
|
+
return if keep_database_yml?(release_to_link)
|
253
|
+
if config["db_adapter"] || File.exist?("#{c.release_path}/Gemfile.lock")
|
254
|
+
info "~> Generating database.yml from Gemfile.lock"
|
255
|
+
database_yml = "#{release_to_link}/config/database.yml"
|
256
|
+
node = EY::Serverside.node
|
257
|
+
node_app = node["engineyard"]["environment"]["apps"].find { |app| app['name'] == c['app'] }
|
258
|
+
abort("Invalid application name for target environment: #{c['app']}") unless node_app
|
259
|
+
|
260
|
+
db_stack_name = node[:engineyard][:environment][:db_stack_name]
|
261
|
+
instances = node[:engineyard][:environment][:instances]
|
262
|
+
db_master = {"public_hostname" => "localhost"} # you know, just in case
|
263
|
+
db_slaves = []
|
264
|
+
instances.each do |i|
|
265
|
+
case i['role']
|
266
|
+
when 'db_master', 'solo'
|
267
|
+
db_master = i
|
268
|
+
when 'db_slave'
|
269
|
+
db_slaves << i
|
270
|
+
end
|
271
|
+
end
|
272
|
+
db_host = db_master["public_hostname"]
|
273
|
+
db_slaves_hosts = db_slaves.map {|slave| slave["public_hostname"]}
|
274
|
+
|
275
|
+
if config["db_adapter"]
|
276
|
+
adapter = config["db_adapter"]
|
277
|
+
elsif bundler_gems_include?("mysql2")
|
278
|
+
adapter = "mysql2"
|
279
|
+
elsif bundler_gems_include?("mysql")
|
280
|
+
adapter = "mysql"
|
281
|
+
elsif bundler_gems_include?("pg")
|
282
|
+
adapter = "postgresql"
|
283
|
+
elsif bundler_gems_include?("jdbc-mysql")
|
284
|
+
adapter = "mysql"
|
285
|
+
elsif bundler_gems_include?("jdbc-postgres")
|
286
|
+
adapter = "postgresql"
|
287
|
+
elsif db_stack_name && db_stack_name =~ /postgres/
|
288
|
+
adapter = "postgresql"
|
289
|
+
else
|
290
|
+
adapter = "mysql"
|
291
|
+
end
|
292
|
+
|
293
|
+
File.open(database_yml, "w") do |file|
|
294
|
+
contents = <<-EOS.gsub(/^\s{12}/, '')
|
295
|
+
#{node[:engineyard][:environment][:framework_env]}:
|
296
|
+
adapter: #{adapter}
|
297
|
+
database: #{node_app[:database_name]}
|
298
|
+
username: #{node[:engineyard][:environment][:ssh_username]}
|
299
|
+
password: #{node[:engineyard][:environment][:ssh_password]}
|
300
|
+
host: #{db_host}
|
301
|
+
reconnect: true
|
302
|
+
EOS
|
303
|
+
db_slaves_hosts.each_with_index do |host, n|
|
304
|
+
slave_name = n.zero? ? "slave" : "slave_#{n}"
|
305
|
+
contents << <<-EOS.gsub(/^\s{14}/, '')
|
306
|
+
#{slave_name}:
|
307
|
+
adapter: #{adapter}
|
308
|
+
database: #{node_app[:database_name]}
|
309
|
+
username: #{node[:engineyard][:environment][:ssh_username]}
|
310
|
+
password: #{node[:engineyard][:environment][:ssh_password]}
|
311
|
+
host: #{host}
|
312
|
+
reconnect: true
|
313
|
+
EOS
|
314
|
+
end
|
315
|
+
file << contents
|
316
|
+
end
|
317
|
+
else
|
318
|
+
info "~> Symlinking database.yml config"
|
319
|
+
run "ln -nfs #{c.shared_path}/config/database.yml #{release_to_link}/config/database.yml"
|
320
|
+
end
|
321
|
+
end
|
322
|
+
|
251
323
|
# task
|
252
324
|
def symlink(release_to_link=c.release_path)
|
253
325
|
info "~> Symlinking code"
|
@@ -319,7 +391,7 @@ module EY
|
|
319
391
|
raise
|
320
392
|
end
|
321
393
|
|
322
|
-
def warn_about_missing_lockfile
|
394
|
+
def warn_about_missing_lockfile(missing_lock_version)
|
323
395
|
info "!>"
|
324
396
|
info "!> WARNING: Gemfile.lock is missing!"
|
325
397
|
info "!> You can get different gems in production than what you tested with."
|
@@ -329,30 +401,52 @@ module EY
|
|
329
401
|
info "!> Fix this by running \"git add Gemfile.lock; git commit\" and deploying again."
|
330
402
|
info "!> If you don't have a Gemfile.lock, run \"bundle lock\" to create one."
|
331
403
|
info "!>"
|
332
|
-
info "!> This deployment will use bundler #{
|
404
|
+
info "!> This deployment will use bundler #{missing_lock_version} to run 'bundle install'."
|
333
405
|
info "!>"
|
334
406
|
end
|
335
407
|
|
336
|
-
def
|
408
|
+
def keep_database_yml?(release_to_link=c.release_path)
|
409
|
+
File.exists?(File.join(release_to_link, "config", "keep.database.yml"))
|
410
|
+
end
|
411
|
+
|
412
|
+
# returns true if "bundle list" includes all gems requested
|
413
|
+
def bundler_gems_include?(*gems)
|
414
|
+
lockfile = File.join(c.release_path, "Gemfile.lock")
|
415
|
+
@lockfile_contents ||= File.read(lockfile)
|
416
|
+
|
417
|
+
# Parsing Gemfile.lock which looks like
|
418
|
+
# GEM
|
419
|
+
# remote: http://rubygems.org/
|
420
|
+
# specs:
|
421
|
+
# activemodel (3.0.10)
|
422
|
+
# activesupport (= 3.0.10)
|
423
|
+
# builder (~> 2.1.2)
|
424
|
+
# i18n (~> 0.5.0)
|
425
|
+
#
|
426
|
+
gems.inject(true) {|found_all, gem| found_all && (@lockfile_contents =~ / #{gem} \(/)}
|
427
|
+
end
|
428
|
+
|
429
|
+
def get_bundler_installer(lockfile, options = '')
|
337
430
|
parser = LockfileParser.new(File.read(lockfile))
|
338
431
|
case parser.lockfile_version
|
339
432
|
when :bundler09
|
340
|
-
bundler_09_installer(parser.bundler_version)
|
433
|
+
bundler_09_installer(parser.bundler_version, options)
|
341
434
|
when :bundler10
|
342
|
-
bundler_10_installer(parser.bundler_version)
|
435
|
+
bundler_10_installer(parser.bundler_version, options)
|
343
436
|
else
|
344
437
|
raise "Unknown lockfile version #{parser.lockfile_version}"
|
345
438
|
end
|
346
439
|
end
|
347
440
|
public :get_bundler_installer
|
348
441
|
|
349
|
-
def bundler_09_installer(version)
|
350
|
-
|
442
|
+
def bundler_09_installer(version, options = '')
|
443
|
+
default_options = '--without=development --without=test'
|
444
|
+
BundleInstaller.new(version, default_options + options)
|
351
445
|
end
|
352
446
|
|
353
|
-
def bundler_10_installer(version)
|
354
|
-
|
355
|
-
|
447
|
+
def bundler_10_installer(version, options = '')
|
448
|
+
default_options = "--deployment --path #{c.shared_path}/bundled_gems --binstubs #{c.binstubs_path} --without development test"
|
449
|
+
BundleInstaller.new(version, default_options + options)
|
356
450
|
end
|
357
451
|
end # DeployBase
|
358
452
|
|
@@ -79,11 +79,11 @@ module EY
|
|
79
79
|
when '='
|
80
80
|
bundler_version
|
81
81
|
when '>='
|
82
|
-
Gem::Version.new(bundler_version) > Gem::Version.new(DEFAULT) ? bundler_version : DEFAULT
|
82
|
+
::Gem::Version.new(bundler_version) > ::Gem::Version.new(DEFAULT) ? bundler_version : DEFAULT
|
83
83
|
when '~>'
|
84
|
-
bundler_gem_version = Gem::Version.new(bundler_version)
|
84
|
+
bundler_gem_version = ::Gem::Version.new(bundler_version)
|
85
85
|
recommendation = bundler_gem_version.spermy_recommendation.gsub(/~>\s*(.+)$/, '\1.')
|
86
|
-
DEFAULT.start_with?(recommendation) && Gem::Version.new(DEFAULT) > bundler_gem_version ? DEFAULT : bundler_version
|
86
|
+
DEFAULT.start_with?(recommendation) && ::Gem::Version.new(DEFAULT) > bundler_gem_version ? DEFAULT : bundler_version
|
87
87
|
end
|
88
88
|
end
|
89
89
|
|
@@ -54,6 +54,7 @@ module EY
|
|
54
54
|
need_later { server.run(Escape.shell_command(wrapper + [to_run])) }
|
55
55
|
end
|
56
56
|
barrier *results
|
57
|
+
|
57
58
|
# MRI's truthiness check is an internal C thing that does not call
|
58
59
|
# any methods... so Dataflow cannot proxy it & we must "x == true"
|
59
60
|
# Rubinius, wherefore art thou!?
|
@@ -0,0 +1,7 @@
|
|
1
|
+
diff --git a/ext/openssl/openssl_missing.h b/ext/openssl/openssl_missing.h
|
2
|
+
index 2ebf61a..8a0202a 100644
|
3
|
+
--- a/ext/openssl/openssl_missing.h
|
4
|
+
+++ b/ext/openssl/openssl_missing.h
|
5
|
+
@@ -123,2 +122,0 @@ int BN_mod_sub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m, BN_
|
6
|
+
-int BN_rand_range(BIGNUM *r, BIGNUM *range);
|
7
|
+
-int BN_pseudo_rand_range(BIGNUM *r, BIGNUM *range);
|
data/spec/custom_deploy_spec.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require File.dirname(__FILE__) + '/spec_helper'
|
2
|
+
require 'fileutils'
|
2
3
|
|
3
4
|
describe "the EY::Serverside::Deploy API" do
|
4
5
|
it "calls tasks in the right order" do
|
@@ -29,9 +30,12 @@ describe "the EY::Serverside::Deploy API" do
|
|
29
30
|
def cleanup_old_releases() @call_order << 'cleanup_old_releases' end
|
30
31
|
def conditionally_enable_maintenance_page() @call_order << 'conditionally_enable_maintenance_page' end
|
31
32
|
def disable_maintenance_page() @call_order << 'disable_maintenance_page' end
|
33
|
+
def generate_database_yml(path) @call_order << 'generate_database_yml' end
|
32
34
|
end
|
33
35
|
|
34
|
-
|
36
|
+
setup_dna_json
|
37
|
+
|
38
|
+
td = TestDeploy.new(EY::Serverside::Deploy::Configuration.new('app' => 'myfirstapp'))
|
35
39
|
td.deploy
|
36
40
|
td.call_order.should == %w(
|
37
41
|
push_code
|
@@ -39,6 +43,7 @@ describe "the EY::Serverside::Deploy API" do
|
|
39
43
|
create_revision_file
|
40
44
|
bundle
|
41
45
|
symlink_configs
|
46
|
+
generate_database_yml
|
42
47
|
conditionally_enable_maintenance_page
|
43
48
|
migrate
|
44
49
|
symlink
|
@@ -53,15 +58,17 @@ describe "the EY::Serverside::Deploy API" do
|
|
53
58
|
end
|
54
59
|
|
55
60
|
before(:each) do
|
56
|
-
@tempdir =
|
57
|
-
@config
|
58
|
-
@deploy
|
61
|
+
@tempdir = File.join(Dir.tmpdir, "serverside-deploy-#{Time.now.to_i}-#{$$}")
|
62
|
+
@config = EY::Serverside::Deploy::Configuration.new('repository_cache' => @tempdir)
|
63
|
+
@deploy = TestQuietDeploy.new(@config)
|
64
|
+
end
|
65
|
+
|
66
|
+
after do
|
67
|
+
FileUtils.rm_rf(@tempdir)
|
59
68
|
end
|
60
69
|
|
61
70
|
def write_eydeploy(relative_path, contents = "def got_new_methods() 'from the file on disk' end")
|
62
|
-
FileUtils.mkdir_p(File.join(
|
63
|
-
@tempdir,
|
64
|
-
File.dirname(relative_path)))
|
71
|
+
FileUtils.mkdir_p(File.join(@tempdir, File.dirname(relative_path)))
|
65
72
|
|
66
73
|
File.open(File.join(@tempdir, relative_path), 'w') do |f|
|
67
74
|
f.write contents
|
@@ -0,0 +1,29 @@
|
|
1
|
+
GEM
|
2
|
+
remote: http://rubygems.org/
|
3
|
+
specs:
|
4
|
+
activemodel (3.0.10)
|
5
|
+
activesupport (= 3.0.10)
|
6
|
+
builder (~> 2.1.2)
|
7
|
+
i18n (~> 0.5.0)
|
8
|
+
activerecord (3.0.10)
|
9
|
+
activemodel (= 3.0.10)
|
10
|
+
activesupport (= 3.0.10)
|
11
|
+
arel (~> 2.0.10)
|
12
|
+
tzinfo (~> 0.3.23)
|
13
|
+
activerecord-jdbc-adapter (1.1.3)
|
14
|
+
activerecord-jdbcmysql-adapter (1.1.3)
|
15
|
+
activerecord-jdbc-adapter (= 1.1.3)
|
16
|
+
jdbc-mysql (~> 5.1.0)
|
17
|
+
activesupport (3.0.10)
|
18
|
+
arel (2.0.10)
|
19
|
+
builder (2.1.2)
|
20
|
+
i18n (0.5.0)
|
21
|
+
jdbc-mysql (5.1.13)
|
22
|
+
tzinfo (0.3.29)
|
23
|
+
|
24
|
+
PLATFORMS
|
25
|
+
ruby
|
26
|
+
|
27
|
+
DEPENDENCIES
|
28
|
+
activerecord
|
29
|
+
activerecord-jdbcmysql-adapter
|
@@ -0,0 +1,29 @@
|
|
1
|
+
GEM
|
2
|
+
remote: http://rubygems.org/
|
3
|
+
specs:
|
4
|
+
activemodel (3.0.10)
|
5
|
+
activesupport (= 3.0.10)
|
6
|
+
builder (~> 2.1.2)
|
7
|
+
i18n (~> 0.5.0)
|
8
|
+
activerecord (3.0.10)
|
9
|
+
activemodel (= 3.0.10)
|
10
|
+
activesupport (= 3.0.10)
|
11
|
+
arel (~> 2.0.10)
|
12
|
+
tzinfo (~> 0.3.23)
|
13
|
+
activerecord-jdbc-adapter (1.1.3)
|
14
|
+
activerecord-jdbcpostgresql-adapter (1.1.3)
|
15
|
+
activerecord-jdbc-adapter (= 1.1.3)
|
16
|
+
jdbc-postgres (~> 9.0.0)
|
17
|
+
activesupport (3.0.10)
|
18
|
+
arel (2.0.10)
|
19
|
+
builder (2.1.2)
|
20
|
+
i18n (0.5.0)
|
21
|
+
jdbc-postgres (9.0.801)
|
22
|
+
tzinfo (0.3.29)
|
23
|
+
|
24
|
+
PLATFORMS
|
25
|
+
ruby
|
26
|
+
|
27
|
+
DEPENDENCIES
|
28
|
+
activerecord
|
29
|
+
activerecord-jdbcpostgresql-adapter
|