class ChefApply::Action::GenerateTempCookbook::RecipeLookup

When users are trying to converge a local recipe on a remote target, there is a very specific (but expansive) set of things they can specify. This class encapsulates that logic for testing purposes. We either return a path to a recipe or we raise an error.

Attributes

cookbook_repo_paths[R]

Public Class Methods

new(cookbook_repo_paths) click to toggle source
# File lib/chef_apply/action/generate_temp_cookbook/recipe_lookup.rb, line 34
def initialize(cookbook_repo_paths)
  @cookbook_repo_paths = cookbook_repo_paths
end

Public Instance Methods

find_recipe(cookbook, recipe_name = nil) click to toggle source

Find the specified recipe or default recipe if none is specified. Raise an error if recipe cannot be found.

# File lib/chef_apply/action/generate_temp_cookbook/recipe_lookup.rb, line 83
def find_recipe(cookbook, recipe_name = nil)
  recipes = cookbook.recipe_filenames_by_name.merge(cookbook.recipe_yml_filenames_by_name)
  if recipe_name.nil?
    default_recipe = recipes["default"]
    raise NoDefaultRecipe.new(cookbook.root_dir, cookbook.name) if default_recipe.nil?

    default_recipe
  else
    recipe = recipes[recipe_name]
    raise RecipeNotFound.new(cookbook.root_dir, recipe_name, recipes.keys, cookbook.name) if recipe.nil?

    recipe
  end
end
load_cookbook(path_or_name) click to toggle source

Given a cookbook path or name, try to load that cookbook. Either return a cookbook object or raise an error.

# File lib/chef_apply/action/generate_temp_cookbook/recipe_lookup.rb, line 46
def load_cookbook(path_or_name)
  require "chef/exceptions"
  if File.directory?(path_or_name)
    cookbook_path = path_or_name
    # First, is there a cookbook in the specified dir that matches?
    require "chef/cookbook/cookbook_version_loader"
    begin
      v = Chef::Cookbook::CookbookVersionLoader.new(cookbook_path)
      v.load!
      cookbook = v.cookbook_version
    rescue Chef::Exceptions::CookbookNotFoundInRepo
      raise InvalidCookbook.new(cookbook_path)
    end
  else
    cookbook_name = path_or_name
    # Second, is there a cookbook in their local repository that matches?
    require "chef/cookbook_loader"
    cb_loader = Chef::CookbookLoader.new(cookbook_repo_paths)
    cb_loader.load_cookbooks

    begin
      cookbook = cb_loader[cookbook_name]
    rescue Chef::Exceptions::CookbookNotFoundInRepo
      cookbook_repo_paths.each do |repo_path|
        cookbook_path = File.join(repo_path, cookbook_name)
        if File.directory?(cookbook_path)
          raise InvalidCookbook.new(cookbook_path)
        end
      end
      raise CookbookNotFound.new(cookbook_name, cookbook_repo_paths)
    end
  end
  cookbook
end
split(recipe_specifier) click to toggle source

The recipe specifier is provided by the customer as either a path OR a cookbook and optional recipe name.

# File lib/chef_apply/action/generate_temp_cookbook/recipe_lookup.rb, line 40
def split(recipe_specifier)
  recipe_specifier.split("::")
end