Skip to content

Commit

Permalink
Improved cookiecutter templates
Browse files Browse the repository at this point in the history
This change will extract the actual test matrix from the existing file
and reproduce it as part of the template. No need to configure it in
pyproject.toml anymore.

[noissue]
  • Loading branch information
mdellweg committed Mar 23, 2024
1 parent 838502d commit d6d1d33
Show file tree
Hide file tree
Showing 9 changed files with 200 additions and 39 deletions.
28 changes: 14 additions & 14 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,24 +16,24 @@ jobs:
fail-fast: false
matrix:
include:
- python: "3.11"
image_tag: "nightly"
- image_tag: "nightly"
pulp_api_root: "/relocated/djnd/"
- python: "3.11"
image_tag: "latest"
- python: "3.12"
image_tag: "3.39"
- python: "3.12"
image_tag: "3.28"
python: "3.11"
- image_tag: "latest"
python: "3.11"
- image_tag: "3.39"
python: "3.12"
- image_tag: "3.28"
lower_bounds: true
- python: "3.8"
image_tag: "3.22"
- python: "3.9"
image_tag: "3.21"
python: "3.12"
- image_tag: "3.22"
python: "3.8"
- image_tag: "3.21"
pulp_api_root: "/relocated/djnd/"
- python: "3.10"
image_tag: "3.18"
python: "3.9"
- image_tag: "3.18"
lower_bounds: true
python: "3.10"
steps:
- uses: "actions/checkout@v4"
- uses: "actions/cache@v4"
Expand Down
10 changes: 9 additions & 1 deletion .ci/scripts/apply_templates.py → cookiecutter/apply_templates.py
100644 → 100755
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
#!/bin/env python3

from pathlib import Path

import toml
import yaml

from cookiecutter.main import cookiecutter

if __name__ == "__main__":
Expand All @@ -10,12 +14,16 @@
with open("pyproject.toml") as fp:
config = toml.load(fp)["tool"]["pulp_cli_template"]

# CI
sections.append("ci")
with open(".github/workflows/test.yml") as fp:
config["test_matrix"] = yaml.safe_load(fp)["jobs"]["test"]["strategy"]["matrix"]

# Docs
if config["docs"]:
sections.append("docs")

cutter_path = Path(__file__).parent.parent.parent / "cookiecutter"
cutter_path = Path(__file__).parent

for section in sections:
print(f"Apply {section} template")
Expand Down
4 changes: 3 additions & 1 deletion cookiecutter/ci/cookiecutter.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,12 @@
"__project_name": "pulp-cli{{ cookiecutter.__app_label_suffix }}",
"__project_slug": "{{ cookiecutter.__project_name | lower | replace(' ', '_') }}",
"_copy_without_render": [
"CHANGES/.TEMPLATE.md",
".github/workflows/collect_changes.yml",
".github/workflows/pr.yml",
".github/workflows/release.yml",
".github/workflows/release_branch.yml",
".github/workflows/pr_checks.yml"
]
],
"_extensions": [".pulp_filter_extension.PulpFilterExtension"]
}
17 changes: 17 additions & 0 deletions cookiecutter/ci/hooks/post_gen_project.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# flake8: noqa

import os
import shutil
import sys

REMOVE_PATHS = [
{% if not cookiecutter.glue -%} "CHANGES/pulp-glue{{ cookiecutter.__app_label_suffix }}", {%- endif %}
]

for path in REMOVE_PATHS:
path = path.strip()
if path and os.path.exists(path):
if os.path.isdir(path):
shutil.rmtree(path)
else:
os.unlink(path)
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,7 @@ jobs:
runs-on: "ubuntu-20.04"
strategy:
fail-fast: false
matrix:
include:
{{ cookiecutter.test_matrix | indent(10) }}
matrix:{{ cookiecutter.test_matrix | to_nice_yaml(level=4, embed_in="dict") }}
steps:
- uses: "actions/checkout@v4"
{%- include "cache_action" %}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@

{# TOWNCRIER TEMPLATE #}
{% for section, _ in sections.items() %}
{%- set section_slug = "-" + section|replace(" ", "-")|replace("_", "-")|lower %}
{% if section %}### {{section}} {: #{{versiondata.version}}{{section_slug}} }

{% else %}
{%- set section_slug = "" %}
{% endif %}

{% if sections[section] %}
{% for category, val in definitions.items() if category in sections[section]%}
#### {{ definitions[category]['name'] }} {: #{{versiondata.version}}{{section_slug}}-{{category}} }

{% if definitions[category]['showcontent'] %}
{% for text, values in sections[section][category].items() %}
- {{ text }}
{% if values %}
{{ values|join(',\n ') }}
{% endif %}
{% endfor %}

{% else %}
- {{ sections[section][category]['']|join(', ') }}

{% endif %}
{% if sections[section][category]|length == 0 %}
No significant changes.

{% else %}
{% endif %}

{% endfor %}
{% else %}
No significant changes.


{% endif %}
{% endfor %}
---


113 changes: 113 additions & 0 deletions cookiecutter/pulp_filter_extension.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
import shlex
import typing as t

from jinja2 import Environment
from jinja2.ext import Extension


def _assert_key(key: t.Any) -> str:
assert isinstance(key, str)
assert key.isidentifier()
return key


def to_nice_yaml(data: t.Any, level: int = 0, embed_in: str = "") -> str:
"""Filter for Jinja 2 templates to render human readable YAML."""
# Don't even believe this is complete!
# Yes, I have checked pyyaml and ruamel.
# Should I call this markup language "jaml" or "yson"?

nl = False
if isinstance(data, str):
result = f'"{data}"'
elif data is True:
result = "true"
elif data is False:
result = "false"
elif isinstance(data, int):
result = f"{data}"
elif isinstance(data, list):
if len(data):
nl = embed_in == "dict"
result = ("\n" + " " * level).join(
("-" + to_nice_yaml(item, level + 1, "list") for item in data)
)
else:
result = "[]"
elif isinstance(data, dict):
if len(data):
nl = embed_in == "dict"
result = ("\n" + " " * level).join(
(
f"{_assert_key(key)}:" + to_nice_yaml(value, level + 1, "dict")
for key, value in sorted(data.items())
)
)
else:
result = "{}"
else:
raise NotImplementedError("YAML sucks!")
if nl:
return "\n" + " " * level + result
elif embed_in:
return " " + result
else:
return result


def to_camel(name: str) -> str:
return name.title().replace("_", "")


def to_dash(name: str) -> str:
return name.replace("_", "-")


def to_snake(name: str) -> str:
return name.replace("-", "_")


class PulpFilterExtension(Extension):
def __init__(self, environment: Environment):
super().__init__(environment)
environment.filters["camel"] = to_camel
environment.filters["caps"] = str.upper
environment.filters["dash"] = to_dash
environment.filters["snake"] = to_snake
environment.filters["to_nice_yaml"] = to_nice_yaml
environment.filters["shquote"] = shlex.quote


try:
import pytest
except ImportError:
pass
else:

@pytest.mark.parametrize(
"value,level,embed_in,out",
[
([], 0, "", "[]"),
({}, 0, "", "{}"),
("test", 0, "", '"test"'),
({}, 1, "dict", " {}"),
([], 1, "list", " []"),
({}, 1, "list", " {}"),
([], 1, "dict", " []"),
([{}], 0, "", "- {}"),
([[[]]], 0, "", "- - []"),
(
{"a": [], "b": "test", "c": [True, False]},
2,
"list",
""" a: []
b: "test"
c:
- true
- false""",
),
({"b": 1, "a": 0}, 0, "", "a: 0\nb: 1"),
],
)
def test_to_nice_yaml(value, level, embed_in, out):
assert to_nice_yaml(value, level, embed_in) == out
21 changes: 1 addition & 20 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -66,26 +66,6 @@ namespaces = true
app_label = ""
docs = true
translations = true
test_matrix = """
- python: "3.11"
image_tag: "nightly"
pulp_api_root: "/relocated/djnd/"
- python: "3.11"
image_tag: "latest"
- python: "3.12"
image_tag: "3.39"
- python: "3.12"
image_tag: "3.28"
lower_bounds: true
- python: "3.8"
image_tag: "3.22"
- python: "3.9"
image_tag: "3.21"
pulp_api_root: "/relocated/djnd/"
- python: "3.10"
image_tag: "3.18"
lower_bounds: true
"""

[tool.towncrier]
filename = "docs/CHANGES.md"
Expand Down Expand Up @@ -141,6 +121,7 @@ showcontent = false

[tool.black]
line-length = 100
exclude = "cookiecutter/ci/hooks"

[tool.isort]
profile = "black"
Expand Down

0 comments on commit d6d1d33

Please sign in to comment.