class ReaPack::Index::ConflictDetector

Constants

Entry

Attributes

buckets[R]

Public Class Methods

new() click to toggle source
# File lib/reapack/index/cdetector.rb, line 29
def initialize
  @buckets = {}
end

Public Instance Methods

[](key) click to toggle source
# File lib/reapack/index/cdetector.rb, line 39
def [](key)
  Selector.new key, self
end
bucket(name) click to toggle source
# File lib/reapack/index/cdetector.rb, line 45
def bucket(name)
  raise ArgumentError, 'bucket name is not a symbol' unless name.is_a? Symbol
  @buckets[name] ||= []
end
clear() click to toggle source
# File lib/reapack/index/cdetector.rb, line 50
def clear
  @buckets.clear
end
initialize_clone(other) click to toggle source
Calls superclass method
# File lib/reapack/index/cdetector.rb, line 33
def initialize_clone(other)
  super
  other.instance_variable_set :@buckets,
    Hash[@buckets.map {|k, v| [k, v.clone] }]
end
load_xml(node) click to toggle source
# File lib/reapack/index/cdetector.rb, line 89
def load_xml(node)
  Category.find_all(node).each {|cat|
    Package.find_all(cat.node).each {|pkg|
      pkgroot = File.join(cat.name, pkg.name)

      pkg.versions.last&.children(Source::TAG)&.each {|src|
        type = src[:type] || pkg.type
        platform = src[:platform] || :all
        entry = Entry.new pkgroot, platform.to_sym

        if src[:file]
          entry.file = ReaPack::Index.expand(src[:file], cat.name)
        else
          entry.file = pkgroot
        end

        bucket(type.to_sym) << entry
      }
    }
  }
end
resolve(bname, key = nil) click to toggle source
# File lib/reapack/index/cdetector.rb, line 54
def resolve(bname, key = nil)
  dups = bucket(bname).group_by {|e| e.file }.values.select {|a| a.size > 1 }

  errors = dups.map {|a|
    packages = a.map {|e| e.key }.uniq
    next if key && !packages.include?(key)

    if packages.size == 1 || !key
      original = sort_platforms(a)[1]
      msg = "duplicate file '#{original.file}'"
    else
      original = sort_platforms(a.select {|e| e.key != key }).first
      msg = "'#{original.file}' conflicts with '#{original.key}'"
    end

    platforms = a.map {|e| e.platform }.uniq

    if platforms.size > 1
      # check platform inheritance
      platforms.any? {|p|
        break true unless Source::PLATFORMS[p]
        loop do
          p = Source::PLATFORMS[p] or break false
          break true if platforms.include? p
        end
      } or next
    end

    platform = original.platform
    platform == :all ? msg : "#{msg} on #{platform}"
  }.compact

  errors unless errors.empty?
end

Private Instance Methods

levels() click to toggle source
# File lib/reapack/index/cdetector.rb, line 118
def levels
  @@levels ||= begin
    Hash[Source::PLATFORMS.map {|name, parent|
      levels = 0

      loop do
        break unless parent
        levels += 1
        parent = Source::PLATFORMS[parent]
      end

      [name, levels]
    }]
  end
end
sort_platforms(set) click to toggle source
# File lib/reapack/index/cdetector.rb, line 112
def sort_platforms(set)
  set.group_by {|e| levels[e.platform] || 0 }.sort
    .map {|_, a| a.sort_by {|e| Source::PLATFORMS.keys.index(e.platform) || 0 } }
    .flatten
end