berkshelf 1.2.0.rc1 → 1.2.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (37) hide show
  1. data/CHANGELOG.md +8 -0
  2. data/Gemfile +1 -1
  3. data/README.md +2 -0
  4. data/berkshelf.gemspec +4 -3
  5. data/features/step_definitions/filesystem_steps.rb +0 -1
  6. data/generator_files/Gemfile.erb +0 -3
  7. data/generator_files/Vagrantfile.erb +13 -1
  8. data/lib/berkshelf.rb +0 -1
  9. data/lib/berkshelf/berksfile.rb +11 -4
  10. data/lib/berkshelf/cached_cookbook.rb +2 -257
  11. data/lib/berkshelf/chef.rb +0 -1
  12. data/lib/berkshelf/chef/config.rb +3 -0
  13. data/lib/berkshelf/chef/cookbook.rb +0 -2
  14. data/lib/berkshelf/community_rest.rb +31 -6
  15. data/lib/berkshelf/cookbook_source.rb +5 -1
  16. data/lib/berkshelf/errors.rb +24 -0
  17. data/lib/berkshelf/git.rb +49 -1
  18. data/lib/berkshelf/init_generator.rb +1 -1
  19. data/lib/berkshelf/locations/chef_api_location.rb +6 -3
  20. data/lib/berkshelf/locations/path_location.rb +2 -0
  21. data/lib/berkshelf/version.rb +1 -1
  22. data/spec/spec_helper.rb +9 -2
  23. data/spec/support/chef_api.rb +1 -10
  24. data/spec/unit/berkshelf/cached_cookbook_spec.rb +37 -458
  25. data/spec/unit/berkshelf/git_spec.rb +119 -9
  26. data/spec/unit/berkshelf/init_generator_spec.rb +0 -1
  27. metadata +30 -24
  28. data/lib/berkshelf/chef/cookbook/metadata.rb +0 -556
  29. data/lib/berkshelf/chef/cookbook/syntax_check.rb +0 -158
  30. data/lib/berkshelf/chef/digester.rb +0 -67
  31. data/lib/berkshelf/mixin/checksum.rb +0 -16
  32. data/lib/berkshelf/mixin/params_validate.rb +0 -218
  33. data/lib/berkshelf/mixin/shell_out.rb +0 -23
  34. data/lib/berkshelf/uploader.rb +0 -80
  35. data/spec/unit/berkshelf/uploader_spec.rb +0 -27
  36. data/spec/unit/chef/cookbook/metadata_spec.rb +0 -5
  37. data/spec/unit/chef/digester_spec.rb +0 -41
@@ -1,158 +0,0 @@
1
- module Berkshelf::Chef::Cookbook
2
- # Encapsulates the process of validating the ruby syntax of files in Chef
3
- # cookbooks.
4
- #
5
- # Borrowed and modified from: {https://github.com/opscode/chef/blob/11.4.0/lib/chef/cookbook/syntax_check.rb}
6
- #
7
- # Copyright:: Copyright (c) 2010 Opscode, Inc.
8
- #
9
- # Licensed under the Apache License, Version 2.0 (the "License");
10
- # you may not use this file except in compliance with the License.
11
- # You may obtain a copy of the License at
12
- #
13
- # http://www.apache.org/licenses/LICENSE-2.0
14
- #
15
- # Unless required by applicable law or agreed to in writing, software
16
- # distributed under the License is distributed on an "AS IS" BASIS,
17
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18
- # See the License for the specific language governing permissions and
19
- # limitations under the License.
20
- class SyntaxCheck
21
- # Implements set behavior with disk-based persistence. Objects in the set
22
- # are expected to be strings containing only characters that are valid in
23
- # filenames.
24
- #
25
- # This class is used to track which files have been syntax checked so
26
- # that known good files are not rechecked.
27
- class PersistentSet
28
- attr_reader :cache_path
29
-
30
- # Create a new PersistentSet. Values in the set are persisted by
31
- # creating a file in the +cache_path+ directory. If not given, the
32
- # value of Chef::Config[:syntax_check_cache_path] is used; if that
33
- # value is not configured, the value of
34
- # Chef::Config[:cache_options][:path] is used.
35
- #--
36
- # history: prior to Chef 11, the cache implementation was based on
37
- # moneta and configured via cache_options[:path]. Knife configs
38
- # generated with Chef 11 will have `syntax_check_cache_path`, but older
39
- # configs will have `cache_options[:path]`. `cache_options` is marked
40
- # deprecated in chef/config.rb but doesn't currently trigger a warning.
41
- # See also: CHEF-3715
42
- def initialize(cache_path = nil)
43
- @cache_path = cache_path || Berkshelf::Chef::Config[:syntax_check_cache_path] ||
44
- Berkshelf::Chef::Config[:cache_options][:path]
45
- @cache_path_created = false
46
- end
47
-
48
- # Adds +value+ to the set's collection.
49
- def add(value)
50
- ensure_cache_path_created
51
- FileUtils.touch(File.join(cache_path, value))
52
- end
53
-
54
- # Returns true if the set includes +value+
55
- def include?(value)
56
- File.exist?(File.join(cache_path, value))
57
- end
58
-
59
- private
60
-
61
- def ensure_cache_path_created
62
- return true if @cache_path_created
63
- FileUtils.mkdir_p(cache_path)
64
- @cache_path_created = true
65
- end
66
- end
67
-
68
- include Berkshelf::Mixin::ShellOut
69
- include Berkshelf::Mixin::Checksum
70
-
71
- attr_reader :cookbook_path
72
-
73
- # A PersistentSet object that tracks which files have already been
74
- # validated.
75
- attr_reader :validated_files
76
-
77
- # Create a new SyntaxCheck object
78
- #
79
- # @param [String] cookbook_path
80
- # the (on disk) path to the cookbook
81
- def initialize(cookbook_path)
82
- @cookbook_path = cookbook_path
83
- @validated_files = PersistentSet.new
84
- end
85
-
86
- def ruby_files
87
- Dir[File.join(cookbook_path, '**', '*.rb')]
88
- end
89
-
90
- def untested_ruby_files
91
- ruby_files.reject do |file|
92
- if validated?(file)
93
- true
94
- else
95
- false
96
- end
97
- end
98
- end
99
-
100
- def template_files
101
- Dir[File.join(cookbook_path, '**', '*.erb')]
102
- end
103
-
104
- def untested_template_files
105
- template_files.reject do |file|
106
- if validated?(file)
107
- true
108
- else
109
- false
110
- end
111
- end
112
- end
113
-
114
- def validated?(file)
115
- validated_files.include?(checksum(file))
116
- end
117
-
118
- def validated(file)
119
- validated_files.add(checksum(file))
120
- end
121
-
122
- def validate_ruby_files
123
- untested_ruby_files.each do |ruby_file|
124
- return false unless validate_ruby_file(ruby_file)
125
- validated(ruby_file)
126
- end
127
- end
128
-
129
- def validate_templates
130
- untested_template_files.each do |template|
131
- return false unless validate_template(template)
132
- validated(template)
133
- end
134
- end
135
-
136
- def validate_template(erb_file)
137
- result = shell_out("erubis -x #{erb_file} | ruby -c")
138
- result.error!
139
- true
140
- rescue Mixlib::ShellOut::ShellCommandFailed
141
- file_relative_path = erb_file[/^#{Regexp.escape(cookbook_path+File::Separator)}(.*)/, 1]
142
- Berkshelf.ui.error("Erb template #{file_relative_path} has a syntax error:")
143
- result.stderr.each_line { |l| Chef::Log.fatal(l.chomp) }
144
- false
145
- end
146
-
147
- def validate_ruby_file(ruby_file)
148
- result = shell_out("ruby -c #{ruby_file}")
149
- result.error!
150
- true
151
- rescue Mixlib::ShellOut::ShellCommandFailed
152
- file_relative_path = ruby_file[/^#{Regexp.escape(cookbook_path+File::Separator)}(.*)/, 1]
153
- Berkshelf.ui.error("Cookbook file #{file_relative_path} has a ruby syntax error:")
154
- result.stderr.each_line { |l| Berkshelf.ui.error(l.chomp) }
155
- false
156
- end
157
- end
158
- end
@@ -1,67 +0,0 @@
1
- require 'digest'
2
-
3
- module Berkshelf::Chef
4
- # Borrowed and modified from: {https://github.com/opscode/chef/blob/11.4.0/lib/chef/digester.rb}
5
- #
6
- # Copyright:: Copyright (c) 2009 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
- class Digester
20
- class << self
21
- def instance
22
- @instance ||= new
23
- end
24
-
25
- def checksum_for_file(*args)
26
- instance.checksum_for_file(*args)
27
- end
28
-
29
- def md5_checksum_for_file(*args)
30
- instance.generate_md5_checksum_for_file(*args)
31
- end
32
- end
33
-
34
- def validate_checksum(*args)
35
- self.class.validate_checksum(*args)
36
- end
37
-
38
- def checksum_for_file(file)
39
- generate_checksum(file)
40
- end
41
-
42
- def generate_checksum(file)
43
- checksum_file(file, Digest::SHA256.new)
44
- end
45
-
46
- def generate_md5_checksum_for_file(file)
47
- checksum_file(file, Digest::MD5.new)
48
- end
49
-
50
- def generate_md5_checksum(io)
51
- checksum_io(io, Digest::MD5.new)
52
- end
53
-
54
- private
55
-
56
- def checksum_file(file, digest)
57
- File.open(file, 'rb') { |f| checksum_io(f, digest) }
58
- end
59
-
60
- def checksum_io(io, digest)
61
- while chunk = io.read(1024 * 8)
62
- digest.update(chunk)
63
- end
64
- digest.hexdigest
65
- end
66
- end
67
- end
@@ -1,16 +0,0 @@
1
- require 'berkshelf/chef'
2
-
3
- module Berkshelf::Mixin
4
- # @author Jamie Winsor <reset@riotgames.com>
5
- #
6
- # Inspired by and dependency-free replacement for
7
- # {https://github.com/opscode/chef/blob/11.4.0/lib/chef/mixin/checksum.rb}
8
- module Checksum
9
- # @param [String] file
10
- #
11
- # @return [String]
12
- def checksum(file)
13
- Berkshelf::Chef::Digester.checksum_for_file(file)
14
- end
15
- end
16
- end
@@ -1,218 +0,0 @@
1
- module Berkshelf::Mixin
2
- # Borrowed and modified from: {https://raw.github.com/opscode/chef/11.4.0/lib/chef/mixin/params_validate.rb}
3
- #
4
- # Copyright:: Copyright (c) 2008 Opscode, Inc.
5
- #
6
- # Licensed under the Apache License, Version 2.0 (the "License");
7
- # you may not use this file except in compliance with the License.
8
- # You may obtain a copy of the License at
9
- #
10
- # http://www.apache.org/licenses/LICENSE-2.0
11
- #
12
- # Unless required by applicable law or agreed to in writing, software
13
- # distributed under the License is distributed on an "AS IS" BASIS,
14
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
- # See the License for the specific language governing permissions and
16
- # limitations under the License.
17
- module ParamsValidate
18
- # Takes a hash of options, along with a map to validate them. Returns the original
19
- # options hash, plus any changes that might have been made (through things like setting
20
- # default values in the validation map)
21
- #
22
- # For example:
23
- #
24
- # validate({ :one => "neat" }, { :one => { :kind_of => String }})
25
- #
26
- # Would raise an exception if the value of :one above is not a kind_of? string. Valid
27
- # map options are:
28
- #
29
- # :default:: Sets the default value for this parameter.
30
- # :callbacks:: Takes a hash of Procs, which should return true if the argument is valid.
31
- # The key will be inserted into the error message if the Proc does not return true:
32
- # "Option #{key}'s value #{value} #{message}!"
33
- # :kind_of:: Ensure that the value is a kind_of?(Whatever). If passed an array, it will ensure
34
- # that the value is one of those types.
35
- # :respond_to:: Ensure that the value has a given method. Takes one method name or an array of
36
- # method names.
37
- # :required:: Raise an exception if this parameter is missing. Valid values are true or false,
38
- # by default, options are not required.
39
- # :regex:: Match the value of the paramater against a regular expression.
40
- # :equal_to:: Match the value of the paramater with ==. An array means it can be equal to any
41
- # of the values.
42
- def validate(opts, map)
43
- #--
44
- # validate works by taking the keys in the validation map, assuming it's a hash, and
45
- # looking for _pv_:symbol as methods. Assuming it find them, it calls the right
46
- # one.
47
- #++
48
- raise ArgumentError, "Options must be a hash" unless opts.kind_of?(Hash)
49
- raise ArgumentError, "Validation Map must be a hash" unless map.kind_of?(Hash)
50
-
51
- map.each do |key, validation|
52
- unless key.kind_of?(Symbol) || key.kind_of?(String)
53
- raise ArgumentError, "Validation map keys must be symbols or strings!"
54
- end
55
- case validation
56
- when true
57
- _pv_required(opts, key)
58
- when false
59
- true
60
- when Hash
61
- validation.each do |check, carg|
62
- check_method = "_pv_#{check.to_s}"
63
- if self.respond_to?(check_method, true)
64
- self.send(check_method, opts, key, carg)
65
- else
66
- raise ArgumentError, "Validation map has unknown check: #{check}"
67
- end
68
- end
69
- end
70
- end
71
- opts
72
- end
73
-
74
- def set_or_return(symbol, arg, validation)
75
- iv_symbol = "@#{symbol.to_s}".to_sym
76
- map = {
77
- symbol => validation
78
- }
79
-
80
- if arg == nil && self.instance_variable_defined?(iv_symbol) == true
81
- self.instance_variable_get(iv_symbol)
82
- else
83
- opts = validate({ symbol => arg }, { symbol => validation })
84
- self.instance_variable_set(iv_symbol, opts[symbol])
85
- end
86
- end
87
-
88
- private
89
-
90
- # Return the value of a parameter, or nil if it doesn't exist.
91
- def _pv_opts_lookup(opts, key)
92
- if opts.has_key?(key.to_s)
93
- opts[key.to_s]
94
- elsif opts.has_key?(key.to_sym)
95
- opts[key.to_sym]
96
- else
97
- nil
98
- end
99
- end
100
-
101
- # Raise an exception if the parameter is not found.
102
- def _pv_required(opts, key, is_required=true)
103
- if is_required
104
- if (opts.has_key?(key.to_s) && !opts[key.to_s].nil?) ||
105
- (opts.has_key?(key.to_sym) && !opts[key.to_sym].nil?)
106
- true
107
- else
108
- raise ValidationFailed, "Required argument #{key} is missing!"
109
- end
110
- end
111
- end
112
-
113
- def _pv_equal_to(opts, key, to_be)
114
- value = _pv_opts_lookup(opts, key)
115
- unless value.nil?
116
- passes = false
117
- Array(to_be).each do |tb|
118
- passes = true if value == tb
119
- end
120
- unless passes
121
- raise ValidationFailed, "Option #{key} must be equal to one of: #{to_be.join(", ")}! You passed #{value.inspect}."
122
- end
123
- end
124
- end
125
-
126
- # Raise an exception if the parameter is not a kind_of?(to_be)
127
- def _pv_kind_of(opts, key, to_be)
128
- value = _pv_opts_lookup(opts, key)
129
- unless value.nil?
130
- passes = false
131
- Array(to_be).each do |tb|
132
- passes = true if value.kind_of?(tb)
133
- end
134
- unless passes
135
- raise ValidationFailed, "Option #{key} must be a kind of #{to_be}! You passed #{value.inspect}."
136
- end
137
- end
138
- end
139
-
140
- # Raise an exception if the parameter does not respond to a given set of methods.
141
- def _pv_respond_to(opts, key, method_name_list)
142
- value = _pv_opts_lookup(opts, key)
143
- unless value.nil?
144
- Array(method_name_list).each do |method_name|
145
- unless value.respond_to?(method_name)
146
- raise ValidationFailed, "Option #{key} must have a #{method_name} method!"
147
- end
148
- end
149
- end
150
- end
151
-
152
- # Assert that parameter returns false when passed a predicate method.
153
- # For example, :cannot_be => :blank will raise a ValidationFailed
154
- # error value.blank? returns a 'truthy' (not nil or false) value.
155
- #
156
- # Note, this will *PASS* if the object doesn't respond to the method.
157
- # So, to make sure a value is not nil and not blank, you need to do
158
- # both :cannot_be => :blank *and* :cannot_be => :nil (or :required => true)
159
- def _pv_cannot_be(opts, key, predicate_method_base_name)
160
- value = _pv_opts_lookup(opts, key)
161
- predicate_method = (predicate_method_base_name.to_s + "?").to_sym
162
-
163
- if value.respond_to?(predicate_method)
164
- if value.send(predicate_method)
165
- raise ValidationFailed, "Option #{key} cannot be #{predicate_method_base_name}"
166
- end
167
- end
168
- end
169
-
170
- # Assign a default value to a parameter.
171
- def _pv_default(opts, key, default_value)
172
- value = _pv_opts_lookup(opts, key)
173
- if value == nil
174
- opts[key] = default_value
175
- end
176
- end
177
-
178
- # Check a parameter against a regular expression.
179
- def _pv_regex(opts, key, regex)
180
- value = _pv_opts_lookup(opts, key)
181
- if value != nil
182
- passes = false
183
- [ regex ].flatten.each do |r|
184
- if value != nil
185
- if r.match(value.to_s)
186
- passes = true
187
- end
188
- end
189
- end
190
- unless passes
191
- raise ValidationFailed, "Option #{key}'s value #{value} does not match regular expression #{regex.inspect}"
192
- end
193
- end
194
- end
195
-
196
- # Check a parameter against a hash of proc's.
197
- def _pv_callbacks(opts, key, callbacks)
198
- raise ArgumentError, "Callback list must be a hash!" unless callbacks.kind_of?(Hash)
199
- value = _pv_opts_lookup(opts, key)
200
- if value != nil
201
- callbacks.each do |message, zeproc|
202
- if zeproc.call(value) != true
203
- raise ValidationFailed, "Option #{key}'s value #{value} #{message}!"
204
- end
205
- end
206
- end
207
- end
208
-
209
- # Allow a parameter to default to @name
210
- def _pv_name_attribute(opts, key, is_name_attribute=true)
211
- if is_name_attribute
212
- if opts[key] == nil
213
- opts[key] = self.instance_variable_get("@name")
214
- end
215
- end
216
- end
217
- end
218
- end