diff --git a/.github/requirements.txt b/.github/requirements.txt index d240ac8..87127dd 100644 --- a/.github/requirements.txt +++ b/.github/requirements.txt @@ -1,7 +1,8 @@ -PyYAML >=5.4 +PyYAML >=5.1 distutils-pytest -lark-parser +git-props +lark pytest >=3.6.0 pytest-dependency >=0.2 python-dateutil -setuptools_scm +setuptools diff --git a/.gitignore b/.gitignore index 02d5097..eb7160f 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,5 @@ __pycache__/ /.env /MANIFEST /_meta.py -/archive/__init__.py /build/ /dist/ diff --git a/CHANGES.rst b/CHANGES.rst index 60ef3bc..6ee0380 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -25,12 +25,13 @@ Bug fixes and minor changes Internal changes ---------------- -+ `#74`_: Review build tool chain. ++ `#74`_, `#80`_: Review build tool chain. .. _#74: https://github.com/RKrahl/archive-tools/pull/74 .. _#75: https://github.com/RKrahl/archive-tools/pull/75 .. _#76: https://github.com/RKrahl/archive-tools/issues/76 .. _#77: https://github.com/RKrahl/archive-tools/pull/77 +.. _#80: https://github.com/RKrahl/archive-tools/pull/80 0.6 (2021-12-12) diff --git a/Makefile b/Makefile index e56bf56..18caece 100644 --- a/Makefile +++ b/Makefile @@ -22,7 +22,6 @@ clean: distclean: clean rm -f MANIFEST _meta.py - rm -f archive/__init__.py rm -rf dist rm -rf tests/.pytest_cache $(MAKE) -C doc distclean diff --git a/README.rst b/README.rst index d5f9051..2256cfd 100644 --- a/README.rst +++ b/README.rst @@ -60,7 +60,7 @@ Required library packages: + `packaging`_ -+ `lark-parser`_ ++ `lark`_ Required for the `backup-tool.py` script. @@ -80,13 +80,13 @@ Optional library packages: - the `--mtime` argument to `archive-tool.py find` recognizes a reduced set of date formats. -+ `setuptools_scm`_ ++ `git-props`_ - The version number is managed using this package. All source - distributions add a static text file with the version number and - fall back using that if `setuptools_scm` is not available. So this - package is only needed to build out of the plain development source - tree as cloned from GitHub. + This package is used to extract some metadata such as the version + number out of git, the version control system. All releases embed + that metadata in the distribution. So this package is only needed + to build out of the plain development source tree as cloned from + GitHub, but not to build a release distribution. + `pytest`_ >= 3.0 @@ -120,10 +120,10 @@ permissions and limitations under the License. .. _PyPI site: https://pypi.org/project/archive-tools/ .. _PyYAML: https://pypi.org/project/PyYAML/ .. _packaging: https://github.com/pypa/packaging/ -.. _lark-parser: https://github.com/lark-parser/lark +.. _lark: https://github.com/lark-parser/lark .. _imapclient: https://github.com/mjs/imapclient/ .. _python-dateutil: https://dateutil.readthedocs.io/en/stable/ -.. _setuptools_scm: https://github.com/pypa/setuptools_scm/ +.. _git-props: https://github.com/RKrahl/git-props .. _pytest: https://pytest.org/ .. _distutils-pytest: https://github.com/RKrahl/distutils-pytest .. _pytest-dependency: https://pypi.python.org/pypi/pytest_dependency/ diff --git a/python-archive-tools.spec b/python-archive-tools.spec index dd56c41..331ce6b 100644 --- a/python-archive-tools.spec +++ b/python-archive-tools.spec @@ -1,32 +1,41 @@ %bcond_without tests %global distname archive-tools -Name: python3-%{distname} +%if 0%{?sle_version} >= 150500 +%global pythons python3 python311 +%else +%{?!python_module:%define python_module() python3-%{**}} +%define skip_python2 1 +%endif + +Name: python-%{distname} Version: $version Release: 0 -Url: $url Summary: $description License: Apache-2.0 +URL: $url Group: Development/Libraries/Python -Source: %{distname}-%{version}.tar.gz +Source: https://github.com/RKrahl/archive-tools/releases/download/%{version}/%{distname}-%{version}.tar.gz +BuildRequires: %{python_module base >= 3.6} +BuildRequires: %{python_module setuptools} BuildRequires: fdupes -BuildRequires: python3-base >= 3.6 -BuildRequires: python3-setuptools +BuildRequires: python-rpm-macros %if %{with tests} -BuildRequires: python3-PyYAML -BuildRequires: python3-lark-parser -BuildRequires: python3-distutils-pytest -BuildRequires: python3-packaging -BuildRequires: python3-pytest-dependency >= 0.2 -BuildRequires: python3-pytest >= 3.0 +BuildRequires: %{python_module PyYAML} +BuildRequires: %{python_module lark-parser} +BuildRequires: %{python_module distutils-pytest} +BuildRequires: %{python_module packaging} +BuildRequires: %{python_module pytest >= 3.0} +BuildRequires: %{python_module pytest-dependency >= 0.2} +BuildRequires: %{python_module python-dateutil} %endif -Requires: python3-PyYAML -Requires: python3-lark-parser -Requires: python3-packaging -Recommends: python3-IMAPClient -Recommends: python3-python-dateutil +Requires: python-PyYAML +Requires: python-lark-parser +Requires: python-packaging +Recommends: python-IMAPClient +Recommends: python-python-dateutil BuildArch: noarch -BuildRoot: %{_tmppath}/%{name}-%{version}-build +%python_subpackages %description $long_description @@ -37,30 +46,29 @@ $long_description %build -python3 setup.py build +%python_build %install -python3 setup.py install --optimize=1 --prefix=%{_prefix} --root=%{buildroot} +%python_install for f in `ls %{buildroot}%{_bindir}` do mv %{buildroot}%{_bindir}/$$f %{buildroot}%{_bindir}/$${f%%.py} done -%fdupes %{buildroot} +%fdupes %{buildroot}%{python_sitelib} %if %{with tests} %check -python3 setup.py test +%python_expand $$python setup.py test %endif -%files -%defattr(-,root,root) -%doc README.rst CHANGES.rst +%files %{python_files} %license LICENSE.txt +%doc README.rst CHANGES.rst %config(noreplace) %{_sysconfdir}/backup.cfg -%{python3_sitelib}/* +%{python_sitelib}/* %{_bindir}/* diff --git a/setup.py b/setup.py index 34347de..615ce48 100644 --- a/setup.py +++ b/setup.py @@ -1,29 +1,9 @@ -#! /usr/bin/python """Tools for managing archives This package provides tools for managing archives. An archive in terms of this package is a (compressed) tar archive file with some embedded metadata on the included files. This metadata include the name, file stats, and checksums of the file. - -The package provides a command line tool to enable the following -tasks: - -+ Create an archive, takes a list of files to include in the archive - as input. - -+ Check the integrity and consistency of an archive. - -+ List the contents of the archive. - -+ Display details on a file in an archive. - -+ Given a list of files as input, list those files that are either not - in the archive or where the file in the archive differs. - -All tasks providing information on an archive take this information -from the embedded metadata. Retrieving this metadata does not require -reading through the compressed tar archive. """ import setuptools @@ -40,15 +20,15 @@ except (ImportError, AttributeError): cmdclass = dict() try: - import setuptools_scm - version = setuptools_scm.get_version() + import gitprops + release = str(gitprops.get_last_release()) + version = str(gitprops.get_version()) except (ImportError, LookupError): try: - import _meta - version = _meta.__version__ + from _meta import release, version except ImportError: log.warn("warning: cannot determine version number") - version = "UNKNOWN" + release = version = "UNKNOWN" docstring = __doc__ @@ -57,43 +37,24 @@ class meta(setuptools.Command): description = "generate meta files" user_options = [] - init_template = '''"""%(doc)s""" - -__version__ = "%(version)s" - -from archive.archive import Archive -from archive.exception import * -''' meta_template = ''' -__version__ = "%(version)s" +release = "%(release)s" +version = "%(version)s" ''' def initialize_options(self): - self.package_dir = None + pass def finalize_options(self): - self.package_dir = {} - if self.distribution.package_dir: - for name, path in self.distribution.package_dir.items(): - self.package_dir[name] = convert_path(path) + pass def run(self): version = self.distribution.get_version() log.info("version: %s", version) values = { + 'release': release, 'version': version, - 'doc': docstring, } - try: - pkgname = self.distribution.packages[0] - except IndexError: - log.warn("warning: no package defined") - else: - pkgdir = Path(self.package_dir.get(pkgname, pkgname)) - if not pkgdir.is_dir(): - pkgdir.mkdir() - with (pkgdir / "__init__.py").open("wt") as f: - print(self.init_template % values, file=f) with Path("_meta.py").open("wt") as f: print(self.meta_template % values, file=f) @@ -121,6 +82,9 @@ class build_py(setuptools.command.build_py.build_py): def run(self): self.run_command('meta') super().run() + package = self.distribution.packages[0].split('.') + outfile = self.get_module_outfile(self.build_lib, package, "_meta") + self.copy_file("_meta.py", outfile, preserve_mode=0) with Path("README.rst").open("rt", encoding="utf8") as f: @@ -153,11 +117,13 @@ def run(self): ], project_urls = dict( Source="https://github.com/RKrahl/archive-tools", - Download="https://github.com/RKrahl/archive-tools/releases/latest", + Download=("https://github.com/RKrahl/archive-tools/releases/%s/" + % release), ), packages = ["archive", "archive.cli", "archive.bt"], + package_dir = {"": "src"}, python_requires = ">=3.6", - install_requires = ["PyYAML", "packaging", "lark"], + install_requires = ["setuptools", "PyYAML", "packaging", "lark"], scripts = ["scripts/archive-tool.py", "scripts/backup-tool.py", "scripts/imap-to-archive.py"], data_files = [("/etc", ["etc/backup.cfg"])], diff --git a/src/archive/__init__.py b/src/archive/__init__.py new file mode 100644 index 0000000..0022c66 --- /dev/null +++ b/src/archive/__init__.py @@ -0,0 +1,11 @@ +"""Tools for managing archives + +This package provides tools for managing archives. An archive in +terms of this package is a (compressed) tar archive file with some +embedded metadata on the included files. This metadata include the +name, file stats, and checksums of the file. +""" + +from ._meta import version as __version__ +from .archive import Archive +from .exception import * diff --git a/archive/archive.py b/src/archive/archive.py similarity index 99% rename from archive/archive.py rename to src/archive/archive.py index 76366c3..66d4d3c 100644 --- a/archive/archive.py +++ b/src/archive/archive.py @@ -10,9 +10,9 @@ import sys import tarfile import tempfile -from archive.manifest import Manifest -from archive.exception import * -from archive.tools import checksum +from .manifest import Manifest +from .exception import * +from .tools import checksum def _is_normalized(p): """Check if the path is normalized. diff --git a/archive/bt/__init__.py b/src/archive/bt/__init__.py similarity index 100% rename from archive/bt/__init__.py rename to src/archive/bt/__init__.py diff --git a/archive/bt/config.py b/src/archive/bt/config.py similarity index 100% rename from archive/bt/config.py rename to src/archive/bt/config.py diff --git a/archive/bt/create.py b/src/archive/bt/create.py similarity index 100% rename from archive/bt/create.py rename to src/archive/bt/create.py diff --git a/archive/bt/index.py b/src/archive/bt/index.py similarity index 100% rename from archive/bt/index.py rename to src/archive/bt/index.py diff --git a/archive/bt/schedule.py b/src/archive/bt/schedule.py similarity index 100% rename from archive/bt/schedule.py rename to src/archive/bt/schedule.py diff --git a/archive/cli/__init__.py b/src/archive/cli/__init__.py similarity index 100% rename from archive/cli/__init__.py rename to src/archive/cli/__init__.py diff --git a/archive/cli/check.py b/src/archive/cli/check.py similarity index 100% rename from archive/cli/check.py rename to src/archive/cli/check.py diff --git a/archive/cli/create.py b/src/archive/cli/create.py similarity index 100% rename from archive/cli/create.py rename to src/archive/cli/create.py diff --git a/archive/cli/diff.py b/src/archive/cli/diff.py similarity index 100% rename from archive/cli/diff.py rename to src/archive/cli/diff.py diff --git a/archive/cli/find.py b/src/archive/cli/find.py similarity index 100% rename from archive/cli/find.py rename to src/archive/cli/find.py diff --git a/archive/cli/info.py b/src/archive/cli/info.py similarity index 100% rename from archive/cli/info.py rename to src/archive/cli/info.py diff --git a/archive/cli/ls.py b/src/archive/cli/ls.py similarity index 100% rename from archive/cli/ls.py rename to src/archive/cli/ls.py diff --git a/archive/cli/verify.py b/src/archive/cli/verify.py similarity index 100% rename from archive/cli/verify.py rename to src/archive/cli/verify.py diff --git a/archive/config.py b/src/archive/config.py similarity index 97% rename from archive/config.py rename to src/archive/config.py index 41e1355..45d4f01 100644 --- a/archive/config.py +++ b/src/archive/config.py @@ -9,7 +9,7 @@ from collections import ChainMap import configparser -from archive.exception import ConfigError +from .exception import ConfigError class Config(ChainMap): diff --git a/archive/exception.py b/src/archive/exception.py similarity index 100% rename from archive/exception.py rename to src/archive/exception.py diff --git a/archive/index.py b/src/archive/index.py similarity index 98% rename from archive/index.py rename to src/archive/index.py index 615dec6..26aa916 100644 --- a/archive/index.py +++ b/src/archive/index.py @@ -4,8 +4,8 @@ from collections.abc import Mapping, Sequence from pathlib import Path import yaml -from archive.archive import Archive -from archive.tools import Version, parse_date +from .archive import Archive +from .tools import Version, parse_date class IndexItem: diff --git a/archive/mailarchive.py b/src/archive/mailarchive.py similarity index 96% rename from archive/mailarchive.py rename to src/archive/mailarchive.py index 1dcc3bf..81c22e1 100644 --- a/archive/mailarchive.py +++ b/src/archive/mailarchive.py @@ -3,8 +3,8 @@ from pathlib import Path from tempfile import TemporaryDirectory, TemporaryFile import yaml -from archive import Archive -from archive.tools import Version, now_str, parse_date, tmp_chdir, tmp_umask +from .archive import Archive +from .tools import Version, now_str, parse_date, tmp_chdir, tmp_umask class MailIndex(list): diff --git a/archive/manifest.py b/src/archive/manifest.py similarity index 98% rename from archive/manifest.py rename to src/archive/manifest.py index 697c531..5d4310b 100644 --- a/archive/manifest.py +++ b/src/archive/manifest.py @@ -13,9 +13,8 @@ import warnings import yaml import archive -from archive.exception import ArchiveInvalidTypeError, ArchiveWarning -from archive.tools import (Version, now_str, parse_date, - checksum, mode_ft, ft_mode) +from .exception import ArchiveInvalidTypeError, ArchiveWarning +from .tools import Version, now_str, parse_date, checksum, mode_ft, ft_mode class DiffStatus(Enum): diff --git a/archive/tools.py b/src/archive/tools.py similarity index 100% rename from archive/tools.py rename to src/archive/tools.py