Venv

Overview

Venv makes working with Virtualenvwrapper, Bash, Vim, and IPython within a project context very easy.

There are a few parts to “venv”:

Quickstart

# print shell configuration for a (hypothetical) dotfiles virtualenv
venv --print-bash dotfiles

# print shell configuration for the current ${VIRTUAL_ENV} [and ${_WRD}]
venv --print-bash -E

# run a bash subprocess within a virtual env
venv -x bash dotfiles
venv -xb dotfiles

# workon a virtualenvwrapper virtualenv (source <(venv -E --print-bash))
we dotfiles

# workon ${WORKON_HOME}/dotfiles/src/otherproject (echo $_APP $_WRD)
we dotfiles otherproject

Usage

__WRK="~/-wrk"                                # cdwrk # workspace
__DOTFILES="~/-dotfiles"                      # cdd cddotfiles
PROJECT_HOME="${__WRK}"                       # cdph cdprojecthome
WORKON_HOME="${__WRK}/-ve27"                  # cdwh cdworkonhome

__VENV=$(which venv.py);
# ${__DOTFILES}/src/dotfiles/venv/ipython_config.py  # source
# ${__DOTFILES}/etc/ipython/ipython_config.py        # symlink
# ~/.ipython/profile_default/ipython_config.py       # symlink
# ${__DOTFILES}/scripts/venv.py                      # symlink ($PATH)
# ${VIRTUAL_ENV}/bin/venv                      # setup.py console_script
# ~/.local/bin/venv                            # setup.py console_script

__VENV="${__DOTFILES}/scripts/venv.py"               # 10-bashrc.venv.sh
# venv()                 -- (set -x; $__VENV $@)     # 10-bashrc.venv.sh
# venv-()                -- (set -x; $__VENV -e $@)  # 10-bashrc.venv.sh

$__VENV --help
venv.py --help
venv -h

# Generate venv CdAlias scripts
venv.py --print-bash-cdalias . | tee venv_cdalias.sh
venv.py --print-ipython-cdalias . | tee venv_cdmagic.py
venv.py --print-vim . | tee venv.vim

# Generate venv configuration for the "dotfiles" virtualenv
venv.py --print-vars --VIRTUAL_ENV="${WORKON_HOME}/dotfiles"
venv.py --print-vars --virtual-env="${WORKON_HOME}/dotfiles"
venv.py --print-vars --ve="${WORKON_HOME}/dotfiles"
venv.py --print-vars --ve dotfiles
venv.py --print-vars dotfiles
venv.py --print-vars dotfiles
venv.py --print-bash dotfiles

## Workon the dotfiles virtualenv
source <(venv.py -q --print-bash dotfiles)

## Workon the dotfiles virtualenv (with a bash subprocess)
venv.py -xb dotfiles

## Workon the dotfiles virtualenv (after virtualenvwrapper workon)
workon dotfiles
source <(venv.py -q --print-bash --from-environ)


## Note: the following two commands are different to argparse:
## (positional VENVSTR and VENVSTRAPP must come last,
##  or be specified as --ve and --app)
venv dotfiles --print-bash        # does not work
venv --print-bash dotfiles        # does work

CdAlias

Each CdAlias in env.aliases is expanded for each output type.

For example, CdAlias('__WRK') becomes cdwrk, %cdwrk, and :Cdwrk:

# Bash
cdwrk
cdwrk<tab>
cdwrk -ve27

# IPython
%cdwrk
cdwrk
cdwrk -ve27

# Vim
call Cd___WRK()
:Cdwrk
:Cdwrk -ve27

Usage

Shell Command

$ python ../src/dotfiles/venv/ipython_config.py --help
usage: venv [-h] [-V] [-v] [-D] [-T] [-q] [-t] [--platform PLATFORM] [-e]
            [--__WRK [__WRK]] [--__DOTFILES [__DOTFILES]]
            [--WORKON_HOME [WORKON_HOME]] [--VENVSTR [VENVSTR_]]
            [--VENVSTRAPP [VENVSTRAPP_]]
            [--VIRTUAL_ENV_NAME [VIRTUAL_ENV_NAME]]
            [--VENVPREFIX [VENVPREFIX]] [--VIRTUAL_ENV [VIRTUAL_ENV]]
            [--_SRC [_SRC]] [--_APP [_APP]] [--_WRD [_WRD]] [--print-json]
            [--print-json-filename [PRINT_JSON_FILENAME]] [--print-vars]
            [--print-bash] [--print-bash-all] [--print-bash-aliases]
            [--print-bash-cdaliases] [-Z] [--print-vim-cdalias]
            [--print-ipython-magics] [--command RUN_COMMAND] [--run-bash]
            [--run-make] [--run-editp] [--run-terminal] [--pall] [--pwrk]
            [--pworkonhome] [--pvirtualenv] [--psrc] [--pwrd] [--pdotfiles]
            [--prel] [--pkg-resource-path] [--compress]
            [VENVSTR] [VENVSTRAPP] ...

venv is a configuration utility for virtual environments.

positional arguments:
  VENVSTR               a name of a virtualenv in WORKON_HOME OR a full path
                        to a VIRTUAL_ENV
  VENVSTRAPP            a path within _SRC (_WRD=_SRC/VENVSTRAPP)
  args

optional arguments:
  -h, --help            show this help message and exit
  -V, --version
  -v, --verbose
  -D, --diff, --show-diffs
  -T, --trace
  -q, --quiet
  -t, --test
  --platform PLATFORM   Platform string (default: None)
  -e, --from-environ    Build venv.env.environ from keys in os.environ
  --__WRK [__WRK], --WRK [__WRK], --wrk [__WRK]
                        Path to workspace -- ~/-wrk
  --__DOTFILES [__DOTFILES], --DOTFILES [__DOTFILES], --dotfiles [__DOTFILES]
                        Path to ${__DOTFILES} symlink -- ~/-dotfiles
  --WORKON_HOME [WORKON_HOME], --workonhome [WORKON_HOME], --wh [WORKON_HOME]
                        Path to ${WORKON_HOME} directory containing
                        VIRTUAL_ENVs
  --VENVSTR [VENVSTR_], --venvstr [VENVSTR_], --ve [VENVSTR_]
                        Path to VIRTUAL_ENV --
                        ${WORKON_HOME}/${VIRTUAL_ENV_NAME} (or a dirname in
                        $WORKON_HOME)
  --VENVSTRAPP [VENVSTRAPP_], --venvstrapp [VENVSTRAPP_]
                        Subpath within {VIRTUAL_ETC}/src/
  --VIRTUAL_ENV_NAME [VIRTUAL_ENV_NAME], --virtual-env-name [VIRTUAL_ENV_NAME], --vename [VIRTUAL_ENV_NAME]
                        dirname in WORKON_HOME --
                        ${WORKON_HOME}/${VIRTUAL_ENV_NAME}
  --VENVPREFIX [VENVPREFIX], --venvprefix [VENVPREFIX], --prefix [VENVPREFIX]
                        Prefix for _SRC, _ETC, _WRD if [ -z VIRTUAL_ENV ]
  --VIRTUAL_ENV [VIRTUAL_ENV], --virtual-env [VIRTUAL_ENV]
                        Path to a $VIRTUAL_ENV
  --_SRC [_SRC], --SRC [_SRC], --src [_SRC]
                        Path to source -- ${VIRTUAL_ENV}/src")
  --_APP [_APP], --APP [_APP], --app [_APP]
                        Path component string -- ${_SRC}/${_APP}
  --_WRD [_WRD], --WRD [_WRD], --wrd [_WRD]
                        Path to working directory -- ${_SRC}/${_APP}
  --print-json          Print venv configuration as JSON
  --print-json-filename [PRINT_JSON_FILENAME]
                        Path to write venv env JSON to
  --print-vars, --vars  Print vars
  --print-bash, --bash  Print Bash shell configuration
  --print-bash-all      Print Bash shell environ and aliases
  --print-bash-aliases, --bash-alias
                        Print Bash alias script
  --print-bash-cdaliases, --bash-cdalias
                        Print Bash cdalias script
  -Z, --print-zsh       Print ZSH shell configuration
  --print-vim-cdalias, --vim
                        Print vimscript configuration
  --print-ipython-magics
                        Print IPython magic methods
  --command RUN_COMMAND, --cmd RUN_COMMAND, -x RUN_COMMAND
                        Run a command in a venv-configured shell
  --run-bash, --xbash, -xb
                        Run bash in the specified venv
  --run-make, --xmake, -xmake
                        Run (cd $_WRD; make $@) in the specified venv
  --run-editp, --open-editors, --edit, -E
                        Open $EDITOR_ with venv.project_files [$PROJECT_FILES]
  --run-terminal, --open-terminals, --terminals, --terms
                        Open terminals within the venv [gnome-terminal]
  --pall, --pathall     Print possible paths for the given path
  --pwrk, --wrk-path    Print $__WRK/$@
  --pworkonhome, --workonhome-path, --pwh
                        Print $__WORKON_HOME/$@
  --pvirtualenv, --virtualenv-path, --pv
                        Print $VIRTUAL_ENV/${@}
  --psrc, --src-path, --ps
                        Print $_SRC/${@}
  --pwrd, --wrd-path, --pw
                        Print $_WRD/${@}
  --pdotfiles, --dotfiles-path, --pd
                        Print ${__DOTFILES}/${path}
  --prel, --relative-path
                        Print ${@}
  --pkg-resource-path   Path from pkg_resources.TODOTODO
  --compress, --compress-paths
                        Path $VAR-ify the given paths from stdin

argparse.REMAINDER: If args must be specified, either (VENVSTR AND VENVSTRAPP)
or (--ve [--app]) must be specified first: venv --ve dotfiles -xmake.

Python API

Python API (see Test_Env, Test_venv_main): A dotfiles.venv.ipython_config.Venv object builds a dotfiles.venv.ipython_config.Env OrderedDict (.env) with $VIRTUAL_ENV-relative paths and environment variables in a common filesystem hierarchy and an OrderedDict of command aliases (.aliases), which can be serialized to a bash script (venv --bash), JSON (venv --print), and IPython configuration.

Example Venv Configuration

Shell Configuration

venv.py --print-bash --compress dotfilesx dotfilesx/docs:

$ python ../scripts/venv.py --print-bash --compress dotfilesx dotfilesx/docs \
| sed "s,${HOME},~,g"
export HOME="~"
export __WRK="${HOME}/-wrk"
export __SRC="${__WRK}/-src"
export __DOTFILES="${HOME}/-dotfiles"
export WORKON_HOME__py27="${__WRK}/-ve27"
export WORKON_HOME__py34="${__WRK}/-ve34"
export WORKON_HOME_DEFAULT="WORKON_HOME__py27"
export CONDA_ROOT__py27="${__WRK}/-conda27"
export CONDA_HOME__py27="${__WRK}/-ce27"
export CONDA_ROOT__py34="${__WRK}/-conda34"
export CONDA_HOME__py34="${__WRK}/-ce34"
export CONDA_ROOT_DEFAULT="CONDA_ROOT__py27"
export CONDA_HOME_DEFAULT="CONDA_HOME__py27"
export CONDA_ROOT="${__WRK}/-conda27"
export CONDA_HOME="${__WRK}/-ce27"
export WORKON_HOME="${__WRK}/-ve27"
export VENVSTR="dotfilesx"
export VENVSTRAPP="${VENVSTR}/docs"
export VIRTUAL_ENV_NAME="${VENVSTR}"
export VIRTUAL_ENV="${WORKON_HOME}/${VENVSTR}"
export VENVPREFIX="${WORKON_HOME}/${VENVSTR}"
export _APP="${VENVSTRAPP}"
export _ETC="${VIRTUAL_ENV}/etc"
export _SRC="${VIRTUAL_ENV}/src"
export _WRD="${_SRC}/${VENVSTRAPP}"
export _BIN="${VIRTUAL_ENV}/bin"
export _ETCOPT="${_ETC}/opt"
export _HOME="${VIRTUAL_ENV}/home"
export _LIB="${VIRTUAL_ENV}/lib"
export _PYLIB="${VIRTUAL_ENV}/lib/python2.7"
export _PYSITE="${VIRTUAL_ENV}/lib/python2.7/site-packages"
export _MNT="${VIRTUAL_ENV}/mnt"
export _MEDIA="${VIRTUAL_ENV}/media"
export _OPT="${VIRTUAL_ENV}/opt"
export _ROOT="${VIRTUAL_ENV}/root"
export _SBIN="${VIRTUAL_ENV}/sbin"
export _SRV="${VIRTUAL_ENV}/srv"
export _TMP="${VIRTUAL_ENV}/tmp"
export _USR="${VIRTUAL_ENV}/usr"
export _USRBIN="${VIRTUAL_ENV}/usr/bin"
export _USRINCLUDE="${VIRTUAL_ENV}/usr/include"
export _USRLIB="${VIRTUAL_ENV}/usr/lib"
export _USRLOCAL="${VIRTUAL_ENV}/usr/local"
export _USRLOCALBIN="${VIRTUAL_ENV}/usr/local/bin"
export _USRSBIN="${VIRTUAL_ENV}/usr/sbin"
export _USRSHARE="${VIRTUAL_ENV}/usr/share"
export _USRSRC="${VIRTUAL_ENV}/usr/src"
export _VAR="${VIRTUAL_ENV}/var"
export _VARCACHE="${VIRTUAL_ENV}/var/cache"
export _VARLIB="${VIRTUAL_ENV}/var/lib"
export _VARLOCK="${VIRTUAL_ENV}/var/lock"
export _LOG="${VIRTUAL_ENV}/var/log"
export _VARMAIL="${VIRTUAL_ENV}/var/mail"
export _VAROPT="${VIRTUAL_ENV}/var/opt"
export _VARRUN="${VIRTUAL_ENV}/var/run"
export _VARSPOOL="${VIRTUAL_ENV}/var/spool"
export _VARTMP="${VIRTUAL_ENV}/var/tmp"
export _WWW="${VIRTUAL_ENV}/var/www"
export PROJECT_FILES=""
export VIMBIN="/usr/bin/vim"
export GVIMBIN=""
export MVIMBIN=""
export GUIVIMBIN=""
export VIMCONF="--servername ${VENVSTRAPP}"
export _EDIT_="/usr/bin/vim -f"
export EDITOR_="/usr/bin/vim -f"
export _NOTEBOOKS="${_SRC}/notebooks"
export _IPYSESKEY="${_SRC}/.ipyseskey"
export _IPQTLOG="${VIRTUAL_ENV}/.ipqt.log"
export _WRD_SETUPY="${_WRD}/setup.py"
export _TEST_="(cdwrd && python "${_WRD_SETUPY}" test)"
export _CFG="${_ETC}/development.ini"
export _EDITCFG_="/usr/bin/vim -f ${_ETC}/development.ini"
export _SHELL_="(cdwrd && "${_BIN}"/pshell "${_CFG}")"
export _SERVE_="(cdwrd && "${_BIN}"/pserve --app-name=main --reload --monitor-restart "${_CFG}")"
export _SVCFG="${_ETC}/supervisord.conf"
export _SVCFG_=" -c "${_ETC}/supervisord.conf""
export _USRLOG="${VIRTUAL_ENV}/-usrlog.log"
export PROJECT_HOME="${HOME}/-wrk"
export CONDA27_ROOT="${__WRK}/-conda27"
export CONDA27_HOME="${__WRK}/-ce27"
export CONDA34_ROOT="${__WRK}/-conda34"
export CONDA34_HOME="${__WRK}/-ce34"

JSON Configuration

venv.py --print-json dotfiles:

$ python ../scripts/venv.py --print-json dotfilesx dotfilesx/docs \
| python ../scripts/venv.py --compress dotfilesx dotfilesx/docs \
| sed "s,${HOME},~,g"
{
    "environ": {
        "HOME": "~",
        "__WRK": "${HOME}/-wrk",
        "__SRC": "${__WRK}/-src",
        "__DOTFILES": "${HOME}/-dotfiles",
        "WORKON_HOME__py27": "${__WRK}/-ve27",
        "WORKON_HOME__py34": "${__WRK}/-ve34",
        "WORKON_HOME_DEFAULT": "WORKON_HOME__py27",
        "CONDA_ROOT__py27": "${__WRK}/-conda27",
        "CONDA_HOME__py27": "${__WRK}/-ce27",
        "CONDA_ROOT__py34": "${__WRK}/-conda34",
        "CONDA_HOME__py34": "${__WRK}/-ce34",
        "CONDA_ROOT_DEFAULT": "CONDA_ROOT__py27",
        "CONDA_HOME_DEFAULT": "CONDA_HOME__py27",
        "CONDA_ROOT": "${__WRK}/-conda27",
        "CONDA_HOME": "${__WRK}/-ce27",
        "WORKON_HOME": "${__WRK}/-ve27",
        "VENVSTR": "${VENVSTR}",
        "VENVSTRAPP": "${VENVSTRAPP}",
        "VIRTUAL_ENV_NAME": "${VENVSTR}",
        "VIRTUAL_ENV": "${WORKON_HOME}/${VENVSTR}",
        "VENVPREFIX": "${WORKON_HOME}/${VENVSTR}",
        "_APP": "${VENVSTRAPP}",
        "_ETC": "${VIRTUAL_ENV}/etc",
        "_SRC": "${VIRTUAL_ENV}/src",
        "_WRD": "${_SRC}/${VENVSTRAPP}",
        "_BIN": "${VIRTUAL_ENV}/bin",
        "_ETCOPT": "${_ETC}/opt",
        "_HOME": "${VIRTUAL_ENV}/home",
        "_LIB": "${VIRTUAL_ENV}/lib",
        "_PYLIB": "${VIRTUAL_ENV}/lib/python2.7",
        "_PYSITE": "${VIRTUAL_ENV}/lib/python2.7/site-packages",
        "_MNT": "${VIRTUAL_ENV}/mnt",
        "_MEDIA": "${VIRTUAL_ENV}/media",
        "_OPT": "${VIRTUAL_ENV}/opt",
        "_ROOT": "${VIRTUAL_ENV}/root",
        "_SBIN": "${VIRTUAL_ENV}/sbin",
        "_SRV": "${VIRTUAL_ENV}/srv",
        "_TMP": "${VIRTUAL_ENV}/tmp",
        "_USR": "${VIRTUAL_ENV}/usr",
        "_USRBIN": "${VIRTUAL_ENV}/usr/bin",
        "_USRINCLUDE": "${VIRTUAL_ENV}/usr/include",
        "_USRLIB": "${VIRTUAL_ENV}/usr/lib",
        "_USRLOCAL": "${VIRTUAL_ENV}/usr/local",
        "_USRLOCALBIN": "${VIRTUAL_ENV}/usr/local/bin",
        "_USRSBIN": "${VIRTUAL_ENV}/usr/sbin",
        "_USRSHARE": "${VIRTUAL_ENV}/usr/share",
        "_USRSRC": "${VIRTUAL_ENV}/usr/src",
        "_VAR": "${VIRTUAL_ENV}/var",
        "_VARCACHE": "${VIRTUAL_ENV}/var/cache",
        "_VARLIB": "${VIRTUAL_ENV}/var/lib",
        "_VARLOCK": "${VIRTUAL_ENV}/var/lock",
        "_LOG": "${VIRTUAL_ENV}/var/log",
        "_VARMAIL": "${VIRTUAL_ENV}/var/mail",
        "_VAROPT": "${VIRTUAL_ENV}/var/opt",
        "_VARRUN": "${VIRTUAL_ENV}/var/run",
        "_VARSPOOL": "${VIRTUAL_ENV}/var/spool",
        "_VARTMP": "${VIRTUAL_ENV}/var/tmp",
        "_WWW": "${VIRTUAL_ENV}/var/www",
        "PROJECT_FILES": "",
        "VIMBIN": "/usr/bin/vim",
        "GVIMBIN": null,
        "MVIMBIN": null,
        "GUIVIMBIN": null,
        "VIMCONF": "--servername ${VENVSTRAPP}",
        "_EDIT_": "/usr/bin/vim -f",
        "EDITOR_": "/usr/bin/vim -f",
        "_NOTEBOOKS": "${_SRC}/notebooks",
        "_IPYSESKEY": "${_SRC}/.ipyseskey",
        "_IPQTLOG": "${VIRTUAL_ENV}/.ipqt.log",
        "_WRD_SETUPY": "${_WRD}/setup.py",
        "_TEST_": "(cdwrd && python \"${_WRD_SETUPY}\" test)",
        "_CFG": "${_ETC}/development.ini",
        "_EDITCFG_": "/usr/bin/vim -f ${_ETC}/development.ini",
        "_SHELL_": "(cdwrd && \"${_BIN}\"/pshell \"${_CFG}\")",
        "_SERVE_": "(cdwrd && \"${_BIN}\"/pserve --app-name=main --reload --monitor-restart \"${_CFG}\")",
        "_SVCFG": "${_ETC}/supervisord.conf",
        "_SVCFG_": " -c \"${_ETC}/supervisord.conf\"",
        "_USRLOG": "${VIRTUAL_ENV}/-usrlog.log",
        "PROJECT_HOME": "${HOME}/-wrk",
        "CONDA27_ROOT": "${__WRK}/-conda27",
        "CONDA27_HOME": "${__WRK}/-ce27",
        "CONDA34_ROOT": "${__WRK}/-conda34",
        "CONDA34_HOME": "${__WRK}/-ce34"
    },
    "aliases": {
        "cdhome": "HOME",
        "cdwrk": "__WRK",
        "cdddotfiles": "__DOTFILES",
        "cdprojecthome": "PROJECT_HOME",
        "cdworkonhome": "WORKON_HOME",
        "cdcondahome": "CONDA_HOME",
        "cdvirtualenv": "VIRTUAL_ENV",
        "cdsrc": "_SRC",
        "cdwrd": "_WRD",
        "cdbin": "_BIN",
        "cdetc": "_ETC",
        "cdlib": "_LIB",
        "cdlog": "_LOG",
        "cdpylib": "_PYLIB",
        "cdpysite": "_PYSITE",
        "cdvar": "_VAR",
        "cdwww": "_WWW",
        "cdls": "set | grep \"^cd.*()\" | cut -f1 -d\" \" #%l",
        "cdhelp": "cat $__DOTFILES/etc/venv/venv.sh | pyline.py -r '^\\s*#+\\s+.*' 'rgx and l'",
        "edit-": "${_EDIT_} %l",
        "gvim-": "/usr/bin/vim -f",
        "ipskey": "(python -c \"import os; print os.urandom(128).encode(\\\"base64\\\")\" > \"${_IPYSESKEY}\" ) && chmod 0600 \"${_IPYSESKEY}\"; # %l",
        "ipnb": "ipython notebook --secure --Session.keyfile=\"${_IPYSESKEY}\" --notebook-dir=\"${_NOTEBOOKS}\" --deep-reload %l",
        "ipqt": "ipython qtconsole --secure --Session.keyfile=\"${_IPYSESKEY}\" --logappend=\"${_IPQTLOG}\" --deep-reload --pprint --colors=linux --ConsoleWidget.font_family=\"Monaco\" --ConsoleWidget.font_size=11 %l",
        "grinv": "grin --follow %l \"${VIRTUAL_ENV}\"",
        "grindv": "grind --follow %l --dirs \"${VIRTUAL_ENV}\"",
        "grins": "grin --follow %l \"${_SRC}\"",
        "grinds": "grind --follow %l --dirs \"${_SRC}\"",
        "test-": "(cdwrd && python \"${_WRD_SETUPY}\" test)",
        "testr-": "reset && (cdwrd && python \"${_WRD_SETUPY}\" test)",
        "nose-": "(cdwrd && nosetests)",
        "grinw": "grin --follow %l \"${_WRD}\"",
        "grin-": "grin --follow %l \"${_WRD}\"",
        "grindw": "grind --follow %l --dirs \"${_WRD}\"",
        "grind-": "grind --follow %l --dirs \"${_WRD}\"",
        "hgv-": "hg view -R \"${_WRD}\"",
        "hgl-": "hg -R \"${_WRD}\" log",
        "editcfg": "\"${_EDITCFG_}\" %l",
        "serve-": "(cdwrd && \"${_BIN}\"/pserve --app-name=main --reload --monitor-restart \"${_CFG}\")",
        "shell-": "(cdwrd && \"${_BIN}\"/pshell \"${_CFG}\")",
        "e": "${_EDIT_} %l",
        "editp": "$GUIVIMBIN $VIMCONF $PROJECT_FILES %l",
        "makewrd": "(cdwrd && make %l)",
        "makew": "(cdwrd && make %l)",
        "make-": "(cdwrd && make %l)",
        "mw": "(cdwrd && make %l)",
        "makewepy": "_logfile=\"${_LOG}/make.log.py\"; (makew %l 2>&1 | tee $_logfile) && e $_logfile",
        "ssv": "supervisord -c \"${_SVCFG}\"",
        "sv": "supervisorctl -c \"${_SVCFG}\"",
        "svt": "sv tail -f",
        "svd": "supervisorctl -c \"${_SVCFG}\" restart dev && supervisorctl -c \"${_SVCFG}\" tail -f dev"
    }
}

Other scripts with venv-style paths

To define a script environment just like venv:

#!/bin/sh

__WRK="${HOME}/-wrk"                          # cdwrk
__DOTFILES="${HOME}/-dotfiles"                # cdd cddotfiles
PROJECT_HOME="${__WRK}"                       # cdph cdprojecthome
WORKON_HOME="${__WRK}/-ve27"                  # cdwh cdworkonhome

VIRTUAL_ENV_NAME="dotfiles"                   # 'dotfiles'
_APP=$VIRTUAL_ENV_NAME                        # 'dotfiles[/p/a/t/h]'
VIRTUAL_ENV="$WORKON_HOME/$VIRTUAL_ENV_NAME"  # cdv cdvirtualenv
_SRC="${VIRTUAL_ENV}/src"                     # cds cdsrc
_BIN="${VIRTUAL_ENV}/bin"                     # cde cdbin
_ETC="${VIRTUAL_ENV}/etc"                     # cde cdetc
_LOG="${VIRTUAL_ENV}/var/log"                 # cdl cdlog
# ... see: venv.py --print-vars / ...
_WRD="${_SRC}/{_APP}"                         # cdw cdwrd

(set -x; test "$_WRD" == "${HOME}/-wrk/-ve27/dotfiles/src/dotfiles"; \
    || echo "Exception: _WRD = '${_WRD}';" )

SeeAlso: unittest.TestCase tests in dotfiles.venv.ipython_config (ipython_config.py).