capistrano 3.4.0 → 3.17.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.
- checksums.yaml +5 -5
- data/.circleci/config.yml +129 -0
- data/.github/issue_template.md +19 -0
- data/.github/pull_request_template.md +22 -0
- data/.github/release-drafter.yml +17 -0
- data/.github/workflows/push.yml +12 -0
- data/.gitignore +8 -5
- data/.rubocop.yml +62 -0
- data/CHANGELOG.md +1 -307
- data/CONTRIBUTING.md +63 -93
- data/DEVELOPMENT.md +127 -0
- data/Dangerfile +1 -0
- data/Gemfile +40 -3
- data/LICENSE.txt +1 -1
- data/README.md +127 -44
- data/RELEASING.md +17 -0
- data/Rakefile +13 -2
- data/UPGRADING-3.7.md +86 -0
- data/bin/cap +1 -1
- data/capistrano.gemspec +21 -24
- data/features/deploy.feature +35 -1
- data/features/doctor.feature +11 -0
- data/features/installation.feature +8 -3
- data/features/stage_failure.feature +9 -0
- data/features/step_definitions/assertions.rb +51 -18
- data/features/step_definitions/cap_commands.rb +9 -0
- data/features/step_definitions/setup.rb +53 -9
- data/features/subdirectory.feature +9 -0
- data/features/support/env.rb +5 -5
- data/features/support/remote_command_helpers.rb +12 -6
- data/features/support/vagrant_helpers.rb +17 -11
- data/lib/Capfile +1 -1
- data/lib/capistrano/all.rb +10 -10
- data/lib/capistrano/application.rb +47 -34
- data/lib/capistrano/configuration/empty_filter.rb +9 -0
- data/lib/capistrano/configuration/filter.rb +17 -47
- data/lib/capistrano/configuration/host_filter.rb +29 -0
- data/lib/capistrano/configuration/null_filter.rb +9 -0
- data/lib/capistrano/configuration/plugin_installer.rb +51 -0
- data/lib/capistrano/configuration/question.rb +31 -9
- data/lib/capistrano/configuration/role_filter.rb +29 -0
- data/lib/capistrano/configuration/scm_resolver.rb +149 -0
- data/lib/capistrano/configuration/server.rb +29 -23
- data/lib/capistrano/configuration/servers.rb +21 -14
- data/lib/capistrano/configuration/validated_variables.rb +110 -0
- data/lib/capistrano/configuration/variables.rb +112 -0
- data/lib/capistrano/configuration.rb +91 -44
- data/lib/capistrano/defaults.rb +26 -4
- data/lib/capistrano/deploy.rb +1 -1
- data/lib/capistrano/doctor/environment_doctor.rb +19 -0
- data/lib/capistrano/doctor/gems_doctor.rb +45 -0
- data/lib/capistrano/doctor/output_helpers.rb +79 -0
- data/lib/capistrano/doctor/servers_doctor.rb +105 -0
- data/lib/capistrano/doctor/variables_doctor.rb +74 -0
- data/lib/capistrano/doctor.rb +6 -0
- data/lib/capistrano/dotfile.rb +1 -2
- data/lib/capistrano/dsl/env.rb +9 -47
- data/lib/capistrano/dsl/paths.rb +11 -25
- data/lib/capistrano/dsl/stages.rb +14 -2
- data/lib/capistrano/dsl/task_enhancements.rb +7 -12
- data/lib/capistrano/dsl.rb +47 -16
- data/lib/capistrano/framework.rb +1 -1
- data/lib/capistrano/i18n.rb +32 -24
- data/lib/capistrano/immutable_task.rb +30 -0
- data/lib/capistrano/install.rb +1 -1
- data/lib/capistrano/plugin.rb +95 -0
- data/lib/capistrano/proc_helpers.rb +13 -0
- data/lib/capistrano/scm/git.rb +100 -0
- data/lib/capistrano/scm/hg.rb +55 -0
- data/lib/capistrano/scm/plugin.rb +13 -0
- data/lib/capistrano/scm/svn.rb +56 -0
- data/lib/capistrano/scm/tasks/git.rake +73 -0
- data/lib/capistrano/scm/tasks/hg.rake +53 -0
- data/lib/capistrano/scm/tasks/svn.rake +53 -0
- data/lib/capistrano/scm.rb +7 -20
- data/lib/capistrano/setup.rb +20 -6
- data/lib/capistrano/tasks/console.rake +4 -8
- data/lib/capistrano/tasks/deploy.rake +105 -73
- data/lib/capistrano/tasks/doctor.rake +24 -0
- data/lib/capistrano/tasks/framework.rake +13 -14
- data/lib/capistrano/tasks/install.rake +14 -15
- data/lib/capistrano/templates/Capfile +21 -10
- data/lib/capistrano/templates/deploy.rb.erb +17 -26
- data/lib/capistrano/templates/stage.rb.erb +9 -9
- data/lib/capistrano/upload_task.rb +1 -1
- data/lib/capistrano/version.rb +1 -1
- data/lib/capistrano/version_validator.rb +5 -10
- data/spec/integration/dsl_spec.rb +289 -240
- data/spec/integration_spec_helper.rb +3 -5
- data/spec/lib/capistrano/application_spec.rb +23 -39
- data/spec/lib/capistrano/configuration/empty_filter_spec.rb +17 -0
- data/spec/lib/capistrano/configuration/filter_spec.rb +83 -85
- data/spec/lib/capistrano/configuration/host_filter_spec.rb +71 -0
- data/spec/lib/capistrano/configuration/null_filter_spec.rb +17 -0
- data/spec/lib/capistrano/configuration/plugin_installer_spec.rb +98 -0
- data/spec/lib/capistrano/configuration/question_spec.rb +58 -26
- data/spec/lib/capistrano/configuration/role_filter_spec.rb +80 -0
- data/spec/lib/capistrano/configuration/scm_resolver_spec.rb +55 -0
- data/spec/lib/capistrano/configuration/server_spec.rb +106 -113
- data/spec/lib/capistrano/configuration/servers_spec.rb +129 -145
- data/spec/lib/capistrano/configuration_spec.rb +224 -63
- data/spec/lib/capistrano/doctor/environment_doctor_spec.rb +44 -0
- data/spec/lib/capistrano/doctor/gems_doctor_spec.rb +67 -0
- data/spec/lib/capistrano/doctor/output_helpers_spec.rb +47 -0
- data/spec/lib/capistrano/doctor/servers_doctor_spec.rb +86 -0
- data/spec/lib/capistrano/doctor/variables_doctor_spec.rb +89 -0
- data/spec/lib/capistrano/dsl/paths_spec.rb +97 -59
- data/spec/lib/capistrano/dsl/task_enhancements_spec.rb +57 -37
- data/spec/lib/capistrano/dsl_spec.rb +84 -11
- data/spec/lib/capistrano/immutable_task_spec.rb +31 -0
- data/spec/lib/capistrano/plugin_spec.rb +84 -0
- data/spec/lib/capistrano/scm/git_spec.rb +184 -0
- data/spec/lib/capistrano/scm/hg_spec.rb +109 -0
- data/spec/lib/capistrano/scm/svn_spec.rb +137 -0
- data/spec/lib/capistrano/scm_spec.rb +7 -8
- data/spec/lib/capistrano/upload_task_spec.rb +7 -7
- data/spec/lib/capistrano/version_validator_spec.rb +61 -46
- data/spec/lib/capistrano_spec.rb +2 -3
- data/spec/spec_helper.rb +21 -8
- data/spec/support/Vagrantfile +9 -10
- data/spec/support/tasks/database.rake +3 -3
- data/spec/support/tasks/fail.rake +4 -3
- data/spec/support/tasks/failed.rake +2 -2
- data/spec/support/tasks/plugin.rake +6 -0
- data/spec/support/tasks/root.rake +4 -4
- data/spec/support/test_app.rb +64 -39
- metadata +100 -55
- data/.travis.yml +0 -13
- data/features/remote_file_task.feature +0 -14
- data/lib/capistrano/git.rb +0 -46
- data/lib/capistrano/hg.rb +0 -43
- data/lib/capistrano/svn.rb +0 -38
- data/lib/capistrano/tasks/git.rake +0 -81
- data/lib/capistrano/tasks/hg.rake +0 -52
- data/lib/capistrano/tasks/svn.rake +0 -52
- data/spec/lib/capistrano/git_spec.rb +0 -81
- data/spec/lib/capistrano/hg_spec.rb +0 -81
- data/spec/lib/capistrano/svn_spec.rb +0 -79
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
require "spec_helper"
|
|
2
|
+
require "rake"
|
|
3
|
+
require "capistrano/immutable_task"
|
|
4
|
+
|
|
5
|
+
module Capistrano
|
|
6
|
+
describe ImmutableTask do
|
|
7
|
+
after do
|
|
8
|
+
# Ensure that any tasks we create in these tests don't pollute other tests
|
|
9
|
+
Rake::Task.clear
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
it "prints warning and raises when task is enhanced" do
|
|
13
|
+
extend(Rake::DSL)
|
|
14
|
+
|
|
15
|
+
load_defaults = Rake::Task.define_task("load:defaults")
|
|
16
|
+
load_defaults.extend(Capistrano::ImmutableTask)
|
|
17
|
+
|
|
18
|
+
$stderr.expects(:puts).with do |message|
|
|
19
|
+
message =~ /^ERROR: load:defaults has already been invoked/
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
expect do
|
|
23
|
+
namespace :load do
|
|
24
|
+
task :defaults do
|
|
25
|
+
# Never reached since load_defaults is frozen and can't be enhanced
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end.to raise_error(/frozen/i)
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
require "spec_helper"
|
|
2
|
+
require "capistrano/plugin"
|
|
3
|
+
|
|
4
|
+
module Capistrano
|
|
5
|
+
describe Plugin do
|
|
6
|
+
include Rake::DSL
|
|
7
|
+
include Capistrano::DSL
|
|
8
|
+
|
|
9
|
+
class DummyPlugin < Capistrano::Plugin
|
|
10
|
+
def define_tasks
|
|
11
|
+
task :hello do
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def register_hooks
|
|
16
|
+
before "deploy:published", "hello"
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
class ExternalTasksPlugin < Capistrano::Plugin
|
|
21
|
+
def define_tasks
|
|
22
|
+
eval_rakefile(
|
|
23
|
+
File.expand_path("../../../support/tasks/plugin.rake", __FILE__)
|
|
24
|
+
)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
# Called from plugin.rake to demonstrate that helper methods work
|
|
28
|
+
def hello
|
|
29
|
+
set :plugin_result, "hello"
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
before do
|
|
34
|
+
# Define an example task to allow testing hooks
|
|
35
|
+
task "deploy:published"
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
after do
|
|
39
|
+
# Clean up any tasks or variables we created during the tests
|
|
40
|
+
Rake::Task.clear
|
|
41
|
+
Capistrano::Configuration.reset!
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
it "defines tasks when constructed" do
|
|
45
|
+
install_plugin(DummyPlugin)
|
|
46
|
+
expect(Rake::Task["hello"]).not_to be_nil
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
it "registers hooks when constructed" do
|
|
50
|
+
install_plugin(DummyPlugin)
|
|
51
|
+
expect(Rake::Task["deploy:published"].prerequisites).to include("hello")
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
it "skips registering hooks if load_hooks: false" do
|
|
55
|
+
install_plugin(DummyPlugin, load_hooks: false)
|
|
56
|
+
expect(Rake::Task["deploy:published"].prerequisites).to be_empty
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
it "doesn't call set_defaults immediately" do
|
|
60
|
+
dummy = DummyPlugin.new
|
|
61
|
+
install_plugin(dummy)
|
|
62
|
+
dummy.expects(:set_defaults).never
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
it "calls set_defaults during load:defaults", capture_io: true do
|
|
66
|
+
dummy = DummyPlugin.new
|
|
67
|
+
dummy.expects(:set_defaults).once
|
|
68
|
+
install_plugin(dummy)
|
|
69
|
+
Rake::Task["load:defaults"].invoke
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
it "is able to load tasks from a .rake file", capture_io: true do
|
|
73
|
+
install_plugin(ExternalTasksPlugin)
|
|
74
|
+
Rake::Task["plugin_test"].invoke
|
|
75
|
+
expect(fetch(:plugin_result)).to eq("hello")
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
it "exposes the SSHKit backend to subclasses" do
|
|
79
|
+
SSHKit::Backend.expects(:current).returns(:backend)
|
|
80
|
+
plugin = DummyPlugin.new
|
|
81
|
+
expect(plugin.send(:backend)).to eq(:backend)
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
end
|
|
@@ -0,0 +1,184 @@
|
|
|
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 "#set_defaults" do
|
|
31
|
+
it "makes git_wrapper_path using a random hex value" do
|
|
32
|
+
env.set(:tmp_dir, "/tmp")
|
|
33
|
+
subject.set_defaults
|
|
34
|
+
expect(env.fetch(:git_wrapper_path)).to match(%r{/tmp/git-ssh-\h{20}\.sh})
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
it "makes git_max_concurrent_connections" do
|
|
38
|
+
subject.set_defaults
|
|
39
|
+
expect(env.fetch(:git_max_concurrent_connections)).to eq(10)
|
|
40
|
+
env.set(:git_max_concurrent_connections, 7)
|
|
41
|
+
expect(env.fetch(:git_max_concurrent_connections)).to eq(7)
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
it "makes git_wait_interval" do
|
|
45
|
+
subject.set_defaults
|
|
46
|
+
expect(env.fetch(:git_wait_interval)).to eq(0)
|
|
47
|
+
env.set(:git_wait_interval, 5)
|
|
48
|
+
expect(env.fetch(:git_wait_interval)).to eq(5)
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
describe "#git" do
|
|
53
|
+
it "should call execute git in the context, with arguments" do
|
|
54
|
+
backend.expects(:execute).with(:git, :init)
|
|
55
|
+
subject.git(:init)
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
describe "#repo_mirror_exists?" do
|
|
60
|
+
it "should call test for repo HEAD" do
|
|
61
|
+
env.set(:repo_path, "/path/to/repo")
|
|
62
|
+
backend.expects(:test).with " [ -f /path/to/repo/HEAD ] "
|
|
63
|
+
|
|
64
|
+
subject.repo_mirror_exists?
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
describe "#check_repo_is_reachable" do
|
|
69
|
+
it "should test the repo url" do
|
|
70
|
+
env.set(:repo_url, "url")
|
|
71
|
+
backend.expects(:execute).with(:git, :'ls-remote', "url", "HEAD").returns(true)
|
|
72
|
+
|
|
73
|
+
subject.check_repo_is_reachable
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
describe "#clone_repo" do
|
|
78
|
+
it "should run git clone" do
|
|
79
|
+
env.set(:repo_url, "url")
|
|
80
|
+
env.set(:repo_path, "path")
|
|
81
|
+
backend.expects(:execute).with(:git, :clone, "--mirror", "url", "path")
|
|
82
|
+
|
|
83
|
+
subject.clone_repo
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
it "should run git clone in shallow mode" do
|
|
87
|
+
env.set(:git_shallow_clone, "1")
|
|
88
|
+
env.set(:repo_url, "url")
|
|
89
|
+
env.set(:repo_path, "path")
|
|
90
|
+
|
|
91
|
+
backend.expects(:execute).with(:git, :clone, "--mirror", "--depth", "1", "--no-single-branch", "url", "path")
|
|
92
|
+
|
|
93
|
+
subject.clone_repo
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
context "with username and password specified" do
|
|
97
|
+
before do
|
|
98
|
+
env.set(:git_http_username, "hello")
|
|
99
|
+
env.set(:git_http_password, "topsecret")
|
|
100
|
+
env.set(:repo_url, "https://example.com/repo.git")
|
|
101
|
+
env.set(:repo_path, "path")
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
it "should include the credentials in the url" do
|
|
105
|
+
backend.expects(:execute).with(:git, :clone, "--mirror", "https://hello:topsecret@example.com/repo.git", "path")
|
|
106
|
+
subject.clone_repo
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
describe "#update_mirror" do
|
|
112
|
+
it "should run git update" do
|
|
113
|
+
env.set(:repo_url, "url")
|
|
114
|
+
|
|
115
|
+
backend.expects(:execute).with(:git, :remote, "set-url", "origin", "url")
|
|
116
|
+
backend.expects(:execute).with(:git, :remote, :update, "--prune")
|
|
117
|
+
|
|
118
|
+
subject.update_mirror
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
it "should run git update in shallow mode" do
|
|
122
|
+
env.set(:git_shallow_clone, "1")
|
|
123
|
+
env.set(:branch, "branch")
|
|
124
|
+
env.set(:repo_url, "url")
|
|
125
|
+
|
|
126
|
+
backend.expects(:execute).with(:git, :remote, "set-url", "origin", "url")
|
|
127
|
+
backend.expects(:execute).with(:git, :fetch, "--depth", "1", "origin", "branch")
|
|
128
|
+
|
|
129
|
+
subject.update_mirror
|
|
130
|
+
end
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
describe "#archive_to_release_path" do
|
|
134
|
+
it "should run git archive without a subtree" do
|
|
135
|
+
env.set(:branch, "branch")
|
|
136
|
+
env.set(:release_path, "path")
|
|
137
|
+
|
|
138
|
+
backend.expects(:execute).with(:git, :archive, "branch", "| /usr/bin/env tar -x -f - -C", "path")
|
|
139
|
+
|
|
140
|
+
subject.archive_to_release_path
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
it "should run git archive with a subtree" do
|
|
144
|
+
env.set(:repo_tree, "tree")
|
|
145
|
+
env.set(:branch, "branch")
|
|
146
|
+
env.set(:release_path, "path")
|
|
147
|
+
|
|
148
|
+
backend.expects(:execute).with(:git, :archive, "branch", "tree", "| /usr/bin/env tar -x --strip-components 1 -f - -C", "path")
|
|
149
|
+
|
|
150
|
+
subject.archive_to_release_path
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
it "should run tar with an overridden name" do
|
|
154
|
+
env.set(:branch, "branch")
|
|
155
|
+
env.set(:release_path, "path")
|
|
156
|
+
SSHKit.config.command_map.expects(:[]).with(:tar).returns("/usr/bin/env gtar")
|
|
157
|
+
|
|
158
|
+
backend.expects(:execute).with(:git, :archive, "branch", "| /usr/bin/env gtar -x -f - -C", "path")
|
|
159
|
+
|
|
160
|
+
subject.archive_to_release_path
|
|
161
|
+
end
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
describe "#fetch_revision" do
|
|
165
|
+
it "should capture git rev-list" do
|
|
166
|
+
env.set(:branch, "branch")
|
|
167
|
+
backend.expects(:capture).with(:git, "rev-list --max-count=1 branch").returns("81cec13b777ff46348693d327fc8e7832f79bf43")
|
|
168
|
+
revision = subject.fetch_revision
|
|
169
|
+
expect(revision).to eq("81cec13b777ff46348693d327fc8e7832f79bf43")
|
|
170
|
+
end
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
describe "#verify_commit" do
|
|
174
|
+
it "should run git verify-commit" do
|
|
175
|
+
env.set(:branch, "branch")
|
|
176
|
+
|
|
177
|
+
backend.expects(:capture).with(:git, "rev-list --max-count=1 branch").returns("81cec13b777ff46348693d327fc8e7832f79bf43")
|
|
178
|
+
backend.expects(:execute).with(:git, :"verify-commit", "81cec13b777ff46348693d327fc8e7832f79bf43")
|
|
179
|
+
|
|
180
|
+
subject.verify_commit
|
|
181
|
+
end
|
|
182
|
+
end
|
|
183
|
+
end
|
|
184
|
+
end
|
|
@@ -0,0 +1,109 @@
|
|
|
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
|
+
env.set(:tmp_dir, "/tmp")
|
|
89
|
+
|
|
90
|
+
SecureRandom.stubs(:hex).with(10).returns("random")
|
|
91
|
+
backend.expects(:execute).with(:hg, "archive -p . -I", "tree", "--rev", :branch, "/tmp/random.tar")
|
|
92
|
+
backend.expects(:execute).with(:mkdir, "-p", "path")
|
|
93
|
+
backend.expects(:execute).with(:tar, "-x --strip-components 1 -f", "/tmp/random.tar", "-C", "path")
|
|
94
|
+
backend.expects(:execute).with(:rm, "/tmp/random.tar")
|
|
95
|
+
|
|
96
|
+
subject.archive_to_release_path
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
describe "#fetch_revision" do
|
|
101
|
+
it "should capture hg log" do
|
|
102
|
+
env.set(:branch, :branch)
|
|
103
|
+
backend.expects(:capture).with(:hg, "log --rev branch --template \"{node}\n\"").returns("01abcde")
|
|
104
|
+
revision = subject.fetch_revision
|
|
105
|
+
expect(revision).to eq("01abcde")
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
end
|
|
@@ -0,0 +1,137 @@
|
|
|
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(:repo_url, "url")
|
|
75
|
+
env.set(:repo_path, "path")
|
|
76
|
+
backend.expects(:capture).with(:svn, :info, "path").returns("URL: url\n")
|
|
77
|
+
|
|
78
|
+
env.set(:svn_username, "someuser")
|
|
79
|
+
env.set(:svn_password, "somepassword")
|
|
80
|
+
backend.expects(:execute).with(:svn, :update, "--username someuser", "--password somepassword")
|
|
81
|
+
|
|
82
|
+
subject.update_mirror
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
context "for specific revision" do
|
|
86
|
+
it "should run svn update" do
|
|
87
|
+
env.set(:repo_url, "url")
|
|
88
|
+
env.set(:repo_path, "path")
|
|
89
|
+
backend.expects(:capture).with(:svn, :info, "path").returns("URL: url\n")
|
|
90
|
+
|
|
91
|
+
env.set(:svn_username, "someuser")
|
|
92
|
+
env.set(:svn_password, "somepassword")
|
|
93
|
+
env.set(:svn_revision, "12345")
|
|
94
|
+
backend.expects(:execute).with(:svn, :update, "--username someuser", "--password somepassword", "--revision 12345")
|
|
95
|
+
|
|
96
|
+
subject.update_mirror
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
it "should run svn switch if repo_url is changed" do
|
|
101
|
+
env.set(:repo_url, "url")
|
|
102
|
+
env.set(:repo_path, "path")
|
|
103
|
+
backend.expects(:capture).with(:svn, :info, "path").returns("URL: old_url\n")
|
|
104
|
+
|
|
105
|
+
env.set(:svn_username, "someuser")
|
|
106
|
+
env.set(:svn_password, "somepassword")
|
|
107
|
+
backend.expects(:execute).with(:svn, :switch, "url", "--username someuser", "--password somepassword")
|
|
108
|
+
backend.expects(:execute).with(:svn, :update, "--username someuser", "--password somepassword")
|
|
109
|
+
|
|
110
|
+
subject.update_mirror
|
|
111
|
+
end
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
describe "#archive_to_release_path" do
|
|
115
|
+
it "should run svn export" do
|
|
116
|
+
env.set(:release_path, "path")
|
|
117
|
+
env.set(:svn_username, "someuser")
|
|
118
|
+
env.set(:svn_password, "somepassword")
|
|
119
|
+
|
|
120
|
+
backend.expects(:execute).with(:svn, :export, "--force", ".", "path", "--username someuser", "--password somepassword")
|
|
121
|
+
|
|
122
|
+
subject.archive_to_release_path
|
|
123
|
+
end
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
describe "#fetch_revision" do
|
|
127
|
+
it "should capture svn version" do
|
|
128
|
+
env.set(:repo_path, "path")
|
|
129
|
+
|
|
130
|
+
backend.expects(:capture).with(:svnversion, "path").returns("12345")
|
|
131
|
+
|
|
132
|
+
revision = subject.fetch_revision
|
|
133
|
+
expect(revision).to eq("12345")
|
|
134
|
+
end
|
|
135
|
+
end
|
|
136
|
+
end
|
|
137
|
+
end
|
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
require
|
|
1
|
+
require "spec_helper"
|
|
2
2
|
|
|
3
|
-
require
|
|
3
|
+
require "capistrano/scm"
|
|
4
4
|
|
|
5
5
|
module RaiseNotImplementedMacro
|
|
6
6
|
def raise_not_implemented_on(method)
|
|
7
7
|
it "should raise NotImplemented on #{method}" do
|
|
8
|
-
expect
|
|
8
|
+
expect do
|
|
9
9
|
subject.send(method)
|
|
10
|
-
|
|
10
|
+
end.to raise_error(NotImplementedError)
|
|
11
11
|
end
|
|
12
12
|
end
|
|
13
13
|
end
|
|
@@ -26,7 +26,7 @@ module BlindStrategy; end
|
|
|
26
26
|
|
|
27
27
|
module Capistrano
|
|
28
28
|
describe SCM do
|
|
29
|
-
let(:context) {
|
|
29
|
+
let(:context) { mock }
|
|
30
30
|
|
|
31
31
|
describe "#initialize" do
|
|
32
32
|
subject { Capistrano::SCM.new(context, DummyStrategy) }
|
|
@@ -63,8 +63,8 @@ module Capistrano
|
|
|
63
63
|
|
|
64
64
|
describe "#release_path" do
|
|
65
65
|
it "should return the release path according to the context" do
|
|
66
|
-
context.expects(:release_path).returns(
|
|
67
|
-
expect(subject.release_path).to eq(
|
|
66
|
+
context.expects(:release_path).returns("/path/to/nowhere")
|
|
67
|
+
expect(subject.release_path).to eq("/path/to/nowhere")
|
|
68
68
|
end
|
|
69
69
|
end
|
|
70
70
|
|
|
@@ -101,4 +101,3 @@ module Capistrano
|
|
|
101
101
|
end
|
|
102
102
|
end
|
|
103
103
|
end
|
|
104
|
-
|
|
@@ -1,19 +1,19 @@
|
|
|
1
|
-
require
|
|
1
|
+
require "spec_helper"
|
|
2
2
|
|
|
3
3
|
describe Capistrano::UploadTask do
|
|
4
4
|
let(:app) { Rake.application = Rake::Application.new }
|
|
5
5
|
|
|
6
|
-
subject(:upload_task) { described_class.define_task(
|
|
6
|
+
subject(:upload_task) { described_class.define_task("path/file.yml") }
|
|
7
7
|
|
|
8
8
|
it { is_expected.to be_a(Rake::FileCreationTask) }
|
|
9
9
|
it { is_expected.to be_needed }
|
|
10
10
|
|
|
11
|
-
context
|
|
12
|
-
let(:normal_task) { Rake::Task.define_task(
|
|
11
|
+
context "inside namespace" do
|
|
12
|
+
let(:normal_task) { Rake::Task.define_task("path/other_file.yml") }
|
|
13
13
|
|
|
14
|
-
around { |ex| app.in_namespace(
|
|
14
|
+
around { |ex| app.in_namespace("namespace", &ex) }
|
|
15
15
|
|
|
16
|
-
it { expect(upload_task.name).to eq(
|
|
17
|
-
it { expect(upload_task.scope.path).to eq(
|
|
16
|
+
it { expect(upload_task.name).to eq("path/file.yml") }
|
|
17
|
+
it { expect(upload_task.scope.path).to eq("namespace") }
|
|
18
18
|
end
|
|
19
19
|
end
|