fpm 0.3.11 → 0.4.0pre1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (43) hide show
  1. data/CHANGELIST +15 -0
  2. data/bin/fpm +2 -15
  3. data/lib/fpm.rb +5 -12
  4. data/lib/fpm/command.rb +323 -0
  5. data/lib/fpm/errors.rb +1 -0
  6. data/lib/fpm/namespace.rb +2 -11
  7. data/lib/fpm/package.rb +255 -100
  8. data/lib/fpm/package/deb.rb +367 -0
  9. data/lib/fpm/package/dir.rb +86 -0
  10. data/lib/fpm/package/gem.rb +162 -0
  11. data/lib/fpm/{source → package}/npm.rb +3 -3
  12. data/lib/fpm/package/pear.rb +41 -0
  13. data/lib/fpm/{target → package}/puppet.rb +1 -3
  14. data/lib/fpm/{source → package}/pyfpm/__init__.py +0 -0
  15. data/lib/fpm/package/pyfpm/__init__.pyc +0 -0
  16. data/lib/fpm/{source → package}/pyfpm/get_metadata.py +15 -3
  17. data/lib/fpm/package/pyfpm/get_metadata.pyc +0 -0
  18. data/lib/fpm/package/python.rb +125 -0
  19. data/lib/fpm/package/rpm.rb +132 -0
  20. data/lib/fpm/{target → package}/solaris.rb +3 -2
  21. data/lib/fpm/package/tar.rb +62 -0
  22. data/lib/fpm/util.rb +56 -7
  23. data/templates/deb.erb +12 -12
  24. data/templates/rpm.erb +32 -38
  25. data/templates/solaris.erb +1 -1
  26. metadata +119 -78
  27. data/lib/fpm/builder.rb +0 -220
  28. data/lib/fpm/flags.rb +0 -20
  29. data/lib/fpm/program.rb +0 -273
  30. data/lib/fpm/rubyfixes.rb +0 -11
  31. data/lib/fpm/source.rb +0 -155
  32. data/lib/fpm/source/dir.rb +0 -59
  33. data/lib/fpm/source/gem.rb +0 -162
  34. data/lib/fpm/source/python.rb +0 -137
  35. data/lib/fpm/source/rpm.rb +0 -28
  36. data/lib/fpm/source/tar.rb +0 -50
  37. data/lib/fpm/target/deb.rb +0 -184
  38. data/lib/fpm/target/rpm.rb +0 -68
  39. data/lib/rpm/header.rb +0 -89
  40. data/lib/rpm/lead.rb +0 -48
  41. data/lib/rpm/namespace.rb +0 -1
  42. data/lib/rpm/rpmfile.rb +0 -81
  43. data/lib/rpm/tag.rb +0 -304
@@ -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
@@ -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
@@ -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
@@ -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