From dd79ccd768e12bf45094c4cdd3ea62e00e4d12a5 Mon Sep 17 00:00:00 2001 From: Olga Lyashevska Date: Tue, 30 Jul 2024 12:03:59 +0200 Subject: [PATCH 01/29] Rename template folder and files in preparation of migration to copier --- {{{cookiecutter.directory_name}} => template}/.editorconfig | 0 .../.githooks/pre-commit | 0 .../.github/next_steps/01_sonarcloud_integration.md.jinja | 0 .../.github/next_steps/02_citation.md.jinja | 0 .../.github/next_steps/03_readthedocs.md.jinja | 0 .../.github/next_steps/04_zenodo_integration.md.jinja | 0 .../.github/next_steps/05_linting.md.jinja | 0 .../.github/workflows/build.yml | 0 .../.github/workflows/cffconvert.yml | 0 .../.github/workflows/documentation.yml | 0 .../.github/workflows/markdown-link-check.yml | 0 .../.github/workflows/next_steps.yml | 0 .../.github/workflows/sonarcloud.yml | 0 {{{cookiecutter.directory_name}} => template}/.gitignore | 0 {{{cookiecutter.directory_name}} => template}/.mlc-config.json | 0 {{{cookiecutter.directory_name}} => template}/.readthedocs.yaml | 0 {{{cookiecutter.directory_name}} => template}/CHANGELOG.md | 0 .../CITATION.cff => template/CITATION.cff.jinja | 0 .../CODE_OF_CONDUCT.md => template/CODE_OF_CONDUCT.md.jinja | 0 .../CONTRIBUTING.md => template/CONTRIBUTING.md.jinja | 0 {{cookiecutter.directory_name}}/LICENSE => template/LICENSE.jinja | 0 {{{cookiecutter.directory_name}} => template}/MANIFEST.in | 0 {{cookiecutter.directory_name}}/NOTICE => template/NOTICE.jinja | 0 .../README.dev.md => template/README.dev.md.jinja | 0 .../README.md => template/README.md.jinja | 0 .../docs/Makefile => template/docs/Makefile.jinja | 0 .../docs/_templates/.gitignore | 0 .../docs/conf.py => template/docs/conf.py.jinja | 0 .../docs/index.rst => template/docs/index.rst.jinja | 0 .../docs/make.bat => template/docs/make.bat.jinja | 0 .../next_steps.md => template/next_steps.md.jinja | 0 .../project_setup.md => template/project_setup.md.jinja | 0 .../pyproject.toml => template/pyproject.toml.jinja | 0 .../sonar-project.properties.jinja | 0 .../src/{{package_name}}/__init__.py.jinja | 0 .../src/{{package_name}}/my_module.py.jinja | 0 {{{cookiecutter.directory_name}} => template}/tests/__init__.py | 0 .../test_my_module.py => template/tests/test_my_module.py.jinja | 0 38 files changed, 0 insertions(+), 0 deletions(-) rename {{{cookiecutter.directory_name}} => template}/.editorconfig (100%) rename {{{cookiecutter.directory_name}} => template}/.githooks/pre-commit (100%) rename {{cookiecutter.directory_name}}/.github/next_steps/01_sonarcloud_integration.md => template/.github/next_steps/01_sonarcloud_integration.md.jinja (100%) rename {{cookiecutter.directory_name}}/.github/next_steps/02_citation.md => template/.github/next_steps/02_citation.md.jinja (100%) rename {{cookiecutter.directory_name}}/.github/next_steps/03_readthedocs.md => template/.github/next_steps/03_readthedocs.md.jinja (100%) rename {{cookiecutter.directory_name}}/.github/next_steps/04_zenodo_integration.md => template/.github/next_steps/04_zenodo_integration.md.jinja (100%) rename {{cookiecutter.directory_name}}/.github/next_steps/05_linting.md => template/.github/next_steps/05_linting.md.jinja (100%) rename {{{cookiecutter.directory_name}} => template}/.github/workflows/build.yml (100%) rename {{{cookiecutter.directory_name}} => template}/.github/workflows/cffconvert.yml (100%) rename {{{cookiecutter.directory_name}} => template}/.github/workflows/documentation.yml (100%) rename {{{cookiecutter.directory_name}} => template}/.github/workflows/markdown-link-check.yml (100%) rename {{{cookiecutter.directory_name}} => template}/.github/workflows/next_steps.yml (100%) rename {{{cookiecutter.directory_name}} => template}/.github/workflows/sonarcloud.yml (100%) rename {{{cookiecutter.directory_name}} => template}/.gitignore (100%) rename {{{cookiecutter.directory_name}} => template}/.mlc-config.json (100%) rename {{{cookiecutter.directory_name}} => template}/.readthedocs.yaml (100%) rename {{{cookiecutter.directory_name}} => template}/CHANGELOG.md (100%) rename {{cookiecutter.directory_name}}/CITATION.cff => template/CITATION.cff.jinja (100%) rename {{cookiecutter.directory_name}}/CODE_OF_CONDUCT.md => template/CODE_OF_CONDUCT.md.jinja (100%) rename {{cookiecutter.directory_name}}/CONTRIBUTING.md => template/CONTRIBUTING.md.jinja (100%) rename {{cookiecutter.directory_name}}/LICENSE => template/LICENSE.jinja (100%) rename {{{cookiecutter.directory_name}} => template}/MANIFEST.in (100%) rename {{cookiecutter.directory_name}}/NOTICE => template/NOTICE.jinja (100%) rename {{cookiecutter.directory_name}}/README.dev.md => template/README.dev.md.jinja (100%) rename {{cookiecutter.directory_name}}/README.md => template/README.md.jinja (100%) rename {{cookiecutter.directory_name}}/docs/Makefile => template/docs/Makefile.jinja (100%) rename {{{cookiecutter.directory_name}} => template}/docs/_templates/.gitignore (100%) rename {{cookiecutter.directory_name}}/docs/conf.py => template/docs/conf.py.jinja (100%) rename {{cookiecutter.directory_name}}/docs/index.rst => template/docs/index.rst.jinja (100%) rename {{cookiecutter.directory_name}}/docs/make.bat => template/docs/make.bat.jinja (100%) rename {{cookiecutter.directory_name}}/next_steps.md => template/next_steps.md.jinja (100%) rename {{cookiecutter.directory_name}}/project_setup.md => template/project_setup.md.jinja (100%) rename {{cookiecutter.directory_name}}/pyproject.toml => template/pyproject.toml.jinja (100%) rename {{cookiecutter.directory_name}}/sonar-project.properties => template/sonar-project.properties.jinja (100%) rename {{cookiecutter.directory_name}}/src/{{cookiecutter.package_name}}/__init__.py => template/src/{{package_name}}/__init__.py.jinja (100%) rename {{cookiecutter.directory_name}}/src/{{cookiecutter.package_name}}/my_module.py => template/src/{{package_name}}/my_module.py.jinja (100%) rename {{{cookiecutter.directory_name}} => template}/tests/__init__.py (100%) rename {{cookiecutter.directory_name}}/tests/test_my_module.py => template/tests/test_my_module.py.jinja (100%) diff --git a/{{cookiecutter.directory_name}}/.editorconfig b/template/.editorconfig similarity index 100% rename from {{cookiecutter.directory_name}}/.editorconfig rename to template/.editorconfig diff --git a/{{cookiecutter.directory_name}}/.githooks/pre-commit b/template/.githooks/pre-commit similarity index 100% rename from {{cookiecutter.directory_name}}/.githooks/pre-commit rename to template/.githooks/pre-commit diff --git a/{{cookiecutter.directory_name}}/.github/next_steps/01_sonarcloud_integration.md b/template/.github/next_steps/01_sonarcloud_integration.md.jinja similarity index 100% rename from {{cookiecutter.directory_name}}/.github/next_steps/01_sonarcloud_integration.md rename to template/.github/next_steps/01_sonarcloud_integration.md.jinja diff --git a/{{cookiecutter.directory_name}}/.github/next_steps/02_citation.md b/template/.github/next_steps/02_citation.md.jinja similarity index 100% rename from {{cookiecutter.directory_name}}/.github/next_steps/02_citation.md rename to template/.github/next_steps/02_citation.md.jinja diff --git a/{{cookiecutter.directory_name}}/.github/next_steps/03_readthedocs.md b/template/.github/next_steps/03_readthedocs.md.jinja similarity index 100% rename from {{cookiecutter.directory_name}}/.github/next_steps/03_readthedocs.md rename to template/.github/next_steps/03_readthedocs.md.jinja diff --git a/{{cookiecutter.directory_name}}/.github/next_steps/04_zenodo_integration.md b/template/.github/next_steps/04_zenodo_integration.md.jinja similarity index 100% rename from {{cookiecutter.directory_name}}/.github/next_steps/04_zenodo_integration.md rename to template/.github/next_steps/04_zenodo_integration.md.jinja diff --git a/{{cookiecutter.directory_name}}/.github/next_steps/05_linting.md b/template/.github/next_steps/05_linting.md.jinja similarity index 100% rename from {{cookiecutter.directory_name}}/.github/next_steps/05_linting.md rename to template/.github/next_steps/05_linting.md.jinja diff --git a/{{cookiecutter.directory_name}}/.github/workflows/build.yml b/template/.github/workflows/build.yml similarity index 100% rename from {{cookiecutter.directory_name}}/.github/workflows/build.yml rename to template/.github/workflows/build.yml diff --git a/{{cookiecutter.directory_name}}/.github/workflows/cffconvert.yml b/template/.github/workflows/cffconvert.yml similarity index 100% rename from {{cookiecutter.directory_name}}/.github/workflows/cffconvert.yml rename to template/.github/workflows/cffconvert.yml diff --git a/{{cookiecutter.directory_name}}/.github/workflows/documentation.yml b/template/.github/workflows/documentation.yml similarity index 100% rename from {{cookiecutter.directory_name}}/.github/workflows/documentation.yml rename to template/.github/workflows/documentation.yml diff --git a/{{cookiecutter.directory_name}}/.github/workflows/markdown-link-check.yml b/template/.github/workflows/markdown-link-check.yml similarity index 100% rename from {{cookiecutter.directory_name}}/.github/workflows/markdown-link-check.yml rename to template/.github/workflows/markdown-link-check.yml diff --git a/{{cookiecutter.directory_name}}/.github/workflows/next_steps.yml b/template/.github/workflows/next_steps.yml similarity index 100% rename from {{cookiecutter.directory_name}}/.github/workflows/next_steps.yml rename to template/.github/workflows/next_steps.yml diff --git a/{{cookiecutter.directory_name}}/.github/workflows/sonarcloud.yml b/template/.github/workflows/sonarcloud.yml similarity index 100% rename from {{cookiecutter.directory_name}}/.github/workflows/sonarcloud.yml rename to template/.github/workflows/sonarcloud.yml diff --git a/{{cookiecutter.directory_name}}/.gitignore b/template/.gitignore similarity index 100% rename from {{cookiecutter.directory_name}}/.gitignore rename to template/.gitignore diff --git a/{{cookiecutter.directory_name}}/.mlc-config.json b/template/.mlc-config.json similarity index 100% rename from {{cookiecutter.directory_name}}/.mlc-config.json rename to template/.mlc-config.json diff --git a/{{cookiecutter.directory_name}}/.readthedocs.yaml b/template/.readthedocs.yaml similarity index 100% rename from {{cookiecutter.directory_name}}/.readthedocs.yaml rename to template/.readthedocs.yaml diff --git a/{{cookiecutter.directory_name}}/CHANGELOG.md b/template/CHANGELOG.md similarity index 100% rename from {{cookiecutter.directory_name}}/CHANGELOG.md rename to template/CHANGELOG.md diff --git a/{{cookiecutter.directory_name}}/CITATION.cff b/template/CITATION.cff.jinja similarity index 100% rename from {{cookiecutter.directory_name}}/CITATION.cff rename to template/CITATION.cff.jinja diff --git a/{{cookiecutter.directory_name}}/CODE_OF_CONDUCT.md b/template/CODE_OF_CONDUCT.md.jinja similarity index 100% rename from {{cookiecutter.directory_name}}/CODE_OF_CONDUCT.md rename to template/CODE_OF_CONDUCT.md.jinja diff --git a/{{cookiecutter.directory_name}}/CONTRIBUTING.md b/template/CONTRIBUTING.md.jinja similarity index 100% rename from {{cookiecutter.directory_name}}/CONTRIBUTING.md rename to template/CONTRIBUTING.md.jinja diff --git a/{{cookiecutter.directory_name}}/LICENSE b/template/LICENSE.jinja similarity index 100% rename from {{cookiecutter.directory_name}}/LICENSE rename to template/LICENSE.jinja diff --git a/{{cookiecutter.directory_name}}/MANIFEST.in b/template/MANIFEST.in similarity index 100% rename from {{cookiecutter.directory_name}}/MANIFEST.in rename to template/MANIFEST.in diff --git a/{{cookiecutter.directory_name}}/NOTICE b/template/NOTICE.jinja similarity index 100% rename from {{cookiecutter.directory_name}}/NOTICE rename to template/NOTICE.jinja diff --git a/{{cookiecutter.directory_name}}/README.dev.md b/template/README.dev.md.jinja similarity index 100% rename from {{cookiecutter.directory_name}}/README.dev.md rename to template/README.dev.md.jinja diff --git a/{{cookiecutter.directory_name}}/README.md b/template/README.md.jinja similarity index 100% rename from {{cookiecutter.directory_name}}/README.md rename to template/README.md.jinja diff --git a/{{cookiecutter.directory_name}}/docs/Makefile b/template/docs/Makefile.jinja similarity index 100% rename from {{cookiecutter.directory_name}}/docs/Makefile rename to template/docs/Makefile.jinja diff --git a/{{cookiecutter.directory_name}}/docs/_templates/.gitignore b/template/docs/_templates/.gitignore similarity index 100% rename from {{cookiecutter.directory_name}}/docs/_templates/.gitignore rename to template/docs/_templates/.gitignore diff --git a/{{cookiecutter.directory_name}}/docs/conf.py b/template/docs/conf.py.jinja similarity index 100% rename from {{cookiecutter.directory_name}}/docs/conf.py rename to template/docs/conf.py.jinja diff --git a/{{cookiecutter.directory_name}}/docs/index.rst b/template/docs/index.rst.jinja similarity index 100% rename from {{cookiecutter.directory_name}}/docs/index.rst rename to template/docs/index.rst.jinja diff --git a/{{cookiecutter.directory_name}}/docs/make.bat b/template/docs/make.bat.jinja similarity index 100% rename from {{cookiecutter.directory_name}}/docs/make.bat rename to template/docs/make.bat.jinja diff --git a/{{cookiecutter.directory_name}}/next_steps.md b/template/next_steps.md.jinja similarity index 100% rename from {{cookiecutter.directory_name}}/next_steps.md rename to template/next_steps.md.jinja diff --git a/{{cookiecutter.directory_name}}/project_setup.md b/template/project_setup.md.jinja similarity index 100% rename from {{cookiecutter.directory_name}}/project_setup.md rename to template/project_setup.md.jinja diff --git a/{{cookiecutter.directory_name}}/pyproject.toml b/template/pyproject.toml.jinja similarity index 100% rename from {{cookiecutter.directory_name}}/pyproject.toml rename to template/pyproject.toml.jinja diff --git a/{{cookiecutter.directory_name}}/sonar-project.properties b/template/sonar-project.properties.jinja similarity index 100% rename from {{cookiecutter.directory_name}}/sonar-project.properties rename to template/sonar-project.properties.jinja diff --git a/{{cookiecutter.directory_name}}/src/{{cookiecutter.package_name}}/__init__.py b/template/src/{{package_name}}/__init__.py.jinja similarity index 100% rename from {{cookiecutter.directory_name}}/src/{{cookiecutter.package_name}}/__init__.py rename to template/src/{{package_name}}/__init__.py.jinja diff --git a/{{cookiecutter.directory_name}}/src/{{cookiecutter.package_name}}/my_module.py b/template/src/{{package_name}}/my_module.py.jinja similarity index 100% rename from {{cookiecutter.directory_name}}/src/{{cookiecutter.package_name}}/my_module.py rename to template/src/{{package_name}}/my_module.py.jinja diff --git a/{{cookiecutter.directory_name}}/tests/__init__.py b/template/tests/__init__.py similarity index 100% rename from {{cookiecutter.directory_name}}/tests/__init__.py rename to template/tests/__init__.py diff --git a/{{cookiecutter.directory_name}}/tests/test_my_module.py b/template/tests/test_my_module.py.jinja similarity index 100% rename from {{cookiecutter.directory_name}}/tests/test_my_module.py rename to template/tests/test_my_module.py.jinja From 616ee560498a469a579345cf9bb350e8fc32696b Mon Sep 17 00:00:00 2001 From: Olga Lyashevska Date: Tue, 30 Jul 2024 12:13:35 +0200 Subject: [PATCH 02/29] Migrate from cookiecutter to copier This migrates from cookiecutter template to copier while keeping all original features. Closes #348 Co-authored-by: Olga Lyashevska Co-authored-by: Sander van Rijn --- .copier-answers.yml | 0 .../ISSUE_TEMPLATE/10_generated_package.md | 2 +- .github/ISSUE_TEMPLATE/20_template.md | 2 +- .gitignore | 2 + ADD_TO_EXISTING_PACKAGE.md | 6 +- CITATION.cff | 2 +- README.md | 2 +- cookiecutter.json | 14 - copier.yml | 70 +++ hooks/post_gen_project.py | 1 - hooks/pre_gen_project.py | 11 - setup.cfg | 7 +- .../01_sonarcloud_integration.md.jinja | 6 +- .../.github/next_steps/02_citation.md.jinja | 4 +- .../next_steps/03_readthedocs.md.jinja | 10 +- .../next_steps/04_zenodo_integration.md.jinja | 2 +- .../.github/next_steps/05_linting.md.jinja | 4 +- template/.gitignore | 2 + template/CITATION.cff.jinja | 16 +- template/CODE_OF_CONDUCT.md.jinja | 2 +- template/CONTRIBUTING.md.jinja | 18 +- template/NOTICE.jinja | 4 +- template/README.dev.md.jinja | 20 +- template/docs/Makefile.jinja | 2 +- template/docs/conf.py.jinja | 8 +- template/docs/index.rst.jinja | 4 +- template/docs/make.bat.jinja | 2 +- template/next_steps.md.jinja | 10 +- template/project_setup.md.jinja | 2 +- template/pyproject.toml.jinja | 32 +- template/sonar-project.properties.jinja | 14 +- .../src/{{package_name}}/__init__.py.jinja | 8 +- .../src/{{package_name}}/my_module.py.jinja | 4 +- template/tests/test_my_module.py.jinja | 4 +- ...== 'Apache-2.0' %}LICENSE{% endif %}.jinja | 201 +++++++++ ...= 'BSD license' %}LICENSE{% endif %}.jinja | 30 ++ ...e v3 or later' %}LICENSE{% endif %}.jinja} | 419 ------------------ ...se v3 or later' %}LICENSE{% endif %}.jinja | 166 +++++++ ...= 'ISC license' %}LICENSE{% endif %}.jinja | 12 + ...= 'MIT licence' %}LICENSE{% endif %}.jinja | 16 + ...ot open source' %}LICENSE{% endif %}.jinja | 1 + template/{{_copier_conf.answers_file}}.jinja | 2 + tests/test_project.py | 24 +- tests/test_values.py | 16 +- 44 files changed, 622 insertions(+), 562 deletions(-) create mode 100644 .copier-answers.yml delete mode 100644 cookiecutter.json create mode 100644 copier.yml delete mode 100644 hooks/post_gen_project.py delete mode 100644 hooks/pre_gen_project.py create mode 100644 template/{% if license == 'Apache-2.0' %}LICENSE{% endif %}.jinja create mode 100644 template/{% if license == 'BSD license' %}LICENSE{% endif %}.jinja rename template/{LICENSE.jinja => {% if license == 'GNU General Public License v3 or later' %}LICENSE{% endif %}.jinja} (60%) create mode 100644 template/{% if license == 'GNU Lesser General Public License v3 or later' %}LICENSE{% endif %}.jinja create mode 100644 template/{% if license == 'ISC license' %}LICENSE{% endif %}.jinja create mode 100644 template/{% if license == 'MIT licence' %}LICENSE{% endif %}.jinja create mode 100644 template/{% if license == 'Not open source' %}LICENSE{% endif %}.jinja create mode 100644 template/{{_copier_conf.answers_file}}.jinja diff --git a/.copier-answers.yml b/.copier-answers.yml new file mode 100644 index 00000000..e69de29b diff --git a/.github/ISSUE_TEMPLATE/10_generated_package.md b/.github/ISSUE_TEMPLATE/10_generated_package.md index 3fdb2a41..19215dd6 100644 --- a/.github/ISSUE_TEMPLATE/10_generated_package.md +++ b/.github/ISSUE_TEMPLATE/10_generated_package.md @@ -7,5 +7,5 @@ assignees: '' --- diff --git a/.github/ISSUE_TEMPLATE/20_template.md b/.github/ISSUE_TEMPLATE/20_template.md index c25688bf..df6e73dc 100644 --- a/.github/ISSUE_TEMPLATE/20_template.md +++ b/.github/ISSUE_TEMPLATE/20_template.md @@ -7,5 +7,5 @@ assignees: '' --- diff --git a/.gitignore b/.gitignore index ec774d30..5b4bd3df 100644 --- a/.gitignore +++ b/.gitignore @@ -26,3 +26,5 @@ env env3 venv venv3 + +.swp diff --git a/ADD_TO_EXISTING_PACKAGE.md b/ADD_TO_EXISTING_PACKAGE.md index 140c28ea..9edfca2b 100644 --- a/ADD_TO_EXISTING_PACKAGE.md +++ b/ADD_TO_EXISTING_PACKAGE.md @@ -4,12 +4,12 @@ The following steps requires that your existing code is in a GitHub repository. 1. Follow the [instructions to create a new package](https://github.com/NLeSC/python-template#how-to-use) with the Python template, while answering the questions like you would for the existing package. -2. Create a Git structure for the new directory: (replace `` with directory name you used during cookiecutter questionnaire) +2. Create a Git structure for the new directory: (replace `` with directory name you used during coopier questionnaire) ```shell $ cd $ git init $ git add --all -$ git commit -m "Added code generated by cookiecutter" +$ git commit -m "Added code generated by copier" $ git branch -M main ``` @@ -24,6 +24,6 @@ $ git merge existing_code/ --allow-unrelated-histories 5. Once all conflicts have been resolved then add all the files to GitHub: ```shell $ git add --all -$ git commit -m "Merged existing code with code generated by cookiecutter" +$ git commit -m "Merged existing code with code generated by copier" $ git push ``` diff --git a/CITATION.cff b/CITATION.cff index 045e0e43..ca4e3295 100644 --- a/CITATION.cff +++ b/CITATION.cff @@ -72,7 +72,7 @@ cff-version: "1.2.0" date-released: 2018-07-17 doi: 10.5281/zenodo.1310751 keywords: - - cookiecutter + - copier - template - Python license: Apache-2.0 diff --git a/README.md b/README.md index e23cebc9..181db8c8 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ Use this [Cookiecutter](https://cookiecutter.readthedocs.io) template to generat an empty Python package. Features include: - Boilerplate unit tests and documentation, -- [Python static setup configuration]({{cookiecutter.directory_name}}/pyproject.toml), +- [Python static setup configuration]({{directory_name}}/pyproject.toml), - Open source software license, - Continuous integration with [GitHub action workflows]({{cookiecutter.directory_name}}/.github/workflows) for building, testing, link checking and linting, - Code style checking with [ruff](https://beta.ruff.rs/), diff --git a/cookiecutter.json b/cookiecutter.json deleted file mode 100644 index 60d0b3f3..00000000 --- a/cookiecutter.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "directory_name": "my-python-project", - "package_name": "my_python_package", - "package_short_description": "Short description of package", - "keyword1": "keyword1", - "keyword2": "keyword2", - "version": "0.1.0", - "github_organization": "", - "license": ["Apache Software License 2.0", "MIT license", "BSD license", "ISC license", "GNU General Public License v3 or later", "GNU Lesser General Public License v3 or later", "Not open source"], - "full_name": "Jane Smith", - "email": "yourname@esciencecenter.nl", - "copyright_holder": "Netherlands eScience Center", - "code_of_conduct_email": "{{ cookiecutter.email }}" -} diff --git a/copier.yml b/copier.yml new file mode 100644 index 00000000..77fc3fd3 --- /dev/null +++ b/copier.yml @@ -0,0 +1,70 @@ +# Essential questions + +package_name: + type: str + default: my_python_package + help: Enter the name of the Python package. + validator: >- + {% if not (package_name | regex_search('^[a-z][a-z0-9\_]+$')) %} + package_name must start with a letter, followed one or more letters, digits or underscores all lowercase. + {% endif %} +package_short_description: + type: str + default: Short description of package + # validator: >- + # {% if '"' in package_short_description %} + # package_short_description must not contain unescaped double quotes. Use \\" for double quotes. + # {% endif %} +keyword1: + type: str + default: keyword1 +keyword2: + type: str + default: keyword2 +version: + type: str + default: 0.1.0 +github_organization: + type: str + default: "" +license: + type: str + choices: + - "Apache Software License 2.0" + - "MIT license" + - "BSD license" + - "ISC license" + - "GNU General Public License v3 or later" + - "GNU Lesser General Public License v3 or later" + - "Not open source" + default: "MIT license" +full_name: + type: str + default: Jane Smith + help: Enter your full name. + # validator: >- + # {% if '"' in full_name %} + # full_name must not contain unescaped double quotes. Use \\" for double quotes. + # {% endif %} +email: + type: str + default: yourname@esciencecenter.nl +copyright_holder: + type: str + default: Netherlands eScience Center +code_of_conduct_email: + type: str + default: "{{ email }}" + +_subdirectory: template + +repository: + default: git@github.com:{{ github_organization }}/{{ directory_name }} + when: false + +repository_url: + default: https://github.com/{{ github_organization }}/{{ directory_name }} + when: false + + +# Optional questions diff --git a/hooks/post_gen_project.py b/hooks/post_gen_project.py deleted file mode 100644 index f7ceaa80..00000000 --- a/hooks/post_gen_project.py +++ /dev/null @@ -1 +0,0 @@ -print("\nProject was successfully generated. For next steps, refer to file {{ cookiecutter.directory_name }}/next_steps.md.\n") diff --git a/hooks/pre_gen_project.py b/hooks/pre_gen_project.py deleted file mode 100644 index 665cbe50..00000000 --- a/hooks/pre_gen_project.py +++ /dev/null @@ -1,11 +0,0 @@ -# Note: cookiecutter first makes the main level directory using -# directory_name from cookiecutter.json before running this hook - -{{ cookiecutter.update({ - "package_name": cookiecutter.package_name.lower().replace(" ", "_").replace("-", "_"), - "directory_name": cookiecutter.directory_name.lower().replace(" ", "-"), - "full_name": cookiecutter.full_name.replace('\"', '\\\"'), - "repository": "git@github.com:" + cookiecutter.github_organization + "/" + cookiecutter.directory_name.lower().replace(" ", "-"), - "repository_url": "https://github.com/" + cookiecutter.github_organization + "/" + cookiecutter.directory_name.lower().replace(" ", "-"), - "package_short_description": cookiecutter.package_short_description.replace('\"', '\\\"') -}) }} diff --git a/setup.cfg b/setup.cfg index 5aef0661..b6b2cb16 100644 --- a/setup.cfg +++ b/setup.cfg @@ -33,7 +33,7 @@ include_package_data = True python_requires = >=3.8 packages = install_requires = - cookiecutter==1.7.2 + copier==9.2.0 [options.data_files] # This section requires setuptools>=40.6.0 @@ -45,9 +45,10 @@ install_requires = dev = coverage [toml] pytest - pytest-cookies + pytest-copie + pyprojroot [tool:pytest] testpaths = tests -norecursedirs = .git .github hooks {{cookiecutter.directory_name}} +norecursedirs = .git .github hooks {{directory_name}} diff --git a/template/.github/next_steps/01_sonarcloud_integration.md.jinja b/template/.github/next_steps/01_sonarcloud_integration.md.jinja index 23761831..152edb6b 100644 --- a/template/.github/next_steps/01_sonarcloud_integration.md.jinja +++ b/template/.github/next_steps/01_sonarcloud_integration.md.jinja @@ -4,13 +4,13 @@ title: 'Next step: Sonarcloud integration' Continuous code quality can be handled by [Sonarcloud](https://sonarcloud.io/). This repository is configured to use Sonarcloud to perform quality analysis and code coverage report on each push. -In order to configure Sonarcloud analysis [GitHub Action workflow]({{cookiecutter.repository_url}}/blob/main/.github/workflows/sonarcloud.yml) you must follow the steps below: +In order to configure Sonarcloud analysis [GitHub Action workflow]({{repository_url}}/blob/main/.github/workflows/sonarcloud.yml) you must follow the steps below: 1. go to [Sonarcloud](https://sonarcloud.io/projects/create) to create a new Sonarcloud project 1. login with your GitHub account 1. add Sonarcloud organization or reuse existing one 1. set up a repository -1. go to [new code definition administration page](https://sonarcloud.io/project/new_code?id={{cookiecutter.github_organization}}_{{cookiecutter.directory_name}}) and select `Number of days` option +1. go to [new code definition administration page](https://sonarcloud.io/project/new_code?id={{github_organization}}_{{directory_name}}) and select `Number of days` option 1. To be able to run the analysis: 1. a token must be created at [Sonarcloud account](https://sonarcloud.io/account/security/) - 1. the created token must be added as `SONAR_TOKEN` to [secrets on GitHub](https://github.com/{{cookiecutter.github_organization}}/{{cookiecutter.directory_name}}/settings/secrets/actions) + 1. the created token must be added as `SONAR_TOKEN` to [secrets on GitHub](https://github.com/{{github_organization}}/{{directory_name}}/settings/secrets/actions) diff --git a/template/.github/next_steps/02_citation.md.jinja b/template/.github/next_steps/02_citation.md.jinja index 7a3279d7..90ffd88f 100644 --- a/template/.github/next_steps/02_citation.md.jinja +++ b/template/.github/next_steps/02_citation.md.jinja @@ -2,7 +2,7 @@ title: 'Next step: Citation data' --- -It is likely that your `CITATION.cff` currently doesn't pass validation. The error messages you get from the [`cffconvert`]({{cookiecutter.repository_url}}/actions/workflows/cffconvert.yml) GitHub Action are unfortunately a bit cryptic, but doing the following helps: +It is likely that your `CITATION.cff` currently doesn't pass validation. The error messages you get from the [`cffconvert`]({{repository_url}}/actions/workflows/cffconvert.yml) GitHub Action are unfortunately a bit cryptic, but doing the following helps: - [ ] Check if the `given-name` and `family-name` keys need updating. If your family name has a name particle like `von` or `van` or `de`, use the `name-particle` key; if your name has a suffix like `Sr` or `IV`, use `name-suffix`. For details, refer to the schema description: https://github.com/citation-file-format/citation-file-format - [ ] Update the value of the `orcid` key. If you do not have an orcid yet, you can get one here [https://orcid.org/](https://orcid.org/). @@ -13,7 +13,7 @@ It is likely that your `CITATION.cff` currently doesn't pass validation. The err Afterwards, the `cffconvert` GitHub Action should be green. -To make sure services like [Zenodo](https://zenodo.org) and the [Research Software Directory](https://research-software-directory.org/) can keep your citation data up to date, the [`cffconvert`]({{cookiecutter.repository_url}}/actions/workflows/cffconvert.yml) GitHub Action checks the following: +To make sure services like [Zenodo](https://zenodo.org) and the [Research Software Directory](https://research-software-directory.org/) can keep your citation data up to date, the [`cffconvert`]({{repository_url}}/actions/workflows/cffconvert.yml) GitHub Action checks the following: 1. Whether your repository includes a `CITATION.cff` file. diff --git a/template/.github/next_steps/03_readthedocs.md.jinja b/template/.github/next_steps/03_readthedocs.md.jinja index fb72b7f3..5c7917d0 100644 --- a/template/.github/next_steps/03_readthedocs.md.jinja +++ b/template/.github/next_steps/03_readthedocs.md.jinja @@ -9,12 +9,12 @@ To host the documentation of this repository please perform the following instru 1. go to [Read the Docs](https://readthedocs.org/dashboard/import/?) 1. log in with your GitHub account -1. find `{{ cookiecutter.github_organization }}/{{ cookiecutter.directory_name }}` in list and press `+` button. +1. find `{{ github_organization }}/{{ directory_name }}` in list and press `+` button. * If repository is not listed, 1. go to [Read the Docs GitHub app](https://github.com/settings/connections/applications/fae83c942bc1d89609e2) - 2. make sure {{ cookiecutter.github_organization }} has been granted access. + 2. make sure {{ github_organization }} has been granted access. 3. reload repository list on Read the Docs import page -1. wait for the first build to be completed at -1. check that the link of the documentation badge in the [README.md]({{ cookiecutter.repository_url }}) works +1. wait for the first build to be completed at +1. check that the link of the documentation badge in the [README.md]({{ repository_url }}) works -See [README.dev.md#]({{cookiecutter.repository_url}}/blob/main/README.dev.md#generating-the-api-docs) how to build documentation site locally. +See [README.dev.md#]({{repository_url}}/blob/main/README.dev.md#generating-the-api-docs) how to build documentation site locally. diff --git a/template/.github/next_steps/04_zenodo_integration.md.jinja b/template/.github/next_steps/04_zenodo_integration.md.jinja index 45ecb639..911d824b 100644 --- a/template/.github/next_steps/04_zenodo_integration.md.jinja +++ b/template/.github/next_steps/04_zenodo_integration.md.jinja @@ -8,7 +8,7 @@ To enable Zenodo integration: 1. Go to http://zenodo.org and login with your GitHub account. When you are redirected to GitHub, *Authorize application* to give permission to Zenodo to access your account. 1. Go to and enable Zenodo integration of your repository by clicking on `On` toggle button. -2. Your package will get a DOI only after you make a release. Create a new release as described in [README.dev.md]({{cookiecutter.repository_url}}/blob/main/README.dev.md#33-github) +2. Your package will get a DOI only after you make a release. Create a new release as described in [README.dev.md]({{repository_url}}/blob/main/README.dev.md#33-github) 3. At this point you should have a DOI. To find out the DOI generated by Zenodo: 1. Visit https://zenodo.org/deposit and click on your repository link 2. You will find the latest DOI in the right column in Versions box in **Cite all versions?** section diff --git a/template/.github/next_steps/05_linting.md.jinja b/template/.github/next_steps/05_linting.md.jinja index cc603833..3c1db2b7 100644 --- a/template/.github/next_steps/05_linting.md.jinja +++ b/template/.github/next_steps/05_linting.md.jinja @@ -2,9 +2,9 @@ title: 'Next step: Linting' --- -Your repository has a [workflow]({{ cookiecutter.repository_url }}/blob/main/.github/workflows/build.yml) which [lints](https://en.wikipedia.org/wiki/Lint_(software)) your code after every push and when creating a pull request. +Your repository has a [workflow]({{ repository_url }}/blob/main/.github/workflows/build.yml) which [lints](https://en.wikipedia.org/wiki/Lint_(software)) your code after every push and when creating a pull request. -Linter workflow may fail if `description` or `keywords` field in [pyproject.toml]({{ cookiecutter.repository_url }}/blob/main/pyproject.toml) is empty. Please update these fields. To validate your changes run: +Linter workflow may fail if `description` or `keywords` field in [pyproject.toml]({{ repository_url }}/blob/main/pyproject.toml) is empty. Please update these fields. To validate your changes run: ```shell ruff . diff --git a/template/.gitignore b/template/.gitignore index 57fb2ab9..baba4dd6 100644 --- a/template/.gitignore +++ b/template/.gitignore @@ -29,3 +29,5 @@ env env3 venv venv3 + +.swp diff --git a/template/CITATION.cff.jinja b/template/CITATION.cff.jinja index 88cb9c25..c4facdd5 100644 --- a/template/CITATION.cff.jinja +++ b/template/CITATION.cff.jinja @@ -1,19 +1,19 @@ # YAML 1.2 --- cff-version: "1.2.0" -title: "{{ cookiecutter.package_name }}" +title: "{{ package_name }}" authors: - - family-names: {{ cookiecutter.full_name.split(' ')[-1] }} - given-names: {{ cookiecutter.full_name.split(' ')[0] }} + family-names: {{ full_name.split(' ')[-1] }} + given-names: {{ full_name.split(' ')[0] }} orcid: "https://orcid.org/0000-0000-0000-0000" date-released: 20??-MM-DD doi: -version: "{{ cookiecutter.version }}" -repository-code: "{{ cookiecutter.repository_url }}" +version: "{{ version }}" +repository-code: "{{ repository_url }}" keywords: - - {{ cookiecutter.keyword1 }} - - {{ cookiecutter.keyword2 }} + - {{ keyword1 }} + - {{ keyword2 }} message: "If you use this software, please cite it using these metadata." {{ { "Apache Software License 2.0": "license: Apache-2.0", "MIT license": "license: MIT", @@ -21,4 +21,4 @@ message: "If you use this software, please cite it using these metadata." "ISC license": "license: ISC", "GNU General Public License v3 or later": "license: GPL-3.0-or-later", "Not open source": "" -}[cookiecutter.license] }} +}[license] }} diff --git a/template/CODE_OF_CONDUCT.md.jinja b/template/CODE_OF_CONDUCT.md.jinja index 500a1c9e..ed591351 100644 --- a/template/CODE_OF_CONDUCT.md.jinja +++ b/template/CODE_OF_CONDUCT.md.jinja @@ -55,7 +55,7 @@ further defined and clarified by project maintainers. ## Enforcement Instances of abusive, harassing, or otherwise unacceptable behavior may be -reported by contacting the project team at {{ cookiecutter.code_of_conduct_email }}. All +reported by contacting the project team at {{ code_of_conduct_email }}. All complaints will be reviewed and investigated and will result in a response that is deemed necessary and appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. diff --git a/template/CONTRIBUTING.md.jinja b/template/CONTRIBUTING.md.jinja index c3ec5d42..fe1b7e11 100644 --- a/template/CONTRIBUTING.md.jinja +++ b/template/CONTRIBUTING.md.jinja @@ -13,13 +13,13 @@ The sections below outline the steps in each case. ## You have a question -1. use the search functionality [here]({{cookiecutter.repository_url}}/issues) to see if someone already filed the same issue; +1. use the search functionality [here]({{repository_url}}/issues) to see if someone already filed the same issue; 2. if your issue search did not yield any relevant results, make a new issue; 3. apply the "Question" label; apply other labels when relevant. ## You think you may have found a bug -1. use the search functionality [here]({{cookiecutter.repository_url}}/issues) to see if someone already filed the same issue; +1. use the search functionality [here]({{repository_url}}/issues) to see if someone already filed the same issue; 1. if your issue search did not yield any relevant results, make a new issue, making sure to provide enough information to the rest of the community to understand the cause and context of the problem. Depending on the issue, you may want to include: - the [SHA hashcode](https://help.github.com/articles/autolinked-references-and-urls/#commit-shas) of the commit that is causing your problem; - some identifying information (name and version number) for dependencies you're using; @@ -36,7 +36,7 @@ The sections below outline the steps in each case. 1. add your own tests (if necessary); 1. update or expand the documentation; 1. update the `CHANGELOG.md` file with your change; -1. [push](http://rogerdudler.github.io/git-guide/) your feature branch to (your fork of) the {{ cookiecutter.package_name }} repository on GitHub; +1. [push](http://rogerdudler.github.io/git-guide/) your feature branch to (your fork of) the {{ package_name }} repository on GitHub; 1. create the pull request, e.g. following the instructions [here](https://help.github.com/articles/creating-a-pull-request/). In case you feel like you've made a valuable contribution, but you don't know how to write or run tests for it, or how to generate the documentation: don't let this discourage you from making the pull request; we can help you! Just go ahead and submit the pull request, but keep in mind that you might be asked to append additional commits to your pull request. @@ -46,23 +46,23 @@ In case you feel like you've made a valuable contribution, but you don't know ho To create a release you need write permission on the repository. 1. Check the author list in [`CITATION.cff`](CITATION.cff) -1. Bump the version using `bump-my-version bump `. For example, `bump-my-version bump major` will increase major version numbers everywhere it's needed (code, meta, etc.) in the repo. Alternatively the version can be manually changed in {{ cookiecutter.package_name }}/__init__.py, pyproject.toml, CITATION.cff and docs/conf.py (and other places it was possibly added). +1. Bump the version using `bump-my-version bump `. For example, `bump-my-version bump major` will increase major version numbers everywhere it's needed (code, meta, etc.) in the repo. Alternatively the version can be manually changed in {{ package_name }}/__init__.py, pyproject.toml, CITATION.cff and docs/conf.py (and other places it was possibly added). 1. Update the `CHANGELOG.md` to include changes made -1. Go to the [GitHub release page]({{ cookiecutter.repository_url }}/releases) +1. Go to the [GitHub release page]({{ repository_url }}/releases) 1. Press draft a new release button 1. Fill version, title and description field 1. Press the Publish Release button -Also a Zenodo entry will be made for the release with its own DOI. \ No newline at end of file +Also a Zenodo entry will be made for the release with its own DOI. diff --git a/template/NOTICE.jinja b/template/NOTICE.jinja index 3ddc2d32..6bfd7580 100644 --- a/template/NOTICE.jinja +++ b/template/NOTICE.jinja @@ -1,2 +1,2 @@ -This product includes {{ cookiecutter.package_name }}, software developed by -{{ cookiecutter.copyright_holder }}. +This product includes {{ package_name }}, software developed by +{{ copyright_holder }}. diff --git a/template/README.dev.md.jinja b/template/README.dev.md.jinja index b839f920..b108be81 100644 --- a/template/README.dev.md.jinja +++ b/template/README.dev.md.jinja @@ -1,4 +1,4 @@ -# `{{ cookiecutter.package_name }}` developer documentation +# `{{ package_name }}` developer documentation If you're looking for user documentation, go [here](README.md). @@ -15,7 +15,7 @@ source env/bin/activate python -m pip install --upgrade pip setuptools # (from the project root directory) -# install {{ cookiecutter.package_name }} as an editable package +# install {{ package_name }} as an editable package python -m pip install --no-cache-dir --editable . # install development dependencies python -m pip install --no-cache-dir --editable .[dev] @@ -35,7 +35,7 @@ The first way requires an activated virtual environment with the development too pytest -v ``` -The second is to use `tox`, which can be installed separately (e.g. with `pip install tox`), i.e. not necessarily inside the virtual environment you use for installing `{{ cookiecutter.package_name }}`, but then builds the necessary virtual environments itself by simply running: +The second is to use `tox`, which can be installed separately (e.g. with `pip install tox`), i.e. not necessarily inside the virtual environment you use for installing `{{ package_name }}`, but then builds the necessary virtual environments itself by simply running: ```shell tox @@ -64,7 +64,7 @@ coverage report ## Running linters locally -For linting and sorting imports we will use [ruff](https://beta.ruff.rs/docs/). Running the linters requires an +For linting and sorting imports we will use [ruff](https://beta.ruff.rs/docs/). Running the linters requires an activated virtual environment with the development tools installed. ```shell @@ -145,8 +145,8 @@ In a new terminal: ```shell # OPTIONAL: prepare a new directory with fresh git clone to ensure the release # has the state of origin/main branch -cd $(mktemp -d {{ cookiecutter.package_name }}.XXXXXX) -git clone {{ cookiecutter.repository }} . +cd $(mktemp -d {{ package_name }}.XXXXXX) +git clone {{ repository }} . # make sure to have a recent version of pip and the publishing dependencies python -m pip install --upgrade pip @@ -160,13 +160,13 @@ python -m twine upload --repository testpypi dist/* ``` Visit -[https://test.pypi.org/project/{{cookiecutter.package_name}}](https://test.pypi.org/project/{{cookiecutter.package_name}}) +[https://test.pypi.org/project/{{package_name}}](https://test.pypi.org/project/{{package_name}}) and verify that your package was uploaded successfully. Keep the terminal open, we'll need it later. In a new terminal, without an activated virtual environment or an env directory: ```shell -cd $(mktemp -d {{ cookiecutter.package_name }}-test.XXXXXX) +cd $(mktemp -d {{ package_name }}-test.XXXXXX) # prepare a clean virtual environment and activate it python -m venv env @@ -178,7 +178,7 @@ python -m pip install --upgrade pip # install from test pypi instance: python -m pip -v install --no-cache-dir \ --index-url https://test.pypi.org/simple/ \ ---extra-index-url https://pypi.org/simple {{ cookiecutter.package_name }} +--extra-index-url https://pypi.org/simple {{ package_name }} ``` Check that the package works as it should when installed from pypitest. @@ -193,4 +193,4 @@ python -m twine upload dist/* ### (3/3) GitHub -Don't forget to also make a [release on GitHub]({{cookiecutter.repository_url}}/releases/new). If your repository uses the GitHub-Zenodo integration this will also trigger Zenodo into making a snapshot of your repository and sticking a DOI on it. +Don't forget to also make a [release on GitHub]({{repository_url}}/releases/new). If your repository uses the GitHub-Zenodo integration this will also trigger Zenodo into making a snapshot of your repository and sticking a DOI on it. diff --git a/template/docs/Makefile.jinja b/template/docs/Makefile.jinja index 48ea1625..db428cf5 100644 --- a/template/docs/Makefile.jinja +++ b/template/docs/Makefile.jinja @@ -4,7 +4,7 @@ # You can set these variables from the command line. SPHINXOPTS = SPHINXBUILD = sphinx-build -SPHINXPROJ = {{ cookiecutter.package_name }} +SPHINXPROJ = {{ package_name }} SOURCEDIR = . BUILDDIR = _build diff --git a/template/docs/conf.py.jinja b/template/docs/conf.py.jinja index c73e3d3b..530c4d8f 100644 --- a/template/docs/conf.py.jinja +++ b/template/docs/conf.py.jinja @@ -17,9 +17,9 @@ # -- Project information ----------------------------------------------------- -project = u"{{ cookiecutter.package_name }}" -copyright = u"{% now "local", "%Y" %}, {{ cookiecutter.copyright_holder }}" -author = u"{{ cookiecutter.full_name.replace('\"', '\\\"') }}" +project = u"{{ package_name }}" +copyright = u"{{ '%Y-%m-%d %H:%M:%S' | strftime }}, {{ copyright_holder }}" +author = u"{{ full_name.replace('\"', '\\\"') }}" # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the @@ -61,7 +61,7 @@ todo_include_todos = False # -- Use autoapi.extension to run sphinx-apidoc ------- -autoapi_dirs = ['../src/{{ cookiecutter.package_name }}'] +autoapi_dirs = ['../src/{{ package_name }}'] # -- Options for HTML output ---------------------------------------------- diff --git a/template/docs/index.rst.jinja b/template/docs/index.rst.jinja index d4af697b..61a86b28 100644 --- a/template/docs/index.rst.jinja +++ b/template/docs/index.rst.jinja @@ -1,9 +1,9 @@ -.. {{ cookiecutter.package_name }} documentation master file, created by +.. {{ package_name }} documentation master file, created by sphinx-quickstart on Wed May 5 22:45:36 2021. You can adapt this file completely to your liking, but it should at least contain the root `toctree` directive. -Welcome to {{ cookiecutter.package_name }}'s documentation! +Welcome to {{ package_name }}'s documentation! ========================================================== .. toctree:: diff --git a/template/docs/make.bat.jinja b/template/docs/make.bat.jinja index 8176c5be..aa58b03f 100644 --- a/template/docs/make.bat.jinja +++ b/template/docs/make.bat.jinja @@ -9,7 +9,7 @@ if "%SPHINXBUILD%" == "" ( ) set SOURCEDIR=. set BUILDDIR=_build -set SPHINXPROJ={{ cookiecutter.package_name }} +set SPHINXPROJ={{ package_name }} if "%1" == "" goto help diff --git a/template/next_steps.md.jinja b/template/next_steps.md.jinja index c9710c54..a44875d6 100644 --- a/template/next_steps.md.jinja +++ b/template/next_steps.md.jinja @@ -14,19 +14,19 @@ Alternatively, you can also use a personal access token, see `git@github.com:` by `https://github.com/`. ```shell -cd {{ cookiecutter.directory_name }} +cd {{ directory_name }} git init git add --all git commit -m "first commit" git branch -M main -git remote add origin {{ cookiecutter.repository }} +git remote add origin {{ repository }} ``` ## Push the initial commit to a new repo on GitHub Go to -[https://github.com/organizations/{{cookiecutter.github_organization}}/repositories/new](https://github.com/organizations/{{cookiecutter.github_organization}}/repositories/new) -and create a new repository named `{{ cookiecutter.directory_name }}` as an empty repository, then push your commits to GitHub: +[https://github.com/organizations/{{github_organization}}/repositories/new](https://github.com/organizations/{{github_organization}}/repositories/new) +and create a new repository named `{{ directory_name }}` as an empty repository, then push your commits to GitHub: ```shell git push --set-upstream origin main @@ -35,7 +35,7 @@ git push --set-upstream origin main ## Check automatically generated issues A short while after you push your commits to GitHub for the first time, a few issues outlining next steps will added -automatically ([here]({{cookiecutter.repository_url}}/issues?q=author%3Aapp%2Fgithub-actions)). Resolve them to complete the +automatically ([here]({{repository_url}}/issues?q=author%3Aapp%2Fgithub-actions)). Resolve them to complete the setup of your repository. ## Project development documentation diff --git a/template/project_setup.md.jinja b/template/project_setup.md.jinja index 3d1b196e..ca065bf2 100644 --- a/template/project_setup.md.jinja +++ b/template/project_setup.md.jinja @@ -76,7 +76,7 @@ help you decide which tool to use for packaging. ## Package version number - We recommend using [semantic versioning](https://guide.esciencecenter.nl/#/best_practices/releases?id=semantic-versioning). -- For convenience, the package version is stored in a single place: `{{ cookiecutter.directory_name }}/pyproject.toml` under the `tool.bumpversion` header. +- For convenience, the package version is stored in a single place: `{{ directory_name }}/pyproject.toml` under the `tool.bumpversion` header. - Don't forget to update the version number before [making a release](https://guide.esciencecenter.nl/#/best_practices/releases)! ## Logging diff --git a/template/pyproject.toml.jinja b/template/pyproject.toml.jinja index ffdb0a0b..4298f46d 100644 --- a/template/pyproject.toml.jinja +++ b/template/pyproject.toml.jinja @@ -9,7 +9,7 @@ build-backend = "setuptools.build_meta" [project] authors = [ - { name = "{{ cookiecutter.full_name }}", email = "{{ cookiecutter.email }}" } + { name = "{{ full_name }}", email = "{{ email }}" } ] classifiers = [ "Development Status :: 2 - Pre-Alpha", @@ -21,7 +21,7 @@ classifiers = [ 'ISC license': 'License :: OSI Approved :: ISC License (ISCL)', 'GNU General Public License v3 or later': 'License :: OSI Approved :: GNU General Public License', 'Not open source': 'License :: Other/Proprietary License' - }[cookiecutter.license] }}", + }[license] }}", "Natural Language :: English", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.8", @@ -31,16 +31,16 @@ classifiers = [ "Programming Language :: Python :: 3.12", ] dependencies = [] -description = "{{ cookiecutter.package_short_description }}" +description = "{{ package_short_description }}" keywords = [ - "{{ cookiecutter.keyword1 }}", - "{{ cookiecutter.keyword2 }}", + "{{ keyword1 }}", + "{{ keyword2 }}", ] license = {file = "LICENSE"} -name = "{{ cookiecutter.package_name }}" +name = "{{ package_name }}" readme = {file = "README.md", content-type = "text/markdown"} requires-python = ">=3.8" -version = "{{ cookiecutter.version }}" +version = "{{ version }}" [project.optional-dependencies] dev = [ @@ -69,24 +69,24 @@ publishing = [ ] [project.urls] -Repository = "{{ cookiecutter.repository_url }}" -Issues = "{{ cookiecutter.repository_url }}/issues" -Changelog = "{{ cookiecutter.repository_url }}/CHANGELOG.md" +Repository = "{{ repository_url }}" +Issues = "{{ repository_url }}/issues" +Changelog = "{{ repository_url }}/CHANGELOG.md" [tool.pytest.ini_options] testpaths = ["tests"] [tool.coverage.run] branch = true -source = ["src/{{ cookiecutter.package_name }}"] +source = ["src/{{ package_name }}"] command_line = "-m pytest" [tool.isort] lines_after_imports = 2 force_single_line = 1 no_lines_before = ["FUTURE", "STDLIB", "THIRDPARTY", "FIRSTPARTY", "LOCALFOLDER"] -known_first_party = "{{ cookiecutter.package_name }}" -src_paths = ["src/{{ cookiecutter.package_name }}", "tests"] +known_first_party = "{{ package_name }}" +src_paths = ["src/{{ package_name }}", "tests"] line_length = 120 [tool.tox] @@ -170,15 +170,15 @@ target-version = "py39" line-length = 120 [tool.ruff.isort] -known-first-party = ["{{ cookiecutter.package_name }}"] +known-first-party = ["{{ package_name }}"] force-single-line = true no-lines-before = ["future","standard-library","third-party","first-party","local-folder"] [tool.bumpversion] -current_version = "{{ cookiecutter.version }}" +current_version = "{{ version }}" [[tool.bumpversion.files]] -filename = "src/{{ cookiecutter.package_name }}/__init__.py" +filename = "src/{{ package_name }}/__init__.py" [[tool.bumpversion.files]] filename = "pyproject.toml" diff --git a/template/sonar-project.properties.jinja b/template/sonar-project.properties.jinja index 512f6831..2455ef43 100644 --- a/template/sonar-project.properties.jinja +++ b/template/sonar-project.properties.jinja @@ -1,12 +1,12 @@ -sonar.organization={{ cookiecutter.github_organization }} -sonar.projectKey={{ cookiecutter.github_organization }}_{{ cookiecutter.directory_name }} +sonar.organization={{ github_organization }} +sonar.projectKey={{ github_organization }}_{{ directory_name }} sonar.host.url=https://sonarcloud.io -sonar.sources=src/{{ cookiecutter.package_name }}/ +sonar.sources=src/{{ package_name }}/ sonar.tests=tests/ -sonar.links.homepage={{ cookiecutter.repository_url }} -sonar.links.scm={{ cookiecutter.repository }} -sonar.links.issue={{ cookiecutter.repository_url }}/issues -sonar.links.ci={{ cookiecutter.repository_url }}/actions +sonar.links.homepage={{ repository_url }} +sonar.links.scm={{ repository }} +sonar.links.issue={{ repository_url }}/issues +sonar.links.ci={{ repository_url }}/actions sonar.python.coverage.reportPaths=coverage.xml sonar.python.xunit.reportPath=xunit-result.xml sonar.python.pylint.reportPaths=pylint-report.txt diff --git a/template/src/{{package_name}}/__init__.py.jinja b/template/src/{{package_name}}/__init__.py.jinja index 4a72a364..27c656dd 100644 --- a/template/src/{{package_name}}/__init__.py.jinja +++ b/template/src/{{package_name}}/__init__.py.jinja @@ -1,8 +1,8 @@ -"""Documentation about {{ cookiecutter.package_name }}.""" +"""Documentation about {{ package_name }}.""" import logging logging.getLogger(__name__).addHandler(logging.NullHandler()) -__author__ = "{{ cookiecutter.full_name }}" -__email__ = "{{ cookiecutter.email }}" -__version__ = "{{ cookiecutter.version }}" +__author__ = "{{ full_name }}" +__email__ = "{{ email }}" +__version__ = "{{ version }}" diff --git a/template/src/{{package_name}}/my_module.py.jinja b/template/src/{{package_name}}/my_module.py.jinja index 1ebf6f27..5b4ecff9 100644 --- a/template/src/{{package_name}}/my_module.py.jinja +++ b/template/src/{{package_name}}/my_module.py.jinja @@ -1,4 +1,4 @@ -"""Documentation about the {{ cookiecutter.package_name }} module.""" +"""Documentation about the {{ package_name }} module.""" # FIXME: put actual code here @@ -19,7 +19,7 @@ def hello(name): Example: This function can be called with `Jane Smith` as argument using - >>> from {{ cookiecutter.package_name }}.my_module import hello + >>> from {{ package_name }}.my_module import hello >>> hello('Jane Smith') 'Hello Jane Smith!' diff --git a/template/tests/test_my_module.py.jinja b/template/tests/test_my_module.py.jinja index ad6481d6..e9047790 100644 --- a/template/tests/test_my_module.py.jinja +++ b/template/tests/test_my_module.py.jinja @@ -1,6 +1,6 @@ -"""Tests for the {{ cookiecutter.package_name }}.my_module module.""" +"""Tests for the {{ package_name }}.my_module module.""" import pytest -from {{ cookiecutter.package_name }}.my_module import hello +from {{ package_name }}.my_module import hello def test_hello(): diff --git a/template/{% if license == 'Apache-2.0' %}LICENSE{% endif %}.jinja b/template/{% if license == 'Apache-2.0' %}LICENSE{% endif %}.jinja new file mode 100644 index 00000000..0183c52a --- /dev/null +++ b/template/{% if license == 'Apache-2.0' %}LICENSE{% endif %}.jinja @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "{}" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/template/{% if license == 'BSD license' %}LICENSE{% endif %}.jinja b/template/{% if license == 'BSD license' %}LICENSE{% endif %}.jinja new file mode 100644 index 00000000..c154409e --- /dev/null +++ b/template/{% if license == 'BSD license' %}LICENSE{% endif %}.jinja @@ -0,0 +1,30 @@ +BSD License + +Copyright (c) {{ '%Y' | strftime }}, {{ copyright_holder }} +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, this + list of conditions and the following disclaimer in the documentation and/or + other materials provided with the distribution. + +* Neither the name of {{ package_name }} nor the names of its + contributors may be used to endorse or promote products derived from this + software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE +OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +OF THE POSSIBILITY OF SUCH DAMAGE. + diff --git a/template/LICENSE.jinja b/template/{% if license == 'GNU General Public License v3 or later' %}LICENSE{% endif %}.jinja similarity index 60% rename from template/LICENSE.jinja rename to template/{% if license == 'GNU General Public License v3 or later' %}LICENSE{% endif %}.jinja index aa06a167..f288702d 100644 --- a/template/LICENSE.jinja +++ b/template/{% if license == 'GNU General Public License v3 or later' %}LICENSE{% endif %}.jinja @@ -1,255 +1,3 @@ -{% if cookiecutter.license == 'MIT license' %} -MIT License - -Copyright (c) {% now 'local', '%Y' %}, {{ cookiecutter.copyright_holder }} - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -{% elif cookiecutter.license == 'BSD license' %} -BSD License - -Copyright (c) {% now 'local', '%Y' %}, {{ cookiecutter.copyright_holder }} -All rights reserved. - -Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: - -* Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - -* Redistributions in binary form must reproduce the above copyright notice, this - list of conditions and the following disclaimer in the documentation and/or - other materials provided with the distribution. - -* Neither the name of {{ cookiecutter.package_name }} nor the names of its - contributors may be used to endorse or promote products derived from this - software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, -INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY -OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE -OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED -OF THE POSSIBILITY OF SUCH DAMAGE. -{% elif cookiecutter.license == 'ISC license' %} -ISC License - -Copyright (c) {% now 'local', '%Y' %}, {{ cookiecutter.copyright_holder }} - -Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies. - -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -{% elif cookiecutter.license == 'Apache Software License 2.0' %} - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "{}" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - -{% elif cookiecutter.license == 'GNU General Public License v3 or later' %} GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 @@ -924,170 +672,3 @@ may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. But first, please read . -{% elif cookiecutter.license == 'GNU Lesser General Public License v3 or later' %} - GNU LESSER GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - - This version of the GNU Lesser General Public License incorporates -the terms and conditions of version 3 of the GNU General Public -License, supplemented by the additional permissions listed below. - - 0. Additional Definitions. - - As used herein, "this License" refers to version 3 of the GNU Lesser -General Public License, and the "GNU GPL" refers to version 3 of the GNU -General Public License. - - "The Library" refers to a covered work governed by this License, -other than an Application or a Combined Work as defined below. - - An "Application" is any work that makes use of an interface provided -by the Library, but which is not otherwise based on the Library. -Defining a subclass of a class defined by the Library is deemed a mode -of using an interface provided by the Library. - - A "Combined Work" is a work produced by combining or linking an -Application with the Library. The particular version of the Library -with which the Combined Work was made is also called the "Linked -Version". - - The "Minimal Corresponding Source" for a Combined Work means the -Corresponding Source for the Combined Work, excluding any source code -for portions of the Combined Work that, considered in isolation, are -based on the Application, and not on the Linked Version. - - The "Corresponding Application Code" for a Combined Work means the -object code and/or source code for the Application, including any data -and utility programs needed for reproducing the Combined Work from the -Application, but excluding the System Libraries of the Combined Work. - - 1. Exception to Section 3 of the GNU GPL. - - You may convey a covered work under sections 3 and 4 of this License -without being bound by section 3 of the GNU GPL. - - 2. Conveying Modified Versions. - - If you modify a copy of the Library, and, in your modifications, a -facility refers to a function or data to be supplied by an Application -that uses the facility (other than as an argument passed when the -facility is invoked), then you may convey a copy of the modified -version: - - a) under this License, provided that you make a good faith effort to - ensure that, in the event an Application does not supply the - function or data, the facility still operates, and performs - whatever part of its purpose remains meaningful, or - - b) under the GNU GPL, with none of the additional permissions of - this License applicable to that copy. - - 3. Object Code Incorporating Material from Library Header Files. - - The object code form of an Application may incorporate material from -a header file that is part of the Library. You may convey such object -code under terms of your choice, provided that, if the incorporated -material is not limited to numerical parameters, data structure -layouts and accessors, or small macros, inline functions and templates -(ten or fewer lines in length), you do both of the following: - - a) Give prominent notice with each copy of the object code that the - Library is used in it and that the Library and its use are - covered by this License. - - b) Accompany the object code with a copy of the GNU GPL and this license - document. - - 4. Combined Works. - - You may convey a Combined Work under terms of your choice that, -taken together, effectively do not restrict modification of the -portions of the Library contained in the Combined Work and reverse -engineering for debugging such modifications, if you also do each of -the following: - - a) Give prominent notice with each copy of the Combined Work that - the Library is used in it and that the Library and its use are - covered by this License. - - b) Accompany the Combined Work with a copy of the GNU GPL and this license - document. - - c) For a Combined Work that displays copyright notices during - execution, include the copyright notice for the Library among - these notices, as well as a reference directing the user to the - copies of the GNU GPL and this license document. - - d) Do one of the following: - - 0) Convey the Minimal Corresponding Source under the terms of this - License, and the Corresponding Application Code in a form - suitable for, and under terms that permit, the user to - recombine or relink the Application with a modified version of - the Linked Version to produce a modified Combined Work, in the - manner specified by section 6 of the GNU GPL for conveying - Corresponding Source. - - 1) Use a suitable shared library mechanism for linking with the - Library. A suitable mechanism is one that (a) uses at run time - a copy of the Library already present on the user's computer - system, and (b) will operate properly with a modified version - of the Library that is interface-compatible with the Linked - Version. - - e) Provide Installation Information, but only if you would otherwise - be required to provide such information under section 6 of the - GNU GPL, and only to the extent that such information is - necessary to install and execute a modified version of the - Combined Work produced by recombining or relinking the - Application with a modified version of the Linked Version. (If - you use option 4d0, the Installation Information must accompany - the Minimal Corresponding Source and Corresponding Application - Code. If you use option 4d1, you must provide the Installation - Information in the manner specified by section 6 of the GNU GPL - for conveying Corresponding Source.) - - 5. Combined Libraries. - - You may place library facilities that are a work based on the -Library side by side in a single library together with other library -facilities that are not Applications and are not covered by this -License, and convey such a combined library under terms of your -choice, if you do both of the following: - - a) Accompany the combined library with a copy of the same work based - on the Library, uncombined with any other library facilities, - conveyed under the terms of this License. - - b) Give prominent notice with the combined library that part of it - is a work based on the Library, and explaining where to find the - accompanying uncombined form of the same work. - - 6. Revised Versions of the GNU Lesser General Public License. - - The Free Software Foundation may publish revised and/or new versions -of the GNU Lesser General Public License from time to time. Such new -versions will be similar in spirit to the present version, but may -differ in detail to address new problems or concerns. - - Each version is given a distinguishing version number. If the -Library as you received it specifies that a certain numbered version -of the GNU Lesser General Public License "or any later version" -applies to it, you have the option of following the terms and -conditions either of that published version or of any later version -published by the Free Software Foundation. If the Library as you -received it does not specify a version number of the GNU Lesser -General Public License, you may choose any version of the GNU Lesser -General Public License ever published by the Free Software Foundation. - - If the Library as you received it specifies that a proxy can decide -whether future versions of the GNU Lesser General Public License shall -apply, that proxy's public statement of acceptance of any version is -permanent authorization for you to choose that version for the -Library. -{% endif %} diff --git a/template/{% if license == 'GNU Lesser General Public License v3 or later' %}LICENSE{% endif %}.jinja b/template/{% if license == 'GNU Lesser General Public License v3 or later' %}LICENSE{% endif %}.jinja new file mode 100644 index 00000000..7125e3e6 --- /dev/null +++ b/template/{% if license == 'GNU Lesser General Public License v3 or later' %}LICENSE{% endif %}.jinja @@ -0,0 +1,166 @@ +GNU LESSER GENERAL PUBLIC LICENSE +Version 3, 29 June 2007 + +Copyright (C) 2007 Free Software Foundation, Inc. + +Everyone is permitted to copy and distribute verbatim copies +of this license document, but changing it is not allowed. + + +This version of the GNU Lesser General Public License incorporates +the terms and conditions of version 3 of the GNU General Public +License, supplemented by the additional permissions listed below. + +0. Additional Definitions. + +As used herein, "this License" refers to version 3 of the GNU Lesser +General Public License, and the "GNU GPL" refers to version 3 of the GNU +General Public License. + +"The Library" refers to a covered work governed by this License, +other than an Application or a Combined Work as defined below. + +An "Application" is any work that makes use of an interface provided +by the Library, but which is not otherwise based on the Library. +Defining a subclass of a class defined by the Library is deemed a mode +of using an interface provided by the Library. + +A "Combined Work" is a work produced by combining or linking an +Application with the Library. The particular version of the Library +with which the Combined Work was made is also called the "Linked +Version". + +The "Minimal Corresponding Source" for a Combined Work means the +Corresponding Source for the Combined Work, excluding any source code +for portions of the Combined Work that, considered in isolation, are +based on the Application, and not on the Linked Version. + +The "Corresponding Application Code" for a Combined Work means the +object code and/or source code for the Application, including any data +and utility programs needed for reproducing the Combined Work from the +Application, but excluding the System Libraries of the Combined Work. + +1. Exception to Section 3 of the GNU GPL. + +You may convey a covered work under sections 3 and 4 of this License +without being bound by section 3 of the GNU GPL. + +2. Conveying Modified Versions. + +If you modify a copy of the Library, and, in your modifications, a +facility refers to a function or data to be supplied by an Application +that uses the facility (other than as an argument passed when the +facility is invoked), then you may convey a copy of the modified +version: + +a) under this License, provided that you make a good faith effort to +ensure that, in the event an Application does not supply the +function or data, the facility still operates, and performs +whatever part of its purpose remains meaningful, or + +b) under the GNU GPL, with none of the additional permissions of +this License applicable to that copy. + +3. Object Code Incorporating Material from Library Header Files. + +The object code form of an Application may incorporate material from +a header file that is part of the Library. You may convey such object +code under terms of your choice, provided that, if the incorporated +material is not limited to numerical parameters, data structure +layouts and accessors, or small macros, inline functions and templates +(ten or fewer lines in length), you do both of the following: + +a) Give prominent notice with each copy of the object code that the +Library is used in it and that the Library and its use are +covered by this License. + +b) Accompany the object code with a copy of the GNU GPL and this license +document. + +4. Combined Works. + +You may convey a Combined Work under terms of your choice that, +taken together, effectively do not restrict modification of the +portions of the Library contained in the Combined Work and reverse +engineering for debugging such modifications, if you also do each of +the following: + +a) Give prominent notice with each copy of the Combined Work that +the Library is used in it and that the Library and its use are +covered by this License. + +b) Accompany the Combined Work with a copy of the GNU GPL and this license +document. + +c) For a Combined Work that displays copyright notices during +execution, include the copyright notice for the Library among +these notices, as well as a reference directing the user to the +copies of the GNU GPL and this license document. + +d) Do one of the following: + +0) Convey the Minimal Corresponding Source under the terms of this +License, and the Corresponding Application Code in a form +suitable for, and under terms that permit, the user to +recombine or relink the Application with a modified version of +the Linked Version to produce a modified Combined Work, in the +manner specified by section 6 of the GNU GPL for conveying +Corresponding Source. + +1) Use a suitable shared library mechanism for linking with the +Library. A suitable mechanism is one that (a) uses at run time +a copy of the Library already present on the user's computer +system, and (b) will operate properly with a modified version +of the Library that is interface-compatible with the Linked +Version. + +e) Provide Installation Information, but only if you would otherwise +be required to provide such information under section 6 of the +GNU GPL, and only to the extent that such information is +necessary to install and execute a modified version of the +Combined Work produced by recombining or relinking the +Application with a modified version of the Linked Version. (If +you use option 4d0, the Installation Information must accompany +the Minimal Corresponding Source and Corresponding Application +Code. If you use option 4d1, you must provide the Installation +Information in the manner specified by section 6 of the GNU GPL +for conveying Corresponding Source.) + +5. Combined Libraries. + +You may place library facilities that are a work based on the +Library side by side in a single library together with other library +facilities that are not Applications and are not covered by this +License, and convey such a combined library under terms of your +choice, if you do both of the following: + +a) Accompany the combined library with a copy of the same work based +on the Library, uncombined with any other library facilities, +conveyed under the terms of this License. + +b) Give prominent notice with the combined library that part of it +is a work based on the Library, and explaining where to find the +accompanying uncombined form of the same work. + +6. Revised Versions of the GNU Lesser General Public License. + +The Free Software Foundation may publish revised and/or new versions +of the GNU Lesser General Public License from time to time. Such new +versions will be similar in spirit to the present version, but may +differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the +Library as you received it specifies that a certain numbered version +of the GNU Lesser General Public License "or any later version" +applies to it, you have the option of following the terms and +conditions either of that published version or of any later version +published by the Free Software Foundation. If the Library as you +received it does not specify a version number of the GNU Lesser +General Public License, you may choose any version of the GNU Lesser +General Public License ever published by the Free Software Foundation. + +If the Library as you received it specifies that a proxy can decide +whether future versions of the GNU Lesser General Public License shall +apply, that proxy's public statement of acceptance of any version is +permanent authorization for you to choose that version for the +Library. \ No newline at end of file diff --git a/template/{% if license == 'ISC license' %}LICENSE{% endif %}.jinja b/template/{% if license == 'ISC license' %}LICENSE{% endif %}.jinja new file mode 100644 index 00000000..137e91fa --- /dev/null +++ b/template/{% if license == 'ISC license' %}LICENSE{% endif %}.jinja @@ -0,0 +1,12 @@ +ISC License + +Copyright (c) {{ '%Y' | strftime }}, {{ copyright_holder }} + +Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, +provided that the above copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, +INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF +THIS SOFTWARE. diff --git a/template/{% if license == 'MIT licence' %}LICENSE{% endif %}.jinja b/template/{% if license == 'MIT licence' %}LICENSE{% endif %}.jinja new file mode 100644 index 00000000..416f547d --- /dev/null +++ b/template/{% if license == 'MIT licence' %}LICENSE{% endif %}.jinja @@ -0,0 +1,16 @@ +MIT License + +Copyright (c) {{ '%Y' | strftime }}, {{ copyright_holder }} + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the Software without restriction, including without limitation the +rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit +persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the +Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/template/{% if license == 'Not open source' %}LICENSE{% endif %}.jinja b/template/{% if license == 'Not open source' %}LICENSE{% endif %}.jinja new file mode 100644 index 00000000..f816229f --- /dev/null +++ b/template/{% if license == 'Not open source' %}LICENSE{% endif %}.jinja @@ -0,0 +1 @@ +Not open source diff --git a/template/{{_copier_conf.answers_file}}.jinja b/template/{{_copier_conf.answers_file}}.jinja new file mode 100644 index 00000000..ea97bd4b --- /dev/null +++ b/template/{{_copier_conf.answers_file}}.jinja @@ -0,0 +1,2 @@ +# Changes here will be overwritten by Copier +{{ _copier_answers|to_nice_yaml -}} \ No newline at end of file diff --git a/tests/test_project.py b/tests/test_project.py index 1163013b..a9cbbdcd 100644 --- a/tests/test_project.py +++ b/tests/test_project.py @@ -4,18 +4,19 @@ from sys import platform from typing import Sequence +from pyprojroot.here import here +from copier import run_copy import pytest IS_WINDOWS = platform.startswith('win') -def test_project_folder(cookies): - project = cookies.bake() +def test_project_folder(copie): + project = copie.copy() assert project.exit_code == 0 assert project.exception is None - assert project.project_path.name == 'my-python-project' - assert project.project_path.is_dir() + assert project.project_dir.is_dir() def run(args: Sequence[str], dirpath: os.PathLike) -> subprocess.CompletedProcess: @@ -41,15 +42,16 @@ def project_env_bin_dir(tmp_path_factory): @pytest.fixture(scope='session') -def baked_with_development_dependencies(cookies_session, project_env_bin_dir): - result = cookies_session.bake() - assert result.exit_code == 0 +def baked_with_development_dependencies(tmp_path_factory, project_env_bin_dir): + project = run_copy(src_path=str(here()), dst_path=str(tmp_path_factory.mktemp('projects')), defaults=True) + project_dir = project.dst_path + bin_dir = project_env_bin_dir - latest_pip_output = run([f'{bin_dir}python', '-m', 'pip', 'install', '--upgrade', 'pip', 'setuptools'], result.project_path) + latest_pip_output = run([f'{bin_dir}python', '-m', 'pip', 'install', '--upgrade', 'pip', 'setuptools'], project_dir) assert latest_pip_output.returncode == 0 - pip_output = run([f'{bin_dir}python', '-m', 'pip', 'install', '--editable', '.[dev]'], result.project_path) + pip_output = run([f'{bin_dir}python', '-m', 'pip', 'install', '--editable', '.[dev]'], project_dir) assert pip_output.returncode == 0 - return result.project_path + return project_dir def test_pytest(baked_with_development_dependencies, project_env_bin_dir): @@ -167,7 +169,7 @@ def test_ruff_check(baked_with_development_dependencies, project_env_bin_dir): project_dir = baked_with_development_dependencies bin_dir = project_env_bin_dir - result = run([f'{bin_dir}ruff', '.'], project_dir) + result = run([f'{bin_dir}ruff', 'check', '.'], project_dir) assert result.returncode == 0 assert '' in result.stdout diff --git a/tests/test_values.py b/tests/test_values.py index 01d748a9..1f240323 100644 --- a/tests/test_values.py +++ b/tests/test_values.py @@ -1,36 +1,36 @@ -def test_double_quotes_in_name_and_description(cookies): +def test_double_quotes_in_name_and_description(copie): ctx = { "project_short_description": '"double quotes"', "full_name": '"name"name' } - project = cookies.bake(extra_context=ctx) + project = copie.copy(extra_answers=ctx) assert project.exit_code == 0 -def test_single_quotes_in_name_and_description(cookies): +def test_single_quotes_in_name_and_description(copie): ctx = { "project_short_description": "'single quotes'", "full_name": "Mr. O'Keefe" } - project = cookies.bake(extra_context=ctx) + project = copie.copy(extra_answers=ctx) assert project.exit_code == 0 -def test_dash_in_directory_name(cookies): +def test_dash_in_directory_name(copie): ctx = { "directory_name": "my-python-project" } - project = cookies.bake(extra_context=ctx) + project = copie.copy(extra_answers=ctx) assert project.exit_code == 0 -def test_space_in_directory_name(cookies): +def test_space_in_directory_name(copie): ctx = { "directory_name": "my python project" } - project = cookies.bake(extra_context=ctx) + project = copie.copy(extra_answers=ctx) assert project.exit_code == 0 From d8ad6a86e29b9acdc2d0fdac216a8ae4806da59d Mon Sep 17 00:00:00 2001 From: Olga Lyashevska Date: Tue, 30 Jul 2024 13:53:26 +0200 Subject: [PATCH 03/29] Update template/README.md.jinja to copier --- template/README.md.jinja | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/template/README.md.jinja b/template/README.md.jinja index 0e5e2918..4ffb4ea4 100644 --- a/template/README.md.jinja +++ b/template/README.md.jinja @@ -4,35 +4,35 @@ | fair-software.eu recommendations | | | :-- | :-- | -| (1/5) code repository | [![github repo badge](https://img.shields.io/badge/github-repo-000.svg?logo=github&labelColor=gray&color=blue)]({{cookiecutter.repository_url}}) | -| (2/5) license | [![github license badge](https://img.shields.io/github/license/{{cookiecutter.github_organization}}/{{cookiecutter.directory_name}})]({{cookiecutter.repository_url}}) | -| (3/5) community registry | [![RSD](https://img.shields.io/badge/rsd-{{cookiecutter.package_name}}-00a3e3.svg)](https://www.research-software.nl/software/{{cookiecutter.package_name}}) [![workflow pypi badge](https://img.shields.io/pypi/v/{{cookiecutter.package_name}}.svg?colorB=blue)](https://pypi.python.org/project/{{cookiecutter.package_name}}/) | +| (1/5) code repository | [![github repo badge](https://img.shields.io/badge/github-repo-000.svg?logo=github&labelColor=gray&color=blue)]({{repository_url}}) | +| (2/5) license | [![github license badge](https://img.shields.io/github/license/{{github_organization}}/{{directory_name}})]({{repository_url}}) | +| (3/5) community registry | [![RSD](https://img.shields.io/badge/rsd-{{package_name}}-00a3e3.svg)](https://www.research-software.nl/software/{{package_name}}) [![workflow pypi badge](https://img.shields.io/pypi/v/{{package_name}}.svg?colorB=blue)](https://pypi.python.org/project/{{package_name}}/) | | (4/5) citation | [![DOI](https://zenodo.org/badge/DOI/.svg)](https://doi.org/) | | (5/5) checklist | [![workflow cii badge](https://bestpractices.coreinfrastructure.org/projects//badge)](https://bestpractices.coreinfrastructure.org/projects/) | | howfairis | [![fair-software badge](https://img.shields.io/badge/fair--software.eu-%E2%97%8F%20%20%E2%97%8F%20%20%E2%97%8F%20%20%E2%97%8F%20%20%E2%97%8B-yellow)](https://fair-software.eu) | | **Other best practices** |   | -| Static analysis | [![workflow scq badge](https://sonarcloud.io/api/project_badges/measure?project={{cookiecutter.github_organization}}_{{cookiecutter.directory_name}}&metric=alert_status)](https://sonarcloud.io/dashboard?id={{cookiecutter.github_organization}}_{{cookiecutter.directory_name}}) | -| Coverage | [![workflow scc badge](https://sonarcloud.io/api/project_badges/measure?project={{cookiecutter.github_organization}}_{{cookiecutter.directory_name}}&metric=coverage)](https://sonarcloud.io/dashboard?id={{cookiecutter.github_organization}}_{{cookiecutter.directory_name}}) | -| Documentation | [![Documentation Status](https://readthedocs.org/projects/{{cookiecutter.directory_name}}/badge/?version=latest)](https://{{cookiecutter.directory_name}}.readthedocs.io/en/latest/?badge=latest) | +| Static analysis | [![workflow scq badge](https://sonarcloud.io/api/project_badges/measure?project={{github_organization}}_{{directory_name}}&metric=alert_status)](https://sonarcloud.io/dashboard?id={{github_organization}}_{{directory_name}}) | +| Coverage | [![workflow scc badge](https://sonarcloud.io/api/project_badges/measure?project={{github_organization}}_{{directory_name}}&metric=coverage)](https://sonarcloud.io/dashboard?id={{github_organization}}_{{directory_name}}) | +| Documentation | [![Documentation Status](https://readthedocs.org/projects/{{directory_name}}/badge/?version=latest)](https://{{directory_name}}.readthedocs.io/en/latest/?badge=latest) | | **GitHub Actions** |   | -| Build | [![build]({{cookiecutter.repository_url}}/actions/workflows/build.yml/badge.svg)]({{cookiecutter.repository_url}}/actions/workflows/build.yml) | -| Citation data consistency | [![cffconvert]({{cookiecutter.repository_url}}/actions/workflows/cffconvert.yml/badge.svg)]({{cookiecutter.repository_url}}/actions/workflows/cffconvert.yml) | -| SonarCloud | [![sonarcloud]({{cookiecutter.repository_url}}/actions/workflows/sonarcloud.yml/badge.svg)]({{cookiecutter.repository_url}}/actions/workflows/sonarcloud.yml) | -| MarkDown link checker | [![markdown-link-check]({{cookiecutter.repository_url}}/actions/workflows/markdown-link-check.yml/badge.svg)]({{cookiecutter.repository_url}}/actions/workflows/markdown-link-check.yml) | +| Build | [![build]({{repository_url}}/actions/workflows/build.yml/badge.svg)]({{repository_url}}/actions/workflows/build.yml) | +| Citation data consistency | [![cffconvert]({{repository_url}}/actions/workflows/cffconvert.yml/badge.svg)]({{repository_url}}/actions/workflows/cffconvert.yml) | +| SonarCloud | [![sonarcloud]({{repository_url}}/actions/workflows/sonarcloud.yml/badge.svg)]({{repository_url}}/actions/workflows/sonarcloud.yml) | +| MarkDown link checker | [![markdown-link-check]({{repository_url}}/actions/workflows/markdown-link-check.yml/badge.svg)]({{repository_url}}/actions/workflows/markdown-link-check.yml) | -## How to use {{ cookiecutter.package_name }} +## How to use {{ package_name }} -{{ cookiecutter.package_short_description }} +{{ package_short_description }} The project setup is documented in [project_setup.md](project_setup.md). Feel free to remove this document (and/or the link to this document) if you don't need it. ## Installation -To install {{ cookiecutter.package_name }} from GitHub repository, do: +To install {{ package_name }} from GitHub repository, do: ```console -git clone {{ cookiecutter.repository }}.git -cd {{ cookiecutter.directory_name }} +git clone {{ repository }}.git +cd {{ directory_name }} python -m pip install . ``` @@ -42,9 +42,9 @@ Include a link to your project's full documentation here. ## Contributing -If you want to contribute to the development of {{ cookiecutter.package_name }}, +If you want to contribute to the development of {{ package_name }}, have a look at the [contribution guidelines](CONTRIBUTING.md). ## Credits -This package was created with [Cookiecutter](https://github.com/audreyr/cookiecutter) and the [NLeSC/python-template](https://github.com/NLeSC/python-template). +This package was created with [Copier](https://github.com/copier-org/copier) and the [NLeSC/python-template](https://github.com/NLeSC/python-template). From 39d374cdedec20a2c581bebf9653dc784e649f2c Mon Sep 17 00:00:00 2001 From: Olga Lyashevska Date: Tue, 30 Jul 2024 15:44:11 +0200 Subject: [PATCH 04/29] Update README.md to use copier --- README.md | 123 ++++++++++++++++++++++++++---------------------------- 1 file changed, 60 insertions(+), 63 deletions(-) diff --git a/README.md b/README.md index 181db8c8..ff88a784 100644 --- a/README.md +++ b/README.md @@ -1,30 +1,27 @@ # Netherlands eScience Center Python Template -Spend less time setting up and configuring your new Python packages and comply with the -[Netherlands eScience Center Software Development Guide](https://guide.esciencecenter.nl/) -from the start. +Spend less time setting up and configuring your new Python packages and comply with the [Netherlands eScience Center Software Development Guide](https://guide.esciencecenter.nl/) from the start. -Use this [Cookiecutter](https://cookiecutter.readthedocs.io) template to generate -an empty Python package. Features include: +Use this [Copier](https://copier.readthedocs.io) template to generate an empty Python package. Features include: - Boilerplate unit tests and documentation, - [Python static setup configuration]({{directory_name}}/pyproject.toml), - Open source software license, -- Continuous integration with [GitHub action workflows]({{cookiecutter.directory_name}}/.github/workflows) for building, testing, link checking and linting, +- Continuous integration with [GitHub action workflows]({{directory_name}}/.github/workflows) for building, testing, link checking and linting, - Code style checking with [ruff](https://beta.ruff.rs/), -- [Editorconfig]({{cookiecutter.directory_name}}/.editorconfig), +- [Editorconfig]({{directory_name}}/.editorconfig), - Usage and contribution documents: - - [README.md]({{cookiecutter.directory_name}}/README.md) for package users, - - [README.dev.md]({{cookiecutter.directory_name}}/README.dev.md) for package developer, - - [project_setup.md]({{cookiecutter.directory_name}}/project_setup.md) with extensive documentation about project setup, - - [Change log]({{cookiecutter.directory_name}}/CHANGELOG.md), - - [Code of Conduct]({{cookiecutter.directory_name}}/CODE_OF_CONDUCT.md), - - [Contributing guidelines]({{cookiecutter.directory_name}}/CONTRIBUTING.md), + - [README.md]({{directory_name}}/README.md) for package users, + - [README.dev.md]({{directory_name}}/README.dev.md) for package developer, + - [project_setup.md]({{directory_name}}/project_setup.md) with extensive documentation about project setup, + - [Change log]({{directory_name}}/CHANGELOG.md), + - [Code of Conduct]({{directory_name}}/CODE_OF_CONDUCT.md), + - [Contributing guidelines]({{directory_name}}/CONTRIBUTING.md), - Continuous code quality and code coverage reporting using [Sonarcloud](https://sonarcloud.io/), -- Automatic creation of [issues]({{cookiecutter.directory_name}}/.github/next_steps) with instructions how to pass all GitHub action workflows and integrate with services like Zenodo and Read the Docs, -- Instructions how to make package [citable]({{cookiecutter.directory_name}}/.github/next_steps/02_citation.md) +- Automatic creation of [issues]({{directory_name}}/.github/next_steps) with instructions how to pass all GitHub action workflows and integrate with services like Zenodo and Read the Docs, +- Instructions how to make package [citable]({{directory_name}}/.github/next_steps/02_citation.md) - FAIR software recommendation badge, -- Optional [pre commit hook]({{cookiecutter.directory_name}}/README.dev.md#running-linters-locally) to catch lint errors early +- Optional [pre commit hook]({{directory_name}}/README.dev.md#running-linters-locally) to catch lint errors early ## Badges @@ -45,24 +42,21 @@ an empty Python package. Features include: ## How to use -### Step 1/3: Install `cookiecutter` - -We recommend installing `cookiecutter` in user space as per `cookiecutter`'s instructions. This way, you don't have to -install `cookiecutter` for every new project. +### Step 1/3: Install `copier` ```shell -python -m pip install --user --upgrade cookiecutter +pipx install copier ``` ### Step 2/3: Generate the files and directory structure -Run `cookiecutter` with the template: +Run `copier` with the template: ```shell # Notes: # 1. See table below for explanation of each question # 2. The files will be generated in a new directory -cookiecutter https://github.com/nlesc/python-template.git +copier copy https://github.com/nlesc/python-template.git path/to/destination ``` | Name | Default value | Explanation | @@ -81,64 +75,67 @@ cookiecutter https://github.com/nlesc/python-template.git | code_of_conduct_email | yourname@esciencecenter.nl | Email address of the person who should be contacted in case of violations of the Code of Conduct. | Once the project files have been generated, follow the steps outlined in -[{{cookiecutter.directory_name}}/next_steps.md]({{cookiecutter.directory_name}}/next_steps.md). +[{{directory_name}}/next_steps.md]({{directory_name}}/next_steps.md). ### Step 3/3: Read about what was just generated Good job! You have now generated the skeleton for your package: ```text -my-python-project/ -├── .editorconfig -├── .githooks -│ └── pre-commit -├── .github -│ ├── next_steps -│ │ ├── 01_sonarcloud_integration.md -│ │ ├── 02_citation.md -│ │ ├── 03_readthedocs.md -│ │ ├── 04_zenodo_integration.md -│ │ └── 05_linting.md -│ └── workflows -│ ├── build.yml -│ ├── cffconvert.yml -│ ├── documentation.yml -│ ├── markdown-link-check.yml -│ ├── next_steps.yml -│ └── sonarcloud.yml -├── .gitignore -├── .mlc-config.json -├── .readthedocs.yaml +. ├── CHANGELOG.md ├── CITATION.cff ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md -├── LICENSE -├── MANIFEST.in -├── NOTICE -├── README.dev.md -├── README.md +├── .copier-answers.yml ├── docs -│ ├── Makefile -│ ├── _templates -│ │ └── .gitignore -│ ├── conf.py -│ ├── index.rst -│ └── make.bat +│   ├── conf.py +│   ├── index.rst +│   ├── make.bat +│   ├── Makefile +│   └── _templates +│   └── .gitignore +├── .editorconfig +├── .githooks +│   └── pre-commit +├── .github +│   ├── next_steps +│   │   ├── 01_sonarcloud_integration.md +│   │   ├── 02_citation.md +│   │   ├── 03_readthedocs.md +│   │   ├── 04_zenodo_integration.md +│   │   └── 05_linting.md +│   └── workflows +│   ├── build.yml +│   ├── cffconvert.yml +│   ├── documentation.yml +│   ├── markdown-link-check.yml +│   ├── next_steps.yml +│   └── sonarcloud.yml +├── .gitignore +├── MANIFEST.in +├── .mlc-config.json ├── next_steps.md +├── NOTICE ├── project_setup.md ├── pyproject.toml +├── README.dev.md +├── README.md +├── .readthedocs.yaml ├── sonar-project.properties ├── src -│ └── my_python_package -│ ├── __init__.py -│ └── my_module.py -└── tests - ├── __init__.py - └── test_my_module.py +│   └── my_python_package +│   ├── __init__.py +│   └── my_module.py +├── tests +│   ├── __init__.py +│   ├── test_my_module.py +│   ├── test_project.py +│   └── test_values.py +└── .zenodo.json ``` -For an explanation of what's there, read on in the [project_setup.md]({{cookiecutter.directory_name}}/project_setup.md) file. +For an explanation of what's there, read on in the [project_setup.md]({{directory_name}}/project_setup.md) file. There are also instructions on how to [apply the template to an existing Python package](ADD_TO_EXISTING_PACKAGE.md). ## Examples From 7c89fe9834875706e35571c844bdc42d51992c82 Mon Sep 17 00:00:00 2001 From: Olga Lyashevska Date: Thu, 1 Aug 2024 11:09:22 +0200 Subject: [PATCH 05/29] Handle directory_name --- README.md | 31 +++++++++---------- copier.yml | 12 +++---- setup.cfg | 2 +- .../01_sonarcloud_integration.md.jinja | 4 +-- .../next_steps/03_readthedocs.md.jinja | 4 +-- template/README.md.jinja | 10 +++--- template/next_steps.md.jinja | 4 +-- template/project_setup.md.jinja | 2 +- template/sonar-project.properties.jinja | 2 +- tests/test_values.py | 18 ----------- 10 files changed, 35 insertions(+), 54 deletions(-) diff --git a/README.md b/README.md index ff88a784..ec98a601 100644 --- a/README.md +++ b/README.md @@ -5,23 +5,23 @@ Spend less time setting up and configuring your new Python packages and comply w Use this [Copier](https://copier.readthedocs.io) template to generate an empty Python package. Features include: - Boilerplate unit tests and documentation, -- [Python static setup configuration]({{directory_name}}/pyproject.toml), +- [Python static setup configuration](template/pyproject.toml), - Open source software license, -- Continuous integration with [GitHub action workflows]({{directory_name}}/.github/workflows) for building, testing, link checking and linting, +- Continuous integration with [GitHub action workflows](template/.github/workflows) for building, testing, link checking and linting, - Code style checking with [ruff](https://beta.ruff.rs/), -- [Editorconfig]({{directory_name}}/.editorconfig), +- [Editorconfig](template/.editorconfig), - Usage and contribution documents: - - [README.md]({{directory_name}}/README.md) for package users, - - [README.dev.md]({{directory_name}}/README.dev.md) for package developer, - - [project_setup.md]({{directory_name}}/project_setup.md) with extensive documentation about project setup, - - [Change log]({{directory_name}}/CHANGELOG.md), - - [Code of Conduct]({{directory_name}}/CODE_OF_CONDUCT.md), - - [Contributing guidelines]({{directory_name}}/CONTRIBUTING.md), + - [README.md](template/README.md) for package users, + - [README.dev.md](template/README.dev.md) for package developer, + - [project_setup.md](template/project_setup.md) with extensive documentation about project setup, + - [Change log](template/CHANGELOG.md), + - [Code of Conduct](template/CODE_OF_CONDUCT.md), + - [Contributing guidelines](template/CONTRIBUTING.md), - Continuous code quality and code coverage reporting using [Sonarcloud](https://sonarcloud.io/), -- Automatic creation of [issues]({{directory_name}}/.github/next_steps) with instructions how to pass all GitHub action workflows and integrate with services like Zenodo and Read the Docs, -- Instructions how to make package [citable]({{directory_name}}/.github/next_steps/02_citation.md) +- Automatic creation of [issues](template/.github/next_steps) with instructions how to pass all GitHub action workflows and integrate with services like Zenodo and Read the Docs, +- Instructions how to make package [citable](template/.github/next_steps/02_citation.md) - FAIR software recommendation badge, -- Optional [pre commit hook]({{directory_name}}/README.dev.md#running-linters-locally) to catch lint errors early +- Optional [pre commit hook](template/README.dev.md#running-linters-locally) to catch lint errors early ## Badges @@ -61,8 +61,7 @@ copier copy https://github.com/nlesc/python-template.git path/to/destination | Name | Default value | Explanation | | ------------------------- | ------------- | ----------- | -| directory_name | my-python-project | Name of the directory that contains the package. Avoid using spaces or uppercase letters for the best experience across operating systems. To get an impression of what will be generated, see the directory tree [below](https://github.com/NLeSC/python-template#step-33-read-about-what-was-just-generated) | -| package_name | my_python_package | Name of the package. Avoid using spaces, dashes, or uppercase letters for the best experience across operating systems. | +| package_name | my_python_package | Name of the package. Avoid using spaces, dashes, or uppercase letters for the best experience across operating systems. This also will be used as the github repository name.| | package_short_description | Short description of package | The information that you enter here will end up in the README, documentation, license, and pyproject.toml, so it may be a good idea to prepare something in advance. | | keyword1 | keyword1 | A term that describes your package. | | keyword2 | keyword2 | Another term that describes your package. | @@ -75,7 +74,7 @@ copier copy https://github.com/nlesc/python-template.git path/to/destination | code_of_conduct_email | yourname@esciencecenter.nl | Email address of the person who should be contacted in case of violations of the Code of Conduct. | Once the project files have been generated, follow the steps outlined in -[{{directory_name}}/next_steps.md]({{directory_name}}/next_steps.md). +[template/next_steps.md](template/next_steps.md). ### Step 3/3: Read about what was just generated @@ -135,7 +134,7 @@ Good job! You have now generated the skeleton for your package: └── .zenodo.json ``` -For an explanation of what's there, read on in the [project_setup.md]({{directory_name}}/project_setup.md) file. +For an explanation of what's there, read on in the [project_setup.md](template/project_setup.md) file. There are also instructions on how to [apply the template to an existing Python package](ADD_TO_EXISTING_PACKAGE.md). ## Examples diff --git a/copier.yml b/copier.yml index 77fc3fd3..8359c1f1 100644 --- a/copier.yml +++ b/copier.yml @@ -11,10 +11,10 @@ package_name: package_short_description: type: str default: Short description of package - # validator: >- - # {% if '"' in package_short_description %} - # package_short_description must not contain unescaped double quotes. Use \\" for double quotes. - # {% endif %} + validator: >- + {% if (package_short_description | regex_replace ('"', '\\\\"')|regex_replace ("'", "\\\\'")%} + package_short_description must not contain unescaped double or single quotes. + {% endif %} keyword1: type: str default: keyword1 @@ -59,11 +59,11 @@ code_of_conduct_email: _subdirectory: template repository: - default: git@github.com:{{ github_organization }}/{{ directory_name }} + default: git@github.com:{{ github_organization }}/{{ package_name }} when: false repository_url: - default: https://github.com/{{ github_organization }}/{{ directory_name }} + default: https://github.com/{{ github_organization }}/{{ package_name }} when: false diff --git a/setup.cfg b/setup.cfg index b6b2cb16..d52e15ba 100644 --- a/setup.cfg +++ b/setup.cfg @@ -51,4 +51,4 @@ dev = [tool:pytest] testpaths = tests -norecursedirs = .git .github hooks {{directory_name}} +norecursedirs = .git .github hooks template diff --git a/template/.github/next_steps/01_sonarcloud_integration.md.jinja b/template/.github/next_steps/01_sonarcloud_integration.md.jinja index 152edb6b..bcc69ce0 100644 --- a/template/.github/next_steps/01_sonarcloud_integration.md.jinja +++ b/template/.github/next_steps/01_sonarcloud_integration.md.jinja @@ -10,7 +10,7 @@ In order to configure Sonarcloud analysis [GitHub Action workflow]({{repository_ 1. login with your GitHub account 1. add Sonarcloud organization or reuse existing one 1. set up a repository -1. go to [new code definition administration page](https://sonarcloud.io/project/new_code?id={{github_organization}}_{{directory_name}}) and select `Number of days` option +1. go to [new code definition administration page](https://sonarcloud.io/project/new_code?id={{github_organization}}_{{package_name}}) and select `Number of days` option 1. To be able to run the analysis: 1. a token must be created at [Sonarcloud account](https://sonarcloud.io/account/security/) - 1. the created token must be added as `SONAR_TOKEN` to [secrets on GitHub](https://github.com/{{github_organization}}/{{directory_name}}/settings/secrets/actions) + 1. the created token must be added as `SONAR_TOKEN` to [secrets on GitHub](https://github.com/{{github_organization}}/{{package_name}}/settings/secrets/actions) diff --git a/template/.github/next_steps/03_readthedocs.md.jinja b/template/.github/next_steps/03_readthedocs.md.jinja index 5c7917d0..5648c020 100644 --- a/template/.github/next_steps/03_readthedocs.md.jinja +++ b/template/.github/next_steps/03_readthedocs.md.jinja @@ -9,12 +9,12 @@ To host the documentation of this repository please perform the following instru 1. go to [Read the Docs](https://readthedocs.org/dashboard/import/?) 1. log in with your GitHub account -1. find `{{ github_organization }}/{{ directory_name }}` in list and press `+` button. +1. find `{{ github_organization }}/{{ package_name }}` in list and press `+` button. * If repository is not listed, 1. go to [Read the Docs GitHub app](https://github.com/settings/connections/applications/fae83c942bc1d89609e2) 2. make sure {{ github_organization }} has been granted access. 3. reload repository list on Read the Docs import page -1. wait for the first build to be completed at +1. wait for the first build to be completed at 1. check that the link of the documentation badge in the [README.md]({{ repository_url }}) works See [README.dev.md#]({{repository_url}}/blob/main/README.dev.md#generating-the-api-docs) how to build documentation site locally. diff --git a/template/README.md.jinja b/template/README.md.jinja index 4ffb4ea4..8093442c 100644 --- a/template/README.md.jinja +++ b/template/README.md.jinja @@ -5,15 +5,15 @@ | fair-software.eu recommendations | | | :-- | :-- | | (1/5) code repository | [![github repo badge](https://img.shields.io/badge/github-repo-000.svg?logo=github&labelColor=gray&color=blue)]({{repository_url}}) | -| (2/5) license | [![github license badge](https://img.shields.io/github/license/{{github_organization}}/{{directory_name}})]({{repository_url}}) | +| (2/5) license | [![github license badge](https://img.shields.io/github/license/{{github_organization}}/{{package_name}})]({{repository_url}}) | | (3/5) community registry | [![RSD](https://img.shields.io/badge/rsd-{{package_name}}-00a3e3.svg)](https://www.research-software.nl/software/{{package_name}}) [![workflow pypi badge](https://img.shields.io/pypi/v/{{package_name}}.svg?colorB=blue)](https://pypi.python.org/project/{{package_name}}/) | | (4/5) citation | [![DOI](https://zenodo.org/badge/DOI/.svg)](https://doi.org/) | | (5/5) checklist | [![workflow cii badge](https://bestpractices.coreinfrastructure.org/projects//badge)](https://bestpractices.coreinfrastructure.org/projects/) | | howfairis | [![fair-software badge](https://img.shields.io/badge/fair--software.eu-%E2%97%8F%20%20%E2%97%8F%20%20%E2%97%8F%20%20%E2%97%8F%20%20%E2%97%8B-yellow)](https://fair-software.eu) | | **Other best practices** |   | -| Static analysis | [![workflow scq badge](https://sonarcloud.io/api/project_badges/measure?project={{github_organization}}_{{directory_name}}&metric=alert_status)](https://sonarcloud.io/dashboard?id={{github_organization}}_{{directory_name}}) | -| Coverage | [![workflow scc badge](https://sonarcloud.io/api/project_badges/measure?project={{github_organization}}_{{directory_name}}&metric=coverage)](https://sonarcloud.io/dashboard?id={{github_organization}}_{{directory_name}}) | -| Documentation | [![Documentation Status](https://readthedocs.org/projects/{{directory_name}}/badge/?version=latest)](https://{{directory_name}}.readthedocs.io/en/latest/?badge=latest) | +| Static analysis | [![workflow scq badge](https://sonarcloud.io/api/project_badges/measure?project={{github_organization}}_{{package_name}}&metric=alert_status)](https://sonarcloud.io/dashboard?id={{github_organization}}_{{package_name}}) | +| Coverage | [![workflow scc badge](https://sonarcloud.io/api/project_badges/measure?project={{github_organization}}_{{package_name}}&metric=coverage)](https://sonarcloud.io/dashboard?id={{github_organization}}_{{package_name}}) | +| Documentation | [![Documentation Status](https://readthedocs.org/projects/{{package_name}}/badge/?version=latest)](https://{{package_name}}.readthedocs.io/en/latest/?badge=latest) | | **GitHub Actions** |   | | Build | [![build]({{repository_url}}/actions/workflows/build.yml/badge.svg)]({{repository_url}}/actions/workflows/build.yml) | | Citation data consistency | [![cffconvert]({{repository_url}}/actions/workflows/cffconvert.yml/badge.svg)]({{repository_url}}/actions/workflows/cffconvert.yml) | @@ -32,7 +32,7 @@ To install {{ package_name }} from GitHub repository, do: ```console git clone {{ repository }}.git -cd {{ directory_name }} +cd {{ package_name }} python -m pip install . ``` diff --git a/template/next_steps.md.jinja b/template/next_steps.md.jinja index a44875d6..8d0aa499 100644 --- a/template/next_steps.md.jinja +++ b/template/next_steps.md.jinja @@ -13,8 +13,8 @@ Alternatively, you can also use a personal access token, see [Creating a personal access token](https://docs.github.com/en/github-ae@latest/authentication/keeping-your-account-and-data-secure/creating-a-personal-access-token). If you choose this option, below you will have to replace `git@github.com:` by `https://github.com/`. +Inside of the generated directory, run the following commands: ```shell -cd {{ directory_name }} git init git add --all git commit -m "first commit" @@ -26,7 +26,7 @@ git remote add origin {{ repository }} Go to [https://github.com/organizations/{{github_organization}}/repositories/new](https://github.com/organizations/{{github_organization}}/repositories/new) -and create a new repository named `{{ directory_name }}` as an empty repository, then push your commits to GitHub: +and create a new repository named `{{ package_name }}` as an empty repository, then push your commits to GitHub: ```shell git push --set-upstream origin main diff --git a/template/project_setup.md.jinja b/template/project_setup.md.jinja index ca065bf2..0f4949f2 100644 --- a/template/project_setup.md.jinja +++ b/template/project_setup.md.jinja @@ -76,7 +76,7 @@ help you decide which tool to use for packaging. ## Package version number - We recommend using [semantic versioning](https://guide.esciencecenter.nl/#/best_practices/releases?id=semantic-versioning). -- For convenience, the package version is stored in a single place: `{{ directory_name }}/pyproject.toml` under the `tool.bumpversion` header. +- For convenience, the package version is stored in a single place: `pyproject.toml` under the `tool.bumpversion` header. - Don't forget to update the version number before [making a release](https://guide.esciencecenter.nl/#/best_practices/releases)! ## Logging diff --git a/template/sonar-project.properties.jinja b/template/sonar-project.properties.jinja index 2455ef43..268e30d7 100644 --- a/template/sonar-project.properties.jinja +++ b/template/sonar-project.properties.jinja @@ -1,5 +1,5 @@ sonar.organization={{ github_organization }} -sonar.projectKey={{ github_organization }}_{{ directory_name }} +sonar.projectKey={{ github_organization }}_{{ package_name }} sonar.host.url=https://sonarcloud.io sonar.sources=src/{{ package_name }}/ sonar.tests=tests/ diff --git a/tests/test_values.py b/tests/test_values.py index 1f240323..f0cafd48 100644 --- a/tests/test_values.py +++ b/tests/test_values.py @@ -16,21 +16,3 @@ def test_single_quotes_in_name_and_description(copie): project = copie.copy(extra_answers=ctx) assert project.exit_code == 0 - - -def test_dash_in_directory_name(copie): - ctx = { - "directory_name": "my-python-project" - } - project = copie.copy(extra_answers=ctx) - - assert project.exit_code == 0 - - -def test_space_in_directory_name(copie): - ctx = { - "directory_name": "my python project" - } - project = copie.copy(extra_answers=ctx) - - assert project.exit_code == 0 From ce6dd062f24cd5654a1d4367bfb7929a8d8850f3 Mon Sep 17 00:00:00 2001 From: "E. G. Patrick Bos" Date: Thu, 1 Aug 2024 15:10:49 +0200 Subject: [PATCH 06/29] fix tests Copier's run_copy on a template, version controlled with git, by default searches for the latest tag conforming to PEP-440 (https://peps.python.org/pep-0440/#public-version-identifiers) and uses that to generate. This meant that it was still using the 0.4.0 version. We now set it to HEAD explicitly in the tests. Note that we didn't see this failure before in the separate repo because there was no history there. --- tests/test_project.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_project.py b/tests/test_project.py index a9cbbdcd..10cb0fd5 100644 --- a/tests/test_project.py +++ b/tests/test_project.py @@ -43,7 +43,7 @@ def project_env_bin_dir(tmp_path_factory): @pytest.fixture(scope='session') def baked_with_development_dependencies(tmp_path_factory, project_env_bin_dir): - project = run_copy(src_path=str(here()), dst_path=str(tmp_path_factory.mktemp('projects')), defaults=True) + project = run_copy(src_path=str(here()), dst_path=str(tmp_path_factory.mktemp('projects')), defaults=True, vcs_ref="HEAD") project_dir = project.dst_path bin_dir = project_env_bin_dir From e1163da30e7c6db6f07b2fba676afe9822882322 Mon Sep 17 00:00:00 2001 From: Olga Lyashevska Date: Thu, 1 Aug 2024 21:40:06 +0200 Subject: [PATCH 07/29] Escape quotes in name and description --- copier.yml | 8 -------- template/CITATION.cff.jinja | 4 ++-- template/README.md.jinja | 2 +- template/pyproject.toml.jinja | 4 ++-- template/src/{{package_name}}/__init__.py.jinja | 2 +- 5 files changed, 6 insertions(+), 14 deletions(-) diff --git a/copier.yml b/copier.yml index 8359c1f1..4bada3f3 100644 --- a/copier.yml +++ b/copier.yml @@ -11,10 +11,6 @@ package_name: package_short_description: type: str default: Short description of package - validator: >- - {% if (package_short_description | regex_replace ('"', '\\\\"')|regex_replace ("'", "\\\\'")%} - package_short_description must not contain unescaped double or single quotes. - {% endif %} keyword1: type: str default: keyword1 @@ -42,10 +38,6 @@ full_name: type: str default: Jane Smith help: Enter your full name. - # validator: >- - # {% if '"' in full_name %} - # full_name must not contain unescaped double quotes. Use \\" for double quotes. - # {% endif %} email: type: str default: yourname@esciencecenter.nl diff --git a/template/CITATION.cff.jinja b/template/CITATION.cff.jinja index c4facdd5..d8cf8a90 100644 --- a/template/CITATION.cff.jinja +++ b/template/CITATION.cff.jinja @@ -4,8 +4,8 @@ cff-version: "1.2.0" title: "{{ package_name }}" authors: - - family-names: {{ full_name.split(' ')[-1] }} - given-names: {{ full_name.split(' ')[0] }} + family-names: {{ full_name.replace('\"', '\\\"').split(' ')[-1] }} + given-names: {{ full_name.replace('\"', '\\\"').split(' ')[0] }} orcid: "https://orcid.org/0000-0000-0000-0000" date-released: 20??-MM-DD doi: diff --git a/template/README.md.jinja b/template/README.md.jinja index 8093442c..04123ae5 100644 --- a/template/README.md.jinja +++ b/template/README.md.jinja @@ -22,7 +22,7 @@ ## How to use {{ package_name }} -{{ package_short_description }} +{{ package_short_description|replace('\"', '\\\"') }} The project setup is documented in [project_setup.md](project_setup.md). Feel free to remove this document (and/or the link to this document) if you don't need it. diff --git a/template/pyproject.toml.jinja b/template/pyproject.toml.jinja index 4298f46d..0636ce80 100644 --- a/template/pyproject.toml.jinja +++ b/template/pyproject.toml.jinja @@ -9,7 +9,7 @@ build-backend = "setuptools.build_meta" [project] authors = [ - { name = "{{ full_name }}", email = "{{ email }}" } + { name = "{{ full_name|replace('\"', '\\\"') }}", email = "{{ email }}" } ] classifiers = [ "Development Status :: 2 - Pre-Alpha", @@ -31,7 +31,7 @@ classifiers = [ "Programming Language :: Python :: 3.12", ] dependencies = [] -description = "{{ package_short_description }}" +description = "{{ package_short_description|replace('\"', '\\\"') }}" keywords = [ "{{ keyword1 }}", "{{ keyword2 }}", diff --git a/template/src/{{package_name}}/__init__.py.jinja b/template/src/{{package_name}}/__init__.py.jinja index 27c656dd..9d801f51 100644 --- a/template/src/{{package_name}}/__init__.py.jinja +++ b/template/src/{{package_name}}/__init__.py.jinja @@ -3,6 +3,6 @@ import logging logging.getLogger(__name__).addHandler(logging.NullHandler()) -__author__ = "{{ full_name }}" +__author__ = "{{ full_name|replace('\"', '\\\"') }}" __email__ = "{{ email }}" __version__ = "{{ version }}" From 95c293db07b2b86383e2ebce206c0cb1f13dc399 Mon Sep 17 00:00:00 2001 From: Olga Lyashevska Date: Thu, 15 Aug 2024 11:59:43 +0200 Subject: [PATCH 08/29] Update readme dev --- README.dev.md | 30 ++++++++++++++++++++---------- 1 file changed, 20 insertions(+), 10 deletions(-) diff --git a/README.dev.md b/README.dev.md index 1039a9a9..1bea64e9 100644 --- a/README.dev.md +++ b/README.dev.md @@ -4,15 +4,17 @@ If you're looking for user documentation, go [here](README.md). ## Development install -### Install `cookiecutter` in user space +### Install `copier` in user space -We recommend installing `cookiecutter` in user space as per `cookiecutter`'s instructions. This way, you don't have to -install `cookiecutter` for every new project. +We recommend installing `copier` in user space. This way, you don't have to +install `copier` for every new project. ```shell -python -m pip install --user --upgrade cookiecutter +python -m pip install --user --upgrade copier ``` + + ### Get your own copy of the repository Before you can do development work on the template, you'll need to check out a local copy of the repository: @@ -23,6 +25,13 @@ git clone https://github.com/NLeSC/python-template.git cd python-template ``` +Please note that if you are working from some other branch than `main`, you should switch to that branch. For example, if you are working from the `dev` branch, you should do: + +```shell +git fetch origin +git switch -c dev origin/dev +``` + ### Create a virtual environment Next, make a virtual environment, activate it, and install the development dependencies in it. This will enable you to @@ -53,7 +62,7 @@ pytest pytest tests/ ``` -## Using `cookiecutter` to generate a new package from the command line +## Using `copier` to generate a new package from the command line While making changes to the template, you'll regularly want to verify that the packages generated with the template still work. Any easy way to do this is to generate new packages in a temporary directory (which will get removed @@ -61,10 +70,10 @@ everytime you reboot), for example like so: ```shell # change directory to a new temporary directory -cd $(mktemp -d --tmpdir cookiecutter-generated.XXXXXX) +cd $(mktemp -d --tmpdir copier-generated.XXXXXX) -# run cookiecutter with the template to generate a new package -cookiecutter +# run copier with the template to generate a new package +copier copy --vcs-ref HEAD # when it asks you for the GitHub organization, put in your own name; # for the other questions, just accept the default @@ -72,8 +81,9 @@ cookiecutter # 'ls' should return just the one directory called 'my-python-project' ls ``` +Notice, that the `--vcs-ref HEAD` flag is used to make sure that the current checked out version of a local template are used. -If your Python package was created successfully, `cookiecutter` will point you to a file +If your Python package was created successfully, `copier` will point you to a file (`my-python-project/next_steps.md`) that contains information on next steps. In addition to the information in `my-python-project/project_setup.md`, the developer documentation @@ -95,7 +105,7 @@ Follow the instructions from `my-python-project/README.dev.md` and make sure tha 2. Verify that the information in `CITATION.cff` is correct. 3. Make sure that `version` in [setup.cfg](setup.cfg) and `version` in [CITATION.cff](CITATION.cff) have been bumped to the to-be-released version of the template 4. Run the unit tests with `pytest tests/` -5. Go through the steps outlined above for [generating a new package from the command line](#using-cookiecutter-to-generate-a-new-package-from-the-command-line), and verify that the generated package works as it should. +5. Go through the steps outlined above for [generating a new package from the command line](#using-copier-to-generate-a-new-package-from-the-command-line), and verify that the generated package works as it should. ### GitHub From 755e96176706f875deb523272e14860db5cab12d Mon Sep 17 00:00:00 2001 From: Olga Lyashevska Date: Thu, 15 Aug 2024 14:07:32 +0200 Subject: [PATCH 09/29] Update README.dev.md Co-authored-by: Abel Soares Siqueira --- README.dev.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.dev.md b/README.dev.md index 1bea64e9..8caf3756 100644 --- a/README.dev.md +++ b/README.dev.md @@ -73,7 +73,7 @@ everytime you reboot), for example like so: cd $(mktemp -d --tmpdir copier-generated.XXXXXX) # run copier with the template to generate a new package -copier copy --vcs-ref HEAD +copier copy --vcs-ref HEAD my-python-project # when it asks you for the GitHub organization, put in your own name; # for the other questions, just accept the default From d7d5dfbd0e92a1e484facb140f2ef16186986b9f Mon Sep 17 00:00:00 2001 From: Olga Lyashevska Date: Thu, 15 Aug 2024 14:07:48 +0200 Subject: [PATCH 10/29] Update README.dev.md Co-authored-by: Abel Soares Siqueira --- README.dev.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.dev.md b/README.dev.md index 8caf3756..c269eee8 100644 --- a/README.dev.md +++ b/README.dev.md @@ -81,7 +81,7 @@ copier copy --vcs-ref HEAD my-python-project # 'ls' should return just the one directory called 'my-python-project' ls ``` -Notice, that the `--vcs-ref HEAD` flag is used to make sure that the current checked out version of a local template are used. +Notice, that the `--vcs-ref HEAD` flag is used to make sure that the current checked out version of the local template is used. If your Python package was created successfully, `copier` will point you to a file (`my-python-project/next_steps.md`) that contains information on next steps. From c7db00f7af25d783e9c1af11094103d3442353b1 Mon Sep 17 00:00:00 2001 From: Sander van Rijn Date: Mon, 19 Aug 2024 12:21:54 +0200 Subject: [PATCH 11/29] switch PR template instructions to copier --- .github/PULL_REQUEST_TEMPLATE.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 72624dc3..d3e00774 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -16,10 +16,9 @@ Create a `python-template-test` repo on GitHub (will be overwritten if existing) ``` -cd $(mktemp -d --tmpdir py-tmpl-XXXXXX) -cookiecutter -c https://github.com//python-template +copier copy --vcs-ref https://github.com//python-template py-tmpl-XXXXXX # Fill with python-template-test info -cd python-template-test +cd py-tmpl-XXXXXX git init git add --all git commit -m "First commit" From 41177d8d8d145fb13f93af5be6d675376b82193b Mon Sep 17 00:00:00 2001 From: Sander van Rijn Date: Mon, 19 Aug 2024 13:53:27 +0200 Subject: [PATCH 12/29] restore mktemp instruction; add explanatory comments --- .github/PULL_REQUEST_TEMPLATE.md | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index d3e00774..eae558d8 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -16,14 +16,18 @@ Create a `python-template-test` repo on GitHub (will be overwritten if existing) ``` -copier copy --vcs-ref https://github.com//python-template py-tmpl-XXXXXX +# Create a temporary directory in /tmp, keep the XXXXXX in the directory name +cd $(mktemp -d --tmpdir py-tmpl-XXXXXX) +# Use --vcs-ref to point to the branch to you want to test +copier copy --vcs-ref https://github.com//python-template . # Fill with python-template-test info -cd py-tmpl-XXXXXX +# Create a local git repo to push to GitHub to trigger CI actions git init git add --all git commit -m "First commit" -git remote add origin https://github.com//python-template-test +git remote add origin git@github.com:/python-template-test.git git push -u origin main -f +# Create a local environment to test your generated package locally python -m venv env source env/bin/activate python -m pip install --upgrade pip setuptools From 98074b7de15df1ab6b2bb1bb8ec0d3edbd6f10fe Mon Sep 17 00:00:00 2001 From: Sander van Rijn Date: Mon, 19 Aug 2024 14:05:37 +0200 Subject: [PATCH 13/29] Update .github/PULL_REQUEST_TEMPLATE.md Co-authored-by: Olga Lyashevska --- .github/PULL_REQUEST_TEMPLATE.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index eae558d8..0145f12d 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -16,7 +16,7 @@ Create a `python-template-test` repo on GitHub (will be overwritten if existing) ``` -# Create a temporary directory in /tmp, keep the XXXXXX in the directory name +# Create a temporary directory by running the following command. Keep the XXXXXX in the directory name. cd $(mktemp -d --tmpdir py-tmpl-XXXXXX) # Use --vcs-ref to point to the branch to you want to test copier copy --vcs-ref https://github.com//python-template . From 1401b8edd5b23e6ccd1b30883235be07e26bfab8 Mon Sep 17 00:00:00 2001 From: Sander van Rijn Date: Mon, 19 Aug 2024 15:01:59 +0200 Subject: [PATCH 14/29] replace cookiecutter with copier in final files --- NOTICE | 2 +- setup.cfg | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/NOTICE b/NOTICE index c1991889..b17007cf 100644 --- a/NOTICE +++ b/NOTICE @@ -1,2 +1,2 @@ -NLeSC Cookiecutter template for Python +NLeSC Copier template for Python Copyright 2021, Netherlands eScience Center diff --git a/setup.cfg b/setup.cfg index d52e15ba..67b1efdd 100644 --- a/setup.cfg +++ b/setup.cfg @@ -17,7 +17,7 @@ classifiers = Programming Language :: Python :: 3.10 Programming Language :: Python :: 3.11 Programming Language :: Python :: 3.12 -description = Cookiecutter template to initialize Python projects in accordance with Netherlands eScience Center best practices +description = Copier template to initialize Python projects in accordance with Netherlands eScience Center best practices long_description = file: README.md long_description_content_type = text/markdown name = Netherlands eScience Center Python Template From 89168be3d8560170e9ad09f22521f69d47c3f368 Mon Sep 17 00:00:00 2001 From: Faruk Date: Mon, 19 Aug 2024 15:47:14 +0200 Subject: [PATCH 15/29] add messages when creating and copying files --- copier.yml | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/copier.yml b/copier.yml index 4bada3f3..f01d8374 100644 --- a/copier.yml +++ b/copier.yml @@ -60,3 +60,34 @@ repository_url: # Optional questions + + +# user messages + +_message_after_copy: | + Your project "{{ package_name }}" has been created successfully! + + Next steps: + + 1. Change directory to the project root: + + $ cd {{ _copier_conf.dst_path }} + + 2. Read ("{{ package_name }}"/next_steps.md) which contains information on next steps. + +_message_after_update: | + Your project "{{ package_name }}" has been updated successfully! + In case there are any conflicts, please resolve them. Then, + you're done. + +_message_before_copy: | + Thanks for generating a project using our template. + + You'll be asked a series of questions whose answers will be used to + generate a tailored project for you. + +_message_before_update: | + Thanks for updating your project using our template. + + You'll be asked a series of questions whose answers are pre-populated + with previously entered values. Feel free to change them as needed. From a4218b5be5e1804418c7a44ece80195b658a8296 Mon Sep 17 00:00:00 2001 From: Faruk Date: Mon, 19 Aug 2024 15:47:44 +0200 Subject: [PATCH 16/29] add messages when creating and copying files --- copier.yml | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/copier.yml b/copier.yml index f01d8374..086e1b4d 100644 --- a/copier.yml +++ b/copier.yml @@ -64,6 +64,12 @@ repository_url: # user messages +_message_before_copy: | + Thanks for generating a project using our template. + + You'll be asked a series of questions whose answers will be used to + generate a tailored project for you. + _message_after_copy: | Your project "{{ package_name }}" has been created successfully! @@ -75,19 +81,13 @@ _message_after_copy: | 2. Read ("{{ package_name }}"/next_steps.md) which contains information on next steps. -_message_after_update: | - Your project "{{ package_name }}" has been updated successfully! - In case there are any conflicts, please resolve them. Then, - you're done. - -_message_before_copy: | - Thanks for generating a project using our template. - - You'll be asked a series of questions whose answers will be used to - generate a tailored project for you. - _message_before_update: | Thanks for updating your project using our template. You'll be asked a series of questions whose answers are pre-populated with previously entered values. Feel free to change them as needed. + +_message_after_update: | + Your project "{{ package_name }}" has been updated successfully! + In case there are any conflicts, please resolve them. Then, + you're done. From f31c6eb9c18c95be302fefabb26007c1a16b12f0 Mon Sep 17 00:00:00 2001 From: "Faruk D." Date: Mon, 19 Aug 2024 16:24:27 +0200 Subject: [PATCH 17/29] remove double quotes --- copier.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/copier.yml b/copier.yml index 086e1b4d..c8e10a97 100644 --- a/copier.yml +++ b/copier.yml @@ -79,7 +79,7 @@ _message_after_copy: | $ cd {{ _copier_conf.dst_path }} - 2. Read ("{{ package_name }}"/next_steps.md) which contains information on next steps. + 2. Read ({{ package_name }}/next_steps.md) which contains information on next steps. _message_before_update: | Thanks for updating your project using our template. From 03bb88704d748b46328214137f095052d3993579 Mon Sep 17 00:00:00 2001 From: "Faruk D." Date: Mon, 19 Aug 2024 16:30:37 +0200 Subject: [PATCH 18/29] update the patch in before copy message --- copier.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/copier.yml b/copier.yml index c8e10a97..23b2ebf8 100644 --- a/copier.yml +++ b/copier.yml @@ -79,7 +79,7 @@ _message_after_copy: | $ cd {{ _copier_conf.dst_path }} - 2. Read ({{ package_name }}/next_steps.md) which contains information on next steps. + 2. Read ({{ _copier_conf.dst_path }}/next_steps.md) which contains information on next steps. _message_before_update: | Thanks for updating your project using our template. From d711d6a16c3c3e4c4ac38e06959e4882996da072 Mon Sep 17 00:00:00 2001 From: "Faruk D." Date: Mon, 19 Aug 2024 16:32:53 +0200 Subject: [PATCH 19/29] update the patch in before copy message --- copier.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/copier.yml b/copier.yml index 23b2ebf8..7deaed02 100644 --- a/copier.yml +++ b/copier.yml @@ -79,7 +79,7 @@ _message_after_copy: | $ cd {{ _copier_conf.dst_path }} - 2. Read ({{ _copier_conf.dst_path }}/next_steps.md) which contains information on next steps. + 2. Read next_steps.md which contains information on next steps. _message_before_update: | Thanks for updating your project using our template. From 344ca0f9b816ef2324ab84d5a26ce8ce82615786 Mon Sep 17 00:00:00 2001 From: Sander van Rijn Date: Mon, 19 Aug 2024 14:38:10 +0200 Subject: [PATCH 20/29] fix typo --- .github/PULL_REQUEST_TEMPLATE.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 0145f12d..e70f32de 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -18,7 +18,7 @@ Create a `python-template-test` repo on GitHub (will be overwritten if existing) ``` # Create a temporary directory by running the following command. Keep the XXXXXX in the directory name. cd $(mktemp -d --tmpdir py-tmpl-XXXXXX) -# Use --vcs-ref to point to the branch to you want to test +# Use --vcs-ref to point to the branch you want to test copier copy --vcs-ref https://github.com//python-template . # Fill with python-template-test info # Create a local git repo to push to GitHub to trigger CI actions From b805491170a31bcc6bfcf64a4872ae45eb8844b7 Mon Sep 17 00:00:00 2001 From: Sander van Rijn Date: Mon, 19 Aug 2024 17:28:29 +0200 Subject: [PATCH 21/29] remove ADD_TO_EXISTING_PACKAGE file --- ADD_TO_EXISTING_PACKAGE.md | 29 ----------------------------- 1 file changed, 29 deletions(-) delete mode 100644 ADD_TO_EXISTING_PACKAGE.md diff --git a/ADD_TO_EXISTING_PACKAGE.md b/ADD_TO_EXISTING_PACKAGE.md deleted file mode 100644 index 9edfca2b..00000000 --- a/ADD_TO_EXISTING_PACKAGE.md +++ /dev/null @@ -1,29 +0,0 @@ -# Add your existing code to directory generated by the NLeSC Python template - -The following steps requires that your existing code is in a GitHub repository. - -1. Follow the [instructions to create a new package](https://github.com/NLeSC/python-template#how-to-use) with the Python template, while answering the questions like you would for the existing package. - -2. Create a Git structure for the new directory: (replace `` with directory name you used during coopier questionnaire) -```shell -$ cd -$ git init -$ git add --all -$ git commit -m "Added code generated by copier" -$ git branch -M main -``` - -3. Import the existing repository from GitHub (Replace `` with your GitHub organization name , `` with your GitHub repository name and `` with your default branch for example `main` or `master`): -```shell -$ git remote add -f existing_code https://github.com// -$ git fetch existing_code -$ git merge existing_code/ --allow-unrelated-histories -``` - -4. The previous step will likely result in several merge conflicts. Solve the conflicts by editing the files. -5. Once all conflicts have been resolved then add all the files to GitHub: -```shell -$ git add --all -$ git commit -m "Merged existing code with code generated by copier" -$ git push -``` From 79cea70a640bd3175766277b624080bb618eb9a7 Mon Sep 17 00:00:00 2001 From: Sander van Rijn Date: Mon, 19 Aug 2024 17:29:40 +0200 Subject: [PATCH 22/29] update usage instruction to explain 3 ways to use copier --- README.md | 63 +++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 57 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index ec98a601..01e51892 100644 --- a/README.md +++ b/README.md @@ -42,20 +42,29 @@ Use this [Copier](https://copier.readthedocs.io) template to generate an empty P ## How to use -### Step 1/3: Install `copier` +There are multiple ways to use this template: +1. Creating a new package based on the template +2. Applying the template's best practices to some pre-existing code +3. Updating a package made with the template based on the latest template updates + +In all three cases, you will need to install copier first: ```shell pipx install copier ``` -### Step 2/3: Generate the files and directory structure +### Option 1: Create a new package + + +#### Step 1/2: Generate the files and directory structure Run `copier` with the template: ```shell # Notes: -# 1. See table below for explanation of each question -# 2. The files will be generated in a new directory +# 1. Make sure that `path/to/destination` is an empty directory +# 2. See table below for explanation of each question +# 3. The files will be generated in the specified destination directory copier copy https://github.com/nlesc/python-template.git path/to/destination ``` @@ -76,7 +85,7 @@ copier copy https://github.com/nlesc/python-template.git path/to/destination Once the project files have been generated, follow the steps outlined in [template/next_steps.md](template/next_steps.md). -### Step 3/3: Read about what was just generated +#### Step 2/2: Read about what was just generated Good job! You have now generated the skeleton for your package: @@ -135,7 +144,49 @@ Good job! You have now generated the skeleton for your package: ``` For an explanation of what's there, read on in the [project_setup.md](template/project_setup.md) file. -There are also instructions on how to [apply the template to an existing Python package](ADD_TO_EXISTING_PACKAGE.md). + +### Option 2: Apply to pre-existing code + +To apply the template to pre-existing code, you can use the same `copier copy` +command as when creating a new package, except that you point to the folder +containing your existing code rather than a new one: + +```shell +copier copy https://github.com/nlesc/python-template.git path/to/existing/code +``` + +This works because if `path/to/destination` already exists, `copier` will +update what is already there by either adding new files or updating +existing files. Copier will ask to overwrite any files that resulted in +conflicts. Especially if your files are already under version control, it is +recommended to answer 'yes' for all files, you will still be able to review +the changes suggested by the template. + +### Option 3. Updating a template-made package + +Copier provides the functionality for re-applying the template to a previously +created project using the `copier update` command. This has two effects: + +1. Your project will be updated according to the latest version of the template +2. You can change any of your previous answers to apply these changes + throughout your entire project. + +```shell +cd path/to/project +copier update +``` + +If you don't want to change any of your answers, but only want to update your +project according to the latest template updates, you can provide the +`--skip-answered` option. This tells copier to reuse all of your previous +answers, and simply bring in all updates from the template into +your current project, such as updating which Python versions are supported. +You will still be asked to answer any new questions that have been added to +the template since you last applied it. + +```shell +copier update --skip-answered +``` ## Examples From 6e09142857e3623b71ea2a22b8110ab0bd583da8 Mon Sep 17 00:00:00 2001 From: Sander van Rijn Date: Tue, 20 Aug 2024 11:16:30 +0200 Subject: [PATCH 23/29] Update README.md Co-authored-by: fdiblen <144492+fdiblen@users.noreply.github.com> --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 01e51892..5752f684 100644 --- a/README.md +++ b/README.md @@ -45,7 +45,7 @@ Use this [Copier](https://copier.readthedocs.io) template to generate an empty P There are multiple ways to use this template: 1. Creating a new package based on the template -2. Applying the template's best practices to some pre-existing code +2. Applying the template to some pre-existing code 3. Updating a package made with the template based on the latest template updates In all three cases, you will need to install copier first: From 5f369e7e9308e01b7bfef86aaa6a2c1a2b12be61 Mon Sep 17 00:00:00 2001 From: Sander van Rijn Date: Tue, 20 Aug 2024 11:16:52 +0200 Subject: [PATCH 24/29] Update README.md Co-authored-by: Olga Lyashevska --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 5752f684..ae8366c5 100644 --- a/README.md +++ b/README.md @@ -42,7 +42,7 @@ Use this [Copier](https://copier.readthedocs.io) template to generate an empty P ## How to use -There are multiple ways to use this template: +There are multiple scenarios to use this template: 1. Creating a new package based on the template 2. Applying the template to some pre-existing code From fc07bfe35eb258dc37e747a13bb0a5e11147c87c Mon Sep 17 00:00:00 2001 From: Sander van Rijn Date: Tue, 20 Aug 2024 11:21:27 +0200 Subject: [PATCH 25/29] Update README.md Co-authored-by: Olga Lyashevska --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index ae8366c5..740838f2 100644 --- a/README.md +++ b/README.md @@ -46,7 +46,7 @@ There are multiple scenarios to use this template: 1. Creating a new package based on the template 2. Applying the template to some pre-existing code -3. Updating a package made with the template based on the latest template updates +3. Updating a package made with the template In all three cases, you will need to install copier first: ```shell From 5aa33ded8c61da1990315eee833d2a7ecc9c0244 Mon Sep 17 00:00:00 2001 From: Sander van Rijn Date: Tue, 20 Aug 2024 11:21:51 +0200 Subject: [PATCH 26/29] Update README.md Co-authored-by: Olga Lyashevska --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 740838f2..9221dbf7 100644 --- a/README.md +++ b/README.md @@ -44,7 +44,7 @@ Use this [Copier](https://copier.readthedocs.io) template to generate an empty P There are multiple scenarios to use this template: -1. Creating a new package based on the template +1. Generating a new package using template 2. Applying the template to some pre-existing code 3. Updating a package made with the template From 227f82beeb1f83cc4a45937f92d1d0e9b69d2ab0 Mon Sep 17 00:00:00 2001 From: Sander van Rijn Date: Tue, 20 Aug 2024 11:32:11 +0200 Subject: [PATCH 27/29] rename options/cases to scenarios --- README.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 9221dbf7..e0fba446 100644 --- a/README.md +++ b/README.md @@ -44,19 +44,19 @@ Use this [Copier](https://copier.readthedocs.io) template to generate an empty P There are multiple scenarios to use this template: -1. Generating a new package using template -2. Applying the template to some pre-existing code -3. Updating a package made with the template +[Scenario 1](#scenario-1-create-a-new-package): Generating a new package using template +[Scenario 2](#scenario-2-apply-to-pre-existing-code): Applying the template to some pre-existing code +[Scenario 3](#scenario-3-updating-a-template-made-package): Updating a package made with the template -In all three cases, you will need to install copier first: +In all three scenarios, you will need to install copier first: ```shell pipx install copier ``` -### Option 1: Create a new package +### Scenario 1: Create a new package -#### Step 1/2: Generate the files and directory structure +#### Step 1/2: Create the files and directory structure Run `copier` with the template: @@ -83,7 +83,7 @@ copier copy https://github.com/nlesc/python-template.git path/to/destination | code_of_conduct_email | yourname@esciencecenter.nl | Email address of the person who should be contacted in case of violations of the Code of Conduct. | Once the project files have been generated, follow the steps outlined in -[template/next_steps.md](template/next_steps.md). +[next_steps.md](template/next_steps.md). #### Step 2/2: Read about what was just generated @@ -145,7 +145,7 @@ Good job! You have now generated the skeleton for your package: For an explanation of what's there, read on in the [project_setup.md](template/project_setup.md) file. -### Option 2: Apply to pre-existing code +### Scenario 2: Apply to pre-existing code To apply the template to pre-existing code, you can use the same `copier copy` command as when creating a new package, except that you point to the folder @@ -162,7 +162,7 @@ conflicts. Especially if your files are already under version control, it is recommended to answer 'yes' for all files, you will still be able to review the changes suggested by the template. -### Option 3. Updating a template-made package +### Scenario 3. Updating a template-made package Copier provides the functionality for re-applying the template to a previously created project using the `copier update` command. This has two effects: From 4debab7de1f2942f4b4dbb5bebbfa51ab1a1fba4 Mon Sep 17 00:00:00 2001 From: Sander van Rijn Date: Tue, 20 Aug 2024 11:50:26 +0200 Subject: [PATCH 28/29] Add pipx install instructions + explanation --- README.md | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index e0fba446..afc8a257 100644 --- a/README.md +++ b/README.md @@ -48,17 +48,26 @@ There are multiple scenarios to use this template: [Scenario 2](#scenario-2-apply-to-pre-existing-code): Applying the template to some pre-existing code [Scenario 3](#scenario-3-updating-a-template-made-package): Updating a package made with the template -In all three scenarios, you will need to install copier first: +In all three scenarios, you will need to install Copier first, which we +recommend doing with [`pipx`](https://github.com/pypa/pipx): ```shell +python3 -m pip install --user pipx +python3 -m pipx ensurepath pipx install copier ``` +> [!NOTE] +> Note that it is also possible to install Copier with regular `pip`, but that +> Copier will then be installed in your common environment and may cause +> conflicts with its dependencies, while `pipx` will install Copier in a +> separate and dedicated environment. + ### Scenario 1: Create a new package #### Step 1/2: Create the files and directory structure -Run `copier` with the template: +Run `copier copy` with the template: ```shell # Notes: @@ -155,7 +164,7 @@ containing your existing code rather than a new one: copier copy https://github.com/nlesc/python-template.git path/to/existing/code ``` -This works because if `path/to/destination` already exists, `copier` will +This works because if `path/to/destination` already exists, Copier will update what is already there by either adding new files or updating existing files. Copier will ask to overwrite any files that resulted in conflicts. Especially if your files are already under version control, it is @@ -171,6 +180,10 @@ created project using the `copier update` command. This has two effects: 2. You can change any of your previous answers to apply these changes throughout your entire project. +> [!CAUTION] +> Do not manually update answers in `.copier-answers.yml`, +> as it will result in unexpected behavior. + ```shell cd path/to/project copier update @@ -178,7 +191,7 @@ copier update If you don't want to change any of your answers, but only want to update your project according to the latest template updates, you can provide the -`--skip-answered` option. This tells copier to reuse all of your previous +`--skip-answered` option. This tells Copier to reuse all of your previous answers, and simply bring in all updates from the template into your current project, such as updating which Python versions are supported. You will still be asked to answer any new questions that have been added to From 399a7a11d336bd48a1326580517b5aeb6d9db590 Mon Sep 17 00:00:00 2001 From: Sander van Rijn Date: Tue, 20 Aug 2024 12:03:54 +0200 Subject: [PATCH 29/29] scenarios as list --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index afc8a257..d7951f13 100644 --- a/README.md +++ b/README.md @@ -44,9 +44,9 @@ Use this [Copier](https://copier.readthedocs.io) template to generate an empty P There are multiple scenarios to use this template: -[Scenario 1](#scenario-1-create-a-new-package): Generating a new package using template -[Scenario 2](#scenario-2-apply-to-pre-existing-code): Applying the template to some pre-existing code -[Scenario 3](#scenario-3-updating-a-template-made-package): Updating a package made with the template +- [Scenario 1](#scenario-1-create-a-new-package): Generating a new package using template +- [Scenario 2](#scenario-2-apply-to-pre-existing-code): Applying the template to some pre-existing code +- [Scenario 3](#scenario-3-updating-a-template-made-package): Updating a package made with the template In all three scenarios, you will need to install Copier first, which we recommend doing with [`pipx`](https://github.com/pypa/pipx):