From 6861170cd7f21e6ef4153993fe996396ed2ab328 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89rico=20Andrei?= Date: Thu, 16 May 2024 19:41:37 +0200 Subject: [PATCH] Improve project generation --- Makefile | 8 ++ backend_addon/cookiecutter.json | 1 + backend_addon/hooks/post_gen_project.py | 8 +- .../MANIFEST.in | 2 +- .../{{ cookiecutter.__folder_name }}/Makefile | 4 - .../.pre-commit-config.yaml | 7 ++ project/cookiecutter.json | 1 + project/hooks/post_gen_project.py | 17 ++-- project/hooks/pre_gen_project.py | 4 +- project/tests/conftest.py | 13 --- project/tests/test_project_backend.py | 34 +++----- .../.pre-commit-config.yaml | 16 ++++ .../{{ cookiecutter.__folder_name }}/Makefile | 87 ++++++++++--------- .../README.md | 10 +-- .../backend/Makefile | 44 ++-------- .../hooks/post_gen_project.py | 4 +- sub/frontend_project/hooks/pre_gen_project.py | 4 +- 17 files changed, 129 insertions(+), 135 deletions(-) create mode 100644 frontend_addon/{{ cookiecutter.__folder_name }}/.pre-commit-config.yaml create mode 100644 project/{{ cookiecutter.__folder_name }}/.pre-commit-config.yaml diff --git a/Makefile b/Makefile index ffd6e4f..bc85565 100644 --- a/Makefile +++ b/Makefile @@ -46,6 +46,14 @@ test: bin/cookieplone ## Test all cookiecutters $(foreach project,$(TOP_LEVEL_TEMPLATES),$(MAKE) -C "./$(project)/" test ;) $(foreach project,$(SUB_TEMPLATES),$(MAKE) -C "./sub/$(project)/" test ;) +.PHONY: test-pdb +test-pdb: bin/cookieplone ## Test all cookiecutters (and stop on error) + @echo "$(GREEN)==> Test all cookiecutters (and stop on error)$(RESET)" + bin/python3 -m pytest tests -x --pdb + $(foreach project,$(TOP_LEVEL_TEMPLATES),$(MAKE) -C "./$(project)/" test-pdb ;) + $(foreach project,$(SUB_TEMPLATES),$(MAKE) -C "./sub/$(project)/" test-pdb ;) + + .PHONY: report-context report-context: bin/cookieplone ## Generate a report of all context options @echo "$(GREEN)==> Generate a report of all context options$(RESET)" diff --git a/backend_addon/cookiecutter.json b/backend_addon/cookiecutter.json index fbcbd0a..8485539 100644 --- a/backend_addon/cookiecutter.json +++ b/backend_addon/cookiecutter.json @@ -19,6 +19,7 @@ "__generator_date_short": "{% now 'utc', '%Y-%m-%d' %}", "__generator_date_long": "{% now 'utc', '%Y-%m-%d %H:%M:%S' %}", "__generator_signature": "This was generated by [cookiecutter-plone](https://github.com/plone/cookieplone-templates/backend_addon) on {{ cookiecutter.__generator_date_long }}", + "__backend_addon_git_initialize": "1", "__prompts__": { "title": "Addon Title", "description": "A short description of your addon", diff --git a/backend_addon/hooks/post_gen_project.py b/backend_addon/hooks/post_gen_project.py index 2f44baa..1c1d11f 100644 --- a/backend_addon/hooks/post_gen_project.py +++ b/backend_addon/hooks/post_gen_project.py @@ -2,10 +2,13 @@ import subprocess import sys +from collections import OrderedDict from pathlib import Path from cookieplone.utils import console, files +context: OrderedDict = {{cookiecutter}} + # PATH OF CONTENT TO BE REMOVED TO_REMOVE_PATHS = { "feature_headless": [ @@ -48,10 +51,11 @@ def initialize_git(): def main(): """Final fixes.""" - keep_headless = int("{{ cookiecutter.feature_headless }}") + keep_headless = int(context.get("feature_headless")) if not keep_headless: remove_files("feature_headless") - initialize_git() + if int(context.get("__backend_addon_git_initialize")): + initialize_git() msg = """ [bold blue]{{ cookiecutter.title }}[/bold blue] diff --git a/backend_addon/{{ cookiecutter.__folder_name }}/MANIFEST.in b/backend_addon/{{ cookiecutter.__folder_name }}/MANIFEST.in index 8c760dd..40ac789 100644 --- a/backend_addon/{{ cookiecutter.__folder_name }}/MANIFEST.in +++ b/backend_addon/{{ cookiecutter.__folder_name }}/MANIFEST.in @@ -1,4 +1,4 @@ -graft src/{{ cookiecutter.github_organization }} +graft src/{{ cookiecutter.__package_namespace }} graft docs graft news graft tests diff --git a/backend_addon/{{ cookiecutter.__folder_name }}/Makefile b/backend_addon/{{ cookiecutter.__folder_name }}/Makefile index 82e7ca3..1d7c8a3 100644 --- a/backend_addon/{{ cookiecutter.__folder_name }}/Makefile +++ b/backend_addon/{{ cookiecutter.__folder_name }}/Makefile @@ -15,10 +15,6 @@ GREEN=`tput setaf 2` RESET=`tput sgr0` YELLOW=`tput setaf 3` -# Set distributions still in development -DISTRIBUTIONS="{{ cookiecutter.__package_name }}" -ALLOWED_DISTRIBUTIONS="{{ cookiecutter.__package_name }}" - PLONE6=6.0-latest # Python checks diff --git a/frontend_addon/{{ cookiecutter.__folder_name }}/.pre-commit-config.yaml b/frontend_addon/{{ cookiecutter.__folder_name }}/.pre-commit-config.yaml new file mode 100644 index 0000000..e09f255 --- /dev/null +++ b/frontend_addon/{{ cookiecutter.__folder_name }}/.pre-commit-config.yaml @@ -0,0 +1,7 @@ +repos: + - repo: https://github.com/pre-commit/mirrors-eslint + rev: 'v9.2.0' + hooks: + - id: eslint + files: '^packages/.*/src/.*/*.(js,jsx,ts,tsx)$' + types: [file] diff --git a/project/cookiecutter.json b/project/cookiecutter.json index 99c61e7..2fe704a 100644 --- a/project/cookiecutter.json +++ b/project/cookiecutter.json @@ -48,6 +48,7 @@ "__generator_date_short": "{% now 'utc', '%Y-%m-%d' %}", "__generator_date_long": "{% now 'utc', '%Y-%m-%d %H:%M:%S' %}", "__generator_signature": "This was generated by [cookieplone-templates](https://github.com/plone/cookieplone-templates) on {{ cookiecutter.__generator_date_long }}", + "__pre_commit_version": "3.7.1", "__gha_enable": true, "__gha_version_checkout": "v4", "__gha_version_docker_stack": "v1.2.0", diff --git a/project/hooks/post_gen_project.py b/project/hooks/post_gen_project.py index 42bd7d4..b9c633e 100644 --- a/project/hooks/post_gen_project.py +++ b/project/hooks/post_gen_project.py @@ -1,17 +1,21 @@ """Post generation hook.""" -from collections import OrderedDict # noQA +from collections import OrderedDict from copy import deepcopy from pathlib import Path from cookieplone import generator from cookieplone.utils import console, files -context = {{cookiecutter}} +context: OrderedDict = {{cookiecutter}} -SUB_PROJECT_REMOVE = [".github"] +BACKEND_ADDON_REMOVE = [ + ".github", + ".git" +] +FRONTEND_ADDON_REMOVE = [".github"] DEVOPS_TO_REMOVE = { "ansible": [ @@ -51,15 +55,18 @@ def generate_backend_addon(context, output_dir): # Go to backend/src/ output_dir = output_dir / "backend" / "src" folder_name = context.get("python_package_name") + # Do not initialize the repository + context["__backend_addon_git_initialize"] = "0" generator.generate_subtemplate( - "backend_addon", output_dir, folder_name, context, SUB_PROJECT_REMOVE + "backend_addon", output_dir, folder_name, context, BACKEND_ADDON_REMOVE ) + files.remove_files(output_dir / folder_name, BACKEND_ADDON_REMOVE) def generate_frontend_addon(context, output_dir): """Run volto generator.""" generator.generate_subtemplate( - "frontend_addon", output_dir, "frontend", context, SUB_PROJECT_REMOVE + "frontend_addon", output_dir, "frontend", context, FRONTEND_ADDON_REMOVE ) diff --git a/project/hooks/pre_gen_project.py b/project/hooks/pre_gen_project.py index 8044bf7..2c666e3 100644 --- a/project/hooks/pre_gen_project.py +++ b/project/hooks/pre_gen_project.py @@ -1,7 +1,7 @@ """Pre generation hook.""" import sys -from collections import OrderedDict # noQA +from collections import OrderedDict from pathlib import Path from textwrap import dedent @@ -10,7 +10,7 @@ output_path = Path().resolve() -context = {{cookiecutter}} +context: OrderedDict = {{cookiecutter}} def check_errors(context: dict) -> data.ContextValidatorResult: diff --git a/project/tests/conftest.py b/project/tests/conftest.py index 8696462..bd9bf18 100644 --- a/project/tests/conftest.py +++ b/project/tests/conftest.py @@ -38,13 +38,6 @@ def context(cookieplone_root) -> dict: } -@pytest.fixture(scope="session") -def context_unittest(context) -> dict: - """Cookiecutter context.""" - new_context = deepcopy(context) - new_context["python_test_framework"] = "unittest" - return new_context - @pytest.fixture(scope="session") def context_devops_cache(context) -> dict: @@ -104,12 +97,6 @@ def cutter_result(cookies_session, context): return cookies_session.bake(extra_context=context) -@pytest.fixture(scope="session") -def cutter_result_unittest(cookies_session, context_unittest): - """Cookiecutter result.""" - return cookies_session.bake(extra_context=context_unittest) - - @pytest.fixture(scope="session") def cutter_result_devops_no_ansible(cookies_session, context_devops_no_ansible): """Cookiecutter result.""" diff --git a/project/tests/test_project_backend.py b/project/tests/test_project_backend.py index 0ec8ec9..745bbb5 100644 --- a/project/tests/test_project_backend.py +++ b/project/tests/test_project_backend.py @@ -28,11 +28,11 @@ def test_backend_top_level_files(cutter_result, filename: str): BACKEND_PACKAGE_FILES_PYTEST = [ "src/ploneorgbr/setup.py", - "src/ploneorgbr/src/ploneorgbr/configure.zcml", - "src/ploneorgbr/src/ploneorgbr/dependencies.zcml", - "src/ploneorgbr/src/ploneorgbr/permissions.zcml", - "src/ploneorgbr/src/ploneorgbr/profiles.zcml", - "src/ploneorgbr/src/ploneorgbr/testing.py", + "src/plonegov.ploneorgbr/src/plonegov/ploneorgbr/configure.zcml", + "src/plonegov.ploneorgbr/src/plonegov/ploneorgbr/dependencies.zcml", + "src/plonegov.ploneorgbr/src/plonegov/ploneorgbr/permissions.zcml", + "src/plonegov.ploneorgbr/src/plonegov/ploneorgbr/profiles.zcml", + "src/plonegov.ploneorgbr/src/plonegov/ploneorgbr/testing.py", "src/ploneorgbr/tests/conftest.py", "src/ploneorgbr/tests/setup/test_setup_install.py", "src/ploneorgbr/tests/setup/test_setup_uninstall.py", @@ -47,21 +47,15 @@ def test_backend_package_files_pytest(cutter_result, filename: str): assert path.is_file() -BACKEND_PACKAGE_FILES_PYTEST = [ - "src/ploneorgbr/setup.py", - "src/ploneorgbr/src/ploneorgbr/configure.zcml", - "src/ploneorgbr/src/ploneorgbr/dependencies.zcml", - "src/ploneorgbr/src/ploneorgbr/permissions.zcml", - "src/ploneorgbr/src/ploneorgbr/profiles.zcml", - "src/ploneorgbr/src/ploneorgbr/testing.py", - "src/ploneorgbr/src/ploneorgbr/tests/__init__.py", - "src/ploneorgbr/src/ploneorgbr/tests/test_setup.py", +FILES_TO_BE_REMOVED = [ + "src/plonegov.ploneorgbr/.github", + "src/plonegov.ploneorgbr/.git", ] - -@pytest.mark.parametrize("filename", BACKEND_FILES) -def test_backend_package_files_unittest(cutter_result_unittest, filename: str): - """Test backend package files.""" - backend_folder = cutter_result_unittest.project_path / "backend" +@pytest.mark.parametrize("filename", FILES_TO_BE_REMOVED) +def test_backend_package_files_removed(cutter_result, filename: str): + """Test backend package files are removed.""" + backend_folder = cutter_result.project_path / "backend" path = backend_folder / filename - assert path.is_file() + assert path.exists() is False + assert path.parent.exists() diff --git a/project/{{ cookiecutter.__folder_name }}/.pre-commit-config.yaml b/project/{{ cookiecutter.__folder_name }}/.pre-commit-config.yaml new file mode 100644 index 0000000..f66eb48 --- /dev/null +++ b/project/{{ cookiecutter.__folder_name }}/.pre-commit-config.yaml @@ -0,0 +1,16 @@ +repos: + - repo: https://github.com/ddanier/sub-pre-commit.git + rev: v{{ cookiecutter.__pre_commit_version }} # MUST match your pre-commit version + hooks: + - id: sub-pre-commit + alias: backend + name: "pre-commit for backend/" + args: ["-p", "backend/src/ploneorg.brasil"] + files: "^backend/src/ploneorg.brasil/.*" + stages: ["commit"] + - id: sub-pre-commit + alias: frontend + name: "pre-commit for frontend" + args: ["-p", "frontend"] + files: "^frontend/.*" + stages: ["commit"] diff --git a/project/{{ cookiecutter.__folder_name }}/Makefile b/project/{{ cookiecutter.__folder_name }}/Makefile index 51da073..b57d949 100644 --- a/project/{{ cookiecutter.__folder_name }}/Makefile +++ b/project/{{ cookiecutter.__folder_name }}/Makefile @@ -9,10 +9,13 @@ MAKEFLAGS+=--warn-undefined-variables MAKEFLAGS+=--no-builtin-rules CURRENT_DIR:=$(shell dirname $(realpath $(lastword $(MAKEFILE_LIST)))) +GIT_FOLDER=$(BACKEND_FOLDER)/.git PROJECT_NAME={{ cookiecutter.project_slug }} STACK_NAME={{ cookiecutter.__devops_stack_name }} +PRE_COMMIT = pipx run --spec "pre-commit=={{ cookiecutter.__pre_commit_version }}" + # We like colors # From: https://coderwall.com/p/izxssa/colored-makefile-for-golang-projects RED=`tput setaf 1` @@ -21,7 +24,7 @@ RESET=`tput sgr0` YELLOW=`tput setaf 3` .PHONY: all -all: build +all: install # Add the following 'help' target to your Makefile # And add help text after each target name starting with '\#\#' @@ -29,50 +32,58 @@ all: build help: ## This help message @grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}' -.PHONY: install-frontend -install-frontend: ## Install React Frontend +########################################### +# Frontend +########################################### +.PHONY: frontend-install +frontend-install: ## Install React Frontend $(MAKE) -C "./frontend/" install -.PHONY: build-frontend -build-frontend: ## Build React Frontend +.PHONY: frontend-build +frontend-build: ## Build React Frontend $(MAKE) -C "./frontend/" build -.PHONY: start-frontend -start-frontend: ## Start React Frontend +.PHONY: frontend-start +frontend-start: ## Start React Frontend $(MAKE) -C "./frontend/" start -.PHONY: install-backend -install-backend: ## Create virtualenv and install Plone - $(MAKE) -C "./backend/" build-dev - $(MAKE) create-site +.PHONY: frontend-test +frontend-test: ## Test frontend codebase + @echo "Test frontend" + $(MAKE) -C "./frontend/" test -.PHONY: build-backend -build-backend: ## Build Backend - $(MAKE) -C "./backend/" build-dev +########################################### +# Backend +########################################### +.PHONY: backend-install +backend-install: ## Create virtualenv and install Plone + $(MAKE) -C "./backend/" install + $(MAKE) backend-create-site -.PHONY: create-site -create-site: ## Create a Plone site with default content +.PHONY: backend-build +backend-build: ## Build Backend + $(MAKE) -C "./backend/" install + +.PHONY: backend-create-site +backend-create-site: ## Create a Plone site with default content $(MAKE) -C "./backend/" create-site -.PHONY: start-backend -start-backend: ## Start Plone Backend +.PHONY: backend-start +backend-start: ## Start Plone Backend $(MAKE) -C "./backend/" start +.PHONY: backend-test +backend-test: ## Test backend codebase + @echo "Test backend" + $(MAKE) -C "./backend/" test + .PHONY: install install: ## Install @echo "Install Backend & Frontend" + if [ -d $(GIT_FOLDER) ]; then $(PRE_COMMIT) install; else echo "$(RED) Not installing pre-commit$(RESET)";fi $(MAKE) install-backend $(MAKE) install-frontend -# TODO production build - -.PHONY: build -build: ## Build in development mode - @echo "Build" - $(MAKE) build-backend - $(MAKE) install-frontend - - .PHONY: start start: ## Start @echo "Starting application" @@ -85,11 +96,11 @@ clean: ## Clean installation $(MAKE) -C "./backend/" clean $(MAKE) -C "./frontend/" clean -.PHONY: format -format: ## Format codebase - @echo "Format codebase" - $(MAKE) -C "./backend/" format - $(MAKE) -C "./frontend/" format +.PHONY: check +check: ## Lint and Format codebase + @echo "Lint and Format codebase" + $(MAKE) -C "./backend/" check + $(MAKE) -C "./frontend/" check .PHONY: i18n i18n: ## Update locales @@ -97,18 +108,8 @@ i18n: ## Update locales $(MAKE) -C "./backend/" i18n $(MAKE) -C "./frontend/" i18n -.PHONY: test-backend -test-backend: ## Test backend codebase - @echo "Test backend" - $(MAKE) -C "./backend/" test - -.PHONY: test-frontend -test-frontend: ## Test frontend codebase - @echo "Test frontend" - $(MAKE) -C "./frontend/" test - .PHONY: test -test: test-backend test-frontend ## Test codebase +test: backend-test frontend-test ## Test codebase .PHONY: build-images build-images: ## Build docker images diff --git a/project/{{ cookiecutter.__folder_name }}/README.md b/project/{{ cookiecutter.__folder_name }}/README.md index 8b74a0f..316ed40 100644 --- a/project/{{ cookiecutter.__folder_name }}/README.md +++ b/project/{{ cookiecutter.__folder_name }}/README.md @@ -1,6 +1,6 @@ # {{ cookiecutter.title }} 🚀 -[![Built with Cookiecutter Plone Starter](https://img.shields.io/badge/built%20with-Cookiecutter%20Plone%20Starter-0083be.svg?logo=cookiecutter)](https://github.com/plone/cookiecutter-plone/) +[![Built with Cookieplone](https://img.shields.io/badge/built%20with-Cookieplone-0083be.svg?logo=cookiecutter)](https://github.com/plone/cookiecutter-plone/) [![Black code style](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/ambv/black) [![Backend Tests](https://github.com/{{ cookiecutter.github_organization }}/{{ cookiecutter.project_slug }}/actions/workflows/backend.yml/badge.svg)](https://github.com/{{ cookiecutter.github_organization }}/{{ cookiecutter.project_slug }}/actions/workflows/backend.yml) [![Frontend Tests](https://github.com/{{ cookiecutter.github_organization }}/{{ cookiecutter.project_slug }}/actions/workflows/frontend.yml/badge.svg)](https://github.com/{{ cookiecutter.github_organization }}/{{ cookiecutter.project_slug }}/actions/workflows/frontend.yml) @@ -38,19 +38,19 @@ make install 1. Create a new Plone site on your first run: ```shell -make create-site +make backend-create-site ``` 2. Start the Backend at [http://localhost:8080/](http://localhost:8080/): ```shell -make start-backend +make backend-start ``` 3. In a new terminal, start the Frontend at [http://localhost:3000/](http://localhost:3000/): ```shell -make start-frontend +make frontend-start ``` Voila! Your Plone site should be live and kicking! 🎉 @@ -92,7 +92,7 @@ This monorepo consists of three distinct sections: `backend`, `frontend`, and `d To automatically format your code and ensure it adheres to quality standards, execute: ```shell -make format +make check ``` Linters can be run individually within the `backend` or `frontend` folders. diff --git a/project/{{ cookiecutter.__folder_name }}/backend/Makefile b/project/{{ cookiecutter.__folder_name }}/backend/Makefile index dda6fe0..c4f0ce7 100644 --- a/project/{{ cookiecutter.__folder_name }}/backend/Makefile +++ b/project/{{ cookiecutter.__folder_name }}/backend/Makefile @@ -16,17 +16,12 @@ RESET=`tput sgr0` YELLOW=`tput setaf 3` BACKEND_FOLDER=$(shell dirname $(realpath $(firstword $(MAKEFILE_LIST)))) - +REPO_ROOT=../ PLONE_VERSION=$$(cat version.txt) -CODE_QUALITY_VERSION=2.1 ifndef LOG_LEVEL LOG_LEVEL=INFO endif -CURRENT_USER=$$(whoami) -USER_INFO=$$(id -u ${CURRENT_USER}) -LINT=docker run --rm -e LOG_LEVEL="${LOG_LEVEL}" -v "${BACKEND_FOLDER}":/github/workspace plone/code-quality:${CODE_QUALITY_VERSION} check -FORMAT=docker run --rm --user="${USER_INFO}" -e LOG_LEVEL="${LOG_LEVEL}" -v "${BACKEND_FOLDER}":/github/workspace plone/code-quality:${CODE_QUALITY_VERSION} format IMAGE_NAME={{ cookiecutter.__container_image_prefix }}-backend IMAGE_TAG=latest @@ -84,15 +79,15 @@ clean-test: ## remove test and coverage artifacts rm -f .coverage rm -fr htmlcov/ -bin/pip: +bin/pipx: @echo "$(GREEN)==> Setup Virtual Env$(RESET)" $(PYTHON) -m venv . - bin/pip install -U "pip" "wheel" "cookiecutter" "mxdev" + bin/pip install -U "pip" "wheel" "pipx" "mxdev" .PHONY: config config: bin/pip ## Create instance configuration @echo "$(GREEN)==> Create instance configuration$(RESET)" - bin/cookiecutter -f --no-input --config-file instance.yaml gh:plone/cookiecutter-zope-instance + bin/pipx run cookiecutter -f --no-input --config-file instance.yaml gh:plone/cookiecutter-zope-instance # i18n bin/i18ndude: bin/pip @@ -113,33 +108,10 @@ build-dev: config ## pip install Plone packages bin/mxdev -c mx.ini bin/pip install -r requirements-mxdev.txt -.PHONY: format -format: ## Format the codebase according to our standards - @echo "$(GREEN)==> Format codebase$(RESET)" - $(FORMAT) - -.PHONY: lint -lint: lint-isort lint-black lint-flake8 lint-zpretty ## check code style - -.PHONY: lint-black -lint-black: ## validate black formating - $(LINT) black - -.PHONY: lint-flake8 -lint-flake8: ## validate black formating - $(LINT) flake8 - -.PHONY: lint-isort -lint-isort: ## validate using isort - $(LINT) isort - -.PHONY: lint-pyroma -lint-pyroma: ## validate using pyroma - $(LINT) pyroma - -.PHONY: lint-zpretty -lint-zpretty: ## validate ZCML/XML using zpretty - $(LINT) zpretty +.PHONY: check +check: ## Format the codebase according to our standards + @echo "$(GREEN)==> Lint and Format codebase$(RESET)" + $(MAKE) -C $(REPO_ROOT) check .PHONY: test test: ## run tests diff --git a/sub/frontend_project/hooks/post_gen_project.py b/sub/frontend_project/hooks/post_gen_project.py index c242e58..3cfc39e 100644 --- a/sub/frontend_project/hooks/post_gen_project.py +++ b/sub/frontend_project/hooks/post_gen_project.py @@ -1,12 +1,12 @@ """Post generation hook.""" -from collections import OrderedDict # noQA +from collections import OrderedDict from pathlib import Path from cookieplone import generator from cookieplone.utils import console, files -context = {{cookiecutter}} +context: OrderedDict = {{cookiecutter}} LOCAL_FILES_FOLDER_NAME = "_project_files" diff --git a/sub/frontend_project/hooks/pre_gen_project.py b/sub/frontend_project/hooks/pre_gen_project.py index ef1e248..989e6a8 100644 --- a/sub/frontend_project/hooks/pre_gen_project.py +++ b/sub/frontend_project/hooks/pre_gen_project.py @@ -1,7 +1,7 @@ """Pre generation hook.""" import sys -from collections import OrderedDict # noQA +from collections import OrderedDict from pathlib import Path from textwrap import dedent @@ -10,7 +10,7 @@ output_path = Path().resolve() -context = {{cookiecutter}} +context: OrderedDict = {{cookiecutter}} def check_errors(context: dict) -> data.ContextValidatorResult: