lib/berkshelf/packager.rb
require "archive/tar/minitar"
require "zlib" unless defined?(Zlib)
module Berkshelf
# A class for archiving and compressing directory containing one or more cookbooks.
#
# Example:
# Archiving a path containing the cookbooks:
# * "/path/to/cookbooks/my_face"
# * "/path/to/cookbooks/nginx"
#
# irb> source = "/path/to/cookbooks"
# irb> packager = Berkshelf::Packager.new("some/path/cookbooks.tar.gz")
# irb> packager.run(source) #=> "some/path/cookbooks.tar.gz"
class Packager
class << self
def validate_destination(path)
path.to_s
end
end
# @return [String]
attr_reader :out_file
# @param [#to_s] out_file
# path to write the archive to
def initialize(out_file)
@out_file = out_file.to_s
@out_dir, @filename = File.split(@out_file)
end
# Archive the contents of given path
#
# @param [#to_s] source
# the filepath to archive the contents of
#
# @raise [PackageError]
# if an error is encountered while writing the out_file
#
# @return [String]
# path to the generated archive
def run(source)
tgz = Zlib::GzipWriter.new(File.open(out_file, "wb"))
Archive::Tar::Minitar.pack(Dir.glob("#{source}/*"), tgz)
out_file
rescue SystemCallError => ex
raise PackageError, ex
end
# Validate that running the packager would be successful. Returns nil if would be
# successful and raises an error if would not.
#
# @raise [PackageError]
# if running the packager would absolutely not result in a success
#
# @return [nil]
def validate!
raise PackageError, "Path is not a directory: #{out_dir}" unless File.directory?(out_dir)
raise PackageError, "Directory is not writable: #{out_dir}" unless File.writable?(out_dir)
end
private
# @return [String]
attr_reader :out_dir
# @return [String]
attr_reader :filename
end
end