Repository: beeware/briefcase

Issue:
Remove upper bound pin `<2.6.0` for cookiecutter
### Describe the bug

Release 2.6.0 of cookiecutter changed whitespace control behavior so it is now pinned `<2.6.0`. This should be removed when this issue is resolved.
- https://github.com/cookiecutter/cookiecutter/issues/2023

### Steps to reproduce

See `pyproject.toml`.

### Expected behavior

cookiecutter has a looser upper bound.

### Screenshots

_No response_

### Environment

- Operating System: all
- Python version: all
- Software versions:
  - Briefcase: `0.3.18.dev65+gb09da47e.d20240223`

### Logs

_No response_

### Additional context

_No response_


Discussion:
I tracked down the source of the templating changes with `cookiecutter==2.6.0`; the details are in https://github.com/cookiecutter/cookiecutter/issues/2023#issuecomment-2043262182 but the takeaway is `cookiecutter` is now respecting the configuration in `_jinja2_env_vars` for resolving templating in the `context` dict as well as the templating in the template repo; previously, the template rendering of the `context` dict ignored what was in `_jinja2_env_vars`. (This definitely helps explain why whitespace control was so incredibly unwieldy when I refactored briefcase-template in to bootstraps...)

So, I expect this to mean that this regression in `cookiecutter` will not be reverted since, IMO, it makes sense for this configuration to be respected for all templating. Therefore, any templates using `_jinja2_env_vars` should be updated to support this new behavior and Briefcase should pin `cookiecutter>=2.6.0`. (This may just be limited to `briefcase-template`.)



Patch:
diff --git a/changes/1663.bugfix.rst b/changes/1663.bugfix.rst
new file mode 100644
index 000000000..6b8b00a39
--- /dev/null
+++ b/changes/1663.bugfix.rst
@@ -0,0 +1,1 @@
+Creating new projects is now compatible with cookiecutter v2.6.0.
diff --git a/pyproject.toml b/pyproject.toml
index 76cda1c9b..f0f74e92a 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -80,7 +80,7 @@ dependencies = [
     # If the package uses calver, we don't pin the upper version, as the upper version
     # provides no basis for determining API stability.
     #
-    "cookiecutter >= 2.3.1, < 2.6.0",  # See beeware/briefcase#1663 to bump <2.6.0 pin
+    "cookiecutter >= 2.6.0, < 3.0",
     "dmgbuild >= 1.6, < 2.0; sys_platform == 'darwin'",
     "GitPython >= 3.1, < 4.0",
     "platformdirs >= 2.6, < 5.0",
diff --git a/src/briefcase/bootstraps/pursuedpybear.py b/src/briefcase/bootstraps/pursuedpybear.py
index ae61847ca..efbe5a463 100644
--- a/src/briefcase/bootstraps/pursuedpybear.py
+++ b/src/briefcase/bootstraps/pursuedpybear.py
@@ -49,19 +49,18 @@ def main():
 
     def pyproject_table_briefcase_app_extra_content(self):
         return """
-
 requires = [
     "ppb~=3.2.0",
 ]
 test_requires = [
-{%- if cookiecutter.test_framework == "pytest" %}
+{% if cookiecutter.test_framework == "pytest" %}
     "pytest",
-{%- endif %}
+{% endif %}
 ]
 """
 
     def pyproject_table_macOS(self):
-        return """
+        return """\
 universal_build = true
 requires = [
     "std-nslog~=1.0.0",
@@ -69,13 +68,13 @@ def pyproject_table_macOS(self):
 """
 
     def pyproject_table_linux(self):
-        return """
+        return """\
 requires = [
 ]
 """
 
     def pyproject_table_linux_system_debian(self):
-        return """
+        return """\
 system_requires = [
 ]
 
@@ -89,7 +88,7 @@ def pyproject_table_linux_system_debian(self):
 """
 
     def pyproject_table_linux_system_rhel(self):
-        return """
+        return """\
 system_requires = [
 ]
 
@@ -104,7 +103,7 @@ def pyproject_table_linux_system_rhel(self):
 """
 
     def pyproject_table_linux_system_suse(self):
-        return """
+        return """\
 system_requires = [
 ]
 
@@ -119,7 +118,7 @@ def pyproject_table_linux_system_suse(self):
 """
 
     def pyproject_table_linux_system_arch(self):
-        return """
+        return """\
 system_requires = [
 ]
 
@@ -133,7 +132,7 @@ def pyproject_table_linux_system_arch(self):
 """
 
     def pyproject_table_linux_appimage(self):
-        return """
+        return """\
 manylinux = "manylinux_2_28"
 
 system_requires = [
@@ -144,29 +143,29 @@ def pyproject_table_linux_appimage(self):
 """
 
     def pyproject_table_linux_flatpak(self):
-        return """
+        return """\
 flatpak_runtime = "org.freedesktop.Platform"
 flatpak_runtime_version = "23.08"
 flatpak_sdk = "org.freedesktop.Sdk"
 """
 
     def pyproject_table_windows(self):
-        return """
+        return """\
 requires = [
 ]
 """
 
     def pyproject_table_iOS(self):
-        return """
+        return """\
 supported = false
 """
 
     def pyproject_table_android(self):
-        return """
+        return """\
 supported = false
 """
 
     def pyproject_table_web(self):
-        return """
+        return """\
 supported = false
 """
diff --git a/src/briefcase/bootstraps/pygame.py b/src/briefcase/bootstraps/pygame.py
index 3e5f87e4e..70693a5b6 100644
--- a/src/briefcase/bootstraps/pygame.py
+++ b/src/briefcase/bootstraps/pygame.py
@@ -59,19 +59,18 @@ def main():
 
     def pyproject_table_briefcase_app_extra_content(self):
         return """
-
 requires = [
     "pygame~=2.2",
 ]
 test_requires = [
-{%- if cookiecutter.test_framework == "pytest" %}
+{% if cookiecutter.test_framework == "pytest" %}
     "pytest",
-{%- endif %}
+{% endif %}
 ]
 """
 
     def pyproject_table_macOS(self):
-        return """
+        return """\
 universal_build = true
 requires = [
     "std-nslog~=1.0.0",
@@ -79,13 +78,13 @@ def pyproject_table_macOS(self):
 """
 
     def pyproject_table_linux(self):
-        return """
+        return """\
 requires = [
 ]
 """
 
     def pyproject_table_linux_system_debian(self):
-        return """
+        return """\
 system_requires = [
 ]
 
@@ -94,7 +93,7 @@ def pyproject_table_linux_system_debian(self):
 """
 
     def pyproject_table_linux_system_rhel(self):
-        return """
+        return """\
 system_requires = [
 ]
 
@@ -103,7 +102,7 @@ def pyproject_table_linux_system_rhel(self):
 """
 
     def pyproject_table_linux_system_suse(self):
-        return """
+        return """\
 system_requires = [
 ]
 
@@ -112,7 +111,7 @@ def pyproject_table_linux_system_suse(self):
 """
 
     def pyproject_table_linux_system_arch(self):
-        return """
+        return """\
 system_requires = [
 ]
 
@@ -121,7 +120,7 @@ def pyproject_table_linux_system_arch(self):
 """
 
     def pyproject_table_linux_appimage(self):
-        return """
+        return """\
 manylinux = "manylinux_2_28"
 
 system_requires = [
@@ -132,29 +131,29 @@ def pyproject_table_linux_appimage(self):
 """
 
     def pyproject_table_linux_flatpak(self):
-        return """
+        return """\
 flatpak_runtime = "org.freedesktop.Platform"
 flatpak_runtime_version = "23.08"
 flatpak_sdk = "org.freedesktop.Sdk"
 """
 
     def pyproject_table_windows(self):
-        return """
+        return """\
 requires = [
 ]
 """
 
     def pyproject_table_iOS(self):
-        return """
+        return """\
 supported = false
 """
 
     def pyproject_table_android(self):
-        return """
+        return """\
 supported = false
 """
 
     def pyproject_table_web(self):
-        return """
+        return """\
 supported = false
 """
diff --git a/src/briefcase/bootstraps/pyside6.py b/src/briefcase/bootstraps/pyside6.py
index e8dbcbeea..aa52cd7ba 100644
--- a/src/briefcase/bootstraps/pyside6.py
+++ b/src/briefcase/bootstraps/pyside6.py
@@ -46,20 +46,19 @@ def main():
 
     def pyproject_table_briefcase_app_extra_content(self):
         return """
-
 requires = [
     "PySide6-Essentials~=6.5",
     # "PySide6-Addons~=6.5",
 ]
 test_requires = [
-{%- if cookiecutter.test_framework == "pytest" %}
+{% if cookiecutter.test_framework == "pytest" %}
     "pytest",
-{%- endif %}
+{% endif %}
 ]
 """
 
     def pyproject_table_macOS(self):
-        return """
+        return """\
 universal_build = true
 requires = [
     "std-nslog~=1.0.0",
@@ -67,13 +66,13 @@ def pyproject_table_macOS(self):
 """
 
     def pyproject_table_linux(self):
-        return """
+        return """\
 requires = [
 ]
 """
 
     def pyproject_table_linux_system_debian(self):
-        return """
+        return """\
 system_requires = [
 ]
 
@@ -102,7 +101,7 @@ def pyproject_table_linux_system_debian(self):
 """
 
     def pyproject_table_linux_system_rhel(self):
-        return """
+        return """\
 system_requires = [
 ]
 
@@ -112,7 +111,7 @@ def pyproject_table_linux_system_rhel(self):
 """
 
     def pyproject_table_linux_system_suse(self):
-        return """
+        return """\
 system_requires = [
 ]
 
@@ -123,7 +122,7 @@ def pyproject_table_linux_system_suse(self):
 """
 
     def pyproject_table_linux_system_arch(self):
-        return """
+        return """\
 system_requires = [
 ]
 
@@ -133,7 +132,7 @@ def pyproject_table_linux_system_arch(self):
 """
 
     def pyproject_table_linux_appimage(self):
-        return """
+        return """\
 manylinux = "manylinux_2_28"
 
 system_requires = [
@@ -145,29 +144,29 @@ def pyproject_table_linux_appimage(self):
 """
 
     def pyproject_table_linux_flatpak(self):
-        return """
+        return """\
 flatpak_runtime = "org.kde.Platform"
 flatpak_runtime_version = "6.6"
 flatpak_sdk = "org.kde.Sdk"
 """
 
     def pyproject_table_windows(self):
-        return """
+        return """\
 requires = [
 ]
 """
 
     def pyproject_table_iOS(self):
-        return """
+        return """\
 supported = false
 """
 
     def pyproject_table_android(self):
-        return """
+        return """\
 supported = false
 """
 
     def pyproject_table_web(self):
-        return """
+        return """\
 supported = false
 """
diff --git a/src/briefcase/bootstraps/toga.py b/src/briefcase/bootstraps/toga.py
index 4305f0ed1..16f87642e 100644
--- a/src/briefcase/bootstraps/toga.py
+++ b/src/briefcase/bootstraps/toga.py
@@ -38,18 +38,17 @@ def app_start_source(self):
 
     def pyproject_table_briefcase_app_extra_content(self):
         return """
-
 requires = [
 ]
 test_requires = [
-{%- if cookiecutter.test_framework == "pytest" %}
+{% if cookiecutter.test_framework == "pytest" %}
     "pytest",
-{%- endif %}
+{% endif %}
 ]
 """
 
     def pyproject_table_macOS(self):
-        return """
+        return """\
 universal_build = true
 requires = [
     "toga-cocoa~=0.4.0",
@@ -58,14 +57,14 @@ def pyproject_table_macOS(self):
 """
 
     def pyproject_table_linux(self):
-        return """
+        return """\
 requires = [
     "toga-gtk~=0.4.0",
 ]
 """
 
     def pyproject_table_linux_system_debian(self):
-        return """
+        return """\
 system_requires = [
     # Needed to compile pycairo wheel
     "libcairo2-dev",
@@ -85,7 +84,7 @@ def pyproject_table_linux_system_debian(self):
 """
 
     def pyproject_table_linux_system_rhel(self):
-        return """
+        return """\
 system_requires = [
     # Needed to compile pycairo wheel
     "cairo-gobject-devel",
@@ -106,7 +105,7 @@ def pyproject_table_linux_system_rhel(self):
 """
 
     def pyproject_table_linux_system_suse(self):
-        return """
+        return """\
 system_requires = [
     # Needed to compile pycairo wheel
     "cairo-devel",
@@ -127,7 +126,7 @@ def pyproject_table_linux_system_suse(self):
 """
 
     def pyproject_table_linux_system_arch(self):
-        return """
+        return """\
 system_requires = [
     # Needed to compile pycairo wheel
     "cairo",
@@ -156,7 +155,7 @@ def pyproject_table_linux_system_arch(self):
 """
 
     def pyproject_table_linux_appimage(self):
-        return """
+        return """\
 manylinux = "manylinux_2_28"
 
 system_requires = [
@@ -179,21 +178,21 @@ def pyproject_table_linux_appimage(self):
 """
 
     def pyproject_table_linux_flatpak(self):
-        return """
+        return """\
 flatpak_runtime = "org.gnome.Platform"
 flatpak_runtime_version = "45"
 flatpak_sdk = "org.gnome.Sdk"
 """
 
     def pyproject_table_windows(self):
-        return """
+        return """\
 requires = [
     "toga-winforms~=0.4.0",
 ]
 """
 
     def pyproject_table_iOS(self):
-        return """
+        return """\
 requires = [
     "toga-iOS~=0.4.0",
     "std-nslog~=1.0.0",
@@ -201,7 +200,7 @@ def pyproject_table_iOS(self):
 """
 
     def pyproject_table_android(self):
-        return """
+        return """\
 requires = [
     "toga-android~=0.4.0",
 ]
@@ -217,7 +216,7 @@ def pyproject_table_android(self):
 """
 
     def pyproject_table_web(self):
-        return """
+        return """\
 requires = [
     "toga-web~=0.4.0",
 ]


Test patch:
diff --git a/tests/commands/new/test_build_context.py b/tests/commands/new/test_build_context.py
index 8911dc32a..050c70cad 100644
--- a/tests/commands/new/test_build_context.py
+++ b/tests/commands/new/test_build_context.py
@@ -92,28 +92,27 @@ def main():
     main().main_loop()
 """,
         pyproject_table_briefcase_app_extra_content="""
-
 requires = [
 ]
 test_requires = [
-{%- if cookiecutter.test_framework == "pytest" %}
+{% if cookiecutter.test_framework == "pytest" %}
     "pytest",
-{%- endif %}
+{% endif %}
 ]
 """,
-        pyproject_table_macOS="""
+        pyproject_table_macOS="""\
 universal_build = true
 requires = [
     "toga-cocoa~=0.4.0",
     "std-nslog~=1.0.0",
 ]
 """,
-        pyproject_table_linux="""
+        pyproject_table_linux="""\
 requires = [
     "toga-gtk~=0.4.0",
 ]
 """,
-        pyproject_table_linux_system_debian="""
+        pyproject_table_linux_system_debian="""\
 system_requires = [
     # Needed to compile pycairo wheel
     "libcairo2-dev",
@@ -131,7 +130,7 @@ def main():
     # "gir1.2-webkit2-4.0",
 ]
 """,
-        pyproject_table_linux_system_rhel="""
+        pyproject_table_linux_system_rhel="""\
 system_requires = [
     # Needed to compile pycairo wheel
     "cairo-gobject-devel",
@@ -150,7 +149,7 @@ def main():
     # "webkit2gtk3",
 ]
 """,
-        pyproject_table_linux_system_suse="""
+        pyproject_table_linux_system_suse="""\
 system_requires = [
     # Needed to compile pycairo wheel
     "cairo-devel",
@@ -169,7 +168,7 @@ def main():
     # "libwebkit2gtk3", "typelib(WebKit2)",
 ]
 """,
-        pyproject_table_linux_system_arch="""
+        pyproject_table_linux_system_arch="""\
 system_requires = [
     # Needed to compile pycairo wheel
     "cairo",
@@ -196,7 +195,7 @@ def main():
     # "webkit2gtk",
 ]
 """,
-        pyproject_table_linux_appimage="""
+        pyproject_table_linux_appimage="""\
 manylinux = "manylinux_2_28"
 
 system_requires = [
@@ -217,23 +216,23 @@ def main():
     "DEPLOY_GTK_VERSION=3 gtk",
 ]
 """,
-        pyproject_table_linux_flatpak="""
+        pyproject_table_linux_flatpak="""\
 flatpak_runtime = "org.gnome.Platform"
 flatpak_runtime_version = "45"
 flatpak_sdk = "org.gnome.Sdk"
 """,
-        pyproject_table_windows="""
+        pyproject_table_windows="""\
 requires = [
     "toga-winforms~=0.4.0",
 ]
 """,
-        pyproject_table_iOS="""
+        pyproject_table_iOS="""\
 requires = [
     "toga-iOS~=0.4.0",
     "std-nslog~=1.0.0",
 ]
 """,
-        pyproject_table_android="""
+        pyproject_table_android="""\
 requires = [
     "toga-android~=0.4.0",
 ]
@@ -247,7 +246,7 @@ def main():
     "androidx.swiperefreshlayout:swiperefreshlayout:1.1.0",
 ]
 """,
-        pyproject_table_web="""
+        pyproject_table_web="""\
 requires = [
     "toga-web~=0.4.0",
 ]
@@ -334,28 +333,27 @@ def main():
     sys.exit(app.exec())
 """,
         pyproject_table_briefcase_app_extra_content="""
-
 requires = [
     "PySide6-Essentials~=6.5",
     # "PySide6-Addons~=6.5",
 ]
 test_requires = [
-{%- if cookiecutter.test_framework == "pytest" %}
+{% if cookiecutter.test_framework == "pytest" %}
     "pytest",
-{%- endif %}
+{% endif %}
 ]
 """,
-        pyproject_table_macOS="""
+        pyproject_table_macOS="""\
 universal_build = true
 requires = [
     "std-nslog~=1.0.0",
 ]
 """,
-        pyproject_table_linux="""
+        pyproject_table_linux="""\
 requires = [
 ]
 """,
-        pyproject_table_linux_system_debian="""
+        pyproject_table_linux_system_debian="""\
 system_requires = [
 ]
 
@@ -382,7 +380,7 @@ def main():
     "libdbus-1-3",
 ]
 """,
-        pyproject_table_linux_system_rhel="""
+        pyproject_table_linux_system_rhel="""\
 system_requires = [
 ]
 
@@ -390,7 +388,7 @@ def main():
     "qt6-qtbase-gui",
 ]
 """,
-        pyproject_table_linux_system_suse="""
+        pyproject_table_linux_system_suse="""\
 system_requires = [
 ]
 
@@ -399,7 +397,7 @@ def main():
     "libQt6Gui6",
 ]
 """,
-        pyproject_table_linux_system_arch="""
+        pyproject_table_linux_system_arch="""\
 system_requires = [
 ]
 
@@ -407,7 +405,7 @@ def main():
     "qt6-base",
 ]
 """,
-        pyproject_table_linux_appimage="""
+        pyproject_table_linux_appimage="""\
 manylinux = "manylinux_2_28"
 
 system_requires = [
@@ -417,22 +415,22 @@ def main():
 linuxdeploy_plugins = [
 ]
 """,
-        pyproject_table_linux_flatpak="""
+        pyproject_table_linux_flatpak="""\
 flatpak_runtime = "org.kde.Platform"
 flatpak_runtime_version = "6.6"
 flatpak_sdk = "org.kde.Sdk"
 """,
-        pyproject_table_windows="""
+        pyproject_table_windows="""\
 requires = [
 ]
 """,
-        pyproject_table_iOS="""
+        pyproject_table_iOS="""\
 supported = false
 """,
-        pyproject_table_android="""
+        pyproject_table_android="""\
 supported = false
 """,
-        pyproject_table_web="""
+        pyproject_table_web="""\
 supported = false
 """,
     )
@@ -519,27 +517,26 @@ def main():
     )
 """,
         pyproject_table_briefcase_app_extra_content="""
-
 requires = [
     "ppb~=3.2.0",
 ]
 test_requires = [
-{%- if cookiecutter.test_framework == "pytest" %}
+{% if cookiecutter.test_framework == "pytest" %}
     "pytest",
-{%- endif %}
+{% endif %}
 ]
 """,
-        pyproject_table_macOS="""
+        pyproject_table_macOS="""\
 universal_build = true
 requires = [
     "std-nslog~=1.0.0",
 ]
 """,
-        pyproject_table_linux="""
+        pyproject_table_linux="""\
 requires = [
 ]
 """,
-        pyproject_table_linux_system_debian="""
+        pyproject_table_linux_system_debian="""\
 system_requires = [
 ]
 
@@ -551,7 +548,7 @@ def main():
     "libsdl2-ttf-2.0-0",
 ]
 """,
-        pyproject_table_linux_system_rhel="""
+        pyproject_table_linux_system_rhel="""\
 system_requires = [
 ]
 
@@ -564,7 +561,7 @@ def main():
     "libmodplug",
 ]
 """,
-        pyproject_table_linux_system_suse="""
+        pyproject_table_linux_system_suse="""\
 system_requires = [
 ]
 
@@ -577,7 +574,7 @@ def main():
     "libmodplug1",
 ]
 """,
-        pyproject_table_linux_system_arch="""
+        pyproject_table_linux_system_arch="""\
 system_requires = [
 ]
 
@@ -589,7 +586,7 @@ def main():
     "sdl2_mixer",
 ]
 """,
-        pyproject_table_linux_appimage="""
+        pyproject_table_linux_appimage="""\
 manylinux = "manylinux_2_28"
 
 system_requires = [
@@ -598,22 +595,22 @@ def main():
 linuxdeploy_plugins = [
 ]
 """,
-        pyproject_table_linux_flatpak="""
+        pyproject_table_linux_flatpak="""\
 flatpak_runtime = "org.freedesktop.Platform"
 flatpak_runtime_version = "23.08"
 flatpak_sdk = "org.freedesktop.Sdk"
 """,
-        pyproject_table_windows="""
+        pyproject_table_windows="""\
 requires = [
 ]
 """,
-        pyproject_table_iOS="""
+        pyproject_table_iOS="""\
 supported = false
 """,
-        pyproject_table_android="""
+        pyproject_table_android="""\
 supported = false
 """,
-        pyproject_table_web="""
+        pyproject_table_web="""\
 supported = false
 """,
     )
@@ -710,55 +707,54 @@ def main():
     pygame.quit()
 """,
         pyproject_table_briefcase_app_extra_content="""
-
 requires = [
     "pygame~=2.2",
 ]
 test_requires = [
-{%- if cookiecutter.test_framework == "pytest" %}
+{% if cookiecutter.test_framework == "pytest" %}
     "pytest",
-{%- endif %}
+{% endif %}
 ]
 """,
-        pyproject_table_macOS="""
+        pyproject_table_macOS="""\
 universal_build = true
 requires = [
     "std-nslog~=1.0.0",
 ]
 """,
-        pyproject_table_linux="""
+        pyproject_table_linux="""\
 requires = [
 ]
 """,
-        pyproject_table_linux_system_debian="""
+        pyproject_table_linux_system_debian="""\
 system_requires = [
 ]
 
 system_runtime_requires = [
 ]
 """,
-        pyproject_table_linux_system_rhel="""
+        pyproject_table_linux_system_rhel="""\
 system_requires = [
 ]
 
 system_runtime_requires = [
 ]
 """,
-        pyproject_table_linux_system_suse="""
+        pyproject_table_linux_system_suse="""\
 system_requires = [
 ]
 
 system_runtime_requires = [
 ]
 """,
-        pyproject_table_linux_system_arch="""
+        pyproject_table_linux_system_arch="""\
 system_requires = [
 ]
 
 system_runtime_requires = [
 ]
 """,
-        pyproject_table_linux_appimage="""
+        pyproject_table_linux_appimage="""\
 manylinux = "manylinux_2_28"
 
 system_requires = [
@@ -767,22 +763,22 @@ def main():
 linuxdeploy_plugins = [
 ]
 """,
-        pyproject_table_linux_flatpak="""
+        pyproject_table_linux_flatpak="""\
 flatpak_runtime = "org.freedesktop.Platform"
 flatpak_runtime_version = "23.08"
 flatpak_sdk = "org.freedesktop.Sdk"
 """,
-        pyproject_table_windows="""
+        pyproject_table_windows="""\
 requires = [
 ]
 """,
-        pyproject_table_iOS="""
+        pyproject_table_iOS="""\
 supported = false
 """,
-        pyproject_table_android="""
+        pyproject_table_android="""\
 supported = false
 """,
-        pyproject_table_web="""
+        pyproject_table_web="""\
 supported = false
 """,
     )
@@ -1083,28 +1079,27 @@ def main():
     main().main_loop()
 """,
         pyproject_table_briefcase_app_extra_content="""
-
 requires = [
 ]
 test_requires = [
-{%- if cookiecutter.test_framework == "pytest" %}
+{% if cookiecutter.test_framework == "pytest" %}
     "pytest",
-{%- endif %}
+{% endif %}
 ]
 """,
-        pyproject_table_macOS="""
+        pyproject_table_macOS="""\
 universal_build = true
 requires = [
     "toga-cocoa~=0.4.0",
     "std-nslog~=1.0.0",
 ]
 """,
-        pyproject_table_linux="""
+        pyproject_table_linux="""\
 requires = [
     "toga-gtk~=0.4.0",
 ]
 """,
-        pyproject_table_linux_system_debian="""
+        pyproject_table_linux_system_debian="""\
 system_requires = [
     # Needed to compile pycairo wheel
     "libcairo2-dev",
@@ -1122,7 +1117,7 @@ def main():
     # "gir1.2-webkit2-4.0",
 ]
 """,
-        pyproject_table_linux_system_rhel="""
+        pyproject_table_linux_system_rhel="""\
 system_requires = [
     # Needed to compile pycairo wheel
     "cairo-gobject-devel",
@@ -1141,7 +1136,7 @@ def main():
     # "webkit2gtk3",
 ]
 """,
-        pyproject_table_linux_system_suse="""
+        pyproject_table_linux_system_suse="""\
 system_requires = [
     # Needed to compile pycairo wheel
     "cairo-devel",
@@ -1160,7 +1155,7 @@ def main():
     # "libwebkit2gtk3", "typelib(WebKit2)",
 ]
 """,
-        pyproject_table_linux_system_arch="""
+        pyproject_table_linux_system_arch="""\
 system_requires = [
     # Needed to compile pycairo wheel
     "cairo",
@@ -1187,7 +1182,7 @@ def main():
     # "webkit2gtk",
 ]
 """,
-        pyproject_table_linux_appimage="""
+        pyproject_table_linux_appimage="""\
 manylinux = "manylinux_2_28"
 
 system_requires = [
@@ -1208,23 +1203,23 @@ def main():
     "DEPLOY_GTK_VERSION=3 gtk",
 ]
 """,
-        pyproject_table_linux_flatpak="""
+        pyproject_table_linux_flatpak="""\
 flatpak_runtime = "org.gnome.Platform"
 flatpak_runtime_version = "45"
 flatpak_sdk = "org.gnome.Sdk"
 """,
-        pyproject_table_windows="""
+        pyproject_table_windows="""\
 requires = [
     "toga-winforms~=0.4.0",
 ]
 """,
-        pyproject_table_iOS="""
+        pyproject_table_iOS="""\
 requires = [
     "toga-iOS~=0.4.0",
     "std-nslog~=1.0.0",
 ]
 """,
-        pyproject_table_android="""
+        pyproject_table_android="""\
 requires = [
     "toga-android~=0.4.0",
 ]
@@ -1238,7 +1233,7 @@ def main():
     "androidx.swiperefreshlayout:swiperefreshlayout:1.1.0",
 ]
 """,
-        pyproject_table_web="""
+        pyproject_table_web="""\
 requires = [
     "toga-web~=0.4.0",
 ]