fpm 1.15.1 → 1.17.0
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 +30 -0
- data/lib/fpm/command.rb +10 -2
- data/lib/fpm/package/deb.rb +102 -18
- data/lib/fpm/package/dir.rb +0 -4
- data/lib/fpm/package/freebsd.rb +23 -11
- data/lib/fpm/package/pacman.rb +8 -4
- data/lib/fpm/package/pyfpm/parse_requires.py +24 -0
- data/lib/fpm/package/python.rb +404 -170
- data/lib/fpm/package/rpm.rb +45 -5
- data/lib/fpm/package/virtualenv.rb +26 -2
- data/lib/fpm/package.rb +0 -1
- data/lib/fpm/rake_task.rb +30 -4
- data/lib/fpm/util.rb +33 -16
- data/lib/fpm/version.rb +1 -1
- data/templates/rpm.erb +1 -1
- metadata +10 -12
data/lib/fpm/package/rpm.rb
CHANGED
@@ -156,7 +156,7 @@ class FPM::Package::RPM < FPM::Package
|
|
156
156
|
|
157
157
|
option "--macro-expansion", :flag,
|
158
158
|
"install-time macro expansion in %pre %post %preun %postun scripts " \
|
159
|
-
"(see: https://rpm.
|
159
|
+
"(see: https://rpm-software-management.github.io/rpm/manual/scriptlet_expansion.html)", :default => false
|
160
160
|
|
161
161
|
option "--verifyscript", "FILE",
|
162
162
|
"a script to be run on verification" do |val|
|
@@ -175,7 +175,7 @@ class FPM::Package::RPM < FPM::Package
|
|
175
175
|
rpm_trigger = []
|
176
176
|
option "--trigger-#{trigger_type}", "'[OPT]PACKAGE: FILEPATH'", "Adds a rpm trigger script located in FILEPATH, " \
|
177
177
|
"having 'OPT' options and linking to 'PACKAGE'. PACKAGE can be a comma seperated list of packages. " \
|
178
|
-
"See:
|
178
|
+
"See: https://rpm-software-management.github.io/rpm/manual/triggers.html" do |trigger|
|
179
179
|
match = trigger.match(/^(\[.*\]|)(.*): (.*)$/)
|
180
180
|
@logger.fatal("Trigger '#{trigger_type}' definition can't be parsed ('#{trigger}')") unless match
|
181
181
|
opt, pkg, file = match.captures
|
@@ -185,6 +185,9 @@ class FPM::Package::RPM < FPM::Package
|
|
185
185
|
end
|
186
186
|
end
|
187
187
|
|
188
|
+
option "--old-perl-dependency-name", :flag,
|
189
|
+
"Use older 'perl' depdency name. Newer Red Hat (and derivatives) use a dependency named 'perl-interpreter'."
|
190
|
+
|
188
191
|
private
|
189
192
|
|
190
193
|
# Fix path name
|
@@ -196,8 +199,8 @@ class FPM::Package::RPM < FPM::Package
|
|
196
199
|
# If and only if any of the above are done, then also replace ' with \', " with \", and \ with \\\\
|
197
200
|
# to accommodate escape and quote processing that rpm will perform in that case (but not otherwise)
|
198
201
|
def rpm_fix_name(name)
|
199
|
-
if name.match?(/[ \t
|
200
|
-
name = name.gsub(/(\ |\t|\[|\]|\*|\?|\%|\$|'|"|\\)/, {
|
202
|
+
if name.match?(/[ \t*?%${}\[\]]/)
|
203
|
+
name = name.gsub(/(\ |\t|\[|\]|\*|\?|\%|\$|'|"|\{|\}|\\)/, {
|
201
204
|
' ' => '?',
|
202
205
|
"\t" => '?',
|
203
206
|
'%' => '[%]',
|
@@ -206,6 +209,10 @@ class FPM::Package::RPM < FPM::Package
|
|
206
209
|
'*' => '[*]',
|
207
210
|
'[' => '[\[]',
|
208
211
|
']' => '[\]]',
|
212
|
+
#'{' => '[\{]',
|
213
|
+
#'}' => '[\}]',
|
214
|
+
'{' => '?',
|
215
|
+
'}' => '?',
|
209
216
|
'"' => '\\"',
|
210
217
|
"'" => "\\'",
|
211
218
|
'\\' => '\\\\\\\\',
|
@@ -275,9 +282,41 @@ class FPM::Package::RPM < FPM::Package
|
|
275
282
|
return @iteration ? @iteration : 1
|
276
283
|
end # def iteration
|
277
284
|
|
285
|
+
# Generate a generic changelog or return an existing definition
|
286
|
+
def changelog
|
287
|
+
if attributes[:rpm_changelog]
|
288
|
+
return attributes[:rpm_changelog]
|
289
|
+
end
|
290
|
+
|
291
|
+
reldate = if attributes[:source_date_epoch].nil?
|
292
|
+
Time.now()
|
293
|
+
else
|
294
|
+
Time.at(attributes[:source_date_epoch].to_i)
|
295
|
+
end
|
296
|
+
changed = reldate.strftime("%a %b %_e %Y")
|
297
|
+
changev = "#{version}-#{iteration}"
|
298
|
+
changev += "%{?dist}" if attributes[:rpm_dist]
|
299
|
+
|
300
|
+
"* #{changed} #{maintainer} - #{changev}\n- Package created with FPM\n"
|
301
|
+
end
|
302
|
+
|
278
303
|
# See FPM::Package#converted_from
|
279
304
|
def converted_from(origin)
|
280
|
-
if origin == FPM::Package::
|
305
|
+
if origin == FPM::Package::CPAN
|
306
|
+
if !attributes[:rpm_old_perl_dependency_name?]
|
307
|
+
fixed_deps = []
|
308
|
+
self.dependencies.collect do |dep|
|
309
|
+
# RPM package "perl" is a metapackage which install all the Perl bits and core modules, then gcc...
|
310
|
+
# this must be replaced by perl-interpreter
|
311
|
+
if name=/^perl([\s<>=].*)$/.match(dep)
|
312
|
+
fixed_deps.push("perl-interpreter#{name[1]}")
|
313
|
+
else
|
314
|
+
fixed_deps.push(dep)
|
315
|
+
end
|
316
|
+
end
|
317
|
+
self.dependencies = fixed_deps
|
318
|
+
end
|
319
|
+
elsif origin == FPM::Package::Gem
|
281
320
|
fixed_deps = []
|
282
321
|
self.dependencies.collect do |dep|
|
283
322
|
# Gem dependency operator "~>" is not compatible with rpm. Translate any found.
|
@@ -473,6 +512,7 @@ class FPM::Package::RPM < FPM::Package
|
|
473
512
|
args += ["--define", "dist .#{attributes[:rpm_dist]}"] if attributes[:rpm_dist]
|
474
513
|
|
475
514
|
args += [
|
515
|
+
"--buildroot", "#{build_path}/BUILD",
|
476
516
|
"--define", "buildroot #{build_path}/BUILD",
|
477
517
|
"--define", "_topdir #{build_path}",
|
478
518
|
"--define", "_sourcedir #{build_path}",
|
@@ -36,7 +36,7 @@ class FPM::Package::Virtualenv < FPM::Package
|
|
36
36
|
:default => nil
|
37
37
|
|
38
38
|
option "--setup-install", :flag, "After building virtualenv run setup.py install "\
|
39
|
-
"useful when building a virtualenv for packages and including their requirements from "
|
39
|
+
"useful when building a virtualenv for packages and including their requirements from "\
|
40
40
|
"requirements.txt"
|
41
41
|
|
42
42
|
option "--system-site-packages", :flag, "Give the virtual environment access to the "\
|
@@ -158,6 +158,31 @@ class FPM::Package::Virtualenv < FPM::Package
|
|
158
158
|
end
|
159
159
|
end
|
160
160
|
|
161
|
+
# [2025-09-30] virtualenv-tools seems broken?
|
162
|
+
# The --update-path will look for a VIRTUAL_ENV= line in bin/activate,
|
163
|
+
# however, the version I tested looks for it with quotations, like VIRTUAL_ENV='
|
164
|
+
# And at time of writing, my `virtualenv` tool doesn't use quotations on this variable
|
165
|
+
#
|
166
|
+
# Maybe best case we can patch it here instead. The path update tool
|
167
|
+
# looks for the original virtualenv path and I think updates any bin
|
168
|
+
# files which point to it.
|
169
|
+
patched = []
|
170
|
+
activate_bin = File.join(virtualenv_build_folder, "bin/activate")
|
171
|
+
fd = File.open(activate_bin)
|
172
|
+
fd.each_line do |line|
|
173
|
+
re = /^VIRTUAL_ENV=([^'"].*)$/
|
174
|
+
match = line.match(re)
|
175
|
+
if match
|
176
|
+
# Quote the VIRTUAL_ENV var assignment to help virtualenv-tools work?
|
177
|
+
patched << "VIRTUAL_ENV='#{match}'\n"
|
178
|
+
else
|
179
|
+
patched << line
|
180
|
+
end
|
181
|
+
end
|
182
|
+
fd.close
|
183
|
+
File.write(activate_bin, patched.join)
|
184
|
+
|
185
|
+
# Rewrite the base path inside the virtualenv to prepare it to be packaged.
|
161
186
|
::Dir.chdir(virtualenv_build_folder) do
|
162
187
|
safesystem("virtualenv-tools", "--update-path", virtualenv_folder)
|
163
188
|
end
|
@@ -191,7 +216,6 @@ class FPM::Package::Virtualenv < FPM::Package
|
|
191
216
|
dir.input(".")
|
192
217
|
@staging_path = dir.staging_path
|
193
218
|
dir.cleanup_build
|
194
|
-
|
195
219
|
end # def input
|
196
220
|
|
197
221
|
# Delete python precompiled files found in a given folder.
|
data/lib/fpm/package.rb
CHANGED
data/lib/fpm/rake_task.rb
CHANGED
@@ -1,13 +1,39 @@
|
|
1
1
|
require "fpm/namespace"
|
2
|
-
require "ostruct"
|
3
2
|
require "rake"
|
4
3
|
require "rake/tasklib"
|
5
4
|
|
6
5
|
class FPM::RakeTask < Rake::TaskLib
|
6
|
+
class Options
|
7
|
+
attr_accessor :args
|
8
|
+
|
9
|
+
def initialize(defaults=nil)
|
10
|
+
if defaults.nil?
|
11
|
+
@h = Hash.new
|
12
|
+
else
|
13
|
+
@h = defaults
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def method_missing(m, *args)
|
18
|
+
if m.end_with?("=")
|
19
|
+
raise ArgumentError, "#{self.class.name}##{m} ... Expected 1 arg, got #{args.length}" if args.length != 1
|
20
|
+
@h[m[0...-1]] = args[0]
|
21
|
+
else
|
22
|
+
raise ArgumentError, "Expected 0 arg, got #{args.length}" if args.length != 0
|
23
|
+
return @h[m]
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def to_h
|
28
|
+
return @h
|
29
|
+
end
|
30
|
+
end # Options
|
31
|
+
|
7
32
|
attr_reader :options
|
8
33
|
|
9
34
|
def initialize(package_name, opts = {}, &block)
|
10
|
-
|
35
|
+
#@options = OpenStruct.new(:name => package_name.to_s)
|
36
|
+
@options = Options.new(:name => package_name.to_s)
|
11
37
|
@source, @target = opts.values_at(:source, :target).map(&:to_s)
|
12
38
|
@directory = File.expand_path(opts[:directory].to_s)
|
13
39
|
|
@@ -18,8 +44,8 @@ class FPM::RakeTask < Rake::TaskLib
|
|
18
44
|
|
19
45
|
task(options.name) do |_, task_args|
|
20
46
|
block.call(*[options, task_args].first(block.arity)) if block_given?
|
21
|
-
abort("Must specify args")
|
22
|
-
@args = options.
|
47
|
+
abort("Must specify args") if options.args.nil?
|
48
|
+
@args = options.args
|
23
49
|
run_cli
|
24
50
|
end
|
25
51
|
end
|
data/lib/fpm/util.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
require "fpm/namespace"
|
2
2
|
require "fileutils"
|
3
|
+
require "stud/temporary"
|
3
4
|
|
4
5
|
# Some utility functions
|
5
6
|
module FPM::Util
|
@@ -135,7 +136,7 @@ module FPM::Util
|
|
135
136
|
raise ExecutableNotFound.new(program)
|
136
137
|
end
|
137
138
|
|
138
|
-
logger.
|
139
|
+
logger.info("Running command", :args => args2)
|
139
140
|
|
140
141
|
stdout_r, stdout_w = IO.pipe
|
141
142
|
stderr_r, stderr_w = IO.pipe
|
@@ -229,15 +230,18 @@ module FPM::Util
|
|
229
230
|
@@ar_cmd_deterministic = false
|
230
231
|
|
231
232
|
# FIXME: don't assume current directory writeable
|
232
|
-
|
233
|
+
emptyfile = Stud::Temporary.pathname
|
234
|
+
testarchive = Stud::Temporary.pathname
|
235
|
+
FileUtils.touch([emptyfile])
|
236
|
+
|
233
237
|
["ar", "gar"].each do |ar|
|
234
238
|
["-qc", "-qcD"].each do |ar_create_opts|
|
235
|
-
FileUtils.rm_f([
|
239
|
+
FileUtils.rm_f([testarchive])
|
236
240
|
# Return this combination if it creates archives without uids or timestamps.
|
237
241
|
# Exitstatus will be nonzero if the archive can't be created,
|
238
242
|
# or its table of contents doesn't match the regular expression.
|
239
243
|
# Be extra-careful about locale and timezone when matching output.
|
240
|
-
system("#{ar} #{ar_create_opts}
|
244
|
+
system("#{ar} #{ar_create_opts} #{testarchive} #{emptyfile} 2>/dev/null && env TZ=UTC LANG=C LC_TIME=C #{ar} -tv #{testarchive} | grep '0/0.*1970' > /dev/null 2>&1")
|
241
245
|
if $?.exitstatus == 0
|
242
246
|
@@ar_cmd = [ar, ar_create_opts]
|
243
247
|
@@ar_cmd_deterministic = true
|
@@ -247,10 +251,8 @@ module FPM::Util
|
|
247
251
|
end
|
248
252
|
# If no combination of ar and options omits timestamps, fall back to default.
|
249
253
|
@@ar_cmd = ["ar", "-qc"]
|
254
|
+
FileUtils.rm_f([testarchive, emptyfile])
|
250
255
|
return @@ar_cmd
|
251
|
-
ensure
|
252
|
-
# Clean up
|
253
|
-
FileUtils.rm_f(["fpm-dummy.ar.tmp", "fpm-dummy.tmp"])
|
254
256
|
end # def ar_cmd
|
255
257
|
|
256
258
|
# Return whether the command returned by ar_cmd can create deterministic archives
|
@@ -264,7 +266,10 @@ module FPM::Util
|
|
264
266
|
return @@tar_cmd if defined? @@tar_cmd
|
265
267
|
|
266
268
|
# FIXME: don't assume current directory writeable
|
267
|
-
|
269
|
+
emptyfile = Stud::Temporary.pathname
|
270
|
+
testarchive = Stud::Temporary.pathname
|
271
|
+
|
272
|
+
FileUtils.touch([emptyfile])
|
268
273
|
|
269
274
|
# Prefer tar that supports more of the features we want, stop if we find tar of our dreams
|
270
275
|
best="tar"
|
@@ -276,7 +281,7 @@ module FPM::Util
|
|
276
281
|
opts=[]
|
277
282
|
score=0
|
278
283
|
["--sort=name", "--mtime=@0"].each do |opt|
|
279
|
-
system("#{tar} #{opt} -cf
|
284
|
+
system("#{tar} #{opt} -cf #{testarchive} #{emptyfile} > /dev/null 2>&1")
|
280
285
|
if $?.exitstatus == 0
|
281
286
|
opts << opt
|
282
287
|
score += 1
|
@@ -292,10 +297,9 @@ module FPM::Util
|
|
292
297
|
end
|
293
298
|
end
|
294
299
|
@@tar_cmd = best
|
300
|
+
FileUtils.rm_f([testarchive, emptyfile])
|
301
|
+
|
295
302
|
return @@tar_cmd
|
296
|
-
ensure
|
297
|
-
# Clean up
|
298
|
-
FileUtils.rm_f(["fpm-dummy.tar.tmp", "fpm-dummy.tmp"])
|
299
303
|
end # def tar_cmd
|
300
304
|
|
301
305
|
# Return whether the command returned by tar_cmd can create deterministic archives
|
@@ -328,7 +332,15 @@ module FPM::Util
|
|
328
332
|
|
329
333
|
|
330
334
|
def copy_entry(src, dst, preserve=false, remove_destination=false)
|
331
|
-
|
335
|
+
st = File.lstat(src)
|
336
|
+
|
337
|
+
filetype = if st.ftype == "file" && st.nlink > 1
|
338
|
+
"hardlink"
|
339
|
+
else
|
340
|
+
st.ftype
|
341
|
+
end
|
342
|
+
|
343
|
+
case filetype
|
332
344
|
when 'fifo'
|
333
345
|
if File.respond_to?(:mkfifo)
|
334
346
|
File.mkfifo(dst)
|
@@ -346,18 +358,23 @@ module FPM::Util
|
|
346
358
|
raise UnsupportedSpecialFile.new("File is device which fpm doesn't know how to copy (#{File.ftype(src)}): #{src}")
|
347
359
|
when 'directory'
|
348
360
|
FileUtils.mkdir(dst) unless File.exist? dst
|
349
|
-
|
350
|
-
#
|
361
|
+
when 'hardlink'
|
362
|
+
# Handle hardlinks
|
363
|
+
# if the file with the same dev and inode has been copied already.
|
351
364
|
# hard link it's copy to `dst`, otherwise make an actual copy
|
352
|
-
st = File.lstat(src)
|
353
365
|
known_entry = copied_entries[[st.dev, st.ino]]
|
354
366
|
if known_entry
|
355
367
|
FileUtils.ln(known_entry, dst)
|
368
|
+
logger.debug("Copying hardlink", :src => src, :dst => dst, :link => known_entry)
|
356
369
|
else
|
357
370
|
FileUtils.copy_entry(src, dst, preserve, false,
|
358
371
|
remove_destination)
|
359
372
|
copied_entries[[st.dev, st.ino]] = dst
|
360
373
|
end
|
374
|
+
else
|
375
|
+
# Normal file, just copy it.
|
376
|
+
FileUtils.copy_entry(src, dst, preserve, false,
|
377
|
+
remove_destination)
|
361
378
|
end # else...
|
362
379
|
end # def copy_entry
|
363
380
|
|
data/lib/fpm/version.rb
CHANGED
data/templates/rpm.erb
CHANGED
metadata
CHANGED
@@ -1,14 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fpm
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.17.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jordan Sissel
|
8
|
-
autorequire:
|
9
8
|
bindir: bin
|
10
9
|
cert_chain: []
|
11
|
-
date:
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
12
11
|
dependencies:
|
13
12
|
- !ruby/object:Gem::Dependency
|
14
13
|
name: cabin
|
@@ -16,14 +15,14 @@ dependencies:
|
|
16
15
|
requirements:
|
17
16
|
- - ">="
|
18
17
|
- !ruby/object:Gem::Version
|
19
|
-
version: 0.
|
18
|
+
version: 0.9.1
|
20
19
|
type: :runtime
|
21
20
|
prerelease: false
|
22
21
|
version_requirements: !ruby/object:Gem::Requirement
|
23
22
|
requirements:
|
24
23
|
- - ">="
|
25
24
|
- !ruby/object:Gem::Version
|
26
|
-
version: 0.
|
25
|
+
version: 0.9.1
|
27
26
|
- !ruby/object:Gem::Dependency
|
28
27
|
name: backports
|
29
28
|
requirement: !ruby/object:Gem::Requirement
|
@@ -56,14 +55,14 @@ dependencies:
|
|
56
55
|
name: clamp
|
57
56
|
requirement: !ruby/object:Gem::Requirement
|
58
57
|
requirements:
|
59
|
-
- - "
|
58
|
+
- - ">="
|
60
59
|
- !ruby/object:Gem::Version
|
61
60
|
version: 1.0.0
|
62
61
|
type: :runtime
|
63
62
|
prerelease: false
|
64
63
|
version_requirements: !ruby/object:Gem::Requirement
|
65
64
|
requirements:
|
66
|
-
- - "
|
65
|
+
- - ">="
|
67
66
|
- !ruby/object:Gem::Version
|
68
67
|
version: 1.0.0
|
69
68
|
- !ruby/object:Gem::Dependency
|
@@ -114,14 +113,14 @@ dependencies:
|
|
114
113
|
requirements:
|
115
114
|
- - "~>"
|
116
115
|
- !ruby/object:Gem::Version
|
117
|
-
version: 3.
|
116
|
+
version: 3.13.0
|
118
117
|
type: :development
|
119
118
|
prerelease: false
|
120
119
|
version_requirements: !ruby/object:Gem::Requirement
|
121
120
|
requirements:
|
122
121
|
- - "~>"
|
123
122
|
- !ruby/object:Gem::Version
|
124
|
-
version: 3.
|
123
|
+
version: 3.13.0
|
125
124
|
- !ruby/object:Gem::Dependency
|
126
125
|
name: insist
|
127
126
|
requirement: !ruby/object:Gem::Requirement
|
@@ -199,6 +198,7 @@ files:
|
|
199
198
|
- lib/fpm/package/puppet.rb
|
200
199
|
- lib/fpm/package/pyfpm/__init__.py
|
201
200
|
- lib/fpm/package/pyfpm/get_metadata.py
|
201
|
+
- lib/fpm/package/pyfpm/parse_requires.py
|
202
202
|
- lib/fpm/package/python.rb
|
203
203
|
- lib/fpm/package/rpm.rb
|
204
204
|
- lib/fpm/package/sh.rb
|
@@ -238,7 +238,6 @@ homepage: https://github.com/jordansissel/fpm
|
|
238
238
|
licenses:
|
239
239
|
- MIT-like
|
240
240
|
metadata: {}
|
241
|
-
post_install_message:
|
242
241
|
rdoc_options: []
|
243
242
|
require_paths:
|
244
243
|
- lib
|
@@ -254,8 +253,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
254
253
|
- !ruby/object:Gem::Version
|
255
254
|
version: '0'
|
256
255
|
requirements: []
|
257
|
-
rubygems_version: 3.
|
258
|
-
signing_key:
|
256
|
+
rubygems_version: 3.6.7
|
259
257
|
specification_version: 4
|
260
258
|
summary: fpm - package building and mangling
|
261
259
|
test_files: []
|