From d9eac1514d040eaaf66b42ddc3bbc2b6de23b231 Mon Sep 17 00:00:00 2001 From: jday7879 <57715292+Jday7879@users.noreply.github.com> Date: Mon, 7 Jul 2025 16:22:50 +0100 Subject: [PATCH 01/14] Removed: - pre-commit files - make files - R files - Example pipeline and unit tests - removed pyproject toml, this only contained pre commit details --- {{ cookiecutter.repo_name }}/.Rprofile | 1 - {{ cookiecutter.repo_name }}/.env | 33 ---- {{ cookiecutter.repo_name }}/.envrc | 23 --- {{ cookiecutter.repo_name }}/.flake8 | 9 - .../.pre-commit-config.yaml | 184 ------------------ {{ cookiecutter.repo_name }}/.secrets | 20 -- .../.secrets.baseline | 94 --------- {{ cookiecutter.repo_name }}/CONTRIBUTING.md | 6 - {{ cookiecutter.repo_name }}/DESCRIPTION | 18 -- {{ cookiecutter.repo_name }}/Makefile | 88 --------- {{ cookiecutter.repo_name }}/make.bat | 72 ------- {{ cookiecutter.repo_name }}/pyproject.toml | 30 --- {{ cookiecutter.repo_name }}/startup.R | 7 - .../tests/test_example_module.py | 54 ----- .../example_config.yml | 3 - .../example_module}/__init__.py | 0 .../example_modules/__init__.py | 0 .../example_modules/example_module.py | 92 --------- .../main.py} | 0 .../run_pipeline.py | 25 --- 20 files changed, 759 deletions(-) delete mode 100644 {{ cookiecutter.repo_name }}/.Rprofile delete mode 100644 {{ cookiecutter.repo_name }}/.env delete mode 100644 {{ cookiecutter.repo_name }}/.envrc delete mode 100644 {{ cookiecutter.repo_name }}/.flake8 delete mode 100644 {{ cookiecutter.repo_name }}/.pre-commit-config.yaml delete mode 100644 {{ cookiecutter.repo_name }}/.secrets delete mode 100644 {{ cookiecutter.repo_name }}/.secrets.baseline delete mode 100644 {{ cookiecutter.repo_name }}/CONTRIBUTING.md delete mode 100644 {{ cookiecutter.repo_name }}/DESCRIPTION delete mode 100644 {{ cookiecutter.repo_name }}/Makefile delete mode 100644 {{ cookiecutter.repo_name }}/make.bat delete mode 100644 {{ cookiecutter.repo_name }}/pyproject.toml delete mode 100644 {{ cookiecutter.repo_name }}/startup.R delete mode 100644 {{ cookiecutter.repo_name }}/tests/test_example_module.py delete mode 100644 {{ cookiecutter.repo_name }}/{{ cookiecutter.repo_name.lower().replace(' ', '_').replace('-', '_') }}/example_config.yml rename {{ cookiecutter.repo_name }}/{tests => {{ cookiecutter.repo_name.lower().replace(' ', '_').replace('-', '_') }}/example_module}/__init__.py (100%) delete mode 100644 {{ cookiecutter.repo_name }}/{{ cookiecutter.repo_name.lower().replace(' ', '_').replace('-', '_') }}/example_modules/__init__.py delete mode 100644 {{ cookiecutter.repo_name }}/{{ cookiecutter.repo_name.lower().replace(' ', '_').replace('-', '_') }}/example_modules/example_module.py rename {{ cookiecutter.repo_name }}/{conftest.py => {{ cookiecutter.repo_name.lower().replace(' ', '_').replace('-', '_') }}/main.py} (100%) delete mode 100644 {{ cookiecutter.repo_name }}/{{ cookiecutter.repo_name.lower().replace(' ', '_').replace('-', '_') }}/run_pipeline.py diff --git a/{{ cookiecutter.repo_name }}/.Rprofile b/{{ cookiecutter.repo_name }}/.Rprofile deleted file mode 100644 index 10c26cf..0000000 --- a/{{ cookiecutter.repo_name }}/.Rprofile +++ /dev/null @@ -1 +0,0 @@ -source('startup.R') diff --git a/{{ cookiecutter.repo_name }}/.env b/{{ cookiecutter.repo_name }}/.env deleted file mode 100644 index d886609..0000000 --- a/{{ cookiecutter.repo_name }}/.env +++ /dev/null @@ -1,33 +0,0 @@ -# Environment variables go here, and can be read in by Python using the `python-dotenv` -# package, and `os.getenv`: -# -# ------------------------------------------------------------------------------------ -# from dotenv import load_dotenv -# import os -# -# # Load the environment variables from the `.env` file, overriding any system -# # environment variables -# load_dotenv(override=True) -# -# # Load secrets from the `.secrets` file, overriding any system environment variables -# load_dotenv(".secrets", override=True) -# -# # Example variable -# EXAMPLE_VARIABLE = os.getenv("EXAMPLE_VARIABLE") -# ------------------------------------------------------------------------------------ -# -# For folder/file path environment variables, use relative paths. -# -# DO NOT STORE SECRETS HERE - this file is version-controlled! You should store secrets -# in the untracked `.secrets` file. - -# Add environment variables for the `docs` directory -DIR_DOCS=./docs - -# Add environment variable for package directory - -# Add environment variables for the `src` directories -DIR_COOKIECUTTER.REPO_NAME.LOWER().REPLACE('','_').REPLACE('-','_') =./{{ cookiecutter.repo_name.lower().replace(' ', '_').replace('-', '_') }} - -# Add environment variables for the `tests` directory -DIR_TESTS=./tests diff --git a/{{ cookiecutter.repo_name }}/.envrc b/{{ cookiecutter.repo_name }}/.envrc deleted file mode 100644 index 10ddb6e..0000000 --- a/{{ cookiecutter.repo_name }}/.envrc +++ /dev/null @@ -1,23 +0,0 @@ -# Orchestration file to load environment variables from the `.env` and `.secrets` files. -# -# Only used by systems with `direnv` (https://direnv.net/) installed. Environment -# variables can be read in by Python using `os.getenv` _without_ using `python-dotenv`: -# -# ------------------------------------------------------------------------------------ -# import os -# -# # Example variable -# EXAMPLE_VARIABLE = os.getenv("EXAMPLE_VARIABLE") -# ------------------------------------------------------------------------------------ -# -# DO NOT STORE SECRETS HERE - this file is version-controlled! You should store secrets -# in the untracked `.secrets` file. This is loaded here using the `dotenv_if_exists` -# command. - -# Add the working directory to `PYTHONPATH`; allows Jupyter notebooks in the -# `notebooks` folder to import `src` -export PYTHONPATH="$PYTHONPATH:$(pwd)" - -# Load the `.env` file, and `.secrets` (if it exists) -dotenv .env -dotenv_if_exists .secrets diff --git a/{{ cookiecutter.repo_name }}/.flake8 b/{{ cookiecutter.repo_name }}/.flake8 deleted file mode 100644 index e9bfa57..0000000 --- a/{{ cookiecutter.repo_name }}/.flake8 +++ /dev/null @@ -1,9 +0,0 @@ -[flake8] -# Rule definitions: http://flake8.pycqa.org/en/latest/user/error-codes.html -# D203: 1 blank line required before class docstring -# W503: line break before binary operator -exclude = venv*,__pycache__,node_modules,bower_components,migrations -ignore = D203,W503 -max-complexity = 9 -max-line-length = 88 -extend-ignore = E203 diff --git a/{{ cookiecutter.repo_name }}/.pre-commit-config.yaml b/{{ cookiecutter.repo_name }}/.pre-commit-config.yaml deleted file mode 100644 index 5adcfa8..0000000 --- a/{{ cookiecutter.repo_name }}/.pre-commit-config.yaml +++ /dev/null @@ -1,184 +0,0 @@ -# See https://pre-commit.com for more information -# See https://pre-commit.com/hooks.html for more hooks -repos: -{% if cookiecutter.locked_down_environment == "No" %} - - repo: https://github.com/kynan/nbstripout - rev: 0.8.1 - hooks: - - id: nbstripout - name: nbstripout - Strip outputs from notebooks (auto-fixes) - args: - - --extra-keys - - "metadata.colab metadata.kernelspec cell.metadata.colab cell.metadata.executionInfo cell.metadata.id cell.metadata.outputId" - - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v5.0.0 - hooks: - - id: check-added-large-files - name: Check for files larger than 5 MB - args: [ "--maxkb=5120" ] - - id: end-of-file-fixer - name: Check for a blank line at the end of scripts (auto-fixes) - exclude: '\.Rd' - - id: trailing-whitespace - name: Check for trailing whitespaces (auto-fixes) - - repo: https://github.com/pycqa/isort - rev: 6.0.1 - hooks: - - id: isort - name: isort - Sort python imports (auto-fixes) - args: [ "--profile", "black", "--filter-files" ] - - id: isort - name: isort - Sort cython imports (auto-fixes) - types: [cython] - args: [ "--profile", "black", "--filter-files" ] - - id: isort - name: isort - Sort pyi imports (auto-fixes) - types: [pyi] - args: [ "--profile", "black", "--filter-files" ] - - repo: https://github.com/psf/black - rev: 25.1.0 # Replace by any tag/version: https://github.com/psf/black/tags - hooks: - - id: black - name: black - consistent Python code formatting (auto-fixes) - language_version: python # Should be a command that runs python3.6+ - - repo: https://github.com/PyCQA/flake8 - rev: 7.1.2 - hooks: - - id: flake8 - name: flake8 - Python linting - - repo: https://github.com/nbQA-dev/nbQA - rev: 0.12.0 - hooks: - - id: nbqa-isort - name: nbqa-isort - Sort Python imports (notebooks; auto-fixes) - args: [ --nbqa-mutate ] - additional_dependencies: [ isort==5.8.0 ] - - id: nbqa-black - name: nbqa-black - consistent Python code formatting (notebooks; auto-fixes) - args: [ --nbqa-mutate ] - additional_dependencies: [ black==21.5b2 ] - # TODO: Disabled for now until it's clear how to add noqa to specific cells of a Jupyter notebook - #- id: nbqa-flake8 - # name: nbqa-flake8 - Python linting (notebooks) - # additional_dependencies: [ flake8==3.9.2 ] - - repo: https://github.com/Yelp/detect-secrets - rev: v1.5.0 - hooks: - - id: detect-secrets - name: detect-secrets - Detect secrets in staged code - args: [ "--baseline", ".secrets.baseline" ] - exclude: .*/tests/.*|^\.cruft\.json$ - - repo: https://github.com/PyCQA/bandit - rev: 1.8.3 - hooks: - - id: bandit - name: bandit - Checks for vulnerabilities - args: ["-c", "pyproject.toml"] - additional_dependencies: ["bandit[toml]"] -{% endif -%} -{% if cookiecutter.using_R == "Yes" %} - # R specific hooks: https://github.com/lorenzwalthert/precommit - - repo: https://github.com/lorenzwalthert/precommit - rev: v0.1.3 - hooks: - - id: style-files - name: Style files using styler - args: [ --style_pkg=styler, --style_fun=tidyverse_style ] - - id: roxygenize - name: Run roxygen2::roxygenize() - # codemeta must be above use-tidy-description when both are used - # - id: codemeta-description-updated - - id: use-tidy-description - name: Run sethis::use_tidy_description() - - id: lintr - name: Run lintr::linters_with_defaults() - exclude: renv/activate.R - - id: readme-rmd-rendered - name: Check README.Rmd has been rendered to README.md - - id: parsable-R - name: Check for valid R code using the parse() function - - id: no-browser-statement - name: Check for accidential browser() statements -{% endif -%} -{% if cookiecutter.locked_down_environment == "Yes" %} -- repo: local - hooks: - - id: nbstripout - name: nbstripout - Strip outputs from notebooks (auto-fixes) - entry: nbstripout - language: system - args: - - --extra-keys - - "metadata.colab metadata.kernelspec cell.metadata.colab cell.metadata.executionInfo cell.metadata.id cell.metadata.outputId" - - - id: check-added-large-files - name: Check for files larger than 5 MB - entry: check-added-large-files - language: system - args: - - "--maxkb=5120" - - - id: end-of-file-fixer - name: Check for a blank line at the end of scripts (auto-fixes) - entry: end-of-file-fixer - language: system - exclude: '\.Rd' - - - id: trailing-whitespace - name: Check for trailing whitespaces (auto-fixes) - entry: trailing-whitespace-fixer - language: system - - - id: isort - name: isort - Sort python imports (auto-fixes) - entry: isort - language: system - args: - - "--profile" - - "black" - - "--filter-files" - - - id: black - name: black - consistent Python code formatting (auto-fixes) - entry: black - language: system - types: [python] - - - id: flake8 - name: flake8 - Python linting - entry: flake8 - language: system - types: [python] - - - id: nbqa-isort - name: nbqa-isort - Sort Python imports (notebooks; auto-fixes) - entry: nbqa - language: system - args: - - isort - - --nbqa-mutate - - - id: nbqa-black - name: nbqa-black - consistent Python code formatting (notebooks; auto-fixes) - entry: nbqa - language: system - types: [python] - args: - - black - - --nbqa-mutate - - - id: detect-secrets - name: detect-secrets - Detect secrets in staged code - entry: detect-secrets-hook - language: system - exclude: .*/tests/.*|^\.cruft\.json$ - - - id: bandit - name: bandit - Checks for vulnerabilities - entry: bandit - language: system - args: - - "-c" - - "pyproject.toml" - -{% endif -%} diff --git a/{{ cookiecutter.repo_name }}/.secrets b/{{ cookiecutter.repo_name }}/.secrets deleted file mode 100644 index 60bc85d..0000000 --- a/{{ cookiecutter.repo_name }}/.secrets +++ /dev/null @@ -1,20 +0,0 @@ -# Secrets and credentials should be stored here as environmental variables. For example: -# -# # Google Cloud authentication credentials -# GOOGLE_APPLICATION_CREDENTIALS=path/to/credentials.json -# -# These environment variables can then be read in by Python using the `python-dotenv` -# package, and `os.getenv`: -# -# ------------------------------------------------------------------------------------ -# from dotenv import load_dotenv -# import os -# -# # Load secrets from the `.secrets` file, overriding any system environment variables -# load_dotenv(".secrets", override=True) -# -# # Google Cloud authentication credentials -# GOOGLE_APPLICATION_CREDENTIALS = os.getenv("GOOGLE_APPLICATION_CREDENTIALS") -# ------------------------------------------------------------------------------------ -# -# This file is NOT version-controlled! diff --git a/{{ cookiecutter.repo_name }}/.secrets.baseline b/{{ cookiecutter.repo_name }}/.secrets.baseline deleted file mode 100644 index 58012f6..0000000 --- a/{{ cookiecutter.repo_name }}/.secrets.baseline +++ /dev/null @@ -1,94 +0,0 @@ -{ - "version": "1.0.3", - "plugins_used": [ - { - "name": "ArtifactoryDetector" - }, - { - "name": "AWSKeyDetector" - }, - { - "name": "AzureStorageKeyDetector" - }, - { - "name": "Base64HighEntropyString", - "limit": 4.5 - }, - { - "name": "BasicAuthDetector" - }, - { - "name": "CloudantDetector" - }, - { - "name": "HexHighEntropyString", - "limit": 3.0 - }, - { - "name": "IbmCloudIamDetector" - }, - { - "name": "IbmCosHmacDetector" - }, - { - "name": "JwtTokenDetector" - }, - { - "name": "KeywordDetector", - "keyword_exclude": "" - }, - { - "name": "MailchimpDetector" - }, - { - "name": "NpmDetector" - }, - { - "name": "PrivateKeyDetector" - }, - { - "name": "SlackDetector" - }, - { - "name": "SoftlayerDetector" - }, - { - "name": "SquareOAuthDetector" - }, - { - "name": "StripeDetector" - }, - { - "name": "TwilioKeyDetector" - } - ], - "filters_used": [ - { - "path": "detect_secrets.filters.allowlist.is_line_allowlisted" - }, - { - "path": "detect_secrets.filters.common.is_ignored_due_to_verification_policies", - "min_level": 2 - }, - { - "path": "detect_secrets.filters.heuristic.is_indirect_reference" - }, - { - "path": "detect_secrets.filters.heuristic.is_likely_id_string" - }, - { - "path": "detect_secrets.filters.heuristic.is_potential_uuid" - }, - { - "path": "detect_secrets.filters.heuristic.is_prefixed_with_dollar_sign" - }, - { - "path": "detect_secrets.filters.heuristic.is_sequential_string" - }, - { - "path": "detect_secrets.filters.heuristic.is_templated_secret" - } - ], - "results": {}, - "generated_at": "2021-06-14T10:43:14Z" -} diff --git a/{{ cookiecutter.repo_name }}/CONTRIBUTING.md b/{{ cookiecutter.repo_name }}/CONTRIBUTING.md deleted file mode 100644 index 46ca528..0000000 --- a/{{ cookiecutter.repo_name }}/CONTRIBUTING.md +++ /dev/null @@ -1,6 +0,0 @@ -# Contributing - -[Our contributing guidelines can be found at -`docs/contributor_guide/CONTRIBUTING.md`][contributing]. - -[contributing]: ./docs/contributor_guide/CONTRIBUTING.md diff --git a/{{ cookiecutter.repo_name }}/DESCRIPTION b/{{ cookiecutter.repo_name }}/DESCRIPTION deleted file mode 100644 index c6d3568..0000000 --- a/{{ cookiecutter.repo_name }}/DESCRIPTION +++ /dev/null @@ -1,18 +0,0 @@ -Package: {{ cookiecutter.repo_name }} -Title: {{ cookiecutter.project_name }} -Version: {{ cookiecutter.project_version }} -Authors@R: - person("{{ cookiecutter.organisation_handle }}", , , "organisation@email.address", role = c("aut", "cre")) -Description: {{ cookiecutter.overview }} -License: MIT + file LICENSE -Imports: - docopt, - git2r, - lintr, - styler, - usethis -Encoding: UTF-8 -Language: en-GB -LazyData: true -Roxygen: list(markdown = TRUE) -RoxygenNote: 7.0.0 diff --git a/{{ cookiecutter.repo_name }}/Makefile b/{{ cookiecutter.repo_name }}/Makefile deleted file mode 100644 index 24203d8..0000000 --- a/{{ cookiecutter.repo_name }}/Makefile +++ /dev/null @@ -1,88 +0,0 @@ -.PHONY: - coverage - coverage_html - coverage_xml - docs - docs_check_external_links - help - install - install_dev - prepare_docs_folder - -.DEFAULT_GOAL := help - -## Install the Python package for contributors, and install pre-commit hooks -install_dev: - python -m pip install -U pip setuptools - python -m pip install -e .[dev] - pre-commit install - -## Install the Python package for users -install: - python -m pip install -U pip setuptools - python -m pip install -e . - -## Create a `docs/_build` folder, if it does not exist. Otherwise delete any sub-folders and their contents within it -prepare_docs_folder: - if [ ! -d "./docs/_build" ]; then mkdir ./docs/_build; fi - find ./docs/_build -mindepth 1 -maxdepth 1 -type d -exec rm -rf {} \; - -## Compile the Sphinx documentation in HTML format in the docs/_build folder from a clean build -docs: prepare_docs_folder install_dev - sphinx-build -b html ./docs ./docs/_build - -## Check external links in the Sphinx documentation using linkcheck in the docs/_build folder from a clean build -docs_check_external_links: prepare_docs_folder install_dev - sphinx-build -b linkcheck ./docs ./docs/_build - -## Run code coverage -coverage: install_dev - coverage run -m pytest - -## Run code coverage, and produce a HTML output -coverage_html: coverage - coverage html - -## Run code coverage, and produce an XML output -coverage_xml: coverage - coverage xml - -## Get help on all make commands; referenced from https://github.com/drivendata/cookiecutter-data-science -help: - @echo "$$(tput bold)Available rules:$$(tput sgr0)" - @echo - @sed -n -e "/^## / { \ - h; \ - s/.*//; \ - :doc" \ - -e "H; \ - n; \ - s/^## //; \ - t doc" \ - -e "s/:.*//; \ - G; \ - s/\\n## /---/; \ - s/\\n/ /g; \ - p; \ - }" ${MAKEFILE_LIST} \ - | LC_ALL='C' sort --ignore-case \ - | awk -F '---' \ - -v ncol=$$(tput cols) \ - -v indent=25 \ - -v col_on="$$(tput setaf 6)" \ - -v col_off="$$(tput sgr0)" \ - '{ \ - printf "%s%*s%s ", col_on, -indent, $$1, col_off; \ - n = split($$2, words, " "); \ - line_length = ncol - indent; \ - for (i = 1; i <= n; i++) { \ - line_length -= length(words[i]) + 1; \ - if (line_length <= 0) { \ - line_length = ncol - indent - length(words[i]) - 1; \ - printf "\n%*s ", -indent, " "; \ - } \ - printf "%s ", words[i]; \ - } \ - printf "\n"; \ - }' \ - | more $(shell test $(shell uname) = Darwin && echo '--no-init --raw-control-chars') diff --git a/{{ cookiecutter.repo_name }}/make.bat b/{{ cookiecutter.repo_name }}/make.bat deleted file mode 100644 index 6f79204..0000000 --- a/{{ cookiecutter.repo_name }}/make.bat +++ /dev/null @@ -1,72 +0,0 @@ -@echo off - - -IF /I "%1"=="" GOTO .DEFAULT_GOAL -IF /I "%1"=="install" GOTO install -IF /I "%1"=="install_dev" GOTO install_dev -IF /I "%1"=="prepare_docs_folder" GOTO prepare_docs_folder -IF /I "%1"=="docs" GOTO docs -IF /I "%1"=="docs_check_external_links" GOTO docs_check_external_links -IF /I "%1"=="coverage" GOTO coverage -IF /I "%1"=="coverage_html" GOTO coverage_html -IF /I "%1"=="coverage_xml" GOTO coverage_xml -IF /I "%1"=="help" GOTO help -GOTO error - -:.DEFAULT_GOAL - GOTO help - -:install_dev - python -m pip install -U pip setuptools - python -m pip install -e .[dev] - pre-commit install - GOTO :EOF - -:install - python -m pip install -U pip setuptools - python -m pip install -e . - GOTO :EOF - -:prepare_docs_folder - IF exist "./docs/_build" ( rmdir /s /q "./docs/_build/" ) - mkdir ".\docs\_build" - GOTO :EOF - -:docs - CALL make.bat prepare_docs_folder - CALL make.bat install_dev - sphinx-build -b html ./docs ./docs/_build - GOTO :EOF - -:docs_check_external_links - CALL make.bat prepare_docs_folder - CALL make.bat install_dev - sphinx-build -b linkcheck ./docs ./docs/_build - GOTO :EOF - -:coverage - CALL make.bat install_dev - coverage run -m pytest - GOTO :EOF - -:coverage_html - CALL make.bat coverage - coverage html - GOTO :EOF - -:coverage_xml - CALL make.bat coverage - coverage xml - GOTO :EOF - -:help - ECHO make: Use one of the following commands: install, install_dev, docs, docs_check_external_links, coverage, coverage_html, coverage_xml. - GOTO :EOF - -:error - IF "%1"=="" ( - ECHO make: *** No targets specified and no makefile found. Stop. - ) ELSE ( - ECHO make: *** No rule to make target '%1%'. Stop. - ) - GOTO :EOF diff --git a/{{ cookiecutter.repo_name }}/pyproject.toml b/{{ cookiecutter.repo_name }}/pyproject.toml deleted file mode 100644 index 64b919e..0000000 --- a/{{ cookiecutter.repo_name }}/pyproject.toml +++ /dev/null @@ -1,30 +0,0 @@ -# `coverage` configurations -[tool.coverage.run] -source = [ - "./" -] - -[tool.coverage.report] -exclude_lines = [ - "if __name__ == .__main__.:" -] - -# `isort` configurations -[tool.isort] -profile = "black" - -# `pytest` configurations -[tool.pytest.ini_options] -addopts = [ - "-vv", - "--doctest-modules" -] -doctest_optionflags = "NORMALIZE_WHITESPACE" -testpaths = [ - "./tests" -] - -# `bandit' configurations -[tool.bandit] -exclude_dirs = ["tests", "docs"] -skips = [] diff --git a/{{ cookiecutter.repo_name }}/startup.R b/{{ cookiecutter.repo_name }}/startup.R deleted file mode 100644 index c4a19de..0000000 --- a/{{ cookiecutter.repo_name }}/startup.R +++ /dev/null @@ -1,7 +0,0 @@ -if (length(grep(pattern = "devtools", x = utils::installed.packages()[, 1])) == 0) { - Sys.setenv(R_PROFILE_USER = "/dev/null") - utils::install.packages(pkgs = "devtools", Ncpus = 1, repos = "https://CRAN.R-project.org") - # install packages from DESCRIPTION file - devtools::install() - Sys.unsetenv("R_PROFILE_USER") -} diff --git a/{{ cookiecutter.repo_name }}/tests/test_example_module.py b/{{ cookiecutter.repo_name }}/tests/test_example_module.py deleted file mode 100644 index a480ae6..0000000 --- a/{{ cookiecutter.repo_name }}/tests/test_example_module.py +++ /dev/null @@ -1,54 +0,0 @@ -import pytest - -from {{ cookiecutter.repo_name.lower().replace(' ', '_').replace('-', '_') }}.example_modules.example_module import ( - hello_world, - print_favourite_number, - print_string, -) - - -class TestHelloWorld: - def test_string_concat(self): - assert hello_world("Bob", "ONS") == "Hello Bob and hello everyone at ONS" - - def test_name_type_error(self): - with pytest.raises(TypeError): - hello_world(1, "ONS") - - def test_company_type_error(self): - with pytest.raises(TypeError): - hello_world("Bob", 1) - - def test_name_and_company_type_error(self): - with pytest.raises(TypeError): - hello_world(1, 2) - - -class TestPrintString: - def test_print_statements(self, capsys): - print_string("Hello world and hello ONS") - captured = capsys.readouterr() - assert captured.out == "Hello world and hello ONS\n" - - def test_type_error(self): - with pytest.raises(TypeError): - print_string(1) - - -class TestPrintFavouriteNumber: - def test_string_concat(self, capsys): - print_favourite_number(7, "Bob") - captured = capsys.readouterr() - assert captured.out == "Bob's favourite number is 7!\n" - - def test_name_type_error(self): - with pytest.raises(TypeError): - print_favourite_number("7", "Bob") - - def test_company_type_error(self): - with pytest.raises(TypeError): - print_favourite_number(7, 1) - - def test_name_and_company_type_error(self): - with pytest.raises(TypeError): - print_favourite_number("1", 2) diff --git a/{{ cookiecutter.repo_name }}/{{ cookiecutter.repo_name.lower().replace(' ', '_').replace('-', '_') }}/example_config.yml b/{{ cookiecutter.repo_name }}/{{ cookiecutter.repo_name.lower().replace(' ', '_').replace('-', '_') }}/example_config.yml deleted file mode 100644 index 7acc3b8..0000000 --- a/{{ cookiecutter.repo_name }}/{{ cookiecutter.repo_name.lower().replace(' ', '_').replace('-', '_') }}/example_config.yml +++ /dev/null @@ -1,3 +0,0 @@ -user_name: "John Stat" -company: "ONS" -favourite_number: 42 diff --git a/{{ cookiecutter.repo_name }}/tests/__init__.py b/{{ cookiecutter.repo_name }}/{{ cookiecutter.repo_name.lower().replace(' ', '_').replace('-', '_') }}/example_module/__init__.py similarity index 100% rename from {{ cookiecutter.repo_name }}/tests/__init__.py rename to {{ cookiecutter.repo_name }}/{{ cookiecutter.repo_name.lower().replace(' ', '_').replace('-', '_') }}/example_module/__init__.py diff --git a/{{ cookiecutter.repo_name }}/{{ cookiecutter.repo_name.lower().replace(' ', '_').replace('-', '_') }}/example_modules/__init__.py b/{{ cookiecutter.repo_name }}/{{ cookiecutter.repo_name.lower().replace(' ', '_').replace('-', '_') }}/example_modules/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/{{ cookiecutter.repo_name }}/{{ cookiecutter.repo_name.lower().replace(' ', '_').replace('-', '_') }}/example_modules/example_module.py b/{{ cookiecutter.repo_name }}/{{ cookiecutter.repo_name.lower().replace(' ', '_').replace('-', '_') }}/example_modules/example_module.py deleted file mode 100644 index 7ec4165..0000000 --- a/{{ cookiecutter.repo_name }}/{{ cookiecutter.repo_name.lower().replace(' ', '_').replace('-', '_') }}/example_modules/example_module.py +++ /dev/null @@ -1,92 +0,0 @@ -def hello_world(name, company): - """This function returns a welcoming string given and company - and a persons name. - - Parameters - ---------- - name : str - The name you would like to say hello to - company : str - The company name to say hello to - - Returns - ------- - str - Complete string greating a person and the company - - Raises - ------ - TypeError - name is not a str - TypeError - company is not a str - TypeError - neither company or name are str variables - """ - if isinstance(name, str) and isinstance(company, str): - string = "Hello " + name + " and hello everyone at " + company - return string - - elif not isinstance(name, str): - raise TypeError("The 'name' variable entered was not a string") - - elif not isinstance(company, str): - raise TypeError("The 'company' variable entered was not a string") - - else: - raise TypeError("The 'name' and 'company' variables entered were not strings") - - -def print_string(string): - """function that prints a string after validating the input - - Parameters - ---------- - string : str - string to print ouy - - Raises - ------ - TypeError - If 'string' variable is not a str - """ - if isinstance(string, str): - print(string) - else: - raise TypeError("The 'string' variable entered was not a string") - - -def print_favourite_number(favourite_number, name): - """Function to print sentence of a name and a person favourite number - - Parameters - ---------- - favourite_number : int - Integer number to print - name : str - Person name to print - - Raises - ------ - TypeError - The name variable is not a str - TypeError - The favourite_number variable is not an int - TypeError - Both the name and favourite_number varibles are not str and int - respectively. - """ - if isinstance(name, str) and isinstance(favourite_number, int): - string = name + "'s favourite number is " + str(favourite_number) + "!" - print(string) - - elif not isinstance(name, str): - raise TypeError("The 'name' variable entered was not a string") - - elif not isinstance(favourite_number, int): - raise TypeError("The 'favourite_number' variable entered was not an integer") - - else: - raise TypeError( - "The 'name' and 'favourite_number' variables have incorrect types" - ) diff --git a/{{ cookiecutter.repo_name }}/conftest.py b/{{ cookiecutter.repo_name }}/{{ cookiecutter.repo_name.lower().replace(' ', '_').replace('-', '_') }}/main.py similarity index 100% rename from {{ cookiecutter.repo_name }}/conftest.py rename to {{ cookiecutter.repo_name }}/{{ cookiecutter.repo_name.lower().replace(' ', '_').replace('-', '_') }}/main.py diff --git a/{{ cookiecutter.repo_name }}/{{ cookiecutter.repo_name.lower().replace(' ', '_').replace('-', '_') }}/run_pipeline.py b/{{ cookiecutter.repo_name }}/{{ cookiecutter.repo_name.lower().replace(' ', '_').replace('-', '_') }}/run_pipeline.py deleted file mode 100644 index 7b86d55..0000000 --- a/{{ cookiecutter.repo_name }}/{{ cookiecutter.repo_name.lower().replace(' ', '_').replace('-', '_') }}/run_pipeline.py +++ /dev/null @@ -1,25 +0,0 @@ -import yaml - -from {{ cookiecutter.repo_name.lower().replace(' ', '_').replace('-', '_') }}.example_modules.example_module import ( - hello_world, - print_favourite_number, - print_string, -) - - -def run_pipeline(): - """This is the main function that runs the pipeline""" - with open("{{ cookiecutter.repo_name.lower().replace(' ', '_').replace('-', '_') }}/example_config.yml", "r") as file: - example_config = yaml.safe_load(file) - - name = example_config["user_name"] - company = example_config["company"] - favourite_number = example_config["favourite_number"] - - hello_string = hello_world(name, company) - print_string(hello_string) - print_favourite_number(favourite_number, name) - - -if __name__ == "__main__": - run_pipeline() From a24a43e0350e0b4bcf8f9fb08b8545ce2df2289b Mon Sep 17 00:00:00 2001 From: jday7879 <57715292+Jday7879@users.noreply.github.com> Date: Tue, 8 Jul 2025 08:19:22 +0100 Subject: [PATCH 02/14] Changes: - added change log - removed locked down question and unit tests --- cookiecutter.json | 1 - tests/test_govcookiecutter_creation.py | 9 --------- ...test_govcookiecutter_injected_variables.py | 19 +++++++------------ {{ cookiecutter.repo_name }}/CHANGELOG.md | 16 ++++++++++++++++ {{ cookiecutter.repo_name }}/setup.cfg | 12 +----------- 5 files changed, 24 insertions(+), 33 deletions(-) create mode 100644 {{ cookiecutter.repo_name }}/CHANGELOG.md diff --git a/cookiecutter.json b/cookiecutter.json index 97a739e..9faa039 100644 --- a/cookiecutter.json +++ b/cookiecutter.json @@ -7,6 +7,5 @@ "repo_name": "{{ cookiecutter.project_name.lower().replace(' ', '_').replace('-', '_') }}", "overview": "Brief overview of your project.", "project_version": "0.0.1", - "locked_down_environment": ["No", "Yes"], "using_R": ["No", "Yes"] } diff --git a/tests/test_govcookiecutter_creation.py b/tests/test_govcookiecutter_creation.py index c348b8f..4544d59 100644 --- a/tests/test_govcookiecutter_creation.py +++ b/tests/test_govcookiecutter_creation.py @@ -8,13 +8,11 @@ @pytest.mark.parametrize("test_input_repository_hosting_platform", ["GitHub", "GitLab"]) @pytest.mark.parametrize("test_input_project_name", ["A project", "Another project"]) @pytest.mark.parametrize("test_input_using_r", ["Yes", "No"]) -@pytest.mark.parametrize("test_input_locked_down_environment", ["Yes", "No"]) def test_request_template_generated_correctly( cookies, test_input_repository_hosting_platform: str, test_input_project_name: str, test_input_using_r: str, - test_input_locked_down_environment: str, ) -> None: """Test the pull or merge request templates are created correctly.""" @@ -24,7 +22,6 @@ def test_request_template_generated_correctly( "repository_hosting_platform": test_input_repository_hosting_platform, "project_name": test_input_project_name, "using_R": test_input_using_r, - "locked_down_environment": test_input_locked_down_environment, } ) @@ -57,12 +54,10 @@ def test_organisational_framework_correct() -> None: @pytest.mark.parametrize("test_input_repository_name", ["a", "b"]) @pytest.mark.parametrize("test_input_using_r", ["Yes", "No"]) -@pytest.mark.parametrize("test_input_locked_down_environment", ["Yes", "No"]) def test_repo_name_directory_correct( cookies, test_input_repository_name: str, test_input_using_r: str, - test_input_locked_down_environment: str, ) -> None: """Check the project repository is generated with the correct name.""" @@ -71,7 +66,6 @@ def test_repo_name_directory_correct( extra_context={ "repo_name": test_input_repository_name, "using_R": test_input_using_r, - "locked_down_environment": test_input_locked_down_environment, } ) @@ -111,14 +105,12 @@ def test_repo_name_directory_correct( @pytest.mark.parametrize("test_input_repository_hosting_platform", ["GitHub", "GitLab"]) @pytest.mark.parametrize("test_input_organisational_framework", ["GDS", "N/A"]) @pytest.mark.parametrize("test_input_using_r", ["No", "Yes"]) -@pytest.mark.parametrize("test_input_locked_down_environment", ["Yes", "No"]) def test_builds_correctly( cookies, test_input_context: Dict[str, str], test_input_repository_hosting_platform: str, test_input_organisational_framework: str, test_input_using_r: str, - test_input_locked_down_environment: str, ) -> None: """Test that the projects are built correctly with no errors.""" @@ -129,7 +121,6 @@ def test_builds_correctly( "repository_hosting_platform": test_input_repository_hosting_platform, "organisational_framework": test_input_organisational_framework, "using_R": test_input_using_r, - "locked_down_environment": test_input_locked_down_environment, } ) diff --git a/tests/test_govcookiecutter_injected_variables.py b/tests/test_govcookiecutter_injected_variables.py index dd1afc1..9c129bb 100644 --- a/tests/test_govcookiecutter_injected_variables.py +++ b/tests/test_govcookiecutter_injected_variables.py @@ -17,11 +17,6 @@ '[u"{{ cookiecutter.organisation_handle }}"],': 0, '"{{ cookiecutter.organisation_handle }}",': 0, } -# CONTACT_EMAIL_COUNT = { -# "mailto:{{ cookiecutter.contact_email }}": 2, -# "[{{ cookiecutter.contact_email }}][email-address].": 1, -# '"{{ cookiecutter.contact_email }}")': 0, -# } PROJECT_NAME_COUNT = { '"{{ cookiecutter.project_name }}"': 1, '"{{ cookiecutter.project_name }}",': 0, @@ -41,8 +36,8 @@ "{{ cookiecutter.overview }}": 2, } PROJECT_VERSION_COUNT = { - '"{{ cookiecutter.project_version }}"': 2, - "{{ cookiecutter.project_version }}": 1, + '"{{ cookiecutter.project_version }}"': 1, + "{{ cookiecutter.project_version }}": 2, } USING_R_NO_COUNT = { "https://github.com/lorenzwalthert/precommit": 0, @@ -52,7 +47,7 @@ "`startup.R`": 0, } USING_R_YES_COUNT = { - "https://github.com/lorenzwalthert/precommit": 2, + "https://github.com/lorenzwalthert/precommit": 0, "`.lintr`": 0, "`.Rprofile`": 0, "`DESCRIPTION`": 0, @@ -158,28 +153,28 @@ def recursive_open_and_count_search_terms( ( "project_name", "Project_2", - {**PROJECT_NAME_COUNT, "{{ cookiecutter.project_name }}": 3}, + {**PROJECT_NAME_COUNT, "{{ cookiecutter.project_name }}": 2}, {"using_R": "Yes"}, ), ("repo_name", "repo_1", REPO_NAME_COUNT, {"using_R": "No"}), ( "repo_name", "repo_2", - {**REPO_NAME_COUNT, "{{ cookiecutter.repo_name }}": 3}, + {**REPO_NAME_COUNT, "{{ cookiecutter.repo_name }}": 2}, {"using_R": "Yes"}, ), ("overview", "overview_1", OVERVIEW_COUNT, {"using_R": "No"}), ( "overview", "overview_1", - {**OVERVIEW_COUNT, "{{ cookiecutter.overview }}": 3}, + {**OVERVIEW_COUNT, "{{ cookiecutter.overview }}": 2}, {"using_R": "Yes"}, ), ("project_version", "project_version_1", PROJECT_VERSION_COUNT, {"using_R": "No"}), ( "project_version", "project_version_2", - {**PROJECT_VERSION_COUNT, "{{ cookiecutter.project_version }}": 2}, + {**PROJECT_VERSION_COUNT, "{{ cookiecutter.project_version }}": 1}, {"using_R": "Yes"}, ), ("using_R", "No", USING_R_NO_COUNT, {}), diff --git a/{{ cookiecutter.repo_name }}/CHANGELOG.md b/{{ cookiecutter.repo_name }}/CHANGELOG.md new file mode 100644 index 0000000..5994cb6 --- /dev/null +++ b/{{ cookiecutter.repo_name }}/CHANGELOG.md @@ -0,0 +1,16 @@ +# Changelog + +All notable changes to this project will be documented in this file, grouped by Added, Fixed, Changed, and Removed. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## [Unreleased] - + +### Added + +### Fixed + +### Changed + +### Removed \ No newline at end of file diff --git a/{{ cookiecutter.repo_name }}/setup.cfg b/{{ cookiecutter.repo_name }}/setup.cfg index 22a8a56..c79d518 100644 --- a/{{ cookiecutter.repo_name }}/setup.cfg +++ b/{{ cookiecutter.repo_name }}/setup.cfg @@ -21,18 +21,8 @@ install_requires = [options.extras_require] dev = coverage - detect-secrets == 1.0.3 myst-parser - pre-commit pytest - detect-secrets python-dotenv Sphinx - toml {% if cookiecutter.locked_down_environment == "Yes" %} - pre-commit-hooks - nbstripout - isort - black - flake8 - nbqa - bandit {% endif -%} + toml From 9f812008b53ba7056441a2e747ae702b104f7780 Mon Sep 17 00:00:00 2001 From: jday7879 <57715292+Jday7879@users.noreply.github.com> Date: Tue, 8 Jul 2025 08:50:06 +0100 Subject: [PATCH 03/14] Removed: - locked down question and tests - with or without R question and tests --- cookiecutter.json | 3 +- .../modify_govcookiecutter.md | 8 --- hooks/post_gen_project.py | 6 +- tests/test_govcookiecutter_creation.py | 9 --- ...test_govcookiecutter_injected_variables.py | 60 +++++-------------- .../.govcookiecutter/manifest.json | 10 ---- {{ cookiecutter.repo_name }}/README.md | 20 ------- 7 files changed, 19 insertions(+), 97 deletions(-) delete mode 100644 {{ cookiecutter.repo_name }}/.govcookiecutter/manifest.json diff --git a/cookiecutter.json b/cookiecutter.json index 9faa039..0f77a8d 100644 --- a/cookiecutter.json +++ b/cookiecutter.json @@ -6,6 +6,5 @@ "project_name": "Your new project name", "repo_name": "{{ cookiecutter.project_name.lower().replace(' ', '_').replace('-', '_') }}", "overview": "Brief overview of your project.", - "project_version": "0.0.1", - "using_R": ["No", "Yes"] + "project_version": "0.0.1" } diff --git a/docs/contributing_guide/modify_govcookiecutter.md b/docs/contributing_guide/modify_govcookiecutter.md index 9077a71..f2f3c56 100644 --- a/docs/contributing_guide/modify_govcookiecutter.md +++ b/docs/contributing_guide/modify_govcookiecutter.md @@ -118,14 +118,6 @@ For example, for the following Markdown: The contributing guidelines for this project. -{% if cookiecutter.using_R == "Yes" -%} -### `DESCRIPTION` - -R-specific information related to the project including the name, authors and packages -necessary for the project. - -{% endif -%} - ### `LICENSE` The licence for this project... diff --git a/hooks/post_gen_project.py b/hooks/post_gen_project.py index ed7f3c9..939321f 100644 --- a/hooks/post_gen_project.py +++ b/hooks/post_gen_project.py @@ -160,9 +160,9 @@ def parse_features_json(file: Union[Path, str]) -> List[Path]: ) # Delete files defined in the `manifest.json` file - delete_files_and_folders( - parse_features_json(Path(".govcookiecutter", "manifest.json")) - ) + # delete_files_and_folders( + # parse_features_json(Path(".govcookiecutter", "manifest.json")) + # ) # Remove `DIR_GOVCOOKIECUTTER` delete_files_and_folders(DIR_GOVCOOKIECUTTER) diff --git a/tests/test_govcookiecutter_creation.py b/tests/test_govcookiecutter_creation.py index 4544d59..62ff179 100644 --- a/tests/test_govcookiecutter_creation.py +++ b/tests/test_govcookiecutter_creation.py @@ -7,12 +7,10 @@ @pytest.mark.parametrize("test_input_repository_hosting_platform", ["GitHub", "GitLab"]) @pytest.mark.parametrize("test_input_project_name", ["A project", "Another project"]) -@pytest.mark.parametrize("test_input_using_r", ["Yes", "No"]) def test_request_template_generated_correctly( cookies, test_input_repository_hosting_platform: str, test_input_project_name: str, - test_input_using_r: str, ) -> None: """Test the pull or merge request templates are created correctly.""" @@ -21,7 +19,6 @@ def test_request_template_generated_correctly( extra_context={ "repository_hosting_platform": test_input_repository_hosting_platform, "project_name": test_input_project_name, - "using_R": test_input_using_r, } ) @@ -53,11 +50,9 @@ def test_organisational_framework_correct() -> None: @pytest.mark.parametrize("test_input_repository_name", ["a", "b"]) -@pytest.mark.parametrize("test_input_using_r", ["Yes", "No"]) def test_repo_name_directory_correct( cookies, test_input_repository_name: str, - test_input_using_r: str, ) -> None: """Check the project repository is generated with the correct name.""" @@ -65,7 +60,6 @@ def test_repo_name_directory_correct( test_output_project = cookies.bake( extra_context={ "repo_name": test_input_repository_name, - "using_R": test_input_using_r, } ) @@ -104,13 +98,11 @@ def test_repo_name_directory_correct( @pytest.mark.parametrize("test_input_context", args_builds_correctly) @pytest.mark.parametrize("test_input_repository_hosting_platform", ["GitHub", "GitLab"]) @pytest.mark.parametrize("test_input_organisational_framework", ["GDS", "N/A"]) -@pytest.mark.parametrize("test_input_using_r", ["No", "Yes"]) def test_builds_correctly( cookies, test_input_context: Dict[str, str], test_input_repository_hosting_platform: str, test_input_organisational_framework: str, - test_input_using_r: str, ) -> None: """Test that the projects are built correctly with no errors.""" @@ -120,7 +112,6 @@ def test_builds_correctly( **test_input_context, "repository_hosting_platform": test_input_repository_hosting_platform, "organisational_framework": test_input_organisational_framework, - "using_R": test_input_using_r, } ) diff --git a/tests/test_govcookiecutter_injected_variables.py b/tests/test_govcookiecutter_injected_variables.py index 9c129bb..cae0650 100644 --- a/tests/test_govcookiecutter_injected_variables.py +++ b/tests/test_govcookiecutter_injected_variables.py @@ -39,20 +39,6 @@ '"{{ cookiecutter.project_version }}"': 1, "{{ cookiecutter.project_version }}": 2, } -USING_R_NO_COUNT = { - "https://github.com/lorenzwalthert/precommit": 0, - "`.lintr`": 0, - "`.Rprofile`": 0, - "`DESCRIPTION`": 0, - "`startup.R`": 0, -} -USING_R_YES_COUNT = { - "https://github.com/lorenzwalthert/precommit": 0, - "`.lintr`": 0, - "`.Rprofile`": 0, - "`DESCRIPTION`": 0, - "`startup.R`": 0, -} def replace_cookiecutter_jinja2_counts( @@ -133,67 +119,52 @@ def recursive_open_and_count_search_terms( # Define the test cases for the `test_injected_counts_correct` test args_injected_counts_correct = [ - ("organisation_name", "org_1", ORGANISATION_NAME_COUNT, {"using_R": "No"}), - ("organisation_name", "org_2", ORGANISATION_NAME_COUNT, {"using_R": "Yes"}), - ("organisation_handle", "handle_1", ORGANISATION_HANDLE_COUNT, {"using_R": "No"}), + ("organisation_name", "org_1", ORGANISATION_NAME_COUNT), + ("organisation_name", "org_2", ORGANISATION_NAME_COUNT), + ("organisation_handle", "handle_1", ORGANISATION_HANDLE_COUNT), ( "organisation_handle", "handle_2", - {**ORGANISATION_HANDLE_COUNT, '"{{ cookiecutter.organisation_handle }}",': 0}, - {"using_R": "Yes"}, + {**ORGANISATION_HANDLE_COUNT, '"{{ cookiecutter.organisation_handle }}",': 0} ), - # ("contact_email", "email@1", CONTACT_EMAIL_COUNT, {"using_R": "No"}), - # ( - # "contact_email", - # "email@2", - # {**CONTACT_EMAIL_COUNT, '"{{ cookiecutter.contact_email }}")': 0}, - # {"using_R": "Yes"}, - # ), - ("project_name", "Project_1", PROJECT_NAME_COUNT, {"using_R": "No"}), + ("project_name", "Project_1", PROJECT_NAME_COUNT), ( "project_name", "Project_2", - {**PROJECT_NAME_COUNT, "{{ cookiecutter.project_name }}": 2}, - {"using_R": "Yes"}, + {**PROJECT_NAME_COUNT, "{{ cookiecutter.project_name }}": 2} ), - ("repo_name", "repo_1", REPO_NAME_COUNT, {"using_R": "No"}), + ("repo_name", "repo_1", REPO_NAME_COUNT), ( "repo_name", "repo_2", - {**REPO_NAME_COUNT, "{{ cookiecutter.repo_name }}": 2}, - {"using_R": "Yes"}, + {**REPO_NAME_COUNT, "{{ cookiecutter.repo_name }}": 2} ), - ("overview", "overview_1", OVERVIEW_COUNT, {"using_R": "No"}), + ("overview", "overview_1", OVERVIEW_COUNT), ( "overview", "overview_1", - {**OVERVIEW_COUNT, "{{ cookiecutter.overview }}": 2}, - {"using_R": "Yes"}, + {**OVERVIEW_COUNT, "{{ cookiecutter.overview }}": 2} ), - ("project_version", "project_version_1", PROJECT_VERSION_COUNT, {"using_R": "No"}), + ("project_version", "project_version_1", PROJECT_VERSION_COUNT), ( "project_version", "project_version_2", - {**PROJECT_VERSION_COUNT, "{{ cookiecutter.project_version }}": 1}, - {"using_R": "Yes"}, + {**PROJECT_VERSION_COUNT, "{{ cookiecutter.project_version }}": 1} ), - ("using_R", "No", USING_R_NO_COUNT, {}), - ("using_R", "Yes", USING_R_YES_COUNT, {}), ] @pytest.mark.parametrize( "test_input_variable, test_input_value, " - "test_input_variable_counts, test_input_other_context", + "test_input_variable_counts", args_injected_counts_correct, ) def test_injected_counts_correct( cookies, test_input_variable: str, test_input_value: str, - test_input_variable_counts: Dict[str, int], - test_input_other_context: Dict[str, str], -) -> None: + test_input_variable_counts: Dict[str, int] + ) -> None: # Generate the expected counts test_expected_counts = replace_cookiecutter_jinja2_counts( @@ -206,7 +177,6 @@ def test_injected_counts_correct( test_output_project = cookies.bake( extra_context={ test_input_variable: test_input_value, - **test_input_other_context, } ) diff --git a/{{ cookiecutter.repo_name }}/.govcookiecutter/manifest.json b/{{ cookiecutter.repo_name }}/.govcookiecutter/manifest.json deleted file mode 100644 index 33a087c..0000000 --- a/{{ cookiecutter.repo_name }}/.govcookiecutter/manifest.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "features": [ - { - "name": "R files", - "description": "R files that are removed if not enabled.", - "remove": {% if cookiecutter.using_R == "No" %}true{% else %}false{% endif %}, - "resources": [".Rprofile", ".lintr", "DESCRIPTION", "startup.R"] - } - ] -} diff --git a/{{ cookiecutter.repo_name }}/README.md b/{{ cookiecutter.repo_name }}/README.md index 015b0da..2fdaffc 100644 --- a/{{ cookiecutter.repo_name }}/README.md +++ b/{{ cookiecutter.repo_name }}/README.md @@ -21,9 +21,6 @@ a virtual environment. ## Requirements - Python 3.9+ installed -{% if cookiecutter.using_R == "Yes" -%} -- R 4.2.3+ installed -{% endif -%} - a `.secrets` file with the required [secrets and credentials](#required-secrets-and-credentials) - to have [loaded environment variables][docs-loading-environment-variables] from `.env` @@ -39,14 +36,6 @@ python -m pip install -U pip setuptools pip install -e . ``` -{% if cookiecutter.using_R == "Yes" -%} -While in the root folder in an R console, such as that in Rstudio, -install the R components with: -```R -install.packages(".") -``` -{% endif -%} - ### Install for contributors (Python only) To install the contributing requirements, use: @@ -60,15 +49,6 @@ This installs an editable version of the package. This means that when you updat package code you do not have to reinstall it for the changes to take effect. This saves a lot of time when you test your code. -{% if cookiecutter.using_R == "Yes" -%} -While in the root folder in an R console, such as that in Rstudio, load the package -using `devtools`: -```R -#install.packages("devtools") -devtools::load_all() -``` -{% endif -%} - Remember to update the setup and requirement files inline with any changes to your package. From b470ffc965e1ddb7cf6d85df5875b87102cb81b6 Mon Sep 17 00:00:00 2001 From: jday7879 <57715292+Jday7879@users.noreply.github.com> Date: Tue, 8 Jul 2025 09:55:06 +0100 Subject: [PATCH 04/14] remove .lintr file --- {{ cookiecutter.repo_name }}/.lintr | 4 ---- 1 file changed, 4 deletions(-) delete mode 100644 {{ cookiecutter.repo_name }}/.lintr diff --git a/{{ cookiecutter.repo_name }}/.lintr b/{{ cookiecutter.repo_name }}/.lintr deleted file mode 100644 index 86fcfe6..0000000 --- a/{{ cookiecutter.repo_name }}/.lintr +++ /dev/null @@ -1,4 +0,0 @@ -linters: linters_with_defaults( - line_length_linter = line_length_linter(120), - commented_code_linter = NULL - ) From 98ff63718f97342afd5fc105cff67436fa548f73 Mon Sep 17 00:00:00 2001 From: jday7879 <57715292+Jday7879@users.noreply.github.com> Date: Tue, 8 Jul 2025 11:01:27 +0100 Subject: [PATCH 05/14] add hook to check repo_name length --- hooks/__init__.py | 4 +++- hooks/pre_gen_project.py | 15 +++++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) create mode 100644 hooks/pre_gen_project.py diff --git a/hooks/__init__.py b/hooks/__init__.py index 06bc4bd..0d3c3ea 100644 --- a/hooks/__init__.py +++ b/hooks/__init__.py @@ -4,10 +4,12 @@ set_aqa_framework, set_request_template, ) +from hooks.pre_gen_project import check_repo_name_structure __all__ = ( "delete_files_and_folders", + "check_repo_name_structure", "parse_features_json", "set_aqa_framework", - "set_request_template", + "set_request_template", ) diff --git a/hooks/pre_gen_project.py b/hooks/pre_gen_project.py new file mode 100644 index 0000000..a7a79c9 --- /dev/null +++ b/hooks/pre_gen_project.py @@ -0,0 +1,15 @@ + +def check_repo_name_structure(repo_name: str) -> None: + """Check if the repository name follows the correct structure. + + Args: + repo_name: The name of the repository to check. + + Raises: + ValueError: If the repository name does not follow the correct structure. + """ + if len(repo_name) > 2: + raise ValueError( + "Repository name must not exceed 88 characters." + ) + From e3447f30187d6fc2039db0001651af0014446653 Mon Sep 17 00:00:00 2001 From: jday7879 <57715292+Jday7879@users.noreply.github.com> Date: Tue, 8 Jul 2025 13:17:22 +0100 Subject: [PATCH 06/14] add check for length of repo name, change package to use dash not underscore --- hooks/pre_gen_project.py | 12 ++++++++++-- {{ cookiecutter.repo_name }}/setup.cfg | 2 +- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/hooks/pre_gen_project.py b/hooks/pre_gen_project.py index a7a79c9..d635e41 100644 --- a/hooks/pre_gen_project.py +++ b/hooks/pre_gen_project.py @@ -8,8 +8,16 @@ def check_repo_name_structure(repo_name: str) -> None: Raises: ValueError: If the repository name does not follow the correct structure. """ - if len(repo_name) > 2: + print("checking repo name length",repo_name) + + if len(repo_name) > 88: + print("checking repo name length") raise ValueError( - "Repository name must not exceed 88 characters." + "Repository name must not exceed 100 characters." ) + +if __name__ == "__main__": + + # Check the format of the contact email address supplied is a valid one + check_repo_name_structure("{{ cookiecutter.repo_name }}") \ No newline at end of file diff --git a/{{ cookiecutter.repo_name }}/setup.cfg b/{{ cookiecutter.repo_name }}/setup.cfg index c79d518..00d5fbf 100644 --- a/{{ cookiecutter.repo_name }}/setup.cfg +++ b/{{ cookiecutter.repo_name }}/setup.cfg @@ -1,5 +1,5 @@ [metadata] -name = {{ cookiecutter.repo_name }} +name = {{ cookiecutter.repo_name.lower().replace(" ","-").replace("_","-") }} description = {{ cookiecutter.overview }} version = {{ cookiecutter.project_version }} author = {{ cookiecutter.organisation_handle }} From 9f4728ba09d3e0afd6d5de7e82cfb686d90b65b9 Mon Sep 17 00:00:00 2001 From: jday7879 <57715292+Jday7879@users.noreply.github.com> Date: Tue, 8 Jul 2025 14:27:52 +0100 Subject: [PATCH 07/14] create pytoml, remove setup files --- {{ cookiecutter.repo_name }}/pyproject.toml | 33 +++++++++++++++++++++ {{ cookiecutter.repo_name }}/setup.cfg | 28 ----------------- {{ cookiecutter.repo_name }}/setup.py | 4 --- 3 files changed, 33 insertions(+), 32 deletions(-) create mode 100644 {{ cookiecutter.repo_name }}/pyproject.toml delete mode 100644 {{ cookiecutter.repo_name }}/setup.cfg delete mode 100644 {{ cookiecutter.repo_name }}/setup.py diff --git a/{{ cookiecutter.repo_name }}/pyproject.toml b/{{ cookiecutter.repo_name }}/pyproject.toml new file mode 100644 index 0000000..3382f3f --- /dev/null +++ b/{{ cookiecutter.repo_name }}/pyproject.toml @@ -0,0 +1,33 @@ +[project] +name = "{{ cookiecutter.repo_name.lower().replace(' ', '-').replace('_', '-') }}" +description = "{{ cookiecutter.overview }}" +version = "{{ cookiecutter.project_version }}" +authors = [ + {"name" = "{{ cookiecutter.organisation_handle }}"} +] +requires-python = ">=3.9" +classifiers = [ + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12" +] +dependencies = [ + "pyyaml" +] + +[project.optional-dependencies] +dev = [ + "coverage", + "myst-parser", + "pytest", + "python-dotenv", + "Sphinx", + "toml" +] + +[tool.setuptools] +zip-safe = false + +[tool.setuptools.packages.find] +include = ["{{ cookiecutter.repo_name.lower().replace(' ', '_').replace('-', '_') }}"] diff --git a/{{ cookiecutter.repo_name }}/setup.cfg b/{{ cookiecutter.repo_name }}/setup.cfg deleted file mode 100644 index 00d5fbf..0000000 --- a/{{ cookiecutter.repo_name }}/setup.cfg +++ /dev/null @@ -1,28 +0,0 @@ -[metadata] -name = {{ cookiecutter.repo_name.lower().replace(" ","-").replace("_","-") }} -description = {{ cookiecutter.overview }} -version = {{ cookiecutter.project_version }} -author = {{ cookiecutter.organisation_handle }} -platforms = win32 -classifiers = - Programming Language :: Python :: 3.9 - Programming Language :: Python :: 3.10 - Programming Language :: Python :: 3.11 - Programming Language :: Python :: 3.12 - -[options] -packages = - {{ cookiecutter.repo_name.lower().replace(' ', '_').replace('-', '_') }} -python_requires = >=3.9 -zip_safe = no -install_requires = - pyyaml - -[options.extras_require] -dev = - coverage - myst-parser - pytest - python-dotenv - Sphinx - toml diff --git a/{{ cookiecutter.repo_name }}/setup.py b/{{ cookiecutter.repo_name }}/setup.py deleted file mode 100644 index 7f1a176..0000000 --- a/{{ cookiecutter.repo_name }}/setup.py +++ /dev/null @@ -1,4 +0,0 @@ -from setuptools import setup - -if __name__ == "__main__": - setup() From 13c9474f4e4f563a701a1ccc94fc022b26405114 Mon Sep 17 00:00:00 2001 From: jday7879 <57715292+Jday7879@users.noreply.github.com> Date: Tue, 8 Jul 2025 14:28:11 +0100 Subject: [PATCH 08/14] auto find modules --- {{ cookiecutter.repo_name }}/pyproject.toml | 2 -- 1 file changed, 2 deletions(-) diff --git a/{{ cookiecutter.repo_name }}/pyproject.toml b/{{ cookiecutter.repo_name }}/pyproject.toml index 3382f3f..a464521 100644 --- a/{{ cookiecutter.repo_name }}/pyproject.toml +++ b/{{ cookiecutter.repo_name }}/pyproject.toml @@ -29,5 +29,3 @@ dev = [ [tool.setuptools] zip-safe = false -[tool.setuptools.packages.find] -include = ["{{ cookiecutter.repo_name.lower().replace(' ', '_').replace('-', '_') }}"] From 9c2d3f191b44c3d0d3047aacc261402c5d23085d Mon Sep 17 00:00:00 2001 From: jday7879 <57715292+Jday7879@users.noreply.github.com> Date: Wed, 9 Jul 2025 11:46:18 +0100 Subject: [PATCH 09/14] hooks and clear changelog --- CHANGELOG.md | 66 ------------------- hooks/__init__.py | 2 +- hooks/pre_gen_project.py | 9 +-- ...test_govcookiecutter_injected_variables.py | 25 +++---- {{ cookiecutter.repo_name }}/CHANGELOG.md | 2 +- {{ cookiecutter.repo_name }}/pyproject.toml | 1 - 6 files changed, 13 insertions(+), 92 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 02d8d86..17880fb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,69 +14,3 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed ### Removed - -## [2.1.0] - 2nd June 2025 - -### Added - -- Example test and module -- Example pipeline -- Version to config -- Dev dependencies to config -- New requirements: `bandit` and `jinja2-time` -- `bandit` to user pre-commit hooks -- Including common Excel file times in the default .gitignore -- `bandit` to dev pre-commit hooks -- R install guidance to template README -- Setup question for locked down environments, uses local installed packages for commit hooks - -### Fixed - -- Broken links - -### Changed - -- Updated instructions on running the tests -- Updated imports -- Exclude certain files from pre-commit hooks -- Updated README to use `python -m` -- Minor contributing guidance changes -- Updated Python versions to 3.9-3.12 -- Updated Python versions in workflows to 3.9-3.12 -- Updated dev pre-commit hook versions via `pre-commit autoupdate` -- Template code of conduct updated -- Template contributing guidance updated -- Updated README -- Updated documentation website for `govcookiecutter` and created repo structures - -### Removed - -- Example data folder -- Removed the Email Address prompts from the installation. - -## [2.0.0] - 6th March 2023 - -### Added - -- Workflow to check external links on pull request - -### Fixed - -- Broken links - -### Changed - -- Updated folder structure -- Relative links have been replaced with complete paths -- Workflow actions now use later versions -- Updated CRAN link being installed from in startup.R -- Updates to the Contributing Guidance - -### Removed - -- Workflow support for Python 3.6 - - -[unreleased]: https://github.com/best-practice-and-impact/govcookiecutter -[2.1.0]: https://github.com/best-practice-and-impact/govcookiecutter/tree/2.1.0 -[2.0.0]: https://github.com/best-practice-and-impact/govcookiecutter/tree/2.0.0 diff --git a/hooks/__init__.py b/hooks/__init__.py index 0d3c3ea..1dadecc 100644 --- a/hooks/__init__.py +++ b/hooks/__init__.py @@ -11,5 +11,5 @@ "check_repo_name_structure", "parse_features_json", "set_aqa_framework", - "set_request_template", + "set_request_template", ) diff --git a/hooks/pre_gen_project.py b/hooks/pre_gen_project.py index d635e41..6fca095 100644 --- a/hooks/pre_gen_project.py +++ b/hooks/pre_gen_project.py @@ -1,4 +1,3 @@ - def check_repo_name_structure(repo_name: str) -> None: """Check if the repository name follows the correct structure. @@ -8,16 +7,14 @@ def check_repo_name_structure(repo_name: str) -> None: Raises: ValueError: If the repository name does not follow the correct structure. """ - print("checking repo name length",repo_name) + print("checking repo name length", repo_name) if len(repo_name) > 88: print("checking repo name length") - raise ValueError( - "Repository name must not exceed 100 characters." - ) + raise ValueError("Repository name must not exceed 100 characters.") if __name__ == "__main__": # Check the format of the contact email address supplied is a valid one - check_repo_name_structure("{{ cookiecutter.repo_name }}") \ No newline at end of file + check_repo_name_structure("{{ cookiecutter.repo_name }}") diff --git a/tests/test_govcookiecutter_injected_variables.py b/tests/test_govcookiecutter_injected_variables.py index cae0650..7debfd5 100644 --- a/tests/test_govcookiecutter_injected_variables.py +++ b/tests/test_govcookiecutter_injected_variables.py @@ -125,46 +125,37 @@ def recursive_open_and_count_search_terms( ( "organisation_handle", "handle_2", - {**ORGANISATION_HANDLE_COUNT, '"{{ cookiecutter.organisation_handle }}",': 0} + {**ORGANISATION_HANDLE_COUNT, '"{{ cookiecutter.organisation_handle }}",': 0}, ), ("project_name", "Project_1", PROJECT_NAME_COUNT), ( "project_name", "Project_2", - {**PROJECT_NAME_COUNT, "{{ cookiecutter.project_name }}": 2} + {**PROJECT_NAME_COUNT, "{{ cookiecutter.project_name }}": 2}, ), ("repo_name", "repo_1", REPO_NAME_COUNT), - ( - "repo_name", - "repo_2", - {**REPO_NAME_COUNT, "{{ cookiecutter.repo_name }}": 2} - ), + ("repo_name", "repo_2", {**REPO_NAME_COUNT, "{{ cookiecutter.repo_name }}": 2}), ("overview", "overview_1", OVERVIEW_COUNT), - ( - "overview", - "overview_1", - {**OVERVIEW_COUNT, "{{ cookiecutter.overview }}": 2} - ), + ("overview", "overview_1", {**OVERVIEW_COUNT, "{{ cookiecutter.overview }}": 2}), ("project_version", "project_version_1", PROJECT_VERSION_COUNT), ( "project_version", "project_version_2", - {**PROJECT_VERSION_COUNT, "{{ cookiecutter.project_version }}": 1} + {**PROJECT_VERSION_COUNT, "{{ cookiecutter.project_version }}": 1}, ), ] @pytest.mark.parametrize( - "test_input_variable, test_input_value, " - "test_input_variable_counts", + "test_input_variable, test_input_value, " "test_input_variable_counts", args_injected_counts_correct, ) def test_injected_counts_correct( cookies, test_input_variable: str, test_input_value: str, - test_input_variable_counts: Dict[str, int] - ) -> None: + test_input_variable_counts: Dict[str, int], +) -> None: # Generate the expected counts test_expected_counts = replace_cookiecutter_jinja2_counts( diff --git a/{{ cookiecutter.repo_name }}/CHANGELOG.md b/{{ cookiecutter.repo_name }}/CHANGELOG.md index 5994cb6..17880fb 100644 --- a/{{ cookiecutter.repo_name }}/CHANGELOG.md +++ b/{{ cookiecutter.repo_name }}/CHANGELOG.md @@ -13,4 +13,4 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed -### Removed \ No newline at end of file +### Removed diff --git a/{{ cookiecutter.repo_name }}/pyproject.toml b/{{ cookiecutter.repo_name }}/pyproject.toml index a464521..83ea6da 100644 --- a/{{ cookiecutter.repo_name }}/pyproject.toml +++ b/{{ cookiecutter.repo_name }}/pyproject.toml @@ -28,4 +28,3 @@ dev = [ [tool.setuptools] zip-safe = false - From 78a1c87c15a7fb34f085e3a6b2086296c0e0ec22 Mon Sep 17 00:00:00 2001 From: Jday7879 <57715292+Jday7879@users.noreply.github.com> Date: Fri, 11 Jul 2025 12:42:52 +0100 Subject: [PATCH 10/14] 8 version setup (#14) * Remove project version question * Update readme to point towards lite * commit hook changes * update changelog --- CHANGELOG.md | 4 ++++ README.md | 19 +++++++++++-------- cookiecutter.json | 3 +-- ...test_govcookiecutter_injected_variables.py | 10 ---------- {{ cookiecutter.repo_name }}/docs/conf.py | 4 ++-- {{ cookiecutter.repo_name }}/pyproject.toml | 2 +- 6 files changed, 19 insertions(+), 23 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 17880fb..22e603d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,5 +12,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Fixed ### Changed +- point readme towards govcookiecutter-lite, added section on original govcookiecutter ### Removed +- Project version from setup, default is 0.0.1 +- locked down setup question, not needed as commit hooks have been removed +- removed all R files, not included in lite version diff --git a/README.md b/README.md index 0fb5977..d187ab9 100644 --- a/README.md +++ b/README.md @@ -1,21 +1,23 @@ # `govcookiecutter` -## What is govcookiecutter? +## What is govcookiecutter-lite? -A cookiecutter template for analytical, Python-, or Python and R-based projects within +A lightweight cookiecutter template for analytical Python-based projects within His Majesty's Government, and wider public sector. ## How is the template used? -This template helps to set up standardised project structures, and [includes security -features using pre-commit hooks][docs-pre-commit]. This cookiecutter template also acts +This template helps to set up standardised project structures. This cookiecutter template also acts as an installable template (python projects only). It also provides an Agile, centralised, and lightweight analytical quality assurance -(AQA) process. Pull or merge request templates are used to nudge users to complete this -process. [This helps meet HM Government best practice on producing quality analysis, as +(AQA) process. [This helps meet HM Government best practice on producing quality analysis, as defined in the Aqua Book][aqua-book]. +govcookiecutter-lite was developed from the original [govcookiecutter][govcookiecutter] but has +minimised the project creation to include only the minimum files and structure to quickly setup +python packages. + [For reasons why we developed `govcookiecutter`, read the blog post][blog-post], and [watch the live demonstration from March 2021 on version 0.5.3][youtube]. @@ -85,13 +87,13 @@ Next, open your terminal, navigate to the directory where you want your new repository to exist. Then run the following command for the latest stable release: ```shell -python -m cookiecutter https://github.com/best-practice-and-impact/govcookiecutter.git +python -m cookiecutter https://github.com/best-practice-and-impact/govcookiecutter-lite.git ``` or for a specific branch, tag, or commit SHA `{SPECIFIC}`, run: ```shell -python -m cookiecutter https://github.com/best-practice-and-impact/govcookiecutter.git --checkout {SPECIFIC} +python -m cookiecutter https://github.com/best-practice-and-impact/govcookiecutter-lite.git --checkout {SPECIFIC} ``` Follow the prompts; if you are asked to re-download `govcookiecutter`, input `yes`. @@ -168,6 +170,7 @@ project][drivendata]. Specifically, it uses a modified version of the `help` com [cruft]: https://github.com/cruft/cruft [docs-pre-commit]: ./CONTRIBUTING.md#getting-started [drivendata]: http://drivendata.github.io/cookiecutter-data-science/ +[govcookiecutter]: https://github.com/best-practice-and-impact/govcookiecutter.git [homebrew]: https://brew.sh/ [issue-windows-os]: https://github.com/best-practice-and-impact/govcookiecutter/issues/20 [pluralsight]: https://www.pluralsight.com/tech-blog/managing-python-environments/ diff --git a/cookiecutter.json b/cookiecutter.json index 0f77a8d..2dfdf4f 100644 --- a/cookiecutter.json +++ b/cookiecutter.json @@ -5,6 +5,5 @@ "organisational_framework": ["GDS", "N/A"], "project_name": "Your new project name", "repo_name": "{{ cookiecutter.project_name.lower().replace(' ', '_').replace('-', '_') }}", - "overview": "Brief overview of your project.", - "project_version": "0.0.1" + "overview": "Brief overview of your project." } diff --git a/tests/test_govcookiecutter_injected_variables.py b/tests/test_govcookiecutter_injected_variables.py index 7debfd5..234425b 100644 --- a/tests/test_govcookiecutter_injected_variables.py +++ b/tests/test_govcookiecutter_injected_variables.py @@ -35,10 +35,6 @@ '"{{ cookiecutter.overview }}",': 0, "{{ cookiecutter.overview }}": 2, } -PROJECT_VERSION_COUNT = { - '"{{ cookiecutter.project_version }}"': 1, - "{{ cookiecutter.project_version }}": 2, -} def replace_cookiecutter_jinja2_counts( @@ -137,12 +133,6 @@ def recursive_open_and_count_search_terms( ("repo_name", "repo_2", {**REPO_NAME_COUNT, "{{ cookiecutter.repo_name }}": 2}), ("overview", "overview_1", OVERVIEW_COUNT), ("overview", "overview_1", {**OVERVIEW_COUNT, "{{ cookiecutter.overview }}": 2}), - ("project_version", "project_version_1", PROJECT_VERSION_COUNT), - ( - "project_version", - "project_version_2", - {**PROJECT_VERSION_COUNT, "{{ cookiecutter.project_version }}": 1}, - ), ] diff --git a/{{ cookiecutter.repo_name }}/docs/conf.py b/{{ cookiecutter.repo_name }}/docs/conf.py index e7d3fdf..6e0fd05 100644 --- a/{{ cookiecutter.repo_name }}/docs/conf.py +++ b/{{ cookiecutter.repo_name }}/docs/conf.py @@ -55,9 +55,9 @@ # |version| and |release|, also used in # various other places throughout the built documents. # The short X.Y.Z version. -version = "{{ cookiecutter.project_version }}" +version = "0.0.1" # The full version, including alpha/beta/rc tags. -release = "{{ cookiecutter.project_version }}" +release = "0.0.1" # List of patterns, relative to source directory, # that match files and directories to diff --git a/{{ cookiecutter.repo_name }}/pyproject.toml b/{{ cookiecutter.repo_name }}/pyproject.toml index 83ea6da..a8f5b95 100644 --- a/{{ cookiecutter.repo_name }}/pyproject.toml +++ b/{{ cookiecutter.repo_name }}/pyproject.toml @@ -1,7 +1,7 @@ [project] name = "{{ cookiecutter.repo_name.lower().replace(' ', '-').replace('_', '-') }}" description = "{{ cookiecutter.overview }}" -version = "{{ cookiecutter.project_version }}" +version = "0.0.1" authors = [ {"name" = "{{ cookiecutter.organisation_handle }}"} ] From 39a991607bed0561869650799880c70fd136e3ab Mon Sep 17 00:00:00 2001 From: Jday7879 <57715292+Jday7879@users.noreply.github.com> Date: Mon, 14 Jul 2025 15:39:05 +0100 Subject: [PATCH 11/14] removed overview setup question (#16) --- CHANGELOG.md | 1 + cookiecutter.json | 3 +-- tests/test_govcookiecutter_creation.py | 2 -- tests/test_govcookiecutter_injected_variables.py | 7 +------ {{ cookiecutter.repo_name }}/README.md | 2 +- {{ cookiecutter.repo_name }}/pyproject.toml | 2 +- 6 files changed, 5 insertions(+), 12 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 22e603d..bc15868 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,3 +18,4 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Project version from setup, default is 0.0.1 - locked down setup question, not needed as commit hooks have been removed - removed all R files, not included in lite version +- removed overview setup question, a placeholder has been inserted into readme and project toml \ No newline at end of file diff --git a/cookiecutter.json b/cookiecutter.json index 2dfdf4f..a98a098 100644 --- a/cookiecutter.json +++ b/cookiecutter.json @@ -4,6 +4,5 @@ "organisation_handle": "Your GitHub/GitLab organisation name, for example ukgovdatascience", "organisational_framework": ["GDS", "N/A"], "project_name": "Your new project name", - "repo_name": "{{ cookiecutter.project_name.lower().replace(' ', '_').replace('-', '_') }}", - "overview": "Brief overview of your project." + "repo_name": "{{ cookiecutter.project_name.lower().replace(' ', '_').replace('-', '_') }}" } diff --git a/tests/test_govcookiecutter_creation.py b/tests/test_govcookiecutter_creation.py index 62ff179..dcbf3bd 100644 --- a/tests/test_govcookiecutter_creation.py +++ b/tests/test_govcookiecutter_creation.py @@ -80,7 +80,6 @@ def test_repo_name_directory_correct( "contact_email": "email@1", "project_name": "Project_1", "repo_name": "repo_1", - "overview": "overview_1", "project_version": "version_1", }, { @@ -89,7 +88,6 @@ def test_repo_name_directory_correct( "contact_email": "email@2", "project_name": "Project_2", "repo_name": "repo_2", - "overview": "overview_2", "project_version": "version_2", }, ] diff --git a/tests/test_govcookiecutter_injected_variables.py b/tests/test_govcookiecutter_injected_variables.py index 234425b..e6b04f1 100644 --- a/tests/test_govcookiecutter_injected_variables.py +++ b/tests/test_govcookiecutter_injected_variables.py @@ -31,10 +31,7 @@ '"{{ cookiecutter.repo_name }}doc"': 1, "{{ cookiecutter.repo_name }}": 2, } -OVERVIEW_COUNT = { - '"{{ cookiecutter.overview }}",': 0, - "{{ cookiecutter.overview }}": 2, -} + def replace_cookiecutter_jinja2_counts( @@ -131,8 +128,6 @@ def recursive_open_and_count_search_terms( ), ("repo_name", "repo_1", REPO_NAME_COUNT), ("repo_name", "repo_2", {**REPO_NAME_COUNT, "{{ cookiecutter.repo_name }}": 2}), - ("overview", "overview_1", OVERVIEW_COUNT), - ("overview", "overview_1", {**OVERVIEW_COUNT, "{{ cookiecutter.overview }}": 2}), ] diff --git a/{{ cookiecutter.repo_name }}/README.md b/{{ cookiecutter.repo_name }}/README.md index 2fdaffc..de1ed95 100644 --- a/{{ cookiecutter.repo_name }}/README.md +++ b/{{ cookiecutter.repo_name }}/README.md @@ -1,6 +1,6 @@ # `{{ cookiecutter.repo_name }}` -{{ cookiecutter.overview }} +A placeholder description for your python project ```{warning} Where this documentation refers to the root folder we mean where this README.md is diff --git a/{{ cookiecutter.repo_name }}/pyproject.toml b/{{ cookiecutter.repo_name }}/pyproject.toml index a8f5b95..0cc8e34 100644 --- a/{{ cookiecutter.repo_name }}/pyproject.toml +++ b/{{ cookiecutter.repo_name }}/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "{{ cookiecutter.repo_name.lower().replace(' ', '-').replace('_', '-') }}" -description = "{{ cookiecutter.overview }}" +description = "A placeholder description for your python project" version = "0.0.1" authors = [ {"name" = "{{ cookiecutter.organisation_handle }}"} From 1609c7b0670ed9604b2c7340a005add32d8b7d93 Mon Sep 17 00:00:00 2001 From: Jday7879 <57715292+Jday7879@users.noreply.github.com> Date: Wed, 16 Jul 2025 07:43:52 +0100 Subject: [PATCH 12/14] 3 remove hosting platform (#15) * removing hosting platform setup question * hooks --- CHANGELOG.md | 5 +- cookiecutter.json | 1 - docs/reference/docs_ref_README.md | 1 - hooks/__init__.py | 2 - hooks/post_gen_project.py | 66 ---------------- tests/test_govcookiecutter_creation.py | 39 ---------- .../test_set_request_template.py | 75 ------------------- .../docs/contributor_guide/CODE_OF_CONDUCT.md | 2 +- 8 files changed, 4 insertions(+), 187 deletions(-) delete mode 100644 tests/test_post_gen_project/test_set_request_template.py diff --git a/CHANGELOG.md b/CHANGELOG.md index bc15868..735a7cf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Removed - Project version from setup, default is 0.0.1 -- locked down setup question, not needed as commit hooks have been removed +- locked down setup question, not needed as commit hooks have been removed - removed all R files, not included in lite version -- removed overview setup question, a placeholder has been inserted into readme and project toml \ No newline at end of file +- hosting platform setup question, PR templates not included in lite version +- removed overview setup question, a placeholder has been inserted into readme and project toml diff --git a/cookiecutter.json b/cookiecutter.json index a98a098..98cbf20 100644 --- a/cookiecutter.json +++ b/cookiecutter.json @@ -1,6 +1,5 @@ { "organisation_name": "Your public sector organisation name, for example Government Digital Service", - "repository_hosting_platform": ["GitHub", "GitLab"], "organisation_handle": "Your GitHub/GitLab organisation name, for example ukgovdatascience", "organisational_framework": ["GDS", "N/A"], "project_name": "Your new project name", diff --git a/docs/reference/docs_ref_README.md b/docs/reference/docs_ref_README.md index 4d1049c..bbcbd84 100644 --- a/docs/reference/docs_ref_README.md +++ b/docs/reference/docs_ref_README.md @@ -26,7 +26,6 @@ hooks fail, the generated project will be rolled-back, and deleted. :toctree: api/ set_aqa_framework - set_request_template ``` diff --git a/hooks/__init__.py b/hooks/__init__.py index 1dadecc..a94d332 100644 --- a/hooks/__init__.py +++ b/hooks/__init__.py @@ -2,7 +2,6 @@ delete_files_and_folders, parse_features_json, set_aqa_framework, - set_request_template, ) from hooks.pre_gen_project import check_repo_name_structure @@ -11,5 +10,4 @@ "check_repo_name_structure", "parse_features_json", "set_aqa_framework", - "set_request_template", ) diff --git a/hooks/post_gen_project.py b/hooks/post_gen_project.py index 939321f..fa9f0dc 100644 --- a/hooks/post_gen_project.py +++ b/hooks/post_gen_project.py @@ -50,62 +50,6 @@ def set_aqa_framework( _ = Path(dir_organisational_framework_aqa).rename(dir_cookiecutter_docs_aqa) -def set_request_template( - path_organisational_framework_request_template: Union[Path, str], - dir_govcookiecutter: Union[Path, str], - repository_hosting_platform: str, -) -> None: - """Set a pull or merge request template in the outputted project structure for a - specific organisation. - - A pull request template is created if the user chooses GitHub as their repository - hosting platform. A merge request template is created if they choose GitLab instead. - - Args: - path_organisational_framework_request_template: A file path to the specific - organisation pull or merge request template. - dir_govcookiecutter: A folder path to the outputted `govcookiecutter` template. - repository_hosting_platform: The repository hosting platform. Must be one of - "GitHub" or "GitLab" (case insensitive). - - Returns: - A organisation-specific pull or merge request template in the correct location, - depending on their choice of GitHub or GitLab as the repository hosting - platform. If neither GitHub or GitLab are chosen, a `ValueError` is raised. - - """ - - # Define the file path where the request template will be moved, which is dependent - # on the repository hosting platform. If the `dir_request_template` is not - # initially one of `.github` or `.gitlab`, raise a `ValueError` - if repository_hosting_platform.lower() == "github": - path_request_template = Path(dir_govcookiecutter).joinpath( - f".{repository_hosting_platform.lower()}", "pull_request_template.md" - ) - elif repository_hosting_platform.lower() == "gitlab": - path_request_template = Path(dir_govcookiecutter).joinpath( - f".{repository_hosting_platform.lower()}", - "merge_request_templates", - "{{ cookiecutter.project_name }}.md", - ) - else: - raise ValueError( - "`repository_hosting_platform` must be one of `GitHub` or `GitLab`: " - f"{repository_hosting_platform}" - ) - - # Recursively create all the directories to the parent directory of - # `path_request_template` if they do not already exist - if not path_request_template.parent.is_dir(): - path_request_template.parent.mkdir(parents=True, exist_ok=True) - - # Move the `path_organisational_framework_request_template` to - # `path_request_template` - _ = Path(path_organisational_framework_request_template).rename( - path_request_template - ) - - def parse_features_json(file: Union[Path, str]) -> List[Path]: """Parse a JSON file containing filepaths. @@ -153,16 +97,6 @@ def parse_features_json(file: Union[Path, str]) -> List[Path]: set_aqa_framework( DIR_ORGANISATIONAL_FRAMEWORKS.joinpath("aqa"), Path("docs").joinpath("aqa") ) - set_request_template( - DIR_ORGANISATIONAL_FRAMEWORKS.joinpath("request_template.md"), - Path.cwd(), - "{{ cookiecutter.repository_hosting_platform }}", - ) - - # Delete files defined in the `manifest.json` file - # delete_files_and_folders( - # parse_features_json(Path(".govcookiecutter", "manifest.json")) - # ) # Remove `DIR_GOVCOOKIECUTTER` delete_files_and_folders(DIR_GOVCOOKIECUTTER) diff --git a/tests/test_govcookiecutter_creation.py b/tests/test_govcookiecutter_creation.py index dcbf3bd..2dd0ea5 100644 --- a/tests/test_govcookiecutter_creation.py +++ b/tests/test_govcookiecutter_creation.py @@ -5,42 +5,6 @@ from sphinx.cmd.build import main -@pytest.mark.parametrize("test_input_repository_hosting_platform", ["GitHub", "GitLab"]) -@pytest.mark.parametrize("test_input_project_name", ["A project", "Another project"]) -def test_request_template_generated_correctly( - cookies, - test_input_repository_hosting_platform: str, - test_input_project_name: str, -) -> None: - """Test the pull or merge request templates are created correctly.""" - - # Create a new project adding extra context; return it's `project_path` attribute - test_output_project = cookies.bake( - extra_context={ - "repository_hosting_platform": test_input_repository_hosting_platform, - "project_name": test_input_project_name, - } - ) - - # Check that the build passes - assert test_output_project.exit_code == 0 - assert test_output_project.exception is None - - # Define the path to the pull or merge request template - test_output = test_output_project.project_path - if test_input_repository_hosting_platform == "GitHub": - assert test_output.joinpath(".github", "pull_request_template.md").is_file() - elif test_input_repository_hosting_platform == "GitLab": - assert test_output.joinpath( - ".gitlab", "merge_request_templates", f"{test_input_project_name}.md" - ).is_file() - else: - pytest.fail( - "Unknown `repository_hosting_platform` value: " - f"{test_input_repository_hosting_platform}" - ) - - @pytest.mark.skip( reason="Unclear how to test this, unless there is a title in each " "framework" ) @@ -94,12 +58,10 @@ def test_repo_name_directory_correct( @pytest.mark.parametrize("test_input_context", args_builds_correctly) -@pytest.mark.parametrize("test_input_repository_hosting_platform", ["GitHub", "GitLab"]) @pytest.mark.parametrize("test_input_organisational_framework", ["GDS", "N/A"]) def test_builds_correctly( cookies, test_input_context: Dict[str, str], - test_input_repository_hosting_platform: str, test_input_organisational_framework: str, ) -> None: """Test that the projects are built correctly with no errors.""" @@ -108,7 +70,6 @@ def test_builds_correctly( test_output_project = cookies.bake( extra_context={ **test_input_context, - "repository_hosting_platform": test_input_repository_hosting_platform, "organisational_framework": test_input_organisational_framework, } ) diff --git a/tests/test_post_gen_project/test_set_request_template.py b/tests/test_post_gen_project/test_set_request_template.py deleted file mode 100644 index fd0fb6f..0000000 --- a/tests/test_post_gen_project/test_set_request_template.py +++ /dev/null @@ -1,75 +0,0 @@ -from pathlib import Path - -import pytest - -from hooks.post_gen_project import set_request_template - -# Define test cases for the `TestSetRequestTemplate` test class -args_test_set_request_template_valueerror_for_bad_repository_hosting_platform = [ - "hello", - "world", -] -args_test_set_request_template_request_template_moved_correctly = [ - "Github", - "gitlab", - "GITHUB", - "gitLab", -] -args_test_set_request_template_temporary_frameworks = [ - ("This is the request template.", "This is the AQA file."), - ("Here is the request template.", "Here is the AQA file."), -] - - -@pytest.mark.parametrize( - "test_input_request_template, test_input_aqa", - args_test_set_request_template_temporary_frameworks, -) -class TestSetRequestTemplate: - @pytest.mark.parametrize( - "test_input_repository_hosting_platform", - args_test_set_request_template_valueerror_for_bad_repository_hosting_platform, - ) - def test_valueerror_for_bad_repository_hosting_platform( - self, temporary_frameworks: Path, test_input_repository_hosting_platform: str - ) -> None: - """Test a ``ValueError`` is raised if the repository hosting platform is not - Github or GitLab.""" - with pytest.raises(ValueError): - set_request_template( - temporary_frameworks.joinpath("request_template.md"), - temporary_frameworks.parent, - test_input_repository_hosting_platform, - ) - - @pytest.mark.parametrize( - "test_input_repository_hosting_platform", - args_test_set_request_template_request_template_moved_correctly, - ) - def test_request_template_moved_correctly( - self, - temporary_frameworks: Path, - test_input_request_template: str, - test_input_repository_hosting_platform: str, - ) -> None: - """Test the right AQA framework folder is moved to the correct location.""" - - # Execute the `set_request_template` function - set_request_template( - temporary_frameworks.joinpath("request_template.md"), - temporary_frameworks.parent, - test_input_repository_hosting_platform, - ) - - # Assert the correct text has been written to the correct location - if test_input_repository_hosting_platform.lower() == "github": - test_output = temporary_frameworks.parent.joinpath( - ".github", "pull_request_template.md" - ).read_text() - else: - test_output = temporary_frameworks.parent.joinpath( - ".gitlab", - "merge_request_templates", - "{{ cookiecutter.project_name }}.md", - ).read_text() - assert test_output == test_input_request_template diff --git a/{{ cookiecutter.repo_name }}/docs/contributor_guide/CODE_OF_CONDUCT.md b/{{ cookiecutter.repo_name }}/docs/contributor_guide/CODE_OF_CONDUCT.md index d757174..2c798eb 100644 --- a/{{ cookiecutter.repo_name }}/docs/contributor_guide/CODE_OF_CONDUCT.md +++ b/{{ cookiecutter.repo_name }}/docs/contributor_guide/CODE_OF_CONDUCT.md @@ -10,7 +10,7 @@ Code][civil-service-code]. Where this Code of Conduct says: -- "Project", we mean this {{ cookiecutter.repository_hosting_platform }} repository, `{{ cookiecutter.repo_name }}` ; +- "Project", we mean this git repository, `{{ cookiecutter.repo_name }}` ; - "Maintainer", we mean active developers of the primary project team(s) behind `{{ cookiecutter.organisation_handle }}`; and - "Leadership", we mean `{{ cookiecutter.organisation_handle }}` organisation owners, line managers, and other leadership within the {{ cookiecutter.organisation_name }}. From b26b2b86c7e5e6938ecaab195b9fbfd9438d6df5 Mon Sep 17 00:00:00 2001 From: Luke Davies <117165341+ldavies99@users.noreply.github.com> Date: Wed, 16 Jul 2025 11:19:50 +0100 Subject: [PATCH 13/14] 6 remove setup question for repo_name (#17) * Change every instance of cookiecutter.repo_name to instead be a formatted version of cookiecutter.project_name * Update change log * Apply formatting to repo name * Revert "Apply formatting to repo name" This reverts commit 5e986bfec3f5ecbc4eb92488c068d4617b443106. * Update cookiecutter.json Co-authored-by: Jday7879 <57715292+Jday7879@users.noreply.github.com> --------- Co-authored-by: Jday7879 <57715292+Jday7879@users.noreply.github.com> --- CHANGELOG.md | 3 ++- CONTRIBUTING.md | 2 +- README.md | 4 +-- cookiecutter.json | 3 +-- .../docs_contributor_README.md | 2 +- .../modify_govcookiecutter.md | 26 +++++++++---------- docs/docs_README.md | 4 +-- .../docs_structure_README.md | 6 ++--- docs/index.md | 2 +- .../docs_repo_frameworks_README.md | 2 +- docs/{{ cookiecutter.repo_name }}/docs.md | 2 +- .../docs_repo_README.md | 4 +-- .../source_code.md | 2 +- docs/{{ cookiecutter.repo_name }}/tests.md | 2 +- hooks/pre_gen_project.py | 2 +- pyproject.toml | 6 ++--- tests/test_env.py | 4 +-- tests/test_govcookiecutter_creation.py | 4 +-- ...test_govcookiecutter_injected_variables.py | 11 -------- .../.gitignore | 0 .../GDS/aqa/aqa_plan.md | 0 .../GDS/aqa/assumptions_caveats.md | 0 .../GDS/aqa/data_log.md | 0 .../GDS/aqa/gds_aqa_README.md | 0 .../GDS/request_template.md | 0 .../framework_README.md | 0 .../CHANGELOG.md | 0 .../CODE_OF_CONDUCT.md | 2 +- .../LICENSE | 0 .../README.md | 12 ++++----- .../docs/Quality Assurance/QA_README.md | 0 .../docs/_static/.gitkeep | 0 .../docs/aqa/aqa_plan.md | 0 .../docs/aqa/assumptions_caveats.md | 0 .../docs/aqa/data_log.md | 0 .../docs/conf.py | 2 +- .../docs/contributor_guide/CODE_OF_CONDUCT.md | 4 +-- .../docs/contributor_guide/CONTRIBUTING.md | 2 +- .../contributor_guide/contributor_README.md | 9 +++++++ .../docs/index.md | 0 .../docs/repo_docs_README.md | 0 .../loading_environment_variables.md | 0 .../docs/user_guide/user_guide_README.md | 8 ++++++ .../docs/user_guide/using_pytest.md | 0 .../pyproject.toml | 2 +- .../tests/repo_tests_README.md | 3 +++ .../__init__.py | 0 .../example_module/__init__.py | 0 .../main.py | 0 .../contributor_guide/contributor_README.md | 9 ------- .../docs/user_guide/user_guide_README.md | 8 ------ .../tests/repo_tests_README.md | 3 --- 52 files changed, 70 insertions(+), 85 deletions(-) rename {{{ cookiecutter.repo_name }} => {{ cookiecutter.project_name }}}/.gitignore (100%) rename {{{ cookiecutter.repo_name }} => {{ cookiecutter.project_name }}}/.govcookiecutter/organisational_frameworks/GDS/aqa/aqa_plan.md (100%) rename {{{ cookiecutter.repo_name }} => {{ cookiecutter.project_name }}}/.govcookiecutter/organisational_frameworks/GDS/aqa/assumptions_caveats.md (100%) rename {{{ cookiecutter.repo_name }} => {{ cookiecutter.project_name }}}/.govcookiecutter/organisational_frameworks/GDS/aqa/data_log.md (100%) rename {{{ cookiecutter.repo_name }} => {{ cookiecutter.project_name }}}/.govcookiecutter/organisational_frameworks/GDS/aqa/gds_aqa_README.md (100%) rename {{{ cookiecutter.repo_name }} => {{ cookiecutter.project_name }}}/.govcookiecutter/organisational_frameworks/GDS/request_template.md (100%) rename {{{ cookiecutter.repo_name }} => {{ cookiecutter.project_name }}}/.govcookiecutter/organisational_frameworks/framework_README.md (100%) rename {{{ cookiecutter.repo_name }} => {{ cookiecutter.project_name }}}/CHANGELOG.md (100%) rename {{{ cookiecutter.repo_name }} => {{ cookiecutter.project_name }}}/CODE_OF_CONDUCT.md (73%) rename {{{ cookiecutter.repo_name }} => {{ cookiecutter.project_name }}}/LICENSE (100%) rename {{{ cookiecutter.repo_name }} => {{ cookiecutter.project_name }}}/README.md (87%) rename {{{ cookiecutter.repo_name }} => {{ cookiecutter.project_name }}}/docs/Quality Assurance/QA_README.md (100%) rename {{{ cookiecutter.repo_name }} => {{ cookiecutter.project_name }}}/docs/_static/.gitkeep (100%) rename {{{ cookiecutter.repo_name }} => {{ cookiecutter.project_name }}}/docs/aqa/aqa_plan.md (100%) rename {{{ cookiecutter.repo_name }} => {{ cookiecutter.project_name }}}/docs/aqa/assumptions_caveats.md (100%) rename {{{ cookiecutter.repo_name }} => {{ cookiecutter.project_name }}}/docs/aqa/data_log.md (100%) rename {{{ cookiecutter.repo_name }} => {{ cookiecutter.project_name }}}/docs/conf.py (98%) rename {{{ cookiecutter.repo_name }} => {{ cookiecutter.project_name }}}/docs/contributor_guide/CODE_OF_CONDUCT.md (95%) rename {{{ cookiecutter.repo_name }} => {{ cookiecutter.project_name }}}/docs/contributor_guide/CONTRIBUTING.md (97%) create mode 100644 {{ cookiecutter.project_name }}/docs/contributor_guide/contributor_README.md rename {{{ cookiecutter.repo_name }} => {{ cookiecutter.project_name }}}/docs/index.md (100%) rename {{{ cookiecutter.repo_name }} => {{ cookiecutter.project_name }}}/docs/repo_docs_README.md (100%) rename {{{ cookiecutter.repo_name }} => {{ cookiecutter.project_name }}}/docs/user_guide/loading_environment_variables.md (100%) create mode 100644 {{ cookiecutter.project_name }}/docs/user_guide/user_guide_README.md rename {{{ cookiecutter.repo_name }} => {{ cookiecutter.project_name }}}/docs/user_guide/using_pytest.md (100%) rename {{{ cookiecutter.repo_name }} => {{ cookiecutter.project_name }}}/pyproject.toml (87%) create mode 100644 {{ cookiecutter.project_name }}/tests/repo_tests_README.md rename {{{ cookiecutter.repo_name }}/{{ cookiecutter.repo_name.lower().replace(' ', '_').replace('-', '_') }} => {{ cookiecutter.project_name }}/{{ cookiecutter.project_name.lower().replace(' ', '_').replace('-', '_') }}}/__init__.py (100%) rename {{{ cookiecutter.repo_name }}/{{ cookiecutter.repo_name.lower().replace(' ', '_').replace('-', '_') }} => {{ cookiecutter.project_name }}/{{ cookiecutter.project_name.lower().replace(' ', '_').replace('-', '_') }}}/example_module/__init__.py (100%) rename {{{ cookiecutter.repo_name }}/{{ cookiecutter.repo_name.lower().replace(' ', '_').replace('-', '_') }} => {{ cookiecutter.project_name }}/{{ cookiecutter.project_name.lower().replace(' ', '_').replace('-', '_') }}}/main.py (100%) delete mode 100644 {{ cookiecutter.repo_name }}/docs/contributor_guide/contributor_README.md delete mode 100644 {{ cookiecutter.repo_name }}/docs/user_guide/user_guide_README.md delete mode 100644 {{ cookiecutter.repo_name }}/tests/repo_tests_README.md diff --git a/CHANGELOG.md b/CHANGELOG.md index 735a7cf..0b2f7ce 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,5 +18,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Project version from setup, default is 0.0.1 - locked down setup question, not needed as commit hooks have been removed - removed all R files, not included in lite version -- hosting platform setup question, PR templates not included in lite version - removed overview setup question, a placeholder has been inserted into readme and project toml +- removed repo name question, instead derived from project name question +- hosting platform setup question, PR templates not included in lite version diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index a499cba..59ef006 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -78,7 +78,7 @@ pytest Code coverage of Python scripts is measured using the [`coverage` Python package][coverage]; its configuration can be found in `pyproject.toml`. Note coverage only extends to Python scripts in the `hooks`, and -`{{ cookiecutter.repo_name }}/{{ cookiecutter.repo_name.lower().replace(' ', '_').replace('-', '_') }}` folders. +`{{ cookiecutter.project_name.lower().replace(' ', '_').replace('-', '_') }}/{{ cookiecutter.project_name.lower().replace(' ', '_').replace('-', '_') }}` folders. To run code coverage, and view it as an HTML report, enter the following command in your terminal: diff --git a/README.md b/README.md index d187ab9..c1139aa 100644 --- a/README.md +++ b/README.md @@ -28,8 +28,8 @@ The cookiecutter template generated for each project will follow this folder str ```shell . └── govcookiecutter/ - ├── {{ cookiecutter.repo_name }}/ - │ └── {{ cookiecutter.repo_name.lower().replace(' ', '_').replace('-', '_') }}/ + ├── {{ cookiecutter.project_name.lower().replace(' ', '_').replace('-', '_') }}/ + │ └── {{ cookiecutter.project_name.lower().replace(' ', '_').replace('-', '_') }}/ │ ├── example_modules/ │ │ ├── __init__.py │ │ └── example_module.py diff --git a/cookiecutter.json b/cookiecutter.json index 98cbf20..f8fea7e 100644 --- a/cookiecutter.json +++ b/cookiecutter.json @@ -2,6 +2,5 @@ "organisation_name": "Your public sector organisation name, for example Government Digital Service", "organisation_handle": "Your GitHub/GitLab organisation name, for example ukgovdatascience", "organisational_framework": ["GDS", "N/A"], - "project_name": "Your new project name", - "repo_name": "{{ cookiecutter.project_name.lower().replace(' ', '_').replace('-', '_') }}" + "project_name": "your_new_project_name" } diff --git a/docs/contributing_guide/docs_contributor_README.md b/docs/contributing_guide/docs_contributor_README.md index 1bc04b2..06d2260 100644 --- a/docs/contributing_guide/docs_contributor_README.md +++ b/docs/contributing_guide/docs_contributor_README.md @@ -7,6 +7,6 @@ This is the contributor guide for the `govcookiecutter` project. ../CODE_OF_CONDUCT.md ../CONTRIBUTING.md ./modify_govcookiecutter.md -../{{ cookiecutter.repo_name }}/.govcookiecutter/organisational_frameworks/docs_repo_frameworks_README.md +../{{ cookiecutter.project_name.lower().replace(' ', '_').replace('-', '_') }}/.govcookiecutter/organisational_frameworks/docs_repo_frameworks_README.md ``` diff --git a/docs/contributing_guide/modify_govcookiecutter.md b/docs/contributing_guide/modify_govcookiecutter.md index f2f3c56..bb2d1e1 100644 --- a/docs/contributing_guide/modify_govcookiecutter.md +++ b/docs/contributing_guide/modify_govcookiecutter.md @@ -17,13 +17,13 @@ When you open your terminal and run: cookiecutter https://github.com/best-practice-and-impact/govcookiecutter.git ``` -you'll see a list of prompts to answer; one of them is `repo_name`. +you'll see a list of prompts to answer; one of them is `project_name`. -Your answer for `repo_name` is used to overwrite every instance of -`{{ cookiecutter.repo_name }}`. The first instance is the `govcookiecutter` folder -`{{ cookiecutter.repo_name }}`, which becomes your outputted project! +Your answer for `project_name` is used to overwrite every instance of +`{{ cookiecutter.project_name.lower().replace(' ', '_').replace('-', '_') }}`. The first instance is the `govcookiecutter` folder +`{{ cookiecutter.project_name.lower().replace(' ', '_').replace('-', '_') }}`, which becomes your outputted project! -This means every folder and file contained within the `{{ cookiecutter.repo_name }}` +This means every folder and file contained within the `{{ cookiecutter.project_name.lower().replace(' ', '_').replace('-', '_') }}` folder becomes part of your output project, including their content. Anything else outside of this folder in `govcookiecutter` will not exist in the outputted project. @@ -33,7 +33,7 @@ The prompts, and their default responses are defined in `cookiecutter.json`. Her keys starting with `_` are not shown to the user, but provide template extensions. One such extension is `jinja2_time.TimeExtension`, which is used to add the correct -year in the `{{ cookiecutter.repo_name }}/LICENSE` file. +year in the `{{ cookiecutter.project_name.lower().replace(' ', '_').replace('-', '_') }}/LICENSE` file. All other keys are used to inject the user responses throughout the template. This happens wherever you see `{{ cookiecutter.{KEY} }}`, where `{KEY}` is the key in @@ -44,9 +44,7 @@ to the user. If the user does not enter a response, these default values are use Values that are lists are shown as numerical options to the user, with the first list element as the default value. -Note that these default values can also contain Jinja templating! For example, the -default response for `repo_name` is actually based on `project_name`, but with all -characters in lowercase, and any spaces replaced with hyphens. +Note that these default values can also contain Jinja templating! ## Validating user entries @@ -75,7 +73,7 @@ defined in `hooks/post_gen_project.py`. These hooks only run after a project has generated and, if they fail, will rollback the entire project. Conditional files and folders are defined as `features` in the -`{{ cookiecutter.repo_name }}/manifest.json` file, which looks like: +`{{ cookiecutter.project_name.lower().replace(' ', '_').replace('-', '_') }}/manifest.json` file, which looks like: ``` { @@ -138,11 +136,11 @@ These are performed in the `hooks/post_gen_project.py`file. ## Tests, coverage, and continuous integration All pre- and post-generation hooks should be fully tested, alongside any generic -functions that we want to supply to users within the `{{ cookiecutter.repo_name }}` +functions that we want to supply to users within the `{{ cookiecutter.project_name.lower().replace(' ', '_').replace('-', '_') }}` package. These tests should be written in `tests` or -`{{ cookiecutter.repo_name }}/tests` as appropriate. +`{{ cookiecutter.project_name.lower().replace(' ', '_').replace('-', '_') }}/tests` as appropriate. -Coverage also only covers the `hooks` and `{{ cookiecutter.repo_name }}/{{ cookiecutter.repo_name.lower().replace(' ', '_').replace('-', '_') }}` folders. +Coverage also only covers the `hooks` and `{{ cookiecutter.project_name.lower().replace(' ', '_').replace('-', '_') }}/{{ cookiecutter.project_name.lower().replace(' ', '_').replace('-', '_') }}` folders. ### Testing Jinja templating @@ -150,7 +148,7 @@ Most of the tests are straightforward, and comprehensive. However, to test the J injection of user responses, the `test_govcookiecutter_injected_variables.py` script adopts a test-driven development approach to completeness. -This test parses all the content of the `{{ cookiecutter.repo_name }}` folder, and +This test parses all the content of the `{{ cookiecutter.project_name.lower().replace(' ', '_').replace('-', '_') }}` folder, and counts the number of times the replacement variable and its variations appear. The constant dictionary variables at the top of the test script define the different diff --git a/docs/docs_README.md b/docs/docs_README.md index 71a8107..aa5bb2e 100644 --- a/docs/docs_README.md +++ b/docs/docs_README.md @@ -6,8 +6,8 @@ This folder contains documentation for `govcookiecutter`. These are written in M Further details to consider when modifying these files are supplied in the [contributing guidance][contributing-guidance]. ``` -To include documentation from the `{{ cookiecutter.repo_name }}` -folder without duplicating it, refer to it in a file within the `docs/{{ cookiecutter.repo_name }}` folder. +To include documentation from the `{{ cookiecutter.project_name.lower().replace(' ', '_').replace('-', '_') }}` +folder without duplicating it, refer to it in a file within the `docs/{{ cookiecutter.project_name.lower().replace(' ', '_').replace('-', '_') }}` folder. To build the documentation, run: diff --git a/docs/govcookiecutter_structure/docs_structure_README.md b/docs/govcookiecutter_structure/docs_structure_README.md index 825d66d..2e873be 100644 --- a/docs/govcookiecutter_structure/docs_structure_README.md +++ b/docs/govcookiecutter_structure/docs_structure_README.md @@ -9,7 +9,7 @@ Further detail on folder contents is available: ./example.md ./hooks.md ./tests.md -../{{ cookiecutter.repo_name }}/docs_repo_README.md +../{{ cookiecutter.project_name.lower().replace(' ', '_').replace('-', '_') }}/docs_repo_README.md ``` ## Top-level files @@ -101,7 +101,7 @@ Python imports are arranged according to the [specification defined by `black`][ #### `pytest` -To run the tests within the `tests`, and `{{ cookiecutter.repo_name }}/tests` folders +To run the tests within the `tests`, and `{{ cookiecutter.project_name.lower().replace(' ', '_').replace('-', '_') }}/tests` folders using the `pytest` Python package, enter the following command: ```shell @@ -125,7 +125,7 @@ make coverage_html ``` A code coverage report in HTML will be produced on the code in the `hooks` and -`{{ cookiecutter.repo_name }}/{{ cookiecutter.repo_name.lower().replace(' ', '_').replace('-', '_') }}` folders. +`{{ cookiecutter.project_name.lower().replace(' ', '_').replace('-', '_') }}/{{ cookiecutter.project_name.lower().replace(' ', '_').replace('-', '_') }}` folders. This HTML report can be accessed at `htmlcov/index.html`. ### `README.md` diff --git a/docs/index.md b/docs/index.md index 263bd64..dcde541 100644 --- a/docs/index.md +++ b/docs/index.md @@ -8,6 +8,6 @@ self ./contributing_guide/docs_contributor_README.md ./govcookiecutter_structure/docs_structure_README.md -./{{ cookiecutter.repo_name }}/docs_repo_README.md +./{{ cookiecutter.project_name.lower().replace(' ', '_').replace('-', '_') }}/docs_repo_README.md ./reference/docs_ref_README.md ``` diff --git a/docs/{{ cookiecutter.repo_name }}/.govcookiecutter/organisational_frameworks/docs_repo_frameworks_README.md b/docs/{{ cookiecutter.repo_name }}/.govcookiecutter/organisational_frameworks/docs_repo_frameworks_README.md index 3066c3d..648660d 100644 --- a/docs/{{ cookiecutter.repo_name }}/.govcookiecutter/organisational_frameworks/docs_repo_frameworks_README.md +++ b/docs/{{ cookiecutter.repo_name }}/.govcookiecutter/organisational_frameworks/docs_repo_frameworks_README.md @@ -1,2 +1,2 @@ -```{include} ../../../../{{ cookiecutter.repo_name }}/.govcookiecutter/organisational_frameworks/framework_README.md +```{include} ../../../../{{ cookiecutter.project_name.lower().replace(' ', '_').replace('-', '_') }}/.govcookiecutter/organisational_frameworks/framework_README.md ``` diff --git a/docs/{{ cookiecutter.repo_name }}/docs.md b/docs/{{ cookiecutter.repo_name }}/docs.md index e8799ba..d42c3ea 100644 --- a/docs/{{ cookiecutter.repo_name }}/docs.md +++ b/docs/{{ cookiecutter.repo_name }}/docs.md @@ -1,2 +1,2 @@ -```{include} ../../{{ cookiecutter.repo_name }}/docs/repo_docs_README.md +```{include} ../../{{ cookiecutter.project_name.lower().replace(' ', '_').replace('-', '_') }}/docs/repo_docs_README.md ``` diff --git a/docs/{{ cookiecutter.repo_name }}/docs_repo_README.md b/docs/{{ cookiecutter.repo_name }}/docs_repo_README.md index b858ef8..9ab279f 100644 --- a/docs/{{ cookiecutter.repo_name }}/docs_repo_README.md +++ b/docs/{{ cookiecutter.repo_name }}/docs_repo_README.md @@ -1,7 +1,7 @@ -# `{{ cookiecutter.repo_name }}` folder structure +# `{{ cookiecutter.project_name.lower().replace(' ', '_').replace('-', '_') }}` folder structure This is information about the structure of the created repository contained -in the `{{ cookiecutter.repo_name }}` folder within the `govcookiecutter` repository. +in the `{{ cookiecutter.project_name.lower().replace(' ', '_').replace('-', '_') }}` folder within the `govcookiecutter` repository. Some of these files may not be present in the actual created repository, as this is customised based on the user's answers to the prompts on set-ups. diff --git a/docs/{{ cookiecutter.repo_name }}/source_code.md b/docs/{{ cookiecutter.repo_name }}/source_code.md index 1591930..7c5ad92 100644 --- a/docs/{{ cookiecutter.repo_name }}/source_code.md +++ b/docs/{{ cookiecutter.repo_name }}/source_code.md @@ -1,4 +1,4 @@ -# `{{ cookiecutter.repo_name.lower().replace(' ', '_').replace('-', '_') }}` folder overview +# `{{ cookiecutter.project_name.lower().replace(' ', '_').replace('-', '_') }}` folder overview This is where source code for the created project is stored. We recommend following a standard Python project structure, with functions grouped into modules inside a descriptively named folder. The created repository contains an `example_module.py` diff --git a/docs/{{ cookiecutter.repo_name }}/tests.md b/docs/{{ cookiecutter.repo_name }}/tests.md index 5d230f7..678fae4 100644 --- a/docs/{{ cookiecutter.repo_name }}/tests.md +++ b/docs/{{ cookiecutter.repo_name }}/tests.md @@ -1,2 +1,2 @@ -```{include} ../../{{ cookiecutter.repo_name }}/tests/repo_tests_README.md +```{include} ../../{{ cookiecutter.project_name.lower().replace(' ', '_').replace('-', '_') }}/tests/repo_tests_README.md ``` diff --git a/hooks/pre_gen_project.py b/hooks/pre_gen_project.py index 6fca095..5f29cbe 100644 --- a/hooks/pre_gen_project.py +++ b/hooks/pre_gen_project.py @@ -17,4 +17,4 @@ def check_repo_name_structure(repo_name: str) -> None: if __name__ == "__main__": # Check the format of the contact email address supplied is a valid one - check_repo_name_structure("{{ cookiecutter.repo_name }}") + check_repo_name_structure("{{ cookiecutter.project_name.lower().replace(' ', '_').replace('-', '_') }}") diff --git a/pyproject.toml b/pyproject.toml index dece2fa..71141f1 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -2,10 +2,10 @@ [tool.coverage.run] source = [ "./hooks", - "./{{ cookiecutter.repo_name }}/{{ cookiecutter.repo_name.lower().replace(' ', '_').replace('-', '_') }}" + "./{{ cookiecutter.project_name.lower().replace(' ', '_').replace('-', '_') }}/{{ cookiecutter.project_name.lower().replace(' ', '_').replace('-', '_') }}" ] omit = [ - "./{{ cookiecutter.repo_name }}/{{ cookiecutter.repo_name.lower().replace(' ', '_').replace('-', '_') }}/run_pipeline.py" + "./{{ cookiecutter.project_name.lower().replace(' ', '_').replace('-', '_') }}/{{ cookiecutter.project_name.lower().replace(' ', '_').replace('-', '_') }}/run_pipeline.py" ] [tool.coverage.omit] @@ -26,7 +26,7 @@ addopts = [ "--doctest-modules", "--ignore='./docs/'", "--ignore='./example/'", - "--ignore='./{{ cookiecutter.repo_name }}/docs/'" + "--ignore='./{{ cookiecutter.project_name.lower().replace(' ', '_').replace('-', '_') }}/docs/'" ] doctest_optionflags = "NORMALIZE_WHITESPACE" testpaths = [ diff --git a/tests/test_env.py b/tests/test_env.py index 4eeb8ec..54b893b 100644 --- a/tests/test_env.py +++ b/tests/test_env.py @@ -4,7 +4,7 @@ from dotenv import dotenv_values # Define a path to the `govcookiecutter` template directory, and its `.env` file -DIR_TEMPLATE = Path("{{ cookiecutter.repo_name }}") +DIR_TEMPLATE = Path("{{ cookiecutter.project_name.lower().replace(' ', '_').replace('-', '_') }}") PATH_TEMPLATE_ENV = DIR_TEMPLATE.joinpath(".env") # Define a list of directory names to recursively ignore, as well as a list of @@ -119,7 +119,7 @@ def define_expected_env_variables( ): if ( d.name.upper() - == "{{ cookiecutter.repo_name.lower().replace(' ', '_').replace('-', '_') }}".upper() # noqa: E501 + == "{{ cookiecutter.project_name.lower().replace(' ', '_').replace('-', '_') }}".upper() # noqa: E501 ): env_expected_dir_variable = loop_directories_children( d, env_expected_dir_variable diff --git a/tests/test_govcookiecutter_creation.py b/tests/test_govcookiecutter_creation.py index 2dd0ea5..1e33305 100644 --- a/tests/test_govcookiecutter_creation.py +++ b/tests/test_govcookiecutter_creation.py @@ -23,7 +23,7 @@ def test_repo_name_directory_correct( # Create a new project adding extra context test_output_project = cookies.bake( extra_context={ - "repo_name": test_input_repository_name, + "project_name": test_input_repository_name, } ) @@ -43,7 +43,6 @@ def test_repo_name_directory_correct( "organisation_handle": "handle_1", "contact_email": "email@1", "project_name": "Project_1", - "repo_name": "repo_1", "project_version": "version_1", }, { @@ -51,7 +50,6 @@ def test_repo_name_directory_correct( "organisation_handle": "handle_2", "contact_email": "email@2", "project_name": "Project_2", - "repo_name": "repo_2", "project_version": "version_2", }, ] diff --git a/tests/test_govcookiecutter_injected_variables.py b/tests/test_govcookiecutter_injected_variables.py index e6b04f1..7b14d5c 100644 --- a/tests/test_govcookiecutter_injected_variables.py +++ b/tests/test_govcookiecutter_injected_variables.py @@ -23,15 +23,6 @@ 'u"{{ cookiecutter.project_name }}': 0, "{{ cookiecutter.project_name }}": 2, } -REPO_NAME_COUNT = { - '"{{ cookiecutter.repo_name }}",': 0, - "`{{ cookiecutter.repo_name }}`": 8, - "`{{ cookiecutter.repo_name }}`,": 1, - '"{{ cookiecutter.repo_name }}.tex",': 0, - '"{{ cookiecutter.repo_name }}doc"': 1, - "{{ cookiecutter.repo_name }}": 2, -} - def replace_cookiecutter_jinja2_counts( @@ -126,8 +117,6 @@ def recursive_open_and_count_search_terms( "Project_2", {**PROJECT_NAME_COUNT, "{{ cookiecutter.project_name }}": 2}, ), - ("repo_name", "repo_1", REPO_NAME_COUNT), - ("repo_name", "repo_2", {**REPO_NAME_COUNT, "{{ cookiecutter.repo_name }}": 2}), ] diff --git a/{{ cookiecutter.repo_name }}/.gitignore b/{{ cookiecutter.project_name }}/.gitignore similarity index 100% rename from {{ cookiecutter.repo_name }}/.gitignore rename to {{ cookiecutter.project_name }}/.gitignore diff --git a/{{ cookiecutter.repo_name }}/.govcookiecutter/organisational_frameworks/GDS/aqa/aqa_plan.md b/{{ cookiecutter.project_name }}/.govcookiecutter/organisational_frameworks/GDS/aqa/aqa_plan.md similarity index 100% rename from {{ cookiecutter.repo_name }}/.govcookiecutter/organisational_frameworks/GDS/aqa/aqa_plan.md rename to {{ cookiecutter.project_name }}/.govcookiecutter/organisational_frameworks/GDS/aqa/aqa_plan.md diff --git a/{{ cookiecutter.repo_name }}/.govcookiecutter/organisational_frameworks/GDS/aqa/assumptions_caveats.md b/{{ cookiecutter.project_name }}/.govcookiecutter/organisational_frameworks/GDS/aqa/assumptions_caveats.md similarity index 100% rename from {{ cookiecutter.repo_name }}/.govcookiecutter/organisational_frameworks/GDS/aqa/assumptions_caveats.md rename to {{ cookiecutter.project_name }}/.govcookiecutter/organisational_frameworks/GDS/aqa/assumptions_caveats.md diff --git a/{{ cookiecutter.repo_name }}/.govcookiecutter/organisational_frameworks/GDS/aqa/data_log.md b/{{ cookiecutter.project_name }}/.govcookiecutter/organisational_frameworks/GDS/aqa/data_log.md similarity index 100% rename from {{ cookiecutter.repo_name }}/.govcookiecutter/organisational_frameworks/GDS/aqa/data_log.md rename to {{ cookiecutter.project_name }}/.govcookiecutter/organisational_frameworks/GDS/aqa/data_log.md diff --git a/{{ cookiecutter.repo_name }}/.govcookiecutter/organisational_frameworks/GDS/aqa/gds_aqa_README.md b/{{ cookiecutter.project_name }}/.govcookiecutter/organisational_frameworks/GDS/aqa/gds_aqa_README.md similarity index 100% rename from {{ cookiecutter.repo_name }}/.govcookiecutter/organisational_frameworks/GDS/aqa/gds_aqa_README.md rename to {{ cookiecutter.project_name }}/.govcookiecutter/organisational_frameworks/GDS/aqa/gds_aqa_README.md diff --git a/{{ cookiecutter.repo_name }}/.govcookiecutter/organisational_frameworks/GDS/request_template.md b/{{ cookiecutter.project_name }}/.govcookiecutter/organisational_frameworks/GDS/request_template.md similarity index 100% rename from {{ cookiecutter.repo_name }}/.govcookiecutter/organisational_frameworks/GDS/request_template.md rename to {{ cookiecutter.project_name }}/.govcookiecutter/organisational_frameworks/GDS/request_template.md diff --git a/{{ cookiecutter.repo_name }}/.govcookiecutter/organisational_frameworks/framework_README.md b/{{ cookiecutter.project_name }}/.govcookiecutter/organisational_frameworks/framework_README.md similarity index 100% rename from {{ cookiecutter.repo_name }}/.govcookiecutter/organisational_frameworks/framework_README.md rename to {{ cookiecutter.project_name }}/.govcookiecutter/organisational_frameworks/framework_README.md diff --git a/{{ cookiecutter.repo_name }}/CHANGELOG.md b/{{ cookiecutter.project_name }}/CHANGELOG.md similarity index 100% rename from {{ cookiecutter.repo_name }}/CHANGELOG.md rename to {{ cookiecutter.project_name }}/CHANGELOG.md diff --git a/{{ cookiecutter.repo_name }}/CODE_OF_CONDUCT.md b/{{ cookiecutter.project_name }}/CODE_OF_CONDUCT.md similarity index 73% rename from {{ cookiecutter.repo_name }}/CODE_OF_CONDUCT.md rename to {{ cookiecutter.project_name }}/CODE_OF_CONDUCT.md index 6a8f475..2a4d6bc 100644 --- a/{{ cookiecutter.repo_name }}/CODE_OF_CONDUCT.md +++ b/{{ cookiecutter.project_name }}/CODE_OF_CONDUCT.md @@ -1,4 +1,4 @@ -# Code of conduct for `{{ cookiecutter.repo_name }}` +# Code of conduct for `{{ cookiecutter.project_name.lower().replace(' ', '_').replace('-', '_') }}` [Our code of conduct can be found at `docs/contributor_guide/CODE_OF_CONDUCT.md`][code-of-conduct]. diff --git a/{{ cookiecutter.repo_name }}/LICENSE b/{{ cookiecutter.project_name }}/LICENSE similarity index 100% rename from {{ cookiecutter.repo_name }}/LICENSE rename to {{ cookiecutter.project_name }}/LICENSE diff --git a/{{ cookiecutter.repo_name }}/README.md b/{{ cookiecutter.project_name }}/README.md similarity index 87% rename from {{ cookiecutter.repo_name }}/README.md rename to {{ cookiecutter.project_name }}/README.md index de1ed95..a34e061 100644 --- a/{{ cookiecutter.repo_name }}/README.md +++ b/{{ cookiecutter.project_name }}/README.md @@ -1,4 +1,4 @@ -# `{{ cookiecutter.repo_name }}` +# `{{ cookiecutter.project_name.lower().replace(' ', '_').replace('-', '_') }}` A placeholder description for your python project @@ -6,7 +6,7 @@ A placeholder description for your python project Where this documentation refers to the root folder we mean where this README.md is located. ``` -## What is `{{ cookiecutter.repo_name }}`? +## What is `{{ cookiecutter.project_name.lower().replace(' ', '_').replace('-', '_') }}`? Add a summary of your project here. @@ -59,7 +59,7 @@ To run the pipeline, run the following code in the terminal (either in the root project, or by specifying the path to `run_pipeline.py` from elsewhere). ```shell -python src/{{ cookiecutter.repo_name.lower().replace(' ', '_').replace('-', '_') }}/run_pipeline.py +python src/{{ cookiecutter.project_name.lower().replace(' ', '_').replace('-', '_') }}/run_pipeline.py ``` Alternatively, most Python IDEs allow you to run the code directly using a `run` button. @@ -84,8 +84,8 @@ The cookiecutter template generated for each project will follow this folder str ```shell . -├── {{ cookiecutter.repo_name }}/ -│ └── {{ cookiecutter.repo_name.lower().replace(' ', '_').replace('-', '_') }}/ +├── {{ cookiecutter.project_name.lower().replace(' ', '_').replace('-', '_') }}/ +│ └── {{ cookiecutter.project_name.lower().replace(' ', '_').replace('-', '_') }}/ │ ├── example_modules/ │ │ ├── __init__.py │ │ └── example_module.py @@ -103,7 +103,7 @@ Crown copyright and available under the terms of the Open Government 3.0 licence ## Contributing -If you want to help us build and improve `{{ cookiecutter.repo_name }}`, please take a look at our +If you want to help us build and improve `{{ cookiecutter.project_name.lower().replace(' ', '_').replace('-', '_') }}`, please take a look at our [contributing guidelines][contributing]. ## Acknowledgements diff --git a/{{ cookiecutter.repo_name }}/docs/Quality Assurance/QA_README.md b/{{ cookiecutter.project_name }}/docs/Quality Assurance/QA_README.md similarity index 100% rename from {{ cookiecutter.repo_name }}/docs/Quality Assurance/QA_README.md rename to {{ cookiecutter.project_name }}/docs/Quality Assurance/QA_README.md diff --git a/{{ cookiecutter.repo_name }}/docs/_static/.gitkeep b/{{ cookiecutter.project_name }}/docs/_static/.gitkeep similarity index 100% rename from {{ cookiecutter.repo_name }}/docs/_static/.gitkeep rename to {{ cookiecutter.project_name }}/docs/_static/.gitkeep diff --git a/{{ cookiecutter.repo_name }}/docs/aqa/aqa_plan.md b/{{ cookiecutter.project_name }}/docs/aqa/aqa_plan.md similarity index 100% rename from {{ cookiecutter.repo_name }}/docs/aqa/aqa_plan.md rename to {{ cookiecutter.project_name }}/docs/aqa/aqa_plan.md diff --git a/{{ cookiecutter.repo_name }}/docs/aqa/assumptions_caveats.md b/{{ cookiecutter.project_name }}/docs/aqa/assumptions_caveats.md similarity index 100% rename from {{ cookiecutter.repo_name }}/docs/aqa/assumptions_caveats.md rename to {{ cookiecutter.project_name }}/docs/aqa/assumptions_caveats.md diff --git a/{{ cookiecutter.repo_name }}/docs/aqa/data_log.md b/{{ cookiecutter.project_name }}/docs/aqa/data_log.md similarity index 100% rename from {{ cookiecutter.repo_name }}/docs/aqa/data_log.md rename to {{ cookiecutter.project_name }}/docs/aqa/data_log.md diff --git a/{{ cookiecutter.repo_name }}/docs/conf.py b/{{ cookiecutter.project_name }}/docs/conf.py similarity index 98% rename from {{ cookiecutter.repo_name }}/docs/conf.py rename to {{ cookiecutter.project_name }}/docs/conf.py index 6e0fd05..639624a 100644 --- a/{{ cookiecutter.repo_name }}/docs/conf.py +++ b/{{ cookiecutter.project_name }}/docs/conf.py @@ -165,7 +165,7 @@ # html_search_scorer = "scorer.js" # Output file base name for HTML help builder. -htmlhelp_basename = "{{ cookiecutter.repo_name }}doc" +htmlhelp_basename = "{{ cookiecutter.project_name.lower().replace(' ', '_').replace('-', '_') }}doc" # -- Options for autosection output ---------------- diff --git a/{{ cookiecutter.repo_name }}/docs/contributor_guide/CODE_OF_CONDUCT.md b/{{ cookiecutter.project_name }}/docs/contributor_guide/CODE_OF_CONDUCT.md similarity index 95% rename from {{ cookiecutter.repo_name }}/docs/contributor_guide/CODE_OF_CONDUCT.md rename to {{ cookiecutter.project_name }}/docs/contributor_guide/CODE_OF_CONDUCT.md index 2c798eb..6c1a97e 100644 --- a/{{ cookiecutter.repo_name }}/docs/contributor_guide/CODE_OF_CONDUCT.md +++ b/{{ cookiecutter.project_name }}/docs/contributor_guide/CODE_OF_CONDUCT.md @@ -1,4 +1,4 @@ -# Code of conduct for `{{ cookiecutter.repo_name }}` +# Code of conduct for `{{ cookiecutter.project_name.lower().replace(' ', '_').replace('-', '_') }}` All contributors to this repository hosted by `{{ cookiecutter.organisation_handle }}` are expected to follow the Contributor Covenant Code of Conduct. Those working within HM Government are also expected to follow the [Civil Service @@ -10,7 +10,7 @@ Code][civil-service-code]. Where this Code of Conduct says: -- "Project", we mean this git repository, `{{ cookiecutter.repo_name }}` ; +- "Project", we mean this repository `{{ cookiecutter.project_name.lower().replace(' ', '_').replace('-', '_') }}` ; - "Maintainer", we mean active developers of the primary project team(s) behind `{{ cookiecutter.organisation_handle }}`; and - "Leadership", we mean `{{ cookiecutter.organisation_handle }}` organisation owners, line managers, and other leadership within the {{ cookiecutter.organisation_name }}. diff --git a/{{ cookiecutter.repo_name }}/docs/contributor_guide/CONTRIBUTING.md b/{{ cookiecutter.project_name }}/docs/contributor_guide/CONTRIBUTING.md similarity index 97% rename from {{ cookiecutter.repo_name }}/docs/contributor_guide/CONTRIBUTING.md rename to {{ cookiecutter.project_name }}/docs/contributor_guide/CONTRIBUTING.md index 0d90efb..ee541b9 100644 --- a/{{ cookiecutter.repo_name }}/docs/contributor_guide/CONTRIBUTING.md +++ b/{{ cookiecutter.project_name }}/docs/contributor_guide/CONTRIBUTING.md @@ -69,7 +69,7 @@ pytest Code coverage of Python scripts is measured using the [`coverage` Python package][coverage]; its configuration can be found in `pyproject.toml`. Note coverage -only extends to Python scripts in the `{{ cookiecutter.repo_name.lower().replace(' ', '_').replace('-', '_') }}` folder. +only extends to Python scripts in the `{{ cookiecutter.project_name.lower().replace(' ', '_').replace('-', '_') }}` folder. To run code coverage, and view it as an HTML report, enter the following command in your terminal: diff --git a/{{ cookiecutter.project_name }}/docs/contributor_guide/contributor_README.md b/{{ cookiecutter.project_name }}/docs/contributor_guide/contributor_README.md new file mode 100644 index 0000000..410b80e --- /dev/null +++ b/{{ cookiecutter.project_name }}/docs/contributor_guide/contributor_README.md @@ -0,0 +1,9 @@ +# Contributing guide + +This is the contributor guide for the `{{ cookiecutter.project_name.lower().replace(' ', '_').replace('-', '_') }}` project. + +```{toctree} +:maxdepth: 2 +./CODE_OF_CONDUCT.md +./CONTRIBUTING.md +``` diff --git a/{{ cookiecutter.repo_name }}/docs/index.md b/{{ cookiecutter.project_name }}/docs/index.md similarity index 100% rename from {{ cookiecutter.repo_name }}/docs/index.md rename to {{ cookiecutter.project_name }}/docs/index.md diff --git a/{{ cookiecutter.repo_name }}/docs/repo_docs_README.md b/{{ cookiecutter.project_name }}/docs/repo_docs_README.md similarity index 100% rename from {{ cookiecutter.repo_name }}/docs/repo_docs_README.md rename to {{ cookiecutter.project_name }}/docs/repo_docs_README.md diff --git a/{{ cookiecutter.repo_name }}/docs/user_guide/loading_environment_variables.md b/{{ cookiecutter.project_name }}/docs/user_guide/loading_environment_variables.md similarity index 100% rename from {{ cookiecutter.repo_name }}/docs/user_guide/loading_environment_variables.md rename to {{ cookiecutter.project_name }}/docs/user_guide/loading_environment_variables.md diff --git a/{{ cookiecutter.project_name }}/docs/user_guide/user_guide_README.md b/{{ cookiecutter.project_name }}/docs/user_guide/user_guide_README.md new file mode 100644 index 0000000..112198f --- /dev/null +++ b/{{ cookiecutter.project_name }}/docs/user_guide/user_guide_README.md @@ -0,0 +1,8 @@ +# User guide + +This is the user guide for the `{{ cookiecutter.project_name.lower().replace(' ', '_').replace('-', '_') }}` project. + +```{toctree} +:maxdepth: 2 +./loading_environment_variables.md +``` diff --git a/{{ cookiecutter.repo_name }}/docs/user_guide/using_pytest.md b/{{ cookiecutter.project_name }}/docs/user_guide/using_pytest.md similarity index 100% rename from {{ cookiecutter.repo_name }}/docs/user_guide/using_pytest.md rename to {{ cookiecutter.project_name }}/docs/user_guide/using_pytest.md diff --git a/{{ cookiecutter.repo_name }}/pyproject.toml b/{{ cookiecutter.project_name }}/pyproject.toml similarity index 87% rename from {{ cookiecutter.repo_name }}/pyproject.toml rename to {{ cookiecutter.project_name }}/pyproject.toml index 0cc8e34..5b63ddb 100644 --- a/{{ cookiecutter.repo_name }}/pyproject.toml +++ b/{{ cookiecutter.project_name }}/pyproject.toml @@ -1,5 +1,5 @@ [project] -name = "{{ cookiecutter.repo_name.lower().replace(' ', '-').replace('_', '-') }}" +name = "{{ cookiecutter.project_name.lower().replace(' ', '-').replace('_', '-') }}" description = "A placeholder description for your python project" version = "0.0.1" authors = [ diff --git a/{{ cookiecutter.project_name }}/tests/repo_tests_README.md b/{{ cookiecutter.project_name }}/tests/repo_tests_README.md new file mode 100644 index 0000000..e6651fe --- /dev/null +++ b/{{ cookiecutter.project_name }}/tests/repo_tests_README.md @@ -0,0 +1,3 @@ +# `tests` folder overview + +All tests for the functions defined in the `{{ cookiecutter.project_name.lower().replace(' ', '_').replace('-', '_') }}` folder should be stored here. diff --git a/{{ cookiecutter.repo_name }}/{{ cookiecutter.repo_name.lower().replace(' ', '_').replace('-', '_') }}/__init__.py b/{{ cookiecutter.project_name }}/{{ cookiecutter.project_name.lower().replace(' ', '_').replace('-', '_') }}/__init__.py similarity index 100% rename from {{ cookiecutter.repo_name }}/{{ cookiecutter.repo_name.lower().replace(' ', '_').replace('-', '_') }}/__init__.py rename to {{ cookiecutter.project_name }}/{{ cookiecutter.project_name.lower().replace(' ', '_').replace('-', '_') }}/__init__.py diff --git a/{{ cookiecutter.repo_name }}/{{ cookiecutter.repo_name.lower().replace(' ', '_').replace('-', '_') }}/example_module/__init__.py b/{{ cookiecutter.project_name }}/{{ cookiecutter.project_name.lower().replace(' ', '_').replace('-', '_') }}/example_module/__init__.py similarity index 100% rename from {{ cookiecutter.repo_name }}/{{ cookiecutter.repo_name.lower().replace(' ', '_').replace('-', '_') }}/example_module/__init__.py rename to {{ cookiecutter.project_name }}/{{ cookiecutter.project_name.lower().replace(' ', '_').replace('-', '_') }}/example_module/__init__.py diff --git a/{{ cookiecutter.repo_name }}/{{ cookiecutter.repo_name.lower().replace(' ', '_').replace('-', '_') }}/main.py b/{{ cookiecutter.project_name }}/{{ cookiecutter.project_name.lower().replace(' ', '_').replace('-', '_') }}/main.py similarity index 100% rename from {{ cookiecutter.repo_name }}/{{ cookiecutter.repo_name.lower().replace(' ', '_').replace('-', '_') }}/main.py rename to {{ cookiecutter.project_name }}/{{ cookiecutter.project_name.lower().replace(' ', '_').replace('-', '_') }}/main.py diff --git a/{{ cookiecutter.repo_name }}/docs/contributor_guide/contributor_README.md b/{{ cookiecutter.repo_name }}/docs/contributor_guide/contributor_README.md deleted file mode 100644 index 2583bac..0000000 --- a/{{ cookiecutter.repo_name }}/docs/contributor_guide/contributor_README.md +++ /dev/null @@ -1,9 +0,0 @@ -# Contributing guide - -This is the contributor guide for the `{{ cookiecutter.repo_name }}` project. - -```{toctree} -:maxdepth: 2 -./CODE_OF_CONDUCT.md -./CONTRIBUTING.md -``` diff --git a/{{ cookiecutter.repo_name }}/docs/user_guide/user_guide_README.md b/{{ cookiecutter.repo_name }}/docs/user_guide/user_guide_README.md deleted file mode 100644 index bb0f140..0000000 --- a/{{ cookiecutter.repo_name }}/docs/user_guide/user_guide_README.md +++ /dev/null @@ -1,8 +0,0 @@ -# User guide - -This is the user guide for the `{{ cookiecutter.repo_name }}` project. - -```{toctree} -:maxdepth: 2 -./loading_environment_variables.md -``` diff --git a/{{ cookiecutter.repo_name }}/tests/repo_tests_README.md b/{{ cookiecutter.repo_name }}/tests/repo_tests_README.md deleted file mode 100644 index 6ec5b07..0000000 --- a/{{ cookiecutter.repo_name }}/tests/repo_tests_README.md +++ /dev/null @@ -1,3 +0,0 @@ -# `tests` folder overview - -All tests for the functions defined in the `{{ cookiecutter.repo_name.lower().replace(' ', '_').replace('-', '_') }}` folder should be stored here. From 2f069e247aea9af1ce9952c3c21aa22bdf9c7dd9 Mon Sep 17 00:00:00 2001 From: jday7879 <57715292+Jday7879@users.noreply.github.com> Date: Wed, 16 Jul 2025 14:19:49 +0100 Subject: [PATCH 14/14] remove framework code and tests, aqa framework files set as default --- CONTRIBUTING.md | 7 -- cookiecutter.json | 1 - .../docs_contributor_README.md | 1 - .../modify_govcookiecutter.md | 1 - .../docs_repo_frameworks_README.md | 2 - .../dot_govcookiecutter.md | 13 --- hooks/__init__.py | 2 - hooks/post_gen_project.py | 42 --------- tests/test_govcookiecutter_creation.py | 11 --- .../test_set_aqa_framework.py | 91 ------------------- .../GDS/aqa/aqa_plan.md | 12 --- .../GDS/aqa/assumptions_caveats.md | 30 ------ .../GDS/aqa/data_log.md | 30 ------ .../GDS/request_template.md | 34 ------- .../framework_README.md | 31 ------- .../docs/aqa/assumptions_caveats.md | 27 ++++++ .../docs/aqa/data_log.md | 27 ++++++ .../GDS => docs}/aqa/gds_aqa_README.md | 0 18 files changed, 54 insertions(+), 308 deletions(-) delete mode 100644 docs/{{ cookiecutter.repo_name }}/.govcookiecutter/organisational_frameworks/docs_repo_frameworks_README.md delete mode 100644 tests/test_post_gen_project/test_set_aqa_framework.py delete mode 100644 {{ cookiecutter.project_name }}/.govcookiecutter/organisational_frameworks/GDS/aqa/aqa_plan.md delete mode 100644 {{ cookiecutter.project_name }}/.govcookiecutter/organisational_frameworks/GDS/aqa/assumptions_caveats.md delete mode 100644 {{ cookiecutter.project_name }}/.govcookiecutter/organisational_frameworks/GDS/aqa/data_log.md delete mode 100644 {{ cookiecutter.project_name }}/.govcookiecutter/organisational_frameworks/GDS/request_template.md delete mode 100644 {{ cookiecutter.project_name }}/.govcookiecutter/organisational_frameworks/framework_README.md rename {{ cookiecutter.project_name }}/{.govcookiecutter/organisational_frameworks/GDS => docs}/aqa/gds_aqa_README.md (100%) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 59ef006..7526038 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -114,13 +114,6 @@ make docs This should create an HTML version of your documentation accessible from `docs/_build/index.html`. -## Organisational frameworks - -Organisational frameworks are stored in the -`.govcookiecutter/organisational_frameworks` folder. [If you would like to add your own -organisation's framework, follow the instructions][docs-govcookiecutter-frameworks] in -the `README.md` file in that folder. - [code-of-conduct]: https://github.com/best-practice-and-impact/govcookiecutter/blob/main/CODE_OF_CONDUCT.md [coverage]: https://coverage.readthedocs.io/ [detect-secrets-repo]: https://github.com/Yelp/detect-secrets/tree/master diff --git a/cookiecutter.json b/cookiecutter.json index f8fea7e..5a320bd 100644 --- a/cookiecutter.json +++ b/cookiecutter.json @@ -1,6 +1,5 @@ { "organisation_name": "Your public sector organisation name, for example Government Digital Service", "organisation_handle": "Your GitHub/GitLab organisation name, for example ukgovdatascience", - "organisational_framework": ["GDS", "N/A"], "project_name": "your_new_project_name" } diff --git a/docs/contributing_guide/docs_contributor_README.md b/docs/contributing_guide/docs_contributor_README.md index 06d2260..2791a82 100644 --- a/docs/contributing_guide/docs_contributor_README.md +++ b/docs/contributing_guide/docs_contributor_README.md @@ -7,6 +7,5 @@ This is the contributor guide for the `govcookiecutter` project. ../CODE_OF_CONDUCT.md ../CONTRIBUTING.md ./modify_govcookiecutter.md -../{{ cookiecutter.project_name.lower().replace(' ', '_').replace('-', '_') }}/.govcookiecutter/organisational_frameworks/docs_repo_frameworks_README.md ``` diff --git a/docs/contributing_guide/modify_govcookiecutter.md b/docs/contributing_guide/modify_govcookiecutter.md index bb2d1e1..dcd8b09 100644 --- a/docs/contributing_guide/modify_govcookiecutter.md +++ b/docs/contributing_guide/modify_govcookiecutter.md @@ -197,7 +197,6 @@ then use semantic versioning to number our releases][semver]. This helps our use select a different version of `govcookiecutter` to use based on their individual needs. [cookiecutter]: https://cookiecutter.readthedocs.io -[docs-organisational-frameworks]: https://github.com/best-practice-and-impact/govcookiecutter/blob/main/docs/%7B%7B%20cookiecutter.repo_name%20%7D%7D/.govcookiecutter/organisational_frameworks/docs_repo_frameworks_README.md [github-issues]: https://github.com/best-practice-and-impact/govcookiecutter/issues [html5-email-format]: https://html.spec.whatwg.org/multipage/input.html#valid-e-mail-address [jinja]: https://jinja.palletsprojects.com diff --git a/docs/{{ cookiecutter.repo_name }}/.govcookiecutter/organisational_frameworks/docs_repo_frameworks_README.md b/docs/{{ cookiecutter.repo_name }}/.govcookiecutter/organisational_frameworks/docs_repo_frameworks_README.md deleted file mode 100644 index 648660d..0000000 --- a/docs/{{ cookiecutter.repo_name }}/.govcookiecutter/organisational_frameworks/docs_repo_frameworks_README.md +++ /dev/null @@ -1,2 +0,0 @@ -```{include} ../../../../{{ cookiecutter.project_name.lower().replace(' ', '_').replace('-', '_') }}/.govcookiecutter/organisational_frameworks/framework_README.md -``` diff --git a/docs/{{ cookiecutter.repo_name }}/dot_govcookiecutter.md b/docs/{{ cookiecutter.repo_name }}/dot_govcookiecutter.md index 52ef5b5..72fe5b6 100644 --- a/docs/{{ cookiecutter.repo_name }}/dot_govcookiecutter.md +++ b/docs/{{ cookiecutter.repo_name }}/dot_govcookiecutter.md @@ -4,16 +4,3 @@ Used in cookiecutter configuation for removing files in the created repository that are not required for users not using R. - -## organisational_frameworks/ - -Contains folders for organisation-specific frameworks. These allow for customisation of the created repository. -The folders require: - -- A template Analytical Quality Assurance (AQA) plan -- A template data log -- A template assumptions and caveats log -- A `pull_request_template.md` -- A `README.md`. - -`govcookiecutter` currently contains a Government Digital Service framework. diff --git a/hooks/__init__.py b/hooks/__init__.py index a94d332..d4d5baf 100644 --- a/hooks/__init__.py +++ b/hooks/__init__.py @@ -1,7 +1,6 @@ from hooks.post_gen_project import ( delete_files_and_folders, parse_features_json, - set_aqa_framework, ) from hooks.pre_gen_project import check_repo_name_structure @@ -9,5 +8,4 @@ "delete_files_and_folders", "check_repo_name_structure", "parse_features_json", - "set_aqa_framework", ) diff --git a/hooks/post_gen_project.py b/hooks/post_gen_project.py index fa9f0dc..3bbfd9f 100644 --- a/hooks/post_gen_project.py +++ b/hooks/post_gen_project.py @@ -24,32 +24,6 @@ def delete_files_and_folders(paths: Union[Path, str, List[Path], List[str]]) -> _ = [f.unlink() for f in paths if f.is_file() and f.exists()] -def set_aqa_framework( - dir_organisational_framework_aqa: Union[Path, str], - dir_cookiecutter_docs_aqa: Union[Path, str], -) -> None: - """Set a specific organisational analytical quality assurance (AQA) framework. - - Args: - dir_organisational_framework_aqa: A folder path that contains a specific - organisational AQA framework. - dir_cookiecutter_docs_aqa: A folder path within the outputted project - structure, where the contents of `dir_organisational_framework_aqa` will - reside. - - Returns: - The organisation-specific AQA framework in the outputted project structure's - `dir_cookiecutter_docs_aqa` folder. - - """ - - # Remove the default `docs/aqa` folder, and its contents - delete_files_and_folders(dir_cookiecutter_docs_aqa) - - # Copy the relevant organisational AQA framework to the `docs/aqa` folder - _ = Path(dir_organisational_framework_aqa).rename(dir_cookiecutter_docs_aqa) - - def parse_features_json(file: Union[Path, str]) -> List[Path]: """Parse a JSON file containing filepaths. @@ -82,21 +56,5 @@ def parse_features_json(file: Union[Path, str]) -> List[Path]: # Define the folder path to `.govcookiecutter` DIR_GOVCOOKIECUTTER = Path(".govcookiecutter") - # Check `{{ cookiecutter.organisational_framework }}` is not `N/A` - if "{{ cookiecutter.organisational_framework }}" != "N/A": - - # Define the folder path to the specific organisation framework of interest in - # the `organisational_frameworks` - # folder - DIR_ORGANISATIONAL_FRAMEWORKS = DIR_GOVCOOKIECUTTER.joinpath( - "organisational_frameworks", "{{ cookiecutter.organisational_framework }}" - ) - - # Transfer the `aqa` folder, and the pull/merge request templates to the - # correct folder paths - set_aqa_framework( - DIR_ORGANISATIONAL_FRAMEWORKS.joinpath("aqa"), Path("docs").joinpath("aqa") - ) - # Remove `DIR_GOVCOOKIECUTTER` delete_files_and_folders(DIR_GOVCOOKIECUTTER) diff --git a/tests/test_govcookiecutter_creation.py b/tests/test_govcookiecutter_creation.py index 1e33305..d697827 100644 --- a/tests/test_govcookiecutter_creation.py +++ b/tests/test_govcookiecutter_creation.py @@ -5,14 +5,6 @@ from sphinx.cmd.build import main -@pytest.mark.skip( - reason="Unclear how to test this, unless there is a title in each " "framework" -) -def test_organisational_framework_correct() -> None: - """Test that the correct organisational framework is built.""" - pass - - @pytest.mark.parametrize("test_input_repository_name", ["a", "b"]) def test_repo_name_directory_correct( cookies, @@ -56,11 +48,9 @@ def test_repo_name_directory_correct( @pytest.mark.parametrize("test_input_context", args_builds_correctly) -@pytest.mark.parametrize("test_input_organisational_framework", ["GDS", "N/A"]) def test_builds_correctly( cookies, test_input_context: Dict[str, str], - test_input_organisational_framework: str, ) -> None: """Test that the projects are built correctly with no errors.""" @@ -68,7 +58,6 @@ def test_builds_correctly( test_output_project = cookies.bake( extra_context={ **test_input_context, - "organisational_framework": test_input_organisational_framework, } ) diff --git a/tests/test_post_gen_project/test_set_aqa_framework.py b/tests/test_post_gen_project/test_set_aqa_framework.py deleted file mode 100644 index b434c96..0000000 --- a/tests/test_post_gen_project/test_set_aqa_framework.py +++ /dev/null @@ -1,91 +0,0 @@ -from pathlib import Path -from unittest.mock import MagicMock - -import pytest - -from hooks.post_gen_project import delete_files_and_folders, set_aqa_framework - - -@pytest.fixture -def patch_delete_files_and_folders(mocker) -> MagicMock: - """Patch the ``delete_files_and_folders`` function.""" - return mocker.patch( - "hooks.post_gen_project.delete_files_and_folders", - side_effect=delete_files_and_folders, - ) - - -# Define test cases for the `TestSetAqaFramework` test class -args_test_set_aqa_framework = ["hello", "world"] -args_test_set_aqa_framework_temporary_frameworks = [ - ("This is the request template.", "This is the AQA file."), - ("Here is the request template.", "Here is the AQA file."), -] - - -@pytest.mark.parametrize( - "test_input_dir_cookiecutter_docs_aqa", args_test_set_aqa_framework -) -@pytest.mark.parametrize( - "test_input_request_template, test_input_aqa", - args_test_set_aqa_framework_temporary_frameworks, -) -class TestSetAqaFramework: - def test_delete_files_and_folders_called_once_correctly( - self, - temporary_frameworks: Path, - patch_delete_files_and_folders: MagicMock, - test_input_dir_cookiecutter_docs_aqa: str, - ) -> None: - """Test the ``delete_files_and_folders`` function is called once correctly.""" - - # Define a path to the example output folder, which is the parent of - # `temporary_frameworks`, and create a directory with an example text file - dir_docs_aqa = temporary_frameworks.parent.joinpath( - test_input_dir_cookiecutter_docs_aqa - ) - dir_docs_aqa.mkdir() - dir_docs_aqa.joinpath("example.txt").write_text( - f"New file in: {repr(test_input_dir_cookiecutter_docs_aqa)}" - ) - - # Execute the `set_aqa_framework` function - set_aqa_framework(temporary_frameworks, dir_docs_aqa) - - # Assert `delete_files_and_folders` is called once correctly, then delete the - # output folder for the next test - # execution - patch_delete_files_and_folders.assert_called_once_with(dir_docs_aqa) - - def test_aqa_framework_folder_moved_correctly( - self, - temporary_frameworks: Path, - test_input_request_template: str, - test_input_aqa: str, - test_input_dir_cookiecutter_docs_aqa: str, - ) -> None: - """Test the right AQA framework folder is moved to the correct location.""" - - # Define a path to the example output folder, which is the parent of - # `temporary_frameworks`, and create a - # directory with an example text file - dir_docs_aqa = temporary_frameworks.parent.joinpath( - test_input_dir_cookiecutter_docs_aqa - ) - dir_docs_aqa.mkdir() - dir_docs_aqa.joinpath("example.txt").write_text( - f"New file in: {repr(test_input_dir_cookiecutter_docs_aqa)}" - ) - - # Execute the `set_aqa_framework` function - set_aqa_framework(temporary_frameworks, dir_docs_aqa) - - # Assert the correct text has been written - assert ( - dir_docs_aqa.joinpath("request_template.md").read_text() - == test_input_request_template - ) - assert dir_docs_aqa.joinpath("aqa", "aqa.md").read_text() == test_input_aqa - - # Assert the `dir_framework` has been removed - assert not temporary_frameworks.exists() diff --git a/{{ cookiecutter.project_name }}/.govcookiecutter/organisational_frameworks/GDS/aqa/aqa_plan.md b/{{ cookiecutter.project_name }}/.govcookiecutter/organisational_frameworks/GDS/aqa/aqa_plan.md deleted file mode 100644 index 3fa183d..0000000 --- a/{{ cookiecutter.project_name }}/.govcookiecutter/organisational_frameworks/GDS/aqa/aqa_plan.md +++ /dev/null @@ -1,12 +0,0 @@ -# Analytical quality assurance plan - -This analytical quality assurance (AQA) plan outlines [our implementation of the -Aqua Book][aqua-book] for this project. [Further resources related to the Aqua Book -are also available on GOV.UK][aqua-book-resources]. - -This is a living document, and should be updated and/or modified as necessary. For -example if new tasks not listed here become relevant to project success, please add -them to this plan. - -[aqua-book]: https://www.gov.uk/government/publications/the-aqua-book-guidance-on-producing-quality-analysis-for-government -[aqua-book-resources]: https://www.gov.uk/government/collections/aqua-book-resources diff --git a/{{ cookiecutter.project_name }}/.govcookiecutter/organisational_frameworks/GDS/aqa/assumptions_caveats.md b/{{ cookiecutter.project_name }}/.govcookiecutter/organisational_frameworks/GDS/aqa/assumptions_caveats.md deleted file mode 100644 index 30a5d03..0000000 --- a/{{ cookiecutter.project_name }}/.govcookiecutter/organisational_frameworks/GDS/aqa/assumptions_caveats.md +++ /dev/null @@ -1,30 +0,0 @@ -# Assumptions and caveats log - -This log contains a list of assumptions and caveats used in this analysis. - -## Definitions - -Assumptions are RAG-rated according to the following definitions for quality and -impact[^1]: - -[^1]: With thanks to the Home Office Analytical Quality Assurance team for these definitions. - -| RAG | Assumption quality | Assumption impact | -|-------|---------------------------------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------| -| Green | Reliable assumption, well understood and/or documented; anything up to a validated & recent set of actual data. | Marginal assumptions; their changes have no or limited impact on the outputs. | -| Amber | Some evidence to support the assumption; may vary from a source with poor methodology to a good source that is a few years old. | Assumptions with a relevant, even if not critical, impact on the outputs. | -| Red | Little evidence to support the assumption; may vary from an opinion to a limited data source with poor methodology. | Core assumptions of the analysis; the output would be drastically affected by their change. | - -## Assumption 1: Insert plain English title here - -* Quality: Insert RAG rating here -* Impact: Insert RAG rating here - -Add plain English description here. - -## Assumption 2: Insert plain English title here - -* Quality: Insert RAG rating here -* Impact: Insert RAG rating here - -Add plain English description here. diff --git a/{{ cookiecutter.project_name }}/.govcookiecutter/organisational_frameworks/GDS/aqa/data_log.md b/{{ cookiecutter.project_name }}/.govcookiecutter/organisational_frameworks/GDS/aqa/data_log.md deleted file mode 100644 index 0a020f8..0000000 --- a/{{ cookiecutter.project_name }}/.govcookiecutter/organisational_frameworks/GDS/aqa/data_log.md +++ /dev/null @@ -1,30 +0,0 @@ -# Data log - -This log contains a list of data sources used in this analysis. - -## Definitions - -Assumptions are RAG-rated according to the following definitions for quality and -suitability[^1]: - -[^1]: With thanks to the Home Office Analytical Quality Assurance team for these definitions. - -| RAG | Data quality | Data suitability | -|-------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| Green | Data is well understood and there are no major issues with quality. Minor issues are understood and documented. | Data is best available for the required purpose and has been validated (for example against published statistics). | -| Amber | Data is well understood. There are quality issues (for example missing values, step changes, large number of outliers) that can be explained, documented or shown to have negligible impact. | Not the ideal data set for the analysis, but the best available at the time. Results will reflect the fact that it is not the ideal data set and it will subject to sensitivity analysis where appropriate. | -| Red | Data is not well understood. There are major quality issues that cannot be fully explained and/or have a significant impact on analysis outputs. | There are concerns about the suitability of the data set for this application, which could negatively affect the quality and accuracy of the analysis. Its derivation / sample size is not known. | - -## Source 1: Insert plain English title here - -* Quality: Insert RAG rating here -* Suitability: Insert RAG rating here - -Add plain English description here. - -### Source 2: Insert plain English title here - -* Quality: Insert RAG rating here -* Suitability: Insert RAG rating here - -Add plain English description here. diff --git a/{{ cookiecutter.project_name }}/.govcookiecutter/organisational_frameworks/GDS/request_template.md b/{{ cookiecutter.project_name }}/.govcookiecutter/organisational_frameworks/GDS/request_template.md deleted file mode 100644 index a6fc3c0..0000000 --- a/{{ cookiecutter.project_name }}/.govcookiecutter/organisational_frameworks/GDS/request_template.md +++ /dev/null @@ -1,34 +0,0 @@ -# Summary - -Add your summary here - keep it brief, to the point, and in plain English. [For further -information about pull requests, check out the GDS -Way](https://gds-way.cloudapps.digital/standards/pull-requests.html). - -# Checklists - - - -This pull/merge request meets the following requirements: - -- [ ] code runs -- [ ] [developments are ethical][data-ethics-framework] and secure -- [ ] you have made proportionate checks that the code works correctly -- [ ] test suite passes -- [ ] developments adhere to AQA plan (see `docs/aqa/aqa_plan.md`) -- [ ] data log updated (see `docs/aqa/data_log.md`), if necessary -- [ ] assumptions, and caveats log updated (see `docs/aqa/assumptions_caveats.md`), if - necessary -- [ ] [minimum usable documentation][agilemodeling] written in the `docs` folder - -Comments have been added below around the incomplete checks. - -[agilemodeling]: http://agilemodeling.com/essays/documentLate.htm -[data-ethics-framework]: https://www.gov.uk/government/publications/data-ethics-framework diff --git a/{{ cookiecutter.project_name }}/.govcookiecutter/organisational_frameworks/framework_README.md b/{{ cookiecutter.project_name }}/.govcookiecutter/organisational_frameworks/framework_README.md deleted file mode 100644 index 4e3725b..0000000 --- a/{{ cookiecutter.project_name }}/.govcookiecutter/organisational_frameworks/framework_README.md +++ /dev/null @@ -1,31 +0,0 @@ -# `organisation_frameworks` folder - -This folder contains all organisation-specific frameworks. Each sub-folder is named for -an organisation, and the name must be listed in the `organisational_framework` variable -in the root-level `cookiecutter.json` file to be used; see the `GDS` folder for an -example framework structure. - -## Analytical quality assurance (AQA) framework - -Within each organisation folder, there must be a `aqa` folder that contains templates -for the: - -- analytical quality assurance (AQA) plan; -- data log; and -- assumptions and caveats log. - -It must also include a `README.md` to link the AQA templates together using in -[MyST syntax][myst-parser]. - -## Pull or merge request template - -A `request_template.md` file must be included in each organisation folder. This will be -used to create a pull (GitHub) or merge (GitLab) request template in the project -structure created by `govcookiecutter`. - -You should include hints, and nudges to make sure contributors to your organisation's -projects follow its AQA framework. - -[aqua-book]: https://www.gov.uk/government/publications/the-aqua-book-guidance-on-producing-quality-analysis-for-government -[aqua-book-resources]: https://www.gov.uk/government/collections/aqua-book-resources -[myst-parser]: https://myst-parser.readthedocs.io/ diff --git a/{{ cookiecutter.project_name }}/docs/aqa/assumptions_caveats.md b/{{ cookiecutter.project_name }}/docs/aqa/assumptions_caveats.md index 2ec9d5c..30a5d03 100644 --- a/{{ cookiecutter.project_name }}/docs/aqa/assumptions_caveats.md +++ b/{{ cookiecutter.project_name }}/docs/aqa/assumptions_caveats.md @@ -1,3 +1,30 @@ # Assumptions and caveats log This log contains a list of assumptions and caveats used in this analysis. + +## Definitions + +Assumptions are RAG-rated according to the following definitions for quality and +impact[^1]: + +[^1]: With thanks to the Home Office Analytical Quality Assurance team for these definitions. + +| RAG | Assumption quality | Assumption impact | +|-------|---------------------------------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------| +| Green | Reliable assumption, well understood and/or documented; anything up to a validated & recent set of actual data. | Marginal assumptions; their changes have no or limited impact on the outputs. | +| Amber | Some evidence to support the assumption; may vary from a source with poor methodology to a good source that is a few years old. | Assumptions with a relevant, even if not critical, impact on the outputs. | +| Red | Little evidence to support the assumption; may vary from an opinion to a limited data source with poor methodology. | Core assumptions of the analysis; the output would be drastically affected by their change. | + +## Assumption 1: Insert plain English title here + +* Quality: Insert RAG rating here +* Impact: Insert RAG rating here + +Add plain English description here. + +## Assumption 2: Insert plain English title here + +* Quality: Insert RAG rating here +* Impact: Insert RAG rating here + +Add plain English description here. diff --git a/{{ cookiecutter.project_name }}/docs/aqa/data_log.md b/{{ cookiecutter.project_name }}/docs/aqa/data_log.md index a73f169..0a020f8 100644 --- a/{{ cookiecutter.project_name }}/docs/aqa/data_log.md +++ b/{{ cookiecutter.project_name }}/docs/aqa/data_log.md @@ -1,3 +1,30 @@ # Data log This log contains a list of data sources used in this analysis. + +## Definitions + +Assumptions are RAG-rated according to the following definitions for quality and +suitability[^1]: + +[^1]: With thanks to the Home Office Analytical Quality Assurance team for these definitions. + +| RAG | Data quality | Data suitability | +|-------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| Green | Data is well understood and there are no major issues with quality. Minor issues are understood and documented. | Data is best available for the required purpose and has been validated (for example against published statistics). | +| Amber | Data is well understood. There are quality issues (for example missing values, step changes, large number of outliers) that can be explained, documented or shown to have negligible impact. | Not the ideal data set for the analysis, but the best available at the time. Results will reflect the fact that it is not the ideal data set and it will subject to sensitivity analysis where appropriate. | +| Red | Data is not well understood. There are major quality issues that cannot be fully explained and/or have a significant impact on analysis outputs. | There are concerns about the suitability of the data set for this application, which could negatively affect the quality and accuracy of the analysis. Its derivation / sample size is not known. | + +## Source 1: Insert plain English title here + +* Quality: Insert RAG rating here +* Suitability: Insert RAG rating here + +Add plain English description here. + +### Source 2: Insert plain English title here + +* Quality: Insert RAG rating here +* Suitability: Insert RAG rating here + +Add plain English description here. diff --git a/{{ cookiecutter.project_name }}/.govcookiecutter/organisational_frameworks/GDS/aqa/gds_aqa_README.md b/{{ cookiecutter.project_name }}/docs/aqa/gds_aqa_README.md similarity index 100% rename from {{ cookiecutter.project_name }}/.govcookiecutter/organisational_frameworks/GDS/aqa/gds_aqa_README.md rename to {{ cookiecutter.project_name }}/docs/aqa/gds_aqa_README.md