berkshelf 1.2.0.rc1 → 1.2.1
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/CHANGELOG.md +8 -0
- data/Gemfile +1 -1
- data/README.md +2 -0
- data/berkshelf.gemspec +4 -3
- data/features/step_definitions/filesystem_steps.rb +0 -1
- data/generator_files/Gemfile.erb +0 -3
- data/generator_files/Vagrantfile.erb +13 -1
- data/lib/berkshelf.rb +0 -1
- data/lib/berkshelf/berksfile.rb +11 -4
- data/lib/berkshelf/cached_cookbook.rb +2 -257
- data/lib/berkshelf/chef.rb +0 -1
- data/lib/berkshelf/chef/config.rb +3 -0
- data/lib/berkshelf/chef/cookbook.rb +0 -2
- data/lib/berkshelf/community_rest.rb +31 -6
- data/lib/berkshelf/cookbook_source.rb +5 -1
- data/lib/berkshelf/errors.rb +24 -0
- data/lib/berkshelf/git.rb +49 -1
- data/lib/berkshelf/init_generator.rb +1 -1
- data/lib/berkshelf/locations/chef_api_location.rb +6 -3
- data/lib/berkshelf/locations/path_location.rb +2 -0
- data/lib/berkshelf/version.rb +1 -1
- data/spec/spec_helper.rb +9 -2
- data/spec/support/chef_api.rb +1 -10
- data/spec/unit/berkshelf/cached_cookbook_spec.rb +37 -458
- data/spec/unit/berkshelf/git_spec.rb +119 -9
- data/spec/unit/berkshelf/init_generator_spec.rb +0 -1
- metadata +30 -24
- data/lib/berkshelf/chef/cookbook/metadata.rb +0 -556
- data/lib/berkshelf/chef/cookbook/syntax_check.rb +0 -158
- data/lib/berkshelf/chef/digester.rb +0 -67
- data/lib/berkshelf/mixin/checksum.rb +0 -16
- data/lib/berkshelf/mixin/params_validate.rb +0 -218
- data/lib/berkshelf/mixin/shell_out.rb +0 -23
- data/lib/berkshelf/uploader.rb +0 -80
- data/spec/unit/berkshelf/uploader_spec.rb +0 -27
- data/spec/unit/chef/cookbook/metadata_spec.rb +0 -5
- data/spec/unit/chef/digester_spec.rb +0 -41
@@ -3,6 +3,7 @@ require 'spec_helper'
|
|
3
3
|
describe Berkshelf::Git do
|
4
4
|
describe "ClassMethods" do
|
5
5
|
subject { Berkshelf::Git }
|
6
|
+
let(:git) { Berkshelf::Git }
|
6
7
|
|
7
8
|
describe "::find_git" do
|
8
9
|
it "should find git" do
|
@@ -33,16 +34,60 @@ describe Berkshelf::Git do
|
|
33
34
|
describe "::checkout" do
|
34
35
|
let(:repo_path) { clone_target_for('nginx') }
|
35
36
|
let(:repo) {
|
36
|
-
origin_uri = git_origin_for('nginx', tags: ['1.0.1'])
|
37
|
-
|
37
|
+
origin_uri = git_origin_for('nginx', tags: ['1.0.1', '1.0.2'], branches: ['topic', 'next_topic'])
|
38
|
+
git.clone(origin_uri, repo_path)
|
38
39
|
}
|
39
|
-
let(:tag) { "1.0.1" }
|
40
40
|
|
41
|
-
|
42
|
-
|
41
|
+
shared_examples "able to checkout git ref" do |test_ref|
|
42
|
+
it "checks out the specified ref of the given repository" do
|
43
|
+
git.checkout(repo, ref)
|
44
|
+
|
45
|
+
Dir.chdir repo_path do
|
46
|
+
test_ref ||= ref
|
47
|
+
%x[git rev-parse #{test_ref}].should == %x[git rev-parse HEAD]
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
context 'with sha commit id' do
|
53
|
+
let(:ref) { git_sha_for_ref('nginx', '1.0.1') }
|
54
|
+
|
55
|
+
it_behaves_like 'able to checkout git ref'
|
56
|
+
end
|
57
|
+
|
58
|
+
context 'with tags' do
|
59
|
+
let(:ref) { "1.0.1" }
|
60
|
+
|
61
|
+
it_behaves_like 'able to checkout git ref'
|
62
|
+
|
63
|
+
context 'after checking out another tag' do
|
64
|
+
let(:other_tag) { '1.0.2' }
|
65
|
+
before do
|
66
|
+
git.checkout(repo, other_tag)
|
67
|
+
Dir.chdir repo_path do
|
68
|
+
run! "echo 'uncommitted change' >> content_file"
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
it_behaves_like 'able to checkout git ref'
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
context 'with branches' do
|
77
|
+
let(:ref) { 'topic' }
|
43
78
|
|
44
|
-
|
45
|
-
|
79
|
+
it_behaves_like 'able to checkout git ref', 'origin/topic'
|
80
|
+
|
81
|
+
context 'after checking out another branch' do
|
82
|
+
let(:other_branch) { 'next_topic' }
|
83
|
+
before do
|
84
|
+
git.checkout(repo, other_branch)
|
85
|
+
Dir.chdir repo_path do
|
86
|
+
run! "echo 'uncommitted change' >> content_file"
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
it_behaves_like 'able to checkout git ref', 'origin/topic'
|
46
91
|
end
|
47
92
|
end
|
48
93
|
end
|
@@ -52,11 +97,76 @@ describe Berkshelf::Git do
|
|
52
97
|
before(:each) do |example|
|
53
98
|
origin_uri = git_origin_for('nginx', tags: ['1.1.1'])
|
54
99
|
subject.clone(origin_uri, repo_path)
|
55
|
-
subject.checkout(repo_path,
|
100
|
+
subject.checkout(repo_path, git_sha_for_ref('nginx', '1.1.1'))
|
56
101
|
end
|
57
102
|
|
58
103
|
it "returns the ref for HEAD" do
|
59
|
-
expect(subject.rev_parse(repo_path)).to eql(
|
104
|
+
expect(subject.rev_parse(repo_path)).to eql(git_sha_for_ref('nginx', '1.1.1'))
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
describe "::show_ref" do
|
109
|
+
let(:repo_path) { clone_target_for('nginx') }
|
110
|
+
let(:tags) { ['1.0.1'] }
|
111
|
+
let(:branches) { ['topic'] }
|
112
|
+
let!(:repo) {
|
113
|
+
origin_uri = git_origin_for('nginx', tags: tags, branches: branches)
|
114
|
+
git.clone(origin_uri, repo_path)
|
115
|
+
}
|
116
|
+
|
117
|
+
it 'returns the commit id for the given tag' do
|
118
|
+
git.show_ref(repo_path, '1.0.1').should == git_sha_for_ref('nginx', '1.0.1')
|
119
|
+
end
|
120
|
+
|
121
|
+
it 'returns the commit id for the given branch' do
|
122
|
+
git.show_ref(repo_path, 'topic').should == git_sha_for_ref('nginx', 'topic')
|
123
|
+
end
|
124
|
+
|
125
|
+
context 'with an ambiguous ref' do
|
126
|
+
let(:tags) { ['topic'] }
|
127
|
+
let(:branches) { ['topic'] }
|
128
|
+
|
129
|
+
it 'raises an error' do
|
130
|
+
expect {git.show_ref(repo_path, 'topic')}.to raise_error(Berkshelf::AmbiguousGitRef)
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
describe '::revision_from_ref' do
|
136
|
+
let(:repo_path) { clone_target_for('nginx') }
|
137
|
+
let(:tags) { ['1.0.1'] }
|
138
|
+
let(:branches) { ['topic'] }
|
139
|
+
let!(:repo) {
|
140
|
+
origin_uri = git_origin_for('nginx', tags: tags, branches: branches)
|
141
|
+
git.clone(origin_uri, repo_path)
|
142
|
+
}
|
143
|
+
|
144
|
+
context 'with sha commit id' do
|
145
|
+
let(:revision) { git_sha_for_ref('nginx', '1.0.1') }
|
146
|
+
it 'returns the passed revision' do
|
147
|
+
git.revision_from_ref(repo_path, revision).should == revision
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
context 'with tag' do
|
152
|
+
let(:revision) { git_sha_for_ref('nginx', '1.0.1') }
|
153
|
+
it 'returns the revision' do
|
154
|
+
git.revision_from_ref(repo_path, '1.0.1').should == revision
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
context 'with branch' do
|
159
|
+
let(:revision) { git_sha_for_ref('nginx', 'topic') }
|
160
|
+
it 'returns the revision' do
|
161
|
+
git.revision_from_ref(repo_path, 'topic').should == revision
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
165
|
+
context 'with an invalid ref' do
|
166
|
+
let(:ref) { 'foobar' }
|
167
|
+
it 'raises an error' do
|
168
|
+
expect { git.revision_from_ref(repo_path, ref) }.to raise_error(Berkshelf::InvalidGitRef)
|
169
|
+
end
|
60
170
|
end
|
61
171
|
end
|
62
172
|
|
metadata
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: berkshelf
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.2.
|
5
|
-
prerelease:
|
4
|
+
version: 1.2.1
|
5
|
+
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Jamie Winsor
|
@@ -12,7 +12,7 @@ authors:
|
|
12
12
|
autorequire:
|
13
13
|
bindir: bin
|
14
14
|
cert_chain: []
|
15
|
-
date: 2013-
|
15
|
+
date: 2013-03-07 00:00:00.000000000 Z
|
16
16
|
dependencies:
|
17
17
|
- !ruby/object:Gem::Dependency
|
18
18
|
name: yajl-ruby
|
@@ -101,7 +101,7 @@ dependencies:
|
|
101
101
|
requirements:
|
102
102
|
- - ! '>='
|
103
103
|
- !ruby/object:Gem::Version
|
104
|
-
version: 0.
|
104
|
+
version: 0.8.3
|
105
105
|
type: :runtime
|
106
106
|
prerelease: false
|
107
107
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -109,7 +109,7 @@ dependencies:
|
|
109
109
|
requirements:
|
110
110
|
- - ! '>='
|
111
111
|
- !ruby/object:Gem::Version
|
112
|
-
version: 0.
|
112
|
+
version: 0.8.3
|
113
113
|
- !ruby/object:Gem::Dependency
|
114
114
|
name: chozo
|
115
115
|
requirement: !ruby/object:Gem::Requirement
|
@@ -117,7 +117,7 @@ dependencies:
|
|
117
117
|
requirements:
|
118
118
|
- - ! '>='
|
119
119
|
- !ruby/object:Gem::Version
|
120
|
-
version: 0.
|
120
|
+
version: 0.6.1
|
121
121
|
type: :runtime
|
122
122
|
prerelease: false
|
123
123
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -125,7 +125,7 @@ dependencies:
|
|
125
125
|
requirements:
|
126
126
|
- - ! '>='
|
127
127
|
- !ruby/object:Gem::Version
|
128
|
-
version: 0.
|
128
|
+
version: 0.6.1
|
129
129
|
- !ruby/object:Gem::Dependency
|
130
130
|
name: hashie
|
131
131
|
requirement: !ruby/object:Gem::Requirement
|
@@ -133,7 +133,7 @@ dependencies:
|
|
133
133
|
requirements:
|
134
134
|
- - ! '>='
|
135
135
|
- !ruby/object:Gem::Version
|
136
|
-
version:
|
136
|
+
version: 2.0.2
|
137
137
|
type: :runtime
|
138
138
|
prerelease: false
|
139
139
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -141,7 +141,7 @@ dependencies:
|
|
141
141
|
requirements:
|
142
142
|
- - ! '>='
|
143
143
|
- !ruby/object:Gem::Version
|
144
|
-
version:
|
144
|
+
version: 2.0.2
|
145
145
|
- !ruby/object:Gem::Dependency
|
146
146
|
name: minitar
|
147
147
|
requirement: !ruby/object:Gem::Requirement
|
@@ -222,6 +222,22 @@ dependencies:
|
|
222
222
|
- - ~>
|
223
223
|
- !ruby/object:Gem::Version
|
224
224
|
version: 0.16.0
|
225
|
+
- !ruby/object:Gem::Dependency
|
226
|
+
name: retryable
|
227
|
+
requirement: !ruby/object:Gem::Requirement
|
228
|
+
none: false
|
229
|
+
requirements:
|
230
|
+
- - ! '>='
|
231
|
+
- !ruby/object:Gem::Version
|
232
|
+
version: '0'
|
233
|
+
type: :runtime
|
234
|
+
prerelease: false
|
235
|
+
version_requirements: !ruby/object:Gem::Requirement
|
236
|
+
none: false
|
237
|
+
requirements:
|
238
|
+
- - ! '>='
|
239
|
+
- !ruby/object:Gem::Version
|
240
|
+
version: '0'
|
225
241
|
- !ruby/object:Gem::Dependency
|
226
242
|
name: moneta
|
227
243
|
requirement: !ruby/object:Gem::Requirement
|
@@ -487,9 +503,6 @@ files:
|
|
487
503
|
- lib/berkshelf/chef/config.rb
|
488
504
|
- lib/berkshelf/chef/cookbook.rb
|
489
505
|
- lib/berkshelf/chef/cookbook/chefignore.rb
|
490
|
-
- lib/berkshelf/chef/cookbook/metadata.rb
|
491
|
-
- lib/berkshelf/chef/cookbook/syntax_check.rb
|
492
|
-
- lib/berkshelf/chef/digester.rb
|
493
506
|
- lib/berkshelf/cli.rb
|
494
507
|
- lib/berkshelf/command.rb
|
495
508
|
- lib/berkshelf/community_rest.rb
|
@@ -517,14 +530,10 @@ files:
|
|
517
530
|
- lib/berkshelf/locations/site_location.rb
|
518
531
|
- lib/berkshelf/lockfile.rb
|
519
532
|
- lib/berkshelf/mixin.rb
|
520
|
-
- lib/berkshelf/mixin/checksum.rb
|
521
|
-
- lib/berkshelf/mixin/params_validate.rb
|
522
533
|
- lib/berkshelf/mixin/path_helpers.rb
|
523
|
-
- lib/berkshelf/mixin/shell_out.rb
|
524
534
|
- lib/berkshelf/resolver.rb
|
525
535
|
- lib/berkshelf/thor.rb
|
526
536
|
- lib/berkshelf/ui.rb
|
527
|
-
- lib/berkshelf/uploader.rb
|
528
537
|
- lib/berkshelf/vagrant.rb
|
529
538
|
- lib/berkshelf/vagrant/action/clean.rb
|
530
539
|
- lib/berkshelf/vagrant/action/install.rb
|
@@ -592,11 +601,8 @@ files:
|
|
592
601
|
- spec/unit/berkshelf/lockfile_spec.rb
|
593
602
|
- spec/unit/berkshelf/resolver_spec.rb
|
594
603
|
- spec/unit/berkshelf/ui_spec.rb
|
595
|
-
- spec/unit/berkshelf/uploader_spec.rb
|
596
604
|
- spec/unit/berkshelf_spec.rb
|
597
605
|
- spec/unit/chef/config_spec.rb
|
598
|
-
- spec/unit/chef/cookbook/metadata_spec.rb
|
599
|
-
- spec/unit/chef/digester_spec.rb
|
600
606
|
homepage: http://berkshelf.com
|
601
607
|
licenses:
|
602
608
|
- Apache 2.0
|
@@ -613,9 +619,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
613
619
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
614
620
|
none: false
|
615
621
|
requirements:
|
616
|
-
- - ! '
|
622
|
+
- - ! '>='
|
617
623
|
- !ruby/object:Gem::Version
|
618
|
-
version:
|
624
|
+
version: '0'
|
625
|
+
segments:
|
626
|
+
- 0
|
627
|
+
hash: -3254137740807236813
|
619
628
|
requirements: []
|
620
629
|
rubyforge_project:
|
621
630
|
rubygems_version: 1.8.24
|
@@ -702,9 +711,6 @@ test_files:
|
|
702
711
|
- spec/unit/berkshelf/lockfile_spec.rb
|
703
712
|
- spec/unit/berkshelf/resolver_spec.rb
|
704
713
|
- spec/unit/berkshelf/ui_spec.rb
|
705
|
-
- spec/unit/berkshelf/uploader_spec.rb
|
706
714
|
- spec/unit/berkshelf_spec.rb
|
707
715
|
- spec/unit/chef/config_spec.rb
|
708
|
-
- spec/unit/chef/cookbook/metadata_spec.rb
|
709
|
-
- spec/unit/chef/digester_spec.rb
|
710
716
|
has_rdoc:
|
@@ -1,556 +0,0 @@
|
|
1
|
-
module Berkshelf::Chef::Cookbook
|
2
|
-
# @author Jamie Winsor <reset@riotgames.com>
|
3
|
-
#
|
4
|
-
# Borrowed and modified from: {https://raw.github.com/opscode/chef/11.4.0/lib/chef/cookbook/metadata.rb}
|
5
|
-
#
|
6
|
-
# Copyright:: Copyright 2008-2010 Opscode, Inc.
|
7
|
-
#
|
8
|
-
# Licensed under the Apache License, Version 2.0 (the "License");
|
9
|
-
# you may not use this file except in compliance with the License.
|
10
|
-
# You may obtain a copy of the License at
|
11
|
-
#
|
12
|
-
# http://www.apache.org/licenses/LICENSE-2.0
|
13
|
-
#
|
14
|
-
# Unless required by applicable law or agreed to in writing, software
|
15
|
-
# distributed under the License is distributed on an "AS IS" BASIS,
|
16
|
-
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
17
|
-
# See the License for the specific language governing permissions and
|
18
|
-
# limitations under the License.
|
19
|
-
#
|
20
|
-
# == Chef::Cookbook::Metadata
|
21
|
-
# Chef::Cookbook::Metadata provides a convenient DSL for declaring metadata
|
22
|
-
# about Chef Cookbooks.
|
23
|
-
class Metadata
|
24
|
-
class << self
|
25
|
-
def from_hash(hash)
|
26
|
-
new.from_hash(hash)
|
27
|
-
end
|
28
|
-
end
|
29
|
-
|
30
|
-
NAME = 'name'.freeze
|
31
|
-
DESCRIPTION = 'description'.freeze
|
32
|
-
LONG_DESCRIPTION = 'long_description'.freeze
|
33
|
-
MAINTAINER = 'maintainer'.freeze
|
34
|
-
MAINTAINER_EMAIL = 'maintainer_email'.freeze
|
35
|
-
LICENSE = 'license'.freeze
|
36
|
-
PLATFORMS = 'platforms'.freeze
|
37
|
-
DEPENDENCIES = 'dependencies'.freeze
|
38
|
-
RECOMMENDATIONS = 'recommendations'.freeze
|
39
|
-
SUGGESTIONS = 'suggestions'.freeze
|
40
|
-
CONFLICTING = 'conflicting'.freeze
|
41
|
-
PROVIDING = 'providing'.freeze
|
42
|
-
REPLACING = 'replacing'.freeze
|
43
|
-
ATTRIBUTES = 'attributes'.freeze
|
44
|
-
GROUPINGS = 'groupings'.freeze
|
45
|
-
RECIPES = 'recipes'.freeze
|
46
|
-
VERSION = 'version'.freeze
|
47
|
-
|
48
|
-
COMPARISON_FIELDS = [
|
49
|
-
:name, :description, :long_description, :maintainer,
|
50
|
-
:maintainer_email, :license, :platforms, :dependencies,
|
51
|
-
:recommendations, :suggestions, :conflicting, :providing,
|
52
|
-
:replacing, :attributes, :groupings, :recipes, :version
|
53
|
-
]
|
54
|
-
|
55
|
-
include Berkshelf::Mixin::ParamsValidate
|
56
|
-
include Chozo::Mixin::FromFile
|
57
|
-
|
58
|
-
attr_reader :cookbook
|
59
|
-
attr_reader :platforms
|
60
|
-
attr_reader :dependencies
|
61
|
-
attr_reader :recommendations
|
62
|
-
attr_reader :suggestions
|
63
|
-
attr_reader :conflicting
|
64
|
-
attr_reader :providing
|
65
|
-
attr_reader :replacing
|
66
|
-
attr_reader :attributes
|
67
|
-
attr_reader :groupings
|
68
|
-
attr_reader :recipes
|
69
|
-
attr_reader :version
|
70
|
-
|
71
|
-
# Builds a new Chef::Cookbook::Metadata object.
|
72
|
-
#
|
73
|
-
# === Parameters
|
74
|
-
# cookbook<String>:: An optional cookbook object
|
75
|
-
# maintainer<String>:: An optional maintainer
|
76
|
-
# maintainer_email<String>:: An optional maintainer email
|
77
|
-
# license<String>::An optional license. Default is Apache v2.0
|
78
|
-
#
|
79
|
-
# === Returns
|
80
|
-
# metadata<Chef::Cookbook::Metadata>
|
81
|
-
def initialize(cookbook = nil, maintainer = 'YOUR_COMPANY_NAME', maintainer_email = 'YOUR_EMAIL', license = 'none')
|
82
|
-
@cookbook = cookbook
|
83
|
-
@name = cookbook ? cookbook.name : ""
|
84
|
-
@long_description = ""
|
85
|
-
self.maintainer(maintainer)
|
86
|
-
self.maintainer_email(maintainer_email)
|
87
|
-
self.license(license)
|
88
|
-
self.description('A fabulous new cookbook')
|
89
|
-
@platforms = Hashie::Mash.new
|
90
|
-
@dependencies = Hashie::Mash.new
|
91
|
-
@recommendations = Hashie::Mash.new
|
92
|
-
@suggestions = Hashie::Mash.new
|
93
|
-
@conflicting = Hashie::Mash.new
|
94
|
-
@providing = Hashie::Mash.new
|
95
|
-
@replacing = Hashie::Mash.new
|
96
|
-
@attributes = Hashie::Mash.new
|
97
|
-
@groupings = Hashie::Mash.new
|
98
|
-
@recipes = Hashie::Mash.new
|
99
|
-
@version = Solve::Version.new("0.0.0")
|
100
|
-
if cookbook
|
101
|
-
@recipes = cookbook.fully_qualified_recipe_names.inject({}) do |r, e|
|
102
|
-
e = self.name if e =~ /::default$/
|
103
|
-
r[e] = ""
|
104
|
-
self.provides e
|
105
|
-
r
|
106
|
-
end
|
107
|
-
end
|
108
|
-
end
|
109
|
-
|
110
|
-
def ==(other)
|
111
|
-
COMPARISON_FIELDS.inject(true) do |equal_so_far, field|
|
112
|
-
equal_so_far && other.respond_to?(field) && (other.send(field) == send(field))
|
113
|
-
end
|
114
|
-
end
|
115
|
-
|
116
|
-
# Sets the cookbooks maintainer, or returns it.
|
117
|
-
#
|
118
|
-
# === Parameters
|
119
|
-
# maintainer<String>:: The maintainers name
|
120
|
-
#
|
121
|
-
# === Returns
|
122
|
-
# maintainer<String>:: Returns the current maintainer.
|
123
|
-
def maintainer(arg = nil)
|
124
|
-
set_or_return(
|
125
|
-
:maintainer,
|
126
|
-
arg,
|
127
|
-
:kind_of => [ String ]
|
128
|
-
)
|
129
|
-
end
|
130
|
-
|
131
|
-
# Sets the maintainers email address, or returns it.
|
132
|
-
#
|
133
|
-
# === Parameters
|
134
|
-
# maintainer_email<String>:: The maintainers email address
|
135
|
-
#
|
136
|
-
# === Returns
|
137
|
-
# maintainer_email<String>:: Returns the current maintainer email.
|
138
|
-
def maintainer_email(arg = nil)
|
139
|
-
set_or_return(
|
140
|
-
:maintainer_email,
|
141
|
-
arg,
|
142
|
-
:kind_of => [ String ]
|
143
|
-
)
|
144
|
-
end
|
145
|
-
|
146
|
-
# Sets the current license, or returns it.
|
147
|
-
#
|
148
|
-
# === Parameters
|
149
|
-
# license<String>:: The current license.
|
150
|
-
#
|
151
|
-
# === Returns
|
152
|
-
# license<String>:: Returns the current license
|
153
|
-
def license(arg = nil)
|
154
|
-
set_or_return(
|
155
|
-
:license,
|
156
|
-
arg,
|
157
|
-
:kind_of => [ String ]
|
158
|
-
)
|
159
|
-
end
|
160
|
-
|
161
|
-
# Sets the current description, or returns it. Should be short - one line only!
|
162
|
-
#
|
163
|
-
# === Parameters
|
164
|
-
# description<String>:: The new description
|
165
|
-
#
|
166
|
-
# === Returns
|
167
|
-
# description<String>:: Returns the description
|
168
|
-
def description(arg = nil)
|
169
|
-
set_or_return(
|
170
|
-
:description,
|
171
|
-
arg,
|
172
|
-
:kind_of => [ String ]
|
173
|
-
)
|
174
|
-
end
|
175
|
-
|
176
|
-
# Sets the current long description, or returns it. Might come from a README, say.
|
177
|
-
#
|
178
|
-
# === Parameters
|
179
|
-
# long_description<String>:: The new long description
|
180
|
-
#
|
181
|
-
# === Returns
|
182
|
-
# long_description<String>:: Returns the long description
|
183
|
-
def long_description(arg = nil)
|
184
|
-
set_or_return(
|
185
|
-
:long_description,
|
186
|
-
arg,
|
187
|
-
:kind_of => [ String ]
|
188
|
-
)
|
189
|
-
end
|
190
|
-
|
191
|
-
# Sets the current cookbook version, or returns it. Can be two or three digits, seperated
|
192
|
-
# by dots. ie: '2.1', '1.5.4' or '0.9'.
|
193
|
-
#
|
194
|
-
# === Parameters
|
195
|
-
# version<String>:: The curent version, as a string
|
196
|
-
#
|
197
|
-
# === Returns
|
198
|
-
# version<String>:: Returns the current version
|
199
|
-
def version(arg = nil)
|
200
|
-
if arg
|
201
|
-
@version = Solve::Version.new(arg)
|
202
|
-
end
|
203
|
-
|
204
|
-
@version.to_s
|
205
|
-
end
|
206
|
-
|
207
|
-
# Sets the name of the cookbook, or returns it.
|
208
|
-
#
|
209
|
-
# === Parameters
|
210
|
-
# name<String>:: The curent cookbook name.
|
211
|
-
#
|
212
|
-
# === Returns
|
213
|
-
# name<String>:: Returns the current cookbook name.
|
214
|
-
def name(arg = nil)
|
215
|
-
set_or_return(
|
216
|
-
:name,
|
217
|
-
arg,
|
218
|
-
:kind_of => [ String ]
|
219
|
-
)
|
220
|
-
end
|
221
|
-
|
222
|
-
# Adds a supported platform, with version checking strings.
|
223
|
-
#
|
224
|
-
# === Parameters
|
225
|
-
# platform<String>,<Symbol>:: The platform (like :ubuntu or :mac_os_x)
|
226
|
-
# version<String>:: A version constraint of the form "OP VERSION",
|
227
|
-
# where OP is one of < <= = > >= ~> and VERSION has
|
228
|
-
# the form x.y.z or x.y.
|
229
|
-
#
|
230
|
-
# === Returns
|
231
|
-
# versions<Array>:: Returns the list of versions for the platform
|
232
|
-
def supports(platform, *version_args)
|
233
|
-
version = version_args.first
|
234
|
-
@platforms[platform] = Solve::Constraint.new(version).to_s
|
235
|
-
@platforms[platform]
|
236
|
-
rescue Solve::Errors::InvalidConstraintFormat => ex
|
237
|
-
raise InvalidVersionConstraint, ex.to_s
|
238
|
-
end
|
239
|
-
|
240
|
-
# Adds a dependency on another cookbook, with version checking strings.
|
241
|
-
#
|
242
|
-
# === Parameters
|
243
|
-
# cookbook<String>:: The cookbook
|
244
|
-
# version<String>:: A version constraint of the form "OP VERSION",
|
245
|
-
# where OP is one of < <= = > >= ~> and VERSION has
|
246
|
-
# the form x.y.z or x.y.
|
247
|
-
#
|
248
|
-
# === Returns
|
249
|
-
# versions<Array>:: Returns the list of versions for the platform
|
250
|
-
def depends(cookbook, *version_args)
|
251
|
-
version = version_args.first
|
252
|
-
@dependencies[cookbook] = Solve::Constraint.new(version).to_s
|
253
|
-
@dependencies[cookbook]
|
254
|
-
rescue Solve::Errors::InvalidConstraintFormat => ex
|
255
|
-
raise InvalidVersionConstraint, ex.to_s
|
256
|
-
end
|
257
|
-
|
258
|
-
# Adds a recommendation for another cookbook, with version checking strings.
|
259
|
-
#
|
260
|
-
# === Parameters
|
261
|
-
# cookbook<String>:: The cookbook
|
262
|
-
# version<String>:: A version constraint of the form "OP VERSION",
|
263
|
-
# where OP is one of < <= = > >= ~> and VERSION has
|
264
|
-
# the form x.y.z or x.y.
|
265
|
-
#
|
266
|
-
# === Returns
|
267
|
-
# versions<Array>:: Returns the list of versions for the platform
|
268
|
-
def recommends(cookbook, *version_args)
|
269
|
-
version = version_args.first
|
270
|
-
@recommendations[cookbook] = Solve::Constraint.new(version).to_s
|
271
|
-
@recommendations[cookbook]
|
272
|
-
rescue Solve::Errors::InvalidConstraintFormat => ex
|
273
|
-
raise InvalidVersionConstraint, ex.to_s
|
274
|
-
end
|
275
|
-
|
276
|
-
# Adds a suggestion for another cookbook, with version checking strings.
|
277
|
-
#
|
278
|
-
# === Parameters
|
279
|
-
# cookbook<String>:: The cookbook
|
280
|
-
# version<String>:: A version constraint of the form "OP VERSION",
|
281
|
-
# where OP is one of < <= = > >= ~> and VERSION has the
|
282
|
-
# formx.y.z or x.y.
|
283
|
-
#
|
284
|
-
# === Returns
|
285
|
-
# versions<Array>:: Returns the list of versions for the platform
|
286
|
-
def suggests(cookbook, *version_args)
|
287
|
-
version = version_args.first
|
288
|
-
@suggestions[cookbook] = Solve::Constraint.new(version).to_s
|
289
|
-
@suggestions[cookbook]
|
290
|
-
rescue Solve::Errors::InvalidConstraintFormat => ex
|
291
|
-
raise InvalidVersionConstraint, ex.to_s
|
292
|
-
end
|
293
|
-
|
294
|
-
# Adds a conflict for another cookbook, with version checking strings.
|
295
|
-
#
|
296
|
-
# === Parameters
|
297
|
-
# cookbook<String>:: The cookbook
|
298
|
-
# version<String>:: A version constraint of the form "OP VERSION",
|
299
|
-
# where OP is one of < <= = > >= ~> and VERSION has
|
300
|
-
# the form x.y.z or x.y.
|
301
|
-
#
|
302
|
-
# === Returns
|
303
|
-
# versions<Array>:: Returns the list of versions for the platform
|
304
|
-
def conflicts(cookbook, *version_args)
|
305
|
-
version = version_args.first
|
306
|
-
@conflicting[cookbook] = Solve::Constraint.new(version).to_s
|
307
|
-
@conflicting[cookbook]
|
308
|
-
rescue Solve::Errors::InvalidConstraintFormat => ex
|
309
|
-
raise InvalidVersionConstraint, ex.to_s
|
310
|
-
end
|
311
|
-
|
312
|
-
# Adds a recipe, definition, or resource provided by this cookbook.
|
313
|
-
#
|
314
|
-
# Recipes are specified as normal
|
315
|
-
# Definitions are followed by (), and can include :params for prototyping
|
316
|
-
# Resources are the stringified version (service[apache2])
|
317
|
-
#
|
318
|
-
# === Parameters
|
319
|
-
# recipe, definition, resource<String>:: The thing we provide
|
320
|
-
# version<String>:: A version constraint of the form "OP VERSION",
|
321
|
-
# where OP is one of < <= = > >= ~> and VERSION has
|
322
|
-
# the form x.y.z or x.y.
|
323
|
-
#
|
324
|
-
# === Returns
|
325
|
-
# versions<Array>:: Returns the list of versions for the platform
|
326
|
-
def provides(cookbook, *version_args)
|
327
|
-
version = version_args.first
|
328
|
-
@providing[cookbook] = Solve::Constraint.new(version).to_s
|
329
|
-
@providing[cookbook]
|
330
|
-
rescue Solve::Errors::InvalidConstraintFormat => ex
|
331
|
-
raise InvalidVersionConstraint, ex.to_s
|
332
|
-
end
|
333
|
-
|
334
|
-
# Adds a cookbook that is replaced by this one, with version checking strings.
|
335
|
-
#
|
336
|
-
# === Parameters
|
337
|
-
# cookbook<String>:: The cookbook we replace
|
338
|
-
# version<String>:: A version constraint of the form "OP VERSION",
|
339
|
-
# where OP is one of < <= = > >= ~> and VERSION has the form x.y.z or x.y.
|
340
|
-
#
|
341
|
-
# === Returns
|
342
|
-
# versions<Array>:: Returns the list of versions for the platform
|
343
|
-
def replaces(cookbook, *version_args)
|
344
|
-
version = version_args.first
|
345
|
-
@replacing[cookbook] = Solve::Constraint.new(version).to_s
|
346
|
-
@replacing[cookbook]
|
347
|
-
rescue Solve::Errors::InvalidConstraintFormat => ex
|
348
|
-
raise InvalidVersionConstraint, ex.to_s
|
349
|
-
end
|
350
|
-
|
351
|
-
# Adds a description for a recipe.
|
352
|
-
#
|
353
|
-
# === Parameters
|
354
|
-
# recipe<String>:: The recipe
|
355
|
-
# description<String>:: The description of the recipe
|
356
|
-
#
|
357
|
-
# === Returns
|
358
|
-
# description<String>:: Returns the current description
|
359
|
-
def recipe(name, description)
|
360
|
-
@recipes[name] = description
|
361
|
-
end
|
362
|
-
|
363
|
-
# Adds an attribute )hat a user needs to configure for this cookbook. Takes
|
364
|
-
# a name (with the / notation for a nested attribute), followed by any of
|
365
|
-
# these options
|
366
|
-
#
|
367
|
-
# display_name<String>:: What a UI should show for this attribute
|
368
|
-
# description<String>:: A hint as to what this attr is for
|
369
|
-
# choice<Array>:: An array of choices to present to the user.
|
370
|
-
# calculated<Boolean>:: If true, the default value is calculated by the recipe and cannot be displayed.
|
371
|
-
# type<String>:: "string" or "array" - default is "string" ("hash" is supported for backwards compatibility)
|
372
|
-
# required<String>:: Whether this attr is 'required', 'recommended' or 'optional' - default 'optional' (true/false values also supported for backwards compatibility)
|
373
|
-
# recipes<Array>:: An array of recipes which need this attr set.
|
374
|
-
# default<String>,<Array>,<Hash>:: The default value
|
375
|
-
#
|
376
|
-
# === Parameters
|
377
|
-
# name<String>:: The name of the attribute ('foo', or 'apache2/log_dir')
|
378
|
-
# options<Hash>:: The description of the options
|
379
|
-
#
|
380
|
-
# === Returns
|
381
|
-
# options<Hash>:: Returns the current options hash
|
382
|
-
def attribute(name, options)
|
383
|
-
validate(
|
384
|
-
options,
|
385
|
-
{
|
386
|
-
:display_name => { :kind_of => String },
|
387
|
-
:description => { :kind_of => String },
|
388
|
-
:choice => { :kind_of => [ Array ], :default => [] },
|
389
|
-
:calculated => { :equal_to => [ true, false ], :default => false },
|
390
|
-
:type => { :equal_to => [ "string", "array", "hash", "symbol" ], :default => "string" },
|
391
|
-
:required => { :equal_to => [ "required", "recommended", "optional", true, false ], :default => "optional" },
|
392
|
-
:recipes => { :kind_of => [ Array ], :default => [] },
|
393
|
-
:default => { :kind_of => [ String, Array, Hash ] }
|
394
|
-
}
|
395
|
-
)
|
396
|
-
options[:required] = remap_required_attribute(options[:required]) unless options[:required].nil?
|
397
|
-
validate_string_array(options[:choice])
|
398
|
-
validate_calculated_default_rule(options)
|
399
|
-
validate_choice_default_rule(options)
|
400
|
-
|
401
|
-
@attributes[name] = options
|
402
|
-
@attributes[name]
|
403
|
-
end
|
404
|
-
|
405
|
-
def grouping(name, options)
|
406
|
-
validate(
|
407
|
-
options,
|
408
|
-
{
|
409
|
-
:title => { :kind_of => String },
|
410
|
-
:description => { :kind_of => String }
|
411
|
-
}
|
412
|
-
)
|
413
|
-
@groupings[name] = options
|
414
|
-
@groupings[name]
|
415
|
-
end
|
416
|
-
|
417
|
-
def to_hash
|
418
|
-
{
|
419
|
-
NAME => self.name,
|
420
|
-
DESCRIPTION => self.description,
|
421
|
-
LONG_DESCRIPTION => self.long_description,
|
422
|
-
MAINTAINER => self.maintainer,
|
423
|
-
MAINTAINER_EMAIL => self.maintainer_email,
|
424
|
-
LICENSE => self.license,
|
425
|
-
PLATFORMS => self.platforms,
|
426
|
-
DEPENDENCIES => self.dependencies,
|
427
|
-
RECOMMENDATIONS => self.recommendations,
|
428
|
-
SUGGESTIONS => self.suggestions,
|
429
|
-
CONFLICTING => self.conflicting,
|
430
|
-
PROVIDING => self.providing,
|
431
|
-
REPLACING => self.replacing,
|
432
|
-
ATTRIBUTES => self.attributes,
|
433
|
-
GROUPINGS => self.groupings,
|
434
|
-
RECIPES => self.recipes,
|
435
|
-
VERSION => self.version
|
436
|
-
}
|
437
|
-
end
|
438
|
-
|
439
|
-
def from_hash(o)
|
440
|
-
@name = o[NAME] if o.has_key?(NAME)
|
441
|
-
@description = o[DESCRIPTION] if o.has_key?(DESCRIPTION)
|
442
|
-
@long_description = o[LONG_DESCRIPTION] if o.has_key?(LONG_DESCRIPTION)
|
443
|
-
@maintainer = o[MAINTAINER] if o.has_key?(MAINTAINER)
|
444
|
-
@maintainer_email = o[MAINTAINER_EMAIL] if o.has_key?(MAINTAINER_EMAIL)
|
445
|
-
@license = o[LICENSE] if o.has_key?(LICENSE)
|
446
|
-
@platforms = o[PLATFORMS] if o.has_key?(PLATFORMS)
|
447
|
-
@dependencies = handle_deprecated_constraints(o[DEPENDENCIES]) if o.has_key?(DEPENDENCIES)
|
448
|
-
@recommendations = handle_deprecated_constraints(o[RECOMMENDATIONS]) if o.has_key?(RECOMMENDATIONS)
|
449
|
-
@suggestions = handle_deprecated_constraints(o[SUGGESTIONS]) if o.has_key?(SUGGESTIONS)
|
450
|
-
@conflicting = handle_deprecated_constraints(o[CONFLICTING]) if o.has_key?(CONFLICTING)
|
451
|
-
@providing = o[PROVIDING] if o.has_key?(PROVIDING)
|
452
|
-
@replacing = handle_deprecated_constraints(o[REPLACING]) if o.has_key?(REPLACING)
|
453
|
-
@attributes = o[ATTRIBUTES] if o.has_key?(ATTRIBUTES)
|
454
|
-
@groupings = o[GROUPINGS] if o.has_key?(GROUPINGS)
|
455
|
-
@recipes = o[RECIPES] if o.has_key?(RECIPES)
|
456
|
-
@version = o[VERSION] if o.has_key?(VERSION)
|
457
|
-
self
|
458
|
-
end
|
459
|
-
|
460
|
-
def from_file(filepath)
|
461
|
-
super
|
462
|
-
rescue IOError => ex
|
463
|
-
raise Berkshelf::CookbookNotFound, ex.to_s
|
464
|
-
end
|
465
|
-
|
466
|
-
private
|
467
|
-
|
468
|
-
# Verify that the given array is an array of strings
|
469
|
-
#
|
470
|
-
# Raise an exception if the members of the array are not Strings
|
471
|
-
#
|
472
|
-
# === Parameters
|
473
|
-
# arry<Array>:: An array to be validated
|
474
|
-
def validate_string_array(arry)
|
475
|
-
if arry.kind_of?(Array)
|
476
|
-
arry.each do |choice|
|
477
|
-
validate( {:choice => choice}, {:choice => {:kind_of => String}} )
|
478
|
-
end
|
479
|
-
end
|
480
|
-
end
|
481
|
-
|
482
|
-
# For backwards compatibility, remap Boolean values to String
|
483
|
-
# true is mapped to "required"
|
484
|
-
# false is mapped to "optional"
|
485
|
-
#
|
486
|
-
# === Parameters
|
487
|
-
# required_attr<String><Boolean>:: The value of options[:required]
|
488
|
-
#
|
489
|
-
# === Returns
|
490
|
-
# required_attr<String>:: "required", "recommended", or "optional"
|
491
|
-
def remap_required_attribute(value)
|
492
|
-
case value
|
493
|
-
when true
|
494
|
-
value = "required"
|
495
|
-
when false
|
496
|
-
value = "optional"
|
497
|
-
end
|
498
|
-
value
|
499
|
-
end
|
500
|
-
|
501
|
-
def validate_calculated_default_rule(options)
|
502
|
-
calculated_conflict = ((options[:default].is_a?(Array) && !options[:default].empty?) ||
|
503
|
-
(options[:default].is_a?(String) && !options[:default] != "")) &&
|
504
|
-
options[:calculated] == true
|
505
|
-
raise ArgumentError, "Default cannot be specified if calculated is true!" if calculated_conflict
|
506
|
-
end
|
507
|
-
|
508
|
-
def validate_choice_default_rule(options)
|
509
|
-
return if !options[:choice].is_a?(Array) || options[:choice].empty?
|
510
|
-
|
511
|
-
if options[:default].is_a?(String) && options[:default] != ""
|
512
|
-
raise ArgumentError, "Default must be one of your choice values!" if options[:choice].index(options[:default]) == nil
|
513
|
-
end
|
514
|
-
|
515
|
-
if options[:default].is_a?(Array) && !options[:default].empty?
|
516
|
-
options[:default].each do |val|
|
517
|
-
raise ArgumentError, "Default values must be a subset of your choice values!" if options[:choice].index(val) == nil
|
518
|
-
end
|
519
|
-
end
|
520
|
-
end
|
521
|
-
|
522
|
-
# This method translates version constraint strings from
|
523
|
-
# cookbooks with the old format.
|
524
|
-
#
|
525
|
-
# Before we began respecting version constraints, we allowed
|
526
|
-
# multiple constraints to be placed on cookbooks, as well as the
|
527
|
-
# << and >> operators, which are now just < and >. For
|
528
|
-
# specifications with more than one constraint, we return an
|
529
|
-
# empty array (otherwise, we're silently abiding only part of
|
530
|
-
# the contract they have specified to us). If there is only one
|
531
|
-
# constraint, we are replacing the old << and >> with the new <
|
532
|
-
# and >.
|
533
|
-
def handle_deprecated_constraints(specification)
|
534
|
-
specification.inject(Hashie::Mash.new) do |acc, (cb, constraints)|
|
535
|
-
constraints = Array(constraints)
|
536
|
-
acc[cb] = (constraints.empty? || constraints.size > 1) ? [] : constraints.first.gsub(/>>/, '>').gsub(/<</, '<')
|
537
|
-
acc
|
538
|
-
end
|
539
|
-
end
|
540
|
-
end
|
541
|
-
|
542
|
-
#== Chef::Cookbook::MinimalMetadata
|
543
|
-
# MinimalMetadata is a duck type of Cookbook::Metadata, used
|
544
|
-
# internally by Chef Server when determining the optimal set of
|
545
|
-
# cookbooks for a node.
|
546
|
-
#
|
547
|
-
# MinimalMetadata objects typically contain only enough information
|
548
|
-
# to solve the cookbook collection for a run list, but not enough to
|
549
|
-
# generate the proper response
|
550
|
-
class MinimalMetadata < Metadata
|
551
|
-
def initialize(name, params)
|
552
|
-
@name = name
|
553
|
-
from_hash(params)
|
554
|
-
end
|
555
|
-
end
|
556
|
-
end
|