fpm 1.4.0 → 1.5.0

Sign up to get free protection for your applications and to get access to all the features.
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