-
Notifications
You must be signed in to change notification settings - Fork 1.9k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Ruby version installation errors and warnings
Currently when a customer tries to upgrade their stack and are using an old version of Ruby they get a very unhelpful error: ``` Command: 'set -o pipefail; curl -L --fail --retry 5 --retry-delay 1 --connect-timeout 3 --max-time 30 https://s3-external-1.amazonaws.com/heroku-buildpack-ruby/heroku-18/ruby-1.9.3.tgz -s -o - | tar zxf - ' failed on attempt 1 of 3. Command: 'set -o pipefail; curl -L --fail --retry 5 --retry-delay 1 --connect-timeout 3 --max-time 30 https://s3-external-1.amazonaws.com/heroku-buildpack-ruby/heroku-18/ruby-1.9.3.tgz -s -o - | tar zxf - ' failed on attempt 2 of 3. ! ! An error occurred while installing ruby-1.9.3 ! ! Heroku recommends you use the latest supported Ruby version listed here: ! https://devcenter.heroku.com/articles/ruby-support#supported-runtimes ! ! For more information on syntax for declaring a Ruby version see: ! https://devcenter.heroku.com/articles/ruby-versions ! ! ! Debug InformationCommand: 'set -o pipefail; curl -L --fail --retry 5 --retry-delay 1 --connect-timeout 3 --max-time 30 https://s3-external-1.amazonaws.com/heroku-buildpack-ruby/heroku-18/ruby-1.9.3.tgz -s -o - | tar zxf - ' failed unexpectedly: ! ! gzip: stdin: unexpected end of file ! tar: Child returned status 1 ! tar: Error is not recoverable: exiting now ! ! Push rejected, failed to compile Ruby app. ! Push failed ``` This is awful and gives no context. The goal of this PR is to do a few things: - If a Ruby version does not exist on any stack, explicitly state the problem - If a Ruby version exists, but not on your current stack, list the stacks it is present on - If a Ruby version exists, but not for the next stack (i.e. heroku-16 if you're deploying to cedar-14) then the customer should get a warning
- Loading branch information
Showing
6 changed files
with
188 additions
and
46 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
# This class is used to check whether a binary exists on one or more stacks. | ||
# The main motivation for adding this logic is to help people who are upgrading | ||
# to a new stack if it does not have a given Ruby version. For example if someone | ||
# is using Ruby 1.9.3 on the cedar-14 stack then they should be informed that it | ||
# does not exist if they try to use it on the Heroku-18 stack. | ||
# | ||
# Example | ||
# | ||
# download = LanguagePack::Helpers::DownloadPresence.new( | ||
# 'ruby-1.9.3.tgz', | ||
# stacks: ['cedar-14', 'heroku-16', 'heroku-18'] | ||
# ) | ||
# | ||
# download.call | ||
# | ||
# puts download.exists? #=> true | ||
# puts download.valid_stack_list #=> ['cedar-14'] | ||
class LanguagePack::Helpers::DownloadPresence | ||
STACKS = ['cedar-14', 'heroku-16', 'heroku-18'] | ||
|
||
def initialize(path, stacks: STACKS) | ||
@path = path | ||
@stacks = stacks | ||
@fetchers = [] | ||
@threads = [] | ||
@stacks.each do |stack| | ||
@fetchers << LanguagePack::Fetcher.new(LanguagePack::Base::VENDOR_URL, stack) | ||
end | ||
end | ||
|
||
def next_stack(stack) | ||
next_index = @stacks.index(stack) + 1 | ||
|
||
@stacks[next_index] | ||
end | ||
|
||
def exists_on_next_stack?(stack) | ||
next_index = @stacks.index(stack) + 1 | ||
@threads[next_index] | ||
end | ||
|
||
def valid_stack_list | ||
raise "not invoked yet, use the `call` method first" if @threads.empty? | ||
|
||
@threads.map.with_index do |thread, i| | ||
@stacks[i] if thread.value | ||
end.compact | ||
end | ||
|
||
def exists? | ||
raise "not invoked yet, use the `call` method first" if @threads.empty? | ||
|
||
@threads.any? {|t| t.value } | ||
end | ||
|
||
def does_not_exist? | ||
!exists? | ||
end | ||
|
||
def call | ||
@fetchers.map do |fetcher| | ||
@threads << Thread.new do | ||
fetcher.exists?(@path) | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
require "spec_helper" | ||
|
||
describe LanguagePack::Helpers::DownloadPresence do | ||
it "knows if exists on the next stack" do | ||
download = LanguagePack::Helpers::DownloadPresence.new( | ||
'ruby-1.9.3.tgz', | ||
stacks: ['cedar-14', 'heroku-16', 'heroku-18'] | ||
) | ||
|
||
download.call | ||
|
||
expect(download.next_stack("cedar-14")).to eq("heroku-16") | ||
expect(download.next_stack("heroku-16")).to eq("heroku-18") | ||
expect(download.next_stack("heroku-18")).to be_falsey | ||
|
||
expect(download.exists_on_next_stack?("cedar-14")).to be_truthy | ||
end | ||
|
||
|
||
it "detects when a package is not present on higher stacks" do | ||
download = LanguagePack::Helpers::DownloadPresence.new( | ||
'ruby-1.9.3.tgz', | ||
stacks: ['cedar-14', 'heroku-16', 'heroku-18'] | ||
) | ||
|
||
download.call | ||
|
||
expect(download.exists?).to eq(true) | ||
expect(download.valid_stack_list).to eq(['cedar-14']) | ||
end | ||
|
||
it "detects when a package is present on two stacks but not a third" do | ||
download = LanguagePack::Helpers::DownloadPresence.new( | ||
'ruby-2.3.0.tgz', | ||
stacks: ['cedar-14', 'heroku-16', 'heroku-18'] | ||
) | ||
|
||
download.call | ||
|
||
expect(download.exists?).to eq(true) | ||
expect(download.valid_stack_list).to eq(['cedar-14', 'heroku-16']) | ||
end | ||
|
||
it "detects when a package does not exist" do | ||
download = LanguagePack::Helpers::DownloadPresence.new( | ||
'does-not-exist.tgz', | ||
stacks: ['cedar-14', 'heroku-16', 'heroku-18'] | ||
) | ||
|
||
download.call | ||
|
||
expect(download.exists?).to eq(false) | ||
expect(download.valid_stack_list).to eq([]) | ||
end | ||
|
||
it "detects default ruby version" do | ||
download = LanguagePack::Helpers::DownloadPresence.new( | ||
"#{LanguagePack::RubyVersion::DEFAULT_VERSION}.tgz", | ||
) | ||
|
||
download.call | ||
|
||
expect(download.exists?).to eq(true) | ||
expect(download.valid_stack_list).to include(LanguagePack::Helpers::DownloadPresence::STACKS.last) | ||
end | ||
end |