Cross package maker. DEB/RPM generation or conversion. Derived from jordansissel/fpm.

⌈⌋ branch:  cross package maker


Check-in [4e74257a17]

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
SHA1:4e74257a171d168a8e69ef9d4f500b3d4b76e20c
Date: 2014-10-25 05:36:37
User: jls
Comment:Add input and output rpm trigger support This adds several rpm-specific flags: --before-install --after-install --before-uninstall --after-target-uninstall Fixes #626 (merged by hand)
Tags And Properties
  • sym-trunk inherited from [2b439be7d6]
Context
2014-10-25
05:41
[795fc2ae89] Add npm specs (user: jls, tags: trunk)
05:36
[4e74257a17] Add input and output rpm trigger support This adds several rpm-specific flags: --before-install --after-install --before-uninstall --after-target-uninstall Fixes #626 (merged by hand) (user: jls, tags: trunk)
05:28
[d84b9cf55e] Move from @logger ivar to logger method. Tests pass. Hope is all we have. And hugs. (user: jls, tags: trunk)
Changes

Changes to lib/fpm/package/rpm.rb.

131
132
133
134
135
136
137















138
139
140
141
142
143
144
...
278
279
280
281
282
283
284















285
286
287
288
289
290
291
...
309
310
311
312
313
314
315
316











317
318
319
320
321
322
323
    "pretrans script" do |val|
    File.expand_path(val) # Get the full path to the script
  end # --pretrans
  option "--posttrans", "FILE",
    "posttrans script" do |val|
    File.expand_path(val) # Get the full path to the script
  end # --posttrans















  private

  # Fix path name
  # Replace [ with [\[] to make rpm not use globs
  # Replace * with [*] to make rpm not use globs
  # Replace ? with [?] to make rpm not use globs
  # Replace % with [%] to make rpm not expand macros
................................................................................
    end

  setscript.call(:rpm_verifyscript)
  setscript.call(:rpm_posttrans)
  setscript.call(:rpm_pretrans)
  end # def converted
















  def input(path)
    rpm = ::RPM::File.new(path)

    tags = {}
    rpm.header.tags.each do |tag|
      tags[tag.tag] = tag.value
    end
................................................................................
    self.scripts[:rpm_verifyscript] = tags[:verifyscript]
    self.scripts[:rpm_posttrans] = tags[:posttrans]
    self.scripts[:rpm_pretrans] = tags[:pretrans]
    # TODO(sissel): prefix these scripts above with a shebang line if there isn't one?
    # Also taking into account the value of tags[preinprog] etc, something like:
    #    #!#{tags[:preinprog]}
    #    #{tags[prein]}
    # TODO(sissel): put 'trigger scripts' stuff into attributes












    if !attributes[:no_auto_depends?]
      self.dependencies += rpm.requires.collect do |name, operator, version|
        [name, operator, version].join(" ")
      end
    end








>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







 







<
>
>
>
>
>
>
>
>
>
>
>







131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
...
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
...
339
340
341
342
343
344
345

346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
    "pretrans script" do |val|
    File.expand_path(val) # Get the full path to the script
  end # --pretrans
  option "--posttrans", "FILE",
    "posttrans script" do |val|
    File.expand_path(val) # Get the full path to the script
  end # --posttrans

  ["before-install","after-install","before-uninstall","after-target-uninstall"].each do |trigger_type|
     rpm_trigger = []
     option "--trigger-#{trigger_type}", "'[OPT]PACKAGE: FILEPATH'", "Adds a rpm trigger script located in FILEPATH, " \
            "having 'OPT' options and linking to 'PACKAGE'. PACKAGE can be a comma seperated list of packages. " \
            "See: http://rpm.org/api/4.4.2.2/triggers.html" do |trigger|
       match = trigger.match(/^(\[.*\]|)(.*): (.*)$/)
       @logger.fatal("Trigger '#{trigger_type}' definition can't be parsed ('#{trigger}')") unless match
       opt, pkg, file = match.captures
       @logger.fatal("File given for --trigger-#{trigger_type} does not exist (#{file})") unless File.exists?(file)
       rpm_trigger << [pkg, File.read(file), opt.tr('[]','')]
       next rpm_trigger
     end
   end
 
  private

  # Fix path name
  # Replace [ with [\[] to make rpm not use globs
  # Replace * with [*] to make rpm not use globs
  # Replace ? with [?] to make rpm not use globs
  # Replace % with [%] to make rpm not expand macros
................................................................................
    end

  setscript.call(:rpm_verifyscript)
  setscript.call(:rpm_posttrans)
  setscript.call(:rpm_pretrans)
  end # def converted

  def rpm_get_trigger_type(flag)
    puts "#{flag.to_s(2)}"
    if (flag & (1 << 25)) == (1 << 25)
       :rpm_trigger_before_install
    elsif (flag & (1 << 16)) == (1 << 16)
       :rpm_trigger_after_install
    elsif (flag & (1 << 17)) == (1 << 17)
       :rpm_trigger_before_uninstall
    elsif (flag & (1 << 18)) == (1 << 18)
       :rpm_trigger_after_target_uninstall
    else
       @logger.fatal("I don't know about this triggerflag ('#{flag}')")
    end
  end # def rpm_get_trigger

  def input(path)
    rpm = ::RPM::File.new(path)

    tags = {}
    rpm.header.tags.each do |tag|
      tags[tag.tag] = tag.value
    end
................................................................................
    self.scripts[:rpm_verifyscript] = tags[:verifyscript]
    self.scripts[:rpm_posttrans] = tags[:posttrans]
    self.scripts[:rpm_pretrans] = tags[:pretrans]
    # TODO(sissel): prefix these scripts above with a shebang line if there isn't one?
    # Also taking into account the value of tags[preinprog] etc, something like:
    #    #!#{tags[:preinprog]}
    #    #{tags[prein]}


    val = tags[:triggerindex].zip(tags[:triggername],tags[:triggerflags],tags[:triggerversion]).group_by{ |x| x[0]}
    val = val.collect do |order,data|
      new_data = data.collect { |x| [ x[1], rpm.operator(x[2]), x[3]].join(" ").strip}.join(", ")
      [order, rpm_get_trigger_type(data[0][2]), new_data]
    end
    val.each do |order, attr,data|
      self.attributes[attr] = [] if self.attributes[attr].nil?
      scriptprog = (tags[:triggerscriptprog][order] == '/bin/sh') ? "" : "-p #{tags[:triggerscriptprog][order]}"
      self.attributes[attr] << [data,tags[:triggerscripts][order],scriptprog]
    end

    if !attributes[:no_auto_depends?]
      self.dependencies += rpm.requires.collect do |name, operator, version|
        [name, operator, version].join(" ")
      end
    end

Changes to spec/fpm/package/rpm_spec.rb.

151
152
153
154
155
156
157






158
159
160
161
162
163
164
...
256
257
258
259
260
261
262




































263
264
265
266
267
268
269
        subject.scripts[:before_remove] = "example before_remove"
        subject.scripts[:after_remove] = "example after_remove"
        subject.scripts[:rpm_verifyscript] = "example rpm_verifyscript"
        subject.scripts[:rpm_posttrans] = "example rpm_posttrans"
        subject.scripts[:rpm_pretrans] = "example rpm_pretrans"








        # Write the rpm out
        subject.output(@target)

        # Read the rpm
        @rpm = ::RPM::File.new(@target)

        @rpmtags = {}
................................................................................
        insist { @rpm.tags[:preinprog] } == "/bin/sh"
      end

      it "should have the correct 'postin' script" do
        insist { @rpm.tags[:postin] } == "example after_install"
        insist { @rpm.tags[:postinprog] } == "/bin/sh"
      end





































      it "should use md5/gzip by default" do
        insist { @rpmtags[:payloadcompressor] } == "gzip"

        # For whatever reason, the 'filedigestalgo' tag is an array of numbers.
        # I only ever see one element in this array, so just do value.first
        # 







>
>
>
>
>
>







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
...
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
        subject.scripts[:before_remove] = "example before_remove"
        subject.scripts[:after_remove] = "example after_remove"
        subject.scripts[:rpm_verifyscript] = "example rpm_verifyscript"
        subject.scripts[:rpm_posttrans] = "example rpm_posttrans"
        subject.scripts[:rpm_pretrans] = "example rpm_pretrans"


        # Test for triggers #626
        subject.attributes[:rpm_trigger_before_install] = [["test","#!/bin/sh\necho before_install trigger executed\n"]]
        subject.attributes[:rpm_trigger_after_install] = [["test","#!/bin/sh\necho after_install trigger executed\n"]]
        subject.attributes[:rpm_trigger_before_uninstall] = [["test","#!/bin/sh\necho before_uninstall trigger executed\n"]]
        subject.attributes[:rpm_trigger_after_target_uninstall] = [["test","#!/bin/sh\necho after_target_uninstall trigger executed\n"]]

        # Write the rpm out
        subject.output(@target)

        # Read the rpm
        @rpm = ::RPM::File.new(@target)

        @rpmtags = {}
................................................................................
        insist { @rpm.tags[:preinprog] } == "/bin/sh"
      end

      it "should have the correct 'postin' script" do
        insist { @rpm.tags[:postin] } == "example after_install"
        insist { @rpm.tags[:postinprog] } == "/bin/sh"
      end
 
      it "should have the correct 'before_install' trigger script" do
        insist { @rpm.tags[:triggername][0] } == "test"
        insist { @rpm.tags[:triggerversion][0] } == ""
        insist { @rpm.tags[:triggerflags][0] & (1 << 25)} == ( 1 << 25) # See FPM::Package::RPM#rpm_get_trigger_type
        insist { @rpm.tags[:triggerindex][0] } == 0
        insist { @rpm.tags[:triggerscriptprog][0] } == "/bin/sh"
        insist { @rpm.tags[:triggerscripts][0] } == "#!/bin/sh\necho before_install trigger executed"
      end

      it "should have the correct 'after_install' trigger script" do
        insist { @rpm.tags[:triggername][1] } == "test"
        insist { @rpm.tags[:triggerversion][1] } == ""
        insist { @rpm.tags[:triggerflags][1] & (1 << 16)} == ( 1 << 16) # See FPM::Package::RPM#rpm_get_trigger_type
        insist { @rpm.tags[:triggerindex][1] } == 1
        insist { @rpm.tags[:triggerscriptprog][1] } == "/bin/sh"
        insist { @rpm.tags[:triggerscripts][1] } == "#!/bin/sh\necho after_install trigger executed"
      end

      it "should have the correct 'before_uninstall' trigger script" do
        insist { @rpm.tags[:triggername][2] } == "test"
        insist { @rpm.tags[:triggerversion][2] } == ""
        insist { @rpm.tags[:triggerflags][2] & (1 << 17)} == ( 1 << 17) # See FPM::Package::RPM#rpm_get_trigger_type
        insist { @rpm.tags[:triggerindex][2] } == 2
        insist { @rpm.tags[:triggerscriptprog][2] } == "/bin/sh"
        insist { @rpm.tags[:triggerscripts][2] } == "#!/bin/sh\necho before_uninstall trigger executed"
      end

      it "should have the correct 'after_target_uninstall' trigger script" do
        insist { @rpm.tags[:triggername][3] } == "test"
        insist { @rpm.tags[:triggerversion][3] } == ""
        insist { @rpm.tags[:triggerflags][3] & (1 << 18)} == ( 1 << 18) # See FPM::Package::RPM#rpm_get_trigger_type
        insist { @rpm.tags[:triggerindex][3] } == 3
        insist { @rpm.tags[:triggerscriptprog][3] } == "/bin/sh"
        insist { @rpm.tags[:triggerscripts][3] } == "#!/bin/sh\necho after_target_uninstall trigger executed"
      end

      it "should use md5/gzip by default" do
        insist { @rpmtags[:payloadcompressor] } == "gzip"

        # For whatever reason, the 'filedigestalgo' tag is an array of numbers.
        # I only ever see one element in this array, so just do value.first
        # 

Changes to templates/rpm.erb.

185
186
187
188
189
190
191















192
193
194
195
196
197
198
-%>
<% scriptmap.each do |name, rpmname| -%>
<%   if script?(name) -%>
%<%=   rpmname %>
<%=    script(name) %>
<%   end -%>
<% end -%>
















%files
%defattr(<%= attributes[:rpm_defattrfile] %>,<%= attributes[:rpm_user] || "root" %>,<%= attributes[:rpm_group] || "root" %>,<%= attributes[:rpm_defattrdir] %>)
<%# Output config files and then regular files. -%>
<% config_files.each do |path| -%>
%config(noreplace) <%= rpm_file_entry(path) %>
<% end -%>







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
-%>
<% scriptmap.each do |name, rpmname| -%>
<%   if script?(name) -%>
%<%=   rpmname %>
<%=    script(name) %>
<%   end -%>
<% end -%>

<%# This section adds any triggers, as ordered in the command line -%>
<%
  triggermap = {
    :before_install => "prein",
    :after_install => "in",
    :before_uninstall => "un",
    :after_target_uninstall => "postun"
  } 
  triggermap.each do |name, rpmtype|
    (attributes["rpm_trigger_#{name}".to_sym] or []).each do |trigger_name, trigger_script, trigger_scriptprog| -%>
%trigger<%= rpmtype -%> <%= trigger_scriptprog -%> -- <%= trigger_name %>
<%= trigger_script %>
<%   end -%>
<% end -%>

%files
%defattr(<%= attributes[:rpm_defattrfile] %>,<%= attributes[:rpm_user] || "root" %>,<%= attributes[:rpm_group] || "root" %>,<%= attributes[:rpm_defattrdir] %>)
<%# Output config files and then regular files. -%>
<% config_files.each do |path| -%>
%config(noreplace) <%= rpm_file_entry(path) %>
<% end -%>