fpm 1.10.2 → 1.15.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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)
|