1
0
Fork 0
mirror of https://github.com/YunoHost-Apps/django-fmd_ynh.git synced 2024-09-03 18:26:27 +02:00

update project setup

inspired from: https://github.com/YunoHost-Apps/django_example_ynh
This commit is contained in:
JensDiemer 2022-08-15 16:56:45 +02:00
parent 98c8b39881
commit 882a811389
19 changed files with 340 additions and 271 deletions

View file

@ -17,4 +17,4 @@ accesslog = '__LOG_FILE__'
errorlog = '__LOG_FILE__' errorlog = '__LOG_FILE__'
# https://docs.gunicorn.org/en/latest/settings.html#pidfile # https://docs.gunicorn.org/en/latest/settings.html#pidfile
pidfile = '__FINAL_HOME_PATH__/gunicorn.pid' pidfile = '__FINALPATH__/gunicorn.pid'

View file

@ -1,4 +1,4 @@
#!__FINAL_HOME_PATH__/venv/bin/python #!__FINALPATH__/venv/bin/python
import os import os
import sys import sys

View file

@ -1,17 +1,11 @@
location __PATH__/static/ { location __PATH__/static/ {
# Django static files # Service static files by nginx
# e.g.: /var/www/$app/static
alias __PUBLIC_PATH__/static/; alias __PUBLIC_PATH__/static/;
expires 30d; expires 30d;
} }
# TODO: django-sendfile2:
#location __PATH__/media/ {
# # DATA_DIR/media/
# alias __PUBLIC_PATH__/media/;
# expires 30d;
#}
location __PATH__/ { location __PATH__/ {
# https://github.com/benoitc/gunicorn/blob/master/examples/nginx.conf # https://github.com/benoitc/gunicorn/blob/master/examples/nginx.conf

View file

@ -10,9 +10,9 @@ bleach==5.0.1; python_version >= "3.7" and python_full_version < "4.0.0" \
bx-django-utils==26; python_version >= "3.7" and python_full_version < "4.0.0" \ bx-django-utils==26; python_version >= "3.7" and python_full_version < "4.0.0" \
--hash=sha256:c04776c4c6b275ddcadae79fd1578e6ae9ba92d8cf752a9ee4f2b70a22f4236e \ --hash=sha256:c04776c4c6b275ddcadae79fd1578e6ae9ba92d8cf752a9ee4f2b70a22f4236e \
--hash=sha256:19349d0a8fa165d87b4fd544efb61418f7d6c41cfabaa46d0153bb6d844262a1 --hash=sha256:19349d0a8fa165d87b4fd544efb61418f7d6c41cfabaa46d0153bb6d844262a1
bx-py-utils==67; python_version >= "3.7" and python_full_version < "4.0.0" \ bx-py-utils==68; python_version >= "3.7" and python_full_version < "4.0.0" \
--hash=sha256:4810dcab69146ffd5c31d45710c47fa9ac63f074b26326bc2f17eb7eb7f5e09e \ --hash=sha256:00c3fbc9b5f48626a0a58141aaa90104349bac9723941c64f528f8742b0961db \
--hash=sha256:981877273d1c480f8d6f1de78b1a034c97b5e420df75e66799b320ff9133a047 --hash=sha256:fe5808c379db7165a51cbf5e4d947ef783d78bdfb5c47665e85e9cfe0b520ff9
certifi==2022.6.15; python_version >= "3.7" and python_version < "4" and python_full_version < "4.0.0" \ certifi==2022.6.15; python_version >= "3.7" and python_version < "4" and python_full_version < "4.0.0" \
--hash=sha256:fe86415d55e84719d75f8b69414f6438ac3547d2078ab91b67e779ef69378412 \ --hash=sha256:fe86415d55e84719d75f8b69414f6438ac3547d2078ab91b67e779ef69378412 \
--hash=sha256:84c85a9078b11105f04f3036a9482ae10e4621616db313fe045dd24743a0820d --hash=sha256:84c85a9078b11105f04f3036a9482ae10e4621616db313fe045dd24743a0820d
@ -46,9 +46,9 @@ django-redis==5.2.0; python_version >= "3.7" and python_full_version < "4.0.0" \
django-tools==0.51.0; python_version >= "3.7" and python_full_version < "4.0.0" \ django-tools==0.51.0; python_version >= "3.7" and python_full_version < "4.0.0" \
--hash=sha256:ebe69065ae5504e66667125858a7edd1cf6627e2b96cb03aeaab9e0ee3b8b98b \ --hash=sha256:ebe69065ae5504e66667125858a7edd1cf6627e2b96cb03aeaab9e0ee3b8b98b \
--hash=sha256:4fe3768d4d863e7f3fa8bd7a3f014c4320ab320776218641fe760202c08f2d5a --hash=sha256:4fe3768d4d863e7f3fa8bd7a3f014c4320ab320776218641fe760202c08f2d5a
django-yunohost-integration==0.2.4; python_version >= "3.7" and python_full_version < "4.0.0" \ django-yunohost-integration==0.3.0; python_version >= "3.7" and python_full_version < "4.0.0" \
--hash=sha256:f5cdb5480025e90de0221d2b1c6282f517fd0c903702563cccb771cb3e1d9417 \ --hash=sha256:f7f8e9d55c50231bb32d3809b240d6ac718aadac1a1f471284baa1bfa6e98dff \
--hash=sha256:a4b3617a3b39225d6162fa88827e9fe8b65388e26a0bbc23ea665c62aa8cb044 --hash=sha256:d0e9cc91d241075613cb54b5da0879ad9b8ad3d22b84130cd7a331025650406e
django==3.2.15; python_version >= "3.7" and python_full_version < "4.0.0" \ django==3.2.15; python_version >= "3.7" and python_full_version < "4.0.0" \
--hash=sha256:115baf5049d5cf4163e43492cdc7139c306ed6d451e7d3571fe9612903903713 \ --hash=sha256:115baf5049d5cf4163e43492cdc7139c306ed6d451e7d3571fe9612903903713 \
--hash=sha256:f71934b1a822f14a86c9ac9634053689279cd04ae69cb6ade4a59471b886582b --hash=sha256:f71934b1a822f14a86c9ac9634053689279cd04ae69cb6ade4a59471b886582b
@ -118,9 +118,9 @@ pyparsing==3.0.9; python_version >= "3.7" and python_full_version < "4.0.0" and
python-stdnum==1.17; python_version >= "3.7" and python_full_version < "4.0.0" \ python-stdnum==1.17; python_version >= "3.7" and python_full_version < "4.0.0" \
--hash=sha256:374e2b5e13912ccdbf50b0b23fca2c3e0531174805c32d74e145f37756328340 \ --hash=sha256:374e2b5e13912ccdbf50b0b23fca2c3e0531174805c32d74e145f37756328340 \
--hash=sha256:a46e6cf9652807314d369b654b255c86a59f93d18be2834f3d567ed1a346c547 --hash=sha256:a46e6cf9652807314d369b654b255c86a59f93d18be2834f3d567ed1a346c547
pytz==2022.1; python_version >= "3.7" and python_full_version < "4.0.0" \ pytz==2022.2.1; python_version >= "3.7" and python_full_version < "4.0.0" \
--hash=sha256:e68985985296d9a66a881eb3193b0906246245294a881e7c8afe623866ac6a5c \ --hash=sha256:220f481bdafa09c3955dfbdddb7b57780e9a94f5127e35456a48589b9e0c0197 \
--hash=sha256:1e760e2fe6a8163bc0b3d9a19c4f84342afa0a2affebfaa84b01b978a02ecaa7 --hash=sha256:cea221417204f2d1a2aa03ddae3e867921971d0d76f14d87abb4414415bbdcf5
redis==4.3.4; python_version >= "3.7" and python_full_version < "4.0.0" \ redis==4.3.4; python_version >= "3.7" and python_full_version < "4.0.0" \
--hash=sha256:a52d5694c9eb4292770084fa8c863f79367ca19884b329ab574d5cb2036b3e54 \ --hash=sha256:a52d5694c9eb4292770084fa8c863f79367ca19884b329ab574d5cb2036b3e54 \
--hash=sha256:ddf27071df4adf3821c4f2ca59d67525c3a82e5f268bed97b813cb4fabf87880 --hash=sha256:ddf27071df4adf3821c4f2ca59d67525c3a82e5f268bed97b813cb4fabf87880

View file

@ -2,7 +2,7 @@
################################################################################ ################################################################################
# Please do not modify this file, it will be reset at the next update. # Please do not modify this file, it will be reset at the next update.
# You can edit the file __FINAL_HOME_PATH__/local_settings.py and add/modify the settings you need. # You can edit the file __FINALPATH__/local_settings.py and add/modify the settings you need.
# The parameters you add in local_settings.py will overwrite these, # The parameters you add in local_settings.py will overwrite these,
# but you can use the options and documentation in this file to find out what can be done. # but you can use the options and documentation in this file to find out what can be done.
@ -11,45 +11,78 @@
from pathlib import Path as __Path from pathlib import Path as __Path
from django.core.validators import EmailValidator as __EmailValidator
from django_yunohost_integration.base_settings import * # noqa from django_yunohost_integration.base_settings import * # noqa
from django_yunohost_integration.secret_key import get_or_create_secret as __get_or_create_secret from django_yunohost_integration.secret_key import get_or_create_secret as __get_or_create_secret
from findmydevice_project.settings.base import * # noqa from findmydevice_project.settings.base import * # noqa
# ----------------------------------------------------------------------------- FINALPATH = __Path('__FINALPATH__') # /opt/yunohost/$app
assert FINALPATH.is_dir(), f'Directory not exists: {FINALPATH}'
FINAL_HOME_PATH = __Path('__FINAL_HOME_PATH__') # /opt/yunohost/$app PUBLIC_PATH = __Path('__PUBLIC_PATH__') # /var/www/$app
assert FINAL_HOME_PATH.is_dir(), f'Directory not exists: {FINAL_HOME_PATH}' assert PUBLIC_PATH.is_dir(), f'Directory not exists: {PUBLIC_PATH}'
FINAL_WWW_PATH = __Path('__FINAL_WWW_PATH__') # /var/www/$app LOG_FILE = __Path('__LOG_FILE__') # /var/log/$app/django_example_ynh.log
assert FINAL_WWW_PATH.is_dir(), f'Directory not exists: {FINAL_WWW_PATH}'
LOG_FILE = __Path('__LOG_FILE__') # /var/log/$app/django-fmd.log
assert LOG_FILE.is_file(), f'File not exists: {LOG_FILE}' assert LOG_FILE.is_file(), f'File not exists: {LOG_FILE}'
PATH_URL = '__PATH_URL__' # $YNH_APP_ARG_PATH PATH_URL = '__PATH_URL__' # $YNH_APP_ARG_PATH
PATH_URL = PATH_URL.strip('/') PATH_URL = PATH_URL.strip('/')
# ----------------------------------------------------------------------------- ROOT_URLCONF = 'urls' # /opt/yunohost/django-fmd/urls.py
ROOT_URLCONF = 'urls' # /opt/yunohost/django-fmd/ynh_urls.py # -----------------------------------------------------------------------------
# config_panel.toml settings:
DEBUG_ENABLED = '__DEBUG_ENABLED__'
LOG_LEVEL = '__LOG_LEVEL__'
ADMIN_EMAIL = '__ADMIN_EMAIL__'
DEFAULT_FROM_EMAIL = '__DEFAULT_FROM_EMAIL__'
# -----------------------------------------------------------------------------
# Use/convert/validate config_panel.toml settings:
DEBUG = bool(int(DEBUG_ENABLED))
assert LOG_LEVEL in (
'DEBUG',
'INFO',
'WARNING',
'ERROR',
'CRITICAL',
), f'Invalid LOG_LEVEL: {LOG_LEVEL!r}'
__EmailValidator(
message='ADMIN_EMAIL %(value)r from config panel is not valid!',
)(ADMIN_EMAIL)
__EmailValidator(
message='DEFAULT_FROM_EMAIL %(value)r from config panel is not valid!',
)(DEFAULT_FROM_EMAIL)
# -----------------------------------------------------------------------------
# Function that will be called to finalize a user profile: # Function that will be called to finalize a user profile:
YNH_SETUP_USER = 'setup_user.setup_project_user' YNH_SETUP_USER = 'setup_user.setup_project_user'
SECRET_KEY = __get_or_create_secret(FINAL_HOME_PATH / 'secret.txt') # /opt/yunohost/$app/secret.txt SECRET_KEY = __get_or_create_secret(FINALPATH / 'secret.txt') # /opt/yunohost/$app/secret.txt
INSTALLED_APPS.append('django_yunohost_integration') INSTALLED_APPS += [
'axes', # https://github.com/jazzband/django-axes
'django_yunohost_integration',
]
MIDDLEWARE.insert( MIDDLEWARE.insert(
MIDDLEWARE.index('django.contrib.auth.middleware.AuthenticationMiddleware') + 1, MIDDLEWARE.index('django.contrib.auth.middleware.AuthenticationMiddleware') + 1,
# login a user via HTTP_REMOTE_USER header from SSOwat: # login a user via HTTP_REMOTE_USER header from SSOwat:
'django_yunohost_integration.sso_auth.auth_middleware.SSOwatRemoteUserMiddleware', 'django_yunohost_integration.sso_auth.auth_middleware.SSOwatRemoteUserMiddleware',
) )
# AxesMiddleware should be the last middleware:
MIDDLEWARE.append('axes.middleware.AxesMiddleware')
# Keep ModelBackend around for per-user permissions and superuser # Keep ModelBackend around for per-user permissions and superuser
AUTHENTICATION_BACKENDS = ( AUTHENTICATION_BACKENDS = (
'axes.backends.AxesBackend', # AxesBackend should be the first backend!
#
# Authenticate via SSO and nginx 'HTTP_REMOTE_USER' header: # Authenticate via SSO and nginx 'HTTP_REMOTE_USER' header:
'django_yunohost_integration.sso_auth.auth_backend.SSOwatUserBackend', 'django_yunohost_integration.sso_auth.auth_backend.SSOwatUserBackend',
# #
@ -62,10 +95,11 @@ LOGIN_URL = '/yunohost/sso/'
LOGOUT_REDIRECT_URL = '/yunohost/sso/' LOGOUT_REDIRECT_URL = '/yunohost/sso/'
# /yunohost/sso/?action=logout # /yunohost/sso/?action=logout
# ----------------------------------------------------------------------------- # -----------------------------------------------------------------------------
ADMINS = (('__ADMIN__', '__ADMINMAIL__'),) ADMINS = (('__ADMIN__', ADMIN_EMAIL),)
MANAGERS = ADMINS MANAGERS = ADMINS
@ -94,10 +128,6 @@ EMAIL_SUBJECT_PREFIX = f'[{SITE_TITLE}] '
# E-mail address that error messages come from. # E-mail address that error messages come from.
SERVER_EMAIL = 'noreply@__DOMAIN__' SERVER_EMAIL = 'noreply@__DOMAIN__'
# Default email address to use for various automated correspondence from
# the site managers. Used for registration emails.
DEFAULT_FROM_EMAIL = '__ADMINMAIL__'
# List of URLs your site is supposed to serve # List of URLs your site is supposed to serve
ALLOWED_HOSTS = ['__DOMAIN__'] ALLOWED_HOSTS = ['__DOMAIN__']
@ -128,8 +158,9 @@ else:
STATIC_URL = '/static/' STATIC_URL = '/static/'
MEDIA_URL = '/media/' MEDIA_URL = '/media/'
STATIC_ROOT = str(FINAL_WWW_PATH / 'static') STATIC_ROOT = str(PUBLIC_PATH / 'static')
MEDIA_ROOT = str(FINAL_WWW_PATH / 'media') MEDIA_ROOT = str(PUBLIC_PATH / 'media')
# ----------------------------------------------------------------------------- # -----------------------------------------------------------------------------
@ -157,12 +188,24 @@ LOGGING = {
}, },
}, },
'loggers': { 'loggers': {
'': {'handlers': ['log_file', 'mail_admins'], 'level': 'INFO', 'propagate': False}, '': {'handlers': ['log_file', 'mail_admins'], 'level': LOG_LEVEL, 'propagate': False},
'django': {'handlers': ['log_file', 'mail_admins'], 'level': 'INFO', 'propagate': False}, 'django': {'handlers': ['log_file', 'mail_admins'], 'level': LOG_LEVEL, 'propagate': False},
'axes': {'handlers': ['log_file', 'mail_admins'], 'level': 'WARNING', 'propagate': False}, 'axes': {'handlers': ['log_file', 'mail_admins'], 'level': LOG_LEVEL, 'propagate': False},
'django_tools': {'handlers': ['log_file', 'mail_admins'], 'level': 'INFO', 'propagate': False}, 'django_tools': {
'django_yunohost_integration': {'handlers': ['log_file', 'mail_admins'], 'level': 'INFO', 'propagate': False}, 'handlers': ['log_file', 'mail_admins'],
'findmydevice': {'handlers': ['log_file', 'mail_admins'], 'level': 'INFO', 'propagate': False}, 'level': LOG_LEVEL,
'propagate': False,
},
'django_yunohost_integration': {
'handlers': ['log_file', 'mail_admins'],
'level': LOG_LEVEL,
'propagate': False,
},
'findmydevice': {
'handlers': ['log_file', 'mail_admins'],
'level': LOG_LEVEL,
'propagate': False,
},
}, },
} }

17
conf/systemd.service Normal file
View file

@ -0,0 +1,17 @@
[Unit]
Description=__APP__ server
After=redis.service postgresql.service
[Service]
User=__APP__
Group=__APP__
WorkingDirectory=__FINALPATH__/
ExecStart=__FINALPATH__/venv/bin/gunicorn --config __FINALPATH__/gunicorn.conf.py wsgi
StandardOutput=syslog
StandardError=syslog
SyslogIdentifier=__APP__-server
[Install]
WantedBy=multi-user.target

View file

@ -1,27 +1,19 @@
from django.conf import settings from django.conf import settings
from django.conf.urls import static
from django.urls import include, path from django.urls import include, path
from django.views.static import serve from django.views.static import serve
import findmydevice import findmydevice
# from django_yunohost_integration.views import request_media_debug_view
if settings.PATH_URL: if settings.PATH_URL:
# settings.PATH_URL is the $YNH_APP_ARG_PATH # settings.PATH_URL is the $YNH_APP_ARG_PATH
# Prefix all urls with "PATH_URL": # Prefix all urls with "PATH_URL":
urlpatterns = [ urlpatterns = [
# path(f'{settings.PATH_URL}/debug/', request_media_debug_view),
path(f'{settings.PATH_URL}/', include('findmydevice_project.urls')), path(f'{settings.PATH_URL}/', include('findmydevice_project.urls')),
# #
# TODO: Serve from nginx server ;) # TODO: Serve from nginx server ;)
path(f'{settings.PATH_URL}/<path:path>', serve, {'document_root': findmydevice.WEB_PATH}) path(f'{settings.PATH_URL}/<path:path>', serve, {'document_root': findmydevice.WEB_PATH})
] ]
if settings.SERVE_FILES:
urlpatterns += static.static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
else: else:
# Installed to domain root, without a path prefix # Installed to domain root, without a path prefix
# Just use the default project urls.py # Just use the default project urls.py

View file

@ -22,6 +22,12 @@ def main():
django_settings_path=BASE_PATH / 'conf' / 'settings.py', django_settings_path=BASE_PATH / 'conf' / 'settings.py',
destination=BASE_PATH / 'local_test', destination=BASE_PATH / 'local_test',
runserver=True, runserver=True,
extra_replacements={
'__DEBUG_ENABLED__': '1',
'__LOG_LEVEL__': 'DEBUG',
'__ADMIN_EMAIL__': 'foo-bar@test.tld',
'__DEFAULT_FROM_EMAIL__': 'django_app@test.tld',
},
) )

94
poetry.lock generated
View file

@ -10,7 +10,7 @@ python-versions = ">=3.7"
typing-extensions = {version = "*", markers = "python_version < \"3.8\""} typing-extensions = {version = "*", markers = "python_version < \"3.8\""}
[package.extras] [package.extras]
tests = ["pytest", "pytest-asyncio", "mypy (>=0.800)"] tests = ["mypy (>=0.800)", "pytest-asyncio", "pytest"]
[[package]] [[package]]
name = "astor" name = "astor"
@ -48,10 +48,10 @@ optional = false
python-versions = ">=3.5" python-versions = ">=3.5"
[package.extras] [package.extras]
dev = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "mypy (>=0.900,!=0.940)", "pytest-mypy-plugins", "zope.interface", "furo", "sphinx", "sphinx-notfound-page", "pre-commit", "cloudpickle"] tests_no_zope = ["cloudpickle", "pytest-mypy-plugins", "mypy (>=0.900,!=0.940)", "pytest (>=4.3.0)", "pympler", "hypothesis", "coverage[toml] (>=5.0.2)"]
docs = ["furo", "sphinx", "zope.interface", "sphinx-notfound-page"] tests = ["cloudpickle", "zope.interface", "pytest-mypy-plugins", "mypy (>=0.900,!=0.940)", "pytest (>=4.3.0)", "pympler", "hypothesis", "coverage[toml] (>=5.0.2)"]
tests = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "mypy (>=0.900,!=0.940)", "pytest-mypy-plugins", "zope.interface", "cloudpickle"] docs = ["sphinx-notfound-page", "zope.interface", "sphinx", "furo"]
tests_no_zope = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "mypy (>=0.900,!=0.940)", "pytest-mypy-plugins", "cloudpickle"] dev = ["cloudpickle", "pre-commit", "sphinx-notfound-page", "sphinx", "furo", "zope.interface", "pytest-mypy-plugins", "mypy (>=0.900,!=0.940)", "pytest (>=4.3.0)", "pympler", "hypothesis", "coverage[toml] (>=5.0.2)"]
[[package]] [[package]]
name = "beautifulsoup4" name = "beautifulsoup4"
@ -65,8 +65,8 @@ python-versions = ">=3.6.0"
soupsieve = ">1.2" soupsieve = ">1.2"
[package.extras] [package.extras]
html5lib = ["html5lib"]
lxml = ["lxml"] lxml = ["lxml"]
html5lib = ["html5lib"]
[[package]] [[package]]
name = "black" name = "black"
@ -86,10 +86,10 @@ typed-ast = {version = ">=1.4.2", markers = "python_version < \"3.8\" and implem
typing-extensions = {version = ">=3.10.0.0", markers = "python_version < \"3.10\""} typing-extensions = {version = ">=3.10.0.0", markers = "python_version < \"3.10\""}
[package.extras] [package.extras]
colorama = ["colorama (>=0.4.3)"]
d = ["aiohttp (>=3.7.4)"]
jupyter = ["ipython (>=7.8.0)", "tokenize-rt (>=3.2.0)"]
uvloop = ["uvloop (>=0.15.2)"] uvloop = ["uvloop (>=0.15.2)"]
jupyter = ["tokenize-rt (>=3.2.0)", "ipython (>=7.8.0)"]
d = ["aiohttp (>=3.7.4)"]
colorama = ["colorama (>=0.4.3)"]
[[package]] [[package]]
name = "bleach" name = "bleach"
@ -104,8 +104,8 @@ six = ">=1.9.0"
webencodings = "*" webencodings = "*"
[package.extras] [package.extras]
dev = ["mypy (==0.961)", "black (==22.3.0)", "wheel (==0.37.1)", "twine (==4.0.1)", "tox (==3.25.0)", "Sphinx (==4.3.2)", "pytest (==7.1.2)", "pip-tools (==6.6.2)", "hashin (==0.17.0)", "flake8 (==4.0.1)", "build (==0.8.0)"]
css = ["tinycss2 (>=1.1.0,<1.2)"] css = ["tinycss2 (>=1.1.0,<1.2)"]
dev = ["build (==0.8.0)", "flake8 (==4.0.1)", "hashin (==0.17.0)", "pip-tools (==6.6.2)", "pytest (==7.1.2)", "Sphinx (==4.3.2)", "tox (==3.25.0)", "twine (==4.0.1)", "wheel (==0.37.1)", "black (==22.3.0)", "mypy (==0.961)"]
[[package]] [[package]]
name = "bx-django-utils" name = "bx-django-utils"
@ -122,7 +122,7 @@ python-stdnum = "*"
[[package]] [[package]]
name = "bx-py-utils" name = "bx-py-utils"
version = "67" version = "68"
description = "Various Python utility functions" description = "Various Python utility functions"
category = "main" category = "main"
optional = false optional = false
@ -179,7 +179,7 @@ python-versions = ">=3.6"
colorama = {version = "*", markers = "sys_platform == \"win32\""} colorama = {version = "*", markers = "sys_platform == \"win32\""}
[package.extras] [package.extras]
development = ["black", "flake8", "mypy", "pytest", "types-colorama"] development = ["types-colorama", "pytest", "mypy", "flake8", "black"]
[[package]] [[package]]
name = "coverage" name = "coverage"
@ -242,7 +242,7 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
wrapt = ">=1.10,<2" wrapt = ">=1.10,<2"
[package.extras] [package.extras]
dev = ["tox", "bump2version (<1)", "sphinx (<2)", "importlib-metadata (<3)", "importlib-resources (<4)", "configparser (<5)", "sphinxcontrib-websupport (<2)", "zipp (<2)", "PyTest (<5)", "PyTest-Cov (<2.6)", "pytest", "pytest-cov"] dev = ["pytest-cov", "pytest", "PyTest-Cov (<2.6)", "PyTest (<5)", "zipp (<2)", "sphinxcontrib-websupport (<2)", "configparser (<5)", "importlib-resources (<4)", "importlib-metadata (<3)", "sphinx (<2)", "bump2version (<1)", "tox"]
[[package]] [[package]]
name = "distlib" name = "distlib"
@ -266,8 +266,8 @@ pytz = "*"
sqlparse = ">=0.2.2" sqlparse = ">=0.2.2"
[package.extras] [package.extras]
argon2 = ["argon2-cffi (>=19.1.0)"]
bcrypt = ["bcrypt"] bcrypt = ["bcrypt"]
argon2 = ["argon2-cffi (>=19.1.0)"]
[[package]] [[package]]
name = "django-axes" name = "django-axes"
@ -351,7 +351,7 @@ pprintpp = "*"
[[package]] [[package]]
name = "django-yunohost-integration" name = "django-yunohost-integration"
version = "0.2.4" version = "0.3.0"
description = "Glue code to package django projects as yunohost apps." description = "Glue code to package django projects as yunohost apps."
category = "main" category = "main"
optional = false optional = false
@ -384,8 +384,8 @@ optional = false
python-versions = ">=3.7" python-versions = ">=3.7"
[package.extras] [package.extras]
docs = ["furo (>=2022.6.21)", "sphinx (>=5.1.1)", "sphinx-autodoc-typehints (>=1.19.1)"] testing = ["pytest-timeout (>=2.1)", "pytest-cov (>=3)", "pytest (>=7.1.2)", "coverage (>=6.4.2)", "covdefaults (>=2.2)"]
testing = ["covdefaults (>=2.2)", "coverage (>=6.4.2)", "pytest (>=7.1.2)", "pytest-cov (>=3)", "pytest-timeout (>=2.1)"] docs = ["sphinx-autodoc-typehints (>=1.19.1)", "sphinx (>=5.1.1)", "furo (>=2022.6.21)"]
[[package]] [[package]]
name = "flake8" name = "flake8"
@ -456,8 +456,8 @@ typing-extensions = {version = ">=3.6.4", markers = "python_version < \"3.8\""}
zipp = ">=0.5" zipp = ">=0.5"
[package.extras] [package.extras]
docs = ["sphinx", "jaraco.packaging (>=8.2)", "rst.linker (>=1.9)"] testing = ["importlib-resources (>=1.3)", "pytest-mypy", "pytest-black (>=0.3.7)", "flufl.flake8", "pyfakefs", "pep517", "packaging", "pytest-enabler (>=1.0.1)", "pytest-cov", "pytest-flake8", "pytest-checkdocs (>=2.4)", "pytest (>=4.6)"]
testing = ["pytest (>=4.6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytest-cov", "pytest-enabler (>=1.0.1)", "packaging", "pep517", "pyfakefs", "flufl.flake8", "pytest-black (>=0.3.7)", "pytest-mypy", "importlib-resources (>=1.3)"] docs = ["rst.linker (>=1.9)", "jaraco.packaging (>=8.2)", "sphinx"]
[[package]] [[package]]
name = "iniconfig" name = "iniconfig"
@ -476,10 +476,10 @@ optional = false
python-versions = ">=3.6.1,<4.0" python-versions = ">=3.6.1,<4.0"
[package.extras] [package.extras]
pipfile_deprecated_finder = ["pipreqs", "requirementslib"]
requirements_deprecated_finder = ["pipreqs", "pip-api"]
colors = ["colorama (>=0.4.3,<0.5.0)"]
plugins = ["setuptools"] plugins = ["setuptools"]
colors = ["colorama (>=0.4.3,<0.5.0)"]
requirements_deprecated_finder = ["pip-api", "pipreqs"]
pipfile_deprecated_finder = ["requirementslib", "pipreqs"]
[[package]] [[package]]
name = "mccabe" name = "mccabe"
@ -525,8 +525,8 @@ optional = false
python-versions = ">=3.7" python-versions = ">=3.7"
[package.extras] [package.extras]
docs = ["furo (>=2021.7.5b38)", "proselint (>=0.10.2)", "sphinx-autodoc-typehints (>=1.12)", "sphinx (>=4)"] test = ["pytest (>=6)", "pytest-mock (>=3.6)", "pytest-cov (>=2.7)", "appdirs (==1.4.4)"]
test = ["appdirs (==1.4.4)", "pytest-cov (>=2.7)", "pytest-mock (>=3.6)", "pytest (>=6)"] docs = ["sphinx (>=4)", "sphinx-autodoc-typehints (>=1.12)", "proselint (>=0.10.2)", "furo (>=2021.7.5b38)"]
[[package]] [[package]]
name = "pluggy" name = "pluggy"
@ -600,7 +600,7 @@ optional = false
python-versions = ">=3.6.8" python-versions = ">=3.6.8"
[package.extras] [package.extras]
diagrams = ["railroad-diagrams", "jinja2"] diagrams = ["jinja2", "railroad-diagrams"]
[[package]] [[package]]
name = "pytest" name = "pytest"
@ -622,7 +622,7 @@ py = ">=1.8.2"
tomli = ">=1.0.0" tomli = ">=1.0.0"
[package.extras] [package.extras]
testing = ["argcomplete", "hypothesis (>=3.56)", "mock", "nose", "pygments (>=2.7.2)", "requests", "xmlschema"] testing = ["xmlschema", "requests", "pygments (>=2.7.2)", "nose", "mock", "hypothesis (>=3.56)", "argcomplete"]
[[package]] [[package]]
name = "pytest-cov" name = "pytest-cov"
@ -666,8 +666,8 @@ python-versions = ">=3.5"
pytest = ">=5.4.0" pytest = ">=5.4.0"
[package.extras] [package.extras]
docs = ["sphinx", "sphinx-rtd-theme"] testing = ["django-configurations (>=2.0)", "django"]
testing = ["django", "django-configurations (>=2.0)"] docs = ["sphinx-rtd-theme", "sphinx"]
[[package]] [[package]]
name = "python-stdnum" name = "python-stdnum"
@ -678,13 +678,13 @@ optional = false
python-versions = "*" python-versions = "*"
[package.extras] [package.extras]
soap = ["zeep"]
soap-alt = ["suds"]
soap-fallback = ["pysimplesoap"] soap-fallback = ["pysimplesoap"]
soap-alt = ["suds"]
soap = ["zeep"]
[[package]] [[package]]
name = "pytz" name = "pytz"
version = "2022.1" version = "2022.2.1"
description = "World timezone definitions, modern and historical" description = "World timezone definitions, modern and historical"
category = "main" category = "main"
optional = false optional = false
@ -717,8 +717,8 @@ packaging = ">=20.4"
typing-extensions = {version = "*", markers = "python_version < \"3.8\""} typing-extensions = {version = "*", markers = "python_version < \"3.8\""}
[package.extras] [package.extras]
ocsp = ["requests (>=2.26.0)", "pyopenssl (==20.0.1)", "cryptography (>=36.0.1)"]
hiredis = ["hiredis (>=1.0.0)"] hiredis = ["hiredis (>=1.0.0)"]
ocsp = ["cryptography (>=36.0.1)", "pyopenssl (==20.0.1)", "requests (>=2.26.0)"]
[[package]] [[package]]
name = "requests" name = "requests"
@ -735,8 +735,8 @@ idna = ">=2.5,<4"
urllib3 = ">=1.21.1,<1.27" urllib3 = ">=1.21.1,<1.27"
[package.extras] [package.extras]
socks = ["PySocks (>=1.5.6,!=1.5.7)"]
use_chardet_on_py3 = ["chardet (>=3.0.2,<6)"] use_chardet_on_py3 = ["chardet (>=3.0.2,<6)"]
socks = ["PySocks (>=1.5.6,!=1.5.7)"]
[[package]] [[package]]
name = "six" name = "six"
@ -806,8 +806,8 @@ toml = ">=0.9.4"
virtualenv = ">=16.0.0,<20.0.0 || >20.0.0,<20.0.1 || >20.0.1,<20.0.2 || >20.0.2,<20.0.3 || >20.0.3,<20.0.4 || >20.0.4,<20.0.5 || >20.0.5,<20.0.6 || >20.0.6,<20.0.7 || >20.0.7" virtualenv = ">=16.0.0,<20.0.0 || >20.0.0,<20.0.1 || >20.0.1,<20.0.2 || >20.0.2,<20.0.3 || >20.0.3,<20.0.4 || >20.0.4,<20.0.5 || >20.0.5,<20.0.6 || >20.0.6,<20.0.7 || >20.0.7"
[package.extras] [package.extras]
docs = ["pygments-github-lexers (>=0.0.5)", "sphinx (>=2.0.0)", "sphinxcontrib-autoprogram (>=0.1.5)", "towncrier (>=18.5.0)"] testing = ["pathlib2 (>=2.3.3)", "psutil (>=5.6.1)", "pytest-randomly (>=1.0.0)", "pytest-mock (>=1.10.0)", "pytest-cov (>=2.5.1)", "pytest (>=4.0.0)", "freezegun (>=0.3.11)", "flaky (>=3.4.0)"]
testing = ["flaky (>=3.4.0)", "freezegun (>=0.3.11)", "pytest (>=4.0.0)", "pytest-cov (>=2.5.1)", "pytest-mock (>=1.10.0)", "pytest-randomly (>=1.0.0)", "psutil (>=5.6.1)", "pathlib2 (>=2.3.3)"] docs = ["towncrier (>=18.5.0)", "sphinxcontrib-autoprogram (>=0.1.5)", "sphinx (>=2.0.0)", "pygments-github-lexers (>=0.0.5)"]
[[package]] [[package]]
name = "typed-ast" name = "typed-ast"
@ -834,9 +834,9 @@ optional = false
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*, <4" python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*, <4"
[package.extras] [package.extras]
brotli = ["brotlicffi (>=0.8.0)", "brotli (>=1.0.9)", "brotlipy (>=0.6.0)"]
secure = ["pyOpenSSL (>=0.14)", "cryptography (>=1.3.4)", "idna (>=2.0.0)", "certifi", "ipaddress"]
socks = ["PySocks (>=1.5.6,!=1.5.7,<2.0)"] socks = ["PySocks (>=1.5.6,!=1.5.7,<2.0)"]
secure = ["ipaddress", "certifi", "idna (>=2.0.0)", "cryptography (>=1.3.4)", "pyOpenSSL (>=0.14)"]
brotli = ["brotlipy (>=0.6.0)", "brotli (>=1.0.9)", "brotlicffi (>=0.8.0)"]
[[package]] [[package]]
name = "virtualenv" name = "virtualenv"
@ -853,8 +853,8 @@ importlib-metadata = {version = ">=0.12", markers = "python_version < \"3.8\""}
platformdirs = ">=2,<3" platformdirs = ">=2,<3"
[package.extras] [package.extras]
docs = ["proselint (>=0.10.2)", "sphinx (>=3)", "sphinx-argparse (>=0.2.5)", "sphinx-rtd-theme (>=0.4.3)", "towncrier (>=21.3)"] testing = ["pytest-timeout (>=1)", "pytest-randomly (>=1)", "pytest-mock (>=2)", "pytest-freezegun (>=0.4.1)", "pytest-env (>=0.6.2)", "pytest (>=4)", "packaging (>=20.0)", "flaky (>=3)", "coverage-enable-subprocess (>=1)", "coverage (>=4)"]
testing = ["coverage (>=4)", "coverage-enable-subprocess (>=1)", "flaky (>=3)", "packaging (>=20.0)", "pytest (>=4)", "pytest-env (>=0.6.2)", "pytest-freezegun (>=0.4.1)", "pytest-mock (>=2)", "pytest-randomly (>=1)", "pytest-timeout (>=1)"] docs = ["towncrier (>=21.3)", "sphinx-rtd-theme (>=0.4.3)", "sphinx-argparse (>=0.2.5)", "sphinx (>=3)", "proselint (>=0.10.2)"]
[[package]] [[package]]
name = "webencodings" name = "webencodings"
@ -881,8 +881,8 @@ optional = false
python-versions = ">=3.7" python-versions = ">=3.7"
[package.extras] [package.extras]
docs = ["sphinx", "jaraco.packaging (>=9)", "rst.linker (>=1.9)", "jaraco.tidelift (>=1.4)"] testing = ["pytest-mypy (>=0.9.1)", "pytest-black (>=0.3.7)", "func-timeout", "jaraco.itertools", "pytest-enabler (>=1.3)", "pytest-cov", "pytest-flake8", "pytest-checkdocs (>=2.4)", "pytest (>=6)"]
testing = ["pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytest-cov", "pytest-enabler (>=1.3)", "jaraco.itertools", "func-timeout", "pytest-black (>=0.3.7)", "pytest-mypy (>=0.9.1)"] docs = ["jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "jaraco.packaging (>=9)", "sphinx"]
[metadata] [metadata]
lock-version = "1.1" lock-version = "1.1"
@ -947,8 +947,8 @@ bx-django-utils = [
{file = "bx_django_utils-26.tar.gz", hash = "sha256:19349d0a8fa165d87b4fd544efb61418f7d6c41cfabaa46d0153bb6d844262a1"}, {file = "bx_django_utils-26.tar.gz", hash = "sha256:19349d0a8fa165d87b4fd544efb61418f7d6c41cfabaa46d0153bb6d844262a1"},
] ]
bx-py-utils = [ bx-py-utils = [
{file = "bx_py_utils-67-py3-none-any.whl", hash = "sha256:4810dcab69146ffd5c31d45710c47fa9ac63f074b26326bc2f17eb7eb7f5e09e"}, {file = "bx_py_utils-68-py3-none-any.whl", hash = "sha256:00c3fbc9b5f48626a0a58141aaa90104349bac9723941c64f528f8742b0961db"},
{file = "bx_py_utils-67.tar.gz", hash = "sha256:981877273d1c480f8d6f1de78b1a034c97b5e420df75e66799b320ff9133a047"}, {file = "bx_py_utils-68.tar.gz", hash = "sha256:fe5808c379db7165a51cbf5e4d947ef783d78bdfb5c47665e85e9cfe0b520ff9"},
] ]
certifi = [ certifi = [
{file = "certifi-2022.6.15-py3-none-any.whl", hash = "sha256:fe86415d55e84719d75f8b69414f6438ac3547d2078ab91b67e779ef69378412"}, {file = "certifi-2022.6.15-py3-none-any.whl", hash = "sha256:fe86415d55e84719d75f8b69414f6438ac3547d2078ab91b67e779ef69378412"},
@ -1058,8 +1058,8 @@ django-tools = [
{file = "django_tools-0.51.0-py3-none-any.whl", hash = "sha256:4fe3768d4d863e7f3fa8bd7a3f014c4320ab320776218641fe760202c08f2d5a"}, {file = "django_tools-0.51.0-py3-none-any.whl", hash = "sha256:4fe3768d4d863e7f3fa8bd7a3f014c4320ab320776218641fe760202c08f2d5a"},
] ]
django-yunohost-integration = [ django-yunohost-integration = [
{file = "django_yunohost_integration-0.2.4-py3-none-any.whl", hash = "sha256:f5cdb5480025e90de0221d2b1c6282f517fd0c903702563cccb771cb3e1d9417"}, {file = "django_yunohost_integration-0.3.0-py3-none-any.whl", hash = "sha256:f7f8e9d55c50231bb32d3809b240d6ac718aadac1a1f471284baa1bfa6e98dff"},
{file = "django_yunohost_integration-0.2.4.tar.gz", hash = "sha256:a4b3617a3b39225d6162fa88827e9fe8b65388e26a0bbc23ea665c62aa8cb044"}, {file = "django_yunohost_integration-0.3.0.tar.gz", hash = "sha256:d0e9cc91d241075613cb54b5da0879ad9b8ad3d22b84130cd7a331025650406e"},
] ]
docopt = [ docopt = [
{file = "docopt-0.6.2.tar.gz", hash = "sha256:49b3a825280bd66b3aa83585ef59c4a8c82f2c8a522dbe754a8bc8d08c85c491"}, {file = "docopt-0.6.2.tar.gz", hash = "sha256:49b3a825280bd66b3aa83585ef59c4a8c82f2c8a522dbe754a8bc8d08c85c491"},
@ -1209,8 +1209,8 @@ python-stdnum = [
{file = "python_stdnum-1.17-py2.py3-none-any.whl", hash = "sha256:a46e6cf9652807314d369b654b255c86a59f93d18be2834f3d567ed1a346c547"}, {file = "python_stdnum-1.17-py2.py3-none-any.whl", hash = "sha256:a46e6cf9652807314d369b654b255c86a59f93d18be2834f3d567ed1a346c547"},
] ]
pytz = [ pytz = [
{file = "pytz-2022.1-py2.py3-none-any.whl", hash = "sha256:e68985985296d9a66a881eb3193b0906246245294a881e7c8afe623866ac6a5c"}, {file = "pytz-2022.2.1-py2.py3-none-any.whl", hash = "sha256:220f481bdafa09c3955dfbdddb7b57780e9a94f5127e35456a48589b9e0c0197"},
{file = "pytz-2022.1.tar.gz", hash = "sha256:1e760e2fe6a8163bc0b3d9a19c4f84342afa0a2affebfaa84b01b978a02ecaa7"}, {file = "pytz-2022.2.1.tar.gz", hash = "sha256:cea221417204f2d1a2aa03ddae3e867921971d0d76f14d87abb4414415bbdcf5"},
] ]
pyupgrade = [ pyupgrade = [
{file = "pyupgrade-2.37.3-py2.py3-none-any.whl", hash = "sha256:9746efd064dbf53d7f86d6f88a1d48120f58dbfc378f517768634740ea2225e2"}, {file = "pyupgrade-2.37.3-py2.py3-none-any.whl", hash = "sha256:9746efd064dbf53d7f86d6f88a1d48120f58dbfc378f517768634740ea2225e2"},

View file

@ -68,7 +68,7 @@ lines_after_imports=2
[tool.pytest.ini_options] [tool.pytest.ini_options]
# https://docs.pytest.org/en/latest/customize.html#pyproject-toml # https://docs.pytest.org/en/latest/customize.html#pyproject-toml
minversion = "6.0" minversion = "6.0"
norecursedirs = ".* .git __pycache__ conf coverage* dist htmlcov" norecursedirs = ".* .git __pycache__ conf local_test coverage* dist htmlcov"
# sometimes helpfull "addopts" arguments: # sometimes helpfull "addopts" arguments:
# -vv # -vv
# --verbose # --verbose
@ -103,7 +103,7 @@ skip_missing_interpreters = True
[testenv] [testenv]
passenv = * passenv = *
whitelist_externals = make whitelist_externals = pytest
commands = commands =
pytest findmydevice findmydevice_project pytest findmydevice findmydevice_project
""" """

View file

@ -1,25 +0,0 @@
"""
Run pytest against local test creation
"""
from pathlib import Path
try:
from django_yunohost_integration.pytest_helper import run_pytest
except ImportError as err:
raise ImportError('Did you forget to activate a virtual environment?') from err
BASE_PATH = Path(__file__).parent
def main():
run_pytest(
django_settings_path=BASE_PATH / 'conf' / 'settings.py',
destination=BASE_PATH / 'local_test',
)
if __name__ == '__main__':
main()

View file

@ -13,6 +13,22 @@ app=$YNH_APP_INSTANCE_NAME
# Currently not used: django-fmd has no public pages, yet! # Currently not used: django-fmd has no public pages, yet!
is_public=$YNH_APP_ARG_IS_PUBLIC is_public=$YNH_APP_ARG_IS_PUBLIC
#=================================================
# ARGUMENTS FROM CONFIG PANEL
#=================================================
# 'debug_enabled' -> '__DEBUG_ENABLED__' -> settings.DEBUG
debug_enabled="0"
# 'log_level' -> '__LOG_LEVEL__' -> settings.LOG_LEVEL
log_level="WARNING"
# 'admin_email' -> '__ADMIN_EMAIL__' add in settings.ADMINS
admin_email="${admin}@${domain}"
# 'default_from_email' -> '__DEFAULT_FROM_EMAIL__' -> settings.DEFAULT_FROM_EMAIL
default_from_email="${app}@${domain}"
#================================================= #=================================================
# SET CONSTANTS # SET CONSTANTS
#================================================= #=================================================
@ -20,10 +36,7 @@ is_public=$YNH_APP_ARG_IS_PUBLIC
public_path=/var/www/$app public_path=/var/www/$app
final_path=/opt/yunohost/$app final_path=/opt/yunohost/$app
log_path=/var/log/$app log_path=/var/log/$app
log_file="${log_path}/django-fmd.log" log_file="${log_path}/${app}.log"
# Default: settings.DEBUG=False
django_debug="False"
#================================================= #=================================================
# COMMON VARIABLES # COMMON VARIABLES

View file

@ -30,10 +30,21 @@ final_path=$(ynh_app_setting_get --app="$app" --key=final_path)
log_path=$(ynh_app_setting_get --app="$app" --key=log_path) log_path=$(ynh_app_setting_get --app="$app" --key=log_path)
port=$(ynh_app_setting_get --app="$app" --key=port) port=$(ynh_app_setting_get --app="$app" --key=port)
db_pwd=$(ynh_app_setting_get --app="$app" --key=psqlpwd) db_pwd=$(ynh_app_setting_get --app="$app" --key=psqlpwd)
admin_mail=$(ynh_user_get_info "$admin" mail) db_name=$(ynh_sanitize_dbid --db_name="$app")
db_user=$db_name
redis_db=$(ynh_app_setting_get --app="$app" --key=redis_db) redis_db=$(ynh_app_setting_get --app="$app" --key=redis_db)
#-------------------------------------------------
# config_panel.toml settings:
debug_enabled=$(ynh_app_setting_get --app="$app" --key=debug_enabled)
log_level=$(ynh_app_setting_get --app="$app" --key=log_level)
admin_email=$(ynh_app_setting_get --app="$app" --key=admin_email)
default_from_email=$(ynh_app_setting_get --app="$app" --key=default_from_email)
#================================================= #=================================================
# BACKUP BEFORE UPGRADE THEN ACTIVE TRAP # BACKUP BEFORE UPGRADE THEN ACTIVE TRAP
#================================================= #=================================================
@ -114,27 +125,7 @@ fi
#================================================= #=================================================
ynh_script_progression --message="Modify django-fmd's config file..." ynh_script_progression --message="Modify django-fmd's config file..."
# save old settings file ynh_add_config --template="settings.py" --destination="$final_path/settings.py"
settings="$final_path/settings.py"
ynh_backup_if_checksum_is_different --file="$settings"
cp "../conf/settings.py" "$settings"
ynh_replace_string --match_string="__APP__" --replace_string="$app" --target_file="$settings"
ynh_replace_string --match_string="__DB_PWD__" --replace_string="$db_pwd" --target_file="$settings"
ynh_replace_string --match_string="__ADMIN__" --replace_string="$admin" --target_file="$settings"
ynh_replace_string --match_string="__ADMINMAIL__" --replace_string="$admin_mail" --target_file="$settings"
ynh_replace_string --match_string="__FINAL_HOME_PATH__" --replace_string="$final_path" --target_file="$settings"
ynh_replace_string --match_string="__FINAL_WWW_PATH__" --replace_string="$public_path" --target_file="$settings"
ynh_replace_string --match_string="__LOG_FILE__" --replace_string="$log_file" --target_file="$settings"
ynh_replace_string --match_string="__REDIS_DB__" --replace_string="$redis_db" --target_file="$settings"
# Difference to install/upgrade scripts: Use $new_domain and $new_path here:
ynh_replace_string --match_string="__DOMAIN__" --replace_string="$new_domain" --target_file="$settings"
ynh_replace_string --match_string="__PATH_URL__" --replace_string="$new_path" --target_file="$settings"
# Recalculate and store the config file checksum into the app settings
ynh_store_file_checksum --file="$settings"
#================================================= #=================================================
# GENERIC FINALISATION # GENERIC FINALISATION

View file

@ -50,15 +50,22 @@ ynh_app_setting_set --app="$app" --key=path --value="$path_url"
# Find a free port # Find a free port
port=$(ynh_find_port --port=8000) port=$(ynh_find_port --port=8000)
# Set port as application setting # Set port as application setting
# https://github.com/YunoHost/yunohost/blob/dev/data/helpers.d/setting # https://yunohost.org/en/contribute/packaging_apps/helpers
# https://github.com/YunoHost/yunohost/blob/dev/helpers/setting
ynh_app_setting_set --app="$app" --key=port --value="$port" ynh_app_setting_set --app="$app" --key=port --value="$port"
db_pwd=$(ynh_app_setting_get --app="$app" --key=psqlpwd) db_pwd=$(ynh_app_setting_get --app="$app" --key=psqlpwd)
admin_mail=$(ynh_user_get_info --username="$admin" --key=mail)
redis_db=$(ynh_redis_get_free_db)
# Always deactivate settings.DEBUG: redis_db=$(ynh_redis_get_free_db)
ynh_app_setting_set --app=$app --key=django_debug --value="False" ynh_app_setting_set --app="$app" --key=redis_db --value="$redis_db"
#-------------------------------------------------
# config_panel.toml settings:
ynh_app_setting_set --app="$app" --key=debug_enabled --value="$debug_enabled"
ynh_app_setting_set --app="$app" --key=log_level --value="$log_level"
ynh_app_setting_set --app="$app" --key=admin_email --value="$admin_email"
ynh_app_setting_set --app="$app" --key=default_from_email --value="$default_from_email"
#================================================= #=================================================
# STANDARD MODIFICATIONS # STANDARD MODIFICATIONS
@ -89,7 +96,8 @@ ynh_psql_setup_db --db_user="$db_user" --db_name="$db_name"
ynh_script_progression --message="Configuring nginx web server..." ynh_script_progression --message="Configuring nginx web server..."
# Create a dedicated nginx config # Create a dedicated nginx config
# https://github.com/YunoHost/yunohost/blob/dev/data/helpers.d/nginx # https://yunohost.org/en/contribute/packaging_apps/helpers
# https://github.com/YunoHost/yunohost/blob/dev/helpers/nginx
ynh_add_nginx_config "public_path" "port" ynh_add_nginx_config "public_path" "port"
#================================================= #=================================================
@ -101,9 +109,9 @@ ynh_script_progression --message="Configuring system user..."
ynh_system_user_create --username="$app" --home_dir="$final_path" --use_shell ynh_system_user_create --username="$app" --home_dir="$final_path" --use_shell
#================================================= #=================================================
# PIP INSTALLATION # PYTHON VIRTUALENV
#================================================= #=================================================
ynh_script_progression --message="Install project via pip..." --weight=50 ynh_script_progression --message="Create Python virtualenv..." --weight=5
# Always recreate everything fresh with current python version # Always recreate everything fresh with current python version
ynh_secure_remove "${final_path}/venv" ynh_secure_remove "${final_path}/venv"
@ -114,6 +122,11 @@ python3 -m venv --without-pip "${final_path}/venv"
cp ../conf/requirements.txt "$final_path/requirements.txt" cp ../conf/requirements.txt "$final_path/requirements.txt"
chown -R "$app:" "$final_path" chown -R "$app:" "$final_path"
#=================================================
# PIP INSTALLATION
#=================================================
ynh_script_progression --message="Install project via pip..." --weight=45
#run source in a 'sub shell' #run source in a 'sub shell'
( (
set +o nounset set +o nounset
@ -129,45 +142,17 @@ chown -R "$app:" "$final_path"
# ================================================ # ================================================
ynh_script_progression --message="Create project configuration files..." ynh_script_progression --message="Create project configuration files..."
gunicorn_conf="$final_path/gunicorn.conf.py" ynh_add_config --template="gunicorn.conf.py" --destination="$final_path/gunicorn.conf.py"
cp "../conf/gunicorn.conf.py" "$gunicorn_conf"
ynh_replace_string --match_string="__FINAL_HOME_PATH__" --replace_string="$final_path" --target_file="$gunicorn_conf"
ynh_replace_string --match_string="__LOG_FILE__" --replace_string="$log_file" --target_file="$gunicorn_conf"
ynh_replace_string --match_string="__PORT__" --replace_string="$port" --target_file="$gunicorn_conf"
ynh_store_file_checksum --file="$gunicorn_conf"
cp ../conf/manage.py "$final_path/manage.py" ynh_add_config --template="manage.py" --destination="$final_path/manage.py"
ynh_replace_string --match_string="__FINAL_HOME_PATH__" --replace_string="$final_path" --target_file="$final_path/manage.py"
ynh_store_file_checksum --file="$final_path/manage.py"
chmod +x "$final_path/manage.py" chmod +x "$final_path/manage.py"
settings="$final_path/settings.py" ynh_add_config --template="settings.py" --destination="$final_path/settings.py"
cp "../conf/settings.py" "$settings" ynh_add_config --template="setup_user.py" --destination="$final_path/setup_user.py"
ynh_add_config --template="urls.py" --destination="$final_path/urls.py"
ynh_add_config --template="wsgi.py" --destination="$final_path/wsgi.py"
ynh_replace_string --match_string="__APP__" --replace_string="$app" --target_file="$settings" touch "$final_path/local_settings.py"
ynh_replace_string --match_string="__DB_NAME__" --replace_string="$db_name" --target_file="$settings"
ynh_replace_string --match_string="__DB_USER__" --replace_string="$db_user" --target_file="$settings"
ynh_replace_string --match_string="__DB_PWD__" --replace_string="$db_pwd" --target_file="$settings"
ynh_replace_string --match_string="__ADMIN__" --replace_string="$admin" --target_file="$settings"
ynh_replace_string --match_string="__ADMINMAIL__" --replace_string="$admin_mail" --target_file="$settings"
ynh_replace_string --match_string="__FINAL_HOME_PATH__" --replace_string="$final_path" --target_file="$settings"
ynh_replace_string --match_string="__FINAL_WWW_PATH__" --replace_string="$public_path" --target_file="$settings"
ynh_replace_string --match_string="__LOG_FILE__" --replace_string="$log_file" --target_file="$settings"
ynh_replace_string --match_string="__REDIS_DB__" --replace_string="$redis_db" --target_file="$settings"
ynh_replace_string --match_string="__DOMAIN__" --replace_string="$domain" --target_file="$settings"
ynh_replace_string --match_string="__PATH_URL__" --replace_string="$path_url" --target_file="$settings"
# Calculate and store the config file checksum into the app settings
ynh_store_file_checksum --file="$settings"
ynh_app_setting_set --app="$app" --key=redis_db --value="$redis_db"
cp ../conf/setup_user.py "$final_path/setup_user.py"
cp ../conf/urls.py "$final_path/urls.py"
cp ../conf/wsgi.py "$final_path/wsgi.py"
ynh_add_config --template="local_settings.py" --destination="$final_path/local_settings.py"
#================================================= #=================================================
# MIGRATE / COLLECTSTATIC / CREATEADMIN # MIGRATE / COLLECTSTATIC / CREATEADMIN
@ -183,7 +168,7 @@ cd "$final_path" || exit
./manage.py collectstatic --no-input ./manage.py collectstatic --no-input
# Create/update Django superuser (set unusable password, because auth done via SSOwat): # Create/update Django superuser (set unusable password, because auth done via SSOwat):
./manage.py create_superuser --username="$admin" --email="$admin_mail" ./manage.py create_superuser --username="$admin" --email="$(ynh_user_get_info "$admin" mail)"
# Check the configuration # Check the configuration
# This may fail in some cases with errors, etc., but the app works and the user can fix issues later. # This may fail in some cases with errors, etc., but the app works and the user can fix issues later.
@ -225,13 +210,29 @@ chmod o-rwx "$final_path"
#================================================= #=================================================
ynh_script_progression --message="Configuring a systemd service..." ynh_script_progression --message="Configuring a systemd service..."
# https://github.com/YunoHost/yunohost/blob/dev/data/helpers.d/systemd # https://yunohost.org/en/contribute/packaging_apps/helpers
ynh_add_systemd_config --service="$app" --template="django-fmd.service" # https://github.com/YunoHost/yunohost/blob/dev/helpers/systemd
ynh_add_systemd_config --service="$app" --template="systemd.service"
#================================================= #=================================================
# Start django-fmd via systemd # SETUP SSOWAT
#================================================= #=================================================
ynh_script_progression --message="Starting django-fmd's services..." --weight=5 ynh_script_progression --message="Configuring SSOwat..."
# Currently there are no public pages:
#
## Make app public if necessary or protect it
#if [ $is_public -eq 1 ]
#then
# # Everyone can access the app.
# # The "main" permission is automatically created before the install script.
# ynh_permission_update --permission "main" --add "visitors"
#fi
#=================================================
# Start the app server via systemd
#=================================================
ynh_script_progression --message="Starting django_example_ynh's services..." --weight=5
ynh_systemd_action --service_name="$app" --action="start" ynh_systemd_action --service_name="$app" --action="start"

View file

@ -20,8 +20,8 @@ ynh_abort_if_errors
#================================================= #=================================================
ynh_script_progression --message="Loading settings..." ynh_script_progression --message="Loading settings..."
public_path=$(ynh_app_setting_get --app="$app" --key=public_path)
final_path=$(ynh_app_setting_get --app="$app" --key=final_path) final_path=$(ynh_app_setting_get --app="$app" --key=final_path)
public_path=$(ynh_app_setting_get --app="$app" --key=public_path)
db_name=$(ynh_app_setting_get --app="$app" --key=db_name) db_name=$(ynh_app_setting_get --app="$app" --key=db_name)
db_user=$db_name db_user=$db_name
db_pwd=$(ynh_app_setting_get --app="$app" --key=psqlpwd) db_pwd=$(ynh_app_setting_get --app="$app" --key=psqlpwd)
@ -34,8 +34,6 @@ path_url=$(ynh_app_setting_get --app="$app" --key=path)
#================================================= #=================================================
ynh_script_progression --message="Validating restoration parameters..." ynh_script_progression --message="Validating restoration parameters..."
ynh_webpath_available --domain=$domain --path_url=$path_url \
|| ynh_die --message="Path not available: ${domain}${path_url}"
test ! -d $final_path \ test ! -d $final_path \
|| ynh_die --message="There is already a directory: $final_path " || ynh_die --message="There is already a directory: $final_path "
@ -52,8 +50,8 @@ ynh_restore_file --origin_path="/etc/nginx/conf.d/$domain.d/$app.conf"
#================================================= #=================================================
ynh_script_progression --message="Restoring the app main directory..." ynh_script_progression --message="Restoring the app main directory..."
ynh_restore_file --origin_path="$public_path"
ynh_restore_file --origin_path="$final_path" ynh_restore_file --origin_path="$final_path"
ynh_restore_file --origin_path="$public_path"
#================================================= #=================================================
# RECREATE THE DEDICATED USER # RECREATE THE DEDICATED USER
@ -81,10 +79,10 @@ ynh_script_progression --message="Reinstalling dependencies..." --weight=20
ynh_exec_warn_less ynh_install_app_dependencies "$pkg_dependencies" ynh_exec_warn_less ynh_install_app_dependencies "$pkg_dependencies"
#================================================= #=================================================
# REINSTALL PYTHON VIRTUALENV # PYTHON VIRTUALENV
# Maybe the backup contains a other Python version # Maybe the backup contains a other Python version
#================================================= #=================================================
ynh_script_progression --message="Upgrade Python virtualenv..." --weight=50 ynh_script_progression --message="Recreate Python virtualenv..." --weight=5
# Always recreate everything fresh with current python version # Always recreate everything fresh with current python version
ynh_secure_remove "${final_path}/venv" ynh_secure_remove "${final_path}/venv"
@ -93,6 +91,10 @@ ynh_secure_remove "${final_path}/venv"
python3 -m venv --without-pip "${final_path}/venv" python3 -m venv --without-pip "${final_path}/venv"
chown -R "$app:" "$final_path" chown -R "$app:" "$final_path"
#=================================================
# PIP INSTALLATION
#=================================================
ynh_script_progression --message="Install project via pip..." --weight=45
#run source in a 'sub shell' #run source in a 'sub shell'
( (
set +o nounset set +o nounset

View file

@ -26,10 +26,34 @@ db_pwd=$(ynh_app_setting_get --app="$app" --key=psqlpwd)
db_name=$(ynh_sanitize_dbid --db_name="$app") db_name=$(ynh_sanitize_dbid --db_name="$app")
db_user=$db_name db_user=$db_name
admin_mail=$(ynh_user_get_info "$admin" mail)
redis_db=$(ynh_app_setting_get --app="$app" --key=redis_db) redis_db=$(ynh_app_setting_get --app="$app" --key=redis_db)
django_debug=$(ynh_app_setting_get --app="$app" --key=django_debug) #-------------------------------------------------
# config_panel.toml settings:
debug_enabled=$(ynh_app_setting_get --app="$app" --key=debug_enabled)
if [ -z "$debug_enabled" ]; then
debug_enabled="0"
ynh_app_setting_set --app="$app" --key=debug_enabled --value="$debug_enabled"
fi
log_level=$(ynh_app_setting_get --app="$app" --key=log_level)
if [ -z "$log_level" ]; then
log_level="WARNING"
ynh_app_setting_set --app="$app" --key=log_level --value="$log_level"
fi
admin_email=$(ynh_app_setting_get --app="$app" --key=admin_email)
if [ -z "$admin_email" ]; then
admin_email="${admin}@${domain}"
ynh_app_setting_set --app="$app" --key=admin_email --value="$admin_email"
fi
default_from_email=$(ynh_app_setting_get --app="$app" --key=default_from_email)
if [ -z "$default_from_email" ]; then
default_from_email="${app}@${domain}"
ynh_app_setting_set --app="$app" --key=default_from_email --value="$default_from_email"
fi
#================================================= #=================================================
# BACKUP BEFORE UPGRADE THEN ACTIVE TRAP # BACKUP BEFORE UPGRADE THEN ACTIVE TRAP
@ -54,20 +78,14 @@ ynh_script_progression --message="Stopping systemd services..." --weight=5
ynh_systemd_action --service_name="$app" --action="stop" ynh_systemd_action --service_name="$app" --action="stop"
#=================================================
# Manage old settings
#=================================================
# Always deactivate settings.DEBUG:
ynh_app_setting_set --app=$app --key=django_debug --value="False"
#================================================= #=================================================
# NGINX CONFIGURATION # NGINX CONFIGURATION
#================================================= #=================================================
ynh_script_progression --message="Upgrading nginx web server configuration..." ynh_script_progression --message="Upgrading nginx web server configuration..."
# Create a dedicated nginx config # Create a dedicated nginx config
# https://github.com/YunoHost/yunohost/blob/dev/data/helpers.d/nginx # https://yunohost.org/en/contribute/packaging_apps/helpers
# https://github.com/YunoHost/yunohost/blob/dev/helpers/nginx
ynh_add_nginx_config "public_path" "port" ynh_add_nginx_config "public_path" "port"
#================================================= #=================================================
@ -92,12 +110,12 @@ ynh_system_user_create --username="$app" --home_dir="$final_path" --use_shell
#================================================= #=================================================
ynh_script_progression --message="Configuring a systemd service..." ynh_script_progression --message="Configuring a systemd service..."
ynh_add_systemd_config --service="$app" --template="django-fmd.service" ynh_add_systemd_config --service="$app" --template="systemd.service"
#================================================= #=================================================
# UPGRADE VENV # PYTHON VIRTUALENV
#================================================= #=================================================
ynh_script_progression --message="Upgrade project via pip..." --weight=50 ynh_script_progression --message="Recreate Python virtualenv..." --weight=5
# Always recreate everything fresh with current python version # Always recreate everything fresh with current python version
ynh_secure_remove "${final_path}/venv" ynh_secure_remove "${final_path}/venv"
@ -108,6 +126,10 @@ python3 -m venv --without-pip "${final_path}/venv"
cp ../conf/requirements.txt "$final_path/requirements.txt" cp ../conf/requirements.txt "$final_path/requirements.txt"
chown -R "$app:" "$final_path" chown -R "$app:" "$final_path"
#=================================================
# PIP INSTALLATION
#=================================================
ynh_script_progression --message="Install project via pip..." --weight=45
#run source in a 'sub shell' #run source in a 'sub shell'
( (
set +o nounset set +o nounset
@ -123,54 +145,15 @@ chown -R "$app:" "$final_path"
# ================================================ # ================================================
ynh_script_progression --message="Create project configuration files..." ynh_script_progression --message="Create project configuration files..."
gunicorn_conf="$final_path/gunicorn.conf.py" ynh_add_config --template="gunicorn.conf.py" --destination="$final_path/gunicorn.conf.py"
ynh_backup_if_checksum_is_different --file="$gunicorn_conf"
cp "../conf/gunicorn.conf.py" "$gunicorn_conf"
ynh_replace_string --match_string="__FINAL_HOME_PATH__" --replace_string="$final_path" --target_file="$gunicorn_conf"
ynh_replace_string --match_string="__LOG_FILE__" --replace_string="$log_file" --target_file="$gunicorn_conf"
ynh_replace_string --match_string="__PORT__" --replace_string="$port" --target_file="$gunicorn_conf"
ynh_store_file_checksum --file="$gunicorn_conf"
cp ../conf/manage.py "$final_path/manage.py" ynh_add_config --template="manage.py" --destination="$final_path/manage.py"
ynh_replace_string --match_string="__FINAL_HOME_PATH__" --replace_string="$final_path" --target_file="$final_path/manage.py"
ynh_store_file_checksum --file="$final_path/manage.py"
chmod +x "$final_path/manage.py" chmod +x "$final_path/manage.py"
# save old settings file ynh_add_config --template="settings.py" --destination="$final_path/settings.py"
settings="$final_path/settings.py" ynh_add_config --template="setup_user.py" --destination="$final_path/setup_user.py"
ynh_backup_if_checksum_is_different --file="$settings" ynh_add_config --template="urls.py" --destination="$final_path/urls.py"
ynh_add_config --template="wsgi.py" --destination="$final_path/wsgi.py"
cp "../conf/settings.py" "$settings"
ynh_replace_string --match_string="__APP__" --replace_string="$app" --target_file="$settings"
ynh_replace_string --match_string="__DB_NAME__" --replace_string="$db_name" --target_file="$settings"
ynh_replace_string --match_string="__DB_USER__" --replace_string="$db_user" --target_file="$settings"
ynh_replace_string --match_string="__DB_PWD__" --replace_string="$db_pwd" --target_file="$settings"
ynh_replace_string --match_string="__ADMIN__" --replace_string="$admin" --target_file="$settings"
ynh_replace_string --match_string="__ADMINMAIL__" --replace_string="$admin_mail" --target_file="$settings"
ynh_replace_string --match_string="__FINAL_HOME_PATH__" --replace_string="$final_path" --target_file="$settings"
ynh_replace_string --match_string="__FINAL_WWW_PATH__" --replace_string="$public_path" --target_file="$settings"
ynh_replace_string --match_string="__LOG_FILE__" --replace_string="$log_file" --target_file="$settings"
ynh_replace_string --match_string="__REDIS_DB__" --replace_string="$redis_db" --target_file="$settings"
ynh_replace_string --match_string="__DOMAIN__" --replace_string="$domain" --target_file="$settings"
ynh_replace_string --match_string="__PATH_URL__" --replace_string="$path_url" --target_file="$settings"
# Recalculate and store the config file checksum into the app settings
ynh_store_file_checksum --file="$settings"
ynh_backup_if_checksum_is_different --file="$final_path/setup_user.py"
cp ../conf/setup_user.py "$final_path/setup_user.py"
ynh_backup_if_checksum_is_different --file="$final_path/urls.py"
cp ../conf/urls.py "$final_path/urls.py"
ynh_backup_if_checksum_is_different --file="$final_path/wsgi.py"
cp ../conf/wsgi.py "$final_path/wsgi.py"
# Regenerate a fresh local_settings:
ynh_backup_if_checksum_is_different --file="$final_path/local_settings.py"
ynh_add_config --template="local_settings.py" --destination="$final_path/local_settings.py"
#================================================= #=================================================
# MIGRATE PYINVENTORY # MIGRATE PYINVENTORY
@ -186,7 +169,7 @@ cd "$final_path" || exit
./manage.py collectstatic --no-input ./manage.py collectstatic --no-input
# Create/update Django superuser (set unusable password, because auth done via SSOwat): # Create/update Django superuser (set unusable password, because auth done via SSOwat):
./manage.py create_superuser --username="$admin" --email="$admin_mail" ./manage.py create_superuser --username="$admin" --email="$(ynh_user_get_info "$admin" mail)"
# Check the configuration # Check the configuration
# This may fail in some cases with errors, etc., but the app works and the user can fix issues later. # This may fail in some cases with errors, etc., but the app works and the user can fix issues later.
@ -224,9 +207,9 @@ chmod o-rwx "$public_path"
chmod o-rwx "$final_path" chmod o-rwx "$final_path"
#================================================= #=================================================
# Start django-fmd via systemd # Start the app server via systemd
#================================================= #=================================================
ynh_script_progression --message="Starting django-fmd's services..." --weight=5 ynh_script_progression --message="Starting django_example_ynh's services..." --weight=5
ynh_systemd_action --service_name="$app" --action="start" ynh_systemd_action --service_name="$app" --action="start"

43
tests/conftest.py Normal file
View file

@ -0,0 +1,43 @@
"""
Special pytest init:
- Build a "local_test" YunoHost installation
- init Django with this local test installation
So the pytests will run against this local test installation
"""
import os
import sys
from pathlib import Path
import django
from django_yunohost_integration.local_test import create_local_test
BASE_PATH = Path(__file__).parent.parent
os.environ['DJANGO_SETTINGS_MODULE'] = 'settings'
def pytest_configure():
print('Compile YunoHost files...')
final_path = create_local_test(
django_settings_path=BASE_PATH / 'conf' / 'settings.py',
destination=BASE_PATH / 'local_test',
runserver=False,
extra_replacements={
'__DEBUG_ENABLED__': '0',
'__LOG_LEVEL__': 'INFO',
'__ADMIN_EMAIL__': 'foo-bar@test.tld',
'__DEFAULT_FROM_EMAIL__': 'django_app@test.tld',
},
)
print('Local test files created here:')
print(f'"{final_path}"')
os.chdir(final_path)
final_home_str = str(final_path)
if final_home_str not in sys.path:
sys.path.insert(0, final_home_str)
django.setup()

View file

@ -29,6 +29,9 @@ class DjangoYnhTestCase(HtmlAssertionMixin, TestCase):
assert isinstance(settings, LazySettings) assert isinstance(settings, LazySettings)
assert settings.configured is True assert settings.configured is True
assert 'django_yunohost_integration' in settings.INSTALLED_APPS
assert 'findmydevice.apps.FindMyDeviceConfig' in settings.INSTALLED_APPS
assert settings.PATH_URL == 'app_path' assert settings.PATH_URL == 'app_path'
def assert_path(path, end_text): def assert_path(path, end_text):
@ -36,11 +39,17 @@ class DjangoYnhTestCase(HtmlAssertionMixin, TestCase):
path = str(path) path = str(path)
assert path.endswith(end_text) assert path.endswith(end_text)
assert_path(settings.FINAL_HOME_PATH, '/local_test/opt_yunohost') assert_path(settings.FINALPATH, '/local_test/opt_yunohost')
assert_path(settings.FINAL_WWW_PATH, '/local_test/var_www') assert_path(settings.PUBLIC_PATH, '/local_test/var_www')
assert_path(settings.LOG_FILE, '/local_test/var_log_django-fmd.log') assert_path(settings.LOG_FILE, '/local_test/var_log_django-fmd.log')
assert settings.ROOT_URLCONF == 'urls' assert settings.ROOT_URLCONF == 'urls' # ./conf/urls.py
middlewares = [entry.rsplit('.', 1)[-1] for entry in settings.MIDDLEWARE]
assert 'SSOwatRemoteUserMiddleware' in middlewares
auth_backends = [entry.rsplit('.', 1)[-1] for entry in settings.AUTHENTICATION_BACKENDS]
assert 'SSOwatUserBackend' in auth_backends
def test_urls(self): def test_urls(self):
assert reverse('admin:index') == '/app_path/admin/' assert reverse('admin:index') == '/app_path/admin/'

View file

@ -53,7 +53,7 @@ def test_poetry_check():
def test_requirements_txt(): def test_requirements_txt():
requirements_txt = Path('conf', 'requirements.txt') requirements_txt = PACKAGE_ROOT / 'conf' / 'requirements.txt'
assert_is_file(requirements_txt) assert_is_file(requirements_txt)
output = poetry_check_output('export', '-f', 'requirements.txt') output = poetry_check_output('export', '-f', 'requirements.txt')