opentemplate 0.0.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ LICENSES/Apache-2.0.txt
@@ -0,0 +1,208 @@
1
+ Metadata-Version: 2.4
2
+ Name: opentemplate
3
+ Version: 0.0.1
4
+ Summary: The simplest to use, yet the most comprehensive Python template
5
+ Author: open-nudge
6
+ Maintainer: open-nudge
7
+ License-Expression: Apache-2.0
8
+ Classifier: Development Status :: 2 - Pre-Alpha
9
+ Classifier: Intended Audience :: Developers
10
+ Classifier: Programming Language :: Python
11
+ Classifier: Programming Language :: Python :: 3 :: Only
12
+ Classifier: Programming Language :: Python :: 3.11
13
+ Classifier: Programming Language :: Python :: 3.12
14
+ Classifier: Programming Language :: Python :: 3.13
15
+ Classifier: Topic :: Software Development :: Libraries
16
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
17
+ Classifier: Typing :: Typed
18
+ Project-URL: Changelog, https://github.com/open-nudge/opentemplate/blob/master/CHANGELOG.md
19
+ Project-URL: Documentation, https://open-nudge.github.io/opentemplate
20
+ Project-URL: Homepage, https://open-nudge.github.io/opentemplate
21
+ Project-URL: Issues, https://github.com/open-nudge/opentemplate/issues
22
+ Project-URL: Repository, https://github.com/open-nudge/opentemplate
23
+ Requires-Python: >=3.11
24
+ Description-Content-Type: text/markdown
25
+
26
+ <!--
27
+ SPDX-FileCopyrightText: © 2025 open-nudge <https://github.com/open-nudge>
28
+ SPDX-FileContributor: szymonmaszke <github@maszke.co>
29
+
30
+ SPDX-License-Identifier: Apache-2.0
31
+ -->
32
+
33
+ # opentemplate
34
+
35
+ <!-- mkdocs remove start -->
36
+
37
+ <!-- vale off -->
38
+
39
+ <!-- pyml disable-num-lines 30 line-length-->
40
+
41
+ <p align="center">
42
+ <em>The simplest to use, yet the most comprehensive Python template</em>
43
+ </p>
44
+
45
+ <div align="center">
46
+
47
+ <a href="https://pypi.org/project/opentemplate">![PyPI - Python Version](https://img.shields.io/pypi/v/opentemplate?style=for-the-badge&label=release&labelColor=grey&color=blue)
48
+ </a>
49
+ <a href="https://pypi.org/project/opentemplate">![Python Version from PEP 621 TOML](https://img.shields.io/python/required-version-toml?tomlFilePath=https%3A%2F%2Fraw.githubusercontent.com%2Fopen-nudge%2Fopentemplate%2Fmain%2Fpyproject.toml&style=for-the-badge&label=python&labelColor=grey&color=blue)
50
+ </a>
51
+ <a href="https://opensource.org/licenses/Apache-2.0">![License](https://img.shields.io/badge/License-Apache_2.0-blue?style=for-the-badge)
52
+ </a>
53
+ <a>![Coverage Hardcoded](https://img.shields.io/badge/coverage-100%25-green?style=for-the-badge)
54
+ </a>
55
+ <a href="https://scorecard.dev/viewer/?uri=github.com/open-nudge/opentemplate">![OSSF-Scorecard Score](https://img.shields.io/ossf-scorecard/github.com/open-nudge/opentemplate?style=for-the-badge&label=OSSF)
56
+ </a>
57
+
58
+ </div>
59
+
60
+ <p align="center">
61
+ ✨ <a href="#features">Features</a>
62
+ 🚀 <a href="#quick-start">Quick start</a>
63
+ 📚 <a href="https://open-nudge.github.io/opentemplate">Documentation</a>
64
+ 🤝 <a href="#contribute">Contribute</a>
65
+ 👍 <a href="https://github.com/open-nudge/opentemplate/blob/main/ADOPTERS.md">Adopters</a>
66
+ 📜 <a href="#legal">Legal</a>
67
+ </p>
68
+ <!-- vale on -->
69
+
70
+ ______________________________________________________________________
71
+
72
+ <!-- mkdocs remove end -->
73
+
74
+ ## Features
75
+
76
+ __opentemplate__ is a Python template with the following features:
77
+
78
+ - [__Truly open source__](https://open-nudge.github.io/opentemplate/template/about/philosophy):
79
+ no tokens, no fees, no premium plans, open source software only
80
+ - [__Ease of use__](https://open-nudge.github.io/opentemplate/template/quickstart/usage):
81
+ clone templated repo, run `pdm setup` and __focus on your code__
82
+ - [__Consistency__](https://open-nudge.github.io/opentemplate/template/configuration/basic):
83
+ `pre-commit` and `GitHub Actions` share the same config (`pyproject.toml`)
84
+ - [__Security__](https://open-nudge.github.io/opentemplate/template/details/security):
85
+ [SLSA](https://slsa.dev/) L3+ (public/enterprise) or L2 (private),
86
+ [OSSF Best Practices](https://github.com/ossf/scorecard)
87
+ - [__Batteries included__](https://open-nudge.github.io/opentemplate/template/details):
88
+ multiple checkers for Python, YAML, Markdown, prose, etc.
89
+ - [__Performance__](https://open-nudge.github.io/opentemplate/template/details/github-actions):
90
+ Parallel checks, builds, minimally-sized caches and checkouts
91
+
92
+ ## Quick start
93
+
94
+ ### Installation
95
+
96
+ > [!NOTE]
97
+ > [Install `pdm`](https://pdm-project.org/en/latest/#recommended-installation-method)
98
+ > (if you don't have it already), for Linux/MacOS:
99
+
100
+ ```sh
101
+ curl -sSL https://pdm-project.org/install-pdm.py | python3 -
102
+ ```
103
+
104
+ 1. Create a new GitHub repository using this template
105
+ (green `Use this template` button)
106
+ 1. Name your repo (__use underscore `_`, not hyphens `-`__)
107
+ 1. Add project description (__necessary!__)
108
+ 1. __Wait until the setup commit appears__
109
+ (performed by `github-actions[bot]`, it may take a few minutes)
110
+ 1. Clone the repository
111
+ 1. Run `pdm setup` command locally to setup development environment
112
+
113
+ > [!IMPORTANT]
114
+ > For more details read the
115
+ > [documentation](https://open-nudge.github.io/opentemplate/template/quickstart/installation)
116
+
117
+ ### Usage
118
+
119
+ 1. Create a new branch
120
+ 1. Optionally add dependencies to `pyproject.toml`
121
+ 1. Write code in `/src/<project_name>` and tests in `/tests`
122
+ 1. Use `git add`, `git commit` and `git push` your changes
123
+ 1. `pre-commit` will guide you through the process
124
+
125
+ > [!IMPORTANT]
126
+ > For more details read the
127
+ > [documentation](https://open-nudge.github.io/opentemplate/template/quickstart/usage)
128
+
129
+ ### Examples
130
+
131
+ <details>
132
+ <summary><b><big>Run checkers or fixers manually</big></b> (click me)</summary>
133
+ &nbsp;
134
+
135
+ ```sh
136
+ > pdm check-<group> # pdm fix-<group>
137
+ ```
138
+
139
+ Note that all `check` and `fix` commands are grouped for your convenience:
140
+
141
+ ```sh
142
+ > pdm check-all # pdm fix-all
143
+ ```
144
+
145
+ </details>
146
+
147
+ <details>
148
+ <summary><b><big>Adjust template</big></b> (click me)</summary>
149
+ &nbsp;
150
+
151
+ > Most of the adjustments can be done by __only__ editing `pyproject.toml`
152
+
153
+ Common changes to `pyproject.toml`:
154
+
155
+ - Add dev dependencies under `[dependency-groups]`
156
+ (everything is named `dev-<group>`)
157
+ - Modify `[tool.pdm.scripts]` for custom command
158
+ (`check-<group>` or `fix-<group>`, the latter modifies files)
159
+ - Use `[tool.<name>]` to adjust specific tool configuration
160
+
161
+ > __Adjusting these sections will affect `pre-commit` and `GitHub Actions`__
162
+
163
+ </details>
164
+
165
+ <details>
166
+ <summary><b><big>Disable some pre-commit check</big></b> (click me)</summary>
167
+ &nbsp;
168
+
169
+ > Disabling checks should be done cautiously!
170
+
171
+ `pre-commit` checks are defined in `.pre-commit-config.yaml`.
172
+
173
+ Disable a check using `SKIP` environment variable:
174
+
175
+ ```sh
176
+ SKIP='<group1>,<group2>` git commit -m <message>
177
+ ```
178
+
179
+ For details, refer to the `id` fields in `.pre-commit-config.yaml`.
180
+
181
+ > Some commands have both `<group>-fix` and `<group>-check`
182
+ > for different actions!
183
+
184
+ </details>
185
+
186
+ <!-- mkdocs remove start -->
187
+
188
+ ## Contribute
189
+
190
+ We welcome your contributions! Start here:
191
+
192
+ - [Code of Conduct](/CODE_OF_CONDUCT.md)
193
+ - [Contributing Guide](/CONTRIBUTING.md)
194
+ - [Roadmap](/ROADMAP.md)
195
+ - [Changelog](/CHANGELOG.md)
196
+ - [Report security vulnerabilities](/SECURITY.md)
197
+ - [Open an Issue](https://github.com/open-nudge/opentemplate/issues)
198
+
199
+ ## Legal
200
+
201
+ - This project is licensed under the _Apache 2.0 License_ - see
202
+ the [LICENSE](/LICENSE.md) file for details.
203
+ - This project is copyrighted by _open-nudge_ - the
204
+ appropriate copyright notice is included in each file.
205
+
206
+ <!-- mkdocs remove end -->
207
+
208
+ <!-- md-dead-link-check: on -->
@@ -0,0 +1,183 @@
1
+ <!--
2
+ SPDX-FileCopyrightText: © 2025 open-nudge <https://github.com/open-nudge>
3
+ SPDX-FileContributor: szymonmaszke <github@maszke.co>
4
+
5
+ SPDX-License-Identifier: Apache-2.0
6
+ -->
7
+
8
+ # opentemplate
9
+
10
+ <!-- mkdocs remove start -->
11
+
12
+ <!-- vale off -->
13
+
14
+ <!-- pyml disable-num-lines 30 line-length-->
15
+
16
+ <p align="center">
17
+ <em>The simplest to use, yet the most comprehensive Python template</em>
18
+ </p>
19
+
20
+ <div align="center">
21
+
22
+ <a href="https://pypi.org/project/opentemplate">![PyPI - Python Version](https://img.shields.io/pypi/v/opentemplate?style=for-the-badge&label=release&labelColor=grey&color=blue)
23
+ </a>
24
+ <a href="https://pypi.org/project/opentemplate">![Python Version from PEP 621 TOML](https://img.shields.io/python/required-version-toml?tomlFilePath=https%3A%2F%2Fraw.githubusercontent.com%2Fopen-nudge%2Fopentemplate%2Fmain%2Fpyproject.toml&style=for-the-badge&label=python&labelColor=grey&color=blue)
25
+ </a>
26
+ <a href="https://opensource.org/licenses/Apache-2.0">![License](https://img.shields.io/badge/License-Apache_2.0-blue?style=for-the-badge)
27
+ </a>
28
+ <a>![Coverage Hardcoded](https://img.shields.io/badge/coverage-100%25-green?style=for-the-badge)
29
+ </a>
30
+ <a href="https://scorecard.dev/viewer/?uri=github.com/open-nudge/opentemplate">![OSSF-Scorecard Score](https://img.shields.io/ossf-scorecard/github.com/open-nudge/opentemplate?style=for-the-badge&label=OSSF)
31
+ </a>
32
+
33
+ </div>
34
+
35
+ <p align="center">
36
+ ✨ <a href="#features">Features</a>
37
+ 🚀 <a href="#quick-start">Quick start</a>
38
+ 📚 <a href="https://open-nudge.github.io/opentemplate">Documentation</a>
39
+ 🤝 <a href="#contribute">Contribute</a>
40
+ 👍 <a href="https://github.com/open-nudge/opentemplate/blob/main/ADOPTERS.md">Adopters</a>
41
+ 📜 <a href="#legal">Legal</a>
42
+ </p>
43
+ <!-- vale on -->
44
+
45
+ ______________________________________________________________________
46
+
47
+ <!-- mkdocs remove end -->
48
+
49
+ ## Features
50
+
51
+ __opentemplate__ is a Python template with the following features:
52
+
53
+ - [__Truly open source__](https://open-nudge.github.io/opentemplate/template/about/philosophy):
54
+ no tokens, no fees, no premium plans, open source software only
55
+ - [__Ease of use__](https://open-nudge.github.io/opentemplate/template/quickstart/usage):
56
+ clone templated repo, run `pdm setup` and __focus on your code__
57
+ - [__Consistency__](https://open-nudge.github.io/opentemplate/template/configuration/basic):
58
+ `pre-commit` and `GitHub Actions` share the same config (`pyproject.toml`)
59
+ - [__Security__](https://open-nudge.github.io/opentemplate/template/details/security):
60
+ [SLSA](https://slsa.dev/) L3+ (public/enterprise) or L2 (private),
61
+ [OSSF Best Practices](https://github.com/ossf/scorecard)
62
+ - [__Batteries included__](https://open-nudge.github.io/opentemplate/template/details):
63
+ multiple checkers for Python, YAML, Markdown, prose, etc.
64
+ - [__Performance__](https://open-nudge.github.io/opentemplate/template/details/github-actions):
65
+ Parallel checks, builds, minimally-sized caches and checkouts
66
+
67
+ ## Quick start
68
+
69
+ ### Installation
70
+
71
+ > [!NOTE]
72
+ > [Install `pdm`](https://pdm-project.org/en/latest/#recommended-installation-method)
73
+ > (if you don't have it already), for Linux/MacOS:
74
+
75
+ ```sh
76
+ curl -sSL https://pdm-project.org/install-pdm.py | python3 -
77
+ ```
78
+
79
+ 1. Create a new GitHub repository using this template
80
+ (green `Use this template` button)
81
+ 1. Name your repo (__use underscore `_`, not hyphens `-`__)
82
+ 1. Add project description (__necessary!__)
83
+ 1. __Wait until the setup commit appears__
84
+ (performed by `github-actions[bot]`, it may take a few minutes)
85
+ 1. Clone the repository
86
+ 1. Run `pdm setup` command locally to setup development environment
87
+
88
+ > [!IMPORTANT]
89
+ > For more details read the
90
+ > [documentation](https://open-nudge.github.io/opentemplate/template/quickstart/installation)
91
+
92
+ ### Usage
93
+
94
+ 1. Create a new branch
95
+ 1. Optionally add dependencies to `pyproject.toml`
96
+ 1. Write code in `/src/<project_name>` and tests in `/tests`
97
+ 1. Use `git add`, `git commit` and `git push` your changes
98
+ 1. `pre-commit` will guide you through the process
99
+
100
+ > [!IMPORTANT]
101
+ > For more details read the
102
+ > [documentation](https://open-nudge.github.io/opentemplate/template/quickstart/usage)
103
+
104
+ ### Examples
105
+
106
+ <details>
107
+ <summary><b><big>Run checkers or fixers manually</big></b> (click me)</summary>
108
+ &nbsp;
109
+
110
+ ```sh
111
+ > pdm check-<group> # pdm fix-<group>
112
+ ```
113
+
114
+ Note that all `check` and `fix` commands are grouped for your convenience:
115
+
116
+ ```sh
117
+ > pdm check-all # pdm fix-all
118
+ ```
119
+
120
+ </details>
121
+
122
+ <details>
123
+ <summary><b><big>Adjust template</big></b> (click me)</summary>
124
+ &nbsp;
125
+
126
+ > Most of the adjustments can be done by __only__ editing `pyproject.toml`
127
+
128
+ Common changes to `pyproject.toml`:
129
+
130
+ - Add dev dependencies under `[dependency-groups]`
131
+ (everything is named `dev-<group>`)
132
+ - Modify `[tool.pdm.scripts]` for custom command
133
+ (`check-<group>` or `fix-<group>`, the latter modifies files)
134
+ - Use `[tool.<name>]` to adjust specific tool configuration
135
+
136
+ > __Adjusting these sections will affect `pre-commit` and `GitHub Actions`__
137
+
138
+ </details>
139
+
140
+ <details>
141
+ <summary><b><big>Disable some pre-commit check</big></b> (click me)</summary>
142
+ &nbsp;
143
+
144
+ > Disabling checks should be done cautiously!
145
+
146
+ `pre-commit` checks are defined in `.pre-commit-config.yaml`.
147
+
148
+ Disable a check using `SKIP` environment variable:
149
+
150
+ ```sh
151
+ SKIP='<group1>,<group2>` git commit -m <message>
152
+ ```
153
+
154
+ For details, refer to the `id` fields in `.pre-commit-config.yaml`.
155
+
156
+ > Some commands have both `<group>-fix` and `<group>-check`
157
+ > for different actions!
158
+
159
+ </details>
160
+
161
+ <!-- mkdocs remove start -->
162
+
163
+ ## Contribute
164
+
165
+ We welcome your contributions! Start here:
166
+
167
+ - [Code of Conduct](/CODE_OF_CONDUCT.md)
168
+ - [Contributing Guide](/CONTRIBUTING.md)
169
+ - [Roadmap](/ROADMAP.md)
170
+ - [Changelog](/CHANGELOG.md)
171
+ - [Report security vulnerabilities](/SECURITY.md)
172
+ - [Open an Issue](https://github.com/open-nudge/opentemplate/issues)
173
+
174
+ ## Legal
175
+
176
+ - This project is licensed under the _Apache 2.0 License_ - see
177
+ the [LICENSE](/LICENSE.md) file for details.
178
+ - This project is copyrighted by _open-nudge_ - the
179
+ appropriate copyright notice is included in each file.
180
+
181
+ <!-- mkdocs remove end -->
182
+
183
+ <!-- md-dead-link-check: on -->
@@ -0,0 +1,746 @@
1
+ [build-system]
2
+ build-backend = "pdm.backend"
3
+ requires = [
4
+ "commition[pdm]>=0.0.1",
5
+ "pdm-backend>=2",
6
+ ]
7
+
8
+ [project]
9
+ name = "opentemplate"
10
+ description = "The simplest to use, yet the most comprehensive Python template"
11
+ readme = "README.md"
12
+ license = "Apache-2.0"
13
+ maintainers = [
14
+ { name = "open-nudge" },
15
+ ]
16
+ authors = [
17
+ { name = "open-nudge" },
18
+ ]
19
+ requires-python = ">=3.11"
20
+ classifiers = [
21
+ "Development Status :: 2 - Pre-Alpha",
22
+ "Intended Audience :: Developers",
23
+ "Programming Language :: Python",
24
+ "Programming Language :: Python :: 3 :: Only",
25
+ "Programming Language :: Python :: 3.11",
26
+ "Programming Language :: Python :: 3.12",
27
+ "Programming Language :: Python :: 3.13",
28
+ "Topic :: Software Development :: Libraries",
29
+ "Topic :: Software Development :: Libraries :: Python Modules",
30
+ "Typing :: Typed",
31
+ ]
32
+ dynamic = []
33
+ dependencies = []
34
+ version = "0.0.1"
35
+
36
+ [project.urls]
37
+ Changelog = "https://github.com/open-nudge/opentemplate/blob/master/CHANGELOG.md"
38
+ Documentation = "https://open-nudge.github.io/opentemplate"
39
+ Homepage = "https://open-nudge.github.io/opentemplate"
40
+ Issues = "https://github.com/open-nudge/opentemplate/issues"
41
+ Repository = "https://github.com/open-nudge/opentemplate"
42
+
43
+ [dependency-groups]
44
+ dev-tests = [
45
+ "coverage>=7",
46
+ "hypothesis>=6",
47
+ "pytest>=8",
48
+ "pytest-asyncio>=1",
49
+ "pytest-html>=4",
50
+ "pytest-pretty-terminal>=1",
51
+ "pytest-randomly>=3",
52
+ ]
53
+ dev-docs = [
54
+ "cairosvg>=2",
55
+ "markdown>=3",
56
+ "mike>=2",
57
+ "mkdocs-awesome-nav>=3",
58
+ "mkdocs-gen-files>=0.5.0",
59
+ "mkdocs-git-revision-date-localized-plugin>=1",
60
+ "mkdocs-github-admonitions-plugin>=0.0.3",
61
+ "mkdocs-jupyter>=0.25.1",
62
+ "mkdocs-link-marker>=0.1.3",
63
+ "mkdocs-literate-nav>=0.6.0",
64
+ "mkdocs-material>=9",
65
+ "mkdocs-minify-plugin>=0.8.0",
66
+ "mkdocs-open-in-new-tab>=1",
67
+ "mkdocs-redirects>=1",
68
+ "mkdocs-section-index>=0.3.4",
69
+ "mkdocstrings>=0.25.0",
70
+ "mkdocstrings-python>=1",
71
+ "pillow>=10",
72
+ "pygments>=2",
73
+ "pymdown-extensions>=10",
74
+ "termynal>=0.12.1",
75
+ ]
76
+ dev-python = [
77
+ "fawltydeps>=0.17.0",
78
+ "interrogate>=1",
79
+ "ruff>=0.5.6",
80
+ ]
81
+ dev-typing = [
82
+ "basedpyright>=1.28.1",
83
+ ]
84
+ dev-shell = [
85
+ "shellcheck-py>=0.10.0",
86
+ ]
87
+ dev-yaml = [
88
+ "yamllint>=1",
89
+ ]
90
+ dev-markdown = [
91
+ "md-dead-link-check>=1.2.0",
92
+ "mdformat>=0.7.19",
93
+ "mdformat_frontmatter>=2",
94
+ "mdformat_footnote>=0.1.1",
95
+ "mdformat-gfm>=0.3.7",
96
+ "mdformat_gfm_alerts>=1",
97
+ "mdformat-mkdocs>=4",
98
+ "pymarkdownlnt>=0.9.21",
99
+ ]
100
+ dev-ini = [
101
+ "pyinilint>=0.17",
102
+ ]
103
+ dev-pyproject = [
104
+ "validate-pyproject>=0.18",
105
+ ]
106
+ dev-code = [
107
+ "editorconfig-checker>=3",
108
+ "codespell>=2",
109
+ ]
110
+ dev-citation = [
111
+ "cffconvert @ git+https://github.com/citation-file-format/cffconvert@b6045d78aac9e02b039703b030588d54d53262ac",
112
+ ]
113
+ dev-security = [
114
+ "semgrep>=1; platform_system!='Windows' and python_version=='3.11'",
115
+ ]
116
+ dev-github = [
117
+ "zizmor>=1",
118
+ "check-jsonschema>=0.31.2",
119
+ ]
120
+ dev-legal = [
121
+ "reuse>=4",
122
+ ]
123
+ dev-release = [
124
+ "spdx-tools>=0.8.3",
125
+ "cyclonedx-bom>=4",
126
+ "git-cliff>=2",
127
+ "reuse>=4",
128
+ ]
129
+ dev-generation = [
130
+ "cogapp>=3",
131
+ "cogeol>=0.0.1",
132
+ ]
133
+ dev-commit = [
134
+ "conventional-pre-commit>=4",
135
+ ]
136
+ dev-pre-commit = [
137
+ "pre-commit>=3",
138
+ ]
139
+ dev-all = [
140
+ { include-group = "dev-tests" },
141
+ { include-group = "dev-docs" },
142
+ { include-group = "dev-python" },
143
+ { include-group = "dev-typing" },
144
+ { include-group = "dev-shell" },
145
+ { include-group = "dev-yaml" },
146
+ { include-group = "dev-markdown" },
147
+ { include-group = "dev-ini" },
148
+ { include-group = "dev-pyproject" },
149
+ { include-group = "dev-code" },
150
+ { include-group = "dev-citation" },
151
+ { include-group = "dev-security" },
152
+ { include-group = "dev-github" },
153
+ { include-group = "dev-legal" },
154
+ { include-group = "dev-release" },
155
+ { include-group = "dev-generation" },
156
+ { include-group = "dev-commit" },
157
+ { include-group = "dev-pre-commit" },
158
+ ]
159
+
160
+ [tool.pdm]
161
+ distribution = true
162
+
163
+ [tool.pdm.version]
164
+ source = "call"
165
+ getter = "commition.plugin.pdm:git"
166
+
167
+ [tool.pdm.scripts]
168
+ check-typing = "basedpyright --stats"
169
+ check-shell = "shellcheck -x -S style -o all"
170
+ check-ini = "pyinilint"
171
+ check-citation = "cffconvert --validate -i {args:CITATION.cff}"
172
+ check-docs = "mkdocs build"
173
+ check-pre-commit-config = "pre-commit validate-config {args:.pre-commit-config.yaml}"
174
+ check-pre-commit-hooks = "pre-commit validate-manifest {args:.pre-commit-hooks.yaml}"
175
+ check-github = "zizmor --persona auditor --verbose {args:.}"
176
+ check-legal = "reuse lint"
177
+ lock = "pdm lock -G:all"
178
+ pre-commit-all = "pre-commit run {args:''} --all-files"
179
+ check-commit = "conventional-pre-commit --strict --scopes '' feat fix feat! fix!"
180
+
181
+ [tool.pdm.scripts.tests]
182
+ composite = [
183
+ "pdm run coverage run -m pytest -x --pretty {args:tests}",
184
+ "pdm run coverage report",
185
+ ]
186
+
187
+ [tool.pdm.scripts.tests-all]
188
+ composite = [
189
+ "setup-environment",
190
+ "pdm install --prod -G:all --no-editable",
191
+ "pdm install -G dev-tests --no-editable",
192
+ "pdm use 3.13",
193
+ "pdm run tests {args:tests}",
194
+ "pdm use 3.12",
195
+ "pdm run tests {args:tests}",
196
+ "pdm use 3.11",
197
+ "pdm run tests {args:tests}",
198
+ ]
199
+
200
+ [tool.pdm.scripts.check-python]
201
+ composite = [
202
+ "fawltydeps --detailed --code {args:.}",
203
+ "ruff format --check {args:.}",
204
+ "ruff check {args:.}",
205
+ "interrogate {args:.}",
206
+ ]
207
+
208
+ [tool.pdm.scripts.fix-python]
209
+ composite = [
210
+ "fawltydeps --detailed --code {args:.}",
211
+ "ruff format {args:.}",
212
+ "ruff check --fix {args:.}",
213
+ "interrogate {args:.}",
214
+ ]
215
+
216
+ [tool.pdm.scripts.fix-shell]
217
+ shell = "pdm run shellcheck -x -S style -o all {args} | git apply --allow-empty"
218
+
219
+ [tool.pdm.scripts.check-yaml]
220
+ composite = [
221
+ "yamllint {args:.}",
222
+ ]
223
+
224
+ [tool.pdm.scripts.check-markdown]
225
+ composite = [
226
+ "mdformat --check {args:.}",
227
+ "pymarkdownlnt scan -r {args:.}",
228
+ "md-dead-link-check {args:.}",
229
+ ]
230
+
231
+ [tool.pdm.scripts.fix-markdown]
232
+ composite = [
233
+ "mdformat {args:.}",
234
+ "pymarkdownlnt fix -r {args:.}",
235
+ "pymarkdownlnt scan -r {args:.}",
236
+ "md-dead-link-check {args:.}",
237
+ ]
238
+
239
+ [tool.pdm.scripts.check-pyproject]
240
+ composite = [
241
+ "validate-pyproject {args:pyproject.toml}",
242
+ ]
243
+
244
+ [tool.pdm.scripts.check-code]
245
+ composite = [
246
+ "codespell {args:.}",
247
+ "ec",
248
+ ]
249
+
250
+ [tool.pdm.scripts.fix-code]
251
+ composite = [
252
+ "codespell --write-changes {args:.}",
253
+ "ec",
254
+ ]
255
+
256
+ [tool.pdm.scripts.check-security]
257
+ cmd = [
258
+ "semgrep",
259
+ "scan",
260
+ "--config=p/python",
261
+ "--config=p/secrets",
262
+ "--config=p/security-audit",
263
+ "--config=p/ci",
264
+ "--config=p/github-actions",
265
+ "--config=p/bandit",
266
+ "--config=p/gitleaks",
267
+ "--error",
268
+ "--metrics=off",
269
+ "--severity=INFO",
270
+ "--strict",
271
+ "{args:.}",
272
+ ]
273
+
274
+ [tool.pdm.scripts.check-renovate]
275
+ cmd = [
276
+ "check-jsonschema",
277
+ "--builtin-schema",
278
+ "vendor.renovate",
279
+ "{args:./.github/renovate.json}",
280
+ ]
281
+
282
+ [tool.pdm.scripts.check-github-actions]
283
+ composite = [
284
+ "check-jsonschema --verbose --builtin-schema vendor.github-actions",
285
+ ]
286
+
287
+ [tool.pdm.scripts.check-github-workflows]
288
+ composite = [
289
+ "check-jsonschema --verbose --builtin-schema github-workflows-require-timeout",
290
+ "check-jsonschema --verbose --builtin-schema github-workflows",
291
+ ]
292
+
293
+ [tool.pdm.scripts.fix-legal]
294
+ shell = " bash -c \"pdm run reuse annotate --license='$(basename $(readlink -f LICENSE.md) .txt)' --copyright='open-nudge <https://github.com/open-nudge>' --contributor='$(git config get user.name) <$(git config get user.email)>' --copyright-prefix=spdx-symbol --merge-copyrights --recursive --fallback-dot-license {args:.}\"\n"
295
+
296
+ [tool.pdm.scripts.check-generation]
297
+ cmd = [
298
+ "cog",
299
+ "-c",
300
+ "--check",
301
+ "{args:\n pyproject.toml\n ./.github/workflows/cache-item-reusable.yml\n ./.github/workflows/cache-reusable.yml\n ./.github/workflows/run-reusable.yml\n ./.github/workflows/tests-reusable.yml\n ./.github/workflows/release-sbom-attest-reusable.yml\n ./.github/workflows/release-sbom-run-reusable.yml\n ./.github/workflows/release-sboms-reusable.yml\n }\n ",
302
+ ]
303
+
304
+ [tool.pdm.scripts.fix-generation]
305
+ cmd = [
306
+ "cog",
307
+ "-c",
308
+ "-r",
309
+ "{args:\n pyproject.toml\n ./.github/workflows/cache-item-reusable.yml\n ./.github/workflows/cache-reusable.yml\n ./.github/workflows/run-reusable.yml\n ./.github/workflows/tests-reusable.yml\n ./.github/workflows/release-sbom-attest-reusable.yml\n ./.github/workflows/release-sbom-run-reusable.yml\n ./.github/workflows/release-sboms-reusable.yml\n }\n ",
310
+ ]
311
+
312
+ [tool.pdm.scripts.check-all]
313
+ composite = [
314
+ "check-generation",
315
+ "check-citation",
316
+ "check-markdown",
317
+ "check-yaml",
318
+ "check-pre-commit",
319
+ "check-pyproject",
320
+ "check-legal",
321
+ "check-workflows",
322
+ "check-security",
323
+ "check-docs",
324
+ "check-python",
325
+ ]
326
+
327
+ [tool.pdm.scripts.fix-all]
328
+ composite = [
329
+ "fix-generation",
330
+ "check-citation",
331
+ "fix-markdown",
332
+ "check-yaml",
333
+ "check-pre-commit",
334
+ "fix-pyproject",
335
+ "fix-legal",
336
+ "check-legal",
337
+ "check-workflows",
338
+ "check-security",
339
+ "check-docs",
340
+ "fix-python",
341
+ ]
342
+
343
+ [tool.pdm.scripts.setup-environment]
344
+ composite = [
345
+ "pdm self update",
346
+ "pdm python install 3.13",
347
+ "pdm python install 3.12",
348
+ "pdm python install 3.11",
349
+ "pdm use 3.13",
350
+ "pdm install --prod -G:all --no-editable",
351
+ "pdm install -G dev-tests --no-editable",
352
+ "pdm use 3.12",
353
+ "pdm install --prod -G:all --no-editable",
354
+ "pdm install -G dev-tests --no-editable",
355
+ "pdm use 3.11",
356
+ ]
357
+
358
+ [tool.pdm.scripts.setup]
359
+ composite = [
360
+ "setup-environment",
361
+ "pdm install -G:all --no-editable",
362
+ "pdm run pre-commit install --install-hooks",
363
+ ]
364
+
365
+ [tool.pdm.scripts.sbom-python]
366
+ shell = " bash -c 'pdm run cyclonedx-py environment $(pdm info --python) --PEP-639 --mc-type library --schema-version 1.6'\n"
367
+
368
+ [tool.pdm.scripts.sbom-legal]
369
+ shell = " bash -c \" pdm run reuse spdx --add-license-concluded --creator-organization='open-nudge <https://github.com/open-nudge>' --creator-person='$(git config get user.name) <$(git config get user.email)>' > .sbom-legal.spdx && pdm run pyspdxtools --version \"SPDX-2.2\" --novalidation -i .sbom-legal.spdx -o .sbom-legal.json && ( cat .sbom-legal.json && rm .sbom-legal.spdx .sbom-legal.json )\"\n"
370
+
371
+ [tool.pdm.scripts.sbom-all]
372
+ composite = [
373
+ "sbom-python",
374
+ "sbom-legal",
375
+ ]
376
+
377
+ [tool.pdm.scripts.changelog]
378
+ cmd = "pdm run git-cliff"
379
+
380
+ [tool.pdm.scripts.changelog-latest]
381
+ cmd = "pdm run git-cliff --latest"
382
+
383
+ [tool.pdm.scripts.check-release]
384
+ composite = [
385
+ "sbom-all",
386
+ "changelog",
387
+ "changelog-latest",
388
+ "pdm build",
389
+ ]
390
+
391
+ [tool.pdm.scripts.commit]
392
+ shell = "echo \"By committing to this repository, you agree to the Developer Certificate of Origin (DCO).\"\nprintf \"See here: https://developercertificate.org/ for more information.\n\"\ngit commit --signoff --gpg-sign\n"
393
+
394
+ [tool.pdm.scripts.commit-type]
395
+ shell = "echo \"By committing to this repository, you agree to the Developer Certificate of Origin (DCO).\"\nprintf \"See here: https://developercertificate.org/ for more information.\n\"\n\noptions=(\"fix\" \"feat\" \"fix!\" \"feat!\")\nPS3=\"Select commit type (1-4) or Quit (5): \"\nselect opt in \"${options[@]}\" \"Quit\"; do\n case \"$REPLY\" in\n 1) break;;\n 2) break;;\n 3) break;;\n 4) break;;\n 5) exit 0; break;;\n *) echo \"Invalid option.\"; continue;;\n esac\ndone\n\nread -r -p \"\nCommit title message: \" title\n\necho \"\nYour commit will be: '$opt: $title'\n\"\n\ngit commit -S --signoff -m \"$opt: $title\"\n"
396
+
397
+ [tool.pdm.scripts.commit-guided]
398
+ shell = "echo \"By committing to this repository, you agree to the Developer Certificate of Origin (DCO).\"\nprintf \"See here: https://developercertificate.org/ for more information.\n\"\n\necho \"Please provide commit type (one of fix/feat/fix!/feat!):\"\necho \"- fix: A bug fix (not breaking backward compatibility).\"\necho \"- feat: A new feature (not breaking backward compatibility).\"\necho \"- fix!: A bug fix (breaking backward compatibility).\"\necho \"- feat!: A new feature (breaking backward compatibility).\"\necho \"\"\n\noptions=(\"fix\" \"feat\" \"fix!\" \"feat!\")\nPS3=\"Select commit type (1-4) or Quit (5): \"\nselect opt in \"${options[@]}\" \"Quit\"; do\n case \"$REPLY\" in\n 1) break;;\n 2) break;;\n 3) break;;\n 4) break;;\n 5) exit 0; break;;\n *) echo \"Invalid option.\";continue;;\n esac\ndone\n\nprintf \"\nYou picked %s type.\n\" \"$opt\"\n\necho \"Please provide commit title message:\"\necho \"- Use the imperative, present tense: 'change' not 'changed' nor 'changes'\"\necho \"- Short (72 chars or less) informative summary of changes\"\necho \"- Lowercase\"\necho \"- No dot at the end\n\"\necho \"Example: 'add performance tests'\n\"\n\nread -r -p \"Commit title message: \" title\n\necho \"\nYour commit will be: '$opt: $title'\n\"\n\nread -p \"Would you like to make this commit? (Y/N): \" confirm && [[ $confirm == [yY] || $confirm == [yY][eE][sS] ]] || exit 1\n\ngit commit -S --signoff -m \"$opt: $title\"\n"
399
+
400
+ [tool.ruff]
401
+ line-length = 80
402
+ src = [
403
+ "src",
404
+ "test",
405
+ ]
406
+ extend-exclude = [
407
+ ".pdm-plugins",
408
+ ]
409
+ unsafe-fixes = false
410
+ show-fixes = true
411
+
412
+ [tool.ruff.format]
413
+ docstring-code-format = true
414
+
415
+ [tool.ruff.lint]
416
+ select = [
417
+ "ALL",
418
+ ]
419
+ extend-ignore = [
420
+ "ANN401",
421
+ "COM812",
422
+ "ISC001",
423
+ "TID252",
424
+ ]
425
+
426
+ [tool.ruff.lint.extend-per-file-ignores]
427
+ "tests/**.py" = [
428
+ "INP001",
429
+ "S101",
430
+ ]
431
+ "template-setup/overwrite/tests/**.py" = [
432
+ "INP001",
433
+ "S101",
434
+ ]
435
+
436
+ [tool.ruff.lint.flake8-bandit]
437
+ check-typed-exception = true
438
+
439
+ [tool.ruff.lint.flake8-boolean-trap]
440
+ extend-allowed-calls = [
441
+ "django.db.models.Value",
442
+ "pydantic.Field",
443
+ ]
444
+
445
+ [tool.ruff.lint.flake8-builtins]
446
+ builtins-allowed-modules = [
447
+ "id",
448
+ ]
449
+
450
+ [tool.ruff.lint.flake8-import-conventions]
451
+ banned-from = [
452
+ "numpy",
453
+ "pandas",
454
+ "polars",
455
+ "typing",
456
+ ]
457
+
458
+ [tool.ruff.lint.flake8-pytest-style]
459
+ parametrize-values-type = "tuple"
460
+
461
+ [tool.ruff.lint.flake8-type-checking]
462
+ strict = true
463
+
464
+ [tool.ruff.lint.isort]
465
+ detect-same-package = false
466
+ lines-between-types = 1
467
+ required-imports = [
468
+ "from __future__ import annotations",
469
+ ]
470
+ section-order = [
471
+ "future",
472
+ "standard-library",
473
+ "third-party",
474
+ "ml",
475
+ "testing",
476
+ "first-party",
477
+ "local-folder",
478
+ ]
479
+
480
+ [tool.ruff.lint.isort.sections]
481
+ ml = [
482
+ "pandas",
483
+ "numpy",
484
+ "polars",
485
+ "matplotlib",
486
+ "seaborn",
487
+ "scipy",
488
+ "sklearn",
489
+ "statsmodels",
490
+ "nltk",
491
+ "spacy",
492
+ "gensim",
493
+ "tensorflow",
494
+ "torch",
495
+ "pytorch-lightning",
496
+ "lightning",
497
+ "coremltools",
498
+ "torchmetrics",
499
+ "xgboost",
500
+ "lightgbm",
501
+ "catboost",
502
+ "fastai",
503
+ "mlflow",
504
+ "neptune",
505
+ "dvc",
506
+ "wandb",
507
+ "dask",
508
+ "pyspark",
509
+ ]
510
+ testing = [
511
+ "pytest*",
512
+ "hypothesis",
513
+ ]
514
+
515
+ [tool.ruff.lint.mccabe]
516
+ max-complexity = 6
517
+
518
+ [tool.ruff.lint.pep8-naming]
519
+ classmethod-decorators = [
520
+ "pydantic.validator",
521
+ ]
522
+
523
+ [tool.ruff.lint.pycodestyle]
524
+ max-doc-length = 80
525
+ max-line-length = 120
526
+
527
+ [tool.ruff.lint.pydocstyle]
528
+ convention = "google"
529
+ ignore-decorators = [
530
+ "typing.overload",
531
+ ]
532
+
533
+ [tool.ruff.lint.pylint]
534
+ max-branches = 6
535
+ max-locals = 10
536
+ max-nested-blocks = 3
537
+ max-public-methods = 10
538
+ max-returns = 5
539
+ max-statements = 20
540
+
541
+ [tool.codespell]
542
+ skip = "*pdm.lock,*__pypackages__/*"
543
+ ignore-words-list = "intoto"
544
+ check-filenames = true
545
+ interactive = 0
546
+
547
+ [tool.coverage.run]
548
+ branch = true
549
+ relative_files = true
550
+ source = [
551
+ "src",
552
+ "tests",
553
+ ]
554
+ source_pkgs = [
555
+ "opentemplate",
556
+ ]
557
+ omit = [
558
+ "src/opentemplate/**",
559
+ ]
560
+
561
+ [tool.coverage.paths]
562
+ source = [
563
+ "src/opentemplate",
564
+ "**/opentemplate",
565
+ ]
566
+
567
+ [tool.coverage.report]
568
+ exclude_also = [
569
+ "def __repr__",
570
+ "if self.debug:",
571
+ "if settings.DEBUG",
572
+ "raise AssertionError",
573
+ "raise NotImplementedError",
574
+ "if 0:",
575
+ "if __name__ == .__main__.:",
576
+ "if TYPE_CHECKING:",
577
+ "if typing.TYPE_CHECKING:",
578
+ "class .*\\bProtocol\\):",
579
+ "@(abc\\.)?abstractmethod",
580
+ ]
581
+ fail_under = 100
582
+ precision = 2
583
+ show_missing = true
584
+ skip_empty = true
585
+
586
+ [tool.fawltydeps]
587
+ ignore_undeclared = [
588
+ "mkdocs_gen_files",
589
+ "pytest",
590
+ "hypothesis",
591
+ "opentemplate",
592
+ ]
593
+ ignore_unused = [
594
+ "basedpyright",
595
+ "cairosvg",
596
+ "cffconvert",
597
+ "check-jsonschema",
598
+ "cogapp",
599
+ "cogeol",
600
+ "conventional-pre-commit",
601
+ "coverage",
602
+ "cyclonedx-bom",
603
+ "editorconfig-checker",
604
+ "git-cliff",
605
+ "hypothesis",
606
+ "interrogate",
607
+ "markdown",
608
+ "md-dead-link-check",
609
+ "mdformat",
610
+ "mdformat-gfm",
611
+ "mdformat_footnote",
612
+ "mdformat_frontmatter",
613
+ "semgrep",
614
+ "shellcheck-py",
615
+ "termynal",
616
+ "validate-pyproject",
617
+ "yamllint",
618
+ "zizmor",
619
+ "codespell",
620
+ "fawltydeps",
621
+ "mdformat-mkdocs",
622
+ "mdformat_gfm_alerts",
623
+ "mike",
624
+ "mkdocs-awesome-nav",
625
+ "mkdocs-gen-files",
626
+ "mkdocs-git-revision-date-localized-plugin",
627
+ "mkdocs-github-admonitions-plugin",
628
+ "mkdocs-jupyter",
629
+ "mkdocs-link-marker",
630
+ "mkdocs-literate-nav",
631
+ "mkdocs-material",
632
+ "mkdocs-minify-plugin",
633
+ "mkdocs-open-in-new-tab",
634
+ "mkdocs-redirects",
635
+ "mkdocs-section-index",
636
+ "mkdocstrings",
637
+ "mkdocstrings-python",
638
+ "pillow",
639
+ "pre-commit",
640
+ "pygments",
641
+ "pyinilint",
642
+ "pymarkdownlnt",
643
+ "pymdown-extensions",
644
+ "pytest",
645
+ "pytest-asyncio",
646
+ "pytest-html",
647
+ "pytest-pretty-terminal",
648
+ "pytest-randomly",
649
+ "reuse",
650
+ "ruff",
651
+ "spdx-tools",
652
+ ]
653
+
654
+ [tool.interrogate]
655
+ verbose = 1
656
+ style = "google"
657
+ fail-under = 100
658
+ exclude = [
659
+ "build",
660
+ "test",
661
+ ".pdm-plugins",
662
+ ]
663
+
664
+ [tool.basedpyright]
665
+ exclude = [
666
+ "**/node_modules",
667
+ "**/__pycache__",
668
+ "**/.*",
669
+ "**/__pypackages__",
670
+ "site/*",
671
+ "docs/scripts/gen_ref_pages.py",
672
+ "docs/scripts/preprocess_files.py",
673
+ ]
674
+ pythonPlatform = "All"
675
+ pythonVersion = "3.11"
676
+ failOnWarnings = true
677
+ analyzeUnannotatedFunctions = true
678
+ deprecateTypingAliases = true
679
+ strictGenericNarrowing = true
680
+ typeCheckingMode = "all"
681
+ reportAny = "none"
682
+ reportUnknownVariableType = "none"
683
+ reportUnknownMemberType = "none"
684
+ reportMissingTypeStubs = "none"
685
+ reportPrivateLocalImportUsage = "none"
686
+ reportPrivateImportUsage = "none"
687
+ extraPaths = [
688
+ "__pypackages__/3.11/lib",
689
+ ]
690
+
691
+ [tool.pymarkdown.plugins.md007]
692
+ enabled = false
693
+
694
+ [tool.pymarkdown.plugins.md028]
695
+ enabled = false
696
+
697
+ [tool.pymarkdown.plugins.md033]
698
+ enabled = false
699
+
700
+ [tool.pymarkdown.plugins.md034]
701
+ enabled = false
702
+
703
+ [tool.pymarkdown.plugins.md041]
704
+ enabled = false
705
+
706
+ [tool.pymarkdown.plugins.md042]
707
+ enabled = false
708
+
709
+ [tool.md_dead_link_check]
710
+ exclude_links = [
711
+ "https://github.com/open-nudge/opentemplate*",
712
+ "https://open-nudge.github.io/opentemplate*",
713
+ "/LICENSE.md",
714
+ "https://open-nudge.github.io*",
715
+ "templateskip",
716
+ ]
717
+ exclude_files = [
718
+ "template-setup/overwrite/*",
719
+ "pypackages/*",
720
+ ]
721
+
722
+ [tool.commition]
723
+ include_paths = [
724
+ "src/*",
725
+ "pyproject.toml",
726
+ ]
727
+ exclude_commiters = [
728
+ "github-actions[bot]",
729
+ ]
730
+
731
+ [tool.git-cliff.changelog]
732
+ header = ""
733
+ body = "{%- macro remote_url() -%}\n https://github.com/{{ remote.github.owner }}/{{ remote.github.repo }}\n{%- endmacro -%}\n\n{%- if version -%}\n {% if previous.version %}\n # [{{ version | trim_start_matches(pat=\"v\") }}]({{ self::remote_url() }}/compare/{{ previous.version }}..{{ version }}) - {{ timestamp | date(format=\"%Y-%m-%d\") }} ([vs HEAD]({{ self::remote_url() }}/compare/{{ version }}..HEAD))\n {%- else -%}\n # {{ version | trim_start_matches(pat=\"v\") }} - {{ timestamp | date(format=\"%Y-%m-%d\") }} ([vs HEAD]({{ self::remote_url() }}/compare/{{ version }}..HEAD))\n {%- endif %}\n{%- else -%}\n# Untagged ([vs HEAD]({{ self::remote_url() }}/compare/..HEAD))\n{%- endif %}\n\n__Commits by type__\n\n{% set total = commits | length -%}\n\n{%- set human = self::count_commits(commits=commits, bot=false) -%}\n{%- set bot = self::count_commits(commits=commits, bot=true) -%}\n\n{%- set python = self::count_commits(commits=commits, label=\"python\") -%}\n{%- set other = self::count_commits(commits=commits, label=\"python\", contains=false) -%}\n\nTotal | Human | Bots | Python | Other\n:---: | :---: | :---:| :---: | :---:\n{{ total }} | {{ human }} | {{ bot }} | {{ python }} | {{ other }}\n\n__Commits by labels__\n\n{% set security = self::count_commits(commits=commits, label=\"security\") -%}\n{%- set tests = self::count_commits(commits=commits, label=\"tests\") -%}\n{%- set legal = self::count_commits(commits=commits, label=\"legal\") -%}\n{%- set docs = self::count_commits(commits=commits, label=\"docs\") -%}\n{%- set actions = self::count_commits(commits=commits, label=\"actions\") -%}\n{%- set deps = self::count_commits(commits=commits, label=\"deps\") -%}\n{%- set config = self::count_commits(commits=commits, label=\"config\") -%}\n\nSecurity | Tests | Legal | Docs | Actions | Config | Dependencies |\n :---: | :---: | :---: | :---:| :---: | :---: | :---: |\n{{ security }} | {{ tests }} | {{ legal }} | {{ docs }} | {{ actions }} | {{ config }} | {{ deps }}\n\n{% set python_data = [python, \"Python\", true, get_env(name=\"PYTHON_PACKAGE_VERSION\", default=\"\")] -%}\n{%- set other_data = [other, \"Other\", false, \"\"] -%}\n{%- set data = [python_data, other_data] -%}\n\n{%- for item in data%}\n {%- if item[0] != \"0\" -%}\n ## {{ item[1] }} ({% if item[3] %}v{{ item[3] }}, {% endif %}{{ item[0] }} commits)\n {{- self::display(\n commits=commits | filter(attribute=\"breaking\", value=true),\n header=\"Breaking changes\",\n python=item[2],\n display_group=true,\n )-}}\n {{- self::display(\n commits=commits | filter(attribute=\"breaking\", value=false) | filter(attribute=\"group\", value=\"feat\"),\n header=\"Features\",\n python=item[2],\n )-}}\n {{- self::display(\n commits=commits | filter(attribute=\"breaking\", value=false) | filter(attribute=\"group\", value=\"fix\"),\n header=\"Fixes\",\n python=item[2],\n )-}}\n {{- self::display(\n commits=commits,\n header=\"Bots\",\n python=item[2],\n display_group=true,\n bot=true,\n )-}}\n {% endif -%}\n{% endfor %}\n\n{%- macro count_commits(commits, label=false, bot=\"ignore\", contains=true) -%}\n {% set counter = 0 %}\n {%- for commit in commits %}\n {%- if\n (\n not label or\n (\n (contains and commit.remote.pr_labels and label in commit.remote.pr_labels)\n or\n (not contains and commit.remote.pr_labels and label not in commit.remote.pr_labels)\n )\n )\n and\n (\n bot == \"ignore\"\n or\n (not bot and not \"[bot]\" in commit.author.name)\n or\n (bot and \"[bot]\" in commit.author.name)\n )\n -%}\n {%- set_global counter = counter + 1 -%}\n {%- endif -%}\n {%- endfor -%}\n {{- counter -}}\n{%- endmacro -%}\n\n{%- macro display(commits, header, python, bot=false, display_group=false) -%}\n {%- set n_commits = self::count_commits(\n commits=commits,\n label=\"python\",\n bot=bot,\n contains=python,\n ) -%}\n {%- if n_commits != \"0\" %}\n\n ### {{ header }} ({{ n_commits }} commits)\n\n {% endif -%}\n {%- for commit in commits -%}\n {%- if\n (\n python == \"ignore\"\n or\n (python and commit.remote.pr_labels and \"python\" in commit.remote.pr_labels)\n or\n (not python and commit.remote.pr_labels and \"python\" not in commit.remote.pr_labels)\n )\n and\n (\n bot == \"ignore\"\n or\n (bot and \"[bot]\" in commit.author.name)\n or\n (not bot and not \"[bot]\" in commit.author.name)\n )\n -%}\n - {% if display_group -%}\n {% if commit.group == \"feat\" -%}[FEATURE] {% elif commit.group == \"fix\" -%}[FIX] {% else -%}[?] {% endif -%}\n {%- endif -%}\n {{ commit.message | split(pat=\"\n\") | first | upper_first | trim }} {% if commit.remote.username -%}\n (by [__@{{ commit.remote.username }}__](https://github.com/{{ commit.remote.username }})) {% elif \"[bot]\" in commit.author.name -%}\n (by __@{{ commit.author.name }}__ [BOT]) {% elif commit.author.name -%}\n (by __@{{ commit.author.name }}__) {% endif -%}\n {% if commit.remote.pr_number -%}\n ([#{{ commit.remote.pr_number }}]({{ self::remote_url() }}/pull/{{ commit.remote.pr_number }}))\n {%- endif %}\n {%- if commit.remote.pr_labels and commit.remote.pr_labels | length > 0 %}\n {%- for label in commit.remote.pr_labels -%}\n {%- if label == \"security\" %} [SECURITY]\n {%- elif label == \"tests\" %} [TESTS]\n {%- elif label == \"legal\" %} [LEGAL]\n {%- elif label == \"docs\" %} [DOCS]\n {%- elif label == \"actions\" %} [ACTIONS]\n {%- elif label == \"config\" %} [CONFIG]\n {%- elif label == \"deps\" %} [DEPS]\n {%- endif -%}\n {%- endfor %}\n {%- endif %}\n {%- endif %}\n {% endfor -%}\n{%- endmacro -%}\n"
734
+ footer = ""
735
+ trim = true
736
+
737
+ [tool.git-cliff.git]
738
+ conventional_commits = true
739
+ filter_unconventional = true
740
+ commit_parsers = [
741
+ { message = "^feat", group = "feat" },
742
+ { message = "^fix", group = "fix" },
743
+ ]
744
+ filter_commits = true
745
+ topo_order = false
746
+ sort_commits = "oldest"
@@ -0,0 +1,14 @@
1
+ <!--
2
+ SPDX-FileCopyrightText: © 2025 open-nudge <https://github.com/open-nudge>
3
+ SPDX-FileContributor: szymonmaszke <github@maszke.co>
4
+
5
+ SPDX-License-Identifier: Apache-2.0
6
+ -->
7
+
8
+ # Tests of opentemplate
9
+
10
+ - `test_smoke.py` - generic
11
+ [smoke tests](https://grafana.com/blog/2024/01/30/smoke-testing/)
12
+ to check if the package is importable
13
+
14
+ <!-- Describe your testing here -->