Commit cabeb85d authored by Dmitry Bogatov's avatar Dmitry Bogatov

Import Upstream version 7.1

parent a17df1c3
......@@ -36,6 +36,9 @@ gem archives
7z archives
7z
lzh archives
lha
Microsoft Cabinet archives
cabextract
......
Changes in dtrx
===============
Version 7.1
-----------
New features
~~~~~~~~~~~~
* LZH archives are now supported.
Bug fixes
~~~~~~~~~
* dtrx will no longer offer to extract the zero archive files found in a
zero-file archive.
* Temporary directories will be cleaned up after extracting an empty
archive.
Version 7.0
-----------
At this point, I consider dtrx to be mature software. It's maybe a little
too interactive, but otherwise it does everything I want, and it does it
very well. Expect new releases to be few and far between going forward.
New features
~~~~~~~~~~~~
* If any of dtrx's command line arguments are URLs, it will automatically
download them with `wget -c` in the current directory before extracting
them. See the documentation for more information about this feature.
Note that there might be trouble if there's already a file in the
directory where wget would normally save the download.
Enhancements
~~~~~~~~~~~~
* dtrx will try to extract ZIP files with 7z if unzip is not successful.
Thanks to Edward H for reporting this bug.
* dtrx will be smarter about removing extensions from filenames when
extracting to a new directory or file.
* dtrx will not ask you if you want to recurse through an archive if
the number of archives inside the original file is small.
Version 6.6
-----------
......
Metadata-Version: 1.0
Name: dtrx
Version: 6.6
Version: 7.1
Summary: Script to intelligently extract multiple archive types
Home-page: http://www.brettcsmith.org/2007/dtrx/
Author: Brett Smith
......@@ -8,17 +8,17 @@ Author-email: brettcsmith@brettcsmith.org
License: GNU General Public License, version 3 or later
Download-URL: http://www.brettcsmith.org/2007/dtrx/
Description: dtrx extracts archives in a number of different
formats; it currently supports tar, zip (including self-extracting
.exe files), cpio, rpm, deb, gem, 7z, cab, rar, and InstallShield
files. It can also decompress files compressed with gzip, bzip2,
lzma, xz, or compress.
formats; it currently supports tar, zip (including self-extracting
.exe files), cpio, rpm, deb, gem, 7z, cab, rar, and InstallShield
files. It can also decompress files compressed with gzip, bzip2,
lzma, xz, or compress.
In addition to providing one command to handle many different archive
types, dtrx also aids the user by extracting contents consistently.
By default, everything will be written to a dedicated directory
that's named after the archive. dtrx will also change the
permissions to ensure that the owner can read and write all those
files.
In addition to providing one command to handle many different archive
types, dtrx also aids the user by extracting contents consistently.
By default, everything will be written to a dedicated directory
that's named after the archive. dtrx will also change the
permissions to ensure that the owner can read and write all those
files.
Platform: UNKNOWN
Classifier: Development Status :: 5 - Production/Stable
Classifier: Environment :: Console
......
......@@ -7,10 +7,10 @@ cleanly extract many archive types
----------------------------------
:Author: Brett Smith <brettcsmith@brettcsmith.org>
:Date: 2009-07-04
:Date: 2011-11-19
:Copyright:
dtrx 6.5 is copyright © 2006-2009 Brett Smith and others. Feel free to
dtrx 7.1 is copyright © 2006-2011 Brett Smith and others. Feel free to
send comments, bug reports, patches, and so on. You can find the latest
version of dtrx on its home page at
<http://www.brettcsmith.org/2007/dtrx/>.
......@@ -28,7 +28,7 @@ cleanly extract many archive types
You should have received a copy of the GNU General Public License along
with this program; if not, see <http://www.gnu.org/licenses/>.
:Version: 6.5
:Version: 7.1
:Manual section: 1
SYNOPSIS
......@@ -41,8 +41,8 @@ DESCRIPTION
dtrx extracts archives in a number of different formats; it currently
supports tar, zip (including self-extracting .exe files), cpio, rpm, deb,
gem, 7z, cab, rar, and InstallShield files. It can also decompress files
compressed with gzip, bzip2, lzma, or compress.
gem, 7z, cab, rar, lzh, and InstallShield files. It can also decompress
files compressed with gzip, bzip2, lzma, xz, or compress.
In addition to providing one command to handle many different archive
types, dtrx also aids the user by extracting contents consistently. By
......@@ -55,6 +55,11 @@ arguments. For example::
$ dtrx coreutils-5.*.tar.gz
You may specify URLs as arguments as well. If you do, dtrx will use `wget
-c` to download the URL to the current directory and then extract what it
downloads. This may fail if you already have a file in the current
directory with the same name as the file you're trying to download.
OPTIONS
=======
......@@ -108,12 +113,11 @@ dtrx supports a number of options to mandate specific behavior:
contents.
-q, --quiet
Suppress warning messages. Listing this option twice will cause dtrx to
be silent.
Suppress warning messages. List this option twice to make dtrx silent.
-v, --verbose
Show the files that are being extracted. Listing this option twice will
cause dtrx to print debugging information.
Show the files that are being extracted. List this option twice to
print debugging information.
--help
Display basic help.
......
This diff is collapsed.
......@@ -3,7 +3,7 @@
from distutils.core import setup
setup(name="dtrx",
version = "6.6",
version = "7.1",
description = "Script to intelligently extract multiple archive types",
author = "Brett Smith",
author_email = "brettcsmith@brettcsmith.org",
......
......@@ -24,7 +24,10 @@ import yaml
import sys
import tempfile
from sets import Set as set
try:
set
except NameError:
from sets import Set as set
if os.path.exists('scripts/dtrx') and os.path.exists('tests'):
os.chdir('tests')
......@@ -34,16 +37,10 @@ else:
print "ERROR: Can't run tests in this directory!"
sys.exit(2)
X_SCRIPT = os.path.realpath('../scripts/dtrx')
DTRX_SCRIPT = os.path.realpath('../scripts/dtrx')
SHELL_CMD = ['sh', '-se']
ROOT_DIR = os.path.realpath(os.curdir)
OUTCOMES = ['error', 'failed', 'passed']
TESTSCRIPT_NAME = 'testscript.sh'
SCRIPT_PROLOGUE = """#!/bin/sh
set -e
"""
input_buffer = tempfile.TemporaryFile()
output_buffer = tempfile.TemporaryFile()
class ExtractorTestError(Exception):
pass
......@@ -62,25 +59,27 @@ class ExtractorTest(object):
if isinstance(value, str):
value = [value]
setattr(self, key, value)
def get_results(self, commands, stdin=None):
print >>output_buffer, "Output from %s:" % (' '.join(commands),)
output_buffer.flush()
status = subprocess.call(commands, stdout=output_buffer,
stderr=output_buffer, stdin=stdin)
process = subprocess.Popen(['find', '!', '-name', TESTSCRIPT_NAME],
stdout=subprocess.PIPE)
process.wait()
if self.input and (not self.input.endswith('\n')):
self.input = self.input + '\n'
def start_proc(self, command, stdin=None, output=None):
process = subprocess.Popen(command, stdin=subprocess.PIPE,
stdout=output, stderr=output)
if stdin:
process.stdin.write(stdin)
process.stdin.close()
return process
def get_results(self, command, stdin=None):
print >>self.outbuffer, "Output from %s:" % (' '.join(command),)
self.outbuffer.flush()
status = self.start_proc(command, stdin, self.outbuffer).wait()
process = subprocess.Popen(['find'], stdout=subprocess.PIPE)
output = process.stdout.read(-1)
process.stdout.close()
process.wait()
return status, set(output.split('\n'))
def write_script(self, commands):
script = open(TESTSCRIPT_NAME, 'w')
script.write("%s%s\n" % (SCRIPT_PROLOGUE, commands))
script.close()
subprocess.call(['chmod', 'u+w', TESTSCRIPT_NAME])
def run_script(self, key):
commands = getattr(self, key)
if commands is not None:
......@@ -88,38 +87,27 @@ class ExtractorTest(object):
directory_hint = '../'
else:
directory_hint = ''
self.write_script(commands)
subprocess.call(['sh', TESTSCRIPT_NAME, directory_hint])
self.start_proc(SHELL_CMD + [directory_hint], commands)
def get_shell_results(self):
self.run_script('prerun')
self.write_script(self.baseline)
return self.get_results(['sh', TESTSCRIPT_NAME] + self.filenames)
return self.get_results(SHELL_CMD + self.filenames, self.baseline)
def get_extractor_results(self):
self.run_script('prerun')
input_buffer.seek(0, 0)
input_buffer.truncate()
if self.input:
input_buffer.write(self.input)
if not self.input.endswith('\n'):
input_buffer.write('\n')
input_buffer.seek(0, 0)
input_buffer.flush()
return self.get_results([X_SCRIPT] + self.options + self.filenames,
input_buffer)
return self.get_results([DTRX_SCRIPT] + self.options + self.filenames,
self.input)
def get_posttest_result(self):
if not self.posttest:
return 0
self.write_script(self.posttest)
return subprocess.call(['sh', TESTSCRIPT_NAME])
return self.start_proc(SHELL_CMD, self.posttest).wait()
def clean(self):
self.run_script('cleanup')
if self.directory:
target = os.path.join(ROOT_DIR, self.directory)
extra_options = ['!', '-name', TESTSCRIPT_NAME]
extra_options = []
else:
target = ROOT_DIR
extra_options = ['(', '(', '-type', 'd',
......@@ -138,8 +126,8 @@ class ExtractorTest(object):
def show_status(self, status, message=None):
raw_status = status.lower()
if raw_status != 'passed':
output_buffer.seek(0, 0)
sys.stdout.write(output_buffer.read(-1))
self.outbuffer.seek(0, 0)
sys.stdout.write(self.outbuffer.read(-1))
if message is None:
last_part = ''
else:
......@@ -153,13 +141,13 @@ class ExtractorTest(object):
status, expected = self.get_shell_results()
self.clean()
if expected != actual:
print >>output_buffer, "Only in baseline results:"
print >>output_buffer, '\n'.join(expected.difference(actual))
print >>output_buffer, "Only in actual results:"
print >>output_buffer, '\n'.join(actual.difference(expected))
print >>self.outbuffer, "Only in baseline results:"
print >>self.outbuffer, '\n'.join(expected.difference(actual))
print >>self.outbuffer, "Only in actual results:"
print >>self.outbuffer, '\n'.join(actual.difference(expected))
return self.show_status('FAILED')
elif posttest_result != 0:
print >>output_buffer, "Posttest gave status code", posttest_result
print >>self.outbuffer, "Posttest gave status code", posttest_result
return self.show_status('FAILED')
return self.show_status('Passed')
......@@ -187,24 +175,23 @@ class ExtractorTest(object):
return None
def check_results(self):
output_buffer.seek(0, 0)
output_buffer.truncate()
self.clean()
status, actual = self.get_extractor_results()
output_buffer.seek(0, 0)
output_buffer.readline()
output = output_buffer.read(-1)
self.outbuffer.seek(0, 0)
self.outbuffer.readline()
output = self.outbuffer.read(-1)
problem = (self.have_error_mismatch(status) or
self.check_output(output) or self.grep_output(output))
if problem:
return self.show_status('FAILED', problem)
if self.baseline:
if self.baseline is not None:
return self.compare_results(actual)
else:
self.clean()
return self.show_status('Passed')
def run(self):
self.outbuffer = tempfile.TemporaryFile()
if self.directory:
os.mkdir(self.directory)
os.chdir(self.directory)
......@@ -212,6 +199,7 @@ class ExtractorTest(object):
result = self.check_results()
except ExtractorTestError, error:
result = self.show_status('ERROR', error)
self.outbuffer.close()
if self.directory:
os.chdir(ROOT_DIR)
subprocess.call(['chmod', '-R', '700', self.directory])
......@@ -240,5 +228,3 @@ for outcome in OUTCOMES:
for result in results:
counts[result] += 1
print " Totals:", ', '.join(["%s %s" % (counts[key], key) for key in OUTCOMES])
input_buffer.close()
output_buffer.close()
......@@ -22,6 +22,13 @@
cd test-1.23
unzip -q ../$1
- name: basic .lzh
filenames: test-1.23.lzh
baseline: |
mkdir test-1.23
cd test-1.23
lha xq ../$1
- name: basic .deb
filenames: test-1.23_all.deb
baseline: |
......@@ -74,46 +81,63 @@
tar -xOf $1 metadata.gz | zcat > test-1.23.gem-metadata.txt
cleanup: rm -f test-1.23.gem-metadata.txt
posttest: |
if [ "x`cat test-1.23.gem-metadata.txt`" != "xhi" ]; then exit 1; fi
exec [ "$(cat test-1.23.gem-metadata.txt)" = "hi" ]
- name: recursion and permissions
filenames: test-recursive-badperms.tar.bz2
options: -n -r
baseline: |
mkdir test-recursive-badperms
cd test-recursive-badperms
tar -jxf ../$1
mkdir test-badperms
cd test-badperms
tar -xf ../test-badperms.tar
extract() {
mkdir "$1"
cd "$1"
tar "-${3}xf" "../$2"
}
extract test-recursive-badperms "$1" j
extract test-badperms test-badperms.tar
chmod 700 testdir
posttest: |
if [ "x`cat test-recursive-badperms/test-badperms/testdir/testfile`" != \
"xhey" ]; then exit 1; fi
exec [ "$(cat test-recursive-badperms/test-badperms/testdir/testfile)" = \
"hey" ]
- name: decompressing gz
- name: decompressing gz, not interactive
directory: inside-dir
filenames: ../test-text.gz
options: ""
antigrep: "."
baseline: |
zcat $1 >test-text
posttest: |
if [ "x`cat test-text`" != "xhi" ]; then exit 1; fi
exec [ "$(cat test-text)" = "hi" ]
- name: decompressing bz2
- name: decompressing bz2, not interactive
directory: inside-dir
filenames: ../test-text.bz2
options: ""
antigrep: "."
baseline: |
bzcat $1 >test-text
posttest: |
if [ "x`cat test-text`" != "xhi" ]; then exit 1; fi
exec [ "$(cat test-text)" = "hi" ]
- name: decompressing xz
- name: decompressing xz, not interactive
directory: inside-dir
filenames: ../test-text.xz
options: ""
antigrep: "."
baseline: |
xzcat $1 >test-text
posttest: |
if [ "x`cat test-text`" != "xhi" ]; then exit 1; fi
exec [ "$(cat test-text)" = "hi" ]
- name: decompressing lzip, not interactive
directory: inside-dir
filenames: ../test-text.lz
options: ""
antigrep: "."
baseline: |
lzip -cd <$1 >test-text
posttest: |
exec [ "$(cat test-text)" = "hi" ]
- name: decompression with -r
directory: inside-dir
......@@ -163,7 +187,7 @@
tar -xf test-badperms.tar
chmod 700 testdir
posttest: |
if [ "x`cat testdir/testfile`" != "xhey" ]; then exit 1; fi
exec [ "$(cat testdir/testfile)" = "hey" ]
- name: no files
error: true
......@@ -222,6 +246,17 @@
test-1.23/a/b
test-1.23/foobar
- name: list contents of LZH
options: -n -l
filenames: test-1.23.lzh
output: |
1/
1/2/
1/2/3
a/
a/b
foobar
- name: list contents of .cpio
options: -n -l
filenames: test-1.23.cpio
......@@ -434,17 +469,16 @@
i
n
baseline: |
mkdir test-recursive-badperms
cd test-recursive-badperms
tar -jxf ../$1
mkdir test-badperms
cd test-badperms
tar -xf ../test-badperms.tar
extract() {
mkdir "$1"
cd "$1"
tar "-${3}xf" "../$2"
}
extract test-recursive-badperms "$1" j
extract test-badperms test-badperms.tar
chmod 700 testdir
cd ../..
mkdir test-recursive-badperms.1
cd test-recursive-badperms.1
tar -jxf ../$1
extract test-recursive-badperms.1 "$1" j
- name: interactive recursion (never)
filenames: test-recursive-badperms.tar.bz2 test-recursive-badperms.tar.bz2
......@@ -685,9 +719,28 @@
- name: extracting empty archive
filenames: test-empty.tar.bz2
options: ""
baseline: ""
antigrep: '.'
- name: listing empty archive
filenames: test-empty.tar.bz2
options: -l
antigrep: '.'
- name: download and extract
filenames: http://brettcsmith.org/2007/dtrx/test-download.gz
directory: inside-dir
baseline: |
wget "$1"
zcat test-download.gz >test-download
cleanup: rm -f test-download.gz test-download
- name: recursive archive without prompt
filenames: test-recursive-no-prompt.tar.bz2
options: ""
baseline: |
mkdir test-recursive-no-prompt
cd test-recursive-no-prompt
tar -jxf ../$1
antigrep: '.'
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment