fpm-itchio 1.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/CHANGELIST +629 -0
- data/CONTRIBUTORS +26 -0
- data/LICENSE +21 -0
- data/bin/fpm +8 -0
- data/lib/fpm.rb +18 -0
- data/lib/fpm/command.rb +642 -0
- data/lib/fpm/errors.rb +4 -0
- data/lib/fpm/namespace.rb +4 -0
- data/lib/fpm/package.rb +524 -0
- data/lib/fpm/package/cpan.rb +378 -0
- data/lib/fpm/package/deb.rb +887 -0
- data/lib/fpm/package/dir.rb +207 -0
- data/lib/fpm/package/empty.rb +13 -0
- data/lib/fpm/package/gem.rb +224 -0
- data/lib/fpm/package/npm.rb +120 -0
- data/lib/fpm/package/osxpkg.rb +164 -0
- data/lib/fpm/package/p5p.rb +124 -0
- data/lib/fpm/package/pacman.rb +397 -0
- data/lib/fpm/package/pear.rb +117 -0
- data/lib/fpm/package/pkgin.rb +35 -0
- data/lib/fpm/package/puppet.rb +120 -0
- data/lib/fpm/package/pyfpm/__init__.py +1 -0
- data/lib/fpm/package/pyfpm/get_metadata.py +104 -0
- data/lib/fpm/package/python.rb +317 -0
- data/lib/fpm/package/rpm.rb +583 -0
- data/lib/fpm/package/sh.rb +69 -0
- data/lib/fpm/package/solaris.rb +95 -0
- data/lib/fpm/package/tar.rb +74 -0
- data/lib/fpm/package/virtualenv.rb +145 -0
- data/lib/fpm/package/zip.rb +63 -0
- data/lib/fpm/rake_task.rb +59 -0
- data/lib/fpm/util.rb +253 -0
- data/lib/fpm/version.rb +3 -0
- data/templates/deb.erb +52 -0
- data/templates/deb/changelog.erb +5 -0
- data/templates/deb/ldconfig.sh.erb +13 -0
- data/templates/deb/postinst_upgrade.sh.erb +62 -0
- data/templates/deb/postrm_upgrade.sh.erb +46 -0
- data/templates/deb/preinst_upgrade.sh.erb +41 -0
- data/templates/deb/prerm_upgrade.sh.erb +39 -0
- data/templates/osxpkg.erb +11 -0
- data/templates/p5p_metadata.erb +12 -0
- data/templates/pacman.erb +47 -0
- data/templates/pacman/INSTALL.erb +41 -0
- data/templates/puppet/package.pp.erb +34 -0
- data/templates/puppet/package/remove.pp.erb +13 -0
- data/templates/rpm.erb +261 -0
- data/templates/rpm/filesystem_list +14514 -0
- data/templates/sh.erb +367 -0
- data/templates/solaris.erb +15 -0
- metadata +265 -0
@@ -0,0 +1,69 @@
|
|
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 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?(:after_install)
|
28
|
+
File.write(File.join(fpm_meta_path, "after_install"), script(:after_install))
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def install_script
|
33
|
+
path = build_path("installer.sh")
|
34
|
+
File.open(path, "w") do |file|
|
35
|
+
file.write template("sh.erb").result(binding)
|
36
|
+
end
|
37
|
+
path
|
38
|
+
end
|
39
|
+
|
40
|
+
# Returns the path to the tar file containing the packed up staging directory
|
41
|
+
def payload
|
42
|
+
payload_tar = build_path("payload.tar")
|
43
|
+
logger.info("Creating payload tar ", :path => payload_tar)
|
44
|
+
|
45
|
+
args = [ tar_cmd,
|
46
|
+
"-C",
|
47
|
+
staging_path,
|
48
|
+
"-cf",
|
49
|
+
payload_tar,
|
50
|
+
"--owner=0",
|
51
|
+
"--group=0",
|
52
|
+
"--numeric-owner",
|
53
|
+
"." ]
|
54
|
+
|
55
|
+
unless safesystem(*args)
|
56
|
+
raise "Command failed while creating payload tar: #{args}"
|
57
|
+
end
|
58
|
+
payload_tar
|
59
|
+
end
|
60
|
+
|
61
|
+
# Where we keep metadata and post install scripts and such
|
62
|
+
def fpm_meta_path
|
63
|
+
@fpm_meta_path ||= begin
|
64
|
+
path = File.join(staging_path, ".fpm")
|
65
|
+
FileUtils.mkdir_p(path)
|
66
|
+
path
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
@@ -0,0 +1,95 @@
|
|
1
|
+
require "erb"
|
2
|
+
require "fpm/namespace"
|
3
|
+
require "fpm/package"
|
4
|
+
require "fpm/errors"
|
5
|
+
require "fpm/util"
|
6
|
+
|
7
|
+
# TODO(sissel): Add dependency checking support.
|
8
|
+
# IIRC this has to be done as a 'checkinstall' step.
|
9
|
+
class FPM::Package::Solaris < FPM::Package
|
10
|
+
|
11
|
+
option "--user", "USER",
|
12
|
+
"Set the user to USER in the prototype files.",
|
13
|
+
:default => 'root'
|
14
|
+
|
15
|
+
option "--group", "GROUP",
|
16
|
+
"Set the group to GROUP in the prototype file.",
|
17
|
+
:default => 'root'
|
18
|
+
|
19
|
+
def architecture
|
20
|
+
case @architecture
|
21
|
+
when nil, "native"
|
22
|
+
@architecture = %x{uname -p}.chomp
|
23
|
+
end
|
24
|
+
# "all" is a valid arch according to
|
25
|
+
# http://www.bolthole.com/solaris/makeapackage.html
|
26
|
+
|
27
|
+
return @architecture
|
28
|
+
end # def architecture
|
29
|
+
|
30
|
+
def specfile(builddir)
|
31
|
+
"#{builddir}/pkginfo"
|
32
|
+
end
|
33
|
+
|
34
|
+
def output(output_path)
|
35
|
+
self.scripts.each do |name, path|
|
36
|
+
case name
|
37
|
+
when "pre-install"
|
38
|
+
safesystem("cp", path, "./preinstall")
|
39
|
+
File.chmod(0755, "./preinstall")
|
40
|
+
when "post-install"
|
41
|
+
safesystem("cp", path, "./postinstall")
|
42
|
+
File.chmod(0755, "./postinstall")
|
43
|
+
when "pre-uninstall"
|
44
|
+
raise FPM::InvalidPackageConfiguration.new(
|
45
|
+
"pre-uninstall is not supported by Solaris packages"
|
46
|
+
)
|
47
|
+
when "post-uninstall"
|
48
|
+
raise FPM::InvalidPackageConfiguration.new(
|
49
|
+
"post-uninstall is not supported by Solaris packages"
|
50
|
+
)
|
51
|
+
end # case name
|
52
|
+
end # self.scripts.each
|
53
|
+
|
54
|
+
template = template("solaris.erb")
|
55
|
+
File.open("#{build_path}/pkginfo", "w") do |pkginfo|
|
56
|
+
pkginfo.puts template.result(binding)
|
57
|
+
end
|
58
|
+
|
59
|
+
# Generate the package 'Prototype' file
|
60
|
+
File.open("#{build_path}/Prototype", "w") do |prototype|
|
61
|
+
prototype.puts("i pkginfo")
|
62
|
+
prototype.puts("i preinstall") if self.scripts["pre-install"]
|
63
|
+
prototype.puts("i postinstall") if self.scripts["post-install"]
|
64
|
+
|
65
|
+
# TODO(sissel): preinstall/postinstall
|
66
|
+
# strip @prefix, since BASEDIR will set prefix via the pkginfo file
|
67
|
+
IO.popen("pkgproto #{staging_path}/#{@prefix}=").each_line do |line|
|
68
|
+
type, klass, path, mode, user, group = line.split
|
69
|
+
|
70
|
+
prototype.puts([type, klass, path, mode, attributes[:solaris_user], attributes[:solaris_group]].join(" "))
|
71
|
+
end # popen "pkgproto ..."
|
72
|
+
end # File prototype
|
73
|
+
|
74
|
+
::Dir.chdir staging_path do
|
75
|
+
# Should create a package directory named by the package name.
|
76
|
+
safesystem("pkgmk", "-o", "-f", "#{build_path}/Prototype", "-d", build_path)
|
77
|
+
end
|
78
|
+
|
79
|
+
|
80
|
+
# Convert the 'package directory' built above to a real solaris package.
|
81
|
+
safesystem("pkgtrans", "-s", build_path, output_path, name)
|
82
|
+
safesystem("cp", "#{build_path}/#{output_path}", output_path)
|
83
|
+
end # def output
|
84
|
+
|
85
|
+
def default_output
|
86
|
+
v = version
|
87
|
+
v = "#{epoch}:#{v}" if epoch
|
88
|
+
if iteration
|
89
|
+
"#{name}_#{v}-#{iteration}_#{architecture}.#{type}"
|
90
|
+
else
|
91
|
+
"#{name}_#{v}_#{architecture}.#{type}"
|
92
|
+
end
|
93
|
+
end # def default_output
|
94
|
+
end # class FPM::Deb
|
95
|
+
|
@@ -0,0 +1,74 @@
|
|
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 tarball as a package.
|
8
|
+
#
|
9
|
+
# This provides no metadata. Both input and output are supported.
|
10
|
+
class FPM::Package::Tar < FPM::Package
|
11
|
+
|
12
|
+
# Input a tarball. Compressed tarballs should be OK.
|
13
|
+
def input(input_path)
|
14
|
+
# use part of the filename as the package name
|
15
|
+
self.name = File.basename(input_path).split(".").first
|
16
|
+
|
17
|
+
# Unpack the tarball to the build path before ultimately moving it to
|
18
|
+
# staging.
|
19
|
+
args = ["-xf", input_path, "-C", build_path]
|
20
|
+
|
21
|
+
# Add the tar compression flag if necessary
|
22
|
+
tar_compression_flag(input_path).tap do |flag|
|
23
|
+
args << flag unless flag.nil?
|
24
|
+
end
|
25
|
+
|
26
|
+
safesystem("tar", *args)
|
27
|
+
|
28
|
+
# use dir to set stuff up properly, mainly so I don't have to reimplement
|
29
|
+
# the chdir/prefix stuff special for tar.
|
30
|
+
dir = convert(FPM::Package::Dir)
|
31
|
+
if attributes[:chdir]
|
32
|
+
dir.attributes[:chdir] = File.join(build_path, attributes[:chdir])
|
33
|
+
else
|
34
|
+
dir.attributes[:chdir] = build_path
|
35
|
+
end
|
36
|
+
|
37
|
+
cleanup_staging
|
38
|
+
# Tell 'dir' to input "." and chdir/prefix will help it figure out the
|
39
|
+
# rest.
|
40
|
+
dir.input(".")
|
41
|
+
@staging_path = dir.staging_path
|
42
|
+
dir.cleanup_build
|
43
|
+
end # def input
|
44
|
+
|
45
|
+
# Output a tarball.
|
46
|
+
#
|
47
|
+
# If the output path ends predictably (like in .tar.gz) it will try to obey
|
48
|
+
# the compression type.
|
49
|
+
def output(output_path)
|
50
|
+
output_check(output_path)
|
51
|
+
# Unpack the tarball to the staging path
|
52
|
+
args = ["-cf", output_path, "-C", staging_path]
|
53
|
+
tar_compression_flag(output_path).tap do |flag|
|
54
|
+
args << flag unless flag.nil?
|
55
|
+
end
|
56
|
+
args << "."
|
57
|
+
|
58
|
+
safesystem("tar", *args)
|
59
|
+
end # def output
|
60
|
+
|
61
|
+
# Generate the proper tar flags based on the path name.
|
62
|
+
def tar_compression_flag(path)
|
63
|
+
case path
|
64
|
+
when /\.tar\.bz2$/
|
65
|
+
return "-j"
|
66
|
+
when /\.tar\.gz$|\.tgz$/
|
67
|
+
return "-z"
|
68
|
+
when /\.tar\.xz$/
|
69
|
+
return "-J"
|
70
|
+
else
|
71
|
+
return nil
|
72
|
+
end
|
73
|
+
end # def tar_compression_flag
|
74
|
+
end # class FPM::Package::Tar
|
@@ -0,0 +1,145 @@
|
|
1
|
+
require "fpm/namespace"
|
2
|
+
require "fpm/package"
|
3
|
+
require "fpm/util"
|
4
|
+
|
5
|
+
# Support for python virtualenv packages.
|
6
|
+
#
|
7
|
+
# This supports input, but not output.
|
8
|
+
#
|
9
|
+
class FPM::Package::Virtualenv < FPM::Package
|
10
|
+
# Flags '--foo' will be accessable as attributes[:virtualenv_foo]
|
11
|
+
|
12
|
+
option "--pypi", "PYPI_URL",
|
13
|
+
"PyPi Server uri for retrieving packages.",
|
14
|
+
:default => "https://pypi.python.org/simple"
|
15
|
+
option "--package-name-prefix", "PREFIX", "Name to prefix the package " \
|
16
|
+
"name with.", :default => "virtualenv"
|
17
|
+
|
18
|
+
option "--install-location", "DIRECTORY", "Location to which to " \
|
19
|
+
"install the virtualenv by default.", :default => "/usr/share/python" do |path|
|
20
|
+
File.expand_path(path)
|
21
|
+
end
|
22
|
+
|
23
|
+
option "--fix-name", :flag, "Should the target package name be prefixed?",
|
24
|
+
:default => true
|
25
|
+
option "--other-files-dir", "DIRECTORY", "Optionally, the contents of the " \
|
26
|
+
"specified directory may be added to the package. This is useful if the " \
|
27
|
+
"virtualenv needs configuration files, etc.", :default => nil
|
28
|
+
option "--pypi-extra-url", "PYPI_EXTRA_URL",
|
29
|
+
"PyPi extra-index-url for pointing to your priviate PyPi",
|
30
|
+
:multivalued => true, :attribute_name => :virtualenv_pypi_extra_index_urls,
|
31
|
+
:default => nil
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
# Input a package.
|
36
|
+
#
|
37
|
+
# `package` can look like `psutil==2.2.1` or `psutil`.
|
38
|
+
def input(package)
|
39
|
+
installdir = attributes[:virtualenv_install_location]
|
40
|
+
m = /^([^=]+)==([^=]+)$/.match(package)
|
41
|
+
package_version = nil
|
42
|
+
|
43
|
+
if m
|
44
|
+
package_name = m[1]
|
45
|
+
package_version = m[2]
|
46
|
+
self.version ||= package_version
|
47
|
+
else
|
48
|
+
package_name = package
|
49
|
+
package_version = nil
|
50
|
+
end
|
51
|
+
|
52
|
+
virtualenv_name = package_name
|
53
|
+
|
54
|
+
self.name ||= package_name
|
55
|
+
|
56
|
+
if self.attributes[:virtualenv_fix_name?]
|
57
|
+
self.name = [self.attributes[:virtualenv_package_name_prefix],
|
58
|
+
self.name].join("-")
|
59
|
+
end
|
60
|
+
|
61
|
+
virtualenv_folder =
|
62
|
+
File.join(installdir,
|
63
|
+
virtualenv_name)
|
64
|
+
|
65
|
+
virtualenv_build_folder = build_path(virtualenv_folder)
|
66
|
+
|
67
|
+
::FileUtils.mkdir_p(virtualenv_build_folder)
|
68
|
+
|
69
|
+
safesystem("virtualenv", virtualenv_build_folder)
|
70
|
+
pip_exe = File.join(virtualenv_build_folder, "bin", "pip")
|
71
|
+
python_exe = File.join(virtualenv_build_folder, "bin", "python")
|
72
|
+
|
73
|
+
# Why is this hack here? It looks important, so I'll keep it in.
|
74
|
+
safesystem(pip_exe, "install", "-U", "-i",
|
75
|
+
attributes[:virtualenv_pypi],
|
76
|
+
"pip", "distribute")
|
77
|
+
safesystem(pip_exe, "uninstall", "-y", "distribute")
|
78
|
+
|
79
|
+
extra_index_url_args = []
|
80
|
+
if attributes[:virtualenv_pypi_extra_index_urls]
|
81
|
+
attributes[:virtualenv_pypi_extra_index_urls].each do |extra_url|
|
82
|
+
extra_index_url_args << "--extra-index-url" << extra_url
|
83
|
+
end
|
84
|
+
end
|
85
|
+
pip_args = [pip_exe, "install", "-i", attributes[:virtualenv_pypi]] << extra_index_url_args << package
|
86
|
+
safesystem(*pip_args.flatten)
|
87
|
+
|
88
|
+
if package_version.nil?
|
89
|
+
frozen = safesystemout(pip_exe, "freeze")
|
90
|
+
package_version = frozen[/#{package}==[^=]+$/].split("==")[1].chomp!
|
91
|
+
self.version ||= package_version
|
92
|
+
end
|
93
|
+
|
94
|
+
::Dir[build_path + "/**/*"].each do |f|
|
95
|
+
if ! File.world_readable? f
|
96
|
+
File.lchmod(File.stat(f).mode | 444)
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
::Dir.chdir(virtualenv_build_folder) do
|
101
|
+
safesystem("virtualenv-tools", "--update-path", virtualenv_folder)
|
102
|
+
end
|
103
|
+
|
104
|
+
if !attributes[:virtualenv_other_files_dir].nil?
|
105
|
+
# Copy all files from other dir to build_path
|
106
|
+
Find.find(attributes[:virtualenv_other_files_dir]) do |path|
|
107
|
+
src = path.gsub(/^#{attributes[:virtualenv_other_files_dir]}/, '')
|
108
|
+
dst = File.join(build_path, src)
|
109
|
+
copy_entry(path, dst, preserve=true, remove_destination=true)
|
110
|
+
copy_metadata(path, dst)
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
remove_python_compiled_files virtualenv_build_folder
|
115
|
+
|
116
|
+
# use dir to set stuff up properly, mainly so I don't have to reimplement
|
117
|
+
# the chdir/prefix stuff special for tar.
|
118
|
+
dir = convert(FPM::Package::Dir)
|
119
|
+
|
120
|
+
if attributes[:chdir]
|
121
|
+
dir.attributes[:chdir] = File.join(build_path, attributes[:chdir])
|
122
|
+
else
|
123
|
+
dir.attributes[:chdir] = build_path
|
124
|
+
end
|
125
|
+
|
126
|
+
cleanup_staging
|
127
|
+
# Tell 'dir' to input "." and chdir/prefix will help it figure out the
|
128
|
+
# rest.
|
129
|
+
dir.input(".")
|
130
|
+
@staging_path = dir.staging_path
|
131
|
+
dir.cleanup_build
|
132
|
+
|
133
|
+
end # def input
|
134
|
+
|
135
|
+
# Delete python precompiled files found in a given folder.
|
136
|
+
def remove_python_compiled_files path
|
137
|
+
logger.debug("Now removing python object and compiled files from the virtualenv")
|
138
|
+
Find.find(path) do |path|
|
139
|
+
if path.end_with? '.pyc' or path.end_with? '.pyo'
|
140
|
+
FileUtils.rm path
|
141
|
+
end
|
142
|
+
end
|
143
|
+
end
|
144
|
+
public(:input)
|
145
|
+
end # class FPM::Package::Virtualenv
|
@@ -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
|