# -*- 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 # Set the name of the virtualenv app to use. if [ "${VIRTUALENVWRAPPER_VIRTUALENV:-}" = "" ] then VIRTUALENVWRAPPER_VIRTUALENV="virtualenv" fi # Set the name of the virtualenv-clone app to use. if [ "${VIRTUALENVWRAPPER_VIRTUALENV_CLONE:-}" = "" ] then VIRTUALENVWRAPPER_VIRTUALENV_CLONE="virtualenv-clone" fi # Define script folder depending on the platorm (Win32/Unix) VIRTUALENVWRAPPER_ENV_BIN_DIR="bin" if [ "${OS:-}" = "Windows_NT" ] && ([ "${MSYSTEM:-}" = "MINGW32" ] || [ "${MSYSTEM:-}" = "MINGW64" ]) then # Only assign this for msys, cygwin use standard Unix paths # and its own python installation VIRTUALENVWRAPPER_ENV_BIN_DIR="Scripts" fi # 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 # Let the user tell us they never want to cd to projects # automatically. export VIRTUALENVWRAPPER_WORKON_CD=${VIRTUALENVWRAPPER_WORKON_CD:-1} # Remember where we are running from. if [ -z "${VIRTUALENVWRAPPER_SCRIPT:-}" ] then if [ -n "$BASH" ] then export VIRTUALENVWRAPPER_SCRIPT="$BASH_SOURCE" elif [ -n "$ZSH_VERSION" ] then export VIRTUALENVWRAPPER_SCRIPT="$0" else export VIRTUALENVWRAPPER_SCRIPT="${.sh.file}" fi fi # 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 -q "$@" else command \cd "$@" fi } 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 } 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 } 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 } # 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 } #HOOK_VERBOSE_OPTION="-q" # Function to wrap mktemp so tests can replace it for error condition # testing. function virtualenvwrapper_mktemp { command \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)" touch "$file" 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 } # Run the hooks function virtualenvwrapper_run_hook { typeset hook_script typeset result hook_script="$(virtualenvwrapper_tempfile ${1}-hook)" || return 1 # Use a subshell to run the python interpreter with hook_loader so # we can change the working directory. This avoids having the # Python 3 interpreter decide that its "prefix" is the virtualenv # if we happen to be inside the virtualenv when we start. ( \ virtualenvwrapper_cd "$WORKON_HOME" && "$VIRTUALENVWRAPPER_PYTHON" -m 'virtualenvwrapper.hook_loader' \ ${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 <&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 } # Verify that virtualenv is installed and visible function virtualenvwrapper_verify_virtualenv { virtualenvwrapper_verify_resource $VIRTUALENVWRAPPER_VIRTUALENV } function virtualenvwrapper_verify_virtualenv_clone { virtualenvwrapper_verify_resource $VIRTUALENVWRAPPER_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 } # 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 } # Help text for mkvirtualenv function virtualenvwrapper_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" $@; } # Create a new environment, in the WORKON_HOME. # # Usage: mkvirtualenv [options] ENVNAME # (where the options are passed directly to virtualenv) # #:help:mkvirtualenv: Create a new virtualenv in $WORKON_HOME function mkvirtualenv { typeset -a in_args typeset -a out_args typeset -i i typeset tst typeset a typeset envname typeset requirements typeset packages typeset interpreter typeset project 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]}" if [ ! -d "$project" ] then echo "Cannot associate project with $project, it is not a directory" 1>&2 return 1 fi project="$(virtualenvwrapper_absolutepath ${project})";; -h|--help) virtualenvwrapper_mkvirtualenv_help $a; return;; -i) i=$(( $i + 1 )); packages="$packages ${in_args[$i]}";; -p|--python*) if echo "$a" | grep -q "=" then interpreter="$(echo "$a" | cut -f2 -d=)" else i=$(( $i + 1 )) interpreter="${in_args[$i]}" fi;; -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" RC=$? [ $RC -ne 0 ] && return $RC 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" } #:help:rmvirtualenv: Remove a virtualenv function rmvirtualenv { virtualenvwrapper_verify_workon_home || return 1 if [ ${#@} = 0 ] then echo "Please specify an environment." >&2 return 1 fi # support to remove several environments typeset env_name # Must quote the parameters, as environments could have spaces in their names 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 if [ ! -d "$env_dir" ]; then echo "Did not find environment $env_dir to remove." >&2 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 } # 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. # Note that this is a little tricky, as there may be spaces in the path. # # 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. # This yields a single, space-separated line containing all matches. # 2. Replace the trailing newline with a space, so every # possible env has a space following it. # 3. Strip the bindir/activate script suffix, replacing it with # a slash, as that is an illegal character in a directory name. # This yields a slash-separated list of possible env names. # 4. Replace each slash with a newline to show the output one name per line. # 5. Eliminate any lines with * on them because that means there # were no envs. (virtualenvwrapper_cd "$WORKON_HOME" && echo */$VIRTUALENVWRAPPER_ENV_BIN_DIR/activate) 2>/dev/null \ | command \tr "\n" " " \ | command \sed "s|/$VIRTUALENVWRAPPER_ENV_BIN_DIR/activate |/|g" \ | command \tr "/" "\n" \ | command \sed "/^\s*$/d" \ | (unset GREP_OPTIONS; command \egrep -v '^\*$') 2>/dev/null } function _lsvirtualenv_usage { echo "lsvirtualenv [-blh]" echo " -b -- brief mode" echo " -l -- long mode" echo " -h -- this help message" } #:help:lsvirtualenv: list virtualenvs function lsvirtualenv { typeset long_mode=true if command -v "getopts" >/dev/null 2>&1 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 allvirtualenv showvirtualenv "$env_name" else virtualenvwrapper_show_workon_options fi } #:help:showvirtualenv: show details of a single virtualenv 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 virtualenvwrapper_run_hook "get_env_details" "$env_name" echo } # Show help for workon function virtualenvwrapper_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 "" echo " workon (-c|--cd) envname" echo "" echo " After activating the environment, cd to the associated" echo " project directory if it is set." echo "" echo " workon (-n|--no-cd) envname" echo "" echo " After activating the environment, do not cd to the" echo " associated project directory." echo "" } #:help:workon: list or change working virtualenvs function workon { typeset -a in_args typeset -a out_args in_args=( "$@" ) if [ -n "$ZSH_VERSION" ] then i=1 tst="-le" else i=0 tst="-lt" fi typeset cd_after_activate=$VIRTUALENVWRAPPER_WORKON_CD while [ $i $tst $# ] do a="${in_args[$i]}" case "$a" in -h|--help) virtualenvwrapper_workon_help; return 0;; -n|--no-cd) cd_after_activate=0;; -c|--cd) cd_after_activate=1;; *) if [ ${#out_args} -gt 0 ] then out_args=( "${out_args[@]-}" "$a" ) else out_args=( "$a" ) fi;; esac i=$(( $i + 1 )) done set -- "${out_args[@]}" typeset env_name="$1" if [ "$env_name" = "" ] then lsvirtualenv -b return 1 elif [ "$env_name" = "." ] then # The IFS default of breaking on whitespace causes issues if there # are spaces in the env_name, so change it. IFS='%' env_name="$(basename $(pwd))" unset IFS 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, but make sure it's the deactivate function # we set up type deactivate >/dev/null 2>&1 if [ $? -eq 0 ] then typeset -f deactivate | grep 'typeset env_postdeactivate_hook' >/dev/null 2>&1 if [ $? -eq 0 ] then deactivate unset -f deactivate >/dev/null 2>&1 fi 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 () { typeset env_postdeactivate_hook typeset old_env # 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_PROJECT_CD=$cd_after_activate virtualenvwrapper_run_hook "post_activate" return 0 } # 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/$VIRTUALENVWRAPPER_ENV_BIN_DIR/python" -V 2>&1 | cut -f2 -d' ' | cut -f-2 -d. } # 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.sysconfig; print(distutils.sysconfig.get_python_lib())" } # 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. # #:help:add2virtualenv: add directory to the import path 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 } # Does a ``cd`` to the site-packages directory of the currently-active # virtualenv. #:help:cdsitepackages: change to the site-packages directory 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" } # Does a ``cd`` to the root of the currently-active virtualenv. #:help:cdvirtualenv: change to the $VIRTUAL_ENV directory function cdvirtualenv { virtualenvwrapper_verify_workon_home || return 1 virtualenvwrapper_verify_active_environment || return 1 virtualenvwrapper_cd "$VIRTUAL_ENV/$1" } # Shows the content of the site-packages directory of the currently-active # virtualenv #:help:lssitepackages: list contents of the site-packages directory 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 } # Toggles the currently-active virtualenv between having and not having # access to the global site-packages. #:help:toggleglobalsitepackages: turn access to global site-packages on/off 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 } #:help:cpvirtualenv: 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 it's already in workon if [ ! -e "$WORKON_HOME/$src_name" ]; then # so it's 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" } # # 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 } # Given a virtualenv directory and a project directory, # set the virtualenv up to be associated with the # project #:help:setvirtualenvproject: associate a project directory with a virtualenv function setvirtualenvproject { typeset venv="$1" typeset prj="$2" if [ -z "$venv" ] then venv="$VIRTUAL_ENV" fi if [ -z "$prj" ] then prj="$(pwd)" else prj=$(virtualenvwrapper_absolutepath "${prj}") fi # If what we were given isn't a directory, see if it is under # $WORKON_HOME. if [ ! -d "$venv" ] then venv="$WORKON_HOME/$venv" fi if [ ! -d "$venv" ] then echo "No virtualenv $(basename $venv)" 1>&2 return 1 fi # Make sure we have a valid project setting if [ ! -d "$prj" ] then echo "Cannot associate virtualenv with \"$prj\", it is not a directory" 1>&2 return 1 fi echo "Setting project for $(basename $venv) to $prj" echo "$prj" > "$venv/$VIRTUALENVWRAPPER_PROJECT_FILENAME" } # Show help for mkproject function virtualenvwrapper_mkproject_help { echo "Usage: mkproject [-f|--force] [-t template] [virtualenv options] project_name" echo echo "-f, --force Create the virtualenv even if the project directory" echo " already exists" 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 } #:help:mkproject: 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 force typeset templates in_args=( "$@" ) force=0 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) virtualenvwrapper_mkproject_help; return;; -f|--force) force=1;; -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" -a $force -eq 0 ] then echo "Project $envname already exists." >&2 return 1 fi mkvirtualenv "$@" || return 1 virtualenvwrapper_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" virtualenvwrapper_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" "$PROJECT_HOME/$envname" done virtualenvwrapper_run_hook "project.post_mkproject" } #:help:cdproject: 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 virtualenvwrapper_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 } # # Temporary virtualenv # # Originally part of virtualenvwrapper.tmpenv plugin # #:help:mktmpenv: create a temporary virtualenv function mktmpenv { typeset tmpenvname typeset RC typeset -a in_args typeset -a out_args in_args=( "$@" ) if [ -n "$ZSH_VERSION" ] then i=1 tst="-le" else i=0 tst="-lt" fi typeset cd_after_activate=$VIRTUALENVWRAPPER_WORKON_CD while [ $i $tst $# ] do a="${in_args[$i]}" case "$a" in -n|--no-cd) cd_after_activate=0;; -c|--cd) cd_after_activate=1;; *) if [ ${#out_args} -gt 0 ] then out_args=( "${out_args[@]-}" "$a" ) else out_args=( "$a" ) fi;; esac i=$(( $i + 1 )) done set -- "${out_args[@]}" # 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 tmpenvname="tmp-$tmpenvname" # Create the environment mkvirtualenv "$@" "$tmpenvname" RC=$? if [ $RC -ne 0 ] then return $RC fi # Change working directory [ "$cd_after_activate" = "1" ] && 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/$VIRTUALENVWRAPPER_ENV_BIN_DIR/postdeactivate" < "$req_file" if [ -n "$(cat "$req_file")" ] then echo "Uninstalling packages:" cat "$req_file" echo pip uninstall -y $(cat "$req_file" | grep -v '^-f' | sed 's/>/=/g' | cut -f1 -d=) else echo "Nothing to remove." fi rm -f "$req_file" } # # Run a command in each virtualenv # #:help:allvirtualenv: run a command in all virtualenvs function allvirtualenv { virtualenvwrapper_verify_workon_home || return 1 typeset d # The IFS default of breaking on whitespace causes issues if there # are spaces in the env_name, so change it. IFS='%' virtualenvwrapper_show_workon_options | while read d do [ ! -d "$WORKON_HOME/$d" ] && continue echo "$d" echo "$d" | sed 's/./=/g' # Activate the environment, but not with workon # because we don't want to trigger any hooks. (source "$WORKON_HOME/$d/$VIRTUALENVWRAPPER_ENV_BIN_DIR/activate"; virtualenvwrapper_cd "$VIRTUAL_ENV"; "$@") echo done unset IFS } #:help:virtualenvwrapper: show this help message function virtualenvwrapper { cat <