kumade 0.4.0 → 0.5.0

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.
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