class R10K::Puppetfile

Attributes

basedir[R]

@!attribute [r] basedir

@return [String] The base directory that contains the Puppetfile
environment[RW]

@!attribute [rw] environment

@return [R10K::Environment] Optional R10K::Environment that this Puppetfile belongs to.
force[RW]

@!attribute [rw] force

@return [Boolean] Overwrite any locally made changes
forge[R]

@!attribute [r] forge

@return [String] The URL to use for the Puppet Forge
moduledir[R]

@!attribute [r] moduledir

@return [String] The directory to install the modules #{basedir}/modules
modules[R]

@!attribute [r] modules

@return [Array<R10K::Module>]
puppetfile_path[R]

@!attrbute [r] #puppetfile_path

@return [String] The path to the Puppetfile

Public Class Methods

new(basedir, moduledir = nil, puppetfile_path = nil, puppetfile_name = nil, force = nil ) click to toggle source

@param [String] basedir @param [String] moduledir The directory to install the modules, default to #{basedir}/modules @param [String] #puppetfile_path The path to the Puppetfile, default to #{basedir}/Puppetfile @param [String] puppetfile_name The name of the Puppetfile, default to 'Puppetfile' @param [Boolean] force Shall we overwrite locally made changes?

# File lib/r10k/puppetfile.rb, line 45
def initialize(basedir, moduledir = nil, puppetfile_path = nil, puppetfile_name = nil, force = nil )
  @basedir         = basedir
  @force           = force || false
  @moduledir       = moduledir  || File.join(basedir, 'modules')
  @puppetfile_path = puppetfile_path || File.join(basedir, 'Puppetfile')

  @modules = []
  @managed_content = {}
  @forge   = 'forgeapi.puppetlabs.com'

  @loaded = false
end

Public Instance Methods

accept(visitor) click to toggle source
# File lib/r10k/puppetfile.rb, line 148
def accept(visitor)
  visitor.visit(:puppetfile, self) do
    modules.each do |mod|
      mod.accept(visitor)
    end
  end
end
add_module(name, args) click to toggle source

@param [String] name @param [*Object] args

# File lib/r10k/puppetfile.rb, line 102
def add_module(name, args)
  if args.is_a?(Hash) && install_path = args.delete(:install_path)
    install_path = resolve_install_path(install_path)
    validate_install_path(install_path, name)
  else
    install_path = @moduledir
  end

  # Keep track of all the content this Puppetfile is managing to enable purging.
  @managed_content[install_path] = Array.new unless @managed_content.has_key?(install_path)

  mod = R10K::Module.new(name, install_path, args, @environment)

  @managed_content[install_path] << mod.name
  @modules << mod
end
desired_contents() click to toggle source

Returns an array of the full paths to all the content being managed. @note This implements a required method for the Purgeable mixin @return [Array<String>]

# File lib/r10k/puppetfile.rb, line 130
def desired_contents
  self.load unless @loaded

  @managed_content.flat_map do |install_path, modnames|
    modnames.collect { |name| File.join(install_path, name) }
  end
end
load() click to toggle source
# File lib/r10k/puppetfile.rb, line 58
def load
  if File.readable? @puppetfile_path
    self.load!
  else
    logger.debug _("Puppetfile %{path} missing or unreadable") % {path: @puppetfile_path.inspect}
  end
end
load!() click to toggle source
# File lib/r10k/puppetfile.rb, line 66
def load!
  dsl = R10K::Puppetfile::DSL.new(self)
  dsl.instance_eval(puppetfile_contents, @puppetfile_path)
  validate_no_duplicate_names(@modules)
  @loaded = true
rescue SyntaxError, LoadError, ArgumentError => e
  raise R10K::Error.wrap(e, _("Failed to evaluate %{path}") % {path: @puppetfile_path})
end
managed_directories() click to toggle source
# File lib/r10k/puppetfile.rb, line 121
def managed_directories
  self.load unless @loaded

  @managed_content.keys
end
purge_exclusions() click to toggle source
# File lib/r10k/puppetfile.rb, line 138
def purge_exclusions
  exclusions = managed_directories

  if environment && environment.respond_to?(:desired_contents)
    exclusions += environment.desired_contents
  end

  exclusions
end
set_forge(forge) click to toggle source

@param [String] forge

# File lib/r10k/puppetfile.rb, line 76
def set_forge(forge)
  @forge = forge
end
set_moduledir(moduledir) click to toggle source

@param [String] moduledir

# File lib/r10k/puppetfile.rb, line 92
def set_moduledir(moduledir)
  @moduledir = if Pathname.new(moduledir).absolute?
    moduledir
  else
    File.join(basedir, moduledir)
  end
end
validate_no_duplicate_names(modules) click to toggle source

@param [Array<String>] modules

# File lib/r10k/puppetfile.rb, line 81
def validate_no_duplicate_names(modules)
  dupes = modules
          .group_by { |mod| mod.name }
          .select { |_, v| v.size > 1 }.map(&:first)
  unless dupes.empty?
    logger.warn _('Puppetfiles should not contain duplicate module names and will result in an error in r10k v3.x.')
    logger.warn _("Remove the duplicates of the following modules: %{dupes}" % {dupes: dupes.join(" ")})
  end
end

Private Instance Methods

puppetfile_contents() click to toggle source
# File lib/r10k/puppetfile.rb, line 158
def puppetfile_contents
  File.read(@puppetfile_path)
end
resolve_install_path(path) click to toggle source
# File lib/r10k/puppetfile.rb, line 162
def resolve_install_path(path)
  pn = Pathname.new(path)

  unless pn.absolute?
    pn = Pathname.new(File.join(basedir, path))
  end

  # .cleanpath is as good as we can do without touching the filesystem.
  # The .realpath methods will also choke if some of the intermediate
  # paths are missing, even though we will create them later as needed.
  pn.cleanpath.to_s
end
validate_install_path(path, modname) click to toggle source
# File lib/r10k/puppetfile.rb, line 175
def validate_install_path(path, modname)
  real_basedir = Pathname.new(basedir).cleanpath.to_s

  unless /^#{Regexp.escape(real_basedir)}.*/ =~ path
    raise R10K::Error.new("Puppetfile cannot manage content '#{modname}' outside of containing environment: #{path} is not within #{real_basedir}")
  end

  true
end