class FPM::Package::Pacman
Constants
- COMPRESSION_TYPES
-
The list of supported compression types. Default is xz (LZMA2)
- FIND_SCRIPT_FUNCTION_LINE
Public Class Methods
Source
# File lib/fpm/package/pacman.rb, line 31 def initialize(*args) super(*args) attributes[:pacman_optional_depends] = [] end
FPM::Package::new
Public Instance Methods
Source
# File lib/fpm/package/pacman.rb, line 36 def architecture case @architecture when nil return %x{uname -m}.chomp # default to current arch when "amd64" # debian and pacman disagree on architecture names return "x86_64" when "native" return %x{uname -m}.chomp # 'native' is current arch when "all", "any", "noarch" return "any" else return @architecture end end
Source
# File lib/fpm/package/pacman.rb, line 228 def compression_ending case self.attributes[:pacman_compression] when nil, "zstd" return ".zst" when "none" return "" when "gz" return ".gz" when "xz" return ".xz" when "bzip2" return ".bz2" when "zstd" return ".zst" else return ".zst" end end
Source
# File lib/fpm/package/pacman.rb, line 209 def compression_option case self.attributes[:pacman_compression] when nil, "zstd" return "--zstd" when "none" return "" when "gz" return "-z" when "xz" return "--xz" when "bzip2" return "-j" when "zstd" return "--zstd" else return "--zstd" end end
Source
# File lib/fpm/package/pacman.rb, line 55 def config_files return @config_files || [] end
Source
# File lib/fpm/package/pacman.rb, line 292 def data_tar_flags data_tar_flags = [] if attributes[:pacman_use_file_permissions?].nil? if !attributes[:pacman_user].nil? if attributes[:pacman_user] == 'root' data_tar_flags += [ "--numeric-owner", "--owner", "0" ] else data_tar_flags += [ "--owner", attributes[:deb_user] ] end end if !attributes[:pacman_group].nil? if attributes[:pacman_group] == 'root' data_tar_flags += [ "--numeric-owner", "--group", "0" ] else data_tar_flags += [ "--group", attributes[:deb_group] ] end end end return data_tar_flags end
Source
# File lib/fpm/package/pacman.rb, line 314 def default_output v = version v = "#{epoch}:#{v}" if epoch if iteration "#{name}_#{v}-#{iteration}_#{architecture}.#{type}" else "#{name}_#{v}_#{architecture}.#{type}" end end
Source
# File lib/fpm/package/pacman.rb, line 59 def dependencies bogus_regex = /[^\sA-Za-z0-9><=+._@-]/ # Actually modifies depencies if they are not right bogus_dependencies = @dependencies.grep bogus_regex if bogus_dependencies.any? @dependencies.reject! { |a| a =~ bogus_regex } logger.warn("Some of the dependencies looked like they weren't package " \ "names. Such dependency entries only serve to confuse arch. " \ "I am removing them.", :removed_dependencies => bogus_dependencies, :fixed_dependencies => @dependencies) end return @dependencies end
Source
# File lib/fpm/package/pacman.rb, line 96 def input(pacman_pkg_path) control = {} # Unpack the control tarball safesystem(tar_cmd, "-C", staging_path, "-xf", pacman_pkg_path) pkginfo = staging_path(".PKGINFO") mtree = staging_path(".MTREE") install = staging_path(".INSTALL") control_contents = File.read(pkginfo) FileUtils.rm(pkginfo) FileUtils.rm(mtree) control_lines = control_contents.split("\n") control_lines.each do |line| key, val = line.split(/ += +/, 2) if control.has_key? key control[key].push(val) else control[key] = [val] end end self.name = control["pkgname"][0] # Parse 'epoch:version-iteration' in the version string version_re = /^(?:([0-9]+):)?(.+?)(?:-(.*))?$/ m = version_re.match(control["pkgver"][0]) if !m raise "Unsupported version string '#{control["pkgver"][0]}'" end self.epoch, self.version, self.iteration = m.captures self.maintainer = control["packager"][0] # Arch has no notion of vendor, so... #self.vendor = self.url = control["url"][0] # Groups could include more than one. # Speaking of just taking the first entry of the field: # A crude thing to do, but I suppose it's better than nothing. # -- Daniel Haskin, 3/24/2015 self.category = control["group"] && control["group"][0] || self.category # Licenses could include more than one. # Speaking of just taking the first entry of the field: # A crude thing to do, but I suppose it's better than nothing. # -- Daniel Haskin, 3/24/2015 self.license = control["license"][0] || self.license self.architecture = control["arch"][0] self.dependencies = control["depend"] || self.dependencies self.provides = control["provides"] || self.provides self.conflicts = control["conflict"] || self.conflicts self.replaces = control["replaces"] || self.replaces self.description = control["pkgdesc"][0] if control.include? "backup" self.config_files = control["backup"].map{|file| "/" + file} else self.config_files = [] end self.dependencies = control["depend"] || self.dependencies if attributes[:no_auto_depends?] self.dependencies = [] end self.attributes[:pacman_optional_depends] = control["optdepend"] || [] # There are other available attributes, but I didn't include them because: # - makedepend: deps needed to make the arch package. But it's already # made. It just needs to be converted at this point # - checkdepend: See above # - makepkgopt: See above # - size: can be dynamically generated # - builddate: Should be changed to time of package conversion in the new # package, so this value should be thrown away. if File.exist?(install) functions = parse_install_script(install) if functions.include?("pre_install") self.scripts[:before_install] = functions["pre_install"].join("\n") end if functions.include?("post_install") self.scripts[:after_install] = functions["post_install"].join("\n") end if functions.include?("pre_upgrade") self.scripts[:before_upgrade] = functions["pre_upgrade"].join("\n") end if functions.include?("post_upgrade") self.scripts[:after_upgrade] = functions["post_upgrade"].join("\n") end if functions.include?("pre_remove") self.scripts[:before_remove] = functions["pre_remove"].join("\n") end if functions.include?("post_remove") self.scripts[:after_remove] = functions["post_remove"].join("\n") end FileUtils.rm(install) end # Note: didn't use `self.directories`. # Pacman doesn't really record that information, to my knowledge. end
Add a new source to this package. The exact behavior depends on the kind of package being managed.
For instance:
-
for
FPM::Package::Dir
, << expects a path to a directory or files. -
for
FPM::Package::RPM
, << expects a path to an rpm.
The idea is that you can keep pumping in new things to a package for later conversion or output.
Implementations are expected to put files relevant to the ‘input’ in the staging_path
Source
# File lib/fpm/package/pacman.rb, line 51 def iteration return @iteration || 1 end
Source
# File lib/fpm/package/pacman.rb, line 248 def output(output_path) output_check(output_path) # Copy all files from staging to BUILD dir Find.find(staging_path) do |path| src = path.gsub(/^#{staging_path}/, '') dst = build_path(src) begin copy_entry(path, dst, preserve=true, remove_destination=true) rescue copy_entry(path, dst, preserve=false, remove_destination=true) end copy_metadata(path, dst) end # This value is used later in the template for PKGINFO size = safesystemout("du", "-sk", build_path).split(/\s+/)[0].to_i * 1024 builddate = Time.new.to_i pkginfo = template("pacman.erb").result(binding) pkginfo_file = build_path(".PKGINFO") File.write(pkginfo_file, pkginfo) if script?(:before_install) or script?(:after_install) or \ script?(:before_upgrade) or script?(:after_upgrade) or \ script?(:before_remove) or script?(:after_remove) install_script = template("pacman/INSTALL.erb").result(binding) install_script_file = build_path(".INSTALL") File.write(install_script_file, install_script) end generate_mtree File.expand_path(output_path).tap do |path| ::Dir.chdir(build_path) do safesystem(*([tar_cmd, compression_option, "-cf", path] + data_tar_flags + \ ::Dir.entries(".").reject{|entry| entry =~ /^\.{1,2}$/ })) end end end
Output this package to the given path.
Source
# File lib/fpm/package/pacman.rb, line 326 def to_s(format=nil) # Default format if nil # git_1.7.9.3-1-amd64.pkg.tar.xz return super(format.nil? ? "NAME-FULLVERSION-ARCH.EXTENSION" : format) end
FPM::Package#to_s
Source
# File lib/fpm/package/pacman.rb, line 324 def to_s_extension; "pkg.tar#{compression_ending}"; end
Private Instance Methods
Source
# File lib/fpm/package/pacman.rb, line 334 def generate_mtree ::Dir.chdir(build_path) do cmd = "LANG=C bsdtar " cmd += "-czf .MTREE " cmd += "--format=mtree " cmd += "--options='!all,use-set,type,uid,gid,mode,time,size,md5,sha256,link' " cmd += ::Dir.entries(".").reject{|entry| entry =~ /^\.{1,2}$/ }.join(" ") safesystem(cmd) end end
Source
# File lib/fpm/package/pacman.rb, line 352 def gobble_function(cons,prod) level = 1 while level > 0 line = cons.next # Not the best, but pretty good # short of writing an *actual* sh # parser level += line.count "{" level -= line.count "}" if level > 0 prod.push(line.rstrip()) else fine = line.sub(/\s*[}]\s*$/, "") if !(fine =~ /^\s*$/) prod.push(fine.rstrip()) end end end end
KNOWN ISSUE: If an un-matched bracket is used in valid bash, as in ‘echo “{”`, this function will choke. However, to cover this case basically requires writing almost half a bash parser, and it is a very small corner case. Otherwise, this approach is very robust.
Source
# File lib/fpm/package/pacman.rb, line 375 def parse_install_script(path) global_lines = [] look_for = Set.new(["pre_install", "post_install", "pre_upgrade", "post_upgrade", "pre_remove", "post_remove"]) functions = {} look_for.each do |fname| functions[fname] = [] end open(path, "r") do |iscript| lines = iscript.each begin while true line = lines.next # This regex picks up beginning names of posix shell # functions # Examples: # fname() { # fname() { echo hi } m = FIND_SCRIPT_FUNCTION_LINE.match(line) if not m.nil? and look_for.include? m[1] if not m[2].nil? functions[m[1]].push(m[2].rstrip()) end gobble_function(lines, functions[m[1]]) else global_lines.push(line.rstrip()) end end rescue StopIteration end end look_for.each do |name| # Add global lines to each function to preserve global variables, etc. functions[name] = global_lines + functions[name] end return functions end