fpm 1.13.0 → 1.15.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.rst +67 -7
- data/CONTRIBUTORS +1 -0
- data/LICENSE +1 -1
- data/lib/fpm/command.rb +93 -3
- data/lib/fpm/package/cpan.rb +2 -1
- data/lib/fpm/package/deb.rb +148 -22
- data/lib/fpm/package/dir.rb +1 -1
- data/lib/fpm/package/empty.rb +12 -0
- data/lib/fpm/package/freebsd.rb +1 -3
- data/lib/fpm/package/gem.rb +18 -9
- data/lib/fpm/package/osxpkg.rb +6 -1
- data/lib/fpm/package/pacman.rb +1 -1
- data/lib/fpm/package/pleaserun.rb +1 -0
- data/lib/fpm/package/puppet.rb +1 -1
- data/lib/fpm/package/pyfpm/get_metadata.py +6 -0
- data/lib/fpm/package/python.rb +40 -18
- data/lib/fpm/package/rpm.rb +28 -10
- data/lib/fpm/package/virtualenv.rb +2 -0
- data/lib/fpm/package.rb +3 -2
- data/lib/fpm/util.rb +32 -2
- data/lib/fpm/version.rb +1 -1
- data/templates/deb/changelog.erb +1 -1
- data/templates/deb/deb.changes.erb +1 -1
- data/templates/deb.erb +1 -1
- metadata +17 -57
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d2157b42ae94755f7521964dc3f92af2a535ee87506303aca5bb72222b48495b
|
4
|
+
data.tar.gz: 8772b7c1f612dfe8bd698b136418bda8c7b63d9243b1b253832917ad926cab7c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9cee7c2885fcf85d75cdc74b2e41399ddce10693fefc3c0b09c49e73b16fcd73140527d646ee5886ef231de7cb202a67f22130d01324d83923195833693f00e2
|
7
|
+
data.tar.gz: 18f5d405ecd21a0309abf1e08219b0b23aa60eb2e8e7e3f00d7c17ea31e5a3e7b4cbf3a9b9e5bbfb467111a4b8ea9424d61a0f0ff81c9179490e54b17cbfde29
|
data/CHANGELOG.rst
CHANGED
@@ -1,6 +1,67 @@
|
|
1
1
|
Release Notes and Change Log
|
2
2
|
============================
|
3
3
|
|
4
|
+
1.15.1 (January 31, 2023)
|
5
|
+
^^^^^^^^^^^^^^^^^^^^^^^^^
|
6
|
+
* Ruby 3.2.0 now supported. This fixes error 'undefined method exists? for File' '(`#1981`_, `#1988`_; Nicholas Hubbard, romulasry)
|
7
|
+
|
8
|
+
1.15.0 (November 13, 2022)
|
9
|
+
^^^^^^^^^^^^^^^^^^^^^^^^^^
|
10
|
+
* 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)
|
11
|
+
* deb: Periods are now accepted in package names (`#1899`_; C. Cooke)
|
12
|
+
* Fix bug where fpm would crash if ``--workdir`` pointed at a path that didn't
|
13
|
+
exist. (`#1959`_; Jordan Sissel)
|
14
|
+
* osxpkg: this package format now supports the fpm ``--prefix`` flag(`#1909`_, `#1908`_; Jordan Sissel, mcataga)
|
15
|
+
* cpan: Fix bug where fpm would fail on certain Perl modules due to their source tarball structure (`#1940`_; Nicholas Hubbard, William N. Braswell, Jr.)
|
16
|
+
* cpan: Fix crash on certain CPAN modules where the author field was blank (`#1942`_, `#1937`_, `#1523`_, `#1528`_; Nicholas Hubbard, William N. Braswell, Jr.)
|
17
|
+
* 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)
|
18
|
+
* 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)
|
19
|
+
* pleaserun: Add ``--pleaserun-user`` flag. (`#1912`_; Evgeny Stambulchik)
|
20
|
+
* deb: The default ``--deb-priority`` is now "optional" instead of "extra" (`#1913`_; Chris Novakovic)
|
21
|
+
* 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)
|
22
|
+
* 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)
|
23
|
+
* Fix bug where subprocesses could hang waiting for input (`#1955`_, `#1519`_, `#1522`_; Nicholas Hubbard, William N. Braswell, Jr.)
|
24
|
+
* Update Dockerfile to use ubuntu:20.04 (`#1935`_; Gnought)
|
25
|
+
* internal: Fix a code typo (`#1948`_; Nicholas Hubbard)
|
26
|
+
* internal tests: Support newer versions of lintian (`#1939`_, `#1907`_; Jordan Sissel)
|
27
|
+
* 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)
|
28
|
+
* Improve support for Ruby 3.1.0 and newer that changed the API for ERB (`#1897`_; Jordan Sissel)
|
29
|
+
|
30
|
+
1.14.2 (March 30, 2022)
|
31
|
+
^^^^^^^^^^^^^^^^^^^^^^^
|
32
|
+
* deb: fix bug causing ``--deb-compression none`` to invoke ``tar`` incorrectly (`#1879`_; John Howard)
|
33
|
+
* rpm: Better support for paths that have spaces and mixed quotation marks in them. (`#1882`_, `#1886`_, `#1385`_; John Bollinger and Jordan Sissel)
|
34
|
+
* pacman: Fix typo preventing the use of ``--pacman-compression xz`` (`#1876`_; mszprejda)
|
35
|
+
* 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)
|
36
|
+
* docs: Small but lovely documentation fixes (`#1875`_ by Corey Quinn, `#1864`_ by Geoff Beier)
|
37
|
+
* Fixed mistake causing the test suite to fail when ``rake`` wasn't available. (`#1877`_; Jordan Sissel)
|
38
|
+
|
39
|
+
1.14.1 (November 10, 2021)
|
40
|
+
^^^^^^^^^^^^^^^^^^^^^^^^^^
|
41
|
+
* 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)
|
42
|
+
|
43
|
+
1.14.0 (November 9, 2021)
|
44
|
+
^^^^^^^^^^^^^^^^^^^^^^^^^
|
45
|
+
* 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)
|
46
|
+
* python: Support extras_require build markers in python packages (`#1307`_, `#1816`_; Joris Vandermeersch)
|
47
|
+
* 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)
|
48
|
+
* 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)
|
49
|
+
* deb: Only show a warning about /etc and config files if there are files in /etc (`#1852`_, `#1851`_; Jordan Sissel)
|
50
|
+
|
51
|
+
* rpm: replace dash with underscore in rpm's "Release" field aka what fpm calls ``--iteration``. (`#1834`_, `#1833`_; Jordan Sissel)
|
52
|
+
* empty: `fpm -s empty ...` now defaults to "all" architecture instead of "native". (`#1850`_, `#1846`_; Jordan Sissel)
|
53
|
+
* 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)
|
54
|
+
* Typo fixes in documentation are always appreciated! (`#1842`_; Clayton Wong)
|
55
|
+
* fpm can now (we hope!) now be tested more easily from docker (`#1818`_, `#1682`_, `#1453`_; @directionless, Jordan Sissel, Douglas Muth)
|
56
|
+
|
57
|
+
1.13.1 (July 6, 2021)
|
58
|
+
^^^^^^^^^^^^^^^^^^^^^
|
59
|
+
* deb: The `--provides` flag now allows for versions. Previously, fpm would
|
60
|
+
remove the version part of a provides field when generating deb packages.
|
61
|
+
(`#1788`_, `#1803`_; Jordan Sissel, Phil Schwartz, tympanix)
|
62
|
+
* osxpkg: Update documentation to include installing `rpm` tools on OSX
|
63
|
+
(`#1797`_; allen joslin)
|
64
|
+
|
4
65
|
1.13.0 (June 19, 2021)
|
5
66
|
^^^^^^^^^^^^^^^^^^^^^^
|
6
67
|
* Apple M1 users should now work (`#1772`_, `#1785`_, `#1786`_; Jordan Sissel)
|
@@ -12,8 +73,7 @@ Release Notes and Change Log
|
|
12
73
|
* 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)
|
13
74
|
* 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)
|
14
75
|
* deb: Fix syntax error in `postinst` (`--after-install`) script. (`#1752`_, `#1749`_, `#1764`_; rmanus, Adam Mohammed, Elliot Murphy, kimw, Jordan Sissel)
|
15
|
-
* deb: --deb-compression now uses the same compression and file suffix on the control.tar file (`#1760`_; Philippe Poilbarbe
|
16
|
-
)
|
76
|
+
* deb: --deb-compression now uses the same compression and file suffix on the control.tar file (`#1760`_; Philippe Poilbarbe)
|
17
77
|
|
18
78
|
|
19
79
|
1.12.0 (January 19, 2021)
|
@@ -51,7 +111,7 @@ Release Notes and Change Log
|
|
51
111
|
* cpan: Adds `--[no-]cpan-verbose` flag which, when set, runs `cpanm` with the `--verbose` flag (`#1511`_; William N. Braswell, Jr)
|
52
112
|
|
53
113
|
1.10.0 (May 21, 2018)
|
54
|
-
|
114
|
+
^^^^^^^^^^^^^^^^^^^^^
|
55
115
|
|
56
116
|
* Pin `ruby-xz` dependency to one which allows Ruby versions older than 2.3.0 (`#1494`_; Marat Sharafutdinov)
|
57
117
|
* Documentation improvements: `#1488`_; Arthur Burkart. `#1384`_; Justin Kolberg. `#1452`_; Anatoli Babenia.
|
@@ -79,7 +139,7 @@ Release Notes and Change Log
|
|
79
139
|
* rpm: Fix `--config-files` handling (`#1390`_, `#1391`_; Jordan Sissel)
|
80
140
|
|
81
141
|
1.9.1 (July 28, 2017) happy sysadmin day!
|
82
|
-
|
142
|
+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
83
143
|
|
84
144
|
* Documentation improvements: `#1291`_; Pablo Castellano. `#1321`_; ge-fa. `#1309`_; jesusbagpuss. `#1349`_; Perry Stole. `#1352`_, Jordan Sissel. `#1384`_; Justin Kolberg.
|
85
145
|
* Testing improvements: `#1320`_; Rob Young. `#1266`_; Ryan Parman. `#1374`_; Thiago Figueiró.
|
@@ -108,9 +168,9 @@ Release Notes and Change Log
|
|
108
168
|
* Other: Remove unused archive-tar-minitar as a dependency of fpm (`#1355`_; Diego Martins)
|
109
169
|
* Other: Add stud as a runtime dependency (`#1354`_; Elan Ruusamäe)
|
110
170
|
|
111
|
-
.. _reproducible_builds
|
112
|
-
.. _path mapping
|
113
|
-
.. _Deterministic output
|
171
|
+
.. _reproducible_builds: https://reproducible-builds.org/
|
172
|
+
.. _path mapping: source/dir.html#path-mapping
|
173
|
+
.. _Deterministic output: source/gem.html
|
114
174
|
|
115
175
|
1.9.0 (July 28, 2017)
|
116
176
|
^^^^^^^^^^^^^^^^^^^^^
|
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-
|
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.exist?(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
|
|
@@ -355,7 +371,7 @@ class FPM::Command < Clamp::Command
|
|
355
371
|
|
356
372
|
# If --inputs was specified, read it as a file.
|
357
373
|
if !inputs.nil?
|
358
|
-
if !File.
|
374
|
+
if !File.exist?(inputs)
|
359
375
|
logger.fatal("File given for --inputs does not exist (#{inputs})")
|
360
376
|
return 1
|
361
377
|
end
|
@@ -370,7 +386,7 @@ class FPM::Command < Clamp::Command
|
|
370
386
|
# If --exclude-file was specified, read it as a file and append to
|
371
387
|
# the exclude pattern list.
|
372
388
|
if !exclude_file.nil?
|
373
|
-
if !File.
|
389
|
+
if !File.exist?(exclude_file)
|
374
390
|
logger.fatal("File given for --exclude-file does not exist (#{exclude_file})")
|
375
391
|
return 1
|
376
392
|
end
|
@@ -435,7 +451,7 @@ class FPM::Command < Clamp::Command
|
|
435
451
|
# Skip scripts not set
|
436
452
|
next if path.nil?
|
437
453
|
|
438
|
-
if !File.
|
454
|
+
if !File.exist?(path)
|
439
455
|
logger.error("No such file (for #{scriptname.to_s}): #{path.inspect}")
|
440
456
|
script_errors << path
|
441
457
|
end
|
@@ -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
|
data/lib/fpm/package/cpan.rb
CHANGED
@@ -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
|
-
|
308
|
+
%q{--transform=s,[./]*[^/]*/,,} ]
|
308
309
|
safesystem("tar", *args)
|
309
310
|
return directory
|
310
311
|
end
|
data/lib/fpm/package/deb.rb
CHANGED
@@ -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,30 @@ 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
|
+
# 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
|
+
VERSION_FIELD_PATTERN = /
|
47
|
+
(?:(?:[0-9]+):)? # The epoch, an unsigned int
|
48
|
+
(?:[A-Za-z0-9+~.-]+) # upstream version, probably should not contain dashes?
|
49
|
+
(?:-[A-Za-z0-9+~.]+)? # debian_revision
|
50
|
+
/x # Version field pattern
|
51
|
+
RELATIONSHIP_FIELD_PATTERN = /^
|
52
|
+
(?<name>[A-z0-9][A-z0-9_.-]+)
|
53
|
+
(?:\s*\((?<relation>[<>=]+)\s(?<version>#{VERSION_FIELD_PATTERN})\))?
|
54
|
+
$/x # Relationship field pattern
|
55
|
+
|
28
56
|
option "--ignore-iteration-in-dependencies", :flag,
|
29
57
|
"For '=' (equal) dependencies, allow iterations on the specified " \
|
30
58
|
"version. Default is to be specific. This option allows the same " \
|
@@ -78,7 +106,7 @@ class FPM::Package::Deb < FPM::Package
|
|
78
106
|
end
|
79
107
|
|
80
108
|
option "--priority", "PRIORITY",
|
81
|
-
"The debian package 'priority' value.", :default => "
|
109
|
+
"The debian package 'priority' value.", :default => "optional"
|
82
110
|
|
83
111
|
option "--use-file-permissions", :flag,
|
84
112
|
"Use existing file permissions when defining ownership and modes"
|
@@ -201,7 +229,7 @@ class FPM::Package::Deb < FPM::Package
|
|
201
229
|
|
202
230
|
def initialize(*args)
|
203
231
|
super(*args)
|
204
|
-
attributes[:deb_priority] = "
|
232
|
+
attributes[:deb_priority] = "optional"
|
205
233
|
end # def initialize
|
206
234
|
|
207
235
|
private
|
@@ -272,6 +300,21 @@ class FPM::Package::Deb < FPM::Package
|
|
272
300
|
return (attributes[:prefix] or "/")
|
273
301
|
end # def prefix
|
274
302
|
|
303
|
+
def version
|
304
|
+
if @version.kind_of?(String)
|
305
|
+
if @version.start_with?("v") && @version.gsub(/^v/, "") =~ /^#{VERSION_FIELD_PATTERN}$/
|
306
|
+
logger.warn("Debian 'Version' field needs to start with a digit. I was provided '#{@version}' which seems like it just has a 'v' prefix to an otherwise-valid Debian version, I'll remove the 'v' for you.")
|
307
|
+
@version = @version.gsub(/^v/, "")
|
308
|
+
end
|
309
|
+
|
310
|
+
if @version !~ /^#{VERSION_FIELD_PATTERN}$/
|
311
|
+
raise FPM::InvalidPackageConfiguration, "The version looks invalid for Debian packages. Debian version field must contain only alphanumerics and . (period), + (plus), - (hyphen) or ~ (tilde). I have '#{@version}' which which isn't valid."
|
312
|
+
end
|
313
|
+
end
|
314
|
+
|
315
|
+
return @version
|
316
|
+
end
|
317
|
+
|
275
318
|
def input(input_path)
|
276
319
|
extract_info(input_path)
|
277
320
|
extract_files(input_path)
|
@@ -427,6 +470,12 @@ class FPM::Package::Deb < FPM::Package
|
|
427
470
|
|
428
471
|
def output(output_path)
|
429
472
|
self.provides = self.provides.collect { |p| fix_provides(p) }
|
473
|
+
|
474
|
+
self.provides.each do |provide|
|
475
|
+
if !valid_provides_field?(provide)
|
476
|
+
raise FPM::InvalidPackageConfiguration, "Found invalid Provides field values (#{provide.inspect}). This is not valid in a Debian package."
|
477
|
+
end
|
478
|
+
end
|
430
479
|
output_check(output_path)
|
431
480
|
# Abort if the target path already exists.
|
432
481
|
|
@@ -542,7 +591,7 @@ class FPM::Package::Deb < FPM::Package
|
|
542
591
|
end # No need to close, GzipWriter#close will close it.
|
543
592
|
end
|
544
593
|
|
545
|
-
if File.
|
594
|
+
if File.exist?(dest_changelog) and not File.exist?(dest_upstream_changelog)
|
546
595
|
# see https://www.debian.org/doc/debian-policy/ch-docs.html#s-changelogs
|
547
596
|
File.rename(dest_changelog, dest_upstream_changelog)
|
548
597
|
end
|
@@ -592,25 +641,24 @@ class FPM::Package::Deb < FPM::Package
|
|
592
641
|
when "gz", nil
|
593
642
|
datatar = build_path("data.tar.gz")
|
594
643
|
controltar = build_path("control.tar.gz")
|
595
|
-
|
644
|
+
compression_flags = ["-z"]
|
596
645
|
when "bzip2"
|
597
646
|
datatar = build_path("data.tar.bz2")
|
598
|
-
controltar = build_path("control.tar.
|
599
|
-
|
647
|
+
controltar = build_path("control.tar.gz")
|
648
|
+
compression_flags = ["-j"]
|
600
649
|
when "xz"
|
601
650
|
datatar = build_path("data.tar.xz")
|
602
651
|
controltar = build_path("control.tar.xz")
|
603
|
-
|
652
|
+
compression_flags = ["-J"]
|
604
653
|
when "none"
|
605
654
|
datatar = build_path("data.tar")
|
606
655
|
controltar = build_path("control.tar")
|
607
|
-
|
656
|
+
compression_flags = []
|
608
657
|
else
|
609
658
|
raise FPM::InvalidPackageConfiguration,
|
610
659
|
"Unknown compression type '#{self.attributes[:deb_compression]}'"
|
611
660
|
end
|
612
|
-
|
613
|
-
args = [ tar_cmd, "-C", staging_path, compression ] + data_tar_flags + [ "-cf", datatar, "." ]
|
661
|
+
args = [ tar_cmd, "-C", staging_path ] + compression_flags + data_tar_flags + [ "-cf", datatar, "." ]
|
614
662
|
if tar_cmd_supports_sort_names_and_set_mtime? and not attributes[:source_date_epoch].nil?
|
615
663
|
# Use gnu tar options to force deterministic file order and timestamp
|
616
664
|
args += ["--sort=name", ("--mtime=@%s" % attributes[:source_date_epoch])]
|
@@ -660,9 +708,46 @@ class FPM::Package::Deb < FPM::Package
|
|
660
708
|
fix_provides(provides)
|
661
709
|
end.flatten
|
662
710
|
|
711
|
+
if origin == FPM::Package::CPAN
|
712
|
+
# The fpm cpan code presents dependencies and provides fields as perl(ModuleName)
|
713
|
+
# so we'll need to convert them to something debian supports.
|
714
|
+
|
715
|
+
# Replace perl(ModuleName) > 1.0 with Debian-style perl-ModuleName (> 1.0)
|
716
|
+
perldepfix = lambda do |dep|
|
717
|
+
m = dep.match(/perl\((?<name>[A-Za-z0-9_:]+)\)\s*(?<op>.*$)/)
|
718
|
+
if m.nil?
|
719
|
+
# 'dep' syntax didn't look like 'perl(Name) > 1.0'
|
720
|
+
dep
|
721
|
+
else
|
722
|
+
# Also replace '::' in the perl module name with '-'
|
723
|
+
modulename = m["name"].gsub("::", "-")
|
724
|
+
|
725
|
+
# Fix any upper-casing or other naming concerns Debian has about packages
|
726
|
+
name = "#{attributes[:cpan_package_name_prefix]}-#{modulename}"
|
727
|
+
|
728
|
+
if m["op"].empty?
|
729
|
+
name
|
730
|
+
else
|
731
|
+
# 'dep' syntax was like this (version constraint): perl(Module) > 1.0
|
732
|
+
"#{name} (#{m["op"]})"
|
733
|
+
end
|
734
|
+
end
|
735
|
+
end
|
736
|
+
|
737
|
+
rejects = [ "perl(vars)", "perl(warnings)", "perl(strict)", "perl(Config)" ]
|
738
|
+
self.dependencies = self.dependencies.reject do |dep|
|
739
|
+
# Reject non-module Perl dependencies like 'vars' and 'warnings'
|
740
|
+
rejects.include?(dep)
|
741
|
+
end.collect(&perldepfix).collect(&method(:fix_dependency))
|
742
|
+
|
743
|
+
# Also fix the Provides field 'perl(ModuleName) = version' to be 'perl-modulename (= version)'
|
744
|
+
self.provides = self.provides.collect(&perldepfix).collect(&method(:fix_provides))
|
745
|
+
|
746
|
+
end # if origin == FPM::Packagin::CPAN
|
747
|
+
|
663
748
|
if origin == FPM::Package::Deb
|
664
749
|
changelog_path = staging_path("usr/share/doc/#{name}/changelog.Debian.gz")
|
665
|
-
if File.
|
750
|
+
if File.exist?(changelog_path)
|
666
751
|
logger.debug("Found a deb changelog file, using it.", :path => changelog_path)
|
667
752
|
attributes[:deb_changelog] = build_path("deb_changelog")
|
668
753
|
File.open(attributes[:deb_changelog], "w") do |deb_changelog|
|
@@ -676,7 +761,7 @@ class FPM::Package::Deb < FPM::Package
|
|
676
761
|
|
677
762
|
if origin == FPM::Package::Deb
|
678
763
|
changelog_path = staging_path("usr/share/doc/#{name}/changelog.gz")
|
679
|
-
if File.
|
764
|
+
if File.exist?(changelog_path)
|
680
765
|
logger.debug("Found an upstream changelog file, using it.", :path => changelog_path)
|
681
766
|
attributes[:deb_upstream_changelog] = build_path("deb_upstream_changelog")
|
682
767
|
File.open(attributes[:deb_upstream_changelog], "w") do |deb_upstream_changelog|
|
@@ -687,6 +772,19 @@ class FPM::Package::Deb < FPM::Package
|
|
687
772
|
File.unlink(changelog_path)
|
688
773
|
end
|
689
774
|
end
|
775
|
+
|
776
|
+
if origin == FPM::Package::Gem
|
777
|
+
# fpm's gem input will have provides as "rubygem-name = version"
|
778
|
+
# and we need to convert this to Debian-style "rubygem-name (= version)"
|
779
|
+
self.provides = self.provides.collect do |provides|
|
780
|
+
m = /^(#{attributes[:gem_package_name_prefix]})-([^\s]+)\s*=\s*(.*)$/.match(provides)
|
781
|
+
if m
|
782
|
+
"#{m[1]}-#{m[2]} (= #{m[3]})"
|
783
|
+
else
|
784
|
+
provides
|
785
|
+
end
|
786
|
+
end
|
787
|
+
end
|
690
788
|
end # def converted_from
|
691
789
|
|
692
790
|
def debianize_op(op)
|
@@ -761,6 +859,32 @@ class FPM::Package::Deb < FPM::Package
|
|
761
859
|
end
|
762
860
|
end # def fix_dependency
|
763
861
|
|
862
|
+
def valid_provides_field?(text)
|
863
|
+
m = RELATIONSHIP_FIELD_PATTERN.match(text)
|
864
|
+
if m.nil?
|
865
|
+
logger.error("Invalid relationship field for debian package: #{text}")
|
866
|
+
return false
|
867
|
+
end
|
868
|
+
|
869
|
+
# Per Debian Policy manual, https://www.debian.org/doc/debian-policy/ch-relationships.html#syntax-of-relationship-fields
|
870
|
+
# >> The relations allowed are <<, <=, =, >= and >> for strictly earlier, earlier or equal,
|
871
|
+
# >> exactly equal, later or equal and strictly later, respectively. The exception is the
|
872
|
+
# >> Provides field, for which only = is allowed
|
873
|
+
if m["relation"] == "=" || m["relation"] == nil
|
874
|
+
return true
|
875
|
+
end
|
876
|
+
return false
|
877
|
+
end
|
878
|
+
|
879
|
+
def valid_relationship_field?(text)
|
880
|
+
m = RELATIONSHIP_FIELD_PATTERN.match(text)
|
881
|
+
if m.nil?
|
882
|
+
logger.error("Invalid relationship field for debian package: #{text}")
|
883
|
+
return false
|
884
|
+
end
|
885
|
+
return true
|
886
|
+
end
|
887
|
+
|
764
888
|
def fix_provides(provides)
|
765
889
|
name_re = /^[^ \(]+/
|
766
890
|
name = provides[name_re]
|
@@ -775,6 +899,11 @@ class FPM::Package::Deb < FPM::Package
|
|
775
899
|
"debs don't like underscores")
|
776
900
|
provides = provides.gsub("_", "-")
|
777
901
|
end
|
902
|
+
|
903
|
+
if m = provides.match(/^([A-Za-z0-9_-]+)\s*=\s*(\d+.*$)/)
|
904
|
+
logger.warn("Replacing 'provides' entry #{provides} with syntax 'name (= version)'")
|
905
|
+
provides = "#{m[1]} (= #{m[2]})"
|
906
|
+
end
|
778
907
|
return provides.rstrip
|
779
908
|
end
|
780
909
|
|
@@ -802,18 +931,15 @@ class FPM::Package::Deb < FPM::Package
|
|
802
931
|
|
803
932
|
# Tar up the staging_path into control.tar.{compression type}
|
804
933
|
case self.attributes[:deb_compression]
|
805
|
-
when "gz", nil
|
934
|
+
when "gz", "bzip2", nil
|
806
935
|
controltar = "control.tar.gz"
|
807
|
-
|
808
|
-
when "bzip2"
|
809
|
-
controltar = "control.tar.bz2"
|
810
|
-
compression = "-j"
|
936
|
+
compression_flags = ["-z"]
|
811
937
|
when "xz"
|
812
938
|
controltar = "control.tar.xz"
|
813
|
-
|
939
|
+
compression_flags = ["-J"]
|
814
940
|
when "none"
|
815
941
|
controltar = "control.tar"
|
816
|
-
|
942
|
+
compression_flags = []
|
817
943
|
else
|
818
944
|
raise FPM::InvalidPackageConfiguration,
|
819
945
|
"Unknown compression type '#{self.attributes[:deb_compression]}'"
|
@@ -823,7 +949,7 @@ class FPM::Package::Deb < FPM::Package
|
|
823
949
|
build_path(controltar).tap do |controltar|
|
824
950
|
logger.info("Creating", :path => controltar, :from => control_path)
|
825
951
|
|
826
|
-
args = [ tar_cmd, "-C", control_path
|
952
|
+
args = [ tar_cmd, "-C", control_path ] + compression_flags + [ "-cf", controltar,
|
827
953
|
"--owner=0", "--group=0", "--numeric-owner", "." ]
|
828
954
|
if tar_cmd_supports_sort_names_and_set_mtime? and not attributes[:source_date_epoch].nil?
|
829
955
|
# Force deterministic file order and timestamp
|
@@ -912,7 +1038,7 @@ class FPM::Package::Deb < FPM::Package
|
|
912
1038
|
etcfiles = []
|
913
1039
|
# Add everything in /etc
|
914
1040
|
begin
|
915
|
-
if !attributes[:deb_no_default_config_files?]
|
1041
|
+
if !attributes[:deb_no_default_config_files?] && File.exist?(staging_path("/etc"))
|
916
1042
|
logger.warn("Debian packaging tools generally labels all files in /etc as config files, " \
|
917
1043
|
"as mandated by policy, so fpm defaults to this behavior for deb packages. " \
|
918
1044
|
"You can disable this default behavior with --deb-no-default-config-files flag")
|
@@ -1086,5 +1212,5 @@ class FPM::Package::Deb < FPM::Package
|
|
1086
1212
|
return data_tar_flags
|
1087
1213
|
end # def data_tar_flags
|
1088
1214
|
|
1089
|
-
public(:input, :output, :architecture, :name, :prefix, :converted_from, :to_s, :data_tar_flags)
|
1215
|
+
public(:input, :output, :architecture, :name, :prefix, :version, :converted_from, :to_s, :data_tar_flags)
|
1090
1216
|
end # class FPM::Target::Deb
|
data/lib/fpm/package/dir.rb
CHANGED
@@ -43,7 +43,7 @@ class FPM::Package::Dir < FPM::Package
|
|
43
43
|
# This mapping should work the same way 'rsync -a' does
|
44
44
|
# Meaning 'rsync -a source dest'
|
45
45
|
# and 'source=dest' in fpm work the same as the above rsync
|
46
|
-
if path =~ /.=./ && !File.
|
46
|
+
if path =~ /.=./ && !File.exist?(chdir == '.' ? path : File.join(chdir, path))
|
47
47
|
origin, destination = path.split("=", 2)
|
48
48
|
|
49
49
|
if File.directory?(origin) && origin[-1,1] == "/"
|
data/lib/fpm/package/empty.rb
CHANGED
@@ -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
|
data/lib/fpm/package/freebsd.rb
CHANGED
@@ -86,9 +86,7 @@ class FPM::Package::FreeBSD < FPM::Package
|
|
86
86
|
# We use --files-from here to keep the tar entries from having `./` as the prefix.
|
87
87
|
# This is done as a best effor to mimic what FreeBSD packages do, having everything at the top-level as
|
88
88
|
# file names, like "+MANIFEST" instead of "./+MANIFEST"
|
89
|
-
|
90
|
-
# a leading slash. I don't know if this has any negative impact on freebsd packages.
|
91
|
-
safesystem("tar", "-Jcf", output_path, "-C", staging_path, "--files-from", build_path("file_list"))
|
89
|
+
safesystem("tar", "-Jcf", output_path, "-C", staging_path, "--files-from", build_path("file_list"), "--transform", 's|^\([^+]\)|/\1|')
|
92
90
|
end # def output
|
93
91
|
|
94
92
|
# Handle architecture naming conversion:
|
data/lib/fpm/package/gem.rb
CHANGED
@@ -104,19 +104,18 @@ class FPM::Package::Gem < FPM::Package
|
|
104
104
|
FileUtils.mkdir(download_dir) unless File.directory?(download_dir)
|
105
105
|
|
106
106
|
if attributes[:gem_git_repo]
|
107
|
-
require "git"
|
108
107
|
logger.debug("Git cloning in directory #{download_dir}")
|
109
|
-
|
108
|
+
safesystem("git", "-C", download_dir, "clone", attributes[:gem_git_repo], ".")
|
110
109
|
if attributes[:gem_git_branch]
|
111
|
-
|
112
|
-
g.pull('origin',attributes[:gem_git_branch])
|
110
|
+
safesystem("git", "-C", download_dir, "checkout", attributes[:gem_git_branch])
|
113
111
|
end
|
114
|
-
|
115
|
-
|
112
|
+
|
113
|
+
gem_build = [ "#{attributes[:gem_gem]}", "build", "#{download_dir}/#{gem_name}.gemspec"]
|
114
|
+
::Dir.chdir(download_dir) do |dir|
|
116
115
|
logger.debug("Building in directory #{dir}")
|
117
116
|
safesystem(*gem_build)
|
118
117
|
end
|
119
|
-
gem_files = ::Dir.glob(File.join(
|
118
|
+
gem_files = ::Dir.glob(File.join(download_dir, "*.gem"))
|
120
119
|
else
|
121
120
|
gem_fetch = [ "#{attributes[:gem_gem]}", "fetch", gem_name]
|
122
121
|
gem_fetch += ["--prerelease"] if attributes[:gem_prerelease?]
|
@@ -135,9 +134,19 @@ class FPM::Package::Gem < FPM::Package
|
|
135
134
|
return gem_files.first
|
136
135
|
end # def download
|
137
136
|
|
137
|
+
GEMSPEC_YAML_CLASSES = [ ::Gem::Specification, ::Gem::Version, Time, ::Gem::Dependency, ::Gem::Requirement, Symbol ]
|
138
138
|
def load_package_info(gem_path)
|
139
|
-
|
140
|
-
|
139
|
+
# TODO(sissel): Maybe we should check if `safe_load` method exists instead of this version check?
|
140
|
+
if ::Gem::Version.new(RUBY_VERSION) >= ::Gem::Version.new("3.1.0")
|
141
|
+
# Ruby 3.1.0 switched to a Psych/YAML version that defaults to "safe" loading
|
142
|
+
# and unfortunately `gem specification --yaml` emits YAML that requires
|
143
|
+
# class loaders to process correctly
|
144
|
+
spec = YAML.load(%x{#{attributes[:gem_gem]} specification #{gem_path} --yaml},
|
145
|
+
:permitted_classes => GEMSPEC_YAML_CLASSES)
|
146
|
+
else
|
147
|
+
# Older versions of ruby call this method YAML.safe_load
|
148
|
+
spec = YAML.safe_load(%x{#{attributes[:gem_gem]} specification #{gem_path} --yaml}, GEMSPEC_YAML_CLASSES)
|
149
|
+
end
|
141
150
|
|
142
151
|
if !attributes[:gem_package_prefix].nil?
|
143
152
|
attributes[:gem_package_name_prefix] = attributes[:gem_package_prefix]
|
data/lib/fpm/package/osxpkg.rb
CHANGED
@@ -4,7 +4,6 @@ require "fileutils"
|
|
4
4
|
require "fpm/package/dir"
|
5
5
|
require 'tempfile' # stdlib
|
6
6
|
require 'pathname' # stdlib
|
7
|
-
require 'rexml/document' # stdlib
|
8
7
|
|
9
8
|
# Use an OS X pkg built with pkgbuild.
|
10
9
|
#
|
@@ -103,6 +102,7 @@ class FPM::Package::OSXpkg < FPM::Package
|
|
103
102
|
|
104
103
|
# Extract name and version from PackageInfo XML
|
105
104
|
def extract_info(package)
|
105
|
+
require 'rexml/document'
|
106
106
|
build_path("expand").tap do |path|
|
107
107
|
doc = REXML::Document.new File.open(File.join(path, "PackageInfo"))
|
108
108
|
pkginfo_elem = doc.elements["pkg-info"]
|
@@ -148,6 +148,11 @@ class FPM::Package::OSXpkg < FPM::Package
|
|
148
148
|
write_scripts
|
149
149
|
args += ["--scripts", scripts_path]
|
150
150
|
end
|
151
|
+
|
152
|
+
if attributes[:prefix]
|
153
|
+
args += ["--install-location", attributes[:prefix]]
|
154
|
+
end
|
155
|
+
|
151
156
|
args << output_path
|
152
157
|
|
153
158
|
safesystem("pkgbuild", *args)
|
data/lib/fpm/package/pacman.rb
CHANGED
@@ -18,6 +18,7 @@ class FPM::Package::PleaseRun < FPM::Package
|
|
18
18
|
|
19
19
|
option "--name", "SERVICE_NAME", "The name of the service you are creating"
|
20
20
|
option "--chdir", "CHDIR", "The working directory used by the service"
|
21
|
+
option "--user", "USER", "The user to use for executing this program."
|
21
22
|
|
22
23
|
private
|
23
24
|
def input(command)
|
data/lib/fpm/package/puppet.rb
CHANGED
@@ -60,7 +60,7 @@ class FPM::Package::Puppet < FPM::Package
|
|
60
60
|
end # case name
|
61
61
|
end # self.scripts.each
|
62
62
|
|
63
|
-
if File.
|
63
|
+
if File.exist?(params[:output])
|
64
64
|
# TODO(sissel): Allow folks to choose output?
|
65
65
|
logger.error("Puppet module directory '#{params[:output]}' already " \
|
66
66
|
"exists. Delete it or choose another output (-p flag)")
|
@@ -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
|
|
@@ -107,3 +112,4 @@ class get_metadata(Command):
|
|
107
112
|
else:
|
108
113
|
# For Python 2.5 and Debian's python-json
|
109
114
|
output.write(json.write(data))
|
115
|
+
output.close()
|
data/lib/fpm/package/python.rb
CHANGED
@@ -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[:
|
134
|
-
#
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
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
|
-
"
|
153
|
+
"--no-binary", ":all:",
|
154
|
+
"-d", build_path,
|
150
155
|
"-i", attributes[:python_pypi],
|
151
156
|
]
|
152
157
|
|
@@ -157,13 +162,28 @@ class FPM::Package::Python < FPM::Package
|
|
157
162
|
]
|
158
163
|
end
|
159
164
|
|
160
|
-
setup_cmd
|
161
|
-
|
162
|
-
target,
|
163
|
-
want_pkg,
|
164
|
-
]
|
165
|
-
|
165
|
+
setup_cmd << want_pkg
|
166
|
+
|
166
167
|
safesystem(*setup_cmd)
|
168
|
+
|
169
|
+
# Pip removed the --build flag sometime in 2021, it seems: https://github.com/pypa/pip/issues/8333
|
170
|
+
# A workaround for pip removing the `--build` flag. Previously, `pip download --build ...` would leave
|
171
|
+
# behind a directory with the Python package extracted and ready to be used.
|
172
|
+
# For example, `pip download ... Django` puts `Django-4.0.4.tar.tz` into the build_path directory.
|
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"))
|
176
|
+
if files.length != 1
|
177
|
+
raise "Unexpected directory layout after `pip download ...`. This might be an fpm bug? The directory is #{build_path}"
|
178
|
+
end
|
179
|
+
|
180
|
+
safesystem("tar", "-zxf", files[0], "-C", target)
|
181
|
+
else
|
182
|
+
# no pip, use easy_install
|
183
|
+
logger.debug("no pip, defaulting to easy_install", :easy_install => attributes[:python_easyinstall])
|
184
|
+
safesystem(attributes[:python_easyinstall], "-i",
|
185
|
+
attributes[:python_pypi], "--editable", "-U",
|
186
|
+
"--build-directory", target, want_pkg)
|
167
187
|
end
|
168
188
|
|
169
189
|
# easy_install will put stuff in @tmpdir/packagename/, so find that:
|
@@ -239,7 +259,9 @@ class FPM::Package::Python < FPM::Package
|
|
239
259
|
self.description = metadata["description"]
|
240
260
|
# Sometimes the license field is multiple lines; do best-effort and just
|
241
261
|
# use the first line.
|
242
|
-
|
262
|
+
if metadata["license"]
|
263
|
+
self.license = metadata["license"].split(/[\r\n]+/).first
|
264
|
+
end
|
243
265
|
self.version = metadata["version"]
|
244
266
|
self.url = metadata["url"]
|
245
267
|
|
data/lib/fpm/package/rpm.rb
CHANGED
@@ -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.
|
@@ -189,17 +192,26 @@ class FPM::Package::RPM < FPM::Package
|
|
189
192
|
# Replace * with [*] to make rpm not use globs
|
190
193
|
# Replace ? with [?] to make rpm not use globs
|
191
194
|
# Replace % with [%] to make rpm not expand macros
|
195
|
+
# Replace whitespace with ? to make rpm not split the filename
|
196
|
+
# If and only if any of the above are done, then also replace ' with \', " with \", and \ with \\\\
|
197
|
+
# to accommodate escape and quote processing that rpm will perform in that case (but not otherwise)
|
192
198
|
def rpm_fix_name(name)
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
199
|
+
if name.match?(/[ \t*?%$\[\]]/)
|
200
|
+
name = name.gsub(/(\ |\t|\[|\]|\*|\?|\%|\$|'|"|\\)/, {
|
201
|
+
' ' => '?',
|
202
|
+
"\t" => '?',
|
203
|
+
'%' => '[%]',
|
204
|
+
'$' => '[$]',
|
205
|
+
'?' => '[?]',
|
206
|
+
'*' => '[*]',
|
207
|
+
'[' => '[\[]',
|
208
|
+
']' => '[\]]',
|
209
|
+
'"' => '\\"',
|
210
|
+
"'" => "\\'",
|
211
|
+
'\\' => '\\\\\\\\',
|
212
|
+
})
|
213
|
+
end
|
214
|
+
name
|
203
215
|
end
|
204
216
|
|
205
217
|
def rpm_file_entry(file)
|
@@ -254,6 +266,12 @@ class FPM::Package::RPM < FPM::Package
|
|
254
266
|
|
255
267
|
# This method ensures a default value for iteration if none is provided.
|
256
268
|
def iteration
|
269
|
+
if @iteration.kind_of?(String) and @iteration.include?("-")
|
270
|
+
logger.warn("Package iteration '#{@iteration}' includes dashes, converting" \
|
271
|
+
" to underscores. rpmbuild does not allow the dashes in the package iteration (called 'Release' in rpm)")
|
272
|
+
@iteration = @iteration.gsub(/-/, "_")
|
273
|
+
end
|
274
|
+
|
257
275
|
return @iteration ? @iteration : 1
|
258
276
|
end # def iteration
|
259
277
|
|
data/lib/fpm/package.rb
CHANGED
@@ -331,11 +331,12 @@ class FPM::Package
|
|
331
331
|
template_path = File.join(template_dir, path)
|
332
332
|
template_code = File.read(template_path)
|
333
333
|
logger.info("Reading template", :path => template_path)
|
334
|
-
erb =
|
334
|
+
erb = erbnew(template_code)
|
335
335
|
erb.filename = template_path
|
336
336
|
return erb
|
337
337
|
end # def template
|
338
338
|
|
339
|
+
|
339
340
|
#######################################
|
340
341
|
# The following methods are provided to
|
341
342
|
# easily override particular substitut-
|
@@ -518,7 +519,7 @@ class FPM::Package
|
|
518
519
|
# flag), then apply it as an ERB template.
|
519
520
|
def script(script_name)
|
520
521
|
if attributes[:template_scripts?]
|
521
|
-
erb =
|
522
|
+
erb = erbnew(scripts[script_name])
|
522
523
|
# TODO(sissel): find the original file name for the file.
|
523
524
|
erb.filename = "script(#{script_name})"
|
524
525
|
return erb.result(binding)
|
data/lib/fpm/util.rb
CHANGED
@@ -154,10 +154,13 @@ module FPM::Util
|
|
154
154
|
|
155
155
|
yield(*args3)
|
156
156
|
|
157
|
-
|
157
|
+
stdin_w.close if opts[:stdin] and not stdin_w.closed?
|
158
158
|
stdout_r.close unless stdout_r.closed?
|
159
159
|
stderr_r.close unless stderr_r.closed?
|
160
160
|
else
|
161
|
+
# If no block given (not interactive) we should close stdin_w because we
|
162
|
+
# won't be able to give input which may cause a hang.
|
163
|
+
stdin_w.close
|
161
164
|
# Log both stdout and stderr as 'info' because nobody uses stderr for
|
162
165
|
# actually reporting errors and as a result 'stderr' is a misnomer.
|
163
166
|
logger.pipe(stdout_r => :info, stderr_r => :info)
|
@@ -342,7 +345,7 @@ module FPM::Util
|
|
342
345
|
when 'characterSpecial', 'blockSpecial'
|
343
346
|
raise UnsupportedSpecialFile.new("File is device which fpm doesn't know how to copy (#{File.ftype(src)}): #{src}")
|
344
347
|
when 'directory'
|
345
|
-
FileUtils.mkdir(dst) unless File.
|
348
|
+
FileUtils.mkdir(dst) unless File.exist? dst
|
346
349
|
else
|
347
350
|
# if the file with the same dev and inode has been copied already -
|
348
351
|
# hard link it's copy to `dst`, otherwise make an actual copy
|
@@ -406,6 +409,33 @@ module FPM::Util
|
|
406
409
|
def logger
|
407
410
|
@logger ||= Cabin::Channel.get
|
408
411
|
end # def logger
|
412
|
+
|
413
|
+
def erbnew(template_code)
|
414
|
+
# In Ruby 2.6(?), Ruby changed how ERB::new is invoked.
|
415
|
+
# First, it added keyword args like `ERB.new(..., trim_mode: "-")`
|
416
|
+
# Later, it deprecated then removed the safe_level feature.
|
417
|
+
# As of Ruby 3.1, warnings are printed at runtime when ERB.new is called with the old syntax.
|
418
|
+
# Ruby 2.5 and older does not support the ERB.new keyword args.
|
419
|
+
#
|
420
|
+
# My tests showed:
|
421
|
+
# * Ruby 2.3.0 through 3.0 work correctly with the old syntax.
|
422
|
+
# * Ruby 3.1.0 and newer (at time of writing, Ruby 3.2) require the new syntax
|
423
|
+
# Therefore, in order to support the most versions of ruby, we need to do a version check
|
424
|
+
# to invoke ERB.new correctly and without printed warnings.
|
425
|
+
# References: https://github.com/jordansissel/fpm/issues/1894
|
426
|
+
# Honestly, I'm not sure if Gem::Version is correct to use in this situation, but it works.
|
427
|
+
|
428
|
+
# on older versions of Ruby, RUBY_VERSION is a frozen string, and
|
429
|
+
# Gem::Version.new calls String#strip! which throws an exception.
|
430
|
+
# so we have to call String#dup to get an unfrozen copy.
|
431
|
+
if Gem::Version.new(RUBY_VERSION.dup) < Gem::Version.new("3.1.0")
|
432
|
+
# Ruby 3.0.x and older
|
433
|
+
return ERB.new(template_code, nil, "-")
|
434
|
+
else
|
435
|
+
# Ruby 3.1.0 and newer
|
436
|
+
return ERB.new(template_code, trim_mode: "-")
|
437
|
+
end
|
438
|
+
end
|
409
439
|
end # module FPM::Util
|
410
440
|
|
411
441
|
require 'fpm/util/tar_writer'
|
data/lib/fpm/version.rb
CHANGED
data/templates/deb/changelog.erb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
<%= name %> (<%= "#{epoch}:" if epoch %><%= version %><%= "-" + iteration.to_s if iteration %>)
|
1
|
+
<%= name %> (<%= "#{epoch}:" if epoch %><%= version %><%= "-" + iteration.to_s if iteration %>) <%= distribution %>; urgency=medium
|
2
2
|
|
3
3
|
* Package created with FPM.
|
4
4
|
|
@@ -14,7 +14,7 @@ Description: <%= firstline %>
|
|
14
14
|
<%= remainder.collect { |l| l =~ /^ *$/ ? " ." : " #{l}" }.join("\n") %>
|
15
15
|
<% end -%>
|
16
16
|
Changes:
|
17
|
-
<%= name %> (<%= "#{epoch}:" if epoch %><%= version %><%= "-" + iteration.to_s if iteration %>)
|
17
|
+
<%= name %> (<%= "#{epoch}:" if epoch %><%= version %><%= "-" + iteration.to_s if iteration %>) <%= distribution %>; urgency=medium
|
18
18
|
* Package created with FPM.
|
19
19
|
Checksums-Sha1:
|
20
20
|
<% changes_files.each do |file| -%>
|
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.
|
28
|
+
Provides: <%= provides.join ", " %>
|
29
29
|
<% end -%>
|
30
30
|
<% if !replaces.empty? -%>
|
31
31
|
Replaces: <%= replaces.collect { |d| fix_dependency(d) }.flatten.join(", ") %>
|
metadata
CHANGED
@@ -1,35 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fpm
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.15.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jordan Sissel
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2023-02-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
-
- !ruby/object:Gem::Dependency
|
14
|
-
name: json
|
15
|
-
requirement: !ruby/object:Gem::Requirement
|
16
|
-
requirements:
|
17
|
-
- - ">="
|
18
|
-
- !ruby/object:Gem::Version
|
19
|
-
version: 1.7.7
|
20
|
-
- - "<"
|
21
|
-
- !ruby/object:Gem::Version
|
22
|
-
version: '3.0'
|
23
|
-
type: :runtime
|
24
|
-
prerelease: false
|
25
|
-
version_requirements: !ruby/object:Gem::Requirement
|
26
|
-
requirements:
|
27
|
-
- - ">="
|
28
|
-
- !ruby/object:Gem::Version
|
29
|
-
version: 1.7.7
|
30
|
-
- - "<"
|
31
|
-
- !ruby/object:Gem::Version
|
32
|
-
version: '3.0'
|
33
13
|
- !ruby/object:Gem::Dependency
|
34
14
|
name: cabin
|
35
15
|
requirement: !ruby/object:Gem::Requirement
|
@@ -86,20 +66,6 @@ dependencies:
|
|
86
66
|
- - "~>"
|
87
67
|
- !ruby/object:Gem::Version
|
88
68
|
version: 1.0.0
|
89
|
-
- !ruby/object:Gem::Dependency
|
90
|
-
name: rake
|
91
|
-
requirement: !ruby/object:Gem::Requirement
|
92
|
-
requirements:
|
93
|
-
- - "~>"
|
94
|
-
- !ruby/object:Gem::Version
|
95
|
-
version: '10'
|
96
|
-
type: :development
|
97
|
-
prerelease: false
|
98
|
-
version_requirements: !ruby/object:Gem::Requirement
|
99
|
-
requirements:
|
100
|
-
- - "~>"
|
101
|
-
- !ruby/object:Gem::Version
|
102
|
-
version: '10'
|
103
69
|
- !ruby/object:Gem::Dependency
|
104
70
|
name: pleaserun
|
105
71
|
requirement: !ruby/object:Gem::Requirement
|
@@ -114,26 +80,6 @@ dependencies:
|
|
114
80
|
- - "~>"
|
115
81
|
- !ruby/object:Gem::Version
|
116
82
|
version: 0.0.29
|
117
|
-
- !ruby/object:Gem::Dependency
|
118
|
-
name: git
|
119
|
-
requirement: !ruby/object:Gem::Requirement
|
120
|
-
requirements:
|
121
|
-
- - ">="
|
122
|
-
- !ruby/object:Gem::Version
|
123
|
-
version: 1.3.0
|
124
|
-
- - "<"
|
125
|
-
- !ruby/object:Gem::Version
|
126
|
-
version: '2.0'
|
127
|
-
type: :runtime
|
128
|
-
prerelease: false
|
129
|
-
version_requirements: !ruby/object:Gem::Requirement
|
130
|
-
requirements:
|
131
|
-
- - ">="
|
132
|
-
- !ruby/object:Gem::Version
|
133
|
-
version: 1.3.0
|
134
|
-
- - "<"
|
135
|
-
- !ruby/object:Gem::Version
|
136
|
-
version: '2.0'
|
137
83
|
- !ruby/object:Gem::Dependency
|
138
84
|
name: stud
|
139
85
|
requirement: !ruby/object:Gem::Requirement
|
@@ -204,6 +150,20 @@ dependencies:
|
|
204
150
|
- - ">="
|
205
151
|
- !ruby/object:Gem::Version
|
206
152
|
version: '0'
|
153
|
+
- !ruby/object:Gem::Dependency
|
154
|
+
name: rake
|
155
|
+
requirement: !ruby/object:Gem::Requirement
|
156
|
+
requirements:
|
157
|
+
- - ">="
|
158
|
+
- !ruby/object:Gem::Version
|
159
|
+
version: '0'
|
160
|
+
type: :development
|
161
|
+
prerelease: false
|
162
|
+
version_requirements: !ruby/object:Gem::Requirement
|
163
|
+
requirements:
|
164
|
+
- - ">="
|
165
|
+
- !ruby/object:Gem::Version
|
166
|
+
version: '0'
|
207
167
|
description: Convert directories, rpms, python eggs, rubygems, and more to rpms, debs,
|
208
168
|
solaris packages and more. Win at package management without wasting pointless hours
|
209
169
|
debugging bad rpm specs!
|
@@ -294,7 +254,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
294
254
|
- !ruby/object:Gem::Version
|
295
255
|
version: '0'
|
296
256
|
requirements: []
|
297
|
-
rubygems_version: 3.
|
257
|
+
rubygems_version: 3.4.1
|
298
258
|
signing_key:
|
299
259
|
specification_version: 4
|
300
260
|
summary: fpm - package building and mangling
|