Class: Chef::CookbookLoader

Inherits:
Object
  • Object
show all
Includes:
Enumerable
Defined in:
lib/chef/cookbook_loader.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(*repo_paths) ⇒ CookbookLoader

Returns a new instance of CookbookLoader.

Raises:

  • (ArgumentError)


41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
# File 'lib/chef/cookbook_loader.rb', line 41

def initialize(*repo_paths)
  repo_paths = repo_paths.flatten
  raise ArgumentError, "You must specify at least one cookbook repo path" if repo_paths.empty?
  @cookbooks_by_name = Mash.new
  @loaded_cookbooks = {}
  @metadata = Mash.new
  @cookbooks_paths = Hash.new { |h, k| h[k] = [] } # for deprecation warnings
  @chefignores = {}
  @repo_paths = repo_paths.map do |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
  # this variable
  @merged_cookbooks = []
end

Instance Attribute Details

#cookbook_pathsObject (readonly)

Returns the value of attribute cookbook_paths.



36
37
38
# File 'lib/chef/cookbook_loader.rb', line 36

def cookbook_paths
  @cookbook_paths
end

#cookbooks_by_nameObject (readonly)

Returns the value of attribute cookbooks_by_name.



34
35
36
# File 'lib/chef/cookbook_loader.rb', line 34

def cookbooks_by_name
  @cookbooks_by_name
end

#merged_cookbooksObject (readonly)

Returns the value of attribute merged_cookbooks.



35
36
37
# File 'lib/chef/cookbook_loader.rb', line 35

def merged_cookbooks
  @merged_cookbooks
end

#metadataObject (readonly)

Returns the value of attribute metadata.



37
38
39
# File 'lib/chef/cookbook_loader.rb', line 37

def 
  @metadata
end

Instance Method Details

#[](cookbook) ⇒ Object Also known as: fetch



123
124
125
126
127
128
129
# File 'lib/chef/cookbook_loader.rb', line 123

def [](cookbook)
  if @cookbooks_by_name.has_key?(cookbook.to_sym) || load_cookbook(cookbook.to_sym)
    @cookbooks_by_name[cookbook.to_sym]
  else
    raise Exceptions::CookbookNotFoundInRepo, "Cannot find a cookbook named #{cookbook}; did you forget to add metadata to a cookbook? (https://docs.chef.io/config_rb_metadata.html)"
  end
end

#cookbook_namesObject



145
146
147
# File 'lib/chef/cookbook_loader.rb', line 145

def cookbook_names
  @cookbooks_by_name.keys.sort
end

#eachObject



139
140
141
142
143
# File 'lib/chef/cookbook_loader.rb', line 139

def each
  @cookbooks_by_name.keys.sort { |a, b| a.to_s <=> b.to_s }.each do |cname|
    yield(cname, @cookbooks_by_name[cname])
  end
end

#has_key?(cookbook_name) ⇒ Boolean Also known as: cookbook_exists?, key?

Returns:

  • (Boolean)


133
134
135
# File 'lib/chef/cookbook_loader.rb', line 133

def has_key?(cookbook_name)
  not self[cookbook_name.to_sym].nil?
end

#load_cookbook(cookbook_name) ⇒ Object



93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
# File 'lib/chef/cookbook_loader.rb', line 93

def load_cookbook(cookbook_name)
  preload_cookbooks

  return @cookbooks_by_name[cookbook_name] if @cookbooks_by_name.has_key?(cookbook_name)

  return nil unless @loaders_by_name.key?(cookbook_name.to_s)

  cookbook_loaders_for(cookbook_name).each do |loader|
    loader.load

    next if loader.empty?

    @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)
    else
      @loaded_cookbooks[cookbook_name] = loader
    end
  end

  if @loaded_cookbooks.has_key?(cookbook_name)
    cookbook_version = @loaded_cookbooks[cookbook_name].cookbook_version
    @cookbooks_by_name[cookbook_name] = cookbook_version
    @metadata[cookbook_name] = cookbook_version.
  end
  @cookbooks_by_name[cookbook_name]
end

#load_cookbooksObject



87
88
89
90
91
# File 'lib/chef/cookbook_loader.rb', line 87

def load_cookbooks
  ret = load_cookbooks_without_shadow_warning
  warn_about_cookbook_shadowing
  ret
end

#load_cookbooks_without_shadow_warningObject

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Will be removed when cookbook shadowing is removed, do NOT create new consumers of this API.



79
80
81
82
83
84
85
# File 'lib/chef/cookbook_loader.rb', line 79

def load_cookbooks_without_shadow_warning
  preload_cookbooks
  @loaders_by_name.each do |cookbook_name, _loaders|
    load_cookbook(cookbook_name)
  end
  @cookbooks_by_name
end

#merged_cookbook_pathsObject

for deprecation warnings



63
64
65
66
67
# File 'lib/chef/cookbook_loader.rb', line 63

def merged_cookbook_paths # for deprecation warnings
  merged_cookbook_paths = {}
  @merged_cookbooks.each { |c| merged_cookbook_paths[c] = @cookbooks_paths[c] }
  merged_cookbook_paths
end

#valuesObject Also known as: cookbooks



149
150
151
# File 'lib/chef/cookbook_loader.rb', line 149

def values
  @cookbooks_by_name.values
end

#warn_about_cookbook_shadowingObject



69
70
71
72
73
74
# File 'lib/chef/cookbook_loader.rb', line 69

def warn_about_cookbook_shadowing
  unless merged_cookbooks.empty?
    Chef::Log.deprecation "The cookbook(s): #{merged_cookbooks.join(', ')} exist in multiple places in your cookbook_path. " +
      "A composite version has been compiled.  This has been deprecated since 0.10.4, in Chef 13 this behavior will be REMOVED."
  end
end