1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
|
require "erb"
require "fpm/namespace"
require "fpm/package"
require "fpm/errors"
require "fpm/util"
class FPM::Target::Deb < FPM::Package
# Supported Debian control files
CONTROL_FILES = {
"pre-install" => [:script, "preinst"],
"post-install" => [:script, "postinst"],
"pre-uninstall" => [:script, "prerm"],
"post-uninstall" => [:script, "postrm"],
"debconf-config" => [:script, "config"],
"debconf-templates" => [:text, "templates"]
}
def self.flags(opts, settings)
settings.target[:deb] = "deb"
opts.on("--ignore-iteration-in-dependencies",
"For = dependencies, allow iterations on the specified version. Default is to be specific.") do |x|
settings.target[:ignore_iteration] = true
end
opts.on("--pre-depends DEPENDENCY", "Add DEPENDENCY as Pre-Depends.") do |dep|
(settings.target[:pre_depends] ||= []) << dep
end
# Take care about the case when we want custom control file but still use fpm ...
opts.on("--custom-control FILEPATH",
"Custom version of the Debian control file.") do |control|
settings.target[:control] = File.expand_path(control)
end
# Add custom debconf config file
opts.on("--config SCRIPTPATH",
"Add SCRIPTPATH as debconf config file.") do |config|
settings.scripts["debconf-config"] = File.expand_path(config)
end
# Add custom debconf templates file
opts.on("--templates FILEPATH",
"Add FILEPATH as debconf templates file.") do |templates|
settings.scripts["debconf-templates"] = File.expand_path(templates)
end
end
def needs_md5sums
case %x{uname -s}.chomp
when "Darwin"
return false
else
return true
end
end # def needs_md5sums
def architecture
if @architecture.nil? or @architecture == "native"
# Default architecture should be 'native' which we'll need
# to ask the system about.
arch = %x{dpkg --print-architecture 2> /dev/null}.chomp
if $?.exitstatus != 0
arch = %x{uname -m}.chomp
@logger.warn("Can't find 'dpkg' tool (need it to get default " \
"architecture!). Please specificy --architecture " \
"specifically. (Defaulting now to #{arch})")
end
@architecture = arch
elsif @architecture == "x86_64"
# Debian calls x86_64 "amd64"
@architecture = "amd64"
end
return @architecture
end # def architecture
def specfile(builddir)
"#{builddir}/control"
end
def name
if @name =~ /[A-Z]/
@logger.warn("Debian tools (dpkg/apt) don't do well with packages " \
"that use capital letters in the name. In some cases it will " \
"automatically downcase them, in others it will not. It is confusing." \
"Best to not use any capital letters at all.")
@name = @name.downcase
end
if @name.include?("_")
@logger.info("Package name '#{@name}' includes underscores, converting" \
" to dashes")
@name = @name.gsub(/[_]/, "-")
end
return @name
end
def build!(params)
control_files = [ "control" ]
if File.exists? "./md5sums"
control_files << "md5sums"
end
# Use custom Debian control file when given ...
if self.settings[:control]
%x{cp #{self.settings[:control]} ./control 2> /dev/null 2>&1}
@logger.warn("Unable to process custom Debian control file (exit " \
"code: #{$?.exitstatus}). Falling back to default " \
"template.") unless $?.exitstatus == 0
end
# place the control files
self.scripts.each do |name, path|
ctrl_type, ctrl_file = CONTROL_FILES[name]
if ctrl_file
safesystem("cp", path, "./#{ctrl_file}")
safesystem("chmod", "a+x", "./#{ctrl_file}") if ctrl_type == :script
control_files << ctrl_file
else
raise "Unsupported script name '#{name}' (path: #{path})"
end
end # self.scripts.each
if self.config_files.any?
File.open('conffiles', 'w'){ |f| f.puts(config_files.join("\n")) }
control_files << 'conffiles'
end
# Make the control
safesystem(tar_cmd, "--numeric-owner", "--owner=0", "--group=0",
"-zcf", "control.tar.gz", *control_files)
# create debian-binary
File.open("debian-binary", "w") { |f| f.puts "2.0" }
# pack up the .deb
safesystem("ar", "-qc", "#{params[:output]}", "debian-binary", "control.tar.gz", "data.tar.gz")
end # def build
def default_output
if iteration
"#{name}_#{version}-#{iteration}_#{architecture}.#{type}"
else
"#{name}_#{version}_#{architecture}.#{type}"
end
end # def default_output
def fix_dependency(dep)
if dep =~ /[\(,\|]/
# Don't "fix" ones that could appear well formed already.
else
da = dep.split(/ +/)
if da.size > 1
# Convert strings 'foo >= bar' to 'foo (>= bar)'
dep = "#{da[0]} (#{da[1]} #{da[2]})"
end
end
name_re = /^[^ \(]+/
name = dep[name_re]
if name =~ /[A-Z]/
@logger.warn("Downcasing dependency '#{name}' because deb packages " \
" don't work so good with uppercase names")
dep.gsub!(name_re) { |n| n.downcase }
end
if dep =~ /_/
@logger.warn("Replacing underscores with dashes in '#{dep}' because " \
"debs don't like underscores")
dep.gsub!("_", "-")
end
# Convert gem ~> X.Y.Z to '>= X.Y.Z' and << X.Y+1.0
if dep =~ /\(~>/
name, version = dep.gsub(/[()~>]/, "").split(/ +/)[0..1]
nextversion = version.split(".").collect { |v| v.to_i }
l = nextversion.length
nextversion[l-2] += 1
nextversion[l-1] = 0
nextversion = nextversion.join(".")
return ["#{name} (>= #{version})", "#{name} (<< #{nextversion})"]
# ignore iterations for = dependencies if flag specified
elsif (m = dep.match(/(\S+)\s+\(= (.+)\)/)) && self.settings[:ignore_iteration]
name, version = m[1..2]
nextversion = version.split('.').collect { |v| v.to_i }
nextversion[-1] += 1
nextversion = nextversion.join(".")
return ["#{name} (>= #{version})", "#{name} (<< #{nextversion})"]
else
return dep
end
end # def fix_dependency
def pre_dependencies
self.settings[:pre_depends] || []
end # def pre_dependencies
end # class FPM::Target::Deb
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
|
|