capistrano 3.0.0.pre2 → 3.0.0.pre3

Sign up to get free protection for your applications and to get access to all the features.
@@ -34,5 +34,7 @@ module Capistrano
34
34
  def local_user
35
35
  `whoami`
36
36
  end
37
+
37
38
  end
38
39
  end
40
+ self.extend Capistrano::DSL
@@ -12,7 +12,7 @@ module Capistrano
12
12
 
13
13
  def any?(key)
14
14
  value = fetch(key)
15
- if value.respond_to?(:any)
15
+ if value && value.respond_to?(:any?)
16
16
  value.any?
17
17
  else
18
18
  !fetch(key).nil?
@@ -27,8 +27,12 @@ module Capistrano
27
27
  env.ask(key, value)
28
28
  end
29
29
 
30
- def role(name, servers)
31
- env.role(name, servers)
30
+ def role(name, servers, options={})
31
+ env.role(name, servers, options)
32
+ end
33
+
34
+ def server(name, properties={})
35
+ env.server(name, properties)
32
36
  end
33
37
 
34
38
  def roles(*names)
@@ -54,4 +58,3 @@ module Capistrano
54
58
  end
55
59
  end
56
60
  end
57
-
@@ -13,11 +13,12 @@ en = {
13
13
  stage_not_set: 'Stage not set, please call something such as `cap production deploy`, where production is a stage you have defined.',
14
14
  written_file: 'create %{file}',
15
15
  question: 'Please enter %{key}: |%{default_value}|',
16
- keeping_releases: 'Keeping %{keep_releases} of %{releases} deployed releases',
16
+ keeping_releases: 'Keeping %{keep_releases} of %{releases} deployed releases on %{host}',
17
17
  linked_file_does_not_exist: 'linked file %{file} does not exist on %{host}',
18
18
  mirror_exists: "The repository mirror is at %{at}",
19
19
  revision_log_message: 'Branch %{branch} deployed as release %{release} by %{user}',
20
20
  rollback_log_message: '%{user} rolled back to release %{release}',
21
+ filter_removes_all_servers: 'Your filter `:%{filter}` would remove all matching servers',
21
22
  console: {
22
23
  welcome: 'capistrano console - enter command to execute on %{stage}',
23
24
  bye: 'bye'
@@ -112,13 +112,10 @@ namespace :deploy do
112
112
 
113
113
  desc 'Clean up old releases'
114
114
  task :cleanup do
115
- releases = on primary :app do
116
- capture(:ls, '-xt', releases_path).split.reverse
117
- end
118
-
119
- on roles :all do
115
+ on roles :all do |host|
116
+ releases = capture(:ls, '-xt', releases_path).split.reverse
120
117
  if releases.count >= fetch(:keep_releases)
121
- info t(:keeping_releases, keep_releases: fetch(:keep_releases), releases: releases.count)
118
+ info t(:keeping_releases, host: host.to_s, keep_releases: fetch(:keep_releases), releases: releases.count)
122
119
  directories = (releases - releases.last(fetch(:keep_releases))).map { |release|
123
120
  releases_path.join(release) }.join(" ")
124
121
  execute :rm, '-rf', directories
@@ -8,10 +8,14 @@ require 'capistrano/deploy'
8
8
  #
9
9
  # For documentation on these, see for example:
10
10
  #
11
+ # https://github.com/capistrano/rvm
12
+ # https://github.com/capistrano/rbenv
11
13
  # https://github.com/capistrano/bundler
12
14
  # https://github.com/capistrano/rails/tree/master/assets
13
15
  # https://github.com/capistrano/rails/tree/master/migrations
14
16
  #
17
+ # require 'capistrano/rvm'
18
+ # require 'capistrano/rbenv'
15
19
  # require 'capistrano/bundler'
16
20
  # require 'capistrano/rails/assets'
17
21
  # require 'capistrano/rails/migrations'
@@ -1,3 +1,3 @@
1
1
  module Capistrano
2
- VERSION = "3.0.0.pre2"
2
+ VERSION = "3.0.0.pre3"
3
3
  end
@@ -0,0 +1,34 @@
1
+ require 'integration_spec_helper'
2
+
3
+ describe 'cap deploy:finished', slow: true do
4
+ before do
5
+ install_test_app_with(config)
6
+ end
7
+
8
+ describe 'deploy' do
9
+ let(:config) {
10
+ %{
11
+ set :stage, :#{stage}
12
+ set :deploy_to, '#{deploy_to}'
13
+ set :repo, 'git://github.com/capistrano/capistrano.git'
14
+ set :branch, 'v3'
15
+ server 'localhost', roles: %w{web app}, user: '#{current_user}'
16
+ set :linked_files, %w{config/database.yml}
17
+ set :linked_dirs, %w{bin log public/system vendor/bundle}
18
+ }
19
+ }
20
+
21
+ describe 'log_revision' do
22
+ before do
23
+ cap 'deploy:started'
24
+ cap 'deploy:update'
25
+ cap 'deploy:finalize'
26
+ cap 'deploy:finished'
27
+ end
28
+
29
+ it 'writes the log file' do
30
+ expect(deploy_to.join('revisions.log')).to be_a_file
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,36 @@
1
+ require 'integration_spec_helper'
2
+
3
+ describe 'cap deploy:finished', slow: true do
4
+ before do
5
+ install_test_app_with(config)
6
+ end
7
+
8
+ describe 'deploy' do
9
+ let(:config) {
10
+ %{
11
+ set :stage, :#{stage}
12
+ set :deploy_to, '#{deploy_to}'
13
+ set :repo, 'git://github.com/capistrano/capistrano.git'
14
+ set :branch, 'v3'
15
+ server 'localhost', roles: %w{web app}, user: '#{current_user}'
16
+ set :linked_files, %w{config/database.yml}
17
+ set :linked_dirs, %w{bin log public/system vendor/bundle}
18
+ }
19
+ }
20
+
21
+ describe 'symlink' do
22
+ before do
23
+ cap 'deploy:started'
24
+ cap 'deploy:update'
25
+ cap 'deploy:finalize'
26
+ end
27
+
28
+ describe 'release' do
29
+ it 'symlinks the release to `current`' do
30
+ expect(File.symlink?(current_path)).to be_true
31
+ expect(File.readlink(current_path)).to match /\/tmp\/test_app\/deploy_to\/releases\/\d{14}/
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,74 @@
1
+ require 'integration_spec_helper'
2
+
3
+ describe 'cap deploy:started', slow: true do
4
+ before do
5
+ install_test_app_with(config)
6
+ end
7
+
8
+ describe 'deploy:check' do
9
+ let(:config) {
10
+ %{
11
+ set :stage, :#{stage}
12
+ set :deploy_to, '#{deploy_to}'
13
+ set :repo, 'git://github.com/capistrano/capistrano.git'
14
+ set :branch, 'v3'
15
+ server 'localhost', roles: %w{web app}, user: '#{current_user}'
16
+ set :linked_files, %w{config/database.yml}
17
+ set :linked_dirs, %w{bin log public/system vendor/bundle}
18
+ }
19
+ }
20
+
21
+ describe 'directories' do
22
+ before do
23
+ cap 'deploy:check:directories'
24
+ end
25
+
26
+ it 'ensures the directory structure' do
27
+ expect(shared_path).to be_a_directory
28
+ expect(releases_path).to be_a_directory
29
+ end
30
+ end
31
+
32
+ describe 'linked_dirs' do
33
+ before do
34
+ cap 'deploy:check:linked_dirs'
35
+ end
36
+
37
+ it 'ensure directories to be linked in `shared`' do
38
+ [
39
+ shared_path.join('bin'),
40
+ shared_path.join('log'),
41
+ shared_path.join('public/system'),
42
+ shared_path.join('vendor/bundle'),
43
+ ].each do |dir|
44
+ expect(dir).to be_a_directory
45
+ end
46
+ end
47
+ end
48
+
49
+ describe 'linked_files' do
50
+
51
+ subject { cap 'deploy:check:linked_files' }
52
+
53
+ context 'file does not exist' do
54
+ it 'fails' do
55
+ expect(subject).to match 'config/database.yml does not exist'
56
+ end
57
+ end
58
+
59
+ context 'file exists' do
60
+ before do
61
+ create_shared_directory('config')
62
+ create_shared_file('config/database.yml')
63
+ end
64
+
65
+ it 'suceeds' do
66
+ expect(subject).not_to match 'config/database.yml does not exist'
67
+ expect(subject).to match 'successful'
68
+ end
69
+
70
+ end
71
+ end
72
+ end
73
+ end
74
+
@@ -0,0 +1,45 @@
1
+ require 'integration_spec_helper'
2
+
3
+ describe 'cap deploy:update', slow: true do
4
+ before do
5
+ install_test_app_with(config)
6
+ end
7
+
8
+ describe 'deploy' do
9
+ let(:config) {
10
+ %{
11
+ set :stage, :#{stage}
12
+ set :deploy_to, '#{deploy_to}'
13
+ set :repo, 'git://github.com/capistrano/capistrano.git'
14
+ set :branch, 'v3'
15
+ server 'localhost', roles: %w{web app}, user: '#{current_user}'
16
+ set :linked_files, %w{config/database.yml}
17
+ set :linked_dirs, %w{bin log public/system vendor/bundle}
18
+ }
19
+ }
20
+
21
+ describe 'symlink' do
22
+ before do
23
+ cap 'deploy:started'
24
+ create_shared_directory('config')
25
+ create_shared_file('config/database.yml')
26
+ cap 'deploy:symlink:shared'
27
+ end
28
+
29
+ describe 'linked_dirs' do
30
+ it 'symlinks the directories in shared to `current`' do
31
+ %w{bin log public/system vendor/bundle}.each do |dir|
32
+ expect(release_path.join(dir)).to be_a_symlink_to shared_path.join(dir)
33
+ end
34
+ end
35
+ end
36
+
37
+ describe 'linked_files' do
38
+ it 'symlinks the files in shared to `current`' do
39
+ file = 'config/database.yml'
40
+ expect(release_path.join(file)).to be_a_symlink_to shared_path.join(file)
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,254 @@
1
+ require 'spec_helper'
2
+
3
+ describe Capistrano::DSL do
4
+
5
+ let(:dsl) { Class.new.extend Capistrano::DSL }
6
+
7
+ describe 'setting and fetching hosts' do
8
+ describe 'when defining a host using the `server` syntax' do
9
+ before do
10
+ dsl.server 'example1.com', roles: %w{web}, active: true
11
+ dsl.server 'example2.com', roles: %w{web}
12
+ dsl.server 'example3.com', roles: %w{app web}, active: true
13
+ dsl.server 'example4.com', roles: %w{app}, primary: true
14
+ end
15
+
16
+ describe 'fetching all servers' do
17
+ subject { dsl.roles(:all) }
18
+
19
+ it 'returns all servers' do
20
+ expect(subject.map(&:hostname)).to eq %w{example1.com example2.com example3.com example4.com}
21
+ end
22
+ end
23
+
24
+ describe 'fetching servers by role' do
25
+ subject { dsl.roles(:app) }
26
+
27
+ it 'returns the servers' do
28
+ expect(subject.map(&:hostname)).to eq %w{example3.com example4.com}
29
+ end
30
+ end
31
+
32
+ describe 'fetching filtered servers by role' do
33
+ subject { dsl.roles(:app, filter: :active) }
34
+
35
+ it 'returns the servers' do
36
+ expect(subject.map(&:hostname)).to eq %w{example3.com}
37
+ end
38
+ end
39
+
40
+ describe 'fetching selected servers by role' do
41
+ subject { dsl.roles(:app, select: :active) }
42
+
43
+ it 'returns the servers' do
44
+ expect(subject.map(&:hostname)).to eq %w{example3.com}
45
+ end
46
+ end
47
+
48
+ describe 'fetching the primary server by role' do
49
+ context 'when inferring primary status based on order' do
50
+ subject { dsl.primary(:web) }
51
+ it 'returns the servers' do
52
+ expect(subject.hostname).to eq 'example1.com'
53
+ end
54
+ end
55
+
56
+ context 'when the attribute `primary` is explicity set' do
57
+ subject { dsl.primary(:app) }
58
+ it 'returns the servers' do
59
+ expect(subject.hostname).to eq 'example4.com'
60
+ end
61
+ end
62
+ end
63
+
64
+ end
65
+
66
+ describe 'when defining hosts using the `role` syntax' do
67
+ before do
68
+ dsl.role :web, %w{example1.com example2.com example3.com}
69
+ dsl.role :web, %w{example1.com}, active: true
70
+ dsl.role :app, %w{example3.com example4.com}
71
+ dsl.role :app, %w{example3.com}, active: true
72
+ dsl.role :app, %w{example4.com}, primary: true
73
+ end
74
+
75
+ describe 'fetching all servers' do
76
+ subject { dsl.roles(:all) }
77
+
78
+ it 'returns all servers' do
79
+ expect(subject.map(&:hostname)).to eq %w{example1.com example2.com example3.com example4.com}
80
+ end
81
+ end
82
+
83
+ describe 'fetching servers by role' do
84
+ subject { dsl.roles(:app) }
85
+
86
+ it 'returns the servers' do
87
+ expect(subject.map(&:hostname)).to eq %w{example3.com example4.com}
88
+ end
89
+ end
90
+
91
+ describe 'fetching filtered servers by role' do
92
+ subject { dsl.roles(:app, filter: :active) }
93
+
94
+ it 'returns the servers' do
95
+ expect(subject.map(&:hostname)).to eq %w{example3.com}
96
+ end
97
+ end
98
+
99
+ describe 'fetching selected servers by role' do
100
+ subject { dsl.roles(:app, select: :active) }
101
+
102
+ it 'returns the servers' do
103
+ expect(subject.map(&:hostname)).to eq %w{example3.com}
104
+ end
105
+ end
106
+
107
+ describe 'fetching the primary server by role' do
108
+ context 'when inferring primary status based on order' do
109
+ subject { dsl.primary(:web) }
110
+ it 'returns the servers' do
111
+ expect(subject.hostname).to eq 'example1.com'
112
+ end
113
+ end
114
+
115
+ context 'when the attribute `primary` is explicity set' do
116
+ subject { dsl.primary(:app) }
117
+ it 'returns the servers' do
118
+ expect(subject.hostname).to eq 'example4.com'
119
+ end
120
+ end
121
+ end
122
+
123
+ end
124
+
125
+ end
126
+
127
+ describe 'setting and fetching variables' do
128
+
129
+ before do
130
+ dsl.set :scm, :git
131
+ end
132
+
133
+ context 'without a default' do
134
+ context 'when the variables is defined' do
135
+ it 'returns the variable' do
136
+ expect(dsl.fetch(:scm)).to eq :git
137
+ end
138
+ end
139
+
140
+ context 'when the variables is undefined' do
141
+ it 'returns nil' do
142
+ expect(dsl.fetch(:source_control)).to be_nil
143
+ end
144
+ end
145
+ end
146
+
147
+ context 'with a default' do
148
+ context 'when the variables is defined' do
149
+ it 'returns the variable' do
150
+ expect(dsl.fetch(:scm, :svn)).to eq :git
151
+ end
152
+ end
153
+
154
+ context 'when the variables is undefined' do
155
+ it 'returns the default' do
156
+ expect(dsl.fetch(:source_control, :svn)).to eq :svn
157
+ end
158
+ end
159
+ end
160
+
161
+ end
162
+
163
+ describe 'asking for a variable' do
164
+ before do
165
+ dsl.ask(:scm, :svn)
166
+ $stdout.stubs(:puts)
167
+ end
168
+
169
+ context 'variable is provided' do
170
+ before do
171
+ $stdin.expects(:gets).returns('git')
172
+ end
173
+
174
+ it 'sets the input as the variable' do
175
+ expect(dsl.fetch(:scm)).to eq 'git'
176
+ end
177
+ end
178
+
179
+ context 'variable is not provided' do
180
+ before do
181
+ $stdin.expects(:gets).returns('')
182
+ end
183
+
184
+ it 'sets the variable as the default' do
185
+ expect(dsl.fetch(:scm)).to eq :svn
186
+ end
187
+ end
188
+ end
189
+
190
+ describe 'checking for presence' do
191
+ subject { dsl.any? :linked_files }
192
+
193
+ before do
194
+ dsl.set(:linked_files, linked_files)
195
+ end
196
+
197
+ context 'variable is an non-empty array' do
198
+ let(:linked_files) { %w{1} }
199
+
200
+ it { should be_true }
201
+ end
202
+
203
+ context 'variable is an empty array' do
204
+ let(:linked_files) { [] }
205
+ it { should be_false }
206
+ end
207
+
208
+ context 'variable exists, is not an array' do
209
+ let(:linked_files) { stub }
210
+ it { should be_true }
211
+ end
212
+
213
+ context 'variable is nil' do
214
+ let(:linked_files) { nil }
215
+ it { should be_false }
216
+ end
217
+ end
218
+
219
+ describe 'configuration SSHKit' do
220
+ let(:config) { SSHKit.config }
221
+ let(:backend) { SSHKit.config.backend.config }
222
+ let(:default_env) { { rails_env: :production } }
223
+
224
+ before do
225
+ dsl.set(:format, :dot)
226
+ dsl.set(:log_level, :debug)
227
+ dsl.set(:default_env, default_env)
228
+ dsl.set(:pty, true)
229
+ dsl.set(:connection_timeout, 10)
230
+ dsl.configure_backend
231
+ end
232
+
233
+ it 'sets the output' do
234
+ expect(config.output).to be_a SSHKit::Formatter::Dot
235
+ end
236
+
237
+ it 'sets the output verbosity' do
238
+ expect(config.output_verbosity).to eq 0
239
+ end
240
+
241
+ it 'sets the default env' do
242
+ expect(config.default_env).to eq default_env
243
+ end
244
+
245
+ it 'sets the backend pty' do
246
+ expect(backend.pty).to be_true
247
+ end
248
+
249
+ it 'sets the backend connection timeout' do
250
+ expect(backend.connection_timeout).to eq 10
251
+ end
252
+ end
253
+
254
+ end