fpm 1.11.0 → 1.15.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: 24a4dd08de1d4ad02888c110b88ab0d6fd590d4d913aba61ec459d126fb84d40
4
- data.tar.gz: d8c7e7867cff9198ee1d170a17534946a8cb82c1217ddb09d316f061e3be86d2
3
+ metadata.gz: ea647fcf022326ec4218db722e99c134664446ef0f5ce1885a7440acb1bc6a85
4
+ data.tar.gz: 8fa7b284c275629fac6d598211c2c54628c527435afbc835582279c760162786
5
5
  SHA512:
6
- metadata.gz: df2cbe11e18c252ef87d75f724abb3de218be2b9050e8d1918c6d323ab49e02b84793a4de327f522f04eca2fa56d90d5ba50a56f49fb36f6d5e976f10a6b4e56
7
- data.tar.gz: 3b93a0208cb451ee13c4cdc65adec6e68c46e2619f2d54114cfa6e4745be52d28ba12223701fc496866c4878b914f896232a389b0f37f07667c80224f6724933
6
+ metadata.gz: a8f4c7e20bc10732d29febc59824562d2da5d1273d6ca96788d0e033b08b9b4dad1fac8281f8030f70a65dd465fbffc194448f13291cc51105172e35370c1800
7
+ data.tar.gz: 4fcd3503b21ec04b1edb28ffca688898799d35f437cf097f4a3938adab78644bd0294bf9a4af327827bea63df04028150ada442727a0a41c005b59911c2d7a42
data/CHANGELOG.rst CHANGED
@@ -1,6 +1,95 @@
1
1
  Release Notes and Change Log
2
2
  ============================
3
3
 
4
+ 1.15.0 (November 13, 2022)
5
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^
6
+ * New flag ``--fpm-options-file path/to/file`` which allows you to specify additional fpm flags in an external file of your choosing. (`#1905`_, `#1902`_, `#1827`_; Jordan Sissel, Will Furnell, hjpotter92)
7
+ * deb: Periods are now accepted in package names (`#1899`_; C. Cooke)
8
+ * Fix bug where fpm would crash if ``--workdir`` pointed at a path that didn't
9
+ exist. (`#1959`_; Jordan Sissel)
10
+ * osxpkg: this package format now supports the fpm ``--prefix`` flag(`#1909`_, `#1908`_; Jordan Sissel, mcataga)
11
+ * cpan: Fix bug where fpm would fail on certain Perl modules due to their source tarball structure (`#1940`_; Nicholas Hubbard, William N. Braswell, Jr.)
12
+ * cpan: Fix crash on certain CPAN modules where the author field was blank (`#1942`_, `#1937`_, `#1523`_, `#1528`_; Nicholas Hubbard, William N. Braswell, Jr.)
13
+ * deb: The distribution field of the debian changelog and changes files will now use the value set by ``--deb-dist`` (default is "unstable") (`#1934`_; Chabert Loïc)
14
+ * python: Fix errors in how fpm invoked ``pip``. Previously, fpm would use pip's ``--build`` flag, but this was removed a while ago, and fpm is now aware! (`#1896`_, `#1831`_, `#1893`_, `#1916`_; Jordan Sissel, Svyatogor Chuykov)
15
+ * pleaserun: Add ``--pleaserun-user`` flag. (`#1912`_; Evgeny Stambulchik)
16
+ * deb: The default ``--deb-priority`` is now "optional" instead of "extra" (`#1913`_; Chris Novakovic)
17
+ * https://github.com/jordansissel/fpm/pull/1897 (`#1897`_; Jordan Sissel)
18
+ * Enable installation of fpm on older versions of ruby. This change removed ``git`` rubygem dependency. (`#1946`_, `#1923`_; Jordan Sissel, Andreas Wirooks, Ruslan Kuprieiev, jamshid, Lorenzo Castellino, Sam Hughes)
19
+ * Enable operation of fpm on very old versions of ruby (as old as Ruby 1.9.3). This changed removed ``json`` rubygem dependency. (`#1950`_, `#1949`_, `#1741`_, `#1264`_, `#1798`_, `#1800`_, `#1784`_; Jordan Sissel and many others)
20
+ * Fix bug where subprocesses could hang waiting for input (`#1955`_, `#1519`_, `#1522`_; Nicholas Hubbard, William N. Braswell, Jr.)
21
+ * Update Dockerfile to use ubuntu:20.04 (`#1935`_; Gnought)
22
+ * internal: Fix a code typo (`#1948`_; Nicholas Hubbard)
23
+ * internal tests: Support newer versions of lintian (`#1939`_, `#1907`_; Jordan Sissel)
24
+ * Improve support for Ruby 3.1.0 and newer that would previously crash with an error mentioning Psych::DisallowedClass (`#1898`_, `#1895`_; Jordan Sissel, Alexandre ZANNI)
25
+ * Improve support for Ruby 3.1.0 and newer that changed the API for ERB
26
+
27
+ 1.14.2 (March 30, 2022)
28
+ ^^^^^^^^^^^^^^^^^^^^^^^
29
+ * deb: fix bug causing ``--deb-compression none`` to invoke ``tar`` incorrectly (`#1879`_; John Howard)
30
+ * rpm: Better support for paths that have spaces and mixed quotation marks in them. (`#1882`_, `#1886`_, `#1385`_; John Bollinger and Jordan Sissel)
31
+ * pacman: Fix typo preventing the use of ``--pacman-compression xz`` (`#1876`_; mszprejda)
32
+ * docs: All supported package types now have dedicated documentation pages. Some pages are small stubs and would benefit from future improvement. (`#1884`_; mcandre, Jordan Sissel)
33
+ * docs: Small but lovely documentation fixes (`#1875`_ by Corey Quinn, `#1864`_ by Geoff Beier)
34
+ * Fixed mistake causing the test suite to fail when ``rake`` wasn't available. (`#1877`_; Jordan Sissel)
35
+
36
+ 1.14.1 (November 10, 2021)
37
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^
38
+ * 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)
39
+
40
+ 1.14.0 (November 9, 2021)
41
+ ^^^^^^^^^^^^^^^^^^^^^^^^^
42
+ * 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)
43
+ * python: Support extras_require build markers in python packages (`#1307`_, `#1816`_; Joris Vandermeersch)
44
+ * 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)
45
+ * 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)
46
+ * deb: Only show a warning about /etc and config files if there are files in /etc (`#1852`_, `#1851`_; Jordan Sissel)
47
+
48
+ * rpm: replace dash with underscore in rpm's "Release" field aka what fpm calls ``--iteration``. (`#1834`_, `#1833`_; Jordan Sissel)
49
+ * empty: `fpm -s empty ...` now defaults to "all" architecture instead of "native". (`#1850`_, `#1846`_; Jordan Sissel)
50
+ * 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)
51
+ * Typo fixes in documentation are always appreciated! (`#1842`_; Clayton Wong)
52
+ * fpm can now (we hope!) now be tested more easily from docker (`#1818`_, `#1682`_, `#1453`_; @directionless, Jordan Sissel, Douglas Muth)
53
+
54
+ 1.13.1 (July 6, 2021)
55
+ ^^^^^^^^^^^^^^^^^^^^^
56
+ * deb: The `--provides` flag now allows for versions. Previously, fpm would
57
+ remove the version part of a provides field when generating deb packages.
58
+ (`#1788`_, `#1803`_; Jordan Sissel, Phil Schwartz, tympanix)
59
+ * osxpkg: Update documentation to include installing `rpm` tools on OSX
60
+ (`#1797`_; allen joslin)
61
+
62
+ 1.13.0 (June 19, 2021)
63
+ ^^^^^^^^^^^^^^^^^^^^^^
64
+ * Apple M1 users should now work (`#1772`_, `#1785`_, `#1786`_; Jordan Sissel)
65
+ * 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)
66
+ * 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)
67
+ * Docs: Fix a typo in an example (`#1785`_; Zoe O'Connell)
68
+ * rpm: File paths can now contain single-quote characters (`#1774`_; Jordan Sissel)
69
+ * rpm: Use correct SPEC syntax when using --after-upgrade or similar features (`#1761`_; Jo Vandeginste. Robert Fielding)
70
+ * 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)
71
+ * 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)
72
+ * deb: Fix syntax error in `postinst` (`--after-install`) script. (`#1752`_, `#1749`_, `#1764`_; rmanus, Adam Mohammed, Elliot Murphy, kimw, Jordan Sissel)
73
+ * deb: --deb-compression now uses the same compression and file suffix on the control.tar file (`#1760`_; Philippe Poilbarbe)
74
+
75
+
76
+ 1.12.0 (January 19, 2021)
77
+ ^^^^^^^^^^^^^^^^^^^^^^^^^
78
+
79
+ * Pin ffi dependency to ruby ffi 1.12.x to try keeping fpm compatible with older/abandoned rubies like 2.0 and 2.1. (`#1709`_; Matt Patterson)
80
+ * deb: New flag to add 'set -e' to all scripts. `--deb-maintainerscripts-force-errorchecks` which defaults to off. (`#1697`_; Andreas Ulm)
81
+ * deb: Fix bug when converting rubygems to debs where certain constraints like `~>1` would generate a deb dependency that couldn't be satisfied. (`#1699`_; Vlastimil Holer)
82
+ * deb: Fix error 'uninitialized constant FPM::Package::Deb::Zlib' (`#1739`_, `#1740`_; Federico Lancerin)
83
+ * python: Prepend to PYTHONPATH instead of replacing it. This should help on platforms that rely heavily on PYTHONPATH, such as NixOSX (`#1711`_, `#1710`_; anarg)
84
+ * python: Add `--python-trusted-host` flag which passes `--trusted-host` flag to `pip` (`#1737`_; Vladimir Ponarevsky)
85
+ * Documentation improvements (`#1724`_, `#1738`_, `#1667`_, `#1636`_)
86
+ * Dockerfile updated to Alpine 3.12 (`#1745`_; Cameron Nemo)
87
+ * Remove the 'backports' deprecation warning (`#1727`_; Jose Galvez)
88
+ * sh: Performance improvement when printing package metadata (`#1729`_; James Logsdon, Ed Healy)
89
+ * rpm: Add support for `xzmt` compression (multithreaded xz compressor) to help when creating very large packages (several gigabytes). (`#1447`_, `#1419`_; amnobc)
90
+ * rpm: Add `--rpm-macro-expansion` flag to enable macro expansion in scripts during rpmbuild. See https://rpm.org/user_doc/scriptlet_expansion.html for more details. (`#1642`_; juliantrzeciak)
91
+ * deb: use correct control.tar filename (`#1668`_; Mike Perham)
92
+
4
93
  1.11.0 (January 30, 2019)
5
94
  ^^^^^^^^^^^^^^^^^^^^^^^^^
6
95
 
@@ -19,7 +108,7 @@ Release Notes and Change Log
19
108
  * cpan: Adds `--[no-]cpan-verbose` flag which, when set, runs `cpanm` with the `--verbose` flag (`#1511`_; William N. Braswell, Jr)
20
109
 
21
110
  1.10.0 (May 21, 2018)
22
- ^^^^^^^^^^^^^^^^^^^^
111
+ ^^^^^^^^^^^^^^^^^^^^^
23
112
 
24
113
  * Pin `ruby-xz` dependency to one which allows Ruby versions older than 2.3.0 (`#1494`_; Marat Sharafutdinov)
25
114
  * Documentation improvements: `#1488`_; Arthur Burkart. `#1384`_; Justin Kolberg. `#1452`_; Anatoli Babenia.
@@ -47,7 +136,7 @@ Release Notes and Change Log
47
136
  * rpm: Fix `--config-files` handling (`#1390`_, `#1391`_; Jordan Sissel)
48
137
 
49
138
  1.9.1 (July 28, 2017) happy sysadmin day!
50
- ^^^^^^^^^^^^^^^^^^^^^
139
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
51
140
 
52
141
  * Documentation improvements: `#1291`_; Pablo Castellano. `#1321`_; ge-fa. `#1309`_; jesusbagpuss. `#1349`_; Perry Stole. `#1352`_, Jordan Sissel. `#1384`_; Justin Kolberg.
53
142
  * Testing improvements: `#1320`_; Rob Young. `#1266`_; Ryan Parman. `#1374`_; Thiago Figueiró.
@@ -76,9 +165,9 @@ Release Notes and Change Log
76
165
  * Other: Remove unused archive-tar-minitar as a dependency of fpm (`#1355`_; Diego Martins)
77
166
  * Other: Add stud as a runtime dependency (`#1354`_; Elan Ruusamäe)
78
167
 
79
- .. _reproducible_builds:: https://reproducible-builds.org/
80
- .. _path mapping:: http://fpm.readthedocs.io/en/latest/source/dir.html#path-mapping
81
- .. _Deterministic output:: http://fpm.readthedocs.io/en/latest/source/gem.html
168
+ .. _reproducible_builds: https://reproducible-builds.org/
169
+ .. _path mapping: source/dir.html#path-mapping
170
+ .. _Deterministic output: source/gem.html
82
171
 
83
172
  1.9.0 (July 28, 2017)
84
173
  ^^^^^^^^^^^^^^^^^^^^^
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
data/lib/fpm/command.rb CHANGED
@@ -247,6 +247,13 @@ class FPM::Command < Clamp::Command
247
247
  "See https://reproducible-builds.org/specs/source-date-epoch ",
248
248
  :environment_variable => "SOURCE_DATE_EPOCH"
249
249
 
250
+ option "--fpm-options-file", "FPM_OPTIONS_FILE",
251
+ "A file that contains additional fpm options. Any fpm flag format is valid in this file. " \
252
+ "This can be useful on build servers where you want to use a common configuration or " \
253
+ "inject other parameters from a file instead of from a command-line flag.." do |path|
254
+ load_options(path)
255
+ end
256
+
250
257
  parameter "[ARGS] ...",
251
258
  "Inputs to the source package type. For the 'dir' type, this is the files" \
252
259
  " and directories you want to include in the package. For others, like " \
@@ -291,6 +298,15 @@ class FPM::Command < Clamp::Command
291
298
  args << "."
292
299
  end
293
300
 
301
+ if !File.exists?(workdir)
302
+ logger.fatal("Given --workdir=#{workdir} is not a path that exists.")
303
+ raise FPM::Package::InvalidArgument, "The given workdir '#{workdir}' does not exist."
304
+ end
305
+ if !File.directory?(workdir)
306
+ logger.fatal("Given --workdir=#{workdir} must be a directory")
307
+ raise FPM::Package::InvalidArgument, "The given workdir '#{workdir}' must be a directory."
308
+ end
309
+
294
310
  logger.info("Setting workdir", :workdir => workdir)
295
311
  ENV["TMP"] = workdir
296
312
 
@@ -571,12 +587,86 @@ class FPM::Command < Clamp::Command
571
587
 
572
588
  ARGV.unshift(*flags)
573
589
  ARGV.push(*args)
590
+
574
591
  super(run_args)
575
592
  rescue FPM::Package::InvalidArgument => e
576
593
  logger.error("Invalid package argument: #{e}")
577
594
  return 1
578
595
  end # def run
579
596
 
597
+ def load_options(path)
598
+ @loaded_files ||= []
599
+
600
+ if @loaded_files.include?(path)
601
+ #logger.error("Options file was already loaded once. Refusing to load a second time.", :path => path)
602
+ raise FPM::Package::InvalidArgument, "Options file already loaded once. Refusing to load a second time. Maybe a file tries to load itself? Path: #{path}"
603
+ end
604
+
605
+ if !File.exist?(path)
606
+ logger.fatal("Cannot load options from file because the file doesn't exist.", :path => path)
607
+ end
608
+
609
+ if !File.readable?(path)
610
+ logger.fatal("Cannot load options from file because the file isn't readable.", :path => path)
611
+ end
612
+
613
+ @loaded_files << path
614
+
615
+ logger.info("Loading flags from file", :path => path)
616
+
617
+ # Safety check, abort if the file is huge. Arbitrarily chosen limit is 100kb
618
+ stat = File.stat(path)
619
+ max = 100 * 1024
620
+ if stat.size > max
621
+ logger.fatal("Refusing to load options from file because the file seems pretty large.", :path => path, :size => stat.size)
622
+ raise FPM::Package::InvalidArgument, "Options file given to --fpm-options-file is seems too large. For safety, fpm is refusing to load this. Path: #{path} - Size: #{stat.size}, maximum allowed size #{max}."
623
+ end
624
+
625
+ File.read(path).split($/).each do |line|
626
+ logger.info("Processing flags from file", :path => path, :line => line)
627
+ # With apologies for this hack to mdub (Mike Williams, author of Clamp)...
628
+ # The following code will read a file and parse the file
629
+ # as flags as if they were in same argument position as the given --fpm-options-file option.
630
+
631
+ args = Shellwords.split(line)
632
+ while args.any?
633
+ arg = args.shift
634
+
635
+ # Lookup the Clamp option by its --flag-name or short name like -f
636
+ if arg =~ /^-/
637
+ # Single-letter options like -a or -z
638
+ if single_letter = arg.match(/^(-[A-Za-z0-9])(.*)$/)
639
+ option = self.class.find_option(single_letter.match(1))
640
+ arg, remainder = single_letter.match(1), single_letter.match(2)
641
+ if option.flag?
642
+ # Flags aka switches take no arguments, so we push the rest of the 'arg' entry back onto the args list
643
+
644
+ # For combined letter flags, like `-abc`, we want to consume the
645
+ # `-a` and then push `-bc` back to be processed.
646
+ # Only do this if there's more flags, like, not for `-a` but yes for `-abc`
647
+ args.unshift("-" + remainder) unless remainder.empty?
648
+ else
649
+ # Single letter options that take arguments, like `-ohello` same as `-o hello`
650
+
651
+ # For single letter flags with values, like `-ofilename` aka `-o filename`, push the remainder ("filename")
652
+ # back onto the args list so that it is consumed when we extract the flag value.
653
+ args.unshift(remainder) unless remainder.empty?
654
+ end
655
+ elsif arg.match(/^--/)
656
+ # Lookup the flag by its long --flag-name
657
+ option = self.class.find_option(arg)
658
+ end
659
+ end
660
+
661
+ # Extract the flag value, if any, from the remaining args list.
662
+ value = option.extract_value(arg, args)
663
+
664
+ # Process the flag into `self`
665
+ option.of(self).take(value)
666
+ end
667
+ end
668
+ end
669
+
580
670
  # A simple flag validator
581
671
  #
582
672
  # The goal of this class is to ensure the flags and arguments given
@@ -3,7 +3,7 @@ require "fpm/namespace"
3
3
  require "fpm/package"
4
4
  require "fpm/errors"
5
5
  require "fpm/util"
6
- require "backports"
6
+ require "backports/latest"
7
7
  require "fileutils"
8
8
  require "digest"
9
9
  require 'digest/sha1'
@@ -112,6 +112,7 @@ class FPM::Package::CPAN < FPM::Package
112
112
  self.vendor = case metadata["author"]
113
113
  when String; metadata["author"]
114
114
  when Array; metadata["author"].join(", ")
115
+ when NilClass; "No Vendor Or Author Provided"
115
116
  else
116
117
  raise FPM::InvalidPackageConfiguration, "Unexpected CPAN 'author' field type: #{metadata["author"].class}. This is a bug."
117
118
  end if metadata.include?("author")
@@ -304,7 +305,7 @@ class FPM::Package::CPAN < FPM::Package
304
305
  directory = build_path("module")
305
306
  ::Dir.mkdir(directory)
306
307
  args = [ "-C", directory, "-zxf", tarball,
307
- "--strip-components", "1" ]
308
+ %q{--transform=s,[./]*[^/]*/,,} ]
308
309
  safesystem("tar", *args)
309
310
  return directory
310
311
  end
@@ -3,9 +3,14 @@ require "fpm/namespace"
3
3
  require "fpm/package"
4
4
  require "fpm/errors"
5
5
  require "fpm/util"
6
- require "backports"
6
+ require "backports/latest"
7
7
  require "fileutils"
8
8
  require "digest"
9
+ require "zlib"
10
+
11
+ # For handling conversion
12
+ require "fpm/package/cpan"
13
+ require "fpm/package/gem"
9
14
 
10
15
  # Support for debian packages (.deb files)
11
16
  #
@@ -24,6 +29,22 @@ class FPM::Package::Deb < FPM::Package
24
29
  # The list of supported compression types. Default is gz (gzip)
25
30
  COMPRESSION_TYPES = [ "gz", "bzip2", "xz", "none" ]
26
31
 
32
+ # https://www.debian.org/doc/debian-policy/ch-relationships.html#syntax-of-relationship-fields
33
+ # Example value with version relationship: libc6 (>= 2.2.1)
34
+ # Example value: libc6
35
+
36
+ # Package name docs here: https://www.debian.org/doc/debian-policy/ch-controlfields.html#s-f-source
37
+ # Package names (both source and binary, see Package) must consist only of lower case letters (a-z),
38
+ # digits (0-9), plus (+) and minus (-) signs, and periods (.).
39
+ # They must be at least two characters long and must start with an alphanumeric character.
40
+
41
+ # Version string docs here: https://www.debian.org/doc/debian-policy/ch-controlfields.html#s-f-version
42
+ # The format is: [epoch:]upstream_version[-debian_revision].
43
+ # epoch - This is a single (generally small) unsigned integer
44
+ # upstream_version - must contain only alphanumerics 6 and the characters . + - ~
45
+ # debian_revision - only alphanumerics and the characters + . ~
46
+ RELATIONSHIP_FIELD_PATTERN = /^(?<name>[A-z0-9][A-z0-9_.-]+)(?: *\((?<relation>[<>=]+) *(?<version>(?:[0-9]+:)?[0-9A-Za-z+~.-]+(?:-[0-9A-Za-z+~.]+)?)\))?$/
47
+
27
48
  option "--ignore-iteration-in-dependencies", :flag,
28
49
  "For '=' (equal) dependencies, allow iterations on the specified " \
29
50
  "version. Default is to be specific. This option allows the same " \
@@ -77,7 +98,7 @@ class FPM::Package::Deb < FPM::Package
77
98
  end
78
99
 
79
100
  option "--priority", "PRIORITY",
80
- "The debian package 'priority' value.", :default => "extra"
101
+ "The debian package 'priority' value.", :default => "optional"
81
102
 
82
103
  option "--use-file-permissions", :flag,
83
104
  "Use existing file permissions when defining ownership and modes"
@@ -177,10 +198,14 @@ class FPM::Package::Deb < FPM::Package
177
198
  end
178
199
 
179
200
  option "--systemd", "FILEPATH", "Add FILEPATH as a systemd script",
180
- :multivalued => true do |file|
201
+ :multivalued => true do |file|
181
202
  next File.expand_path(file)
182
203
  end
183
204
 
205
+ option "--systemd-enable", :flag , "Enable service on install or upgrade", :default => false
206
+
207
+ option "--systemd-auto-start", :flag , "Start service after install or upgrade", :default => false
208
+
184
209
  option "--systemd-restart-after-upgrade", :flag , "Restart service after upgrade", :default => true
185
210
 
186
211
  option "--after-purge", "FILE",
@@ -189,9 +214,14 @@ class FPM::Package::Deb < FPM::Package
189
214
  File.expand_path(val) # Get the full path to the script
190
215
  end # --after-purge
191
216
 
217
+ option "--maintainerscripts-force-errorchecks", :flag ,
218
+ "Activate errexit shell option according to lintian. " \
219
+ "https://lintian.debian.org/tags/maintainer-script-ignores-errors.html",
220
+ :default => false
221
+
192
222
  def initialize(*args)
193
223
  super(*args)
194
- attributes[:deb_priority] = "extra"
224
+ attributes[:deb_priority] = "optional"
195
225
  end # def initialize
196
226
 
197
227
  private
@@ -218,6 +248,9 @@ class FPM::Package::Deb < FPM::Package
218
248
  when "x86_64"
219
249
  # Debian calls x86_64 "amd64"
220
250
  @architecture = "amd64"
251
+ when "aarch64"
252
+ # Debian calls aarch64 "arm64"
253
+ @architecture = "arm64"
221
254
  when "noarch"
222
255
  # Debian calls noarch "all"
223
256
  @architecture = "all"
@@ -414,6 +447,12 @@ class FPM::Package::Deb < FPM::Package
414
447
 
415
448
  def output(output_path)
416
449
  self.provides = self.provides.collect { |p| fix_provides(p) }
450
+
451
+ self.provides.each do |provide|
452
+ if !valid_provides_field?(provide)
453
+ raise FPM::InvalidPackageConfiguration, "Found invalid Provides field values (#{provide.inspect}). This is not valid in a Debian package."
454
+ end
455
+ end
417
456
  output_check(output_path)
418
457
  # Abort if the target path already exists.
419
458
 
@@ -453,6 +492,7 @@ class FPM::Package::Deb < FPM::Package
453
492
  raise "#{name}: tar is insufficient to support source_date_epoch."
454
493
  end
455
494
 
495
+ attributes[:deb_systemd] = []
456
496
  attributes.fetch(:deb_systemd_list, []).each do |systemd|
457
497
  name = File.basename(systemd, ".service")
458
498
  dest_systemd = staging_path("lib/systemd/system/#{name}.service")
@@ -460,19 +500,19 @@ class FPM::Package::Deb < FPM::Package
460
500
  FileUtils.cp(systemd, dest_systemd)
461
501
  File.chmod(0644, dest_systemd)
462
502
 
463
- # set the attribute with the systemd service name
464
- attributes[:deb_systemd] = name
503
+ # add systemd service name to attribute
504
+ attributes[:deb_systemd] << name
465
505
  end
466
506
 
467
- if script?(:before_upgrade) or script?(:after_upgrade) or attributes[:deb_systemd]
507
+ if script?(:before_upgrade) or script?(:after_upgrade) or attributes[:deb_systemd].any?
468
508
  puts "Adding action files"
469
509
  if script?(:before_install) or script?(:before_upgrade)
470
510
  scripts[:before_install] = template("deb/preinst_upgrade.sh.erb").result(binding)
471
511
  end
472
- if script?(:before_remove) or attributes[:deb_systemd]
512
+ if script?(:before_remove) or not attributes[:deb_systemd].empty?
473
513
  scripts[:before_remove] = template("deb/prerm_upgrade.sh.erb").result(binding)
474
514
  end
475
- if script?(:after_install) or script?(:after_upgrade) or attributes[:deb_systemd]
515
+ if script?(:after_install) or script?(:after_upgrade) or attributes[:deb_systemd].any?
476
516
  scripts[:after_install] = template("deb/postinst_upgrade.sh.erb").result(binding)
477
517
  end
478
518
  if script?(:after_remove)
@@ -577,22 +617,25 @@ class FPM::Package::Deb < FPM::Package
577
617
  case self.attributes[:deb_compression]
578
618
  when "gz", nil
579
619
  datatar = build_path("data.tar.gz")
580
- compression = "-z"
620
+ controltar = build_path("control.tar.gz")
621
+ compression_flags = ["-z"]
581
622
  when "bzip2"
582
623
  datatar = build_path("data.tar.bz2")
583
- compression = "-j"
624
+ controltar = build_path("control.tar.gz")
625
+ compression_flags = ["-j"]
584
626
  when "xz"
585
627
  datatar = build_path("data.tar.xz")
586
- compression = "-J"
628
+ controltar = build_path("control.tar.xz")
629
+ compression_flags = ["-J"]
587
630
  when "none"
588
631
  datatar = build_path("data.tar")
589
- compression = ""
632
+ controltar = build_path("control.tar")
633
+ compression_flags = []
590
634
  else
591
635
  raise FPM::InvalidPackageConfiguration,
592
636
  "Unknown compression type '#{self.attributes[:deb_compression]}'"
593
637
  end
594
-
595
- args = [ tar_cmd, "-C", staging_path, compression ] + data_tar_flags + [ "-cf", datatar, "." ]
638
+ args = [ tar_cmd, "-C", staging_path ] + compression_flags + data_tar_flags + [ "-cf", datatar, "." ]
596
639
  if tar_cmd_supports_sort_names_and_set_mtime? and not attributes[:source_date_epoch].nil?
597
640
  # Use gnu tar options to force deterministic file order and timestamp
598
641
  args += ["--sort=name", ("--mtime=@%s" % attributes[:source_date_epoch])]
@@ -605,7 +648,7 @@ class FPM::Package::Deb < FPM::Package
605
648
  # the 'debian-binary' file has to be first
606
649
  File.expand_path(output_path).tap do |output_path|
607
650
  ::Dir.chdir(build_path) do
608
- safesystem(*ar_cmd, output_path, "debian-binary", "control.tar.gz", datatar)
651
+ safesystem(*ar_cmd, output_path, "debian-binary", controltar, datatar)
609
652
  end
610
653
  end
611
654
 
@@ -642,6 +685,43 @@ class FPM::Package::Deb < FPM::Package
642
685
  fix_provides(provides)
643
686
  end.flatten
644
687
 
688
+ if origin == FPM::Package::CPAN
689
+ # The fpm cpan code presents dependencies and provides fields as perl(ModuleName)
690
+ # so we'll need to convert them to something debian supports.
691
+
692
+ # Replace perl(ModuleName) > 1.0 with Debian-style perl-ModuleName (> 1.0)
693
+ perldepfix = lambda do |dep|
694
+ m = dep.match(/perl\((?<name>[A-Za-z0-9_:]+)\)\s*(?<op>.*$)/)
695
+ if m.nil?
696
+ # 'dep' syntax didn't look like 'perl(Name) > 1.0'
697
+ dep
698
+ else
699
+ # Also replace '::' in the perl module name with '-'
700
+ modulename = m["name"].gsub("::", "-")
701
+
702
+ # Fix any upper-casing or other naming concerns Debian has about packages
703
+ name = "#{attributes[:cpan_package_name_prefix]}-#{modulename}"
704
+
705
+ if m["op"].empty?
706
+ name
707
+ else
708
+ # 'dep' syntax was like this (version constraint): perl(Module) > 1.0
709
+ "#{name} (#{m["op"]})"
710
+ end
711
+ end
712
+ end
713
+
714
+ rejects = [ "perl(vars)", "perl(warnings)", "perl(strict)", "perl(Config)" ]
715
+ self.dependencies = self.dependencies.reject do |dep|
716
+ # Reject non-module Perl dependencies like 'vars' and 'warnings'
717
+ rejects.include?(dep)
718
+ end.collect(&perldepfix).collect(&method(:fix_dependency))
719
+
720
+ # Also fix the Provides field 'perl(ModuleName) = version' to be 'perl-modulename (= version)'
721
+ self.provides = self.provides.collect(&perldepfix).collect(&method(:fix_provides))
722
+
723
+ end # if origin == FPM::Packagin::CPAN
724
+
645
725
  if origin == FPM::Package::Deb
646
726
  changelog_path = staging_path("usr/share/doc/#{name}/changelog.Debian.gz")
647
727
  if File.exists?(changelog_path)
@@ -669,6 +749,19 @@ class FPM::Package::Deb < FPM::Package
669
749
  File.unlink(changelog_path)
670
750
  end
671
751
  end
752
+
753
+ if origin == FPM::Package::Gem
754
+ # fpm's gem input will have provides as "rubygem-name = version"
755
+ # and we need to convert this to Debian-style "rubygem-name (= version)"
756
+ self.provides = self.provides.collect do |provides|
757
+ m = /^(#{attributes[:gem_package_name_prefix]})-([^\s]+)\s*=\s*(.*)$/.match(provides)
758
+ if m
759
+ "#{m[1]}-#{m[2]} (= #{m[3]})"
760
+ else
761
+ provides
762
+ end
763
+ end
764
+ end
672
765
  end # def converted_from
673
766
 
674
767
  def debianize_op(op)
@@ -710,8 +803,13 @@ class FPM::Package::Deb < FPM::Package
710
803
  name, version = dep.gsub(/[()~>]/, "").split(/ +/)[0..1]
711
804
  nextversion = version.split(".").collect { |v| v.to_i }
712
805
  l = nextversion.length
713
- nextversion[l-2] += 1
714
- nextversion[l-1] = 0
806
+ if l > 1
807
+ nextversion[l-2] += 1
808
+ nextversion[l-1] = 0
809
+ else
810
+ # Single component versions ~> 1
811
+ nextversion[l-1] += 1
812
+ end
715
813
  nextversion = nextversion.join(".")
716
814
  return ["#{name} (>= #{version})", "#{name} (<< #{nextversion})"]
717
815
  elsif (m = dep.match(/(\S+)\s+\(!= (.+)\)/))
@@ -738,6 +836,32 @@ class FPM::Package::Deb < FPM::Package
738
836
  end
739
837
  end # def fix_dependency
740
838
 
839
+ def valid_provides_field?(text)
840
+ m = RELATIONSHIP_FIELD_PATTERN.match(text)
841
+ if m.nil?
842
+ logger.error("Invalid relationship field for debian package: #{text}")
843
+ return false
844
+ end
845
+
846
+ # Per Debian Policy manual, https://www.debian.org/doc/debian-policy/ch-relationships.html#syntax-of-relationship-fields
847
+ # >> The relations allowed are <<, <=, =, >= and >> for strictly earlier, earlier or equal,
848
+ # >> exactly equal, later or equal and strictly later, respectively. The exception is the
849
+ # >> Provides field, for which only = is allowed
850
+ if m["relation"] == "=" || m["relation"] == nil
851
+ return true
852
+ end
853
+ return false
854
+ end
855
+
856
+ def valid_relationship_field?(text)
857
+ m = RELATIONSHIP_FIELD_PATTERN.match(text)
858
+ if m.nil?
859
+ logger.error("Invalid relationship field for debian package: #{text}")
860
+ return false
861
+ end
862
+ return true
863
+ end
864
+
741
865
  def fix_provides(provides)
742
866
  name_re = /^[^ \(]+/
743
867
  name = provides[name_re]
@@ -752,6 +876,11 @@ class FPM::Package::Deb < FPM::Package
752
876
  "debs don't like underscores")
753
877
  provides = provides.gsub("_", "-")
754
878
  end
879
+
880
+ if m = provides.match(/^([A-Za-z0-9_-]+)\s*=\s*(\d+.*$)/)
881
+ logger.warn("Replacing 'provides' entry #{provides} with syntax 'name (= version)'")
882
+ provides = "#{m[1]} (= #{m[2]})"
883
+ end
755
884
  return provides.rstrip
756
885
  end
757
886
 
@@ -779,28 +908,25 @@ class FPM::Package::Deb < FPM::Package
779
908
 
780
909
  # Tar up the staging_path into control.tar.{compression type}
781
910
  case self.attributes[:deb_compression]
782
- when "gz", nil
783
- controltar = build_path("control.tar.gz")
784
- compression = "-z"
785
- when "bzip2"
786
- controltar = build_path("control.tar.bz2")
787
- compression = "-j"
911
+ when "gz", "bzip2", nil
912
+ controltar = "control.tar.gz"
913
+ compression_flags = ["-z"]
788
914
  when "xz"
789
- controltar = build_path("control.tar.xz")
790
- compression = "-J"
915
+ controltar = "control.tar.xz"
916
+ compression_flags = ["-J"]
791
917
  when "none"
792
- controltar = build_path("control.tar")
793
- compression = ""
918
+ controltar = "control.tar"
919
+ compression_flags = []
794
920
  else
795
921
  raise FPM::InvalidPackageConfiguration,
796
922
  "Unknown compression type '#{self.attributes[:deb_compression]}'"
797
923
  end
798
924
 
799
925
  # Make the control.tar.gz
800
- build_path("control.tar.gz").tap do |controltar|
926
+ build_path(controltar).tap do |controltar|
801
927
  logger.info("Creating", :path => controltar, :from => control_path)
802
928
 
803
- args = [ tar_cmd, "-C", control_path, compression, "-cf", controltar,
929
+ args = [ tar_cmd, "-C", control_path ] + compression_flags + [ "-cf", controltar,
804
930
  "--owner=0", "--group=0", "--numeric-owner", "." ]
805
931
  if tar_cmd_supports_sort_names_and_set_mtime? and not attributes[:source_date_epoch].nil?
806
932
  # Force deterministic file order and timestamp
@@ -889,7 +1015,7 @@ class FPM::Package::Deb < FPM::Package
889
1015
  etcfiles = []
890
1016
  # Add everything in /etc
891
1017
  begin
892
- if !attributes[:deb_no_default_config_files?]
1018
+ if !attributes[:deb_no_default_config_files?] && File.exists?(staging_path("/etc"))
893
1019
  logger.warn("Debian packaging tools generally labels all files in /etc as config files, " \
894
1020
  "as mandated by policy, so fpm defaults to this behavior for deb packages. " \
895
1021
  "You can disable this default behavior with --deb-no-default-config-files flag")