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/CONTRIBUTORS
CHANGED
@@ -20,6 +20,8 @@ llasram
|
|
20
20
|
sbuss
|
21
21
|
Brett Gailey (github: dnbert)
|
22
22
|
Daniel Haskin (github: djhaskin987)
|
23
|
+
Richard Grainger (github: liger1978)
|
24
|
+
seph (github: directionless)
|
23
25
|
|
24
26
|
If you have contributed (bug reports, feature requests, help in IRC, blog
|
25
27
|
posts, code, etc) and aren't listed here, please let me know if you wish to be
|
data/LICENSE
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
(This is an MIT-style license)
|
2
2
|
|
3
|
-
Copyright (c) 2011-
|
3
|
+
Copyright (c) 2011-2021 Jordan Sissel and contributors.
|
4
4
|
|
5
5
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
6
|
of this software and associated documentation files (the "Software"), to deal
|
data/bin/fpm
CHANGED
data/lib/fpm/command.rb
CHANGED
@@ -45,13 +45,13 @@ class FPM::Command < Clamp::Command
|
|
45
45
|
return lines.join("\n")
|
46
46
|
end # def help
|
47
47
|
|
48
|
-
option "-t", "OUTPUT_TYPE",
|
48
|
+
option ["-t", "--output-type"], "OUTPUT_TYPE",
|
49
49
|
"the type of package you want to create (deb, rpm, solaris, etc)",
|
50
50
|
:attribute_name => :output_type
|
51
|
-
option "-s", "INPUT_TYPE",
|
51
|
+
option ["-s", "--input-type"], "INPUT_TYPE",
|
52
52
|
"the package type to use as input (gem, rpm, python, etc)",
|
53
53
|
:attribute_name => :input_type
|
54
|
-
option "-C", "CHDIR",
|
54
|
+
option ["-C", "--chdir"], "CHDIR",
|
55
55
|
"Change directory to here before searching for files",
|
56
56
|
:attribute_name => :chdir
|
57
57
|
option "--prefix", "PREFIX",
|
@@ -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 " \
|
@@ -256,12 +270,6 @@ class FPM::Command < Clamp::Command
|
|
256
270
|
|
257
271
|
# Execute this command. See Clamp::Command#execute and Clamp's documentation
|
258
272
|
def execute
|
259
|
-
# Short-circuit if someone simply runs `fpm --version`
|
260
|
-
if ARGV == [ "--version" ]
|
261
|
-
puts FPM::VERSION
|
262
|
-
return 0
|
263
|
-
end
|
264
|
-
|
265
273
|
logger.level = :warn
|
266
274
|
logger.level = :info if verbose? # --verbose
|
267
275
|
logger.level = :debug if debug? # --debug
|
@@ -269,7 +277,6 @@ class FPM::Command < Clamp::Command
|
|
269
277
|
logger.level = log_level.to_sym
|
270
278
|
end
|
271
279
|
|
272
|
-
|
273
280
|
if (stray_flags = args.grep(/^-/); stray_flags.any?)
|
274
281
|
logger.warn("All flags should be before the first argument " \
|
275
282
|
"(stray flags found: #{stray_flags}")
|
@@ -514,9 +521,16 @@ class FPM::Command < Clamp::Command
|
|
514
521
|
end
|
515
522
|
end # def execute
|
516
523
|
|
517
|
-
def run(
|
524
|
+
def run(run_args)
|
518
525
|
logger.subscribe(STDOUT)
|
519
526
|
|
527
|
+
# Short circuit for a `fpm --version` or `fpm -v` short invocation that
|
528
|
+
# is the user asking us for the version of fpm.
|
529
|
+
if run_args == [ "-v" ] || run_args == [ "--version" ]
|
530
|
+
puts FPM::VERSION
|
531
|
+
return 0
|
532
|
+
end
|
533
|
+
|
520
534
|
# fpm initialization files, note the order of the following array is
|
521
535
|
# important, try .fpm in users home directory first and then the current
|
522
536
|
# directory
|
@@ -557,7 +571,7 @@ class FPM::Command < Clamp::Command
|
|
557
571
|
|
558
572
|
ARGV.unshift(*flags)
|
559
573
|
ARGV.push(*args)
|
560
|
-
super(
|
574
|
+
super(run_args)
|
561
575
|
rescue FPM::Package::InvalidArgument => e
|
562
576
|
logger.error("Invalid package argument: #{e}")
|
563
577
|
return 1
|
data/lib/fpm/package/apk.rb
CHANGED
@@ -3,12 +3,12 @@ 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
9
|
require 'digest/sha1'
|
10
10
|
|
11
|
-
# Support for
|
11
|
+
# Support for Alpine packages (.apk files)
|
12
12
|
#
|
13
13
|
# This class supports both input and output of packages.
|
14
14
|
class FPM::Package::APK< FPM::Package
|
@@ -144,9 +144,9 @@ class FPM::Package::APK< FPM::Package
|
|
144
144
|
scripts = {}
|
145
145
|
|
146
146
|
scripts = register_script('post-install', :after_install, scripts)
|
147
|
-
scripts = register_script('
|
148
|
-
scripts = register_script('
|
149
|
-
scripts = register_script('post-
|
147
|
+
scripts = register_script('pre-install', :before_install, scripts)
|
148
|
+
scripts = register_script('pre-upgrade', :before_upgrade, scripts)
|
149
|
+
scripts = register_script('post-upgrade', :after_upgrade, scripts)
|
150
150
|
scripts = register_script('pre-deinstall', :before_remove, scripts)
|
151
151
|
scripts = register_script('post-deinstall', :after_remove, scripts)
|
152
152
|
|
@@ -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
@@ -3,6 +3,7 @@ require "fpm/package"
|
|
3
3
|
require "fpm/util"
|
4
4
|
require "fileutils"
|
5
5
|
require "find"
|
6
|
+
require "pathname"
|
6
7
|
|
7
8
|
class FPM::Package::CPAN < FPM::Package
|
8
9
|
# Flags '--foo' will be accessable as attributes[:npm_foo]
|
@@ -24,6 +25,9 @@ class FPM::Package::CPAN < FPM::Package
|
|
24
25
|
option "--test", :flag,
|
25
26
|
"Run the tests before packaging?", :default => true
|
26
27
|
|
28
|
+
option "--verbose", :flag,
|
29
|
+
"Produce verbose output from cpanm?", :default => false
|
30
|
+
|
27
31
|
option "--perl-lib-path", "PERL_LIB_PATH",
|
28
32
|
"Path of target Perl Libraries"
|
29
33
|
|
@@ -48,6 +52,7 @@ class FPM::Package::CPAN < FPM::Package
|
|
48
52
|
|
49
53
|
if File.exist?(package)
|
50
54
|
moduledir = package
|
55
|
+
result = {}
|
51
56
|
else
|
52
57
|
result = search(package)
|
53
58
|
tarball = download(result, version)
|
@@ -97,6 +102,12 @@ class FPM::Package::CPAN < FPM::Package
|
|
97
102
|
self.name = fix_name(metadata["name"])
|
98
103
|
end
|
99
104
|
|
105
|
+
unless metadata["module"].nil?
|
106
|
+
metadata["module"].each do |m|
|
107
|
+
self.provides << cap_name(m["name"]) + " = #{self.version}"
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
100
111
|
# author is not always set or it may be a string instead of an array
|
101
112
|
self.vendor = case metadata["author"]
|
102
113
|
when String; metadata["author"]
|
@@ -129,24 +140,36 @@ class FPM::Package::CPAN < FPM::Package
|
|
129
140
|
cpanm_flags += ["--mirror", "#{attributes[:cpan_mirror]}"] if !attributes[:cpan_mirror].nil?
|
130
141
|
cpanm_flags += ["--mirror-only"] if attributes[:cpan_mirror_only?] && !attributes[:cpan_mirror].nil?
|
131
142
|
cpanm_flags += ["--force"] if attributes[:cpan_cpanm_force?]
|
143
|
+
cpanm_flags += ["--verbose"] if attributes[:cpan_verbose?]
|
132
144
|
|
133
145
|
safesystem(attributes[:cpan_cpanm_bin], *cpanm_flags)
|
134
146
|
|
135
147
|
if !attributes[:no_auto_depends?]
|
136
|
-
|
137
|
-
|
148
|
+
found_dependencies = {}
|
149
|
+
if metadata["requires"]
|
150
|
+
found_dependencies.merge!(metadata["requires"])
|
151
|
+
end
|
152
|
+
if metadata["prereqs"]
|
153
|
+
if metadata["prereqs"]["runtime"]
|
154
|
+
if metadata["prereqs"]["runtime"]["requires"]
|
155
|
+
found_dependencies.merge!(metadata["prereqs"]["runtime"]["requires"])
|
156
|
+
end
|
157
|
+
end
|
158
|
+
end
|
159
|
+
unless found_dependencies.empty?
|
160
|
+
found_dependencies.each do |dep_name, version|
|
138
161
|
# Special case for representing perl core as a version.
|
139
162
|
if dep_name == "perl"
|
163
|
+
m = version.to_s.match(/^(\d)\.(\d{3})(\d{3})$/)
|
164
|
+
if m
|
165
|
+
version = m[1] + '.' + m[2].sub(/^0*/, '') + '.' + m[3].sub(/^0*/, '')
|
166
|
+
end
|
140
167
|
self.dependencies << "#{dep_name} >= #{version}"
|
141
168
|
next
|
142
169
|
end
|
143
170
|
dep = search(dep_name)
|
144
171
|
|
145
|
-
|
146
|
-
name = fix_name(dep["distribution"])
|
147
|
-
else
|
148
|
-
name = fix_name(dep_name)
|
149
|
-
end
|
172
|
+
name = cap_name(dep_name)
|
150
173
|
|
151
174
|
if version.to_s == "0"
|
152
175
|
# Assume 'Foo = 0' means any version?
|
@@ -154,12 +177,14 @@ class FPM::Package::CPAN < FPM::Package
|
|
154
177
|
else
|
155
178
|
# The 'version' string can be something complex like:
|
156
179
|
# ">= 0, != 1.0, != 1.2"
|
180
|
+
# If it is not specified explicitly, require the given
|
181
|
+
# version or newer, as that is all CPAN itself enforces
|
157
182
|
if version.is_a?(String)
|
158
183
|
version.split(/\s*,\s*/).each do |v|
|
159
184
|
if v =~ /\s*[><=]/
|
160
185
|
self.dependencies << "#{name} #{v}"
|
161
186
|
else
|
162
|
-
self.dependencies << "#{name}
|
187
|
+
self.dependencies << "#{name} >= #{v}"
|
163
188
|
end
|
164
189
|
end
|
165
190
|
else
|
@@ -220,11 +245,7 @@ class FPM::Package::CPAN < FPM::Package
|
|
220
245
|
# Empty install_base to avoid local::lib being used.
|
221
246
|
"INSTALL_BASE=")
|
222
247
|
end
|
223
|
-
|
224
|
-
make = [ "env", "PERL5LIB=#{build_path("cpan/lib/perl5")}", "make" ]
|
225
|
-
else
|
226
|
-
make = [ "make" ]
|
227
|
-
end
|
248
|
+
make = [ "env", "PERL5LIB=#{build_path("cpan/lib/perl5")}", "make" ]
|
228
249
|
safesystem(*make)
|
229
250
|
safesystem(*(make + ["test"])) if attributes[:cpan_test?]
|
230
251
|
safesystem(*(make + ["DESTDIR=#{staging_path}", "install"]))
|
@@ -246,6 +267,21 @@ class FPM::Package::CPAN < FPM::Package
|
|
246
267
|
:path => path.gsub(staging_path, ""))
|
247
268
|
File.unlink(path)
|
248
269
|
end
|
270
|
+
|
271
|
+
# Remove useless .packlist files and their empty parent folders
|
272
|
+
# https://github.com/jordansissel/fpm/issues/1179
|
273
|
+
::Dir.glob(File.join(staging_path, glob_prefix, "**/.packlist")).each do |path|
|
274
|
+
logger.debug("Removing useless file.",
|
275
|
+
:path => path.gsub(staging_path, ""))
|
276
|
+
File.unlink(path)
|
277
|
+
Pathname.new(path).parent.ascend do |parent|
|
278
|
+
if ::Dir.entries(parent).sort == ['.', '..'].sort
|
279
|
+
FileUtils.rmdir parent
|
280
|
+
else
|
281
|
+
break
|
282
|
+
end
|
283
|
+
end
|
284
|
+
end
|
249
285
|
end
|
250
286
|
|
251
287
|
|
@@ -281,38 +317,35 @@ class FPM::Package::CPAN < FPM::Package
|
|
281
317
|
:distribution => distribution,
|
282
318
|
:version => cpan_version)
|
283
319
|
|
284
|
-
# default to latest
|
320
|
+
# default to latest version unless we specify one
|
285
321
|
if cpan_version.nil?
|
286
|
-
self.version = metadata["version"]
|
322
|
+
self.version = "#{metadata["version"]}"
|
287
323
|
else
|
288
|
-
|
289
|
-
self.version = "v#{cpan_version}"
|
290
|
-
else
|
291
|
-
self.version = cpan_version
|
292
|
-
end
|
324
|
+
self.version = "#{cpan_version}"
|
293
325
|
end
|
294
326
|
|
295
|
-
|
327
|
+
# Search metacpan to get download URL for this version of the module
|
328
|
+
metacpan_search_url = "https://fastapi.metacpan.org/v1/release/_search"
|
329
|
+
metacpan_search_query = '{"fields":["download_url"],"filter":{"term":{"name":"' + "#{distribution}-#{self.version}" + '"}}}'
|
296
330
|
begin
|
297
|
-
|
331
|
+
search_response = httppost(metacpan_search_url,metacpan_search_query)
|
298
332
|
rescue Net::HTTPServerException => e
|
299
333
|
logger.error("metacpan release query failed.", :error => e.message,
|
300
|
-
:url =>
|
334
|
+
:url => metacpan_search_url)
|
301
335
|
raise FPM::InvalidPackageConfiguration, "metacpan release query failed"
|
302
336
|
end
|
303
337
|
|
304
|
-
data =
|
338
|
+
data = search_response.body
|
305
339
|
release_metadata = JSON.parse(data)
|
306
|
-
archive = release_metadata["archive"]
|
307
340
|
|
308
|
-
|
309
|
-
|
341
|
+
download_url = release_metadata['hits']['hits'][0]['fields']['download_url']
|
342
|
+
download_path = URI.parse(download_url).path
|
343
|
+
tarball = File.basename(download_path)
|
310
344
|
|
311
345
|
url_base = "http://www.cpan.org/"
|
312
346
|
url_base = "#{attributes[:cpan_mirror]}" if !attributes[:cpan_mirror].nil?
|
313
347
|
|
314
|
-
|
315
|
-
url = "#{url_base}/authors/id/#{author[0,1]}/#{author[0,2]}/#{author}/#{archive}"
|
348
|
+
url = "#{url_base}#{download_path}"
|
316
349
|
logger.debug("Fetching perl module", :url => url)
|
317
350
|
|
318
351
|
begin
|
@@ -333,7 +366,7 @@ class FPM::Package::CPAN < FPM::Package
|
|
333
366
|
|
334
367
|
def search(package)
|
335
368
|
logger.info("Asking metacpan about a module", :module => package)
|
336
|
-
metacpan_url = "
|
369
|
+
metacpan_url = "https://fastapi.metacpan.org/v1/module/" + package
|
337
370
|
begin
|
338
371
|
response = httpfetch(metacpan_url)
|
339
372
|
rescue Net::HTTPServerException => e
|
@@ -351,6 +384,10 @@ class FPM::Package::CPAN < FPM::Package
|
|
351
384
|
return metadata
|
352
385
|
end # def metadata
|
353
386
|
|
387
|
+
def cap_name(name)
|
388
|
+
return "perl(" + name.gsub("-", "::") + ")"
|
389
|
+
end # def cap_name
|
390
|
+
|
354
391
|
def fix_name(name)
|
355
392
|
case name
|
356
393
|
when "perl"; return "perl"
|
@@ -366,6 +403,7 @@ class FPM::Package::CPAN < FPM::Package
|
|
366
403
|
else
|
367
404
|
http = Net::HTTP.new(uri.host, uri.port)
|
368
405
|
end
|
406
|
+
http.use_ssl = uri.scheme == 'https'
|
369
407
|
response = http.request(Net::HTTP::Get.new(uri.request_uri))
|
370
408
|
case response
|
371
409
|
when Net::HTTPSuccess; return response
|
@@ -374,5 +412,22 @@ class FPM::Package::CPAN < FPM::Package
|
|
374
412
|
end
|
375
413
|
end
|
376
414
|
|
415
|
+
def httppost(url, body)
|
416
|
+
uri = URI.parse(url)
|
417
|
+
if ENV['http_proxy']
|
418
|
+
proxy = URI.parse(ENV['http_proxy'])
|
419
|
+
http = Net::HTTP.Proxy(proxy.host,proxy.port,proxy.user,proxy.password).new(uri.host, uri.port)
|
420
|
+
else
|
421
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
422
|
+
end
|
423
|
+
http.use_ssl = uri.scheme == 'https'
|
424
|
+
response = http.post(uri.request_uri, body)
|
425
|
+
case response
|
426
|
+
when Net::HTTPSuccess; return response
|
427
|
+
when Net::HTTPRedirection; return httppost(response["location"])
|
428
|
+
else; response.error!
|
429
|
+
end
|
430
|
+
end
|
431
|
+
|
377
432
|
public(:input)
|
378
433
|
end # class FPM::Package::NPM
|