J'ai un tas de projets dans mon ~/Documents
. Je travaille presque exclusivement en python, donc ce sont essentiellement tous les projets python. Chacun, par exemple ~/Documents/foo
a son propre virtualenv, ~/Documents/foo/venv
(on les appelle toujours venv). Chaque fois que je passe d'un projet à l'autre, soit environ 10 fois par jour, je fais
deactivate
cd ..
cd foo
source venv/bin/activate
J'ai atteint le point où j'en ai marre de taper deactivate
et source venv/bin/activate
. Je cherche un moyen de simplement cd ../foo
et faire gérer les opérations virtualenv pour moi.
Je connais VirtualEnvWrapper qui est un peu lourd à mon avis. Il semble déplacer tous vos virtualenvs ailleurs, et ajoute un peu plus de complexité qu'il n'en supprime, pour autant que je sache. (Les opinions dissidentes sont les bienvenues!)
Je ne connais pas trop bien les scripts Shell. Si vous pouvez recommander un script à faible maintenance à ajouter à mon ~/.zshrc
qui accomplit cela, ce serait plus que suffisant, mais à partir d'une recherche rapide sur Google, je n'ai pas trouvé un tel script.
Je suis zsh
/ oh-my-zsh
utilisateur. oh-my-zsh
ne semble pas avoir de plugin pour cela. La meilleure réponse à cette question serait que quelqu'un contribue à oh-my-zsh
plugin qui fait cela. (Ce que je pourrais faire si les réponses ici sont ternes.
Mettez quelque chose comme ça dans votre .zshrc
function cd() {
if [[ -d ./venv ]] ; then
deactivate
fi
builtin cd $1
if [[ -d ./venv ]] ; then
. ./venv/bin/activate
fi
}
Edit : Comme indiqué dans les commentaires cd
- dans un sous-dossier de l'environnement virtuel actuel le désactiverait. Une idée pourrait être de désactiver l'environnement actuel uniquement si cd
- en un nouveau, comme
function cd() {
builtin cd $1
if [[ -n "$VIRTUAL_ENV" && -d ./venv ]] ; then
deactivate
. ./venv/bin/activate
fi
}
cela pourrait encore être amélioré, peut-être en le transformant en une "commande d'invite" ou en essayant une correspondance de préfixe sur les noms de dossier pour vérifier qu'il y a un env virtuel quelque part sur le chemin, mais mon Shell-fu n'est pas bon assez.
Ajoutez les éléments suivants dans votre .bashrc ou .zshrc
function cd() {
builtin cd "$@"
if [[ -z "$VIRTUAL_ENV" ]] ; then
## If env folder is found then activate the vitualenv
if [[ -d ./.env ]] ; then
source ./.env/bin/activate
fi
else
## check the current folder belong to earlier VIRTUAL_ENV folder
# if yes then do nothing
# else deactivate
parentdir="$(dirname "$VIRTUAL_ENV")"
if [[ "$PWD"/ != "$parentdir"/* ]] ; then
deactivate
fi
fi
}
Ce code ne désactivera pas le virtualenv même si quelqu'un va dans le sous-dossier. Inspiré par les réponses de @ agnul et @ Gilles .
Si le virtualenv est fait par pipenv, alors veuillez considérer cette page wiki .
De plus, pour plus de sécurité, veuillez considérer direnv .
Plutôt que d'écrire un script personnalisé, vous pourriez utiliser direnv . Ce n'est pas une solution spécifique à zsh (pour cela, vous pouvez essayer zsh-autoenv ), mais elle est bien entretenue et facile à utiliser avec zsh. Une fois que vous l'avez installé, vous voudrez mettre eval "$(direnv hook zsh)"
à la fin de votre .zshrc
. À ce stade, vous pouvez faire:
$ source ~/.zshrc
$ cd foo
$ echo "layout python" > .envrc
direnv: error .envrc is blocked. Run `direnv allow` to approve its content.
$ direnv allow
direnv: loading .envrc
direnv: export +VIRTUAL_ENV ~PATH
Vous devriez maintenant être dans votre virtualenv. Vous pouvez tester en exécutant pip freeze
pour voir que vos packages spécifiques à virtualenv sont installés. Pour désactiver
$ cd ..
direnv: unloading
Pour la postérité: j'ai utilisé la solution de @ MS_ mais j'ai rencontré le problème où cd
ing directement d'un projet à un autre désactive l'ancien virtualenv mais n'active pas le nouveau. Il s'agit d'une version légèrement modifiée de cette solution qui résout ce problème:
# auto activate virtualenv
# Modified solution based on https://stackoverflow.com/questions/45216663/how-to-automatically-activate-virtualenvs-when-cding-into-a-directory/56309561#56309561
function cd() {
builtin cd "$@"
## Default path to virtualenv in your projects
DEFAULT_ENV_PATH="./env"
## If env folder is found then activate the vitualenv
function activate_venv() {
if [[ -f "${DEFAULT_ENV_PATH}/bin/activate" ]] ; then
source "${DEFAULT_ENV_PATH}/bin/activate"
echo "Activating ${VIRTUAL_ENV}"
fi
}
if [[ -z "$VIRTUAL_ENV" ]] ; then
activate_venv
else
## check the current folder belong to earlier VIRTUAL_ENV folder
# if yes then do nothing
# else deactivate then run a new env folder check
parentdir="$(dirname ${VIRTUAL_ENV})"
if [[ "$PWD"/ != "$parentdir"/* ]] ; then
echo "Deactivating ${VIRTUAL_ENV}"
deactivate
activate_venv
fi
fi
}
Par loin l'option la plus simple (en 2019+) est d'ajouter virtualenvwrapper
dans votre ~/.zshrc
plugins
Par exemple:
plugins=(
git pip python brew virtualenvwrapper
)
Voici ma solution, qui:
venv
actuellement actif, et ne fait rien dans ce casvenv
, désactivez celui qui est actif s'il y en a unvenv
peu importe s'il y en avait un ancien ou non.Dans mon bash_aliases
:
function cd() {
builtin cd "$@"
if [ $(dirname "$VIRTUAL_ENV") == $(pwd) ] ; then
# Already at the active virtual env
return
fi
if [[ -d ./venv ]] ; then
if type deactivate > /dev/null 2>&1 ; then
printf "Deactivating virtualenv %s\n" "$VIRTUAL_ENV"
deactivate
fi
source ./venv/bin/activate
printf "Setting up virtualenv %s\n" "$VIRTUAL_ENV"
fi
}
Basé sur la solution de @ MS_:
function cd() {
builtin cd "$@"
## If env folder is found then activate the vitualenv
if [[ -d ./venv ]] ; then
source ./venv/bin/activate
fi
if [[ -n "$VIRTUAL_ENV" ]] ; then
## check the current folder belong to earlier VIRTUAL_ENV folder
# if yes then do nothing
# else deactivate
parentdir="$(dirname "$VIRTUAL_ENV")"
if [[ "$PWD"/ != "$parentdir"/* ]] ; then
deactivate
fi
fi
}
Voici (encore) une autre solution pour activer automatiquement un environnement virtuel; il est basé sur un certain nombre de réponses déjà publiées ici.
Cela fonctionnera pour tout nom ou répertoire de l'environnement virtuel (pas seulement ./env
, ./venv
, etc.). Prend également en charge les sous-répertoires, ainsi que cd
- dans les liens symboliques des dossiers de l'environnement virtuel (parent).
Ce code recherche un pyvenv.cfg
fichier au lieu d'un répertoire nommé particulier. Si l'un se trouve dans un sous-répertoire du dossier actuel, l'environnement est automatiquement activé. Une fois à l'intérieur d'un environnement virtuel, cet état est conservé jusqu'à ce que vous quittiez le répertoire de l'environnement virtuel parent, auquel point l'environnement est désactivé.
Placez-le dans votre .bashrc
ou .bash_profile
.
function cd() {
builtin cd "$@"
if [[ -z "$VIRTUAL_ENV" ]] ; then
# If config file is found -> activate the vitual environment
venv_cfg_filepath=$(find . -maxdepth 2 -type f -name 'pyvenv.cfg' 2> /dev/null)
if [[ -z "$venv_cfg_filepath" ]]; then
return # no config file found
fi
venv_filepath=$(cut -d '/' -f -2 <<< ${venv_cfg_filepath})
if [[ -d "$venv_filepath" ]] ; then
source "${venv_filepath}"/bin/activate
fi
else
# If the current directory is not contained
# within the venv parent directory -> deactivate the venv.
cur_dir=$(pwd -P)
venv_dir="$(dirname "$VIRTUAL_ENV")"
if [[ "$cur_dir"/ != "$venv_dir"/* ]] ; then
deactivate
fi
fi
}
Personnellement, je pense que c'est une amélioration de beaucoup de solutions ici, car cela devrait fonctionner pour n'importe quel environnement virtuel
c'est la solution sans cd'ing, avec zsh réglé sur setop auto_cd
nous pourrons changer de répertoire sans cd, tapez simplement le nom du répertoire et appuyez sur Entrée. c'est une des solutions ci-dessus:
# auto activate virtualenv
# Modified solution based on https://stackoverflow.com/questions/45216663/how-to-automatically-activate-virtualenvs-when-cding-into-a-directory/56309561#56309561
function auto_active_env() {
## Default path to virtualenv in your projects
DEFAULT_ENV_PATH="./env"
## If env folder is found then activate the vitualenv
function activate_venv() {
if [[ -f "${DEFAULT_ENV_PATH}/bin/activate" ]] ; then
source "${DEFAULT_ENV_PATH}/bin/activate"
echo "Activating ${VIRTUAL_ENV}"
fi
}
if [[ -z "$VIRTUAL_ENV" ]] ; then
activate_venv
else
## check the current folder belong to earlier VIRTUAL_ENV folder
# if yes then do nothing
# else deactivate then run a new env folder check
parentdir="$(dirname ${VIRTUAL_ENV})"
if [[ "$PWD"/ != "$parentdir"/* ]] ; then
echo "Deactivating ${VIRTUAL_ENV}"
deactivate
activate_venv
fi
fi
}
chpwd_functions=(${chpwd_functions[@]} "auto_active_env")
Voici ma solution:
/venv
part) et vérifiez que la commande de désactivation existe Voici le script:
function cd() {
builtin cd $1
if [[ -z "${VIRTUAL_ENV}" ]]; then
if [[ -d ./venv && -f ./venv/bin/activate ]]; then
source ./venv/bin/activate
fi
Elif [[ ! "$(pwd)" == ${VIRTUAL_ENV:0:n-5}* && ! -z "$(command -v deactivate)" ]]; then
deactivate
fi
}
Remarque: vous devez l'ajouter à .bashrc
. Si cela ne fonctionne pas, vérifiez si votre .profile
ne remplace pas votre commande (cela m'est arrivé)