kumade 0.4.0 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (41) hide show
  1. data/README.md +9 -1
  2. data/features/kumade_executable.feature +11 -12
  3. data/features/kumade_without_jammit.feature +2 -2
  4. data/kumade.gemspec +1 -0
  5. data/lib/kumade.rb +7 -1
  6. data/lib/kumade/cli.rb +4 -4
  7. data/lib/kumade/command_line.rb +33 -0
  8. data/lib/kumade/configuration.rb +13 -6
  9. data/lib/kumade/deployer.rb +9 -9
  10. data/lib/kumade/git.rb +25 -20
  11. data/lib/kumade/heroku.rb +18 -11
  12. data/lib/kumade/outputter.rb +21 -0
  13. data/lib/kumade/packager.rb +23 -76
  14. data/lib/kumade/packager_list.rb +29 -0
  15. data/lib/kumade/packagers/jammit_packager.rb +20 -0
  16. data/lib/kumade/packagers/more_packager.rb +20 -0
  17. data/lib/kumade/packagers/noop_packager.rb +14 -0
  18. data/lib/kumade/rake_task_runner.rb +29 -0
  19. data/lib/kumade/version.rb +1 -1
  20. data/spec/kumade/cli_spec.rb +5 -5
  21. data/spec/kumade/command_line_spec.rb +107 -0
  22. data/spec/kumade/configuration_spec.rb +15 -2
  23. data/spec/kumade/deployer_spec.rb +39 -25
  24. data/spec/kumade/git_spec.rb +168 -57
  25. data/spec/kumade/heroku_spec.rb +19 -25
  26. data/spec/kumade/outputter_spec.rb +50 -0
  27. data/spec/kumade/packager_list_spec.rb +31 -0
  28. data/spec/kumade/packager_spec.rb +66 -275
  29. data/spec/kumade/packagers/jammit_packager_spec.rb +27 -0
  30. data/spec/kumade/packagers/more_packager_spec.rb +37 -0
  31. data/spec/kumade/packagers/noop_packager_spec.rb +9 -0
  32. data/spec/kumade/rake_task_runner_spec.rb +75 -0
  33. data/spec/spec_helper.rb +13 -2
  34. data/spec/support/define_constant.rb +41 -0
  35. data/spec/support/environments.rb +32 -0
  36. data/spec/support/git.rb +5 -0
  37. data/spec/support/heroku.rb +6 -6
  38. data/spec/support/shared_examples/packager.rb +6 -0
  39. metadata +65 -28
  40. data/lib/kumade/base.rb +0 -35
  41. data/spec/kumade/base_spec.rb +0 -99
@@ -1,49 +1,26 @@
1
1
  require 'spec_helper'
2
2
 
3
- describe Kumade::Git, "#heroku_remote?" do
3
+ describe Kumade::Git, "#heroku_remote?", :with_mock_outputter do
4
4
  context "when the environment is a Heroku repository" do
5
- let(:environment) { 'staging' }
5
+ include_context "with Heroku environment"
6
6
 
7
- before do
8
- force_add_heroku_remote(environment)
9
- Kumade.configuration.environment = environment
10
- end
11
-
12
- after { remove_remote(environment) }
13
-
14
- its(:heroku_remote?) { should == true }
7
+ it { should be_heroku_remote }
15
8
  end
16
9
 
17
10
  context "when the environment is a Heroku repository managed with heroku-accounts" do
18
- let(:another_heroku_environment) { 'another_staging' }
19
- let(:another_heroku_url) { 'git@heroku.work:my-app.git' }
11
+ include_context "with Heroku-accounts environment"
20
12
 
21
- before do
22
- force_add_heroku_remote(another_heroku_environment)
23
- Kumade.configuration.environment = another_heroku_environment
24
- end
25
-
26
- after { remove_remote(another_heroku_environment) }
27
-
28
- its(:heroku_remote?) { should == true }
13
+ it { should be_heroku_remote }
29
14
  end
30
15
 
31
16
  context "when the environment is not a Heroku repository" do
32
- let(:not_a_heroku_env) { 'fake_heroku' }
33
- let(:not_a_heroku_url) { 'git@github.com:gabebw/kumade.git' }
34
-
35
- before do
36
- `git remote add #{not_a_heroku_env} #{not_a_heroku_url}`
37
- Kumade.configuration.environment = not_a_heroku_env
38
- end
39
-
40
- after { remove_remote(not_a_heroku_env) }
17
+ include_context "with non-Heroku environment"
41
18
 
42
- its(:heroku_remote?) { should == false }
19
+ it { should_not be_heroku_remote }
43
20
  end
44
21
  end
45
22
 
46
- describe Kumade::Git, ".environments" do
23
+ describe Kumade::Git, ".environments", :with_mock_outputter do
47
24
  let(:environment) { 'staging' }
48
25
  let(:not_a_heroku_env) { 'fake_heroku' }
49
26
  let(:not_a_heroku_url) { 'git@github.com:gabebw/kumade.git' }
@@ -63,56 +40,190 @@ describe Kumade::Git, ".environments" do
63
40
  end
64
41
  end
65
42
 
66
- describe Kumade::Git, "#branch_exist?" do
67
- let(:command_line) { mock("Cocaine::CommandLine") }
68
- let(:branch) { "branch" }
43
+ describe Kumade::Git, "#push", :with_mock_outputter do
44
+ let(:branch) { 'branch' }
45
+ let(:remote) { 'my-remote' }
46
+ let(:command_line) { stub("Kumade::CommandLine instance", :run_or_error => true) }
69
47
 
70
48
  before do
71
- command_line.stubs(:run)
72
- Cocaine::CommandLine.expects(:new).with("git show-ref #{branch}").returns(command_line)
49
+ Kumade::CommandLine.stubs(:new => command_line)
50
+ end
51
+
52
+ it "pushes to the correct remote" do
53
+ subject.push(branch, remote)
54
+ Kumade::CommandLine.should have_received(:new).with("git push #{remote} #{branch}")
55
+ command_line.should have_received(:run_or_error).once
56
+ end
57
+
58
+ it "can force push" do
59
+ subject.push(branch, remote, true)
60
+ Kumade::CommandLine.should have_received(:new).with("git push -f #{remote} #{branch}")
61
+ command_line.should have_received(:run_or_error).once
62
+ end
63
+
64
+ it "prints a success message" do
65
+ subject.push(branch, remote)
66
+ Kumade.configuration.outputter.should have_received(:success).with("Pushed #{branch} -> #{remote}")
67
+ end
68
+ end
69
+
70
+ describe Kumade::Git, "#create", :with_mock_outputter do
71
+ let(:branch) { "my-new-branch" }
72
+ it "creates a branch" do
73
+ subject.create(branch)
74
+ system("git show-ref #{branch} > /dev/null").should be_true
73
75
  end
74
76
 
75
- it "returns true when the branch exists" do
76
- subject.branch_exist?("branch").should be_true
77
+ context "when the branch already exists" do
78
+ before do
79
+ subject.create(branch)
80
+ end
77
81
 
78
- command_line.should have_received(:run)
82
+ it "does not error" do
83
+ subject.create(branch)
84
+ Kumade.configuration.outputter.should have_received(:error).never
85
+ end
79
86
  end
87
+ end
80
88
 
81
- it "returns false if the branch doesn't exist" do
82
- command_line.stubs(:run).raises(Cocaine::ExitStatusError)
89
+ describe Kumade::Git, "#delete", :with_mock_outputter do
90
+ let(:branch_to_delete) { 'branch_to_delete' }
91
+ let(:branch_to_checkout) { 'branch_to_checkout' }
92
+
93
+ before do
94
+ subject.create(branch_to_delete)
95
+ subject.create(branch_to_checkout)
96
+ end
83
97
 
84
- subject.branch_exist?("branch").should be_false
98
+ it "switches to a branch" do
99
+ subject.delete(branch_to_delete, branch_to_checkout)
100
+ subject.current_branch.should == branch_to_checkout
101
+ end
85
102
 
86
- command_line.should have_received(:run)
103
+ it "deletes a branch" do
104
+ subject.delete(branch_to_delete, branch_to_checkout)
105
+ `git show-ref #{branch_to_delete}`.strip.should be_empty
87
106
  end
88
107
  end
89
108
 
90
- describe Kumade::Git, "#dirty?" do
91
- context "when dirty" do
92
- let(:failing_command_line) { mock("CommandLine instance") }
109
+ describe Kumade::Git, "#add_and_commit_all_assets_in", :with_mock_outputter do
110
+ let(:directory) { 'assets' }
111
+
112
+ before do
113
+ Dir.mkdir(directory)
114
+ Dir.chdir(directory) do
115
+ File.open('new-file', 'w') do |f|
116
+ f.write('some content')
117
+ end
118
+ end
119
+ end
120
+
121
+ it "switches to the deploy branch" do
122
+ subject.add_and_commit_all_assets_in(directory)
123
+ subject.current_branch.should == Kumade::Heroku::DEPLOY_BRANCH
124
+ end
93
125
 
126
+ it "uses a bland commit message" do
127
+ subject.add_and_commit_all_assets_in(directory)
128
+ `git log -n1 --pretty=format:%s`.should == 'Compiled assets.'
129
+ end
130
+
131
+ it "commits everything in the dir" do
132
+ subject.add_and_commit_all_assets_in(directory)
133
+ subject.should_not be_dirty
134
+ end
135
+
136
+ it "prints a success message" do
137
+ subject.add_and_commit_all_assets_in(directory)
138
+ Kumade.configuration.outputter.should have_received(:success).with('Added and committed all assets')
139
+ end
140
+
141
+ context "if the command fails" do
142
+ let(:command_line) { mock('CommandLine', :run_or_error => nil) }
143
+ before do
144
+ Kumade::CommandLine.stubs(:new => command_line)
145
+ end
146
+
147
+ it "prints an error message if something goes wrong" do
148
+ subject.add_and_commit_all_assets_in(directory)
149
+ command_line.should have_received(:run_or_error).once
150
+ end
151
+ end
152
+ end
153
+
154
+ describe Kumade::Git, "#current_branch", :with_mock_outputter do
155
+ it "returns the current branch" do
156
+ subject.current_branch.should == 'master'
157
+ `git checkout -b new-branch 2>/dev/null`
158
+ subject.current_branch.should == 'new-branch'
159
+ end
160
+ end
161
+
162
+ describe Kumade::Git, "#remote_exists?", :with_mock_outputter do
163
+ context "when pretending" do
164
+ before { Kumade.configuration.pretending = true }
165
+ it "returns true no matter what" do
166
+ subject.remote_exists?('not-a-remote').should be_true
167
+ end
168
+ end
169
+
170
+ context "when not pretending" do
171
+ let(:good_remote) { 'good-remote' }
172
+ let(:bad_remote) { 'bad-remote' }
94
173
  before do
95
- failing_command_line.stubs(:run).raises(Cocaine::ExitStatusError)
174
+ Kumade.configuration.pretending = false
175
+ force_add_heroku_remote(good_remote)
176
+ end
96
177
 
97
- Cocaine::CommandLine.expects(:new).
98
- with("git diff --exit-code").
99
- returns(failing_command_line)
178
+ it "returns true if the remote exists" do
179
+ subject.remote_exists?(good_remote).should be_true
100
180
  end
101
181
 
102
- it "returns true" do
103
- subject.dirty?.should == true
182
+ it "returns false if the remote does not exist" do
183
+ subject.remote_exists?(bad_remote).should be_false
104
184
  end
105
185
  end
186
+ end
187
+
188
+ describe Kumade::Git, "#dirty?", :with_mock_outputter do
189
+ context "when dirty" do
190
+ before { dirty_the_repo }
191
+
192
+ it { should be_dirty }
193
+ end
106
194
 
107
195
  context "when clean" do
196
+ it { should_not be_dirty }
197
+ end
198
+ end
199
+
200
+
201
+ describe Kumade::Git, "#ensure_clean_git", :with_mock_outputter do
202
+ context "when pretending" do
108
203
  before do
109
- Cocaine::CommandLine.expects(:new).
110
- with("git diff --exit-code").
111
- returns(stub("Successful CommandLine", :run => true))
204
+ Kumade.configuration.pretending = true
205
+ dirty_the_repo
112
206
  end
113
207
 
114
- it "returns false" do
115
- subject.dirty?.should == false
208
+ it "prints a success message" do
209
+ subject.ensure_clean_git
210
+ Kumade.configuration.outputter.should have_received(:success).with("Git repo is clean")
211
+ end
212
+ end
213
+
214
+ context "when repo is clean" do
215
+ it "prints a success message" do
216
+ subject.ensure_clean_git
217
+ Kumade.configuration.outputter.should have_received(:success).with("Git repo is clean")
218
+ end
219
+ end
220
+
221
+ context "when repo is dirty" do
222
+ before { dirty_the_repo }
223
+
224
+ it "prints an error message" do
225
+ subject.ensure_clean_git
226
+ Kumade.configuration.outputter.should have_received(:error).with("Cannot deploy: repo is not clean.")
116
227
  end
117
228
  end
118
229
  end
@@ -1,12 +1,12 @@
1
1
  require 'spec_helper'
2
2
 
3
- describe Kumade::Heroku, "DEPLOY_BRANCH" do
3
+ describe Kumade::Heroku, "DEPLOY_BRANCH", :with_mock_outputter do
4
4
  subject { Kumade::Heroku::DEPLOY_BRANCH }
5
5
 
6
6
  it { should == "deploy" }
7
7
  end
8
8
 
9
- describe Kumade::Heroku, "#sync" do
9
+ describe Kumade::Heroku, "#sync", :with_mock_outputter do
10
10
  let(:environment) { 'staging' }
11
11
 
12
12
  before do
@@ -23,11 +23,10 @@ describe Kumade::Heroku, "#sync" do
23
23
  end
24
24
  end
25
25
 
26
- describe Kumade::Heroku, "#migrate_database" do
26
+ describe Kumade::Heroku, "#migrate_database", :with_mock_outputter do
27
27
  let(:environment) { 'staging' }
28
28
 
29
29
  before do
30
- STDOUT.stubs(:puts)
31
30
  subject.stubs(:heroku)
32
31
  force_add_heroku_remote(environment)
33
32
  end
@@ -40,40 +39,38 @@ describe Kumade::Heroku, "#migrate_database" do
40
39
 
41
40
  context "when pretending" do
42
41
  before do
43
- STDOUT.stubs(:puts)
44
42
  Kumade.configuration.pretending = true
45
43
  end
46
44
 
47
45
  it "does not run the command" do
48
46
  subject.migrate_database
49
47
 
50
- subject.should_not have_received(:heroku)
48
+ subject.should have_received(:heroku).never
51
49
  end
52
50
 
53
51
  it "prints a message" do
54
52
  subject.migrate_database
55
53
 
56
- STDOUT.should have_received(:puts).with(regexp_matches(/Migrated #{environment}/))
54
+ Kumade.configuration.outputter.should have_received(:success).with(regexp_matches(/Migrated #{environment}/))
57
55
  end
58
56
  end
59
57
  end
60
58
 
61
- describe Kumade::Heroku, "#heroku" do
62
- let(:command_line_instance) { stub("Cocaine::CommandLine instance", :run => true) }
59
+ describe Kumade::Heroku, "#heroku", :with_mock_outputter do
60
+ let(:command_instance) { stub("Kumade::CommandLine instance", :run_or_error => true) }
63
61
 
64
62
  before do
65
- STDOUT.stubs(:puts)
63
+ Kumade::CommandLine.stubs(:new => command_instance)
66
64
  end
67
65
 
68
66
  context "when on Cedar" do
69
67
  include_context "when on Cedar"
70
68
 
71
69
  it "runs commands with `run`" do
72
- Cocaine::CommandLine.expects(:new).
73
- with(regexp_matches(/bundle exec heroku run/)).
74
- returns(command_line_instance)
75
-
76
70
  subject.heroku("rake")
71
+
72
+ Kumade::CommandLine.should have_received(:new).with(regexp_matches(/bundle exec heroku run rake/)).once
73
+ command_instance.should have_received(:run_or_error).once
77
74
  end
78
75
  end
79
76
 
@@ -81,16 +78,15 @@ describe Kumade::Heroku, "#heroku" do
81
78
  include_context "when not on Cedar"
82
79
 
83
80
  it "runs commands without `run`" do
84
- Cocaine::CommandLine.expects(:new).
85
- with(regexp_matches(/bundle exec heroku rake/)).
86
- returns(command_line_instance)
87
-
88
81
  subject.heroku("rake")
82
+
83
+ Kumade::CommandLine.should have_received(:new).with(regexp_matches(/bundle exec heroku rake/)).once
84
+ command_instance.should have_received(:run_or_error).once
89
85
  end
90
86
  end
91
87
  end
92
88
 
93
- describe Kumade::Heroku, "#cedar?" do
89
+ describe Kumade::Heroku, "#cedar?", :with_mock_outputter do
94
90
  context "when on Cedar" do
95
91
  include_context "when on Cedar"
96
92
 
@@ -108,14 +104,12 @@ describe Kumade::Heroku, "#cedar?" do
108
104
  end
109
105
  end
110
106
 
111
- describe Kumade::Heroku, "#delete_deploy_branch" do
112
- before { STDOUT.stubs(:puts) }
107
+ describe Kumade::Heroku, "#delete_deploy_branch", :with_mock_outputter do
108
+ before { subject.git.stubs(:delete) }
113
109
 
114
110
  it "deletes the deploy branch" do
115
- Cocaine::CommandLine.expects(:new).
116
- with("git checkout master && git branch -D deploy").
117
- returns(stub(:run => true))
118
-
119
111
  subject.delete_deploy_branch
112
+
113
+ subject.git.should have_received(:delete).with(Kumade::Heroku::DEPLOY_BRANCH, 'master').once
120
114
  end
121
115
  end
@@ -0,0 +1,50 @@
1
+ require 'spec_helper'
2
+
3
+ describe Kumade::Outputter, "#success" do
4
+ before { STDOUT.stubs(:puts) }
5
+
6
+ it "prints a message to STDOUT" do
7
+ subject.success("woo hoo")
8
+ STDOUT.should have_received(:puts).with(regexp_matches(/==> woo hoo/))
9
+ end
10
+ end
11
+
12
+ describe Kumade::Outputter, "#error" do
13
+ before { STDOUT.stubs(:puts) }
14
+
15
+ it "raises a DeploymentError with the given message" do
16
+ lambda { subject.error("uh oh") }.should raise_error(Kumade::DeploymentError, "uh oh")
17
+ end
18
+
19
+ it "prints a message to STDOUT" do
20
+ subject.error("uh oh") rescue nil
21
+ STDOUT.should have_received(:puts).with(regexp_matches(/==> ! uh oh/))
22
+ end
23
+ end
24
+
25
+ describe Kumade::Outputter, "#info" do
26
+ before { STDOUT.stubs(:puts) }
27
+
28
+ it "prints a message to STDOUT" do
29
+ subject.info("the more you know")
30
+ STDOUT.should have_received(:puts).with(regexp_matches(/==> the more you know/))
31
+ end
32
+ end
33
+
34
+ describe Kumade::Outputter, "#say_command" do
35
+ before { STDOUT.stubs(:puts) }
36
+
37
+ it "prints a formatted message to STDOUT" do
38
+ subject.say_command("git checkout master")
39
+ STDOUT.should have_received(:puts).with(" " * 8 + "git checkout master")
40
+ end
41
+ end
42
+
43
+ describe Kumade::Outputter, "#info" do
44
+ before { STDOUT.stubs(:puts) }
45
+
46
+ it "prints a message to STDOUT" do
47
+ subject.info("the more you know")
48
+ STDOUT.should have_received(:puts).with(regexp_matches(/==> the more you know/))
49
+ end
50
+ end
@@ -0,0 +1,31 @@
1
+ require 'spec_helper'
2
+
3
+ describe Kumade::PackagerList, "detecting packages", :with_mock_outputter do
4
+ it "returns an array containing the Jammit packager if Jammit is installed" do
5
+ Kumade::JammitPackager.stubs(:installed? => true)
6
+ Kumade::MorePackager.stubs(:installed? => false)
7
+
8
+ Kumade::PackagerList.new.to_a.should == [Kumade::JammitPackager]
9
+ end
10
+
11
+ it "returns an array containing the More packager if More is installed" do
12
+ Kumade::JammitPackager.stubs(:installed? => false)
13
+ Kumade::MorePackager.stubs(:installed? => true)
14
+
15
+ Kumade::PackagerList.new.to_a.should == [Kumade::MorePackager]
16
+ end
17
+
18
+ it "returns multiple packagers if they are installed" do
19
+ Kumade::JammitPackager.stubs(:installed? => true)
20
+ Kumade::MorePackager.stubs(:installed? => true)
21
+
22
+ Kumade::PackagerList.new.to_a.should =~ [Kumade::JammitPackager, Kumade::MorePackager]
23
+ end
24
+
25
+ it "returns an array containing the no-op packager if no other packagers are found" do
26
+ Kumade::JammitPackager.stubs(:installed? => false)
27
+ Kumade::MorePackager.stubs(:installed? => false)
28
+
29
+ Kumade::PackagerList.new.to_a.should == [Kumade::NoopPackager]
30
+ end
31
+ end