diff --git a/.github/workflows/checks.yml b/.github/workflows/checks.yml index e7bda0a6f..83249664e 100644 --- a/.github/workflows/checks.yml +++ b/.github/workflows/checks.yml @@ -20,7 +20,7 @@ jobs: uses: ./.github/actions/python-environment - name: Check Version(s) - run: poetry run -- nox -s version:check -- `poetry run -- python -c "from noxconfig import PROJECT_CONFIG; print(PROJECT_CONFIG.version_file)"` + run: poetry run -- nox -s version:check Documentation: name: Docs diff --git a/doc/changes/unreleased.md b/doc/changes/unreleased.md index b5716a1e2..235c0c794 100644 --- a/doc/changes/unreleased.md +++ b/doc/changes/unreleased.md @@ -1,4 +1,13 @@ # Unreleased +## Summary + +With #441, please ensure that the location of the `version.py` is given for `Config.version_file`, +which is specified in the `noxconfig.py` + ## 📚 Documentation -* Updated getting_started.rst for allowing tag-based releases \ No newline at end of file +* Updated getting_started.rst for allowing tag-based releases + +## ✨ Features + +* [#441](https://github.com/exasol/python-toolbox/issues/441): Switched nox task for `version:check` to use the config value of `version_file` to specify the location of the `version.py` \ No newline at end of file diff --git a/exasol/toolbox/nox/_format.py b/exasol/toolbox/nox/_format.py index 39304bdf9..31eeb29c5 100644 --- a/exasol/toolbox/nox/_format.py +++ b/exasol/toolbox/nox/_format.py @@ -36,7 +36,7 @@ def _pyupgrade(session: Session, files: Iterable[str]) -> None: def fix(session: Session) -> None: """Runs all automated fixes on the code base""" py_files = [f"{file}" for file in python_files(PROJECT_CONFIG.root)] - _version(session, Mode.Fix, PROJECT_CONFIG.version_file) + _version(session, Mode.Fix) _pyupgrade(session, py_files) _code_format(session, Mode.Fix, py_files) diff --git a/exasol/toolbox/nox/_package_version.py b/exasol/toolbox/nox/_package_version.py index 1435f249b..8a854901f 100644 --- a/exasol/toolbox/nox/_package_version.py +++ b/exasol/toolbox/nox/_package_version.py @@ -1,5 +1,4 @@ import argparse -import sys from argparse import ( ArgumentParser, Namespace, @@ -10,8 +9,11 @@ import nox from nox import Session -from exasol.toolbox.error import ToolboxError from exasol.toolbox.util.version import Version +from noxconfig import ( + PROJECT_CONFIG, + Config, +) _SUCCESS = 0 _FAILURE = 1 @@ -21,7 +23,7 @@ # ATTENTION: # This file is generated by exasol/toolbox/nox/_package_version.py when using: # * either "poetry run -- nox -s project:fix" - # * or "poetry run -- nox version:check -- --fix" + # * or "poetry run -- nox version:check -- --fix" # Do not edit this file manually! # If you need to change the version, do so in the pyproject.toml, e.g. by using `poetry version X.Y.Z`. MAJOR = {major} @@ -33,12 +35,8 @@ # fmt: on -def write_version_module(version: Version, path: str, exists_ok: bool = True) -> None: - version_file = Path(path) - if version_file.exists() and not exists_ok: - raise ToolboxError(f"Version file [{version_file}] already exists.") - version_file.unlink(missing_ok=True) - with open(version_file, "w", encoding="utf-8") as f: +def write_version_module(version: Version, version_file: Path) -> None: + with version_file.open(mode="w", encoding="utf-8") as f: f.write( _VERSION_MODULE_TEMPLATE.format( major=version.major, minor=version.minor, patch=version.patch @@ -51,8 +49,6 @@ def _create_parser() -> ArgumentParser: prog="nox -s version:check --", formatter_class=argparse.ArgumentDefaultsHelpFormatter, ) - parser.add_argument("version_module", help="Path to version module") - parser.add_argument("files", nargs="*") parser.add_argument( "-d", "--debug", @@ -65,46 +61,39 @@ def _create_parser() -> ArgumentParser: "--fix", action="store_true", default=False, - help="fix instead of check.", + help="updates the `version.py`, instead of performing a check.", ) return parser -def _main_debug(args: Namespace) -> int: - module_version = Version.from_python_module(args.version_module) - poetry_version = Version.from_poetry() +def _version_check(args: Namespace, config: Config) -> int: + version_file = config.version_file + module_version = Version.from_python_module(version_file) + poetry_version = Version.from_poetry() if args.fix: - write_version_module(poetry_version, args.version_module) + print( + f"Updating version in {version_file} from {module_version} to {poetry_version}" + ) + write_version_module(version=poetry_version, version_file=version_file) + module_version = Version.from_python_module(version_file) if module_version != poetry_version: print( - f"Version in pyproject.toml {poetry_version} and {args.version_module} {module_version} do not match!" + f"Version in pyproject.toml ({poetry_version}) and {version_file} ({module_version}) do not match!" ) - if args.fix: - print( - f"Updating version in file ({args.version_module}) from {module_version} to {poetry_version}" - ) - return _SUCCESS - return _FAILURE return _SUCCESS -def _main(args: Namespace) -> int: - try: - return _main_debug(args) - except Exception as ex: - print(f"Error while executing program, details: {ex}", file=sys.stderr) - return _FAILURE - - @nox.session(name="version:check", python=False) def version_check(session: Session) -> None: - """""" + """ + Compare the version in the `version.py` to that + declared in the `pyproject.toml`. + """ parser = _create_parser() args = parser.parse_args(session.posargs) - entry_point = _main if not args.debug else _main_debug - if entry_point(args): + if _version_check(args=args, config=PROJECT_CONFIG): session.error() diff --git a/exasol/toolbox/nox/_release.py b/exasol/toolbox/nox/_release.py index fcd7ebe1b..63f3c372d 100644 --- a/exasol/toolbox/nox/_release.py +++ b/exasol/toolbox/nox/_release.py @@ -44,19 +44,19 @@ def _create_parser() -> argparse.ArgumentParser: "--no-add", default=False, action="store_true", - help=("Neither add nor commit the changes"), + help="Neither add nor commit the changes", ) parser.add_argument( "--no-branch", default=False, action="store_true", - help=("Do not create a branch to commit the changes on"), + help="Do not create a branch to commit the changes on", ) parser.add_argument( "--no-pr", default=False, action="store_true", - help=("Do not create a pull request for the changes"), + help="Do not create a pull request for the changes", ) return parser @@ -67,7 +67,7 @@ def _is_valid_version(old: Version, new: Version) -> bool: def _update_project_version(session: Session, version: Version) -> Version: session.run("poetry", "version", f"{version}") - _version(session, Mode.Fix, PROJECT_CONFIG.version_file) + _version(session, Mode.Fix) return version @@ -129,7 +129,7 @@ def run(*args: str): @nox.session(name="release:prepare", python=False) -def prepare_release(session: Session, python=False) -> None: +def prepare_release(session: Session) -> None: """ Prepares the project for a new release. """ diff --git a/exasol/toolbox/nox/_shared.py b/exasol/toolbox/nox/_shared.py index 8f4284abd..b198904e6 100644 --- a/exasol/toolbox/nox/_shared.py +++ b/exasol/toolbox/nox/_shared.py @@ -36,10 +36,10 @@ def python_files(project_root: Path) -> Iterable[Path]: return [path for path in files if not set(path.parts).intersection(deny_list)] -def _version(session: Session, mode: Mode, version_file: Path) -> None: +def _version(session: Session, mode: Mode) -> None: command = ["nox", "-s", "version:check", "--"] command = command if mode == Mode.Check else command + ["--fix"] - session.run(*command, f"{version_file}") + session.run(*command) def _context_parser() -> argparse.ArgumentParser: diff --git a/exasol/toolbox/nox/tasks.py b/exasol/toolbox/nox/tasks.py index 7076a4443..65e690f3c 100644 --- a/exasol/toolbox/nox/tasks.py +++ b/exasol/toolbox/nox/tasks.py @@ -35,7 +35,7 @@ def check(session: Session) -> None: """Runs all available checks on the project""" context = _context(session, coverage=True) py_files = [f"{file}" for file in python_files(PROJECT_CONFIG.root)] - _version(session, Mode.Check, PROJECT_CONFIG.version_file) + _version(session, Mode.Check) _code_format(session, Mode.Check, py_files) _pylint(session, py_files) _type_check(session, py_files) diff --git a/exasol/toolbox/templates/github/workflows/checks.yml b/exasol/toolbox/templates/github/workflows/checks.yml index 1d08744ff..8af2f87ac 100644 --- a/exasol/toolbox/templates/github/workflows/checks.yml +++ b/exasol/toolbox/templates/github/workflows/checks.yml @@ -19,13 +19,7 @@ jobs: uses: exasol/python-toolbox/.github/actions/python-environment@1.2.0 - name: Check Version(s) - run: | - echo "Please enable the version check by replacing this output with shell command bellow:" - echo "" - echo "poetry run -- nox -s version:check -- <>" - echo "" - echo "Note: <> needs to point to the version file of the project (version.py)." - exit 1 + run: poetry run -- nox -s version:check Documentation: name: Docs diff --git a/exasol/toolbox/version.py b/exasol/toolbox/version.py index 9cfff41a5..631cc874c 100644 --- a/exasol/toolbox/version.py +++ b/exasol/toolbox/version.py @@ -1,7 +1,7 @@ # ATTENTION: # This file is generated by exasol/toolbox/nox/_package_version.py when using: # * either "poetry run -- nox -s project:fix" -# * or "poetry run -- nox version:check -- --fix" +# * or "poetry run -- nox version:check -- --fix" # Do not edit this file manually! # If you need to change the version, do so in the pyproject.toml, e.g. by using `poetry version X.Y.Z`. MAJOR = 1 diff --git a/project-template/{{cookiecutter.repo_name}}/exasol/{{cookiecutter.package_name}}/version.py b/project-template/{{cookiecutter.repo_name}}/exasol/{{cookiecutter.package_name}}/version.py index 7691647fd..e27082add 100644 --- a/project-template/{{cookiecutter.repo_name}}/exasol/{{cookiecutter.package_name}}/version.py +++ b/project-template/{{cookiecutter.repo_name}}/exasol/{{cookiecutter.package_name}}/version.py @@ -1,7 +1,7 @@ # ATTENTION: # This file is generated by exasol/toolbox/nox/_package_version.py when using: # * either "poetry run -- nox -s project:fix" -# * or "poetry run -- nox -s version:check -- --fix" +# * or "poetry run -- nox -s version:check -- --fix" # Do not edit this file manually! # If you need to change the version, do so in the pyproject.toml, e.g. by using `poetry version X.Y.Z`. MAJOR = 0 diff --git a/test/unit/nox/_package_version_test.py b/test/unit/nox/_package_version_test.py new file mode 100644 index 000000000..fe2783ab7 --- /dev/null +++ b/test/unit/nox/_package_version_test.py @@ -0,0 +1,68 @@ +from unittest import mock + +import pytest + +from exasol.toolbox.nox._package_version import ( + _create_parser, + _version_check, + write_version_module, +) +from exasol.toolbox.util.version import Version +from noxconfig import ( + Config, +) + +DEFAULT_VERSION = Version(major=0, minor=1, patch=0) +ALTERNATE_VERSION = Version(major=0, minor=2, patch=0) + + +@pytest.fixture +def config(version_file) -> Config: + return Config(version_file=version_file) + + +@pytest.fixture +def version_file(tmp_path): + version_file = tmp_path / "version.py" + write_version_module(version=DEFAULT_VERSION, version_file=version_file) + return version_file + + +def test_write_version_module(version_file) -> None: + write_version_module(version=ALTERNATE_VERSION, version_file=version_file) + assert version_file.exists() + + with version_file.open(mode="r", encoding="utf-8") as f: + result = f.read() + assert "MAJOR = 0\nMINOR = 2\nPATCH = 0\n" in result + + +class TestVersionCheck: + @staticmethod + @mock.patch.object(Version, "from_poetry", return_value=DEFAULT_VERSION) + def test_same_value_is_successful(from_poetry, config): + Version(major=0, minor=1, patch=0) + parser = _create_parser() + args = parser.parse_args([]) + + result = _version_check(args=args, config=config) + assert result == 0 + + @staticmethod + @mock.patch.object(Version, "from_poetry", return_value=ALTERNATE_VERSION) + def test_different_value_is_failure(from_poetry, config): + Version(major=0, minor=1, patch=0) + parser = _create_parser() + args = parser.parse_args([]) + + result = _version_check(args=args, config=config) + assert result == 1 + + @staticmethod + @mock.patch.object(Version, "from_poetry", return_value=ALTERNATE_VERSION) + def test_with_fix(from_poetry, config, version_file): + parser = _create_parser() + args = parser.parse_args(["--fix"]) + + result = _version_check(args=args, config=config) + assert result == 0