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 +4 -4
- data/CHANGELOG.rst +39 -0
- data/lib/fpm/command.rb +14 -0
- data/lib/fpm/package.rb +17 -1
- data/lib/fpm/package/apk.rb +1 -1
- data/lib/fpm/package/cpan.rb +26 -15
- data/lib/fpm/package/deb.rb +65 -24
- data/lib/fpm/package/dir.rb +8 -14
- data/lib/fpm/package/gem.rb +110 -2
- data/lib/fpm/package/pleaserun.rb +12 -2
- data/lib/fpm/package/python.rb +11 -0
- data/lib/fpm/package/rpm.rb +9 -0
- data/lib/fpm/package/tar.rb +1 -9
- data/lib/fpm/package/virtualenv.rb +28 -6
- data/lib/fpm/package/zip.rb +5 -21
- data/lib/fpm/util.rb +88 -18
- data/lib/fpm/version.rb +1 -1
- data/templates/deb/changelog.erb +1 -1
- data/templates/deb/postrm_upgrade.sh.erb +12 -5
- metadata +49 -62
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b9fb4eab81222c77d6790e9e06c8348744a020e7
|
4
|
+
data.tar.gz: a29942bc9fcc9dcbe6bf0f4d1fbfa431d202eb2b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c97a69b63e17f684c7f481bda43e479d34a030e253b0a7294de356eaf1a35dc83b230deec5cf77270ff17756b98b8336016588be3ea41317ec354bd56649c1e8
|
7
|
+
data.tar.gz: a3708d970c1d1b6d4d384893f7c596b5fad2ea6d4eb01e0baa42bec1de3bbb85286f3d5acab9823928cf00bb04f59c98247d307269f04fe01bae824f387e59cf
|
data/CHANGELOG.rst
CHANGED
@@ -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`
|
data/lib/fpm/command.rb
CHANGED
@@ -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 " \
|
data/lib/fpm/package.rb
CHANGED
@@ -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
|
data/lib/fpm/package/apk.rb
CHANGED
@@ -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
|
241
|
+
data << file.read(TAR_CHUNK_SIZE)
|
242
242
|
end
|
243
243
|
|
244
244
|
# Clear ownership fields
|
data/lib/fpm/package/cpan.rb
CHANGED
@@ -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
|
-
|
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}
|
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 = "
|
324
|
-
metacpan_search_query = '{"
|
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]['
|
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 = "
|
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
|
data/lib/fpm/package/deb.rb
CHANGED
@@ -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("
|
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 =
|
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("
|
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
|
-
|
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]}'"
|
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(
|
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]
|
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
|
|
data/lib/fpm/package/dir.rb
CHANGED
@@ -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,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
|
-
|
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
|
+
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|
|