kumade 0.0.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/.gitignore +7 -0
- data/.rspec +1 -0
- data/.rvmrc +1 -0
- data/Gemfile +4 -0
- data/Rakefile +11 -0
- data/features/deploying.feature +23 -0
- data/features/loading_tasks.feature +23 -0
- data/features/step_definitions/stub_steps.rb +10 -0
- data/features/step_definitions/task_steps.rb +15 -0
- data/features/support/env.rb +5 -0
- data/features/support/insert_into_rakefile.rb +15 -0
- data/features/support/require_kumade.rb +18 -0
- data/kumade.gemspec +27 -0
- data/lib/kumade.rb +32 -0
- data/lib/kumade/deployer.rb +153 -0
- data/lib/kumade/tasks/deploy.rake +16 -0
- data/lib/kumade/version.rb +3 -0
- data/spec/deployer_spec.rb +504 -0
- data/spec/kumade_spec.rb +52 -0
- data/spec/spec_helper.rb +8 -0
- metadata +143 -0
data/.gitignore
ADDED
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--color
|
data/.rvmrc
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
rvm 1.9.2@kumade
|
data/Gemfile
ADDED
data/Rakefile
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
require 'bundler'
|
2
|
+
Bundler::GemHelper.install_tasks
|
3
|
+
|
4
|
+
require 'cucumber/rake/task'
|
5
|
+
require 'rspec/core/rake_task'
|
6
|
+
|
7
|
+
RSpec::Core::RakeTask.new(:spec)
|
8
|
+
Cucumber::Rake::Task.new(:cucumber)
|
9
|
+
|
10
|
+
desc "Run specs and cucumber features"
|
11
|
+
task :default => [:spec, :cucumber]
|
@@ -0,0 +1,23 @@
|
|
1
|
+
Feature: Deploying to Heroku
|
2
|
+
In order to easily use Heroku's services
|
3
|
+
As a user
|
4
|
+
I want to deploy to Heroku
|
5
|
+
|
6
|
+
Background:
|
7
|
+
Given a directory named "deployer"
|
8
|
+
And I cd to "deployer"
|
9
|
+
And I stub out the "staging" deploy method
|
10
|
+
And I stub out the "production" deploy method
|
11
|
+
And I load the tasks
|
12
|
+
|
13
|
+
Scenario: deploy task is an alias for deploy:staging
|
14
|
+
When I successfully run the rake task "deploy"
|
15
|
+
Then the output should contain "Force pushed master -> staging"
|
16
|
+
|
17
|
+
Scenario: Deploying to staging
|
18
|
+
When I successfully run the rake task "deploy:staging"
|
19
|
+
Then the output should contain "Force pushed master -> staging"
|
20
|
+
|
21
|
+
Scenario: Deploying to production
|
22
|
+
When I successfully run the rake task "deploy:production"
|
23
|
+
Then the output should contain "Force pushed master -> production"
|
@@ -0,0 +1,23 @@
|
|
1
|
+
Feature: Loading tasks
|
2
|
+
In order to use Kumade
|
3
|
+
As a user
|
4
|
+
I want to load Rake tasks
|
5
|
+
|
6
|
+
Scenario: Load Rake tasks
|
7
|
+
Given a directory named "taskloader"
|
8
|
+
When I cd to "taskloader"
|
9
|
+
And I write to "Gemfile" with:
|
10
|
+
"""
|
11
|
+
source "http://rubygems.org"
|
12
|
+
gem "rake", "0.8.7"
|
13
|
+
gem "kumade"
|
14
|
+
"""
|
15
|
+
And I write to "Rakefile" with:
|
16
|
+
"""
|
17
|
+
require 'kumade'
|
18
|
+
Kumade.load_tasks
|
19
|
+
"""
|
20
|
+
And I run `rake -T`
|
21
|
+
Then the output should contain "deploy"
|
22
|
+
And the output should contain "deploy:staging"
|
23
|
+
And the output should contain "deploy:production"
|
@@ -0,0 +1,15 @@
|
|
1
|
+
When /^I load the tasks$/ do
|
2
|
+
prepend_require_kumade_to_rakefile!
|
3
|
+
|
4
|
+
steps %{
|
5
|
+
When I append to "Rakefile" with:
|
6
|
+
"""
|
7
|
+
|
8
|
+
Kumade.load_tasks
|
9
|
+
"""
|
10
|
+
}
|
11
|
+
end
|
12
|
+
|
13
|
+
When /^I successfully run the rake task "([^"]*)"$/ do |task_name|
|
14
|
+
When %{I successfully run `bundle exec rake #{task_name}`}
|
15
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module InsertIntoRakefileHelpers
|
2
|
+
def insert_after_tasks_are_loaded(new_content)
|
3
|
+
rakefile_path = File.join(current_dir, 'Rakefile')
|
4
|
+
current_rakefile_content = File.readlines(rakefile_path)
|
5
|
+
load_tasks_index = current_rakefile_content.index("Kumade.load_tasks")
|
6
|
+
|
7
|
+
new_rakefile_content = current_rakefile_content[0..load_tasks_index].join +
|
8
|
+
"\n" + new_content +
|
9
|
+
current_rakefile_content[load_tasks_index..-1].join
|
10
|
+
When %{I write to "Rakefile" with:}, new_rakefile_content
|
11
|
+
When %{I commit everything in the current directory to git}
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
World(InsertIntoRakefileHelpers)
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
|
3
|
+
module RequireKumade
|
4
|
+
def prepend_require_kumade_to_rakefile!
|
5
|
+
rakefile_path = File.join(current_dir, 'Rakefile')
|
6
|
+
if File.exist?(rakefile_path)
|
7
|
+
unless `head -n1 #{rakefile_path}`.include?("require 'kumade'")
|
8
|
+
current_rakefile_content = File.read(rakefile_path)
|
9
|
+
new_rakefile_content = "require 'kumade'\n" + current_rakefile_content
|
10
|
+
When %{I write to "Rakefile" with:}, new_rakefile_content
|
11
|
+
end
|
12
|
+
else
|
13
|
+
Given %{an empty file named "Rakefile"}
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
World(RequireKumade)
|
data/kumade.gemspec
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "kumade/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "kumade"
|
7
|
+
s.version = Kumade::VERSION
|
8
|
+
s.platform = Gem::Platform::RUBY
|
9
|
+
s.authors = ["Gabe Berke-Williams"]
|
10
|
+
s.email = ["gabe@thoughtbot.com"]
|
11
|
+
s.homepage = ""
|
12
|
+
s.summary = %q{Simple rake tasks for deploying to Heroku}
|
13
|
+
s.description = s.summary
|
14
|
+
|
15
|
+
s.files = `git ls-files`.split("\n")
|
16
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
17
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
18
|
+
s.require_paths = ["lib"]
|
19
|
+
|
20
|
+
s.add_dependency('heroku')
|
21
|
+
|
22
|
+
s.add_development_dependency('rake', '~> 0.8.7')
|
23
|
+
s.add_development_dependency('rspec', '~> 2.6.0')
|
24
|
+
s.add_development_dependency('cucumber', '~> 1.0.2')
|
25
|
+
s.add_development_dependency('aruba', '~> 0.4.3')
|
26
|
+
s.add_development_dependency('jammit', '~> 0.6.3')
|
27
|
+
end
|
data/lib/kumade.rb
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'kumade/deployer'
|
2
|
+
|
3
|
+
class Kumade
|
4
|
+
def self.load_tasks
|
5
|
+
deployer.load_tasks
|
6
|
+
end
|
7
|
+
|
8
|
+
class << self
|
9
|
+
attr_writer :staging, :production
|
10
|
+
attr_accessor :staging_app, :production_app
|
11
|
+
|
12
|
+
def reset!
|
13
|
+
@staging = nil
|
14
|
+
@production = nil
|
15
|
+
|
16
|
+
@staging_app = nil
|
17
|
+
@production_app = nil
|
18
|
+
end
|
19
|
+
|
20
|
+
def staging
|
21
|
+
@staging ||= 'staging'
|
22
|
+
end
|
23
|
+
|
24
|
+
def production
|
25
|
+
@production ||= 'production'
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.deployer
|
30
|
+
@deployer ||= Deployer.new
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,153 @@
|
|
1
|
+
class Kumade
|
2
|
+
class Deployer
|
3
|
+
def load_tasks
|
4
|
+
load 'kumade/tasks/deploy.rake'
|
5
|
+
end
|
6
|
+
|
7
|
+
def pre_deploy
|
8
|
+
ensure_clean_git
|
9
|
+
ensure_rake_passes
|
10
|
+
package_assets
|
11
|
+
git_push('origin')
|
12
|
+
end
|
13
|
+
|
14
|
+
def deploy_to_staging
|
15
|
+
pre_deploy
|
16
|
+
git_force_push(Kumade.staging)
|
17
|
+
heroku_migrate(:staging)
|
18
|
+
end
|
19
|
+
|
20
|
+
def deploy_to_production
|
21
|
+
pre_deploy
|
22
|
+
git_force_push(Kumade.production)
|
23
|
+
heroku_migrate(:production)
|
24
|
+
end
|
25
|
+
|
26
|
+
def git_push(remote)
|
27
|
+
run_or_raise("git push #{remote} master",
|
28
|
+
"Failed to push master -> #{remote}")
|
29
|
+
announce "Pushed master -> #{remote}"
|
30
|
+
end
|
31
|
+
|
32
|
+
def git_force_push(remote)
|
33
|
+
run_or_raise("git push -f #{remote} master",
|
34
|
+
"Failed to force push master -> #{remote}")
|
35
|
+
announce "Force pushed master -> #{remote}"
|
36
|
+
end
|
37
|
+
|
38
|
+
def heroku_migrate(environment)
|
39
|
+
app = if environment == :staging
|
40
|
+
Kumade.staging_app
|
41
|
+
elsif environment == :production
|
42
|
+
Kumade.production_app
|
43
|
+
end
|
44
|
+
|
45
|
+
run("bundle exec heroku rake db:migrate --app #{app}")
|
46
|
+
end
|
47
|
+
|
48
|
+
def ensure_clean_git
|
49
|
+
if git_dirty?
|
50
|
+
raise "Cannot deploy: repo is not clean."
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def ensure_rake_passes
|
55
|
+
if default_task_exists?
|
56
|
+
raise "Cannot deploy: tests did not pass" unless rake_succeeded?
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def package_assets
|
61
|
+
package_with_jammit if jammit_installed?
|
62
|
+
package_with_more if more_installed?
|
63
|
+
end
|
64
|
+
|
65
|
+
def package_with_jammit
|
66
|
+
Jammit.package!
|
67
|
+
announce("Successfully packaged with Jammit")
|
68
|
+
if git_dirty?
|
69
|
+
git_add_and_commit_all_assets_in(absolute_assets_path)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def package_with_more
|
74
|
+
Rake::Task['more:generate'].invoke
|
75
|
+
if git_dirty?
|
76
|
+
announce("Successfully packaged with More")
|
77
|
+
|
78
|
+
git_add_and_commit_all_assets_in(more_assets_path)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
def git_add_and_commit_all_assets_in(dir)
|
83
|
+
announce "Committing assets"
|
84
|
+
run_or_raise("git add #{dir} && git commit -m 'Assets'",
|
85
|
+
"Cannot deploy: couldn't commit assets")
|
86
|
+
end
|
87
|
+
|
88
|
+
def git_add_and_commit_all_more_assets
|
89
|
+
announce "Committing assets"
|
90
|
+
run_or_raise("git add #{more_assets_path} && git commit -m 'Assets'",
|
91
|
+
"Cannot deploy: couldn't commit assets")
|
92
|
+
end
|
93
|
+
|
94
|
+
def absolute_assets_path
|
95
|
+
File.join(Jammit::PUBLIC_ROOT, Jammit.package_path)
|
96
|
+
end
|
97
|
+
|
98
|
+
def more_assets_path
|
99
|
+
File.join('public', ::Less::More.destination_path)
|
100
|
+
end
|
101
|
+
|
102
|
+
def jammit_installed?
|
103
|
+
@jammit_installed ||=
|
104
|
+
(defined?(Jammit) ||
|
105
|
+
begin
|
106
|
+
require 'jammit'
|
107
|
+
rescue LoadError
|
108
|
+
false
|
109
|
+
end)
|
110
|
+
end
|
111
|
+
|
112
|
+
def more_installed?
|
113
|
+
@more_installed ||=
|
114
|
+
(defined?(Less::More) ||
|
115
|
+
begin
|
116
|
+
require 'less/more'
|
117
|
+
rescue LoadError
|
118
|
+
false
|
119
|
+
end)
|
120
|
+
end
|
121
|
+
|
122
|
+
def default_task_exists?
|
123
|
+
Rake::Task.task_defined?('default')
|
124
|
+
end
|
125
|
+
|
126
|
+
def rake_succeeded?
|
127
|
+
begin
|
128
|
+
Rake::Task[:default].invoke
|
129
|
+
rescue
|
130
|
+
false
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
def git_dirty?
|
135
|
+
git_changed = `git status --short 2> /dev/null | tail -n1`
|
136
|
+
dirty = git_changed.size > 0
|
137
|
+
end
|
138
|
+
|
139
|
+
def run(command)
|
140
|
+
announce "+ #{command}"
|
141
|
+
announce "- #{system command}"
|
142
|
+
$?.success?
|
143
|
+
end
|
144
|
+
|
145
|
+
def run_or_raise(command, error_message)
|
146
|
+
raise(error_message) unless run(command)
|
147
|
+
end
|
148
|
+
|
149
|
+
def announce(message)
|
150
|
+
puts message
|
151
|
+
end
|
152
|
+
end
|
153
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
class Kumade
|
2
|
+
desc "Alias for deploy:staging"
|
3
|
+
task :deploy => 'deploy:staging'
|
4
|
+
|
5
|
+
namespace :deploy do
|
6
|
+
desc "Deploy to Heroku staging"
|
7
|
+
task :staging do
|
8
|
+
deployer.deploy_to_staging
|
9
|
+
end
|
10
|
+
|
11
|
+
desc "Deploy to Heroku production"
|
12
|
+
task :production do
|
13
|
+
deployer.deploy_to_production
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,504 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'jammit'
|
3
|
+
|
4
|
+
class Kumade
|
5
|
+
describe Deployer, "#load_tasks" do
|
6
|
+
it "loads the deploy tasks" do
|
7
|
+
Rake.application.tasks.should be_empty
|
8
|
+
subject.load_tasks
|
9
|
+
task_names = Rake.application.tasks.map{|task| task.name }
|
10
|
+
%w(deploy deploy:production deploy:staging).each do |expected_name|
|
11
|
+
task_names.should include expected_name
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
describe Deployer, "#pre_deploy" do
|
17
|
+
it "calls the correct methods in order" do
|
18
|
+
%w(
|
19
|
+
ensure_clean_git
|
20
|
+
ensure_rake_passes
|
21
|
+
package_assets
|
22
|
+
git_push
|
23
|
+
).each do |task|
|
24
|
+
subject.should_receive(task).ordered.and_return(true)
|
25
|
+
end
|
26
|
+
|
27
|
+
subject.pre_deploy
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
describe Deployer, "#deploy_to_staging" do
|
32
|
+
it "calls the correct methods in order" do
|
33
|
+
subject.stub(:run => true)
|
34
|
+
|
35
|
+
subject.should_receive(:pre_deploy).
|
36
|
+
ordered.
|
37
|
+
and_return(true)
|
38
|
+
|
39
|
+
subject.should_receive(:git_force_push).
|
40
|
+
ordered.
|
41
|
+
with('staging').
|
42
|
+
and_return(true)
|
43
|
+
|
44
|
+
subject.should_receive(:heroku_migrate).
|
45
|
+
ordered.
|
46
|
+
with(:staging)
|
47
|
+
|
48
|
+
subject.deploy_to_staging
|
49
|
+
end
|
50
|
+
|
51
|
+
it "deploys to Kumade.staging" do
|
52
|
+
subject.stub(:pre_deploy => true,
|
53
|
+
:run => true)
|
54
|
+
Kumade.staging = 'orange'
|
55
|
+
|
56
|
+
subject.should_receive(:git_force_push).with('orange')
|
57
|
+
|
58
|
+
subject.deploy_to_staging
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
describe Deployer, "#deploy_to_production" do
|
63
|
+
it "calls the correct methods in order" do
|
64
|
+
subject.stub(:run => true)
|
65
|
+
|
66
|
+
subject.should_receive(:pre_deploy).
|
67
|
+
ordered.
|
68
|
+
and_return(true)
|
69
|
+
|
70
|
+
subject.should_receive(:git_force_push).
|
71
|
+
ordered.
|
72
|
+
with('production').
|
73
|
+
and_return(true)
|
74
|
+
|
75
|
+
subject.should_receive(:heroku_migrate).
|
76
|
+
ordered.
|
77
|
+
with(:production)
|
78
|
+
|
79
|
+
subject.deploy_to_production
|
80
|
+
end
|
81
|
+
|
82
|
+
it "deploys to Kumade.production" do
|
83
|
+
subject.stub(:pre_deploy => true,
|
84
|
+
:run => true)
|
85
|
+
Kumade.production = 'orange'
|
86
|
+
|
87
|
+
subject.should_receive(:git_force_push).with('orange')
|
88
|
+
|
89
|
+
subject.deploy_to_production
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
describe Deployer, "#git_push" do
|
94
|
+
let(:remote){ 'origin' }
|
95
|
+
|
96
|
+
before { subject.stub(:announce) }
|
97
|
+
|
98
|
+
it "calls `git push`" do
|
99
|
+
subject.should_receive(:run).
|
100
|
+
with("git push #{remote} master").
|
101
|
+
and_return(true)
|
102
|
+
subject.git_push(remote)
|
103
|
+
end
|
104
|
+
|
105
|
+
context "when `git push` fails" do
|
106
|
+
before do
|
107
|
+
subject.stub(:run).and_return(false)
|
108
|
+
end
|
109
|
+
|
110
|
+
it "raises an error" do
|
111
|
+
lambda do
|
112
|
+
subject.git_push(remote)
|
113
|
+
end.should raise_error("Failed to push master -> #{remote}")
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
context "when `git push` succeeds" do
|
118
|
+
before do
|
119
|
+
subject.stub(:run).and_return(true)
|
120
|
+
end
|
121
|
+
|
122
|
+
it "does not raise an error" do
|
123
|
+
subject.stub(:announce).and_return(false)
|
124
|
+
lambda do
|
125
|
+
subject.git_push(remote)
|
126
|
+
end.should_not raise_error
|
127
|
+
end
|
128
|
+
|
129
|
+
it "prints the correct message" do
|
130
|
+
subject.should_receive(:announce).
|
131
|
+
with("Pushed master -> #{remote}")
|
132
|
+
|
133
|
+
subject.git_push(remote)
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
describe Deployer, "#git_force_push" do
|
139
|
+
let(:remote){ 'origin' }
|
140
|
+
before { subject.stub(:announce) }
|
141
|
+
|
142
|
+
it "calls `git push -f`" do
|
143
|
+
subject.should_receive(:run).
|
144
|
+
with("git push -f #{remote} master").
|
145
|
+
and_return(true)
|
146
|
+
subject.git_force_push(remote)
|
147
|
+
end
|
148
|
+
|
149
|
+
context "when `git push -f` fails" do
|
150
|
+
before do
|
151
|
+
subject.stub(:run).and_return(false)
|
152
|
+
end
|
153
|
+
|
154
|
+
it "raises an error" do
|
155
|
+
lambda do
|
156
|
+
subject.git_force_push(remote)
|
157
|
+
end.should raise_error("Failed to force push master -> #{remote}")
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
context "when `git push -f` succeeds" do
|
162
|
+
before do
|
163
|
+
subject.stub(:run).and_return(true)
|
164
|
+
end
|
165
|
+
|
166
|
+
it "does not raise an error" do
|
167
|
+
lambda do
|
168
|
+
subject.git_force_push(remote)
|
169
|
+
end.should_not raise_error
|
170
|
+
end
|
171
|
+
|
172
|
+
it "prints the correct message" do
|
173
|
+
subject.should_receive(:announce).
|
174
|
+
with("Force pushed master -> #{remote}")
|
175
|
+
|
176
|
+
subject.git_force_push(remote)
|
177
|
+
end
|
178
|
+
end
|
179
|
+
end
|
180
|
+
|
181
|
+
describe Deployer, "#ensure_clean_git" do
|
182
|
+
context "when git is dirty" do
|
183
|
+
before { subject.stub(:git_dirty?).and_return(true) }
|
184
|
+
|
185
|
+
it "raises an error" do
|
186
|
+
lambda do
|
187
|
+
subject.ensure_clean_git
|
188
|
+
end.should raise_error("Cannot deploy: repo is not clean.")
|
189
|
+
end
|
190
|
+
end
|
191
|
+
|
192
|
+
context "when git is clean" do
|
193
|
+
before { subject.stub(:git_dirty?).and_return(false) }
|
194
|
+
|
195
|
+
it "does not raise an error" do
|
196
|
+
lambda do
|
197
|
+
subject.ensure_clean_git
|
198
|
+
end.should_not raise_error
|
199
|
+
end
|
200
|
+
end
|
201
|
+
end
|
202
|
+
|
203
|
+
describe Deployer, "#ensure_rake_passes" do
|
204
|
+
context "with a default task" do
|
205
|
+
before do
|
206
|
+
subject.stub(:default_task_exists?).and_return(true)
|
207
|
+
end
|
208
|
+
|
209
|
+
it "does not raise an error if the default task succeeds" do
|
210
|
+
subject.stub(:rake_succeeded?).and_return(true)
|
211
|
+
lambda do
|
212
|
+
subject.ensure_rake_passes
|
213
|
+
end.should_not raise_error
|
214
|
+
end
|
215
|
+
|
216
|
+
it "raises an error if the default task failse" do
|
217
|
+
subject.stub(:rake_succeeded?).and_return(false)
|
218
|
+
lambda do
|
219
|
+
subject.ensure_rake_passes
|
220
|
+
end.should raise_error("Cannot deploy: tests did not pass")
|
221
|
+
end
|
222
|
+
end
|
223
|
+
end
|
224
|
+
|
225
|
+
describe Deployer, "#default_task_exists?" do
|
226
|
+
before { Rake::Task.clear }
|
227
|
+
|
228
|
+
it "returns true if a default task does exist" do
|
229
|
+
Rake::Task.define_task(:default){}
|
230
|
+
|
231
|
+
subject.default_task_exists?.should be_true
|
232
|
+
end
|
233
|
+
|
234
|
+
it "returns false if a default task does not exist" do
|
235
|
+
subject.default_task_exists?.should be_false
|
236
|
+
end
|
237
|
+
end
|
238
|
+
|
239
|
+
describe Deployer, "#rake_succeeded?" do
|
240
|
+
before { Rake::Task.clear }
|
241
|
+
|
242
|
+
it "returns true if the default task passed" do
|
243
|
+
Rake::Task.define_task(:default){}
|
244
|
+
|
245
|
+
subject.rake_succeeded?.should be_true
|
246
|
+
end
|
247
|
+
|
248
|
+
it "returns false if the default task failed" do
|
249
|
+
Rake::Task.define_task(:default){ fail "blerg" }
|
250
|
+
subject.rake_succeeded?.should be_false
|
251
|
+
end
|
252
|
+
end
|
253
|
+
|
254
|
+
describe Deployer, "#package_assets" do
|
255
|
+
context "with Jammit installed" do
|
256
|
+
it "calls package_with_jammit" do
|
257
|
+
subject.should_receive(:package_with_jammit)
|
258
|
+
subject.package_assets
|
259
|
+
end
|
260
|
+
end
|
261
|
+
|
262
|
+
context "with Jammit not installed" do
|
263
|
+
before { subject.stub(:jammit_installed? => false) }
|
264
|
+
it "does not call package_with_jammit" do
|
265
|
+
subject.should_receive(:package_with_jammit).exactly(0).times
|
266
|
+
subject.package_assets
|
267
|
+
end
|
268
|
+
end
|
269
|
+
|
270
|
+
context "with More installed" do
|
271
|
+
before do
|
272
|
+
subject.stub(:jammit_installed? => false)
|
273
|
+
subject.stub(:more_installed? => true)
|
274
|
+
end
|
275
|
+
|
276
|
+
it "calls package_with_more" do
|
277
|
+
subject.should_receive(:package_with_more)
|
278
|
+
subject.package_assets
|
279
|
+
end
|
280
|
+
end
|
281
|
+
|
282
|
+
context "with More not installed" do
|
283
|
+
before do
|
284
|
+
subject.stub(:jammit_installed? => false)
|
285
|
+
subject.stub(:more_installed? => false)
|
286
|
+
end
|
287
|
+
|
288
|
+
it "does not call package_with_more" do
|
289
|
+
subject.should_receive(:package_with_more).exactly(0).times
|
290
|
+
subject.package_assets
|
291
|
+
end
|
292
|
+
end
|
293
|
+
end
|
294
|
+
|
295
|
+
describe Deployer, "#package_with_jammit" do
|
296
|
+
before do
|
297
|
+
subject.stub(:git_add_and_commit_all_assets_in)
|
298
|
+
subject.stub(:announce)
|
299
|
+
Jammit.stub(:package!)
|
300
|
+
end
|
301
|
+
|
302
|
+
it "calls Jammit.package!" do
|
303
|
+
Jammit.should_receive(:package!).once
|
304
|
+
subject.package_with_jammit
|
305
|
+
end
|
306
|
+
|
307
|
+
it "prints the correct message if packaging succeeded" do
|
308
|
+
subject.should_receive(:announce).with("Successfully packaged with Jammit")
|
309
|
+
|
310
|
+
subject.package_with_jammit
|
311
|
+
end
|
312
|
+
|
313
|
+
it "raises an error if packaging failed" do
|
314
|
+
Jammit.stub(:package!) do
|
315
|
+
raise Jammit::MissingConfiguration.new("random Jammit error")
|
316
|
+
end
|
317
|
+
|
318
|
+
lambda do
|
319
|
+
subject.package_with_jammit
|
320
|
+
end.should raise_error(Jammit::MissingConfiguration)
|
321
|
+
end
|
322
|
+
|
323
|
+
it "calls git_add_and_commit_all_assets_in if assets were added" do
|
324
|
+
subject.stub(:git_dirty?).and_return(true)
|
325
|
+
subject.stub(:absolute_assets_path => 'blerg')
|
326
|
+
subject.should_receive(:git_add_and_commit_all_assets_in).
|
327
|
+
with('blerg').
|
328
|
+
and_return(true)
|
329
|
+
|
330
|
+
subject.package_with_jammit
|
331
|
+
end
|
332
|
+
|
333
|
+
it "does not call git_add_and_commit_all_jammit_assets if no assets were added" do
|
334
|
+
subject.stub(:git_dirty?).and_return(false)
|
335
|
+
subject.should_receive(:git_add_and_commit_all_assets_in).exactly(0).times
|
336
|
+
|
337
|
+
subject.package_with_jammit
|
338
|
+
end
|
339
|
+
end
|
340
|
+
|
341
|
+
describe Deployer, "#package_with_more" do
|
342
|
+
before do
|
343
|
+
subject.stub(:git_add_and_commit_all_assets_in).and_return(true)
|
344
|
+
subject.stub(:announce)
|
345
|
+
Rake::Task.clear
|
346
|
+
Rake::Task.define_task('more:generate'){}
|
347
|
+
module ::Less
|
348
|
+
class More
|
349
|
+
def self.destination_path
|
350
|
+
'blerg'
|
351
|
+
end
|
352
|
+
end
|
353
|
+
end
|
354
|
+
end
|
355
|
+
|
356
|
+
it "calls the more:generate task" do
|
357
|
+
Rake::Task.clear
|
358
|
+
more_generate_task = Rake::Task.define_task('more:generate'){}
|
359
|
+
more_generate_task.should_receive(:invoke).once
|
360
|
+
subject.package_with_more
|
361
|
+
end
|
362
|
+
|
363
|
+
it "prints the correct message if packaging succeeded" do
|
364
|
+
subject.should_receive(:announce).with("Successfully packaged with More")
|
365
|
+
|
366
|
+
subject.package_with_more
|
367
|
+
end
|
368
|
+
|
369
|
+
it "prints no message if packaging was a no-op" do
|
370
|
+
subject.stub(:git_dirty? => false)
|
371
|
+
subject.should_receive(:announce).exactly(0).times
|
372
|
+
|
373
|
+
subject.package_with_more
|
374
|
+
end
|
375
|
+
|
376
|
+
it "raises an error if packaging failed" do
|
377
|
+
Rake::Task.clear
|
378
|
+
Rake::Task.define_task('more:generate') do
|
379
|
+
fail "blerg"
|
380
|
+
end
|
381
|
+
|
382
|
+
lambda do
|
383
|
+
subject.package_with_more
|
384
|
+
end.should raise_error("blerg")
|
385
|
+
end
|
386
|
+
|
387
|
+
it "calls git_add_and_commit_all_assets_in if assets were added" do
|
388
|
+
subject.stub(:git_dirty?).and_return(true)
|
389
|
+
subject.stub(:more_assets_path).and_return('blerg')
|
390
|
+
subject.should_receive(:git_add_and_commit_all_assets_in).
|
391
|
+
with('blerg').
|
392
|
+
and_return(true)
|
393
|
+
|
394
|
+
subject.package_with_more
|
395
|
+
end
|
396
|
+
|
397
|
+
it "does not call git_add_and_commit_all_more_assets if no assets were added" do
|
398
|
+
subject.stub(:git_dirty?).and_return(false)
|
399
|
+
subject.should_receive(:git_add_and_commit_all_assets_in).exactly(0).times
|
400
|
+
|
401
|
+
subject.package_with_more
|
402
|
+
end
|
403
|
+
end
|
404
|
+
|
405
|
+
describe Deployer, "#git_add_and_commit_all_assets_in" do
|
406
|
+
before do
|
407
|
+
subject.stub(:announce)
|
408
|
+
subject.stub(:run).and_return(true)
|
409
|
+
end
|
410
|
+
|
411
|
+
it "announces the correct message" do
|
412
|
+
subject.should_receive(:announce).with("Committing assets")
|
413
|
+
|
414
|
+
subject.git_add_and_commit_all_assets_in('blerg')
|
415
|
+
end
|
416
|
+
|
417
|
+
it "runs the correct commands" do
|
418
|
+
subject.should_receive(:run).
|
419
|
+
with("git add blerg && git commit -m 'Assets'")
|
420
|
+
|
421
|
+
subject.git_add_and_commit_all_assets_in('blerg')
|
422
|
+
end
|
423
|
+
|
424
|
+
it "raises an error if it could not add and commit assets" do
|
425
|
+
subject.stub(:run).and_return(false)
|
426
|
+
|
427
|
+
lambda do
|
428
|
+
subject.git_add_and_commit_all_assets_in('blerg')
|
429
|
+
end.should raise_error("Cannot deploy: couldn't commit assets")
|
430
|
+
end
|
431
|
+
end
|
432
|
+
|
433
|
+
describe Deployer, "#absolute_assets_path" do
|
434
|
+
it "returns the correct asset path" do
|
435
|
+
Jammit.stub(:package_path => 'blerg')
|
436
|
+
current_dir = File.expand_path(Dir.pwd)
|
437
|
+
subject.absolute_assets_path.should == File.join(current_dir, 'public', 'blerg')
|
438
|
+
end
|
439
|
+
end
|
440
|
+
|
441
|
+
describe Deployer, "#more_assets_path" do
|
442
|
+
it "returns the correct asset path" do
|
443
|
+
module ::Less
|
444
|
+
class More
|
445
|
+
def self.destination_path
|
446
|
+
'blerg'
|
447
|
+
end
|
448
|
+
end
|
449
|
+
end
|
450
|
+
subject.more_assets_path.should == 'public/blerg'
|
451
|
+
end
|
452
|
+
end
|
453
|
+
|
454
|
+
describe Deployer, "#jammit_installed?" do
|
455
|
+
it "returns true because it's loaded by the Gemfile" do
|
456
|
+
subject.jammit_installed?.should be_true
|
457
|
+
end
|
458
|
+
end
|
459
|
+
|
460
|
+
describe Deployer, "#more_installed?" do
|
461
|
+
before do
|
462
|
+
if defined?(Less)
|
463
|
+
Object.send(:remove_const, :Less)
|
464
|
+
end
|
465
|
+
end
|
466
|
+
|
467
|
+
it "returns false if it does not find Less::More" do
|
468
|
+
subject.more_installed?.should be_false
|
469
|
+
end
|
470
|
+
|
471
|
+
it "returns true if it finds Less::More" do
|
472
|
+
module Less
|
473
|
+
class More
|
474
|
+
end
|
475
|
+
end
|
476
|
+
subject.more_installed?.should be_true
|
477
|
+
end
|
478
|
+
end
|
479
|
+
|
480
|
+
describe Deployer, "#heroku_migrate" do
|
481
|
+
let(:staging_app) { 'staging-sushi' }
|
482
|
+
let(:production_app){ 'production-sushi' }
|
483
|
+
|
484
|
+
before do
|
485
|
+
Kumade.reset!
|
486
|
+
Kumade.staging_app = staging_app
|
487
|
+
Kumade.production_app = production_app
|
488
|
+
end
|
489
|
+
|
490
|
+
it "runs db:migrate with the correct staging app" do
|
491
|
+
subject.should_receive(:run).
|
492
|
+
with("bundle exec heroku rake db:migrate --app #{staging_app}")
|
493
|
+
|
494
|
+
subject.heroku_migrate(:staging)
|
495
|
+
end
|
496
|
+
|
497
|
+
it "runs db:migrate with the correct production app" do
|
498
|
+
subject.should_receive(:run).
|
499
|
+
with("bundle exec heroku rake db:migrate --app #{production_app}")
|
500
|
+
|
501
|
+
subject.heroku_migrate(:production)
|
502
|
+
end
|
503
|
+
end
|
504
|
+
end
|
data/spec/kumade_spec.rb
ADDED
@@ -0,0 +1,52 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Kumade, "staging remote" do
|
4
|
+
before { Kumade.reset! }
|
5
|
+
it "defaults to staging" do
|
6
|
+
Kumade.staging.should == 'staging'
|
7
|
+
end
|
8
|
+
|
9
|
+
it "can be set" do
|
10
|
+
Kumade.staging = 'orange'
|
11
|
+
Kumade.staging.should == 'orange'
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
describe Kumade, "staging app" do
|
16
|
+
before { Kumade.reset! }
|
17
|
+
|
18
|
+
it "defaults to nil" do
|
19
|
+
Kumade.staging_app.should be_nil
|
20
|
+
end
|
21
|
+
|
22
|
+
it "can be set" do
|
23
|
+
Kumade.staging_app = 'orange'
|
24
|
+
Kumade.staging_app.should == 'orange'
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
describe Kumade, "production remote" do
|
29
|
+
before { Kumade.reset! }
|
30
|
+
|
31
|
+
it "defaults to production" do
|
32
|
+
Kumade.production.should == 'production'
|
33
|
+
end
|
34
|
+
|
35
|
+
it "can be set" do
|
36
|
+
Kumade.production = 'orange'
|
37
|
+
Kumade.production.should == 'orange'
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
describe Kumade, "production app" do
|
42
|
+
before { Kumade.reset! }
|
43
|
+
|
44
|
+
it "defaults to nil" do
|
45
|
+
Kumade.production_app.should be_nil
|
46
|
+
end
|
47
|
+
|
48
|
+
it "can be set" do
|
49
|
+
Kumade.production_app = 'orange'
|
50
|
+
Kumade.production_app.should == 'orange'
|
51
|
+
end
|
52
|
+
end
|
data/spec/spec_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,143 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: kumade
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Gabe Berke-Williams
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2011-07-26 00:00:00.000000000 -04:00
|
13
|
+
default_executable:
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: heroku
|
17
|
+
requirement: &2152569700 !ruby/object:Gem::Requirement
|
18
|
+
none: false
|
19
|
+
requirements:
|
20
|
+
- - ! '>='
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: '0'
|
23
|
+
type: :runtime
|
24
|
+
prerelease: false
|
25
|
+
version_requirements: *2152569700
|
26
|
+
- !ruby/object:Gem::Dependency
|
27
|
+
name: rake
|
28
|
+
requirement: &2152569200 !ruby/object:Gem::Requirement
|
29
|
+
none: false
|
30
|
+
requirements:
|
31
|
+
- - ~>
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 0.8.7
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: *2152569200
|
37
|
+
- !ruby/object:Gem::Dependency
|
38
|
+
name: rspec
|
39
|
+
requirement: &2152568700 !ruby/object:Gem::Requirement
|
40
|
+
none: false
|
41
|
+
requirements:
|
42
|
+
- - ~>
|
43
|
+
- !ruby/object:Gem::Version
|
44
|
+
version: 2.6.0
|
45
|
+
type: :development
|
46
|
+
prerelease: false
|
47
|
+
version_requirements: *2152568700
|
48
|
+
- !ruby/object:Gem::Dependency
|
49
|
+
name: cucumber
|
50
|
+
requirement: &2152568240 !ruby/object:Gem::Requirement
|
51
|
+
none: false
|
52
|
+
requirements:
|
53
|
+
- - ~>
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
version: 1.0.2
|
56
|
+
type: :development
|
57
|
+
prerelease: false
|
58
|
+
version_requirements: *2152568240
|
59
|
+
- !ruby/object:Gem::Dependency
|
60
|
+
name: aruba
|
61
|
+
requirement: &2152567780 !ruby/object:Gem::Requirement
|
62
|
+
none: false
|
63
|
+
requirements:
|
64
|
+
- - ~>
|
65
|
+
- !ruby/object:Gem::Version
|
66
|
+
version: 0.4.3
|
67
|
+
type: :development
|
68
|
+
prerelease: false
|
69
|
+
version_requirements: *2152567780
|
70
|
+
- !ruby/object:Gem::Dependency
|
71
|
+
name: jammit
|
72
|
+
requirement: &2152567320 !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ~>
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: 0.6.3
|
78
|
+
type: :development
|
79
|
+
prerelease: false
|
80
|
+
version_requirements: *2152567320
|
81
|
+
description: Simple rake tasks for deploying to Heroku
|
82
|
+
email:
|
83
|
+
- gabe@thoughtbot.com
|
84
|
+
executables: []
|
85
|
+
extensions: []
|
86
|
+
extra_rdoc_files: []
|
87
|
+
files:
|
88
|
+
- .gitignore
|
89
|
+
- .rspec
|
90
|
+
- .rvmrc
|
91
|
+
- Gemfile
|
92
|
+
- Rakefile
|
93
|
+
- features/deploying.feature
|
94
|
+
- features/loading_tasks.feature
|
95
|
+
- features/step_definitions/stub_steps.rb
|
96
|
+
- features/step_definitions/task_steps.rb
|
97
|
+
- features/support/env.rb
|
98
|
+
- features/support/insert_into_rakefile.rb
|
99
|
+
- features/support/require_kumade.rb
|
100
|
+
- kumade.gemspec
|
101
|
+
- lib/kumade.rb
|
102
|
+
- lib/kumade/deployer.rb
|
103
|
+
- lib/kumade/tasks/deploy.rake
|
104
|
+
- lib/kumade/version.rb
|
105
|
+
- spec/deployer_spec.rb
|
106
|
+
- spec/kumade_spec.rb
|
107
|
+
- spec/spec_helper.rb
|
108
|
+
has_rdoc: true
|
109
|
+
homepage: ''
|
110
|
+
licenses: []
|
111
|
+
post_install_message:
|
112
|
+
rdoc_options: []
|
113
|
+
require_paths:
|
114
|
+
- lib
|
115
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
116
|
+
none: false
|
117
|
+
requirements:
|
118
|
+
- - ! '>='
|
119
|
+
- !ruby/object:Gem::Version
|
120
|
+
version: '0'
|
121
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
122
|
+
none: false
|
123
|
+
requirements:
|
124
|
+
- - ! '>='
|
125
|
+
- !ruby/object:Gem::Version
|
126
|
+
version: '0'
|
127
|
+
requirements: []
|
128
|
+
rubyforge_project:
|
129
|
+
rubygems_version: 1.6.2
|
130
|
+
signing_key:
|
131
|
+
specification_version: 3
|
132
|
+
summary: Simple rake tasks for deploying to Heroku
|
133
|
+
test_files:
|
134
|
+
- features/deploying.feature
|
135
|
+
- features/loading_tasks.feature
|
136
|
+
- features/step_definitions/stub_steps.rb
|
137
|
+
- features/step_definitions/task_steps.rb
|
138
|
+
- features/support/env.rb
|
139
|
+
- features/support/insert_into_rakefile.rb
|
140
|
+
- features/support/require_kumade.rb
|
141
|
+
- spec/deployer_spec.rb
|
142
|
+
- spec/kumade_spec.rb
|
143
|
+
- spec/spec_helper.rb
|