minestrone 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (96) hide show
  1. checksums.yaml +7 -0
  2. data/.github/workflows/main.yml +32 -0
  3. data/.gitignore +5 -0
  4. data/Gemfile +10 -0
  5. data/LICENSE.txt +22 -0
  6. data/README.md +35 -0
  7. data/Rakefile +10 -0
  8. data/bin/capify +89 -0
  9. data/bin/min +5 -0
  10. data/docs/lib-codebase-map.md +162 -0
  11. data/docs/lib-dependency-graph.svg +129 -0
  12. data/lib/minestrone/callback.rb +45 -0
  13. data/lib/minestrone/cli/help.rb +131 -0
  14. data/lib/minestrone/cli/help.txt +72 -0
  15. data/lib/minestrone/cli/options.rb +232 -0
  16. data/lib/minestrone/cli.rb +159 -0
  17. data/lib/minestrone/command.rb +177 -0
  18. data/lib/minestrone/configuration/actions/file_transfer.rb +53 -0
  19. data/lib/minestrone/configuration/actions/inspect.rb +46 -0
  20. data/lib/minestrone/configuration/actions/invocation.rb +202 -0
  21. data/lib/minestrone/configuration/alias_task.rb +29 -0
  22. data/lib/minestrone/configuration/callbacks.rb +129 -0
  23. data/lib/minestrone/configuration/connections.rb +66 -0
  24. data/lib/minestrone/configuration/execution.rb +139 -0
  25. data/lib/minestrone/configuration/loading.rb +207 -0
  26. data/lib/minestrone/configuration/log_formatters.rb +75 -0
  27. data/lib/minestrone/configuration/namespaces.rb +225 -0
  28. data/lib/minestrone/configuration/servers.rb +70 -0
  29. data/lib/minestrone/configuration/variables.rb +115 -0
  30. data/lib/minestrone/configuration.rb +69 -0
  31. data/lib/minestrone/errors.rb +17 -0
  32. data/lib/minestrone/ext/string.rb +7 -0
  33. data/lib/minestrone/extensions.rb +56 -0
  34. data/lib/minestrone/logger.rb +171 -0
  35. data/lib/minestrone/processable.rb +50 -0
  36. data/lib/minestrone/recipes/deploy/assets.rb +194 -0
  37. data/lib/minestrone/recipes/deploy/bundler.rb +81 -0
  38. data/lib/minestrone/recipes/deploy/dependencies.rb +44 -0
  39. data/lib/minestrone/recipes/deploy/local_dependency.rb +45 -0
  40. data/lib/minestrone/recipes/deploy/remote_dependency.rb +119 -0
  41. data/lib/minestrone/recipes/deploy/scm/base.rb +204 -0
  42. data/lib/minestrone/recipes/deploy/scm/git.rb +284 -0
  43. data/lib/minestrone/recipes/deploy/scm/none.rb +54 -0
  44. data/lib/minestrone/recipes/deploy/scm.rb +22 -0
  45. data/lib/minestrone/recipes/deploy/strategy/base.rb +87 -0
  46. data/lib/minestrone/recipes/deploy/strategy/copy.rb +353 -0
  47. data/lib/minestrone/recipes/deploy/strategy/remote_cache.rb +80 -0
  48. data/lib/minestrone/recipes/deploy/strategy.rb +22 -0
  49. data/lib/minestrone/recipes/deploy.rb +639 -0
  50. data/lib/minestrone/recipes/standard.rb +23 -0
  51. data/lib/minestrone/recipes/templates/maintenance.rhtml +53 -0
  52. data/lib/minestrone/server_definition.rb +56 -0
  53. data/lib/minestrone/ssh.rb +81 -0
  54. data/lib/minestrone/task_definition.rb +82 -0
  55. data/lib/minestrone/transfer.rb +205 -0
  56. data/lib/minestrone/version.rb +11 -0
  57. data/lib/minestrone.rb +3 -0
  58. data/minestrone.gemspec +32 -0
  59. data/test/cli/execute_test.rb +130 -0
  60. data/test/cli/help_test.rb +178 -0
  61. data/test/cli/options_test.rb +315 -0
  62. data/test/cli/ui_test.rb +26 -0
  63. data/test/cli_test.rb +17 -0
  64. data/test/command_test.rb +305 -0
  65. data/test/configuration/actions/file_transfer_test.rb +61 -0
  66. data/test/configuration/actions/inspect_test.rb +76 -0
  67. data/test/configuration/actions/invocation_test.rb +258 -0
  68. data/test/configuration/alias_task_test.rb +110 -0
  69. data/test/configuration/callbacks_test.rb +201 -0
  70. data/test/configuration/connections_test.rb +192 -0
  71. data/test/configuration/execution_test.rb +176 -0
  72. data/test/configuration/loading_test.rb +149 -0
  73. data/test/configuration/namespace_dsl_test.rb +325 -0
  74. data/test/configuration/servers_test.rb +100 -0
  75. data/test/configuration/variables_test.rb +191 -0
  76. data/test/configuration_test.rb +77 -0
  77. data/test/deploy/local_dependency_test.rb +61 -0
  78. data/test/deploy/remote_dependency_test.rb +146 -0
  79. data/test/deploy/scm/base_test.rb +55 -0
  80. data/test/deploy/scm/git_test.rb +260 -0
  81. data/test/deploy/scm/none_test.rb +26 -0
  82. data/test/deploy/strategy/copy_test.rb +360 -0
  83. data/test/extensions_test.rb +69 -0
  84. data/test/fixtures/cli_integration.rb +5 -0
  85. data/test/fixtures/config.rb +4 -0
  86. data/test/fixtures/custom.rb +3 -0
  87. data/test/logger_formatting_test.rb +149 -0
  88. data/test/logger_test.rb +134 -0
  89. data/test/recipes_test.rb +26 -0
  90. data/test/server_definition_test.rb +121 -0
  91. data/test/ssh_test.rb +99 -0
  92. data/test/task_definition_test.rb +117 -0
  93. data/test/transfer_test.rb +172 -0
  94. data/test/utils.rb +28 -0
  95. data/test/version_test.rb +11 -0
  96. metadata +258 -0
@@ -0,0 +1,260 @@
1
+ require "utils"
2
+ require 'minestrone/recipes/deploy/scm/git'
3
+
4
+ class DeploySCMGitTest < Test::Unit::TestCase
5
+ class TestSCM < Minestrone::Deploy::SCM::Git
6
+ default_command "git"
7
+ end
8
+
9
+ def setup
10
+ @config = { :repository => "." }
11
+ def @config.exists?(name); key?(name); end
12
+
13
+ @source = TestSCM.new(@config)
14
+ end
15
+
16
+ def test_head
17
+ assert_equal "HEAD", @source.head
18
+
19
+ # With :branch
20
+ @config[:branch] = "master"
21
+ assert_equal "master", @source.head
22
+ end
23
+
24
+ def test_origin
25
+ assert_equal "origin", @source.origin
26
+ @config[:remote] = "username"
27
+ assert_equal "username", @source.origin
28
+ end
29
+
30
+ def test_checkout
31
+ @config[:repository] = "git@somehost.com:project.git"
32
+ dest = "/var/www"
33
+ rev = 'c2d9e79'
34
+ assert_equal "git clone -q git@somehost.com:project.git /var/www && cd /var/www && git checkout -q -b deploy #{rev}", @source.checkout(rev, dest)
35
+
36
+ # With :scm_command
37
+ git = "/opt/local/bin/git"
38
+ @config[:scm_command] = git
39
+ assert_equal "#{git} clone -q git@somehost.com:project.git /var/www && cd /var/www && #{git} checkout -q -b deploy #{rev}", @source.checkout(rev, dest).gsub(/\s+/, ' ')
40
+
41
+ # with submodules
42
+ @config[:git_enable_submodules] = true
43
+ assert_equal "#{git} clone -q git@somehost.com:project.git /var/www && cd /var/www && #{git} checkout -q -b deploy #{rev} && #{git} submodule -q init && #{git} submodule -q sync && export GIT_RECURSIVE=$([ ! \"`#{git} --version`\" \\< \"git version 1.6.5\" ] && echo --recursive) && #{git} submodule -q update --init $GIT_RECURSIVE", @source.checkout(rev, dest).gsub(/\s+/, ' ')
44
+ end
45
+
46
+ def test_checkout_branching
47
+ @config[:repository] = "git@somehost.com:project.git"
48
+ dest = "/var/www"
49
+ rev = 'c2d9e79'
50
+ assert_equal "git clone -q git@somehost.com:project.git /var/www && cd /var/www && git checkout -q -b deploy c2d9e79", @source.checkout(rev, dest)
51
+
52
+ # with :branch
53
+ @config[:branch] = "master"
54
+ assert_equal "git clone -q -b master git@somehost.com:project.git /var/www && cd /var/www && git checkout -q -b deploy c2d9e79", @source.checkout(rev, dest)
55
+
56
+ # with :branch with hash code
57
+ @config[:branch] = "c2d9e79"
58
+ assert_equal "git clone -q git@somehost.com:project.git /var/www && cd /var/www && git checkout -q -b deploy c2d9e79", @source.checkout(rev, dest)
59
+ end
60
+
61
+ def test_checkout_submodules_without_recursive
62
+ @config[:repository] = "git@somehost.com:project.git"
63
+ dest = "/var/www"
64
+ rev = 'c2d9e79'
65
+ @config[:git_enable_submodules] = true
66
+ @config[:git_submodules_recursive] = false
67
+ assert_equal "git clone -q git@somehost.com:project.git /var/www && cd /var/www && git checkout -q -b deploy #{rev} && git submodule -q init && git submodule -q sync && git submodule -q update --init", @source.checkout(rev, dest).gsub(/\s+/, ' ')
68
+ end
69
+
70
+ def test_checkout_with_verbose_should_not_use_q_switch
71
+ @config[:repository] = "git@somehost.com:project.git"
72
+ @config[:scm_verbose] = true
73
+ dest = "/var/www"
74
+ rev = 'c2d9e79'
75
+ assert_equal "git clone git@somehost.com:project.git /var/www && cd /var/www && git checkout -b deploy #{rev}", @source.checkout(rev, dest)
76
+ end
77
+
78
+ def test_checkout_with_verbose_off_should_use_q_switch
79
+ @config[:repository] = "git@somehost.com:project.git"
80
+ @config[:scm_verbose] = false
81
+ dest = "/var/www"
82
+ rev = 'c2d9e79'
83
+ assert_equal "git clone -q git@somehost.com:project.git /var/www && cd /var/www && git checkout -q -b deploy #{rev}", @source.checkout(rev, dest)
84
+ end
85
+
86
+ def test_diff
87
+ assert_equal "git diff master", @source.diff('master')
88
+ assert_equal "git diff master..branch", @source.diff('master', 'branch')
89
+ end
90
+
91
+ def test_log
92
+ assert_equal "git log master..", @source.log('master')
93
+ assert_equal "git log master..branch", @source.log('master', 'branch')
94
+ end
95
+
96
+ def test_query_revision_from_remote
97
+ revision = @source.query_revision('HEAD') do |o|
98
+ assert_equal "git ls-remote . HEAD", o
99
+ "d11006102c07c94e5d54dd0ee63dca825c93ed61\tHEAD"
100
+ end
101
+ assert_equal "d11006102c07c94e5d54dd0ee63dca825c93ed61", revision
102
+ end
103
+
104
+ def test_query_revision_falls_back_to_local
105
+ revision = @source.query_revision('d11006') do |o|
106
+ return nil if o == "git ls-remote . d11006"
107
+ assert_equal "git rev-parse --revs-only d11006", o
108
+ "d11006102c07c94e5d54dd0ee63dca825c93ed61"
109
+ end
110
+ assert_equal "d11006102c07c94e5d54dd0ee63dca825c93ed61", revision
111
+ end
112
+
113
+ def test_query_revision_has_whitespace
114
+ revision = @source.query_revision('HEAD') do |o|
115
+ assert_equal "git ls-remote . HEAD", o
116
+ "d11006102c07c94e5d54dd0ee63dca825c93ed61\tHEAD\r"
117
+ end
118
+ assert_equal "d11006102c07c94e5d54dd0ee63dca825c93ed61", revision
119
+ end
120
+
121
+ def test_query_revision_deprecation_error
122
+ assert_raise(ArgumentError) do
123
+ @source.query_revision('origin/release') {}
124
+ end
125
+ end
126
+
127
+ def test_sync
128
+ dest = "/var/www"
129
+ rev = 'c2d9e79'
130
+ assert_equal "cd #{dest} && git fetch -q origin && git fetch --tags -q origin && git reset -q --hard #{rev} && git clean -q -d -x -f", @source.sync(rev, dest)
131
+
132
+ # With :scm_command
133
+ git = "/opt/local/bin/git"
134
+ @config[:scm_command] = git
135
+ assert_equal "cd #{dest} && #{git} fetch -q origin && #{git} fetch --tags -q origin && #{git} reset -q --hard #{rev} && #{git} clean -q -d -x -f", @source.sync(rev, dest)
136
+
137
+ # with submodules
138
+ @config[:git_enable_submodules] = true
139
+ assert_equal "cd #{dest} && #{git} fetch -q origin && #{git} fetch --tags -q origin && #{git} reset -q --hard #{rev} && #{git} submodule -q init && #{git} submodule -q sync && export GIT_RECURSIVE=$([ ! \"`#{git} --version`\" \\< \"git version 1.6.5\" ] && echo --recursive) && #{git} submodule -q update --init $GIT_RECURSIVE && #{git} clean -q -d -x -f", @source.sync(rev, dest)
140
+ end
141
+
142
+ def test_sync_with_remote
143
+ dest = "/var/www"
144
+ rev = 'c2d9e79'
145
+ remote = "username"
146
+ repository = "git@somehost.com:project.git"
147
+
148
+ @config[:repository] = repository
149
+ @config[:remote] = remote
150
+
151
+ assert_equal "cd #{dest} && git config remote.#{remote}.url #{repository} && git config remote.#{remote}.fetch +refs/heads/*:refs/remotes/#{remote}/* && git fetch -q #{remote} && git fetch --tags -q username && git reset -q --hard #{rev} && git clean -q -d -x -f", @source.sync(rev, dest)
152
+ end
153
+
154
+ def test_shallow_clone
155
+ @config[:repository] = "git@somehost.com:project.git"
156
+ @config[:git_shallow_clone] = 1
157
+ @config[:branch] = nil
158
+ dest = "/var/www"
159
+ rev = 'c2d9e79'
160
+ assert_equal "git clone -q --depth 1 git@somehost.com:project.git /var/www && cd /var/www && git checkout -q -b deploy #{rev}", @source.checkout(rev, dest)
161
+ end
162
+
163
+ def test_shallow_clone_with_branch
164
+ @config[:repository] = "git@somehost.com:project.git"
165
+ @config[:git_shallow_clone] = 1
166
+ @config[:branch] = 'foobar'
167
+ dest = "/var/www"
168
+ rev = 'c2d9e79'
169
+ assert_equal "git clone -q -b foobar --depth 1 git@somehost.com:project.git /var/www && cd /var/www && git checkout -q -b deploy #{rev}", @source.checkout(rev, dest)
170
+ end
171
+
172
+ def test_remote_clone
173
+ @config[:repository] = "git@somehost.com:project.git"
174
+ @config[:remote] = "username"
175
+ dest = "/var/www"
176
+ rev = 'c2d9e79'
177
+ assert_equal "git clone -q -o username git@somehost.com:project.git /var/www && cd /var/www && git checkout -q -b deploy #{rev}", @source.checkout(rev, dest)
178
+ end
179
+
180
+ def test_remote_clone_with_submodules
181
+ @config[:repository] = "git@somehost.com:project.git"
182
+ @config[:remote] = "username"
183
+ @config[:git_enable_submodules] = true
184
+ dest = "/var/www"
185
+ rev = 'c2d9e79'
186
+ assert_equal "git clone -q -o username git@somehost.com:project.git /var/www && cd /var/www && git checkout -q -b deploy #{rev} && git submodule -q init && git submodule -q sync && export GIT_RECURSIVE=$([ ! \"`git --version`\" \\< \"git version 1.6.5\" ] && echo --recursive) && git submodule -q update --init $GIT_RECURSIVE", @source.checkout(rev, dest)
187
+ end
188
+
189
+ # Tests from base_test.rb, makin' sure we didn't break anything up there!
190
+ def test_command_should_default_to_default_command
191
+ assert_equal "git", @source.command
192
+ @source.local { assert_equal "git", @source.command }
193
+ end
194
+
195
+ def test_command_should_use_scm_command_if_available
196
+ @config[:scm_command] = "/opt/local/bin/git"
197
+ assert_equal "/opt/local/bin/git", @source.command
198
+ end
199
+
200
+ def test_command_should_use_scm_command_in_local_mode_if_local_scm_command_not_set
201
+ @config[:scm_command] = "/opt/local/bin/git"
202
+ @source.local { assert_equal "/opt/local/bin/git", @source.command }
203
+ end
204
+
205
+ def test_command_should_use_local_scm_command_in_local_mode_if_local_scm_command_is_set
206
+ @config[:scm_command] = "/opt/local/bin/git"
207
+ @config[:local_scm_command] = "/usr/local/bin/git"
208
+ assert_equal "/opt/local/bin/git", @source.command
209
+ @source.local { assert_equal "/usr/local/bin/git", @source.command }
210
+ end
211
+
212
+ def test_command_should_use_default_if_scm_command_is_default
213
+ @config[:scm_command] = :default
214
+ assert_equal "git", @source.command
215
+ end
216
+
217
+ def test_command_should_use_default_in_local_mode_if_local_scm_command_is_default
218
+ @config[:scm_command] = "/foo/bar/git"
219
+ @config[:local_scm_command] = :default
220
+ @source.local { assert_equal "git", @source.command }
221
+ end
222
+
223
+ def test_local_mode_proxy_should_treat_messages_as_being_in_local_mode
224
+ @config[:scm_command] = "/foo/bar/git"
225
+ @config[:local_scm_command] = :default
226
+ assert_equal "git", @source.local.command
227
+ assert_equal "/foo/bar/git", @source.command
228
+ end
229
+
230
+ def test_prompt_password
231
+ require 'minestrone/logger'
232
+ require 'minestrone/cli'
233
+ Minestrone::CLI.stubs(:password_prompt).returns("opensesame")
234
+
235
+ text = 'password:'
236
+ assert_equal %("opensesame"\n), @source.handle_data(mock_state, :test_stream, text)
237
+ end
238
+
239
+ def test_sends_passphrase_if_set
240
+ require 'minestrone/logger'
241
+ text = "passphrase:"
242
+ @config[:scm_passphrase] = "opensesame"
243
+ assert_equal %("opensesame"\n), @source.handle_data(mock_state, :test_stream, text)
244
+ end
245
+
246
+ def test_prompt_passphrase
247
+ require 'minestrone/logger'
248
+ require 'minestrone/cli'
249
+ Minestrone::CLI.stubs(:password_prompt).returns("opensesame")
250
+
251
+ text = 'passphrase:'
252
+ assert_equal %("opensesame"\n), @source.handle_data(mock_state, :test_stream, text)
253
+ end
254
+
255
+ private
256
+
257
+ def mock_state
258
+ { :channel => { :host => "abc" } }
259
+ end
260
+ end
@@ -0,0 +1,26 @@
1
+ require 'utils'
2
+ require 'minestrone/recipes/deploy/scm/none'
3
+
4
+ class DeploySCMNoneTest < Test::Unit::TestCase
5
+ class TestSCM < Minestrone::Deploy::SCM::None
6
+ default_command 'none'
7
+ end
8
+
9
+ def setup
10
+ @config = {}
11
+ def @config.exists?(name); key?(name); end
12
+ @source = TestSCM.new(@config)
13
+ end
14
+
15
+ def test_the_truth
16
+ assert true
17
+ end
18
+
19
+ def test_checkout
20
+ @config[:repository] = '.'
21
+ rev = ''
22
+ dest = '/var/www'
23
+ assert_equal "cp -R . /var/www", @source.checkout(rev, dest)
24
+ end
25
+
26
+ end
@@ -0,0 +1,360 @@
1
+ require "utils"
2
+ require 'minestrone/logger'
3
+ require 'minestrone/recipes/deploy/strategy/copy'
4
+ require 'stringio'
5
+
6
+ class DeployStrategyCopyTest < Test::Unit::TestCase
7
+ def setup
8
+ @config = { :application => "captest",
9
+ :releases_path => "/u/apps/test/releases",
10
+ :release_path => "/u/apps/test/releases/1234567890",
11
+ :real_revision => "154" }
12
+ @config.stubs(:logger).returns(stub_everything)
13
+
14
+ @source = mock("source")
15
+ @config.stubs(:source).returns(@source)
16
+ @strategy = Minestrone::Deploy::Strategy::Copy.new(@config)
17
+ end
18
+
19
+ def test_deploy_with_defaults_should_use_remote_gtar
20
+ @config[:copy_remote_tar] = 'gtar'
21
+
22
+ Dir.expects(:tmpdir).returns("/temp/dir")
23
+ @source.expects(:checkout).with("154", "/temp/dir/1234567890").returns(:local_checkout)
24
+ @strategy.expects(:system).with(:local_checkout)
25
+
26
+ Dir.expects(:chdir).with("/temp/dir").yields
27
+ @strategy.expects(:system).with("tar czf 1234567890.tar.gz 1234567890")
28
+ @strategy.expects(:upload).with("/temp/dir/1234567890.tar.gz", "/tmp/1234567890.tar.gz")
29
+ @strategy.expects(:run).with("cd /u/apps/test/releases && gtar xzf /tmp/1234567890.tar.gz && rm /tmp/1234567890.tar.gz")
30
+
31
+ mock_file = mock("file")
32
+ mock_file.expects(:puts).with("154")
33
+ File.expects(:open).with("/temp/dir/1234567890/REVISION", "w").yields(mock_file)
34
+
35
+ FileUtils.expects(:rm).with("/temp/dir/1234567890.tar.gz")
36
+ FileUtils.expects(:rm_rf).with("/temp/dir/1234567890")
37
+
38
+ @strategy.deploy!
39
+ end
40
+
41
+ def test_deploy_with_defaults_should_use_local_gtar
42
+ @config[:copy_local_tar] = 'gtar'
43
+
44
+ Dir.expects(:tmpdir).returns("/temp/dir")
45
+ @source.expects(:checkout).with("154", "/temp/dir/1234567890").returns(:local_checkout)
46
+ @strategy.expects(:system).with(:local_checkout)
47
+
48
+ Dir.expects(:chdir).with("/temp/dir").yields
49
+ @strategy.expects(:system).with("gtar czf 1234567890.tar.gz 1234567890")
50
+ @strategy.expects(:upload).with("/temp/dir/1234567890.tar.gz", "/tmp/1234567890.tar.gz")
51
+ @strategy.expects(:run).with("cd /u/apps/test/releases && tar xzf /tmp/1234567890.tar.gz && rm /tmp/1234567890.tar.gz")
52
+
53
+ mock_file = mock("file")
54
+ mock_file.expects(:puts).with("154")
55
+ File.expects(:open).with("/temp/dir/1234567890/REVISION", "w").yields(mock_file)
56
+
57
+ FileUtils.expects(:rm).with("/temp/dir/1234567890.tar.gz")
58
+ FileUtils.expects(:rm_rf).with("/temp/dir/1234567890")
59
+
60
+ @strategy.deploy!
61
+ end
62
+
63
+ def test_deploy_with_defaults_should_use_tar_gz_and_checkout
64
+ Dir.expects(:tmpdir).returns("/temp/dir")
65
+ @source.expects(:checkout).with("154", "/temp/dir/1234567890").returns(:local_checkout)
66
+ @strategy.expects(:system).with(:local_checkout)
67
+
68
+ prepare_standard_compress_and_copy!
69
+ @strategy.deploy!
70
+ end
71
+
72
+ def test_deploy_with_exclusions_should_remove_patterns_from_destination
73
+ @config[:copy_exclude] = ".git"
74
+ Dir.expects(:tmpdir).returns("/temp/dir")
75
+ @source.expects(:checkout).with("154", "/temp/dir/1234567890").returns(:local_checkout)
76
+ @strategy.expects(:system).with(:local_checkout)
77
+ Dir.expects(:glob).with("/temp/dir/1234567890/.git", File::FNM_DOTMATCH).returns(%w(/temp/dir/1234567890/.git))
78
+
79
+ FileUtils.expects(:rm_rf).with(%w(/temp/dir/1234567890/.git))
80
+ prepare_standard_compress_and_copy!
81
+ @strategy.deploy!
82
+ end
83
+
84
+ def test_deploy_with_exclusions_should_remove_glob_patterns_from_destination
85
+ @config[:copy_exclude] = ".gi*"
86
+ Dir.expects(:tmpdir).returns("/temp/dir")
87
+ @source.expects(:checkout).with("154", "/temp/dir/1234567890").returns(:local_checkout)
88
+ @strategy.expects(:system).with(:local_checkout)
89
+ Dir.expects(:glob).with("/temp/dir/1234567890/.gi*", File::FNM_DOTMATCH).returns(%w(/temp/dir/1234567890/.git))
90
+
91
+ FileUtils.expects(:rm_rf).with(%w(/temp/dir/1234567890/.git))
92
+ prepare_standard_compress_and_copy!
93
+ @strategy.deploy!
94
+ end
95
+
96
+ def test_deploy_with_export_should_use_tar_gz_and_export
97
+ Dir.expects(:tmpdir).returns("/temp/dir")
98
+ @config[:copy_strategy] = :export
99
+ @source.expects(:export).with("154", "/temp/dir/1234567890").returns(:local_export)
100
+ @strategy.expects(:system).with(:local_export)
101
+
102
+ prepare_standard_compress_and_copy!
103
+ @strategy.deploy!
104
+ end
105
+
106
+ def test_deploy_with_zip_should_use_zip_and_checkout
107
+ Dir.expects(:tmpdir).returns("/temp/dir")
108
+ Dir.expects(:chdir).with("/temp/dir").yields
109
+ @config[:copy_compression] = :zip
110
+ @source.expects(:checkout).with("154", "/temp/dir/1234567890").returns(:local_checkout)
111
+
112
+ @strategy.expects(:system).with(:local_checkout)
113
+ @strategy.expects(:system).with("zip -qyr 1234567890.zip 1234567890")
114
+ @strategy.expects(:upload).with("/temp/dir/1234567890.zip", "/tmp/1234567890.zip")
115
+ @strategy.expects(:run).with("cd /u/apps/test/releases && unzip -q /tmp/1234567890.zip && rm /tmp/1234567890.zip")
116
+
117
+ mock_file = mock("file")
118
+ mock_file.expects(:puts).with("154")
119
+ File.expects(:open).with("/temp/dir/1234567890/REVISION", "w").yields(mock_file)
120
+
121
+ FileUtils.expects(:rm).with("/temp/dir/1234567890.zip")
122
+ FileUtils.expects(:rm_rf).with("/temp/dir/1234567890")
123
+
124
+ @strategy.deploy!
125
+ end
126
+
127
+ def test_deploy_with_bzip2_should_use_bz2_and_checkout
128
+ Dir.expects(:tmpdir).returns("/temp/dir")
129
+ Dir.expects(:chdir).with("/temp/dir").yields
130
+ @config[:copy_compression] = :bzip2
131
+ @source.expects(:checkout).with("154", "/temp/dir/1234567890").returns(:local_checkout)
132
+
133
+ @strategy.expects(:system).with(:local_checkout)
134
+ @strategy.expects(:system).with("tar cjf 1234567890.tar.bz2 1234567890")
135
+ @strategy.expects(:upload).with("/temp/dir/1234567890.tar.bz2", "/tmp/1234567890.tar.bz2")
136
+ @strategy.expects(:run).with("cd /u/apps/test/releases && tar xjf /tmp/1234567890.tar.bz2 && rm /tmp/1234567890.tar.bz2")
137
+
138
+ mock_file = mock("file")
139
+ mock_file.expects(:puts).with("154")
140
+ File.expects(:open).with("/temp/dir/1234567890/REVISION", "w").yields(mock_file)
141
+
142
+ FileUtils.expects(:rm).with("/temp/dir/1234567890.tar.bz2")
143
+ FileUtils.expects(:rm_rf).with("/temp/dir/1234567890")
144
+
145
+ @strategy.deploy!
146
+ end
147
+
148
+ def test_deploy_with_unknown_compression_type_should_error
149
+ @config[:copy_compression] = :bogus
150
+ Dir.expects(:tmpdir).returns("/temp/dir")
151
+ @source.expects(:checkout).with("154", "/temp/dir/1234567890").returns(:local_checkout)
152
+ @strategy.stubs(:system)
153
+ File.stubs(:open)
154
+
155
+ assert_raises(ArgumentError) { @strategy.deploy! }
156
+ end
157
+
158
+ def test_deploy_with_custom_copy_dir_should_use_that_as_tmpdir
159
+ Dir.expects(:tmpdir).never
160
+ Dir.expects(:chdir).with("/other/path").yields
161
+ @config[:copy_dir] = "/other/path"
162
+ @source.expects(:checkout).with("154", "/other/path/1234567890").returns(:local_checkout)
163
+
164
+ @strategy.expects(:system).with(:local_checkout)
165
+ @strategy.expects(:system).with("tar czf 1234567890.tar.gz 1234567890")
166
+ @strategy.expects(:upload).with("/other/path/1234567890.tar.gz", "/tmp/1234567890.tar.gz")
167
+ @strategy.expects(:run).with("cd /u/apps/test/releases && tar xzf /tmp/1234567890.tar.gz && rm /tmp/1234567890.tar.gz")
168
+
169
+ mock_file = mock("file")
170
+ mock_file.expects(:puts).with("154")
171
+ File.expects(:open).with("/other/path/1234567890/REVISION", "w").yields(mock_file)
172
+
173
+ FileUtils.expects(:rm).with("/other/path/1234567890.tar.gz")
174
+ FileUtils.expects(:rm_rf).with("/other/path/1234567890")
175
+
176
+ @strategy.deploy!
177
+ end
178
+
179
+ def test_deploy_with_copy_remote_dir_should_copy_to_that_dir
180
+ @config[:copy_remote_dir] = "/somewhere/else"
181
+ Dir.expects(:tmpdir).returns("/temp/dir")
182
+ Dir.expects(:chdir).yields
183
+ @source.expects(:checkout).returns(:local_checkout)
184
+
185
+ @strategy.expects(:system).with(:local_checkout)
186
+ @strategy.expects(:system).with("tar czf 1234567890.tar.gz 1234567890")
187
+ @strategy.expects(:upload).with("/temp/dir/1234567890.tar.gz", "/somewhere/else/1234567890.tar.gz")
188
+ @strategy.expects(:run).with("cd /u/apps/test/releases && tar xzf /somewhere/else/1234567890.tar.gz && rm /somewhere/else/1234567890.tar.gz")
189
+
190
+ mock_file = mock("file")
191
+ mock_file.expects(:puts).with("154")
192
+ File.expects(:open).with("/temp/dir/1234567890/REVISION", "w").yields(mock_file)
193
+
194
+ FileUtils.expects(:rm).with("/temp/dir/1234567890.tar.gz")
195
+ FileUtils.expects(:rm_rf).with("/temp/dir/1234567890")
196
+
197
+ @strategy.deploy!
198
+ end
199
+
200
+ def test_deploy_with_copy_via_should_use_the_given_transfer_method
201
+ @config[:copy_via] = :scp
202
+ Dir.expects(:tmpdir).returns("/temp/dir")
203
+ Dir.expects(:chdir).yields
204
+ @source.expects(:checkout).returns(:local_checkout)
205
+
206
+ @strategy.expects(:system).with(:local_checkout)
207
+ @strategy.expects(:system).with("tar czf 1234567890.tar.gz 1234567890")
208
+ @strategy.expects(:upload).with("/temp/dir/1234567890.tar.gz", "/tmp/1234567890.tar.gz", {:via => :scp})
209
+ @strategy.expects(:run).with("cd /u/apps/test/releases && tar xzf /tmp/1234567890.tar.gz && rm /tmp/1234567890.tar.gz")
210
+
211
+ mock_file = mock("file")
212
+ mock_file.expects(:puts).with("154")
213
+ File.expects(:open).with("/temp/dir/1234567890/REVISION", "w").yields(mock_file)
214
+
215
+ FileUtils.expects(:rm).with("/temp/dir/1234567890.tar.gz")
216
+ FileUtils.expects(:rm_rf).with("/temp/dir/1234567890")
217
+
218
+ @strategy.deploy!
219
+ end
220
+
221
+ def test_with_copy_cache_should_checkout_to_cache_if_cache_does_not_exist_and_then_copy
222
+ @config[:copy_cache] = true
223
+
224
+ Dir.stubs(:tmpdir).returns("/temp/dir")
225
+ File.expects(:exist?).with("/temp/dir/captest").returns(false)
226
+ Dir.expects(:chdir).with("/temp/dir/captest").yields
227
+
228
+ @source.expects(:checkout).with("154", "/temp/dir/captest").returns(:local_checkout)
229
+ @strategy.expects(:system).with(:local_checkout)
230
+
231
+ FileUtils.expects(:mkdir_p).with("/temp/dir/1234567890")
232
+
233
+ prepare_directory_tree!("/temp/dir/captest")
234
+
235
+ prepare_standard_compress_and_copy!
236
+ @strategy.deploy!
237
+ end
238
+
239
+ def test_with_copy_cache_should_update_cache_if_cache_exists_and_then_copy
240
+ @config[:copy_cache] = true
241
+
242
+ Dir.stubs(:tmpdir).returns("/temp/dir")
243
+ File.expects(:exist?).with("/temp/dir/captest").returns(true)
244
+ Dir.expects(:chdir).with("/temp/dir/captest").yields
245
+
246
+ @source.expects(:sync).with("154", "/temp/dir/captest").returns(:local_sync)
247
+ @strategy.expects(:system).with(:local_sync)
248
+
249
+ FileUtils.expects(:mkdir_p).with("/temp/dir/1234567890")
250
+
251
+ prepare_directory_tree!("/temp/dir/captest")
252
+
253
+ prepare_standard_compress_and_copy!
254
+ @strategy.deploy!
255
+ end
256
+
257
+ def test_with_copy_cache_with_custom_absolute_cache_dir_path_should_use_specified_cache_dir
258
+ @config[:copy_cache] = "/u/caches/captest"
259
+
260
+ Dir.stubs(:tmpdir).returns("/temp/dir")
261
+ File.expects(:exist?).with("/u/caches/captest").returns(true)
262
+ Dir.expects(:chdir).with("/u/caches/captest").yields
263
+
264
+ @source.expects(:sync).with("154", "/u/caches/captest").returns(:local_sync)
265
+ @strategy.expects(:system).with(:local_sync)
266
+
267
+ FileUtils.expects(:mkdir_p).with("/temp/dir/1234567890")
268
+
269
+ prepare_directory_tree!("/u/caches/captest")
270
+
271
+ prepare_standard_compress_and_copy!
272
+ @strategy.deploy!
273
+ end
274
+
275
+ def test_with_copy_cache_with_custom_relative_cache_dir_path_should_use_specified_cache_dir
276
+ @config[:copy_cache] = "caches/captest"
277
+
278
+ Dir.stubs(:pwd).returns("/u")
279
+ Dir.stubs(:tmpdir).returns("/temp/dir")
280
+ File.expects(:exist?).with("/u/caches/captest").returns(true)
281
+ Dir.expects(:chdir).with("/u/caches/captest").yields
282
+
283
+ @source.expects(:sync).with("154", "/u/caches/captest").returns(:local_sync)
284
+ @strategy.expects(:system).with(:local_sync)
285
+
286
+ FileUtils.expects(:mkdir_p).with("/temp/dir/1234567890")
287
+
288
+ prepare_directory_tree!("/u/caches/captest")
289
+
290
+ prepare_standard_compress_and_copy!
291
+ @strategy.deploy!
292
+ end
293
+
294
+ def test_with_copy_cache_with_excludes_should_not_copy_excluded_files
295
+ @config[:copy_cache] = true
296
+ @config[:copy_exclude] = "*/bar.txt"
297
+
298
+ Dir.stubs(:tmpdir).returns("/temp/dir")
299
+ File.expects(:exist?).with("/temp/dir/captest").returns(true)
300
+ Dir.expects(:chdir).with("/temp/dir/captest").yields
301
+
302
+ @source.expects(:sync).with("154", "/temp/dir/captest").returns(:local_sync)
303
+ @strategy.expects(:system).with(:local_sync)
304
+
305
+ FileUtils.expects(:mkdir_p).with("/temp/dir/1234567890")
306
+
307
+ prepare_directory_tree!("/temp/dir/captest", true)
308
+
309
+ prepare_standard_compress_and_copy!
310
+ @strategy.deploy!
311
+ end
312
+
313
+ def test_with_build_script_should_run_script
314
+ @config[:build_script] = "mkdir bin"
315
+
316
+ Dir.expects(:tmpdir).returns("/temp/dir")
317
+ @source.expects(:checkout).with("154", "/temp/dir/1234567890").returns(:local_checkout)
318
+ @strategy.expects(:system).with(:local_checkout)
319
+
320
+ Dir.expects(:chdir).with("/temp/dir/1234567890").yields
321
+ @strategy.expects(:system).with("mkdir bin")
322
+
323
+ prepare_standard_compress_and_copy!
324
+ @strategy.deploy!
325
+ end
326
+
327
+ private
328
+
329
+ def prepare_directory_tree!(cache, exclude = false)
330
+ Dir.expects(:glob).with("*", File::FNM_DOTMATCH).returns([".", "..", "app", "app{1}", "foo.txt"])
331
+ File.expects(:ftype).with("app").returns("directory")
332
+ File.expects(:ftype).with("app{1}").returns("directory")
333
+ FileUtils.expects(:mkdir).with("/temp/dir/1234567890/app")
334
+ FileUtils.expects(:mkdir).with("/temp/dir/1234567890/app{1}")
335
+ File.expects(:ftype).with("foo.txt").returns("file")
336
+ FileUtils.expects(:ln).with("foo.txt", "/temp/dir/1234567890/foo.txt")
337
+
338
+ Dir.expects(:glob).with("app/*", File::FNM_DOTMATCH).returns(["app/.", "app/..", "app/bar.txt"])
339
+ Dir.expects(:glob).with("app\\{1\\}/*", File::FNM_DOTMATCH).returns(["app{1}/.", "app{1}/.."])
340
+
341
+ unless exclude
342
+ File.expects(:ftype).with("app/bar.txt").returns("file")
343
+ FileUtils.expects(:ln).with("app/bar.txt", "/temp/dir/1234567890/app/bar.txt")
344
+ end
345
+ end
346
+
347
+ def prepare_standard_compress_and_copy!
348
+ Dir.expects(:chdir).with("/temp/dir").yields
349
+ @strategy.expects(:system).with("tar czf 1234567890.tar.gz 1234567890")
350
+ @strategy.expects(:upload).with("/temp/dir/1234567890.tar.gz", "/tmp/1234567890.tar.gz")
351
+ @strategy.expects(:run).with("cd /u/apps/test/releases && tar xzf /tmp/1234567890.tar.gz && rm /tmp/1234567890.tar.gz")
352
+
353
+ mock_file = mock("file")
354
+ mock_file.expects(:puts).with("154")
355
+ File.expects(:open).with("/temp/dir/1234567890/REVISION", "w").yields(mock_file)
356
+
357
+ FileUtils.expects(:rm).with("/temp/dir/1234567890.tar.gz")
358
+ FileUtils.expects(:rm_rf).with("/temp/dir/1234567890")
359
+ end
360
+ end