puppetfile-resolver 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/LICENSE +201 -0
- data/README.md +169 -0
- data/lib/puppetfile-resolver.rb +7 -0
- data/lib/puppetfile-resolver/cache/base.rb +28 -0
- data/lib/puppetfile-resolver/cache/persistent.rb +50 -0
- data/lib/puppetfile-resolver/data/ruby_ca_certs.pem +3432 -0
- data/lib/puppetfile-resolver/models.rb +8 -0
- data/lib/puppetfile-resolver/models/missing_module_specification.rb +27 -0
- data/lib/puppetfile-resolver/models/module_dependency.rb +55 -0
- data/lib/puppetfile-resolver/models/module_specification.rb +114 -0
- data/lib/puppetfile-resolver/models/puppet_dependency.rb +34 -0
- data/lib/puppetfile-resolver/models/puppet_specification.rb +25 -0
- data/lib/puppetfile-resolver/models/puppetfile_dependency.rb +14 -0
- data/lib/puppetfile-resolver/puppetfile.rb +22 -0
- data/lib/puppetfile-resolver/puppetfile/base_module.rb +62 -0
- data/lib/puppetfile-resolver/puppetfile/document.rb +125 -0
- data/lib/puppetfile-resolver/puppetfile/forge_module.rb +14 -0
- data/lib/puppetfile-resolver/puppetfile/git_module.rb +19 -0
- data/lib/puppetfile-resolver/puppetfile/invalid_module.rb +16 -0
- data/lib/puppetfile-resolver/puppetfile/local_module.rb +14 -0
- data/lib/puppetfile-resolver/puppetfile/parser/errors.rb +19 -0
- data/lib/puppetfile-resolver/puppetfile/parser/r10k_eval.rb +133 -0
- data/lib/puppetfile-resolver/puppetfile/parser/r10k_eval/dsl.rb +51 -0
- data/lib/puppetfile-resolver/puppetfile/parser/r10k_eval/module/forge.rb +50 -0
- data/lib/puppetfile-resolver/puppetfile/parser/r10k_eval/module/git.rb +32 -0
- data/lib/puppetfile-resolver/puppetfile/parser/r10k_eval/module/invalid.rb +27 -0
- data/lib/puppetfile-resolver/puppetfile/parser/r10k_eval/module/local.rb +26 -0
- data/lib/puppetfile-resolver/puppetfile/parser/r10k_eval/module/svn.rb +30 -0
- data/lib/puppetfile-resolver/puppetfile/parser/r10k_eval/puppet_module.rb +36 -0
- data/lib/puppetfile-resolver/puppetfile/svn_module.rb +16 -0
- data/lib/puppetfile-resolver/puppetfile/validation_errors.rb +106 -0
- data/lib/puppetfile-resolver/resolution_provider.rb +182 -0
- data/lib/puppetfile-resolver/resolution_result.rb +30 -0
- data/lib/puppetfile-resolver/resolver.rb +77 -0
- data/lib/puppetfile-resolver/spec_searchers/common.rb +15 -0
- data/lib/puppetfile-resolver/spec_searchers/forge.rb +75 -0
- data/lib/puppetfile-resolver/spec_searchers/git.rb +64 -0
- data/lib/puppetfile-resolver/spec_searchers/local.rb +45 -0
- data/lib/puppetfile-resolver/ui/debug_ui.rb +15 -0
- data/lib/puppetfile-resolver/ui/null_ui.rb +20 -0
- data/lib/puppetfile-resolver/util.rb +23 -0
- data/lib/puppetfile-resolver/version.rb +5 -0
- data/puppetfile-cli.rb +101 -0
- data/spec/spec_helper.rb +48 -0
- data/spec/unit/puppetfile-resolver/puppetfile/document_spec.rb +316 -0
- data/spec/unit/puppetfile-resolver/puppetfile/parser/r10k_eval_spec.rb +460 -0
- data/spec/unit/puppetfile-resolver/resolver_spec.rb +421 -0
- metadata +124 -0
@@ -0,0 +1,36 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'puppetfile-resolver/puppetfile/parser/r10k_eval/module/invalid'
|
4
|
+
require 'puppetfile-resolver/puppetfile/parser/r10k_eval/module/forge'
|
5
|
+
require 'puppetfile-resolver/puppetfile/parser/r10k_eval/module/git'
|
6
|
+
require 'puppetfile-resolver/puppetfile/parser/r10k_eval/module/local'
|
7
|
+
require 'puppetfile-resolver/puppetfile/parser/r10k_eval/module/svn'
|
8
|
+
|
9
|
+
module PuppetfileResolver
|
10
|
+
module Puppetfile
|
11
|
+
module Parser
|
12
|
+
module R10KEval
|
13
|
+
module PuppetModule
|
14
|
+
def self.from_puppetfile(title, args)
|
15
|
+
return Module::Git.to_document_module(title, args) if Module::Git.implements?(title, args)
|
16
|
+
return Module::Svn.to_document_module(title, args) if Module::Svn.implements?(title, args)
|
17
|
+
return Module::Local.to_document_module(title, args) if Module::Local.implements?(title, args)
|
18
|
+
return Module::Forge.to_document_module(title, args) if Module::Forge.implements?(title, args)
|
19
|
+
|
20
|
+
Module::Invalid.to_document_module(title, args)
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.parse_title(title)
|
24
|
+
if (match = title.match(/\A(\w+)\Z/))
|
25
|
+
[nil, match[1]]
|
26
|
+
elsif (match = title.match(/\A(\w+)[-\/](\w+)\Z/))
|
27
|
+
[match[1], match[2]]
|
28
|
+
else
|
29
|
+
raise ArgumentError, format("Module name (%<title>s) must match either 'modulename' or 'owner/modulename'", title: title)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'puppetfile-resolver/puppetfile/base_module'
|
4
|
+
|
5
|
+
module PuppetfileResolver
|
6
|
+
module Puppetfile
|
7
|
+
class SvnModule < BaseModule
|
8
|
+
attr_accessor :remote
|
9
|
+
|
10
|
+
def initialize(title)
|
11
|
+
super
|
12
|
+
@module_type = SVN_MODULE
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,106 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module PuppetfileResolver
|
4
|
+
module Puppetfile
|
5
|
+
class DocumentValidationErrorBase
|
6
|
+
attr_accessor :message
|
7
|
+
attr_accessor :puppet_module
|
8
|
+
|
9
|
+
def initialize(message, puppet_module)
|
10
|
+
@message = message
|
11
|
+
@puppet_module = puppet_module
|
12
|
+
end
|
13
|
+
|
14
|
+
def to_s
|
15
|
+
"#{puppet_module.name}: #{message}"
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
# Validation Error classes for parsing Puppetfiles
|
20
|
+
class DocumentInvalidModuleError < DocumentValidationErrorBase
|
21
|
+
end
|
22
|
+
|
23
|
+
class DocumentDuplicateModuleError < DocumentValidationErrorBase
|
24
|
+
attr_accessor :duplicates
|
25
|
+
|
26
|
+
def initialize(message, puppet_module, duplicates)
|
27
|
+
super(message, puppet_module)
|
28
|
+
@duplicates = duplicates
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
# Terminal Errors during resolution
|
33
|
+
class DocumentResolveError < StandardError
|
34
|
+
attr_reader :molinillo_error
|
35
|
+
|
36
|
+
def initialize(message, molinillo_error)
|
37
|
+
@molinillo_error = molinillo_error
|
38
|
+
super(message)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
class DocumentCircularDependencyError < DocumentResolveError
|
43
|
+
def initialize(puppetfile_document, molinillo_error)
|
44
|
+
@puppetfile_document = puppetfile_document
|
45
|
+
super(molinillo_error.message, molinillo_error)
|
46
|
+
end
|
47
|
+
|
48
|
+
def puppetfile_modules
|
49
|
+
module_names = @molinillo_error.dependencies.map(&:name)
|
50
|
+
@puppetfile_document.modules.select { |mod| module_names.include?(mod.name) }
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
class DocumentVersionConflictError < DocumentResolveError
|
55
|
+
def initialize(molinillo_error)
|
56
|
+
super(molinillo_error.message_with_trees(solver_name: 'Puppetfile Resolver'), molinillo_error)
|
57
|
+
end
|
58
|
+
|
59
|
+
def puppetfile_modules
|
60
|
+
puppetfile_modules = []
|
61
|
+
molinillo_error.conflicts.reduce(''.dup) do |_o, (_name, conflict)|
|
62
|
+
# We don't actually care about the dependency tree,
|
63
|
+
# only the leaves within. So just grab all of leaves and
|
64
|
+
# find all of the modules in the Puppetfile document
|
65
|
+
conflict
|
66
|
+
.requirement_trees
|
67
|
+
.flatten
|
68
|
+
.uniq
|
69
|
+
.select { |req| req.is_a?(PuppetfileResolver::Models::PuppetfileDependency) }
|
70
|
+
.each do |req|
|
71
|
+
puppetfile_modules << req.puppetfile_module unless puppetfile_modules.include?(req.puppetfile_module)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
puppetfile_modules
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
# Resolution Validation Error classes for validating
|
80
|
+
# a valid Puppetfile against a dependency resolution
|
81
|
+
class DocumentResolutionErrorBase < DocumentValidationErrorBase
|
82
|
+
attr_accessor :puppet_module
|
83
|
+
attr_accessor :module_specification
|
84
|
+
|
85
|
+
def initialize(message, puppet_module, module_specification)
|
86
|
+
super(message, puppet_module)
|
87
|
+
@module_specification = module_specification
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
class DocumentLatestVersionError < DocumentResolutionErrorBase
|
92
|
+
end
|
93
|
+
|
94
|
+
class DocumentMissingModuleError < DocumentResolutionErrorBase
|
95
|
+
end
|
96
|
+
|
97
|
+
class DocumentMissingDependenciesError < DocumentResolutionErrorBase
|
98
|
+
attr_accessor :missing_specifications
|
99
|
+
|
100
|
+
def initialize(message, puppet_module, module_specification, missing_specifications)
|
101
|
+
super(message, puppet_module, module_specification)
|
102
|
+
@missing_specifications = missing_specifications
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
@@ -0,0 +1,182 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'molinillo'
|
4
|
+
require 'puppetfile-resolver/cache/base'
|
5
|
+
require 'puppetfile-resolver/spec_searchers/forge'
|
6
|
+
require 'puppetfile-resolver/spec_searchers/git'
|
7
|
+
require 'puppetfile-resolver/spec_searchers/local'
|
8
|
+
|
9
|
+
module PuppetfileResolver
|
10
|
+
class ResolutionProvider
|
11
|
+
include Molinillo::SpecificationProvider
|
12
|
+
|
13
|
+
# options
|
14
|
+
# module_paths : Array of paths
|
15
|
+
# strict_mode : [Boolean] Whether missing dependencies throw an error (default: false)
|
16
|
+
def initialize(puppetfile_document, puppet_version, resolver_ui, options = {})
|
17
|
+
require 'semantic_puppet'
|
18
|
+
|
19
|
+
@puppetfile_document = puppetfile_document
|
20
|
+
raise 'The UI object must be of type Molinillo::UI' if resolver_ui.nil? || !resolver_ui.is_a?(Molinillo::UI)
|
21
|
+
@resolver_ui = resolver_ui
|
22
|
+
# TODO: This default crap should move to the resolve class and we just validate (and raise) here
|
23
|
+
@puppet_module_paths = options[:module_paths].nil? ? [] : options[:module_paths]
|
24
|
+
@allow_missing_modules = options[:allow_missing_modules].nil? ? true : options[:allow_missing_modules] == true
|
25
|
+
# There can be only one puppet specification in existance so we pre-load here.
|
26
|
+
@puppet_specification = Models::PuppetSpecification.new(puppet_version)
|
27
|
+
@module_info = {}
|
28
|
+
@cache = options[:cache].nil? ? Cache::Base.new : options[:cache]
|
29
|
+
end
|
30
|
+
|
31
|
+
# Search for the specifications that match the given dependency.
|
32
|
+
# The specifications in the returned array will be considered in reverse
|
33
|
+
# order, so the latest version ought to be last.
|
34
|
+
# @note This method should be 'pure', i.e. the return value should depend
|
35
|
+
# only on the `dependency` parameter.
|
36
|
+
#
|
37
|
+
# @param [Object] dependency
|
38
|
+
# @return [Array<Object>] the specifications that satisfy the given
|
39
|
+
# `dependency`.
|
40
|
+
def search_for(dependency)
|
41
|
+
case dependency
|
42
|
+
when Models::PuppetDependency
|
43
|
+
result = find_puppet_specifications(dependency)
|
44
|
+
when Models::ModuleDependency
|
45
|
+
result = find_all_module_specifications(dependency).select do |spec|
|
46
|
+
dependency.satisified_by?(spec)
|
47
|
+
end
|
48
|
+
else
|
49
|
+
# No idea how we got here?!?!
|
50
|
+
raise ArgumentError, "Unknown Dependency type #{dependency.class}"
|
51
|
+
end
|
52
|
+
|
53
|
+
return result if result.empty? || result.count == 1
|
54
|
+
# Reverse sort by version
|
55
|
+
result.sort! { |a, b| a.version > b.version ? 1 : -1 }
|
56
|
+
end
|
57
|
+
|
58
|
+
def find_puppet_specifications(dependency)
|
59
|
+
# Puppet specifications are a bit special as there can be only one (Highlander style)
|
60
|
+
dependency.satisified_by?(@puppet_specification) ? [@puppet_specification] : []
|
61
|
+
end
|
62
|
+
|
63
|
+
# Returns the dependencies of `specification`.
|
64
|
+
# @note This method should be 'pure', i.e. the return value should depend
|
65
|
+
# only on the `specification` parameter.
|
66
|
+
#
|
67
|
+
# @param [Object] specification
|
68
|
+
# @return [Array<Object>] the dependencies that are required by the given
|
69
|
+
# `specification`.
|
70
|
+
def dependencies_for(specification)
|
71
|
+
specification.dependencies(@cache, @resolver_ui)
|
72
|
+
end
|
73
|
+
|
74
|
+
# Returns the name for the given `dependency`.
|
75
|
+
# @note This method should be 'pure', i.e. the return value should depend
|
76
|
+
# only on the `dependency` parameter.
|
77
|
+
#
|
78
|
+
# @param [Object] dependency
|
79
|
+
# @return [String] the name for the given `dependency`.
|
80
|
+
def name_for(dependency)
|
81
|
+
dependency.name
|
82
|
+
end
|
83
|
+
|
84
|
+
# Determines whether the given `requirement` is satisfied by the given
|
85
|
+
# `spec`, in the context of the current `activated` dependency graph.
|
86
|
+
#
|
87
|
+
# @param [Object] requirement
|
88
|
+
# @param [DependencyGraph] activated the current dependency graph in the
|
89
|
+
# resolution process.
|
90
|
+
# @param [Object] spec
|
91
|
+
# @return [Boolean] whether `requirement` is satisfied by `spec` in the
|
92
|
+
# context of the current `activated` dependency graph.
|
93
|
+
def requirement_satisfied_by?(requirement, _activated, spec)
|
94
|
+
requirement.satisified_by?(spec)
|
95
|
+
end
|
96
|
+
|
97
|
+
def name_for_explicit_dependency_source
|
98
|
+
'Puppetfile'
|
99
|
+
end
|
100
|
+
|
101
|
+
def name_for_locking_dependency_source
|
102
|
+
'Puppetfile'
|
103
|
+
end
|
104
|
+
|
105
|
+
def sort_dependencies(dependencies, activated, conflicts) # rubocop:disable Lint/UnusedMethodArgument You're drunk rubocop
|
106
|
+
dependencies.sort_by do |dependency|
|
107
|
+
name = name_for(dependency)
|
108
|
+
[
|
109
|
+
activated.vertex_named(name).payload ? 0 : 1,
|
110
|
+
conflicts[name] ? 0 : 1
|
111
|
+
]
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
# Returns whether this dependency, which has no possible matching
|
116
|
+
# specifications, can safely be ignored.
|
117
|
+
#
|
118
|
+
# @param [Object] dependency
|
119
|
+
# @return [Boolean] whether this dependency can safely be skipped.
|
120
|
+
def allow_missing?(dependency)
|
121
|
+
# Puppet dependencies must _always_ be resolvable
|
122
|
+
return false if dependency.is_a?(Models::PuppetDependency)
|
123
|
+
# Explicit Puppetfile dependencies must _always_ be resolvable
|
124
|
+
return false if dependency.is_a?(Models::PuppetfileDependency)
|
125
|
+
@allow_missing_modules
|
126
|
+
end
|
127
|
+
|
128
|
+
private
|
129
|
+
|
130
|
+
def find_all_module_specifications(dependency)
|
131
|
+
return @module_info[dependency.name] unless @module_info[dependency.name].nil?
|
132
|
+
|
133
|
+
@module_info[dependency.name] = []
|
134
|
+
|
135
|
+
# Find the module as specified in the Puppetfile?
|
136
|
+
mod = @puppetfile_document.modules.find { |item| item.name == dependency.name }
|
137
|
+
unless mod.nil?
|
138
|
+
case mod.module_type
|
139
|
+
when Puppetfile::FORGE_MODULE
|
140
|
+
@module_info[dependency.name] = safe_spec_search(dependency) { SpecSearchers::Forge.find_all(dependency, @cache, @resolver_ui) }
|
141
|
+
when Puppetfile::GIT_MODULE
|
142
|
+
@module_info[dependency.name] = safe_spec_search(dependency) { SpecSearchers::Git.find_all(mod, dependency, @cache, @resolver_ui) }
|
143
|
+
else # rubocop:disable Style/EmptyElse
|
144
|
+
# Errr.... Nothing
|
145
|
+
end
|
146
|
+
end
|
147
|
+
return @module_info[dependency.name] unless @module_info[dependency.name].empty?
|
148
|
+
|
149
|
+
# It's not in the Puppetfile, so perhaps it's in our modulepath?
|
150
|
+
@module_info[dependency.name] = safe_spec_search(dependency) { SpecSearchers::Local.find_all(mod, @puppet_module_paths, dependency, @cache, @resolver_ui) }
|
151
|
+
return @module_info[dependency.name] unless @module_info[dependency.name].empty?
|
152
|
+
|
153
|
+
# It's not in the Puppetfile and not on disk, so perhaps it's on the Forge?
|
154
|
+
# The forge needs an owner and name to be able to resolve
|
155
|
+
if dependency.name && dependency.owner # rubocop:disable Style/IfUnlessModifier
|
156
|
+
@module_info[dependency.name] = safe_spec_search(dependency) { SpecSearchers::Forge.find_all(dependency, @cache, @resolver_ui) }
|
157
|
+
end
|
158
|
+
|
159
|
+
# If we can't find any specifications for the module and we're allowing missing modules
|
160
|
+
# then create a MissingModuleSpecification for the purposes of the dependency graph
|
161
|
+
if @allow_missing_modules && @module_info[dependency.name].empty? # rubocop:disable Style/IfUnlessModifier
|
162
|
+
@module_info[dependency.name] << Models::MissingModuleSpecification.new(name: dependency.name)
|
163
|
+
end
|
164
|
+
@module_info[dependency.name]
|
165
|
+
end
|
166
|
+
|
167
|
+
def safe_spec_search(dependency)
|
168
|
+
results = yield
|
169
|
+
# The PuppetfileDependency has the resolver flags, so we need to inject them into the specifications
|
170
|
+
return results unless dependency.is_a?(PuppetfileResolver::Models::PuppetfileDependency) || results.empty?
|
171
|
+
results.each { |spec| spec.resolver_flags = dependency.puppetfile_module.resolver_flags }
|
172
|
+
|
173
|
+
results
|
174
|
+
rescue StandardError => e
|
175
|
+
if @allow_missing_modules
|
176
|
+
@resolver_ui.debug { "Error while querying a specification searcher #{e.inspect}" }
|
177
|
+
return []
|
178
|
+
end
|
179
|
+
raise
|
180
|
+
end
|
181
|
+
end
|
182
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'molinillo'
|
4
|
+
|
5
|
+
module PuppetfileResolver
|
6
|
+
class ResolutionResult
|
7
|
+
attr_reader :dependency_graph
|
8
|
+
|
9
|
+
def initialize(dependency_graph, puppetfile_document)
|
10
|
+
raise "Expected Molinillo::DependencyGraph but got #{dependency_graph.class}" unless dependency_graph.is_a?(Molinillo::DependencyGraph)
|
11
|
+
@dependency_graph = dependency_graph
|
12
|
+
@puppetfile_document = puppetfile_document
|
13
|
+
end
|
14
|
+
|
15
|
+
def specifications
|
16
|
+
# Note - Later rubies have `.transform_values` however we support old Ruby versions
|
17
|
+
result = {}
|
18
|
+
@dependency_graph.vertices.each { |key, vertex| result[key] = vertex.payload }
|
19
|
+
result
|
20
|
+
end
|
21
|
+
|
22
|
+
def to_dot
|
23
|
+
@dependency_graph.to_dot
|
24
|
+
end
|
25
|
+
|
26
|
+
def validation_errors
|
27
|
+
@puppetfile_document.resolution_validation_errors(self)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'molinillo'
|
4
|
+
require 'puppetfile-resolver/resolution_provider'
|
5
|
+
require 'puppetfile-resolver/resolution_result'
|
6
|
+
require 'puppetfile-resolver/models'
|
7
|
+
|
8
|
+
module PuppetfileResolver
|
9
|
+
class Resolver
|
10
|
+
attr_reader :puppetfile
|
11
|
+
attr_reader :dependencies_to_resolve
|
12
|
+
|
13
|
+
def initialize(puppetfile_document, puppet_version = nil)
|
14
|
+
@puppetfile = puppetfile_document
|
15
|
+
raise 'Puppetfile is not valid' unless @puppetfile.valid?
|
16
|
+
@puppet_version = puppet_version
|
17
|
+
|
18
|
+
@dependencies_to_resolve = dependencies_from_puppetfile
|
19
|
+
end
|
20
|
+
|
21
|
+
# options
|
22
|
+
# :cache => Cache Object
|
23
|
+
# :module_paths => Array[String]
|
24
|
+
def resolve(options = {})
|
25
|
+
if options[:ui]
|
26
|
+
raise 'The UI object must be of type Molinillo::UI' unless options[:ui].is_a?(Molinillo::UI)
|
27
|
+
ui = options[:ui]
|
28
|
+
else
|
29
|
+
require 'puppetfile-resolver/ui/null_ui'
|
30
|
+
ui = PuppetfileResolver::UI::NullUI.new
|
31
|
+
end
|
32
|
+
provider = ResolutionProvider.new(@puppetfile, @puppet_version, ui, options)
|
33
|
+
|
34
|
+
resolver = Molinillo::Resolver.new(provider, ui)
|
35
|
+
begin
|
36
|
+
result = resolver.resolve(dependencies_to_resolve)
|
37
|
+
rescue Molinillo::VersionConflict => e
|
38
|
+
# Wrap the Molinillo error
|
39
|
+
new_e = PuppetfileResolver::Puppetfile::DocumentVersionConflictError.new(e)
|
40
|
+
raise new_e, new_e.message, e.backtrace
|
41
|
+
rescue Molinillo::CircularDependencyError => e
|
42
|
+
# Wrap the Molinillo error
|
43
|
+
new_e = PuppetfileResolver::Puppetfile::DocumentCircularDependencyError.new(@puppetfile, e)
|
44
|
+
raise new_e, new_e.message, e.backtrace
|
45
|
+
end
|
46
|
+
ResolutionResult.new(result, @puppetfile)
|
47
|
+
end
|
48
|
+
|
49
|
+
private
|
50
|
+
|
51
|
+
def dependencies_from_puppetfile
|
52
|
+
result = []
|
53
|
+
@puppetfile.modules.each do |mod|
|
54
|
+
# Use an open version unless we get a valid version number
|
55
|
+
if mod.version.nil? || mod.version == :latest
|
56
|
+
version = '>= 0' # Note the `>=` is important. Don't use `>`
|
57
|
+
else
|
58
|
+
version = "=#{mod.version}"
|
59
|
+
end
|
60
|
+
|
61
|
+
result << Models::PuppetfileDependency.new(
|
62
|
+
name: mod.title,
|
63
|
+
version_requirement: version,
|
64
|
+
puppetfile_module: mod
|
65
|
+
)
|
66
|
+
end
|
67
|
+
# We also depend on Puppet, so add an open ended requirement if no version
|
68
|
+
# was specified or add a strict version requirement
|
69
|
+
if @puppet_version.nil?
|
70
|
+
result << Models::PuppetDependency.new('>= 0')
|
71
|
+
else
|
72
|
+
result << Models::PuppetDependency.new(@puppet_version.to_s)
|
73
|
+
end
|
74
|
+
result
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|