fpm 0.1.4 → 0.1.5
Sign up to get free protection for your applications and to get access to all the features.
- data/bin/fpm +14 -18
- data/lib/fpm.rb +9 -1
- data/lib/fpm/builder.rb +133 -0
- data/lib/fpm/namespace.rb +13 -1
- data/lib/fpm/package.rb +47 -22
- data/lib/fpm/source.rb +88 -0
- data/lib/fpm/source/dir.rb +14 -0
- data/lib/fpm/source/gem.rb +86 -0
- data/lib/fpm/source/rpm.rb +28 -0
- data/lib/fpm/target/deb.rb +31 -0
- data/lib/fpm/target/rpm.rb +19 -0
- data/templates/deb.erb +10 -10
- data/templates/rpm.erb +41 -0
- metadata +12 -5
- data/lib/fpm/deb.rb +0 -74
data/bin/fpm
CHANGED
@@ -5,6 +5,8 @@ require "rubygems"
|
|
5
5
|
require "optparse"
|
6
6
|
require "ostruct"
|
7
7
|
require "erb"
|
8
|
+
|
9
|
+
$: << "#{File.dirname(__FILE__)}/../lib"
|
8
10
|
require "fpm"
|
9
11
|
|
10
12
|
def main(args)
|
@@ -49,29 +51,23 @@ def main(args)
|
|
49
51
|
opts.on("-C DIRECTORY", "Change directory before searching for files") do |dir|
|
50
52
|
settings.chdir = dir
|
51
53
|
end
|
52
|
-
end # OptionParser
|
53
54
|
|
54
|
-
|
55
|
+
opts.on("-t PACKAGE_TYPE", "the type of package you want to create") do |type|
|
56
|
+
settings.package_type = type
|
57
|
+
end
|
55
58
|
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
end
|
59
|
+
opts.on("-s SOURCE_TYPE", "what to build the package from") do |st|
|
60
|
+
settings.source_type = st
|
61
|
+
end
|
62
|
+
end # OptionParser
|
60
63
|
|
61
|
-
|
62
|
-
package.name = settings.package_name
|
63
|
-
package.version = settings.version
|
64
|
-
package.maintainer = settings.maintainer if settings.maintainer
|
65
|
-
package.architecture = (settings.architecture or %x{uname -m}.chomp)
|
66
|
-
package.dependencies = (settings.dependencies or [])
|
64
|
+
opts.parse!(args)
|
67
65
|
|
68
66
|
p settings
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
"paths" => args, # Remainder of args are paths.
|
73
|
-
})
|
67
|
+
FPM::Builder.new(settings, args).assemble!
|
68
|
+
|
69
|
+
return 0
|
74
70
|
end # def main
|
75
71
|
|
76
|
-
ret = main(ARGV)
|
72
|
+
ret = main(ARGV)
|
77
73
|
exit(ret != nil ? ret : 0)
|
data/lib/fpm.rb
CHANGED
data/lib/fpm/builder.rb
ADDED
@@ -0,0 +1,133 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
class FPM::Builder
|
3
|
+
# where is the package's root?
|
4
|
+
def root
|
5
|
+
@root ||= (@source.root || '.')
|
6
|
+
end
|
7
|
+
|
8
|
+
# where the package goes
|
9
|
+
def output
|
10
|
+
@output ||= begin
|
11
|
+
o = @package.default_output
|
12
|
+
if o.start_with? '/'
|
13
|
+
o
|
14
|
+
else
|
15
|
+
File.join(@working_dir, o)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
# things to clean up afterwards
|
21
|
+
def garbage
|
22
|
+
@garbage ||= []
|
23
|
+
end
|
24
|
+
|
25
|
+
attr_reader :paths
|
26
|
+
attr_reader :package
|
27
|
+
attr_reader :source
|
28
|
+
|
29
|
+
def initialize(settings, paths=[])
|
30
|
+
@working_dir = Dir.pwd
|
31
|
+
root = settings.chdir || '.'
|
32
|
+
paths = ['.'] if paths.empty?
|
33
|
+
@source = source_class_for(settings.source_type || 'dir').new(
|
34
|
+
paths, root,
|
35
|
+
:version => settings.version,
|
36
|
+
:name => settings.package_name
|
37
|
+
)
|
38
|
+
|
39
|
+
@package = package_class_for(settings.package_type).new(@source)
|
40
|
+
@paths = paths
|
41
|
+
|
42
|
+
@output = settings.package_path
|
43
|
+
end # def initialize
|
44
|
+
|
45
|
+
def tar_path
|
46
|
+
@tar_path ||= "#{builddir}/data.tar"
|
47
|
+
end
|
48
|
+
|
49
|
+
# Assemble the package
|
50
|
+
def assemble!
|
51
|
+
output.gsub!(/VERSION/, "#{@source[:version]}-#{@source[:iteration]}")
|
52
|
+
output.gsub!(/ARCH/, @package.architecture)
|
53
|
+
|
54
|
+
File.delete(output) if File.exists?(output) && !File.directory?(output)
|
55
|
+
|
56
|
+
make_builddir!
|
57
|
+
|
58
|
+
::Dir.chdir root do
|
59
|
+
@source.make_tarball!(tar_path)
|
60
|
+
|
61
|
+
generate_md5sums
|
62
|
+
generate_specfile
|
63
|
+
end
|
64
|
+
|
65
|
+
::Dir.chdir(builddir) do
|
66
|
+
@package.build!({
|
67
|
+
:tarball => tar_path,
|
68
|
+
:output => output
|
69
|
+
})
|
70
|
+
end
|
71
|
+
|
72
|
+
cleanup!
|
73
|
+
end # def assemble!
|
74
|
+
|
75
|
+
private
|
76
|
+
def builddir
|
77
|
+
@builddir ||= File.expand_path(
|
78
|
+
"#{Dir.pwd}/build-#{@package.type}-#{File.basename(output)}"
|
79
|
+
)
|
80
|
+
end
|
81
|
+
|
82
|
+
def make_builddir!
|
83
|
+
FileUtils.rm_rf builddir
|
84
|
+
garbage << builddir
|
85
|
+
FileUtils.mkdir(builddir) if !File.directory?(builddir)
|
86
|
+
end
|
87
|
+
|
88
|
+
# TODO: [Jay] make this better.
|
89
|
+
def package_class_for(type)
|
90
|
+
type = FPM::Target::constants.find { |c| c.downcase == type }
|
91
|
+
if !type
|
92
|
+
raise ArgumentError, "unknown package type #{type.inspect}"
|
93
|
+
end
|
94
|
+
|
95
|
+
return FPM::Target.const_get(type)
|
96
|
+
end
|
97
|
+
|
98
|
+
# TODO: [Jay] make this better.
|
99
|
+
def source_class_for(type)
|
100
|
+
type = FPM::Source::constants.find { |c| c.downcase == type }
|
101
|
+
if !type
|
102
|
+
raise ArgumentError, "unknown package type #{type.inspect}"
|
103
|
+
end
|
104
|
+
|
105
|
+
return FPM::Source.const_get(type)
|
106
|
+
end
|
107
|
+
|
108
|
+
def cleanup!
|
109
|
+
return [] if garbage.empty?
|
110
|
+
FileUtils.rm_rf(garbage) && garbage.clear
|
111
|
+
end
|
112
|
+
|
113
|
+
def generate_specfile
|
114
|
+
File.open(@package.specfile(builddir), "w") do |f|
|
115
|
+
f.puts @package.render_spec
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
def generate_md5sums
|
120
|
+
md5sums = checksum(paths)
|
121
|
+
File.open("#{builddir}/md5sums", "w") { |f| f.puts md5sums }
|
122
|
+
md5sums
|
123
|
+
end
|
124
|
+
|
125
|
+
def checksum(paths)
|
126
|
+
md5sums = []
|
127
|
+
paths.each do |path|
|
128
|
+
md5sums += %x{find #{path} -type f -print0 | xargs -0 md5sum}.split("\n")
|
129
|
+
end
|
130
|
+
end # def checksum
|
131
|
+
|
132
|
+
|
133
|
+
end
|
data/lib/fpm/namespace.rb
CHANGED
data/lib/fpm/package.rb
CHANGED
@@ -37,31 +37,56 @@ class FPM::Package
|
|
37
37
|
|
38
38
|
# Array of dependencies.
|
39
39
|
attr_accessor :dependencies
|
40
|
+
|
41
|
+
# a summary or description of the package
|
42
|
+
attr_accessor :summary
|
40
43
|
|
41
|
-
def initialize
|
42
|
-
@
|
43
|
-
|
44
|
-
@
|
45
|
-
@
|
46
|
-
|
47
|
-
@
|
48
|
-
@
|
49
|
-
|
50
|
-
|
51
|
-
@
|
44
|
+
def initialize(source)
|
45
|
+
@source = source
|
46
|
+
|
47
|
+
@name = source[:name] # || fail
|
48
|
+
@version = source[:version] # || fail
|
49
|
+
|
50
|
+
@dependencies = source[:dependencies] || []
|
51
|
+
@iteration = source[:iteration] || 1
|
52
|
+
@url = source[:url] || "http://nourlgiven.example.com/no/url/given"
|
53
|
+
@category = source[:category] || "default"
|
54
|
+
@license = source[:license] || "unknown"
|
55
|
+
@maintainer = source[:maintainer] || "<#{ENV["USER"]}@#{Socket.gethostname}>"
|
56
|
+
@architecture = source[:architecture] || %x{uname -m}.chomp
|
57
|
+
@summary = source[:summary] || "no summary given"
|
58
|
+
end
|
59
|
+
|
60
|
+
def generate_specfile(builddir, paths)
|
61
|
+
spec = template.result(binding)
|
62
|
+
File.open(specfile(builddir), "w") { |f| f.puts spec }
|
63
|
+
end
|
64
|
+
|
65
|
+
def generate_md5sums(builddir, paths)
|
66
|
+
md5sums = self.checksum(paths)
|
67
|
+
File.open("#{builddir}/md5sums", "w") { |f| f.puts md5sums }
|
68
|
+
md5sums
|
69
|
+
end
|
70
|
+
|
71
|
+
# TODO [Jay]: make this better...?
|
72
|
+
def type
|
73
|
+
self.class.name.split(':').last.downcase
|
52
74
|
end
|
53
75
|
|
54
|
-
def
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
end # paths.each
|
62
|
-
dirs = dirs.sort { |a,b| a.length <=> b.length}
|
63
|
-
system(*["tar", "--owner=root", "--group=root", "-cf", output, "--no-recursion", *dirs])
|
64
|
-
system(*["tar", "--owner=root", "--group=root", "-rf", output, *paths])
|
76
|
+
def template
|
77
|
+
@template ||= begin
|
78
|
+
tpl = File.read(
|
79
|
+
"#{FPM::DIRS[:templates]}/#{type}.erb"
|
80
|
+
)
|
81
|
+
ERB.new(tpl, nil, "<>")
|
82
|
+
end
|
65
83
|
end
|
66
84
|
|
85
|
+
def render_spec
|
86
|
+
template.result(binding)
|
87
|
+
end
|
88
|
+
|
89
|
+
def default_output
|
90
|
+
"#{name}-#{version}-#{iteration}.#{architecture}.#{type}"
|
91
|
+
end
|
67
92
|
end
|
data/lib/fpm/source.rb
ADDED
@@ -0,0 +1,88 @@
|
|
1
|
+
require "fpm/namespace"
|
2
|
+
|
3
|
+
# Abstract class for a "thing to build a package from"
|
4
|
+
class FPM::Source
|
5
|
+
# standard package metadata
|
6
|
+
%w(
|
7
|
+
name
|
8
|
+
version
|
9
|
+
iteration
|
10
|
+
architecture
|
11
|
+
maintainer
|
12
|
+
category
|
13
|
+
url
|
14
|
+
summary
|
15
|
+
).each do |attr|
|
16
|
+
attr = :"#{attr}"
|
17
|
+
define_method(attr) { self[attr] }
|
18
|
+
define_method(:"#{attr}=") { |v| self[attr] = v}
|
19
|
+
end
|
20
|
+
|
21
|
+
def dependencies
|
22
|
+
self[:dependencies] ||= []
|
23
|
+
end
|
24
|
+
|
25
|
+
attr_reader :paths
|
26
|
+
attr_reader :root
|
27
|
+
def initialize(paths, root, params={})
|
28
|
+
@paths = paths
|
29
|
+
@root = root
|
30
|
+
|
31
|
+
get_source
|
32
|
+
get_metadata
|
33
|
+
|
34
|
+
# override the inferred data with the passed-in data
|
35
|
+
params.each do |k,v|
|
36
|
+
self[k] = v if v != nil
|
37
|
+
end
|
38
|
+
end # def initialize
|
39
|
+
|
40
|
+
# this method should take the paths and root and infer as much
|
41
|
+
# about the package as it can.
|
42
|
+
def get_metadata
|
43
|
+
raise NoMethodError,
|
44
|
+
"Please subclass FPM::Source and define get_metadata"
|
45
|
+
end # def get_metadata
|
46
|
+
|
47
|
+
# This method should be overridden by package sources that need to do any
|
48
|
+
# kind of fetching.
|
49
|
+
def get_source
|
50
|
+
# noop by default
|
51
|
+
end # def get_source
|
52
|
+
def make_tarball!(tar_path)
|
53
|
+
raise NoMethodError,
|
54
|
+
"Please subclass FPM::Source and define make_tarball!(tar_path)"
|
55
|
+
end
|
56
|
+
|
57
|
+
def metadata
|
58
|
+
@metadata ||= {}
|
59
|
+
end
|
60
|
+
|
61
|
+
def [](key)
|
62
|
+
metadata[key.to_sym]
|
63
|
+
end
|
64
|
+
|
65
|
+
def []=(key,val)
|
66
|
+
metadata[key.to_sym] = val
|
67
|
+
end
|
68
|
+
|
69
|
+
# MySourceClass.new('/tmp/build').package(FPM::Deb).assemble(params)
|
70
|
+
def package(pkg_cls)
|
71
|
+
pkg_cls.new(self)
|
72
|
+
end
|
73
|
+
|
74
|
+
private
|
75
|
+
def tar(output, paths, chdir=".")
|
76
|
+
dirs = []
|
77
|
+
paths.each do |path|
|
78
|
+
while path != "/" and path != "."
|
79
|
+
dirs << path if !dirs.include?(path)
|
80
|
+
path = File.dirname(path)
|
81
|
+
end
|
82
|
+
end # paths.each
|
83
|
+
system(*["tar", "-C", chdir, "--owner=root", "--group=root",
|
84
|
+
"-cf", output, "--no-recursion", *dirs]) if dirs.any?
|
85
|
+
system(*["tar", "-C", chdir,
|
86
|
+
"--owner=root", "--group=root", "-rf", output, *paths])
|
87
|
+
end # def tar
|
88
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require "fpm/source"
|
2
|
+
|
3
|
+
class FPM::Source::Dir < FPM::Source
|
4
|
+
def get_metadata
|
5
|
+
self[:name] = File.basename(File.expand_path(root))
|
6
|
+
end
|
7
|
+
|
8
|
+
def make_tarball!(tar_path)
|
9
|
+
tar(tar_path, paths)
|
10
|
+
|
11
|
+
# TODO(sissel): Make a helper method.
|
12
|
+
system(*["gzip", "-f", tar_path])
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,86 @@
|
|
1
|
+
require "fpm/namespace"
|
2
|
+
require "fpm/source"
|
3
|
+
require "rubygems/package"
|
4
|
+
require "rubygems"
|
5
|
+
require "fileutils"
|
6
|
+
|
7
|
+
class FPM::Source::Gem < FPM::Source
|
8
|
+
def get_source
|
9
|
+
gem = @paths.first
|
10
|
+
looks_like_name_re = /^[A-Za-z0-9_-]+$/
|
11
|
+
if !File.exists?(gem)
|
12
|
+
if gem =~ looks_like_name_re
|
13
|
+
# TODO(sissel): Use the Gem API
|
14
|
+
download(gem)
|
15
|
+
else
|
16
|
+
raise "Path '#{gem}' is not a file and does not appear to be the name of a rubygem."
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end # def get_source
|
20
|
+
|
21
|
+
def download(gem_name, version=nil)
|
22
|
+
# This code mostly mutated from rubygem's fetch_command.rb
|
23
|
+
# Code use permissible by rubygems's "GPL or these conditions below"
|
24
|
+
# http://rubygems.rubyforge.org/rubygems-update/LICENSE_txt.html
|
25
|
+
|
26
|
+
puts "Trying to download #{gem_name} (version=#{version})"
|
27
|
+
dep = ::Gem::Dependency.new gem_name, version
|
28
|
+
# How to handle prerelease? Some extra magic options?
|
29
|
+
#dep.prerelease = options[:prerelease]
|
30
|
+
|
31
|
+
specs_and_sources, errors =
|
32
|
+
::Gem::SpecFetcher.fetcher.fetch_with_errors(dep, false, true, false)
|
33
|
+
spec, source_uri = specs_and_sources.sort_by { |s,| s.version }.last
|
34
|
+
|
35
|
+
if spec.nil? then
|
36
|
+
raise "Invalid gem? Name: #{gem_name}, Version: #{version}, Errors: #{errors}"
|
37
|
+
end
|
38
|
+
|
39
|
+
path = ::Gem::RemoteFetcher.fetcher.download spec, source_uri
|
40
|
+
FileUtils.mv path, spec.file_name
|
41
|
+
@paths = [spec.file_name]
|
42
|
+
end
|
43
|
+
|
44
|
+
def get_metadata
|
45
|
+
File.open(@paths.first, 'r') do |f|
|
46
|
+
::Gem::Package.open(f, 'r') do |gem|
|
47
|
+
spec = gem.metadata
|
48
|
+
%w(
|
49
|
+
description
|
50
|
+
license
|
51
|
+
summary
|
52
|
+
version
|
53
|
+
).each do |field|
|
54
|
+
self[field] = spec.send(field)
|
55
|
+
end
|
56
|
+
|
57
|
+
self[:name] = "rubygem-#{spec.name}"
|
58
|
+
self[:maintainer] = spec.author
|
59
|
+
self[:url] = spec.homepage
|
60
|
+
|
61
|
+
# TODO [Jay]: this will be different for different
|
62
|
+
# package managers. Need to decide how to handle this.
|
63
|
+
self[:category] = 'Languages/Development/Ruby'
|
64
|
+
|
65
|
+
self[:dependencies] = spec.runtime_dependencies.map do |dep|
|
66
|
+
reqs = dep.requirement.to_s.gsub(/,/, '')
|
67
|
+
"rubygem-#{dep.name} #{reqs}"
|
68
|
+
end
|
69
|
+
end # ::Gem::Package
|
70
|
+
end # File.open (the gem)
|
71
|
+
end # def get_metadata
|
72
|
+
|
73
|
+
def make_tarball!(tar_path)
|
74
|
+
tmpdir = "#{tar_path}.dir"
|
75
|
+
installdir = "#{tmpdir}/#{::Gem::dir}"
|
76
|
+
::FileUtils.mkdir_p(installdir)
|
77
|
+
args = ["gem", "install", "--quiet", "--no-ri", "--no-rdoc",
|
78
|
+
"--install-dir", installdir, @paths.first]
|
79
|
+
system(*args)
|
80
|
+
tar(tar_path, ".", tmpdir)
|
81
|
+
|
82
|
+
# TODO(sissel): Make a helper method.
|
83
|
+
system(*["gzip", "-f", tar_path])
|
84
|
+
end
|
85
|
+
|
86
|
+
end # class FPM::Source::Gem
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require "fpm/source"
|
2
|
+
|
3
|
+
class FPM::Source::RPM < FPM::Source
|
4
|
+
def get_metadata
|
5
|
+
self[:name] = %x{rpm -q --qf '%{name}' -p #{@paths.first}}
|
6
|
+
|
7
|
+
self[:version] = %x{rpm -q --qf '%{version}' -p #{@paths.first}}
|
8
|
+
self[:iteration] = %x{rpm -q --qf '%{release}' -p #{@paths.first}}
|
9
|
+
self[:summary] = %x{rpm -q --qf '%{summary}' -p #{@paths.first}}
|
10
|
+
#self[:description] = %x{rpm -q --qf '%{description}' -p #{@paths.first}}
|
11
|
+
self[:dependencies] = %x{rpm -qRp #{@paths.first}}.split("\n")\
|
12
|
+
.collect { |line| line.strip }
|
13
|
+
|
14
|
+
@rpm = @paths.first
|
15
|
+
@paths = %x{rpm -qlp #{@paths.first}}.split("\n")
|
16
|
+
|
17
|
+
end
|
18
|
+
|
19
|
+
def make_tarball!(tar_path)
|
20
|
+
tmpdir = "#{tar_path}.dir"
|
21
|
+
::Dir.mkdir(tmpdir)
|
22
|
+
system("rpm2cpio #{@rpm} | (cd #{tmpdir}; cpio -i --make-directories)")
|
23
|
+
tar(tar_path, ".", tmpdir)
|
24
|
+
|
25
|
+
# TODO(sissel): Make a helper method.
|
26
|
+
system(*["gzip", "-f", tar_path])
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require "erb"
|
2
|
+
require "fpm/namespace"
|
3
|
+
require "fpm/package"
|
4
|
+
|
5
|
+
class FPM::Target::Deb < FPM::Package
|
6
|
+
# Debian calls x86_64 "amd64"
|
7
|
+
def architecture
|
8
|
+
if @architecture == "x86_64"
|
9
|
+
"amd64"
|
10
|
+
else
|
11
|
+
@architecture
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def specfile(builddir)
|
16
|
+
"#{builddir}/control"
|
17
|
+
end
|
18
|
+
|
19
|
+
def build!(params)
|
20
|
+
# Make the control
|
21
|
+
system("tar -zcf control.tar.gz control md5sums")
|
22
|
+
|
23
|
+
# create debian-binary
|
24
|
+
File.open("debian-binary", "w") { |f| f.puts "2.0" }
|
25
|
+
|
26
|
+
# pack up the .deb
|
27
|
+
system("ar -qc #{params[:output]} debian-binary control.tar.gz data.tar.gz")
|
28
|
+
|
29
|
+
end # def build
|
30
|
+
end # class FPM::Deb
|
31
|
+
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require "fpm/package"
|
2
|
+
|
3
|
+
class FPM::Target::Rpm < FPM::Package
|
4
|
+
def specfile(builddir)
|
5
|
+
"#{builddir}/#{name}.spec"
|
6
|
+
end
|
7
|
+
|
8
|
+
def build!(params)
|
9
|
+
raise "No package name given. Can't assemble package" if !@name
|
10
|
+
Dir.mkdir("BUILD")
|
11
|
+
args = ["rpmbuild", "-ba",
|
12
|
+
"--define", "buildroot #{Dir.pwd}/BUILD",
|
13
|
+
"--define", "_topdir #{Dir.pwd}",
|
14
|
+
"--define", "_sourcedir #{Dir.pwd}",
|
15
|
+
"--define", "_rpmdir #{params[:output]}",
|
16
|
+
"#{name}.spec"]
|
17
|
+
system(*args)
|
18
|
+
end
|
19
|
+
end
|
data/templates/deb.erb
CHANGED
@@ -1,13 +1,13 @@
|
|
1
|
-
Package: <%=
|
2
|
-
Version: <%=
|
3
|
-
Architecture: <%=
|
4
|
-
Maintainer: <%=
|
5
|
-
<% if
|
6
|
-
Depends: <%=
|
1
|
+
Package: <%= name %>
|
2
|
+
Version: <%= version %>-<%= iteration %>
|
3
|
+
Architecture: <%= architecture %>
|
4
|
+
Maintainer: <%= maintainer or "<unknown>" %>
|
5
|
+
<% if dependencies.size > 0 %>
|
6
|
+
Depends: <%= dependencies.join(", ") %>
|
7
7
|
<% end %>
|
8
8
|
Standards-Version: 3.9.1
|
9
|
-
Section: <%=
|
9
|
+
Section: <%= category or "unknown" %>
|
10
10
|
Priority: extra
|
11
|
-
Homepage: <%=
|
12
|
-
Description: <%=
|
13
|
-
<%=
|
11
|
+
Homepage: <%= url or "http://nourlgiven.example.com/" %>
|
12
|
+
Description: <%= summary or "no summary given" %>
|
13
|
+
<%= summary or "no description given"%>
|
data/templates/rpm.erb
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
Name: <%= @name %>
|
2
|
+
Version: <%= @version %>
|
3
|
+
Release: <%= @iteration %>
|
4
|
+
Summary: <%= @summary %>
|
5
|
+
|
6
|
+
Group: <%= @category %>
|
7
|
+
<%#
|
8
|
+
TODO: [Jay] rpms require a license
|
9
|
+
let's detect it intelligently
|
10
|
+
%>
|
11
|
+
License: <%= @license %>
|
12
|
+
Source0: %{_sourcedir}/data.tar.gz
|
13
|
+
BuildRoot: %(mktemp -ud %{_tmppath}/%{name}-%{version}-%{release}-XXXXXX)
|
14
|
+
|
15
|
+
<% if @dependencies && !@dependencies.empty? %>
|
16
|
+
Requires: <%= @dependencies.join(", ") %>
|
17
|
+
<% end %>
|
18
|
+
|
19
|
+
%description
|
20
|
+
<%= @summary %>
|
21
|
+
|
22
|
+
%prep
|
23
|
+
echo "PREP"
|
24
|
+
pwd
|
25
|
+
tar -zvxf %SOURCE0
|
26
|
+
|
27
|
+
%build
|
28
|
+
#noop
|
29
|
+
|
30
|
+
%install
|
31
|
+
#noop
|
32
|
+
|
33
|
+
%clean
|
34
|
+
rm -rf $RPM_BUILD_ROOT
|
35
|
+
|
36
|
+
|
37
|
+
%files
|
38
|
+
%defattr(-,root,root,-)
|
39
|
+
<%= @source.paths.join("\n") %>
|
40
|
+
|
41
|
+
%changelog
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fpm
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 17
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 1
|
9
|
-
-
|
10
|
-
version: 0.1.
|
9
|
+
- 5
|
10
|
+
version: 0.1.5
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Jordan Sissel
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2011-01-
|
18
|
+
date: 2011-01-07 00:00:00 -08:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
@@ -42,12 +42,19 @@ extensions: []
|
|
42
42
|
extra_rdoc_files: []
|
43
43
|
|
44
44
|
files:
|
45
|
-
- lib/fpm/
|
45
|
+
- lib/fpm/builder.rb
|
46
46
|
- lib/fpm/namespace.rb
|
47
|
+
- lib/fpm/source.rb
|
48
|
+
- lib/fpm/source/dir.rb
|
49
|
+
- lib/fpm/source/rpm.rb
|
50
|
+
- lib/fpm/source/gem.rb
|
51
|
+
- lib/fpm/target/deb.rb
|
52
|
+
- lib/fpm/target/rpm.rb
|
47
53
|
- lib/fpm/package.rb
|
48
54
|
- lib/fpm.rb
|
49
55
|
- bin/fpm
|
50
56
|
- bin/fpm-npm
|
57
|
+
- templates/rpm.erb
|
51
58
|
- templates/deb.erb
|
52
59
|
has_rdoc: true
|
53
60
|
homepage: https://github.com/jordansissel/fpm
|
data/lib/fpm/deb.rb
DELETED
@@ -1,74 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
#
|
3
|
-
|
4
|
-
require "erb"
|
5
|
-
require "fpm/namespace"
|
6
|
-
require "fpm/package"
|
7
|
-
|
8
|
-
class FPM::Deb < FPM::Package
|
9
|
-
|
10
|
-
# Assemble the package.
|
11
|
-
# params:
|
12
|
-
# "root" => "/some/path" # the 'root' of your package directory
|
13
|
-
# "paths" => [ "/some/path" ...] # paths to icnlude in this package
|
14
|
-
# "output" => "foo.deb" # what to output to.
|
15
|
-
#
|
16
|
-
# The 'output' file path will have 'VERSION' and 'ARCH' replaced with
|
17
|
-
# the appropriate values if if you want the filename generated.
|
18
|
-
def assemble(params)
|
19
|
-
raise "No package name given. Can't assemble package" if !@name
|
20
|
-
|
21
|
-
root = params["root"]
|
22
|
-
paths = params["paths"]
|
23
|
-
output = params["output"]
|
24
|
-
type = "deb"
|
25
|
-
|
26
|
-
p self.inspect
|
27
|
-
|
28
|
-
# Debian calls x86_64 "amd64"
|
29
|
-
@architecture = "amd64" if @architecture == "x86_64"
|
30
|
-
|
31
|
-
output.gsub!(/VERSION/, "#{@version}-#{@iteration}")
|
32
|
-
output.gsub!(/ARCH/, @architecture)
|
33
|
-
|
34
|
-
builddir = "#{Dir.pwd}/build-#{type}-#{File.basename(output)}"
|
35
|
-
@garbage << builddir
|
36
|
-
|
37
|
-
Dir.mkdir(builddir) if !File.directory?(builddir)
|
38
|
-
|
39
|
-
Dir.chdir(root || ".") do
|
40
|
-
self.tar("#{builddir}/data.tar", paths)
|
41
|
-
# TODO(sissel): Make a helper method.
|
42
|
-
system(*["gzip", "-f", "#{builddir}/data.tar"])
|
43
|
-
|
44
|
-
# Generate md5sums
|
45
|
-
md5sums = self.checksum(paths)
|
46
|
-
File.open("#{builddir}/md5sums", "w") { |f| f.puts md5sums.join("\n") }
|
47
|
-
|
48
|
-
# Generate 'control' file
|
49
|
-
template = File.new("#{File.dirname(__FILE__)}/../../templates/deb.erb").read()
|
50
|
-
control = ERB.new(template, nil, "<>").result(binding)
|
51
|
-
File.open("#{builddir}/control", "w") { |f| f.puts control }
|
52
|
-
end
|
53
|
-
|
54
|
-
# create control.tar.gz
|
55
|
-
Dir.chdir(builddir) do
|
56
|
-
# Make the control
|
57
|
-
system("tar -zcf control.tar.gz control md5sums")
|
58
|
-
|
59
|
-
# create debian-binary
|
60
|
-
File.open("debian-binary", "w") { |f| f.puts "2.0" }
|
61
|
-
|
62
|
-
# pack up the .deb
|
63
|
-
system("ar -qc #{output} debian-binary control.tar.gz data.tar.gz")
|
64
|
-
end
|
65
|
-
end # def assemble
|
66
|
-
|
67
|
-
def checksum(paths)
|
68
|
-
md5sums = []
|
69
|
-
paths.each do |path|
|
70
|
-
md5sums += %x{find #{path} -type f -print0 | xargs -0 md5sum}.split("\n")
|
71
|
-
end
|
72
|
-
end # def checksum
|
73
|
-
end # class FPM::Deb
|
74
|
-
|