diff --git a/news/221.bugfix b/news/221.bugfix new file mode 100644 index 00000000..903d7ee6 --- /dev/null +++ b/news/221.bugfix @@ -0,0 +1 @@ +Standardize usage of the repository URLs in templates. @ericof diff --git a/pyproject.toml b/pyproject.toml index caa2d99a..f68840e5 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -5,7 +5,7 @@ description = "Collection of templates for Plone integrators to use through Cook readme = "README.md" requires-python = ">=3.10" dependencies = [ - "cookieplone>=0.9.6", + "cookieplone>=0.9.7", "gitpython>=3.1.43", "pytest>=8.3.5", "pytest-cookies>=0.7.0", diff --git a/templates/add-ons/backend/cookiecutter.json b/templates/add-ons/backend/cookiecutter.json index 6b7b3117..0758b267 100644 --- a/templates/add-ons/backend/cookiecutter.json +++ b/templates/add-ons/backend/cookiecutter.json @@ -12,6 +12,7 @@ "initialize_documentation": ["1", "0"], "__project_slug": "{{ cookiecutter.python_package_name }}", "__repository_url": "https://github.com/{{ cookiecutter.github_organization }}/{{ cookiecutter.__project_slug }}", + "__repository_git": "git@github.com:{{ cookiecutter.github_organization }}/{{ cookiecutter.__project_slug }}", "__feature_headless": "{{ cookiecutter.feature_headless }}", "__feature_distribution": "0", "__package_path": "{{ cookiecutter.python_package_name | package_path }}", diff --git a/templates/add-ons/backend/hooks/pre_gen_project.py b/templates/add-ons/backend/hooks/pre_gen_project.py new file mode 100644 index 00000000..6a2e382b --- /dev/null +++ b/templates/add-ons/backend/hooks/pre_gen_project.py @@ -0,0 +1,17 @@ +"""Pre generation hook.""" + +from collections import OrderedDict +from pathlib import Path + +output_path = Path().resolve() + +context: OrderedDict = {{cookiecutter}} + + +def main(): + """Validate context.""" + pass + + +if __name__ == "__main__": + main() diff --git a/templates/add-ons/backend/{{ cookiecutter.__folder_name }}/README.md b/templates/add-ons/backend/{{ cookiecutter.__folder_name }}/README.md index d935206b..157bb16d 100644 --- a/templates/add-ons/backend/{{ cookiecutter.__folder_name }}/README.md +++ b/templates/add-ons/backend/{{ cookiecutter.__folder_name }}/README.md @@ -20,7 +20,36 @@ And to create the Plone site: make create-site ``` -## Add features using `plonecli` or `bobtemplates.plone` +## Contribute + +- [Issue tracker]({{ cookiecutter.__repository_url }}/issues) +- [Source code]({{ cookiecutter.__repository_url }}/) + +### Prerequisites โœ… + +- An [operating system](https://6.docs.plone.org/install/create-project-cookieplone.html#prerequisites-for-installation) that runs all the requirements mentioned. +- [uv](https://6.docs.plone.org/install/create-project-cookieplone.html#uv) +- [Make](https://6.docs.plone.org/install/create-project-cookieplone.html#make) +- [Git](https://6.docs.plone.org/install/create-project-cookieplone.html#git) +- [Docker](https://docs.docker.com/get-started/get-docker/) (optional) + +### Installation ๐Ÿ”ง + +1. Clone this repository, then change your working directory. + + ```shell + git clone {{ cookiecutter.__repository_git }}.git + cd {{ cookiecutter.__project_slug }} + ``` + +2. Install this code base. + + ```shell + make install + ``` + + +### Add features using `plonecli` or `bobtemplates.plone` This package provides markers as strings (``) that are compatible with [`plonecli`](https://github.com/plone/plonecli) and [`bobtemplates.plone`](https://github.com/plone/bobtemplates.plone). These markers act as hooks to add all kinds of subtemplates, including behaviors, control panels, upgrade steps, or other subtemplates from `plonecli`. @@ -48,11 +77,6 @@ You can check the list of available subtemplates in the [`bobtemplates.plone` `R See also the documentation of [Mockup and Patternslib](https://6.docs.plone.org/classic-ui/mockup.html) for how to build the UI toolkit for Classic UI. ``` -## Contribute - -- [Issue Tracker]({{ cookiecutter.__repository_url }}/issues) -- [Source Code]({{ cookiecutter.__repository_url }}/) - ## License The project is licensed under GPLv2. diff --git a/templates/add-ons/backend/{{ cookiecutter.__folder_name }}/src/packagename/locales/__main__.py b/templates/add-ons/backend/{{ cookiecutter.__folder_name }}/src/packagename/locales/__main__.py index 2f067b00..1cd3960b 100644 --- a/templates/add-ons/backend/{{ cookiecutter.__folder_name }}/src/packagename/locales/__main__.py +++ b/templates/add-ons/backend/{{ cookiecutter.__folder_name }}/src/packagename/locales/__main__.py @@ -1,11 +1,9 @@ """Update locales.""" -from pathlib import Path - import logging import re import subprocess - +from pathlib import Path logger = logging.getLogger("i18n") logger.setLevel(logging.DEBUG) @@ -17,7 +15,7 @@ target_path = locale_path.parent.resolve() domains = [path.name[:-4] for path in locale_path.glob("*.pot")] -i18ndude = "uv run i18ndude" +i18ndude = "uvx i18ndude" # ignore node_modules files resulting in errors excludes = '"*.html *json-schema*.xml"' diff --git a/templates/add-ons/documentation_starter/cookiecutter.json b/templates/add-ons/documentation_starter/cookiecutter.json index 55058d35..a413178a 100644 --- a/templates/add-ons/documentation_starter/cookiecutter.json +++ b/templates/add-ons/documentation_starter/cookiecutter.json @@ -5,12 +5,12 @@ "email": "collective@plone.org", "github_organization": "collective", "initialize_git": ["1", "0"], - "plone_version": "6.0", "__folder_name": "{{ cookiecutter.github_organization|lower }}.{{ cookiecutter.title|replace(' ', '')|replace('-', '_')|replace('.', '')|lower }}", "__normalized_package_name": "{{ cookiecutter.title|replace(' ', '')|replace('-', '_')|replace('.', '')|lower }}", + "__project_slug": "{{ cookiecutter.__normalized_package_name }}", + "__repository_url": "https://github.com/{{ cookiecutter.github_organization }}/{{ cookiecutter.__project_slug }}", + "__repository_git": "git@github.com:{{ cookiecutter.github_organization }}/{{ cookiecutter.__project_slug }}", "__year": "{% now 'local', '%Y' %}", - "__profile_language": "en", - "__version_package": "1.0.0a0", "__generator_date_long": "{% now 'utc', '%Y-%m-%d %H:%M:%S' %}", "__generator_signature": "This was generated by the [cookieplone-templates documentation_starter template](https://github.com/plone/cookieplone-templates/tree/main/documentation_starter) on {{ cookiecutter.__generator_date_long }}", "__documentation_starter_format": "1", diff --git a/templates/add-ons/documentation_starter/hooks/pre_gen_project.py b/templates/add-ons/documentation_starter/hooks/pre_gen_project.py new file mode 100644 index 00000000..6a2e382b --- /dev/null +++ b/templates/add-ons/documentation_starter/hooks/pre_gen_project.py @@ -0,0 +1,17 @@ +"""Pre generation hook.""" + +from collections import OrderedDict +from pathlib import Path + +output_path = Path().resolve() + +context: OrderedDict = {{cookiecutter}} + + +def main(): + """Validate context.""" + pass + + +if __name__ == "__main__": + main() diff --git a/templates/add-ons/documentation_starter/{{cookiecutter.__folder_name}}/.gitignore b/templates/add-ons/documentation_starter/{{ cookiecutter.__folder_name }}/.gitignore similarity index 100% rename from templates/add-ons/documentation_starter/{{cookiecutter.__folder_name}}/.gitignore rename to templates/add-ons/documentation_starter/{{ cookiecutter.__folder_name }}/.gitignore diff --git a/templates/add-ons/documentation_starter/{{cookiecutter.__folder_name}}/.readthedocs.yaml b/templates/add-ons/documentation_starter/{{ cookiecutter.__folder_name }}/.readthedocs.yaml similarity index 100% rename from templates/add-ons/documentation_starter/{{cookiecutter.__folder_name}}/.readthedocs.yaml rename to templates/add-ons/documentation_starter/{{ cookiecutter.__folder_name }}/.readthedocs.yaml diff --git a/templates/add-ons/documentation_starter/{{cookiecutter.__folder_name}}/.vale.ini b/templates/add-ons/documentation_starter/{{ cookiecutter.__folder_name }}/.vale.ini similarity index 100% rename from templates/add-ons/documentation_starter/{{cookiecutter.__folder_name}}/.vale.ini rename to templates/add-ons/documentation_starter/{{ cookiecutter.__folder_name }}/.vale.ini diff --git a/templates/add-ons/documentation_starter/{{cookiecutter.__folder_name}}/LICENSE.md b/templates/add-ons/documentation_starter/{{ cookiecutter.__folder_name }}/LICENSE.md similarity index 100% rename from templates/add-ons/documentation_starter/{{cookiecutter.__folder_name}}/LICENSE.md rename to templates/add-ons/documentation_starter/{{ cookiecutter.__folder_name }}/LICENSE.md diff --git a/templates/add-ons/documentation_starter/{{cookiecutter.__folder_name}}/Makefile b/templates/add-ons/documentation_starter/{{ cookiecutter.__folder_name }}/Makefile similarity index 100% rename from templates/add-ons/documentation_starter/{{cookiecutter.__folder_name}}/Makefile rename to templates/add-ons/documentation_starter/{{ cookiecutter.__folder_name }}/Makefile diff --git a/templates/add-ons/documentation_starter/{{cookiecutter.__folder_name}}/README.md b/templates/add-ons/documentation_starter/{{ cookiecutter.__folder_name }}/README.md similarity index 96% rename from templates/add-ons/documentation_starter/{{cookiecutter.__folder_name}}/README.md rename to templates/add-ons/documentation_starter/{{ cookiecutter.__folder_name }}/README.md index 1269d6db..5f12a40b 100644 --- a/templates/add-ons/documentation_starter/{{cookiecutter.__folder_name}}/README.md +++ b/templates/add-ons/documentation_starter/{{ cookiecutter.__folder_name }}/README.md @@ -118,3 +118,7 @@ See also Read the Docs documentation: - [Pull request previews](https://docs.readthedocs.com/platform/stable/pull-requests.html) - [Build process overview](https://docs.readthedocs.com/platform/stable/builds.html) + +## Credits and acknowledgements ๐Ÿ™ + +{{ cookiecutter.__generator_signature }}. A special thanks to all contributors and supporters! diff --git a/templates/add-ons/documentation_starter/{{cookiecutter.__folder_name}}/docs/_static/favicon.ico b/templates/add-ons/documentation_starter/{{ cookiecutter.__folder_name }}/docs/_static/favicon.ico similarity index 100% rename from templates/add-ons/documentation_starter/{{cookiecutter.__folder_name}}/docs/_static/favicon.ico rename to templates/add-ons/documentation_starter/{{ cookiecutter.__folder_name }}/docs/_static/favicon.ico diff --git a/templates/add-ons/documentation_starter/{{cookiecutter.__folder_name}}/docs/_static/logo.svg b/templates/add-ons/documentation_starter/{{ cookiecutter.__folder_name }}/docs/_static/logo.svg similarity index 100% rename from templates/add-ons/documentation_starter/{{cookiecutter.__folder_name}}/docs/_static/logo.svg rename to templates/add-ons/documentation_starter/{{ cookiecutter.__folder_name }}/docs/_static/logo.svg diff --git a/templates/add-ons/documentation_starter/{{cookiecutter.__folder_name}}/docs/_templates/404.html b/templates/add-ons/documentation_starter/{{ cookiecutter.__folder_name }}/docs/_templates/404.html similarity index 100% rename from templates/add-ons/documentation_starter/{{cookiecutter.__folder_name}}/docs/_templates/404.html rename to templates/add-ons/documentation_starter/{{ cookiecutter.__folder_name }}/docs/_templates/404.html diff --git a/templates/add-ons/documentation_starter/{{cookiecutter.__folder_name}}/docs/concepts/index.md b/templates/add-ons/documentation_starter/{{ cookiecutter.__folder_name }}/docs/concepts/index.md similarity index 100% rename from templates/add-ons/documentation_starter/{{cookiecutter.__folder_name}}/docs/concepts/index.md rename to templates/add-ons/documentation_starter/{{ cookiecutter.__folder_name }}/docs/concepts/index.md diff --git a/templates/add-ons/documentation_starter/{{cookiecutter.__folder_name}}/docs/conf.py b/templates/add-ons/documentation_starter/{{ cookiecutter.__folder_name }}/docs/conf.py similarity index 94% rename from templates/add-ons/documentation_starter/{{cookiecutter.__folder_name}}/docs/conf.py rename to templates/add-ons/documentation_starter/{{ cookiecutter.__folder_name }}/docs/conf.py index 698ee3ae..54c946f6 100644 --- a/templates/add-ons/documentation_starter/{{cookiecutter.__folder_name}}/docs/conf.py +++ b/templates/add-ons/documentation_starter/{{ cookiecutter.__folder_name }}/docs/conf.py @@ -19,9 +19,9 @@ # -- Project information ----------------------------------------------------- -project = "{{cookiecutter.title}}" -author = "{{cookiecutter.author}}" -trademark_name = "{{cookiecutter.github_organization}}" +project = "{{ cookiecutter.title }}" +author = "{{ cookiecutter.author }}" +trademark_name = "{{ cookiecutter.github_organization }}" now = datetime.now() year = str(now.year) copyright = year @@ -95,7 +95,7 @@ # Ignore file downloads r"^/_static/", # Ignore pages that require authentication - r"https://github.com/{{ cookiecutter.github_organization }}/{{ cookiecutter.__normalized_package_name }}/issues/new", # requires auth + r"{{ cookiecutter.__repository_url }}/issues/new", # requires auth # Ignore github.com pages with anchors r"https://github.com/.*#.*", # Ignore other specific anchors @@ -155,7 +155,7 @@ "icon_links": [ { "name": "GitHub", - "url": "https://github.com/{{ cookiecutter.github_organization }}/{{ cookiecutter.__normalized_package_name }}", + "url": "{{ cookiecutter.__repository_url }}", "icon": "fa-brands fa-square-github", "type": "fontawesome", "attributes": { @@ -182,7 +182,7 @@ "navigation_with_keys": True, "path_to_docs": "docs/{{ cookiecutter.__folder_name }}", "repository_branch": "main", - "repository_url": "https://github.com/{{ cookiecutter.github_organization }}/{{ cookiecutter.__normalized_package_name }}", + "repository_url": "{{ cookiecutter.__repository_url }}", "search_bar_text": "Search", "show_toc_level": 2, "use_edit_page_button": True, @@ -192,7 +192,7 @@ # suggest edit link # remark: is mandatory in "edit_page_url_template" # html_context = { -# "edit_page_url_template": "https://github.com/{{ cookiecutter.github_organization }}/{{ cookiecutter.__normalized_package_name }}/edit/main/docs/", +# "edit_page_url_template": "{{ cookiecutter.__repository_url }}/edit/main/docs/", # } # Announce that we have an opensearch plugin @@ -201,7 +201,7 @@ # The name for this set of Sphinx documents. If None, it defaults to # " v documentation". -html_title = "%(project)s v%(release)s" % {"project": project, "release": release} +html_title = f"{project} v{release}" # If false, no index is generated. html_use_index = True diff --git a/templates/add-ons/documentation_starter/{{cookiecutter.__folder_name}}/docs/glossary.md b/templates/add-ons/documentation_starter/{{ cookiecutter.__folder_name }}/docs/glossary.md similarity index 100% rename from templates/add-ons/documentation_starter/{{cookiecutter.__folder_name}}/docs/glossary.md rename to templates/add-ons/documentation_starter/{{ cookiecutter.__folder_name }}/docs/glossary.md diff --git a/templates/add-ons/documentation_starter/{{cookiecutter.__folder_name}}/docs/how-to-guides/index.md b/templates/add-ons/documentation_starter/{{ cookiecutter.__folder_name }}/docs/how-to-guides/index.md similarity index 100% rename from templates/add-ons/documentation_starter/{{cookiecutter.__folder_name}}/docs/how-to-guides/index.md rename to templates/add-ons/documentation_starter/{{ cookiecutter.__folder_name }}/docs/how-to-guides/index.md diff --git a/templates/add-ons/documentation_starter/{{cookiecutter.__folder_name}}/docs/index.md b/templates/add-ons/documentation_starter/{{ cookiecutter.__folder_name }}/docs/index.md similarity index 100% rename from templates/add-ons/documentation_starter/{{cookiecutter.__folder_name}}/docs/index.md rename to templates/add-ons/documentation_starter/{{ cookiecutter.__folder_name }}/docs/index.md diff --git a/templates/add-ons/documentation_starter/{{cookiecutter.__folder_name}}/docs/reference/index.md b/templates/add-ons/documentation_starter/{{ cookiecutter.__folder_name }}/docs/reference/index.md similarity index 100% rename from templates/add-ons/documentation_starter/{{cookiecutter.__folder_name}}/docs/reference/index.md rename to templates/add-ons/documentation_starter/{{ cookiecutter.__folder_name }}/docs/reference/index.md diff --git a/templates/add-ons/documentation_starter/{{cookiecutter.__folder_name}}/docs/robots.txt b/templates/add-ons/documentation_starter/{{ cookiecutter.__folder_name }}/docs/robots.txt similarity index 100% rename from templates/add-ons/documentation_starter/{{cookiecutter.__folder_name}}/docs/robots.txt rename to templates/add-ons/documentation_starter/{{ cookiecutter.__folder_name }}/docs/robots.txt diff --git a/templates/add-ons/documentation_starter/{{cookiecutter.__folder_name}}/docs/tutorials/index.md b/templates/add-ons/documentation_starter/{{ cookiecutter.__folder_name }}/docs/tutorials/index.md similarity index 100% rename from templates/add-ons/documentation_starter/{{cookiecutter.__folder_name}}/docs/tutorials/index.md rename to templates/add-ons/documentation_starter/{{ cookiecutter.__folder_name }}/docs/tutorials/index.md diff --git a/templates/add-ons/documentation_starter/{{cookiecutter.__folder_name}}/pyproject.toml b/templates/add-ons/documentation_starter/{{ cookiecutter.__folder_name }}/pyproject.toml similarity index 93% rename from templates/add-ons/documentation_starter/{{cookiecutter.__folder_name}}/pyproject.toml rename to templates/add-ons/documentation_starter/{{ cookiecutter.__folder_name }}/pyproject.toml index 55dc6ee3..2ab9c9a9 100644 --- a/templates/add-ons/documentation_starter/{{cookiecutter.__folder_name}}/pyproject.toml +++ b/templates/add-ons/documentation_starter/{{ cookiecutter.__folder_name }}/pyproject.toml @@ -53,7 +53,7 @@ dev = [ ] [project.urls] -Repository = "https://github.com/{{ cookiecutter.github_organization }}/{{ cookiecutter.__normalized_package_name }}" +Repository = "{{ cookiecutter.__repository_url }}" Documentation = "https://MY_READTHEDOCS_PROJECT_SLUG.readthedocs.io/" [build-system] diff --git a/templates/add-ons/documentation_starter/{{cookiecutter.__folder_name}}/styles/config/vocabularies/Base/accept.txt b/templates/add-ons/documentation_starter/{{ cookiecutter.__folder_name }}/styles/config/vocabularies/Base/accept.txt similarity index 100% rename from templates/add-ons/documentation_starter/{{cookiecutter.__folder_name}}/styles/config/vocabularies/Base/accept.txt rename to templates/add-ons/documentation_starter/{{ cookiecutter.__folder_name }}/styles/config/vocabularies/Base/accept.txt diff --git a/templates/add-ons/documentation_starter/{{cookiecutter.__folder_name}}/styles/config/vocabularies/Base/reject.txt b/templates/add-ons/documentation_starter/{{ cookiecutter.__folder_name }}/styles/config/vocabularies/Base/reject.txt similarity index 100% rename from templates/add-ons/documentation_starter/{{cookiecutter.__folder_name}}/styles/config/vocabularies/Base/reject.txt rename to templates/add-ons/documentation_starter/{{ cookiecutter.__folder_name }}/styles/config/vocabularies/Base/reject.txt diff --git a/templates/add-ons/documentation_starter/{{cookiecutter.__folder_name}}/styles/config/vocabularies/Plone/accept.txt b/templates/add-ons/documentation_starter/{{ cookiecutter.__folder_name }}/styles/config/vocabularies/Plone/accept.txt similarity index 100% rename from templates/add-ons/documentation_starter/{{cookiecutter.__folder_name}}/styles/config/vocabularies/Plone/accept.txt rename to templates/add-ons/documentation_starter/{{ cookiecutter.__folder_name }}/styles/config/vocabularies/Plone/accept.txt diff --git a/templates/add-ons/documentation_starter/{{cookiecutter.__folder_name}}/styles/config/vocabularies/Plone/reject.txt b/templates/add-ons/documentation_starter/{{ cookiecutter.__folder_name }}/styles/config/vocabularies/Plone/reject.txt similarity index 100% rename from templates/add-ons/documentation_starter/{{cookiecutter.__folder_name}}/styles/config/vocabularies/Plone/reject.txt rename to templates/add-ons/documentation_starter/{{ cookiecutter.__folder_name }}/styles/config/vocabularies/Plone/reject.txt diff --git a/templates/add-ons/frontend/.gitignore b/templates/add-ons/frontend/.gitignore index cea40042..d391cc05 100644 --- a/templates/add-ons/frontend/.gitignore +++ b/templates/add-ons/frontend/.gitignore @@ -1 +1 @@ -volto-addon +volto-add-on diff --git a/templates/add-ons/frontend/cookiecutter.json b/templates/add-ons/frontend/cookiecutter.json index e2d5f0ea..b309a3d3 100644 --- a/templates/add-ons/frontend/cookiecutter.json +++ b/templates/add-ons/frontend/cookiecutter.json @@ -11,6 +11,7 @@ "initialize_documentation": ["1", "0"], "__project_slug": "{{ cookiecutter.frontend_addon_name }}", "__repository_url": "https://github.com/{{ cookiecutter.github_organization }}/{{ cookiecutter.__project_slug }}", + "__repository_git": "git@github.com:{{ cookiecutter.github_organization }}/{{ cookiecutter.__project_slug }}", "__folder_name": "{{ cookiecutter.frontend_addon_name }}", "__npm_package_name": "{{ cookiecutter.npm_package_name }}", "__version_frontend_package": "1.0.0-alpha.0", @@ -19,7 +20,8 @@ "__version_mrs_developer": "^2.2.0", "__version_pnpm": "9.1.1", "__version_release_it": "^17.1.1", - "__gha_version_node": "20.x", + "__node_version": "{{ cookiecutter.volto_version | node_version_for_volto }}", + "__gha_version_node": "{{ cookiecutter.__node_version }}", "__gha_version_checkout": "v4", "__gha_version_setup_node": "v4", "__gha_version_cache": "v4", @@ -45,6 +47,7 @@ "_copy_without_render": [], "_extensions": [ "cookieplone.filters.use_prerelease_versions", + "cookieplone.filters.node_version_for_volto", "cookieplone.filters.latest_volto" ], "__cookieplone_repository_path": "", @@ -53,7 +56,6 @@ "__generator_template_url": "https://github.com/plone/cookieplone-templates/tree/main/{{ cookiecutter.__cookieplone_template }}", "__generator_date_long": "{% now 'utc', '%Y-%m-%d %H:%M:%S' %}", "__generator_signature": "This was generated by [the cookieplone-templates {{ cookiecutter.__cookieplone_template }} template]({{ cookiecutter.__generator_template_url }}) on {{ cookiecutter.__generator_date_long }}", - "__cookieplone_template": "", "__cookieplone_subtemplates": [ [ "documentation_starter", diff --git a/templates/add-ons/frontend/hooks/pre_gen_project.py b/templates/add-ons/frontend/hooks/pre_gen_project.py index d783a088..91b3bdd7 100644 --- a/templates/add-ons/frontend/hooks/pre_gen_project.py +++ b/templates/add-ons/frontend/hooks/pre_gen_project.py @@ -1,6 +1,7 @@ """Pre generation hook.""" import sys +from collections import OrderedDict from pathlib import Path from textwrap import dedent @@ -9,15 +10,7 @@ output_path = Path().resolve() -context = { - "frontend_addon_name": "{{ cookiecutter.frontend_addon_name }}", - "title": "{{ cookiecutter.title }}", - "description": "{{ cookiecutter.description }}", - "author": "{{ cookiecutter.author }}", - "email": "{{ cookiecutter.email }}", - "github_organization": "{{ cookiecutter.github_organization }}", - "npm_package_name": "{{ cookiecutter.__npm_package_name }}", -} +context: OrderedDict = {{cookiecutter}} def check_errors(context: dict) -> data.ContextValidatorResult: diff --git a/templates/add-ons/frontend/{{ cookiecutter.__folder_name }}/README.md b/templates/add-ons/frontend/{{ cookiecutter.__folder_name }}/README.md index fb7c03f9..5622b9d6 100644 --- a/templates/add-ons/frontend/{{ cookiecutter.__folder_name }}/README.md +++ b/templates/add-ons/frontend/{{ cookiecutter.__folder_name }}/README.md @@ -16,6 +16,28 @@ To install your project, you must choose the method appropriate to your version of Volto. +### Volto 18 and later + +Add `{{ cookiecutter.__npm_package_name }}` to your `package.json`: + +```json +"dependencies": { + "{{ cookiecutter.__npm_package_name }}": "*" +} +``` + +Add `{{ cookiecutter.__npm_package_name }}` to your `volto.config.js`: + +```javascript +const addons = ['{{ cookiecutter.__npm_package_name }}']; +``` + +If this package provides a Volto theme, and you want to activate it, then add the following to your `volto.config.js`: + +```javascript +const theme = '{{ cookiecutter.__npm_package_name }}'; +``` + ### Volto 17 and earlier Create a new Volto project (you can skip this step if you already have one): @@ -50,28 +72,6 @@ Start volto with: yarn start ``` -### Volto 18 and later - -Add `{{ cookiecutter.__npm_package_name }}` to your `package.json`: - -```json -"dependencies": { - "{{ cookiecutter.__npm_package_name }}": "*" -} -``` - -Add `{{ cookiecutter.__npm_package_name }}` to your `volto.config.js`: - -```javascript -const addons = ['{{ cookiecutter.__npm_package_name }}']; -``` - -If this package provides a Volto theme, and you want to activate it, then add the following to your `volto.config.js`: - -```javascript -const theme = '{{ cookiecutter.__npm_package_name }}'; -``` - ## Test installation Visit http://localhost:3000/ in a browser, login, and check the awesome new features. @@ -83,11 +83,29 @@ The development of this add-on is done in isolation using a new approach using p For this reason, it only works with pnpm and Volto 18 (currently in alpha). -### Pre-requisites +### Prerequisites โœ… + +- An [operating system](https://6.docs.plone.org/install/create-project-cookieplone.html#prerequisites-for-installation) that runs all the requirements mentioned. +- [nvm](https://6.docs.plone.org/install/create-project-cookieplone.html#nvm) +- [Node.js and pnpm](https://6.docs.plone.org/install/create-project.html#node-js) {{ cookiecutter.__node_version }} +- [Make](https://6.docs.plone.org/install/create-project-cookieplone.html#make) +- [Git](https://6.docs.plone.org/install/create-project-cookieplone.html#git) +- [Docker](https://docs.docker.com/get-started/get-docker/) (optional) + +### Installation ๐Ÿ”ง + +1. Clone this repository, then change your working directory. + + ```shell + git clone {{ cookiecutter.__repository_git }}.git + cd {{ cookiecutter.__project_slug }} + ``` + +2. Install this code base. -- [Node.js](https://6.docs.plone.org/install/create-project.html#node-js) -- [Make](https://6.docs.plone.org/install/create-project.html#make) -- [Docker](https://6.docs.plone.org/install/create-project.html#docker) + ```shell + make install + ``` ### Make convenience commands diff --git a/templates/add-ons/frontend/{{ cookiecutter.__folder_name }}/packages/{{ cookiecutter.frontend_addon_name }}/package.json b/templates/add-ons/frontend/{{ cookiecutter.__folder_name }}/packages/{{ cookiecutter.frontend_addon_name }}/package.json index ed1167f5..b27750d5 100644 --- a/templates/add-ons/frontend/{{ cookiecutter.__folder_name }}/packages/{{ cookiecutter.frontend_addon_name }}/package.json +++ b/templates/add-ons/frontend/{{ cookiecutter.__folder_name }}/packages/{{ cookiecutter.frontend_addon_name }}/package.json @@ -14,7 +14,7 @@ "homepage": "{{ cookiecutter.__repository_url }}#readme", "repository": { "type": "git", - "url": "git@github.com:{{ cookiecutter.github_organization }}/{{ cookiecutter.__project_slug }}.git" + "url": "{{ cookiecutter.__repository_git }}" }, "publishConfig": { "access": "public" @@ -26,6 +26,7 @@ "release-major-alpha": "release-it major --preRelease=alpha", "release-alpha": "release-it --preRelease=alpha" }, + "addons": [], "dependencies": {}, "peerDependencies": { "react": "18.2.0", diff --git a/templates/projects/monorepo/cookiecutter.json b/templates/projects/monorepo/cookiecutter.json index 4f62d18e..94671171 100644 --- a/templates/projects/monorepo/cookiecutter.json +++ b/templates/projects/monorepo/cookiecutter.json @@ -20,6 +20,7 @@ "initialize_documentation": ["1", "0"], "__project_slug": "{{ cookiecutter.project_slug }}", "__repository_url": "https://github.com/{{ cookiecutter.github_organization }}/{{ cookiecutter.__project_slug }}", + "__repository_git": "git@github.com:{{ cookiecutter.github_organization }}/{{ cookiecutter.__project_slug }}", "__version_package": "1.0.0a0", "__version_frontend_package": "1.0.0-alpha.0", "__feature_headless": "1", diff --git a/templates/projects/monorepo/hooks/post_gen_project.py b/templates/projects/monorepo/hooks/post_gen_project.py index bc15bca8..5060d0b2 100644 --- a/templates/projects/monorepo/hooks/post_gen_project.py +++ b/templates/projects/monorepo/hooks/post_gen_project.py @@ -80,6 +80,7 @@ def generate_addons_backend(context, output_dir): def generate_addons_frontend(context, output_dir): """Run volto generator.""" + folder_name = "frontend" # Handle packages inside an organization frontend_addon_name = context.get("frontend_addon_name") if frontend_addon_name.startswith("@") and "/" in frontend_addon_name: @@ -91,7 +92,7 @@ def generate_addons_frontend(context, output_dir): generator.generate_subtemplate( f"{TEMPLATES_FOLDER}/add-ons/frontend", output_dir, - "frontend", + folder_name, context, FRONTEND_ADDON_REMOVE, ) diff --git a/templates/projects/monorepo/{{ cookiecutter.__folder_name }}/README.md b/templates/projects/monorepo/{{ cookiecutter.__folder_name }}/README.md index 9a7dd784..87bdb400 100644 --- a/templates/projects/monorepo/{{ cookiecutter.__folder_name }}/README.md +++ b/templates/projects/monorepo/{{ cookiecutter.__folder_name }}/README.md @@ -11,47 +11,50 @@ ### Prerequisites โœ… -Ensure you have the following installed: +- An [operating system](https://6.docs.plone.org/install/create-project-cookieplone.html#prerequisites-for-installation) that runs all the requirements mentioned. +- [uv](https://6.docs.plone.org/install/create-project-cookieplone.html#uv) +- [nvm](https://6.docs.plone.org/install/create-project-cookieplone.html#nvm) +- [Node.js and pnpm](https://6.docs.plone.org/install/create-project.html#node-js) {{ cookiecutter.__node_version }} +- [Make](https://6.docs.plone.org/install/create-project-cookieplone.html#make) +- [Git](https://6.docs.plone.org/install/create-project-cookieplone.html#git) +- [Docker](https://docs.docker.com/get-started/get-docker/) (optional) -- Python 3.11 ๐Ÿ -- Node {{ cookiecutter.__node_version }} ๐ŸŸฉ -- pnpm ๐Ÿงถ -- Docker ๐Ÿณ ### Installation ๐Ÿ”ง -1. Clone the repository: +1. Clone this repository, then change your working directory. -```shell -git clone git@github.com:{{ cookiecutter.github_organization }}/{{ cookiecutter.__project_slug }}.git -cd {{ cookiecutter.__project_slug }} -``` + ```shell + git clone {{ cookiecutter.__repository_git }}.git + cd {{ cookiecutter.__project_slug }} + ``` -2. Install both Backend and Frontend: +2. Install this code base. + + ```shell + make install + ``` -```shell -make install -``` ### Fire Up the Servers ๐Ÿ”ฅ -1. Create a new Plone site on your first run: +1. Create a new Plone site on your first run. -```shell -make backend-create-site -``` + ```shell + make backend-create-site + ``` -2. Start the Backend at [http://localhost:8080/](http://localhost:8080/): +2. Start the backend at http://localhost:8080/. -```shell -make backend-start -``` + ```shell + make backend-start + ``` -3. In a new terminal, start the Frontend at [http://localhost:3000/](http://localhost:3000/): +3. In a new shell session, start the frontend at http://localhost:3000/. -```shell -make frontend-start -``` + ```shell + make frontend-start + ``` Voila! Your Plone site should be live and kicking! ๐ŸŽ‰ diff --git a/templates/sub/cache/hooks/pre_gen_project.py b/templates/sub/cache/hooks/pre_gen_project.py new file mode 100644 index 00000000..6a2e382b --- /dev/null +++ b/templates/sub/cache/hooks/pre_gen_project.py @@ -0,0 +1,17 @@ +"""Pre generation hook.""" + +from collections import OrderedDict +from pathlib import Path + +output_path = Path().resolve() + +context: OrderedDict = {{cookiecutter}} + + +def main(): + """Validate context.""" + pass + + +if __name__ == "__main__": + main() diff --git a/templates/sub/project_settings/cookiecutter.json b/templates/sub/project_settings/cookiecutter.json index 03ec78a9..5080e29d 100644 --- a/templates/sub/project_settings/cookiecutter.json +++ b/templates/sub/project_settings/cookiecutter.json @@ -7,13 +7,17 @@ "python_package_name": "{{ cookiecutter.project_slug|replace(' ', '')|replace('-', '.') }}", "frontend_addon_name": "volto-{{ cookiecutter.python_package_name|replace('_', '-')|replace('.', '-') }}", "language_code": "en", + "use_prerelease_versions": "{{ 'No' | use_prerelease_versions }}", "plone_version": "{{ 'No' | latest_plone }}", + "volto_version": "{{ cookiecutter.use_prerelease_versions | latest_volto }}", "github_organization": "collective", "container_registry": ["github", "docker_hub", "gitlab"], "__feature_distribution": "0", "__backend_managed_by_uv": "false", - "__project_slug": "{{ cookiecutter.python_package_name }}", + "__project_slug": "{{ cookiecutter.project_slug }}", "__repository_url": "https://github.com/{{ cookiecutter.github_organization }}/{{ cookiecutter.__project_slug }}", + "__repository_git": "git@github.com:{{ cookiecutter.github_organization }}/{{ cookiecutter.__project_slug }}", + "__node_version": "{{ cookiecutter.volto_version | node_version_for_volto }}", "__npm_package_name": "{{ cookiecutter.frontend_addon_name }}", "__container_registry_prefix": "{{ cookiecutter.container_registry | image_prefix }}", "__container_image_prefix": "{{ cookiecutter.__container_registry_prefix }}{{ cookiecutter.github_organization }}/{{ cookiecutter.project_slug }}", @@ -25,7 +29,12 @@ "__supported_versions_python": ["{{ cookiecutter.__python_version }}"], "__supported_versions_plone": ["{{ cookiecutter.plone_version | as_major_minor }}"], "__python_version_identifier": "{{ cookiecutter.__python_version | replace('.', '') }}", + "__version_frontend_package": "1.0.0-alpha.0", + "__version_plone_volto": "{{ cookiecutter.volto_version }}", + "__version_plone_scripts": "^3.6.1", + "__version_mrs_developer": "^2.2.0", "__version_pnpm": "9.1.1", + "__version_release_it": "^17.1.1", "_copy_without_render": [], "_extensions": [ "cookieplone.filters.use_prerelease_versions", @@ -42,5 +51,9 @@ "cookieplone.filters.latest_plone" ], "__cookieplone_repository_path": "", - "__cookieplone_template": "" + "__cookieplone_template": "", + "__generator_sha": "", + "__generator_template_url": "https://github.com/plone/cookieplone-templates/tree/main/{{ cookiecutter.__cookieplone_template }}", + "__generator_date_long": "{% now 'utc', '%Y-%m-%d %H:%M:%S' %}", + "__generator_signature": "Generated from the [`cookieplone-templates` {{ cookiecutter.__cookieplone_template }} template]({{ cookiecutter.__generator_template_url }}) on {{ cookiecutter.__generator_date_long }}." } diff --git a/templates/sub/project_settings/{{ cookiecutter.__folder_name }}/backend/README.md b/templates/sub/project_settings/{{ cookiecutter.__folder_name }}/backend/README.md new file mode 100644 index 00000000..3a1ebcf3 --- /dev/null +++ b/templates/sub/project_settings/{{ cookiecutter.__folder_name }}/backend/README.md @@ -0,0 +1,87 @@ +# {{ cookiecutter.python_package_name }} + +{{ cookiecutter.description }} + +## Features + +TODO: List our awesome features + +## Installation + +Install {{ cookiecutter.python_package_name }} with uv. + +```shell +uv add {{ cookiecutter.python_package_name }} +``` + +Create the Plone site. + +```shell +make create-site +``` + +## Contribute + +- [Issue tracker]({{ cookiecutter.__repository_url }}/issues) +- [Source code]({{ cookiecutter.__repository_url }}/) + +### Prerequisites โœ… + +- An [operating system](https://6.docs.plone.org/install/create-project-cookieplone.html#prerequisites-for-installation) that runs all the requirements mentioned. +- [uv](https://6.docs.plone.org/install/create-project-cookieplone.html#uv) +- [Make](https://6.docs.plone.org/install/create-project-cookieplone.html#make) +- [Git](https://6.docs.plone.org/install/create-project-cookieplone.html#git) +- [Docker](https://docs.docker.com/get-started/get-docker/) (optional) + +### Installation ๐Ÿ”ง + +1. Clone this repository. + + ```shell + git clone {{ cookiecutter.__repository_git }}.git + cd {{ cookiecutter.__project_slug }}/backend + ``` + +2. Install this code base. + + ```shell + make install + ``` + + +### Add features using `plonecli` or `bobtemplates.plone` + +This package provides markers as strings (``) that are compatible with [`plonecli`](https://github.com/plone/plonecli) and [`bobtemplates.plone`](https://github.com/plone/bobtemplates.plone). +These markers act as hooks to add all kinds of features through subtemplates, including behaviors, control panels, upgrade steps, or other subtemplates from `bobtemplates.plone`. +`plonecli` is a command line client for `bobtemplates.plone`, adding autocompletion and other features. + +To add a feature as a subtemplate to your package, use the following command pattern. + +```shell +make add +``` + +For example, you can add a content type to your package with the following command. + +```shell +make add content_type +``` + +You can add a behavior with the following command. + +```shell +make add behavior +``` + +```{seealso} +You can check the list of available subtemplates in the [`bobtemplates.plone` `README.md` file](https://github.com/plone/bobtemplates.plone/?tab=readme-ov-file#provided-subtemplates). +See also the documentation of [Mockup and Patternslib](https://6.docs.plone.org/classic-ui/mockup.html) for how to build the UI toolkit for Classic UI. +``` + +## License + +The project is licensed under GPLv2. + +## Credits and acknowledgements ๐Ÿ™ + +{{ cookiecutter.__generator_signature }}. A special thanks to all contributors and supporters! diff --git a/templates/sub/project_settings/{{ cookiecutter.__folder_name }}/backend/pyproject.toml b/templates/sub/project_settings/{{ cookiecutter.__folder_name }}/backend/pyproject.toml index cf5ae5c8..756dc885 100644 --- a/templates/sub/project_settings/{{ cookiecutter.__folder_name }}/backend/pyproject.toml +++ b/templates/sub/project_settings/{{ cookiecutter.__folder_name }}/backend/pyproject.toml @@ -49,7 +49,7 @@ test = [ ] [project.urls] -Homepage = "https://github.com/{{ cookiecutter.github_organization }}/{{ cookiecutter.project_slug }}" +Homepage = "{{ cookiecutter.__repository_url }}" PyPI = "https://pypi.org/project/{{ cookiecutter.python_package_name }}" Source = "{{ cookiecutter.__repository_url }}" Tracker = "{{ cookiecutter.__repository_url }}/issues" @@ -88,7 +88,7 @@ filename = "CHANGELOG.md" start_string = "\n" title_format = "## {version} ({project_date})" template = "news/.changelog_template.jinja" -issue_format = "[#{issue}](https://github.com/{{ cookiecutter.github_organization }}/{{ cookiecutter.python_package_name }}/issues/{issue})" +issue_format = "[#{issue}]({{ cookiecutter.__repository_url }}/issues/{issue})" underlines = ["", "", ""] [[tool.towncrier.type]] diff --git a/templates/sub/project_settings/{{ cookiecutter.__folder_name }}/backend/src/packagename/locales/__main__.py b/templates/sub/project_settings/{{ cookiecutter.__folder_name }}/backend/src/packagename/locales/__main__.py index 2f067b00..1cd3960b 100644 --- a/templates/sub/project_settings/{{ cookiecutter.__folder_name }}/backend/src/packagename/locales/__main__.py +++ b/templates/sub/project_settings/{{ cookiecutter.__folder_name }}/backend/src/packagename/locales/__main__.py @@ -1,11 +1,9 @@ """Update locales.""" -from pathlib import Path - import logging import re import subprocess - +from pathlib import Path logger = logging.getLogger("i18n") logger.setLevel(logging.DEBUG) @@ -17,7 +15,7 @@ target_path = locale_path.parent.resolve() domains = [path.name[:-4] for path in locale_path.glob("*.pot")] -i18ndude = "uv run i18ndude" +i18ndude = "uvx i18ndude" # ignore node_modules files resulting in errors excludes = '"*.html *json-schema*.xml"' diff --git a/templates/sub/project_settings/{{ cookiecutter.__folder_name }}/frontend/README.md b/templates/sub/project_settings/{{ cookiecutter.__folder_name }}/frontend/README.md new file mode 100644 index 00000000..e715e5b5 --- /dev/null +++ b/templates/sub/project_settings/{{ cookiecutter.__folder_name }}/frontend/README.md @@ -0,0 +1,195 @@ +# {{ cookiecutter.title }} ({{ cookiecutter.__npm_package_name }}) + +{{ cookiecutter.description }} + +[![npm](https://img.shields.io/npm/v/{{ cookiecutter.__npm_package_name }})](https://www.npmjs.com/package/{{ cookiecutter.__npm_package_name }}) +[![](https://img.shields.io/badge/-Storybook-ff4785?logo=Storybook&logoColor=white&style=flat-square)](https://{{ cookiecutter.github_organization }}.github.io/{{ cookiecutter.frontend_addon_name }}/) +[![CI]({{ cookiecutter.__repository_url }}/actions/workflows/main.yml/badge.svg)]({{ cookiecutter.__repository_url }}/actions/workflows/main.yml) + + +## Features + + + +## Installation + +To install your project, you must choose the method appropriate to your version of Volto. + + +### Volto 18 and later + +Add `{{ cookiecutter.__npm_package_name }}` to your `package.json`. + +```json +"dependencies": { + "{{ cookiecutter.__npm_package_name }}": "*" +} +``` + +Add `{{ cookiecutter.__npm_package_name }}` to your `volto.config.js`. + +```javascript +const addons = ['{{ cookiecutter.__npm_package_name }}']; +``` + +If this package provides a Volto theme, and you want to activate it, then add the following to your `volto.config.js`. + +```javascript +const theme = '{{ cookiecutter.__npm_package_name }}'; +``` + +### Volto 17 and earlier + +Create a new Volto project. +You can skip this step if you already have one. + +``` +npm install -g yo @plone/generator-volto +yo @plone/volto my-volto-project --addon {{ cookiecutter.__npm_package_name }} +cd my-volto-project +``` + +Add `{{ cookiecutter.__npm_package_name }}` to your `package.json`. + +```JSON +"addons": [ + "{{ cookiecutter.__npm_package_name }}" +], + +"dependencies": { + "{{ cookiecutter.__npm_package_name }}": "*" +} +``` + +Download and install the new add-on. + +``` +yarn install +``` + +Start Volto. + +``` +yarn start +``` + +## Test installation + +Visit http://localhost:3000/ in a browser, login, and check the awesome new features. + + +## Development + +The development of this add-on is done in isolation using pnpm workspaces, the latest `mrs-developer`, and other Volto core improvements. +For these reasons, it only works with pnpm and Volto 18. + + +### Prerequisites โœ… + +- An [operating system](https://6.docs.plone.org/install/create-project-cookieplone.html#prerequisites-for-installation) that runs all the requirements mentioned. +- [nvm](https://6.docs.plone.org/install/create-project-cookieplone.html#nvm) +- [Node.js and pnpm](https://6.docs.plone.org/install/create-project.html#node-js) {{ cookiecutter.__node_version }} +- [Make](https://6.docs.plone.org/install/create-project-cookieplone.html#make) +- [Git](https://6.docs.plone.org/install/create-project-cookieplone.html#git) +- [Docker](https://docs.docker.com/get-started/get-docker/) (optional) + +### Installation ๐Ÿ”ง + +1. Clone this repository, then change your working directory. + + ```shell + git clone {{ cookiecutter.__repository_git }}.git + cd {{ cookiecutter.__project_slug }}/frontend + ``` + +2. Install this code base. + + ```shell + make install + ``` + + +### Make convenience commands + +Run `make help` to list the available Make commands. + + +### Set up development environment + +Install package requirements. + +```shell +make install +``` + +### Start developing + +Start the backend. + +```shell +make backend-docker-start +``` + +In a separate terminal session, start the frontend. + +```shell +make start +``` + +### Lint code + +Run ESlint, Prettier, and Stylelint in analyze mode. + +```shell +make lint +``` + +### Format code + +Run ESlint, Prettier, and Stylelint in fix mode. + +```shell +make format +``` + +### i18n + +Extract the i18n messages to locales. + +```shell +make i18n +``` + +### Unit tests + +Run unit tests. + +```shell +make test +``` + +### Run Cypress tests + +Run each of these steps in separate terminal sessions. + +In the first session, start the frontend in development mode. + +```shell +make acceptance-frontend-dev-start +``` + +In the second session, start the backend acceptance server. + +```shell +make acceptance-backend-start +``` + +In the third session, start the Cypress interactive test runner. + +```shell +make acceptance-test +``` + +## License + +The project is licensed under the MIT license. diff --git a/templates/sub/project_settings/{{ cookiecutter.__folder_name }}/frontend/package.json b/templates/sub/project_settings/{{ cookiecutter.__folder_name }}/frontend/package.json new file mode 100644 index 00000000..f4367a82 --- /dev/null +++ b/templates/sub/project_settings/{{ cookiecutter.__folder_name }}/frontend/package.json @@ -0,0 +1,50 @@ +{ + "name": "{{ cookiecutter.__npm_package_name }}-dev", + "version": "{{ cookiecutter.__version_frontend_package }}", + "description": "{{ cookiecutter.description }}", + "author": "{{ cookiecutter.author }}", + "homepage": "{{ cookiecutter.__repository_url }}", + "license": "MIT", + "keywords": [ + "volto-addon", + "volto", + "plone", + "react" + ], + "scripts": { + "preinstall": "npx only-allow pnpm", + "start": "VOLTOCONFIG=$(pwd)/volto.config.js pnpm --filter @plone/volto start", + "start:prod": "pnpm --filter @plone/volto start:prod", + "build": "VOLTOCONFIG=$(pwd)/volto.config.js pnpm --filter @plone/volto build", + "build:deps": "pnpm --filter @plone/registry --filter @plone/components build", + "i18n": "pnpm --filter {{ cookiecutter.__npm_package_name }} i18n && VOLTOCONFIG=$(pwd)/volto.config.js pnpm --filter @plone/volto i18n", + "test": "RAZZLE_JEST_CONFIG=$(pwd)/jest-addon.config.js pnpm --filter @plone/volto test -- --passWithNoTests", + "lint": "VOLTOCONFIG=$(pwd)/volto.config.js eslint --max-warnings=0 'packages/**/src/**/*.{js,jsx,ts,tsx}'", + "lint:fix": "VOLTOCONFIG=$(pwd)/volto.config.js eslint --fix 'packages/**/src/**/*.{js,jsx,ts,tsx}'", + "prettier": "prettier --check 'packages/**/src/**/*.{js,jsx,ts,tsx}'", + "prettier:fix": "prettier --write 'packages/**/src/**/*.{js,jsx,ts,tsx}' ", + "stylelint": "stylelint 'packages/**/src/**/*.{css,scss,less}' --allow-empty-input", + "stylelint:fix": "stylelint 'packages/**/src/**/*.{css,scss,less}' --fix --allow-empty-input", + "dry-release": "pnpm --filter {{ cookiecutter.__npm_package_name }} dry-release", + "release": "pnpm --filter {{ cookiecutter.__npm_package_name }} release", + "release-major-alpha": "pnpm --filter {{ cookiecutter.__npm_package_name }} release-major-alpha", + "release-alpha": "pnpm --filter {{ cookiecutter.__npm_package_name }} release-alpha", + "storybook": "VOLTOCONFIG=$(pwd)/volto.config.js pnpm --filter @plone/volto storybook dev -p 6006 -c $(pwd)/.storybook", + "storybook-build": "VOLTOCONFIG=$(pwd)/volto.config.js pnpm --filter @plone/volto build-storybook -c $(pwd)/.storybook" + }, + "dependencies": { + "@plone/volto": "workspace:*", + "@plone/registry": "workspace:*", + "{{ cookiecutter.__npm_package_name }}": "workspace:*" + }, + "devDependencies": { + "mrs-developer": "{{ cookiecutter.__version_mrs_developer }}" + }, + "pnpm": { + "overrides": { + "@pmmmwh/react-refresh-webpack-plugin": "^0.5.15", + "react-refresh": "^0.14.2" + } + }, + "packageManager": "pnpm@{{ cookiecutter.__version_pnpm }}" +} diff --git a/templates/sub/project_settings/{{ cookiecutter.__folder_name }}/frontend/packages/{{ cookiecutter.frontend_addon_name }}/package.json b/templates/sub/project_settings/{{ cookiecutter.__folder_name }}/frontend/packages/{{ cookiecutter.frontend_addon_name }}/package.json new file mode 100644 index 00000000..b27750d5 --- /dev/null +++ b/templates/sub/project_settings/{{ cookiecutter.__folder_name }}/frontend/packages/{{ cookiecutter.frontend_addon_name }}/package.json @@ -0,0 +1,39 @@ +{ + "name": "{{ cookiecutter.__npm_package_name }}", + "version": "{{ cookiecutter.__version_frontend_package }}", + "description": "{{ cookiecutter.description }}", + "main": "src/index.js", + "license": "MIT", + "keywords": [ + "volto-addon", + "volto", + "plone", + "react" + ], + "author": "{{ cookiecutter.author }}", + "homepage": "{{ cookiecutter.__repository_url }}#readme", + "repository": { + "type": "git", + "url": "{{ cookiecutter.__repository_git }}" + }, + "publishConfig": { + "access": "public" + }, + "scripts": { + "i18n": "rm -rf build/messages && NODE_ENV=production i18n --addon", + "dry-release": "release-it --dry-run", + "release": "release-it", + "release-major-alpha": "release-it major --preRelease=alpha", + "release-alpha": "release-it --preRelease=alpha" + }, + "addons": [], + "dependencies": {}, + "peerDependencies": { + "react": "18.2.0", + "react-dom": "18.2.0" + }, + "devDependencies": { + "@plone/scripts": "{{ cookiecutter.__version_plone_scripts }}", + "release-it": "{{ cookiecutter.__version_release_it }}" + } +} diff --git a/templates/sub/project_settings/{{ cookiecutter.__folder_name }}/frontend/packages/{{ cookiecutter.frontend_addon_name }}/towncrier.toml b/templates/sub/project_settings/{{ cookiecutter.__folder_name }}/frontend/packages/{{ cookiecutter.frontend_addon_name }}/towncrier.toml new file mode 100644 index 00000000..9b11d5f5 --- /dev/null +++ b/templates/sub/project_settings/{{ cookiecutter.__folder_name }}/frontend/packages/{{ cookiecutter.frontend_addon_name }}/towncrier.toml @@ -0,0 +1,33 @@ +[tool.towncrier] +filename = "CHANGELOG.md" +directory = "news/" +title_format = "## {version} ({project_date})" +underlines = ["", "", ""] +template = "./node_modules/@plone/scripts/templates/towncrier_template.jinja" +start_string = "\n" +issue_format = "[#{issue}]({{ cookiecutter.__repository_url }}/issue/{issue})" + +[[tool.towncrier.type]] +directory = "breaking" +name = "Breaking" +showcontent = true + +[[tool.towncrier.type]] +directory = "feature" +name = "Feature" +showcontent = true + +[[tool.towncrier.type]] +directory = "bugfix" +name = "Bugfix" +showcontent = true + +[[tool.towncrier.type]] +directory = "internal" +name = "Internal" +showcontent = true + +[[tool.towncrier.type]] +directory = "documentation" +name = "Documentation" +showcontent = true diff --git a/tests/templates/add-ons/backend/test_backend_cutter.py b/tests/templates/add-ons/backend/test_backend_cutter.py index a581cef4..52c3ff51 100644 --- a/tests/templates/add-ons/backend/test_backend_cutter.py +++ b/tests/templates/add-ons/backend/test_backend_cutter.py @@ -20,9 +20,9 @@ def test_variable_substitution(build_files_list, variable_pattern, cutter_result for path in paths: with open(path) as fh: for line in fh: - match = variable_pattern.search(line) + match = {pattern.search(line) for pattern in variable_pattern} msg = f"cookiecutter variable not replaced in {path}" - assert match is None, msg + assert match == {None}, msg def test_root_files_generated(cutter_result, root_file_path): diff --git a/tests/templates/add-ons/backend/test_backend_cutter_distribution.py b/tests/templates/add-ons/backend/test_backend_cutter_distribution.py index 188f4f63..61b72470 100644 --- a/tests/templates/add-ons/backend/test_backend_cutter_distribution.py +++ b/tests/templates/add-ons/backend/test_backend_cutter_distribution.py @@ -26,9 +26,9 @@ def test_variable_substitution(build_files_list, variable_pattern, cutter_result for path in paths: with open(path) as fh: for line in fh: - match = variable_pattern.search(line) + match = {pattern.search(line) for pattern in variable_pattern} msg = f"cookiecutter variable not replaced in {path}" - assert match is None, msg + assert match == {None}, msg def test_trove_classifier_set(cutter_result): diff --git a/tests/templates/add-ons/backend/test_backend_cutter_no_headless.py b/tests/templates/add-ons/backend/test_backend_cutter_no_headless.py index 389f33d0..4c213b60 100644 --- a/tests/templates/add-ons/backend/test_backend_cutter_no_headless.py +++ b/tests/templates/add-ons/backend/test_backend_cutter_no_headless.py @@ -26,9 +26,9 @@ def test_variable_substitution(build_files_list, variable_pattern, cutter_result for path in paths: with open(path) as fh: for line in fh: - match = variable_pattern.search(line) + match = {pattern.search(line) for pattern in variable_pattern} msg = f"cookiecutter variable not replaced in {path}" - assert match is None, msg + assert match == {None}, msg def test_root_files_generated(cutter_result, root_file_path): diff --git a/tests/templates/add-ons/backend/test_backend_variables.py b/tests/templates/add-ons/backend/test_backend_variables.py index f82a8e87..0ca01d78 100644 --- a/tests/templates/add-ons/backend/test_backend_variables.py +++ b/tests/templates/add-ons/backend/test_backend_variables.py @@ -1,8 +1,8 @@ -ALLOWED_MISSING = [] +ALLOWED_MISSING = [ + "initialize_git", +] ALLOWED_NOT_USED = [ - "__documentation_starter_format", "__generator_sha", - "__normalized_package_name", ] diff --git a/tests/templates/add-ons/documentation_starter/conftest.py b/tests/templates/add-ons/documentation_starter/conftest.py index 8b0b5307..33bfa646 100644 --- a/tests/templates/add-ons/documentation_starter/conftest.py +++ b/tests/templates/add-ons/documentation_starter/conftest.py @@ -79,6 +79,5 @@ def bad_context() -> dict: def pytest_generate_tests(metafunc): - print("Here it is====================================") if "root_file_path" in metafunc.fixturenames: metafunc.parametrize("root_file_path", EXPECTED_FILES) diff --git a/tests/templates/add-ons/documentation_starter/test_cutter.py b/tests/templates/add-ons/documentation_starter/test_docs_cutter.py similarity index 57% rename from tests/templates/add-ons/documentation_starter/test_cutter.py rename to tests/templates/add-ons/documentation_starter/test_docs_cutter.py index 1ac84ddb..3cde90f2 100644 --- a/tests/templates/add-ons/documentation_starter/test_cutter.py +++ b/tests/templates/add-ons/documentation_starter/test_docs_cutter.py @@ -11,17 +11,6 @@ def test_creation(cookies, template_path, context: dict): assert result.project_path.is_dir() -def test_variable_substitution(build_files_list, variable_pattern, cutter_result): - """Check if no file was unprocessed.""" - paths = build_files_list(cutter_result.project_path) - for path in paths: - with open(path) as fh: - for line in fh: - match = variable_pattern.search(line) - msg = f"cookiecutter variable not replaced in {path}" - assert match is None, msg - - def test_git_initialization(cutter_result): from cookieplone.utils import git diff --git a/tests/templates/add-ons/documentation_starter/test_docs_variables.py b/tests/templates/add-ons/documentation_starter/test_docs_variables.py new file mode 100644 index 00000000..42c04d0f --- /dev/null +++ b/tests/templates/add-ons/documentation_starter/test_docs_variables.py @@ -0,0 +1,16 @@ +ALLOWED_MISSING = [] +ALLOWED_NOT_USED = [ + "__repository_git", +] + + +def test_no_missing_variables(variables_missing): + """Test no variable is missing from cookiecutter.json""" + assert len(variables_missing) == len(ALLOWED_MISSING) + assert variables_missing == ALLOWED_MISSING + + +def test_not_used_variables(variables_not_used): + """Test variables are used.""" + assert len(variables_not_used) == len(ALLOWED_NOT_USED) + assert variables_not_used == ALLOWED_NOT_USED diff --git a/tests/templates/add-ons/frontend/test_frontend_cutter.py b/tests/templates/add-ons/frontend/test_frontend_cutter.py index bf7aa796..df976149 100644 --- a/tests/templates/add-ons/frontend/test_frontend_cutter.py +++ b/tests/templates/add-ons/frontend/test_frontend_cutter.py @@ -73,9 +73,9 @@ def test_variable_substitution(build_files_list, variable_pattern, cutter_result for path in paths: with open(path) as fh: for line in fh: - match = variable_pattern.search(line) + match = {pattern.search(line) for pattern in variable_pattern} msg = f"cookiecutter variable not replaced in {path}" - assert match is None, msg + assert match == {None}, msg @pytest.mark.parametrize( diff --git a/tests/templates/add-ons/frontend/test_frontend_variables.py b/tests/templates/add-ons/frontend/test_frontend_variables.py index 511ca1e9..0ca01d78 100644 --- a/tests/templates/add-ons/frontend/test_frontend_variables.py +++ b/tests/templates/add-ons/frontend/test_frontend_variables.py @@ -1,11 +1,8 @@ -ALLOWED_MISSING = [] +ALLOWED_MISSING = [ + "initialize_git", +] ALLOWED_NOT_USED = [ - "__documentation_starter_format", "__generator_sha", - "__normalized_package_name", - "__profile_language", - "__version_package", - "__year", ] diff --git a/tests/templates/projects/monorepo/test_project_cutter.py b/tests/templates/projects/monorepo/test_project_cutter.py index 57ed0206..9f27fdf4 100644 --- a/tests/templates/projects/monorepo/test_project_cutter.py +++ b/tests/templates/projects/monorepo/test_project_cutter.py @@ -25,9 +25,9 @@ def test_variable_substitution(cutter_result, variable_pattern): for path in paths: with open(path) as fh: for line in fh: - match = variable_pattern.search(line) + match = {pattern.search(line) for pattern in variable_pattern} msg = f"cookiecutter variable not replaced in {path}" - assert match is None, msg + assert match == {None}, msg FOLDERS = [ diff --git a/tests/templates/projects/monorepo/test_project_generation.py b/tests/templates/projects/monorepo/test_project_generation.py index 7c9d0192..2c3e6a70 100644 --- a/tests/templates/projects/monorepo/test_project_generation.py +++ b/tests/templates/projects/monorepo/test_project_generation.py @@ -62,3 +62,26 @@ def test_json_schema( ): path = cutter_result.project_path / file_path assert schema_validate_file(path, schema_name) + + +@pytest.mark.parametrize( + "file_path,bad_url", + [ + ["README.md", "https://github.com/plonegovbr/plonegov.ploneorgbr"], + ["README.md", "https://github.com/plonegovbr/volto-ploneorgbr"], + ["backend/README.md", "https://github.com/plonegovbr/plonegov.ploneorgbr"], + ["backend/pyproject.toml", "https://github.com/plonegovbr/plonegov.ploneorgbr"], + ["frontend/README.md", "https://github.com/plonegovbr/volto-ploneorgbr"], + [ + "frontend/packages/volto-ploneorgbr/package.json", + "https://github.com/plonegovbr/volto-ploneorgbr", + ], + [ + "frontend/packages/volto-ploneorgbr/towncrier.toml", + "https://github.com/plonegovbr/volto-ploneorgbr", + ], + ], +) +def test_repository_url(cutter_result, file_path: str, bad_url: str): + path = cutter_result.project_path / file_path + assert bad_url not in path.read_text() diff --git a/tests/templates/projects/monorepo/test_project_variables.py b/tests/templates/projects/monorepo/test_project_variables.py index d1334f8d..c8bdf2a2 100644 --- a/tests/templates/projects/monorepo/test_project_variables.py +++ b/tests/templates/projects/monorepo/test_project_variables.py @@ -1,5 +1,5 @@ -ALLOWED_MISSING = ["feature_headless", "npm_package_name"] -ALLOWED_NOT_USED = ["__documentation_starter_format", "__normalized_package_name"] +ALLOWED_MISSING = ["feature_headless", "initialize_git", "npm_package_name"] +ALLOWED_NOT_USED = [] def test_no_missing_variables(variables_missing): diff --git a/tests/templates/sub/cache/test_sub_cache_cutter.py b/tests/templates/sub/cache/test_sub_cache_cutter.py index 704f4f47..d86b830c 100644 --- a/tests/templates/sub/cache/test_sub_cache_cutter.py +++ b/tests/templates/sub/cache/test_sub_cache_cutter.py @@ -18,9 +18,9 @@ def test_variable_substitution(build_files_list, variable_pattern, cutter_result for path in paths: with open(path) as fh: for line in fh: - match = variable_pattern.search(line) + match = {pattern.search(line) for pattern in variable_pattern} msg = f"cookiecutter variable not replaced in {path}" - assert match is None, msg + assert match == {None}, msg @pytest.mark.parametrize( diff --git a/tests/templates/sub/frontend_project/test_sub_frontend_project_cutter.py b/tests/templates/sub/frontend_project/test_sub_frontend_project_cutter.py index 3fb5d02a..ff54436c 100644 --- a/tests/templates/sub/frontend_project/test_sub_frontend_project_cutter.py +++ b/tests/templates/sub/frontend_project/test_sub_frontend_project_cutter.py @@ -20,9 +20,9 @@ def test_variable_substitution(build_files_list, variable_pattern, cutter_result for path in paths: with open(path) as fh: for line in fh: - match = variable_pattern.search(line) + match = {pattern.search(line) for pattern in variable_pattern} msg = f"cookiecutter variable not replaced in {path}" - assert match is None, msg + assert match == {None}, msg @pytest.mark.parametrize( diff --git a/tests/templates/sub/project_settings/conftest.py b/tests/templates/sub/project_settings/conftest.py index deb65395..6026fa45 100644 --- a/tests/templates/sub/project_settings/conftest.py +++ b/tests/templates/sub/project_settings/conftest.py @@ -22,6 +22,7 @@ def context(annotate_context, cookieplone_root) -> dict: "frontend_addon_name": "volto-project-title", "language_code": "en", "github_organization": "collective", + "use_prerelease_versions": "No", "__node_version": "20", }, cookieplone_root, diff --git a/tests/templates/sub/project_settings/test_sub_project_settings_cutter.py b/tests/templates/sub/project_settings/test_sub_project_settings_cutter.py index 37b56ddc..d8c1383b 100644 --- a/tests/templates/sub/project_settings/test_sub_project_settings_cutter.py +++ b/tests/templates/sub/project_settings/test_sub_project_settings_cutter.py @@ -20,9 +20,9 @@ def test_variable_substitution(build_files_list, variable_pattern, cutter_result for path in paths: with open(path) as fh: for line in fh: - match = variable_pattern.search(line) + match = {pattern.search(line) for pattern in variable_pattern} msg = f"cookiecutter variable not replaced in {path}" - assert match is None, msg + assert match == {None}, msg GENERATED_FILES = [ diff --git a/tests/templates/sub/project_settings/test_sub_project_settings_variables.py b/tests/templates/sub/project_settings/test_sub_project_settings_variables.py index 52b784e0..5e0cf791 100644 --- a/tests/templates/sub/project_settings/test_sub_project_settings_variables.py +++ b/tests/templates/sub/project_settings/test_sub_project_settings_variables.py @@ -1,5 +1,5 @@ ALLOWED_MISSING = [] -ALLOWED_NOT_USED = [] +ALLOWED_NOT_USED = ["__generator_sha", "__version_plone_volto"] def test_no_missing_variables(variables_missing): diff --git a/uv.lock b/uv.lock index 2a06d88e..815f4690 100644 --- a/uv.lock +++ b/uv.lock @@ -200,7 +200,7 @@ wheels = [ [[package]] name = "cookieplone" -version = "0.9.6" +version = "0.9.7" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "black" }, @@ -214,9 +214,9 @@ dependencies = [ { name = "xmltodict" }, { name = "zpretty" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/68/7b/3052c94b5724a24509cbcfd2b68ecff98164390798931fb9efebc9e61a40/cookieplone-0.9.6.tar.gz", hash = "sha256:926148228d1827c3502015d0429379f711d95a63022f9aa563d0c9785bc8beda", size = 34276 } +sdist = { url = "https://files.pythonhosted.org/packages/af/5b/54cc74d2d8a56bb8742a805c9df1bc748f2e3e45ef534b4f7da8544f7978/cookieplone-0.9.7.tar.gz", hash = "sha256:1c6dbb4e67a04c3f82bc7120973ac4336dbfb91aa2400898e8719c446467531a", size = 34400 } wheels = [ - { url = "https://files.pythonhosted.org/packages/71/22/f3605c331fbb2f34b2d3e17e60caeb34b626b7605baa218d94f941610648/cookieplone-0.9.6-py3-none-any.whl", hash = "sha256:b22dd1a0daef9153cf30ca032d3adc14f7058bf688ad131ed85a707877319351", size = 29541 }, + { url = "https://files.pythonhosted.org/packages/a9/f8/f165a6f5b3db9dbf82ac33e1f71e884b66fc06ad3d632ffda2265b32e1fc/cookieplone-0.9.7-py3-none-any.whl", hash = "sha256:cf36a7be942efb252fddb210ffdd1e052539a2cdab408cf001915f54404a01d1", size = 29548 }, ] [[package]] @@ -235,7 +235,7 @@ dependencies = [ [package.metadata] requires-dist = [ - { name = "cookieplone", specifier = ">=0.9.6" }, + { name = "cookieplone", specifier = ">=0.9.7" }, { name = "gitpython", specifier = ">=3.1.43" }, { name = "pytest", specifier = ">=8.3.5" }, { name = "pytest-cookies", specifier = ">=0.7.0" },