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