diff --git a/doc/changes/unreleased.md b/doc/changes/unreleased.md index 6f367b399..1fad4d6ff 100644 --- a/doc/changes/unreleased.md +++ b/doc/changes/unreleased.md @@ -38,6 +38,7 @@ take care and will need to make manual changes to ensure it still works with * #649: Restricted noxconfig usage throughout exasol.toolbox to only exasol.toolbox.nox.* * #647: Added summary to changelog template +* #657: Updated `release:prepare` to modify cookiecutter template exasol-toolbox version range ## Refactoring diff --git a/exasol/toolbox/templates/pre-commit-config.yaml b/exasol/toolbox/templates/pre-commit-config.yaml deleted file mode 100644 index b4eaf6b80..000000000 --- a/exasol/toolbox/templates/pre-commit-config.yaml +++ /dev/null @@ -1,36 +0,0 @@ -default_stages: [ commit ] -repos: - - - repo: local - hooks: - - id: code-format - name: code-format - types: [ python ] - pass_filenames: false - language: system - entry: poetry run -- nox -s format:fix - - - repo: local - hooks: - - id: type-check - name: type-check - types: [ python ] - pass_filenames: false - language: system - entry: poetry run -- nox -s lint:typing - - - repo: local - hooks: - - id: lint - name: lint - types: [ python ] - pass_filenames: false - language: system - entry: poetry run -- nox -s lint:code - - - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.4.0 - hooks: - - id: check-yaml - - id: end-of-file-fixer - - id: trailing-whitespace diff --git a/exasol/toolbox/util/release/cookiecutter.py b/exasol/toolbox/util/release/cookiecutter.py new file mode 100644 index 000000000..82b2a89bb --- /dev/null +++ b/exasol/toolbox/util/release/cookiecutter.py @@ -0,0 +1,17 @@ +from json import ( + dumps, + loads, +) +from pathlib import Path + +from exasol.toolbox.util.version import Version + + +def update_cookiecutter_default(cookiecutter_json: Path, version: Version) -> None: + contents = cookiecutter_json.read_text() + contents_as_dict = loads(contents) + + contents_as_dict["exasol_toolbox_version_range"] = f">={version},<{version.major+1}" + + updated_contents = dumps(contents_as_dict, indent=2) + cookiecutter_json.write_text(updated_contents) diff --git a/noxconfig.py b/noxconfig.py index 51ac4f73d..8f20383e3 100644 --- a/noxconfig.py +++ b/noxconfig.py @@ -9,44 +9,51 @@ from exasol.toolbox.config import BaseConfig from exasol.toolbox.nox.plugin import hookimpl from exasol.toolbox.tools.replace_version import update_github_yml +from exasol.toolbox.util.release.cookiecutter import update_cookiecutter_default from exasol.toolbox.util.version import Version class UpdateTemplates: - TEMPLATE_PATH: Path = Path(__file__).parent / "exasol" / "toolbox" / "templates" PARENT_PATH: Path = Path(__file__).parent @property - def template_workflows(self) -> list[Path]: - gh_workflows = self.TEMPLATE_PATH / "github" / "workflows" + def github_template_workflows(self) -> list[Path]: + gh_workflows = ( + self.PARENT_PATH + / "exasol" + / "toolbox" + / "templates" + / "github" + / "workflows" + ) return [f for f in gh_workflows.iterdir() if f.is_file()] @property - def actions(self) -> list[Path]: + def github_actions(self) -> list[Path]: gh_actions = self.PARENT_PATH / ".github" / "actions" return [f for f in gh_actions.rglob("*") if f.is_file()] + @property + def cookiecutter_json(self) -> Path: + return self.PARENT_PATH / "project-template" / "cookiecutter.json" + @hookimpl def prepare_release_update_version(self, session, config, version: Version) -> None: - for workflow in self.template_workflows: + for workflow in self.github_template_workflows: update_github_yml(workflow, version) - for action in self.actions: + for action in self.github_actions: update_github_yml(action, version) + update_cookiecutter_default(self.cookiecutter_json, version) + @hookimpl - def prepare_release_add_files(self, session, config): - return self.template_workflows + self.actions - - -# BaseConfig -# - Use -# Project_Config = BaseConfig() -# - modify -# Project_Config = BaseConfig(python_versions=["3.12"]) -# - expand (Do not overwrite the attributes of BaseConfig) -# class ProjectConfig(BaseConfig): -# extra_data: list[str] = ["data"] + def prepare_release_add_files(self, session, config) -> list[Path]: + return ( + self.github_template_workflows + + self.github_actions + + [self.cookiecutter_json] + ) ROOT_PATH = Path(__file__).parent diff --git a/project-template/cookiecutter.json b/project-template/cookiecutter.json index 81cedc696..3aa430337 100644 --- a/project-template/cookiecutter.json +++ b/project-template/cookiecutter.json @@ -9,8 +9,11 @@ "author_email": "opensource@exasol.com", "project_short_tag": "", "python_version_min": "3.10", + "exasol_toolbox_version_range": ">=4.0.1,<5", "license_year": "{% now 'utc', '%Y' %}", "__repo_name_slug": "{{cookiecutter.package_name}}", "__package_name_slug": "{{cookiecutter.package_name}}", - "_extensions": ["cookiecutter.extensions.TimeExtension"] + "_extensions": [ + "cookiecutter.extensions.TimeExtension" + ] } diff --git a/project-template/{{cookiecutter.repo_name}}/pyproject.toml b/project-template/{{cookiecutter.repo_name}}/pyproject.toml index 027477215..33dcc0710 100644 --- a/project-template/{{cookiecutter.repo_name}}/pyproject.toml +++ b/project-template/{{cookiecutter.repo_name}}/pyproject.toml @@ -18,7 +18,7 @@ dependencies = [] [dependency-groups] dev = [ - "exasol-toolbox>=4.0.1,<5", + "exasol-toolbox{{cookiecutter.exasol_toolbox_version_range}}", ] [tool.poetry] diff --git a/test/unit/util/release/cookiecutter_test.py b/test/unit/util/release/cookiecutter_test.py new file mode 100644 index 000000000..e363d20a6 --- /dev/null +++ b/test/unit/util/release/cookiecutter_test.py @@ -0,0 +1,53 @@ +from inspect import cleandoc +from json import loads +from pathlib import Path + +import pytest + +from exasol.toolbox.util.release.cookiecutter import update_cookiecutter_default +from exasol.toolbox.util.version import Version + + +@pytest.fixture +def cookiecutter_json(tmp_path: Path) -> Path: + cookiecutter_json = tmp_path / "cookiecutter.json" + contents = """ + { + "project_name": "Yet Another Project", + "repo_name": "{{cookiecutter.project_name | lower | replace(' ', '-')}}", + "package_name": "{{cookiecutter.repo_name | replace('-', '_')}}", + "pypi_package_name": "exasol-{{cookiecutter.repo_name}}", + "import_package": "exasol.{{cookiecutter.package_name}}", + "description": "", + "author_full_name": "Exasol AG", + "author_email": "opensource@exasol.com", + "project_short_tag": "", + "python_version_min": "3.10", + "exasol_toolbox_version_range": ">=4.0.1,<5", + "license_year": "{% now 'utc', '%Y' %}", + "__repo_name_slug": "{{cookiecutter.package_name}}", + "__package_name_slug": "{{cookiecutter.package_name}}", + "_extensions": [ + "cookiecutter.extensions.TimeExtension" + ] + } + """ + cookiecutter_json.write_text(cleandoc(contents)) + return cookiecutter_json + + +@pytest.mark.parametrize( + "version,expected", + [ + pytest.param(Version(major=5, minor=0, patch=7), ">=5.0.7,<6"), + pytest.param(Version(major=6, minor=2, patch=7), ">=6.2.7,<7"), + ], +) +def test_update_cookiecutter_default( + cookiecutter_json, version: Version, expected: str +): + update_cookiecutter_default(cookiecutter_json=cookiecutter_json, version=version) + + updated_json = cookiecutter_json.read_text() + updated_dict = loads(updated_json) + assert updated_dict["exasol_toolbox_version_range"] == expected