Files
EndraApp/packaging/share/get_python_deps.sh

139 lines
3.9 KiB
Bash
Executable File

#!/bin/bash
## This script generates a full list of python dependencies for this project
## as required for a specific packaging pipeline.
## The dependencies are listed with specific versions
## This list is consists of:
## - the dependencies declared in $REQS_MAIN
## - complemented by $REQS_MANUAL
## - and their dependencies recursively
## - filtered by $REQS_EXCLUSIONS
set -euo pipefail
# the absolute path of this script's directory
SCRIPT_DIR="$( cd -- "$(dirname "$0")" >/dev/null 2>&1 ; pwd -P )"
PYTHON="${PYTHON:-python}"
if ! [ -e "$REQS_MANUAL" ]; then
"REQS_MANUAL not found: $REQS_MANUAL"
exit 1
fi
if ! [ -e "$REQS_MAIN" ]; then
"REQS_MANUAL not found: $REQS_MAIN"
exit 1
fi
if ! [ -e "$REQS_EXCLUSIONS" ]; then
"REQS_MANUAL not found: $REQS_EXCLUSIONS"
exit 1
fi
if ! [ -d "$PY_VENV_DIR" ]; then
"PY_VENV_DIR not found: $PY_VENV_DIR"
exit 1
fi
OS=$($PYTHON -c "import platform;print(platform.system())")
echo $PY_VENV_DIR
if [ $OS = "Windows" ];then
source $PY_VENV_DIR/Scripts/activate
else
source $PY_VENV_DIR/bin/activate
fi
function filter_reqs(){
REQS_BASE=$1
REQS_FILTER=$2
REQS_OUTPUT=$3
# Normalize exclusions: strip version part if present (keep only package name)
exclusions=$(sed -E 's/[[:space:]]*#.*//; s/[[:space:]]*$//; /^$/d; s/==.*$//; /^$/d; s/>=.*$//; /^$/d; s/<=.*$//' "$REQS_FILTER")
# echo "Got exclusions "
# Build grep pattern from exclusions (anchor to start of line, match until ==)
if [[ -n "$exclusions" ]] && [[ -s $REQS_FILTER ]] && [[ -s $REQS_BASE ]]; then
local tmp_file="$(mktemp)"
pattern=$(printf '%s\n' $exclusions | sed 's/^/^/; s/$//' | paste -sd'|' -)
# echo "got pattern"
# echo $pattern
# echo "grep -Ev \"$pattern\" \"$REQS_BASE\" | tee \"$tmp_file\""
grep -Ev "$pattern" "$REQS_BASE" | tee "$tmp_file" || true
# echo "ran filter"
mv $tmp_file $REQS_OUTPUT
else
# No exclusions, just copy
if ! [ $REQS_BASE = $REQS_OUTPUT ];then
cp "$REQS_BASE" "$REQS_OUTPUT"
fi
fi
# echo $(cat $REQS_OUTPUT)
}
echo "Prepending manual specifications..."
## Prepend manual requirements to auto-generated ones
tmp_file_merge="$(mktemp)"
tmp_file_main="$(mktemp)"
# reqs in manual override reqs in main
filter_reqs $REQS_MAIN $REQS_MANUAL $tmp_file_main
cat "$REQS_MANUAL" "$tmp_file_main" | grep -v "^#" | grep -v "^$" > "$tmp_file_merge"
mv "$tmp_file_merge" "$REQS_AUTO"
echo "Filtering from exclusions..."
## Filter auto-generated python dependencies using exclusions list
if [ -e "$REQS_EXCLUSIONS" ]; then
filter_reqs $REQS_AUTO $REQS_EXCLUSIONS $REQS_AUTO
fi
# sort $REQS_AUTO -o $REQS_AUTO
pip install pipdeptree
# get packages needed in this venv that are not part of this project's requirements
reqs_venv=$(mktemp)
python -m pipdeptree -f --warn silence \
| sed 's/^[[:space:]]*//' \
| sort -u \
| grep -v "/" \
| grep -v "Editable" \
| tee $reqs_venv
# remove packages in $reqs_venv that are part of this project's requiremnts
filter_reqs $reqs_venv $REQS_AUTO $reqs_venv
echo "Installing packages..."
pip install --ignore-installed -r $REQS_AUTO
echo "Installed packages!"
# Read package names (ignoring comments and empty lines)
echo "
packages=\$(grep -vE '^\s*(#|$)' \"$REQS_AUTO\" | cut -d'>' -f1 | cut -d'<' -f1 | cut -d'=' -f1 | tr '\n' ',' | sed 's/,$//')
"
if [ -s "$REQS_AUTO" ]; then
packages=$(grep -vE '^\s*(#|$)' "$REQS_AUTO" | cut -d'>' -f1 | cut -d'<' -f1 | cut -d'=' -f1 | tr '\n' ',' | sed 's/,$//')
else
packages=""
fi
echo "Generating recursive dependencies..."
# # Generate dependency tree only for these packages, recursively
python -m pipdeptree -f --warn silence -p "$packages" \
| sed 's/^[[:space:]]*//' \
| sort -u \
| grep -v "/" \
| grep -v "Editable" \
| tee "$REQS_AUTO"
echo "Filtering by exclusions..."
# remove packages in $reqs_installed that are included in $REQS_EXCLUSIONS
filter_reqs $REQS_AUTO $REQS_EXCLUSIONS $REQS_AUTO