diff --git a/.travis.yml b/.travis.yml
index 61c4cc3..2a281f0 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -5,6 +5,7 @@ python:
- "3.6"
- "3.7"
- "3.8"
+ - "3.9"
install: pip install -r .travis_require
script: make test
diff --git a/CHANGES.rst b/CHANGES.rst
index 125463b..769e88a 100644
--- a/CHANGES.rst
+++ b/CHANGES.rst
@@ -1,80 +1,172 @@
Changelog
=========
+
+0.5.1 (2020-12-12)
+~~~~~~~~~~~~~~~~~~
+
+Bug fixes and minor changes
+---------------------------
+
++ `#46`_, `#47`_: `archive-tool` fails with :exc:`NameError` when
+ trying to emit a warning.
+
+.. _#46: https://github.com/RKrahl/archive-tools/issues/46
+.. _#47: https://github.com/RKrahl/archive-tools/pull/47
+
+
0.5 (2020-05-09)
- New features
- + #45: The files argument to `archive-tool check` defaults to
- the archive's basedir.
+~~~~~~~~~~~~~~~~
+
+New features
+------------
+
++ `#45`_: The files argument to `archive-tool check` defaults to the
+ archive's basedir.
+
+Bug fixes and minor changes
+---------------------------
+
++ Fix: some test data have not been included in the source
+ distribution.
+
+.. _#45: https://github.com/RKrahl/archive-tools/issues/45
- Bug fixes and minor changes
- + Fix: some test data have not been included in the source
- distribution.
0.4 (2019-12-26)
- New features
- + #15, #43: Add `archive-tool find` subcommand.
- + #38, #39: Add `archive-tool diff` subcommand.
- + #40, #44: Add setting tags in the header of the manifest.
- + #41: Add a :meth:`Archive.extract` method.
- + Add a :meth:`Manifest.sort` method.
+~~~~~~~~~~~~~~~~
+
+New features
+------------
+
++ `#15`_, `#43`_: Add `archive-tool find` subcommand.
+
++ `#38`_, `#39`_: Add `archive-tool diff` subcommand.
+
++ `#40`_, `#44`_: Add setting tags in the header of the manifest.
+
++ `#41`_: Add a :meth:`Archive.extract` method.
+
++ Add a :meth:`Manifest.sort` method.
+
+Internal changes
+----------------
+
++ Reorganization of the `archive-tool` script, move the code into
+ submodules in the new `archive.cli` package.
+
+.. _#15: https://github.com/RKrahl/archive-tools/issues/15
+.. _#38: https://github.com/RKrahl/archive-tools/issues/38
+.. _#39: https://github.com/RKrahl/archive-tools/pull/39
+.. _#40: https://github.com/RKrahl/archive-tools/issues/40
+.. _#41: https://github.com/RKrahl/archive-tools/pull/41
+.. _#43: https://github.com/RKrahl/archive-tools/pull/43
+.. _#44: https://github.com/RKrahl/archive-tools/pull/44
- Internal changes
- + Reorganization of the `archive-tool` script, move the code into
- submodules in the new `archive.cli` package.
0.3 (2019-08-06)
- New features
- + #33: `archive-tool create` should have an option to exclude files.
- + #35: :class:`FileInfo` calculates checksums lazily.
- + #34: files of unsupported type are ignored when creating an
- archive. A warning is emitted instead of raising an error.
-
- Incompatible changes
- + #36: Drop support for strings in the file name arguments
- `path`, `paths`, `basedir`, and `workdir` of the methods
- :meth:`Archive.create` and :meth:`Archive.open`. These
- arguments require :class:`Path` objects now.
-
- Bug fixes and minor changes
- + #37: `archive-tool create` throws an error when trying to
- explicitly add a symlink.
+~~~~~~~~~~~~~~~~
+
+New features
+------------
+
++ `#33`_: `archive-tool create` should have an option to exclude files.
+
++ `#35`_: :class:`FileInfo` calculates checksums lazily.
+
++ `#34`_: files of unsupported type are ignored when creating an
+ archive. A warning is emitted instead of raising an error.
+
+Incompatible changes
+--------------------
+
++ `#36`_: Drop support for strings in the file name arguments `path`,
+ `paths`, `basedir`, and `workdir` of the methods
+ :meth:`Archive.create` and :meth:`Archive.open`. These arguments
+ require :class:`Path` objects now.
+
+Bug fixes and minor changes
+---------------------------
+
++ `#37`_: `archive-tool create` throws an error when trying to
+ explicitly add a symlink.
+
+.. _#33: https://github.com/RKrahl/archive-tools/issues/33
+.. _#34: https://github.com/RKrahl/archive-tools/issues/34
+.. _#35: https://github.com/RKrahl/archive-tools/issues/35
+.. _#36: https://github.com/RKrahl/archive-tools/pull/36
+.. _#37: https://github.com/RKrahl/archive-tools/issues/37
+
0.2 (2019-07-14)
- New features
- + #28: support deduplication.
- + #26 and #30: add support for custom metadata:
- - Add methods :meth:`Archive.add_metadata` and
- :meth:`Archive.get_metadata` to add and to retrieve custom
- metadata to and from archives.
- - Add a list of metadata items in the header of the
- manifest.
- - Bump manifest version to 1.1.
- + #4, #32: Add :class:`MailArchive` implementing a special
- flavour of an :class:`Archive` for storing mails.
- + #27: Add command line flags `--prefix
` and `--stdin` to
- `archive-tool check`.
-
- Incompatible changes
- + #23 and #26: review the API of :class:`Archive`:
- - Add two methods :meth:`Archive.create` and
- :meth:`Archive.open` that create and read archives
- respectively.
- - The :meth:`Archive.__init__` method does not create or
- open archives any longer.
- - :meth:`Archive.verify` does not accept the mode argument
- any more.
- - :class:`Archive` keeps a file object to read the tarfile.
- It is opened in :meth:`Archive.open`.
- :meth:`Archive.verify` does not reopen the tarfile, but
- relies on the internal file object to be left open.
- - Add a :meth:`Archive.close` method.
- - :class:`Archive` implements the context manager protocol.
-
- Bug fixes and minor changes
- + #20: :meth:`Archive.create` takes a working directory as
- optional argument.
- + #29: Verfiy fails if archive contains hard links.
- + #25: `archive-tool check` should ignore metadata.
+~~~~~~~~~~~~~~~~
+
+New features
+------------
+
++ `#28`_: support deduplication.
+
++ `#26`_ and `#30`_: add support for custom metadata:
+
+ - Add methods :meth:`Archive.add_metadata` and
+ :meth:`Archive.get_metadata` to add and to retrieve custom
+ metadata to and from archives.
+
+ - Add a list of metadata items in the header of the manifest.
+
+ - Bump manifest version to 1.1.
+
++ `#4`_, `#32`_: Add :class:`MailArchive` implementing a special
+ flavour of an :class:`Archive` for storing mails.
+
++ `#27`_: Add command line flags `--prefix ` and `--stdin` to
+ `archive-tool check`.
+
+Incompatible changes
+--------------------
+
++ `#23`_ and `#26`_: review the API of :class:`Archive`:
+
+ - Add two methods :meth:`Archive.create` and :meth:`Archive.open`
+ that create and read archives respectively.
+
+ - The :meth:`Archive.__init__` method does not create or open
+ archives any longer.
+
+ - :meth:`Archive.verify` does not accept the mode argument any more.
+
+ - :class:`Archive` keeps a file object to read the tarfile. It is
+ opened in :meth:`Archive.open`. :meth:`Archive.verify` does not
+ reopen the tarfile, but relies on the internal file object to be
+ left open.
+
+ - Add a :meth:`Archive.close` method.
+
+ - :class:`Archive` implements the context manager protocol.
+
+Bug fixes and minor changes
+---------------------------
+
++ `#20`_: :meth:`Archive.create` takes a working directory as optional
+ argument.
+
++ `#29`_: Verify fails if archive contains hard links.
+
++ `#25`_: `archive-tool check` should ignore metadata.
+
+.. _#4: https://github.com/RKrahl/archive-tools/issues/4
+.. _#20: https://github.com/RKrahl/archive-tools/issues/20
+.. _#23: https://github.com/RKrahl/archive-tools/issues/23
+.. _#25: https://github.com/RKrahl/archive-tools/issues/25
+.. _#26: https://github.com/RKrahl/archive-tools/pull/26
+.. _#27: https://github.com/RKrahl/archive-tools/issues/27
+.. _#28: https://github.com/RKrahl/archive-tools/issues/28
+.. _#29: https://github.com/RKrahl/archive-tools/issues/29
+.. _#30: https://github.com/RKrahl/archive-tools/pull/30
+.. _#32: https://github.com/RKrahl/archive-tools/pull/32
+
0.1 (2019-04-14)
- + Initial release.
+~~~~~~~~~~~~~~~~
+
++ Initial release.
diff --git a/archive/cli/__init__.py b/archive/cli/__init__.py
index 56be379..e0f5124 100644
--- a/archive/cli/__init__.py
+++ b/archive/cli/__init__.py
@@ -9,6 +9,8 @@
subcmds = [ "create", "verify", "ls", "info", "check", "diff", "find", ]
+argparser = argparse.ArgumentParser()
+
def showwarning(message, category, filename, lineno, file=None, line=None):
"""Display ArchiveWarning in a somewhat more user friendly manner.
All other warnings are formatted the standard way.
@@ -32,7 +34,6 @@ def showwarning(message, category, filename, lineno, file=None, line=None):
def archive_tool():
warnings.showwarning = showwarning
- argparser = argparse.ArgumentParser()
subparsers = argparser.add_subparsers(title='subcommands', dest='subcmd')
for sc in subcmds:
m = importlib.import_module('archive.cli.%s' % sc)
diff --git a/python-archive-tools.spec b/python-archive-tools.spec
index 2522f63..7589767 100644
--- a/python-archive-tools.spec
+++ b/python-archive-tools.spec
@@ -1,4 +1,4 @@
-%bcond_with tests
+%bcond_without tests
%global distname archive-tools
Name: python3-%{distname}
@@ -9,6 +9,7 @@ Summary: $description
License: Apache-2.0
Group: Development/Libraries/Python
Source: %{distname}-%{version}.tar.gz
+BuildRequires: fdupes
BuildRequires: python3-base >= 3.4
%if %{with tests}
BuildRequires: python3-PyYAML
@@ -40,6 +41,7 @@ for f in `ls %{buildroot}%{_bindir}`
do
mv %{buildroot}%{_bindir}/$$f %{buildroot}%{_bindir}/$${f%%.py}
done
+%fdupes %{buildroot}
%if %{with tests}
diff --git a/setup.py b/setup.py
index 29f30f6..a587a96 100644
--- a/setup.py
+++ b/setup.py
@@ -131,6 +131,7 @@ def run(self):
"Programming Language :: Python :: 3.6",
"Programming Language :: Python :: 3.7",
"Programming Language :: Python :: 3.8",
+ "Programming Language :: Python :: 3.9",
"Topic :: System :: Archiving",
],
cmdclass = {'build_py': build_py, 'sdist': sdist, 'init_py': init_py},
diff --git a/tests/conftest.py b/tests/conftest.py
index 4971982..2420a2b 100644
--- a/tests/conftest.py
+++ b/tests/conftest.py
@@ -6,7 +6,6 @@
from pathlib import Path
from random import getrandbits
import shutil
-import stat
import subprocess
import sys
import tempfile
diff --git a/tests/test_02_create.py b/tests/test_02_create.py
index 80ee412..cbc788e 100644
--- a/tests/test_02_create.py
+++ b/tests/test_02_create.py
@@ -5,7 +5,6 @@
from pathlib import Path
import shutil
import subprocess
-import tarfile
import pytest
from pytest_dependency import depends
from archive import Archive
diff --git a/tests/test_03_create_dedup.py b/tests/test_03_create_dedup.py
index 6ec6fcc..cae60ad 100644
--- a/tests/test_03_create_dedup.py
+++ b/tests/test_03_create_dedup.py
@@ -9,7 +9,6 @@
import pytest
from pytest_dependency import depends
from archive.archive import Archive, DedupMode
-from archive.manifest import Manifest
from conftest import *
diff --git a/tests/test_04_cli_error.py b/tests/test_04_cli_error.py
index cd90eeb..9ed8c19 100644
--- a/tests/test_04_cli_error.py
+++ b/tests/test_04_cli_error.py
@@ -3,8 +3,8 @@
import os
from pathlib import Path
+import re
import stat
-import subprocess
import tarfile
from tempfile import TemporaryFile
from archive.manifest import Manifest
@@ -114,7 +114,10 @@ def test_cli_create_rel_start_basedir(test_dir, testname, monkeypatch):
callscript("archive-tool.py", args, returncode=1, stderr=f)
f.seek(0)
line = f.readline()
- assert "'base/msg.txt' does not start with 'base/data'" in line
+ # The actual error message differs between Python versions, so
+ # lets just assert that the error is something about
+ # 'base/msg.txt' and 'base/data'.
+ assert re.search(r"'base/msg.txt'.*'base/data'", line)
def test_cli_ls_archive_not_found(test_dir, monkeypatch):
monkeypatch.chdir(str(test_dir))
diff --git a/tests/test_04_cli_warn.py b/tests/test_04_cli_warn.py
new file mode 100644
index 0000000..3f48c1b
--- /dev/null
+++ b/tests/test_04_cli_warn.py
@@ -0,0 +1,61 @@
+"""Test warnings issued by the command line tool.
+"""
+
+from pathlib import Path
+import socket
+from tempfile import TemporaryFile
+import pytest
+from archive import Archive
+from conftest import *
+
+
+# Setup a directory with some test data to be put into an archive.
+# Make sure that we have all kind of different things in there.
+testdata = [
+ DataDir(Path("base"), 0o755),
+ DataDir(Path("base", "data"), 0o750),
+ DataDir(Path("base", "empty"), 0o755),
+ DataFile(Path("base", "msg.txt"), 0o644),
+ DataFile(Path("base", "data", "rnd.dat"), 0o600),
+ DataSymLink(Path("base", "s.dat"), Path("data", "rnd.dat")),
+]
+
+@pytest.fixture(scope="module")
+def test_dir(tmpdir):
+ setup_testdata(tmpdir, testdata)
+ return tmpdir
+
+class tmp_socket():
+ """A context manager temporarily creating a unix socket.
+ """
+ def __init__(self, path):
+ self.path = path
+ self.socket = socket.socket(socket.AF_UNIX)
+ self.socket.bind(str(self.path))
+ def __enter__(self):
+ return self.socket
+ def __exit__(self, type, value, tb):
+ self.socket.close()
+ self.path.unlink()
+
+def test_cli_warn_ignore_socket(test_dir, testname, monkeypatch):
+ """Create an archive from a directory containing a socket.
+
+ archive-tool.py should issue a warning that the socket has been
+ ignored, but otherwise proceed to create the archive.
+ """
+ monkeypatch.chdir(str(test_dir))
+ name = archive_name(tags=[testname])
+ basedir = Path("base")
+ fp = basedir / "socket"
+ with tmp_socket(fp):
+ with TemporaryFile(mode="w+t", dir=str(test_dir)) as f:
+ args = ["create", name, "base"]
+ callscript("archive-tool.py", args, stderr=f)
+ f.seek(0)
+ line = f.readline().strip()
+ assert line == ("archive-tool.py: %s: socket ignored" % fp)
+ with Archive().open(name) as archive:
+ assert archive.basedir == basedir
+ check_manifest(archive.manifest, testdata)
+ archive.verify()
diff --git a/tests/test_05_mailarchive_create.py b/tests/test_05_mailarchive_create.py
index c2acd2a..08950be 100644
--- a/tests/test_05_mailarchive_create.py
+++ b/tests/test_05_mailarchive_create.py
@@ -2,7 +2,6 @@
"""
import email
-from pathlib import Path
import pytest
from pytest_dependency import depends
import yaml