fpm 1.10.2 → 1.15.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/CHANGELOG.rst +101 -5
- data/CONTRIBUTORS +1 -0
- data/LICENSE +1 -1
- data/lib/fpm/command.rb +90 -0
- data/lib/fpm/package/apk.rb +1 -1
- data/lib/fpm/package/cpan.rb +2 -1
- data/lib/fpm/package/deb.rb +200 -27
- data/lib/fpm/package/dir.rb +3 -3
- data/lib/fpm/package/empty.rb +13 -1
- data/lib/fpm/package/freebsd.rb +13 -20
- data/lib/fpm/package/gem.rb +50 -14
- data/lib/fpm/package/osxpkg.rb +6 -1
- data/lib/fpm/package/pacman.rb +22 -10
- data/lib/fpm/package/pleaserun.rb +1 -0
- data/lib/fpm/package/pyfpm/get_metadata.py +5 -0
- data/lib/fpm/package/python.rb +54 -7
- data/lib/fpm/package/rpm.rb +56 -16
- data/lib/fpm/package/sh.rb +1 -1
- data/lib/fpm/package/snap.rb +130 -0
- data/lib/fpm/package/tar.rb +1 -1
- data/lib/fpm/package/virtualenv.rb +3 -2
- data/lib/fpm/package/zip.rb +1 -1
- data/lib/fpm/package.rb +5 -4
- data/lib/fpm/util/tar_writer.rb +1 -1
- data/lib/fpm/util.rb +59 -46
- data/lib/fpm/version.rb +1 -1
- data/lib/fpm.rb +1 -0
- data/templates/deb/changelog.erb +1 -1
- data/templates/deb/deb.changes.erb +2 -3
- data/templates/deb/postinst_upgrade.sh.erb +30 -8
- data/templates/deb/postrm_upgrade.sh.erb +5 -0
- data/templates/deb/preinst_upgrade.sh.erb +5 -0
- data/templates/deb/prerm_upgrade.sh.erb +12 -4
- data/templates/deb.erb +2 -2
- data/templates/rpm.erb +5 -5
- data/templates/sh.erb +6 -1
- metadata +30 -78
data/lib/fpm/package/deb.rb
CHANGED
@@ -3,9 +3,14 @@ require "fpm/namespace"
|
|
3
3
|
require "fpm/package"
|
4
4
|
require "fpm/errors"
|
5
5
|
require "fpm/util"
|
6
|
-
require "backports"
|
6
|
+
require "backports/latest"
|
7
7
|
require "fileutils"
|
8
8
|
require "digest"
|
9
|
+
require "zlib"
|
10
|
+
|
11
|
+
# For handling conversion
|
12
|
+
require "fpm/package/cpan"
|
13
|
+
require "fpm/package/gem"
|
9
14
|
|
10
15
|
# Support for debian packages (.deb files)
|
11
16
|
#
|
@@ -22,7 +27,23 @@ class FPM::Package::Deb < FPM::Package
|
|
22
27
|
} unless defined?(SCRIPT_MAP)
|
23
28
|
|
24
29
|
# The list of supported compression types. Default is gz (gzip)
|
25
|
-
COMPRESSION_TYPES = [ "gz", "bzip2", "xz" ]
|
30
|
+
COMPRESSION_TYPES = [ "gz", "bzip2", "xz", "none" ]
|
31
|
+
|
32
|
+
# https://www.debian.org/doc/debian-policy/ch-relationships.html#syntax-of-relationship-fields
|
33
|
+
# Example value with version relationship: libc6 (>= 2.2.1)
|
34
|
+
# Example value: libc6
|
35
|
+
|
36
|
+
# Package name docs here: https://www.debian.org/doc/debian-policy/ch-controlfields.html#s-f-source
|
37
|
+
# Package names (both source and binary, see Package) must consist only of lower case letters (a-z),
|
38
|
+
# digits (0-9), plus (+) and minus (-) signs, and periods (.).
|
39
|
+
# They must be at least two characters long and must start with an alphanumeric character.
|
40
|
+
|
41
|
+
# Version string docs here: https://www.debian.org/doc/debian-policy/ch-controlfields.html#s-f-version
|
42
|
+
# The format is: [epoch:]upstream_version[-debian_revision].
|
43
|
+
# epoch - This is a single (generally small) unsigned integer
|
44
|
+
# upstream_version - must contain only alphanumerics 6 and the characters . + - ~
|
45
|
+
# debian_revision - only alphanumerics and the characters + . ~
|
46
|
+
RELATIONSHIP_FIELD_PATTERN = /^(?<name>[A-z0-9][A-z0-9_.-]+)(?: *\((?<relation>[<>=]+) *(?<version>(?:[0-9]+:)?[0-9A-Za-z+~.-]+(?:-[0-9A-Za-z+~.]+)?)\))?$/
|
26
47
|
|
27
48
|
option "--ignore-iteration-in-dependencies", :flag,
|
28
49
|
"For '=' (equal) dependencies, allow iterations on the specified " \
|
@@ -77,7 +98,7 @@ class FPM::Package::Deb < FPM::Package
|
|
77
98
|
end
|
78
99
|
|
79
100
|
option "--priority", "PRIORITY",
|
80
|
-
"The debian package 'priority' value.", :default => "
|
101
|
+
"The debian package 'priority' value.", :default => "optional"
|
81
102
|
|
82
103
|
option "--use-file-permissions", :flag,
|
83
104
|
"Use existing file permissions when defining ownership and modes"
|
@@ -177,10 +198,14 @@ class FPM::Package::Deb < FPM::Package
|
|
177
198
|
end
|
178
199
|
|
179
200
|
option "--systemd", "FILEPATH", "Add FILEPATH as a systemd script",
|
180
|
-
|
201
|
+
:multivalued => true do |file|
|
181
202
|
next File.expand_path(file)
|
182
203
|
end
|
183
204
|
|
205
|
+
option "--systemd-enable", :flag , "Enable service on install or upgrade", :default => false
|
206
|
+
|
207
|
+
option "--systemd-auto-start", :flag , "Start service after install or upgrade", :default => false
|
208
|
+
|
184
209
|
option "--systemd-restart-after-upgrade", :flag , "Restart service after upgrade", :default => true
|
185
210
|
|
186
211
|
option "--after-purge", "FILE",
|
@@ -189,9 +214,14 @@ class FPM::Package::Deb < FPM::Package
|
|
189
214
|
File.expand_path(val) # Get the full path to the script
|
190
215
|
end # --after-purge
|
191
216
|
|
217
|
+
option "--maintainerscripts-force-errorchecks", :flag ,
|
218
|
+
"Activate errexit shell option according to lintian. " \
|
219
|
+
"https://lintian.debian.org/tags/maintainer-script-ignores-errors.html",
|
220
|
+
:default => false
|
221
|
+
|
192
222
|
def initialize(*args)
|
193
223
|
super(*args)
|
194
|
-
attributes[:deb_priority] = "
|
224
|
+
attributes[:deb_priority] = "optional"
|
195
225
|
end # def initialize
|
196
226
|
|
197
227
|
private
|
@@ -218,6 +248,9 @@ class FPM::Package::Deb < FPM::Package
|
|
218
248
|
when "x86_64"
|
219
249
|
# Debian calls x86_64 "amd64"
|
220
250
|
@architecture = "amd64"
|
251
|
+
when "aarch64"
|
252
|
+
# Debian calls aarch64 "arm64"
|
253
|
+
@architecture = "arm64"
|
221
254
|
when "noarch"
|
222
255
|
# Debian calls noarch "all"
|
223
256
|
@architecture = "all"
|
@@ -265,10 +298,32 @@ class FPM::Package::Deb < FPM::Package
|
|
265
298
|
end # def input
|
266
299
|
|
267
300
|
def extract_info(package)
|
301
|
+
compression = `#{ar_cmd[0]} t #{package}`.split("\n").grep(/control.tar/).first.split(".").last
|
302
|
+
case compression
|
303
|
+
when "gz"
|
304
|
+
controltar = "control.tar.gz"
|
305
|
+
compression = "-z"
|
306
|
+
when "bzip2","bz2"
|
307
|
+
controltar = "control.tar.bz2"
|
308
|
+
compression = "-j"
|
309
|
+
when "xz"
|
310
|
+
controltar = "control.tar.xz"
|
311
|
+
compression = "-J"
|
312
|
+
when 'tar'
|
313
|
+
controltar = "control.tar"
|
314
|
+
compression = ""
|
315
|
+
when nil
|
316
|
+
raise FPM::InvalidPackageConfiguration, "Missing control.tar in deb source package #{package}"
|
317
|
+
else
|
318
|
+
raise FPM::InvalidPackageConfiguration,
|
319
|
+
"Unknown compression type '#{compression}' for control.tar in deb source package #{package}"
|
320
|
+
end
|
321
|
+
|
268
322
|
build_path("control").tap do |path|
|
269
323
|
FileUtils.mkdir(path) if !File.directory?(path)
|
324
|
+
# unpack the control.tar.{,gz,bz2,xz} from the deb package into staging_path
|
270
325
|
# Unpack the control tarball
|
271
|
-
safesystem(ar_cmd[0] + " p #{package}
|
326
|
+
safesystem(ar_cmd[0] + " p #{package} #{controltar} | tar #{compression} -xf - -C #{path}")
|
272
327
|
|
273
328
|
control = File.read(File.join(path, "control"))
|
274
329
|
|
@@ -376,19 +431,28 @@ class FPM::Package::Deb < FPM::Package
|
|
376
431
|
when "xz"
|
377
432
|
datatar = "data.tar.xz"
|
378
433
|
compression = "-J"
|
434
|
+
when 'tar'
|
435
|
+
datatar = "data.tar"
|
436
|
+
compression = ""
|
437
|
+
when nil
|
438
|
+
raise FPM::InvalidPackageConfiguration, "Missing data.tar in deb source package #{package}"
|
379
439
|
else
|
380
440
|
raise FPM::InvalidPackageConfiguration,
|
381
|
-
"Unknown compression type '#{
|
382
|
-
"in deb source package #{package}"
|
441
|
+
"Unknown compression type '#{compression}' for data.tar in deb source package #{package}"
|
383
442
|
end
|
384
443
|
|
385
444
|
# unpack the data.tar.{gz,bz2,xz} from the deb package into staging_path
|
386
|
-
safesystem(ar_cmd[0] + " p #{package} #{datatar} "
|
387
|
-
"| tar #{compression} -xf - -C #{staging_path}")
|
445
|
+
safesystem(ar_cmd[0] + " p #{package} #{datatar} | tar #{compression} -xf - -C #{staging_path}")
|
388
446
|
end # def extract_files
|
389
447
|
|
390
448
|
def output(output_path)
|
391
449
|
self.provides = self.provides.collect { |p| fix_provides(p) }
|
450
|
+
|
451
|
+
self.provides.each do |provide|
|
452
|
+
if !valid_provides_field?(provide)
|
453
|
+
raise FPM::InvalidPackageConfiguration, "Found invalid Provides field values (#{provide.inspect}). This is not valid in a Debian package."
|
454
|
+
end
|
455
|
+
end
|
392
456
|
output_check(output_path)
|
393
457
|
# Abort if the target path already exists.
|
394
458
|
|
@@ -428,6 +492,7 @@ class FPM::Package::Deb < FPM::Package
|
|
428
492
|
raise "#{name}: tar is insufficient to support source_date_epoch."
|
429
493
|
end
|
430
494
|
|
495
|
+
attributes[:deb_systemd] = []
|
431
496
|
attributes.fetch(:deb_systemd_list, []).each do |systemd|
|
432
497
|
name = File.basename(systemd, ".service")
|
433
498
|
dest_systemd = staging_path("lib/systemd/system/#{name}.service")
|
@@ -435,19 +500,19 @@ class FPM::Package::Deb < FPM::Package
|
|
435
500
|
FileUtils.cp(systemd, dest_systemd)
|
436
501
|
File.chmod(0644, dest_systemd)
|
437
502
|
|
438
|
-
#
|
439
|
-
attributes[:deb_systemd]
|
503
|
+
# add systemd service name to attribute
|
504
|
+
attributes[:deb_systemd] << name
|
440
505
|
end
|
441
506
|
|
442
|
-
if script?(:before_upgrade) or script?(:after_upgrade) or attributes[:deb_systemd]
|
507
|
+
if script?(:before_upgrade) or script?(:after_upgrade) or attributes[:deb_systemd].any?
|
443
508
|
puts "Adding action files"
|
444
509
|
if script?(:before_install) or script?(:before_upgrade)
|
445
510
|
scripts[:before_install] = template("deb/preinst_upgrade.sh.erb").result(binding)
|
446
511
|
end
|
447
|
-
if script?(:before_remove) or attributes[:deb_systemd]
|
512
|
+
if script?(:before_remove) or not attributes[:deb_systemd].empty?
|
448
513
|
scripts[:before_remove] = template("deb/prerm_upgrade.sh.erb").result(binding)
|
449
514
|
end
|
450
|
-
if script?(:after_install) or script?(:after_upgrade) or attributes[:deb_systemd]
|
515
|
+
if script?(:after_install) or script?(:after_upgrade) or attributes[:deb_systemd].any?
|
451
516
|
scripts[:after_install] = template("deb/postinst_upgrade.sh.erb").result(binding)
|
452
517
|
end
|
453
518
|
if script?(:after_remove)
|
@@ -552,19 +617,25 @@ class FPM::Package::Deb < FPM::Package
|
|
552
617
|
case self.attributes[:deb_compression]
|
553
618
|
when "gz", nil
|
554
619
|
datatar = build_path("data.tar.gz")
|
555
|
-
|
620
|
+
controltar = build_path("control.tar.gz")
|
621
|
+
compression_flags = ["-z"]
|
556
622
|
when "bzip2"
|
557
623
|
datatar = build_path("data.tar.bz2")
|
558
|
-
|
624
|
+
controltar = build_path("control.tar.gz")
|
625
|
+
compression_flags = ["-j"]
|
559
626
|
when "xz"
|
560
627
|
datatar = build_path("data.tar.xz")
|
561
|
-
|
628
|
+
controltar = build_path("control.tar.xz")
|
629
|
+
compression_flags = ["-J"]
|
630
|
+
when "none"
|
631
|
+
datatar = build_path("data.tar")
|
632
|
+
controltar = build_path("control.tar")
|
633
|
+
compression_flags = []
|
562
634
|
else
|
563
635
|
raise FPM::InvalidPackageConfiguration,
|
564
636
|
"Unknown compression type '#{self.attributes[:deb_compression]}'"
|
565
637
|
end
|
566
|
-
|
567
|
-
args = [ tar_cmd, "-C", staging_path, compression ] + data_tar_flags + [ "-cf", datatar, "." ]
|
638
|
+
args = [ tar_cmd, "-C", staging_path ] + compression_flags + data_tar_flags + [ "-cf", datatar, "." ]
|
568
639
|
if tar_cmd_supports_sort_names_and_set_mtime? and not attributes[:source_date_epoch].nil?
|
569
640
|
# Use gnu tar options to force deterministic file order and timestamp
|
570
641
|
args += ["--sort=name", ("--mtime=@%s" % attributes[:source_date_epoch])]
|
@@ -577,7 +648,7 @@ class FPM::Package::Deb < FPM::Package
|
|
577
648
|
# the 'debian-binary' file has to be first
|
578
649
|
File.expand_path(output_path).tap do |output_path|
|
579
650
|
::Dir.chdir(build_path) do
|
580
|
-
safesystem(*ar_cmd, output_path, "debian-binary",
|
651
|
+
safesystem(*ar_cmd, output_path, "debian-binary", controltar, datatar)
|
581
652
|
end
|
582
653
|
end
|
583
654
|
|
@@ -614,6 +685,43 @@ class FPM::Package::Deb < FPM::Package
|
|
614
685
|
fix_provides(provides)
|
615
686
|
end.flatten
|
616
687
|
|
688
|
+
if origin == FPM::Package::CPAN
|
689
|
+
# The fpm cpan code presents dependencies and provides fields as perl(ModuleName)
|
690
|
+
# so we'll need to convert them to something debian supports.
|
691
|
+
|
692
|
+
# Replace perl(ModuleName) > 1.0 with Debian-style perl-ModuleName (> 1.0)
|
693
|
+
perldepfix = lambda do |dep|
|
694
|
+
m = dep.match(/perl\((?<name>[A-Za-z0-9_:]+)\)\s*(?<op>.*$)/)
|
695
|
+
if m.nil?
|
696
|
+
# 'dep' syntax didn't look like 'perl(Name) > 1.0'
|
697
|
+
dep
|
698
|
+
else
|
699
|
+
# Also replace '::' in the perl module name with '-'
|
700
|
+
modulename = m["name"].gsub("::", "-")
|
701
|
+
|
702
|
+
# Fix any upper-casing or other naming concerns Debian has about packages
|
703
|
+
name = "#{attributes[:cpan_package_name_prefix]}-#{modulename}"
|
704
|
+
|
705
|
+
if m["op"].empty?
|
706
|
+
name
|
707
|
+
else
|
708
|
+
# 'dep' syntax was like this (version constraint): perl(Module) > 1.0
|
709
|
+
"#{name} (#{m["op"]})"
|
710
|
+
end
|
711
|
+
end
|
712
|
+
end
|
713
|
+
|
714
|
+
rejects = [ "perl(vars)", "perl(warnings)", "perl(strict)", "perl(Config)" ]
|
715
|
+
self.dependencies = self.dependencies.reject do |dep|
|
716
|
+
# Reject non-module Perl dependencies like 'vars' and 'warnings'
|
717
|
+
rejects.include?(dep)
|
718
|
+
end.collect(&perldepfix).collect(&method(:fix_dependency))
|
719
|
+
|
720
|
+
# Also fix the Provides field 'perl(ModuleName) = version' to be 'perl-modulename (= version)'
|
721
|
+
self.provides = self.provides.collect(&perldepfix).collect(&method(:fix_provides))
|
722
|
+
|
723
|
+
end # if origin == FPM::Packagin::CPAN
|
724
|
+
|
617
725
|
if origin == FPM::Package::Deb
|
618
726
|
changelog_path = staging_path("usr/share/doc/#{name}/changelog.Debian.gz")
|
619
727
|
if File.exists?(changelog_path)
|
@@ -641,6 +749,19 @@ class FPM::Package::Deb < FPM::Package
|
|
641
749
|
File.unlink(changelog_path)
|
642
750
|
end
|
643
751
|
end
|
752
|
+
|
753
|
+
if origin == FPM::Package::Gem
|
754
|
+
# fpm's gem input will have provides as "rubygem-name = version"
|
755
|
+
# and we need to convert this to Debian-style "rubygem-name (= version)"
|
756
|
+
self.provides = self.provides.collect do |provides|
|
757
|
+
m = /^(#{attributes[:gem_package_name_prefix]})-([^\s]+)\s*=\s*(.*)$/.match(provides)
|
758
|
+
if m
|
759
|
+
"#{m[1]}-#{m[2]} (= #{m[3]})"
|
760
|
+
else
|
761
|
+
provides
|
762
|
+
end
|
763
|
+
end
|
764
|
+
end
|
644
765
|
end # def converted_from
|
645
766
|
|
646
767
|
def debianize_op(op)
|
@@ -682,8 +803,13 @@ class FPM::Package::Deb < FPM::Package
|
|
682
803
|
name, version = dep.gsub(/[()~>]/, "").split(/ +/)[0..1]
|
683
804
|
nextversion = version.split(".").collect { |v| v.to_i }
|
684
805
|
l = nextversion.length
|
685
|
-
|
686
|
-
|
806
|
+
if l > 1
|
807
|
+
nextversion[l-2] += 1
|
808
|
+
nextversion[l-1] = 0
|
809
|
+
else
|
810
|
+
# Single component versions ~> 1
|
811
|
+
nextversion[l-1] += 1
|
812
|
+
end
|
687
813
|
nextversion = nextversion.join(".")
|
688
814
|
return ["#{name} (>= #{version})", "#{name} (<< #{nextversion})"]
|
689
815
|
elsif (m = dep.match(/(\S+)\s+\(!= (.+)\)/))
|
@@ -710,6 +836,32 @@ class FPM::Package::Deb < FPM::Package
|
|
710
836
|
end
|
711
837
|
end # def fix_dependency
|
712
838
|
|
839
|
+
def valid_provides_field?(text)
|
840
|
+
m = RELATIONSHIP_FIELD_PATTERN.match(text)
|
841
|
+
if m.nil?
|
842
|
+
logger.error("Invalid relationship field for debian package: #{text}")
|
843
|
+
return false
|
844
|
+
end
|
845
|
+
|
846
|
+
# Per Debian Policy manual, https://www.debian.org/doc/debian-policy/ch-relationships.html#syntax-of-relationship-fields
|
847
|
+
# >> The relations allowed are <<, <=, =, >= and >> for strictly earlier, earlier or equal,
|
848
|
+
# >> exactly equal, later or equal and strictly later, respectively. The exception is the
|
849
|
+
# >> Provides field, for which only = is allowed
|
850
|
+
if m["relation"] == "=" || m["relation"] == nil
|
851
|
+
return true
|
852
|
+
end
|
853
|
+
return false
|
854
|
+
end
|
855
|
+
|
856
|
+
def valid_relationship_field?(text)
|
857
|
+
m = RELATIONSHIP_FIELD_PATTERN.match(text)
|
858
|
+
if m.nil?
|
859
|
+
logger.error("Invalid relationship field for debian package: #{text}")
|
860
|
+
return false
|
861
|
+
end
|
862
|
+
return true
|
863
|
+
end
|
864
|
+
|
713
865
|
def fix_provides(provides)
|
714
866
|
name_re = /^[^ \(]+/
|
715
867
|
name = provides[name_re]
|
@@ -724,6 +876,11 @@ class FPM::Package::Deb < FPM::Package
|
|
724
876
|
"debs don't like underscores")
|
725
877
|
provides = provides.gsub("_", "-")
|
726
878
|
end
|
879
|
+
|
880
|
+
if m = provides.match(/^([A-Za-z0-9_-]+)\s*=\s*(\d+.*$)/)
|
881
|
+
logger.warn("Replacing 'provides' entry #{provides} with syntax 'name (= version)'")
|
882
|
+
provides = "#{m[1]} (= #{m[2]})"
|
883
|
+
end
|
727
884
|
return provides.rstrip
|
728
885
|
end
|
729
886
|
|
@@ -749,11 +906,27 @@ class FPM::Package::Deb < FPM::Package
|
|
749
906
|
write_triggers # write trigger config to 'triggers' file
|
750
907
|
write_md5sums # write the md5sums file
|
751
908
|
|
909
|
+
# Tar up the staging_path into control.tar.{compression type}
|
910
|
+
case self.attributes[:deb_compression]
|
911
|
+
when "gz", "bzip2", nil
|
912
|
+
controltar = "control.tar.gz"
|
913
|
+
compression_flags = ["-z"]
|
914
|
+
when "xz"
|
915
|
+
controltar = "control.tar.xz"
|
916
|
+
compression_flags = ["-J"]
|
917
|
+
when "none"
|
918
|
+
controltar = "control.tar"
|
919
|
+
compression_flags = []
|
920
|
+
else
|
921
|
+
raise FPM::InvalidPackageConfiguration,
|
922
|
+
"Unknown compression type '#{self.attributes[:deb_compression]}'"
|
923
|
+
end
|
924
|
+
|
752
925
|
# Make the control.tar.gz
|
753
|
-
build_path(
|
926
|
+
build_path(controltar).tap do |controltar|
|
754
927
|
logger.info("Creating", :path => controltar, :from => control_path)
|
755
928
|
|
756
|
-
args = [ tar_cmd, "-C", control_path
|
929
|
+
args = [ tar_cmd, "-C", control_path ] + compression_flags + [ "-cf", controltar,
|
757
930
|
"--owner=0", "--group=0", "--numeric-owner", "." ]
|
758
931
|
if tar_cmd_supports_sort_names_and_set_mtime? and not attributes[:source_date_epoch].nil?
|
759
932
|
# Force deterministic file order and timestamp
|
@@ -842,7 +1015,7 @@ class FPM::Package::Deb < FPM::Package
|
|
842
1015
|
etcfiles = []
|
843
1016
|
# Add everything in /etc
|
844
1017
|
begin
|
845
|
-
if !attributes[:deb_no_default_config_files?]
|
1018
|
+
if !attributes[:deb_no_default_config_files?] && File.exists?(staging_path("/etc"))
|
846
1019
|
logger.warn("Debian packaging tools generally labels all files in /etc as config files, " \
|
847
1020
|
"as mandated by policy, so fpm defaults to this behavior for deb packages. " \
|
848
1021
|
"You can disable this default behavior with --deb-no-default-config-files flag")
|
@@ -931,7 +1104,7 @@ class FPM::Package::Deb < FPM::Package
|
|
931
1104
|
|
932
1105
|
if attributes[:deb_templates]
|
933
1106
|
FileUtils.cp(attributes[:deb_templates], control_path("templates"))
|
934
|
-
File.chmod(
|
1107
|
+
File.chmod(0644, control_path("templates"))
|
935
1108
|
end
|
936
1109
|
end # def write_debconf
|
937
1110
|
|
data/lib/fpm/package/dir.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
require "fpm/package"
|
2
2
|
require "fpm/util"
|
3
|
-
require "backports"
|
3
|
+
require "backports/latest"
|
4
4
|
require "fileutils"
|
5
5
|
require "find"
|
6
6
|
require "socket"
|
@@ -83,8 +83,8 @@ class FPM::Package::Dir < FPM::Package
|
|
83
83
|
# can include license data from themselves (rpms, gems, etc),
|
84
84
|
# but to make sure a simple dir -> rpm works without having
|
85
85
|
# to specify a license.
|
86
|
-
self.license
|
87
|
-
self.vendor
|
86
|
+
self.license ||= "unknown"
|
87
|
+
self.vendor ||= [ENV["USER"], Socket.gethostname].join("@")
|
88
88
|
ensure
|
89
89
|
# Clean up any logger context we added.
|
90
90
|
logger.remove("method")
|
data/lib/fpm/package/empty.rb
CHANGED
@@ -1,9 +1,21 @@
|
|
1
1
|
require "fpm/package"
|
2
|
-
require "backports"
|
2
|
+
require "backports/latest"
|
3
3
|
|
4
4
|
# Empty Package type. For strict/meta/virtual package creation
|
5
5
|
|
6
6
|
class FPM::Package::Empty < FPM::Package
|
7
|
+
def initialize(*args)
|
8
|
+
super(*args)
|
9
|
+
|
10
|
+
# Override FPM::Package's default "native" architecture value
|
11
|
+
# This feels like the right default because an empty package has no
|
12
|
+
# architecture-specific files, and in most cases an empty package should be
|
13
|
+
# installable anywhere.
|
14
|
+
#
|
15
|
+
# https://github.com/jordansissel/fpm/issues/1846
|
16
|
+
@architecture = "all"
|
17
|
+
end
|
18
|
+
|
7
19
|
def output(output_path)
|
8
20
|
logger.warn("Your package has gone into the void.")
|
9
21
|
end
|
data/lib/fpm/package/freebsd.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
require "backports" # gem backports
|
1
|
+
require "backports/latest" # gem backports/latest
|
2
2
|
require "fpm/package"
|
3
3
|
require "fpm/util"
|
4
4
|
require "digest"
|
@@ -17,10 +17,6 @@ class FPM::Package::FreeBSD < FPM::Package
|
|
17
17
|
:default => "fpm/<name>"
|
18
18
|
|
19
19
|
def output(output_path)
|
20
|
-
# See https://github.com/jordansissel/fpm/issues/1090
|
21
|
-
# require xz later, because this triggers a load of liblzma.so.5 that is
|
22
|
-
# unavailable on older CentOS/RH distros.
|
23
|
-
require "xz"
|
24
20
|
output_check(output_path)
|
25
21
|
|
26
22
|
# Build the packaging metadata files.
|
@@ -80,22 +76,17 @@ class FPM::Package::FreeBSD < FPM::Package
|
|
80
76
|
file.write(pkgdata.to_json + "\n")
|
81
77
|
end
|
82
78
|
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
FPM::Util::TarWriter.new(xz) do |tar|
|
87
|
-
# The manifests must come first for pkg.
|
88
|
-
add_path(tar, "+COMPACT_MANIFEST",
|
89
|
-
File.join(staging_path, "+COMPACT_MANIFEST"))
|
90
|
-
add_path(tar, "+MANIFEST",
|
91
|
-
File.join(staging_path, "+MANIFEST"))
|
92
|
-
|
93
|
-
checksums.keys.each do |path|
|
94
|
-
add_path(tar, "/" + path, File.join(staging_path, path))
|
95
|
-
end
|
96
|
-
end
|
97
|
-
end
|
79
|
+
file_list = File.new(build_path("file_list"), "w")
|
80
|
+
files.each do |i|
|
81
|
+
file_list.puts(i)
|
98
82
|
end
|
83
|
+
file_list.close
|
84
|
+
|
85
|
+
# Create the .txz package archive from the files in staging_path.
|
86
|
+
# We use --files-from here to keep the tar entries from having `./` as the prefix.
|
87
|
+
# This is done as a best effor to mimic what FreeBSD packages do, having everything at the top-level as
|
88
|
+
# file names, like "+MANIFEST" instead of "./+MANIFEST"
|
89
|
+
safesystem("tar", "-Jcf", output_path, "-C", staging_path, "--files-from", build_path("file_list"), "--transform", 's|^\([^+]\)|/\1|')
|
99
90
|
end # def output
|
100
91
|
|
101
92
|
# Handle architecture naming conversion:
|
@@ -110,6 +101,8 @@ class FPM::Package::FreeBSD < FPM::Package
|
|
110
101
|
wordsize = case @architecture
|
111
102
|
when nil, 'native'
|
112
103
|
%x{getconf LONG_BIT}.chomp # 'native' is current arch
|
104
|
+
when 'arm64'
|
105
|
+
'64'
|
113
106
|
when 'amd64'
|
114
107
|
'64'
|
115
108
|
when 'i386'
|
data/lib/fpm/package/gem.rb
CHANGED
@@ -53,6 +53,15 @@ class FPM::Package::Gem < FPM::Package
|
|
53
53
|
"The directory where fpm installs the gem temporarily before conversion. " \
|
54
54
|
"Normally a random subdirectory of workdir."
|
55
55
|
|
56
|
+
option "--git-repo", "GIT_REPO",
|
57
|
+
"Use this git repo address as the source of the gem instead of " \
|
58
|
+
"rubygems.org.", :default => nil
|
59
|
+
|
60
|
+
option "--git-branch", "GIT_BRANCH",
|
61
|
+
"When using a git repo as the source of the gem instead of " \
|
62
|
+
"rubygems.org, use this git branch.",
|
63
|
+
:default => nil
|
64
|
+
|
56
65
|
# Override parent method
|
57
66
|
def staging_path(path=nil)
|
58
67
|
@gem_staging_path ||= attributes[:gem_stagingdir] || Stud::Temporary.directory("package-#{type}-staging")
|
@@ -91,20 +100,32 @@ class FPM::Package::Gem < FPM::Package
|
|
91
100
|
|
92
101
|
logger.info("Trying to download", :gem => gem_name, :version => gem_version)
|
93
102
|
|
94
|
-
gem_fetch = [ "#{attributes[:gem_gem]}", "fetch", gem_name]
|
95
|
-
|
96
|
-
gem_fetch += ["--prerelease"] if attributes[:gem_prerelease?]
|
97
|
-
gem_fetch += ["--version", gem_version] if gem_version
|
98
|
-
|
99
103
|
download_dir = build_path(gem_name)
|
100
104
|
FileUtils.mkdir(download_dir) unless File.directory?(download_dir)
|
101
105
|
|
102
|
-
|
103
|
-
logger.debug("
|
104
|
-
safesystem(
|
105
|
-
|
106
|
+
if attributes[:gem_git_repo]
|
107
|
+
logger.debug("Git cloning in directory #{download_dir}")
|
108
|
+
safesystem("git", "-C", download_dir, "clone", attributes[:gem_git_repo], ".")
|
109
|
+
if attributes[:gem_git_branch]
|
110
|
+
safesystem("git", "-C", download_dir, "checkout", attributes[:gem_git_branch])
|
111
|
+
end
|
106
112
|
|
107
|
-
|
113
|
+
gem_build = [ "#{attributes[:gem_gem]}", "build", "#{download_dir}/#{gem_name}.gemspec"]
|
114
|
+
::Dir.chdir(download_dir) do |dir|
|
115
|
+
logger.debug("Building in directory #{dir}")
|
116
|
+
safesystem(*gem_build)
|
117
|
+
end
|
118
|
+
gem_files = ::Dir.glob(File.join(download_dir, "*.gem"))
|
119
|
+
else
|
120
|
+
gem_fetch = [ "#{attributes[:gem_gem]}", "fetch", gem_name]
|
121
|
+
gem_fetch += ["--prerelease"] if attributes[:gem_prerelease?]
|
122
|
+
gem_fetch += ["--version", gem_version] if gem_version
|
123
|
+
::Dir.chdir(download_dir) do |dir|
|
124
|
+
logger.debug("Downloading in directory #{dir}")
|
125
|
+
safesystem(*gem_fetch)
|
126
|
+
end
|
127
|
+
gem_files = ::Dir.glob(File.join(download_dir, "*.gem"))
|
128
|
+
end
|
108
129
|
|
109
130
|
if gem_files.length != 1
|
110
131
|
raise "Unexpected number of gem files in #{download_dir}, #{gem_files.length} should be 1"
|
@@ -113,9 +134,19 @@ class FPM::Package::Gem < FPM::Package
|
|
113
134
|
return gem_files.first
|
114
135
|
end # def download
|
115
136
|
|
137
|
+
GEMSPEC_YAML_CLASSES = [ ::Gem::Specification, ::Gem::Version, Time, ::Gem::Dependency, ::Gem::Requirement, Symbol ]
|
116
138
|
def load_package_info(gem_path)
|
117
|
-
|
118
|
-
|
139
|
+
# TODO(sissel): Maybe we should check if `safe_load` method exists instead of this version check?
|
140
|
+
if ::Gem::Version.new(RUBY_VERSION) >= ::Gem::Version.new("3.1.0")
|
141
|
+
# Ruby 3.1.0 switched to a Psych/YAML version that defaults to "safe" loading
|
142
|
+
# and unfortunately `gem specification --yaml` emits YAML that requires
|
143
|
+
# class loaders to process correctly
|
144
|
+
spec = YAML.load(%x{#{attributes[:gem_gem]} specification #{gem_path} --yaml},
|
145
|
+
:permitted_classes => GEMSPEC_YAML_CLASSES)
|
146
|
+
else
|
147
|
+
# Older versions of ruby call this method YAML.safe_load
|
148
|
+
spec = YAML.safe_load(%x{#{attributes[:gem_gem]} specification #{gem_path} --yaml}, GEMSPEC_YAML_CLASSES)
|
149
|
+
end
|
119
150
|
|
120
151
|
if !attributes[:gem_package_prefix].nil?
|
121
152
|
attributes[:gem_package_name_prefix] = attributes[:gem_package_prefix]
|
@@ -198,8 +229,13 @@ class FPM::Package::Gem < FPM::Package
|
|
198
229
|
|
199
230
|
::FileUtils.mkdir_p(installdir)
|
200
231
|
# TODO(sissel): Allow setting gem tool path
|
201
|
-
args = [attributes[:gem_gem], "install", "--quiet", "--no-
|
202
|
-
|
232
|
+
args = [attributes[:gem_gem], "install", "--quiet", "--no-user-install", "--install-dir", installdir]
|
233
|
+
if ::Gem::VERSION =~ /^[012]\./
|
234
|
+
args += [ "--no-ri", "--no-rdoc" ]
|
235
|
+
else
|
236
|
+
# Rubygems 3.0.0 changed --no-ri to --no-document
|
237
|
+
args += [ "--no-document" ]
|
238
|
+
end
|
203
239
|
|
204
240
|
if !attributes[:gem_embed_dependencies?]
|
205
241
|
args += ["--ignore-dependencies"]
|
data/lib/fpm/package/osxpkg.rb
CHANGED
@@ -4,7 +4,6 @@ require "fileutils"
|
|
4
4
|
require "fpm/package/dir"
|
5
5
|
require 'tempfile' # stdlib
|
6
6
|
require 'pathname' # stdlib
|
7
|
-
require 'rexml/document' # stdlib
|
8
7
|
|
9
8
|
# Use an OS X pkg built with pkgbuild.
|
10
9
|
#
|
@@ -103,6 +102,7 @@ class FPM::Package::OSXpkg < FPM::Package
|
|
103
102
|
|
104
103
|
# Extract name and version from PackageInfo XML
|
105
104
|
def extract_info(package)
|
105
|
+
require 'rexml/document'
|
106
106
|
build_path("expand").tap do |path|
|
107
107
|
doc = REXML::Document.new File.open(File.join(path, "PackageInfo"))
|
108
108
|
pkginfo_elem = doc.elements["pkg-info"]
|
@@ -148,6 +148,11 @@ class FPM::Package::OSXpkg < FPM::Package
|
|
148
148
|
write_scripts
|
149
149
|
args += ["--scripts", scripts_path]
|
150
150
|
end
|
151
|
+
|
152
|
+
if attributes[:prefix]
|
153
|
+
args += ["--install-location", attributes[:prefix]]
|
154
|
+
end
|
155
|
+
|
151
156
|
args << output_path
|
152
157
|
|
153
158
|
safesystem("pkgbuild", *args)
|