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.
- data/CHANGELIST +15 -0
- data/bin/fpm +2 -15
- data/lib/fpm.rb +5 -12
- data/lib/fpm/command.rb +323 -0
- data/lib/fpm/errors.rb +1 -0
- data/lib/fpm/namespace.rb +2 -11
- data/lib/fpm/package.rb +255 -100
- data/lib/fpm/package/deb.rb +367 -0
- data/lib/fpm/package/dir.rb +86 -0
- data/lib/fpm/package/gem.rb +162 -0
- data/lib/fpm/{source → package}/npm.rb +3 -3
- data/lib/fpm/package/pear.rb +41 -0
- data/lib/fpm/{target → package}/puppet.rb +1 -3
- data/lib/fpm/{source → package}/pyfpm/__init__.py +0 -0
- data/lib/fpm/package/pyfpm/__init__.pyc +0 -0
- data/lib/fpm/{source → package}/pyfpm/get_metadata.py +15 -3
- data/lib/fpm/package/pyfpm/get_metadata.pyc +0 -0
- data/lib/fpm/package/python.rb +125 -0
- data/lib/fpm/package/rpm.rb +132 -0
- data/lib/fpm/{target → package}/solaris.rb +3 -2
- data/lib/fpm/package/tar.rb +62 -0
- data/lib/fpm/util.rb +56 -7
- data/templates/deb.erb +12 -12
- data/templates/rpm.erb +32 -38
- data/templates/solaris.erb +1 -1
- metadata +119 -78
- data/lib/fpm/builder.rb +0 -220
- data/lib/fpm/flags.rb +0 -20
- data/lib/fpm/program.rb +0 -273
- data/lib/fpm/rubyfixes.rb +0 -11
- data/lib/fpm/source.rb +0 -155
- data/lib/fpm/source/dir.rb +0 -59
- data/lib/fpm/source/gem.rb +0 -162
- data/lib/fpm/source/python.rb +0 -137
- data/lib/fpm/source/rpm.rb +0 -28
- data/lib/fpm/source/tar.rb +0 -50
- data/lib/fpm/target/deb.rb +0 -184
- data/lib/fpm/target/rpm.rb +0 -68
- data/lib/rpm/header.rb +0 -89
- data/lib/rpm/lead.rb +0 -48
- data/lib/rpm/namespace.rb +0 -1
- data/lib/rpm/rpmfile.rb +0 -81
- 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/
|
2
|
+
require "fpm/package"
|
3
3
|
require "fpm/util"
|
4
4
|
require "fileutils"
|
5
5
|
|
6
|
-
class FPM::
|
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::
|
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
|
-
|
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
|
-
|
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,
|
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
|
Binary file
|
@@ -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
|