berkshelf 3.0.0.beta7 → 3.0.0.beta8

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 (94) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/.travis.yml +4 -1
  4. data/CONTRIBUTING.md +1 -1
  5. data/Gemfile +0 -1
  6. data/Guardfile +0 -8
  7. data/README.md +33 -13
  8. data/berkshelf.gemspec +3 -3
  9. data/features/commands/install.feature +16 -88
  10. data/features/commands/search.feature +15 -0
  11. data/features/commands/shelf/show.feature +2 -2
  12. data/features/commands/shelf/uninstall.feature +1 -1
  13. data/features/commands/show.feature +3 -3
  14. data/features/commands/update.feature +29 -1
  15. data/features/commands/upload.feature +172 -7
  16. data/features/commands/vendor.feature +32 -0
  17. data/features/json_formatter.feature +26 -24
  18. data/features/lifecycle.feature +285 -0
  19. data/features/lockfile.feature +9 -7
  20. data/features/step_definitions/chef_server_steps.rb +1 -0
  21. data/features/step_definitions/cli_steps.rb +2 -2
  22. data/features/step_definitions/filesystem_steps.rb +2 -4
  23. data/gem_graph.png +0 -0
  24. data/generator_files/chefignore +0 -2
  25. data/lib/berkshelf.rb +39 -14
  26. data/lib/berkshelf/berksfile.rb +161 -113
  27. data/lib/berkshelf/cached_cookbook.rb +2 -2
  28. data/lib/berkshelf/cli.rb +15 -3
  29. data/lib/berkshelf/commands/shelf.rb +3 -7
  30. data/lib/berkshelf/community_rest.rb +9 -9
  31. data/lib/berkshelf/config.rb +3 -3
  32. data/lib/berkshelf/cookbook_generator.rb +0 -8
  33. data/lib/berkshelf/cookbook_store.rb +1 -2
  34. data/lib/berkshelf/dependency.rb +25 -138
  35. data/lib/berkshelf/downloader.rb +41 -7
  36. data/lib/berkshelf/errors.rb +113 -214
  37. data/lib/berkshelf/formatters/base.rb +42 -0
  38. data/lib/berkshelf/formatters/human.rb +145 -0
  39. data/lib/berkshelf/formatters/json.rb +149 -133
  40. data/lib/berkshelf/formatters/null.rb +8 -18
  41. data/lib/berkshelf/init_generator.rb +1 -1
  42. data/lib/berkshelf/installer.rb +115 -104
  43. data/lib/berkshelf/location.rb +22 -121
  44. data/lib/berkshelf/locations/base.rb +75 -0
  45. data/lib/berkshelf/locations/git.rb +196 -0
  46. data/lib/berkshelf/locations/github.rb +8 -0
  47. data/lib/berkshelf/locations/path.rb +78 -0
  48. data/lib/berkshelf/lockfile.rb +452 -290
  49. data/lib/berkshelf/logger.rb +9 -3
  50. data/lib/berkshelf/mixin/logging.rb +4 -9
  51. data/lib/berkshelf/resolver.rb +12 -12
  52. data/lib/berkshelf/source.rb +13 -1
  53. data/lib/berkshelf/version.rb +1 -1
  54. data/spec/fixtures/cookbooks/example_cookbook-0.5.0/metadata.rb +3 -7
  55. data/spec/fixtures/cookbooks/example_cookbook/metadata.rb +3 -6
  56. data/spec/spec_helper.rb +5 -6
  57. data/spec/support/matchers/file_system_matchers.rb +4 -0
  58. data/spec/support/shared_examples/formatter.rb +11 -0
  59. data/spec/unit/berkshelf/berksfile_spec.rb +25 -28
  60. data/spec/unit/berkshelf/cli_spec.rb +19 -11
  61. data/spec/unit/berkshelf/dependency_spec.rb +4 -164
  62. data/spec/unit/berkshelf/formatters/base_spec.rb +35 -0
  63. data/spec/unit/berkshelf/formatters/human_spec.rb +7 -0
  64. data/spec/unit/berkshelf/formatters/json_spec.rb +7 -0
  65. data/spec/unit/berkshelf/formatters/null_spec.rb +7 -11
  66. data/spec/unit/berkshelf/location_spec.rb +16 -144
  67. data/spec/unit/berkshelf/locations/base_spec.rb +80 -0
  68. data/spec/unit/berkshelf/locations/git_spec.rb +249 -0
  69. data/spec/unit/berkshelf/locations/path_spec.rb +107 -0
  70. data/spec/unit/berkshelf/lockfile_parser_spec.rb +3 -3
  71. data/spec/unit/berkshelf/lockfile_spec.rb +55 -11
  72. data/spec/unit/berkshelf/logger_spec.rb +2 -2
  73. data/spec/unit/berkshelf/mixin/logging_spec.rb +5 -9
  74. data/spec/unit/berkshelf/source_spec.rb +32 -13
  75. data/spec/unit/berkshelf_spec.rb +6 -9
  76. metadata +33 -33
  77. data/.ruby-version +0 -1
  78. data/berkshelf-complete.sh +0 -75
  79. data/lib/berkshelf/formatters.rb +0 -110
  80. data/lib/berkshelf/formatters/human_readable.rb +0 -142
  81. data/lib/berkshelf/git.rb +0 -204
  82. data/lib/berkshelf/locations/git_location.rb +0 -135
  83. data/lib/berkshelf/locations/github_location.rb +0 -55
  84. data/lib/berkshelf/locations/mercurial_location.rb +0 -114
  85. data/lib/berkshelf/locations/path_location.rb +0 -88
  86. data/lib/berkshelf/mercurial.rb +0 -146
  87. data/lib/berkshelf/mixin.rb +0 -7
  88. data/spec/support/mercurial.rb +0 -123
  89. data/spec/unit/berkshelf/formatters_spec.rb +0 -114
  90. data/spec/unit/berkshelf/git_spec.rb +0 -312
  91. data/spec/unit/berkshelf/locations/git_location_spec.rb +0 -126
  92. data/spec/unit/berkshelf/locations/mercurial_location_spec.rb +0 -131
  93. data/spec/unit/berkshelf/locations/path_location_spec.rb +0 -25
  94. data/spec/unit/berkshelf/mercurial_spec.rb +0 -172
@@ -1,126 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Berkshelf::GitLocation do
4
- let(:constraint) { double('comp-vconstraint', satisfies?: true) }
5
- let(:dependency) { double('dep', name: "berkshelf-cookbook-fixture", version_constraint: constraint) }
6
-
7
- describe "ClassMethods" do
8
- describe "::new" do
9
- it 'raises InvalidGitURI if given an invalid Git URI for options[:git]' do
10
- expect {
11
- described_class.new(dependency, git: '/something/on/disk')
12
- }.to raise_error(Berkshelf::InvalidGitURI)
13
- end
14
- end
15
- end
16
-
17
- let(:storage_path) { Berkshelf::CookbookStore.instance.storage_path }
18
- subject { described_class.new(dependency, git: 'git://github.com/RiotGames/berkshelf-cookbook-fixture.git') }
19
-
20
- describe '#download' do
21
- context 'when a local revision is present' do
22
- let(:cached) { double('cached') }
23
-
24
- before do
25
- Berkshelf::Git.stub(:rev_parse).and_return('abcd1234')
26
- described_class.any_instance.stub(:cached?).and_return(true)
27
- described_class.any_instance.stub(:validate_cached).with(cached).and_return(cached)
28
- Berkshelf::CachedCookbook.stub(:from_store_path).with(any_args()).and_return(cached)
29
- end
30
-
31
- it 'returns the cached cookbook' do
32
- expect(subject.download).to eq(cached)
33
- end
34
- end
35
-
36
- it 'returns an instance of Berkshelf::CachedCookbook' do
37
- expect(subject.download).to be_a(Berkshelf::CachedCookbook)
38
- end
39
-
40
- it 'downloads the cookbook to the given destination' do
41
- cached_cookbook = subject.download
42
- ref = subject.ref
43
-
44
- expect(storage_path).to have_structure {
45
- directory "#{cached_cookbook.cookbook_name}-#{ref}" do
46
- file 'metadata.rb'
47
- end
48
- }
49
- end
50
-
51
- context 'given no ref/branch/tag options is given' do
52
- subject { described_class.new(dependency, git: 'git://github.com/RiotGames/berkshelf-cookbook-fixture.git') }
53
-
54
- it 'sets the branch attribute to the HEAD revision of the cloned repo' do
55
- subject.download
56
- expect(subject.branch).to_not be_nil
57
- end
58
- end
59
-
60
- context 'given a git repo that does not exist' do
61
- before { dependency.stub(name: "doesnot_exist") }
62
- subject { described_class.new(dependency, git: 'git://github.com/RiotGames/thisrepo_does_not_exist.git') }
63
-
64
- it 'raises a GitError' do
65
- Berkshelf::Git.stub(:git).and_raise(Berkshelf::GitError.new(''))
66
- expect { subject.download }.to raise_error(Berkshelf::GitError)
67
- end
68
- end
69
-
70
- context 'given a git repo that does not contain a cookbook' do
71
- let(:fake_remote) { remote_path('not_a_cookbook') }
72
- before { dependency.stub(name: "doesnot_exist") }
73
- subject { described_class.new(dependency, git: "file://#{fake_remote}.git") }
74
-
75
- it 'raises a CookbookNotFound error' do
76
- Berkshelf::Git.stub(:clone).and_return {
77
- FileUtils.mkdir_p(fake_remote)
78
- Dir.chdir(fake_remote) { |dir| `git init && echo hi > README && git add README && git commit README -m 'README'`; dir }
79
- }
80
-
81
- expect { subject.download }.to raise_error(Berkshelf::CookbookNotFound)
82
- end
83
- end
84
-
85
- context 'given the content at the Git repo does not satisfy the version constraint' do
86
- before { constraint.stub(satisfies?: false) }
87
- subject { described_class.new(dependency, git: 'git://github.com/RiotGames/berkshelf-cookbook-fixture.git') }
88
-
89
- it 'raises a CookbookValidationFailure error' do
90
- expect { subject.download }.to raise_error(Berkshelf::CookbookValidationFailure)
91
- end
92
- end
93
-
94
- context 'given a value for tag' do
95
- let(:tag) { 'v1.0.0' }
96
-
97
- subject do
98
- described_class.new(dependency, git: 'git://github.com/RiotGames/berkshelf-cookbook-fixture.git', tag: tag)
99
- end
100
-
101
- let(:cached) { subject.download }
102
- let(:sha) { subject.ref }
103
- let(:expected_path) { storage_path.join("#{cached.cookbook_name}-#{sha}") }
104
-
105
- it 'returns a cached cookbook with a path that contains the ref' do
106
- expect(cached.path).to eq(expected_path)
107
- end
108
- end
109
-
110
- context 'give a value for branch' do
111
- let(:branch) { 'master' }
112
-
113
- subject do
114
- described_class.new(dependency, git: 'git://github.com/RiotGames/berkshelf-cookbook-fixture.git',
115
- branch: branch)
116
- end
117
- let(:cached) { subject.download }
118
- let(:sha) { subject.ref }
119
- let(:expected_path) { storage_path.join("#{cached.cookbook_name}-#{sha}") }
120
-
121
- it 'returns a cached cookbook with a path that contains the ref' do
122
- expect(cached.path).to eq(expected_path)
123
- end
124
- end
125
- end
126
- end
@@ -1,131 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Berkshelf::MercurialLocation do
4
- include Berkshelf::RSpec::Mercurial
5
-
6
- let(:cookbook_uri) { mercurial_origin_for('fake_cookbook', is_cookbook: true, tags: ["1.0.0"], branches: ["mybranch"]) }
7
- let(:constraint) { double('comp-vconstraint', satisfies?: true) }
8
- let(:dependency) { double('dep', name: "berkshelf-cookbook-fixture", version_constraint: constraint) }
9
- let(:storage_path) { Berkshelf::CookbookStore.instance.storage_path }
10
-
11
- describe '::initialize' do
12
- it 'raises InvalidHgURI if given an invalid URI for options[:hg]' do
13
- expect {
14
- described_class.new(dependency, hg: '/something/on/disk')
15
- }.to raise_error(Berkshelf::InvalidHgURI)
16
- end
17
- end
18
-
19
- subject { described_class.new(dependency, hg: cookbook_uri) }
20
-
21
- describe '#download' do
22
- before do
23
- clean_tmp_path
24
- FileUtils.mkdir_p(storage_path)
25
- cookbook_uri
26
- end
27
-
28
- context 'when a local revision is present' do
29
- let(:cached) { double('cached') }
30
-
31
- before do
32
- Berkshelf::Mercurial.stub(:rev_parse).and_return('abcd1234')
33
- described_class.any_instance.stub(:cached?).and_return(true)
34
- described_class.any_instance.stub(:validate_cached).with(cached).and_return(cached)
35
- Berkshelf::CachedCookbook.stub(:from_store_path).with(any_args()).and_return(cached)
36
- end
37
-
38
- it 'returns the cached cookbook' do
39
- expect(subject.download).to eq(cached)
40
- end
41
- end
42
-
43
- it 'returns an instance of Berkshelf::CachedCookbook' do
44
- expect(subject.download).to be_a(Berkshelf::CachedCookbook)
45
- end
46
-
47
- it 'downloads the cookbook to the given destination' do
48
- cached_cookbook = subject.download
49
- rev = subject.rev
50
-
51
- expect(storage_path).to have_structure {
52
- directory "#{cached_cookbook.cookbook_name}-#{rev}" do
53
- file 'metadata.rb'
54
- end
55
- }
56
- end
57
-
58
- context 'given no ref/branch/tag options is given' do
59
- subject { described_class.new(dependency, hg: cookbook_uri) }
60
-
61
- it 'sets the branch attribute to the default revision of the cloned repo' do
62
- subject.download
63
- expect(subject.branch).to_not be_nil
64
- end
65
- end
66
-
67
- context 'given a repo that does not exist' do
68
- before { dependency.stub(name: "doesnot_exist") }
69
- subject { described_class.new(dependency, hg: 'http://thisdoesntexist.org/notarepo') }
70
-
71
- it 'raises a MercurailError' do
72
- Berkshelf::Mercurial.stub(:hg).and_raise(Berkshelf::MercurialError.new(''))
73
- expect {
74
- subject.download
75
- }.to raise_error(Berkshelf::MercurialError)
76
- end
77
- end
78
-
79
- context 'given a hg repo that does not contain a cookbook' do
80
- let(:fake_remote) { mercurial_origin_for('not_a_cookbook', is_cookbook: false) }
81
- subject { described_class.new(dependency, hg: fake_remote) }
82
-
83
- it 'raises a CookbookNotFound error' do
84
- expect {
85
- subject.download
86
- }.to raise_error(Berkshelf::CookbookNotFound)
87
- end
88
- end
89
-
90
- context 'given the content at the repo does not satisfy the version constraint' do
91
- before { constraint.stub(satisfies?: false) }
92
- subject do
93
- described_class.new(dependency,
94
- hg: cookbook_uri
95
- )
96
- end
97
-
98
- it 'raises a CookbookValidationFailure error' do
99
- expect {
100
- subject.download
101
- }.to raise_error(Berkshelf::CookbookValidationFailure)
102
- end
103
- end
104
-
105
- context 'given a value for tag' do
106
- let(:tag) { '1.0.0' }
107
- subject { described_class.new(dependency, hg: cookbook_uri, tag: tag) }
108
-
109
- let(:cached) { subject.download }
110
- let(:sha) { subject.rev }
111
- let(:expected_path) { storage_path.join("#{cached.cookbook_name}-#{sha}") }
112
-
113
- it 'returns a cached cookbook with a path that contains the ref' do
114
- expect(cached.path).to eq(expected_path)
115
- end
116
- end
117
-
118
- context 'give a value for branch' do
119
- let(:branch) { 'mybranch' }
120
- subject { described_class.new(dependency, hg: cookbook_uri, branch: branch) }
121
-
122
- let(:cached) { subject.download }
123
- let(:sha) { subject.rev }
124
- let(:expected_path) { storage_path.join("#{cached.cookbook_name}-#{sha}") }
125
-
126
- it 'returns a cached cookbook with a path that contains the ref' do
127
- expect(cached.path).to eq(expected_path)
128
- end
129
- end
130
- end
131
- end
@@ -1,25 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Berkshelf::PathLocation do
4
- let(:constraint) { double('comp-vconstraint', satisfies?: true) }
5
- let(:dependency) { double('dep', name: "nginx", version_constraint: constraint) }
6
- let(:path) { fixtures_path.join('cookbooks', 'example_cookbook').to_s }
7
-
8
- describe "ClassMethods" do
9
- describe "::new" do
10
- it 'assigns the value of :path to #path' do
11
- location = described_class.new(dependency, path: path)
12
- expect(location.path).to eq(path)
13
- end
14
- end
15
- end
16
-
17
- let(:options) { { path: path } }
18
- let(:instance) { described_class.new(dependency, options) }
19
-
20
- describe "#download" do
21
- it "returns a CachedCookbook" do
22
- expect(instance.download).to be_a(Berkshelf::CachedCookbook)
23
- end
24
- end
25
- end
@@ -1,172 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Berkshelf::Mercurial do
4
- include Berkshelf::RSpec::Mercurial
5
-
6
- let(:hg) { Berkshelf::Mercurial }
7
-
8
- describe '::find_hg' do
9
- it 'finds hg' do
10
- expect(described_class.find_hg).to_not be_nil
11
- end
12
-
13
- it 'raises an error if mercurial cannot be not found' do
14
- ENV.should_receive(:[]).with('PATH').and_return(String.new)
15
-
16
- expect {
17
- described_class.find_hg
18
- }.to raise_error(Berkshelf::MercurialNotFound)
19
- end
20
- end
21
-
22
- describe '::clone' do
23
- let(:target) { clone_path('nginx') }
24
-
25
- it 'clones the repository to the target path' do
26
- origin_uri = mercurial_origin_for('nginx')
27
-
28
- described_class.clone(origin_uri, target)
29
-
30
- expect(target).to exist
31
- expect(target).to be_directory
32
- end
33
- end
34
-
35
- describe '::checkout' do
36
- let(:repo_path) { clone_path('nginx') }
37
- let(:repo) {
38
- origin_uri = mercurial_origin_for('nginx', tags: ['1.0.1', '1.0.2'], branches: ['topic', 'next_topic'])
39
- hg.clone(origin_uri, repo_path)
40
- }
41
-
42
- shared_examples 'able to checkout hg rev' do |test_rev|
43
- it 'checks out the specified rev of the given repository' do
44
- hg.checkout(repo, rev)
45
-
46
- Dir.chdir repo_path do
47
- test_rev ||= rev
48
- expect(%x[hg id -r #{test_rev}].split(' ').first).to eq(%x[hg id -i].strip)
49
- end
50
- end
51
- end
52
-
53
- context 'with sha commit id' do
54
- let(:rev) { id_for_rev('nginx', '1.0.1') }
55
-
56
- it_behaves_like 'able to checkout hg rev'
57
- end
58
-
59
- context 'with tags' do
60
- let(:rev) { '1.0.1' }
61
-
62
- it_behaves_like 'able to checkout hg rev'
63
-
64
- context 'after checking out another tag' do
65
- let(:other_tag) { '1.0.2' }
66
- before do
67
- hg.checkout(repo, other_tag)
68
- Dir.chdir repo_path do
69
- shell_out "echo 'uncommitted change' >> content_file"
70
- end
71
- end
72
-
73
- it_behaves_like 'able to checkout hg rev'
74
- end
75
- end
76
-
77
- context 'with branches' do
78
- let(:rev) { 'topic' }
79
-
80
- it_behaves_like 'able to checkout hg rev', 'topic'
81
-
82
- context 'after checking out another branch' do
83
- let(:other_branch) { 'next_topic' }
84
- before do
85
- hg.checkout(repo, other_branch)
86
- Dir.chdir repo_path do
87
- shell_out "echo 'uncommitted change' >> content_file"
88
- end
89
- end
90
-
91
- it_behaves_like 'able to checkout hg rev', 'topic'
92
- end
93
- end
94
- end
95
-
96
- describe '::rev_parse' do
97
- let(:repo_path) { clone_path('nginx') }
98
-
99
- before(:each) do
100
- origin_uri = mercurial_origin_for('nginx', tags: ['1.1.1'])
101
- described_class.clone(origin_uri, repo_path)
102
- described_class.checkout(repo_path, id_for_rev('nginx', '1.1.1'))
103
- end
104
-
105
- it 'returns the ref for HEAD' do
106
- rev = described_class.rev_parse(repo_path)
107
- ref = id_for_rev('nginx', '1.1.1')
108
-
109
- expect(rev).to eql(ref)
110
- end
111
- end
112
-
113
- let(:https_uri) { 'https://hghub.com/reset/' }
114
- let(:http_uri) { 'http://hghub.com/reset/' }
115
- let(:invalid_uri) { '/something/on/disk' }
116
-
117
- describe '::validate_uri' do
118
- context 'given an invalid URI' do
119
- it 'returns false' do
120
- expect(described_class.validate_uri(invalid_uri)).to be_false
121
- end
122
- end
123
-
124
- context 'given a HTTP URI' do
125
- it 'returns true' do
126
- expect(described_class.validate_uri(http_uri)).to be_true
127
- end
128
- end
129
-
130
- context 'given a valid HTTPS URI' do
131
- it 'returns true' do
132
- expect(described_class.validate_uri(https_uri)).to be_true
133
- end
134
- end
135
-
136
- context 'given an integer' do
137
- it 'returns false' do
138
- expect(described_class.validate_uri(123)).to be_false
139
- end
140
- end
141
- end
142
-
143
- describe '::validate_uri!' do
144
- context 'given an invalid URI' do
145
- it 'raises InvalidHgURI' do
146
- expect {
147
- described_class.validate_uri!(invalid_uri)
148
- }.to raise_error(Berkshelf::InvalidHgURI)
149
- end
150
- end
151
-
152
- context 'given a HTTP URI' do
153
- it 'raises InvalidHgURI' do
154
- expect(described_class.validate_uri!(http_uri)).to be_true
155
- end
156
- end
157
-
158
- context 'given a valid HTTPS URI' do
159
- it 'returns true' do
160
- expect(described_class.validate_uri!(https_uri)).to be_true
161
- end
162
- end
163
-
164
- context 'given an integer' do
165
- it 'raises InvalidHgURI' do
166
- expect {
167
- described_class.validate_uri!(123)
168
- }.to raise_error(Berkshelf::InvalidHgURI)
169
- end
170
- end
171
- end
172
- end