fpm 0.3.11 → 0.4.0pre1
Sign up to get free protection for your applications and to get access to all the features.
- 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
data/lib/fpm/source/rpm.rb
DELETED
@@ -1,28 +0,0 @@
|
|
1
|
-
require "fpm/source"
|
2
|
-
require "fpm/util"
|
3
|
-
|
4
|
-
class FPM::Source::RPM < FPM::Source
|
5
|
-
def get_metadata
|
6
|
-
@rpm = @paths.first
|
7
|
-
self[:name] = %x{rpm -q --qf '%{name}' -p #{@rpm}}.chomp
|
8
|
-
|
9
|
-
self[:version] = %x{rpm -q --qf '%{version}' -p #{@rpm}}.chomp
|
10
|
-
self[:iteration] = %x{rpm -q --qf '%{release}' -p #{@rpm}}.chomp
|
11
|
-
self[:summary] = %x{rpm -q --qf '%{summary}' -p #{@rpm}}.chomp
|
12
|
-
#self[:description] = %x{rpm -q --qf '%{description}' -p #{@rpm}}
|
13
|
-
self[:dependencies] = %x{rpm -qRp #{@rpm}}.split("\n")\
|
14
|
-
.collect { |line| line.strip }
|
15
|
-
|
16
|
-
@paths = %x{rpm -qlp #{@rpm}}.split("\n")
|
17
|
-
end
|
18
|
-
|
19
|
-
def make_tarball!(tar_path, builddir)
|
20
|
-
tmpdir = "#{tar_path}.dir"
|
21
|
-
::Dir.mkdir(tmpdir)
|
22
|
-
safesystem("rpm2cpio #{@rpm} | (cd #{tmpdir}; cpio -i --make-directories)")
|
23
|
-
tar(tar_path, ".", tmpdir)
|
24
|
-
@paths = ["."]
|
25
|
-
# TODO(sissel): Make a helper method.
|
26
|
-
safesystem(*["gzip", "-f", tar_path])
|
27
|
-
end
|
28
|
-
end
|
data/lib/fpm/source/tar.rb
DELETED
@@ -1,50 +0,0 @@
|
|
1
|
-
require "fpm/rubyfixes"
|
2
|
-
require "fpm/source"
|
3
|
-
require "fpm/util"
|
4
|
-
require "fileutils"
|
5
|
-
|
6
|
-
class FPM::Source::Tar < FPM::Source
|
7
|
-
def get_metadata
|
8
|
-
self[:name] = @paths.first.split(".").first
|
9
|
-
end # def get_metadata
|
10
|
-
|
11
|
-
def make_tarball!(tar_path, builddir)
|
12
|
-
input_tarball = @paths.first
|
13
|
-
|
14
|
-
if input_tarball =~ /\.tar\.bz2$/
|
15
|
-
compression = :bipz2
|
16
|
-
elsif input_tarball =~ /\.tar\.gz$/
|
17
|
-
compression = :gzip
|
18
|
-
elsif input_tarball =~ /\.tar\.xz$/
|
19
|
-
compression = :lzma
|
20
|
-
else
|
21
|
-
compression = :none
|
22
|
-
end
|
23
|
-
|
24
|
-
# Unpack the tar file
|
25
|
-
installdir = "#{builddir}/tarbuild/#{self[:prefix]}"
|
26
|
-
FileUtils.mkdir_p(installdir)
|
27
|
-
flags = "-xf #{input_tarball} -C #{installdir}"
|
28
|
-
case compression
|
29
|
-
when :bzip2; flags += " -j"
|
30
|
-
when :gzip; flags += " -z"
|
31
|
-
when :lzma; flags += " --lzma"
|
32
|
-
end
|
33
|
-
#puts("tar #{flags}")
|
34
|
-
#sleep 5
|
35
|
-
safesystem("tar #{flags}")
|
36
|
-
|
37
|
-
if self[:prefix]
|
38
|
-
@paths = [self[:prefix]]
|
39
|
-
else
|
40
|
-
@paths = ["."]
|
41
|
-
end
|
42
|
-
|
43
|
-
::Dir.chdir("#{builddir}/tarbuild") do
|
44
|
-
tar(tar_path, ".")
|
45
|
-
end
|
46
|
-
|
47
|
-
# TODO(sissel): Make a helper method.
|
48
|
-
safesystem(*["gzip", "-f", tar_path])
|
49
|
-
end # def make_tarball!
|
50
|
-
end # class FPM::Source::Dir
|
data/lib/fpm/target/deb.rb
DELETED
@@ -1,184 +0,0 @@
|
|
1
|
-
require "erb"
|
2
|
-
require "fpm/namespace"
|
3
|
-
require "fpm/package"
|
4
|
-
require "fpm/errors"
|
5
|
-
require "fpm/util"
|
6
|
-
|
7
|
-
class FPM::Target::Deb < FPM::Package
|
8
|
-
|
9
|
-
def self.flags(opts, settings)
|
10
|
-
settings.target[:deb] = "deb"
|
11
|
-
|
12
|
-
opts.on("--ignore-iteration-in-dependencies",
|
13
|
-
"For = dependencies, allow iterations on the specified version. Default is to be specific.") do |x|
|
14
|
-
settings.target[:ignore_iteration] = true
|
15
|
-
end
|
16
|
-
|
17
|
-
opts.on("--pre-depends DEPENDENCY", "Add DEPENDENCY as Pre-Depends.") do |dep|
|
18
|
-
(settings.target[:pre_depends] ||= []) << dep
|
19
|
-
end
|
20
|
-
|
21
|
-
# Take care about the case when we want custom control file but still use fpm ...
|
22
|
-
opts.on("--custom-control FILEPATH",
|
23
|
-
"Custom version of the Debian control file.") do |control|
|
24
|
-
settings.target[:control] = File.expand_path(control)
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
|
-
def needs_md5sums
|
29
|
-
case %x{uname -s}.chomp
|
30
|
-
when "Darwin"
|
31
|
-
return false
|
32
|
-
else
|
33
|
-
return true
|
34
|
-
end
|
35
|
-
end # def needs_md5sums
|
36
|
-
|
37
|
-
def architecture
|
38
|
-
if @architecture.nil? or @architecture == "native"
|
39
|
-
# Default architecture should be 'native' which we'll need
|
40
|
-
# to ask the system about.
|
41
|
-
arch = %x{dpkg --print-architecture 2> /dev/null}.chomp
|
42
|
-
if $?.exitstatus != 0
|
43
|
-
arch = %x{uname -m}.chomp
|
44
|
-
@logger.warn("Can't find 'dpkg' tool (need it to get default " \
|
45
|
-
"architecture!). Please specificy --architecture " \
|
46
|
-
"specifically. (Defaulting now to #{arch})")
|
47
|
-
end
|
48
|
-
@architecture = arch
|
49
|
-
elsif @architecture == "x86_64"
|
50
|
-
# Debian calls x86_64 "amd64"
|
51
|
-
@architecture = "amd64"
|
52
|
-
end
|
53
|
-
|
54
|
-
return @architecture
|
55
|
-
end # def architecture
|
56
|
-
|
57
|
-
def specfile(builddir)
|
58
|
-
"#{builddir}/control"
|
59
|
-
end
|
60
|
-
|
61
|
-
def name
|
62
|
-
if @name =~ /[A-Z]/
|
63
|
-
@logger.warn("Debian tools (dpkg/apt) don't do well with packages " \
|
64
|
-
"that use capital letters in the name. In some cases it will " \
|
65
|
-
"automatically downcase them, in others it will not. It is confusing." \
|
66
|
-
"Best to not use any capital letters at all.")
|
67
|
-
@name = @name.downcase
|
68
|
-
end
|
69
|
-
|
70
|
-
if @name.include?("_")
|
71
|
-
@logger.info("Package name '#{@name}' includes underscores, converting" \
|
72
|
-
" to dashes")
|
73
|
-
@name = @name.gsub(/[_]/, "-")
|
74
|
-
end
|
75
|
-
|
76
|
-
return @name
|
77
|
-
end
|
78
|
-
|
79
|
-
def build!(params)
|
80
|
-
control_files = [ "control" ]
|
81
|
-
if File.exists? "./md5sums"
|
82
|
-
control_files << "md5sums"
|
83
|
-
end
|
84
|
-
|
85
|
-
# Use custom Debian control file when given ...
|
86
|
-
if self.settings[:control]
|
87
|
-
%x{cp #{self.settings[:control]} ./control 2> /dev/null 2>&1}
|
88
|
-
@logger.warn("Unable to process custom Debian control file (exit " \
|
89
|
-
"code: #{$?.exitstatus}). Falling back to default " \
|
90
|
-
"template.") unless $?.exitstatus == 0
|
91
|
-
end
|
92
|
-
|
93
|
-
# place the postinst prerm files
|
94
|
-
self.scripts.each do |name, path|
|
95
|
-
case name
|
96
|
-
when "pre-install"
|
97
|
-
safesystem("cp #{path} ./preinst")
|
98
|
-
control_files << "preinst"
|
99
|
-
when "post-install"
|
100
|
-
safesystem("cp #{path} ./postinst")
|
101
|
-
control_files << "postinst"
|
102
|
-
when "pre-uninstall"
|
103
|
-
safesystem("cp #{path} ./prerm")
|
104
|
-
control_files << "prerm"
|
105
|
-
when "post-uninstall"
|
106
|
-
safesystem("cp #{path} ./postrm")
|
107
|
-
control_files << "postrm"
|
108
|
-
else raise "Unsupported script name '#{name}' (path: #{path})"
|
109
|
-
end # case name
|
110
|
-
end # self.scripts.each
|
111
|
-
|
112
|
-
if self.config_files.any?
|
113
|
-
File.open('conffiles', 'w'){ |f| f.puts(config_files.join("\n")) }
|
114
|
-
control_files << 'conffiles'
|
115
|
-
end
|
116
|
-
|
117
|
-
# Make the control
|
118
|
-
safesystem("tar -zcf control.tar.gz #{control_files.map{ |f| "./#{f}" }.join(" ")}")
|
119
|
-
|
120
|
-
# create debian-binary
|
121
|
-
File.open("debian-binary", "w") { |f| f.puts "2.0" }
|
122
|
-
|
123
|
-
# pack up the .deb
|
124
|
-
safesystem("ar -qc #{params[:output]} debian-binary control.tar.gz data.tar.gz")
|
125
|
-
end # def build
|
126
|
-
|
127
|
-
def default_output
|
128
|
-
if iteration
|
129
|
-
"#{name}_#{version}-#{iteration}_#{architecture}.#{type}"
|
130
|
-
else
|
131
|
-
"#{name}_#{version}_#{architecture}.#{type}"
|
132
|
-
end
|
133
|
-
end # def default_output
|
134
|
-
|
135
|
-
def fix_dependency(dep)
|
136
|
-
if dep =~ /[\(,\|]/
|
137
|
-
# Don't "fix" ones that could appear well formed already.
|
138
|
-
else
|
139
|
-
da = dep.split(/ +/)
|
140
|
-
if da.size > 1
|
141
|
-
# Convert strings 'foo >= bar' to 'foo (>= bar)'
|
142
|
-
dep = "#{da[0]} (#{da[1]} #{da[2]})"
|
143
|
-
end
|
144
|
-
end
|
145
|
-
|
146
|
-
name_re = /^[^ \(]+/
|
147
|
-
name = dep[name_re]
|
148
|
-
if name =~ /[A-Z]/
|
149
|
-
@logger.warn("Downcasing dependency '#{name}' because deb packages " \
|
150
|
-
" don't work so good with uppercase names")
|
151
|
-
dep.gsub!(name_re) { |n| n.downcase }
|
152
|
-
end
|
153
|
-
|
154
|
-
if dep =~ /_/
|
155
|
-
@logger.warn("Replacing underscores with dashes in '#{dep}' because " \
|
156
|
-
"debs don't like underscores")
|
157
|
-
dep.gsub!("_", "-")
|
158
|
-
end
|
159
|
-
|
160
|
-
# Convert gem ~> X.Y.Z to '>= X.Y.Z' and << X.Y+1.0
|
161
|
-
if dep =~ /\(~>/
|
162
|
-
name, version = dep.gsub(/[()~>]/, "").split(/ +/)[0..1]
|
163
|
-
nextversion = version.split(".").collect { |v| v.to_i }
|
164
|
-
l = nextversion.length
|
165
|
-
nextversion[l-2] += 1
|
166
|
-
nextversion[l-1] = 0
|
167
|
-
nextversion = nextversion.join(".")
|
168
|
-
return ["#{name} (>= #{version})", "#{name} (<< #{nextversion})"]
|
169
|
-
# ignore iterations for = dependencies if flag specified
|
170
|
-
elsif (m = dep.match(/(\S+)\s+\(= (.+)\)/)) && self.settings[:ignore_iteration]
|
171
|
-
name, version = m[1..2]
|
172
|
-
nextversion = version.split('.').collect { |v| v.to_i }
|
173
|
-
nextversion[-1] += 1
|
174
|
-
nextversion = nextversion.join(".")
|
175
|
-
return ["#{name} (>= #{version})", "#{name} (<< #{nextversion})"]
|
176
|
-
else
|
177
|
-
return dep
|
178
|
-
end
|
179
|
-
end # def fix_dependency
|
180
|
-
|
181
|
-
def pre_dependencies
|
182
|
-
self.settings[:pre_depends] || []
|
183
|
-
end # def pre_dependencies
|
184
|
-
end # class FPM::Target::Deb
|
data/lib/fpm/target/rpm.rb
DELETED
@@ -1,68 +0,0 @@
|
|
1
|
-
require "fpm/package"
|
2
|
-
require "fpm/util"
|
3
|
-
|
4
|
-
class FPM::Target::Rpm < FPM::Package
|
5
|
-
def architecture
|
6
|
-
case @architecture
|
7
|
-
when nil
|
8
|
-
return %x{uname -m}.chomp # default to current arch
|
9
|
-
when "native"
|
10
|
-
return %x{uname -m}.chomp # 'native' is current arch
|
11
|
-
when "all"
|
12
|
-
# Translate fpm "all" arch to what it means in RPM.
|
13
|
-
return "noarch"
|
14
|
-
else
|
15
|
-
return @architecture
|
16
|
-
end
|
17
|
-
end # def architecture
|
18
|
-
|
19
|
-
def specfile(builddir)
|
20
|
-
"#{builddir}/#{name}.spec"
|
21
|
-
end
|
22
|
-
|
23
|
-
def url
|
24
|
-
if @url.nil? || @url.empty?
|
25
|
-
'http://nourlgiven.example.com'
|
26
|
-
else
|
27
|
-
@url
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
|
-
def iteration
|
32
|
-
if @iteration.nil? || @iteration.empty?
|
33
|
-
# Default iteration value of 1 makes sense.
|
34
|
-
return '1'
|
35
|
-
else
|
36
|
-
return @iteration
|
37
|
-
end
|
38
|
-
end # def iteration
|
39
|
-
|
40
|
-
def version
|
41
|
-
if @version.kind_of?(String) and @version.include?("-")
|
42
|
-
@logger.info("Package version '#{@version}' includes dashes, converting" \
|
43
|
-
" to underscores")
|
44
|
-
@version = @version.gsub(/-/, "_")
|
45
|
-
end
|
46
|
-
|
47
|
-
return @version
|
48
|
-
end
|
49
|
-
|
50
|
-
def build!(params)
|
51
|
-
raise "No package name given. Can't assemble package" if !@name
|
52
|
-
# TODO(sissel): Abort if 'rpmbuild' tool not found.
|
53
|
-
|
54
|
-
%w(BUILD RPMS SRPMS SOURCES SPECS).each { |d| Dir.mkdir(d) }
|
55
|
-
args = ["rpmbuild", "-ba",
|
56
|
-
"--define", "buildroot #{Dir.pwd}/BUILD",
|
57
|
-
"--define", "_topdir #{Dir.pwd}",
|
58
|
-
"--define", "_sourcedir #{Dir.pwd}",
|
59
|
-
"--define", "_rpmdir #{Dir.pwd}/RPMS",
|
60
|
-
"#{name}.spec"]
|
61
|
-
safesystem(*args)
|
62
|
-
|
63
|
-
Dir["#{Dir.pwd}/RPMS/**/*.rpm"].each do |path|
|
64
|
-
# This should only output one rpm, should we verify this?
|
65
|
-
safesystem("mv", path, params[:output])
|
66
|
-
end
|
67
|
-
end # def build!
|
68
|
-
end # class FPM::Target::RPM
|
data/lib/rpm/header.rb
DELETED
@@ -1,89 +0,0 @@
|
|
1
|
-
require File.join(File.dirname(__FILE__), "namespace")
|
2
|
-
require File.join(File.dirname(__FILE__), "tag")
|
3
|
-
|
4
|
-
class RPMFile::Header
|
5
|
-
attr_reader :tags
|
6
|
-
attr_reader :length
|
7
|
-
|
8
|
-
attr_accessor :magic # 8-byte string magic
|
9
|
-
attr_accessor :index_count # rpmlib calls this field 'il' unhelpfully
|
10
|
-
attr_accessor :data_length # rpmlib calls this field 'dl' unhelpfully
|
11
|
-
|
12
|
-
HEADER_SIGNED_TYPE = 5
|
13
|
-
HEADER_MAGIC = "\x8e\xad\xe8\x01\x00\x00\x00\x00"
|
14
|
-
|
15
|
-
def initialize(rpm)
|
16
|
-
@rpm = rpm
|
17
|
-
@tags = []
|
18
|
-
end
|
19
|
-
|
20
|
-
def read
|
21
|
-
# TODO(sissel): update the comments here to reflect learnings about rpm
|
22
|
-
# internals
|
23
|
-
# At this point assume we've read and consumed the lead and signature.
|
24
|
-
#len = @rpm.signature.index_length + @rpm.signature
|
25
|
-
#
|
26
|
-
# header size is
|
27
|
-
# ( @rpm.signature.index_length * size of a header entry )
|
28
|
-
# + @rpm.signature.data_length
|
29
|
-
#
|
30
|
-
# header 'entries' are an
|
31
|
-
# int32 (tag id), int32 (tag type), int32 (offset), uint32 (count)
|
32
|
-
#
|
33
|
-
# See rpm's header.c, the headerLoad method function for reference.
|
34
|
-
|
35
|
-
# Header always starts with HEADER_MAGIC + index_count(2bytes) +
|
36
|
-
# data_length(2bytes)
|
37
|
-
data = @rpm.file.read(16).unpack("a8NN")
|
38
|
-
# TODO(sissel): @index_count is really a count, rename?
|
39
|
-
@magic, @index_count, @data_length = data
|
40
|
-
validate
|
41
|
-
|
42
|
-
entry_size = 16 # tag id, type, offset, count == 16 bytes
|
43
|
-
@index_size = @index_count * entry_size
|
44
|
-
tag_data = @rpm.file.read(@index_size)
|
45
|
-
data = @rpm.file.read(@data_length)
|
46
|
-
|
47
|
-
#ap :data => data
|
48
|
-
|
49
|
-
(0 ... @index_count).each do |i|
|
50
|
-
offset = i * entry_size
|
51
|
-
entry_data = tag_data[i * entry_size, entry_size]
|
52
|
-
entry = entry_data.unpack("NNNN")
|
53
|
-
entry << data
|
54
|
-
tag = ::RPMFile::Tag.new(*entry)
|
55
|
-
@tags << tag
|
56
|
-
|
57
|
-
#ap tag.tag => {
|
58
|
-
#:type => tag.type,
|
59
|
-
#:offset => tag.offset,
|
60
|
-
#:count => tag.count,
|
61
|
-
#:value => (tag.value rescue "???"),
|
62
|
-
#}
|
63
|
-
end # each index
|
64
|
-
@length = @magic.size + @index_size + @data_length
|
65
|
-
end # def read
|
66
|
-
|
67
|
-
def write
|
68
|
-
raise "not implemented yet"
|
69
|
-
# Sort tags by type (integer value)
|
70
|
-
# emit all tags in order
|
71
|
-
# then emit all data segments in same order
|
72
|
-
end # def write
|
73
|
-
|
74
|
-
def validate
|
75
|
-
# TODO(sissel): raise real exceptions
|
76
|
-
if @magic != ::RPMFile::Header::HEADER_MAGIC
|
77
|
-
raise "Header magic did not match; got #{@magic.inspect}, " \
|
78
|
-
"expected #{::RPMFile::Header::HEADER_MAGIC.inspect}"
|
79
|
-
end
|
80
|
-
|
81
|
-
#if !(0..32).include?(@index_count)
|
82
|
-
#raise "Invalid 'index_count' value #{@index_count}, expected to be in range [0..32]"
|
83
|
-
#end
|
84
|
-
|
85
|
-
#if !(0..8192).include?(@data_length)
|
86
|
-
#raise "Invalid 'data_length' value #{@data_length}, expected to be in range [0..8192]"
|
87
|
-
#end
|
88
|
-
end # def validate
|
89
|
-
end # class RPMFile::Header
|
data/lib/rpm/lead.rb
DELETED
@@ -1,48 +0,0 @@
|
|
1
|
-
require File.join(File.dirname(__FILE__), "namespace")
|
2
|
-
|
3
|
-
class RPMFile::Lead
|
4
|
-
#struct rpmlead {
|
5
|
-
attr_accessor :magic #unsigned char magic[4];
|
6
|
-
attr_accessor :major #unsigned char major;
|
7
|
-
attr_accessor :minor #unsigned char minor;
|
8
|
-
attr_accessor :type #short type;
|
9
|
-
attr_accessor :archnum #short archnum;
|
10
|
-
attr_accessor :name #char name[66];
|
11
|
-
attr_accessor :osnum #short osnum;
|
12
|
-
attr_accessor :signature_type #short signature_type;
|
13
|
-
attr_accessor :reserved #char reserved[16];
|
14
|
-
#}
|
15
|
-
|
16
|
-
attr_accessor :length
|
17
|
-
|
18
|
-
def initialize(rpm)
|
19
|
-
@rpm = rpm
|
20
|
-
end
|
21
|
-
|
22
|
-
def type
|
23
|
-
case @type
|
24
|
-
when 0
|
25
|
-
return :binary
|
26
|
-
when 1
|
27
|
-
return :source
|
28
|
-
else
|
29
|
-
raise "Unknown package 'type' value #{@type}"
|
30
|
-
end
|
31
|
-
end # def type
|
32
|
-
|
33
|
-
def read
|
34
|
-
# Use 'A' here instead of 'a' to trim nulls.
|
35
|
-
@length = 96
|
36
|
-
data = @rpm.file.read(@length).unpack("A4CCnnA66nnA16")
|
37
|
-
@magic, @major, @minor, @type, @archnum, @name, \
|
38
|
-
@osnum, @signature_type, @reserved = data
|
39
|
-
|
40
|
-
return nil
|
41
|
-
end # def read
|
42
|
-
|
43
|
-
def write(file)
|
44
|
-
data = [ @magic, @major, @minor, @type, @archnum, @name, \
|
45
|
-
@osnum, @signature_type, @reserved ].pack("a4CCnna66nna16")
|
46
|
-
file.write(data)
|
47
|
-
end # def write
|
48
|
-
end # class RPMFile::Lead
|