librarian-puppet-lmco 0.9.8.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (126) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +5 -0
  3. data/LICENSE +20 -0
  4. data/README.md +187 -0
  5. data/bin/librarian-puppet +9 -0
  6. data/lib/librarian/puppet.rb +22 -0
  7. data/lib/librarian/puppet/cli.rb +85 -0
  8. data/lib/librarian/puppet/dsl.rb +16 -0
  9. data/lib/librarian/puppet/environment.rb +54 -0
  10. data/lib/librarian/puppet/extension.rb +47 -0
  11. data/lib/librarian/puppet/lockfile/parser.rb +53 -0
  12. data/lib/librarian/puppet/source.rb +4 -0
  13. data/lib/librarian/puppet/source/forge.rb +348 -0
  14. data/lib/librarian/puppet/source/git.rb +121 -0
  15. data/lib/librarian/puppet/source/githubtarball.rb +249 -0
  16. data/lib/librarian/puppet/source/local.rb +57 -0
  17. data/lib/librarian/puppet/source/path.rb +12 -0
  18. data/lib/librarian/puppet/templates/Puppetfile +10 -0
  19. data/lib/librarian/puppet/version.rb +5 -0
  20. data/vendor/librarian/CHANGELOG.md +224 -0
  21. data/vendor/librarian/Gemfile +6 -0
  22. data/vendor/librarian/MIT-LICENSE +20 -0
  23. data/vendor/librarian/README.md +401 -0
  24. data/vendor/librarian/Rakefile +34 -0
  25. data/vendor/librarian/bin/librarian-chef +7 -0
  26. data/vendor/librarian/bin/librarian-mock +7 -0
  27. data/vendor/librarian/config/cucumber.yaml +1 -0
  28. data/vendor/librarian/features/chef/cli/init.feature +11 -0
  29. data/vendor/librarian/features/chef/cli/install.feature +64 -0
  30. data/vendor/librarian/features/chef/cli/show.feature +77 -0
  31. data/vendor/librarian/features/chef/cli/version.feature +11 -0
  32. data/vendor/librarian/features/support/env.rb +9 -0
  33. data/vendor/librarian/lib/librarian.rb +11 -0
  34. data/vendor/librarian/lib/librarian/action.rb +5 -0
  35. data/vendor/librarian/lib/librarian/action/base.rb +24 -0
  36. data/vendor/librarian/lib/librarian/action/clean.rb +44 -0
  37. data/vendor/librarian/lib/librarian/action/ensure.rb +24 -0
  38. data/vendor/librarian/lib/librarian/action/install.rb +95 -0
  39. data/vendor/librarian/lib/librarian/action/persist_resolution_mixin.rb +51 -0
  40. data/vendor/librarian/lib/librarian/action/resolve.rb +46 -0
  41. data/vendor/librarian/lib/librarian/action/update.rb +44 -0
  42. data/vendor/librarian/lib/librarian/chef.rb +1 -0
  43. data/vendor/librarian/lib/librarian/chef/cli.rb +47 -0
  44. data/vendor/librarian/lib/librarian/chef/dsl.rb +16 -0
  45. data/vendor/librarian/lib/librarian/chef/environment.rb +27 -0
  46. data/vendor/librarian/lib/librarian/chef/extension.rb +9 -0
  47. data/vendor/librarian/lib/librarian/chef/integration/knife.rb +46 -0
  48. data/vendor/librarian/lib/librarian/chef/manifest_reader.rb +59 -0
  49. data/vendor/librarian/lib/librarian/chef/source.rb +4 -0
  50. data/vendor/librarian/lib/librarian/chef/source/git.rb +25 -0
  51. data/vendor/librarian/lib/librarian/chef/source/github.rb +27 -0
  52. data/vendor/librarian/lib/librarian/chef/source/local.rb +69 -0
  53. data/vendor/librarian/lib/librarian/chef/source/path.rb +12 -0
  54. data/vendor/librarian/lib/librarian/chef/source/site.rb +442 -0
  55. data/vendor/librarian/lib/librarian/chef/templates/Cheffile +15 -0
  56. data/vendor/librarian/lib/librarian/cli.rb +223 -0
  57. data/vendor/librarian/lib/librarian/cli/manifest_presenter.rb +93 -0
  58. data/vendor/librarian/lib/librarian/config.rb +7 -0
  59. data/vendor/librarian/lib/librarian/config/database.rb +205 -0
  60. data/vendor/librarian/lib/librarian/config/file_source.rb +47 -0
  61. data/vendor/librarian/lib/librarian/config/hash_source.rb +33 -0
  62. data/vendor/librarian/lib/librarian/config/source.rb +149 -0
  63. data/vendor/librarian/lib/librarian/dependency.rb +147 -0
  64. data/vendor/librarian/lib/librarian/dsl.rb +108 -0
  65. data/vendor/librarian/lib/librarian/dsl/receiver.rb +46 -0
  66. data/vendor/librarian/lib/librarian/dsl/target.rb +171 -0
  67. data/vendor/librarian/lib/librarian/environment.rb +182 -0
  68. data/vendor/librarian/lib/librarian/error.rb +4 -0
  69. data/vendor/librarian/lib/librarian/helpers.rb +13 -0
  70. data/vendor/librarian/lib/librarian/linter/source_linter.rb +55 -0
  71. data/vendor/librarian/lib/librarian/lockfile.rb +29 -0
  72. data/vendor/librarian/lib/librarian/lockfile/compiler.rb +66 -0
  73. data/vendor/librarian/lib/librarian/lockfile/parser.rb +123 -0
  74. data/vendor/librarian/lib/librarian/logger.rb +46 -0
  75. data/vendor/librarian/lib/librarian/manifest.rb +140 -0
  76. data/vendor/librarian/lib/librarian/manifest_set.rb +151 -0
  77. data/vendor/librarian/lib/librarian/mock.rb +1 -0
  78. data/vendor/librarian/lib/librarian/mock/cli.rb +19 -0
  79. data/vendor/librarian/lib/librarian/mock/dsl.rb +15 -0
  80. data/vendor/librarian/lib/librarian/mock/environment.rb +24 -0
  81. data/vendor/librarian/lib/librarian/mock/extension.rb +9 -0
  82. data/vendor/librarian/lib/librarian/mock/source.rb +1 -0
  83. data/vendor/librarian/lib/librarian/mock/source/mock.rb +80 -0
  84. data/vendor/librarian/lib/librarian/mock/source/mock/registry.rb +83 -0
  85. data/vendor/librarian/lib/librarian/resolution.rb +46 -0
  86. data/vendor/librarian/lib/librarian/resolver.rb +81 -0
  87. data/vendor/librarian/lib/librarian/resolver/implementation.rb +223 -0
  88. data/vendor/librarian/lib/librarian/source.rb +2 -0
  89. data/vendor/librarian/lib/librarian/source/basic_api.rb +45 -0
  90. data/vendor/librarian/lib/librarian/source/git.rb +134 -0
  91. data/vendor/librarian/lib/librarian/source/git/repository.rb +217 -0
  92. data/vendor/librarian/lib/librarian/source/local.rb +54 -0
  93. data/vendor/librarian/lib/librarian/source/path.rb +56 -0
  94. data/vendor/librarian/lib/librarian/spec.rb +13 -0
  95. data/vendor/librarian/lib/librarian/spec_change_set.rb +173 -0
  96. data/vendor/librarian/lib/librarian/specfile.rb +17 -0
  97. data/vendor/librarian/lib/librarian/support/abstract_method.rb +21 -0
  98. data/vendor/librarian/lib/librarian/ui.rb +64 -0
  99. data/vendor/librarian/lib/librarian/version.rb +3 -0
  100. data/vendor/librarian/librarian.gemspec +35 -0
  101. data/vendor/librarian/spec/functional/chef/cli_spec.rb +194 -0
  102. data/vendor/librarian/spec/functional/chef/source/git_spec.rb +432 -0
  103. data/vendor/librarian/spec/functional/chef/source/site_spec.rb +266 -0
  104. data/vendor/librarian/spec/functional/source/git/repository_spec.rb +150 -0
  105. data/vendor/librarian/spec/integration/chef/source/git_spec.rb +441 -0
  106. data/vendor/librarian/spec/integration/chef/source/site_spec.rb +217 -0
  107. data/vendor/librarian/spec/support/cli_macro.rb +114 -0
  108. data/vendor/librarian/spec/support/method_patch_macro.rb +30 -0
  109. data/vendor/librarian/spec/support/with_env_macro.rb +20 -0
  110. data/vendor/librarian/spec/unit/action/base_spec.rb +18 -0
  111. data/vendor/librarian/spec/unit/action/clean_spec.rb +102 -0
  112. data/vendor/librarian/spec/unit/action/ensure_spec.rb +37 -0
  113. data/vendor/librarian/spec/unit/action/install_spec.rb +111 -0
  114. data/vendor/librarian/spec/unit/config/database_spec.rb +327 -0
  115. data/vendor/librarian/spec/unit/dependency_spec.rb +212 -0
  116. data/vendor/librarian/spec/unit/dsl_spec.rb +173 -0
  117. data/vendor/librarian/spec/unit/environment_spec.rb +173 -0
  118. data/vendor/librarian/spec/unit/lockfile/parser_spec.rb +162 -0
  119. data/vendor/librarian/spec/unit/lockfile_spec.rb +65 -0
  120. data/vendor/librarian/spec/unit/manifest_set_spec.rb +202 -0
  121. data/vendor/librarian/spec/unit/manifest_spec.rb +36 -0
  122. data/vendor/librarian/spec/unit/mock/source/mock_spec.rb +22 -0
  123. data/vendor/librarian/spec/unit/resolver_spec.rb +233 -0
  124. data/vendor/librarian/spec/unit/source/git_spec.rb +29 -0
  125. data/vendor/librarian/spec/unit/spec_change_set_spec.rb +169 -0
  126. metadata +220 -0
@@ -0,0 +1,432 @@
1
+ require 'pathname'
2
+ require 'securerandom'
3
+
4
+ require 'librarian'
5
+ require 'librarian/helpers'
6
+ require 'librarian/error'
7
+ require 'librarian/action/resolve'
8
+ require 'librarian/action/install'
9
+ require 'librarian/action/update'
10
+ require 'librarian/chef'
11
+
12
+ module Librarian
13
+ module Chef
14
+ module Source
15
+ describe Git do
16
+
17
+ let(:project_path) do
18
+ project_path = Pathname.new(__FILE__).expand_path
19
+ project_path = project_path.dirname until project_path.join("Rakefile").exist?
20
+ project_path
21
+ end
22
+ let(:tmp_path) { project_path.join("tmp/spec/chef/git-source") }
23
+
24
+ let(:cookbooks_path) { tmp_path.join("cookbooks") }
25
+
26
+ # depends on repo_path being defined in each context
27
+ let(:env) { Environment.new(:project_path => repo_path) }
28
+
29
+ context "a single dependency with a git source" do
30
+
31
+ let(:sample_path) { tmp_path.join("sample") }
32
+ let(:sample_metadata) do
33
+ Helpers.strip_heredoc(<<-METADATA)
34
+ version "0.6.5"
35
+ METADATA
36
+ end
37
+
38
+ let(:first_sample_path) { cookbooks_path.join("first-sample") }
39
+ let(:first_sample_metadata) do
40
+ Helpers.strip_heredoc(<<-METADATA)
41
+ version "3.2.1"
42
+ METADATA
43
+ end
44
+
45
+ let(:second_sample_path) { cookbooks_path.join("second-sample") }
46
+ let(:second_sample_metadata) do
47
+ Helpers.strip_heredoc(<<-METADATA)
48
+ version "4.3.2"
49
+ METADATA
50
+ end
51
+
52
+ before :all do
53
+ sample_path.rmtree if sample_path.exist?
54
+ sample_path.mkpath
55
+ sample_path.join("metadata.rb").open("wb") { |f| f.write(sample_metadata) }
56
+ Dir.chdir(sample_path) do
57
+ `git init`
58
+ `git add metadata.rb`
59
+ `git commit -m "Initial commit."`
60
+ end
61
+
62
+ cookbooks_path.rmtree if cookbooks_path.exist?
63
+ cookbooks_path.mkpath
64
+ first_sample_path.mkpath
65
+ first_sample_path.join("metadata.rb").open("wb") { |f| f.write(first_sample_metadata) }
66
+ second_sample_path.mkpath
67
+ second_sample_path.join("metadata.rb").open("wb") { |f| f.write(second_sample_metadata) }
68
+ Dir.chdir(cookbooks_path) do
69
+ `git init`
70
+ `git add .`
71
+ `git commit -m "Initial commit."`
72
+ end
73
+ end
74
+
75
+ context "resolving" do
76
+ let(:repo_path) { tmp_path.join("repo/resolve") }
77
+ before do
78
+ repo_path.rmtree if repo_path.exist?
79
+ repo_path.mkpath
80
+ repo_path.join("cookbooks").mkpath
81
+ cheffile = Helpers.strip_heredoc(<<-CHEFFILE)
82
+ #!/usr/bin/env ruby
83
+ cookbook "sample", :git => #{sample_path.to_s.inspect}
84
+ CHEFFILE
85
+ repo_path.join("Cheffile").open("wb") { |f| f.write(cheffile) }
86
+ end
87
+
88
+ context "the resolve" do
89
+ it "should not raise an exception" do
90
+ expect { Action::Resolve.new(env).run }.to_not raise_error
91
+ end
92
+ end
93
+
94
+ context "the results" do
95
+ before { Action::Resolve.new(env).run }
96
+
97
+ it "should create the lockfile" do
98
+ repo_path.join("Cheffile.lock").should exist
99
+ end
100
+
101
+ it "should not attempt to install the sample cookbok" do
102
+ repo_path.join("cookbooks/sample").should_not exist
103
+ end
104
+ end
105
+ end
106
+
107
+ context "installing" do
108
+ let(:repo_path) { tmp_path.join("repo/install") }
109
+ before do
110
+ repo_path.rmtree if repo_path.exist?
111
+ repo_path.mkpath
112
+ repo_path.join("cookbooks").mkpath
113
+ cheffile = Helpers.strip_heredoc(<<-CHEFFILE)
114
+ #!/usr/bin/env ruby
115
+ cookbook "sample", :git => #{sample_path.to_s.inspect}
116
+ CHEFFILE
117
+ repo_path.join("Cheffile").open("wb") { |f| f.write(cheffile) }
118
+
119
+ Action::Resolve.new(env).run
120
+ end
121
+
122
+ context "the install" do
123
+ it "should not raise an exception" do
124
+ expect { Action::Install.new(env).run }.to_not raise_error
125
+ end
126
+ end
127
+
128
+ context "the results" do
129
+ before { Action::Install.new(env).run }
130
+
131
+ it "should create the lockfile" do
132
+ repo_path.join("Cheffile.lock").should exist
133
+ end
134
+
135
+ it "should create the directory for the cookbook" do
136
+ repo_path.join("cookbooks/sample").should exist
137
+ end
138
+
139
+ it "should copy the cookbook files into the cookbook directory" do
140
+ repo_path.join("cookbooks/sample/metadata.rb").should exist
141
+ end
142
+ end
143
+ end
144
+
145
+ context "resolving and and separately installing" do
146
+ let(:repo_path) { tmp_path.join("repo/resolve-install") }
147
+ before do
148
+ repo_path.rmtree if repo_path.exist?
149
+ repo_path.mkpath
150
+ repo_path.join("cookbooks").mkpath
151
+ cheffile = Helpers.strip_heredoc(<<-CHEFFILE)
152
+ #!/usr/bin/env ruby
153
+ cookbook "sample", :git => #{sample_path.to_s.inspect}
154
+ CHEFFILE
155
+ repo_path.join("Cheffile").open("wb") { |f| f.write(cheffile) }
156
+
157
+ Action::Resolve.new(env).run
158
+ repo_path.join("tmp").rmtree if repo_path.join("tmp").exist?
159
+ end
160
+
161
+ context "the install" do
162
+ it "should not raise an exception" do
163
+ expect { Action::Install.new(env).run }.to_not raise_error
164
+ end
165
+ end
166
+
167
+ context "the results" do
168
+ before { Action::Install.new(env).run }
169
+
170
+ it "should create the directory for the cookbook" do
171
+ repo_path.join("cookbooks/sample").should exist
172
+ end
173
+
174
+ it "should copy the cookbook files into the cookbook directory" do
175
+ repo_path.join("cookbooks/sample/metadata.rb").should exist
176
+ end
177
+ end
178
+ end
179
+
180
+ context "resolving, changing, and resolving" do
181
+ let(:repo_path) { tmp_path.join("repo/resolve-update") }
182
+ before do
183
+ repo_path.rmtree if repo_path.exist?
184
+ repo_path.mkpath
185
+ repo_path.join("cookbooks").mkpath
186
+ cheffile = Helpers.strip_heredoc(<<-CHEFFILE)
187
+ git #{cookbooks_path.to_s.inspect}
188
+ cookbook "first-sample"
189
+ CHEFFILE
190
+ repo_path.join("Cheffile").open("wb") { |f| f.write(cheffile) }
191
+ Action::Resolve.new(env).run
192
+
193
+ cheffile = Helpers.strip_heredoc(<<-CHEFFILE)
194
+ git #{cookbooks_path.to_s.inspect}
195
+ cookbook "first-sample"
196
+ cookbook "second-sample"
197
+ CHEFFILE
198
+ repo_path.join("Cheffile").open("wb") { |f| f.write(cheffile) }
199
+ end
200
+
201
+ context "the second resolve" do
202
+ it "should not raise an exception" do
203
+ expect { Action::Resolve.new(env).run }.to_not raise_error
204
+ end
205
+ end
206
+ end
207
+
208
+ end
209
+
210
+ context "with a path" do
211
+
212
+ let(:git_path) { tmp_path.join("big-git-repo") }
213
+ let(:sample_path) { git_path.join("buttercup") }
214
+ let(:sample_metadata) do
215
+ Helpers.strip_heredoc(<<-METADATA)
216
+ version "0.6.5"
217
+ METADATA
218
+ end
219
+
220
+ before :all do
221
+ git_path.rmtree if git_path.exist?
222
+ git_path.mkpath
223
+ sample_path.mkpath
224
+ sample_path.join("metadata.rb").open("wb") { |f| f.write(sample_metadata) }
225
+ Dir.chdir(git_path) do
226
+ `git init`
227
+ `git add .`
228
+ `git commit -m "Initial commit."`
229
+ end
230
+ end
231
+
232
+ context "if no path option is given" do
233
+ let(:repo_path) { tmp_path.join("repo/resolve") }
234
+ before do
235
+ repo_path.rmtree if repo_path.exist?
236
+ repo_path.mkpath
237
+ repo_path.join("cookbooks").mkpath
238
+ cheffile = Helpers.strip_heredoc(<<-CHEFFILE)
239
+ #!/usr/bin/env ruby
240
+ cookbook "sample",
241
+ :git => #{git_path.to_s.inspect}
242
+ CHEFFILE
243
+ repo_path.join("Cheffile").open("wb") { |f| f.write(cheffile) }
244
+ end
245
+
246
+ it "should not resolve" do
247
+ expect{ Action::Resolve.new(env).run }.to raise_error
248
+ end
249
+ end
250
+
251
+ context "if the path option is wrong" do
252
+ let(:repo_path) { tmp_path.join("repo/resolve") }
253
+ before do
254
+ repo_path.rmtree if repo_path.exist?
255
+ repo_path.mkpath
256
+ repo_path.join("cookbooks").mkpath
257
+ cheffile = Helpers.strip_heredoc(<<-CHEFFILE)
258
+ #!/usr/bin/env ruby
259
+ cookbook "sample",
260
+ :git => #{git_path.to_s.inspect},
261
+ :path => "jelly"
262
+ CHEFFILE
263
+ repo_path.join("Cheffile").open("wb") { |f| f.write(cheffile) }
264
+ end
265
+
266
+ it "should not resolve" do
267
+ expect{ Action::Resolve.new(env).run }.to raise_error
268
+ end
269
+ end
270
+
271
+ context "if the path option is right" do
272
+ let(:repo_path) { tmp_path.join("repo/resolve") }
273
+ before do
274
+ repo_path.rmtree if repo_path.exist?
275
+ repo_path.mkpath
276
+ repo_path.join("cookbooks").mkpath
277
+ cheffile = Helpers.strip_heredoc(<<-CHEFFILE)
278
+ #!/usr/bin/env ruby
279
+ cookbook "sample",
280
+ :git => #{git_path.to_s.inspect},
281
+ :path => "buttercup"
282
+ CHEFFILE
283
+ repo_path.join("Cheffile").open("wb") { |f| f.write(cheffile) }
284
+ end
285
+
286
+ context "the resolve" do
287
+ it "should not raise an exception" do
288
+ expect { Action::Resolve.new(env).run }.to_not raise_error
289
+ end
290
+ end
291
+
292
+ context "the results" do
293
+ before { Action::Resolve.new(env).run }
294
+
295
+ it "should create the lockfile" do
296
+ repo_path.join("Cheffile.lock").should exist
297
+ end
298
+ end
299
+ end
300
+
301
+ end
302
+
303
+ context "missing a metadata" do
304
+ let(:git_path) { tmp_path.join("big-git-repo") }
305
+ let(:repo_path) { tmp_path.join("repo/resolve") }
306
+ before do
307
+ repo_path.rmtree if repo_path.exist?
308
+ repo_path.mkpath
309
+ repo_path.join("cookbooks").mkpath
310
+ cheffile = Helpers.strip_heredoc(<<-CHEFFILE)
311
+ cookbook "sample",
312
+ :git => #{git_path.to_s.inspect}
313
+ CHEFFILE
314
+ repo_path.join("Cheffile").open("wb") { |f| f.write(cheffile) }
315
+ end
316
+
317
+ context "the resolve" do
318
+ it "should raise an exception" do
319
+ expect { Action::Resolve.new(env).run }.to raise_error
320
+ end
321
+
322
+ it "should explain the problem" do
323
+ expect { Action::Resolve.new(env).run }.
324
+ to raise_error(Error, /no metadata file found/i)
325
+ end
326
+ end
327
+
328
+ context "the results" do
329
+ before { Action::Resolve.new(env).run rescue nil }
330
+
331
+ it "should not create the lockfile" do
332
+ repo_path.join("Cheffile.lock").should_not exist
333
+ end
334
+
335
+ it "should not create the directory for the cookbook" do
336
+ repo_path.join("cookbooks/sample").should_not exist
337
+ end
338
+ end
339
+ end
340
+
341
+ context "when upstream updates" do
342
+ let(:git_path) { tmp_path.join("upstream-updates-repo") }
343
+ let(:repo_path) { tmp_path.join("repo/resolve-with-upstream-updates") }
344
+
345
+ let(:sample_metadata) do
346
+ Helpers.strip_heredoc(<<-METADATA)
347
+ version "0.6.5"
348
+ METADATA
349
+ end
350
+ before do
351
+
352
+ # set up the git repo as normal, but let's also set up a release-stable branch
353
+ # from which our Cheffile will only pull stable releases
354
+ git_path.rmtree if git_path.exist?
355
+ git_path.mkpath
356
+ git_path.join("metadata.rb").open("w+b"){|f| f.write(sample_metadata)}
357
+
358
+ Dir.chdir(git_path) do
359
+ `git init`
360
+ `git add metadata.rb`
361
+ `git commit -m "Initial Commit."`
362
+ `git checkout -b some-branch --quiet`
363
+ `echo 'hi' > some-file`
364
+ `git add some-file`
365
+ `git commit -m 'Some File.'`
366
+ `git checkout master --quiet`
367
+ end
368
+
369
+ # set up the chef repo as normal, except the Cheffile points to the release-stable
370
+ # branch - we expect when the upstream copy of that branch is changed, then we can
371
+ # fetch & merge those changes when we update
372
+ repo_path.rmtree if repo_path.exist?
373
+ repo_path.mkpath
374
+ repo_path.join("cookbooks").mkpath
375
+ cheffile = Helpers.strip_heredoc(<<-CHEFFILE)
376
+ cookbook "sample",
377
+ :git => #{git_path.to_s.inspect},
378
+ :ref => "some-branch"
379
+ CHEFFILE
380
+ repo_path.join("Cheffile").open("wb") { |f| f.write(cheffile) }
381
+ Action::Resolve.new(env).run
382
+
383
+ # change the upstream copy of that branch: we expect to be able to pull the latest
384
+ # when we re-resolve
385
+ Dir.chdir(git_path) do
386
+ `git checkout some-branch --quiet`
387
+ `echo 'ho' > some-other-file`
388
+ `git add some-other-file`
389
+ `git commit -m 'Some Other File.'`
390
+ `git checkout master --quiet`
391
+ end
392
+ end
393
+
394
+ let(:metadata_file) { repo_path.join("cookbooks/sample/metadata.rb") }
395
+ let(:old_code_file) { repo_path.join("cookbooks/sample/some-file") }
396
+ let(:new_code_file) { repo_path.join("cookbooks/sample/some-other-file") }
397
+
398
+ context "when updating not a cookbook from that source" do
399
+ before do
400
+ Action::Update.new(env).run
401
+ end
402
+
403
+ it "should pull the tip from upstream" do
404
+ Action::Install.new(env).run
405
+
406
+ metadata_file.should exist #sanity
407
+ old_code_file.should exist #sanity
408
+
409
+ new_code_file.should_not exist # the assertion
410
+ end
411
+ end
412
+
413
+ context "when updating a cookbook from that source" do
414
+ before do
415
+ Action::Update.new(env, :names => %w(sample)).run
416
+ end
417
+
418
+ it "should pull the tip from upstream" do
419
+ Action::Install.new(env).run
420
+
421
+ metadata_file.should exist #sanity
422
+ old_code_file.should exist #sanity
423
+
424
+ new_code_file.should exist # the assertion
425
+ end
426
+ end
427
+ end
428
+
429
+ end
430
+ end
431
+ end
432
+ end
@@ -0,0 +1,266 @@
1
+ require 'pathname'
2
+ require 'json'
3
+ require 'webmock'
4
+
5
+ require 'librarian'
6
+ require 'librarian/helpers'
7
+ require 'librarian/chef'
8
+ require 'librarian/linter/source_linter'
9
+
10
+ module Librarian
11
+ module Chef
12
+ module Source
13
+ describe Site do
14
+
15
+ include WebMock::API
16
+
17
+ let(:project_path) do
18
+ project_path = Pathname.new(__FILE__).expand_path
19
+ project_path = project_path.dirname until project_path.join("Rakefile").exist?
20
+ project_path
21
+ end
22
+ let(:tmp_path) { project_path.join("tmp/spec/functional/chef/source/site") }
23
+ after { tmp_path.rmtree if tmp_path && tmp_path.exist? }
24
+ let(:sample_path) { tmp_path.join("sample") }
25
+ let(:sample_metadata) do
26
+ Helpers.strip_heredoc(<<-METADATA)
27
+ version "0.6.5"
28
+ METADATA
29
+ end
30
+
31
+ let(:api_url) { "http://site.cookbooks.com" }
32
+
33
+ let(:sample_index_data) do
34
+ {
35
+ "name" => "sample",
36
+ "versions" => [
37
+ "#{api_url}/cookbooks/sample/versions/0_6_5"
38
+ ]
39
+ }
40
+ end
41
+ let(:sample_0_6_5_data) do
42
+ {
43
+ "version" => "0.6.5",
44
+ "file" => "#{api_url}/cookbooks/sample/versions/0_6_5/file.tar.gz"
45
+ }
46
+ end
47
+ let(:sample_0_6_5_package) do
48
+ s = StringIO.new
49
+ z = Zlib::GzipWriter.new(s, Zlib::NO_COMPRESSION)
50
+ t = Archive::Tar::Minitar::Output.new(z)
51
+ t.tar.add_file_simple("sample/metadata.rb", :mode => 0700,
52
+ :size => sample_metadata.bytesize){|io| io.write(sample_metadata)}
53
+ t.close
54
+ z.close unless z.closed?
55
+ s.string
56
+ end
57
+
58
+ # depends on repo_path being defined in each context
59
+ let(:env) { Environment.new(:project_path => repo_path) }
60
+
61
+ before do
62
+ stub_request(:get, "#{api_url}/cookbooks/sample").
63
+ to_return(:body => JSON.dump(sample_index_data))
64
+
65
+ stub_request(:get, "#{api_url}/cookbooks/sample/versions/0_6_5").
66
+ to_return(:body => JSON.dump(sample_0_6_5_data))
67
+
68
+ stub_request(:get, "#{api_url}/cookbooks/sample/versions/0_6_5/file.tar.gz").
69
+ to_return(:body => sample_0_6_5_package)
70
+ end
71
+
72
+ after do
73
+ WebMock.reset!
74
+ end
75
+
76
+ let(:repo_path) { tmp_path.join("methods") }
77
+ before { repo_path.mkpath }
78
+
79
+ describe "lint" do
80
+ it "lints" do
81
+ Librarian::Linter::SourceLinter.lint! described_class
82
+ end
83
+ end
84
+
85
+ describe "class methods" do
86
+
87
+ describe ".lock_name" do
88
+ specify { described_class.lock_name.should == "SITE" }
89
+ end
90
+
91
+ describe ".from_spec_args" do
92
+ it "gives the expected source" do
93
+ args = { }
94
+ source = described_class.from_spec_args(env, api_url, args)
95
+ source.uri.should == api_url
96
+ end
97
+
98
+ it "raises on unexpected args" do
99
+ args = {:k => 3}
100
+ expect { described_class.from_spec_args(env, api_url, args) }.
101
+ to raise_error Librarian::Error, "unrecognized options: k"
102
+ end
103
+ end
104
+
105
+ describe ".from_lock_options" do
106
+ it "gives the expected source" do
107
+ options = {:remote => api_url}
108
+ source = described_class.from_lock_options(env, options)
109
+ source.uri.should == api_url
110
+ end
111
+
112
+ it "roundtrips" do
113
+ options = {:remote => api_url}
114
+ source = described_class.from_lock_options(env, options)
115
+ source.to_lock_options.should == options
116
+ end
117
+ end
118
+
119
+ end
120
+
121
+ describe "instance methods" do
122
+ let(:source) { described_class.new(env, api_url) }
123
+
124
+ describe "#manifests" do
125
+ it "gives a list of all manifests" do
126
+ manifests = source.manifests("sample")
127
+ manifests.should have(1).item
128
+ manifest = manifests.first
129
+ manifest.source.should be source
130
+ manifest.version.should == Manifest::Version.new("0.6.5")
131
+ manifest.dependencies.should be_empty
132
+ end
133
+ end
134
+
135
+ describe "#fetch_version" do
136
+ it "fetches the version based on extra" do
137
+ extra = "#{api_url}/cookbooks/sample/versions/0_6_5"
138
+ source.fetch_version("sample", extra).should == "0.6.5"
139
+ end
140
+ end
141
+
142
+ describe "#fetch_dependencies" do
143
+ it "fetches the dependencies based on extra" do
144
+ extra = "#{api_url}/cookbooks/sample/versions/0_6_5"
145
+ source.fetch_dependencies("sample", "0.6.5", extra).should == [ ]
146
+ end
147
+ end
148
+
149
+ describe "#pinned?" do
150
+ it "returns false" do
151
+ source.should_not be_pinned
152
+ end
153
+ end
154
+
155
+ describe "#unpin!" do
156
+ it "is a no-op" do
157
+ source.unpin!
158
+ end
159
+ end
160
+
161
+ describe "#install!" do
162
+ before { env.install_path.mkpath }
163
+
164
+ context "directly" do
165
+ it "installs the manifest" do
166
+ manifest = Manifest.new(source, "sample")
167
+ manifest.version = "0.6.5"
168
+ source.install!(manifest)
169
+ text = env.install_path.join("sample/metadata.rb").read
170
+ text.should == sample_metadata
171
+ end
172
+ end
173
+
174
+ context "indirectly" do
175
+ it "installs the manifest" do
176
+ manifest = source.manifests("sample").first
177
+ source.install!(manifest)
178
+ text = env.install_path.join("sample/metadata.rb").read
179
+ text.should == sample_metadata
180
+ end
181
+ end
182
+ end
183
+
184
+ describe "#to_spec_args" do
185
+ it "gives the expected spec args" do
186
+ source.to_spec_args.should == [api_url, { }]
187
+ end
188
+ end
189
+
190
+ describe "#to_lock_options" do
191
+ it "gives the expected lock options" do
192
+ source.to_lock_options.should == {:remote => api_url}
193
+ end
194
+
195
+ it "roundtrips" do
196
+ options = source.to_lock_options
197
+ described_class.from_lock_options(env, options).should == source
198
+ end
199
+ end
200
+
201
+ end
202
+
203
+ describe "following http redirects" do
204
+ let(:source) { described_class.new(env, api_url) }
205
+
206
+ def redirect_to(url)
207
+ {:status => 302, :headers => {"Location" => url}}
208
+ end
209
+
210
+ context "with a sequence of http redirects" do
211
+ before do
212
+ stub_request(:get, "#{api_url}/cookbooks/sample").
213
+ to_return redirect_to "#{api_url}/cookbooks/sample-1"
214
+ stub_request(:get, "#{api_url}/cookbooks/sample-1").
215
+ to_return redirect_to "#{api_url}/cookbooks/sample-2"
216
+ stub_request(:get, "#{api_url}/cookbooks/sample-2").
217
+ to_return(:body => JSON.dump(sample_index_data))
218
+ end
219
+
220
+ it "follows a sequence of redirects" do
221
+ manifest = source.manifests("sample").first
222
+ manifest.version.to_s.should == "0.6.5"
223
+ end
224
+ end
225
+
226
+ context "with too many http redirects" do
227
+ before do
228
+ stub_request(:get, "#{api_url}/cookbooks/sample").
229
+ to_return redirect_to "#{api_url}/cookbooks/sample-1"
230
+ (1 .. 11).each do |i|
231
+ stub_request(:get, "#{api_url}/cookbooks/sample-#{i}").
232
+ to_return redirect_to "#{api_url}/cookbooks/sample-#{i + 1}"
233
+ end
234
+ stub_request(:get, "#{api_url}/cookbooks/sample-12").
235
+ to_return(:body => JSON.dump(sample_index_data))
236
+ end
237
+
238
+ it "raises, warning of too many redirects" do
239
+ expect { source.manifests("sample").first }.
240
+ to raise_error Librarian::Error, /because too many redirects!/
241
+ end
242
+ end
243
+
244
+ context "with a redirect cycle" do
245
+ before do
246
+ stub_request(:get, "#{api_url}/cookbooks/sample").
247
+ to_return redirect_to "#{api_url}/cookbooks/sample-1"
248
+ (1 .. 8).each do |i|
249
+ stub_request(:get, "#{api_url}/cookbooks/sample-#{i}").
250
+ to_return redirect_to "#{api_url}/cookbooks/sample-#{i + 1}"
251
+ end
252
+ stub_request(:get, "#{api_url}/cookbooks/sample-9").
253
+ to_return redirect_to "#{api_url}/cookbooks/sample-6"
254
+ end
255
+
256
+ it "raises, warning of a redirect cycle" do
257
+ expect { source.manifests("sample").first }.
258
+ to raise_error Librarian::Error, /because redirect cycle!/
259
+ end
260
+ end
261
+ end
262
+
263
+ end
264
+ end
265
+ end
266
+ end