diff options
author | danielsdeleo <dan@getchef.com> | 2014-08-05 15:01:14 -0700 |
---|---|---|
committer | danielsdeleo <dan@getchef.com> | 2014-08-12 11:03:09 -0700 |
commit | 7545eda303bbb6034a0a2397e1a510b19bdd5e9b (patch) | |
tree | 3746156e8b704b7a0cb5560ada6bc3b0e27a39a8 /lib/chef/cookbook_loader.rb | |
parent | f5ea885549b840cbb9008f739d1f6f1784e06f97 (diff) | |
download | chef-7545eda303bbb6034a0a2397e1a510b19bdd5e9b.tar.gz |
Remove assumption that cookbook names match dirnames in CookbookLoader
Cookbooks are now loaded with a "preload" step that reads cookbook
metadata to determine the name. Cookbooks are fully loaded later.
Diffstat (limited to 'lib/chef/cookbook_loader.rb')
-rw-r--r-- | lib/chef/cookbook_loader.rb | 69 |
1 files changed, 55 insertions, 14 deletions
diff --git a/lib/chef/cookbook_loader.rb b/lib/chef/cookbook_loader.rb index 27cf978acb..cac5548565 100644 --- a/lib/chef/cookbook_loader.rb +++ b/lib/chef/cookbook_loader.rb @@ -50,6 +50,9 @@ class Chef repo_path = File.expand_path(repo_path) end + @preloaded_cookbooks = false + @loaders_by_name = {} + # Used to track which cookbooks appear in multiple places in the cookbook repos # and are merged in to a single cookbook by file shadowing. This behavior is # deprecated, so users of this class may issue warnings to the user by checking @@ -64,25 +67,25 @@ class Chef end def load_cookbooks - @repo_paths.each do |repo_path| - Dir[File.join(repo_path, "*")].each do |cookbook_path| - load_cookbook(File.basename(cookbook_path), [repo_path]) - end + preload_cookbooks + @loaders_by_name.each do |cookbook_name, _loaders| + load_cookbook(cookbook_name) end @cookbooks_by_name end - def load_cookbook(cookbook_name, repo_paths=nil) - repo_paths ||= @repo_paths - repo_paths.each do |repo_path| - @chefignores[repo_path] ||= Cookbook::Chefignore.new(repo_path) - cookbook_path = File.join(repo_path, cookbook_name.to_s) - next unless File.directory?(cookbook_path) and Dir[File.join(repo_path, "*")].include?(cookbook_path) - loader = Cookbook::CookbookVersionLoader.new(cookbook_path, @chefignores[repo_path]) - loader.load_cookbooks + def load_cookbook(cookbook_name) + preload_cookbooks + + return nil unless @loaders_by_name.key?(cookbook_name.to_s) + + @loaders_by_name[cookbook_name.to_s].each do |loader| + loader.load + next if loader.empty? - cookbook_name = loader.cookbook_name - @cookbooks_paths[cookbook_name] << cookbook_path # for deprecation warnings + + @cookbooks_paths[cookbook_name] << loader.cookbook_path # for deprecation warnings + if @loaded_cookbooks.key?(cookbook_name) @merged_cookbooks << cookbook_name # for deprecation warnings @loaded_cookbooks[cookbook_name].merge!(loader) @@ -130,5 +133,43 @@ class Chef end alias :cookbooks :values + private + + def preload_cookbooks + return false if @preloaded_cookbooks + + all_directories_in_repo_paths.each do |cookbook_path| + preload_cookbook(cookbook_path) + end + @preloaded_cookbooks = true + true + end + + def preload_cookbook(cookbook_path) + repo_path = File.dirname(cookbook_path) + @chefignores[repo_path] ||= Cookbook::Chefignore.new(repo_path) + loader = Cookbook::CookbookVersionLoader.new(cookbook_path, @chefignores[repo_path]) + + cookbook_name = loader.cookbook_name + + # TODO: wrap @loaders_by_name so string keys are encapsulated + @loaders_by_name[cookbook_name.to_s] ||= [] + @loaders_by_name[cookbook_name.to_s] << loader + end + + def all_directories_in_repo_paths + @all_directories_in_repo_paths ||= + all_files_in_repo_paths.select { |path| File.directory?(path) } + end + + def all_files_in_repo_paths + @all_files_in_repo_paths ||= + begin + @repo_paths.inject([]) do |all_children, repo_path| + all_children += Dir[File.join(repo_path, "*")] + end + end + end + end end |