Ruby variable in recipe behaes differently duirng cookbook runs

The following segment of code is in a recipe. When the recipe runs the 1st time, puts shows file_list only has 2 elements [“attributes/default.rb”, “metadata.rb”]. When the recipe runs again, file_list now also contains elements pushed from the Dir block. Why is that and how to have the array contain all the elements during the 1st run?


file_list = Array.new

Dir.glob("#{node[‘cookbook_dir’]}/#{node[‘cookbook_name’]}/recipes/*.rb") do |f|
f2 = f[/recipes/(.+).rb/]
file_list.push(f2)
end

file_list.push(“attributes/default.rb”)
file_list.push(“metadata.rb”)

puts “File list: #{file_list}”

Most likely at the time the code runs the first time, there are no files in that directory. Check out https://coderanger.net/two-pass/ for an overview of the compile/converge process and how it causes these kinds of bugs.

Coderanger, I have a number of .rb files in the recipes directory before I run this code the first time. This is a bug (outside of my code)?

@Victor I would agree with @coderanger that this would appear to be a compile/converge issue.

Might be easier to explain what you are trying to do; Chef does store the cookbook manifests.

The only comment I’d make about the Ruby code above is that I’d prefer to create a path using File.join, it doesn’t make the code any more readable but should take care of any adjoining path separators so you don’t have to interpolate with slashes.

Dir[File.join(node['cookbook_dir'], node['cookbook_name'], 'recipes', '*.rb')] do |f|

I was trying to create a list that contains files from different directories. The following worked:
file_list = Array.new
file_list << Dir[File.join(node[‘cookbook_dir’], node[‘cookbook_name’], ‘recipes’, ‘*.rb’)]
file_list << …

Thanks to you guys.