fpm 1.4.0 → 1.5.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: c5242a72c4435675eabd2eb890ac8296bf77553b
4
- data.tar.gz: 3aeda059fb3d5cfab49e0eaff6cb457c7a61e374
3
+ metadata.gz: ce725d9c506143e502cfc1e27ff5c6346240f305
4
+ data.tar.gz: 09b9b1840e5525eb9930e7dad71070abc589275a
5
5
  SHA512:
6
- metadata.gz: 91d43f3e9ec89f218d08f2d05a0b2cf43c6e06ea2e617ce353bd4be58892167b7617f50f2bc1758a5946033ffc974d05bb9be01396759f79e8b532f5aa5efb93
7
- data.tar.gz: 613babff93a8b1e0acf992ea46d4de82bfa0f175f20b1194f039049480f818a3d52cce267c282ec2721324a839de72da5a777c454a264f914e276b02c54ca4b4
6
+ metadata.gz: 4a33d2dc5a2ca57fcceef601c5ed80da8021bbd8ae6365ec62b5a2b91bc7c2bd59f62ced044dafe592dd48b6f211b68c6200cd761dbd105f0d684c56105d2922
7
+ data.tar.gz: 526287eceec55b3280544fbfcf851f091bc614a14137efbaf796a5ac549a7743ee04438099901f7896a823f627d731c019a44f6ac2f623f8b38bf0fc0edf30d7
data/CHANGELIST CHANGED
@@ -1,4 +1,35 @@
1
- 1.4.0 (???)
1
+ 1.5.0 (April 12, 2016)
2
+ - Arch package support is now available via -s pacman and -t pacman.
3
+ (#916; wonderful community effort making this happen!)
4
+ - FreeBSD packages can now be built `-t freebsd`
5
+ (#1073; huge community effort making this happen!)
6
+ - You can now set fpm flags and arguments with the FPMOPTS environment
7
+ variable (#977, mildred)
8
+ - Using --exclude-file no longer causes a crash. Yay! (#982, wyaeld)
9
+ - A new rake task is available for folks who want to invoke fpm from rake
10
+ (#756, pstengel)
11
+ - On FreeBSD, when tarring, gtar is now used. (#1008, liv3d)
12
+ - virtualenv: Add --virtualenv-pypi-extra-url flag to specify additional PyPI
13
+ locations to use when searching for packages (#1012, Paul Krohn)
14
+ - deb: Init scripts, etc/default, and upstart files are automatically added
15
+ as config files in a debian package. Disable this behavior with
16
+ ---deb-auto-config-files
17
+ - deb: Small changes to make lintian complain less about our resulting debs.
18
+ - deb: New flag --deb-systemd lets you specify a systemd service file to include
19
+ in your package. (#952, Jens Peter Schroer)
20
+ - cpan: Add --[no-]cpan-cpanm-force flag to pass --force to cpanm.
21
+ - rpm: File names with both spaces and symbols should now be packageable.
22
+ (#946, iwonbigbro)
23
+ - cpan: Now queries MetaCPAN for package info if we can't find any in the
24
+ cpan archive we just downloaded. (#849, BaxterStockman)
25
+ - rpm: You can now specify custom rpm tags at the command line. Be careful,
26
+ as no validation is done on this before sending to rpmbuild. (#687, vStone)
27
+ - cpan: Install if the package name given is a local file (#986, mdom)
28
+ - sh: Metadata now available as env vars for post-install scripts (#1006, Ed Healy)
29
+ - rpm: No more warning if you don't set an epoch. (#1053, Joseph Frazier)
30
+
31
+
32
+ 1.4.0 (July 26, 2015)
2
33
  - Solaris 11 IPS packages 'p5p' now supported `-t p5p`. (Jonathan Craig)
3
34
  - Python Virtualenv is now supported `-t virtualenv` (#930, Simone
4
35
  Margaritelli and Daniel Haskin)
data/lib/fpm.rb CHANGED
@@ -16,3 +16,4 @@ require "fpm/package/osxpkg"
16
16
  require "fpm/package/solaris"
17
17
  require "fpm/package/p5p"
18
18
  require "fpm/package/pkgin"
19
+ require "fpm/package/freebsd"
@@ -56,8 +56,8 @@ class FPM::Command < Clamp::Command
56
56
  :attribute_name => :chdir
57
57
  option "--prefix", "PREFIX",
58
58
  "A path to prefix files with when building the target package. This may " \
59
- "be necessary for all input packages. For example, the 'gem' type will " \
60
- "prefix with your gem directory automatically."
59
+ "not be necessary for all input packages. For example, the 'gem' type " \
60
+ "will prefix with your gem directory automatically."
61
61
  option ["-p", "--package"], "OUTPUT", "The package file path to output."
62
62
  option ["-f", "--force"], :flag, "Force output even if it will overwrite an " \
63
63
  "existing file", :default => false
@@ -107,7 +107,7 @@ class FPM::Command < Clamp::Command
107
107
  "specified multiple times.", :multivalued => true,
108
108
  :attribute_name => :provides
109
109
  option "--conflicts", "CONFLICTS",
110
- "Other packages/versions this package conflicts with. This flag can " \
110
+ "Other packages/versions this package conflicts with. This flag can be " \
111
111
  "specified multiple times.", :multivalued => true,
112
112
  :attribute_name => :conflicts
113
113
  option "--replaces", "REPLACES",
@@ -122,7 +122,9 @@ class FPM::Command < Clamp::Command
122
122
  "directory all files inside it will be recursively marked as config files.",
123
123
  :multivalued => true, :attribute_name => :config_files
124
124
  option "--directories", "DIRECTORIES", "Recursively mark a directory as being owned " \
125
- "by the package", :multivalued => true, :attribute_name => :directories
125
+ "by the package. Use this flag multiple times if you have multiple directories " \
126
+ "and they are not under the same parent directory ", :multivalued => true,
127
+ :attribute_name => :directories
126
128
  option ["-a", "--architecture"], "ARCHITECTURE",
127
129
  "The architecture name. Usually matches 'uname -m'. For automatic values," \
128
130
  " you can use '-a all' or '-a native'. These two strings will be " \
@@ -149,11 +151,8 @@ class FPM::Command < Clamp::Command
149
151
  "patterns to exclude from input."
150
152
 
151
153
  option "--description", "DESCRIPTION", "Add a description for this package." \
152
- " You can include '\n' sequences to indicate newline breaks.",
153
- :default => "no description" do |val|
154
- # Replace literal "\n" sequences with a newline character.
155
- val.gsub("\\n", "\n")
156
- end
154
+ " You can include '\\n' sequences to indicate newline breaks.",
155
+ :default => "no description"
157
156
  option "--url", "URI", "Add a url for this package.",
158
157
  :default => "http://example.com/no-uri-given"
159
158
  option "--inputs", "INPUTS_PATH",
@@ -202,7 +201,7 @@ class FPM::Command < Clamp::Command
202
201
  "--before-install, --after-install, --before-remove, and \n" \
203
202
  "--after-remove will behave in a backwards-compatible manner\n" \
204
203
  "(they will not be upgrade-case aware).\n" \
205
- "Currently only supports deb and rpm packages." do |val|
204
+ "Currently only supports deb, rpm and pacman packages." do |val|
206
205
  File.expand_path(val) # Get the full path to the script
207
206
  end # --after-upgrade
208
207
  option "--before-upgrade", "FILE",
@@ -210,7 +209,7 @@ class FPM::Command < Clamp::Command
210
209
  "--before-install, --after-install, --before-remove, and \n" \
211
210
  "--after-remove will behave in a backwards-compatible manner\n" \
212
211
  "(they will not be upgrade-case aware).\n" \
213
- "Currently only supports deb and rpm packages." do |val|
212
+ "Currently only supports deb, rpm and pacman packages." do |val|
214
213
  File.expand_path(val) # Get the full path to the script
215
214
  end # --before-upgrade
216
215
 
@@ -314,7 +313,7 @@ class FPM::Command < Clamp::Command
314
313
  #
315
314
  # Things like '--foo-bar' will be available as pkg.attributes[:foo_bar]
316
315
  self.class.declared_options.each do |option|
317
- with(option.attribute_name) do |attr|
316
+ option.attribute_name.tap do |attr|
318
317
  next if attr == "help"
319
318
  # clamp makes option attributes available as accessor methods
320
319
  # --foo-bar is available as 'foo_bar'. Put these in the package
@@ -363,11 +362,13 @@ class FPM::Command < Clamp::Command
363
362
  return 1
364
363
  end
365
364
 
365
+ # Ensure hash is initialized
366
+ input.attributes[:excludes] ||= []
367
+
366
368
  # Read each line as a path
367
- File.new(exclude-file, "r").each_line do |line|
369
+ File.new(exclude_file, "r").each_line do |line|
368
370
  # Handle each line as if it were an argument
369
- # 'excludes' is defined above near the -x option.
370
- excludes << line.strip
371
+ input.attributes[:excludes] << line.strip
371
372
  end
372
373
  end
373
374
 
@@ -396,7 +397,6 @@ class FPM::Command < Clamp::Command
396
397
  set.call(input, :url)
397
398
  set.call(input, :vendor)
398
399
  set.call(input, :version)
399
- set.call(input, :architecture)
400
400
 
401
401
  input.conflicts += conflicts
402
402
  input.dependencies += dependencies
@@ -414,7 +414,6 @@ class FPM::Command < Clamp::Command
414
414
 
415
415
  input.attrs = h
416
416
 
417
-
418
417
  script_errors = []
419
418
  setscript = proc do |scriptname|
420
419
  # 'self.send(scriptname) == self.before_install == --before-install
@@ -509,7 +508,7 @@ class FPM::Command < Clamp::Command
509
508
  end
510
509
  end # def execute
511
510
 
512
- def run(*args)
511
+ def run(*run_args)
513
512
  logger.subscribe(STDOUT)
514
513
 
515
514
  # fpm initialization files, note the order of the following array is
@@ -518,21 +517,41 @@ class FPM::Command < Clamp::Command
518
517
  rc_files = [ ".fpm" ]
519
518
  rc_files << File.join(ENV["HOME"], ".fpm") if ENV["HOME"]
520
519
 
520
+ rc_args = []
521
+
522
+ if ENV["FPMOPTS"]
523
+ logger.warn("Loading flags from FPMOPTS environment variable")
524
+ rc_args.push(*Shellwords.shellsplit(ENV["FPMOPTS"]))
525
+ end
526
+
521
527
  rc_files.each do |rc_file|
522
528
  if File.readable? rc_file
523
529
  logger.warn("Loading flags from rc file #{rc_file}")
524
- File.readlines(rc_file).each do |line|
525
- # reverse becasue 'unshift' pushes onto the left side of the array.
526
- Shellwords.shellsplit(line).reverse.each do |arg|
527
- # Put '.fpm'-file flags *before* the command line flags
528
- # so that we the CLI can override the .fpm flags
529
- ARGV.unshift(arg)
530
- end
531
- end
530
+ rc_args.push(*Shellwords.shellsplit(File.read(rc_file)))
532
531
  end
533
532
  end
534
533
 
535
- super(*args)
534
+ flags = []
535
+ args = []
536
+ while rc_args.size > 0 do
537
+ arg = rc_args.shift
538
+ opt = self.class.find_option(arg)
539
+ if opt and not opt.flag?
540
+ flags.push(arg)
541
+ flags.push(rc_args.shift)
542
+ elsif opt or arg[0] == "-"
543
+ flags.push(arg)
544
+ else
545
+ args.push(arg)
546
+ end
547
+ end
548
+
549
+ logger.warn("Additional options: #{flags.join " "}") if flags.size > 0
550
+ logger.warn("Additional arguments: #{args.join " "}") if args.size > 0
551
+
552
+ ARGV.unshift(*flags)
553
+ ARGV.push(*args)
554
+ super(*run_args)
536
555
  rescue FPM::Package::InvalidArgument => e
537
556
  logger.error("Invalid package argument: #{e}")
538
557
  return 1
@@ -567,21 +586,21 @@ class FPM::Command < Clamp::Command
567
586
 
568
587
  # Verify the types requested are valid
569
588
  types = FPM::Package.types.keys.sort
570
- with(@command.input_type) do |val|
589
+ @command.input_type.tap do |val|
571
590
  next if val.nil?
572
591
  mandatory(FPM::Package.types.include?(val),
573
592
  "Invalid input package -s flag) type #{val.inspect}. " \
574
593
  "Expected one of: #{types.join(", ")}")
575
594
  end
576
595
 
577
- with(@command.output_type) do |val|
596
+ @command.output_type.tap do |val|
578
597
  next if val.nil?
579
598
  mandatory(FPM::Package.types.include?(val),
580
599
  "Invalid output package (-t flag) type #{val.inspect}. " \
581
600
  "Expected one of: #{types.join(", ")}")
582
601
  end
583
602
 
584
- with (@command.dependencies) do |dependencies|
603
+ @command.dependencies.tap do |dependencies|
585
604
  # Verify dependencies don't include commas (#257)
586
605
  dependencies.each do |dep|
587
606
  next unless dep.include?(",")
@@ -155,7 +155,7 @@ class FPM::Package
155
155
  # Iterate over all the options and set defaults
156
156
  if self.class.respond_to?(:declared_options)
157
157
  self.class.declared_options.each do |option|
158
- with(option.attribute_name) do |attr|
158
+ option.attribute_name.tap do |attr|
159
159
  # clamp makes option attributes available as accessor methods
160
160
  # do --foo-bar is available as 'foo_bar'
161
161
  # make these available as package attributes.
@@ -216,7 +216,7 @@ class FPM::Package
216
216
  return pkg
217
217
  end # def convert
218
218
 
219
- # This method is invoked on a package when it has been covered to a new
219
+ # This method is invoked on a package when it has been converted to a new
220
220
  # package format. The purpose of this method is to do any extra conversion
221
221
  # steps, like translating dependency conditions, etc.
222
222
  def converted_from(origin)
@@ -351,7 +351,7 @@ class FPM::Package
351
351
  system("#{editor} #{Shellwords.escape(path)}")
352
352
  if !$?.success?
353
353
  raise ProcessFailed.new("'#{editor}' failed (exit code " \
354
- "#{$?.exitstatus}) Full command was: "\
354
+ "#{$?.exitstatus}) Full command was: " \
355
355
  "#{command}");
356
356
  end
357
357
 
@@ -379,7 +379,7 @@ class FPM::Package
379
379
 
380
380
  if File.fnmatch(wildcard, match_path)
381
381
  logger.info("Removing excluded path", :path => match_path, :matches => wildcard)
382
- FileUtils.remove_entry_secure(path)
382
+ FileUtils.rm_r(path)
383
383
  Find.prune
384
384
  break
385
385
  end
@@ -30,6 +30,9 @@ class FPM::Package::CPAN < FPM::Package
30
30
  option "--sandbox-non-core", :flag,
31
31
  "Sandbox all non-core modules, even if they're already installed", :default => true
32
32
 
33
+ option "--cpanm-force", :flag,
34
+ "Pass the --force parameter to cpanm", :default => false
35
+
33
36
  private
34
37
  def input(package)
35
38
  #if RUBY_VERSION =~ /^1\.8/
@@ -43,7 +46,7 @@ class FPM::Package::CPAN < FPM::Package
43
46
  require "net/http"
44
47
  require "json"
45
48
 
46
- if (attributes[:cpan_local_module?])
49
+ if File.exist?(package)
47
50
  moduledir = package
48
51
  else
49
52
  result = search(package)
@@ -53,19 +56,28 @@ class FPM::Package::CPAN < FPM::Package
53
56
 
54
57
  # Read package metadata (name, version, etc)
55
58
  if File.exist?(File.join(moduledir, "META.json"))
56
- metadata = JSON.parse(File.read(File.join(moduledir, ("META.json"))))
59
+ local_metadata = JSON.parse(File.read(File.join(moduledir, ("META.json"))))
57
60
  elsif File.exist?(File.join(moduledir, ("META.yml")))
58
61
  require "yaml"
59
- metadata = YAML.load_file(File.join(moduledir, ("META.yml")))
62
+ local_metadata = YAML.load_file(File.join(moduledir, ("META.yml")))
60
63
  elsif File.exist?(File.join(moduledir, "MYMETA.json"))
61
- metadata = JSON.parse(File.read(File.join(moduledir, ("MYMETA.json"))))
64
+ local_metadata = JSON.parse(File.read(File.join(moduledir, ("MYMETA.json"))))
62
65
  elsif File.exist?(File.join(moduledir, ("MYMETA.yml")))
63
66
  require "yaml"
64
- metadata = YAML.load_file(File.join(moduledir, ("MYMETA.yml")))
65
- else
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?
66
77
  raise FPM::InvalidPackageConfiguration,
67
- "Could not find package metadata. Checked for META.json and META.yml"
78
+ "Could not find package metadata. Checked for META.json, META.yml, and MetaCPAN API data"
68
79
  end
80
+
69
81
  self.version = metadata["version"]
70
82
  self.description = metadata["abstract"]
71
83
 
@@ -116,6 +128,7 @@ class FPM::Package::CPAN < FPM::Package
116
128
  cpanm_flags += ["-n"] if !attributes[:cpan_test?]
117
129
  cpanm_flags += ["--mirror", "#{attributes[:cpan_mirror]}"] if !attributes[:cpan_mirror].nil?
118
130
  cpanm_flags += ["--mirror-only"] if attributes[:cpan_mirror_only?] && !attributes[:cpan_mirror].nil?
131
+ cpanm_flags += ["--force"] if attributes[:cpan_cpanm_force?]
119
132
 
120
133
  safesystem(attributes[:cpan_cpanm_bin], *cpanm_flags)
121
134
 
@@ -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
@@ -128,26 +132,38 @@ class FPM::Package::Deb < FPM::Package
128
132
  "Do not add all files in /etc as configuration files by default for Debian packages.",
129
133
  :default => false
130
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
+
131
140
  option "--shlibs", "SHLIBS", "Include control/shlibs content. This flag " \
132
141
  "expects a string that is used as the contents of the shlibs file. " \
133
142
  "See the following url for a description of this file and its format: " \
134
143
  "http://www.debian.org/doc/debian-policy/ch-sharedlibs.html#s-shlibs"
135
144
 
136
145
  option "--init", "FILEPATH", "Add FILEPATH as an init script",
137
- :multivalued => true do |file|
146
+ :multivalued => true do |file|
138
147
  next File.expand_path(file)
139
148
  end
140
149
 
141
150
  option "--default", "FILEPATH", "Add FILEPATH as /etc/default configuration",
142
- :multivalued => true do |file|
151
+ :multivalued => true do |file|
143
152
  next File.expand_path(file)
144
153
  end
145
154
 
146
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",
147
161
  :multivalued => true do |file|
148
162
  next File.expand_path(file)
149
163
  end
150
164
 
165
+ option "--systemd-restart-after-upgrade", :flag , "Restart service after upgrade", :default => true
166
+
151
167
  def initialize(*args)
152
168
  super(*args)
153
169
  attributes[:deb_priority] = "extra"
@@ -224,7 +240,7 @@ class FPM::Package::Deb < FPM::Package
224
240
  end # def input
225
241
 
226
242
  def extract_info(package)
227
- with(build_path("control")) do |path|
243
+ build_path("control").tap do |path|
228
244
  FileUtils.mkdir(path) if !File.directory?(path)
229
245
  # Unpack the control tarball
230
246
  safesystem("ar p #{package} control.tar.gz | tar -zxf - -C #{path}")
@@ -256,7 +272,7 @@ class FPM::Package::Deb < FPM::Package
256
272
  self.name = parse.call("Package")
257
273
  self.url = parse.call("Homepage")
258
274
  self.vendor = parse.call("Vendor") || self.vendor
259
- with(parse.call("Provides")) do |provides_str|
275
+ parse.call("Provides").tap do |provides_str|
260
276
  next if provides_str.nil?
261
277
  self.provides = provides_str.split(/\s*,\s*/)
262
278
  end
@@ -371,14 +387,26 @@ class FPM::Package::Deb < FPM::Package
371
387
  end
372
388
  end
373
389
 
374
- 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"
375
403
  if script?(:before_install) or script?(:before_upgrade)
376
404
  scripts[:before_install] = template("deb/preinst_upgrade.sh.erb").result(binding)
377
405
  end
378
- if script?(:before_remove)
406
+ if script?(:before_remove) or attributes[:deb_systemd]
379
407
  scripts[:before_remove] = template("deb/prerm_upgrade.sh.erb").result(binding)
380
408
  end
381
- if script?(:after_install) or script?(:after_upgrade)
409
+ if script?(:after_install) or script?(:after_upgrade) or attributes[:deb_systemd]
382
410
  scripts[:after_install] = template("deb/postinst_upgrade.sh.erb").result(binding)
383
411
  end
384
412
  if script?(:after_remove)
@@ -404,9 +432,14 @@ class FPM::Package::Deb < FPM::Package
404
432
  "Unknown compression type '#{self.attributes[:deb_compression]}'"
405
433
  end
406
434
 
407
- # 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
408
441
  dest_changelog = File.join(staging_path, "usr/share/doc/#{name}/changelog.Debian.gz")
409
- FileUtils.mkdir_p(File.dirname(dest_changelog))
442
+ mkdir_p(File.dirname(dest_changelog))
410
443
  File.new(dest_changelog, "wb", 0644).tap do |changelog|
411
444
  Zlib::GzipWriter.new(changelog, Zlib::BEST_COMPRESSION).tap do |changelog_gz|
412
445
  if attributes[:deb_changelog]
@@ -423,10 +456,30 @@ class FPM::Package::Deb < FPM::Package
423
456
  end.close
424
457
  end # No need to close, GzipWriter#close will close it.
425
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
+
426
479
  attributes.fetch(:deb_init_list, []).each do |init|
427
480
  name = File.basename(init, ".init")
428
481
  dest_init = File.join(staging_path, "etc/init.d/#{name}")
429
- FileUtils.mkdir_p(File.dirname(dest_init))
482
+ mkdir_p(File.dirname(dest_init))
430
483
  FileUtils.cp init, dest_init
431
484
  File.chmod(0755, dest_init)
432
485
  end
@@ -434,7 +487,7 @@ class FPM::Package::Deb < FPM::Package
434
487
  attributes.fetch(:deb_default_list, []).each do |default|
435
488
  name = File.basename(default, ".default")
436
489
  dest_default = File.join(staging_path, "etc/default/#{name}")
437
- FileUtils.mkdir_p(File.dirname(dest_default))
490
+ mkdir_p(File.dirname(dest_default))
438
491
  FileUtils.cp default, dest_default
439
492
  File.chmod(0644, dest_default)
440
493
  end
@@ -442,22 +495,48 @@ class FPM::Package::Deb < FPM::Package
442
495
  attributes.fetch(:deb_upstart_list, []).each do |upstart|
443
496
  name = File.basename(upstart, ".upstart")
444
497
  dest_upstart = staging_path("etc/init/#{name}.conf")
445
- FileUtils.mkdir_p(File.dirname(dest_upstart))
498
+ mkdir_p(File.dirname(dest_upstart))
446
499
  FileUtils.cp(upstart, dest_upstart)
447
500
  File.chmod(0644, dest_upstart)
448
501
 
449
502
  # Install an init.d shim that calls upstart
450
- dest_init = staging_path("/etc/init.d/#{name}")
451
- FileUtils.mkdir_p(File.dirname(dest_init))
503
+ dest_init = staging_path("etc/init.d/#{name}")
504
+ mkdir_p(File.dirname(dest_init))
452
505
  FileUtils.ln_s("/lib/init/upstart-job", dest_init)
453
506
  end
454
507
 
508
+ attributes.fetch(:deb_systemd_list, []).each do |systemd|
509
+ name = File.basename(systemd, ".service")
510
+ dest_systemd = staging_path("lib/systemd/system/#{name}.service")
511
+ mkdir_p(File.dirname(dest_systemd))
512
+ FileUtils.cp(systemd, dest_systemd)
513
+ File.chmod(0644, dest_systemd)
514
+ end
515
+
516
+ write_control_tarball
517
+
518
+ # Tar up the staging_path into data.tar.{compression type}
519
+ case self.attributes[:deb_compression]
520
+ when "gz", nil
521
+ datatar = build_path("data.tar.gz")
522
+ compression = "-z"
523
+ when "bzip2"
524
+ datatar = build_path("data.tar.bz2")
525
+ compression = "-j"
526
+ when "xz"
527
+ datatar = build_path("data.tar.xz")
528
+ compression = "-J"
529
+ else
530
+ raise FPM::InvalidPackageConfiguration,
531
+ "Unknown compression type '#{self.attributes[:deb_compression]}'"
532
+ end
533
+
455
534
  args = [ tar_cmd, "-C", staging_path, compression ] + data_tar_flags + [ "-cf", datatar, "." ]
456
535
  safesystem(*args)
457
536
 
458
537
  # pack up the .deb, which is just an 'ar' archive with 3 files
459
538
  # the 'debian-binary' file has to be first
460
- with(File.expand_path(output_path)) do |output_path|
539
+ File.expand_path(output_path).tap do |output_path|
461
540
  ::Dir.chdir(build_path) do
462
541
  safesystem("ar", "-qc", output_path, "debian-binary", "control.tar.gz", datatar)
463
542
  end
@@ -485,6 +564,20 @@ class FPM::Package::Deb < FPM::Package
485
564
  File.unlink(changelog_path)
486
565
  end
487
566
  end
567
+
568
+ if origin == FPM::Package::Deb
569
+ changelog_path = staging_path("usr/share/doc/#{name}/changelog.gz")
570
+ if File.exists?(changelog_path)
571
+ logger.debug("Found an upstream changelog file, using it.", :path => changelog_path)
572
+ attributes[:deb_upstream_changelog] = build_path("deb_upstream_changelog")
573
+ File.open(attributes[:deb_upstream_changelog], "w") do |deb_upstream_changelog|
574
+ Zlib::GzipReader.open(changelog_path) do |gz|
575
+ IO::copy_stream(gz, deb_upstream_changelog)
576
+ end
577
+ end
578
+ File.unlink(changelog_path)
579
+ end
580
+ end
488
581
  end # def converted_from
489
582
 
490
583
  def debianize_op(op)
@@ -594,7 +687,7 @@ class FPM::Package::Deb < FPM::Package
594
687
  write_md5sums # write the md5sums file
595
688
 
596
689
  # Make the control.tar.gz
597
- with(build_path("control.tar.gz")) do |controltar|
690
+ build_path("control.tar.gz").tap do |controltar|
598
691
  logger.info("Creating", :path => controltar, :from => control_path)
599
692
 
600
693
  args = [ tar_cmd, "-C", control_path, "-zcf", controltar,
@@ -627,7 +720,7 @@ class FPM::Package::Deb < FPM::Package
627
720
  end
628
721
 
629
722
  # Write the control file
630
- with(control_path("control")) do |control|
723
+ control_path("control").tap do |control|
631
724
  if attributes[:deb_custom_control]
632
725
  logger.debug("Using '#{attributes[:deb_custom_control]}' template for the control file")
633
726
  control_data = File.read(attributes[:deb_custom_control])
@@ -651,7 +744,7 @@ class FPM::Package::Deb < FPM::Package
651
744
  SCRIPT_MAP.each do |scriptname, filename|
652
745
  next unless script?(scriptname)
653
746
 
654
- with(control_path(filename)) do |controlscript|
747
+ control_path(filename).tap do |controlscript|
655
748
  logger.debug("Writing control script", :source => filename, :target => controlscript)
656
749
  File.write(controlscript, script(scriptname))
657
750
  # deb maintainer scripts are required to be executable
@@ -661,18 +754,38 @@ class FPM::Package::Deb < FPM::Package
661
754
  end # def write_scripts
662
755
 
663
756
  def write_conffiles
664
- allconfigs = []
665
-
666
757
  # expand recursively a given path to be put in allconfigs
667
758
  def add_path(path, allconfigs)
668
759
  # Strip leading /
669
760
  path = path[1..-1] if path[0,1] == "/"
670
761
  cfg_path = File.expand_path(path, staging_path)
671
- Find.find(cfg_path).select { |p| File.file?(p) }.each do |p|
672
- allconfigs << p.gsub("#{staging_path}/", '')
762
+ Find.find(cfg_path) do |p|
763
+ if File.file?(p)
764
+ allconfigs << p.gsub("#{staging_path}/", '')
765
+ end
673
766
  end
674
767
  end
675
768
 
769
+ # check for any init scripts or default files
770
+ inits = attributes.fetch(:deb_init_list, [])
771
+ defaults = attributes.fetch(:deb_default_list, [])
772
+ upstarts = attributes.fetch(:deb_upstart_list, [])
773
+ etcfiles = []
774
+ # Add everything in /etc
775
+ begin
776
+ if !attributes[:deb_no_default_config_files?]
777
+ logger.warn("Debian packaging tools generally labels all files in /etc as config files, " \
778
+ "as mandated by policy, so fpm defaults to this behavior for deb packages. " \
779
+ "You can disable this default behavior with --deb-no-default-config-files flag")
780
+ add_path("/etc", etcfiles)
781
+ end
782
+ rescue Errno::ENOENT
783
+ end
784
+
785
+ return unless (config_files.any? or inits.any? or defaults.any? or upstarts.any? or etcfiles.any?)
786
+
787
+ allconfigs = etcfiles
788
+
676
789
  # scan all conf file paths for files and add them
677
790
  config_files.each do |path|
678
791
  begin
@@ -683,21 +796,31 @@ class FPM::Package::Deb < FPM::Package
683
796
  end
684
797
  end
685
798
 
686
- # Also add everything in /etc
687
- begin
688
- if !attributes[:deb_no_default_config_files?]
689
- logger.warn("Debian packaging tools generally labels all files in /etc as config files, " \
690
- "as mandated by policy, so fpm defaults to this behavior for deb packages. " \
691
- "You can disable this default behavior with --deb-no-default-config-files flag")
692
- add_path("/etc", allconfigs)
799
+ if attributes[:deb_auto_config_files?]
800
+ inits.each do |init|
801
+ name = File.basename(init, ".init")
802
+ initscript = "/etc/init.d/#{name}"
803
+ logger.debug("Add conf file declaration for init script", :script => initscript)
804
+ allconfigs << initscript[1..-1]
805
+ end
806
+ defaults.each do |default|
807
+ name = File.basename(default, ".default")
808
+ confdefaults = "/etc/default/#{name}"
809
+ logger.debug("Add conf file declaration for defaults", :default => confdefaults)
810
+ allconfigs << confdefaults[1..-1]
811
+ end
812
+ upstarts.each do |upstart|
813
+ name = File.basename(upstart, ".upstart")
814
+ upstartscript = "etc/init/#{name}.conf"
815
+ logger.debug("Add conf file declaration for upstart script", :script => upstartscript)
816
+ allconfigs << upstartscript[1..-1]
693
817
  end
694
- rescue Errno::ENOENT
695
818
  end
696
819
 
697
820
  allconfigs.sort!.uniq!
698
821
  return unless allconfigs.any?
699
822
 
700
- with(control_path("conffiles")) do |conffiles|
823
+ control_path("conffiles").tap do |conffiles|
701
824
  File.open(conffiles, "w") do |out|
702
825
  allconfigs.each do |cf|
703
826
  # We need to put the leading / back. Stops lintian relative-conffile error.
@@ -730,7 +853,7 @@ class FPM::Package::Deb < FPM::Package
730
853
  end # def write_debconf
731
854
 
732
855
  def write_meta_files
733
- files = attributes[:deb_meta_files]
856
+ files = attributes[:deb_meta_file]
734
857
  return unless files
735
858
  files.each do |fn|
736
859
  dest = control_path(File.basename(fn))
@@ -747,6 +870,7 @@ class FPM::Package::Deb < FPM::Package
747
870
 
748
871
  if lines.size > 0
749
872
  File.open(control_path("triggers"), 'a') do |f|
873
+ f.chmod 0644
750
874
  f.write "\n" if f.size > 0
751
875
  f.write lines
752
876
  end
@@ -774,6 +898,10 @@ class FPM::Package::Deb < FPM::Package
774
898
  end
775
899
  end # def write_md5sums
776
900
 
901
+ def mkdir_p(dir)
902
+ FileUtils.mkdir_p(dir, :mode => 0755)
903
+ end
904
+
777
905
  def to_s(format=nil)
778
906
  # Default format if nil
779
907
  # git_1.7.9.3-1_amd64.deb