heroku_hatchet 1.3.7 → 1.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (48) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +3 -2
  3. data/CHANGELOG.md +5 -0
  4. data/hatchet.gemspec +2 -0
  5. data/hatchet.json +2 -1
  6. data/lib/hatchet.rb +1 -1
  7. data/lib/hatchet/app.rb +4 -3
  8. data/lib/hatchet/version.rb +1 -1
  9. data/test/hatchet/allow_failure_anvil_test.rb +0 -29
  10. data/test/hatchet/anvil_test.rb +0 -16
  11. data/test/hatchet/app_test.rb +9 -0
  12. data/test/hatchet/config_test.rb +9 -6
  13. data/test/hatchet/edit_repo_test.rb +3 -3
  14. data/test/hatchet/heroku_api_test.rb +7 -2
  15. data/test/hatchet/multi_cmd_runner_test.rb +2 -6
  16. data/test/hatchet/runner_test.rb +2 -2
  17. metadata +33 -65
  18. data/test/fixtures/buildpacks/heroku-buildpack-ruby/.gitignore +0 -4
  19. data/test/fixtures/buildpacks/heroku-buildpack-ruby/CHANGELOG.md +0 -378
  20. data/test/fixtures/buildpacks/heroku-buildpack-ruby/Gemfile +0 -10
  21. data/test/fixtures/buildpacks/heroku-buildpack-ruby/LICENSE +0 -9
  22. data/test/fixtures/buildpacks/heroku-buildpack-ruby/README.md +0 -192
  23. data/test/fixtures/buildpacks/heroku-buildpack-ruby/Rakefile +0 -358
  24. data/test/fixtures/buildpacks/heroku-buildpack-ruby/bin/compile +0 -13
  25. data/test/fixtures/buildpacks/heroku-buildpack-ruby/bin/detect +0 -12
  26. data/test/fixtures/buildpacks/heroku-buildpack-ruby/bin/release +0 -9
  27. data/test/fixtures/buildpacks/heroku-buildpack-ruby/hatchet.json +0 -25
  28. data/test/fixtures/buildpacks/heroku-buildpack-ruby/lib/language_pack.rb +0 -27
  29. data/test/fixtures/buildpacks/heroku-buildpack-ruby/lib/language_pack/base.rb +0 -175
  30. data/test/fixtures/buildpacks/heroku-buildpack-ruby/lib/language_pack/bundler_lockfile.rb +0 -19
  31. data/test/fixtures/buildpacks/heroku-buildpack-ruby/lib/language_pack/disable_deploys.rb +0 -17
  32. data/test/fixtures/buildpacks/heroku-buildpack-ruby/lib/language_pack/no_lockfile.rb +0 -16
  33. data/test/fixtures/buildpacks/heroku-buildpack-ruby/lib/language_pack/rack.rb +0 -43
  34. data/test/fixtures/buildpacks/heroku-buildpack-ruby/lib/language_pack/rails2.rb +0 -91
  35. data/test/fixtures/buildpacks/heroku-buildpack-ruby/lib/language_pack/rails3.rb +0 -86
  36. data/test/fixtures/buildpacks/heroku-buildpack-ruby/lib/language_pack/rails4.rb +0 -66
  37. data/test/fixtures/buildpacks/heroku-buildpack-ruby/lib/language_pack/ruby.rb +0 -681
  38. data/test/fixtures/buildpacks/heroku-buildpack-ruby/lib/language_pack/shell_helpers.rb +0 -62
  39. data/test/fixtures/buildpacks/heroku-buildpack-ruby/spec/bugs_spec.rb +0 -11
  40. data/test/fixtures/buildpacks/heroku-buildpack-ruby/spec/no_lockfile_spec.rb +0 -10
  41. data/test/fixtures/buildpacks/heroku-buildpack-ruby/spec/rails23_spec.rb +0 -11
  42. data/test/fixtures/buildpacks/heroku-buildpack-ruby/spec/rails3_spec.rb +0 -22
  43. data/test/fixtures/buildpacks/heroku-buildpack-ruby/spec/rails4_spec.rb +0 -12
  44. data/test/fixtures/buildpacks/heroku-buildpack-ruby/spec/rubies_spec.rb +0 -38
  45. data/test/fixtures/buildpacks/heroku-buildpack-ruby/spec/spec_helper.rb +0 -35
  46. data/test/fixtures/buildpacks/heroku-buildpack-ruby/support/s3/hmac +0 -79
  47. data/test/fixtures/buildpacks/heroku-buildpack-ruby/support/s3/s3 +0 -223
  48. data/test/fixtures/buildpacks/heroku-buildpack-ruby/vendor/syck_hack.rb +0 -64
@@ -1,86 +0,0 @@
1
- require "language_pack"
2
- require "language_pack/rails2"
3
-
4
- # Rails 3 Language Pack. This is for all Rails 3.x apps.
5
- class LanguagePack::Rails3 < LanguagePack::Rails2
6
- # detects if this is a Rails 3.x app
7
- # @return [Boolean] true if it's a Rails 3.x app
8
- def self.use?
9
- if gemfile_lock?
10
- rails_version = LanguagePack::Ruby.gem_version('railties')
11
- rails_version >= Gem::Version.new('3.0.0') && rails_version < Gem::Version.new('4.0.0') if rails_version
12
- end
13
- end
14
-
15
- def name
16
- "Ruby/Rails"
17
- end
18
-
19
- def default_process_types
20
- # let's special case thin here
21
- web_process = gem_is_bundled?("thin") ?
22
- "bundle exec thin start -R config.ru -e $RAILS_ENV -p $PORT" :
23
- "bundle exec rails server -p $PORT"
24
-
25
- super.merge({
26
- "web" => web_process,
27
- "console" => "bundle exec rails console"
28
- })
29
- end
30
-
31
- private
32
-
33
- def plugins
34
- super.concat(%w( rails3_serve_static_assets )).uniq
35
- end
36
-
37
- # runs the tasks for the Rails 3.1 asset pipeline
38
- def run_assets_precompile_rake_task
39
- log("assets_precompile") do
40
- setup_database_url_env
41
-
42
- if rake_task_defined?("assets:precompile")
43
- topic("Preparing app for Rails asset pipeline")
44
- if File.exists?("public/assets/manifest.yml")
45
- puts "Detected manifest.yml, assuming assets were compiled locally"
46
- else
47
- ENV["RAILS_GROUPS"] ||= "assets"
48
- ENV["RAILS_ENV"] ||= "production"
49
-
50
- puts "Running: rake assets:precompile"
51
- require 'benchmark'
52
- time = Benchmark.realtime { pipe("env PATH=$PATH:bin bundle exec rake assets:precompile 2>&1") }
53
-
54
- if $?.success?
55
- log "assets_precompile", :status => "success"
56
- puts "Asset precompilation completed (#{"%.2f" % time}s)"
57
- else
58
- log "assets_precompile", :status => "failure"
59
- puts "Precompiling assets failed, enabling runtime asset compilation"
60
- install_plugin("rails31_enable_runtime_asset_compilation")
61
- puts "Please see this article for troubleshooting help:"
62
- puts "http://devcenter.heroku.com/articles/rails31_heroku_cedar#troubleshooting"
63
- end
64
- end
65
- end
66
- end
67
- end
68
-
69
- # setup the database url as an environment variable
70
- def setup_database_url_env
71
- ENV["DATABASE_URL"] ||= begin
72
- # need to use a dummy DATABASE_URL here, so rails can load the environment
73
- scheme =
74
- if gem_is_bundled?("pg")
75
- "postgres"
76
- elsif gem_is_bundled?("mysql")
77
- "mysql"
78
- elsif gem_is_bundled?("mysql2")
79
- "mysql2"
80
- elsif gem_is_bundled?("sqlite3") || gem_is_bundled?("sqlite3-ruby")
81
- "sqlite3"
82
- end
83
- "#{scheme}://user:pass@127.0.0.1/dbname"
84
- end
85
- end
86
- end
@@ -1,66 +0,0 @@
1
- require "language_pack"
2
- require "language_pack/rails3"
3
-
4
- # Rails 4 Language Pack. This is for all Rails 4.x apps.
5
- class LanguagePack::Rails4 < LanguagePack::Rails3
6
- # detects if this is a Rails 3.x app
7
- # @return [Boolean] true if it's a Rails 3.x app
8
- def self.use?
9
- if gemfile_lock?
10
- rails_version = LanguagePack::Ruby.gem_version('railties')
11
- rails_version >= Gem::Version.new('4.0.0.beta') && rails_version < Gem::Version.new('5.0.0') if rails_version
12
- end
13
- end
14
-
15
- def name
16
- "Ruby/Rails"
17
- end
18
-
19
- def default_process_types
20
- web_process = gem_is_bundled?("thin") ?
21
- "bin/rails server thin -p $PORT -e $RAILS_ENV" :
22
- "bin/rails server -p $PORT -e $RAILS_ENV"
23
- super.merge({
24
- "web" => web_process,
25
- "console" => "bin/rails console"
26
- })
27
- end
28
-
29
- private
30
- def plugins
31
- []
32
- end
33
-
34
- def run_assets_precompile_rake_task
35
- log("assets_precompile") do
36
- setup_database_url_env
37
-
38
- if rake_task_defined?("assets:precompile")
39
- topic("Preparing app for Rails asset pipeline")
40
- if Dir.glob('public/assets/manifest-*.json').any?
41
- puts "Detected manifest file, assuming assets were compiled locally"
42
- else
43
- ENV["RAILS_GROUPS"] ||= "assets"
44
- ENV["RAILS_ENV"] ||= "production"
45
-
46
- puts "Running: rake assets:precompile"
47
- require 'benchmark'
48
- time = Benchmark.realtime { pipe("env PATH=$PATH:bin bundle exec rake assets:precompile 2>&1") }
49
-
50
- if $?.success?
51
- log "assets_precompile", :status => "success"
52
- puts "Asset precompilation completed (#{"%.2f" % time}s)"
53
- else
54
- log "assets_precompile", :status => "failure"
55
- error "Precompiling assets failed."
56
- end
57
- end
58
- else
59
- puts "Error detecting the assets:precompile task"
60
- end
61
- end
62
- end
63
-
64
- def create_database_yml
65
- end
66
- end
@@ -1,681 +0,0 @@
1
- require "tmpdir"
2
- require "rubygems"
3
- require "language_pack"
4
- require "language_pack/base"
5
- require "language_pack/bundler_lockfile"
6
-
7
- # base Ruby Language Pack. This is for any base ruby app.
8
- class LanguagePack::Ruby < LanguagePack::Base
9
- include LanguagePack::BundlerLockfile
10
- extend LanguagePack::BundlerLockfile
11
-
12
- BUILDPACK_VERSION = "v61"
13
- LIBYAML_VERSION = "0.1.4"
14
- LIBYAML_PATH = "libyaml-#{LIBYAML_VERSION}"
15
- BUNDLER_VERSION = "1.3.2"
16
- BUNDLER_GEM_PATH = "bundler-#{BUNDLER_VERSION}"
17
- NODE_VERSION = "0.4.7"
18
- NODE_JS_BINARY_PATH = "node-#{NODE_VERSION}"
19
- JVM_BASE_URL = "http://heroku-jdk.s3.amazonaws.com"
20
- JVM_VERSION = "openjdk7-latest"
21
-
22
- # detects if this is a valid Ruby app
23
- # @return [Boolean] true if it's a Ruby app
24
- def self.use?
25
- File.exist?("Gemfile")
26
- end
27
-
28
- def self.lockfile_parser
29
- require "bundler"
30
- Bundler::LockfileParser.new(File.read("Gemfile.lock"))
31
- end
32
-
33
- def self.gem_version(name)
34
- gem_version = nil
35
- bootstrap_bundler do |bundler_path|
36
- $: << "#{bundler_path}/gems/bundler-#{LanguagePack::Ruby::BUNDLER_VERSION}/lib"
37
- gem = lockfile_parser.specs.detect {|gem| gem.name == name }
38
- gem_version = gem.version if gem
39
- end
40
-
41
- gem_version
42
- end
43
-
44
- def name
45
- "Ruby"
46
- end
47
-
48
- def default_addons
49
- add_dev_database_addon
50
- end
51
-
52
- def default_config_vars
53
- vars = {
54
- "LANG" => "en_US.UTF-8",
55
- "PATH" => default_path,
56
- "GEM_PATH" => slug_vendor_base,
57
- }
58
-
59
- ruby_version_jruby? ? vars.merge({
60
- "JAVA_OPTS" => default_java_opts,
61
- "JRUBY_OPTS" => default_jruby_opts,
62
- "JAVA_TOOL_OPTIONS" => default_java_tool_options
63
- }) : vars
64
- end
65
-
66
- def default_process_types
67
- {
68
- "rake" => "bundle exec rake",
69
- "console" => "bundle exec irb"
70
- }
71
- end
72
-
73
- def compile
74
- Dir.chdir(build_path)
75
- remove_vendor_bundle
76
- install_ruby
77
- install_jvm
78
- setup_language_pack_environment
79
- setup_profiled
80
- allow_git do
81
- install_language_pack_gems
82
- build_bundler
83
- create_database_yml
84
- install_binaries
85
- run_assets_precompile_rake_task
86
- end
87
- end
88
-
89
- private
90
-
91
- # the base PATH environment variable to be used
92
- # @return [String] the resulting PATH
93
- def default_path
94
- "bin:#{slug_vendor_base}/bin:/usr/local/bin:/usr/bin:/bin"
95
- end
96
-
97
- # the relative path to the bundler directory of gems
98
- # @return [String] resulting path
99
- def slug_vendor_base
100
- if @slug_vendor_base
101
- @slug_vendor_base
102
- elsif @ruby_version == "ruby-1.8.7"
103
- @slug_vendor_base = "vendor/bundle/1.8"
104
- else
105
- @slug_vendor_base = run(%q(ruby -e "require 'rbconfig';puts \"vendor/bundle/#{RUBY_ENGINE}/#{RbConfig::CONFIG['ruby_version']}\"")).chomp
106
- end
107
- end
108
-
109
- # the relative path to the vendored ruby directory
110
- # @return [String] resulting path
111
- def slug_vendor_ruby
112
- "vendor/#{ruby_version}"
113
- end
114
-
115
- # the relative path to the vendored jvm
116
- # @return [String] resulting path
117
- def slug_vendor_jvm
118
- "vendor/jvm"
119
- end
120
-
121
- # the absolute path of the build ruby to use during the buildpack
122
- # @return [String] resulting path
123
- def build_ruby_path
124
- "/tmp/#{ruby_version}"
125
- end
126
-
127
- # fetch the ruby version from bundler
128
- # @return [String, nil] returns the ruby version if detected or nil if none is detected
129
- def ruby_version
130
- return @ruby_version if @ruby_version_run
131
-
132
- @ruby_version_run = true
133
-
134
- bootstrap_bundler do |bundler_path|
135
- old_system_path = "/usr/local/bin:/usr/local/sbin:/usr/bin:/bin:/usr/sbin:/sbin"
136
- @ruby_version = run_stdout("env PATH=#{old_system_path}:#{bundler_path}/bin GEM_PATH=#{bundler_path} bundle platform --ruby").chomp
137
- end
138
-
139
- if @ruby_version == "No ruby version specified" && ENV['RUBY_VERSION']
140
- # for backwards compatibility.
141
- # this will go away in the future
142
- @ruby_version = ENV['RUBY_VERSION']
143
- @ruby_version_env_var = true
144
- elsif @ruby_version == "No ruby version specified"
145
- @ruby_version = nil
146
- else
147
- @ruby_version = @ruby_version.sub('(', '').sub(')', '').split.join('-')
148
- @ruby_version_env_var = false
149
- end
150
-
151
- @ruby_version
152
- end
153
-
154
- # determine if we're using rbx
155
- # @return [Boolean] true if we are and false if we aren't
156
- def ruby_version_rbx?
157
- ruby_version ? ruby_version.match(/rbx-/) : false
158
- end
159
-
160
- # determine if we're using jruby
161
- # @return [Boolean] true if we are and false if we aren't
162
- def ruby_version_jruby?
163
- @ruby_version_jruby ||= ruby_version ? ruby_version.match(/jruby-/) : false
164
- end
165
-
166
- # default JAVA_OPTS
167
- # return [String] string of JAVA_OPTS
168
- def default_java_opts
169
- "-Xmx384m -Xss512k -XX:+UseCompressedOops -Dfile.encoding=UTF-8"
170
- end
171
-
172
- # default JRUBY_OPTS
173
- # return [String] string of JRUBY_OPTS
174
- def default_jruby_opts
175
- "-Xcompile.invokedynamic=true"
176
- end
177
-
178
- # default JAVA_TOOL_OPTIONS
179
- # return [String] string of JAVA_TOOL_OPTIONS
180
- def default_java_tool_options
181
- "-Djava.rmi.server.useCodebaseOnly=true"
182
- end
183
-
184
- # list the available valid ruby versions
185
- # @note the value is memoized
186
- # @return [Array] list of Strings of the ruby versions available
187
- def ruby_versions
188
- return @ruby_versions if @ruby_versions
189
-
190
- Dir.mktmpdir("ruby_versions-") do |tmpdir|
191
- Dir.chdir(tmpdir) do
192
- run("curl -O #{VENDOR_URL}/ruby_versions.yml")
193
- @ruby_versions = YAML::load_file("ruby_versions.yml")
194
- end
195
- end
196
-
197
- @ruby_versions
198
- end
199
-
200
- # sets up the environment variables for the build process
201
- def setup_language_pack_environment
202
- setup_ruby_install_env
203
-
204
- config_vars = default_config_vars.each do |key, value|
205
- ENV[key] ||= value
206
- end
207
- ENV["GEM_HOME"] = slug_vendor_base
208
- ENV["PATH"] = "#{ruby_install_binstub_path}:#{config_vars["PATH"]}"
209
- end
210
-
211
- # sets up the profile.d script for this buildpack
212
- def setup_profiled
213
- set_env_override "GEM_PATH", "$HOME/#{slug_vendor_base}:$GEM_PATH"
214
- set_env_default "LANG", "en_US.UTF-8"
215
- set_env_override "PATH", "$HOME/bin:$HOME/#{slug_vendor_base}/bin:$PATH"
216
-
217
- if ruby_version_jruby?
218
- set_env_default "JAVA_OPTS", default_java_opts
219
- set_env_default "JRUBY_OPTS", default_jruby_opts
220
- set_env_default "JAVA_TOOL_OPTIONS", default_java_tool_options
221
- end
222
- end
223
-
224
- # determines if a build ruby is required
225
- # @return [Boolean] true if a build ruby is required
226
- def build_ruby?
227
- @build_ruby ||= !ruby_version_rbx? && !ruby_version_jruby? && !%w{ruby-1.9.3 ruby-2.0.0}.include?(ruby_version)
228
- end
229
-
230
- # install the vendored ruby
231
- # @return [Boolean] true if it installs the vendored ruby and false otherwise
232
- def install_ruby
233
- return false unless ruby_version
234
-
235
- invalid_ruby_version_message = <<ERROR
236
- Invalid RUBY_VERSION specified: #{ruby_version}
237
- Valid versions: #{ruby_versions.join(", ")}
238
- ERROR
239
-
240
- if build_ruby?
241
- FileUtils.mkdir_p(build_ruby_path)
242
- Dir.chdir(build_ruby_path) do
243
- ruby_vm = ruby_version_rbx? ? "rbx" : "ruby"
244
- run("curl #{VENDOR_URL}/#{ruby_version.sub(ruby_vm, "#{ruby_vm}-build")}.tgz -s -o - | tar zxf -")
245
- end
246
- error invalid_ruby_version_message unless $?.success?
247
- end
248
-
249
- FileUtils.mkdir_p(slug_vendor_ruby)
250
- Dir.chdir(slug_vendor_ruby) do
251
- run("curl #{VENDOR_URL}/#{ruby_version}.tgz -s -o - | tar zxf -")
252
- end
253
- error invalid_ruby_version_message unless $?.success?
254
-
255
- bin_dir = "bin"
256
- FileUtils.mkdir_p bin_dir
257
- Dir["#{slug_vendor_ruby}/bin/*"].each do |bin|
258
- run("ln -s ../#{bin} #{bin_dir}")
259
- end
260
-
261
- if !@ruby_version_env_var
262
- topic "Using Ruby version: #{ruby_version}"
263
- else
264
- topic "Using RUBY_VERSION: #{ruby_version}"
265
- puts "WARNING: RUBY_VERSION support has been deprecated and will be removed entirely on August 1, 2012."
266
- puts "See https://devcenter.heroku.com/articles/ruby-versions#selecting_a_version_of_ruby for more information."
267
- end
268
-
269
- true
270
- end
271
-
272
- # vendors JVM into the slug for JRuby
273
- def install_jvm
274
- if ruby_version_jruby?
275
- topic "Installing JVM: #{JVM_VERSION}"
276
-
277
- FileUtils.mkdir_p(slug_vendor_jvm)
278
- Dir.chdir(slug_vendor_jvm) do
279
- run("curl #{JVM_BASE_URL}/#{JVM_VERSION}.tar.gz -s -o - | tar xzf -")
280
- end
281
-
282
- bin_dir = "bin"
283
- FileUtils.mkdir_p bin_dir
284
- Dir["#{slug_vendor_jvm}/bin/*"].each do |bin|
285
- run("ln -s ../#{bin} #{bin_dir}")
286
- end
287
- end
288
- end
289
-
290
- # find the ruby install path for its binstubs during build
291
- # @return [String] resulting path or empty string if ruby is not vendored
292
- def ruby_install_binstub_path
293
- @ruby_install_binstub_path ||=
294
- if build_ruby?
295
- "#{build_ruby_path}/bin"
296
- elsif ruby_version
297
- "#{slug_vendor_ruby}/bin"
298
- else
299
- ""
300
- end
301
- end
302
-
303
- # setup the environment so we can use the vendored ruby
304
- def setup_ruby_install_env
305
- ENV["PATH"] = "#{ruby_install_binstub_path}:#{ENV["PATH"]}"
306
-
307
- if ruby_version_jruby?
308
- ENV['JAVA_OPTS'] = default_java_opts
309
- end
310
- end
311
-
312
- # list of default gems to vendor into the slug
313
- # @return [Array] resulting list of gems
314
- def gems
315
- [BUNDLER_GEM_PATH]
316
- end
317
-
318
- # installs vendored gems into the slug
319
- def install_language_pack_gems
320
- FileUtils.mkdir_p(slug_vendor_base)
321
- Dir.chdir(slug_vendor_base) do |dir|
322
- gems.each do |gem|
323
- run("curl #{VENDOR_URL}/#{gem}.tgz -s -o - | tar xzf -")
324
- end
325
- Dir["bin/*"].each {|path| run("chmod 755 #{path}") }
326
- end
327
- end
328
-
329
- # default set of binaries to install
330
- # @return [Array] resulting list
331
- def binaries
332
- add_node_js_binary
333
- end
334
-
335
- # vendors binaries into the slug
336
- def install_binaries
337
- binaries.each {|binary| install_binary(binary) }
338
- Dir["bin/*"].each {|path| run("chmod +x #{path}") }
339
- end
340
-
341
- # vendors individual binary into the slug
342
- # @param [String] name of the binary package from S3.
343
- # Example: https://s3.amazonaws.com/language-pack-ruby/node-0.4.7.tgz, where name is "node-0.4.7"
344
- def install_binary(name)
345
- bin_dir = "bin"
346
- FileUtils.mkdir_p bin_dir
347
- Dir.chdir(bin_dir) do |dir|
348
- run("curl #{VENDOR_URL}/#{name}.tgz -s -o - | tar xzf -")
349
- end
350
- end
351
-
352
- # removes a binary from the slug
353
- # @param [String] relative path of the binary on the slug
354
- def uninstall_binary(path)
355
- FileUtils.rm File.join('bin', File.basename(path)), :force => true
356
- end
357
-
358
- # install libyaml into the LP to be referenced for psych compilation
359
- # @param [String] tmpdir to store the libyaml files
360
- def install_libyaml(dir)
361
- FileUtils.mkdir_p dir
362
- Dir.chdir(dir) do |dir|
363
- run("curl #{VENDOR_URL}/#{LIBYAML_PATH}.tgz -s -o - | tar xzf -")
364
- end
365
- end
366
-
367
- # remove `vendor/bundle` that comes from the git repo
368
- # in case there are native ext.
369
- # users should be using `bundle pack` instead.
370
- # https://github.com/heroku/heroku-buildpack-ruby/issues/21
371
- def remove_vendor_bundle
372
- if File.exists?("vendor/bundle")
373
- topic "WARNING: Removing `vendor/bundle`."
374
- puts "Checking in `vendor/bundle` is not supported. Please remove this directory"
375
- puts "and add it to your .gitignore. To vendor your gems with Bundler, use"
376
- puts "`bundle pack` instead."
377
- FileUtils.rm_rf("vendor/bundle")
378
- end
379
- end
380
-
381
- # runs bundler to install the dependencies
382
- def build_bundler
383
- log("bundle") do
384
- bundle_without = ENV["BUNDLE_WITHOUT"] || "development:test"
385
- bundle_command = "bundle install --without #{bundle_without} --path vendor/bundle --binstubs vendor/bundle/bin"
386
-
387
- unless File.exist?("Gemfile.lock")
388
- error "Gemfile.lock is required. Please run \"bundle install\" locally\nand commit your Gemfile.lock."
389
- end
390
-
391
- if has_windows_gemfile_lock?
392
- topic "WARNING: Removing `Gemfile.lock` because it was generated on Windows."
393
- puts "Bundler will do a full resolve so native gems are handled properly."
394
- puts "This may result in unexpected gem versions being used in your app."
395
-
396
- log("bundle", "has_windows_gemfile_lock")
397
- File.unlink("Gemfile.lock")
398
- else
399
- # using --deployment is preferred if we can
400
- bundle_command += " --deployment"
401
- cache_load ".bundle"
402
- end
403
-
404
- version = run_stdout("bundle version").strip
405
- topic("Installing dependencies using #{version}")
406
-
407
- load_bundler_cache
408
-
409
- bundler_output = ""
410
- Dir.mktmpdir("libyaml-") do |tmpdir|
411
- libyaml_dir = "#{tmpdir}/#{LIBYAML_PATH}"
412
- install_libyaml(libyaml_dir)
413
-
414
- # need to setup compile environment for the psych gem
415
- yaml_include = File.expand_path("#{libyaml_dir}/include")
416
- yaml_lib = File.expand_path("#{libyaml_dir}/lib")
417
- pwd = run("pwd").chomp
418
- bundler_path = "#{pwd}/#{slug_vendor_base}/gems/#{BUNDLER_GEM_PATH}/lib"
419
- # we need to set BUNDLE_CONFIG and BUNDLE_GEMFILE for
420
- # codon since it uses bundler.
421
- env_vars = "env BUNDLE_GEMFILE=#{pwd}/Gemfile BUNDLE_CONFIG=#{pwd}/.bundle/config CPATH=#{yaml_include}:$CPATH CPPATH=#{yaml_include}:$CPPATH LIBRARY_PATH=#{yaml_lib}:$LIBRARY_PATH RUBYOPT=\"#{syck_hack}\""
422
- env_vars += " BUNDLER_LIB_PATH=#{bundler_path}" if ruby_version.match(/^ruby-1\.8\.7/)
423
- puts "Running: #{bundle_command}"
424
- bundler_output << pipe("#{env_vars} #{bundle_command} --no-clean 2>&1")
425
-
426
- end
427
-
428
- if $?.success?
429
- log "bundle", :status => "success"
430
- puts "Cleaning up the bundler cache."
431
- pipe "bundle clean 2> /dev/null"
432
- cache_store ".bundle"
433
- cache_store "vendor/bundle"
434
-
435
- # Keep gem cache out of the slug
436
- FileUtils.rm_rf("#{slug_vendor_base}/cache")
437
-
438
- # symlink binstubs
439
- bin_dir = "bin"
440
- FileUtils.mkdir_p bin_dir
441
- Dir["#{slug_vendor_base}/bin/*"].each do |bin|
442
- run("ln -s ../#{bin} #{bin_dir}") unless File.exist?("#{bin_dir}/#{bin}")
443
- end
444
- else
445
- log "bundle", :status => "failure"
446
- error_message = "Failed to install gems via Bundler."
447
- if bundler_output.match(/Installing sqlite3 \([\w.]+\) with native extensions\s+Gem::Installer::ExtensionBuildError: ERROR: Failed to build gem native extension./)
448
- error_message += <<ERROR
449
-
450
-
451
- Detected sqlite3 gem which is not supported on Heroku.
452
- http://devcenter.heroku.com/articles/how-do-i-use-sqlite3-for-development
453
- ERROR
454
- end
455
-
456
- error error_message
457
- end
458
- end
459
- end
460
-
461
- # RUBYOPT line that requires syck_hack file
462
- # @return [String] require string if needed or else an empty string
463
- def syck_hack
464
- syck_hack_file = File.expand_path(File.join(File.dirname(__FILE__), "../../vendor/syck_hack"))
465
- ruby_version = run_stdout('ruby -e "puts RUBY_VERSION"').chomp
466
- # < 1.9.3 includes syck, so we need to use the syck hack
467
- if Gem::Version.new(ruby_version) < Gem::Version.new("1.9.3")
468
- "-r#{syck_hack_file}"
469
- else
470
- ""
471
- end
472
- end
473
-
474
- # writes ERB based database.yml for Rails. The database.yml uses the DATABASE_URL from the environment during runtime.
475
- def create_database_yml
476
- log("create_database_yml") do
477
- return unless File.directory?("config")
478
- topic("Writing config/database.yml to read from DATABASE_URL")
479
- File.open("config/database.yml", "w") do |file|
480
- file.puts <<-DATABASE_YML
481
- <%
482
-
483
- require 'cgi'
484
- require 'uri'
485
-
486
- begin
487
- uri = URI.parse(ENV["DATABASE_URL"])
488
- rescue URI::InvalidURIError
489
- raise "Invalid DATABASE_URL"
490
- end
491
-
492
- raise "No RACK_ENV or RAILS_ENV found" unless ENV["RAILS_ENV"] || ENV["RACK_ENV"]
493
-
494
- def attribute(name, value, force_string = false)
495
- if value
496
- value_string =
497
- if force_string
498
- '"' + value + '"'
499
- else
500
- value
501
- end
502
- "\#{name}: \#{value_string}"
503
- else
504
- ""
505
- end
506
- end
507
-
508
- adapter = uri.scheme
509
- adapter = "postgresql" if adapter == "postgres"
510
-
511
- database = (uri.path || "").split("/")[1]
512
-
513
- username = uri.user
514
- password = uri.password
515
-
516
- host = uri.host
517
- port = uri.port
518
-
519
- params = CGI.parse(uri.query || "")
520
-
521
- %>
522
-
523
- <%= ENV["RAILS_ENV"] || ENV["RACK_ENV"] %>:
524
- <%= attribute "adapter", adapter %>
525
- <%= attribute "database", database %>
526
- <%= attribute "username", username %>
527
- <%= attribute "password", password, true %>
528
- <%= attribute "host", host %>
529
- <%= attribute "port", port %>
530
-
531
- <% params.each do |key, value| %>
532
- <%= key %>: <%= value.first %>
533
- <% end %>
534
- DATABASE_YML
535
- end
536
- end
537
- end
538
-
539
- # add bundler to the load path
540
- # @note it sets a flag, so the path can only be loaded once
541
- def add_bundler_to_load_path
542
- return if @bundler_loadpath
543
- $: << File.expand_path(Dir["#{slug_vendor_base}/gems/bundler*/lib"].first)
544
- @bundler_loadpath = true
545
- end
546
-
547
- # detects whether the Gemfile.lock contains the Windows platform
548
- # @return [Boolean] true if the Gemfile.lock was created on Windows
549
- def has_windows_gemfile_lock?
550
- lockfile_parser.platforms.detect do |platform|
551
- /mingw|mswin/.match(platform.os) if platform.is_a?(Gem::Platform)
552
- end
553
- end
554
-
555
- # detects if a gem is in the bundle.
556
- # @param [String] name of the gem in question
557
- # @return [String, nil] if it finds the gem, it will return the line from bundle show or nil if nothing is found.
558
- def gem_is_bundled?(gem)
559
- @bundler_gems ||= lockfile_parser.specs.map(&:name)
560
- @bundler_gems.include?(gem)
561
- end
562
-
563
- # setup the lockfile parser
564
- # @return [Bundler::LockfileParser] a Bundler::LockfileParser
565
- def lockfile_parser
566
- add_bundler_to_load_path
567
- @lockfile_parser ||= LanguagePack::Ruby.lockfile_parser
568
- end
569
-
570
- # detects if a rake task is defined in the app
571
- # @param [String] the task in question
572
- # @return [Boolean] true if the rake task is defined in the app
573
- def rake_task_defined?(task)
574
- run("env PATH=$PATH bundle exec rake #{task} --dry-run") && $?.success?
575
- end
576
-
577
- # executes the block with GIT_DIR environment variable removed since it can mess with the current working directory git thinks it's in
578
- # @param [block] block to be executed in the GIT_DIR free context
579
- def allow_git(&blk)
580
- git_dir = ENV.delete("GIT_DIR") # can mess with bundler
581
- blk.call
582
- ENV["GIT_DIR"] = git_dir
583
- end
584
-
585
- # decides if we need to enable the dev database addon
586
- # @return [Array] the database addon if the pg gem is detected or an empty Array if it isn't.
587
- def add_dev_database_addon
588
- gem_is_bundled?("pg") ? ['heroku-postgresql:dev'] : []
589
- end
590
-
591
- # decides if we need to install the node.js binary
592
- # @note execjs will blow up if no JS RUNTIME is detected and is loaded.
593
- # @return [Array] the node.js binary path if we need it or an empty Array
594
- def add_node_js_binary
595
- gem_is_bundled?('execjs') ? [NODE_JS_BINARY_PATH] : []
596
- end
597
-
598
- def run_assets_precompile_rake_task
599
- if rake_task_defined?("assets:precompile")
600
- require 'benchmark'
601
-
602
- topic "Running: rake assets:precompile"
603
- time = Benchmark.realtime { pipe("env PATH=$PATH:bin bundle exec rake assets:precompile 2>&1") }
604
- if $?.success?
605
- puts "Asset precompilation completed (#{"%.2f" % time}s)"
606
- end
607
- end
608
- end
609
-
610
- def bundler_cache
611
- "vendor/bundle"
612
- end
613
-
614
- def load_bundler_cache
615
- cache_load "vendor"
616
-
617
- full_ruby_version = run_stdout(%q(ruby -v)).chomp
618
- rubygems_version = run_stdout(%q(gem -v)).chomp
619
- heroku_metadata = "vendor/heroku"
620
- old_rubygems_version = nil
621
- ruby_version_cache = "#{heroku_metadata}/ruby_version"
622
- buildpack_version_cache = "#{heroku_metadata}/buildpack_version"
623
- bundler_version_cache = "#{heroku_metadata}/bundler_version"
624
- rubygems_version_cache = "#{heroku_metadata}/rubygems_version"
625
-
626
- old_rubygems_version = File.read(rubygems_version_cache).chomp if File.exists?(rubygems_version_cache)
627
-
628
- # fix bug from v37 deploy
629
- if File.exists?("vendor/ruby_version")
630
- puts "Broken cache detected. Purging build cache."
631
- cache_clear("vendor")
632
- FileUtils.rm_rf("vendor/ruby_version")
633
- purge_bundler_cache
634
- # fix bug introduced in v38
635
- elsif !File.exists?(buildpack_version_cache) && File.exists?(ruby_version_cache)
636
- puts "Broken cache detected. Purging build cache."
637
- purge_bundler_cache
638
- elsif cache_exists?(bundler_cache) && File.exists?(ruby_version_cache) && full_ruby_version != File.read(ruby_version_cache).chomp
639
- puts "Ruby version change detected. Clearing bundler cache."
640
- puts "Old: #{File.read(ruby_version_cache).chomp}"
641
- puts "New: #{full_ruby_version}"
642
- purge_bundler_cache
643
- end
644
-
645
- # fix git gemspec bug from Bundler 1.3.0+ upgrade
646
- if File.exists?(bundler_cache) && !File.exists?(bundler_version_cache) && !run("find vendor/bundle/*/*/bundler/gems/*/ -name *.gemspec").include?("No such file or directory")
647
- puts "Old bundler cache detected. Clearing bundler cache."
648
- purge_bundler_cache
649
- end
650
-
651
- # fix for https://github.com/heroku/heroku-buildpack-ruby/issues/86
652
- if (!File.exists?(rubygems_version_cache) ||
653
- (old_rubygems_version == "2.0.0" && old_rubygems_version != rubygems_version)) &&
654
- File.exists?(ruby_version_cache) && File.read(ruby_version_cache).chomp.include?("ruby 2.0.0p0")
655
- puts "Updating to rubygems #{rubygems_version}. Clearing bundler cache."
656
- purge_bundler_cache
657
- end
658
-
659
- FileUtils.mkdir_p(heroku_metadata)
660
- File.open(ruby_version_cache, 'w') do |file|
661
- file.puts full_ruby_version
662
- end
663
- File.open(buildpack_version_cache, 'w') do |file|
664
- file.puts BUILDPACK_VERSION
665
- end
666
- File.open(bundler_version_cache, 'w') do |file|
667
- file.puts BUNDLER_VERSION
668
- end
669
- File.open(rubygems_version_cache, 'w') do |file|
670
- file.puts rubygems_version
671
- end
672
- cache_store heroku_metadata
673
- end
674
-
675
- def purge_bundler_cache
676
- FileUtils.rm_rf(bundler_cache)
677
- cache_clear bundler_cache
678
- # need to reinstall language pack gems
679
- install_language_pack_gems
680
- end
681
- end