fpm 1.12.0 → 1.14.1

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: 28f939bd20768768cb05026a39c8a270596368c654ec5606a43a0e75afa845ad
4
- data.tar.gz: 0d7eea7108832e79994ba3ee9511c3715b384906f7ef3a2ab5e907cfc764609a
3
+ metadata.gz: '079f0bd8cc1fe2a84b6e5dfc38cc0ae2e509d271d9752e0fb739c7cde79c746b'
4
+ data.tar.gz: 28ed14320c22c0dc5767781d3f325cd4e817b16e42999b0a2d1e2713522d0761
5
5
  SHA512:
6
- metadata.gz: 555edd6cd5d4b0098e075011e48db96e52c454b8557735a51202307dcaeb4920a5efe93bb6d99cedf9d3ff95ff445c37059e1fc308e0602482977587d532e4b1
7
- data.tar.gz: 2803ea8cb3af495d5fd20e75bee0eba11dc262ac59b86e63b75ef3cef7417440e88e1fec9172f7a1ea5cf0705e2ce36bc65e7b9c1c5469eb0e78b292ac822716
6
+ metadata.gz: b6287a7079c1f00a327d92a268f46df825cdbcc5008d719a23a4dd8f4fdba574bedf735f559207781794c7c29cf39153092d1f1452d8d3ddd4d23f808a8856ae
7
+ data.tar.gz: 4c90779c8b7990818a76dc4fd60035311fe8ad461e7717271abd11318d1cad10bff03783468ee78fa17bc8455d692deabd69c41bb0ffef8195d6c4be61a56d6e
data/CHANGELOG.rst CHANGED
@@ -1,6 +1,46 @@
1
1
  Release Notes and Change Log
2
2
  ============================
3
3
 
4
+ 1.14.1 (November 10, 2021)
5
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^
6
+ * Fix a bug that impacted fpm api usage (from other ruby programs) that caused an error "NameError: uninitialized constant FPM::Package::CPAN" when trying to output a Deb package. (`#1854`_, `#1856`_; Karol Bucek, Jordan Sissel)
7
+
8
+ 1.14.0 (November 9, 2021)
9
+ ^^^^^^^^^^^^^^^^^^^^^^^^^
10
+ * python: Use pip by default for fetching Python packages. This matches the Python 3 "installation" docs which recommend calling pip as ``python -m pip`` where ``python`` depends on ``--python-bin`` (default "python"). Previous default was to use `easy_install` which is no longer available on many newer systems. To use easy_install, you can set ``--no-python-internal-pip`` to revert this pip default. Further, you can specify your own pip path instead of using ``python -m pip`` with the ``--python-pip /path/to/pip`` flag. (`#1820`_, `#1821`_; Jordan Sissel)
11
+ * python: Support extras_require build markers in python packages (`#1307`_, `#1816`_; Joris Vandermeersch)
12
+ * freebsd: Fix bug which caused fpm to generate incorrect FreeBSD packages "missing leading `/`" (`#1811`_, `#1812`_, `#1844`_, `#1832`_, `#1845`_; Vlastimil Holer, Clayton Wong, Markus Ueberall, Jordan Sissel)
13
+ * deb: In order to only allow fpm to create valid packages, fpm now rejects packages with invalid "provides" (``--provides``) values. (`#1829`_, `#1825`_; Jordan Sissel, Peter Teichman)
14
+ * deb: Only show a warning about /etc and config files if there are files in /etc (`#1852`_, `#1851`_; Jordan Sissel)
15
+
16
+ * rpm: replace dash with underscore in rpm's "Release" field aka what fpm calls ``--iteration``. (`#1834`_, `#1833`_; Jordan Sissel)
17
+ * empty: `fpm -s empty ...` now defaults to "all" architecture instead of "native". (`#1850`_, `#1846`_; Jordan Sissel)
18
+ * Significant documentation improvements rewriting most of the documentation. New overview pages, full CLI flag listing, and new sections dedicated package types (rpm, cpan, deb, etc). (`#1815`_, `#1817`_, `#1838`_; Vedant K, Jordan Sissel)
19
+ * Typo fixes in documentation are always appreciated! (`#1842`_; Clayton Wong)
20
+ * fpm can now (we hope!) now be tested more easily from docker (`#1818`_, `#1682`_, `#1453`_; @directionless, Jordan Sissel, Douglas Muth)
21
+
22
+ 1.13.1 (July 6, 2021)
23
+ ^^^^^^^^^^^^^^^^^^^^^
24
+ * deb: The `--provides` flag now allows for versions. Previously, fpm would
25
+ remove the version part of a provides field when generating deb packages.
26
+ (`#1788`_, `#1803`_; Jordan Sissel, Phil Schwartz, tympanix)
27
+ * osxpkg: Update documentation to include installing `rpm` tools on OSX
28
+ (`#1797`_; allen joslin)
29
+
30
+ 1.13.0 (June 19, 2021)
31
+ ^^^^^^^^^^^^^^^^^^^^^^
32
+ * Apple M1 users should now work (`#1772`_, `#1785`_, `#1786`_; Jordan Sissel)
33
+ * Removed `ffi` ruby library as a dependency. This should make it easier to support a wider range of Ruby versions (Ruby 2.2, 3.0, etc) and platforms (like arm64, Apple M1, etc) in the future. (`#1785`_, `#1786`_; Jordan Sissel)
34
+ * Now uses the correct architecture synonym for ARM 64 systems. Debian uses `arm64` as a synonym for what other systems call `aarch64` (linux kernel, RPM, Arch Linux). (`#1775`_; Steve Kamerman)
35
+ * Docs: Fix a typo in an example (`#1785`_; Zoe O'Connell)
36
+ * rpm: File paths can now contain single-quote characters (`#1774`_; Jordan Sissel)
37
+ * rpm: Use correct SPEC syntax when using --after-upgrade or similar features (`#1761`_; Jo Vandeginste. Robert Fielding)
38
+ * Ruby 3.0 support: Added `rexml` as a runtime dependency. In Ruby 2.0, `rexml` came by default, but in Ruby 3.0, `rexml` is now a bundled gem and some distributiosn do not include it by default. (`#1794`_; Jordan Sissel)
39
+ * Fix error "git: not found (Git::GitExecuteError)". Now loads `git` library only when using git features. (`#1753`_, `#1748`_, `#1751`_, `#1766`_; Jordan Sissel, Cameron Nemo, Jason Rogers, Luke Short)
40
+ * deb: Fix syntax error in `postinst` (`--after-install`) script. (`#1752`_, `#1749`_, `#1764`_; rmanus, Adam Mohammed, Elliot Murphy, kimw, Jordan Sissel)
41
+ * deb: --deb-compression now uses the same compression and file suffix on the control.tar file (`#1760`_; Philippe Poilbarbe)
42
+
43
+
4
44
  1.12.0 (January 19, 2021)
5
45
  ^^^^^^^^^^^^^^^^^^^^^^^^^
6
46
 
@@ -36,7 +76,7 @@ Release Notes and Change Log
36
76
  * cpan: Adds `--[no-]cpan-verbose` flag which, when set, runs `cpanm` with the `--verbose` flag (`#1511`_; William N. Braswell, Jr)
37
77
 
38
78
  1.10.0 (May 21, 2018)
39
- ^^^^^^^^^^^^^^^^^^^^
79
+ ^^^^^^^^^^^^^^^^^^^^^
40
80
 
41
81
  * Pin `ruby-xz` dependency to one which allows Ruby versions older than 2.3.0 (`#1494`_; Marat Sharafutdinov)
42
82
  * Documentation improvements: `#1488`_; Arthur Burkart. `#1384`_; Justin Kolberg. `#1452`_; Anatoli Babenia.
@@ -64,7 +104,7 @@ Release Notes and Change Log
64
104
  * rpm: Fix `--config-files` handling (`#1390`_, `#1391`_; Jordan Sissel)
65
105
 
66
106
  1.9.1 (July 28, 2017) happy sysadmin day!
67
- ^^^^^^^^^^^^^^^^^^^^^
107
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
68
108
 
69
109
  * Documentation improvements: `#1291`_; Pablo Castellano. `#1321`_; ge-fa. `#1309`_; jesusbagpuss. `#1349`_; Perry Stole. `#1352`_, Jordan Sissel. `#1384`_; Justin Kolberg.
70
110
  * Testing improvements: `#1320`_; Rob Young. `#1266`_; Ryan Parman. `#1374`_; Thiago Figueiró.
@@ -93,9 +133,9 @@ Release Notes and Change Log
93
133
  * Other: Remove unused archive-tar-minitar as a dependency of fpm (`#1355`_; Diego Martins)
94
134
  * Other: Add stud as a runtime dependency (`#1354`_; Elan Ruusamäe)
95
135
 
96
- .. _reproducible_builds:: https://reproducible-builds.org/
97
- .. _path mapping:: http://fpm.readthedocs.io/en/latest/source/dir.html#path-mapping
98
- .. _Deterministic output:: http://fpm.readthedocs.io/en/latest/source/gem.html
136
+ .. _reproducible_builds: https://reproducible-builds.org/
137
+ .. _path mapping: source/dir.html#path-mapping
138
+ .. _Deterministic output: source/gem.html
99
139
 
100
140
  1.9.0 (July 28, 2017)
101
141
  ^^^^^^^^^^^^^^^^^^^^^
data/CONTRIBUTORS CHANGED
@@ -21,6 +21,7 @@ sbuss
21
21
  Brett Gailey (github: dnbert)
22
22
  Daniel Haskin (github: djhaskin987)
23
23
  Richard Grainger (github: liger1978)
24
+ seph (github: directionless)
24
25
 
25
26
  If you have contributed (bug reports, feature requests, help in IRC, blog
26
27
  posts, code, etc) and aren't listed here, please let me know if you wish to be
data/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  (This is an MIT-style license)
2
2
 
3
- Copyright (c) 2011-2017 Jordan Sissel and contributors.
3
+ Copyright (c) 2011-2021 Jordan Sissel and contributors.
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
@@ -8,6 +8,10 @@ require "fileutils"
8
8
  require "digest"
9
9
  require "zlib"
10
10
 
11
+ # For handling conversion
12
+ require "fpm/package/cpan"
13
+ require "fpm/package/gem"
14
+
11
15
  # Support for debian packages (.deb files)
12
16
  #
13
17
  # This class supports both input and output of packages.
@@ -25,6 +29,17 @@ class FPM::Package::Deb < FPM::Package
25
29
  # The list of supported compression types. Default is gz (gzip)
26
30
  COMPRESSION_TYPES = [ "gz", "bzip2", "xz", "none" ]
27
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
+ # Version string docs here: https://www.debian.org/doc/debian-policy/ch-controlfields.html#s-f-version
37
+ # The format is: [epoch:]upstream_version[-debian_revision].
38
+ # epoch - This is a single (generally small) unsigned integer
39
+ # upstream_version - must contain only alphanumerics 6 and the characters . + - ~
40
+ # debian_revision - only alphanumerics and the characters + . ~
41
+ RELATIONSHIP_FIELD_PATTERN = /^(?<name>[A-z0-9_-]+)(?: *\((?<relation>[<>=]+) *(?<version>(?:[0-9]+:)?[0-9A-Za-z+~.-]+(?:-[0-9A-Za-z+~.]+)?)\))?$/
42
+
28
43
  option "--ignore-iteration-in-dependencies", :flag,
29
44
  "For '=' (equal) dependencies, allow iterations on the specified " \
30
45
  "version. Default is to be specific. This option allows the same " \
@@ -178,7 +193,7 @@ class FPM::Package::Deb < FPM::Package
178
193
  end
179
194
 
180
195
  option "--systemd", "FILEPATH", "Add FILEPATH as a systemd script",
181
- :multivalued => true do |file|
196
+ :multivalued => true do |file|
182
197
  next File.expand_path(file)
183
198
  end
184
199
 
@@ -228,6 +243,9 @@ class FPM::Package::Deb < FPM::Package
228
243
  when "x86_64"
229
244
  # Debian calls x86_64 "amd64"
230
245
  @architecture = "amd64"
246
+ when "aarch64"
247
+ # Debian calls aarch64 "arm64"
248
+ @architecture = "arm64"
231
249
  when "noarch"
232
250
  # Debian calls noarch "all"
233
251
  @architecture = "all"
@@ -424,6 +442,12 @@ class FPM::Package::Deb < FPM::Package
424
442
 
425
443
  def output(output_path)
426
444
  self.provides = self.provides.collect { |p| fix_provides(p) }
445
+
446
+ self.provides.each do |provide|
447
+ if !valid_provides_field?(provide)
448
+ raise FPM::InvalidPackageConfiguration, "Found invalid Provides field values (#{provide.inspect}). This is not valid in a Debian package."
449
+ end
450
+ end
427
451
  output_check(output_path)
428
452
  # Abort if the target path already exists.
429
453
 
@@ -588,15 +612,19 @@ class FPM::Package::Deb < FPM::Package
588
612
  case self.attributes[:deb_compression]
589
613
  when "gz", nil
590
614
  datatar = build_path("data.tar.gz")
615
+ controltar = build_path("control.tar.gz")
591
616
  compression = "-z"
592
617
  when "bzip2"
593
618
  datatar = build_path("data.tar.bz2")
619
+ controltar = build_path("control.tar.gz")
594
620
  compression = "-j"
595
621
  when "xz"
596
622
  datatar = build_path("data.tar.xz")
623
+ controltar = build_path("control.tar.xz")
597
624
  compression = "-J"
598
625
  when "none"
599
626
  datatar = build_path("data.tar")
627
+ controltar = build_path("control.tar")
600
628
  compression = ""
601
629
  else
602
630
  raise FPM::InvalidPackageConfiguration,
@@ -616,7 +644,7 @@ class FPM::Package::Deb < FPM::Package
616
644
  # the 'debian-binary' file has to be first
617
645
  File.expand_path(output_path).tap do |output_path|
618
646
  ::Dir.chdir(build_path) do
619
- safesystem(*ar_cmd, output_path, "debian-binary", "control.tar.gz", datatar)
647
+ safesystem(*ar_cmd, output_path, "debian-binary", controltar, datatar)
620
648
  end
621
649
  end
622
650
 
@@ -653,6 +681,43 @@ class FPM::Package::Deb < FPM::Package
653
681
  fix_provides(provides)
654
682
  end.flatten
655
683
 
684
+ if origin == FPM::Package::CPAN
685
+ # The fpm cpan code presents dependencies and provides fields as perl(ModuleName)
686
+ # so we'll need to convert them to something debian supports.
687
+
688
+ # Replace perl(ModuleName) > 1.0 with Debian-style perl-ModuleName (> 1.0)
689
+ perldepfix = lambda do |dep|
690
+ m = dep.match(/perl\((?<name>[A-Za-z0-9_:]+)\)\s*(?<op>.*$)/)
691
+ if m.nil?
692
+ # 'dep' syntax didn't look like 'perl(Name) > 1.0'
693
+ dep
694
+ else
695
+ # Also replace '::' in the perl module name with '-'
696
+ modulename = m["name"].gsub("::", "-")
697
+
698
+ # Fix any upper-casing or other naming concerns Debian has about packages
699
+ name = "#{attributes[:cpan_package_name_prefix]}-#{modulename}"
700
+
701
+ if m["op"].empty?
702
+ name
703
+ else
704
+ # 'dep' syntax was like this (version constraint): perl(Module) > 1.0
705
+ "#{name} (#{m["op"]})"
706
+ end
707
+ end
708
+ end
709
+
710
+ rejects = [ "perl(vars)", "perl(warnings)", "perl(strict)", "perl(Config)" ]
711
+ self.dependencies = self.dependencies.reject do |dep|
712
+ # Reject non-module Perl dependencies like 'vars' and 'warnings'
713
+ rejects.include?(dep)
714
+ end.collect(&perldepfix).collect(&method(:fix_dependency))
715
+
716
+ # Also fix the Provides field 'perl(ModuleName) = version' to be 'perl-modulename (= version)'
717
+ self.provides = self.provides.collect(&perldepfix).collect(&method(:fix_provides))
718
+
719
+ end # if origin == FPM::Packagin::CPAN
720
+
656
721
  if origin == FPM::Package::Deb
657
722
  changelog_path = staging_path("usr/share/doc/#{name}/changelog.Debian.gz")
658
723
  if File.exists?(changelog_path)
@@ -680,6 +745,19 @@ class FPM::Package::Deb < FPM::Package
680
745
  File.unlink(changelog_path)
681
746
  end
682
747
  end
748
+
749
+ if origin == FPM::Package::Gem
750
+ # fpm's gem input will have provides as "rubygem-name = version"
751
+ # and we need to convert this to Debian-style "rubygem-name (= version)"
752
+ self.provides = self.provides.collect do |provides|
753
+ m = /^(#{attributes[:gem_package_name_prefix]})-([^\s]+)\s*=\s*(.*)$/.match(provides)
754
+ if m
755
+ "#{m[1]}-#{m[2]} (= #{m[3]})"
756
+ else
757
+ provides
758
+ end
759
+ end
760
+ end
683
761
  end # def converted_from
684
762
 
685
763
  def debianize_op(op)
@@ -754,6 +832,32 @@ class FPM::Package::Deb < FPM::Package
754
832
  end
755
833
  end # def fix_dependency
756
834
 
835
+ def valid_provides_field?(text)
836
+ m = RELATIONSHIP_FIELD_PATTERN.match(text)
837
+ if m.nil?
838
+ logger.error("Invalid relationship field for debian package: #{text}")
839
+ return false
840
+ end
841
+
842
+ # Per Debian Policy manual, https://www.debian.org/doc/debian-policy/ch-relationships.html#syntax-of-relationship-fields
843
+ # >> The relations allowed are <<, <=, =, >= and >> for strictly earlier, earlier or equal,
844
+ # >> exactly equal, later or equal and strictly later, respectively. The exception is the
845
+ # >> Provides field, for which only = is allowed
846
+ if m["relation"] == "=" || m["relation"] == nil
847
+ return true
848
+ end
849
+ return false
850
+ end
851
+
852
+ def valid_relationship_field?(text)
853
+ m = RELATIONSHIP_FIELD_PATTERN.match(text)
854
+ if m.nil?
855
+ logger.error("Invalid relationship field for debian package: #{text}")
856
+ return false
857
+ end
858
+ return true
859
+ end
860
+
757
861
  def fix_provides(provides)
758
862
  name_re = /^[^ \(]+/
759
863
  name = provides[name_re]
@@ -768,6 +872,11 @@ class FPM::Package::Deb < FPM::Package
768
872
  "debs don't like underscores")
769
873
  provides = provides.gsub("_", "-")
770
874
  end
875
+
876
+ if m = provides.match(/^([A-Za-z0-9_-]+)\s*=\s*(\d+.*$)/)
877
+ logger.warn("Replacing 'provides' entry #{provides} with syntax 'name (= version)'")
878
+ provides = "#{m[1]} (= #{m[2]})"
879
+ end
771
880
  return provides.rstrip
772
881
  end
773
882
 
@@ -795,12 +904,9 @@ class FPM::Package::Deb < FPM::Package
795
904
 
796
905
  # Tar up the staging_path into control.tar.{compression type}
797
906
  case self.attributes[:deb_compression]
798
- when "gz", nil
907
+ when "gz", "bzip2", nil
799
908
  controltar = "control.tar.gz"
800
909
  compression = "-z"
801
- when "bzip2"
802
- controltar = "control.tar.bz2"
803
- compression = "-j"
804
910
  when "xz"
805
911
  controltar = "control.tar.xz"
806
912
  compression = "-J"
@@ -905,7 +1011,7 @@ class FPM::Package::Deb < FPM::Package
905
1011
  etcfiles = []
906
1012
  # Add everything in /etc
907
1013
  begin
908
- if !attributes[:deb_no_default_config_files?]
1014
+ if !attributes[:deb_no_default_config_files?] && File.exists?(staging_path("/etc"))
909
1015
  logger.warn("Debian packaging tools generally labels all files in /etc as config files, " \
910
1016
  "as mandated by policy, so fpm defaults to this behavior for deb packages. " \
911
1017
  "You can disable this default behavior with --deb-no-default-config-files flag")
@@ -4,6 +4,18 @@ require "backports/latest"
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
@@ -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
- # Create the .txz package archive from the files in staging_path.
84
- File.open(output_path, "wb") do |file|
85
- XZ::StreamWriter.new(file) do |xz|
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'
@@ -4,7 +4,6 @@ require "rubygems"
4
4
  require "fileutils"
5
5
  require "fpm/util"
6
6
  require "yaml"
7
- require "git"
8
7
 
9
8
  # A rubygems package.
10
9
  #
@@ -105,6 +104,7 @@ class FPM::Package::Gem < FPM::Package
105
104
  FileUtils.mkdir(download_dir) unless File.directory?(download_dir)
106
105
 
107
106
  if attributes[:gem_git_repo]
107
+ require "git"
108
108
  logger.debug("Git cloning in directory #{download_dir}")
109
109
  g = Git.clone(attributes[:gem_git_repo],gem_name,:path => download_dir)
110
110
  if attributes[:gem_git_branch]
@@ -90,6 +90,11 @@ class get_metadata(Command):
90
90
  for dep in pkg_resources.parse_requirements(
91
91
  self.distribution.install_requires):
92
92
  final_deps.extend(self.process_dep(dep))
93
+ if getattr(self.distribution, 'extras_require', None):
94
+ for dep in pkg_resources.parse_requirements(
95
+ v for k, v in self.distribution.extras_require.items()
96
+ if k.startswith(':') and pkg_resources.evaluate_marker(k[1:])):
97
+ final_deps.extend(self.process_dep(dep))
93
98
 
94
99
  data["dependencies"] = final_deps
95
100
 
@@ -79,7 +79,11 @@ 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
+ option "--internal-pip", :flag,
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
+ :attribute_name => :python_internal_pip,
86
+ :default => true
83
87
 
84
88
  private
85
89
 
@@ -130,23 +134,24 @@ class FPM::Package::Python < FPM::Package
130
134
  target = build_path(package)
131
135
  FileUtils.mkdir(target) unless File.directory?(target)
132
136
 
133
- if attributes[:python_pip].nil?
134
- # no pip, use easy_install
135
- logger.debug("no pip, defaulting to easy_install", :easy_install => attributes[:python_easyinstall])
136
- safesystem(attributes[:python_easyinstall], "-i",
137
- attributes[:python_pypi], "--editable", "-U",
138
- "--build-directory", target, want_pkg)
139
- else
137
+ if attributes[:python_internal_pip?]
138
+ # XXX: Should we detect if internal pip is available?
139
+ attributes[:python_pip] = [ attributes[:python_bin], "-m", "pip"]
140
+ end
141
+
142
+ # attributes[:python_pip] -- expected to be a path
143
+ if attributes[:python_pip]
140
144
  logger.debug("using pip", :pip => attributes[:python_pip])
141
145
  # TODO: Support older versions of pip
142
146
 
147
+ pip = [attributes[:python_pip]] if pip.is_a?(String)
143
148
  setup_cmd = [
144
- attributes[:python_pip],
149
+ *attributes[:python_pip],
145
150
  "download",
146
151
  "--no-clean",
147
152
  "--no-deps",
148
- "--no-binary",
149
- ":all:",
153
+ "--no-binary", ":all:",
154
+ "-d", build_path,
150
155
  "-i", attributes[:python_pypi],
151
156
  ]
152
157
 
@@ -164,6 +169,12 @@ class FPM::Package::Python < FPM::Package
164
169
  ]
165
170
 
166
171
  safesystem(*setup_cmd)
172
+ else
173
+ # no pip, use easy_install
174
+ logger.debug("no pip, defaulting to easy_install", :easy_install => attributes[:python_easyinstall])
175
+ safesystem(attributes[:python_easyinstall], "-i",
176
+ attributes[:python_pypi], "--editable", "-U",
177
+ "--build-directory", target, want_pkg)
167
178
  end
168
179
 
169
180
  # easy_install will put stuff in @tmpdir/packagename/, so find that:
@@ -4,6 +4,9 @@ require "fileutils"
4
4
  require "find"
5
5
  require "arr-pm/file" # gem 'arr-pm'
6
6
 
7
+ # For conversion handling
8
+ require "fpm/package/gem"
9
+
7
10
  # RPM Package type.
8
11
  #
9
12
  # Build RPMs without having to waste hours reading Maximum-RPM.
@@ -190,14 +193,15 @@ class FPM::Package::RPM < FPM::Package
190
193
  # Replace ? with [?] to make rpm not use globs
191
194
  # Replace % with [%] to make rpm not expand macros
192
195
  def rpm_fix_name(name)
193
- name = name.gsub(/(\ |\[|\]|\*|\?|\%|\$)/, {
196
+ name = name.gsub(/(\ |\[|\]|\*|\?|\%|\$|')/, {
194
197
  ' ' => '?',
195
198
  '%' => '[%]',
196
199
  '$' => '[$]',
197
200
  '?' => '[?]',
198
201
  '*' => '[*]',
199
202
  '[' => '[\[]',
200
- ']' => '[\]]'
203
+ ']' => '[\]]',
204
+ "'" => "\\'",
201
205
  })
202
206
  end
203
207
 
@@ -239,6 +243,8 @@ class FPM::Package::RPM < FPM::Package
239
243
  return %x{uname -m}.chomp # default to current arch
240
244
  when "amd64" # debian and redhat disagree on architecture names
241
245
  return "x86_64"
246
+ when "arm64" # debian and redhat disagree on architecture names
247
+ return "aarch64"
242
248
  when "native"
243
249
  return %x{uname -m}.chomp # 'native' is current arch
244
250
  when "all"
@@ -251,6 +257,12 @@ class FPM::Package::RPM < FPM::Package
251
257
 
252
258
  # This method ensures a default value for iteration if none is provided.
253
259
  def iteration
260
+ if @iteration.kind_of?(String) and @iteration.include?("-")
261
+ logger.warn("Package iteration '#{@iteration}' includes dashes, converting" \
262
+ " to underscores. rpmbuild does not allow the dashes in the package iteration (called 'Release' in rpm)")
263
+ @iteration = @iteration.gsub(/-/, "_")
264
+ end
265
+
254
266
  return @iteration ? @iteration : 1
255
267
  end # def iteration
256
268
 
@@ -2,6 +2,8 @@ require "fpm/namespace"
2
2
  require "fpm/package"
3
3
  require "fpm/util"
4
4
 
5
+ require "fpm/package/dir"
6
+
5
7
  # Support for python virtualenv packages.
6
8
  #
7
9
  # This supports input, but not output.
data/lib/fpm/util.rb CHANGED
@@ -1,21 +1,8 @@
1
1
  require "fpm/namespace"
2
- require "childprocess"
3
- require "ffi"
4
2
  require "fileutils"
5
3
 
6
4
  # Some utility functions
7
5
  module FPM::Util
8
- extend FFI::Library
9
- ffi_lib FFI::Library::LIBC
10
-
11
- # mknod is __xmknod in glibc a wrapper around mknod to handle
12
- # various stat struct formats. See bits/stat.h in glibc source
13
- begin
14
- attach_function :mknod, :mknod, [:string, :uint, :ulong], :int
15
- rescue FFI::NotFoundError
16
- # glibc/io/xmknod.c int __xmknod (int vers, const char *path, mode_t mode, dev_t *dev)
17
- attach_function :xmknod, :__xmknod, [:int, :string, :uint, :pointer], :int
18
- end
19
6
 
20
7
  # Raised if safesystem cannot find the program to run.
21
8
  class ExecutableNotFound < StandardError; end
@@ -23,6 +10,12 @@ module FPM::Util
23
10
  # Raised if a safesystem program exits nonzero
24
11
  class ProcessFailed < StandardError; end
25
12
 
13
+ # Raised when a named pipe cannot be copied due to missing functions in fpm and ruby.
14
+ class NamedPipeCannotBeCopied < StandardError; end
15
+
16
+ # Raised when an attempting to copy a special file such as a block device.
17
+ class UnsupportedSpecialFile < StandardError; end
18
+
26
19
  # Is the given program in the system's PATH?
27
20
  def program_in_path?(program)
28
21
  # return false if path is not set
@@ -146,31 +139,22 @@ module FPM::Util
146
139
 
147
140
  stdout_r, stdout_w = IO.pipe
148
141
  stderr_r, stderr_w = IO.pipe
142
+ stdin_r, stdin_w = IO.pipe
149
143
 
150
- process = ChildProcess.build(*args2)
151
- process.environment.merge!(env)
152
-
153
- process.io.stdout = stdout_w
154
- process.io.stderr = stderr_w
155
-
156
- if block_given? and opts[:stdin]
157
- process.duplex = true
158
- end
159
-
160
- process.start
144
+ pid = Process.spawn(env, *args2, :out => stdout_w, :err => stderr_w, :in => stdin_r)
161
145
 
162
146
  stdout_w.close; stderr_w.close
163
- logger.debug("Process is running", :pid => process.pid)
147
+ logger.debug("Process is running", :pid => pid)
164
148
  if block_given?
165
149
  args3 = []
166
150
  args3.push(process) if opts[:process]
167
- args3.push(process.io.stdin) if opts[:stdin]
151
+ args3.push(stdin_w) if opts[:stdin]
168
152
  args3.push(stdout_r) if opts[:stdout]
169
153
  args3.push(stderr_r) if opts[:stderr]
170
154
 
171
155
  yield(*args3)
172
156
 
173
- process.io.stdin.close if opts[:stdin] and not process.io.stdin.closed?
157
+ stdin_w_close if opts[:stdin] and not stdin_w.closed?
174
158
  stdout_r.close unless stdout_r.closed?
175
159
  stderr_r.close unless stderr_r.closed?
176
160
  else
@@ -179,9 +163,10 @@ module FPM::Util
179
163
  logger.pipe(stdout_r => :info, stderr_r => :info)
180
164
  end
181
165
 
182
- process.wait if process.alive?
166
+ Process.waitpid(pid)
167
+ status = $?
183
168
 
184
- return process.exit_code
169
+ return status.exitstatus
185
170
  end # def execmd
186
171
 
187
172
  # Run a command safely in a way that gets reports useful errors.
@@ -316,19 +301,6 @@ module FPM::Util
316
301
  return @@tar_cmd_deterministic
317
302
  end
318
303
 
319
- # wrapper around mknod ffi calls
320
- def mknod_w(path, mode, dev)
321
- rc = -1
322
- case %x{uname -s}.chomp
323
- when 'Linux'
324
- # bits/stat.h #define _MKNOD_VER_LINUX 0
325
- rc = xmknod(0, path, mode, FFI::MemoryPointer.new(dev))
326
- else
327
- rc = mknod(path, mode, dev)
328
- end
329
- rc
330
- end
331
-
332
304
  def copy_metadata(source, destination)
333
305
  source_stat = File::lstat(source)
334
306
  dest_stat = File::lstat(destination)
@@ -354,10 +326,21 @@ module FPM::Util
354
326
 
355
327
  def copy_entry(src, dst, preserve=false, remove_destination=false)
356
328
  case File.ftype(src)
357
- when 'fifo', 'characterSpecial', 'blockSpecial', 'socket'
358
- st = File.stat(src)
359
- rc = mknod_w(dst, st.mode, st.dev)
360
- raise SystemCallError.new("mknod error", FFI.errno) if rc == -1
329
+ when 'fifo'
330
+ if File.respond_to?(:mkfifo)
331
+ File.mkfifo(dst)
332
+ elsif program_exists?("mkfifo")
333
+ safesystem("mkfifo", dst)
334
+ else
335
+ raise NamedPipeCannotBeCopied("Unable to copy. Cannot find program 'mkfifo' and Ruby is missing the 'File.mkfifo' method: #{src}")
336
+ end
337
+ when 'socket'
338
+ require "socket"
339
+ # In 2019, Ruby's FileUtils added this as a way to "copy" a unix socket.
340
+ # Reference: https://github.com/ruby/fileutils/pull/36/files
341
+ UNIXServer.new(dst).close()
342
+ when 'characterSpecial', 'blockSpecial'
343
+ raise UnsupportedSpecialFile.new("File is device which fpm doesn't know how to copy (#{File.ftype(src)}): #{src}")
361
344
  when 'directory'
362
345
  FileUtils.mkdir(dst) unless File.exists? dst
363
346
  else
data/lib/fpm/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module FPM
2
- VERSION = "1.12.0"
2
+ VERSION = "1.14.1"
3
3
  end
@@ -20,6 +20,7 @@ debsystemctl=$(command -v deb-systemd-invoke || echo systemctl)
20
20
  <% attributes[:deb_systemd].each do |service| -%>
21
21
  if ! systemctl is-enabled <%= service %> >/dev/null
22
22
  then
23
+ : # Ensure this if-clause is not empty. If it were empty, and we had an 'else', then it is an error in shell syntax
23
24
  <% if attributes[:deb_systemd_enable?]-%>
24
25
  systemctl enable <%= service %> >/dev/null || true
25
26
  <% end -%>
data/templates/deb.erb CHANGED
@@ -25,7 +25,7 @@ Build-Depends: <%= attributes[:deb_build_depends].collect { |d| fix_dependency(d
25
25
  <% if !provides.empty? -%>
26
26
  <%# Turn each provides from 'foo = 123' to simply 'foo' because Debian :\ -%>
27
27
  <%# http://www.debian.org/doc/debian-policy/ch-relationships.html -%>
28
- Provides: <%= provides.map {|p| p.split(" ").first}.join ", " %>
28
+ Provides: <%= provides.join ", " %>
29
29
  <% end -%>
30
30
  <% if !replaces.empty? -%>
31
31
  Replaces: <%= replaces.collect { |d| fix_dependency(d) }.flatten.join(", ") %>
data/templates/rpm.erb CHANGED
@@ -126,7 +126,7 @@ Obsoletes: <%= repl %>
126
126
  -%>
127
127
  <% if script?(:before_upgrade) or script?(:after_upgrade) -%>
128
128
  <% if script?(:before_upgrade) or script?(:before_install) -%>
129
- %pre <% if attributes[:rpm_macro_expansion?] -%><%= " -e " %> <% end -%>
129
+ %pre <% if attributes[:rpm_macro_expansion?] -%><%= " -e " %> <% end %>
130
130
  upgrade() {
131
131
  <%# Making sure that at least one command is in the function -%>
132
132
  <%# avoids a lot of potential errors, including the case that -%>
@@ -156,7 +156,7 @@ then
156
156
  fi
157
157
  <% end -%>
158
158
  <% if script?(:after_upgrade) or script?(:after_install) -%>
159
- %post <% if attributes[:rpm_macro_expansion?] -%><%= " -e " %> <% end -%>
159
+ %post <% if attributes[:rpm_macro_expansion?] -%><%= " -e " %> <% end %>
160
160
  upgrade() {
161
161
  <%# Making sure that at least one command is in the function -%>
162
162
  <%# avoids a lot of potential errors, including the case that -%>
@@ -186,7 +186,7 @@ then
186
186
  fi
187
187
  <% end -%>
188
188
  <% if script?(:before_remove) -%>
189
- %preun <% if attributes[:rpm_macro_expansion?] -%><%= " -e " %> <% end -%>
189
+ %preun <% if attributes[:rpm_macro_expansion?] -%><%= " -e " %> <% end %>
190
190
  if [ "${1}" -eq 0 ]
191
191
  then
192
192
  <%# Making sure that at least one command is in the function -%>
@@ -197,7 +197,7 @@ then
197
197
  fi
198
198
  <% end -%>
199
199
  <% if script?(:after_remove) -%>
200
- %postun <% if attributes[:rpm_macro_expansion?] -%><%= " -e " %> <% end -%>
200
+ %postun <% if attributes[:rpm_macro_expansion?] -%><%= " -e " %> <% end %>
201
201
  if [ "${1}" -eq 0 ]
202
202
  then
203
203
  <%# Making sure that at least one command is in the function -%>
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.12.0
4
+ version: 1.14.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jordan Sissel
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-01-19 00:00:00.000000000 Z
11
+ date: 2021-11-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: json
@@ -64,14 +64,14 @@ dependencies:
64
64
  requirements:
65
65
  - - "~>"
66
66
  - !ruby/object:Gem::Version
67
- version: 0.0.10
67
+ version: 0.0.11
68
68
  type: :runtime
69
69
  prerelease: false
70
70
  version_requirements: !ruby/object:Gem::Requirement
71
71
  requirements:
72
72
  - - "~>"
73
73
  - !ruby/object:Gem::Version
74
- version: 0.0.10
74
+ version: 0.0.11
75
75
  - !ruby/object:Gem::Dependency
76
76
  name: clamp
77
77
  requirement: !ruby/object:Gem::Requirement
@@ -86,62 +86,6 @@ dependencies:
86
86
  - - "~>"
87
87
  - !ruby/object:Gem::Version
88
88
  version: 1.0.0
89
- - !ruby/object:Gem::Dependency
90
- name: childprocess
91
- requirement: !ruby/object:Gem::Requirement
92
- requirements:
93
- - - "<"
94
- - !ruby/object:Gem::Version
95
- version: 1.0.0
96
- type: :runtime
97
- prerelease: false
98
- version_requirements: !ruby/object:Gem::Requirement
99
- requirements:
100
- - - "<"
101
- - !ruby/object:Gem::Version
102
- version: 1.0.0
103
- - !ruby/object:Gem::Dependency
104
- name: ffi
105
- requirement: !ruby/object:Gem::Requirement
106
- requirements:
107
- - - "~>"
108
- - !ruby/object:Gem::Version
109
- version: 1.12.0
110
- type: :runtime
111
- prerelease: false
112
- version_requirements: !ruby/object:Gem::Requirement
113
- requirements:
114
- - - "~>"
115
- - !ruby/object:Gem::Version
116
- version: 1.12.0
117
- - !ruby/object:Gem::Dependency
118
- name: rake
119
- requirement: !ruby/object:Gem::Requirement
120
- requirements:
121
- - - "~>"
122
- - !ruby/object:Gem::Version
123
- version: '10'
124
- type: :development
125
- prerelease: false
126
- version_requirements: !ruby/object:Gem::Requirement
127
- requirements:
128
- - - "~>"
129
- - !ruby/object:Gem::Version
130
- version: '10'
131
- - !ruby/object:Gem::Dependency
132
- name: ruby-xz
133
- requirement: !ruby/object:Gem::Requirement
134
- requirements:
135
- - - "~>"
136
- - !ruby/object:Gem::Version
137
- version: 0.2.3
138
- type: :runtime
139
- prerelease: false
140
- version_requirements: !ruby/object:Gem::Requirement
141
- requirements:
142
- - - "~>"
143
- - !ruby/object:Gem::Version
144
- version: 0.2.3
145
89
  - !ruby/object:Gem::Dependency
146
90
  name: pleaserun
147
91
  requirement: !ruby/object:Gem::Requirement
@@ -190,6 +134,20 @@ dependencies:
190
134
  - - ">="
191
135
  - !ruby/object:Gem::Version
192
136
  version: '0'
137
+ - !ruby/object:Gem::Dependency
138
+ name: rexml
139
+ requirement: !ruby/object:Gem::Requirement
140
+ requirements:
141
+ - - ">="
142
+ - !ruby/object:Gem::Version
143
+ version: '0'
144
+ type: :runtime
145
+ prerelease: false
146
+ version_requirements: !ruby/object:Gem::Requirement
147
+ requirements:
148
+ - - ">="
149
+ - !ruby/object:Gem::Version
150
+ version: '0'
193
151
  - !ruby/object:Gem::Dependency
194
152
  name: rspec
195
153
  requirement: !ruby/object:Gem::Requirement
@@ -306,7 +264,7 @@ homepage: https://github.com/jordansissel/fpm
306
264
  licenses:
307
265
  - MIT-like
308
266
  metadata: {}
309
- post_install_message:
267
+ post_install_message:
310
268
  rdoc_options: []
311
269
  require_paths:
312
270
  - lib
@@ -322,9 +280,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
322
280
  - !ruby/object:Gem::Version
323
281
  version: '0'
324
282
  requirements: []
325
- rubyforge_project:
326
- rubygems_version: 2.7.6
327
- signing_key:
283
+ rubygems_version: 3.2.31
284
+ signing_key:
328
285
  specification_version: 4
329
286
  summary: fpm - package building and mangling
330
287
  test_files: []