summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAustin Ziegler <austin@rubyforge.org>2007-02-05 04:09:51 +0000
committerAustin Ziegler <austin@rubyforge.org>2007-02-05 04:09:51 +0000
commit498bb3c674bf011a9b4d0ba6bb4a84a2a2c925b6 (patch)
tree26ef5bb238e248eeab2c742a0a24a3f8c24db59b
parent0b8fa777cab062609fa05952d1f7b9660e2e9cff (diff)
downloaddiff-lcs-498bb3c674bf011a9b4d0ba6bb4a84a2a2c925b6.tar.gz
Finishing cleanup.
-rw-r--r--tags/version_0_5_0/minitar/ChangeLog8
-rw-r--r--tags/version_0_5_0/minitar/Install6
-rw-r--r--tags/version_0_5_0/minitar/README67
-rw-r--r--tags/version_0_5_0/minitar/bin/minitar26
-rw-r--r--tags/version_0_5_0/minitar/install.rb264
-rw-r--r--tags/version_0_5_0/minitar/lib/archive/tar/minitar.rb979
-rw-r--r--tags/version_0_5_0/minitar/lib/archive/tar/minitar/command.rb815
-rw-r--r--tags/version_0_5_0/minitar/tests/tc_tar.rb624
-rw-r--r--tags/version_0_5_0/minitar/tests/testall.rb20
-rw-r--r--tags/version_0_5_1/minitar/ChangeLog11
-rw-r--r--tags/version_0_5_1/minitar/Install6
-rw-r--r--tags/version_0_5_1/minitar/README66
-rw-r--r--tags/version_0_5_1/minitar/Rakefile112
-rw-r--r--tags/version_0_5_1/minitar/bin/minitar26
-rw-r--r--tags/version_0_5_1/minitar/install.rb262
-rw-r--r--tags/version_0_5_1/minitar/lib/archive/tar/minitar.rb979
-rw-r--r--tags/version_0_5_1/minitar/lib/archive/tar/minitar/command.rb814
-rw-r--r--tags/version_0_5_1/minitar/tests/tc_tar.rb624
-rw-r--r--tags/version_0_5_1/minitar/tests/testall.rb20
19 files changed, 0 insertions, 5729 deletions
diff --git a/tags/version_0_5_0/minitar/ChangeLog b/tags/version_0_5_0/minitar/ChangeLog
deleted file mode 100644
index baf5d74..0000000
--- a/tags/version_0_5_0/minitar/ChangeLog
+++ /dev/null
@@ -1,8 +0,0 @@
-Revision history for Ruby library Archive::Tar::Minitar. Unless explicitly
-noted otherwise, all changes are produced by Austin Ziegler
-<minitar@halostatue.ca>.
-
-== Archive::Tar::Minitar
-* Initial release. Does files and directories. Command does create, extract,
-* and list.
-
diff --git a/tags/version_0_5_0/minitar/Install b/tags/version_0_5_0/minitar/Install
deleted file mode 100644
index ef1af1a..0000000
--- a/tags/version_0_5_0/minitar/Install
+++ /dev/null
@@ -1,6 +0,0 @@
-Installing this package is as simple as:
-
-% ruby install.rb
-
-Alternatively, you can use the RubyGem version of Archive::Tar::Minitar
-available as archive-tar-minitar-0.5.0.gem from the usual sources.
diff --git a/tags/version_0_5_0/minitar/README b/tags/version_0_5_0/minitar/README
deleted file mode 100644
index 6b75a1a..0000000
--- a/tags/version_0_5_0/minitar/README
+++ /dev/null
@@ -1,67 +0,0 @@
-Archive::Tar::Minitar README
-============================
-Archive::Tar::Minitar is a pure-Ruby library and command-line utility
-that provides the ability to deal with POSIX tar(1) archive files. The
-implementation is based heavily on Mauricio Fernández's implementation
-in rpa-base, but has been reorganised to promote reuse in other
-projects.
-
-This release is version 0.5.0. The library can only handle files and
-directories at this point. A future version will be expanded to handle
-symbolic links and hard links in a portable manner. The command line
-utility, minitar, can only create archives, extract from archives, and
-list archive contents.
-
-Using this library is easy. The simplest case is:
-
- require 'zlib'
- require 'archive/tar/minitar'
- include Archive::Tar
-
- # Packs everything that matches Find.find('tests')
- File.open('test.tar', 'wb') { |tar| Minitar.pack('tests', tar) }
- # Unpacks 'test.tar' to 'x', creating 'x' if necessary.
- Minitar.unpack('test.tar', 'x')
-
-A gzipped tar can be written with:
-
- tgz = Zlib::GzipWriter.new(File.open('test.tgz', 'wb'))
- # Warning: tgz will be closed!
- Minitar.pack('tests', tgz)
-
- tgz = Zlib::GzipReader.new(File.open('test.tgz', 'rb'))
- # Warning: tgz will be closed!
- Minitar.unpack(tgz, 'x')
-
-As the case above shows, one need not write to a file. However, it will
-sometimes require that one dive a little deeper into the API, as in the
-case of StringIO objects. Note that I'm not providing a block with
-Minitar::Output, as Minitar::Output#close automatically closes both the
-Output object and the wrapped data stream object.
-
- begin
- sgz = Zlib::GzipWriter.new(StringIO.new(""))
- tar = Output.new(sgz)
- Find.find('tests') do |entry|
- Minitar.pack_file(entry, tar)
- end
- ensure
- # Closes both tar and sgz.
- tar.close
- end
-
-Copyright
-=========
-# Copyright 2004 Mauricio Julio Fernández Pradier and Austin Ziegler
-#
-# This program is based on and incorporates parts of RPA::Package from
-# rpa-base (lib/rpa/package.rb and lib/rpa/util.rb) by Mauricio and has been
-# adapted to be more generic by Austin.
-#
-# 'minitar' contains an adaptation of Ruby/ProgressBar by Satoru
-# Takabayashi <satoru@namazu.org>, copyright © 2001 - 2004.
-#
-# This program is free software. It may be redistributed and/or modified
-# under the terms of the GPL version 2 (or later) or Ruby's licence.
-#
-# $Id$
diff --git a/tags/version_0_5_0/minitar/bin/minitar b/tags/version_0_5_0/minitar/bin/minitar
deleted file mode 100644
index f887e48..0000000
--- a/tags/version_0_5_0/minitar/bin/minitar
+++ /dev/null
@@ -1,26 +0,0 @@
-#!/usr/bin/env ruby
-#--
-# Archive::Tar::Minitar 0.5.0
-# Copyright © 2004 Mauricio Julio Fernández Pradier and Austin Ziegler
-#
-# This program is based on and incorporates parts of RPA::Package from
-# rpa-base (lib/rpa/package.rb and lib/rpa/util.rb) by Mauricio and has been
-# adapted to be more generic by Austin.
-#
-# It is licensed under the GNU General Public Licence or Ruby's licence.
-#
-# $Id$
-#++
-
- # 1) Try to load Archive::Tar::Minitar from the gem.
- # 2) Try to load Archive::Tar::Minitar from $LOAD_PATH.
-begin
- require 'rubygems'
- require_gem 'archive-tar-minitar'
-rescue LoadError
- require 'archive/tar/minitar'
-end
-
-require 'archive/tar/minitar/command'
-
-exit Archive::Tar::Minitar::Command.run(ARGV)
diff --git a/tags/version_0_5_0/minitar/install.rb b/tags/version_0_5_0/minitar/install.rb
deleted file mode 100644
index 5772e0b..0000000
--- a/tags/version_0_5_0/minitar/install.rb
+++ /dev/null
@@ -1,264 +0,0 @@
-#! /usr/bin/env ruby
-#--
-# Copyright 2004 Austin Ziegler <ruby-install@halostatue.ca>
-# Install utility. Based on the original installation script for rdoc by the
-# Pragmatic Programmers.
-#
-# This program is free software. It may be redistributed and/or modified under
-# the terms of the GPL version 2 (or later) or the Ruby licence.
-#
-# Usage
-# -----
-# In most cases, if you have a typical project layout, you will need to do
-# absolutely nothing to make this work for you. This layout is:
-#
-# bin/ # executable files -- "commands"
-# lib/ # the source of the library
-# tests/ # unit tests
-#
-# The default behaviour:
-# 1) Run all unit test files (ending in .rb) found in all directories under
-# tests/.
-# 2) Build Rdoc documentation from all files in bin/ (excluding .bat and .cmd),
-# all .rb files in lib/, ./README, ./ChangeLog, and ./Install.
-# 3) Build ri documentation from all files in bin/ (excluding .bat and .cmd),
-# and all .rb files in lib/. This is disabled by default on Win32.
-# 4) Install commands from bin/ into the Ruby bin directory. On Windows, if a
-# if a corresponding batch file (.bat or .cmd) exists in the bin directory,
-# it will be copied over as well. Otherwise, a batch file (always .bat) will
-# be created to run the specified command.
-# 5) Install all library files ending in .rb from lib/ into Ruby's
-# site_lib/version directory.
-#
-# $Id$
-#++
-
-require 'rbconfig'
-require 'find'
-require 'fileutils'
-require 'rdoc/rdoc'
-require 'optparse'
-require 'ostruct'
-
-InstallOptions = OpenStruct.new
-
-def glob(list)
- g = list.map { |i| Dir.glob(i) }
- g.flatten!
- g.compact!
- g.reject! { |e| e =~ /CVS/ }
- g
-end
-
- # Set these values to what you want installed.
-bins = glob(%w{bin/**/*}).reject { |e| e =~ /\.(bat|cmd)$/ }
-rdoc = glob(%w{bin/**/* lib/**/*.rb README ChangeLog Install}).reject { |e| e=~ /\.(bat|cmd)$/ }
-ri = glob(%w(bin/**/*.rb lib/**/*.rb)).reject { |e| e=~ /\.(bat|cmd)$/ }
-libs = glob(%w{lib/**/*.rb})
-tests = glob(%w{tests/**/*.rb})
-
-def do_bins(bins, target, strip = 'bin/')
- bins.each do |bf|
- obf = bf.gsub(/#{strip}/, '')
- install_binfile(bf, obf, target)
- end
-end
-
-def do_libs(libs, strip = 'lib/')
- libs.each do |lf|
- olf = File.join(InstallOptions.site_dir, lf.gsub(/#{strip}/, ''))
- op = File.dirname(olf)
- File.makedirs(op, true)
- File.chmod(0755, op)
- File.install(lf, olf, 0755, true)
- end
-end
-
-##
-# Prepare the file installation.
-#
-def prepare_installation
- InstallOptions.rdoc = true
- if RUBY_PLATFORM == "i386-mswin32"
- InstallOptions.ri = false
- else
- InstallOptions.ri = true
- end
- InstallOptions.tests = true
-
- ARGV.options do |opts|
- opts.banner = "Usage: #{File.basename($0)} [options]"
- opts.separator ""
- opts.on('--[no-]rdoc', 'Prevents the creation of RDoc output.', 'Default on.') do |onrdoc|
- InstallOptions.rdoc = onrdoc
- end
- opts.on('--[no-]ri', 'Prevents the creation of RI output.', 'Default off on mswin32.') do |onri|
- InstallOptions.ri = onri
- end
- opts.on('--[no-]tests', 'Prevents the execution of unit tests.', 'Default on.') do |ontest|
- InstallOptions.tests = ontest
- end
- opts.on('--quick', 'Performs a quick installation. Only the', 'installation is done.') do |quick|
- InstallOptions.rdoc = false
- InstallOptions.ri = false
- InstallOptions.tests = false
- end
- opts.on('--full', 'Performs a full installation. All', 'optional installation steps are run.') do |full|
- InstallOptions.rdoc = true
- InstallOptions.ri = true
- InstallOptions.tests = true
- end
- opts.separator("")
- opts.on_tail('--help', "Shows this help text.") do
- $stderr.puts opts
- exit
- end
-
- opts.parse!
- end
-
- bds = [".", ENV['TMP'], ENV['TEMP']]
-
- version = [Config::CONFIG["MAJOR"], Config::CONFIG["MINOR"]].join(".")
- ld = File.join(Config::CONFIG["libdir"], "ruby", version)
-
- sd = Config::CONFIG["sitelibdir"]
- if sd.nil?
- sd = $:.find { |x| x =~ /site_ruby/ }
- if sd.nil?
- sd = File.join(ld, "site_ruby")
- elsif sd !~ Regexp.quote(version)
- sd = File.join(sd, version)
- end
- end
-
- if (destdir = ENV['DESTDIR'])
- bd = "#{destdir}#{Config::CONFIG['bindir']}"
- sd = "#{destdir}#{sd}"
- bds << bd
-
- FileUtils.makedirs(bd)
- FileUtils.makedirs(sd)
- else
- bds << Config::CONFIG['bindir']
- end
-
- InstallOptions.bin_dirs = bds.compact
- InstallOptions.site_dir = sd
- InstallOptions.bin_dir = bd
- InstallOptions.lib_dir = ld
-end
-
-##
-# Build the rdoc documentation. Also, try to build the RI documentation.
-#
-def build_rdoc(files)
- r = RDoc::RDoc.new
- r.document(["--main", "README", "--title", "Diff::LCS -- A Diff Algorithm",
- "--line-numbers"] + files)
-
-rescue RDoc::RDocError => e
- $stderr.puts e.message
-rescue Exception => e
- $stderr.puts "Couldn't build RDoc documentation\n#{e.message}"
-end
-
-def build_ri(files)
- ri = RDoc::RDoc.new
- ri.document(["--ri-site", "--merge"] + files)
-rescue RDoc::RDocError => e
- $stderr.puts e.message
-rescue Exception => e
- $stderr.puts "Couldn't build Ri documentation\n#{e.message}"
-end
-
-def run_tests(test_list)
- require 'test/unit/ui/console/testrunner'
- $:.unshift "lib"
- test_list.each do |test|
- next if File.directory?(test)
- require test
- end
-
- tests = []
- ObjectSpace.each_object { |o| tests << o if o.kind_of?(Class) }
- tests.delete_if { |o| !o.ancestors.include?(Test::Unit::TestCase) }
- tests.delete_if { |o| o == Test::Unit::TestCase }
-
- tests.each { |test| Test::Unit::UI::Console::TestRunner.run(test) }
- $:.shift
-end
-
-##
-# Install file(s) from ./bin to Config::CONFIG['bindir']. Patch it on the way
-# to insert a #! line; on a Unix install, the command is named as expected
-# (e.g., bin/rdoc becomes rdoc); the shebang line handles running it. Under
-# windows, we add an '.rb' extension and let file associations do their stuff.
-def install_binfile(from, op_file, target)
- tmp_dir = nil
- InstallOptions.bin_dirs.each do |t|
- if File.directory?(t) and File.writable?(t)
- tmp_dir = t
- break
- end
- end
-
- fail "Cannot find a temporary directory" unless tmp_dir
- tmp_file = File.join(tmp_dir, '_tmp')
- ruby = File.join(Config::CONFIG['bindir'], Config::CONFIG['ruby_install_name'])
-
- File.open(from) do |ip|
- File.open(tmp_file, "w") do |op|
- ruby = File.join(Config::CONFIG['bindir'], Config::CONFIG['ruby_install_name'])
- op.puts "#!#{ruby}"
- op.write ip.read
- end
- end
-
- if Config::CONFIG["target_os"] =~ /win/io
- installed_wrapper = false
-
- if File.exists?("#{from}.bat")
- FileUtils.install("#{from}.bat", File.join(target, "#{op_file}.bat"), :mode => 0755, :verbose => true)
- installed_wrapper = true
- end
-
- if File.exists?("#{from}.cmd")
- FileUtils.install("#{from}.cmd", File.join(target, "#{op_file}.cmd"), :mode => 0755, :verbose => true)
- installed_wrapper = true
- end
-
- if not installed_wrapper
- tmp_file2 = File.join(tmp_dir, '_tmp_wrapper')
- cwn = File.join(Config::CONFIG['bindir'], op_file)
- cwv = CMD_WRAPPER.gsub('<ruby>', ruby.gsub(%r{/}) { "\\" }).gsub!('<command>', cwn.gsub(%r{/}) { "\\" } )
-
- File.open(tmp_file2, "wb") { |cw| cw.puts cwv }
- FileUtils.install(tmp_file2, File.join(target, "#{op_file}.bat"), :mode => 0755, :verbose => true)
-
- File.unlink(tmp_file2)
- installed_wrapper = true
- end
- end
- FileUtils.install(tmp_file, File.join(target, op_file), :mode => 0755, :verbose => true)
- File.unlink(tmp_file)
-end
-
-CMD_WRAPPER = <<-EOS
-@echo off
-if "%OS%"=="Windows_NT" goto WinNT
-<ruby> -x "<command>" %1 %2 %3 %4 %5 %6 %7 %8 %9
-goto done
-:WinNT
-<ruby> -x "<command>" %*
-goto done
-:done
-EOS
-
-prepare_installation
-
-run_tests(tests) if InstallOptions.tests
-build_rdoc(rdoc) if InstallOptions.rdoc
-build_ri(ri) if InstallOptions.ri
-do_bins(bins, Config::CONFIG['bindir'])
-do_libs(libs)
diff --git a/tags/version_0_5_0/minitar/lib/archive/tar/minitar.rb b/tags/version_0_5_0/minitar/lib/archive/tar/minitar.rb
deleted file mode 100644
index aace0dd..0000000
--- a/tags/version_0_5_0/minitar/lib/archive/tar/minitar.rb
+++ /dev/null
@@ -1,979 +0,0 @@
-#!/usr/bin/env ruby
-#--
-# Archive::Tar::Minitar 0.5.0
-# Copyright © 2004 Mauricio Julio Fernández Pradier and Austin Ziegler
-#
-# This program is based on and incorporates parts of RPA::Package from
-# rpa-base (lib/rpa/package.rb and lib/rpa/util.rb) by Mauricio and has been
-# adapted to be more generic by Austin.
-#
-# It is licensed under the GNU General Public Licence or Ruby's licence.
-#
-# $Id$
-#++
-
-module Archive; end
-module Archive::Tar; end
-
- # = Archive::Tar::PosixHeader
- # Implements the POSIX tar header as a Ruby class. The structure of
- # the POSIX tar header is:
- #
- # struct tarfile_entry_posix
- # { // pack/unpack
- # char name[100]; // ASCII (+ Z unless filled) a100/Z100
- # char mode[8]; // 0 padded, octal, null a8 /A8
- # char uid[8]; // ditto a8 /A8
- # char gid[8]; // ditto a8 /A8
- # char size[12]; // 0 padded, octal, null a12 /A12
- # char mtime[12]; // 0 padded, octal, null a12 /A12
- # char checksum[8]; // 0 padded, octal, null, space a8 /A8
- # char typeflag[1]; // see below a /a
- # char linkname[100]; // ASCII + (Z unless filled) a100/Z100
- # char magic[6]; // "ustar\0" a6 /A6
- # char version[2]; // "00" a2 /A2
- # char uname[32]; // ASCIIZ a32 /Z32
- # char gname[32]; // ASCIIZ a32 /Z32
- # char devmajor[8]; // 0 padded, octal, null a8 /A8
- # char devminor[8]; // 0 padded, octal, null a8 /A8
- # char prefix[155]; // ASCII (+ Z unless filled) a155/Z155
- # };
- #
- # The +typeflag+ may be one of the following known values:
- #
- # <tt>"0"</tt>:: Regular file. NULL should be treated as a synonym, for
- # compatibility purposes.
- # <tt>"1"</tt>:: Hard link.
- # <tt>"2"</tt>:: Symbolic link.
- # <tt>"3"</tt>:: Character device node.
- # <tt>"4"</tt>:: Block device node.
- # <tt>"5"</tt>:: Directory.
- # <tt>"6"</tt>:: FIFO node.
- # <tt>"7"</tt>:: Reserved.
- #
- # POSIX indicates that "A POSIX-compliant implementation must treat any
- # unrecognized typeflag value as a regular file."
-class Archive::Tar::PosixHeader
- FIELDS = %w(name mode uid gid size mtime checksum typeflag linkname) +
- %w(magic version uname gname devmajor devminor prefix)
-
- FIELDS.each { |field| attr_reader field.intern }
-
- HEADER_PACK_FORMAT = "a100a8a8a8a12a12a7aaa100a6a2a32a32a8a8a155"
- HEADER_UNPACK_FORMAT = "Z100A8A8A8A12A12A8aZ100A6A2Z32Z32A8A8Z155"
-
- # Creates a new PosixHeader from a data stream.
- def self.new_from_stream(stream)
- data = stream.read(512)
- fields = data.unpack(HEADER_UNPACK_FORMAT)
- name = fields.shift
- mode = fields.shift.oct
- uid = fields.shift.oct
- gid = fields.shift.oct
- size = fields.shift.oct
- mtime = fields.shift.oct
- checksum = fields.shift.oct
- typeflag = fields.shift
- linkname = fields.shift
- magic = fields.shift
- version = fields.shift.oct
- uname = fields.shift
- gname = fields.shift
- devmajor = fields.shift.oct
- devminor = fields.shift.oct
- prefix = fields.shift
-
- empty = (data == "\0" * 512)
-
- new(:name => name, :mode => mode, :uid => uid, :gid => gid,
- :size => size, :mtime => mtime, :checksum => checksum,
- :typeflag => typeflag, :magic => magic, :version => version,
- :uname => uname, :gname => gname, :devmajor => devmajor,
- :devminor => devminor, :prefix => prefix, :empty => empty)
- end
-
- # Creates a new PosixHeader. A PosixHeader cannot be created unless the
- # #name, #size, #prefix, and #mode are provided.
- def initialize(vals)
- unless vals[:name] && vals[:size] && vals[:prefix] && vals[:mode]
- raise ArgumentError
- end
-
- vals[:mtime] ||= 0
- vals[:checksum] ||= ""
- vals[:typeflag] ||= "0"
- vals[:magic] ||= "ustar"
- vals[:version] ||= "00"
-
- FIELDS.each do |field|
- instance_variable_set("@#{field}", vals[field.intern])
- end
- @empty = vals[:empty]
- end
-
- def empty?
- @empty
- end
-
- def to_s
- update_checksum
- header(@checksum)
- end
-
- # Update the checksum field.
- def update_checksum
- hh = header(" " * 8)
- @checksum = oct(calculate_checksum(hh), 6)
- end
-
- private
- def oct(num, len)
- if num.nil?
- "\0" * (len + 1)
- else
- "%0#{len}o" % num
- end
- end
-
- def calculate_checksum(hdr)
- hdr.unpack("C*").inject { |aa, bb| aa + bb }
- end
-
- def header(chksum)
- arr = [name, oct(mode, 7), oct(uid, 7), oct(gid, 7), oct(size, 11),
- oct(mtime, 11), chksum, " ", typeflag, linkname, magic, version,
- uname, gname, oct(devmajor, 7), oct(devminor, 7), prefix]
- str = arr.pack(HEADER_PACK_FORMAT)
- str + "\0" * ((512 - str.size) % 512)
- end
-end
-
-require 'fileutils'
-require 'find'
-
- # = Archive::Tar::Minitar 0.5.0
- # Archive::Tar::Minitar is a pure-Ruby library and command-line
- # utility that provides the ability to deal with POSIX tar(1) archive
- # files. The implementation is based heavily on Mauricio Fernández's
- # implementation in rpa-base, but has been reorganised to promote
- # reuse in other projects.
- #
- # This tar class performs a subset of all tar (POSIX tape archive)
- # operations. We can only deal with typeflags 0, 1, 2, and 5 (see
- # Archive::Tar::PosixHeader). All other typeflags will be treated as
- # normal files.
- #
- # NOTE::: support for typeflags 1 and 2 is not yet implemented in this
- # version.
- #
- # This release is version 0.5.0. The library can only handle files and
- # directories at this point. A future version will be expanded to
- # handle symbolic links and hard links in a portable manner. The
- # command line utility, minitar, can only create archives, extract
- # from archives, and list archive contents.
- #
- # == Synopsis
- # Using this library is easy. The simplest case is:
- #
- # require 'zlib'
- # require 'archive/tar/minitar'
- # include Archive::Tar
- #
- # # Packs everything that matches Find.find('tests')
- # File.open('test.tar', 'wb') { |tar| Minitar.pack('tests', tar) }
- # # Unpacks 'test.tar' to 'x', creating 'x' if necessary.
- # Minitar.unpack('test.tar', 'x')
- #
- # A gzipped tar can be written with:
- #
- # tgz = Zlib::GzipWriter.new(File.open('test.tgz', 'wb'))
- # # Warning: tgz will be closed!
- # Minitar.pack('tests', tgz)
- #
- # tgz = Zlib::GzipReader.new(File.open('test.tgz', 'rb'))
- # # Warning: tgz will be closed!
- # Minitar.unpack(tgz, 'x')
- #
- # As the case above shows, one need not write to a file. However, it
- # will sometimes require that one dive a little deeper into the API,
- # as in the case of StringIO objects. Note that I'm not providing a
- # block with Minitar::Output, as Minitar::Output#close automatically
- # closes both the Output object and the wrapped data stream object.
- #
- # begin
- # sgz = Zlib::GzipWriter.new(StringIO.new(""))
- # tar = Output.new(sgz)
- # Find.find('tests') do |entry|
- # Minitar.pack_file(entry, tar)
- # end
- # ensure
- # # Closes both tar and sgz.
- # tar.close
- # end
- #
- # == Copyright
- # Copyright 2004 Mauricio Julio Fernández Pradier and Austin Ziegler
- #
- # This program is based on and incorporates parts of RPA::Package from
- # rpa-base (lib/rpa/package.rb and lib/rpa/util.rb) by Mauricio and
- # has been adapted to be more generic by Austin.
- #
- # 'minitar' contains an adaptation of Ruby/ProgressBar by Satoru
- # Takabayashi <satoru@namazu.org>, copyright © 2001 - 2004.
- #
- # This program is free software. It may be redistributed and/or
- # modified under the terms of the GPL version 2 (or later) or Ruby's
- # licence.
-module Archive::Tar::Minitar
- VERSION = "0.5.0"
-
- # The exception raised when a wrapped data stream class is expected to
- # respond to #rewind or #pos but does not.
- class NonSeekableStream < StandardError; end
- # The exception raised when a block is required for proper operation of
- # the method.
- class BlockRequired < ArgumentError; end
- # The exception raised when operations are performed on a stream that has
- # previously been closed.
- class ClosedStream < StandardError; end
- # The exception raised when a filename exceeds 256 bytes in length,
- # the maximum supported by the standard Tar format.
- class FileNameTooLong < StandardError; end
- # The exception raised when a data stream ends before the amount of data
- # expected in the archive's PosixHeader.
- class UnexpectedEOF < StandardError; end
-
- # The class that writes a tar format archive to a data stream.
- class Writer
- # A stream wrapper that can only be written to. Any attempt to read
- # from this restricted stream will result in a NameError being thrown.
- class RestrictedStream
- def initialize(anIO)
- @io = anIO
- end
-
- def write(data)
- @io.write(data)
- end
- end
-
- # A RestrictedStream that also has a size limit.
- class BoundedStream < Archive::Tar::Minitar::Writer::RestrictedStream
- # The exception raised when the user attempts to write more data to
- # a BoundedStream than has been allocated.
- class FileOverflow < RuntimeError; end
-
- # The maximum number of bytes that may be written to this data
- # stream.
- attr_reader :limit
- # The current total number of bytes written to this data stream.
- attr_reader :written
-
- def initialize(io, limit)
- @io = io
- @limit = limit
- @written = 0
- end
-
- def write(data)
- raise FileOverflow if (data.size + @written) > @limit
- @io.write(data)
- @written += data.size
- data.size
- end
- end
-
- # With no associated block, +Writer::open+ is a synonym for
- # +Writer::new+. If the optional code block is given, it will be
- # passed the new _writer_ as an argument and the Writer object will
- # automatically be closed when the block terminates. In this instance,
- # +Writer::open+ returns the value of the block.
- def self.open(anIO)
- writer = Writer.new(anIO)
-
- return writer unless block_given?
-
- begin
- res = yield writer
- ensure
- writer.close
- end
-
- res
- end
-
- # Creates and returns a new Writer object.
- def initialize(anIO)
- @io = anIO
- @closed = false
- end
-
- # Adds a file to the archive as +name+. +opts+ must contain the
- # following values:
- #
- # <tt>:mode</tt>:: The Unix file permissions mode value.
- # <tt>:size</tt>:: The size, in bytes.
- #
- # +opts+ may contain the following values:
- #
- # <tt>:uid</tt>: The Unix file owner user ID number.
- # <tt>:gid</tt>: The Unix file owner group ID number.
- # <tt>:mtime</tt>:: The *integer* modification time value.
- #
- # It will not be possible to add more than <tt>opts[:size]</tt> bytes
- # to the file.
- def add_file_simple(name, opts = {}) # :yields BoundedStream:
- raise Archive::Tar::Minitar::BlockRequired unless block_given?
- raise Archive::Tar::ClosedStream if @closed
-
- name, prefix = split_name(name)
-
- header = { :name => name, :mode => opts[:mode], :mtime => opts[:mtime],
- :size => opts[:size], :gid => opts[:gid], :uid => opts[:uid],
- :prefix => prefix }
- header = Archive::Tar::PosixHeader.new(header).to_s
- @io.write(header)
-
- os = BoundedStream.new(@io, opts[:size])
- yield os
- # FIXME: what if an exception is raised in the block?
-
- min_padding = opts[:size] - os.written
- @io.write("\0" * min_padding)
- remainder = (512 - (opts[:size] % 512)) % 512
- @io.write("\0" * remainder)
- end
-
- # Adds a file to the archive as +name+. +opts+ must contain the
- # following value:
- #
- # <tt>:mode</tt>:: The Unix file permissions mode value.
- #
- # +opts+ may contain the following values:
- #
- # <tt>:uid</tt>: The Unix file owner user ID number.
- # <tt>:gid</tt>: The Unix file owner group ID number.
- # <tt>:mtime</tt>:: The *integer* modification time value.
- #
- # The file's size will be determined from the amount of data written
- # to the stream.
- #
- # For #add_file to be used, the Archive::Tar::Minitar::Writer must be
- # wrapping a stream object that is seekable (e.g., it responds to
- # #pos=). Otherwise, #add_file_simple must be used.
- #
- # +opts+ may be modified during the writing to the stream.
- def add_file(name, opts = {}) # :yields RestrictedStream, +opts+:
- raise Archive::Tar::Minitar::BlockRequired unless block_given?
- raise Archive::Tar::Minitar::ClosedStream if @closed
- raise Archive::Tar::Minitar::NonSeekableStream unless @io.respond_to?(:pos=)
-
- name, prefix = split_name(name)
- init_pos = @io.pos
- @io.write("\0" * 512) # placeholder for the header
-
- yield RestrictedStream.new(@io), opts
- # FIXME: what if an exception is raised in the block?
-
- size = @io.pos - (init_pos + 512)
- remainder = (512 - (size % 512)) % 512
- @io.write("\0" * remainder)
-
- final_pos = @io.pos
- @io.pos = init_pos
-
- header = { :name => name, :mode => opts[:mode], :mtime => opts[:mtime],
- :size => size, :gid => opts[:gid], :uid => opts[:uid],
- :prefix => prefix }
- header = Archive::Tar::PosixHeader.new(header).to_s
- @io.write(header)
- @io.pos = final_pos
- end
-
- # Creates a directory in the tar.
- def mkdir(name, opts = {})
- raise ClosedStream if @closed
- name, prefix = split_name(name)
- header = { :name => name, :mode => opts[:mode], :typeflag => "5",
- :size => 0, :gid => opts[:gid], :uid => opts[:uid],
- :mtime => opts[:mtime], :prefix => prefix }
- header = Archive::Tar::PosixHeader.new(header).to_s
- @io.write(header)
- nil
- end
-
- # Passes the #flush method to the wrapped stream, used for buffered
- # streams.
- def flush
- raise ClosedStream if @closed
- @io.flush if @io.respond_to?(:flush)
- end
-
- # Closes the Writer.
- def close
- return if @closed
- @io.write("\0" * 1024)
- @closed = true
- end
-
- private
- def split_name(name)
- raise FileNameTooLong if name.size > 256
- if name.size <= 100
- prefix = ""
- else
- parts = name.split(/\//)
- newname = parts.pop
-
- nxt = ""
-
- loop do
- nxt = parts.pop
- break if newname.size + 1 + nxt.size > 100
- newname = "#{nxt}/#{newname}"
- end
-
- prefix = (parts + [nxt]).join("/")
-
- name = newname
-
- raise FileNameTooLong if name.size > 100 || prefix.size > 155
- end
- return name, prefix
- end
- end
-
- # The class that reads a tar format archive from a data stream. The data
- # stream may be sequential or random access, but certain features only work
- # with random access data streams.
- class Reader
- # This marks the EntryStream closed for reading without closing the
- # actual data stream.
- module InvalidEntryStream
- def read(len = nil); raise ClosedStream; end
- def getc; raise ClosedStream; end
- def rewind; raise ClosedStream; end
- end
-
- # EntryStreams are pseudo-streams on top of the main data stream.
- class EntryStream
- Archive::Tar::PosixHeader::FIELDS.each do |field|
- attr_reader field.intern
- end
-
- def initialize(header, anIO)
- @io = anIO
- @name = header.name
- @mode = header.mode
- @uid = header.uid
- @gid = header.gid
- @size = header.size
- @mtime = header.mtime
- @checksum = header.checksum
- @typeflag = header.typeflag
- @linkname = header.linkname
- @magic = header.magic
- @version = header.version
- @uname = header.uname
- @gname = header.gname
- @devmajor = header.devmajor
- @devminor = header.devminor
- @prefix = header.prefix
- @read = 0
- @orig_pos = @io.pos
- end
-
- # Reads +len+ bytes (or all remaining data) from the entry. Returns
- # +nil+ if there is no more data to read.
- def read(len = nil)
- return nil if @read >= @size
- len ||= @size - @read
- max_read = [len, @size - @read].min
- ret = @io.read(max_read)
- @read += ret.size
- ret
- end
-
- # Reads one byte from the entry. Returns +nil+ if there is no more data
- # to read.
- def getc
- return nil if @read >= @size
- ret = @io.getc
- @read += 1 if ret
- ret
- end
-
- # Returns +true+ if the entry represents a directory.
- def directory?
- @typeflag == "5"
- end
- alias_method :directory, :directory?
-
- # Returns +true+ if the entry represents a plain file.
- def file?
- @typeflag == "0"
- end
- alias_method :file, :file?
-
- # Returns +true+ if the current read pointer is at the end of the
- # EntryStream data.
- def eof?
- @read >= @size
- end
-
- # Returns the current read pointer in the EntryStream.
- def pos
- @read
- end
-
- # Sets the current read pointer to the beginning of the EntryStream.
- def rewind
- raise NonSeekableStream unless @io.respond_to?(:pos=)
- @io.pos = @orig_pos
- @read = 0
- end
-
- def bytes_read
- @read
- end
-
- # Returns the full and proper name of the entry.
- def full_name
- if @prefix != ""
- File.join(@prefix, @name)
- else
- @name
- end
- end
-
- # Closes the entry.
- def close
- invalidate
- end
-
- private
- def invalidate
- extend InvalidEntryStream
- end
- end
-
- # With no associated block, +Reader::open+ is a synonym for
- # +Reader::new+. If the optional code block is given, it will be passed
- # the new _writer_ as an argument and the Reader object will
- # automatically be closed when the block terminates. In this instance,
- # +Reader::open+ returns the value of the block.
- def self.open(anIO)
- reader = Reader.new(anIO)
-
- return reader unless block_given?
-
- begin
- res = yield reader
- ensure
- reader.close
- end
-
- res
- end
-
- # Creates and returns a new Reader object.
- def initialize(anIO)
- @io = anIO
- @init_pos = anIO.pos
- end
-
- # Iterates through each entry in the data stream.
- def each(&block)
- each_entry(&block)
- end
-
- # Resets the read pointer to the beginning of data stream. Do not call
- # this during a #each or #each_entry iteration. This only works with
- # random access data streams that respond to #rewind and #pos.
- def rewind
- if @init_pos == 0
- raise NonSeekableStream unless @io.respond_to?(:rewind)
- @io.rewind
- else
- raise NonSeekableStream unless @io.respond_to?(:pos=)
- @io.pos = @init_pos
- end
- end
-
- # Iterates through each entry in the data stream.
- def each_entry
- loop do
- return if @io.eof?
-
- header = Archive::Tar::PosixHeader.new_from_stream(@io)
- return if header.empty?
-
- entry = EntryStream.new(header, @io)
- size = entry.size
-
- yield entry
-
- skip = (512 - (size % 512)) % 512
-
- if @io.respond_to?(:seek)
- # avoid reading...
- @io.seek(size - entry.bytes_read, IO::SEEK_CUR)
- else
- pending = size - entry.bytes_read
- while pending > 0
- bread = @io.read([pending, 4096].min).size
- raise UnexpectedEOF if @io.eof?
- pending -= bread
- end
- end
- @io.read(skip) # discard trailing zeros
- # make sure nobody can use #read, #getc or #rewind anymore
- entry.close
- end
- end
-
- def close
- end
- end
-
- # Wraps a Archive::Tar::Minitar::Reader with convenience methods and
- # wrapped stream management; Input only works with random access data
- # streams. See Input::new for details.
- class Input
- include Enumerable
-
- # With no associated block, +Input::open+ is a synonym for
- # +Input::new+. If the optional code block is given, it will be passed
- # the new _writer_ as an argument and the Input object will
- # automatically be closed when the block terminates. In this instance,
- # +Input::open+ returns the value of the block.
- def self.open(input)
- stream = Input.new(input)
- return stream unless block_given?
-
- begin
- res = yield stream
- ensure
- stream.close
- end
-
- res
- end
-
- # Creates a new Input object. If +input+ is a stream object that responds
- # to #read), then it will simply be wrapped. Otherwise, one will be
- # created and opened using Kernel#open. When Input#close is called, the
- # stream object wrapped will be closed.
- def initialize(input)
- if input.respond_to?(:read)
- @io = input
- else
- @io = open(input, "rb")
- end
- @tarreader = Archive::Tar::Minitar::Reader.new(@io)
- end
-
- # Iterates through each entry and rewinds to the beginning of the stream
- # when finished.
- def each(&block)
- @tarreader.each { |entry| yield entry }
- ensure
- @tarreader.rewind
- end
-
- # Extracts the current +entry+ to +destdir+. If a block is provided, it
- # yields an +action+ Symbol, the full name of the file being extracted
- # (+name+), and a Hash of statistical information (+stats+).
- #
- # The +action+ will be one of:
- # <tt>:dir</tt>:: The +entry+ is a directory.
- # <tt>:file_start</tt>:: The +entry+ is a file; the extract of the
- # file is just beginning.
- # <tt>:file_progress</tt>:: Yielded every 4096 bytes during the extract
- # of the +entry+.
- # <tt>:file_done</tt>:: Yielded when the +entry+ is completed.
- #
- # The +stats+ hash contains the following keys:
- # <tt>:current</tt>:: The current total number of bytes read in the
- # +entry+.
- # <tt>:currinc</tt>:: The current number of bytes read in this read
- # cycle.
- # <tt>:entry</tt>:: The entry being extracted; this is a
- # Reader::EntryStream, with all methods thereof.
- def extract_entry(destdir, entry) # :yields action, name, stats:
- stats = {
- :current => 0,
- :currinc => 0,
- :entry => entry
- }
-
- if entry.directory?
- dest = File.join(destdir, entry.full_name)
-
- yield :dir, entry.full_name, stats if block_given?
-
- if Archive::Tar::Minitar.dir?(dest)
- begin
- FileUtils.chmod(entry.mode, dest)
- rescue Exception
- nil
- end
- else
- FileUtils.mkdir_p(dest, :mode => entry.mode)
- FileUtils.chmod(entry.mode, dest)
- end
-
- fsync_dir(dest)
- fsync_dir(File.join(dest, ".."))
- return
- else # it's a file
- destdir = File.join(destdir, File.dirname(entry.full_name))
- FileUtils.mkdir_p(destdir, :mode => 0755)
-
- destfile = File.join(destdir, File.basename(entry.full_name))
- FileUtils.chmod(0600, destfile) rescue nil # Errno::ENOENT
-
- yield :file_start, entry.full_name, stats if block_given?
-
- File.open(destfile, "wb", entry.mode) do |os|
- loop do
- data = entry.read(4096)
- break unless data
-
- stats[:currinc] = os.write(data)
- stats[:current] += stats[:currinc]
-
- yield :file_progress, entry.full_name, stats if block_given?
- end
- os.fsync
- end
-
- FileUtils.chmod(entry.mode, destfile)
- fsync_dir(File.dirname(destfile))
- fsync_dir(File.join(File.dirname(destfile), ".."))
-
- yield :file_done, entry.full_name, stats if block_given?
- end
- end
-
- # Returns the Reader object for direct access.
- def tar
- @tarreader
- end
-
- # Closes the Reader object and the wrapped data stream.
- def close
- @io.close
- @tarreader.close
- end
-
- private
- def fsync_dir(dirname)
- # make sure this hits the disc
- dir = open(dirname, 'rb')
- dir.fsync
- rescue # ignore IOError if it's an unpatched (old) Ruby
- nil
- ensure
- dir.close if dir rescue nil
- end
- end
-
- # Wraps a Archive::Tar::Minitar::Writer with convenience methods and
- # wrapped stream management; Output only works with random access data
- # streams. See Output::new for details.
- class Output
- # With no associated block, +Output::open+ is a synonym for
- # +Output::new+. If the optional code block is given, it will be passed
- # the new _writer_ as an argument and the Output object will
- # automatically be closed when the block terminates. In this instance,
- # +Output::open+ returns the value of the block.
- def self.open(output)
- stream = Output.new(output)
- return stream unless block_given?
-
- begin
- res = yield stream
- ensure
- stream.close
- end
-
- res
- end
-
- # Creates a new Output object. If +output+ is a stream object that
- # responds to #read), then it will simply be wrapped. Otherwise, one will
- # be created and opened using Kernel#open. When Output#close is called,
- # the stream object wrapped will be closed.
- def initialize(output)
- if output.respond_to?(:write)
- @io = output
- else
- @io = ::File.open(output, "wb")
- end
- @tarwriter = Archive::Tar::Minitar::Writer.new(@io)
- end
-
- # Returns the Writer object for direct access.
- def tar
- @tarwriter
- end
-
- # Closes the Writer object and the wrapped data stream.
- def close
- @tarwriter.close
- @io.close
- end
- end
-
- class << self
- # Tests if +path+ refers to a directory. Fixes an apparently
- # corrupted <tt>stat()</tt> call on Windows.
- def dir?(path)
- File.directory?((path[-1] == ?/) ? path : "#{path}/")
- end
-
- # A convenience method for wrapping Archive::Tar::Minitar::Input.open
- # (mode +r+) and Archive::Tar::Minitar::Output.open (mode +w+). No other
- # modes are currently supported.
- def open(dest, mode = "r", &block)
- case mode
- when "r"
- Input.open(dest, &block)
- when "w"
- Output.open(dest, &block)
- else
- raise "Unknown open mode for Archive::Tar::Minitar.open."
- end
- end
-
- # A convenience method to packs the file provided. +entry+ may either be
- # a filename (in which case various values for the file (see below) will
- # be obtained from <tt>File#stat(entry)</tt> or a Hash with the fields:
- #
- # <tt>:name</tt>:: The filename to be packed into the tarchive.
- # *REQUIRED*.
- # <tt>:mode</tt>:: The mode to be applied.
- # <tt>:uid</tt>:: The user owner of the file. (Ignored on Windows.)
- # <tt>:gid</tt>:: The group owner of the file. (Ignored on Windows.)
- # <tt>:mtime</tt>:: The modification Time of the file.
- #
- # During packing, if a block is provided, #pack_file yields an +action+
- # Symol, the full name of the file being packed, and a Hash of
- # statistical information, just as with
- # Archive::Tar::Minitar::Input#extract_entry.
- #
- # The +action+ will be one of:
- # <tt>:dir</tt>:: The +entry+ is a directory.
- # <tt>:file_start</tt>:: The +entry+ is a file; the extract of the
- # file is just beginning.
- # <tt>:file_progress</tt>:: Yielded every 4096 bytes during the extract
- # of the +entry+.
- # <tt>:file_done</tt>:: Yielded when the +entry+ is completed.
- #
- # The +stats+ hash contains the following keys:
- # <tt>:current</tt>:: The current total number of bytes read in the
- # +entry+.
- # <tt>:currinc</tt>:: The current number of bytes read in this read
- # cycle.
- # <tt>:name</tt>:: The filename to be packed into the tarchive.
- # *REQUIRED*.
- # <tt>:mode</tt>:: The mode to be applied.
- # <tt>:uid</tt>:: The user owner of the file. (+nil+ on Windows.)
- # <tt>:gid</tt>:: The group owner of the file. (+nil+ on Windows.)
- # <tt>:mtime</tt>:: The modification Time of the file.
- def pack_file(entry, outputter) #:yields action, name, stats:
- outputter = outputter.tar if outputter.kind_of?(Archive::Tar::Minitar::Output)
-
- stats = {}
-
- if entry.kind_of?(Hash)
- name = entry[:name]
-
- entry.each { |kk, vv| opts[kk] = vv unless vv.nil? }
- else
- name = entry
- end
-
- name = name.sub(%r{\./}, '')
- stat = File.stat(name)
- stats[:mode] ||= stat.mode
- stats[:mtime] ||= stat.mtime
- stats[:size] = stat.size
-
- if RUBY_PLATFORM =~ /win32/
- stats[:uid] = nil
- stats[:gid] = nil
- else
- stats[:uid] ||= stat.uid
- stats[:gid] ||= stat.gid
- end
-
- case
- when File.file?(name)
- outputter.add_file_simple(name, stats) do |os|
- stats[:current] = 0
- yield :file_start, name, stats if block_given?
- File.open(name, "rb") do |ff|
- until ff.eof?
- stats[:currinc] = os.write(ff.read(4096))
- stats[:current] += stats[:currinc]
- yield :file_progress, name, stats if block_given?
- end
- end
- yield :file_done, name, stats if block_given?
- end
- when dir?(name)
- yield :dir, name, stats if block_given?
- outputter.mkdir(name, stats)
- else
- raise "Don't yet know how to pack this type of file."
- end
- end
-
- # A convenience method to pack files specified by +src+ into +dest+. If
- # +src+ is an Array, then each file detailed therein will be packed into
- # the resulting Archive::Tar::Minitar::Output stream; if +recurse_dirs+
- # is true, then directories will be recursed.
- #
- # If +src+ is an Array, it will be treated as the argument to Find.find;
- # all files matching will be packed.
- def pack(src, dest, recurse_dirs = true, &block)
- Output.open(dest) do |outp|
- if src.kind_of?(Array)
- src.each do |entry|
- pack_file(entry, outp, &block)
- if dir?(entry) and recurse_dirs
- Dir["#{entry}/**/**"].each do |ee|
- pack_file(ee, outp, &block)
- end
- end
- end
- else
- Find.find(src) do |entry|
- pack_file(entry, outp, &block)
- end
- end
- end
- end
-
- # A convenience method to unpack files from +src+ into the directory
- # specified by +dest+. Only those files named explicitly in +files+
- # will be extracted.
- def unpack(src, dest, files = [], &block)
- Input.open(src) do |inp|
- if File.exist?(dest) and (not dir?(dest))
- raise "Can't unpack to a non-directory."
- elsif not File.exist?(dest)
- FileUtils.mkdir_p(dest)
- end
-
- inp.each do |entry|
- if files.empty? or files.include?(entry.full_name)
- inp.extract_entry(dest, entry, &block)
- end
- end
- end
- end
- end
-end
diff --git a/tags/version_0_5_0/minitar/lib/archive/tar/minitar/command.rb b/tags/version_0_5_0/minitar/lib/archive/tar/minitar/command.rb
deleted file mode 100644
index fa65170..0000000
--- a/tags/version_0_5_0/minitar/lib/archive/tar/minitar/command.rb
+++ /dev/null
@@ -1,815 +0,0 @@
-#!/usr/bin/env ruby
-#--
-# Archive::Tar::Baby 0.5.0
-# Copyright © 2004 Mauricio Julio Fernández Pradier and Austin Ziegler
-# This is free software with ABSOLUTELY NO WARRANTY.
-#
-# This program is based on and incorporates parts of RPA::Package from
-# rpa-base (lib/rpa/package.rb and lib/rpa/util.rb) by Mauricio and has been
-# adapted to be more generic by Austin.
-#
-# This file contains an adaptation of Ruby/ProgressBar by Satoru
-# Takabayashi <satoru@namazu.org>, copyright © 2001 - 2004.
-#
-# It is licensed under the GNU General Public Licence or Ruby's licence.
-#
-# $Id$
-#++
-
-require 'zlib'
-
-# TODO: add
-# TODO: delete ???
-
-require 'optparse'
-require 'ostruct'
-require 'fileutils'
-
-module Archive::Tar::Minitar::Command
- class ProgressBar
- VERSION = "0.8"
-
- attr_accessor :total
- attr_accessor :title
-
- def initialize (title, total, out = STDERR)
- @title = title
- @total = total
- @out = out
- @bar_width = 80
- @bar_mark = "o"
- @current = 0
- @previous = 0
- @is_finished = false
- @start_time = Time.now
- @previous_time = @start_time
- @title_width = 14
- @format = "%-#{@title_width}s %3d%% %s %s"
- @format_arguments = [:title, :percentage, :bar, :stat]
- show
- end
-
- private
- def convert_bytes (bytes)
- if bytes < 1024
- sprintf("%6dB", bytes)
- elsif bytes < 1024 * 1000 # 1000kb
- sprintf("%5.1fKB", bytes.to_f / 1024)
- elsif bytes < 1024 * 1024 * 1000 # 1000mb
- sprintf("%5.1fMB", bytes.to_f / 1024 / 1024)
- else
- sprintf("%5.1fGB", bytes.to_f / 1024 / 1024 / 1024)
- end
- end
-
- def transfer_rate
- bytes_per_second = @current.to_f / (Time.now - @start_time)
- sprintf("%s/s", convert_bytes(bytes_per_second))
- end
-
- def bytes
- convert_bytes(@current)
- end
-
- def format_time (t)
- t = t.to_i
- sec = t % 60
- min = (t / 60) % 60
- hour = t / 3600
- sprintf("%02d:%02d:%02d", hour, min, sec);
- end
-
- # ETA stands for Estimated Time of Arrival.
- def eta
- if @current == 0
- "ETA: --:--:--"
- else
- elapsed = Time.now - @start_time
- eta = elapsed * @total / @current - elapsed;
- sprintf("ETA: %s", format_time(eta))
- end
- end
-
- def elapsed
- elapsed = Time.now - @start_time
- sprintf("Time: %s", format_time(elapsed))
- end
-
- def stat
- if @is_finished then elapsed else eta end
- end
-
- def stat_for_file_transfer
- if @is_finished then
- sprintf("%s %s %s", bytes, transfer_rate, elapsed)
- else
- sprintf("%s %s %s", bytes, transfer_rate, eta)
- end
- end
-
- def eol
- if @is_finished then "\n" else "\r" end
- end
-
- def bar
- len = percentage * @bar_width / 100
- sprintf("|%s%s|", @bar_mark * len, " " * (@bar_width - len))
- end
-
- def percentage(value = nil)
- if @total.zero?
- 100
- else
- (value || @current) * 100 / @total
- end
- end
-
- def title
- @title[0,(@title_width - 1)] + ":"
- end
-
- def get_width
- # FIXME: I don't know how portable it is.
- default_width = 80
- # begin
- # tiocgwinsz = 0x5413
- # data = [0, 0, 0, 0].pack("SSSS")
- # if @out.ioctl(tiocgwinsz, data) >= 0 then
- # rows, cols, xpixels, ypixels = data.unpack("SSSS")
- # if cols >= 0 then cols else default_width end
- # else
- # default_width
- # end
- # rescue Exception
- # default_width
- # end
- end
-
- def show
- arguments = @format_arguments.map {|method| send(method) }
- line = sprintf(@format, *arguments)
-
- width = get_width
- if line.length == width - 1
- @out.print(line + eol)
- elsif line.length >= width
- @bar_width = [@bar_width - (line.length - width + 1), 0].max
- if @bar_width == 0 then @out.print(line + eol) else show end
- else # line.length < width - 1
- @bar_width += width - line.length + 1
- show
- end
- @previous_time = Time.now
- end
-
- def show_progress
- if @total.zero?
- cur_percentage = 100
- prev_percentage = 0
- else
- cur_percentage = (@current * 100 / @total).to_i
- prev_percentage = (@previous * 100 / @total).to_i
- end
-
- if cur_percentage > prev_percentage ||
- Time.now - @previous_time >= 1 ||
- @is_finished
- show
- end
- end
-
- public
- def file_transfer_mode
- @format_arguments = [:title, :percentage, :bar, :stat_for_file_transfer]
- end
-
- def format= (format)
- @format = format
- end
-
- def format_arguments= (arguments)
- @format_arguments = arguments
- end
-
- def finish
- @current = @total
- @is_finished = true
- show_progress
- end
-
- def halt
- @is_finished = true
- show_progress
- end
-
- def set (count)
- if count < 0 || count > @total
- raise "invalid count: #{count} (total: #{@total})"
- end
- @current = count
- show_progress
- @previous = @current
- end
-
- def inc (step = 1)
- @current += step
- @current = @total if @current > @total
- show_progress
- @previous = @current
- end
-
- def inspect
- "(ProgressBar: #{@current}/#{@total})"
- end
- end
-
- class CommandPattern
- class AbstractCommandError < Exception; end
- class UnknownCommandError < RuntimeError; end
- class CommandAlreadyExists < RuntimeError; end
-
- class << self
- def add(command)
- command = command.new if command.kind_of?(Class)
-
- @commands ||= {}
- if @commands.has_key?(command.name)
- raise CommandAlreadyExists
- else
- @commands[command.name] = command
- end
-
- if command.respond_to?(:altname)
- unless @commands.has_key?(command.altname)
- @commands[command.altname] = command
- end
- end
- end
-
- def <<(command)
- add(command)
- end
-
- attr_accessor :default
- def default=(command) #:nodoc:
- if command.kind_of?(CommandPattern)
- @default = command
- elsif command.kind_of?(Class)
- @default = command.new
- elsif @commands.has_key?(command)
- @default = @commands[command]
- else
- raise UnknownCommandError
- end
- end
-
- def command?(command)
- @commands.has_key?(command)
- end
-
- def command(command)
- if command?(command)
- @commands[command]
- else
- @default
- end
- end
-
- def [](cmd)
- self.command(cmd)
- end
-
- def default_ioe(ioe = {})
- ioe[:input] ||= $stdin
- ioe[:output] ||= $stdout
- ioe[:error] ||= $stderr
- ioe
- end
- end
-
- def [](args, opts = {}, ioe = {})
- call(args, opts, ioe)
- end
-
- def name
- raise AbstractCommandError
- end
-
- def call(args, opts = {}, ioe = {})
- raise AbstractCommandError
- end
-
- def help
- raise AbstractCommandError
- end
-
- end
-
- class CommandHelp < CommandPattern
- def name
- "help"
- end
-
- def call(args, opts = {}, ioe = {})
- ioe = CommandPattern.default_ioe(ioe)
-
- help_on = args.shift
-
- if CommandPattern.command?(help_on)
- ioe[:output] << CommandPattern[help_on].help
- elsif help_on == "commands"
- ioe[:output] << <<-EOH
-The commands known to minitar are:
-
- minitar create Creates a new tarfile.
- minitar extract Extracts files from a tarfile.
- minitar list Lists files in the tarfile.
-
-All commands accept the options --verbose and --progress, which are
-mutually exclusive. In "minitar list", --progress means the same as
---verbose.
-
- --verbose, -V Performs the requested command verbosely.
- --progress, -P Shows a progress bar, if appropriate, for the action
- being performed.
-
- EOH
- else
- ioe[:output] << "Unknown command: #{help_on}\n" unless help_on.nil? or help_on.empty?
- ioe[:output] << self.help
- end
-
- 0
- end
-
- def help
- help = <<-EOH
-This is a basic help message containing pointers to more information on
-how to use this command-line tool. Try:
-
- minitar help commands list all 'minitar' commands
- minitar help <COMMAND> show help on <COMMAND>
- (e.g., 'minitar help create')
- EOH
- end
-# minitar add Adds a file to an existing tarfile.
-# minitar delete Deletes a file from an existing tarfile.
- end
-
- class CommandCreate < CommandPattern
- def name
- "create"
- end
-
- def altname
- "cr"
- end
-
- def call(args, opts = {}, ioe = {})
- argv = []
-
- while (arg = args.shift)
- case arg
- when '--compress', '-z'
- opts[:compress] = true
- else
- argv << arg
- end
- end
-
- if argv.size < 2
- ioe[:output] << "Not enough arguments.\n\n"
- CommandPattern["help"][["create"]]
- return 255
- end
-
- output = argv.shift
- if '-' == output
- opts[:name] = "STDOUT"
- output = ioe[:output]
- opts[:output] = ioe[:error]
- else
- opts[:name] = output
- output = File.open(output, "wb")
- opts[:output] = ioe[:output]
- end
-
- if opts[:name] =~ /\.tar\.gz$|\.tgz$/ or opts[:compress]
- output = Zlib::GzipWriter.new(output)
- end
-
- files = []
- if argv.include?("--")
- # Read stdin for the list of files.
- files = ""
- files << ioe[:input].read while not ioe[:input].eof?
- files = files.split(/\r\n|\n|\r/)
- args.delete("--")
- end
-
- files << argv.to_a
- files.flatten!
-
- if opts[:verbose]
- watcher = lambda do |action, name, stats|
- opts[:output] << "#{name}\n" if action == :dir or action == :file_done
- end
- finisher = lambda { opts[:output] << "\n" }
- elsif opts[:progress]
- progress = ProgressBar.new(opts[:name], 1)
- watcher = lambda do |action, name, stats|
- case action
- when :file_start, :dir
- progress.title = File.basename(name)
- if action == :dir
- progress.total += 1
- progress.inc
- else
- progress.total += stats[:size]
- end
- when :file_progress
- progress.inc(stats[:currinc])
- end
- end
- finisher = lambda do
- progress.title = opts[:name]
- progress.finish
- end
- else
- watcher = nil
- finisher = lambda { }
- end
-
- Archive::Tar::Minitar.pack(files, output, &watcher)
- finisher.call
- 0
- ensure
- output.close if output and not output.closed?
- end
-
- def help
- help = <<-EOH
- minitar create [OPTIONS] <tarfile|-> <file|directory|-->+
-
-Creates a new tarfile. If the tarfile is named .tar.gz or .tgz, then it
-will be compressed automatically. If the tarfile is "-", then it will be
-output to standard output (stdout) so that minitar may be piped.
-
-The files or directories that will be packed into the tarfile are
-specified after the name of the tarfile itself. Directories will be
-processed recursively. If the token "--" is found in the list of files
-to be packed, additional filenames will be read from standard input
-(stdin). If any file is not found, the packaging will be halted.
-
-create Options:
- --compress, -z Compresses the tarfile with gzip.
-
- EOH
- end
- end
-
- class CommandExtract < CommandPattern
- def name
- "extract"
- end
-
- def altname
- "ex"
- end
-
- def call(args, opts = {}, ioe = {})
- argv = []
- output = nil
- dest = "."
- files = []
-
- while (arg = args.shift)
- case arg
- when '--uncompress', '-z'
- opts[:uncompress] = true
- when '--pipe'
- opts[:output] = ioe[:error]
- output = ioe[:output]
- when '--output', '-o'
- dest = args.shift
- else
- argv << arg
- end
- end
-
- if argv.size < 1
- ioe[:output] << "Not enough arguments.\n\n"
- CommandPattern["help"][["extract"]]
- return 255
- end
-
- input = argv.shift
- if '-' == input
- opts[:name] = "STDIN"
- input = ioe[:input]
- else
- opts[:name] = input
- input = File.open(input, "rb")
- end
-
- if opts[:name] =~ /\.tar\.gz$|\.tgz$/ or opts[:uncompress]
- input = Zlib::GzipReader.new(input)
- end
-
- files << argv.to_a
- files.flatten!
-
- if opts[:verbose]
- watcher = lambda do |action, name, stats|
- opts[:output] << "#{name}\n" if action == :dir or action == :file_done
- end
- finisher = lambda { opts[:output] << "\n" }
- elsif opts[:progress]
- progress = ProgressBar.new(opts[:name], 1)
- watcher = lambda do |action, name, stats|
- case action
- when :file_start, :dir
- progress.title = File.basename(name)
- if action == :dir
- progress.total += 1
- progress.inc
- else
- progress.total += stats[:entry].size
- end
- when :file_progress
- progress.inc(stats[:currinc])
- end
- end
- finisher = lambda do
- progress.title = opts[:name]
- progress.finish
- end
- else
- watcher = nil
- finisher = lambda { }
- end
-
- if output.nil?
- Archive::Tar::Minitar.unpack(input, dest, files, &watcher)
- finisher.call
- else
- Archive::Tar::Minitar::Input.open(input) do |inp|
- inp.each do |entry|
- stats = {
- :mode => entry.mode,
- :mtime => entry.mtime,
- :size => entry.size,
- :gid => entry.gid,
- :uid => entry.uid,
- :current => 0,
- :currinc => 0,
- :entry => entry
- }
-
- if files.empty? or files.include?(entry.full_name)
- if entry.directory?
- puts "Directory: #{entry.full_name}"
- watcher[:dir, dest, stats] unless watcher.nil?
- else
- puts "File: #{entry.full_name}"
- watcher[:file_start, destfile, stats] unless watcher.nil?
- loop do
- data = entry.read(4096)
- break unless data
- stats[:currinc] = output.write(data)
- stats[:current] += stats[:currinc]
-
- watcher[:file_progress, name, stats] unless watcher.nil?
- end
- watcher[:file_done, name, stats] unless watcher.nil?
- end
- end
- end
- end
- end
-
- 0
- end
-
- def help
- help = <<-EOH
- minitar extract [OPTIONS] <tarfile|-> [<file>+]
-
-Extracts files from an existing tarfile. If the tarfile is named .tar.gz
-or .tgz, then it will be uncompressed automatically. If the tarfile is
-"-", then it will be read from standard input (stdin) so that minitar
-may be piped.
-
-The files or directories that will be extracted from the tarfile are
-specified after the name of the tarfile itself. Directories will be
-processed recursively. Files must be specified in full. A file
-"foo/bar/baz.txt" cannot simply be specified by specifying "baz.txt".
-Any file not found will simply be skipped and an error will be reported.
-
-extract Options:
- --uncompress, -z Uncompresses the tarfile with gzip.
- --pipe Emits the extracted files to STDOUT for piping.
- --output, -o Extracts the files to the specified directory.
-
- EOH
- end
- end
-
- class CommandList < CommandPattern
- def name
- "list"
- end
-
- def altname
- "ls"
- end
-
- def modestr(mode)
- s = "---"
- s[0] = ?r if (mode & 4) == 4
- s[1] = ?w if (mode & 2) == 2
- s[2] = ?x if (mode & 1) == 1
- s
- end
-
- def call(args, opts = {}, ioe = {})
- argv = []
- output = nil
- dest = "."
- files = []
- opts[:field] = "name"
-
- while (arg = args.shift)
- case arg
- when '--sort', '-S'
- opts[:sort] = true
- opts[:field] = args.shift
- when '--reverse', '-R'
- opts[:reverse] = true
- opts[:sort] = true
- when '--uncompress', '-z'
- opts[:uncompress] = true
- when '-l'
- opts[:verbose] = true
- else
- argv << arg
- end
- end
-
- if argv.size < 1
- ioe[:output] << "Not enough arguments.\n\n"
- CommandPattern["help"][["list"]]
- return 255
- end
-
- input = argv.shift
- if '-' == input
- opts[:name] = "STDIN"
- input = ioe[:input]
- else
- opts[:name] = input
- input = File.open(input, "rb")
- end
-
- if opts[:name] =~ /\.tar\.gz$|\.tgz$/ or opts[:uncompress]
- input = Zlib::GzipReader.new(input)
- end
-
- files << argv.to_a
- files.flatten!
-
- if opts[:verbose] or opts[:progress]
- format = "%10s %4d %8s %8s %8d %12s %s"
- datefmt = "%b %d %Y"
- timefmt = "%b %d %H:%M"
- fields = %w(permissions inodes user group size date fullname)
- else
- format = "%s"
- fields = %w(fullname)
- end
-
- opts[:field] = opts[:field].intern
- opts[:field] = :full_name if opts[:field] == :name
-
- output = []
-
- Archive::Tar::Minitar::Input.open(input) do |inp|
- today = Time.now
- oneyear = Time.mktime(today.year - 1, today.month, today.day)
- inp.each do |entry|
- value = format % fields.map do |ff|
- case ff
- when "permissions"
- s = entry.directory? ? "d" : "-"
- s << modestr(entry.mode / 0100)
- s << modestr(entry.mode / 0010)
- s << modestr(entry.mode)
- when "inodes"
- entry.size / 512
- when "user"
- entry.uname || entry.uid || 0
- when "group"
- entry.gname || entry.gid || 0
- when "size"
- entry.size
- when "date"
- if Time.at(entry.mtime) > (oneyear)
- Time.at(entry.mtime).strftime(timefmt)
- else
- Time.at(entry.mtime).strftime(datefmt)
- end
- when "fullname"
- entry.full_name
- end
- end
-
- if opts[:sort]
- output << [entry.send(opts[:field]), value]
- else
- ioe[:output] << value << "\n"
- end
-
- end
- end
-
- if opts[:sort]
- output = output.sort { |a, b| a[0] <=> b[0] }
- if opts[:reverse]
- output.reverse_each { |oo| ioe[:output] << oo[1] << "\n" }
- else
- output.each { |oo| ioe[:output] << oo[1] << "\n" }
- end
- end
-
- 0
- end
-
- def help
- help = <<-EOH
- minitar list [OPTIONS] <tarfile|-> [<file>+]
-
-Lists files in an existing tarfile. If the tarfile is named .tar.gz or
-.tgz, then it will be uncompressed automatically. If the tarfile is "-",
-then it will be read from standard input (stdin) so that minitar may be
-piped.
-
-If --verbose or --progress is specified, then the file list will be
-similar to that produced by the Unix command "ls -l".
-
-list Options:
- --uncompress, -z Uncompresses the tarfile with gzip.
- --sort [<FIELD>], -S Sorts the list of files by the specified
- field. The sort defaults to the filename.
- --reverse, -R Reverses the sort.
- -l Lists the files in detail.
-
-Sort Fields:
- name, mtime, size
-
- EOH
- end
- end
-
- CommandPattern << CommandHelp
- CommandPattern << CommandCreate
- CommandPattern << CommandExtract
- CommandPattern << CommandList
-# CommandPattern << CommandAdd
-# CommandPattern << CommandDelete
-
- def self.run(argv, input = $stdin, output = $stdout, error = $stderr)
- ioe = {
- :input => input,
- :output => output,
- :error => error,
- }
- opts = { }
-
- if argv.include?("--version")
- output << <<-EOB
-minitar #{Archive::Tar::Minitar::VERSION}
- Copyright 2004 Mauricio Julio Fernández Pradier and Austin Ziegler
- This is free software with ABSOLUTELY NO WARRANTY.
-
- see http://rubyforge.org/projects/ruwiki for more information
- EOB
- end
-
- if argv.include?("--verbose") or argv.include?("-V")
- opts[:verbose] = true
- argv.delete("--verbose")
- argv.delete("-V")
- end
-
- if argv.include?("--progress") or argv.include?("-P")
- opts[:progress] = true
- opts[:verbose] = false
- argv.delete("--progress")
- argv.delete("-P")
- end
-
- command = CommandPattern[(argv.shift or "").downcase]
- command ||= CommandPattern["help"]
- return command[argv, opts, ioe]
- end
-end
diff --git a/tags/version_0_5_0/minitar/tests/tc_tar.rb b/tags/version_0_5_0/minitar/tests/tc_tar.rb
deleted file mode 100644
index 542eea4..0000000
--- a/tags/version_0_5_0/minitar/tests/tc_tar.rb
+++ /dev/null
@@ -1,624 +0,0 @@
-#!/usr/bin/env ruby
-#--
-# Ruwiki version 0.8.0
-# Copyright © 2002 - 2004, Digikata and HaloStatue
-# Alan Chen (alan@digikata.com)
-# Austin Ziegler (ruwiki@halostatue.ca)
-#
-# Licensed under the same terms as Ruby.
-#
-# $Id$
-#++
-
-$LOAD_PATH.unshift("#{File.dirname(__FILE__)}/../lib") if __FILE__ == $0
-
-require 'archive/tar/minitar'
-require 'test/unit'
-require 'stringio'
-require 'yaml'
-require 'zlib'
-
-module TarTester
-private
- def assert_headers_equal(h1, h2)
- fields = %w(name 100 mode 8 uid 8 gid 8 size 12 mtime 12 checksum 8
- typeflag 1 linkname 100 magic 6 version 2 uname 32 gname 32
- devmajor 8 devminor 8 prefix 155)
- offset = 0
- until fields.empty?
- name = fields.shift
- length = fields.shift.to_i
- if name == "checksum"
- chksum_off = offset
- offset += length
- next
- end
- assert_equal(h1[offset, length], h2[offset, length],
- "Field #{name} of the tar header differs.")
- offset += length
- end
- assert_equal(h1[chksum_off, 8], h2[chksum_off, 8], "Checksumes differ.")
- end
-
- def tar_file_header(fname, dname, mode, length)
- h = header("0", fname, dname, length, mode)
- checksum = calc_checksum(h)
- header("0", fname, dname, length, mode, checksum)
- end
-
- def tar_dir_header(name, prefix, mode)
- h = header("5", name, prefix, 0, mode)
- checksum = calc_checksum(h)
- header("5", name, prefix, 0, mode, checksum)
- end
-
- def header(type, fname, dname, length, mode, checksum = nil)
- checksum ||= " " * 8
- arr = [ASCIIZ(fname, 100), Z(to_oct(mode, 7)), Z(to_oct(nil, 7)),
- Z(to_oct(nil, 7)), Z(to_oct(length, 11)), Z(to_oct(0, 11)),
- checksum, type, "\0" * 100, "ustar\0", "00", ASCIIZ("", 32),
- ASCIIZ("", 32), Z(to_oct(nil, 7)), Z(to_oct(nil, 7)),
- ASCIIZ(dname, 155) ]
- arr = arr.join("").split(//).map{ |x| x[0] }
- h = arr.pack("C100C8C8C8C12C12C8CC100C6C2C32C32C8C8C155")
- ret = h + "\0" * (512 - h.size)
- assert_equal(512, ret.size)
- ret
- end
-
- def calc_checksum(header)
- sum = header.unpack("C*").inject { |s, a| s + a }
- SP(Z(to_oct(sum, 6)))
- end
-
- def to_oct(n, pad_size)
- if n.nil?
- "\0" * pad_size
- else
- "%0#{pad_size}o" % n
- end
- end
-
- def ASCIIZ(str, length)
- str + "\0" * (length - str.length)
- end
-
- def SP(s)
- s + " "
- end
-
- def Z(s)
- s + "\0"
- end
-
- def SP_Z(s)
- s + " \0"
- end
-end
-
-class TC_Tar__Header < Test::Unit::TestCase
- include Archive::Tar::Minitar
- include TarTester
-
- def test_arguments_are_checked
- e = ArgumentError
- assert_raises(e) { Archive::Tar::PosixHeader.new(:name => "", :size => "", :mode => "") }
- assert_raises(e) { Archive::Tar::PosixHeader.new(:name => "", :size => "", :prefix => "") }
- assert_raises(e) { Archive::Tar::PosixHeader.new(:name => "", :prefix => "", :mode => "") }
- assert_raises(e) { Archive::Tar::PosixHeader.new(:prefix => "", :size => "", :mode => "") }
- end
-
- def test_basic_headers
- header = { :name => "bla", :mode => 012345, :size => 10, :prefix => "", :typeflag => "0" }
- assert_headers_equal(tar_file_header("bla", "", 012345, 10),
- Archive::Tar::PosixHeader.new(header).to_s)
- header = { :name => "bla", :mode => 012345, :size => 0, :prefix => "", :typeflag => "5" }
- assert_headers_equal(tar_dir_header("bla", "", 012345),
- Archive::Tar::PosixHeader.new(header).to_s)
- end
-
- def test_long_name_works
- header = { :name => "a" * 100, :mode => 012345, :size => 10, :prefix => "" }
- assert_headers_equal(tar_file_header("a" * 100, "", 012345, 10),
- Archive::Tar::PosixHeader.new(header).to_s)
- header = { :name => "a" * 100, :mode => 012345, :size => 10, :prefix => "bb" * 60 }
- assert_headers_equal(tar_file_header("a" * 100, "bb" * 60, 012345, 10),
- Archive::Tar::PosixHeader.new(header).to_s)
- end
-
- def test_new_from_stream
- header = tar_file_header("a" * 100, "", 012345, 10)
- h = nil
- header = StringIO.new(header)
- assert_nothing_raised { h = Archive::Tar::PosixHeader.new_from_stream(header) }
- assert_equal("a" * 100, h.name)
- assert_equal(012345, h.mode)
- assert_equal(10, h.size)
- assert_equal("", h.prefix)
- assert_equal("ustar", h.magic)
- end
-
- def test_new_from_stream_with_evil_name
- header = tar_file_header("a \0" + "\0" * 97, "", 012345, 10)
- h = nil
- header = StringIO.new(header)
- assert_nothing_raised{ h = Archive::Tar::PosixHeader.new_from_stream header }
- assert_equal("a ", h.name)
- end
-end
-
-class TC_Tar__Writer < Test::Unit::TestCase
- include Archive::Tar::Minitar
- include TarTester
-
- class DummyIO
- attr_reader :data
-
- def initialize
- @data = ""
- end
-
- def write(dat)
- data << dat
- dat.size
- end
-
- def reset
- @data = ""
- end
- end
-
- def setup
- @data = "a" * 10
- @dummyos = DummyIO.new
- @os = Writer.new(@dummyos)
- end
-
- def teardown
- @os.close
- end
-
- def test_add_file_simple
- @dummyos.reset
-
- Writer.open(@dummyos) do |os|
- os.add_file_simple("lib/foo/bar", :mode => 0644, :size => 10) do |f|
- f.write "a" * 10
- end
- os.add_file_simple("lib/bar/baz", :mode => 0644, :size => 100) do |f|
- f.write "fillme"
- end
- end
-
- assert_headers_equal(tar_file_header("lib/foo/bar", "", 0644, 10),
- @dummyos.data[0, 512])
- assert_equal("a" * 10 + "\0" * 502, @dummyos.data[512, 512])
- assert_headers_equal(tar_file_header("lib/bar/baz", "", 0644, 100),
- @dummyos.data[512 * 2, 512])
- assert_equal("fillme" + "\0" * 506, @dummyos.data[512 * 3, 512])
- assert_equal("\0" * 512, @dummyos.data[512 * 4, 512])
- assert_equal("\0" * 512, @dummyos.data[512 * 5, 512])
- end
-
- def test_write_operations_fail_after_closed
- @dummyos.reset
- @os.add_file_simple("sadd", :mode => 0644, :size => 20) { |f| }
- @os.close
- assert_raises(ClosedStream) { @os.flush }
- assert_raises(ClosedStream) { @os.add_file("dfdsf", :mode => 0644) {} }
- assert_raises(ClosedStream) { @os.mkdir "sdfdsf", :mode => 0644 }
- end
-
- def test_file_name_is_split_correctly
- # test insane file lengths, and: a{100}/b{155}, etc
- @dummyos.reset
- names = [ "#{'a' * 155}/#{'b' * 100}", "#{'a' * 151}/#{'qwer/' * 19}bla" ]
- o_names = [ "#{'b' * 100}", "#{'qwer/' * 19}bla" ]
- o_prefixes = [ "a" * 155, "a" * 151 ]
- names.each do |name|
- @os.add_file_simple(name, :mode => 0644, :size => 10) { }
- end
- o_names.each_with_index do |nam, i|
- assert_headers_equal(tar_file_header(nam, o_prefixes[i], 0644, 10),
- @dummyos.data[2 * i * 512, 512])
- end
- assert_raises(FileNameTooLong) do
- @os.add_file_simple(File.join("a" * 152, "b" * 10, "a" * 92),
- :mode => 0644, :size => 10) { }
- end
- assert_raises(FileNameTooLong) do
- @os.add_file_simple(File.join("a" * 162, "b" * 10),
- :mode => 0644, :size => 10) { }
- end
- assert_raises(FileNameTooLong) do
- @os.add_file_simple(File.join("a" * 10, "b" * 110),
- :mode => 0644, :size => 10) { }
- end
- end
-
- def test_add_file
- dummyos = StringIO.new
- class << dummyos
- def method_missing(meth, *a)
- self.string.send(meth, *a)
- end
- end
- os = Writer.new dummyos
- content1 = ('a'..'z').to_a.join("") # 26
- content2 = ('aa'..'zz').to_a.join("") # 1352
- Writer.open(dummyos) do |os|
- os.add_file("lib/foo/bar", :mode => 0644) { |f, opts| f.write "a" * 10 }
- os.add_file("lib/bar/baz", :mode => 0644) { |f, opts| f.write content1 }
- os.add_file("lib/bar/baz", :mode => 0644) { |f, opts| f.write content2 }
- os.add_file("lib/bar/baz", :mode => 0644) { |f, opts| }
- end
- assert_headers_equal(tar_file_header("lib/foo/bar", "", 0644, 10),
- dummyos[0, 512])
- assert_equal(%Q(#{"a" * 10}#{"\0" * 502}), dummyos[512, 512])
- offset = 512 * 2
- [content1, content2, ""].each do |data|
- assert_headers_equal(tar_file_header("lib/bar/baz", "", 0644,
- data.size), dummyos[offset, 512])
- offset += 512
- until !data || data == ""
- chunk = data[0, 512]
- data[0, 512] = ""
- assert_equal(chunk + "\0" * (512 - chunk.size),
- dummyos[offset, 512])
- offset += 512
- end
- end
- assert_equal("\0" * 1024, dummyos[offset, 1024])
- end
-
- def test_add_file_tests_seekability
- assert_raises(Archive::Tar::Minitar::NonSeekableStream) do
- @os.add_file("libdfdsfd", :mode => 0644) { |f| }
- end
- end
-
- def test_write_header
- @dummyos.reset
- @os.add_file_simple("lib/foo/bar", :mode => 0644, :size => 0) { |f| }
- @os.flush
- assert_headers_equal(tar_file_header("lib/foo/bar", "", 0644, 0),
- @dummyos.data[0, 512])
- @dummyos.reset
- @os.mkdir("lib/foo", :mode => 0644)
- assert_headers_equal(tar_dir_header("lib/foo", "", 0644),
- @dummyos.data[0, 512])
- @os.mkdir("lib/bar", :mode => 0644)
- assert_headers_equal(tar_dir_header("lib/bar", "", 0644),
- @dummyos.data[512 * 1, 512])
- end
-
- def test_write_data
- @dummyos.reset
- @os.add_file_simple("lib/foo/bar", :mode => 0644, :size => 10) do |f|
- f.write @data
- end
- @os.flush
- assert_equal(@data + ("\0" * (512-@data.size)),
- @dummyos.data[512, 512])
- end
-
- def test_file_size_is_checked
- @dummyos.reset
- assert_raises(Archive::Tar::Minitar::Writer::BoundedStream::FileOverflow) do
- @os.add_file_simple("lib/foo/bar", :mode => 0644, :size => 10) do |f|
- f.write "1" * 100
- end
- end
- assert_nothing_raised do
- @os.add_file_simple("lib/foo/bar", :mode => 0644, :size => 10) {|f| }
- end
- end
-end
-
-class TC_Tar__Reader < Test::Unit::TestCase
- include Archive::Tar::Minitar
- include TarTester
-
- def setup
- end
-
- def teardown
- end
-
- def test_multiple_entries
- str = tar_file_header("lib/foo", "", 010644, 10) + "\0" * 512
- str += tar_file_header("bar", "baz", 0644, 0)
- str += tar_dir_header("foo", "bar", 012345)
- str += "\0" * 1024
- names = %w[lib/foo bar foo]
- prefixes = ["", "baz", "bar"]
- modes = [010644, 0644, 012345]
- sizes = [10, 0, 0]
- isdir = [false, false, true]
- isfile = [true, true, false]
- Reader.new(StringIO.new(str)) do |is|
- i = 0
- is.each_entry do |entry|
- assert_kind_of(Reader::EntryStream, entry)
- assert_equal(names[i], entry.name)
- assert_equal(prefixes[i], entry.prefix)
- assert_equal(sizes[i], entry.size)
- assert_equal(modes[i], entry.mode)
- assert_equal(isdir[i], entry.directory?)
- assert_equal(isfile[i], entry.file?)
- if prefixes[i] != ""
- assert_equal(File.join(prefixes[i], names[i]), entry.full_name)
- else
- assert_equal(names[i], entry.name)
- end
- i += 1
- end
- assert_equal(names.size, i)
- end
- end
-
- def test_rewind_entry_works
- content = ('a'..'z').to_a.join(" ")
- str = tar_file_header("lib/foo", "", 010644, content.size) + content +
- "\0" * (512 - content.size)
- str << "\0" * 1024
- Reader.new(StringIO.new(str)) do |is|
- is.each_entry do |entry|
- 3.times do
- entry.rewind
- assert_equal(content, entry.read)
- assert_equal(content.size, entry.pos)
- end
- end
- end
- end
-
- def test_rewind_works
- content = ('a'..'z').to_a.join(" ")
- str = tar_file_header("lib/foo", "", 010644, content.size) + content +
- "\0" * (512 - content.size)
- str << "\0" * 1024
- Reader.new(StringIO.new(str)) do |is|
- 3.times do
- is.rewind
- i = 0
- is.each_entry do |entry|
- assert_equal(content, entry.read)
- i += 1
- end
- assert_equal(1, i)
- end
- end
- end
-
- def test_read_works
- contents = ('a'..'z').inject(""){|s, x| s << x * 100}
- str = tar_file_header("lib/foo", "", 010644, contents.size) + contents
- str += "\0" * (512 - (str.size % 512))
- Reader.new(StringIO.new(str)) do |is|
- is.each_entry do |entry|
- assert_kind_of(Reader::EntryStream, entry)
- data = entry.read(3000) # bigger than contents.size
- assert_equal(contents, data)
- assert_equal(true, entry.eof?)
- end
- end
- Reader.new(StringIO.new(str)) do |is|
- is.each_entry do |entry|
- assert_kind_of(Reader::EntryStream, entry)
- data = entry.read(100)
- (entry.size - data.size).times {|i| data << entry.getc.chr }
- assert_equal(contents, data)
- assert_equal(nil, entry.read(10))
- assert_equal(true, entry.eof?)
- end
- end
- Reader.new(StringIO.new(str)) do |is|
- is.each_entry do |entry|
- assert_kind_of(Reader::EntryStream, entry)
- data = entry.read
- assert_equal(contents, data)
- assert_equal(nil, entry.read(10))
- assert_equal(nil, entry.read)
- assert_equal(nil, entry.getc)
- assert_equal(true, entry.eof?)
- end
- end
- end
-
- def test_eof_works
- str = tar_file_header("bar", "baz", 0644, 0)
- Reader.new(StringIO.new(str)) do |is|
- is.each_entry do |entry|
- assert_kind_of(Reader::EntryStream, entry)
- data = entry.read
- assert_equal(nil, data)
- assert_equal(nil, entry.read(10))
- assert_equal(nil, entry.read)
- assert_equal(nil, entry.getc)
- assert_equal(true, entry.eof?)
- end
- end
- str = tar_dir_header("foo", "bar", 012345)
- Reader.new(StringIO.new(str)) do |is|
- is.each_entry do |entry|
- assert_kind_of(Reader::EntryStream, entry)
- data = entry.read
- assert_equal(nil, data)
- assert_equal(nil, entry.read(10))
- assert_equal(nil, entry.read)
- assert_equal(nil, entry.getc)
- assert_equal(true, entry.eof?)
- end
- end
- str = tar_dir_header("foo", "bar", 012345)
- str += tar_file_header("bar", "baz", 0644, 0)
- str += tar_file_header("bar", "baz", 0644, 0)
- Reader.new(StringIO.new(str)) do |is|
- is.each_entry do |entry|
- assert_kind_of(Reader::EntryStream, entry)
- data = entry.read
- assert_equal(nil, data)
- assert_equal(nil, entry.read(10))
- assert_equal(nil, entry.read)
- assert_equal(nil, entry.getc)
- assert_equal(true, entry.eof?)
- end
- end
- end
-end
-
-class TC_Tar__Input < Test::Unit::TestCase
- include Archive::Tar::Minitar
- include TarTester
-
- require 'rbconfig'
-
- TEST_TGZ = "\037\213\010\000\001B1A\000\vKI,I\324+I,\322K\257b\240\0250\000\002sSS\254\342 `dj\306``nnnbndbjd\000\0247336`P0\240\231\213\220@i1\320\367@+\351a\327 \004\362\335\034\f\313\034\r\035\031\270\337Ns\344b2\344q\335\375M\304\266QM1W\357\321>\221U\021\005\246\306\367\356\367u3\262;\212\004\265\236\\\334}\351,\377\037;\217\223\301e\247\030\024\\\236\211\277\347\346sii\265\010\330\355\234\240\362\274\371[\202\361\366\302S\316\335o&~m\237r\355\377\303\230\365\352WNW\334\266_\373\273\237\347Q\315t?\263{\377?\006\271\337?\367\207\325\346]\371\376y\307_\234~d\3772\265\346\261}\323\317\373\315\352\377O\376\271/\305\377?X\253\324\303S\373\361\347\277\372^)\267\377\363\03460\331\311\\wW|\031\203\300@\207\325p\004i\2319\251\3064\266\203P\376702B\313\377\246\246\006&\243\371\237\036 $#\263X\001\210@\351@\301XO\201\227k\240]4\nF\301(\030\005\243\200\036\000\000\004\330t\023\000\f\000\000"
- FILETIMES = Time.mktime(2004).to_i
-
- TEST_CONTENTS = [
- [ "data.tar.gz", 174, 0755 ],
- [ "file3", 18, 0755 ],
- ]
-
- TEST_DATA_CONTENTS = [
- [ "data", 0, 010644 ],
- [ "data/file1", 16, 010644 ],
- [ "data/file2", 16, 010644 ],
- [ "data/__dir__", 0, 010644 ],
- ]
-
- def setup
- FileUtils.mkdir_p("data__")
- end
-
- def teardown
- FileUtils.rm_rf("data__")
- end
-
- def test_each_works
- gzr = Zlib::GzipReader.new(StringIO.new(TEST_TGZ))
- Input.open(gzr) do |is|
- ii = 0
- is.each_with_index do |entry, ii|
- assert_kind_of(Reader::EntryStream, entry)
- assert_equal(TEST_CONTENTS[ii][0], entry.name)
- assert_equal(TEST_CONTENTS[ii][1], entry.size)
- assert_equal(TEST_CONTENTS[ii][2], entry.mode)
- assert_equal(FILETIMES, entry.mtime)
-
- if 0 == ii
- gzr2 = Zlib::GzipReader.new(StringIO.new(entry.read))
- Input.open(gzr2) do |is2|
- jj = 0
- is2.each_with_index do |entry2, jj|
- assert_kind_of(Reader::EntryStream, entry2)
- assert_equal(TEST_DATA_CONTENTS[jj][0], entry2.name)
- assert_equal(TEST_DATA_CONTENTS[jj][1], entry2.size)
- assert_equal(TEST_DATA_CONTENTS[jj][2], entry2.mode)
- assert_equal(FILETIMES, entry2.mtime)
- end
- assert_equal(3, jj)
- end
- end
- end
- assert_equal(1, ii)
- end
- end
-
- def test_extract_entry_works
- gzr = Zlib::GzipReader.new(StringIO.new(TEST_TGZ))
- Input.open(gzr) do |is|
- ii = 0
- is.each_with_index do |entry, ii|
- is.extract_entry("data__", entry)
- name = File.join("data__", entry.name)
-
- if entry.directory?
- assert(File.directory?(name))
- else
- assert(File.file?(name))
-
- assert_equal(TEST_CONTENTS[ii][1], File.stat(name).size)
- end
- assert_equal(TEST_CONTENTS[ii][2], File.stat(name).mode) unless RUBY_PLATFORM =~ /win32/
-
- if 0 == ii
- begin
- ff = File.open(name, "rb")
- gzr2 = Zlib::GzipReader.new(ff)
- Input.open(gzr2) do |is2|
- jj = 0
- is2.each_with_index do |entry2, jj|
- is2.extract_entry("data__", entry2)
- name2 = File.join("data__", entry2.name)
-
- if entry2.directory?
- assert(File.directory?(name2))
- else
- assert(File.file?(name2))
- assert_equal(TEST_DATA_CONTENTS[jj][1], File.stat(name2).size, name2)
- end
- assert_equal(TEST_DATA_CONTENTS[jj][2], File.stat(name2).mode, name2) unless RUBY_PLATFORM =~ /win32/
- end
- end
- ensure
- ff.close unless ff.closed?
- end
- end
- end
- assert_equal(1, ii)
- end
- end
-end
-
-class TC_Tar__Output < Test::Unit::TestCase
- include Archive::Tar::Minitar
- include TarTester
-
- def setup
- FileUtils.mkdir_p("data__")
- %w(a b c).each do |filename|
- name = File.join("data__", filename)
- File.open(name, "wb") { |f| f.puts "#{name}: 123456789012345678901234567890" }
- end
- @tarfile = "data__/bla2.tar"
- end
-
- def teardown
- FileUtils.rm_rf("data__")
- end
-
- def test_file_looks_good
- Output.open(@tarfile) do |os|
- Dir.chdir("data__") do
- %w(a b c).each do |name|
- stat = File.stat(name)
- opts = { :size => stat.size, :mode => 0644 }
- os.tar.add_file_simple(name, opts) do |ss|
- File.open(name, "rb") { |ff| ss.write(ff.read(4096)) until ff.eof? }
- end
- end
- end
- end
- ff = File.open(@tarfile, "rb")
- Reader.open(ff) do |is|
- ii = 0
- is.each do |entry|
- case ii
- when 0
- assert_equal("a", entry.name)
- when 1
- assert_equal("b", entry.name)
- when 2
- assert_equal("c", entry.name)
- end
- ii += 1
- end
- assert_equal(3, ii)
- end
- ensure
- ff.close if ff
- end
-end
diff --git a/tags/version_0_5_0/minitar/tests/testall.rb b/tags/version_0_5_0/minitar/tests/testall.rb
deleted file mode 100644
index 9c65d0f..0000000
--- a/tags/version_0_5_0/minitar/tests/testall.rb
+++ /dev/null
@@ -1,20 +0,0 @@
-#!/usr/bin/env ruby
-#--
-# Ruwiki version 0.8.0
-# Copyright © 2002 - 2003, Digikata and HaloStatue
-# Alan Chen (alan@digikata.com)
-# Austin Ziegler (ruwiki@halostatue.ca)
-#
-# Licensed under the same terms as Ruby.
-#
-# $Id$
-#++
-
-$LOAD_PATH.unshift("#{File.dirname(__FILE__)}/../lib") if __FILE__ == $0
-
-puts "Checking for test cases:"
-Dir['tc*.rb'].each do |testcase|
- puts "\t#{testcase}"
- require testcase
-end
-puts " "
diff --git a/tags/version_0_5_1/minitar/ChangeLog b/tags/version_0_5_1/minitar/ChangeLog
deleted file mode 100644
index df66842..0000000
--- a/tags/version_0_5_1/minitar/ChangeLog
+++ /dev/null
@@ -1,11 +0,0 @@
-Revision history for Ruby library Archive::Tar::Minitar. Unless explicitly
-noted otherwise, all changes are produced by Austin Ziegler
-<minitar@halostatue.ca>.
-
-== 0.5.1
-* Fixed a variable name error.
-
-== Archive::Tar::Minitar 0.5.0
-* Initial release. Does files and directories. Command does create, extract,
-* and list.
-
diff --git a/tags/version_0_5_1/minitar/Install b/tags/version_0_5_1/minitar/Install
deleted file mode 100644
index 1f75cee..0000000
--- a/tags/version_0_5_1/minitar/Install
+++ /dev/null
@@ -1,6 +0,0 @@
-Installing this package is as simple as:
-
-% ruby install.rb
-
-Alternatively, you can use the RubyGem version of Archive::Tar::Minitar
-available as archive-tar-minitar-0.5.1.gem from the usual sources.
diff --git a/tags/version_0_5_1/minitar/README b/tags/version_0_5_1/minitar/README
deleted file mode 100644
index 9c25a34..0000000
--- a/tags/version_0_5_1/minitar/README
+++ /dev/null
@@ -1,66 +0,0 @@
-Archive::Tar::Minitar README
-============================
-Archive::Tar::Minitar is a pure-Ruby library and command-line utility that
-provides the ability to deal with POSIX tar(1) archive files. The
-implementation is based heavily on Mauricio Fernández's implementation in
-rpa-base, but has been reorganised to promote reuse in other projects.
-
-This release is version 0.5.1, offering a bugfix over version 0.5.0. The
-library can only handle files and directories at this point. A future version
-will be expanded to handle symbolic links and hard links in a portable manner.
-The command line utility, minitar, can only create archives, extract from
-archives, and list archive contents.
-
-Using this library is easy. The simplest case is:
-
- require 'zlib'
- require 'archive/tar/minitar'
- include Archive::Tar
-
- # Packs everything that matches Find.find('tests')
- File.open('test.tar', 'wb') { |tar| Minitar.pack('tests', tar) }
- # Unpacks 'test.tar' to 'x', creating 'x' if necessary.
- Minitar.unpack('test.tar', 'x')
-
-A gzipped tar can be written with:
-
- tgz = Zlib::GzipWriter.new(File.open('test.tgz', 'wb'))
- # Warning: tgz will be closed!
- Minitar.pack('tests', tgz)
-
- tgz = Zlib::GzipReader.new(File.open('test.tgz', 'rb'))
- # Warning: tgz will be closed!
- Minitar.unpack(tgz, 'x')
-
-As the case above shows, one need not write to a file. However, it will
-sometimes require that one dive a little deeper into the API, as in the case
-of StringIO objects. Note that I'm not providing a block with Minitar::Output,
-as Minitar::Output#close automatically closes both the Output object and the
-wrapped data stream object.
-
- begin
- sgz = Zlib::GzipWriter.new(StringIO.new(""))
- tar = Output.new(sgz)
- Find.find('tests') do |entry|
- Minitar.pack_file(entry, tar)
- end
- ensure
- # Closes both tar and sgz.
- tar.close
- end
-
-Copyright
-=========
-# Copyright 2004 Mauricio Julio Fernández Pradier and Austin Ziegler
-#
-# This program is based on and incorporates parts of RPA::Package from
-# rpa-base (lib/rpa/package.rb and lib/rpa/util.rb) by Mauricio and has been
-# adapted to be more generic by Austin.
-#
-# 'minitar' contains an adaptation of Ruby/ProgressBar by Satoru
-# Takabayashi <satoru@namazu.org>, copyright © 2001 - 2004.
-#
-# This program is free software. It may be redistributed and/or modified
-# under the terms of the GPL version 2 (or later) or Ruby's licence.
-#
-# $Id$
diff --git a/tags/version_0_5_1/minitar/Rakefile b/tags/version_0_5_1/minitar/Rakefile
deleted file mode 100644
index 449f8c0..0000000
--- a/tags/version_0_5_1/minitar/Rakefile
+++ /dev/null
@@ -1,112 +0,0 @@
-#! /usr/bin/env rake
-$LOAD_PATH.unshift('lib')
-
-require 'rubygems'
-require 'rake/testtask'
-require 'rake/gempackagetask'
-require 'rake/contrib/rubyforgepublisher'
-require 'archive/tar/minitar'
-require 'zlib'
-
-DISTDIR = "archive-tar-minitar-#{Archive::Tar::Minitar::VERSION}"
-TARDIST = "../#{DISTDIR}.tar.gz"
-
-DATE_RE = %r<(\d{4})[./-]?(\d{2})[./-]?(\d{2})(?:[\sT]?(\d{2})[:.]?(\d{2})[:.]?(\d{2})?)?>
-
-if ENV['RELEASE_DATE']
- year, month, day, hour, minute, second = DATE_RE.match(ENV['RELEASE_DATE']).captures
- year ||= 0
- month ||= 0
- day ||= 0
- hour ||= 0
- minute ||= 0
- second ||= 0
- ReleaseDate = Time.mktime(year, month, day, hour, minute, second)
-else
- ReleaseDate = nil
-end
-
- # This rakefile must do the following:
- # 1. Run the unit tests, successfully.
- # 2. Modify the Readme.tarfile, Readme.rubygems, and data files to include
- # the proper version #.
- # 2. Create a package.
- # 3. Modify the existing pages so that properties!editable is set to
- # +false+.
- # 4.
-
-task :test do |t|
- require 'test/unit/testsuite'
- require 'test/unit/ui/console/testrunner'
-
- runner = Test::Unit::UI::Console::TestRunner
-
- $LOAD_PATH.unshift('tests')
- $stderr.puts "Checking for test cases:" if t.verbose
- Dir['tests/tc_*.rb'].each do |testcase|
- $stderr.puts "\t#{testcase}" if t.verbose
- load testcase
- end
-
- suite = Test::Unit::TestSuite.new
-
- ObjectSpace.each_object(Class) do |testcase|
- suite << testcase.suite if testcase < Test::Unit::TestCase
- end
-
- runner.run(suite)
-end
-
-spec = eval(File.read("archive-tar-minitar.gemspec"))
-desc "Build the RubyGem for Archive::Tar::Minitar."
-Rake::GemPackageTask.new(spec) do |g|
- g.need_tar = false
- g.need_zip = false
- g.package_dir = ".."
-end
-
-desc "Build an Archive::Tar::Minitar .tar.gz distribution."
-task :tar => [ TARDIST ]
-file TARDIST do |t|
- current = File.basename(Dir.pwd)
- Dir.chdir("..") do
- begin
- files = Dir["#{current}/**/*"].select { |dd| dd !~ %r{(?:/CVS/?|~$)} }
- files.map! do |dd|
- ddnew = dd.gsub(/^#{current}/, DISTDIR)
- mtime = ReleaseDate || File.stat(dd).mtime
- if File.directory?(dd)
- { :name => ddnew, :mode => 0555, :dir => true, :mtime => mtime }
- else
- if dd =~ %r{bin/}
- mode = 0755
- else
- mode = 0644
- end
- data = File.read(dd)
- { :name => ddnew, :mode => mode, :data => data, :size => data.size,
- :mtime => mtime }
- end
- end
-
- ff = File.open(t.name.gsub(%r{^\.\./}o, ''), "wb")
- gz = Zlib::GzipWriter.new(ff)
- tw = Archive::Tar::Minitar::Writer.new(gz)
-
- files.each do |entry|
- if entry[:dir]
- tw.mkdir(entry[:name], entry)
- else
- tw.add_file_simple(entry[:name], entry) { |os| os.write(entry[:data]) }
- end
- end
- ensure
- tw.close if tw
- gz.close if gz
- end
- end
-end
-
-desc "Build everything."
-task :default => [ :test, :tar, :gem ] do
-end
diff --git a/tags/version_0_5_1/minitar/bin/minitar b/tags/version_0_5_1/minitar/bin/minitar
deleted file mode 100644
index cfdf85e..0000000
--- a/tags/version_0_5_1/minitar/bin/minitar
+++ /dev/null
@@ -1,26 +0,0 @@
-#!/usr/bin/env ruby
-#--
-# Archive::Tar::Minitar 0.5.1
-# Copyright © 2004 Mauricio Julio Fernández Pradier and Austin Ziegler
-#
-# This program is based on and incorporates parts of RPA::Package from
-# rpa-base (lib/rpa/package.rb and lib/rpa/util.rb) by Mauricio and has been
-# adapted to be more generic by Austin.
-#
-# It is licensed under the GNU General Public Licence or Ruby's licence.
-#
-# $Id$
-#++
-
- # 1) Try to load Archive::Tar::Minitar from the gem.
- # 2) Try to load Archive::Tar::Minitar from $LOAD_PATH.
-begin
- require 'rubygems'
- require_gem 'archive-tar-minitar', '= 0.5.1'
-rescue LoadError
- require 'archive/tar/minitar'
-end
-
-require 'archive/tar/minitar/command'
-
-exit Archive::Tar::Minitar::Command.run(ARGV)
diff --git a/tags/version_0_5_1/minitar/install.rb b/tags/version_0_5_1/minitar/install.rb
deleted file mode 100644
index 4bd3d7a..0000000
--- a/tags/version_0_5_1/minitar/install.rb
+++ /dev/null
@@ -1,262 +0,0 @@
-#! /usr/bin/env ruby
-#--
-# Copyright 2004 Austin Ziegler <ruby-install@halostatue.ca>
-# Install utility. Based on the original installation script for rdoc by the
-# Pragmatic Programmers.
-#
-# This program is free software. It may be redistributed and/or modified under
-# the terms of the GPL version 2 (or later) or the Ruby licence.
-#
-# Usage
-# -----
-# In most cases, if you have a typical project layout, you will need to do
-# absolutely nothing to make this work for you. This layout is:
-#
-# bin/ # executable files -- "commands"
-# lib/ # the source of the library
-# tests/ # unit tests
-#
-# The default behaviour:
-# 1) Run all unit test files (ending in .rb) found in all directories under
-# tests/.
-# 2) Build Rdoc documentation from all files in bin/ (excluding .bat and .cmd),
-# all .rb files in lib/, ./README, ./ChangeLog, and ./Install.
-# 3) Build ri documentation from all files in bin/ (excluding .bat and .cmd),
-# and all .rb files in lib/. This is disabled by default on Win32.
-# 4) Install commands from bin/ into the Ruby bin directory. On Windows, if a
-# if a corresponding batch file (.bat or .cmd) exists in the bin directory,
-# it will be copied over as well. Otherwise, a batch file (always .bat) will
-# be created to run the specified command.
-# 5) Install all library files ending in .rb from lib/ into Ruby's
-# site_lib/version directory.
-#
-# $Id$
-#++
-
-require 'rbconfig'
-require 'find'
-require 'fileutils'
-require 'rdoc/rdoc'
-require 'optparse'
-require 'ostruct'
-
-InstallOptions = OpenStruct.new
-
-def glob(list)
- g = list.map { |i| Dir.glob(i) }
- g.flatten!
- g.compact!
- g.reject! { |e| e =~ /CVS/ }
- g
-end
-
- # Set these values to what you want installed.
-bins = glob(%w{bin/**/*}).reject { |e| e =~ /\.(bat|cmd)$/ }
-rdoc = glob(%w{bin/**/* lib/**/*.rb README ChangeLog Install}).reject { |e| e=~ /\.(bat|cmd)$/ }
-ri = glob(%w(bin/**/*.rb lib/**/*.rb)).reject { |e| e=~ /\.(bat|cmd)$/ }
-libs = glob(%w{lib/**/*.rb})
-tests = glob(%w{tests/**/*.rb})
-
-def do_bins(bins, target, strip = 'bin/')
- bins.each do |bf|
- obf = bf.gsub(/#{strip}/, '')
- install_binfile(bf, obf, target)
- end
-end
-
-def do_libs(libs, strip = 'lib/')
- libs.each do |lf|
- olf = File.join(InstallOptions.site_dir, lf.gsub(/#{strip}/, ''))
- op = File.dirname(olf)
- File.makedirs(op, true)
- File.chmod(0755, op)
- File.install(lf, olf, 0755, true)
- end
-end
-
-##
-# Prepare the file installation.
-#
-def prepare_installation
- InstallOptions.rdoc = true
- if RUBY_PLATFORM == "i386-mswin32"
- InstallOptions.ri = false
- else
- InstallOptions.ri = true
- end
- InstallOptions.tests = true
-
- ARGV.options do |opts|
- opts.banner = "Usage: #{File.basename($0)} [options]"
- opts.separator ""
- opts.on('--[no-]rdoc', 'Prevents the creation of RDoc output.', 'Default on.') do |onrdoc|
- InstallOptions.rdoc = onrdoc
- end
- opts.on('--[no-]ri', 'Prevents the creation of RI output.', 'Default off on mswin32.') do |onri|
- InstallOptions.ri = onri
- end
- opts.on('--[no-]tests', 'Prevents the execution of unit tests.', 'Default on.') do |ontest|
- InstallOptions.tests = ontest
- end
- opts.on('--quick', 'Performs a quick installation. Only the', 'installation is done.') do |quick|
- InstallOptions.rdoc = false
- InstallOptions.ri = false
- InstallOptions.tests = false
- end
- opts.on('--full', 'Performs a full installation. All', 'optional installation steps are run.') do |full|
- InstallOptions.rdoc = true
- InstallOptions.ri = true
- InstallOptions.tests = true
- end
- opts.separator("")
- opts.on_tail('--help', "Shows this help text.") do
- $stderr.puts opts
- exit
- end
-
- opts.parse!
- end
-
- bds = [".", ENV['TMP'], ENV['TEMP']]
-
- version = [Config::CONFIG["MAJOR"], Config::CONFIG["MINOR"]].join(".")
- ld = File.join(Config::CONFIG["libdir"], "ruby", version)
-
- sd = Config::CONFIG["sitelibdir"]
- if sd.nil?
- sd = $:.find { |x| x =~ /site_ruby/ }
- if sd.nil?
- sd = File.join(ld, "site_ruby")
- elsif sd !~ Regexp.quote(version)
- sd = File.join(sd, version)
- end
- end
-
- if (destdir = ENV['DESTDIR'])
- bd = "#{destdir}#{Config::CONFIG['bindir']}"
- sd = "#{destdir}#{sd}"
- bds << bd
-
- FileUtils.makedirs(bd)
- FileUtils.makedirs(sd)
- else
- bds << Config::CONFIG['bindir']
- end
-
- InstallOptions.bin_dirs = bds.compact
- InstallOptions.site_dir = sd
- InstallOptions.bin_dir = bd
- InstallOptions.lib_dir = ld
-end
-
-##
-# Build the rdoc documentation. Also, try to build the RI documentation.
-#
-def build_rdoc(files)
- r = RDoc::RDoc.new
- r.document(["--main", "README", "--title", "Diff::LCS -- A Diff Algorithm",
- "--line-numbers"] + files)
-
-rescue RDoc::RDocError => e
- $stderr.puts e.message
-rescue Exception => e
- $stderr.puts "Couldn't build RDoc documentation\n#{e.message}"
-end
-
-def build_ri(files)
- ri = RDoc::RDoc.new
- ri.document(["--ri-site", "--merge"] + files)
-rescue RDoc::RDocError => e
- $stderr.puts e.message
-rescue Exception => e
- $stderr.puts "Couldn't build Ri documentation\n#{e.message}"
-end
-
-def run_tests(test_list)
- require 'test/unit/ui/console/testrunner'
- $:.unshift "lib"
- test_list.each do |test|
- next if File.directory?(test)
- require test
- end
-
- tests = Test::Unit::TestSuite.new
- ObjectSpace.each_object(Class) { |o| tests << o.suite if o < Test::Unit::TestCase }
-
- Test::Unit::UI::Console::TestRunner.run(tests)
- $:.shift
-end
-
-##
-# Install file(s) from ./bin to Config::CONFIG['bindir']. Patch it on the way
-# to insert a #! line; on a Unix install, the command is named as expected
-# (e.g., bin/rdoc becomes rdoc); the shebang line handles running it. Under
-# windows, we add an '.rb' extension and let file associations do their stuff.
-def install_binfile(from, op_file, target)
- tmp_dir = nil
- InstallOptions.bin_dirs.each do |t|
- if File.directory?(t) and File.writable?(t)
- tmp_dir = t
- break
- end
- end
-
- fail "Cannot find a temporary directory" unless tmp_dir
- tmp_file = File.join(tmp_dir, '_tmp')
- ruby = File.join(Config::CONFIG['bindir'], Config::CONFIG['ruby_install_name'])
-
- File.open(from) do |ip|
- File.open(tmp_file, "w") do |op|
- ruby = File.join(Config::CONFIG['bindir'], Config::CONFIG['ruby_install_name'])
- op.puts "#!#{ruby}"
- op.write ip.read
- end
- end
-
- if Config::CONFIG["target_os"] =~ /win/io
- installed_wrapper = false
-
- if File.exists?("#{from}.bat")
- FileUtils.install("#{from}.bat", File.join(target, "#{op_file}.bat"), :mode => 0755, :verbose => true)
- installed_wrapper = true
- end
-
- if File.exists?("#{from}.cmd")
- FileUtils.install("#{from}.cmd", File.join(target, "#{op_file}.cmd"), :mode => 0755, :verbose => true)
- installed_wrapper = true
- end
-
- if not installed_wrapper
- tmp_file2 = File.join(tmp_dir, '_tmp_wrapper')
- cwn = File.join(Config::CONFIG['bindir'], op_file)
- cwv = CMD_WRAPPER.gsub('<ruby>', ruby.gsub(%r{/}) { "\\" }).gsub!('<command>', cwn.gsub(%r{/}) { "\\" } )
-
- File.open(tmp_file2, "wb") { |cw| cw.puts cwv }
- FileUtils.install(tmp_file2, File.join(target, "#{op_file}.bat"), :mode => 0755, :verbose => true)
-
- File.unlink(tmp_file2)
- installed_wrapper = true
- end
- end
- FileUtils.install(tmp_file, File.join(target, op_file), :mode => 0755, :verbose => true)
- File.unlink(tmp_file)
-end
-
-CMD_WRAPPER = <<-EOS
-@echo off
-if "%OS%"=="Windows_NT" goto WinNT
-<ruby> -x "<command>" %1 %2 %3 %4 %5 %6 %7 %8 %9
-goto done
-:WinNT
-<ruby> -x "<command>" %*
-goto done
-:done
-EOS
-
-prepare_installation
-
-run_tests(tests) if InstallOptions.tests
-build_rdoc(rdoc) if InstallOptions.rdoc
-build_ri(ri) if InstallOptions.ri
-do_bins(bins, Config::CONFIG['bindir'])
-do_libs(libs)
diff --git a/tags/version_0_5_1/minitar/lib/archive/tar/minitar.rb b/tags/version_0_5_1/minitar/lib/archive/tar/minitar.rb
deleted file mode 100644
index 7d381e7..0000000
--- a/tags/version_0_5_1/minitar/lib/archive/tar/minitar.rb
+++ /dev/null
@@ -1,979 +0,0 @@
-#!/usr/bin/env ruby
-#--
-# Archive::Tar::Minitar 0.5.1
-# Copyright © 2004 Mauricio Julio Fernández Pradier and Austin Ziegler
-#
-# This program is based on and incorporates parts of RPA::Package from
-# rpa-base (lib/rpa/package.rb and lib/rpa/util.rb) by Mauricio and has been
-# adapted to be more generic by Austin.
-#
-# It is licensed under the GNU General Public Licence or Ruby's licence.
-#
-# $Id$
-#++
-
-module Archive; end
-module Archive::Tar; end
-
- # = Archive::Tar::PosixHeader
- # Implements the POSIX tar header as a Ruby class. The structure of
- # the POSIX tar header is:
- #
- # struct tarfile_entry_posix
- # { // pack/unpack
- # char name[100]; // ASCII (+ Z unless filled) a100/Z100
- # char mode[8]; // 0 padded, octal, null a8 /A8
- # char uid[8]; // ditto a8 /A8
- # char gid[8]; // ditto a8 /A8
- # char size[12]; // 0 padded, octal, null a12 /A12
- # char mtime[12]; // 0 padded, octal, null a12 /A12
- # char checksum[8]; // 0 padded, octal, null, space a8 /A8
- # char typeflag[1]; // see below a /a
- # char linkname[100]; // ASCII + (Z unless filled) a100/Z100
- # char magic[6]; // "ustar\0" a6 /A6
- # char version[2]; // "00" a2 /A2
- # char uname[32]; // ASCIIZ a32 /Z32
- # char gname[32]; // ASCIIZ a32 /Z32
- # char devmajor[8]; // 0 padded, octal, null a8 /A8
- # char devminor[8]; // 0 padded, octal, null a8 /A8
- # char prefix[155]; // ASCII (+ Z unless filled) a155/Z155
- # };
- #
- # The +typeflag+ may be one of the following known values:
- #
- # <tt>"0"</tt>:: Regular file. NULL should be treated as a synonym, for
- # compatibility purposes.
- # <tt>"1"</tt>:: Hard link.
- # <tt>"2"</tt>:: Symbolic link.
- # <tt>"3"</tt>:: Character device node.
- # <tt>"4"</tt>:: Block device node.
- # <tt>"5"</tt>:: Directory.
- # <tt>"6"</tt>:: FIFO node.
- # <tt>"7"</tt>:: Reserved.
- #
- # POSIX indicates that "A POSIX-compliant implementation must treat any
- # unrecognized typeflag value as a regular file."
-class Archive::Tar::PosixHeader
- FIELDS = %w(name mode uid gid size mtime checksum typeflag linkname) +
- %w(magic version uname gname devmajor devminor prefix)
-
- FIELDS.each { |field| attr_reader field.intern }
-
- HEADER_PACK_FORMAT = "a100a8a8a8a12a12a7aaa100a6a2a32a32a8a8a155"
- HEADER_UNPACK_FORMAT = "Z100A8A8A8A12A12A8aZ100A6A2Z32Z32A8A8Z155"
-
- # Creates a new PosixHeader from a data stream.
- def self.new_from_stream(stream)
- data = stream.read(512)
- fields = data.unpack(HEADER_UNPACK_FORMAT)
- name = fields.shift
- mode = fields.shift.oct
- uid = fields.shift.oct
- gid = fields.shift.oct
- size = fields.shift.oct
- mtime = fields.shift.oct
- checksum = fields.shift.oct
- typeflag = fields.shift
- linkname = fields.shift
- magic = fields.shift
- version = fields.shift.oct
- uname = fields.shift
- gname = fields.shift
- devmajor = fields.shift.oct
- devminor = fields.shift.oct
- prefix = fields.shift
-
- empty = (data == "\0" * 512)
-
- new(:name => name, :mode => mode, :uid => uid, :gid => gid,
- :size => size, :mtime => mtime, :checksum => checksum,
- :typeflag => typeflag, :magic => magic, :version => version,
- :uname => uname, :gname => gname, :devmajor => devmajor,
- :devminor => devminor, :prefix => prefix, :empty => empty)
- end
-
- # Creates a new PosixHeader. A PosixHeader cannot be created unless the
- # #name, #size, #prefix, and #mode are provided.
- def initialize(vals)
- unless vals[:name] && vals[:size] && vals[:prefix] && vals[:mode]
- raise ArgumentError
- end
-
- vals[:mtime] ||= 0
- vals[:checksum] ||= ""
- vals[:typeflag] ||= "0"
- vals[:magic] ||= "ustar"
- vals[:version] ||= "00"
-
- FIELDS.each do |field|
- instance_variable_set("@#{field}", vals[field.intern])
- end
- @empty = vals[:empty]
- end
-
- def empty?
- @empty
- end
-
- def to_s
- update_checksum
- header(@checksum)
- end
-
- # Update the checksum field.
- def update_checksum
- hh = header(" " * 8)
- @checksum = oct(calculate_checksum(hh), 6)
- end
-
- private
- def oct(num, len)
- if num.nil?
- "\0" * (len + 1)
- else
- "%0#{len}o" % num
- end
- end
-
- def calculate_checksum(hdr)
- hdr.unpack("C*").inject { |aa, bb| aa + bb }
- end
-
- def header(chksum)
- arr = [name, oct(mode, 7), oct(uid, 7), oct(gid, 7), oct(size, 11),
- oct(mtime, 11), chksum, " ", typeflag, linkname, magic, version,
- uname, gname, oct(devmajor, 7), oct(devminor, 7), prefix]
- str = arr.pack(HEADER_PACK_FORMAT)
- str + "\0" * ((512 - str.size) % 512)
- end
-end
-
-require 'fileutils'
-require 'find'
-
- # = Archive::Tar::Minitar 0.5.1
- # Archive::Tar::Minitar is a pure-Ruby library and command-line
- # utility that provides the ability to deal with POSIX tar(1) archive
- # files. The implementation is based heavily on Mauricio Fernández's
- # implementation in rpa-base, but has been reorganised to promote
- # reuse in other projects.
- #
- # This tar class performs a subset of all tar (POSIX tape archive)
- # operations. We can only deal with typeflags 0, 1, 2, and 5 (see
- # Archive::Tar::PosixHeader). All other typeflags will be treated as
- # normal files.
- #
- # NOTE::: support for typeflags 1 and 2 is not yet implemented in this
- # version.
- #
- # This release is version 0.5.1. The library can only handle files and
- # directories at this point. A future version will be expanded to
- # handle symbolic links and hard links in a portable manner. The
- # command line utility, minitar, can only create archives, extract
- # from archives, and list archive contents.
- #
- # == Synopsis
- # Using this library is easy. The simplest case is:
- #
- # require 'zlib'
- # require 'archive/tar/minitar'
- # include Archive::Tar
- #
- # # Packs everything that matches Find.find('tests')
- # File.open('test.tar', 'wb') { |tar| Minitar.pack('tests', tar) }
- # # Unpacks 'test.tar' to 'x', creating 'x' if necessary.
- # Minitar.unpack('test.tar', 'x')
- #
- # A gzipped tar can be written with:
- #
- # tgz = Zlib::GzipWriter.new(File.open('test.tgz', 'wb'))
- # # Warning: tgz will be closed!
- # Minitar.pack('tests', tgz)
- #
- # tgz = Zlib::GzipReader.new(File.open('test.tgz', 'rb'))
- # # Warning: tgz will be closed!
- # Minitar.unpack(tgz, 'x')
- #
- # As the case above shows, one need not write to a file. However, it
- # will sometimes require that one dive a little deeper into the API,
- # as in the case of StringIO objects. Note that I'm not providing a
- # block with Minitar::Output, as Minitar::Output#close automatically
- # closes both the Output object and the wrapped data stream object.
- #
- # begin
- # sgz = Zlib::GzipWriter.new(StringIO.new(""))
- # tar = Output.new(sgz)
- # Find.find('tests') do |entry|
- # Minitar.pack_file(entry, tar)
- # end
- # ensure
- # # Closes both tar and sgz.
- # tar.close
- # end
- #
- # == Copyright
- # Copyright 2004 Mauricio Julio Fernández Pradier and Austin Ziegler
- #
- # This program is based on and incorporates parts of RPA::Package from
- # rpa-base (lib/rpa/package.rb and lib/rpa/util.rb) by Mauricio and
- # has been adapted to be more generic by Austin.
- #
- # 'minitar' contains an adaptation of Ruby/ProgressBar by Satoru
- # Takabayashi <satoru@namazu.org>, copyright © 2001 - 2004.
- #
- # This program is free software. It may be redistributed and/or
- # modified under the terms of the GPL version 2 (or later) or Ruby's
- # licence.
-module Archive::Tar::Minitar
- VERSION = "0.5.1"
-
- # The exception raised when a wrapped data stream class is expected to
- # respond to #rewind or #pos but does not.
- class NonSeekableStream < StandardError; end
- # The exception raised when a block is required for proper operation of
- # the method.
- class BlockRequired < ArgumentError; end
- # The exception raised when operations are performed on a stream that has
- # previously been closed.
- class ClosedStream < StandardError; end
- # The exception raised when a filename exceeds 256 bytes in length,
- # the maximum supported by the standard Tar format.
- class FileNameTooLong < StandardError; end
- # The exception raised when a data stream ends before the amount of data
- # expected in the archive's PosixHeader.
- class UnexpectedEOF < StandardError; end
-
- # The class that writes a tar format archive to a data stream.
- class Writer
- # A stream wrapper that can only be written to. Any attempt to read
- # from this restricted stream will result in a NameError being thrown.
- class RestrictedStream
- def initialize(anIO)
- @io = anIO
- end
-
- def write(data)
- @io.write(data)
- end
- end
-
- # A RestrictedStream that also has a size limit.
- class BoundedStream < Archive::Tar::Minitar::Writer::RestrictedStream
- # The exception raised when the user attempts to write more data to
- # a BoundedStream than has been allocated.
- class FileOverflow < RuntimeError; end
-
- # The maximum number of bytes that may be written to this data
- # stream.
- attr_reader :limit
- # The current total number of bytes written to this data stream.
- attr_reader :written
-
- def initialize(io, limit)
- @io = io
- @limit = limit
- @written = 0
- end
-
- def write(data)
- raise FileOverflow if (data.size + @written) > @limit
- @io.write(data)
- @written += data.size
- data.size
- end
- end
-
- # With no associated block, +Writer::open+ is a synonym for
- # +Writer::new+. If the optional code block is given, it will be
- # passed the new _writer_ as an argument and the Writer object will
- # automatically be closed when the block terminates. In this instance,
- # +Writer::open+ returns the value of the block.
- def self.open(anIO)
- writer = Writer.new(anIO)
-
- return writer unless block_given?
-
- begin
- res = yield writer
- ensure
- writer.close
- end
-
- res
- end
-
- # Creates and returns a new Writer object.
- def initialize(anIO)
- @io = anIO
- @closed = false
- end
-
- # Adds a file to the archive as +name+. +opts+ must contain the
- # following values:
- #
- # <tt>:mode</tt>:: The Unix file permissions mode value.
- # <tt>:size</tt>:: The size, in bytes.
- #
- # +opts+ may contain the following values:
- #
- # <tt>:uid</tt>: The Unix file owner user ID number.
- # <tt>:gid</tt>: The Unix file owner group ID number.
- # <tt>:mtime</tt>:: The *integer* modification time value.
- #
- # It will not be possible to add more than <tt>opts[:size]</tt> bytes
- # to the file.
- def add_file_simple(name, opts = {}) # :yields BoundedStream:
- raise Archive::Tar::Minitar::BlockRequired unless block_given?
- raise Archive::Tar::ClosedStream if @closed
-
- name, prefix = split_name(name)
-
- header = { :name => name, :mode => opts[:mode], :mtime => opts[:mtime],
- :size => opts[:size], :gid => opts[:gid], :uid => opts[:uid],
- :prefix => prefix }
- header = Archive::Tar::PosixHeader.new(header).to_s
- @io.write(header)
-
- os = BoundedStream.new(@io, opts[:size])
- yield os
- # FIXME: what if an exception is raised in the block?
-
- min_padding = opts[:size] - os.written
- @io.write("\0" * min_padding)
- remainder = (512 - (opts[:size] % 512)) % 512
- @io.write("\0" * remainder)
- end
-
- # Adds a file to the archive as +name+. +opts+ must contain the
- # following value:
- #
- # <tt>:mode</tt>:: The Unix file permissions mode value.
- #
- # +opts+ may contain the following values:
- #
- # <tt>:uid</tt>: The Unix file owner user ID number.
- # <tt>:gid</tt>: The Unix file owner group ID number.
- # <tt>:mtime</tt>:: The *integer* modification time value.
- #
- # The file's size will be determined from the amount of data written
- # to the stream.
- #
- # For #add_file to be used, the Archive::Tar::Minitar::Writer must be
- # wrapping a stream object that is seekable (e.g., it responds to
- # #pos=). Otherwise, #add_file_simple must be used.
- #
- # +opts+ may be modified during the writing to the stream.
- def add_file(name, opts = {}) # :yields RestrictedStream, +opts+:
- raise Archive::Tar::Minitar::BlockRequired unless block_given?
- raise Archive::Tar::Minitar::ClosedStream if @closed
- raise Archive::Tar::Minitar::NonSeekableStream unless @io.respond_to?(:pos=)
-
- name, prefix = split_name(name)
- init_pos = @io.pos
- @io.write("\0" * 512) # placeholder for the header
-
- yield RestrictedStream.new(@io), opts
- # FIXME: what if an exception is raised in the block?
-
- size = @io.pos - (init_pos + 512)
- remainder = (512 - (size % 512)) % 512
- @io.write("\0" * remainder)
-
- final_pos = @io.pos
- @io.pos = init_pos
-
- header = { :name => name, :mode => opts[:mode], :mtime => opts[:mtime],
- :size => size, :gid => opts[:gid], :uid => opts[:uid],
- :prefix => prefix }
- header = Archive::Tar::PosixHeader.new(header).to_s
- @io.write(header)
- @io.pos = final_pos
- end
-
- # Creates a directory in the tar.
- def mkdir(name, opts = {})
- raise ClosedStream if @closed
- name, prefix = split_name(name)
- header = { :name => name, :mode => opts[:mode], :typeflag => "5",
- :size => 0, :gid => opts[:gid], :uid => opts[:uid],
- :mtime => opts[:mtime], :prefix => prefix }
- header = Archive::Tar::PosixHeader.new(header).to_s
- @io.write(header)
- nil
- end
-
- # Passes the #flush method to the wrapped stream, used for buffered
- # streams.
- def flush
- raise ClosedStream if @closed
- @io.flush if @io.respond_to?(:flush)
- end
-
- # Closes the Writer.
- def close
- return if @closed
- @io.write("\0" * 1024)
- @closed = true
- end
-
- private
- def split_name(name)
- raise FileNameTooLong if name.size > 256
- if name.size <= 100
- prefix = ""
- else
- parts = name.split(/\//)
- newname = parts.pop
-
- nxt = ""
-
- loop do
- nxt = parts.pop
- break if newname.size + 1 + nxt.size > 100
- newname = "#{nxt}/#{newname}"
- end
-
- prefix = (parts + [nxt]).join("/")
-
- name = newname
-
- raise FileNameTooLong if name.size > 100 || prefix.size > 155
- end
- return name, prefix
- end
- end
-
- # The class that reads a tar format archive from a data stream. The data
- # stream may be sequential or random access, but certain features only work
- # with random access data streams.
- class Reader
- # This marks the EntryStream closed for reading without closing the
- # actual data stream.
- module InvalidEntryStream
- def read(len = nil); raise ClosedStream; end
- def getc; raise ClosedStream; end
- def rewind; raise ClosedStream; end
- end
-
- # EntryStreams are pseudo-streams on top of the main data stream.
- class EntryStream
- Archive::Tar::PosixHeader::FIELDS.each do |field|
- attr_reader field.intern
- end
-
- def initialize(header, anIO)
- @io = anIO
- @name = header.name
- @mode = header.mode
- @uid = header.uid
- @gid = header.gid
- @size = header.size
- @mtime = header.mtime
- @checksum = header.checksum
- @typeflag = header.typeflag
- @linkname = header.linkname
- @magic = header.magic
- @version = header.version
- @uname = header.uname
- @gname = header.gname
- @devmajor = header.devmajor
- @devminor = header.devminor
- @prefix = header.prefix
- @read = 0
- @orig_pos = @io.pos
- end
-
- # Reads +len+ bytes (or all remaining data) from the entry. Returns
- # +nil+ if there is no more data to read.
- def read(len = nil)
- return nil if @read >= @size
- len ||= @size - @read
- max_read = [len, @size - @read].min
- ret = @io.read(max_read)
- @read += ret.size
- ret
- end
-
- # Reads one byte from the entry. Returns +nil+ if there is no more data
- # to read.
- def getc
- return nil if @read >= @size
- ret = @io.getc
- @read += 1 if ret
- ret
- end
-
- # Returns +true+ if the entry represents a directory.
- def directory?
- @typeflag == "5"
- end
- alias_method :directory, :directory?
-
- # Returns +true+ if the entry represents a plain file.
- def file?
- @typeflag == "0"
- end
- alias_method :file, :file?
-
- # Returns +true+ if the current read pointer is at the end of the
- # EntryStream data.
- def eof?
- @read >= @size
- end
-
- # Returns the current read pointer in the EntryStream.
- def pos
- @read
- end
-
- # Sets the current read pointer to the beginning of the EntryStream.
- def rewind
- raise NonSeekableStream unless @io.respond_to?(:pos=)
- @io.pos = @orig_pos
- @read = 0
- end
-
- def bytes_read
- @read
- end
-
- # Returns the full and proper name of the entry.
- def full_name
- if @prefix != ""
- File.join(@prefix, @name)
- else
- @name
- end
- end
-
- # Closes the entry.
- def close
- invalidate
- end
-
- private
- def invalidate
- extend InvalidEntryStream
- end
- end
-
- # With no associated block, +Reader::open+ is a synonym for
- # +Reader::new+. If the optional code block is given, it will be passed
- # the new _writer_ as an argument and the Reader object will
- # automatically be closed when the block terminates. In this instance,
- # +Reader::open+ returns the value of the block.
- def self.open(anIO)
- reader = Reader.new(anIO)
-
- return reader unless block_given?
-
- begin
- res = yield reader
- ensure
- reader.close
- end
-
- res
- end
-
- # Creates and returns a new Reader object.
- def initialize(anIO)
- @io = anIO
- @init_pos = anIO.pos
- end
-
- # Iterates through each entry in the data stream.
- def each(&block)
- each_entry(&block)
- end
-
- # Resets the read pointer to the beginning of data stream. Do not call
- # this during a #each or #each_entry iteration. This only works with
- # random access data streams that respond to #rewind and #pos.
- def rewind
- if @init_pos == 0
- raise NonSeekableStream unless @io.respond_to?(:rewind)
- @io.rewind
- else
- raise NonSeekableStream unless @io.respond_to?(:pos=)
- @io.pos = @init_pos
- end
- end
-
- # Iterates through each entry in the data stream.
- def each_entry
- loop do
- return if @io.eof?
-
- header = Archive::Tar::PosixHeader.new_from_stream(@io)
- return if header.empty?
-
- entry = EntryStream.new(header, @io)
- size = entry.size
-
- yield entry
-
- skip = (512 - (size % 512)) % 512
-
- if @io.respond_to?(:seek)
- # avoid reading...
- @io.seek(size - entry.bytes_read, IO::SEEK_CUR)
- else
- pending = size - entry.bytes_read
- while pending > 0
- bread = @io.read([pending, 4096].min).size
- raise UnexpectedEOF if @io.eof?
- pending -= bread
- end
- end
- @io.read(skip) # discard trailing zeros
- # make sure nobody can use #read, #getc or #rewind anymore
- entry.close
- end
- end
-
- def close
- end
- end
-
- # Wraps a Archive::Tar::Minitar::Reader with convenience methods and
- # wrapped stream management; Input only works with random access data
- # streams. See Input::new for details.
- class Input
- include Enumerable
-
- # With no associated block, +Input::open+ is a synonym for
- # +Input::new+. If the optional code block is given, it will be passed
- # the new _writer_ as an argument and the Input object will
- # automatically be closed when the block terminates. In this instance,
- # +Input::open+ returns the value of the block.
- def self.open(input)
- stream = Input.new(input)
- return stream unless block_given?
-
- begin
- res = yield stream
- ensure
- stream.close
- end
-
- res
- end
-
- # Creates a new Input object. If +input+ is a stream object that responds
- # to #read), then it will simply be wrapped. Otherwise, one will be
- # created and opened using Kernel#open. When Input#close is called, the
- # stream object wrapped will be closed.
- def initialize(input)
- if input.respond_to?(:read)
- @io = input
- else
- @io = open(input, "rb")
- end
- @tarreader = Archive::Tar::Minitar::Reader.new(@io)
- end
-
- # Iterates through each entry and rewinds to the beginning of the stream
- # when finished.
- def each(&block)
- @tarreader.each { |entry| yield entry }
- ensure
- @tarreader.rewind
- end
-
- # Extracts the current +entry+ to +destdir+. If a block is provided, it
- # yields an +action+ Symbol, the full name of the file being extracted
- # (+name+), and a Hash of statistical information (+stats+).
- #
- # The +action+ will be one of:
- # <tt>:dir</tt>:: The +entry+ is a directory.
- # <tt>:file_start</tt>:: The +entry+ is a file; the extract of the
- # file is just beginning.
- # <tt>:file_progress</tt>:: Yielded every 4096 bytes during the extract
- # of the +entry+.
- # <tt>:file_done</tt>:: Yielded when the +entry+ is completed.
- #
- # The +stats+ hash contains the following keys:
- # <tt>:current</tt>:: The current total number of bytes read in the
- # +entry+.
- # <tt>:currinc</tt>:: The current number of bytes read in this read
- # cycle.
- # <tt>:entry</tt>:: The entry being extracted; this is a
- # Reader::EntryStream, with all methods thereof.
- def extract_entry(destdir, entry) # :yields action, name, stats:
- stats = {
- :current => 0,
- :currinc => 0,
- :entry => entry
- }
-
- if entry.directory?
- dest = File.join(destdir, entry.full_name)
-
- yield :dir, entry.full_name, stats if block_given?
-
- if Archive::Tar::Minitar.dir?(dest)
- begin
- FileUtils.chmod(entry.mode, dest)
- rescue Exception
- nil
- end
- else
- FileUtils.mkdir_p(dest, :mode => entry.mode)
- FileUtils.chmod(entry.mode, dest)
- end
-
- fsync_dir(dest)
- fsync_dir(File.join(dest, ".."))
- return
- else # it's a file
- destdir = File.join(destdir, File.dirname(entry.full_name))
- FileUtils.mkdir_p(destdir, :mode => 0755)
-
- destfile = File.join(destdir, File.basename(entry.full_name))
- FileUtils.chmod(0600, destfile) rescue nil # Errno::ENOENT
-
- yield :file_start, entry.full_name, stats if block_given?
-
- File.open(destfile, "wb", entry.mode) do |os|
- loop do
- data = entry.read(4096)
- break unless data
-
- stats[:currinc] = os.write(data)
- stats[:current] += stats[:currinc]
-
- yield :file_progress, entry.full_name, stats if block_given?
- end
- os.fsync
- end
-
- FileUtils.chmod(entry.mode, destfile)
- fsync_dir(File.dirname(destfile))
- fsync_dir(File.join(File.dirname(destfile), ".."))
-
- yield :file_done, entry.full_name, stats if block_given?
- end
- end
-
- # Returns the Reader object for direct access.
- def tar
- @tarreader
- end
-
- # Closes the Reader object and the wrapped data stream.
- def close
- @io.close
- @tarreader.close
- end
-
- private
- def fsync_dir(dirname)
- # make sure this hits the disc
- dir = open(dirname, 'rb')
- dir.fsync
- rescue # ignore IOError if it's an unpatched (old) Ruby
- nil
- ensure
- dir.close if dir rescue nil
- end
- end
-
- # Wraps a Archive::Tar::Minitar::Writer with convenience methods and
- # wrapped stream management; Output only works with random access data
- # streams. See Output::new for details.
- class Output
- # With no associated block, +Output::open+ is a synonym for
- # +Output::new+. If the optional code block is given, it will be passed
- # the new _writer_ as an argument and the Output object will
- # automatically be closed when the block terminates. In this instance,
- # +Output::open+ returns the value of the block.
- def self.open(output)
- stream = Output.new(output)
- return stream unless block_given?
-
- begin
- res = yield stream
- ensure
- stream.close
- end
-
- res
- end
-
- # Creates a new Output object. If +output+ is a stream object that
- # responds to #read), then it will simply be wrapped. Otherwise, one will
- # be created and opened using Kernel#open. When Output#close is called,
- # the stream object wrapped will be closed.
- def initialize(output)
- if output.respond_to?(:write)
- @io = output
- else
- @io = ::File.open(output, "wb")
- end
- @tarwriter = Archive::Tar::Minitar::Writer.new(@io)
- end
-
- # Returns the Writer object for direct access.
- def tar
- @tarwriter
- end
-
- # Closes the Writer object and the wrapped data stream.
- def close
- @tarwriter.close
- @io.close
- end
- end
-
- class << self
- # Tests if +path+ refers to a directory. Fixes an apparently
- # corrupted <tt>stat()</tt> call on Windows.
- def dir?(path)
- File.directory?((path[-1] == ?/) ? path : "#{path}/")
- end
-
- # A convenience method for wrapping Archive::Tar::Minitar::Input.open
- # (mode +r+) and Archive::Tar::Minitar::Output.open (mode +w+). No other
- # modes are currently supported.
- def open(dest, mode = "r", &block)
- case mode
- when "r"
- Input.open(dest, &block)
- when "w"
- Output.open(dest, &block)
- else
- raise "Unknown open mode for Archive::Tar::Minitar.open."
- end
- end
-
- # A convenience method to packs the file provided. +entry+ may either be
- # a filename (in which case various values for the file (see below) will
- # be obtained from <tt>File#stat(entry)</tt> or a Hash with the fields:
- #
- # <tt>:name</tt>:: The filename to be packed into the tarchive.
- # *REQUIRED*.
- # <tt>:mode</tt>:: The mode to be applied.
- # <tt>:uid</tt>:: The user owner of the file. (Ignored on Windows.)
- # <tt>:gid</tt>:: The group owner of the file. (Ignored on Windows.)
- # <tt>:mtime</tt>:: The modification Time of the file.
- #
- # During packing, if a block is provided, #pack_file yields an +action+
- # Symol, the full name of the file being packed, and a Hash of
- # statistical information, just as with
- # Archive::Tar::Minitar::Input#extract_entry.
- #
- # The +action+ will be one of:
- # <tt>:dir</tt>:: The +entry+ is a directory.
- # <tt>:file_start</tt>:: The +entry+ is a file; the extract of the
- # file is just beginning.
- # <tt>:file_progress</tt>:: Yielded every 4096 bytes during the extract
- # of the +entry+.
- # <tt>:file_done</tt>:: Yielded when the +entry+ is completed.
- #
- # The +stats+ hash contains the following keys:
- # <tt>:current</tt>:: The current total number of bytes read in the
- # +entry+.
- # <tt>:currinc</tt>:: The current number of bytes read in this read
- # cycle.
- # <tt>:name</tt>:: The filename to be packed into the tarchive.
- # *REQUIRED*.
- # <tt>:mode</tt>:: The mode to be applied.
- # <tt>:uid</tt>:: The user owner of the file. (+nil+ on Windows.)
- # <tt>:gid</tt>:: The group owner of the file. (+nil+ on Windows.)
- # <tt>:mtime</tt>:: The modification Time of the file.
- def pack_file(entry, outputter) #:yields action, name, stats:
- outputter = outputter.tar if outputter.kind_of?(Archive::Tar::Minitar::Output)
-
- stats = {}
-
- if entry.kind_of?(Hash)
- name = entry[:name]
-
- entry.each { |kk, vv| stats[kk] = vv unless vv.nil? }
- else
- name = entry
- end
-
- name = name.sub(%r{\./}, '')
- stat = File.stat(name)
- stats[:mode] ||= stat.mode
- stats[:mtime] ||= stat.mtime
- stats[:size] = stat.size
-
- if RUBY_PLATFORM =~ /win32/
- stats[:uid] = nil
- stats[:gid] = nil
- else
- stats[:uid] ||= stat.uid
- stats[:gid] ||= stat.gid
- end
-
- case
- when File.file?(name)
- outputter.add_file_simple(name, stats) do |os|
- stats[:current] = 0
- yield :file_start, name, stats if block_given?
- File.open(name, "rb") do |ff|
- until ff.eof?
- stats[:currinc] = os.write(ff.read(4096))
- stats[:current] += stats[:currinc]
- yield :file_progress, name, stats if block_given?
- end
- end
- yield :file_done, name, stats if block_given?
- end
- when dir?(name)
- yield :dir, name, stats if block_given?
- outputter.mkdir(name, stats)
- else
- raise "Don't yet know how to pack this type of file."
- end
- end
-
- # A convenience method to pack files specified by +src+ into +dest+. If
- # +src+ is an Array, then each file detailed therein will be packed into
- # the resulting Archive::Tar::Minitar::Output stream; if +recurse_dirs+
- # is true, then directories will be recursed.
- #
- # If +src+ is an Array, it will be treated as the argument to Find.find;
- # all files matching will be packed.
- def pack(src, dest, recurse_dirs = true, &block)
- Output.open(dest) do |outp|
- if src.kind_of?(Array)
- src.each do |entry|
- pack_file(entry, outp, &block)
- if dir?(entry) and recurse_dirs
- Dir["#{entry}/**/**"].each do |ee|
- pack_file(ee, outp, &block)
- end
- end
- end
- else
- Find.find(src) do |entry|
- pack_file(entry, outp, &block)
- end
- end
- end
- end
-
- # A convenience method to unpack files from +src+ into the directory
- # specified by +dest+. Only those files named explicitly in +files+
- # will be extracted.
- def unpack(src, dest, files = [], &block)
- Input.open(src) do |inp|
- if File.exist?(dest) and (not dir?(dest))
- raise "Can't unpack to a non-directory."
- elsif not File.exist?(dest)
- FileUtils.mkdir_p(dest)
- end
-
- inp.each do |entry|
- if files.empty? or files.include?(entry.full_name)
- inp.extract_entry(dest, entry, &block)
- end
- end
- end
- end
- end
-end
diff --git a/tags/version_0_5_1/minitar/lib/archive/tar/minitar/command.rb b/tags/version_0_5_1/minitar/lib/archive/tar/minitar/command.rb
deleted file mode 100644
index fe9ae8b..0000000
--- a/tags/version_0_5_1/minitar/lib/archive/tar/minitar/command.rb
+++ /dev/null
@@ -1,814 +0,0 @@
-#!/usr/bin/env ruby
-#--
-# Archive::Tar::Baby 0.5.1
-# Copyright © 2004 Mauricio Julio Fernández Pradier and Austin Ziegler
-# This is free software with ABSOLUTELY NO WARRANTY.
-#
-# This program is based on and incorporates parts of RPA::Package from
-# rpa-base (lib/rpa/package.rb and lib/rpa/util.rb) by Mauricio and has been
-# adapted to be more generic by Austin.
-#
-# This file contains an adaptation of Ruby/ProgressBar by Satoru
-# Takabayashi <satoru@namazu.org>, copyright © 2001 - 2004.
-#
-# It is licensed under the GNU General Public Licence or Ruby's licence.
-#
-# $Id$
-#++
-
-require 'zlib'
-
-# TODO: add
-# TODO: delete ???
-
-require 'optparse'
-require 'ostruct'
-require 'fileutils'
-
-module Archive::Tar::Minitar::Command
- class ProgressBar
- VERSION = "0.8"
-
- attr_accessor :total
- attr_accessor :title
-
- def initialize (title, total, out = STDERR)
- @title = title
- @total = total
- @out = out
- @bar_width = 80
- @bar_mark = "o"
- @current = 0
- @previous = 0
- @is_finished = false
- @start_time = Time.now
- @previous_time = @start_time
- @title_width = 14
- @format = "%-#{@title_width}s %3d%% %s %s"
- @format_arguments = [:title, :percentage, :bar, :stat]
- show
- end
-
- private
- def convert_bytes (bytes)
- if bytes < 1024
- sprintf("%6dB", bytes)
- elsif bytes < 1024 * 1000 # 1000kb
- sprintf("%5.1fKB", bytes.to_f / 1024)
- elsif bytes < 1024 * 1024 * 1000 # 1000mb
- sprintf("%5.1fMB", bytes.to_f / 1024 / 1024)
- else
- sprintf("%5.1fGB", bytes.to_f / 1024 / 1024 / 1024)
- end
- end
-
- def transfer_rate
- bytes_per_second = @current.to_f / (Time.now - @start_time)
- sprintf("%s/s", convert_bytes(bytes_per_second))
- end
-
- def bytes
- convert_bytes(@current)
- end
-
- def format_time (t)
- t = t.to_i
- sec = t % 60
- min = (t / 60) % 60
- hour = t / 3600
- sprintf("%02d:%02d:%02d", hour, min, sec);
- end
-
- # ETA stands for Estimated Time of Arrival.
- def eta
- if @current == 0
- "ETA: --:--:--"
- else
- elapsed = Time.now - @start_time
- eta = elapsed * @total / @current - elapsed;
- sprintf("ETA: %s", format_time(eta))
- end
- end
-
- def elapsed
- elapsed = Time.now - @start_time
- sprintf("Time: %s", format_time(elapsed))
- end
-
- def stat
- if @is_finished then elapsed else eta end
- end
-
- def stat_for_file_transfer
- if @is_finished then
- sprintf("%s %s %s", bytes, transfer_rate, elapsed)
- else
- sprintf("%s %s %s", bytes, transfer_rate, eta)
- end
- end
-
- def eol
- if @is_finished then "\n" else "\r" end
- end
-
- def bar
- len = percentage * @bar_width / 100
- sprintf("|%s%s|", @bar_mark * len, " " * (@bar_width - len))
- end
-
- def percentage(value = nil)
- if @total.zero?
- 100
- else
- (value || @current) * 100 / @total
- end
- end
-
- def title
- @title[0,(@title_width - 1)] + ":"
- end
-
- def get_width
- # FIXME: I don't know how portable it is.
- default_width = 80
- # begin
- # tiocgwinsz = 0x5413
- # data = [0, 0, 0, 0].pack("SSSS")
- # if @out.ioctl(tiocgwinsz, data) >= 0 then
- # rows, cols, xpixels, ypixels = data.unpack("SSSS")
- # if cols >= 0 then cols else default_width end
- # else
- # default_width
- # end
- # rescue Exception
- # default_width
- # end
- end
-
- def show
- arguments = @format_arguments.map {|method| send(method) }
- line = sprintf(@format, *arguments)
-
- width = get_width
- if line.length == width - 1
- @out.print(line + eol)
- elsif line.length >= width
- @bar_width = [@bar_width - (line.length - width + 1), 0].max
- if @bar_width == 0 then @out.print(line + eol) else show end
- else # line.length < width - 1
- @bar_width += width - line.length + 1
- show
- end
- @previous_time = Time.now
- end
-
- def show_progress
- if @total.zero?
- cur_percentage = 100
- prev_percentage = 0
- else
- cur_percentage = (@current * 100 / @total).to_i
- prev_percentage = (@previous * 100 / @total).to_i
- end
-
- if cur_percentage > prev_percentage ||
- Time.now - @previous_time >= 1 ||
- @is_finished
- show
- end
- end
-
- public
- def file_transfer_mode
- @format_arguments = [:title, :percentage, :bar, :stat_for_file_transfer]
- end
-
- def format= (format)
- @format = format
- end
-
- def format_arguments= (arguments)
- @format_arguments = arguments
- end
-
- def finish
- @current = @total
- @is_finished = true
- show_progress
- end
-
- def halt
- @is_finished = true
- show_progress
- end
-
- def set (count)
- if count < 0 || count > @total
- raise "invalid count: #{count} (total: #{@total})"
- end
- @current = count
- show_progress
- @previous = @current
- end
-
- def inc (step = 1)
- @current += step
- @current = @total if @current > @total
- show_progress
- @previous = @current
- end
-
- def inspect
- "(ProgressBar: #{@current}/#{@total})"
- end
- end
-
- class CommandPattern
- class AbstractCommandError < Exception; end
- class UnknownCommandError < RuntimeError; end
- class CommandAlreadyExists < RuntimeError; end
-
- class << self
- def add(command)
- command = command.new if command.kind_of?(Class)
-
- @commands ||= {}
- if @commands.has_key?(command.name)
- raise CommandAlreadyExists
- else
- @commands[command.name] = command
- end
-
- if command.respond_to?(:altname)
- unless @commands.has_key?(command.altname)
- @commands[command.altname] = command
- end
- end
- end
-
- def <<(command)
- add(command)
- end
-
- attr_accessor :default
- def default=(command) #:nodoc:
- if command.kind_of?(CommandPattern)
- @default = command
- elsif command.kind_of?(Class)
- @default = command.new
- elsif @commands.has_key?(command)
- @default = @commands[command]
- else
- raise UnknownCommandError
- end
- end
-
- def command?(command)
- @commands.has_key?(command)
- end
-
- def command(command)
- if command?(command)
- @commands[command]
- else
- @default
- end
- end
-
- def [](cmd)
- self.command(cmd)
- end
-
- def default_ioe(ioe = {})
- ioe[:input] ||= $stdin
- ioe[:output] ||= $stdout
- ioe[:error] ||= $stderr
- ioe
- end
- end
-
- def [](args, opts = {}, ioe = {})
- call(args, opts, ioe)
- end
-
- def name
- raise AbstractCommandError
- end
-
- def call(args, opts = {}, ioe = {})
- raise AbstractCommandError
- end
-
- def help
- raise AbstractCommandError
- end
- end
-
- class CommandHelp < CommandPattern
- def name
- "help"
- end
-
- def call(args, opts = {}, ioe = {})
- ioe = CommandPattern.default_ioe(ioe)
-
- help_on = args.shift
-
- if CommandPattern.command?(help_on)
- ioe[:output] << CommandPattern[help_on].help
- elsif help_on == "commands"
- ioe[:output] << <<-EOH
-The commands known to minitar are:
-
- minitar create Creates a new tarfile.
- minitar extract Extracts files from a tarfile.
- minitar list Lists files in the tarfile.
-
-All commands accept the options --verbose and --progress, which are
-mutually exclusive. In "minitar list", --progress means the same as
---verbose.
-
- --verbose, -V Performs the requested command verbosely.
- --progress, -P Shows a progress bar, if appropriate, for the action
- being performed.
-
- EOH
- else
- ioe[:output] << "Unknown command: #{help_on}\n" unless help_on.nil? or help_on.empty?
- ioe[:output] << self.help
- end
-
- 0
- end
-
- def help
- help = <<-EOH
-This is a basic help message containing pointers to more information on
-how to use this command-line tool. Try:
-
- minitar help commands list all 'minitar' commands
- minitar help <COMMAND> show help on <COMMAND>
- (e.g., 'minitar help create')
- EOH
- end
-# minitar add Adds a file to an existing tarfile.
-# minitar delete Deletes a file from an existing tarfile.
- end
-
- class CommandCreate < CommandPattern
- def name
- "create"
- end
-
- def altname
- "cr"
- end
-
- def call(args, opts = {}, ioe = {})
- argv = []
-
- while (arg = args.shift)
- case arg
- when '--compress', '-z'
- opts[:compress] = true
- else
- argv << arg
- end
- end
-
- if argv.size < 2
- ioe[:output] << "Not enough arguments.\n\n"
- CommandPattern["help"][["create"]]
- return 255
- end
-
- output = argv.shift
- if '-' == output
- opts[:name] = "STDOUT"
- output = ioe[:output]
- opts[:output] = ioe[:error]
- else
- opts[:name] = output
- output = File.open(output, "wb")
- opts[:output] = ioe[:output]
- end
-
- if opts[:name] =~ /\.tar\.gz$|\.tgz$/ or opts[:compress]
- output = Zlib::GzipWriter.new(output)
- end
-
- files = []
- if argv.include?("--")
- # Read stdin for the list of files.
- files = ""
- files << ioe[:input].read while not ioe[:input].eof?
- files = files.split(/\r\n|\n|\r/)
- args.delete("--")
- end
-
- files << argv.to_a
- files.flatten!
-
- if opts[:verbose]
- watcher = lambda do |action, name, stats|
- opts[:output] << "#{name}\n" if action == :dir or action == :file_done
- end
- finisher = lambda { opts[:output] << "\n" }
- elsif opts[:progress]
- progress = ProgressBar.new(opts[:name], 1)
- watcher = lambda do |action, name, stats|
- case action
- when :file_start, :dir
- progress.title = File.basename(name)
- if action == :dir
- progress.total += 1
- progress.inc
- else
- progress.total += stats[:size]
- end
- when :file_progress
- progress.inc(stats[:currinc])
- end
- end
- finisher = lambda do
- progress.title = opts[:name]
- progress.finish
- end
- else
- watcher = nil
- finisher = lambda { }
- end
-
- Archive::Tar::Minitar.pack(files, output, &watcher)
- finisher.call
- 0
- ensure
- output.close if output and not output.closed?
- end
-
- def help
- help = <<-EOH
- minitar create [OPTIONS] <tarfile|-> <file|directory|-->+
-
-Creates a new tarfile. If the tarfile is named .tar.gz or .tgz, then it
-will be compressed automatically. If the tarfile is "-", then it will be
-output to standard output (stdout) so that minitar may be piped.
-
-The files or directories that will be packed into the tarfile are
-specified after the name of the tarfile itself. Directories will be
-processed recursively. If the token "--" is found in the list of files
-to be packed, additional filenames will be read from standard input
-(stdin). If any file is not found, the packaging will be halted.
-
-create Options:
- --compress, -z Compresses the tarfile with gzip.
-
- EOH
- end
- end
-
- class CommandExtract < CommandPattern
- def name
- "extract"
- end
-
- def altname
- "ex"
- end
-
- def call(args, opts = {}, ioe = {})
- argv = []
- output = nil
- dest = "."
- files = []
-
- while (arg = args.shift)
- case arg
- when '--uncompress', '-z'
- opts[:uncompress] = true
- when '--pipe'
- opts[:output] = ioe[:error]
- output = ioe[:output]
- when '--output', '-o'
- dest = args.shift
- else
- argv << arg
- end
- end
-
- if argv.size < 1
- ioe[:output] << "Not enough arguments.\n\n"
- CommandPattern["help"][["extract"]]
- return 255
- end
-
- input = argv.shift
- if '-' == input
- opts[:name] = "STDIN"
- input = ioe[:input]
- else
- opts[:name] = input
- input = File.open(input, "rb")
- end
-
- if opts[:name] =~ /\.tar\.gz$|\.tgz$/ or opts[:uncompress]
- input = Zlib::GzipReader.new(input)
- end
-
- files << argv.to_a
- files.flatten!
-
- if opts[:verbose]
- watcher = lambda do |action, name, stats|
- opts[:output] << "#{name}\n" if action == :dir or action == :file_done
- end
- finisher = lambda { opts[:output] << "\n" }
- elsif opts[:progress]
- progress = ProgressBar.new(opts[:name], 1)
- watcher = lambda do |action, name, stats|
- case action
- when :file_start, :dir
- progress.title = File.basename(name)
- if action == :dir
- progress.total += 1
- progress.inc
- else
- progress.total += stats[:entry].size
- end
- when :file_progress
- progress.inc(stats[:currinc])
- end
- end
- finisher = lambda do
- progress.title = opts[:name]
- progress.finish
- end
- else
- watcher = nil
- finisher = lambda { }
- end
-
- if output.nil?
- Archive::Tar::Minitar.unpack(input, dest, files, &watcher)
- finisher.call
- else
- Archive::Tar::Minitar::Input.open(input) do |inp|
- inp.each do |entry|
- stats = {
- :mode => entry.mode,
- :mtime => entry.mtime,
- :size => entry.size,
- :gid => entry.gid,
- :uid => entry.uid,
- :current => 0,
- :currinc => 0,
- :entry => entry
- }
-
- if files.empty? or files.include?(entry.full_name)
- if entry.directory?
- puts "Directory: #{entry.full_name}"
- watcher[:dir, dest, stats] unless watcher.nil?
- else
- puts "File: #{entry.full_name}"
- watcher[:file_start, destfile, stats] unless watcher.nil?
- loop do
- data = entry.read(4096)
- break unless data
- stats[:currinc] = output.write(data)
- stats[:current] += stats[:currinc]
-
- watcher[:file_progress, name, stats] unless watcher.nil?
- end
- watcher[:file_done, name, stats] unless watcher.nil?
- end
- end
- end
- end
- end
-
- 0
- end
-
- def help
- help = <<-EOH
- minitar extract [OPTIONS] <tarfile|-> [<file>+]
-
-Extracts files from an existing tarfile. If the tarfile is named .tar.gz
-or .tgz, then it will be uncompressed automatically. If the tarfile is
-"-", then it will be read from standard input (stdin) so that minitar
-may be piped.
-
-The files or directories that will be extracted from the tarfile are
-specified after the name of the tarfile itself. Directories will be
-processed recursively. Files must be specified in full. A file
-"foo/bar/baz.txt" cannot simply be specified by specifying "baz.txt".
-Any file not found will simply be skipped and an error will be reported.
-
-extract Options:
- --uncompress, -z Uncompresses the tarfile with gzip.
- --pipe Emits the extracted files to STDOUT for piping.
- --output, -o Extracts the files to the specified directory.
-
- EOH
- end
- end
-
- class CommandList < CommandPattern
- def name
- "list"
- end
-
- def altname
- "ls"
- end
-
- def modestr(mode)
- s = "---"
- s[0] = ?r if (mode & 4) == 4
- s[1] = ?w if (mode & 2) == 2
- s[2] = ?x if (mode & 1) == 1
- s
- end
-
- def call(args, opts = {}, ioe = {})
- argv = []
- output = nil
- dest = "."
- files = []
- opts[:field] = "name"
-
- while (arg = args.shift)
- case arg
- when '--sort', '-S'
- opts[:sort] = true
- opts[:field] = args.shift
- when '--reverse', '-R'
- opts[:reverse] = true
- opts[:sort] = true
- when '--uncompress', '-z'
- opts[:uncompress] = true
- when '-l'
- opts[:verbose] = true
- else
- argv << arg
- end
- end
-
- if argv.size < 1
- ioe[:output] << "Not enough arguments.\n\n"
- CommandPattern["help"][["list"]]
- return 255
- end
-
- input = argv.shift
- if '-' == input
- opts[:name] = "STDIN"
- input = ioe[:input]
- else
- opts[:name] = input
- input = File.open(input, "rb")
- end
-
- if opts[:name] =~ /\.tar\.gz$|\.tgz$/ or opts[:uncompress]
- input = Zlib::GzipReader.new(input)
- end
-
- files << argv.to_a
- files.flatten!
-
- if opts[:verbose] or opts[:progress]
- format = "%10s %4d %8s %8s %8d %12s %s"
- datefmt = "%b %d %Y"
- timefmt = "%b %d %H:%M"
- fields = %w(permissions inodes user group size date fullname)
- else
- format = "%s"
- fields = %w(fullname)
- end
-
- opts[:field] = opts[:field].intern
- opts[:field] = :full_name if opts[:field] == :name
-
- output = []
-
- Archive::Tar::Minitar::Input.open(input) do |inp|
- today = Time.now
- oneyear = Time.mktime(today.year - 1, today.month, today.day)
- inp.each do |entry|
- value = format % fields.map do |ff|
- case ff
- when "permissions"
- s = entry.directory? ? "d" : "-"
- s << modestr(entry.mode / 0100)
- s << modestr(entry.mode / 0010)
- s << modestr(entry.mode)
- when "inodes"
- entry.size / 512
- when "user"
- entry.uname || entry.uid || 0
- when "group"
- entry.gname || entry.gid || 0
- when "size"
- entry.size
- when "date"
- if Time.at(entry.mtime) > (oneyear)
- Time.at(entry.mtime).strftime(timefmt)
- else
- Time.at(entry.mtime).strftime(datefmt)
- end
- when "fullname"
- entry.full_name
- end
- end
-
- if opts[:sort]
- output << [entry.send(opts[:field]), value]
- else
- ioe[:output] << value << "\n"
- end
-
- end
- end
-
- if opts[:sort]
- output = output.sort { |a, b| a[0] <=> b[0] }
- if opts[:reverse]
- output.reverse_each { |oo| ioe[:output] << oo[1] << "\n" }
- else
- output.each { |oo| ioe[:output] << oo[1] << "\n" }
- end
- end
-
- 0
- end
-
- def help
- help = <<-EOH
- minitar list [OPTIONS] <tarfile|-> [<file>+]
-
-Lists files in an existing tarfile. If the tarfile is named .tar.gz or
-.tgz, then it will be uncompressed automatically. If the tarfile is "-",
-then it will be read from standard input (stdin) so that minitar may be
-piped.
-
-If --verbose or --progress is specified, then the file list will be
-similar to that produced by the Unix command "ls -l".
-
-list Options:
- --uncompress, -z Uncompresses the tarfile with gzip.
- --sort [<FIELD>], -S Sorts the list of files by the specified
- field. The sort defaults to the filename.
- --reverse, -R Reverses the sort.
- -l Lists the files in detail.
-
-Sort Fields:
- name, mtime, size
-
- EOH
- end
- end
-
- CommandPattern << CommandHelp
- CommandPattern << CommandCreate
- CommandPattern << CommandExtract
- CommandPattern << CommandList
-# CommandPattern << CommandAdd
-# CommandPattern << CommandDelete
-
- def self.run(argv, input = $stdin, output = $stdout, error = $stderr)
- ioe = {
- :input => input,
- :output => output,
- :error => error,
- }
- opts = { }
-
- if argv.include?("--version")
- output << <<-EOB
-minitar #{Archive::Tar::Minitar::VERSION}
- Copyright 2004 Mauricio Julio Fernández Pradier and Austin Ziegler
- This is free software with ABSOLUTELY NO WARRANTY.
-
- see http://rubyforge.org/projects/ruwiki for more information
- EOB
- end
-
- if argv.include?("--verbose") or argv.include?("-V")
- opts[:verbose] = true
- argv.delete("--verbose")
- argv.delete("-V")
- end
-
- if argv.include?("--progress") or argv.include?("-P")
- opts[:progress] = true
- opts[:verbose] = false
- argv.delete("--progress")
- argv.delete("-P")
- end
-
- command = CommandPattern[(argv.shift or "").downcase]
- command ||= CommandPattern["help"]
- return command[argv, opts, ioe]
- end
-end
diff --git a/tags/version_0_5_1/minitar/tests/tc_tar.rb b/tags/version_0_5_1/minitar/tests/tc_tar.rb
deleted file mode 100644
index 542eea4..0000000
--- a/tags/version_0_5_1/minitar/tests/tc_tar.rb
+++ /dev/null
@@ -1,624 +0,0 @@
-#!/usr/bin/env ruby
-#--
-# Ruwiki version 0.8.0
-# Copyright © 2002 - 2004, Digikata and HaloStatue
-# Alan Chen (alan@digikata.com)
-# Austin Ziegler (ruwiki@halostatue.ca)
-#
-# Licensed under the same terms as Ruby.
-#
-# $Id$
-#++
-
-$LOAD_PATH.unshift("#{File.dirname(__FILE__)}/../lib") if __FILE__ == $0
-
-require 'archive/tar/minitar'
-require 'test/unit'
-require 'stringio'
-require 'yaml'
-require 'zlib'
-
-module TarTester
-private
- def assert_headers_equal(h1, h2)
- fields = %w(name 100 mode 8 uid 8 gid 8 size 12 mtime 12 checksum 8
- typeflag 1 linkname 100 magic 6 version 2 uname 32 gname 32
- devmajor 8 devminor 8 prefix 155)
- offset = 0
- until fields.empty?
- name = fields.shift
- length = fields.shift.to_i
- if name == "checksum"
- chksum_off = offset
- offset += length
- next
- end
- assert_equal(h1[offset, length], h2[offset, length],
- "Field #{name} of the tar header differs.")
- offset += length
- end
- assert_equal(h1[chksum_off, 8], h2[chksum_off, 8], "Checksumes differ.")
- end
-
- def tar_file_header(fname, dname, mode, length)
- h = header("0", fname, dname, length, mode)
- checksum = calc_checksum(h)
- header("0", fname, dname, length, mode, checksum)
- end
-
- def tar_dir_header(name, prefix, mode)
- h = header("5", name, prefix, 0, mode)
- checksum = calc_checksum(h)
- header("5", name, prefix, 0, mode, checksum)
- end
-
- def header(type, fname, dname, length, mode, checksum = nil)
- checksum ||= " " * 8
- arr = [ASCIIZ(fname, 100), Z(to_oct(mode, 7)), Z(to_oct(nil, 7)),
- Z(to_oct(nil, 7)), Z(to_oct(length, 11)), Z(to_oct(0, 11)),
- checksum, type, "\0" * 100, "ustar\0", "00", ASCIIZ("", 32),
- ASCIIZ("", 32), Z(to_oct(nil, 7)), Z(to_oct(nil, 7)),
- ASCIIZ(dname, 155) ]
- arr = arr.join("").split(//).map{ |x| x[0] }
- h = arr.pack("C100C8C8C8C12C12C8CC100C6C2C32C32C8C8C155")
- ret = h + "\0" * (512 - h.size)
- assert_equal(512, ret.size)
- ret
- end
-
- def calc_checksum(header)
- sum = header.unpack("C*").inject { |s, a| s + a }
- SP(Z(to_oct(sum, 6)))
- end
-
- def to_oct(n, pad_size)
- if n.nil?
- "\0" * pad_size
- else
- "%0#{pad_size}o" % n
- end
- end
-
- def ASCIIZ(str, length)
- str + "\0" * (length - str.length)
- end
-
- def SP(s)
- s + " "
- end
-
- def Z(s)
- s + "\0"
- end
-
- def SP_Z(s)
- s + " \0"
- end
-end
-
-class TC_Tar__Header < Test::Unit::TestCase
- include Archive::Tar::Minitar
- include TarTester
-
- def test_arguments_are_checked
- e = ArgumentError
- assert_raises(e) { Archive::Tar::PosixHeader.new(:name => "", :size => "", :mode => "") }
- assert_raises(e) { Archive::Tar::PosixHeader.new(:name => "", :size => "", :prefix => "") }
- assert_raises(e) { Archive::Tar::PosixHeader.new(:name => "", :prefix => "", :mode => "") }
- assert_raises(e) { Archive::Tar::PosixHeader.new(:prefix => "", :size => "", :mode => "") }
- end
-
- def test_basic_headers
- header = { :name => "bla", :mode => 012345, :size => 10, :prefix => "", :typeflag => "0" }
- assert_headers_equal(tar_file_header("bla", "", 012345, 10),
- Archive::Tar::PosixHeader.new(header).to_s)
- header = { :name => "bla", :mode => 012345, :size => 0, :prefix => "", :typeflag => "5" }
- assert_headers_equal(tar_dir_header("bla", "", 012345),
- Archive::Tar::PosixHeader.new(header).to_s)
- end
-
- def test_long_name_works
- header = { :name => "a" * 100, :mode => 012345, :size => 10, :prefix => "" }
- assert_headers_equal(tar_file_header("a" * 100, "", 012345, 10),
- Archive::Tar::PosixHeader.new(header).to_s)
- header = { :name => "a" * 100, :mode => 012345, :size => 10, :prefix => "bb" * 60 }
- assert_headers_equal(tar_file_header("a" * 100, "bb" * 60, 012345, 10),
- Archive::Tar::PosixHeader.new(header).to_s)
- end
-
- def test_new_from_stream
- header = tar_file_header("a" * 100, "", 012345, 10)
- h = nil
- header = StringIO.new(header)
- assert_nothing_raised { h = Archive::Tar::PosixHeader.new_from_stream(header) }
- assert_equal("a" * 100, h.name)
- assert_equal(012345, h.mode)
- assert_equal(10, h.size)
- assert_equal("", h.prefix)
- assert_equal("ustar", h.magic)
- end
-
- def test_new_from_stream_with_evil_name
- header = tar_file_header("a \0" + "\0" * 97, "", 012345, 10)
- h = nil
- header = StringIO.new(header)
- assert_nothing_raised{ h = Archive::Tar::PosixHeader.new_from_stream header }
- assert_equal("a ", h.name)
- end
-end
-
-class TC_Tar__Writer < Test::Unit::TestCase
- include Archive::Tar::Minitar
- include TarTester
-
- class DummyIO
- attr_reader :data
-
- def initialize
- @data = ""
- end
-
- def write(dat)
- data << dat
- dat.size
- end
-
- def reset
- @data = ""
- end
- end
-
- def setup
- @data = "a" * 10
- @dummyos = DummyIO.new
- @os = Writer.new(@dummyos)
- end
-
- def teardown
- @os.close
- end
-
- def test_add_file_simple
- @dummyos.reset
-
- Writer.open(@dummyos) do |os|
- os.add_file_simple("lib/foo/bar", :mode => 0644, :size => 10) do |f|
- f.write "a" * 10
- end
- os.add_file_simple("lib/bar/baz", :mode => 0644, :size => 100) do |f|
- f.write "fillme"
- end
- end
-
- assert_headers_equal(tar_file_header("lib/foo/bar", "", 0644, 10),
- @dummyos.data[0, 512])
- assert_equal("a" * 10 + "\0" * 502, @dummyos.data[512, 512])
- assert_headers_equal(tar_file_header("lib/bar/baz", "", 0644, 100),
- @dummyos.data[512 * 2, 512])
- assert_equal("fillme" + "\0" * 506, @dummyos.data[512 * 3, 512])
- assert_equal("\0" * 512, @dummyos.data[512 * 4, 512])
- assert_equal("\0" * 512, @dummyos.data[512 * 5, 512])
- end
-
- def test_write_operations_fail_after_closed
- @dummyos.reset
- @os.add_file_simple("sadd", :mode => 0644, :size => 20) { |f| }
- @os.close
- assert_raises(ClosedStream) { @os.flush }
- assert_raises(ClosedStream) { @os.add_file("dfdsf", :mode => 0644) {} }
- assert_raises(ClosedStream) { @os.mkdir "sdfdsf", :mode => 0644 }
- end
-
- def test_file_name_is_split_correctly
- # test insane file lengths, and: a{100}/b{155}, etc
- @dummyos.reset
- names = [ "#{'a' * 155}/#{'b' * 100}", "#{'a' * 151}/#{'qwer/' * 19}bla" ]
- o_names = [ "#{'b' * 100}", "#{'qwer/' * 19}bla" ]
- o_prefixes = [ "a" * 155, "a" * 151 ]
- names.each do |name|
- @os.add_file_simple(name, :mode => 0644, :size => 10) { }
- end
- o_names.each_with_index do |nam, i|
- assert_headers_equal(tar_file_header(nam, o_prefixes[i], 0644, 10),
- @dummyos.data[2 * i * 512, 512])
- end
- assert_raises(FileNameTooLong) do
- @os.add_file_simple(File.join("a" * 152, "b" * 10, "a" * 92),
- :mode => 0644, :size => 10) { }
- end
- assert_raises(FileNameTooLong) do
- @os.add_file_simple(File.join("a" * 162, "b" * 10),
- :mode => 0644, :size => 10) { }
- end
- assert_raises(FileNameTooLong) do
- @os.add_file_simple(File.join("a" * 10, "b" * 110),
- :mode => 0644, :size => 10) { }
- end
- end
-
- def test_add_file
- dummyos = StringIO.new
- class << dummyos
- def method_missing(meth, *a)
- self.string.send(meth, *a)
- end
- end
- os = Writer.new dummyos
- content1 = ('a'..'z').to_a.join("") # 26
- content2 = ('aa'..'zz').to_a.join("") # 1352
- Writer.open(dummyos) do |os|
- os.add_file("lib/foo/bar", :mode => 0644) { |f, opts| f.write "a" * 10 }
- os.add_file("lib/bar/baz", :mode => 0644) { |f, opts| f.write content1 }
- os.add_file("lib/bar/baz", :mode => 0644) { |f, opts| f.write content2 }
- os.add_file("lib/bar/baz", :mode => 0644) { |f, opts| }
- end
- assert_headers_equal(tar_file_header("lib/foo/bar", "", 0644, 10),
- dummyos[0, 512])
- assert_equal(%Q(#{"a" * 10}#{"\0" * 502}), dummyos[512, 512])
- offset = 512 * 2
- [content1, content2, ""].each do |data|
- assert_headers_equal(tar_file_header("lib/bar/baz", "", 0644,
- data.size), dummyos[offset, 512])
- offset += 512
- until !data || data == ""
- chunk = data[0, 512]
- data[0, 512] = ""
- assert_equal(chunk + "\0" * (512 - chunk.size),
- dummyos[offset, 512])
- offset += 512
- end
- end
- assert_equal("\0" * 1024, dummyos[offset, 1024])
- end
-
- def test_add_file_tests_seekability
- assert_raises(Archive::Tar::Minitar::NonSeekableStream) do
- @os.add_file("libdfdsfd", :mode => 0644) { |f| }
- end
- end
-
- def test_write_header
- @dummyos.reset
- @os.add_file_simple("lib/foo/bar", :mode => 0644, :size => 0) { |f| }
- @os.flush
- assert_headers_equal(tar_file_header("lib/foo/bar", "", 0644, 0),
- @dummyos.data[0, 512])
- @dummyos.reset
- @os.mkdir("lib/foo", :mode => 0644)
- assert_headers_equal(tar_dir_header("lib/foo", "", 0644),
- @dummyos.data[0, 512])
- @os.mkdir("lib/bar", :mode => 0644)
- assert_headers_equal(tar_dir_header("lib/bar", "", 0644),
- @dummyos.data[512 * 1, 512])
- end
-
- def test_write_data
- @dummyos.reset
- @os.add_file_simple("lib/foo/bar", :mode => 0644, :size => 10) do |f|
- f.write @data
- end
- @os.flush
- assert_equal(@data + ("\0" * (512-@data.size)),
- @dummyos.data[512, 512])
- end
-
- def test_file_size_is_checked
- @dummyos.reset
- assert_raises(Archive::Tar::Minitar::Writer::BoundedStream::FileOverflow) do
- @os.add_file_simple("lib/foo/bar", :mode => 0644, :size => 10) do |f|
- f.write "1" * 100
- end
- end
- assert_nothing_raised do
- @os.add_file_simple("lib/foo/bar", :mode => 0644, :size => 10) {|f| }
- end
- end
-end
-
-class TC_Tar__Reader < Test::Unit::TestCase
- include Archive::Tar::Minitar
- include TarTester
-
- def setup
- end
-
- def teardown
- end
-
- def test_multiple_entries
- str = tar_file_header("lib/foo", "", 010644, 10) + "\0" * 512
- str += tar_file_header("bar", "baz", 0644, 0)
- str += tar_dir_header("foo", "bar", 012345)
- str += "\0" * 1024
- names = %w[lib/foo bar foo]
- prefixes = ["", "baz", "bar"]
- modes = [010644, 0644, 012345]
- sizes = [10, 0, 0]
- isdir = [false, false, true]
- isfile = [true, true, false]
- Reader.new(StringIO.new(str)) do |is|
- i = 0
- is.each_entry do |entry|
- assert_kind_of(Reader::EntryStream, entry)
- assert_equal(names[i], entry.name)
- assert_equal(prefixes[i], entry.prefix)
- assert_equal(sizes[i], entry.size)
- assert_equal(modes[i], entry.mode)
- assert_equal(isdir[i], entry.directory?)
- assert_equal(isfile[i], entry.file?)
- if prefixes[i] != ""
- assert_equal(File.join(prefixes[i], names[i]), entry.full_name)
- else
- assert_equal(names[i], entry.name)
- end
- i += 1
- end
- assert_equal(names.size, i)
- end
- end
-
- def test_rewind_entry_works
- content = ('a'..'z').to_a.join(" ")
- str = tar_file_header("lib/foo", "", 010644, content.size) + content +
- "\0" * (512 - content.size)
- str << "\0" * 1024
- Reader.new(StringIO.new(str)) do |is|
- is.each_entry do |entry|
- 3.times do
- entry.rewind
- assert_equal(content, entry.read)
- assert_equal(content.size, entry.pos)
- end
- end
- end
- end
-
- def test_rewind_works
- content = ('a'..'z').to_a.join(" ")
- str = tar_file_header("lib/foo", "", 010644, content.size) + content +
- "\0" * (512 - content.size)
- str << "\0" * 1024
- Reader.new(StringIO.new(str)) do |is|
- 3.times do
- is.rewind
- i = 0
- is.each_entry do |entry|
- assert_equal(content, entry.read)
- i += 1
- end
- assert_equal(1, i)
- end
- end
- end
-
- def test_read_works
- contents = ('a'..'z').inject(""){|s, x| s << x * 100}
- str = tar_file_header("lib/foo", "", 010644, contents.size) + contents
- str += "\0" * (512 - (str.size % 512))
- Reader.new(StringIO.new(str)) do |is|
- is.each_entry do |entry|
- assert_kind_of(Reader::EntryStream, entry)
- data = entry.read(3000) # bigger than contents.size
- assert_equal(contents, data)
- assert_equal(true, entry.eof?)
- end
- end
- Reader.new(StringIO.new(str)) do |is|
- is.each_entry do |entry|
- assert_kind_of(Reader::EntryStream, entry)
- data = entry.read(100)
- (entry.size - data.size).times {|i| data << entry.getc.chr }
- assert_equal(contents, data)
- assert_equal(nil, entry.read(10))
- assert_equal(true, entry.eof?)
- end
- end
- Reader.new(StringIO.new(str)) do |is|
- is.each_entry do |entry|
- assert_kind_of(Reader::EntryStream, entry)
- data = entry.read
- assert_equal(contents, data)
- assert_equal(nil, entry.read(10))
- assert_equal(nil, entry.read)
- assert_equal(nil, entry.getc)
- assert_equal(true, entry.eof?)
- end
- end
- end
-
- def test_eof_works
- str = tar_file_header("bar", "baz", 0644, 0)
- Reader.new(StringIO.new(str)) do |is|
- is.each_entry do |entry|
- assert_kind_of(Reader::EntryStream, entry)
- data = entry.read
- assert_equal(nil, data)
- assert_equal(nil, entry.read(10))
- assert_equal(nil, entry.read)
- assert_equal(nil, entry.getc)
- assert_equal(true, entry.eof?)
- end
- end
- str = tar_dir_header("foo", "bar", 012345)
- Reader.new(StringIO.new(str)) do |is|
- is.each_entry do |entry|
- assert_kind_of(Reader::EntryStream, entry)
- data = entry.read
- assert_equal(nil, data)
- assert_equal(nil, entry.read(10))
- assert_equal(nil, entry.read)
- assert_equal(nil, entry.getc)
- assert_equal(true, entry.eof?)
- end
- end
- str = tar_dir_header("foo", "bar", 012345)
- str += tar_file_header("bar", "baz", 0644, 0)
- str += tar_file_header("bar", "baz", 0644, 0)
- Reader.new(StringIO.new(str)) do |is|
- is.each_entry do |entry|
- assert_kind_of(Reader::EntryStream, entry)
- data = entry.read
- assert_equal(nil, data)
- assert_equal(nil, entry.read(10))
- assert_equal(nil, entry.read)
- assert_equal(nil, entry.getc)
- assert_equal(true, entry.eof?)
- end
- end
- end
-end
-
-class TC_Tar__Input < Test::Unit::TestCase
- include Archive::Tar::Minitar
- include TarTester
-
- require 'rbconfig'
-
- TEST_TGZ = "\037\213\010\000\001B1A\000\vKI,I\324+I,\322K\257b\240\0250\000\002sSS\254\342 `dj\306``nnnbndbjd\000\0247336`P0\240\231\213\220@i1\320\367@+\351a\327 \004\362\335\034\f\313\034\r\035\031\270\337Ns\344b2\344q\335\375M\304\266QM1W\357\321>\221U\021\005\246\306\367\356\367u3\262;\212\004\265\236\\\334}\351,\377\037;\217\223\301e\247\030\024\\\236\211\277\347\346sii\265\010\330\355\234\240\362\274\371[\202\361\366\302S\316\335o&~m\237r\355\377\303\230\365\352WNW\334\266_\373\273\237\347Q\315t?\263{\377?\006\271\337?\367\207\325\346]\371\376y\307_\234~d\3772\265\346\261}\323\317\373\315\352\377O\376\271/\305\377?X\253\324\303S\373\361\347\277\372^)\267\377\363\03460\331\311\\wW|\031\203\300@\207\325p\004i\2319\251\3064\266\203P\376702B\313\377\246\246\006&\243\371\237\036 $#\263X\001\210@\351@\301XO\201\227k\240]4\nF\301(\030\005\243\200\036\000\000\004\330t\023\000\f\000\000"
- FILETIMES = Time.mktime(2004).to_i
-
- TEST_CONTENTS = [
- [ "data.tar.gz", 174, 0755 ],
- [ "file3", 18, 0755 ],
- ]
-
- TEST_DATA_CONTENTS = [
- [ "data", 0, 010644 ],
- [ "data/file1", 16, 010644 ],
- [ "data/file2", 16, 010644 ],
- [ "data/__dir__", 0, 010644 ],
- ]
-
- def setup
- FileUtils.mkdir_p("data__")
- end
-
- def teardown
- FileUtils.rm_rf("data__")
- end
-
- def test_each_works
- gzr = Zlib::GzipReader.new(StringIO.new(TEST_TGZ))
- Input.open(gzr) do |is|
- ii = 0
- is.each_with_index do |entry, ii|
- assert_kind_of(Reader::EntryStream, entry)
- assert_equal(TEST_CONTENTS[ii][0], entry.name)
- assert_equal(TEST_CONTENTS[ii][1], entry.size)
- assert_equal(TEST_CONTENTS[ii][2], entry.mode)
- assert_equal(FILETIMES, entry.mtime)
-
- if 0 == ii
- gzr2 = Zlib::GzipReader.new(StringIO.new(entry.read))
- Input.open(gzr2) do |is2|
- jj = 0
- is2.each_with_index do |entry2, jj|
- assert_kind_of(Reader::EntryStream, entry2)
- assert_equal(TEST_DATA_CONTENTS[jj][0], entry2.name)
- assert_equal(TEST_DATA_CONTENTS[jj][1], entry2.size)
- assert_equal(TEST_DATA_CONTENTS[jj][2], entry2.mode)
- assert_equal(FILETIMES, entry2.mtime)
- end
- assert_equal(3, jj)
- end
- end
- end
- assert_equal(1, ii)
- end
- end
-
- def test_extract_entry_works
- gzr = Zlib::GzipReader.new(StringIO.new(TEST_TGZ))
- Input.open(gzr) do |is|
- ii = 0
- is.each_with_index do |entry, ii|
- is.extract_entry("data__", entry)
- name = File.join("data__", entry.name)
-
- if entry.directory?
- assert(File.directory?(name))
- else
- assert(File.file?(name))
-
- assert_equal(TEST_CONTENTS[ii][1], File.stat(name).size)
- end
- assert_equal(TEST_CONTENTS[ii][2], File.stat(name).mode) unless RUBY_PLATFORM =~ /win32/
-
- if 0 == ii
- begin
- ff = File.open(name, "rb")
- gzr2 = Zlib::GzipReader.new(ff)
- Input.open(gzr2) do |is2|
- jj = 0
- is2.each_with_index do |entry2, jj|
- is2.extract_entry("data__", entry2)
- name2 = File.join("data__", entry2.name)
-
- if entry2.directory?
- assert(File.directory?(name2))
- else
- assert(File.file?(name2))
- assert_equal(TEST_DATA_CONTENTS[jj][1], File.stat(name2).size, name2)
- end
- assert_equal(TEST_DATA_CONTENTS[jj][2], File.stat(name2).mode, name2) unless RUBY_PLATFORM =~ /win32/
- end
- end
- ensure
- ff.close unless ff.closed?
- end
- end
- end
- assert_equal(1, ii)
- end
- end
-end
-
-class TC_Tar__Output < Test::Unit::TestCase
- include Archive::Tar::Minitar
- include TarTester
-
- def setup
- FileUtils.mkdir_p("data__")
- %w(a b c).each do |filename|
- name = File.join("data__", filename)
- File.open(name, "wb") { |f| f.puts "#{name}: 123456789012345678901234567890" }
- end
- @tarfile = "data__/bla2.tar"
- end
-
- def teardown
- FileUtils.rm_rf("data__")
- end
-
- def test_file_looks_good
- Output.open(@tarfile) do |os|
- Dir.chdir("data__") do
- %w(a b c).each do |name|
- stat = File.stat(name)
- opts = { :size => stat.size, :mode => 0644 }
- os.tar.add_file_simple(name, opts) do |ss|
- File.open(name, "rb") { |ff| ss.write(ff.read(4096)) until ff.eof? }
- end
- end
- end
- end
- ff = File.open(@tarfile, "rb")
- Reader.open(ff) do |is|
- ii = 0
- is.each do |entry|
- case ii
- when 0
- assert_equal("a", entry.name)
- when 1
- assert_equal("b", entry.name)
- when 2
- assert_equal("c", entry.name)
- end
- ii += 1
- end
- assert_equal(3, ii)
- end
- ensure
- ff.close if ff
- end
-end
diff --git a/tags/version_0_5_1/minitar/tests/testall.rb b/tags/version_0_5_1/minitar/tests/testall.rb
deleted file mode 100644
index 9c65d0f..0000000
--- a/tags/version_0_5_1/minitar/tests/testall.rb
+++ /dev/null
@@ -1,20 +0,0 @@
-#!/usr/bin/env ruby
-#--
-# Ruwiki version 0.8.0
-# Copyright © 2002 - 2003, Digikata and HaloStatue
-# Alan Chen (alan@digikata.com)
-# Austin Ziegler (ruwiki@halostatue.ca)
-#
-# Licensed under the same terms as Ruby.
-#
-# $Id$
-#++
-
-$LOAD_PATH.unshift("#{File.dirname(__FILE__)}/../lib") if __FILE__ == $0
-
-puts "Checking for test cases:"
-Dir['tc*.rb'].each do |testcase|
- puts "\t#{testcase}"
- require testcase
-end
-puts " "