require 'fileutils'
class FPM::Builder
# where is the package's root?
def root
@root ||= (@source.root || '.')
end
# where the package goes
def output
@output ||= begin
o = @package.default_output
if o.start_with? '/'
o
else
File.join(@working_dir, o)
end
end
end
# things to clean up afterwards
def garbage
@garbage ||= []
end
# the spec or control file
def spec
@spec ||= @source.render(@package.template)
end
attr_reader :paths
attr_reader :package
attr_reader :source
def initialize(settings, paths=[])
@working_dir = Dir.pwd
root = settings.chdir || '.'
paths = ['.'] if paths.empty?
@source = source_class_for(settings.source_type || 'dir').new(paths, root, :version => settings.version)
@package = package_class_for(settings.package_type).new(@source)
@paths = paths
@output = settings.package_path
if @output
@output.gsub! /VERSION/, @source[:version]
@output.gsub! /ARCH/, @package.architecture
end
end # def initialize
def tar_path
@tar_path ||= "#{builddir}/data.tar"
end
# Assemble the package
def assemble!
output.gsub!(/VERSION/, "#{@source[:version]}-#{@source[:iteration]}")
output.gsub!(/ARCH/, @package.architecture)
File.delete(output) if File.exists?(output)
make_builddir!
::Dir.chdir root do
@source.make_tarball!(tar_path)
generate_md5sums
generate_specfile
end
::Dir.chdir(builddir) do
@package.build!({
:tarball => tar_path,
:output => output
})
end
cleanup!
end # def assemble!
private
def builddir
@builddir ||= File.expand_path(
"#{Dir.pwd}/build-#{@package.type}-#{File.basename(output)}"
)
end
def make_builddir!
FileUtils.rm_rf builddir
garbage << builddir
FileUtils.mkdir(builddir) if !File.directory?(builddir)
p :exists => File.directory?(builddir)
end
# TODO: [Jay] make this better.
def package_class_for(type)
({
:deb => FPM::Deb,
:rpm => FPM::Rpm
})[:"#{type}"]
end
# TODO: [Jay] make this better.
def source_class_for(type)
case type.to_s
when 'gem'
FPM::Gem
when 'dir'
FPM::Dir
when 'tar'
FPM::Tar
else
raise ArgumentError, "unknown package type #{type.inspect}"
end
end
def cleanup!
return [] if garbage.empty?
FileUtils.rm_rf(garbage) && garbage.clear
end
def generate_specfile
File.open(@package.specfile(builddir), "w") { |f| f.puts spec }
end
def generate_md5sums
md5sums = checksum(paths)
File.open("#{builddir}/md5sums", "w") { |f| f.puts md5sums }
md5sums
end
def checksum(paths)
md5sums = []
paths.each do |path|
md5sums += %x{find #{path} -type f -print0 | xargs -0 md5sum}.split("\n")
end
end # def checksum
end