lib/teapot/dependency.rb in teapot-1.0.0.pre.rc7 vs lib/teapot/dependency.rb in teapot-1.0.0.pre.rc9

- old
+ new

@@ -35,10 +35,18 @@ end Provision = Struct.new(:value) Alias = Struct.new(:dependencies) + def priority= value + @priority = value + end + + def priority + @priority || 0 + end + def provides?(name) provisions.key? name end def provides(name_or_aliases, &block) @@ -70,11 +78,11 @@ def dependencies @dependencies ||= Set.new end class Chain - def initialize(selection, dependencies, providers) + def initialize(selection, dependencies, providers, options = {}) # Explicitly selected targets which will be used when resolving ambiguity: @selection = Set.new(selection) # The list of dependencies that needs to be satisfied: @dependencies = dependencies @@ -86,10 +94,12 @@ @ordered = [] @provisions = [] @unresolved = [] @conflicts = {} + @options = options + @dependencies.each do |dependency| expand(dependency, "<top>") end end @@ -103,20 +113,47 @@ attr :unresolved attr :conflicts private + def ignore_priority? + @options[:ignore_priority] + end + + def filter_by_priority(viable_providers) + # Sort from highest priority to lowest priority: + viable_providers = viable_providers.sort{|a,b| b.priority <=> a.priority} + + # The first item has the highest priority: + highest_priority = viable_providers.first.priority + + # We compute all providers with the same highest priority (may be zero): + return viable_providers.take_while{|provider| provider.priority == highest_priority} + end + + def filter_by_selection(viable_providers) + return viable_providers.select{|provider| @selection.include? provider.name} + end + def find_provider(dependency, parent) # Mostly, only one package will satisfy the dependency... viable_providers = @providers.select{|provider| provider.provides? dependency} # puts "** Found #{viable_providers.collect(&:name).join(', ')} viable providers.".color(:magenta) if viable_providers.size > 1 # ... however in some cases (typically where aliases are being used) an explicit selection must be made for the build to work correctly. - explicit_providers = viable_providers.select{|provider| @selection.include? provider.name} - + explicit_providers = filter_by_selection(viable_providers) + # puts "** Filtering to #{explicit_providers.collect(&:name).join(', ')} explicit providers.".color(:magenta) + + if explicit_providers.size != 1 and !ignore_priority? + # If we were unable to select a single package, we may use the priority to limit the number of possible options: + explicit_providers = viable_providers if explicit_providers.empty? + + explicit_providers = filter_by_priority(explicit_providers) + end + if explicit_providers.size == 0 # No provider was explicitly specified, thus we require explicit conflict resolution: @conflicts[dependency] = viable_providers return nil