summaryrefslogtreecommitdiff
path: root/lib/chef/cookbook_loader.rb
diff options
context:
space:
mode:
authordanielsdeleo <dan@getchef.com>2014-08-05 15:01:14 -0700
committerdanielsdeleo <dan@getchef.com>2014-08-12 11:03:09 -0700
commit7545eda303bbb6034a0a2397e1a510b19bdd5e9b (patch)
tree3746156e8b704b7a0cb5560ada6bc3b0e27a39a8 /lib/chef/cookbook_loader.rb
parentf5ea885549b840cbb9008f739d1f6f1784e06f97 (diff)
downloadchef-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.rb69
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