Minitip pew et OSX


Ceci est un post invité de coyote posté sous licence creative common 3.0 unported.

Comme tout bon lecteur de S&M, je me fais un devoir d’adopter tous les outils conseillés par nos maîtres (oui bon sauf crossbar.io – j’ai une vie…)

Donc, j’étais très heureux de découvrir pew mais soyons honnête, ce n’est pas exactement un drop-in replacement de virtualenv-wrapper. Bien sûr, c’est très proche et c’est beaucoup mieux mais… deux-trois petites bricoles n’emmerdaient toujours.

Le problème

bash sous OSX et Linux ont des configurations et conventions un poil différentes ce qui fait que par défaut, si vous n’êtes pas déjà au fait de ces différences, vous vous rendez compte que dès que vous activez un environnement avec pew, tout est cassé : votre prompt, vos raccourcis, etc.

Tout ça est dû au fait que (/!\ simplification inside) :

* Sous linux, au lancement de tout shell, le contenu du bashrc (~/.bashrc, /etc/bashrc) est exécuté.
* Sous OSX, au lancement d’un terminal, le contenu du ~/.bash_login est exécuté puis au lancement de subshell, c’est le ~/bashrc.

C’est con, mais ça veut dire qu’à chaque pew workon toto, seul .bashrc est exécuté. Et généralement, sous OSX, il est vide ou non existant.

La solution

C’est très simple, mais ça prends quand même 5mn…

On ne peut pas simplement tout déplacer du .bash_login vers le .bashrc, sinon hors virtualenv ça ne marchera pas. Voici donc comment je fais moi, mais c’est juste parce que je suis paresseux.

~/.bash_login:

source ~/.bashrc

Et c’est tout. En gros, on court-circuite le comportement OSX pour revenir vers du plus standard.

Extrait du ~/.bashrc:

# modification de diverses variables que je veux PARTOUT (hors env et dans env)
export PATH=/usr/local/mongodb-osx-x86_64-2.6.3/bin:$PATH
 
# modifications que je veux uniquement HORS env
# si vous avez d'autres versions de python ou pip dans votre path,
# comme le .bashrc est lancé après l'inclusion du path de l'environ par pew
# vous devez bricoler sinon vous aurez pas la bonne version. 
if [ "${VIRTUAL_ENV}a" = "a" ]
	then
	export PATH="/Library/Frameworks/Python.framework/Versions/3.4/bin:${PATH}"
else
        # modification voulues uniquement dans l'env ?
fi
 
# raccourcis pour les vieilles habitudes. c'est ce qui me derange
# le plus avec pew :)
function workon() {
	pew-workon $@;
}
 
# completion pew sur le raccourci. vous connaissez le nom de vos envs vous ?
_pew()
{
    local cur=${COMP_WORDS[COMP_CWORD]}
    COMPREPLY=( $(compgen -W "$(pew-ls)" -- ${cur}) )
}
complete -F _pew workon
 
# renvoie le path d'un projet depuis le nom de l'env pour faire d'une pierre deux coups (optionnel)
# utilise pyp
function pwdof() {
	path=`pwd`
	env_name=`echo $@| pyp "p.split('/')[-1]"`
	if [ "${env_name}" = "toto" ]
		then
		path=~/src/toto-project;
	fi
 
	echo $path;
}
 
# coloration du prompt a l’intérieur du subshell
# j'aime avoir les branches git et le nom de l'env dans mon prompt.
# donc pour que votre prompt marche dehors ET dedans (exemple)
function color_prompt {
    local __user_and_host="\[\033[01;32m\]\u@\h"
    local __cur_location="\[\033[01;34m\]\w"
    local __git_branch_color="\[\033[31m\]"
    local __git_branch='`git branch 2> /dev/null | grep -e ^* | sed -E  s/^\\\\\*\ \(.+\)$/\(\\\\\1\)\ /`'
    local __prompt_tail="\[\033[35m\]$"
    local __last_color="\[\033[00m\]"
    export PS1="$__user_and_host $__cur_location $__git_branch_color$__git_branch$__prompt_tail$__last_color "
    if [ "${VIRTUAL_ENV}a" != "a" ]
    	then
		export PS1="(\$(basename '$VIRTUAL_ENV'))$PS1";
 
		# facultatif: permet de faire un cd au lancement du subshell
		cd `pwdof ${VIRTUAL_ENV}`
   	fi
}
color_prompt
 
# completion de la commande pew qui n'est pas installé par pip
# mais qui reste pratique.
# adapté depuis: https://github.com/berdario/pew/blob/master/pew/complete_scripts/complete.bash
_pew()
{
	local cur=${COMP_WORDS[COMP_CWORD]}
	local prev=${COMP_WORDS[COMP_CWORD-1]}
    args="--help --python -i -a -r"
    commands="ls add mkproject rm lssitepackages cp workon new mktmpenv setproject show wipeenv sitepackages_dir inall toggleglobalsitepackages"
 
    case $prev in
        ls|show|rm|workon|cp|setproject)
            COMPREPLY=( $(compgen -W "$(pew-ls)" -- ${cur}) )
            return 0
            ;;
        inall)
            _command_offset 2
            return 0
            ;;
        mktmpenv|new)
            COMPREPLY=( $(compgen -W "${args}" -- ${cur}) )
            return 0
            ;;
        mkproject)
            COMPREPLY=( $(compgen -W "${args} -t --list" -- ${cur}) )
            return 0
            ;;
        add)
            COMPREPLY=( $(compgen -W "--help -d" -- ${cur}) )
            return 0
            ;;
    esac
 
    COMPREPLY=( $(compgen -W "${commands}" -- ${cur}) )
 
}
complete -F _pew pew

Et voilà !

Ça casse pas trois pattes à un canard mais si vous êtes sous OSX, que vous avez installé, vu que c’était pas parfait puis vous êtes dit «on verra plus tard» et bien le moment est arrivé.

Des questions Python sans rapport avec l'article ? Posez-les sur IndexError.