def run
name = @name.tr('/', '-')
version = options[:version] || '>= 0.0.0'
results = { :action => :install, :module_name => name, :module_version => version }
begin
if mod = installed_modules[name]
unless forced?
if Semantic::VersionRange.parse(version).include? mod.version
results[:result] = :noop
results[:version] = mod.version
return results
else
changes = Checksummer.run(installed_modules[name].mod.path) rescue []
raise AlreadyInstalledError,
:module_name => name,
:installed_version => installed_modules[name].version,
:requested_version => options[:version] || :latest,
:local_changes => changes
end
end
end
@install_dir.prepare(name, options[:version] || 'latest')
results[:install_dir] = @install_dir.target
unless @local_tarball && @ignore_dependencies
Puppet.notice "Downloading from #{module_repository.host} ..."
end
if @ignore_dependencies
graph = build_single_module_graph(name, version)
else
graph = build_dependency_graph(name, version)
end
unless forced?
add_module_name_constraints_to_graph(graph)
end
installed_modules.each do |mod, release|
mod = mod.tr('/', '-')
next if mod == name
version = release.version
unless forced?
">=#{version} #{version.major}.x".tap do |range|
graph.add_constraint('installed', mod, range) do |node|
Semantic::VersionRange.parse(range).include? node.version
end
end
release.mod.dependencies.each do |dep|
dep_name = dep['name'].tr('/', '-')
dep['version_requirement'].tap do |range|
graph.add_constraint("#{mod} constraint", dep_name, range) do |node|
Semantic::VersionRange.parse(range).include? node.version
end
end
end
end
end
if graph.dependencies[name].empty?
raise NoCandidateReleasesError, results.merge(:module_name => name, :source => module_repository.host, :requested_version => options[:version] || :latest)
end
begin
Puppet.info "Resolving dependencies ..."
releases = Semantic::Dependency.resolve(graph)
rescue Semantic::Dependency::UnsatisfiableGraph
raise NoVersionsSatisfyError, results.merge(:requested_name => name)
end
unless forced?
releases.each do |rel|
if mod = installed_modules_source.by_name[rel.name.split('-').last]
next if mod.has_metadata? && mod.forge_name.tr('/', '-') == rel.name
if rel.name != name
dependency = {
:name => rel.name,
:version => rel.version
}
end
raise InstallConflictError,
:requested_module => name,
:requested_version => options[:version] || 'latest',
:dependency => dependency,
:directory => mod.path,
:metadata => mod.metadata
end
end
end
Puppet.info "Preparing to install ..."
releases.each { |release| release.prepare }
Puppet.notice 'Installing -- do not interrupt ...'
releases.each do |release|
installed = installed_modules[release.name]
if forced? || installed.nil?
release.install(Pathname.new(results[:install_dir]))
else
release.install(Pathname.new(installed.mod.modulepath))
end
end
results[:result] = :success
results[:installed_modules] = releases
results[:graph] = [ build_install_graph(releases.first, releases) ]
rescue ModuleToolError, ForgeError => err
results[:error] = {
:oneline => err.message,
:multiline => err.multiline,
}
ensure
results[:result] ||= :failure
end
results
end