Class: Berkshelf::Berksfile
- Inherits:
-
Object
- Object
- Berkshelf::Berksfile
- Extended by:
- Forwardable
- Defined in:
- lib/berkshelf/berksfile.rb
Overview
Constant Summary collapse
- @@active_group =
nil
Instance Attribute Summary collapse
- #cached_cookbooks ⇒ Array<Berkshelf::CachedCookbook> readonly
- #downloader ⇒ Berkshelf::Downloader readonly
-
#filepath ⇒ String
readonly
The path on disk to the file representing this instance of Berksfile.
Class Method Summary collapse
- .from_file(file) ⇒ Berksfile
-
.vendor(cookbooks, path) ⇒ String
Copy all cached_cookbooks to the given directory.
Instance Method Summary collapse
- #[](name) ⇒ Berkshelf::CookbookSource (also: #get_source)
-
#add_source(name, constraint = nil, options = {}) ⇒ Array<Berkshelf::CookbookSource]
Add a source of the given name and constraint to the array of sources.
-
#chef_api(value, options = {}) ⇒ Hash
Add a ‘Chef API’ default location which will be used to resolve cookbook sources that do not contain an explicit location.
-
#cookbook(*args) ⇒ Object
Add a cookbook source to the Berksfile to be retrieved and have it’s dependencies recursively retrieved and resolved.
- #group(*args) ⇒ Object
-
#groups ⇒ Hash
A hash containing group names as keys and an array of CookbookSources that are a member of that group as values.
- #has_source?(source) ⇒ Boolean
-
#initialize(path) ⇒ Berksfile
constructor
A new instance of Berksfile.
- #install(options = {}) ⇒ Array<Berkshelf::CachedCookbook>
-
#load(content) ⇒ Berksfile
Reload this instance of Berksfile with the given content.
-
#metadata(options = {}) ⇒ Object
Use a Cookbook metadata file to determine additional cookbook sources to retrieve.
-
#outdated(options = {}) ⇒ Hash
Get a list of all the cookbooks which have newer versions found on the community site versus what your current constraints allow.
- #remove_source(source) ⇒ Berkshelf::CookbookSource
-
#resolve(options = {}) ⇒ Array<Berkshelf::CachedCookbooks]
Finds a solution for the Berksfile and returns an array of CachedCookbooks.
-
#site(value) ⇒ Hash
Add a ‘Site’ default location which will be used to resolve cookbook sources that do not contain an explicit location.
- #sources(options = {}) ⇒ Array<Berkshelf::CookbookSource>
- #update(options = {}) ⇒ Object
- #upload(options = {}) ⇒ Object
Constructor Details
#initialize(path) ⇒ Berksfile
Returns a new instance of Berksfile.
78 79 80 81 82 83 |
# File 'lib/berkshelf/berksfile.rb', line 78 def initialize(path) @filepath = path @sources = Hash.new @downloader = Downloader.new(Berkshelf.cookbook_store) @cached_cookbooks = nil end |
Instance Attribute Details
#cached_cookbooks ⇒ Array<Berkshelf::CachedCookbook> (readonly)
73 74 75 |
# File 'lib/berkshelf/berksfile.rb', line 73 def cached_cookbooks @cached_cookbooks end |
#downloader ⇒ Berkshelf::Downloader (readonly)
70 71 72 |
# File 'lib/berkshelf/berksfile.rb', line 70 def downloader @downloader end |
#filepath ⇒ String (readonly)
Returns The path on disk to the file representing this instance of Berksfile.
67 68 69 |
# File 'lib/berkshelf/berksfile.rb', line 67 def filepath @filepath end |
Class Method Details
.from_file(file) ⇒ Berksfile
13 14 15 16 17 18 19 |
# File 'lib/berkshelf/berksfile.rb', line 13 def from_file(file) content = File.read(file) object = new(file) object.load(content) rescue Errno::ENOENT => e raise BerksfileNotFound, "No Berksfile or Berksfile.lock found at: #{file}" end |
.vendor(cookbooks, path) ⇒ String
Copy all cached_cookbooks to the given directory. Each cookbook will be contained in a directory named after the name of the cookbook.
31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 |
# File 'lib/berkshelf/berksfile.rb', line 31 def vendor(cookbooks, path) chefignore_file = [ File.join(Dir.pwd, 'chefignore'), File.join(Dir.pwd, 'cookbooks', 'chefignore') ].find { |f| File.exists?(f) } chefignore = chefignore_file && ::Chef::Cookbook::Chefignore.new(chefignore_file) path = File.(path) FileUtils.mkdir_p(path) scratch = Berkshelf.mktmpdir cookbooks.each do |cb| dest = File.join(scratch, cb.cookbook_name, "/") FileUtils.mkdir_p(dest) # Dir.glob does not support backslash as a File separator src = cb.path.to_s.gsub('\\', '/') files = Dir.glob(File.join(src, "*")) # Filter out files using chefignore files = chefignore.remove_ignores_from(files) if chefignore FileUtils.cp_r(files, dest) end FileUtils.remove_dir(path, force: true) FileUtils.mv(scratch, path) path end |
Instance Method Details
#[](name) ⇒ Berkshelf::CookbookSource Also known as: get_source
348 349 350 |
# File 'lib/berkshelf/berksfile.rb', line 348 def [](name) @sources[name] end |
#add_source(name, constraint = nil, options = {}) ⇒ Array<Berkshelf::CookbookSource]
Add a source of the given name and constraint to the array of sources.
253 254 255 256 257 258 259 260 261 262 263 264 265 |
# File 'lib/berkshelf/berksfile.rb', line 253 def add_source(name, constraint = nil, = {}) if has_source?(name) # Only raise an exception if the source is a true duplicate groups = ([:group].nil? || [:group].empty?) ? [:default] : [:group] if !(@sources[name].groups & groups).empty? raise DuplicateSourceDefined, "Berksfile contains multiple sources named '#{name}'. Use only one, or put them in different groups." end end [:constraint] = constraint @sources[name] = CookbookSource.new(name, ) end |
#chef_api(value, options = {}) ⇒ Hash
specifying the symbol :config as the value of the chef_api default location will attempt to use the contents of your Berkshelf configuration to find the Chef API to interact with.
Add a ‘Chef API’ default location which will be used to resolve cookbook sources that do not contain an explicit location.
237 238 239 |
# File 'lib/berkshelf/berksfile.rb', line 237 def chef_api(value, = {}) add_location(:chef_api, value, ) end |
#cookbook(name, version_constraint, options = {}) ⇒ Object #cookbook(name, options = {}) ⇒ Object
Add a cookbook source to the Berksfile to be retrieved and have it’s dependencies recursively retrieved and resolved.
152 153 154 155 156 157 158 159 160 161 162 163 |
# File 'lib/berkshelf/berksfile.rb', line 152 def cookbook(*args) = args.last.is_a?(Hash) ? args.pop : Hash.new name, constraint = args [:group] = Array([:group]) if @@active_group [:group] += @@active_group end add_source(name, constraint, ) end |
#group(*args) ⇒ Object
165 166 167 168 169 |
# File 'lib/berkshelf/berksfile.rb', line 165 def group(*args) @@active_group = args yield @@active_group = nil end |
#groups ⇒ Hash
Returns a hash containing group names as keys and an array of CookbookSources that are a member of that group as values
Example:
{
nautilus: [
#<Berkshelf::CookbookSource @name="nginx">,
#<Berkshelf::CookbookSource @name="mysql">,
],
skarner: [
#<Berkshelf::CookbookSource @name="nginx">
]
}.
333 334 335 336 337 338 339 340 341 342 |
# File 'lib/berkshelf/berksfile.rb', line 333 def groups {}.tap do |groups| sources.each do |source| source.groups.each do |group| groups[group] ||= [] groups[group] << source end end end end |
#has_source?(source) ⇒ Boolean
279 280 281 |
# File 'lib/berkshelf/berksfile.rb', line 279 def has_source?(source) @sources.has_key?(source.to_s) end |
#install(options = {}) ⇒ Array<Berkshelf::CachedCookbook>
364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 |
# File 'lib/berkshelf/berksfile.rb', line 364 def install( = {}) resolver = Resolver.new( self.downloader, sources: sources() ) @cached_cookbooks = resolver.resolve write_lockfile(resolver.sources) unless lockfile_present? if [:path] self.class.vendor(@cached_cookbooks, [:path]) end self.cached_cookbooks end |
#load(content) ⇒ Berksfile
Reload this instance of Berksfile with the given content. The content is a string that may contain terms from the included DSL.
525 526 527 528 529 530 531 532 |
# File 'lib/berkshelf/berksfile.rb', line 525 def load(content) begin instance_eval(content) rescue => e raise BerksfileReadError.new(e), "An error occurred while reading the Berksfile: #{e.to_s}" end self end |
#metadata(options = {}) ⇒ Object
Use a Cookbook metadata file to determine additional cookbook sources to retrieve. All sources found in the metadata will use the default locations set in the Berksfile (if any are set) or the default locations defined by Berkshelf.
179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 |
# File 'lib/berkshelf/berksfile.rb', line 179 def ( = {}) path = [:path] || File.dirname(filepath) = Berkshelf.(path) unless raise CookbookNotFound, "No 'metadata.rb' found at #{path}" end = Chef::Cookbook::Metadata.new .from_file(.to_s) name = if .name.empty? || .name.nil? File.basename(File.dirname()) else .name end constraint = "= #{.version}" add_source(name, constraint, path: File.dirname()) end |
#outdated(options = {}) ⇒ Hash
Get a list of all the cookbooks which have newer versions found on the community site versus what your current constraints allow
431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 |
# File 'lib/berkshelf/berksfile.rb', line 431 def outdated( = {}) outdated = Hash.new sources().each do |cookbook| location = cookbook.location || Location.init(cookbook.name, cookbook.version_constraint) if location.is_a?(SiteLocation) latest_version = SiteLocation.new(cookbook.name, cookbook.version_constraint).latest_version[0] unless cookbook.version_constraint.satisfies?(latest_version) outdated[cookbook] = latest_version end end end outdated end |
#remove_source(source) ⇒ Berkshelf::CookbookSource
271 272 273 |
# File 'lib/berkshelf/berksfile.rb', line 271 def remove_source(source) @sources.delete(source.to_s) end |
#resolve(options = {}) ⇒ Array<Berkshelf::CachedCookbooks]
Finds a solution for the Berksfile and returns an array of CachedCookbooks.
510 511 512 513 514 515 |
# File 'lib/berkshelf/berksfile.rb', line 510 def resolve( = {}) Resolver.new( self.downloader, sources: sources() ).resolve end |
#site(value) ⇒ Hash
specifying the symbol :opscode as the value of the site default location is an alias for the latest API of the Opscode Community Site.
Add a ‘Site’ default location which will be used to resolve cookbook sources that do not contain an explicit location.
216 217 218 |
# File 'lib/berkshelf/berksfile.rb', line 216 def site(value) add_location(:site, value) end |
#sources(options = {}) ⇒ Array<Berkshelf::CookbookSource>
295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 |
# File 'lib/berkshelf/berksfile.rb', line 295 def sources( = {}) l_sources = @sources.collect { |name, source| source }.flatten cookbooks = Array(.fetch(:cookbooks, nil)) except = Array(.fetch(:except, nil)).collect(&:to_sym) only = Array(.fetch(:only, nil)).collect(&:to_sym) case when !except.empty? && !only.empty? raise Berkshelf::ArgumentError, "Cannot specify both :except and :only" when !cookbooks.empty? if !except.empty? && !only.empty? Berkshelf.ui.warn "Cookbooks were specified, ignoring :except and :only" end l_sources.select { |source| [:cookbooks].include?(source.name) } when !except.empty? l_sources.select { |source| (except & source.groups).empty? } when !only.empty? l_sources.select { |source| !(only & source.groups).empty? } else l_sources end end |
#update(options = {}) ⇒ Object
388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 |
# File 'lib/berkshelf/berksfile.rb', line 388 def update( = {}) resolver = Resolver.new( self.downloader, sources: sources() ) cookbooks = resolver.resolve sources = resolver.sources missing_cookbooks = ([:cookbooks] - cookbooks.map(&:cookbook_name)) unless missing_cookbooks.empty? raise Berkshelf::CookbookNotFound, "Could not find cookbooks #{missing_cookbooks.collect{|cookbook| "'#{cookbook}'"}.join(', ')} in any of the sources. #{missing_cookbooks.size == 1 ? 'Is it' : 'Are they' } in your Berksfile?" end update_lockfile(sources) if [:path] self.class.vendor(cookbooks, [:path]) end cookbooks end |
#upload(options = {}) ⇒ Object
483 484 485 486 487 488 489 490 491 492 493 494 495 496 |
# File 'lib/berkshelf/berksfile.rb', line 483 def upload( = {}) uploader = Uploader.new() solution = resolve() solution.each do |cb| Berkshelf.formatter.upload cb.cookbook_name, cb.version, [:server_url] uploader.upload(cb, ) end rescue Ridley::Errors::ClientKeyFileNotFound => e msg = "Could not upload cookbooks: Missing Chef client key: '#{Berkshelf::Config.instance.chef.client_key}'." msg << " Generate or update your Berkshelf configuration that contains a valid path to a Chef client key." raise UploadFailure, msg end |