Class: Solve::RubySolver
- Inherits:
-
Object
- Object
- Solve::RubySolver
- Includes:
- Molinillo::SpecificationProvider
- Defined in:
- lib/solve/ruby_solver.rb
Instance Attribute Summary collapse
-
#demands_array ⇒ Array<String>, Array<Array<String, String>>
readonly
Demands.
-
#graph ⇒ Solve::Graph
readonly
Graph object with references to all known artifacts and dependency constraints.
Class Method Summary collapse
-
.activate ⇒ Object
For optional solver engines, this attempts to load depenencies.
-
.timeout ⇒ Integer
The timeout (in seconds) to use when resolving graphs.
Instance Method Summary collapse
-
#after_resolution ⇒ Object
Callback required by Molinillo, called when the solve is complete.
-
#allow_missing?(dependency) ⇒ Boolean
Callback required by Molinillo Returns whether this dependency, which has no possible matching specifications, can safely be ignored.
-
#before_resolution ⇒ Object
Callback required by Molinillo, called when the solve starts.
-
#debug(current_resolver_depth = 0) ⇒ Object
Callback required by Molinillo, gives debug information about the solution.
-
#demands ⇒ Array<Solve::Demand>
The problem demands given as Demand model objects.
-
#dependencies_for(specification) ⇒ Array<Solve::Dependency>
Callback required by Molinillo Returns the dependencies of ‘specification`.
-
#indicate_progress ⇒ Object
Callback required by Molinillo, called when resolving every progress_rate.
-
#initialize(graph, demands, options = {}) ⇒ RubySolver
constructor
A new instance of RubySolver.
-
#name_for(dependency) ⇒ String
Callback required by Molinillo Returns the name for the given ‘dependency`.
-
#name_for_explicit_dependency_source ⇒ String
Callback required by Molinillo.
-
#progress_rate ⇒ Integer
Callback required by Molinillo, called when the solve starts.
-
#requirement_satisfied_by?(requirement, activated, spec) ⇒ Boolean
Callback required by Molinillo Determines whether the given ‘requirement` is satisfied by the given `spec`, in the context of the current `activated` dependency graph.
-
#resolve(options = {}) ⇒ Hash, List
Returns a hash like { “Artifact Name” => “Version”,… } unless the :sorted option is true, then it returns a list like [[“Artifact Name”, “Version],…].
-
#search_for(dependency) ⇒ Array<Solve::Artifact>
Callback required by Molinillo Search for the specifications that match the given dependency.
-
#sort_dependencies(dependencies, activated, conflicts) ⇒ Array<Solve::Dependency>
Callback required by Molinillo Sort dependencies so that the ones that are easiest to resolve are first.
Constructor Details
#initialize(graph, demands, options = {}) ⇒ RubySolver
Returns a new instance of RubySolver.
43 44 45 46 47 48 49 50 51 52 53 |
# File 'lib/solve/ruby_solver.rb', line 43 def initialize(graph, demands, = {}) @graph = graph @demands_array = demands @timeout_ms = self.class.timeout @ui = [:ui] # could be nil, but that's okay @dependency_source = [:dependency_source] || "user-specified dependency" @molinillo_graph = Molinillo::DependencyGraph.new @resolver = Molinillo::Resolver.new(self, self) end |
Instance Attribute Details
#demands_array ⇒ Array<String>, Array<Array<String, String>> (readonly)
Returns demands.
34 35 36 |
# File 'lib/solve/ruby_solver.rb', line 34 def demands_array @demands_array end |
#graph ⇒ Solve::Graph (readonly)
Graph object with references to all known artifacts and dependency constraints.
29 30 31 |
# File 'lib/solve/ruby_solver.rb', line 29 def graph @graph end |
Class Method Details
.activate ⇒ Object
For optional solver engines, this attempts to load depenencies. The RubySolver is a non-optional component, so this is a no-op
20 21 22 |
# File 'lib/solve/ruby_solver.rb', line 20 def activate true end |
.timeout ⇒ Integer
The timeout (in seconds) to use when resolving graphs. Default is 10. This can be configured by setting the SOLVE_TIMEOUT environment variable.
13 14 15 16 |
# File 'lib/solve/ruby_solver.rb', line 13 def timeout seconds = 30 unless ( seconds = ENV["SOLVE_TIMEOUT"] ) seconds.to_i * 1_000 end |
Instance Method Details
#after_resolution ⇒ Object
Callback required by Molinillo, called when the solve is complete.
115 116 117 |
# File 'lib/solve/ruby_solver.rb', line 115 def after_resolution @ui.say("Finished dependency resolution") if @ui end |
#allow_missing?(dependency) ⇒ Boolean
Callback required by Molinillo Returns whether this dependency, which has no possible matching specifications, can safely be ignored.
253 254 255 |
# File 'lib/solve/ruby_solver.rb', line 253 def allow_missing?(dependency) false end |
#before_resolution ⇒ Object
Callback required by Molinillo, called when the solve starts
109 110 111 |
# File 'lib/solve/ruby_solver.rb', line 109 def before_resolution @ui.say("Starting dependency resolution") if @ui end |
#debug(current_resolver_depth = 0) ⇒ Object
Callback required by Molinillo, gives debug information about the solution
127 128 129 130 131 |
# File 'lib/solve/ruby_solver.rb', line 127 def debug(current_resolver_depth = 0) # debug info will be returned if you call yield here, but it seems to be # broken in current Molinillo @ui.say(yield) if @ui end |
#demands ⇒ Array<Solve::Demand>
The problem demands given as Demand model objects
57 58 59 60 61 |
# File 'lib/solve/ruby_solver.rb', line 57 def demands demands_array.map do |name, constraint| Demand.new(self, name, constraint) end end |
#dependencies_for(specification) ⇒ Array<Solve::Dependency>
This method should be ‘pure’, i.e. the return value should depend only on the ‘specification` parameter.
Callback required by Molinillo Returns the dependencies of ‘specification`.
157 158 159 |
# File 'lib/solve/ruby_solver.rb', line 157 def dependencies_for(specification) specification.dependencies end |
#indicate_progress ⇒ Object
Callback required by Molinillo, called when resolving every progress_rate
121 122 123 |
# File 'lib/solve/ruby_solver.rb', line 121 def indicate_progress nil end |
#name_for(dependency) ⇒ String
This method should be ‘pure’, i.e. the return value should depend only on the ‘dependency` parameter.
Callback required by Molinillo Returns the name for the given ‘dependency`.
212 213 214 |
# File 'lib/solve/ruby_solver.rb', line 212 def name_for(dependency) dependency.name end |
#name_for_explicit_dependency_source ⇒ String
Callback required by Molinillo
219 220 221 |
# File 'lib/solve/ruby_solver.rb', line 219 def name_for_explicit_dependency_source @dependency_source end |
#progress_rate ⇒ Integer
Callback required by Molinillo, called when the solve starts
103 104 105 |
# File 'lib/solve/ruby_solver.rb', line 103 def progress_rate 1 end |
#requirement_satisfied_by?(requirement, activated, spec) ⇒ Boolean
Callback required by Molinillo Determines whether the given ‘requirement` is satisfied by the given `spec`, in the context of the current `activated` dependency graph.
171 172 173 174 175 176 177 178 179 |
# File 'lib/solve/ruby_solver.rb', line 171 def requirement_satisfied_by?(requirement, activated, spec) version = spec.version return false unless requirement.constraint.satisfies?(version) shared_possibility_versions = possibility_versions(requirement, activated) return false if !shared_possibility_versions.empty? && !shared_possibility_versions.include?(version) true end |
#resolve(options = {}) ⇒ Hash, List
Returns a hash like { “Artifact Name” => “Version”,… } unless the :sorted option is true, then it returns a list like [[“Artifact Name”, “Version],…]
73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 |
# File 'lib/solve/ruby_solver.rb', line 73 def resolve( = {}) @ui = [:ui] if [:ui] solved_graph = resolve_with_error_wrapping solution = solved_graph.map(&:payload) unsorted_solution = solution.inject({}) do |stringified_soln, artifact| stringified_soln[artifact.name] = artifact.version.to_s stringified_soln end if [:sorted] build_sorted_solution(unsorted_solution) else unsorted_solution end end |
#search_for(dependency) ⇒ Array<Solve::Artifact>
This method should be ‘pure’, i.e. the return value should depend only on the ‘dependency` parameter.
Callback required by Molinillo Search for the specifications that match the given dependency. The specifications in the returned array will be considered in reverse order, so the latest version ought to be last.
144 145 146 147 148 |
# File 'lib/solve/ruby_solver.rb', line 144 def search_for(dependency) # This array gets mutated by Molinillo; it's okay because sort returns a # new array. graph.versions(dependency.name, dependency.constraint).sort end |
#sort_dependencies(dependencies, activated, conflicts) ⇒ Array<Solve::Dependency>
Callback required by Molinillo Sort dependencies so that the ones that are easiest to resolve are first. Easiest to resolve is (usually) defined by:
1) Is this dependency already activated?
2) How relaxed are the requirements?
3) Are there any conflicts for this dependency?
4) How many possibilities are there to satisfy this dependency?
236 237 238 239 240 241 242 243 244 245 |
# File 'lib/solve/ruby_solver.rb', line 236 def sort_dependencies(dependencies, activated, conflicts) dependencies.sort_by do |dependency| name = name_for(dependency) [ activated.vertex_named(name).payload ? 0 : 1, conflicts[name] ? 0 : 1, search_for(dependency).count, ] end end |