Skip to content

Instantly share code, notes, and snippets.

@alastori
Last active December 5, 2025 17:51
Show Gist options
  • Select an option

  • Save alastori/6a43ec4d876029cb30aee808a0b93768 to your computer and use it in GitHub Desktop.

Select an option

Save alastori/6a43ec4d876029cb30aee808a0b93768 to your computer and use it in GitHub Desktop.
Script to relocate venvs from ~/Sandbox into ~/.venvs and leave symlinks
Script to relocate venvs from ~/Sandbox into ~/.venvs and leave symlinks
#!/usr/bin/env bash
set -euo pipefail
VENV_ROOT="${VENV_ROOT:-$HOME/.venvs}"
mkdir -p "$VENV_ROOT"
echo "Scanning $HOME/Sandbox for virtualenv activate scripts..."
processed=0
migrated=0
skipped=0
while IFS= read -r -d '' activate_path; do
env_path="$(dirname "$activate_path")"
env_dir="$(cd "$env_path/.." && pwd)"
project_dir="$(dirname "$env_dir")"
venv_name="$(basename "$env_dir")"
# Use project name + venv name for better uniqueness
# If venv is named .venv, use just project name; otherwise use project_venvname
project_name="$(basename "$project_dir")"
if [[ "$venv_name" == ".venv" ]]; then
target_name="$project_name"
else
target_name="${project_name}_${venv_name}"
fi
target="$VENV_ROOT/$target_name"
((processed++))
echo " • found env at $env_dir"
echo " project: $project_name, venv: $venv_name → $target_name"
if [[ -L "$env_dir" ]]; then
echo " - already symlink, skipping"
((skipped++))
continue
fi
if [[ -e "$target" ]]; then
echo " - target exists ($target), skipping"
((skipped++))
continue
fi
mv "$env_dir" "$target"
ln -sfn "$target" "$env_dir"
echo " - migrated -> $target"
((migrated++))
done < <(find -L "$HOME/Sandbox" -type f -path '*/bin/activate' -print0 2>/dev/null)
echo "Done. processed=$processed migrated=$migrated skipped=$skipped"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment