fpm 1.0.2 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: d61a0cdec8509988ddad4461c5d8e97ec8e13e7d
4
+ data.tar.gz: 1450b23e93208cf29b03ee1e65fc2b3e4c21502f
5
+ SHA512:
6
+ metadata.gz: 2f93f3d2dad2f43aa06db81125b39962855519e7e6c854636b95a378336ca8be63888b65a53c7400528c6b43278d711eaf3d2803df4f980231b7891495c78813
7
+ data.tar.gz: 5533a18ec9ef6c1a8b43a8a9e7c26bef3bd878eb79b3e7cfd086080ce2f0d17cbc5d606ec6808b5c20b0469ca0c0d7ce325750dc6f80ab549a0cd44ce66bc964
data/CHANGELIST CHANGED
@@ -1,3 +1,34 @@
1
+ 1.1.0 (???)
2
+ - New package type: zip, for converting to and from zip files (Jordan Sissel)
3
+ - New package type: sh, a self-extracting package installation shell archive. (#651, Chris Gerber)
4
+ - 'fpm --version' will now emit the version of fpm.
5
+ - rpm: supports packaging fifo files (Adam Stephens)
6
+ - deb: Add --deb-use-file-permissions (Adam Stephens)
7
+ - cpan: Improve how fpm tries to find cpan artifacts for download (#614, Tim Nicholas)
8
+ - gem: Add --gem-disable-dependency for removing one or more specific rubygem
9
+ dependencies from the automatically-generated list (#598, Derek Olsen)
10
+ - python: Add --python-scripts-executable for setting a custom interpreter to
11
+ use for the hashbang line at the top of may python package scripts.
12
+ (#628, Vladimir Rutsky)
13
+ - Allow absolute paths with --directories even when --prefix is used (Vladimir Rutsky)
14
+ - dir: Now correctly identifies hardlinked files and creates a package correctly
15
+ with that knowledge (#365, #623, #659; Vladimir Rutsky)
16
+ - rpm: Add --rpm-auto-add-exclude-directories for excluding directories
17
+ from the --rpm-auto-add-directories behavior (#640, Vladimir Rutsky)
18
+ - general: --config-files now accepts directories and will recursively mark any
19
+ files within as config files inside the package (#642, Vladimir Rutsky)
20
+ - general: If you specify a --config-files path that doesn't exist, you will
21
+ now get an error. (#654, Alan Franzoni)
22
+ - python: Support --python-pypi when using --python-pip (#652, David Lindquist)
23
+ - deb: Tests now try to make packages ensure we don't upset lintian (#648, Sam Crang)
24
+ - rpm: Fix architecture targeting (#676, Rob Kinyon)
25
+ - rpm: Allow --rpm-user and --rpm-group to override the user/group even if
26
+ --rpm-use-file-permissions is enabled. (#679, Jordan Sissel)
27
+ - gem: Add --gem-version-bins for appending the gem version to the file name
28
+ of executable scripts a rubygem may install. (Jan Vansteenkiste)
29
+ - python: Attempt to provide better error messages for known issues in python
30
+ environments (#664, Jordan Sissel)
31
+
1
32
  1.0.2 (January 10, 2013)
2
33
  - rpm: No longer converts - to _ in dependency strings (#603, Bulat
3
34
  Shakirzyanov)
@@ -101,7 +101,8 @@ class FPM::Command < Clamp::Command
101
101
  option "--config-files", "CONFIG_FILES",
102
102
  "Mark a file in the package as being a config file. This uses 'conffiles'" \
103
103
  " in debs and %config in rpm. If you have multiple files to mark as " \
104
- "configuration files, specify this flag multiple times.",
104
+ "configuration files, specify this flag multiple times. If argument is " \
105
+ "directory all files inside it will be recursively marked as config files.",
105
106
  :multivalued => true, :attribute_name => :config_files
106
107
  option "--directories", "DIRECTORIES", "Recursively mark a directory as being owned " \
107
108
  "by the package", :multivalued => true, :attribute_name => :directories
@@ -217,6 +218,12 @@ class FPM::Command < Clamp::Command
217
218
 
218
219
  # Execute this command. See Clamp::Command#execute and Clamp's documentation
219
220
  def execute
221
+ # Short-circuit if someone simply runs `fpm --version`
222
+ if ARGV == [ "--version" ]
223
+ puts FPM::VERSION
224
+ return 0
225
+ end
226
+
220
227
  @logger.level = :warn
221
228
 
222
229
  if (stray_flags = args.grep(/^-/); stray_flags.any?)
@@ -385,8 +392,9 @@ class FPM::Command < Clamp::Command
385
392
 
386
393
  # Write the output somewhere, package can be nil if no --package is specified,
387
394
  # and that's OK.
395
+ package_file = output.to_s(package)
388
396
  begin
389
- output.output(output.to_s(package))
397
+ output.output(package_file)
390
398
  rescue FPM::Package::FileAlreadyExists => e
391
399
  @logger.fatal(e.message)
392
400
  return 1
@@ -395,6 +403,7 @@ class FPM::Command < Clamp::Command
395
403
  return 1
396
404
  end
397
405
 
406
+ @logger.log("Created package", :path => package_file)
398
407
  return 0
399
408
  rescue FPM::Util::ExecutableNotFound => e
400
409
  @logger.error("Need executable '#{e}' to convert #{input_type} to #{output_type}")
@@ -242,6 +242,7 @@ class FPM::Package::CPAN < FPM::Package
242
242
  def download(metadata, cpan_version=nil)
243
243
  distribution = metadata["distribution"]
244
244
  author = metadata["author"]
245
+
245
246
  @logger.info("Downloading perl module",
246
247
  :distribution => distribution,
247
248
  :version => cpan_version)
@@ -257,9 +258,27 @@ class FPM::Package::CPAN < FPM::Package
257
258
  end
258
259
  end
259
260
 
260
- tarball = "#{distribution}-#{self.version}.tar.gz"
261
+ metacpan_release_url = "http://api.metacpan.org/v0/release/#{author}/#{distribution}-#{self.version}"
262
+ begin
263
+ release_response = httpfetch(metacpan_release_url)
264
+ rescue Net::HTTPServerException => e
265
+ @logger.error("metacpan release query failed.", :error => e.message,
266
+ :module => package, :url => metacpan_release_url)
267
+ raise FPM::InvalidPackageConfiguration, "metacpan release query failed"
268
+ end
269
+
270
+ data = release_response.body
271
+ release_metadata = JSON.parse(data)
272
+ archive = release_metadata["archive"]
273
+
274
+ # should probably be basepathed from the url
275
+ tarball = File.basename(archive)
276
+
277
+ url_base = "http://www.cpan.org/"
278
+ url_base = "#{attributes[:cpan_mirror]}" if !attributes[:cpan_mirror].nil?
279
+
261
280
  #url = "http://www.cpan.org/CPAN/authors/id/#{author[0,1]}/#{author[0,2]}/#{author}/#{tarball}"
262
- url = "http://www.cpan.org/authors/id/#{author[0,1]}/#{author[0,2]}/#{author}/#{tarball}"
281
+ url = "#{url_base}/authors/id/#{author[0,1]}/#{author[0,2]}/#{author}/#{archive}"
263
282
  @logger.debug("Fetching perl module", :url => url)
264
283
 
265
284
  begin
@@ -76,6 +76,9 @@ class FPM::Package::Deb < FPM::Package
76
76
  option "--priority", "PRIORITY",
77
77
  "The debian package 'priority' value.", :default => "extra"
78
78
 
79
+ option "--use-file-permissions", :flag,
80
+ "Use existing file permissions when defining ownership and modes"
81
+
79
82
  option "--user", "USER", "The owner of files in this package", :default => 'root'
80
83
 
81
84
  option "--group", "GROUP", "The group owner of files in this package", :default => 'root'
@@ -342,23 +345,6 @@ class FPM::Package::Deb < FPM::Package
342
345
  "Unknown compression type '#{self.attributes[:deb_compression]}'"
343
346
  end
344
347
 
345
- tar_flags = []
346
- if !attributes[:deb_user].nil?
347
- if attributes[:deb_user] == 'root'
348
- tar_flags += [ "--numeric-owner", "--owner", "0" ]
349
- else
350
- tar_flags += [ "--owner", attributes[:deb_user] ]
351
- end
352
- end
353
-
354
- if !attributes[:deb_group].nil?
355
- if attributes[:deb_group] == 'root'
356
- tar_flags += [ "--numeric-owner", "--group", "0" ]
357
- else
358
- tar_flags += [ "--group", attributes[:deb_group] ]
359
- end
360
- end
361
-
362
348
  if attributes[:deb_changelog]
363
349
  dest_changelog = File.join(staging_path, "usr/share/doc/#{name}/changelog.Debian")
364
350
  FileUtils.mkdir_p(File.dirname(dest_changelog))
@@ -396,7 +382,7 @@ class FPM::Package::Deb < FPM::Package
396
382
  FileUtils.ln_s("/lib/init/upstart-job", dest_init)
397
383
  end
398
384
 
399
- args = [ tar_cmd, "-C", staging_path, compression ] + tar_flags + [ "-cf", datatar, "." ]
385
+ args = [ tar_cmd, "-C", staging_path, compression ] + data_tar_flags + [ "-cf", datatar, "." ]
400
386
  safesystem(*args)
401
387
 
402
388
  # pack up the .deb, which is just an 'ar' archive with 3 files
@@ -406,7 +392,6 @@ class FPM::Package::Deb < FPM::Package
406
392
  safesystem("ar", "-qc", output_path, "debian-binary", "control.tar.gz", datatar)
407
393
  end
408
394
  end
409
- @logger.log("Created deb package", :path => output_path)
410
395
  end # def output
411
396
 
412
397
  def converted_from(origin)
@@ -612,7 +597,10 @@ class FPM::Package::Deb < FPM::Package
612
597
  File.open(control_path("conffiles"), "w") do |out|
613
598
  # 'config_files' comes from FPM::Package and is usually set with
614
599
  # FPM::Command's --config-files flag
615
- allconfigs.each { |cf| out.puts(cf) }
600
+ allconfigs.each do |cf|
601
+ # We need to put the leading / back. Stops lintian relative-conffile error.
602
+ out.puts("/" + cf)
603
+ end
616
604
  end
617
605
  end # def write_conffiles
618
606
 
@@ -664,5 +652,27 @@ class FPM::Package::Deb < FPM::Package
664
652
  return super(format)
665
653
  end # def to_s
666
654
 
667
- public(:input, :output, :architecture, :name, :prefix, :converted_from, :to_s)
655
+ def data_tar_flags
656
+ data_tar_flags = []
657
+ if attributes[:deb_use_file_permissions?].nil?
658
+ if !attributes[:deb_user].nil?
659
+ if attributes[:deb_user] == 'root'
660
+ data_tar_flags += [ "--numeric-owner", "--owner", "0" ]
661
+ else
662
+ data_tar_flags += [ "--owner", attributes[:deb_user] ]
663
+ end
664
+ end
665
+
666
+ if !attributes[:deb_group].nil?
667
+ if attributes[:deb_group] == 'root'
668
+ data_tar_flags += [ "--numeric-owner", "--group", "0" ]
669
+ else
670
+ data_tar_flags += [ "--group", attributes[:deb_group] ]
671
+ end
672
+ end
673
+ end
674
+ return data_tar_flags
675
+ end # def data_tar_flags
676
+
677
+ public(:input, :output, :architecture, :name, :prefix, :converted_from, :to_s, :data_tar_flags)
668
678
  end # class FPM::Target::Deb
@@ -38,6 +38,11 @@ class FPM::Package::Gem < FPM::Package
38
38
  "shebang rewritten to use env?", :default => true
39
39
 
40
40
  option "--prerelease", :flag, "Allow prerelease versions of a gem", :default => false
41
+ option "--disable-dependency", "gem_name",
42
+ "The gem name to remove from dependency list",
43
+ :multivalued => true, :attribute_name => :gem_disable_dependencies
44
+
45
+ option "--version-bins", :flag, "Append the version to the bins", :default => false
41
46
 
42
47
  def input(gem)
43
48
  # 'arg' is the name of the rubygem we should unpack.
@@ -147,6 +152,10 @@ class FPM::Package::Gem < FPM::Package
147
152
 
148
153
  # Some reqs can be ">= a, < b" versions, let's handle that.
149
154
  reqs.to_s.split(/, */).each do |req|
155
+ if attributes[:gem_disable_dependencies]
156
+ next if attributes[:gem_disable_dependencies].include?(dep.name)
157
+ end
158
+
150
159
  if attributes[:gem_fix_dependencies?]
151
160
  name = fix_name(dep.name)
152
161
  else
@@ -198,6 +207,11 @@ class FPM::Package::Gem < FPM::Package
198
207
  ::Dir.rmdir(tmp)
199
208
  tmp = File.dirname(tmp)
200
209
  end
210
+ if attributes[:gem_version_bins?]
211
+ (::Dir.entries(bin_path) - ['.','..']).each do |bin|
212
+ FileUtils.mv("#{bin_path}/#{bin}", "#{bin_path}/#{bin}-#{self.version}")
213
+ end
214
+ end
201
215
  end # def install_to_staging
202
216
 
203
217
  # Sanitize package name.
@@ -63,6 +63,12 @@ class FPM::Package::Python < FPM::Package
63
63
  option "--obey-requirements-txt", :flag, "Use a requirements.txt file " \
64
64
  "in the top-level directory of the python package for dependency " \
65
65
  "detection.", :default => false
66
+ option "--scripts-executable", "PYTHON_EXECUTABLE", "Set custom python " \
67
+ "interpreter in installing scripts. By default distutils will replace " \
68
+ "python interpreter in installing scripts (specified by shebang) with " \
69
+ "current python interpreter (sys.executable). This option is equivalent " \
70
+ "to appending 'build_scripts --executable PYTHON_EXECUTABLE' arguments " \
71
+ "to 'setup.py install' command."
66
72
 
67
73
  private
68
74
 
@@ -121,8 +127,7 @@ class FPM::Package::Python < FPM::Package
121
127
  "--build-directory", target, want_pkg)
122
128
  else
123
129
  @logger.debug("using pip", :pip => attributes[:python_pip])
124
- safesystem(attributes[:python_pip], "install", "--no-install",
125
- "-U", "--build", target, want_pkg)
130
+ safesystem(attributes[:python_pip], "install", "--no-install", "-i", attributes[:python_pypi], "-U", "--build", target, want_pkg)
126
131
  end
127
132
 
128
133
  # easy_install will put stuff in @tmpdir/packagename/, so find that:
@@ -140,6 +145,26 @@ class FPM::Package::Python < FPM::Package
140
145
  attributes[:python_package_name_prefix] = attributes[:python_package_prefix]
141
146
  end
142
147
 
148
+ begin
149
+ json_test_code = [
150
+ "try:",
151
+ " import json",
152
+ "except ImportError:",
153
+ " import simplejson as json"
154
+ ].join("\n")
155
+ safesystem("#{attributes[:python_bin]} -c '#{json_test_code}'")
156
+ rescue FPM::Util::ProcessFailed => e
157
+ @logger.error("Your python environment is missing json support (either json or simplejson python module). I cannot continue without this.", :python => attributes[:python_bin], :error => e)
158
+ raise FPM::Util::ProcessFailed, "Python (#{attributes[:python_bin]}) is missing simplejson or json modules."
159
+ end
160
+
161
+ begin
162
+ safesystem("#{attributes[:python_bin]} -c 'import pkg_resources'")
163
+ rescue FPM::Util::ProcessFailed => e
164
+ @logger.error("Your python environment is missing a working setuptools module. I tried to find the 'pkg_resources' module but failed.", :python => attributes[:python_bin], :error => e)
165
+ raise FPM::Util::ProcessFailed, "Python (#{attributes[:python_bin]}) is missing pkg_resources module."
166
+ end
167
+
143
168
  # Add ./pyfpm/ to the python library path
144
169
  pylib = File.expand_path(File.dirname(__FILE__))
145
170
 
@@ -272,6 +297,11 @@ class FPM::Package::Python < FPM::Package
272
297
  flags += [ "--install-scripts", File.join(prefix, "bin") ]
273
298
  end
274
299
 
300
+ if !attributes[:python_scripts_executable].nil?
301
+ # Overwrite installed python scripts shebang binary with provided executable
302
+ flags += [ "build_scripts", "--executable", attributes[:python_scripts_executable] ]
303
+ end
304
+
275
305
  safesystem(attributes[:python_bin], "setup.py", "install", *flags)
276
306
  end
277
307
  end # def install_to_staging
@@ -30,19 +30,11 @@ class FPM::Package::RPM < FPM::Package
30
30
  } unless defined?(COMPRESSION_MAP)
31
31
 
32
32
  option "--use-file-permissions", :flag,
33
- "Use existing file permissions when defining ownership and modes"
33
+ "Use existing file permissions when defining ownership and modes."
34
34
 
35
- option "--user", "USER",
36
- "Set the user to USER in the %files section.",
37
- :default => 'root' do |value|
38
- value
39
- end
35
+ option "--user", "USER", "Set the user to USER in the %files section. Overrides the user when used with use-file-permissions setting."
40
36
 
41
- option "--group", "GROUP",
42
- "Set the group to GROUP in the %files section.",
43
- :default => 'root' do |value|
44
- value
45
- end
37
+ option "--group", "GROUP", "Set the group to GROUP in the %files section. Overrides the group when used with use-file-permissions setting."
46
38
 
47
39
  option "--defattrfile", "ATTR",
48
40
  "Set the default file mode (%defattr).",
@@ -95,6 +87,9 @@ class FPM::Package::RPM < FPM::Package
95
87
  option "--sign", :flag, "Pass --sign to rpmbuild"
96
88
 
97
89
  option "--auto-add-directories", :flag, "Auto add directories not part of filesystem"
90
+ option "--auto-add-exclude-directories", "DIRECTORIES",
91
+ "Additional directories ignored by '--rpm-auto-add-directories' flag",
92
+ :multivalued => true, :attribute_name => :auto_add_exclude_directories
98
93
 
99
94
  option "--autoreqprov", :flag, "Enable RPM's AutoReqProv option"
100
95
  option "--autoreq", :flag, "Enable RPM's AutoReq option"
@@ -141,8 +136,11 @@ class FPM::Package::RPM < FPM::Package
141
136
  # Stat the original filename in the relative staging path
142
137
  ::Dir.chdir(staging_path) do
143
138
  stat = File.stat(original_file.gsub(/\"/, '').sub(/^\//,''))
144
- user = Etc.getpwuid(stat.uid).name
145
- group = Etc.getgrgid(stat.gid).name
139
+
140
+ # rpm_user and rpm_group attribute should override file ownership
141
+ # otherwise use the current file user/group by name.
142
+ user = attributes[:rpm_user] || Etc.getpwuid(stat.uid).name
143
+ group = attributes[:rpm_group] || Etc.getgrgid(stat.gid).name
146
144
  mode = stat.mode
147
145
  return sprintf("%%attr(%o, %s, %s) %s\n", mode & 4095 , user, group, file)
148
146
  end
@@ -301,11 +299,19 @@ class FPM::Package::RPM < FPM::Package
301
299
  rpm.extract(staging_path)
302
300
  end # def input
303
301
 
302
+ def prefixed_path(path)
303
+ Pathname.new(path).absolute?() ? path : File.join(self.prefix, path)
304
+ end # def prefixed_path
305
+
304
306
  def output(output_path)
305
307
  output_check(output_path)
306
308
  %w(BUILD RPMS SRPMS SOURCES SPECS).each { |d| FileUtils.mkdir_p(build_path(d)) }
307
309
  args = ["rpmbuild", "-bb"]
308
310
 
311
+ if %x{uname -m}.chomp != self.architecture
312
+ args += [ '--target', self.architecture ]
313
+ end
314
+
309
315
  # issue #309
310
316
  if !attributes[:rpm_os].nil?
311
317
  rpm_target = "#{architecture}-unknown-#{attributes[:rpm_os]}"
@@ -324,6 +330,7 @@ class FPM::Package::RPM < FPM::Package
324
330
  if attributes[:rpm_auto_add_directories?]
325
331
  fs_dirs_list = File.join(template_dir, "rpm", "filesystem_list")
326
332
  fs_dirs = File.readlines(fs_dirs_list).reject { |x| x =~ /^\s*#/}.map { |x| x.chomp }
333
+ fs_dirs.concat((attributes[:auto_add_exclude_directories] or []))
327
334
 
328
335
  Find.find(staging_path) do |path|
329
336
  next if path == staging_path
@@ -333,7 +340,7 @@ class FPM::Package::RPM < FPM::Package
333
340
  end
334
341
  end
335
342
  else
336
- self.directories = self.directories.map { |x| File.join(self.prefix, x) }
343
+ self.directories = self.directories.map { |x| self.prefixed_path(x) }
337
344
  alldirs = []
338
345
  self.directories.each do |path|
339
346
  Find.find(File.join(staging_path, path)) do |subpath|
@@ -348,14 +355,15 @@ class FPM::Package::RPM < FPM::Package
348
355
  # scan all conf file paths for files and add them
349
356
  allconfigs = []
350
357
  self.config_files.each do |path|
351
- cfg_path = File.expand_path(path, staging_path)
358
+ cfg_path = File.join(staging_path, path)
359
+ raise "Config file path #{cfg_path} does not exist" unless File.exist?(cfg_path)
352
360
  Find.find(cfg_path) do |p|
353
361
  allconfigs << p.gsub("#{staging_path}/", '') if File.file? p
354
362
  end
355
363
  end
356
364
  allconfigs.sort!.uniq!
357
365
 
358
- self.config_files = allconfigs.map { |x| File.join(self.prefix, x) }
366
+ self.config_files = allconfigs.map { |x| File.join("/", x) }
359
367
 
360
368
  (attributes[:rpm_rpmbuild_define] or []).each do |define|
361
369
  args += ["--define", define]
@@ -383,8 +391,6 @@ class FPM::Package::RPM < FPM::Package
383
391
  # This should only output one rpm, should we verify this?
384
392
  FileUtils.cp(rpmpath, output_path)
385
393
  end
386
-
387
- @logger.log("Created rpm", :path => output_path)
388
394
  end # def output
389
395
 
390
396
  def prefix
@@ -394,7 +400,7 @@ class FPM::Package::RPM < FPM::Package
394
400
  def build_sub_dir
395
401
  return "BUILD"
396
402
  #return File.join("BUILD", prefix)
397
- end # def prefix
403
+ end # def build_sub_dir
398
404
 
399
405
  def version
400
406
  if @version.kind_of?(String) and @version.include?("-")
@@ -433,5 +439,5 @@ class FPM::Package::RPM < FPM::Package
433
439
 
434
440
  public(:input, :output, :converted_from, :architecture, :to_s, :iteration,
435
441
  :payload_compression, :digest_algorithm, :prefix, :build_sub_dir,
436
- :epoch, :version)
442
+ :epoch, :version, :prefixed_path)
437
443
  end # class FPM::Package::RPM
@@ -0,0 +1,75 @@
1
+ require "erb"
2
+ require "fpm/namespace"
3
+ require "fpm/package"
4
+ require "fpm/errors"
5
+ require "fpm/util"
6
+ require "backports"
7
+ require "fileutils"
8
+ require "digest"
9
+
10
+ # Support for self extracting sh files (.sh files)
11
+ #
12
+ # This class only supports output of packages.
13
+ #
14
+ # The sh package is a single sh file with a bzipped tar payload concatenated to the end.
15
+ # The script can unpack the tarball to install it and call optional post install scripts.
16
+ class FPM::Package::Sh < FPM::Package
17
+
18
+ def output(output_path)
19
+ create_scripts
20
+
21
+ # Make one file. The installscript can unpack itself.
22
+ `cat #{install_script} #{payload} > #{output_path}`
23
+ FileUtils.chmod("+x", output_path)
24
+ end
25
+
26
+ def create_scripts
27
+ if script?(:before_install)
28
+ # the scripts are kept in the payload so what would before install be if we've already
29
+ # unpacked the payload?
30
+ raise "sh package does not support before install scripts."
31
+ end
32
+
33
+ if script?(:after_install)
34
+ File.write(File.join(fpm_meta_path, "after_install"), script(:after_install))
35
+ end
36
+ end
37
+
38
+ def install_script
39
+ path = build_path("installer.sh")
40
+ File.open(path, "w") do |file|
41
+ file.write template("sh.erb").result(binding)
42
+ end
43
+ path
44
+ end
45
+
46
+ # Returns the path to the tar file containing the packed up staging directory
47
+ def payload
48
+ payload_tar = build_path("payload.tar")
49
+ @logger.info("Creating payload tar ", :path => payload_tar)
50
+
51
+ args = [ tar_cmd,
52
+ "-C",
53
+ staging_path,
54
+ "-cf",
55
+ payload_tar,
56
+ "--owner=0",
57
+ "--group=0",
58
+ "--numeric-owner",
59
+ "." ]
60
+
61
+ unless safesystem(*args)
62
+ raise "Command failed while creating payload tar: #{args}"
63
+ end
64
+ payload_tar
65
+ end
66
+
67
+ # Where we keep metadata and post install scripts and such
68
+ def fpm_meta_path
69
+ @fpm_meta_path ||= begin
70
+ path = File.join(staging_path, ".fpm")
71
+ FileUtils.mkdir_p(path)
72
+ path
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,63 @@
1
+ require "backports" # gem backports
2
+ require "fpm/package"
3
+ require "fpm/util"
4
+ require "fileutils"
5
+ require "fpm/package/dir"
6
+
7
+ # Use a zip as a package.
8
+ #
9
+ # This provides no metadata. Both input and output are supported.
10
+ class FPM::Package::Zip < FPM::Package
11
+
12
+ # Input a zipfile.
13
+ def input(input_path)
14
+ # use part of the filename as the package name
15
+ self.name = File.extname(input_path)[1..-1]
16
+
17
+ realpath = Pathname.new(input_path).realpath.to_s
18
+ ::Dir.chdir(build_path) do
19
+ safesystem("unzip", realpath)
20
+ end
21
+
22
+ # use dir to set stuff up properly, mainly so I don't have to reimplement
23
+ # the chdir/prefix stuff special for zip.
24
+ dir = convert(FPM::Package::Dir)
25
+ if attributes[:chdir]
26
+ dir.attributes[:chdir] = File.join(build_path, attributes[:chdir])
27
+ else
28
+ dir.attributes[:chdir] = build_path
29
+ end
30
+
31
+ cleanup_staging
32
+ # Tell 'dir' to input "." and chdir/prefix will help it figure out the
33
+ # rest.
34
+ dir.input(".")
35
+ @staging_path = dir.staging_path
36
+ dir.cleanup_build
37
+ end # def input
38
+
39
+ # Output a tarball.
40
+ #
41
+ # If the output path ends predictably (like in .tar.gz) it will try to obey
42
+ # the compression type.
43
+ def output(output_path)
44
+ output_check(output_path)
45
+
46
+ files = Find.find(staging_path).to_a
47
+ safesystem("zip", output_path, *files)
48
+ end # def output
49
+
50
+ # Generate the proper tar flags based on the path name.
51
+ def tar_compression_flag(path)
52
+ case path
53
+ when /\.tar\.bz2$/
54
+ return "-j"
55
+ when /\.tar\.gz$|\.tgz$/
56
+ return "-z"
57
+ when /\.tar\.xz$/
58
+ return "-J"
59
+ else
60
+ return nil
61
+ end
62
+ end # def tar_compression_flag
63
+ end # class FPM::Package::Tar
@@ -30,18 +30,29 @@ module FPM::Util
30
30
  return envpath.select { |p| File.executable?(File.join(p, program)) }.any?
31
31
  end # def program_in_path
32
32
 
33
+ def program_exists?(program)
34
+ # Scan path to find the executable
35
+ # Do this to help the user get a better error message.
36
+ return program_in_path?(program) if !program.include?("/")
37
+ return File.executable?(program)
38
+ end # def program_exists?
39
+
40
+ def default_shell
41
+ shell = ENV["SHELL"]
42
+ return "/bin/sh" if shell.nil? || shell.empty?
43
+ return shell
44
+ end
45
+
33
46
  # Run a command safely in a way that gets reports useful errors.
34
47
  def safesystem(*args)
35
48
  # ChildProcess isn't smart enough to run a $SHELL if there's
36
49
  # spaces in the first arg and there's only 1 arg.
37
50
  if args.size == 1
38
- args = [ ENV["SHELL"], "-c", args[0] ]
51
+ args = [ default_shell, "-c", args[0] ]
39
52
  end
40
53
  program = args[0]
41
54
 
42
- # Scan path to find the executable
43
- # Do this to help the user get a better error message.
44
- if !program.include?("/") and !program_in_path?(program)
55
+ if !program_exists?(program)
45
56
  raise ExecutableNotFound.new(program)
46
57
  end
47
58
 
@@ -73,7 +84,7 @@ module FPM::Util
73
84
  return success
74
85
  end # def safesystem
75
86
 
76
- # Run a command safely in a way that captures output and status.
87
+ # Run a command safely in a way that captures output and status.
77
88
  def safesystemout(*args)
78
89
  if args.size == 1
79
90
  args = [ ENV["SHELL"], "-c", args[0] ]
@@ -155,7 +166,29 @@ module FPM::Util
155
166
  when 'directory'
156
167
  FileUtils.mkdir(dst) unless File.exists? dst
157
168
  else
158
- FileUtils.copy_entry(src, dst)
159
- end
160
- end
169
+ # if the file with the same dev and inode has been copied already -
170
+ # hard link it's copy to `dst`, otherwise make an actual copy
171
+ st = File.lstat(src)
172
+ known_entry = copied_entries[[st.dev, st.ino]]
173
+ if known_entry
174
+ FileUtils.ln(known_entry, dst)
175
+ else
176
+ FileUtils.copy_entry(src, dst)
177
+ copied_entries[[st.dev, st.ino]] = dst
178
+ end
179
+ end # else...
180
+ end # def copy_entry
181
+
182
+ def copied_entries
183
+ # TODO(sissel): I wonder that this entry-copy knowledge needs to be put
184
+ # into a separate class/module. As is, calling copy_entry the same way
185
+ # in slightly different contexts will result in weird or bad behavior.
186
+ # What I mean is if we do:
187
+ # pkg = FPM::Package::Dir...
188
+ # pkg.output()...
189
+ # pkg.output()...
190
+ # The 2nd output call will fail or behave weirdly because @copied_entries
191
+ # is already populated. even though this is anew round of copying.
192
+ return @copied_entries ||= {}
193
+ end # def copied_entries
161
194
  end # module FPM::Util
@@ -1,3 +1,3 @@
1
1
  module FPM
2
- VERSION = "1.0.2"
2
+ VERSION = "1.1.0"
3
3
  end
@@ -41,7 +41,6 @@ Epoch: <%= epoch %>
41
41
  Release: <%= iteration or 1 %>
42
42
  <%# use the first line of the description as the summary -%>
43
43
  Summary: <%= description.split("\n").first.empty? ? "_" : description.split("\n").first %>
44
- BuildArch: <%= architecture %>
45
44
  <% if !attributes[:rpm_autoreqprov?] -%>
46
45
  AutoReqProv: no
47
46
  <% else -%>
@@ -127,7 +126,7 @@ Obsoletes: <%= repl %>
127
126
  <% end -%>
128
127
 
129
128
  %files
130
- %defattr(<%= attributes[:rpm_defattrfile] %>,<%= attributes[:rpm_user] %>,<%= attributes[:rpm_group] %>,<%= attributes[:rpm_defattrdir] %>)
129
+ %defattr(<%= attributes[:rpm_defattrfile] %>,<%= attributes[:rpm_user] || "root" %>,<%= attributes[:rpm_group] || "root" %>,<%= attributes[:rpm_defattrdir] %>)
131
130
  <%# Output config files and then regular files. -%>
132
131
  <% config_files.each do |path| -%>
133
132
  %config(noreplace) <%= rpm_file_entry(path) %>
@@ -0,0 +1,297 @@
1
+ #!/bin/bash
2
+
3
+ # bail out if any part of this fails
4
+ set -e
5
+
6
+ # This is the self-extracting installer script for an FPM shell installer package.
7
+ # It contains the logic to unpack a tar archive appended to the end of this script
8
+ # and, optionally, to run post install logic.
9
+ # Run the package file with -h to see a usage message or look at the print_usage method.
10
+ #
11
+ # The post install scripts are called with INSTALL_ROOT, INSTALL_DIR and VERBOSE exported
12
+ # into the environment for their use.
13
+ #
14
+ # INSTALL_ROOT = the path passed in with -i or a relative directory of the name of the package
15
+ # file with no extension
16
+ # INSTALL_DIR = the same as INSTALL_ROOT unless -c (capistrano release directory) argumetn
17
+ # is used. Then it is $INSTALL_ROOT/releases/<datestamp>
18
+ # CURRENT_DIR = if -c argument is used, this is set to the $INSTALL_ROOT/current which is
19
+ # symlinked to INSTALL_DIR
20
+ # VERBOSE = is set if the package was called with -v for verbose output
21
+ function main() {
22
+ set_install_dir
23
+
24
+ create_pid
25
+
26
+ wait_for_others
27
+
28
+ kill_others
29
+
30
+ set_owner
31
+
32
+ unpack_payload
33
+
34
+ if [ "$UNPACK_ONLY" == "1" ] ; then
35
+ echo "Unpacking complete, not moving symlinks or restarting because unpack only was specified."
36
+ else
37
+ create_symlinks
38
+
39
+ set +e # don't exit on errors to allow us to clean up
40
+ if ! run_post_install ; then
41
+ revert_symlinks
42
+ log "Installation failed."
43
+ exit 1
44
+ else
45
+ clean_out_old_releases
46
+ log "Installation complete."
47
+ fi
48
+ fi
49
+ }
50
+
51
+ # deletes the PID file for this installation
52
+ function delete_pid(){
53
+ rm -f ${INSTALL_ROOT}/$$.pid 2> /dev/null
54
+ }
55
+
56
+ # creates a PID file for this installation
57
+ function create_pid(){
58
+ trap "delete_pid" EXIT
59
+ echo $$> ${INSTALL_ROOT}/$$.pid
60
+ }
61
+
62
+
63
+ # checks for other PID files and sleeps for a grace period if found
64
+ function wait_for_others(){
65
+ local count=`ls ${INSTALL_ROOT}/*.pid | wc -l`
66
+
67
+ if [ $count -gt 1 ] ; then
68
+ sleep 10
69
+ fi
70
+ }
71
+
72
+ # kills other running installations
73
+ function kill_others(){
74
+ for PID_FILE in $(ls ${INSTALL_ROOT}/*.pid) ; do
75
+ local p=`cat ${PID_FILE}`
76
+ if ! [ $p == $$ ] ; then
77
+ kill -9 $p
78
+ rm -f $PID_FILE 2> /dev/null
79
+ fi
80
+ done
81
+ }
82
+
83
+ # echos metadata file. A function so that we can have it change after we set INSTALL_ROOT
84
+ function fpm_metadata_file(){
85
+ echo "${INSTALL_ROOT}/.install-metadata"
86
+ }
87
+
88
+ # if this package was installed at this location already we will find a metadata file with the details
89
+ # about the installation that we left here. Load from that if available but allow command line args to trump
90
+ function load_environment(){
91
+ local METADATA=$(fpm_metadata_file)
92
+ if [ -r "${METADATA}" ] ; then
93
+ log "Found existing metadata file '${METADATA}'. Loading previous install details. Env vars in current environment will take precedence over saved values."
94
+ local TMP="/tmp/$(basename $0).$$.tmp"
95
+ # save existing environment, load saved environment from previous run from install-metadata and then
96
+ # overlay current environment so that anything set currencly will take precedence
97
+ # but missing values will be loaded from previous runs.
98
+ save_environment "$TMP"
99
+ source "${METADATA}"
100
+ source $TMP
101
+ rm "$TMP"
102
+ fi
103
+ }
104
+
105
+ # write out metadata for future installs
106
+ function save_environment(){
107
+ local METADATA=$1
108
+ echo -n "" > ${METADATA} # empty file
109
+
110
+ # just piping env to a file doesn't quote the variables. This does
111
+ # filter out multiline junk and _. _ is a readonly variable
112
+ env | egrep "^[^ ]+=.*" | grep -v "^_=" | while read ENVVAR ; do
113
+ local NAME=${ENVVAR%%=*}
114
+ # sed is to preserve variable values with dollars (for escaped variables or $() style command replacement),
115
+ # and command replacement backticks
116
+ # Escaped parens captures backward reference \1 which gets replaced with backslash and \1 to esape them in the saved
117
+ # variable value
118
+ local VALUE=$(eval echo '$'$NAME | sed 's/\([$`]\)/\\\1/g')
119
+ echo "export $NAME=\"$VALUE\"" >> ${METADATA}
120
+ done
121
+
122
+ if [ -n "${OWNER}" ] ; then
123
+ chown ${OWNER} ${METADATA}
124
+ fi
125
+ }
126
+
127
+ function set_install_dir(){
128
+ # if INSTALL_ROOT isn't set by parsed args, use basename of package file with no extension
129
+ DEFAULT_DIR=$(echo $(basename $0) | sed -e 's/\.[^\.]*$//')
130
+ INSTALL_DIR=${INSTALL_ROOT:-$DEFAULT_DIR}
131
+
132
+ DATESTAMP=$(date +%Y%m%d%H%M%S)
133
+ if [ -z "$USE_FLAT_RELEASE_DIRECTORY" ] ; then
134
+ <%= "RELEASE_ID=#{release_id}" if respond_to?(:release_id) %>
135
+ INSTALL_DIR="${RELEASES_DIR}/${RELEASE_ID:-$DATESTAMP}"
136
+ fi
137
+
138
+ mkdir -p "$INSTALL_DIR" || die "Unable to create install directory $INSTALL_DIR"
139
+
140
+ export INSTALL_DIR
141
+
142
+ log "Installing package to '$INSTALL_DIR'"
143
+ }
144
+
145
+ function set_owner(){
146
+ export OWNER=${OWNER:-$USER}
147
+ log "Installing as user $OWNER"
148
+ }
149
+
150
+ function unpack_payload(){
151
+ if [ "$FORCE" == "1" ] || [ ! "$(ls -A $INSTALL_DIR)" ] ; then
152
+ log "Unpacking payload . . ."
153
+ local archive_line=$(grep -a -n -m1 '__ARCHIVE__$' $0 | sed 's/:.*//')
154
+ tail -n +$((archive_line + 1)) $0 | tar -C $INSTALL_DIR -xf - > /dev/null || die "Failed to unpack payload from the end of '$0' into '$INSTALL_DIR'"
155
+ else
156
+ # Files are already here, just move symlinks
157
+ log "Directory already exists and has contents ($INSTALL_DIR). Not unpacking payload."
158
+ fi
159
+ }
160
+
161
+ function run_post_install(){
162
+ local AFTER_INSTALL=$INSTALL_DIR/.fpm/after_install
163
+ if [ -r $AFTER_INSTALL ] ; then
164
+ chmod +x $AFTER_INSTALL
165
+ log "Running post install script"
166
+ log $($AFTER_INSTALL)
167
+ return $?
168
+ fi
169
+ return 0
170
+ }
171
+
172
+ function create_symlinks(){
173
+ [ -n "$USE_FLAT_RELEASE_DIRECTORY" ] && return
174
+
175
+ export CURRENT_DIR="$INSTALL_ROOT/current"
176
+ if [ -e "$CURRENT_DIR" ] ; then
177
+ OLD_CURRENT_TARGET=$(readlink $CURRENT_DIR)
178
+ rm "$CURRENT_DIR"
179
+ fi
180
+ ln -s "$INSTALL_DIR" "$CURRENT_DIR"
181
+
182
+ log "Symlinked '$INSTALL_DIR' to '$CURRENT_DIR'"
183
+ }
184
+
185
+ # in case post install fails we may have to back out switching the symlink to current
186
+ # We can't switch the symlink after because post install may assume that it is in the
187
+ # exact state of being installed (services looking to current for their latest code)
188
+ function revert_symlinks(){
189
+ if [ -n "$OLD_CURRENT_TARGET" ] ; then
190
+ log "Putting current symlink back to '$OLD_CURRENT_TARGET'"
191
+ if [ -e "$CURRENT_DIR" ] ; then
192
+ rm "$CURRENT_DIR"
193
+ fi
194
+ ln -s "$OLD_CURRENT_TARGET" "$CURRENT_DIR"
195
+ fi
196
+ }
197
+
198
+ function clean_out_old_releases(){
199
+ [ -n "$USE_FLAT_RELEASE_DIRECTORY" ] && return
200
+
201
+ while [ $(ls -tr "${RELEASES_DIR}" | wc -l) -gt 2 ] ; do
202
+ OLDEST_RELEASE=$(ls -tr "${RELEASES_DIR}" | head -1)
203
+ log "Deleting old release '${OLDEST_RELEASE}'"
204
+ rm -rf "${RELEASES_DIR}/${OLDEST_RELEASE}"
205
+ done
206
+ }
207
+
208
+ function print_usage(){
209
+ echo "Usage: `basename $0` [options]"
210
+ echo "Install this package"
211
+ echo " -i <DIRECTORY> : install_root - an optional directory to install to."
212
+ echo " Default is package file name without file extension"
213
+ echo " -o <USER> : owner - the name of the user that will own the files installed"
214
+ echo " by the package. Defaults to current user"
215
+ echo " -r: disable capistrano style release directories - Default behavior is to create a releases directory inside"
216
+ echo " install_root and unpack contents into a date stamped (or build time id named) directory under the release"
217
+ echo " directory. Then create a 'current' symlink under install_root to the unpacked"
218
+ echo " directory once installation is complete replacing the symlink if it already "
219
+ echo " exists. If this flag is set just install into install_root directly"
220
+ echo " -u: Unpack the package, but do not install and symlink the payload"
221
+ echo " -f: force - Always overwrite existing installations"
222
+ echo " -y: yes - Don't prompt to clobber existing installations"
223
+ echo " -v: verbose - More output on installation"
224
+ echo " -h: help - Display this message"
225
+ }
226
+
227
+ function die () {
228
+ local message=$*
229
+ echo "Error: $message : $!"
230
+ exit 1
231
+ }
232
+
233
+ function log(){
234
+ local message=$*
235
+ if [ -n "$VERBOSE" ] ; then
236
+ echo "$*"
237
+ fi
238
+ }
239
+
240
+ function parse_args() {
241
+ args=`getopt i:o:rfuyvh $*`
242
+
243
+ if [ $? != 0 ] ; then
244
+ print_usage
245
+ exit 2
246
+ fi
247
+ set -- $args
248
+ for i
249
+ do
250
+ case "$i"
251
+ in
252
+ -r)
253
+ USE_FLAT_RELEASE_DIRECTORY=1
254
+ shift;;
255
+ -i)
256
+ shift;
257
+ export INSTALL_ROOT="$1"
258
+ export RELEASES_DIR="${INSTALL_ROOT}/releases"
259
+ shift;;
260
+ -o)
261
+ shift;
262
+ export OWNER="$1"
263
+ shift;;
264
+ -v)
265
+ export VERBOSE=1
266
+ shift;;
267
+ -u)
268
+ UNPACK_ONLY=1
269
+ shift;;
270
+ -f)
271
+ FORCE=1
272
+ shift;;
273
+ -y)
274
+ CONFIRM="y"
275
+ shift;;
276
+ -h)
277
+ print_usage
278
+ exit 0
279
+ shift;;
280
+ --)
281
+ shift; break;;
282
+ esac
283
+ done
284
+ }
285
+
286
+ # parse args first to get install root
287
+ parse_args $*
288
+ # load environment from previous installations so we get defaults from that
289
+ load_environment
290
+ # reparse args so they can override any settings from previous installations if provided on the command line
291
+ parse_args $*
292
+
293
+ main
294
+ save_environment $(fpm_metadata_file)
295
+ exit 0
296
+
297
+ __ARCHIVE__
metadata CHANGED
@@ -1,100 +1,74 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fpm
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.2
5
- prerelease:
4
+ version: 1.1.0
6
5
  platform: ruby
7
6
  authors:
8
7
  - Jordan Sissel
9
8
  autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2014-01-10 00:00:00.000000000 Z
11
+ date: 2014-04-23 00:00:00.000000000 Z
13
12
  dependencies:
14
13
  - !ruby/object:Gem::Dependency
15
14
  name: json
16
15
  requirement: !ruby/object:Gem::Requirement
17
- none: false
18
16
  requirements:
19
- - - ! '>='
17
+ - - '>='
20
18
  - !ruby/object:Gem::Version
21
19
  version: 1.7.7
22
20
  type: :runtime
23
21
  prerelease: false
24
22
  version_requirements: !ruby/object:Gem::Requirement
25
- none: false
26
23
  requirements:
27
- - - ! '>='
24
+ - - '>='
28
25
  - !ruby/object:Gem::Version
29
26
  version: 1.7.7
30
27
  - !ruby/object:Gem::Dependency
31
28
  name: cabin
32
29
  requirement: !ruby/object:Gem::Requirement
33
- none: false
34
30
  requirements:
35
- - - ! '>='
31
+ - - '>='
36
32
  - !ruby/object:Gem::Version
37
33
  version: 0.6.0
38
34
  type: :runtime
39
35
  prerelease: false
40
36
  version_requirements: !ruby/object:Gem::Requirement
41
- none: false
42
37
  requirements:
43
- - - ! '>='
38
+ - - '>='
44
39
  - !ruby/object:Gem::Version
45
40
  version: 0.6.0
46
41
  - !ruby/object:Gem::Dependency
47
42
  name: backports
48
43
  requirement: !ruby/object:Gem::Requirement
49
- none: false
50
44
  requirements:
51
- - - ! '>='
45
+ - - '>='
52
46
  - !ruby/object:Gem::Version
53
47
  version: 2.6.2
54
48
  type: :runtime
55
49
  prerelease: false
56
50
  version_requirements: !ruby/object:Gem::Requirement
57
- none: false
58
51
  requirements:
59
- - - ! '>='
52
+ - - '>='
60
53
  - !ruby/object:Gem::Version
61
54
  version: 2.6.2
62
55
  - !ruby/object:Gem::Dependency
63
56
  name: arr-pm
64
57
  requirement: !ruby/object:Gem::Requirement
65
- none: false
66
58
  requirements:
67
59
  - - ~>
68
60
  - !ruby/object:Gem::Version
69
- version: 0.0.8
61
+ version: 0.0.9
70
62
  type: :runtime
71
63
  prerelease: false
72
64
  version_requirements: !ruby/object:Gem::Requirement
73
- none: false
74
65
  requirements:
75
66
  - - ~>
76
67
  - !ruby/object:Gem::Version
77
- version: 0.0.8
78
- - !ruby/object:Gem::Dependency
79
- name: ftw
80
- requirement: !ruby/object:Gem::Requirement
81
- none: false
82
- requirements:
83
- - - ~>
84
- - !ruby/object:Gem::Version
85
- version: 0.0.30
86
- type: :runtime
87
- prerelease: false
88
- version_requirements: !ruby/object:Gem::Requirement
89
- none: false
90
- requirements:
91
- - - ~>
92
- - !ruby/object:Gem::Version
93
- version: 0.0.30
68
+ version: 0.0.9
94
69
  - !ruby/object:Gem::Dependency
95
70
  name: clamp
96
71
  requirement: !ruby/object:Gem::Requirement
97
- none: false
98
72
  requirements:
99
73
  - - ~>
100
74
  - !ruby/object:Gem::Version
@@ -102,7 +76,6 @@ dependencies:
102
76
  type: :runtime
103
77
  prerelease: false
104
78
  version_requirements: !ruby/object:Gem::Requirement
105
- none: false
106
79
  requirements:
107
80
  - - ~>
108
81
  - !ruby/object:Gem::Version
@@ -110,55 +83,48 @@ dependencies:
110
83
  - !ruby/object:Gem::Dependency
111
84
  name: childprocess
112
85
  requirement: !ruby/object:Gem::Requirement
113
- none: false
114
86
  requirements:
115
- - - ! '>='
87
+ - - '>='
116
88
  - !ruby/object:Gem::Version
117
89
  version: '0'
118
90
  type: :runtime
119
91
  prerelease: false
120
92
  version_requirements: !ruby/object:Gem::Requirement
121
- none: false
122
93
  requirements:
123
- - - ! '>='
94
+ - - '>='
124
95
  - !ruby/object:Gem::Version
125
96
  version: '0'
126
97
  - !ruby/object:Gem::Dependency
127
98
  name: ffi
128
99
  requirement: !ruby/object:Gem::Requirement
129
- none: false
130
100
  requirements:
131
- - - ! '>='
101
+ - - '>='
132
102
  - !ruby/object:Gem::Version
133
103
  version: '0'
134
104
  type: :runtime
135
105
  prerelease: false
136
106
  version_requirements: !ruby/object:Gem::Requirement
137
- none: false
138
107
  requirements:
139
- - - ! '>='
108
+ - - '>='
140
109
  - !ruby/object:Gem::Version
141
110
  version: '0'
142
111
  - !ruby/object:Gem::Dependency
143
112
  name: rspec
144
113
  requirement: !ruby/object:Gem::Requirement
145
- none: false
146
114
  requirements:
147
- - - ! '>='
115
+ - - '>='
148
116
  - !ruby/object:Gem::Version
149
117
  version: '0'
150
118
  type: :development
151
119
  prerelease: false
152
120
  version_requirements: !ruby/object:Gem::Requirement
153
- none: false
154
121
  requirements:
155
- - - ! '>='
122
+ - - '>='
156
123
  - !ruby/object:Gem::Version
157
124
  version: '0'
158
125
  - !ruby/object:Gem::Dependency
159
126
  name: insist
160
127
  requirement: !ruby/object:Gem::Requirement
161
- none: false
162
128
  requirements:
163
129
  - - ~>
164
130
  - !ruby/object:Gem::Version
@@ -166,7 +132,6 @@ dependencies:
166
132
  type: :development
167
133
  prerelease: false
168
134
  version_requirements: !ruby/object:Gem::Requirement
169
- none: false
170
135
  requirements:
171
136
  - - ~>
172
137
  - !ruby/object:Gem::Version
@@ -174,49 +139,43 @@ dependencies:
174
139
  - !ruby/object:Gem::Dependency
175
140
  name: minitest
176
141
  requirement: !ruby/object:Gem::Requirement
177
- none: false
178
142
  requirements:
179
- - - ! '>='
143
+ - - '>='
180
144
  - !ruby/object:Gem::Version
181
145
  version: '0'
182
146
  type: :development
183
147
  prerelease: false
184
148
  version_requirements: !ruby/object:Gem::Requirement
185
- none: false
186
149
  requirements:
187
- - - ! '>='
150
+ - - '>='
188
151
  - !ruby/object:Gem::Version
189
152
  version: '0'
190
153
  - !ruby/object:Gem::Dependency
191
154
  name: pry
192
155
  requirement: !ruby/object:Gem::Requirement
193
- none: false
194
156
  requirements:
195
- - - ! '>='
157
+ - - '>='
196
158
  - !ruby/object:Gem::Version
197
159
  version: '0'
198
160
  type: :development
199
161
  prerelease: false
200
162
  version_requirements: !ruby/object:Gem::Requirement
201
- none: false
202
163
  requirements:
203
- - - ! '>='
164
+ - - '>='
204
165
  - !ruby/object:Gem::Version
205
166
  version: '0'
206
167
  - !ruby/object:Gem::Dependency
207
168
  name: stud
208
169
  requirement: !ruby/object:Gem::Requirement
209
- none: false
210
170
  requirements:
211
- - - ! '>='
171
+ - - '>='
212
172
  - !ruby/object:Gem::Version
213
173
  version: '0'
214
174
  type: :development
215
175
  prerelease: false
216
176
  version_requirements: !ruby/object:Gem::Requirement
217
- none: false
218
177
  requirements:
219
- - - ! '>='
178
+ - - '>='
220
179
  - !ruby/object:Gem::Version
221
180
  version: '0'
222
181
  description: Convert directories, rpms, python eggs, rubygems, and more to rpms, debs,
@@ -228,39 +187,42 @@ executables:
228
187
  extensions: []
229
188
  extra_rdoc_files: []
230
189
  files:
231
- - lib/fpm.rb
232
- - lib/fpm/package.rb
233
- - lib/fpm/version.rb
234
- - lib/fpm/namespace.rb
235
- - lib/fpm/util.rb
236
- - lib/fpm/errors.rb
237
190
  - lib/fpm/command.rb
238
- - lib/fpm/package/pkgin.rb
239
- - lib/fpm/package/tar.rb
240
- - lib/fpm/package/pyfpm/__init__.pyc
241
- - lib/fpm/package/pyfpm/get_metadata.pyc
242
- - lib/fpm/package/pyfpm/get_metadata.py
243
- - lib/fpm/package/pyfpm/__init__.py
191
+ - lib/fpm/errors.rb
192
+ - lib/fpm/namespace.rb
193
+ - lib/fpm/package/cpan.rb
194
+ - lib/fpm/package/deb.rb
244
195
  - lib/fpm/package/dir.rb
245
- - lib/fpm/package/npm.rb
196
+ - lib/fpm/package/empty.rb
246
197
  - lib/fpm/package/gem.rb
247
- - lib/fpm/package/deb.rb
198
+ - lib/fpm/package/npm.rb
199
+ - lib/fpm/package/osxpkg.rb
200
+ - lib/fpm/package/pear.rb
201
+ - lib/fpm/package/pkgin.rb
248
202
  - lib/fpm/package/puppet.rb
249
- - lib/fpm/package/cpan.rb
203
+ - lib/fpm/package/pyfpm/__init__.py
204
+ - lib/fpm/package/pyfpm/__init__.pyc
205
+ - lib/fpm/package/pyfpm/get_metadata.py
206
+ - lib/fpm/package/pyfpm/get_metadata.pyc
250
207
  - lib/fpm/package/python.rb
251
- - lib/fpm/package/osxpkg.rb
252
- - lib/fpm/package/solaris.rb
253
208
  - lib/fpm/package/rpm.rb
254
- - lib/fpm/package/empty.rb
255
- - lib/fpm/package/pear.rb
209
+ - lib/fpm/package/sh.rb
210
+ - lib/fpm/package/solaris.rb
211
+ - lib/fpm/package/tar.rb
212
+ - lib/fpm/package/zip.rb
213
+ - lib/fpm/package.rb
214
+ - lib/fpm/util.rb
215
+ - lib/fpm/version.rb
216
+ - lib/fpm.rb
256
217
  - bin/fpm
257
- - templates/rpm.erb
218
+ - templates/deb/ldconfig.sh.erb
258
219
  - templates/deb.erb
259
220
  - templates/osxpkg.erb
260
- - templates/rpm/filesystem_list
261
- - templates/deb/ldconfig.sh.erb
262
- - templates/puppet/package.pp.erb
263
221
  - templates/puppet/package/remove.pp.erb
222
+ - templates/puppet/package.pp.erb
223
+ - templates/rpm/filesystem_list
224
+ - templates/rpm.erb
225
+ - templates/sh.erb
264
226
  - templates/solaris.erb
265
227
  - LICENSE
266
228
  - CONTRIBUTORS
@@ -268,27 +230,26 @@ files:
268
230
  homepage: https://github.com/jordansissel/fpm
269
231
  licenses:
270
232
  - MIT-like
233
+ metadata: {}
271
234
  post_install_message:
272
235
  rdoc_options: []
273
236
  require_paths:
274
237
  - lib
275
238
  - lib
276
239
  required_ruby_version: !ruby/object:Gem::Requirement
277
- none: false
278
240
  requirements:
279
- - - ! '>='
241
+ - - '>='
280
242
  - !ruby/object:Gem::Version
281
243
  version: '0'
282
244
  required_rubygems_version: !ruby/object:Gem::Requirement
283
- none: false
284
245
  requirements:
285
- - - ! '>='
246
+ - - '>='
286
247
  - !ruby/object:Gem::Version
287
248
  version: '0'
288
249
  requirements: []
289
250
  rubyforge_project:
290
- rubygems_version: 1.8.23
251
+ rubygems_version: 2.1.11
291
252
  signing_key:
292
- specification_version: 3
253
+ specification_version: 4
293
254
  summary: fpm - package building and mangling
294
255
  test_files: []