cookbook-omnifetch 0.7.0 → 0.10.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (41) hide show
  1. checksums.yaml +5 -5
  2. data/lib/cookbook-omnifetch.rb +17 -13
  3. data/lib/cookbook-omnifetch/artifactory.rb +10 -5
  4. data/lib/cookbook-omnifetch/artifactserver.rb +1 -1
  5. data/lib/cookbook-omnifetch/base.rb +1 -1
  6. data/lib/cookbook-omnifetch/chef_server.rb +14 -3
  7. data/lib/cookbook-omnifetch/chef_server_artifact.rb +15 -4
  8. data/lib/cookbook-omnifetch/git.rb +3 -3
  9. data/lib/cookbook-omnifetch/integration.rb +6 -1
  10. data/lib/cookbook-omnifetch/metadata_based_installer.rb +14 -13
  11. data/lib/cookbook-omnifetch/path.rb +1 -1
  12. data/lib/cookbook-omnifetch/threaded_job_queue.rb +1 -1
  13. data/lib/cookbook-omnifetch/version.rb +1 -1
  14. metadata +15 -85
  15. data/.gitignore +0 -23
  16. data/.rspec +0 -1
  17. data/.travis.yml +0 -11
  18. data/Gemfile +0 -8
  19. data/README.md +0 -90
  20. data/Rakefile +0 -19
  21. data/cookbook-omnifetch.gemspec +0 -39
  22. data/spec/fixtures/cookbooks/example_cookbook-0.5.0/README.md +0 -12
  23. data/spec/fixtures/cookbooks/example_cookbook-0.5.0/metadata.rb +0 -3
  24. data/spec/fixtures/cookbooks/example_cookbook-0.5.0/recipes/default.rb +0 -8
  25. data/spec/fixtures/cookbooks/example_cookbook/.gitignore +0 -2
  26. data/spec/fixtures/cookbooks/example_cookbook/.kitchen.yml +0 -26
  27. data/spec/fixtures/cookbooks/example_cookbook/Berksfile +0 -1
  28. data/spec/fixtures/cookbooks/example_cookbook/Berksfile.lock +0 -3
  29. data/spec/fixtures/cookbooks/example_cookbook/README.md +0 -12
  30. data/spec/fixtures/cookbooks/example_cookbook/metadata.rb +0 -3
  31. data/spec/fixtures/cookbooks/example_cookbook/recipes/default.rb +0 -8
  32. data/spec/spec_helper.rb +0 -43
  33. data/spec/unit/artifactory_spec.rb +0 -64
  34. data/spec/unit/artifactserver_spec.rb +0 -116
  35. data/spec/unit/base_spec.rb +0 -87
  36. data/spec/unit/chef_server_artifact_spec.rb +0 -74
  37. data/spec/unit/chef_server_spec.rb +0 -72
  38. data/spec/unit/exceptions_spec.rb +0 -87
  39. data/spec/unit/git_spec.rb +0 -290
  40. data/spec/unit/metadata_based_installer_spec.rb +0 -137
  41. data/spec/unit/path_spec.rb +0 -119
@@ -1,87 +0,0 @@
1
- require "spec_helper"
2
- require "cookbook-omnifetch/base"
3
-
4
- module CookbookOmnifetch
5
- describe BaseLocation do
6
- let(:constraint) { double("constraint") }
7
- let(:dependency) { double("dependency", name: "cookbook", version_constraint: constraint) }
8
-
9
- subject { described_class.new(dependency) }
10
-
11
- describe "#installed?" do
12
- it "is an abstract function" do
13
- expect { subject.installed? }.to raise_error(AbstractFunction)
14
- end
15
- end
16
-
17
- describe "#install" do
18
- it "is an abstract function" do
19
- expect { subject.install }.to raise_error(AbstractFunction)
20
- end
21
- end
22
-
23
- describe "#cached_cookbook" do
24
- it "is an abstract function" do
25
- expect { subject.cached_cookbook }.to raise_error(AbstractFunction)
26
- end
27
- end
28
-
29
- describe "#to_lock" do
30
- it "is an abstract function" do
31
- expect { subject.to_lock }.to raise_error(AbstractFunction)
32
- end
33
- end
34
-
35
- describe "#lock_data" do
36
- it "is an abstract function" do
37
- expect { subject.lock_data }.to raise_error(AbstractFunction)
38
- end
39
- end
40
-
41
- describe "#validate_cached!" do
42
- context "when the path is not a cookbook" do
43
- before { CookbookOmnifetch.stub(:cookbook?).and_return(false) }
44
-
45
- it "raises an error" do
46
- expect do
47
- subject.validate_cached!("/foo/bar")
48
- end.to raise_error(NotACookbook)
49
- end
50
- end
51
-
52
- context "when the path is a cookbook" do
53
- let(:cookbook) do
54
- double("cookbook",
55
- cookbook_name: "cookbook",
56
- version: "0.1.0"
57
- )
58
- end
59
-
60
- before do
61
- CookbookOmnifetch.stub(:cookbook?).and_return(true)
62
- MockCachedCookbook.stub(:from_path).and_return(cookbook)
63
- end
64
-
65
- it "raises an error if the constraint does not satisfy" do
66
- constraint.stub(:satisfies?).with("0.1.0").and_return(false)
67
- expect do
68
- subject.validate_cached!(cookbook)
69
- end.to raise_error(CookbookValidationFailure)
70
- end
71
-
72
- it "raises an error if the names do not match" do
73
- constraint.stub(:satisfies?).with("0.1.0").and_return(true)
74
- cookbook.stub(:cookbook_name).and_return("different_name")
75
- expect do
76
- subject.validate_cached!(cookbook)
77
- end.to raise_error(MismatchedCookbookName)
78
- end
79
-
80
- it "returns true when the validation succeeds" do
81
- constraint.stub(:satisfies?).with("0.1.0").and_return(true)
82
- expect(subject.validate_cached!(cookbook)).to be true
83
- end
84
- end
85
- end
86
- end
87
- end
@@ -1,74 +0,0 @@
1
- require "spec_helper"
2
- require "cookbook-omnifetch/chef_server.rb"
3
-
4
- RSpec.describe CookbookOmnifetch::ChefServerArtifactLocation do
5
-
6
- let(:http_client) { double("Http Client") }
7
-
8
- let(:test_root) { "/some/fake/path" }
9
-
10
- let(:storage_path) { File.join(test_root, "storage") }
11
-
12
- let(:dependency) { double("Dependency", name: cookbook_name) }
13
-
14
- let(:cookbook_name) { "example" }
15
-
16
- let(:cookbook_identifier) { "467dc855408ce8b74f991c5dc2fd72a6aa369b60" }
17
-
18
- let(:url) { "https://chef.example.com/organizations/example" }
19
-
20
- let(:options) { { chef_server_artifact: url, identifier: cookbook_identifier, http_client: http_client } }
21
-
22
- let(:expected_cache_key) { "example-467dc855408ce8b74f991c5dc2fd72a6aa369b60" }
23
-
24
- subject(:chef_server_artifact_location) { described_class.new(dependency, options) }
25
-
26
- before do
27
- allow(CookbookOmnifetch).to receive(:storage_path).and_return(Pathname.new(storage_path))
28
- end
29
-
30
- it "has a URI" do
31
- expect(chef_server_artifact_location.uri).to eq(url)
32
- end
33
-
34
- it "has an HTTP client" do
35
- expect(chef_server_artifact_location.http_client).to eq(http_client)
36
- end
37
-
38
- it "has a metadata_based_installer" do
39
- installer = chef_server_artifact_location.installer
40
- expect(installer).to be_a(CookbookOmnifetch::MetadataBasedInstaller)
41
- expect(installer.http_client).to eq(http_client)
42
- expect(installer.url_path).to eq("/cookbook_artifacts/example/467dc855408ce8b74f991c5dc2fd72a6aa369b60")
43
- expect(installer.install_path.to_s).to eq(File.join(storage_path, expected_cache_key))
44
- end
45
-
46
- it "has a cache key containing the site URI and version" do
47
- expect(chef_server_artifact_location.cache_key).to eq(expected_cache_key)
48
- end
49
-
50
- it "has an identifier" do
51
- expect(chef_server_artifact_location.cookbook_identifier).to eq(cookbook_identifier)
52
- end
53
-
54
- it "provides lock data as a Hash" do
55
- expected_data = {
56
- "chef_server" => url,
57
- "server_identifier" => cookbook_identifier,
58
- }
59
- expect(chef_server_artifact_location.lock_data).to eq(expected_data)
60
- end
61
-
62
- describe "when installing" do
63
-
64
- let(:installer) { instance_double("CookbookOmnifetch::MetadataBasedInstaller") }
65
-
66
- it "delegates to the MetadataBasedInstaller" do
67
- allow(chef_server_artifact_location).to receive(:installer).and_return(installer)
68
- expect(installer).to receive(:install)
69
- chef_server_artifact_location.install
70
- end
71
-
72
- end
73
-
74
- end
@@ -1,72 +0,0 @@
1
- require "spec_helper"
2
- require "cookbook-omnifetch/chef_server.rb"
3
-
4
- RSpec.describe CookbookOmnifetch::ChefServerLocation do
5
-
6
- let(:http_client) { double("Http Client") }
7
-
8
- let(:test_root) { "/some/fake/path" }
9
-
10
- let(:storage_path) { File.join(test_root, "storage") }
11
-
12
- let(:dependency) { double("Dependency", name: cookbook_name) }
13
-
14
- let(:cookbook_name) { "example" }
15
-
16
- let(:cookbook_version) { "0.5.0" }
17
-
18
- let(:url) { "https://chef.example.com/organizations/example" }
19
-
20
- let(:options) { { chef_server: url, version: cookbook_version, http_client: http_client } }
21
-
22
- subject(:chef_server_location) { described_class.new(dependency, options) }
23
-
24
- before do
25
- allow(CookbookOmnifetch).to receive(:storage_path).and_return(Pathname.new(storage_path))
26
- end
27
-
28
- it "has a URI" do
29
- expect(chef_server_location.uri).to eq(url)
30
- end
31
-
32
- it "has an HTTP client" do
33
- expect(chef_server_location.http_client).to eq(http_client)
34
- end
35
-
36
- it "has a metadata_based_installer" do
37
- installer = chef_server_location.installer
38
- expect(installer).to be_a(CookbookOmnifetch::MetadataBasedInstaller)
39
- expect(installer.http_client).to eq(http_client)
40
- expect(installer.url_path).to eq("/cookbooks/example/0.5.0")
41
- expect(installer.install_path.to_s).to eq(File.join(storage_path, "example-0.5.0"))
42
- end
43
-
44
- it "has a cache key containing the site URI and version" do
45
- expect(chef_server_location.cache_key).to eq("example-0.5.0")
46
- end
47
-
48
- it "has an exact version" do
49
- expect(chef_server_location.cookbook_version).to eq("0.5.0")
50
- end
51
-
52
- it "provides lock data as a Hash" do
53
- expected_data = {
54
- "chef_server" => url,
55
- "version" => "0.5.0",
56
- }
57
- expect(chef_server_location.lock_data).to eq(expected_data)
58
- end
59
-
60
- describe "when installing" do
61
-
62
- let(:installer) { instance_double("CookbookOmnifetch::MetadataBasedInstaller") }
63
-
64
- it "delegates to the MetadataBasedInstaller" do
65
- allow(chef_server_location).to receive(:installer).and_return(installer)
66
- expect(installer).to receive(:install)
67
- chef_server_location.install
68
- end
69
-
70
- end
71
-
72
- end
@@ -1,87 +0,0 @@
1
- require "spec_helper"
2
- require "cookbook-omnifetch/exceptions"
3
-
4
- module CookbookOmnifetch
5
- describe "Exceptions" do
6
-
7
- describe NotACookbook do
8
-
9
- subject(:exception) do
10
- described_class.new("/path/to/cookbook")
11
- end
12
-
13
- let(:message) do
14
- "The resource at '/path/to/cookbook' does not appear to be a valid cookbook. Does it have a metadata.rb?"
15
- end
16
-
17
- it "creates an informative error in #message" do
18
- expect(exception.message).to eq(message)
19
- end
20
-
21
- it "creates an informative error in #to_s" do
22
- expect(exception.to_s).to eq(message)
23
- end
24
-
25
- end
26
-
27
- describe CookbookValidationFailure do
28
-
29
- let(:dependency) { instance_double("ChefDK::Policyfile::CookbookLocationSpecification", to_s: "apt ~> 1.2.3") }
30
-
31
- # The exception class itself doesn't use this
32
- let(:cached_cookbook) { Object.new }
33
-
34
- subject(:exception) do
35
- described_class.new(dependency, cached_cookbook)
36
- end
37
-
38
- let(:message) do
39
- "The cookbook downloaded for apt ~> 1.2.3 did not satisfy the constraint."
40
- end
41
-
42
- it "creates an informative error in #message" do
43
- expect(exception.message).to eq(message)
44
- end
45
-
46
- it "creates an informative error in #to_s" do
47
- expect(exception.to_s).to eq(message)
48
- end
49
-
50
- end
51
-
52
- describe MismatchedCookbookName do
53
-
54
- let(:dependency) { instance_double("ChefDK::Policyfile::CookbookLocationSpecification", name: "apt") }
55
-
56
- let(:cached_cookbook) { instance_double("Chef::Cookbook", cookbook_name: "apt") }
57
-
58
- subject(:exception) do
59
- described_class.new(dependency, cached_cookbook)
60
- end
61
-
62
- let(:message) do
63
- <<-EOM
64
- In your Berksfile, you have:
65
-
66
- cookbook 'apt'
67
-
68
- But that cookbook is actually named 'apt'
69
-
70
- This can cause potentially unwanted side-effects in the future.
71
-
72
- NOTE: If you do not explicitly set the 'name' attribute in the metadata, the name of the directory will be used instead. This is often a cause of confusion for dependency solving.
73
- EOM
74
- end
75
-
76
- it "creates an informative error in #message" do
77
- expect(exception.message).to eq(message)
78
- end
79
-
80
- it "creates an informative error in #to_s" do
81
- expect(exception.to_s).to eq(message)
82
- end
83
-
84
- end
85
-
86
- end
87
- end
@@ -1,290 +0,0 @@
1
- require "spec_helper"
2
- require "cookbook-omnifetch/git"
3
-
4
- module CookbookOmnifetch
5
- describe GitLocation do
6
- let(:dependency) { double(name: "bacon") }
7
-
8
- subject do
9
- described_class.new(dependency, git: "https://repo.com", branch: "ham",
10
- tag: "v1.2.3", ref: "abc123", revision: "defjkl123456", rel: "hi")
11
- end
12
-
13
- describe ".initialize" do
14
- it "sets the uri" do
15
- instance = described_class.new(dependency, git: "https://repo.com")
16
- expect(instance.uri).to eq("https://repo.com")
17
- end
18
-
19
- it "sets the branch" do
20
- instance = described_class.new(dependency,
21
- git: "https://repo.com", branch: "magic_new_feature")
22
- expect(instance.branch).to eq("magic_new_feature")
23
- end
24
-
25
- it "sets the tag" do
26
- instance = described_class.new(dependency,
27
- git: "https://repo.com", tag: "v1.2.3")
28
- expect(instance.tag).to eq("v1.2.3")
29
- end
30
-
31
- it "adds the ref" do
32
- instance = described_class.new(dependency,
33
- git: "https://repo.com", ref: "abc123")
34
- expect(instance.ref).to eq("abc123")
35
- end
36
-
37
- it "sets the revision" do
38
- instance = described_class.new(dependency,
39
- git: "https://repo.com", revision: "abcde12345")
40
- expect(instance.revision).to eq("abcde12345")
41
- end
42
-
43
- it "sets the rel" do
44
- instance = described_class.new(dependency,
45
- git: "https://repo.com", rel: "internal/path")
46
- expect(instance.rel).to eq("internal/path")
47
- end
48
-
49
- context "rev_parse" do
50
- def rev_parse(instance)
51
- instance.instance_variable_get(:@rev_parse)
52
- end
53
-
54
- it "uses the :ref option with priority" do
55
- instance = described_class.new(dependency,
56
- git: "https://repo.com", ref: "abc123", branch: "magic_new_feature")
57
- expect(rev_parse(instance)).to eq("abc123")
58
- end
59
-
60
- it "uses the :branch option with priority" do
61
- instance = described_class.new(dependency,
62
- git: "https://repo.com", branch: "magic_new_feature", tag: "v1.2.3")
63
- expect(rev_parse(instance)).to eq("magic_new_feature")
64
- end
65
-
66
- it "uses the :tag option" do
67
- instance = described_class.new(dependency,
68
- git: "https://repo.com", tag: "v1.2.3")
69
- expect(rev_parse(instance)).to eq("v1.2.3")
70
- end
71
-
72
- it 'uses "master" when none is given' do
73
- instance = described_class.new(dependency, git: "https://repo.com")
74
- expect(rev_parse(instance)).to eq("master")
75
- end
76
- end
77
- end
78
-
79
- describe "#cache_key" do
80
-
81
- it "concatenates the name and revision" do
82
- subject.stub(:revision).and_return("abcdef123456")
83
- expect(subject.cache_key).to eq("bacon-abcdef123456")
84
- end
85
- end
86
-
87
- describe "#installed?" do
88
- it "returns false when there is no revision" do
89
- subject.stub(:revision).and_return(nil)
90
- expect(subject.installed?).to be false
91
- end
92
-
93
- it "returns false when the install_path does not exist" do
94
- subject.stub(:revision).and_return("abcd1234")
95
- subject.stub(:install_path).and_return(double(exist?: false))
96
- expect(subject.installed?).to be false
97
- end
98
-
99
- it "returns true when the location is installed" do
100
- subject.stub(:revision).and_return("abcd1234")
101
- subject.stub(:install_path).and_return(double(exist?: true))
102
- expect(subject.installed?).to be true
103
- end
104
- end
105
-
106
- describe "#install" do
107
- before do
108
- File.stub(:chmod)
109
- FileUtils.stub(:cp_r)
110
- subject.stub(:validate_cached!)
111
- subject.stub(:git)
112
- end
113
-
114
- context "when the repository is cached" do
115
- it "pulls a new version" do
116
- Dir.stub(:chdir) { |args, &b| b.call } # Force eval the chdir block
117
-
118
- subject.stub(:cached?).and_return(true)
119
- expect(subject).to receive(:git).with(
120
- 'fetch --force --tags https://repo.com "refs/heads/*:refs/heads/*"'
121
- )
122
- subject.install
123
- end
124
- end
125
-
126
- context "when the revision is not cached" do
127
- it "clones the repository" do
128
- Dir.stub(:chdir) { |args, &b| b.call } # Force eval the chdir block
129
-
130
- cache_path = subject.send(:cache_path)
131
- subject.stub(:cached?).and_return(false)
132
- expect(subject).to receive(:git).with(
133
- %{clone https://repo.com "#{cache_path}" --bare --no-hardlinks}
134
- )
135
- subject.install
136
- end
137
- end
138
- end
139
-
140
- describe "#cached_cookbook" do
141
- it "returns nil if the cookbook is not installed" do
142
- subject.stub(:installed?).and_return(false)
143
- expect(subject.cached_cookbook).to be_nil
144
- end
145
-
146
- it "returns the cookbook at the install_path" do
147
- subject.stub(:installed?).and_return(true)
148
- MockCachedCookbook.stub(:from_path)
149
-
150
- expect(MockCachedCookbook).to receive(:from_path).once
151
- subject.cached_cookbook
152
- end
153
- end
154
-
155
- describe "#==" do
156
- let(:other) { subject.dup }
157
-
158
- it "returns true when everything matches" do
159
- expect(subject).to eq(other)
160
- end
161
-
162
- it "returns false when the other location is not an GitLocation" do
163
- other.stub(:is_a?).and_return(false)
164
- expect(subject).to_not eq(other)
165
- end
166
-
167
- it "returns false when the uri is different" do
168
- other.stub(:uri).and_return("different")
169
- expect(subject).to_not eq(other)
170
- end
171
-
172
- it "returns false when the branch is different" do
173
- other.stub(:branch).and_return("different")
174
- expect(subject).to_not eq(other)
175
- end
176
-
177
- it "returns false when the tag is different" do
178
- other.stub(:tag).and_return("different")
179
- expect(subject).to_not eq(other)
180
- end
181
-
182
- it "returns false when the ref is different" do
183
- other.stub(:ref).and_return("different")
184
- expect(subject).to_not eq(other)
185
- end
186
-
187
- it "returns false when the rel is different" do
188
- other.stub(:rel).and_return("different")
189
- expect(subject).to_not eq(other)
190
- end
191
- end
192
-
193
- describe "#to_s" do
194
- it "prefers the tag" do
195
- expect(subject.to_s).to eq("https://repo.com (at v1.2.3/hi)")
196
- end
197
-
198
- it "prefers the branch" do
199
- subject.stub(:tag).and_return(nil)
200
- expect(subject.to_s).to eq("https://repo.com (at ham/hi)")
201
- end
202
-
203
- it "falls back to the ref" do
204
- subject.stub(:tag).and_return(nil)
205
- subject.stub(:branch).and_return(nil)
206
- expect(subject.to_s).to eq("https://repo.com (at abc123/hi)")
207
- end
208
-
209
- it "does not use the rel if missing" do
210
- subject.stub(:rel).and_return(nil)
211
- expect(subject.to_s).to eq("https://repo.com (at v1.2.3)")
212
- end
213
- end
214
-
215
- describe "#to_lock" do
216
- it "includes all the information" do
217
- expect(subject.to_lock).to eq <<-EOH.gsub(/^ {8}/, "")
218
- git: https://repo.com
219
- revision: defjkl123456
220
- ref: abc123
221
- branch: ham
222
- tag: v1.2.3
223
- rel: hi
224
- EOH
225
- end
226
-
227
- it "does not include the branch if missing" do
228
- subject.stub(:branch).and_return(nil)
229
- expect(subject.to_lock).to_not include("branch")
230
- end
231
-
232
- it "does not include the tag if missing" do
233
- subject.stub(:tag).and_return(nil)
234
- expect(subject.to_lock).to_not include("tag")
235
- end
236
-
237
- it "does not include the rel if missing" do
238
- subject.stub(:rel).and_return(nil)
239
- expect(subject.to_lock).to_not include("rel")
240
- end
241
- end
242
-
243
- describe "#lock_data" do
244
- let(:full_lock_data) do
245
- {
246
- "git" => "https://repo.com",
247
- "revision" => "defjkl123456",
248
- "ref" => "abc123",
249
- "branch" => "ham",
250
- "tag" => "v1.2.3",
251
- "rel" => "hi",
252
- }
253
- end
254
-
255
- it "includes all the information" do
256
- expect(subject.lock_data).to eq(full_lock_data)
257
- end
258
-
259
- it "does not include the branch if missing" do
260
- subject.stub(:branch).and_return(nil)
261
- expect(subject.lock_data).to_not have_key("branch")
262
- end
263
-
264
- it "does not include the tag if missing" do
265
- subject.stub(:tag).and_return(nil)
266
- expect(subject.lock_data).to_not have_key("tag")
267
- end
268
-
269
- it "does not include the rel if missing" do
270
- subject.stub(:rel).and_return(nil)
271
- expect(subject.lock_data).to_not have_key("rel")
272
- end
273
- end
274
-
275
- describe "#git" do
276
- before { described_class.send(:public, :git) }
277
-
278
- it "raises an error if Git is not installed" do
279
- CookbookOmnifetch.stub(:which).and_return(false)
280
- expect { subject.git("foo") }.to raise_error(GitNotInstalled)
281
- end
282
-
283
- it "raises an error if the command fails" do
284
- shell_out = double("shell_out", success?: false, stderr: nil)
285
- MockShellOut.stub(:shell_out).and_return(shell_out)
286
- expect { subject.git("foo") }.to raise_error(GitCommandError)
287
- end
288
- end
289
- end
290
- end