cure-fpm 1.3.3b → 1.6.0b

Sign up to get free protection for your applications and to get access to all the features.
Files changed (46) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELIST +73 -0
  3. data/CONTRIBUTORS +1 -1
  4. data/LICENSE +1 -1
  5. data/lib/fpm.rb +2 -0
  6. data/lib/fpm/command.rb +100 -50
  7. data/lib/fpm/package.rb +42 -28
  8. data/lib/fpm/package/apk.rb +510 -0
  9. data/lib/fpm/package/cpan.rb +50 -25
  10. data/lib/fpm/package/deb.rb +211 -47
  11. data/lib/fpm/package/dir.rb +29 -28
  12. data/lib/fpm/package/empty.rb +6 -0
  13. data/lib/fpm/package/freebsd.rb +144 -0
  14. data/lib/fpm/package/gem.rb +5 -5
  15. data/lib/fpm/package/npm.rb +2 -2
  16. data/lib/fpm/package/osxpkg.rb +8 -7
  17. data/lib/fpm/package/p5p.rb +124 -0
  18. data/lib/fpm/package/pacman.rb +399 -0
  19. data/lib/fpm/package/pleaserun.rb +63 -0
  20. data/lib/fpm/package/pyfpm/get_metadata.py +9 -1
  21. data/lib/fpm/package/python.rb +19 -7
  22. data/lib/fpm/package/rpm.rb +58 -18
  23. data/lib/fpm/package/sh.rb +1 -7
  24. data/lib/fpm/package/solaris.rb +1 -1
  25. data/lib/fpm/package/tar.rb +14 -2
  26. data/lib/fpm/package/virtualenv.rb +145 -0
  27. data/lib/fpm/package/zip.rb +1 -1
  28. data/lib/fpm/rake_task.rb +60 -0
  29. data/lib/fpm/util.rb +176 -48
  30. data/lib/fpm/util/tar_writer.rb +80 -0
  31. data/lib/fpm/version.rb +1 -1
  32. data/templates/deb/postinst_upgrade.sh.erb +33 -2
  33. data/templates/deb/postrm_upgrade.sh.erb +10 -1
  34. data/templates/deb/preinst_upgrade.sh.erb +11 -2
  35. data/templates/deb/prerm_upgrade.sh.erb +14 -2
  36. data/templates/p5p_metadata.erb +12 -0
  37. data/templates/pacman.erb +47 -0
  38. data/templates/pacman/INSTALL.erb +41 -0
  39. data/templates/pleaserun/generate-cleanup.sh +17 -0
  40. data/templates/pleaserun/install-path.sh +17 -0
  41. data/templates/pleaserun/install.sh +117 -0
  42. data/templates/pleaserun/scripts/after-install.sh +4 -0
  43. data/templates/pleaserun/scripts/before-remove.sh +12 -0
  44. data/templates/rpm.erb +38 -6
  45. data/templates/sh.erb +38 -3
  46. metadata +81 -9
@@ -27,6 +27,12 @@ class FPM::Package::CPAN < FPM::Package
27
27
  option "--perl-lib-path", "PERL_LIB_PATH",
28
28
  "Path of target Perl Libraries"
29
29
 
30
+ option "--sandbox-non-core", :flag,
31
+ "Sandbox all non-core modules, even if they're already installed", :default => true
32
+
33
+ option "--cpanm-force", :flag,
34
+ "Pass the --force parameter to cpanm", :default => false
35
+
30
36
  private
31
37
  def input(package)
32
38
  #if RUBY_VERSION =~ /^1\.8/
@@ -40,7 +46,7 @@ class FPM::Package::CPAN < FPM::Package
40
46
  require "net/http"
41
47
  require "json"
42
48
 
43
- if (attributes[:cpan_local_module?])
49
+ if File.exist?(package)
44
50
  moduledir = package
45
51
  else
46
52
  result = search(package)
@@ -49,20 +55,29 @@ class FPM::Package::CPAN < FPM::Package
49
55
  end
50
56
 
51
57
  # Read package metadata (name, version, etc)
52
- if File.exists?(File.join(moduledir, "META.json"))
53
- metadata = JSON.parse(File.read(File.join(moduledir, ("META.json"))))
54
- elsif File.exists?(File.join(moduledir, ("META.yml")))
58
+ if File.exist?(File.join(moduledir, "META.json"))
59
+ local_metadata = JSON.parse(File.read(File.join(moduledir, ("META.json"))))
60
+ elsif File.exist?(File.join(moduledir, ("META.yml")))
55
61
  require "yaml"
56
- metadata = YAML.load_file(File.join(moduledir, ("META.yml")))
57
- elsif File.exists?(File.join(moduledir, "MYMETA.json"))
58
- metadata = JSON.parse(File.read(File.join(moduledir, ("MYMETA.json"))))
59
- elsif File.exists?(File.join(moduledir, ("MYMETA.yml")))
62
+ local_metadata = YAML.load_file(File.join(moduledir, ("META.yml")))
63
+ elsif File.exist?(File.join(moduledir, "MYMETA.json"))
64
+ local_metadata = JSON.parse(File.read(File.join(moduledir, ("MYMETA.json"))))
65
+ elsif File.exist?(File.join(moduledir, ("MYMETA.yml")))
60
66
  require "yaml"
61
- metadata = YAML.load_file(File.join(moduledir, ("MYMETA.yml")))
62
- else
63
- raise FPM::InvalidPackageConfiguration,
64
- "Could not find package metadata. Checked for META.json and META.yml"
67
+ local_metadata = YAML.load_file(File.join(moduledir, ("MYMETA.yml")))
68
+ end
69
+
70
+ # Merge the MetaCPAN query result and the metadata pulled from the local
71
+ # META file(s). The local data overwrites the query data for all keys the
72
+ # two hashes have in common. Merge with an empty hash if there was no
73
+ # local META file.
74
+ metadata = result.merge(local_metadata || {})
75
+
76
+ if metadata.empty?
77
+ raise FPM::InvalidPackageConfiguration,
78
+ "Could not find package metadata. Checked for META.json, META.yml, and MetaCPAN API data"
65
79
  end
80
+
66
81
  self.version = metadata["version"]
67
82
  self.description = metadata["abstract"]
68
83
 
@@ -100,14 +115,24 @@ class FPM::Package::CPAN < FPM::Package
100
115
  # We'll install to a temporary directory.
101
116
  logger.info("Installing any build or configure dependencies")
102
117
 
103
- cpanm_flags = ["-L", build_path("cpan"), moduledir]
104
- cpanm_flags += ["-n"] if attributes[:cpan_test?]
118
+ if attributes[:cpan_sandbox_non_core?]
119
+ cpanm_flags = ["-L", build_path("cpan"), moduledir]
120
+ else
121
+ cpanm_flags = ["-l", build_path("cpan"), moduledir]
122
+ end
123
+
124
+ # This flag causes cpanm to ONLY download dependencies, skipping the target
125
+ # module itself. This is fine, because the target module has already been
126
+ # downloaded, and there's no need to download twice, test twice, etc.
127
+ cpanm_flags += ["--installdeps"]
128
+ cpanm_flags += ["-n"] if !attributes[:cpan_test?]
105
129
  cpanm_flags += ["--mirror", "#{attributes[:cpan_mirror]}"] if !attributes[:cpan_mirror].nil?
106
130
  cpanm_flags += ["--mirror-only"] if attributes[:cpan_mirror_only?] && !attributes[:cpan_mirror].nil?
131
+ cpanm_flags += ["--force"] if attributes[:cpan_cpanm_force?]
107
132
 
108
133
  safesystem(attributes[:cpan_cpanm_bin], *cpanm_flags)
109
134
 
110
- if !attributes[:no_auto_depends?]
135
+ if !attributes[:no_auto_depends?]
111
136
  unless metadata["requires"].nil?
112
137
  metadata["requires"].each do |dep_name, version|
113
138
  # Special case for representing perl core as a version.
@@ -116,7 +141,7 @@ class FPM::Package::CPAN < FPM::Package
116
141
  next
117
142
  end
118
143
  dep = search(dep_name)
119
-
144
+
120
145
  if dep.include?("distribution")
121
146
  name = fix_name(dep["distribution"])
122
147
  else
@@ -156,7 +181,7 @@ class FPM::Package::CPAN < FPM::Package
156
181
 
157
182
  # Try Makefile.PL, Build.PL
158
183
  #
159
- if File.exists?("Build.PL")
184
+ if File.exist?("Build.PL")
160
185
  # Module::Build is in use here; different actions required.
161
186
  safesystem(attributes[:cpan_perl_bin],
162
187
  "-Mlocal::lib=#{build_path("cpan")}",
@@ -180,7 +205,7 @@ class FPM::Package::CPAN < FPM::Package
180
205
  # Empty install_base to avoid local::lib being used.
181
206
  "--install_base", "")
182
207
  end
183
- elsif File.exists?("Makefile.PL")
208
+ elsif File.exist?("Makefile.PL")
184
209
  if attributes[:cpan_perl_lib_path]
185
210
  perl_lib_path = attributes[:cpan_perl_lib_path]
186
211
  safesystem(attributes[:cpan_perl_bin],
@@ -206,7 +231,7 @@ class FPM::Package::CPAN < FPM::Package
206
231
 
207
232
 
208
233
  else
209
- raise FPM::InvalidPackageConfiguration,
234
+ raise FPM::InvalidPackageConfiguration,
210
235
  "I don't know how to build #{name}. No Makefile.PL nor " \
211
236
  "Build.PL found"
212
237
  end
@@ -231,10 +256,10 @@ class FPM::Package::CPAN < FPM::Package
231
256
  # Find any shared objects in the staging directory to set architecture as
232
257
  # native if found; otherwise keep the 'all' default.
233
258
  Find.find(staging_path) do |path|
234
- if path =~ /\.so$/
259
+ if path =~ /\.so$/
235
260
  logger.info("Found shared library, setting architecture=native",
236
261
  :path => path)
237
- self.architecture = "native"
262
+ self.architecture = "native"
238
263
  end
239
264
  end
240
265
  end
@@ -272,7 +297,7 @@ class FPM::Package::CPAN < FPM::Package
272
297
  release_response = httpfetch(metacpan_release_url)
273
298
  rescue Net::HTTPServerException => e
274
299
  logger.error("metacpan release query failed.", :error => e.message,
275
- :module => package, :url => metacpan_release_url)
300
+ :url => metacpan_release_url)
276
301
  raise FPM::InvalidPackageConfiguration, "metacpan release query failed"
277
302
  end
278
303
 
@@ -280,7 +305,7 @@ class FPM::Package::CPAN < FPM::Package
280
305
  release_metadata = JSON.parse(data)
281
306
  archive = release_metadata["archive"]
282
307
 
283
- # should probably be basepathed from the url
308
+ # should probably be basepathed from the url
284
309
  tarball = File.basename(archive)
285
310
 
286
311
  url_base = "http://www.cpan.org/"
@@ -289,7 +314,7 @@ class FPM::Package::CPAN < FPM::Package
289
314
  #url = "http://www.cpan.org/CPAN/authors/id/#{author[0,1]}/#{author[0,2]}/#{author}/#{tarball}"
290
315
  url = "#{url_base}/authors/id/#{author[0,1]}/#{author[0,2]}/#{author}/#{archive}"
291
316
  logger.debug("Fetching perl module", :url => url)
292
-
317
+
293
318
  begin
294
319
  response = httpfetch(url)
295
320
  rescue Net::HTTPServerException => e
@@ -336,7 +361,7 @@ class FPM::Package::CPAN < FPM::Package
336
361
  def httpfetch(url)
337
362
  uri = URI.parse(url)
338
363
  if ENV['http_proxy']
339
- proxy = URI.parse(ENV['http_proxy'])
364
+ proxy = URI.parse(ENV['http_proxy'])
340
365
  http = Net::HTTP.Proxy(proxy.host,proxy.port,proxy.user,proxy.password).new(uri.host, uri.port)
341
366
  else
342
367
  http = Net::HTTP.new(uri.host, uri.port)
@@ -23,7 +23,7 @@ class FPM::Package::Deb < FPM::Package
23
23
  # The list of supported compression types. Default is gz (gzip)
24
24
  COMPRESSION_TYPES = [ "gz", "bzip2", "xz" ]
25
25
 
26
- option "--ignore-iteration-in-dependencies", :flag,
26
+ option "--ignore-iteration-in-dependencies", :flag,
27
27
  "For '=' (equal) dependencies, allow iterations on the specified " \
28
28
  "version. Default is to be specific. This option allows the same " \
29
29
  "version of a package but any iteration is permitted"
@@ -73,10 +73,10 @@ class FPM::Package::Deb < FPM::Package
73
73
  value.to_i
74
74
  end
75
75
 
76
- option "--priority", "PRIORITY",
76
+ option "--priority", "PRIORITY",
77
77
  "The debian package 'priority' value.", :default => "extra"
78
78
 
79
- option "--use-file-permissions", :flag,
79
+ option "--use-file-permissions", :flag,
80
80
  "Use existing file permissions when defining ownership and modes"
81
81
 
82
82
  option "--user", "USER", "The owner of files in this package", :default => 'root'
@@ -87,6 +87,10 @@ class FPM::Package::Deb < FPM::Package
87
87
  File.expand_path(file)
88
88
  end
89
89
 
90
+ option "--upstream-changelog", "FILEPATH", "Add FILEPATH as upstream changelog" do |file|
91
+ File.expand_path(file)
92
+ end
93
+
90
94
  option "--recommends", "PACKAGE", "Add PACKAGE to Recommends" do |pkg|
91
95
  @recommends ||= []
92
96
  @recommends << pkg
@@ -124,26 +128,42 @@ class FPM::Package::Deb < FPM::Package
124
128
  next @custom_fields
125
129
  end
126
130
 
131
+ option "--no-default-config-files", :flag,
132
+ "Do not add all files in /etc as configuration files by default for Debian packages.",
133
+ :default => false
134
+
135
+ option "--auto-config-files", :flag,
136
+ "Init script and default configuration files will be labeled as " \
137
+ "configuration files for Debian packages.",
138
+ :default => true
139
+
127
140
  option "--shlibs", "SHLIBS", "Include control/shlibs content. This flag " \
128
141
  "expects a string that is used as the contents of the shlibs file. " \
129
142
  "See the following url for a description of this file and its format: " \
130
143
  "http://www.debian.org/doc/debian-policy/ch-sharedlibs.html#s-shlibs"
131
144
 
132
145
  option "--init", "FILEPATH", "Add FILEPATH as an init script",
133
- :multivalued => true do |file|
146
+ :multivalued => true do |file|
134
147
  next File.expand_path(file)
135
148
  end
136
149
 
137
150
  option "--default", "FILEPATH", "Add FILEPATH as /etc/default configuration",
138
- :multivalued => true do |file|
151
+ :multivalued => true do |file|
139
152
  next File.expand_path(file)
140
153
  end
141
154
 
142
155
  option "--upstart", "FILEPATH", "Add FILEPATH as an upstart script",
156
+ :multivalued => true do |file|
157
+ next File.expand_path(file)
158
+ end
159
+
160
+ option "--systemd", "FILEPATH", "Add FILEPATH as a systemd script",
143
161
  :multivalued => true do |file|
144
162
  next File.expand_path(file)
145
163
  end
146
164
 
165
+ option "--systemd-restart-after-upgrade", :flag , "Restart service after upgrade", :default => true
166
+
147
167
  def initialize(*args)
148
168
  super(*args)
149
169
  attributes[:deb_priority] = "extra"
@@ -162,7 +182,7 @@ class FPM::Package::Deb < FPM::Package
162
182
  @architecture = %x{dpkg --print-architecture 2> /dev/null}.chomp
163
183
  if $?.exitstatus != 0 or @architecture.empty?
164
184
  # if dpkg fails or emits nothing, revert back to uname -m
165
- @architecture = %x{uname -m}.chomp
185
+ @architecture = %x{uname -m}.chomp
166
186
  end
167
187
  else
168
188
  @architecture = %x{uname -m}.chomp
@@ -209,7 +229,7 @@ class FPM::Package::Deb < FPM::Package
209
229
 
210
230
  return @name
211
231
  end # def name
212
-
232
+
213
233
  def prefix
214
234
  return (attributes[:prefix] or "/")
215
235
  end # def prefix
@@ -220,14 +240,14 @@ class FPM::Package::Deb < FPM::Package
220
240
  end # def input
221
241
 
222
242
  def extract_info(package)
223
- with(build_path("control")) do |path|
243
+ build_path("control").tap do |path|
224
244
  FileUtils.mkdir(path) if !File.directory?(path)
225
245
  # Unpack the control tarball
226
246
  safesystem("ar p #{package} control.tar.gz | tar -zxf - -C #{path}")
227
247
 
228
248
  control = File.read(File.join(path, "control"))
229
249
 
230
- parse = lambda do |field|
250
+ parse = lambda do |field|
231
251
  value = control[/^#{field.capitalize}: .*/]
232
252
  if value.nil?
233
253
  return nil
@@ -252,7 +272,7 @@ class FPM::Package::Deb < FPM::Package
252
272
  self.name = parse.call("Package")
253
273
  self.url = parse.call("Homepage")
254
274
  self.vendor = parse.call("Vendor") || self.vendor
255
- with(parse.call("Provides")) do |provides_str|
275
+ parse.call("Provides").tap do |provides_str|
256
276
  next if provides_str.nil?
257
277
  self.provides = provides_str.split(/\s*,\s*/)
258
278
  end
@@ -267,6 +287,22 @@ class FPM::Package::Deb < FPM::Package
267
287
  #self.config_files = config_files
268
288
 
269
289
  self.dependencies += parse_depends(parse.call("Depends")) if !attributes[:no_auto_depends?]
290
+
291
+ if File.file?(File.join(path, "preinst"))
292
+ self.scripts[:before_install] = File.read(File.join(path, "preinst"))
293
+ end
294
+ if File.file?(File.join(path, "postinst"))
295
+ self.scripts[:after_install] = File.read(File.join(path, "postinst"))
296
+ end
297
+ if File.file?(File.join(path, "prerm"))
298
+ self.scripts[:before_remove] = File.read(File.join(path, "prerm"))
299
+ end
300
+ if File.file?(File.join(path, "postrm"))
301
+ self.scripts[:after_remove] = File.read(File.join(path, "postrm"))
302
+ end
303
+ if File.file?(File.join(path, "conffiles"))
304
+ self.config_files = File.read(File.join(path, "conffiles")).split("\n")
305
+ end
270
306
  end
271
307
  end # def extract_info
272
308
 
@@ -289,7 +325,7 @@ class FPM::Package::Deb < FPM::Package
289
325
  m = dep_re.match(dep)
290
326
  if m
291
327
  name, op, version = m.captures
292
- # deb uses ">>" and "<<" for greater and less than respectively.
328
+ # deb uses ">>" and "<<" for greater and less than respectively.
293
329
  # fpm wants just ">" and "<"
294
330
  op = "<" if op == "<<"
295
331
  op = ">" if op == ">>"
@@ -309,10 +345,10 @@ class FPM::Package::Deb < FPM::Package
309
345
  when "gz"
310
346
  datatar = "data.tar.gz"
311
347
  compression = "-z"
312
- when "bzip2"
348
+ when "bzip2"
313
349
  datatar = "data.tar.bz2"
314
350
  compression = "-j"
315
- when "xz"
351
+ when "xz"
316
352
  datatar = "data.tar.xz"
317
353
  compression = "-J"
318
354
  else
@@ -351,14 +387,26 @@ class FPM::Package::Deb < FPM::Package
351
387
  end
352
388
  end
353
389
 
354
- if script?(:before_upgrade) or script?(:after_upgrade)
390
+ attributes.fetch(:deb_systemd_list, []).each do |systemd|
391
+ name = File.basename(systemd, ".service")
392
+ dest_systemd = staging_path("lib/systemd/system/#{name}.service")
393
+ mkdir_p(File.dirname(dest_systemd))
394
+ FileUtils.cp(systemd, dest_systemd)
395
+ File.chmod(0644, dest_systemd)
396
+
397
+ # set the attribute with the systemd service name
398
+ attributes[:deb_systemd] = name
399
+ end
400
+
401
+ if script?(:before_upgrade) or script?(:after_upgrade) or attributes[:deb_systemd]
402
+ puts "Adding action files"
355
403
  if script?(:before_install) or script?(:before_upgrade)
356
404
  scripts[:before_install] = template("deb/preinst_upgrade.sh.erb").result(binding)
357
405
  end
358
- if script?(:before_remove)
406
+ if script?(:before_remove) or attributes[:deb_systemd]
359
407
  scripts[:before_remove] = template("deb/prerm_upgrade.sh.erb").result(binding)
360
408
  end
361
- if script?(:after_install) or script?(:after_upgrade)
409
+ if script?(:after_install) or script?(:after_upgrade) or attributes[:deb_systemd]
362
410
  scripts[:after_install] = template("deb/postinst_upgrade.sh.erb").result(binding)
363
411
  end
364
412
  if script?(:after_remove)
@@ -373,7 +421,7 @@ class FPM::Package::Deb < FPM::Package
373
421
  when "gz", nil
374
422
  datatar = build_path("data.tar.gz")
375
423
  compression = "-z"
376
- when "bzip2"
424
+ when "bzip2"
377
425
  datatar = build_path("data.tar.bz2")
378
426
  compression = "-j"
379
427
  when "xz"
@@ -384,9 +432,14 @@ class FPM::Package::Deb < FPM::Package
384
432
  "Unknown compression type '#{self.attributes[:deb_compression]}'"
385
433
  end
386
434
 
387
- # Write the changelog file
435
+ # There are two changelogs that may appear:
436
+ # - debian-specific changelog, which should be archived as changelog.Debian.gz
437
+ # - upstream changelog, which should be archived as changelog.gz
438
+ # see https://www.debian.org/doc/debian-policy/ch-docs.html#s-changelogs
439
+
440
+ # Write the changelog.Debian.gz file
388
441
  dest_changelog = File.join(staging_path, "usr/share/doc/#{name}/changelog.Debian.gz")
389
- FileUtils.mkdir_p(File.dirname(dest_changelog))
442
+ mkdir_p(File.dirname(dest_changelog))
390
443
  File.new(dest_changelog, "wb", 0644).tap do |changelog|
391
444
  Zlib::GzipWriter.new(changelog, Zlib::BEST_COMPRESSION).tap do |changelog_gz|
392
445
  if attributes[:deb_changelog]
@@ -403,10 +456,30 @@ class FPM::Package::Deb < FPM::Package
403
456
  end.close
404
457
  end # No need to close, GzipWriter#close will close it.
405
458
 
459
+ # Write the changelog.gz file (upstream changelog)
460
+ dest_upstream_changelog = File.join(staging_path, "usr/share/doc/#{name}/changelog.gz")
461
+ if attributes[:deb_upstream_changelog]
462
+ File.new(dest_upstream_changelog, "wb", 0644).tap do |changelog|
463
+ Zlib::GzipWriter.new(changelog, Zlib::BEST_COMPRESSION).tap do |changelog_gz|
464
+ logger.info("Writing user-specified upstream changelog", :source => attributes[:deb_upstream_changelog])
465
+ File.new(attributes[:deb_upstream_changelog]).tap do |fd|
466
+ chunk = nil
467
+ # Ruby 1.8.7 doesn't have IO#copy_stream
468
+ changelog_gz.write(chunk) while chunk = fd.read(16384)
469
+ end.close
470
+ end.close
471
+ end # No need to close, GzipWriter#close will close it.
472
+ end
473
+
474
+ if File.exists?(dest_changelog) and not File.exists?(dest_upstream_changelog)
475
+ # see https://www.debian.org/doc/debian-policy/ch-docs.html#s-changelogs
476
+ File.rename(dest_changelog, dest_upstream_changelog)
477
+ end
478
+
406
479
  attributes.fetch(:deb_init_list, []).each do |init|
407
480
  name = File.basename(init, ".init")
408
481
  dest_init = File.join(staging_path, "etc/init.d/#{name}")
409
- FileUtils.mkdir_p(File.dirname(dest_init))
482
+ mkdir_p(File.dirname(dest_init))
410
483
  FileUtils.cp init, dest_init
411
484
  File.chmod(0755, dest_init)
412
485
  end
@@ -414,30 +487,57 @@ class FPM::Package::Deb < FPM::Package
414
487
  attributes.fetch(:deb_default_list, []).each do |default|
415
488
  name = File.basename(default, ".default")
416
489
  dest_default = File.join(staging_path, "etc/default/#{name}")
417
- FileUtils.mkdir_p(File.dirname(dest_default))
490
+ mkdir_p(File.dirname(dest_default))
418
491
  FileUtils.cp default, dest_default
419
492
  File.chmod(0644, dest_default)
420
493
  end
421
494
 
422
495
  attributes.fetch(:deb_upstart_list, []).each do |upstart|
423
496
  name = File.basename(upstart, ".upstart")
424
- dest_upstart = staging_path("etc/init/#{name}.conf")
425
- FileUtils.mkdir_p(File.dirname(dest_upstart))
497
+ name = "#{name}.conf" if !(name =~ /\.conf$/)
498
+ dest_upstart = staging_path("etc/init/#{name}")
499
+ mkdir_p(File.dirname(dest_upstart))
426
500
  FileUtils.cp(upstart, dest_upstart)
427
501
  File.chmod(0644, dest_upstart)
428
502
 
429
503
  # Install an init.d shim that calls upstart
430
- dest_init = staging_path("/etc/init.d/#{name}")
431
- FileUtils.mkdir_p(File.dirname(dest_init))
504
+ dest_init = staging_path("etc/init.d/#{name}")
505
+ mkdir_p(File.dirname(dest_init))
432
506
  FileUtils.ln_s("/lib/init/upstart-job", dest_init)
433
507
  end
434
508
 
509
+ attributes.fetch(:deb_systemd_list, []).each do |systemd|
510
+ name = File.basename(systemd, ".service")
511
+ dest_systemd = staging_path("lib/systemd/system/#{name}.service")
512
+ mkdir_p(File.dirname(dest_systemd))
513
+ FileUtils.cp(systemd, dest_systemd)
514
+ File.chmod(0644, dest_systemd)
515
+ end
516
+
517
+ write_control_tarball
518
+
519
+ # Tar up the staging_path into data.tar.{compression type}
520
+ case self.attributes[:deb_compression]
521
+ when "gz", nil
522
+ datatar = build_path("data.tar.gz")
523
+ compression = "-z"
524
+ when "bzip2"
525
+ datatar = build_path("data.tar.bz2")
526
+ compression = "-j"
527
+ when "xz"
528
+ datatar = build_path("data.tar.xz")
529
+ compression = "-J"
530
+ else
531
+ raise FPM::InvalidPackageConfiguration,
532
+ "Unknown compression type '#{self.attributes[:deb_compression]}'"
533
+ end
534
+
435
535
  args = [ tar_cmd, "-C", staging_path, compression ] + data_tar_flags + [ "-cf", datatar, "." ]
436
536
  safesystem(*args)
437
537
 
438
538
  # pack up the .deb, which is just an 'ar' archive with 3 files
439
539
  # the 'debian-binary' file has to be first
440
- with(File.expand_path(output_path)) do |output_path|
540
+ File.expand_path(output_path).tap do |output_path|
441
541
  ::Dir.chdir(build_path) do
442
542
  safesystem("ar", "-qc", output_path, "debian-binary", "control.tar.gz", datatar)
443
543
  end
@@ -465,6 +565,20 @@ class FPM::Package::Deb < FPM::Package
465
565
  File.unlink(changelog_path)
466
566
  end
467
567
  end
568
+
569
+ if origin == FPM::Package::Deb
570
+ changelog_path = staging_path("usr/share/doc/#{name}/changelog.gz")
571
+ if File.exists?(changelog_path)
572
+ logger.debug("Found an upstream changelog file, using it.", :path => changelog_path)
573
+ attributes[:deb_upstream_changelog] = build_path("deb_upstream_changelog")
574
+ File.open(attributes[:deb_upstream_changelog], "w") do |deb_upstream_changelog|
575
+ Zlib::GzipReader.open(changelog_path) do |gz|
576
+ IO::copy_stream(gz, deb_upstream_changelog)
577
+ end
578
+ end
579
+ File.unlink(changelog_path)
580
+ end
581
+ end
468
582
  end # def converted_from
469
583
 
470
584
  def debianize_op(op)
@@ -574,10 +688,10 @@ class FPM::Package::Deb < FPM::Package
574
688
  write_md5sums # write the md5sums file
575
689
 
576
690
  # Make the control.tar.gz
577
- with(build_path("control.tar.gz")) do |controltar|
691
+ build_path("control.tar.gz").tap do |controltar|
578
692
  logger.info("Creating", :path => controltar, :from => control_path)
579
693
 
580
- args = [ tar_cmd, "-C", control_path, "-zcf", controltar,
694
+ args = [ tar_cmd, "-C", control_path, "-zcf", controltar,
581
695
  "--owner=0", "--group=0", "--numeric-owner", "." ]
582
696
  safesystem(*args)
583
697
  end
@@ -607,7 +721,7 @@ class FPM::Package::Deb < FPM::Package
607
721
  end
608
722
 
609
723
  # Write the control file
610
- with(control_path("control")) do |control|
724
+ control_path("control").tap do |control|
611
725
  if attributes[:deb_custom_control]
612
726
  logger.debug("Using '#{attributes[:deb_custom_control]}' template for the control file")
613
727
  control_data = File.read(attributes[:deb_custom_control])
@@ -631,39 +745,84 @@ class FPM::Package::Deb < FPM::Package
631
745
  SCRIPT_MAP.each do |scriptname, filename|
632
746
  next unless script?(scriptname)
633
747
 
634
- with(control_path(filename)) do |controlscript|
748
+ control_path(filename).tap do |controlscript|
635
749
  logger.debug("Writing control script", :source => filename, :target => controlscript)
636
750
  File.write(controlscript, script(scriptname))
637
751
  # deb maintainer scripts are required to be executable
638
752
  File.chmod(0755, controlscript)
639
753
  end
640
- end
754
+ end
641
755
  end # def write_scripts
642
756
 
643
757
  def write_conffiles
644
- return unless config_files.any?
645
-
646
- # scan all conf file paths for files and add them
647
- allconfigs = []
648
- config_files.each do |path|
758
+ # expand recursively a given path to be put in allconfigs
759
+ def add_path(path, allconfigs)
649
760
  # Strip leading /
650
761
  path = path[1..-1] if path[0,1] == "/"
651
762
  cfg_path = File.expand_path(path, staging_path)
652
- begin
653
- Find.find(cfg_path) do |p|
654
- allconfigs << p.gsub("#{staging_path}/", '') if File.file? p
763
+ Find.find(cfg_path) do |p|
764
+ if File.file?(p)
765
+ allconfigs << p.gsub("#{staging_path}/", '')
655
766
  end
656
- rescue Errno::ENOENT => e
767
+ end
768
+ end
769
+
770
+ # check for any init scripts or default files
771
+ inits = attributes.fetch(:deb_init_list, [])
772
+ defaults = attributes.fetch(:deb_default_list, [])
773
+ upstarts = attributes.fetch(:deb_upstart_list, [])
774
+ etcfiles = []
775
+ # Add everything in /etc
776
+ begin
777
+ if !attributes[:deb_no_default_config_files?]
778
+ logger.warn("Debian packaging tools generally labels all files in /etc as config files, " \
779
+ "as mandated by policy, so fpm defaults to this behavior for deb packages. " \
780
+ "You can disable this default behavior with --deb-no-default-config-files flag")
781
+ add_path("/etc", etcfiles)
782
+ end
783
+ rescue Errno::ENOENT
784
+ end
785
+
786
+ return unless (config_files.any? or inits.any? or defaults.any? or upstarts.any? or etcfiles.any?)
787
+
788
+ allconfigs = etcfiles
789
+
790
+ # scan all conf file paths for files and add them
791
+ config_files.each do |path|
792
+ begin
793
+ add_path(path, allconfigs)
794
+ rescue Errno::ENOENT
657
795
  raise FPM::InvalidPackageConfiguration,
658
- "Error trying to use '#{cfg_path}' as a config file in the package. Does it exist?"
796
+ "Error trying to use '#{path}' as a config file in the package. Does it exist?"
659
797
  end
660
798
  end
799
+
800
+ if attributes[:deb_auto_config_files?]
801
+ inits.each do |init|
802
+ name = File.basename(init, ".init")
803
+ initscript = "/etc/init.d/#{name}"
804
+ logger.debug("Add conf file declaration for init script", :script => initscript)
805
+ allconfigs << initscript[1..-1]
806
+ end
807
+ defaults.each do |default|
808
+ name = File.basename(default, ".default")
809
+ confdefaults = "/etc/default/#{name}"
810
+ logger.debug("Add conf file declaration for defaults", :default => confdefaults)
811
+ allconfigs << confdefaults[1..-1]
812
+ end
813
+ upstarts.each do |upstart|
814
+ name = File.basename(upstart, ".upstart")
815
+ upstartscript = "etc/init/#{name}.conf"
816
+ logger.debug("Add conf file declaration for upstart script", :script => upstartscript)
817
+ allconfigs << upstartscript[1..-1]
818
+ end
819
+ end
820
+
661
821
  allconfigs.sort!.uniq!
822
+ return unless allconfigs.any?
662
823
 
663
- with(control_path("conffiles")) do |conffiles|
824
+ control_path("conffiles").tap do |conffiles|
664
825
  File.open(conffiles, "w") do |out|
665
- # 'config_files' comes from FPM::Package and is usually set with
666
- # FPM::Command's --config-files flag
667
826
  allconfigs.each do |cf|
668
827
  # We need to put the leading / back. Stops lintian relative-conffile error.
669
828
  out.puts("/" + cf)
@@ -679,6 +838,7 @@ class FPM::Package::Deb < FPM::Package
679
838
  File.open(control_path("shlibs"), "w") do |out|
680
839
  out.write(attributes[:deb_shlibs])
681
840
  end
841
+ File.chmod(0644, control_path("shlibs"))
682
842
  end # def write_shlibs
683
843
 
684
844
  def write_debconf
@@ -694,7 +854,7 @@ class FPM::Package::Deb < FPM::Package
694
854
  end # def write_debconf
695
855
 
696
856
  def write_meta_files
697
- files = attributes[:deb_meta_files]
857
+ files = attributes[:deb_meta_file]
698
858
  return unless files
699
859
  files.each do |fn|
700
860
  dest = control_path(File.basename(fn))
@@ -711,6 +871,7 @@ class FPM::Package::Deb < FPM::Package
711
871
 
712
872
  if lines.size > 0
713
873
  File.open(control_path("triggers"), 'a') do |f|
874
+ f.chmod 0644
714
875
  f.write "\n" if f.size > 0
715
876
  f.write lines
716
877
  end
@@ -738,11 +899,14 @@ class FPM::Package::Deb < FPM::Package
738
899
  end
739
900
  end # def write_md5sums
740
901
 
902
+ def mkdir_p(dir)
903
+ FileUtils.mkdir_p(dir, :mode => 0755)
904
+ end
905
+
741
906
  def to_s(format=nil)
742
907
  # Default format if nil
743
908
  # git_1.7.9.3-1_amd64.deb
744
- return super("NAME_FULLVERSION_ARCH.TYPE") if format.nil?
745
- return super(format)
909
+ return super(format.nil? ? "NAME_FULLVERSION_ARCH.EXTENSION" : format)
746
910
  end # def to_s
747
911
 
748
912
  def data_tar_flags