python-env 3.65 KB
Newer Older
1 2 3 4 5 6
#!/bin/bash
##
# Use the Python virtual environment.
#

_PYTHONLIB_SHELL=false
7
_PYTHONLIB_ENVDIR=".env/venv"
8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58
_PYTHONLIB_COMMAND=()

function _pythonlib_parse() {

    local opt

    # Parse the command line
    while getopts ":he:s" opt ; do
        case $opt in
            e)
                _PYTHONLIB_ENVDIR="$OPTARG"
                ;;
            s)
                _PYTHONLIB_SHELL=true
                ;;
            h)
                cat <<EOM
Enter the Python environment.
Syntax: $(basename "$0") [<options>] [<commands>]
        $(basename "$0") -s
        source $(basename "$0") [<options>]
Options:
    -e <env-dir>    Specify the environment directory (default: $environment)
    -s              Start a shell in the environment
    -h              This help message

Note: Using 'source' only works with bash at present.
EOM
                exit
                ;;
        esac
    done

    _PYTHONLIB_COMMAND=("${@:${OPTIND}}")
    unset -f _PYTHONLIB_parse
}

_pythonlib_parse "$@"

if [[ ! -d "$_PYTHONLIB_ENVDIR" ]] ; then
    echo "Python environment directory '$_PYTHONLIB_ENVDIR' does not exist" >&2
elif [[ ! -f "$_PYTHONLIB_ENVDIR/bin/activate" ]] ; then
    echo "Python environment directory '$_PYTHONLIB_ENVDIR' was not set up properly" >&2
else
    # Canonicalise the environment directory
    _PYTHONLIB_ENVDIR="$(cd "${_PYTHONLIB_ENVDIR}" && pwd -P)"

    if [[ "${#_PYTHONLIB_COMMAND[@]}" != '0' ]] ; then
        # Commands were given; execute them in the environment
        source "${_PYTHONLIB_ENVDIR}/bin/activate"
        "${_PYTHONLIB_COMMAND[@]}"
59 60
        # And terminate with the return code
        exit $?
61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78
    elif "$_PYTHONLIB_SHELL" ; then
        echo "Dropping to shell"
        # Commands were not given, but a shell was requested
        if [[ "$SHELL" =~ /fish ]] ; then
            # Fish does not appear to be able to be given a startup file,
            # as far as can be seen.
            # BUT we can insert ourselves into the initialisation by
            # adding files to the conf.d directory.
            __magic_value="$RANDOM.$$"
            mkdir -p "${XDG_CONFIG_HOME:-${HOME}/.config}/fish/conf.d"
            cat <<EOM > "${XDG_CONFIG_HOME:-${HOME}/.config}/fish/conf.d/pythonlib.$__magic_value.fish"
set -l me "${XDG_CONFIG_HOME:-${HOME}/.config}/fish/conf.d/pythonlib.$__magic_value.fish"
if [ "\$__PYTHONLIB_MAGIC" = "$__magic_value" ]
    source "${_PYTHONLIB_ENVDIR}/bin/activate.fish"
    # Remove ourselves now that we've been used.
    rm "\$me"
else
    set -l hours_ago (math \\( (date +%s) - (stat --format '%Z' "\$me") \\) / \\( 60 \\* 60 \\))
79
    if test \$hours_ago -ge 2
80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108
        # This script hasn't been used for over 2 hours - something has
        # gone wrong, and it's not going to be invoked. It should really
        # have been run within moments.
        rm "\$me"
    end
end
EOM
            echo "Press ctrl-d, or use 'exit' to end shell."
            __PYTHONLIB_MAGIC=${__magic_value} fish
        elif [[ "$SHELL" =~ /bash ]] ; then
            # Start the bash shell, with the environment activated by
            # making the rcfile run the user's file, then the activation.
            echo "Press ctrl-d, or use 'exit' to end shell."
            bash -i --rcfile <(echo "source ~/.bashrc ; source '${_PYTHONLIB_ENVDIR}/bin/activate'")
        else
            echo "Shell '$SHELL' is not understood" >&2
            exit 1
        fi
        echo "Returned from Python environment shell"
    else
        # No commands were given; it's likely they source'd us to get the
        # correct environment.
        source "${_PYTHONLIB_ENVDIR}/bin/activate"
    fi
fi

unset _PYTHONLIB_SHELL
unset _PYTHONLIB_COMMAND
unset _PYTHONLIB_ENVDIR