diff --git a/lib/librarian/puppet/action/resolve.rb b/lib/librarian/puppet/action/resolve.rb index 9c39f6c6..6b2b30b9 100644 --- a/lib/librarian/puppet/action/resolve.rb +++ b/lib/librarian/puppet/action/resolve.rb @@ -1,4 +1,5 @@ require 'librarian/action/resolve' +require 'librarian/puppet/resolver' module Librarian module Puppet @@ -15,6 +16,10 @@ def run end end + def resolver + Resolver.new(environment) + end + end end end diff --git a/lib/librarian/puppet/dependency.rb b/lib/librarian/puppet/dependency.rb index c5d6bd44..5338554f 100644 --- a/lib/librarian/puppet/dependency.rb +++ b/lib/librarian/puppet/dependency.rb @@ -5,13 +5,21 @@ class Dependency < Librarian::Dependency include Librarian::Puppet::Util - def initialize(name, requirement, source) + attr_accessor :parent + private :parent= + + def initialize(name, requirement, source, parent = nil) # Issue #235 fail if forge source is not defined raise Error, "forge entry is not defined in Puppetfile" if source.instance_of?(Array) && source.empty? + self.parent = parent super(normalize_name(name), requirement, source) end + def to_s + "#{name} (#{requirement}) <#{source}> (from #{parent.nil? ? '' : parent})" + end + end end diff --git a/lib/librarian/puppet/dsl.rb b/lib/librarian/puppet/dsl.rb index 9ea48bdf..602f7645 100644 --- a/lib/librarian/puppet/dsl.rb +++ b/lib/librarian/puppet/dsl.rb @@ -37,6 +37,37 @@ def receiver(target) Receiver.new(target) end + def run(specfile = nil, sources = []) + specfile, sources = nil, specfile if specfile.kind_of?(Array) && sources.empty? + + Target.new(self).tap do |target| + target.precache_sources(sources) + debug_named_source_cache("Pre-Cached Sources", target) + + specfile ||= Proc.new if block_given? + + if specfile.kind_of?(Pathname) and !File.exists?(specfile) + debug { "Specfile #{specfile} not found, using defaults" } unless specfile.nil? + receiver(target).run(specfile, &default_specfile) + else + receiver(target).run(specfile) + end + + post_process_target(target) + + debug_named_source_cache("Post-Cached Sources", target) + end.to_spec + end + + class Target < Librarian::Dsl::Target + def dependency(name, *args) + options = args.last.is_a?(Hash) ? args.pop : {} + source = source_from_options(options) || @source + dep = dependency_type.new(name, args, source, 'Puppetfile') + @dependencies << dep + end + end + class Receiver < Librarian::Dsl::Receiver attr_reader :specfile, :working_path diff --git a/lib/librarian/puppet/lockfile.rb b/lib/librarian/puppet/lockfile.rb index f2053eb8..e51ce9c6 100644 --- a/lib/librarian/puppet/lockfile.rb +++ b/lib/librarian/puppet/lockfile.rb @@ -25,7 +25,46 @@ class << manifests_index alias_method :old_lookup, :[] define_method(:[]) { |k| self.old_lookup(normalize_name(k)) } end - super(lines, manifests_index) + dependencies = [] + while lines.first =~ /^ {2}([\w\-\/]+)(?: \((.*)\))?$/ + lines.shift + name, requirement = $1, $2.split(/,\s*/) + dependencies << environment.dsl_class.dependency_type.new(name, requirement, manifests_index[name].source, 'lockfile') + end + dependencies + end + + def compile_placeholder_manifests(sources_ast) + manifests = {} + sources_ast.each do |source_ast| + source_type = source_ast[:type] + source = source_type.from_lock_options(environment, source_ast[:options]) + source_ast[:manifests].each do |manifest_name, manifest_ast| + manifests[manifest_name] = ManifestPlaceholder.new( + source, + manifest_name, + manifest_ast[:version], + manifest_ast[:dependencies].map do |k, v| + environment.dsl_class.dependency_type.new(k, v, nil, manifest_name) + end + ) + end + end + manifests + end + + def compile(sources_ast) + manifests = compile_placeholder_manifests(sources_ast) + manifests = manifests.map do |name, manifest| + dependencies = manifest.dependencies.map do |d| + environment.dsl_class.dependency_type.new(d.name, d.requirement, manifests[d.name].source, name) + end + real = Manifest.new(manifest.source, manifest.name) + real.version = manifest.version + real.dependencies = manifest.dependencies + real + end + ManifestSet.sort(manifests) end end diff --git a/lib/librarian/puppet/resolver.rb b/lib/librarian/puppet/resolver.rb new file mode 100644 index 00000000..33cc1b1b --- /dev/null +++ b/lib/librarian/puppet/resolver.rb @@ -0,0 +1,21 @@ +require 'librarian/resolver' + +module Librarian + module Puppet + class Resolver < Librarian::Resolver + + class Implementation < Librarian::Resolver::Implementation + def sourced_dependency_for(dependency) + return dependency if dependency.source + + source = dependency_source_map[dependency.name] || default_source + dependency.class.new(dependency.name, dependency.requirement, source, dependency.parent) + end + end + + def implementation(spec) + Implementation.new(self, spec, :cyclic => cyclic) + end + end + end +end diff --git a/lib/librarian/puppet/source/forge.rb b/lib/librarian/puppet/source/forge.rb index 0cc31505..feeed648 100644 --- a/lib/librarian/puppet/source/forge.rb +++ b/lib/librarian/puppet/source/forge.rb @@ -144,7 +144,7 @@ def fetch_version(name, version_uri) def fetch_dependencies(name, version, version_uri) repo(name).dependencies(version).map do |k, v| v = Librarian::Dependency::Requirement.new(v).to_gem_requirement - Dependency.new(k, v, nil) + Dependency.new(k, v, nil, name) end end diff --git a/lib/librarian/puppet/source/local.rb b/lib/librarian/puppet/source/local.rb index 4a3744ce..c35b5309 100644 --- a/lib/librarian/puppet/source/local.rb +++ b/lib/librarian/puppet/source/local.rb @@ -44,7 +44,7 @@ def fetch_dependencies(name, version, extra) parsed_metadata['dependencies'].each do |d| gem_requirement = Librarian::Dependency::Requirement.new(d['version_requirement']).to_gem_requirement - new_dependency = Dependency.new(d['name'], gem_requirement, forge_source) + new_dependency = Dependency.new(d['name'], gem_requirement, forge_source, name) dependencies << new_dependency end