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.
Files changed (38) hide show
  1. checksums.yaml +4 -4
  2. data/bosh-workspace.gemspec +5 -4
  3. data/lib/bosh/cli/commands/deployment_patch.rb +0 -1
  4. data/lib/bosh/cli/commands/prepare.rb +12 -11
  5. data/lib/bosh/workspace.rb +4 -3
  6. data/lib/bosh/workspace/credentials.rb +12 -5
  7. data/lib/bosh/workspace/git_credentials_provider.rb +80 -0
  8. data/lib/bosh/workspace/{git_remote_url.rb → helpers/git_protocol_helper.rb} +4 -8
  9. data/lib/bosh/workspace/helpers/project_deployment_helper.rb +10 -2
  10. data/lib/bosh/workspace/helpers/release_helper.rb +33 -7
  11. data/lib/bosh/workspace/manifest_builder.rb +6 -8
  12. data/lib/bosh/workspace/merge_tool.rb +73 -0
  13. data/lib/bosh/workspace/project_deployment.rb +20 -5
  14. data/lib/bosh/workspace/release.rb +103 -67
  15. data/lib/bosh/workspace/schemas/credentials.rb +22 -0
  16. data/lib/bosh/workspace/schemas/project_deployment.rb +14 -1
  17. data/lib/bosh/workspace/version.rb +1 -1
  18. data/spec/assets/bin/spruce +0 -0
  19. data/spec/assets/manifests-repo/deployments/foo.yml +1 -0
  20. data/spec/assets/manifests-repo/stubs/foo.yml +4 -0
  21. data/spec/commands/prepare_spec.rb +39 -12
  22. data/spec/credentials_spec.rb +8 -0
  23. data/spec/git_credentials_provider_spec.rb +82 -0
  24. data/spec/{git_remote_url_spec.rb → helpers/git_protocol_helper_spec.rb} +10 -11
  25. data/spec/helpers/project_deployment_helper_spec.rb +12 -1
  26. data/spec/helpers/release_helper_spec.rb +157 -73
  27. data/spec/manifest_builder_spec.rb +6 -5
  28. data/spec/merge_tool_spec.rb +98 -0
  29. data/spec/project_deployment_spec.rb +43 -1
  30. data/spec/release_spec.rb +369 -354
  31. data/spec/rugged_spec.rb +64 -0
  32. data/spec/schemas/credentials_spec.rb +22 -5
  33. data/spec/spec_helper.rb +1 -0
  34. metadata +35 -15
  35. data/lib/bosh/workspace/helpers/git_credentials_helper.rb +0 -111
  36. data/lib/bosh/workspace/helpers/spiff_helper.rb +0 -34
  37. data/spec/helpers/git_credentials_helper_spec.rb +0 -190
  38. 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(:manifest_file) { get_tmp_file_path(ruby_code + manifest.to_yaml, file_name) }
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
@@ -1,491 +1,506 @@
1
1
  require "fileutils"
2
2
 
3
- describe Bosh::Workspace::Release do
4
- include Bosh::Workspace::GitCredentialsHelper
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
-
13
- def load_release(release_data)
14
- Bosh::Workspace::Release.new(release_data, releases_dir).tap do |r|
15
- fetch_or_clone_repo(r.repo_dir, repo)
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
- context "with new structure within 'releases' folder" do
20
- let(:repo) { extracted_asset_dir("foo", "foo-boshrelease-repo-new-structure.zip") }
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
- describe "#update_repo" do
23
- subject do
24
- Dir[File.join(releases_dir, name, "releases/**/foo*.yml")].to_s
25
- end
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
- context "latest version" do
28
- before { release.update_repo }
28
+ context "latest version" do
29
+ before { release.update_repo }
29
30
 
30
- let(:version) { "latest" }
31
+ let(:version) { "latest" }
31
32
 
32
- it "checks out repo" do
33
- expect(subject).to match(/releases\/foo\/foo-12.yml/)
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
- context "version from before new structure" do
38
- before { release.update_repo }
38
+ context "version from before new structure" do
39
+ before { release.update_repo }
39
40
 
40
- let(:version) { "11" }
41
+ let(:version) { "11" }
41
42
 
42
- it "checks out repo" do
43
- expect(subject).to match(/releases\/foo-11.yml/)
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
- describe "attributes" do
49
- let(:release_data) { { "name" => name, "version" => version, "git" => repo } }
50
- let(:version) { "12" }
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
- context ", using a local url" do
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
- it 'replaces the version placeholder with the version number' do
72
- expect(release.url).to eq "http://local.url/release?12"
73
- end
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 'with no version placeholder' do
77
- let(:url) { "http://local.url/release" }
78
- let(:version) { "12" }
79
- let(:release_data) {{ "name" => name, "version" => version, "url" => url }}
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
- it 'returns the same url' do
82
- expect(release.url).to eq "http://local.url/release"
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
- before do
94
- FileUtils.rm_rf(releases_dir)
95
- end
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
- describe "#update_repo" do
98
- subject do
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
- context "latest version" do
103
- before { release.update_repo }
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
- expect(subject).to match(/releases\/foo-bar\/foo-bar-2.yml/)
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
- describe "attributes" do
112
- let(:version) { "1" }
113
- subject { release }
114
- its(:name) { should eq name}
115
- its(:git_url) { should eq repo }
116
- its(:repo_dir) { should match(/\/#{name}$/) }
117
- its(:manifest) { should match "releases/#{name}/#{name}-#{version}.yml$" }
118
- its(:name_version) { should eq "#{name}/#{version}" }
119
- its(:version) { should eq version }
120
- its(:manifest_file) do
121
- should match(/\/releases\/#{name}\/#{name}-#{version}.yml$/)
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
- 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" }
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
- describe "#update_repo" do
133
- subject { Rugged::Repository.new(File.join(releases_dir, name)) }
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
- release = load_release( "name" => name, "version" => 1, "git" => repo)
140
- release.update_repo
141
- release.required_submodules.each do |submodule|
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
- it "clones + checks out required submodules" do
148
- expect(subject.submodules["src/submodule"].workdir_oid)
149
- .to eq "2244c436777f7c305fb81a8a6e29079c92a2ab9d"
150
- end
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
- release = load_release( "name" => name, "version" => 2, "git" => repo)
161
- release.update_repo
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
- it "clones + checks out required submodules" do
169
- expect(subject.submodules["src/submodule"].workdir_oid)
170
- .to eq "95eed8c967af969d659a766b0551a75a729a7b65"
171
- end
172
- it "doesn't clone/checkout extraneous submodules" do
173
- expect(subject.submodules["src/other"].workdir_oid).to eq nil
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
- context "from v1 to v2" do
178
- before do
179
- FileUtils.rm_rf(releases_dir)
180
- allow_any_instance_of(Rugged::Submodule).to receive(:url).and_return(subrepo)
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
- it "updates the submodules appropriately" do
184
- release = load_release("name" => name, "version" => 1, "git" => repo)
185
- release.update_repo
186
- release.required_submodules.each do |submodule|
187
- fetch_or_clone_repo(File.join(release.repo_dir, submodule.path), submodule.url)
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
- # Now move to v2 on existing repo
195
- release = load_release("name" => name, "version" => 2, "git" => repo)
196
- release.update_repo
197
- release.required_submodules.each do |submodule|
198
- fetch_or_clone_repo(File.join(release.repo_dir, submodule.path), submodule.url)
199
- release.update_submodule(submodule)
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
- context "given a release with deprecated structure within 'releases' folder" do
210
- let(:repo) { extracted_asset_dir("foo", "foo-boshrelease-repo.zip") }
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
- describe "#update_repo" do
213
- subject { Dir[File.join(releases_dir, name, "releases/foo*.yml")].to_s }
216
+ describe "#update_repo" do
217
+ subject { Dir[File.join(releases_dir, name, "releases/foo*.yml")].to_s }
214
218
 
215
- context "latest version" do
216
- before { release.update_repo }
219
+ context "latest version" do
220
+ before { release.update_repo }
217
221
 
218
- let(:version) { "latest" }
222
+ let(:version) { "latest" }
219
223
 
220
- it "checks out repo" do
221
- expect(subject).to match(/foo-12.yml/)
222
- end
224
+ it "checks out repo" do
225
+ expect(subject).to match(/foo-12.yml/)
226
+ end
223
227
 
224
- it "does not include templates from master" do
225
- expect(templates).to_not match(/deployment.yml/)
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
- context "specific version" do
230
- let(:version) { "12" }
231
- before { release.update_repo }
233
+ context "specific version" do
234
+ let(:version) { "12" }
235
+ before { release.update_repo }
232
236
 
233
- it "checks out repo" do
234
- expect(subject).to match(/foo-11.yml/)
235
- end
237
+ it "checks out repo" do
238
+ expect(subject).to match(/foo-11.yml/)
239
+ end
236
240
 
237
- it "does not include templates from master" do
238
- expect(templates).to_not match(/deployment.yml/)
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
- context "specific version" do
243
- let(:version) { "2" }
246
+ context "specific version" do
247
+ let(:version) { "2" }
244
248
 
245
- it "checks out repo" do
246
- release.update_repo
247
- expect(subject).to match(/foo-2.yml/)
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
- context "specific ref with latest release" do
252
- let(:release_data) do
253
- {"name" => name, "version" => "latest", "ref" => "66658", "git" => repo}
254
- end
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
- it "checks out repo" do
257
- release.update_repo
258
- expect(subject).to match(/foo-2.yml/)
259
- expect(subject).to_not match(/foo-3.yml/)
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
- context "updated version" do
264
- let(:version) { "11" }
267
+ context "updated version" do
268
+ let(:version) { "11" }
265
269
 
266
- it "checks out file with multiple commits" do
267
- release.update_repo
268
- expect(subject).to match(/foo-11.yml/)
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
- context "non existing version " do
273
- let(:version) { "13" }
276
+ context "non existing version " do
277
+ let(:version) { "13" }
274
278
 
275
- it "raises an error" do
276
- expect { release.update_repo }.
277
- to raise_error(/Could not find version/)
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
- context "already cloned repo" do
282
- before do
283
- load_release("name" => name, "version" => 1, "git" => repo).update_repo
284
- end
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
- it "version 3" do
287
- release.update_repo
288
- expect(subject).to match(/foo-3.yml/)
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
- context "multiple releases" do
293
- let(:version) { "11" }
296
+ context "multiple releases" do
297
+ let(:version) { "11" }
294
298
 
295
- before do
296
- load_release("name" => "foo", "version" => 2, "git" => repo).update_repo
297
- end
299
+ before do
300
+ load_release("name" => "foo", "version" => 2, "git" => repo).update_repo
301
+ end
298
302
 
299
- it "version 11" do
300
- release.update_repo
301
- expect(subject).to match(/foo-11.yml/)
302
- expect(templates).to_not match(/deployment.yml/)
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
- context "specific version" do
307
- let(:version) { "11" }
308
- before { release.update_repo }
310
+ context "specific version" do
311
+ let(:version) { "11" }
312
+ before { release.update_repo }
309
313
 
310
- it "checks out repo" do
311
- expect(subject).to match(/foo-11.yml/)
312
- end
314
+ it "checks out repo" do
315
+ expect(subject).to match(/foo-11.yml/)
316
+ end
313
317
 
314
- it "does not include templates from master" do
315
- expect(templates).to_not match(/deployment.yml/)
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
- context "specific version" do
320
- let(:version) { "2" }
323
+ context "specific version" do
324
+ let(:version) { "2" }
321
325
 
322
- it "checks out repo" do
323
- release.update_repo
324
- expect(subject).to match(/foo-2.yml/)
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
- context "specific ref with latest release" do
329
- let(:release_data) do
330
- {"name" => name, "version" => "latest", "ref" => "66658", "git" => repo}
331
- end
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
- it "checks out repo" do
334
- release.update_repo
335
- expect(subject).to match(/foo-2.yml/)
336
- expect(subject).to_not match(/foo-3.yml/)
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
- context "updated version " do
341
- let(:version) { "11" }
344
+ context "updated version " do
345
+ let(:version) { "11" }
342
346
 
343
- it "checks out file with multiple commits" do
344
- release.update_repo
345
- expect(subject).to match(/foo-11.yml/)
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
- context "non existing version " do
350
- let(:version) { "13" }
353
+ context "non existing version " do
354
+ let(:version) { "13" }
351
355
 
352
- it "raises an error" do
353
- expect { release.version }.
354
- to raise_error(/Could not find version/)
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
- context "already cloned repo" do
359
- before do
360
- load_release("name" => name, "version" => 1, "git" => repo).update_repo
361
- end
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
- it "version 3" do
364
- release.update_repo
365
- expect(subject).to match(/foo-3.yml/)
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
- context "multiple releases" do
370
- let(:version) { "11" }
373
+ context "multiple releases" do
374
+ let(:version) { "11" }
371
375
 
372
- before do
373
- load_release("name" => "foo", "version" => 2, "git" => repo).update_repo
374
- end
376
+ before do
377
+ load_release("name" => "foo", "version" => 2, "git" => repo).update_repo
378
+ end
375
379
 
376
- it "version 11" do
377
- release.update_repo
378
- expect(subject).to match(/foo-11.yml/)
379
- expect(templates).to_not match(/deployment.yml/)
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
- context "new release in already cloned repo" do
384
- let(:version) { "12" }
387
+ context "new release in already cloned repo" do
388
+ let(:version) { "12" }
385
389
 
386
- before do
387
- load_release("name" => name, "version" => 1, "git" => repo).update_repo
388
- extracted_asset_dir("foo", "foo-boshrelease-repo-updated.zip")
389
- end
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
- it "version 12" do
392
- release.update_repo
393
- expect(subject).to match(/foo-12.yml/)
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
- context "given a release which is located in a subfolder" do
412
- let(:repo) { extracted_asset_dir("foo", "foo-boshrelease-repo-subdir.zip") }
413
- let(:release_data) do
414
- { "name" => name, "version" => version, "git" => repo, "path" => "release" }
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
- describe "#update_repo" do
418
- subject do
419
- Dir[File.join(releases_dir, name, "release/releases/**/*.yml")].to_s
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
- context "latest version" do
423
- before { release.update_repo }
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
- let(:version) { "latest" }
426
+ context "latest version" do
427
+ before { release.update_repo }
426
428
 
427
- it "checks out repo" do
428
- expect(subject).to match(/release\/releases\/foo-12.yml/)
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
- describe "attributes" do
434
- let(:version) { "12" }
435
- subject { release }
436
- its(:name) { should eq name }
437
- its(:git_url) { should eq repo }
438
- its(:repo_dir) { should match(/\/#{name}$/) }
439
- its(:release_dir) { should match(/\/#{name}\/release$/) }
440
- its(:manifest) { should match "release/releases/#{name}-#{version}.yml$" }
441
- its(:name_version) { should eq "#{name}/#{version}" }
442
- its(:version) { should eq version }
443
- its(:manifest_file) do
444
- should match(/\/release\/releases\/#{name}-#{version}.yml$/)
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
- context "correct checkout behavior:" do
450
- let(:repo) { extracted_asset_dir("foo", "foo-boshrelease-repo.zip") }
451
- let(:release_data) { { "name" => name, "version" => version,
452
- "git" => repo, "ref" => :fooref } }
453
- let(:repo) { 'foo/bar' }
454
- let(:repository) do
455
- instance_double('Rugged::Repository', lookup: double(oid: :fooref))
456
- end
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
- describe "#update_repo_with_ref" do
459
- subject { Bosh::Workspace::Release.new(release_data, releases_dir) }
462
+ describe "#update_repo_with_ref" do
463
+ subject do
464
+ Release.new(release_data, releases_dir, callback)
465
+ end
460
466
 
461
- before do
462
- expect(Rugged::Repository).to receive(:new).and_return(repository)
463
- end
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
- it "calls checkout_tree and checkout" do
466
- expect(repository).to receive("checkout_tree").at_least(:once)
467
- expect(repository).to receive("checkout").at_least(:once)
468
- subject.update_repo
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
- context "given a release which moved a directory to a symlink across versions" do
474
- let(:repo) { extracted_asset_dir("symlinkreplacement", "symlinkreplacement-boshrelease-repo.zip") }
475
- let(:name) { "symlinkreplacement" }
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
- describe "#update_repo" do
478
- subject { Rugged::Repository.new(File.join(releases_dir, name)) }
479
- context "using a previous version should work" do
480
- before do
481
- FileUtils.rm_rf(releases_dir)
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
- release = load_release("name" => name, "version" => "1", "git" => repo)
484
- release.update_repo
485
- end
486
- it "git state is happy" do
487
- expect(subject.head.target.oid).to eq "d96521d1940934b1941e0f4a462d3a5e9f31c75d"
488
- expect(subject.diff_workdir(subject.head.target.oid).size).to eq 0
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