heroku_san 4.3.0 → 4.3.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,5 +1,20 @@
1
1
  language: ruby
2
+ bundler_args: --without development
3
+ script: "bundle exec rake travis"
2
4
  rvm:
3
- - 1.8.7
4
5
  - 1.9.2
5
6
  - 1.9.3
7
+ - 2.0.0
8
+ env:
9
+ global:
10
+ - secure: dAxfEdg/7Cb/G9vkrn/ifdvycbXWtK2ey60JMepOxx9v3QyaqoSY3w5G0QB+4+uyOYmHwtif8tnK3Sa8jbBgqhAlXaxqxOT8WmQKYlhSgwWX4lQe4lUM5jkOkfNHRMRaQvCAn27gNAjdIRU7sb2cU/pm64eAFbU01TejJOM7Aow=
11
+ before_install:
12
+ - wget -qO- https://toolbelt.heroku.com/install-ubuntu.sh | sh
13
+ before_script:
14
+ - git config --global user.name "Travis CI"
15
+ - git config --global user.email "travis@example.com"
16
+ - echo -e "Host heroku.com\n\tStrictHostKeyChecking no\n" >> ~/.ssh/config
17
+ - ./spec/support/travis-ssh-keygen.sh < /dev/null
18
+ - heroku keys:add ~/.ssh/id_rsa.pub < /dev/null
19
+ after_script:
20
+ - ./spec/support/travis-key-cleanup.sh
data/Gemfile CHANGED
@@ -3,21 +3,27 @@ source 'https://rubygems.org'
3
3
  # Specify dependencies in heroku_san.gemspec
4
4
  gemspec
5
5
 
6
- group :development do
7
- gem 'rails', '>= 2'
8
- gem 'rspec'
6
+ group :test do
9
7
  gem 'aruba'
8
+ gem 'bundler', '~> 1.1'
10
9
  gem 'cucumber'
10
+ gem 'godot'
11
+ gem 'rails', '3.2.7'
11
12
  gem 'rake'
12
- gem 'bundler', '~> 1.1'
13
+ gem 'rspec', '~> 2.14'
14
+ gem 'sqlite3'
15
+ gem 'pg'
16
+ end
17
+
18
+ group :development do
13
19
  gem 'git-smart'
14
- gem 'godot'
15
20
  gem 'guard'
16
- gem 'rb-inotify', :require => false
17
- gem 'rb-fsevent', :require => false
18
- gem 'rb-fchange', :require => false
19
- gem 'terminal-notifier-guard'
20
- gem 'guard-rspec'
21
21
  gem 'guard-bundler'
22
22
  gem 'guard-cucumber'
23
+ gem 'guard-rspec'
24
+ gem 'rb-fchange', :require => false
25
+ gem 'rb-fsevent', :require => false
26
+ gem 'rb-inotify', :require => false
27
+ gem 'terminal-notifier-guard'
28
+ gem 'travis', '~> 1.5.6'
23
29
  end
data/Rakefile CHANGED
@@ -3,6 +3,8 @@ require 'rubygems'
3
3
  require 'bundler/setup'
4
4
  require 'bundler/gem_tasks'
5
5
  require 'rspec/core/rake_task'
6
+ require 'cucumber'
7
+ require 'cucumber/rake/task'
6
8
 
7
9
  desc 'Default: run unit tests.'
8
10
  task :default => :spec
@@ -11,3 +13,18 @@ desc "Run all specs"
11
13
  RSpec::Core::RakeTask.new do |t|
12
14
  t.pattern = 'spec/**/*_spec.rb'
13
15
  end
16
+
17
+ namespace 'cucumber' do
18
+ Cucumber::Rake::Task.new(:remote) do |t|
19
+ t.profile = "remote"
20
+ end
21
+
22
+ Cucumber::Rake::Task.new(:default) do |t|
23
+ t.profile = "default"
24
+ end
25
+ end
26
+
27
+ desc "Run travis test suite"
28
+ task :travis => [:spec, 'cucumber:default', 'cucumber:remote']
29
+
30
+ # for app in `heroku apps | tail +2`; do heroku apps:destroy --app $app --confirm $app; done
@@ -8,7 +8,7 @@ Feature: heroku_san can control a project on Heroku
8
8
  Scenario: Installs a project
9
9
  Given I have a new Rails project
10
10
  When I am in the project directory
11
- And I add heroku_san to the Gemfile
11
+ And I add heroku_san to the rails Gemfile
12
12
  Then rake reports that the heroku: tasks are available
13
13
 
14
14
  Scenario: Manipulates a Rails app on Heroku
@@ -0,0 +1,47 @@
1
+ @slow_process @announce-cmd
2
+ Feature: heroku_san can shell out to heroku without errors
3
+
4
+ Scenario: Bundling a ruby 2.0 project
5
+ Given I run `mkdir -p ruby2test`
6
+ And I cd to "ruby2test"
7
+ And I write to "Gemfile" with:
8
+ """
9
+ source "https://rubygems.org"
10
+ ruby '2.0.0'
11
+ gem 'heroku_san', :path => '../../../.'
12
+ """
13
+
14
+ And I write to "get_heroku_version.rb" with:
15
+ """
16
+ #!/usr/bin/env ruby
17
+
18
+ puts ENV['RUBY_VERSION']
19
+
20
+ ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../Gemfile', __FILE__)
21
+
22
+ require 'bundler/setup'
23
+
24
+ require 'heroku_san'
25
+
26
+ api = HerokuSan::API.new
27
+
28
+ api.sh('cool_app', 'version')
29
+ """
30
+ And I write to "run_in_ruby_2.sh" with:
31
+ """
32
+ #!/usr/bin/env bash
33
+
34
+ [[ -s "$HOME/.rvm/scripts/rvm" ]] && source "$HOME/.rvm/scripts/rvm"
35
+
36
+ rvm use 2.0.0
37
+ bundle install
38
+
39
+ ruby get_heroku_version.rb
40
+ """
41
+ And I run `chmod +x run_in_ruby_2.sh`
42
+ And I cleanly run `./run_in_ruby_2.sh`
43
+ Then the output should contain "heroku-toolbelt"
44
+ # Fail if we see "Your Ruby version is 1.9.3, but your Gemfile specified 2.0.0"
45
+ Then the output should not contain "Your Ruby version"
46
+ Then the output should not contain "your Gemfile specified"
47
+
@@ -54,7 +54,7 @@ end
54
54
  When /^I add heroku_san to the rails Gemfile$/ do
55
55
  overwrite_file 'Gemfile', <<EOT.strip_heredoc
56
56
  source 'https://rubygems.org'
57
- ruby '1.9.3'
57
+ ruby '#{ruby_version}'
58
58
  gem 'rails', '3.2.7'
59
59
  gem 'pg'
60
60
  group :development, :test do
@@ -67,7 +67,7 @@ end
67
67
  When /^I add heroku_san to the sinatra Gemfile$/ do
68
68
  overwrite_file 'Gemfile', <<EOT.strip_heredoc
69
69
  source 'https://rubygems.org'
70
- ruby '1.9.3'
70
+ ruby '#{ruby_version}'
71
71
  gem 'sinatra'
72
72
  group :development, :test do
73
73
  gem 'heroku_san', :path => '../../../.'
@@ -87,6 +87,10 @@ When /^I run bundle install$/ do
87
87
  run_clean "bundle install"
88
88
  end
89
89
 
90
+ When /^I cleanly run `([^`]*)`$/ do |cmd|
91
+ run_clean(cmd)
92
+ end
93
+
90
94
  Then /^rake reports that the heroku: tasks are available$/ do
91
95
  output = run_clean 'rake -T heroku:'
92
96
  assert_partial_output 'rake heroku:apps', output
@@ -197,13 +201,14 @@ When /^I install an addon$/ do
197
201
  test_app:
198
202
  app: #{@app}
199
203
  addons:
200
- - scheduler:standard
204
+ - heroku-postgresql:dev
205
+ - pgbackups:plus
201
206
 
202
207
  END_CONFIG
203
208
 
204
209
  output = run_clean 'rake test_app heroku:addons'
205
210
  # The output should show the new one ...
206
- assert_partial_output "scheduler:standard", output
211
+ assert_partial_output "heroku-postgresql:dev", output
207
212
  end
208
213
 
209
214
  Then /^(?:heroku_san|issue \d+) (?:is green|has been fixed)$/ do
@@ -230,3 +235,7 @@ def overwrite_simple_config_file
230
235
 
231
236
  EOT
232
237
  end
238
+
239
+ def ruby_version
240
+ ENV['TRAVIS_RUBY_VERSION'] || '1.9.3'
241
+ end
@@ -23,23 +23,8 @@ Gem::Specification.new do |s|
23
23
  https://toolbelt.heroku.com/
24
24
  }
25
25
 
26
- if s.respond_to? :specification_version then
27
- s.specification_version = 3
28
-
29
- if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
30
- s.add_runtime_dependency(%q<heroku-api>, ['>= 0.1.2'])
31
- s.add_runtime_dependency(%q<rake>)
32
- else
33
- s.add_dependency(%q<rails>, ['>= 2'])
34
- s.add_dependency(%q<heroku-api>, ['>= 0.1.2'])
35
- s.add_dependency(%q<aruba>)
36
- s.add_dependency(%q<cucumber>)
37
- end
38
- else
39
- s.add_dependency(%q<rails>, ['>= 2'])
40
- s.add_dependency(%q<heroku-api>, ['>= 0.1.2'])
41
- s.add_dependency(%q<aruba>)
42
- s.add_dependency(%q<cucumber>)
43
- end
26
+ s.add_runtime_dependency("heroku-api", [">= 0.1.2"])
27
+ s.add_runtime_dependency("json")
28
+ s.add_runtime_dependency("rake")
44
29
  end
45
30
 
@@ -3,7 +3,23 @@ require 'time'
3
3
  module HerokuSan
4
4
  class API
5
5
  def initialize(options = {})
6
- @heroku_api = Heroku::API.new(options)
6
+ @options = options
7
+ @options[:api_key] ||= auth_token
8
+ @heroku_api = Heroku::API.new(@options)
9
+ end
10
+
11
+ def sh(app, *command)
12
+ preflight_check_for_cli
13
+
14
+ cmd = (command + ['--app', app]).compact
15
+
16
+ show_command = cmd.join(' ')
17
+ $stderr.puts show_command if @debug
18
+
19
+ ok = Bundler.with_clean_env { system "heroku", *cmd }
20
+
21
+ status = $?
22
+ ok or fail "Command failed with status (#{status.exitstatus}): [heroku #{show_command}]"
7
23
  end
8
24
 
9
25
  def method_missing(name, *args)
@@ -15,5 +31,17 @@ module HerokuSan
15
31
  $stderr.puts "\nHeroku API ERROR: #{status} (#{msg})\n\n"
16
32
  raise error
17
33
  end
34
+
35
+ private
36
+
37
+ def auth_token
38
+ ENV['HEROKU_API_KEY'] || Bundler.with_clean_env { `heroku auth:token`.chomp }
39
+ rescue Errno::ENOENT
40
+ nil
41
+ end
42
+
43
+ def preflight_check_for_cli
44
+ raise "The Heroku Toolbelt is required for this action. http://toolbelt.heroku.com" if Bundler.with_clean_env { system('heroku version') == nil }
45
+ end
18
46
  end
19
- end
47
+ end
@@ -4,13 +4,15 @@ module HerokuSan
4
4
  attr_accessor :configuration
5
5
  attr_accessor :external_configuration
6
6
  attr_reader :options
7
+ attr_reader :stage_factory
7
8
 
8
- def initialize(configurable)
9
+ def initialize(configurable, stage_factory = HerokuSan::Stage)
9
10
  @config_file = configurable.config_file
10
11
  default_options = {
11
12
  'deploy' => HerokuSan::Deploy::Rails
12
13
  }
13
14
  @options = default_options.merge(configurable.options || {})
15
+ @stage_factory = stage_factory
14
16
  end
15
17
 
16
18
  def parse
@@ -20,7 +22,7 @@ module HerokuSan
20
22
  def stages
21
23
  configured? or parse
22
24
  configuration.inject({}) do |stages, (stage, settings)|
23
- stages[stage] = HerokuSan::Stage.new(stage, settings.merge('deploy' => (options[:deploy]||options['deploy'])))
25
+ stages[stage] = stage_factory.new(stage, settings.merge('deploy' => (options[:deploy]||options['deploy'])))
24
26
  stages
25
27
  end
26
28
  end
@@ -2,28 +2,23 @@ require 'heroku-api'
2
2
  require 'json'
3
3
  require_relative 'application'
4
4
 
5
- MOCK = false unless defined?(MOCK)
6
-
7
5
  module HerokuSan
8
6
  class Stage
9
7
  include HerokuSan::Git
10
- attr_reader :name
11
- attr_reader :options
12
8
  include HerokuSan::Application
13
9
 
10
+ attr_reader :name, :options, :heroku
11
+
14
12
  def initialize(stage, options = {})
15
13
  @name = stage
16
14
  @options = options
15
+ @heroku = options.delete(:api) || HerokuSan::API.new
17
16
  end
18
17
 
19
18
  def ==(other)
20
19
  other.name == name && other.options == options
21
20
  end
22
21
 
23
- def heroku
24
- @heroku ||= HerokuSan::API.new(:api_key => auth_token, :mock => MOCK)
25
- end
26
-
27
22
  def app
28
23
  @options['app'] or raise MissingApp, "#{name}: is missing the app: configuration value. I don't know what to access on Heroku."
29
24
  end
@@ -49,7 +44,7 @@ module HerokuSan
49
44
  end
50
45
 
51
46
  def run(command, args = nil)
52
- sh_heroku "run", command, *args
47
+ heroku.sh app, "run", command, *args
53
48
  end
54
49
 
55
50
  def push(sha = nil, force = false)
@@ -128,31 +123,11 @@ module HerokuSan
128
123
  end
129
124
 
130
125
  def logs(tail = false)
131
- sh_heroku 'logs', (tail ? '--tail' : nil)
126
+ heroku.sh app, 'logs', (tail ? '--tail' : nil)
132
127
  end
133
128
 
134
129
  def revision
135
130
  git_named_rev(git_revision(repo))
136
131
  end
137
-
138
- private
139
-
140
- def auth_token
141
- @auth_token ||= (ENV['HEROKU_API_KEY'] || `heroku auth:token`.chomp unless MOCK)
142
- end
143
-
144
- def sh_heroku(*command)
145
- preflight_check_for_cli
146
- cmd = (command + ['--app', app]).compact
147
- show_command = cmd.join(' ')
148
- $stderr.puts show_command if @debug
149
- ok = system "heroku", *cmd
150
- status = $?
151
- ok or fail "Command failed with status (#{status.exitstatus}): [heroku #{show_command}]"
152
- end
153
-
154
- def preflight_check_for_cli
155
- raise "The Heroku Toolbelt is required for this action. http://toolbelt.heroku.com" if system('heroku version') == nil
156
- end
157
132
  end
158
133
  end
@@ -1,3 +1,3 @@
1
1
  module HerokuSan
2
- VERSION = "4.3.0"
2
+ VERSION = "4.3.1"
3
3
  end
@@ -3,7 +3,7 @@ require 'spec_helper'
3
3
  # https://github.com/fastestforward/heroku_san/issues/105
4
4
  module HerokuSan
5
5
  describe HerokuSan::API do
6
- subject(:api) { HerokuSan::API.new(:api_key => 'key', :mock => true)}
6
+ subject(:api) { HerokuSan::API.new(:api_key => 'key', :double => true)}
7
7
  it "is a proxy to the Heroku::API" do
8
8
  Heroku::API.any_instance.should_receive(:api_method).with(1, 2, {:arg => 3}) {true}
9
9
  api.api_method(1, 2, {:arg => 3}).should be_true
@@ -12,7 +12,7 @@ describe HerokuSan::API do
12
12
  it "reports Excon errors in a more human readable format" do
13
13
  error_message = 'Name is already taken'
14
14
  status_message = '000 Status'
15
- response = mock("Response", :body => %Q[{"error":"#{error_message}"}], :headers => {'Status' => status_message})
15
+ response = double("Response", :body => %Q[{"error":"#{error_message}"}], :headers => {'Status' => status_message})
16
16
  Heroku::API.any_instance.should_receive(:api_method).and_raise(Heroku::API::Errors::ErrorWithResponse.new("excon message", response))
17
17
 
18
18
  $stderr.should_receive(:puts).with("\nHeroku API ERROR: #{status_message} (#{error_message})\n\n")
@@ -2,8 +2,8 @@ require 'spec_helper'
2
2
 
3
3
  module HerokuSan
4
4
  describe HerokuSan::Application do
5
- let(:stage) { HerokuSan::Stage.new('production', {"deploy" => HerokuSan::Deploy::Rails, "app" => "awesomeapp", "stack" => "cedar"}) }
6
- let(:response) { stub }
5
+ let(:stage) { Factory::Stage.build('production', {"deploy" => HerokuSan::Deploy::Rails, "app" => "awesomeapp", "stack" => "cedar"}) }
6
+ let(:response) { double }
7
7
 
8
8
  before do
9
9
  stage.heroku.stub(:get_ps).with(stage.app) { response }
@@ -3,13 +3,13 @@ require 'spec_helper'
3
3
  module HerokuSan
4
4
  describe HerokuSan::Configuration do
5
5
  let(:configurable) { Configurable.new }
6
- let(:configuration) { HerokuSan::Configuration.new(configurable) }
6
+ let(:configuration) { HerokuSan::Configuration.new(configurable, Factory::Stage) }
7
7
 
8
8
  describe "#stages" do
9
9
  it "creates a configuration hash" do
10
10
  configuration.configuration = {'production' => {}}
11
11
  configuration.stages.should == {
12
- 'production' => HerokuSan::Stage.new('production', 'deploy' => HerokuSan::Deploy::Rails)
12
+ 'production' => Factory::Stage.build('production', 'deploy' => HerokuSan::Deploy::Rails)
13
13
  }
14
14
  end
15
15
 
@@ -17,7 +17,7 @@ describe HerokuSan::Configuration do
17
17
  configurable.options = {'deploy' => HerokuSan::Deploy::Base}
18
18
  configuration.configuration = {'production' => {}}
19
19
  configuration.stages.should == {
20
- 'production' => HerokuSan::Stage.new('production', 'deploy' => HerokuSan::Deploy::Base)
20
+ 'production' => Factory::Stage.build('production', 'deploy' => HerokuSan::Deploy::Base)
21
21
  }
22
22
  end
23
23
  end
@@ -3,7 +3,7 @@ require 'spec_helper'
3
3
  module HerokuSan
4
4
  module Deploy
5
5
  describe Base do
6
- let(:stage) { HerokuSan::Stage.new('test', {"app" => "awesomeapp", "deploy" => 'HerokuSan::Deploy::Base'}) }
6
+ let(:stage) { Factory::Stage.build('test', {"app" => "awesomeapp", "deploy" => 'HerokuSan::Deploy::Base'}) }
7
7
 
8
8
  it "calls push" do
9
9
  subject = described_class.new(stage)
@@ -3,7 +3,7 @@ require 'spec_helper'
3
3
  module HerokuSan
4
4
  module Deploy
5
5
  describe Rails do
6
- let(:stage) { HerokuSan::Stage.new('test', {"app" => "awesomeapp", "deploy" => 'HerokuSan::Deploy::Rails'}) }
6
+ let(:stage) { Factory::Stage.build('test', {"app" => "awesomeapp", "deploy" => 'HerokuSan::Deploy::Rails'}) }
7
7
 
8
8
  it "calls push, rake db:migrate & restart" do
9
9
  subject = described_class.new(stage, {})
@@ -54,13 +54,13 @@ describe HerokuSan::Parser do
54
54
  end
55
55
 
56
56
  describe "#merge_external_config" do
57
- let(:stages) { [stub(:name => 'production', :config => prod_config), stub(:name => 'staging', :config => staging_config)] }
58
- let(:prod_config) { mock('Production Config') }
57
+ let(:stages) { [double(:name => 'production', :config => prod_config), double(:name => 'staging', :config => staging_config)] }
58
+ let(:prod_config) { double('Production Config') }
59
59
  let(:staging_config) { {'EXTRA' => 'bar'} }
60
60
  let(:extras) { {'production' => {'EXTRA' => 'bar'}, 'staging' => {'EXTRA' => 'foo'}} }
61
61
 
62
62
  context "with no extras" do
63
- let(:parseable) { stub :external_configuration => nil }
63
+ let(:parseable) { double :external_configuration => nil }
64
64
 
65
65
  it "doesn't change prod_config" do
66
66
  prod_config.should_not_receive :merge!
@@ -69,7 +69,7 @@ describe HerokuSan::Parser do
69
69
  end
70
70
 
71
71
  context "with extra" do
72
- let(:parseable) { stub :external_configuration => 'config_repos' }
72
+ let(:parseable) { double :external_configuration => 'config_repos' }
73
73
  before(:each) do
74
74
  parser.should_receive(:git_clone).with('config_repos', anything)
75
75
  parser.should_receive(:parse_yaml).and_return(extras)
@@ -6,7 +6,7 @@ describe HerokuSan::Project do
6
6
  let(:heroku_san) { HerokuSan::Project.new }
7
7
  subject { heroku_san }
8
8
  before do
9
- HerokuSan::Configuration.new(Configurable.new).tap do |config|
9
+ HerokuSan::Configuration.new(Configurable.new, Factory::Stage).tap do |config|
10
10
  config.configuration = {'production' => {}, 'staging' => {}, 'demo' => {}}
11
11
  heroku_san.configuration = config
12
12
  end
@@ -1,21 +1,22 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  module HerokuSan
4
+ STOCK_CONFIG = {"BUNDLE_WITHOUT"=>"development:test", "LANG"=>"en_US.UTF-8", "RACK_ENV"=>"production"}
5
+
4
6
  describe HerokuSan::Stage do
5
7
  include HerokuSan::Git
6
- subject { HerokuSan::Stage.new('production', {"deploy" => HerokuSan::Deploy::Rails, "app" => "awesomeapp", "stack" => "cedar"})}
7
- STOCK_CONFIG = {"BUNDLE_WITHOUT"=>"development:test", "LANG"=>"en_US.UTF-8", "RACK_ENV"=>"production"}
8
+ subject { Factory::Stage.build('production', {"deploy" => HerokuSan::Deploy::Rails, "app" => "awesomeapp", "stack" => "cedar"})}
8
9
  before do
9
- HerokuSan::Stage.any_instance.stub(:preflight_check_for_cli)
10
+ HerokuSan::API.any_instance.stub(:preflight_check_for_cli)
10
11
  end
11
12
 
12
13
  context "initializes" do
13
- subject { HerokuSan::Stage.new('production',
14
+ subject { Factory::Stage.build('production',
14
15
  {"stack" => "cedar",
15
16
  "app" => "awesomeapp-demo",
16
17
  "tag" => "demo/*",
17
18
  "config"=> {"BUNDLE_WITHOUT"=>"development:test"},
18
- "addons"=> ['one:addon', 'two:addons'],
19
+ "addons"=> ['one:addon', 'two:addons']
19
20
  })}
20
21
 
21
22
  its(:name) { should == 'production' }
@@ -30,7 +31,7 @@ describe HerokuSan::Stage do
30
31
  describe "#app" do
31
32
  its(:app) { should == 'awesomeapp'}
32
33
  context "blank app" do
33
- subject { HerokuSan::Stage.new('production') }
34
+ subject { Factory::Stage.build('production') }
34
35
  it "should raise an error" do
35
36
  expect { subject.app }.to raise_error(HerokuSan::MissingApp, /production: is missing the app: configuration value\./)
36
37
  end
@@ -39,20 +40,20 @@ describe HerokuSan::Stage do
39
40
 
40
41
  describe "#stack" do
41
42
  it "returns the name of the stack from Heroku" do
42
- subject = HerokuSan::Stage.new('production', {"app" => "awesomeapp"})
43
+ subject = Factory::Stage.build('production', {"app" => "awesomeapp"})
43
44
  with_app(subject, 'name' => subject.app) do |app_data|
44
45
  subject.stack.should == 'bamboo-mri-1.9.2'
45
46
  end
46
47
  end
47
48
 
48
49
  it "returns the stack name from the config when it is set there" do
49
- subject = HerokuSan::Stage.new('production', {"app" => "awesomeapp", "stack" => "cedar"})
50
+ subject = Factory::Stage.build('production', {"app" => "awesomeapp", "stack" => "cedar"})
50
51
  subject.stack.should == 'cedar'
51
52
  end
52
53
  end
53
54
 
54
55
  describe '#addons' do
55
- subject { HerokuSan::Stage.new('production', {'addons' => addons}) }
56
+ subject { Factory::Stage.build('production', {'addons' => addons}) }
56
57
  context 'default' do
57
58
  let(:addons) { nil }
58
59
  its(:addons) { should == [] }
@@ -73,7 +74,7 @@ describe HerokuSan::Stage do
73
74
 
74
75
  describe "#run" do
75
76
  it "runs commands using the new cedar format" do
76
- subject.should_receive(:system).with("heroku", "run", "worker foo bar bleh", "--app", "awesomeapp") { true }
77
+ subject.heroku.should_receive(:system).with("heroku", "run", "worker foo bar bleh", "--app", "awesomeapp") { true }
77
78
  subject.run 'worker foo bar bleh'
78
79
  end
79
80
  end
@@ -123,7 +124,7 @@ describe HerokuSan::Stage do
123
124
  class TestDeployStrategy < HerokuSan::Deploy::Base
124
125
  def deploy; end
125
126
  end
126
- subject = HerokuSan::Stage.new('test', {"app" => "awesomeapp", "deploy" => TestDeployStrategy})
127
+ subject = Factory::Stage.build('test', {"app" => "awesomeapp", "deploy" => TestDeployStrategy})
127
128
  it "(custom) calls deploy" do
128
129
  TestDeployStrategy.any_instance.should_receive(:deploy)
129
130
  subject.deploy
@@ -154,7 +155,7 @@ describe HerokuSan::Stage do
154
155
  it "wraps it in a maintenance mode" do
155
156
  with_app(subject, 'name' => subject.app) do |app_data|
156
157
  subject.heroku.should_receive(:post_app_maintenance).with(subject.app, '1').ordered
157
- reactor = mock("Reactor"); reactor.should_receive(:scram).with(:now).ordered
158
+ reactor = double("Reactor"); reactor.should_receive(:scram).with(:now).ordered
158
159
  subject.heroku.should_receive(:post_app_maintenance).with(subject.app, '0').ordered
159
160
 
160
161
  subject.maintenance {reactor.scram(:now)}
@@ -164,7 +165,7 @@ describe HerokuSan::Stage do
164
165
  it "ensures that maintenance mode is turned off" do
165
166
  with_app(subject, 'name' => subject.app) do |app_data|
166
167
  subject.heroku.should_receive(:post_app_maintenance).with(subject.app, '1').ordered
167
- reactor = mock("Reactor"); reactor.should_receive(:scram).and_raise(RuntimeError)
168
+ reactor = double("Reactor"); reactor.should_receive(:scram).and_raise(RuntimeError)
168
169
  subject.heroku.should_receive(:post_app_maintenance).with(subject.app, '0').ordered
169
170
 
170
171
  expect do subject.maintenance {reactor.scram(:now)} end.to raise_error
@@ -183,12 +184,12 @@ describe HerokuSan::Stage do
183
184
  end
184
185
 
185
186
  it "creates an app on heroku" do
186
- subject = HerokuSan::Stage.new('production')
187
+ subject = Factory::Stage.build('production')
187
188
  (@app = subject.create).should =~ /generated-name-\d+/
188
189
  end
189
190
 
190
191
  it "uses the default stack if none is given" do
191
- subject = HerokuSan::Stage.new('production')
192
+ subject = Factory::Stage.build('production')
192
193
  (@app = subject.create).should =~ /generated-name-\d+/
193
194
  subject.heroku.get_stack(@app).body.detect{|stack| stack['current']}['name'].should == 'bamboo-mri-1.9.2'
194
195
  end
@@ -209,14 +210,14 @@ describe HerokuSan::Stage do
209
210
 
210
211
  describe "#push_config" do
211
212
  it "updates the configuration settings on Heroku" do
212
- subject = HerokuSan::Stage.new('test', {"app" => "awesomeapp", "config" => {'FOO' => 'bar', 'DOG' => 'emu'}})
213
+ subject = Factory::Stage.build('test', {"app" => "awesomeapp", "config" => {'FOO' => 'bar', 'DOG' => 'emu'}})
213
214
  with_app(subject, 'name' => subject.app) do |app_data|
214
215
  subject.push_config.should == STOCK_CONFIG.merge('FOO' => 'bar', 'DOG' => 'emu')
215
216
  end
216
217
  end
217
218
 
218
219
  it "pushes the options hash" do
219
- subject = HerokuSan::Stage.new('test', {"app" => "awesomeapp", "config" => {'FOO' => 'bar', 'DOG' => 'emu'}})
220
+ subject = Factory::Stage.build('test', {"app" => "awesomeapp", "config" => {'FOO' => 'bar', 'DOG' => 'emu'}})
220
221
  with_app(subject, 'name' => subject.app) do |app_data|
221
222
  subject.push_config('RACK_ENV' => 'magic').should == STOCK_CONFIG.merge('RACK_ENV' => 'magic')
222
223
  end
@@ -233,12 +234,12 @@ describe HerokuSan::Stage do
233
234
 
234
235
  describe "#logs" do
235
236
  it "returns log files" do
236
- subject.should_receive(:system).with("heroku", "logs", "--app", "awesomeapp") { true }
237
+ subject.heroku.should_receive(:system).with("heroku", "logs", "--app", "awesomeapp") { true }
237
238
  subject.logs
238
239
  end
239
240
 
240
241
  it "tails log files" do
241
- subject.should_receive(:system).with("heroku", "logs", "--tail", "--app", "awesomeapp") { true }
242
+ subject.heroku.should_receive(:system).with("heroku", "logs", "--tail", "--app", "awesomeapp") { true }
242
243
  subject.logs(:tail)
243
244
  end
244
245
  end
@@ -266,7 +267,7 @@ describe HerokuSan::Stage do
266
267
  end
267
268
 
268
269
  describe '#install_addons' do
269
- subject { HerokuSan::Stage.new('production', {"app" => "awesomeapp", "stack" => "bamboo-ree-1.8.7", "addons" => %w[custom_domains:basic ssl:piggyback]})}
270
+ subject { Factory::Stage.build('production', {"app" => "awesomeapp", "stack" => "bamboo-ree-1.8.7", "addons" => %w[custom_domains:basic ssl:piggyback]})}
270
271
 
271
272
  it "installs the addons" do
272
273
  with_app(subject, 'name' => subject.app) do |app_data|
@@ -276,7 +277,7 @@ describe HerokuSan::Stage do
276
277
  end
277
278
 
278
279
  it "only installs missing addons" do
279
- subject = HerokuSan::Stage.new('production', {"app" => "awesomeapp", "stack" => "bamboo-ree-1.8.7", "addons" => %w[shared-database:5mb custom_domains:basic ssl:piggyback]})
280
+ subject = Factory::Stage.build('production', {"app" => "awesomeapp", "stack" => "bamboo-ree-1.8.7", "addons" => %w[shared-database:5mb custom_domains:basic ssl:piggyback]})
280
281
  with_app(subject, 'name' => subject.app) do |app_data|
281
282
  subject.install_addons.map{|a| a['name']}.should include *%w[shared-database:5mb custom_domains:basic ssl:piggyback]
282
283
  end
@@ -3,8 +3,6 @@ Bundler.setup
3
3
 
4
4
  SPEC_ROOT = File.dirname(__FILE__)
5
5
 
6
- MOCK = ENV['MOCK'] != 'false'
7
-
8
6
  # Requires supporting ruby files with custom matchers and macros, etc,
9
7
  # in spec/support/ and its subdirectories.
10
8
  Dir[File.join(SPEC_ROOT, "support/**/*.rb")].each {|f| require f}
@@ -0,0 +1,14 @@
1
+ module Factory
2
+ class Stage
3
+ class << self
4
+ def build(stage, options = {})
5
+ HerokuSan::Stage.new(
6
+ stage,
7
+ options.merge({api: HerokuSan::API.new(:api_key => "MOCK", mock: true)})
8
+ )
9
+ end
10
+
11
+ alias :new :build
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,3 @@
1
+ #!/bin/sh
2
+
3
+ heroku keys:remove travis-${TRAVIS_JOB_ID}@example.com
@@ -0,0 +1,3 @@
1
+ #!/bin/sh
2
+
3
+ ssh-keygen -f ~/.ssh/id_rsa -C travis-${TRAVIS_JOB_ID}@example.com -N ''
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: heroku_san
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.3.0
4
+ version: 4.3.1
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -12,7 +12,7 @@ authors:
12
12
  autorequire:
13
13
  bindir: bin
14
14
  cert_chain: []
15
- date: 2013-07-29 00:00:00.000000000 Z
15
+ date: 2013-10-23 00:00:00.000000000 Z
16
16
  dependencies:
17
17
  - !ruby/object:Gem::Dependency
18
18
  name: heroku-api
@@ -30,6 +30,22 @@ dependencies:
30
30
  - - ! '>='
31
31
  - !ruby/object:Gem::Version
32
32
  version: 0.1.2
33
+ - !ruby/object:Gem::Dependency
34
+ name: json
35
+ requirement: !ruby/object:Gem::Requirement
36
+ none: false
37
+ requirements:
38
+ - - ! '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ type: :runtime
42
+ prerelease: false
43
+ version_requirements: !ruby/object:Gem::Requirement
44
+ none: false
45
+ requirements:
46
+ - - ! '>='
47
+ - !ruby/object:Gem::Version
48
+ version: '0'
33
49
  - !ruby/object:Gem::Dependency
34
50
  name: rake
35
51
  requirement: !ruby/object:Gem::Requirement
@@ -71,6 +87,7 @@ files:
71
87
  - features/extended-config.feature
72
88
  - features/issue_113.feature
73
89
  - features/remote.feature
90
+ - features/shell_execution.feature
74
91
  - features/step_definitions/remote_steps.rb
75
92
  - features/support/env.rb
76
93
  - heroku_san.gemspec
@@ -105,8 +122,11 @@ files:
105
122
  - spec/heroku_san/project_spec.rb
106
123
  - spec/heroku_san/stage_spec.rb
107
124
  - spec/spec_helper.rb
125
+ - spec/support/factory.rb
108
126
  - spec/support/heroku.rb
109
127
  - spec/support/mocks.rb
128
+ - spec/support/travis-key-cleanup.sh
129
+ - spec/support/travis-ssh-keygen.sh
110
130
  homepage: http://github.com/fastestforward/heroku_san
111
131
  licenses:
112
132
  - MIT
@@ -122,7 +142,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
122
142
  version: '0'
123
143
  segments:
124
144
  - 0
125
- hash: -1774718932546341856
145
+ hash: 364838446742760909
126
146
  required_rubygems_version: !ruby/object:Gem::Requirement
127
147
  none: false
128
148
  requirements:
@@ -141,6 +161,7 @@ test_files:
141
161
  - features/extended-config.feature
142
162
  - features/issue_113.feature
143
163
  - features/remote.feature
164
+ - features/shell_execution.feature
144
165
  - features/step_definitions/remote_steps.rb
145
166
  - features/support/env.rb
146
167
  - spec/fixtures/example.yml
@@ -156,5 +177,8 @@ test_files:
156
177
  - spec/heroku_san/project_spec.rb
157
178
  - spec/heroku_san/stage_spec.rb
158
179
  - spec/spec_helper.rb
180
+ - spec/support/factory.rb
159
181
  - spec/support/heroku.rb
160
182
  - spec/support/mocks.rb
183
+ - spec/support/travis-key-cleanup.sh
184
+ - spec/support/travis-ssh-keygen.sh