deployd/interpreter/extensions/python3
Arija A. 82680e3572
Implement basic deployment
Signed-off-by: Arija A. <ari@ari.lt>
2025-07-21 05:15:24 +03:00

157 lines
4.1 KiB
Bash

#!/bin/sh
PY3_PYTHON=$(command -v python3) || {
echo "[py3_version] python3 is not installed" >&2
return 1
}
export PY3_PYTHON
__py3_abs_path() {
path="$1"
if [ -d "$path" ]; then
(cd "$path" 2>/dev/null && pwd) || return 1
else
dir="${path%/*}"
file="${path##*/}"
if [ "$dir" = "$path" ]; then
printf '%s/%s\n' "$(pwd)" "$path"
else
(cd "$dir" 2>/dev/null && printf '%s/%s\n' "$(pwd)" "$file") || return 1
fi
fi
}
# Ensure a Python 3 virtual environment exists in ./venv (or given dir)
# Usage: py3_venv [path]
py3_venv() {
venv_dir="${1:-venv}"
venv_dir="$(__py3_abs_path "$venv_dir")"
if [ ! -d "$venv_dir" ]; then
info "[py3_venv] Creating virtual environment in $venv_dir"
python3 -m venv "$venv_dir" || {
error "[py3_venv] Failed to create virtual environment"
return 1
}
else
info "[py3_venv] Virtual environment already exists in $venv_dir"
fi
# shellcheck disable=SC1090
. "$venv_dir/bin/activate" || {
error "[py3_venv] Failed to activate virtualenv"
return 1
}
PY3_PYTHON="$venv_dir/bin/python"
export PY3_PYTHON
}
# Install from requirements.txt using pip inside the active or specified venv
# Usage: py3_requirements <requirements.txt path> [venv_dir]
py3_requirements() {
requirements_file="$1"
venv_dir="${2:-venv}"
venv_dir="$(__py3_abs_path "$venv_dir")"
if [ ! -f "$requirements_file" ]; then
error "[py3_requirements] Requirements file not found: $requirements_file"
return 1
fi
# Activate venv or fallback
if [ -f "$venv_dir/bin/activate" ]; then
# shellcheck disable=SC1090
. "$venv_dir/bin/activate" || {
error "[py3_requirements] Failed to activate virtualenv"
return 1
}
info "[py3_requirements] Installing requirements from $requirements_file"
pip install --upgrade pip
pip install --upgrade -r "$requirements_file" || {
error "[py3_requirements] Failed to install requirements"
return 1
}
deactivate
else
error "[py3_requirements] Virtual environment not found at $venv_dir"
return 1
fi
}
# Install one or more Python packages inside activated or specified venv
# Usage: py3_install <pkg1> [pkg2 ...] [venv_dir:<path>]
# Note: If you want to specify the venv dir, append it as last arg as: venv_dir:/path/to/venv
py3_install() {
pkgs=''
venv_dir='venv'
arg=''
for arg in "$@"; do
case "$arg" in
venv_dir:*)
venv_dir="${arg#venv_dir:}"
;;
*)
pkgs="$pkgs $arg"
;;
esac
done
venv_dir="$(__py3_abs_path "$venv_dir")"
if [ ! -d "$venv_dir" ]; then
error "[py3_install] Virtual environment not found at $venv_dir"
return 1
fi
# Activate venv
# shellcheck disable=SC1090
. "$venv_dir/bin/activate" || {
error "[py3_install] Failed to activate virtualenv"
return 1
}
info "[py3_install] Installing packages:$pkgs"
pip install --upgrade pip
pip install --upgrade $pkgs || {
error "[py3_install] Failed to install packages"
deactivate
return 1
}
deactivate
}
# Check if python3 interpreter version >= X (major * 100 + minor * 10)
# Usage: py3_version 310 (for Python 3.10, exact), py3_version 310 ? (for Python 3.10, at least)
# Returns 0 if version is >= argument, else 1
py3_version() {
required_version="$1"
if [ -z "$required_version" ]; then
error "[py3_version] Missing required version argument" >&2
return 1
fi
version_str=$("$PY3_PYTHON" -c 'import sys; v=sys.version_info; print(f"{v.major}{v.minor:02}")')
# e.g. "310" for 3.10
if [ "$2" = '?' ]; then
if [ "$version_str" -ge "$required_version" ]; then
return 0
else
return 1
fi
else
if [ "$version_str" -eq "$required_version" ]; then
return 0
else
return 1
fi
fi
}