fpm 0.1.0 → 0.1.1
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/bin/fpm +17 -98
- data/lib/fpm.rb +3 -0
- data/lib/fpm/deb.rb +74 -0
- data/lib/fpm/namespace.rb +1 -0
- data/lib/fpm/package.rb +66 -0
- data/templates/deb.erb +11 -0
- metadata +8 -3
data/bin/fpm
CHANGED
@@ -1,9 +1,11 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
#
|
3
3
|
|
4
|
+
require "rubygems"
|
4
5
|
require "optparse"
|
5
6
|
require "ostruct"
|
6
7
|
require "erb"
|
8
|
+
require "fpm"
|
7
9
|
|
8
10
|
def main(args)
|
9
11
|
settings = OpenStruct.new
|
@@ -11,6 +13,7 @@ def main(args)
|
|
11
13
|
opts = OptionParser.new do |opts|
|
12
14
|
opts.banner = "Usage: #{$0} [options]"
|
13
15
|
|
16
|
+
# TODO(sissel): Maybe this should be '-o OUTPUT' ?
|
14
17
|
opts.on("-p PACKAGEFILE", "--package PACKAGEFILE",
|
15
18
|
"The package file to manage") do |path|
|
16
19
|
if path =~ /^\//
|
@@ -50,109 +53,25 @@ def main(args)
|
|
50
53
|
|
51
54
|
opts.parse!(args)
|
52
55
|
|
53
|
-
# Actions:
|
54
|
-
# create package
|
55
|
-
#
|
56
|
-
# files: add, remove
|
57
|
-
# scripts: add, remove
|
58
|
-
# metadata: set, add, remove
|
59
|
-
|
60
56
|
if !settings.package_path
|
61
57
|
$stderr.puts "No package file given to manage. Give with -p PACKAGEFILE"
|
62
58
|
return 1
|
63
59
|
end
|
64
60
|
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
architecture = "amd64"
|
80
|
-
end
|
81
|
-
|
82
|
-
|
83
|
-
url = (settings.url or "http://example.com/")
|
84
|
-
dependencies = (settings.dependencies or [])
|
85
|
-
return binding
|
86
|
-
end
|
87
|
-
|
88
|
-
metadata = mkbinding.call
|
89
|
-
|
90
|
-
package_path = settings.package_path
|
91
|
-
package_path.gsub!(/VERSION/, eval('"#{version}-#{package_iteration}"', metadata))
|
92
|
-
package_path.gsub!(/ARCH/, eval("architecture", metadata))
|
93
|
-
|
94
|
-
|
95
|
-
if type != "deb"
|
96
|
-
$stderr.puts "Unsupported package type '#{type}'"
|
97
|
-
return 1
|
98
|
-
end
|
99
|
-
|
100
|
-
|
101
|
-
builddir = "#{Dir.pwd}/build-#{type}-#{File.basename(package_path)}"
|
102
|
-
Dir.mkdir(builddir) if !File.directory?(builddir)
|
103
|
-
template = File.new("#{File.dirname(__FILE__)}/../templates/#{type}.erb").read()
|
104
|
-
|
105
|
-
Dir.chdir(settings.chdir || ".") do
|
106
|
-
puts Dir.pwd
|
107
|
-
|
108
|
-
# Add directories first.
|
109
|
-
dirs = []
|
110
|
-
paths.each do |path|
|
111
|
-
while path != "/" and path != "."
|
112
|
-
if !dirs.include?(path) or File.symlink?(path)
|
113
|
-
dirs << path
|
114
|
-
else
|
115
|
-
#puts "Skipping: #{path}"
|
116
|
-
#puts !dirs.include?(path)
|
117
|
-
#puts !File.symlink?(path)
|
118
|
-
end
|
119
|
-
path = File.dirname(path)
|
120
|
-
end
|
121
|
-
end
|
122
|
-
dirs = dirs.sort { |a,b| a.length <=> b.length}
|
123
|
-
puts dirs.join("\n")
|
124
|
-
system(*["tar", "--owner=root", "--group=root", "-cf", "#{builddir}/data.tar", "--no-recursion", *dirs])
|
125
|
-
puts paths.join("\n")
|
126
|
-
#paths = paths.reject { |p| File.symlink?(p) }
|
127
|
-
system(*["tar", "--owner=root", "--group=root", "-rf", "#{builddir}/data.tar", *paths])
|
128
|
-
system(*["gzip", "-f", "#{builddir}/data.tar"])
|
129
|
-
|
130
|
-
# Generate md5sums
|
131
|
-
md5sums = []
|
132
|
-
paths.each do |path|
|
133
|
-
md5sums += %x{find #{path} -type f -print0 | xargs -0 md5sum}.split("\n")
|
134
|
-
end
|
135
|
-
File.open("#{builddir}/md5sums", "w") { |f| f.puts md5sums.join("\n") }
|
136
|
-
|
137
|
-
# Generate 'control' file
|
138
|
-
control = ERB.new(template).result(metadata)
|
139
|
-
File.open("#{builddir}/control", "w") { |f| f.puts control }
|
140
|
-
end
|
141
|
-
|
142
|
-
# create control.tar.gz
|
143
|
-
Dir.chdir(builddir) do
|
144
|
-
system("tar -zcf control.tar.gz control md5sums")
|
145
|
-
end
|
146
|
-
|
147
|
-
Dir.chdir(builddir) do
|
148
|
-
# create debian-binary
|
149
|
-
File.open("debian-binary", "w") { |f| f.puts "2.0" }
|
150
|
-
end
|
151
|
-
|
152
|
-
Dir.chdir(builddir) do
|
153
|
-
system("ar -qc #{package_path} debian-binary control.tar.gz data.tar.gz")
|
154
|
-
end
|
155
|
-
end
|
61
|
+
package = FPM::Deb.new
|
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 [])
|
67
|
+
|
68
|
+
p settings
|
69
|
+
package.assemble({
|
70
|
+
"output" => settings.package_path,
|
71
|
+
"root" => settings.chdir,
|
72
|
+
"paths" => args, # Remainder of args are paths.
|
73
|
+
})
|
74
|
+
end # def main
|
156
75
|
|
157
76
|
ret = main(ARGV)
|
158
77
|
exit(ret != nil ? ret : 0)
|
data/lib/fpm.rb
ADDED
data/lib/fpm/deb.rb
ADDED
@@ -0,0 +1,74 @@
|
|
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).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
|
+
|
@@ -0,0 +1 @@
|
|
1
|
+
module FPM; end
|
data/lib/fpm/package.rb
ADDED
@@ -0,0 +1,66 @@
|
|
1
|
+
require "fpm/namespace"
|
2
|
+
require "socket" # for Socket.gethostname
|
3
|
+
|
4
|
+
class FPM::Package
|
5
|
+
# The name of this package
|
6
|
+
attr_accessor :name
|
7
|
+
|
8
|
+
# The version of this package (the upstream version)
|
9
|
+
attr_accessor :version
|
10
|
+
|
11
|
+
# The iteration of this package.
|
12
|
+
# Debian calls this 'release' and is the last '-NUMBER' in the version
|
13
|
+
# RedHat has this as 'Release' in the .spec file
|
14
|
+
# FreeBSD calls this 'PORTREVISION'
|
15
|
+
# If left unpicked, it defaults to 1.
|
16
|
+
attr_accessor :iteration
|
17
|
+
|
18
|
+
# Who maintains this package? This could be the upstream author
|
19
|
+
# or the package maintainer. You pick.
|
20
|
+
attr_accessor :maintainer
|
21
|
+
|
22
|
+
# URL for this package.
|
23
|
+
# Could be the homepage. Could be the download url. You pick.
|
24
|
+
attr_accessor :url
|
25
|
+
|
26
|
+
# The category of this package.
|
27
|
+
# RedHat calls this 'Group'
|
28
|
+
# Debian calls this 'Section'
|
29
|
+
# FreeBSD would put this in /usr/ports/<category>/...
|
30
|
+
attr_accessor :category
|
31
|
+
|
32
|
+
# A identifier representing the license. Any string is fine.
|
33
|
+
attr_accessor :license
|
34
|
+
|
35
|
+
# What architecture is this package for?
|
36
|
+
attr_accessor :architecture
|
37
|
+
|
38
|
+
# Array of dependencies.
|
39
|
+
attr_accessor :dependencies
|
40
|
+
|
41
|
+
def initialize
|
42
|
+
@iteration = 1
|
43
|
+
@url = ""
|
44
|
+
@category = "default"
|
45
|
+
@license = "unknown"
|
46
|
+
@maintainer = "<#{ENV["USER"]}@#{Socket.gethostname}>"
|
47
|
+
@architecture = nil
|
48
|
+
|
49
|
+
# Garbage is stuff you may want to clean up.
|
50
|
+
@garbage = []
|
51
|
+
end
|
52
|
+
|
53
|
+
def tar(output, paths)
|
54
|
+
dirs = []
|
55
|
+
paths.each do |path|
|
56
|
+
while path != "/" and path != "."
|
57
|
+
dirs << path if !dirs.include?(path)
|
58
|
+
path = File.dirname(path)
|
59
|
+
end
|
60
|
+
end # paths.each
|
61
|
+
dirs = dirs.sort { |a,b| a.length <=> b.length}
|
62
|
+
system(*["tar", "--owner=root", "--group=root", "-cf", output, "--no-recursion", *dirs])
|
63
|
+
system(*["tar", "--owner=root", "--group=root", "-rf", output, *paths])
|
64
|
+
end
|
65
|
+
|
66
|
+
end
|
data/templates/deb.erb
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
Package: <%= @name %>
|
2
|
+
Version: <%= @version %>-<%= @iteration %>
|
3
|
+
Architecture: <%= @architecture %>
|
4
|
+
Maintainer: <%= @maintainer %>
|
5
|
+
Depends: <%= @dependencies.join(", ") %>
|
6
|
+
Section: <%= @category %>
|
7
|
+
Priority: extra
|
8
|
+
Homepage: <%= @url %>
|
9
|
+
Description: <%= @summary %>
|
10
|
+
<%= @summary %>
|
11
|
+
|
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: 25
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 1
|
9
|
-
-
|
10
|
-
version: 0.1.
|
9
|
+
- 1
|
10
|
+
version: 0.1.1
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Jordan Sissel
|
@@ -41,7 +41,12 @@ extensions: []
|
|
41
41
|
extra_rdoc_files: []
|
42
42
|
|
43
43
|
files:
|
44
|
+
- lib/fpm/deb.rb
|
45
|
+
- lib/fpm/namespace.rb
|
46
|
+
- lib/fpm/package.rb
|
47
|
+
- lib/fpm.rb
|
44
48
|
- bin/fpm
|
49
|
+
- templates/deb.erb
|
45
50
|
has_rdoc: true
|
46
51
|
homepage: https://github.com/jordansissel/fpm
|
47
52
|
licenses: []
|