heroku_san 2.1.0 → 2.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG.md +5 -0
- data/features/config.feature +2 -1
- data/features/extended-config.feature +29 -17
- data/features/remote.feature +29 -56
- data/features/step_definitions/remote_steps.rb +123 -0
- data/features/support/env.rb +1 -1
- data/heroku_san.gemspec +2 -2
- data/lib/heroku_san/project.rb +1 -0
- data/lib/heroku_san/stage.rb +30 -15
- data/lib/heroku_san/version.rb +1 -1
- data/lib/tasks.rb +12 -9
- data/spec/heroku_san/project_spec.rb +4 -5
- data/spec/heroku_san/stage_spec.rb +57 -71
- metadata +20 -19
- data/.gitmodules +0 -3
data/CHANGELOG.md
CHANGED
data/features/config.feature
CHANGED
@@ -6,6 +6,7 @@ Feature: Command Line
|
|
6
6
|
And I overwrite "Gemfile" with:
|
7
7
|
"""
|
8
8
|
source :rubygems
|
9
|
+
gem 'rails'
|
9
10
|
gem 'heroku_san', :path => '../../../.'
|
10
11
|
"""
|
11
12
|
|
@@ -28,7 +29,7 @@ Feature: Command Line
|
|
28
29
|
And the output should contain "staging is shorthand for the Heroku app awesomeapp-staging"
|
29
30
|
And the output should contain "demo is shorthand for the Heroku app awesomeapp-demo"
|
30
31
|
|
31
|
-
Scenario: Config file still accepts the heroku_san format
|
32
|
+
Scenario: Config file still accepts the old heroku_san format
|
32
33
|
Given a file named "config/heroku.yml" with:
|
33
34
|
"""
|
34
35
|
apps:
|
@@ -1,17 +1,32 @@
|
|
1
1
|
Feature: Extended config
|
2
2
|
|
3
3
|
Background:
|
4
|
+
Given a directory named "test-config"
|
5
|
+
And I cd to "test-config"
|
6
|
+
And I run `git init .`
|
7
|
+
And a file named "config.yml" with:
|
8
|
+
"""
|
9
|
+
production:
|
10
|
+
TEST_REMOTE: 'hello_production'
|
11
|
+
staging:
|
12
|
+
TEST_REMOTE: 'goodbye_staging'
|
13
|
+
"""
|
14
|
+
And I run `git add .`
|
15
|
+
And I run `git commit -m 'Initial commit'`
|
16
|
+
And I cd to ".."
|
4
17
|
Given I run `rails new heroku_san_test -O`
|
5
18
|
And I cd to "heroku_san_test"
|
6
19
|
And I overwrite "Gemfile" with:
|
7
20
|
"""
|
8
21
|
source :rubygems
|
22
|
+
gem 'rails'
|
9
23
|
gem 'heroku_san', :path => '../../../.'
|
10
24
|
"""
|
25
|
+
|
11
26
|
Scenario: Config information can be pulled from a separate git repository
|
12
27
|
Given a file named "config/heroku.yml" with:
|
13
28
|
"""
|
14
|
-
config_repo: 'file:///<%= File.join(File.expand_path(File.dirname(__FILE__)), '..', '
|
29
|
+
config_repo: 'file:///<%= File.join(File.expand_path(File.dirname(__FILE__)), '..', 'test-config') %>'
|
15
30
|
production:
|
16
31
|
app: awesomeapp
|
17
32
|
staging:
|
@@ -19,11 +34,10 @@ Feature: Extended config
|
|
19
34
|
demo:
|
20
35
|
app: awesomeapp-demo
|
21
36
|
"""
|
22
|
-
|
23
37
|
When I run `rake --trace all heroku:config:list:local`
|
24
38
|
|
25
|
-
Then the output should contain "
|
26
|
-
And the output should contain "
|
39
|
+
Then the output should contain "TEST_REMOTE: hello_production"
|
40
|
+
And the output should contain "TEST_REMOTE: goodbye_staging"
|
27
41
|
|
28
42
|
Scenario: Config information can be listed
|
29
43
|
Given a file named "config/heroku.yml" with:
|
@@ -31,38 +45,36 @@ Feature: Extended config
|
|
31
45
|
production:
|
32
46
|
app: awesomeapp
|
33
47
|
config:
|
34
|
-
TEST_LOCAL: '
|
48
|
+
TEST_LOCAL: 'hello_production'
|
35
49
|
staging:
|
36
50
|
app: awesomeapp-staging
|
37
51
|
config:
|
38
|
-
TEST_LOCAL: '
|
52
|
+
TEST_LOCAL: 'goodbye_staging'
|
39
53
|
demo:
|
40
54
|
app: awesomeapp-demo
|
41
55
|
"""
|
42
|
-
|
43
56
|
When I run `rake --trace all heroku:config:list:local`
|
44
57
|
|
45
|
-
Then the output should contain "
|
46
|
-
And the output should contain "
|
58
|
+
Then the output should contain "TEST_LOCAL: hello_production"
|
59
|
+
And the output should contain "TEST_LOCAL: goodbye_staging"
|
47
60
|
|
48
61
|
Scenario: Config information can be merged between local and remote
|
49
62
|
Given a file named "config/heroku.yml" with:
|
50
63
|
"""
|
51
|
-
config_repo: 'file:///<%= File.join(File.expand_path(File.dirname(__FILE__)), '..', '
|
64
|
+
config_repo: 'file:///<%= File.join(File.expand_path(File.dirname(__FILE__)), '..', 'test-config') %>'
|
52
65
|
production:
|
53
66
|
app: awesomeapp
|
54
67
|
config:
|
55
|
-
TEST_LOCAL: '
|
68
|
+
TEST_LOCAL: 'hello_production'
|
56
69
|
staging:
|
57
70
|
app: awesomeapp-staging
|
58
71
|
config:
|
59
|
-
TEST_LOCAL: '
|
72
|
+
TEST_LOCAL: 'goodbye_staging'
|
60
73
|
TEST_REMOTE: 'overridden_by_remote'
|
61
74
|
"""
|
62
|
-
|
63
75
|
When I run `rake --trace all heroku:config:list:local`
|
64
76
|
|
65
|
-
Then the output should contain "
|
66
|
-
And the output should contain "
|
67
|
-
And the output should contain "
|
68
|
-
And the output should contain "
|
77
|
+
Then the output should contain "TEST_LOCAL: hello_production"
|
78
|
+
And the output should contain "TEST_REMOTE: hello_production"
|
79
|
+
And the output should contain "TEST_LOCAL: goodbye_staging"
|
80
|
+
And the output should contain "TEST_REMOTE: goodbye_staging"
|
data/features/remote.feature
CHANGED
@@ -1,57 +1,30 @@
|
|
1
|
-
@announce @slow_process
|
2
|
-
Feature:
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
When I
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
Then the output should contain "Maintenance mode enabled."
|
15
|
-
|
16
|
-
When I run `rake demo restart`
|
17
|
-
Then the output should contain "Restarting processes... done"
|
18
|
-
|
19
|
-
When I run `rake demo heroku:maintenance_off`
|
20
|
-
Then the output should contain "Maintenance mode disabled."
|
21
|
-
|
22
|
-
When I run `rake demo heroku:rake[db:seed]`
|
23
|
-
Then I run `curl -s http://heroku-san-demo-demo.heroku.com/droids.text`
|
24
|
-
And the output should contain "C3PO, Marvin, R2D2, Robby"
|
1
|
+
@announce-cmd @slow_process
|
2
|
+
Feature: heroku_san can control a project on Heroku
|
3
|
+
WARNING: This WILL create apps on Heroku!
|
4
|
+
You must login with the heroku cli before starting
|
5
|
+
this test; otherwise it will probably hang the first
|
6
|
+
time it tries to do anything with Heroku itself.
|
7
|
+
|
8
|
+
Scenario: Installing on a project
|
9
|
+
Given I have a new Rails project
|
10
|
+
When I am in the project directory
|
11
|
+
And I add heroku_san to the Gemfile
|
12
|
+
And I run bundle install
|
13
|
+
Then rake reports that the heroku: tasks are available
|
25
14
|
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
And I run
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
And
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
# Given I run `rake heroku:create_config`
|
43
|
-
|
44
|
-
# When I run `rake demo heroku:create`
|
45
|
-
# Then the output should contain "somthing about the created app"
|
46
|
-
# $ rake all heroku:create
|
47
|
-
# heroku create heroku-san-demo-demo
|
48
|
-
# Creating heroku-san-demo-demo.... done, stack is bamboo-mri-1.9.2
|
49
|
-
# http://heroku-san-demo-demo.heroku.com/ | git@heroku.com:heroku-san-demo-demo.git
|
50
|
-
# Git remote heroku added
|
51
|
-
# heroku create heroku-san-demo-production
|
52
|
-
# Creating heroku-san-demo-production... done, stack is bamboo-mri-1.9.2
|
53
|
-
# http://heroku-san-demo-production.heroku.com/ | git@heroku.com:heroku-san-demo-production.git
|
54
|
-
# heroku create heroku-san-demo-staging
|
55
|
-
# Creating heroku-san-demo-staging... done, stack is bamboo-mri-1.9.2
|
56
|
-
# http://heroku-san-demo-staging.heroku.com/ | git@heroku.com:heroku-san-demo-staging.git
|
57
|
-
|
15
|
+
Scenario: Manipulates the project on Heroku
|
16
|
+
Given I have a new Rails project
|
17
|
+
When I am in the project directory
|
18
|
+
And I add heroku_san to the Gemfile
|
19
|
+
And I run bundle install
|
20
|
+
And I create a new config/heroku.yml file
|
21
|
+
And I create my project on Heroku
|
22
|
+
And I list the remote configuration
|
23
|
+
And I curl the app home page
|
24
|
+
And I configure my project
|
25
|
+
And I turn maintenance on
|
26
|
+
And I deploy my project
|
27
|
+
And I turn maintenance off
|
28
|
+
And I restart my project
|
29
|
+
And I list all apps on Heroku
|
30
|
+
Then heroku_san is green
|
@@ -0,0 +1,123 @@
|
|
1
|
+
World(Aruba::Api)
|
2
|
+
|
3
|
+
Given /^I have a new Rails project$/ do
|
4
|
+
# template = File.join(File.expand_path(File.dirname(__FILE__)), '..', '..', 'features', 'data', 'template.rb')
|
5
|
+
cmd = "rails new heroku_san_test --quiet --force --database=postgresql --skip-bundle --skip-javascript --skip-test-unit --skip-sprockets" #" --template #{template}"
|
6
|
+
run_simple unescape(cmd)
|
7
|
+
end
|
8
|
+
|
9
|
+
When /^I am in the project directory$/ do
|
10
|
+
cd '/heroku_san_test'
|
11
|
+
end
|
12
|
+
|
13
|
+
When /^I add heroku_san to the Gemfile$/ do
|
14
|
+
append_to_file 'Gemfile', <<EOT
|
15
|
+
group :development, :test do
|
16
|
+
gem 'heroku_san', :path => '../../../.'
|
17
|
+
end
|
18
|
+
EOT
|
19
|
+
end
|
20
|
+
|
21
|
+
When /^I run bundle install$/ do
|
22
|
+
use_clean_gemset 'heroku_san_test'
|
23
|
+
run_simple 'bundle install --quiet'
|
24
|
+
write_file '.rvmrc', "rvm use default@heroku_san_test\n"
|
25
|
+
end
|
26
|
+
|
27
|
+
Then /^rake reports that the heroku: tasks are available$/ do
|
28
|
+
run_simple 'rake -T heroku:'
|
29
|
+
assert_partial_output 'rake heroku:apps', all_output
|
30
|
+
end
|
31
|
+
|
32
|
+
When /^I create a new config\/heroku\.yml file$/ do
|
33
|
+
run_simple 'rake heroku:create_config'
|
34
|
+
assert_matching_output %q{Copied example config to ".*.config.heroku.yml"}, all_output
|
35
|
+
assert_matching_output %q{Please edit ".*.config.heroku.yml" with your application's settings.}, all_output
|
36
|
+
overwrite_file 'config/heroku.yml', <<EOT
|
37
|
+
---
|
38
|
+
test_app:
|
39
|
+
EOT
|
40
|
+
end
|
41
|
+
|
42
|
+
When /^I create my project on Heroku$/ do
|
43
|
+
cmd = 'rake test_app heroku:create'
|
44
|
+
run_simple unescape(cmd)
|
45
|
+
assert_matching_output %q{test_app: Created ([\w-]+)}, all_output
|
46
|
+
output = stdout_from cmd
|
47
|
+
@app = output.match(/test_app: Created ([\w-]+)/)[1]
|
48
|
+
overwrite_file 'config/heroku.yml', <<EOT
|
49
|
+
---
|
50
|
+
test_app:
|
51
|
+
app: #{@app}
|
52
|
+
EOT
|
53
|
+
end
|
54
|
+
|
55
|
+
When /^I list the remote configuration$/ do
|
56
|
+
cmd = 'rake test_app heroku:config:list'
|
57
|
+
run_simple unescape(cmd)
|
58
|
+
assert_partial_output "APP_NAME: #{@app}", all_output
|
59
|
+
assert_partial_output "URL: #{@app}.heroku.com", all_output
|
60
|
+
output = stdout_from cmd
|
61
|
+
@url = output.match(/\bURL:\s+(.*.heroku.com)\b/)[1]
|
62
|
+
@curl = unescape("curl --silent http://#{@url}")
|
63
|
+
end
|
64
|
+
|
65
|
+
When /^I curl the app home page$/ do
|
66
|
+
run_simple @curl
|
67
|
+
output = stdout_from @curl
|
68
|
+
assert_partial_output '<h1><strong>Heroku | Welcome to your new app!</strong></h1>', output
|
69
|
+
end
|
70
|
+
|
71
|
+
When /^I configure my project$/ do
|
72
|
+
overwrite_file 'config/heroku.yml', <<EOT
|
73
|
+
---
|
74
|
+
test_app:
|
75
|
+
app: #{@app}
|
76
|
+
config:
|
77
|
+
DROIDS: marvin
|
78
|
+
EOT
|
79
|
+
cmd = 'rake test_app heroku:config'
|
80
|
+
run_simple unescape(cmd)
|
81
|
+
assert_partial_output 'DROIDS: marvin', all_output
|
82
|
+
end
|
83
|
+
|
84
|
+
When /^I turn maintenance on$/ do
|
85
|
+
run_simple 'rake test_app heroku:maintenance_on'
|
86
|
+
assert_partial_output 'test_app: Maintenance mode enabled.', all_output
|
87
|
+
run_simple @curl
|
88
|
+
output = stdout_from @curl
|
89
|
+
assert_partial_output '<title>Offline for Maintenance</title>', all_output
|
90
|
+
end
|
91
|
+
|
92
|
+
When /^I turn maintenance off$/ do
|
93
|
+
run_simple 'rake test_app heroku:maintenance_off'
|
94
|
+
assert_partial_output 'test_app: Maintenance mode disabled.', all_output
|
95
|
+
run_simple @curl + "/droids"
|
96
|
+
assert_partial_output %Q{<code>marvin</code>}, all_output
|
97
|
+
end
|
98
|
+
|
99
|
+
When /^I restart my project$/ do
|
100
|
+
run_simple 'rake test_app heroku:restart'
|
101
|
+
assert_partial_output 'test_app: Restarted.', all_output
|
102
|
+
end
|
103
|
+
|
104
|
+
When /^I deploy my project$/ do
|
105
|
+
run_simple 'git init .'
|
106
|
+
run_simple 'rails generate scaffold droids'
|
107
|
+
append_to_file 'app/views/droids/index.html.erb', %Q{\n<div><code><%= ENV['DROIDS'] -%></code></div>\n}
|
108
|
+
run_simple 'git add .'
|
109
|
+
run_simple 'git commit -m "Initial commit"'
|
110
|
+
run_simple 'rake test_app deploy'
|
111
|
+
assert_partial_output "http://#{@app}.heroku.com deployed to Heroku", all_output
|
112
|
+
end
|
113
|
+
|
114
|
+
When /^I list all apps on Heroku$/ do
|
115
|
+
run_simple 'rake heroku:apps'
|
116
|
+
assert_partial_output "test_app is shorthand for the Heroku app #{@app} located at:", all_output
|
117
|
+
assert_partial_output "git@heroku.com:#{@app}.git", all_output
|
118
|
+
assert_matching_output '@ \w{40} master', all_output
|
119
|
+
end
|
120
|
+
|
121
|
+
Then /^heroku_san is green$/ do
|
122
|
+
run_simple "heroku apps:destroy #{@app} --confirm #{@app}"
|
123
|
+
end
|
data/features/support/env.rb
CHANGED
data/heroku_san.gemspec
CHANGED
@@ -22,13 +22,13 @@ Gem::Specification.new do |s|
|
|
22
22
|
s.specification_version = 3
|
23
23
|
|
24
24
|
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
25
|
-
s.
|
25
|
+
s.add_development_dependency(%q<rails>, ['>= 2'])
|
26
26
|
s.add_runtime_dependency(%q<heroku>, ['>= 2'])
|
27
27
|
s.add_runtime_dependency(%q<rake>)
|
28
28
|
s.add_development_dependency(%q<aruba>)
|
29
29
|
s.add_development_dependency(%q<cucumber>)
|
30
30
|
s.add_development_dependency(%q<rake>)
|
31
|
-
s.add_development_dependency(%q<bundler>, ['~> 1.
|
31
|
+
s.add_development_dependency(%q<bundler>, ['~> 1.1 '])
|
32
32
|
else
|
33
33
|
s.add_dependency(%q<rails>, ['>= 2'])
|
34
34
|
s.add_dependency(%q<heroku>, ['>= 2'])
|
data/lib/heroku_san/project.rb
CHANGED
@@ -101,6 +101,7 @@ module HerokuSan
|
|
101
101
|
|
102
102
|
# make sure each app has a 'config' section & merge w/extra
|
103
103
|
app_settings.keys.each do |name|
|
104
|
+
app_settings[name] ||= {}
|
104
105
|
app_settings[name]['config'] ||= {}
|
105
106
|
app_settings[name]['config'].merge!(extra_config[name]) if extra_config[name]
|
106
107
|
end
|
data/lib/heroku_san/stage.rb
CHANGED
@@ -1,3 +1,6 @@
|
|
1
|
+
require 'heroku'
|
2
|
+
require 'json'
|
3
|
+
|
1
4
|
module HerokuSan
|
2
5
|
class Stage
|
3
6
|
attr_reader :name
|
@@ -8,6 +11,10 @@ module HerokuSan
|
|
8
11
|
@options = options
|
9
12
|
end
|
10
13
|
|
14
|
+
def heroku
|
15
|
+
Heroku::Auth.client
|
16
|
+
end
|
17
|
+
|
11
18
|
def app
|
12
19
|
@options['app'] or raise MissingApp, "#{name}: is missing the app: configuration value. I don't know what to access on Heroku."
|
13
20
|
end
|
@@ -17,7 +24,7 @@ module HerokuSan
|
|
17
24
|
end
|
18
25
|
|
19
26
|
def stack
|
20
|
-
@options['stack'] ||=
|
27
|
+
@options['stack'] ||= heroku.list_stacks(app).detect{|stack| stack['current']}['name']
|
21
28
|
end
|
22
29
|
|
23
30
|
def tag
|
@@ -42,47 +49,55 @@ module HerokuSan
|
|
42
49
|
end
|
43
50
|
|
44
51
|
def migrate
|
45
|
-
|
46
|
-
|
52
|
+
rake('db:migrate')
|
53
|
+
restart
|
54
|
+
end
|
55
|
+
|
56
|
+
def rake(*args)
|
57
|
+
run 'rake', args.join(' ')
|
58
|
+
# heroku.rake app, args.join(' ')
|
47
59
|
end
|
48
60
|
|
49
61
|
def maintenance(action = nil)
|
50
62
|
if block_given?
|
51
|
-
|
63
|
+
heroku.maintenance(app, :on)
|
52
64
|
begin
|
53
65
|
yield
|
54
66
|
ensure
|
55
|
-
|
67
|
+
heroku.maintenance(app, :off)
|
56
68
|
end
|
57
69
|
else
|
58
70
|
raise ArgumentError, "Action #{action.inspect} must be one of (:on, :off)", caller if ![:on, :off].include?(action)
|
59
|
-
|
71
|
+
heroku.maintenance(app, action)
|
60
72
|
end
|
61
73
|
end
|
62
74
|
|
63
|
-
def create
|
64
|
-
|
75
|
+
def create # DEPREC?
|
76
|
+
if @options['stack']
|
77
|
+
heroku.create(@options['app'], {:stack => @options['stack']})
|
78
|
+
else
|
79
|
+
heroku.create(@options['app'])
|
80
|
+
end
|
65
81
|
end
|
66
82
|
|
67
|
-
def sharing_add(email)
|
83
|
+
def sharing_add(email) # DEPREC?
|
68
84
|
sh_heroku "sharing:add #{email.chomp}"
|
69
85
|
end
|
70
86
|
|
71
|
-
def sharing_remove(email)
|
87
|
+
def sharing_remove(email) # DEPREC?
|
72
88
|
sh_heroku "sharing:remove #{email.chomp}"
|
73
89
|
end
|
74
90
|
|
75
91
|
def long_config
|
76
|
-
|
92
|
+
heroku.config_vars(app)
|
77
93
|
end
|
78
94
|
|
79
|
-
def push_config(options =
|
80
|
-
|
81
|
-
sh_heroku "config:add #{vars}"
|
95
|
+
def push_config(options = nil)
|
96
|
+
JSON.parse(heroku.add_config_vars(app, options || config))
|
82
97
|
end
|
83
98
|
|
84
99
|
def restart
|
85
|
-
|
100
|
+
heroku.ps_restart(app)
|
86
101
|
end
|
87
102
|
|
88
103
|
def logs(tail = false)
|
data/lib/heroku_san/version.rb
CHANGED
data/lib/tasks.rb
CHANGED
@@ -20,7 +20,7 @@ namespace :heroku do
|
|
20
20
|
desc "Creates the Heroku app"
|
21
21
|
task :create do
|
22
22
|
each_heroku_app do |stage|
|
23
|
-
stage.create
|
23
|
+
puts "#{stage.name}: Created #{stage.create}"
|
24
24
|
end
|
25
25
|
end
|
26
26
|
|
@@ -82,7 +82,7 @@ namespace :heroku do
|
|
82
82
|
desc 'Add config:vars to each application.'
|
83
83
|
task :config do
|
84
84
|
each_heroku_app do |stage|
|
85
|
-
stage.push_config
|
85
|
+
puts y(stage.push_config)
|
86
86
|
end
|
87
87
|
end
|
88
88
|
|
@@ -91,7 +91,7 @@ namespace :heroku do
|
|
91
91
|
filename = %Q{#{@heroku_san.config_file.to_s}}
|
92
92
|
if @heroku_san.create_config
|
93
93
|
puts "Copied example config to #{filename.inspect}"
|
94
|
-
if ENV['EDITOR']
|
94
|
+
if ENV['EDITOR'] && ENV['EDITOR'] != ''
|
95
95
|
sh "#{ENV['EDITOR']} #{filename}"
|
96
96
|
else
|
97
97
|
puts "Please edit #{filename.inspect} with your application's settings."
|
@@ -109,7 +109,7 @@ namespace :heroku do
|
|
109
109
|
puts command
|
110
110
|
config = Hash[`#{command}`.scan(/^(.+?)\s*=>\s*(.+)$/)]
|
111
111
|
if config['RACK_ENV'] != stage.name
|
112
|
-
stage.push_config RACK_ENV: stage.name
|
112
|
+
puts stage.push_config RACK_ENV: stage.name
|
113
113
|
end
|
114
114
|
end
|
115
115
|
end
|
@@ -118,7 +118,7 @@ namespace :heroku do
|
|
118
118
|
task :list do
|
119
119
|
each_heroku_app do |stage|
|
120
120
|
puts "#{stage.name}:"
|
121
|
-
stage.long_config
|
121
|
+
puts y(stage.long_config)
|
122
122
|
end
|
123
123
|
end
|
124
124
|
|
@@ -126,9 +126,8 @@ namespace :heroku do
|
|
126
126
|
desc "Lists local config variables without setting them"
|
127
127
|
task :local do
|
128
128
|
each_heroku_app do |stage|
|
129
|
-
|
130
|
-
|
131
|
-
end
|
129
|
+
puts "#{stage.name}:"
|
130
|
+
puts y(stage.config)
|
132
131
|
end
|
133
132
|
end
|
134
133
|
end
|
@@ -137,7 +136,7 @@ namespace :heroku do
|
|
137
136
|
desc 'Runs a rake task remotely'
|
138
137
|
task :rake, [:task] do |t, args|
|
139
138
|
each_heroku_app do |stage|
|
140
|
-
stage.
|
139
|
+
puts stage.rake args.task
|
141
140
|
end
|
142
141
|
end
|
143
142
|
|
@@ -161,6 +160,7 @@ namespace :heroku do
|
|
161
160
|
task :maintenance do
|
162
161
|
each_heroku_app do |stage|
|
163
162
|
stage.maintenance :on
|
163
|
+
puts "#{stage.name}: Maintenance mode enabled."
|
164
164
|
end
|
165
165
|
end
|
166
166
|
|
@@ -168,6 +168,7 @@ namespace :heroku do
|
|
168
168
|
task :maintenance_on do
|
169
169
|
each_heroku_app do |stage|
|
170
170
|
stage.maintenance :on
|
171
|
+
puts "#{stage.name}: Maintenance mode enabled."
|
171
172
|
end
|
172
173
|
end
|
173
174
|
|
@@ -175,6 +176,7 @@ namespace :heroku do
|
|
175
176
|
task :maintenance_off do
|
176
177
|
each_heroku_app do |stage|
|
177
178
|
stage.maintenance :off
|
179
|
+
puts "#{stage.name}: Maintenance mode disabled."
|
178
180
|
end
|
179
181
|
end
|
180
182
|
|
@@ -227,6 +229,7 @@ namespace :heroku do
|
|
227
229
|
task :restart do
|
228
230
|
each_heroku_app do |stage|
|
229
231
|
stage.restart
|
232
|
+
puts "#{stage.name}: Restarted."
|
230
233
|
end
|
231
234
|
end
|
232
235
|
|
@@ -6,7 +6,7 @@ describe HerokuSan::Project do
|
|
6
6
|
heroku_san = HerokuSan::Project.new("/u/should/never/get/here")
|
7
7
|
heroku_san.all.should == []
|
8
8
|
end
|
9
|
-
|
9
|
+
|
10
10
|
context "using the example config file" do
|
11
11
|
let(:heroku_config_file) { File.join(SPEC_ROOT, "fixtures", "example.yml") }
|
12
12
|
let(:template_config_file) {
|
@@ -14,10 +14,9 @@ describe HerokuSan::Project do
|
|
14
14
|
(File.respond_to? :realpath) ? File.realpath(path) : path
|
15
15
|
}
|
16
16
|
let(:heroku_san) { HerokuSan::Project.new(heroku_config_file) }
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
end
|
17
|
+
subject { heroku_san }
|
18
|
+
|
19
|
+
its(:all) { should =~ %w[production staging demo] }
|
21
20
|
|
22
21
|
context "using the heroku_san format" do
|
23
22
|
let(:heroku_san) { HerokuSan::Project.new(File.join(SPEC_ROOT, "fixtures", "old_format.yml")) }
|
@@ -1,9 +1,15 @@
|
|
1
1
|
require 'spec_helper'
|
2
|
+
require 'heroku/client'
|
2
3
|
|
3
4
|
describe HerokuSan::Stage do
|
4
5
|
include Git
|
5
6
|
subject { HerokuSan::Stage.new('production', {"app" => "awesomeapp", "stack" => "bamboo-ree-1.8.7"})}
|
6
7
|
|
8
|
+
before do
|
9
|
+
@heroku_client = mock(Heroku::Client)
|
10
|
+
Heroku::Auth.stub(:client).and_return(@heroku_client)
|
11
|
+
end
|
12
|
+
|
7
13
|
context "initializes" do
|
8
14
|
subject { HerokuSan::Stage.new('production',
|
9
15
|
{"stack" => "cedar",
|
@@ -30,38 +36,29 @@ describe HerokuSan::Stage do
|
|
30
36
|
end
|
31
37
|
end
|
32
38
|
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
aspen-mri-1.8.6
|
40
|
-
* bamboo-mri-1.9.2
|
41
|
-
bamboo-ree-1.8.7
|
42
|
-
cedar (beta)
|
43
|
-
EOT
|
44
|
-
}
|
45
|
-
subject.stack.should == 'bamboo-mri-1.9.2'
|
46
|
-
end
|
47
|
-
|
48
|
-
it "returns the stack name from the config if it is set there" do
|
49
|
-
subject = HerokuSan::Stage.new('production', {"app" => "awesomeapp", "stack" => "cedar"})
|
50
|
-
subject.should_not_receive("`")
|
51
|
-
subject.stack.should == 'cedar'
|
52
|
-
end
|
39
|
+
describe "#stack" do
|
40
|
+
it "returns the name of the stack from Heroku" do
|
41
|
+
subject = HerokuSan::Stage.new('production', {"app" => "awesomeapp"})
|
42
|
+
@heroku_client.should_receive(:list_stacks).with('awesomeapp').
|
43
|
+
and_return { [{'name' => 'other'}, {'name' => 'the-one', 'current' => true}] }
|
44
|
+
subject.stack.should == 'the-one'
|
53
45
|
end
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
46
|
+
|
47
|
+
it "returns the stack name from the config if it is set there" do
|
48
|
+
subject = HerokuSan::Stage.new('production', {"app" => "awesomeapp", "stack" => "cedar"})
|
49
|
+
subject.stack.should == 'cedar'
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
describe "#run" do
|
54
|
+
it "runs commands using the pre-cedar format" do
|
55
|
+
subject.should_receive(:sh).with("heroku run:rake foo bar bleh --app awesomeapp")
|
56
|
+
subject.run 'rake', 'foo bar bleh'
|
57
|
+
end
|
58
|
+
it "runs commands using the new cedar format" do
|
59
|
+
subject = HerokuSan::Stage.new('production', {"app" => "awesomeapp", "stack" => "cedar"})
|
60
|
+
subject.should_receive(:sh).with("heroku run worker foo bar bleh --app awesomeapp")
|
61
|
+
subject.run 'worker', 'foo bar bleh'
|
65
62
|
end
|
66
63
|
end
|
67
64
|
|
@@ -89,21 +86,22 @@ EOT
|
|
89
86
|
|
90
87
|
describe "#migrate" do
|
91
88
|
it "runs rake db:migrate" do
|
92
|
-
subject.should_receive(:
|
93
|
-
|
94
|
-
|
89
|
+
subject.should_receive(:rake).with('db:migrate').and_return 'output:'
|
90
|
+
# @heroku_client.should_receive(:rake).with('awesomeapp', 'db:migrate').and_return "output:"
|
91
|
+
@heroku_client.should_receive(:ps_restart).with('awesomeapp').and_return "restarted"
|
92
|
+
subject.migrate.should == "restarted"
|
95
93
|
end
|
96
94
|
end
|
97
95
|
|
98
96
|
describe "#maintenance" do
|
99
97
|
it ":on" do
|
100
|
-
|
101
|
-
subject.maintenance
|
98
|
+
@heroku_client.should_receive(:maintenance).with('awesomeapp', :on) {'on'}
|
99
|
+
subject.maintenance(:on).should == 'on'
|
102
100
|
end
|
103
101
|
|
104
102
|
it ":off" do
|
105
|
-
|
106
|
-
subject.maintenance
|
103
|
+
@heroku_client.should_receive(:maintenance).with('awesomeapp', :off) {'off'}
|
104
|
+
subject.maintenance(:off).should == 'off'
|
107
105
|
end
|
108
106
|
|
109
107
|
it "otherwise raises an ArgumentError" do
|
@@ -114,21 +112,17 @@ EOT
|
|
114
112
|
|
115
113
|
context "with a block" do
|
116
114
|
it "wraps it in a maitenance mode" do
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
subject.maintenance do
|
121
|
-
reactor.scram(:now)
|
122
|
-
end
|
115
|
+
reactor = mock("Reactor"); reactor.should_receive(:scram).with(:now).ordered
|
116
|
+
@heroku_client.should_receive(:maintenance).with('awesomeapp', :on).ordered
|
117
|
+
@heroku_client.should_receive(:maintenance).with('awesomeapp', :off).ordered
|
118
|
+
subject.maintenance do reactor.scram(:now) end
|
123
119
|
end
|
124
120
|
it "ensures that maintenance mode is turned off" do
|
125
|
-
|
121
|
+
@heroku_client.should_receive(:maintenance).with('awesomeapp', :on).ordered
|
126
122
|
reactor = mock("Reactor"); reactor.should_receive(:scram).with(:now).and_raise(RuntimeError)
|
127
|
-
|
123
|
+
@heroku_client.should_receive(:maintenance).with('awesomeapp', :off).ordered
|
128
124
|
expect {
|
129
|
-
subject.maintenance do
|
130
|
-
reactor.scram(:now)
|
131
|
-
end
|
125
|
+
subject.maintenance do reactor.scram(:now) end
|
132
126
|
}.to raise_error
|
133
127
|
end
|
134
128
|
end
|
@@ -136,14 +130,19 @@ EOT
|
|
136
130
|
|
137
131
|
describe "#create" do
|
138
132
|
it "creates an app on heroku" do
|
139
|
-
|
133
|
+
@heroku_client.should_receive(:create).with('awesomeapp', {:stack => 'bamboo-ree-1.8.7'})
|
140
134
|
subject.create
|
141
135
|
end
|
142
136
|
it "uses the default stack if none is given" do
|
143
137
|
subject = HerokuSan::Stage.new('production', {"app" => "awesomeapp"})
|
144
|
-
|
138
|
+
@heroku_client.should_receive(:create).with('awesomeapp')
|
145
139
|
subject.create
|
146
140
|
end
|
141
|
+
it "sends a nil app name if none is given (Heroku will generate one)" do
|
142
|
+
subject = HerokuSan::Stage.new('production', {"app" => nil})
|
143
|
+
@heroku_client.should_receive(:create).with(nil).and_return('warm-ocean-9218')
|
144
|
+
subject.create.should == 'warm-ocean-9218'
|
145
|
+
end
|
147
146
|
end
|
148
147
|
|
149
148
|
describe "#sharing_add" do
|
@@ -161,24 +160,16 @@ EOT
|
|
161
160
|
end
|
162
161
|
|
163
162
|
describe "#long_config" do
|
164
|
-
it "
|
165
|
-
|
166
|
-
|
167
|
-
BUNDLE_WITHOUT => development:test
|
168
|
-
DATABASE_URL => postgres://thnodhxrzn:T0-UwxLyFgXcnBSHmyhv@ec2-50-19-216-194.compute-1.amazonaws.com/thnodhxrzn
|
169
|
-
LANG => en_US.UTF-8
|
170
|
-
RACK_ENV => production
|
171
|
-
SHARED_DATABASE_URL => postgres://thnodhxrzn:T0-UwxLyFgXcnBSHmyhv@ec2-50-19-216-194.compute-1.amazonaws.com/thnodhxrzn
|
172
|
-
EOT
|
173
|
-
}
|
174
|
-
subject.long_config
|
163
|
+
it "returns the remote config" do
|
164
|
+
@heroku_client.should_receive(:config_vars).with('awesomeapp') { {'A' => 'one', 'B' => 'two'} }
|
165
|
+
subject.long_config.should == { 'A' => 'one', 'B' => 'two' }
|
175
166
|
end
|
176
167
|
end
|
177
168
|
|
178
169
|
describe "#restart" do
|
179
170
|
it "restarts an app" do
|
180
|
-
|
181
|
-
subject.restart
|
171
|
+
@heroku_client.should_receive(:ps_restart).with('awesomeapp').and_return "restarted"
|
172
|
+
subject.restart.should == 'restarted'
|
182
173
|
end
|
183
174
|
end
|
184
175
|
|
@@ -196,16 +187,11 @@ EOT
|
|
196
187
|
describe "#push_config" do
|
197
188
|
it "updates the configuration settings on Heroku" do
|
198
189
|
subject = HerokuSan::Stage.new('test', {"app" => "awesomeapp", "config" => {FOO: 'bar', DOG: 'emu'}})
|
199
|
-
|
200
|
-
subject.push_config
|
201
|
-
end
|
202
|
-
it "properly escapes variables" do
|
203
|
-
subject = HerokuSan::Stage.new('test', {"app" => "awesomeapp", "config" => {FOO: ' bar\emu bat zebra '}})
|
204
|
-
subject.should_receive(:sh).with("heroku config:add FOO=#{Shellwords.escape(' bar\emu bat zebra ')} --app awesomeapp")
|
190
|
+
@heroku_client.should_receive(:add_config_vars).with('awesomeapp', {:FOO => 'bar', :DOG => 'emu'}).and_return("{}")
|
205
191
|
subject.push_config
|
206
192
|
end
|
207
193
|
it "pushes the options hash" do
|
208
|
-
|
194
|
+
@heroku_client.should_receive(:add_config_vars).with('awesomeapp', {:RACK_ENV => 'magic'}).and_return("{}")
|
209
195
|
subject.push_config(RACK_ENV: 'magic')
|
210
196
|
end
|
211
197
|
end
|
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: 2.1.
|
4
|
+
version: 2.1.1
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -12,22 +12,22 @@ authors:
|
|
12
12
|
autorequire:
|
13
13
|
bindir: bin
|
14
14
|
cert_chain: []
|
15
|
-
date: 2012-03-
|
15
|
+
date: 2012-03-21 00:00:00.000000000Z
|
16
16
|
dependencies:
|
17
17
|
- !ruby/object:Gem::Dependency
|
18
18
|
name: rails
|
19
|
-
requirement: &
|
19
|
+
requirement: &2156274700 !ruby/object:Gem::Requirement
|
20
20
|
none: false
|
21
21
|
requirements:
|
22
22
|
- - ! '>='
|
23
23
|
- !ruby/object:Gem::Version
|
24
24
|
version: '2'
|
25
|
-
type: :
|
25
|
+
type: :development
|
26
26
|
prerelease: false
|
27
|
-
version_requirements: *
|
27
|
+
version_requirements: *2156274700
|
28
28
|
- !ruby/object:Gem::Dependency
|
29
29
|
name: heroku
|
30
|
-
requirement: &
|
30
|
+
requirement: &2156273500 !ruby/object:Gem::Requirement
|
31
31
|
none: false
|
32
32
|
requirements:
|
33
33
|
- - ! '>='
|
@@ -35,10 +35,10 @@ dependencies:
|
|
35
35
|
version: '2'
|
36
36
|
type: :runtime
|
37
37
|
prerelease: false
|
38
|
-
version_requirements: *
|
38
|
+
version_requirements: *2156273500
|
39
39
|
- !ruby/object:Gem::Dependency
|
40
40
|
name: rake
|
41
|
-
requirement: &
|
41
|
+
requirement: &2156272240 !ruby/object:Gem::Requirement
|
42
42
|
none: false
|
43
43
|
requirements:
|
44
44
|
- - ! '>='
|
@@ -46,10 +46,10 @@ dependencies:
|
|
46
46
|
version: '0'
|
47
47
|
type: :runtime
|
48
48
|
prerelease: false
|
49
|
-
version_requirements: *
|
49
|
+
version_requirements: *2156272240
|
50
50
|
- !ruby/object:Gem::Dependency
|
51
51
|
name: aruba
|
52
|
-
requirement: &
|
52
|
+
requirement: &2156270800 !ruby/object:Gem::Requirement
|
53
53
|
none: false
|
54
54
|
requirements:
|
55
55
|
- - ! '>='
|
@@ -57,10 +57,10 @@ dependencies:
|
|
57
57
|
version: '0'
|
58
58
|
type: :development
|
59
59
|
prerelease: false
|
60
|
-
version_requirements: *
|
60
|
+
version_requirements: *2156270800
|
61
61
|
- !ruby/object:Gem::Dependency
|
62
62
|
name: cucumber
|
63
|
-
requirement: &
|
63
|
+
requirement: &2156269420 !ruby/object:Gem::Requirement
|
64
64
|
none: false
|
65
65
|
requirements:
|
66
66
|
- - ! '>='
|
@@ -68,10 +68,10 @@ dependencies:
|
|
68
68
|
version: '0'
|
69
69
|
type: :development
|
70
70
|
prerelease: false
|
71
|
-
version_requirements: *
|
71
|
+
version_requirements: *2156269420
|
72
72
|
- !ruby/object:Gem::Dependency
|
73
73
|
name: rake
|
74
|
-
requirement: &
|
74
|
+
requirement: &2156268140 !ruby/object:Gem::Requirement
|
75
75
|
none: false
|
76
76
|
requirements:
|
77
77
|
- - ! '>='
|
@@ -79,18 +79,18 @@ dependencies:
|
|
79
79
|
version: '0'
|
80
80
|
type: :development
|
81
81
|
prerelease: false
|
82
|
-
version_requirements: *
|
82
|
+
version_requirements: *2156268140
|
83
83
|
- !ruby/object:Gem::Dependency
|
84
84
|
name: bundler
|
85
|
-
requirement: &
|
85
|
+
requirement: &2156263700 !ruby/object:Gem::Requirement
|
86
86
|
none: false
|
87
87
|
requirements:
|
88
88
|
- - ~>
|
89
89
|
- !ruby/object:Gem::Version
|
90
|
-
version: '1.
|
90
|
+
version: '1.1'
|
91
91
|
type: :development
|
92
92
|
prerelease: false
|
93
|
-
version_requirements: *
|
93
|
+
version_requirements: *2156263700
|
94
94
|
description: Manage multiple Heroku instances/apps for a single Rails app using Rake
|
95
95
|
email: elijah.miller@gmail.com
|
96
96
|
executables: []
|
@@ -99,7 +99,6 @@ extra_rdoc_files:
|
|
99
99
|
- README.rdoc
|
100
100
|
files:
|
101
101
|
- .gitignore
|
102
|
-
- .gitmodules
|
103
102
|
- .rvmrc
|
104
103
|
- CHANGELOG.md
|
105
104
|
- Gemfile
|
@@ -113,6 +112,7 @@ files:
|
|
113
112
|
- features/config.feature
|
114
113
|
- features/extended-config.feature
|
115
114
|
- features/remote.feature
|
115
|
+
- features/step_definitions/remote_steps.rb
|
116
116
|
- features/support/env.rb
|
117
117
|
- heroku_san.gemspec
|
118
118
|
- lib/git.rb
|
@@ -160,6 +160,7 @@ test_files:
|
|
160
160
|
- features/config.feature
|
161
161
|
- features/extended-config.feature
|
162
162
|
- features/remote.feature
|
163
|
+
- features/step_definitions/remote_steps.rb
|
163
164
|
- features/support/env.rb
|
164
165
|
- spec/fixtures/example.yml
|
165
166
|
- spec/fixtures/extended_config.yml
|
data/.gitmodules
DELETED