fpm 1.15.1 → 1.16.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 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