Skip to content

Instantly share code, notes, and snippets.

@tomwhoiscontrary
Created February 18, 2020 19:40
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tomwhoiscontrary/a4b4136bf4615d1488dbf6f335543bf8 to your computer and use it in GitHub Desktop.
Save tomwhoiscontrary/a4b4136bf4615d1488dbf6f335543bf8 to your computer and use it in GitHub Desktop.
My super sweet Python run-module-in-a-venv script
#! /bin/bash -eu
shopt -s failglob
force=
while getopts "f" flag
do
case $flag in
f) force=y ;;
esac
done
shift $((OPTIND - 1))
module_path=$1
log() {
echo "$@" >&2
}
die() {
log "$@"
exit 1
}
[[ -e $module_path ]] || die "module does not exist: ${module_path}"
[[ -d $module_path ]] || die "module is not a directory: ${module_path}"
[[ -f $module_path/__main__.py ]] || die "module does not have a top-level script: ${module_path}"
venv_path=${module_path}_venv
cmp_optional() {
[[ ! -e $1 && ! -e $2 ]] && return 0
[[ -e $1 && -e $2 ]] || return 1
cmp --silent $1 $2
}
if [[ -e $venv_path ]]
then
if [[ -n "$force" ]]
then
log "discarding venv - force requested"
rm -r $venv_path
fi
if ! cmp_optional $module_path/requirements.txt $venv_path/requirements.txt
then
log "discarding venv - requirements have changed"
rm -r $venv_path
fi
fi
if [[ ! -e $venv_path ]]
then
log "creating venv at ${venv_path}"
python3 -m venv $venv_path
if [[ -f $module_path/requirements.txt ]]
then
cp $module_path/requirements.txt $venv_path/
$venv_path/bin/pip install -r $venv_path/requirements.txt
fi
ln -s $(readlink -f $module_path) $venv_path/lib/*/site-packages/
fi
exec $venv_path/bin/python -m $(basename $module_path)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment