lib/tasks/tar.rb in buildr-1.2.5 vs lib/tasks/tar.rb in buildr-1.2.6

- old
+ new

@@ -1,112 +1,87 @@ -require 'buildr' +require 'tasks/zip' require 'archive/tar/minitar' module Buildr - class TarTask < Rake::FileTask - attr_reader :included + # The TarTask creates a new Tar file. You can include any number of files and and directories, + # use exclusion patterns, and include files into specific directories. + # + # To create a GZipped Tar, either set the gzip option to true, or use the .tgz or .gz suffix. + # + # For example: + # tar("test.tgz").tap do |task| + # task.include "srcs" + # task.include "README", "LICENSE" + # end + # + # See Buildr#tar and ArchiveTask. + class TarTask < ArchiveTask - def initialize(*args) + # To create a GZipped Tar, either set this option to true, or use the .tgz/.gz suffix. + attr_accessor :gzip + # Permission mode for files contained in the Tar. Defaults to 0755. + attr_accessor :mode + + def initialize(*args, &block) #:nodoc: super - @included = {} - enhance do - $stdout << "Creating #{t.name}.\n" if verbose - rm(name, :verbose=>false) rescue nil - mkdir_p(File.dirname(name), :verbose=>false) - begin - out = File.new(name, "w+") - out = Zlib::GzipWriter.new(out) if (/.tgz$/ =~ name) - create_tar_internal(out) - rescue - rm(name, :verbose=>false) rescue nil - raise - end - end + self.gzip = name =~ /\.[t?]gz$/ + self.mode = '0755' end - def with(options) - options.each do |k,v| - send "#{k}=", v - end - end + private - def include(*args) - options = (Hash === args.last) ? args.pop : {} - args = args.flatten - options[:path] ||= "/" - check_add_path_internal options - if options[:as] - raise "Only use :as with one include file at a time" if args.length > 1 - dest_file = File.join(options[:path], options[:as]) - include_internal(dest_file, args.pop, options) - else - args.each do |f| - dest_file = File.join(options[:path], File.basename(f.to_s)) - include_internal(dest_file, f, options) + def create_from(file_map) + if gzip + StringIO.new.tap do |io| + create_tar io, file_map + io.seek 0 + Zlib::GzipWriter.open(name) { |gzip| gzip.write io.read } end + else + File.open(name, 'wb') { |file| create_tar file, file_map } end end - private + def create_tar(out, file_map) + Archive::Tar::Minitar::Writer.open(out) do |tar| + options = { :mode=>mode || '0755', :mtime=>Time.now } - def check_add_path_internal(opts) - unless @included.has_key?(opts[:path]) - include_internal(opts[:path], :mkdir_in_tar, opts) - end - end - - def include_internal(dst, src, opts) - raise %Q("#{dst}" was already included in the archive with source path "#{@included[dst][:source_path]}".) if @included[dst] - @included[dst] = opts.merge({:source_path => src}) - enhance([src]) unless :mkdir_in_tar == src - end - - def create_tar_internal(out) - begin - Archive::Tar::Minitar::Writer.open(out) do |tar| - @included.keys.sort.each do |dst| - opts = @included[dst] - src = opts[:source_path] - if :mkdir_in_tar == src - $stdout << "adding directory #{dst}.\n" if verbose - tar.mkdir(dst, {:mode=>"0755", :mtime=>Time.now}.merge(opts.reject{|k,v| not [:mode, :uid, :gid, :mtime].include?(k)})) - else - $stdout << "adding #{dst} from #{src}\n" if verbose - is = File.new(src, "rb") - opts[:size] = is.stat.size - opts[:mode] ||= is.stat.mode - opts[:mtime] ||= is.stat.mtime - opts[:uid] ||= 80 - opts[:gid] ||= 80 - tar.add_file_simple(dst, opts.reject{|k,v| not [:size, :mode, :uid, :gid, :mtime].include?(k)}) do |os| + file_map.each do |path, content| + if content.respond_to?(:call) + tar.add_file(path, options) { |os, opts| content.call os } + elsif content.nil? || File.directory?(content.to_s) + else + File.open content.to_s, 'rb' do |is| + tar.add_file path, options.merge(:mode=>is.stat.mode, :mtime=>is.stat.mtime, :uid=>is.stat.uid, :gid=>is.stat.gid) do |os, opts| while data = is.read(4096) os.write(data) - $stdout << "." if verbose end end - $stdout << "\n" if verbose end end end - ensure out.close end end + end - class TarballTask < TarTask +end - def initialize(*args) - super - end - def include(*args) - options = (Hash === args.last) ? args.pop : {} - args = args.flatten - options[:path] ||= "/" - options[:path] = File.join(name.pathmap("%n"), options[:path]) - super args, options - end - - end - +# :call-seq: +# tar(file) => TarTask +# +# The TarTask creates a new Tar file. You can include any number of files and +# and directories, use exclusion patterns, and include files into specific +# directories. +# +# To create a GZipped Tar, either set the gzip option to true, or use the .tgz or .gz suffix. +# +# For example: +# tar("test.tgz").tap do |tgz| +# tgz.include "srcs" +# tgz.include "README", "LICENSE" +# end +def tar(file) + TarTask.define_task(file) end