class Ridley::Chef::Cookbook
Constants
- CHEF_JSON_CLASS
- CHEF_TYPE
Attributes
@return [Ridley::Chef::Chefignore, nil]
@return [Array]
@return [Boolean]
@return [Hashie::Mash]
a Hashie::Mash containing Cookbook file category names as keys and an Array of Hashes containing metadata about the files belonging to that category. This is used to communicate what a Cookbook looks like when uploading to a Chef Server. example: { :recipes => [ { name: "default.rb", path: "recipes/default.rb", checksum: "fb1f925dcd5fc4ebf682c4442a21c619", specificity: "default" } ] ... ... }
Public Class Methods
@param [String] filepath
a path on disk to the location of a file to checksum
@return [String]
a checksum that can be used to uniquely identify the file understood by a Chef Server.
# File lib/ridley/chef/cookbook.rb, line 15 def checksum(filepath) Ridley::Chef::Digester.md5_checksum_for_file(filepath) end
Creates a new instance of Ridley::Chef::Cookbook
from a path on disk containing a Cookbook
.
The name of the Cookbook
is determined by the value of the name attribute set in the cookbooks' metadata. If the name attribute is not present the name of the loaded cookbook is determined by directory containing the cookbook.
@param [#to_s] path
a path on disk to the location of a Cookbook
@raise [IOError] if the path does not contain a metadata.rb or metadata.json file
@return [Ridley::Chef::Cookbook]
# File lib/ridley/chef/cookbook.rb, line 32 def from_path(path) path = Pathname.new(path) if (file = path.join(Metadata::COMPILED_FILE_NAME)).exist? metadata = Metadata.from_json(File.read(file)) elsif (file = path.join(Metadata::RAW_FILE_NAME)).exist? metadata = Metadata.from_file(file) else raise IOError, "no #{Metadata::COMPILED_FILE_NAME} or #{Metadata::RAW_FILE_NAME} found at #{path}" end unless metadata.name.presence raise Ridley::Errors::MissingNameAttribute.new(path) end new(metadata.name, path, metadata) end
# File lib/ridley/chef/cookbook.rb, line 85 def initialize(name, path, metadata) @cookbook_name = name @path = Pathname.new(path) @metadata = metadata @frozen = false @chefignore = Ridley::Chef::Chefignore.new(@path) rescue nil clear_files load_files end
Public Instance Methods
# File lib/ridley/chef/cookbook.rb, line 228 def <=>(other) [self.cookbook_name, self.version] <=> [other.cookbook_name, other.version] end
@return [Hash]
an hash containing the checksums and expanded file paths of all of the files found in the instance of CachedCookbook example: { "da97c94bb6acb2b7900cbf951654fea3" => "/Users/reset/.ridley/nginx-0.101.2/README.md" }
# File lib/ridley/chef/cookbook.rb, line 104 def checksums {}.tap do |checksums| files.each do |file| checksums[self.class.checksum(file)] = file end end end
Compiles the raw metadata of the cookbook and writes it to a metadata.json file at the given out path. The default out path is the directory containing the cookbook itself.
@param [String] out
directory to output compiled metadata to
@return [String]
path to the compiled metadata
# File lib/ridley/chef/cookbook.rb, line 120 def compile_metadata(out = self.path) filepath = File.join(out, Metadata::COMPILED_FILE_NAME) File.open(filepath, "wb+") do |f| f.write(metadata.to_json) end filepath end
Returns true if the cookbook instance has a compiled metadata file and false if it does not.
@return [Boolean]
# File lib/ridley/chef/cookbook.rb, line 133 def compiled_metadata? manifest[:root_files].any? { |file| file[:name].downcase == Metadata::COMPILED_FILE_NAME } end
@param [Symbol] category
the category of file to generate metadata about
@param [String] target
the filepath to the file to get metadata information about
@return [Hash]
a Hash containing a name, path, checksum, and specificity key representing the metadata about a file contained in a Cookbook. This metadata is used when uploading a Cookbook's files to a Chef Server.
@example
file_metadata(:root_files, "somefile.h") => { name: "default.rb", path: "recipes/default.rb", checksum: "fb1f925dcd5fc4ebf682c4442a21c619", specificity: "default" }
# File lib/ridley/chef/cookbook.rb, line 154 def file_metadata(category, target) target = Pathname.new(target) { name: target.basename.to_s, path: target.relative_path_from(path).to_s, checksum: self.class.checksum(target), specificity: file_specificity(category, target) } end
@param [Symbol] category @param [Pathname] target
@return [String]
# File lib/ridley/chef/cookbook.rb, line 169 def file_specificity(category, target) case category when :files, :templates relpath = target.relative_path_from(path).to_s relpath.slice(/(.+)\/(.+)\/.+/, 2) || 'root_default' else 'default' end end
@return [String]
the name of the cookbook and the version number separated by a dash (-). example: "nginx-0.101.2"
# File lib/ridley/chef/cookbook.rb, line 184 def name "#{cookbook_name}-#{version}" end
Reload the cookbook from the files located on disk at `#path`.
# File lib/ridley/chef/cookbook.rb, line 189 def reload clear_files load_files end
# File lib/ridley/chef/cookbook.rb, line 207 def to_hash result = manifest.dup result[:chef_type] = CHEF_TYPE result[:name] = name result[:cookbook_name] = cookbook_name result[:version] = version result[:metadata] = metadata.to_hash result[:frozen?] = frozen result end
# File lib/ridley/chef/cookbook.rb, line 218 def to_json(*args) result = self.to_hash result['json_class'] = CHEF_JSON_CLASS result.to_json(*args) end
# File lib/ridley/chef/cookbook.rb, line 224 def to_s "#{cookbook_name} (#{version}) '#{path}'" end
# File lib/ridley/chef/cookbook.rb, line 194 def validate raise IOError, "No Cookbook found at: #{path}" unless path.exist? unless syntax_checker.validate_ruby_files raise Ridley::Errors::CookbookSyntaxError, "Invalid ruby files in cookbook: #{cookbook_name} (#{version})." end unless syntax_checker.validate_templates raise Ridley::Errors::CookbookSyntaxError, "Invalid template files in cookbook: #{cookbook_name} (#{version})." end true end
Private Instance Methods
# File lib/ridley/chef/cookbook.rb, line 240 def clear_files @files = Array.new @manifest = Hashie::Mash.new( recipes: Array.new, definitions: Array.new, libraries: Array.new, attributes: Array.new, files: Array.new, templates: Array.new, resources: Array.new, providers: Array.new, root_files: Array.new ) end
Determine if the given file should be ignored by the chefignore
@return [Boolean]
true if it should be ignored, false otherwise
# File lib/ridley/chef/cookbook.rb, line 308 def ignored?(file) !!chefignore && chefignore.ignored?(file) end
# File lib/ridley/chef/cookbook.rb, line 255 def load_files load_shallow(:recipes, 'recipes', '*.rb') load_shallow(:definitions, 'definitions', '*.rb') load_shallow(:attributes, 'attributes', '*.rb') load_recursively(:libraries, 'libraries', '*.rb') load_recursively(:files, "files", "*") load_recursively(:templates, "templates", "*") load_recursively(:resources, "resources", "*.rb") load_recursively(:providers, "providers", "*.rb") load_root end
# File lib/ridley/chef/cookbook.rb, line 278 def load_recursively(category, category_dir, glob) [].tap do |files| file_spec = path.join(category_dir, '**', glob) Dir.glob(file_spec, File::FNM_DOTMATCH).each do |file| next if File.directory?(file) next if ignored?(file) @files << file @manifest[category] << file_metadata(category, file) end end end
# File lib/ridley/chef/cookbook.rb, line 267 def load_root [].tap do |files| Dir.glob(path.join('*'), File::FNM_DOTMATCH).each do |file| next if File.directory?(file) next if ignored?(file) @files << file @manifest[:root_files] << file_metadata(:root_files, file) end end end
# File lib/ridley/chef/cookbook.rb, line 290 def load_shallow(category, *path_glob) [].tap do |files| Dir[path.join(*path_glob)].each do |file| next if ignored?(file) @files << file @manifest[category] << file_metadata(category, file) end end end
# File lib/ridley/chef/cookbook.rb, line 300 def syntax_checker @syntax_checker ||= Cookbook::SyntaxCheck.new(path.to_s, chefignore) end