Created
February 8, 2014 01:37
-
-
Save JonRowe/8875343 to your computer and use it in GitHub Desktop.
Update heroku apps running old versions of libyaml.
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
require 'json' | |
class Shell | |
def self.heroku_apps | |
new('heroku apps').cache_at 'heroku_app_cache' | |
end | |
def self.ruby_version app | |
new("heroku run \"ruby -v\" --app #{app}").cache_at "ruby_version_#{app}" | |
end | |
def self.yaml_version app | |
new("heroku run \"ruby -r yaml -e 'puts Psych::LIBYAML_VERSION'\" --app #{app}").cache_at "yaml_version_#{app}" | |
end | |
def initialize cmd | |
@cmd = cmd | |
end | |
def cache_at key | |
from_key(key) || cache(key,from_cmd) | |
end | |
private | |
def json | |
@json ||= | |
begin | |
if File.exist?(file) | |
JSON.parse(File.read file) | |
else | |
{} | |
end | |
end | |
end | |
def from_key name | |
json[name] | |
end | |
def from_cmd | |
`#{@cmd}` | |
end | |
def cache name, string | |
json[name] = string | |
write_cache | |
string | |
end | |
def file | |
'./heroku_app_info.json' | |
end | |
def write_cache | |
File.open(file,'w+') { |file| file.write JSON.dump json } | |
end | |
end | |
class Heroku | |
def self.apps | |
new.apps | |
end | |
def self.ruby_version_for name | |
new.ruby_version_for name | |
end | |
def self.yaml_version_for name | |
new.yaml_version_for name | |
end | |
def apps | |
lines_containing_apps strip_trailing_info parse(Shell.heroku_apps) | |
end | |
def ruby_version_for name | |
RubyVersionString.new parse(Shell.ruby_version name).find { |line| line =~ /ruby\s+\d\.\d\.\d/ } | |
end | |
def yaml_version_for name | |
parse(Shell.yaml_version name).find { |line| line =~ /\d+\.\d+\.\d+/ } | |
end | |
private | |
def parse string | |
string.split("\n") | |
end | |
def strip_trailing_info lines | |
lines.map { |app| app.gsub(/\s+.*/,'') } | |
end | |
def lines_containing_apps lines | |
lines.select { |app| app =~ /^[\w-]+$/ } | |
end | |
end | |
class NestedHash < Hash | |
def initialize | |
super { |hash, key| hash[key] = Hash.new } | |
end | |
end | |
class RubyVersionString | |
def initialize string | |
@major, @patch = string.scan(/(\d\.\d\.\d)(?:-?p(\d\d\d))?/).first | |
end | |
attr_reader :major | |
def patch | |
@patch.to_i | |
end | |
end | |
module Versions | |
module_function | |
def for provider | |
provider.apps.inject(NestedHash.new) do |hash, app| | |
version = provider.ruby_version_for app | |
hash[version.major][app] = version.patch | |
hash | |
end | |
end | |
end | |
ALLOWED_VERSIONS = | |
{ | |
'1.9.3' => 484, | |
'2.0.0' => 353, | |
} | |
versions = Heroku.apps.map do |app| | |
[app, Heroku.ruby_version_for(app), Heroku.yaml_version_for(app)] | |
end | |
to_upgrade = versions.select do |app, ruby, version| | |
if version | |
major, minor, patch = version.split('.').map &:to_i | |
major <= 0 && minor <= 1 && patch <= 4 | |
end | |
end | |
to_upgrade.each do |app,ruby, version| | |
puts "App #{app} running old yaml version #{version} (#{ruby.major})" | |
`heroku git:clone #{app} && cd #{app} && git ci -m "rebuild yaml" --allow-empty && git push heroku master` | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment