Class: Batali::ScoreKeeper
- Inherits:
-
Grimoire::UnitScoreKeeper
- Object
- Grimoire::UnitScoreKeeper
- Batali::ScoreKeeper
- Defined in:
- lib/batali/score_keeper.rb
Overview
Provide scores for units
Instance Method Summary collapse
-
#preferred_score ⇒ Symbol
Always prefer higher scoring units.
-
#score_for(unit, *args) ⇒ Numeric, NilClass
Provide score for given unit.
Instance Method Details
#preferred_score ⇒ Symbol
Always prefer higher scoring units
12 13 14 |
# File 'lib/batali/score_keeper.rb', line 12 def preferred_score :highscore end |
#score_for(unit, *args) ⇒ Numeric, NilClass
Provide score for given unit
21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 |
# File 'lib/batali/score_keeper.rb', line 21 def score_for(unit, *args) opts = args.detect{|a| a.is_a?(Hash)} || {} multiplier = 1 manifest_unit = manifest.cookbook.detect do |m_unit| m_unit.name == unit.name end if(manifest_unit) # If the unit version matches the manifest version, this # should be _the_ preferred version if(manifest_unit.version == unit.version) multiplier = 10000000 elsif(opts[:solver] && opts[:solver].new_world) new_world_unit = opts[:solver].new_world.units.detect do |n_unit| n_unit.name == unit.name && n_unit.version == unit.version end multiplier = 10000000 if new_world_unit else # If the unit version satisfies within the patch segment of # the manifest version score those versions highest for upgrade if(UnitRequirement.new("~> #{manifest_unit.version}").satisfied_by?(unit.version)) multiplier = 1000000 else # If the unit version satisfies within the minor or major # version segments of the manifest version, bump score # value up (with satisfaction within minor segment being # worth more than satisfaction within major segment) pos = UnitRequirement.new("~> #{manifest_unit.version.segments.slice(0,2).join('.')}").satisfied_by?(unit.version) ? 1 : 0 multi_val = pos == 1 ? 1000 : 100 distance = (manifest_unit.version.segments[pos] - unit.version.segments[pos]) if(distance > 0) distance = 1.0 / distance else distance = 0 end multiplier = multi_val + (multi_val * distance) end end else if(opts[:solver] && opts[:solver].new_world) new_world_unit = opts[:solver].new_world.units.detect do |n_unit| n_unit.name == unit.name && n_unit.version == unit.version end multiplier = 10000000 if new_world_unit end end score = [] # Generate a "value" for each segment of the version with # growing importance (major > minor > patch) unit.version.segments.reverse.each_with_index.map do |val, pos| if(val == 0) score.push 0 else score.push (2 - (1.0 / val)) * ((pos + 1)**10) end end # Sum the score for each segment to provide the score for the # version and multiply by defined multiplier to force higher # score when manifest drives desire for versions closer to # version defined within manifest score = score.inject(&:+) * multiplier debug "Score <#{unit.name}:#{unit.version}>: #{score}" score end |