Cross package maker. DEB/RPM generation or conversion. Derived from jordansissel/fpm.

⌈⌋ ⎇ branch:  cross package maker


Artifact [5702239c41]

Artifact 5702239c4173400ca25dac4b4f67fb4b687f7ff8:

  • File lib/fpm/package/filter_deps.rb — part of check-in [06c1480758] at 2014-12-22 12:35:32 on branch trunk — Add missing update(opts) parameter. (user: mario size: 2827)

# api: fpm
# title: Dependency matching
# description: resolves package names for other distributions, using distromatch/whohas
# type: filter
# category: dependency
# version: 0.1
# depends: bin:whohas | bin:distromatch
# license: MITL
# 
# Package names in -d dependency lists aren't universal across distributions.
# Which kind of complicates building targetted RPMs (or sometimes DEBs).
# 
# Distromatch or whohas.pl can resolve library and package names across
# different Linux systems. They're utilized in this filter to convert basenames
# between each other. Debian being the assumed reference point, you should
# standardize on theirs for specifying fpm -d lists.
# 
# A flag `-u deps=opensuse` flag can be used to specify the desired target
# distro/family.
#
#  → With `-u deps=fedora..debian` an inverse lookup is performed, only with
#    Distromatch though.
#
#  → Using whohas only plain package lists are fetched and distros and
#    package names searched raw.
#
# Optimum version matches aren't performed. (This is where it's getting even
# more complicated.)
#
# Obviously as these lookups can be time-consuming, you may wish to use either
# of the mentioned tools manually, and prepare per-package --dependencies lists
# yourself. Whohas is likely most revealing for that.


require "fpm/package"
require "fpm/util"

# Resolve package names cross-distro for dependency, suggest, conflicts, .. lists
class FPM::Package::Filter_Deps < FPM::Package

  def initialize()
    @dm = `which distromatch`
    @wh = `which whohas`
    logger.warning("Neither distromatch nor whohas are available.") unless (@dm or @wh)
    super
    @source = "debian"
    @target = "debian"
    @opts = []
  end
  
  # traverse lists
  def update(opts=nil)
    
    # check for `-u deps=target` or `deps=source..target` options (option tokens are preseparated in command.rb)
    if opts.count >= 2
      @source, @target = opts
    elsif opts.count == 1
      @target = opts[0]
    end
    
    # replace all the things
    @dependencies = translate(@dependencies)
    @provides = translate(@provides)
    @replaces = translate(@replaces)
    @conflicts = translate(@conflicts)
  end

  # replace individual package references
  def translate(deps)
    renamed = []
    deps.each do |name|
      name =~ /([\w\.\+\-]+)(.*)/
      name, ver = [$1, $2]
      name = resolve(name)
      renamed << "#{name}#{ver}"
    end
    return renamed
  end

  # lookup tools
  def resolve(pkg)
    if target == source
      return pkg
    elsif @dm
      return distromatch(pkg)
    else
      return whohas(pkg)
    end
  end

  def distromatch(pkg)
    return pkg
  end

  def whohas(pkg)
    ls = `#{@wh} --no-threads --shallow -d #{@target} #{pkg}`
    if ls =~ /\w+\s+(\S+)/
      return $1
    else
      return pkg
    end
  end

end