#!/usr/bin/env bash shopt -s extglob shopt -s nullglob # This is necessary since this script is sometimes sourced from # subshells that don't have the variables from bin/compile. # Remove this once we no longer wrap all the things in `sub_env`. BIN_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd) ROOT_DIR=$(dirname "${BIN_DIR}") # shellcheck source=vendor/buildpack-stdlib_v8.sh source "${ROOT_DIR}/vendor/buildpack-stdlib_v8.sh" if [ "$(uname)" == Darwin ]; then sed() { command sed -l "$@"; } else sed() { command sed -u "$@"; } fi # Syntax sugar. indent() { sed "s/^/ /" } # Clean up pip output cleanup() { sed -e 's/\.\.\.\+/.../g' | sed -e '/already satisfied/Id' | sed -e '/No files were found to uninstall/Id' | sed -e '/Overwriting/Id' | sed -e '/python executable/Id' | sed -e '/no previously-included files/Id' } # Buildpack Steps. puts-step() { echo "-----> $*" } # Buildpack Warnings. puts-warn() { echo " ! $*" } # Does some serious copying. deep-cp() { declare source="$1" target="$2" mkdir -p "$target" # cp doesn't like being called without source params, # so make sure they expand to something first. # subshell to avoid surprising caller with shopts. ( shopt -s nullglob dotglob set -- "$source"/!(tmp|.|..) [[ $# == 0 ]] || cp -a "$@" "$target" ) } # Measure the size of the Python installation. measure-size() { echo "$(du -s .heroku/python 2>/dev/null || echo 0) | awk '{print $1}')" } # Python version operator > version_gt() { test "$(printf '%s\n' "$@" | sort -V | head -n 1)" != "$1"; } # Python verison operator >= version_gte() { if [ "$1" == "$2" ]; then return 0 fi version_gt "$1" "$2" } # Check if Python 2 python2_check() { VERSION="$1" version_gte "$VERSION" "python-2.7.0" && version_gt "python-3.0.0" "$VERSION" } # Check if Python 3 python3_check() { VERSION="$1" version_gte "$VERSION" "python-3.0.0" && version_gt "python-4.0.0" "$VERSION" } # Check if Python version needs to install SQLite3 python_sqlite3_check() { VERSION="$1" MIN_PYTHON_3="python-3.5.6" MIN_PYTHON_2="python-2.7.15" ( python2_check "$VERSION" && version_gte "$VERSION" "$MIN_PYTHON_2" ) \ || ( python3_check "$VERSION" && version_gte "$VERSION" "$MIN_PYTHON_3" ) } is_module_available() { # Returns 0 is the specified module exists, otherwise returns 1. # Uses pkgutil rather than pkg_resources or pip's CLI, since pkgutil exists # in the stdlib, and doesn't depend on the choice of package manager. local module_name="${1}" python -c "import sys, pkgutil; sys.exit(0 if pkgutil.find_loader('${module_name}') else 1)" }