fpm 1.8.1 → 1.9.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 2053d568639fe148fe3d955eb70e27c41bfb9d6b
4
- data.tar.gz: 1a4d6ac0ddd23b851d74e8cdbe5c57d3c5378ef7
3
+ metadata.gz: b9fb4eab81222c77d6790e9e06c8348744a020e7
4
+ data.tar.gz: a29942bc9fcc9dcbe6bf0f4d1fbfa431d202eb2b
5
5
  SHA512:
6
- metadata.gz: dbf0ccf583f7833316f65e28494ab6fc761ec937518af0f4bdc2812591f2a7205b60490e997b38e98a8ff44d5c5d31b95b3834f538ae90c9e783e1f6e1da462f
7
- data.tar.gz: 1d9316d61d328cd8978b2bc5bc3e50e7f08bd6b30e2fe29c82d3096aea7731d963920555d0db6f37407b98ed5798540881fecd80b400d13505e8d10d6a43df77
6
+ metadata.gz: c97a69b63e17f684c7f481bda43e479d34a030e253b0a7294de356eaf1a35dc83b230deec5cf77270ff17756b98b8336016588be3ea41317ec354bd56649c1e8
7
+ data.tar.gz: a3708d970c1d1b6d4d384893f7c596b5fad2ea6d4eb01e0baa42bec1de3bbb85286f3d5acab9823928cf00bb04f59c98247d307269f04fe01bae824f387e59cf
@@ -1,6 +1,45 @@
1
1
  Release Notes and Change Log
2
2
  ============================
3
3
 
4
+ 1.9.1 (July 28, 2017) happy sysadmin day!
5
+ ^^^^^^^^^^^^^^^^^^^^^
6
+
7
+ * Documentation improvements: `#1291`_; Pablo Castellano. `#1321`_; ge-fa. `#1309`_; jesusbagpuss. `#1349`_; Perry Stole. `#1352`_, Jordan Sissel. `#1384`_; Justin Kolberg.
8
+ * Testing improvements: `#1320`_; Rob Young. `#1266`_; Ryan Parman. `#1374`_; Thiago Figueiró.
9
+ * Fix bug so fpm can now copy symlinks correctly (`#1348`_; ServiusHack)
10
+ * apk: Improve performance (`#1358`_; Jan Delgado)
11
+ * cpan: Fix crash when CPAN query returns a version value that was a number and fpm was expecting a string. (`#1344`_, `#1343`_; liger1978)
12
+ * cpan: Fix MetaCPAN searches to use v1 of MetaCPAN's API. The v0 API is no longer provided by MetaCPAN. (`#1341`_, `#1339`; Bob Bell)
13
+ * cpan: Have perl modules implicitly "provide" (`--provides`) capabilities. (`#1340`_; Bob Bell. `#1345`_; liger1978)
14
+ * cpan: Now transforms perl version values like "5.008001" to "5.8.1" (`#1342`_; Bob Bell)
15
+ * cpan: Use `>=` ("this version or newer") for package dependencies instead of `=` ("exactly this version"). (`#1338`_; Bob Bell)
16
+ * deb: Add `--deb-after-purge` flag for running a script after `apt-get purge` is run. (Alexander Weidinger)
17
+ * deb: fix bug when using `--deb-upstart` would use the wrong file name (`#1325`_, `#1287`_; vbakayev)
18
+ * deb: New flags `--deb-interest-noawait` and `--deb-activate-nowait`. (`#1225`_, `#1359`_; Philippe Poilbarbe)
19
+ * dir: Remove a debug statement that would put fpm into a debug prompt (`#1293`_, `#1259`_; Joseph Anthony Pasquale Holsten)
20
+ * dir: When using `path mapping`_ (`a=b` syntax), and `a` is a symlink, use the path `b` as the symlink, not `b/a` (`#1253`_, Nemanja Boric)
21
+ * gem: Can now make reproducible_builds_ when building a deb (`-s gem -t deb`). See the `Deterministic output`_ docs.
22
+ * gem: Add `--gem-embed-dependencies` flag to include in the output package all dependent gems of the target. For example, `fpm -s gem -t rpm --gem-embed-dependencies rails` will create a single `rails` rpm that includes active_support, active_record, etc.
23
+ * pleaserun: Add more flags (`--pleaserun-chdir`, `--pleaserun-user`, etc) to allow more customization of pleaserun services. (`#1311`_; Paulo Sousa)
24
+ * python: Add `--python-setup-py-arguments` flag for passing arbitrary flags to `python setup.py install` (`#1120`_, `#1376`_; Ward Vandewege, Joseph Anthony Pasquale Holsten)
25
+ * rpm: --config-files can now copy files from outside of the package source. This means you can do things like `fpm -s gem -t rpm --config-files etc/my/config` and have `etc/my/config` come from the local filesystem. (`#860`_, `#1379`_; jakerobinson, Joseph Anthony Pasquale Holsten)
26
+ * tar: Only create `.scripts` directory if there are scripts to include (`#1123`_, `#1374`_; Thiago Figueiró)
27
+ * virtualenv: Add `--virtualenv-find-links` flag which appends `--find-links` to the `pip install` command.
28
+ * virtualenv: documentation improvements (Nick Griffiths)
29
+ * virtualenv: Make `--prefix` useful and deprecate `--virtualenv-install-location` (`#1262`_; Nick Griffiths)
30
+ * zip: fix bug in output where the temporary directory would be included in the file listing (`#1313`_, `#1314`_; Bob Vincent)
31
+ * Other: Remove unused archive-tar-minitar as a dependency of fpm (`#1355`_; Diego Martins)
32
+ * Other: Add stud as a runtime dependency (`#1354`_; Elan Ruusamäe)
33
+
34
+ .. _reproducible_builds:: https://reproducible-builds.org/
35
+ .. _path mapping:: http://fpm.readthedocs.io/en/latest/source/dir.html#path-mapping
36
+ .. _Deterministic output:: http://fpm.readthedocs.io/en/latest/source/gem.html
37
+
38
+ 1.9.0 (July 28, 2017)
39
+ ^^^^^^^^^^^^^^^^^^^^^
40
+
41
+ Yanked offline. I forgot some dependency changes. Hi.
42
+
4
43
  1.8.1 (February 7, 2017)
5
44
  ^^^^^^^^^^^^^^^^^^^^^^^^
6
45
  * Pin archive-tar-minitar library to version 0.5.2 to work around a problem breaking `gem install fpm`
@@ -233,6 +233,20 @@ class FPM::Command < Clamp::Command
233
233
  "copying, downloading, etc. Roughly any scratch space fpm needs to build " \
234
234
  "your package.", :default => Dir.tmpdir
235
235
 
236
+ option "--source-date-epoch-from-changelog", :flag,
237
+ "Use release date from changelog as timestamp on generated files to reduce nondeterminism. " \
238
+ "Experimental; only implemented for gem so far. ",
239
+ :default => false
240
+
241
+ option "--source-date-epoch-default", "SOURCE_DATE_EPOCH_DEFAULT",
242
+ "If no release date otherwise specified, use this value as timestamp on generated files to reduce nondeterminism. " \
243
+ "Reproducible build environments such as dpkg-dev and rpmbuild set this via envionment variable SOURCE_DATE_EPOCH " \
244
+ "variable to the integer unix timestamp to use in generated archives, " \
245
+ "and expect tools like fpm to use it as a hint to avoid nondeterministic output. " \
246
+ "This is a Unix timestamp, i.e. number of seconds since 1 Jan 1970 UTC. " \
247
+ "See https://reproducible-builds.org/specs/source-date-epoch ",
248
+ :environment_variable => "SOURCE_DATE_EPOCH"
249
+
236
250
  parameter "[ARGS] ...",
237
251
  "Inputs to the source package type. For the 'dir' type, this is the files" \
238
252
  " and directories you want to include in the package. For others, like " \
@@ -175,8 +175,8 @@ class FPM::Package
175
175
  @directories = []
176
176
  @attrs = {}
177
177
 
178
- staging_path
179
178
  build_path
179
+ # Dont' initialize staging_path just yet, do it lazily so subclass can get a word in.
180
180
  end # def initialize
181
181
 
182
182
  # Get the 'type' for this instance.
@@ -492,6 +492,22 @@ class FPM::Package
492
492
  return scripts.include?(name)
493
493
  end # def script?
494
494
 
495
+ # write all scripts to .scripts (tar and dir)
496
+ def write_scripts
497
+ scripts_path = File.join(staging_path, ".scripts")
498
+ target_scripts = [:before_install, :after_install, :before_remove, :after_remove]
499
+ if target_scripts.any? {|name| script?(name)}
500
+ ::Dir.mkdir(scripts_path)
501
+ target_scripts.each do |name|
502
+ next unless script?(name)
503
+ out = File.join(scripts_path, name.to_s)
504
+ logger.debug('Writing script', :source => name, :target => out)
505
+ File.write(out, script(name))
506
+ File.chmod(0755, out)
507
+ end
508
+ end
509
+ end
510
+
495
511
  # Get the contents of the script by a given name.
496
512
  #
497
513
  # If template_scripts? is set in attributes (often by the --template-scripts
@@ -238,7 +238,7 @@ class FPM::Package::APK< FPM::Package
238
238
  record_length = determine_record_length(record_length)
239
239
 
240
240
  until(data.length == record_length)
241
- data += file.read(TAR_CHUNK_SIZE)
241
+ data << file.read(TAR_CHUNK_SIZE)
242
242
  end
243
243
 
244
244
  # Clear ownership fields
@@ -99,6 +99,12 @@ class FPM::Package::CPAN < FPM::Package
99
99
  self.name = fix_name(metadata["name"])
100
100
  end
101
101
 
102
+ unless metadata["module"].nil?
103
+ metadata["module"].each do |m|
104
+ self.provides << cap_name(m["name"]) + " = #{self.version}"
105
+ end
106
+ end
107
+
102
108
  # author is not always set or it may be a string instead of an array
103
109
  self.vendor = case metadata["author"]
104
110
  when String; metadata["author"]
@@ -150,16 +156,16 @@ class FPM::Package::CPAN < FPM::Package
150
156
  found_dependencies.each do |dep_name, version|
151
157
  # Special case for representing perl core as a version.
152
158
  if dep_name == "perl"
159
+ m = version.match(/^(\d)\.(\d{3})(\d{3})$/)
160
+ if m
161
+ version = m[1] + '.' + m[2].sub(/^0*/, '') + '.' + m[3].sub(/^0*/, '')
162
+ end
153
163
  self.dependencies << "#{dep_name} >= #{version}"
154
164
  next
155
165
  end
156
166
  dep = search(dep_name)
157
167
 
158
- if dep.include?("distribution")
159
- name = fix_name(dep["distribution"])
160
- else
161
- name = fix_name(dep_name)
162
- end
168
+ name = cap_name(dep_name)
163
169
 
164
170
  if version.to_s == "0"
165
171
  # Assume 'Foo = 0' means any version?
@@ -167,12 +173,14 @@ class FPM::Package::CPAN < FPM::Package
167
173
  else
168
174
  # The 'version' string can be something complex like:
169
175
  # ">= 0, != 1.0, != 1.2"
176
+ # If it is not specified explicitly, require the given
177
+ # version or newer, as that is all CPAN itself enforces
170
178
  if version.is_a?(String)
171
179
  version.split(/\s*,\s*/).each do |v|
172
180
  if v =~ /\s*[><=]/
173
181
  self.dependencies << "#{name} #{v}"
174
182
  else
175
- self.dependencies << "#{name} = #{v}"
183
+ self.dependencies << "#{name} >= #{v}"
176
184
  end
177
185
  end
178
186
  else
@@ -259,7 +267,7 @@ class FPM::Package::CPAN < FPM::Package
259
267
  :path => path.gsub(staging_path, ""))
260
268
  File.unlink(path)
261
269
  end
262
-
270
+
263
271
  # Remove useless .packlist files and their empty parent folders
264
272
  # https://github.com/jordansissel/fpm/issues/1179
265
273
  ::Dir.glob(File.join(staging_path, glob_prefix, "**/.packlist")).each do |path|
@@ -315,13 +323,10 @@ class FPM::Package::CPAN < FPM::Package
315
323
  else
316
324
  self.version = "#{cpan_version}"
317
325
  end
318
-
319
- # remove 'v' prefix from version if it is there
320
- self.version.sub!(/^v/, '')
321
-
326
+
322
327
  # Search metacpan to get download URL for this version of the module
323
- metacpan_search_url = "http://api.metacpan.org/v0/release/_search"
324
- metacpan_search_query = '{"query":{"match_all":{}},"filter":{"term":{"release.name":"' + "#{distribution}-#{self.version}" + '"}}}'
328
+ metacpan_search_url = "https://fastapi.metacpan.org/v1/release/_search"
329
+ metacpan_search_query = '{"fields":["download_url"],"filter":{"term":{"name":"' + "#{distribution}-#{self.version}" + '"}}}'
325
330
  begin
326
331
  search_response = httppost(metacpan_search_url,metacpan_search_query)
327
332
  rescue Net::HTTPServerException => e
@@ -333,7 +338,7 @@ class FPM::Package::CPAN < FPM::Package
333
338
  data = search_response.body
334
339
  release_metadata = JSON.parse(data)
335
340
 
336
- download_url = release_metadata['hits']['hits'][0]['_source']['download_url']
341
+ download_url = release_metadata['hits']['hits'][0]['fields']['download_url']
337
342
  download_path = URI.parse(download_url).path
338
343
  tarball = File.basename(download_path)
339
344
 
@@ -361,7 +366,7 @@ class FPM::Package::CPAN < FPM::Package
361
366
 
362
367
  def search(package)
363
368
  logger.info("Asking metacpan about a module", :module => package)
364
- metacpan_url = "http://api.metacpan.org/v0/module/" + package
369
+ metacpan_url = "https://fastapi.metacpan.org/v1/module/" + package
365
370
  begin
366
371
  response = httpfetch(metacpan_url)
367
372
  rescue Net::HTTPServerException => e
@@ -379,6 +384,10 @@ class FPM::Package::CPAN < FPM::Package
379
384
  return metadata
380
385
  end # def metadata
381
386
 
387
+ def cap_name(name)
388
+ return "perl(" + name.gsub("-", "::") + ")"
389
+ end # def cap_name
390
+
382
391
  def fix_name(name)
383
392
  case name
384
393
  when "perl"; return "perl"
@@ -394,6 +403,7 @@ class FPM::Package::CPAN < FPM::Package
394
403
  else
395
404
  http = Net::HTTP.new(uri.host, uri.port)
396
405
  end
406
+ http.use_ssl = uri.scheme == 'https'
397
407
  response = http.request(Net::HTTP::Get.new(uri.request_uri))
398
408
  case response
399
409
  when Net::HTTPSuccess; return response
@@ -410,6 +420,7 @@ class FPM::Package::CPAN < FPM::Package
410
420
  else
411
421
  http = Net::HTTP.new(uri.host, uri.port)
412
422
  end
423
+ http.use_ssl = uri.scheme == 'https'
413
424
  response = http.post(uri.request_uri, body)
414
425
  case response
415
426
  when Net::HTTPSuccess; return response
@@ -18,6 +18,7 @@ class FPM::Package::Deb < FPM::Package
18
18
  :after_install => "postinst",
19
19
  :before_remove => "prerm",
20
20
  :after_remove => "postrm",
21
+ :after_purge => "postrm",
21
22
  } unless defined?(SCRIPT_MAP)
22
23
 
23
24
  # The list of supported compression types. Default is gz (gzip)
@@ -121,6 +122,18 @@ class FPM::Package::Deb < FPM::Package
121
122
  next @activated_triggers
122
123
  end
123
124
 
125
+ option "--interest-noawait", "EVENT", "Package is interested in EVENT trigger without awaiting" do |event|
126
+ @interested_noawait_triggers ||= []
127
+ @interested_noawait_triggers << event
128
+ next @interested_noawait_triggers
129
+ end
130
+
131
+ option "--activate-noawait", "EVENT", "Package activates EVENT trigger" do |event|
132
+ @activated_noawait_triggers ||= []
133
+ @activated_noawait_triggers << event
134
+ next @activated_noawait_triggers
135
+ end
136
+
124
137
  option "--field", "'FIELD: VALUE'", "Add custom field to the control file" do |fv|
125
138
  @custom_fields ||= {}
126
139
  field, value = fv.split(/: */, 2)
@@ -164,6 +177,12 @@ class FPM::Package::Deb < FPM::Package
164
177
 
165
178
  option "--systemd-restart-after-upgrade", :flag , "Restart service after upgrade", :default => true
166
179
 
180
+ option "--after-purge", "FILE",
181
+ "A script to be run after package removal to purge remaining (config) files " \
182
+ "(a.k.a. postrm purge within apt-get purge)" do |val|
183
+ File.expand_path(val) # Get the full path to the script
184
+ end # --after-purge
185
+
167
186
  def initialize(*args)
168
187
  super(*args)
169
188
  attributes[:deb_priority] = "extra"
@@ -243,7 +262,7 @@ class FPM::Package::Deb < FPM::Package
243
262
  build_path("control").tap do |path|
244
263
  FileUtils.mkdir(path) if !File.directory?(path)
245
264
  # Unpack the control tarball
246
- safesystem("ar p #{package} control.tar.gz | tar -zxf - -C #{path}")
265
+ safesystem(ar_cmd[0] + " p #{package} control.tar.gz | tar -zxf - -C #{path}")
247
266
 
248
267
  control = File.read(File.join(path, "control"))
249
268
 
@@ -340,7 +359,7 @@ class FPM::Package::Deb < FPM::Package
340
359
 
341
360
  def extract_files(package)
342
361
  # Find out the compression type
343
- compression = `ar t #{package}`.split("\n").grep(/data.tar/).first.split(".").last
362
+ compression = `#{ar_cmd[0]} t #{package}`.split("\n").grep(/data.tar/).first.split(".").last
344
363
  case compression
345
364
  when "gz"
346
365
  datatar = "data.tar.gz"
@@ -358,7 +377,7 @@ class FPM::Package::Deb < FPM::Package
358
377
  end
359
378
 
360
379
  # unpack the data.tar.{gz,bz2,xz} from the deb package into staging_path
361
- safesystem("ar p #{package} #{datatar} " \
380
+ safesystem(ar_cmd[0] + " p #{package} #{datatar} " \
362
381
  "| tar #{compression} -xf - -C #{staging_path}")
363
382
  end # def extract_files
364
383
 
@@ -387,6 +406,22 @@ class FPM::Package::Deb < FPM::Package
387
406
  end
388
407
  end
389
408
 
409
+ if attributes[:source_date_epoch].nil? and not attributes[:source_date_epoch_default].nil?
410
+ attributes[:source_date_epoch] = attributes[:source_date_epoch_default]
411
+ end
412
+ if attributes[:source_date_epoch] == "0"
413
+ logger.error("Alas, ruby's Zlib::GzipWriter does not support setting an mtime of zero. Aborting.")
414
+ raise "#{name}: source_date_epoch of 0 not supported."
415
+ end
416
+ if not attributes[:source_date_epoch].nil? and not ar_cmd_deterministic?
417
+ logger.error("Alas, could not find an ar that can handle -D option. Try installing recent gnu binutils. Aborting.")
418
+ raise "#{name}: ar is insufficient to support source_date_epoch."
419
+ end
420
+ if not attributes[:source_date_epoch].nil? and not tar_cmd_supports_sort_names_and_set_mtime?
421
+ logger.error("Alas, could not find a tar that can set mtime and sort. Try installing recent gnu tar. Aborting.")
422
+ raise "#{name}: tar is insufficient to support source_date_epoch."
423
+ end
424
+
390
425
  attributes.fetch(:deb_systemd_list, []).each do |systemd|
391
426
  name = File.basename(systemd, ".service")
392
427
  dest_systemd = staging_path("lib/systemd/system/#{name}.service")
@@ -412,24 +447,9 @@ class FPM::Package::Deb < FPM::Package
412
447
  if script?(:after_remove)
413
448
  scripts[:after_remove] = template("deb/postrm_upgrade.sh.erb").result(binding)
414
449
  end
415
- end
416
-
417
- write_control_tarball
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]}'"
450
+ if script?(:after_purge)
451
+ scripts[:after_purge] = template("deb/postrm_upgrade.sh.erb").result(binding)
452
+ end
433
453
  end
434
454
 
435
455
  # There are two changelogs that may appear:
@@ -442,6 +462,9 @@ class FPM::Package::Deb < FPM::Package
442
462
  mkdir_p(File.dirname(dest_changelog))
443
463
  File.new(dest_changelog, "wb", 0644).tap do |changelog|
444
464
  Zlib::GzipWriter.new(changelog, Zlib::BEST_COMPRESSION).tap do |changelog_gz|
465
+ if not attributes[:source_date_epoch].nil?
466
+ changelog_gz.mtime = attributes[:source_date_epoch].to_i
467
+ end
445
468
  if attributes[:deb_changelog]
446
469
  logger.info("Writing user-specified changelog", :source => attributes[:deb_changelog])
447
470
  File.new(attributes[:deb_changelog]).tap do |fd|
@@ -461,6 +484,9 @@ class FPM::Package::Deb < FPM::Package
461
484
  if attributes[:deb_upstream_changelog]
462
485
  File.new(dest_upstream_changelog, "wb", 0644).tap do |changelog|
463
486
  Zlib::GzipWriter.new(changelog, Zlib::BEST_COMPRESSION).tap do |changelog_gz|
487
+ if not attributes[:source_date_epoch].nil?
488
+ changelog_gz.mtime = attributes[:source_date_epoch].to_i
489
+ end
464
490
  logger.info("Writing user-specified upstream changelog", :source => attributes[:deb_upstream_changelog])
465
491
  File.new(attributes[:deb_upstream_changelog]).tap do |fd|
466
492
  chunk = nil
@@ -494,6 +520,7 @@ class FPM::Package::Deb < FPM::Package
494
520
 
495
521
  attributes.fetch(:deb_upstart_list, []).each do |upstart|
496
522
  name = File.basename(upstart, ".upstart")
523
+ dest_init = staging_path("etc/init.d/#{name}")
497
524
  name = "#{name}.conf" if !(name =~ /\.conf$/)
498
525
  dest_upstart = staging_path("etc/init/#{name}")
499
526
  mkdir_p(File.dirname(dest_upstart))
@@ -501,7 +528,6 @@ class FPM::Package::Deb < FPM::Package
501
528
  File.chmod(0644, dest_upstart)
502
529
 
503
530
  # Install an init.d shim that calls upstart
504
- dest_init = staging_path("etc/init.d/#{name}")
505
531
  mkdir_p(File.dirname(dest_init))
506
532
  FileUtils.ln_s("/lib/init/upstart-job", dest_init)
507
533
  end
@@ -533,13 +559,19 @@ class FPM::Package::Deb < FPM::Package
533
559
  end
534
560
 
535
561
  args = [ tar_cmd, "-C", staging_path, compression ] + data_tar_flags + [ "-cf", datatar, "." ]
562
+ if tar_cmd_supports_sort_names_and_set_mtime? and not attributes[:source_date_epoch].nil?
563
+ # Use gnu tar options to force deterministic file order and timestamp
564
+ args += ["--sort=name", ("--mtime=@%s" % attributes[:source_date_epoch])]
565
+ # gnu tar obeys GZIP environment variable with options for gzip; -n = forget original filename and date
566
+ args.unshift({"GZIP" => "-9n"})
567
+ end
536
568
  safesystem(*args)
537
569
 
538
570
  # pack up the .deb, which is just an 'ar' archive with 3 files
539
571
  # the 'debian-binary' file has to be first
540
572
  File.expand_path(output_path).tap do |output_path|
541
573
  ::Dir.chdir(build_path) do
542
- safesystem("ar", "-qc", output_path, "debian-binary", "control.tar.gz", datatar)
574
+ safesystem(*ar_cmd, output_path, "debian-binary", "control.tar.gz", datatar)
543
575
  end
544
576
  end
545
577
  end # def output
@@ -693,6 +725,12 @@ class FPM::Package::Deb < FPM::Package
693
725
 
694
726
  args = [ tar_cmd, "-C", control_path, "-zcf", controltar,
695
727
  "--owner=0", "--group=0", "--numeric-owner", "." ]
728
+ if tar_cmd_supports_sort_names_and_set_mtime? and not attributes[:source_date_epoch].nil?
729
+ # Force deterministic file order and timestamp
730
+ args += ["--sort=name", ("--mtime=@%s" % attributes[:source_date_epoch])]
731
+ # gnu tar obeys GZIP environment variable with options for gzip; -n = forget original filename and date
732
+ args.unshift({"GZIP" => "-9n"})
733
+ end
696
734
  safesystem(*args)
697
735
  end
698
736
 
@@ -865,7 +903,10 @@ class FPM::Package::Deb < FPM::Package
865
903
 
866
904
  def write_triggers
867
905
  lines = [['interest', :deb_interest],
868
- ['activate', :deb_activate]].map { |label, attr|
906
+ ['activate', :deb_activate],
907
+ ['interest-noawait', :deb_interest_noawait],
908
+ ['activate-noawait', :deb_activate_noawait],
909
+ ].map { |label, attr|
869
910
  (attributes[attr] || []).map { |e| "#{label} #{e}\n" }
870
911
  }.flatten.join('')
871
912
 
@@ -101,18 +101,7 @@ class FPM::Package::Dir < FPM::Package
101
101
  end
102
102
 
103
103
  # Write the scripts, too.
104
- scripts_path = File.join(output_path, ".scripts")
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,19 @@ class FPM::Package::Dir < FPM::Package
147
136
 
148
137
  # For single file copies, permit file destinations
149
138
  fileinfo = File.lstat(source)
150
- if fileinfo.file? && !File.directory?(destination)
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
- copy(source, File.join(destination, source))
147
+ if destination_is_directory
148
+ copy(source, File.join(destination, source))
149
+ else
150
+ copy(source, destination)
151
+ end
158
152
  else
159
153
  # Copy all files from 'path' into staging_path
160
154
  Find.find(source) do |path|