# class Puppet::Module

Support for modules

### Constants

FILETYPES

### Attributes

author[RW]
dependencies[RW]
description[RW]
environment[RW]
forge_name[RW]
license[RW]
name[R]
path[R]
project_page[RW]
puppetversion[RW]
source[RW]
summary[RW]
version[RW]

### Public Class Methods

find(modname, environment = nil) click to toggle source

Find and return the `module` that `path` belongs to. If `path` is absolute, or if there is no module whose name is the first component of `path`, return `nil`

    # File lib/puppet/module.rb, line 27
    def self.find(modname, environment = nil)
      return nil unless modname
      Puppet::Node::Environment.new(environment).module(modname)
    end

new(name, path, environment) click to toggle source

    # File lib/puppet/module.rb, line 38
    def initialize(name, path, environment)
      @name = name
      @path = path
      @environment = environment

      assert_validity

      load_metadata if has_metadata?

      validate_puppet_version
    end

### Public Instance Methods

dependencies_as_modules() click to toggle source

    # File lib/puppet/module.rb, line 168
    def dependencies_as_modules
      dependent_modules = []
      dependencies and dependencies.each do |dep|
        author, dep_name = dep["name"].split('/')
        found_module = environment.module(dep_name)
        dependent_modules << found_module if found_module
      end

      dependent_modules
    end

has_local_changes?() click to toggle source

    # File lib/puppet/module.rb, line 183
    def has_local_changes?
      changes = Puppet::ModuleTool::Applications::Checksummer.run(path)
      !changes.empty?
    end

has_metadata?() click to toggle source

    # File lib/puppet/module.rb, line 50
    def has_metadata?
      return false unless metadata_file

      return false unless FileTest.exist?(metadata_file)

      metadata = PSON.parse File.read(metadata_file)

      return metadata.is_a?(Hash) && !metadata.keys.empty?
    end

license_file() click to toggle source

    # File lib/puppet/module.rb, line 99
    def license_file
      return @license_file if defined?(@license_file)

      return @license_file = nil unless path
      @license_file = File.join(path, "License")
    end

load_metadata() click to toggle source

    # File lib/puppet/module.rb, line 106
    def load_metadata
      data = PSON.parse File.read(metadata_file)
      @forge_name = data['name'].gsub('-', '/') if data['name']

      [:source, :author, :version, :license, :puppetversion, :dependencies].each do |attr|
        unless value = data[attr.to_s]
          unless attr == :puppetversion
            raise MissingMetadata, "No #{attr} module metadata provided for #{self.name}"
          end
        end

        # NOTICE: The fallback to `versionRequirement` is something we'd like to
        # not have to support, but we have a reasonable number of releases that
        # don't use `version_requirement`. When we can deprecate this, we should.
        if attr == :dependencies
          value.tap do |dependencies|
            dependencies.each do |dep|
              dep['version_requirement'] ||= dep['versionRequirement'] || '>= 0.0.0'
            end
          end
        end

        send(attr.to_s + "=", value)
      end
    end

local_changes() click to toggle source

    # File lib/puppet/module.rb, line 188
    def local_changes
      Puppet::ModuleTool::Applications::Checksummer.run(path)
    end

match_manifests(rest) click to toggle source

Return the list of manifests matching the given glob pattern, defaulting to ‘init.{pp,rb}’ for empty modules.

    # File lib/puppet/module.rb, line 134
    def match_manifests(rest)
      pat = File.join(path, "manifests", rest || 'init')
      [manifest("init.pp"),manifest("init.rb")].compact + Dir.
        glob(pat + (File.extname(pat).empty? ? '.{pp,rb}' : '')).
        reject { |f| FileTest.directory?(f) }
    end

metadata_file() click to toggle source

    # File lib/puppet/module.rb, line 141
    def metadata_file
      return @metadata_file if defined?(@metadata_file)

      return @metadata_file = nil unless path
      @metadata_file = File.join(path, "metadata.json")
    end

modulepath() click to toggle source

    # File lib/puppet/module.rb, line 148
    def modulepath
      File.dirname(path) if path
    end

plugin_directory() click to toggle source

Find all plugin directories. This is used by the Plugins fileserving mount.

    # File lib/puppet/module.rb, line 153
    def plugin_directory
      subpath("lib")
    end

required_by() click to toggle source

    # File lib/puppet/module.rb, line 179
    def required_by
      environment.module_requirements[self.forge_name] || {}
    end

supports(name, version = nil) click to toggle source

    # File lib/puppet/module.rb, line 157
    def supports(name, version = nil)
      @supports ||= []
      @supports << [name, version]
    end

to_s() click to toggle source

    # File lib/puppet/module.rb, line 162
    def to_s
      result = "Module #{name}"
      result += "(#{path})" if path
      result
    end

unmet_dependencies() click to toggle source

Identify and mark unmet dependencies. A dependency will be marked unmet for the following reasons:

    * not installed and is thus considered missing
    * installed and does not meet the version requirements for this module
    * installed and doesn't use semantic versioning

Returns a list of hashes representing the details of an unmet dependency.

Example:

    [
      {
        :reason => :missing,
        :name   => 'puppetlabs-mysql',
        :version_constraint => 'v0.0.1',
        :mod_details => {
          :installed_version => '0.0.1'
        }
        :parent => {
          :name    => 'puppetlabs-bacula',
          :version => 'v1.0.0'
        }
      }
    ]

    # File lib/puppet/module.rb, line 218
    def unmet_dependencies
      unmet_dependencies = []
      return unmet_dependencies unless dependencies

      dependencies.each do |dependency|
        forge_name = dependency['name']
        version_string = dependency['version_requirement'] || '>= 0.0.0'

        dep_mod = begin
          environment.module_by_forge_name(forge_name)
        rescue => e
          nil
        end

        error_details = {
          :name => forge_name,
          :version_constraint => version_string.gsub(/^(?=\d)/, "v"),
          :parent => {
            :name => self.forge_name,
            :version => self.version.gsub(/^(?=\d)/, "v")
          },
          :mod_details => {
            :installed_version => dep_mod.nil? ? nil : dep_mod.version
          }
        }

        unless dep_mod
          error_details[:reason] = :missing
          unmet_dependencies << error_details
          next
        end

        if version_string
          begin
            required_version_semver_range = SemVer[version_string]
            actual_version_semver = SemVer.new(dep_mod.version)
          rescue ArgumentError
            error_details[:reason] = :non_semantic_version
            unmet_dependencies << error_details
            next
          end

          unless required_version_semver_range.include? actual_version_semver
            error_details[:reason] = :version_mismatch
            unmet_dependencies << error_details
            next
          end
        end
      end

      unmet_dependencies
    end

validate_puppet_version() click to toggle source

    # File lib/puppet/module.rb, line 271
    def validate_puppet_version
      return unless puppetversion and puppetversion != Puppet.version
      raise IncompatibleModule, "Module #{self.name} is only compatible with Puppet version #{puppetversion}, not #{Puppet.version}"
    end