fpm 1.6.1 → 1.14.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/CHANGELOG.rst +674 -0
- data/CONTRIBUTORS +2 -0
- data/LICENSE +1 -1
- data/bin/fpm +0 -1
- data/lib/fpm/command.rb +26 -12
- data/lib/fpm/package/apk.rb +6 -6
- data/lib/fpm/package/cpan.rb +85 -30
- data/lib/fpm/package/deb.rb +298 -44
- data/lib/fpm/package/dir.rb +12 -17
- data/lib/fpm/package/empty.rb +13 -1
- data/lib/fpm/package/freebsd.rb +37 -33
- data/lib/fpm/package/gem.rb +167 -13
- data/lib/fpm/package/pacman.rb +28 -12
- data/lib/fpm/package/pleaserun.rb +13 -1
- data/lib/fpm/package/pyfpm/get_metadata.py +10 -0
- data/lib/fpm/package/python.rb +57 -8
- data/lib/fpm/package/rpm.rb +62 -10
- data/lib/fpm/package/sh.rb +1 -1
- data/lib/fpm/package/snap.rb +130 -0
- data/lib/fpm/package/tar.rb +2 -10
- data/lib/fpm/package/virtualenv.rb +76 -14
- data/lib/fpm/package/zip.rb +6 -22
- data/lib/fpm/package.rb +27 -6
- data/lib/fpm/util/tar_writer.rb +3 -1
- data/lib/fpm/util.rb +115 -62
- data/lib/fpm/version.rb +1 -1
- data/lib/fpm.rb +2 -0
- data/templates/deb/changelog.erb +1 -1
- data/templates/deb/deb.changes.erb +30 -0
- data/templates/deb/postinst_upgrade.sh.erb +30 -8
- data/templates/deb/postrm_upgrade.sh.erb +17 -5
- data/templates/deb/preinst_upgrade.sh.erb +5 -0
- data/templates/deb/prerm_upgrade.sh.erb +12 -4
- data/templates/deb.erb +7 -7
- data/templates/rpm.erb +14 -12
- data/templates/sh.erb +6 -1
- metadata +33 -64
- data/CHANGELIST +0 -650
- data/lib/fpm/package/pyfpm/__init__.pyc +0 -0
- data/lib/fpm/package/pyfpm/get_metadata.pyc +0 -0
data/lib/fpm/package/deb.rb
CHANGED
@@ -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
|
#
|
@@ -18,10 +23,22 @@ class FPM::Package::Deb < FPM::Package
|
|
18
23
|
:after_install => "postinst",
|
19
24
|
:before_remove => "prerm",
|
20
25
|
:after_remove => "postrm",
|
26
|
+
:after_purge => "postrm",
|
21
27
|
} unless defined?(SCRIPT_MAP)
|
22
28
|
|
23
29
|
# The list of supported compression types. Default is gz (gzip)
|
24
|
-
COMPRESSION_TYPES = [ "gz", "bzip2", "xz" ]
|
30
|
+
COMPRESSION_TYPES = [ "gz", "bzip2", "xz", "none" ]
|
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+~.]+)?)\))?$/
|
25
42
|
|
26
43
|
option "--ignore-iteration-in-dependencies", :flag,
|
27
44
|
"For '=' (equal) dependencies, allow iterations on the specified " \
|
@@ -49,6 +66,8 @@ class FPM::Package::Deb < FPM::Package
|
|
49
66
|
value
|
50
67
|
end
|
51
68
|
|
69
|
+
option "--dist", "DIST-TAG", "Set the deb distribution.", :default => "unstable"
|
70
|
+
|
52
71
|
# Take care about the case when we want custom control file but still use fpm ...
|
53
72
|
option "--custom-control", "FILEPATH",
|
54
73
|
"Custom version of the Debian control file." do |control|
|
@@ -87,6 +106,10 @@ class FPM::Package::Deb < FPM::Package
|
|
87
106
|
File.expand_path(file)
|
88
107
|
end
|
89
108
|
|
109
|
+
option "--generate-changes", :flag,
|
110
|
+
"Generate PACKAGENAME.changes file.",
|
111
|
+
:default => false
|
112
|
+
|
90
113
|
option "--upstream-changelog", "FILEPATH", "Add FILEPATH as upstream changelog" do |file|
|
91
114
|
File.expand_path(file)
|
92
115
|
end
|
@@ -121,6 +144,18 @@ class FPM::Package::Deb < FPM::Package
|
|
121
144
|
next @activated_triggers
|
122
145
|
end
|
123
146
|
|
147
|
+
option "--interest-noawait", "EVENT", "Package is interested in EVENT trigger without awaiting" do |event|
|
148
|
+
@interested_noawait_triggers ||= []
|
149
|
+
@interested_noawait_triggers << event
|
150
|
+
next @interested_noawait_triggers
|
151
|
+
end
|
152
|
+
|
153
|
+
option "--activate-noawait", "EVENT", "Package activates EVENT trigger" do |event|
|
154
|
+
@activated_noawait_triggers ||= []
|
155
|
+
@activated_noawait_triggers << event
|
156
|
+
next @activated_noawait_triggers
|
157
|
+
end
|
158
|
+
|
124
159
|
option "--field", "'FIELD: VALUE'", "Add custom field to the control file" do |fv|
|
125
160
|
@custom_fields ||= {}
|
126
161
|
field, value = fv.split(/: */, 2)
|
@@ -158,12 +193,27 @@ class FPM::Package::Deb < FPM::Package
|
|
158
193
|
end
|
159
194
|
|
160
195
|
option "--systemd", "FILEPATH", "Add FILEPATH as a systemd script",
|
161
|
-
|
196
|
+
:multivalued => true do |file|
|
162
197
|
next File.expand_path(file)
|
163
198
|
end
|
164
199
|
|
200
|
+
option "--systemd-enable", :flag , "Enable service on install or upgrade", :default => false
|
201
|
+
|
202
|
+
option "--systemd-auto-start", :flag , "Start service after install or upgrade", :default => false
|
203
|
+
|
165
204
|
option "--systemd-restart-after-upgrade", :flag , "Restart service after upgrade", :default => true
|
166
205
|
|
206
|
+
option "--after-purge", "FILE",
|
207
|
+
"A script to be run after package removal to purge remaining (config) files " \
|
208
|
+
"(a.k.a. postrm purge within apt-get purge)" do |val|
|
209
|
+
File.expand_path(val) # Get the full path to the script
|
210
|
+
end # --after-purge
|
211
|
+
|
212
|
+
option "--maintainerscripts-force-errorchecks", :flag ,
|
213
|
+
"Activate errexit shell option according to lintian. " \
|
214
|
+
"https://lintian.debian.org/tags/maintainer-script-ignores-errors.html",
|
215
|
+
:default => false
|
216
|
+
|
167
217
|
def initialize(*args)
|
168
218
|
super(*args)
|
169
219
|
attributes[:deb_priority] = "extra"
|
@@ -193,6 +243,9 @@ class FPM::Package::Deb < FPM::Package
|
|
193
243
|
when "x86_64"
|
194
244
|
# Debian calls x86_64 "amd64"
|
195
245
|
@architecture = "amd64"
|
246
|
+
when "aarch64"
|
247
|
+
# Debian calls aarch64 "arm64"
|
248
|
+
@architecture = "arm64"
|
196
249
|
when "noarch"
|
197
250
|
# Debian calls noarch "all"
|
198
251
|
@architecture = "all"
|
@@ -240,10 +293,32 @@ class FPM::Package::Deb < FPM::Package
|
|
240
293
|
end # def input
|
241
294
|
|
242
295
|
def extract_info(package)
|
296
|
+
compression = `#{ar_cmd[0]} t #{package}`.split("\n").grep(/control.tar/).first.split(".").last
|
297
|
+
case compression
|
298
|
+
when "gz"
|
299
|
+
controltar = "control.tar.gz"
|
300
|
+
compression = "-z"
|
301
|
+
when "bzip2","bz2"
|
302
|
+
controltar = "control.tar.bz2"
|
303
|
+
compression = "-j"
|
304
|
+
when "xz"
|
305
|
+
controltar = "control.tar.xz"
|
306
|
+
compression = "-J"
|
307
|
+
when 'tar'
|
308
|
+
controltar = "control.tar"
|
309
|
+
compression = ""
|
310
|
+
when nil
|
311
|
+
raise FPM::InvalidPackageConfiguration, "Missing control.tar in deb source package #{package}"
|
312
|
+
else
|
313
|
+
raise FPM::InvalidPackageConfiguration,
|
314
|
+
"Unknown compression type '#{compression}' for control.tar in deb source package #{package}"
|
315
|
+
end
|
316
|
+
|
243
317
|
build_path("control").tap do |path|
|
244
318
|
FileUtils.mkdir(path) if !File.directory?(path)
|
319
|
+
# unpack the control.tar.{,gz,bz2,xz} from the deb package into staging_path
|
245
320
|
# Unpack the control tarball
|
246
|
-
safesystem("
|
321
|
+
safesystem(ar_cmd[0] + " p #{package} #{controltar} | tar #{compression} -xf - -C #{path}")
|
247
322
|
|
248
323
|
control = File.read(File.join(path, "control"))
|
249
324
|
|
@@ -340,30 +415,39 @@ class FPM::Package::Deb < FPM::Package
|
|
340
415
|
|
341
416
|
def extract_files(package)
|
342
417
|
# Find out the compression type
|
343
|
-
compression =
|
418
|
+
compression = `#{ar_cmd[0]} t #{package}`.split("\n").grep(/data.tar/).first.split(".").last
|
344
419
|
case compression
|
345
420
|
when "gz"
|
346
421
|
datatar = "data.tar.gz"
|
347
422
|
compression = "-z"
|
348
|
-
when "bzip2"
|
423
|
+
when "bzip2","bz2"
|
349
424
|
datatar = "data.tar.bz2"
|
350
425
|
compression = "-j"
|
351
426
|
when "xz"
|
352
427
|
datatar = "data.tar.xz"
|
353
428
|
compression = "-J"
|
429
|
+
when 'tar'
|
430
|
+
datatar = "data.tar"
|
431
|
+
compression = ""
|
432
|
+
when nil
|
433
|
+
raise FPM::InvalidPackageConfiguration, "Missing data.tar in deb source package #{package}"
|
354
434
|
else
|
355
435
|
raise FPM::InvalidPackageConfiguration,
|
356
|
-
"Unknown compression type '#{
|
357
|
-
"in deb source package #{package}"
|
436
|
+
"Unknown compression type '#{compression}' for data.tar in deb source package #{package}"
|
358
437
|
end
|
359
438
|
|
360
439
|
# unpack the data.tar.{gz,bz2,xz} from the deb package into staging_path
|
361
|
-
safesystem("
|
362
|
-
"| tar #{compression} -xf - -C #{staging_path}")
|
440
|
+
safesystem(ar_cmd[0] + " p #{package} #{datatar} | tar #{compression} -xf - -C #{staging_path}")
|
363
441
|
end # def extract_files
|
364
442
|
|
365
443
|
def output(output_path)
|
366
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
|
367
451
|
output_check(output_path)
|
368
452
|
# Abort if the target path already exists.
|
369
453
|
|
@@ -387,6 +471,23 @@ class FPM::Package::Deb < FPM::Package
|
|
387
471
|
end
|
388
472
|
end
|
389
473
|
|
474
|
+
if attributes[:source_date_epoch].nil? and not attributes[:source_date_epoch_default].nil?
|
475
|
+
attributes[:source_date_epoch] = attributes[:source_date_epoch_default]
|
476
|
+
end
|
477
|
+
if attributes[:source_date_epoch] == "0"
|
478
|
+
logger.error("Alas, ruby's Zlib::GzipWriter does not support setting an mtime of zero. Aborting.")
|
479
|
+
raise "#{name}: source_date_epoch of 0 not supported."
|
480
|
+
end
|
481
|
+
if not attributes[:source_date_epoch].nil? and not ar_cmd_deterministic?
|
482
|
+
logger.error("Alas, could not find an ar that can handle -D option. Try installing recent gnu binutils. Aborting.")
|
483
|
+
raise "#{name}: ar is insufficient to support source_date_epoch."
|
484
|
+
end
|
485
|
+
if not attributes[:source_date_epoch].nil? and not tar_cmd_supports_sort_names_and_set_mtime?
|
486
|
+
logger.error("Alas, could not find a tar that can set mtime and sort. Try installing recent gnu tar. Aborting.")
|
487
|
+
raise "#{name}: tar is insufficient to support source_date_epoch."
|
488
|
+
end
|
489
|
+
|
490
|
+
attributes[:deb_systemd] = []
|
390
491
|
attributes.fetch(:deb_systemd_list, []).each do |systemd|
|
391
492
|
name = File.basename(systemd, ".service")
|
392
493
|
dest_systemd = staging_path("lib/systemd/system/#{name}.service")
|
@@ -394,42 +495,27 @@ class FPM::Package::Deb < FPM::Package
|
|
394
495
|
FileUtils.cp(systemd, dest_systemd)
|
395
496
|
File.chmod(0644, dest_systemd)
|
396
497
|
|
397
|
-
#
|
398
|
-
attributes[:deb_systemd]
|
498
|
+
# add systemd service name to attribute
|
499
|
+
attributes[:deb_systemd] << name
|
399
500
|
end
|
400
501
|
|
401
|
-
if script?(:before_upgrade) or script?(:after_upgrade) or attributes[:deb_systemd]
|
502
|
+
if script?(:before_upgrade) or script?(:after_upgrade) or attributes[:deb_systemd].any?
|
402
503
|
puts "Adding action files"
|
403
504
|
if script?(:before_install) or script?(:before_upgrade)
|
404
505
|
scripts[:before_install] = template("deb/preinst_upgrade.sh.erb").result(binding)
|
405
506
|
end
|
406
|
-
if script?(:before_remove) or attributes[:deb_systemd]
|
507
|
+
if script?(:before_remove) or not attributes[:deb_systemd].empty?
|
407
508
|
scripts[:before_remove] = template("deb/prerm_upgrade.sh.erb").result(binding)
|
408
509
|
end
|
409
|
-
if script?(:after_install) or script?(:after_upgrade) or attributes[:deb_systemd]
|
510
|
+
if script?(:after_install) or script?(:after_upgrade) or attributes[:deb_systemd].any?
|
410
511
|
scripts[:after_install] = template("deb/postinst_upgrade.sh.erb").result(binding)
|
411
512
|
end
|
412
513
|
if script?(:after_remove)
|
413
514
|
scripts[:after_remove] = template("deb/postrm_upgrade.sh.erb").result(binding)
|
414
515
|
end
|
415
|
-
|
416
|
-
|
417
|
-
|
418
|
-
|
419
|
-
# Tar up the staging_path into data.tar.{compression type}
|
420
|
-
case self.attributes[:deb_compression]
|
421
|
-
when "gz", nil
|
422
|
-
datatar = build_path("data.tar.gz")
|
423
|
-
compression = "-z"
|
424
|
-
when "bzip2"
|
425
|
-
datatar = build_path("data.tar.bz2")
|
426
|
-
compression = "-j"
|
427
|
-
when "xz"
|
428
|
-
datatar = build_path("data.tar.xz")
|
429
|
-
compression = "-J"
|
430
|
-
else
|
431
|
-
raise FPM::InvalidPackageConfiguration,
|
432
|
-
"Unknown compression type '#{self.attributes[:deb_compression]}'"
|
516
|
+
if script?(:after_purge)
|
517
|
+
scripts[:after_purge] = template("deb/postrm_upgrade.sh.erb").result(binding)
|
518
|
+
end
|
433
519
|
end
|
434
520
|
|
435
521
|
# There are two changelogs that may appear:
|
@@ -442,6 +528,9 @@ class FPM::Package::Deb < FPM::Package
|
|
442
528
|
mkdir_p(File.dirname(dest_changelog))
|
443
529
|
File.new(dest_changelog, "wb", 0644).tap do |changelog|
|
444
530
|
Zlib::GzipWriter.new(changelog, Zlib::BEST_COMPRESSION).tap do |changelog_gz|
|
531
|
+
if not attributes[:source_date_epoch].nil?
|
532
|
+
changelog_gz.mtime = attributes[:source_date_epoch].to_i
|
533
|
+
end
|
445
534
|
if attributes[:deb_changelog]
|
446
535
|
logger.info("Writing user-specified changelog", :source => attributes[:deb_changelog])
|
447
536
|
File.new(attributes[:deb_changelog]).tap do |fd|
|
@@ -461,6 +550,9 @@ class FPM::Package::Deb < FPM::Package
|
|
461
550
|
if attributes[:deb_upstream_changelog]
|
462
551
|
File.new(dest_upstream_changelog, "wb", 0644).tap do |changelog|
|
463
552
|
Zlib::GzipWriter.new(changelog, Zlib::BEST_COMPRESSION).tap do |changelog_gz|
|
553
|
+
if not attributes[:source_date_epoch].nil?
|
554
|
+
changelog_gz.mtime = attributes[:source_date_epoch].to_i
|
555
|
+
end
|
464
556
|
logger.info("Writing user-specified upstream changelog", :source => attributes[:deb_upstream_changelog])
|
465
557
|
File.new(attributes[:deb_upstream_changelog]).tap do |fd|
|
466
558
|
chunk = nil
|
@@ -494,6 +586,7 @@ class FPM::Package::Deb < FPM::Package
|
|
494
586
|
|
495
587
|
attributes.fetch(:deb_upstart_list, []).each do |upstart|
|
496
588
|
name = File.basename(upstart, ".upstart")
|
589
|
+
dest_init = staging_path("etc/init.d/#{name}")
|
497
590
|
name = "#{name}.conf" if !(name =~ /\.conf$/)
|
498
591
|
dest_upstart = staging_path("etc/init/#{name}")
|
499
592
|
mkdir_p(File.dirname(dest_upstart))
|
@@ -501,7 +594,6 @@ class FPM::Package::Deb < FPM::Package
|
|
501
594
|
File.chmod(0644, dest_upstart)
|
502
595
|
|
503
596
|
# Install an init.d shim that calls upstart
|
504
|
-
dest_init = staging_path("etc/init.d/#{name}")
|
505
597
|
mkdir_p(File.dirname(dest_init))
|
506
598
|
FileUtils.ln_s("/lib/init/upstart-job", dest_init)
|
507
599
|
end
|
@@ -520,28 +612,65 @@ class FPM::Package::Deb < FPM::Package
|
|
520
612
|
case self.attributes[:deb_compression]
|
521
613
|
when "gz", nil
|
522
614
|
datatar = build_path("data.tar.gz")
|
615
|
+
controltar = build_path("control.tar.gz")
|
523
616
|
compression = "-z"
|
524
617
|
when "bzip2"
|
525
618
|
datatar = build_path("data.tar.bz2")
|
619
|
+
controltar = build_path("control.tar.gz")
|
526
620
|
compression = "-j"
|
527
621
|
when "xz"
|
528
622
|
datatar = build_path("data.tar.xz")
|
623
|
+
controltar = build_path("control.tar.xz")
|
529
624
|
compression = "-J"
|
625
|
+
when "none"
|
626
|
+
datatar = build_path("data.tar")
|
627
|
+
controltar = build_path("control.tar")
|
628
|
+
compression = ""
|
530
629
|
else
|
531
630
|
raise FPM::InvalidPackageConfiguration,
|
532
631
|
"Unknown compression type '#{self.attributes[:deb_compression]}'"
|
533
632
|
end
|
534
633
|
|
535
634
|
args = [ tar_cmd, "-C", staging_path, compression ] + data_tar_flags + [ "-cf", datatar, "." ]
|
635
|
+
if tar_cmd_supports_sort_names_and_set_mtime? and not attributes[:source_date_epoch].nil?
|
636
|
+
# Use gnu tar options to force deterministic file order and timestamp
|
637
|
+
args += ["--sort=name", ("--mtime=@%s" % attributes[:source_date_epoch])]
|
638
|
+
# gnu tar obeys GZIP environment variable with options for gzip; -n = forget original filename and date
|
639
|
+
args.unshift({"GZIP" => "-9n"})
|
640
|
+
end
|
536
641
|
safesystem(*args)
|
537
642
|
|
538
643
|
# pack up the .deb, which is just an 'ar' archive with 3 files
|
539
644
|
# the 'debian-binary' file has to be first
|
540
645
|
File.expand_path(output_path).tap do |output_path|
|
541
646
|
::Dir.chdir(build_path) do
|
542
|
-
safesystem(
|
647
|
+
safesystem(*ar_cmd, output_path, "debian-binary", controltar, datatar)
|
543
648
|
end
|
544
649
|
end
|
650
|
+
|
651
|
+
# if a PACKAGENAME.changes file is to be created
|
652
|
+
if self.attributes[:deb_generate_changes?]
|
653
|
+
distribution = self.attributes[:deb_dist]
|
654
|
+
|
655
|
+
# gather information about the files to distribute
|
656
|
+
files = [ output_path ]
|
657
|
+
changes_files = []
|
658
|
+
files.each do |path|
|
659
|
+
changes_files.push({
|
660
|
+
:name => path,
|
661
|
+
:size => File.size?(path),
|
662
|
+
:md5sum => Digest::MD5.file(path).hexdigest,
|
663
|
+
:sha1sum => Digest::SHA1.file(path).hexdigest,
|
664
|
+
:sha256sum => Digest::SHA2.file(path).hexdigest,
|
665
|
+
})
|
666
|
+
end
|
667
|
+
|
668
|
+
# write change infos to .changes file
|
669
|
+
changes_path = File.basename(output_path, '.deb') + '.changes'
|
670
|
+
changes_data = template("deb/deb.changes.erb").result(binding)
|
671
|
+
File.write(changes_path, changes_data)
|
672
|
+
logger.log("Created changes", :path => changes_path)
|
673
|
+
end # if deb_generate_changes
|
545
674
|
end # def output
|
546
675
|
|
547
676
|
def converted_from(origin)
|
@@ -552,6 +681,43 @@ class FPM::Package::Deb < FPM::Package
|
|
552
681
|
fix_provides(provides)
|
553
682
|
end.flatten
|
554
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
|
+
|
555
721
|
if origin == FPM::Package::Deb
|
556
722
|
changelog_path = staging_path("usr/share/doc/#{name}/changelog.Debian.gz")
|
557
723
|
if File.exists?(changelog_path)
|
@@ -579,6 +745,19 @@ class FPM::Package::Deb < FPM::Package
|
|
579
745
|
File.unlink(changelog_path)
|
580
746
|
end
|
581
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
|
582
761
|
end # def converted_from
|
583
762
|
|
584
763
|
def debianize_op(op)
|
@@ -620,8 +799,13 @@ class FPM::Package::Deb < FPM::Package
|
|
620
799
|
name, version = dep.gsub(/[()~>]/, "").split(/ +/)[0..1]
|
621
800
|
nextversion = version.split(".").collect { |v| v.to_i }
|
622
801
|
l = nextversion.length
|
623
|
-
|
624
|
-
|
802
|
+
if l > 1
|
803
|
+
nextversion[l-2] += 1
|
804
|
+
nextversion[l-1] = 0
|
805
|
+
else
|
806
|
+
# Single component versions ~> 1
|
807
|
+
nextversion[l-1] += 1
|
808
|
+
end
|
625
809
|
nextversion = nextversion.join(".")
|
626
810
|
return ["#{name} (>= #{version})", "#{name} (<< #{nextversion})"]
|
627
811
|
elsif (m = dep.match(/(\S+)\s+\(!= (.+)\)/))
|
@@ -648,6 +832,32 @@ class FPM::Package::Deb < FPM::Package
|
|
648
832
|
end
|
649
833
|
end # def fix_dependency
|
650
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
|
+
|
651
861
|
def fix_provides(provides)
|
652
862
|
name_re = /^[^ \(]+/
|
653
863
|
name = provides[name_re]
|
@@ -662,6 +872,11 @@ class FPM::Package::Deb < FPM::Package
|
|
662
872
|
"debs don't like underscores")
|
663
873
|
provides = provides.gsub("_", "-")
|
664
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
|
665
880
|
return provides.rstrip
|
666
881
|
end
|
667
882
|
|
@@ -687,12 +902,34 @@ class FPM::Package::Deb < FPM::Package
|
|
687
902
|
write_triggers # write trigger config to 'triggers' file
|
688
903
|
write_md5sums # write the md5sums file
|
689
904
|
|
905
|
+
# Tar up the staging_path into control.tar.{compression type}
|
906
|
+
case self.attributes[:deb_compression]
|
907
|
+
when "gz", "bzip2", nil
|
908
|
+
controltar = "control.tar.gz"
|
909
|
+
compression = "-z"
|
910
|
+
when "xz"
|
911
|
+
controltar = "control.tar.xz"
|
912
|
+
compression = "-J"
|
913
|
+
when "none"
|
914
|
+
controltar = "control.tar"
|
915
|
+
compression = ""
|
916
|
+
else
|
917
|
+
raise FPM::InvalidPackageConfiguration,
|
918
|
+
"Unknown compression type '#{self.attributes[:deb_compression]}'"
|
919
|
+
end
|
920
|
+
|
690
921
|
# Make the control.tar.gz
|
691
|
-
build_path(
|
922
|
+
build_path(controltar).tap do |controltar|
|
692
923
|
logger.info("Creating", :path => controltar, :from => control_path)
|
693
924
|
|
694
|
-
args = [ tar_cmd, "-C", control_path, "-
|
925
|
+
args = [ tar_cmd, "-C", control_path, compression, "-cf", controltar,
|
695
926
|
"--owner=0", "--group=0", "--numeric-owner", "." ]
|
927
|
+
if tar_cmd_supports_sort_names_and_set_mtime? and not attributes[:source_date_epoch].nil?
|
928
|
+
# Force deterministic file order and timestamp
|
929
|
+
args += ["--sort=name", ("--mtime=@%s" % attributes[:source_date_epoch])]
|
930
|
+
# gnu tar obeys GZIP environment variable with options for gzip; -n = forget original filename and date
|
931
|
+
args.unshift({"GZIP" => "-9n"})
|
932
|
+
end
|
696
933
|
safesystem(*args)
|
697
934
|
end
|
698
935
|
|
@@ -774,7 +1011,7 @@ class FPM::Package::Deb < FPM::Package
|
|
774
1011
|
etcfiles = []
|
775
1012
|
# Add everything in /etc
|
776
1013
|
begin
|
777
|
-
if !attributes[:deb_no_default_config_files?]
|
1014
|
+
if !attributes[:deb_no_default_config_files?] && File.exists?(staging_path("/etc"))
|
778
1015
|
logger.warn("Debian packaging tools generally labels all files in /etc as config files, " \
|
779
1016
|
"as mandated by policy, so fpm defaults to this behavior for deb packages. " \
|
780
1017
|
"You can disable this default behavior with --deb-no-default-config-files flag")
|
@@ -789,11 +1026,25 @@ class FPM::Package::Deb < FPM::Package
|
|
789
1026
|
|
790
1027
|
# scan all conf file paths for files and add them
|
791
1028
|
config_files.each do |path|
|
1029
|
+
logger.debug("Checking if #{path} exists")
|
1030
|
+
cfe = File.exist?("#{path}")
|
1031
|
+
logger.debug("Check result #{cfe}")
|
792
1032
|
begin
|
793
1033
|
add_path(path, allconfigs)
|
794
1034
|
rescue Errno::ENOENT
|
795
|
-
|
796
|
-
|
1035
|
+
if !cfe
|
1036
|
+
raise FPM::InvalidPackageConfiguration,
|
1037
|
+
"Error trying to use '#{path}' as a config file in the package. Does it exist?"
|
1038
|
+
else
|
1039
|
+
dcl = File.join(staging_path, path)
|
1040
|
+
if !File.exist?("#{dcl}")
|
1041
|
+
logger.debug("Adding config file #{path} to Staging area #{staging_path}")
|
1042
|
+
FileUtils.mkdir_p(File.dirname(dcl))
|
1043
|
+
FileUtils.cp_r path, dcl
|
1044
|
+
else
|
1045
|
+
logger.debug("Config file aready exists in staging area.")
|
1046
|
+
end
|
1047
|
+
end
|
797
1048
|
end
|
798
1049
|
end
|
799
1050
|
|
@@ -849,7 +1100,7 @@ class FPM::Package::Deb < FPM::Package
|
|
849
1100
|
|
850
1101
|
if attributes[:deb_templates]
|
851
1102
|
FileUtils.cp(attributes[:deb_templates], control_path("templates"))
|
852
|
-
File.chmod(
|
1103
|
+
File.chmod(0644, control_path("templates"))
|
853
1104
|
end
|
854
1105
|
end # def write_debconf
|
855
1106
|
|
@@ -865,7 +1116,10 @@ class FPM::Package::Deb < FPM::Package
|
|
865
1116
|
|
866
1117
|
def write_triggers
|
867
1118
|
lines = [['interest', :deb_interest],
|
868
|
-
['activate', :deb_activate]
|
1119
|
+
['activate', :deb_activate],
|
1120
|
+
['interest-noawait', :deb_interest_noawait],
|
1121
|
+
['activate-noawait', :deb_activate_noawait],
|
1122
|
+
].map { |label, attr|
|
869
1123
|
(attributes[attr] || []).map { |e| "#{label} #{e}\n" }
|
870
1124
|
}.flatten.join('')
|
871
1125
|
|
data/lib/fpm/package/dir.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
require "fpm/package"
|
2
2
|
require "fpm/util"
|
3
|
-
require "backports"
|
3
|
+
require "backports/latest"
|
4
4
|
require "fileutils"
|
5
5
|
require "find"
|
6
6
|
require "socket"
|
@@ -83,8 +83,8 @@ class FPM::Package::Dir < FPM::Package
|
|
83
83
|
# can include license data from themselves (rpms, gems, etc),
|
84
84
|
# but to make sure a simple dir -> rpm works without having
|
85
85
|
# to specify a license.
|
86
|
-
self.license
|
87
|
-
self.vendor
|
86
|
+
self.license ||= "unknown"
|
87
|
+
self.vendor ||= [ENV["USER"], Socket.gethostname].join("@")
|
88
88
|
ensure
|
89
89
|
# Clean up any logger context we added.
|
90
90
|
logger.remove("method")
|
@@ -101,18 +101,7 @@ class FPM::Package::Dir < FPM::Package
|
|
101
101
|
end
|
102
102
|
|
103
103
|
# Write the scripts, too.
|
104
|
-
|
105
|
-
::Dir.mkdir(scripts_path)
|
106
|
-
[:before_install, :after_install, :before_remove, :after_remove].each do |name|
|
107
|
-
next unless script?(name)
|
108
|
-
out = File.join(scripts_path, name.to_s)
|
109
|
-
logger.debug("Writing script", :source => name, :target => out)
|
110
|
-
File.write(out, script(name))
|
111
|
-
require "pry"
|
112
|
-
binding.pry
|
113
|
-
File.chmod(0755, out)
|
114
|
-
end
|
115
|
-
|
104
|
+
write_scripts
|
116
105
|
ensure
|
117
106
|
logger.remove("method")
|
118
107
|
end # def output
|
@@ -147,14 +136,20 @@ class FPM::Package::Dir < FPM::Package
|
|
147
136
|
|
148
137
|
# For single file copies, permit file destinations
|
149
138
|
fileinfo = File.lstat(source)
|
150
|
-
|
139
|
+
destination_is_directory = File.directory?(destination)
|
140
|
+
if fileinfo.file? && !destination_is_directory
|
151
141
|
if destination[-1,1] == "/"
|
152
142
|
copy(source, File.join(destination, source))
|
153
143
|
else
|
154
144
|
copy(source, destination)
|
155
145
|
end
|
156
146
|
elsif fileinfo.symlink?
|
157
|
-
|
147
|
+
# Treat them same as files
|
148
|
+
if destination[-1,1] == "/"
|
149
|
+
copy(source, File.join(destination, source))
|
150
|
+
else
|
151
|
+
copy(source, destination)
|
152
|
+
end
|
158
153
|
else
|
159
154
|
# Copy all files from 'path' into staging_path
|
160
155
|
Find.find(source) do |path|
|
data/lib/fpm/package/empty.rb
CHANGED
@@ -1,9 +1,21 @@
|
|
1
1
|
require "fpm/package"
|
2
|
-
require "backports"
|
2
|
+
require "backports/latest"
|
3
3
|
|
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
|