berkshelf 1.4.6 → 2.0.0.beta

Sign up to get free protection for your applications and to get access to all the features.
Files changed (96) hide show
  1. data/.gitignore +1 -0
  2. data/CHANGELOG.md +1 -5
  3. data/CONTRIBUTING.md +3 -1
  4. data/Gemfile +11 -1
  5. data/README.md +16 -0
  6. data/Thorfile +3 -1
  7. data/berkshelf.gemspec +26 -38
  8. data/features/apply_command.feature +32 -0
  9. data/features/configure_command.feature +31 -0
  10. data/features/contingent_command.feature +5 -5
  11. data/features/default_locations.feature +2 -2
  12. data/features/groups_install.feature +19 -20
  13. data/features/info_command.feature +13 -13
  14. data/features/install_command.feature +86 -83
  15. data/features/json_formatter.feature +60 -23
  16. data/features/list_command.feature +5 -11
  17. data/features/lockfile.feature +286 -6
  18. data/features/open_command.feature +8 -4
  19. data/features/outdated_command.feature +8 -15
  20. data/features/package_command.feature +39 -0
  21. data/features/show_command.feature +8 -9
  22. data/features/step_definitions/chef_server_steps.rb +20 -2
  23. data/features/step_definitions/cli_steps.rb +10 -2
  24. data/features/step_definitions/configure_cli_steps.rb +7 -0
  25. data/features/step_definitions/filesystem_steps.rb +19 -14
  26. data/features/step_definitions/json_steps.rb +22 -5
  27. data/features/step_definitions/utility_steps.rb +13 -1
  28. data/features/support/env.rb +10 -23
  29. data/features/update_command.feature +105 -24
  30. data/features/upload_command.feature +0 -14
  31. data/features/vendor_install.feature +3 -3
  32. data/generator_files/Vagrantfile.erb +11 -11
  33. data/lib/berkshelf.rb +6 -5
  34. data/lib/berkshelf/berksfile.rb +267 -99
  35. data/lib/berkshelf/cli.rb +70 -34
  36. data/lib/berkshelf/cli_commands/test_command.rb +11 -0
  37. data/lib/berkshelf/community_rest.rb +1 -1
  38. data/lib/berkshelf/config.rb +19 -2
  39. data/lib/berkshelf/cookbook_source.rb +41 -12
  40. data/lib/berkshelf/cookbook_store.rb +8 -4
  41. data/lib/berkshelf/errors.rb +61 -29
  42. data/lib/berkshelf/formatters.rb +13 -19
  43. data/lib/berkshelf/formatters/human_readable.rb +8 -0
  44. data/lib/berkshelf/formatters/json.rb +12 -1
  45. data/lib/berkshelf/formatters/null.rb +23 -0
  46. data/lib/berkshelf/init_generator.rb +22 -11
  47. data/lib/berkshelf/location.rb +8 -10
  48. data/lib/berkshelf/locations/chef_api_location.rb +4 -5
  49. data/lib/berkshelf/locations/git_location.rb +14 -12
  50. data/lib/berkshelf/locations/path_location.rb +16 -1
  51. data/lib/berkshelf/locations/site_location.rb +1 -3
  52. data/lib/berkshelf/lockfile.rb +230 -33
  53. data/lib/berkshelf/resolver.rb +2 -1
  54. data/lib/berkshelf/ui.rb +4 -8
  55. data/lib/berkshelf/version.rb +1 -1
  56. data/lib/thor/monkies/shell.rb +2 -5
  57. data/spec/fixtures/cassettes/Berkshelf_Resolver/{ClassMethods/_initialize → _initialize}/adds_the_dependencies_of_the_source_as_sources.yml +0 -0
  58. data/spec/fixtures/cookbooks/example_cookbook/.gitignore +2 -0
  59. data/spec/fixtures/cookbooks/example_cookbook/.kitchen.yml +26 -0
  60. data/spec/fixtures/cookbooks/example_cookbook/Berksfile.lock +5 -0
  61. data/spec/fixtures/lockfiles/default.lock +11 -0
  62. data/spec/{config/knife.rb → knife.rb.sample} +2 -2
  63. data/spec/spec_helper.rb +15 -3
  64. data/spec/support/chef_api.rb +19 -5
  65. data/spec/support/chef_server.rb +4 -3
  66. data/spec/support/knife.rb +18 -0
  67. data/spec/unit/berkshelf/berksfile_spec.rb +332 -235
  68. data/spec/unit/berkshelf/cached_cookbook_spec.rb +40 -42
  69. data/spec/unit/berkshelf/chef/cookbook/chefignore_spec.rb +11 -15
  70. data/spec/unit/berkshelf/community_rest_spec.rb +16 -14
  71. data/spec/unit/berkshelf/config_spec.rb +36 -20
  72. data/spec/unit/berkshelf/cookbook_generator_spec.rb +6 -10
  73. data/spec/unit/berkshelf/cookbook_source_spec.rb +244 -183
  74. data/spec/unit/berkshelf/cookbook_store_spec.rb +72 -76
  75. data/spec/unit/berkshelf/core_ext/file_utils_spec.rb +2 -2
  76. data/spec/unit/berkshelf/downloader_spec.rb +137 -157
  77. data/spec/unit/berkshelf/errors_spec.rb +1 -1
  78. data/spec/unit/berkshelf/formatters/null_spec.rb +17 -0
  79. data/spec/unit/berkshelf/formatters_spec.rb +83 -90
  80. data/spec/unit/berkshelf/git_spec.rb +219 -207
  81. data/spec/unit/berkshelf/init_generator_spec.rb +73 -73
  82. data/spec/unit/berkshelf/location_spec.rb +143 -162
  83. data/spec/unit/berkshelf/locations/chef_api_location_spec.rb +94 -89
  84. data/spec/unit/berkshelf/locations/git_location_spec.rb +75 -59
  85. data/spec/unit/berkshelf/locations/path_location_spec.rb +46 -30
  86. data/spec/unit/berkshelf/locations/site_location_spec.rb +4 -4
  87. data/spec/unit/berkshelf/lockfile_spec.rb +185 -1
  88. data/spec/unit/berkshelf/logger_spec.rb +6 -24
  89. data/spec/unit/berkshelf/mixin/logging_spec.rb +6 -8
  90. data/spec/unit/berkshelf/resolver_spec.rb +36 -38
  91. data/spec/unit/berkshelf/ui_spec.rb +9 -10
  92. data/spec/unit/berkshelf_spec.rb +41 -40
  93. data/spec/unit/chef/config_spec.rb +9 -11
  94. metadata +55 -203
  95. data/spec/config/berkshelf.pem +0 -27
  96. data/spec/config/validator.pem +0 -27
@@ -1,19 +1,19 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Berkshelf::SiteLocation do
4
- describe "#download" do
4
+ describe '#download' do
5
5
  pending
6
6
  end
7
7
 
8
- describe "#target_version" do
8
+ describe '#target_version' do
9
9
  pending
10
10
  end
11
11
 
12
- describe "#to_hash" do
12
+ describe '#to_hash' do
13
13
  pending
14
14
  end
15
15
 
16
- describe "#to_s" do
16
+ describe '#to_s' do
17
17
  pending
18
18
  end
19
19
  end
@@ -1,5 +1,189 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Berkshelf::Lockfile do
4
- pending
4
+ let!(:content) { File.read(fixtures_path.join('lockfiles/default.lock')) }
5
+ let(:berksfile) { Berkshelf::Berksfile.new('Berksfile') }
6
+
7
+ before do
8
+ File.stub(:read).and_return(content)
9
+ end
10
+
11
+ describe '.initialize' do
12
+ it 'does not throw an exception' do
13
+ expect {
14
+ Berkshelf::Lockfile.new(berksfile)
15
+ }.to_not raise_error
16
+ end
17
+
18
+ it 'has the correct sha' do
19
+ expect(subject.sha).to eq('6b76225554cc1f7c0aea0f8b3f10c6743aeba67e')
20
+ end
21
+
22
+ it 'has the correct sources' do
23
+ expect(subject).to have_source 'build-essential'
24
+ expect(subject).to have_source 'chef-client'
25
+ end
26
+ end
27
+
28
+
29
+
30
+ subject { Berkshelf::Lockfile.new(berksfile) }
31
+
32
+ describe '#reset_sha!' do
33
+ it 'sets the sha to nil' do
34
+ expect { subject.reset_sha! }.to change { subject.sha }.to nil
35
+ end
36
+ end
37
+
38
+ describe '#sources' do
39
+ it 'returns an array' do
40
+ expect(subject.sources).to be_a(Array)
41
+ end
42
+ end
43
+
44
+ describe '#find' do
45
+ it 'returns a matching cookbook' do
46
+ expect(subject.find('build-essential').name).to eq 'build-essential'
47
+ end
48
+
49
+ it 'returns nil for a missing cookbook' do
50
+ expect(subject.find('foo')).to be_nil
51
+ end
52
+ end
53
+
54
+ describe '#has_source?' do
55
+ it 'returns true if a matching cookbook is found' do
56
+ expect(subject.has_source?('build-essential')).to be_true
57
+ end
58
+
59
+ it 'returns false if no matching cookbook is found' do
60
+ expect(subject.has_source?('foo')).to be_false
61
+ end
62
+ end
63
+
64
+ describe '#update' do
65
+ it 'resets the sources' do
66
+ subject.should_receive(:reset_sources!).once
67
+ subject.update([])
68
+ end
69
+
70
+ it 'updates the sha' do
71
+ expect {
72
+ subject.update([])
73
+ }.to change { subject.sha }
74
+ end
75
+
76
+ it 'appends each of the sources' do
77
+ source = double('source')
78
+ subject.should_receive(:append).with(source).once
79
+ subject.update([source])
80
+ end
81
+
82
+ it 'saves the file' do
83
+ subject.should_receive(:save).once
84
+ subject.update([])
85
+ end
86
+ end
87
+
88
+ describe '#add' do
89
+ let(:source) { double('source', name: 'build-essential') }
90
+
91
+ it 'adds the new source to the @sources instance variable' do
92
+ subject.add(source)
93
+ expect(subject).to have_source(source)
94
+ end
95
+
96
+ it 'does not add duplicate sources' do
97
+ 5.times { subject.add(source) }
98
+ expect(subject).to have_source(source)
99
+ end
100
+ end
101
+
102
+ describe '#remove' do
103
+ let(:source) { double('source', name: 'build-essential') }
104
+
105
+ before do
106
+ subject.add(source)
107
+ end
108
+
109
+ it 'removes the source' do
110
+ subject.remove(source)
111
+ expect(subject).to_not have_source(source)
112
+ end
113
+
114
+ it 'raises an except if the source does not exist' do
115
+ expect {
116
+ subject.remove(nil)
117
+ }.to raise_error Berkshelf::CookbookNotFound
118
+ end
119
+ end
120
+
121
+ describe '#to_s' do
122
+ it 'returns a pretty-formatted string' do
123
+ expect(subject.to_s).to eq '#<Berkshelf::Lockfile Berksfile.lock>'
124
+ end
125
+ end
126
+
127
+ describe '#inspect' do
128
+ it 'returns a pretty-formatted, detailed string' do
129
+ expect(subject.inspect).to eq '#<Berkshelf::Lockfile Berksfile.lock, sources: [#<Berkshelf::CookbookSource: build-essential (>= 0.0.0), locked_version: 1.1.2, groups: [:default], location: default>, #<Berkshelf::CookbookSource: chef-client (>= 0.0.0), locked_version: 2.1.4, groups: [:default], location: default>]>'
130
+ end
131
+ end
132
+
133
+ describe '#to_hash' do
134
+ let(:hash) { subject.to_hash }
135
+
136
+ it 'has the `:sha` key' do
137
+ expect(hash).to have_key(:sha)
138
+ end
139
+
140
+ it 'has the `:sources` key' do
141
+ expect(hash).to have_key(:sources)
142
+ end
143
+ end
144
+
145
+ describe '#to_json' do
146
+ it 'dumps the #to_hash to JSON' do
147
+ JSON.should_receive(:pretty_generate).with(subject.to_hash, {})
148
+ subject.to_json
149
+ end
150
+ end
151
+
152
+ describe '#save' do
153
+ before { Berkshelf::Lockfile.send(:public, :save) }
154
+ let(:file) { double('file') }
155
+
156
+ before(:each) do
157
+ File.stub(:open).with('Berksfile.lock', 'w')
158
+ end
159
+
160
+ it 'saves itself to a file on disk' do
161
+ File.should_receive(:open).with(/(.+)\/Berksfile\.lock/, 'w').and_yield(file)
162
+ file.should_receive(:write).once
163
+ subject.save
164
+ end
165
+ end
166
+
167
+ describe '#reset_sources!' do
168
+ before { Berkshelf::Lockfile.send(:public, :reset_sources!) }
169
+
170
+ it 'sets the sources to an empty hash' do
171
+ expect {
172
+ subject.reset_sources!
173
+ }.to change { subject.sources }.to([])
174
+ end
175
+ end
176
+
177
+ describe '#cookbook_name' do
178
+ before { Berkshelf::Lockfile.send(:public, :cookbook_name) }
179
+
180
+ it 'accepts a cookbook source' do
181
+ source = double('source', name: 'build-essential', is_a?: true)
182
+ expect(subject.cookbook_name(source)).to eq 'build-essential'
183
+ end
184
+
185
+ it 'accepts a string' do
186
+ expect(subject.cookbook_name('build-essential')).to eq 'build-essential'
187
+ end
188
+ end
5
189
  end
@@ -1,29 +1,11 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Berkshelf::Logger do
4
- subject { described_class }
5
-
6
- it "responds to :info" do
7
- subject.should respond_to(:info)
8
- end
9
-
10
- it "responds to :warn" do
11
- subject.should respond_to(:warn)
12
- end
13
-
14
- it "responds to :error" do
15
- subject.should respond_to(:error)
16
- end
17
-
18
- it "responds to :fatal" do
19
- subject.should respond_to(:fatal)
20
- end
21
-
22
- it "responds to :debug" do
23
- subject.should respond_to(:debug)
24
- end
25
-
26
- it "responds to :deprecate" do
27
- subject.should respond_to(:deprecate)
4
+ %w(info warn error fatal debug deprecate).each do |meth|
5
+ describe "##{meth}" do
6
+ it 'responds' do
7
+ expect(Berkshelf::Logger).to respond_to(meth.to_sym)
8
+ end
9
+ end
28
10
  end
29
11
  end
@@ -2,19 +2,17 @@ require 'spec_helper'
2
2
 
3
3
  describe Berkshelf::Mixin::Logging do
4
4
  subject do
5
- Class.new do
6
- include Berkshelf::Mixin::Logging
7
- end.new
5
+ Class.new { include Berkshelf::Mixin::Logging }.new
8
6
  end
9
7
 
10
- describe "#log" do
11
- it "returns the Berkshelf::Logger" do
12
- subject.log.should eql(Berkshelf::Logger)
8
+ describe '#log' do
9
+ it 'returns the Berkshelf::Logger' do
10
+ expect(subject.log).to eq(Berkshelf::Logger)
13
11
  end
14
12
  end
15
13
 
16
- describe "#log_exception" do
17
- it "logs the exception and it's backtrace as fatal" do
14
+ describe '#log_exception' do
15
+ it 'logs the exception and backtrace as fatal' do
18
16
  ex = Exception.new('msg')
19
17
  ex.stub(:backtrace).and_return(['one', 'two'])
20
18
  subject.log.should_receive(:fatal).exactly(2).times
@@ -18,63 +18,57 @@ describe Berkshelf::Resolver, :chef_server, vcr: { record: :new_episodes, serial
18
18
  )
19
19
  end
20
20
 
21
- describe "ClassMethods" do
22
- subject { described_class }
23
-
24
- describe "::initialize" do
25
- it "adds the specified sources to the sources hash" do
26
- resolver = subject.new(berksfile, sources: [source], skip_dependencies: true)
27
-
28
- resolver.should have_source(source.name)
29
- end
30
-
31
- it "should not add dependencies if requested" do
32
- resolver = subject.new(berksfile, sources: [source], skip_dependencies: true)
33
-
34
- resolver.should_not have_source("nginx")
35
- end
21
+ describe '.initialize' do
22
+ it 'adds the specified sources to the sources hash' do
23
+ resolver = Berkshelf::Resolver.new(berksfile, sources: [source], skip_dependencies: true)
24
+ expect(resolver).to have_source(source.name)
25
+ end
36
26
 
37
- it "adds the dependencies of the source as sources" do
38
- resolver = subject.new(berksfile, sources: [source])
27
+ it 'does not add dependencies if skipped' do
28
+ resolver = Berkshelf::Resolver.new(berksfile, sources: [source], skip_dependencies: true)
29
+ expect(resolver).to_not have_source('nginx')
30
+ end
39
31
 
40
- resolver.should have_source("nginx")
41
- end
32
+ it 'adds the dependencies of the source as sources' do
33
+ resolver = Berkshelf::Resolver.new(berksfile, sources: [source])
34
+ expect(resolver).to have_source('nginx')
42
35
  end
43
36
  end
44
37
 
45
- subject { described_class.new(berksfile) }
46
38
 
47
- describe "#add_source" do
39
+
40
+ subject { Berkshelf::Resolver.new(berksfile) }
41
+
42
+ describe '#add_source' do
48
43
  let(:package_version) { double('package-version', dependencies: Array.new) }
49
44
 
50
- it "adds the source to the instance of resolver" do
45
+ it 'adds the source to the instance of resolver' do
51
46
  subject.add_source(source, false)
52
-
53
- subject.sources.should include(source)
47
+ expect(subject.sources).to include(source)
54
48
  end
55
49
 
56
- it "adds an artifact of the same name of the source to the graph" do
50
+ it 'adds an artifact of the same name of the source to the graph' do
57
51
  subject.graph.should_receive(:artifacts).with(source.name, source.cached_cookbook.version)
58
52
 
59
53
  subject.add_source(source, false)
60
54
  end
61
55
 
62
- it "adds the dependencies of the source as packages to the graph" do
56
+ it 'adds the dependencies of the source as packages to the graph' do
63
57
  subject.should_receive(:add_source_dependencies).with(source)
64
58
 
65
59
  subject.add_source(source)
66
60
  end
67
61
 
68
- it "raises a DuplicateSourceDefined exception if a source of the same name is added" do
62
+ it 'raises a DuplicateSourceDefined exception if a source of the same name is added' do
69
63
  subject.should_receive(:has_source?).with(source).and_return(true)
70
64
 
71
- lambda {
65
+ expect {
72
66
  subject.add_source(source)
73
- }.should raise_error(Berkshelf::DuplicateSourceDefined)
67
+ }.to raise_error(Berkshelf::DuplicateSourceDefined)
74
68
  end
75
69
 
76
- context "when include_dependencies is false" do
77
- it "does not try to include_dependencies" do
70
+ context 'when include_dependencies is false' do
71
+ it 'does not try to include_dependencies' do
78
72
  subject.should_not_receive(:add_source_dependencies)
79
73
 
80
74
  subject.add_source(source, false)
@@ -82,21 +76,25 @@ describe Berkshelf::Resolver, :chef_server, vcr: { record: :new_episodes, serial
82
76
  end
83
77
  end
84
78
 
85
- describe "#get_source" do
79
+ describe '#get_source' do
86
80
  before { subject.add_source(source, false) }
87
81
 
88
- context "given a string representation of the source to retrieve" do
89
- it "returns the source of the same name" do
90
- subject.get_source(source.name).should eql(source)
82
+ context 'given a string representation of the source to retrieve' do
83
+ it 'returns the source of the same name' do
84
+ expect(subject.get_source(source.name)).to eq(source)
91
85
  end
92
86
  end
93
87
  end
94
88
 
95
- describe "#has_source?" do
89
+ describe '#has_source?' do
96
90
  before { subject.add_source(source, false) }
97
91
 
98
- it "returns the source of the given name" do
99
- subject.has_source?(source.name).should be_true
92
+ it 'returns true if the source exists' do
93
+ expect(subject.has_source?(source.name)).to be_true
94
+ end
95
+
96
+ it 'returns false if the source does not exist' do
97
+ expect(subject.has_source?('non-existent')).to be_false
100
98
  end
101
99
  end
102
100
  end
@@ -1,30 +1,29 @@
1
1
  require 'spec_helper'
2
2
 
3
-
4
- describe Thor::Shell::Color do
3
+ describe Thor::Base.shell do
5
4
  let(:stdout) { double('stdout') }
6
5
  let(:stderr) { double('stderr') }
7
6
 
8
7
  before do
9
- Thor::Shell::Basic.any_instance.stub(:stdout).and_return(stdout)
10
- Thor::Shell::Basic.any_instance.stub(:stderr).and_return(stderr)
8
+ described_class.any_instance.stub(:stdout).and_return(stdout)
9
+ described_class.any_instance.stub(:stderr).and_return(stderr)
11
10
  end
12
11
 
13
- context '#mute!' do
12
+ describe '#mute!' do
14
13
  it 'sets @mute to true' do
15
14
  subject.mute!
16
15
  expect(subject.instance_variable_get(:@mute)).to be_true
17
16
  end
18
17
  end
19
18
 
20
- context '#unmute!' do
19
+ describe '#unmute!' do
21
20
  it 'sets @mute to false' do
22
21
  subject.unmute!
23
22
  expect(subject.instance_variable_get(:@mute)).to be_false
24
23
  end
25
24
  end
26
25
 
27
- context '#say' do
26
+ describe '#say' do
28
27
  context 'when quiet?' do
29
28
  before do
30
29
  subject.stub(:quiet?).and_return(true)
@@ -49,7 +48,7 @@ describe Thor::Shell::Color do
49
48
  end
50
49
  end
51
50
 
52
- context '#say_status' do
51
+ describe '#say_status' do
53
52
  context 'when quiet?' do
54
53
  before do
55
54
  subject.stub(:quiet?).and_return(true)
@@ -74,7 +73,7 @@ describe Thor::Shell::Color do
74
73
  end
75
74
  end
76
75
 
77
- context '#warn' do
76
+ describe '#warn' do
78
77
  context 'when quiet?' do
79
78
  before do
80
79
  subject.stub(:quiet?).and_return(true)
@@ -100,7 +99,7 @@ describe Thor::Shell::Color do
100
99
  end
101
100
  end
102
101
 
103
- context '#deprecated' do
102
+ describe '#deprecated' do
104
103
  it 'prefixes the message with "[DEPRECATED]"' do
105
104
  subject.should_receive(:warn).with('[DEPRECATION] That was deprecated!')
106
105
  subject.deprecated 'That was deprecated!'