fpm 1.8.1 → 1.9.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 +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|
|