diff --git a/.gitignore b/.gitignore index 051f986..c065e9c 100644 --- a/.gitignore +++ b/.gitignore @@ -12,3 +12,5 @@ html pkg publish test/cache.tst +tmp/ +.byebug_history diff --git a/.hoerc b/.hoerc index 75d7e96..cd32cc1 100644 --- a/.hoerc +++ b/.hoerc @@ -1,20 +1,42 @@ --- exclude: !ruby/regexp '/ - \.(tmp|swp)$ - | - CVS/ - | - (?i:TAGS) - | - \.(svn|git|hg|DS_Store|idea|vagrant)\/ - | - Gemfile(?:\.lock)? - | - type-lists\/ - | - \.(coveralls|pullreview|travis).yml$ - | - \.gemspec + \.(?: + tmp | + swp + )$ + | + \.(?: + autotest | + byebug_history | + gemtest | + gitignore | + hoerc | + simplecov-prelude.rb + )$ + | + (?: + appveyor | + coveralls | + pullreview | + rubocop | + travis + )\.yml$ + | + \b(?i:TAGS)$ + | + \.(?: + DS_Store | + bundle | + git | + hg | + idea | + svn | + vagrant + )\/ + | + [gG]emfile(?:\.lock)? + | + \.gemspec$ | Vagrantfile /x' diff --git a/.rubocop.yml b/.rubocop.yml new file mode 100644 index 0000000..425dc18 --- /dev/null +++ b/.rubocop.yml @@ -0,0 +1,106 @@ +--- +AllCops: + DisplayCopNames: true + DisplayStyleGuide: true + ExtraDetails: true + +Style/AlignHash: + EnforcedColonStyle: key + EnforcedHashRocketStyle: key + EnforcedLastArgumentHashStyle: enforce_implicit + +Style/AlignParameters: + EnforcedStyle: with_fixed_indentation + +Style/AndOr: + Enabled: false + +Style/AsciiComments: + Enabled: false + +Style/AsciiIdentifiers: + Enabled: false + +Style/BarePercentLiterals: + EnforcedStyle: percent_q + +Style/BlockDelimiters: + EnforcedStyle: semantic + IgnoredMethods: + - assert_raises + ProceduralMethods: + - spec + +Style/BracesAroundHashParameters: + EnforcedStyle: context_dependent + +Style/ClassAndModuleChildren: + Enabled: false + +Style/ClassCheck: + EnforcedStyle: kind_of? + +Style/CommandLiteral: + EnforcedStyle: percent_x + +Style/CommentAnnotation: + Enabled: true + +Style/Copyright: + Enabled: false + +Style/DotPosition: + EnforcedStyle: trailing + +Style/DoubleNegation: + Enabled: false + +Style/Encoding: # For a gem that is using Ruby 1.9, change this to true. + Enabled: false + +Style/FileName: + Exclude: + - lib/mime-types.rb + +Style/FormatString: + EnforcedStyle: percent + +Style/MultilineBlockChain: + Enabled: false + +Style/MultilineOperationIndentation: + EnforcedStyle: indented + +Style/ParallelAssignment: + Enabled: false + +Style/RegexpLiteral: + Enabled: false + +Style/SpaceInsideBrackets: + Enabled: false + +Style/UnneededPercentQ: + Enabled: false + +# This is one of the hobgoblins. +Metrics/AbcSize: + Enabled: false + +# This is one of the hobgoblins. +Metrics/ClassLength: + Enabled: false + +Metrics/CyclomaticComplexity: + Enabled: false + +Metrics/LineLength: + Exclude: + - Rakefile + +# This is one of the hobgoblins. +Metrics/MethodLength: + Enabled: false + +Metrics/PerceivedComplexity: + Enabled: false diff --git a/.simplecov-prelude.rb b/.simplecov-prelude.rb new file mode 100644 index 0000000..5ed413f --- /dev/null +++ b/.simplecov-prelude.rb @@ -0,0 +1,13 @@ +require 'psych' if ENV['CI'] +require 'simplecov' + +if ENV['CI'] + require 'coveralls' + SimpleCov.formatter = Coveralls::SimpleCov::Formatter +end + +SimpleCov.start do + command_name 'Minitest' +end + +gem 'minitest' diff --git a/.travis.yml b/.travis.yml index acc7742..c12be97 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,35 +1,34 @@ --- language: ruby +env: + - DEV=1 rvm: - - 2.1.0 + - 2.4.0 + - 2.3.3 + - 2.2.6 + - 2.1.9 - 2.0.0 + - jruby-9.0.5.0 + - jruby-9.1.6.0 - 1.9.3 - 1.8.7 - ree - ruby-head - jruby-19mode - - jruby-head - - rbx-2 matrix: allow_failures: - - rvm: rbx-2 - - rvm: jruby-head - rvm: ruby-head - rvm: 1.8.7 - rvm: ree gemfile: - Gemfile +before_install: + - pushd .. && git clone https://github.com/halostatue/minitar.git && popd before_script: - - | - case "${TRAVIS_RUBY_VERSION}" in - rbx*) - gem install psych - ;; - esac - - rake travis:before -t -script: rake travis + - bundle exec rake travis:before -t +script: bundle exec rake travis after_script: - - rake travis:after -t + - bundle exec rake travis:after -t notifications: email: recipients: diff --git a/Contributing.md b/Contributing.md new file mode 100644 index 0000000..d2025be --- /dev/null +++ b/Contributing.md @@ -0,0 +1,71 @@ +## Contributing + +I value any contribution to minitar-cli you can provide: a bug report, a +feature request, or code contributions. There are a few guidelines for +contributing to minitar: + +* Code changes *will not* be accepted without tests. The test suite is + written with [Minitest][]. +* Match my coding style. +* Use a thoughtfully-named topic branch that contains your change. Rebase + your commits into logical chunks as necessary. +* Use [quality commit messages][]. +* Do not change the version number; when your patch is accepted and a release + is made, the version will be updated at that point. +* Submit a GitHub pull request with your changes. +* New or changed behaviours require appropriate documentation. + +### Test Dependencies + +minitar-cli uses Ryan Davis’s [Hoe][] to manage the release process, and it +adds a number of rake tasks. You will mostly be interested in: + + $ rake + +which runs the tests the same way that: + + $ rake test + $ rake travis + +will do. + +To assist with the installation of the development dependencies for +minitar-cli, I have provided the simplest possible Gemfile pointing to the +(generated) `minitar-cli.gemspec` file. This will permit you to do: + + $ bundle install + +to get the development dependencies. If you aleady have `hoe` installed, you +can accomplish the same thing with: + + $ rake newb + +This task will install any missing dependencies, run the tests/specs, and +generate the RDoc. + +You can run tests with code coverage analysis by running: + + $ rake test:coverage + +### Workflow + +Here's the most direct way to get your work merged into the project: + +* Fork the project. +* Clone down your fork (`git clone git://github.com//minitar-cli.git`). +* Create a topic branch to contain your change (`git checkout -b + my_awesome_feature`). +* Hack away, add tests. Not necessarily in that order. +* Make sure everything still passes by running `rake`. +* If necessary, rebase your commits into logical chunks, without errors. +* Push the branch up (`git push origin my_awesome_feature`). +* Create a pull request against halostatue/minitar-cli and describe what your + change does and the why you think it should be merged. + +### Contributors + +* Austin Ziegler created minitar-cli, extracted from Archive::Tar::Minitar. + +[Minitest]: https://github.com/seattlerb/minitest +[quality commit messages]: http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html +[Hoe]: https://github.com/seattlerb/hoe diff --git a/Contributing.rdoc b/Contributing.rdoc deleted file mode 100644 index 201290e..0000000 --- a/Contributing.rdoc +++ /dev/null @@ -1,64 +0,0 @@ -== Contributing - -I value any contribution to minitar-cli you can provide: a bug report, a -feature request, or code contributions. - -As minitar is a mature codebase, there are a few guidelines: - -* Code changes *will* *not* be accepted without tests. The test suite is - written with {Minitest}[https://github.com/seattlerb/minitest]. -* Match my coding style. -* Use a thoughtfully-named topic branch that contains your change. Rebase your - commits into logical chunks as necessary. -* Use {quality commit messages}[http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html]. -* Do not change the version number; when your patch is accepted and a release - is made, the version will be updated at that point. -* Submit a GitHub pull request with your changes. -* New or changed behaviours require new or updated documentation. - -=== Test Dependencies - -minitar-cli uses Ryan Davis’s {Hoe}[https://github.com/seattlerb/hoe] to manage -the release process, and it adds a number of rake tasks. You will mostly be -interested in: - - $ rake - -which runs the tests the same way that: - - $ rake test - $ rake travis - -will do. - -To assist with the installation of the development dependencies for -minitar-cli, I have provided the simplest possible Gemfile pointing to the -(generated) +minitar-cli.gemspec+ file. This will permit you to do: - - $ bundle install - -to get the development dependencies. If you aleady have +hoe+ installed, you -can accomplish the same thing with: - - $ rake newb - -This task will install any missing dependencies, run the tests/specs, and -generate the RDoc. - -=== Workflow - -Here's the most direct way to get your work merged into the project: - -* Fork the project. -* Clone down your fork (git clone git://github.com//minitar-cli.git). -* Create a topic branch to contain your change (git checkout -b my\_awesome\_feature). -* Hack away, add tests. Not necessarily in that order. -* Make sure everything still passes by running +rake+. -* If necessary, rebase your commits into logical chunks, without errors. -* Push the branch up (git push origin my\_awesome\_feature). -* Create a pull request against halostatue/minitar-cli and describe what your - change does and the why you think it should be merged. - -=== Contributors - -* Austin Ziegler created minitar-cli, extraced from Archive::Tar::Minitar. diff --git a/Gemfile b/Gemfile index 359a82d..576ea91 100644 --- a/Gemfile +++ b/Gemfile @@ -3,11 +3,27 @@ # NOTE: This file is present to keep Travis CI happy. Edits to it will not # be accepted. -source "https://rubygems.org/" +source 'https://rubygems.org/' -if RUBY_VERSION < "1.9" - gem 'mime-types', '~> 1.25' -end +mime_version = + if RUBY_VERSION < '1.9' + gem 'rdoc', '< 4.0' + gem 'rake', '~> 10.0' + '1.25' + elsif RUBY_VERSION < '2.0' + '2.0' + elsif RUBY_VERSION >= '2.0' + if RUBY_ENGINE == 'ruby' + gem 'byebug' if ENV['DEV'] + gem 'simplecov', '~> 0.7' + gem 'coveralls', '~> 0.7' + end + '3.0' + end + +gem 'mime-types', "~> #{mime_version}" + +gem 'minitar', :path => '../minitar' if ENV['DEV'] gemspec diff --git a/History.md b/History.md new file mode 100644 index 0000000..aeb6c1b --- /dev/null +++ b/History.md @@ -0,0 +1,21 @@ +## 0.6 / 2017-02-06 + +* Hello, minitar-cli. This is a new gem containing code originally from + archive-tar-minitar. + +* Enhancements: + + * Extracted `bin/minitar` from [minitar][]. + * Replaced Satoru Takabayashi’s [Ruby Progress Bar][] with + [busyloop/powerbar][]. + +* Bugs: + +* Development: + + * Modernized minitar tooling around Hoe. + * Added travis and coveralls. + +[minitar]: https://github.com/halostatue/minitar +[Ruby Progress Bar]: https://namazu.org/~satoru/ruby-progressbar/ +[busyloop/powerbar]: https://github.com/busyloop/powerbar diff --git a/History.rdoc b/History.rdoc deleted file mode 100644 index 1c148f4..0000000 --- a/History.rdoc +++ /dev/null @@ -1,17 +0,0 @@ -== 0.6 / YYYY-MM-DD - -* Hello, minitar-cli. This is a new gem containing code originally from - archive-tar-minitar. - -* Enhancements: - * Extracted bin/minitar from - {minitar}[https://github.com/halostatue/minitar]. - * Replaced Satoru Takabayashi’s - {Ruby Progress Bar}[namazu.org/~satoru/ruby-progressbar/] with - {busyloop/powerbar}[https://github.com/busyloop/powerbar]. - -* Bugs: - -* Development: - * Modernized minitar tooling around Hoe. - * Added travis and coveralls. diff --git a/Licence.rdoc b/Licence.md similarity index 60% rename from Licence.rdoc rename to Licence.md index 22ef108..d26ff21 100644 --- a/Licence.rdoc +++ b/Licence.md @@ -1,12 +1,15 @@ -== Licence +## Licence minitar-cli is free software that may be redistributed and/or modified under the terms of Ruby’s licence or the Simplified BSD licence. -* Copyright 2004–2014 Austin Ziegler. +* Copyright 2004–2017 Austin Ziegler. +* Portions copyright 2004 Mauricio Julio Fernández Pradier. + +### Simplified BSD Licence -=== Simplified BSD Licence See the file docs/bsdl.txt in the main distribution. -=== Ruby’s Licence +### Ruby’s Licence + See the file docs/ruby.txt in the main distribution. diff --git a/Manifest.txt b/Manifest.txt index f124453..017b966 100644 --- a/Manifest.txt +++ b/Manifest.txt @@ -1,16 +1,22 @@ -.autotest -.gemtest -.gitignore -.hoerc -Contributing.rdoc -History.rdoc -Licence.rdoc +Contributing.md +History.md +Licence.md Manifest.txt README.rdoc Rakefile bin/minitar docs/bsdl.txt docs/ruby.txt -lib/minitar-cli.rb lib/minitar/cli.rb +lib/minitar/cli/command.rb +lib/minitar/cli/command/create.rb +lib/minitar/cli/command/extract.rb +lib/minitar/cli/command/help.rb +lib/minitar/cli/command/list.rb +lib/minitar/cli/commander.rb +test/fixtures/bad-dir.tar.gz +test/fixtures/spaces.tar.gz test/minitest_helper.rb +test/support/command_line_test_helper.rb +test/test_cli_help.rb +test/test_cli_list.rb diff --git a/README.rdoc b/README.rdoc index 41024a3..9169820 100644 --- a/README.rdoc +++ b/README.rdoc @@ -4,8 +4,9 @@ home :: https://github.com/halostatue/minitar-cli/ code :: https://github.com/halostatue/minitar-cli/ bugs :: https://github.com/halostatue/minitar-cli/issues rdoc :: http://rdoc.info/gems/minitar-cli/ -continuous integration :: {}[https://travis-ci.org/halostatue/minitar-cli] -test coverage :: {Coverage Status}[https://coveralls.io/r/halostatue/minitar-cli] +continuous integration :: {}[https://travis-ci.org/halostatue/minitar-cli] + {}[https://ci.appveyor.com/project/halostatue/minitar-cli] +test coverage :: {Coverage Status}[https://coveralls.io/r/halostatue/minitar-cli] == Description @@ -28,7 +29,3 @@ The minitar-cli tool uses a {Semantic Versioning}[http://semver.org/] scheme with one change: * When PATCH is zero (+0+), it will be omitted from version references. - -:include: Contributing.rdoc - -:include: Licence.rdoc diff --git a/Rakefile b/Rakefile index 84f2c15..1f31f7e 100644 --- a/Rakefile +++ b/Rakefile @@ -13,54 +13,35 @@ Hoe.plugin :email unless ENV['CI'] or ENV['TRAVIS'] spec = Hoe.spec 'minitar-cli' do developer('Austin Ziegler', 'halostatue@gmail.com') - self.need_tar = true - self.require_ruby_version '>= 1.8' + require_ruby_version '>= 1.8' - self.history_file = 'History.rdoc' + self.history_file = 'History.md' self.readme_file = 'README.rdoc' - self.extra_rdoc_files = FileList["*.rdoc"].to_a - self.licenses = ["Ruby", "BSD-2-Clause"] - - self.extra_deps << ['archive-tar-minitar', '~> 0.6.0'] - self.extra_deps << ['powerbar', '~> 1.0'] - - self.extra_dev_deps << ['hoe-doofus', '~> 1.0'] - self.extra_dev_deps << ['hoe-gemspec2', '~> 1.1'] - self.extra_dev_deps << ['hoe-git', '~> 1.6'] - self.extra_dev_deps << ['hoe-rubygems', '~> 1.0'] - self.extra_dev_deps << ['hoe-travis', '~> 1.2'] - self.extra_dev_deps << ['minitest', '~> 5.3'] - self.extra_dev_deps << ['minitest-autotest', ['>= 1.0.b', '<2']] - self.extra_dev_deps << ['rake', '~> 10.0'] - self.extra_dev_deps << ['simplecov', '~> 0.7'] - self.extra_dev_deps << ['coveralls', '~> 0.7'] + self.licenses = ['Ruby', 'BSD-2-Clause'] + + extra_deps << ['minitar', '~> 0.6.0'] + extra_deps << ['powerbar', '~> 1.0'] + + extra_dev_deps << ['hoe-doofus', '~> 1.0'] + extra_dev_deps << ['hoe-gemspec2', '~> 1.1'] + extra_dev_deps << ['hoe-git', '~> 1.6'] + extra_dev_deps << ['hoe-rubygems', '~> 1.0'] + extra_dev_deps << ['hoe-travis', '~> 1.2'] + extra_dev_deps << ['minitest', '~> 5.3'] + extra_dev_deps << ['minitest-autotest', ['>= 1.0', '<2']] + extra_dev_deps << ['rake', '>= 10.0', '< 12'] + extra_dev_deps << ['rdoc', '>= 0.0'] end -if RUBY_VERSION >= "1.9" +if RUBY_VERSION >= '2.0' && RUBY_ENGINE == 'ruby' namespace :test do - task :coveralls do - spec.test_prelude = [ - 'require "psych"', - 'require "simplecov"', - 'require "coveralls"', - 'SimpleCov.formatter = Coveralls::SimpleCov::Formatter', - 'SimpleCov.start("test_frameworks") { command_name "Minitest" }', - 'gem "minitest"' - ].join('; ') - Rake::Task['test'].execute - end - desc 'Run test coverage' task :coverage do - spec.test_prelude = [ - 'require "simplecov"', - 'SimpleCov.start("test_frameworks") { command_name "Minitest" }', - 'gem "minitest"' - ].join('; ') + spec.test_prelude = 'load ".simplecov-prelude.rb"' Rake::Task['test'].execute end end - Rake::Task['travis'].prerequisites.replace(%w(test:coveralls)) + Rake::Task['travis'].prerequisites.replace(%w(test:coverage)) end diff --git a/appveyor.yml b/appveyor.yml new file mode 100644 index 0000000..2f44052 --- /dev/null +++ b/appveyor.yml @@ -0,0 +1,29 @@ +version: '{build}' +skip_tags: true +clone_depth: 10 +init: [] +environment: + matrix: + - ruby_version: 193 + - ruby_version: 200 + - ruby_version: 200-x64 + - ruby_version: 21 + - ruby_version: 21-x64 + - ruby_version: 22 + - ruby_version: 22-x64 + - ruby_version: 23 + - ruby_version: 23-x64 + - ruby_version: 24 + - ruby_version: 24-x64 +install: +- SET PATH=C:\Ruby%ruby_version%\bin;%PATH% +- SET DEV=1 +- ruby --version +- gem --version +- gem install bundler --quiet --no-ri --no-rdoc +- bundle --version +- pushd .. && git clone https://github.com/halostatue/minitar.git && popd +- bundle install +build: off +test_script: + - bundle exec rake test diff --git a/bin/minitar b/bin/minitar index d5a685c..3d5cdbe 100755 --- a/bin/minitar +++ b/bin/minitar @@ -1,6 +1,9 @@ #! /usr/bin/env ruby # coding: utf-8 +git_path = File.expand_path('../../.git', __FILE__) +$:.unshift(File.expand_path('../../lib', __FILE__)) if File.exist?(git_path) + require 'minitar/cli' exit Minitar::CLI.run(ARGV) diff --git a/lib/minitar-cli.rb b/lib/minitar-cli.rb deleted file mode 100644 index 8fd2b7a..0000000 --- a/lib/minitar-cli.rb +++ /dev/null @@ -1,3 +0,0 @@ -# coding: utf-8 - -require 'minitar/cli' diff --git a/lib/minitar/cli.rb b/lib/minitar/cli.rb index 8375bae..c3e9b84 100644 --- a/lib/minitar/cli.rb +++ b/lib/minitar/cli.rb @@ -1,607 +1,64 @@ -#!/usr/bin/env ruby -#-- -# Archive::Tar::Baby 0.5.2 -# Copyright 2004 Mauricio Julio Ferna'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 , copyright 2001 - 2004. -# -# It is licensed under the GNU General Public Licence or Ruby's licence. -# -# $Id$ -#++ +# frozen_string_literal: true -require 'zlib' -require 'optparse' -require 'ostruct' -require 'fileutils' +require 'minitar' -module Minitar - module CLI - VERSION = '0.6' - class CommandPattern - class AbstractCommandError < Exception; end - class UnknownCommandError < RuntimeError; end - class CommandAlreadyExists < RuntimeError; end +# The Minitar command-line application. +class Minitar::CLI + VERSION = '0.6' #:nodoc: - class << self - def add(command) - command = command.new if command.kind_of?(Class) + class AbstractCommandError < Exception; end + class UnknownCommandError < StandardError; end + class CommandAlreadyExists < StandardError; end - @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 - alias_method :<<, :add - - attr_reader :default - def default=(command) - 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 show help on - (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] + - -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. + def self.run(argv, input = $stdin, output = $stdout, error = $stderr) + new(input, output, error).run(argv) + end -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. + attr_reader :commander + attr_reader :ioe + + def initialize(input = $stdin, output = $stdout, error = $stderr) + @ioe = { + :input => input, + :output => output, + :error => error, + } + @commander = Minitar::CLI::Commander.new(ioe) + Minitar::CLI::Command.children.each { |command| + commander.register(command) + } + commander.default_command = 'help' + end -create Options: - --compress, -z Compresses the tarfile with gzip. + def run(argv) + opts = { } - EOH - end + if argv.include?("--version") + output << "minitar #{VERSION}\n" 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] [+] - -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 + if argv.include?("--verbose") or argv.include?("-V") + opts[:verbose] = true + argv.delete("--verbose") + argv.delete("-V") 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].to_sym - 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] [+] - -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 [], -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 + if argv.include?("--progress") or argv.include?("-P") + opts[:progress] = true + opts[:verbose] = false + argv.delete("--progress") + argv.delete("-P") 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 << "minitar #{VERSION}\n" - 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 + command = commander[(argv.shift or "").downcase] + command ||= commander["help"] + return command.call(argv, opts) end end + +require 'minitar/cli/command' +require 'minitar/cli/commander' +require 'minitar/cli/command/help' +require 'minitar/cli/command/create' +require 'minitar/cli/command/extract' +require 'minitar/cli/command/list' diff --git a/lib/minitar/cli/command.rb b/lib/minitar/cli/command.rb new file mode 100644 index 0000000..b73190b --- /dev/null +++ b/lib/minitar/cli/command.rb @@ -0,0 +1,43 @@ +# frozen_string_literal: true + +class Minitar::CLI::Command + @children = [] + + attr_reader :commander + attr_reader :ioe + + class << self + attr_reader :children + + def inherited(subclass) + children << subclass + end + end + + module CatchMinitarErrors + def call(args, opts) + run(args, opts) + rescue Archive::Tar::Minitar::Error => error + ioe[:error] << "#{error}\n" + 5 + end + end + + def initialize(commander) + @commander = commander + @ioe = commander.ioe + end + + def name + raise Minitar::CLI::AbstractCommandError + end + + def call(args, opts = {}) + raise Minitar::CLI::AbstractCommandError + end + alias [] call + + def help + raise Minitar::CLI::AbstractCommandError + end +end diff --git a/lib/minitar/cli/command/create.rb b/lib/minitar/cli/command/create.rb new file mode 100644 index 0000000..d3bae79 --- /dev/null +++ b/lib/minitar/cli/command/create.rb @@ -0,0 +1,123 @@ +# frozen_string_literal: true + +class Minitar::CLI::Command::Create < Minitar::CLI::Command + def name + "create" + end + + def altname + "cr" + end + + HELP = <<-EOH + minitar create [OPTIONS] + + +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 + + include CatchMinitarErrors + + def run(args, opts = {}) + 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" + commander.command("help").call(%w(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] + require 'powerbar' + progress = PowerBar.new(:msg => opts[:name], :total => 1) + watcher = lambda do |action, name, stats| + progress_info = {} + + case action + when :file_start, :dir + progress_info[:msg] = File.basename(name) + + if action == :dir + progress_info[:total] = progress.total + 1 + progress_info[:done] = progress.done + 1 + else + progress_info[:total] = progress.total + stats[:size] + end + when :file_progress + progress_info[:done] = progress.done + stats[:currinc] + end + + progress.show(progress_info) + end + finisher = lambda do + progress.show(:msg => opts[:name]) + progress.close(true) + 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 + end +end diff --git a/lib/minitar/cli/command/extract.rb b/lib/minitar/cli/command/extract.rb new file mode 100644 index 0000000..f7e2444 --- /dev/null +++ b/lib/minitar/cli/command/extract.rb @@ -0,0 +1,157 @@ +# frozen_string_literal: true + +class Minitar::CLI::Command::Extract < Minitar::CLI::Command + def name + "extract" + end + + def altname + "ex" + end + + HELP = <<-EOH + minitar extract [OPTIONS] [+] + +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 + + include CatchMinitarErrors + + def run(args, opts = {}) + argv = [] + output = nil + dest = "." + files = [] + + while (arg = args.shift) + case arg + when '--uncompress', '-z' + opts[:uncompress] = true + when '--pipe' + output = ioe[:output] + ioe[:output] = ioe[:error] + when '--output', '-o' + dest = args.shift + else + argv << arg + end + end + + if argv.size < 1 + ioe[:output] << "Not enough arguments.\n\n" + commander.command("help").call(%w(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| + ioe[:output] << "#{name}\n" if action == :dir or action == :file_done + end + finisher = lambda { ioe[:output] << "\n" } + elsif opts[:progress] + require 'powerbar' + progress = PowerBar.new(:msg => opts[:name], :total => 1) + watcher = lambda do |action, name, stats| + progress_info = {} + + case action + when :file_start, :dir + progress_info[:msg] = File.basename(name) + if action == :dir + progress_info[:total] = progress.total + 1 + progress_info[:done] = progress.done + 1 + else + progress_info[:total] = progress.total + stats[:entry].size + end + when :file_progress + progress_info[:done] = progress.done + stats[:currinc] + end + + progress.show(progress_info) + end + finisher = lambda do + progress.show(:msg => opts[:name]) + progress.close(true) + 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 + end +end diff --git a/lib/minitar/cli/command/help.rb b/lib/minitar/cli/command/help.rb new file mode 100644 index 0000000..a8f7416 --- /dev/null +++ b/lib/minitar/cli/command/help.rb @@ -0,0 +1,52 @@ +# frozen_string_literal: true + +class Minitar::CLI::Command::Help < Minitar::CLI::Command + def name + "help" + end + + COMMANDS = <<-EOS +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. + + EOS + + BASIC = <<-EOS +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 show help on + (e.g., 'minitar help create') +EOS + + def call(args, opts = {}) + help_on = args.shift + + if commander.command?(help_on) + ioe[:output] << commander[help_on].help + elsif help_on == "commands" + ioe[:output] << COMMANDS + else + ioe[:output] << "Unknown command: #{help_on}\n" unless help_on.nil? or help_on.empty? + ioe[:output] << help + end + + 0 + end + + def help + BASIC + end +end diff --git a/lib/minitar/cli/command/list.rb b/lib/minitar/cli/command/list.rb new file mode 100644 index 0000000..326fb51 --- /dev/null +++ b/lib/minitar/cli/command/list.rb @@ -0,0 +1,159 @@ +# frozen_string_literal: true + +class Minitar::CLI::Command::List < Minitar::CLI::Command + def name + "list" + end + + def altname + "ls" + end + + HELP = <<-EOH + minitar list [OPTIONS] [+] + +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 [], -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 + + def modestr(mode) + s = String.new("---") + s[0] = ?r if (mode & 4) == 4 + s[1] = ?w if (mode & 2) == 2 + s[2] = ?x if (mode & 1) == 1 + s + end + + include CatchMinitarErrors + + def run(args, opts = {}) + argv = [] + output = nil + 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" + commander.command("help").call(%w(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].to_sym + 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 = String.new(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 + end +end diff --git a/lib/minitar/cli/commander.rb b/lib/minitar/cli/commander.rb new file mode 100644 index 0000000..4431d29 --- /dev/null +++ b/lib/minitar/cli/commander.rb @@ -0,0 +1,59 @@ +# frozen_string_literal: true + +class Minitar::CLI::Commander + attr_reader :commands + attr_reader :default_command + attr_reader :ioe + + def initialize(ioe) + @ioe = default_ioe(ioe) + @commands = {} + @default_command = nil + end + + def register(command) + command = command.new(self) if command.kind_of?(Class) + raise CommandAlreadyExists if command.commander != self + raise CommandAlreadyExists if command?(command.name) + + commands[command.name] = command + + if command.respond_to?(:altname) + commands[command.altname] = command unless command?(command.altname) + end + end + + def default_command=(command) + command = command.new if command.kind_of?(Class) + + @default_command = + if command.kind_of?(Minitar::CLI::Command) + register(command) unless command?(command.name) + command + elsif command?(command) + 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_command + end + end + alias [] command + + def default_ioe(ioe = {}) + ioe[:input] ||= $stdin + ioe[:output] ||= $stdout + ioe[:error] ||= $stderr + ioe + end +end diff --git a/minitar-cli.gemspec b/minitar-cli.gemspec index 1f244c2..0348b2b 100644 --- a/minitar-cli.gemspec +++ b/minitar-cli.gemspec @@ -8,67 +8,61 @@ Gem::Specification.new do |s| s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version= s.require_paths = ["lib"] s.authors = ["Austin Ziegler"] - s.date = "2014-12-22" + s.date = "2017-02-07" s.description = "minitar-cli is a pure-Ruby command-line tool that uses\n{minitar}[https://github.com/halostatue/minitar] to provide a command-line\ntool, +minitar+, for working with POSIX tar(1) archive files.\n\nThis is release 0.6, extracted from {minitar}[https://halostatue.ca/minitar],\nwith modernizations." s.email = ["halostatue@gmail.com"] s.executables = ["minitar"] - s.extra_rdoc_files = ["Contributing.rdoc", "History.rdoc", "Licence.rdoc", "Manifest.txt", "README.rdoc", "docs/bsdl.txt", "docs/ruby.txt", "Contributing.rdoc", "History.rdoc", "Licence.rdoc", "README.rdoc"] - s.files = [".autotest", ".gemtest", ".gitignore", ".hoerc", "Contributing.rdoc", "History.rdoc", "Licence.rdoc", "Manifest.txt", "README.rdoc", "Rakefile", "bin/minitar", "docs/bsdl.txt", "docs/ruby.txt", "lib/minitar-cli.rb", "lib/minitar/cli.rb", "test/minitest_helper.rb"] + s.extra_rdoc_files = ["Contributing.md", "History.md", "Licence.md", "Manifest.txt", "README.rdoc", "docs/bsdl.txt", "docs/ruby.txt"] + s.files = ["Contributing.md", "History.md", "Licence.md", "Manifest.txt", "README.rdoc", "Rakefile", "bin/minitar", "docs/bsdl.txt", "docs/ruby.txt", "lib/minitar/cli.rb", "lib/minitar/cli/command.rb", "lib/minitar/cli/command/create.rb", "lib/minitar/cli/command/extract.rb", "lib/minitar/cli/command/help.rb", "lib/minitar/cli/command/list.rb", "lib/minitar/cli/commander.rb", "test/fixtures/bad-dir.tar.gz", "test/fixtures/spaces.tar.gz", "test/minitest_helper.rb", "test/support/command_line_test_helper.rb", "test/test_cli_help.rb", "test/test_cli_list.rb"] s.homepage = "https://github.com/halostatue/minitar-cli/" s.licenses = ["Ruby", "BSD-2-Clause"] s.rdoc_options = ["--main", "README.rdoc"] s.required_ruby_version = Gem::Requirement.new(">= 1.8") - s.rubygems_version = "2.4.2" + s.rubygems_version = "2.5.1" s.summary = "minitar-cli is a pure-Ruby command-line tool that uses {minitar}[https://github.com/halostatue/minitar] to provide a command-line tool, +minitar+, for working with POSIX tar(1) archive files" if s.respond_to? :specification_version then s.specification_version = 4 if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then - s.add_runtime_dependency(%q, ["~> 0.6.0"]) + s.add_runtime_dependency(%q, ["~> 0.6.0"]) s.add_runtime_dependency(%q, ["~> 1.0"]) - s.add_development_dependency(%q, ["~> 5.4"]) - s.add_development_dependency(%q, ["~> 4.0"]) + s.add_development_dependency(%q, ["~> 5.9"]) s.add_development_dependency(%q, ["~> 1.0"]) s.add_development_dependency(%q, ["~> 1.1"]) s.add_development_dependency(%q, ["~> 1.6"]) s.add_development_dependency(%q, ["~> 1.0"]) s.add_development_dependency(%q, ["~> 1.2"]) - s.add_development_dependency(%q, ["< 2", ">= 1.0.b"]) - s.add_development_dependency(%q, ["~> 10.0"]) - s.add_development_dependency(%q, ["~> 0.7"]) - s.add_development_dependency(%q, ["~> 0.7"]) - s.add_development_dependency(%q, ["~> 3.13"]) + s.add_development_dependency(%q, ["< 2", ">= 1.0"]) + s.add_development_dependency(%q, ["< 12", ">= 10.0"]) + s.add_development_dependency(%q, [">= 0.0"]) + s.add_development_dependency(%q, ["~> 3.16"]) else - s.add_dependency(%q, ["~> 0.6.0"]) + s.add_dependency(%q, ["~> 0.6.0"]) s.add_dependency(%q, ["~> 1.0"]) - s.add_dependency(%q, ["~> 5.4"]) - s.add_dependency(%q, ["~> 4.0"]) + s.add_dependency(%q, ["~> 5.9"]) s.add_dependency(%q, ["~> 1.0"]) s.add_dependency(%q, ["~> 1.1"]) s.add_dependency(%q, ["~> 1.6"]) s.add_dependency(%q, ["~> 1.0"]) s.add_dependency(%q, ["~> 1.2"]) - s.add_dependency(%q, ["< 2", ">= 1.0.b"]) - s.add_dependency(%q, ["~> 10.0"]) - s.add_dependency(%q, ["~> 0.7"]) - s.add_dependency(%q, ["~> 0.7"]) - s.add_dependency(%q, ["~> 3.13"]) + s.add_dependency(%q, ["< 2", ">= 1.0"]) + s.add_dependency(%q, ["< 12", ">= 10.0"]) + s.add_dependency(%q, [">= 0.0"]) + s.add_dependency(%q, ["~> 3.16"]) end else - s.add_dependency(%q, ["~> 0.6.0"]) + s.add_dependency(%q, ["~> 0.6.0"]) s.add_dependency(%q, ["~> 1.0"]) - s.add_dependency(%q, ["~> 5.4"]) - s.add_dependency(%q, ["~> 4.0"]) + s.add_dependency(%q, ["~> 5.9"]) s.add_dependency(%q, ["~> 1.0"]) s.add_dependency(%q, ["~> 1.1"]) s.add_dependency(%q, ["~> 1.6"]) s.add_dependency(%q, ["~> 1.0"]) s.add_dependency(%q, ["~> 1.2"]) - s.add_dependency(%q, ["< 2", ">= 1.0.b"]) - s.add_dependency(%q, ["~> 10.0"]) - s.add_dependency(%q, ["~> 0.7"]) - s.add_dependency(%q, ["~> 0.7"]) - s.add_dependency(%q, ["~> 3.13"]) + s.add_dependency(%q, ["< 2", ">= 1.0"]) + s.add_dependency(%q, ["< 12", ">= 10.0"]) + s.add_dependency(%q, [">= 0.0"]) + s.add_dependency(%q, ["~> 3.16"]) end end diff --git a/test/fixtures/bad-dir.tar.gz b/test/fixtures/bad-dir.tar.gz new file mode 100644 index 0000000..955d026 Binary files /dev/null and b/test/fixtures/bad-dir.tar.gz differ diff --git a/test/fixtures/spaces.tar.gz b/test/fixtures/spaces.tar.gz new file mode 100644 index 0000000..b3cb71e Binary files /dev/null and b/test/fixtures/spaces.tar.gz differ diff --git a/test/minitest_helper.rb b/test/minitest_helper.rb index 0533c03..3296bfe 100644 --- a/test/minitest_helper.rb +++ b/test/minitest_helper.rb @@ -1,93 +1,11 @@ # -*- ruby encoding: utf-8 -*- require 'fileutils' +require 'minitar' gem 'minitest' require 'minitest/autorun' -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 assert_modes_equal(expected, actual, name) - unless RUBY_PLATFORM =~ /win32/ - expected = "%04o" % (expected & 0777) - actual = "%04o" % (actual & 0777) - - assert_equal(expected, actual, "Mode for #{name} does not match") - end - 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.bytes.to_a - 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 +Dir.glob(File.join(File.dirname(__FILE__), 'support/*.rb')).each do |support| + require support end diff --git a/test/support/command_line_test_helper.rb b/test/support/command_line_test_helper.rb new file mode 100644 index 0000000..501300b --- /dev/null +++ b/test/support/command_line_test_helper.rb @@ -0,0 +1,11 @@ +# frozen_string_literal: true + +require 'minitar/cli' + +module CommandLineTestHelper + def minitar(*args) + Minitar::CLI.run(args) + end + + Minitest::Test.send(:include, self) +end diff --git a/test/test_cli_help.rb b/test/test_cli_help.rb new file mode 100644 index 0000000..0e362a4 --- /dev/null +++ b/test/test_cli_help.rb @@ -0,0 +1,71 @@ +# frozen_string_literal: true + +require 'minitest_helper' + +class TestCLIHelp < Minitest::Test + def test_help_output_with_no_args + assert_output Minitar::CLI::Command::Help::BASIC do + assert_equal 0, minitar + end + end + + def test_help_output_with_help + assert_output Minitar::CLI::Command::Help::BASIC do + assert_equal 0, minitar("help") + end + end + + def test_help_output_with_bad_command + assert_output Minitar::CLI::Command::Help::BASIC do + assert_equal 0, minitar("foo") + end + end + + def test_help_output_with_help_bad_command + assert_output "Unknown command: foo\n#{Minitar::CLI::Command::Help::BASIC}" do + assert_equal 0, minitar(*%w(help foo)) + end + end + + def test_help_output_commands + assert_output Minitar::CLI::Command::Help::COMMANDS do + assert_equal 0, minitar(*%w(help commands)) + end + end + + def test_help_output_create + assert_output Minitar::CLI::Command::Create::HELP do + assert_equal 0, minitar(*%w(help create)) + end + end + + def test_help_output_create_minargs + assert_output "Not enough arguments.\n\n#{Minitar::CLI::Command::Create::HELP}" do + assert_equal 255, minitar(*%w(create)) + end + end + + def test_help_output_list + assert_output Minitar::CLI::Command::List::HELP do + assert_equal 0, minitar(*%w(help list)) + end + end + + def test_help_output_list_minargs + assert_output "Not enough arguments.\n\n#{Minitar::CLI::Command::List::HELP}" do + assert_equal 255, minitar(*%w(list)) + end + end + + def test_help_output_extract + assert_output Minitar::CLI::Command::Extract::HELP do + assert_equal 0, minitar(*%w(help extract)) + end + end + + def test_help_output_extract_minargs + assert_output "Not enough arguments.\n\n#{Minitar::CLI::Command::Extract::HELP}" do + assert_equal 255, minitar(*%w(extract)) + end + end +end diff --git a/test/test_cli_list.rb b/test/test_cli_list.rb new file mode 100644 index 0000000..1c5699e --- /dev/null +++ b/test/test_cli_list.rb @@ -0,0 +1,218 @@ +# frozen_string_literal: true + +class TestCLIList < Minitest::Test + def list_bad_dir(args = []) + list_fixture('bad-dir', args) + end + + def list_spaces(args = []) + list_fixture('spaces', args) + end + + def list_fixture(name, args = []) + args = %W(list test/fixtures/#{name}.tar.gz) + Array(args) + minitar(*args) + end + + def test_list_output_bad_dir_fixture + assert_output "../qwerty\n" do + assert_equal 0, list_bad_dir + end + end + + def test_list_output_spaces + expected = <<-EOS +./ +./.autotest +./.byebug_history +./.coveralls.yml +./.gemtest +./.gitignore +./.hoerc +./.pullreview.yml +./.rubocop.yml +./.simplecov-prelude.rb +./.travis.yml +./appveyor.yml +./bin/ +./Code-of-Conduct.md +./Contributing.md +./docs/ +./Gemfile +./Gemfile.lock +./History.md +./lib/ +./Licence.md +./Manifest.txt +./minitar-cli.gemspec +./Rakefile +./README.rdoc +./lib/minitar/ +./lib/minitar/cli/ +./lib/minitar/cli.rb +./lib/minitar/cli/command/ +./lib/minitar/cli/command.rb +./lib/minitar/cli/commander.rb +./lib/minitar/cli/command/create.rb +./lib/minitar/cli/command/extract.rb +./lib/minitar/cli/command/help.rb +./lib/minitar/cli/command/list.rb +./docs/bsdl.txt +./docs/ruby.txt +./bin/minitar + EOS + + assert_output expected do + assert_equal 0, list_spaces + end + end + + def test_list_output_spaces_verbose + expected = <<-EOS +drwxr-xr-x 0 austin staff 0 Feb 07 00:24 ./ +-rw-r--r-- 1 austin staff 688 Feb 07 00:29 ./.autotest +-rw-r--r-- 0 austin staff 160 Feb 07 00:29 ./.byebug_history +-rw-r--r-- 0 austin staff 28 Feb 07 00:29 ./.coveralls.yml +-rw-r--r-- 0 austin staff 0 Feb 07 00:29 ./.gemtest +-rw-r--r-- 0 austin staff 141 Feb 07 00:29 ./.gitignore +-rw-r--r-- 0 austin staff 505 Feb 07 00:29 ./.hoerc +-rw-r--r-- 2 austin staff 1319 Feb 07 00:29 ./.pullreview.yml +-rw-r--r-- 3 austin staff 1759 Feb 07 00:29 ./.rubocop.yml +-rw-r--r-- 0 austin staff 211 Feb 07 00:29 ./.simplecov-prelude.rb +-rw-r--r-- 1 austin staff 639 Feb 07 00:29 ./.travis.yml +-rw-r--r-- 1 austin staff 643 Feb 07 00:29 ./appveyor.yml +drwxr-xr-x 0 austin staff 0 Feb 06 11:46 ./bin/ +-rw-r--r-- 6 austin staff 3230 Feb 07 00:29 ./Code-of-Conduct.md +-rw-r--r-- 4 austin staff 2499 Feb 07 00:29 ./Contributing.md +drwxr-xr-x 0 austin staff 0 Nov 02 23:43 ./docs/ +-rw-r--r-- 1 austin staff 548 Feb 07 00:29 ./Gemfile +-rw-r--r-- 2 austin staff 1484 Feb 07 00:29 ./Gemfile.lock +-rw-r--r-- 1 austin staff 575 Feb 07 00:29 ./History.md +drwxr-xr-x 0 austin staff 0 Feb 06 11:44 ./lib/ +-rw-r--r-- 0 austin staff 410 Feb 07 00:29 ./Licence.md +-rw-r--r-- 0 austin staff 453 Feb 07 00:29 ./Manifest.txt +-rw-r--r-- 7 austin staff 3974 Feb 07 00:29 ./minitar-cli.gemspec +-rw-r--r-- 2 austin staff 1267 Feb 07 00:29 ./Rakefile +-rw-r--r-- 2 austin staff 1261 Feb 07 00:29 ./README.rdoc +drwxr-xr-x 0 austin staff 0 Feb 06 16:48 ./lib/minitar/ +drwxr-xr-x 0 austin staff 0 Feb 06 17:39 ./lib/minitar/cli/ +-rw-r--r-- 3 austin staff 1582 Feb 07 00:29 ./lib/minitar/cli.rb +drwxr-xr-x 0 austin staff 0 Feb 07 00:16 ./lib/minitar/cli/command/ +-rw-r--r-- 1 austin staff 728 Feb 07 00:29 ./lib/minitar/cli/command.rb +-rw-r--r-- 2 austin staff 1287 Feb 07 00:29 ./lib/minitar/cli/commander.rb +-rw-r--r-- 6 austin staff 3119 Feb 07 00:29 ./lib/minitar/cli/command/create.rb +-rw-r--r-- 8 austin staff 4296 Feb 07 00:29 ./lib/minitar/cli/command/extract.rb +-rw-r--r-- 2 austin staff 1362 Feb 07 00:29 ./lib/minitar/cli/command/help.rb +-rw-r--r-- 7 austin staff 3881 Feb 07 00:29 ./lib/minitar/cli/command/list.rb +-rw-r--r-- 2 austin staff 1226 Feb 07 00:29 ./docs/bsdl.txt +-rw-r--r-- 4 austin staff 2503 Feb 07 00:29 ./docs/ruby.txt +-rwxr-xr-x 0 austin staff 219 Feb 07 00:29 ./bin/minitar + EOS + + assert_output expected do + assert_equal 0, list_spaces("--verbose") + end + end + + def test_list_output_spaces_verbose_sort_size + expected = <<-EOS +drwxr-xr-x 0 austin staff 0 Feb 07 00:24 ./ +-rw-r--r-- 0 austin staff 0 Feb 07 00:29 ./.gemtest +drwxr-xr-x 0 austin staff 0 Feb 06 11:46 ./bin/ +drwxr-xr-x 0 austin staff 0 Nov 02 23:43 ./docs/ +drwxr-xr-x 0 austin staff 0 Feb 06 11:44 ./lib/ +drwxr-xr-x 0 austin staff 0 Feb 06 16:48 ./lib/minitar/ +drwxr-xr-x 0 austin staff 0 Feb 06 17:39 ./lib/minitar/cli/ +drwxr-xr-x 0 austin staff 0 Feb 07 00:16 ./lib/minitar/cli/command/ +-rw-r--r-- 0 austin staff 28 Feb 07 00:29 ./.coveralls.yml +-rw-r--r-- 0 austin staff 141 Feb 07 00:29 ./.gitignore +-rw-r--r-- 0 austin staff 160 Feb 07 00:29 ./.byebug_history +-rw-r--r-- 0 austin staff 211 Feb 07 00:29 ./.simplecov-prelude.rb +-rwxr-xr-x 0 austin staff 219 Feb 07 00:29 ./bin/minitar +-rw-r--r-- 0 austin staff 410 Feb 07 00:29 ./Licence.md +-rw-r--r-- 0 austin staff 453 Feb 07 00:29 ./Manifest.txt +-rw-r--r-- 0 austin staff 505 Feb 07 00:29 ./.hoerc +-rw-r--r-- 1 austin staff 548 Feb 07 00:29 ./Gemfile +-rw-r--r-- 1 austin staff 575 Feb 07 00:29 ./History.md +-rw-r--r-- 1 austin staff 639 Feb 07 00:29 ./.travis.yml +-rw-r--r-- 1 austin staff 643 Feb 07 00:29 ./appveyor.yml +-rw-r--r-- 1 austin staff 688 Feb 07 00:29 ./.autotest +-rw-r--r-- 1 austin staff 728 Feb 07 00:29 ./lib/minitar/cli/command.rb +-rw-r--r-- 2 austin staff 1226 Feb 07 00:29 ./docs/bsdl.txt +-rw-r--r-- 2 austin staff 1261 Feb 07 00:29 ./README.rdoc +-rw-r--r-- 2 austin staff 1267 Feb 07 00:29 ./Rakefile +-rw-r--r-- 2 austin staff 1287 Feb 07 00:29 ./lib/minitar/cli/commander.rb +-rw-r--r-- 2 austin staff 1319 Feb 07 00:29 ./.pullreview.yml +-rw-r--r-- 2 austin staff 1362 Feb 07 00:29 ./lib/minitar/cli/command/help.rb +-rw-r--r-- 2 austin staff 1484 Feb 07 00:29 ./Gemfile.lock +-rw-r--r-- 3 austin staff 1582 Feb 07 00:29 ./lib/minitar/cli.rb +-rw-r--r-- 3 austin staff 1759 Feb 07 00:29 ./.rubocop.yml +-rw-r--r-- 4 austin staff 2499 Feb 07 00:29 ./Contributing.md +-rw-r--r-- 4 austin staff 2503 Feb 07 00:29 ./docs/ruby.txt +-rw-r--r-- 6 austin staff 3119 Feb 07 00:29 ./lib/minitar/cli/command/create.rb +-rw-r--r-- 6 austin staff 3230 Feb 07 00:29 ./Code-of-Conduct.md +-rw-r--r-- 7 austin staff 3881 Feb 07 00:29 ./lib/minitar/cli/command/list.rb +-rw-r--r-- 7 austin staff 3974 Feb 07 00:29 ./minitar-cli.gemspec +-rw-r--r-- 8 austin staff 4296 Feb 07 00:29 ./lib/minitar/cli/command/extract.rb + EOS + + assert_output expected do + assert_equal 0, list_spaces(%w(--verbose --sort size)) + end + end + + def test_list_output_spaces_verbose_sort_size_reverse + expected = <<-EOS +-rw-r--r-- 8 austin staff 4296 Feb 07 00:29 ./lib/minitar/cli/command/extract.rb +-rw-r--r-- 7 austin staff 3974 Feb 07 00:29 ./minitar-cli.gemspec +-rw-r--r-- 7 austin staff 3881 Feb 07 00:29 ./lib/minitar/cli/command/list.rb +-rw-r--r-- 6 austin staff 3230 Feb 07 00:29 ./Code-of-Conduct.md +-rw-r--r-- 6 austin staff 3119 Feb 07 00:29 ./lib/minitar/cli/command/create.rb +-rw-r--r-- 4 austin staff 2503 Feb 07 00:29 ./docs/ruby.txt +-rw-r--r-- 4 austin staff 2499 Feb 07 00:29 ./Contributing.md +-rw-r--r-- 3 austin staff 1759 Feb 07 00:29 ./.rubocop.yml +-rw-r--r-- 3 austin staff 1582 Feb 07 00:29 ./lib/minitar/cli.rb +-rw-r--r-- 2 austin staff 1484 Feb 07 00:29 ./Gemfile.lock +-rw-r--r-- 2 austin staff 1362 Feb 07 00:29 ./lib/minitar/cli/command/help.rb +-rw-r--r-- 2 austin staff 1319 Feb 07 00:29 ./.pullreview.yml +-rw-r--r-- 2 austin staff 1287 Feb 07 00:29 ./lib/minitar/cli/commander.rb +-rw-r--r-- 2 austin staff 1267 Feb 07 00:29 ./Rakefile +-rw-r--r-- 2 austin staff 1261 Feb 07 00:29 ./README.rdoc +-rw-r--r-- 2 austin staff 1226 Feb 07 00:29 ./docs/bsdl.txt +-rw-r--r-- 1 austin staff 728 Feb 07 00:29 ./lib/minitar/cli/command.rb +-rw-r--r-- 1 austin staff 688 Feb 07 00:29 ./.autotest +-rw-r--r-- 1 austin staff 643 Feb 07 00:29 ./appveyor.yml +-rw-r--r-- 1 austin staff 639 Feb 07 00:29 ./.travis.yml +-rw-r--r-- 1 austin staff 575 Feb 07 00:29 ./History.md +-rw-r--r-- 1 austin staff 548 Feb 07 00:29 ./Gemfile +-rw-r--r-- 0 austin staff 505 Feb 07 00:29 ./.hoerc +-rw-r--r-- 0 austin staff 453 Feb 07 00:29 ./Manifest.txt +-rw-r--r-- 0 austin staff 410 Feb 07 00:29 ./Licence.md +-rwxr-xr-x 0 austin staff 219 Feb 07 00:29 ./bin/minitar +-rw-r--r-- 0 austin staff 211 Feb 07 00:29 ./.simplecov-prelude.rb +-rw-r--r-- 0 austin staff 160 Feb 07 00:29 ./.byebug_history +-rw-r--r-- 0 austin staff 141 Feb 07 00:29 ./.gitignore +-rw-r--r-- 0 austin staff 28 Feb 07 00:29 ./.coveralls.yml +drwxr-xr-x 0 austin staff 0 Feb 07 00:16 ./lib/minitar/cli/command/ +drwxr-xr-x 0 austin staff 0 Feb 06 17:39 ./lib/minitar/cli/ +drwxr-xr-x 0 austin staff 0 Feb 06 16:48 ./lib/minitar/ +drwxr-xr-x 0 austin staff 0 Feb 06 11:44 ./lib/ +drwxr-xr-x 0 austin staff 0 Nov 02 23:43 ./docs/ +drwxr-xr-x 0 austin staff 0 Feb 06 11:46 ./bin/ +-rw-r--r-- 0 austin staff 0 Feb 07 00:29 ./.gemtest +drwxr-xr-x 0 austin staff 0 Feb 07 00:24 ./ + EOS + + assert_output expected do + assert_equal 0, list_spaces(%w(--verbose --sort size --reverse)) + end + end + + def test_list_stdin + assert_output "../qwerty\n" do + File.open('test/fixtures/bad-dir.tar.gz') do |f| + assert_equal 0, Minitar::CLI.run(%w(list - --uncompress), f) + end + end + end +end