Skip to content

Commit

Permalink
Support Python packages with no namespace or multiple namespaces
Browse files Browse the repository at this point in the history
  • Loading branch information
davisagli committed Oct 27, 2024
1 parent 6f17615 commit 510b2a2
Show file tree
Hide file tree
Showing 76 changed files with 83 additions and 103 deletions.
13 changes: 5 additions & 8 deletions backend_addon/cookiecutter.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,11 @@
"email": "[email protected]",
"github_organization": "collective",
"python_package_name": "{{ cookiecutter.github_organization|lower }}.{{ cookiecutter.title|replace(' ', '')|replace('-', '_')|replace('.', '')|lower }}",
"feature_headless": [
"1",
"0"
],
"feature_headless": ["1", "0"],
"__feature_headless": "{{ cookiecutter.feature_headless }}",
"__feature_distribution": "0",
"__package_name": "{{ cookiecutter.python_package_name | package_name }}",
"__package_namespace": "{{ cookiecutter.python_package_name | package_namespace }}",
"__package_namespaces": "{{ cookiecutter.python_package_name | package_namespaces }}",
"__package_path": "{{ cookiecutter.python_package_name | package_path }}",
"__folder_name": "{{ cookiecutter.python_package_name }}",
"__python_package_name_upper": "{{ cookiecutter.python_package_name | pascal_case }}",
"__profile_language": "en",
Expand All @@ -38,8 +35,8 @@
"_copy_without_render": [],
"_extensions": [
"cookieplone.filters.pascal_case",
"cookieplone.filters.package_name",
"cookieplone.filters.package_namespace"
"cookieplone.filters.package_namespaces",
"cookieplone.filters.package_path"
],
"__cookieplone_repository_path": "",
"__cookieplone_template": ""
Expand Down
36 changes: 24 additions & 12 deletions backend_addon/hooks/post_gen_project.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@
from collections import OrderedDict
from copy import deepcopy
from pathlib import Path
import os

from cookieplone.settings import QUIET_MODE_VAR
from cookieplone.utils import console, files, git, plone

context: OrderedDict = {{cookiecutter}}
Expand All @@ -18,12 +20,18 @@


def handle_feature_headless(context: OrderedDict, output_dir: Path):
package_namespace = context.get("__package_namespace")
package_name = context.get("__package_name")
output_dir = output_dir / "src" / package_namespace / package_name
output_dir = output_dir / "src" / "packagename"
files.remove_files(output_dir, FEATURES_TO_REMOVE["feature_headless"])


def handle_create_namespace_packages(context: OrderedDict, output_dir: Path):
plone.create_namespace_packages(output_dir / "src/packagename", context["python_package_name"])


def handle_format(context: OrderedDict, output_dir: Path):
plone.format_python_codebase(output_dir)


def handle_git_initialization(context: OrderedDict, output_dir: Path):
"""Initialize a GIT repository for the project codebase."""
git.initialize_repository(output_dir)
Expand All @@ -32,9 +40,11 @@ def handle_git_initialization(context: OrderedDict, output_dir: Path):
def main():
"""Final fixes."""
output_dir = Path().cwd()
is_subtemplate = os.environ.get(QUIET_MODE_VAR) == "1"
remove_headless = not int(
context.get("feature_headless")
) # {{ cookiecutter.__feature_headless }}
create_namespace_packages = not is_subtemplate
initialize_git = bool(
int(context.get("__backend_addon_git_initialize"))
) # {{ cookiecutter.__backend_addon_git_initialize }}
Expand All @@ -48,6 +58,16 @@ def main():
"Remove files used in headless setup",
remove_headless,
],
[
handle_create_namespace_packages,
"Create namespace packages",
create_namespace_packages,
],
[
handle_format,
"Format code",
backend_format,
],
[
handle_git_initialization,
"Initialize Git repository",
Expand All @@ -61,18 +81,10 @@ def main():
console.print(f" -> {title}")
func(new_context, output_dir)

# Run format
if backend_format:
plone.format_python_codebase(output_dir)

msg = """
[bold blue]{{ cookiecutter.title }}[/bold blue]
Now, enter the repository run the code formatter with:
make format
start coding, and push to your organization.
Now, enter the repository, start coding, and push to your organization.
Sorry for the convenience,
The Plone Community.
Expand Down
11 changes: 4 additions & 7 deletions backend_addon/tests/test_cutter.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,8 @@ def test_root_files_generated(cutter_result, file_path):
@pytest.mark.parametrize("file_path", PKG_SRC_FILES)
def test_pkg_src_files_generated(cutter_result, file_path: str):
"""Check if distribution files were generated."""
package_namespace = cutter_result.context["__package_namespace"]
package_name = cutter_result.context["__package_name"]
file_path = file_path.format(package_name=package_name)
src_path = cutter_result.project_path / "src" / package_namespace / package_name
package_path = cutter_result.context["__package_path"]
src_path = cutter_result.project_path / "src" / package_path
path = src_path / file_path
assert path.exists()
assert path.is_file()
Expand All @@ -52,9 +50,8 @@ def test_pkg_src_files_generated(cutter_result, file_path: str):
@pytest.mark.parametrize("file_path", PKG_SRC_FEATURE_HEADLESS)
def test_pkg_src_feature_files_generated(cutter_result, file_path: str):
"""Check if feature-specific files were generated."""
package_namespace = cutter_result.context["__package_namespace"]
package_name = cutter_result.context["__package_name"]
src_path = cutter_result.project_path / "src" / package_namespace / package_name
package_path = cutter_result.context["__package_path"]
src_path = cutter_result.project_path / "src" / package_path
path = src_path / file_path
assert path.exists()
assert path.is_file()
Expand Down
13 changes: 6 additions & 7 deletions backend_addon/tests/test_cutter_no_headless.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,8 @@ def test_root_files_generated(cutter_result, file_path):
@pytest.mark.parametrize("file_path", PKG_SRC_FILES)
def test_pkg_src_files_generated(cutter_result, file_path: str):
"""Check if distribution files were generated."""
package_namespace = cutter_result.context["__package_namespace"]
package_name = cutter_result.context["__package_name"]
file_path = file_path.format(package_name=package_name)
src_path = cutter_result.project_path / "src" / package_namespace / package_name
package_path = cutter_result.context["__package_path"]
src_path = cutter_result.project_path / "src" / package_path
path = src_path / file_path
assert path.exists()
assert path.is_file()
Expand All @@ -56,8 +54,9 @@ def test_pkg_src_files_generated(cutter_result, file_path: str):
@pytest.mark.parametrize("file_path", PKG_SRC_FEATURE_HEADLESS)
def test_pkg_src_headless_files_not_generated(cutter_result, file_path: str):
"""Check feature-specific files were not generated."""
package_namespace = cutter_result.context["__package_namespace"]
package_name = cutter_result.context["__package_name"]
src_path = cutter_result.project_path / "src" / package_namespace / package_name
package_path = cutter_result.context["__package_path"]
src_path = cutter_result.project_path / "src" / package_path
path = src_path / file_path
assert path.exists() is False

# test with 0 and 2 namespaces
2 changes: 1 addition & 1 deletion backend_addon/{{ cookiecutter.__folder_name }}/MANIFEST.in
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
graft src/{{ cookiecutter.__package_namespace }}
graft src/{{ cookiecutter.__package_path }}
graft docs
graft news
graft tests
Expand Down
2 changes: 1 addition & 1 deletion backend_addon/{{ cookiecutter.__folder_name }}/setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@
},
license="GPL version 2",
packages=find_packages("src", exclude=["ez_setup"]),
namespace_packages=["{{ cookiecutter.__package_namespace }}"],
namespace_packages=[{{ cookiecutter.__package_namespaces }}],
package_dir={"": "src"},
include_package_data=True,
zip_safe=False,
Expand Down

This file was deleted.

1 change: 0 additions & 1 deletion frontend_addon/tests/test_cutter.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,6 @@ def test_root_files_generated(cutter_result, file_path):
def test_pkg_src_files_generated(cutter_result, file_path: str):
"""Check if package files were generated."""
package_name = cutter_result.context["frontend_addon_name"]
file_path = file_path.format(package_name=package_name)
src_path = cutter_result.project_path / "packages" / package_name
path = src_path / file_path
assert path.exists()
Expand Down
24 changes: 5 additions & 19 deletions project/cookiecutter.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,23 +12,10 @@
"frontend_addon_name": "volto-{{ cookiecutter.python_package_name|replace('_', '-')|replace('.', '-') }}",
"language_code": ["en", "de", "es", "pt-br", "nl", "fi"],
"github_organization": "collective",
"container_registry": [
"github",
"docker_hub",
"gitlab"
],
"devops_cache": [
"1",
"0"
],
"devops_ansible": [
"1",
"0"
],
"devops_gha_deploy": [
"1",
"0"
],
"container_registry": ["github", "docker_hub", "gitlab"],
"devops_cache": ["1", "0"],
"devops_ansible": ["1", "0"],
"devops_gha_deploy": ["1", "0"],
"__feature_headless": "1",
"__npm_package_name": "{{ cookiecutter.frontend_addon_name }}",
"__folder_name": "{{ cookiecutter.project_slug }}",
Expand Down Expand Up @@ -65,8 +52,8 @@
"__devops_varnish_version": "7.4",
"__devops_db_version": "14",
"__devops_db_password": "{{ random_ascii_string(12) }}",
"__backend_addon_format": "1",
"__backend_addon_git_initialize": "0",
"__backend_addon_format": "1",
"__project_git_initialize": "1",
"__prompts__": {
"title": "Project Title",
Expand Down Expand Up @@ -119,7 +106,6 @@
"devops/tasks",
"devops/inventory/group_vars/all/users.yml",
"devops/inventory/group_vars/all/projects.yml"

],
"_extensions": [
"cookieplone.filters.use_prerelease_versions",
Expand Down
3 changes: 3 additions & 0 deletions project/hooks/post_gen_project.py
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,9 @@ def main():
console.print(f" -> {title}")
func(new_context, output_dir)

# Create namespace packages
plone.create_namespace_packages(output_dir / "backend/src/packagename", context["python_package_name"])

# Run format
if backend_format:
backend_folder = output_dir / "backend"
Expand Down
16 changes: 3 additions & 13 deletions sub/cache/cookiecutter.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,9 @@
"project_slug": "{{ cookiecutter.title | slugify }}",
"author": "Plone Foundation",
"email": "[email protected]",
"python_package_name": "{{ cookiecutter.project_slug|replace(' ', '')|replace('-', '.') }}",
"github_organization": "collective",
"container_registry": [
"github",
"docker_hub",
"gitlab"
],
"container_registry": ["github", "docker_hub", "gitlab"],
"__folder_name": "{{ cookiecutter.project_slug }}",
"__package_name": "{{ cookiecutter.python_package_name | package_name }}",
"__package_namespace": "{{ cookiecutter.python_package_name | package_namespace }}",
"__container_registry_prefix": "{{ cookiecutter.container_registry | image_prefix }}",
"__container_image_prefix": "{{ cookiecutter.__container_registry_prefix }}{{ cookiecutter.github_organization }}/{{ cookiecutter.project_slug }}",
"__gha_version_checkout": "v4",
Expand All @@ -22,13 +15,10 @@
"__gha_version_docker_login": "v3",
"__gha_version_docker_build_push": "v4",
"__devops_varnish_version": "7.4",
"_copy_without_render": [
],
"_copy_without_render": [],
"_extensions": [
"cookieplone.filters.extract_host",
"cookieplone.filters.image_prefix",
"cookieplone.filters.package_name",
"cookieplone.filters.package_namespace"
"cookieplone.filters.image_prefix"
],
"__cookieplone_repository_path": "",
"__cookieplone_template": ""
Expand Down
4 changes: 1 addition & 3 deletions sub/cache/hooks/post_gen_project.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,7 @@ def set_configurations(package_root: Path, context: OrderedDict):
def main():
"""Final fixes."""
output_dir = Path().cwd()
namespace = context.get("__package_namespace")
package_name = context.get("__package_name")
package_root = output_dir / "backend/src" / namespace / package_name
package_root = output_dir / "backend/src/packagename"
set_configurations(package_root, context)


Expand Down
4 changes: 2 additions & 2 deletions sub/cache/tests/test_cutter.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,8 @@ def test_json_schema(
"file_path",
[
".github/workflows/varnish.yml",
"backend/src/project/title/profiles/default/registry/plone.cachepurging.interfaces.ICachePurgingSettings.xml", # noQA
"backend/src/project/title/profiles/default/registry/plone.caching.interfaces.ICacheSettings.xml", # noQA
"backend/src/packagename/profiles/default/registry/plone.cachepurging.interfaces.ICachePurgingSettings.xml", # noQA
"backend/src/packagename/profiles/default/registry/plone.caching.interfaces.ICacheSettings.xml", # noQA
"devops/varnish/etc/varnish.vcl",
"devops/varnish/Dockerfile",
],
Expand Down
8 changes: 4 additions & 4 deletions sub/project_settings/cookiecutter.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@
"__container_registry_prefix": "{{ cookiecutter.container_registry | image_prefix }}",
"__container_image_prefix": "{{ cookiecutter.__container_registry_prefix }}{{ cookiecutter.github_organization }}/{{ cookiecutter.project_slug }}",
"__folder_name": "{{ cookiecutter.project_slug }}",
"__package_name": "{{ cookiecutter.python_package_name | package_name }}",
"__package_namespace": "{{ cookiecutter.python_package_name | package_namespace }}",
"__package_namespaces": "{{ cookiecutter.python_package_name | package_namespaces }}",
"__package_path": "{{ cookiecutter.python_package_name | package_path }}",
"__profile_language": "{{ cookiecutter.language_code|gs_language_code }}",
"__locales_language": "{{ cookiecutter.language_code|locales_language_code }}",
"_copy_without_render": [],
Expand All @@ -28,8 +28,8 @@
"cookieplone.filters.pascal_case",
"cookieplone.filters.locales_language_code",
"cookieplone.filters.gs_language_code",
"cookieplone.filters.package_name",
"cookieplone.filters.package_namespace",
"cookieplone.filters.package_namespaces",
"cookieplone.filters.package_path",
"cookieplone.filters.latest_volto",
"cookieplone.filters.latest_plone"
],
Expand Down
42 changes: 21 additions & 21 deletions sub/project_settings/tests/test_cutter.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,27 +33,27 @@ def test_variable_substitution(build_files_list, variable_pattern, cutter_result
"backend/requirements-docker.txt",
"backend/scripts/create_site.py",
"backend/setup.py",
"backend/src/project/title/locales/__init__.py",
"backend/src/project/title/locales/en/LC_MESSAGES/project.title.po",
"backend/src/project/title/locales/project.title.pot",
"backend/src/project/title/locales/update.py",
"backend/src/project/title/profiles/default/registry/plone.base.interfaces.controlpanel.IMailSchema.xml", # noQA
"backend/src/project/title/profiles/default/registry/plone.base.interfaces.controlpanel.ISiteSchema.xml", # noQA
"backend/src/project/title/profiles/default/registry/plone.i18n.interfaces.ILanguageSchema.xml",
"backend/src/project/title/profiles/initial/metadata.xml",
"backend/src/project/title/setuphandlers/examplecontent/.gitkeep",
"backend/src/project/title/setuphandlers/examplecontent/content/__metadata__.json",
"backend/src/project/title/setuphandlers/examplecontent/content/a58ccead718140c1baa98d43595fc3e6/data.json",
"backend/src/project/title/setuphandlers/examplecontent/content/a58ccead718140c1baa98d43595fc3e6/image/plone-foundation.png",
"backend/src/project/title/setuphandlers/examplecontent/content/a720393b3c0240e5bd27c43fcd2cfd1e/data.json",
"backend/src/project/title/setuphandlers/examplecontent/content/plone_site_root/data.json",
"backend/src/project/title/setuphandlers/examplecontent/discussions.json",
"backend/src/project/title/setuphandlers/examplecontent/portlets.json",
"backend/src/project/title/setuphandlers/examplecontent/principals.json",
"backend/src/project/title/setuphandlers/examplecontent/redirects.json",
"backend/src/project/title/setuphandlers/examplecontent/relations.json",
"backend/src/project/title/setuphandlers/examplecontent/translations.json",
"backend/src/project/title/setuphandlers/initial.py",
"backend/src/packagename/locales/__init__.py",
"backend/src/packagename/locales/en/LC_MESSAGES/project.title.po",
"backend/src/packagename/locales/project.title.pot",
"backend/src/packagename/locales/update.py",
"backend/src/packagename/profiles/default/registry/plone.base.interfaces.controlpanel.IMailSchema.xml", # noQA
"backend/src/packagename/profiles/default/registry/plone.base.interfaces.controlpanel.ISiteSchema.xml", # noQA
"backend/src/packagename/profiles/default/registry/plone.i18n.interfaces.ILanguageSchema.xml",
"backend/src/packagename/profiles/initial/metadata.xml",
"backend/src/packagename/setuphandlers/examplecontent/.gitkeep",
"backend/src/packagename/setuphandlers/examplecontent/content/__metadata__.json",
"backend/src/packagename/setuphandlers/examplecontent/content/a58ccead718140c1baa98d43595fc3e6/data.json",
"backend/src/packagename/setuphandlers/examplecontent/content/a58ccead718140c1baa98d43595fc3e6/image/plone-foundation.png",
"backend/src/packagename/setuphandlers/examplecontent/content/a720393b3c0240e5bd27c43fcd2cfd1e/data.json",
"backend/src/packagename/setuphandlers/examplecontent/content/plone_site_root/data.json",
"backend/src/packagename/setuphandlers/examplecontent/discussions.json",
"backend/src/packagename/setuphandlers/examplecontent/portlets.json",
"backend/src/packagename/setuphandlers/examplecontent/principals.json",
"backend/src/packagename/setuphandlers/examplecontent/redirects.json",
"backend/src/packagename/setuphandlers/examplecontent/relations.json",
"backend/src/packagename/setuphandlers/examplecontent/translations.json",
"backend/src/packagename/setuphandlers/initial.py",
"frontend/.dockerignore",
"frontend/Dockerfile",
"frontend/Makefile",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ endif
PLONE_SITE_ID=Plone
BACKEND_FOLDER=$(shell dirname $(realpath $(firstword $(MAKEFILE_LIST))))
PLONE_VERSION=$(shell cat $(BACKEND_FOLDER)/version.txt)
EXAMPLE_CONTENT_FOLDER=${BACKEND_FOLDER}/src/{{ cookiecutter.__package_namespace }}/{{ cookiecutter.__package_name }}/setuphandlers/examplecontent
EXAMPLE_CONTENT_FOLDER=${BACKEND_FOLDER}/src/{{ cookiecutter.__package_path }}/setuphandlers/examplecontent

GIT_FOLDER=$(BACKEND_FOLDER)/.git
VENV_FOLDER=$(BACKEND_FOLDER)/.venv
Expand Down Expand Up @@ -132,7 +132,7 @@ build-image: ## Build Docker Images
# Acceptance tests
.PHONY: acceptance-backend-start
acceptance-backend-start: ## Start backend acceptance server
ZSERVER_HOST=0.0.0.0 ZSERVER_PORT=55001 LISTEN_PORT=55001 APPLY_PROFILES="{{ cookiecutter.__package_namespace }}/{{ cookiecutter.__package_name }}:default" CONFIGURE_PACKAGES="plone.restapi,plone.volto,plone.volto.cors,{{ cookiecutter.__package_namespace }}/{{ cookiecutter.__package_name }}" $(BIN_FOLDER)/robot-server plone.app.robotframework.testing.VOLTO_ROBOT_TESTING
ZSERVER_HOST=0.0.0.0 ZSERVER_PORT=55001 LISTEN_PORT=55001 APPLY_PROFILES="{{ cookiecutter.python_package_name }}:default" CONFIGURE_PACKAGES="plone.restapi,plone.volto,plone.volto.cors,{{ cookiecutter.python_package_name }}" $(BIN_FOLDER)/robot-server plone.app.robotframework.testing.VOLTO_ROBOT_TESTING

.PHONY: acceptance-image-build
acceptance-image-build: ## Build Docker Images
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@
},
license="GPL version 2",
packages=find_packages("src", exclude=["ez_setup"]),
namespace_packages=["{{ cookiecutter.__package_namespace }}"],
namespace_packages=[{{ cookiecutter.__package_namespaces }}],
package_dir={"": "src"},
include_package_data=True,
zip_safe=False,
Expand Down

0 comments on commit 510b2a2

Please sign in to comment.