fpm-itchio 1.4.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 +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
|