mirror of
https://github.com/YunoHost-Apps/django-for-runners_ynh.git
synced 2024-09-03 18:26:16 +02:00
commit
b1c9fc5b91
8 changed files with 543 additions and 197 deletions
354
conf/install_python.py
Executable file
354
conf/install_python.py
Executable file
|
@ -0,0 +1,354 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
"""
|
||||
DocWrite: install_python.md # Install Python Interpreter
|
||||
|
||||
`install_python.py` downloads, builds and installs a Python interpreter, but:
|
||||
- **only** if the system Python is not the required major version
|
||||
- **only** once (if the required major version is not already build and installed)
|
||||
|
||||
Origin of this script is:
|
||||
* https://github.com/jedie/manageprojects/blob/main/manageprojects/install_python.py
|
||||
|
||||
Licensed under GPL-3.0-or-later (Feel free to copy and use it in your project)
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import hashlib
|
||||
import logging
|
||||
import os
|
||||
import re
|
||||
import shlex
|
||||
import shutil
|
||||
import ssl
|
||||
import subprocess
|
||||
import sys
|
||||
import tempfile
|
||||
import urllib.request
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
"""DocWrite: install_python.md # Install Python Interpreter
|
||||
Minimal needed Python version to run the script is: **v3.9**."""
|
||||
assert sys.version_info >= (3, 9), f'Python version {sys.version_info} is too old!'
|
||||
|
||||
|
||||
DEFAULT_MAJOR_VERSION = '3.11'
|
||||
|
||||
"""DocWrite: install_python.md # Install Python Interpreter
|
||||
Download Python source code from official Python FTP server:
|
||||
DocWriteMacro: manageprojects.tests.docwrite_macros.ftp_url"""
|
||||
PY_FTP_INDEX_URL = 'https://www.python.org/ftp/python/'
|
||||
|
||||
"""DocWrite: install_python.md ## Supported Python Versions
|
||||
The following major Python versions are supported and verified with GPG keys:
|
||||
DocWriteMacro: manageprojects.tests.docwrite_macros.supported_python_versions
|
||||
The GPG keys taken from the official Python download page: https://www.python.org/downloads/"""
|
||||
GPG_KEY_IDS = {
|
||||
# Thomas Wouters (3.12.x and 3.13.x source files and tags):
|
||||
'3.13': 'A821E680E5FA6305',
|
||||
'3.12': 'A821E680E5FA6305',
|
||||
#
|
||||
# Pablo Galindo Salgado (3.10.x and 3.11.x source files and tags):
|
||||
'3.11': '64E628F8D684696D',
|
||||
'3.10': '64E628F8D684696D',
|
||||
}
|
||||
GPG_KEY_SERVER = 'hkps://keys.openpgp.org'
|
||||
|
||||
"""DocWrite: install_python.md ## Workflow - 3. Check local installed Python
|
||||
We assume that the `make altinstall` will install local Python interpreter into:
|
||||
DocWriteMacro: manageprojects.tests.docwrite_macros.default_install_prefix
|
||||
See: https://docs.python.org/3/using/configure.html#cmdoption-prefix"""
|
||||
DEFAULT_INSTALL_PREFIX = '/usr/local'
|
||||
|
||||
TEMP_PREFIX = 'setup_python_'
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class TemporaryDirectory:
|
||||
"""tempfile.TemporaryDirectory in Python 3.9 has no "delete", yet."""
|
||||
|
||||
def __init__(self, prefix, delete: bool):
|
||||
self.prefix = prefix
|
||||
self.delete = delete
|
||||
|
||||
def __enter__(self) -> Path:
|
||||
self.temp_path = Path(tempfile.mkdtemp(prefix=self.prefix))
|
||||
return self.temp_path
|
||||
|
||||
def __exit__(self, exc_type, exc_val, exc_tb):
|
||||
if self.delete:
|
||||
shutil.rmtree(self.temp_path, ignore_errors=True)
|
||||
if exc_type:
|
||||
return False
|
||||
|
||||
|
||||
def fetch(url: str) -> bytes:
|
||||
"""DocWrite: install_python.md # Install Python Interpreter
|
||||
Download only over verified HTTPS connection."""
|
||||
context = ssl.create_default_context(purpose=ssl.Purpose.SERVER_AUTH)
|
||||
with urllib.request.urlopen(url=url, context=context) as response:
|
||||
return response.read()
|
||||
|
||||
|
||||
def get_html_page(url) -> str:
|
||||
logger.debug('Getting HTML page from %s', url)
|
||||
html = fetch(url).decode('utf-8')
|
||||
assert html, 'Failed to get Python FTP index page'
|
||||
return html
|
||||
|
||||
|
||||
def extract_versions(*, html, major_version) -> list[str]:
|
||||
pattern = rf'href="({re.escape(major_version)}\.[0-9]+)'
|
||||
logger.debug('Extracting versions with pattern: %s', pattern)
|
||||
versions = re.findall(pattern, html)
|
||||
versions.sort(reverse=True)
|
||||
logger.debug('Extracted versions: %s', versions)
|
||||
return versions
|
||||
|
||||
|
||||
def get_latest_versions(*, html, major_version) -> str:
|
||||
latest_versions = extract_versions(html=html, major_version=major_version)[0]
|
||||
logger.info('Latest version of Python %s: %s', major_version, latest_versions)
|
||||
return latest_versions
|
||||
|
||||
|
||||
def run(args, **kwargs):
|
||||
logger.debug('Running: %s (%s)', shlex.join(str(arg) for arg in args), kwargs)
|
||||
return subprocess.run(args, **kwargs)
|
||||
|
||||
|
||||
def run_build_step(args, *, step: str, cwd: Path) -> None:
|
||||
with tempfile.NamedTemporaryFile(prefix=f'{TEMP_PREFIX}_{step}_', suffix='.txt', delete=False) as temp_file:
|
||||
logger.info('Running: %s... Output in %s', shlex.join(str(arg) for arg in args), temp_file.name)
|
||||
try:
|
||||
subprocess.run(args, stdout=temp_file, stderr=temp_file, check=True, cwd=cwd)
|
||||
except subprocess.SubprocessError as err:
|
||||
logger.error('Failed to run %s step: %s', step, err)
|
||||
run(['tail', temp_file.name])
|
||||
raise
|
||||
|
||||
|
||||
def get_python_version(python_bin: str | Path) -> str | None:
|
||||
logger.debug('Check %s version', python_bin)
|
||||
if output := run([python_bin, '-V'], capture_output=True, text=True).stdout.split():
|
||||
full_version = output[-1]
|
||||
logger.info('Version of "%s" is: %r', python_bin, full_version)
|
||||
return full_version
|
||||
|
||||
|
||||
def download2temp(*, temp_path: Path, base_url: str, filename: str) -> Path:
|
||||
url = f'{base_url}/{filename}'
|
||||
dst_path = temp_path / filename
|
||||
logger.info('Downloading %s into %s...', url, dst_path)
|
||||
dst_path.write_bytes(fetch(url))
|
||||
logger.info('Downloaded %s is %d Bytes', filename, dst_path.stat().st_size)
|
||||
return dst_path
|
||||
|
||||
|
||||
def verify_download(*, major_version: str, tar_file_path: Path, asc_file_path: Path, delete_temp: bool):
|
||||
"""DocWrite: install_python.md ## Workflow - 5. Verify download
|
||||
The sha256 hash downloaded tar archive will logged.
|
||||
If `gpg` is available, the signature will be verified.
|
||||
"""
|
||||
hash_obj = hashlib.sha256(tar_file_path.read_bytes())
|
||||
logger.info('Downloaded sha256: %s', hash_obj.hexdigest())
|
||||
|
||||
"""DocWrite: install_python.md # Install Python Interpreter
|
||||
The Downloaded tar archive will be verified with the GPG signature, if `gpg` is available."""
|
||||
if gpg_bin := shutil.which('gpg'):
|
||||
logger.debug('Verifying signature with %s...', gpg_bin)
|
||||
assert major_version in GPG_KEY_IDS, f'No GPG key ID for Python {major_version}'
|
||||
gpg_key_id = GPG_KEY_IDS[major_version]
|
||||
with TemporaryDirectory(prefix='install-python-gpg-', delete=delete_temp) as temp_path:
|
||||
"""DocWrite: install_python.md ## Workflow - 5. Verify download
|
||||
We set the `GNUPGHOME` environment variable to a temporary directory."""
|
||||
env = {'GNUPGHOME': str(temp_path)}
|
||||
run([gpg_bin, '--keyserver', GPG_KEY_SERVER, '--recv-keys', gpg_key_id], check=True, env=env)
|
||||
run([gpg_bin, '--verify', asc_file_path, tar_file_path], check=True, env=env)
|
||||
run(['gpgconf', '--kill', 'all'], check=True, env=env)
|
||||
else:
|
||||
logger.warning('No GPG verification possible! (gpg not found)')
|
||||
|
||||
|
||||
def install_python(
|
||||
major_version: str,
|
||||
*,
|
||||
write_check: bool = True,
|
||||
delete_temp: bool = True,
|
||||
) -> Path:
|
||||
logger.info('Requested major Python version: %s', major_version)
|
||||
|
||||
"""DocWrite: install_python.md ## Workflow
|
||||
The setup process is as follows:"""
|
||||
|
||||
"""DocWrite: install_python.md ## Workflow - 1. Check system Python
|
||||
If the system Python is the same major version as the required Python, we skip the installation."""
|
||||
for try_version in (major_version, '3'):
|
||||
filename = f'python{try_version}'
|
||||
logger.debug('Checking %s...', filename)
|
||||
if python3bin := shutil.which(filename):
|
||||
if (full_version := get_python_version(python3bin)) and full_version.startswith(major_version):
|
||||
logger.info('Python version already installed: Return path %r of it.', python3bin)
|
||||
"""DocWrite: install_python.md ## Workflow - 1. Check system Python
|
||||
The script just returns the path to the system Python interpreter."""
|
||||
return Path(python3bin)
|
||||
|
||||
"""DocWrite: install_python.md ## Workflow - 2. Get latest Python release
|
||||
We fetch the latest Python release from the Python FTP server, from:
|
||||
DocWriteMacro: manageprojects.tests.docwrite_macros.ftp_url"""
|
||||
# Get latest full version number of Python from Python FTP:
|
||||
py_required_version = get_latest_versions(
|
||||
html=get_html_page(PY_FTP_INDEX_URL),
|
||||
major_version=major_version,
|
||||
)
|
||||
|
||||
local_bin_path = Path(DEFAULT_INSTALL_PREFIX) / 'bin'
|
||||
|
||||
"""DocWrite: install_python.md ## Workflow - 3. Check local installed Python
|
||||
The script checks if the latest release already build and installed."""
|
||||
local_python_path = local_bin_path / f'python{major_version}'
|
||||
if local_python_path.exists() and get_python_version(local_python_path) == py_required_version:
|
||||
logger.info('Local Python is up-to-date')
|
||||
"""DocWrite: install_python.md ## Workflow - 3. Check local installed Python
|
||||
If the local Python is up-to-date, the script exist and returns the path this local interpreter."""
|
||||
return local_python_path
|
||||
|
||||
"""DocWrite: install_python.md ## Workflow - 4. Download Python sources
|
||||
Before we start building Python, check if we have write permissions.
|
||||
The check can be skipped via CLI argument."""
|
||||
if write_check and not os.access(local_bin_path, os.W_OK):
|
||||
raise PermissionError(f'No write permission to {local_bin_path} (Hint: Call with "sudo" ?!)')
|
||||
|
||||
"""DocWrite: install_python.md ## Workflow - 4. Download Python sources
|
||||
The download will be done in a temporary directory. The directory will be deleted after the installation.
|
||||
This can be skipped via CLI argument. The directory will be prefixed with:
|
||||
DocWriteMacro: manageprojects.tests.docwrite_macros.temp_prefix"""
|
||||
with TemporaryDirectory(prefix=TEMP_PREFIX, delete=delete_temp) as temp_path:
|
||||
base_url = f'{PY_FTP_INDEX_URL}{py_required_version}'
|
||||
|
||||
tar_filename = f'Python-{py_required_version}.tar.xz'
|
||||
asc_filename = f'{tar_filename}.asc'
|
||||
asc_file_path = download2temp(
|
||||
temp_path=temp_path,
|
||||
base_url=base_url,
|
||||
filename=asc_filename,
|
||||
)
|
||||
tar_file_path = download2temp(
|
||||
temp_path=temp_path,
|
||||
base_url=base_url,
|
||||
filename=tar_filename,
|
||||
)
|
||||
verify_download(
|
||||
major_version=major_version,
|
||||
tar_file_path=tar_file_path,
|
||||
asc_file_path=asc_file_path,
|
||||
delete_temp=delete_temp,
|
||||
)
|
||||
|
||||
tar_bin = shutil.which('tar')
|
||||
logger.debug('Extracting %s with ...', tar_file_path)
|
||||
run([tar_bin, 'xf', tar_file_path], check=True, cwd=temp_path)
|
||||
extracted_dir = temp_path / f'Python-{py_required_version}'
|
||||
|
||||
logger.info('Building Python %s (may take a while)...', py_required_version)
|
||||
|
||||
"""DocWrite: install_python.md ## Workflow - 6. Build and install Python
|
||||
If the verify passed, the script will start the build process."""
|
||||
run_build_step(
|
||||
['./configure', '--enable-optimizations'],
|
||||
step='configure',
|
||||
cwd=extracted_dir,
|
||||
)
|
||||
run_build_step(
|
||||
['make', f'-j{os.cpu_count()}'],
|
||||
step='make',
|
||||
cwd=extracted_dir,
|
||||
)
|
||||
|
||||
"""DocWrite: install_python.md ## Workflow - 6. Build and install Python
|
||||
The installation will be done with `make altinstall`."""
|
||||
run_build_step(
|
||||
['make', 'altinstall'],
|
||||
step='install',
|
||||
cwd=extracted_dir,
|
||||
)
|
||||
|
||||
logger.info('Python %s installed to %s', py_required_version, local_python_path)
|
||||
|
||||
local_python_version = get_python_version(local_python_path)
|
||||
assert local_python_version == py_required_version, f'{local_python_version} is not {py_required_version}'
|
||||
|
||||
return local_python_path
|
||||
|
||||
|
||||
def get_parser() -> argparse.ArgumentParser:
|
||||
"""
|
||||
DocWrite: install_python.md ## CLI
|
||||
The CLI interface looks like e.g.:
|
||||
```shell
|
||||
$ python3 install_python.py --help
|
||||
|
||||
DocWriteMacro: manageprojects.tests.docwrite_macros.help
|
||||
```
|
||||
"""
|
||||
parser = argparse.ArgumentParser(
|
||||
description='Install Python Interpreter',
|
||||
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
'major_version',
|
||||
nargs=argparse.OPTIONAL,
|
||||
default=DEFAULT_MAJOR_VERSION,
|
||||
choices=sorted(GPG_KEY_IDS.keys()),
|
||||
help='Specify the Python version',
|
||||
)
|
||||
parser.add_argument(
|
||||
'-v',
|
||||
'--verbose',
|
||||
action='count',
|
||||
default=0,
|
||||
help='Increase verbosity level (can be used multiple times, e.g.: -vv)',
|
||||
)
|
||||
parser.add_argument(
|
||||
'--skip-temp-deletion',
|
||||
action='store_true',
|
||||
help='Skip deletion of temporary files',
|
||||
)
|
||||
parser.add_argument(
|
||||
'--skip-write-check',
|
||||
action='store_true',
|
||||
help='Skip the test for write permission to /usr/local/bin',
|
||||
)
|
||||
return parser
|
||||
|
||||
|
||||
def main() -> Path:
|
||||
parser = get_parser()
|
||||
args = parser.parse_args()
|
||||
verbose2level = {0: logging.WARNING, 1: logging.INFO, 2: logging.DEBUG}
|
||||
logging.basicConfig(
|
||||
level=verbose2level.get(args.verbose, logging.DEBUG),
|
||||
format='%(levelname)9s %(message)s',
|
||||
stream=sys.stderr,
|
||||
)
|
||||
logger.debug('Arguments: %s', args)
|
||||
return install_python(
|
||||
major_version=args.major_version,
|
||||
write_check=not args.skip_write_check,
|
||||
delete_temp=not args.skip_temp_deletion,
|
||||
)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
python_path = main()
|
||||
|
||||
"""DocWrite: install_python.md ## Workflow - 7. print the path
|
||||
If no errors occurred, the path to the Python interpreter will be printed to `stdout`.
|
||||
So it's usable in shell scripts, like:
|
||||
DocWriteMacro: manageprojects.tests.docwrite_macros.example_shell_script
|
||||
"""
|
||||
print(python_path)
|
|
@ -41,9 +41,9 @@ bx-py-utils==98 \
|
|||
# cli-base-utilities
|
||||
# django-for-runners
|
||||
# django-tools
|
||||
cattrs==23.2.3 \
|
||||
--hash=sha256:0341994d94971052e9ee70662542699a3162ea1e0c62f7ce1b4a57f563685108 \
|
||||
--hash=sha256:a934090d95abaa9e911dac357e3a8699e0b4b14f8529bcc7d2b1ad9d51672b9f
|
||||
cattrs==24.1.0 \
|
||||
--hash=sha256:043bb8af72596432a7df63abcff0055ac0f198a4d2e95af8db5a936a7074a761 \
|
||||
--hash=sha256:8274f18b253bf7674a43da851e3096370d67088165d23138b04a1c04c8eaf48e
|
||||
# via requests-cache
|
||||
certifi==2024.7.4 \
|
||||
--hash=sha256:5a1e7645bc0ec61a09e26c36f6106dd4cf40c6db3a1fb6352b0244e7fb057c7b \
|
||||
|
@ -158,51 +158,72 @@ colorlog==6.8.2 \
|
|||
# django-for-runners
|
||||
# django-tools
|
||||
# django-yunohost-integration
|
||||
contourpy==1.2.1 \
|
||||
--hash=sha256:00e5388f71c1a0610e6fe56b5c44ab7ba14165cdd6d695429c5cd94021e390b2 \
|
||||
--hash=sha256:10a37ae557aabf2509c79715cd20b62e4c7c28b8cd62dd7d99e5ed3ce28c3fd9 \
|
||||
--hash=sha256:11959f0ce4a6f7b76ec578576a0b61a28bdc0696194b6347ba3f1c53827178b9 \
|
||||
--hash=sha256:187fa1d4c6acc06adb0fae5544c59898ad781409e61a926ac7e84b8f276dcef4 \
|
||||
--hash=sha256:1a07fc092a4088ee952ddae19a2b2a85757b923217b7eed584fdf25f53a6e7ce \
|
||||
--hash=sha256:1cac0a8f71a041aa587410424ad46dfa6a11f6149ceb219ce7dd48f6b02b87a7 \
|
||||
--hash=sha256:1d59e739ab0e3520e62a26c60707cc3ab0365d2f8fecea74bfe4de72dc56388f \
|
||||
--hash=sha256:2855c8b0b55958265e8b5888d6a615ba02883b225f2227461aa9127c578a4922 \
|
||||
--hash=sha256:2e785e0f2ef0d567099b9ff92cbfb958d71c2d5b9259981cd9bee81bd194c9a4 \
|
||||
--hash=sha256:309be79c0a354afff9ff7da4aaed7c3257e77edf6c1b448a779329431ee79d7e \
|
||||
--hash=sha256:39f3ecaf76cd98e802f094e0d4fbc6dc9c45a8d0c4d185f0f6c2234e14e5f75b \
|
||||
--hash=sha256:457499c79fa84593f22454bbd27670227874cd2ff5d6c84e60575c8b50a69619 \
|
||||
--hash=sha256:49e70d111fee47284d9dd867c9bb9a7058a3c617274900780c43e38d90fe1205 \
|
||||
--hash=sha256:4c75507d0a55378240f781599c30e7776674dbaf883a46d1c90f37e563453480 \
|
||||
--hash=sha256:4c863140fafc615c14a4bf4efd0f4425c02230eb8ef02784c9a156461e62c965 \
|
||||
--hash=sha256:4d8908b3bee1c889e547867ca4cdc54e5ab6be6d3e078556814a22457f49423c \
|
||||
--hash=sha256:5b9eb0ca724a241683c9685a484da9d35c872fd42756574a7cfbf58af26677fd \
|
||||
--hash=sha256:6022cecf8f44e36af10bd9118ca71f371078b4c168b6e0fab43d4a889985dbb5 \
|
||||
--hash=sha256:6150ffa5c767bc6332df27157d95442c379b7dce3a38dff89c0f39b63275696f \
|
||||
--hash=sha256:62828cada4a2b850dbef89c81f5a33741898b305db244904de418cc957ff05dc \
|
||||
--hash=sha256:7b4182299f251060996af5249c286bae9361fa8c6a9cda5efc29fe8bfd6062ec \
|
||||
--hash=sha256:94b34f32646ca0414237168d68a9157cb3889f06b096612afdd296003fdd32fd \
|
||||
--hash=sha256:9ce6889abac9a42afd07a562c2d6d4b2b7134f83f18571d859b25624a331c90b \
|
||||
--hash=sha256:9cffe0f850e89d7c0012a1fb8730f75edd4320a0a731ed0c183904fe6ecfc3a9 \
|
||||
--hash=sha256:a12a813949e5066148712a0626895c26b2578874e4cc63160bb007e6df3436fe \
|
||||
--hash=sha256:a1eea9aecf761c661d096d39ed9026574de8adb2ae1c5bd7b33558af884fb2ce \
|
||||
--hash=sha256:a31f94983fecbac95e58388210427d68cd30fe8a36927980fab9c20062645609 \
|
||||
--hash=sha256:ac58bdee53cbeba2ecad824fa8159493f0bf3b8ea4e93feb06c9a465d6c87da8 \
|
||||
--hash=sha256:af3f4485884750dddd9c25cb7e3915d83c2db92488b38ccb77dd594eac84c4a0 \
|
||||
--hash=sha256:b33d2bc4f69caedcd0a275329eb2198f560b325605810895627be5d4b876bf7f \
|
||||
--hash=sha256:b59c0ffceff8d4d3996a45f2bb6f4c207f94684a96bf3d9728dbb77428dd8cb8 \
|
||||
--hash=sha256:bb6834cbd983b19f06908b45bfc2dad6ac9479ae04abe923a275b5f48f1a186b \
|
||||
--hash=sha256:bd3db01f59fdcbce5b22afad19e390260d6d0222f35a1023d9adc5690a889364 \
|
||||
--hash=sha256:bd7c23df857d488f418439686d3b10ae2fbf9bc256cd045b37a8c16575ea1040 \
|
||||
--hash=sha256:c2528d60e398c7c4c799d56f907664673a807635b857df18f7ae64d3e6ce2d9f \
|
||||
--hash=sha256:d31a63bc6e6d87f77d71e1abbd7387ab817a66733734883d1fc0021ed9bfa083 \
|
||||
--hash=sha256:d4492d82b3bc7fbb7e3610747b159869468079fe149ec5c4d771fa1f614a14df \
|
||||
--hash=sha256:ddcb8581510311e13421b1f544403c16e901c4e8f09083c881fab2be80ee31ba \
|
||||
--hash=sha256:e1d59258c3c67c865435d8fbeb35f8c59b8bef3d6f46c1f29f6123556af28445 \
|
||||
--hash=sha256:eb3315a8a236ee19b6df481fc5f997436e8ade24a9f03dfdc6bd490fea20c6da \
|
||||
--hash=sha256:ef2b055471c0eb466033760a521efb9d8a32b99ab907fc8358481a1dd29e3bd3 \
|
||||
--hash=sha256:ef5adb9a3b1d0c645ff694f9bca7702ec2c70f4d734f9922ea34de02294fdf72 \
|
||||
--hash=sha256:f32c38afb74bd98ce26de7cc74a67b40afb7b05aae7b42924ea990d51e4dac02 \
|
||||
--hash=sha256:fe0ccca550bb8e5abc22f530ec0466136379c01321fd94f30a22231e8a48d985
|
||||
contourpy==1.3.0 \
|
||||
--hash=sha256:00ccd0dbaad6d804ab259820fa7cb0b8036bda0686ef844d24125d8287178ce0 \
|
||||
--hash=sha256:0be4d8425bfa755e0fd76ee1e019636ccc7c29f77a7c86b4328a9eb6a26d0639 \
|
||||
--hash=sha256:0dce35502151b6bd35027ac39ba6e5a44be13a68f55735c3612c568cac3805fd \
|
||||
--hash=sha256:0fa4c02abe6c446ba70d96ece336e621efa4aecae43eaa9b030ae5fb92b309ad \
|
||||
--hash=sha256:14e262f67bd7e6eb6880bc564dcda30b15e351a594657e55b7eec94b6ef72843 \
|
||||
--hash=sha256:167d6c890815e1dac9536dca00828b445d5d0df4d6a8c6adb4a7ec3166812fa8 \
|
||||
--hash=sha256:1ec4dc6bf570f5b22ed0d7efba0dfa9c5b9e0431aeea7581aa217542d9e809a4 \
|
||||
--hash=sha256:303c252947ab4b14c08afeb52375b26781ccd6a5ccd81abcdfc1fafd14cf93c1 \
|
||||
--hash=sha256:31cd3a85dbdf1fc002280c65caa7e2b5f65e4a973fcdf70dd2fdcb9868069294 \
|
||||
--hash=sha256:32b238b3b3b649e09ce9aaf51f0c261d38644bdfa35cbaf7b263457850957a84 \
|
||||
--hash=sha256:33c92cdae89ec5135d036e7218e69b0bb2851206077251f04a6c4e0e21f03927 \
|
||||
--hash=sha256:345af746d7766821d05d72cb8f3845dfd08dd137101a2cb9b24de277d716def8 \
|
||||
--hash=sha256:3634b5385c6716c258d0419c46d05c8aa7dc8cb70326c9a4fb66b69ad2b52e09 \
|
||||
--hash=sha256:364174c2a76057feef647c802652f00953b575723062560498dc7930fc9b1cb7 \
|
||||
--hash=sha256:36e0cff201bcb17a0a8ecc7f454fe078437fa6bda730e695a92f2d9932bd507f \
|
||||
--hash=sha256:36f965570cff02b874773c49bfe85562b47030805d7d8360748f3eca570f4cab \
|
||||
--hash=sha256:3bb3808858a9dc68f6f03d319acd5f1b8a337e6cdda197f02f4b8ff67ad2057b \
|
||||
--hash=sha256:3e1c7fa44aaae40a2247e2e8e0627f4bea3dd257014764aa644f319a5f8600e3 \
|
||||
--hash=sha256:3faeb2998e4fcb256542e8a926d08da08977f7f5e62cf733f3c211c2a5586223 \
|
||||
--hash=sha256:420d39daa61aab1221567b42eecb01112908b2cab7f1b4106a52caaec8d36973 \
|
||||
--hash=sha256:4553c421929ec95fb07b3aaca0fae668b2eb5a5203d1217ca7c34c063c53d087 \
|
||||
--hash=sha256:4865cd1d419e0c7a7bf6de1777b185eebdc51470800a9f42b9e9decf17762081 \
|
||||
--hash=sha256:4cfb5c62ce023dfc410d6059c936dcf96442ba40814aefbfa575425a3a7f19dc \
|
||||
--hash=sha256:4d63ee447261e963af02642ffcb864e5a2ee4cbfd78080657a9880b8b1868e18 \
|
||||
--hash=sha256:570ef7cf892f0afbe5b2ee410c507ce12e15a5fa91017a0009f79f7d93a1268f \
|
||||
--hash=sha256:637f674226be46f6ba372fd29d9523dd977a291f66ab2a74fbeb5530bb3f445d \
|
||||
--hash=sha256:68a32389b06b82c2fdd68276148d7b9275b5f5cf13e5417e4252f6d1a34f72a2 \
|
||||
--hash=sha256:69375194457ad0fad3a839b9e29aa0b0ed53bb54db1bfb6c3ae43d111c31ce41 \
|
||||
--hash=sha256:6cb6cc968059db9c62cb35fbf70248f40994dfcd7aa10444bbf8b3faeb7c2d67 \
|
||||
--hash=sha256:710a26b3dc80c0e4febf04555de66f5fd17e9cf7170a7b08000601a10570bda6 \
|
||||
--hash=sha256:732896af21716b29ab3e988d4ce14bc5133733b85956316fb0c56355f398099b \
|
||||
--hash=sha256:75ee7cb1a14c617f34a51d11fa7524173e56551646828353c4af859c56b766e2 \
|
||||
--hash=sha256:76a896b2f195b57db25d6b44e7e03f221d32fe318d03ede41f8b4d9ba1bff53c \
|
||||
--hash=sha256:76c905ef940a4474a6289c71d53122a4f77766eef23c03cd57016ce19d0f7b42 \
|
||||
--hash=sha256:7a52040312b1a858b5e31ef28c2e865376a386c60c0e248370bbea2d3f3b760d \
|
||||
--hash=sha256:7ffa0db17717a8ffb127efd0c95a4362d996b892c2904db72428d5b52e1938a4 \
|
||||
--hash=sha256:81cb5ed4952aae6014bc9d0421dec7c5835c9c8c31cdf51910b708f548cf58e5 \
|
||||
--hash=sha256:834e0cfe17ba12f79963861e0f908556b2cedd52e1f75e6578801febcc6a9f49 \
|
||||
--hash=sha256:87ddffef1dbe5e669b5c2440b643d3fdd8622a348fe1983fad7a0f0ccb1cd67b \
|
||||
--hash=sha256:880ea32e5c774634f9fcd46504bf9f080a41ad855f4fef54f5380f5133d343c7 \
|
||||
--hash=sha256:8ca947601224119117f7c19c9cdf6b3ab54c5726ef1d906aa4a69dfb6dd58102 \
|
||||
--hash=sha256:90f73a5116ad1ba7174341ef3ea5c3150ddf20b024b98fb0c3b29034752c8aeb \
|
||||
--hash=sha256:92f8557cbb07415a4d6fa191f20fd9d2d9eb9c0b61d1b2f52a8926e43c6e9af7 \
|
||||
--hash=sha256:94e848a6b83da10898cbf1311a815f770acc9b6a3f2d646f330d57eb4e87592e \
|
||||
--hash=sha256:9c0da700bf58f6e0b65312d0a5e695179a71d0163957fa381bb3c1f72972537c \
|
||||
--hash=sha256:a11077e395f67ffc2c44ec2418cfebed032cd6da3022a94fc227b6faf8e2acb8 \
|
||||
--hash=sha256:aea348f053c645100612b333adc5983d87be69acdc6d77d3169c090d3b01dc35 \
|
||||
--hash=sha256:b11b39aea6be6764f84360fce6c82211a9db32a7c7de8fa6dd5397cf1d079c3b \
|
||||
--hash=sha256:c6c7c2408b7048082932cf4e641fa3b8ca848259212f51c8c59c45aa7ac18f14 \
|
||||
--hash=sha256:c6ec93afeb848a0845a18989da3beca3eec2c0f852322efe21af1931147d12cb \
|
||||
--hash=sha256:cacd81e2d4b6f89c9f8a5b69b86490152ff39afc58a95af002a398273e5ce589 \
|
||||
--hash=sha256:d402880b84df3bec6eab53cd0cf802cae6a2ef9537e70cf75e91618a3801c20c \
|
||||
--hash=sha256:d51fca85f9f7ad0b65b4b9fe800406d0d77017d7270d31ec3fb1cc07358fdea0 \
|
||||
--hash=sha256:d73f659398a0904e125280836ae6f88ba9b178b2fed6884f3b1f95b989d2c8da \
|
||||
--hash=sha256:d78ab28a03c854a873787a0a42254a0ccb3cb133c672f645c9f9c8f3ae9d0800 \
|
||||
--hash=sha256:da84c537cb8b97d153e9fb208c221c45605f73147bd4cadd23bdae915042aad6 \
|
||||
--hash=sha256:dbc4c3217eee163fa3984fd1567632b48d6dfd29216da3ded3d7b844a8014a66 \
|
||||
--hash=sha256:e12968fdfd5bb45ffdf6192a590bd8ddd3ba9e58360b29683c6bb71a7b41edca \
|
||||
--hash=sha256:e1fd23e9d01591bab45546c089ae89d926917a66dceb3abcf01f6105d927e2cb \
|
||||
--hash=sha256:e8134301d7e204c88ed7ab50028ba06c683000040ede1d617298611f9dc6240c \
|
||||
--hash=sha256:eb8b141bb00fa977d9122636b16aa67d37fd40a3d8b52dd837e536d64b9a4d06 \
|
||||
--hash=sha256:eca7e17a65f72a5133bdbec9ecf22401c62bcf4821361ef7811faee695799779 \
|
||||
--hash=sha256:f317576606de89da6b7e0861cf6061f6146ead3528acabff9236458a6ba467f8 \
|
||||
--hash=sha256:fd2a0fc506eccaaa7595b7e1418951f213cf8255be2600f1ea1b61e46a60c55f \
|
||||
--hash=sha256:fe41b41505a5a33aeaed2a613dccaeaa74e0e3ead6dd6fd3a118fb471644fd6c
|
||||
# via matplotlib
|
||||
cycler==0.12.1 \
|
||||
--hash=sha256:85cef7cff222d8644161529808465972e51340599459b8ac3ccbac5a854e0d30 \
|
||||
|
@ -860,9 +881,9 @@ pygments==2.18.0 \
|
|||
--hash=sha256:786ff802f32e91311bff3889f6e9a86e81505fe99f2735bb6d60ae0c5004f199 \
|
||||
--hash=sha256:b8e6aca0523f3ab76fee51799c488e38782ac06eafcf95e7ba832985c8e7b13a
|
||||
# via rich
|
||||
pyparsing==3.1.3 \
|
||||
--hash=sha256:1e80fdf93e6c1aeaf4702523f1d48f66d52fa6459096a8f812591157270a5896 \
|
||||
--hash=sha256:5d549d2a1b5e1c3e952bb55ea247bfb5ad427ea307566a350db2b3c34d4ce181
|
||||
pyparsing==3.1.4 \
|
||||
--hash=sha256:a6a7ee4235a3f944aa1fa2249307708f893fe5717dc603503c6c7969c070fb7c \
|
||||
--hash=sha256:f86ec8d1a83f11977c9a6ea7598e8c27fc5cddfa5b07ea2241edbbde1d7bc032
|
||||
# via matplotlib
|
||||
python-dateutil==2.9.0.post0 \
|
||||
--hash=sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3 \
|
||||
|
@ -952,9 +973,9 @@ retry-requests==2.0.0 \
|
|||
--hash=sha256:38e8e3f55051e7b7915c1768884269097865a5da2ea87d5dcafd6ba9498c363f \
|
||||
--hash=sha256:3d02135e5aafedf09240414182fc7389c5d2b4de0252daba0054c9d6a27e7639
|
||||
# via django-for-runners
|
||||
rich==13.7.1 \
|
||||
--hash=sha256:4edbae314f59eb482f54e9e30bf00d33350aaa94f4bfcd4e9e3110e64d0d7222 \
|
||||
--hash=sha256:9be308cb1fe2f1f57d67ce99e95af38a1e2bc71ad9813b0e247cf7ffbcc3a432
|
||||
rich==13.8.0 \
|
||||
--hash=sha256:2e85306a063b9492dffc86278197a60cbece75bcb766022f3436f567cae11bdc \
|
||||
--hash=sha256:a5ac1f1cd448ade0d59cc3356f7db7a7ccda2c8cbae9c7a90c28ff463d3e91f4
|
||||
# via
|
||||
# cli-base-utilities
|
||||
# django-rich
|
||||
|
|
17
for_runners_ynh/tests/test_install_python.py
Normal file
17
for_runners_ynh/tests/test_install_python.py
Normal file
|
@ -0,0 +1,17 @@
|
|||
"""
|
||||
https://github.com/jedie/manageprojects/blob/main/docs/install_python.md#include-in-own-projects
|
||||
"""
|
||||
|
||||
from django_yunohost_integration.path_utils import get_project_root
|
||||
from manageprojects.utilities.include_install_python import IncludeInstallPythonBaseTestCase
|
||||
|
||||
|
||||
class IncludeInstallPythonTestCase(IncludeInstallPythonBaseTestCase):
|
||||
"""
|
||||
Updates `conf/install_python.py` from `manageprojects` if needed.
|
||||
"""
|
||||
|
||||
DESTINATION_PATH = get_project_root() / 'conf' / 'install_python.py'
|
||||
|
||||
def test_install_python_is_up2date(self):
|
||||
self.auto_update_install_python()
|
|
@ -21,7 +21,7 @@ dependencies = [
|
|||
dev = [
|
||||
"bx_django_utils", # https://github.com/boxine/bx_django_utils
|
||||
"beautifulsoup4", # https://pypi.org/project/beautifulsoup4/
|
||||
"manageprojects", # https://github.com/jedie/manageprojects
|
||||
"manageprojects>=0.18.0", # https://github.com/jedie/manageprojects
|
||||
"pip-tools", # https://github.com/jazzband/pip-tools/
|
||||
"tblib", # https://github.com/ionelmc/python-tblib
|
||||
"tox", # https://github.com/tox-dev/tox
|
||||
|
|
|
@ -115,9 +115,9 @@ cachetools==5.5.0 \
|
|||
--hash=sha256:02134e8439cdc2ffb62023ce1debca2944c3f289d66bb17ead3ab3dede74b292 \
|
||||
--hash=sha256:2cc24fb4cbe39633fb7badd9db9ca6295d766d9c2995f245725a46715d050f2a
|
||||
# via tox
|
||||
cattrs==23.2.3 \
|
||||
--hash=sha256:0341994d94971052e9ee70662542699a3162ea1e0c62f7ce1b4a57f563685108 \
|
||||
--hash=sha256:a934090d95abaa9e911dac357e3a8699e0b4b14f8529bcc7d2b1ad9d51672b9f
|
||||
cattrs==24.1.0 \
|
||||
--hash=sha256:043bb8af72596432a7df63abcff0055ac0f198a4d2e95af8db5a936a7074a761 \
|
||||
--hash=sha256:8274f18b253bf7674a43da851e3096370d67088165d23138b04a1c04c8eaf48e
|
||||
# via requests-cache
|
||||
certifi==2024.7.4 \
|
||||
--hash=sha256:5a1e7645bc0ec61a09e26c36f6106dd4cf40c6db3a1fb6352b0244e7fb057c7b \
|
||||
|
@ -323,51 +323,72 @@ colorlog==6.8.2 \
|
|||
# django-for-runners
|
||||
# django-tools
|
||||
# django-yunohost-integration
|
||||
contourpy==1.2.1 \
|
||||
--hash=sha256:00e5388f71c1a0610e6fe56b5c44ab7ba14165cdd6d695429c5cd94021e390b2 \
|
||||
--hash=sha256:10a37ae557aabf2509c79715cd20b62e4c7c28b8cd62dd7d99e5ed3ce28c3fd9 \
|
||||
--hash=sha256:11959f0ce4a6f7b76ec578576a0b61a28bdc0696194b6347ba3f1c53827178b9 \
|
||||
--hash=sha256:187fa1d4c6acc06adb0fae5544c59898ad781409e61a926ac7e84b8f276dcef4 \
|
||||
--hash=sha256:1a07fc092a4088ee952ddae19a2b2a85757b923217b7eed584fdf25f53a6e7ce \
|
||||
--hash=sha256:1cac0a8f71a041aa587410424ad46dfa6a11f6149ceb219ce7dd48f6b02b87a7 \
|
||||
--hash=sha256:1d59e739ab0e3520e62a26c60707cc3ab0365d2f8fecea74bfe4de72dc56388f \
|
||||
--hash=sha256:2855c8b0b55958265e8b5888d6a615ba02883b225f2227461aa9127c578a4922 \
|
||||
--hash=sha256:2e785e0f2ef0d567099b9ff92cbfb958d71c2d5b9259981cd9bee81bd194c9a4 \
|
||||
--hash=sha256:309be79c0a354afff9ff7da4aaed7c3257e77edf6c1b448a779329431ee79d7e \
|
||||
--hash=sha256:39f3ecaf76cd98e802f094e0d4fbc6dc9c45a8d0c4d185f0f6c2234e14e5f75b \
|
||||
--hash=sha256:457499c79fa84593f22454bbd27670227874cd2ff5d6c84e60575c8b50a69619 \
|
||||
--hash=sha256:49e70d111fee47284d9dd867c9bb9a7058a3c617274900780c43e38d90fe1205 \
|
||||
--hash=sha256:4c75507d0a55378240f781599c30e7776674dbaf883a46d1c90f37e563453480 \
|
||||
--hash=sha256:4c863140fafc615c14a4bf4efd0f4425c02230eb8ef02784c9a156461e62c965 \
|
||||
--hash=sha256:4d8908b3bee1c889e547867ca4cdc54e5ab6be6d3e078556814a22457f49423c \
|
||||
--hash=sha256:5b9eb0ca724a241683c9685a484da9d35c872fd42756574a7cfbf58af26677fd \
|
||||
--hash=sha256:6022cecf8f44e36af10bd9118ca71f371078b4c168b6e0fab43d4a889985dbb5 \
|
||||
--hash=sha256:6150ffa5c767bc6332df27157d95442c379b7dce3a38dff89c0f39b63275696f \
|
||||
--hash=sha256:62828cada4a2b850dbef89c81f5a33741898b305db244904de418cc957ff05dc \
|
||||
--hash=sha256:7b4182299f251060996af5249c286bae9361fa8c6a9cda5efc29fe8bfd6062ec \
|
||||
--hash=sha256:94b34f32646ca0414237168d68a9157cb3889f06b096612afdd296003fdd32fd \
|
||||
--hash=sha256:9ce6889abac9a42afd07a562c2d6d4b2b7134f83f18571d859b25624a331c90b \
|
||||
--hash=sha256:9cffe0f850e89d7c0012a1fb8730f75edd4320a0a731ed0c183904fe6ecfc3a9 \
|
||||
--hash=sha256:a12a813949e5066148712a0626895c26b2578874e4cc63160bb007e6df3436fe \
|
||||
--hash=sha256:a1eea9aecf761c661d096d39ed9026574de8adb2ae1c5bd7b33558af884fb2ce \
|
||||
--hash=sha256:a31f94983fecbac95e58388210427d68cd30fe8a36927980fab9c20062645609 \
|
||||
--hash=sha256:ac58bdee53cbeba2ecad824fa8159493f0bf3b8ea4e93feb06c9a465d6c87da8 \
|
||||
--hash=sha256:af3f4485884750dddd9c25cb7e3915d83c2db92488b38ccb77dd594eac84c4a0 \
|
||||
--hash=sha256:b33d2bc4f69caedcd0a275329eb2198f560b325605810895627be5d4b876bf7f \
|
||||
--hash=sha256:b59c0ffceff8d4d3996a45f2bb6f4c207f94684a96bf3d9728dbb77428dd8cb8 \
|
||||
--hash=sha256:bb6834cbd983b19f06908b45bfc2dad6ac9479ae04abe923a275b5f48f1a186b \
|
||||
--hash=sha256:bd3db01f59fdcbce5b22afad19e390260d6d0222f35a1023d9adc5690a889364 \
|
||||
--hash=sha256:bd7c23df857d488f418439686d3b10ae2fbf9bc256cd045b37a8c16575ea1040 \
|
||||
--hash=sha256:c2528d60e398c7c4c799d56f907664673a807635b857df18f7ae64d3e6ce2d9f \
|
||||
--hash=sha256:d31a63bc6e6d87f77d71e1abbd7387ab817a66733734883d1fc0021ed9bfa083 \
|
||||
--hash=sha256:d4492d82b3bc7fbb7e3610747b159869468079fe149ec5c4d771fa1f614a14df \
|
||||
--hash=sha256:ddcb8581510311e13421b1f544403c16e901c4e8f09083c881fab2be80ee31ba \
|
||||
--hash=sha256:e1d59258c3c67c865435d8fbeb35f8c59b8bef3d6f46c1f29f6123556af28445 \
|
||||
--hash=sha256:eb3315a8a236ee19b6df481fc5f997436e8ade24a9f03dfdc6bd490fea20c6da \
|
||||
--hash=sha256:ef2b055471c0eb466033760a521efb9d8a32b99ab907fc8358481a1dd29e3bd3 \
|
||||
--hash=sha256:ef5adb9a3b1d0c645ff694f9bca7702ec2c70f4d734f9922ea34de02294fdf72 \
|
||||
--hash=sha256:f32c38afb74bd98ce26de7cc74a67b40afb7b05aae7b42924ea990d51e4dac02 \
|
||||
--hash=sha256:fe0ccca550bb8e5abc22f530ec0466136379c01321fd94f30a22231e8a48d985
|
||||
contourpy==1.3.0 \
|
||||
--hash=sha256:00ccd0dbaad6d804ab259820fa7cb0b8036bda0686ef844d24125d8287178ce0 \
|
||||
--hash=sha256:0be4d8425bfa755e0fd76ee1e019636ccc7c29f77a7c86b4328a9eb6a26d0639 \
|
||||
--hash=sha256:0dce35502151b6bd35027ac39ba6e5a44be13a68f55735c3612c568cac3805fd \
|
||||
--hash=sha256:0fa4c02abe6c446ba70d96ece336e621efa4aecae43eaa9b030ae5fb92b309ad \
|
||||
--hash=sha256:14e262f67bd7e6eb6880bc564dcda30b15e351a594657e55b7eec94b6ef72843 \
|
||||
--hash=sha256:167d6c890815e1dac9536dca00828b445d5d0df4d6a8c6adb4a7ec3166812fa8 \
|
||||
--hash=sha256:1ec4dc6bf570f5b22ed0d7efba0dfa9c5b9e0431aeea7581aa217542d9e809a4 \
|
||||
--hash=sha256:303c252947ab4b14c08afeb52375b26781ccd6a5ccd81abcdfc1fafd14cf93c1 \
|
||||
--hash=sha256:31cd3a85dbdf1fc002280c65caa7e2b5f65e4a973fcdf70dd2fdcb9868069294 \
|
||||
--hash=sha256:32b238b3b3b649e09ce9aaf51f0c261d38644bdfa35cbaf7b263457850957a84 \
|
||||
--hash=sha256:33c92cdae89ec5135d036e7218e69b0bb2851206077251f04a6c4e0e21f03927 \
|
||||
--hash=sha256:345af746d7766821d05d72cb8f3845dfd08dd137101a2cb9b24de277d716def8 \
|
||||
--hash=sha256:3634b5385c6716c258d0419c46d05c8aa7dc8cb70326c9a4fb66b69ad2b52e09 \
|
||||
--hash=sha256:364174c2a76057feef647c802652f00953b575723062560498dc7930fc9b1cb7 \
|
||||
--hash=sha256:36e0cff201bcb17a0a8ecc7f454fe078437fa6bda730e695a92f2d9932bd507f \
|
||||
--hash=sha256:36f965570cff02b874773c49bfe85562b47030805d7d8360748f3eca570f4cab \
|
||||
--hash=sha256:3bb3808858a9dc68f6f03d319acd5f1b8a337e6cdda197f02f4b8ff67ad2057b \
|
||||
--hash=sha256:3e1c7fa44aaae40a2247e2e8e0627f4bea3dd257014764aa644f319a5f8600e3 \
|
||||
--hash=sha256:3faeb2998e4fcb256542e8a926d08da08977f7f5e62cf733f3c211c2a5586223 \
|
||||
--hash=sha256:420d39daa61aab1221567b42eecb01112908b2cab7f1b4106a52caaec8d36973 \
|
||||
--hash=sha256:4553c421929ec95fb07b3aaca0fae668b2eb5a5203d1217ca7c34c063c53d087 \
|
||||
--hash=sha256:4865cd1d419e0c7a7bf6de1777b185eebdc51470800a9f42b9e9decf17762081 \
|
||||
--hash=sha256:4cfb5c62ce023dfc410d6059c936dcf96442ba40814aefbfa575425a3a7f19dc \
|
||||
--hash=sha256:4d63ee447261e963af02642ffcb864e5a2ee4cbfd78080657a9880b8b1868e18 \
|
||||
--hash=sha256:570ef7cf892f0afbe5b2ee410c507ce12e15a5fa91017a0009f79f7d93a1268f \
|
||||
--hash=sha256:637f674226be46f6ba372fd29d9523dd977a291f66ab2a74fbeb5530bb3f445d \
|
||||
--hash=sha256:68a32389b06b82c2fdd68276148d7b9275b5f5cf13e5417e4252f6d1a34f72a2 \
|
||||
--hash=sha256:69375194457ad0fad3a839b9e29aa0b0ed53bb54db1bfb6c3ae43d111c31ce41 \
|
||||
--hash=sha256:6cb6cc968059db9c62cb35fbf70248f40994dfcd7aa10444bbf8b3faeb7c2d67 \
|
||||
--hash=sha256:710a26b3dc80c0e4febf04555de66f5fd17e9cf7170a7b08000601a10570bda6 \
|
||||
--hash=sha256:732896af21716b29ab3e988d4ce14bc5133733b85956316fb0c56355f398099b \
|
||||
--hash=sha256:75ee7cb1a14c617f34a51d11fa7524173e56551646828353c4af859c56b766e2 \
|
||||
--hash=sha256:76a896b2f195b57db25d6b44e7e03f221d32fe318d03ede41f8b4d9ba1bff53c \
|
||||
--hash=sha256:76c905ef940a4474a6289c71d53122a4f77766eef23c03cd57016ce19d0f7b42 \
|
||||
--hash=sha256:7a52040312b1a858b5e31ef28c2e865376a386c60c0e248370bbea2d3f3b760d \
|
||||
--hash=sha256:7ffa0db17717a8ffb127efd0c95a4362d996b892c2904db72428d5b52e1938a4 \
|
||||
--hash=sha256:81cb5ed4952aae6014bc9d0421dec7c5835c9c8c31cdf51910b708f548cf58e5 \
|
||||
--hash=sha256:834e0cfe17ba12f79963861e0f908556b2cedd52e1f75e6578801febcc6a9f49 \
|
||||
--hash=sha256:87ddffef1dbe5e669b5c2440b643d3fdd8622a348fe1983fad7a0f0ccb1cd67b \
|
||||
--hash=sha256:880ea32e5c774634f9fcd46504bf9f080a41ad855f4fef54f5380f5133d343c7 \
|
||||
--hash=sha256:8ca947601224119117f7c19c9cdf6b3ab54c5726ef1d906aa4a69dfb6dd58102 \
|
||||
--hash=sha256:90f73a5116ad1ba7174341ef3ea5c3150ddf20b024b98fb0c3b29034752c8aeb \
|
||||
--hash=sha256:92f8557cbb07415a4d6fa191f20fd9d2d9eb9c0b61d1b2f52a8926e43c6e9af7 \
|
||||
--hash=sha256:94e848a6b83da10898cbf1311a815f770acc9b6a3f2d646f330d57eb4e87592e \
|
||||
--hash=sha256:9c0da700bf58f6e0b65312d0a5e695179a71d0163957fa381bb3c1f72972537c \
|
||||
--hash=sha256:a11077e395f67ffc2c44ec2418cfebed032cd6da3022a94fc227b6faf8e2acb8 \
|
||||
--hash=sha256:aea348f053c645100612b333adc5983d87be69acdc6d77d3169c090d3b01dc35 \
|
||||
--hash=sha256:b11b39aea6be6764f84360fce6c82211a9db32a7c7de8fa6dd5397cf1d079c3b \
|
||||
--hash=sha256:c6c7c2408b7048082932cf4e641fa3b8ca848259212f51c8c59c45aa7ac18f14 \
|
||||
--hash=sha256:c6ec93afeb848a0845a18989da3beca3eec2c0f852322efe21af1931147d12cb \
|
||||
--hash=sha256:cacd81e2d4b6f89c9f8a5b69b86490152ff39afc58a95af002a398273e5ce589 \
|
||||
--hash=sha256:d402880b84df3bec6eab53cd0cf802cae6a2ef9537e70cf75e91618a3801c20c \
|
||||
--hash=sha256:d51fca85f9f7ad0b65b4b9fe800406d0d77017d7270d31ec3fb1cc07358fdea0 \
|
||||
--hash=sha256:d73f659398a0904e125280836ae6f88ba9b178b2fed6884f3b1f95b989d2c8da \
|
||||
--hash=sha256:d78ab28a03c854a873787a0a42254a0ccb3cb133c672f645c9f9c8f3ae9d0800 \
|
||||
--hash=sha256:da84c537cb8b97d153e9fb208c221c45605f73147bd4cadd23bdae915042aad6 \
|
||||
--hash=sha256:dbc4c3217eee163fa3984fd1567632b48d6dfd29216da3ded3d7b844a8014a66 \
|
||||
--hash=sha256:e12968fdfd5bb45ffdf6192a590bd8ddd3ba9e58360b29683c6bb71a7b41edca \
|
||||
--hash=sha256:e1fd23e9d01591bab45546c089ae89d926917a66dceb3abcf01f6105d927e2cb \
|
||||
--hash=sha256:e8134301d7e204c88ed7ab50028ba06c683000040ede1d617298611f9dc6240c \
|
||||
--hash=sha256:eb8b141bb00fa977d9122636b16aa67d37fd40a3d8b52dd837e536d64b9a4d06 \
|
||||
--hash=sha256:eca7e17a65f72a5133bdbec9ecf22401c62bcf4821361ef7811faee695799779 \
|
||||
--hash=sha256:f317576606de89da6b7e0861cf6061f6146ead3528acabff9236458a6ba467f8 \
|
||||
--hash=sha256:fd2a0fc506eccaaa7595b7e1418951f213cf8255be2600f1ea1b61e46a60c55f \
|
||||
--hash=sha256:fe41b41505a5a33aeaed2a613dccaeaa74e0e3ead6dd6fd3a118fb471644fd6c
|
||||
# via matplotlib
|
||||
cookiecutter==2.6.0 \
|
||||
--hash=sha256:a54a8e37995e4ed963b3e82831072d1ad4b005af736bb17b99c2cbd9d41b6e2d \
|
||||
|
@ -966,9 +987,9 @@ lxml==5.3.0 \
|
|||
--hash=sha256:f914c03e6a31deb632e2daa881fe198461f4d06e57ac3d0e05bbcab8eae01945 \
|
||||
--hash=sha256:fb66442c2546446944437df74379e9cf9e9db353e61301d1a0e26482f43f0dd8
|
||||
# via django-for-runners
|
||||
manageprojects==0.17.1 \
|
||||
--hash=sha256:355d970261f14b53b574d102e7e82462fe6769baa06c479f00f07a0bcfcb8e4d \
|
||||
--hash=sha256:4662ff7f0e64ea9b420b67c270594c88542858a1434ebe8b5f93b7bf2ae2e706
|
||||
manageprojects==0.18.0 \
|
||||
--hash=sha256:37b452c8eb464cf79d29f4e30e8e9c9bce0c1e525a3112d11ff66f99bd48dda4 \
|
||||
--hash=sha256:548ca16ba2c1d58c8f532d35cfbfb16fee236695b090b0e2d5303b1e9f60ce99
|
||||
# via for_runners_ynh (pyproject.toml)
|
||||
markdown-it-py==3.0.0 \
|
||||
--hash=sha256:355216845c60bd96232cd8d8c40e8f9765cc86f46880e43a8fd22dc1a1a8cab1 \
|
||||
|
@ -1181,6 +1202,7 @@ mypy==1.11.2 \
|
|||
# via
|
||||
# for_runners_ynh (pyproject.toml)
|
||||
# manageprojects
|
||||
# refurb
|
||||
mypy-extensions==1.0.0 \
|
||||
--hash=sha256:4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d \
|
||||
--hash=sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782
|
||||
|
@ -1489,9 +1511,9 @@ pygments==2.18.0 \
|
|||
# darker
|
||||
# readme-renderer
|
||||
# rich
|
||||
pyparsing==3.1.3 \
|
||||
--hash=sha256:1e80fdf93e6c1aeaf4702523f1d48f66d52fa6459096a8f812591157270a5896 \
|
||||
--hash=sha256:5d549d2a1b5e1c3e952bb55ea247bfb5ad427ea307566a350db2b3c34d4ce181
|
||||
pyparsing==3.1.4 \
|
||||
--hash=sha256:a6a7ee4235a3f944aa1fa2249307708f893fe5717dc603503c6c7969c070fb7c \
|
||||
--hash=sha256:f86ec8d1a83f11977c9a6ea7598e8c27fc5cddfa5b07ea2241edbbde1d7bc032
|
||||
# via
|
||||
# matplotlib
|
||||
# pip-requirements-parser
|
||||
|
@ -1595,6 +1617,10 @@ redis==5.0.8 \
|
|||
--hash=sha256:0c5b10d387568dfe0698c6fad6615750c24170e548ca2deac10c649d463e9870 \
|
||||
--hash=sha256:56134ee08ea909106090934adc36f65c9bcbbaecea5b21ba704ba6fb561f8eb4
|
||||
# via django-redis
|
||||
refurb==2.0.0 \
|
||||
--hash=sha256:8a8f1e7c131ef7dc460cbecbeaf536f5eb0ecb657c099d7823941f0e65b1cfe1 \
|
||||
--hash=sha256:fa9e950dc6edd7473642569c118f8714eefd1e6f21a15ee4210a1be853aaaf80
|
||||
# via manageprojects
|
||||
requests==2.32.3 \
|
||||
--hash=sha256:55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760 \
|
||||
--hash=sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6
|
||||
|
@ -1623,9 +1649,9 @@ rfc3986==2.0.0 \
|
|||
--hash=sha256:50b1502b60e289cb37883f3dfd34532b8873c7de9f49bb546641ce9cbd256ebd \
|
||||
--hash=sha256:97aacf9dbd4bfd829baad6e6309fa6573aaf1be3f6fa735c8ab05e46cecb261c
|
||||
# via twine
|
||||
rich==13.7.1 \
|
||||
--hash=sha256:4edbae314f59eb482f54e9e30bf00d33350aaa94f4bfcd4e9e3110e64d0d7222 \
|
||||
--hash=sha256:9be308cb1fe2f1f57d67ce99e95af38a1e2bc71ad9813b0e247cf7ffbcc3a432
|
||||
rich==13.8.0 \
|
||||
--hash=sha256:2e85306a063b9492dffc86278197a60cbece75bcb766022f3436f567cae11bdc \
|
||||
--hash=sha256:a5ac1f1cd448ade0d59cc3356f7db7a7ccda2c8cbae9c7a90c28ff463d3e91f4
|
||||
# via
|
||||
# cli-base-utilities
|
||||
# cookiecutter
|
||||
|
@ -1753,9 +1779,9 @@ wheel==0.44.0 \
|
|||
--hash=sha256:2376a90c98cc337d18623527a97c31797bd02bad0033d41547043a1cbfbe448f \
|
||||
--hash=sha256:a29c3f2817e95ab89aa4660681ad547c0e9547f20e75b0562fe7723c9a2a9d49
|
||||
# via pip-tools
|
||||
zipp==3.20.0 \
|
||||
--hash=sha256:0145e43d89664cfe1a2e533adc75adafed82fe2da404b4bbb6b026c0157bdb31 \
|
||||
--hash=sha256:58da6168be89f0be59beb194da1250516fdaa062ccebd30127ac65d30045e10d
|
||||
zipp==3.20.1 \
|
||||
--hash=sha256:9960cd8967c8f85a56f920d5d507274e74f9ff813a0ab8889a5b5be2daf44064 \
|
||||
--hash=sha256:c22b14cc4763c5a5b04134207736c107db42e9d3ef2d9779d465f5f1bcba572b
|
||||
# via importlib-metadata
|
||||
|
||||
# The following packages are considered to be unsafe in a requirements file:
|
||||
|
@ -1765,7 +1791,7 @@ pip==24.2 \
|
|||
# via
|
||||
# pip-api
|
||||
# pip-tools
|
||||
setuptools==73.0.1 \
|
||||
--hash=sha256:b208925fcb9f7af924ed2dc04708ea89791e24bde0d3020b27df0e116088b34e \
|
||||
--hash=sha256:d59a3e788ab7e012ab2c4baed1b376da6366883ee20d7a5fc426816e3d7b1193
|
||||
setuptools==74.0.0 \
|
||||
--hash=sha256:0274581a0037b638b9fc1c6883cc71c0210865aaa76073f7882376b641b84e8f \
|
||||
--hash=sha256:a85e96b8be2b906f3e3e789adec6a9323abf79758ecfa3065bd740d81158b11e
|
||||
# via pip-tools
|
||||
|
|
|
@ -40,90 +40,16 @@ log_file="${log_path}/${app}.log"
|
|||
|
||||
|
||||
#==================================================================================
|
||||
# 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
|
||||
PY_REQUIRED_MAJOR=3.11
|
||||
|
||||
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 "$@"
|
||||
ynh_print_info --message="Install latest Python v${PY_REQUIRED_MAJOR}..."
|
||||
|
||||
# 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
|
||||
py_app_version="/usr/local/bin/python${py_built_version%.*}"
|
||||
ynh_print_info --message="Using already used python3 built version: $py_app_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"
|
||||
ynh_exec_warn_less python3 "$data_dir/install_python.py" -vv ${PY_REQUIRED_MAJOR}
|
||||
py_app_version=$(python3 "$data_dir/install_python.py" ${PY_REQUIRED_MAJOR})
|
||||
|
||||
# Print some version information:
|
||||
ynh_print_info --message="Python version: $($py_app_version -VV)"
|
||||
|
@ -134,7 +60,7 @@ myynh_install_python() {
|
|||
|
||||
myynh_setup_python_venv() {
|
||||
# Install Python if needed:
|
||||
myynh_install_python --python="$py_required_version"
|
||||
myynh_install_python
|
||||
|
||||
# Create a virtualenv with python installed by myynh_install_python():
|
||||
# Skip pip because of: https://github.com/YunoHost/issues/issues/1960
|
||||
|
|
|
@ -68,6 +68,7 @@ ynh_use_logrotate --logfile="$log_file" --specific_user=$app
|
|||
# PYTHON VIRTUALENV
|
||||
#=================================================
|
||||
ynh_script_progression --message="Create and setup Python virtualenv..." --weight=45
|
||||
cp ../conf/install_python.py "$data_dir/install_python.py"
|
||||
cp ../conf/requirements.txt "$data_dir/requirements.txt"
|
||||
myynh_setup_python_venv
|
||||
|
||||
|
|
|
@ -51,6 +51,7 @@ ynh_add_systemd_config --service=$app --template="systemd.service"
|
|||
# PYTHON VIRTUALENV
|
||||
#=================================================
|
||||
ynh_script_progression --message="Create and setup Python virtualenv..." --weight=45
|
||||
cp ../conf/install_python.py "$data_dir/install_python.py"
|
||||
cp ../conf/requirements.txt "$data_dir/requirements.txt"
|
||||
myynh_setup_python_venv
|
||||
|
||||
|
|
Loading…
Reference in a new issue