fpm 0.3.11 → 0.4.0pre1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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