class Kitchen::Recipe

An object that yields a Document for modification (those modifications are the “recipe”)

Attributes

document[R]

The document the recipe makes available for modification @return [Document]

my_i18n_backend[R]

An I18n backend specific to this recipe, may be nil @return [I18n::Backend::Simple, nil]

source_location[R]

The file location of the recipe @return [String]

Public Class Methods

new(locales_dir: nil, &block) click to toggle source

Make a new Recipe

@param locales_dir [String, nil] the absolute path to a folder containing recipe-specific

I18n translations.  If not provided, Kitchen will look for a `locales` directory in the
same directory as the recipe source.  Recipe-specific translations override those in
Kitchen.  If no recipe-specific locales directory exists, Kitchen will just use its default
translations.

@yield A block for defining the steps of the recipe @yieldparam doc [Document] an object representing an XML document

# File lib/kitchen/recipe.rb, line 46
def initialize(locales_dir: nil, &block)
  raise(RecipeError, 'Recipes must be initialized with a block') unless block_given?

  @source_location = block.source_location[0]
  @block = block

  load_my_i18n_backend(locales_dir)
end

Public Instance Methods

bake() click to toggle source

Executes the block given to Recipe.new on the document. Aka, does the baking.

# File lib/kitchen/recipe.rb, line 57
def bake
  with_my_locales do
    @block.to_proc.call(document)
  end
rescue RecipeError, ElementNotFoundError, Nokogiri::CSS::SyntaxError => e
  print_recipe_error_and_exit(e)
rescue ArgumentError, NoMethodError => e
  raise unless any_stack_file_matches_source_location?(e)

  print_recipe_error_and_exit(e)
rescue NameError => e
  raise unless stack_starts_with_source_location?(e)

  print_recipe_error_and_exit(e)
end
document=(document) click to toggle source

Sets the document so the recipe can yield it for modification

@param document [Document] the document to modify @raise [StandardError] if not passed supported document type

# File lib/kitchen/recipe.rb, line 26
def document=(document)
  @document =
    case document
    when Kitchen::Document
      document
    else
      raise "Unsupported document type `#{document.class}`"
    end
end

Protected Instance Methods

any_stack_file_matches_source_location?(error) click to toggle source
# File lib/kitchen/recipe.rb, line 79
def any_stack_file_matches_source_location?(error)
  error.backtrace.any? { |entry| entry.start_with?(@source_location) }
end
load_my_i18n_backend(locales_dir) click to toggle source
# File lib/kitchen/recipe.rb, line 83
def load_my_i18n_backend(locales_dir)
  locales_dir ||= begin
    guessed_locales_dir = "#{File.dirname(@source_location)}/locales"
    File.directory?(guessed_locales_dir) ? guessed_locales_dir : nil
  end

  return unless locales_dir

  @my_i18n_backend = I18n::Backend::Simple.new
  @my_i18n_backend.load_translations(Dir[File.expand_path("#{locales_dir}/*.yml")])
end
print_recipe_error_and_exit(error) click to toggle source

Print the given recipe error and do a process exit

@param error [RecipeError] the error

stack_starts_with_source_location?(error) click to toggle source
# File lib/kitchen/recipe.rb, line 75
def stack_starts_with_source_location?(error)
  error.backtrace.first.start_with?(source_location)
end
with_my_locales() { || ... } click to toggle source
# File lib/kitchen/recipe.rb, line 95
def with_my_locales
  original_i18n_backend = I18n.backend
  I18n.backend = I18n::Backend::Chain.new(my_i18n_backend, original_i18n_backend)
  yield
ensure
  I18n.backend = original_i18n_backend
end