fpm 1.15.1 → 1.16.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d2157b42ae94755f7521964dc3f92af2a535ee87506303aca5bb72222b48495b
4
- data.tar.gz: 8772b7c1f612dfe8bd698b136418bda8c7b63d9243b1b253832917ad926cab7c
3
+ metadata.gz: f6f1fc4a26f95d77ce3626231e5b7674b8908fe7afc7e2c524f573852291ed2b
4
+ data.tar.gz: e31fa7d3a39de85c3a75b847fc9c336e5096ca32ecd08720554f3057e73e28ef
5
5
  SHA512:
6
- metadata.gz: 9cee7c2885fcf85d75cdc74b2e41399ddce10693fefc3c0b09c49e73b16fcd73140527d646ee5886ef231de7cb202a67f22130d01324d83923195833693f00e2
7
- data.tar.gz: 18f5d405ecd21a0309abf1e08219b0b23aa60eb2e8e7e3f00d7c17ea31e5a3e7b4cbf3a9b9e5bbfb467111a4b8ea9424d61a0f0ff81c9179490e54b17cbfde29
6
+ metadata.gz: f6988868dc8fae9930af5163495bb76d4afa631b58d8608f903349aefd253321ab35d88ad7b5445793b6d6d378ca941bb65d3b3353244511d32d5c13bd22c8fa
7
+ data.tar.gz: fd0660808bb60d2796bc80fe25c5fd3e63f942ce24f79c4591e2d7c1917ef42af6529db07d116677ba439283843a99a80d8d5615c787815cd3a44a3540a5e474
data/CHANGELOG.rst CHANGED
@@ -1,6 +1,24 @@
1
1
  Release Notes and Change Log
2
2
  ============================
3
3
 
4
+ 1.16.0 (December 8, 2024)
5
+ ^^^^^^^^^^^^^^^^^^^^^^^^^
6
+
7
+ * deb: Add support for zstd compression (`#2009`_, `#2084`_; Ștefan Rusu)
8
+ * deb: Add compression level setting, ``--deb-compression-level`` (`#2036`_; Hugo Beauzée-Luyssen)
9
+ * rpm: Generate an empty rpm changelog if none is given. This should help cases where ``rpmlint`` would complain about missing a changelog entry in the rpm. (`#2041`_; Gordon Bleux)
10
+ * deb: When converting from an rpm, remove package information that is not valid on Debian systems. (`#2053`_, `#1627`; Jordan Stopford, Jamesits)
11
+ * python: Fix bug when PYTHONPATH has spaces in it (`#2062`_; Kristof Willaert)
12
+ * deb: You can now choose a different systemd directory with ``--deb-systemd-path`` (`#2063`_; Reinier Schoof)
13
+ * freebsd: OS version can now be specified with ``--freebsd-osversion``: (`#2064`_; David Newhall II)
14
+ * freebsd: Improve the 'architecture' value used by fpm to generate freebsd packages (`#2064`_, `#1880`_; David Newhall II, Matthew R Kasun)
15
+ * deb: Timer units can be given to ``--deb-systemd`` now (`#2065`_, `#1978`_; phillipp, Robert Schneider)
16
+ * rpm: When converting cpan packages, use newer ``perl-interpreter`` dependency name. To use the old dependency name ``perl``, use the flag ``--rpm-old-perl-dependency-name`` (`#2066`_, `#2085`_; Kevin Duret, Nicholas Hubbard, William N. Braswell, Jr., Jordan Sissel))
17
+ * Some errors now correctly print just an error message instead of dumping a ruby stack trace (`#2067`_; Jordan Sissel)
18
+ * python: Support modules which download as zip files (`#2068`_, `#2074`_, `#2072`_; Matt Ezell, hussainbani, hbani)
19
+ * rpm: Fix rpm build failures on Fedora 41 (`#2082`_, `#2076`_; Wayne Heaney, Antheas Kapenekakis, Romain Geissler)
20
+
21
+
4
22
  1.15.1 (January 31, 2023)
5
23
  ^^^^^^^^^^^^^^^^^^^^^^^^^
6
24
  * Ruby 3.2.0 now supported. This fixes error 'undefined method exists? for File' '(`#1981`_, `#1988`_; Nicholas Hubbard, romulasry)
data/lib/fpm/command.rb CHANGED
@@ -410,7 +410,12 @@ class FPM::Command < Clamp::Command
410
410
  set = proc do |object, attribute|
411
411
  # if the package's attribute is currently nil *or* the flag setting for this
412
412
  # attribute is non-default, use the value.
413
- if object.send(attribute).nil? || send(attribute) != send("default_#{attribute}")
413
+
414
+ # Not all options have a default value, so we assume `nil` if there's no default. (#1543)
415
+ # In clamp >= 1.3.0, options without `:default => ..` will not have any # `default_xyz`
416
+ # methods generated, so we need to check for the presence of this method first.
417
+ default = respond_to?("default_#{attribute}") ? send("default_#{attribute}") : nil
418
+ if object.send(attribute).nil? || send(attribute) != default
414
419
  logger.info("Setting from flags: #{attribute}=#{send(attribute)}")
415
420
  object.send("#{attribute}=", send(attribute))
416
421
  end
@@ -27,7 +27,7 @@ class FPM::Package::Deb < FPM::Package
27
27
  } unless defined?(SCRIPT_MAP)
28
28
 
29
29
  # The list of supported compression types. Default is gz (gzip)
30
- COMPRESSION_TYPES = [ "gz", "bzip2", "xz", "none" ]
30
+ COMPRESSION_TYPES = [ "gz", "bzip2", "xz", "zst", "none" ]
31
31
 
32
32
  # https://www.debian.org/doc/debian-policy/ch-relationships.html#syntax-of-relationship-fields
33
33
  # Example value with version relationship: libc6 (>= 2.2.1)
@@ -73,12 +73,25 @@ class FPM::Package::Deb < FPM::Package
73
73
  option "--compression", "COMPRESSION", "The compression type to use, must " \
74
74
  "be one of #{COMPRESSION_TYPES.join(", ")}.", :default => "gz" do |value|
75
75
  if !COMPRESSION_TYPES.include?(value)
76
- raise ArgumentError, "deb compression value of '#{value}' is invalid. " \
76
+ raise FPM::Package::InvalidArgument, "deb compression value of '#{value}' is invalid. " \
77
77
  "Must be one of #{COMPRESSION_TYPES.join(", ")}"
78
78
  end
79
79
  value
80
80
  end
81
81
 
82
+ option "--compression-level", "[0-9]", "Select a compression level. 0 is none or minimal. 9 is max compression.",
83
+ # Specify which compression level to use on the compressor backend, when building a package
84
+ :default => nil do |value|
85
+ valint = value.to_i
86
+ # if self.attributes[:deb_compression].nil?
87
+ # raise "Can't specify a compression level with compression disabled"
88
+ # end
89
+ unless value =~ /^\d$/ && valint >= 0 && valint <= 9
90
+ raise "Invalid compression level '#{value}'. Valid values are integers between 0 and 9 inclusive."
91
+ end
92
+ valint
93
+ end
94
+
82
95
  option "--dist", "DIST-TAG", "Set the deb distribution.", :default => "unstable"
83
96
 
84
97
  # Take care about the case when we want custom control file but still use fpm ...
@@ -210,6 +223,11 @@ class FPM::Package::Deb < FPM::Package
210
223
  next File.expand_path(file)
211
224
  end
212
225
 
226
+ option "--systemd-path", "FILEPATH", "Relative path to the systemd service directory",
227
+ :default => "lib/systemd/system" do |file|
228
+ next file.gsub(/^\/*/, '')
229
+ end
230
+
213
231
  option "--systemd-enable", :flag , "Enable service on install or upgrade", :default => false
214
232
 
215
233
  option "--systemd-auto-start", :flag , "Start service after install or upgrade", :default => false
@@ -262,6 +280,9 @@ class FPM::Package::Deb < FPM::Package
262
280
  when "noarch"
263
281
  # Debian calls noarch "all"
264
282
  @architecture = "all"
283
+ when "ppc64le"
284
+ # Debian calls ppc64le "ppc64el"
285
+ @architecture = "ppc64el"
265
286
  end
266
287
  return @architecture
267
288
  end # def architecture
@@ -332,6 +353,9 @@ class FPM::Package::Deb < FPM::Package
332
353
  when "xz"
333
354
  controltar = "control.tar.xz"
334
355
  compression = "-J"
356
+ when "zst"
357
+ controltar = "control.tar.zst"
358
+ compression = "--use-compress-program 'zstd -d'"
335
359
  when 'tar'
336
360
  controltar = "control.tar"
337
361
  compression = ""
@@ -344,7 +368,7 @@ class FPM::Package::Deb < FPM::Package
344
368
 
345
369
  build_path("control").tap do |path|
346
370
  FileUtils.mkdir(path) if !File.directory?(path)
347
- # unpack the control.tar.{,gz,bz2,xz} from the deb package into staging_path
371
+ # unpack the control.tar.{,gz,bz2,xz,zst} from the deb package into staging_path
348
372
  # Unpack the control tarball
349
373
  safesystem(ar_cmd[0] + " p #{package} #{controltar} | tar #{compression} -xf - -C #{path}")
350
374
 
@@ -364,7 +388,7 @@ class FPM::Package::Deb < FPM::Package
364
388
  version_re = /^(?:([0-9]+):)?(.+?)(?:-(.*))?$/
365
389
  m = version_re.match(parse.call("Version"))
366
390
  if !m
367
- raise "Unsupported version string '#{parse.call("Version")}'"
391
+ raise FPM::InvalidPackageConfiguration, "Unsupported version string '#{parse.call("Version")}'"
368
392
  end
369
393
  self.epoch, self.version, self.iteration = m.captures
370
394
 
@@ -454,6 +478,9 @@ class FPM::Package::Deb < FPM::Package
454
478
  when "xz"
455
479
  datatar = "data.tar.xz"
456
480
  compression = "-J"
481
+ when "zst"
482
+ datatar = "data.tar.zst"
483
+ compression = "--use-compress-program 'zstd -d'"
457
484
  when 'tar'
458
485
  datatar = "data.tar"
459
486
  compression = ""
@@ -504,27 +531,36 @@ class FPM::Package::Deb < FPM::Package
504
531
  end
505
532
  if attributes[:source_date_epoch] == "0"
506
533
  logger.error("Alas, ruby's Zlib::GzipWriter does not support setting an mtime of zero. Aborting.")
507
- raise "#{name}: source_date_epoch of 0 not supported."
534
+ raise FPM::InvalidPackageConfiguration, "#{name}: source_date_epoch of 0 not supported."
508
535
  end
509
536
  if not attributes[:source_date_epoch].nil? and not ar_cmd_deterministic?
510
537
  logger.error("Alas, could not find an ar that can handle -D option. Try installing recent gnu binutils. Aborting.")
511
- raise "#{name}: ar is insufficient to support source_date_epoch."
538
+ raise FPM::InvalidPackageConfiguration, "#{name}: ar is insufficient to support source_date_epoch."
512
539
  end
513
540
  if not attributes[:source_date_epoch].nil? and not tar_cmd_supports_sort_names_and_set_mtime?
514
541
  logger.error("Alas, could not find a tar that can set mtime and sort. Try installing recent gnu tar. Aborting.")
515
- raise "#{name}: tar is insufficient to support source_date_epoch."
542
+ raise FPM::InvalidPackageConfiguration, "#{name}: tar is insufficient to support source_date_epoch."
516
543
  end
517
544
 
518
545
  attributes[:deb_systemd] = []
519
546
  attributes.fetch(:deb_systemd_list, []).each do |systemd|
520
- name = File.basename(systemd, ".service")
521
- dest_systemd = staging_path("lib/systemd/system/#{name}.service")
547
+ name = File.basename(systemd)
548
+ extname = File.extname(name)
549
+
550
+ name_with_extension = if extname.empty?
551
+ "#{name}.service"
552
+ elsif [".service", ".timer"].include?(extname)
553
+ name
554
+ else
555
+ raise FPM::InvalidPackageConfiguration, "Invalid systemd unit file extension: #{extname}. Expected .service or .timer, or no extension."
556
+ end
557
+
558
+ dest_systemd = staging_path(File.join(attributes[:deb_systemd_path], "#{name_with_extension}"))
522
559
  mkdir_p(File.dirname(dest_systemd))
523
560
  FileUtils.cp(systemd, dest_systemd)
524
561
  File.chmod(0644, dest_systemd)
525
562
 
526
- # add systemd service name to attribute
527
- attributes[:deb_systemd] << name
563
+ attributes[:deb_systemd] << name_with_extension
528
564
  end
529
565
 
530
566
  if script?(:before_upgrade) or script?(:after_upgrade) or attributes[:deb_systemd].any?
@@ -627,8 +663,12 @@ class FPM::Package::Deb < FPM::Package
627
663
  end
628
664
 
629
665
  attributes.fetch(:deb_systemd_list, []).each do |systemd|
630
- name = File.basename(systemd, ".service")
631
- dest_systemd = staging_path("lib/systemd/system/#{name}.service")
666
+ name = File.basename(systemd)
667
+ extname = File.extname(systemd)
668
+ name_with_extension = extname.empty? ? "#{name}.service" : name
669
+
670
+ dest_systemd = staging_path(File.join(attributes[:deb_systemd_path], "#{name_with_extension}"))
671
+
632
672
  mkdir_p(File.dirname(dest_systemd))
633
673
  FileUtils.cp(systemd, dest_systemd)
634
674
  File.chmod(0644, dest_systemd)
@@ -642,18 +682,29 @@ class FPM::Package::Deb < FPM::Package
642
682
  datatar = build_path("data.tar.gz")
643
683
  controltar = build_path("control.tar.gz")
644
684
  compression_flags = ["-z"]
685
+ # gnu tar obeys GZIP environment variable with options for gzip; -n = forget original filename and date
686
+ compressor_options = {"GZIP" => "-#{self.attributes[:deb_compression_level] || 9}" +
687
+ "#{'n' if tar_cmd_supports_sort_names_and_set_mtime? and not attributes[:source_date_epoch].nil?}"}
645
688
  when "bzip2"
646
689
  datatar = build_path("data.tar.bz2")
647
690
  controltar = build_path("control.tar.gz")
648
691
  compression_flags = ["-j"]
692
+ compressor_options = {"BZIP" => "-#{self.attributes[:deb_compression_level] || 9}"}
649
693
  when "xz"
650
694
  datatar = build_path("data.tar.xz")
651
695
  controltar = build_path("control.tar.xz")
652
696
  compression_flags = ["-J"]
697
+ compressor_options = {"XZ_OPT" => "-#{self.attributes[:deb_compression_level] || 3}"}
698
+ when "zst"
699
+ datatar = build_path("data.tar.zst")
700
+ controltar = build_path("control.tar.zst")
701
+ compression_flags = ["--use-compress-program", "zstd"]
702
+ compressor_options = {"ZSTD_CLEVEL" => "-#{self.attributes[:deb_compression_level] || 3}"}
653
703
  when "none"
654
704
  datatar = build_path("data.tar")
655
705
  controltar = build_path("control.tar")
656
706
  compression_flags = []
707
+ compressor_options = {}
657
708
  else
658
709
  raise FPM::InvalidPackageConfiguration,
659
710
  "Unknown compression type '#{self.attributes[:deb_compression]}'"
@@ -662,9 +713,8 @@ class FPM::Package::Deb < FPM::Package
662
713
  if tar_cmd_supports_sort_names_and_set_mtime? and not attributes[:source_date_epoch].nil?
663
714
  # Use gnu tar options to force deterministic file order and timestamp
664
715
  args += ["--sort=name", ("--mtime=@%s" % attributes[:source_date_epoch])]
665
- # gnu tar obeys GZIP environment variable with options for gzip; -n = forget original filename and date
666
- args.unshift({"GZIP" => "-9n"})
667
716
  end
717
+ args.unshift(compressor_options)
668
718
  safesystem(*args)
669
719
 
670
720
  # pack up the .deb, which is just an 'ar' archive with 3 files
@@ -704,9 +754,17 @@ class FPM::Package::Deb < FPM::Package
704
754
  self.dependencies = self.dependencies.collect do |dep|
705
755
  fix_dependency(dep)
706
756
  end.flatten
757
+
758
+ # If an invalid depends field was found i.e. /bin.sh then fix_depends will blank it
759
+ # Make sure we remove this blank here
760
+ self.dependencies = self.dependencies.reject { |p| p.empty? }
761
+
707
762
  self.provides = self.provides.collect do |provides|
708
763
  fix_provides(provides)
709
764
  end.flatten
765
+ # If an invalid provides field was found i.e. mypackage(arch) then fix_provides will blank it
766
+ # Make sure we remove this blank here
767
+ self.provides = self.provides.reject { |p| p.empty? }
710
768
 
711
769
  if origin == FPM::Package::CPAN
712
770
  # The fpm cpan code presents dependencies and provides fields as perl(ModuleName)
@@ -721,7 +779,7 @@ class FPM::Package::Deb < FPM::Package
721
779
  else
722
780
  # Also replace '::' in the perl module name with '-'
723
781
  modulename = m["name"].gsub("::", "-")
724
-
782
+
725
783
  # Fix any upper-casing or other naming concerns Debian has about packages
726
784
  name = "#{attributes[:cpan_package_name_prefix]}-#{modulename}"
727
785
 
@@ -807,6 +865,18 @@ class FPM::Package::Deb < FPM::Package
807
865
  end
808
866
  end
809
867
 
868
+ if dep.start_with?("/")
869
+ logger.warn("Blanking 'dependency' field '#{dep}' because it's invalid")
870
+ dep = ""
871
+ return dep
872
+ end
873
+
874
+ if dep.include?("rpmlib")
875
+ logger.warn("Blanking 'dependency' field '#{dep}' because it's invalid")
876
+ dep = ""
877
+ return dep
878
+ end
879
+
810
880
  name_re = /^[^ \(]+/
811
881
  name = dep[name_re]
812
882
  if name =~ /[A-Z]/
@@ -900,6 +970,11 @@ class FPM::Package::Deb < FPM::Package
900
970
  provides = provides.gsub("_", "-")
901
971
  end
902
972
 
973
+ if provides.include?("(") and !provides.include?("(=")
974
+ logger.warn("Blanking 'provides' field '#{provides}' because it's invalid")
975
+ provides = ""
976
+ end
977
+
903
978
  if m = provides.match(/^([A-Za-z0-9_-]+)\s*=\s*(\d+.*$)/)
904
979
  logger.warn("Replacing 'provides' entry #{provides} with syntax 'name (= version)'")
905
980
  provides = "#{m[1]} (= #{m[2]})"
@@ -934,12 +1009,21 @@ class FPM::Package::Deb < FPM::Package
934
1009
  when "gz", "bzip2", nil
935
1010
  controltar = "control.tar.gz"
936
1011
  compression_flags = ["-z"]
1012
+ # gnu tar obeys GZIP environment variable with options for gzip; -n = forget original filename and date
1013
+ compressor_options = {"GZIP" => "-#{self.attributes[:deb_compression_level] || 9}" +
1014
+ "#{'n' if tar_cmd_supports_sort_names_and_set_mtime? and not attributes[:source_date_epoch].nil?}"}
937
1015
  when "xz"
938
1016
  controltar = "control.tar.xz"
939
1017
  compression_flags = ["-J"]
1018
+ compressor_options = {"XZ_OPT" => "-#{self.attributes[:deb_compression_level] || 3}"}
1019
+ when "zst"
1020
+ controltar = "control.tar.zst"
1021
+ compression_flags = ["--use-compress-program", "zstd"]
1022
+ compressor_options = {"ZSTD_CLEVEL" => "-#{self.attributes[:deb_compression_level] || 3}"}
940
1023
  when "none"
941
1024
  controltar = "control.tar"
942
1025
  compression_flags = []
1026
+ compressor_options = {}
943
1027
  else
944
1028
  raise FPM::InvalidPackageConfiguration,
945
1029
  "Unknown compression type '#{self.attributes[:deb_compression]}'"
@@ -954,9 +1038,8 @@ class FPM::Package::Deb < FPM::Package
954
1038
  if tar_cmd_supports_sort_names_and_set_mtime? and not attributes[:source_date_epoch].nil?
955
1039
  # Force deterministic file order and timestamp
956
1040
  args += ["--sort=name", ("--mtime=@%s" % attributes[:source_date_epoch])]
957
- # gnu tar obeys GZIP environment variable with options for gzip; -n = forget original filename and date
958
- args.unshift({"GZIP" => "-9n"})
959
1041
  end
1042
+ args.unshift(compressor_options)
960
1043
  safesystem(*args)
961
1044
  end
962
1045
 
@@ -16,6 +16,10 @@ class FPM::Package::FreeBSD < FPM::Package
16
16
  "Sets the FreeBSD 'origin' pkg field",
17
17
  :default => "fpm/<name>"
18
18
 
19
+ option "--osversion", "VERSION",
20
+ "Sets the FreeBSD 'version' pkg field, ie 12 or 13, use '*' for all.",
21
+ :default => "13"
22
+
19
23
  def output(output_path)
20
24
  output_check(output_path)
21
25
 
@@ -90,28 +94,36 @@ class FPM::Package::FreeBSD < FPM::Package
90
94
  end # def output
91
95
 
92
96
  # Handle architecture naming conversion:
93
- # <osname>:<osversion>:<arch>:<wordsize>[.other]
97
+ # <osname>:<osversion>:<arch>
94
98
  def architecture
95
- osname = %x{uname -s}.chomp
96
- osversion = %x{uname -r}.chomp.split('.').first
97
-
98
- # Essentially because no testing on other platforms
99
- arch = 'x86'
99
+ osname = 'FreeBSD'
100
100
 
101
- wordsize = case @architecture
101
+ arch = case @architecture
102
102
  when nil, 'native'
103
103
  %x{getconf LONG_BIT}.chomp # 'native' is current arch
104
104
  when 'arm64'
105
- '64'
105
+ 'arm64'
106
+ when 'aarch64'
107
+ 'arm64'
106
108
  when 'amd64'
107
- '64'
109
+ 'amd64'
110
+ when 'x86_64'
111
+ 'amd64'
108
112
  when 'i386'
109
- '32'
113
+ 'i386'
114
+ when 'i686'
115
+ 'i386'
116
+ when 'any'
117
+ '*'
118
+ when 'all'
119
+ '*'
120
+ when 'noarch'
121
+ '*'
110
122
  else
111
123
  %x{getconf LONG_BIT}.chomp # default to native, the current arch
112
124
  end
113
125
 
114
- return [osname, osversion, arch, wordsize].join(':')
126
+ return [osname, attributes[:freebsd_osversion], arch].join(':')
115
127
  end
116
128
 
117
129
  def add_path(tar, tar_path, path)
@@ -79,7 +79,7 @@ class FPM::Package::Python < FPM::Package
79
79
  option "--setup-py-arguments", "setup_py_argument",
80
80
  "Arbitrary argument(s) to be passed to setup.py",
81
81
  :multivalued => true, :attribute_name => :python_setup_py_arguments,
82
- :default => []
82
+ :default => []
83
83
  option "--internal-pip", :flag,
84
84
  "Use the pip module within python to install modules - aka 'python -m pip'. This is the recommended usage since Python 3.4 (2014) instead of invoking the 'pip' script",
85
85
  :attribute_name => :python_internal_pip,
@@ -171,13 +171,19 @@ class FPM::Package::Python < FPM::Package
171
171
  # behind a directory with the Python package extracted and ready to be used.
172
172
  # For example, `pip download ... Django` puts `Django-4.0.4.tar.tz` into the build_path directory.
173
173
  # If we expect `pip` to leave an unknown-named file in the `build_path` directory, let's check for
174
- # a single file and unpack it. I don't know if it will /always/ be a .tar.gz though.
175
- files = ::Dir.glob(File.join(build_path, "*.tar.gz"))
174
+ # a single file and unpack it.
175
+ files = ::Dir.glob(File.join(build_path, "*.{tar.gz,zip}"))
176
176
  if files.length != 1
177
177
  raise "Unexpected directory layout after `pip download ...`. This might be an fpm bug? The directory is #{build_path}"
178
178
  end
179
179
 
180
- safesystem("tar", "-zxf", files[0], "-C", target)
180
+ if files[0].end_with?("tar.gz")
181
+ safesystem("tar", "-zxf", files[0], "-C", target)
182
+ elsif files[0].end_with?("zip")
183
+ safesystem("unzip", files[0], "-d", target)
184
+ else
185
+ raise "Unexpected file format after `pip download ...`. This might be an fpm bug? The file is #{files[0]}"
186
+ end
181
187
  else
182
188
  # no pip, use easy_install
183
189
  logger.debug("no pip, defaulting to easy_install", :easy_install => attributes[:python_easyinstall])
@@ -230,7 +236,7 @@ class FPM::Package::Python < FPM::Package
230
236
 
231
237
  output = ::Dir.chdir(setup_dir) do
232
238
  tmp = build_path("metadata.json")
233
- setup_cmd = "env PYTHONPATH=#{pylib}:$PYTHONPATH #{attributes[:python_bin]} " \
239
+ setup_cmd = "env PYTHONPATH=#{pylib.shellescape}:$PYTHONPATH #{attributes[:python_bin]} " \
234
240
  "setup.py --command-packages=pyfpm get_metadata --output=#{tmp}"
235
241
 
236
242
  if attributes[:python_obey_requirements_txt?]
@@ -185,6 +185,9 @@ class FPM::Package::RPM < FPM::Package
185
185
  end
186
186
  end
187
187
 
188
+ option "--old-perl-dependency-name", :flag,
189
+ "Use older 'perl' depdency name. Newer Red Hat (and derivatives) use a dependency named 'perl-interpreter'."
190
+
188
191
  private
189
192
 
190
193
  # Fix path name
@@ -275,9 +278,41 @@ class FPM::Package::RPM < FPM::Package
275
278
  return @iteration ? @iteration : 1
276
279
  end # def iteration
277
280
 
281
+ # Generate a generic changelog or return an existing definition
282
+ def changelog
283
+ if attributes[:rpm_changelog]
284
+ return attributes[:rpm_changelog]
285
+ end
286
+
287
+ reldate = if attributes[:source_date_epoch].nil?
288
+ Time.now()
289
+ else
290
+ Time.at(attributes[:source_date_epoch].to_i)
291
+ end
292
+ changed = reldate.strftime("%a %b %_e %Y")
293
+ changev = "#{version}-#{iteration}"
294
+ changev += "%{?dist}" if attributes[:rpm_dist]
295
+
296
+ "* #{changed} #{maintainer} - #{changev}\n- Package created with FPM\n"
297
+ end
298
+
278
299
  # See FPM::Package#converted_from
279
300
  def converted_from(origin)
280
- if origin == FPM::Package::Gem
301
+ if origin == FPM::Package::CPAN
302
+ if !attributes[:rpm_old_perl_dependency_name?]
303
+ fixed_deps = []
304
+ self.dependencies.collect do |dep|
305
+ # RPM package "perl" is a metapackage which install all the Perl bits and core modules, then gcc...
306
+ # this must be replaced by perl-interpreter
307
+ if name=/^perl([\s<>=].*)$/.match(dep)
308
+ fixed_deps.push("perl-interpreter#{name[1]}")
309
+ else
310
+ fixed_deps.push(dep)
311
+ end
312
+ end
313
+ self.dependencies = fixed_deps
314
+ end
315
+ elsif origin == FPM::Package::Gem
281
316
  fixed_deps = []
282
317
  self.dependencies.collect do |dep|
283
318
  # Gem dependency operator "~>" is not compatible with rpm. Translate any found.
@@ -473,6 +508,7 @@ class FPM::Package::RPM < FPM::Package
473
508
  args += ["--define", "dist .#{attributes[:rpm_dist]}"] if attributes[:rpm_dist]
474
509
 
475
510
  args += [
511
+ "--buildroot", "#{build_path}/BUILD",
476
512
  "--define", "buildroot #{build_path}/BUILD",
477
513
  "--define", "_topdir #{build_path}",
478
514
  "--define", "_sourcedir #{build_path}",
data/lib/fpm/util.rb CHANGED
@@ -1,5 +1,6 @@
1
1
  require "fpm/namespace"
2
2
  require "fileutils"
3
+ require "stud/temporary"
3
4
 
4
5
  # Some utility functions
5
6
  module FPM::Util
@@ -229,15 +230,18 @@ module FPM::Util
229
230
  @@ar_cmd_deterministic = false
230
231
 
231
232
  # FIXME: don't assume current directory writeable
232
- FileUtils.touch(["fpm-dummy.tmp"])
233
+ emptyfile = Stud::Temporary.pathname
234
+ testarchive = Stud::Temporary.pathname
235
+ FileUtils.touch([emptyfile])
236
+
233
237
  ["ar", "gar"].each do |ar|
234
238
  ["-qc", "-qcD"].each do |ar_create_opts|
235
- FileUtils.rm_f(["fpm-dummy.ar.tmp"])
239
+ FileUtils.rm_f([testarchive])
236
240
  # Return this combination if it creates archives without uids or timestamps.
237
241
  # Exitstatus will be nonzero if the archive can't be created,
238
242
  # or its table of contents doesn't match the regular expression.
239
243
  # Be extra-careful about locale and timezone when matching output.
240
- system("#{ar} #{ar_create_opts} fpm-dummy.ar.tmp fpm-dummy.tmp 2>/dev/null && env TZ=UTC LANG=C LC_TIME=C #{ar} -tv fpm-dummy.ar.tmp | grep '0/0.*1970' > /dev/null 2>&1")
244
+ system("#{ar} #{ar_create_opts} #{testarchive} #{emptyfile} 2>/dev/null && env TZ=UTC LANG=C LC_TIME=C #{ar} -tv #{testarchive} | grep '0/0.*1970' > /dev/null 2>&1")
241
245
  if $?.exitstatus == 0
242
246
  @@ar_cmd = [ar, ar_create_opts]
243
247
  @@ar_cmd_deterministic = true
@@ -247,10 +251,8 @@ module FPM::Util
247
251
  end
248
252
  # If no combination of ar and options omits timestamps, fall back to default.
249
253
  @@ar_cmd = ["ar", "-qc"]
254
+ FileUtils.rm_f([testarchive, emptyfile])
250
255
  return @@ar_cmd
251
- ensure
252
- # Clean up
253
- FileUtils.rm_f(["fpm-dummy.ar.tmp", "fpm-dummy.tmp"])
254
256
  end # def ar_cmd
255
257
 
256
258
  # Return whether the command returned by ar_cmd can create deterministic archives
@@ -264,7 +266,10 @@ module FPM::Util
264
266
  return @@tar_cmd if defined? @@tar_cmd
265
267
 
266
268
  # FIXME: don't assume current directory writeable
267
- FileUtils.touch(["fpm-dummy.tmp"])
269
+ emptyfile = Stud::Temporary.pathname
270
+ testarchive = Stud::Temporary.pathname
271
+
272
+ FileUtils.touch([emptyfile])
268
273
 
269
274
  # Prefer tar that supports more of the features we want, stop if we find tar of our dreams
270
275
  best="tar"
@@ -276,7 +281,7 @@ module FPM::Util
276
281
  opts=[]
277
282
  score=0
278
283
  ["--sort=name", "--mtime=@0"].each do |opt|
279
- system("#{tar} #{opt} -cf fpm-dummy.tar.tmp fpm-dummy.tmp > /dev/null 2>&1")
284
+ system("#{tar} #{opt} -cf #{testarchive} #{emptyfile} > /dev/null 2>&1")
280
285
  if $?.exitstatus == 0
281
286
  opts << opt
282
287
  score += 1
@@ -292,10 +297,9 @@ module FPM::Util
292
297
  end
293
298
  end
294
299
  @@tar_cmd = best
300
+ FileUtils.rm_f([testarchive, emptyfile])
301
+
295
302
  return @@tar_cmd
296
- ensure
297
- # Clean up
298
- FileUtils.rm_f(["fpm-dummy.tar.tmp", "fpm-dummy.tmp"])
299
303
  end # def tar_cmd
300
304
 
301
305
  # Return whether the command returned by tar_cmd can create deterministic archives
data/lib/fpm/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module FPM
2
- VERSION = "1.15.1"
2
+ VERSION = "1.16.0"
3
3
  end
data/templates/rpm.erb CHANGED
@@ -260,4 +260,4 @@ fi
260
260
  <% end -%>
261
261
 
262
262
  %changelog
263
- <%= attributes[:rpm_changelog] %>
263
+ <%= changelog %>
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fpm
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.15.1
4
+ version: 1.16.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jordan Sissel
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-02-01 00:00:00.000000000 Z
11
+ date: 2024-12-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: cabin
@@ -56,14 +56,14 @@ dependencies:
56
56
  name: clamp
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
- - - "~>"
59
+ - - ">="
60
60
  - !ruby/object:Gem::Version
61
61
  version: 1.0.0
62
62
  type: :runtime
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
- - - "~>"
66
+ - - ">="
67
67
  - !ruby/object:Gem::Version
68
68
  version: 1.0.0
69
69
  - !ruby/object:Gem::Dependency
@@ -254,7 +254,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
254
254
  - !ruby/object:Gem::Version
255
255
  version: '0'
256
256
  requirements: []
257
- rubygems_version: 3.4.1
257
+ rubygems_version: 3.2.22
258
258
  signing_key:
259
259
  specification_version: 4
260
260
  summary: fpm - package building and mangling