Class: Chef::Cookbook::CookbookVersionLoader

Inherits:
Object
  • Object
show all
Defined in:
lib/chef/cookbook/cookbook_version_loader.rb

Constant Summary collapse

FILETYPES_SUBJECT_TO_IGNORE =
[ :attribute_filenames,
:definition_filenames,
:recipe_filenames,
:template_filenames,
:file_filenames,
:library_filenames,
:resource_filenames,
:provider_filenames]
UPLOADED_COOKBOOK_VERSION_FILE =
".uploaded-cookbook-version.json".freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(path, chefignore = nil) ⇒ CookbookVersionLoader

Returns a new instance of CookbookVersionLoader.



28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
# File 'lib/chef/cookbook/cookbook_version_loader.rb', line 28

def initialize(path, chefignore=nil)
  @cookbook_path = File.expand_path( path ) # cookbook_path from which this was loaded
  # We keep a list of all cookbook paths that have been merged in
  @cookbook_paths = [ @cookbook_path ]
  @cookbook_name = File.basename( path )
  @chefignore = chefignore
   = Hash.new
  @relative_path = /#{Regexp.escape(@cookbook_path)}\/(.+)$/
  @cookbook_settings = {
    :attribute_filenames  => {},
    :definition_filenames => {},
    :recipe_filenames     => {},
    :template_filenames   => {},
    :file_filenames       => {},
    :library_filenames    => {},
    :resource_filenames   => {},
    :provider_filenames   => {},
    :root_filenames       => {}
  }

   = []
end

Instance Attribute Details

#cookbook_nameObject (readonly)

Returns the value of attribute cookbook_name.



21
22
23
# File 'lib/chef/cookbook/cookbook_version_loader.rb', line 21

def cookbook_name
  @cookbook_name
end

#cookbook_pathsObject (readonly)

Returns the value of attribute cookbook_paths.



23
24
25
# File 'lib/chef/cookbook/cookbook_version_loader.rb', line 23

def cookbook_paths
  @cookbook_paths
end

#cookbook_settingsObject (readonly)

Returns the value of attribute cookbook_settings.



22
23
24
# File 'lib/chef/cookbook/cookbook_version_loader.rb', line 22

def cookbook_settings
  @cookbook_settings
end

#frozenObject (readonly)

Returns the value of attribute frozen.



25
26
27
# File 'lib/chef/cookbook/cookbook_version_loader.rb', line 25

def frozen
  @frozen
end

#metadata_filenamesObject (readonly)

Returns the value of attribute metadata_filenames.



24
25
26
# File 'lib/chef/cookbook/cookbook_version_loader.rb', line 24

def 
  
end

#uploaded_cookbook_version_fileObject (readonly)

Returns the value of attribute uploaded_cookbook_version_file.



26
27
28
# File 'lib/chef/cookbook/cookbook_version_loader.rb', line 26

def uploaded_cookbook_version_file
  @uploaded_cookbook_version_file
end

Instance Method Details

#apply_json_cookbook_version_metadata(file) ⇒ Object



188
189
190
191
192
193
194
195
196
# File 'lib/chef/cookbook/cookbook_version_loader.rb', line 188

def (file)
  begin
    data = Chef::JSONCompat.from_json(IO.read(file), :create_additions => false)
    .from_hash(data['metadata'])
  rescue JSON::ParserError
    Chef::Log.error("Couldn't parse cookbook metadata JSON for #@cookbook_name in " + file)
    raise
  end
end

#apply_json_metadata(file) ⇒ Object



179
180
181
182
183
184
185
186
# File 'lib/chef/cookbook/cookbook_version_loader.rb', line 179

def (file)
  begin
    .from_json(IO.read(file))
  rescue JSON::ParserError
    Chef::Log.error("Couldn't parse cookbook metadata JSON for #@cookbook_name in " + file)
    raise
  end
end

#apply_ruby_metadata(file) ⇒ Object



170
171
172
173
174
175
176
177
# File 'lib/chef/cookbook/cookbook_version_loader.rb', line 170

def (file)
  begin
    .from_file(file)
  rescue JSON::ParserError
    Chef::Log.error("Error evaluating metadata.rb for #@cookbook_name in " + file)
    raise
  end
end

#chefignoreObject



136
137
138
# File 'lib/chef/cookbook/cookbook_version_loader.rb', line 136

def chefignore
  @chefignore ||= Chefignore.new(File.basename(@cookbook_path))
end

#cookbook_versionObject



85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
# File 'lib/chef/cookbook/cookbook_version_loader.rb', line 85

def cookbook_version
  return nil if empty?

  Chef::CookbookVersion.new(@cookbook_name.to_sym, *@cookbook_paths).tap do |c|
    c.attribute_filenames  = cookbook_settings[:attribute_filenames].values
    c.definition_filenames = cookbook_settings[:definition_filenames].values
    c.recipe_filenames     = cookbook_settings[:recipe_filenames].values
    c.template_filenames   = cookbook_settings[:template_filenames].values
    c.file_filenames       = cookbook_settings[:file_filenames].values
    c.library_filenames    = cookbook_settings[:library_filenames].values
    c.resource_filenames   = cookbook_settings[:resource_filenames].values
    c.provider_filenames   = cookbook_settings[:provider_filenames].values
    c.root_filenames       = cookbook_settings[:root_filenames].values
    c.   = 
    c.             = (c)
    c.freeze_version if @frozen
  end
end

#empty?Boolean

Returns:

  • (Boolean)


122
123
124
# File 'lib/chef/cookbook/cookbook_version_loader.rb', line 122

def empty?
  @cookbook_settings.values.all? { |files_hash| files_hash.empty? } && .size == 0
end

#load_as(category, *path_glob) ⇒ Object



156
157
158
159
160
# File 'lib/chef/cookbook/cookbook_version_loader.rb', line 156

def load_as(category, *path_glob)
  Dir[File.join(@cookbook_path, *path_glob)].each do |file|
    @cookbook_settings[category][file[@relative_path, 1]] = file
  end
end

#load_cookbooksObject



51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
# File 'lib/chef/cookbook/cookbook_version_loader.rb', line 51

def load_cookbooks
  load_as(:attribute_filenames, 'attributes', '*.rb')
  load_as(:definition_filenames, 'definitions', '*.rb')
  load_as(:recipe_filenames, 'recipes', '*.rb')
  load_as(:library_filenames, 'libraries', '*.rb')
  load_recursively_as(:template_filenames, "templates", "*")
  load_recursively_as(:file_filenames, "files", "*")
  load_recursively_as(:resource_filenames, "resources", "*.rb")
  load_recursively_as(:provider_filenames, "providers", "*.rb")
  load_root_files

  remove_ignored_files

  if File.exists?(File.join(@cookbook_path, UPLOADED_COOKBOOK_VERSION_FILE))
    @uploaded_cookbook_version_file = File.join(@cookbook_path, UPLOADED_COOKBOOK_VERSION_FILE)
  end

  if File.exists?(File.join(@cookbook_path, "metadata.rb"))
     << File.join(@cookbook_path, "metadata.rb")
  elsif File.exists?(File.join(@cookbook_path, "metadata.json"))
     << File.join(@cookbook_path, "metadata.json")
  elsif @uploaded_cookbook_version_file
     << @uploaded_cookbook_version_file
  end

  # Set frozen based on .uploaded-cookbook-version.json
  set_frozen

  if empty?
    Chef::Log.warn "found a directory #{cookbook_name} in the cookbook path, but it contains no cookbook files. skipping."
  end
  @cookbook_settings
end

#load_recursively_as(category, category_dir, glob) ⇒ Object



148
149
150
151
152
153
154
# File 'lib/chef/cookbook/cookbook_version_loader.rb', line 148

def load_recursively_as(category, category_dir, glob)
  file_spec = File.join(@cookbook_path, category_dir, '**', glob)
  Dir.glob(file_spec, File::FNM_DOTMATCH).each do |file|
    next if File.directory?(file)
    @cookbook_settings[category][file[@relative_path, 1]] = file
  end
end

#load_root_filesObject



140
141
142
143
144
145
146
# File 'lib/chef/cookbook/cookbook_version_loader.rb', line 140

def load_root_files
  Dir.glob(File.join(@cookbook_path, '*'), File::FNM_DOTMATCH).each do |file|
    next if File.directory?(file)
    next if File.basename(file) == UPLOADED_COOKBOOK_VERSION_FILE
    @cookbook_settings[:root_filenames][file[@relative_path, 1]] = file
  end
end

#merge!(other_cookbook_loader) ⇒ Object



126
127
128
129
130
131
132
133
134
# File 'lib/chef/cookbook/cookbook_version_loader.rb', line 126

def merge!(other_cookbook_loader)
  other_cookbook_settings = other_cookbook_loader.cookbook_settings
  @cookbook_settings.each do |file_type, file_list|
    file_list.merge!(other_cookbook_settings[file_type])
  end
  .concat(other_cookbook_loader.)
  @cookbook_paths += other_cookbook_loader.cookbook_paths
  @frozen = true if other_cookbook_loader.frozen
end

#metadata(cookbook_version) ⇒ Object

Generates the Cookbook::Metadata object



105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
# File 'lib/chef/cookbook/cookbook_version_loader.rb', line 105

def (cookbook_version)
   = Chef::Cookbook::.new(cookbook_version)
  .each do ||
    case 
    when /\.rb$/
      ()
    when @uploaded_cookbook_version_file
      ()
    when /\.json$/
      ()
    else
      raise RuntimeError, "Invalid metadata file: #{metadata_file} for cookbook: #{cookbook_version}"
    end
  end
  
end

#remove_ignored_filesObject



162
163
164
165
166
167
168
# File 'lib/chef/cookbook/cookbook_version_loader.rb', line 162

def remove_ignored_files
  @cookbook_settings.each_value do |file_list|
    file_list.reject! do |relative_path, full_path|
      chefignore.ignored?(relative_path)
    end
  end
end

#set_frozenObject



198
199
200
201
202
203
204
205
206
207
208
# File 'lib/chef/cookbook/cookbook_version_loader.rb', line 198

def set_frozen
  if uploaded_cookbook_version_file
    begin
      data = Chef::JSONCompat.from_json(IO.read(uploaded_cookbook_version_file), :create_additions => false)
      @frozen = data['frozen?']
    rescue JSON::ParserError
      Chef::Log.error("Couldn't parse cookbook metadata JSON for #@cookbook_name in #{uploaded_cookbook_version_file}")
      raise
    end
  end
end