fpm 0.3.11 → 0.4.0pre1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (43) hide show
  1. data/CHANGELIST +15 -0
  2. data/bin/fpm +2 -15
  3. data/lib/fpm.rb +5 -12
  4. data/lib/fpm/command.rb +323 -0
  5. data/lib/fpm/errors.rb +1 -0
  6. data/lib/fpm/namespace.rb +2 -11
  7. data/lib/fpm/package.rb +255 -100
  8. data/lib/fpm/package/deb.rb +367 -0
  9. data/lib/fpm/package/dir.rb +86 -0
  10. data/lib/fpm/package/gem.rb +162 -0
  11. data/lib/fpm/{source → package}/npm.rb +3 -3
  12. data/lib/fpm/package/pear.rb +41 -0
  13. data/lib/fpm/{target → package}/puppet.rb +1 -3
  14. data/lib/fpm/{source → package}/pyfpm/__init__.py +0 -0
  15. data/lib/fpm/package/pyfpm/__init__.pyc +0 -0
  16. data/lib/fpm/{source → package}/pyfpm/get_metadata.py +15 -3
  17. data/lib/fpm/package/pyfpm/get_metadata.pyc +0 -0
  18. data/lib/fpm/package/python.rb +125 -0
  19. data/lib/fpm/package/rpm.rb +132 -0
  20. data/lib/fpm/{target → package}/solaris.rb +3 -2
  21. data/lib/fpm/package/tar.rb +62 -0
  22. data/lib/fpm/util.rb +56 -7
  23. data/templates/deb.erb +12 -12
  24. data/templates/rpm.erb +32 -38
  25. data/templates/solaris.erb +1 -1
  26. metadata +119 -78
  27. data/lib/fpm/builder.rb +0 -220
  28. data/lib/fpm/flags.rb +0 -20
  29. data/lib/fpm/program.rb +0 -273
  30. data/lib/fpm/rubyfixes.rb +0 -11
  31. data/lib/fpm/source.rb +0 -155
  32. data/lib/fpm/source/dir.rb +0 -59
  33. data/lib/fpm/source/gem.rb +0 -162
  34. data/lib/fpm/source/python.rb +0 -137
  35. data/lib/fpm/source/rpm.rb +0 -28
  36. data/lib/fpm/source/tar.rb +0 -50
  37. data/lib/fpm/target/deb.rb +0 -184
  38. data/lib/fpm/target/rpm.rb +0 -68
  39. data/lib/rpm/header.rb +0 -89
  40. data/lib/rpm/lead.rb +0 -48
  41. data/lib/rpm/namespace.rb +0 -1
  42. data/lib/rpm/rpmfile.rb +0 -81
  43. data/lib/rpm/tag.rb +0 -304
@@ -0,0 +1,162 @@
1
+ require "fpm/namespace"
2
+ require "fpm/package"
3
+ require "rubygems/package"
4
+ require "rubygems"
5
+ require "fileutils"
6
+ require "fpm/util"
7
+
8
+ # A rubygems package.
9
+ #
10
+ # This does not currently support 'output'
11
+ #
12
+ # The following attributes are supported:
13
+ #
14
+ # * :gem_bin_path
15
+ # * :package_name_prefix
16
+ # * :gem_gem
17
+ class FPM::Package::Gem < FPM::Package
18
+ option "--bin-path", "DIRECTORY", "The directory to install gem executables",
19
+ :default => ::Gem::bindir
20
+ option "--package-prefix", "NAMEPREFIX",
21
+ "(DEPRECATED, use --package-name-prefix) Name to prefix the package " \
22
+ "name with." do |value|
23
+ @logger.warn("Using deprecated flag: --package-prefix. Please use " \
24
+ "--package-name-prefix")
25
+ value
26
+ end
27
+ option "--package-name-prefix", "PREFIX", "Name to prefix the package " \
28
+ "name with.", :default => "rubygem"
29
+ option "--gem", "PATH_TO_GEM",
30
+ "The path to the 'gem' tool (defaults to 'gem' and searches " \
31
+ "your $PATH)", :default => "gem"
32
+
33
+ def input(gem)
34
+ # 'arg' is the name of the rubygem we should unpack.
35
+ path_to_gem = download_if_necessary(gem, version)
36
+
37
+ # Got a good gem now (downloaded or otherwise)
38
+ #
39
+ # 1. unpack it into staging_path
40
+ # 2. take the metadata from it and update our wonderful package with it.
41
+ load_package_info(path_to_gem)
42
+ install_to_staging(path_to_gem)
43
+ end # def input
44
+
45
+ def download_if_necessary(gem, gem_version)
46
+ path = gem
47
+ if !File.exists?(path)
48
+ looks_like_name_re = /^[A-Za-z0-9_-]+$/
49
+ if path =~ looks_like_name_re
50
+ path = download(gem, gem_version)
51
+ else
52
+ raise FPM::Package::InvalidArgument.new("Gem '#{gem}' doesn't appear to be a valid rubygem file or name?")
53
+ end
54
+ end
55
+
56
+ @logger.info("Using gem file", :path => path)
57
+ return path
58
+ end # def download_if_necessary
59
+
60
+ def download(gem_name, gem_version=nil)
61
+ # This code mostly mutated from rubygem's fetch_command.rb
62
+ # Code use permissible by rubygems's "GPL or these conditions below"
63
+ # http://rubygems.rubyforge.org/rubygems-update/LICENSE_txt.html
64
+
65
+ @logger.info("Trying to download", :gem => gem_name, :version => gem_version)
66
+ dep = ::Gem::Dependency.new(gem_name, gem_version)
67
+
68
+ # TODO(sissel): Make a flag to allow prerelease gems?
69
+ #dep.prerelease = options[:prerelease]
70
+
71
+ if ::Gem::SpecFetcher.fetcher.respond_to?(:fetch_with_errors)
72
+ specs_and_sources, errors =
73
+ ::Gem::SpecFetcher.fetcher.fetch_with_errors(dep, true, true, false)
74
+ else
75
+ specs_and_sources =
76
+ ::Gem::SpecFetcher.fetcher.fetch(dep, true)
77
+ errors = "???"
78
+ end
79
+ spec, source_uri = specs_and_sources.sort_by { |s,| s.version }.last
80
+
81
+ if spec.nil? then
82
+ @logger.error("Invalid gem?", :name => gem_name, :version => gem_version, :errors => errors)
83
+ raise InvalidArgument.new("Invalid gem: #{gem_name}")
84
+ end
85
+
86
+ path = ::Gem::RemoteFetcher.fetcher.download(spec, source_uri)
87
+ return path
88
+ end # def download
89
+
90
+ def load_package_info(gem_path)
91
+ file = File.new(gem_path, 'r')
92
+
93
+ ::Gem::Package.open(file, 'r') do |gem|
94
+ spec = gem.metadata
95
+
96
+ if !attributes[:gem_package_prefix].nil?
97
+ attributes[:gem_package_name_prefix] = attributes[:gem_package_prefix]
98
+ end
99
+
100
+ self.name = [attributes[:gem_package_name_prefix], spec.name].join("-")
101
+ self.license = (spec.license or "no license listed in #{File.basename(file)}")
102
+ self.version = spec.version.to_s
103
+ self.vendor = spec.author
104
+ self.url = spec.homepage
105
+ self.category = "Languages/Development/Ruby"
106
+
107
+ # if the gemspec has C extensions defined, then this should be a 'native' arch.
108
+ if !spec.extensions.empty?
109
+ self.architecture = "native"
110
+ else
111
+ self.architecture = "all"
112
+ end
113
+
114
+ # make sure we have a description
115
+ description_options = [ spec.description, spec.summary, "#{spec.name} - no description given" ]
116
+ self.description = description_options.find { |d| !(d.nil? or d.strip.empty?) }
117
+
118
+ # Upstream rpms seem to do this, might as well share.
119
+ self.provides << "rubygem(#{self.name})"
120
+
121
+ # By default, we'll usually automatically provide this, but in the case that we are
122
+ # composing multiple packages, it's best to explicitly include it in the provides list.
123
+ self.provides << "rubygem-#{self.name}"
124
+
125
+ spec.runtime_dependencies.map do |dep|
126
+ # rubygems 1.3.5 doesn't have 'Gem::Dependency#requirement'
127
+ if dep.respond_to?(:requirement)
128
+ reqs = dep.requirement.to_s
129
+ else
130
+ reqs = dep.version_requirements
131
+ end
132
+
133
+ # Some reqs can be ">= a, < b" versions, let's handle that.
134
+ reqs.to_s.split(/, */).each do |req|
135
+ self.dependencies << "#{attributes[:gem_package_name_prefix]}-#{dep.name} #{req}"
136
+ end
137
+ end # runtime_dependencies
138
+ end # ::Gem::Package
139
+ end # def load_package_info
140
+
141
+ def install_to_staging(gem_path)
142
+ if attributes.include?(:path_prefix)
143
+ installdir = "#{staging_path}/#{attributes[:path_prefix]}"
144
+ else
145
+ installdir = File.join(staging_path, ::Gem::dir)
146
+ end
147
+
148
+ ::FileUtils.mkdir_p(installdir)
149
+ # TODO(sissel): Allow setting gem tool path
150
+ args = [attributes[:gem_gem], "install", "--quiet", "--no-ri", "--no-rdoc",
151
+ "--install-dir", installdir, "--ignore-dependencies", "-E"]
152
+ if attributes[:gem_bin_path]
153
+ bin_path = File.join(staging_path, attributes[:gem_bin_path])
154
+ args += ["--bindir", bin_path]
155
+ end
156
+
157
+ args << gem_path
158
+ safesystem(*args)
159
+ end # def install_to_staging
160
+
161
+ public(:input, :output)
162
+ end # class FPM::Package::Gem
@@ -1,9 +1,9 @@
1
1
  require "fpm/namespace"
2
- require "fpm/source"
2
+ require "fpm/package"
3
3
  require "fpm/util"
4
4
  require "fileutils"
5
5
 
6
- class FPM::Source::Npm < FPM::Source
6
+ class FPM::Package::NPM < FPM::Package
7
7
  def get_source(params)
8
8
  @npm = @paths.first
9
9
  end # def get_source
@@ -33,4 +33,4 @@ class FPM::Source::Npm < FPM::Source
33
33
  safesystem(*["gzip", "-f", tar_path])
34
34
  end
35
35
 
36
- end # class FPM::Source::Gem
36
+ end # class FPM::Package::NPM
@@ -0,0 +1,41 @@
1
+ require "fpm/namespace"
2
+ require "fpm/package"
3
+ require "fileutils"
4
+ require "fpm/util"
5
+
6
+ class FPM::Package::PEAR < FPM::Package
7
+ option "--package-prefix", "PREFIX",
8
+ "Name prefix for python package", :default => "php-pear"
9
+
10
+ def input(input_package)
11
+ if !program_in_path?("pear")
12
+ raise ExecutableNotFound.new("pear")
13
+ end
14
+
15
+ # Create a temporary config file
16
+ @logger.debug("Creating pear config file")
17
+ config = File.expand_path(build_path("pear.config"))
18
+ installroot = attributes[:prefix] || "/usr/share"
19
+ safesystem("pear", "config-create", staging_path(installroot), config)
20
+
21
+ @logger.info("Fetching package information", :package => input_package)
22
+ pear_cmd = "pear -c #{config} remote-info #{input_package}"
23
+ name = %x{#{pear_cmd} | sed -ne '/^Package\s*/s/^Package\s*//p'}.chomp
24
+ self.name = "#{attributes[:pear_package_prefix]}-#{name}"
25
+ self.version = %x{#{pear_cmd} | sed -ne '/^Latest\s*/s/^Latest\s*//p'}.chomp
26
+ self.description = %x{#{pear_cmd} | sed -ne '/^Summary\s*/s/^Summary\s*//p'}.chomp
27
+
28
+ @logger.info("Installing pear package", :package => input_package,
29
+ :directory => staging_path)
30
+ ::Dir.chdir(staging_path) do
31
+ safesystem("pear", "-c", config, "install", "-n", "-f", "-P", ".",
32
+ input_package)
33
+ end
34
+
35
+ # Remove the stuff we don't want
36
+ delete_these = [".depdb", ".depdblock", ".filemap", ".lock", ".channel"]
37
+ Find.find(staging_path) do |path|
38
+ FileUtils.rm_r(path) if delete_these.include?(File.basename(path))
39
+ end
40
+ end # def input
41
+ end # class FPM::Package::PEAR
@@ -5,9 +5,7 @@ require "fpm/errors"
5
5
  require "etc"
6
6
  require "fileutils"
7
7
 
8
- # TODO(sissel): Add dependency checking support.
9
- # IIRC this has to be done as a 'checkinstall' step.
10
- class FPM::Target::Puppet < FPM::Package
8
+ class FPM::Package::Puppet < FPM::Package
11
9
  def architecture
12
10
  case @architecture
13
11
  when nil, "native"
File without changes
Binary file
@@ -61,7 +61,7 @@ class get_metadata(Command):
61
61
  dependencies = [dependencies]
62
62
 
63
63
  final_deps = []
64
- dep_re = re.compile("([^<>= ]+)(?:\s*([<>=]{1,2})\s*(.*))?$")
64
+ dep_re = re.compile("([^<>= ]+)(?:\s*([<>=]{1,2})\s*([^,]*))?(?:,\s*([<>=]{1,2})\s*(.*))?$")
65
65
  for dep in dependencies:
66
66
  # python deps are strings that look like:
67
67
  # "packagename"
@@ -74,10 +74,17 @@ class get_metadata(Command):
74
74
  elif m.groups()[1] is None:
75
75
  name, cond, version = m.groups()[0], ">=", 0
76
76
  else:
77
- name, cond, version = m.groups()
77
+ groups = m.groups()
78
+ name, cond, version = groups[0:3]
79
+ if groups[3] is not None:
80
+ final_deps.append("%s %s %s" % (groups[0],
81
+ self._replace_deprecated(groups[3]),
82
+ groups[4]))
78
83
  # end if
79
84
 
80
- final_deps.append("%s %s %s" % (name, cond, version))
85
+ final_deps.append("%s %s %s" % (name,
86
+ self._replace_deprecated(cond),
87
+ version))
81
88
  # end for i in dependencies
82
89
 
83
90
  data["dependencies"] = final_deps
@@ -90,4 +97,9 @@ class get_metadata(Command):
90
97
  print json.write(data)
91
98
 
92
99
  # def run
100
+
101
+ def _replace_deprecated(self, sign):
102
+ """Replace deprecated operators"""
103
+ return {'<': '<<', '>': '>>'}.get(sign, sign)
104
+
93
105
  # class list_dependencies
@@ -0,0 +1,125 @@
1
+ require "fpm/namespace"
2
+ require "fpm/package"
3
+ require "fpm/util"
4
+ require "rubygems/package"
5
+ require "rubygems"
6
+ require "fileutils"
7
+ require "tmpdir"
8
+ require "json"
9
+
10
+ class FPM::Package::Python < FPM::Package
11
+ option "--bin", "PYTHON_EXECUTABLE",
12
+ "The path to the python executable you wish to run.", :default => "python"
13
+ option "--easyinstall", "EASYINSTALL_EXECUTABLE",
14
+ "The path to the easy_install executable tool", :default => "easy_install"
15
+ option "--pypi", "PYPI_URL",
16
+ "PyPi Server uri for retrieving packages.",
17
+ :default => "http://pypi.python.org/simple"
18
+ option "--package-prefix", "PREFIX",
19
+ "Name prefix for python package", :default => "python"
20
+
21
+ def input(package)
22
+ path_to_package = download_if_necessary(package, version)
23
+
24
+ if File.directory?(path_to_package)
25
+ setup_py = File.join(path_to_package, "setup.py")
26
+ else
27
+ setup_py = path_to_package
28
+ end
29
+
30
+ if !File.exists?(setup_py)
31
+ @logger.error("Could not find 'setup.py'", :path => setup_py)
32
+ raise "Unable to find python package; tried #{setup_py}"
33
+ end
34
+
35
+ load_package_info(setup_py)
36
+ install_to_staging(setup_py)
37
+ end # def input
38
+
39
+ def download_if_necessary(package, version=nil)
40
+ path = package
41
+ # If it's a path, assume local build.
42
+ if File.directory?(path) or (File.exists?(path) and File.basename(path) == "setup.py")
43
+ return path
44
+ end
45
+
46
+ @logger.info("Trying to download", :package => package)
47
+
48
+ if version.nil?
49
+ want_pkg = "#{package}"
50
+ else
51
+ want_pkg = "#{package}==#{version}"
52
+ end
53
+
54
+ # TODO(sissel): support a settable path to 'easy_install'
55
+ # TODO(sissel): support a tunable for uthe url to pypi
56
+ safesystem("easy_install", "-i", "http://pypi.python.org/simple",
57
+ "--editable", "-U", "--build-directory", build_path, want_pkg)
58
+
59
+ # easy_install will put stuff in @tmpdir/packagename/, so find that:
60
+ # @tmpdir/somepackage/setup.py
61
+ dirs = ::Dir.glob(File.join(build_path, "*"))
62
+ if dirs.length != 1
63
+ raise "Unexpected directory layout after easy_install. Maybe file a bug? The directory is #{build_path}"
64
+ end
65
+ return dirs.first
66
+ end # def download
67
+
68
+ def load_package_info(setup_py)
69
+ if !attributes.include?(:package_name_prefix)
70
+ attributes[:package_name_prefix] = "python"
71
+ end
72
+
73
+ # Add ./pyfpm/ to the python library path
74
+ pylib = File.expand_path(File.dirname(__FILE__))
75
+ setup_cmd = "env PYTHONPATH=#{pylib} #{self.attributes[:python_bin]} #{setup_py} --command-packages=pyfpm get_metadata"
76
+ output = ::Dir.chdir(File.dirname(setup_py)) { `#{setup_cmd}` }
77
+ puts output
78
+ metadata = JSON.parse(output[/\{.*\}/msx])
79
+
80
+ self.architecture = metadata["architecture"]
81
+ self.description = metadata["description"]
82
+ self.license = metadata["license"]
83
+ self.version = metadata["version"]
84
+ self.url = metadata["url"]
85
+
86
+ self.name = fix_name(metadata["name"])
87
+
88
+ self.dependencies += metadata["dependencies"].collect do |dep|
89
+ name, cmp, version = dep.split
90
+ name = fix_name(name)
91
+ "#{name} #{cmp} #{version}"
92
+ end
93
+ end # def load_package_info
94
+
95
+ # Sanitize package name.
96
+ # Some PyPI packages can be named 'python-foo', so we don't want to end up
97
+ # with a package named 'python-python-foo'.
98
+ # But we want packages named like 'pythonweb' to be suffixed
99
+ # 'python-pythonweb'.
100
+ def fix_name(name)
101
+ if name.start_with?("python")
102
+ # If the python package is called "python-foo" strip the "python-" part while
103
+ # prepending the package name prefix.
104
+ return [attributes[:package_name_prefix], name.gsub(/^python-/, "")].join("-")
105
+ else
106
+ return [attributes[:package_name_prefix], name].join("-")
107
+ end
108
+ end # def fix_name
109
+
110
+ def install_to_staging(setup_py)
111
+ dir = File.dirname(setup_py)
112
+
113
+ # Some setup.py's assume $PWD == current directory of setup.py, so let's
114
+ # chdir first.
115
+ ::Dir.chdir(dir) do
116
+ if attributes[:prefix]
117
+ safesystem(attributes[:python_bin], "setup.py", "install", "--prefix",
118
+ File.join(staging_path, attributes[:prefix]))
119
+ else
120
+ safesystem(attributes[:python_bin], "setup.py", "install", "--root",
121
+ staging_path)
122
+ end
123
+ end
124
+ end # def install_to_staging
125
+ end # class FPM::Package::Python
@@ -0,0 +1,132 @@
1
+ require "fpm/package"
2
+ require "backports"
3
+ require "fileutils"
4
+ require "find"
5
+ require "arr-pm/file" # gem 'arr-pm'
6
+
7
+ # RPM Package type.
8
+ #
9
+ # Build RPMs without having to waste hours reading Maximum-RPM.
10
+ # Well, in case you want to read it, here: http://www.rpm.org/max-rpm/
11
+ #
12
+ # The following attributes are supported:
13
+ #
14
+ # * :rpm_rpmbuild_define - an array of definitions to give to rpmbuild.
15
+ # These are used, verbatim, each as: --define ITEM
16
+ class FPM::Package::RPM < FPM::Package
17
+ option "--rpmbuild-define", "DEFINITION",
18
+ "Pass a --define argument to rpmbuild." do |define|
19
+ attributes[:rpm_rpmbuild_define] ||= []
20
+ attributes[:rpm_rpmbuild_define] << define
21
+ end
22
+
23
+ private
24
+
25
+ def architecture
26
+ case @architecture
27
+ when nil
28
+ return %x{uname -m}.chomp # default to current arch
29
+ when "amd64" # debian and redhat disagree on architecture names
30
+ return "x86_64"
31
+ when "native"
32
+ return %x{uname -m}.chomp # 'native' is current arch
33
+ when "all"
34
+ # Translate fpm "all" arch to what it means in RPM.
35
+ return "noarch"
36
+ else
37
+ return @architecture
38
+ end
39
+ end # def architecture
40
+
41
+ # See FPM::Package#converted_from
42
+ def converted_from(origin)
43
+ if origin == FPM::Package::Gem
44
+ # Gem dependency operator "~>" is not compatible with rpm. Translate any found.
45
+ fixed_deps = []
46
+ self.dependencies.collect do |dep|
47
+ name, op, version = dep.split(/\s+/)
48
+ if op == "~>"
49
+ # ~> x.y means: > x.y and < (x+1).0
50
+ fixed_deps << "#{name} > #{version}"
51
+ fixed_deps << "#{name} < #{version.to_i + 1}.0.0"
52
+ else
53
+ fixed_deps << dep
54
+ end
55
+ end
56
+ self.dependencies = fixed_deps
57
+ end
58
+ end # def converted
59
+
60
+ def input(path)
61
+ rpm = ::RPM::File.new(path)
62
+
63
+ tags = {}
64
+ rpm.header.tags.each do |tag|
65
+ tags[tag.tag] = tag.value
66
+ end
67
+
68
+ self.architecture = tags[:arch]
69
+ self.category = tags[:group]
70
+ self.config_files = config_files
71
+ self.description = tags[:description]
72
+ self.epoch = (tags[:epoch] || [nil]).first # for some reason epoch is an array
73
+ self.iteration = tags[:release]
74
+ self.license = tags[:license]
75
+ self.maintainer = maintainer
76
+ self.name = tags[:name]
77
+ self.url = tags[:url]
78
+ self.vendor = tags[:vendor]
79
+ self.version = tags[:version]
80
+
81
+ # TODO(sissel): Collect {pre,post}{install,uninstall} scripts
82
+ # TODO(sissel): put 'trigger scripts' stuff into attributes
83
+ # TODO(sissel): support provides
84
+ # TODO(sissel): support conflicts
85
+ # TODO(sissel): support replaces
86
+
87
+ self.dependencies += rpm.requires.collect do |name, operator, version|
88
+ [name, operator, version].join(" ")
89
+ end
90
+ #input.replaces += replaces
91
+
92
+ # Extract to the staging directory
93
+ rpm.extract(staging_path)
94
+ end # def input
95
+
96
+ def output(output_path)
97
+ %w(BUILD RPMS SRPMS SOURCES SPECS).each { |d| FileUtils.mkdir_p(build_path(d)) }
98
+ args = ["rpmbuild", "-bb",
99
+ "--define", "buildroot #{build_path}/BUILD",
100
+ "--define", "_topdir #{build_path}",
101
+ "--define", "_sourcedir #{build_path}",
102
+ "--define", "_rpmdir #{build_path}/RPMS"]
103
+
104
+ (attributes[:rpm_rpmbuild_define] or []).each do |define|
105
+ args += ["--define", define]
106
+ end
107
+
108
+ rpmspec = template("rpm.erb").result(binding)
109
+ specfile = File.join(build_path("SPECS"), "#{name}.spec")
110
+ File.write(specfile, rpmspec)
111
+ File.write("/tmp/rpm.spec", rpmspec)
112
+
113
+ args << specfile
114
+ #if defines.empty?
115
+ #args = prefixargs + spec
116
+ #else
117
+ #args = prefixargs + defines.collect{ |define| ["--define", define] }.flatten + spec
118
+ #end
119
+
120
+ @logger.info("Running rpmbuild", :args => args)
121
+ safesystem(*args)
122
+
123
+ ::Dir["#{build_path}/RPMS/**/*.rpm"].each do |rpmpath|
124
+ # This should only output one rpm, should we verify this?
125
+ FileUtils.cp(rpmpath, output_path)
126
+ end
127
+
128
+ @logger.log("Created rpm", :path => output_path)
129
+ end # def output
130
+
131
+ public(:input, :output, :converted_from)
132
+ end # class FPM::Package::RPM