What goes under the hood of `mkvirtualenv` command?

virtualenv, virtualenvwrapper

Solution

So this is the line that does the trick.

(
    [ -n "$ZSH_VERSION" ] && setopt SH_WORD_SPLIT
    \cd "$WORKON_HOME" &&
    "$VIRTUALENVWRAPPER_VIRTUALENV" $VIRTUALENVWRAPPER_VIRTUALENV_ARGS "$@" &&
    [ -d "$WORKON_HOME/$envname" ] && \
        virtualenvwrapper_run_hook "pre_mkvirtualenv" "$envname"
)

`$VIRTUALENVWRAPPER_VIRTUALENV` is in fact the location of where the current `virtualenv` program resides.

In terminal,

Calvins-MacBook-Pro.local ttys004 Mon Apr 23 13:24:14 |~|
calvin$ which $VIRTUALENVWRAPPER_VIRTUALENV
/opt/local/library/Frameworks/Python.framework/Versions/2.7/bin/virtualenv

Mytsery solved.

Problem

I am curious about what happens under the hood of the `mkvirtualenv` command and so I am trying to understand how it calls `virtualenv`. The lowest hanging fruit is to figure where the virtualenv program is located after installation and where the mkvirtualenv program is located after installation. So:- ``` Calvins-MacBook-Pro.local ttys006 Mon Apr 23 12:31:07 |~| calvin$ which mkvirtualenv Calvins-MacBook-Pro.local ttys006 Mon Apr 23 12:31:10 |~| calvin$ which virtualenv /opt/local/library/Frameworks/Python.framework/Versions/2.7/bin/virtualenv ``` So the strange thing I see here is that `which mkvirtualenv` does not give any result. Why? Digging further, in the virtualenvwrapper directory after installing it, I see only 3 python files:- ``` Calvins-MacBook-Pro.local ttys004 Mon Apr 23 12:28:05 |/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/virtualenvwrapper| calvin$ ls -la total 88 drwxr-xr-x 8 root wheel 272 Apr 13 15:07 . drwxr-xr-x 29 root wheel 986 Apr 15 00:55 .. -rw-r--r-- 1 root wheel 5292 Apr 13 15:05 hook_loader.py -rw-r--r-- 1 root wheel 4810 Apr 13 15:07 hook_loader.pyc -rw-r--r-- 1 root wheel 1390 Apr 13 15:05 project.py -rw-r--r-- 1 root wheel 2615 Apr 13 15:07 project.pyc -rw-r--r-- 1 root wheel 7381 Apr 13 15:05 user_scripts.py -rw-r--r-- 1 root wheel 11472 Apr 13 15:07 user_scripts.pyc ``` And I suppose that the only reason why `mkvirtualenv` is now available in my terminal is because I have added in a `source/opt/local/library/Frameworks/Python.framework/Versions/2.7/bin/virtualenvwrapper.sh`. So answering the question I asked earlier, this is simply because `mkvirtualenv` is expressed as a bash function and is available in my terminal because I have sourced virtualenvwrapper.sh in my `.bashrc` or `.bash_profile` files. Digging into the `virtualenvwrapper.sh` script, I see ``` # 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) mkvirtualenv_help; return;; -i) i=$(( $i + 1 )); packages="$packages ${in_args[$i]}";; -r) i=$(( $i + 1 )); requirements="${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[@]}" eval "envname=\$$#" virtualenvwrapper_verify_workon_home || return 1 virtualenvwrapper_verify_virtualenv || return 1 ( [ -n "$ZSH_VERSION" ] && setopt SH_WORD_SPLIT \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" } ``` Here's where I don't understand yet - I don't seem to see any direct reference to `virtualenv` in this bash function. So how exactly does this bash function `mkvirtualenv` pass the arguments from command line (e.g. `mkvirtualenv -p python2.7 --no-site-packages mynewproject`) to the python `virtualenv` program?

Original source