heroku_san 4.3.2 → 4.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.ruby-version +1 -1
- data/.travis.yml +4 -3
- data/CHANGELOG.md +5 -0
- data/Gemfile +3 -11
- data/README.md +3 -2
- data/features/shell_execution.feature +3 -5
- data/features/step_definitions/remote_steps.rb +6 -7
- data/lib/heroku_san/api.rb +1 -1
- data/lib/heroku_san/version.rb +1 -1
- data/spec/heroku_san/api_spec.rb +5 -5
- data/spec/heroku_san/application_spec.rb +6 -6
- data/spec/heroku_san/configuration_spec.rb +8 -8
- data/spec/heroku_san/deploy/base_spec.rb +4 -4
- data/spec/heroku_san/deploy/rails_spec.rb +3 -3
- data/spec/heroku_san/git_spec.rb +28 -28
- data/spec/heroku_san/parser_spec.rb +12 -12
- data/spec/heroku_san/project_spec.rb +15 -15
- data/spec/heroku_san/stage_spec.rb +55 -55
- metadata +19 -30
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 3a9578dfc90a0553a24f7ec7ee3059d872b6ab98
|
4
|
+
data.tar.gz: 3267d16a4619e35fd9109ede728c98dcd75b6d4b
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 232012170dde11b1fdb6399d9d036a2aec44517182fbb2a77f49bad94c7b5a1361057fe7d1458bca2c9bffa4bef7b7140d848b224063dc8eb7e67554d5e0e0f5
|
7
|
+
data.tar.gz: 00c8e215b7c4fb746e6b8e2d3efb58e86eea8be063704a302b4ee06dba2f01d26096d0b84fe4fc562c6df849daf4136676459dfa52bbb9e62196802a5dd5197d
|
data/.ruby-version
CHANGED
@@ -1 +1 @@
|
|
1
|
-
|
1
|
+
2.2.4
|
data/.travis.yml
CHANGED
@@ -2,9 +2,10 @@ language: ruby
|
|
2
2
|
bundler_args: --without development
|
3
3
|
script: "bundle exec rake travis"
|
4
4
|
rvm:
|
5
|
-
-
|
6
|
-
- 1
|
7
|
-
- 2.
|
5
|
+
- 2.0
|
6
|
+
- 2.1
|
7
|
+
- 2.2
|
8
|
+
- 2.3
|
8
9
|
env:
|
9
10
|
global:
|
10
11
|
- secure: dAxfEdg/7Cb/G9vkrn/ifdvycbXWtK2ey60JMepOxx9v3QyaqoSY3w5G0QB+4+uyOYmHwtif8tnK3Sa8jbBgqhAlXaxqxOT8WmQKYlhSgwWX4lQe4lUM5jkOkfNHRMRaQvCAn27gNAjdIRU7sb2cU/pm64eAFbU01TejJOM7Aow=
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,10 @@
|
|
1
1
|
# Change Log (curated)
|
2
2
|
|
3
|
+
# The Future
|
4
|
+
|
5
|
+
* [https://github.com/fastestforward/heroku_san/releases](https://github.com/fastestforward/heroku_san/releases)
|
6
|
+
* GitHub releases pages will replace the ChangeLog
|
7
|
+
|
3
8
|
## v4.3.0
|
4
9
|
|
5
10
|
* Add #ensure_{all|one}_worker(s)_running -- which will restart your web workers until they stay up
|
data/Gemfile
CHANGED
@@ -5,25 +5,17 @@ gemspec
|
|
5
5
|
|
6
6
|
group :test do
|
7
7
|
gem 'aruba'
|
8
|
-
gem 'bundler'
|
8
|
+
gem 'bundler'
|
9
9
|
gem 'cucumber'
|
10
10
|
gem 'godot'
|
11
|
-
gem 'rails'
|
11
|
+
gem 'rails'
|
12
12
|
gem 'rake'
|
13
|
-
gem 'rspec'
|
13
|
+
gem 'rspec'
|
14
14
|
gem 'sqlite3'
|
15
15
|
gem 'pg'
|
16
16
|
end
|
17
17
|
|
18
18
|
group :development do
|
19
19
|
gem 'git-smart'
|
20
|
-
gem 'guard'
|
21
|
-
gem 'guard-bundler'
|
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
20
|
gem 'travis', '~> 1.5.6'
|
29
21
|
end
|
data/README.md
CHANGED
@@ -3,10 +3,11 @@ Helpful rake tasks for Heroku.
|
|
3
3
|
|
4
4
|
[![Build Status](https://secure.travis-ci.org/fastestforward/heroku_san.png)](http://travis-ci.org/fastestforward/heroku_san)
|
5
5
|
[![Code Climate](https://codeclimate.com/github/fastestforward/heroku_san.png)](https://codeclimate.com/github/fastestforward/heroku_san)
|
6
|
+
[![Gemnasium](https://gemnasium.com/fastestforward/heroku_san.png)](https://gemnasium.com/fastestforward/heroku_san)
|
6
7
|
|
7
8
|
## Install
|
8
9
|
|
9
|
-
### Rails 3
|
10
|
+
### Rails 3+
|
10
11
|
|
11
12
|
Add this to your `Gemfile`:
|
12
13
|
|
@@ -62,7 +63,7 @@ Update your `Rakefile`:
|
|
62
63
|
|
63
64
|
In `config/heroku.yml` you will need to add the Heroku apps that you would like to attach to this project. You can generate this file by running:
|
64
65
|
|
65
|
-
### Rails 3
|
66
|
+
### Rails 3+
|
66
67
|
|
67
68
|
```sh
|
68
69
|
rails generate heroku_san
|
@@ -1,13 +1,13 @@
|
|
1
1
|
@slow_process @announce-cmd
|
2
2
|
Feature: heroku_san can shell out to heroku without errors
|
3
3
|
|
4
|
-
Scenario: Bundling a ruby 2.
|
4
|
+
Scenario: Bundling a ruby 2.2.4 project
|
5
5
|
Given I run `mkdir -p ruby2test`
|
6
6
|
And I cd to "ruby2test"
|
7
7
|
And I write to "Gemfile" with:
|
8
8
|
"""
|
9
9
|
source "https://rubygems.org"
|
10
|
-
ruby '2.
|
10
|
+
ruby '2.2.4'
|
11
11
|
gem 'heroku_san', :path => '../../../.'
|
12
12
|
"""
|
13
13
|
|
@@ -31,9 +31,7 @@ Feature: heroku_san can shell out to heroku without errors
|
|
31
31
|
"""
|
32
32
|
#!/usr/bin/env bash
|
33
33
|
|
34
|
-
|
35
|
-
|
36
|
-
rvm use 2.0.0
|
34
|
+
rbenv local 2.2.4
|
37
35
|
bundle install
|
38
36
|
|
39
37
|
ruby get_heroku_version.rb
|
@@ -55,7 +55,7 @@ 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
57
|
ruby '#{ruby_version}'
|
58
|
-
gem 'rails', '
|
58
|
+
gem 'rails', '4.2.6'
|
59
59
|
gem 'pg'
|
60
60
|
group :development, :test do
|
61
61
|
gem 'heroku_san', :path => '../../../.'
|
@@ -177,12 +177,12 @@ end
|
|
177
177
|
|
178
178
|
When /^I deploy my project$/ do
|
179
179
|
run_clean 'rake test_app deploy'
|
180
|
-
assert_partial_output "
|
180
|
+
assert_partial_output "https://#{@app}.herokuapp.com/ deployed to Heroku", all_output
|
181
181
|
end
|
182
182
|
|
183
183
|
When /^I deploy to tag "([^"]*)"$/ do |tag|
|
184
184
|
run_clean "rake test_app deploy[#{tag}]"
|
185
|
-
assert_partial_output "
|
185
|
+
assert_partial_output "https://#{@app}.herokuapp.com/ deployed to Heroku", all_output
|
186
186
|
end
|
187
187
|
|
188
188
|
When /^I list all apps on Heroku$/ do
|
@@ -196,18 +196,17 @@ When /^I list all apps on Heroku$/ do
|
|
196
196
|
end
|
197
197
|
|
198
198
|
When /^I install an addon$/ do
|
199
|
-
# Install the campfire addon.
|
200
199
|
overwrite_file 'config/heroku.yml', <<END_CONFIG.strip_heredoc
|
201
200
|
test_app:
|
202
201
|
app: #{@app}
|
203
202
|
addons:
|
204
|
-
- heroku-postgresql:dev
|
203
|
+
- heroku-postgresql:hobby-dev
|
205
204
|
|
206
205
|
END_CONFIG
|
207
206
|
|
208
207
|
output = run_clean 'rake test_app heroku:addons'
|
209
208
|
# The output should show the new one ...
|
210
|
-
assert_partial_output "heroku-postgresql:dev", output
|
209
|
+
assert_partial_output "heroku-postgresql:hobby-dev", output
|
211
210
|
end
|
212
211
|
|
213
212
|
Then /^(?:heroku_san|issue \d+) (?:is green|has been fixed)$/ do
|
@@ -236,5 +235,5 @@ EOT
|
|
236
235
|
end
|
237
236
|
|
238
237
|
def ruby_version
|
239
|
-
ENV['TRAVIS_RUBY_VERSION'] || '
|
238
|
+
ENV['TRAVIS_RUBY_VERSION'] || '2.2.4'
|
240
239
|
end
|
data/lib/heroku_san/api.rb
CHANGED
data/lib/heroku_san/version.rb
CHANGED
data/spec/heroku_san/api_spec.rb
CHANGED
@@ -5,22 +5,22 @@ module HerokuSan
|
|
5
5
|
describe HerokuSan::API do
|
6
6
|
subject(:api) { HerokuSan::API.new(:api_key => 'key', :double => true)}
|
7
7
|
it "is a proxy to the Heroku::API" do
|
8
|
-
Heroku::API.
|
9
|
-
api.api_method(1, 2, {:arg => 3}).
|
8
|
+
expect_any_instance_of(Heroku::API).to receive(:api_method).with(1, 2, {:arg => 3}) {true}
|
9
|
+
expect(api.api_method(1, 2, {:arg => 3})).to be_truthy
|
10
10
|
end
|
11
11
|
|
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
15
|
response = double("Response", :body => %Q[{"error":"#{error_message}"}], :headers => {'Status' => status_message})
|
16
|
-
Heroku::API.
|
16
|
+
expect_any_instance_of(Heroku::API).to receive(:api_method).and_raise(Heroku::API::Errors::ErrorWithResponse.new("excon message", response))
|
17
17
|
|
18
|
-
$stderr.
|
18
|
+
expect($stderr).to receive(:puts).with("\nHeroku API ERROR: #{status_message} (#{error_message})\n\n")
|
19
19
|
|
20
20
|
expect {
|
21
21
|
api.api_method
|
22
22
|
}.to raise_error(Heroku::API::Errors::ErrorWithResponse, "excon message") {|error|
|
23
|
-
error.backtrace.
|
23
|
+
expect(error.backtrace).to eq []
|
24
24
|
}
|
25
25
|
end
|
26
26
|
end
|
@@ -6,7 +6,7 @@ module HerokuSan
|
|
6
6
|
let(:response) { double }
|
7
7
|
|
8
8
|
before do
|
9
|
-
stage.heroku.
|
9
|
+
allow(stage.heroku).to receive(:get_ps).with(stage.app) { response }
|
10
10
|
end
|
11
11
|
|
12
12
|
describe "#ensure_one_worker_running" do
|
@@ -29,8 +29,8 @@ module HerokuSan
|
|
29
29
|
it "should block until at least one worker is running, and restart any crashed workers it sees" do
|
30
30
|
|
31
31
|
with_app(stage, 'name' => stage.app) do |app_data|
|
32
|
-
response.
|
33
|
-
stage.heroku.
|
32
|
+
expect(response).to receive(:body).twice.and_return(none_running, one_running_with_crash)
|
33
|
+
expect(stage.heroku).to receive(:post_ps_restart).with(stage.app, ps: 'web.1')
|
34
34
|
|
35
35
|
stage.ensure_one_worker_running
|
36
36
|
end
|
@@ -69,9 +69,9 @@ module HerokuSan
|
|
69
69
|
|
70
70
|
it "should block until all workers are running, and restart any crashed workers it sees" do
|
71
71
|
with_app(stage, 'name' => stage.app) do |app_data|
|
72
|
-
response.
|
73
|
-
stage.heroku.
|
74
|
-
stage.heroku.
|
72
|
+
expect(response).to receive(:body).exactly(4).times.and_return(some_crashes, some_restarting, one_crash, all_up)
|
73
|
+
expect(stage.heroku).to receive(:post_ps_restart).with(stage.app, ps: 'worker.1').twice
|
74
|
+
expect(stage.heroku).to receive(:post_ps_restart).with(stage.app, ps: 'web.1').once
|
75
75
|
|
76
76
|
stage.ensure_all_workers_running
|
77
77
|
end
|
@@ -8,17 +8,17 @@ describe HerokuSan::Configuration do
|
|
8
8
|
describe "#stages" do
|
9
9
|
it "creates a configuration hash" do
|
10
10
|
configuration.configuration = {'production' => {}}
|
11
|
-
configuration.stages.
|
11
|
+
expect(configuration.stages).to eq(
|
12
12
|
'production' => Factory::Stage.build('production', 'deploy' => HerokuSan::Deploy::Rails)
|
13
|
-
|
13
|
+
)
|
14
14
|
end
|
15
15
|
|
16
16
|
it "configures the deploy strategy" do
|
17
17
|
configurable.options = {'deploy' => HerokuSan::Deploy::Base}
|
18
18
|
configuration.configuration = {'production' => {}}
|
19
|
-
configuration.stages.
|
19
|
+
expect(configuration.stages).to eq(
|
20
20
|
'production' => Factory::Stage.build('production', 'deploy' => HerokuSan::Deploy::Base)
|
21
|
-
|
21
|
+
)
|
22
22
|
end
|
23
23
|
end
|
24
24
|
|
@@ -27,15 +27,15 @@ describe HerokuSan::Configuration do
|
|
27
27
|
it "creates a new file using the example file" do
|
28
28
|
Dir.mktmpdir do |dir|
|
29
29
|
configurable.config_file = tmp_config_file = File.join(dir, 'config.yml')
|
30
|
-
FileUtils.
|
31
|
-
configuration.generate_config.
|
30
|
+
expect(FileUtils).to receive(:cp).with(configuration.template, tmp_config_file)
|
31
|
+
expect(configuration.generate_config).to be_truthy
|
32
32
|
end
|
33
33
|
end
|
34
34
|
|
35
35
|
it "does not overwrite an existing file" do
|
36
|
-
FileUtils.
|
36
|
+
expect(FileUtils).not_to receive(:cp)
|
37
37
|
configurable.config_file = fixture("example.yml")
|
38
|
-
configuration.generate_config.
|
38
|
+
expect(configuration.generate_config).to be_falsey
|
39
39
|
end
|
40
40
|
end
|
41
41
|
end
|
@@ -7,25 +7,25 @@ module HerokuSan
|
|
7
7
|
|
8
8
|
it "calls push" do
|
9
9
|
subject = described_class.new(stage)
|
10
|
-
stage.
|
10
|
+
expect(stage).to receive(:push).with(nil, nil)
|
11
11
|
subject.deploy
|
12
12
|
end
|
13
13
|
|
14
14
|
it "calls push(sha)" do
|
15
15
|
subject = described_class.new(stage, 'sha')
|
16
|
-
stage.
|
16
|
+
expect(stage).to receive(:push).with('sha', nil)
|
17
17
|
subject.deploy
|
18
18
|
end
|
19
19
|
|
20
20
|
it "calls push(nil, :force)" do
|
21
21
|
subject = described_class.new(stage, nil, :force)
|
22
|
-
stage.
|
22
|
+
expect(stage).to receive(:push).with(nil, :force)
|
23
23
|
subject.deploy
|
24
24
|
end
|
25
25
|
|
26
26
|
it "calls push(sha, :force)" do
|
27
27
|
subject = described_class.new(stage, 'sha', :force)
|
28
|
-
stage.
|
28
|
+
expect(stage).to receive(:push).with('sha', :force)
|
29
29
|
subject.deploy
|
30
30
|
end
|
31
31
|
end
|
@@ -7,9 +7,9 @@ module HerokuSan
|
|
7
7
|
|
8
8
|
it "calls push, rake db:migrate & restart" do
|
9
9
|
subject = described_class.new(stage, {})
|
10
|
-
stage.
|
11
|
-
stage.
|
12
|
-
stage.
|
10
|
+
expect(stage).to receive(:push) { "pushed" } # "mock" super
|
11
|
+
expect(stage).to receive(:run).with('rake db:migrate') { "migrated" }
|
12
|
+
expect(stage).to receive(:restart) { "restarted" }
|
13
13
|
subject.deploy
|
14
14
|
end
|
15
15
|
end
|
data/spec/heroku_san/git_spec.rb
CHANGED
@@ -6,81 +6,81 @@ class GitTest; include HerokuSan::Git; end
|
|
6
6
|
describe GitTest do
|
7
7
|
describe "#git_push" do
|
8
8
|
it "pushes to heroku" do
|
9
|
-
subject.
|
10
|
-
subject.
|
11
|
-
subject.
|
9
|
+
expect(subject).to receive(:sh).with("git update-ref refs/heroku_san/deploy HEAD^{commit}")
|
10
|
+
expect(subject).to receive(:sh).with("git push git@heroku.com:awesomeapp.git refs/heroku_san/deploy:refs/heads/master")
|
11
|
+
expect(subject).to receive(:sh).with("git update-ref -d refs/heroku_san/deploy")
|
12
12
|
subject.git_push(nil, 'git@heroku.com:awesomeapp.git')
|
13
13
|
end
|
14
14
|
|
15
15
|
it "pushes a specific commit to heroku" do
|
16
|
-
subject.
|
17
|
-
subject.
|
18
|
-
subject.
|
16
|
+
expect(subject).to receive(:sh).with("git update-ref refs/heroku_san/deploy kommit^{commit}")
|
17
|
+
expect(subject).to receive(:sh).with("git push git@heroku.com:awesomeapp.git refs/heroku_san/deploy:refs/heads/master")
|
18
|
+
expect(subject).to receive(:sh).with("git update-ref -d refs/heroku_san/deploy")
|
19
19
|
subject.git_push('kommit', 'git@heroku.com:awesomeapp.git')
|
20
20
|
end
|
21
21
|
|
22
22
|
it "includes options, too" do
|
23
|
-
subject.
|
24
|
-
subject.
|
25
|
-
subject.
|
23
|
+
expect(subject).to receive(:sh).with("git update-ref refs/heroku_san/deploy HEAD^{commit}")
|
24
|
+
expect(subject).to receive(:sh).with("git push git@heroku.com:awesomeapp.git --force -v refs/heroku_san/deploy:refs/heads/master")
|
25
|
+
expect(subject).to receive(:sh).with("git update-ref -d refs/heroku_san/deploy")
|
26
26
|
subject.git_push(nil, 'git@heroku.com:awesomeapp.git', %w[--force -v])
|
27
27
|
end
|
28
28
|
|
29
29
|
it "propagates any errors, but still cleans up" do
|
30
|
-
subject.
|
31
|
-
subject.
|
32
|
-
subject.
|
33
|
-
expect { subject.git_push(nil, 'git@heroku.com:awesomeapp.git') }.to raise_error
|
30
|
+
expect(subject).to receive(:sh).with("git update-ref refs/heroku_san/deploy HEAD^{commit}")
|
31
|
+
expect(subject).to receive(:sh).with("git push git@heroku.com:awesomeapp.git refs/heroku_san/deploy:refs/heads/master").and_raise
|
32
|
+
expect(subject).to receive(:sh).with("git update-ref -d refs/heroku_san/deploy")
|
33
|
+
expect { subject.git_push(nil, 'git@heroku.com:awesomeapp.git') }.to raise_error StandardError
|
34
34
|
end
|
35
35
|
end
|
36
36
|
|
37
37
|
describe "#git_tag" do
|
38
38
|
it "returns the latest tag that matches the pattern" do
|
39
|
-
subject.
|
40
|
-
subject.git_tag('pattern*').
|
39
|
+
expect(subject).to receive("`").with("git tag -l 'pattern*'") { "x\n\y\n\z\n" }
|
40
|
+
expect(subject.git_tag('pattern*')).to eq "z"
|
41
41
|
end
|
42
42
|
|
43
43
|
it "raises exception if no tags match the pattern" do
|
44
|
-
subject.
|
44
|
+
expect(subject).to receive("`").with("git tag -l 'pattern*'") { "\n" }
|
45
45
|
expect {
|
46
46
|
subject.git_tag('pattern*')
|
47
47
|
}.to raise_error(HerokuSan::Git::NoTagFoundError)
|
48
48
|
end
|
49
49
|
|
50
50
|
it "returns nil for a nil glob" do
|
51
|
-
subject.
|
52
|
-
subject.git_tag(nil).
|
51
|
+
expect(subject).not_to receive("`").with("git tag -l ''") { "\n" }
|
52
|
+
expect(subject.git_tag(nil)).to be_nil
|
53
53
|
end
|
54
54
|
end
|
55
55
|
|
56
56
|
describe "#git_rev_parse" do
|
57
57
|
it "returns the rev based on the tag" do
|
58
|
-
subject.
|
59
|
-
subject.git_rev_parse('prod/1234567890').
|
58
|
+
expect(subject).to receive("`").with("git rev-parse prod/1234567890") { "sha\n" }
|
59
|
+
expect(subject.git_rev_parse('prod/1234567890')).to eq "sha"
|
60
60
|
end
|
61
61
|
|
62
62
|
it "returns nil for a blank tag" do
|
63
|
-
subject.
|
64
|
-
subject.git_rev_parse(nil).
|
63
|
+
expect(subject).not_to receive("`").with("git rev-parse ") { "\n" }
|
64
|
+
expect(subject.git_rev_parse(nil)).to be_nil
|
65
65
|
end
|
66
66
|
end
|
67
67
|
|
68
68
|
describe "#git_revision" do
|
69
69
|
it "returns the current revision of the repository (on Heroku)" do
|
70
|
-
subject.
|
71
|
-
subject.git_revision('staging').
|
70
|
+
expect(subject).to receive("`").with("git ls-remote --heads staging master") { "sha\n" }
|
71
|
+
expect(subject.git_revision('staging')).to eq 'sha'
|
72
72
|
end
|
73
73
|
|
74
74
|
it "returns nil if there is no revision (i.e. not deployed yet)" do
|
75
|
-
subject.
|
76
|
-
subject.git_revision('staging').
|
75
|
+
expect(subject).to receive("`").with("git ls-remote --heads staging master") { "\n" }
|
76
|
+
expect(subject.git_revision('staging')).to be_nil
|
77
77
|
end
|
78
78
|
end
|
79
79
|
|
80
80
|
describe "#git_named_rev" do
|
81
81
|
it "returns symbolic names for given rev" do
|
82
|
-
subject.
|
83
|
-
subject.git_named_rev('sha').
|
82
|
+
expect(subject).to receive("`").with("git name-rev sha") {"sha production/123456\n"}
|
83
|
+
expect(subject.git_named_rev('sha')).to eq 'sha production/123456'
|
84
84
|
end
|
85
85
|
end
|
86
86
|
end
|
@@ -11,10 +11,10 @@ describe HerokuSan::Parser do
|
|
11
11
|
it "returns a list of apps" do
|
12
12
|
parser.parse(parseable)
|
13
13
|
|
14
|
-
parseable.configuration.keys.
|
15
|
-
parseable.configuration['production'].
|
16
|
-
parseable.configuration['staging'].
|
17
|
-
parseable.configuration['demo'].
|
14
|
+
expect(parseable.configuration.keys).to match %w[production staging demo]
|
15
|
+
expect(parseable.configuration['production']).to eq({'app' => 'awesomeapp', 'tag' => 'production/*', 'config' => {'BUNDLE_WITHOUT' => 'development:test', 'GOOGLE_ANALYTICS' => 'UA-12345678-1'}})
|
16
|
+
expect(parseable.configuration['staging']).to eq({'app' => 'awesomeapp-staging', 'stack' => 'bamboo-ree-1.8.7', 'config' => {'BUNDLE_WITHOUT' => 'development:test'}})
|
17
|
+
expect(parseable.configuration['demo']).to eq({'app' => 'awesomeapp-demo', 'stack' => 'cedar', 'config' => {'BUNDLE_WITHOUT' => 'development:test'}})
|
18
18
|
end
|
19
19
|
end
|
20
20
|
|
@@ -24,12 +24,12 @@ describe HerokuSan::Parser do
|
|
24
24
|
it "returns a list of apps" do
|
25
25
|
parser.parse(parseable)
|
26
26
|
|
27
|
-
parseable.configuration.keys.
|
28
|
-
parseable.configuration.
|
27
|
+
expect(parseable.configuration.keys).to match %w[production staging demo]
|
28
|
+
expect(parseable.configuration).to eq({
|
29
29
|
'production' => {'app' => 'awesomeapp', 'config' => {}},
|
30
30
|
'staging' => {'app' => 'awesomeapp-staging', 'config' => {}},
|
31
31
|
'demo' => {'app' => 'awesomeapp-demo', 'config' => {}}
|
32
|
-
}
|
32
|
+
})
|
33
33
|
end
|
34
34
|
end
|
35
35
|
end
|
@@ -63,7 +63,7 @@ describe HerokuSan::Parser do
|
|
63
63
|
let(:parseable) { double :external_configuration => nil }
|
64
64
|
|
65
65
|
it "doesn't change prod_config" do
|
66
|
-
prod_config.
|
66
|
+
expect(prod_config).not_to receive :merge!
|
67
67
|
parser.merge_external_config! parseable, stages
|
68
68
|
end
|
69
69
|
end
|
@@ -71,18 +71,18 @@ describe HerokuSan::Parser do
|
|
71
71
|
context "with extra" do
|
72
72
|
let(:parseable) { double :external_configuration => 'config_repos' }
|
73
73
|
before(:each) do
|
74
|
-
parser.
|
75
|
-
parser.
|
74
|
+
expect(parser).to receive(:git_clone).with('config_repos', anything)
|
75
|
+
expect(parser).to receive(:parse_yaml).and_return(extras)
|
76
76
|
end
|
77
77
|
|
78
78
|
it "merges extra configuration bits" do
|
79
|
-
prod_config.
|
79
|
+
expect(prod_config).to receive(:merge!).with extras['production']
|
80
80
|
parser.merge_external_config! parseable, [stages.first]
|
81
81
|
end
|
82
82
|
|
83
83
|
it "overrides the main configuration" do
|
84
84
|
parser.merge_external_config! parseable, [stages.last]
|
85
|
-
staging_config.
|
85
|
+
expect(staging_config).to eq("EXTRA" => "foo")
|
86
86
|
end
|
87
87
|
end
|
88
88
|
end
|
@@ -14,32 +14,32 @@ describe HerokuSan::Project do
|
|
14
14
|
|
15
15
|
describe "#apps constructs the deploy list" do
|
16
16
|
it "appends known shorthands to apps" do
|
17
|
-
heroku_san.apps.
|
17
|
+
expect(heroku_san.apps).to eq []
|
18
18
|
heroku_san << 'production'
|
19
|
-
heroku_san.apps.
|
19
|
+
expect(heroku_san.apps).to eq %w[production]
|
20
20
|
heroku_san << 'staging'
|
21
|
-
heroku_san.apps.
|
21
|
+
expect(heroku_san.apps).to eq %w[production staging]
|
22
22
|
heroku_san << 'unknown'
|
23
|
-
heroku_san.apps.
|
23
|
+
expect(heroku_san.apps).to eq %w[production staging]
|
24
24
|
end
|
25
25
|
|
26
26
|
it "appends .all (or any array)" do
|
27
27
|
heroku_san << heroku_san.all
|
28
|
-
heroku_san.apps.
|
28
|
+
expect(heroku_san.apps).to eq heroku_san.all
|
29
29
|
end
|
30
30
|
|
31
31
|
describe "extra (default) behaviors" do
|
32
32
|
specify "on a git branch that matches an app name" do
|
33
|
-
heroku_san.
|
34
|
-
$stdout.
|
33
|
+
expect(heroku_san).to receive(:git_active_branch) { "staging" }
|
34
|
+
expect($stdout).to receive(:puts).with("Defaulting to 'staging' as it matches the current branch")
|
35
35
|
expect {
|
36
|
-
heroku_san.apps.
|
36
|
+
expect(heroku_san.apps).to eq %w[staging]
|
37
37
|
}.to change{heroku_san.instance_variable_get('@apps')}.from([]).to(%w[staging])
|
38
38
|
end
|
39
|
-
|
39
|
+
|
40
40
|
specify "on a git branch that doesn't matches an app name" do
|
41
|
-
heroku_san.
|
42
|
-
heroku_san.apps.
|
41
|
+
expect(heroku_san).to receive(:git_active_branch) { "master" }
|
42
|
+
expect(heroku_san.apps).to eq %w[]
|
43
43
|
end
|
44
44
|
|
45
45
|
context "with only a single configured app" do
|
@@ -51,9 +51,9 @@ describe HerokuSan::Project do
|
|
51
51
|
end
|
52
52
|
|
53
53
|
it "returns the app" do
|
54
|
-
$stdout.
|
54
|
+
expect($stdout).to receive(:puts).with('Defaulting to "production" since only one app is defined')
|
55
55
|
expect {
|
56
|
-
heroku_san.apps.
|
56
|
+
expect(heroku_san.apps).to eq %w[production]
|
57
57
|
}.to change{heroku_san.instance_variable_get('@apps')}.from([]).to(%w[production])
|
58
58
|
end
|
59
59
|
end
|
@@ -68,7 +68,7 @@ describe HerokuSan::Project do
|
|
68
68
|
it "yields to a block with args" do
|
69
69
|
heroku_san << 'production'
|
70
70
|
block = double('block')
|
71
|
-
block.
|
71
|
+
expect(block).to receive(:action).with(heroku_san['production'])
|
72
72
|
heroku_san.each_app do |stage|
|
73
73
|
block.action(stage)
|
74
74
|
end
|
@@ -78,7 +78,7 @@ describe HerokuSan::Project do
|
|
78
78
|
describe "#[]" do
|
79
79
|
it "returns a config section" do
|
80
80
|
heroku_san.all.each do |app|
|
81
|
-
heroku_san[app].
|
81
|
+
expect(heroku_san[app]).to be_a HerokuSan::Stage
|
82
82
|
end
|
83
83
|
end
|
84
84
|
end
|
@@ -7,7 +7,7 @@ describe HerokuSan::Stage do
|
|
7
7
|
include HerokuSan::Git
|
8
8
|
subject { Factory::Stage.build('production', {"deploy" => HerokuSan::Deploy::Rails, "app" => "awesomeapp", "stack" => "cedar"})}
|
9
9
|
before do
|
10
|
-
HerokuSan::API.
|
10
|
+
allow_any_instance_of(HerokuSan::API).to receive(:preflight_check_for_cli)
|
11
11
|
end
|
12
12
|
|
13
13
|
context "initializes" do
|
@@ -19,17 +19,17 @@ describe HerokuSan::Stage do
|
|
19
19
|
"addons"=> ['one:addon', 'two:addons']
|
20
20
|
})}
|
21
21
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
22
|
+
it { expect(subject.name).to eq 'production' }
|
23
|
+
it { expect(subject.app).to eq 'awesomeapp-demo' }
|
24
|
+
it { expect(subject.stack).to eq 'cedar' }
|
25
|
+
it { expect(subject.tag).to eq "demo/*" }
|
26
|
+
it { expect(subject.config).to eq("BUNDLE_WITHOUT"=>"development:test") }
|
27
|
+
it { expect(subject.repo).to eq 'git@heroku.com:awesomeapp-demo.git' }
|
28
|
+
it { expect(subject.addons).to eq ['one:addon', 'two:addons'] }
|
29
29
|
end
|
30
30
|
|
31
31
|
describe "#app" do
|
32
|
-
|
32
|
+
it { expect(subject.app).to eq 'awesomeapp'}
|
33
33
|
context "blank app" do
|
34
34
|
subject { Factory::Stage.build('production') }
|
35
35
|
it "should raise an error" do
|
@@ -42,13 +42,13 @@ describe HerokuSan::Stage do
|
|
42
42
|
it "returns the name of the stack from Heroku" do
|
43
43
|
subject = Factory::Stage.build('production', {"app" => "awesomeapp"})
|
44
44
|
with_app(subject, 'name' => subject.app) do |app_data|
|
45
|
-
subject.stack.
|
45
|
+
expect(subject.stack).to eq 'bamboo-mri-1.9.2'
|
46
46
|
end
|
47
47
|
end
|
48
48
|
|
49
49
|
it "returns the stack name from the config when it is set there" do
|
50
50
|
subject = Factory::Stage.build('production', {"app" => "awesomeapp", "stack" => "cedar"})
|
51
|
-
subject.stack.
|
51
|
+
expect(subject.stack).to eq 'cedar'
|
52
52
|
end
|
53
53
|
end
|
54
54
|
|
@@ -56,7 +56,7 @@ describe HerokuSan::Stage do
|
|
56
56
|
subject { Factory::Stage.build('production', {'addons' => addons}) }
|
57
57
|
context 'default' do
|
58
58
|
let(:addons) { nil }
|
59
|
-
|
59
|
+
it { expect(subject.addons).to eq [] }
|
60
60
|
end
|
61
61
|
context 'nested' do
|
62
62
|
# This is for when you do:
|
@@ -68,37 +68,37 @@ describe HerokuSan::Stage do
|
|
68
68
|
# - *default_addons
|
69
69
|
# - other
|
70
70
|
let(:addons) { [ ['a', 'b'], 'other' ] }
|
71
|
-
|
71
|
+
it { expect(subject.addons).to eq [ 'a', 'b', 'other' ] }
|
72
72
|
end
|
73
73
|
end
|
74
74
|
|
75
75
|
describe "#run" do
|
76
76
|
it "runs commands using the new cedar format" do
|
77
|
-
subject.heroku.
|
77
|
+
expect(subject.heroku).to receive(:system).with("heroku", "run", "worker foo bar bleh", "--app", "awesomeapp", "--exit-code") { true }
|
78
78
|
subject.run 'worker foo bar bleh'
|
79
79
|
end
|
80
80
|
end
|
81
81
|
|
82
82
|
describe "#push" do
|
83
83
|
it "deploys to heroku" do
|
84
|
-
subject.
|
85
|
-
subject.
|
84
|
+
expect(subject).to receive(:git_parsed_tag).with(nil) {'tag'}
|
85
|
+
expect(subject).to receive(:git_push).with('tag', subject.repo, [])
|
86
86
|
subject.push
|
87
87
|
end
|
88
88
|
|
89
89
|
it "deploys with a custom sha" do
|
90
|
-
subject.
|
90
|
+
expect(subject).to receive(:git_push).with('deadbeef', subject.repo, [])
|
91
91
|
subject.push('deadbeef')
|
92
92
|
end
|
93
93
|
|
94
94
|
it "deploys with --force" do
|
95
|
-
subject.
|
96
|
-
subject.
|
95
|
+
expect(subject).to receive(:git_parsed_tag).with(nil) {'tag'}
|
96
|
+
expect(subject).to receive(:git_push).with('tag', subject.repo, %w[--force])
|
97
97
|
subject.push(nil, :force)
|
98
98
|
end
|
99
99
|
|
100
100
|
it "deploys with a custom sha & --force" do
|
101
|
-
subject.
|
101
|
+
expect(subject).to receive(:git_push).with('deadbeef', subject.repo, %w[--force])
|
102
102
|
subject.push('deadbeef', :force)
|
103
103
|
end
|
104
104
|
end
|
@@ -106,8 +106,8 @@ describe HerokuSan::Stage do
|
|
106
106
|
describe "#migrate" do
|
107
107
|
it "runs rake db:migrate" do
|
108
108
|
with_app(subject, 'name' => subject.app) do |app_data|
|
109
|
-
subject.
|
110
|
-
subject.migrate.
|
109
|
+
expect(subject).to receive(:run).with('rake db:migrate').and_return 'output:'
|
110
|
+
expect(subject.migrate).to eq "restarted"
|
111
111
|
end
|
112
112
|
end
|
113
113
|
end
|
@@ -115,7 +115,7 @@ describe HerokuSan::Stage do
|
|
115
115
|
describe "#deploy" do
|
116
116
|
context "using the default strategy" do
|
117
117
|
it "(rails) pushes & migrates" do
|
118
|
-
HerokuSan::Deploy::Rails.
|
118
|
+
allow_any_instance_of(HerokuSan::Deploy::Rails).to receive(:deploy)
|
119
119
|
subject.deploy
|
120
120
|
end
|
121
121
|
end
|
@@ -126,7 +126,7 @@ describe HerokuSan::Stage do
|
|
126
126
|
end
|
127
127
|
subject = Factory::Stage.build('test', {"app" => "awesomeapp", "deploy" => TestDeployStrategy})
|
128
128
|
it "(custom) calls deploy" do
|
129
|
-
TestDeployStrategy.
|
129
|
+
expect_any_instance_of(TestDeployStrategy).to receive(:deploy)
|
130
130
|
subject.deploy
|
131
131
|
end
|
132
132
|
end
|
@@ -135,13 +135,13 @@ describe HerokuSan::Stage do
|
|
135
135
|
describe "#maintenance" do
|
136
136
|
it ":on" do
|
137
137
|
with_app(subject, 'name' => subject.app )do |app_data|
|
138
|
-
subject.maintenance(:on).status.
|
138
|
+
expect(subject.maintenance(:on).status).to eq 200
|
139
139
|
end
|
140
140
|
end
|
141
141
|
|
142
142
|
it ":off" do
|
143
143
|
with_app(subject, 'name' => subject.app) do |app_data|
|
144
|
-
subject.maintenance(:off).status.
|
144
|
+
expect(subject.maintenance(:off).status).to eq 200
|
145
145
|
end
|
146
146
|
end
|
147
147
|
|
@@ -154,9 +154,9 @@ describe HerokuSan::Stage do
|
|
154
154
|
context "with a block" do
|
155
155
|
it "wraps it in a maintenance mode" do
|
156
156
|
with_app(subject, 'name' => subject.app) do |app_data|
|
157
|
-
subject.heroku.
|
158
|
-
reactor = double("Reactor"); reactor.
|
159
|
-
subject.heroku.
|
157
|
+
expect(subject.heroku).to receive(:post_app_maintenance).with(subject.app, '1').ordered
|
158
|
+
reactor = double("Reactor"); expect(reactor).to receive(:scram).with(:now).ordered
|
159
|
+
expect(subject.heroku).to receive(:post_app_maintenance).with(subject.app, '0').ordered
|
160
160
|
|
161
161
|
subject.maintenance {reactor.scram(:now)}
|
162
162
|
end
|
@@ -164,11 +164,11 @@ describe HerokuSan::Stage do
|
|
164
164
|
|
165
165
|
it "ensures that maintenance mode is turned off" do
|
166
166
|
with_app(subject, 'name' => subject.app) do |app_data|
|
167
|
-
subject.heroku.
|
168
|
-
reactor = double("Reactor"); reactor.
|
169
|
-
subject.heroku.
|
167
|
+
expect(subject.heroku).to receive(:post_app_maintenance).with(subject.app, '1').ordered
|
168
|
+
reactor = double("Reactor"); expect(reactor).to receive(:scram).and_raise(RuntimeError)
|
169
|
+
expect(subject.heroku).to receive(:post_app_maintenance).with(subject.app, '0').ordered
|
170
170
|
|
171
|
-
expect do subject.maintenance {reactor.scram(:now)} end.to raise_error
|
171
|
+
expect do subject.maintenance {reactor.scram(:now)} end.to raise_error StandardError
|
172
172
|
end
|
173
173
|
end
|
174
174
|
end
|
@@ -180,30 +180,30 @@ describe HerokuSan::Stage do
|
|
180
180
|
end
|
181
181
|
|
182
182
|
it "uses the provided name" do
|
183
|
-
(@app = subject.create).
|
183
|
+
expect((@app = subject.create)).to eq 'awesomeapp'
|
184
184
|
end
|
185
185
|
|
186
186
|
it "creates an app on heroku" do
|
187
187
|
subject = Factory::Stage.build('production')
|
188
|
-
(@app = subject.create).
|
188
|
+
expect(@app = subject.create).to match /generated-name-\d+/
|
189
189
|
end
|
190
190
|
|
191
191
|
it "uses the default stack if none is given" do
|
192
192
|
subject = Factory::Stage.build('production')
|
193
|
-
(@app = subject.create).
|
194
|
-
subject.heroku.get_stack(@app).body.detect{|stack| stack['current']}['name'].
|
193
|
+
expect(@app = subject.create).to match /generated-name-\d+/
|
194
|
+
expect(subject.heroku.get_stack(@app).body.detect{|stack| stack['current']}['name']).to eq 'bamboo-mri-1.9.2'
|
195
195
|
end
|
196
196
|
|
197
197
|
it "uses the stack from the config" do
|
198
|
-
(@app = subject.create).
|
199
|
-
subject.heroku.get_stack(@app).body.detect{|stack| stack['current']}['name'].
|
198
|
+
expect(@app = subject.create).to eq 'awesomeapp'
|
199
|
+
expect(subject.heroku.get_stack(@app).body.detect{|stack| stack['current']}['name']).to eq 'cedar'
|
200
200
|
end
|
201
201
|
end
|
202
202
|
|
203
203
|
describe "#long_config" do
|
204
204
|
it "returns the remote config" do
|
205
205
|
with_app(subject, 'name' => subject.app) do |app_data|
|
206
|
-
subject.long_config.
|
206
|
+
expect(subject.long_config).to eq STOCK_CONFIG
|
207
207
|
end
|
208
208
|
end
|
209
209
|
end
|
@@ -212,14 +212,14 @@ describe HerokuSan::Stage do
|
|
212
212
|
it "updates the configuration settings on Heroku" do
|
213
213
|
subject = Factory::Stage.build('test', {"app" => "awesomeapp", "config" => {'FOO' => 'bar', 'DOG' => 'emu'}})
|
214
214
|
with_app(subject, 'name' => subject.app) do |app_data|
|
215
|
-
subject.push_config.
|
215
|
+
expect(subject.push_config).to eq STOCK_CONFIG.merge('FOO' => 'bar', 'DOG' => 'emu')
|
216
216
|
end
|
217
217
|
end
|
218
218
|
|
219
219
|
it "pushes the options hash" do
|
220
220
|
subject = Factory::Stage.build('test', {"app" => "awesomeapp", "config" => {'FOO' => 'bar', 'DOG' => 'emu'}})
|
221
221
|
with_app(subject, 'name' => subject.app) do |app_data|
|
222
|
-
subject.push_config('RACK_ENV' => 'magic').
|
222
|
+
expect(subject.push_config('RACK_ENV' => 'magic')).to eq STOCK_CONFIG.merge('RACK_ENV' => 'magic')
|
223
223
|
end
|
224
224
|
end
|
225
225
|
end
|
@@ -227,41 +227,41 @@ describe HerokuSan::Stage do
|
|
227
227
|
describe "#restart" do
|
228
228
|
it "restarts an app" do
|
229
229
|
with_app(subject, 'name' => subject.app) do |app_data|
|
230
|
-
subject.restart.
|
230
|
+
expect(subject.restart).to eq 'restarted'
|
231
231
|
end
|
232
232
|
end
|
233
233
|
end
|
234
234
|
|
235
235
|
describe "#logs" do
|
236
236
|
it "returns log files" do
|
237
|
-
subject.heroku.
|
237
|
+
expect(subject.heroku).to receive(:system).with("heroku", "logs", "--app", "awesomeapp", "--exit-code") { true }
|
238
238
|
subject.logs
|
239
239
|
end
|
240
240
|
|
241
241
|
it "tails log files" do
|
242
|
-
subject.heroku.
|
242
|
+
expect(subject.heroku).to receive(:system).with("heroku", "logs", "--tail", "--app", "awesomeapp", "--exit-code") { true }
|
243
243
|
subject.logs(:tail)
|
244
244
|
end
|
245
245
|
end
|
246
246
|
|
247
247
|
describe "#revision" do
|
248
248
|
it "returns the named remote revision for the stage" do
|
249
|
-
subject.
|
250
|
-
subject.
|
251
|
-
subject.revision.
|
249
|
+
expect(subject).to receive(:git_revision).with(subject.repo) {"sha"}
|
250
|
+
expect(subject).to receive(:git_named_rev).with('sha') {"sha production/123456"}
|
251
|
+
expect(subject.revision).to eq 'sha production/123456'
|
252
252
|
end
|
253
253
|
|
254
254
|
it "returns nil if the stage has never been deployed" do
|
255
|
-
subject.
|
256
|
-
subject.
|
257
|
-
subject.revision.
|
255
|
+
expect(subject).to receive(:git_revision).with(subject.repo) {nil}
|
256
|
+
expect(subject).to receive(:git_named_rev).with(nil) {''}
|
257
|
+
expect(subject.revision).to eq ''
|
258
258
|
end
|
259
259
|
end
|
260
260
|
|
261
261
|
describe "#installed_addons" do
|
262
262
|
it "returns the list of installed addons" do
|
263
263
|
with_app(subject, 'name' => subject.app) do |app_data|
|
264
|
-
subject.installed_addons.map{|a|a['name']}.
|
264
|
+
expect(subject.installed_addons.map{|a|a['name']}).to include *%w[shared-database:5mb]
|
265
265
|
end
|
266
266
|
end
|
267
267
|
end
|
@@ -271,15 +271,15 @@ describe HerokuSan::Stage do
|
|
271
271
|
|
272
272
|
it "installs the addons" do
|
273
273
|
with_app(subject, 'name' => subject.app) do |app_data|
|
274
|
-
subject.install_addons.map{|a| a['name']}.
|
275
|
-
subject.installed_addons.map{|a|a['name']}.
|
274
|
+
expect(subject.install_addons.map{|a| a['name']}).to include *%w[custom_domains:basic ssl:piggyback]
|
275
|
+
expect(subject.installed_addons.map{|a|a['name']}).to match subject.install_addons.map{|a| a['name']}
|
276
276
|
end
|
277
277
|
end
|
278
278
|
|
279
279
|
it "only installs missing addons" do
|
280
280
|
subject = Factory::Stage.build('production', {"app" => "awesomeapp", "stack" => "bamboo-ree-1.8.7", "addons" => %w[shared-database:5mb custom_domains:basic ssl:piggyback]})
|
281
281
|
with_app(subject, 'name' => subject.app) do |app_data|
|
282
|
-
subject.install_addons.map{|a| a['name']}.
|
282
|
+
expect(subject.install_addons.map{|a| a['name']}).to include *%w[shared-database:5mb custom_domains:basic ssl:piggyback]
|
283
283
|
end
|
284
284
|
end
|
285
285
|
end
|
metadata
CHANGED
@@ -1,8 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: heroku_san
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 4.
|
5
|
-
prerelease:
|
4
|
+
version: 4.4.0
|
6
5
|
platform: ruby
|
7
6
|
authors:
|
8
7
|
- Elijah Miller
|
@@ -12,54 +11,48 @@ authors:
|
|
12
11
|
autorequire:
|
13
12
|
bindir: bin
|
14
13
|
cert_chain: []
|
15
|
-
date:
|
14
|
+
date: 2016-03-11 00:00:00.000000000 Z
|
16
15
|
dependencies:
|
17
16
|
- !ruby/object:Gem::Dependency
|
18
17
|
name: heroku-api
|
19
18
|
requirement: !ruby/object:Gem::Requirement
|
20
|
-
none: false
|
21
19
|
requirements:
|
22
|
-
- -
|
20
|
+
- - ">="
|
23
21
|
- !ruby/object:Gem::Version
|
24
22
|
version: 0.1.2
|
25
23
|
type: :runtime
|
26
24
|
prerelease: false
|
27
25
|
version_requirements: !ruby/object:Gem::Requirement
|
28
|
-
none: false
|
29
26
|
requirements:
|
30
|
-
- -
|
27
|
+
- - ">="
|
31
28
|
- !ruby/object:Gem::Version
|
32
29
|
version: 0.1.2
|
33
30
|
- !ruby/object:Gem::Dependency
|
34
31
|
name: json
|
35
32
|
requirement: !ruby/object:Gem::Requirement
|
36
|
-
none: false
|
37
33
|
requirements:
|
38
|
-
- -
|
34
|
+
- - ">="
|
39
35
|
- !ruby/object:Gem::Version
|
40
36
|
version: '0'
|
41
37
|
type: :runtime
|
42
38
|
prerelease: false
|
43
39
|
version_requirements: !ruby/object:Gem::Requirement
|
44
|
-
none: false
|
45
40
|
requirements:
|
46
|
-
- -
|
41
|
+
- - ">="
|
47
42
|
- !ruby/object:Gem::Version
|
48
43
|
version: '0'
|
49
44
|
- !ruby/object:Gem::Dependency
|
50
45
|
name: rake
|
51
46
|
requirement: !ruby/object:Gem::Requirement
|
52
|
-
none: false
|
53
47
|
requirements:
|
54
|
-
- -
|
48
|
+
- - ">="
|
55
49
|
- !ruby/object:Gem::Version
|
56
50
|
version: '0'
|
57
51
|
type: :runtime
|
58
52
|
prerelease: false
|
59
53
|
version_requirements: !ruby/object:Gem::Requirement
|
60
|
-
none: false
|
61
54
|
requirements:
|
62
|
-
- -
|
55
|
+
- - ">="
|
63
56
|
- !ruby/object:Gem::Version
|
64
57
|
version: '0'
|
65
58
|
description: Manage multiple Heroku instances/apps for a single Rails app using Rake
|
@@ -69,10 +62,10 @@ extensions: []
|
|
69
62
|
extra_rdoc_files:
|
70
63
|
- README.md
|
71
64
|
files:
|
72
|
-
- .gitignore
|
73
|
-
- .ruby-gemset
|
74
|
-
- .ruby-version
|
75
|
-
- .travis.yml
|
65
|
+
- ".gitignore"
|
66
|
+
- ".ruby-gemset"
|
67
|
+
- ".ruby-version"
|
68
|
+
- ".travis.yml"
|
76
69
|
- CHANGELOG.md
|
77
70
|
- Gemfile
|
78
71
|
- Guardfile
|
@@ -130,32 +123,28 @@ files:
|
|
130
123
|
homepage: http://github.com/fastestforward/heroku_san
|
131
124
|
licenses:
|
132
125
|
- MIT
|
126
|
+
metadata: {}
|
133
127
|
post_install_message:
|
134
128
|
rdoc_options: []
|
135
129
|
require_paths:
|
136
130
|
- lib
|
137
131
|
required_ruby_version: !ruby/object:Gem::Requirement
|
138
|
-
none: false
|
139
132
|
requirements:
|
140
|
-
- -
|
133
|
+
- - ">="
|
141
134
|
- !ruby/object:Gem::Version
|
142
135
|
version: '0'
|
143
|
-
segments:
|
144
|
-
- 0
|
145
|
-
hash: -1867339558335233432
|
146
136
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
147
|
-
none: false
|
148
137
|
requirements:
|
149
|
-
- -
|
138
|
+
- - ">="
|
150
139
|
- !ruby/object:Gem::Version
|
151
140
|
version: '0'
|
152
141
|
requirements: []
|
153
142
|
rubyforge_project:
|
154
|
-
rubygems_version:
|
143
|
+
rubygems_version: 2.4.5.1
|
155
144
|
signing_key:
|
156
|
-
specification_version:
|
157
|
-
summary:
|
158
|
-
|
145
|
+
specification_version: 4
|
146
|
+
summary: 'A bunch of useful Rake tasks for managing your Heroku apps. NOTE: The Heroku
|
147
|
+
Toolbelt must be installed to use this gem. https://toolbelt.heroku.com/'
|
159
148
|
test_files:
|
160
149
|
- features/config.feature
|
161
150
|
- features/extended-config.feature
|