bosh-workspace 0.9.2 → 0.9.3
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/bosh-workspace.gemspec +5 -4
- data/lib/bosh/cli/commands/deployment_patch.rb +0 -1
- data/lib/bosh/cli/commands/prepare.rb +12 -11
- data/lib/bosh/workspace.rb +4 -3
- data/lib/bosh/workspace/credentials.rb +12 -5
- data/lib/bosh/workspace/git_credentials_provider.rb +80 -0
- data/lib/bosh/workspace/{git_remote_url.rb → helpers/git_protocol_helper.rb} +4 -8
- data/lib/bosh/workspace/helpers/project_deployment_helper.rb +10 -2
- data/lib/bosh/workspace/helpers/release_helper.rb +33 -7
- data/lib/bosh/workspace/manifest_builder.rb +6 -8
- data/lib/bosh/workspace/merge_tool.rb +73 -0
- data/lib/bosh/workspace/project_deployment.rb +20 -5
- data/lib/bosh/workspace/release.rb +103 -67
- data/lib/bosh/workspace/schemas/credentials.rb +22 -0
- data/lib/bosh/workspace/schemas/project_deployment.rb +14 -1
- data/lib/bosh/workspace/version.rb +1 -1
- data/spec/assets/bin/spruce +0 -0
- data/spec/assets/manifests-repo/deployments/foo.yml +1 -0
- data/spec/assets/manifests-repo/stubs/foo.yml +4 -0
- data/spec/commands/prepare_spec.rb +39 -12
- data/spec/credentials_spec.rb +8 -0
- data/spec/git_credentials_provider_spec.rb +82 -0
- data/spec/{git_remote_url_spec.rb → helpers/git_protocol_helper_spec.rb} +10 -11
- data/spec/helpers/project_deployment_helper_spec.rb +12 -1
- data/spec/helpers/release_helper_spec.rb +157 -73
- data/spec/manifest_builder_spec.rb +6 -5
- data/spec/merge_tool_spec.rb +98 -0
- data/spec/project_deployment_spec.rb +43 -1
- data/spec/release_spec.rb +369 -354
- data/spec/rugged_spec.rb +64 -0
- data/spec/schemas/credentials_spec.rb +22 -5
- data/spec/spec_helper.rb +1 -0
- metadata +35 -15
- data/lib/bosh/workspace/helpers/git_credentials_helper.rb +0 -111
- data/lib/bosh/workspace/helpers/spiff_helper.rb +0 -34
- data/spec/helpers/git_credentials_helper_spec.rb +0 -190
- data/spec/helpers/spiff_helper_spec.rb +0 -68
@@ -0,0 +1,98 @@
|
|
1
|
+
module Bosh::Workspace
|
2
|
+
describe MergeTool do
|
3
|
+
|
4
|
+
subject { Bosh::Workspace::MergeTool.new(tool_name) }
|
5
|
+
let(:templates) { %w(foo.yml bar.yml) }
|
6
|
+
let(:target_file) { 'spiffed_manifest.yml' }
|
7
|
+
let(:path) { asset_dir('bin') }
|
8
|
+
|
9
|
+
around do |example|
|
10
|
+
original_path = ENV['PATH']
|
11
|
+
ENV['PATH'] = path
|
12
|
+
example.run
|
13
|
+
ENV['PATH'] = original_path
|
14
|
+
end
|
15
|
+
|
16
|
+
context 'unknown tool' do
|
17
|
+
let(:tool_name) { 'unknown-tool' }
|
18
|
+
it 'raises an error' do
|
19
|
+
expect { subject.merge(templates, target_file).to raise_error }
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
%w(spiff spruce).each do |tool_name|
|
24
|
+
context tool_name do
|
25
|
+
let(:file) { instance_double("File") }
|
26
|
+
before do
|
27
|
+
allow(File).to receive(:open).with(target_file, 'w').and_yield(file)
|
28
|
+
allow(file).to receive(:write).with(output)
|
29
|
+
end
|
30
|
+
|
31
|
+
context 'using tool name as a string' do
|
32
|
+
before do
|
33
|
+
expect(subject).to receive(:sh).at_least(:once).with(*args).and_yield(result)
|
34
|
+
end
|
35
|
+
|
36
|
+
let(:result) { Bosh::Exec::Result.new(tool_name, output, 0, false) }
|
37
|
+
let(:args) { [/#{tool_name} merge/, Hash] }
|
38
|
+
let(:tool_name) { tool_name }
|
39
|
+
|
40
|
+
context 'not found error' do
|
41
|
+
let(:path) { asset_dir('empty_bin') }
|
42
|
+
let(:result) { Bosh::Exec::Result.new(tool_name, 'command not found', 1, false) }
|
43
|
+
|
44
|
+
it 'raises an error' do
|
45
|
+
expect(subject).to receive(:say).with(/Command failed/)
|
46
|
+
expect { subject.merge(templates, target_file) }
|
47
|
+
.to raise_error /command not found/
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
describe '#merge' do
|
52
|
+
let(:output) { "---\n{}" }
|
53
|
+
|
54
|
+
it 'merges manifests' do
|
55
|
+
subject.merge(templates, target_file)
|
56
|
+
end
|
57
|
+
|
58
|
+
context 'spaces in template paths' do
|
59
|
+
let(:templates) { ['space test/foo space test.yml'] }
|
60
|
+
let(:args) { [/space\\ test\/foo\\ space\\ test.yml/, Hash] }
|
61
|
+
|
62
|
+
it 'merges manifests' do
|
63
|
+
subject.merge(templates, target_file)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
|
70
|
+
context 'using tool name as a hash with version and name' do
|
71
|
+
subject { Bosh::Workspace::MergeTool.new('name' => tool_name, 'version' => '0.1.0') }
|
72
|
+
let(:result) { Bosh::Exec::Result.new(tool_name, output, 0, false) }
|
73
|
+
|
74
|
+
before do
|
75
|
+
expect(subject).to receive(:sh).with(/#{tool_name} -v/, Hash).and_yield(result)
|
76
|
+
expect(subject).to receive(:sh).with(/#{tool_name} merge/, Hash).and_yield(result)
|
77
|
+
end
|
78
|
+
|
79
|
+
describe 'with correct version' do
|
80
|
+
let(:output) { "#{tool_name} version 0.1.0" }
|
81
|
+
it 'merges manifests' do
|
82
|
+
subject.merge(templates, target_file)
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
describe 'with wrong version' do
|
87
|
+
let(:output) { "#{tool_name} version 0.2.0" }
|
88
|
+
it 'merges manifests' do
|
89
|
+
expect(subject).to receive(:warning).with(/0\.2\.0/)
|
90
|
+
subject.merge(templates, target_file)
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
@@ -1,7 +1,8 @@
|
|
1
1
|
module Bosh::Workspace
|
2
2
|
describe ProjectDeployment do
|
3
3
|
subject { Bosh::Workspace::ProjectDeployment.new manifest_file }
|
4
|
-
let(:
|
4
|
+
let(:manifest_content) { ruby_code + manifest.to_yaml }
|
5
|
+
let(:manifest_file) { get_tmp_file_path(manifest_content, file_name) }
|
5
6
|
let(:file_name) { "foo.yml" }
|
6
7
|
let(:manifest) { :manifest }
|
7
8
|
let(:ruby_code) { "<% ruby_var=42 %>" }
|
@@ -15,6 +16,47 @@ module Bosh::Workspace
|
|
15
16
|
end
|
16
17
|
end
|
17
18
|
|
19
|
+
describe '#manifest' do
|
20
|
+
let(:stub_file) { /stubs\/#{file_name}/ }
|
21
|
+
before do
|
22
|
+
allow(File).to receive(:exist?).with(manifest_file).and_return(true)
|
23
|
+
allow(File).to receive(:read).with(manifest_file).and_return(manifest_content)
|
24
|
+
end
|
25
|
+
|
26
|
+
context 'with stub file' do
|
27
|
+
let(:manifest) { { 'director_uuid' => '<%= p("stub.value") %>' } }
|
28
|
+
let(:stub_content) { "---\nproperties:\n stub:\n value: litmus\n" }
|
29
|
+
before do
|
30
|
+
allow(File).to receive(:exist?).with(stub_file).and_return(true)
|
31
|
+
allow(File).to receive(:read).with(stub_file).and_return(stub_content)
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'reads manifest using bosh-template render' do
|
35
|
+
expect(subject.manifest['director_uuid']).to eq('litmus')
|
36
|
+
end
|
37
|
+
|
38
|
+
context 'with missing properties' do
|
39
|
+
let(:stub_content) { "---\nproperties:\n stub: litmus\n" }
|
40
|
+
it 'raises error' do
|
41
|
+
expect { subject.manifest }.to raise_error /Can't find property/
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
46
|
+
|
47
|
+
context 'without stub file' do
|
48
|
+
let(:manifest) { { 'director_uuid' => 'litmus' } }
|
49
|
+
|
50
|
+
before do
|
51
|
+
allow(File).to receive(:exist?).with(stub_file).and_return(false)
|
52
|
+
end
|
53
|
+
|
54
|
+
it 'reads manifest without errors' do
|
55
|
+
expect(subject.manifest['director_uuid']).to eq('litmus')
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
18
60
|
describe "#perform_validation" do
|
19
61
|
context "valid" do
|
20
62
|
it "validates" do
|
data/spec/release_spec.rb
CHANGED
@@ -1,491 +1,506 @@
|
|
1
1
|
require "fileutils"
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
3
|
+
module Bosh::Workspace
|
4
|
+
describe Release do
|
5
|
+
let(:name) { "foo" }
|
6
|
+
let(:release) { load_release(release_data) }
|
7
|
+
let(:version) { "3" }
|
8
|
+
let(:url) { "http://local.url/release" }
|
9
|
+
let(:release_data) { { "name" => name, "version" => version, "git" => repo } }
|
10
|
+
let(:releases_dir) { File.join(asset_dir("manifests-repo"), ".releases") }
|
11
|
+
let(:templates) { Dir[File.join(releases_dir, name, "templates/*.yml")].to_s }
|
12
|
+
let(:callback) { proc {} }
|
13
|
+
|
14
|
+
def load_release(release_data, options = {}, skip_update = false)
|
15
|
+
Release.new(release_data, releases_dir, callback, options).tap do |r|
|
16
|
+
r.update_repo(options) unless skip_update
|
17
|
+
end
|
16
18
|
end
|
17
|
-
end
|
18
19
|
|
19
|
-
|
20
|
-
|
20
|
+
context "with new structure within 'releases' folder" do
|
21
|
+
let(:repo) { extracted_asset_dir("foo", "foo-boshrelease-repo-new-structure.zip") }
|
21
22
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
23
|
+
describe "#update_repo" do
|
24
|
+
subject do
|
25
|
+
Dir[File.join(releases_dir, name, "releases/**/foo*.yml")].to_s
|
26
|
+
end
|
26
27
|
|
27
|
-
|
28
|
-
|
28
|
+
context "latest version" do
|
29
|
+
before { release.update_repo }
|
29
30
|
|
30
|
-
|
31
|
+
let(:version) { "latest" }
|
31
32
|
|
32
|
-
|
33
|
-
|
33
|
+
it "checks out repo" do
|
34
|
+
expect(subject).to match(/releases\/foo\/foo-12.yml/)
|
35
|
+
end
|
34
36
|
end
|
35
|
-
end
|
36
37
|
|
37
|
-
|
38
|
-
|
38
|
+
context "version from before new structure" do
|
39
|
+
before { release.update_repo }
|
39
40
|
|
40
|
-
|
41
|
+
let(:version) { "11" }
|
41
42
|
|
42
|
-
|
43
|
-
|
43
|
+
it "checks out repo" do
|
44
|
+
expect(subject).to match(/releases\/foo-11.yml/)
|
45
|
+
end
|
44
46
|
end
|
45
47
|
end
|
46
|
-
end
|
47
48
|
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
subject { release }
|
53
|
-
|
54
|
-
its(:name) { should eq name }
|
55
|
-
its(:git_url) { should eq repo }
|
56
|
-
its(:repo_dir) { should match(/\/#{name}$/) }
|
57
|
-
its(:release_dir) { should match(/\/#{name}$/) }
|
58
|
-
its(:manifest) { should match "releases/#{name}/#{name}-#{version}.yml$" }
|
59
|
-
its(:name_version) { should eq "#{name}/#{version}" }
|
60
|
-
its(:version) { should eq version }
|
61
|
-
its(:manifest_file) do
|
62
|
-
should match(/\/releases\/#{name}\/#{name}-#{version}.yml$/)
|
63
|
-
end
|
49
|
+
describe "attributes" do
|
50
|
+
let(:release_data) { { "name" => name, "version" => version, "git" => repo } }
|
51
|
+
let(:version) { "12" }
|
64
52
|
|
65
|
-
|
66
|
-
context "with a version placeholder" do
|
67
|
-
let(:url) { "http://local.url/release?^VERSION^" }
|
68
|
-
let(:version) { "12" }
|
69
|
-
let(:release_data) { { "name" => name, "version" => version, "url" => url } }
|
53
|
+
subject { release }
|
70
54
|
|
71
|
-
|
72
|
-
|
73
|
-
|
55
|
+
its(:name) { should eq name }
|
56
|
+
its(:git_url) { should eq repo }
|
57
|
+
its(:repo_dir) { should match(/\/#{name}$/) }
|
58
|
+
its(:release_dir) { should match(/\/#{name}$/) }
|
59
|
+
its(:manifest) { should match "releases/#{name}/#{name}-#{version}.yml$" }
|
60
|
+
its(:name_version) { should eq "#{name}/#{version}" }
|
61
|
+
its(:version) { should eq version }
|
62
|
+
its(:manifest_file) do
|
63
|
+
should match(/\/releases\/#{name}\/#{name}-#{version}.yml$/)
|
74
64
|
end
|
75
65
|
|
76
|
-
context
|
77
|
-
|
78
|
-
|
79
|
-
|
66
|
+
context ", using a local url" do
|
67
|
+
context "with a version placeholder" do
|
68
|
+
let(:url) { "http://local.url/release?^VERSION^" }
|
69
|
+
let(:version) { "12" }
|
70
|
+
let(:release_data) { { "name" => name, "version" => version, "url" => url } }
|
71
|
+
|
72
|
+
it 'replaces the version placeholder with the version number' do
|
73
|
+
expect(release.url).to eq "http://local.url/release?12"
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
context 'with no version placeholder' do
|
78
|
+
let(:url) { "http://local.url/release" }
|
79
|
+
let(:version) { "12" }
|
80
|
+
let(:release_data) {{ "name" => name, "version" => version, "url" => url }}
|
80
81
|
|
81
|
-
|
82
|
-
|
82
|
+
it 'returns the same url' do
|
83
|
+
expect(release.url).to eq "http://local.url/release"
|
84
|
+
end
|
83
85
|
end
|
84
86
|
end
|
85
87
|
end
|
86
88
|
end
|
87
|
-
end
|
88
|
-
|
89
|
-
context "given a release with index + release v1 last touched on the same commit" do
|
90
|
-
let(:repo) { extracted_asset_dir("foo-bar", "foo-bar-boshrelease-repo.zip") }
|
91
|
-
let(:name) { "foo-bar" }
|
92
89
|
|
93
|
-
|
94
|
-
|
95
|
-
|
90
|
+
context "given a release with index + release v1 last touched on the same commit" do
|
91
|
+
let(:repo) { extracted_asset_dir("foo-bar", "foo-bar-boshrelease-repo.zip") }
|
92
|
+
let(:name) { "foo-bar" }
|
96
93
|
|
97
|
-
|
98
|
-
|
99
|
-
Dir[File.join(releases_dir, name, "releases/foo-bar/foo-bar*.yml")].to_s
|
94
|
+
before do
|
95
|
+
FileUtils.rm_rf(releases_dir)
|
100
96
|
end
|
101
97
|
|
102
|
-
|
103
|
-
|
98
|
+
describe "#update_repo" do
|
99
|
+
subject do
|
100
|
+
Dir[File.join(releases_dir, name, "releases/foo-bar/foo-bar*.yml")].to_s
|
101
|
+
end
|
102
|
+
|
103
|
+
context "latest version" do
|
104
|
+
before { release.update_repo }
|
104
105
|
let(:version) { "latest" }
|
105
106
|
it "checks out repo" do
|
106
|
-
|
107
|
+
expect(subject).to match(/releases\/foo-bar\/foo-bar-2.yml/)
|
108
|
+
end
|
107
109
|
end
|
108
110
|
end
|
109
|
-
end
|
110
111
|
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
112
|
+
describe "attributes" do
|
113
|
+
let(:version) { "1" }
|
114
|
+
subject { release }
|
115
|
+
its(:name) { should eq name}
|
116
|
+
its(:git_url) { should eq repo }
|
117
|
+
its(:repo_dir) { should match(/\/#{name}$/) }
|
118
|
+
its(:manifest) { should match "releases/#{name}/#{name}-#{version}.yml$" }
|
119
|
+
its(:name_version) { should eq "#{name}/#{version}" }
|
120
|
+
its(:version) { should eq version }
|
121
|
+
its(:manifest_file) do
|
122
|
+
should match(/\/releases\/#{name}\/#{name}-#{version}.yml$/)
|
123
|
+
end
|
122
124
|
end
|
123
125
|
end
|
124
|
-
end
|
125
126
|
|
127
|
+
context "given a release with submodule templates" do
|
128
|
+
let(:repo) { extracted_asset_dir("supermodule", "supermodule-boshrelease-repo.zip") }
|
129
|
+
let(:subrepo) { extracted_asset_dir("submodule-boshrelease", "submodule-boshrelease-repo.zip") }
|
130
|
+
let(:name) { "supermodule" }
|
131
|
+
let(:version) { "2" }
|
126
132
|
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
133
|
+
before do
|
134
|
+
FileUtils.rm_rf(releases_dir)
|
135
|
+
allow_any_instance_of(Rugged::Submodule).to receive(:url).and_return(subrepo)
|
136
|
+
end
|
131
137
|
|
132
|
-
|
133
|
-
|
134
|
-
context "with templates in submodules" do
|
135
|
-
before do
|
136
|
-
FileUtils.rm_rf(releases_dir)
|
137
|
-
allow_any_instance_of(Rugged::Submodule).to receive(:url).and_return(subrepo)
|
138
|
+
describe "#update_repo" do
|
139
|
+
subject { Rugged::Repository.new(File.join(releases_dir, name)) }
|
138
140
|
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
fetch_or_clone_repo(File.join(release.repo_dir, submodule.path), submodule.url)
|
143
|
-
release.update_submodule(submodule)
|
141
|
+
context "with templates in submodules" do
|
142
|
+
before do
|
143
|
+
release = load_release("name" => name, "version" => 1, "git" => repo)
|
144
144
|
end
|
145
|
-
end
|
146
145
|
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
it "doesn't clone/checkout extraneous submodules" do
|
152
|
-
expect(subject.submodules["src/other"].workdir_oid).to eq nil
|
153
|
-
end
|
154
|
-
end
|
155
|
-
context "with templates in submodules" do
|
156
|
-
before do
|
157
|
-
FileUtils.rm_rf(releases_dir)
|
158
|
-
allow_any_instance_of(Rugged::Submodule).to receive(:url).and_return(subrepo)
|
146
|
+
it "clones + checks out required submodules" do
|
147
|
+
expect(subject.submodules["src/submodule"].workdir_oid)
|
148
|
+
.to eq "2244c436777f7c305fb81a8a6e29079c92a2ab9d"
|
149
|
+
end
|
159
150
|
|
160
|
-
|
161
|
-
|
162
|
-
release.required_submodules.each do |submodule|
|
163
|
-
fetch_or_clone_repo(File.join(release.repo_dir, submodule.path), submodule.url)
|
164
|
-
release.update_submodule(submodule)
|
151
|
+
it "doesn't clone/checkout extraneous submodules" do
|
152
|
+
expect(subject.submodules["src/other"].workdir_oid).to eq nil
|
165
153
|
end
|
166
154
|
end
|
167
155
|
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
156
|
+
context "with templates in submodules" do
|
157
|
+
before { load_release(release_data) }
|
158
|
+
|
159
|
+
it "clones + checks out required submodules" do
|
160
|
+
expect(subject.submodules["src/submodule"].workdir_oid)
|
161
|
+
.to eq "95eed8c967af969d659a766b0551a75a729a7b65"
|
162
|
+
end
|
163
|
+
it "doesn't clone/checkout extraneous submodules" do
|
164
|
+
expect(subject.submodules["src/other"].workdir_oid).to eq nil
|
165
|
+
end
|
174
166
|
end
|
175
|
-
end
|
176
167
|
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
168
|
+
context "from v1 to v2" do
|
169
|
+
let(:version) { 1 }
|
170
|
+
before { load_release(release_data) }
|
171
|
+
|
172
|
+
it "updates the submodules appropriately" do
|
173
|
+
expect(subject.submodules["src/submodule"].workdir_oid)
|
174
|
+
.to eq "2244c436777f7c305fb81a8a6e29079c92a2ab9d"
|
175
|
+
expect(subject.submodules["src/other"].workdir_oid).to eq nil
|
176
|
+
|
177
|
+
# Now move to v2 on existing repo
|
178
|
+
release = load_release("name" => name, "version" => 2, "git" => repo)
|
179
|
+
release.update_repo
|
180
|
+
expect(subject.submodules["src/submodule"].workdir_oid)
|
181
|
+
.to eq "95eed8c967af969d659a766b0551a75a729a7b65"
|
182
|
+
expect(subject.submodules["src/other"].workdir_oid).to eq nil
|
183
|
+
end
|
181
184
|
end
|
182
185
|
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
release.update_submodule(submodule)
|
186
|
+
context "while being offline" do
|
187
|
+
subject { load_release(release_data, offline: true) }
|
188
|
+
|
189
|
+
it 'fails when repo does not yet exist' do
|
190
|
+
expect{ subject }.to raise_error /not allowed in offline mode/
|
189
191
|
end
|
190
|
-
expect(subject.submodules["src/submodule"].workdir_oid)
|
191
|
-
.to eq "2244c436777f7c305fb81a8a6e29079c92a2ab9d"
|
192
|
-
expect(subject.submodules["src/other"].workdir_oid).to eq nil
|
193
192
|
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
193
|
+
context "with an already cloned release" do
|
194
|
+
before { load_release(release_data) }
|
195
|
+
|
196
|
+
it 'validates local data exists' do
|
197
|
+
expect{ subject }.to_not raise_error
|
198
|
+
end
|
199
|
+
|
200
|
+
context "when using latest version" do
|
201
|
+
let(:version) { "latest" }
|
202
|
+
subject { load_release(release_data, { offline: true }, true) }
|
203
|
+
it 'warns when using latest while offline' do
|
204
|
+
expect(subject).to receive(:warning).with(/using 'latest' local/i)
|
205
|
+
subject.update_repo
|
206
|
+
end
|
207
|
+
end
|
200
208
|
end
|
201
|
-
expect(subject.submodules["src/submodule"].workdir_oid)
|
202
|
-
.to eq "95eed8c967af969d659a766b0551a75a729a7b65"
|
203
|
-
expect(subject.submodules["src/other"].workdir_oid).to eq nil
|
204
209
|
end
|
205
210
|
end
|
206
211
|
end
|
207
|
-
end
|
208
212
|
|
209
|
-
|
210
|
-
|
213
|
+
context "given a release with deprecated structure within 'releases' folder" do
|
214
|
+
let(:repo) { extracted_asset_dir("foo", "foo-boshrelease-repo.zip") }
|
211
215
|
|
212
|
-
|
213
|
-
|
216
|
+
describe "#update_repo" do
|
217
|
+
subject { Dir[File.join(releases_dir, name, "releases/foo*.yml")].to_s }
|
214
218
|
|
215
|
-
|
216
|
-
|
219
|
+
context "latest version" do
|
220
|
+
before { release.update_repo }
|
217
221
|
|
218
|
-
|
222
|
+
let(:version) { "latest" }
|
219
223
|
|
220
|
-
|
221
|
-
|
222
|
-
|
224
|
+
it "checks out repo" do
|
225
|
+
expect(subject).to match(/foo-12.yml/)
|
226
|
+
end
|
223
227
|
|
224
|
-
|
225
|
-
|
228
|
+
it "does not include templates from master" do
|
229
|
+
expect(templates).to_not match(/deployment.yml/)
|
230
|
+
end
|
226
231
|
end
|
227
|
-
end
|
228
232
|
|
229
|
-
|
230
|
-
|
231
|
-
|
233
|
+
context "specific version" do
|
234
|
+
let(:version) { "12" }
|
235
|
+
before { release.update_repo }
|
232
236
|
|
233
|
-
|
234
|
-
|
235
|
-
|
237
|
+
it "checks out repo" do
|
238
|
+
expect(subject).to match(/foo-11.yml/)
|
239
|
+
end
|
236
240
|
|
237
|
-
|
238
|
-
|
241
|
+
it "does not include templates from master" do
|
242
|
+
expect(templates).to_not match(/deployment.yml/)
|
243
|
+
end
|
239
244
|
end
|
240
|
-
end
|
241
245
|
|
242
|
-
|
243
|
-
|
246
|
+
context "specific version" do
|
247
|
+
let(:version) { "2" }
|
244
248
|
|
245
|
-
|
246
|
-
|
247
|
-
|
249
|
+
it "checks out repo" do
|
250
|
+
release.update_repo
|
251
|
+
expect(subject).to match(/foo-2.yml/)
|
252
|
+
end
|
248
253
|
end
|
249
|
-
end
|
250
254
|
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
+
context "specific ref with latest release" do
|
256
|
+
let(:release_data) do
|
257
|
+
{"name" => name, "version" => "latest", "ref" => "66658", "git" => repo}
|
258
|
+
end
|
255
259
|
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
+
it "checks out repo" do
|
261
|
+
release.update_repo
|
262
|
+
expect(subject).to match(/foo-2.yml/)
|
263
|
+
expect(subject).to_not match(/foo-3.yml/)
|
264
|
+
end
|
260
265
|
end
|
261
|
-
end
|
262
266
|
|
263
|
-
|
264
|
-
|
267
|
+
context "updated version" do
|
268
|
+
let(:version) { "11" }
|
265
269
|
|
266
|
-
|
267
|
-
|
268
|
-
|
270
|
+
it "checks out file with multiple commits" do
|
271
|
+
release.update_repo
|
272
|
+
expect(subject).to match(/foo-11.yml/)
|
273
|
+
end
|
269
274
|
end
|
270
|
-
end
|
271
275
|
|
272
|
-
|
273
|
-
|
276
|
+
context "non existing version " do
|
277
|
+
let(:version) { "13" }
|
274
278
|
|
275
|
-
|
276
|
-
|
277
|
-
|
279
|
+
it "raises an error" do
|
280
|
+
expect { release.update_repo }
|
281
|
+
.to raise_error(/Could not find version/)
|
282
|
+
end
|
278
283
|
end
|
279
|
-
end
|
280
284
|
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
+
context "already cloned repo" do
|
286
|
+
before do
|
287
|
+
load_release("name" => name, "version" => 1, "git" => repo).update_repo
|
288
|
+
end
|
285
289
|
|
286
|
-
|
287
|
-
|
288
|
-
|
290
|
+
it "version 3" do
|
291
|
+
release.update_repo
|
292
|
+
expect(subject).to match(/foo-3.yml/)
|
293
|
+
end
|
289
294
|
end
|
290
|
-
end
|
291
295
|
|
292
|
-
|
293
|
-
|
296
|
+
context "multiple releases" do
|
297
|
+
let(:version) { "11" }
|
294
298
|
|
295
|
-
|
296
|
-
|
297
|
-
|
299
|
+
before do
|
300
|
+
load_release("name" => "foo", "version" => 2, "git" => repo).update_repo
|
301
|
+
end
|
298
302
|
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
+
it "version 11" do
|
304
|
+
release.update_repo
|
305
|
+
expect(subject).to match(/foo-11.yml/)
|
306
|
+
expect(templates).to_not match(/deployment.yml/)
|
307
|
+
end
|
303
308
|
end
|
304
|
-
end
|
305
309
|
|
306
|
-
|
307
|
-
|
308
|
-
|
310
|
+
context "specific version" do
|
311
|
+
let(:version) { "11" }
|
312
|
+
before { release.update_repo }
|
309
313
|
|
310
|
-
|
311
|
-
|
312
|
-
|
314
|
+
it "checks out repo" do
|
315
|
+
expect(subject).to match(/foo-11.yml/)
|
316
|
+
end
|
313
317
|
|
314
|
-
|
315
|
-
|
318
|
+
it "does not include templates from master" do
|
319
|
+
expect(templates).to_not match(/deployment.yml/)
|
320
|
+
end
|
316
321
|
end
|
317
|
-
end
|
318
322
|
|
319
|
-
|
320
|
-
|
323
|
+
context "specific version" do
|
324
|
+
let(:version) { "2" }
|
321
325
|
|
322
|
-
|
323
|
-
|
324
|
-
|
326
|
+
it "checks out repo" do
|
327
|
+
release.update_repo
|
328
|
+
expect(subject).to match(/foo-2.yml/)
|
329
|
+
end
|
325
330
|
end
|
326
|
-
end
|
327
331
|
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
+
context "specific ref with latest release" do
|
333
|
+
let(:release_data) do
|
334
|
+
{"name" => name, "version" => "latest", "ref" => "66658", "git" => repo}
|
335
|
+
end
|
332
336
|
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
+
it "checks out repo" do
|
338
|
+
release.update_repo
|
339
|
+
expect(subject).to match(/foo-2.yml/)
|
340
|
+
expect(subject).to_not match(/foo-3.yml/)
|
341
|
+
end
|
337
342
|
end
|
338
|
-
end
|
339
343
|
|
340
|
-
|
341
|
-
|
344
|
+
context "updated version " do
|
345
|
+
let(:version) { "11" }
|
342
346
|
|
343
|
-
|
344
|
-
|
345
|
-
|
347
|
+
it "checks out file with multiple commits" do
|
348
|
+
release.update_repo
|
349
|
+
expect(subject).to match(/foo-11.yml/)
|
350
|
+
end
|
346
351
|
end
|
347
|
-
end
|
348
352
|
|
349
|
-
|
350
|
-
|
353
|
+
context "non existing version " do
|
354
|
+
let(:version) { "13" }
|
351
355
|
|
352
|
-
|
353
|
-
|
354
|
-
|
356
|
+
it "raises an error" do
|
357
|
+
expect { release.version }.
|
358
|
+
to raise_error(/Could not find version/)
|
359
|
+
end
|
355
360
|
end
|
356
|
-
end
|
357
361
|
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
|
362
|
+
context "already cloned repo" do
|
363
|
+
before do
|
364
|
+
load_release("name" => name, "version" => 1, "git" => repo).update_repo
|
365
|
+
end
|
362
366
|
|
363
|
-
|
364
|
-
|
365
|
-
|
367
|
+
it "version 3" do
|
368
|
+
release.update_repo
|
369
|
+
expect(subject).to match(/foo-3.yml/)
|
370
|
+
end
|
366
371
|
end
|
367
|
-
end
|
368
372
|
|
369
|
-
|
370
|
-
|
373
|
+
context "multiple releases" do
|
374
|
+
let(:version) { "11" }
|
371
375
|
|
372
|
-
|
373
|
-
|
374
|
-
|
376
|
+
before do
|
377
|
+
load_release("name" => "foo", "version" => 2, "git" => repo).update_repo
|
378
|
+
end
|
375
379
|
|
376
|
-
|
377
|
-
|
378
|
-
|
379
|
-
|
380
|
+
it "version 11" do
|
381
|
+
release.update_repo
|
382
|
+
expect(subject).to match(/foo-11.yml/)
|
383
|
+
expect(templates).to_not match(/deployment.yml/)
|
384
|
+
end
|
380
385
|
end
|
381
|
-
end
|
382
386
|
|
383
|
-
|
384
|
-
|
387
|
+
context "new release in already cloned repo" do
|
388
|
+
let(:version) { "12" }
|
385
389
|
|
386
|
-
|
387
|
-
|
388
|
-
|
389
|
-
|
390
|
+
before do
|
391
|
+
load_release("name" => name, "version" => 1, "git" => repo).update_repo
|
392
|
+
extracted_asset_dir("foo", "foo-boshrelease-repo-updated.zip")
|
393
|
+
end
|
390
394
|
|
391
|
-
|
392
|
-
|
393
|
-
|
395
|
+
it "version 12" do
|
396
|
+
release.update_repo
|
397
|
+
expect(subject).to match(/foo-12.yml/)
|
398
|
+
end
|
394
399
|
end
|
395
400
|
end
|
396
|
-
end
|
397
|
-
|
398
|
-
describe "attributes" do
|
399
|
-
subject { release }
|
400
|
-
its(:name) { should eq name }
|
401
|
-
its(:git_url) { should eq repo }
|
402
|
-
its(:repo_dir) { should match(/\/#{name}$/) }
|
403
|
-
its(:release_dir) { should match(/\/#{name}$/) }
|
404
|
-
its(:manifest_file) { should match(/\/#{name}-#{version}.yml$/) }
|
405
|
-
its(:manifest) { should match "releases/#{name}-#{version}.yml$" }
|
406
|
-
its(:name_version) { should eq "#{name}/#{version}" }
|
407
|
-
its(:version) { should eq version.to_s }
|
408
|
-
end
|
409
|
-
end
|
410
401
|
|
411
|
-
|
412
|
-
|
413
|
-
|
414
|
-
|
402
|
+
describe "attributes" do
|
403
|
+
subject { release }
|
404
|
+
its(:name) { should eq name }
|
405
|
+
its(:git_url) { should eq repo }
|
406
|
+
its(:repo_dir) { should match(/\/#{name}$/) }
|
407
|
+
its(:release_dir) { should match(/\/#{name}$/) }
|
408
|
+
its(:manifest_file) { should match(/\/#{name}-#{version}.yml$/) }
|
409
|
+
its(:manifest) { should match "releases/#{name}-#{version}.yml$" }
|
410
|
+
its(:name_version) { should eq "#{name}/#{version}" }
|
411
|
+
its(:version) { should eq version.to_s }
|
412
|
+
end
|
415
413
|
end
|
416
414
|
|
417
|
-
|
418
|
-
|
419
|
-
|
415
|
+
context "given a release which is located in a subfolder" do
|
416
|
+
let(:repo) { extracted_asset_dir("foo", "foo-boshrelease-repo-subdir.zip") }
|
417
|
+
let(:release_data) do
|
418
|
+
{ "name" => name, "version" => version, "git" => repo, "path" => "release" }
|
420
419
|
end
|
421
420
|
|
422
|
-
|
423
|
-
|
421
|
+
describe "#update_repo" do
|
422
|
+
subject do
|
423
|
+
Dir[File.join(releases_dir, name, "release/releases/**/*.yml")].to_s
|
424
|
+
end
|
424
425
|
|
425
|
-
|
426
|
+
context "latest version" do
|
427
|
+
before { release.update_repo }
|
426
428
|
|
427
|
-
|
428
|
-
|
429
|
+
let(:version) { "latest" }
|
430
|
+
|
431
|
+
it "checks out repo" do
|
432
|
+
expect(subject).to match(/release\/releases\/foo-12.yml/)
|
433
|
+
end
|
429
434
|
end
|
430
435
|
end
|
431
|
-
end
|
432
436
|
|
433
|
-
|
434
|
-
|
435
|
-
|
436
|
-
|
437
|
-
|
438
|
-
|
439
|
-
|
440
|
-
|
441
|
-
|
442
|
-
|
443
|
-
|
444
|
-
|
437
|
+
describe "attributes" do
|
438
|
+
let(:version) { "12" }
|
439
|
+
subject { release }
|
440
|
+
its(:name) { should eq name }
|
441
|
+
its(:git_url) { should eq repo }
|
442
|
+
its(:repo_dir) { should match(/\/#{name}$/) }
|
443
|
+
its(:release_dir) { should match(/\/#{name}\/release$/) }
|
444
|
+
its(:manifest) { should match "release/releases/#{name}-#{version}.yml$" }
|
445
|
+
its(:name_version) { should eq "#{name}/#{version}" }
|
446
|
+
its(:version) { should eq version }
|
447
|
+
its(:manifest_file) do
|
448
|
+
should match(/\/release\/releases\/#{name}-#{version}.yml$/)
|
449
|
+
end
|
445
450
|
end
|
446
451
|
end
|
447
|
-
end
|
448
452
|
|
449
|
-
|
450
|
-
|
451
|
-
|
452
|
-
|
453
|
-
|
454
|
-
|
455
|
-
|
456
|
-
|
453
|
+
context "correct checkout behavior:" do
|
454
|
+
let(:repo) { extracted_asset_dir("foo", "foo-boshrelease-repo.zip") }
|
455
|
+
let(:release_data) { { "name" => name, "version" => version,
|
456
|
+
"git" => repo, "ref" => :fooref } }
|
457
|
+
let(:repo) { 'foo/bar' }
|
458
|
+
let(:repository) do
|
459
|
+
instance_double('Rugged::Repository', lookup: double(oid: :fooref))
|
460
|
+
end
|
457
461
|
|
458
|
-
|
459
|
-
|
462
|
+
describe "#update_repo_with_ref" do
|
463
|
+
subject do
|
464
|
+
Release.new(release_data, releases_dir, callback)
|
465
|
+
end
|
460
466
|
|
461
|
-
|
462
|
-
|
463
|
-
|
467
|
+
before do
|
468
|
+
expect(Rugged::Repository).to receive(:new)
|
469
|
+
.and_return(repository).at_least(:once)
|
470
|
+
expect(repository).to receive(:fetch)
|
471
|
+
expect(repository).to receive(:references) do
|
472
|
+
{ 'refs/remotes/origin/HEAD' =>
|
473
|
+
double(resolve: double(target_id: :oid)) }
|
474
|
+
end
|
475
|
+
end
|
464
476
|
|
465
|
-
|
466
|
-
|
467
|
-
|
468
|
-
|
477
|
+
it "calls checkout_tree and checkout" do
|
478
|
+
expect(repository).to receive("checkout_tree").at_least(:once)
|
479
|
+
expect(repository).to receive("checkout").at_least(:once)
|
480
|
+
subject.update_repo
|
481
|
+
end
|
469
482
|
end
|
470
483
|
end
|
471
|
-
end
|
472
484
|
|
473
|
-
|
474
|
-
|
475
|
-
|
485
|
+
context "given a release which moved a directory to a symlink across versions" do
|
486
|
+
let(:repo) do
|
487
|
+
extracted_asset_dir("symlinkreplacement", "symlinkreplacement-boshrelease-repo.zip")
|
488
|
+
end
|
489
|
+
let(:name) { "symlinkreplacement" }
|
476
490
|
|
477
|
-
|
478
|
-
|
479
|
-
|
480
|
-
|
481
|
-
|
491
|
+
describe "#update_repo" do
|
492
|
+
subject { Rugged::Repository.new(File.join(releases_dir, name)) }
|
493
|
+
context "using a previous version should work" do
|
494
|
+
before do
|
495
|
+
FileUtils.rm_rf(releases_dir)
|
482
496
|
|
483
|
-
|
484
|
-
|
485
|
-
|
486
|
-
|
487
|
-
|
488
|
-
|
497
|
+
release = load_release("name" => name, "version" => "1", "git" => repo)
|
498
|
+
release.update_repo
|
499
|
+
end
|
500
|
+
it "git state is happy" do
|
501
|
+
expect(subject.head.target.oid).to eq "d96521d1940934b1941e0f4a462d3a5e9f31c75d"
|
502
|
+
expect(subject.diff_workdir(subject.head.target.oid).size).to eq 0
|
503
|
+
end
|
489
504
|
end
|
490
505
|
end
|
491
506
|
end
|