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/lib/fpm/package/rpm.rb
CHANGED
@@ -1,9 +1,12 @@
|
|
1
1
|
require "fpm/package"
|
2
|
-
require "backports"
|
2
|
+
require "backports/latest"
|
3
3
|
require "fileutils"
|
4
4
|
require "find"
|
5
5
|
require "arr-pm/file" # gem 'arr-pm'
|
6
6
|
|
7
|
+
# For conversion handling
|
8
|
+
require "fpm/package/gem"
|
9
|
+
|
7
10
|
# RPM Package type.
|
8
11
|
#
|
9
12
|
# Build RPMs without having to waste hours reading Maximum-RPM.
|
@@ -24,9 +27,10 @@ class FPM::Package::RPM < FPM::Package
|
|
24
27
|
|
25
28
|
COMPRESSION_MAP = {
|
26
29
|
"none" => "w0.gzdio",
|
27
|
-
"xz" => "
|
28
|
-
"
|
29
|
-
"
|
30
|
+
"xz" => ".xzdio",
|
31
|
+
"xzmt" => "T.xzdio",
|
32
|
+
"gzip" => ".gzdio",
|
33
|
+
"bzip2" => ".bzdio"
|
30
34
|
} unless defined?(COMPRESSION_MAP)
|
31
35
|
|
32
36
|
option "--use-file-permissions", :flag,
|
@@ -67,6 +71,15 @@ class FPM::Package::RPM < FPM::Package
|
|
67
71
|
value.downcase
|
68
72
|
end
|
69
73
|
|
74
|
+
option "--compression-level", "[0-9]", "Select a compression level. 0 is store-only. 9 is max compression.",
|
75
|
+
:default => "9" do |value|
|
76
|
+
valint = value.to_i
|
77
|
+
unless value =~ /^\d$/ && valint >= 0 && valint <= 9
|
78
|
+
raise "Invalid compression level '#{value}'. Valid values are integers between 0 and 9 inclusive."
|
79
|
+
end
|
80
|
+
valint
|
81
|
+
end
|
82
|
+
|
70
83
|
option "--compression", COMPRESSION_MAP.keys.join("|"),
|
71
84
|
"Select a compression method. gzip works on the most platforms.",
|
72
85
|
:default => "gzip" do |value|
|
@@ -141,6 +154,10 @@ class FPM::Package::RPM < FPM::Package
|
|
141
154
|
"names in rpm requires instead of the redhat style " \
|
142
155
|
"rubygem(foo).", :default => false
|
143
156
|
|
157
|
+
option "--macro-expansion", :flag,
|
158
|
+
"install-time macro expansion in %pre %post %preun %postun scripts " \
|
159
|
+
"(see: https://rpm.org/user_doc/scriptlet_expansion.html)", :default => false
|
160
|
+
|
144
161
|
option "--verifyscript", "FILE",
|
145
162
|
"a script to be run on verification" do |val|
|
146
163
|
File.expand_path(val) # Get the full path to the script
|
@@ -176,14 +193,15 @@ class FPM::Package::RPM < FPM::Package
|
|
176
193
|
# Replace ? with [?] to make rpm not use globs
|
177
194
|
# Replace % with [%] to make rpm not expand macros
|
178
195
|
def rpm_fix_name(name)
|
179
|
-
name = name.gsub(/(\ |\[|\]
|
196
|
+
name = name.gsub(/(\ |\[|\]|\*|\?|\%|\$|')/, {
|
180
197
|
' ' => '?',
|
181
198
|
'%' => '[%]',
|
182
199
|
'$' => '[$]',
|
183
200
|
'?' => '[?]',
|
184
201
|
'*' => '[*]',
|
185
202
|
'[' => '[\[]',
|
186
|
-
']' => '[\]]'
|
203
|
+
']' => '[\]]',
|
204
|
+
"'" => "\\'",
|
187
205
|
})
|
188
206
|
end
|
189
207
|
|
@@ -225,6 +243,8 @@ class FPM::Package::RPM < FPM::Package
|
|
225
243
|
return %x{uname -m}.chomp # default to current arch
|
226
244
|
when "amd64" # debian and redhat disagree on architecture names
|
227
245
|
return "x86_64"
|
246
|
+
when "arm64" # debian and redhat disagree on architecture names
|
247
|
+
return "aarch64"
|
228
248
|
when "native"
|
229
249
|
return %x{uname -m}.chomp # 'native' is current arch
|
230
250
|
when "all"
|
@@ -237,6 +257,12 @@ class FPM::Package::RPM < FPM::Package
|
|
237
257
|
|
238
258
|
# This method ensures a default value for iteration if none is provided.
|
239
259
|
def iteration
|
260
|
+
if @iteration.kind_of?(String) and @iteration.include?("-")
|
261
|
+
logger.warn("Package iteration '#{@iteration}' includes dashes, converting" \
|
262
|
+
" to underscores. rpmbuild does not allow the dashes in the package iteration (called 'Release' in rpm)")
|
263
|
+
@iteration = @iteration.gsub(/-/, "_")
|
264
|
+
end
|
265
|
+
|
240
266
|
return @iteration ? @iteration : 1
|
241
267
|
end # def iteration
|
242
268
|
|
@@ -472,6 +498,22 @@ class FPM::Package::RPM < FPM::Package
|
|
472
498
|
self.directories = alldirs
|
473
499
|
end
|
474
500
|
|
501
|
+
# include external config files
|
502
|
+
(attributes[:config_files] or []).each do |conf|
|
503
|
+
dest_conf = File.join(staging_path, conf)
|
504
|
+
|
505
|
+
if File.exist?(dest_conf)
|
506
|
+
logger.debug("Using --config-file from staging area", :path => conf)
|
507
|
+
elsif File.exist?(conf)
|
508
|
+
logger.info("Copying --config-file from local path", :path => conf)
|
509
|
+
FileUtils.mkdir_p(File.dirname(dest_conf))
|
510
|
+
FileUtils.cp_r conf, dest_conf
|
511
|
+
else
|
512
|
+
logger.error("Failed to find given --config-file", :path => conf)
|
513
|
+
raise "Could not find config file '#{conf}' in staging area or on host. This can happen if you specify `--config-file '#{conf}'` but this file does not exist in the source package and also does not exist in filesystem."
|
514
|
+
end
|
515
|
+
end
|
516
|
+
|
475
517
|
# scan all conf file paths for files and add them
|
476
518
|
allconfigs = []
|
477
519
|
self.config_files.each do |path|
|
@@ -499,10 +541,11 @@ class FPM::Package::RPM < FPM::Package
|
|
499
541
|
end
|
500
542
|
|
501
543
|
# copy all files from staging to BUILD dir
|
544
|
+
# [#1538] Be sure to preserve the original timestamps.
|
502
545
|
Find.find(staging_path) do |path|
|
503
546
|
src = path.gsub(/^#{staging_path}/, '')
|
504
547
|
dst = File.join(build_path, build_sub_dir, src)
|
505
|
-
copy_entry(path, dst)
|
548
|
+
copy_entry(path, dst, preserve=true)
|
506
549
|
end
|
507
550
|
|
508
551
|
rpmspec = template("rpm.erb").result(binding)
|
@@ -523,7 +566,11 @@ class FPM::Package::RPM < FPM::Package
|
|
523
566
|
end # def output
|
524
567
|
|
525
568
|
def prefix
|
526
|
-
|
569
|
+
if attributes[:prefix] and attributes[:prefix] != '/'
|
570
|
+
return attributes[:prefix].chomp('/')
|
571
|
+
else
|
572
|
+
return "/"
|
573
|
+
end
|
527
574
|
end # def prefix
|
528
575
|
|
529
576
|
def build_sub_dir
|
@@ -533,7 +580,7 @@ class FPM::Package::RPM < FPM::Package
|
|
533
580
|
|
534
581
|
def summary
|
535
582
|
if !attributes[:rpm_summary]
|
536
|
-
return @description.split("\n").
|
583
|
+
return @description.split("\n").find { |line| !line.strip.empty? } || "_"
|
537
584
|
end
|
538
585
|
|
539
586
|
return attributes[:rpm_summary]
|
@@ -576,7 +623,12 @@ class FPM::Package::RPM < FPM::Package
|
|
576
623
|
end # def to_s
|
577
624
|
|
578
625
|
def payload_compression
|
579
|
-
|
626
|
+
if attributes[:rpm_compression] == 'none'
|
627
|
+
# when 'none' ignore any compression level and return w0.gzdio
|
628
|
+
return COMPRESSION_MAP[attributes[:rpm_compression]]
|
629
|
+
else
|
630
|
+
return "w#{attributes[:rpm_compression_level]}" + COMPRESSION_MAP[attributes[:rpm_compression]]
|
631
|
+
end
|
580
632
|
end # def payload_compression
|
581
633
|
|
582
634
|
def digest_algorithm
|
data/lib/fpm/package/sh.rb
CHANGED
@@ -0,0 +1,130 @@
|
|
1
|
+
require "yaml"
|
2
|
+
|
3
|
+
require "fpm/package"
|
4
|
+
require "fpm/util"
|
5
|
+
require "fileutils"
|
6
|
+
require "fpm/package/dir"
|
7
|
+
|
8
|
+
# Support for snaps (.snap files).
|
9
|
+
#
|
10
|
+
# This supports the input and output of snaps.
|
11
|
+
class FPM::Package::Snap < FPM::Package
|
12
|
+
|
13
|
+
option "--yaml", "FILEPATH",
|
14
|
+
"Custom version of the snap.yaml file." do | snap_yaml |
|
15
|
+
File.expand_path(snap_yaml)
|
16
|
+
end
|
17
|
+
|
18
|
+
option "--confinement", "CONFINEMENT",
|
19
|
+
"Type of confinement to use for this snap.",
|
20
|
+
default: "devmode" do | confinement |
|
21
|
+
if ['strict', 'devmode', 'classic'].include? confinement
|
22
|
+
confinement
|
23
|
+
else
|
24
|
+
raise "Unsupported confinement type '#{confinement}'"
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
option "--grade", "GRADE", "Grade of this snap.",
|
29
|
+
default: "devel" do | grade |
|
30
|
+
if ['stable', 'devel'].include? grade
|
31
|
+
grade
|
32
|
+
else
|
33
|
+
raise "Unsupported grade type '#{grade}'"
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
# Input a snap
|
38
|
+
def input(input_snap)
|
39
|
+
extract_snap_to_staging input_snap
|
40
|
+
extract_snap_metadata_from_staging
|
41
|
+
end # def input
|
42
|
+
|
43
|
+
# Output a snap.
|
44
|
+
def output(output_snap)
|
45
|
+
output_check(output_snap)
|
46
|
+
|
47
|
+
write_snap_yaml
|
48
|
+
|
49
|
+
# Create the snap from the staging path
|
50
|
+
safesystem("mksquashfs", staging_path, output_snap, "-noappend", "-comp",
|
51
|
+
"xz", "-no-xattrs", "-no-fragments", "-all-root")
|
52
|
+
end # def output
|
53
|
+
|
54
|
+
def to_s(format=nil)
|
55
|
+
# Default format if nil
|
56
|
+
# name_version_arch.snap
|
57
|
+
return super(format.nil? ? "NAME_FULLVERSION_ARCH.EXTENSION" : format)
|
58
|
+
end # def to_s
|
59
|
+
|
60
|
+
private
|
61
|
+
|
62
|
+
def extract_snap_to_staging(snap_path)
|
63
|
+
safesystem("unsquashfs", "-f", "-d", staging_path, snap_path)
|
64
|
+
end
|
65
|
+
|
66
|
+
def extract_snap_metadata_from_staging
|
67
|
+
metadata = YAML.safe_load(File.read(
|
68
|
+
staging_path(File.join("meta", "snap.yaml"))))
|
69
|
+
|
70
|
+
self.name = metadata["name"]
|
71
|
+
self.version = metadata["version"]
|
72
|
+
self.description = metadata["summary"] + "\n" + metadata["description"]
|
73
|
+
self.architecture = metadata["architectures"][0]
|
74
|
+
self.attributes[:snap_confinement] = metadata["confinement"]
|
75
|
+
self.attributes[:snap_grade] = metadata["grade"]
|
76
|
+
|
77
|
+
if metadata["apps"].nil?
|
78
|
+
attributes[:snap_apps] = []
|
79
|
+
else
|
80
|
+
attributes[:snap_apps] = metadata["apps"]
|
81
|
+
end
|
82
|
+
|
83
|
+
if metadata["hooks"].nil?
|
84
|
+
attributes[:snap_hooks] = []
|
85
|
+
else
|
86
|
+
attributes[:snap_hooks] = metadata["hooks"]
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
def write_snap_yaml
|
91
|
+
# Write the snap.yaml
|
92
|
+
if attributes[:snap_yaml]
|
93
|
+
logger.debug("Using '#{attributes[:snap_yaml]}' as the snap.yaml")
|
94
|
+
yaml_data = File.read(attributes[:snap_yaml])
|
95
|
+
else
|
96
|
+
summary, *remainder = (self.description or "no summary given").split("\n")
|
97
|
+
description = "no description given"
|
98
|
+
if remainder.any?
|
99
|
+
description = remainder.join("\n")
|
100
|
+
end
|
101
|
+
|
102
|
+
yaml_data = {
|
103
|
+
"name" => self.name,
|
104
|
+
"version" => self.version,
|
105
|
+
"summary" => summary,
|
106
|
+
"description" => description,
|
107
|
+
"architectures" => [self.architecture],
|
108
|
+
"confinement" => self.attributes[:snap_confinement],
|
109
|
+
"grade" => self.attributes[:snap_grade],
|
110
|
+
}
|
111
|
+
|
112
|
+
unless attributes[:snap_apps].nil? or attributes[:snap_apps].empty?
|
113
|
+
yaml_data["apps"] = attributes[:snap_apps]
|
114
|
+
end
|
115
|
+
|
116
|
+
unless attributes[:snap_hooks].nil? or attributes[:snap_hooks].empty?
|
117
|
+
yaml_data["hooks"] = attributes[:snap_hooks]
|
118
|
+
end
|
119
|
+
|
120
|
+
yaml_data = yaml_data.to_yaml
|
121
|
+
end
|
122
|
+
|
123
|
+
FileUtils.mkdir_p(staging_path("meta"))
|
124
|
+
snap_yaml_path = staging_path(File.join("meta", "snap.yaml"))
|
125
|
+
logger.debug("Writing snap.yaml", :path => snap_yaml_path)
|
126
|
+
File.write(snap_yaml_path, yaml_data)
|
127
|
+
File.chmod(0644, snap_yaml_path)
|
128
|
+
edit_file(snap_yaml_path) if attributes[:edit?]
|
129
|
+
end # def write_snap_yaml
|
130
|
+
end # class FPM::Package::Snap
|
data/lib/fpm/package/tar.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
require "backports" # gem backports
|
1
|
+
require "backports/latest" # gem backports/latest
|
2
2
|
require "fpm/package"
|
3
3
|
require "fpm/util"
|
4
4
|
require "fileutils"
|
@@ -50,15 +50,7 @@ class FPM::Package::Tar < FPM::Package
|
|
50
50
|
output_check(output_path)
|
51
51
|
|
52
52
|
# Write the scripts, too.
|
53
|
-
|
54
|
-
::Dir.mkdir(scripts_path)
|
55
|
-
[:before_install, :after_install, :before_remove, :after_remove].each do |name|
|
56
|
-
next unless script?(name)
|
57
|
-
out = File.join(scripts_path, name.to_s)
|
58
|
-
logger.debug("Writing script", :source => name, :target => out)
|
59
|
-
File.write(out, script(name))
|
60
|
-
File.chmod(0755, out)
|
61
|
-
end
|
53
|
+
write_scripts
|
62
54
|
|
63
55
|
# Unpack the tarball to the staging path
|
64
56
|
args = ["-cf", output_path, "-C", staging_path]
|
@@ -2,6 +2,8 @@ require "fpm/namespace"
|
|
2
2
|
require "fpm/package"
|
3
3
|
require "fpm/util"
|
4
4
|
|
5
|
+
require "fpm/package/dir"
|
6
|
+
|
5
7
|
# Support for python virtualenv packages.
|
6
8
|
#
|
7
9
|
# This supports input, but not output.
|
@@ -15,8 +17,11 @@ class FPM::Package::Virtualenv < FPM::Package
|
|
15
17
|
option "--package-name-prefix", "PREFIX", "Name to prefix the package " \
|
16
18
|
"name with.", :default => "virtualenv"
|
17
19
|
|
18
|
-
option "--install-location", "DIRECTORY", "
|
19
|
-
|
20
|
+
option "--install-location", "DIRECTORY", "DEPRECATED: Use --prefix instead." \
|
21
|
+
" Location to which to install the virtualenv by default.",
|
22
|
+
:default => "/usr/share/python" do |path|
|
23
|
+
logger.warn("Using deprecated flag: --install-location. Please use " \
|
24
|
+
"--prefix instead.")
|
20
25
|
File.expand_path(path)
|
21
26
|
end
|
22
27
|
|
@@ -30,6 +35,19 @@ class FPM::Package::Virtualenv < FPM::Package
|
|
30
35
|
:multivalued => true, :attribute_name => :virtualenv_pypi_extra_index_urls,
|
31
36
|
:default => nil
|
32
37
|
|
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 "
|
40
|
+
"requirements.txt"
|
41
|
+
|
42
|
+
option "--system-site-packages", :flag, "Give the virtual environment access to the "\
|
43
|
+
"global site-packages"
|
44
|
+
|
45
|
+
option "--find-links", "PIP_FIND_LINKS", "If a url or path to an html file, then parse for "\
|
46
|
+
"links to archives. If a local path or file:// url that's a directory, then look "\
|
47
|
+
"for archives in the directory listing.",
|
48
|
+
:multivalued => true, :attribute_name => :virtualenv_find_links_urls,
|
49
|
+
:default => nil
|
50
|
+
|
33
51
|
private
|
34
52
|
|
35
53
|
# Input a package.
|
@@ -40,7 +58,18 @@ class FPM::Package::Virtualenv < FPM::Package
|
|
40
58
|
m = /^([^=]+)==([^=]+)$/.match(package)
|
41
59
|
package_version = nil
|
42
60
|
|
43
|
-
|
61
|
+
is_requirements_file = (File.basename(package) == "requirements.txt")
|
62
|
+
|
63
|
+
if is_requirements_file
|
64
|
+
if !File.file?(package)
|
65
|
+
raise FPM::InvalidPackageConfiguration, "Path looks like a requirements.txt, but it doesn't exist: #{package}"
|
66
|
+
end
|
67
|
+
|
68
|
+
package = File.join(::Dir.pwd, package) if File.dirname(package) == "."
|
69
|
+
package_name = File.basename(File.dirname(package))
|
70
|
+
logger.info("No name given. Using the directory's name", :name => package_name)
|
71
|
+
package_version = nil
|
72
|
+
elsif m
|
44
73
|
package_name = m[1]
|
45
74
|
package_version = m[2]
|
46
75
|
self.version ||= package_version
|
@@ -58,23 +87,33 @@ class FPM::Package::Virtualenv < FPM::Package
|
|
58
87
|
self.name].join("-")
|
59
88
|
end
|
60
89
|
|
90
|
+
# prefix wins over previous virtual_install_location behaviour
|
61
91
|
virtualenv_folder =
|
62
|
-
|
63
|
-
|
92
|
+
if self.attributes[:prefix]
|
93
|
+
self.attributes[:prefix]
|
94
|
+
else
|
95
|
+
File.join(installdir,
|
96
|
+
virtualenv_name)
|
97
|
+
end
|
64
98
|
|
65
99
|
virtualenv_build_folder = build_path(virtualenv_folder)
|
66
100
|
|
67
101
|
::FileUtils.mkdir_p(virtualenv_build_folder)
|
68
102
|
|
69
|
-
|
103
|
+
if self.attributes[:virtualenv_system_site_packages?]
|
104
|
+
logger.info("Creating virtualenv with --system-site-packages")
|
105
|
+
safesystem("virtualenv", "--system-site-packages", virtualenv_build_folder)
|
106
|
+
else
|
107
|
+
safesystem("virtualenv", virtualenv_build_folder)
|
108
|
+
end
|
109
|
+
|
70
110
|
pip_exe = File.join(virtualenv_build_folder, "bin", "pip")
|
71
111
|
python_exe = File.join(virtualenv_build_folder, "bin", "python")
|
72
112
|
|
73
113
|
# Why is this hack here? It looks important, so I'll keep it in.
|
74
|
-
safesystem(pip_exe, "install", "-U", "-i",
|
114
|
+
safesystem(python_exe, pip_exe, "install", "-U", "-i",
|
75
115
|
attributes[:virtualenv_pypi],
|
76
|
-
"pip"
|
77
|
-
safesystem(pip_exe, "uninstall", "-y", "distribute")
|
116
|
+
"pip")
|
78
117
|
|
79
118
|
extra_index_url_args = []
|
80
119
|
if attributes[:virtualenv_pypi_extra_index_urls]
|
@@ -82,12 +121,34 @@ class FPM::Package::Virtualenv < FPM::Package
|
|
82
121
|
extra_index_url_args << "--extra-index-url" << extra_url
|
83
122
|
end
|
84
123
|
end
|
85
|
-
|
124
|
+
|
125
|
+
find_links_url_args = []
|
126
|
+
if attributes[:virtualenv_find_links_urls]
|
127
|
+
attributes[:virtualenv_find_links_urls].each do |links_url|
|
128
|
+
find_links_url_args << "--find-links" << links_url
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
target_args = []
|
133
|
+
if is_requirements_file
|
134
|
+
target_args << "-r" << package
|
135
|
+
else
|
136
|
+
target_args << package
|
137
|
+
end
|
138
|
+
|
139
|
+
pip_args = [python_exe, pip_exe, "install", "-i", attributes[:virtualenv_pypi]] << extra_index_url_args << find_links_url_args << target_args
|
86
140
|
safesystem(*pip_args.flatten)
|
87
141
|
|
88
|
-
if
|
89
|
-
|
90
|
-
|
142
|
+
if attributes[:virtualenv_setup_install?]
|
143
|
+
logger.info("Running PACKAGE setup.py")
|
144
|
+
setup_args = [python_exe, "setup.py", "install"]
|
145
|
+
safesystem(*setup_args.flatten)
|
146
|
+
end
|
147
|
+
|
148
|
+
if ! is_requirements_file && package_version.nil?
|
149
|
+
frozen = safesystemout(python_exe, pip_exe, "freeze")
|
150
|
+
frozen_version = frozen[/#{package}==[^=]+$/]
|
151
|
+
package_version = frozen_version && frozen_version.split("==")[1].chomp!
|
91
152
|
self.version ||= package_version
|
92
153
|
end
|
93
154
|
|
@@ -116,7 +177,8 @@ class FPM::Package::Virtualenv < FPM::Package
|
|
116
177
|
# use dir to set stuff up properly, mainly so I don't have to reimplement
|
117
178
|
# the chdir/prefix stuff special for tar.
|
118
179
|
dir = convert(FPM::Package::Dir)
|
119
|
-
|
180
|
+
# don't double prefix the files
|
181
|
+
dir.attributes[:prefix] = nil
|
120
182
|
if attributes[:chdir]
|
121
183
|
dir.attributes[:chdir] = File.join(build_path, attributes[:chdir])
|
122
184
|
else
|
data/lib/fpm/package/zip.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
require "backports" # gem backports
|
1
|
+
require "backports/latest" # gem backports/latest
|
2
2
|
require "fpm/package"
|
3
3
|
require "fpm/util"
|
4
4
|
require "fileutils"
|
@@ -36,28 +36,12 @@ class FPM::Package::Zip < FPM::Package
|
|
36
36
|
dir.cleanup_build
|
37
37
|
end # def input
|
38
38
|
|
39
|
-
# Output a
|
40
|
-
#
|
41
|
-
# If the output path ends predictably (like in .tar.gz) it will try to obey
|
42
|
-
# the compression type.
|
39
|
+
# Output a zipfile.
|
43
40
|
def output(output_path)
|
44
41
|
output_check(output_path)
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
end # def output
|
49
|
-
|
50
|
-
# Generate the proper tar flags based on the path name.
|
51
|
-
def tar_compression_flag(path)
|
52
|
-
case path
|
53
|
-
when /\.tar\.bz2$/
|
54
|
-
return "-j"
|
55
|
-
when /\.tar\.gz$|\.tgz$/
|
56
|
-
return "-z"
|
57
|
-
when /\.tar\.xz$/
|
58
|
-
return "-J"
|
59
|
-
else
|
60
|
-
return nil
|
42
|
+
realpath = Pathname.new(output_path).realdirpath.to_s
|
43
|
+
::Dir.chdir(staging_path) do
|
44
|
+
safesystem("zip", "-9r", realpath, ".")
|
61
45
|
end
|
62
|
-
end # def
|
46
|
+
end # def output
|
63
47
|
end # class FPM::Package::Tar
|
data/lib/fpm/package.rb
CHANGED
@@ -3,11 +3,13 @@ require "fpm/util" # local
|
|
3
3
|
require "pathname" # stdlib
|
4
4
|
require "find"
|
5
5
|
require "tmpdir" # stdlib
|
6
|
-
require "
|
6
|
+
require "ostruct"
|
7
|
+
require "backports/latest"
|
7
8
|
require "socket" # stdlib, for Socket.gethostname
|
8
9
|
require "shellwords" # stdlib, for Shellwords.escape
|
9
10
|
require "erb" # stdlib, for template processing
|
10
11
|
require "cabin" # gem "cabin"
|
12
|
+
require "stud/temporary"
|
11
13
|
|
12
14
|
# This class is the parent of all packages.
|
13
15
|
# If you want to implement an FPM package type, you'll inherit from this.
|
@@ -117,7 +119,10 @@ class FPM::Package
|
|
117
119
|
|
118
120
|
def initialize
|
119
121
|
# Attributes for this specific package
|
120
|
-
@attributes = {
|
122
|
+
@attributes = {
|
123
|
+
# Default work location
|
124
|
+
:workdir => ::Dir.tmpdir
|
125
|
+
}
|
121
126
|
|
122
127
|
# Reference
|
123
128
|
# http://www.debian.org/doc/manuals/maint-guide/first.en.html
|
@@ -174,8 +179,8 @@ class FPM::Package
|
|
174
179
|
@directories = []
|
175
180
|
@attrs = {}
|
176
181
|
|
177
|
-
staging_path
|
178
182
|
build_path
|
183
|
+
# Dont' initialize staging_path just yet, do it lazily so subclass can get a word in.
|
179
184
|
end # def initialize
|
180
185
|
|
181
186
|
# Get the 'type' for this instance.
|
@@ -249,7 +254,7 @@ class FPM::Package
|
|
249
254
|
end # def output
|
250
255
|
|
251
256
|
def staging_path(path=nil)
|
252
|
-
@staging_path ||= ::
|
257
|
+
@staging_path ||= Stud::Temporary.directory("package-#{type}-staging")
|
253
258
|
|
254
259
|
if path.nil?
|
255
260
|
return @staging_path
|
@@ -259,7 +264,7 @@ class FPM::Package
|
|
259
264
|
end # def staging_path
|
260
265
|
|
261
266
|
def build_path(path=nil)
|
262
|
-
@build_path ||= ::
|
267
|
+
@build_path ||= Stud::Temporary.directory("package-#{type}-build")
|
263
268
|
|
264
269
|
if path.nil?
|
265
270
|
return @build_path
|
@@ -311,7 +316,7 @@ class FPM::Package
|
|
311
316
|
# the path before returning.
|
312
317
|
#
|
313
318
|
# Wrapping Find.find in an Enumerator is required for sane operation in ruby 1.8.7,
|
314
|
-
# but requires the 'backports' gem (which is used in other places in fpm)
|
319
|
+
# but requires the 'backports/latest' gem (which is used in other places in fpm)
|
315
320
|
return Enumerator.new { |y| Find.find(staging_path) { |path| y << path } } \
|
316
321
|
.select { |path| path != staging_path } \
|
317
322
|
.select { |path| is_leaf.call(path) } \
|
@@ -491,6 +496,22 @@ class FPM::Package
|
|
491
496
|
return scripts.include?(name)
|
492
497
|
end # def script?
|
493
498
|
|
499
|
+
# write all scripts to .scripts (tar and dir)
|
500
|
+
def write_scripts
|
501
|
+
scripts_path = File.join(staging_path, ".scripts")
|
502
|
+
target_scripts = [:before_install, :after_install, :before_remove, :after_remove]
|
503
|
+
if target_scripts.any? {|name| script?(name)}
|
504
|
+
::Dir.mkdir(scripts_path)
|
505
|
+
target_scripts.each do |name|
|
506
|
+
next unless script?(name)
|
507
|
+
out = File.join(scripts_path, name.to_s)
|
508
|
+
logger.debug('Writing script', :source => name, :target => out)
|
509
|
+
File.write(out, script(name))
|
510
|
+
File.chmod(0755, out)
|
511
|
+
end
|
512
|
+
end
|
513
|
+
end
|
514
|
+
|
494
515
|
# Get the contents of the script by a given name.
|
495
516
|
#
|
496
517
|
# If template_scripts? is set in attributes (often by the --template-scripts
|
data/lib/fpm/util/tar_writer.rb
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
require 'rubygems/package'
|
2
2
|
|
3
|
+
require 'stringio'
|
4
|
+
|
3
5
|
module FPM
|
4
6
|
module Issues
|
5
7
|
module TarWriter
|
@@ -27,7 +29,7 @@ end # module FPM
|
|
27
29
|
|
28
30
|
module FPM; module Util; end; end
|
29
31
|
|
30
|
-
# Like the ::Gem::Package::TarWriter but contains some backports and bug fixes
|
32
|
+
# Like the ::Gem::Package::TarWriter but contains some backports/latest and bug fixes
|
31
33
|
class FPM::Util::TarWriter < ::Gem::Package::TarWriter
|
32
34
|
if FPM::Issues::TarWriter.has_issues_with_split_name?
|
33
35
|
def split_name(name)
|