Izaya
Izaya

Reputation: 1568

How to remove all pipenv virtualenvs when the directory was deleted?

I have a directory A/ containing a Pipfile and a Pipfile.lock obtained by running pipenv install. So this directory has a corresponding virtualenv at /home/username/.local/share/virtualenvs/A-....

Then I delete this A/ directory. Is there a way to check all pipenv virtualenvs, find directories that were deleted and remove the corresponding virtualenvs ?

In this case it should find that A/ was deleted and so remove the virtualenv: /home/username/.local/share/virtualenvs/A-....

Upvotes: 10

Views: 5736

Answers (3)

yestema
yestema

Reputation: 8112

pipenv has no special option for it. But you can use these bash scripts (I made them using the venvs directory ~/.local/share/virtualenvs/ so you should change it if your venvs folder is different)

PRINT useless venvs:

for f in $(find ~/.local/share/virtualenvs/*/.project -type f); do proj_path="$(cat $f)"  && [ ! -d "$proj_path" ] && echo ${f//\/.project};  done;

PRINT not existing projects paths that still have corresponding venvs:

for f in $(find ~/.local/share/virtualenvs/*/.project -type f); do proj_path="$(cat $f)"  && [ ! -d "$proj_path" ] && echo $proj_path;  done;

PRINT both (useless venvs and not existing project folders):

for f in $(find ~/.local/share/virtualenvs/*/.project -type f); do proj_path="$(cat $f)" && [ ! -d "$proj_path" ] && echo $proj_path "\n"${f//\/.project} "\n";  done;

DELETE useless venvs

for f in $(find ~/.local/share/virtualenvs/*/.project -type f); do proj_path="$(cat $f)" && [ ! -d "$proj_path" ] && rm -rif ${f//\/.project} && echo DELETING ${f//\/.project};  done;

Try printing the venvs before deleting!

p.s. If your venv folder is not ~/.local/share/virtualenvs/, make sure to change it to your venv path!

Upvotes: 12

ys_huang
ys_huang

Reputation: 103

I built a function for this based on the answer of @yestema. You can check it in my repo. Save the code below into your profile, e.q. ~/.bashrc .

# extra pipenv command
pipenv_correspond(){
  local isDefault=true
  local isLS=true
  local isRM=false

  local show_proj_root=true
  local CORRESPOND=""
  declare -a venvs_root_arr=()
  
  local help_book='Usage: pipenv_correspond [OPTION]\n\nOPTION:
  ls,  --list                list all the corresponding projects_root & venvs
  uls, --useless             list all the not existing projects_roots that still have correspondenting venvs
  npr, --no-project-root     hide projects_root
  rm,  --remove              remove all the venvs from command: "ls" or "uls", deafult is use "uls"
  '
  function Show_root(){
    declare -a venvs_arr=()
    declare -i num_venvs=0
    if $show_proj_root; then
      for f in $(find ~/.local/share/virtualenvs/*/.project -type f); do
        proj_root="$(cat $f)" && [ $CORRESPOND -d $proj_root ] && echo "\nproj: $proj_root\nvenv: ${f//\/.project}\n" && venvs_root_arr+=(${f//\/.project}) && num_venvs+=1
      done
    else
      for f in $(find ~/.local/share/virtualenvs/*/.project -type f); do
        proj_root="$(cat $f)" && [ $CORRESPOND -d $proj_root ] && echo "${f//\/.project}\n" && venvs_root_arr+=(${f//\/.project}) && num_venvs+=1
      done
    fi
    echo "Total venvs: $num_venvs"
  }
  if [ "$#" -gt 0 ]; then
    while [ "$#" -gt 0 ]; do
      case $1 in
        "-h" | "--help" )
          echo $help_book
          return
        ;;
        "ls" | "--list" )
          isDefault=false
          isLS=true
          shift 1
        ;;
        "uls" | "--useless" )
          isDefault=false
          isLS=false
          shift 1
        ;;
        "npr" | "--no-project-root" )
          show_proj_root=false
          shift 1
        ;;
        "rm"  | "--remove" )
          isRM=true
          shift 1 
        ;;
        *)
          echo "\e[31mWrong command keyword!\e[0m" 
          return
        ;;
      esac
    done
  fi
  
  if ! $isLS || ( $isRM && $isDefault ); then
    CORRESPOND="!"
    echo "Useless venvs:"
  else
    echo "Still corresponding venvs:"
  fi

  Show_root venvs_root_arr

  if $isRM; then
    while ! $isDefault && $isLS; do
      printf "\e[33mAre you sure you want to remove all venvs that still existing projects_roots?[y/n] \e[0m"
      read respond
      if [ "$respond" = "n" -o "$respond" = "N" ]; then
        echo "bye~~~"
        return
      elif [ "$respond" != "y" -a "$respond" != "Y" ]; then
        echo "Must type 'y' or 'n'!"
      else
        break
      fi
    done
    echo $venvs_root_arr
    echo "\e[33mWait...\e[0m" 
    for value in ${venvs_root_arr[@]}; do
      echo "remving... $value"
      rm -rf $value
    done
    echo "\e[32mSuccessflly removed all venvs!!\e[0m" 
  fi
}

Upvotes: 1

TDN
TDN

Reputation: 445

Here is a bash script to check and clean up abandoned pipenv environments interactively based on the answer of @yestema.

#!/usr/bin/env bash

# Author: TiDu Nguyen
# https://gist.github.com/tidunguyen/0fc018326f33c29e819be7f388360a5b

# get all pipenv environments
allPipenvEnv=$(find ~/.local/share/virtualenvs/*/.project -type f)

# find abandoned environments
abandonedEnv=()
for f in $allPipenvEnv; do
    proj_path="$(cat $f)" && [ ! -d $proj_path ] && abandonedEnv+=($proj_path)
done

# if there is any abandoned environment, prompt for cleaning, else, exit
if [ ${#abandonedEnv[@]} -eq 0 ]; then
    echo "No abandoned environment, hooray"
else
    echo "Found ${#abandonedEnv[@]} abandoned pipenv environment(s):"
    for value in "${abandonedEnv[@]}"; do
        echo $value
    done

    echo -e "\nClean up abandoned pipenv environments?"
    select choice in "Yes" "No"; do
        case $choice in
        Yes)
            for f in $allPipenvEnv; do
                proj_path="$(cat $f)" && [ ! -d $proj_path ] && rm -rif ${f//\/.project/} && echo DELETING ${f//\/.project/}
            done
            echo "Done!"
            break
            ;;
        No)
            break
            ;;
        esac
    done
fi

Upvotes: 2

Related Questions