diff --git a/.github/workflows/python.yml b/.github/workflows/python.yml index 2895d02..cd16575 100644 --- a/.github/workflows/python.yml +++ b/.github/workflows/python.yml @@ -66,7 +66,7 @@ jobs: - uses: actions/setup-python@v5 with: python-version: '3.13' - - run: pip install build + - run: pip install build~=1.2 - run: python -m build - uses: pypa/gh-action-pypi-publish@release/v1 with: diff --git a/Dockerfile b/Dockerfile index cf69741..d72808a 100644 --- a/Dockerfile +++ b/Dockerfile @@ -45,8 +45,7 @@ WORKDIR /home/user/version-query COPY --chown=${USER_ID}:${GROUP_ID} requirements*.txt ./ RUN set -Eeuxo pipefail && \ - pip3 install --no-cache-dir -r requirements_ci.txt && \ - pip3 uninstall -y version-query + pip3 install --no-cache-dir -r requirements_ci.txt # prepare version-query for testing diff --git a/Jenkinsfile b/Jenkinsfile index affeba9..7d715ed 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -94,8 +94,7 @@ pipeline { set -Eeuxo pipefail python3 -m twine upload \ dist/${PYTHON_PACKAGE}-${VERSION}-py3-none-any.whl \ - dist/${PYTHON_PACKAGE}-${VERSION}.tar.gz \ - dist/${PYTHON_PACKAGE}-${VERSION}.zip + dist/${PYTHON_PACKAGE}-${VERSION}.tar.gz """ } } @@ -111,8 +110,7 @@ pipeline { script { githubUtils.createRelease([ "dist/${PYTHON_PACKAGE}-${VERSION}-py3-none-any.whl", - "dist/${PYTHON_PACKAGE}-${VERSION}.tar.gz", - "dist/${PYTHON_PACKAGE}-${VERSION}.zip" + "dist/${PYTHON_PACKAGE}-${VERSION}.tar.gz" ]) } } diff --git a/pyproject.toml b/pyproject.toml index cc2b226..8033d54 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [build-system] requires = [ - 'boilerplates[setup] ~= 1.0', + 'boilerplates[setup] ~= 1.2', 'GitPython ~= 3.1', 'packaging >= 24.0', 'semver >= 2.13, < 3.1' diff --git a/requirements.txt b/requirements.txt index fc09370..3854aff 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,4 @@ -boilerplates[cli,logging] ~= 1.0 +boilerplates[cli,logging] ~= 1.2 GitPython ~= 3.1 packaging >= 24.0 semver >= 2.13, < 3.1 diff --git a/requirements_test.txt b/requirements_test.txt index 105cb6d..ef036ce 100644 --- a/requirements_test.txt +++ b/requirements_test.txt @@ -1,3 +1,2 @@ -r requirements.txt -boilerplates[git-repo-tests,packaging-tests] ~= 1.0 -setuptools >= 67.4 +boilerplates[git-repo-tests,packaging-tests] ~= 1.2 diff --git a/setup.py b/setup.py index dc24b5b..ffe4c0e 100644 --- a/setup.py +++ b/setup.py @@ -15,7 +15,6 @@ class Package(boilerplates.setup.Package): 'Development Status :: 5 - Production/Stable', 'Environment :: Console', 'Intended Audience :: Developers', - 'License :: OSI Approved :: Apache Software License', 'Natural Language :: English', 'Operating System :: MacOS', 'Operating System :: Microsoft :: Windows', diff --git a/test/examples.py b/test/examples.py index 8aef6ef..18f60ce 100644 --- a/test/examples.py +++ b/test/examples.py @@ -9,8 +9,6 @@ from version_query.version import VersionComponent -_HERE = pathlib.Path(__file__).resolve().parent - _GIT_REPOS_ROOT = pathlib.Path(os.environ.get('EXAMPLE_PROJECTS_PATH', '..')).resolve() GIT_REPO_EXAMPLES = list(_ for _ in _GIT_REPOS_ROOT.glob('**/.git') if _.is_dir()) diff --git a/test/test_cli.py b/test/test_cli.py new file mode 100644 index 0000000..a9e8527 --- /dev/null +++ b/test/test_cli.py @@ -0,0 +1,81 @@ +"""Tests of the CLI.""" + +import contextlib +import io +import logging +import runpy +import sys +import unittest + +from version_query.version import VersionComponent +from version_query.query import \ + query_caller, query_version_str, predict_caller, predict_version_str + +_LOG = logging.getLogger(__name__) + + +@contextlib.contextmanager +def temporarily_set_logger_level(logger_name: str, level: int): + """Change logger level on enter and restore on exit of this context.""" + logger = logging.getLogger(logger_name) + level_ = logger.level + logger.setLevel(level) + try: + yield + finally: + logger.setLevel(level_) + + +def preserve_logger_level(logger_name: str): + return temporarily_set_logger_level(logger_name, logging.getLogger(logger_name).level) + + +def run_module(name: str, *args, run_name: str = '__main__') -> None: + backup_sys_argv = sys.argv + sys.argv = [name + '.py'] + list(args) + runpy.run_module(name, run_name=run_name, alter_sys=True) + sys.argv = backup_sys_argv + + +class Tests(unittest.TestCase): + + def test_not_as_main(self): # pylint: disable = no-self-use + run_module('version_query', run_name='__not_main__') + + def test_help(self): + sio = io.StringIO() + with contextlib.redirect_stderr(sio), preserve_logger_level('version_query'), \ + self.assertRaises(SystemExit): + run_module('version_query') + _LOG.info('%s', sio.getvalue()) + + def test_bad_usage(self): + sio = io.StringIO() + with contextlib.redirect_stderr(sio), preserve_logger_level('version_query'), \ + self.assertRaises(ValueError): + run_module('version_query', '-p', '-i', '.') + _LOG.info('%s', sio.getvalue()) + + def test_here(self): + sio = io.StringIO() + with temporarily_set_logger_level('version_query', logging.ERROR), \ + contextlib.redirect_stdout(sio): + run_module('version_query', '.') + self.assertEqual(sio.getvalue().rstrip(), query_caller().to_str()) + self.assertEqual(sio.getvalue().rstrip(), query_version_str()) + + def test_increment_here(self): + sio = io.StringIO() + with temporarily_set_logger_level('version_query', logging.ERROR), \ + contextlib.redirect_stdout(sio): + run_module('version_query', '-i', '.') + self.assertEqual(sio.getvalue().rstrip(), + query_caller().increment(VersionComponent.Patch).to_str()) + + def test_predict_here(self): + sio = io.StringIO() + with temporarily_set_logger_level('version_query', logging.ERROR), \ + contextlib.redirect_stdout(sio): + run_module('version_query', '-p', '.') + self.assertEqual(sio.getvalue().rstrip(), predict_caller().to_str()) + self.assertEqual(sio.getvalue().rstrip(), predict_version_str()) diff --git a/test/test_query.py b/test/test_query.py index 9572bac..897ed58 100644 --- a/test/test_query.py +++ b/test/test_query.py @@ -1,47 +1,26 @@ """Tests of querying tools.""" -import contextlib import importlib -import io import logging import os import pathlib import sys import tempfile import unittest -import unittest.mock from boilerplates.packaging_tests import run_module -from version_query.version import VersionComponent, Version +from version_query.version import Version from version_query.git_query import query_git_repo, predict_git_repo from version_query.py_query import query_metadata_json, query_pkg_info, query_package_folder -from version_query.query import \ - query_folder, query_caller, query_version_str, predict_caller, predict_version_str +from version_query.query import query_folder, query_caller from .examples import \ PY_LIB_DIR, GIT_REPO_EXAMPLES, METADATA_JSON_EXAMPLE_PATHS, PKG_INFO_EXAMPLE_PATHS, \ PACKAGE_FOLDER_EXAMPLES +from .test_cli import preserve_logger_level _LOG = logging.getLogger(__name__) -IGNORED_FOLDER_NAMES = ['opencv'] - - -@contextlib.contextmanager -def temporarily_set_logger_level(logger_name: str, level: int): - """Change logger level on enter and restore on exit of this context.""" - logger = logging.getLogger(logger_name) - level_ = logger.level - logger.setLevel(level) - try: - yield - finally: - logger.setLevel(level_) - - -def preserve_logger_level(logger_name: str): - return temporarily_set_logger_level(logger_name, logging.getLogger(logger_name).level) - class Tests(unittest.TestCase): @@ -63,8 +42,6 @@ def test_example_count_checking(self): def _query_test_case(self, paths, query_function): for path in paths: - if any(_ in path.parts for _ in IGNORED_FOLDER_NAMES) or not path.exists(): - continue with self.subTest(path=path, query_function=query_function): _LOG.debug('testing %s() on %s', query_function.__name__, path) try: @@ -164,46 +141,3 @@ def test_query_caller(self): version = query_caller() _LOG.debug('caller: %s', version) self.assertIsInstance(version, Version) - - def test_not_as_main(self): # pylint: disable = no-self-use - run_module('version_query', run_name=None) - - def test_help(self): - sio = io.StringIO() - with contextlib.redirect_stderr(sio): - with preserve_logger_level('version_query'): - with self.assertRaises(SystemExit): - run_module('version_query') - _LOG.info('%s', sio.getvalue()) - - def test_bad_usage(self): - sio = io.StringIO() - with contextlib.redirect_stderr(sio): - with preserve_logger_level('version_query'): - with self.assertRaises(ValueError): - run_module('version_query', '-p', '-i', '.') - _LOG.info('%s', sio.getvalue()) - - def test_here(self): - with temporarily_set_logger_level('version_query', logging.INFO): - sio = io.StringIO() - with contextlib.redirect_stdout(sio): - run_module('version_query', '.') - self.assertEqual(sio.getvalue().rstrip(), query_caller().to_str()) - self.assertEqual(sio.getvalue().rstrip(), query_version_str()) - - def test_increment_here(self): - sio = io.StringIO() - with contextlib.redirect_stdout(sio): - with preserve_logger_level('version_query'): - run_module('version_query', '-i', '.') - self.assertEqual(sio.getvalue().rstrip(), - query_caller().increment(VersionComponent.Patch).to_str()) - - def test_predict_here(self): - with temporarily_set_logger_level('version_query', logging.INFO): - sio = io.StringIO() - with contextlib.redirect_stdout(sio): - run_module('version_query', '-p', '.') - self.assertEqual(sio.getvalue().rstrip(), predict_caller().to_str()) - self.assertEqual(sio.getvalue().rstrip(), predict_version_str())