class Inspec::Resolver
def resolve(deps, top_level = true, seen_items = {}, path_string = '') # rubocop:disable Metrics/AbcSize
def resolve(deps, top_level = true, seen_items = {}, path_string = '') # rubocop:disable Metrics/AbcSize graph = {} if top_level Inspec::Log.debug("Starting traversal of dependencies #{deps.map(&:to_s)}") else Inspec::Log.debug("Traversing dependency tree of transitive dependency #{deps.map(&:name)}") end detect_duplicates(deps, top_level, path_string) deps.each do |dep| new_seen_items = seen_items.dup new_path_string = if path_string.empty? dep.name else path_string + " -> #{dep.name}" end if new_seen_items.key?(dep.resolved_source) fail Inspec::CyclicDependencyError, "Dependency #{dep} would cause a dependency cycle (#{new_path_string})" else new_seen_items[dep.resolved_source] = true end if !dep.source_satisfies_spec? fail Inspec::UnsatisfiedVersionSpecification, "The profile #{dep.name} from #{dep.resolved_source} has a version #{dep.source_version} which doesn't match #{dep.required_version}" end Inspec::Log.debug("Adding dependency #{dep.name} (#{dep.resolved_source})") graph[dep.name] = dep if !dep.dependencies.empty? resolve(dep.dependencies, false, new_seen_items.dup, new_path_string) end end Inspec::Log.debug('Dependency traversal complete.') if top_level graph end