class Ridley::Chef::Cookbook::SyntaxCheck
Encapsulates the process of validating the ruby syntax of files in Chef
cookbooks.
Borrowed and modified from: {github.com/opscode/chef/blob/11.4.0/lib/chef/cookbook/syntax_check.rb}
- Copyright
-
Copyright © 2010 Opscode, Inc.
Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
Attributes
@return [Ridley::Chef::Chefignore, nil]
A PersistentSet
object that tracks which files have already been validated.
Public Class Methods
Create a new SyntaxCheck
object
@param [String] cookbook_path
the (on disk) path to the cookbook
@param [Ridley::Chef::Chefignore] chefignore
the instance of R::C::Chefignore to filter out
# File lib/ridley/chef/cookbook/syntax_check.rb, line 85 def initialize(cookbook_path, chefignore = nil) @cookbook_path = cookbook_path @validated_files = PersistentSet.new @chefignore = chefignore end
Public Instance Methods
# File lib/ridley/chef/cookbook/syntax_check.rb, line 92 def ruby_files Dir[File.join(cookbook_path, '**', '*.rb')].reject { |f| ignored?(f) } end
# File lib/ridley/chef/cookbook/syntax_check.rb, line 100 def template_files Dir[File.join(cookbook_path, '**', '*.erb')].reject { |f| ignored?(f) } end
# File lib/ridley/chef/cookbook/syntax_check.rb, line 96 def untested_ruby_files ruby_files.reject { |file| validated?(file) } end
# File lib/ridley/chef/cookbook/syntax_check.rb, line 104 def untested_template_files template_files.reject { |file| validated?(file) } end
Borrowed from: github.com/opscode/chef/blob/d111e82/lib/chef/cookbook/syntax_check.rb#L242-L264
# File lib/ridley/chef/cookbook/syntax_check.rb, line 159 def validate_ruby_file(ruby_file) # Even when we're compiling the code w/ RubyVM, syntax errors just # print to $stderr. We want to capture this and handle the printing # ourselves, so we must temporarily swap $stderr to capture the output. old_stderr = $stderr tmp_stderr = $stderr = StringIO.new abs_path = File.expand_path(ruby_file) file_content = IO.read(abs_path) # We have to wrap this in a block so the user code evaluates in a # similar context as what Chef does normally. Otherwise RubyVM # will reject some common idioms, like using `return` to end evaluation # of a recipe. See also CHEF-5199 wrapped_content = "Object.new.instance_eval do\n#{file_content}\nend\n" RubyVM::InstructionSequence.new(wrapped_content, ruby_file, abs_path, 0) true rescue SyntaxError $stderr = old_stderr invalid_ruby_file(ruby_file, tmp_stderr.string) false ensure $stderr = old_stderr if defined?(old_stderr) && old_stderr end
# File lib/ridley/chef/cookbook/syntax_check.rb, line 116 def validate_ruby_files untested_ruby_files.each do |ruby_file| return false unless validate_ruby_file(ruby_file) validated(ruby_file) end true end
Borrowed from: github.com/opscode/chef/blob/d111e82/lib/chef/cookbook/syntax_check.rb#L191-L215
# File lib/ridley/chef/cookbook/syntax_check.rb, line 133 def validate_template(erb_file) old_stderr = $stderr engine = Erubis::Eruby.new engine.convert!(IO.read(erb_file)) ruby_code = engine.src # Even when we're compiling the code w/ RubyVM, syntax errors just # print to $stderr. We want to capture this and handle the printing # ourselves, so we must temporarily swap $stderr to capture the output. tmp_stderr = $stderr = StringIO.new abs_path = File.expand_path(erb_file) RubyVM::InstructionSequence.new(ruby_code, erb_file, abs_path, 0) true rescue SyntaxError $stderr = old_stderr invalid_erb_file(erb_file, tmp_stderr.string) false ensure $stderr = old_stderr if defined?(old_stderr) && old_stderr end
# File lib/ridley/chef/cookbook/syntax_check.rb, line 124 def validate_templates untested_template_files.each do |template| return false unless validate_template(template) validated(template) end true end
# File lib/ridley/chef/cookbook/syntax_check.rb, line 112 def validated(file) validated_files.add(checksum(file)) end
# File lib/ridley/chef/cookbook/syntax_check.rb, line 108 def validated?(file) validated_files.include?(checksum(file)) end
Private Instance Methods
# File lib/ridley/chef/cookbook/syntax_check.rb, line 188 def ignored?(file) !!chefignore && chefignore.ignored?(file) end
Debug a syntax error in a template.
# File lib/ridley/chef/cookbook/syntax_check.rb, line 193 def invalid_erb_file(erb_file, error_message) log.error("Erb template #{erb_file} has a syntax error:") error_message.each_line { |l| log.error(l.chomp) } nil end
Debugs ruby syntax errors by printing the path to the file and any diagnostic info given in error_message
# File lib/ridley/chef/cookbook/syntax_check.rb, line 201 def invalid_ruby_file(ruby_file, error_message) log.error("Cookbook file #{ruby_file} has a ruby syntax error:") error_message.each_line { |l| log.error(l.chomp) } false end