├── .all-contributorsrc ├── .editorconfig ├── .github └── workflows │ └── main.yml ├── .gitignore ├── CHANGELOG.md ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── copier.yml ├── includes ├── licenses │ ├── header.txt.jinja │ └── stub.md.jinja └── pyproject │ └── deps-pep-621.toml.jinja ├── pyproject.toml ├── template ├── .editorconfig ├── .gitignore ├── .pre-commit-config.yaml.jinja ├── CHANGELOG.md ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md.jinja ├── README.md.jinja ├── pyproject.toml.jinja ├── src │ └── {{ package_name }} │ │ ├── __init__.py.jinja │ │ └── {% if use_types %}py.typed{% endif %} ├── {% if documentation != '' %}.readthedocs.yaml{% endif %}.jinja ├── {% if documentation == 'mkdocs' %}docs{% endif %} │ └── index.md.jinja ├── {% if documentation == 'mkdocs' %}mkdocs.yml{% endif %}.jinja ├── {% if documentation == 'sphinx' %}docs{% endif %} │ ├── conf.py.jinja │ └── index.md.jinja ├── {% if license == 'Apache-2.0' %}LICENSE{% endif %}.jinja ├── {% if license == 'BSD-3-Clause' %}LICENSE{% endif %}.jinja ├── {% if license == 'EUPL-1.2' %}LICENSE{% endif %}.jinja ├── {% if license == 'GPL-3.0-only' %}LICENSE{% endif %}.jinja ├── {% if license == 'MIT' %}LICENSE{% endif %}.jinja ├── {% if license == 'MPL-2.0' %}LICENSE{% endif %}.jinja ├── {% if use_git and dev_platform == 'GitHub' %}.github{% endif %} │ ├── ISSUE_TEMPLATE │ │ ├── 01-bug-report.yml.jinja │ │ ├── 02-question.yml.jinja │ │ ├── 03-feature-request.yml.jinja │ │ └── config.yml.jinja │ ├── PULL_REQUEST_TEMPLATE.md │ ├── SUPPORT.md.jinja │ └── workflows │ │ ├── cron.yml │ │ ├── main.yml │ │ ├── release.yml │ │ └── test.yml.jinja └── {% if use_test %}tests{% endif %} │ ├── integration │ └── .keep │ ├── system │ ├── .keep │ └── test_import.py.jinja │ └── unit │ └── .keep └── tests ├── conftest.py ├── test_partials.py └── test_template_init.py /.all-contributorsrc: -------------------------------------------------------------------------------- 1 | { 2 | "files": [ 3 | "README.md" 4 | ], 5 | "imageSize": 100, 6 | "commit": false, 7 | "commitType": "docs", 8 | "commitConvention": "angular", 9 | "contributors": [ 10 | { 11 | "login": "Midnighter", 12 | "name": "Moritz E. Beber", 13 | "avatar_url": "https://avatars.githubusercontent.com/u/135653?v=4", 14 | "profile": "https://github.com/Midnighter", 15 | "contributions": [ 16 | "code", 17 | "review", 18 | "ideas" 19 | ] 20 | }, 21 | { 22 | "login": "blink1073", 23 | "name": "Steven Silvester", 24 | "avatar_url": "https://avatars.githubusercontent.com/u/2096628?v=4", 25 | "profile": "https://www.linkedin.com/in/steven-silvester-90318721/", 26 | "contributions": [ 27 | "code", 28 | "review", 29 | "ideas" 30 | ] 31 | }, 32 | { 33 | "login": "sneakers-the-rat", 34 | "name": "Jonny Saunders", 35 | "avatar_url": "https://avatars.githubusercontent.com/u/12961499?v=4", 36 | "profile": "https://jon-e.net", 37 | "contributions": [ 38 | "code", 39 | "review" 40 | ] 41 | }, 42 | { 43 | "login": "ucodery", 44 | "name": "Jeremy Paige", 45 | "avatar_url": "https://avatars.githubusercontent.com/u/28751151?v=4", 46 | "profile": "http://blog.ucodery.com", 47 | "contributions": [ 48 | "code", 49 | "review" 50 | ] 51 | }, 52 | { 53 | "login": "lwasser", 54 | "name": "Leah Wasser", 55 | "avatar_url": "https://avatars.githubusercontent.com/u/7649194?v=4", 56 | "profile": "http://www.leahwasser.com", 57 | "contributions": [ 58 | "code", 59 | "review" 60 | ] 61 | }, 62 | { 63 | "login": "agriyakhetarpal", 64 | "name": "Agriya Khetarpal", 65 | "avatar_url": "https://avatars.githubusercontent.com/u/74401230?v=4", 66 | "profile": "https://github.com/agriyakhetarpal", 67 | "contributions": [ 68 | "review" 69 | ] 70 | }, 71 | { 72 | "login": "yuvipanda", 73 | "name": "Yuvi Panda", 74 | "avatar_url": "https://avatars.githubusercontent.com/u/30430?v=4", 75 | "profile": "https://github.com/yuvipanda", 76 | "contributions": [ 77 | "code", 78 | "review" 79 | ] 80 | } 81 | ], 82 | "contributorsPerLine": 7, 83 | "skipCi": true, 84 | "repoType": "github", 85 | "repoHost": "https://github.com", 86 | "projectName": "pyos-package-template", 87 | "projectOwner": "pyOpenSci" 88 | } 89 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # Editor Configuration (http://editorconfig.org) 2 | root = true 3 | 4 | [*] 5 | charset = utf-8 6 | indent_style = space 7 | indent_size = 4 8 | end_of_line = lf 9 | insert_final_newline = true 10 | trim_trailing_whitespace = true 11 | max_line_length = 88 12 | 13 | [*.{json,yml,yaml}] 14 | indent_size = 2 15 | 16 | [*.{md,rst}] 17 | trim_trailing_whitespace = false 18 | 19 | [Makefile] 20 | indent_style = tab 21 | -------------------------------------------------------------------------------- /.github/workflows/main.yml: -------------------------------------------------------------------------------- 1 | name: CI-CD 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | pull_request: 8 | branches: 9 | - main 10 | 11 | jobs: 12 | test: 13 | runs-on: ${{ matrix.os }} 14 | strategy: 15 | fail-fast: false 16 | matrix: 17 | os: [ubuntu-latest, macos-latest, windows-latest] 18 | python-version: ["3.10", "3.13"] 19 | 20 | steps: 21 | - uses: actions/checkout@v4 22 | 23 | - name: Set up Python ${{ matrix.python-version }} 24 | uses: actions/setup-python@v5 25 | with: 26 | python-version: ${{ matrix.python-version }} 27 | 28 | - name: Install dependencies 29 | run: | 30 | python -m pip install --upgrade pip 31 | python -m pip install hatch 32 | 33 | - name: Test suite 34 | run: hatch run +py=${{ matrix.python-version }} test:run -- -vv -s 35 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ### Linux template 2 | *~ 3 | 4 | # temporary files which can be created if a process still has a handle open of a deleted file 5 | .fuse_hidden* 6 | 7 | # KDE directory preferences 8 | .directory 9 | 10 | # Linux trash folder which might appear on any partition or disk 11 | .Trash-* 12 | 13 | # .nfs files are created when an open file is removed but is still being accessed 14 | .nfs* 15 | 16 | ### Windows template 17 | # Windows thumbnail cache files 18 | Thumbs.db 19 | Thumbs.db:encryptable 20 | ehthumbs.db 21 | ehthumbs_vista.db 22 | 23 | # Dump file 24 | *.stackdump 25 | 26 | # Folder config file 27 | [Dd]esktop.ini 28 | 29 | # Recycle Bin used on file shares 30 | $RECYCLE.BIN/ 31 | 32 | # Windows Installer files 33 | *.cab 34 | *.msi 35 | *.msix 36 | *.msm 37 | *.msp 38 | 39 | # Windows shortcuts 40 | *.lnk 41 | 42 | ### JupyterNotebooks template 43 | # gitignore template for Jupyter Notebooks 44 | # website: http://jupyter.org/ 45 | 46 | .ipynb_checkpoints 47 | */.ipynb_checkpoints/* 48 | 49 | # IPython 50 | profile_default/ 51 | ipython_config.py 52 | 53 | # Remove previous ipynb_checkpoints 54 | # git rm -r .ipynb_checkpoints/ 55 | 56 | ### macOS template 57 | # General 58 | .DS_Store 59 | .AppleDouble 60 | .LSOverride 61 | 62 | # Icon must end with two \r 63 | Icon 64 | 65 | # Thumbnails 66 | ._* 67 | 68 | # Files that might appear in the root of a volume 69 | .DocumentRevisions-V100 70 | .fseventsd 71 | .Spotlight-V100 72 | .TemporaryItems 73 | .Trashes 74 | .VolumeIcon.icns 75 | .com.apple.timemachine.donotpresent 76 | 77 | # Directories potentially created on remote AFP share 78 | .AppleDB 79 | .AppleDesktop 80 | Network Trash Folder 81 | Temporary Items 82 | .apdisk 83 | 84 | ### Python template 85 | # Byte-compiled / optimized / DLL files 86 | __pycache__/ 87 | *.py[cod] 88 | *$py.class 89 | 90 | # C extensions 91 | *.so 92 | 93 | # Distribution / packaging 94 | .Python 95 | build/ 96 | develop-eggs/ 97 | dist/ 98 | downloads/ 99 | eggs/ 100 | .eggs/ 101 | lib/ 102 | lib64/ 103 | parts/ 104 | sdist/ 105 | var/ 106 | wheels/ 107 | share/python-wheels/ 108 | *.egg-info/ 109 | .installed.cfg 110 | *.egg 111 | MANIFEST 112 | 113 | # PyInstaller 114 | # Usually these files are written by a python script from a template 115 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 116 | *.manifest 117 | *.spec 118 | 119 | # Installer logs 120 | pip-log.txt 121 | pip-delete-this-directory.txt 122 | 123 | # Unit test / coverage reports 124 | htmlcov/ 125 | .tox/ 126 | .nox/ 127 | .coverage 128 | .coverage.* 129 | .cache 130 | nosetests.xml 131 | coverage.xml 132 | *.cover 133 | *.py,cover 134 | .hypothesis/ 135 | .pytest_cache/ 136 | cover/ 137 | 138 | # Translations 139 | *.mo 140 | *.pot 141 | 142 | # Django stuff: 143 | *.log 144 | local_settings.py 145 | db.sqlite3 146 | db.sqlite3-journal 147 | 148 | # Flask stuff: 149 | instance/ 150 | .webassets-cache 151 | 152 | # Scrapy stuff: 153 | .scrapy 154 | 155 | # Sphinx documentation 156 | docs/_build/ 157 | 158 | # PyBuilder 159 | .pybuilder/ 160 | target/ 161 | 162 | # Jupyter Notebook 163 | 164 | # IPython 165 | 166 | # pyenv 167 | # For a library or package, you might want to ignore these files since the code is 168 | # intended to run in multiple environments; otherwise, check them in: 169 | # .python-version 170 | 171 | # pipenv 172 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. 173 | # However, in case of collaboration, if having platform-specific dependencies or dependencies 174 | # having no cross-platform support, pipenv may install dependencies that don't work, or not 175 | # install all needed dependencies. 176 | #Pipfile.lock 177 | 178 | # poetry 179 | # Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control. 180 | # This is especially recommended for binary packages to ensure reproducibility, and is more 181 | # commonly ignored for libraries. 182 | # https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control 183 | #poetry.lock 184 | 185 | # pdm 186 | # Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control. 187 | #pdm.lock 188 | # pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it 189 | # in version control. 190 | # https://pdm.fming.dev/#use-with-ide 191 | .pdm.toml 192 | 193 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm 194 | __pypackages__/ 195 | 196 | # Celery stuff 197 | celerybeat-schedule 198 | celerybeat.pid 199 | 200 | # SageMath parsed files 201 | *.sage.py 202 | 203 | # Environments 204 | .env 205 | .venv 206 | env/ 207 | venv/ 208 | ENV/ 209 | env.bak/ 210 | venv.bak/ 211 | 212 | # Spyder project settings 213 | .spyderproject 214 | .spyproject 215 | 216 | # Rope project settings 217 | .ropeproject 218 | 219 | # mkdocs documentation 220 | /site 221 | 222 | # mypy 223 | .mypy_cache/ 224 | .dmypy.json 225 | dmypy.json 226 | 227 | # Pyre type checker 228 | .pyre/ 229 | 230 | # pytype static type analyzer 231 | .pytype/ 232 | 233 | # Cython debug symbols 234 | cython_debug/ 235 | 236 | # PyCharm 237 | # JetBrains specific template is maintained in a separate JetBrains.gitignore that can 238 | # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore 239 | # and can be added to the global gitignore or merged into this file. For a more nuclear 240 | # option (not recommended) you can uncomment the following to ignore the entire idea folder. 241 | #.idea/ 242 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # pyOpenSci packaging template Changelog 2 | 3 | ## [Unreleased] 4 | 5 | * Update release workflow to follow PyPA / PyPI recommended practices (@lwasser, #48) 6 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to the pyOpenSci Python package template 2 | 3 | To work on the template locally, you can call the copier template directly. Note that by default, `copier` uses the latest tag in your commit history. To ensure it uses the latest commit on your current active branch use: 4 | 5 | `copier copy -r HEAD /path/to/your/template destination-dir` 6 | 7 | If you want to test it against the latest tag in your local commit history, you can use: 8 | 9 | `copier copy /path/to/your/template destination-dir` 10 | 11 | ## Run the tests 12 | 13 | You can use Hatch to run all of the tests for the template: 14 | 15 | `hatch run test:run` 16 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2024 pyOpenSci 2 | 3 | Redistribution and use in source and binary forms, with or without modification, 4 | are permitted provided that the following conditions are met: 5 | 6 | 1. Redistributions of source code must retain the above copyright notice, this 7 | list of conditions and the following disclaimer. 8 | 9 | 2. Redistributions in binary form must reproduce the above copyright notice, 10 | this list of conditions and the following disclaimer in the documentation and/or 11 | other materials provided with the distribution. 12 | 13 | 3. Neither the name of the copyright holder nor the names of its contributors 14 | may be used to endorse or promote products derived from this software without 15 | specific prior written permission. 16 | 17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND 18 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 19 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 20 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR 21 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 22 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 23 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 24 | ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 26 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # pyOpenSci Python Package Template 2 | 3 | [![All Contributors](https://img.shields.io/badge/all_contributors-7-orange.svg?style=flat-square)](#contributors-) 4 | 5 | [![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.14052273.svg)](https://doi.org/10.5281/zenodo.14052273) 6 | [![Copier](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/copier-org/copier/master/img/badge/badge-black.json)](https://github.com/copier-org/copier) 7 | 8 | > A Python package template that supports the pyOpenSci 9 | > pure [Python packaging tutorial](https://www.pyopensci.org/python-package-guide/tutorials/intro.html). 10 | This template can be used with [copier](https://copier.readthedocs.io) to initialize a 11 | new Python package project structure following the practices outlined in the pyOpenSci 12 | tutorial. 13 | 14 | ## Get started 15 | 16 | To use this template: 17 | 18 | 1. Install copier using [pipx](https://pipx.pypa.io/stable/) or pip preferably with a [virtual environment](https://www.pyopensci.org/python-package-guide/CONTRIBUTING.html#create-a-virtual-environment). 19 | 20 | Global Installation: 21 | 22 | ```console 23 | pipx install copier 24 | ``` 25 | 26 | or Environment specific installation: 27 | 28 | ```console 29 | pip install copier 30 | ``` 31 | 32 | 2. Run the below copier command. Please note that copier creates a target directory if 33 | it doesn't exist yet. It will also **create and possibly overwrite files in the given 34 | directory, even if it already exists!** That includes your current directory if that 35 | is your target. 36 | 37 | ```console 38 | copier copy gh:pyopensci/pyos-package-template path/here 39 | ``` 40 | 41 | The command below will create the package directory in your current working directory. 42 | 43 | ```console 44 | copier copy gh:pyopensci/pyos-package-template . 45 | ``` 46 | 47 | Used in the above way, copier will use the latest tagged release, which is probably 48 | the safest option. You can provide an option `--vcs-ref` to choose specific branches 49 | as your source. You can read more about generating your project 50 | in the [copier documentation](https://copier.readthedocs.io/en/stable/generating/). 51 | 52 | ## Run the template workflow 53 | 54 | Once you have installed copier, you are ready to create your Python package template. 55 | First, run the command below from your favorite shell. Note that this is copying our template from GitHub so it 56 | will require internet access to run properly. 57 | 58 | The command below will create the package directory in your current working directory. 59 | 60 | `copier copy gh:pyopensci/pyos-package-template .` 61 | 62 | If you wish to create the package directory in another directory you can specify it like this: 63 | 64 | `copier copy gh:pyopensci/pyos-package-template dirname-here` 65 | 66 | ## Template overview 67 | 68 | The copier template will ask you a series of questions which you can respond to. The questions will 69 | help you customize the template. 70 | 71 | Below is what the template workflow will look like when you run it. In the example below, you 72 | "fully customize" the template. 73 | 74 | ```console 75 | ➜ copier copy gh:pyopensci/pyos-package-template . 76 | 🎤 Who is the copyright holder, for example, yourself or your organization? Used in the license 77 | pyos 78 | 🎤 Who is the author of the package to be? Used in the package description. 79 | pyos 80 | 🎤 The author's email address. Used in the package description. 81 | youremail@youremail.com 82 | 🎤 What is the name of the project? Used as the title in the README.md and other places. 83 | mypkg 84 | 🎤 Please provide a short description for the package. 85 | (Finish with 'Alt+Enter' or 'Esc then Enter') 86 | > description here 87 | 🎤 Do you want to skip all remaining questions and simply use the provided default values? 88 | No, I want to fully customize the template. 89 | 🎤 What is the project slug? Used in hyperlinks. 90 | mypkg 91 | 🎤 What is the Python package name? Used as the name of the package and the top-level import. 92 | mypkg 93 | 🎤 Do you want to use dynamic versioning of your package or static? Dynamic means that versions 94 | No 95 | 🎤 Do you want to use git with a development platform, like GitHub or GitLab? 96 | Yes 97 | 🎤 Which development platform are you planning to use? Used to generate certain documentation an 98 | GitHub 99 | 🎤 Your or your organization's username on GitHub. Used to generate certain documentation and hy 100 | pyopensci 101 | 🎤 Do you want to include documentation for your project and which framework do you want to use? 102 | Sphinx (https://www.pyopensci.org/pyos-sphinx-theme) 103 | 🎤 Do you want to use hatch environments for running isolated commands like linting, building do 104 | Yes 105 | 🎤 Do you want to lint your code and generally check the formatting of your files? 106 | Yes 107 | 🎤 Do you want to use typing annotations and type check your code? 108 | No 109 | 🎤 Do you want to test your code? Generally, we strongly recommend that you do, but for a quick 110 | Yes 111 | 🎤 Which license do you want to use? Used in the license file. 112 | MIT 113 | 🎤 What is the starting year of the project? Used in copyright statements. 114 | 2024 115 | ``` 116 | 117 | ### Stay up-to-date 118 | 119 | The community will likely continue to develop this template. If at any point, you want 120 | to adopt those changes for your project, you can update it. Read more about that process 121 | in the [copier documentation](https://copier.readthedocs.io/en/stable/updating/). 122 | 123 | ## Contributors ✨ 124 | 125 | Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/docs/en/emoji-key)): 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 |
Moritz E. Beber
Moritz E. Beber

💻 👀 🤔
Steven Silvester
Steven Silvester

💻 👀 🤔
Jonny Saunders
Jonny Saunders

💻 👀
Jeremy Paige
Jeremy Paige

💻 👀
Leah Wasser
Leah Wasser

💻 👀
Agriya Khetarpal
Agriya Khetarpal

👀
Yuvi Panda
Yuvi Panda

💻 👀
143 | 144 | 145 | 146 | 147 | 148 | 149 | This project follows the [all-contributors](https://github.com/all-contributors/all-contributors) specification. Contributions of any kind welcome! 150 | -------------------------------------------------------------------------------- /copier.yml: -------------------------------------------------------------------------------- 1 | copyright_holder: 2 | type: str 3 | help: "Who is the copyright holder, for example, yourself or your organization? Used in the license file and project description." 4 | 5 | author_name: 6 | type: str 7 | help: "Who is the author of the package to be? Used in the package description." 8 | default: "{{ copyright_holder }}" 9 | 10 | author_email: 11 | type: str 12 | help: "The author's email address. Used in the package description." 13 | 14 | project_name: 15 | type: str 16 | help: "What is the name of the project? Used as the title in the README.md and other places." 17 | 18 | package_description: 19 | type: str 20 | multiline: true 21 | help: "Please provide a short description for the package." 22 | 23 | use_default: 24 | type: str 25 | help: "Do you want to skip all remaining questions and simply use the provided default values?" 26 | choices: 27 | "No, I want to fully customize the template.": "no" 28 | "Yes, with all the bells and whistles.": "full" 29 | "Yes, but with a minimal setup.": "minimal" 30 | default: "no" 31 | 32 | project_slug: 33 | when: "{{ use_default == 'no' }}" 34 | type: str 35 | help: "What is the project slug? Used in hyperlinks." 36 | default: "{{ project_name|lower|replace(' ', '-') }}" 37 | 38 | package_name: 39 | when: "{{ use_default == 'no' }}" 40 | type: str 41 | help: "What is the Python package name? Used as the name of the package and the top-level import." 42 | default: "{{ project_slug|replace('-', '_') }}" 43 | 44 | use_vcs_version: 45 | when: "{{ use_default == 'no' }}" 46 | type: bool 47 | default: "{% if use_default != 'minimal' %}yes{% else %}no{% endif %}" 48 | help: "Do you want to use dynamic versioning of your package or static? Dynamic means that versions use your version control system (VCS), such as git tags, for creating versions." 49 | 50 | use_git: 51 | when: "{{ use_default == 'no' }}" 52 | type: bool 53 | default: "{% if use_default != 'minimal' %}yes{% else %}no{% endif %}" 54 | help: "Do you want to use git with a development platform, like GitHub or GitLab?" 55 | 56 | dev_platform: 57 | when: "{{ use_default == 'no' and use_git }}" 58 | type: str 59 | help: "Which development platform are you planning to use? Used to generate certain documentation and hyperlinks." 60 | choices: 61 | - "GitHub" 62 | - "GitLab" 63 | default: "GitHub" 64 | 65 | dev_platform_url: 66 | type: str 67 | when: false 68 | default: "https://{{ dev_platform|lower }}.com" 69 | 70 | username: 71 | when: "{{ use_git }}" 72 | type: str 73 | help: "Your or your organization's username on {{ dev_platform }}. Used to generate certain documentation and hyperlinks." 74 | 75 | documentation: 76 | when: "{{ use_default == 'no' }}" 77 | type: str 78 | help: "Do you want to include documentation for your project and which framework do you want to use?" 79 | choices: 80 | "Sphinx (https://pydata-sphinx-theme.readthedocs.io/en/stable/index.html)": sphinx 81 | "mkdocs-material (https://squidfunk.github.io/mkdocs-material)": mkdocs 82 | No: "" 83 | default: "{% if use_default != 'minimal' %}sphinx{% else %}{% endif %}" 84 | 85 | use_hatch_envs: 86 | when: "{{ use_default == 'no' }}" 87 | type: bool 88 | default: "{% if use_default != 'minimal' %}yes{% else %}no{% endif %}" 89 | help: "Do you want to use hatch environments for running isolated commands like linting, building docs, or testing?" 90 | 91 | use_lint: 92 | when: "{{ use_default == 'no' }}" 93 | type: bool 94 | default: "{% if use_default != 'minimal' %}yes{% else %}no{% endif %}" 95 | help: "Do you want to lint your code and generally check the formatting of your files?" 96 | 97 | use_types: 98 | when: "{{ use_default == 'no' }}" 99 | type: bool 100 | default: "{% if use_default != 'minimal' %}yes{% else %}no{% endif %}" 101 | help: "Do you want to use typing annotations and type check your code?" 102 | 103 | use_test: 104 | when: "{{ use_default == 'no' }}" 105 | type: bool 106 | default: "{% if use_default != 'minimal' %}yes{% else %}no{% endif %}" 107 | help: "Do you want to test your code? Generally, we strongly recommend that you do, but for a quick demo you may want to avoid this." 108 | 109 | license: 110 | when: "{{ use_default == 'no' }}" 111 | type: str 112 | help: | 113 | Which license do you want to use? Includes a LICENSE file in the repository root. 114 | For more information, see: 115 | - https://www.pyopensci.org/python-package-guide/documentation/repository-files/license-files.html 116 | - https://opensource.org/licenses 117 | choices: 118 | "Permissive - MIT": "MIT" 119 | "Permissive - BSD-3-Clause": "BSD-3-Clause" 120 | "Permissive - Apache-2.0": "Apache-2.0" 121 | "Copyleft - GPL-3.0": "GPL-3.0-only" 122 | "Copyleft - EUPL-1.2": "EUPL-1.2" 123 | "Intermediate - MPL-2.0": "MPL-2.0" 124 | default: MIT 125 | 126 | year: 127 | when: "{{ use_default == 'no' }}" 128 | type: str 129 | help: "What is the starting year of the project? Used in copyright statements." 130 | default: "2025" 131 | 132 | _subdirectory: "template" 133 | -------------------------------------------------------------------------------- /includes/licenses/header.txt.jinja: -------------------------------------------------------------------------------- 1 | {%- if license == "MIT" -%} 2 | # MIT License 3 | # 4 | # Copyright (c) {{ year }} {{ copyright_holder }} 5 | # 6 | # Permission is hereby granted, free of charge, to any person obtaining a copy 7 | # of this software and associated documentation files (the "Software"), to deal 8 | # in the Software without restriction, including without limitation the rights 9 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | # copies of the Software, and to permit persons to whom the Software is 11 | # furnished to do so, subject to the following conditions: 12 | # 13 | # The above copyright notice and this permission notice (including the next 14 | # paragraph) shall be included in all copies or substantial portions of the 15 | # Software. 16 | # 17 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | # SOFTWARE. 24 | {%- elif license == "BSD-3-Clause" -%} 25 | # Copyright (c) {{ year }} {{ copyright_holder }} 26 | # 27 | # Redistribution and use in source and binary forms, with or without 28 | # modification, are permitted provided that the following conditions are met: 29 | # 30 | # 1. Redistributions of source code must retain the above copyright notice, 31 | # this list of conditions and the following disclaimer. 32 | # 2. Redistributions in binary form must reproduce the above copyright 33 | # notice, this list of conditions and the following disclaimer in the 34 | # documentation and/or other materials provided with the distribution. 35 | # 3. Neither the name of the copyright holder nor the names of its 36 | # contributors may be used to endorse or promote products derived from this 37 | # software without specific prior written permission. 38 | # 39 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 40 | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 41 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 42 | # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 43 | # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 44 | # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 45 | # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 46 | # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 47 | # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 48 | # POSSIBILITY OF SUCH DAMAGE. 49 | {%- elif license == "Apache-2.0" -%} 50 | # Copyright (c) {{ year }} {{ copyright_holder }} 51 | # 52 | # Licensed under the Apache License, Version 2.0 (the "License"); you may not 53 | # use this file except in compliance with the License. You may obtain a copy of 54 | # the License at 55 | # 56 | # https://www.apache.org/licenses/LICENSE-2.0 57 | # 58 | # Unless required by applicable law or agreed to in writing, software 59 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 60 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 61 | # License for the specific language governing permissions and limitations under 62 | # the License. 63 | {%- elif license == "GPL-3.0-only" -%} 64 | # Copyright © {{ year }} {{ copyright_holder }} 65 | # 66 | # This program is free software: you can redistribute it and/or modify 67 | # it under the terms of the [GNU General Public License 3.0](./LICENSE) 68 | # as published by the Free Software Foundation 69 | # 70 | # This program is distributed in the hope that it will be useful, 71 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 72 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 73 | # GNU General Public License for more details. 74 | # 75 | # You should have received a copy of the GNU General Public License along with 76 | # this program. If not, see https://www.gnu.org/licenses/. 77 | {%- elif license == "EUPL-1.2" -%} 78 | # Copyright © {{ year }} {{ copyright_holder }}. 79 | # Free software licensed under the EUPL 1.2 or later 80 | {%- elif license == "MPL-2.0" -%} 81 | # Copyright © {{ year }} {{ copyright_holder }}. 82 | # 83 | # This Source Code Form is subject to the terms of the Mozilla Public 84 | # License, v. 2.0. If a copy of the MPL was not distributed with this 85 | # file, You can obtain one at https://mozilla.org/MPL/2.0/. 86 | {%- endif %} -------------------------------------------------------------------------------- /includes/licenses/stub.md.jinja: -------------------------------------------------------------------------------- 1 | {%- if license_path is not defined or license_path is none -%} 2 | {# to not make a link, explicitly pass False. leaving undefined uses default location #} 3 | {%- set license_path = "./LICENSE" -%} 4 | {%- endif -%} 5 | {%- macro license_link(name) -%} 6 | {%- if not license_path %}{{ name }}{% else %}[{{ name }}]({{ license_path }}){% endif -%} 7 | {%- endmacro -%} 8 | {%- if license == "MIT" -%} 9 | - Copyright © {{ year }} {{ copyright_holder }}. 10 | - Free software distributed under the {{ license_link('MIT License') }}. 11 | {%- elif license == "BSD-3-Clause" -%} 12 | - Copyright © {{ year }} {{ copyright_holder }}. 13 | - Free software distributed under the {{ license_link('3-Clause BSD License') }}. 14 | {%- elif license == "Apache-2.0" -%} 15 | - Copyright © {{ year }} {{ copyright_holder }}. 16 | - Free software distributed under the {{ license_link('Apache Software License 2.0') }}. 17 | {%- elif license == "GPL-3.0-only" -%} 18 | - Copyright © {{ year }} {{ copyright_holder }}. 19 | - Free software licensed under the {{ license_link('GNU Public License 3.0') }}. 20 | {%- elif license == "EUPL-1.2" -%} 21 | - Copyright © {{ year }} {{ copyright_holder }}. 22 | - Free software licensed under the {{ license_link('EUPL 1.2 or later') }}. 23 | {%- elif license == "MPL-2.0" -%} 24 | - Copyright © {{ year }} {{ copyright_holder }}. 25 | - This Source Code Form is subject to the terms of the {{ license_link('Mozilla Public License, v2.0') }}. 26 | {%- endif -%} 27 | -------------------------------------------------------------------------------- /includes/pyproject/deps-pep-621.toml.jinja: -------------------------------------------------------------------------------- 1 | {% if documentation == "mkdocs" -%} 2 | docs = [ 3 | "mkdocs-material ~=9.5", 4 | "mkdocstrings[python] ~=0.24", 5 | "mkdocs-awesome-pages-plugin ~=2.9", 6 | ] 7 | {% elif documentation == "sphinx" -%} 8 | docs = [ 9 | "pydata_sphinx_theme ~=0.16", 10 | "myst-parser ~=4.0", 11 | "Sphinx ~=8.0", 12 | "sphinx-autobuild ==2024.10.3" 13 | ] 14 | {% endif %} 15 | {%- if use_test -%} 16 | tests = [ 17 | "pytest", 18 | "pytest-cov", 19 | "pytest-raises", 20 | "pytest-randomly", 21 | "pytest-xdist", 22 | ] 23 | {% endif %} 24 | {%- if use_lint -%} 25 | style = [ 26 | "pydoclint", 27 | "ruff", 28 | ] 29 | {% endif %} 30 | {%- if use_types -%} 31 | types = [ 32 | "mypy", 33 | ] 34 | {% endif -%} 35 | audit = [ 36 | "pip-audit", 37 | ] 38 | -------------------------------------------------------------------------------- /pyproject.toml: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Tool Configuration 3 | ################################################################################ 4 | 5 | [tool.pytest.ini_options] 6 | testpaths = ["tests"] 7 | markers = [ 8 | "docs: Tests relating to generated documentation!", 9 | "installs: Tests that install packages, e.g. from executing hatch env scripts", 10 | ] 11 | 12 | [tool.ruff] 13 | line-length = 88 14 | 15 | [tool.ruff.lint] 16 | select = ["ALL"] 17 | ignore = [ 18 | "D107", # 'Missing docstring in __init__' ignored because pydoclint wants us to document the class instead. 19 | "D203", # '1 blank line required before class docstring' ignored because we want no blank line. 20 | "D212", # 'Multi-line docstring summary should start at the first line' ignored because we want the summary to start on the second line. 21 | "D407", # 'Missing dashed underline after section' ignored because Google style docstrings don't underline. 22 | "ANN002", # 'Missing type annotation for {*args} in method'. 23 | "ANN003", # 'Missing type annotation for {*kwargs} in method'. 24 | "ANN101", # 'Missing type annotation for {self} in method'. 25 | "ANN102", # 'Missing type annotation for {cls} in classmethod'. 26 | ] 27 | 28 | [tool.ruff.lint.extend-per-file-ignores] 29 | "tests/**/*.py" = [ 30 | "A001", 31 | "A002", 32 | "S101", # 'Use of assert detected' ignored because we are using pytest. 33 | "INP001", # 'Insecure input' ignored because we are testing. 34 | "ANN201", # 'Missing type annotation for {return}' ignored because all tests return `None`. 35 | "S602", 36 | "S603", 37 | "S607", 38 | ] 39 | 40 | [tool.ruff.lint.isort] 41 | case-sensitive = true 42 | lines-after-imports = 1 43 | 44 | ################################################################################ 45 | # Hatch Environments 46 | ################################################################################ 47 | 48 | [tool.hatch.envs.default] 49 | skip-install = true 50 | 51 | [tool.hatch.envs.dev] 52 | description = """ 53 | Describe the environment for local development. 54 | """ 55 | dependencies = [ 56 | "copier ~=9.3", 57 | ] 58 | path = ".venv" 59 | 60 | 61 | [tool.hatch.envs.test] 62 | description = """ 63 | Test the instantiation of the template. 64 | """ 65 | dependencies = [ 66 | "copier ~=9.3", 67 | "GitPython ~=3.1", 68 | "hatch ~=1.12", 69 | "pytest ~=8.3", 70 | "pytest-xdist ~=3.6", 71 | "pre-commit", 72 | "ruamel.yaml>=0.18.0", 73 | "validate-pyproject >=0.22", 74 | "trove-classifiers>=2021.10.20", 75 | "tomli >=2.0.2; python_version<'3.11'", 76 | ] 77 | 78 | [[tool.hatch.envs.test.matrix]] 79 | python = ["3.10", "3.11", "3.12", "3.13"] 80 | 81 | [tool.hatch.envs.test.scripts] 82 | run = "pytest {args:--numprocesses=auto}" 83 | -------------------------------------------------------------------------------- /template/.editorconfig: -------------------------------------------------------------------------------- 1 | # Editor Configuration (http://editorconfig.org) 2 | root = true 3 | 4 | [*] 5 | charset = utf-8 6 | indent_style = space 7 | indent_size = 4 8 | end_of_line = lf 9 | insert_final_newline = true 10 | trim_trailing_whitespace = true 11 | max_line_length = 88 12 | 13 | [*.{json,yml,yaml}] 14 | indent_size = 2 15 | 16 | [*.{md,rst}] 17 | trim_trailing_whitespace = false 18 | 19 | [Makefile] 20 | indent_style = tab 21 | -------------------------------------------------------------------------------- /template/.gitignore: -------------------------------------------------------------------------------- 1 | ### Linux template 2 | *~ 3 | 4 | # temporary files which can be created if a process still has a handle open of a deleted file 5 | .fuse_hidden* 6 | 7 | # KDE directory preferences 8 | .directory 9 | 10 | # Linux trash folder which might appear on any partition or disk 11 | .Trash-* 12 | 13 | # .nfs files are created when an open file is removed but is still being accessed 14 | .nfs* 15 | 16 | ### Windows template 17 | # Windows thumbnail cache files 18 | Thumbs.db 19 | Thumbs.db:encryptable 20 | ehthumbs.db 21 | ehthumbs_vista.db 22 | 23 | # Dump file 24 | *.stackdump 25 | 26 | # Folder config file 27 | [Dd]esktop.ini 28 | 29 | # Recycle Bin used on file shares 30 | $RECYCLE.BIN/ 31 | 32 | # Windows Installer files 33 | *.cab 34 | *.msi 35 | *.msix 36 | *.msm 37 | *.msp 38 | 39 | # Windows shortcuts 40 | *.lnk 41 | 42 | ### JupyterNotebooks template 43 | # gitignore template for Jupyter Notebooks 44 | # website: http://jupyter.org/ 45 | 46 | .ipynb_checkpoints 47 | */.ipynb_checkpoints/* 48 | 49 | # IPython 50 | profile_default/ 51 | ipython_config.py 52 | 53 | # Remove previous ipynb_checkpoints 54 | # git rm -r .ipynb_checkpoints/ 55 | 56 | ### macOS template 57 | # General 58 | .DS_Store 59 | .AppleDouble 60 | .LSOverride 61 | 62 | # Icon must end with two \r 63 | Icon 64 | 65 | # Thumbnails 66 | ._* 67 | 68 | # Files that might appear in the root of a volume 69 | .DocumentRevisions-V100 70 | .fseventsd 71 | .Spotlight-V100 72 | .TemporaryItems 73 | .Trashes 74 | .VolumeIcon.icns 75 | .com.apple.timemachine.donotpresent 76 | 77 | # Directories potentially created on remote AFP share 78 | .AppleDB 79 | .AppleDesktop 80 | Network Trash Folder 81 | Temporary Items 82 | .apdisk 83 | 84 | ### Python template 85 | # Byte-compiled / optimized / DLL files 86 | __pycache__/ 87 | *.py[cod] 88 | *$py.class 89 | 90 | # C extensions 91 | *.so 92 | 93 | # Distribution / packaging 94 | .Python 95 | build/ 96 | develop-eggs/ 97 | dist/ 98 | downloads/ 99 | eggs/ 100 | .eggs/ 101 | lib/ 102 | lib64/ 103 | parts/ 104 | sdist/ 105 | var/ 106 | wheels/ 107 | share/python-wheels/ 108 | *.egg-info/ 109 | .installed.cfg 110 | *.egg 111 | MANIFEST 112 | 113 | # PyInstaller 114 | # Usually these files are written by a python script from a template 115 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 116 | *.manifest 117 | *.spec 118 | 119 | # Installer logs 120 | pip-log.txt 121 | pip-delete-this-directory.txt 122 | 123 | # Unit test / coverage reports 124 | htmlcov/ 125 | .tox/ 126 | .nox/ 127 | .coverage 128 | .coverage.* 129 | .cache 130 | nosetests.xml 131 | coverage.xml 132 | *.cover 133 | *.py,cover 134 | .hypothesis/ 135 | .pytest_cache/ 136 | cover/ 137 | 138 | # Translations 139 | *.mo 140 | *.pot 141 | 142 | # Django stuff: 143 | *.log 144 | local_settings.py 145 | db.sqlite3 146 | db.sqlite3-journal 147 | 148 | # Flask stuff: 149 | instance/ 150 | .webassets-cache 151 | 152 | # Scrapy stuff: 153 | .scrapy 154 | 155 | # Sphinx documentation 156 | docs/_build/ 157 | docs/api 158 | 159 | # PyBuilder 160 | .pybuilder/ 161 | target/ 162 | 163 | # Jupyter Notebook 164 | 165 | # IPython 166 | 167 | # pyenv 168 | # For a library or package, you might want to ignore these files since the code is 169 | # intended to run in multiple environments; otherwise, check them in: 170 | # .python-version 171 | 172 | # pipenv 173 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. 174 | # However, in case of collaboration, if having platform-specific dependencies or dependencies 175 | # having no cross-platform support, pipenv may install dependencies that don't work, or not 176 | # install all needed dependencies. 177 | #Pipfile.lock 178 | 179 | # poetry 180 | # Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control. 181 | # This is especially recommended for binary packages to ensure reproducibility, and is more 182 | # commonly ignored for libraries. 183 | # https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control 184 | #poetry.lock 185 | 186 | # pdm 187 | # Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control. 188 | #pdm.lock 189 | # pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it 190 | # in version control. 191 | # https://pdm.fming.dev/#use-with-ide 192 | .pdm.toml 193 | 194 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm 195 | __pypackages__/ 196 | 197 | # Celery stuff 198 | celerybeat-schedule 199 | celerybeat.pid 200 | 201 | # SageMath parsed files 202 | *.sage.py 203 | 204 | # Environments 205 | .env 206 | .venv 207 | env/ 208 | venv/ 209 | ENV/ 210 | env.bak/ 211 | venv.bak/ 212 | 213 | # Spyder project settings 214 | .spyderproject 215 | .spyproject 216 | 217 | # Rope project settings 218 | .ropeproject 219 | 220 | # mkdocs documentation 221 | /site 222 | 223 | # mypy 224 | .mypy_cache/ 225 | .dmypy.json 226 | dmypy.json 227 | 228 | # Pyre type checker 229 | .pyre/ 230 | 231 | # pytype static type analyzer 232 | .pytype/ 233 | 234 | # Cython debug symbols 235 | cython_debug/ 236 | 237 | # PyCharm 238 | # JetBrains specific template is maintained in a separate JetBrains.gitignore that can 239 | # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore 240 | # and can be added to the global gitignore or merged into this file. For a more nuclear 241 | # option (not recommended) you can uncomment the following to ignore the entire idea folder. 242 | #.idea/ 243 | 244 | # Hatch-VCS 245 | _version.py 246 | -------------------------------------------------------------------------------- /template/.pre-commit-config.yaml.jinja: -------------------------------------------------------------------------------- 1 | repos: 2 | {%- if use_lint %} 3 | - repo: https://github.com/pre-commit/pre-commit-hooks 4 | rev: v4.6.0 5 | hooks: 6 | - id: check-case-conflict 7 | - id: check-ast 8 | - id: check-docstring-first 9 | - id: check-executables-have-shebangs 10 | - id: check-added-large-files 11 | - id: check-case-conflict 12 | - id: check-merge-conflict 13 | - id: check-json 14 | - id: check-toml 15 | - id: check-yaml 16 | - id: debug-statements 17 | - id: end-of-file-fixer 18 | - id: trailing-whitespace 19 | - repo: https://github.com/astral-sh/ruff-pre-commit 20 | rev: v0.6.0 21 | hooks: 22 | - id: ruff 23 | args: ["--fix", "--exit-non-zero-on-fix"] 24 | - id: ruff-format 25 | - repo: https://github.com/jsh9/pydoclint 26 | rev: 0.5.6 27 | hooks: 28 | - id: pydoclint 29 | - repo: https://github.com/python-jsonschema/check-jsonschema 30 | rev: 0.29.1 31 | hooks: 32 | {%- if dev_platform == "GitHub" %} 33 | - id: check-github-workflows 34 | {%- elif dev_platform == "GitLab" %} 35 | - id: check-gitlab-ci 36 | {%- endif %} 37 | - id: check-readthedocs 38 | - repo: https://github.com/executablebooks/mdformat 39 | rev: 0.7.17 40 | hooks: 41 | - id: mdformat 42 | additional_dependencies: 43 | [mdformat-gfm, mdformat-frontmatter, mdformat-footnote] 44 | {%- endif %} 45 | -------------------------------------------------------------------------------- /template/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | All notable changes to this project will be documented in this file. 4 | 5 | The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), 6 | and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). 7 | 8 | ## [Unreleased] 9 | 10 | - Upcoming features and fixes 11 | 12 | ## [0.1.0] - (1979-01-01) 13 | 14 | - First release 15 | -------------------------------------------------------------------------------- /template/CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | We as members, contributors, and leaders pledge to make participation in our 6 | community a harassment-free experience for everyone, regardless of age, body 7 | size, visible or invisible disability, ethnicity, sex characteristics, gender 8 | identity and expression, level of experience, education, socio-economic status, 9 | nationality, personal appearance, race, religion, or sexual identity 10 | and orientation. 11 | 12 | We pledge to act and interact in ways that contribute to an open, welcoming, 13 | diverse, inclusive, and healthy community. 14 | 15 | ## Our Standards 16 | 17 | Examples of behavior that contributes to a positive environment for our 18 | community include: 19 | 20 | - Demonstrating empathy and kindness toward other people 21 | - Being respectful of differing opinions, viewpoints, and experiences 22 | - Giving and gracefully accepting constructive feedback 23 | - Accepting responsibility and apologizing to those affected by our mistakes, 24 | and learning from the experience 25 | - Focusing on what is best not just for us as individuals, but for the 26 | overall community 27 | 28 | Examples of unacceptable behavior include: 29 | 30 | - The use of sexualized language or imagery, and sexual attention or 31 | advances of any kind 32 | - Trolling, insulting or derogatory comments, and personal or political attacks 33 | - Public or private harassment 34 | - Publishing others' private information, such as a physical or email 35 | address, without their explicit permission 36 | - Other conduct which could reasonably be considered inappropriate in a 37 | professional setting 38 | 39 | ## Enforcement Responsibilities 40 | 41 | Community leaders are responsible for clarifying and enforcing our standards of 42 | acceptable behavior and will take appropriate and fair corrective action in 43 | response to any behavior that they deem inappropriate, threatening, offensive, 44 | or harmful. 45 | 46 | Community leaders have the right and responsibility to remove, edit, or reject 47 | comments, commits, code, wiki edits, issues, and other contributions that are 48 | not aligned to this Code of Conduct, and will communicate reasons for moderation 49 | decisions when appropriate. 50 | 51 | ## Scope 52 | 53 | This Code of Conduct applies within all community spaces, and also applies when 54 | an individual is officially representing the community in public spaces. 55 | Examples of representing our community include using an official e-mail address, 56 | posting via an official social media account, or acting as an appointed 57 | representative at an online or offline event. 58 | 59 | ## Enforcement 60 | 61 | [//]: # (TODO: You need to choose whom and how to contact them.) 62 | 63 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 64 | reported to the community leaders responsible for enforcement at 65 | \[INSERT CONTACT METHOD\]. 66 | All complaints will be reviewed and investigated promptly and fairly. 67 | 68 | All community leaders are obligated to respect the privacy and security of the 69 | reporter of any incident. 70 | 71 | ## Enforcement Guidelines 72 | 73 | Community leaders will follow these Community Impact Guidelines in determining 74 | the consequences for any action they deem in violation of this Code of Conduct: 75 | 76 | ### 1. Correction 77 | 78 | **Community Impact**: Use of inappropriate language or other behavior deemed 79 | unprofessional or unwelcome in the community. 80 | 81 | **Consequence**: A private, written warning from community leaders, providing 82 | clarity around the nature of the violation and an explanation of why the 83 | behavior was inappropriate. A public apology may be requested. 84 | 85 | ### 2. Warning 86 | 87 | **Community Impact**: A violation through a single incident or series 88 | of actions. 89 | 90 | **Consequence**: A warning with consequences for continued behavior. No 91 | interaction with the people involved, including unsolicited interaction with 92 | those enforcing the Code of Conduct, for a specified period of time. This 93 | includes avoiding interactions in community spaces as well as external channels 94 | like social media. Violating these terms may lead to a temporary or 95 | permanent ban. 96 | 97 | ### 3. Temporary Ban 98 | 99 | **Community Impact**: A serious violation of community standards, including 100 | sustained inappropriate behavior. 101 | 102 | **Consequence**: A temporary ban from any sort of interaction or public 103 | communication with the community for a specified period of time. No public or 104 | private interaction with the people involved, including unsolicited interaction 105 | with those enforcing the Code of Conduct, is allowed during this period. 106 | Violating these terms may lead to a permanent ban. 107 | 108 | ### 4. Permanent Ban 109 | 110 | **Community Impact**: Demonstrating a pattern of violation of community 111 | standards, including sustained inappropriate behavior, harassment of an 112 | individual, or aggression toward or disparagement of classes of individuals. 113 | 114 | **Consequence**: A permanent ban from any sort of public interaction within 115 | the community. 116 | 117 | ## Attribution 118 | 119 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], 120 | version 2.0, available at 121 | https://www.contributor-covenant.org/version/2/0/code_of_conduct.html. 122 | 123 | Community Impact Guidelines were inspired by [Mozilla's code of conduct 124 | enforcement ladder](https://github.com/mozilla/diversity). 125 | 126 | For answers to common questions about this code of conduct, see the FAQ at 127 | https://www.contributor-covenant.org/faq. Translations are available at 128 | https://www.contributor-covenant.org/translations. 129 | 130 | [homepage]: https://www.contributor-covenant.org 131 | -------------------------------------------------------------------------------- /template/CONTRIBUTING.md.jinja: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | Contributions are welcome, and they are greatly appreciated! Every little bit 4 | helps, and credit will always be given. 5 | 6 | ## Example Contributions 7 | 8 | You can contribute in many ways, for example: 9 | 10 | * [Report bugs](#report-bugs) 11 | * [Fix Bugs](#fix-bugs) 12 | * [Implement Features](#implement-features) 13 | * [Write Documentation](#write-documentation) 14 | * [Submit Feedback](#submit-feedback) 15 | 16 | ### Report Bugs 17 | 18 | Report bugs at {{ dev_platform_url }}/{{ username }}/{{ project_slug }}/issues. 19 | 20 | **If you are reporting a bug, please follow the template guidelines. The more 21 | detailed your report, the easier and thus faster we can help you.** 22 | 23 | ### Fix Bugs 24 | 25 | Look through the {{ dev_platform }} issues for bugs. Anything labelled with `bug` and 26 | `help wanted` is open to whoever wants to implement it. When you decide to work on such 27 | an issue, please assign yourself to it and add a comment that you'll be working on that, 28 | too. If you see another issue without the `help wanted` label, just post a comment, the 29 | maintainers are usually happy for any support that they can get. 30 | 31 | ### Implement Features 32 | 33 | Look through the {{ dev_platform }} issues for features. Anything labelled with 34 | `enhancement` and `help wanted` is open to whoever wants to implement it. As 35 | for [fixing bugs](#fix-bugs), please assign yourself to the issue and add a comment that 36 | you'll be working on that, too. If another enhancement catches your fancy, but it 37 | doesn't have the `help wanted` label, just post a comment, the maintainers are usually 38 | happy for any support that they can get. 39 | 40 | ### Write Documentation 41 | 42 | {{ project_name }} could always use more documentation, whether as 43 | part of the official documentation, in docstrings, or even on the web in blog 44 | posts, articles, and such. Just [open an issue]({{ dev_platform_url }}/{{ username }}/ 45 | {{ project_slug }}/issues) to let us know what you will be working on 46 | so that we can provide you with guidance. 47 | 48 | ### Submit Feedback 49 | 50 | The best way to send feedback is to file an issue at {{ dev_platform_url }}/ 51 | {{ username }}/{{ project_slug }}/issues. If your feedback fits the format of one of 52 | the issue templates, please use that. Remember that this is a volunteer-driven 53 | project and everybody has limited time. 54 | 55 | ## Get Started! 56 | 57 | Ready to contribute? Here's how to set up {{ project_name }} for 58 | local development. 59 | 60 | 1. Fork the {{ dev_platform_url }}/{{ username }}/{{ project_slug }} 61 | repository on {{ dev_platform }}. 62 | 2. Clone your fork locally 63 | 64 | ```shell 65 | git clone git@{{ dev_platform|lower }}.com:your_name_here/{{ project_slug }}.git 66 | ``` 67 | 68 | 3. [Install hatch](https://hatch.pypa.io/latest/install/). 69 | 70 | 4. Create a branch for local development using the default branch (typically `main`) 71 | as a starting 72 | point. Use `fix` or `feat` as a prefix for your branch name. 73 | 74 | ```shell 75 | git checkout main 76 | git checkout -b fix-name-of-your-bugfix 77 | ``` 78 | 79 | Now you can make your changes locally. 80 | 81 | 5. When you're done making changes, apply the quality assurance tools and check 82 | that your changes pass our test suite. This is all included with tox 83 | 84 | ```shell 85 | hatch run test:run 86 | ``` 87 | 88 | 6. Commit your changes and push your branch to {{ dev_platform }}. Please use [semantic 89 | commit messages](https://www.conventionalcommits.org/). 90 | 91 | ```shell 92 | git add . 93 | git commit -m "fix: summarize your changes" 94 | git push -u origin fix-name-of-your-bugfix 95 | ``` 96 | 97 | 7. Open the link displayed in the message when pushing your new branch in order 98 | to submit a pull request. 99 | 100 | ### Pull Request Guidelines 101 | 102 | Before you submit a pull request, check that it meets these guidelines: 103 | 104 | 1. The pull request should include tests. 105 | 2. If the pull request adds functionality, the docs should be updated. Put your 106 | new functionality into a function with a docstring. 107 | 3. Your pull request will automatically be checked by the full test suite. 108 | It needs to pass all of them before it can be considered for merging. 109 | -------------------------------------------------------------------------------- /template/README.md.jinja: -------------------------------------------------------------------------------- 1 | # {{ project_name }} 2 | 3 | | | | 4 | |---|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| 5 | | Package | [![Latest PyPI Version](https://img.shields.io/pypi/v/{{project_slug}}.svg)](https://pypi.org/project/{{project_slug}}/) [![Supported Python Versions](https://img.shields.io/pypi/pyversions/{{project_slug}}.svg)](https://pypi.org/project/{{project_slug}}/) [![Documentation](https://readthedocs.org/projects/{{project_slug}}/badge/?version=latest)](https://{{project_slug}}.readthedocs.io/en/latest/?badge=latest) | 6 | | Meta | [![{{ license }}](https://img.shields.io/pypi/l/{{project_slug}}.svg)](LICENSE) [![Code of Conduct](https://img.shields.io/badge/Contributor%20Covenant-v2.0%20adopted-ff69b4.svg)](.github/CODE_OF_CONDUCT.md) [![Checked with mypy](https://www.mypy-lang.org/static/mypy_badge.svg)](https://mypy-lang.org/) [![Code Style Black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/ambv/black) [![Linting: Ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/charliermarsh/ruff/main/assets/badge/v2.json)](https://github.com/astral-sh/ruff) | 7 | | Automation | | 8 | 9 | _{{ package_description }}_ 10 | 11 | ## Copyright 12 | 13 | {% include pathjoin("includes", "licenses", "stub.md.jinja") %} 14 | -------------------------------------------------------------------------------- /template/pyproject.toml.jinja: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Build Configuration 3 | ################################################################################ 4 | 5 | [build-system] 6 | build-backend = "hatchling.build" 7 | requires = ["hatchling"{% if use_vcs_version %}, "hatch-vcs"{% endif %}] 8 | 9 | ################################################################################ 10 | # Project Configuration 11 | ################################################################################ 12 | 13 | [project] 14 | name = "{{ package_name }}" 15 | {% if use_vcs_version %} 16 | dynamic = ["version"] 17 | {% else %} 18 | version = "0.1.0" 19 | {% endif %} 20 | {%- set wrapped_description = package_description | trim | wordwrap(width=88) %} 21 | description = {% if "\n" in wrapped_description -%} 22 | """ 23 | {{ wrapped_description }} 24 | """ 25 | {%- else -%} 26 | "{{ wrapped_description }}" 27 | {%- endif %} 28 | authors = [ 29 | { name = "{{ author_name }}", email = "{{ author_email }}" }, 30 | ] 31 | license = "{{ license }}" 32 | readme = {"file" = "README.md", "content-type" = "text/markdown"} 33 | # Please consult https://pypi.org/classifiers/ for a full list. 34 | classifiers = [ 35 | "Development Status :: 2 - Pre-Alpha", 36 | "Intended Audience :: Science/Research", 37 | {%- if license == "MIT" %} 38 | "License :: OSI Approved :: MIT License", 39 | {% elif license == "BSD-3-Clause" %} 40 | "License :: OSI Approved :: BSD License", 41 | {% elif license == "Apache-2.0" %} 42 | "License :: OSI Approved :: Apache Software License", 43 | {% endif -%} 44 | "Operating System :: OS Independent", 45 | "Programming Language :: Python :: 3 :: Only", 46 | {%- if use_types %} 47 | "Typing :: Typed", 48 | {%- endif %} 49 | ] 50 | # TODO: add keywords 51 | keywords = [] 52 | # TODO: add dependencies 53 | dependencies = [] 54 | 55 | [project.urls] 56 | {%- if use_git %} 57 | Homepage = "{{ dev_platform_url }}/{{ username }}/{{ project_slug }}" 58 | "Source Code" = "{{ dev_platform_url }}/{{ username }}/{{ project_slug }}" 59 | "Bug Tracker" = "{{ dev_platform_url }}/{{ username }}/{{ project_slug }}/issues" 60 | {%- endif %} 61 | Documentation = "https://{{ project_slug }}.readthedocs.io" 62 | Download = "https://pypi.org/project/{{ project_slug }}/#files" 63 | 64 | [project.optional-dependencies] 65 | dev = [ 66 | "hatch", 67 | "pre-commit", 68 | {%- if not use_hatch_envs %} 69 | "{{ package_name }}[ 70 | {%- if documentation!="" %}docs,{% endif -%} 71 | {%- if use_test %}tests,{% endif -%} 72 | {%- if use_lint %}style,{% endif -%} 73 | {%- if use_types %}types,{% endif -%} 74 | audit]", 75 | {%- endif %} 76 | ] 77 | {%- if not use_hatch_envs %} 78 | {% include pathjoin('includes', 'pyproject', 'deps-pep-621.toml.jinja') %} 79 | {%- endif %} 80 | ################################################################################ 81 | # Tool Configuration 82 | ################################################################################ 83 | 84 | [tool.hatch.build] 85 | only-packages = true 86 | 87 | [tool.hatch.build.targets.wheel] 88 | packages = ["src/{{ package_name }}"] 89 | 90 | {%- if use_vcs_version %} 91 | [tool.hatch.build.hooks.vcs] 92 | version-file = "src/{{ package_name }}/_version.py" 93 | 94 | [tool.hatch.version] 95 | source = "vcs" 96 | {%- endif %} 97 | 98 | {%- if use_test %} 99 | [tool.pytest.ini_options] 100 | testpaths = ["tests"] 101 | markers = ["raises"] 102 | 103 | [tool.coverage.paths] 104 | source = [ 105 | "src/{{ package_name }}", 106 | "*/site-packages/{{ package_name }}", 107 | ] 108 | 109 | [tool.coverage.run] 110 | branch = true 111 | parallel = true 112 | {%- if use_vcs_version %} 113 | omit = [ 114 | "src/{{ package_name }}/_version.py", 115 | ] 116 | {%- endif %} 117 | 118 | [tool.coverage.report] 119 | exclude_lines = ["pragma: no cover"] 120 | precision = 2 121 | {%- endif %} 122 | 123 | {%- if use_lint %} 124 | [tool.ruff] 125 | line-length = 88 126 | 127 | [tool.ruff.lint] 128 | select = ["ALL"] 129 | ignore = [ 130 | "D107", # 'Missing docstring in __init__' ignored because pydoclint wants us to document the class instead. 131 | "D203", # '1 blank line required before class docstring' ignored because we want no blank line. 132 | "D212", # 'Multi-line docstring summary should start at the first line' ignored because we want the summary to start on the second line. 133 | "D407", # 'Missing dashed underline after section' ignored because Google style docstrings don't underline. 134 | "ANN002", # 'Missing type annotation for {*args} in method'. 135 | "ANN003", # 'Missing type annotation for {*kwargs} in method'. 136 | "ANN101", # 'Missing type annotation for {self} in method'. 137 | "ANN102", # 'Missing type annotation for {cls} in classmethod'. 138 | ] 139 | exclude = [ 140 | {%- if use_vcs_version %} 141 | "src/{{ package_name }}/_version.py", 142 | {%- endif %} 143 | {%- if documentation == "sphinx" %} 144 | "docs/conf.py", 145 | {%- endif %} 146 | ] 147 | 148 | [tool.ruff.lint.extend-per-file-ignores] 149 | "__init__.py" = [ 150 | "E401", # 'Multiple imports on one line' 151 | "E402", # 'Module level import not at top of file' 152 | "F401", # 'Imported but unused' 153 | "I001", # 'Import block is un-sorted or un-formatted' ignored because we may have to import in a particular, not-alphabetical order. 154 | ] 155 | "tests/**/*.py" = [ 156 | "S101", # 'Use of assert detected' ignored because we are using pytest. 157 | "INP001", # 'Insecure input' ignored because we are testing. 158 | "ANN201", # 'Missing type annotation for {return}' ignored because all tests return `None`. 159 | ] 160 | 161 | [tool.ruff.lint.isort] 162 | case-sensitive = true 163 | known-first-party = ["src", "{{ package_name }}"] 164 | lines-after-imports = 1 165 | 166 | [tool.pydoclint] 167 | style = "numpy" 168 | arg-type-hints-in-docstring = false 169 | check-return-types = false 170 | check-yield-types = false 171 | {%- if use_vcs_version %} 172 | exclude = "_version.py" 173 | {%- endif %} 174 | {%- endif %} 175 | 176 | {%- if use_types %} 177 | # TODO: Adjust mypy configuration. 178 | #[tool.mypy] 179 | #plugins = [ 180 | # "pydantic.mypy", 181 | #] 182 | 183 | # Stop mypy from complaining about missing types from imports. 184 | #[[tool.mypy.overrides]] 185 | #module = [ 186 | # "pandas", 187 | #] 188 | #ignore_missing_imports = true 189 | 190 | #[tool.pydantic-mypy] 191 | #init_forbid_extra = true 192 | #init_typed = true 193 | #warn_required_dynamic_aliases = true 194 | {%- endif %} 195 | 196 | {%- if use_hatch_envs %} 197 | ################################################################################ 198 | # Hatch Environments 199 | ################################################################################ 200 | 201 | {%- if use_lint %} 202 | [tool.hatch.envs.style] 203 | description = """Check the style of the codebase.""" 204 | dependencies = [ 205 | "pydoclint", 206 | "ruff", 207 | ] 208 | detached = true 209 | 210 | [tool.hatch.envs.style.scripts] 211 | docstrings = "pydoclint src/ tests/" 212 | code = "ruff check {args}" 213 | format = "ruff format {args}" 214 | check = ["docstrings", "code"] 215 | {%- endif %} 216 | 217 | [tool.hatch.envs.audit] 218 | description = """Check dependencies for security vulnerabilities.""" 219 | extra-dependencies = [ 220 | "pip-audit", 221 | ] 222 | 223 | [tool.hatch.envs.audit.scripts] 224 | check = ["pip-audit"] 225 | 226 | {%- if use_types %} 227 | [tool.hatch.envs.types] 228 | description = """Check the static types of the codebase.""" 229 | dependencies = [ 230 | "mypy", 231 | ] 232 | 233 | [tool.hatch.envs.types.scripts] 234 | check = "mypy src/{{ package_name }}" 235 | {%- endif %} 236 | 237 | {%- if documentation != "" %} 238 | [tool.hatch.envs.docs] 239 | description = """Build or serve the documentation.""" 240 | {%- if documentation == "mkdocs" %} 241 | extra-dependencies = [ 242 | "mkdocs-material ~=9.5", 243 | "mkdocstrings[python] ~=0.24", 244 | "mkdocs-awesome-pages-plugin ~=2.9", 245 | ] 246 | {%- elif documentation == "sphinx" %} 247 | python = "3.10" 248 | dependencies = [ 249 | "pydata_sphinx_theme ~=0.16", 250 | "myst-parser ~=4.0", 251 | "Sphinx ~=8.0", 252 | "sphinx-autobuild ==2024.10.3" 253 | ] 254 | {%- endif %} 255 | 256 | [tool.hatch.envs.docs.scripts] 257 | {%- if documentation == "mkdocs" %} 258 | build = "mkdocs build {args:--clean --strict}" 259 | serve = "mkdocs serve {args}" 260 | {%- endif %} 261 | {%- if documentation == "sphinx" %} 262 | build = ["sphinx-apidoc -o docs/api src/{{ package_name}}", "sphinx-build {args:-W -b html docs docs/_build}"] 263 | serve = ["sphinx-apidoc -o docs/api src/{{ package_name}}", "sphinx-autobuild docs --watch src/{{ package_name }} {args:-b html docs/_build/serve}"] 264 | {%- endif %} 265 | {%- endif %} 266 | 267 | [tool.hatch.envs.install] 268 | description = """Test the installation the package.""" 269 | dependencies = [ 270 | "pip", 271 | "twine", 272 | ] 273 | detached = true 274 | 275 | [tool.hatch.envs.install.scripts] 276 | check = [ 277 | "pip check", 278 | "hatch build {args:--clean}", 279 | "twine check dist/*", 280 | ] 281 | 282 | {%- if use_test %} 283 | [tool.hatch.envs.test] 284 | description = """Run the test suite.""" 285 | extra-dependencies = [ 286 | "pytest", 287 | "pytest-cov", 288 | "pytest-raises", 289 | "pytest-randomly", 290 | "pytest-xdist", 291 | ] 292 | 293 | [[tool.hatch.envs.test.matrix]] 294 | python = ["3.10", "3.11", "3.12", "3.13"] 295 | 296 | [tool.hatch.envs.test.scripts] 297 | run = "pytest {args:--cov={{ package_name }} --cov-report=term-missing}" 298 | {%- endif %} 299 | {%- endif %} 300 | -------------------------------------------------------------------------------- /template/src/{{ package_name }}/__init__.py.jinja: -------------------------------------------------------------------------------- 1 | {% include pathjoin("includes", "licenses", "header.txt.jinja") %} 2 | 3 | """Provide top level symbols.""" 4 | -------------------------------------------------------------------------------- /template/src/{{ package_name }}/{% if use_types %}py.typed{% endif %}: -------------------------------------------------------------------------------- 1 | # PEP-561 Support File. 2 | # "Package maintainers who wish to support type checking of their code MUST add a marker file named py.typed to their package supporting typing". 3 | -------------------------------------------------------------------------------- /template/{% if documentation != '' %}.readthedocs.yaml{% endif %}.jinja: -------------------------------------------------------------------------------- 1 | # Read the Docs configuration file 2 | # See https://docs.readthedocs.io/en/stable/config-file/v2.html for details 3 | version: 2 4 | 5 | build: 6 | os: ubuntu-lts-latest 7 | tools: 8 | python: "3.12" 9 | commands: 10 | - pip install --upgrade pip setuptools wheel 11 | - pip install hatch 12 | {%- if documentation == "mkdocs" %} 13 | - hatch run docs:build -- --strict --site-dir "${READTHEDOCS_OUTPUT}/html" 14 | 15 | mkdocs: 16 | configuration: mkdocs.yml 17 | {%- elif documentation == "sphinx" %} 18 | - hatch run docs:build 19 | {%- endif %} 20 | -------------------------------------------------------------------------------- /template/{% if documentation == 'mkdocs' %}docs{% endif %}/index.md.jinja: -------------------------------------------------------------------------------- 1 | # {{ project_name }} 2 | 3 | {{ package_description }} 4 | 5 | ## Copyright 6 | 7 | {%- with license_path = "../LICENSE" -%} 8 | {% include pathjoin("includes", "licenses", "stub.md.jinja") %} 9 | {%- endwith -%} -------------------------------------------------------------------------------- /template/{% if documentation == 'mkdocs' %}mkdocs.yml{% endif %}.jinja: -------------------------------------------------------------------------------- 1 | site_name: {{ project_name }} 2 | site_description: {{ package_description }} 3 | site_author: {{ author_name }} 4 | site_url: https://{{ project_slug }}.readthedocs.io/ 5 | 6 | markdown_extensions: 7 | - admonition 8 | - toc: 9 | permalink: true 10 | - pymdownx.highlight: 11 | anchor_linenums: true 12 | - pymdownx.inlinehilite 13 | - pymdownx.superfences: 14 | - pymdownx.emoji: 15 | emoji_index: !!python/name:material.extensions.emoji.twemoji 16 | emoji_generator: !!python/name:material.extensions.emoji.to_svg 17 | 18 | theme: 19 | features: 20 | - content.code.annotate 21 | - navigation.indexes 22 | - navigation.instant 23 | - navigation.tracking 24 | - navigation.top 25 | name: material 26 | palette: 27 | - media: "(prefers-color-scheme: light)" 28 | scheme: default 29 | primary: green 30 | accent: light green 31 | toggle: 32 | icon: material/weather-night 33 | name: Switch to dark mode 34 | - media: "(prefers-color-scheme: dark)" 35 | scheme: slate 36 | primary: green 37 | accent: light green 38 | toggle: 39 | icon: material/weather-sunny 40 | name: Switch to light mode 41 | 42 | plugins: 43 | - search 44 | - mkdocstrings: 45 | handlers: 46 | python: 47 | paths: [src] 48 | options: 49 | show_submodules: true 50 | show_category_heading: true 51 | show_if_no_docstring: true 52 | show_signature_annotations: true 53 | default_handler: python 54 | - awesome-pages 55 | 56 | extra: 57 | social: 58 | - icon: fontawesome/brands/{{ dev_platform | lower }} 59 | link: {{ dev_platform_url }}/{{ username }} 60 | name: {{ author_name }} 61 | 62 | copyright: Copyright © {{ year }} {{ copyright_holder }} 63 | 64 | repo_url: {{ dev_platform_url }}/{{ username }}/{{ project_slug }} 65 | repo_name: {{ username }}/{{ project_slug }} 66 | 67 | watch: 68 | - src/{{ package_name }} 69 | -------------------------------------------------------------------------------- /template/{% if documentation == 'sphinx' %}docs{% endif %}/conf.py.jinja: -------------------------------------------------------------------------------- 1 | # 2 | # {{ project_name }} documentation build configuration file 3 | # 4 | import importlib.metadata 5 | 6 | # -- General configuration ----------------------------------------------------- 7 | 8 | # Add any Sphinx extension module names here, as strings. They can be extensions 9 | # coming with Sphinx (named 'sphinx.ext.*') or your custom ones. 10 | extensions = [ 11 | "myst_parser", 12 | "sphinx.ext.intersphinx", 13 | "sphinx.ext.autodoc", 14 | ] 15 | 16 | # The suffix of source filenames. 17 | source_suffix = ".rst" 18 | 19 | # The master toctree document. 20 | master_doc = "index" 21 | 22 | # General information about the project. 23 | project = "{{ project_name }}" 24 | copyright = "Copyright © {{ year }} {{ copyright_holder }}" 25 | html_show_sphinx = False 26 | 27 | # The version info for the project you're documenting, acts as replacement for 28 | # |version| and |release|, also used in various other places throughout the 29 | # built documents. 30 | version = importlib.metadata.version("{{ package_name }}") 31 | 32 | # The name of the Pygments (syntax highlighting) style to use. 33 | pygments_style = "default" 34 | 35 | # The language for content autogenerated by Sphinx. Refer to documentation 36 | # for a list of supported languages. 37 | # 38 | # This is also used if you do content translation via gettext catalogs. 39 | # Usually you set "language" from the command line for these cases. 40 | language = "en" 41 | 42 | # -- Options for extensions ---------------------------------------------------- 43 | # https://myst-parser.readthedocs.io/en/latest/syntax/optional.html 44 | myst_enable_extensions = ["html_image"] 45 | 46 | 47 | # -- Options for HTML output --------------------------------------------------- 48 | 49 | html_theme = "pydata_sphinx_theme" 50 | 51 | # The name for this set of Sphinx documents. If None, it defaults to 52 | # " v documentation". 53 | # html_title = None 54 | 55 | # A shorter title for the navigation bar. Default is the same as html_title. 56 | # html_short_title = None 57 | 58 | # The name of an image file (relative to this directory) to place at the top 59 | # of the sidebar. 60 | # html_logo = None 61 | 62 | # The name of an image file (within the static path) to use as favicon of the 63 | # docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 64 | # pixels large. 65 | # html_favicon = None 66 | 67 | # Add any paths that contain custom static files (such as style sheets) here, 68 | # relative to this directory. They are copied after the builtin static files, 69 | # so a file named "default.css" will overwrite the builtin "default.css". 70 | # html_static_path = ['_static'] 71 | 72 | # Custom sidebar templates, maps document names to template names. 73 | # html_sidebars = {} 74 | 75 | # Additional templates that should be rendered to pages, maps page names to 76 | # template names. 77 | # html_additional_pages = {} 78 | 79 | # If true, links to the reST sources are added to the pages. 80 | # html_show_sourcelink = True 81 | 82 | # If true, an OpenSearch description file will be output, and all pages will 83 | # contain a tag referring to it. The value of this option must be the 84 | # base URL from which the finished HTML is served. 85 | # html_use_opensearch = '' 86 | 87 | # If nonempty, this is the file name suffix for HTML files (e.g. ".xhtml"). 88 | # html_file_suffix = '' 89 | 90 | # Output file base name for HTML help builder. 91 | htmlhelp_basename = "{{ project_name }}_doc" 92 | 93 | 94 | intersphinx_mapping = { 95 | "python": ("https://docs.python.org/", None), 96 | } 97 | -------------------------------------------------------------------------------- /template/{% if documentation == 'sphinx' %}docs{% endif %}/index.md.jinja: -------------------------------------------------------------------------------- 1 | # {{ project_name }} 2 | 3 | ## Overview 4 | 5 | {{ package_description }} 6 | 7 | [API Documentation](./api/modules.rst) 8 | 9 | ## Copyright 10 | 11 | {% with license_path = False -%} 12 | {% include pathjoin("includes", "licenses", "stub.md.jinja") %} 13 | {%- endwith %} 14 | 15 | ```{toctree} 16 | :hidden: 17 | ./api/modules.rst 18 | ``` 19 | -------------------------------------------------------------------------------- /template/{% if license == 'Apache-2.0' %}LICENSE{% endif %}.jinja: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | https://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | -------------------------------------------------------------------------------- /template/{% if license == 'BSD-3-Clause' %}LICENSE{% endif %}.jinja: -------------------------------------------------------------------------------- 1 | Copyright (c) {{ year }} {{ copyright_holder }} 2 | 3 | Redistribution and use in source and binary forms, with or without modification, 4 | are permitted provided that the following conditions are met: 5 | 6 | 1. Redistributions of source code must retain the above copyright notice, 7 | this list of conditions and the following disclaimer. 8 | 2. Redistributions in binary form must reproduce the above copyright notice, 9 | this list of conditions and the following disclaimer in the documentation 10 | and/or other materials provided with the distribution. 11 | 3. Neither the name of the copyright holder nor the names of its 12 | contributors may be used to endorse or promote products derived from this 13 | software without specific prior written permission. 14 | 15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 16 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR 19 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 22 | ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | -------------------------------------------------------------------------------- /template/{% if license == 'EUPL-1.2' %}LICENSE{% endif %}.jinja: -------------------------------------------------------------------------------- 1 | EUROPEAN UNION PUBLIC LICENCE v. 1.2 2 | EUPL © the European Union 2007, 2016 3 | 4 | This European Union Public Licence (the ‘EUPL’) applies to the Work (as defined 5 | below) which is provided under the terms of this Licence. Any use of the Work, 6 | other than as authorised under this Licence is prohibited (to the extent such 7 | use is covered by a right of the copyright holder of the Work). 8 | 9 | The Work is provided under the terms of this Licence when the Licensor (as 10 | defined below) has placed the following notice immediately following the 11 | copyright notice for the Work: 12 | 13 | Licensed under the EUPL 14 | 15 | or has expressed by any other means his willingness to license under the EUPL. 16 | 17 | 1. Definitions 18 | 19 | In this Licence, the following terms have the following meaning: 20 | 21 | - ‘The Licence’: this Licence. 22 | 23 | - ‘The Original Work’: the work or software distributed or communicated by the 24 | Licensor under this Licence, available as Source Code and also as Executable 25 | Code as the case may be. 26 | 27 | - ‘Derivative Works’: the works or software that could be created by the 28 | Licensee, based upon the Original Work or modifications thereof. This Licence 29 | does not define the extent of modification or dependence on the Original Work 30 | required in order to classify a work as a Derivative Work; this extent is 31 | determined by copyright law applicable in the country mentioned in Article 15. 32 | 33 | - ‘The Work’: the Original Work or its Derivative Works. 34 | 35 | - ‘The Source Code’: the human-readable form of the Work which is the most 36 | convenient for people to study and modify. 37 | 38 | - ‘The Executable Code’: any code which has generally been compiled and which is 39 | meant to be interpreted by a computer as a program. 40 | 41 | - ‘The Licensor’: the natural or legal person that distributes or communicates 42 | the Work under the Licence. 43 | 44 | - ‘Contributor(s)’: any natural or legal person who modifies the Work under the 45 | Licence, or otherwise contributes to the creation of a Derivative Work. 46 | 47 | - ‘The Licensee’ or ‘You’: any natural or legal person who makes any usage of 48 | the Work under the terms of the Licence. 49 | 50 | - ‘Distribution’ or ‘Communication’: any act of selling, giving, lending, 51 | renting, distributing, communicating, transmitting, or otherwise making 52 | available, online or offline, copies of the Work or providing access to its 53 | essential functionalities at the disposal of any other natural or legal 54 | person. 55 | 56 | 2. Scope of the rights granted by the Licence 57 | 58 | The Licensor hereby grants You a worldwide, royalty-free, non-exclusive, 59 | sublicensable licence to do the following, for the duration of copyright vested 60 | in the Original Work: 61 | 62 | - use the Work in any circumstance and for all usage, 63 | - reproduce the Work, 64 | - modify the Work, and make Derivative Works based upon the Work, 65 | - communicate to the public, including the right to make available or display 66 | the Work or copies thereof to the public and perform publicly, as the case may 67 | be, the Work, 68 | - distribute the Work or copies thereof, 69 | - lend and rent the Work or copies thereof, 70 | - sublicense rights in the Work or copies thereof. 71 | 72 | Those rights can be exercised on any media, supports and formats, whether now 73 | known or later invented, as far as the applicable law permits so. 74 | 75 | In the countries where moral rights apply, the Licensor waives his right to 76 | exercise his moral right to the extent allowed by law in order to make effective 77 | the licence of the economic rights here above listed. 78 | 79 | The Licensor grants to the Licensee royalty-free, non-exclusive usage rights to 80 | any patents held by the Licensor, to the extent necessary to make use of the 81 | rights granted on the Work under this Licence. 82 | 83 | 3. Communication of the Source Code 84 | 85 | The Licensor may provide the Work either in its Source Code form, or as 86 | Executable Code. If the Work is provided as Executable Code, the Licensor 87 | provides in addition a machine-readable copy of the Source Code of the Work 88 | along with each copy of the Work that the Licensor distributes or indicates, in 89 | a notice following the copyright notice attached to the Work, a repository where 90 | the Source Code is easily and freely accessible for as long as the Licensor 91 | continues to distribute or communicate the Work. 92 | 93 | 4. Limitations on copyright 94 | 95 | Nothing in this Licence is intended to deprive the Licensee of the benefits from 96 | any exception or limitation to the exclusive rights of the rights owners in the 97 | Work, of the exhaustion of those rights or of other applicable limitations 98 | thereto. 99 | 100 | 5. Obligations of the Licensee 101 | 102 | The grant of the rights mentioned above is subject to some restrictions and 103 | obligations imposed on the Licensee. Those obligations are the following: 104 | 105 | Attribution right: The Licensee shall keep intact all copyright, patent or 106 | trademarks notices and all notices that refer to the Licence and to the 107 | disclaimer of warranties. The Licensee must include a copy of such notices and a 108 | copy of the Licence with every copy of the Work he/she distributes or 109 | communicates. The Licensee must cause any Derivative Work to carry prominent 110 | notices stating that the Work has been modified and the date of modification. 111 | 112 | Copyleft clause: If the Licensee distributes or communicates copies of the 113 | Original Works or Derivative Works, this Distribution or Communication will be 114 | done under the terms of this Licence or of a later version of this Licence 115 | unless the Original Work is expressly distributed only under this version of the 116 | Licence — for example by communicating ‘EUPL v. 1.2 only’. The Licensee 117 | (becoming Licensor) cannot offer or impose any additional terms or conditions on 118 | the Work or Derivative Work that alter or restrict the terms of the Licence. 119 | 120 | Compatibility clause: If the Licensee Distributes or Communicates Derivative 121 | Works or copies thereof based upon both the Work and another work licensed under 122 | a Compatible Licence, this Distribution or Communication can be done under the 123 | terms of this Compatible Licence. For the sake of this clause, ‘Compatible 124 | Licence’ refers to the licences listed in the appendix attached to this Licence. 125 | Should the Licensee's obligations under the Compatible Licence conflict with 126 | his/her obligations under this Licence, the obligations of the Compatible 127 | Licence shall prevail. 128 | 129 | Provision of Source Code: When distributing or communicating copies of the Work, 130 | the Licensee will provide a machine-readable copy of the Source Code or indicate 131 | a repository where this Source will be easily and freely available for as long 132 | as the Licensee continues to distribute or communicate the Work. 133 | 134 | Legal Protection: This Licence does not grant permission to use the trade names, 135 | trademarks, service marks, or names of the Licensor, except as required for 136 | reasonable and customary use in describing the origin of the Work and 137 | reproducing the content of the copyright notice. 138 | 139 | 6. Chain of Authorship 140 | 141 | The original Licensor warrants that the copyright in the Original Work granted 142 | hereunder is owned by him/her or licensed to him/her and that he/she has the 143 | power and authority to grant the Licence. 144 | 145 | Each Contributor warrants that the copyright in the modifications he/she brings 146 | to the Work are owned by him/her or licensed to him/her and that he/she has the 147 | power and authority to grant the Licence. 148 | 149 | Each time You accept the Licence, the original Licensor and subsequent 150 | Contributors grant You a licence to their contributions to the Work, under the 151 | terms of this Licence. 152 | 153 | 7. Disclaimer of Warranty 154 | 155 | The Work is a work in progress, which is continuously improved by numerous 156 | Contributors. It is not a finished work and may therefore contain defects or 157 | ‘bugs’ inherent to this type of development. 158 | 159 | For the above reason, the Work is provided under the Licence on an ‘as is’ basis 160 | and without warranties of any kind concerning the Work, including without 161 | limitation merchantability, fitness for a particular purpose, absence of defects 162 | or errors, accuracy, non-infringement of intellectual property rights other than 163 | copyright as stated in Article 6 of this Licence. 164 | 165 | This disclaimer of warranty is an essential part of the Licence and a condition 166 | for the grant of any rights to the Work. 167 | 168 | 8. Disclaimer of Liability 169 | 170 | Except in the cases of wilful misconduct or damages directly caused to natural 171 | persons, the Licensor will in no event be liable for any direct or indirect, 172 | material or moral, damages of any kind, arising out of the Licence or of the use 173 | of the Work, including without limitation, damages for loss of goodwill, work 174 | stoppage, computer failure or malfunction, loss of data or any commercial 175 | damage, even if the Licensor has been advised of the possibility of such damage. 176 | However, the Licensor will be liable under statutory product liability laws as 177 | far such laws apply to the Work. 178 | 179 | 9. Additional agreements 180 | 181 | While distributing the Work, You may choose to conclude an additional agreement, 182 | defining obligations or services consistent with this Licence. However, if 183 | accepting obligations, You may act only on your own behalf and on your sole 184 | responsibility, not on behalf of the original Licensor or any other Contributor, 185 | and only if You agree to indemnify, defend, and hold each Contributor harmless 186 | for any liability incurred by, or claims asserted against such Contributor by 187 | the fact You have accepted any warranty or additional liability. 188 | 189 | 10. Acceptance of the Licence 190 | 191 | The provisions of this Licence can be accepted by clicking on an icon ‘I agree’ 192 | placed under the bottom of a window displaying the text of this Licence or by 193 | affirming consent in any other similar way, in accordance with the rules of 194 | applicable law. Clicking on that icon indicates your clear and irrevocable 195 | acceptance of this Licence and all of its terms and conditions. 196 | 197 | Similarly, you irrevocably accept this Licence and all of its terms and 198 | conditions by exercising any rights granted to You by Article 2 of this Licence, 199 | such as the use of the Work, the creation by You of a Derivative Work or the 200 | Distribution or Communication by You of the Work or copies thereof. 201 | 202 | 11. Information to the public 203 | 204 | In case of any Distribution or Communication of the Work by means of electronic 205 | communication by You (for example, by offering to download the Work from a 206 | remote location) the distribution channel or media (for example, a website) must 207 | at least provide to the public the information requested by the applicable law 208 | regarding the Licensor, the Licence and the way it may be accessible, concluded, 209 | stored and reproduced by the Licensee. 210 | 211 | 12. Termination of the Licence 212 | 213 | The Licence and the rights granted hereunder will terminate automatically upon 214 | any breach by the Licensee of the terms of the Licence. 215 | 216 | Such a termination will not terminate the licences of any person who has 217 | received the Work from the Licensee under the Licence, provided such persons 218 | remain in full compliance with the Licence. 219 | 220 | 13. Miscellaneous 221 | 222 | Without prejudice of Article 9 above, the Licence represents the complete 223 | agreement between the Parties as to the Work. 224 | 225 | If any provision of the Licence is invalid or unenforceable under applicable 226 | law, this will not affect the validity or enforceability of the Licence as a 227 | whole. Such provision will be construed or reformed so as necessary to make it 228 | valid and enforceable. 229 | 230 | The European Commission may publish other linguistic versions or new versions of 231 | this Licence or updated versions of the Appendix, so far this is required and 232 | reasonable, without reducing the scope of the rights granted by the Licence. New 233 | versions of the Licence will be published with a unique version number. 234 | 235 | All linguistic versions of this Licence, approved by the European Commission, 236 | have identical value. Parties can take advantage of the linguistic version of 237 | their choice. 238 | 239 | 14. Jurisdiction 240 | 241 | Without prejudice to specific agreement between parties, 242 | 243 | - any litigation resulting from the interpretation of this License, arising 244 | between the European Union institutions, bodies, offices or agencies, as a 245 | Licensor, and any Licensee, will be subject to the jurisdiction of the Court 246 | of Justice of the European Union, as laid down in article 272 of the Treaty on 247 | the Functioning of the European Union, 248 | 249 | - any litigation arising between other parties and resulting from the 250 | interpretation of this License, will be subject to the exclusive jurisdiction 251 | of the competent court where the Licensor resides or conducts its primary 252 | business. 253 | 254 | 15. Applicable Law 255 | 256 | Without prejudice to specific agreement between parties, 257 | 258 | - this Licence shall be governed by the law of the European Union Member State 259 | where the Licensor has his seat, resides or has his registered office, 260 | 261 | - this licence shall be governed by Belgian law if the Licensor has no seat, 262 | residence or registered office inside a European Union Member State. 263 | 264 | Appendix 265 | 266 | ‘Compatible Licences’ according to Article 5 EUPL are: 267 | 268 | - GNU General Public License (GPL) v. 2, v. 3 269 | - GNU Affero General Public License (AGPL) v. 3 270 | - Open Software License (OSL) v. 2.1, v. 3.0 271 | - Eclipse Public License (EPL) v. 1.0 272 | - CeCILL v. 2.0, v. 2.1 273 | - Mozilla Public Licence (MPL) v. 2 274 | - GNU Lesser General Public Licence (LGPL) v. 2.1, v. 3 275 | - Creative Commons Attribution-ShareAlike v. 3.0 Unported (CC BY-SA 3.0) for 276 | works other than software 277 | - European Union Public Licence (EUPL) v. 1.1, v. 1.2 278 | - Québec Free and Open-Source Licence — Reciprocity (LiLiQ-R) or Strong 279 | Reciprocity (LiLiQ-R+). 280 | 281 | The European Commission may update this Appendix to later versions of the above 282 | licences without producing a new version of the EUPL, as long as they provide 283 | the rights granted in Article 2 of this Licence and protect the covered Source 284 | Code from exclusive appropriation. 285 | 286 | All other changes or additions to this Appendix require the production of a new 287 | EUPL version. 288 | -------------------------------------------------------------------------------- /template/{% if license == 'GPL-3.0-only' %}LICENSE{% endif %}.jinja: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 3, 29 June 2007 3 | 4 | Copyright (C) 2007 Free Software Foundation, Inc. 5 | Everyone is permitted to copy and distribute verbatim copies 6 | of this license document, but changing it is not allowed. 7 | 8 | Preamble 9 | 10 | The GNU General Public License is a free, copyleft license for 11 | software and other kinds of works. 12 | 13 | The licenses for most software and other practical works are designed 14 | to take away your freedom to share and change the works. By contrast, 15 | the GNU General Public License is intended to guarantee your freedom to 16 | share and change all versions of a program--to make sure it remains free 17 | software for all its users. We, the Free Software Foundation, use the 18 | GNU General Public License for most of our software; it applies also to 19 | any other work released this way by its authors. You can apply it to 20 | your programs, too. 21 | 22 | When we speak of free software, we are referring to freedom, not 23 | price. Our General Public Licenses are designed to make sure that you 24 | have the freedom to distribute copies of free software (and charge for 25 | them if you wish), that you receive source code or can get it if you 26 | want it, that you can change the software or use pieces of it in new 27 | free programs, and that you know you can do these things. 28 | 29 | To protect your rights, we need to prevent others from denying you 30 | these rights or asking you to surrender the rights. Therefore, you have 31 | certain responsibilities if you distribute copies of the software, or if 32 | you modify it: responsibilities to respect the freedom of others. 33 | 34 | For example, if you distribute copies of such a program, whether 35 | gratis or for a fee, you must pass on to the recipients the same 36 | freedoms that you received. You must make sure that they, too, receive 37 | or can get the source code. And you must show them these terms so they 38 | know their rights. 39 | 40 | Developers that use the GNU GPL protect your rights with two steps: 41 | (1) assert copyright on the software, and (2) offer you this License 42 | giving you legal permission to copy, distribute and/or modify it. 43 | 44 | For the developers' and authors' protection, the GPL clearly explains 45 | that there is no warranty for this free software. For both users' and 46 | authors' sake, the GPL requires that modified versions be marked as 47 | changed, so that their problems will not be attributed erroneously to 48 | authors of previous versions. 49 | 50 | Some devices are designed to deny users access to install or run 51 | modified versions of the software inside them, although the manufacturer 52 | can do so. This is fundamentally incompatible with the aim of 53 | protecting users' freedom to change the software. The systematic 54 | pattern of such abuse occurs in the area of products for individuals to 55 | use, which is precisely where it is most unacceptable. Therefore, we 56 | have designed this version of the GPL to prohibit the practice for those 57 | products. If such problems arise substantially in other domains, we 58 | stand ready to extend this provision to those domains in future versions 59 | of the GPL, as needed to protect the freedom of users. 60 | 61 | Finally, every program is threatened constantly by software patents. 62 | States should not allow patents to restrict development and use of 63 | software on general-purpose computers, but in those that do, we wish to 64 | avoid the special danger that patents applied to a free program could 65 | make it effectively proprietary. To prevent this, the GPL assures that 66 | patents cannot be used to render the program non-free. 67 | 68 | The precise terms and conditions for copying, distribution and 69 | modification follow. 70 | 71 | TERMS AND CONDITIONS 72 | 73 | 0. Definitions. 74 | 75 | "This License" refers to version 3 of the GNU General Public License. 76 | 77 | "Copyright" also means copyright-like laws that apply to other kinds of 78 | works, such as semiconductor masks. 79 | 80 | "The Program" refers to any copyrightable work licensed under this 81 | License. Each licensee is addressed as "you". "Licensees" and 82 | "recipients" may be individuals or organizations. 83 | 84 | To "modify" a work means to copy from or adapt all or part of the work 85 | in a fashion requiring copyright permission, other than the making of an 86 | exact copy. The resulting work is called a "modified version" of the 87 | earlier work or a work "based on" the earlier work. 88 | 89 | A "covered work" means either the unmodified Program or a work based 90 | on the Program. 91 | 92 | To "propagate" a work means to do anything with it that, without 93 | permission, would make you directly or secondarily liable for 94 | infringement under applicable copyright law, except executing it on a 95 | computer or modifying a private copy. Propagation includes copying, 96 | distribution (with or without modification), making available to the 97 | public, and in some countries other activities as well. 98 | 99 | To "convey" a work means any kind of propagation that enables other 100 | parties to make or receive copies. Mere interaction with a user through 101 | a computer network, with no transfer of a copy, is not conveying. 102 | 103 | An interactive user interface displays "Appropriate Legal Notices" 104 | to the extent that it includes a convenient and prominently visible 105 | feature that (1) displays an appropriate copyright notice, and (2) 106 | tells the user that there is no warranty for the work (except to the 107 | extent that warranties are provided), that licensees may convey the 108 | work under this License, and how to view a copy of this License. If 109 | the interface presents a list of user commands or options, such as a 110 | menu, a prominent item in the list meets this criterion. 111 | 112 | 1. Source Code. 113 | 114 | The "source code" for a work means the preferred form of the work 115 | for making modifications to it. "Object code" means any non-source 116 | form of a work. 117 | 118 | A "Standard Interface" means an interface that either is an official 119 | standard defined by a recognized standards body, or, in the case of 120 | interfaces specified for a particular programming language, one that 121 | is widely used among developers working in that language. 122 | 123 | The "System Libraries" of an executable work include anything, other 124 | than the work as a whole, that (a) is included in the normal form of 125 | packaging a Major Component, but which is not part of that Major 126 | Component, and (b) serves only to enable use of the work with that 127 | Major Component, or to implement a Standard Interface for which an 128 | implementation is available to the public in source code form. A 129 | "Major Component", in this context, means a major essential component 130 | (kernel, window system, and so on) of the specific operating system 131 | (if any) on which the executable work runs, or a compiler used to 132 | produce the work, or an object code interpreter used to run it. 133 | 134 | The "Corresponding Source" for a work in object code form means all 135 | the source code needed to generate, install, and (for an executable 136 | work) run the object code and to modify the work, including scripts to 137 | control those activities. However, it does not include the work's 138 | System Libraries, or general-purpose tools or generally available free 139 | programs which are used unmodified in performing those activities but 140 | which are not part of the work. For example, Corresponding Source 141 | includes interface definition files associated with source files for 142 | the work, and the source code for shared libraries and dynamically 143 | linked subprograms that the work is specifically designed to require, 144 | such as by intimate data communication or control flow between those 145 | subprograms and other parts of the work. 146 | 147 | The Corresponding Source need not include anything that users 148 | can regenerate automatically from other parts of the Corresponding 149 | Source. 150 | 151 | The Corresponding Source for a work in source code form is that 152 | same work. 153 | 154 | 2. Basic Permissions. 155 | 156 | All rights granted under this License are granted for the term of 157 | copyright on the Program, and are irrevocable provided the stated 158 | conditions are met. This License explicitly affirms your unlimited 159 | permission to run the unmodified Program. The output from running a 160 | covered work is covered by this License only if the output, given its 161 | content, constitutes a covered work. This License acknowledges your 162 | rights of fair use or other equivalent, as provided by copyright law. 163 | 164 | You may make, run and propagate covered works that you do not 165 | convey, without conditions so long as your license otherwise remains 166 | in force. You may convey covered works to others for the sole purpose 167 | of having them make modifications exclusively for you, or provide you 168 | with facilities for running those works, provided that you comply with 169 | the terms of this License in conveying all material for which you do 170 | not control copyright. Those thus making or running the covered works 171 | for you must do so exclusively on your behalf, under your direction 172 | and control, on terms that prohibit them from making any copies of 173 | your copyrighted material outside their relationship with you. 174 | 175 | Conveying under any other circumstances is permitted solely under 176 | the conditions stated below. Sublicensing is not allowed; section 10 177 | makes it unnecessary. 178 | 179 | 3. Protecting Users' Legal Rights From Anti-Circumvention Law. 180 | 181 | No covered work shall be deemed part of an effective technological 182 | measure under any applicable law fulfilling obligations under article 183 | 11 of the WIPO copyright treaty adopted on 20 December 1996, or 184 | similar laws prohibiting or restricting circumvention of such 185 | measures. 186 | 187 | When you convey a covered work, you waive any legal power to forbid 188 | circumvention of technological measures to the extent such circumvention 189 | is effected by exercising rights under this License with respect to 190 | the covered work, and you disclaim any intention to limit operation or 191 | modification of the work as a means of enforcing, against the work's 192 | users, your or third parties' legal rights to forbid circumvention of 193 | technological measures. 194 | 195 | 4. Conveying Verbatim Copies. 196 | 197 | You may convey verbatim copies of the Program's source code as you 198 | receive it, in any medium, provided that you conspicuously and 199 | appropriately publish on each copy an appropriate copyright notice; 200 | keep intact all notices stating that this License and any 201 | non-permissive terms added in accord with section 7 apply to the code; 202 | keep intact all notices of the absence of any warranty; and give all 203 | recipients a copy of this License along with the Program. 204 | 205 | You may charge any price or no price for each copy that you convey, 206 | and you may offer support or warranty protection for a fee. 207 | 208 | 5. Conveying Modified Source Versions. 209 | 210 | You may convey a work based on the Program, or the modifications to 211 | produce it from the Program, in the form of source code under the 212 | terms of section 4, provided that you also meet all of these conditions: 213 | 214 | a) The work must carry prominent notices stating that you modified 215 | it, and giving a relevant date. 216 | 217 | b) The work must carry prominent notices stating that it is 218 | released under this License and any conditions added under section 219 | 7. This requirement modifies the requirement in section 4 to 220 | "keep intact all notices". 221 | 222 | c) You must license the entire work, as a whole, under this 223 | License to anyone who comes into possession of a copy. This 224 | License will therefore apply, along with any applicable section 7 225 | additional terms, to the whole of the work, and all its parts, 226 | regardless of how they are packaged. This License gives no 227 | permission to license the work in any other way, but it does not 228 | invalidate such permission if you have separately received it. 229 | 230 | d) If the work has interactive user interfaces, each must display 231 | Appropriate Legal Notices; however, if the Program has interactive 232 | interfaces that do not display Appropriate Legal Notices, your 233 | work need not make them do so. 234 | 235 | A compilation of a covered work with other separate and independent 236 | works, which are not by their nature extensions of the covered work, 237 | and which are not combined with it such as to form a larger program, 238 | in or on a volume of a storage or distribution medium, is called an 239 | "aggregate" if the compilation and its resulting copyright are not 240 | used to limit the access or legal rights of the compilation's users 241 | beyond what the individual works permit. Inclusion of a covered work 242 | in an aggregate does not cause this License to apply to the other 243 | parts of the aggregate. 244 | 245 | 6. Conveying Non-Source Forms. 246 | 247 | You may convey a covered work in object code form under the terms 248 | of sections 4 and 5, provided that you also convey the 249 | machine-readable Corresponding Source under the terms of this License, 250 | in one of these ways: 251 | 252 | a) Convey the object code in, or embodied in, a physical product 253 | (including a physical distribution medium), accompanied by the 254 | Corresponding Source fixed on a durable physical medium 255 | customarily used for software interchange. 256 | 257 | b) Convey the object code in, or embodied in, a physical product 258 | (including a physical distribution medium), accompanied by a 259 | written offer, valid for at least three years and valid for as 260 | long as you offer spare parts or customer support for that product 261 | model, to give anyone who possesses the object code either (1) a 262 | copy of the Corresponding Source for all the software in the 263 | product that is covered by this License, on a durable physical 264 | medium customarily used for software interchange, for a price no 265 | more than your reasonable cost of physically performing this 266 | conveying of source, or (2) access to copy the 267 | Corresponding Source from a network server at no charge. 268 | 269 | c) Convey individual copies of the object code with a copy of the 270 | written offer to provide the Corresponding Source. This 271 | alternative is allowed only occasionally and noncommercially, and 272 | only if you received the object code with such an offer, in accord 273 | with subsection 6b. 274 | 275 | d) Convey the object code by offering access from a designated 276 | place (gratis or for a charge), and offer equivalent access to the 277 | Corresponding Source in the same way through the same place at no 278 | further charge. You need not require recipients to copy the 279 | Corresponding Source along with the object code. If the place to 280 | copy the object code is a network server, the Corresponding Source 281 | may be on a different server (operated by you or a third party) 282 | that supports equivalent copying facilities, provided you maintain 283 | clear directions next to the object code saying where to find the 284 | Corresponding Source. Regardless of what server hosts the 285 | Corresponding Source, you remain obligated to ensure that it is 286 | available for as long as needed to satisfy these requirements. 287 | 288 | e) Convey the object code using peer-to-peer transmission, provided 289 | you inform other peers where the object code and Corresponding 290 | Source of the work are being offered to the general public at no 291 | charge under subsection 6d. 292 | 293 | A separable portion of the object code, whose source code is excluded 294 | from the Corresponding Source as a System Library, need not be 295 | included in conveying the object code work. 296 | 297 | A "User Product" is either (1) a "consumer product", which means any 298 | tangible personal property which is normally used for personal, family, 299 | or household purposes, or (2) anything designed or sold for incorporation 300 | into a dwelling. In determining whether a product is a consumer product, 301 | doubtful cases shall be resolved in favor of coverage. For a particular 302 | product received by a particular user, "normally used" refers to a 303 | typical or common use of that class of product, regardless of the status 304 | of the particular user or of the way in which the particular user 305 | actually uses, or expects or is expected to use, the product. A product 306 | is a consumer product regardless of whether the product has substantial 307 | commercial, industrial or non-consumer uses, unless such uses represent 308 | the only significant mode of use of the product. 309 | 310 | "Installation Information" for a User Product means any methods, 311 | procedures, authorization keys, or other information required to install 312 | and execute modified versions of a covered work in that User Product from 313 | a modified version of its Corresponding Source. The information must 314 | suffice to ensure that the continued functioning of the modified object 315 | code is in no case prevented or interfered with solely because 316 | modification has been made. 317 | 318 | If you convey an object code work under this section in, or with, or 319 | specifically for use in, a User Product, and the conveying occurs as 320 | part of a transaction in which the right of possession and use of the 321 | User Product is transferred to the recipient in perpetuity or for a 322 | fixed term (regardless of how the transaction is characterized), the 323 | Corresponding Source conveyed under this section must be accompanied 324 | by the Installation Information. But this requirement does not apply 325 | if neither you nor any third party retains the ability to install 326 | modified object code on the User Product (for example, the work has 327 | been installed in ROM). 328 | 329 | The requirement to provide Installation Information does not include a 330 | requirement to continue to provide support service, warranty, or updates 331 | for a work that has been modified or installed by the recipient, or for 332 | the User Product in which it has been modified or installed. Access to a 333 | network may be denied when the modification itself materially and 334 | adversely affects the operation of the network or violates the rules and 335 | protocols for communication across the network. 336 | 337 | Corresponding Source conveyed, and Installation Information provided, 338 | in accord with this section must be in a format that is publicly 339 | documented (and with an implementation available to the public in 340 | source code form), and must require no special password or key for 341 | unpacking, reading or copying. 342 | 343 | 7. Additional Terms. 344 | 345 | "Additional permissions" are terms that supplement the terms of this 346 | License by making exceptions from one or more of its conditions. 347 | Additional permissions that are applicable to the entire Program shall 348 | be treated as though they were included in this License, to the extent 349 | that they are valid under applicable law. If additional permissions 350 | apply only to part of the Program, that part may be used separately 351 | under those permissions, but the entire Program remains governed by 352 | this License without regard to the additional permissions. 353 | 354 | When you convey a copy of a covered work, you may at your option 355 | remove any additional permissions from that copy, or from any part of 356 | it. (Additional permissions may be written to require their own 357 | removal in certain cases when you modify the work.) You may place 358 | additional permissions on material, added by you to a covered work, 359 | for which you have or can give appropriate copyright permission. 360 | 361 | Notwithstanding any other provision of this License, for material you 362 | add to a covered work, you may (if authorized by the copyright holders of 363 | that material) supplement the terms of this License with terms: 364 | 365 | a) Disclaiming warranty or limiting liability differently from the 366 | terms of sections 15 and 16 of this License; or 367 | 368 | b) Requiring preservation of specified reasonable legal notices or 369 | author attributions in that material or in the Appropriate Legal 370 | Notices displayed by works containing it; or 371 | 372 | c) Prohibiting misrepresentation of the origin of that material, or 373 | requiring that modified versions of such material be marked in 374 | reasonable ways as different from the original version; or 375 | 376 | d) Limiting the use for publicity purposes of names of licensors or 377 | authors of the material; or 378 | 379 | e) Declining to grant rights under trademark law for use of some 380 | trade names, trademarks, or service marks; or 381 | 382 | f) Requiring indemnification of licensors and authors of that 383 | material by anyone who conveys the material (or modified versions of 384 | it) with contractual assumptions of liability to the recipient, for 385 | any liability that these contractual assumptions directly impose on 386 | those licensors and authors. 387 | 388 | All other non-permissive additional terms are considered "further 389 | restrictions" within the meaning of section 10. If the Program as you 390 | received it, or any part of it, contains a notice stating that it is 391 | governed by this License along with a term that is a further 392 | restriction, you may remove that term. If a license document contains 393 | a further restriction but permits relicensing or conveying under this 394 | License, you may add to a covered work material governed by the terms 395 | of that license document, provided that the further restriction does 396 | not survive such relicensing or conveying. 397 | 398 | If you add terms to a covered work in accord with this section, you 399 | must place, in the relevant source files, a statement of the 400 | additional terms that apply to those files, or a notice indicating 401 | where to find the applicable terms. 402 | 403 | Additional terms, permissive or non-permissive, may be stated in the 404 | form of a separately written license, or stated as exceptions; 405 | the above requirements apply either way. 406 | 407 | 8. Termination. 408 | 409 | You may not propagate or modify a covered work except as expressly 410 | provided under this License. Any attempt otherwise to propagate or 411 | modify it is void, and will automatically terminate your rights under 412 | this License (including any patent licenses granted under the third 413 | paragraph of section 11). 414 | 415 | However, if you cease all violation of this License, then your 416 | license from a particular copyright holder is reinstated (a) 417 | provisionally, unless and until the copyright holder explicitly and 418 | finally terminates your license, and (b) permanently, if the copyright 419 | holder fails to notify you of the violation by some reasonable means 420 | prior to 60 days after the cessation. 421 | 422 | Moreover, your license from a particular copyright holder is 423 | reinstated permanently if the copyright holder notifies you of the 424 | violation by some reasonable means, this is the first time you have 425 | received notice of violation of this License (for any work) from that 426 | copyright holder, and you cure the violation prior to 30 days after 427 | your receipt of the notice. 428 | 429 | Termination of your rights under this section does not terminate the 430 | licenses of parties who have received copies or rights from you under 431 | this License. If your rights have been terminated and not permanently 432 | reinstated, you do not qualify to receive new licenses for the same 433 | material under section 10. 434 | 435 | 9. Acceptance Not Required for Having Copies. 436 | 437 | You are not required to accept this License in order to receive or 438 | run a copy of the Program. Ancillary propagation of a covered work 439 | occurring solely as a consequence of using peer-to-peer transmission 440 | to receive a copy likewise does not require acceptance. However, 441 | nothing other than this License grants you permission to propagate or 442 | modify any covered work. These actions infringe copyright if you do 443 | not accept this License. Therefore, by modifying or propagating a 444 | covered work, you indicate your acceptance of this License to do so. 445 | 446 | 10. Automatic Licensing of Downstream Recipients. 447 | 448 | Each time you convey a covered work, the recipient automatically 449 | receives a license from the original licensors, to run, modify and 450 | propagate that work, subject to this License. You are not responsible 451 | for enforcing compliance by third parties with this License. 452 | 453 | An "entity transaction" is a transaction transferring control of an 454 | organization, or substantially all assets of one, or subdividing an 455 | organization, or merging organizations. If propagation of a covered 456 | work results from an entity transaction, each party to that 457 | transaction who receives a copy of the work also receives whatever 458 | licenses to the work the party's predecessor in interest had or could 459 | give under the previous paragraph, plus a right to possession of the 460 | Corresponding Source of the work from the predecessor in interest, if 461 | the predecessor has it or can get it with reasonable efforts. 462 | 463 | You may not impose any further restrictions on the exercise of the 464 | rights granted or affirmed under this License. For example, you may 465 | not impose a license fee, royalty, or other charge for exercise of 466 | rights granted under this License, and you may not initiate litigation 467 | (including a cross-claim or counterclaim in a lawsuit) alleging that 468 | any patent claim is infringed by making, using, selling, offering for 469 | sale, or importing the Program or any portion of it. 470 | 471 | 11. Patents. 472 | 473 | A "contributor" is a copyright holder who authorizes use under this 474 | License of the Program or a work on which the Program is based. The 475 | work thus licensed is called the contributor's "contributor version". 476 | 477 | A contributor's "essential patent claims" are all patent claims 478 | owned or controlled by the contributor, whether already acquired or 479 | hereafter acquired, that would be infringed by some manner, permitted 480 | by this License, of making, using, or selling its contributor version, 481 | but do not include claims that would be infringed only as a 482 | consequence of further modification of the contributor version. For 483 | purposes of this definition, "control" includes the right to grant 484 | patent sublicenses in a manner consistent with the requirements of 485 | this License. 486 | 487 | Each contributor grants you a non-exclusive, worldwide, royalty-free 488 | patent license under the contributor's essential patent claims, to 489 | make, use, sell, offer for sale, import and otherwise run, modify and 490 | propagate the contents of its contributor version. 491 | 492 | In the following three paragraphs, a "patent license" is any express 493 | agreement or commitment, however denominated, not to enforce a patent 494 | (such as an express permission to practice a patent or covenant not to 495 | sue for patent infringement). To "grant" such a patent license to a 496 | party means to make such an agreement or commitment not to enforce a 497 | patent against the party. 498 | 499 | If you convey a covered work, knowingly relying on a patent license, 500 | and the Corresponding Source of the work is not available for anyone 501 | to copy, free of charge and under the terms of this License, through a 502 | publicly available network server or other readily accessible means, 503 | then you must either (1) cause the Corresponding Source to be so 504 | available, or (2) arrange to deprive yourself of the benefit of the 505 | patent license for this particular work, or (3) arrange, in a manner 506 | consistent with the requirements of this License, to extend the patent 507 | license to downstream recipients. "Knowingly relying" means you have 508 | actual knowledge that, but for the patent license, your conveying the 509 | covered work in a country, or your recipient's use of the covered work 510 | in a country, would infringe one or more identifiable patents in that 511 | country that you have reason to believe are valid. 512 | 513 | If, pursuant to or in connection with a single transaction or 514 | arrangement, you convey, or propagate by procuring conveyance of, a 515 | covered work, and grant a patent license to some of the parties 516 | receiving the covered work authorizing them to use, propagate, modify 517 | or convey a specific copy of the covered work, then the patent license 518 | you grant is automatically extended to all recipients of the covered 519 | work and works based on it. 520 | 521 | A patent license is "discriminatory" if it does not include within 522 | the scope of its coverage, prohibits the exercise of, or is 523 | conditioned on the non-exercise of one or more of the rights that are 524 | specifically granted under this License. You may not convey a covered 525 | work if you are a party to an arrangement with a third party that is 526 | in the business of distributing software, under which you make payment 527 | to the third party based on the extent of your activity of conveying 528 | the work, and under which the third party grants, to any of the 529 | parties who would receive the covered work from you, a discriminatory 530 | patent license (a) in connection with copies of the covered work 531 | conveyed by you (or copies made from those copies), or (b) primarily 532 | for and in connection with specific products or compilations that 533 | contain the covered work, unless you entered into that arrangement, 534 | or that patent license was granted, prior to 28 March 2007. 535 | 536 | Nothing in this License shall be construed as excluding or limiting 537 | any implied license or other defenses to infringement that may 538 | otherwise be available to you under applicable patent law. 539 | 540 | 12. No Surrender of Others' Freedom. 541 | 542 | If conditions are imposed on you (whether by court order, agreement or 543 | otherwise) that contradict the conditions of this License, they do not 544 | excuse you from the conditions of this License. If you cannot convey a 545 | covered work so as to satisfy simultaneously your obligations under this 546 | License and any other pertinent obligations, then as a consequence you may 547 | not convey it at all. For example, if you agree to terms that obligate you 548 | to collect a royalty for further conveying from those to whom you convey 549 | the Program, the only way you could satisfy both those terms and this 550 | License would be to refrain entirely from conveying the Program. 551 | 552 | 13. Use with the GNU Affero General Public License. 553 | 554 | Notwithstanding any other provision of this License, you have 555 | permission to link or combine any covered work with a work licensed 556 | under version 3 of the GNU Affero General Public License into a single 557 | combined work, and to convey the resulting work. The terms of this 558 | License will continue to apply to the part which is the covered work, 559 | but the special requirements of the GNU Affero General Public License, 560 | section 13, concerning interaction through a network will apply to the 561 | combination as such. 562 | 563 | 14. Revised Versions of this License. 564 | 565 | The Free Software Foundation may publish revised and/or new versions of 566 | the GNU General Public License from time to time. Such new versions will 567 | be similar in spirit to the present version, but may differ in detail to 568 | address new problems or concerns. 569 | 570 | Each version is given a distinguishing version number. If the 571 | Program specifies that a certain numbered version of the GNU General 572 | Public License "or any later version" applies to it, you have the 573 | option of following the terms and conditions either of that numbered 574 | version or of any later version published by the Free Software 575 | Foundation. If the Program does not specify a version number of the 576 | GNU General Public License, you may choose any version ever published 577 | by the Free Software Foundation. 578 | 579 | If the Program specifies that a proxy can decide which future 580 | versions of the GNU General Public License can be used, that proxy's 581 | public statement of acceptance of a version permanently authorizes you 582 | to choose that version for the Program. 583 | 584 | Later license versions may give you additional or different 585 | permissions. However, no additional obligations are imposed on any 586 | author or copyright holder as a result of your choosing to follow a 587 | later version. 588 | 589 | 15. Disclaimer of Warranty. 590 | 591 | THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY 592 | APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT 593 | HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY 594 | OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, 595 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 596 | PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM 597 | IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF 598 | ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 599 | 600 | 16. Limitation of Liability. 601 | 602 | IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 603 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS 604 | THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY 605 | GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE 606 | USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF 607 | DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD 608 | PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), 609 | EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF 610 | SUCH DAMAGES. 611 | 612 | 17. Interpretation of Sections 15 and 16. 613 | 614 | If the disclaimer of warranty and limitation of liability provided 615 | above cannot be given local legal effect according to their terms, 616 | reviewing courts shall apply local law that most closely approximates 617 | an absolute waiver of all civil liability in connection with the 618 | Program, unless a warranty or assumption of liability accompanies a 619 | copy of the Program in return for a fee. 620 | 621 | END OF TERMS AND CONDITIONS 622 | -------------------------------------------------------------------------------- /template/{% if license == 'MIT' %}LICENSE{% endif %}.jinja: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) {{ year }} {{ copyright_holder }} 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software is furnished to do so, 10 | subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice (including the next 13 | paragraph) shall be included in all copies or substantial portions of the 14 | Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 18 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 19 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 20 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /template/{% if license == 'MPL-2.0' %}LICENSE{% endif %}.jinja: -------------------------------------------------------------------------------- 1 | Mozilla Public License Version 2.0 2 | ================================== 3 | 4 | 1. Definitions 5 | -------------- 6 | 7 | 1.1. "Contributor" 8 | means each individual or legal entity that creates, contributes to 9 | the creation of, or owns Covered Software. 10 | 11 | 1.2. "Contributor Version" 12 | means the combination of the Contributions of others (if any) used 13 | by a Contributor and that particular Contributor's Contribution. 14 | 15 | 1.3. "Contribution" 16 | means Covered Software of a particular Contributor. 17 | 18 | 1.4. "Covered Software" 19 | means Source Code Form to which the initial Contributor has attached 20 | the notice in Exhibit A, the Executable Form of such Source Code 21 | Form, and Modifications of such Source Code Form, in each case 22 | including portions thereof. 23 | 24 | 1.5. "Incompatible With Secondary Licenses" 25 | means 26 | 27 | (a) that the initial Contributor has attached the notice described 28 | in Exhibit B to the Covered Software; or 29 | 30 | (b) that the Covered Software was made available under the terms of 31 | version 1.1 or earlier of the License, but not also under the 32 | terms of a Secondary License. 33 | 34 | 1.6. "Executable Form" 35 | means any form of the work other than Source Code Form. 36 | 37 | 1.7. "Larger Work" 38 | means a work that combines Covered Software with other material, in 39 | a separate file or files, that is not Covered Software. 40 | 41 | 1.8. "License" 42 | means this document. 43 | 44 | 1.9. "Licensable" 45 | means having the right to grant, to the maximum extent possible, 46 | whether at the time of the initial grant or subsequently, any and 47 | all of the rights conveyed by this License. 48 | 49 | 1.10. "Modifications" 50 | means any of the following: 51 | 52 | (a) any file in Source Code Form that results from an addition to, 53 | deletion from, or modification of the contents of Covered 54 | Software; or 55 | 56 | (b) any new file in Source Code Form that contains any Covered 57 | Software. 58 | 59 | 1.11. "Patent Claims" of a Contributor 60 | means any patent claim(s), including without limitation, method, 61 | process, and apparatus claims, in any patent Licensable by such 62 | Contributor that would be infringed, but for the grant of the 63 | License, by the making, using, selling, offering for sale, having 64 | made, import, or transfer of either its Contributions or its 65 | Contributor Version. 66 | 67 | 1.12. "Secondary License" 68 | means either the GNU General Public License, Version 2.0, the GNU 69 | Lesser General Public License, Version 2.1, the GNU Affero General 70 | Public License, Version 3.0, or any later versions of those 71 | licenses. 72 | 73 | 1.13. "Source Code Form" 74 | means the form of the work preferred for making modifications. 75 | 76 | 1.14. "You" (or "Your") 77 | means an individual or a legal entity exercising rights under this 78 | License. For legal entities, "You" includes any entity that 79 | controls, is controlled by, or is under common control with You. For 80 | purposes of this definition, "control" means (a) the power, direct 81 | or indirect, to cause the direction or management of such entity, 82 | whether by contract or otherwise, or (b) ownership of more than 83 | fifty percent (50%) of the outstanding shares or beneficial 84 | ownership of such entity. 85 | 86 | 2. License Grants and Conditions 87 | -------------------------------- 88 | 89 | 2.1. Grants 90 | 91 | Each Contributor hereby grants You a world-wide, royalty-free, 92 | non-exclusive license: 93 | 94 | (a) under intellectual property rights (other than patent or trademark) 95 | Licensable by such Contributor to use, reproduce, make available, 96 | modify, display, perform, distribute, and otherwise exploit its 97 | Contributions, either on an unmodified basis, with Modifications, or 98 | as part of a Larger Work; and 99 | 100 | (b) under Patent Claims of such Contributor to make, use, sell, offer 101 | for sale, have made, import, and otherwise transfer either its 102 | Contributions or its Contributor Version. 103 | 104 | 2.2. Effective Date 105 | 106 | The licenses granted in Section 2.1 with respect to any Contribution 107 | become effective for each Contribution on the date the Contributor first 108 | distributes such Contribution. 109 | 110 | 2.3. Limitations on Grant Scope 111 | 112 | The licenses granted in this Section 2 are the only rights granted under 113 | this License. No additional rights or licenses will be implied from the 114 | distribution or licensing of Covered Software under this License. 115 | Notwithstanding Section 2.1(b) above, no patent license is granted by a 116 | Contributor: 117 | 118 | (a) for any code that a Contributor has removed from Covered Software; 119 | or 120 | 121 | (b) for infringements caused by: (i) Your and any other third party's 122 | modifications of Covered Software, or (ii) the combination of its 123 | Contributions with other software (except as part of its Contributor 124 | Version); or 125 | 126 | (c) under Patent Claims infringed by Covered Software in the absence of 127 | its Contributions. 128 | 129 | This License does not grant any rights in the trademarks, service marks, 130 | or logos of any Contributor (except as may be necessary to comply with 131 | the notice requirements in Section 3.4). 132 | 133 | 2.4. Subsequent Licenses 134 | 135 | No Contributor makes additional grants as a result of Your choice to 136 | distribute the Covered Software under a subsequent version of this 137 | License (see Section 10.2) or under the terms of a Secondary License (if 138 | permitted under the terms of Section 3.3). 139 | 140 | 2.5. Representation 141 | 142 | Each Contributor represents that the Contributor believes its 143 | Contributions are its original creation(s) or it has sufficient rights 144 | to grant the rights to its Contributions conveyed by this License. 145 | 146 | 2.6. Fair Use 147 | 148 | This License is not intended to limit any rights You have under 149 | applicable copyright doctrines of fair use, fair dealing, or other 150 | equivalents. 151 | 152 | 2.7. Conditions 153 | 154 | Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted 155 | in Section 2.1. 156 | 157 | 3. Responsibilities 158 | ------------------- 159 | 160 | 3.1. Distribution of Source Form 161 | 162 | All distribution of Covered Software in Source Code Form, including any 163 | Modifications that You create or to which You contribute, must be under 164 | the terms of this License. You must inform recipients that the Source 165 | Code Form of the Covered Software is governed by the terms of this 166 | License, and how they can obtain a copy of this License. You may not 167 | attempt to alter or restrict the recipients' rights in the Source Code 168 | Form. 169 | 170 | 3.2. Distribution of Executable Form 171 | 172 | If You distribute Covered Software in Executable Form then: 173 | 174 | (a) such Covered Software must also be made available in Source Code 175 | Form, as described in Section 3.1, and You must inform recipients of 176 | the Executable Form how they can obtain a copy of such Source Code 177 | Form by reasonable means in a timely manner, at a charge no more 178 | than the cost of distribution to the recipient; and 179 | 180 | (b) You may distribute such Executable Form under the terms of this 181 | License, or sublicense it under different terms, provided that the 182 | license for the Executable Form does not attempt to limit or alter 183 | the recipients' rights in the Source Code Form under this License. 184 | 185 | 3.3. Distribution of a Larger Work 186 | 187 | You may create and distribute a Larger Work under terms of Your choice, 188 | provided that You also comply with the requirements of this License for 189 | the Covered Software. If the Larger Work is a combination of Covered 190 | Software with a work governed by one or more Secondary Licenses, and the 191 | Covered Software is not Incompatible With Secondary Licenses, this 192 | License permits You to additionally distribute such Covered Software 193 | under the terms of such Secondary License(s), so that the recipient of 194 | the Larger Work may, at their option, further distribute the Covered 195 | Software under the terms of either this License or such Secondary 196 | License(s). 197 | 198 | 3.4. Notices 199 | 200 | You may not remove or alter the substance of any license notices 201 | (including copyright notices, patent notices, disclaimers of warranty, 202 | or limitations of liability) contained within the Source Code Form of 203 | the Covered Software, except that You may alter any license notices to 204 | the extent required to remedy known factual inaccuracies. 205 | 206 | 3.5. Application of Additional Terms 207 | 208 | You may choose to offer, and to charge a fee for, warranty, support, 209 | indemnity or liability obligations to one or more recipients of Covered 210 | Software. However, You may do so only on Your own behalf, and not on 211 | behalf of any Contributor. You must make it absolutely clear that any 212 | such warranty, support, indemnity, or liability obligation is offered by 213 | You alone, and You hereby agree to indemnify every Contributor for any 214 | liability incurred by such Contributor as a result of warranty, support, 215 | indemnity or liability terms You offer. You may include additional 216 | disclaimers of warranty and limitations of liability specific to any 217 | jurisdiction. 218 | 219 | 4. Inability to Comply Due to Statute or Regulation 220 | --------------------------------------------------- 221 | 222 | If it is impossible for You to comply with any of the terms of this 223 | License with respect to some or all of the Covered Software due to 224 | statute, judicial order, or regulation then You must: (a) comply with 225 | the terms of this License to the maximum extent possible; and (b) 226 | describe the limitations and the code they affect. Such description must 227 | be placed in a text file included with all distributions of the Covered 228 | Software under this License. Except to the extent prohibited by statute 229 | or regulation, such description must be sufficiently detailed for a 230 | recipient of ordinary skill to be able to understand it. 231 | 232 | 5. Termination 233 | -------------- 234 | 235 | 5.1. The rights granted under this License will terminate automatically 236 | if You fail to comply with any of its terms. However, if You become 237 | compliant, then the rights granted under this License from a particular 238 | Contributor are reinstated (a) provisionally, unless and until such 239 | Contributor explicitly and finally terminates Your grants, and (b) on an 240 | ongoing basis, if such Contributor fails to notify You of the 241 | non-compliance by some reasonable means prior to 60 days after You have 242 | come back into compliance. Moreover, Your grants from a particular 243 | Contributor are reinstated on an ongoing basis if such Contributor 244 | notifies You of the non-compliance by some reasonable means, this is the 245 | first time You have received notice of non-compliance with this License 246 | from such Contributor, and You become compliant prior to 30 days after 247 | Your receipt of the notice. 248 | 249 | 5.2. If You initiate litigation against any entity by asserting a patent 250 | infringement claim (excluding declaratory judgment actions, 251 | counter-claims, and cross-claims) alleging that a Contributor Version 252 | directly or indirectly infringes any patent, then the rights granted to 253 | You by any and all Contributors for the Covered Software under Section 254 | 2.1 of this License shall terminate. 255 | 256 | 5.3. In the event of termination under Sections 5.1 or 5.2 above, all 257 | end user license agreements (excluding distributors and resellers) which 258 | have been validly granted by You or Your distributors under this License 259 | prior to termination shall survive termination. 260 | 261 | ************************************************************************ 262 | * * 263 | * 6. Disclaimer of Warranty * 264 | * ------------------------- * 265 | * * 266 | * Covered Software is provided under this License on an "as is" * 267 | * basis, without warranty of any kind, either expressed, implied, or * 268 | * statutory, including, without limitation, warranties that the * 269 | * Covered Software is free of defects, merchantable, fit for a * 270 | * particular purpose or non-infringing. The entire risk as to the * 271 | * quality and performance of the Covered Software is with You. * 272 | * Should any Covered Software prove defective in any respect, You * 273 | * (not any Contributor) assume the cost of any necessary servicing, * 274 | * repair, or correction. This disclaimer of warranty constitutes an * 275 | * essential part of this License. No use of any Covered Software is * 276 | * authorized under this License except under this disclaimer. * 277 | * * 278 | ************************************************************************ 279 | 280 | ************************************************************************ 281 | * * 282 | * 7. Limitation of Liability * 283 | * -------------------------- * 284 | * * 285 | * Under no circumstances and under no legal theory, whether tort * 286 | * (including negligence), contract, or otherwise, shall any * 287 | * Contributor, or anyone who distributes Covered Software as * 288 | * permitted above, be liable to You for any direct, indirect, * 289 | * special, incidental, or consequential damages of any character * 290 | * including, without limitation, damages for lost profits, loss of * 291 | * goodwill, work stoppage, computer failure or malfunction, or any * 292 | * and all other commercial damages or losses, even if such party * 293 | * shall have been informed of the possibility of such damages. This * 294 | * limitation of liability shall not apply to liability for death or * 295 | * personal injury resulting from such party's negligence to the * 296 | * extent applicable law prohibits such limitation. Some * 297 | * jurisdictions do not allow the exclusion or limitation of * 298 | * incidental or consequential damages, so this exclusion and * 299 | * limitation may not apply to You. * 300 | * * 301 | ************************************************************************ 302 | 303 | 8. Litigation 304 | ------------- 305 | 306 | Any litigation relating to this License may be brought only in the 307 | courts of a jurisdiction where the defendant maintains its principal 308 | place of business and such litigation shall be governed by laws of that 309 | jurisdiction, without reference to its conflict-of-law provisions. 310 | Nothing in this Section shall prevent a party's ability to bring 311 | cross-claims or counter-claims. 312 | 313 | 9. Miscellaneous 314 | ---------------- 315 | 316 | This License represents the complete agreement concerning the subject 317 | matter hereof. If any provision of this License is held to be 318 | unenforceable, such provision shall be reformed only to the extent 319 | necessary to make it enforceable. Any law or regulation which provides 320 | that the language of a contract shall be construed against the drafter 321 | shall not be used to construe this License against a Contributor. 322 | 323 | 10. Versions of the License 324 | --------------------------- 325 | 326 | 10.1. New Versions 327 | 328 | Mozilla Foundation is the license steward. Except as provided in Section 329 | 10.3, no one other than the license steward has the right to modify or 330 | publish new versions of this License. Each version will be given a 331 | distinguishing version number. 332 | 333 | 10.2. Effect of New Versions 334 | 335 | You may distribute the Covered Software under the terms of the version 336 | of the License under which You originally received the Covered Software, 337 | or under the terms of any subsequent version published by the license 338 | steward. 339 | 340 | 10.3. Modified Versions 341 | 342 | If you create software not governed by this License, and you want to 343 | create a new license for such software, you may create and use a 344 | modified version of this License if you rename the license and remove 345 | any references to the name of the license steward (except to note that 346 | such modified license differs from this License). 347 | 348 | 10.4. Distributing Source Code Form that is Incompatible With Secondary 349 | Licenses 350 | 351 | If You choose to distribute Source Code Form that is Incompatible With 352 | Secondary Licenses under the terms of this version of the License, the 353 | notice described in Exhibit B of this License must be attached. 354 | 355 | Exhibit A - Source Code Form License Notice 356 | ------------------------------------------- 357 | 358 | This Source Code Form is subject to the terms of the Mozilla Public 359 | License, v. 2.0. If a copy of the MPL was not distributed with this 360 | file, You can obtain one at https://mozilla.org/MPL/2.0/. 361 | 362 | If it is not possible or desirable to put the notice in a particular 363 | file, then You may include the notice in a location (such as a LICENSE 364 | file in a relevant directory) where a recipient would be likely to look 365 | for such a notice. 366 | 367 | You may add additional accurate notices of copyright ownership. 368 | 369 | Exhibit B - "Incompatible With Secondary Licenses" Notice 370 | --------------------------------------------------------- 371 | 372 | This Source Code Form is "Incompatible With Secondary Licenses", as 373 | defined by the Mozilla Public License, v. 2.0. 374 | -------------------------------------------------------------------------------- /template/{% if use_git and dev_platform == 'GitHub' %}.github{% endif %}/ISSUE_TEMPLATE/01-bug-report.yml.jinja: -------------------------------------------------------------------------------- 1 | name: 🐞 Bug report 2 | description: Report a problem to help improve this project 3 | title: "[BUG] " 4 | labels: [bug, triage] 5 | body: 6 | - type: checkboxes 7 | attributes: 8 | label: Is there an existing issue for this? 9 | description: Please search to see if an issue already exists for the bug you encountered. 10 | options: 11 | - label: I have searched the existing issues 12 | required: true 13 | 14 | - type: textarea 15 | attributes: 16 | label: Problem description 17 | description: | 18 | A concise description of what you're experiencing. 19 | 20 | Please explain: 21 | 22 | * **what** you tried to achieve, 23 | * **how** you went about it (referring to the code sample), and 24 | * **why** the current behaviour is a problem and what output you expected instead. 25 | validations: 26 | required: false 27 | 28 | - type: textarea 29 | attributes: 30 | label: Code sample 31 | description: > 32 | Create a [minimal, complete, verifiable example](https://stackoverflow.com/help/mcve). 33 | Please, paste your code between the ``` tickmarks below or link to a [gist](https://gist.github.com/). 34 | value: | 35 | Code run: 36 | 37 | ```python 38 | ``` 39 | 40 | Traceback: 41 | 42 | ```text 43 | ``` 44 | validations: 45 | required: false 46 | 47 | - type: textarea 48 | attributes: 49 | label: Environment 50 | description: > 51 | Please paste the output of running `depinfo --markdown {{ package_name }}` 52 | in your environment between the `details` tags below. 53 | value: | 54 |
55 | 56 |
57 | validations: 58 | required: true 59 | 60 | - type: textarea 61 | attributes: 62 | label: Anything else? 63 | description: | 64 | Links? References? Anything that will give us more context about the issue you are encountering! 65 | 66 | Tip: You can attach images or log files by clicking this area to highlight it and then dragging files in. 67 | validations: 68 | required: false 69 | -------------------------------------------------------------------------------- /template/{% if use_git and dev_platform == 'GitHub' %}.github{% endif %}/ISSUE_TEMPLATE/02-question.yml.jinja: -------------------------------------------------------------------------------- 1 | name: Question 2 | description: Ask a question 3 | title: "[Question] " 4 | labels: [question] 5 | body: 6 | - type: checkboxes 7 | attributes: 8 | label: Checklist 9 | description: > 10 | To help keep this issue tracker clean and focused, please make sure that you have 11 | tried **all** of the following resources before submitting your question. 12 | options: 13 | - label: I searched the [documentation](https://{{ project_slug }}.readthedocs.io). 14 | required: true 15 | - label: I looked through existing [discussion topics]({{ dev_platform_url }}/{{ username }}/{{ project_slug }}/discussions). 16 | required: true 17 | - label: I looked for [similar issues]({{ dev_platform_url }}/{{ username }}/{{ project_slug }}/issues). 18 | required: true 19 | - label: I looked up my question/problem in a search engine. 20 | required: true 21 | 22 | - type: textarea 23 | attributes: 24 | label: Question 25 | description: Please ask your question 26 | validations: 27 | required: true 28 | -------------------------------------------------------------------------------- /template/{% if use_git and dev_platform == 'GitHub' %}.github{% endif %}/ISSUE_TEMPLATE/03-feature-request.yml.jinja: -------------------------------------------------------------------------------- 1 | name: Feature request 2 | description: Suggest an idea for this project 3 | title: "[Feature] " 4 | labels: [enhancement] 5 | body: 6 | - type: checkboxes 7 | attributes: 8 | label: Checklist 9 | description: > 10 | Please make sure you check all these items before submitting your feature request. 11 | options: 12 | - label: There are [no similar issues or pull requests]({{ dev_platform_url }}/{{ username }}/{{ project_slug }}/issues) for this yet. 13 | required: true 14 | 15 | - type: textarea 16 | attributes: 17 | label: Problem 18 | description: > 19 | A clear and concise description of what you are trying to achieve. 20 | placeholder: > 21 | "I want to be able to [...] but I can't because [...]". 22 | validations: 23 | required: false 24 | 25 | - type: textarea 26 | attributes: 27 | label: Solution 28 | description: > 29 | A clear and concise description of what you would want to happen. 30 | For API changes, try to provide a code snippet of what you would like the new API to look like. 31 | validations: 32 | required: false 33 | 34 | - type: textarea 35 | attributes: 36 | label: Alternatives 37 | description: > 38 | Please describe any alternative solutions or features you've considered to solve 39 | your problem and why they didn't help. 40 | validations: 41 | required: false 42 | 43 | - type: textarea 44 | attributes: 45 | label: Anything else? 46 | description: > 47 | Provide any additional context, screenshots, tracebacks, etc. about the feature here. 48 | validations: 49 | required: false 50 | -------------------------------------------------------------------------------- /template/{% if use_git and dev_platform == 'GitHub' %}.github{% endif %}/ISSUE_TEMPLATE/config.yml.jinja: -------------------------------------------------------------------------------- 1 | blank_issues_enabled: true 2 | contact_links: 3 | - name: Community Support 4 | url: {{ dev_platform_url }}/{{ username }}/{{ project_slug }}/discussions 5 | about: Please ask and answer questions here. 6 | -------------------------------------------------------------------------------- /template/{% if use_git and dev_platform == 'GitHub' %}.github{% endif %}/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | - [ ] fix #(issue number) 2 | - [ ] description of feature/fix 3 | - [ ] tests added/passed 4 | - [ ] add an entry to the [changelog](../CHANGELOG.md) 5 | -------------------------------------------------------------------------------- /template/{% if use_git and dev_platform == 'GitHub' %}.github{% endif %}/SUPPORT.md.jinja: -------------------------------------------------------------------------------- 1 | # Support 2 | 3 | * Start a [discussion topic]({{ dev_platform_url }}/{{ username }}/{{ project_slug }}/discussions) 4 | * Email the authors or maintainers 5 | -------------------------------------------------------------------------------- /template/{% if use_git and dev_platform == 'GitHub' %}.github{% endif %}/workflows/cron.yml: -------------------------------------------------------------------------------- 1 | name: Cron Test 2 | 3 | on: 4 | schedule: 5 | # Run every Tuesday at 10:30. 6 | - cron: '30 10 * * 2' 7 | 8 | jobs: 9 | prerequisites: 10 | uses: ./.github/workflows/test.yml 11 | -------------------------------------------------------------------------------- /template/{% if use_git and dev_platform == 'GitHub' %}.github{% endif %}/workflows/main.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | - dev 8 | pull_request: 9 | branches: 10 | - main 11 | - dev 12 | 13 | jobs: 14 | prerequisites: 15 | uses: ./.github/workflows/test.yml 16 | -------------------------------------------------------------------------------- /template/{% if use_git and dev_platform == 'GitHub' %}.github{% endif %}/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: Publish to PyPI 2 | 3 | on: 4 | release: 5 | types: [published] 6 | 7 | jobs: 8 | prerequisites: 9 | uses: ./.github/workflows/test.yml 10 | # Setup build separate from publish for added security 11 | # See https://github.com/pypa/gh-action-pypi-publish/issues/217#issuecomment-1965727093 12 | build: 13 | needs: [prerequisites] 14 | runs-on: ubuntu-latest 15 | # Environment is encouraged for increased security 16 | steps: 17 | - name: Checkout 18 | uses: actions/checkout@v4 19 | with: 20 | # This fetch element is only important if you are use SCM based 21 | # versioning (that looks at git tags to gather the version). 22 | # setuptools-scm needs tags to form a valid version number 23 | fetch-tags: true 24 | 25 | - name: Setup Python 26 | uses: actions/setup-python@v5 27 | with: 28 | # You can modify what version of Python you want to use for your release 29 | python-version: "3.11" 30 | 31 | # Security recommends we should pin deps. Should we pin the workflow version? 32 | - name: Install hatch 33 | uses: pypa/hatch@a3c83ab3d481fbc2dc91dd0088628817488dd1d5 34 | 35 | - name: Build package using Hatch 36 | run: | 37 | hatch build 38 | echo "" 39 | echo "Generated files:" 40 | ls -lh dist/ 41 | 42 | # Store an artifact of the build to use in the publish step below 43 | - name: Store the distribution packages 44 | uses: actions/upload-artifact@v4 45 | with: 46 | name: python-package-distributions 47 | path: dist/ 48 | if-no-files-found: error 49 | publish: 50 | name: >- 51 | Publish Python 🐍 distribution 📦 to PyPI 52 | # Modify the repo name below to be your project's repo name. 53 | if: github.repository_owner == "{{ username }}" 54 | needs: 55 | - build 56 | runs-on: ubuntu-latest 57 | # Environment required here for trusted publisher 58 | environment: 59 | name: pypi 60 | # Modify the url to be the name of your package 61 | url: https://pypi.org/p/${{ package_name }} 62 | permissions: 63 | id-token: write # this permission is mandatory for PyPI publishing 64 | steps: 65 | - name: Download dists 66 | uses: actions/download-artifact@v4 67 | with: 68 | name: python-package-distributions 69 | path: dist/ 70 | merge-multiple: true 71 | - name: Publish package to PyPI 72 | # Only publish to real PyPI on release 73 | if: github.event_name == 'release' && github.event.action == 'published' 74 | uses: pypa/gh-action-pypi-publish@release/v1 75 | -------------------------------------------------------------------------------- /template/{% if use_git and dev_platform == 'GitHub' %}.github{% endif %}/workflows/test.yml.jinja: -------------------------------------------------------------------------------- 1 | name: Test Suite 2 | 3 | on: 4 | workflow_dispatch: {} 5 | workflow_call: {} 6 | 7 | jobs: 8 | {%- if use_lint %} 9 | {%- raw %} 10 | lint: 11 | runs-on: ${{ matrix.os }} 12 | strategy: 13 | fail-fast: false 14 | matrix: 15 | os: [ubuntu-latest] 16 | python-version: ["3.10"] 17 | 18 | steps: 19 | - uses: actions/checkout@v4 20 | 21 | - name: Set up Python ${{ matrix.python-version }} 22 | uses: actions/setup-python@v5 23 | with: 24 | python-version: ${{ matrix.python-version }} 25 | {%- endraw %} 26 | 27 | {%- if use_hatch_envs %} 28 | - name: Install hatch 29 | uses: pypa/hatch@install 30 | 31 | - name: Check code style 32 | run: hatch run style:code 33 | 34 | - name: Check docstrings 35 | run: hatch run style:docstrings 36 | 37 | - name: Build documentation 38 | run: hatch run docs:build 39 | {%- endif %} 40 | {%- endif %} 41 | 42 | {%- raw %} 43 | test: 44 | runs-on: ${{ matrix.os }} 45 | strategy: 46 | fail-fast: false 47 | matrix: 48 | os: [ubuntu-latest, macos-latest, windows-latest] 49 | python-version: ["3.10", "3.13"] 50 | 51 | steps: 52 | - uses: actions/checkout@v4 53 | 54 | - name: Set up Python ${{ matrix.python-version }} 55 | uses: actions/setup-python@v5 56 | with: 57 | python-version: ${{ matrix.python-version }} 58 | {%- endraw %} 59 | 60 | {%- if use_hatch_envs %} 61 | - name: Install hatch 62 | uses: pypa/hatch@install 63 | 64 | - name: Check installation 65 | run: hatch run install:check 66 | 67 | - name: Check dependencies 68 | run: hatch run audit:check 69 | 70 | {%- if use_types %} 71 | - name: Check types 72 | run: hatch run types:check 73 | {%- endif %} 74 | 75 | {%- if use_test %} 76 | {%- raw %} 77 | - name: Test suite 78 | run: hatch run +py=${{ matrix.python-version }} test:run 79 | 80 | - name: Report coverage 81 | shell: bash 82 | run: bash <(curl -s https://codecov.io/bash) 83 | {%- endraw %} 84 | {%- endif %} 85 | {%- endif %} 86 | -------------------------------------------------------------------------------- /template/{% if use_test %}tests{% endif %}/integration/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyOpenSci/pyos-package-template/c9f914981b8fb6f439eef3bd0d855d396e8086bd/template/{% if use_test %}tests{% endif %}/integration/.keep -------------------------------------------------------------------------------- /template/{% if use_test %}tests{% endif %}/system/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyOpenSci/pyos-package-template/c9f914981b8fb6f439eef3bd0d855d396e8086bd/template/{% if use_test %}tests{% endif %}/system/.keep -------------------------------------------------------------------------------- /template/{% if use_test %}tests{% endif %}/system/test_import.py.jinja: -------------------------------------------------------------------------------- 1 | {% include pathjoin("includes", "licenses", "header.txt.jinja") %} 2 | 3 | """Test that the package can be imported.""" 4 | 5 | 6 | def test_import(): 7 | """Test that the package can be imported.""" 8 | import {{ package_name }} # noqa: F401 9 | -------------------------------------------------------------------------------- /template/{% if use_test %}tests{% endif %}/unit/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyOpenSci/pyos-package-template/c9f914981b8fb6f439eef3bd0d855d396e8086bd/template/{% if use_test %}tests{% endif %}/unit/.keep -------------------------------------------------------------------------------- /tests/conftest.py: -------------------------------------------------------------------------------- 1 | """Provide fixtures to the entire test suite.""" 2 | 3 | import shutil 4 | from pathlib import Path 5 | from typing import TYPE_CHECKING, Generator 6 | 7 | import pytest 8 | from _pytest.monkeypatch import MonkeyPatch 9 | from jinja2 import Environment, FileSystemLoader 10 | from ruamel.yaml import YAML 11 | 12 | if TYPE_CHECKING: 13 | from _pytest.config.argparsing import Parser 14 | from _pytest.tmpdir import TempPathFactory 15 | 16 | COPIER_CONFIG_PATH = Path(__file__).parents[1] / "copier.yml" 17 | INCLUDES_PATH = Path(__file__).parents[1] / "includes" 18 | 19 | 20 | def _load_copier_config() -> dict: 21 | yaml = YAML(typ="safe") 22 | with COPIER_CONFIG_PATH.open("r") as yfile: 23 | return yaml.load(yfile) 24 | 25 | 26 | # don't mutate or else i'll have to get out the spray bottle (make it a fixture) 27 | COPIER_CONFIG = _load_copier_config() 28 | 29 | # -------------------------------------------------- 30 | # pytest hooks 31 | # -------------------------------------------------- 32 | 33 | 34 | def pytest_addoption(parser: "Parser") -> None: 35 | """Add options to pytest.""" 36 | parser.addoption( 37 | "--reuse-envs", 38 | action="store_true", 39 | help="After tests run, don't remove hatch environments created for " 40 | "generated projects (not the test environments for the " 41 | "pyos-package-template project itself).\n" 42 | "otherwise, use a temporary directoy and remove it afterwards.", 43 | ) 44 | 45 | 46 | # -------------------------------------------------- 47 | # Fixtures - autouse 48 | # -------------------------------------------------- 49 | 50 | 51 | @pytest.fixture(scope="session", autouse=True) 52 | def cleanup_hatch_envs( 53 | pytestconfig: pytest.Config, 54 | tmp_path_factory: "TempPathFactory", 55 | monkeypatch_session: MonkeyPatch, 56 | ) -> None: 57 | """ 58 | Use a temporary directory for hatch envs & cleanup after session. 59 | 60 | Unless --reuse-envs flag present. 61 | """ 62 | if pytestconfig.getoption("--reuse-envs"): 63 | yield 64 | return 65 | 66 | hatch_dir = tmp_path_factory.mktemp("hatch") 67 | monkeypatch_session.setenv("HATCH_DATA_DIR", str(hatch_dir)) 68 | 69 | try: 70 | yield 71 | finally: 72 | shutil.rmtree(hatch_dir, ignore_errors=True) 73 | 74 | 75 | # --------------------------------------------- 76 | # Fixtures - exports 77 | # --------------------------------------------- 78 | 79 | 80 | @pytest.fixture(scope="session") 81 | def monkeypatch_session() -> Generator[MonkeyPatch, None, None]: 82 | """Monkeypatch you can use with a session scoped fixture.""" 83 | mpatch = MonkeyPatch() 84 | yield mpatch 85 | mpatch.undo() 86 | 87 | 88 | @pytest.fixture(scope="module") 89 | def includes() -> Environment: 90 | """Jinja environment loaded with the partials dir.""" 91 | return Environment( 92 | loader=FileSystemLoader(searchpath=str(INCLUDES_PATH.resolve())), 93 | autoescape=True, 94 | ) 95 | 96 | 97 | @pytest.fixture( 98 | scope="module", 99 | params=COPIER_CONFIG["license"]["choices"].values(), 100 | ) 101 | def license(request: pytest.FixtureRequest) -> str: 102 | """Provide a recognized license classification.""" 103 | return request.param 104 | -------------------------------------------------------------------------------- /tests/test_partials.py: -------------------------------------------------------------------------------- 1 | """Test jinja template partials.""" 2 | 3 | from pathlib import Path 4 | 5 | import pytest 6 | from jinja2 import Environment 7 | 8 | _license_stub_names = { 9 | "MIT": "MIT License", 10 | "BSD-3-Clause" : "3-Clause BSD License", 11 | "Apache-2.0": "Apache Software License 2.0", 12 | "GPL-3.0-only": "GNU Public License 3.0", 13 | "EUPL-1.2": "EUPL 1.2 or later", 14 | "MPL-2.0": "Mozilla Public License, v2.0", 15 | } 16 | 17 | @pytest.mark.parametrize("license_path", [None, False, "../LICENSE"]) 18 | def test_license_stub(license: str, license_path: Path, includes: Environment): 19 | """License stub generates with the correct license and link to license file.""" 20 | year = "100" 21 | copyright_holder = "The Commons" 22 | license_name = _license_stub_names[license] 23 | 24 | template = includes.get_template("licenses/stub.md.jinja") 25 | stub = template.render({ 26 | "license": license, 27 | "license_path": license_path, 28 | "copyright_holder": copyright_holder, 29 | "year": year, 30 | }) 31 | 32 | for substring in ("Copyright", year, copyright_holder, license_name): 33 | assert substring in stub 34 | 35 | if license_path is None: 36 | # default location 37 | assert f"[{license_name}](./LICENSE)" in stub 38 | elif not license_path: 39 | # aka an explicit false to not make a link 40 | # aka the worst way to test this 41 | assert "[" not in stub 42 | assert "]" not in stub 43 | else: 44 | assert f"[{license_name}]({license_path})" in stub 45 | -------------------------------------------------------------------------------- /tests/test_template_init.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2024 pyOpenSci. 2 | # Copyright (c) 2022 Moritz E. Beber. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # https://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | 17 | """Test the template initialization.""" 18 | 19 | from __future__ import annotations 20 | 21 | import logging 22 | import os 23 | import subprocess 24 | import sys 25 | from datetime import datetime, timezone 26 | from pathlib import Path 27 | from typing import Callable 28 | 29 | import pytest 30 | from copier import run_copy 31 | from git import Repo 32 | from validate_pyproject import api as validator_api 33 | 34 | try: 35 | import tomllib 36 | except ImportError: 37 | # < python3.11 38 | # same thing right 39 | import tomli as tomllib 40 | 41 | TEMPLATE = Path(__file__).parents[1] 42 | 43 | logger = logging.getLogger(__name__) 44 | 45 | 46 | @pytest.fixture(scope="module", params=["GitHub", "GitLab"]) 47 | def dev_platform(request: pytest.FixtureRequest) -> str: 48 | """Provide a recognized development platform.""" 49 | return request.param 50 | 51 | 52 | @pytest.fixture( 53 | scope="module", 54 | params=["mkdocs", "sphinx", ""], 55 | ) 56 | def documentation(request: pytest.FixtureRequest) -> str: 57 | """Provide a documentation option.""" 58 | return request.param 59 | 60 | 61 | @pytest.fixture(scope="module") 62 | def answers() -> dict[str, str]: 63 | """Provide a full project context.""" 64 | today = datetime.now(tz=timezone.utc).date() 65 | return { 66 | "copyright_holder": "Citadel of Ricks", 67 | "author_name": "Rick Sanchez", 68 | "author_email": "rick@galaxybrain.science", 69 | "project_name": "Alien Clones", 70 | "project_slug": "alien-clones", 71 | "package_name": "alien_clones", 72 | "package_description": "Wubba Lubba Dub-Dub", 73 | "username": "rickprime", 74 | "year": str(today.year), 75 | } 76 | 77 | 78 | @pytest.fixture 79 | def generated(tmp_path: Path, answers: dict[str, str]) -> Callable[..., Path]: 80 | """Fixture closure to generate a template project, overriding passed data values.""" 81 | def _generated(**kwargs) -> Path: 82 | run_copy( 83 | src_path=str(TEMPLATE), 84 | dst_path=tmp_path, 85 | vcs_ref="HEAD", 86 | data={ 87 | **answers, 88 | **kwargs, 89 | }, 90 | defaults=True, 91 | ) 92 | 93 | init_git(tmp_path) 94 | 95 | return tmp_path 96 | return _generated 97 | 98 | 99 | def init_git(path: Path): 100 | """Initialize a git repository such that hatch-vcs can be used.""" 101 | project_dir = path.resolve(strict=True) 102 | repo = Repo.init(project_dir) 103 | repo.index.add( 104 | [ 105 | Path(dirpath, name) 106 | for dirpath, _, filenames in os.walk(project_dir) 107 | for name in filenames 108 | ], 109 | ) 110 | repo.index.commit("chore: initialize template") 111 | 112 | 113 | def test_init_template( 114 | dev_platform: str, 115 | license: str, 116 | documentation: str, 117 | generated: Callable[..., Path], 118 | ) -> None: 119 | """Expect that the template can be initialized with all combinations of choices.""" 120 | parent = generated( 121 | dev_platform=dev_platform, 122 | license=license, 123 | documentation=documentation, 124 | ) 125 | 126 | project_files = {path.relative_to(parent) for path in parent.rglob("*")} 127 | expected = { 128 | Path("README.md"), 129 | Path("pyproject.toml"), 130 | Path("src"), 131 | Path("tests"), 132 | Path("LICENSE"), 133 | } 134 | assert expected.issubset(project_files), expected.difference(project_files) 135 | 136 | 137 | @pytest.mark.installs 138 | def test_template_suite( 139 | generated: Callable[..., Path], 140 | ) -> None: 141 | """Expect that the test suite passes for the initialized template.""" 142 | project_dir = generated() 143 | 144 | # Run the local test suite. 145 | try: 146 | subprocess.run( 147 | "hatch run install:check", 148 | cwd=project_dir, 149 | check=True, 150 | shell=True, 151 | ) 152 | subprocess.run( 153 | f"hatch run +py={sys.version_info.major}.{sys.version_info.minor} test:run", 154 | cwd=project_dir, 155 | check=True, 156 | shell=True, 157 | ) 158 | subprocess.run( 159 | "hatch run style:check", 160 | cwd=project_dir, 161 | check=True, 162 | shell=True, 163 | ) 164 | subprocess.run( 165 | "hatch run audit:check", 166 | cwd=project_dir, 167 | check=True, 168 | shell=True, 169 | ) 170 | 171 | except subprocess.CalledProcessError as error: 172 | logger.error( # noqa: TRY400 173 | "Command = %r; Return code = %d.", 174 | error.cmd, 175 | error.returncode, 176 | ) 177 | raise 178 | 179 | 180 | @pytest.mark.docs 181 | @pytest.mark.installs 182 | def test_docs_build(documentation: str, generated: Callable[..., Path]): 183 | """The docs should build.""" 184 | if not documentation: 185 | return 186 | 187 | project = generated(documentation=documentation) 188 | 189 | subprocess.run( 190 | "hatch run docs:build", 191 | cwd=project, 192 | check=True, 193 | shell=True, 194 | ) 195 | subprocess.run( 196 | "pre-commit run --all-files -v check-readthedocs", 197 | cwd=project, 198 | check=True, 199 | shell=True, 200 | ) 201 | 202 | 203 | @pytest.mark.installs 204 | def test_dev_platform_github(generated: Callable[..., Path]): 205 | """Test github stuff idk!.""" 206 | project = generated(use_git=True, dev_platform="GitHub") 207 | 208 | workflows_dir = project / ".github" / "workflows" 209 | assert workflows_dir.exists() 210 | workflows = list(workflows_dir.iterdir()) 211 | assert len(workflows) > 0 212 | assert all(workflow.suffix in (".yml", ".yaml") for workflow in workflows) 213 | 214 | subprocess.run( 215 | "pre-commit run --all-files -v check-github-workflows", 216 | cwd=project, 217 | check=True, 218 | shell=True, 219 | ) 220 | 221 | 222 | @pytest.mark.installs 223 | def test_dev_platform_gitlab(generated: Callable[..., Path]): 224 | """Test gitlab stuff idk!.""" 225 | project = generated(use_git=True, dev_platform="GitLab") 226 | 227 | subprocess.run( 228 | "pre-commit run --all-files -v check-gitlab-ci", 229 | cwd=project, 230 | check=True, 231 | shell=True, 232 | ) 233 | 234 | 235 | def test_non_hatch_deps( 236 | documentation: str, 237 | generated: Callable[..., Path], 238 | ) -> None: 239 | """When we aren't using hatch, we should still get the optional dependencies.""" 240 | project = generated( 241 | use_hatch_envs=False, 242 | use_lint=True, 243 | use_types=True, 244 | use_test=True, 245 | use_git=False, 246 | documentation=documentation, 247 | ) 248 | 249 | pyproject_file = project / "pyproject.toml" 250 | with pyproject_file.open("rb") as pfile: 251 | pyproject = tomllib.load(pfile) 252 | 253 | # validate pyproject.toml file if present 254 | validator_api.Validator()(pyproject) 255 | 256 | optional_deps = pyproject["project"]["optional-dependencies"] 257 | groups = ("dev", "tests", "style", "types", "audit") 258 | assert all(group in optional_deps for group in groups) 259 | 260 | # we don't want to hardcode all our deps here, 261 | # bc that would be a very fragile test indeed. 262 | # Instead, we just assume their presence and that the validity of the pyproject file 263 | # means that they have been correctly specified. 264 | # except for the docs, where we want to test our switch works :) 265 | if documentation: 266 | assert "docs" in optional_deps 267 | assert any(dep.startswith(documentation) for dep in optional_deps["docs"]) 268 | --------------------------------------------------------------------------------