class PuppetForge::V3::Metadata

This class provides a data structure representing a module’s metadata. @api private

Constants

DEFAULTS

Attributes

module_name[RW]
name[RW]

Public Class Methods

new() click to toggle source
# File lib/puppet_forge/v3/metadata.rb, line 26
def initialize
  @data = DEFAULTS.dup
  @data['dependencies'] = @data['dependencies'].dup
end

Public Instance Methods

add_dependency(name, version_requirement=nil, repository=nil) click to toggle source

Validates the name and version_requirement for a dependency, then creates the Dependency and adds it. Returns the Dependency that was added.

# File lib/puppet_forge/v3/metadata.rb, line 61
def add_dependency(name, version_requirement=nil, repository=nil)
  validate_name(name)
  validate_version_range(version_requirement) if version_requirement

  if dup = @data['dependencies'].find { |d| d.full_module_name == name && d.version_requirement != version_requirement }
    raise ArgumentError, "Dependency conflict for #{full_module_name}: Dependency #{name} was given conflicting version requirements #{version_requirement} and #{dup.version_requirement}. Verify that there are no duplicates in the metadata.json or the Modulefile."
  end

  dep = Dependency.new(name, version_requirement, repository)
  @data['dependencies'].add(dep)

  dep
end
dashed_name() click to toggle source

Returns a filesystem-friendly version of this module name.

# File lib/puppet_forge/v3/metadata.rb, line 32
def dashed_name
  PuppetForge::V3.normalize_name(@data['name']) if @data['name']
end
Also aliased as: full_module_name
dependencies() click to toggle source
# File lib/puppet_forge/v3/metadata.rb, line 83
def dependencies
  @data['dependencies'].to_a
end
description() click to toggle source

Provides an accessor for the now defunct ‘description’ property. This addresses a regression in Puppet 3.6.x where previously valid templates refering to the ‘description’ property were broken. @deprecated

# File lib/puppet_forge/v3/metadata.rb, line 79
def description
  @data['description']
end
full_module_name()
Alias for: dashed_name
method_missing(name, *args) click to toggle source

Expose any metadata keys as callable reader methods.

Calls superclass method
# File lib/puppet_forge/v3/metadata.rb, line 108
def method_missing(name, *args)
  return @data[name.to_s] if @data.key? name.to_s
  super
end
release_name() click to toggle source

Returns a string that uniquely represents this version of this module.

# File lib/puppet_forge/v3/metadata.rb, line 37
def release_name
  return nil unless @data['name'] && @data['version']
  [ dashed_name, @data['version'] ].join('-')
end
to_data_hash()
Alias for: to_hash
to_hash() click to toggle source

Returns a hash of the module’s metadata. Used by Puppet’s automated serialization routines.

@see Puppet::Network::FormatSupport#to_data_hash

# File lib/puppet_forge/v3/metadata.rb, line 91
def to_hash
  @data
end
Also aliased as: to_data_hash
to_json() click to toggle source
# File lib/puppet_forge/v3/metadata.rb, line 96
def to_json
  data = @data.dup.merge('dependencies' => dependencies)

  contents = data.keys.map do |k|
    value = (JSON.pretty_generate(data[k]) rescue data[k].to_json)
    "#{k.to_json}: #{value}"
  end

  "{\n" + contents.join(",\n").gsub(/^/, '  ') + "\n}\n"
end
update(data, with_dependencies = true) click to toggle source

Merges the current set of metadata with another metadata hash. This method also handles the validation of module names and versions, in an effort to be proactive about module publishing constraints.

# File lib/puppet_forge/v3/metadata.rb, line 48
def update(data, with_dependencies = true)
  process_name(data) if data['name']
  process_version(data) if data['version']
  process_source(data) if data['source']
  merge_dependencies(data) if with_dependencies && data['dependencies']

  @data.merge!(data)
  return self
end

Private Instance Methods

merge_dependencies(data) click to toggle source

Validates and parses the dependencies.

# File lib/puppet_forge/v3/metadata.rb, line 150
def merge_dependencies(data)
  data['dependencies'].each do |dep|
    add_dependency(dep['name'], dep['version_requirement'], dep['repository'])
  end

  # Clear dependencies so @data dependencies are not overwritten
  data.delete 'dependencies'
end
process_name(data) click to toggle source

Do basic validation and parsing of the name parameter.

# File lib/puppet_forge/v3/metadata.rb, line 116
def process_name(data)
  validate_name(data['name'])
  author, @module_name = data['name'].split(/[-\/]/, 2)

  data['author'] ||= author if @data['author'] == DEFAULTS['author']
end
process_source(data) click to toggle source

Do basic parsing of the source parameter. If the source is hosted on GitHub, we can predict sensible defaults for both project_page and issues_url.

# File lib/puppet_forge/v3/metadata.rb, line 131
def process_source(data)
  if data['source'] =~ %r[://]
    source_uri = URI.parse(data['source'])
  else
    source_uri = URI.parse("http://#{data['source']}")
  end

  if source_uri.host =~ /^(www\.)?github\.com$/
    source_uri.scheme = 'https'
    source_uri.path.sub!(/\.git$/, '')
    data['project_page'] ||= @data['project_page'] || source_uri.to_s
    data['issues_url'] ||= @data['issues_url'] || source_uri.to_s.sub(/\/*$/, '') + '/issues'
  end

rescue URI::Error
  return
end
process_version(data) click to toggle source

Do basic validation on the version parameter.

# File lib/puppet_forge/v3/metadata.rb, line 124
def process_version(data)
  validate_version(data['version'])
end
validate_name(name) click to toggle source

Validates that the given module name is both namespaced and well-formed.

# File lib/puppet_forge/v3/metadata.rb, line 160
def validate_name(name)
  return if name =~ /\A[a-z0-9]+[-\/][a-z][a-z0-9_]*\Z/i

  namespace, modname = name.split(/[-\/]/, 2)
  modname = :namespace_missing if namespace == ''

  err = case modname
  when nil, '', :namespace_missing
    "the field must be a namespaced module name"
  when /[^a-z0-9_]/i
    "the module name contains non-alphanumeric (or underscore) characters"
  when /^[^a-z]/i
    "the module name must begin with a letter"
  else
    "the namespace contains non-alphanumeric characters"
  end

  raise ArgumentError, "Invalid 'name' field in metadata.json: #{err}"
end
validate_version(version) click to toggle source

Validates that the version string can be parsed by SemanticPuppet.

# File lib/puppet_forge/v3/metadata.rb, line 181
def validate_version(version)
  return if SemanticPuppet::Version.valid?(version)

  err = "version string cannot be parsed as a valid Semantic Version"
  raise ArgumentError, "Invalid 'version' field in metadata.json: #{err}"
end
validate_version_range(version_range) click to toggle source

Validates that the version range can be parsed by SemanticPuppet.

# File lib/puppet_forge/v3/metadata.rb, line 189
def validate_version_range(version_range)
  SemanticPuppet::VersionRange.parse(version_range)
rescue ArgumentError => e
  raise ArgumentError, "Invalid 'version_range' field in metadata.json: #{e}"
end