Class: Chef::Cookbook::Metadata

Inherits:
Object
  • Object
show all
Includes:
Mixin::FromFile, Mixin::ParamsValidate
Defined in:
lib/chef/cookbook/metadata.rb

Overview

Chef::Cookbook::Metadata

Chef::Cookbook::Metadata provides a convenient DSL for declaring metadata about Chef Cookbooks.

Direct Known Subclasses

MinimalMetadata

Constant Summary collapse

NAME =
'name'.freeze
DESCRIPTION =
'description'.freeze
LONG_DESCRIPTION =
'long_description'.freeze
MAINTAINER =
'maintainer'.freeze
MAINTAINER_EMAIL =
'maintainer_email'.freeze
LICENSE =
'license'.freeze
PLATFORMS =
'platforms'.freeze
DEPENDENCIES =
'dependencies'.freeze
RECOMMENDATIONS =
'recommendations'.freeze
SUGGESTIONS =
'suggestions'.freeze
CONFLICTING =
'conflicting'.freeze
PROVIDING =
'providing'.freeze
REPLACING =
'replacing'.freeze
ATTRIBUTES =
'attributes'.freeze
GROUPINGS =
'groupings'.freeze
RECIPES =
'recipes'.freeze
VERSION =
'version'.freeze
SOURCE_URL =
'source_url'.freeze
ISSUES_URL =
'issues_url'.freeze
COMPARISON_FIELDS =
[ :name, :description, :long_description, :maintainer,
:maintainer_email, :license, :platforms, :dependencies,
:recommendations, :suggestions, :conflicting, :providing,
:replacing, :attributes, :groupings, :recipes, :version,
:source_url, :issues_url ]
VERSION_CONSTRAINTS =
{:depends     => DEPENDENCIES,
:recommends  => RECOMMENDATIONS,
:suggests    => SUGGESTIONS,
:conflicts   => CONFLICTING,
:provides    => PROVIDING,
:replaces    => REPLACING }

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Mixin::FromFile

#class_from_file, #from_file

Methods included from Mixin::ParamsValidate

#lazy, #set_or_return, #validate

Constructor Details

#initializeMetadata

Builds a new Chef::Cookbook::Metadata object.

Parameters

cookbook<String>

An optional cookbook object

maintainer<String>

An optional maintainer

maintainer_email<String>

An optional maintainer email

license<String>::An optional license. Default is Apache v2.0

Returns

metadata<Chef::Cookbook::Metadata>



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/metadata.rb', line 96

def initialize
  @name =  nil

  @description = ''
  @long_description = ''
  @license = 'All rights reserved'

  @maintainer = nil
  @maintainer_email = nil

  @platforms = Mash.new
  @dependencies = Mash.new
  @recommendations = Mash.new
  @suggestions = Mash.new
  @conflicting = Mash.new
  @providing = Mash.new
  @replacing = Mash.new
  @attributes = Mash.new
  @groupings = Mash.new
  @recipes = Mash.new
  @version = Version.new("0.0.0")
  @source_url = ''
  @issues_url = ''

  @errors = []
end

Instance Attribute Details

#attributesObject (readonly)

Returns the value of attribute attributes.



81
82
83
# File 'lib/chef/cookbook/metadata.rb', line 81

def attributes
  @attributes
end

#conflictingObject (readonly)

Returns the value of attribute conflicting.



78
79
80
# File 'lib/chef/cookbook/metadata.rb', line 78

def conflicting
  @conflicting
end

#dependenciesObject (readonly)

Returns the value of attribute dependencies.



75
76
77
# File 'lib/chef/cookbook/metadata.rb', line 75

def dependencies
  @dependencies
end

#groupingsObject (readonly)

Returns the value of attribute groupings.



82
83
84
# File 'lib/chef/cookbook/metadata.rb', line 82

def groupings
  @groupings
end

#platformsObject (readonly)

Returns the value of attribute platforms.



74
75
76
# File 'lib/chef/cookbook/metadata.rb', line 74

def platforms
  @platforms
end

#providingObject (readonly)

Returns the value of attribute providing.



79
80
81
# File 'lib/chef/cookbook/metadata.rb', line 79

def providing
  @providing
end

#recipesObject (readonly)

Returns the value of attribute recipes.



83
84
85
# File 'lib/chef/cookbook/metadata.rb', line 83

def recipes
  @recipes
end

#recommendationsObject (readonly)

Returns the value of attribute recommendations.



76
77
78
# File 'lib/chef/cookbook/metadata.rb', line 76

def recommendations
  @recommendations
end

#replacingObject (readonly)

Returns the value of attribute replacing.



80
81
82
# File 'lib/chef/cookbook/metadata.rb', line 80

def replacing
  @replacing
end

#suggestionsObject (readonly)

Returns the value of attribute suggestions.



77
78
79
# File 'lib/chef/cookbook/metadata.rb', line 77

def suggestions
  @suggestions
end

#version(arg = nil) ⇒ Object (readonly)

Sets the current cookbook version, or returns it. Can be two or three digits, seperated by dots. ie: ‘2.1’, ‘1.5.4’ or ‘0.9’.

Parameters

version<String>

The curent version, as a string

Returns

version<String>

Returns the current version



238
239
240
# File 'lib/chef/cookbook/metadata.rb', line 238

def version
  @version
end

Class Method Details

.from_hash(o) ⇒ Object



505
506
507
508
509
# File 'lib/chef/cookbook/metadata.rb', line 505

def self.from_hash(o)
  cm = self.new()
  cm.from_hash(o)
  cm
end

.from_json(string) ⇒ Object



534
535
536
537
# File 'lib/chef/cookbook/metadata.rb', line 534

def self.from_json(string)
  o = Chef::JSONCompat.from_json(string)
  self.from_hash(o)
end

.validate_json(json_str) ⇒ Object



539
540
541
542
543
544
545
546
547
548
549
550
551
552
# File 'lib/chef/cookbook/metadata.rb', line 539

def self.validate_json(json_str)
  o = Chef::JSONCompat.from_json(json_str)
   = new()
  VERSION_CONSTRAINTS.each do |dependency_type, hash_key|
    if dependency_group = o[hash_key]
     dependency_group.each do |cb_name, constraints|
       if .respond_to?(method_name)
         .public_send(method_name, cb_name, *Array(constraints))
       end
     end
    end
  end
  true
end

Instance Method Details

#==(other) ⇒ Object



123
124
125
126
127
# File 'lib/chef/cookbook/metadata.rb', line 123

def ==(other)
  COMPARISON_FIELDS.inject(true) do |equal_so_far, field|
    equal_so_far && other.respond_to?(field) && (other.send(field) == send(field))
  end
end

#attribute(name, options) ⇒ Object

Adds an attribute that a user needs to configure for this cookbook. Takes a name (with the / notation for a nested attribute), followed by any of these options

display_name<String>:: What a UI should show for this attribute
description<String>:: A hint as to what this attr is for
choice<Array>:: An array of choices to present to the user.
calculated<Boolean>:: If true, the default value is calculated by the recipe and cannot be displayed.
type<String>:: "string" or "array" - default is "string"  ("hash" is supported for backwards compatibility)
required<String>:: Whether this attr is 'required', 'recommended' or 'optional' - default 'optional' (true/false values also supported for backwards compatibility)
recipes<Array>:: An array of recipes which need this attr set.
default<String>,<Array>,<Hash>:: The default value

Parameters

name<String>

The name of the attribute (‘foo’, or ‘apache2/log_dir’)

options<Hash>

The description of the options

Returns

options<Hash>

Returns the current options hash



440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
# File 'lib/chef/cookbook/metadata.rb', line 440

def attribute(name, options)
  validate(
    options,
    {
      :display_name => { :kind_of => String },
      :description => { :kind_of => String },
      :choice => { :kind_of => [ Array ], :default => [] },
      :calculated => { :equal_to => [ true, false ], :default => false },
      :type => { :equal_to => [ "string", "array", "hash", "symbol", "boolean", "numeric" ], :default => "string" },
      :required => { :equal_to => [ "required", "recommended", "optional", true, false ], :default => "optional" },
      :recipes => { :kind_of => [ Array ], :default => [] },
      :default => { :kind_of => [ String, Array, Hash, Symbol, Numeric, TrueClass, FalseClass ] },
      :source_url => { :kind_of => String },
      :issues_url => { :kind_of => String }
    }
  )
  options[:required] = remap_required_attribute(options[:required]) unless options[:required].nil?
  validate_choice_array(options)
  validate_calculated_default_rule(options)
  validate_choice_default_rule(options)

  @attributes[name] = options
  @attributes[name]
end

#conflicts(cookbook, *version_args) ⇒ Object

Adds a conflict for another cookbook, with version checking strings.

Parameters

cookbook<String>

The cookbook

version<String>

A version constraint of the form “OP VERSION”,

where OP is one of < <= = > >= ~> and VERSION has the form x.y.z or x.y.

Returns

versions<Array>

Returns the list of versions for the platform



339
340
341
342
343
344
# File 'lib/chef/cookbook/metadata.rb', line 339

def conflicts(cookbook, *version_args)
  version = new_args_format(:conflicts, cookbook, version_args)
  constraint = validate_version_constraint(:conflicts, cookbook, version)
  @conflicting[cookbook] = constraint.to_s
  @conflicting[cookbook]
end

#depends(cookbook, *version_args) ⇒ Object

Adds a dependency on another cookbook, with version checking strings.

Parameters

cookbook<String>

The cookbook

version<String>

A version constraint of the form “OP VERSION”,

where OP is one of < <= = > >= ~> and VERSION has the form x.y.z or x.y.

Returns

versions<Array>

Returns the list of versions for the platform



288
289
290
291
292
293
# File 'lib/chef/cookbook/metadata.rb', line 288

def depends(cookbook, *version_args)
  version = new_args_format(:depends, cookbook, version_args)
  constraint = validate_version_constraint(:depends, cookbook, version)
  @dependencies[cookbook] = constraint.to_s
  @dependencies[cookbook]
end

#description(arg = nil) ⇒ Object

Sets the current description, or returns it. Should be short - one line only!

Parameters

description<String>

The new description

Returns

description<String>

Returns the description



207
208
209
210
211
212
213
# File 'lib/chef/cookbook/metadata.rb', line 207

def description(arg=nil)
  set_or_return(
    :description,
    arg,
    :kind_of => [ String ]
  )
end

#errorsObject

A list of validation errors for this metadata object. See #valid? for comments about the validation criteria.

If there are any validation errors, one or more error strings will be returned. Otherwise an empty array is returned.

Returns

error messages<Array>

Whether this metadata object is valid



150
151
152
153
# File 'lib/chef/cookbook/metadata.rb', line 150

def errors
  run_validation
  @errors
end

#from_hash(o) ⇒ Object



511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
# File 'lib/chef/cookbook/metadata.rb', line 511

def from_hash(o)
  @name                         = o[NAME] if o.has_key?(NAME)
  @description                  = o[DESCRIPTION] if o.has_key?(DESCRIPTION)
  @long_description             = o[LONG_DESCRIPTION] if o.has_key?(LONG_DESCRIPTION)
  @maintainer                   = o[MAINTAINER] if o.has_key?(MAINTAINER)
  @maintainer_email             = o[MAINTAINER_EMAIL] if o.has_key?(MAINTAINER_EMAIL)
  @license                      = o[LICENSE] if o.has_key?(LICENSE)
  @platforms                    = o[PLATFORMS] if o.has_key?(PLATFORMS)
  @dependencies                 = handle_deprecated_constraints(o[DEPENDENCIES]) if o.has_key?(DEPENDENCIES)
  @recommendations              = handle_deprecated_constraints(o[RECOMMENDATIONS]) if o.has_key?(RECOMMENDATIONS)
  @suggestions                  = handle_deprecated_constraints(o[SUGGESTIONS]) if o.has_key?(SUGGESTIONS)
  @conflicting                  = handle_deprecated_constraints(o[CONFLICTING]) if o.has_key?(CONFLICTING)
  @providing                    = o[PROVIDING] if o.has_key?(PROVIDING)
  @replacing                    = handle_deprecated_constraints(o[REPLACING]) if o.has_key?(REPLACING)
  @attributes                   = o[ATTRIBUTES] if o.has_key?(ATTRIBUTES)
  @groupings                    = o[GROUPINGS] if o.has_key?(GROUPINGS)
  @recipes                      = o[RECIPES] if o.has_key?(RECIPES)
  @version                      = o[VERSION] if o.has_key?(VERSION)
  @source_url                   = o[SOURCE_URL] if o.has_key?(SOURCE_URL)
  @issues_url                   = o[ISSUES_URL] if o.has_key?(ISSUES_URL)
  self
end

#from_json(string) ⇒ Object



554
555
556
557
# File 'lib/chef/cookbook/metadata.rb', line 554

def from_json(string)
  o = Chef::JSONCompat.from_json(string)
  from_hash(o)
end

#grouping(name, options) ⇒ Object



465
466
467
468
469
470
471
472
473
474
475
# File 'lib/chef/cookbook/metadata.rb', line 465

def grouping(name, options)
  validate(
    options,
    {
      :title => { :kind_of => String },
      :description => { :kind_of => String }
    }
  )
  @groupings[name] = options
  @groupings[name]
end

#issues_url(arg = nil) ⇒ Object

Sets the cookbook’s issues URL, or returns it.

Parameters

issues_url<String>

The issues URL

Returns

issues_url<String>

Returns the current issues URL.



581
582
583
584
585
586
587
# File 'lib/chef/cookbook/metadata.rb', line 581

def issues_url(arg=nil)
  set_or_return(
    :issues_url,
    arg,
    :kind_of => [ String ]
  )
end

#license(arg = nil) ⇒ Object

Sets the current license, or returns it.

Parameters

license<String>

The current license.

Returns

license<String>

Returns the current license



192
193
194
195
196
197
198
# File 'lib/chef/cookbook/metadata.rb', line 192

def license(arg=nil)
  set_or_return(
    :license,
    arg,
    :kind_of => [ String ]
  )
end

#long_description(arg = nil) ⇒ Object

Sets the current long description, or returns it. Might come from a README, say.

Parameters

long_description<String>

The new long description

Returns

long_description<String>

Returns the long description



222
223
224
225
226
227
228
# File 'lib/chef/cookbook/metadata.rb', line 222

def long_description(arg=nil)
  set_or_return(
    :long_description,
    arg,
    :kind_of => [ String ]
  )
end

#maintainer(arg = nil) ⇒ Object

Sets the cookbooks maintainer, or returns it.

Parameters

maintainer<String>

The maintainers name

Returns

maintainer<String>

Returns the current maintainer.



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

def maintainer(arg=nil)
  set_or_return(
    :maintainer,
    arg,
    :kind_of => [ String ]
  )
end

#maintainer_email(arg = nil) ⇒ Object

Sets the maintainers email address, or returns it.

Parameters

maintainer_email<String>

The maintainers email address

Returns

maintainer_email<String>

Returns the current maintainer email.



177
178
179
180
181
182
183
# File 'lib/chef/cookbook/metadata.rb', line 177

def maintainer_email(arg=nil)
  set_or_return(
    :maintainer_email,
    arg,
    :kind_of => [ String ]
  )
end

#name(arg = nil) ⇒ Object

Sets the name of the cookbook, or returns it.

Parameters

name<String>

The curent cookbook name.

Returns

name<String>

Returns the current cookbook name.



253
254
255
256
257
258
259
# File 'lib/chef/cookbook/metadata.rb', line 253

def name(arg=nil)
  set_or_return(
    :name,
    arg,
    :kind_of => [ String ]
  )
end

#provides(cookbook, *version_args) ⇒ Object

Adds a recipe, definition, or resource provided by this cookbook.

Recipes are specified as normal Definitions are followed by (), and can include :params for prototyping Resources are the stringified version (service)

Parameters

recipe, definition, resource<String>

The thing we provide

version<String>

A version constraint of the form “OP VERSION”,

where OP is one of < <= = > >= ~> and VERSION has the form x.y.z or x.y.

Returns

versions<Array>

Returns the list of versions for the platform



360
361
362
363
364
365
# File 'lib/chef/cookbook/metadata.rb', line 360

def provides(cookbook, *version_args)
  version = new_args_format(:provides, cookbook, version_args)
  constraint = validate_version_constraint(:provides, cookbook, version)
  @providing[cookbook] = constraint.to_s
  @providing[cookbook]
end

#recipe(name, description) ⇒ Object

Adds a description for a recipe.

Parameters

recipe<String>

The recipe

description<String>

The description of the recipe

Returns

description<String>

Returns the current description



391
392
393
# File 'lib/chef/cookbook/metadata.rb', line 391

def recipe(name, description)
  @recipes[name] = description
end

#recipes_from_cookbook_version(cookbook) ⇒ Object

Sets the cookbook’s recipes to the list of recipes in the given cookbook. Any recipe that already has a description (if set by the #recipe method) will not be updated.

Parameters

cookbook<CookbookVersion>

CookbookVersion object representing the cookbook

description<String>

The description of the recipe

Returns

recipe_unqualified_names<Array>

An array of the recipe names given by the cookbook



405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
# File 'lib/chef/cookbook/metadata.rb', line 405

def recipes_from_cookbook_version(cookbook)
  cookbook.fully_qualified_recipe_names.map do |recipe_name|
    unqualified_name =
      if recipe_name =~ /::default$/
        self.name.to_s
      else
        recipe_name
      end

    @recipes[unqualified_name] ||= ""
    provides(unqualified_name)

    unqualified_name
  end
end

#recommends(cookbook, *version_args) ⇒ Object

Adds a recommendation for another cookbook, with version checking strings.

Parameters

cookbook<String>

The cookbook

version<String>

A version constraint of the form “OP VERSION”,

where OP is one of < <= = > >= ~> and VERSION has the form x.y.z or x.y.

Returns

versions<Array>

Returns the list of versions for the platform



305
306
307
308
309
310
# File 'lib/chef/cookbook/metadata.rb', line 305

def recommends(cookbook, *version_args)
  version = new_args_format(:recommends, cookbook,  version_args)
  constraint = validate_version_constraint(:recommends, cookbook, version)
  @recommendations[cookbook] = constraint.to_s
  @recommendations[cookbook]
end

#replaces(cookbook, *version_args) ⇒ Object

Adds a cookbook that is replaced by this one, with version checking strings.

Parameters

cookbook<String>

The cookbook we replace

version<String>

A version constraint of the form “OP VERSION”,

where OP is one of < <= = > >= ~> and VERSION has the form x.y.z or x.y.

Returns

versions<Array>

Returns the list of versions for the platform



376
377
378
379
380
381
# File 'lib/chef/cookbook/metadata.rb', line 376

def replaces(cookbook, *version_args)
  version = new_args_format(:replaces, cookbook, version_args)
  constraint = validate_version_constraint(:replaces, cookbook, version)
  @replacing[cookbook] = constraint.to_s
  @replacing[cookbook]
end

#source_url(arg = nil) ⇒ Object

Sets the cookbook’s source URL, or returns it.

Parameters

maintainer<String>

The source URL

Returns

source_url<String>

Returns the current source URL.



566
567
568
569
570
571
572
# File 'lib/chef/cookbook/metadata.rb', line 566

def source_url(arg=nil)
  set_or_return(
    :source_url,
    arg,
    :kind_of => [ String ]
  )
end

#suggests(cookbook, *version_args) ⇒ Object

Adds a suggestion for another cookbook, with version checking strings.

Parameters

cookbook<String>

The cookbook

version<String>

A version constraint of the form “OP VERSION”,

where OP is one of < <= = > >= ~> and VERSION has the formx.y.z or x.y.

Returns

versions<Array>

Returns the list of versions for the platform



322
323
324
325
326
327
# File 'lib/chef/cookbook/metadata.rb', line 322

def suggests(cookbook, *version_args)
  version = new_args_format(:suggests, cookbook, version_args)
  constraint = validate_version_constraint(:suggests, cookbook, version)
  @suggestions[cookbook] = constraint.to_s
  @suggestions[cookbook]
end

#supports(platform, *version_args) ⇒ Object

Adds a supported platform, with version checking strings.

Parameters

platform<String>,<Symbol>

The platform (like :ubuntu or :mac_os_x)

version<String>

A version constraint of the form “OP VERSION”,

where OP is one of < <= = > >= ~> and VERSION has the form x.y.z or x.y.

Returns

versions<Array>

Returns the list of versions for the platform



271
272
273
274
275
276
# File 'lib/chef/cookbook/metadata.rb', line 271

def supports(platform, *version_args)
  version = new_args_format(:supports, platform, version_args)
  constraint = validate_version_constraint(:supports, platform, version)
  @platforms[platform] = constraint.to_s
  @platforms[platform]
end

#to_hashObject



477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
# File 'lib/chef/cookbook/metadata.rb', line 477

def to_hash
  {
    NAME                   => self.name,
    DESCRIPTION            => self.description,
    LONG_DESCRIPTION       => self.long_description,
    MAINTAINER             => self.maintainer,
    MAINTAINER_EMAIL       => self.maintainer_email,
    LICENSE                => self.license,
    PLATFORMS              => self.platforms,
    DEPENDENCIES           => self.dependencies,
    RECOMMENDATIONS        => self.recommendations,
    SUGGESTIONS            => self.suggestions,
    CONFLICTING            => self.conflicting,
    PROVIDING              => self.providing,
    REPLACING              => self.replacing,
    ATTRIBUTES             => self.attributes,
    GROUPINGS              => self.groupings,
    RECIPES                => self.recipes,
    VERSION                => self.version,
    SOURCE_URL             => self.source_url,
    ISSUES_URL             => self.issues_url
  }
end

#to_json(*a) ⇒ Object



501
502
503
# File 'lib/chef/cookbook/metadata.rb', line 501

def to_json(*a)
  Chef::JSONCompat.to_json(to_hash, *a)
end

#valid?Boolean

Whether this metadata is valid. In order to be valid, all required fields must be set. Chef’s validation implementation checks the content of a given field when setting (and raises an error if the content does not meet the criteria), so the content of the fields is not considered when checking validity.

Returns

valid<Boolean>

Whether this metadata object is valid

Returns:

  • (Boolean)


137
138
139
140
# File 'lib/chef/cookbook/metadata.rb', line 137

def valid?
  run_validation
  @errors.empty?
end