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

⌈⌋ branch:  cross package maker


Check-in [d80d7e6df3]

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

Overview
SHA1:d80d7e6df32e5fd48d145c4c2479bb825305734f
Date: 2013-04-19 15:42:02
User: jls
Comment:Merge pull request #414 from r4um/auto_rpm_dirs Fix #199 Auto add directories for rpm.
Tags And Properties
  • sym-trunk inherited from [2b439be7d6]
Context
2013-04-22
15:43
[710c018141] Merge pull request #420 from r4um/fix_258 #258 Make root/root as owner of control files (user: jls, tags: trunk)
09:42
[d7ed65f844] #258 Make root/root as owner of control files (user: pranay.kanwar, tags: trunk)
05:49
[618e87df21] #411 Translate noarch architecture to all for debian (user: pranay.kanwar, tags: trunk)
05:42
[ace42aee1b] Do no generate empty prefix (user: pranay.kanwar, tags: trunk)
2013-04-19
15:42
[d80d7e6df3] Merge pull request #414 from r4um/auto_rpm_dirs Fix #199 Auto add directories for rpm. (user: jls, tags: trunk)
15:41
[1445d61281] Merge pull request #417 from rafacas/master Fixed an error showed by puppet if the EMPTY file is very large (user: jls, tags: trunk)
2013-04-17
16:10
[3514279ff8] #353 Remove trailing slash from prefix (user: pranay.kanwar, tags: trunk)
Changes

Changes to lib/fpm/package.rb.

308
309
310
311
312
313
314
315
316



317
318
319
320
321
322
323
    # but requires the 'backports' gem (which is used in other places in fpm)
    return Enumerator.new { |y| Find.find(staging_path) { |path| y << path } } \
      .select { |path| path != staging_path } \
      .select { |path| is_leaf.call(path) } \
      .collect { |path| path[staging_path.length + 1.. -1] }
  end # def files
 
  def template(path)
    template_dir = File.expand_path(File.join(File.dirname(__FILE__), "..", "..", "templates"))



    template_path = File.join(template_dir, path)
    template_code = File.read(template_path)
    @logger.info("Reading template", :path => template_path)
    erb = ERB.new(template_code, nil, "-")
    erb.filename = template_path
    return erb
  end # def template







|
|
>
>
>







308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
    # but requires the 'backports' gem (which is used in other places in fpm)
    return Enumerator.new { |y| Find.find(staging_path) { |path| y << path } } \
      .select { |path| path != staging_path } \
      .select { |path| is_leaf.call(path) } \
      .collect { |path| path[staging_path.length + 1.. -1] }
  end # def files
 
  def template_dir
    File.expand_path(File.join(File.dirname(__FILE__), "..", "..", "templates"))
  end

  def template(path)
    template_path = File.join(template_dir, path)
    template_code = File.read(template_path)
    @logger.info("Reading template", :path => template_path)
    erb = ERB.new(template_code, nil, "-")
    erb.filename = template_path
    return erb
  end # def template

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

78
79
80
81
82
83
84


85
86













87

88
89
90
91
92
93
94
...
261
262
263
264
265
266
267


























268
269
270
271
272
273
274

  option "--changelog", "FILEPATH", "Add changelog from FILEPATH contents" do |file|
    File.read(File.expand_path(file))
  end

  option "--sign", :flag, "Pass --sign to rpmbuild"



  private














  def rpm_file_entry(file)

    return file unless attributes[:rpm_use_file_permissions?]

    stat = File.stat( file.gsub(/\"/, '') )
    user = Etc.getpwuid(stat.uid).name
    group = Etc.getgrgid(stat.gid).name
    mode = stat.mode
    return sprintf("%%attr(%o, %s, %s) %s\n", mode & 4095 , user, group, file)
................................................................................
      "--define", "_topdir #{build_path}",
      "--define", "_sourcedir #{build_path}",
      "--define", "_rpmdir #{build_path}/RPMS",
    ]

    args += ["--sign"] if attributes[:rpm_sign?]



























    (attributes[:rpm_rpmbuild_define] or []).each do |define|
      args += ["--define", define]
    end

    rpmspec = template("rpm.erb").result(binding)
    specfile = File.join(build_path("SPECS"), "#{name}.spec")
    File.write(specfile, rpmspec)







>
>


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

>







 







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







78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
...
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
312
313
314
315
316

  option "--changelog", "FILEPATH", "Add changelog from FILEPATH contents" do |file|
    File.read(File.expand_path(file))
  end

  option "--sign", :flag, "Pass --sign to rpmbuild"

  option "--auto-add-directories", :flag, "Auto add directories not part of filesystem"

  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
  def rpm_fix_name(name)
    name = "\"#{name}\"" if name[/\s/]
    name = name.gsub("[", "[\\[]")
    name = name.gsub("*", "[*]")
    name = name.gsub("?", "[?]")
    name = name.gsub("%", "[%]")
  end

  def rpm_file_entry(file)
    file = rpm_fix_name(file)
    return file unless attributes[:rpm_use_file_permissions?]

    stat = File.stat( file.gsub(/\"/, '') )
    user = Etc.getpwuid(stat.uid).name
    group = Etc.getgrgid(stat.gid).name
    mode = stat.mode
    return sprintf("%%attr(%o, %s, %s) %s\n", mode & 4095 , user, group, file)
................................................................................
      "--define", "_topdir #{build_path}",
      "--define", "_sourcedir #{build_path}",
      "--define", "_rpmdir #{build_path}/RPMS",
    ]

    args += ["--sign"] if attributes[:rpm_sign?]

    if attributes[:rpm_auto_add_directories?]
      fs_dirs_list = File.join(template_dir, "rpm", "filesystem_list")
      fs_dirs = File.readlines(fs_dirs_list).reject { |x| x =~ /^\s*#/}.map { |x| x.chomp }

      Find.find(staging_path) do |path|
        next if path == staging_path
        if File.directory? path
          add_path = path.gsub(/^#{staging_path}/,'')
          self.directories << add_path if not fs_dirs.include? add_path
        end
      end
    else
      self.directories = self.directories.map { |x| File.join(self.prefix, x) }
      alldirs = []
      self.directories.each do |path|
        Find.find(File.join(staging_path, path)) do |subpath|
          if File.directory? subpath
            alldirs << subpath.gsub(/^#{staging_path}/, '')
          end
        end
      end
      self.directories = alldirs
    end

    self.config_files = self.config_files.map { |x| File.join(self.prefix, x) }

    (attributes[:rpm_rpmbuild_define] or []).each do |define|
      args += ["--define", define]
    end

    rpmspec = template("rpm.erb").result(binding)
    specfile = File.join(build_path("SPECS"), "#{name}.spec")
    File.write(specfile, rpmspec)

Changes to templates/rpm.erb.

23
24
25
26
27
28
29

30
31
32
33
34
35
36
37
38
...
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
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
<%# use the first line of the description as the summary -%>
Summary: <%= description.split("\n").first.empty? ? "_" :  description.split("\n").first %>
BuildArch: <%= architecture %>
AutoReqProv: no
# Seems specifying BuildRoot is required on older rpmbuild (like on CentOS 5)
# fpm passes '--define buildroot ...' on the commandline, so just reuse that.
BuildRoot: %buildroot

<% if !prefix.nil? and !prefix.empty? %>
Prefix: <%= prefix %>
<% end -%>

Group: <%= category %>
<%# Sometimes the 'license' field has multiple lines... Hack around it. 
  # While technically yes this means we are 'modifying' the license,
  # since the job of FPM is to get shit done and that this is  only
  # modifying whitespace, it should be reasonably OK. -%>
................................................................................
<%   end -%>
<% end -%>

%files
%defattr(-,<%= attributes[:rpm_user] %>,<%= attributes[:rpm_group] %>,-)
<%# Output config files and then regular files. -%>
<% config_files.each do |path| -%>
%config(noreplace) <%= File.join(prefix, path) %>
<% end -%>
<% subdirs = [] -%>
<% directories.each do |path| -%>
%dir <%= rpm_file_entry(File.join(prefix, path)) %>
<%#  We need to include hidden directories, but exclude . and .. -%>
<%   ::Dir.glob("#{path}/**/*/", File::FNM_DOTMATCH) do |subdir| -%>
<%     next if File.basename(subdir) =~ /^\.+$/ -%>
%dir <%= rpm_file_entry(File.join(prefix, subdir)) %>
<% subdirs << subdir -%>
<%   end -%>
<% end -%>
<%# list only files, not directories? -%>
<%= 
  # Reject config files already listed or parent directories, then prefix files
  # with "/", then make sure paths with spaces are quoted. I hate rpm so much.

  # 'files' here is the method FPM::Package#files.
  # The 'files' section of rpm can be 
  # 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
  files.collect { |f| "/#{f}" } \


    .reject { |f| config_files.include?(f) } \
    .reject { |f| subdirs.include?("#{f}/") } \
    .collect { |f| f[/\s/] and "\"#{f}\"" or f } \
    .collect { |f| f.gsub("[", "[\\[]") } \
    .collect { |f| f.gsub("*", "[*]") } \
    .collect { |f| f.gsub("?", "[?]") } \
    .collect { |f| f.gsub("%", "[%]") } \

    .map { |f| rpm_file_entry(f) } \
    .join("\n")
    #.collect { |f| File.join(prefix, f) } \
%>


%changelog
<%= attributes[:rpm_changelog] %>







>

|







 







|

|

|
<
<
<
<
<
<


<
|
|
<
<
<
<
<
<
<
<
>
>
|
<
<
<
<
<
<
>
|
<
<
<
>



23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
...
112
113
114
115
116
117
118
119
120
121
122
123






124
125

126
127








128
129
130






131
132



133
134
135
136
<%# use the first line of the description as the summary -%>
Summary: <%= description.split("\n").first.empty? ? "_" :  description.split("\n").first %>
BuildArch: <%= architecture %>
AutoReqProv: no
# Seems specifying BuildRoot is required on older rpmbuild (like on CentOS 5)
# fpm passes '--define buildroot ...' on the commandline, so just reuse that.
BuildRoot: %buildroot
# Add prefix, must not end with /
<% if !prefix.nil? and !prefix.empty? %>
Prefix: <%= prefix.gsub(/\/$/, '') %>
<% end -%>

Group: <%= category %>
<%# Sometimes the 'license' field has multiple lines... Hack around it. 
  # While technically yes this means we are 'modifying' the license,
  # since the job of FPM is to get shit done and that this is  only
  # modifying whitespace, it should be reasonably OK. -%>
................................................................................
<%   end -%>
<% end -%>

%files
%defattr(-,<%= attributes[:rpm_user] %>,<%= attributes[:rpm_group] %>,-)
<%# Output config files and then regular files. -%>
<% config_files.each do |path| -%>
%config(noreplace) <%= rpm_fix_name(path) %>
<% end -%>
<%# list directories %>
<% directories.each do |path| -%>
%dir <%= rpm_file_entry(path) %>






<% end -%>
<%# list only files, not directories? -%>

# Reject config files already listed or parent directories, then prefix files
# with "/", then make sure paths with spaces are quoted. I hate rpm so much.








<% files.each do |path| -%>
<%   path = "/#{path}" -%>
<%   next if config_files.include?(path)-%>






<%   next if directories.include?(path)-%>
<%= rpm_file_entry(path) %>



<% end -%>

%changelog
<%= attributes[:rpm_changelog] %>

Added templates/rpm/filesystem_list.

more than 10,000 changes