Skip to content

Commit 445bca4

Browse files
committed
Remove jinja tags from pyproject.toml and remove dependencies through the post hook
1 parent f3f7667 commit 445bca4

File tree

6 files changed

+231
-151
lines changed

6 files changed

+231
-151
lines changed

Diff for: hooks/post_gen_project.py

+124
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
import string
55
from pathlib import Path
66

7+
from tomlkit import dumps, parse
8+
79
try:
810
# Inspired by
911
# https://github.com/django/django/blob/master/django/utils/crypto.py
@@ -502,8 +504,130 @@ def main():
502504
if "{{ cookiecutter.use_async }}".lower() == "n":
503505
remove_async_files()
504506

507+
manipulate_pyproject()
508+
505509
print(SUCCESS + "Project initialized, keep up the good work!" + TERMINATOR)
506510

507511

512+
def manipulate_pyproject():
513+
514+
path = Path("pyproject.toml")
515+
project = parse(path.read_text())
516+
517+
if "{{cookiecutter.frontend_pipeline}}" != "Gulp":
518+
del project["tool"]["pytest"]["ini_options"]["norecursedirs"]
519+
520+
if "{{cookiecutter.use_drf}}" == "y":
521+
project["tool"]["mypy"]["plugins"].append("mypy_drf_plugin.main")
522+
else:
523+
remove_dependency(project, "djangorestframework")
524+
remove_dependency(project, "django-cors-headers")
525+
remove_dependency(project, "drf-spectacular")
526+
527+
if "{{cookiecutter.use_drf}}" == "n":
528+
remove_dev_dependency(project, "djangorestframework-stubs")
529+
530+
if "{{cookiecutter.use_docker}}" == "y":
531+
replace_dependency(project, "psycopg", "psycopg[c]")
532+
else:
533+
replace_dependency(project, "psycopg", "psycopg[binary]")
534+
535+
if "{{cookiecutter.use_async}}" == "n" and "{{cookiecutter.use_async}}" == "n":
536+
remove_dev_dependency(project, "watchfiles")
537+
538+
if "{{cookiecutter.frontend_pipeline}}" != "Django Compressor":
539+
remove_dependency(project, "rcssmin")
540+
remove_dependency(project, "django-compressor")
541+
542+
if "{{cookiecutter.frontend_pipeline}}" != "Webpack":
543+
remove_dependency(project, "django-webpack-loader")
544+
545+
if "{{cookiecutter.use_whitenoise}}" != "y":
546+
remove_dependency(project, "whitenoise")
547+
548+
if "{{cookiecutter.use_whitenoise}}" != "n":
549+
remove_dependency(project, "Collectfasta")
550+
551+
if "{{cookiecutter.use_sentry}}" != "y":
552+
remove_dependency(project, "sentry-sdk")
553+
554+
if "{{cookiecutter.use_docker}}" != "n" or "{{cookiecutter.windows}}" != "y":
555+
remove_dependency(project, "hiredis")
556+
557+
if "{{cookiecutter.use_celery}}" != "y":
558+
remove_dev_dependency(project, "celery")
559+
remove_dev_dependency(project, "django-celery-beat")
560+
561+
if "{{cookiecutter.use_docker}}" != "y":
562+
remove_dev_dependency(project, "flower")
563+
564+
if "{{cookiecutter.use_async}}" != "y":
565+
remove_dependency(project, "uvicorn[standard]")
566+
remove_dependency(project, "uvicorn-worker")
567+
568+
if "{{cookiecutter.cloud_provider}}":
569+
cloud_providers = {
570+
"AWS": "s3",
571+
"GCP": "google",
572+
"Azure": "azure",
573+
}
574+
575+
p = cloud_providers["{{cookiecutter.cloud_provider}}"]
576+
577+
if p:
578+
replace_dependency(project, "django-storages", f"django-storages[{p}]")
579+
else:
580+
remove_dependency(project, "django-storages")
581+
582+
if "{{cookiecutter.mail_service}}":
583+
mail_service_providers = {
584+
"Mailgun": "mailgun",
585+
"Amazon SES": "amazon-ses",
586+
"Mailjet": "mailjet",
587+
"Mandrill": "mandrill",
588+
"Postmark": "postmark",
589+
"Sendgrid": "sendgrid",
590+
"Brevo": "brevo",
591+
"SparkPost": "sparkpost",
592+
"Other SMTP": "",
593+
}
594+
595+
p = mail_service_providers["{{cookiecutter.mail_service}}"]
596+
if p:
597+
replace_dependency(project, "django-anymail", f"django-anymail[{p}]")
598+
else:
599+
remove_dependency(project, "django-anymail")
600+
601+
path.write_text(dumps(project))
602+
603+
604+
def replace_dependency(p, dep, target):
605+
x = []
606+
for i, d in enumerate(p["project"]["dependencies"]):
607+
if d.startswith(dep):
608+
x.append(d.replace(dep, target))
609+
else:
610+
x.append(d)
611+
612+
p["project"]["dependencies"] = x
613+
614+
615+
def remove_dependency(p, dep):
616+
dependencies = []
617+
for i, d in enumerate(p["project"]["dependencies"]):
618+
if not d.startswith(dep):
619+
dependencies.append(d)
620+
p["project"]["dependencies"] = dependencies
621+
622+
623+
def remove_dev_dependency(p, dep):
624+
dependencies = []
625+
for i, d in enumerate(p["dependency-groups"]["dev"]):
626+
if not d.startswith(dep):
627+
dependencies.append(d)
628+
629+
p["dependency-groups"]["dev"] = dependencies
630+
631+
508632
if __name__ == "__main__":
509633
main()

Diff for: pyproject.toml

+1
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ dependencies = [
4545
"requests==2.32.3",
4646
"ruff==0.11.4",
4747
"sh==2.1; sys_platform!='win23'",
48+
"tomlkit>=0.13.2",
4849
"tox==4.23.2",
4950
"tox-uv>=1.17",
5051
]

Diff for: tests/test_cookiecutter_generation.py

+2
Original file line numberDiff line numberDiff line change
@@ -439,6 +439,8 @@ def test_pyproject_toml(cookies, context):
439439
assert data["project"]["authors"][0]["name"] == author_name
440440
assert data["project"]["name"] == context["project_slug"]
441441

442+
assert "norecursedirs" not in data["tool"]["pytest"]["ini_options"]
443+
442444

443445
def test_pre_commit_without_heroku(cookies, context):
444446
context.update({"use_heroku": "n"})

Diff for: tests/test_hooks.py

+25-1
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,14 @@
44
from pathlib import Path
55

66
import pytest
7+
from tomlkit import parse
78

8-
from hooks.post_gen_project import append_to_gitignore_file
9+
from hooks.post_gen_project import (
10+
append_to_gitignore_file,
11+
remove_dependency,
12+
remove_dev_dependency,
13+
replace_dependency,
14+
)
915

1016

1117
@pytest.fixture
@@ -25,3 +31,21 @@ def test_append_to_gitignore_file(working_directory):
2531
linesep = os.linesep.encode()
2632
assert gitignore_file.read_bytes() == b"node_modules/" + linesep + b".envs/*" + linesep
2733
assert gitignore_file.read_text() == "node_modules/\n.envs/*\n"
34+
35+
36+
def test_replace_dependency():
37+
38+
def has_dependency(dependencies: list[str], dependency: str):
39+
return any(dep.startswith(dependency) or dep == dependency for dep in dependencies)
40+
41+
p = Path(__file__).parent.parent / "{{cookiecutter.project_slug}}" / "pyproject.toml"
42+
project = parse(p.read_text())
43+
44+
remove_dependency(project, "djangorestframework")
45+
remove_dev_dependency(project, "djangorestframework-stubs")
46+
47+
replace_dependency(project, "psycopg", "psycopg[c]")
48+
49+
assert has_dependency(project["project"]["dependencies"], "psycopg[c]")
50+
assert not has_dependency(project["project"]["dependencies"], "djangorestframework")
51+
assert not has_dependency(project["dependency-groups"]["dev"], "djangorestframework-stubs")

Diff for: uv.lock

+11
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)