Merge branch 'master' into django-30

This commit is contained in:
Bruno Alla 2020-03-23 21:33:47 +00:00
commit ac903aafea
12 changed files with 84 additions and 49 deletions

View File

@ -99,6 +99,7 @@ Listed in alphabetical order.
Dani Hodovic `@danihodovic`_ Dani Hodovic `@danihodovic`_
Daniel Hepper `@dhepper`_ @danielhepper Daniel Hepper `@dhepper`_ @danielhepper
Daniel Hillier `@danifus`_ Daniel Hillier `@danifus`_
Daniel Sears `@highpost`_ @highpost
Daniele Tricoli `@eriol`_ Daniele Tricoli `@eriol`_
David Díaz `@ddiazpinto`_ @DavidDiazPinto David Díaz `@ddiazpinto`_ @DavidDiazPinto
Davit Tovmasyan `@davitovmasyan`_ Davit Tovmasyan `@davitovmasyan`_
@ -140,6 +141,7 @@ Listed in alphabetical order.
Jerome Leclanche `@jleclanche`_ @Adys Jerome Leclanche `@jleclanche`_ @Adys
Jimmy Gitonga `@afrowave`_ @afrowave Jimmy Gitonga `@afrowave`_ @afrowave
John Cass `@jcass77`_ @cass_john John Cass `@jcass77`_ @cass_john
Jules Cheron `@jules-ch`_
Julien Almarcha `@sladinji`_ Julien Almarcha `@sladinji`_
Julio Castillo `@juliocc`_ Julio Castillo `@juliocc`_
Kaido Kert `@kaidokert`_ Kaido Kert `@kaidokert`_
@ -300,6 +302,7 @@ Listed in alphabetical order.
.. _@hairychris: https://github.com/hairychris .. _@hairychris: https://github.com/hairychris
.. _@hanaquadara: https://github.com/hanaquadara .. _@hanaquadara: https://github.com/hanaquadara
.. _@hendrikschneider: https://github.com/hendrikschneider .. _@hendrikschneider: https://github.com/hendrikschneider
.. _@highpost: https://github.com/highpost
.. _@hjwp: https://github.com/hjwp .. _@hjwp: https://github.com/hjwp
.. _@howiezhao: https://github.com/howiezhao .. _@howiezhao: https://github.com/howiezhao
.. _@IanLee1521: https://github.com/IanLee1521 .. _@IanLee1521: https://github.com/IanLee1521
@ -313,6 +316,7 @@ Listed in alphabetical order.
.. _@jcass77: https://github.com/jcass77 .. _@jcass77: https://github.com/jcass77
.. _@jeromecaisip: https://github.com/jeromecaisip .. _@jeromecaisip: https://github.com/jeromecaisip
.. _@jleclanche: https://github.com/jleclanche .. _@jleclanche: https://github.com/jleclanche
.. _@jules-ch: https://github.com/jules-ch
.. _@juliocc: https://github.com/juliocc .. _@juliocc: https://github.com/juliocc
.. _@jvanbrug: https://github.com/jvanbrug .. _@jvanbrug: https://github.com/jvanbrug
.. _@ka7eh: https://github.com/ka7eh .. _@ka7eh: https://github.com/ka7eh

View File

@ -73,15 +73,15 @@ cloud_provider:
mail_service: mail_service:
Select an email service that Django-Anymail provides Select an email service that Django-Anymail provides
1. Amazon SES_ 1. Mailgun_
2. Mailgun_ 2. `Amazon SES`_
3. Mailjet_ 3. Mailjet_
4. Mandrill_ 4. Mandrill_
5. Postmark_ 5. Postmark_
6. SendGrid_ 6. SendGrid_
7. SendinBlue_ 7. SendinBlue_
8. SparkPost_ 8. SparkPost_
9. Plain/Vanilla Django-Anymail_ 9. `Other SMTP`_
use_drf: use_drf:
Indicates whether the project should be configured to use `Django Rest Framework`_. Indicates whether the project should be configured to use `Django Rest Framework`_.
@ -114,8 +114,8 @@ ci_tool:
Select a CI tool for running tests. The choices are: Select a CI tool for running tests. The choices are:
1. None 1. None
2. Travis_ 2. `Travis CI`_
3. Gitlab_ 3. `Gitlab CI`_
keep_local_envs_in_vcs: keep_local_envs_in_vcs:
Indicates whether the project's ``.envs/.local/`` should be kept in VCS Indicates whether the project's ``.envs/.local/`` should be kept in VCS
@ -145,7 +145,7 @@ debug:
.. _AWS: https://aws.amazon.com/s3/ .. _AWS: https://aws.amazon.com/s3/
.. _GCP: https://cloud.google.com/storage/ .. _GCP: https://cloud.google.com/storage/
.. _SES: https://aws.amazon.com/ses/ .. _Amazon SES: https://aws.amazon.com/ses/
.. _Mailgun: https://www.mailgun.com .. _Mailgun: https://www.mailgun.com
.. _Mailjet: https://www.mailjet.com .. _Mailjet: https://www.mailjet.com
.. _Mandrill: http://mandrill.com .. _Mandrill: http://mandrill.com
@ -153,7 +153,7 @@ debug:
.. _SendGrid: https://sendgrid.com .. _SendGrid: https://sendgrid.com
.. _SendinBlue: https://www.sendinblue.com .. _SendinBlue: https://www.sendinblue.com
.. _SparkPost: https://www.sparkpost.com .. _SparkPost: https://www.sparkpost.com
.. _Django-Anymail: https://anymail.readthedocs.io/en/stable/ .. _Other SMTP: https://anymail.readthedocs.io/en/stable/
.. _Django Rest Framework: https://github.com/encode/django-rest-framework/ .. _Django Rest Framework: https://github.com/encode/django-rest-framework/

View File

@ -68,3 +68,15 @@ if (
"You should either use Whitenoise or select a Cloud Provider to serve static files" "You should either use Whitenoise or select a Cloud Provider to serve static files"
) )
sys.exit(1) sys.exit(1)
if (
"{{ cookiecutter.cloud_provider }}" == "GCP"
and "{{ cookiecutter.mail_service }}" == "Amazon SES"
) or (
"{{ cookiecutter.cloud_provider }}" == "None"
and "{{ cookiecutter.mail_service }}" == "Amazon SES"
):
print(
"You should either use AWS or select a different Mail Service for sending emails."
)
sys.exit(1)

View File

@ -14,4 +14,4 @@ tox==3.14.5
pytest==5.4.1 pytest==5.4.1
pytest-cookies==0.5.1 pytest-cookies==0.5.1
pytest-instafail==0.4.1.post0 pytest-instafail==0.4.1.post0
pyyaml==5.3 pyyaml==5.3.1

View File

@ -46,17 +46,33 @@ SUPPORTED_COMBINATIONS = [
{"cloud_provider": "AWS", "use_whitenoise": "n"}, {"cloud_provider": "AWS", "use_whitenoise": "n"},
{"cloud_provider": "GCP", "use_whitenoise": "y"}, {"cloud_provider": "GCP", "use_whitenoise": "y"},
{"cloud_provider": "GCP", "use_whitenoise": "n"}, {"cloud_provider": "GCP", "use_whitenoise": "n"},
{"cloud_provider": "None", "use_whitenoise": "y"}, {"cloud_provider": "None", "use_whitenoise": "y", "mail_service": "Mailgun"},
{"cloud_provider": "None", "use_whitenoise": "y", "mail_service": "Mailjet"},
{"cloud_provider": "None", "use_whitenoise": "y", "mail_service": "Mandrill"},
{"cloud_provider": "None", "use_whitenoise": "y", "mail_service": "Postmark"},
{"cloud_provider": "None", "use_whitenoise": "y", "mail_service": "Sendgrid"},
{"cloud_provider": "None", "use_whitenoise": "y", "mail_service": "SendinBlue"},
{"cloud_provider": "None", "use_whitenoise": "y", "mail_service": "SparkPost"},
{"cloud_provider": "None", "use_whitenoise": "y", "mail_service": "Other SMTP"},
# Note: cloud_provider=None AND use_whitenoise=n is not supported # Note: cloud_provider=None AND use_whitenoise=n is not supported
{"mail_service": "Mailgun"}, {"cloud_provider": "AWS", "mail_service": "Mailgun"},
{"mail_service": "Amazon SES"}, {"cloud_provider": "AWS", "mail_service": "Amazon SES"},
{"mail_service": "Mailjet"}, {"cloud_provider": "AWS", "mail_service": "Mailjet"},
{"mail_service": "Mandrill"}, {"cloud_provider": "AWS", "mail_service": "Mandrill"},
{"mail_service": "Postmark"}, {"cloud_provider": "AWS", "mail_service": "Postmark"},
{"mail_service": "Sendgrid"}, {"cloud_provider": "AWS", "mail_service": "Sendgrid"},
{"mail_service": "SendinBlue"}, {"cloud_provider": "AWS", "mail_service": "SendinBlue"},
{"mail_service": "SparkPost"}, {"cloud_provider": "AWS", "mail_service": "SparkPost"},
{"mail_service": "Other SMTP"}, {"cloud_provider": "AWS", "mail_service": "Other SMTP"},
{"cloud_provider": "GCP", "mail_service": "Mailgun"},
{"cloud_provider": "GCP", "mail_service": "Mailjet"},
{"cloud_provider": "GCP", "mail_service": "Mandrill"},
{"cloud_provider": "GCP", "mail_service": "Postmark"},
{"cloud_provider": "GCP", "mail_service": "Sendgrid"},
{"cloud_provider": "GCP", "mail_service": "SendinBlue"},
{"cloud_provider": "GCP", "mail_service": "SparkPost"},
{"cloud_provider": "GCP", "mail_service": "Other SMTP"},
# Note: cloud_providers GCP and None with mail_service Amazon SES is not supported
{"use_drf": "y"}, {"use_drf": "y"},
{"use_drf": "n"}, {"use_drf": "n"},
{"js_task_runner": "None"}, {"js_task_runner": "None"},
@ -86,6 +102,8 @@ SUPPORTED_COMBINATIONS = [
UNSUPPORTED_COMBINATIONS = [ UNSUPPORTED_COMBINATIONS = [
{"cloud_provider": "None", "use_whitenoise": "n"}, {"cloud_provider": "None", "use_whitenoise": "n"},
{"cloud_provider": "GCP", "mail_service": "Amazon SES"},
{"cloud_provider": "None", "mail_service": "Amazon SES"},
] ]
@ -163,7 +181,7 @@ def test_travis_invokes_pytest(cookies, context):
with open(f"{result.project}/.travis.yml", "r") as travis_yml: with open(f"{result.project}/.travis.yml", "r") as travis_yml:
try: try:
assert yaml.load(travis_yml)["script"] == ["pytest"] assert yaml.load(travis_yml, Loader=yaml.FullLoader)["script"] == ["pytest"]
except yaml.YAMLError as e: except yaml.YAMLError as e:
pytest.fail(e) pytest.fail(e)
@ -179,7 +197,7 @@ def test_gitlab_invokes_flake8_and_pytest(cookies, context):
with open(f"{result.project}/.gitlab-ci.yml", "r") as gitlab_yml: with open(f"{result.project}/.gitlab-ci.yml", "r") as gitlab_yml:
try: try:
gitlab_config = yaml.load(gitlab_yml) gitlab_config = yaml.load(gitlab_yml, Loader=yaml.FullLoader)
assert gitlab_config["flake8"]["script"] == ["flake8"] assert gitlab_config["flake8"]["script"] == ["flake8"]
assert gitlab_config["pytest"]["script"] == ["pytest"] assert gitlab_config["pytest"]["script"] == ["pytest"]
except yaml.YAMLError as e: except yaml.YAMLError as e:

View File

@ -7,7 +7,7 @@ repos:
rev: master rev: master
hooks: hooks:
- id: trailing-whitespace - id: trailing-whitespace
files: (^|/)a/.+\.(py|html|sh|css|js)$ files: (^|/).+\.(py|html|sh|css|js)$
- repo: local - repo: local
hooks: hooks:

View File

@ -1,20 +1,19 @@
""" """
Base settings to build other settings files upon. Base settings to build other settings files upon.
""" """
from pathlib import Path
import environ import environ
ROOT_DIR = ( ROOT_DIR = Path(__file__).parents[2]
environ.Path(__file__) - 3 # {{ cookiecutter.project_slug }}/)
) # ({{ cookiecutter.project_slug }}/config/settings/base.py - 3 = {{ cookiecutter.project_slug }}/) APPS_DIR = ROOT_DIR / "{{ cookiecutter.project_slug }}"
APPS_DIR = ROOT_DIR.path("{{ cookiecutter.project_slug }}")
env = environ.Env() env = environ.Env()
READ_DOT_ENV_FILE = env.bool("DJANGO_READ_DOT_ENV_FILE", default=False) READ_DOT_ENV_FILE = env.bool("DJANGO_READ_DOT_ENV_FILE", default=False)
if READ_DOT_ENV_FILE: if READ_DOT_ENV_FILE:
# OS environment variables take precedence over variables from .env # OS environment variables take precedence over variables from .env
env.read_env(str(ROOT_DIR.path(".env"))) env.read_env(str(ROOT_DIR / ".env"))
# GENERAL # GENERAL
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
@ -36,7 +35,7 @@ USE_L10N = True
# https://docs.djangoproject.com/en/dev/ref/settings/#use-tz # https://docs.djangoproject.com/en/dev/ref/settings/#use-tz
USE_TZ = True USE_TZ = True
# https://docs.djangoproject.com/en/dev/ref/settings/#locale-paths # https://docs.djangoproject.com/en/dev/ref/settings/#locale-paths
LOCALE_PATHS = [ROOT_DIR.path("locale")] LOCALE_PATHS = [str(ROOT_DIR / "locale")]
# DATABASES # DATABASES
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
@ -151,11 +150,11 @@ MIDDLEWARE = [
# STATIC # STATIC
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
# https://docs.djangoproject.com/en/dev/ref/settings/#static-root # https://docs.djangoproject.com/en/dev/ref/settings/#static-root
STATIC_ROOT = str(ROOT_DIR("staticfiles")) STATIC_ROOT = str(ROOT_DIR / "staticfiles")
# https://docs.djangoproject.com/en/dev/ref/settings/#static-url # https://docs.djangoproject.com/en/dev/ref/settings/#static-url
STATIC_URL = "/static/" STATIC_URL = "/static/"
# https://docs.djangoproject.com/en/dev/ref/contrib/staticfiles/#std:setting-STATICFILES_DIRS # https://docs.djangoproject.com/en/dev/ref/contrib/staticfiles/#std:setting-STATICFILES_DIRS
STATICFILES_DIRS = [str(APPS_DIR.path("static"))] STATICFILES_DIRS = [str(APPS_DIR / "static")]
# https://docs.djangoproject.com/en/dev/ref/contrib/staticfiles/#staticfiles-finders # https://docs.djangoproject.com/en/dev/ref/contrib/staticfiles/#staticfiles-finders
STATICFILES_FINDERS = [ STATICFILES_FINDERS = [
"django.contrib.staticfiles.finders.FileSystemFinder", "django.contrib.staticfiles.finders.FileSystemFinder",
@ -165,7 +164,7 @@ STATICFILES_FINDERS = [
# MEDIA # MEDIA
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
# https://docs.djangoproject.com/en/dev/ref/settings/#media-root # https://docs.djangoproject.com/en/dev/ref/settings/#media-root
MEDIA_ROOT = str(APPS_DIR("media")) MEDIA_ROOT = str(APPS_DIR / "media")
# https://docs.djangoproject.com/en/dev/ref/settings/#media-url # https://docs.djangoproject.com/en/dev/ref/settings/#media-url
MEDIA_URL = "/media/" MEDIA_URL = "/media/"
@ -177,7 +176,7 @@ TEMPLATES = [
# https://docs.djangoproject.com/en/dev/ref/settings/#std:setting-TEMPLATES-BACKEND # https://docs.djangoproject.com/en/dev/ref/settings/#std:setting-TEMPLATES-BACKEND
"BACKEND": "django.template.backends.django.DjangoTemplates", "BACKEND": "django.template.backends.django.DjangoTemplates",
# https://docs.djangoproject.com/en/dev/ref/settings/#template-dirs # https://docs.djangoproject.com/en/dev/ref/settings/#template-dirs
"DIRS": [str(APPS_DIR.path("templates"))], "DIRS": [str(APPS_DIR / "templates")],
"OPTIONS": { "OPTIONS": {
# https://docs.djangoproject.com/en/dev/ref/settings/#template-loaders # https://docs.djangoproject.com/en/dev/ref/settings/#template-loaders
# https://docs.djangoproject.com/en/dev/ref/templates/api/#loader-types # https://docs.djangoproject.com/en/dev/ref/templates/api/#loader-types
@ -210,7 +209,7 @@ CRISPY_TEMPLATE_PACK = "bootstrap4"
# FIXTURES # FIXTURES
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
# https://docs.djangoproject.com/en/dev/ref/settings/#fixture-dirs # https://docs.djangoproject.com/en/dev/ref/settings/#fixture-dirs
FIXTURE_DIRS = (str(APPS_DIR.path("fixtures")),) FIXTURE_DIRS = (str(APPS_DIR / "fixtures"),)
# SECURITY # SECURITY
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------

View File

@ -15,15 +15,14 @@ framework.
""" """
import os import os
import sys import sys
from pathlib import Path
from django.core.wsgi import get_wsgi_application from django.core.wsgi import get_wsgi_application
# This allows easy placement of apps within the interior # This allows easy placement of apps within the interior
# {{ cookiecutter.project_slug }} directory. # {{ cookiecutter.project_slug }} directory.
app_path = os.path.abspath( app_path = Path(__file__).parents[1].resolve()
os.path.join(os.path.dirname(os.path.abspath(__file__)), os.pardir) sys.path.append(str(app_path / "{{ cookiecutter.project_slug }}"))
)
sys.path.append(os.path.join(app_path, "{{ cookiecutter.project_slug }}"))
# We defer to a DJANGO_SETTINGS_MODULE already in the environment. This breaks # We defer to a DJANGO_SETTINGS_MODULE already in the environment. This breaks
# if running multiple sites in the same mod_wsgi process. To fix this, use # if running multiple sites in the same mod_wsgi process. To fix this, use
# mod_wsgi daemon mode with each site in its own daemon process, or use # mod_wsgi daemon mode with each site in its own daemon process, or use

View File

@ -1,6 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
import os import os
import sys import sys
from pathlib import Path
if __name__ == "__main__": if __name__ == "__main__":
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "config.settings.local") os.environ.setdefault("DJANGO_SETTINGS_MODULE", "config.settings.local")
@ -24,7 +25,7 @@ if __name__ == "__main__":
# This allows easy placement of apps within the interior # This allows easy placement of apps within the interior
# {{ cookiecutter.project_slug }} directory. # {{ cookiecutter.project_slug }} directory.
current_path = os.path.dirname(os.path.abspath(__file__)) current_path = Path(__file__).parent.resolve()
sys.path.append(os.path.join(current_path, "{{ cookiecutter.project_slug }}")) sys.path.append(str(current_path / "{{ cookiecutter.project_slug }}"))
execute_from_command_line(sys.argv) execute_from_command_line(sys.argv)

View File

@ -1,15 +1,16 @@
import os import os
from pathlib import Path
from typing import Sequence from typing import Sequence
import pytest import pytest
ROOT_DIR_PATH = os.path.dirname(os.path.realpath(__file__)) ROOT_DIR_PATH = Path(__file__).parent.resolve()
PRODUCTION_DOTENVS_DIR_PATH = os.path.join(ROOT_DIR_PATH, ".envs", ".production") PRODUCTION_DOTENVS_DIR_PATH = ROOT_DIR_PATH / ".envs" / ".production"
PRODUCTION_DOTENV_FILE_PATHS = [ PRODUCTION_DOTENV_FILE_PATHS = [
os.path.join(PRODUCTION_DOTENVS_DIR_PATH, ".django"), PRODUCTION_DOTENVS_DIR_PATH / ".django",
os.path.join(PRODUCTION_DOTENVS_DIR_PATH, ".postgres"), PRODUCTION_DOTENVS_DIR_PATH / ".postgres",
] ]
DOTENV_FILE_PATH = os.path.join(ROOT_DIR_PATH, ".env") DOTENV_FILE_PATH = ROOT_DIR_PATH / ".env"
def merge( def merge(
@ -31,9 +32,9 @@ def main():
@pytest.mark.parametrize("merged_file_count", range(3)) @pytest.mark.parametrize("merged_file_count", range(3))
@pytest.mark.parametrize("append_linesep", [True, False]) @pytest.mark.parametrize("append_linesep", [True, False])
def test_merge(tmpdir_factory, merged_file_count: int, append_linesep: bool): def test_merge(tmpdir_factory, merged_file_count: int, append_linesep: bool):
tmp_dir_path = str(tmpdir_factory.getbasetemp()) tmp_dir_path = Path(str(tmpdir_factory.getbasetemp()))
output_file_path = os.path.join(tmp_dir_path, ".env") output_file_path = tmp_dir_path / ".env"
expected_output_file_content = "" expected_output_file_content = ""
merged_file_paths = [] merged_file_paths = []
@ -41,7 +42,7 @@ def test_merge(tmpdir_factory, merged_file_count: int, append_linesep: bool):
merged_file_ord = i + 1 merged_file_ord = i + 1
merged_filename = ".service{}".format(merged_file_ord) merged_filename = ".service{}".format(merged_file_ord)
merged_file_path = os.path.join(tmp_dir_path, merged_filename) merged_file_path = tmp_dir_path / merged_filename
merged_file_content = merged_filename * merged_file_ord merged_file_content = merged_filename * merged_file_ord

View File

@ -8,7 +8,7 @@ psycopg2==2.8.4 --no-binary psycopg2 # https://github.com/psycopg/psycopg2
Collectfast==2.1.0 # https://github.com/antonagestam/collectfast Collectfast==2.1.0 # https://github.com/antonagestam/collectfast
{%- endif %} {%- endif %}
{%- if cookiecutter.use_sentry == "y" %} {%- if cookiecutter.use_sentry == "y" %}
sentry-sdk==0.14.2 # https://github.com/getsentry/sentry-python sentry-sdk==0.14.3 # https://github.com/getsentry/sentry-python
{%- endif %} {%- endif %}
# Django # Django

View File

@ -4,8 +4,9 @@ from celery.result import EagerResult
from {{ cookiecutter.project_slug }}.users.tasks import get_users_count from {{ cookiecutter.project_slug }}.users.tasks import get_users_count
from {{ cookiecutter.project_slug }}.users.tests.factories import UserFactory from {{ cookiecutter.project_slug }}.users.tests.factories import UserFactory
pytestmark = pytest.mark.django_db
@pytest.mark.django_db
def test_user_count(settings): def test_user_count(settings):
"""A basic test to execute the get_users_count Celery task.""" """A basic test to execute the get_users_count Celery task."""
UserFactory.create_batch(3) UserFactory.create_batch(3)