Skip to content

Commit

Permalink
FPM::Builder
Browse files Browse the repository at this point in the history
The builder is the thing that takes a package and a source
and makes them do things.  It is responsible for fpm-wide
defaults, keeping track of paths of things, etc.

Note in particular the change to bin/fpm.
  • Loading branch information
jneen committed Jan 6, 2011
1 parent 734905a commit fea6748
Show file tree
Hide file tree
Showing 2 changed files with 142 additions and 18 deletions.
22 changes: 4 additions & 18 deletions bin/fpm
Expand Up @@ -61,25 +61,11 @@ def main(args)

opts.parse!(args)

if !settings.package_path
$stderr.puts "No package file given to manage. Give with -p PACKAGEFILE"
return 1
end

package = FPM::Deb.new
package.name = settings.package_name
package.version = settings.version
package.maintainer = settings.maintainer if settings.maintainer
package.architecture = (settings.architecture or %x{uname -m}.chomp)
package.dependencies = (settings.dependencies or [])

p settings
package.assemble({
"output" => settings.package_path,
"root" => settings.chdir,
"paths" => args, # Remainder of args are paths.
})
FPM::Builder.new(settings, args).assemble!

return 0
end # def main

ret = main(ARGV)
ret = main(ARGV)
exit(ret != nil ? ret : 0)
138 changes: 138 additions & 0 deletions lib/fpm/builder.rb
@@ -0,0 +1,138 @@
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

def assemble!(params={})
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

0 comments on commit fea6748

Please sign in to comment.