fpm-itchio 1.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/CHANGELIST +629 -0
- data/CONTRIBUTORS +26 -0
- data/LICENSE +21 -0
- data/bin/fpm +8 -0
- data/lib/fpm.rb +18 -0
- data/lib/fpm/command.rb +642 -0
- data/lib/fpm/errors.rb +4 -0
- data/lib/fpm/namespace.rb +4 -0
- data/lib/fpm/package.rb +524 -0
- data/lib/fpm/package/cpan.rb +378 -0
- data/lib/fpm/package/deb.rb +887 -0
- data/lib/fpm/package/dir.rb +207 -0
- data/lib/fpm/package/empty.rb +13 -0
- data/lib/fpm/package/gem.rb +224 -0
- data/lib/fpm/package/npm.rb +120 -0
- data/lib/fpm/package/osxpkg.rb +164 -0
- data/lib/fpm/package/p5p.rb +124 -0
- data/lib/fpm/package/pacman.rb +397 -0
- data/lib/fpm/package/pear.rb +117 -0
- data/lib/fpm/package/pkgin.rb +35 -0
- data/lib/fpm/package/puppet.rb +120 -0
- data/lib/fpm/package/pyfpm/__init__.py +1 -0
- data/lib/fpm/package/pyfpm/get_metadata.py +104 -0
- data/lib/fpm/package/python.rb +317 -0
- data/lib/fpm/package/rpm.rb +583 -0
- data/lib/fpm/package/sh.rb +69 -0
- data/lib/fpm/package/solaris.rb +95 -0
- data/lib/fpm/package/tar.rb +74 -0
- data/lib/fpm/package/virtualenv.rb +145 -0
- data/lib/fpm/package/zip.rb +63 -0
- data/lib/fpm/rake_task.rb +59 -0
- data/lib/fpm/util.rb +253 -0
- data/lib/fpm/version.rb +3 -0
- data/templates/deb.erb +52 -0
- data/templates/deb/changelog.erb +5 -0
- data/templates/deb/ldconfig.sh.erb +13 -0
- data/templates/deb/postinst_upgrade.sh.erb +62 -0
- data/templates/deb/postrm_upgrade.sh.erb +46 -0
- data/templates/deb/preinst_upgrade.sh.erb +41 -0
- data/templates/deb/prerm_upgrade.sh.erb +39 -0
- data/templates/osxpkg.erb +11 -0
- data/templates/p5p_metadata.erb +12 -0
- data/templates/pacman.erb +47 -0
- data/templates/pacman/INSTALL.erb +41 -0
- data/templates/puppet/package.pp.erb +34 -0
- data/templates/puppet/package/remove.pp.erb +13 -0
- data/templates/rpm.erb +261 -0
- data/templates/rpm/filesystem_list +14514 -0
- data/templates/sh.erb +367 -0
- data/templates/solaris.erb +15 -0
- metadata +265 -0
@@ -0,0 +1,583 @@
|
|
1
|
+
require "fpm/package"
|
2
|
+
require "backports"
|
3
|
+
require "fileutils"
|
4
|
+
require "find"
|
5
|
+
require "arr-pm/file" # gem 'arr-pm'
|
6
|
+
|
7
|
+
# RPM Package type.
|
8
|
+
#
|
9
|
+
# Build RPMs without having to waste hours reading Maximum-RPM.
|
10
|
+
# Well, in case you want to read it, here: http://www.rpm.org/max-rpm/
|
11
|
+
#
|
12
|
+
# The following attributes are supported:
|
13
|
+
#
|
14
|
+
# * :rpm_rpmbuild_define - an array of definitions to give to rpmbuild.
|
15
|
+
# These are used, verbatim, each as: --define ITEM
|
16
|
+
class FPM::Package::RPM < FPM::Package
|
17
|
+
DIGEST_ALGORITHM_MAP = {
|
18
|
+
"md5" => 1,
|
19
|
+
"sha1" => 2,
|
20
|
+
"sha256" => 8,
|
21
|
+
"sha384" => 9,
|
22
|
+
"sha512" => 10
|
23
|
+
} unless defined?(DIGEST_ALGORITHM_MAP)
|
24
|
+
|
25
|
+
COMPRESSION_MAP = {
|
26
|
+
"none" => "w0.gzdio",
|
27
|
+
"xz" => "w9.xzdio",
|
28
|
+
"gzip" => "w9.gzdio",
|
29
|
+
"bzip2" => "w9.bzdio"
|
30
|
+
} unless defined?(COMPRESSION_MAP)
|
31
|
+
|
32
|
+
option "--use-file-permissions", :flag,
|
33
|
+
"Use existing file permissions when defining ownership and modes."
|
34
|
+
|
35
|
+
option "--user", "USER", "Set the user to USER in the %files section. Overrides the user when used with use-file-permissions setting."
|
36
|
+
|
37
|
+
option "--group", "GROUP", "Set the group to GROUP in the %files section. Overrides the group when used with use-file-permissions setting."
|
38
|
+
|
39
|
+
option "--defattrfile", "ATTR",
|
40
|
+
"Set the default file mode (%defattr).",
|
41
|
+
:default => '-' do |value|
|
42
|
+
value
|
43
|
+
end
|
44
|
+
|
45
|
+
option "--defattrdir", "ATTR",
|
46
|
+
"Set the default dir mode (%defattr).",
|
47
|
+
:default => '-' do |value|
|
48
|
+
value
|
49
|
+
end
|
50
|
+
|
51
|
+
rpmbuild_define = []
|
52
|
+
option "--rpmbuild-define", "DEFINITION",
|
53
|
+
"Pass a --define argument to rpmbuild." do |define|
|
54
|
+
rpmbuild_define << define
|
55
|
+
next rpmbuild_define
|
56
|
+
end
|
57
|
+
|
58
|
+
option "--dist", "DIST-TAG", "Set the rpm distribution."
|
59
|
+
|
60
|
+
option "--digest", DIGEST_ALGORITHM_MAP.keys.join("|"),
|
61
|
+
"Select a digest algorithm. md5 works on the most platforms.",
|
62
|
+
:default => "md5" do |value|
|
63
|
+
if !DIGEST_ALGORITHM_MAP.include?(value.downcase)
|
64
|
+
raise "Unknown digest algorithm '#{value}'. Valid options " \
|
65
|
+
"include: #{DIGEST_ALGORITHM_MAP.keys.join(", ")}"
|
66
|
+
end
|
67
|
+
value.downcase
|
68
|
+
end
|
69
|
+
|
70
|
+
option "--compression", COMPRESSION_MAP.keys.join("|"),
|
71
|
+
"Select a compression method. gzip works on the most platforms.",
|
72
|
+
:default => "gzip" do |value|
|
73
|
+
if !COMPRESSION_MAP.include?(value.downcase)
|
74
|
+
raise "Unknown compression type '#{value}'. Valid options " \
|
75
|
+
"include: #{COMPRESSION_MAP.keys.join(", ")}"
|
76
|
+
end
|
77
|
+
value.downcase
|
78
|
+
end
|
79
|
+
|
80
|
+
# TODO(sissel): Try to be smart about the default OS.
|
81
|
+
# issue #309
|
82
|
+
option "--os", "OS", "The operating system to target this rpm for. " \
|
83
|
+
"You want to set this to 'linux' if you are using fpm on OS X, for example"
|
84
|
+
|
85
|
+
option "--changelog", "FILEPATH", "Add changelog from FILEPATH contents" do |file|
|
86
|
+
File.read(File.expand_path(file))
|
87
|
+
end
|
88
|
+
|
89
|
+
option "--summary", "SUMMARY",
|
90
|
+
"Set the RPM summary. Overrides the first line on the description if set"
|
91
|
+
|
92
|
+
option "--sign", :flag, "Pass --sign to rpmbuild"
|
93
|
+
|
94
|
+
option "--auto-add-directories", :flag, "Auto add directories not part of filesystem"
|
95
|
+
option "--auto-add-exclude-directories", "DIRECTORIES",
|
96
|
+
"Additional directories ignored by '--rpm-auto-add-directories' flag",
|
97
|
+
:multivalued => true, :attribute_name => :auto_add_exclude_directories
|
98
|
+
|
99
|
+
option "--autoreqprov", :flag, "Enable RPM's AutoReqProv option"
|
100
|
+
option "--autoreq", :flag, "Enable RPM's AutoReq option"
|
101
|
+
option "--autoprov", :flag, "Enable RPM's AutoProv option"
|
102
|
+
|
103
|
+
option "--attr", "ATTRFILE",
|
104
|
+
"Set the attribute for a file (%attr).",
|
105
|
+
:multivalued => true, :attribute_name => :attrs
|
106
|
+
|
107
|
+
option "--init", "FILEPATH", "Add FILEPATH as an init script",
|
108
|
+
:multivalued => true do |file|
|
109
|
+
next File.expand_path(file)
|
110
|
+
end
|
111
|
+
|
112
|
+
rpmbuild_filter_from_provides = []
|
113
|
+
option "--filter-from-provides", "REGEX",
|
114
|
+
"Set %filter_from_provides to the supplied REGEX." do |filter_from_provides|
|
115
|
+
rpmbuild_filter_from_provides << filter_from_provides
|
116
|
+
next rpmbuild_filter_from_provides
|
117
|
+
end
|
118
|
+
rpmbuild_filter_from_requires = []
|
119
|
+
option "--filter-from-requires", "REGEX",
|
120
|
+
"Set %filter_from_requires to the supplied REGEX." do |filter_from_requires|
|
121
|
+
rpmbuild_filter_from_requires << filter_from_requires
|
122
|
+
next rpmbuild_filter_from_requires
|
123
|
+
end
|
124
|
+
|
125
|
+
rpm_tags = []
|
126
|
+
option "--tag", "TAG",
|
127
|
+
"Adds a custom tag in the spec file as is. " \
|
128
|
+
"Example: --rpm-tag 'Requires(post): /usr/sbin/alternatives'" do |add_tag|
|
129
|
+
rpm_tags << add_tag
|
130
|
+
next rpm_tags
|
131
|
+
end
|
132
|
+
|
133
|
+
option "--ignore-iteration-in-dependencies", :flag,
|
134
|
+
"For '=' (equal) dependencies, allow iterations on the specified " \
|
135
|
+
"version. Default is to be specific. This option allows the same " \
|
136
|
+
"version of a package but any iteration is permitted"
|
137
|
+
|
138
|
+
option "--verbatim-gem-dependencies", :flag,
|
139
|
+
"When converting from a gem, leave the old (fpm 0.4.x) style " \
|
140
|
+
"dependency names. This flag will use the old 'rubygem-foo' " \
|
141
|
+
"names in rpm requires instead of the redhat style " \
|
142
|
+
"rubygem(foo).", :default => false
|
143
|
+
|
144
|
+
option "--verifyscript", "FILE",
|
145
|
+
"a script to be run on verification" do |val|
|
146
|
+
File.expand_path(val) # Get the full path to the script
|
147
|
+
end # --verifyscript
|
148
|
+
option "--pretrans", "FILE",
|
149
|
+
"pretrans script" do |val|
|
150
|
+
File.expand_path(val) # Get the full path to the script
|
151
|
+
end # --pretrans
|
152
|
+
option "--posttrans", "FILE",
|
153
|
+
"posttrans script" do |val|
|
154
|
+
File.expand_path(val) # Get the full path to the script
|
155
|
+
end # --posttrans
|
156
|
+
|
157
|
+
["before-install","after-install","before-uninstall","after-target-uninstall"].each do |trigger_type|
|
158
|
+
rpm_trigger = []
|
159
|
+
option "--trigger-#{trigger_type}", "'[OPT]PACKAGE: FILEPATH'", "Adds a rpm trigger script located in FILEPATH, " \
|
160
|
+
"having 'OPT' options and linking to 'PACKAGE'. PACKAGE can be a comma seperated list of packages. " \
|
161
|
+
"See: http://rpm.org/api/4.4.2.2/triggers.html" do |trigger|
|
162
|
+
match = trigger.match(/^(\[.*\]|)(.*): (.*)$/)
|
163
|
+
@logger.fatal("Trigger '#{trigger_type}' definition can't be parsed ('#{trigger}')") unless match
|
164
|
+
opt, pkg, file = match.captures
|
165
|
+
@logger.fatal("File given for --trigger-#{trigger_type} does not exist (#{file})") unless File.exist?(file)
|
166
|
+
rpm_trigger << [pkg, File.read(file), opt.tr('[]','')]
|
167
|
+
next rpm_trigger
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
171
|
+
private
|
172
|
+
|
173
|
+
# Fix path name
|
174
|
+
# Replace [ with [\[] to make rpm not use globs
|
175
|
+
# Replace * with [*] to make rpm not use globs
|
176
|
+
# Replace ? with [?] to make rpm not use globs
|
177
|
+
# Replace % with [%] to make rpm not expand macros
|
178
|
+
def rpm_fix_name(name)
|
179
|
+
name = name.gsub(/(\ |\[|\]|\*|\?|\%|\$)/, {
|
180
|
+
' ' => '?',
|
181
|
+
'%' => '[%]',
|
182
|
+
'$' => '[$]',
|
183
|
+
'?' => '[?]',
|
184
|
+
'*' => '[*]',
|
185
|
+
'[' => '[\[]',
|
186
|
+
']' => '[\]]'
|
187
|
+
})
|
188
|
+
end
|
189
|
+
|
190
|
+
def rpm_file_entry(file)
|
191
|
+
original_file = file
|
192
|
+
file = rpm_fix_name(file)
|
193
|
+
|
194
|
+
if !attributes[:rpm_use_file_permissions?]
|
195
|
+
|
196
|
+
if attrs[file].nil?
|
197
|
+
return file
|
198
|
+
else
|
199
|
+
return sprintf("%%attr(%s) %s\n", attrs[file], file)
|
200
|
+
end
|
201
|
+
end
|
202
|
+
|
203
|
+
return sprintf("%%attr(%s) %s\n", attrs[file], file) unless attrs[file].nil?
|
204
|
+
|
205
|
+
# Stat the original filename in the relative staging path
|
206
|
+
::Dir.chdir(staging_path) do
|
207
|
+
stat = File.lstat(original_file.gsub(/\"/, '').sub(/^\//,''))
|
208
|
+
|
209
|
+
# rpm_user and rpm_group attribute should override file ownership
|
210
|
+
# otherwise use the current file user/group by name.
|
211
|
+
user = attributes[:rpm_user] || Etc.getpwuid(stat.uid).name
|
212
|
+
group = attributes[:rpm_group] || Etc.getgrgid(stat.gid).name
|
213
|
+
mode = stat.mode
|
214
|
+
return sprintf("%%attr(%o, %s, %s) %s\n", mode & 4095 , user, group, file)
|
215
|
+
end
|
216
|
+
end
|
217
|
+
|
218
|
+
|
219
|
+
# Handle any architecture naming conversions.
|
220
|
+
# For example, debian calls amd64 what redhat calls x86_64, this
|
221
|
+
# method fixes those types of things.
|
222
|
+
def architecture
|
223
|
+
case @architecture
|
224
|
+
when nil
|
225
|
+
return %x{uname -m}.chomp # default to current arch
|
226
|
+
when "amd64" # debian and redhat disagree on architecture names
|
227
|
+
return "x86_64"
|
228
|
+
when "native"
|
229
|
+
return %x{uname -m}.chomp # 'native' is current arch
|
230
|
+
when "all"
|
231
|
+
# Translate fpm "all" arch to what it means in RPM.
|
232
|
+
return "noarch"
|
233
|
+
else
|
234
|
+
return @architecture
|
235
|
+
end
|
236
|
+
end # def architecture
|
237
|
+
|
238
|
+
# This method ensures a default value for iteration if none is provided.
|
239
|
+
def iteration
|
240
|
+
return @iteration ? @iteration : 1
|
241
|
+
end # def iteration
|
242
|
+
|
243
|
+
# See FPM::Package#converted_from
|
244
|
+
def converted_from(origin)
|
245
|
+
if origin == FPM::Package::Gem
|
246
|
+
fixed_deps = []
|
247
|
+
self.dependencies.collect do |dep|
|
248
|
+
# Gem dependency operator "~>" is not compatible with rpm. Translate any found.
|
249
|
+
fixed_deps = fixed_deps + expand_pessimistic_constraints(dep)
|
250
|
+
end
|
251
|
+
self.dependencies = fixed_deps
|
252
|
+
|
253
|
+
# Convert 'rubygem-foo' provides values to 'rubygem(foo)'
|
254
|
+
# since that's what most rpm packagers seem to do.
|
255
|
+
self.provides = self.provides.collect do |provides|
|
256
|
+
# Tries to match rubygem_prefix [1], gem_name [2] and version [3] if present
|
257
|
+
# and return it in rubygem_prefix(gem_name) form
|
258
|
+
if name=/^(#{attributes[:gem_package_name_prefix]})-([^\s]+)\s*(.*)$/.match(provides)
|
259
|
+
"#{name[1]}(#{name[2]})#{name[3] ? " #{name[3]}" : ""}"
|
260
|
+
else
|
261
|
+
provides
|
262
|
+
end
|
263
|
+
end
|
264
|
+
if !self.attributes[:rpm_verbatim_gem_dependencies?]
|
265
|
+
self.dependencies = self.dependencies.collect do |dependency|
|
266
|
+
# Tries to match rubygem_prefix [1], gem_name [2] and version [3] if present
|
267
|
+
# and return it in rubygem_prefix(gem_name) form
|
268
|
+
if name=/^(#{attributes[:gem_package_name_prefix]})-([^\s]+)\s*(.*)$/.match(dependency)
|
269
|
+
"#{name[1]}(#{name[2]})#{name[3] ? " #{name[3]}" : ""}"
|
270
|
+
else
|
271
|
+
dependency
|
272
|
+
end
|
273
|
+
end
|
274
|
+
end
|
275
|
+
end
|
276
|
+
|
277
|
+
# Convert != dependency as Conflict =, as rpm doesn't understand !=
|
278
|
+
self.dependencies = self.dependencies.select do |dep|
|
279
|
+
name, op, version = dep.split(/\s+/)
|
280
|
+
dep_ok = true
|
281
|
+
if op == '!='
|
282
|
+
self.conflicts << "#{name} = #{version}"
|
283
|
+
dep_ok = false
|
284
|
+
end
|
285
|
+
dep_ok
|
286
|
+
end
|
287
|
+
|
288
|
+
# if --ignore-iteration-in-dependencies is true convert foo = X, to
|
289
|
+
# foo >= X , foo < X+1
|
290
|
+
if self.attributes[:rpm_ignore_iteration_in_dependencies?]
|
291
|
+
self.dependencies = self.dependencies.collect do |dep|
|
292
|
+
name, op, version = dep.split(/\s+/)
|
293
|
+
if op == '='
|
294
|
+
nextversion = version.split('.').collect { |v| v.to_i }
|
295
|
+
nextversion[-1] += 1
|
296
|
+
nextversion = nextversion.join(".")
|
297
|
+
logger.warn("Converting dependency #{dep} to #{name} >= #{version}, #{name} < #{nextversion}")
|
298
|
+
["#{name} >= #{version}", "#{name} < #{nextversion}"]
|
299
|
+
else
|
300
|
+
dep
|
301
|
+
end
|
302
|
+
end.flatten
|
303
|
+
end
|
304
|
+
|
305
|
+
setscript = proc do |scriptname|
|
306
|
+
script_path = self.attributes[scriptname]
|
307
|
+
# Skip scripts not set
|
308
|
+
next if script_path.nil?
|
309
|
+
if !File.exist?(script_path)
|
310
|
+
logger.error("No such file (for #{scriptname.to_s}): #{script_path.inspect}")
|
311
|
+
script_errors << script_path
|
312
|
+
end
|
313
|
+
# Load the script into memory.
|
314
|
+
scripts[scriptname] = File.read(script_path)
|
315
|
+
end
|
316
|
+
|
317
|
+
setscript.call(:rpm_verifyscript)
|
318
|
+
setscript.call(:rpm_posttrans)
|
319
|
+
setscript.call(:rpm_pretrans)
|
320
|
+
end # def converted
|
321
|
+
|
322
|
+
def rpm_get_trigger_type(flag)
|
323
|
+
if (flag & (1 << 25)) == (1 << 25)
|
324
|
+
# RPMSENSE_TRIGGERPREIN = (1 << 25), /*!< %triggerprein dependency. */
|
325
|
+
:rpm_trigger_before_install
|
326
|
+
elsif (flag & (1 << 16)) == (1 << 16)
|
327
|
+
# RPMSENSE_TRIGGERIN = (1 << 16), /*!< %triggerin dependency. */
|
328
|
+
:rpm_trigger_after_install
|
329
|
+
elsif (flag & (1 << 17)) == (1 << 17)
|
330
|
+
# RPMSENSE_TRIGGERUN = (1 << 17), /*!< %triggerun dependency. */
|
331
|
+
:rpm_trigger_before_uninstall
|
332
|
+
elsif (flag & (1 << 18)) == (1 << 18)
|
333
|
+
# RPMSENSE_TRIGGERPOSTUN = (1 << 18), /*!< %triggerpostun dependency. */
|
334
|
+
:rpm_trigger_after_target_uninstall
|
335
|
+
else
|
336
|
+
@logger.fatal("I don't know about this triggerflag ('#{flag}')")
|
337
|
+
end
|
338
|
+
end # def rpm_get_trigger
|
339
|
+
|
340
|
+
def input(path)
|
341
|
+
rpm = ::RPM::File.new(path)
|
342
|
+
|
343
|
+
tags = {}
|
344
|
+
rpm.header.tags.each do |tag|
|
345
|
+
tags[tag.tag] = tag.value
|
346
|
+
end
|
347
|
+
|
348
|
+
self.architecture = tags[:arch]
|
349
|
+
self.category = tags[:group]
|
350
|
+
self.description = tags[:description]
|
351
|
+
self.epoch = (tags[:epoch] || [nil]).first # for some reason epoch is an array
|
352
|
+
self.iteration = tags[:release]
|
353
|
+
self.license = tags[:license]
|
354
|
+
self.maintainer = maintainer
|
355
|
+
self.name = tags[:name]
|
356
|
+
self.url = tags[:url]
|
357
|
+
self.vendor = tags[:vendor]
|
358
|
+
self.version = tags[:version]
|
359
|
+
|
360
|
+
self.scripts[:before_install] = tags[:prein]
|
361
|
+
self.scripts[:after_install] = tags[:postin]
|
362
|
+
self.scripts[:before_remove] = tags[:preun]
|
363
|
+
self.scripts[:after_remove] = tags[:postun]
|
364
|
+
self.scripts[:rpm_verifyscript] = tags[:verifyscript]
|
365
|
+
self.scripts[:rpm_posttrans] = tags[:posttrans]
|
366
|
+
self.scripts[:rpm_pretrans] = tags[:pretrans]
|
367
|
+
# TODO(sissel): prefix these scripts above with a shebang line if there isn't one?
|
368
|
+
# Also taking into account the value of tags[preinprog] etc, something like:
|
369
|
+
# #!#{tags[:preinprog]}
|
370
|
+
# #{tags[prein]}
|
371
|
+
|
372
|
+
if !tags[:triggerindex].nil?
|
373
|
+
val = tags[:triggerindex].zip(tags[:triggername],tags[:triggerflags],tags[:triggerversion]).group_by{ |x| x[0]}
|
374
|
+
val = val.collect do |order,data|
|
375
|
+
new_data = data.collect { |x| [ x[1], rpm.operator(x[2]), x[3]].join(" ").strip}.join(", ")
|
376
|
+
[order, rpm_get_trigger_type(data[0][2]), new_data]
|
377
|
+
end
|
378
|
+
val.each do |order, attr,data|
|
379
|
+
self.attributes[attr] = [] if self.attributes[attr].nil?
|
380
|
+
scriptprog = (tags[:triggerscriptprog][order] == '/bin/sh') ? "" : "-p #{tags[:triggerscriptprog][order]}"
|
381
|
+
self.attributes[attr] << [data,tags[:triggerscripts][order],scriptprog]
|
382
|
+
end
|
383
|
+
end
|
384
|
+
|
385
|
+
if !attributes[:no_auto_depends?]
|
386
|
+
self.dependencies += rpm.requires.collect do |name, operator, version|
|
387
|
+
[name, operator, version].join(" ")
|
388
|
+
end
|
389
|
+
end
|
390
|
+
|
391
|
+
self.conflicts += rpm.conflicts.collect do |name, operator, version|
|
392
|
+
[name, operator, version].join(" ")
|
393
|
+
end
|
394
|
+
self.provides += rpm.provides.collect do |name, operator, version|
|
395
|
+
[name, operator, version].join(" ")
|
396
|
+
end
|
397
|
+
#input.replaces += replaces
|
398
|
+
|
399
|
+
self.config_files += rpm.config_files
|
400
|
+
|
401
|
+
# rpms support '%dir' things for specifying empty directories to package,
|
402
|
+
# but the rpm header itself doesn't actually record this information.
|
403
|
+
# so there's no 'directories' to copy, so don't try to merge in the
|
404
|
+
# 'directories' feature.
|
405
|
+
# TODO(sissel): If you want this feature, we'll have to find scan
|
406
|
+
# the extracted rpm for empty directories. I'll wait until someone asks for
|
407
|
+
# this feature
|
408
|
+
#self.directories += rpm.directories
|
409
|
+
|
410
|
+
# Extract to the staging directory
|
411
|
+
rpm.extract(staging_path)
|
412
|
+
end # def input
|
413
|
+
|
414
|
+
def prefixed_path(path)
|
415
|
+
Pathname.new(path).absolute?() ? path : File.join(self.prefix, path)
|
416
|
+
end # def prefixed_path
|
417
|
+
|
418
|
+
def output(output_path)
|
419
|
+
output_check(output_path)
|
420
|
+
%w(BUILD RPMS SRPMS SOURCES SPECS).each { |d| FileUtils.mkdir_p(build_path(d)) }
|
421
|
+
args = ["rpmbuild", "-bb"]
|
422
|
+
|
423
|
+
if %x{uname -m}.chomp != self.architecture
|
424
|
+
rpm_target = self.architecture
|
425
|
+
end
|
426
|
+
|
427
|
+
# issue #309
|
428
|
+
if !attributes[:rpm_os].nil?
|
429
|
+
rpm_target = "#{architecture}-unknown-#{attributes[:rpm_os]}"
|
430
|
+
end
|
431
|
+
|
432
|
+
# issue #707
|
433
|
+
if !rpm_target.nil?
|
434
|
+
args += ["--target", rpm_target]
|
435
|
+
end
|
436
|
+
|
437
|
+
# set the rpm dist tag
|
438
|
+
args += ["--define", "dist .#{attributes[:rpm_dist]}"] if attributes[:rpm_dist]
|
439
|
+
|
440
|
+
args += [
|
441
|
+
"--define", "buildroot #{build_path}/BUILD",
|
442
|
+
"--define", "_topdir #{build_path}",
|
443
|
+
"--define", "_sourcedir #{build_path}",
|
444
|
+
"--define", "_rpmdir #{build_path}/RPMS",
|
445
|
+
"--define", "_tmppath #{attributes[:workdir]}"
|
446
|
+
]
|
447
|
+
|
448
|
+
args += ["--sign"] if attributes[:rpm_sign?]
|
449
|
+
|
450
|
+
if attributes[:rpm_auto_add_directories?]
|
451
|
+
fs_dirs_list = File.join(template_dir, "rpm", "filesystem_list")
|
452
|
+
fs_dirs = File.readlines(fs_dirs_list).reject { |x| x =~ /^\s*#/}.map { |x| x.chomp }
|
453
|
+
fs_dirs.concat((attributes[:auto_add_exclude_directories] or []))
|
454
|
+
|
455
|
+
Find.find(staging_path) do |path|
|
456
|
+
next if path == staging_path
|
457
|
+
if File.directory? path and !File.symlink? path
|
458
|
+
add_path = path.gsub(/^#{staging_path}/,'')
|
459
|
+
self.directories << add_path if not fs_dirs.include? add_path
|
460
|
+
end
|
461
|
+
end
|
462
|
+
else
|
463
|
+
self.directories = self.directories.map { |x| self.prefixed_path(x) }
|
464
|
+
alldirs = []
|
465
|
+
self.directories.each do |path|
|
466
|
+
Find.find(File.join(staging_path, path)) do |subpath|
|
467
|
+
if File.directory? subpath and !File.symlink? subpath
|
468
|
+
alldirs << subpath.gsub(/^#{staging_path}/, '')
|
469
|
+
end
|
470
|
+
end
|
471
|
+
end
|
472
|
+
self.directories = alldirs
|
473
|
+
end
|
474
|
+
|
475
|
+
# scan all conf file paths for files and add them
|
476
|
+
allconfigs = []
|
477
|
+
self.config_files.each do |path|
|
478
|
+
cfg_path = File.join(staging_path, path)
|
479
|
+
raise "Config file path #{cfg_path} does not exist" unless File.exist?(cfg_path)
|
480
|
+
Find.find(cfg_path) do |p|
|
481
|
+
allconfigs << p.gsub("#{staging_path}/", '') if File.file? p
|
482
|
+
end
|
483
|
+
end
|
484
|
+
allconfigs.sort!.uniq!
|
485
|
+
|
486
|
+
self.config_files = allconfigs.map { |x| File.join("/", x) }
|
487
|
+
|
488
|
+
# add init script if present
|
489
|
+
(attributes[:rpm_init_list] or []).each do |init|
|
490
|
+
name = File.basename(init, ".init")
|
491
|
+
dest_init = File.join(staging_path, "etc/init.d/#{name}")
|
492
|
+
FileUtils.mkdir_p(File.dirname(dest_init))
|
493
|
+
FileUtils.cp init, dest_init
|
494
|
+
File.chmod(0755, dest_init)
|
495
|
+
end
|
496
|
+
|
497
|
+
(attributes[:rpm_rpmbuild_define] or []).each do |define|
|
498
|
+
args += ["--define", define]
|
499
|
+
end
|
500
|
+
|
501
|
+
# copy all files from staging to BUILD dir
|
502
|
+
Find.find(staging_path) do |path|
|
503
|
+
src = path.gsub(/^#{staging_path}/, '')
|
504
|
+
dst = File.join(build_path, build_sub_dir, src)
|
505
|
+
copy_entry(path, dst)
|
506
|
+
end
|
507
|
+
|
508
|
+
rpmspec = template("rpm.erb").result(binding)
|
509
|
+
specfile = File.join(build_path("SPECS"), "#{name}.spec")
|
510
|
+
File.write(specfile, rpmspec)
|
511
|
+
|
512
|
+
edit_file(specfile) if attributes[:edit?]
|
513
|
+
|
514
|
+
args << specfile
|
515
|
+
|
516
|
+
logger.info("Running rpmbuild", :args => args)
|
517
|
+
safesystem(*args)
|
518
|
+
|
519
|
+
::Dir["#{build_path}/RPMS/**/*.rpm"].each do |rpmpath|
|
520
|
+
# This should only output one rpm, should we verify this?
|
521
|
+
FileUtils.cp(rpmpath, output_path)
|
522
|
+
end
|
523
|
+
end # def output
|
524
|
+
|
525
|
+
def prefix
|
526
|
+
return (attributes[:prefix] or "/")
|
527
|
+
end # def prefix
|
528
|
+
|
529
|
+
def build_sub_dir
|
530
|
+
return "BUILD"
|
531
|
+
#return File.join("BUILD", prefix)
|
532
|
+
end # def build_sub_dir
|
533
|
+
|
534
|
+
def summary
|
535
|
+
if !attributes[:rpm_summary]
|
536
|
+
return @description.split("\n").first || "_"
|
537
|
+
end
|
538
|
+
|
539
|
+
return attributes[:rpm_summary]
|
540
|
+
end # def summary
|
541
|
+
|
542
|
+
def version
|
543
|
+
if @version.kind_of?(String) and @version.include?("-")
|
544
|
+
logger.warn("Package version '#{@version}' includes dashes, converting" \
|
545
|
+
" to underscores")
|
546
|
+
@version = @version.gsub(/-/, "_")
|
547
|
+
end
|
548
|
+
|
549
|
+
return @version
|
550
|
+
end
|
551
|
+
|
552
|
+
# The default epoch value must be nil, see #381
|
553
|
+
def epoch
|
554
|
+
return @epoch if @epoch.is_a?(Numeric)
|
555
|
+
|
556
|
+
if @epoch.nil? or @epoch.empty?
|
557
|
+
logger.warn("no value for epoch is set, defaulting to nil")
|
558
|
+
return nil
|
559
|
+
end
|
560
|
+
|
561
|
+
return @epoch
|
562
|
+
end # def epoch
|
563
|
+
|
564
|
+
def to_s(format=nil)
|
565
|
+
if format.nil?
|
566
|
+
return super("NAME-VERSION-ITERATION.DIST.ARCH.TYPE").gsub('DIST', attributes[:rpm_dist]) if attributes[:rpm_dist]
|
567
|
+
return super("NAME-VERSION-ITERATION.ARCH.TYPE")
|
568
|
+
end
|
569
|
+
return super(format)
|
570
|
+
end # def to_s
|
571
|
+
|
572
|
+
def payload_compression
|
573
|
+
return COMPRESSION_MAP[attributes[:rpm_compression]]
|
574
|
+
end # def payload_compression
|
575
|
+
|
576
|
+
def digest_algorithm
|
577
|
+
return DIGEST_ALGORITHM_MAP[attributes[:rpm_digest]]
|
578
|
+
end # def digest_algorithm
|
579
|
+
|
580
|
+
public(:input, :output, :converted_from, :architecture, :to_s, :iteration,
|
581
|
+
:payload_compression, :digest_algorithm, :prefix, :build_sub_dir,
|
582
|
+
:summary, :epoch, :version, :prefixed_path)
|
583
|
+
end # class FPM::Package::RPM
|