Skip to content

Instantly share code, notes, and snippets.

@harobed
Created March 24, 2013 14:45
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 harobed/66ce862ee0f86475b8dc to your computer and use it in GitHub Desktop.
Save harobed/66ce862ee0f86475b8dc to your computer and use it in GitHub Desktop.
# -*- mode: shell-script -*-
#
# Shell functions to act as wrapper for Ian Bicking's virtualenv
# (http://pypi.python.org/pypi/virtualenv)
#
#
# Copyright Doug Hellmann, All Rights Reserved
#
# Permission to use, copy, modify, and distribute this software and its
# documentation for any purpose and without fee is hereby granted,
# provided that the above copyright notice appear in all copies and that
# both that copyright notice and this permission notice appear in
# supporting documentation, and that the name of Doug Hellmann not be used
# in advertising or publicity pertaining to distribution of the software
# without specific, written prior permission.
#
# DOUG HELLMANN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
# INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
# EVENT SHALL DOUG HELLMANN BE LIABLE FOR ANY SPECIAL, INDIRECT OR
# CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
# USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
# OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.
#
#
# Project home page: http://www.doughellmann.com/projects/virtualenvwrapper/
#
#
# Setup:
#
# 1. Create a directory to hold the virtual environments.
# (mkdir $HOME/.virtualenvs).
# 2. Add a line like "export WORKON_HOME=$HOME/.virtualenvs"
# to your .bashrc.
# 3. Add a line like "source /path/to/this/file/virtualenvwrapper.sh"
# to your .bashrc.
# 4. Run: source ~/.bashrc
# 5. Run: workon
# 6. A list of environments, empty, is printed.
# 7. Run: mkvirtualenv temp
# 8. Run: workon
# 9. This time, the "temp" environment is included.
# 10. Run: workon temp
# 11. The virtual environment is activated.
#
# Locate the global Python where virtualenvwrapper is installed.
if [ "$VIRTUALENVWRAPPER_PYTHON" = "" ]
then
VIRTUALENVWRAPPER_PYTHON="$(command \which python)"
fi
export VIRTUALENVWRAPPER_PYTHON
# Set the name of the virtualenv app to use.
if [ "$VIRTUALENVWRAPPER_VIRTUALENV" = "" ]
then
VIRTUALENVWRAPPER_VIRTUALENV="virtualenv"
fi
export VIRTUALENVWRAPPER_VIRTUALENV
# Set the name of the virtualenv-clone app to use.
if [ "$VIRTUALENVWRAPPER_VIRTUALENV_CLONE" = "" ]
then
VIRTUALENVWRAPPER_VIRTUALENV_CLONE="virtualenv-clone"
fi
export VIRTUALENVWRAPPER_VIRTUALENV_CLONE
# Define script folder depending on the platorm (Win32/Unix)
VIRTUALENVWRAPPER_ENV_BIN_DIR="bin"
if [ "$OS" = "Windows_NT" ] && [ "$MSYSTEM" = "MINGW32" ]
then
# Only assign this for msys, cygwin use standard Unix paths
# and its own python installation
VIRTUALENVWRAPPER_ENV_BIN_DIR="Scripts"
fi
export VIRTUALENVWRAPPER_ENV_BIN_DIR
# Let the user override the name of the file that holds the project
# directory name.
if [ "$VIRTUALENVWRAPPER_PROJECT_FILENAME" = "" ]
then
export VIRTUALENVWRAPPER_PROJECT_FILENAME=".project"
fi
export VIRTUALENVWRAPPER_PROJECT_FILENAME
# Portable shell scripting is hard, let's go shopping.
#
# People insist on aliasing commands like 'cd', either with a real
# alias or even a shell function. Under bash and zsh, "builtin" forces
# the use of a command that is part of the shell itself instead of an
# alias, function, or external command, while "command" does something
# similar but allows external commands. Under ksh "builtin" registers
# a new command from a shared library, but "command" will pick up
# existing builtin commands. We need to use a builtin for cd because
# we are trying to change the state of the current shell, so we use
# "builtin" for bash and zsh but "command" under ksh.
function virtualenvwrapper_cd {
if [ -n "$BASH" ]
then
builtin \cd "$@"
elif [ -n "$ZSH_VERSION" ]
then
builtin \cd "$@"
else
command \cd "$@"
fi
}
export -f virtualenvwrapper_cd
function virtualenvwrapper_expandpath {
if [ "$1" = "" ]; then
return 1
else
"$VIRTUALENVWRAPPER_PYTHON" -c "import os,sys; sys.stdout.write(os.path.normpath(os.path.expanduser(os.path.expandvars(\"$1\")))+'\n')"
return 0
fi
}
export -f virtualenvwrapper_expandpath
function virtualenvwrapper_absolutepath {
if [ "$1" = "" ]; then
return 1
else
"$VIRTUALENVWRAPPER_PYTHON" -c "import os,sys; sys.stdout.write(os.path.abspath(\"$1\")+'\n')"
return 0
fi
}
export -f virtualenvwrapper_absolutepath
function virtualenvwrapper_derive_workon_home {
typeset workon_home_dir="$WORKON_HOME"
# Make sure there is a default value for WORKON_HOME.
# You can override this setting in your .bashrc.
if [ "$workon_home_dir" = "" ]
then
workon_home_dir="$HOME/.virtualenvs"
fi
# If the path is relative, prefix it with $HOME
# (note: for compatibility)
if echo "$workon_home_dir" | (unset GREP_OPTIONS; command \grep '^[^/~]' > /dev/null)
then
workon_home_dir="$HOME/$WORKON_HOME"
fi
# Only call on Python to fix the path if it looks like the
# path might contain stuff to expand.
# (it might be possible to do this in shell, but I don't know a
# cross-shell-safe way of doing it -wolever)
if echo "$workon_home_dir" | (unset GREP_OPTIONS; command \egrep '([\$~]|//)' >/dev/null)
then
# This will normalize the path by:
# - Removing extra slashes (e.g., when TMPDIR ends in a slash)
# - Expanding variables (e.g., $foo)
# - Converting ~s to complete paths (e.g., ~/ to /home/brian/ and ~arthur to /home/arthur)
workon_home_dir=$(virtualenvwrapper_expandpath "$workon_home_dir")
fi
echo "$workon_home_dir"
return 0
}
export -f virtualenvwrapper_derive_workon_home
# Check if the WORKON_HOME directory exists,
# create it if it does not
# seperate from creating the files in it because this used to just error
# and maybe other things rely on the dir existing before that happens.
function virtualenvwrapper_verify_workon_home {
RC=0
if [ ! -d "$WORKON_HOME/" ]
then
if [ "$1" != "-q" ]
then
echo "NOTE: Virtual environments directory $WORKON_HOME does not exist. Creating..." 1>&2
fi
mkdir -p "$WORKON_HOME"
RC=$?
fi
return $RC
}
export -f virtualenvwrapper_verify_workon_home
#HOOK_VERBOSE_OPTION="-q"
# Function to wrap mktemp so tests can replace it for error condition
# testing.
function virtualenvwrapper_mktemp {
command \mktemp "$@"
}
export -f virtualenvwrapper_mktemp
# Expects 1 argument, the suffix for the new file.
function virtualenvwrapper_tempfile {
# Note: the 'X's must come last
typeset suffix=${1:-hook}
typeset file
file="$(virtualenvwrapper_mktemp -t virtualenvwrapper-$suffix-XXXXXXXXXX)"
if [ $? -ne 0 ] || [ -z "$file" ] || [ ! -f "$file" ]
then
echo "ERROR: virtualenvwrapper could not create a temporary file name." 1>&2
return 1
fi
echo $file
return 0
}
export -f virtualenvwrapper_tempfile
# Run the hooks
function virtualenvwrapper_run_hook {
typeset hook_script
typeset result
hook_script="$(virtualenvwrapper_tempfile ${1}-hook)" || return 1
"$VIRTUALENVWRAPPER_PYTHON" -c 'from virtualenvwrapper.hook_loader import main; main()' $HOOK_VERBOSE_OPTION --script "$hook_script" "$@"
result=$?
if [ $result -eq 0 ]
then
if [ ! -f "$hook_script" ]
then
echo "ERROR: virtualenvwrapper_run_hook could not find temporary file $hook_script" 1>&2
command \rm -f "$hook_script"
return 2
fi
# cat "$hook_script"
source "$hook_script"
elif [ "${1}" = "initialize" ]
then
cat - 1>&2 <<EOF
virtualenvwrapper.sh: There was a problem running the initialization hooks.
If Python could not import the module virtualenvwrapper.hook_loader,
check that virtualenv has been installed for
VIRTUALENVWRAPPER_PYTHON=$VIRTUALENVWRAPPER_PYTHON and that PATH is
set properly.
EOF
fi
command \rm -f "$hook_script"
return $result
}
export -f virtualenvwrapper_run_hook
# Set up tab completion. (Adapted from Arthur Koziel's version at
# http://arthurkoziel.com/2008/10/11/virtualenvwrapper-bash-completion/)
function virtualenvwrapper_setup_tab_completion {
if [ -n "$BASH" ] ; then
_virtualenvs () {
local cur="${COMP_WORDS[COMP_CWORD]}"
COMPREPLY=( $(compgen -W "`virtualenvwrapper_show_workon_options`" -- ${cur}) )
}
_cdvirtualenv_complete () {
local cur="$2"
COMPREPLY=( $(cdvirtualenv && compgen -d -- "${cur}" ) )
}
_cdsitepackages_complete () {
local cur="$2"
COMPREPLY=( $(cdsitepackages && compgen -d -- "${cur}" ) )
}
complete -o nospace -F _cdvirtualenv_complete -S/ cdvirtualenv
complete -o nospace -F _cdsitepackages_complete -S/ cdsitepackages
complete -o default -o nospace -F _virtualenvs workon
complete -o default -o nospace -F _virtualenvs rmvirtualenv
complete -o default -o nospace -F _virtualenvs cpvirtualenv
complete -o default -o nospace -F _virtualenvs showvirtualenv
elif [ -n "$ZSH_VERSION" ] ; then
_virtualenvs () {
reply=( $(virtualenvwrapper_show_workon_options) )
}
_cdvirtualenv_complete () {
reply=( $(cdvirtualenv && ls -d ${1}*) )
}
_cdsitepackages_complete () {
reply=( $(cdsitepackages && ls -d ${1}*) )
}
compctl -K _virtualenvs workon rmvirtualenv cpvirtualenv showvirtualenv
compctl -K _cdvirtualenv_complete cdvirtualenv
compctl -K _cdsitepackages_complete cdsitepackages
fi
}
export -f virtualenvwrapper_setup_tab_completion
# Set up virtualenvwrapper properly
function virtualenvwrapper_initialize {
export WORKON_HOME="$(virtualenvwrapper_derive_workon_home)"
virtualenvwrapper_verify_workon_home -q || return 1
# Set the location of the hook scripts
if [ "$VIRTUALENVWRAPPER_HOOK_DIR" = "" ]
then
export VIRTUALENVWRAPPER_HOOK_DIR="$WORKON_HOME"
fi
virtualenvwrapper_run_hook "initialize"
virtualenvwrapper_setup_tab_completion
return 0
}
export -f virtualenvwrapper_initialize
# Verify that the passed resource is in path and exists
function virtualenvwrapper_verify_resource {
typeset exe_path=$(command \which "$1" | (unset GREP_OPTIONS; command \grep -v "not found"))
if [ "$exe_path" = "" ]
then
echo "ERROR: virtualenvwrapper could not find $1 in your path" >&2
return 1
fi
if [ ! -e "$exe_path" ]
then
echo "ERROR: Found $1 in path as \"$exe_path\" but that does not exist" >&2
return 1
fi
return 0
}
export -f virtualenvwrapper_verify_resource
# Verify that virtualenv is installed and visible
function virtualenvwrapper_verify_virtualenv {
virtualenvwrapper_verify_resource $VIRTUALENVWRAPPER_VIRTUALENV
}
export -f virtualenvwrapper_verify_virtualenv
function virtualenvwrapper_verify_virtualenv_clone {
virtualenvwrapper_verify_resource $VIRTUALENVWRAPPER_VIRTUALENV_CLONE
}
export -f virtualenvwrapper_verify_virtualenv_clone
# Verify that the requested environment exists
function virtualenvwrapper_verify_workon_environment {
typeset env_name="$1"
if [ ! -d "$WORKON_HOME/$env_name" ]
then
echo "ERROR: Environment '$env_name' does not exist. Create it with 'mkvirtualenv $env_name'." >&2
return 1
fi
return 0
}
export -f virtualenvwrapper_verify_workon_environment
# Verify that the active environment exists
function virtualenvwrapper_verify_active_environment {
if [ ! -n "${VIRTUAL_ENV}" ] || [ ! -d "${VIRTUAL_ENV}" ]
then
echo "ERROR: no virtualenv active, or active virtualenv is missing" >&2
return 1
fi
return 0
}
export -f virtualenvwrapper_verify_active_environment
# Help text for mkvirtualenv
function mkvirtualenv_help {
echo "Usage: mkvirtualenv [-a project_path] [-i package] [-r requirements_file] [virtualenv options] env_name"
echo
echo " -a project_path"
echo
echo " Provide a full path to a project directory to associate with"
echo " the new environment."
echo
echo " -i package"
echo
echo " Install a package after the environment is created."
echo " This option may be repeated."
echo
echo " -r requirements_file"
echo
echo " Provide a pip requirements file to install a base set of packages"
echo " into the new environment."
echo;
echo 'virtualenv help:';
echo;
"$VIRTUALENVWRAPPER_VIRTUALENV" $@;
}
export -f mkvirtualenv_help
# Create a new environment, in the WORKON_HOME.
#
# Usage: mkvirtualenv [options] ENVNAME
# (where the options are passed directly to virtualenv)
#
function mkvirtualenv {
typeset -a in_args
typeset -a out_args
typeset -i i
typeset tst
typeset a
typeset envname
typeset requirements
typeset packages
in_args=( "$@" )
if [ -n "$ZSH_VERSION" ]
then
i=1
tst="-le"
else
i=0
tst="-lt"
fi
while [ $i $tst $# ]
do
a="${in_args[$i]}"
# echo "arg $i : $a"
case "$a" in
-a)
i=$(( $i + 1 ));
project="${in_args[$i]}";;
-h|--help)
mkvirtualenv_help $a;
return;;
-i)
i=$(( $i + 1 ));
packages="$packages ${in_args[$i]}";;
-p|--python)
i=$(( $i + 1 ));
interpreter="${in_args[$i]}";
interpreter=$(virtualenvwrapper_absolutepath "$interpreter");;
-r)
i=$(( $i + 1 ));
requirements="${in_args[$i]}";
requirements=$(virtualenvwrapper_expandpath "$requirements");;
*)
if [ ${#out_args} -gt 0 ]
then
out_args=( "${out_args[@]-}" "$a" )
else
out_args=( "$a" )
fi;;
esac
i=$(( $i + 1 ))
done
if [ ! -z $interpreter ]
then
out_args=( "--python=$interpreter" ${out_args[@]} )
fi;
set -- "${out_args[@]}"
eval "envname=\$$#"
virtualenvwrapper_verify_workon_home || return 1
virtualenvwrapper_verify_virtualenv || return 1
(
[ -n "$ZSH_VERSION" ] && setopt SH_WORD_SPLIT
virtualenvwrapper_cd "$WORKON_HOME" &&
"$VIRTUALENVWRAPPER_VIRTUALENV" $VIRTUALENVWRAPPER_VIRTUALENV_ARGS "$@" &&
[ -d "$WORKON_HOME/$envname" ] && \
virtualenvwrapper_run_hook "pre_mkvirtualenv" "$envname"
)
typeset RC=$?
[ $RC -ne 0 ] && return $RC
# If they passed a help option or got an error from virtualenv,
# the environment won't exist. Use that to tell whether
# we should switch to the environment and run the hook.
[ ! -d "$WORKON_HOME/$envname" ] && return 0
# If they gave us a project directory, set it up now
# so the activate hooks can find it.
if [ ! -z "$project" ]
then
setvirtualenvproject "$WORKON_HOME/$envname" "$project"
fi
# Now activate the new environment
workon "$envname"
if [ ! -z "$requirements" ]
then
pip install -r "$requirements"
fi
for a in $packages
do
pip install $a
done
virtualenvwrapper_run_hook "post_mkvirtualenv"
}
export -f mkvirtualenv
# Remove an environment, in the WORKON_HOME.
function rmvirtualenv {
virtualenvwrapper_verify_workon_home || return 1
if [ ${#@} = 0 ]
then
echo "Please specify an enviroment." >&2
return 1
fi
# support to remove several environments
typeset env_name
for env_name in $@
do
echo "Removing $env_name..."
typeset env_dir="$WORKON_HOME/$env_name"
if [ "$VIRTUAL_ENV" = "$env_dir" ]
then
echo "ERROR: You cannot remove the active environment ('$env_name')." >&2
echo "Either switch to another environment, or run 'deactivate'." >&2
return 1
fi
# Move out of the current directory to one known to be
# safe, in case we are inside the environment somewhere.
typeset prior_dir="$(pwd)"
virtualenvwrapper_cd "$WORKON_HOME"
virtualenvwrapper_run_hook "pre_rmvirtualenv" "$env_name"
command \rm -rf "$env_dir"
virtualenvwrapper_run_hook "post_rmvirtualenv" "$env_name"
# If the directory we used to be in still exists, move back to it.
if [ -d "$prior_dir" ]
then
virtualenvwrapper_cd "$prior_dir"
fi
done
}
export -f rmvirtualenv
# List the available environments.
function virtualenvwrapper_show_workon_options {
virtualenvwrapper_verify_workon_home || return 1
# NOTE: DO NOT use ls or cd here because colorized versions spew control
# characters into the output list.
# echo seems a little faster than find, even with -depth 3.
#
# 1. Look for environments by finding the activate scripts.
# Use a subshell so we can suppress the message printed
# by zsh if the glob pattern fails to match any files.
# 2. Strip the WORKON_HOME prefix from each name.
# 3. Strip the bindir/activate script suffix.
# 4. Format the output to show one name on a line.
# 5. Eliminate any lines with * on them because that means there
# were no envs.
(echo $WORKON_HOME/*/$VIRTUALENVWRAPPER_ENV_BIN_DIR/activate) 2>/dev/null \
| command \sed "s|$WORKON_HOME/||g" \
| command \sed "s|/$VIRTUALENVWRAPPER_ENV_BIN_DIR/activate||g" \
| command \fmt -w 1 \
| (unset GREP_OPTIONS; command \egrep -v '^\*$') 2>/dev/null
}
export -f virtualenvwrapper_show_workon_options
function _lsvirtualenv_usage {
echo "lsvirtualenv [-blh]"
echo " -b -- brief mode"
echo " -l -- long mode"
echo " -h -- this help message"
}
# List virtual environments
#
# Usage: lsvirtualenv [-l]
function lsvirtualenv {
typeset long_mode=true
if command -v "getopts" &> /dev/null
then
# Use getopts when possible
OPTIND=1
while getopts ":blh" opt "$@"
do
case "$opt" in
l) long_mode=true;;
b) long_mode=false;;
h) _lsvirtualenv_usage;
return 1;;
?) echo "Invalid option: -$OPTARG" >&2;
_lsvirtualenv_usage;
return 1;;
esac
done
else
# fallback on getopt for other shell
typeset -a args
args=($(getopt blh "$@"))
if [ $? != 0 ]
then
_lsvirtualenv_usage
return 1
fi
for opt in $args
do
case "$opt" in
-l) long_mode=true;;
-b) long_mode=false;;
-h) _lsvirtualenv_usage;
return 1;;
esac
done
fi
if $long_mode
then
for env_name in $(virtualenvwrapper_show_workon_options)
do
showvirtualenv "$env_name"
done
else
virtualenvwrapper_show_workon_options
fi
}
export -f lsvirtualenv
# Show details of a virtualenv
#
# Usage: showvirtualenv [env]
function showvirtualenv {
typeset env_name="$1"
if [ -z "$env_name" ]
then
if [ -z "$VIRTUAL_ENV" ]
then
echo "showvirtualenv [env]"
return 1
fi
env_name=$(basename $VIRTUAL_ENV)
fi
echo -n "$env_name"
virtualenvwrapper_run_hook "get_env_details" "$env_name"
echo
}
export -f showvirtualenv
# Show help for workon
function workon_help {
echo "Usage: workon env_name"
echo ""
echo " Deactivate any currently activated virtualenv"
echo " and activate the named environment, triggering"
echo " any hooks in the process."
echo ""
echo " workon"
echo ""
echo " Print a list of available environments."
echo " (See also lsvirtualenv -b)"
echo ""
echo " workon (-h|--help)"
echo ""
echo " Show this help message."
echo ""
}
export -f workon_help
# List or change working virtual environments
#
# Usage: workon [environment_name]
#
function workon {
in_args=( "$@" )
if [ -n "$ZSH_VERSION" ]
then
i=1
tst="-le"
else
i=0
tst="-lt"
fi
while [ $i $tst $# ]
do
a="${in_args[$i]}"
case "$a" in
-h|--help)
workon_help;
return 0;;
esac
i=$(( $i + 1 ))
done
typeset env_name="$1"
if [ "$env_name" = "" ]
then
lsvirtualenv -b
return 1
fi
virtualenvwrapper_verify_workon_home || return 1
virtualenvwrapper_verify_workon_environment $env_name || return 1
activate="$WORKON_HOME/$env_name/$VIRTUALENVWRAPPER_ENV_BIN_DIR/activate"
if [ ! -f "$activate" ]
then
echo "ERROR: Environment '$WORKON_HOME/$env_name' does not contain an activate script." >&2
return 1
fi
# Deactivate any current environment "destructively"
# before switching so we use our override function,
# if it exists.
type deactivate >/dev/null 2>&1
if [ $? -eq 0 ]
then
deactivate
unset -f deactivate >/dev/null 2>&1
fi
virtualenvwrapper_run_hook "pre_activate" "$env_name"
source "$activate"
# Save the deactivate function from virtualenv under a different name
virtualenvwrapper_original_deactivate=`typeset -f deactivate | sed 's/deactivate/virtualenv_deactivate/g'`
eval "$virtualenvwrapper_original_deactivate"
unset -f deactivate >/dev/null 2>&1
# Replace the deactivate() function with a wrapper.
eval 'deactivate () {
# Call the local hook before the global so we can undo
# any settings made by the local postactivate first.
virtualenvwrapper_run_hook "pre_deactivate"
env_postdeactivate_hook="$VIRTUAL_ENV/$VIRTUALENVWRAPPER_ENV_BIN_DIR/postdeactivate"
old_env=$(basename "$VIRTUAL_ENV")
# Call the original function.
virtualenv_deactivate $1
virtualenvwrapper_run_hook "post_deactivate" "$old_env"
if [ ! "$1" = "nondestructive" ]
then
# Remove this function
unset -f virtualenv_deactivate >/dev/null 2>&1
unset -f deactivate >/dev/null 2>&1
fi
}'
virtualenvwrapper_run_hook "post_activate"
return 0
}
export -f workon
# Prints the Python version string for the current interpreter.
function virtualenvwrapper_get_python_version {
# Uses the Python from the virtualenv rather than
# VIRTUALENVWRAPPER_PYTHON because we're trying to determine the
# version installed there so we can build up the path to the
# site-packages directory.
"$VIRTUAL_ENV/bin/python" -V 2>&1 | cut -f2 -d' ' | cut -f-2 -d.
}
export -f virtualenvwrapper_get_python_version
# Prints the path to the site-packages directory for the current environment.
function virtualenvwrapper_get_site_packages_dir {
"$VIRTUAL_ENV/$VIRTUALENVWRAPPER_ENV_BIN_DIR/python" -c "import distutils; print(distutils.sysconfig.get_python_lib())"
}
export -f virtualenvwrapper_get_site_packages_dir
# Path management for packages outside of the virtual env.
# Based on a contribution from James Bennett and Jannis Leidel.
#
# add2virtualenv directory1 directory2 ...
#
# Adds the specified directories to the Python path for the
# currently-active virtualenv. This will be done by placing the
# directory names in a path file named
# "virtualenv_path_extensions.pth" inside the virtualenv's
# site-packages directory; if this file does not exist, it will be
# created first.
function add2virtualenv {
virtualenvwrapper_verify_workon_home || return 1
virtualenvwrapper_verify_active_environment || return 1
site_packages="`virtualenvwrapper_get_site_packages_dir`"
if [ ! -d "${site_packages}" ]
then
echo "ERROR: currently-active virtualenv does not appear to have a site-packages directory" >&2
return 1
fi
# Prefix with _ to ensure we are loaded as early as possible,
# and at least before easy_install.pth.
path_file="$site_packages/_virtualenv_path_extensions.pth"
if [ "$*" = "" ]
then
echo "Usage: add2virtualenv dir [dir ...]"
if [ -f "$path_file" ]
then
echo
echo "Existing paths:"
cat "$path_file" | grep -v "^import"
fi
return 1
fi
remove=0
if [ "$1" = "-d" ]
then
remove=1
shift
fi
if [ ! -f "$path_file" ]
then
echo "import sys; sys.__plen = len(sys.path)" > "$path_file" || return 1
echo "import sys; new=sys.path[sys.__plen:]; del sys.path[sys.__plen:]; p=getattr(sys,'__egginsert',0); sys.path[p:p]=new; sys.__egginsert = p+len(new)" >> "$path_file" || return 1
fi
for pydir in "$@"
do
absolute_path=$(virtualenvwrapper_absolutepath "$pydir")
if [ "$absolute_path" != "$pydir" ]
then
echo "Warning: Converting \"$pydir\" to \"$absolute_path\"" 1>&2
fi
if [ $remove -eq 1 ]
then
sed -i.tmp "\:^$absolute_path$: d" "$path_file"
else
sed -i.tmp '1 a\
'"$absolute_path"'
' "$path_file"
fi
rm -f "${path_file}.tmp"
done
return 0
}
export -f add2virtualenv
# Does a ``cd`` to the site-packages directory of the currently-active
# virtualenv.
function cdsitepackages {
virtualenvwrapper_verify_workon_home || return 1
virtualenvwrapper_verify_active_environment || return 1
typeset site_packages="`virtualenvwrapper_get_site_packages_dir`"
virtualenvwrapper_cd "$site_packages"/$1
}
export -f cdsitepackages
# Does a ``cd`` to the root of the currently-active virtualenv.
function cdvirtualenv {
virtualenvwrapper_verify_workon_home || return 1
virtualenvwrapper_verify_active_environment || return 1
virtualenvwrapper_cd $VIRTUAL_ENV/$1
}
export -f cdvirtualenv
# Shows the content of the site-packages directory of the currently-active
# virtualenv
function lssitepackages {
virtualenvwrapper_verify_workon_home || return 1
virtualenvwrapper_verify_active_environment || return 1
typeset site_packages="`virtualenvwrapper_get_site_packages_dir`"
ls $@ "$site_packages"
path_file="$site_packages/_virtualenv_path_extensions.pth"
if [ -f "$path_file" ]
then
echo
echo "_virtualenv_path_extensions.pth:"
cat "$path_file"
fi
}
export -f lssitepackages
# Toggles the currently-active virtualenv between having and not having
# access to the global site-packages.
function toggleglobalsitepackages {
virtualenvwrapper_verify_workon_home || return 1
virtualenvwrapper_verify_active_environment || return 1
typeset no_global_site_packages_file="`virtualenvwrapper_get_site_packages_dir`/../no-global-site-packages.txt"
if [ -f $no_global_site_packages_file ]; then
rm $no_global_site_packages_file
[ "$1" = "-q" ] || echo "Enabled global site-packages"
else
touch $no_global_site_packages_file
[ "$1" = "-q" ] || echo "Disabled global site-packages"
fi
}
export -f toggleglobalsitepackages
# Duplicate the named virtualenv to make a new one.
function cpvirtualenv {
virtualenvwrapper_verify_workon_home || return 1
virtualenvwrapper_verify_virtualenv_clone || return 1
typeset src_name="$1"
typeset trg_name="$2"
typeset src
typeset trg
# without a source there is nothing to do
if [ "$src_name" = "" ]; then
echo "Please provide a valid virtualenv to copy."
return 1
else
# see if its already in workon
if [ ! -e "$WORKON_HOME/$src_name" ]; then
# so its a virtualenv we are importing
# make sure we have a full path
# and get the name
src=$(virtualenvwrapper_expandpath "$src_name")
# final verification
if [ ! -e "$src" ]; then
echo "Please provide a valid virtualenv to copy."
return 1
fi
src_name=$(basename "$src")
else
src="$WORKON_HOME/$src_name"
fi
fi
if [ "$trg_name" = "" ]; then
# target not given, assume
# same as source
trg="$WORKON_HOME/$src_name"
trg_name="$src_name"
else
trg="$WORKON_HOME/$trg_name"
fi
trg=$(virtualenvwrapper_expandpath "$trg")
# validate trg does not already exist
# catch copying virtualenv in workon home
# to workon home
if [ -e "$trg" ]; then
echo "$trg_name virtualenv already exists."
return 1
fi
echo "Copying $src_name as $trg_name..."
(
[ -n "$ZSH_VERSION" ] && setopt SH_WORD_SPLIT
virtualenvwrapper_cd "$WORKON_HOME" &&
"$VIRTUALENVWRAPPER_VIRTUALENV_CLONE" "$src" "$trg"
[ -d "$trg" ] &&
virtualenvwrapper_run_hook "pre_cpvirtualenv" "$src" "$trg_name" &&
virtualenvwrapper_run_hook "pre_mkvirtualenv" "$trg_name"
)
typeset RC=$?
[ $RC -ne 0 ] && return $RC
[ ! -d "$WORKON_HOME/$trg_name" ] && return 1
# Now activate the new environment
workon "$trg_name"
virtualenvwrapper_run_hook "post_mkvirtualenv"
virtualenvwrapper_run_hook "post_cpvirtualenv"
}
export -f cpvirtualenv
#
# virtualenvwrapper project functions
#
# Verify that the PROJECT_HOME directory exists
function virtualenvwrapper_verify_project_home {
if [ -z "$PROJECT_HOME" ]
then
echo "ERROR: Set the PROJECT_HOME shell variable to the name of the directory where projects should be created." >&2
return 1
fi
if [ ! -d "$PROJECT_HOME" ]
then
[ "$1" != "-q" ] && echo "ERROR: Project directory '$PROJECT_HOME' does not exist. Create it or set PROJECT_HOME to an existing directory." >&2
return 1
fi
return 0
}
export -f virtualenvwrapper_verify_project_home
# Given a virtualenv directory and a project directory,
# set the virtualenv up to be associated with the
# project
function setvirtualenvproject {
typeset venv="$1"
typeset prj="$2"
if [ -z "$venv" ]
then
venv="$VIRTUAL_ENV"
fi
if [ -z "$prj" ]
then
prj="$(pwd)"
fi
echo "Setting project for $(basename $venv) to $prj"
echo "$prj" > "$venv/$VIRTUALENVWRAPPER_PROJECT_FILENAME"
}
export -f setvirtualenvproject
# Show help for mkproject
function mkproject_help {
echo "Usage: mkproject [-t template] [virtualenv options] project_name"
echo ""
echo "Multiple templates may be selected. They are applied in the order"
echo "specified on the command line."
echo;
echo "mkvirtualenv help:"
echo
mkvirtualenv -h;
echo
echo "Available project templates:"
echo
"$VIRTUALENVWRAPPER_PYTHON" -c 'from virtualenvwrapper.hook_loader import main; main()' -l project.template
}
export -f mkproject_help
# Create a new project directory and its associated virtualenv.
function mkproject {
typeset -a in_args
typeset -a out_args
typeset -i i
typeset tst
typeset a
typeset t
typeset templates
in_args=( "$@" )
if [ -n "$ZSH_VERSION" ]
then
i=1
tst="-le"
else
i=0
tst="-lt"
fi
while [ $i $tst $# ]
do
a="${in_args[$i]}"
case "$a" in
-h|--help)
mkproject_help;
return;;
-t)
i=$(( $i + 1 ));
templates="$templates ${in_args[$i]}";;
*)
if [ ${#out_args} -gt 0 ]
then
out_args=( "${out_args[@]-}" "$a" )
else
out_args=( "$a" )
fi;;
esac
i=$(( $i + 1 ))
done
set -- "${out_args[@]}"
# echo "templates $templates"
# echo "remainder $@"
# return 0
eval "typeset envname=\$$#"
virtualenvwrapper_verify_project_home || return 1
if [ -d "$PROJECT_HOME/$envname" ]
then
echo "Project $envname already exists." >&2
return 1
fi
mkvirtualenv "$@" || return 1
cd "$PROJECT_HOME"
virtualenvwrapper_run_hook "project.pre_mkproject" $envname
echo "Creating $PROJECT_HOME/$envname"
mkdir -p "$PROJECT_HOME/$envname"
setvirtualenvproject "$VIRTUAL_ENV" "$PROJECT_HOME/$envname"
cd "$PROJECT_HOME/$envname"
for t in $templates
do
echo
echo "Applying template $t"
# For some reason zsh insists on prefixing the template
# names with a space, so strip them out before passing
# the value to the hook loader.
virtualenvwrapper_run_hook --name $(echo $t | sed 's/^ //') "project.template" $envname
done
virtualenvwrapper_run_hook "project.post_mkproject"
}
export -f mkproject
# Change directory to the active project
function cdproject {
virtualenvwrapper_verify_workon_home || return 1
virtualenvwrapper_verify_active_environment || return 1
if [ -f "$VIRTUAL_ENV/$VIRTUALENVWRAPPER_PROJECT_FILENAME" ]
then
typeset project_dir=$(cat "$VIRTUAL_ENV/$VIRTUALENVWRAPPER_PROJECT_FILENAME")
if [ ! -z "$project_dir" ]
then
cd "$project_dir"
else
echo "Project directory $project_dir does not exist" 1>&2
return 1
fi
else
echo "No project set in $VIRTUAL_ENV/$VIRTUALENVWRAPPER_PROJECT_FILENAME" 1>&2
return 1
fi
return 0
}
export -f cdproject
#
# Temporary virtualenv
#
# Originally part of virtualenvwrapper.tmpenv plugin
#
mktmpenv() {
typeset tmpenvname
typeset RC
# Generate a unique temporary name
tmpenvname=$("$VIRTUALENVWRAPPER_PYTHON" -c 'import uuid,sys; sys.stdout.write(uuid.uuid4()+"\n")' 2>/dev/null)
if [ -z "$tmpenvname" ]
then
# This python does not support uuid
tmpenvname=$("$VIRTUALENVWRAPPER_PYTHON" -c 'import random,sys; sys.stdout.write(hex(random.getrandbits(64))[2:-1]+"\n")' 2>/dev/null)
fi
# Create the environment
mkvirtualenv "$@" "$tmpenvname"
RC=$?
if [ $RC -ne 0 ]
then
return $RC
fi
# Change working directory
cdvirtualenv
# Create the tmpenv marker file
echo "This is a temporary environment. It will be deleted when you run 'deactivate'." | tee "$VIRTUAL_ENV/README.tmpenv"
# Update the postdeactivate script
cat - >> "$VIRTUAL_ENV/bin/postdeactivate" <<EOF
if [ -f "$VIRTUAL_ENV/README.tmpenv" ]
then
echo "Removing temporary environment:" $(basename "$VIRTUAL_ENV")
rmvirtualenv $(basename "$VIRTUAL_ENV")
fi
EOF
}
#
# Invoke the initialization functions
#
virtualenvwrapper_initialize
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment