Class: Fourchette::Heroku

Inherits:
Object
  • Object
show all
Includes:
Logger
Defined in:
lib/fourchette/heroku.rb

Constant Summary collapse

EXCEPTIONS =
[
  Excon::Errors::UnprocessableEntity,
  Excon::Errors::ServiceUnavailable
]

Instance Method Summary collapse

Methods included from Logger

#logger

Instance Method Details

#app_exists?(name) ⇒ Boolean

Returns:

  • (Boolean)


9
10
11
12
13
# File 'lib/fourchette/heroku.rb', line 9

def app_exists?(name)
  client.app.list.collect do |app|
    app if app['name'] == name
  end.reject(&:nil?).any?
end

#clientObject



28
29
30
31
# File 'lib/fourchette/heroku.rb', line 28

def client
  api_key = ENV['FOURCHETTE_HEROKU_API_KEY']
  @heroku_client ||= PlatformAPI.connect(api_key)
end

#config_vars(app_name) ⇒ Object



33
34
35
# File 'lib/fourchette/heroku.rb', line 33

def config_vars(app_name)
  client.config_var.info(app_name)
end

#copy_add_ons(from, to) ⇒ Object



57
58
59
60
61
62
63
64
65
66
67
68
69
70
# File 'lib/fourchette/heroku.rb', line 57

def copy_add_ons(from, to)
  logger.info "Copying addons from #{from} to #{to}"
  from_addons = client.addon.list(from)
  from_addons.each do |addon|
    name = addon['plan']['name']
    begin
      logger.info "Adding #{name} to #{to}"
      client.addon.create(to, plan: name)
    rescue *EXCEPTIONS => e
      logger.error "Failed to copy addon #{name}"
      logger.error e
    end
  end
end

#copy_config(from, to) ⇒ Object



46
47
48
49
50
51
52
53
54
55
# File 'lib/fourchette/heroku.rb', line 46

def copy_config(from, to)
  logger.info "Copying configs from #{from} to #{to}"
  from_congig_vars = config_vars(from)
  # WE SHOULD NOT MOVE THE HEROKU_POSTGRES_*_URL or DATABASE_URL...
  from_congig_vars.reject! do |k, _v|
    k.start_with?('HEROKU_POSTGRESQL_') && k.end_with?('_URL')
  end
  from_congig_vars.reject! { |k, _v| k == ('DATABASE_URL') }
  client.config_var.update(to, from_congig_vars)
end

#copy_pg(from, to) ⇒ Object



72
73
74
75
76
77
78
79
80
# File 'lib/fourchette/heroku.rb', line 72

def copy_pg(from, to)
  if pg_enabled?(from)
    logger.info "Copying Postgres's data from #{from} to #{to}"
    backup = Fourchette::Pgbackups.new
    backup.copy(from, to)
  else
    logger.info "Postgres not enabled on #{from}. Skipping data copy."
  end
end

#copy_rack_and_rails_env_again(from, to) ⇒ Object



82
83
84
85
# File 'lib/fourchette/heroku.rb', line 82

def copy_rack_and_rails_env_again(from, to)
  env_to_update = get_original_env(from)
  client.config_var.update(to, env_to_update) unless env_to_update.empty?
end

#create_app(name) ⇒ Object



41
42
43
44
# File 'lib/fourchette/heroku.rb', line 41

def create_app(name)
  logger.info "Creating #{name}"
  client.app.create(name: name)
end

#delete(app_name) ⇒ Object



23
24
25
26
# File 'lib/fourchette/heroku.rb', line 23

def delete(app_name)
  logger.info "Deleting #{app_name}"
  client.app.delete(app_name)
end

#fork(from, to) ⇒ Object



15
16
17
18
19
20
21
# File 'lib/fourchette/heroku.rb', line 15

def fork(from, to)
  create_app(to)
  copy_config(from, to)
  copy_add_ons(from, to)
  copy_pg(from, to)
  copy_rack_and_rails_env_again(from, to)
end

#get_original_env(from) ⇒ Object



87
88
89
90
91
92
93
94
95
# File 'lib/fourchette/heroku.rb', line 87

def get_original_env(from)
  environments = {}
  %w(RACK_ENV RAILS_ENV).each do |var|
    if client.config_var.info(from)[var]
      environments[var] = client.config_var.info(from)[var]
    end
  end
  environments
end

#git_url(app_name) ⇒ Object



37
38
39
# File 'lib/fourchette/heroku.rb', line 37

def git_url(app_name)
  client.app.info(app_name)['git_url']
end

#pg_enabled?(app) ⇒ Boolean

Returns:

  • (Boolean)


97
98
99
100
101
# File 'lib/fourchette/heroku.rb', line 97

def pg_enabled?(app)
  client.addon.list(app).any? do |addon|
    addon['addon_service']['name'] =~ /heroku.postgres/i
  end
end