From 67a083dd88e51398a128c31c8b2fbbc7ef6d8fab Mon Sep 17 00:00:00 2001 From: Adrian D'Alessandro Date: Thu, 5 Dec 2024 18:27:40 +0000 Subject: [PATCH 1/9] Don't fail getting version if package not installed --- .../{{ cookiecutter.project_slug }}/__init__.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/{{ cookiecutter.project_slug }}/{{ cookiecutter.project_slug }}/__init__.py b/{{ cookiecutter.project_slug }}/{{ cookiecutter.project_slug }}/__init__.py index af3e610..0e777b2 100644 --- a/{{ cookiecutter.project_slug }}/{{ cookiecutter.project_slug }}/__init__.py +++ b/{{ cookiecutter.project_slug }}/{{ cookiecutter.project_slug }}/__init__.py @@ -1,5 +1,8 @@ """The main module for {{ cookiecutter.project_name }}.""" -from importlib.metadata import version +from importlib.metadata import PackageNotFoundError, version -__version__ = version(__name__) +try: + __version__ = version("MUSE_OS") +except PackageNotFoundError: + pass From 6045935038cbe8f1ef800daed854ac1b8d2fa308 Mon Sep 17 00:00:00 2001 From: Adrian D'Alessandro Date: Thu, 5 Dec 2024 18:35:32 +0000 Subject: [PATCH 2/9] Get version dynamically from scm --- {{ cookiecutter.project_slug }}/.vscode/settings.json | 3 ++- {{ cookiecutter.project_slug }}/pyproject.toml | 4 +++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/{{ cookiecutter.project_slug }}/.vscode/settings.json b/{{ cookiecutter.project_slug }}/.vscode/settings.json index d4817cc..c08182d 100644 --- a/{{ cookiecutter.project_slug }}/.vscode/settings.json +++ b/{{ cookiecutter.project_slug }}/.vscode/settings.json @@ -7,5 +7,6 @@ 88 ], "python.testing.unittestEnabled": false, - "python.testing.pytestEnabled": true + "python.testing.pytestEnabled": true, + "editor.formatOnSave": false } diff --git a/{{ cookiecutter.project_slug }}/pyproject.toml b/{{ cookiecutter.project_slug }}/pyproject.toml index a7b076e..17e8ce8 100644 --- a/{{ cookiecutter.project_slug }}/pyproject.toml +++ b/{{ cookiecutter.project_slug }}/pyproject.toml @@ -36,7 +36,7 @@ build-backend = "poetry.core.masonry.api" {%- elif cookiecutter.packaging == "pip-tools" -%} [project] name = "{{ cookiecutter.project_slug }}" -version = "0.1.0" +dynamic = ["version"] description = "{{ cookiecutter.project_description }}" authors = [ { name = "{{ cookiecutter.author }}", email = "{{ cookiecutter.author_email }}" } @@ -73,6 +73,8 @@ build-backend = "setuptools.build_meta" [tool.setuptools.packages.find] exclude = ["htmlcov"] # Exclude the coverage report file from setuptools package finder + +[tool.setuptools_scm] {%- endif %} [tool.mypy] From c097a73a80fd7471da5db7741251a1814df4056d Mon Sep 17 00:00:00 2001 From: Adrian D'Alessandro Date: Fri, 6 Dec 2024 15:02:52 +0000 Subject: [PATCH 3/9] Use __name__ to get package version --- .../{{ cookiecutter.project_slug }}/__init__.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/{{ cookiecutter.project_slug }}/{{ cookiecutter.project_slug }}/__init__.py b/{{ cookiecutter.project_slug }}/{{ cookiecutter.project_slug }}/__init__.py index 0e777b2..2e8353a 100644 --- a/{{ cookiecutter.project_slug }}/{{ cookiecutter.project_slug }}/__init__.py +++ b/{{ cookiecutter.project_slug }}/{{ cookiecutter.project_slug }}/__init__.py @@ -1,8 +1,7 @@ """The main module for {{ cookiecutter.project_name }}.""" +from contextlib import suppress from importlib.metadata import PackageNotFoundError, version -try: - __version__ = version("MUSE_OS") -except PackageNotFoundError: - pass +with suppress(PackageNotFoundError): + __version__ = version(__name__) From 9575e1090f8aedf75cf33a1ee6298ea1d3140669 Mon Sep 17 00:00:00 2001 From: Adrian D'Alessandro Date: Fri, 6 Dec 2024 16:00:23 +0000 Subject: [PATCH 4/9] Instruct to initialise git repo in project setup --- .github/workflows/ci-pip-tools.yml | 2 +- {{ cookiecutter.project_slug }}/README.pip-tools.jinja | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci-pip-tools.yml b/.github/workflows/ci-pip-tools.yml index 1ac81d9..5e5bbd5 100644 --- a/.github/workflows/ci-pip-tools.yml +++ b/.github/workflows/ci-pip-tools.yml @@ -35,6 +35,7 @@ jobs: - name: Install project dependencies working-directory: my_project run: | + git init pip install --upgrade pip pip install -r dev-requirements.txt pip install -e . @@ -50,6 +51,5 @@ jobs: - name: Run pre-commit hooks for project working-directory: my_project run: | - git init git add . pre-commit run -a diff --git a/{{ cookiecutter.project_slug }}/README.pip-tools.jinja b/{{ cookiecutter.project_slug }}/README.pip-tools.jinja index 56b19c0..161b4e7 100644 --- a/{{ cookiecutter.project_slug }}/README.pip-tools.jinja +++ b/{{ cookiecutter.project_slug }}/README.pip-tools.jinja @@ -6,6 +6,13 @@ This is a Python application that uses [`pip-tools`] for packaging and dependenc To get started: +1. Activate a git repository (required for `pre-commit` and the package versioning with +`setuptools-scm`): + + ```bash + git init + ``` + 1. Create and activate a [virtual environment](https://docs.python.org/3/library/venv.html): ```bash From a47278ae5d2a9422a19032f15b9af9008e674388 Mon Sep 17 00:00:00 2001 From: Adrian D'Alessandro Date: Fri, 6 Dec 2024 16:00:38 +0000 Subject: [PATCH 5/9] Tidy up README --- .../README.pip-tools.jinja | 50 ++++++++++++++----- 1 file changed, 38 insertions(+), 12 deletions(-) diff --git a/{{ cookiecutter.project_slug }}/README.pip-tools.jinja b/{{ cookiecutter.project_slug }}/README.pip-tools.jinja index 161b4e7..fb85574 100644 --- a/{{ cookiecutter.project_slug }}/README.pip-tools.jinja +++ b/{{ cookiecutter.project_slug }}/README.pip-tools.jinja @@ -1,6 +1,15 @@ -This is a Python application that uses [`pip-tools`] for packaging and dependency management. It also provides [`pre-commit`](https://pre-commit.com/) hooks (for for [ruff](https://pypi.org/project/ruff/) and [`mypy`](https://mypy.readthedocs.io/en/stable/)) and automated tests using [`pytest`](https://pytest.org/) and [GitHub Actions](https://github.com/features/actions). Pre-commit hooks are automatically kept updated with a dedicated GitHub Action, this can be removed and replace with [pre-commit.ci](https://pre-commit.ci) if using an public repo. It was developed by the [Imperial College Research Computing Service](https://www.imperial.ac.uk/admin-services/ict/self-service/research-support/rcs/). +This is a Python application that uses [`pip-tools`][pip-tools] for packaging and +dependency management. It also provides [`pre-commit`][pre-commit] hooks (for +[`ruff`][ruff] and [`mypy`][mypy]) and automated tests using [`pytest`][pytest] and +[GitHub Actions]. Pre-commit hooks are automatically kept updated with a dedicated +GitHub Action, this can be removed and replaced with [pre-commit.ci] if using a public +repo. The package version is dynamically generated from the most recent git tag using +[`setuptools-scm`][setuptools-scm]. -[`pip-tools`] is chosen as a lightweight dependency manager that adheres to the [latest standards](https://peps.python.org/pep-0621/) using `pyproject.toml`. +[`pip-tools`][pip-tools] is chosen as a lightweight dependency manager that adheres to +the [latest standards] using `pyproject.toml`. + +It was developed by the [Imperial College Research Software Engineering Team]. ## Usage @@ -13,14 +22,14 @@ To get started: git init ``` -1. Create and activate a [virtual environment](https://docs.python.org/3/library/venv.html): +1. Create and activate a [virtual environment]: ```bash python -m venv .venv source .venv/bin/activate # with Powershell on Windows: `.venv\Scripts\Activate.ps1` ``` -1. Install development requirements and the package in editable mode: +2. Install development requirements and the package in editable mode: ```bash pip install -r dev-requirements.txt @@ -39,13 +48,13 @@ To get started: pre-commit install ``` -1. Run the main app: +2. Run the main app: ```bash python -m {{ cookiecutter.project_slug }} ``` -1. Run the tests: +3. Run the tests: ```bash pytest @@ -55,17 +64,20 @@ To get started: To add or remove dependencies: -1. Edit the `dependencies` variables in the `pyproject.toml` file (aim to keep development tools separate from the project requirements). +1. Edit the `dependencies` variables in the `pyproject.toml` file (aim to keep +development tools separate from the project requirements). 2. Update the requirements files: - `pip-compile` for `requirements.txt` - the project requirements. - `pip-compile --extra dev -o dev-requirements.txt` for the development requirements. -{% if cookiecutter.mkdocs %} - `pip-compile --extra doc -o doc-requirements.txt` for the documentation tools. +{% if cookiecutter.mkdocs %} - `pip-compile --extra doc -o doc-requirements.txt` for +the documentation tools. {% endif %}3. Sync the files with your installation (install packages): - `pip-sync *requirements.txt` To upgrade pinned versions, use the `--upgrade` flag with `pip-compile`. -Versions can be restricted from updating within the `pyproject.toml` using standard python package version specifiers, i.e. `"black<23"` or `"pip-tools!=6.12.2"` +Versions can be restricted from updating within the `pyproject.toml` using standard +python package version specifiers, i.e. `"black<23"` or `"pip-tools!=6.12.2"` ## Customising @@ -73,11 +85,25 @@ All configuration can be customised to your preferences. The key places to make for this are: - The `pyproject.toml` file, where you can edit: - - The build system (change from setuptools to other packaging tools like [Hatch](https://hatch.pypa.io/) or [flit](https://flit.pypa.io/)). + - The build system (change from setuptools to other packaging tools like [Hatch] or +[flit]). - The python version. - - The project dependencies. Extra optional dependencies can be added by adding another list under `[project.optional-dependencies]` (i.e. `doc = ["mkdocs"]`). + - The project dependencies. Extra optional dependencies can be added by adding another +list under `[project.optional-dependencies]` (i.e. `doc = ["mkdocs"]`). - The `mypy` and `pytest` configurations. - The `.pre-commit-config.yaml` for pre-commit settings. - The `.github` directory for all the CI configuration. -[`pip-tools`]: https://pip-tools.readthedocs.io/en/latest/ +[pip-tools]: https://pip-tools.readthedocs.io/en/stable/ +[pre-commit]: https://pre-commit.com/ +[ruff]: https://pypi.org/project/ruff/ +[mypy]: https://mypy.readthedocs.io/en/stable/ +[pytest]: https://pytest.org/ +[GitHub Actions]: https://github.com/features/actions +[pre-commit.ci]: https://pre-commit.ci +[setuptools-scm]: https://setuptools-scm.readthedocs.io/en/latest/ +[latest standards]: https://peps.python.org/pep-0621/ +[Imperial College Research Software Engineering Team]: https://www.imperial.ac.uk/admin-services/ict/self-service/research-support/rcs/service-offering/research-software-engineering/ +[virtual environment]: https://docs.python.org/3/library/venv.html +[Hatch]: https://hatch.pypa.io/ +[flit]: https://flit.pypa.io/ From 50e72b77ad03053bf977a0ee052ea3fb946f2192 Mon Sep 17 00:00:00 2001 From: Adrian D'Alessandro Date: Fri, 6 Dec 2024 16:05:41 +0000 Subject: [PATCH 6/9] Only test start of version string because of scm --- .../tests/test_{{ cookiecutter.project_slug}}.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/{{ cookiecutter.project_slug }}/tests/test_{{ cookiecutter.project_slug}}.py b/{{ cookiecutter.project_slug }}/tests/test_{{ cookiecutter.project_slug}}.py index 75e8ef8..a8f3812 100644 --- a/{{ cookiecutter.project_slug }}/tests/test_{{ cookiecutter.project_slug}}.py +++ b/{{ cookiecutter.project_slug }}/tests/test_{{ cookiecutter.project_slug}}.py @@ -5,4 +5,4 @@ def test_version(): """Check that the version is acceptable.""" - assert __version__ == "0.1.0" + assert __version__.startswith("0.1.") From dcb05a7ed64540b66f79f2430434b5ca3da5e1e3 Mon Sep 17 00:00:00 2001 From: Adrian D'Alessandro Date: Fri, 6 Dec 2024 16:08:29 +0000 Subject: [PATCH 7/9] undo auto-changes to readme --- {{ cookiecutter.project_slug }}/README.pip-tools.jinja | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/{{ cookiecutter.project_slug }}/README.pip-tools.jinja b/{{ cookiecutter.project_slug }}/README.pip-tools.jinja index fb85574..eabee65 100644 --- a/{{ cookiecutter.project_slug }}/README.pip-tools.jinja +++ b/{{ cookiecutter.project_slug }}/README.pip-tools.jinja @@ -29,7 +29,7 @@ To get started: source .venv/bin/activate # with Powershell on Windows: `.venv\Scripts\Activate.ps1` ``` -2. Install development requirements and the package in editable mode: +1. Install development requirements and the package in editable mode: ```bash pip install -r dev-requirements.txt @@ -48,13 +48,13 @@ To get started: pre-commit install ``` -2. Run the main app: +1. Run the main app: ```bash python -m {{ cookiecutter.project_slug }} ``` -3. Run the tests: +1. Run the tests: ```bash pytest @@ -66,7 +66,7 @@ To add or remove dependencies: 1. Edit the `dependencies` variables in the `pyproject.toml` file (aim to keep development tools separate from the project requirements). -2. Update the requirements files: +1. Update the requirements files: - `pip-compile` for `requirements.txt` - the project requirements. - `pip-compile --extra dev -o dev-requirements.txt` for the development requirements. {% if cookiecutter.mkdocs %} - `pip-compile --extra doc -o doc-requirements.txt` for From 39e22dac31fdbf107a15b2dc1edb727a31ec57ef Mon Sep 17 00:00:00 2001 From: Adrian D'Alessandro Date: Fri, 6 Dec 2024 16:10:35 +0000 Subject: [PATCH 8/9] more markdownlint... --- {{ cookiecutter.project_slug }}/README.pip-tools.jinja | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/{{ cookiecutter.project_slug }}/README.pip-tools.jinja b/{{ cookiecutter.project_slug }}/README.pip-tools.jinja index eabee65..8dd3ea6 100644 --- a/{{ cookiecutter.project_slug }}/README.pip-tools.jinja +++ b/{{ cookiecutter.project_slug }}/README.pip-tools.jinja @@ -71,7 +71,7 @@ development tools separate from the project requirements). - `pip-compile --extra dev -o dev-requirements.txt` for the development requirements. {% if cookiecutter.mkdocs %} - `pip-compile --extra doc -o doc-requirements.txt` for the documentation tools. -{% endif %}3. Sync the files with your installation (install packages): +{% endif %}1. Sync the files with your installation (install packages): - `pip-sync *requirements.txt` To upgrade pinned versions, use the `--upgrade` flag with `pip-compile`. From 34c77e002608420b96c224d8bb6942ab905e4383 Mon Sep 17 00:00:00 2001 From: Adrian D'Alessandro Date: Wed, 11 Dec 2024 20:34:37 +0000 Subject: [PATCH 9/9] Assert version string is a str in test --- .../tests/test_{{ cookiecutter.project_slug}}.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/{{ cookiecutter.project_slug }}/tests/test_{{ cookiecutter.project_slug}}.py b/{{ cookiecutter.project_slug }}/tests/test_{{ cookiecutter.project_slug}}.py index a8f3812..0f5974f 100644 --- a/{{ cookiecutter.project_slug }}/tests/test_{{ cookiecutter.project_slug}}.py +++ b/{{ cookiecutter.project_slug }}/tests/test_{{ cookiecutter.project_slug}}.py @@ -5,4 +5,4 @@ def test_version(): """Check that the version is acceptable.""" - assert __version__.startswith("0.1.") + assert isinstance(__version__, str)