1
0
Fork 0
mirror of https://github.com/YunoHost-Apps/pyinventory_ynh.git synced 2024-09-03 20:16:09 +02:00

Update project -> migrate from poetry to pip-tools

This commit is contained in:
Jens Diemer 2023-11-01 20:19:13 +01:00
parent b378a519a6
commit 83c98f55f4
19 changed files with 2277 additions and 2709 deletions

View file

@ -1,69 +0,0 @@
name: pytest
on:
# Allow to manually trigger the workflow
workflow_dispatch:
push:
branches:
- master
pull_request:
schedule:
- cron: '0 8 * * *'
jobs:
test:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ["3.11", "3.10", "3.9"]
env:
PYTHONUNBUFFERED: 1
PYTHONWARNINGS: always
steps:
- uses: actions/checkout@v3
# https://github.com/marketplace/actions/checkout
with:
fetch-depth: 0
- name: 'fetch master and testing (for Darker/Black)'
run: |
git fetch origin master
git fetch origin testing
- name: 'Set up Python ${{ matrix.python-version }}'
uses: actions/setup-python@v2
with:
python-version: '${{ matrix.python-version }}'
- uses: actions/cache@v3
# https://github.com/marketplace/actions/cache
with:
path: ~/.cache/
key: dot-cache-files
- name: 'Install package'
run: |
pip3 install poetry
make install
- name: 'List installed packages'
run: |
poetry run pip freeze
- name: 'Run tests with Python v${{ matrix.python-version }}'
run: |
make pytest
- name: 'Run Safety check'
run: |
make safety
- name: 'Upload coverage report'
uses: codecov/codecov-action@v3
# https://github.com/marketplace/actions/codecov
with:
fail_ci_if_error: false
verbose: true

66
.github/workflows/tests.yml vendored Normal file
View file

@ -0,0 +1,66 @@
name: tests
on:
push:
branches:
- main
pull_request:
schedule:
- cron: '0 8 * * *'
jobs:
test:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
python-version: ["3.12", "3.11", "3.10", "3.9"]
env:
PYTHONUNBUFFERED: 1
PYTHONWARNINGS: always
steps:
- name: Checkout
run: |
echo $GITHUB_REF $GITHUB_SHA
git clone https://github.com/$GITHUB_REPOSITORY.git .
git fetch origin $GITHUB_SHA:temporary-ci-branch
git checkout $GITHUB_SHA || (git fetch && git checkout $GITHUB_SHA)
- name: 'fetch master'
run: |
git fetch origin master
- name: 'Set up Python ${{ matrix.python-version }}'
uses: actions/setup-python@v4
# https://github.com/marketplace/actions/setup-python
with:
python-version: '${{ matrix.python-version }}'
cache: 'pip' # caching pip dependencies
cache-dependency-path: '**/requirements.dev.txt'
- name: 'Bootstrap dev venv'
# The first CLI call will create the .venv
run: |
./dev-cli.py version
- name: 'dev CLI help'
run: |
./dev-cli.py --help
- name: 'Safety'
run: |
./dev-cli.py safety
- name: 'Run tests with Python v${{ matrix.python-version }}'
run: |
.venv/bin/coverage erase
./dev-cli.py coverage
- name: 'Upload coverage report'
uses: codecov/codecov-action@v3
# https://github.com/marketplace/actions/codecov
with:
fail_ci_if_error: false
verbose: true

11
.gitignore vendored
View file

@ -1,4 +1,11 @@
.* .*
*.egg-info
__pycache__
/dist/
/coverage.*
/htmlcov/
*.orig
!.github !.github
!.editorconfig !.editorconfig
!.flake8 !.flake8
@ -6,9 +13,5 @@
!.gitkeep !.gitkeep
!/doc/screenshots/.gitkeep !/doc/screenshots/.gitkeep
__pycache__
secret.txt secret.txt
/local_test/ /local_test/
/coverage.*
/htmlcov/

View file

@ -1,65 +0,0 @@
SHELL := /bin/bash
MAX_LINE_LENGTH := 100
all: help
help:
@awk 'BEGIN {FS = ":.*?## "} /^[a-zA-Z0-9 -]+:.*?## / {printf "\033[36m%-22s\033[0m %s\n", $$1, $$2}' $(MAKEFILE_LIST)
check-poetry:
@if [[ "$(shell poetry --version 2>/dev/null)" == *"Poetry"* ]] ; \
then \
echo "Poetry found, ok." ; \
else \
echo 'Please install poetry first, with e.g.:' ; \
echo 'make install-poetry' ; \
exit 1 ; \
fi
install-base-req: ## Install needed base packages via apt
sudo apt install python3-pip python3-venv
install-poetry: ## install or update poetry
curl -sSL https://install.python-poetry.org | python3 -
install: check-poetry ## install project via poetry
python3 -m venv .venv
poetry install
update: check-poetry ## update the sources and installation and generate "conf/requirements.txt"
python3 -m venv .venv
poetry self update
poetry update -v
poetry install
poetry export -f requirements.txt --output conf/requirements.txt
lint: ## Run code formatters and linter
poetry run darker --check
poetry run isort --check-only .
poetry run flake8 .
fix-code-style: ## Fix code formatting
poetry run darker
poetry run isort .
tox-listenvs: check-poetry ## List all tox test environments
poetry run tox --listenvs
tox: check-poetry ## Run pytest via tox with all environments
poetry run tox
pytest: install ## Run pytest
poetry run pytest
local-test: install ## Run local_test.py to run the project locally
poetry run python3 ./local_test.py
local-diff-settings: ## Run "manage.py diffsettings" with local test
poetry run python3 local_test/opt_yunohost/manage.py diffsettings
safety: ## Run https://github.com/pyupio/safety
poetry run safety check --full-report
##############################################################################
.PHONY: help check-poetry install-poetry install update local-test

View file

@ -1,256 +1,367 @@
asgiref==3.7.2 ; python_version >= "3.9" and python_version < "4" \ #
# This file is autogenerated by pip-compile with Python 3.11
# by the following command:
#
# ./dev-cli.py update
#
asgiref==3.7.2 \
--hash=sha256:89b2ef2247e3b562a16eef663bc0e2e703ec6468e2fa8a5cd61cd449786d4f6e \ --hash=sha256:89b2ef2247e3b562a16eef663bc0e2e703ec6468e2fa8a5cd61cd449786d4f6e \
--hash=sha256:9e0ce3aa93a819ba5b45120216b23878cf6e8525eb3848653452b4192b92afed --hash=sha256:9e0ce3aa93a819ba5b45120216b23878cf6e8525eb3848653452b4192b92afed
async-timeout==4.0.3 ; python_version >= "3.9" and python_full_version <= "3.11.2" \ # via django
async-timeout==4.0.3 \
--hash=sha256:4640d96be84d82d02ed59ea2b7105a0f7b33abe8703703cd0ab0bf87c427522f \ --hash=sha256:4640d96be84d82d02ed59ea2b7105a0f7b33abe8703703cd0ab0bf87c427522f \
--hash=sha256:7405140ff1230c310e51dc27b3145b9092d659ce68ff733fb0cefe3ee42be028 --hash=sha256:7405140ff1230c310e51dc27b3145b9092d659ce68ff733fb0cefe3ee42be028
bleach==6.0.0 ; python_version >= "3.9" and python_version < "4" \ # via pyinventory-ynh (pyproject.toml)
--hash=sha256:1a1a85c1595e07d8db14c5f09f09e6433502c51c595970edc090551f0db99414 \ bleach==6.1.0 \
--hash=sha256:33c16e3353dbd13028ab4799a0f89a83f113405c766e9c122df8a06f5b85b3f4 --hash=sha256:0a31f1837963c41d46bbf1331b8778e1308ea0791db03cc4e7357b97cf42a8fe \
bx-django-utils==64 ; python_version >= "3.9" and python_version < "4" \ --hash=sha256:3225f354cfc436b9789c66c4ee030194bee0568fbf9cbdad3bc8b5c26c5f12b6
--hash=sha256:55e920caf2f1fda4f5b199d48558d1e8a8f2408a244833be205e6c4083610906 \ # via django-tools
--hash=sha256:a89c5b6dd13e8ee28b13c315dce28ff5ad0e6637281ef16754cecf32537b5b4f bx-django-utils==66 \
bx-py-utils==85 ; python_version >= "3.9" and python_version < "4" \ --hash=sha256:99a5454284841d7059160d2f03c9c062d8def6c4936bf9a4ffa1fd728dbda08c \
--hash=sha256:8d6ee4bb0c431304b812f5bebb1bc8e2ab05f1b6c2f8d16d352cbcee5e916cd2 \ --hash=sha256:a56f45644dc8f1cfd793bb5c939fcad1b483afbd04192b810f933b10058cd4cc
--hash=sha256:df023fa05cda8e969d2cbdb4cc348d8b7670567a2fe775faf7a0c869ec56eaa2 # via pyinventory
certifi==2023.7.22 ; python_version >= "3.9" and python_version < "4" \ bx-py-utils==88 \
--hash=sha256:32fbc7e9ff3dfb0a817c80fb1d165ec559643dab59c0be549e646acbf8223b75 \
--hash=sha256:3a6f4eeef6abcac834b2c1ea4c5211130fd930a064aa0baabddd7c2bd00e38ac
# via
# bx-django-utils
# cli-base-utilities
# django-tools
# pyinventory
certifi==2023.7.22 \
--hash=sha256:539cc1d13202e33ca466e88b2807e29f4c13049d6d87031a3c110744495cb082 \ --hash=sha256:539cc1d13202e33ca466e88b2807e29f4c13049d6d87031a3c110744495cb082 \
--hash=sha256:92d6037539857d8206b8f6ae472e8b77db8058fec5937a1ef3f54304089edbb9 --hash=sha256:92d6037539857d8206b8f6ae472e8b77db8058fec5937a1ef3f54304089edbb9
charset-normalizer==3.2.0 ; python_version >= "3.9" and python_version < "4" \ # via requests
--hash=sha256:04e57ab9fbf9607b77f7d057974694b4f6b142da9ed4a199859d9d4d5c63fe96 \ charset-normalizer==3.3.2 \
--hash=sha256:09393e1b2a9461950b1c9a45d5fd251dc7c6f228acab64da1c9c0165d9c7765c \ --hash=sha256:06435b539f889b1f6f4ac1758871aae42dc3a8c0e24ac9e60c2384973ad73027 \
--hash=sha256:0b87549028f680ca955556e3bd57013ab47474c3124dc069faa0b6545b6c9710 \ --hash=sha256:06a81e93cd441c56a9b65d8e1d043daeb97a3d0856d177d5c90ba85acb3db087 \
--hash=sha256:1000fba1057b92a65daec275aec30586c3de2401ccdcd41f8a5c1e2c87078706 \ --hash=sha256:0a55554a2fa0d408816b3b5cedf0045f4b8e1a6065aec45849de2d6f3f8e9786 \
--hash=sha256:1249cbbf3d3b04902ff081ffbb33ce3377fa6e4c7356f759f3cd076cc138d020 \ --hash=sha256:0b2b64d2bb6d3fb9112bafa732def486049e63de9618b5843bcdd081d8144cd8 \
--hash=sha256:1920d4ff15ce893210c1f0c0e9d19bfbecb7983c76b33f046c13a8ffbd570252 \ --hash=sha256:10955842570876604d404661fbccbc9c7e684caf432c09c715ec38fbae45ae09 \
--hash=sha256:193cbc708ea3aca45e7221ae58f0fd63f933753a9bfb498a3b474878f12caaad \ --hash=sha256:122c7fa62b130ed55f8f285bfd56d5f4b4a5b503609d181f9ad85e55c89f4185 \
--hash=sha256:1a100c6d595a7f316f1b6f01d20815d916e75ff98c27a01ae817439ea7726329 \ --hash=sha256:1ceae2f17a9c33cb48e3263960dc5fc8005351ee19db217e9b1bb15d28c02574 \
--hash=sha256:1f30b48dd7fa1474554b0b0f3fdfdd4c13b5c737a3c6284d3cdc424ec0ffff3a \ --hash=sha256:1d3193f4a680c64b4b6a9115943538edb896edc190f0b222e73761716519268e \
--hash=sha256:203f0c8871d5a7987be20c72442488a0b8cfd0f43b7973771640fc593f56321f \ --hash=sha256:1f79682fbe303db92bc2b1136016a38a42e835d932bab5b3b1bfcfbf0640e519 \
--hash=sha256:246de67b99b6851627d945db38147d1b209a899311b1305dd84916f2b88526c6 \ --hash=sha256:2127566c664442652f024c837091890cb1942c30937add288223dc895793f898 \
--hash=sha256:2dee8e57f052ef5353cf608e0b4c871aee320dd1b87d351c28764fc0ca55f9f4 \ --hash=sha256:22afcb9f253dac0696b5a4be4a1c0f8762f8239e21b99680099abd9b2b1b2269 \
--hash=sha256:2efb1bd13885392adfda4614c33d3b68dee4921fd0ac1d3988f8cbb7d589e72a \ --hash=sha256:25baf083bf6f6b341f4121c2f3c548875ee6f5339300e08be3f2b2ba1721cdd3 \
--hash=sha256:2f4ac36d8e2b4cc1aa71df3dd84ff8efbe3bfb97ac41242fbcfc053c67434f46 \ --hash=sha256:2e81c7b9c8979ce92ed306c249d46894776a909505d8f5a4ba55b14206e3222f \
--hash=sha256:3170c9399da12c9dc66366e9d14da8bf7147e1e9d9ea566067bbce7bb74bd9c2 \ --hash=sha256:3287761bc4ee9e33561a7e058c72ac0938c4f57fe49a09eae428fd88aafe7bb6 \
--hash=sha256:3b1613dd5aee995ec6d4c69f00378bbd07614702a315a2cf6c1d21461fe17c23 \ --hash=sha256:34d1c8da1e78d2e001f363791c98a272bb734000fcef47a491c1e3b0505657a8 \
--hash=sha256:3bb3d25a8e6c0aedd251753a79ae98a093c7e7b471faa3aa9a93a81431987ace \ --hash=sha256:37e55c8e51c236f95b033f6fb391d7d7970ba5fe7ff453dad675e88cf303377a \
--hash=sha256:3bb7fda7260735efe66d5107fb7e6af6a7c04c7fce9b2514e04b7a74b06bf5dd \ --hash=sha256:3d47fa203a7bd9c5b6cee4736ee84ca03b8ef23193c0d1ca99b5089f72645c73 \
--hash=sha256:41b25eaa7d15909cf3ac4c96088c1f266a9a93ec44f87f1d13d4a0e86c81b982 \ --hash=sha256:3e4d1f6587322d2788836a99c69062fbb091331ec940e02d12d179c1d53e25fc \
--hash=sha256:45de3f87179c1823e6d9e32156fb14c1927fcc9aba21433f088fdfb555b77c10 \ --hash=sha256:42cb296636fcc8b0644486d15c12376cb9fa75443e00fb25de0b8602e64c1714 \
--hash=sha256:46fb8c61d794b78ec7134a715a3e564aafc8f6b5e338417cb19fe9f57a5a9bf2 \ --hash=sha256:45485e01ff4d3630ec0d9617310448a8702f70e9c01906b0d0118bdf9d124cf2 \
--hash=sha256:48021783bdf96e3d6de03a6e39a1171ed5bd7e8bb93fc84cc649d11490f87cea \ --hash=sha256:4a78b2b446bd7c934f5dcedc588903fb2f5eec172f3d29e52a9096a43722adfc \
--hash=sha256:4957669ef390f0e6719db3613ab3a7631e68424604a7b448f079bee145da6e09 \ --hash=sha256:4ab2fe47fae9e0f9dee8c04187ce5d09f48eabe611be8259444906793ab7cbce \
--hash=sha256:5e86d77b090dbddbe78867a0275cb4df08ea195e660f1f7f13435a4649e954e5 \ --hash=sha256:4d0d1650369165a14e14e1e47b372cfcb31d6ab44e6e33cb2d4e57265290044d \
--hash=sha256:6339d047dab2780cc6220f46306628e04d9750f02f983ddb37439ca47ced7149 \ --hash=sha256:549a3a73da901d5bc3ce8d24e0600d1fa85524c10287f6004fbab87672bf3e1e \
--hash=sha256:681eb3d7e02e3c3655d1b16059fbfb605ac464c834a0c629048a30fad2b27489 \ --hash=sha256:55086ee1064215781fff39a1af09518bc9255b50d6333f2e4c74ca09fac6a8f6 \
--hash=sha256:6c409c0deba34f147f77efaa67b8e4bb83d2f11c8806405f76397ae5b8c0d1c9 \ --hash=sha256:572c3763a264ba47b3cf708a44ce965d98555f618ca42c926a9c1616d8f34269 \
--hash=sha256:7095f6fbfaa55defb6b733cfeb14efaae7a29f0b59d8cf213be4e7ca0b857b80 \ --hash=sha256:573f6eac48f4769d667c4442081b1794f52919e7edada77495aaed9236d13a96 \
--hash=sha256:70c610f6cbe4b9fce272c407dd9d07e33e6bf7b4aa1b7ffb6f6ded8e634e3592 \ --hash=sha256:5b4c145409bef602a690e7cfad0a15a55c13320ff7a3ad7ca59c13bb8ba4d45d \
--hash=sha256:72814c01533f51d68702802d74f77ea026b5ec52793c791e2da806a3844a46c3 \ --hash=sha256:6463effa3186ea09411d50efc7d85360b38d5f09b870c48e4600f63af490e56a \
--hash=sha256:7a4826ad2bd6b07ca615c74ab91f32f6c96d08f6fcc3902ceeedaec8cdc3bcd6 \ --hash=sha256:65f6f63034100ead094b8744b3b97965785388f308a64cf8d7c34f2f2e5be0c4 \
--hash=sha256:7c70087bfee18a42b4040bb9ec1ca15a08242cf5867c58726530bdf3945672ed \ --hash=sha256:663946639d296df6a2bb2aa51b60a2454ca1cb29835324c640dafb5ff2131a77 \
--hash=sha256:855eafa5d5a2034b4621c74925d89c5efef61418570e5ef9b37717d9c796419c \ --hash=sha256:6897af51655e3691ff853668779c7bad41579facacf5fd7253b0133308cf000d \
--hash=sha256:8700f06d0ce6f128de3ccdbc1acaea1ee264d2caa9ca05daaf492fde7c2a7200 \ --hash=sha256:68d1f8a9e9e37c1223b656399be5d6b448dea850bed7d0f87a8311f1ff3dabb0 \
--hash=sha256:89f1b185a01fe560bc8ae5f619e924407efca2191b56ce749ec84982fc59a32a \ --hash=sha256:6ac7ffc7ad6d040517be39eb591cac5ff87416c2537df6ba3cba3bae290c0fed \
--hash=sha256:8b2c760cfc7042b27ebdb4a43a4453bd829a5742503599144d54a032c5dc7e9e \ --hash=sha256:6b3251890fff30ee142c44144871185dbe13b11bab478a88887a639655be1068 \
--hash=sha256:8c2f5e83493748286002f9369f3e6607c565a6a90425a3a1fef5ae32a36d749d \ --hash=sha256:6c4caeef8fa63d06bd437cd4bdcf3ffefe6738fb1b25951440d80dc7df8c03ac \
--hash=sha256:8e098148dd37b4ce3baca71fb394c81dc5d9c7728c95df695d2dca218edf40e6 \ --hash=sha256:6ef1d82a3af9d3eecdba2321dc1b3c238245d890843e040e41e470ffa64c3e25 \
--hash=sha256:94aea8eff76ee6d1cdacb07dd2123a68283cb5569e0250feab1240058f53b623 \ --hash=sha256:753f10e867343b4511128c6ed8c82f7bec3bd026875576dfd88483c5c73b2fd8 \
--hash=sha256:95eb302ff792e12aba9a8b8f8474ab229a83c103d74a750ec0bd1c1eea32e669 \ --hash=sha256:7cd13a2e3ddeed6913a65e66e94b51d80a041145a026c27e6bb76c31a853c6ab \
--hash=sha256:9bd9b3b31adcb054116447ea22caa61a285d92e94d710aa5ec97992ff5eb7cf3 \ --hash=sha256:7ed9e526742851e8d5cc9e6cf41427dfc6068d4f5a3bb03659444b4cabf6bc26 \
--hash=sha256:9e608aafdb55eb9f255034709e20d5a83b6d60c054df0802fa9c9883d0a937aa \ --hash=sha256:7f04c839ed0b6b98b1a7501a002144b76c18fb1c1850c8b98d458ac269e26ed2 \
--hash=sha256:a103b3a7069b62f5d4890ae1b8f0597618f628b286b03d4bc9195230b154bfa9 \ --hash=sha256:802fe99cca7457642125a8a88a084cef28ff0cf9407060f7b93dca5aa25480db \
--hash=sha256:a386ebe437176aab38c041de1260cd3ea459c6ce5263594399880bbc398225b2 \ --hash=sha256:80402cd6ee291dcb72644d6eac93785fe2c8b9cb30893c1af5b8fdd753b9d40f \
--hash=sha256:a38856a971c602f98472050165cea2cdc97709240373041b69030be15047691f \ --hash=sha256:8465322196c8b4d7ab6d1e049e4c5cb460d0394da4a27d23cc242fbf0034b6b5 \
--hash=sha256:a401b4598e5d3f4a9a811f3daf42ee2291790c7f9d74b18d75d6e21dda98a1a1 \ --hash=sha256:86216b5cee4b06df986d214f664305142d9c76df9b6512be2738aa72a2048f99 \
--hash=sha256:a7647ebdfb9682b7bb97e2a5e7cb6ae735b1c25008a70b906aecca294ee96cf4 \ --hash=sha256:87d1351268731db79e0f8e745d92493ee2841c974128ef629dc518b937d9194c \
--hash=sha256:aaf63899c94de41fe3cf934601b0f7ccb6b428c6e4eeb80da72c58eab077b19a \ --hash=sha256:8bdb58ff7ba23002a4c5808d608e4e6c687175724f54a5dade5fa8c67b604e4d \
--hash=sha256:b0dac0ff919ba34d4df1b6131f59ce95b08b9065233446be7e459f95554c0dc8 \ --hash=sha256:8c622a5fe39a48f78944a87d4fb8a53ee07344641b0562c540d840748571b811 \
--hash=sha256:baacc6aee0b2ef6f3d308e197b5d7a81c0e70b06beae1f1fcacffdbd124fe0e3 \ --hash=sha256:8d756e44e94489e49571086ef83b2bb8ce311e730092d2c34ca8f7d925cb20aa \
--hash=sha256:bf420121d4c8dce6b889f0e8e4ec0ca34b7f40186203f06a946fa0276ba54029 \ --hash=sha256:8f4a014bc36d3c57402e2977dada34f9c12300af536839dc38c0beab8878f38a \
--hash=sha256:c04a46716adde8d927adb9457bbe39cf473e1e2c2f5d0a16ceb837e5d841ad4f \ --hash=sha256:9063e24fdb1e498ab71cb7419e24622516c4a04476b17a2dab57e8baa30d6e03 \
--hash=sha256:c0b21078a4b56965e2b12f247467b234734491897e99c1d51cee628da9786959 \ --hash=sha256:90d558489962fd4918143277a773316e56c72da56ec7aa3dc3dbbe20fdfed15b \
--hash=sha256:c1c76a1743432b4b60ab3358c937a3fe1341c828ae6194108a94c69028247f22 \ --hash=sha256:923c0c831b7cfcb071580d3f46c4baf50f174be571576556269530f4bbd79d04 \
--hash=sha256:c4983bf937209c57240cff65906b18bb35e64ae872da6a0db937d7b4af845dd7 \ --hash=sha256:95f2a5796329323b8f0512e09dbb7a1860c46a39da62ecb2324f116fa8fdc85c \
--hash=sha256:c4fb39a81950ec280984b3a44f5bd12819953dc5fa3a7e6fa7a80db5ee853952 \ --hash=sha256:96b02a3dc4381e5494fad39be677abcb5e6634bf7b4fa83a6dd3112607547001 \
--hash=sha256:c57921cda3a80d0f2b8aec7e25c8aa14479ea92b5b51b6876d975d925a2ea346 \ --hash=sha256:9f96df6923e21816da7e0ad3fd47dd8f94b2a5ce594e00677c0013018b813458 \
--hash=sha256:c8063cf17b19661471ecbdb3df1c84f24ad2e389e326ccaf89e3fb2484d8dd7e \ --hash=sha256:a10af20b82360ab00827f916a6058451b723b4e65030c5a18577c8b2de5b3389 \
--hash=sha256:ccd16eb18a849fd8dcb23e23380e2f0a354e8daa0c984b8a732d9cfaba3a776d \ --hash=sha256:a50aebfa173e157099939b17f18600f72f84eed3049e743b68ad15bd69b6bf99 \
--hash=sha256:cd6dbe0238f7743d0efe563ab46294f54f9bc8f4b9bcf57c3c666cc5bc9d1299 \ --hash=sha256:a981a536974bbc7a512cf44ed14938cf01030a99e9b3a06dd59578882f06f985 \
--hash=sha256:d62e51710986674142526ab9f78663ca2b0726066ae26b78b22e0f5e571238dd \ --hash=sha256:a9a8e9031d613fd2009c182b69c7b2c1ef8239a0efb1df3f7c8da66d5dd3d537 \
--hash=sha256:db901e2ac34c931d73054d9797383d0f8009991e723dab15109740a63e7f902a \ --hash=sha256:ae5f4161f18c61806f411a13b0310bea87f987c7d2ecdbdaad0e94eb2e404238 \
--hash=sha256:e03b8895a6990c9ab2cdcd0f2fe44088ca1c65ae592b8f795c3294af00a461c3 \ --hash=sha256:aed38f6e4fb3f5d6bf81bfa990a07806be9d83cf7bacef998ab1a9bd660a581f \
--hash=sha256:e1c8a2f4c69e08e89632defbfabec2feb8a8d99edc9f89ce33c4b9e36ab63037 \ --hash=sha256:b01b88d45a6fcb69667cd6d2f7a9aeb4bf53760d7fc536bf679ec94fe9f3ff3d \
--hash=sha256:e4b749b9cc6ee664a3300bb3a273c1ca8068c46be705b6c31cf5d276f8628a94 \ --hash=sha256:b261ccdec7821281dade748d088bb6e9b69e6d15b30652b74cbbac25e280b796 \
--hash=sha256:e6a5bf2cba5ae1bb80b154ed68a3cfa2fa00fde979a7f50d6598d3e17d9ac20c \ --hash=sha256:b2b0a0c0517616b6869869f8c581d4eb2dd83a4d79e0ebcb7d373ef9956aeb0a \
--hash=sha256:e857a2232ba53ae940d3456f7533ce6ca98b81917d47adc3c7fd55dad8fab858 \ --hash=sha256:b4a23f61ce87adf89be746c8a8974fe1c823c891d8f86eb218bb957c924bb143 \
--hash=sha256:ee4006268ed33370957f55bf2e6f4d263eaf4dc3cfc473d1d90baff6ed36ce4a \ --hash=sha256:bd8f7df7d12c2db9fab40bdd87a7c09b1530128315d047a086fa3ae3435cb3a8 \
--hash=sha256:eef9df1eefada2c09a5e7a40991b9fc6ac6ef20b1372abd48d2794a316dc0449 \ --hash=sha256:beb58fe5cdb101e3a055192ac291b7a21e3b7ef4f67fa1d74e331a7f2124341c \
--hash=sha256:f058f6963fd82eb143c692cecdc89e075fa0828db2e5b291070485390b2f1c9c \ --hash=sha256:c002b4ffc0be611f0d9da932eb0f704fe2602a9a949d1f738e4c34c75b0863d5 \
--hash=sha256:f25c229a6ba38a35ae6e25ca1264621cc25d4d38dca2942a7fce0b67a4efe918 \ --hash=sha256:c083af607d2515612056a31f0a8d9e0fcb5876b7bfc0abad3ecd275bc4ebc2d5 \
--hash=sha256:f2a1d0fd4242bd8643ce6f98927cf9c04540af6efa92323e9d3124f57727bfc1 \ --hash=sha256:c180f51afb394e165eafe4ac2936a14bee3eb10debc9d9e4db8958fe36afe711 \
--hash=sha256:f7560358a6811e52e9c4d142d497f1a6e10103d3a6881f18d04dbce3729c0e2c \ --hash=sha256:c235ebd9baae02f1b77bcea61bce332cb4331dc3617d254df3323aa01ab47bd4 \
--hash=sha256:f779d3ad205f108d14e99bb3859aa7dd8e9c68874617c72354d7ecaec2a054ac \ --hash=sha256:cd70574b12bb8a4d2aaa0094515df2463cb429d8536cfb6c7ce983246983e5a6 \
--hash=sha256:f87f746ee241d30d6ed93969de31e5ffd09a2961a051e60ae6bddde9ec3583aa --hash=sha256:d0eccceffcb53201b5bfebb52600a5fb483a20b61da9dbc885f8b103cbe7598c \
colorama==0.4.6 ; python_version >= "3.9" and python_version < "4" and sys_platform == "win32" \ --hash=sha256:d965bba47ddeec8cd560687584e88cf699fd28f192ceb452d1d7ee807c5597b7 \
--hash=sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44 \ --hash=sha256:db364eca23f876da6f9e16c9da0df51aa4f104a972735574842618b8c6d999d4 \
--hash=sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6 --hash=sha256:ddbb2551d7e0102e7252db79ba445cdab71b26640817ab1e3e3648dad515003b \
colorlog==6.7.0 ; python_version >= "3.9" and python_version < "4" \ --hash=sha256:deb6be0ac38ece9ba87dea880e438f25ca3eddfac8b002a2ec3d9183a454e8ae \
--hash=sha256:e06ed3eb3218bc64786f7db41917d4e686cc4856944f53d5bdf83a6884432e12 \
--hash=sha256:e27ad930a842b4c5eb8ac0016b0a54f5aebbe679340c26101df33424142c143c \
--hash=sha256:e537484df0d8f426ce2afb2d0f8e1c3d0b114b83f8850e5f2fbea0e797bd82ae \
--hash=sha256:eb00ed941194665c332bf8e078baf037d6c35d7c4f3102ea2d4f16ca94a26dc8 \
--hash=sha256:eb6904c354526e758fda7167b33005998fb68c46fbc10e013ca97f21ca5c8887 \
--hash=sha256:eb8821e09e916165e160797a6c17edda0679379a4be5c716c260e836e122f54b \
--hash=sha256:efcb3f6676480691518c177e3b465bcddf57cea040302f9f4e6e191af91174d4 \
--hash=sha256:f27273b60488abe721a075bcca6d7f3964f9f6f067c8c4c605743023d7d3944f \
--hash=sha256:f30c3cb33b24454a82faecaf01b19c18562b1e89558fb6c56de4d9118a032fd5 \
--hash=sha256:fb69256e180cb6c8a894fee62b3afebae785babc1ee98b81cdf68bbca1987f33 \
--hash=sha256:fd1abc0d89e30cc4e02e4064dc67fcc51bd941eb395c502aac3ec19fab46b519 \
--hash=sha256:ff8fa367d09b717b2a17a052544193ad76cd49979c805768879cb63d9ca50561
# via requests
cli-base-utilities==0.4.4 \
--hash=sha256:110bef895fb7dfc29662f463ccedc4c985a880afbde2e6dea387d0d2f96f4985 \
--hash=sha256:72d4248776519a21c3448d6e348511ce6fe8c3742c154e158473236c8278fb1c
# via pyinventory-ynh (pyproject.toml)
click==8.1.7 \
--hash=sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28 \
--hash=sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de
# via
# cli-base-utilities
# rich-click
colorlog==6.7.0 \
--hash=sha256:0d33ca236784a1ba3ff9c532d4964126d8a2c44f1f0cb1d2b0728196f512f662 \ --hash=sha256:0d33ca236784a1ba3ff9c532d4964126d8a2c44f1f0cb1d2b0728196f512f662 \
--hash=sha256:bd94bd21c1e13fac7bd3153f4bc3a7dc0eb0974b8bc2fdf1a989e474f6e582e5 --hash=sha256:bd94bd21c1e13fac7bd3153f4bc3a7dc0eb0974b8bc2fdf1a989e474f6e582e5
defusedxml==0.7.1 ; python_version >= "3.9" and python_version < "4" \ # via
# django-yunohost-integration
# pyinventory
defusedxml==0.7.1 \
--hash=sha256:1bb3032db185915b62d7c6209c5a8792be6a32ab2fedacc84e01b52c51aa3e69 \ --hash=sha256:1bb3032db185915b62d7c6209c5a8792be6a32ab2fedacc84e01b52c51aa3e69 \
--hash=sha256:a352e7e428770286cc899e2542b6cdaedb2b4953ff269a210103ec58f6198a61 --hash=sha256:a352e7e428770286cc899e2542b6cdaedb2b4953ff269a210103ec58f6198a61
diff-match-patch==20230430 ; python_version >= "3.9" and python_version < "4" \ # via odfpy
diff-match-patch==20230430 \
--hash=sha256:953019cdb9c9d2c9e47b5b12bcff3cf4746fc4598eb406076fa1fc27e6a1f15c \ --hash=sha256:953019cdb9c9d2c9e47b5b12bcff3cf4746fc4598eb406076fa1fc27e6a1f15c \
--hash=sha256:dce43505fb7b1b317de7195579388df0746d90db07015ed47a85e5e44930ef93 --hash=sha256:dce43505fb7b1b317de7195579388df0746d90db07015ed47a85e5e44930ef93
django-admin-sortable2==2.1.9 ; python_version >= "3.9" and python_version < "4" \ # via
--hash=sha256:6de19689cb2f131d256ce19d2fd148728d551943d8463b1d81f6334adfa0b6fc \ # django-import-export
--hash=sha256:bf036785c598685a0019eb08340b88fe6ca74bd178033e2290e6c41b62fa4bf1 # django-reversion-compare
django-axes==6.1.0 ; python_version >= "3.9" and python_version < "4" \ django==4.2.7 \
--hash=sha256:a7d509dc76e67440839522a182dc63ecafc3bac3af9de6f263d2bcec1154e50e \ --hash=sha256:8e0f1c2c2786b5c0e39fe1afce24c926040fad47c8ea8ad30aaf1188df29fc41 \
--hash=sha256:e3d44d4ec64ba6d470ef01b6c4b53b6b3747de96821f7c0ef96c64bffa9f6f74 --hash=sha256:e1d37c51ad26186de355cbcec16613ebdabfa9689bbade9c538835205a8abbe9
django-ckeditor==6.7.0 ; python_version >= "3.9" and python_version < "4" \ # via
# bx-django-utils
# django-admin-sortable2
# django-axes
# django-ckeditor
# django-dbbackup
# django-debug-toolbar
# django-import-export
# django-js-asset
# django-redis
# django-reversion
# django-reversion-compare
# django-tagulous
# django-tools
# django-yunohost-integration
# pyinventory
django-admin-sortable2==2.1.10 \
--hash=sha256:3756b02c7d09c5b37efe657718d5aae2b75f46fd01bbfe1c39d4e60651019d79 \
--hash=sha256:98d1c8d268398c3c3aff4752f766b2c307a5bd97174938c29f818d8a4697854d
# via pyinventory
django-axes==6.1.1 \
--hash=sha256:29c48ff5f09046afd5e9a16e96d3bbb79f6c11c59f0a7bbd732559e60d0aa9fa \
--hash=sha256:cd1bc4f7becc8e9243eb4090dffa258d7d7125ca0ce3153b6ffc920bccbf2c3f
# via django-yunohost-integration
django-ckeditor==6.7.0 \
--hash=sha256:0489f7a6ae93360d328f77cea17c04891103cbdfa6c962af386bbe47e811671b \ --hash=sha256:0489f7a6ae93360d328f77cea17c04891103cbdfa6c962af386bbe47e811671b \
--hash=sha256:73399fb8f56f565e7519b57adbd7c585623db2cdc8c75666f56918d3eecf7906 --hash=sha256:73399fb8f56f565e7519b57adbd7c585623db2cdc8c75666f56918d3eecf7906
django-dbbackup==4.0.2 ; python_version >= "3.9" and python_version < "4" \ # via pyinventory
django-dbbackup==4.0.2 \
--hash=sha256:1874d684abc22260972a67668a6db3331b24d7e1e8af89eaffdcd61eb27dbc2a \ --hash=sha256:1874d684abc22260972a67668a6db3331b24d7e1e8af89eaffdcd61eb27dbc2a \
--hash=sha256:3ccde831f1a8268fb031b37a8e7e2de3abb556623023af1e859cd7104c09ea2a --hash=sha256:3ccde831f1a8268fb031b37a8e7e2de3abb556623023af1e859cd7104c09ea2a
django-debug-toolbar==4.2.0 ; python_version >= "3.9" and python_version < "4" \ # via pyinventory
django-debug-toolbar==4.2.0 \
--hash=sha256:af99128c06e8e794479e65ab62cc6c7d1e74e1c19beb44dcbf9bad7a9c017327 \ --hash=sha256:af99128c06e8e794479e65ab62cc6c7d1e74e1c19beb44dcbf9bad7a9c017327 \
--hash=sha256:bc7fdaafafcdedefcc67a4a5ad9dac96efd6e41db15bc74d402a54a2ba4854dc --hash=sha256:bc7fdaafafcdedefcc67a4a5ad9dac96efd6e41db15bc74d402a54a2ba4854dc
django-import-export==3.2.0 ; python_version >= "3.9" and python_version < "4" \ # via pyinventory
--hash=sha256:1d3f2cb2ee3cca0386ed60651fa1623be989f130d9fbdf98a67f7dc3a94b8a37 \ django-import-export==3.3.1 \
--hash=sha256:38fd7b9439b9e3aa1a4747421c1087a5bc194e915a28d795fb8429a5f8028f2d --hash=sha256:88ecaf06be06bd95d97cf34f3c911c56c012a7a81712a8956740e5bfc2465162 \
django-js-asset==2.1.0 ; python_version >= "3.9" and python_version < "4" \ --hash=sha256:d02e31908c965d512cc6f7ef6e72935177647b15d3846050d0f094177fca0d86
# via pyinventory
django-js-asset==2.1.0 \
--hash=sha256:36a3a4dd6e9efc895fb127d13126020f6ec1ec9469ad42878d42143f22495d90 \ --hash=sha256:36a3a4dd6e9efc895fb127d13126020f6ec1ec9469ad42878d42143f22495d90 \
--hash=sha256:be6f69ae5c4865617aa7726c48eddb64089a1e7d4ea7d22a35a3beb8282020f6 --hash=sha256:be6f69ae5c4865617aa7726c48eddb64089a1e7d4ea7d22a35a3beb8282020f6
django-redis==5.3.0 ; python_version >= "3.9" and python_version < "4" \ # via django-ckeditor
--hash=sha256:2d8660d39f586c41c9907d5395693c477434141690fd7eca9d32376af00b0aac \ django-redis==5.4.0 \
--hash=sha256:8bc5793ec06b28ea802aad85ec437e7646511d4e571e07ccad19cfed8b9ddd44 --hash=sha256:6a02abaa34b0fea8bf9b707d2c363ab6adc7409950b2db93602e6cb292818c42 \
django-reversion-compare==0.16.2 ; python_version >= "3.9" and python_version < "4" \ --hash=sha256:ebc88df7da810732e2af9987f7f426c96204bf89319df4c6da6ca9a2942edd5b
# via django-yunohost-integration
django-reversion==5.0.6 \
--hash=sha256:6ee25a97070dda14f3e082b8b999bfbecb4a9f082ff1f851e344d056a18c934c \
--hash=sha256:eb69f131f04a31b39fda2ce3bca77599c2a825544b437f79ba8d43a2a5e81eef
# via django-reversion-compare
django-reversion-compare==0.16.2 \
--hash=sha256:5629f226fc73bd7b95de47b2e21e2eba2fa39f004ba0fee6d460e96676c0dc9b \ --hash=sha256:5629f226fc73bd7b95de47b2e21e2eba2fa39f004ba0fee6d460e96676c0dc9b \
--hash=sha256:9d7d096534f5d0e49d7419a8a29b4517580e6a7855529e594d10bfb373f980ab --hash=sha256:9d7d096534f5d0e49d7419a8a29b4517580e6a7855529e594d10bfb373f980ab
django-reversion==5.0.4 ; python_version >= "3.9" and python_version < "4" \ # via pyinventory
--hash=sha256:a591cbce8621b5d036a37617554668b5ef2eb9777682e3af20b6401ee87cfbc5 \ django-tagulous==1.3.3 \
--hash=sha256:c12bab452d31dd3c244456cf1df383acf14ba147cf99404c5e44412596de42fc
django-tagulous==1.3.3 ; python_version >= "3.9" and python_version < "4" \
--hash=sha256:ad3bb85f4cce83a47e4c0257143229cb92a294defa02fe661823b0442b35d478 \ --hash=sha256:ad3bb85f4cce83a47e4c0257143229cb92a294defa02fe661823b0442b35d478 \
--hash=sha256:d445590ae1b5cb9b8c5a425f97bf5f01148a33419c19edeb721ebd9fdd6792fe --hash=sha256:d445590ae1b5cb9b8c5a425f97bf5f01148a33419c19edeb721ebd9fdd6792fe
django-tools==0.54.0 ; python_version >= "3.9" and python_version < "4" \ # via pyinventory
django-tools==0.54.0 \
--hash=sha256:5040a91282be9d1c9d379b0c65da50bcb3691bff03cee54fd4123ace238c3a43 \ --hash=sha256:5040a91282be9d1c9d379b0c65da50bcb3691bff03cee54fd4123ace238c3a43 \
--hash=sha256:a7b7bfa5b9c5a81966454d17dffb2403cee25a806c858ee0486a08798227598f --hash=sha256:a7b7bfa5b9c5a81966454d17dffb2403cee25a806c858ee0486a08798227598f
django-yunohost-integration[ynh]==0.6.0 ; python_version >= "3.9" and python_version < "4" \ # via
# django-yunohost-integration
# pyinventory
django-yunohost-integration[ynh]==0.6.0 \
--hash=sha256:9596ab56b66edf1b56eccaceb4b5807df237e752128e79568cd13b075267f26f \ --hash=sha256:9596ab56b66edf1b56eccaceb4b5807df237e752128e79568cd13b075267f26f \
--hash=sha256:dfb72b94ae30e02948dd60ca76d56da4ca6a74ea04f357b8d61b94807fca0493 --hash=sha256:dfb72b94ae30e02948dd60ca76d56da4ca6a74ea04f357b8d61b94807fca0493
django==4.2.4 ; python_version >= "3.9" and python_version < "4" \ # via
--hash=sha256:7e4225ec065e0f354ccf7349a22d209de09cc1c074832be9eb84c51c1799c432 \ # django-yunohost-integration
--hash=sha256:860ae6a138a238fc4f22c99b52f3ead982bb4b1aad8c0122bcd8c8a3a02e409d # pyinventory-ynh (pyproject.toml)
et-xmlfile==1.1.0 ; python_version >= "3.9" and python_version < "4" \ et-xmlfile==1.1.0 \
--hash=sha256:8eb9e2bc2f8c97e37a2dc85a09ecdcdec9d8a396530a6d5a33b30b9a92da0c5c \ --hash=sha256:8eb9e2bc2f8c97e37a2dc85a09ecdcdec9d8a396530a6d5a33b30b9a92da0c5c \
--hash=sha256:a2ba85d1d6a74ef63837eed693bcb89c3f752169b0e3e7ae5b16ca5e1b3deada --hash=sha256:a2ba85d1d6a74ef63837eed693bcb89c3f752169b0e3e7ae5b16ca5e1b3deada
gunicorn==21.2.0 ; python_version >= "3.9" and python_version < "4" \ # via openpyxl
gunicorn==21.2.0 \
--hash=sha256:3213aa5e8c24949e792bcacfc176fef362e7aac80b76c56f6b5122bf350722f0 \ --hash=sha256:3213aa5e8c24949e792bcacfc176fef362e7aac80b76c56f6b5122bf350722f0 \
--hash=sha256:88ec8bff1d634f98e61b9f65bc4bf3cd918a90806c6f5c48bc5603849ec81033 --hash=sha256:88ec8bff1d634f98e61b9f65bc4bf3cd918a90806c6f5c48bc5603849ec81033
icdiff==2.0.7 ; python_version >= "3.9" and python_version < "4" \ # via
# django-yunohost-integration
# pyinventory
icdiff==2.0.7 \
--hash=sha256:f05d1b3623223dd1c70f7848da7d699de3d9a2550b902a8234d9026292fb5762 \ --hash=sha256:f05d1b3623223dd1c70f7848da7d699de3d9a2550b902a8234d9026292fb5762 \
--hash=sha256:f79a318891adbf59a45e3a7694f5e1f18c5407065264637072ac8363b759866f --hash=sha256:f79a318891adbf59a45e3a7694f5e1f18c5407065264637072ac8363b759866f
idna==3.4 ; python_version >= "3.9" and python_version < "4" \ # via django-tools
idna==3.4 \
--hash=sha256:814f528e8dead7d329833b91c5faa87d60bf71824cd12a7530b5526063d02cb4 \ --hash=sha256:814f528e8dead7d329833b91c5faa87d60bf71824cd12a7530b5526063d02cb4 \
--hash=sha256:90b77e79eaa3eba6de819a0c442c0b4ceefc341a7a2ab77d7562bf49f425c5c2 --hash=sha256:90b77e79eaa3eba6de819a0c442c0b4ceefc341a7a2ab77d7562bf49f425c5c2
markuppy==1.14 ; python_version >= "3.9" and python_version < "4" \ # via requests
markdown-it-py==3.0.0 \
--hash=sha256:355216845c60bd96232cd8d8c40e8f9765cc86f46880e43a8fd22dc1a1a8cab1 \
--hash=sha256:e3f60a94fa066dc52ec76661e37c851cb232d92f9886b15cb560aaada2df8feb
# via rich
markuppy==1.14 \
--hash=sha256:1adee2c0a542af378fe84548ff6f6b0168f3cb7f426b46961038a2bcfaad0d5f --hash=sha256:1adee2c0a542af378fe84548ff6f6b0168f3cb7f426b46961038a2bcfaad0d5f
odfpy==1.4.1 ; python_version >= "3.9" and python_version < "4" \ # via tablib
mdurl==0.1.2 \
--hash=sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8 \
--hash=sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba
# via markdown-it-py
odfpy==1.4.1 \
--hash=sha256:db766a6e59c5103212f3cc92ec8dd50a0f3a02790233ed0b52148b70d3c438ec --hash=sha256:db766a6e59c5103212f3cc92ec8dd50a0f3a02790233ed0b52148b70d3c438ec
openpyxl==3.1.2 ; python_version >= "3.9" and python_version < "4" \ # via tablib
openpyxl==3.1.2 \
--hash=sha256:a6f5977418eff3b2d5500d54d9db50c8277a368436f4e4f8ddb1be3422870184 \ --hash=sha256:a6f5977418eff3b2d5500d54d9db50c8277a368436f4e4f8ddb1be3422870184 \
--hash=sha256:f91456ead12ab3c6c2e9491cf33ba6d08357d802192379bb482f1033ade496f5 --hash=sha256:f91456ead12ab3c6c2e9491cf33ba6d08357d802192379bb482f1033ade496f5
packaging==23.1 ; python_version >= "3.9" and python_version < "4" \ # via tablib
--hash=sha256:994793af429502c4ea2ebf6bf664629d07c1a9fe974af92966e4b8d2df7edc61 \ packaging==23.2 \
--hash=sha256:a392980d2b6cffa644431898be54b0045151319d1e7ec34f0cfed48767dd334f --hash=sha256:048fb0e9405036518eaaf48a55953c750c11e1a1b68e0dd1a9d62ed0c092cfc5 \
pillow==10.0.0 ; python_version >= "3.9" and python_version < "4" \ --hash=sha256:8c491190033a9af7e1d931d0b5dacc2ef47509b34dd0de67ed209b5203fc88c7
--hash=sha256:00e65f5e822decd501e374b0650146063fbb30a7264b4d2744bdd7b913e0cab5 \ # via
--hash=sha256:040586f7d37b34547153fa383f7f9aed68b738992380ac911447bb78f2abe530 \ # django-yunohost-integration
--hash=sha256:0b6eb5502f45a60a3f411c63187db83a3d3107887ad0d036c13ce836f8a36f1d \ # gunicorn
--hash=sha256:1ce91b6ec08d866b14413d3f0bbdea7e24dfdc8e59f562bb77bc3fe60b6144ca \ pillow==10.1.0 \
--hash=sha256:1f62406a884ae75fb2f818694469519fb685cc7eaff05d3451a9ebe55c646891 \ --hash=sha256:00f438bb841382b15d7deb9a05cc946ee0f2c352653c7aa659e75e592f6fa17d \
--hash=sha256:22c10cc517668d44b211717fd9775799ccec4124b9a7f7b3635fc5386e584992 \ --hash=sha256:0248f86b3ea061e67817c47ecbe82c23f9dd5d5226200eb9090b3873d3ca32de \
--hash=sha256:3400aae60685b06bb96f99a21e1ada7bc7a413d5f49bce739828ecd9391bb8f7 \ --hash=sha256:04f6f6149f266a100374ca3cc368b67fb27c4af9f1cc8cb6306d849dcdf12616 \
--hash=sha256:349930d6e9c685c089284b013478d6f76e3a534e36ddfa912cde493f235372f3 \ --hash=sha256:062a1610e3bc258bff2328ec43f34244fcec972ee0717200cb1425214fe5b839 \
--hash=sha256:368ab3dfb5f49e312231b6f27b8820c823652b7cd29cfbd34090565a015e99ba \ --hash=sha256:0a026c188be3b443916179f5d04548092e253beb0c3e2ee0a4e2cdad72f66099 \
--hash=sha256:38250a349b6b390ee6047a62c086d3817ac69022c127f8a5dc058c31ccef17f3 \ --hash=sha256:0f7c276c05a9767e877a0b4c5050c8bee6a6d960d7f0c11ebda6b99746068c2a \
--hash=sha256:3a684105f7c32488f7153905a4e3015a3b6c7182e106fe3c37fbb5ef3e6994c3 \ --hash=sha256:1a8413794b4ad9719346cd9306118450b7b00d9a15846451549314a58ac42219 \
--hash=sha256:3a82c40d706d9aa9734289740ce26460a11aeec2d9c79b7af87bb35f0073c12f \ --hash=sha256:1ab05f3db77e98f93964697c8efc49c7954b08dd61cff526b7f2531a22410106 \
--hash=sha256:3b08d4cc24f471b2c8ca24ec060abf4bebc6b144cb89cba638c720546b1cf538 \ --hash=sha256:1c3ac5423c8c1da5928aa12c6e258921956757d976405e9467c5f39d1d577a4b \
--hash=sha256:3ed64f9ca2f0a95411e88a4efbd7a29e5ce2cea36072c53dd9d26d9c76f753b3 \ --hash=sha256:1c41d960babf951e01a49c9746f92c5a7e0d939d1652d7ba30f6b3090f27e412 \
--hash=sha256:3f07ea8d2f827d7d2a49ecf1639ec02d75ffd1b88dcc5b3a61bbb37a8759ad8d \ --hash=sha256:1fafabe50a6977ac70dfe829b2d5735fd54e190ab55259ec8aea4aaea412fa0b \
--hash=sha256:520f2a520dc040512699f20fa1c363eed506e94248d71f85412b625026f6142c \ --hash=sha256:1fb29c07478e6c06a46b867e43b0bcdb241b44cc52be9bc25ce5944eed4648e7 \
--hash=sha256:5c6e3df6bdd396749bafd45314871b3d0af81ff935b2d188385e970052091017 \ --hash=sha256:24fadc71218ad2b8ffe437b54876c9382b4a29e030a05a9879f615091f42ffc2 \
--hash=sha256:608bfdee0d57cf297d32bcbb3c728dc1da0907519d1784962c5f0c68bb93e5a3 \ --hash=sha256:2cdc65a46e74514ce742c2013cd4a2d12e8553e3a2563c64879f7c7e4d28bce7 \
--hash=sha256:685ac03cc4ed5ebc15ad5c23bc555d68a87777586d970c2c3e216619a5476223 \ --hash=sha256:2ef6721c97894a7aa77723740a09547197533146fba8355e86d6d9a4a1056b14 \
--hash=sha256:76de421f9c326da8f43d690110f0e79fe3ad1e54be811545d7d91898b4c8493e \ --hash=sha256:3b834f4b16173e5b92ab6566f0473bfb09f939ba14b23b8da1f54fa63e4b623f \
--hash=sha256:76edb0a1fa2b4745fb0c99fb9fb98f8b180a1bbceb8be49b087e0b21867e77d3 \ --hash=sha256:3d929a19f5469b3f4df33a3df2983db070ebb2088a1e145e18facbc28cae5b27 \
--hash=sha256:7be600823e4c8631b74e4a0d38384c73f680e6105a7d3c6824fcf226c178c7e6 \ --hash=sha256:41f67248d92a5e0a2076d3517d8d4b1e41a97e2df10eb8f93106c89107f38b57 \
--hash=sha256:81ff539a12457809666fef6624684c008e00ff6bf455b4b89fd00a140eecd640 \ --hash=sha256:47e5bf85b80abc03be7455c95b6d6e4896a62f6541c1f2ce77a7d2bb832af262 \
--hash=sha256:88af2003543cc40c80f6fca01411892ec52b11021b3dc22ec3bc9d5afd1c5334 \ --hash=sha256:4d0152565c6aa6ebbfb1e5d8624140a440f2b99bf7afaafbdbf6430426497f28 \
--hash=sha256:8c11160913e3dd06c8ffdb5f233a4f254cb449f4dfc0f8f4549eda9e542c93d1 \ --hash=sha256:50d08cd0a2ecd2a8657bd3d82c71efd5a58edb04d9308185d66c3a5a5bed9610 \
--hash=sha256:8f8182b523b2289f7c415f589118228d30ac8c355baa2f3194ced084dac2dbba \ --hash=sha256:61f1a9d247317fa08a308daaa8ee7b3f760ab1809ca2da14ecc88ae4257d6172 \
--hash=sha256:9211e7ad69d7c9401cfc0e23d49b69ca65ddd898976d660a2fa5904e3d7a9baa \ --hash=sha256:6932a7652464746fcb484f7fc3618e6503d2066d853f68a4bd97193a3996e273 \
--hash=sha256:92be919bbc9f7d09f7ae343c38f5bb21c973d2576c1d45600fce4b74bafa7ac0 \ --hash=sha256:7a7e3daa202beb61821c06d2517428e8e7c1aab08943e92ec9e5755c2fc9ba5e \
--hash=sha256:9c82b5b3e043c7af0d95792d0d20ccf68f61a1fec6b3530e718b688422727396 \ --hash=sha256:7dbaa3c7de82ef37e7708521be41db5565004258ca76945ad74a8e998c30af8d \
--hash=sha256:9f7c16705f44e0504a3a2a14197c1f0b32a95731d251777dcb060aa83022cb2d \ --hash=sha256:7df5608bc38bd37ef585ae9c38c9cd46d7c81498f086915b0f97255ea60c2818 \
--hash=sha256:9fb218c8a12e51d7ead2a7c9e101a04982237d4855716af2e9499306728fb485 \ --hash=sha256:806abdd8249ba3953c33742506fe414880bad78ac25cc9a9b1c6ae97bedd573f \
--hash=sha256:a74ba0c356aaa3bb8e3eb79606a87669e7ec6444be352870623025d75a14a2bf \ --hash=sha256:883f216eac8712b83a63f41b76ddfb7b2afab1b74abbb413c5df6680f071a6b9 \
--hash=sha256:b4f69b3700201b80bb82c3a97d5e9254084f6dd5fb5b16fc1a7b974260f89f43 \ --hash=sha256:912e3812a1dbbc834da2b32299b124b5ddcb664ed354916fd1ed6f193f0e2d01 \
--hash=sha256:bc2ec7c7b5d66b8ec9ce9f720dbb5fa4bace0f545acd34870eff4a369b44bf37 \ --hash=sha256:937bdc5a7f5343d1c97dc98149a0be7eb9704e937fe3dc7140e229ae4fc572a7 \
--hash=sha256:c189af0545965fa8d3b9613cfdb0cd37f9d71349e0f7750e1fd704648d475ed2 \ --hash=sha256:9882a7451c680c12f232a422730f986a1fcd808da0fd428f08b671237237d651 \
--hash=sha256:c1fbe7621c167ecaa38ad29643d77a9ce7311583761abf7836e1510c580bf3dd \ --hash=sha256:9a92109192b360634a4489c0c756364c0c3a2992906752165ecb50544c251312 \
--hash=sha256:c7cf14a27b0d6adfaebb3ae4153f1e516df54e47e42dcc073d7b3d76111a8d86 \ --hash=sha256:9d7bc666bd8c5a4225e7ac71f2f9d12466ec555e89092728ea0f5c0c2422ea80 \
--hash=sha256:c9f72a021fbb792ce98306ffb0c348b3c9cb967dce0f12a49aa4c3d3fdefa967 \ --hash=sha256:a5f63b5a68daedc54c7c3464508d8c12075e56dcfbd42f8c1bf40169061ae666 \
--hash=sha256:cd25d2a9d2b36fcb318882481367956d2cf91329f6892fe5d385c346c0649629 \ --hash=sha256:a646e48de237d860c36e0db37ecaecaa3619e6f3e9d5319e527ccbc8151df061 \
--hash=sha256:ce543ed15570eedbb85df19b0a1a7314a9c8141a36ce089c0a894adbfccb4568 \ --hash=sha256:a89b8312d51715b510a4fe9fc13686283f376cfd5abca8cd1c65e4c76e21081b \
--hash=sha256:ce7b031a6fc11365970e6a5686d7ba8c63e4c1cf1ea143811acbb524295eabed \ --hash=sha256:a92386125e9ee90381c3369f57a2a50fa9e6aa8b1cf1d9c4b200d41a7dd8e992 \
--hash=sha256:d35e3c8d9b1268cbf5d3670285feb3528f6680420eafe35cccc686b73c1e330f \ --hash=sha256:ae88931f93214777c7a3aa0a8f92a683f83ecde27f65a45f95f22d289a69e593 \
--hash=sha256:d50b6aec14bc737742ca96e85d6d0a5f9bfbded018264b3b70ff9d8c33485551 \ --hash=sha256:afc8eef765d948543a4775f00b7b8c079b3321d6b675dde0d02afa2ee23000b4 \
--hash=sha256:d5d0dae4cfd56969d23d94dc8e89fb6a217be461c69090768227beb8ed28c0a3 \ --hash=sha256:b0eb01ca85b2361b09480784a7931fc648ed8b7836f01fb9241141b968feb1db \
--hash=sha256:d5db32e2a6ccbb3d34d87c87b432959e0db29755727afb37290e10f6e8e62614 \ --hash=sha256:b1c25762197144e211efb5f4e8ad656f36c8d214d390585d1d21281f46d556ba \
--hash=sha256:d72e2ecc68a942e8cf9739619b7f408cc7b272b279b56b2c83c6123fcfa5cdff \ --hash=sha256:b4005fee46ed9be0b8fb42be0c20e79411533d1fd58edabebc0dd24626882cfd \
--hash=sha256:d737a602fbd82afd892ca746392401b634e278cb65d55c4b7a8f48e9ef8d008d \ --hash=sha256:b920e4d028f6442bea9a75b7491c063f0b9a3972520731ed26c83e254302eb1e \
--hash=sha256:d80cf684b541685fccdd84c485b31ce73fc5c9b5d7523bf1394ce134a60c6883 \ --hash=sha256:baada14941c83079bf84c037e2d8b7506ce201e92e3d2fa0d1303507a8538212 \
--hash=sha256:db24668940f82321e746773a4bc617bfac06ec831e5c88b643f91f122a785684 \ --hash=sha256:bb40c011447712d2e19cc261c82655f75f32cb724788df315ed992a4d65696bb \
--hash=sha256:dbc02381779d412145331789b40cc7b11fdf449e5d94f6bc0b080db0a56ea3f0 \ --hash=sha256:c0949b55eb607898e28eaccb525ab104b2d86542a85c74baf3a6dc24002edec2 \
--hash=sha256:dffe31a7f47b603318c609f378ebcd57f1554a3a6a8effbc59c3c69f804296de \ --hash=sha256:c9aeea7b63edb7884b031a35305629a7593272b54f429a9869a4f63a1bf04c34 \
--hash=sha256:edf4392b77bdc81f36e92d3a07a5cd072f90253197f4a52a55a8cec48a12483b \ --hash=sha256:cfe96560c6ce2f4c07d6647af2d0f3c54cc33289894ebd88cfbb3bcd5391e256 \
--hash=sha256:efe8c0681042536e0d06c11f48cebe759707c9e9abf880ee213541c5b46c5bf3 \ --hash=sha256:d27b5997bdd2eb9fb199982bb7eb6164db0426904020dc38c10203187ae2ff2f \
--hash=sha256:f31f9fdbfecb042d046f9d91270a0ba28368a723302786c0009ee9b9f1f60199 \ --hash=sha256:d921bc90b1defa55c9917ca6b6b71430e4286fc9e44c55ead78ca1a9f9eba5f2 \
--hash=sha256:f88a0b92277de8e3ca715a0d79d68dc82807457dae3ab8699c758f07c20b3c51 \ --hash=sha256:e6bf8de6c36ed96c86ea3b6e1d5273c53f46ef518a062464cd7ef5dd2cf92e38 \
--hash=sha256:faaf07ea35355b01a35cb442dd950d8f1bb5b040a7787791a535de13db15ed90 --hash=sha256:eaed6977fa73408b7b8a24e8b14e59e1668cfc0f4c40193ea7ced8e210adf996 \
pprintpp==0.4.0 ; python_version >= "3.9" and python_version < "4" \ --hash=sha256:fa1d323703cfdac2036af05191b969b910d8f115cf53093125e4058f62012c9a \
--hash=sha256:fe1e26e1ffc38be097f0ba1d0d07fcade2bcfd1d023cda5b29935ae8052bd793
# via pyinventory
pprintpp==0.4.0 \
--hash=sha256:b6b4dcdd0c0c0d75e4d7b2f21a9e933e5b2ce62b26e1a54537f9651ae5a5c01d \ --hash=sha256:b6b4dcdd0c0c0d75e4d7b2f21a9e933e5b2ce62b26e1a54537f9651ae5a5c01d \
--hash=sha256:ea826108e2c7f49dc6d66c752973c3fc9749142a798d6b254e1e301cfdbc6403 --hash=sha256:ea826108e2c7f49dc6d66c752973c3fc9749142a798d6b254e1e301cfdbc6403
psycopg2==2.9.7 ; python_version >= "3.9" and python_version < "4" \ # via django-tools
--hash=sha256:1a6a2d609bce44f78af4556bea0c62a5e7f05c23e5ea9c599e07678995609084 \ psycopg2==2.9.9 \
--hash=sha256:44d93a0109dfdf22fe399b419bcd7fa589d86895d3931b01fb321d74dadc68f1 \ --hash=sha256:121081ea2e76729acfb0673ff33755e8703d45e926e416cb59bae3a86c6a4981 \
--hash=sha256:8275abf628c6dc7ec834ea63f6f3846bf33518907a2b9b693d41fd063767a866 \ --hash=sha256:38a8dcc6856f569068b47de286b472b7c473ac7977243593a288ebce0dc89516 \
--hash=sha256:91e81a8333a0037babfc9fe6d11e997a9d4dac0f38c43074886b0d9dead94fe9 \ --hash=sha256:426f9f29bde126913a20a96ff8ce7d73fd8a216cfb323b1f04da402d452853c3 \
--hash=sha256:b22ed9c66da2589a664e0f1ca2465c29b75aaab36fa209d4fb916025fb9119e5 \ --hash=sha256:5e0d98cade4f0e0304d7d6f25bbfbc5bd186e07b38eac65379309c4ca3193efa \
--hash=sha256:b6bd7d9d3a7a63faae6edf365f0ed0e9b0a1aaf1da3ca146e6b043fb3eb5d723 \ --hash=sha256:7e2dacf8b009a1c1e843b5213a87f7c544b2b042476ed7755be813eaf4e8347a \
--hash=sha256:c7949770cafbd2f12cecc97dea410c514368908a103acf519f2a346134caa4d5 \ --hash=sha256:a7653d00b732afb6fc597e29c50ad28087dcb4fbfb28e86092277a559ae4e693 \
--hash=sha256:d1210fcf99aae6f728812d1d2240afc1dc44b9e6cba526a06fb8134f969957c2 \ --hash=sha256:ade01303ccf7ae12c356a5e10911c9e1c51136003a9a1d92f7aa9d010fb98372 \
--hash=sha256:d5c5297e2fbc8068d4255f1e606bfc9291f06f91ec31b2a0d4c536210ac5c0a2 \ --hash=sha256:bac58c024c9922c23550af2a581998624d6e02350f4ae9c5f0bc642c633a2d5e \
--hash=sha256:e9b04cbef584310a1ac0f0d55bb623ca3244c87c51187645432e342de9ae81a8 \ --hash=sha256:c92811b2d4c9b6ea0285942b2e7cac98a59e166d59c588fe5cfe1eda58e72d59 \
--hash=sha256:f00cc35bd7119f1fed17b85bd1007855194dde2cbd8de01ab8ebb17487440ad8 --hash=sha256:d1454bde93fb1e224166811694d600e746430c006fbb031ea06ecc2ea41bf156 \
pyinventory==0.19.2 ; python_version >= "3.9" and python_version < "4" \ --hash=sha256:d735786acc7dd25815e89cc4ad529a43af779db2e25aa7c626de864127e5a024 \
--hash=sha256:06424c8ddf8521cf5806d834e3aede8254a4960f538a210bfd88508d88fb1d36 \ --hash=sha256:de80739447af31525feddeb8effd640782cf5998e1a4e9192ebdf829717e3913 \
--hash=sha256:2d92a7f4b4a7b3191819f671e95070b3dd8844fdf2ceb8d971da1e61b094db24 --hash=sha256:ff432630e510709564c01dafdbe996cb552e0b9f3f065eb89bdce5bd31fabf4c
python-stdnum==1.19 ; python_version >= "3.9" and python_version < "4" \ # via django-yunohost-integration
pygments==2.16.1 \
--hash=sha256:13fc09fa63bc8d8671a6d247e1eb303c4b343eaee81d861f3404db2935653692 \
--hash=sha256:1daff0494820c69bc8941e407aa20f577374ee88364ee10a98fdbe0aece96e29
# via rich
pyinventory==0.19.3 \
--hash=sha256:42e5710956e466df389ddf01c1ab8f9c432890b745a2a32765085c67fda78cfa \
--hash=sha256:b9efc88ca43aa57c4e04f2024087e50015bd9fc969730e3049258b06d048cce4
# via pyinventory-ynh (pyproject.toml)
python-stdnum==1.19 \
--hash=sha256:133ec82f56390ea74c190569e98f2fb14b869808b1d54785708f22d0fead8b3f \ --hash=sha256:133ec82f56390ea74c190569e98f2fb14b869808b1d54785708f22d0fead8b3f \
--hash=sha256:1b5b401ad3f45b798b0317313b781a433f5d7a5ff2c9feb8054664f76f78644e --hash=sha256:1b5b401ad3f45b798b0317313b781a433f5d7a5ff2c9feb8054664f76f78644e
pytz==2023.3 ; python_version >= "3.9" and python_version < "4" \ # via bx-django-utils
--hash=sha256:1d8ce29db189191fb55338ee6d0387d82ab59f3d00eac103412d64e0ebd0c588 \ pytz==2023.3.post1 \
--hash=sha256:a151b3abb88eda1d4e34a9814df37de2a80e301e68ba0fd856fb9b46bfbbbffb --hash=sha256:7b4fddbeb94a1eba4b557da24f19fdf9db575192544270a9101d8509f9f43d7b \
pyyaml==6.0.1 ; python_version >= "3.9" and python_version < "4" \ --hash=sha256:ce42d816b81b68506614c11e8937d3aa9e41007ceb50bfdcb0749b921bf646c7
# via django-dbbackup
pyyaml==6.0.1 \
--hash=sha256:04ac92ad1925b2cff1db0cfebffb6ffc43457495c9b3c39d3fcae417d7125dc5 \
--hash=sha256:062582fca9fabdd2c8b54a3ef1c978d786e0f6b3a1510e0ac93ef59e0ddae2bc \ --hash=sha256:062582fca9fabdd2c8b54a3ef1c978d786e0f6b3a1510e0ac93ef59e0ddae2bc \
--hash=sha256:0d3304d8c0adc42be59c5f8a4d9e3d7379e6955ad754aa9d6ab7a398b59dd1df \
--hash=sha256:1635fd110e8d85d55237ab316b5b011de701ea0f29d07611174a1b42f1444741 \ --hash=sha256:1635fd110e8d85d55237ab316b5b011de701ea0f29d07611174a1b42f1444741 \
--hash=sha256:184c5108a2aca3c5b3d3bf9395d50893a7ab82a38004c8f61c258d4428e80206 \ --hash=sha256:184c5108a2aca3c5b3d3bf9395d50893a7ab82a38004c8f61c258d4428e80206 \
--hash=sha256:18aeb1bf9a78867dc38b259769503436b7c72f7a1f1f4c93ff9a17de54319b27 \ --hash=sha256:18aeb1bf9a78867dc38b259769503436b7c72f7a1f1f4c93ff9a17de54319b27 \
@ -258,7 +369,10 @@ pyyaml==6.0.1 ; python_version >= "3.9" and python_version < "4" \
--hash=sha256:1e2722cc9fbb45d9b87631ac70924c11d3a401b2d7f410cc0e3bbf249f2dca62 \ --hash=sha256:1e2722cc9fbb45d9b87631ac70924c11d3a401b2d7f410cc0e3bbf249f2dca62 \
--hash=sha256:1fe35611261b29bd1de0070f0b2f47cb6ff71fa6595c077e42bd0c419fa27b98 \ --hash=sha256:1fe35611261b29bd1de0070f0b2f47cb6ff71fa6595c077e42bd0c419fa27b98 \
--hash=sha256:28c119d996beec18c05208a8bd78cbe4007878c6dd15091efb73a30e90539696 \ --hash=sha256:28c119d996beec18c05208a8bd78cbe4007878c6dd15091efb73a30e90539696 \
--hash=sha256:326c013efe8048858a6d312ddd31d56e468118ad4cdeda36c719bf5bb6192290 \
--hash=sha256:40df9b996c2b73138957fe23a16a4f0ba614f4c0efce1e9406a184b6d07fa3a9 \
--hash=sha256:42f8152b8dbc4fe7d96729ec2b99c7097d656dc1213a3229ca5383f973a5ed6d \ --hash=sha256:42f8152b8dbc4fe7d96729ec2b99c7097d656dc1213a3229ca5383f973a5ed6d \
--hash=sha256:49a183be227561de579b4a36efbb21b3eab9651dd81b1858589f796549873dd6 \
--hash=sha256:4fb147e7a67ef577a588a0e2c17b6db51dda102c71de36f8549b6816a96e1867 \ --hash=sha256:4fb147e7a67ef577a588a0e2c17b6db51dda102c71de36f8549b6816a96e1867 \
--hash=sha256:50550eb667afee136e9a77d6dc71ae76a44df8b3e51e41b77f6de2932bfe0f47 \ --hash=sha256:50550eb667afee136e9a77d6dc71ae76a44df8b3e51e41b77f6de2932bfe0f47 \
--hash=sha256:510c9deebc5c0225e8c96813043e62b680ba2f9c50a08d3724c7f28a747d1486 \ --hash=sha256:510c9deebc5c0225e8c96813043e62b680ba2f9c50a08d3724c7f28a747d1486 \
@ -266,9 +380,12 @@ pyyaml==6.0.1 ; python_version >= "3.9" and python_version < "4" \
--hash=sha256:596106435fa6ad000c2991a98fa58eeb8656ef2325d7e158344fb33864ed87e3 \ --hash=sha256:596106435fa6ad000c2991a98fa58eeb8656ef2325d7e158344fb33864ed87e3 \
--hash=sha256:6965a7bc3cf88e5a1c3bd2e0b5c22f8d677dc88a455344035f03399034eb3007 \ --hash=sha256:6965a7bc3cf88e5a1c3bd2e0b5c22f8d677dc88a455344035f03399034eb3007 \
--hash=sha256:69b023b2b4daa7548bcfbd4aa3da05b3a74b772db9e23b982788168117739938 \ --hash=sha256:69b023b2b4daa7548bcfbd4aa3da05b3a74b772db9e23b982788168117739938 \
--hash=sha256:6c22bec3fbe2524cde73d7ada88f6566758a8f7227bfbf93a408a9d86bcc12a0 \
--hash=sha256:704219a11b772aea0d8ecd7058d0082713c3562b4e271b849ad7dc4a5c90c13c \ --hash=sha256:704219a11b772aea0d8ecd7058d0082713c3562b4e271b849ad7dc4a5c90c13c \
--hash=sha256:7e07cbde391ba96ab58e532ff4803f79c4129397514e1413a7dc761ccd755735 \ --hash=sha256:7e07cbde391ba96ab58e532ff4803f79c4129397514e1413a7dc761ccd755735 \
--hash=sha256:81e0b275a9ecc9c0c0c07b4b90ba548307583c125f54d5b6946cfee6360c733d \ --hash=sha256:81e0b275a9ecc9c0c0c07b4b90ba548307583c125f54d5b6946cfee6360c733d \
--hash=sha256:855fb52b0dc35af121542a76b9a84f8d1cd886ea97c84703eaa6d88e37a2ad28 \
--hash=sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4 \
--hash=sha256:9046c58c4395dff28dd494285c82ba00b546adfc7ef001486fbf0324bc174fba \ --hash=sha256:9046c58c4395dff28dd494285c82ba00b546adfc7ef001486fbf0324bc174fba \
--hash=sha256:9eb6caa9a297fc2c2fb8862bc5370d0303ddba53ba97e71f08023b6cd73d16a8 \ --hash=sha256:9eb6caa9a297fc2c2fb8862bc5370d0303ddba53ba97e71f08023b6cd73d16a8 \
--hash=sha256:a0cd17c15d3bb3fa06978b4e8958dcdc6e0174ccea823003a106c7d4d7899ac5 \ --hash=sha256:a0cd17c15d3bb3fa06978b4e8958dcdc6e0174ccea823003a106c7d4d7899ac5 \
@ -283,46 +400,79 @@ pyyaml==6.0.1 ; python_version >= "3.9" and python_version < "4" \
--hash=sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43 \ --hash=sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43 \
--hash=sha256:c8098ddcc2a85b61647b2590f825f3db38891662cfc2fc776415143f599bb859 \ --hash=sha256:c8098ddcc2a85b61647b2590f825f3db38891662cfc2fc776415143f599bb859 \
--hash=sha256:d2b04aac4d386b172d5b9692e2d2da8de7bfb6c387fa4f801fbf6fb2e6ba4673 \ --hash=sha256:d2b04aac4d386b172d5b9692e2d2da8de7bfb6c387fa4f801fbf6fb2e6ba4673 \
--hash=sha256:d483d2cdf104e7c9fa60c544d92981f12ad66a457afae824d146093b8c294c54 \
--hash=sha256:d858aa552c999bc8a8d57426ed01e40bef403cd8ccdd0fc5f6f04a00414cac2a \ --hash=sha256:d858aa552c999bc8a8d57426ed01e40bef403cd8ccdd0fc5f6f04a00414cac2a \
--hash=sha256:e7d73685e87afe9f3b36c799222440d6cf362062f78be1013661b00c5c6f678b \
--hash=sha256:f003ed9ad21d6a4713f0a9b5a7a0a79e08dd0f221aff4525a2be4c346ee60aab \ --hash=sha256:f003ed9ad21d6a4713f0a9b5a7a0a79e08dd0f221aff4525a2be4c346ee60aab \
--hash=sha256:f22ac1c3cac4dbc50079e965eba2c1058622631e526bd9afd45fedd49ba781fa \ --hash=sha256:f22ac1c3cac4dbc50079e965eba2c1058622631e526bd9afd45fedd49ba781fa \
--hash=sha256:faca3bdcf85b2fc05d06ff3fbc1f83e1391b3e724afa3feba7d13eeab355484c \ --hash=sha256:faca3bdcf85b2fc05d06ff3fbc1f83e1391b3e724afa3feba7d13eeab355484c \
--hash=sha256:fca0e3a251908a499833aa292323f32437106001d436eca0e6e7833256674585 \ --hash=sha256:fca0e3a251908a499833aa292323f32437106001d436eca0e6e7833256674585 \
--hash=sha256:fd1592b3fdf65fff2ad0004b5e363300ef59ced41c2e6b3a99d4089fa8c5435d \ --hash=sha256:fd1592b3fdf65fff2ad0004b5e363300ef59ced41c2e6b3a99d4089fa8c5435d \
--hash=sha256:fd66fc5d0da6d9815ba2cebeb4205f95818ff4b79c3ebe268e75d961704af52f --hash=sha256:fd66fc5d0da6d9815ba2cebeb4205f95818ff4b79c3ebe268e75d961704af52f
redis==5.0.0 ; python_version >= "3.9" and python_version < "4" \ # via
--hash=sha256:06570d0b2d84d46c21defc550afbaada381af82f5b83e5b3777600e05d8e2ed0 \ # django-yunohost-integration
--hash=sha256:5cea6c0d335c9a7332a460ed8729ceabb4d0c489c7285b0a86dbbf8a017bd120 # tablib
requests==2.31.0 ; python_version >= "3.9" and python_version < "4" \ redis==5.0.1 \
--hash=sha256:0dab495cd5753069d3bc650a0dde8a8f9edde16fc5691b689a566eda58100d0f \
--hash=sha256:ed4802971884ae19d640775ba3b03aa2e7bd5e8fb8dfaed2decce4d0fc48391f
# via django-redis
requests==2.31.0 \
--hash=sha256:58cd2187c01e70e6e26505bca751777aa9f2ee0b7f4300988b709f44e013003f \ --hash=sha256:58cd2187c01e70e6e26505bca751777aa9f2ee0b7f4300988b709f44e013003f \
--hash=sha256:942c5a758f98d790eaed1a29cb6eefc7ffb0d1cf7af05c3d2791656dbd6ad1e1 --hash=sha256:942c5a758f98d790eaed1a29cb6eefc7ffb0d1cf7af05c3d2791656dbd6ad1e1
setuptools==68.1.2 ; python_version >= "3.9" and python_version < "4" \ # via pyinventory
--hash=sha256:3d4dfa6d95f1b101d695a6160a7626e15583af71a5f52176efa5d39a054d475d \ rich==13.6.0 \
--hash=sha256:3d8083eed2d13afc9426f227b24fd1659489ec107c0e86cec2ffdde5c92e790b --hash=sha256:2b38e2fe9ca72c9a00170a1a2d20c63c790d0e10ef1fe35eba76e1e7b1d7d245 \
six==1.16.0 ; python_version >= "3.9" and python_version < "4" \ --hash=sha256:5c14d22737e6d5084ef4771b62d5d4363165b403455a30a1c8ca39dc7b644bef
# via
# cli-base-utilities
# rich-click
rich-click==1.7.1 \
--hash=sha256:660c8ea345343f47c5de88f62afa34a19d9f4c7accdd9c6e39dc17eece6affcd \
--hash=sha256:c37d19af85c86b9a256c18e9d23637ae89478300ec8dc5e220c6ca213675f2f9
# via cli-base-utilities
six==1.16.0 \
--hash=sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926 \ --hash=sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926 \
--hash=sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254 --hash=sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254
sqlparse==0.4.4 ; python_version >= "3.9" and python_version < "4" \ # via bleach
sqlparse==0.4.4 \
--hash=sha256:5430a4fe2ac7d0f93e66f1efc6e1338a41884b7ddf2a350cedd20ccc4d9d28f3 \ --hash=sha256:5430a4fe2ac7d0f93e66f1efc6e1338a41884b7ddf2a350cedd20ccc4d9d28f3 \
--hash=sha256:d446183e84b8349fa3061f0fe7f06ca94ba65b426946ffebe6e3e8295332420c --hash=sha256:d446183e84b8349fa3061f0fe7f06ca94ba65b426946ffebe6e3e8295332420c
tablib[html,ods,xls,xlsx,yaml]==3.5.0 ; python_version >= "3.9" and python_version < "4" \ # via
# django
# django-debug-toolbar
tablib[html,ods,xls,xlsx,yaml]==3.5.0 \
--hash=sha256:9821caa9eca6062ff7299fa645e737aecff982e6b2b42046928a6413c8dabfd9 \ --hash=sha256:9821caa9eca6062ff7299fa645e737aecff982e6b2b42046928a6413c8dabfd9 \
--hash=sha256:f6661dfc45e1d4f51fa8a6239f9c8349380859a5bfaa73280645f046d6c96e33 --hash=sha256:f6661dfc45e1d4f51fa8a6239f9c8349380859a5bfaa73280645f046d6c96e33
typing-extensions==4.7.1 ; python_version >= "3.9" and python_version < "3.11" \ # via
--hash=sha256:440d5dd3af93b060174bf433bccd69b0babc3b15b1a8dca43789fd7f61514b36 \ # django-import-export
--hash=sha256:b75ddc264f0ba5615db7ba217daeb99701ad295353c45f9e95963337ceeeffb2 # tablib
tzdata==2023.3 ; python_version >= "3.9" and python_version < "4" and sys_platform == "win32" \ tomlkit==0.12.1 \
--hash=sha256:11ef1e08e54acb0d4f95bdb1be05da659673de4acbd21bf9c69e94cc5e907a3a \ --hash=sha256:38e1ff8edb991273ec9f6181244a6a391ac30e9f5098e7535640ea6be97a7c86 \
--hash=sha256:7e65763eef3120314099b6939b5546db7adce1e7d6f2e179e3df563c70511eda --hash=sha256:712cbd236609acc6a3e2e97253dfc52d4c2082982a88f61b640ecf0817eab899
urllib3==2.0.4 ; python_version >= "3.9" and python_version < "4" \ # via cli-base-utilities
--hash=sha256:8d22f86aae8ef5e410d4f539fde9ce6b2113a001bb4d189e0aed70642d602b11 \ typing-extensions==4.8.0 \
--hash=sha256:de7df1803967d2c2a98e4b11bb7d6bd9210474c46e8a0401514e3a42a75ebde4 --hash=sha256:8f92fc8806f9a6b641eaa5318da32b44d401efaac0f6678c9bc448ba3605faa0 \
webencodings==0.5.1 ; python_version >= "3.9" and python_version < "4" \ --hash=sha256:df8e4339e9cb77357558cbdbceca33c303714cf861d1eef15e1070055ae8b7ef
# via rich-click
urllib3==2.0.7 \
--hash=sha256:c97dfde1f7bd43a71c8d2a58e369e9b2bf692d1334ea9f9cae55add7d0dd0f84 \
--hash=sha256:fdb6d215c776278489906c2f8916e6e7d4f5a9b602ccbcfdf7f016fc8da0596e
# via requests
webencodings==0.5.1 \
--hash=sha256:a0af1213f3c2226497a97e2b3aa01a7e4bee4f403f95be16fc9acd2947514a78 \ --hash=sha256:a0af1213f3c2226497a97e2b3aa01a7e4bee4f403f95be16fc9acd2947514a78 \
--hash=sha256:b36a1c245f2d304965eb4e0a82848379241dc04b865afcc4aab16748587e1923 --hash=sha256:b36a1c245f2d304965eb4e0a82848379241dc04b865afcc4aab16748587e1923
xlrd==2.0.1 ; python_version >= "3.9" and python_version < "4" \ # via bleach
xlrd==2.0.1 \
--hash=sha256:6a33ee89877bd9abc1158129f6e94be74e2679636b8a205b43b85206c3f0bbdd \ --hash=sha256:6a33ee89877bd9abc1158129f6e94be74e2679636b8a205b43b85206c3f0bbdd \
--hash=sha256:f72f148f54442c6b056bf931dbc34f986fd0c3b0b6b5a58d013c9aef274d0c88 --hash=sha256:f72f148f54442c6b056bf931dbc34f986fd0c3b0b6b5a58d013c9aef274d0c88
xlwt==1.3.0 ; python_version >= "3.9" and python_version < "4" \ # via tablib
xlwt==1.3.0 \
--hash=sha256:a082260524678ba48a297d922cc385f58278b8aa68741596a87de01a9c628b2e \ --hash=sha256:a082260524678ba48a297d922cc385f58278b8aa68741596a87de01a9c628b2e \
--hash=sha256:c59912717a9b28f1a3c2a98fd60741014b06b043936dcecbc113eaaada156c88 --hash=sha256:c59912717a9b28f1a3c2a98fd60741014b06b043936dcecbc113eaaada156c88
# via tablib
# The following packages are considered to be unsafe in a requirements file:
setuptools==68.2.2 \
--hash=sha256:4ac1475276d2f1c48684874089fefcd83bd7162ddaafb81fac866ba0db282a87 \
--hash=sha256:b454a35605876da60632df1a60f736524eb73cc47bbc9f3f1ef1b644de74fd2a
# via django-axes

115
dev-cli.py Executable file
View file

@ -0,0 +1,115 @@
#!/usr/bin/env python3
"""
bootstrap CLI
~~~~~~~~~~~~~
Just call this file, and the magic happens ;)
"""
import hashlib
import subprocess
import sys
import venv
from pathlib import Path
def print_no_pip_error():
print('Error: Pip not available!')
print('Hint: "apt-get install python3-venv"\n')
try:
from ensurepip import version
except ModuleNotFoundError as err:
print(err)
print('-' * 100)
print_no_pip_error()
raise
else:
if not version():
print_no_pip_error()
sys.exit(-1)
assert sys.version_info >= (3, 9), 'Python version is too old!'
if sys.platform == 'win32': # wtf
# Files under Windows, e.g.: .../.venv/Scripts/python.exe
BIN_NAME = 'Scripts'
FILE_EXT = '.exe'
else:
# Files under Linux/Mac and all other than Windows, e.g.: .../.venv/bin/python
BIN_NAME = 'bin'
FILE_EXT = ''
BASE_PATH = Path(__file__).parent
VENV_PATH = BASE_PATH / '.venv'
BIN_PATH = VENV_PATH / BIN_NAME
PYTHON_PATH = BIN_PATH / f'python{FILE_EXT}'
PIP_PATH = BIN_PATH / f'pip{FILE_EXT}'
PIP_SYNC_PATH = BIN_PATH / f'pip-sync{FILE_EXT}'
DEP_LOCK_PATH = BASE_PATH / 'requirements.dev.txt'
DEP_HASH_PATH = VENV_PATH / '.dep_hash'
# script file defined in pyproject.toml as [console_scripts]
# (Under Windows: ".exe" not added!)
PROJECT_SHELL_SCRIPT = BIN_PATH / 'pyinventory_ynh_dev'
def get_dep_hash():
"""Get SHA512 hash from lock file content."""
return hashlib.sha512(DEP_LOCK_PATH.read_bytes()).hexdigest()
def store_dep_hash():
"""Generate .venv/.dep_hash"""
DEP_HASH_PATH.write_text(get_dep_hash())
def venv_up2date():
"""Is existing .venv is up-to-date?"""
if DEP_HASH_PATH.is_file():
return DEP_HASH_PATH.read_text() == get_dep_hash()
return False
def verbose_check_call(*popen_args):
print(f'\n+ {" ".join(str(arg) for arg in popen_args)}\n')
return subprocess.check_call(popen_args)
def main(argv):
assert DEP_LOCK_PATH.is_file(), f'File not found: "{DEP_LOCK_PATH}" !'
# Create virtual env in ".venv/":
if not PYTHON_PATH.is_file():
print('Create virtual env here:', VENV_PATH.absolute())
builder = venv.EnvBuilder(symlinks=True, upgrade=True, with_pip=True)
builder.create(env_dir=VENV_PATH)
# Update pip
verbose_check_call(PYTHON_PATH, '-m', 'pip', 'install', '-U', 'pip')
if not PIP_SYNC_PATH.is_file():
# Install 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"
verbose_check_call(PIP_SYNC_PATH, str(DEP_LOCK_PATH))
# install project
verbose_check_call(PIP_PATH, 'install', '--no-deps', '-e', '.')
store_dep_hash()
# Call our entry point CLI:
try:
verbose_check_call(PROJECT_SHELL_SCRIPT, *argv[1:])
except subprocess.CalledProcessError as err:
sys.exit(err.returncode)
if __name__ == '__main__':
main(sys.argv)

View file

@ -1,32 +0,0 @@
"""
Build a "local_test" YunoHost installation and start the Django dev. server against it.
Run via:
make local-test
see README for details ;)
"""
from pathlib import Path
try:
from django_yunohost_integration.local_test import create_local_test
except ImportError as err:
raise ImportError('Did you forget to activate a virtual environment?') from err
BASE_PATH = Path(__file__).parent
def main():
create_local_test(
django_settings_path=BASE_PATH / 'conf' / 'settings.py',
destination=BASE_PATH / 'local_test',
runserver=True,
extra_replacements={
'__DEBUG_ENABLED__': '1',
},
)
if __name__ == '__main__':
main()

View file

@ -5,7 +5,7 @@ id = "pyinventory"
name = "PyInventory" name = "PyInventory"
description.en = "Web based management to catalog things including state and location etc." description.en = "Web based management to catalog things including state and location etc."
version = "0.19.2~ynh1" version = "0.19.3~ynh1"
maintainers = ["Jens Diemer"] maintainers = ["Jens Diemer"]

2174
poetry.lock generated

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,7 @@
"""
pyinventory_ynh
Web based management to catalog things including state and location etc.
"""
__version__ = '0.19.3+ynh1'
__author__ = 'Jens Diemer <pyinventory_ynh@jensdiemer.de>'

View file

370
pyinventory_ynh/cli/dev.py Normal file
View file

@ -0,0 +1,370 @@
"""
CLI for development
"""
import logging
import sys
from pathlib import Path
import rich_click as click
from bx_py_utils.path import assert_is_file
from cli_base.cli_tools.subprocess_utils import verbose_check_call
from cli_base.cli_tools.version_info import print_version
from django_yunohost_integration.local_test import create_local_test
from manageprojects.utilities import code_style
from manageprojects.utilities.publish import publish_package
from rich import print # noqa; noqa
from rich_click import RichGroup
import pyinventory_ynh
logger = logging.getLogger(__name__)
PACKAGE_ROOT = Path(pyinventory_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_FALSE = dict(is_flag=True, show_default=True, default=False)
ARGUMENT_EXISTING_DIR = dict(
type=click.Path(exists=True, file_okay=False, dir_okay=True, readable=True, path_type=Path)
)
ARGUMENT_NOT_EXISTING_DIR = dict(
type=click.Path(
exists=False,
file_okay=False,
dir_okay=True,
readable=False,
writable=True,
path_type=Path,
)
)
ARGUMENT_EXISTING_FILE = dict(
type=click.Path(exists=True, file_okay=True, dir_okay=False, readable=True, path_type=Path)
)
class ClickGroup(RichGroup): # FIXME: How to set the "info_name" easier?
def make_context(self, info_name, *args, **kwargs):
info_name = './dev-cli.py'
return super().make_context(info_name, *args, **kwargs)
@click.group(
cls=ClickGroup,
epilog='Project Homepage: https://github.com/YunoHost-Apps/pyinventory_ynh',
)
def cli():
pass
@click.command()
@click.option('--verbose/--no-verbose', **OPTION_ARGS_DEFAULT_FALSE)
def mypy(verbose: bool = True):
"""Run Mypy (configured in pyproject.toml)"""
verbose_check_call('mypy', '.', cwd=PACKAGE_ROOT, verbose=verbose, exit_on_error=True)
cli.add_command(mypy)
@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=30', 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():
"""
Run pip-sync and install 'pyinventory_ynh' via pip as editable.
"""
verbose_check_call('pip-sync', PACKAGE_ROOT / 'requirements.dev.txt')
verbose_check_call('pip', 'install', '--no-deps', '-e', '.')
cli.add_command(install)
@click.command()
def safety():
"""
Run safety check against current requirements files
"""
verbose_check_call('safety', 'check', '-r', 'requirements.dev.txt')
cli.add_command(safety)
@click.command()
def update():
"""
Update "requirements*.txt" dependencies files
"""
bin_path = Path(sys.executable).parent
verbose_check_call(bin_path / 'pip', 'install', '-U', 'pip')
verbose_check_call(bin_path / 'pip', 'install', '-U', 'pip-tools')
extra_env = dict(
CUSTOM_COMPILE_COMMAND='./dev-cli.py update',
)
pip_compile_base = [
bin_path / 'pip-compile',
'--verbose',
'--allow-unsafe', # https://pip-tools.readthedocs.io/en/latest/#deprecations
'--resolver=backtracking', # https://pip-tools.readthedocs.io/en/latest/#deprecations
'--upgrade',
'--generate-hashes',
]
# Only "prod" dependencies:
verbose_check_call(
*pip_compile_base,
'pyproject.toml',
'--output-file',
'conf/requirements.txt',
extra_env=extra_env,
)
# dependencies + "dev"-optional-dependencies:
verbose_check_call(
*pip_compile_base,
'pyproject.toml',
'--extra=dev',
'--output-file',
'requirements.dev.txt',
extra_env=extra_env,
)
verbose_check_call(bin_path / 'safety', 'check', '-r', 'requirements.dev.txt')
# Install new dependencies in current .venv:
verbose_check_call(bin_path / 'pip-sync', 'requirements.dev.txt')
cli.add_command(update)
@click.command()
def publish():
"""
Build and upload this project to PyPi
"""
_run_unittest_cli(verbose=False, exit_after_run=False) # Don't publish a broken state
publish_package(
module=pyinventory_ynh,
package_path=PACKAGE_ROOT,
distribution_name='pyinventory_ynh',
)
cli.add_command(publish)
@click.command()
@click.option('--color/--no-color', **OPTION_ARGS_DEFAULT_TRUE)
@click.option('--verbose/--no-verbose', **OPTION_ARGS_DEFAULT_FALSE)
def fix_code_style(color: bool = True, verbose: bool = False):
"""
Fix code style of all pyinventory_ynh source code files via darker
"""
code_style.fix(package_root=PACKAGE_ROOT, color=color, verbose=verbose)
cli.add_command(fix_code_style)
@click.command()
@click.option('--color/--no-color', **OPTION_ARGS_DEFAULT_TRUE)
@click.option('--verbose/--no-verbose', **OPTION_ARGS_DEFAULT_FALSE)
def check_code_style(color: bool = True, verbose: bool = False):
"""
Check code style by calling darker + flake8
"""
code_style.check(package_root=PACKAGE_ROOT, color=color, verbose=verbose)
cli.add_command(check_code_style)
@click.command()
def update_test_snapshot_files():
"""
Update all test snapshot files (by remove and recreate all snapshot files)
"""
def iter_snapshot_files():
yield from PACKAGE_ROOT.rglob('*.snapshot.*')
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:
_run_unittest_cli(
extra_env=dict(
RAISE_SNAPSHOT_ERRORS='0', # Recreate snapshot files without error
),
verbose=False,
exit_after_run=False,
)
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_unittest_cli(extra_env=None, verbose=True, exit_after_run=True):
"""
Call the origin unittest CLI and pass all args to it.
"""
if extra_env is None:
extra_env = dict()
extra_env.update(
dict(
PYTHONUNBUFFERED='1',
PYTHONWARNINGS='always',
)
)
args = sys.argv[2:]
if not args:
if verbose:
args = ('--verbose', '--locals', '--buffer')
else:
args = ('--locals', '--buffer')
verbose_check_call(
sys.executable,
'-m',
'unittest',
*args,
timeout=15 * 60,
extra_env=extra_env,
)
if exit_after_run:
sys.exit(0)
@click.command() # Dummy command
def test():
"""
Run unittests
"""
_run_unittest_cli()
# TODO: Replace pytest with normal Django unittests:
# cli.add_command(test)
def _run_tox():
verbose_check_call(sys.executable, '-m', 'tox', *sys.argv[2:])
sys.exit(0)
@click.command() # Dummy "tox" command
def tox():
"""
Run tox
"""
_run_tox()
# TODO: cli.add_command(tox)
@click.command()
def version():
"""Print version and exit"""
# Pseudo command, because the version always printed on every CLI call ;)
sys.exit(0)
cli.add_command(version)
@click.command()
def local_test():
"""
Build a "local_test" YunoHost installation and start the Django dev. server against it.
"""
create_local_test(
django_settings_path=PACKAGE_ROOT / 'conf' / 'settings.py',
destination=PACKAGE_ROOT / 'local_test',
runserver=True,
extra_replacements={
'__DEBUG_ENABLED__': '1',
},
)
cli.add_command(local_test)
@click.command()
def diffsettings():
"""
Run "diffsettings" manage command against a "local_test" YunoHost installation.
"""
destination = PACKAGE_ROOT / 'local_test'
create_local_test(
django_settings_path=PACKAGE_ROOT / 'conf' / 'settings.py',
destination=destination,
runserver=False,
extra_replacements={
'__DEBUG_ENABLED__': '1',
},
)
app_path = destination / 'opt_yunohost'
verbose_check_call(sys.executable, app_path / 'manage.py', 'diffsettings', cwd=app_path)
cli.add_command(diffsettings)
@click.command()
def pytest():
"""
Run tests via "pytest"
"""
verbose_check_call(sys.executable, '-m', 'pytest', *sys.argv[2:], cwd=PACKAGE_ROOT)
cli.add_command(pytest)
def main():
print_version(pyinventory_ynh)
if len(sys.argv) >= 2:
# Check if we just pass a command call
command = sys.argv[1]
if command == 'test':
# TODO: Call: _run_unittest_cli()
verbose_check_call(sys.executable, '-m', 'pytest', cwd=PACKAGE_ROOT)
sys.exit(0)
elif command == 'tox':
_run_tox()
# Execute Click CLI:
cli()

View file

@ -0,0 +1,6 @@
import os
import unittest.util
# Hacky way to expand the failed test output:
unittest.util._MAX_LENGTH = os.environ.get('UNITTEST_MAX_LENGTH', 300)

View file

@ -0,0 +1,10 @@
from bx_py_utils.test_utils.unittest_utils import BaseDocTests
import pyinventory_ynh
class DocTests(BaseDocTests):
def test_doctests(self):
self.run_doctests(
modules=(pyinventory_ynh,),
)

View file

@ -0,0 +1,68 @@
import subprocess
from unittest import TestCase
from bx_py_utils.path import assert_is_file
from manageprojects.test_utils.click_cli_utils import subprocess_cli
from manageprojects.test_utils.project_setup import check_editor_config, get_py_max_line_length
from manageprojects.utilities import code_style
from packaging.version import Version
from pyinventory_ynh import __version__
from pyinventory_ynh.cli.dev import PACKAGE_ROOT
class ProjectSetupTestCase(TestCase):
def test_version(self):
self.assertIsNotNone(__version__)
version = Version(__version__) # Will raise InvalidVersion() if wrong formatted
self.assertEqual(str(version), __version__)
dev_cli_bin = PACKAGE_ROOT / 'dev-cli.py'
assert_is_file(dev_cli_bin)
output = subprocess.check_output([dev_cli_bin, 'version'], text=True)
self.assertIn(f'pyinventory_ynh v{__version__}', output)
def test_code_style(self):
dev_cli_bin = PACKAGE_ROOT / 'dev-cli.py'
assert_is_file(dev_cli_bin)
try:
output = subprocess_cli(
cli_bin=dev_cli_bin,
args=('check-code-style',),
exit_on_error=False,
)
except subprocess.CalledProcessError as err:
self.assertIn('.venv/bin/darker', err.stdout) # darker was called?
else:
if 'Code style: OK' in output:
self.assertIn('.venv/bin/darker', output) # darker was called?
return # Nothing to fix -> OK
# Try to "auto" fix code style:
try:
output = subprocess_cli(
cli_bin=dev_cli_bin,
args=('fix-code-style',),
exit_on_error=False,
)
except subprocess.CalledProcessError as err:
output = err.stdout
self.assertIn('.venv/bin/darker', output) # darker was called?
# Check again and display the output:
try:
code_style.check(package_root=PACKAGE_ROOT)
except SystemExit as err:
self.assertEqual(err.code, 0, 'Code style error, see output above!')
def test_check_editor_config(self):
check_editor_config(package_root=PACKAGE_ROOT)
max_line_length = get_py_max_line_length(package_root=PACKAGE_ROOT)
self.assertEqual(max_line_length, 119)

View file

@ -1,62 +1,87 @@
[tool.poetry] [project]
name = "pyinventory_ynh" name = "pyinventory_ynh"
description = "YunoHost app package for: https://github.com/jedie/PyInventory" dynamic = ["version"]
version = "0.19.2+ynh1" description = "Web based management to catalog things including state and location etc."
authors = ["Jens Diemer <pyinventory_ynh@jensdiemer.de>"] license = {text = "GPL-3.0-or-later"}
homepage = "https://github.com/YunoHost-Apps/pyinventory_ynh" readme = "README.md"
license = "GPL-3.0-or-later" authors = [
readme = 'README.md' {name = 'Jens Diemer', email = 'pyinventory_ynh@jensdiemer.de'}
]
requires-python = ">=3.9" # Stay with 3.9 until YunoHost used >=Debian 11 (Bullseye)
dependencies = [
"pyinventory", # https://github.com/jedie/PyInventory
#
# extras "ynh" will install: gunicorn, psycopg2, django-redis and django-axes
# see: https://github.com/YunoHost-Apps/django_yunohost_integration/blob/main/pyproject.toml
"django_yunohost_integration[ynh]>=0.6.0", # https://github.com/YunoHost-Apps/django_yunohost_integration
#
"cli-base-utilities>=0.4.4", # https://github.com/jedie/cli-base-utilities
#
# indirect depencies, added because we didn't create the requirements.txt with Python <3.11
# See: https://github.com/jazzband/pip-tools/issues/1326
"async-timeout", # needed by redis for python<=3.11.2
]
[project.optional-dependencies]
dev = [
"bx_django_utils", # https://github.com/boxine/bx_django_utils
"beautifulsoup4", # https://pypi.org/project/beautifulsoup4/
#
# TODO: Remove "pytest" and use normal unittests ;)
"pytest",
"pytest-cov",
"pytest-django",
#
"manageprojects>=0.15.0", # https://github.com/jedie/manageprojects
"pip-tools", # https://github.com/jazzband/pip-tools/
"tox", # https://github.com/tox-dev/tox
"coverage", # https://github.com/nedbat/coveragepy
"autopep8", # https://github.com/hhatto/autopep8
"pyupgrade", # https://github.com/asottile/pyupgrade
"flake8", # https://github.com/pycqa/flake8
"pyflakes", # https://github.com/PyCQA/pyflakes
"codespell", # https://github.com/codespell-project/codespell
"EditorConfig", # https://github.com/editorconfig/editorconfig-core-py
"safety", # https://github.com/pyupio/safety
"mypy", # https://github.com/python/mypy
"twine", # https://github.com/pypa/twine
[tool.poetry.urls] # https://github.com/akaihola/darker
"Bug Tracker" = "https://github.com/jedie/PyInventory/issues" # https://github.com/ikamensh/flynt
# https://github.com/pycqa/isort
# https://github.com/pygments/pygments
"darker[flynt, isort, color]",
[tool.poetry.dependencies] # indirect depencies added because of bug:
python = ">=3.9,<4.0.0" # Stay with 3.9 until YunoHost used >=Debian 11 (Bullseye) # https://github.com/pypa/pip/issues/9644 / https://github.com/jazzband/pip-tools/issues/1866
# # to avoid errors like:
pyinventory = ">=0.19.2" # https://github.com/jedie/PyInventory # In --require-hashes mode, all requirements must have their versions pinned with ==. These do not: ...
# "tomli", # Only needed for Python <3.11
# extras "ynh" will install: gunicorn, psycopg2, django-redis and django-axes "exceptiongroup", # needed by pytest
# see: https://github.com/YunoHost-Apps/django_yunohost_integration/blob/main/pyproject.toml ]
django_yunohost_integration = {version = ">=0.6.0", extras = ["ynh"]} # https://github.com/YunoHost-Apps/django_yunohost_integration
[project.urls]
Documentation = "https://github.com/YunoHost-Apps/pyinventory_ynh"
Source = "https://github.com/YunoHost-Apps/pyinventory_ynh"
[tool.poetry.dev-dependencies] [project.scripts]
cli-base-utilities = "*" # https://github.com/jedie/cli-base-utilities pyinventory_ynh_app = "pyinventory_ynh.__main__:main"
bx_py_utils = "*" # https://github.com/boxine/bx_py_utils pyinventory_ynh_dev = "pyinventory_ynh.cli.dev:main"
bx_django_utils = "*" # https://github.com/boxine/bx_django_utils
tox = ">=4.4.4" # https://github.com/tox-dev/tox
coverage= "*" # https://github.com/nedbat/coveragepy
flake8 = "*" # https://github.com/pycqa/flake8
EditorConfig = "*" # https://github.com/editorconfig/editorconfig-core-py
safety = "*" # https://github.com/pyupio/safety
mypy = "*" # https://github.com/python/mypy
twine = "*" # https://github.com/pypa/twine
poetry-publish = "*" # https://github.com/jedie/poetry-publish
pytest = "*"
pytest-cov = "*"
pytest-django = "*"
requests = "*" # https://github.com/psf/requests
packaging = "*" # https://github.com/pypa/packagi
beautifulsoup4 = "*" # https://pypi.org/project/beautifulsoup4/
# https://github.com/akaihola/darker
# https://github.com/ikamensh/flynt
# https://github.com/pycqa/isort
# https://github.com/pygments/pygments
darker = { version = "*", extras = ["flynt", "isort", "color"] }
tomli = "*" # https://github.com/hukkin/tomli
# tomli only needed for Python <3.11, but see bug:
# https://github.com/pypa/pip/issues/9644#issuecomment-1456583402
#tomli = {version = "*", markers = "python_version < \"3.11\""} # https://github.com/hukkin/tomli
[build-system] [build-system]
requires = ["poetry-core"] requires = ["setuptools>=61.0", "setuptools_scm>=7.1"]
build-backend = "poetry.core.masonry.api" build-backend = "setuptools.build_meta"
[tool.setuptools.packages.find]
where = ["."]
include = ["pyinventory_ynh*"]
[tool.setuptools.dynamic]
version = {attr = "pyinventory_ynh.__version__"}
[tool.darker] [tool.darker]
src = ['.'] src = ['.']
# YunoHost apps still use "master" istead of "main", isn't it?
revision = "origin/master..." revision = "origin/master..."
line_length = 119 line_length = 119
verbose = true verbose = true
@ -78,7 +103,7 @@ log_level = "INFO"
atomic=true atomic=true
profile='black' profile='black'
skip_glob=[".*", "*/htmlcov/*","*/migrations/*","*/local_test/*"] skip_glob=[".*", "*/htmlcov/*","*/migrations/*","*/local_test/*"]
known_first_party=['inventory', 'inventory_project'] known_first_party=['inventory', 'inventory_project', 'pyinventory_ynh']
line_length=119 line_length=119
lines_after_imports=2 lines_after_imports=2
@ -115,6 +140,10 @@ branch = true
parallel = true parallel = true
concurrency = ["multiprocessing"] concurrency = ["multiprocessing"]
source = ['.'] source = ['.']
# TODO: pytest -> Django unitests:
#command_line = '-m unittest --verbose --locals --buffer'
command_line = '-m pytest'
disable_warnings = ["couldnt-parse"]
[tool.coverage.report] [tool.coverage.report]
omit = ['.*', '*/tests/*'] omit = ['.*', '*/tests/*']
@ -133,18 +162,32 @@ exclude_lines = [
legacy_tox_ini = """ legacy_tox_ini = """
[tox] [tox]
isolated_build = True isolated_build = True
envlist = py{311,310,39} envlist = py{312,311,310,39}
skip_missing_interpreters = True skip_missing_interpreters = True
[testenv] [testenv]
passenv = * passenv = *
skip_install = true skip_install = true
allowlist_externals = make commands_pre =
pip install -U pip-tools
pip-sync requirements.dev.txt
commands = commands =
make pytest {envpython} -m coverage run --context='{envname}'
{envpython} -m coverage combine --append
{envpython} -m coverage xml
{envpython} -m coverage report
""" """
[tool.mypy]
warn_unused_configs = true
ignore_missing_imports = true
allow_redefinition = true # https://github.com/python/mypy/issues/7165
show_error_codes = true
plugins = []
exclude = ['.venv', 'tests']
[manageprojects] # https://github.com/jedie/manageprojects [manageprojects] # https://github.com/jedie/manageprojects
initial_revision = "b204761" initial_revision = "b204761"
initial_date = 2022-12-21T20:25:20+01:00 initial_date = 2022-12-21T20:25:20+01:00
@ -169,4 +212,5 @@ _template = "https://github.com/jedie/cookiecutter_templates/"
applied_migrations = [ applied_migrations = [
"877e2ec", # 2023-08-17T20:54:24+02:00 "877e2ec", # 2023-08-17T20:54:24+02:00
"be3f649", # 2023-08-22T19:36:57+02:00 "be3f649", # 2023-08-22T19:36:57+02:00
"c1a9d97", # 2023-11-01T19:59:17+01:00
] ]

1139
requirements.dev.txt Normal file

File diff suppressed because it is too large Load diff

View file

@ -4,7 +4,7 @@
<div id="branding"> <div id="branding">
<h1 id="site-name"> <h1 id="site-name">
<a href="/app_path/"> <a href="/app_path/">
PyInventory v0.19.2 PyInventory v0.19.3
</a> </a>
</h1> </h1>
</div> </div>

View file

@ -1,7 +1,4 @@
import difflib
import os import os
import shutil
import subprocess
from pathlib import Path from pathlib import Path
from unittest import TestCase from unittest import TestCase
@ -16,7 +13,8 @@ from bx_py_utils.path import assert_is_dir, assert_is_file
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 django_yunohost_integration.test_utils import assert_project_version
from inventory import __version__ from inventory import __version__ as inventory_version
from pyinventory_ynh import __version__ as pyinventory_ynh_version
PACKAGE_ROOT = Path(__file__).parent.parent PACKAGE_ROOT = Path(__file__).parent.parent
@ -31,68 +29,25 @@ def assert_file_contains_string(file_path, string):
def test_version(): def test_version():
if 'GITHUB_ACTION' not in os.environ: assert inventory_version in pyinventory_ynh_version, f'{inventory_version!r} not in {pyinventory_ynh_version!r}'
# Github has a rate-limiting... So don't fetch the API if we run as GitHub action
assert_project_version(
current_version=__version__,
github_project_url='https://github.com/jedie/PyInventory',
)
pyproject_toml_path = Path(PACKAGE_ROOT, 'pyproject.toml') assert '+ynh' in pyinventory_ynh_version, f'{pyinventory_ynh_version!r} does not contain "+ynh"'
pyproject_toml = tomllib.loads(pyproject_toml_path.read_text(encoding='UTF-8'))
pyproject_version = pyproject_toml['tool']['poetry']['version']
assert pyproject_version.startswith(
f'{__version__}+ynh'
), f'{pyproject_version!r} does not start with "{__version__}+ynh"'
# pyproject.toml needs a PEP 440 conform version and used "+ynh" # pyproject.toml needs a PEP 440 conform version and used "+ynh"
# the YunoHost syntax is: "~ynh", just "convert this: # the YunoHost syntax is: "~ynh", just "convert this:
manifest_version = pyproject_version.replace('+', '~') manifest_version = pyinventory_ynh_version.replace('+', '~')
assert_file_contains_string( assert_file_contains_string(
file_path=Path(PACKAGE_ROOT, 'manifest.toml'), file_path=Path(PACKAGE_ROOT, 'manifest.toml'),
string=f'version = "{manifest_version}"', string=f'version = "{manifest_version}"',
) )
if 'GITHUB_ACTION' not in os.environ:
def poetry_check_output(*args): # Github has a rate-limiting... So don't fetch the API if we run as GitHub action
poerty_bin = shutil.which('poetry') assert_project_version(
current_version=inventory_version,
output = subprocess.check_output( github_project_url='https://github.com/jedie/PyInventory',
(poerty_bin,) + args,
text=True,
env=os.environ,
stderr=subprocess.STDOUT,
cwd=str(PACKAGE_ROOT),
)
print(output)
return output
def test_poetry_check():
output = poetry_check_output('check')
assert output == 'All set!\n'
def test_requirements_txt():
requirements_txt = PACKAGE_ROOT / 'conf' / 'requirements.txt'
assert_is_file(requirements_txt)
output = poetry_check_output('export', '-f', 'requirements.txt')
assert 'Warning' not in output
current_content = requirements_txt.read_text()
diff = '\n'.join(
difflib.unified_diff(
current_content.splitlines(),
output.splitlines(),
fromfile=str(requirements_txt),
tofile='FRESH EXPORT',
) )
)
print(diff)
assert diff == '', f'{requirements_txt} is not up-to-date! (Hint: call: "make update")'
def test_screenshot_filenames(): def test_screenshot_filenames():
@ -118,31 +73,6 @@ def test_check_editor_config():
check_editor_config(package_root=PACKAGE_ROOT) check_editor_config(package_root=PACKAGE_ROOT)
def _call_make(*args):
make_bin = shutil.which('make')
assert make_bin
return subprocess.check_output(
(make_bin,) + args,
text=True,
env=dict(PATH=os.environ['PATH']),
stderr=subprocess.STDOUT,
cwd=str(PACKAGE_ROOT),
)
def test_check_code_style():
# First try:
try:
_call_make('lint')
except subprocess.CalledProcessError:
# Fix and test again:
try:
_call_make('fix-code-style')
_call_make('lint')
except subprocess.CalledProcessError as err:
raise AssertionError(f'Linting error:\n{"-"*100}\n{err.stdout}\n{"-"*100}')
class ManifestTestCase(TestCase): class ManifestTestCase(TestCase):
def test_manifest_toml(self): def test_manifest_toml(self):
manifest_path = PACKAGE_ROOT / 'manifest.toml' manifest_path = PACKAGE_ROOT / 'manifest.toml'