capistrano 3.6.0 → 3.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/issue_template.md +19 -0
- data/.github/pull_request_template.md +26 -0
- data/.gitignore +1 -0
- data/.travis.yml +10 -2
- data/CHANGELOG.md +63 -1
- data/DEVELOPMENT.md +7 -1
- data/Dangerfile +54 -0
- data/README.md +4 -5
- data/capistrano.gemspec +3 -2
- data/features/support/vagrant_helpers.rb +3 -5
- data/lib/capistrano/all.rb +1 -0
- data/lib/capistrano/configuration/host_filter.rb +1 -1
- data/lib/capistrano/configuration/plugin_installer.rb +20 -2
- data/lib/capistrano/configuration/role_filter.rb +1 -1
- data/lib/capistrano/configuration/scm_resolver.rb +144 -0
- data/lib/capistrano/configuration/validated_variables.rb +48 -13
- data/lib/capistrano/configuration/variables.rb +0 -8
- data/lib/capistrano/configuration.rb +30 -3
- data/lib/capistrano/defaults.rb +3 -1
- data/lib/capistrano/doctor/variables_doctor.rb +1 -1
- data/lib/capistrano/dsl/env.rb +2 -9
- data/lib/capistrano/dsl/paths.rb +1 -1
- data/lib/capistrano/dsl/task_enhancements.rb +0 -8
- data/lib/capistrano/dsl.rb +2 -1
- data/lib/capistrano/i18n.rb +1 -0
- data/lib/capistrano/scm/git.rb +73 -0
- data/lib/capistrano/scm/hg.rb +48 -0
- data/lib/capistrano/scm/plugin.rb +13 -0
- data/lib/capistrano/scm/svn.rb +47 -0
- data/lib/capistrano/{tasks → scm/tasks}/git.rake +9 -24
- data/lib/capistrano/{tasks → scm/tasks}/hg.rake +11 -10
- data/lib/capistrano/{tasks → scm/tasks}/svn.rake +11 -10
- data/lib/capistrano/setup.rb +1 -1
- data/lib/capistrano/tasks/deploy.rake +4 -5
- data/lib/capistrano/templates/Capfile +18 -7
- data/lib/capistrano/templates/deploy.rb.erb +7 -10
- data/lib/capistrano/templates/stage.rb.erb +8 -8
- data/lib/capistrano/version.rb +1 -1
- data/lib/capistrano/version_validator.rb +2 -5
- data/spec/lib/capistrano/configuration/host_filter_spec.rb +5 -0
- data/spec/lib/capistrano/configuration/plugin_installer_spec.rb +98 -0
- data/spec/lib/capistrano/configuration/role_filter_spec.rb +17 -1
- data/spec/lib/capistrano/configuration_spec.rb +61 -2
- data/spec/lib/capistrano/doctor/variables_doctor_spec.rb +0 -7
- data/spec/lib/capistrano/dsl/task_enhancements_spec.rb +0 -15
- data/spec/lib/capistrano/scm/git_spec.rb +131 -0
- data/spec/lib/capistrano/scm/hg_spec.rb +104 -0
- data/spec/lib/capistrano/scm/svn_spec.rb +116 -0
- data/spec/lib/capistrano/scm_spec.rb +1 -1
- metadata +37 -19
- data/features/remote_file_task.feature +0 -14
- data/issue_template.md +0 -21
- data/lib/capistrano/git.rb +0 -54
- data/lib/capistrano/hg.rb +0 -43
- data/lib/capistrano/svn.rb +0 -42
- data/spec/lib/capistrano/git_spec.rb +0 -109
- data/spec/lib/capistrano/hg_spec.rb +0 -90
- data/spec/lib/capistrano/svn_spec.rb +0 -105
@@ -3,9 +3,9 @@
|
|
3
3
|
# Defines a single server with a list of roles and multiple properties.
|
4
4
|
# You can define all roles on a single server, or split them:
|
5
5
|
|
6
|
-
# server
|
7
|
-
# server
|
8
|
-
# server
|
6
|
+
# server "example.com", user: "deploy", roles: %w{app db web}, my_property: :my_value
|
7
|
+
# server "example.com", user: "deploy", roles: %w{app web}, other_property: :other_value
|
8
|
+
# server "db.example.com", user: "deploy", roles: %w{db}
|
9
9
|
|
10
10
|
|
11
11
|
|
@@ -13,7 +13,7 @@
|
|
13
13
|
# ==================
|
14
14
|
|
15
15
|
# Defines a role with one or multiple servers. The primary server in each
|
16
|
-
# group is considered to be the first unless any
|
16
|
+
# group is considered to be the first unless any hosts have the primary
|
17
17
|
# property set. Specify the username and a domain or IP for the server.
|
18
18
|
# Don't use `:all`, it's a meta role.
|
19
19
|
|
@@ -49,13 +49,13 @@
|
|
49
49
|
#
|
50
50
|
# The server-based syntax can be used to override options:
|
51
51
|
# ------------------------------------
|
52
|
-
# server
|
53
|
-
# user:
|
52
|
+
# server "example.com",
|
53
|
+
# user: "user_name",
|
54
54
|
# roles: %w{web app},
|
55
55
|
# ssh_options: {
|
56
|
-
# user:
|
56
|
+
# user: "user_name", # overrides user setting above
|
57
57
|
# keys: %w(/home/user_name/.ssh/id_rsa),
|
58
58
|
# forward_agent: false,
|
59
59
|
# auth_methods: %w(publickey password)
|
60
|
-
# # password:
|
60
|
+
# # password: "please use keys"
|
61
61
|
# }
|
data/lib/capistrano/version.rb
CHANGED
@@ -5,11 +5,8 @@ module Capistrano
|
|
5
5
|
end
|
6
6
|
|
7
7
|
def verify
|
8
|
-
if match?
|
9
|
-
|
10
|
-
else
|
11
|
-
raise "Capfile locked at #{version}, but #{current_version} is loaded"
|
12
|
-
end
|
8
|
+
return self if match?
|
9
|
+
raise "Capfile locked at #{version}, but #{current_version} is loaded"
|
13
10
|
end
|
14
11
|
|
15
12
|
private
|
@@ -55,6 +55,11 @@ module Capistrano
|
|
55
55
|
let(:values) { 'server\d{1,3}$' }
|
56
56
|
it_behaves_like "it filters hosts correctly", %w{server1 server2 server3 server4 server5}
|
57
57
|
end
|
58
|
+
|
59
|
+
context "without number" do
|
60
|
+
let(:values) { "server" }
|
61
|
+
it_behaves_like "it filters hosts correctly", %w{}
|
62
|
+
end
|
58
63
|
end
|
59
64
|
end
|
60
65
|
end
|
@@ -0,0 +1,98 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
require "capistrano/plugin"
|
3
|
+
require "capistrano/scm/plugin"
|
4
|
+
|
5
|
+
module Capistrano
|
6
|
+
class Configuration
|
7
|
+
class ExamplePlugin < Capistrano::Plugin
|
8
|
+
def set_defaults
|
9
|
+
set_if_empty :example_variable, "foo"
|
10
|
+
end
|
11
|
+
|
12
|
+
def define_tasks
|
13
|
+
task :example
|
14
|
+
task :example_prerequisite
|
15
|
+
end
|
16
|
+
|
17
|
+
def register_hooks
|
18
|
+
before :example, :example_prerequisite
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
class ExampleSCMPlugin < Capistrano::SCM::Plugin
|
23
|
+
end
|
24
|
+
|
25
|
+
describe PluginInstaller do
|
26
|
+
include Capistrano::DSL
|
27
|
+
|
28
|
+
let(:installer) { PluginInstaller.new }
|
29
|
+
let(:options) { {} }
|
30
|
+
let(:plugin) { ExamplePlugin.new }
|
31
|
+
|
32
|
+
before do
|
33
|
+
installer.install(plugin, **options)
|
34
|
+
end
|
35
|
+
|
36
|
+
after do
|
37
|
+
Rake::Task.clear
|
38
|
+
Capistrano::Configuration.reset!
|
39
|
+
end
|
40
|
+
|
41
|
+
context "installing plugin" do
|
42
|
+
it "defines tasks" do
|
43
|
+
expect(Rake::Task[:example]).to_not be_nil
|
44
|
+
expect(Rake::Task[:example_prerequisite]).to_not be_nil
|
45
|
+
end
|
46
|
+
|
47
|
+
it "registers hooks" do
|
48
|
+
task = Rake::Task[:example]
|
49
|
+
expect(task.prerequisites).to eq([:example_prerequisite])
|
50
|
+
end
|
51
|
+
|
52
|
+
it "sets defaults when load:defaults is invoked" do
|
53
|
+
expect(fetch(:example_variable)).to be_nil
|
54
|
+
invoke "load:defaults"
|
55
|
+
expect(fetch(:example_variable)).to eq("foo")
|
56
|
+
end
|
57
|
+
|
58
|
+
it "doesn't say an SCM is installed" do
|
59
|
+
expect(installer.scm_installed?).to be_falsey
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
context "installing plugin class" do
|
64
|
+
let(:plugin) { ExamplePlugin }
|
65
|
+
|
66
|
+
it "defines tasks" do
|
67
|
+
expect(Rake::Task[:example]).to_not be_nil
|
68
|
+
expect(Rake::Task[:example_prerequisite]).to_not be_nil
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
context "installing plugin without hooks" do
|
73
|
+
let(:options) { { load_hooks: false } }
|
74
|
+
|
75
|
+
it "doesn't register hooks" do
|
76
|
+
task = Rake::Task[:example]
|
77
|
+
expect(task.prerequisites).to be_empty
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
context "installing plugin and loading immediately" do
|
82
|
+
let(:options) { { load_immediately: true } }
|
83
|
+
|
84
|
+
it "sets defaults immediately" do
|
85
|
+
expect(fetch(:example_variable)).to eq("foo")
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
context "installing an SCM plugin" do
|
90
|
+
let(:plugin) { ExampleSCMPlugin }
|
91
|
+
|
92
|
+
it "says an SCM is installed" do
|
93
|
+
expect(installer.scm_installed?).to be_truthy
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
@@ -11,7 +11,8 @@ module Capistrano
|
|
11
11
|
Server.new("server2").add_role(:web),
|
12
12
|
Server.new("server3").add_role(:redis),
|
13
13
|
Server.new("server4").add_role(:db),
|
14
|
-
Server.new("server5").add_role(:stageweb)
|
14
|
+
Server.new("server5").add_role(:stageweb),
|
15
|
+
Server.new("server6").add_role(:"db.new")
|
15
16
|
]
|
16
17
|
end
|
17
18
|
|
@@ -58,6 +59,21 @@ module Capistrano
|
|
58
59
|
let(:values) { "db,/red/" }
|
59
60
|
it_behaves_like "it filters roles correctly", 3, %w{server1 server3 server4}
|
60
61
|
end
|
62
|
+
|
63
|
+
context "with a dot wildcard" do
|
64
|
+
let(:values) { "db.*" }
|
65
|
+
it_behaves_like "it filters roles correctly", 0, %w{}
|
66
|
+
end
|
67
|
+
|
68
|
+
context "with a dot" do
|
69
|
+
let(:values) { "db.new" }
|
70
|
+
it_behaves_like "it filters roles correctly", 1, %w{server6}
|
71
|
+
end
|
72
|
+
|
73
|
+
context "with a dot wildcard regex" do
|
74
|
+
let(:values) { "/db.*/" }
|
75
|
+
it_behaves_like "it filters roles correctly", 3, %w{server1 server4 server6}
|
76
|
+
end
|
61
77
|
end
|
62
78
|
end
|
63
79
|
end
|
@@ -154,19 +154,29 @@ module Capistrano
|
|
154
154
|
config.set(:key, "longer_value")
|
155
155
|
end
|
156
156
|
|
157
|
-
it "validates
|
157
|
+
it "validates block without error" do
|
158
158
|
config.set(:key) { "longer_value" }
|
159
159
|
expect(config.fetch(:key)).to eq "longer_value"
|
160
160
|
end
|
161
161
|
|
162
|
+
it "validates lambda without error" do
|
163
|
+
config.set :key, -> { "longer_value" }
|
164
|
+
expect(config.fetch(:key)).to eq "longer_value"
|
165
|
+
end
|
166
|
+
|
162
167
|
it "raises an exception on invalid string" do
|
163
168
|
expect { config.set(:key, "sho") }.to raise_error(Capistrano::ValidationError)
|
164
169
|
end
|
165
170
|
|
166
|
-
it "raises an exception on invalid string provided by
|
171
|
+
it "raises an exception on invalid string provided by block" do
|
167
172
|
config.set(:key) { "sho" }
|
168
173
|
expect { config.fetch(:key) }.to raise_error(Capistrano::ValidationError)
|
169
174
|
end
|
175
|
+
|
176
|
+
it "raises an exception on invalid string provided by lambda" do
|
177
|
+
config.set :key, -> { "sho" }
|
178
|
+
expect { config.fetch(:key) }.to raise_error(Capistrano::ValidationError)
|
179
|
+
end
|
170
180
|
end
|
171
181
|
|
172
182
|
context "appending" do
|
@@ -294,5 +304,54 @@ module Capistrano
|
|
294
304
|
expect(config.dry_run?).to eq(true)
|
295
305
|
end
|
296
306
|
end
|
307
|
+
|
308
|
+
describe "custom filtering" do
|
309
|
+
it "accepts a custom filter object" do
|
310
|
+
filter = Object.new
|
311
|
+
def filter.filter(servers)
|
312
|
+
servers
|
313
|
+
end
|
314
|
+
config.add_filter(filter)
|
315
|
+
end
|
316
|
+
|
317
|
+
it "accepts a custom filter as a block" do
|
318
|
+
config.add_filter { |servers| servers }
|
319
|
+
end
|
320
|
+
|
321
|
+
it "raises an error if passed a block and an object" do
|
322
|
+
filter = Object.new
|
323
|
+
def filter.filter(servers)
|
324
|
+
servers
|
325
|
+
end
|
326
|
+
|
327
|
+
expect { config.add_filter(filter) { |servers| servers } }.to raise_error(ArgumentError)
|
328
|
+
end
|
329
|
+
|
330
|
+
it "raises an error if the filter lacks a filter method" do
|
331
|
+
filter = Object.new
|
332
|
+
expect { config.add_filter(filter) }.to raise_error(TypeError)
|
333
|
+
end
|
334
|
+
|
335
|
+
it "calls the filter method of a custom filter" do
|
336
|
+
ENV.delete "ROLES"
|
337
|
+
ENV.delete "HOSTS"
|
338
|
+
|
339
|
+
servers = Configuration::Servers.new
|
340
|
+
|
341
|
+
servers.add_host("test1")
|
342
|
+
servers.add_host("test2")
|
343
|
+
servers.add_host("test3")
|
344
|
+
|
345
|
+
filtered_servers = servers.take(2)
|
346
|
+
|
347
|
+
filter = mock("custom filter")
|
348
|
+
filter.expects(:filter)
|
349
|
+
.with { |subset| subset.is_a? Configuration::Servers }
|
350
|
+
.returns(filtered_servers)
|
351
|
+
|
352
|
+
config.add_filter(filter)
|
353
|
+
expect(config.filter(servers)).to eq(filtered_servers)
|
354
|
+
end
|
355
|
+
end
|
297
356
|
end
|
298
357
|
end
|
@@ -15,7 +15,6 @@ module Capistrano
|
|
15
15
|
env.variables.untrusted! do
|
16
16
|
set :application, "my_app"
|
17
17
|
set :repo_url, ".git"
|
18
|
-
set :git_strategy, "Capistrano::Git::DefaultStrategy"
|
19
18
|
set :copy_strategy, :scp
|
20
19
|
set :custom_setting, "hello"
|
21
20
|
set "string_setting", "hello"
|
@@ -57,12 +56,6 @@ module Capistrano
|
|
57
56
|
.to_stdout
|
58
57
|
end
|
59
58
|
|
60
|
-
it "does not print warning for the whitelisted git_strategy variable" do
|
61
|
-
expect { doc.call }.not_to \
|
62
|
-
output(/:git_strategy is not a recognized Capistrano setting/)\
|
63
|
-
.to_stdout
|
64
|
-
end
|
65
|
-
|
66
59
|
describe "Rake" do
|
67
60
|
before do
|
68
61
|
load File.expand_path("../../../../../lib/capistrano/doctor.rb",
|
@@ -104,20 +104,5 @@ module Capistrano
|
|
104
104
|
expect { Rake::Task["task"].invoke order }.to raise_error(ArgumentError, 'Task "non_existent_task" not found')
|
105
105
|
end
|
106
106
|
end
|
107
|
-
|
108
|
-
describe "remote_file" do
|
109
|
-
subject(:remote_file) { task_enhancements.remote_file("source" => "destination") }
|
110
|
-
|
111
|
-
it { expect(remote_file.name).to eq("source") }
|
112
|
-
it { is_expected.to be_a(Capistrano::UploadTask) }
|
113
|
-
|
114
|
-
describe "namespaced" do
|
115
|
-
let(:app) { Rake.application }
|
116
|
-
around { |ex| app.in_namespace("namespace", &ex) }
|
117
|
-
|
118
|
-
it { expect(remote_file.name).to eq("source") }
|
119
|
-
it { is_expected.to be_a(Capistrano::UploadTask) }
|
120
|
-
end
|
121
|
-
end
|
122
107
|
end
|
123
108
|
end
|
@@ -0,0 +1,131 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
require "capistrano/scm/git"
|
4
|
+
|
5
|
+
module Capistrano
|
6
|
+
describe SCM::Git do
|
7
|
+
subject { Capistrano::SCM::Git.new }
|
8
|
+
|
9
|
+
# This allows us to easily use `set`, `fetch`, etc. in the examples.
|
10
|
+
let(:env) { Capistrano::Configuration.env }
|
11
|
+
|
12
|
+
# Stub the SSHKit backend so we can set up expectations without the plugin
|
13
|
+
# actually executing any commands.
|
14
|
+
let(:backend) { stub }
|
15
|
+
before { SSHKit::Backend.stubs(:current).returns(backend) }
|
16
|
+
|
17
|
+
# Mimic the deploy flow tasks so that the plugin can register its hooks.
|
18
|
+
before do
|
19
|
+
Rake::Task.define_task("deploy:new_release_path")
|
20
|
+
Rake::Task.define_task("deploy:check")
|
21
|
+
Rake::Task.define_task("deploy:set_current_revision")
|
22
|
+
end
|
23
|
+
|
24
|
+
# Clean up any tasks or variables that the plugin defined.
|
25
|
+
after do
|
26
|
+
Rake::Task.clear
|
27
|
+
Capistrano::Configuration.reset!
|
28
|
+
end
|
29
|
+
|
30
|
+
describe "#git" do
|
31
|
+
it "should call execute git in the context, with arguments" do
|
32
|
+
backend.expects(:execute).with(:git, :init)
|
33
|
+
subject.git(:init)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
describe "#repo_mirror_exists?" do
|
38
|
+
it "should call test for repo HEAD" do
|
39
|
+
env.set(:repo_path, "/path/to/repo")
|
40
|
+
backend.expects(:test).with " [ -f /path/to/repo/HEAD ] "
|
41
|
+
|
42
|
+
subject.repo_mirror_exists?
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
describe "#check_repo_is_reachable" do
|
47
|
+
it "should test the repo url" do
|
48
|
+
env.set(:repo_url, "url")
|
49
|
+
backend.expects(:execute).with(:git, :'ls-remote --heads', "url").returns(true)
|
50
|
+
|
51
|
+
subject.check_repo_is_reachable
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
describe "#clone_repo" do
|
56
|
+
it "should run git clone" do
|
57
|
+
env.set(:repo_url, "url")
|
58
|
+
env.set(:repo_path, "path")
|
59
|
+
backend.expects(:execute).with(:git, :clone, "--mirror", "url", "path")
|
60
|
+
|
61
|
+
subject.clone_repo
|
62
|
+
end
|
63
|
+
|
64
|
+
it "should run git clone in shallow mode" do
|
65
|
+
env.set(:git_shallow_clone, "1")
|
66
|
+
env.set(:repo_url, "url")
|
67
|
+
env.set(:repo_path, "path")
|
68
|
+
|
69
|
+
backend.expects(:execute).with(:git, :clone, "--mirror", "--depth", "1", "--no-single-branch", "url", "path")
|
70
|
+
|
71
|
+
subject.clone_repo
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
describe "#update_mirror" do
|
76
|
+
it "should run git update" do
|
77
|
+
backend.expects(:execute).with(:git, :remote, :update, "--prune")
|
78
|
+
|
79
|
+
subject.update_mirror
|
80
|
+
end
|
81
|
+
|
82
|
+
it "should run git update in shallow mode" do
|
83
|
+
env.set(:git_shallow_clone, "1")
|
84
|
+
env.set(:branch, "branch")
|
85
|
+
backend.expects(:execute).with(:git, :fetch, "--depth", "1", "origin", "branch")
|
86
|
+
|
87
|
+
subject.update_mirror
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
describe "#archive_to_release_path" do
|
92
|
+
it "should run git archive without a subtree" do
|
93
|
+
env.set(:branch, "branch")
|
94
|
+
env.set(:release_path, "path")
|
95
|
+
|
96
|
+
backend.expects(:execute).with(:git, :archive, "branch", "| /usr/bin/env tar -x -f - -C", "path")
|
97
|
+
|
98
|
+
subject.archive_to_release_path
|
99
|
+
end
|
100
|
+
|
101
|
+
it "should run git archive with a subtree" do
|
102
|
+
env.set(:repo_tree, "tree")
|
103
|
+
env.set(:branch, "branch")
|
104
|
+
env.set(:release_path, "path")
|
105
|
+
|
106
|
+
backend.expects(:execute).with(:git, :archive, "branch", "tree", "| /usr/bin/env tar -x --strip-components 1 -f - -C", "path")
|
107
|
+
|
108
|
+
subject.archive_to_release_path
|
109
|
+
end
|
110
|
+
|
111
|
+
it "should run tar with an overridden name" do
|
112
|
+
env.set(:branch, "branch")
|
113
|
+
env.set(:release_path, "path")
|
114
|
+
SSHKit.config.command_map.expects(:[]).with(:tar).returns("/usr/bin/env gtar")
|
115
|
+
|
116
|
+
backend.expects(:execute).with(:git, :archive, "branch", "| /usr/bin/env gtar -x -f - -C", "path")
|
117
|
+
|
118
|
+
subject.archive_to_release_path
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
describe "#fetch_revision" do
|
123
|
+
it "should capture git rev-list" do
|
124
|
+
env.set(:branch, "branch")
|
125
|
+
backend.expects(:capture).with(:git, "rev-list --max-count=1 branch").returns("81cec13b777ff46348693d327fc8e7832f79bf43")
|
126
|
+
revision = subject.fetch_revision
|
127
|
+
expect(revision).to eq("81cec13b777ff46348693d327fc8e7832f79bf43")
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
@@ -0,0 +1,104 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
require "capistrano/scm/hg"
|
4
|
+
|
5
|
+
module Capistrano
|
6
|
+
describe SCM::Hg do
|
7
|
+
subject { Capistrano::SCM::Hg.new }
|
8
|
+
|
9
|
+
# This allows us to easily use `set`, `fetch`, etc. in the examples.
|
10
|
+
let(:env) { Capistrano::Configuration.env }
|
11
|
+
|
12
|
+
# Stub the SSHKit backend so we can set up expectations without the plugin
|
13
|
+
# actually executing any commands.
|
14
|
+
let(:backend) { stub }
|
15
|
+
before { SSHKit::Backend.stubs(:current).returns(backend) }
|
16
|
+
|
17
|
+
# Mimic the deploy flow tasks so that the plugin can register its hooks.
|
18
|
+
before do
|
19
|
+
Rake::Task.define_task("deploy:new_release_path")
|
20
|
+
Rake::Task.define_task("deploy:check")
|
21
|
+
Rake::Task.define_task("deploy:set_current_revision")
|
22
|
+
end
|
23
|
+
|
24
|
+
# Clean up any tasks or variables that the plugin defined.
|
25
|
+
after do
|
26
|
+
Rake::Task.clear
|
27
|
+
Capistrano::Configuration.reset!
|
28
|
+
end
|
29
|
+
|
30
|
+
describe "#hg" do
|
31
|
+
it "should call execute hg in the context, with arguments" do
|
32
|
+
backend.expects(:execute).with(:hg, :init)
|
33
|
+
subject.hg(:init)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
describe "#repo_mirror_exists?" do
|
38
|
+
it "should call test for repo HEAD" do
|
39
|
+
env.set(:repo_path, "/path/to/repo")
|
40
|
+
backend.expects(:test).with " [ -d /path/to/repo/.hg ] "
|
41
|
+
|
42
|
+
subject.repo_mirror_exists?
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
describe "#check_repo_is_reachable" do
|
47
|
+
it "should test the repo url" do
|
48
|
+
env.set(:repo_url, :url)
|
49
|
+
backend.expects(:execute).with(:hg, "id", :url)
|
50
|
+
|
51
|
+
subject.check_repo_is_reachable
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
describe "#clone_repo" do
|
56
|
+
it "should run hg clone" do
|
57
|
+
env.set(:repo_url, :url)
|
58
|
+
env.set(:repo_path, "path")
|
59
|
+
|
60
|
+
backend.expects(:execute).with(:hg, "clone", "--noupdate", :url, "path")
|
61
|
+
|
62
|
+
subject.clone_repo
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
describe "#update_mirror" do
|
67
|
+
it "should run hg update" do
|
68
|
+
backend.expects(:execute).with(:hg, "pull")
|
69
|
+
|
70
|
+
subject.update_mirror
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
describe "#archive_to_release_path" do
|
75
|
+
it "should run hg archive without a subtree" do
|
76
|
+
env.set(:branch, :branch)
|
77
|
+
env.set(:release_path, "path")
|
78
|
+
|
79
|
+
backend.expects(:execute).with(:hg, "archive", "path", "--rev", :branch)
|
80
|
+
|
81
|
+
subject.archive_to_release_path
|
82
|
+
end
|
83
|
+
|
84
|
+
it "should run hg archive with a subtree" do
|
85
|
+
env.set(:repo_tree, "tree")
|
86
|
+
env.set(:branch, :branch)
|
87
|
+
env.set(:release_path, "path")
|
88
|
+
|
89
|
+
backend.expects(:execute).with(:hg, "archive --type tgz -p . -I", "tree", "--rev", :branch, "| tar -x --strip-components 1 -f - -C", "path")
|
90
|
+
|
91
|
+
subject.archive_to_release_path
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
describe "#fetch_revision" do
|
96
|
+
it "should capture hg log" do
|
97
|
+
env.set(:branch, :branch)
|
98
|
+
backend.expects(:capture).with(:hg, "log --rev branch --template \"{node}\n\"").returns("01abcde")
|
99
|
+
revision = subject.fetch_revision
|
100
|
+
expect(revision).to eq("01abcde")
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
@@ -0,0 +1,116 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
require "capistrano/scm/svn"
|
4
|
+
|
5
|
+
module Capistrano
|
6
|
+
describe SCM::Svn do
|
7
|
+
subject { Capistrano::SCM::Svn.new }
|
8
|
+
|
9
|
+
# This allows us to easily use `set`, `fetch`, etc. in the examples.
|
10
|
+
let(:env) { Capistrano::Configuration.env }
|
11
|
+
|
12
|
+
# Stub the SSHKit backend so we can set up expectations without the plugin
|
13
|
+
# actually executing any commands.
|
14
|
+
let(:backend) { stub }
|
15
|
+
before { SSHKit::Backend.stubs(:current).returns(backend) }
|
16
|
+
|
17
|
+
# Mimic the deploy flow tasks so that the plugin can register its hooks.
|
18
|
+
before do
|
19
|
+
Rake::Task.define_task("deploy:new_release_path")
|
20
|
+
Rake::Task.define_task("deploy:check")
|
21
|
+
Rake::Task.define_task("deploy:set_current_revision")
|
22
|
+
end
|
23
|
+
|
24
|
+
# Clean up any tasks or variables that the plugin defined.
|
25
|
+
after do
|
26
|
+
Rake::Task.clear
|
27
|
+
Capistrano::Configuration.reset!
|
28
|
+
end
|
29
|
+
|
30
|
+
describe "#svn" do
|
31
|
+
it "should call execute svn in the context, with arguments" do
|
32
|
+
env.set(:svn_username, "someuser")
|
33
|
+
env.set(:svn_password, "somepassword")
|
34
|
+
backend.expects(:execute).with(:svn, :init, "--username someuser", "--password somepassword")
|
35
|
+
subject.svn(:init)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
describe "#repo_mirror_exists?" do
|
40
|
+
it "should call test for repo HEAD" do
|
41
|
+
env.set(:repo_path, "/path/to/repo")
|
42
|
+
backend.expects(:test).with " [ -d /path/to/repo/.svn ] "
|
43
|
+
|
44
|
+
subject.repo_mirror_exists?
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
describe "#check_repo_is_reachable" do
|
49
|
+
it "should test the repo url" do
|
50
|
+
env.set(:repo_url, :url)
|
51
|
+
env.set(:svn_username, "someuser")
|
52
|
+
env.set(:svn_password, "somepassword")
|
53
|
+
backend.expects(:test).with(:svn, :info, :url, "--username someuser", "--password somepassword").returns(true)
|
54
|
+
|
55
|
+
subject.check_repo_is_reachable
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
describe "#clone_repo" do
|
60
|
+
it "should run svn checkout" do
|
61
|
+
env.set(:repo_url, :url)
|
62
|
+
env.set(:repo_path, "path")
|
63
|
+
env.set(:svn_username, "someuser")
|
64
|
+
env.set(:svn_password, "somepassword")
|
65
|
+
|
66
|
+
backend.expects(:execute).with(:svn, :checkout, :url, "path", "--username someuser", "--password somepassword")
|
67
|
+
|
68
|
+
subject.clone_repo
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
describe "#update_mirror" do
|
73
|
+
it "should run svn update" do
|
74
|
+
env.set(:svn_username, "someuser")
|
75
|
+
env.set(:svn_password, "somepassword")
|
76
|
+
backend.expects(:execute).with(:svn, :update, "--username someuser", "--password somepassword")
|
77
|
+
|
78
|
+
subject.update_mirror
|
79
|
+
end
|
80
|
+
|
81
|
+
context "for specific revision" do
|
82
|
+
it "should run svn update" do
|
83
|
+
env.set(:svn_username, "someuser")
|
84
|
+
env.set(:svn_password, "somepassword")
|
85
|
+
env.set(:svn_revision, "12345")
|
86
|
+
backend.expects(:execute).with(:svn, :update, "--username someuser", "--password somepassword", "--revision 12345")
|
87
|
+
|
88
|
+
subject.update_mirror
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
describe "#archive_to_release_path" do
|
94
|
+
it "should run svn export" do
|
95
|
+
env.set(:release_path, "path")
|
96
|
+
env.set(:svn_username, "someuser")
|
97
|
+
env.set(:svn_password, "somepassword")
|
98
|
+
|
99
|
+
backend.expects(:execute).with(:svn, :export, "--force", ".", "path", "--username someuser", "--password somepassword")
|
100
|
+
|
101
|
+
subject.archive_to_release_path
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
describe "#fetch_revision" do
|
106
|
+
it "should capture svn version" do
|
107
|
+
env.set(:repo_path, "path")
|
108
|
+
|
109
|
+
backend.expects(:capture).with(:svnversion, "path").returns("12345")
|
110
|
+
|
111
|
+
revision = subject.fetch_revision
|
112
|
+
expect(revision).to eq("12345")
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|