mirror of
https://github.com/YunoHost-Apps/django-for-runners_ynh.git
synced 2024-09-03 18:26:16 +02:00
commit
7a614965cb
32 changed files with 1997 additions and 1508 deletions
|
@ -16,5 +16,5 @@ max_line_length = 119
|
||||||
indent_style = tab
|
indent_style = tab
|
||||||
insert_final_newline = false
|
insert_final_newline = false
|
||||||
|
|
||||||
[*.yml]
|
[{*.yaml,*.yml}]
|
||||||
indent_size = 2
|
indent_size = 2
|
||||||
|
|
17
.github/workflows/tests.yml
vendored
17
.github/workflows/tests.yml
vendored
|
@ -1,3 +1,5 @@
|
||||||
|
|
||||||
|
|
||||||
name: tests
|
name: tests
|
||||||
|
|
||||||
on:
|
on:
|
||||||
|
@ -14,10 +16,7 @@ jobs:
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
python-version: ["3.12", "3.11", "3.10", "3.9"]
|
python-version: ["3.12", "3.11", "3.10"]
|
||||||
env:
|
|
||||||
PYTHONUNBUFFERED: 1
|
|
||||||
PYTHONWARNINGS: always
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
run: |
|
run: |
|
||||||
|
@ -35,7 +34,7 @@ jobs:
|
||||||
with:
|
with:
|
||||||
python-version: '${{ matrix.python-version }}'
|
python-version: '${{ matrix.python-version }}'
|
||||||
cache: 'pip' # caching pip dependencies
|
cache: 'pip' # caching pip dependencies
|
||||||
cache-dependency-path: '**/requirements.dev.txt'
|
cache-dependency-path: '**/requirements.*.txt'
|
||||||
|
|
||||||
- name: 'Bootstrap dev venv'
|
- name: 'Bootstrap dev venv'
|
||||||
# The first CLI call will create the .venv
|
# The first CLI call will create the .venv
|
||||||
|
@ -46,11 +45,14 @@ jobs:
|
||||||
run: |
|
run: |
|
||||||
./dev-cli.py --help
|
./dev-cli.py --help
|
||||||
|
|
||||||
- name: 'Safety'
|
- name: 'Run pip-audit'
|
||||||
run: |
|
run: |
|
||||||
./dev-cli.py safety
|
./dev-cli.py pip-audit
|
||||||
|
|
||||||
- name: 'Run tests with Python v${{ matrix.python-version }}'
|
- name: 'Run tests with Python v${{ matrix.python-version }}'
|
||||||
|
env:
|
||||||
|
PYTHONUNBUFFERED: 1
|
||||||
|
PYTHONWARNINGS: always
|
||||||
run: |
|
run: |
|
||||||
.venv/bin/coverage erase
|
.venv/bin/coverage erase
|
||||||
./dev-cli.py coverage
|
./dev-cli.py coverage
|
||||||
|
@ -61,3 +63,4 @@ jobs:
|
||||||
with:
|
with:
|
||||||
fail_ci_if_error: false
|
fail_ci_if_error: false
|
||||||
verbose: true
|
verbose: true
|
||||||
|
|
||||||
|
|
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -2,6 +2,7 @@
|
||||||
*.egg-info
|
*.egg-info
|
||||||
__pycache__
|
__pycache__
|
||||||
/dist/
|
/dist/
|
||||||
|
/build/
|
||||||
/coverage.*
|
/coverage.*
|
||||||
/htmlcov/
|
/htmlcov/
|
||||||
*.orig
|
*.orig
|
||||||
|
|
|
@ -5,4 +5,5 @@
|
||||||
- [Irakurri README euskaraz](README_eu.md)
|
- [Irakurri README euskaraz](README_eu.md)
|
||||||
- [Lire le README en français](README_fr.md)
|
- [Lire le README en français](README_fr.md)
|
||||||
- [Le o README en galego](README_gl.md)
|
- [Le o README en galego](README_gl.md)
|
||||||
|
- [Baca README dalam bahasa bahasa Indonesia](README_id.md)
|
||||||
- [阅读中文(简体)的 README](README_zh_Hans.md)
|
- [阅读中文(简体)的 README](README_zh_Hans.md)
|
||||||
|
|
|
@ -31,7 +31,7 @@ This package for YunoHost used [django-yunohost-integration](https://github.com/
|
||||||
More screenshots are here: [jedie.github.io/tree/master/screenshots/django-for-runners](https://github.com/jedie/jedie.github.io/tree/master/screenshots/django-for-runners/README.creole)
|
More screenshots are here: [jedie.github.io/tree/master/screenshots/django-for-runners](https://github.com/jedie/jedie.github.io/tree/master/screenshots/django-for-runners/README.creole)
|
||||||
|
|
||||||
|
|
||||||
**Shipped version:** 0.17.4~ynh1
|
**Shipped version:** 0.18.1~ynh1
|
||||||
|
|
||||||
## Screenshots
|
## Screenshots
|
||||||
|
|
||||||
|
|
|
@ -31,7 +31,7 @@ This package for YunoHost used [django-yunohost-integration](https://github.com/
|
||||||
More screenshots are here: [jedie.github.io/tree/master/screenshots/django-for-runners](https://github.com/jedie/jedie.github.io/tree/master/screenshots/django-for-runners/README.creole)
|
More screenshots are here: [jedie.github.io/tree/master/screenshots/django-for-runners](https://github.com/jedie/jedie.github.io/tree/master/screenshots/django-for-runners/README.creole)
|
||||||
|
|
||||||
|
|
||||||
**Versión actual:** 0.17.4~ynh1
|
**Versión actual:** 0.18.1~ynh1
|
||||||
|
|
||||||
## Capturas
|
## Capturas
|
||||||
|
|
||||||
|
|
|
@ -31,7 +31,7 @@ This package for YunoHost used [django-yunohost-integration](https://github.com/
|
||||||
More screenshots are here: [jedie.github.io/tree/master/screenshots/django-for-runners](https://github.com/jedie/jedie.github.io/tree/master/screenshots/django-for-runners/README.creole)
|
More screenshots are here: [jedie.github.io/tree/master/screenshots/django-for-runners](https://github.com/jedie/jedie.github.io/tree/master/screenshots/django-for-runners/README.creole)
|
||||||
|
|
||||||
|
|
||||||
**Paketatutako bertsioa:** 0.17.4~ynh1
|
**Paketatutako bertsioa:** 0.18.1~ynh1
|
||||||
|
|
||||||
## Pantaila-argazkiak
|
## Pantaila-argazkiak
|
||||||
|
|
||||||
|
|
|
@ -31,7 +31,7 @@ This package for YunoHost used [django-yunohost-integration](https://github.com/
|
||||||
More screenshots are here: [jedie.github.io/tree/master/screenshots/django-for-runners](https://github.com/jedie/jedie.github.io/tree/master/screenshots/django-for-runners/README.creole)
|
More screenshots are here: [jedie.github.io/tree/master/screenshots/django-for-runners](https://github.com/jedie/jedie.github.io/tree/master/screenshots/django-for-runners/README.creole)
|
||||||
|
|
||||||
|
|
||||||
**Version incluse :** 0.17.4~ynh1
|
**Version incluse :** 0.18.1~ynh1
|
||||||
|
|
||||||
## Captures d’écran
|
## Captures d’écran
|
||||||
|
|
||||||
|
|
|
@ -31,7 +31,7 @@ This package for YunoHost used [django-yunohost-integration](https://github.com/
|
||||||
More screenshots are here: [jedie.github.io/tree/master/screenshots/django-for-runners](https://github.com/jedie/jedie.github.io/tree/master/screenshots/django-for-runners/README.creole)
|
More screenshots are here: [jedie.github.io/tree/master/screenshots/django-for-runners](https://github.com/jedie/jedie.github.io/tree/master/screenshots/django-for-runners/README.creole)
|
||||||
|
|
||||||
|
|
||||||
**Versión proporcionada:** 0.17.4~ynh1
|
**Versión proporcionada:** 0.18.1~ynh1
|
||||||
|
|
||||||
## Capturas de pantalla
|
## Capturas de pantalla
|
||||||
|
|
||||||
|
|
60
README_id.md
Normal file
60
README_id.md
Normal file
|
@ -0,0 +1,60 @@
|
||||||
|
<!--
|
||||||
|
N.B.: README ini dibuat secara otomatis oleh <https://github.com/YunoHost/apps/tree/master/tools/readme_generator>
|
||||||
|
Ini TIDAK boleh diedit dengan tangan.
|
||||||
|
-->
|
||||||
|
|
||||||
|
# django-for-runners untuk YunoHost
|
||||||
|
|
||||||
|
[![Tingkat integrasi](https://dash.yunohost.org/integration/django-for-runners.svg)](https://ci-apps.yunohost.org/ci/apps/django-for-runners/) ![Status kerja](https://ci-apps.yunohost.org/ci/badges/django-for-runners.status.svg) ![Status pemeliharaan](https://ci-apps.yunohost.org/ci/badges/django-for-runners.maintain.svg)
|
||||||
|
|
||||||
|
[![Pasang django-for-runners dengan YunoHost](https://install-app.yunohost.org/install-with-yunohost.svg)](https://install-app.yunohost.org/?app=django-for-runners)
|
||||||
|
|
||||||
|
*[Baca README ini dengan bahasa yang lain.](./ALL_README.md)*
|
||||||
|
|
||||||
|
> *Paket ini memperbolehkan Anda untuk memasang django-for-runners secara cepat dan mudah pada server YunoHost.*
|
||||||
|
> *Bila Anda tidak mempunyai YunoHost, silakan berkonsultasi dengan [panduan](https://yunohost.org/install) untuk mempelajari bagaimana untuk memasangnya.*
|
||||||
|
|
||||||
|
## Ringkasan
|
||||||
|
|
||||||
|
[![tests](https://github.com/YunoHost-Apps/django-for-runners_ynh/actions/workflows/tests.yml/badge.svg?branch=main)](https://github.com/YunoHost-Apps/django-for-runners_ynh/actions/workflows/tests.yml)
|
||||||
|
[![codecov](https://codecov.io/github/jedie/for_runners_ynh/branch/main/graph/badge.svg)](https://app.codecov.io/github/jedie/for_runners_ynh)
|
||||||
|
[![for_runners_ynh @ PyPi](https://img.shields.io/pypi/v/for_runners_ynh?label=for_runners_ynh%20%40%20PyPi)](https://pypi.org/project/for_runners_ynh/)
|
||||||
|
[![Python Versions](https://img.shields.io/pypi/pyversions/for_runners_ynh)](https://github.com/YunoHost-Apps/django-for-runners_ynh/blob/main/pyproject.toml)
|
||||||
|
[![License GPL-3.0-or-later](https://img.shields.io/pypi/l/for_runners_ynh)](https://github.com/YunoHost-Apps/django-for-runners_ynh/blob/main/LICENSE)
|
||||||
|
|
||||||
|
[django-for-runners](https://github.com/jedie/django-for-runners) is a libre web-based management for your GPX tracks of your running (or other sports activity). Used [Python](https://www.python.org/)/[Django](https://www.djangoproject.com/).
|
||||||
|
|
||||||
|
Pull requests welcome ;)
|
||||||
|
|
||||||
|
This package for YunoHost used [django-yunohost-integration](https://github.com/YunoHost-Apps/django_yunohost_integration)
|
||||||
|
|
||||||
|
More screenshots are here: [jedie.github.io/tree/master/screenshots/django-for-runners](https://github.com/jedie/jedie.github.io/tree/master/screenshots/django-for-runners/README.creole)
|
||||||
|
|
||||||
|
|
||||||
|
**Versi terkirim:** 0.18.1~ynh1
|
||||||
|
|
||||||
|
## Tangkapan Layar
|
||||||
|
|
||||||
|
![Tangkapan Layar pada django-for-runners](./doc/screenshots/for_runers_v060_2018_07_31_gpx_track.png)
|
||||||
|
![Tangkapan Layar pada django-for-runners](./doc/screenshots/for_runners_v040_2018_6_26_gpx_info.png)
|
||||||
|
![Tangkapan Layar pada django-for-runners](./doc/screenshots/for_runners_v060_2018_07_19_event_costs.png)
|
||||||
|
|
||||||
|
## Dokumentasi dan sumber daya
|
||||||
|
|
||||||
|
- Depot kode aplikasi hulu: <https://github.com/jedie/django-for-runners>
|
||||||
|
- Gudang YunoHost: <https://apps.yunohost.org/app/django-for-runners>
|
||||||
|
- Laporkan bug: <https://github.com/YunoHost-Apps/django-for-runners_ynh/issues>
|
||||||
|
|
||||||
|
## Info developer
|
||||||
|
|
||||||
|
Silakan kirim pull request ke [`testing` branch](https://github.com/YunoHost-Apps/django-for-runners_ynh/tree/testing).
|
||||||
|
|
||||||
|
Untuk mencoba branch `testing`, silakan dilanjutkan seperti:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo yunohost app install https://github.com/YunoHost-Apps/django-for-runners_ynh/tree/testing --debug
|
||||||
|
atau
|
||||||
|
sudo yunohost app upgrade django-for-runners -u https://github.com/YunoHost-Apps/django-for-runners_ynh/tree/testing --debug
|
||||||
|
```
|
||||||
|
|
||||||
|
**Info lebih lanjut mengenai pemaketan aplikasi:** <https://yunohost.org/packaging_apps>
|
|
@ -11,7 +11,7 @@ NON DEVE essere modificato manualmente.
|
||||||
|
|
||||||
*[Leggi questo README in altre lingue.](./ALL_README.md)*
|
*[Leggi questo README in altre lingue.](./ALL_README.md)*
|
||||||
|
|
||||||
> *Questo pacchetto ti permette di installare django-for-runners su un server YunoHost in modo semplice e veloce.*
|
> *Questo pacchetto ti permette di installare django-for-runners su un server YunoHost in modo semplice e veloce.*
|
||||||
> *Se non hai YunoHost, consulta [la guida](https://yunohost.org/install) per imparare a installarlo.*
|
> *Se non hai YunoHost, consulta [la guida](https://yunohost.org/install) per imparare a installarlo.*
|
||||||
|
|
||||||
## Panoramica
|
## Panoramica
|
||||||
|
@ -34,7 +34,7 @@ This package for YunoHost used [django-yunohost-integration](https://github.com/
|
||||||
More screenshots are here: [jedie.github.io/tree/master/screenshots/django-for-runners](https://github.com/jedie/jedie.github.io/tree/master/screenshots/django-for-runners/README.creole)
|
More screenshots are here: [jedie.github.io/tree/master/screenshots/django-for-runners](https://github.com/jedie/jedie.github.io/tree/master/screenshots/django-for-runners/README.creole)
|
||||||
|
|
||||||
|
|
||||||
**Versione pubblicata:** 0.17.4~ynh1
|
**Versione pubblicata:** 0.18.1~ynh1
|
||||||
|
|
||||||
## Screenshot
|
## Screenshot
|
||||||
|
|
||||||
|
|
|
@ -31,7 +31,7 @@ This package for YunoHost used [django-yunohost-integration](https://github.com/
|
||||||
More screenshots are here: [jedie.github.io/tree/master/screenshots/django-for-runners](https://github.com/jedie/jedie.github.io/tree/master/screenshots/django-for-runners/README.creole)
|
More screenshots are here: [jedie.github.io/tree/master/screenshots/django-for-runners](https://github.com/jedie/jedie.github.io/tree/master/screenshots/django-for-runners/README.creole)
|
||||||
|
|
||||||
|
|
||||||
**分发版本:** 0.17.4~ynh1
|
**分发版本:** 0.18.1~ynh1
|
||||||
|
|
||||||
## 截图
|
## 截图
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -59,7 +59,9 @@ if 'axes' not in INSTALLED_APPS:
|
||||||
INSTALLED_APPS.append('django_yunohost_integration.apps.YunohostIntegrationConfig')
|
INSTALLED_APPS.append('django_yunohost_integration.apps.YunohostIntegrationConfig')
|
||||||
|
|
||||||
|
|
||||||
SECRET_KEY = __get_or_create_secret(DATA_DIR_PATH / 'secret.txt') # /home/yunohost.app/$app/secret.txt
|
SECRET_KEY = __get_or_create_secret(
|
||||||
|
DATA_DIR_PATH / 'secret.txt'
|
||||||
|
) # /home/yunohost.app/$app/secret.txt
|
||||||
|
|
||||||
|
|
||||||
MIDDLEWARE.insert(
|
MIDDLEWARE.insert(
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.contrib import admin
|
from django.contrib import admin
|
||||||
from django.urls import path
|
from django.urls import path
|
||||||
|
from django.views.generic import RedirectView
|
||||||
|
|
||||||
from for_runners.views.media_files import UserMediaView
|
from for_runners.views.media_files import UserMediaView
|
||||||
|
|
||||||
|
@ -9,6 +10,7 @@ if settings.PATH_URL:
|
||||||
# settings.PATH_URL is __PATH__
|
# settings.PATH_URL is __PATH__
|
||||||
# Prefix all urls with "PATH_URL":
|
# Prefix all urls with "PATH_URL":
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
|
path('', RedirectView.as_view(url=f'{settings.PATH_URL}/')),
|
||||||
path(f'{settings.PATH_URL}/media/<slug:user_name>/<path:path>', UserMediaView.as_view()),
|
path(f'{settings.PATH_URL}/media/<slug:user_name>/<path:path>', UserMediaView.as_view()),
|
||||||
# TODO: https://github.com/jedie/django-for-runners/issues/25
|
# TODO: https://github.com/jedie/django-for-runners/issues/25
|
||||||
# path(settings.MEDIA_URL.lstrip('/'), include('django_tools.serve_media_app.urls')),
|
# path(settings.MEDIA_URL.lstrip('/'), include('django_tools.serve_media_app.urls')),
|
||||||
|
|
11
dev-cli.py
11
dev-cli.py
|
@ -8,6 +8,7 @@
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import hashlib
|
import hashlib
|
||||||
|
import shlex
|
||||||
import subprocess
|
import subprocess
|
||||||
import sys
|
import sys
|
||||||
import venv
|
import venv
|
||||||
|
@ -32,7 +33,7 @@ else:
|
||||||
sys.exit(-1)
|
sys.exit(-1)
|
||||||
|
|
||||||
|
|
||||||
assert sys.version_info >= (3, 9), 'Python version is too old!'
|
assert sys.version_info >= (3, 10), f'Python version {sys.version_info} is too old!'
|
||||||
|
|
||||||
|
|
||||||
if sys.platform == 'win32': # wtf
|
if sys.platform == 'win32': # wtf
|
||||||
|
@ -77,7 +78,7 @@ def venv_up2date():
|
||||||
|
|
||||||
|
|
||||||
def verbose_check_call(*popen_args):
|
def verbose_check_call(*popen_args):
|
||||||
print(f'\n+ {" ".join(str(arg) for arg in popen_args)}\n')
|
print(f'\n+ {shlex.join(str(arg) for arg in popen_args)}\n')
|
||||||
return subprocess.check_call(popen_args)
|
return subprocess.check_call(popen_args)
|
||||||
|
|
||||||
|
|
||||||
|
@ -86,17 +87,17 @@ def main(argv):
|
||||||
|
|
||||||
# Create virtual env in ".venv/":
|
# Create virtual env in ".venv/":
|
||||||
if not PYTHON_PATH.is_file():
|
if not PYTHON_PATH.is_file():
|
||||||
print('Create virtual env here:', VENV_PATH.absolute())
|
print(f'Create virtual env here: {VENV_PATH.absolute()}')
|
||||||
builder = venv.EnvBuilder(symlinks=True, upgrade=True, with_pip=True)
|
builder = venv.EnvBuilder(symlinks=True, upgrade=True, with_pip=True)
|
||||||
builder.create(env_dir=VENV_PATH)
|
builder.create(env_dir=VENV_PATH)
|
||||||
|
|
||||||
|
if not PROJECT_SHELL_SCRIPT.is_file() or not venv_up2date():
|
||||||
# Update pip
|
# Update pip
|
||||||
verbose_check_call(PYTHON_PATH, '-m', 'pip', 'install', '-U', 'pip')
|
verbose_check_call(PYTHON_PATH, '-m', 'pip', 'install', '-U', 'pip')
|
||||||
|
|
||||||
if not PIP_SYNC_PATH.is_file():
|
|
||||||
# Install pip-tools
|
# Install pip-tools
|
||||||
verbose_check_call(PYTHON_PATH, '-m', 'pip', 'install', '-U', 'pip-tools')
|
verbose_check_call(PYTHON_PATH, '-m', 'pip', 'install', '-U', 'pip-tools')
|
||||||
|
|
||||||
if not PROJECT_SHELL_SCRIPT.is_file() or not venv_up2date():
|
|
||||||
# install requirements via "pip-sync"
|
# install requirements via "pip-sync"
|
||||||
verbose_check_call(PIP_SYNC_PATH, str(DEP_LOCK_PATH))
|
verbose_check_call(PIP_SYNC_PATH, str(DEP_LOCK_PATH))
|
||||||
|
|
||||||
|
|
|
@ -39,16 +39,16 @@ Usage: ./dev-cli.py [OPTIONS] COMMAND [ARGS]...
|
||||||
╰──────────────────────────────────────────────────────────────────────────────────────────────────╯
|
╰──────────────────────────────────────────────────────────────────────────────────────────────────╯
|
||||||
╭─ Commands ───────────────────────────────────────────────────────────────────────────────────────╮
|
╭─ Commands ───────────────────────────────────────────────────────────────────────────────────────╮
|
||||||
│ check-code-style Check code style by calling darker + flake8 │
|
│ check-code-style Check code style by calling darker + flake8 │
|
||||||
│ coverage Run and show coverage. │
|
│ coverage Run tests and show coverage report. │
|
||||||
│ diffsettings Run "diffsettings" manage command against a "local_test" YunoHost │
|
│ diffsettings Run "diffsettings" manage command against a "local_test" YunoHost │
|
||||||
│ installation. │
|
│ installation. │
|
||||||
│ fix-code-style Fix code style of all for_runners_ynh source code files via darker │
|
│ fix-code-style Fix code style of all your_cool_package source code files via darker │
|
||||||
│ install Run pip-sync and install 'for_runners_ynh' via pip as editable. │
|
│ install Run pip-sync and install 'for_runners_ynh' via pip as editable. │
|
||||||
│ local-test Build a "local_test" YunoHost installation and start the Django dev. │
|
│ local-test Build a "local_test" YunoHost installation and start the Django dev. │
|
||||||
│ server against it. │
|
│ server against it. │
|
||||||
│ mypy Run Mypy (configured in pyproject.toml) │
|
│ mypy Run Mypy (configured in pyproject.toml) │
|
||||||
|
│ pip-audit Run pip-audit check against current requirements files │
|
||||||
│ publish Build and upload this project to PyPi │
|
│ publish Build and upload this project to PyPi │
|
||||||
│ safety Run safety check against current requirements files │
|
|
||||||
│ test Compile YunoHost files and run Django unittests │
|
│ test Compile YunoHost files and run Django unittests │
|
||||||
│ tox Run tox │
|
│ tox Run tox │
|
||||||
│ update Update "requirements*.txt" dependencies files │
|
│ update Update "requirements*.txt" dependencies files │
|
||||||
|
|
|
@ -3,5 +3,5 @@
|
||||||
YunoHost app package for https://github.com/jedie/django-for-runners
|
YunoHost app package for https://github.com/jedie/django-for-runners
|
||||||
"""
|
"""
|
||||||
|
|
||||||
__version__ = '0.17.4+ynh1'
|
__version__ = '0.18.1+ynh1'
|
||||||
__author__ = 'Jens Diemer <git@jensdiemer.de>'
|
__author__ = 'Jens Diemer <git@jensdiemer.de>'
|
||||||
|
|
|
@ -1,32 +1,37 @@
|
||||||
"""
|
"""
|
||||||
CLI for development
|
CLI for development
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
import os
|
import shlex
|
||||||
import sys
|
import sys
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
import django
|
|
||||||
import rich_click as click
|
import rich_click as click
|
||||||
from bx_py_utils.path import assert_is_file
|
from cli_base.cli_tools import code_style
|
||||||
|
from cli_base.cli_tools.dev_tools import run_coverage, run_tox
|
||||||
from cli_base.cli_tools.subprocess_utils import verbose_check_call
|
from cli_base.cli_tools.subprocess_utils import verbose_check_call
|
||||||
|
from cli_base.cli_tools.test_utils.snapshot import UpdateTestSnapshotFiles
|
||||||
|
from cli_base.cli_tools.verbosity import OPTION_KWARGS_VERBOSE
|
||||||
from cli_base.cli_tools.version_info import print_version
|
from cli_base.cli_tools.version_info import print_version
|
||||||
|
from cli_base.run_pip_audit import run_pip_audit
|
||||||
from django.core.management.commands.test import Command as DjangoTestCommand
|
from django.core.management.commands.test import Command as DjangoTestCommand
|
||||||
from django_yunohost_integration.local_test import CreateResults, create_local_test
|
from django_yunohost_integration.local_test import create_local_test
|
||||||
from manageprojects.utilities import code_style
|
|
||||||
from manageprojects.utilities.publish import publish_package
|
from manageprojects.utilities.publish import publish_package
|
||||||
from rich import print # noqa; noqa
|
from rich import print
|
||||||
|
from rich.console import Console
|
||||||
|
from rich.traceback import install as rich_traceback_install
|
||||||
from rich_click import RichGroup
|
from rich_click import RichGroup
|
||||||
|
|
||||||
import for_runners_ynh
|
import for_runners_ynh
|
||||||
|
from for_runners_ynh import constants
|
||||||
|
from for_runners_ynh.constants import PACKAGE_ROOT
|
||||||
|
from for_runners_ynh.tests import setup_ynh_tests
|
||||||
|
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
PACKAGE_ROOT = Path(for_runners_ynh.__file__).parent.parent
|
|
||||||
assert_is_file(PACKAGE_ROOT / 'pyproject.toml')
|
|
||||||
|
|
||||||
OPTION_ARGS_DEFAULT_TRUE = dict(is_flag=True, show_default=True, default=True)
|
OPTION_ARGS_DEFAULT_TRUE = dict(is_flag=True, show_default=True, default=True)
|
||||||
OPTION_ARGS_DEFAULT_FALSE = dict(is_flag=True, show_default=True, default=False)
|
OPTION_ARGS_DEFAULT_FALSE = dict(is_flag=True, show_default=True, default=False)
|
||||||
ARGUMENT_EXISTING_DIR = dict(
|
ARGUMENT_EXISTING_DIR = dict(
|
||||||
|
@ -45,7 +50,6 @@ ARGUMENT_NOT_EXISTING_DIR = dict(
|
||||||
ARGUMENT_EXISTING_FILE = dict(
|
ARGUMENT_EXISTING_FILE = dict(
|
||||||
type=click.Path(exists=True, file_okay=True, dir_okay=False, readable=True, path_type=Path)
|
type=click.Path(exists=True, file_okay=True, dir_okay=False, readable=True, path_type=Path)
|
||||||
)
|
)
|
||||||
CLI_EPILOG = 'Project Homepage: https://github.com/YunoHost-Apps/django-for-runners_ynh'
|
|
||||||
|
|
||||||
|
|
||||||
class ClickGroup(RichGroup): # FIXME: How to set the "info_name" easier?
|
class ClickGroup(RichGroup): # FIXME: How to set the "info_name" easier?
|
||||||
|
@ -54,38 +58,22 @@ class ClickGroup(RichGroup): # FIXME: How to set the "info_name" easier?
|
||||||
return super().make_context(info_name, *args, **kwargs)
|
return super().make_context(info_name, *args, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
@click.group(cls=ClickGroup, epilog=CLI_EPILOG)
|
@click.group(
|
||||||
|
cls=ClickGroup,
|
||||||
|
epilog=constants.CLI_EPILOG,
|
||||||
|
)
|
||||||
def cli():
|
def cli():
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
@click.command()
|
@cli.command()
|
||||||
@click.option('--verbose/--no-verbose', **OPTION_ARGS_DEFAULT_FALSE)
|
@click.option('-v', '--verbosity', **OPTION_KWARGS_VERBOSE)
|
||||||
def mypy(verbose: bool = True):
|
def mypy(verbosity: int):
|
||||||
"""Run Mypy (configured in pyproject.toml)"""
|
"""Run Mypy (configured in pyproject.toml)"""
|
||||||
verbose_check_call('mypy', '.', cwd=PACKAGE_ROOT, verbose=verbose, exit_on_error=True)
|
verbose_check_call('mypy', '.', cwd=PACKAGE_ROOT, verbose=verbosity > 0, exit_on_error=True)
|
||||||
|
|
||||||
|
|
||||||
cli.add_command(mypy)
|
@cli.command()
|
||||||
|
|
||||||
|
|
||||||
@click.command()
|
|
||||||
@click.option('--verbose/--no-verbose', **OPTION_ARGS_DEFAULT_FALSE)
|
|
||||||
def coverage(verbose: bool = True):
|
|
||||||
"""
|
|
||||||
Run and show coverage.
|
|
||||||
"""
|
|
||||||
verbose_check_call('coverage', 'run', verbose=verbose, exit_on_error=True)
|
|
||||||
verbose_check_call('coverage', 'combine', '--append', verbose=verbose, exit_on_error=True)
|
|
||||||
verbose_check_call('coverage', 'report', '--fail-under=10', verbose=verbose, exit_on_error=True)
|
|
||||||
verbose_check_call('coverage', 'xml', verbose=verbose, exit_on_error=True)
|
|
||||||
verbose_check_call('coverage', 'json', verbose=verbose, exit_on_error=True)
|
|
||||||
|
|
||||||
|
|
||||||
cli.add_command(coverage)
|
|
||||||
|
|
||||||
|
|
||||||
@click.command()
|
|
||||||
def install():
|
def install():
|
||||||
"""
|
"""
|
||||||
Run pip-sync and install 'for_runners_ynh' via pip as editable.
|
Run pip-sync and install 'for_runners_ynh' via pip as editable.
|
||||||
|
@ -94,21 +82,16 @@ def install():
|
||||||
verbose_check_call('pip', 'install', '--no-deps', '-e', '.')
|
verbose_check_call('pip', 'install', '--no-deps', '-e', '.')
|
||||||
|
|
||||||
|
|
||||||
cli.add_command(install)
|
@cli.command()
|
||||||
|
@click.option('-v', '--verbosity', **OPTION_KWARGS_VERBOSE)
|
||||||
|
def pip_audit(verbosity: int):
|
||||||
@click.command()
|
|
||||||
def safety():
|
|
||||||
"""
|
"""
|
||||||
Run safety check against current requirements files
|
Run pip-audit check against current requirements files
|
||||||
"""
|
"""
|
||||||
verbose_check_call('safety', 'check', '-r', 'requirements.dev.txt')
|
run_pip_audit(base_path=PACKAGE_ROOT, verbosity=verbosity)
|
||||||
|
|
||||||
|
|
||||||
cli.add_command(safety)
|
@cli.command()
|
||||||
|
|
||||||
|
|
||||||
@click.command()
|
|
||||||
def update():
|
def update():
|
||||||
"""
|
"""
|
||||||
Update "requirements*.txt" dependencies files
|
Update "requirements*.txt" dependencies files
|
||||||
|
@ -150,22 +133,19 @@ def update():
|
||||||
extra_env=extra_env,
|
extra_env=extra_env,
|
||||||
)
|
)
|
||||||
|
|
||||||
verbose_check_call(bin_path / 'safety', 'check', '-r', 'requirements.dev.txt')
|
run_pip_audit(base_path=PACKAGE_ROOT)
|
||||||
|
|
||||||
# Install new dependencies in current .venv:
|
# Install new dependencies in current .venv:
|
||||||
verbose_check_call(bin_path / 'pip-sync', 'requirements.dev.txt')
|
verbose_check_call(bin_path / 'pip-sync', 'requirements.dev.txt')
|
||||||
|
|
||||||
|
|
||||||
cli.add_command(update)
|
@cli.command()
|
||||||
|
|
||||||
|
|
||||||
@click.command()
|
|
||||||
def publish():
|
def publish():
|
||||||
"""
|
"""
|
||||||
Build and upload this project to PyPi
|
Build and upload this project to PyPi
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
_run_django_test_cli() # Don't publish a broken state
|
_run_django_test_cli(argv=sys.argv, exit_after_run=True) # Don't publish a broken state
|
||||||
except SystemExit as err:
|
except SystemExit as err:
|
||||||
assert err.code == 0, f'Exit code is not 0: {err.code}'
|
assert err.code == 0, f'Exit code is not 0: {err.code}'
|
||||||
|
|
||||||
|
@ -176,133 +156,87 @@ def publish():
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
cli.add_command(publish)
|
@cli.command()
|
||||||
|
|
||||||
|
|
||||||
@click.command()
|
|
||||||
@click.option('--color/--no-color', **OPTION_ARGS_DEFAULT_TRUE)
|
@click.option('--color/--no-color', **OPTION_ARGS_DEFAULT_TRUE)
|
||||||
@click.option('--verbose/--no-verbose', **OPTION_ARGS_DEFAULT_FALSE)
|
@click.option('-v', '--verbosity', **OPTION_KWARGS_VERBOSE)
|
||||||
def fix_code_style(color: bool = True, verbose: bool = False):
|
def fix_code_style(color: bool, verbosity: int):
|
||||||
"""
|
"""
|
||||||
Fix code style of all for_runners_ynh source code files via darker
|
Fix code style of all your_cool_package source code files via darker
|
||||||
"""
|
"""
|
||||||
code_style.fix(package_root=PACKAGE_ROOT, color=color, verbose=verbose)
|
code_style.fix(package_root=PACKAGE_ROOT, darker_color=color, darker_verbose=verbosity > 0)
|
||||||
|
|
||||||
|
|
||||||
cli.add_command(fix_code_style)
|
@cli.command()
|
||||||
|
|
||||||
|
|
||||||
@click.command()
|
|
||||||
@click.option('--color/--no-color', **OPTION_ARGS_DEFAULT_TRUE)
|
@click.option('--color/--no-color', **OPTION_ARGS_DEFAULT_TRUE)
|
||||||
@click.option('--verbose/--no-verbose', **OPTION_ARGS_DEFAULT_FALSE)
|
@click.option('-v', '--verbosity', **OPTION_KWARGS_VERBOSE)
|
||||||
def check_code_style(color: bool = True, verbose: bool = False):
|
def check_code_style(color: bool, verbosity: int):
|
||||||
"""
|
"""
|
||||||
Check code style by calling darker + flake8
|
Check code style by calling darker + flake8
|
||||||
"""
|
"""
|
||||||
code_style.check(package_root=PACKAGE_ROOT, color=color, verbose=verbose)
|
code_style.check(package_root=PACKAGE_ROOT, darker_color=color, darker_verbose=verbosity > 0)
|
||||||
|
|
||||||
|
|
||||||
cli.add_command(check_code_style)
|
@cli.command()
|
||||||
|
|
||||||
|
|
||||||
@click.command()
|
|
||||||
def update_test_snapshot_files():
|
def update_test_snapshot_files():
|
||||||
"""
|
"""
|
||||||
Update all test snapshot files (by remove and recreate all snapshot files)
|
Update all test snapshot files (by remove and recreate all snapshot files)
|
||||||
"""
|
"""
|
||||||
|
with UpdateTestSnapshotFiles(root_path=PACKAGE_ROOT, verbose=True):
|
||||||
def iter_snapshot_files():
|
# Just recreate them by running tests:
|
||||||
yield from PACKAGE_ROOT.rglob('*.snapshot.*')
|
_run_django_test_cli(argv=sys.argv, exit_after_run=False)
|
||||||
|
|
||||||
removed_file_count = 0
|
|
||||||
for item in iter_snapshot_files():
|
|
||||||
item.unlink()
|
|
||||||
removed_file_count += 1
|
|
||||||
print(f'{removed_file_count} test snapshot files removed... run tests...')
|
|
||||||
|
|
||||||
# Just recreate them by running tests:
|
|
||||||
os.environ['RAISE_SNAPSHOT_ERRORS'] = '0' # Recreate snapshot files without error
|
|
||||||
try:
|
|
||||||
_run_django_test_cli()
|
|
||||||
finally:
|
|
||||||
new_files = len(list(iter_snapshot_files()))
|
|
||||||
print(f'{new_files} test snapshot files created, ok.\n')
|
|
||||||
|
|
||||||
|
|
||||||
cli.add_command(update_test_snapshot_files)
|
def _run_django_test_cli(argv, exit_after_run=True):
|
||||||
|
|
||||||
|
|
||||||
def _run_django_test_cli():
|
|
||||||
"""
|
"""
|
||||||
Call the origin Django test manage command CLI and pass all args to it.
|
Call the origin Django test manage command CLI and pass all args to it.
|
||||||
"""
|
"""
|
||||||
os.environ['DJANGO_SETTINGS_MODULE'] = 'settings'
|
setup_ynh_tests()
|
||||||
|
|
||||||
print('Compile YunoHost files...')
|
print('\nStart Django unittests with:')
|
||||||
result: CreateResults = create_local_test(
|
for default_arg in ('shuffle', 'buffer'):
|
||||||
django_settings_path=PACKAGE_ROOT / 'conf' / 'settings.py',
|
if default_arg not in argv and f'--no-{default_arg}' not in argv:
|
||||||
destination=PACKAGE_ROOT / 'local_test',
|
argv.append(f'--{default_arg}')
|
||||||
runserver=False,
|
print(shlex.join(argv))
|
||||||
extra_replacements={
|
print()
|
||||||
'__DEBUG_ENABLED__': '0', # "1" or "0" string
|
|
||||||
'__LOG_LEVEL__': 'INFO',
|
|
||||||
'__ADMIN_EMAIL__': 'foo-bar@test.tld',
|
|
||||||
'__DEFAULT_FROM_EMAIL__': 'django_app@test.tld',
|
|
||||||
},
|
|
||||||
)
|
|
||||||
print('Local test files created:')
|
|
||||||
print(result)
|
|
||||||
|
|
||||||
data_dir = str(result.data_dir_path)
|
|
||||||
if data_dir not in sys.path:
|
|
||||||
sys.path.insert(0, data_dir)
|
|
||||||
|
|
||||||
django.setup()
|
|
||||||
|
|
||||||
os.chdir(Path(for_runners_ynh.__file__).parent)
|
|
||||||
|
|
||||||
test_command = DjangoTestCommand()
|
test_command = DjangoTestCommand()
|
||||||
test_command.run_from_argv(sys.argv)
|
test_command.run_from_argv(argv)
|
||||||
|
if exit_after_run:
|
||||||
|
sys.exit(0)
|
||||||
|
|
||||||
|
|
||||||
@click.command() # Dummy command
|
@cli.command() # Dummy command
|
||||||
def test():
|
def test():
|
||||||
"""
|
"""
|
||||||
Compile YunoHost files and run Django unittests
|
Compile YunoHost files and run Django unittests
|
||||||
"""
|
"""
|
||||||
_run_django_test_cli()
|
_run_django_test_cli(argv=sys.argv, exit_after_run=True)
|
||||||
|
|
||||||
|
|
||||||
cli.add_command(test)
|
@cli.command() # Dummy command
|
||||||
|
def coverage():
|
||||||
|
"""
|
||||||
|
Run tests and show coverage report.
|
||||||
|
"""
|
||||||
|
run_coverage()
|
||||||
|
|
||||||
|
|
||||||
def _run_tox():
|
@cli.command() # Dummy "tox" command
|
||||||
verbose_check_call(sys.executable, '-m', 'tox', *sys.argv[2:])
|
|
||||||
sys.exit(0)
|
|
||||||
|
|
||||||
|
|
||||||
@click.command() # Dummy "tox" command
|
|
||||||
def tox():
|
def tox():
|
||||||
"""
|
"""
|
||||||
Run tox
|
Run tox
|
||||||
"""
|
"""
|
||||||
_run_tox()
|
run_tox()
|
||||||
|
|
||||||
|
|
||||||
cli.add_command(tox)
|
@cli.command()
|
||||||
|
|
||||||
|
|
||||||
@click.command()
|
|
||||||
def version():
|
def version():
|
||||||
"""Print version and exit"""
|
"""Print version and exit"""
|
||||||
# Pseudo command, because the version always printed on every CLI call ;)
|
# Pseudo command, because the version always printed on every CLI call ;)
|
||||||
sys.exit(0)
|
sys.exit(0)
|
||||||
|
|
||||||
|
|
||||||
cli.add_command(version)
|
@cli.command()
|
||||||
|
|
||||||
|
|
||||||
@click.command()
|
|
||||||
def local_test():
|
def local_test():
|
||||||
"""
|
"""
|
||||||
Build a "local_test" YunoHost installation and start the Django dev. server against it.
|
Build a "local_test" YunoHost installation and start the Django dev. server against it.
|
||||||
|
@ -317,10 +251,7 @@ def local_test():
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
cli.add_command(local_test)
|
@cli.command()
|
||||||
|
|
||||||
|
|
||||||
@click.command()
|
|
||||||
def diffsettings():
|
def diffsettings():
|
||||||
"""
|
"""
|
||||||
Run "diffsettings" manage command against a "local_test" YunoHost installation.
|
Run "diffsettings" manage command against a "local_test" YunoHost installation.
|
||||||
|
@ -343,22 +274,27 @@ def diffsettings():
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
cli.add_command(diffsettings)
|
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
print_version(for_runners_ynh)
|
print_version(for_runners_ynh)
|
||||||
|
|
||||||
print(f'{sys.argv=}')
|
|
||||||
if len(sys.argv) >= 2:
|
if len(sys.argv) >= 2:
|
||||||
# Check if we just pass a command call
|
# Check if we can just pass a command call to origin CLI:
|
||||||
command = sys.argv[1]
|
command = sys.argv[1]
|
||||||
if command == 'test':
|
command_map = {
|
||||||
_run_django_test_cli()
|
'test': _run_django_test_cli,
|
||||||
sys.exit(0)
|
'tox': run_tox,
|
||||||
elif command == 'tox':
|
'coverage': run_coverage,
|
||||||
_run_tox()
|
}
|
||||||
sys.exit(0)
|
if real_func := command_map.get(command):
|
||||||
|
real_func(argv=sys.argv, exit_after_run=True)
|
||||||
|
|
||||||
|
console = Console()
|
||||||
|
rich_traceback_install(
|
||||||
|
width=console.size.width, # full terminal width
|
||||||
|
show_locals=True,
|
||||||
|
suppress=[click],
|
||||||
|
max_frames=2,
|
||||||
|
)
|
||||||
|
|
||||||
print('Execute Click CLI')
|
print('Execute Click CLI')
|
||||||
cli()
|
cli()
|
||||||
|
|
11
for_runners_ynh/constants.py
Normal file
11
for_runners_ynh/constants.py
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
import for_runners_ynh
|
||||||
|
from bx_py_utils.path import assert_is_file
|
||||||
|
|
||||||
|
|
||||||
|
PACKAGE_ROOT = Path(for_runners_ynh.__file__).parent.parent
|
||||||
|
assert_is_file(PACKAGE_ROOT / 'pyproject.toml')
|
||||||
|
|
||||||
|
|
||||||
|
CLI_EPILOG = 'Project Homepage: https://github.com/YunoHost-Apps/django-for-runners_ynh'
|
|
@ -1,6 +1,63 @@
|
||||||
import os
|
import os
|
||||||
|
import sys
|
||||||
import unittest.util
|
import unittest.util
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
import django
|
||||||
|
import for_runners_ynh
|
||||||
|
from bx_py_utils.test_utils.deny_requests import deny_any_real_request
|
||||||
|
from cli_base.cli_tools.verbosity import MAX_LOG_LEVEL, setup_logging
|
||||||
|
from for_runners_ynh.constants import PACKAGE_ROOT
|
||||||
|
from django_yunohost_integration.local_test import CreateResults, create_local_test
|
||||||
|
from rich import print # noqa
|
||||||
|
|
||||||
|
|
||||||
# Hacky way to expand the failed test output:
|
def pre_configure_tests() -> None:
|
||||||
unittest.util._MAX_LENGTH = os.environ.get('UNITTEST_MAX_LENGTH', 300)
|
print(f'Configure unittests via "load_tests Protocol" from {Path(__file__).relative_to(Path.cwd())}')
|
||||||
|
|
||||||
|
# Hacky way to display more "assert"-Context in failing tests:
|
||||||
|
_MIN_MAX_DIFF = unittest.util._MAX_LENGTH - unittest.util._MIN_DIFF_LEN
|
||||||
|
unittest.util._MAX_LENGTH = int(os.environ.get('UNITTEST_MAX_LENGTH', 300))
|
||||||
|
unittest.util._MIN_DIFF_LEN = unittest.util._MAX_LENGTH - _MIN_MAX_DIFF
|
||||||
|
|
||||||
|
# Deny any request via docket/urllib3 because tests they should mock all requests:
|
||||||
|
deny_any_real_request()
|
||||||
|
|
||||||
|
# Display DEBUG logs in tests:
|
||||||
|
setup_logging(verbosity=MAX_LOG_LEVEL)
|
||||||
|
|
||||||
|
|
||||||
|
def setup_ynh_tests() -> None:
|
||||||
|
os.environ['DJANGO_SETTINGS_MODULE'] = 'settings'
|
||||||
|
|
||||||
|
print('Compile YunoHost files...')
|
||||||
|
result: CreateResults = create_local_test(
|
||||||
|
django_settings_path=PACKAGE_ROOT / 'conf' / 'settings.py',
|
||||||
|
destination=PACKAGE_ROOT / 'local_test',
|
||||||
|
runserver=False,
|
||||||
|
extra_replacements={
|
||||||
|
'__DEBUG_ENABLED__': '0', # "1" or "0" string
|
||||||
|
'__LOG_LEVEL__': 'INFO',
|
||||||
|
'__ADMIN_EMAIL__': 'foo-bar@test.tld',
|
||||||
|
'__DEFAULT_FROM_EMAIL__': 'django_app@test.tld',
|
||||||
|
},
|
||||||
|
)
|
||||||
|
print('Local test files created:')
|
||||||
|
print(result)
|
||||||
|
|
||||||
|
data_dir = str(result.data_dir_path)
|
||||||
|
if data_dir not in sys.path:
|
||||||
|
sys.path.insert(0, data_dir)
|
||||||
|
|
||||||
|
django.setup()
|
||||||
|
|
||||||
|
os.chdir(Path(for_runners_ynh.__file__).parent)
|
||||||
|
|
||||||
|
|
||||||
|
def load_tests(loader, tests, pattern):
|
||||||
|
"""
|
||||||
|
Use unittest "load_tests Protocol" as a hook to setup test environment before running tests.
|
||||||
|
https://docs.python.org/3/library/unittest.html#load-tests-protocol
|
||||||
|
"""
|
||||||
|
pre_configure_tests()
|
||||||
|
return loader.discover(start_dir=Path(__file__).parent, pattern=pattern)
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
import os
|
|
||||||
|
|
||||||
from for_runners_ynh.cli.dev import PACKAGE_ROOT
|
from for_runners_ynh.cli.dev import PACKAGE_ROOT
|
||||||
|
|
||||||
|
|
||||||
|
@ -12,9 +10,8 @@ from bx_django_utils.filename import clean_filename
|
||||||
from bx_py_utils.path import assert_is_dir, assert_is_file
|
from bx_py_utils.path import assert_is_dir, assert_is_file
|
||||||
from django.test.testcases import TestCase
|
from django.test.testcases import TestCase
|
||||||
from django_tools.unittest_utils.project_setup import check_editor_config
|
from django_tools.unittest_utils.project_setup import check_editor_config
|
||||||
from django_yunohost_integration.test_utils import assert_project_version
|
|
||||||
|
|
||||||
from for_runners import __version__ as upstream_version
|
from for_runners import __version__ as upstream_version
|
||||||
|
|
||||||
from for_runners_ynh import __version__ as ynh_pkg_version
|
from for_runners_ynh import __version__ as ynh_pkg_version
|
||||||
|
|
||||||
|
|
||||||
|
@ -47,13 +44,6 @@ class ProjectSetupTestCase(TestCase):
|
||||||
manifest_version = ynh_pkg_version.replace('+', '~')
|
manifest_version = ynh_pkg_version.replace('+', '~')
|
||||||
self.assertEqual(self.manifest_cfg['version'], manifest_version)
|
self.assertEqual(self.manifest_cfg['version'], manifest_version)
|
||||||
|
|
||||||
if 'GITHUB_ACTION' not in os.environ:
|
|
||||||
# Github has a rate-limiting... So don't fetch the API if we run as GitHub action
|
|
||||||
assert_project_version(
|
|
||||||
current_version=ynh_pkg_version,
|
|
||||||
github_project_url='https://github.com/jedie/django-for-runners',
|
|
||||||
)
|
|
||||||
|
|
||||||
def test_screenshot_filenames(self):
|
def test_screenshot_filenames(self):
|
||||||
"""
|
"""
|
||||||
https://forum.yunohost.org/t/yunohost-bot-cant-handle-spaces-in-screenshots/19483
|
https://forum.yunohost.org/t/yunohost-bot-cant-handle-spaces-in-screenshots/19483
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
from bx_py_utils.auto_doc import assert_readme_block
|
from bx_py_utils.auto_doc import assert_readme_block
|
||||||
|
from for_runners_ynh.cli.dev import PACKAGE_ROOT, cli
|
||||||
|
from for_runners_ynh.constants import CLI_EPILOG
|
||||||
from manageprojects.test_utils.click_cli_utils import invoke_click
|
from manageprojects.test_utils.click_cli_utils import invoke_click
|
||||||
from manageprojects.tests.base import BaseTestCase
|
from manageprojects.tests.base import BaseTestCase
|
||||||
|
|
||||||
from for_runners_ynh.cli.dev import CLI_EPILOG, PACKAGE_ROOT, cli
|
|
||||||
|
|
||||||
|
|
||||||
def assert_cli_help_in_readme(text_block: str, marker: str, readme_path: Path):
|
def assert_cli_help_in_readme(text_block: str, marker: str, readme_path: Path):
|
||||||
text_block = text_block.replace(CLI_EPILOG, '')
|
text_block = text_block.replace(CLI_EPILOG, '')
|
||||||
|
|
25
local_settings_source.py
Normal file
25
local_settings_source.py
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
# This file will be copied to the "local test" files, to overwrite Django settings
|
||||||
|
|
||||||
|
import os
|
||||||
|
|
||||||
|
|
||||||
|
print('Load local settings file:', __file__)
|
||||||
|
|
||||||
|
ENV_TYPE = os.environ.get('ENV_TYPE', None)
|
||||||
|
print(f'ENV_TYPE: {ENV_TYPE!r}')
|
||||||
|
|
||||||
|
if ENV_TYPE == 'local':
|
||||||
|
print(f'Activate settings overwrite by {__file__}')
|
||||||
|
SECURE_SSL_REDIRECT = False # Don't redirect http to https
|
||||||
|
SERVE_FILES = True # May used in urls.py
|
||||||
|
AUTH_PASSWORD_VALIDATORS = [] # accept all passwords
|
||||||
|
ALLOWED_HOSTS = ['127.0.0.1', 'localhost'] # For local dev. server
|
||||||
|
CACHES = { # Setup a working cache, without Redis ;)
|
||||||
|
'default': {
|
||||||
|
'BACKEND': 'django.core.cache.backends.locmem.LocMemCache',
|
||||||
|
'LOCATION': 'unique-snowflake',
|
||||||
|
},
|
||||||
|
}
|
||||||
|
elif ENV_TYPE == 'test':
|
||||||
|
SILENCED_SYSTEM_CHECKS = ['security.W018'] # tests runs with DEBUG=True
|
||||||
|
ALLOWED_HOSTS = [] # For unittests (Django's setup_test_environment() will add 'testserver')
|
|
@ -5,7 +5,7 @@ id = "django-for-runners"
|
||||||
name = "django-for-runners"
|
name = "django-for-runners"
|
||||||
description.en = "YunoHost app package for https://github.com/jedie/django-for-runners"
|
description.en = "YunoHost app package for https://github.com/jedie/django-for-runners"
|
||||||
|
|
||||||
version = "0.17.4~ynh1"
|
version = "0.18.1~ynh1"
|
||||||
|
|
||||||
maintainers = ["Jens Diemer"]
|
maintainers = ["Jens Diemer"]
|
||||||
|
|
||||||
|
@ -19,7 +19,7 @@ code = "https://github.com/jedie/django-for-runners"
|
||||||
|
|
||||||
[integration]
|
[integration]
|
||||||
# https://yunohost.org/en/packaging_manifest#integration-section
|
# https://yunohost.org/en/packaging_manifest#integration-section
|
||||||
yunohost = ">=11.2.12"
|
yunohost = ">=11.2"
|
||||||
architectures = "all"
|
architectures = "all"
|
||||||
multi_instance = true
|
multi_instance = true
|
||||||
ldap = true
|
ldap = true
|
||||||
|
@ -100,7 +100,7 @@ ram.runtime = "50M" # **estimate** minimum ram requirement. e.g. 50M, 400M, 1G,
|
||||||
[resources.apt]
|
[resources.apt]
|
||||||
# https://yunohost.org/en/packaging_apps_resources#apt
|
# https://yunohost.org/en/packaging_apps_resources#apt
|
||||||
# This will automatically install/uninstall the following apt packages
|
# This will automatically install/uninstall the following apt packages
|
||||||
packages = "build-essential, python3-dev, python3-pip, python3-venv, git, libpq-dev, postgresql, postgresql-contrib, redis-server"
|
packages = "build-essential, python3-dev, python3-pip, python3-venv, git, libpq-dev, postgresql, postgresql-contrib, redis-server, checkinstall, libssl-dev, openssl"
|
||||||
|
|
||||||
[resources.database]
|
[resources.database]
|
||||||
# https://yunohost.org/en/packaging_apps_resources#database
|
# https://yunohost.org/en/packaging_apps_resources#database
|
||||||
|
|
|
@ -9,7 +9,7 @@ authors = [
|
||||||
]
|
]
|
||||||
requires-python = ">=3.9" # Stay with 3.9 until YunoHost used >=Debian 11 (Bullseye)
|
requires-python = ">=3.9" # Stay with 3.9 until YunoHost used >=Debian 11 (Bullseye)
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"django_for_runners", # https://github.com/jedie/django-for-runners
|
"django_for_runners>=0.18.1", # https://github.com/jedie/django-for-runners
|
||||||
#
|
#
|
||||||
# extras "ynh" will install: gunicorn, psycopg2, django-redis and django-axes
|
# extras "ynh" will install: gunicorn, psycopg2, django-redis and django-axes
|
||||||
# see: https://github.com/YunoHost-Apps/django_yunohost_integration/blob/main/pyproject.toml
|
# see: https://github.com/YunoHost-Apps/django_yunohost_integration/blob/main/pyproject.toml
|
||||||
|
@ -25,7 +25,7 @@ dependencies = [
|
||||||
dev = [
|
dev = [
|
||||||
"bx_django_utils", # https://github.com/boxine/bx_django_utils
|
"bx_django_utils", # https://github.com/boxine/bx_django_utils
|
||||||
"beautifulsoup4", # https://pypi.org/project/beautifulsoup4/
|
"beautifulsoup4", # https://pypi.org/project/beautifulsoup4/
|
||||||
"manageprojects>=0.15.0", # https://github.com/jedie/manageprojects
|
"manageprojects", # https://github.com/jedie/manageprojects
|
||||||
"pip-tools", # https://github.com/jazzband/pip-tools/
|
"pip-tools", # https://github.com/jazzband/pip-tools/
|
||||||
"tblib", # https://github.com/ionelmc/python-tblib
|
"tblib", # https://github.com/ionelmc/python-tblib
|
||||||
"tox", # https://github.com/tox-dev/tox
|
"tox", # https://github.com/tox-dev/tox
|
||||||
|
@ -36,7 +36,7 @@ dev = [
|
||||||
"pyflakes", # https://github.com/PyCQA/pyflakes
|
"pyflakes", # https://github.com/PyCQA/pyflakes
|
||||||
"codespell", # https://github.com/codespell-project/codespell
|
"codespell", # https://github.com/codespell-project/codespell
|
||||||
"EditorConfig", # https://github.com/editorconfig/editorconfig-core-py
|
"EditorConfig", # https://github.com/editorconfig/editorconfig-core-py
|
||||||
"safety", # https://github.com/pyupio/safety
|
"pip-audit", # https://github.com/pypa/pip-audit
|
||||||
"mypy", # https://github.com/python/mypy
|
"mypy", # https://github.com/python/mypy
|
||||||
"twine", # https://github.com/pypa/twine
|
"twine", # https://github.com/pypa/twine
|
||||||
|
|
||||||
|
@ -61,6 +61,9 @@ Source = "https://github.com/YunoHost-Apps/django-for-runners_ynh"
|
||||||
for_runners_ynh_app = "for_runners_ynh.__main__:main"
|
for_runners_ynh_app = "for_runners_ynh.__main__:main"
|
||||||
for_runners_ynh_dev = "for_runners_ynh.cli.dev:main"
|
for_runners_ynh_dev = "for_runners_ynh.cli.dev:main"
|
||||||
|
|
||||||
|
[ynh-integration]
|
||||||
|
local_settings_source= "local_settings_source.py"
|
||||||
|
|
||||||
[build-system]
|
[build-system]
|
||||||
requires = ["setuptools>=61.0", "setuptools_scm>=7.1"]
|
requires = ["setuptools>=61.0", "setuptools_scm>=7.1"]
|
||||||
build-backend = "setuptools.build_meta"
|
build-backend = "setuptools.build_meta"
|
||||||
|
@ -73,6 +76,14 @@ include = ["for_runners_ynh*"]
|
||||||
version = {attr = "for_runners_ynh.__version__"}
|
version = {attr = "for_runners_ynh.__version__"}
|
||||||
|
|
||||||
|
|
||||||
|
[tool.cli_base.pip_audit]
|
||||||
|
# https://github.com/jedie/cli-base-utilities/blob/main/docs/pip_audit.md
|
||||||
|
requirements=["requirements.dev.txt"]
|
||||||
|
strict=true
|
||||||
|
require_hashes=true
|
||||||
|
ignore-vuln=[]
|
||||||
|
|
||||||
|
|
||||||
[tool.darker]
|
[tool.darker]
|
||||||
src = ['.']
|
src = ['.']
|
||||||
# YunoHost apps still use "master" istead of "main", isn't it?
|
# YunoHost apps still use "master" istead of "main", isn't it?
|
||||||
|
@ -127,7 +138,7 @@ exclude_lines = [
|
||||||
legacy_tox_ini = """
|
legacy_tox_ini = """
|
||||||
[tox]
|
[tox]
|
||||||
isolated_build = True
|
isolated_build = True
|
||||||
envlist = py{312,311,310,39}
|
envlist = py{312,311,310}
|
||||||
skip_missing_interpreters = True
|
skip_missing_interpreters = True
|
||||||
|
|
||||||
[testenv]
|
[testenv]
|
||||||
|
@ -163,6 +174,7 @@ applied_migrations = [
|
||||||
"3383cb0", # 2023-11-09T20:14:05+01:00
|
"3383cb0", # 2023-11-09T20:14:05+01:00
|
||||||
"4abd4c0", # 2023-11-25T15:59:31+01:00
|
"4abd4c0", # 2023-11-25T15:59:31+01:00
|
||||||
"2f9fd7b", # 2023-11-26T20:13:32+01:00
|
"2f9fd7b", # 2023-11-26T20:13:32+01:00
|
||||||
|
"52669d0", # 2024-08-02T15:47:04+02:00
|
||||||
]
|
]
|
||||||
|
|
||||||
[manageprojects.cookiecutter_context.cookiecutter]
|
[manageprojects.cookiecutter_context.cookiecutter]
|
||||||
|
|
1905
requirements.dev.txt
1905
requirements.dev.txt
File diff suppressed because it is too large
Load diff
|
@ -38,12 +38,107 @@ log_file="${log_path}/${app}.log"
|
||||||
# HELPERS
|
# HELPERS
|
||||||
#=================================================
|
#=================================================
|
||||||
|
|
||||||
|
|
||||||
|
#==================================================================================
|
||||||
|
# myynh_install_python() Borrowed from:
|
||||||
|
# https://github.com/YunoHost-Apps/homeassistant_ynh/blob/master/scripts/_common.sh
|
||||||
|
# Until we get a newer Python in YunoHost, see:
|
||||||
|
# https://forum.yunohost.org/t/use-newer-python-than-3-9/22568
|
||||||
|
#==================================================================================
|
||||||
|
py_required_major=3.11
|
||||||
|
py_required_version=$(curl -Ls https://www.python.org/ftp/python/ \
|
||||||
|
| grep '>'$py_required_major | cut -d '/' -f 2 \
|
||||||
|
| cut -d '>' -f 2 | sort -rV | head -n 1) #3.11.8
|
||||||
|
|
||||||
|
myynh_install_python() {
|
||||||
|
# Declare an array to define the options of this helper.
|
||||||
|
local legacy_args=u
|
||||||
|
local -A args_array=( [p]=python= )
|
||||||
|
local python
|
||||||
|
# Manage arguments with getopts
|
||||||
|
ynh_handle_getopts_args "$@"
|
||||||
|
|
||||||
|
# Check python version from APT
|
||||||
|
local py_apt_version=$(python3 --version | cut -d ' ' -f 2)
|
||||||
|
|
||||||
|
# Usefull variables
|
||||||
|
local python_major=${python%.*}
|
||||||
|
|
||||||
|
# Check existing built version of python in /usr/local/bin
|
||||||
|
if [ -e "/usr/local/bin/python$python_major" ]
|
||||||
|
then
|
||||||
|
local py_built_version=$(/usr/local/bin/python$python_major --version \
|
||||||
|
| cut -d ' ' -f 2)
|
||||||
|
else
|
||||||
|
local py_built_version=0
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Compare version
|
||||||
|
if $(dpkg --compare-versions $py_apt_version ge $python)
|
||||||
|
then
|
||||||
|
# APT >= Required
|
||||||
|
ynh_print_info --message="Using provided python3..."
|
||||||
|
|
||||||
|
py_app_version="python3"
|
||||||
|
|
||||||
|
else
|
||||||
|
# Either python already built or to build
|
||||||
|
if $(dpkg --compare-versions $py_built_version ge $python)
|
||||||
|
then
|
||||||
|
# Built >= Required
|
||||||
|
ynh_print_info --message="Using already used python3 built version..."
|
||||||
|
|
||||||
|
py_app_version="/usr/local/bin/python${py_built_version%.*}"
|
||||||
|
|
||||||
|
else
|
||||||
|
# APT < Minimal & Actual < Minimal => Build & install Python into /usr/local/bin
|
||||||
|
ynh_print_info --message="Building python (may take a while)..."
|
||||||
|
|
||||||
|
# Store current direcotry
|
||||||
|
local MY_DIR=$(pwd)
|
||||||
|
|
||||||
|
# Create a temp direcotry
|
||||||
|
tmpdir="$(mktemp --directory)"
|
||||||
|
cd "$tmpdir"
|
||||||
|
|
||||||
|
# Download
|
||||||
|
wget --output-document="Python-$python.tar.xz" \
|
||||||
|
"https://www.python.org/ftp/python/$python/Python-$python.tar.xz" 2>&1
|
||||||
|
|
||||||
|
# Extract
|
||||||
|
tar xf "Python-$python.tar.xz"
|
||||||
|
|
||||||
|
# Install
|
||||||
|
cd "Python-$python"
|
||||||
|
./configure --enable-optimizations
|
||||||
|
ynh_exec_warn_less make -j4
|
||||||
|
ynh_exec_warn_less make altinstall
|
||||||
|
|
||||||
|
# Go back to working directory
|
||||||
|
cd "$MY_DIR"
|
||||||
|
|
||||||
|
# Clean
|
||||||
|
ynh_secure_remove "$tmpdir"
|
||||||
|
|
||||||
|
# Set version
|
||||||
|
py_app_version="/usr/local/bin/python$python_major"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
# Save python version in settings
|
||||||
|
ynh_app_setting_set --app=$app --key=python --value="$python"
|
||||||
|
}
|
||||||
|
#==================================================================================
|
||||||
|
#==================================================================================
|
||||||
|
|
||||||
myynh_setup_python_venv() {
|
myynh_setup_python_venv() {
|
||||||
# Always recreate everything fresh with current python version
|
# Always recreate everything fresh with current python version
|
||||||
ynh_secure_remove "$data_dir/venv"
|
ynh_secure_remove "$data_dir/venv"
|
||||||
|
|
||||||
|
myynh_install_python --python="$py_required_version"
|
||||||
|
|
||||||
|
# Create a virtualenv with python installed by myynh_install_python():
|
||||||
# Skip pip because of: https://github.com/YunoHost/issues/issues/1960
|
# Skip pip because of: https://github.com/YunoHost/issues/issues/1960
|
||||||
python3 -m venv --without-pip "$data_dir/venv"
|
$py_app_version -m venv --without-pip "$data_dir/venv"
|
||||||
|
|
||||||
chown -c -R "$app:" "$data_dir"
|
chown -c -R "$app:" "$data_dir"
|
||||||
|
|
||||||
|
|
|
@ -101,6 +101,9 @@ cd "$data_dir" || exit
|
||||||
./manage.py migrate --no-input
|
./manage.py migrate --no-input
|
||||||
./manage.py collectstatic --no-input
|
./manage.py collectstatic --no-input
|
||||||
|
|
||||||
|
# Call special Django-For-Runner manage command:
|
||||||
|
./manage.py fill_basedata
|
||||||
|
|
||||||
# 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="$(ynh_user_get_info "$admin" mail)"
|
./manage.py create_superuser --username="$admin" --email="$(ynh_user_get_info "$admin" mail)"
|
||||||
|
|
||||||
|
@ -113,7 +116,7 @@ cd "$data_dir" || exit
|
||||||
#=================================================
|
#=================================================
|
||||||
ynh_script_progression --message="Integrating service in YunoHost..."
|
ynh_script_progression --message="Integrating service in YunoHost..."
|
||||||
|
|
||||||
yunohost service add $app
|
yunohost service add --description $app $app
|
||||||
|
|
||||||
#=================================================
|
#=================================================
|
||||||
# GENERIC FINALIZATION
|
# GENERIC FINALIZATION
|
||||||
|
|
|
@ -57,7 +57,7 @@ systemctl enable $app.service --quiet
|
||||||
#=================================================
|
#=================================================
|
||||||
ynh_script_progression --message="Integrating service in YunoHost..."
|
ynh_script_progression --message="Integrating service in YunoHost..."
|
||||||
|
|
||||||
yunohost service add $app
|
yunohost service add --description $app $app
|
||||||
|
|
||||||
#=================================================
|
#=================================================
|
||||||
# RESTORE THE LOGROTATE CONFIGURATION
|
# RESTORE THE LOGROTATE CONFIGURATION
|
||||||
|
|
|
@ -111,7 +111,7 @@ myynh_fix_file_permissions
|
||||||
#=================================================
|
#=================================================
|
||||||
ynh_script_progression --message="Starting systemd service '$app'..." --weight=5
|
ynh_script_progression --message="Starting systemd service '$app'..." --weight=5
|
||||||
|
|
||||||
yunohost service add $app
|
yunohost service add --description $app $app
|
||||||
ynh_systemd_action --service_name=$app --action="start" --log_path="$log_file"
|
ynh_systemd_action --service_name=$app --action="start" --log_path="$log_file"
|
||||||
|
|
||||||
#=================================================
|
#=================================================
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
<h1 id="site-name">
|
<h1 id="site-name">
|
||||||
<a href="/app_path/">
|
<a href="/app_path/">
|
||||||
<img alt="Logo" height="40px" src="/app_path/static/Django-ForRunners.svg"/>
|
<img alt="Logo" height="40px" src="/app_path/static/Django-ForRunners.svg"/>
|
||||||
Django-ForRunners v0.17.4
|
Django-ForRunners v0.18.1
|
||||||
</a>
|
</a>
|
||||||
</h1>
|
</h1>
|
||||||
</div>
|
</div>
|
||||||
|
@ -87,4 +87,4 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
Loading…
Reference in a new issue