Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions .github/python-project-template.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ default_context:
project_slug: "your-project"
full_name: "Your Name"
license: "MIT"
github_actions_ci: "Yes"
gitlab_ci: "No"
notebooks: "No"
commandlineinterface: "No"
github_actions_ci: true
gitlab_ci: false
notebooks: false
commandlineinterface: false
version_management: "manually"
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ If your Python package contains compiled C++ modules, you might want to check ou
In order to use Python Package Cookiecutter you need the following software installed:

* Python `>= 3.10`
* [Cookiecutter](https://github.com/cookiecutter/cookiecutter) e.g. by doing `pip install cookiecutter`.
* [Cookiecutter](https://github.com/cookiecutter/cookiecutter) `>=2.7` e.g. by doing `pip install cookiecutter`.
* Git `>= 1.8.2`

# Using the Python Package Cookiecutter
Expand Down
46 changes: 39 additions & 7 deletions cookiecutter.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,48 @@
"remote_url": "None",
"project_slug": "{%- if cookiecutter.remote_url == 'None' -%}{{ cookiecutter.project_name|replace('+', 'p')|slugify }}{% else %}{{ cookiecutter.remote_url.split('/')[-1]|replace('.git', '')}}{%- endif -%}",
"full_name": "Your Name",
"license": ["MIT", "BSD-2", "GPL-3.0", "LGPL-3.0", "None"],
"github_actions_ci": ["Yes", "No"],
"gitlab_ci": ["Yes", "No"],
"notebooks": ["Yes", "No"],
"commandlineinterface": ["No", "Yes"],
"version_management": ["manually", "setuptools_scm"],
"license": [
"MIT",
"BSD-2",
"GPL-3.0",
"LGPL-3.0",
"None"
],
"github_actions_ci": true,
"gitlab_ci": true,
"notebooks": true,
"commandlineinterface": false,
"version_management": [
"manually",
"setuptools_scm"
],
"_extensions": [
"local_extensions.PrecommitExtension",
"local_extensions.ShortcutExtension",
"local_extensions.CurrentDateExtension"
],
"__modname": "{{ cookiecutter|modname }}"
"__modname": "{{ cookiecutter|modname }}",
"__prompts__": {
"project_name": "Project name",
"remote_url": "Git remote URL (None to configure it later)",
"project_slug": "Project directory name",
"full_name": "Author full name",
"license": {
"__prompt__": "Project license",
"MIT": "MIT",
"BSD-2": "BSD 2-Clause",
"GPL-3.0": "GNU GPL v3",
"LGPL-3.0": "GNU LGPL v3",
"None": "Do not add a license"
},
"github_actions_ci": "Add GitHub Actions CI?",
"gitlab_ci": "Add GitLab CI?",
"notebooks": "Add an example Jupyter notebook?",
"commandlineinterface": "Add a command-line interface?",
"version_management": {
"__prompt__": "Package version management",
"manually": "Set the version manually",
"setuptools_scm": "Derive the version from Git tags with setuptools-scm"
}
}
}
14 changes: 7 additions & 7 deletions hooks/post_gen_project.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,14 +54,14 @@ def conditional_remove(condition, path):


conditional_remove("{{ cookiecutter.license }}" == "None", "LICENSE.md")
conditional_remove("{{ cookiecutter.github_actions_ci }}" == "No", ".github")
conditional_remove("{{ cookiecutter.github_actions_ci }}" == "No", "codecov.yml")
conditional_remove("{{ cookiecutter.gitlab_ci }}" == "No", ".gitlab-ci.yml")
conditional_remove(not {{ cookiecutter.github_actions_ci }}, ".github")
conditional_remove(not {{ cookiecutter.github_actions_ci }}, "codecov.yml")
conditional_remove(not {{ cookiecutter.gitlab_ci }}, ".gitlab-ci.yml")
conditional_remove(not {{ have_precommit }}, ".pre-commit-config.yaml")
conditional_remove("{{ cookiecutter.notebooks }}" == "No", "notebooks")
conditional_remove("{{ cookiecutter.notebooks }}" == "No", "doc/demo.nblink")
conditional_remove("{{ cookiecutter.commandlineinterface }}" == "No", "src/{{ cookiecutter|modname }}/__main__.py")
conditional_remove("{{ cookiecutter.commandlineinterface }}" == "No", "tests/test_cli.py")
conditional_remove(not {{ cookiecutter.notebooks }}, "notebooks")
conditional_remove(not {{ cookiecutter.notebooks }}, "doc/demo.nblink")
conditional_remove(not {{ cookiecutter.commandlineinterface }}, "src/{{ cookiecutter|modname }}/__main__.py")
conditional_remove(not {{ cookiecutter.commandlineinterface }}, "tests/test_cli.py")
conditional_remove(os.stat("TODO.md").st_size == 0, "TODO.md")

# Set up a Git repository
Expand Down
11 changes: 11 additions & 0 deletions hooks/pre_gen_project.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,17 @@
# user configuration value and exit with an error upon failure.

import sys
from importlib.metadata import version


# Cookiecutter 2.7 coerces command-line and configuration overrides to booleans.
# This check intentionally duplicates the one in pre_prompt.py: Cookiecutter
# versions older than 2.4 do not support pre-prompt hooks, so this remains as a
# fallback for them after prompting.
parts = tuple(int(part) for part in version("cookiecutter").split(".")[:3])
if parts < (2, 7, 0):
sys.stderr.write("This template requires cookiecutter >= 2.7\n")
sys.exit(1)


# Call fail_if with a Jinja template-based condition to abandon the
Expand Down
13 changes: 13 additions & 0 deletions hooks/pre_prompt.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# This script executes before cookiecutter prompts for template variables.
# Details about hooks can be found in the cookiecutter documentation:
# https://cookiecutter.readthedocs.io/en/latest/advanced/hooks.html

import sys
from importlib.metadata import version


# Cookiecutter 2.7 coerces command-line and configuration overrides to booleans.
parts = tuple(int(part) for part in version("cookiecutter").split(".")[:3])
if parts < (2, 7, 0):
sys.stderr.write("This template requires cookiecutter >= 2.7\n")
sys.exit(1)
2 changes: 1 addition & 1 deletion requirements-dev.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
cookiecutter>=2.1
cookiecutter>=2.7
flaky
pre-commit
PyGithub
Expand Down
4 changes: 2 additions & 2 deletions tests/test_bake_project.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ def test_with_remote(cookies):


@pytest.mark.local
@pytest.mark.parametrize("cli", ("Yes", "No"))
@pytest.mark.parametrize("notebooks", ("Yes", "No"))
@pytest.mark.parametrize("cli", (True, False))
@pytest.mark.parametrize("notebooks", (True, False))
@pytest.mark.parametrize("version_management", ("manually", "setuptools_scm"))
def test_pytest_run(cookies, virtualenv, cli, notebooks, version_management):
# Bake the project
Expand Down
2 changes: 1 addition & 1 deletion {{cookiecutter.project_slug}}/.github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ jobs:

- name: Run Python tests
run: |
python -m pytest{% if cookiecutter.notebooks == "Yes" %} --nbval{% endif %}
python -m pytest{% if cookiecutter.notebooks %} --nbval{% endif %}

coverage:
name: Coverage Testing
Expand Down
3 changes: 1 addition & 2 deletions {{cookiecutter.project_slug}}/.gitlab-ci.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
.template: &template
script:
- python -m pip install .[tests]
- python -m pytest{% if cookiecutter.notebooks == "Yes" %} --nbval{% endif %}
- python -m pytest{% if cookiecutter.notebooks %} --nbval{% endif %}

test-{{ cookiecutter|modname }}-python3.10:
image: python:3.10
Expand All @@ -10,4 +10,3 @@ test-{{ cookiecutter|modname }}-python3.10:
test-{{ cookiecutter|modname }}-python3.13:
image: python:3.13
<<: *template

4 changes: 2 additions & 2 deletions {{cookiecutter.project_slug}}/.pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ repos:
- id: check-toml
# Unify file endings
- id: end-of-file-fixer
{%- if cookiecutter.notebooks == "Yes" %}
{%- if cookiecutter.notebooks %}

# Make sure that Jupyter notebooks under version control
# have their outputs stripped before committing
Expand All @@ -32,7 +32,7 @@ repos:
- id: nbstripout
files: ".ipynb"
{%- endif %}
{%- if cookiecutter.github_actions_ci == "Yes" %}
{%- if cookiecutter.github_actions_ci %}

# GitHub Actions Workflow linter
- repo: https://github.com/rhysd/actionlint
Expand Down
4 changes: 2 additions & 2 deletions {{cookiecutter.project_slug}}/FILESTRUCTURE.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,15 @@ This is an explanation of the file structure that the cookiecutter generated for

* Python source files:
* The Python package source files are located in the `src/{{ cookiecutter|modname }}` directory.
{%- if cookiecutter.commandlineinterface == "Yes" %}
{%- if cookiecutter.commandlineinterface %}
* The file `src/{{ cookiecutter|modname }}.__main__.py` defines a command line interface that
is accessible both as the command `{{ cookiecutter|modname }}` and via
`python -m {{ cookiecutter|modname }}`.
* `tests/test_cli.py` contains rudimentary testing of this CLI.
{%- endif %}
* `tests/test_{{ cookiecutter|modname }}.py` contains the unit tests for the package.
* `tests/conftest.py` contains testing setup and configuration for `pytest`
{%- if cookiecutter.notebooks == "Yes" %}
{%- if cookiecutter.notebooks %}
* The `notebooks` directory contains an example Jupyter notebook on how to use `{{ cookiecutter|modname }}`.
This notebook is always executed during `pytest` execution and it is automatically
rendered into the Sphinx documentation.
Expand Down
4 changes: 2 additions & 2 deletions {{cookiecutter.project_slug}}/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,10 @@
[![License: LGPL v3](https://img.shields.io/badge/License-LGPL%20v3-blue.svg)](https://www.gnu.org/licenses/lgpl-3.0)
{% endif -%}
{% if cookiecutter.remote_url != "None" -%}
{% if cookiecutter.github_actions_ci == "Yes" and cookiecutter|is_github -%}
{% if cookiecutter.github_actions_ci and cookiecutter|is_github -%}
[![GitHub Workflow Status](https://img.shields.io/github/actions/workflow/status/{{ cookiecutter|username }}/{{ cookiecutter|remote_slug }}/ci.yml?branch=main)](https://github.com/{{ cookiecutter|username }}/{{ cookiecutter|remote_slug }}/actions/workflows/ci.yml)
{% endif -%}
{% if cookiecutter.gitlab_ci == "Yes" and cookiecutter|is_gitlab -%}
{% if cookiecutter.gitlab_ci and cookiecutter|is_gitlab -%}
[![Gitlab pipeline status](https://img.shields.io/gitlab/pipeline/{{ cookiecutter|username }}/{{ cookiecutter|remote_slug }}/main
{%- if "gitlab.com" not in cookiecutter.remote_url -%}
?gitlab_url={{ cookiecutter|gitlab_instance }}
Expand Down
2 changes: 1 addition & 1 deletion {{cookiecutter.project_slug}}/TODO.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ The following tasks need to be done to get a fully working project:
* Enable the integration of Readthedocs with your Git hoster. In the case of Github, this means
that you need to login at [Read the Docs](https://readthedocs.org) and click the button
*Import a Project*.
{%- if cookiecutter.github_actions_ci == 'Yes' %}
{%- if cookiecutter.github_actions_ci %}
* Enable the integration with `codecov.io` by heading to the [Codecov.io Website](https://codecov.io),
log in (e.g. with your Github credentials) and enable integration for your repository. In order to do
so, you need to select it from the list of repositories (potentially re-syncing with GitHub). Then, head
Expand Down
2 changes: 1 addition & 1 deletion {{cookiecutter.project_slug}}/doc/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.
extensions = [
{%- if cookiecutter.notebooks == "Yes" %}
{%- if cookiecutter.notebooks %}
"nbsphinx",
"nbsphinx_link",
{%- endif %}
Expand Down
2 changes: 1 addition & 1 deletion {{cookiecutter.project_slug}}/doc/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
:caption: Contents:

intro
{%- if cookiecutter.notebooks == "Yes" %}
{%- if cookiecutter.notebooks %}
demo
{%- endif %}
api
Expand Down
10 changes: 5 additions & 5 deletions {{cookiecutter.project_slug}}/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ classifiers = [
"Operating System :: OS Independent",
]
dependencies = [
{%- if cookiecutter.commandlineinterface == "Yes" %}
{%- if cookiecutter.commandlineinterface %}
"click",
{%- endif %}
]
Expand All @@ -52,12 +52,12 @@ dependencies = [
tests = [
"pytest",
"pytest-cov",
{%- if cookiecutter.notebooks == "Yes" %}
{%- if cookiecutter.notebooks %}
"nbval",
{%- endif %}
]
docs = [
{%- if cookiecutter.notebooks == "Yes" %}
{%- if cookiecutter.notebooks %}
"ipykernel",
"nbsphinx",
"nbsphinx-link",
Expand All @@ -66,7 +66,7 @@ docs = [
"sphinx_mdinclude",
"sphinx_rtd_theme",
]
{% if cookiecutter.commandlineinterface == "Yes" %}
{% if cookiecutter.commandlineinterface %}
# Command line scripts installed as part of the installation
[project.scripts]
{{ cookiecutter|modname }} = "{{ cookiecutter|modname }}.__main__:main"
Expand All @@ -92,7 +92,7 @@ write_to = "src/{{ cookiecutter|modname }}/_version.py"
[tool.pytest.ini_options]
testpaths = [
"tests",
{%- if cookiecutter.notebooks == "Yes" %}
{%- if cookiecutter.notebooks %}
"notebooks",
{%- endif %}
]
Loading