bosh-workspace 0.8.5 → 0.9.0.rc1

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 (52) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/.rspec +1 -2
  4. data/.ruby-gemset +1 -1
  5. data/.travis.yml +2 -0
  6. data/Guardfile +2 -2
  7. data/README.md +4 -4
  8. data/bosh-workspace.gemspec +2 -1
  9. data/lib/bosh/cli/commands/deployment_patch.rb +96 -0
  10. data/lib/bosh/cli/commands/prepare.rb +6 -4
  11. data/lib/bosh/workspace/credentials.rb +30 -0
  12. data/lib/bosh/workspace/deployment_patch.rb +90 -0
  13. data/lib/bosh/workspace/helpers/git_credentials_helper.rb +95 -0
  14. data/lib/bosh/workspace/helpers/spiff_helper.rb +1 -0
  15. data/lib/bosh/workspace/project_deployment.rb +2 -44
  16. data/lib/bosh/workspace/release.rb +20 -23
  17. data/lib/bosh/workspace/schemas/credentials.rb +27 -0
  18. data/lib/bosh/workspace/schemas/deployment_patch.rb +15 -0
  19. data/lib/bosh/workspace/schemas/project_deployment.rb +21 -0
  20. data/lib/bosh/workspace/schemas/releases.rb +16 -0
  21. data/lib/bosh/workspace/schemas/stemcells.rb +25 -0
  22. data/lib/bosh/workspace/shell.rb +67 -0
  23. data/lib/bosh/workspace/tasks/bosh_command_runner.rb +29 -0
  24. data/lib/bosh/workspace/tasks/deployment.rb +63 -0
  25. data/lib/bosh/workspace/tasks/workspace.rake +69 -0
  26. data/lib/bosh/workspace/tasks.rb +15 -0
  27. data/lib/bosh/workspace/version.rb +1 -1
  28. data/lib/bosh/workspace.rb +14 -0
  29. data/spec/assets/foo-boshrelease-repo-new-structure.zip +0 -0
  30. data/spec/assets/foo-boshrelease-repo-updated.zip +0 -0
  31. data/spec/assets/foo-boshrelease-repo.zip +0 -0
  32. data/spec/assets/foo-boshworkspace.zip +0 -0
  33. data/spec/commands/deployment_patch_spec.rb +152 -0
  34. data/spec/commands/prepare_spec.rb +5 -3
  35. data/spec/credentials_spec.rb +46 -0
  36. data/spec/deployment_patch_spec.rb +171 -0
  37. data/spec/helpers/git_credentials_helper_spec.rb +160 -0
  38. data/spec/helpers/spiff_helper_spec.rb +16 -3
  39. data/spec/project_deployment_spec.rb +52 -163
  40. data/spec/release_spec.rb +208 -80
  41. data/spec/schemas/credentials_spec.rb +28 -0
  42. data/spec/schemas/deployment_patch_spec.rb +30 -0
  43. data/spec/schemas/project_deployment_spec.rb +45 -0
  44. data/spec/schemas/releases_spec.rb +31 -0
  45. data/spec/schemas/stemcells_spec.rb +37 -0
  46. data/spec/shell_spec.rb +70 -0
  47. data/spec/spec_helper.rb +11 -5
  48. data/spec/support/shared_contexts/rake.rb +37 -0
  49. data/spec/tasks/bosh_command_runner_spec.rb +39 -0
  50. data/spec/tasks/deployment_spec.rb +80 -0
  51. data/spec/tasks/workspace_task_spec.rb +99 -0
  52. metadata +69 -7
data/spec/release_spec.rb CHANGED
@@ -1,123 +1,251 @@
1
1
  describe Bosh::Workspace::Release do
2
- let(:name) { "foo"}
2
+ include Bosh::Workspace::GitCredenialsHelper
3
+ let(:name) { "foo" }
4
+ let(:release) { load_release(release_data) }
3
5
  let(:version) { 3 }
4
- let(:repo) { extracted_asset_dir("foo", "foo-boshrelease-repo.zip") }
5
6
  let(:release_data) { { "name" => name, "version" => version, "git" => repo } }
6
7
  let(:releases_dir) { File.join(asset_dir("manifests-repo"), ".releases") }
7
- let(:release) { Bosh::Workspace::Release.new release_data, releases_dir }
8
8
  let(:templates) { Dir[File.join(releases_dir, name, "templates/*.yml")].to_s }
9
9
 
10
- describe "#update_repo" do
11
- subject { Dir[File.join(releases_dir, name, "releases/foo*.yml")].to_s }
12
-
13
- context "latest version" do
14
- before { release.update_repo }
10
+ def load_release(release_data)
11
+ Bosh::Workspace::Release.new(release_data, releases_dir).tap do |r|
12
+ fetch_or_clone_repo(r.repo_dir, repo)
13
+ end
14
+ end
15
15
 
16
- let(:version) { "latest" }
16
+ context "given a release with new structure within 'releases' folder" do
17
+ let(:repo) { extracted_asset_dir("foo", "foo-boshrelease-repo-new-structure.zip") }
17
18
 
18
- it "checks out repo" do
19
- expect(subject).to match(/foo-11.yml/)
19
+ describe "#update_repo" do
20
+ subject do
21
+ Dir[File.join(releases_dir, name, "releases/#{name}/foo*.yml")].to_s
20
22
  end
21
23
 
22
- it "does not include templates from master" do
23
- expect(templates).to_not match(/deployment.yml/)
24
+ context "latest version" do
25
+ before { release.update_repo }
26
+
27
+ let(:version) { "latest" }
28
+
29
+ it "checks out repo" do
30
+ expect(subject).to match(/foo-11.yml/)
31
+ end
32
+
33
+ it "does not include templates from master" do
34
+ expect(templates).to_not match(/deployment.yml/)
35
+ end
24
36
  end
25
37
  end
26
38
 
27
- context "specific version" do
28
- let(:version) { "11" }
29
- before { release.update_repo }
39
+ describe "attributes" do
40
+ subject { release }
41
+ its(:name) { should eq name }
42
+ its(:git_url) { should eq repo }
43
+ its(:repo_dir) { should match(/\/#{name}$/) }
44
+ its(:manifest_file) { should match(/\/#{name}-#{version}.yml$/) }
45
+ its(:manifest) { should match "releases/#{name}/#{name}-#{version}.yml$" }
46
+ its(:name_version) { should eq "#{name}/#{version}" }
47
+ its(:version) { should eq version }
48
+ end
49
+ end
50
+
51
+ context "given a release with deprecated structure within 'releases' folder" do
52
+ let(:repo) { extracted_asset_dir("foo", "foo-boshrelease-repo.zip") }
53
+
54
+ describe "#update_repo" do
55
+ subject { Dir[File.join(releases_dir, name, "releases/foo*.yml")].to_s }
56
+
57
+ context "latest version" do
58
+ before { release.update_repo }
59
+
60
+ let(:version) { "latest" }
61
+
62
+ it "checks out repo" do
63
+ expect(subject).to match(/foo-11.yml/)
64
+ end
30
65
 
31
- it "checks out repo" do
32
- expect(subject).to match(/foo-11.yml/)
66
+ it "does not include templates from master" do
67
+ expect(templates).to_not match(/deployment.yml/)
68
+ end
33
69
  end
34
70
 
35
- it "does not include templates from master" do
36
- expect(templates).to_not match(/deployment.yml/)
71
+ context "specific version" do
72
+ let(:version) { "11" }
73
+ before { release.update_repo }
74
+
75
+ it "checks out repo" do
76
+ expect(subject).to match(/foo-11.yml/)
77
+ end
78
+
79
+ it "does not include templates from master" do
80
+ expect(templates).to_not match(/deployment.yml/)
81
+ end
37
82
  end
38
- end
39
83
 
40
- context "specific version" do
41
- let(:version) { "2" }
84
+ context "specific version" do
85
+ let(:version) { "2" }
42
86
 
43
- it "checks out repo" do
44
- release.update_repo
45
- expect(subject).to match(/foo-2.yml/)
87
+ it "checks out repo" do
88
+ release.update_repo
89
+ expect(subject).to match(/foo-2.yml/)
90
+ end
46
91
  end
47
- end
48
92
 
49
- context "specific ref with latest release" do
50
- let(:release_data) do
51
- { "name" => name, "version" => "latest", "ref" => "66658", "git" => repo }
93
+ context "specific ref with latest release" do
94
+ let(:release_data) do
95
+ {"name" => name, "version" => "latest", "ref" => "66658", "git" => repo}
96
+ end
97
+
98
+ it "checks out repo" do
99
+ release.update_repo
100
+ expect(subject).to match(/foo-2.yml/)
101
+ expect(subject).to_not match(/foo-3.yml/)
102
+ end
52
103
  end
53
104
 
54
- it "checks out repo" do
55
- release.update_repo
56
- expect(subject).to match(/foo-2.yml/)
57
- expect(subject).to_not match(/foo-3.yml/)
105
+ context "updated version " do
106
+ let(:version) { "11" }
107
+
108
+ it "checks out file with multiple commits" do
109
+ release.update_repo
110
+ expect(subject).to match(/foo-11.yml/)
111
+ end
58
112
  end
59
- end
60
113
 
61
- context "updated version " do
62
- let(:version) { "11" }
114
+ context "non existing version " do
115
+ let(:version) { "12" }
63
116
 
64
- it "checks out file with multiple commits" do
65
- release.update_repo
66
- expect(subject).to match(/foo-11.yml/)
117
+ it "raises an error" do
118
+ expect { release.update_repo }.
119
+ to raise_error(/Could not find version/)
120
+ end
67
121
  end
68
- end
69
122
 
70
- context "non existing version " do
71
- let(:version) { "12" }
123
+ context "already cloned repo" do
124
+ before do
125
+ load_release("name" => name, "version" => 1, "git" => repo).update_repo
126
+ end
72
127
 
73
- it "raises an error" do
74
- expect { release.update_repo }.
75
- to raise_error(/Could not find version/)
128
+ it "version 3" do
129
+ release.update_repo
130
+ expect(subject).to match(/foo-3.yml/)
131
+ end
76
132
  end
77
- end
78
133
 
79
- context "already cloned repo" do
80
- before do
81
- data = { "name" => name, "version" => 1, "git" => repo }
82
- cloned_release = Bosh::Workspace::Release.new(data, releases_dir)
83
- cloned_release.update_repo
134
+ context "multiple releases" do
135
+ let(:version) { "11" }
136
+
137
+ before do
138
+ load_release("name" => "bar", "version" => 2, "git" => repo).update_repo
139
+ end
140
+
141
+ it "version 11" do
142
+ release.update_repo
143
+ expect(subject).to match(/foo-11.yml/)
144
+ expect(templates).to_not match(/deployment.yml/)
145
+ end
84
146
  end
85
147
 
86
- it "version 3" do
87
- release.update_repo
88
- expect(subject).to match(/foo-3.yml/)
148
+ context "specific version" do
149
+ let(:version) { "11" }
150
+ before { release.update_repo }
151
+
152
+ it "checks out repo" do
153
+ expect(subject).to match(/foo-11.yml/)
154
+ end
155
+
156
+ it "does not include templates from master" do
157
+ expect(templates).to_not match(/deployment.yml/)
158
+ end
89
159
  end
90
- end
91
160
 
92
- context "multiple releases" do
93
- let(:version) { "11" }
161
+ context "specific version" do
162
+ let(:version) { "2" }
94
163
 
95
- before do
96
- data = { "name" => "bar", "version" => 2, "git" => repo }
97
- other_release = Bosh::Workspace::Release.new(data, releases_dir)
98
- other_release.update_repo
164
+ it "checks out repo" do
165
+ release.update_repo
166
+ expect(subject).to match(/foo-2.yml/)
167
+ end
99
168
  end
100
169
 
101
- it "version 3" do
102
- release.update_repo
103
- expect(subject).to match(/foo-11.yml/)
104
- expect(templates).to_not match(/deployment.yml/)
170
+ context "specific ref with latest release" do
171
+ let(:release_data) do
172
+ {"name" => name, "version" => "latest", "ref" => "66658", "git" => repo}
173
+ end
174
+
175
+ it "checks out repo" do
176
+ release.update_repo
177
+ expect(subject).to match(/foo-2.yml/)
178
+ expect(subject).to_not match(/foo-3.yml/)
179
+ end
105
180
  end
106
- end
107
- end
108
181
 
109
- describe "attributes" do
110
- subject { release }
111
- its(:name){ should eq name }
112
- its(:git_uri){ should eq repo }
113
- its(:repo_dir){ should match(/\/#{name}$/) }
114
- its(:manifest_file){ should match(/\/#{name}-#{version}.yml$/) }
115
- its(:manifest){ should match "releases/#{name}-#{version}.yml$" }
116
- its(:name_version){ should eq "#{name}/#{version}" }
117
- its(:version){ should eq version }
118
- end
182
+ context "updated version " do
183
+ let(:version) { "11" }
184
+
185
+ it "checks out file with multiple commits" do
186
+ release.update_repo
187
+ expect(subject).to match(/foo-11.yml/)
188
+ end
189
+ end
190
+
191
+ context "non existing version " do
192
+ let(:version) { "12" }
193
+
194
+ it "raises an error" do
195
+ expect { release.version }.
196
+ to raise_error(/Could not find version/)
197
+ end
198
+ end
199
+
200
+ context "already cloned repo" do
201
+ before do
202
+ load_release("name" => name, "version" => 1, "git" => repo).update_repo
203
+ end
119
204
 
120
- after do
121
- FileUtils.rm_r releases_dir
205
+ it "version 3" do
206
+ release.update_repo
207
+ expect(subject).to match(/foo-3.yml/)
208
+ end
209
+ end
210
+
211
+ context "multiple releases" do
212
+ let(:version) { "11" }
213
+
214
+ before do
215
+ load_release("name" => "bar", "version" => 2, "git" => repo).update_repo
216
+ end
217
+
218
+ it "version 11" do
219
+ release.update_repo
220
+ expect(subject).to match(/foo-11.yml/)
221
+ expect(templates).to_not match(/deployment.yml/)
222
+ end
223
+ end
224
+
225
+ context "new release in already cloned repo" do
226
+ let(:version) { "12" }
227
+
228
+ before do
229
+ load_release("name" => name, "version" => 1, "git" => repo).update_repo
230
+ extracted_asset_dir("foo", "foo-boshrelease-repo-updated.zip")
231
+ end
232
+
233
+ it "version 12" do
234
+ release.update_repo
235
+ expect(subject).to match(/foo-12.yml/)
236
+ end
237
+ end
238
+ end
239
+
240
+ describe "attributes" do
241
+ subject { release }
242
+ its(:name) { should eq name }
243
+ its(:git_url) { should eq repo }
244
+ its(:repo_dir) { should match(/\/#{name}$/) }
245
+ its(:manifest_file) { should match(/\/#{name}-#{version}.yml$/) }
246
+ its(:manifest) { should match "releases/#{name}-#{version}.yml$" }
247
+ its(:name_version) { should eq "#{name}/#{version}" }
248
+ its(:version) { should eq version }
249
+ end
122
250
  end
123
251
  end
@@ -0,0 +1,28 @@
1
+ module Bosh::Workspace::Schemas
2
+ describe Credentials do
3
+ let(:username_password) do
4
+ { "url" => "foo", "username" => "bar", "password" => "baz" }
5
+ end
6
+ let(:ssh_key) do
7
+ { "url" => "bar", "private_key" => "foobarkey" }
8
+ end
9
+
10
+ subject { Credentials.new.validate(credentials) }
11
+
12
+ context "valid credentials" do
13
+ let(:credentials) { [username_password, ssh_key] }
14
+ it { expect { subject }.to_not raise_error }
15
+ end
16
+
17
+ %w(url username password private_key).each do |field_name|
18
+ context "missing #{field_name}" do
19
+ let(:credentials) do
20
+ [username_password, ssh_key].map do |c|
21
+ c.delete_if { |k| k == field_name }
22
+ end
23
+ end
24
+ it { expect { subject }.to raise_error(/doesn't validate/i) }
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,30 @@
1
+ module Bosh::Workspace::Schemas
2
+ describe DeploymentPatch do
3
+ before do
4
+ allow_any_instance_of(Releases).to receive(:validate).with(:releases)
5
+ allow_any_instance_of(Stemcells).to receive(:validate).with(:stemcells)
6
+ end
7
+
8
+ let(:deployment_patch) do
9
+ {
10
+ "stemcells" => :stemcells,
11
+ "releases" => :releases,
12
+ "templates_ref" => "477d1228a9f27815d6df3ab977235ab26eecbba6"
13
+ }
14
+ end
15
+
16
+ subject { DeploymentPatch.new.validate(deployment_patch) }
17
+
18
+ %w(stemcells releases).each do |field|
19
+ context "missing #{field}" do
20
+ before { deployment_patch.delete field }
21
+ it { expect { subject }.to raise_error(/#{field}.*missing/i) }
22
+ end
23
+ end
24
+
25
+ context "optional templates_ref" do
26
+ before { deployment_patch.delete "templates_ref" }
27
+ it { expect { subject }.to_not raise_error }
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,45 @@
1
+ module Bosh::Workspace::Schemas
2
+ describe ProjectDeployment do
3
+ before do
4
+ allow_any_instance_of(Releases).to receive(:validate).with(:releases)
5
+ allow_any_instance_of(Stemcells).to receive(:validate).with(:stemcells)
6
+ end
7
+
8
+ let(:project_deployment) do
9
+ {
10
+ "name" => "foo",
11
+ "director_uuid" => "e55134c3-0a63-47be-8409-c9e53e965d5c",
12
+ "stemcells" => :stemcells,
13
+ "releases" => :releases,
14
+ "templates" => [ "foo/bar.yml" ],
15
+ "meta" => { "foo" => "bar" }
16
+ }
17
+ end
18
+
19
+ subject { ProjectDeployment.new.validate(project_deployment) }
20
+
21
+ %w(name director_uuid releases templates meta stemcells).each do |field|
22
+ context "missing #{field}" do
23
+ before { project_deployment.delete field }
24
+ it { expect { subject }.to raise_error(/#{field}.*missing/i) }
25
+ end
26
+ end
27
+
28
+ context "optional domain_name" do
29
+ before { project_deployment["domain_name"] = "example.com" }
30
+ it { expect { subject }.to_not raise_error }
31
+ end
32
+
33
+ context "director_uuid" do
34
+ context "invalid" do
35
+ before { project_deployment["director_uuid"] = "invalid_uuid" }
36
+ it { expect { subject }.to raise_error(/director_uuid.*doesn't validate/) }
37
+ end
38
+
39
+ context "current" do
40
+ before { project_deployment["director_uuid"] = "current" }
41
+ it { expect { subject }.to_not raise_error }
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,31 @@
1
+ module Bosh::Workspace::Schemas
2
+ describe Releases do
3
+ let(:release) do
4
+ {"name" => "foo", "version" => 1, "ref" => "cec3ec1", "git" => "example.com/git.git"}
5
+ end
6
+
7
+ subject { Releases.new.validate(releases) }
8
+
9
+ %w(name version git).each do |field_name|
10
+ context "missing #{field_name}" do
11
+ let(:releases) { [release.delete_if { |k| k == field_name }] }
12
+ it { expect { subject }.to raise_error(/#{field_name}.*missing/i) }
13
+ end
14
+ end
15
+
16
+ context "latest version" do
17
+ let(:releases) { release["version"] = "latest"; [release] }
18
+ it { expect { subject }.to_not raise_error }
19
+ end
20
+
21
+ context "invalid version" do
22
+ let(:releases) { release["version"] = "foo"; [release] }
23
+ it { expect { subject }.to raise_error(/version.*doesn't validate/i) }
24
+ end
25
+
26
+ context "optional ref" do
27
+ let(:releases) { [release.delete_if { |k| k == "ref" }] }
28
+ it { expect { subject }.to_not raise_error }
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,37 @@
1
+ module Bosh::Workspace::Schemas
2
+ describe Stemcells do
3
+ let(:stemcell) do
4
+ {"name" => "foo", "version" => 1}
5
+ end
6
+
7
+ subject { Stemcells.new.validate(stemcells) }
8
+
9
+ %w(name version).each do |field_name|
10
+ context "missing #{field_name}" do
11
+ let(:stemcells) { [stemcell.delete_if { |k| k == field_name }] }
12
+ it { expect { subject }.to raise_error(/#{field_name}.*missing/i) }
13
+ end
14
+ end
15
+
16
+ context "latest version" do
17
+ let(:stemcells) { stemcell["version"] = "latest"; [stemcell] }
18
+ it { expect { subject }.to_not raise_error }
19
+ end
20
+
21
+ context "patch version string" do
22
+ let(:stemcells) { stemcell["version"] = "2719.1"; [stemcell] }
23
+ it { expect { subject }.to_not raise_error }
24
+ end
25
+
26
+ context "patch version float" do
27
+ let(:stemcells) { stemcell["version"] = 2719.1; [stemcell] }
28
+ it { expect { subject }.to_not raise_error }
29
+ end
30
+
31
+ context "invalid version" do
32
+ let(:stemcells) { stemcell["version"] = "foo"; [stemcell] }
33
+ it { expect { subject }.to raise_error(/version.*should match/i) }
34
+ end
35
+ end
36
+ end
37
+
@@ -0,0 +1,70 @@
1
+ module Bosh::Workspace
2
+ describe Shell do
3
+ subject { Shell.new(stdout) }
4
+ let(:stdout) { StringIO.new }
5
+
6
+ describe '#run' do
7
+ it 'shells out, prints and returns the output of the command' do
8
+ expect(subject.run('echo hello; echo world')).to eq("hello\nworld")
9
+ expect(stdout.string).to eq("hello\nworld\n")
10
+ end
11
+
12
+ it 'shells out with specified additional env variables' do
13
+ stub_const('ENV', 'SHELL' => '/bin/bash')
14
+ expect(subject.run('env env', env: { 'VAR' => '123' })).to include('VAR=123')
15
+ expect(stdout.string).to include('VAR=123')
16
+ end
17
+
18
+ it 'shells out with specified additional env variables even when SHELL env variable is not available' do
19
+ stub_const('ENV', {})
20
+ expect(subject.run('env env', env: { 'VAR' => '123' })).to include('VAR=123')
21
+ expect(stdout.string).to include('VAR=123')
22
+ end
23
+
24
+ context 'when "output_command" is specified' do
25
+ it 'outputs the command' do
26
+ subject.run('echo 1;echo 2;echo 3;echo 4;echo 5', output_command: true)
27
+ expect(stdout.string).to include('echo 1;echo 2;echo 3;echo 4;echo 5')
28
+ end
29
+ end
30
+
31
+ context 'when "last_number" is specified' do
32
+ it 'tails "last_number" lines of output' do
33
+ cmd = 'echo 1;echo 2;echo 3;echo 4;echo 5'
34
+ expect(subject.run(cmd, last_number: 3)).to eq("3\n4\n5")
35
+ expect(stdout.string).to eq("1\n2\n3\n4\n5\n")
36
+ end
37
+
38
+ it 'outputs the entire output if more lines are requested than generated' do
39
+ cmd = 'echo 1;echo 2;echo 3;echo 4;echo 5'
40
+ expect(subject.run(cmd, last_number: 6)).to eq("1\n2\n3\n4\n5")
41
+ expect(stdout.string).to eq("1\n2\n3\n4\n5\n")
42
+ end
43
+ end
44
+
45
+ context 'when the command fails' do
46
+ it 'raises an error' do
47
+ expect {
48
+ subject.run('false')
49
+ }.to raise_error /Failed: 'false' from /
50
+ end
51
+
52
+ context 'because the working directory has gone missing' do
53
+ it 'fails gracefully with a slightly helpful error message' do
54
+ allow(Dir).to receive(:pwd).and_raise(Errno::ENOENT, 'No such file or directory - getcwd')
55
+ expect {
56
+ subject.run('false')
57
+ }.to raise_error /from a deleted directory/
58
+ end
59
+ end
60
+
61
+ context 'and ignoring failures' do
62
+ it 'raises an error' do
63
+ subject.run('false', ignore_failures: true)
64
+ expect(stdout.string).to match(/continuing anyway/)
65
+ end
66
+ end
67
+ end
68
+ end
69
+ end
70
+ end
data/spec/spec_helper.rb CHANGED
@@ -19,8 +19,11 @@ require "archive/zip"
19
19
  require "cli"
20
20
 
21
21
  require "bosh/workspace"
22
+ require "bosh/workspace/tasks"
22
23
 
23
24
  RSpec.configure do |config|
25
+ config.filter_run focus: true
26
+ config.run_all_when_everything_filtered = true
24
27
  config.raise_errors_for_deprecations!
25
28
  config.expect_with :rspec do |c|
26
29
  c.syntax = :expect
@@ -28,7 +31,7 @@ RSpec.configure do |config|
28
31
  end
29
32
 
30
33
  # load all files in spec/support/* (but not lower down)
31
- Dir[File.dirname(__FILE__) + '/support/*'].each do |path|
34
+ Dir[File.dirname(__FILE__) + '/support/*/*.rb'].each do |path|
32
35
  require path unless File.directory?(path)
33
36
  end
34
37
 
@@ -81,9 +84,12 @@ end
81
84
  def extracted_asset_dir(name, *path)
82
85
  zipped_file = asset_dir(*path)
83
86
  target_dir = File.expand_path("../../tmp/#{name}", __FILE__)
84
- unless File.directory?(target_dir)
85
- FileUtils.mkdir_p(target_dir)
86
- Archive::Zip.extract(zipped_file, target_dir)
87
- end
87
+ FileUtils.rm_rf(target_dir) if File.exist?(target_dir)
88
+ FileUtils.mkdir_p(target_dir)
89
+ Archive::Zip.extract(zipped_file, target_dir)
88
90
  target_dir
89
91
  end
92
+
93
+ def project_root
94
+ File.expand_path('../../', __FILE__)
95
+ end
@@ -0,0 +1,37 @@
1
+ require "rake"
2
+
3
+ shared_context "rake" do
4
+ let(:rake) { Rake::Application.new }
5
+ let(:task_name) { self.class.top_level_description }
6
+ let(:task_path) { "lib/bosh/workspace/tasks/#{task_name.split(":").first}" }
7
+
8
+ def loaded_files_excluding_current_rake_file
9
+ $".reject { |file| file == File.join(project_root, "#{task_path}.rake") }
10
+ end
11
+
12
+ def clear_main_instance_vars
13
+ TOPLEVEL_BINDING.eval('self').instance_variables.each do |var|
14
+ TOPLEVEL_BINDING.eval('self').remove_instance_variable(var)
15
+ end
16
+ end
17
+
18
+ def setup_already_invoked_tasks
19
+ if defined? already_invoked_tasks
20
+ rake.instance_variable_get(:@tasks).each do |name, task|
21
+ if already_invoked_tasks.include? name
22
+ task.instance_variable_set(:@already_invoked, true)
23
+ end
24
+ end
25
+ end
26
+ end
27
+
28
+ before do
29
+ Rake.application = rake
30
+ Rake.application.rake_require(task_path, [project_root], loaded_files_excluding_current_rake_file)
31
+ setup_already_invoked_tasks
32
+ end
33
+
34
+ after do
35
+ clear_main_instance_vars
36
+ end
37
+ end