whisk_deploy 0.6.26

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 (177) hide show
  1. data/CHANGELOG +292 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.integration_specs +24 -0
  4. data/README.markdown +832 -0
  5. data/Rakefile +105 -0
  6. data/VERSION +1 -0
  7. data/WHY.txt +45 -0
  8. data/bin/wd +61 -0
  9. data/bin/wd_role +42 -0
  10. data/examples/deploy-configs.yml +13 -0
  11. data/examples/deploy-local.yml +4 -0
  12. data/examples/deploy-multiple-remotes.yml +26 -0
  13. data/examples/deploy-staging.yml +8 -0
  14. data/examples/deploy.rake +11 -0
  15. data/examples/deploy.yml +16 -0
  16. data/init.rb +1 -0
  17. data/install.rb +5 -0
  18. data/lib/whiskey_disk.rb +327 -0
  19. data/lib/whiskey_disk/config.rb +127 -0
  20. data/lib/whiskey_disk/config/abstract_filter.rb +19 -0
  21. data/lib/whiskey_disk/config/filter.rb +48 -0
  22. data/lib/whiskey_disk/config/filters/add_environment_name_filter.rb +11 -0
  23. data/lib/whiskey_disk/config/filters/add_project_name_filter.rb +11 -0
  24. data/lib/whiskey_disk/config/filters/check_for_duplicate_domains_filter.rb +21 -0
  25. data/lib/whiskey_disk/config/filters/convert_role_strings_to_list_filter.rb +20 -0
  26. data/lib/whiskey_disk/config/filters/default_config_target_filter.rb +12 -0
  27. data/lib/whiskey_disk/config/filters/default_domain_filter.rb +12 -0
  28. data/lib/whiskey_disk/config/filters/drop_empty_domain_roles_filter.rb +32 -0
  29. data/lib/whiskey_disk/config/filters/environment_scope_filter.rb +20 -0
  30. data/lib/whiskey_disk/config/filters/hashify_domain_entries_filter.rb +29 -0
  31. data/lib/whiskey_disk/config/filters/localize_domains_filter.rb +24 -0
  32. data/lib/whiskey_disk/config/filters/modules/scope_helper.rb +11 -0
  33. data/lib/whiskey_disk/config/filters/normalize_ssh_options_filter.rb +29 -0
  34. data/lib/whiskey_disk/config/filters/project_scope_filter.rb +34 -0
  35. data/lib/whiskey_disk/config/filters/select_project_and_environment_filter.rb +12 -0
  36. data/lib/whiskey_disk/config/filters/stringify_hash_keys_filter.rb +25 -0
  37. data/lib/whiskey_disk/helpers.rb +50 -0
  38. data/lib/whiskey_disk/rake.rb +47 -0
  39. data/scenarios/git_repositories/config.git/HEAD +1 -0
  40. data/scenarios/git_repositories/config.git/config +5 -0
  41. data/scenarios/git_repositories/config.git/description +1 -0
  42. data/scenarios/git_repositories/config.git/git-daemon-export-ok +0 -0
  43. data/scenarios/git_repositories/config.git/hooks/applypatch-msg.sample +15 -0
  44. data/scenarios/git_repositories/config.git/hooks/commit-msg.sample +24 -0
  45. data/scenarios/git_repositories/config.git/hooks/post-commit.sample +8 -0
  46. data/scenarios/git_repositories/config.git/hooks/post-receive.sample +15 -0
  47. data/scenarios/git_repositories/config.git/hooks/post-update.sample +8 -0
  48. data/scenarios/git_repositories/config.git/hooks/pre-applypatch.sample +14 -0
  49. data/scenarios/git_repositories/config.git/hooks/pre-commit.sample +46 -0
  50. data/scenarios/git_repositories/config.git/hooks/pre-rebase.sample +169 -0
  51. data/scenarios/git_repositories/config.git/hooks/prepare-commit-msg.sample +36 -0
  52. data/scenarios/git_repositories/config.git/hooks/update.sample +128 -0
  53. data/scenarios/git_repositories/config.git/info/exclude +6 -0
  54. data/scenarios/git_repositories/config.git/objects/0d/b14dd6ddc54017c0a11960dcda82ed802cde69 +0 -0
  55. data/scenarios/git_repositories/config.git/objects/0e/e781f5ce80d64db32a74a7aae7b5248dafe112 +3 -0
  56. data/scenarios/git_repositories/config.git/objects/17/6bf54cf17d1d1c24556dc059c4144a5df230e8 +0 -0
  57. data/scenarios/git_repositories/config.git/objects/20/e9ff3feaa8ede30f707e5f1b4356e3c02bb7ec +0 -0
  58. data/scenarios/git_repositories/config.git/objects/45/117b1c775f0de415478dbf08ed9d667ab17d13 +0 -0
  59. data/scenarios/git_repositories/config.git/objects/51/3954c9aca090e6ce40359f0e9fde30ea78eb8c +0 -0
  60. data/scenarios/git_repositories/config.git/objects/66/947a7a11a6f5d3d561fe95de284ced3010819a +0 -0
  61. data/scenarios/git_repositories/config.git/objects/6b/bc79311bfac47d3ed724aa82a4814e0dda4c67 +0 -0
  62. data/scenarios/git_repositories/config.git/objects/71/eb5df52676e8e6efba471050b46978173af110 +1 -0
  63. data/scenarios/git_repositories/config.git/objects/84/17d2fe3e8fcc0825249c517b29b0f9ea8b8b31 +2 -0
  64. data/scenarios/git_repositories/config.git/objects/8b/384fcfcf7c0dee7c3c1d5636bee9e645d9cf38 +0 -0
  65. data/scenarios/git_repositories/config.git/objects/bb/59da633ba74296b0c2f9ff70784ac155ddb599 +0 -0
  66. data/scenarios/git_repositories/config.git/objects/cc/b86b26189afbf45d8eb9165812ab86dbdfca63 +0 -0
  67. data/scenarios/git_repositories/config.git/objects/d1/0bcd51fec41f854001e4d61f99d9e282a695d3 +0 -0
  68. data/scenarios/git_repositories/config.git/objects/d8/a8b0f5b1fd66844efb141d9544965ea0065f2d +0 -0
  69. data/scenarios/git_repositories/config.git/objects/e6/b02c66ad632e6b8535c4630cb8fe07732a72fc +0 -0
  70. data/scenarios/git_repositories/config.git/objects/e8/b8bfeeba735c0a1a873082554cb4d7256ac125 +0 -0
  71. data/scenarios/git_repositories/config.git/objects/f9/0181466a1a60b793ca9cc9abd584c18d4e3887 +0 -0
  72. data/scenarios/git_repositories/config.git/objects/f9/49d5d8a4f12c91471e34d4e277239c35ebd10d +0 -0
  73. data/scenarios/git_repositories/config.git/refs/heads/master +1 -0
  74. data/scenarios/git_repositories/project.git/HEAD +1 -0
  75. data/scenarios/git_repositories/project.git/config +5 -0
  76. data/scenarios/git_repositories/project.git/description +1 -0
  77. data/scenarios/git_repositories/project.git/git-daemon-export-ok +0 -0
  78. data/scenarios/git_repositories/project.git/hooks/applypatch-msg.sample +15 -0
  79. data/scenarios/git_repositories/project.git/hooks/commit-msg.sample +24 -0
  80. data/scenarios/git_repositories/project.git/hooks/post-commit.sample +8 -0
  81. data/scenarios/git_repositories/project.git/hooks/post-receive.sample +15 -0
  82. data/scenarios/git_repositories/project.git/hooks/post-update.sample +8 -0
  83. data/scenarios/git_repositories/project.git/hooks/pre-applypatch.sample +14 -0
  84. data/scenarios/git_repositories/project.git/hooks/pre-commit.sample +46 -0
  85. data/scenarios/git_repositories/project.git/hooks/pre-rebase.sample +169 -0
  86. data/scenarios/git_repositories/project.git/hooks/prepare-commit-msg.sample +36 -0
  87. data/scenarios/git_repositories/project.git/hooks/update.sample +128 -0
  88. data/scenarios/git_repositories/project.git/info/exclude +6 -0
  89. data/scenarios/git_repositories/project.git/objects/04/26e152e66c8cd42974279bdcae09be9839c172 +0 -0
  90. data/scenarios/git_repositories/project.git/objects/04/f4de85eaf72ef1631dc6d7424045c0a749b757 +1 -0
  91. data/scenarios/git_repositories/project.git/objects/06/13fe277280cbcdb2856e1eefc70bdaff011b20 +0 -0
  92. data/scenarios/git_repositories/project.git/objects/06/7aca89b86265eee211387434c3e50f37ccf009 +0 -0
  93. data/scenarios/git_repositories/project.git/objects/09/445dacc4822722612d60833c9948219ecdd8f5 +0 -0
  94. data/scenarios/git_repositories/project.git/objects/11/c4ec64326de35462f4e79d0f4229bf8e26e0c5 +0 -0
  95. data/scenarios/git_repositories/project.git/objects/20/1c7641c2e42b0b904e5c1f793489d8b858e4da +2 -0
  96. data/scenarios/git_repositories/project.git/objects/23/979639da60d2d31e9744468df1c1221b101e64 +0 -0
  97. data/scenarios/git_repositories/project.git/objects/27/a3fff2c4c45ab5513a405f694c0a042cb5d417 +1 -0
  98. data/scenarios/git_repositories/project.git/objects/2c/0c33cfba8e1af15df88522c0db2b10a6a94138 +2 -0
  99. data/scenarios/git_repositories/project.git/objects/38/b574660305ecb5fec6b2daa7ee1e0dbf1b6003 +0 -0
  100. data/scenarios/git_repositories/project.git/objects/4a/57abb5e4e426cfc9101b3af22ac83ccbd8e2ad +0 -0
  101. data/scenarios/git_repositories/project.git/objects/4c/77ebdd985e57afe7988480720c5dc77ec525c9 +0 -0
  102. data/scenarios/git_repositories/project.git/objects/51/c94da6f1b8aa9d2346088d3d362475b60c7f32 +0 -0
  103. data/scenarios/git_repositories/project.git/objects/5b/a96acf9cc9b87babe37c032676f53bf1ba9ae7 +2 -0
  104. data/scenarios/git_repositories/project.git/objects/5d/f555601d60f1c2a84d2364af0ad640612c3ba5 +0 -0
  105. data/scenarios/git_repositories/project.git/objects/71/03b5ac94940d596c2160a5cfcd55ca4ccac41f +0 -0
  106. data/scenarios/git_repositories/project.git/objects/73/3fc331098b03523f414f3509b9ae6e637c6866 +0 -0
  107. data/scenarios/git_repositories/project.git/objects/80/26076649ceccbe96a6292f2432652f08483035 +0 -0
  108. data/scenarios/git_repositories/project.git/objects/86/d1ef0976be4567de562224e1b51fbf9820c53a +1 -0
  109. data/scenarios/git_repositories/project.git/objects/87/a9d8b09b3401d21b23d90253332d6b28b47db2 +0 -0
  110. data/scenarios/git_repositories/project.git/objects/8b/030ba688255c917d189ae3f87d7c5ccd226bc2 +0 -0
  111. data/scenarios/git_repositories/project.git/objects/95/c9d5ad9b1c90e4c805516783105fc2037dedeb +2 -0
  112. data/scenarios/git_repositories/project.git/objects/95/d82d043af35a80eabfd56c0d705abfa3488787 +2 -0
  113. data/scenarios/git_repositories/project.git/objects/96/0bf34bb0b46d0aeb0be87f688f4ef06a4b35e1 +0 -0
  114. data/scenarios/git_repositories/project.git/objects/a3/860106dc1d148c7831cd45ae38829b4ed47702 +2 -0
  115. data/scenarios/git_repositories/project.git/objects/a8/506d6439b71784a72ac72d284b2ad53088f573 +0 -0
  116. data/scenarios/git_repositories/project.git/objects/ad/22ea6c7563777936ecfbe50d8e2cf8120fd525 +0 -0
  117. data/scenarios/git_repositories/project.git/objects/ae/3900de54aff557c61c81146d00f9d38e55a265 +1 -0
  118. data/scenarios/git_repositories/project.git/objects/bf/5e3740d52b80abb0378b3f85f93a53b1294521 +1 -0
  119. data/scenarios/git_repositories/project.git/objects/bf/b59811cdbc069418dee14b171e6e7e979784b7 +0 -0
  120. data/scenarios/git_repositories/project.git/objects/cc/5ac0afb24e727d5de344cc26a425f4fb7fd17d +3 -0
  121. data/scenarios/git_repositories/project.git/objects/d1/091aa2dd76885108461110c639e6b33a297fce +0 -0
  122. data/scenarios/git_repositories/project.git/objects/d8/913f6650eb2b7bf2a633732d8452008ca23dcb +0 -0
  123. data/scenarios/git_repositories/project.git/objects/db/d1b9667f1b26b13331ac0c321dced8be1aeab0 +3 -0
  124. data/scenarios/git_repositories/project.git/objects/e4/3b9107e9b1908ce415025e64eb83a493d329b7 +0 -0
  125. data/scenarios/git_repositories/project.git/objects/ef/2a88894d5421920b9dfe67a9a4d8043830e62e +0 -0
  126. data/scenarios/git_repositories/project.git/objects/f4/0123a1ff20c65d8dc15a38a83222647908e6f7 +0 -0
  127. data/scenarios/git_repositories/project.git/objects/f5/0af315b75ca0b12c720dec6d916b76b968c319 +0 -0
  128. data/scenarios/git_repositories/project.git/objects/f6/0215709b7b23f3738e9cbaf634b1c86bbd376a +0 -0
  129. data/scenarios/git_repositories/project.git/refs/heads/bad_rakefile +1 -0
  130. data/scenarios/git_repositories/project.git/refs/heads/hook_with_changed +1 -0
  131. data/scenarios/git_repositories/project.git/refs/heads/master +1 -0
  132. data/scenarios/git_repositories/project.git/refs/heads/no_rake_hooks +1 -0
  133. data/scenarios/git_repositories/project.git/refs/heads/post_rake_tasks +1 -0
  134. data/scenarios/invalid/deploy.yml +1 -0
  135. data/scenarios/local/deploy.yml.erb +17 -0
  136. data/scenarios/remote/deploy.yml +119 -0
  137. data/scenarios/setup/vagrant/.gitignore +3 -0
  138. data/scenarios/setup/vagrant/Vagrantfile +10 -0
  139. data/scenarios/setup/vagrant/manifests/integration.pp +32 -0
  140. data/scenarios/setup/vagrant/pids/.gitignore +1 -0
  141. data/spec/.bacon +0 -0
  142. data/spec/init_spec.rb +9 -0
  143. data/spec/install_spec.rb +43 -0
  144. data/spec/integration/branch_switching_spec.rb +41 -0
  145. data/spec/integration/deployment_failures_spec.rb +106 -0
  146. data/spec/integration/helper_spec.rb +90 -0
  147. data/spec/integration/invalid_configuration_spec.rb +39 -0
  148. data/spec/integration/local_deployments_spec.rb +230 -0
  149. data/spec/integration/post_rake_tasks_spec.rb +226 -0
  150. data/spec/integration/post_scripts_spec.rb +246 -0
  151. data/spec/integration/remote_deployments_spec.rb +166 -0
  152. data/spec/integration/staleness_checks_spec.rb +72 -0
  153. data/spec/spec_helper.rb +117 -0
  154. data/spec/wd_command_spec.rb +986 -0
  155. data/spec/wd_role_command_spec.rb +49 -0
  156. data/spec/whiskey_disk/config/filter_spec.rb +77 -0
  157. data/spec/whiskey_disk/config/filters/add_environment_name_filter_spec.rb +20 -0
  158. data/spec/whiskey_disk/config/filters/add_project_name_filter_spec.rb +19 -0
  159. data/spec/whiskey_disk/config/filters/check_for_duplicate_domains_filter_spec.rb +29 -0
  160. data/spec/whiskey_disk/config/filters/convert_role_strings_to_list_filter_spec.rb +48 -0
  161. data/spec/whiskey_disk/config/filters/default_config_target_filter_spec.rb +19 -0
  162. data/spec/whiskey_disk/config/filters/default_domain_filter_spec.rb +18 -0
  163. data/spec/whiskey_disk/config/filters/drop_empty_domain_roles_filter_spec.rb +60 -0
  164. data/spec/whiskey_disk/config/filters/environment_scope_filter_spec.rb +32 -0
  165. data/spec/whiskey_disk/config/filters/hashify_domain_entries_filter_spec.rb +41 -0
  166. data/spec/whiskey_disk/config/filters/localize_domains_filter_spec.rb +30 -0
  167. data/spec/whiskey_disk/config/filters/normalize_ssh_options_filter_spec.rb +56 -0
  168. data/spec/whiskey_disk/config/filters/project_scope_filter_spec.rb +75 -0
  169. data/spec/whiskey_disk/config/filters/select_project_and_environment_filter_spec.rb +30 -0
  170. data/spec/whiskey_disk/config/filters/stringify_hash_keys_filter_spec.rb +40 -0
  171. data/spec/whiskey_disk/config_spec.rb +754 -0
  172. data/spec/whiskey_disk/helpers_spec.rb +443 -0
  173. data/spec/whiskey_disk/rake_spec.rb +261 -0
  174. data/spec/whiskey_disk_spec.rb +1224 -0
  175. data/tasks/deploy.rake +2 -0
  176. data/whisk_deploy.gemspec +215 -0
  177. metadata +241 -0
@@ -0,0 +1,1224 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), 'spec_helper.rb'))
2
+ require File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib', 'whiskey_disk'))
3
+ require 'rake'
4
+
5
+ # @whiskey_disk subclass that allows us to test in what order ssh commands are
6
+ # issued by @whiskey_disk.run
7
+ class TestOrderedExecution < WhiskeyDisk
8
+ class << self
9
+ def commands
10
+ result = @commands
11
+ @commands = []
12
+ result
13
+ end
14
+
15
+ def system(*args)
16
+ @commands ||= []
17
+ @commands << args.join(' ')
18
+ end
19
+ end
20
+ end
21
+
22
+ describe 'requiring the main library' do
23
+ before do
24
+ Rake.application = @rake = Rake::Application.new
25
+ load File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib', 'whiskey_disk', 'rake.rb'))
26
+ end
27
+
28
+ after do
29
+ Rake.application = nil
30
+ end
31
+
32
+ it 'makes the deploy:setup rake task available' do
33
+ Rake::Task.task_defined?('deploy:setup').should.be.true
34
+ end
35
+
36
+ it 'makes the deploy:now rake task available' do
37
+ Rake::Task.task_defined?('deploy:now').should.be.true
38
+ end
39
+ end
40
+
41
+ describe '@whiskey_disk' do
42
+ describe 'when initializing' do
43
+ it 'works without arguments' do
44
+ lambda { WhiskeyDisk.new }.should.not.raise(ArgumentError)
45
+ end
46
+
47
+ it 'works with an options hash' do
48
+ lambda { WhiskeyDisk.new(:foo => 'bar') }.should.not.raise(ArgumentError)
49
+ end
50
+
51
+ it 'saves the staleness checks state if enabled via the options hash' do
52
+ @whiskey_disk = WhiskeyDisk.new(:staleness_checks => true)
53
+ @whiskey_disk.staleness_checks_enabled?.should == true
54
+ end
55
+
56
+ it 'leaves staleness checks disabled if not enabled via the options hash' do
57
+ @whiskey_disk = WhiskeyDisk.new
58
+ @whiskey_disk.staleness_checks_enabled?.should == false
59
+ end
60
+
61
+ it 'leaves staleness checks disabled if disabled via the options hash' do
62
+ @whiskey_disk = WhiskeyDisk.new(:staleness_checks => false)
63
+ @whiskey_disk.staleness_checks_enabled?.should == false
64
+ end
65
+ end
66
+
67
+ before do
68
+ @whiskey_disk = WhiskeyDisk.new
69
+ end
70
+
71
+ describe 'determining if the deployment is remote' do
72
+ before do
73
+ @parameters = { 'deploy_to' => '/path/to/main/repo' }
74
+ @whiskey_disk.configuration = @parameters
75
+ end
76
+
77
+ it 'allows a domain argument' do
78
+ lambda { @whiskey_disk.remote?('domain') }.should.not.raise(ArgumentError)
79
+ end
80
+
81
+ it 'requires a domain argument' do
82
+ lambda { @whiskey_disk.remote? }.should.raise(ArgumentError)
83
+ end
84
+
85
+ describe 'when a domain limit is specified in the configuration' do
86
+ before do
87
+ @domain = 'myhost'
88
+ @config = WhiskeyDisk::Config.new
89
+ @config.stub!(:domain_limit).and_return(@domain)
90
+ @whiskey_disk.config = @config
91
+ end
92
+
93
+ it 'returns false if the provided domain is nil' do
94
+ @whiskey_disk.remote?(nil).should == false
95
+ end
96
+
97
+ it 'returns false if the provided domain is the string "local"' do
98
+ @whiskey_disk.remote?('local').should == false
99
+ end
100
+
101
+ it 'returns false if the provided domain matches the limit domain from the configuration' do
102
+ @whiskey_disk.remote?(@domain).should == false
103
+ end
104
+
105
+ it 'returns false if the provided domain, ignoring any user@, matches the limit domain from the configuration' do
106
+ @whiskey_disk.remote?("user@" + @domain).should == false
107
+ end
108
+
109
+ it 'returns true if the provided domain does not match the limit domain from the configuration' do
110
+ @whiskey_disk.remote?('smeghost').should == true
111
+ end
112
+ end
113
+
114
+ describe 'when no domain limit is specified in the configuration' do
115
+ before do
116
+ @config = WhiskeyDisk::Config.new
117
+ @config.stub!(:domain_limit).and_return(nil)
118
+ @whiskey_disk.config = @config
119
+ end
120
+
121
+ it 'returns false if the provided domain is nil' do
122
+ @whiskey_disk.remote?(nil).should == false
123
+ end
124
+
125
+ it 'returns false if the provided domain is the string "local"' do
126
+ @whiskey_disk.remote?('local').should == false
127
+ end
128
+
129
+ it 'returns true if the provided domain is non-empty' do
130
+ @whiskey_disk.remote?('smeghost').should == true
131
+ end
132
+ end
133
+ end
134
+
135
+ describe 'determining if the deployment has a configuration repository' do
136
+ before do
137
+ @parameters = { 'deploy_to' => '/path/to/main/repo' }
138
+ @whiskey_disk.configuration = @parameters
139
+ end
140
+
141
+ it 'works without arguments' do
142
+ lambda { @whiskey_disk.has_config_repo? }.should.not.raise(ArgumentError)
143
+ end
144
+
145
+ it 'does not allow arguments' do
146
+ lambda { @whiskey_disk.has_config_repo?(:foo) }.should.raise(ArgumentError)
147
+ end
148
+
149
+ it 'returns true if the configuration includes a non-empty config_repository setting' do
150
+ @parameters['config_repository'] = 'git://foo.git'
151
+ @whiskey_disk.has_config_repo?.should == true
152
+ end
153
+
154
+ it 'returns false if the configuration includes a nil config_repository setting' do
155
+ @parameters['config_repository'] = nil
156
+ @whiskey_disk.has_config_repo?.should == false
157
+ end
158
+
159
+ it 'returns false if the configuration includes a blank config_repository setting' do
160
+ @parameters['config_repository'] = ''
161
+ @whiskey_disk.has_config_repo?.should == false
162
+ end
163
+ end
164
+
165
+ describe 'when checking staleness checks' do
166
+ it 'returns false if staleness checks have not been enabled' do
167
+ @whiskey_disk.staleness_checks_enabled?.should == false
168
+ end
169
+
170
+ it 'returns true if staleness checks have been enabled' do
171
+ @whiskey_disk = WhiskeyDisk.new(:staleness_checks => true)
172
+ @whiskey_disk.staleness_checks_enabled?.should == true
173
+ end
174
+ end
175
+
176
+ describe 'ensuring that the parent path for the main repository checkout is present' do
177
+ before do
178
+ @whiskey_disk.configuration = { 'deploy_to' => '/path/to/main/repo' }
179
+ end
180
+
181
+ it 'fails if the deployment path is not specified' do
182
+ @whiskey_disk.configuration = {}
183
+ lambda { @whiskey_disk.ensure_main_parent_path_is_present }.should.raise
184
+ end
185
+
186
+ it 'attempts to create the parent path for the repository' do
187
+ @whiskey_disk.ensure_main_parent_path_is_present
188
+ @whiskey_disk.buffer.last.should.match(%r{mkdir -p /path/to/main})
189
+ @whiskey_disk.buffer.last.should.not.match(%r{/path/to/main/repo})
190
+ end
191
+ end
192
+
193
+ describe 'ensuring that the parent path for the configuration repository checkout is present' do
194
+ before do
195
+ @whiskey_disk.configuration = { 'deploy_config_to' => '/path/to/config/repo' }
196
+ end
197
+
198
+ it 'fails if the configuration deployment path is not specified' do
199
+ @whiskey_disk.configuration = {}
200
+ lambda { @whiskey_disk.ensure_config_parent_path_is_present }.should.raise
201
+ end
202
+
203
+ it 'attempts to create the parent path for the repository' do
204
+ @whiskey_disk.ensure_config_parent_path_is_present
205
+ @whiskey_disk.buffer.last.should.match(%r{mkdir -p /path/to/config})
206
+ @whiskey_disk.buffer.last.should.not.match(%r{/path/to/config/repo})
207
+ end
208
+ end
209
+
210
+ describe 'checking out the main repository' do
211
+ before do
212
+ @parameters = { 'deploy_to' => '/path/to/main/repo', 'repository' => 'git@ogtastic.com:whiskey_disk.git' }
213
+ @whiskey_disk.configuration = @parameters
214
+ end
215
+
216
+ it 'fails if the deployment path is not specified' do
217
+ @whiskey_disk.configuration = @parameters.merge('deploy_to' => nil)
218
+ lambda { @whiskey_disk.checkout_main_repository }.should.raise
219
+ end
220
+
221
+ it 'fails if the repository is not specified' do
222
+ @whiskey_disk.configuration = @parameters.merge('repository' => nil)
223
+ lambda { @whiskey_disk.checkout_main_repository }.should.raise
224
+ end
225
+
226
+ it 'works from the main repository checkout parent path' do
227
+ @whiskey_disk.checkout_main_repository
228
+ @whiskey_disk.buffer.join(' ').should.match(%r{cd /path/to/main[^/]})
229
+ end
230
+
231
+ it 'attempts to clone the main repository to the repository checkout path' do
232
+ @whiskey_disk.checkout_main_repository
233
+ @whiskey_disk.buffer.join(' ').should.match(%r{clone #{@parameters['repository']} repo})
234
+ end
235
+
236
+ it 'makes the main repository clone conditional on the lack of a main repository checkout' do
237
+ @whiskey_disk.checkout_main_repository
238
+ @whiskey_disk.buffer.join(' ').should.match(%r{if \[ -e #{@parameters['deploy_to']} \]; then .*; fi})
239
+ end
240
+
241
+ it 'does a branch creation checkout of the master branch when no branch is specified' do
242
+ @whiskey_disk.checkout_main_repository
243
+ @whiskey_disk.buffer.join(' ').should.match(%r{git checkout -b master origin/master})
244
+ end
245
+
246
+ it 'falls back to a regular checkout of the master branch with origin branch when no branch is specified' do
247
+ @whiskey_disk.checkout_main_repository
248
+ @whiskey_disk.buffer.join(' ').should.match(%r{\|\| git checkout master origin/master})
249
+ end
250
+
251
+ it 'falls back to a regular checkout of the master branch when no branch is specified' do
252
+ @whiskey_disk.checkout_main_repository
253
+ @whiskey_disk.buffer.join(' ').should.match(%r{\|\| git checkout master origin/master \|\| git checkout master})
254
+ end
255
+
256
+ it 'does a branch creation checkout of the specified branch when a branch is specified' do
257
+ @whiskey_disk.configuration = @parameters.merge({'branch' => 'production'})
258
+ @whiskey_disk.checkout_main_repository
259
+ @whiskey_disk.buffer.join(' ').should.match(%r{git checkout -b production origin/production})
260
+ end
261
+
262
+ it 'falls back to a regular checkout of the specified branch with origin branch when a branch is specified' do
263
+ @whiskey_disk.configuration = @parameters.merge({'branch' => 'production'})
264
+ @whiskey_disk.checkout_main_repository
265
+ @whiskey_disk.buffer.join(' ').should.match(%r{\|\| git checkout production origin/production})
266
+ end
267
+
268
+ it 'falls back to a regular checkout of the specified branch when a branch is specified' do
269
+ @whiskey_disk.configuration = @parameters.merge({'branch' => 'production'})
270
+ @whiskey_disk.checkout_main_repository
271
+ @whiskey_disk.buffer.join(' ').should.match(%r{\|\| git checkout production origin/production \|\| git checkout production})
272
+ end
273
+
274
+ it 'does branch checkouts from the repository path' do
275
+ @whiskey_disk.checkout_main_repository
276
+ @whiskey_disk.buffer.join(' ').should.match(%r{cd /path/to/main/repo && git checkout})
277
+ end
278
+ end
279
+
280
+ describe 'checking out the configuration repository' do
281
+ before do
282
+ @parameters = { 'deploy_config_to' => '/path/to/config/repo', 'config_repository' => 'git@ogtastic.com:config.git' }
283
+ @whiskey_disk.configuration = @parameters
284
+ end
285
+
286
+ it 'fails if the configuration deployment path is not specified' do
287
+ @whiskey_disk.configuration = @parameters.merge('deploy_config_to' => nil)
288
+ lambda { @whiskey_disk.checkout_configuration_repository }.should.raise
289
+ end
290
+
291
+ it 'fails if the configuration repository is not specified' do
292
+ @whiskey_disk.configuration = @parameters.merge('config_repository' => nil)
293
+ lambda { @whiskey_disk.checkout_configuration_repository }.should.raise
294
+ end
295
+
296
+ it 'works from the configuration repository checkout parent path' do
297
+ @whiskey_disk.checkout_configuration_repository
298
+ @whiskey_disk.buffer.join(' ').should.match(%r{cd /path/to/config[^/]})
299
+ end
300
+
301
+ it 'attempts to clone the configuration repository to the repository checkout path' do
302
+ @whiskey_disk.checkout_configuration_repository
303
+ @whiskey_disk.buffer.join(' ').should.match(%r{clone #{@parameters['config_repository']} repo})
304
+ end
305
+
306
+ it 'makes the configuration repository clone conditional on the lack of a main repository checkout' do
307
+ @whiskey_disk.checkout_configuration_repository
308
+ @whiskey_disk.buffer.join(' ').should.match(%r{if \[ -e #{@parameters['deploy_config_to']} \]; then .*; fi})
309
+ end
310
+
311
+ it 'does a branch creation checkout of the master branch when no branch is specified' do
312
+ @whiskey_disk.checkout_configuration_repository
313
+ @whiskey_disk.buffer.join(' ').should.match(%r{git checkout -b master origin/master})
314
+ end
315
+
316
+ it 'falls back to a regular checkout of the master branch with origin branch when no branch is specified' do
317
+ @whiskey_disk.checkout_configuration_repository
318
+ @whiskey_disk.buffer.join(' ').should.match(%r{\|\| git checkout master origin/master})
319
+ end
320
+
321
+ it 'falls back to a regular checkout of the master branch when no branch is specified' do
322
+ @whiskey_disk.checkout_configuration_repository
323
+ @whiskey_disk.buffer.join(' ').should.match(%r{\|\| git checkout master origin/master \|\| git checkout master})
324
+ end
325
+
326
+ it 'does a branch creation checkout of the specified branch when a branch is specified' do
327
+ @whiskey_disk.configuration = @parameters.merge({'config_branch' => 'production'})
328
+ @whiskey_disk.checkout_configuration_repository
329
+ @whiskey_disk.buffer.join(' ').should.match(%r{git checkout -b production origin/production})
330
+ end
331
+
332
+ it 'falls back to a regular checkout of the specified branch with origin branch when a branch is specified' do
333
+ @whiskey_disk.configuration = @parameters.merge({'config_branch' => 'production'})
334
+ @whiskey_disk.checkout_configuration_repository
335
+ @whiskey_disk.buffer.join(' ').should.match(%r{\|\| git checkout production origin/production})
336
+ end
337
+
338
+ it 'falls back to a regular checkout of the specified branch when a branch is specified' do
339
+ @whiskey_disk.configuration = @parameters.merge({'config_branch' => 'production'})
340
+ @whiskey_disk.checkout_configuration_repository
341
+ @whiskey_disk.buffer.join(' ').should.match(%r{\|\| git checkout production origin/production \|\| git checkout production})
342
+ end
343
+
344
+ end
345
+
346
+ describe 'updating the main repository checkout' do
347
+ before do
348
+ @parameters = { 'deploy_to' => '/path/to/main/repo' }
349
+ @whiskey_disk.configuration = @parameters
350
+ end
351
+
352
+ it 'fails if the deployment path is not specified' do
353
+ @whiskey_disk.configuration = @parameters.merge('deploy_to' => nil)
354
+ lambda { @whiskey_disk.update_main_repository_checkout }.should.raise
355
+ end
356
+
357
+ it 'works from the main repository checkout path' do
358
+ @whiskey_disk.update_main_repository_checkout
359
+ @whiskey_disk.buffer.join(' ').should.match(%r{cd /path/to/main/repo})
360
+ end
361
+
362
+ it 'clears out any existing git changes data' do
363
+ @whiskey_disk.update_main_repository_checkout
364
+ @whiskey_disk.buffer.join(' ').should.match(%r{rm -f /path/to/main/repo/.whiskey_disk_git_changes})
365
+ end
366
+
367
+ it 'captures the current git HEAD ref for the current branch' do
368
+ @whiskey_disk.configuration = @parameters.merge({'branch' => 'production'})
369
+ @whiskey_disk.update_main_repository_checkout
370
+ @whiskey_disk.buffer.join(' ').should.match(%r{ml=\`git log -1 --pretty=format:%H\`})
371
+ end
372
+
373
+ it 'captures the current git HEAD ref for the current branch if no branch is specified' do
374
+ @whiskey_disk.update_main_repository_checkout
375
+ @whiskey_disk.buffer.join(' ').should.match(%r{ml=\`git log -1 --pretty=format:%H\`})
376
+ end
377
+
378
+ it 'attempts to fetch only the master branch from the origin if no branch is specified' do
379
+ @whiskey_disk.update_main_repository_checkout
380
+ @whiskey_disk.buffer.join(' ').should.match(%r{git fetch origin \+refs/heads/master:refs/remotes/origin/master})
381
+ end
382
+
383
+ it 'attempts to fetch the specified branch from the origin if a branch is specified' do
384
+ @whiskey_disk.configuration = @parameters.merge({'branch' => 'production'})
385
+ @whiskey_disk.update_main_repository_checkout
386
+ @whiskey_disk.buffer.join(' ').should.match(%r{git fetch origin \+refs/heads/production:refs/remotes/origin/production})
387
+ end
388
+
389
+ it 'works from the default branch if no branch is specified' do
390
+ @whiskey_disk.update_main_repository_checkout
391
+ @whiskey_disk.buffer.join(' ').should.match(%r{git checkout master})
392
+ end
393
+
394
+ it 'works from the specified branch if one is specified' do
395
+ @whiskey_disk.configuration = @parameters.merge({'branch' => 'production'})
396
+ @whiskey_disk.update_main_repository_checkout
397
+ @whiskey_disk.buffer.join(' ').should.match(%r{git checkout production})
398
+ end
399
+
400
+ it 'attempts to reset the master branch from the origin if no branch is specified' do
401
+ @whiskey_disk.update_main_repository_checkout
402
+ @whiskey_disk.buffer.join(' ').should.match(%r{git reset --hard origin/master})
403
+ end
404
+
405
+ it 'attempts to reset the specified branch from the origin if a branch is specified' do
406
+ @whiskey_disk.configuration = @parameters.merge({'branch' => 'production'})
407
+ @whiskey_disk.update_main_repository_checkout
408
+ @whiskey_disk.buffer.join(' ').should.match(%r{git reset --hard origin/production})
409
+ end
410
+
411
+ it 'collects git changes data' do
412
+ @whiskey_disk.update_main_repository_checkout
413
+ @whiskey_disk.buffer.join(' ').should.match(%r{git diff --name-only \$\{ml\}\.\.HEAD > /path/to/main/repo/\.whiskey_disk_git_changes})
414
+ end
415
+ end
416
+
417
+ describe 'updating the configuration repository checkout' do
418
+ before do
419
+ @parameters = { 'deploy_config_to' => '/path/to/config/repo', 'deploy_to' => '/path/to/main/repo' }
420
+ @whiskey_disk.configuration = @parameters
421
+ end
422
+
423
+ it 'fails if the configuration deployment path is not specified' do
424
+ @whiskey_disk.configuration = @parameters.merge('deploy_config_to' => nil)
425
+ lambda { @whiskey_disk.update_configuration_repository_checkout }.should.raise
426
+ end
427
+
428
+ it 'works from the main repository checkout path' do
429
+ @whiskey_disk.update_configuration_repository_checkout
430
+ @whiskey_disk.buffer.join(' ').should.match(%r{cd /path/to/config/repo})
431
+ end
432
+
433
+ it 'clears out any existing rsync changes data' do
434
+ @whiskey_disk.update_configuration_repository_checkout
435
+ @whiskey_disk.buffer.join(' ').should.match(%r{rm -f /path/to/main/repo/.whiskey_disk_rsync_changes})
436
+ end
437
+
438
+ it 'attempts to fetch only the master branch from the origin if no configuration branch is specified' do
439
+ @whiskey_disk.update_configuration_repository_checkout
440
+ @whiskey_disk.buffer.join(' ').should.match(%r{git fetch origin \+refs/heads/master:refs/remotes/origin/master})
441
+ end
442
+
443
+ it 'attempts to fetch the specified branch from the origin if a configuration branch is specified' do
444
+ @whiskey_disk.configuration = @parameters.merge({'config_branch' => 'production'})
445
+ @whiskey_disk.update_configuration_repository_checkout
446
+ @whiskey_disk.buffer.join(' ').should.match(%r{git fetch origin \+refs/heads/production:refs/remotes/origin/production})
447
+ end
448
+
449
+ it 'attempts to reset the master branch from the origin if no configuration branch is specified' do
450
+ @whiskey_disk.update_configuration_repository_checkout
451
+ @whiskey_disk.buffer.join(' ').should.match(%r{git reset --hard origin/master})
452
+ end
453
+
454
+ it 'attempts to reset the master branch from the origin if no configuration branch is specified' do
455
+ @whiskey_disk.configuration = @parameters.merge({'config_branch' => 'production'})
456
+ @whiskey_disk.update_configuration_repository_checkout
457
+ @whiskey_disk.buffer.join(' ').should.match(%r{git reset --hard origin/production})
458
+ end
459
+ end
460
+
461
+ describe 'refreshing the configuration' do
462
+ before do
463
+ @parameters = { 'deploy_to' => '/path/to/main/repo',
464
+ 'deploy_config_to' => '/path/to/config/repo',
465
+ 'environment' => 'production',
466
+ 'config_repository' => 'git@git://foo.bar.git',
467
+ 'config_branch' => 'master',
468
+ 'config_target' => 'staging',
469
+ 'project' => 'whiskey_disk' }
470
+ @whiskey_disk.configuration = @parameters
471
+ end
472
+
473
+ it 'fails if the main deployment path is not specified' do
474
+ @whiskey_disk.configuration = @parameters.merge('deploy_to' => nil)
475
+ lambda { @whiskey_disk.refresh_configuration }.should.raise
476
+ end
477
+
478
+ it 'fails if the configuration deployment path is not specified' do
479
+ @whiskey_disk.configuration = @parameters.merge('deploy_config_to' => nil)
480
+ lambda { @whiskey_disk.refresh_configuration }.should.raise
481
+ end
482
+
483
+ it 'fails if no project name was specified' do
484
+ @whiskey_disk.configuration = @parameters.merge('project' => 'unnamed_project')
485
+ lambda { @whiskey_disk.refresh_configuration }.should.raise
486
+ end
487
+
488
+ it 'uses rsync to overlay the configuration checkout for the project in the config target onto the main checkout' do
489
+ @whiskey_disk.refresh_configuration
490
+ @whiskey_disk.buffer.last.should.match(%r{rsync.* /path/to/config/repo/whiskey_disk/staging/ /path/to/main/repo/})
491
+ end
492
+
493
+ it 'captures rsync change data' do
494
+ @whiskey_disk.refresh_configuration
495
+ @whiskey_disk.buffer.last.should.match(%r{rsync.* --log-format="%t \[%p\] %i %n".*> /path/to/main/repo/.whiskey_disk_rsync_changes})
496
+ end
497
+ end
498
+
499
+ describe 'running post setup hooks' do
500
+ before do
501
+ @whiskey_disk.configuration = { 'deploy_to' => '/path/to/main/repo' }
502
+ ENV['debug'] = nil
503
+ end
504
+
505
+ it 'fails if the deployment path is not specified' do
506
+ @whiskey_disk.configuration = {}
507
+ lambda { @whiskey_disk.run_post_setup_hooks }.should.raise
508
+ end
509
+
510
+ it 'works from the main checkout directory' do
511
+ @whiskey_disk.run_post_setup_hooks
512
+ @whiskey_disk.buffer.join(' ').should.match(%r{cd /path/to/main/repo})
513
+ end
514
+
515
+ describe 'when a post setup script is specified' do
516
+ describe 'and the script path does not start with a "/"' do
517
+ before do
518
+ @whiskey_disk.configuration = { 'deploy_to' => '/path/to/main/repo', 'post_setup_script' => 'path/to/setup/script', 'rake_env' => { 'FOO' => 'BAR' } }
519
+ end
520
+
521
+ it 'cds to the deploy_to path prior to running the script' do
522
+ @whiskey_disk.run_post_setup_hooks
523
+ @whiskey_disk.buffer.join(' ').should.match(%r{cd /path/to/main/repo;.*bash /path/to/main/repo/path/to/setup/script})
524
+ end
525
+
526
+ it 'attempts to run the post setup script with the deployment path prepended' do
527
+ @whiskey_disk.run_post_setup_hooks
528
+ @whiskey_disk.buffer.join(' ').should.match(%r{bash /path/to/main/repo/path/to/setup/script})
529
+ end
530
+
531
+ it 'passes any environment variables when running the post setup script' do
532
+ @whiskey_disk.run_post_setup_hooks
533
+ @whiskey_disk.buffer.join(' ').should.match(%r{FOO='BAR' bash /path/to/main/repo/path/to/setup/script})
534
+ end
535
+
536
+ it 'enables shell verbosity when debugging is enabled' do
537
+ ENV['debug'] = 'true'
538
+ @whiskey_disk.run_post_setup_hooks
539
+ @whiskey_disk.buffer.join(' ').should.match(%r{bash -x /path/to/main/repo/path/to/setup/script})
540
+ end
541
+
542
+ it 'disables shell verbosity when debugging is not enabled' do
543
+ ENV['debug'] = 'false'
544
+ @whiskey_disk.run_post_setup_hooks
545
+ @whiskey_disk.buffer.join(' ').should.match(%r{bash /path/to/main/repo/path/to/setup/script})
546
+ end
547
+ end
548
+
549
+ describe 'and the script path starts with a "/"' do
550
+ before do
551
+ @whiskey_disk.configuration = { 'deploy_to' => '/path/to/main/repo', 'post_setup_script' => '/path/to/setup/script', 'rake_env' => { 'FOO' => 'BAR' } }
552
+ end
553
+
554
+ it 'cds to the deploy_to path prior to running the script' do
555
+ @whiskey_disk.run_post_setup_hooks
556
+ @whiskey_disk.buffer.join(' ').should.match(%r{cd /path/to/main/repo;.*bash /path/to/setup/script})
557
+ end
558
+
559
+ it 'runs the post setup script using its absolute path' do
560
+ @whiskey_disk.run_post_setup_hooks
561
+ @whiskey_disk.buffer.join(' ').should.match(%r{bash /path/to/setup/script})
562
+ end
563
+
564
+ it 'passes any environment variables when running the post setup script' do
565
+ @whiskey_disk.run_post_setup_hooks
566
+ @whiskey_disk.buffer.join(' ').should.match(%r{FOO='BAR' bash /path/to/setup/script})
567
+ end
568
+
569
+ it 'enables shell verbosity when debugging is enabled' do
570
+ ENV['debug'] = 'true'
571
+ @whiskey_disk.run_post_setup_hooks
572
+ @whiskey_disk.buffer.join(' ').should.match(%r{bash -x /path/to/setup/script})
573
+ end
574
+
575
+ it 'disables shell verbosity when debugging is not enabled' do
576
+ ENV['debug'] = 'false'
577
+ @whiskey_disk.run_post_setup_hooks
578
+ @whiskey_disk.buffer.join(' ').should.match(%r{bash /path/to/setup/script})
579
+ end
580
+ end
581
+ end
582
+
583
+ it 'attempts to run the post setup rake tasks' do
584
+ @whiskey_disk.run_post_setup_hooks
585
+ @whiskey_disk.buffer.join(' ').should.match(%r{rake.*deploy:post_setup})
586
+ end
587
+
588
+ it 'runs the post setup tasks with given rake command' do
589
+ @parameters = { 'deploy_to' => '/path/to/main/repo', 'rake_command' => 'bundle exec rake' }
590
+ @whiskey_disk.configuration = @parameters
591
+ @whiskey_disk.run_post_setup_hooks
592
+ @whiskey_disk.buffer.join(' ').should.match(%r{bundle exec rake.*deploy:post_setup})
593
+ end
594
+
595
+ it 'runs the post setup tasks with default rake command if the rake command is empty' do
596
+ @parameters = { 'deploy_to' => '/path/to/main/repo', 'rake_command' => '' }
597
+ @whiskey_disk.configuration = @parameters
598
+ @whiskey_disk.run_post_setup_hooks
599
+ @whiskey_disk.buffer.join(' ').should.match(%r{rake.*deploy:post_setup})
600
+ end
601
+
602
+ it 'uses the same environment when running the rake tasks' do
603
+ @whiskey_disk.run_post_setup_hooks
604
+ @whiskey_disk.buffer.join(' ').should.match(%r{to=#{@env}})
605
+ end
606
+
607
+ it 'makes the post setup rake tasks conditional on the presence of a Rakefile in the deployment path' do
608
+ @whiskey_disk.run_post_setup_hooks
609
+ @whiskey_disk.buffer.join(' ').should.match(%r{if \[ -e /path/to/main/repo/Rakefile \]; then .*; fi})
610
+ end
611
+
612
+ it 'makes the post setup rake tasks conditional on the deploy:post_setup rake task being defined' do
613
+ @whiskey_disk.run_post_setup_hooks
614
+ @whiskey_disk.buffer.join(' ').should.match(%r{rakep=\`.*rake -P\` && if \[\[ \`echo "\$\{rakep\}" | grep deploy:post_setup\` != "" \]\];})
615
+ end
616
+
617
+ it 'uses the given rake command when checking the existance of the deploy:post_setup task' do
618
+ @parameters = { 'deploy_to' => '/path/to/main/repo', 'rake_command' => 'bundle exec rake' }
619
+ @whiskey_disk.configuration = @parameters
620
+ @whiskey_disk.run_post_setup_hooks
621
+ @whiskey_disk.buffer.join(' ').should.match(%r{rakep=\`.*bundle exec rake -P\`})
622
+ end
623
+
624
+ it 'ensures that any rake ENV variable are set when checking for deploy:post_setup tasks' do
625
+ @parameters = { 'deploy_to' => '/path/to/main/repo', 'rake_env' => { 'RAILS_ENV' => 'production', 'FOO' => 'bar' } }
626
+ @whiskey_disk.configuration = @parameters
627
+ @whiskey_disk.run_post_setup_hooks
628
+ @parameters['rake_env'].each_pair do |k,v|
629
+ @whiskey_disk.buffer.join(' ').should.match(%r{#{k}='#{v}' .*rake -P})
630
+ end
631
+ end
632
+
633
+ it 'sets any rake_env variables when running the rake tasks' do
634
+ @parameters = { 'deploy_to' => '/path/to/main/repo', 'rake_env' => { 'RAILS_ENV' => 'production', 'FOO' => 'bar' } }
635
+ @whiskey_disk.configuration = @parameters
636
+ @whiskey_disk.run_post_setup_hooks
637
+ @parameters['rake_env'].each_pair do |k,v|
638
+ @whiskey_disk.buffer.join(' ').should.match(%r{#{k}='#{v}' })
639
+ end
640
+ end
641
+ end
642
+
643
+ describe 'running post deployment hooks' do
644
+ before do
645
+ @whiskey_disk.configuration = { 'deploy_to' => '/path/to/main/repo' }
646
+ ENV['debug'] = nil
647
+ end
648
+
649
+ it 'fails if the deployment path is not specified' do
650
+ @whiskey_disk.configuration = {}
651
+ lambda { @whiskey_disk.run_post_deploy_hooks }.should.raise
652
+ end
653
+
654
+ it 'works from the main checkout directory' do
655
+ @whiskey_disk.run_post_deploy_hooks
656
+ @whiskey_disk.buffer.join(' ').should.match(%r{cd /path/to/main/repo})
657
+ end
658
+
659
+ describe 'when a post deployment script is specified' do
660
+ describe 'and the script path does not start with a "/"' do
661
+ before do
662
+ @whiskey_disk.configuration = { 'deploy_to' => '/path/to/main/repo', 'post_deploy_script' => 'path/to/deployment/script', 'rake_env' => { 'FOO' => 'BAR' } }
663
+ end
664
+
665
+ it 'cds to the deploy_to path prior to running the script' do
666
+ @whiskey_disk.run_post_deploy_hooks
667
+ @whiskey_disk.buffer.join(' ').should.match(%r{cd /path/to/main/repo;.*bash /path/to/main/repo/path/to/deployment/script})
668
+ end
669
+
670
+ it 'attempts to run the post deployment script with the deployment path prepended' do
671
+ @whiskey_disk.run_post_deploy_hooks
672
+ @whiskey_disk.buffer.join(' ').should.match(%r{bash /path/to/main/repo/path/to/deployment/script})
673
+ end
674
+
675
+ it 'passes any environment variables when running the post deploy script' do
676
+ @whiskey_disk.run_post_deploy_hooks
677
+ @whiskey_disk.buffer.join(' ').should.match(%r{FOO='BAR' bash /path/to/main/repo/path/to/deployment/script})
678
+ end
679
+
680
+ it 'enables shell verbosity when debugging is enabled' do
681
+ ENV['debug'] = 'true'
682
+ @whiskey_disk.run_post_deploy_hooks
683
+ @whiskey_disk.buffer.join(' ').should.match(%r{bash -x /path/to/main/repo/path/to/deployment/script})
684
+ end
685
+
686
+ it 'disables shell verbosity when debugging is not enabled' do
687
+ ENV['debug'] = 'false'
688
+ @whiskey_disk.run_post_deploy_hooks
689
+ @whiskey_disk.buffer.join(' ').should.match(%r{bash /path/to/main/repo/path/to/deployment/script})
690
+ end
691
+ end
692
+
693
+ describe 'and the script path starts with a "/"' do
694
+ before do
695
+ @whiskey_disk.configuration = { 'deploy_to' => '/path/to/main/repo', 'post_deploy_script' => '/path/to/deployment/script', 'rake_env' => { 'FOO' => 'BAR' } }
696
+ end
697
+
698
+ it 'cds to the deploy_to path prior to running the script' do
699
+ @whiskey_disk.run_post_deploy_hooks
700
+ @whiskey_disk.buffer.join(' ').should.match(%r{cd /path/to/main/repo;.*bash /path/to/deployment/script})
701
+ end
702
+
703
+ it 'attempts to run the post deployment script using its absolute path' do
704
+ @whiskey_disk.run_post_deploy_hooks
705
+ @whiskey_disk.buffer.join(' ').should.match(%r{bash /path/to/deployment/script})
706
+ end
707
+
708
+ it 'passes any environment variables when running the post deploy script' do
709
+ @whiskey_disk.run_post_deploy_hooks
710
+ @whiskey_disk.buffer.join(' ').should.match(%r{FOO='BAR' bash /path/to/deployment/script})
711
+ end
712
+
713
+ it 'enables shell verbosity when debugging is enabled' do
714
+ ENV['debug'] = 'true'
715
+ @whiskey_disk.run_post_deploy_hooks
716
+ @whiskey_disk.buffer.join(' ').should.match(%r{bash -x /path/to/deployment/script})
717
+ end
718
+
719
+ it 'disables shell verbosity when debugging is not enabled' do
720
+ ENV['debug'] = 'false'
721
+ @whiskey_disk.run_post_deploy_hooks
722
+ @whiskey_disk.buffer.join(' ').should.match(%r{bash /path/to/deployment/script})
723
+ end
724
+ end
725
+ end
726
+
727
+ it 'attempts to run the post deployment rake tasks' do
728
+ @whiskey_disk.run_post_deploy_hooks
729
+ @whiskey_disk.buffer.join(' ').should.match(%r{rake.*deploy:post_deploy})
730
+ end
731
+
732
+ it 'runs the post deployment tasks with given rake command' do
733
+ @parameters = { 'deploy_to' => '/path/to/main/repo', 'rake_command' => 'bundle exec rake' }
734
+ @whiskey_disk.configuration = @parameters
735
+ @whiskey_disk.run_post_deploy_hooks
736
+ @whiskey_disk.buffer.join(' ').should.match(%r{bundle exec rake.*deploy:post_deploy})
737
+ end
738
+
739
+ it 'runs the post deployment tasks with default rake command if the rake command is empty' do
740
+ @parameters = { 'deploy_to' => '/path/to/main/repo', 'rake_command' => '' }
741
+ @whiskey_disk.configuration = @parameters
742
+ @whiskey_disk.run_post_deploy_hooks
743
+ @whiskey_disk.buffer.join(' ').should.match(%r{rake.*deploy:post_deploy})
744
+ end
745
+
746
+ it 'uses the same environment when running the rake tasks' do
747
+ @whiskey_disk.run_post_deploy_hooks
748
+ @whiskey_disk.buffer.join(' ').should.match(%r{to=#{@env}})
749
+ end
750
+
751
+ it 'makes the post deployment rake tasks conditional on the presence of a Rakefile in the deployment path' do
752
+ @whiskey_disk.run_post_deploy_hooks
753
+ @whiskey_disk.buffer.join(' ').should.match(%r{if \[ -e /path/to/main/repo/Rakefile \]; then .*; fi})
754
+ end
755
+
756
+ it 'makes the post deployment rake tasks conditional on the deploy:post_deploy rake task being defined' do
757
+ @whiskey_disk.run_post_deploy_hooks
758
+ @whiskey_disk.buffer.join(' ').should.match(%r{rakep=\`.*rake -P\` && if \[\[ \`echo "\$\{rakep\}" | grep deploy:post_deploy\` != "" \]\];})
759
+ end
760
+
761
+ it 'uses the given rake command when checking the existance of the deploy:post_deploy task' do
762
+ @parameters = { 'deploy_to' => '/path/to/main/repo', 'rake_command' => 'bundle exec rake' }
763
+ @whiskey_disk.configuration = @parameters
764
+ @whiskey_disk.run_post_deploy_hooks
765
+ @whiskey_disk.buffer.join(' ').should.match(%r{rakep=\`.*bundle exec rake -P\`})
766
+ end
767
+
768
+ it 'ensures that any rake ENV variable are set when checking for deploy:post_setup tasks' do
769
+ @parameters = { 'deploy_to' => '/path/to/main/repo', 'rake_env' => { 'RAILS_ENV' => 'production', 'FOO' => 'bar' } }
770
+ @whiskey_disk.configuration = @parameters
771
+ @whiskey_disk.run_post_deploy_hooks
772
+ @parameters['rake_env'].each_pair do |k,v|
773
+ @whiskey_disk.buffer.join(' ').should.match(%r{#{k}='#{v}' .*rake -P})
774
+ end
775
+ end
776
+
777
+ it 'sets any rake_env variables when running the rake tasks' do
778
+ @parameters = { 'deploy_to' => '/path/to/main/repo', 'rake_env' => { 'RAILS_ENV' => 'production', 'FOO' => 'bar' } }
779
+ @whiskey_disk.configuration = @parameters
780
+ @whiskey_disk.run_post_deploy_hooks
781
+ @parameters['rake_env'].each_pair do |k,v|
782
+ @whiskey_disk.buffer.join(' ').should.match(%r{#{k}='#{v}' })
783
+ end
784
+ end
785
+ end
786
+
787
+ describe 'bundling up buffered commands for execution' do
788
+ describe 'when staleness checks are disabled' do
789
+ it 'returns an empty string if there are no commands' do
790
+ @whiskey_disk.bundle.should == ''
791
+ end
792
+
793
+ it 'wraps each command with {} and join with &&s' do
794
+ @whiskey_disk.enqueue("cd foo/bar/baz || true")
795
+ @whiskey_disk.enqueue("rsync -avz --progress /yer/mom /yo/")
796
+ @whiskey_disk.bundle.should == "{ cd foo/bar/baz || true ; } && { rsync -avz --progress /yer/mom /yo/ ; }"
797
+ end
798
+
799
+ it 'does not wrap the bundled commands inside a staleness check' do
800
+ @whiskey_disk.enqueue("cd foo/bar/baz || true")
801
+ @whiskey_disk.enqueue("rsync -avz --progress /yer/mom /yo/")
802
+ @whiskey_disk.bundle.should == "{ cd foo/bar/baz || true ; } && { rsync -avz --progress /yer/mom /yo/ ; }"
803
+ end
804
+ end
805
+
806
+ describe 'when staleness checks are enabled' do
807
+ before do
808
+ @whiskey_disk = WhiskeyDisk.new(:staleness_checks => true)
809
+ end
810
+
811
+ describe 'but not we are not configured for staleness checks on this deployment' do
812
+ before do
813
+ ENV['check'] = nil
814
+ end
815
+
816
+ it 'returns an empty string if there are no commands' do
817
+ @whiskey_disk.bundle.should == ''
818
+ end
819
+
820
+ it 'wraps each command with {} and join with &&s' do
821
+ @whiskey_disk.enqueue("cd foo/bar/baz || true")
822
+ @whiskey_disk.enqueue("rsync -avz --progress /yer/mom /yo/")
823
+ @whiskey_disk.bundle.should == "{ cd foo/bar/baz || true ; } && { rsync -avz --progress /yer/mom /yo/ ; }"
824
+ end
825
+
826
+ it 'does not wrap the bundled commands inside a staleness check' do
827
+ @whiskey_disk.enqueue("cd foo/bar/baz || true")
828
+ @whiskey_disk.enqueue("rsync -avz --progress /yer/mom /yo/")
829
+ @whiskey_disk.bundle.should == "{ cd foo/bar/baz || true ; } && { rsync -avz --progress /yer/mom /yo/ ; }"
830
+ end
831
+ end
832
+
833
+ describe 'and we are configured for staleness checks on this deployment' do
834
+ before do
835
+ ENV['check'] = 'true'
836
+ end
837
+
838
+ describe 'when no configuration repository is in use' do
839
+ before do
840
+ @deploy_to = '/path/to/main/repo'
841
+ @repository = 'git@git://foo.bar.git'
842
+ @parameters = { 'deploy_to' => @deploy_to, 'repository' => @repository }
843
+ @whiskey_disk.configuration = @parameters
844
+ end
845
+
846
+ it 'returns an empty string if there are no commands' do
847
+ @whiskey_disk.bundle.should == ''
848
+ end
849
+
850
+ it 'wraps each command with {} and join with &&s' do
851
+ @whiskey_disk.enqueue("cd foo/bar/baz || true")
852
+ @whiskey_disk.enqueue("rsync -avz --progress /yer/mom /yo/")
853
+ @whiskey_disk.bundle.should.match(Regexp.new(Regexp.escape("{ cd foo/bar/baz || true ; } && { rsync -avz --progress /yer/mom /yo/ ; }")))
854
+ end
855
+
856
+ it 'wraps the bundled commands inside a staleness check which checks only the main repo for staleness' do
857
+ @whiskey_disk.enqueue("COMMAND")
858
+ @whiskey_disk.bundle.should.match(Regexp.new(Regexp.escape("if [[ $ml != ${mr%%\t*} ]] ; then { COMMAND ; }")))
859
+ end
860
+
861
+ it 'adds a notice message for when the repository is not stale' do
862
+ @whiskey_disk.enqueue("COMMAND")
863
+ @whiskey_disk.bundle.should.match(Regexp.new(Regexp.escape("then { COMMAND ; }; else echo \"No changes to deploy.\"; fi")))
864
+ end
865
+
866
+ it "queries the head of the main checkout's current branch if no branch is specified" do
867
+ @whiskey_disk.enqueue("COMMAND")
868
+ @whiskey_disk.bundle.should.match(Regexp.new(Regexp.escape("cd #{@deploy_to}; ml=\`git log -1 --pretty=format:%H\`;")))
869
+ end
870
+
871
+ it "queries the head of the main checkout's current branch if a branch is specified" do
872
+ @whiskey_disk.configuration = @parameters.merge({'branch' => 'production'})
873
+ @whiskey_disk.enqueue("COMMAND")
874
+ @whiskey_disk.bundle.should.match(Regexp.new(Regexp.escape("cd #{@deploy_to}; ml=\`git log -1 --pretty=format:%H\`;")))
875
+ end
876
+
877
+ it "queries the head on the main repository's master branch if no branch is specified" do
878
+ @whiskey_disk.enqueue("COMMAND")
879
+ @whiskey_disk.bundle.should.match(Regexp.new(Regexp.escape("mr=\`git ls-remote #{@repository} refs/heads/master\`;")))
880
+ end
881
+
882
+ it "queries the head of the main repository's specified branch if a branch is specified" do
883
+ @whiskey_disk.configuration = @parameters.merge({'branch' => 'production'})
884
+ @whiskey_disk.enqueue("COMMAND")
885
+ @whiskey_disk.bundle.should.match(Regexp.new(Regexp.escape("mr=\`git ls-remote #{@repository} refs/heads/production\`;")))
886
+ end
887
+
888
+ it 'does not check a configuration repository for staleness' do
889
+ @whiskey_disk.enqueue("COMMAND")
890
+ @whiskey_disk.bundle.should.not.match(/c[lr]=/)
891
+ end
892
+ end
893
+
894
+ describe 'when a configuration repository is in use' do
895
+ before do
896
+ @deploy_to = '/path/to/main/repo'
897
+ @repository = 'git@git://foo.bar.git'
898
+ @deploy_config_to = '/path/to/config/repo'
899
+ @config_repository = 'git@git://foo.bar-config.git'
900
+ @parameters = {
901
+ 'deploy_to' => @deploy_to, 'repository' => @repository,
902
+ 'deploy_config_to' => @deploy_config_to, 'config_repository' => @config_repository
903
+ }
904
+ @whiskey_disk.configuration = @parameters
905
+ end
906
+
907
+ it 'returns an empty string if there are no commands' do
908
+ @whiskey_disk.bundle.should == ''
909
+ end
910
+
911
+ it 'wraps each command with {} and join with &&s' do
912
+ @whiskey_disk.enqueue("cd foo/bar/baz || true")
913
+ @whiskey_disk.enqueue("rsync -avz --progress /yer/mom /yo/")
914
+ @whiskey_disk.bundle.should.match(Regexp.new(Regexp.escape("{ cd foo/bar/baz || true ; } && { rsync -avz --progress /yer/mom /yo/ ; }")))
915
+ end
916
+
917
+ it 'wraps the bundled commands inside a staleness check which checks both main and config repos for staleness' do
918
+ @whiskey_disk.enqueue("COMMAND")
919
+ @whiskey_disk.bundle.should.match(Regexp.new(Regexp.escape("if [[ $ml != ${mr%%\t*} ]] || [[ $cl != ${cr%%\t*} ]]; then { COMMAND ; }")))
920
+ end
921
+
922
+ it 'adds a notice message for when the repositories are not stale' do
923
+ @whiskey_disk.enqueue("COMMAND")
924
+ @whiskey_disk.bundle.should.match(Regexp.new(Regexp.escape("then { COMMAND ; }; else echo \"No changes to deploy.\"; fi")))
925
+ end
926
+
927
+ it "queries the head of the main checkout's current branch if no branch is specified" do
928
+ @whiskey_disk.enqueue("COMMAND")
929
+ @whiskey_disk.bundle.should.match(Regexp.new(Regexp.escape("cd #{@deploy_to}; ml=\`git log -1 --pretty=format:%H\`;")))
930
+ end
931
+
932
+ it "queries the head of the main checkout's current branch if a branch is specified" do
933
+ @whiskey_disk.configuration = @parameters.merge({'branch' => 'production'})
934
+ @whiskey_disk.enqueue("COMMAND")
935
+ @whiskey_disk.bundle.should.match(Regexp.new(Regexp.escape("cd #{@deploy_to}; ml=\`git log -1 --pretty=format:%H\`;")))
936
+ end
937
+
938
+ it "queries the head on the main repository's master branch if no branch is specified" do
939
+ @whiskey_disk.enqueue("COMMAND")
940
+ @whiskey_disk.bundle.should.match(Regexp.new(Regexp.escape("mr=\`git ls-remote #{@repository} refs/heads/master\`;")))
941
+ end
942
+
943
+ it "queries the head of the main repository's specified branch if a branch is specified" do
944
+ @whiskey_disk.configuration = @parameters.merge({'branch' => 'production'})
945
+ @whiskey_disk.enqueue("COMMAND")
946
+ @whiskey_disk.bundle.should.match(Regexp.new(Regexp.escape("mr=\`git ls-remote #{@repository} refs/heads/production\`;")))
947
+ end
948
+
949
+ it "queries the head of the config checkout's current branch if no branch is specified" do
950
+ @whiskey_disk.enqueue("COMMAND")
951
+ @whiskey_disk.bundle.should.match(Regexp.new(Regexp.escape("cd #{@deploy_config_to}; cl=\`git log -1 --pretty=format:%H\`;")))
952
+ end
953
+
954
+ it "queries the head of the config checkout's current branch if a branch is specified" do
955
+ @whiskey_disk.configuration = @parameters.merge({'config_branch' => 'production'})
956
+ @whiskey_disk.enqueue("COMMAND")
957
+ @whiskey_disk.bundle.should.match(Regexp.new(Regexp.escape("cd #{@deploy_config_to}; cl=\`git log -1 --pretty=format:%H\`;")))
958
+ end
959
+
960
+ it "queries the head on the config repository's master branch if no branch is specified" do
961
+ @whiskey_disk.enqueue("COMMAND")
962
+ @whiskey_disk.bundle.should.match(Regexp.new(Regexp.escape("cr=\`git ls-remote #{@config_repository} refs/heads/master\`;")))
963
+ end
964
+
965
+ it "queries the head of the config repository's specified branch if a branch is specified" do
966
+ @whiskey_disk.configuration = @parameters.merge({'config_branch' => 'production'})
967
+ @whiskey_disk.enqueue("COMMAND")
968
+ @whiskey_disk.bundle.should.match(Regexp.new(Regexp.escape("cr=\`git ls-remote #{@config_repository} refs/heads/production\`;")))
969
+ end
970
+ end
971
+ end
972
+ end
973
+ end
974
+
975
+ describe 'determining if a domain is of interest to us' do
976
+ before do
977
+ @config = WhiskeyDisk::Config.new
978
+ @config.stub!(:domain_limit).and_return(false)
979
+ @whiskey_disk.config = @config
980
+ end
981
+
982
+ it 'allows specifying a domain' do
983
+ lambda { @whiskey_disk.domain_of_interest?(:domain) }.should.not.raise(ArgumentError)
984
+ end
985
+
986
+ it 'requires a domain' do
987
+ lambda { @whiskey_disk.domain_of_interest? }.should.raise(ArgumentError)
988
+ end
989
+
990
+ it 'returns true when our configuration does not specify a domain limit' do
991
+ @config.stub!(:domain_limit).and_return(false)
992
+ @whiskey_disk.domain_of_interest?('somedomain').should == true
993
+ end
994
+
995
+ it 'returns true when the specified domain matches the configuration domain limit' do
996
+ @config.stub!(:domain_limit).and_return('somedomain')
997
+ @whiskey_disk.domain_of_interest?('somedomain').should == true
998
+ end
999
+
1000
+ it 'returns true when the specified domain matches the configuration domain limit, with a prepended "user@"' do
1001
+ @config.stub!(:domain_limit).and_return('somedomain')
1002
+ @whiskey_disk.domain_of_interest?('user@somedomain').should == true
1003
+ end
1004
+
1005
+ it 'returns false when the specified domain does not match the configuration domain limit' do
1006
+ @config.stub!(:domain_limit).and_return('otherdomain')
1007
+ @whiskey_disk.domain_of_interest?('somedomain').should == false
1008
+ end
1009
+ end
1010
+
1011
+ describe 'flushing changes' do
1012
+ before do
1013
+ @cmd = 'ls'
1014
+ @domains = [ { 'name' => 'ogc@ogtastic.com' }, { 'name' => 'foo@example.com' }, { 'name' => 'local' } ]
1015
+ @whiskey_disk.configuration = { 'domain' => @domains }
1016
+ @whiskey_disk.stub!(:domain_of_interest?).and_return(true)
1017
+ @whiskey_disk.stub!(:bundle).and_return(@cmd)
1018
+ @whiskey_disk.stub!(:system)
1019
+ @whiskey_disk.stub!(:puts)
1020
+ end
1021
+
1022
+ it 'fails if the domain path is not specified' do
1023
+ @whiskey_disk.configuration = {}
1024
+ lambda { @whiskey_disk.flush}.should.raise
1025
+ end
1026
+
1027
+ it 'uses "run" to issue commands for all remote domains' do
1028
+ @whiskey_disk.should.receive(:run).with({ 'name' => 'ogc@ogtastic.com' }, @cmd)
1029
+ @whiskey_disk.should.receive(:run).with({ 'name' => 'foo@example.com' }, @cmd)
1030
+ @whiskey_disk.flush
1031
+ end
1032
+
1033
+ it 'uses "shell" to issue commands for any local domains' do
1034
+ @whiskey_disk.should.receive(:shell).with({ 'name' => 'local' }, @cmd)
1035
+ @whiskey_disk.flush
1036
+ end
1037
+
1038
+ it 'does not issue a command via run for a remote domain which is not of interest' do
1039
+ @whiskey_disk.stub!(:domain_of_interest?).with('ogc@ogtastic.com').and_return(false)
1040
+ @whiskey_disk.should.not.receive(:run).with({ 'name' => 'ogc@ogtastic.com' }, @cmd)
1041
+ @whiskey_disk.flush
1042
+ end
1043
+
1044
+ it 'does not issue a command via shell for a local domain which is not of interest' do
1045
+ @whiskey_disk.stub!(:domain_of_interest?).with('local').and_return(false)
1046
+ @whiskey_disk.should.not.receive(:shell).with({ 'name' => 'local' }, @cmd)
1047
+ @whiskey_disk.flush
1048
+ end
1049
+ end
1050
+
1051
+ describe 'when running a command string locally' do
1052
+ before do
1053
+ @domain_name = 'local'
1054
+ @domain = { 'name' => @domain_name }
1055
+ @whiskey_disk.configuration = { 'domain' => [ @domain ] }
1056
+ @whiskey_disk.stub!(:system)
1057
+ @whiskey_disk.stub!(:puts)
1058
+ end
1059
+
1060
+ it 'accepts a domain and a command string' do
1061
+ lambda { @whiskey_disk.shell(@domain, 'ls') }.should.not.raise(ArgumentError)
1062
+ end
1063
+
1064
+ it 'requires a domain and a command string' do
1065
+ lambda { @whiskey_disk.shell(@domain) }.should.raise(ArgumentError)
1066
+ end
1067
+
1068
+ describe 'when debugging is enabled' do
1069
+ before { ENV['debug'] = 'true' }
1070
+
1071
+ it 'passes the string to the shell with verbosity enabled' do
1072
+ @whiskey_disk.should.receive(:system).with('bash', '-c', "set -x; ls")
1073
+ @whiskey_disk.shell(@domain, 'ls')
1074
+ end
1075
+
1076
+ it 'includes domain role settings when the domain has roles' do
1077
+ @domain = { 'name' => @domain_name, 'roles' => [ 'web', 'db' ] }
1078
+ @whiskey_disk.configuration = { 'domain' => [ @domain ] }
1079
+ @whiskey_disk.should.receive(:system).with('bash', '-c', "set -x; export WD_ROLES='web:db'; ls")
1080
+ @whiskey_disk.shell(@domain, 'ls')
1081
+ end
1082
+ end
1083
+
1084
+ describe 'when debugging is not enabled' do
1085
+ before { ENV['debug'] = 'false' }
1086
+
1087
+ it 'passes the string to the shell without verbosity enabled' do
1088
+ @whiskey_disk.should.receive(:system).with('bash', '-c', "ls")
1089
+ @whiskey_disk.shell(@domain, 'ls')
1090
+ end
1091
+
1092
+ it 'includes domain role settings when the domain has roles' do
1093
+ @domain = { 'name' => @domain_name, 'roles' => [ 'web', 'db' ] }
1094
+ @whiskey_disk.configuration = { 'domain' => [ @domain ] }
1095
+ @whiskey_disk.should.receive(:system).with('bash', '-c', "export WD_ROLES='web:db'; ls")
1096
+ @whiskey_disk.shell(@domain, 'ls')
1097
+ end
1098
+ end
1099
+ end
1100
+
1101
+ describe 'when running a command string remotely' do
1102
+ before do
1103
+ @domain_name = 'ogc@ogtastic.com'
1104
+ @domain = { 'name' => @domain_name }
1105
+ @whiskey_disk.configuration = { 'domain' => [ @domain ] }
1106
+ @whiskey_disk.stub!(:system)
1107
+ @whiskey_disk.stub!(:puts)
1108
+ end
1109
+
1110
+ it 'accepts a domain and a command string' do
1111
+ lambda { @whiskey_disk.run(@domain, 'ls') }.should.not.raise(ArgumentError)
1112
+ end
1113
+
1114
+ it 'requires a domain and a command string' do
1115
+ lambda { @whiskey_disk.run(@domain) }.should.raise(ArgumentError)
1116
+ end
1117
+
1118
+ describe "building a command" do
1119
+ it 'includes domain role settings when the domain has roles' do
1120
+ @domain = { 'name' => @domain_name, 'roles' => [ 'web', 'db' ] }
1121
+ @whiskey_disk.configuration = { 'domain' => [ @domain ] }
1122
+ @whiskey_disk.build_command(@domain, 'ls').should.match /export WD_ROLES='web:db'; ls/
1123
+ end
1124
+ end
1125
+
1126
+ describe 'when debugging is enabled' do
1127
+ before { ENV['debug'] = 'true' }
1128
+
1129
+ it 'passes the string to ssh for the domain, with verbosity enabled' do
1130
+ @whiskey_disk.should.receive(:system).with('ssh', @domain_name, '-v', "set -x; ls")
1131
+ @whiskey_disk.run(@domain, 'ls')
1132
+ end
1133
+ end
1134
+
1135
+ describe 'when debugging is not enabled' do
1136
+ before { ENV['debug'] = 'false' }
1137
+
1138
+ it 'passes the string to ssh for the domain, with verbosity disabled' do
1139
+ @whiskey_disk.should.receive(:system).with('ssh', @domain_name, "ls")
1140
+ @whiskey_disk.run(@domain, 'ls')
1141
+ end
1142
+ end
1143
+
1144
+ describe 'when ssh_options are specified in the configuration' do
1145
+ before do
1146
+ @domain = { 'name' => @domain_name, 'ssh_options' => [ '-t', '-p 12345' ] }
1147
+
1148
+ @whiskey_disk.configuration = { 'domain' => [ @domain ] }
1149
+ end
1150
+
1151
+ it 'includes the ssh options when running ssh' do
1152
+ @whiskey_disk.should.receive(:system).with('ssh', @domain_name, '-t', '-p 12345', 'ls')
1153
+ @whiskey_disk.run(@domain, 'ls')
1154
+ end
1155
+ end
1156
+ end
1157
+
1158
+ describe 'determining if all the deployments succeeded' do
1159
+ it 'works without arguments' do
1160
+ lambda { @whiskey_disk.success? }.should.not.raise(ArgumentError)
1161
+ end
1162
+
1163
+ it 'does not allow arguments' do
1164
+ lambda { @whiskey_disk.success?(:foo) }.should.raise(ArgumentError)
1165
+ end
1166
+
1167
+ it 'returns true if there are no results recorded' do
1168
+ @whiskey_disk.success?.should.be.true
1169
+ end
1170
+
1171
+ it 'returns true if all recorded results have true statuses' do
1172
+ @whiskey_disk.record_result('1', true)
1173
+ @whiskey_disk.record_result('2', true)
1174
+ @whiskey_disk.record_result('3', true)
1175
+ @whiskey_disk.success?.should.be.true
1176
+ end
1177
+
1178
+ it 'returns false if any recorded result has a false status' do
1179
+ @whiskey_disk.record_result('1', true)
1180
+ @whiskey_disk.record_result('2', false)
1181
+ @whiskey_disk.record_result('3', true)
1182
+ @whiskey_disk.success?.should.be.false
1183
+ end
1184
+ end
1185
+
1186
+ describe 'summarizing the results of a run' do
1187
+ before do
1188
+ @whiskey_disk.stub!(:puts)
1189
+ end
1190
+
1191
+ it 'works without arguments' do
1192
+ lambda { @whiskey_disk.summarize }.should.not.raise(ArgumentError)
1193
+ end
1194
+
1195
+ it 'does not allow arguments' do
1196
+ lambda { @whiskey_disk.summarize(:foo) }.should.raise(ArgumentError)
1197
+ end
1198
+
1199
+ it 'outputs a no runs message when no results are recorded' do
1200
+ @whiskey_disk.should.receive(:puts).with('No deployments to report.')
1201
+ @whiskey_disk.summarize
1202
+ end
1203
+
1204
+ describe 'and there are results recorded' do
1205
+ before do
1206
+ @whiskey_disk.record_result('foo@bar.com', false)
1207
+ @whiskey_disk.record_result('ogc@ogtastic.com', true)
1208
+ @whiskey_disk.record_result('user@example.com', true)
1209
+ end
1210
+
1211
+ it 'outputs a status line for each recorded deployment run' do
1212
+ @whiskey_disk.should.receive(:puts).with('foo@bar.com => failed.')
1213
+ @whiskey_disk.should.receive(:puts).with('ogc@ogtastic.com => succeeded.')
1214
+ @whiskey_disk.should.receive(:puts).with('user@example.com => succeeded.')
1215
+ @whiskey_disk.summarize
1216
+ end
1217
+
1218
+ it 'outputs a summary line including the total runs, count of failures and count of successes.' do
1219
+ @whiskey_disk.should.receive(:puts).with('Total: 3 deployments, 2 successes, 1 failure.')
1220
+ @whiskey_disk.summarize
1221
+ end
1222
+ end
1223
+ end
1224
+ end