PortMan
PortMan

Reputation: 4523

How to share code between recipes

I have a recipe that loops through a bunch of data defined in the attributes:

node["repos"].each do |repo, data|
  ...do stuff...
end

the ...do stuff... section is fairly long, and I would like to re-use it in multiple recipes, the only difference being that data set in the attributes is different.

I tried moving the inside of the loop to another recipe and including it like this:

node["repos"].each do |repo, data|
   include_recipe "other_recipe"
end

But when it tried to run other_recipe, the data variable did not exist.

What is the "proper" way of sharing code between recipes?

Upvotes: 1

Views: 427

Answers (2)

Draco Ater
Draco Ater

Reputation: 21206

The simplest thing would be is moving this do stuff to library.

my_cookbook/libraries/myhelper.rb:

module Myhelper
  def do_stuff( repo, data )
    [...you can use all kinds of resources here as in recipe...]
  end
end

Then you can use this module in recipes like that:

another_cookbook/recipes/some_recipe.rb:

extend Myhelper
do_stuff( node[:attribute1], node[:attribute2] )

Just make sure you add a dependency on my_cookbook in metadata:

another_cookbook/metadata.rb:

depends 'my_cookbook'

Upvotes: 3

coderanger
coderanger

Reputation: 54181

Unfortunately this doesn't work because include_recipe both doesn't allow passing parameters and is "debounced" meaning it only runs once for a given recipe.

The simplest option these days for this kind of thing is to make a custom resource. Other options include definitions and helper methods but I would start with a custom resource and go from there. The inputs to the block of stuff (repo and data in this case) become resource properties and the chunk of recipe code goes in the resource's action method.

Upvotes: 1

Related Questions