module Puppet::ModuleTool::Shared

Public Instance Methods

annotated_version(mod, versions) click to toggle source
# File lib/puppet/module_tool/shared_behaviors.rb, line 59
def annotated_version(mod, versions)
  if versions.empty?
    return implicit_version(mod)
  else
    return "#{implicit_version(mod)}: #{versions.last}"
  end
end
download_tarballs(graph, default_path, forge) click to toggle source
# File lib/puppet/module_tool/shared_behaviors.rb, line 143
def download_tarballs(graph, default_path, forge)
  graph.map do |release|
    begin
      if release[:tarball]
        cache_path = Pathname(release[:tarball])
      else
        cache_path = forge.retrieve(release[:file])
      end
    rescue OpenURI::HTTPError => e
      raise RuntimeError, "Could not download module: #{e.message}"
    end

    [
      { (release[:path] ||= default_path) => cache_path},
      *download_tarballs(release[:dependencies], default_path, forge)
    ]
  end.flatten
end
get_local_constraints() click to toggle source
# File lib/puppet/module_tool/shared_behaviors.rb, line 5
def get_local_constraints
  @local      = Hash.new { |h,k| h[k] = { } }
  @conditions = Hash.new { |h,k| h[k] = [] }
  @installed  = Hash.new { |h,k| h[k] = [] }

  @environment.modules_by_path.values.flatten.each do |mod|
    mod_name = (mod.forge_name || mod.name).gsub('/', '-')
    @installed[mod_name] << mod
    d = @local["#{mod_name}@#{mod.version}"]
    (mod.dependencies || []).each do |hash|
      name, conditions = hash['name'], hash['version_requirement']
      name = name.gsub('/', '-')
      d[name] = conditions
      @conditions[name] << {
        :module => mod_name,
        :version => mod.version,
        :dependency => conditions
      }
    end
  end
end
get_remote_constraints(forge) click to toggle source
# File lib/puppet/module_tool/shared_behaviors.rb, line 27
def get_remote_constraints(forge)
  @remote   = Hash.new { |h,k| h[k] = { } }
  @urls     = {}
  @versions = Hash.new { |h,k| h[k] = [] }

  Puppet.notice "Downloading from #{forge.uri} ..."
  author, modname = Puppet::ModuleTool.username_and_modname_from(@module_name)
  info = forge.remote_dependency_info(author, modname, @options[:version])
  info.each do |pair|
    mod_name, releases = pair
    mod_name = mod_name.gsub('/', '-')
    releases.each do |rel|
      semver = SemVer.new(rel['version'] || '0.0.0') rescue SemVer.MIN
      @versions[mod_name] << { :vstring => rel['version'], :semver => semver }
      @versions[mod_name].sort! { |a, b| a[:semver] <=> b[:semver] }
      @urls["#{mod_name}@#{rel['version']}"] = rel['file']
      d = @remote["#{mod_name}@#{rel['version']}"]
      (rel['dependencies'] || []).each do |name, conditions|
        d[name.gsub('/', '-')] = conditions
      end
    end
  end
end
implicit_version(mod) click to toggle source
# File lib/puppet/module_tool/shared_behaviors.rb, line 51
def implicit_version(mod)
  return :latest if @conditions[mod].empty?
  if @conditions[mod].all? { |c| c[:queued] || c[:module] == :you }
    return :latest
  end
  return :best
end
resolve_constraints(dependencies, source = [{:name => :you}], seen = {}, action = @action) click to toggle source
# File lib/puppet/module_tool/shared_behaviors.rb, line 67
def resolve_constraints(dependencies, source = [{:name => :you}], seen = {}, action = @action)
  dependencies = dependencies.map do |mod, range|
    source.last[:dependency] = range

    @conditions[mod] << {
      :module     => source.last[:name],
      :version    => source.last[:version],
      :dependency => range,
      :queued     => true
    }

    if @force
      range = SemVer[@version] rescue SemVer['>= 0.0.0']
    else
      range = (@conditions[mod]).map do |r|
        SemVer[r[:dependency]] rescue SemVer['>= 0.0.0']
      end.inject(&:&)
    end

    if @action == :install && seen.include?(mod)
      next if range === seen[mod][:semver]

      req_module   = @module_name
      req_versions = @versions["#{@module_name}"].map { |v| v[:semver] }
      raise InvalidDependencyCycleError,
        :module_name       => mod,
        :source            => (source + [{ :name => mod, :version => source.last[:dependency] }]),
        :requested_module  => req_module,
        :requested_version => @version || annotated_version(req_module, req_versions),
        :conditions        => @conditions
    end

    if !(@force || @installed[mod].empty? || source.last[:name] == :you)
      next if range === SemVer.new(@installed[mod].first.version)
      action = :upgrade
    elsif @installed[mod].empty?
      action = :install
    end

    if action == :upgrade
      @conditions.each { |_, conds| conds.delete_if { |c| c[:module] == mod } }
    end

    valid_versions = @versions["#{mod}"].select { |h| range === h[:semver] }

    unless version = valid_versions.last
      req_module   = @module_name
      req_versions = @versions["#{@module_name}"].map { |v| v[:semver] }
      raise NoVersionsSatisfyError,
        :requested_name    => req_module,
        :requested_version => @version || annotated_version(req_module, req_versions),
        :installed_version => @installed[@module_name].empty? ? nil : @installed[@module_name].first.version,
        :dependency_name   => mod,
        :conditions        => @conditions[mod],
        :action            => @action
    end

    seen[mod] = version

    {
      :module           => mod,
      :version          => version,
      :action           => action,
      :previous_version => @installed[mod].empty? ? nil : @installed[mod].first.version,
      :file             => @urls["#{mod}@#{version[:vstring]}"],
      :path             => action == :install ? @options[:target_dir] : (@installed[mod].empty? ? @options[:target_dir] : @installed[mod].first.modulepath),
      :dependencies     => []
    }
  end.compact
  dependencies.each do |mod|
    deps = @remote["#{mod[:module]}@#{mod[:version][:vstring]}"].sort_by(&:first)
    mod[:dependencies] = resolve_constraints(deps, source + [{ :name => mod[:module], :version => mod[:version][:vstring] }], seen, :install)
  end unless @ignore_dependencies
  return dependencies
end