Skip to content

Instantly share code, notes, and snippets.

@jwa91
Created September 5, 2024 22:18
Show Gist options
  • Save jwa91/501406917a16618974e0f7c4371f209d to your computer and use it in GitHub Desktop.
Save jwa91/501406917a16618974e0f7c4371f209d to your computer and use it in GitHub Desktop.
current shell configuration related to Python development
# ----------------------------------------
# File: venv-settings.zsh
# Description: Virtual environment settings and functions
# Author: Jan Willem Altink*
# *some of the functions in here i got from a blog posts, unfortunately i cant find it anymore
# Last Modified: 2024-09-05
# ----------------------------------------
# ----------------------------------------
# Usage:
# $ mkproject <env_name> # Create environment in ~/.venv/ using Python 3.12
# $ workon <env_name> # Activate specified environment
# $ deactivate # Deactivate current environment
# $ rmvirtualenv <env_name> # Remove specified environment
# $ mkproject <env_name> --python=3.11 # Create environment with specific python version
# $ mkprojectsetup # Create project structure in the current directory based on boilerplate
# ----------------------------------------
export PROJECTS_HOME="$HOME/Developer"
export VENV_HOME="$HOME/.venv"
[ -d "$VENV_HOME" ] || mkdir $VENV_HOME
function mkproject() {
if [ $# -eq 0 ]; then
echo "ERROR: Project name not specified. Please specify the name of the project to create."
return 1
fi
local env_name=$1
shift
local python_version="python3.12"
for arg in "$@"; do
if [[ $arg == --python=* ]]; then
python_version="python${arg#*=}"
fi
done
local python_path
if [[ $python_version == python3.12 ]]; then
python_path="/opt/homebrew/bin/python3.12"
else
python_path=$(which $python_version)
fi
if [ ! -x "$python_path" ]; then
echo "ERROR: Python executable for $python_version not found."
return 1
fi
local venv_path=$VENV_HOME/$env_name
if [ -d "$venv_path" ]; then
echo "ERROR: Environment '$env_name' already exists. Switch to it with 'workon $env_name'."
return 1
fi
echo "Creating environment '$env_name' using $python_version at $venv_path"
$python_path -m venv $venv_path
source $venv_path/bin/activate
[ -d "$PROJECTS_HOME/$env_name" ] || mkdir $PROJECTS_HOME/$env_name
cd $PROJECTS_HOME/$env_name
}
function workon() {
if [ $# -eq 0 ]; then
\ls -1 $VENV_HOME
return 0
fi
local env_name=$1
VENV=$VENV_HOME/$env_name/bin/activate
if [ -f $VENV ]; then
if [ -n "$VIRTUAL_ENV" ]; then
deactivate
fi
source $VENV
cd $PROJECTS_HOME/$env_name
else
echo "ERROR: Environment '$1' does not exist. Create it with 'mkproject $1'."
fi
}
function rmvirtualenv() {
if [ -n "$VIRTUAL_ENV" ]; then
echo "Please deactivate the current venv before removing a venv."
return 1
fi
if [ $# -eq 0 ]; then
echo "Please specify an environment"
return 1
fi
echo "Removing $1..."
rm -r $VENV_HOME/$1
}
function _virtualenvs() {
local -a subcmds
_alternative "pids:process ID:($(\ls -1 $VENV_HOME))"
}
compdef _virtualenvs workon
compdef _virtualenvs rmvirtualenv
function deactivate() {
if [ -n "$VIRTUAL_ENV" ]; then
unset VIRTUAL_ENV
if [ -n "${_OLD_VIRTUAL_PATH:-}" ]; then
PATH="${_OLD_VIRTUAL_PATH}"
export PATH
unset _OLD_VIRTUAL_PATH
fi
if [ -n "${_OLD_VIRTUAL_PS1:-}" ]; then
PS1="${_OLD_VIRTUAL_PS1}"
export PS1
unset _OLD_VIRTUAL_PS1
fi
unset VIRTUAL_ENV
if [ -n "${_OLD_VIRTUAL_PYTHONHOME:-}" ]; then
PYTHONHOME="${_OLD_VIRTUAL_PYTHONHOME}"
export PYTHONHOME
unset _OLD_VIRTUAL_PYTHONHOME
fi
hash -r 2>/dev/null
else
echo "No virtual environment is currently active."
fi
}
function terminateproject() {
if [ -z "$VIRTUAL_ENV" ]; then
echo "ERROR: No active virtual environment detected."
return 1
fi
local env_name=$(basename "$VIRTUAL_ENV")
local project_path="$PROJECTS_HOME/$env_name"
local venv_path="$VENV_HOME/$env_name"
echo "WARNING: This will deactivate and remove the current virtual environment '$env_name'"
if [ -d "$project_path" ]; then
echo " and delete the project directory at '$project_path'."
else
echo " (Note: Project directory '$project_path' does not exist)"
fi
echo " This action cannot be undone."
read "response?Are you sure you want to proceed? (y/N) "
if [[ "$response" =~ ^[Yy]$ ]]; then
echo "Deactivating virtual environment..."
deactivate
echo "Removing virtual environment..."
rm -rf "$venv_path"
if [ -d "$project_path" ]; then
echo "Removing project directory..."
rm -rf "$project_path"
else
echo "Project directory not found. Skipping removal."
fi
echo "Project '$env_name' has been terminated."
else
echo "Operation cancelled."
fi
}
BOILERPLATE_DIR="$HOME/developer/python-boilerplate-base"
function replace_placeholders() {
local file="$1"
local project_name="$2"
sed -i '' \
-e "s/{{projectname}}/$project_name/g" \
-e "s/{{CURRENT_YEAR}}/$(date +%Y)/g" \
-e "s/{{CURRENT_DATE}}/$(date +%Y-%m-%d)/g" \
"$file"
}
function mkprojectsetup() {
# Check if we're in a virtual environment
if [ -z "$VIRTUAL_ENV" ]; then
echo "ERROR: No active virtual environment detected. Please activate one first."
return 1
fi
local project_name=$(basename "$VIRTUAL_ENV")
if [ ! -d "$BOILERPLATE_DIR" ]; then
echo "ERROR: Boilerplate directory not found at $BOILERPLATE_DIR"
return 1
fi
cp -R "$BOILERPLATE_DIR"/. .
mv src/projectname "src/$project_name"
replace_placeholders "pyproject.toml" "$project_name"
replace_placeholders "README.md" "$project_name"
echo "Project structure for '$project_name' has been created based on the boilerplate."
echo "Installing the package in editable mode..."
pip install -e .
echo "Project '$project_name' has been set up and installed in editable mode."
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment