berkshelf 2.0.18 → 3.0.0.beta1
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.
- data/.ruby-version +1 -1
- data/.travis.yml +4 -1
- data/CHANGELOG.md +2 -26
- data/Gemfile +12 -2
- data/README.md +9 -1
- data/berkshelf.gemspec +9 -18
- data/bin/berks +3 -13
- data/features/apply_command.feature +11 -9
- data/features/berksfile.feature +8 -10
- data/features/config.feature +1 -2
- data/features/configure_command.feature +13 -14
- data/features/contingent_command.feature +13 -1
- data/features/cookbook_command.feature +2 -4
- data/features/groups_install.feature +10 -2
- data/features/help.feature +1 -1
- data/features/init_command.feature +5 -7
- data/features/install_command.feature +157 -228
- data/features/json_formatter.feature +27 -15
- data/features/licenses.feature +18 -12
- data/features/list_command.feature +6 -1
- data/features/lockfile.feature +116 -72
- data/features/outdated_command.feature +3 -47
- data/features/package_command.feature +10 -7
- data/features/shelf/show.feature +2 -2
- data/features/shelf/uninstall.feature +2 -2
- data/features/show_command.feature +10 -3
- data/features/step_definitions/chef/config_steps.rb +12 -0
- data/features/step_definitions/chef_server_steps.rb +16 -16
- data/features/step_definitions/cli_steps.rb +3 -79
- data/features/step_definitions/config_steps.rb +43 -0
- data/features/step_definitions/environment_steps.rb +7 -0
- data/features/step_definitions/filesystem_steps.rb +12 -57
- data/features/step_definitions/gem_steps.rb +1 -2
- data/features/step_definitions/json_steps.rb +3 -1
- data/features/step_definitions/lockfile_steps.rb +4 -0
- data/features/step_definitions/utility_steps.rb +0 -19
- data/features/support/aruba.rb +12 -0
- data/features/support/env.rb +52 -57
- data/features/update_command.feature +37 -23
- data/features/upload_command.feature +96 -160
- data/generator_files/Berksfile.erb +2 -1
- data/generator_files/Vagrantfile.erb +3 -0
- data/generator_files/default_test.rb.erb +1 -1
- data/generator_files/helpers.rb.erb +1 -1
- data/lib/berkshelf.rb +43 -24
- data/lib/berkshelf/api_client.rb +67 -0
- data/lib/berkshelf/api_client/remote_cookbook.rb +42 -0
- data/lib/berkshelf/berksfile.rb +232 -420
- data/lib/berkshelf/cached_cookbook.rb +22 -10
- data/lib/berkshelf/chef/config.rb +1 -0
- data/lib/berkshelf/cli.rb +66 -68
- data/lib/berkshelf/commands/shelf.rb +1 -1
- data/lib/berkshelf/community_rest.rb +10 -17
- data/lib/berkshelf/config.rb +23 -27
- data/lib/berkshelf/cookbook_generator.rb +3 -4
- data/lib/berkshelf/cookbook_store.rb +74 -17
- data/lib/berkshelf/core_ext/file.rb +2 -2
- data/lib/berkshelf/core_ext/pathname.rb +7 -5
- data/lib/berkshelf/{cookbook_source.rb → dependency.rb} +47 -67
- data/lib/berkshelf/downloader.rb +49 -106
- data/lib/berkshelf/errors.rb +64 -71
- data/lib/berkshelf/formatters.rb +11 -9
- data/lib/berkshelf/formatters/human_readable.rb +9 -9
- data/lib/berkshelf/formatters/json.rb +14 -4
- data/lib/berkshelf/init_generator.rb +3 -3
- data/lib/berkshelf/installer.rb +136 -0
- data/lib/berkshelf/location.rb +91 -131
- data/lib/berkshelf/locations/git_location.rb +9 -11
- data/lib/berkshelf/locations/github_location.rb +1 -1
- data/lib/berkshelf/locations/path_location.rb +10 -27
- data/lib/berkshelf/lockfile.rb +92 -70
- data/lib/berkshelf/logger.rb +4 -7
- data/lib/berkshelf/mixin/config.rb +21 -4
- data/lib/berkshelf/resolver.rb +60 -150
- data/lib/berkshelf/resolver/graph.rb +44 -0
- data/lib/berkshelf/source.rb +55 -0
- data/lib/berkshelf/source_uri.rb +38 -0
- data/lib/berkshelf/version.rb +1 -1
- data/spec/config/knife.rb +1 -1
- data/spec/fixtures/cassettes/Berkshelf_Resolver/_initialize/adds_the_dependencies_of_the_dependency_as_dependencies.yml +3694 -0
- data/spec/fixtures/cookbooks/example_cookbook/Berksfile.lock +1 -1
- data/spec/fixtures/lockfiles/default.lock +1 -1
- data/spec/spec_helper.rb +20 -121
- data/spec/support/chef_api.rb +3 -4
- data/spec/support/chef_server.rb +20 -11
- data/spec/support/git.rb +127 -0
- data/spec/support/kitchen.rb +12 -0
- data/spec/support/path_helpers.rb +69 -0
- data/spec/unit/berkshelf/api_client/remote_cookbook_spec.rb +23 -0
- data/spec/unit/berkshelf/api_client_spec.rb +57 -0
- data/spec/unit/berkshelf/berksfile_spec.rb +206 -324
- data/spec/unit/berkshelf/cached_cookbook_spec.rb +73 -38
- data/spec/unit/berkshelf/community_rest_spec.rb +30 -71
- data/spec/unit/berkshelf/config_spec.rb +3 -14
- data/spec/unit/berkshelf/cookbook_generator_spec.rb +1 -2
- data/spec/unit/berkshelf/cookbook_store_spec.rb +12 -7
- data/spec/unit/berkshelf/dependency_spec.rb +285 -0
- data/spec/unit/berkshelf/downloader_spec.rb +4 -183
- data/spec/unit/berkshelf/formatters/null_spec.rb +1 -1
- data/spec/unit/berkshelf/formatters_spec.rb +4 -2
- data/spec/unit/berkshelf/git_spec.rb +15 -15
- data/spec/unit/berkshelf/installer_spec.rb +39 -0
- data/spec/unit/berkshelf/location_spec.rb +87 -114
- data/spec/unit/berkshelf/locations/git_location_spec.rb +41 -53
- data/spec/unit/berkshelf/locations/path_location_spec.rb +13 -23
- data/spec/unit/berkshelf/lockfile_spec.rb +38 -40
- data/spec/unit/berkshelf/resolver/graph_spec.rb +44 -0
- data/spec/unit/berkshelf/resolver_spec.rb +34 -83
- data/spec/unit/berkshelf/source_spec.rb +23 -0
- data/spec/unit/berkshelf/source_uri_spec.rb +29 -0
- metadata +149 -188
- checksums.yaml +0 -7
- data/features/default_locations.feature +0 -127
- data/features/step_definitions/berksfile_steps.rb +0 -8
- data/features/step_definitions/configure_cli_steps.rb +0 -19
- data/features/vendor_install.feature +0 -19
- data/lib/berkshelf/core_ext/openuri.rb +0 -36
- data/lib/berkshelf/core_ext/rbzip2.rb +0 -8
- data/lib/berkshelf/locations/chef_api_location.rb +0 -228
- data/lib/berkshelf/locations/site_location.rb +0 -92
- data/lib/berkshelf/test.rb +0 -35
- data/spec/knife.rb.sample +0 -12
- data/spec/support/test_generators.rb +0 -27
- data/spec/unit/berkshelf/cli_spec.rb +0 -16
- data/spec/unit/berkshelf/cookbook_source_spec.rb +0 -358
- data/spec/unit/berkshelf/core_ext/pathname_spec.rb +0 -46
- data/spec/unit/berkshelf/locations/chef_api_location_spec.rb +0 -139
- data/spec/unit/berkshelf/locations/site_location_spec.rb +0 -19
|
@@ -1,70 +1,63 @@
|
|
|
1
1
|
require 'spec_helper'
|
|
2
2
|
|
|
3
3
|
describe Berkshelf::CachedCookbook do
|
|
4
|
-
describe
|
|
5
|
-
|
|
6
|
-
|
|
4
|
+
describe "ClassMethods" do
|
|
5
|
+
describe '::from_store_path' do
|
|
6
|
+
let(:path) { fixtures_path.join('cookbooks', 'example_cookbook-0.5.0') }
|
|
7
|
+
let(:cached) { described_class.from_path(path) }
|
|
7
8
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
it 'sets a version number' do
|
|
13
|
-
expect(cached.version).to eq('0.5.0')
|
|
14
|
-
end
|
|
15
|
-
|
|
16
|
-
it 'sets the metadata.name value to the cookbook_name' do
|
|
17
|
-
expect(cached.metadata.name).to eq('example_cookbook')
|
|
18
|
-
end
|
|
9
|
+
it 'returns a CachedCookbook' do
|
|
10
|
+
expect(cached).to be_a(described_class)
|
|
11
|
+
end
|
|
19
12
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
expect(Berkshelf::CachedCookbook.from_store_path(tmp_path)).to be_nil
|
|
13
|
+
it 'sets a version number' do
|
|
14
|
+
expect(cached.version).to eq('0.5.0')
|
|
23
15
|
end
|
|
24
|
-
end
|
|
25
16
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
path = fixtures_path.join('cookbooks', 'example_cookbook')
|
|
29
|
-
expect(Berkshelf::CachedCookbook.from_store_path(path)).to be_nil
|
|
17
|
+
it 'sets the metadata.name value to the cookbook_name' do
|
|
18
|
+
expect(cached.metadata.name).to eq('example_cookbook')
|
|
30
19
|
end
|
|
31
20
|
|
|
32
|
-
context 'given
|
|
33
|
-
|
|
21
|
+
context 'given a path that does not contain a cookbook' do
|
|
22
|
+
it 'returns nil' do
|
|
23
|
+
expect(described_class.from_store_path(tmp_path)).to be_nil
|
|
24
|
+
end
|
|
25
|
+
end
|
|
34
26
|
|
|
35
|
-
|
|
36
|
-
|
|
27
|
+
context 'given a path that does not match the CachedCookbook dirname format' do
|
|
28
|
+
it 'returns nil' do
|
|
29
|
+
path = fixtures_path.join('cookbooks', 'example_cookbook')
|
|
30
|
+
expect(described_class.from_store_path(path)).to be_nil
|
|
37
31
|
end
|
|
38
32
|
end
|
|
39
33
|
end
|
|
40
34
|
|
|
41
|
-
describe '
|
|
35
|
+
describe '::checksum' do
|
|
42
36
|
it 'returns a checksum of the given filepath' do
|
|
43
37
|
path = fixtures_path.join('cookbooks', 'example_cookbook-0.5.0', 'README.md')
|
|
44
|
-
expect(
|
|
38
|
+
expect(described_class.checksum(path)).to eq('6e21094b7a920e374e7261f50e9c4eef')
|
|
45
39
|
end
|
|
46
40
|
|
|
47
41
|
context 'given path does not exist' do
|
|
48
42
|
it 'raises an Errno::ENOENT error' do
|
|
49
43
|
expect {
|
|
50
|
-
|
|
44
|
+
described_class.checksum(fixtures_path.join('notexisting.file'))
|
|
51
45
|
}.to raise_error(Errno::ENOENT)
|
|
52
46
|
end
|
|
53
47
|
end
|
|
54
48
|
end
|
|
55
49
|
end
|
|
56
50
|
|
|
51
|
+
let(:dependencies) { { 'mysql' => '= 1.2.0', 'ntp' => '>= 0.0.0' } }
|
|
52
|
+
let(:recommendations) { { 'database' => '>= 0.0.0' } }
|
|
53
|
+
let(:path) do
|
|
54
|
+
generate_cookbook(Berkshelf.cookbook_store.storage_path,
|
|
55
|
+
'sparkle', '0.1.0', dependencies: dependencies, recommendations: recommendations)
|
|
56
|
+
end
|
|
57
57
|
|
|
58
|
-
|
|
59
|
-
let(:dependencies) { { 'mysql' => '= 1.2.0', 'ntp' => '>= 0.0.0' } }
|
|
60
|
-
let(:recommendations) { { 'database' => '>= 0.0.0' } }
|
|
61
|
-
|
|
62
|
-
let(:path) do
|
|
63
|
-
generate_cookbook(Berkshelf.cookbook_store.storage_path, 'sparkle', '0.1.0', dependencies: dependencies, recommendations: recommendations)
|
|
64
|
-
end
|
|
65
|
-
|
|
66
|
-
subject { Berkshelf::CachedCookbook.from_store_path(path) }
|
|
58
|
+
subject { Berkshelf::CachedCookbook.from_store_path(path) }
|
|
67
59
|
|
|
60
|
+
describe '#dependencies' do
|
|
68
61
|
it 'contains depends from the cookbook metadata' do
|
|
69
62
|
expect(subject.dependencies).to include(dependencies)
|
|
70
63
|
end
|
|
@@ -72,5 +65,47 @@ describe Berkshelf::CachedCookbook do
|
|
|
72
65
|
it 'contains recommendations from the cookbook metadata' do
|
|
73
66
|
expect(subject.dependencies).to include(recommendations)
|
|
74
67
|
end
|
|
68
|
+
|
|
69
|
+
it 'returns a hash' do
|
|
70
|
+
expect(subject.dependencies).to be_a(Hash)
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
describe '#pretty_hash' do
|
|
75
|
+
shared_examples 'a pretty_hash cookbook attribute' do |attribute, key|
|
|
76
|
+
it "is not present when the `#{attribute}` attribute is nil" do
|
|
77
|
+
subject.stub(attribute.to_sym).and_return(nil)
|
|
78
|
+
expect(subject.pretty_hash).to_not have_key((key || attribute).to_sym)
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
it "is not present when the `#{attribute}` attribute is an empty string" do
|
|
82
|
+
subject.stub(attribute.to_sym).and_return('')
|
|
83
|
+
expect(subject.pretty_hash).to_not have_key((key || attribute).to_sym)
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
it "is not present when the `#{attribute}` attribute is an empty array" do
|
|
87
|
+
subject.stub(attribute.to_sym).and_return([])
|
|
88
|
+
expect(subject.pretty_hash).to_not have_key((key || attribute).to_sym)
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
it "is not present when the `#{attribute}` attribute is an empty hash" do
|
|
92
|
+
subject.stub(attribute.to_sym).and_return([])
|
|
93
|
+
expect(subject.pretty_hash).to_not have_key((key || attribute).to_sym)
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
it "is present when the `#{attribute}` attribute has a Hash value" do
|
|
97
|
+
subject.stub(attribute.to_sym).and_return(foo: 'bar')
|
|
98
|
+
expect(subject.pretty_hash).to have_key((key || attribute).to_sym)
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
it_behaves_like 'a pretty_hash cookbook attribute', 'cookbook_name', 'name'
|
|
103
|
+
it_behaves_like 'a pretty_hash cookbook attribute', 'version'
|
|
104
|
+
it_behaves_like 'a pretty_hash cookbook attribute', 'description'
|
|
105
|
+
it_behaves_like 'a pretty_hash cookbook attribute', 'maintainer', 'author'
|
|
106
|
+
it_behaves_like 'a pretty_hash cookbook attribute', 'maintainer_email', 'email'
|
|
107
|
+
it_behaves_like 'a pretty_hash cookbook attribute', 'license'
|
|
108
|
+
it_behaves_like 'a pretty_hash cookbook attribute', 'platforms'
|
|
109
|
+
it_behaves_like 'a pretty_hash cookbook attribute', 'dependencies'
|
|
75
110
|
end
|
|
76
111
|
end
|
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
require 'spec_helper'
|
|
2
2
|
|
|
3
3
|
describe Berkshelf::CommunityREST, vcr: { record: :new_episodes, serialize_with: :json } do
|
|
4
|
-
describe
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
describe 'a tar.gz file' do
|
|
4
|
+
describe "ClassMethods" do
|
|
5
|
+
describe "::unpack" do
|
|
6
|
+
let(:target) { '/foo/bar' }
|
|
7
|
+
let(:destination) { '/destination/bar' }
|
|
8
|
+
let(:file) { double('file') }
|
|
10
9
|
let(:gzip_reader) { double('gzip_reader') }
|
|
11
10
|
|
|
12
11
|
before do
|
|
@@ -15,7 +14,7 @@ describe Berkshelf::CommunityREST, vcr: { record: :new_episodes, serialize_with:
|
|
|
15
14
|
Archive::Tar::Minitar.stub(:unpack).with(gzip_reader, destination)
|
|
16
15
|
end
|
|
17
16
|
|
|
18
|
-
it 'unpacks the
|
|
17
|
+
it 'unpacks the tar' do
|
|
19
18
|
File.should_receive(:open).with(target, 'rb')
|
|
20
19
|
::IO.should_receive(:binread).with(target, 2).and_return([0x1F, 0x8B].pack("C*"))
|
|
21
20
|
Zlib::GzipReader.should_receive(:new).with(file)
|
|
@@ -25,85 +24,45 @@ describe Berkshelf::CommunityREST, vcr: { record: :new_episodes, serialize_with:
|
|
|
25
24
|
end
|
|
26
25
|
end
|
|
27
26
|
|
|
28
|
-
describe
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
Archive::Tar::Minitar.stub(:unpack).with(target, destination)
|
|
27
|
+
describe "::uri_escape_version" do
|
|
28
|
+
it 'returns a string' do
|
|
29
|
+
expect(Berkshelf::CommunityREST.uri_escape_version(nil)).to be_a(String)
|
|
32
30
|
end
|
|
33
31
|
|
|
34
|
-
it '
|
|
35
|
-
::
|
|
36
|
-
::IO.should_receive(:binread).with(target, 8, 257).and_return("ustar\x0000")
|
|
37
|
-
Archive::Tar::Minitar.should_receive(:unpack).with(target, destination)
|
|
38
|
-
|
|
39
|
-
expect(Berkshelf::CommunityREST.unpack(target, destination)).to eq(destination)
|
|
32
|
+
it 'converts a version to it\'s underscored version' do
|
|
33
|
+
expect(Berkshelf::CommunityREST.uri_escape_version('1.1.2')).to eq('1_1_2')
|
|
40
34
|
end
|
|
41
|
-
end
|
|
42
|
-
|
|
43
|
-
describe 'a tar.bz2 file' do
|
|
44
|
-
let(:bzip2_reader) { double('bzip2_reader') }
|
|
45
35
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
RBzip2::Decompressor.stub(:new).with(file).and_return(bzip2_reader)
|
|
49
|
-
Archive::Tar::Minitar.stub(:unpack).with(bzip2_reader, destination)
|
|
36
|
+
it 'works when the version has more than three points' do
|
|
37
|
+
expect(Berkshelf::CommunityREST.uri_escape_version('1.1.1.2')).to eq('1_1_1_2')
|
|
50
38
|
end
|
|
51
39
|
|
|
52
|
-
it '
|
|
53
|
-
|
|
54
|
-
::IO.should_receive(:binread).twice
|
|
55
|
-
::IO.should_receive(:binread).with(target, 3).and_return('BZh')
|
|
56
|
-
RBzip2::Decompressor.should_receive(:new).with(file)
|
|
57
|
-
Archive::Tar::Minitar.should_receive(:unpack).with(bzip2_reader, destination)
|
|
58
|
-
|
|
59
|
-
expect(Berkshelf::CommunityREST.unpack(target, destination)).to eq(destination)
|
|
40
|
+
it 'works when the version has less than three points' do
|
|
41
|
+
expect(Berkshelf::CommunityREST.uri_escape_version('1.2')).to eq('1_2')
|
|
60
42
|
end
|
|
61
43
|
end
|
|
62
|
-
end
|
|
63
|
-
|
|
64
|
-
describe '.uri_escape_version' do
|
|
65
|
-
it 'returns a string' do
|
|
66
|
-
expect(Berkshelf::CommunityREST.uri_escape_version(nil)).to be_a(String)
|
|
67
|
-
end
|
|
68
|
-
|
|
69
|
-
it 'converts a version to it\'s underscored version' do
|
|
70
|
-
expect(Berkshelf::CommunityREST.uri_escape_version('1.1.2')).to eq('1_1_2')
|
|
71
|
-
end
|
|
72
44
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
it 'works when the version has less than three points' do
|
|
78
|
-
expect(Berkshelf::CommunityREST.uri_escape_version('1.2')).to eq('1_2')
|
|
79
|
-
end
|
|
80
|
-
end
|
|
81
|
-
|
|
82
|
-
describe '.version_from_uri' do
|
|
83
|
-
it 'returns a string' do
|
|
84
|
-
expect(Berkshelf::CommunityREST.version_from_uri(nil)).to be_a(String)
|
|
85
|
-
end
|
|
45
|
+
describe "::version_from_uri" do
|
|
46
|
+
it 'returns a string' do
|
|
47
|
+
expect(Berkshelf::CommunityREST.version_from_uri(nil)).to be_a(String)
|
|
48
|
+
end
|
|
86
49
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
50
|
+
it 'extracts the version from the URL' do
|
|
51
|
+
expect(Berkshelf::CommunityREST.version_from_uri('/api/v1/cookbooks/nginx/versions/1_1_2')).to eq('1.1.2')
|
|
52
|
+
end
|
|
90
53
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
54
|
+
it 'works when the version has more than three points' do
|
|
55
|
+
expect(Berkshelf::CommunityREST.version_from_uri('/api/v1/cookbooks/nginx/versions/1_1_1_2')).to eq('1.1.1.2')
|
|
56
|
+
end
|
|
94
57
|
|
|
95
|
-
|
|
96
|
-
|
|
58
|
+
it 'works when the version has less than three points' do
|
|
59
|
+
expect(Berkshelf::CommunityREST.version_from_uri('/api/v1/cookbooks/nginx/versions/1_2')).to eq('1.2')
|
|
60
|
+
end
|
|
97
61
|
end
|
|
98
62
|
end
|
|
99
63
|
|
|
100
|
-
|
|
101
|
-
|
|
102
64
|
let(:api_uri) { Berkshelf::CommunityREST::V1_API }
|
|
103
|
-
|
|
104
|
-
subject do
|
|
105
|
-
Berkshelf::CommunityREST.new(api_uri)
|
|
106
|
-
end
|
|
65
|
+
subject { Berkshelf::CommunityREST.new(api_uri) }
|
|
107
66
|
|
|
108
67
|
describe '#download' do
|
|
109
68
|
let(:archive) { double('archive', path: '/foo/bar', unlink: true) }
|
|
@@ -114,7 +73,7 @@ describe Berkshelf::CommunityREST, vcr: { record: :new_episodes, serialize_with:
|
|
|
114
73
|
end
|
|
115
74
|
|
|
116
75
|
it 'unpacks the archive' do
|
|
117
|
-
Berkshelf::CommunityREST.should_receive(:unpack).with('/foo/bar').once
|
|
76
|
+
Berkshelf::CommunityREST.should_receive(:unpack).with('/foo/bar').once.and_return('/foo/nginx')
|
|
118
77
|
archive.should_receive(:unlink).once
|
|
119
78
|
|
|
120
79
|
subject.download('nginx', '1.4.0')
|
|
@@ -30,21 +30,10 @@ describe Berkshelf::Config do
|
|
|
30
30
|
Berkshelf::Config.instance_variable_set(:@path, nil)
|
|
31
31
|
end
|
|
32
32
|
|
|
33
|
-
|
|
34
|
-
context "with '#{location}' as the config file" do
|
|
35
|
-
let(:path) { File.expand_path(location) }
|
|
36
|
-
before { File.stub(:exists?).with(path).and_return(true) }
|
|
37
|
-
|
|
38
|
-
it "returns '#{location}' as the path" do
|
|
39
|
-
expect(Berkshelf::Config.path).to eq(path)
|
|
40
|
-
end
|
|
41
|
-
end
|
|
42
|
-
end
|
|
43
|
-
|
|
44
|
-
context "when ENV['BERKSHELF_PATH'] is used" do
|
|
33
|
+
context "when ENV['BERKSHELF_CONFIG'] is used" do
|
|
45
34
|
before do
|
|
46
|
-
ENV.stub(:[]).with('
|
|
47
|
-
File.stub(:exists?).with('/tmp').and_return(true)
|
|
35
|
+
ENV.stub(:[]).with('BERKSHELF_CONFIG').and_return('/tmp/config.json')
|
|
36
|
+
File.stub(:exists?).with('/tmp/config.json').and_return(true)
|
|
48
37
|
end
|
|
49
38
|
|
|
50
39
|
it "points to a location within it" do
|
|
@@ -17,7 +17,6 @@ describe Berkshelf::CookbookGenerator do
|
|
|
17
17
|
specify do
|
|
18
18
|
expect(target).to have_structure {
|
|
19
19
|
directory 'attributes'
|
|
20
|
-
directory 'definitions'
|
|
21
20
|
directory 'files' do
|
|
22
21
|
directory 'default'
|
|
23
22
|
end
|
|
@@ -51,7 +50,7 @@ describe Berkshelf::CookbookGenerator do
|
|
|
51
50
|
contains "description 'Installs/Configures sparkle_motion'"
|
|
52
51
|
end
|
|
53
52
|
file 'Berksfile' do
|
|
54
|
-
contains '
|
|
53
|
+
contains 'source "http://api.berkshelf.com"'
|
|
55
54
|
contains 'metadata'
|
|
56
55
|
end
|
|
57
56
|
file 'Gemfile'
|
|
@@ -1,17 +1,20 @@
|
|
|
1
1
|
require 'spec_helper'
|
|
2
2
|
|
|
3
3
|
describe Berkshelf::CookbookStore do
|
|
4
|
-
describe
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
Berkshelf::CookbookStore.new(storage_path)
|
|
4
|
+
describe "ClassMethods" do
|
|
5
|
+
describe "::instance"
|
|
6
|
+
describe "::import"
|
|
8
7
|
|
|
9
|
-
|
|
8
|
+
describe "::new" do
|
|
9
|
+
it 'creates the storage_path' do
|
|
10
|
+
storage_path = tmp_path.join('random_storage')
|
|
11
|
+
Berkshelf::CookbookStore.new(storage_path)
|
|
12
|
+
|
|
13
|
+
expect(storage_path).to exist
|
|
14
|
+
end
|
|
10
15
|
end
|
|
11
16
|
end
|
|
12
17
|
|
|
13
|
-
|
|
14
|
-
|
|
15
18
|
subject { Berkshelf::CookbookStore.new(tmp_path.join("cbstore_rspec")) }
|
|
16
19
|
|
|
17
20
|
describe '#cookbook_path' do
|
|
@@ -104,4 +107,6 @@ describe Berkshelf::CookbookStore do
|
|
|
104
107
|
end
|
|
105
108
|
end
|
|
106
109
|
end
|
|
110
|
+
|
|
111
|
+
describe "#import"
|
|
107
112
|
end
|
|
@@ -0,0 +1,285 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe Berkshelf::Dependency do
|
|
4
|
+
let(:cookbook_name) { 'nginx' }
|
|
5
|
+
let(:berksfile) { double('berksfile', filepath: fixtures_path.join('Berksfile').to_s) }
|
|
6
|
+
|
|
7
|
+
describe "ClassMethods" do
|
|
8
|
+
describe "::new" do
|
|
9
|
+
let(:source) { described_class.new(berksfile, cookbook_name) }
|
|
10
|
+
|
|
11
|
+
context 'given no location key (i.e. :git, :path, :site)' do
|
|
12
|
+
it 'sets a nil valie for location' do
|
|
13
|
+
expect(source.location).to be_nil
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
context 'given no value for :locked_version' do
|
|
18
|
+
it 'returns a wildcard match for any version' do
|
|
19
|
+
expect(source.locked_version).to be_nil
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
context 'given no value for :constraint' do
|
|
24
|
+
it 'returns a wildcard match for any version' do
|
|
25
|
+
expect(source.version_constraint.to_s).to eq('>= 0.0.0')
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
context 'given a value for :constraint' do
|
|
30
|
+
let(:source) { described_class.new(berksfile, cookbook_name, constraint: '~> 1.0.84') }
|
|
31
|
+
|
|
32
|
+
it 'returns a Solve::Constraint for the given version for version_constraint' do
|
|
33
|
+
expect(source.version_constraint.to_s).to eq('~> 1.0.84')
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
context 'given a location key :git' do
|
|
38
|
+
let(:url) { 'git://url_to_git' }
|
|
39
|
+
let(:source) { described_class.new(berksfile, cookbook_name, git: url) }
|
|
40
|
+
|
|
41
|
+
it 'initializes a GitLocation for location' do
|
|
42
|
+
expect(source.location).to be_a(Berkshelf::GitLocation)
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
it 'points to the given Git URL' do
|
|
46
|
+
expect(source.location.uri).to eq(url)
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
context 'given a location key :path' do
|
|
51
|
+
context 'given a value for path that contains a cookbook' do
|
|
52
|
+
let(:path) { fixtures_path.join('cookbooks', 'example_cookbook').to_s }
|
|
53
|
+
let(:location) { described_class.new(berksfile, cookbook_name, path: path).location }
|
|
54
|
+
|
|
55
|
+
it 'initializes a PathLocation for location' do
|
|
56
|
+
expect(location).to be_a(Berkshelf::PathLocation)
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
it 'points to the specified path' do
|
|
60
|
+
expect(location.path).to eq(path)
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
context 'given an invalid option' do
|
|
65
|
+
it 'raises BerkshelfError with a friendly message' do
|
|
66
|
+
expect {
|
|
67
|
+
described_class.new(berksfile, cookbook_name, invalid_opt: 'thisisnotvalid')
|
|
68
|
+
}.to raise_error(Berkshelf::BerkshelfError, "Invalid options for dependency: 'invalid_opt'.")
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
it 'raises BerkshelfError with a messaging containing all of the invalid options' do
|
|
72
|
+
expect {
|
|
73
|
+
described_class.new(berksfile, cookbook_name, invalid_one: 'one', invalid_two: 'two')
|
|
74
|
+
}.to raise_error(Berkshelf::BerkshelfError, "Invalid options for dependency: 'invalid_one', 'invalid_two'.")
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
context 'given multiple location options' do
|
|
79
|
+
it 'raises with an Berkshelf::BerkshelfError' do
|
|
80
|
+
expect {
|
|
81
|
+
described_class.new(berksfile, cookbook_name, path: '/something', git: 'something')
|
|
82
|
+
}.to raise_error(Berkshelf::BerkshelfError)
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
context 'given a group option containing a single group' do
|
|
87
|
+
let(:group) { :production }
|
|
88
|
+
let(:source) { described_class.new(berksfile, cookbook_name, group: group) }
|
|
89
|
+
|
|
90
|
+
it 'assigns the single group to the groups attribute' do
|
|
91
|
+
expect(source.groups).to include(group)
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
context 'given a group option containing an array of groups' do
|
|
96
|
+
let(:groups) { [ :development, :test ] }
|
|
97
|
+
let(:source) { described_class.new(berksfile, cookbook_name, group: groups) }
|
|
98
|
+
|
|
99
|
+
it 'assigns all the groups to the group attribute' do
|
|
100
|
+
expect(source.groups).to eq(groups)
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
context 'given no group option' do
|
|
105
|
+
let(:source) { described_class.new(berksfile, cookbook_name) }
|
|
106
|
+
|
|
107
|
+
it 'has the default group assigned' do
|
|
108
|
+
expect(source.groups).to include(:default)
|
|
109
|
+
end
|
|
110
|
+
end
|
|
111
|
+
end
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
describe "::add_valid_option" do
|
|
115
|
+
before do
|
|
116
|
+
@original = described_class.class_variable_get :@@valid_options
|
|
117
|
+
described_class.class_variable_set :@@valid_options, []
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
after do
|
|
121
|
+
described_class.class_variable_set :@@valid_options, @original
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
it 'adds an option to the list of valid options' do
|
|
125
|
+
described_class.add_valid_option(:one)
|
|
126
|
+
|
|
127
|
+
expect(described_class.valid_options).to have(1).item
|
|
128
|
+
expect(described_class.valid_options).to include(:one)
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
it 'does not add duplicate options to the list of valid options' do
|
|
132
|
+
described_class.add_valid_option(:one)
|
|
133
|
+
described_class.add_valid_option(:one)
|
|
134
|
+
|
|
135
|
+
expect(described_class.valid_options).to have(1).item
|
|
136
|
+
end
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
describe "::add_location_key" do
|
|
140
|
+
before do
|
|
141
|
+
@original = described_class.class_variable_get :@@location_keys
|
|
142
|
+
described_class.class_variable_set :@@location_keys, {}
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
after do
|
|
146
|
+
described_class.class_variable_set :@@location_keys, @original
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
it 'adds a location key and the associated class to the list of valid locations' do
|
|
150
|
+
described_class.add_location_key(:git, described_class)
|
|
151
|
+
|
|
152
|
+
expect(described_class.location_keys).to have(1).item
|
|
153
|
+
expect(described_class.location_keys).to include(:git)
|
|
154
|
+
expect(described_class.location_keys[:git]).to eq(described_class)
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
it 'does not add duplicate location keys to the list of location keys' do
|
|
158
|
+
described_class.add_location_key(:git, described_class)
|
|
159
|
+
described_class.add_location_key(:git, described_class)
|
|
160
|
+
|
|
161
|
+
expect(described_class.location_keys).to have(1).item
|
|
162
|
+
expect(described_class.location_keys).to include(:git)
|
|
163
|
+
end
|
|
164
|
+
end
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
subject { described_class.new(berksfile, cookbook_name) }
|
|
168
|
+
|
|
169
|
+
describe '#add_group' do
|
|
170
|
+
it 'stores strings as symbols' do
|
|
171
|
+
subject.add_group 'foo'
|
|
172
|
+
expect(subject.groups).to eq([:default, :foo])
|
|
173
|
+
end
|
|
174
|
+
|
|
175
|
+
it 'does not store duplicate groups' do
|
|
176
|
+
subject.add_group 'bar'
|
|
177
|
+
subject.add_group 'bar'
|
|
178
|
+
subject.add_group :bar
|
|
179
|
+
expect(subject.groups).to eq([:default, :bar])
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
it 'adds multiple groups' do
|
|
183
|
+
subject.add_group 'baz', 'quux'
|
|
184
|
+
expect(subject.groups).to eq([:default, :baz, :quux])
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
it 'handles multiple groups as an array' do
|
|
188
|
+
subject.add_group ['baz', 'quux']
|
|
189
|
+
expect(subject.groups).to eq([:default, :baz, :quux])
|
|
190
|
+
end
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
describe "#cached_cookbook"
|
|
194
|
+
describe "#download"
|
|
195
|
+
|
|
196
|
+
describe '#downloaded?' do
|
|
197
|
+
it 'returns true if self.cached_cookbook is not nil' do
|
|
198
|
+
subject.stub(:cached_cookbook) { double('cb') }
|
|
199
|
+
expect(subject.downloaded?).to be_true
|
|
200
|
+
end
|
|
201
|
+
|
|
202
|
+
it 'returns false if self.cached_cookbook is nil' do
|
|
203
|
+
subject.stub(:cached_cookbook) { nil }
|
|
204
|
+
expect(subject.downloaded?).to be_false
|
|
205
|
+
end
|
|
206
|
+
end
|
|
207
|
+
|
|
208
|
+
describe '#to_hash' do
|
|
209
|
+
let(:hash) { subject.to_hash }
|
|
210
|
+
|
|
211
|
+
it 'does not include default values' do
|
|
212
|
+
[:constraint, :locked_version, :site, :git, :ref, :path].each do |key|
|
|
213
|
+
expect(hash).to_not have_key(key)
|
|
214
|
+
end
|
|
215
|
+
end
|
|
216
|
+
|
|
217
|
+
it 'includes the constraint' do
|
|
218
|
+
subject.version_constraint = '~> 1.0.0'
|
|
219
|
+
|
|
220
|
+
expect(hash).to have_key(:constraint)
|
|
221
|
+
expect(hash[:constraint]).to eq('~> 1.0.0')
|
|
222
|
+
end
|
|
223
|
+
|
|
224
|
+
it 'includes the locked version' do
|
|
225
|
+
subject.stub(cached_cookbook: double('cached', version: '1.2.3'))
|
|
226
|
+
|
|
227
|
+
expect(hash).to have_key(:locked_version)
|
|
228
|
+
expect(hash[:locked_version]).to eq('1.2.3')
|
|
229
|
+
end
|
|
230
|
+
|
|
231
|
+
it 'includes the git url and ref' do
|
|
232
|
+
location = double('git', uri: 'git://github.com/foo/bar.git', ref: 'abcd1234', rel: nil, download: nil)
|
|
233
|
+
location.stub(:kind_of?).and_return(false)
|
|
234
|
+
location.stub(:kind_of?).with(Berkshelf::GitLocation).and_return(true)
|
|
235
|
+
subject.stub(:location).and_return(location)
|
|
236
|
+
|
|
237
|
+
expect(hash).to have_key(:git)
|
|
238
|
+
expect(hash[:git]).to eq('git://github.com/foo/bar.git')
|
|
239
|
+
expect(hash).to have_key(:ref)
|
|
240
|
+
expect(hash[:ref]).to eq('abcd1234')
|
|
241
|
+
end
|
|
242
|
+
|
|
243
|
+
it 'includes the git url and rel' do
|
|
244
|
+
location = double('git', uri: 'git://github.com/foo/bar.git', ref: nil, rel: 'cookbooks/foo', download: nil)
|
|
245
|
+
location.stub(:kind_of?).and_return(false)
|
|
246
|
+
location.stub(:kind_of?).with(Berkshelf::GitLocation).and_return(true)
|
|
247
|
+
subject.stub(:location).and_return(location)
|
|
248
|
+
|
|
249
|
+
expect(hash).to have_key(:git)
|
|
250
|
+
expect(hash[:git]).to eq('git://github.com/foo/bar.git')
|
|
251
|
+
expect(hash).to have_key(:rel)
|
|
252
|
+
expect(hash[:rel]).to eq('cookbooks/foo')
|
|
253
|
+
end
|
|
254
|
+
|
|
255
|
+
it 'includes a relative path' do
|
|
256
|
+
location = double('path', relative_path: '../dev/foo')
|
|
257
|
+
location.stub(:kind_of?).and_return(false)
|
|
258
|
+
location.stub(:kind_of?).with(Berkshelf::PathLocation).and_return(true)
|
|
259
|
+
subject.stub(:location).and_return(location)
|
|
260
|
+
|
|
261
|
+
expect(hash).to have_key(:path)
|
|
262
|
+
expect(hash[:path]).to eq('../dev/foo')
|
|
263
|
+
end
|
|
264
|
+
end
|
|
265
|
+
|
|
266
|
+
describe "#scm_location?" do
|
|
267
|
+
let(:options) { Hash.new }
|
|
268
|
+
subject { described_class.new(berksfile, cookbook_name, options).scm_location? }
|
|
269
|
+
|
|
270
|
+
context "when the location is a GitLocation" do
|
|
271
|
+
let(:options) { { git: "git@github.com:RiotGames/berkshelf.git" } }
|
|
272
|
+
it { should be_true }
|
|
273
|
+
end
|
|
274
|
+
|
|
275
|
+
context "when the location is a GithubLocation" do
|
|
276
|
+
let(:options) { { github: "RiotGames/berkshelf" } }
|
|
277
|
+
it { should be_true }
|
|
278
|
+
end
|
|
279
|
+
|
|
280
|
+
context "when the location is a PathLocation" do
|
|
281
|
+
let(:options) { { path: fixtures_path.join('cookbooks', 'example_cookbook') } }
|
|
282
|
+
it { should be_false }
|
|
283
|
+
end
|
|
284
|
+
end
|
|
285
|
+
end
|