berkshelf 4.0.1 → 4.1.0

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 (36) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +0 -1
  3. data/.travis.yml +41 -6
  4. data/CHANGELOG.md +15 -0
  5. data/CONTRIBUTING.md +10 -0
  6. data/Gemfile.lock +332 -0
  7. data/berkshelf.gemspec +8 -6
  8. data/features/commands/install.feature +105 -8
  9. data/features/json_formatter.feature +2 -2
  10. data/features/step_definitions/chef/config_steps.rb +1 -1
  11. data/features/step_definitions/chef_server_steps.rb +2 -2
  12. data/features/step_definitions/cli_steps.rb +1 -1
  13. data/features/step_definitions/config_steps.rb +1 -1
  14. data/features/step_definitions/environment_steps.rb +2 -2
  15. data/features/step_definitions/filesystem_steps.rb +3 -5
  16. data/features/step_definitions/json_steps.rb +1 -1
  17. data/features/support/env.rb +8 -8
  18. data/generator_files/Gemfile.erb +0 -14
  19. data/lib/berkshelf/berksfile.rb +47 -0
  20. data/lib/berkshelf/downloader.rb +7 -6
  21. data/lib/berkshelf/lockfile.rb +22 -11
  22. data/lib/berkshelf/resolver.rb +27 -0
  23. data/lib/berkshelf/thor_ext/hash_with_indifferent_access.rb +5 -1
  24. data/lib/berkshelf/version.rb +1 -1
  25. data/spec/fixtures/berksfiles/default +4 -0
  26. data/spec/fixtures/cookbook-path/jenkins-config/metadata.rb +4 -0
  27. data/spec/fixtures/cookbook-store/jenkins-2.0.3/metadata.rb +6 -0
  28. data/spec/fixtures/cookbook-store/jenkins-2.0.4/metadata.rb +5 -0
  29. data/spec/fixtures/lockfiles/default.lock +5 -0
  30. data/spec/fixtures/lockfiles/orphans.lock +21 -0
  31. data/spec/support/chef_server.rb +3 -3
  32. data/spec/unit/berkshelf/berksfile_spec.rb +27 -1
  33. data/spec/unit/berkshelf/init_generator_spec.rb +2 -4
  34. data/spec/unit/berkshelf/lockfile_spec.rb +37 -0
  35. data/spec/unit/berkshelf/resolver_spec.rb +28 -1
  36. metadata +54 -15
@@ -1,5 +1,6 @@
1
1
  module Berkshelf
2
2
  class Resolver
3
+
3
4
  require_relative 'resolver/graph'
4
5
 
5
6
  extend Forwardable
@@ -23,6 +24,7 @@ module Berkshelf
23
24
  @demands = Array.new
24
25
 
25
26
  Array(demands).each { |demand| add_demand(demand) }
27
+ compute_solver_engine(berksfile)
26
28
  end
27
29
 
28
30
  # Add the given dependency to the collection of demands
@@ -102,5 +104,30 @@ module Berkshelf
102
104
  def has_demand?(demand)
103
105
  !get_demand(demand).nil?
104
106
  end
107
+
108
+ # Look at berksfile's solvers, and ask Solve#engine= for the right one,
109
+ # swallowing any exceptions if it's preferred but not required
110
+ #
111
+ # @param [Berksfile] berksfile
112
+ def compute_solver_engine(berksfile)
113
+ if berksfile.required_solver
114
+ begin
115
+ Solve.engine = berksfile.required_solver
116
+ rescue Solve::Errors::InvalidEngine => e
117
+ raise ArgumentError, e.message
118
+ end
119
+ elsif berksfile.preferred_solver
120
+ begin
121
+ Solve.engine = berksfile.preferred_solver
122
+ rescue
123
+ # We should log this, but Berkshelf.log.warn and Berkshelf.formatter.warn
124
+ # both seem inappropriate here.
125
+ # " Preferred solver ':#{berksfile.preferred_solver}' unavailable"
126
+ end
127
+ end
128
+ # We should log this, but Berkshelf.log.info and Berkshelf.formatter.msg
129
+ # both seem inappropriate here.
130
+ # " Selected dependency solver engine ':#{Solve.engine}'"
131
+ end
105
132
  end
106
133
  end
@@ -6,7 +6,11 @@ class Thor
6
6
  end
7
7
 
8
8
  def fetch(key, default = nil)
9
- super(convert_key(key), default)
9
+ if default
10
+ super(convert_key(key), default)
11
+ else
12
+ super(convert_key(key))
13
+ end
10
14
  end
11
15
  end
12
16
  end
@@ -1,3 +1,3 @@
1
1
  module Berkshelf
2
- VERSION = "4.0.1"
2
+ VERSION = "4.1.0"
3
3
  end
@@ -0,0 +1,4 @@
1
+ source 'https://supermarket.chef.io'
2
+ cookbook 'apt', '~> 2.0'
3
+ cookbook 'jenkins', '~> 2.0'
4
+ cookbook 'jenkins-config', path: '../cookbook-path/jenkins-config'
@@ -0,0 +1,4 @@
1
+ name 'jenkins-config'
2
+ version '0.1.0'
3
+
4
+ depends 'jenkins', '~> 2.0'
@@ -0,0 +1,6 @@
1
+ name 'jenkins'
2
+ version '2.0.3'
3
+
4
+ depends 'apt', '~> 2.0'
5
+ depends 'runit', '~> 1.5'
6
+ depends 'yum', '~> 3.0'
@@ -0,0 +1,5 @@
1
+ name 'jenkins'
2
+ version '2.0.4'
3
+
4
+ depends 'apt', '~> 2.0'
5
+ depends 'runit', '~> 1.5'
@@ -1,6 +1,8 @@
1
1
  DEPENDENCIES
2
2
  apt (~> 2.0)
3
3
  jenkins (~> 2.0)
4
+ jenkins-config
5
+ path: ../cookbook-path/jenkins-config
4
6
 
5
7
  GRAPH
6
8
  apt (2.3.6)
@@ -9,6 +11,9 @@ GRAPH
9
11
  apt (~> 2.0)
10
12
  runit (~> 1.5)
11
13
  yum (~> 3.0)
14
+ jenkins-config (0.1.0)
15
+ jenkins (~> 2.0)
16
+ yum (~> 3.0)
12
17
  runit (1.5.8)
13
18
  build-essential (>= 0.0.0)
14
19
  yum (~> 3.0)
@@ -0,0 +1,21 @@
1
+ DEPENDENCIES
2
+ apt (~> 2.0)
3
+ jenkins (~> 2.0)
4
+ jenkins-config
5
+ path: ../cookbook-path/jenkins-config
6
+
7
+ GRAPH
8
+ apt (2.3.6)
9
+ build-essential (1.4.2)
10
+ jenkins (2.0.3)
11
+ apt (~> 2.0)
12
+ runit (~> 1.5)
13
+ jenkins-config (0.1.0)
14
+ jenkins (~> 2.0)
15
+ runit (1.5.8)
16
+ build-essential (>= 0.0.0)
17
+ yum (3.0.6)
18
+ yum-epel (0.2.0)
19
+ yum (~> 3.0)
20
+ zum-foo (0.1.0)
21
+ yum (~> 3.0)
@@ -62,8 +62,8 @@ module Berkshelf::RSpec
62
62
  end
63
63
 
64
64
  def chef_cookbooks
65
- chef_server.data_store.list(['cookbooks']).inject({}) do |hash, name|
66
- hash[name] = chef_server.data_store.list(['cookbooks', name])
65
+ chef_server.data_store.list(['organizations', 'chef', 'cookbooks']).inject({}) do |hash, name|
66
+ hash[name] = chef_server.data_store.list(['organizations', 'chef', 'cookbooks', name])
67
67
  hash
68
68
  end
69
69
  end
@@ -77,7 +77,7 @@ module Berkshelf::RSpec
77
77
  end
78
78
 
79
79
  def chef_environment_locks(name)
80
- JSON.parse(chef_server.data_store.get(['environments', name]))['cookbook_versions']
80
+ JSON.parse(chef_server.data_store.get(['organizations', 'chef', 'environments', name]))['cookbook_versions']
81
81
  rescue ChefZero::DataStore::DataNotFoundError
82
82
  {}
83
83
  end
@@ -9,6 +9,7 @@ describe Berkshelf::Berksfile do
9
9
  cookbook 'mysql'
10
10
  cookbook 'nginx', '< 0.101.2'
11
11
  cookbook 'ssh_known_hosts2', :git => 'https://github.com/erikh/chef-ssh_known_hosts2.git'
12
+ solver :foo, :required
12
13
  EOF
13
14
  end
14
15
  let(:berksfile) { tmp_path.join('Berksfile') }
@@ -238,7 +239,7 @@ describe Berkshelf::Berksfile do
238
239
  describe '#cookbooks' do
239
240
  it 'raises an exception if a cookbook is not installed' do
240
241
  subject.add_dependency('bacon', nil)
241
- expect { subject.cookbooks }.to raise_error
242
+ expect { subject.cookbooks }.to raise_error(Berkshelf::DependencyNotFound)
242
243
  end
243
244
 
244
245
  it 'retrieves the locked (cached) cookbook for each dependency' do
@@ -406,4 +407,29 @@ describe Berkshelf::Berksfile do
406
407
  expect(excludes[:exclude].any? { |exclude| File.fnmatch?(exclude, 'my_cookbook/metadata.rb', File::FNM_DOTMATCH) }).to be(true)
407
408
  end
408
409
  end
410
+
411
+ describe '#solver' do
412
+
413
+ let(:solver_precedence) { :please_dont_exist }
414
+
415
+ it "defaults to nil required solver and :gecode preferred solver" do
416
+ expect(subject.preferred_solver).to equal(:gecode)
417
+ expect(subject.required_solver).to equal(nil)
418
+ end
419
+
420
+ it "adds preferred and required solvers" do
421
+ subject.solver(:a, :preferred)
422
+ subject.solver(:b, :required)
423
+ expect(subject.preferred_solver).to equal(:a)
424
+ expect(subject.required_solver).to equal(:b)
425
+ end
426
+
427
+ it "raises an exception with a bad precedence" do
428
+ expect { subject.solver(:foo, :bar) }.to raise_error(/Invalid solver precedence ':bar'/)
429
+ end
430
+
431
+ it "is a DSL method" do
432
+ expect(subject).to have_exposed_method(:solver)
433
+ end
434
+ end
409
435
  end
@@ -24,9 +24,7 @@ describe Berkshelf::InitGenerator do
24
24
  expect(target).to have_structure {
25
25
  file '.gitignore'
26
26
  file 'Berksfile'
27
- file 'Gemfile' do
28
- contains %(gem 'berkshelf')
29
- end
27
+ file 'Gemfile'
30
28
  file 'Vagrantfile' do
31
29
  contains %(recipe[some_cookbook::default])
32
30
  contains %(config.omnibus.chef_version = 'latest')
@@ -57,7 +55,7 @@ describe Berkshelf::InitGenerator do
57
55
  FileUtils.rm(File.join(target, 'metadata.rb'))
58
56
  expect {
59
57
  Berkshelf::InitGenerator.new([target]).invoke_all
60
- }.to raise_error(Berkshelf::NotACookbook)
58
+ }.to raise_error(Berkshelf::NotACookbook)
61
59
  end
62
60
  end
63
61
 
@@ -292,6 +292,43 @@ describe Berkshelf::Lockfile do
292
292
  expect(subject).to_not have_dependency('apache2')
293
293
  end
294
294
  end
295
+
296
+ describe '#reduce!' do
297
+ let(:berksfile_path) { fixtures_path.join('berksfiles/default').to_s }
298
+ let(:berksfile) { Berkshelf::Berksfile.from_file(berksfile_path) }
299
+
300
+ describe 'with some orphan dependencies' do
301
+ let(:orphans_lock) { fixtures_path.join('lockfiles/orphans.lock').to_s }
302
+ subject { Berkshelf::Lockfile.new(filepath: orphans_lock, berksfile: berksfile) }
303
+
304
+ it 'removes orphan dependencies' do
305
+ graph = subject.graph.instance_variable_get(:@graph)
306
+ expect(graph).to receive(:delete).with('yum-epel').and_call_original
307
+ expect(graph).to receive(:delete).with('zum-foo').and_call_original
308
+ expect(graph).to receive(:delete).with('yum').and_call_original
309
+ subject.reduce!
310
+ end
311
+ end
312
+
313
+ describe 'minimizes updates' do
314
+ subject { Berkshelf::Lockfile.new(filepath: filepath, berksfile: berksfile) }
315
+
316
+ before(:each) do
317
+ cs = fixtures_path.join('cookbook-store')
318
+ allow(Berkshelf::CookbookStore.instance).to receive(:storage_path).and_return(cs)
319
+ end
320
+
321
+ it 'uses the cookbook version specified in the lockfile' do
322
+ subject.reduce!
323
+ expect(subject.berksfile.dependencies[1].cached_cookbook.version).to eq('2.0.3')
324
+ end
325
+
326
+ it 'does not remove locks unnecessarily' do
327
+ expect(subject).to_not receive(:unlock)
328
+ subject.reduce!
329
+ end
330
+ end
331
+ end
295
332
  end
296
333
 
297
334
  describe Berkshelf::Lockfile::Graph do
@@ -4,6 +4,11 @@ describe Berkshelf::Resolver do
4
4
  let(:berksfile) { double('berksfile') }
5
5
  let(:demand) { Berkshelf::Dependency.new(berksfile, "mysql", constraint: "= 1.2.4") }
6
6
 
7
+ before(:each) do
8
+ allow(berksfile).to receive(:required_solver).and_return(nil)
9
+ allow(berksfile).to receive(:preferred_solver).and_return(nil)
10
+ end
11
+
7
12
  describe "ClassMethods" do
8
13
  describe "::initialize" do
9
14
  it 'adds the specified dependencies to the dependencies hash' do
@@ -58,5 +63,27 @@ describe Berkshelf::Resolver do
58
63
  end
59
64
  end
60
65
 
61
- describe "#resolve"
66
+ describe "#resolve" do
67
+ describe 'given a missing required solver' do
68
+ before do
69
+ allow(berksfile).to receive(:required_solver).and_return(:xyzzy)
70
+ allow(berksfile).to receive(:preferred_solver).and_return(nil)
71
+ end
72
+
73
+ it 'should raise an exception about missing required resolver :xyzzy' do
74
+ expect { subject.compute_solver_engine(berksfile) }.to raise_error(/Engine `xyzzy` is not supported/)
75
+ end
76
+ end
77
+
78
+ describe 'given a missing preferred solver' do
79
+ before do
80
+ allow(berksfile).to receive(:required_solver).and_return(nil)
81
+ allow(berksfile).to receive(:preferred_solver).and_return(:xyzzy)
82
+ end
83
+
84
+ it 'should not raise an exception about missing preferred resolver :xyzzy' do
85
+ expect { subject.compute_solver_engine(berksfile) }.not_to raise_error
86
+ end
87
+ end
88
+ end
62
89
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: berkshelf
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.0.1
4
+ version: 4.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jamie Winsor
@@ -12,7 +12,7 @@ authors:
12
12
  autorequire:
13
13
  bindir: bin
14
14
  cert_chain: []
15
- date: 2015-10-07 00:00:00.000000000 Z
15
+ date: 2016-02-04 00:00:00.000000000 Z
16
16
  dependencies:
17
17
  - !ruby/object:Gem::Dependency
18
18
  name: addressable
@@ -174,14 +174,14 @@ dependencies:
174
174
  requirements:
175
175
  - - "~>"
176
176
  - !ruby/object:Gem::Version
177
- version: '1.1'
177
+ version: '2.0'
178
178
  type: :runtime
179
179
  prerelease: false
180
180
  version_requirements: !ruby/object:Gem::Requirement
181
181
  requirements:
182
182
  - - "~>"
183
183
  - !ruby/object:Gem::Version
184
- version: '1.1'
184
+ version: '2.0'
185
185
  - !ruby/object:Gem::Dependency
186
186
  name: thor
187
187
  requirement: !ruby/object:Gem::Requirement
@@ -202,14 +202,14 @@ dependencies:
202
202
  requirements:
203
203
  - - "~>"
204
204
  - !ruby/object:Gem::Version
205
- version: '3.0'
205
+ version: '4.0'
206
206
  type: :runtime
207
207
  prerelease: false
208
208
  version_requirements: !ruby/object:Gem::Requirement
209
209
  requirements:
210
210
  - - "~>"
211
211
  - !ruby/object:Gem::Version
212
- version: '3.0'
212
+ version: '4.0'
213
213
  - !ruby/object:Gem::Dependency
214
214
  name: celluloid
215
215
  requirement: !ruby/object:Gem::Requirement
@@ -244,56 +244,70 @@ dependencies:
244
244
  requirements:
245
245
  - - "~>"
246
246
  - !ruby/object:Gem::Version
247
- version: '0.6'
247
+ version: 0.10.0
248
248
  type: :development
249
249
  prerelease: false
250
250
  version_requirements: !ruby/object:Gem::Requirement
251
251
  requirements:
252
252
  - - "~>"
253
253
  - !ruby/object:Gem::Version
254
- version: '0.6'
254
+ version: 0.10.0
255
255
  - !ruby/object:Gem::Dependency
256
256
  name: chef-zero
257
257
  requirement: !ruby/object:Gem::Requirement
258
258
  requirements:
259
259
  - - "~>"
260
260
  - !ruby/object:Gem::Version
261
- version: 1.5.0
261
+ version: '4.0'
262
+ type: :development
263
+ prerelease: false
264
+ version_requirements: !ruby/object:Gem::Requirement
265
+ requirements:
266
+ - - "~>"
267
+ - !ruby/object:Gem::Version
268
+ version: '4.0'
269
+ - !ruby/object:Gem::Dependency
270
+ name: dep_selector
271
+ requirement: !ruby/object:Gem::Requirement
272
+ requirements:
273
+ - - "~>"
274
+ - !ruby/object:Gem::Version
275
+ version: '1.0'
262
276
  type: :development
263
277
  prerelease: false
264
278
  version_requirements: !ruby/object:Gem::Requirement
265
279
  requirements:
266
280
  - - "~>"
267
281
  - !ruby/object:Gem::Version
268
- version: 1.5.0
282
+ version: '1.0'
269
283
  - !ruby/object:Gem::Dependency
270
284
  name: fuubar
271
285
  requirement: !ruby/object:Gem::Requirement
272
286
  requirements:
273
287
  - - "~>"
274
288
  - !ruby/object:Gem::Version
275
- version: '1.1'
289
+ version: '2.0'
276
290
  type: :development
277
291
  prerelease: false
278
292
  version_requirements: !ruby/object:Gem::Requirement
279
293
  requirements:
280
294
  - - "~>"
281
295
  - !ruby/object:Gem::Version
282
- version: '1.1'
296
+ version: '2.0'
283
297
  - !ruby/object:Gem::Dependency
284
298
  name: rake
285
299
  requirement: !ruby/object:Gem::Requirement
286
300
  requirements:
287
301
  - - "~>"
288
302
  - !ruby/object:Gem::Version
289
- version: '0.9'
303
+ version: '10.1'
290
304
  type: :development
291
305
  prerelease: false
292
306
  version_requirements: !ruby/object:Gem::Requirement
293
307
  requirements:
294
308
  - - "~>"
295
309
  - !ruby/object:Gem::Version
296
- version: '0.9'
310
+ version: '10.1'
297
311
  - !ruby/object:Gem::Dependency
298
312
  name: rspec
299
313
  requirement: !ruby/object:Gem::Requirement
@@ -364,6 +378,20 @@ dependencies:
364
378
  - - "~>"
365
379
  - !ruby/object:Gem::Version
366
380
  version: '0.8'
381
+ - !ruby/object:Gem::Dependency
382
+ name: http
383
+ requirement: !ruby/object:Gem::Requirement
384
+ requirements:
385
+ - - "~>"
386
+ - !ruby/object:Gem::Version
387
+ version: 0.9.8
388
+ type: :development
389
+ prerelease: false
390
+ version_requirements: !ruby/object:Gem::Requirement
391
+ requirements:
392
+ - - "~>"
393
+ - !ruby/object:Gem::Version
394
+ version: 0.9.8
367
395
  description: Manages a Cookbook's, or an Application's, Cookbook dependencies
368
396
  email:
369
397
  - jamie@vialstudios.com
@@ -381,6 +409,7 @@ files:
381
409
  - CHANGELOG.md
382
410
  - CONTRIBUTING.md
383
411
  - Gemfile
412
+ - Gemfile.lock
384
413
  - Guardfile
385
414
  - LICENSE
386
415
  - PLUGINS.md
@@ -496,6 +525,10 @@ files:
496
525
  - spec/config/knife.rb
497
526
  - spec/config/validator.pem
498
527
  - spec/fixtures/Berksfile
528
+ - spec/fixtures/berksfiles/default
529
+ - spec/fixtures/cookbook-path/jenkins-config/metadata.rb
530
+ - spec/fixtures/cookbook-store/jenkins-2.0.3/metadata.rb
531
+ - spec/fixtures/cookbook-store/jenkins-2.0.4/metadata.rb
499
532
  - spec/fixtures/cookbooks/example_cookbook-0.5.0/README.md
500
533
  - spec/fixtures/cookbooks/example_cookbook-0.5.0/metadata.rb
501
534
  - spec/fixtures/cookbooks/example_cookbook-0.5.0/recipes/default.rb
@@ -510,6 +543,7 @@ files:
510
543
  - spec/fixtures/lockfiles/blank.lock
511
544
  - spec/fixtures/lockfiles/default.lock
512
545
  - spec/fixtures/lockfiles/empty.lock
546
+ - spec/fixtures/lockfiles/orphans.lock
513
547
  - spec/spec_helper.rb
514
548
  - spec/support/chef_api.rb
515
549
  - spec/support/chef_server.rb
@@ -576,7 +610,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
576
610
  version: 1.8.0
577
611
  requirements: []
578
612
  rubyforge_project:
579
- rubygems_version: 2.2.2
613
+ rubygems_version: 2.4.7
580
614
  signing_key:
581
615
  specification_version: 4
582
616
  summary: Manages a Cookbook's, or an Application's, Cookbook dependencies
@@ -623,6 +657,10 @@ test_files:
623
657
  - spec/config/knife.rb
624
658
  - spec/config/validator.pem
625
659
  - spec/fixtures/Berksfile
660
+ - spec/fixtures/berksfiles/default
661
+ - spec/fixtures/cookbook-path/jenkins-config/metadata.rb
662
+ - spec/fixtures/cookbook-store/jenkins-2.0.3/metadata.rb
663
+ - spec/fixtures/cookbook-store/jenkins-2.0.4/metadata.rb
626
664
  - spec/fixtures/cookbooks/example_cookbook-0.5.0/README.md
627
665
  - spec/fixtures/cookbooks/example_cookbook-0.5.0/metadata.rb
628
666
  - spec/fixtures/cookbooks/example_cookbook-0.5.0/recipes/default.rb
@@ -637,6 +675,7 @@ test_files:
637
675
  - spec/fixtures/lockfiles/blank.lock
638
676
  - spec/fixtures/lockfiles/default.lock
639
677
  - spec/fixtures/lockfiles/empty.lock
678
+ - spec/fixtures/lockfiles/orphans.lock
640
679
  - spec/spec_helper.rb
641
680
  - spec/support/chef_api.rb
642
681
  - spec/support/chef_server.rb