From 8941824bf4ecded3a9e70bf2baf625f799ef8a33 Mon Sep 17 00:00:00 2001 From: Adam Bolte Date: Tue, 26 Nov 2024 19:57:37 +1100 Subject: [PATCH 01/22] Have deploy_license support multiple file refs eg. GPL-3.0-only and GPL-3.0-or-later should be able to point to the same license file. --- hooks/post_gen_project.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/hooks/post_gen_project.py b/hooks/post_gen_project.py index e83167b..76a5b2a 100644 --- a/hooks/post_gen_project.py +++ b/hooks/post_gen_project.py @@ -13,11 +13,12 @@ LICENSE_SELECTED = "{{ cookiecutter.license }}" -def deploy_license(): +def deploy_license() -> None: """Move the selected license file into the project root Licenses not selected for the project are removed. """ + sources = set() with LICENSE_CONFIG.open(mode="r", encoding="utf-8") as config_file: config = json.load(config_file) for license_option, license_data in config.items(): @@ -26,7 +27,9 @@ def deploy_license(): PROJECT_DIR.joinpath(license_data["destination"]) ) else: - LICENSE_DIR.joinpath(license_data["source"]).unlink() + sources.add(LICENSE_DIR.joinpath(license_data["source"])) + for source in sources: + source.unlink() LICENSE_CONFIG.unlink() LICENSE_DIR.rmdir() From ade1ec91a61393be46592ceef83179ee96ecf091 Mon Sep 17 00:00:00 2001 From: Adam Bolte Date: Tue, 26 Nov 2024 19:59:42 +1100 Subject: [PATCH 02/22] List licenses by SPDX identifier --- cookiecutter.json | 16 +++++++++------- .../licenses/config.json | 14 ++++++++------ 2 files changed, 17 insertions(+), 13 deletions(-) diff --git a/cookiecutter.json b/cookiecutter.json index 9a8d332..82e2b94 100644 --- a/cookiecutter.json +++ b/cookiecutter.json @@ -8,13 +8,15 @@ "github_user_name": "GithubUserName", "github_repo_name": "{{cookiecutter.package_name}}", "license": [ - "Apache License, Version 2.0", - "Expat License", - "GNU GPL version 2", - "GNU GPL version 3", - "GNU AGPL version 3", - "Modified BSD license (3-clause)", - "Not licensed for distribution (no license)" + "Not licensed for distribution (no license)", + "AGPL-3.0-only", + "AGPL-3.0-or-later", + "Apache-2.0", + "BSD-3-Clause", + "GPL-2.0-only", + "GPL-2.0-or-later", + "GPL-3.0-only", + "GPL-3.0-or-later" ], "year": "{% now 'utc', '%Y' %}" } diff --git a/{{cookiecutter.package_name}}/licenses/config.json b/{{cookiecutter.package_name}}/licenses/config.json index 519608f..3203fc5 100644 --- a/{{cookiecutter.package_name}}/licenses/config.json +++ b/{{cookiecutter.package_name}}/licenses/config.json @@ -1,8 +1,10 @@ { - "Apache License, Version 2.0": {"source": "APACHE-2.0", "destination": "LICENSE"}, - "Expat License": {"source": "EXPAT", "destination": "LICENSE"}, - "GNU GPL version 3": {"source": "GPL3", "destination": "COPYING"}, - "GNU GPL version 2": {"source": "GPL2", "destination": "COPYING"}, - "GNU AGPL version 3": {"source": "AGPL3", "destination": "COPYING"}, - "Modified BSD license (3-clause)": {"source": "BSD-3-CLAUSE", "destination": "LICENSE"} + "AGPL-3.0-only": {"source": "AGPL3", "destination": "COPYING"}, + "AGPL-3.0-or-later": {"source": "AGPL3", "destination": "COPYING"}, + "Apache-2.0": {"source": "APACHE-2.0", "destination": "LICENSE"}, + "BSD-3-Clause": {"source": "BSD-3-CLAUSE", "destination": "LICENSE"}, + "GPL-2.0-only": {"source": "GPL2", "destination": "COPYING"}, + "GPL-2.0-or-later": {"source": "GPL2", "destination": "COPYING"}, + "GPL-3.0-only": {"source": "GPL3", "destination": "COPYING"}, + "GPL-3.0-or-later": {"source": "GPL3", "destination": "COPYING"} } From f368121beb16562f29b99801c188b4d0144727b6 Mon Sep 17 00:00:00 2001 From: Adam Bolte Date: Tue, 26 Nov 2024 20:01:02 +1100 Subject: [PATCH 03/22] Update GPLv2 license (removes FSF postal address) --- {{cookiecutter.package_name}}/licenses/GPL2 | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/{{cookiecutter.package_name}}/licenses/GPL2 b/{{cookiecutter.package_name}}/licenses/GPL2 index d159169..9efa6fb 100644 --- a/{{cookiecutter.package_name}}/licenses/GPL2 +++ b/{{cookiecutter.package_name}}/licenses/GPL2 @@ -2,7 +2,7 @@ Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. @@ -304,8 +304,7 @@ the "copyright" line and a pointer to where the full notice is found. GNU General Public License for more details. You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + with this program; if not, see . Also add information on how to contact you by electronic and paper mail. @@ -329,8 +328,8 @@ necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. - , 1 April 1989 - Ty Coon, President of Vice + , 1 April 1989 + Moe Ghoul, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may From f05eecc7ca07141870bb1da163deb990eb15ac63 Mon Sep 17 00:00:00 2001 From: Adam Bolte Date: Tue, 26 Nov 2024 20:02:20 +1100 Subject: [PATCH 04/22] Remove EXPAT license --- {{cookiecutter.package_name}}/licenses/EXPAT | 20 -------------------- 1 file changed, 20 deletions(-) delete mode 100644 {{cookiecutter.package_name}}/licenses/EXPAT diff --git a/{{cookiecutter.package_name}}/licenses/EXPAT b/{{cookiecutter.package_name}}/licenses/EXPAT deleted file mode 100644 index 5ee27cb..0000000 --- a/{{cookiecutter.package_name}}/licenses/EXPAT +++ /dev/null @@ -1,20 +0,0 @@ -Copyright {{cookiecutter.year}} {{cookiecutter.full_name}} - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. From 44295d7edbf552bab7ac7d849c75c894014fa253 Mon Sep 17 00:00:00 2001 From: Adam Bolte Date: Tue, 26 Nov 2024 20:03:30 +1100 Subject: [PATCH 05/22] Move mypi.ini contents to pyproject.toml --- {{cookiecutter.package_name}}/mypi.ini | 7 ------- {{cookiecutter.package_name}}/pyproject.toml | 8 ++++++++ 2 files changed, 8 insertions(+), 7 deletions(-) delete mode 100644 {{cookiecutter.package_name}}/mypi.ini diff --git a/{{cookiecutter.package_name}}/mypi.ini b/{{cookiecutter.package_name}}/mypi.ini deleted file mode 100644 index ef615ee..0000000 --- a/{{cookiecutter.package_name}}/mypi.ini +++ /dev/null @@ -1,7 +0,0 @@ -[mypy] -show_column_numbers = true -disallow_untyped_calls = true -disallow_untyped_defs = true -follow_imports = skip -no_implicit_optional = true -warn_no_return = true diff --git a/{{cookiecutter.package_name}}/pyproject.toml b/{{cookiecutter.package_name}}/pyproject.toml index 5c2a51c..f834f0f 100644 --- a/{{cookiecutter.package_name}}/pyproject.toml +++ b/{{cookiecutter.package_name}}/pyproject.toml @@ -10,3 +10,11 @@ force_grid_wrap = 0 use_parentheses = true ensure_newline_before_comments = true line_length = 79 + +[tool.mypy] +disallow_untyped_calls = true +disallow_untyped_defs = true +follow_imports = skip +no_implicit_optional = true +show_column_numbers = true +warn_no_return = true From 8c4f4a2584186e1128e06ebefbd4edd503a213a9 Mon Sep 17 00:00:00 2001 From: Adam Bolte Date: Tue, 26 Nov 2024 20:05:49 +1100 Subject: [PATCH 06/22] Switch from setuptools to Hatch --- {{cookiecutter.package_name}}/pyproject.toml | 52 +++++++++++++++ {{cookiecutter.package_name}}/setup.py | 70 -------------------- 2 files changed, 52 insertions(+), 70 deletions(-) delete mode 100644 {{cookiecutter.package_name}}/setup.py diff --git a/{{cookiecutter.package_name}}/pyproject.toml b/{{cookiecutter.package_name}}/pyproject.toml index f834f0f..c2565c2 100644 --- a/{{cookiecutter.package_name}}/pyproject.toml +++ b/{{cookiecutter.package_name}}/pyproject.toml @@ -1,3 +1,55 @@ +[build-system] +requires = ["hatchling"] +build-backend = "hatchling.build" + +[project] +name = "{{cookiecutter.package_name}}" +dynamic = ["version"] +requires-python = ">= 3.11" +dependencies = [] +authors = [ + { + name = "{{cookiecutter.package_name}}", + email = "{{cookiecutter.email}}", + }, +] +keywords=[ + "{{cookiecutter.package_name}}" +] +description = "{{cookiecutter.package_short_description}}" +readme = "README.rst" +license = "{{cookiecutter.license}}" +classifiers = [ + "Development Status :: 2 - Pre-Alpha", + "Intended Audience :: Developers", + "Operating System :: OS Independent", + "Programming Language :: Python", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3 :: Only", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", +] + +[project.optional-dependencies] +dev = [ + "black", + "coverage", + "isort", + "mypy", + "pylint", + "sphinx", + "twine", + "wheel", +] + +[project.urls] +Documentation = "http://{{cookiecutter.package_name}}.readthedocs.io" +"Source code" = "https://github.com/{{cookiecutter.github_user_name}}/{{cookiecutter.github_repo_name}}" + +[tool.hatch.version] +path = "src/{{cookiecutter.package_name}}/__about__.py" + [tool.black] line-length = 79 diff --git a/{{cookiecutter.package_name}}/setup.py b/{{cookiecutter.package_name}}/setup.py deleted file mode 100644 index c284105..0000000 --- a/{{cookiecutter.package_name}}/setup.py +++ /dev/null @@ -1,70 +0,0 @@ -import re -from pathlib import PurePath - -from setuptools import setup - -regexp = re.compile(r".*__version__ = [\'\"](.*?)[\'\"]", re.S) - -base_package = "{{cookiecutter.package_name}}" -base_path = PurePath(__file__).parent - -init_file = PurePath(base_path).joinpath( - "{{cookiecutter.package_name}}", "__init__.py" -) -with open(init_file, "r", encoding="utf-8") as f: - module_content = f.read() - - match = regexp.match(module_content) - if match: - version = match.group(1) - else: - raise RuntimeError(f"Cannot find __version__ in {init_file}") - -with open("README.rst", "r", encoding="utf-8") as f: - readme = f.read() - -with open("CHANGELOG.rst", "r", encoding="utf-8") as f: - changes = f.read() - - -def parse_requirements(filename): - """Load requirements from a pip requirements file""" - with open(filename, "r", encoding="utf-8") as fd: - lines = [] - for line in fd: - line.strip() - if line and not line.startswith("#"): - lines.append(line) - return lines - - -requirements = parse_requirements("requirements.txt") - - -if __name__ == "__main__": - setup( - name="{{cookiecutter.package_name}}", - description="{{cookiecutter.package_short_description}}", - long_description="\n\n".join([readme, changes]), - license="{{cookiecutter.license}}", - url="https://github.com/{{cookiecutter.github_user_name}}/{{cookiecutter.github_repo_name}}", - version=version, - author="{{cookiecutter.full_name}}", - author_email="{{cookiecutter.email}}", - maintainer="{{cookiecutter.full_name}}", - maintainer_email="{{cookiecutter.email}}", - install_requires=requirements, - keywords=["{{cookiecutter.package_name}}"], - packages=["{{cookiecutter.package_name}}"], - zip_safe=False, - # https://pypi.org/classifiers/ - classifiers=[ - "Development Status :: 3 - Alpha", - "Intended Audience :: Developers", - "Programming Language :: Python :: 3.7", - "Programming Language :: Python :: 3.8", - "Programming Language :: Python :: 3.9", - "Programming Language :: Python :: 3.10", - "Programming Language :: Python :: 3.11", - ], - ) From 1c242d3bdea47d22847ade344fb0cd581536a840 Mon Sep 17 00:00:00 2001 From: Adam Bolte Date: Tue, 26 Nov 2024 20:07:22 +1100 Subject: [PATCH 07/22] Update README.rst to reflect template changes --- README.rst | 52 +++++++++++++++++++++++++++------------------------- 1 file changed, 27 insertions(+), 25 deletions(-) diff --git a/README.rst b/README.rst index 94fb6ca..28574a6 100644 --- a/README.rst +++ b/README.rst @@ -34,8 +34,7 @@ the following items: developer documentation. - An empty ``CHANGELOG.rst`` file. This file gets included in the user documentation. -- A ``LICENSE`` file (or ``COPYING`` for GNU licenses) that defaults - to the Apache License version 2.0. +- An option ``LICENSE`` file (or ``COPYING`` for GNU licenses). - An ``examples`` directory with a minimal quickstart example script. This script imports the package and prints the package version. It is also called by the unit test suite to ensure it always works. @@ -77,9 +76,9 @@ cookiecutter using ``pip``. The example below shows how to do this. .. code-block:: console - $ python -m venv ccvenv --prompt cc + $ python -m venv --prompt cc ccvenv $ source ccvenv/bin/activate - (cc) $ pip install pip -U # update pip to avoid any warnings + (cc) $ pip install -U pip # update pip to avoid any warnings (cc) $ pip install cookiecutter You are now ready to create a new Python project from the Cookiecutter @@ -132,11 +131,12 @@ using the new project. ReadTheDocs then remove any links to those sites. Affected files are: - README.rst - - setup.py - docs/source/index.rst + - pyproject.toml -- Update any additional useful classifiers in ``setup.py``. The list of - available classifiers can be found `here `_. +- Update any additional useful classifiers in ``pyproject.toml``. The + list of available classifiers can be found `here + `_. Example @@ -162,24 +162,26 @@ Python package name. .. code-block:: console (cc) $ cookiecutter ../cookiecutter-python-project/ - package_display_name [Package-Name]: abc 123 - package_name [abc_123]: - package_short_description [A description of the package]: This is my abc 123 package. - version [0.0.1]: - full_name [Your Name]: First Last - email []: - github_user_name [GithubUserName]: flast - github_repo_name [abc_123]: - Select license: - 1 - Apache License, Version 2.0 - 2 - Expat License - 3 - GNU GPL version 2 - 4 - GNU GPL version 3 - 5 - GNU AGPL version 3 - 6 - Modified BSD license (3-clause) - 7 - Not licensed for distribution (no license) - Choose from 1, 2, 3, 4, 5, 6, 7 [1]: - year [2023]: + [1/10] package_display_name (Package-Name): abc 123 + [2/10] package_name (abc_123): + [3/10] package_short_description (A description of the package): This is my abc 123 package. + [4/10] version (0.0.1): + [5/10] full_name (Your Name): First Last + [6/10] email (): + [7/10] github_user_name (GithubUserName): flast + [8/10] github_repo_name (abc_123): + [9/10] Select license + 1 - Not licensed for distribution (no license) + 2 - AGPL-3.0-only + 3 - AGPL-3.0-or-later + 4 - Apache-2.0 + 5 - BSD-3-Clause + 6 - GPL-2.0-only + 7 - GPL-2.0-or-later + 8 - GPL-3.0-only + 9 - GPL-3.0-or-later + Choose from [1/2/3/4/5/6/7/8/9] (1): + [10/10] year (2024): The project has been created in the ``abc_123`` directory. From a9bcaee44ba2b2ec331a8616e50d1739d8ce0d07 Mon Sep 17 00:00:00 2001 From: Adam Bolte Date: Tue, 26 Nov 2024 20:32:35 +1100 Subject: [PATCH 08/22] Update GitHub Actions Workflow configuration --- .../.github/workflows/ci.yml | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/{{cookiecutter.package_name}}/.github/workflows/ci.yml b/{{cookiecutter.package_name}}/.github/workflows/ci.yml index 4ec428d..f9f3315 100644 --- a/{{cookiecutter.package_name}}/.github/workflows/ci.yml +++ b/{{cookiecutter.package_name}}/.github/workflows/ci.yml @@ -13,7 +13,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: ["3.7", "3.8", "3.9", "3.10", "3.11"] + python-version: ["3.11", "3.12", "3.13"] steps: - uses: actions/checkout@v3 @@ -23,15 +23,14 @@ jobs: python-version: ${{ matrix.python-version }} - name: Install dependencies run: | - python -m pip install --upgrade pip - pip install -r requirements.dev.txt - pip install -r requirements.txt + python -m pip install -U pip + python -m pip install .[dev] - name: Cache pip dependencies uses: actions/cache@v3 with: path: ~/.cache/pip # This path is specific to Ubuntu - # Check for a cache hit for the corresponding dev requirements file - key: ${{ runner.os }}-pip-${{ hashFiles('requirements.dev.txt') }}-${{ hashFiles('requirements.txt') }} + # Check for a cache hit for the corresponding pyproject.toml file + key: ${{ runner.os }}-pip-${{ hashFiles('pyproject.toml') }} restore-keys: | ${{ runner.os }}-pip- ${{ runner.os }}- From 9a540b90870dbb286b442225b306a684bded1db3 Mon Sep 17 00:00:00 2001 From: Adam Bolte Date: Tue, 26 Nov 2024 20:43:58 +1100 Subject: [PATCH 09/22] Limit Python support to 3.11+ --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8f84a9d..87886c2 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -12,7 +12,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: ["3.7", "3.8", "3.9", "3.10", "3.11"] + python-version: ["3.11", "3.12", "3.13"] steps: - uses: actions/checkout@v3 From 5f7d4ae416c73fc00a36a92a4e283fcdf1e720a8 Mon Sep 17 00:00:00 2001 From: Adam Bolte Date: Fri, 29 Nov 2024 12:38:10 +1100 Subject: [PATCH 10/22] Prevent a bug due to unlinking a missing file If we select GPL-3.0-or-later (for example), GPL-3.0-only would be processed first, and the license/GPL3 file would be added to the sources set for removal, because it was not excluded. Next, GPL-3.0-or-later would be processed and would avoid adding the license to sources going forward, but it would already be too late at that point. Here, we remove (or "discard") any existing matches in the sources set if present, when we find the license that matches what was requested. --- hooks/post_gen_project.py | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/hooks/post_gen_project.py b/hooks/post_gen_project.py index 76a5b2a..c28a194 100644 --- a/hooks/post_gen_project.py +++ b/hooks/post_gen_project.py @@ -18,16 +18,19 @@ def deploy_license() -> None: Licenses not selected for the project are removed. """ - sources = set() + sources: set[Path] = set() + selected_source = None with LICENSE_CONFIG.open(mode="r", encoding="utf-8") as config_file: config = json.load(config_file) for license_option, license_data in config.items(): + source_path = LICENSE_DIR.joinpath(license_data["source"]) if license_option == LICENSE_SELECTED: - LICENSE_DIR.joinpath(license_data["source"]).rename( - PROJECT_DIR.joinpath(license_data["destination"]) - ) - else: - sources.add(LICENSE_DIR.joinpath(license_data["source"])) + selected_source = source_path + destination_path = PROJECT_DIR.joinpath(license_data["destination"]) + source_path.rename(destination_path) + sources.discard(source_path) + elif license_data["source"] != selected_source: + sources.add(source_path) for source in sources: source.unlink() LICENSE_CONFIG.unlink() From 6023879511ab273002b7b522a734f953e93350ab Mon Sep 17 00:00:00 2001 From: Adam Bolte Date: Fri, 29 Nov 2024 12:50:14 +1100 Subject: [PATCH 11/22] Remove requirements.txt and requirements.dev.txt Package requirements are now configured in pyproject.toml. --- {{cookiecutter.package_name}}/requirements.dev.txt | 8 -------- {{cookiecutter.package_name}}/requirements.txt | 0 2 files changed, 8 deletions(-) delete mode 100644 {{cookiecutter.package_name}}/requirements.dev.txt delete mode 100644 {{cookiecutter.package_name}}/requirements.txt diff --git a/{{cookiecutter.package_name}}/requirements.dev.txt b/{{cookiecutter.package_name}}/requirements.dev.txt deleted file mode 100644 index 2a426ec..0000000 --- a/{{cookiecutter.package_name}}/requirements.dev.txt +++ /dev/null @@ -1,8 +0,0 @@ -black -coverage -isort -mypy -pylint -sphinx -twine -wheel diff --git a/{{cookiecutter.package_name}}/requirements.txt b/{{cookiecutter.package_name}}/requirements.txt deleted file mode 100644 index e69de29..0000000 From ba9c5aa7ef51fecc6252f41c11b7cb18988f6905 Mon Sep 17 00:00:00 2001 From: Adam Bolte Date: Fri, 29 Nov 2024 20:44:42 +1100 Subject: [PATCH 12/22] Fix pyproject.toml syntax errors --- {{cookiecutter.package_name}}/pyproject.toml | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/{{cookiecutter.package_name}}/pyproject.toml b/{{cookiecutter.package_name}}/pyproject.toml index c2565c2..14536c8 100644 --- a/{{cookiecutter.package_name}}/pyproject.toml +++ b/{{cookiecutter.package_name}}/pyproject.toml @@ -8,10 +8,7 @@ dynamic = ["version"] requires-python = ">= 3.11" dependencies = [] authors = [ - { - name = "{{cookiecutter.package_name}}", - email = "{{cookiecutter.email}}", - }, + {name = "{{cookiecutter.full_name}}", email = "{{cookiecutter.email}}"}, ] keywords=[ "{{cookiecutter.package_name}}" @@ -66,7 +63,7 @@ line_length = 79 [tool.mypy] disallow_untyped_calls = true disallow_untyped_defs = true -follow_imports = skip +follow_imports = "skip" no_implicit_optional = true show_column_numbers = true warn_no_return = true From 0cd97144f3f74a02fcd06fbd3dd4050b73c7c75a Mon Sep 17 00:00:00 2001 From: Adam Bolte Date: Fri, 29 Nov 2024 20:45:14 +1100 Subject: [PATCH 13/22] Improve pyproject.toml license handling From the Python Packaging User Guide of the `license` field documentation: > If you are using a standard, well-known license, it is not necessary > to use this field. Instead, you should use one of the classifiers > starting with License ::. --- {{cookiecutter.package_name}}/pyproject.toml | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/{{cookiecutter.package_name}}/pyproject.toml b/{{cookiecutter.package_name}}/pyproject.toml index 14536c8..9dd2998 100644 --- a/{{cookiecutter.package_name}}/pyproject.toml +++ b/{{cookiecutter.package_name}}/pyproject.toml @@ -15,10 +15,28 @@ keywords=[ ] description = "{{cookiecutter.package_short_description}}" readme = "README.rst" -license = "{{cookiecutter.license}}" classifiers = [ "Development Status :: 2 - Pre-Alpha", "Intended Audience :: Developers", +{%- if cookiecutter.license == "Not licensed for distribution (no license)" %} + "License :: Other/Proprietary License", +{%- elif cookiecutter.license == "AGPL-3.0-only" %} + "License :: OSI Approved :: GNU Affero General Public License v3", +{%- elif cookiecutter.license == "AGPL-3.0-or-later" %} + "License :: OSI Approved :: GNU Affero General Public License v3 or later (AGPLv3+)", +{%- elif cookiecutter.license == "Apache-2.0" %} + "License :: OSI Approved :: Apache Software License", +{%- elif cookiecutter.license == "BSD-3-Clause" %} + "License :: OSI Approved :: BSD License", +{%- elif cookiecutter.license == "GPL-2.0-only" %} + "License :: OSI Approved :: GNU General Public License v2 (GPLv2)", +{%- elif cookiecutter.license == "GPL-2.0-or-later" %} + "License :: OSI Approved :: GNU General Public License v2 or later (GPLv2+)", +{%- elif cookiecutter.license == "GPL-3.0-only" %} + "License :: OSI Approved :: GNU General Public License v3 (GPLv3)", +{%- elif cookiecutter.license == "GPL-3.0-or-later" %} + "License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)", +{%- endif %} "Operating System :: OS Independent", "Programming Language :: Python", "Programming Language :: Python :: 3", From c31ad165a99712f4550da0b6fd7facfff8867418 Mon Sep 17 00:00:00 2001 From: Adam Bolte Date: Fri, 29 Nov 2024 20:57:13 +1100 Subject: [PATCH 14/22] Update Makefile to use pyproject.toml and hatch --- {{cookiecutter.package_name}}/Makefile | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/{{cookiecutter.package_name}}/Makefile b/{{cookiecutter.package_name}}/Makefile index b8c95e9..0375cdd 100644 --- a/{{cookiecutter.package_name}}/Makefile +++ b/{{cookiecutter.package_name}}/Makefile @@ -22,9 +22,8 @@ help: # help: venv - create a dev virtual environment PIP_CMDS = \ source venv/bin/activate && \ - pip install pip --upgrade && \ - pip install -r requirements.dev.txt && \ - pip install -e . + pip install -U pip && \ + pip install -e .[dev] .PHONY: venv venv: @rm -Rf venv @@ -114,8 +113,7 @@ check-lint: @pylint --rcfile=.pylintrc \ {{cookiecutter.package_name}} \ examples \ - tests \ - setup.py + tests # help: check-static-analysis - check code style compliance @@ -149,7 +147,7 @@ serve-docs: # help: dist - create a wheel distribution package .PHONY: dist dist: - @python setup.py bdist_wheel + @hatch build # help: dist-test - test a wheel distribution package From 25f0a7db29f89b7d7df1739013bd5abab108594c Mon Sep 17 00:00:00 2001 From: Adam Bolte Date: Fri, 29 Nov 2024 20:59:25 +1100 Subject: [PATCH 15/22] Improve Makefile whitespace formatting --- {{cookiecutter.package_name}}/Makefile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/{{cookiecutter.package_name}}/Makefile b/{{cookiecutter.package_name}}/Makefile index 0375cdd..f7165df 100644 --- a/{{cookiecutter.package_name}}/Makefile +++ b/{{cookiecutter.package_name}}/Makefile @@ -4,12 +4,14 @@ MAKEFLAGS += --no-print-directory + # Do not remove this block. It is used by the 'help' rule when # constructing the help output. # help: # help: {{cookiecutter.package_display_name}} Makefile help # help: + # help: help - display makefile help information .PHONY: help help: @@ -33,7 +35,6 @@ venv: "\n\n\t$ source venv/bin/activate\n" - # help: clean - clean all files using .gitignore rules .PHONY: clean clean: From a19f1a9e66c839ca9a480963f75936db711f6ca1 Mon Sep 17 00:00:00 2001 From: Adam Bolte Date: Fri, 29 Nov 2024 21:01:13 +1100 Subject: [PATCH 16/22] Correct path of file containing package version --- {{cookiecutter.package_name}}/pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/{{cookiecutter.package_name}}/pyproject.toml b/{{cookiecutter.package_name}}/pyproject.toml index 9dd2998..52ec056 100644 --- a/{{cookiecutter.package_name}}/pyproject.toml +++ b/{{cookiecutter.package_name}}/pyproject.toml @@ -63,7 +63,7 @@ Documentation = "http://{{cookiecutter.package_name}}.readthedocs.io" "Source code" = "https://github.com/{{cookiecutter.github_user_name}}/{{cookiecutter.github_repo_name}}" [tool.hatch.version] -path = "src/{{cookiecutter.package_name}}/__about__.py" +path = "{{cookiecutter.package_name}}/__init__.py" [tool.black] line-length = 79 From 120abd7b20554730da99e1c2a8d77c5ebc311f66 Mon Sep 17 00:00:00 2001 From: Adam Bolte Date: Fri, 29 Nov 2024 21:03:00 +1100 Subject: [PATCH 17/22] Add hatch to dev optional dependencies This is used by the Makefile `dist` target. --- {{cookiecutter.package_name}}/pyproject.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/{{cookiecutter.package_name}}/pyproject.toml b/{{cookiecutter.package_name}}/pyproject.toml index 52ec056..0e8ae61 100644 --- a/{{cookiecutter.package_name}}/pyproject.toml +++ b/{{cookiecutter.package_name}}/pyproject.toml @@ -50,6 +50,7 @@ classifiers = [ dev = [ "black", "coverage", + "hatch", "isort", "mypy", "pylint", From 113c0eb6ee3e5b1e40838743c1930fd85342bee0 Mon Sep 17 00:00:00 2001 From: Adam Bolte Date: Fri, 29 Nov 2024 22:32:22 +1100 Subject: [PATCH 18/22] Check git is available before calling in Makefile --- {{cookiecutter.package_name}}/Makefile | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/{{cookiecutter.package_name}}/Makefile b/{{cookiecutter.package_name}}/Makefile index f7165df..3bd52f3 100644 --- a/{{cookiecutter.package_name}}/Makefile +++ b/{{cookiecutter.package_name}}/Makefile @@ -3,6 +3,13 @@ # python command links to the appropriate virtual environment Python. MAKEFLAGS += --no-print-directory +GIT := $(shell command -v git) + + +define CHECK_GIT +$(if $(GIT),,$(error "git command not available.")) +$(if $(wildcard .git),,$(error "Not a git repository.")) +endef # Do not remove this block. It is used by the 'help' rule when @@ -38,13 +45,15 @@ venv: # help: clean - clean all files using .gitignore rules .PHONY: clean clean: - @git clean -X -f -d + $(call CHECK_GIT) + @$(GIT) clean -X -f -d # help: scrub - clean all files, even untracked files .PHONY: scrub scrub: - git clean -x -f -d + $(call CHECK_GIT) + @$(GIT) clean -x -f -d # help: test - run tests From a8b6d38f318af6633e3441112595bf00a17ed6c3 Mon Sep 17 00:00:00 2001 From: Adam Bolte Date: Fri, 29 Nov 2024 22:32:42 +1100 Subject: [PATCH 19/22] Makefile indentation fix --- {{cookiecutter.package_name}}/Makefile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/{{cookiecutter.package_name}}/Makefile b/{{cookiecutter.package_name}}/Makefile index 3bd52f3..c44afa1 100644 --- a/{{cookiecutter.package_name}}/Makefile +++ b/{{cookiecutter.package_name}}/Makefile @@ -30,9 +30,9 @@ help: # help: venv - create a dev virtual environment PIP_CMDS = \ - source venv/bin/activate && \ - pip install -U pip && \ - pip install -e .[dev] + source venv/bin/activate && \ + pip install -U pip && \ + pip install -e .[dev] .PHONY: venv venv: @rm -Rf venv From c15d2502bd027d55600852d444be9ebb57853fe8 Mon Sep 17 00:00:00 2001 From: Adam Bolte Date: Fri, 29 Nov 2024 22:56:29 +1100 Subject: [PATCH 20/22] Update GitHub Actions root project cache key --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 87886c2..60ce268 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -29,7 +29,7 @@ jobs: with: path: ~/.cache/pip # This path is specific to Ubuntu # Check for a cache hit for the corresponding dev requirements file - key: ${{ runner.os }}-pip-${{ hashFiles('requirements.dev.txt') }}-${{ hashFiles('requirements.txt') }} + key: ${{ runner.os }}-pip-${{ hashFiles('requirements.txt') }} restore-keys: | ${{ runner.os }}-pip- ${{ runner.os }}- From dcf959a0241f4db3cbd2c84726fb7d25bdc968e3 Mon Sep 17 00:00:00 2001 From: Adam Bolte Date: Fri, 29 Nov 2024 22:57:00 +1100 Subject: [PATCH 21/22] Make GitHub Actions run `make venv` instead of pip --- .github/workflows/ci.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 60ce268..d9ebc42 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -39,8 +39,7 @@ jobs: - name: Check example project run: | cd example - pip install -r requirements.dev.txt - pip install . + make venv make help make style make check-style From c172299a3796bb404d9ff575d62669565b649061 Mon Sep 17 00:00:00 2001 From: Adam Bolte Date: Fri, 29 Nov 2024 23:00:36 +1100 Subject: [PATCH 22/22] Have GitHub Actions load the venv before checks --- .github/workflows/ci.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d9ebc42..77be1f2 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -40,6 +40,7 @@ jobs: run: | cd example make venv + . venv/bin/activate make help make style make check-style