quarta-feira, 26 de maio de 2010

Prompt colorido e com git branch

Meu terminal (gnome-terminal + bash) está assim no meu Ubuntu 9.10:






Eu alterei a fonte para Monaco 12px, troquei as cores e adicionei ao prompt o branch do repositório que eu estou (caso a pasta seja um repositório git).

E como isso foi feito?




Instalando a Fonte Monaco no Ubuntu



A instalação da fonte Monaco no Ubuntu pode ser feita da seguinte maneira:



sudo mkdir /usr/share/fonts/macfonts
sudo wget http://jorrel.googlepages.com/Monaco_Linux.ttf -O /usr/share/fonts/macfonts/Monaco_Linux.ttf
sudo fc-cache -f -v


O diretório /usr/share/fonts/macfonts será criado, a fonte Monaco_Linux.ttf será colocada em tal diretório e as configurações de fontes do sistema serão atualizadas. Muito simples!


(Créditos do post http://jorrel.blogspot.com/2007/11/monaco-on-ubuntu.html)



Como Adicionar o git branch ao Prompt


No terminal há uma variável de ambiente chamada PS1, ela guarda a mensagem que será apresentada ao usuário do terminal. Imagine a seguinte situação:


hugo@hugo-laptop:~$ echo $PS1
\u@\h:\w$

Isso significa que será mostrado na mensagem o usuário do sistema, um arroba, o hostname, dois pontos, o diretório atual e um cifrão. Em outras palavras, significa dizer que o usuário é identificado por \u, enquanto o hostname é \h e o diretório é \w.


Para personalizar as mensagens é simples, basta alterar o valor da variável PS1! Por exemplo:


hugo@hugo-laptop:~$ pwd
/home/hugo
hugo@hugo-laptop:~$ export PS1="prompt do \u:\w$ "
prompt do hugo:~$ pwd
/home/hugo
prompt do hugo:~$


A idéia é adicionar à mensagem o nome do branch do repositório git. Para saber o nome do branch no git basta um `git branch` e olhar a linha que começa com asterisco. Por exemplo:



hugo@hugo-laptop:~/should-dsl$ git branch
master
* matchers-as-functions
new_matchers_based_on_hamcrest
nsigustavo_master
rodrigomanhes
separate-matchers
hugo@hugo-laptop:~/should-dsl$


Se for desejado saber apenas o branch atual, podemos usar o grep pra fazer isso:


hugo@hugo-laptop:~/should-dsl$ git branch | grep ^\*
* matchers-as-functions
hugo@hugo-laptop:~/should-dsl$


E se quisermos apenas o nome do branch, sem o asterisco, podemos usar o sed pra remove-lo:


hugo@hugo-laptop:~/should-dsl$ git branch | grep ^\* | sed 's/\* //'
matchers-as-functions
hugo@hugo-laptop:~/should-dsl$

Agora já podemos adicionar o nosso branch à mensagem do terminal:


hugo@hugo-laptop:~/should-dsl$ branch=`git branch 2>/dev/null| grep ^\* | sed 's/\* //'`
hugo@hugo-laptop:~/should-dsl$ export PS1="\u@\h:\w($branch)$ "
hugo@hugo-laptop:~/should-dsl(matchers-as-functions)$

O redirecionamento de erros é pra tratar o caso do comando `git branch` dar um erro, ou seja, a pasta atual não ser um repositório git.



Mas o interessante é ter cores, não!?



Cores no Terminal


É possível usar cores nos terminais unix através de algumas sequências ASCII de cores. Há uma biblioteca, termcolor, que traz esse recurso pro python. Assim, é possível usá-la pra colorir o terminal. Mas no nosso caso vamos ser mais hardcores e lidarmos com as nossas sequências manualmente (porque queremos ser independentes!).



O padrão das sequências de cores é basicamente o seguinte: uma sequência dizendo que se inicia a sequencia, um modificador opcional, a cor, o texto e o finalizador de cor. O que eu quero dizer por modificador é um negrito, por exemplo.



A cor verde, por exemplo, é identificada pelo número 32. A sequência de cores se inicia sempre com um \033[ e sempre termina com um \033[m. Um texto colorido de verde no terminal pode ser feito assim:







Para quem não conseguir visualizar a imagem, o texto no terminal é:


hugo@hugo-laptop:~$ echo -e "\033[32mHello World (verde)\033[m"
Hello World (verde)
hugo@hugo-laptop:~$

Agora chegou a hora de juntar tudo num lugar só!



Mostrando o git branch colorido no prompt


Os comandos aqui usados já foram explicados, então o código segue:


function git_branch_name() {
git branch 2>/dev/null | grep -e '^*' | sed -E 's/^\* (.+)$/(\1) /'
}

function show_colored_git_branch_in_prompt() {
PS1="\[\033[01;32m\]\u@\h:\[\033[01;34m\]\w\[\033[31m\]\$(git_branch_name)\[\033[m\]$ "
}

show_colored_git_branch_in_prompt

Adicione este trecho ao ~/.bashrc e seja feliz!



Caso você queira ver as modificações sem ter que abrir outro terminal, use o comando source:


$ source ~/.bashrc



Peguei a dica nesse post: http://asemanfar.com/Current-Git-Branch-in-Bash-Prompt e alterei algumas coias. Os comentários são excelentes!



Espero que tenham gostado da dica ;-)




Updates:



  • Corrigido PS1 pra ser dinâmico, e não estático
  • Corrigida duplicação de `function`. Valeu Siminino!


quinta-feira, 20 de maio de 2010

Apresentando Retrospectivas

O que será abordado aqui


Eu participava de retrospectivas e até liderava algumas sem conhecer direito, no final acabava sendo algo que não gerava tanto valor e ficavam palavras ao vento. O que eu apresentar aqui no texto é baseado no capítulo 13 do livro Agile Coaching, "Driving Change with Retrospectives" e nos conhecimentos adquirido blogs e livros a fora.


Introdução



Retrospectivas são usadas desde a era industrial pra analisar o que aconteceu com as equipes e estudar possíveis melhorias. Muitas vezes é criada uma linha do tempo (timeline) pra registrar a evolução da equipe. Em Lean Manufecturing essa prática é conhecida como Kaizen, que significa melhora contínua.




Retrospectiva, segundo o Aurélio é:

s.f. O mesmo que retrospecto


Enquanto retrospecto é definido da seguinte forma:

s.m. Vista ou análise de fato passado.


Segundo a Wikipedia, a palavra retrospectiva vem do latim retrospectare, que significa "olhar pra trás". Ou seja, retrospectivas são nada mais, nada menos, que encontros nos quais o objetivo é olhar os fatos decorridos e tentar encontrar pontos que podem ser melhorados e estudar como aplicar tais melhorias, visando aumentar os ganhos e diminuir os desperdícios.

Henrik Kniberg diz em seu famoso livro Scrum and XP from the Trenches: "Sem retrospectivas você percebe que a equipe continua cometendo os mesmos erros de sempre". Retrospectivas tratam do processo que a equipe utiliza, são uma maneira de identificar onde as coisas não estão saindo como o esperado e estudar como reduzir os problemas.

Muitas equipes que tentam fazer retrospectivas acabam desistindo de fazê-las, pois dizem que não sentiram resultados. O problema é que na verdade quem fez não sabia como fazer uma retrospectiva. Pode parecer estranho, mas justificar pra equipe que restrospectivas são fundamentais não é tão simples. Muita gente entorta o nariz da primeira vez, até ver que funciona.

Segundo Rachel Davies e Liz Sedley, autoras do livro Agile Coaching, as retrospectivas devem ser a primeira prática ágil a ser usada pelas equipes que estão começando a usar métodos ágeis. O motivo é que nas retrospectivas são discutidos vários problemas e durante a próxima iteração a equipe já pode introduzir as mudanças e ver melhorias!

O Papel do Facilitador



Toda retrospectiva precisa de alguém pra facilitar o encontro. Alguém que guie a retrospectiva, que consiga extrair os problemas, idéias e soluções da equipe. Tal pessoa é o facilitador da retrospectiva.

Facilitando uma Retrospectiva



Cada vez que uma iteração termina deve ser feita uma retrospectiva pra abordar os seguintes tópicos:

  • Quais idéias a equipe teve desde a última iteração?
  • Quais áreas a equipe quer focar em melhorar?
  • Em quais idéias eles podem trabalhar na próxima iteração?

Metade do tempo da retrospectiva deve ser gasto olhando pra iteração passada pra ver o que aconteceu e os porquês. Em seguida idéias são levantadas para que possam ser criados planos de ação (action plans), que dizem o que deve ser feito pra implantar melhorias.

Basicamente facilitar uma retrospectiva é isso, e os próximos passos são integrar à próxima iteração as ações mais prioritárias.

Para que uma retrospectiva seja proveitosa, leva tempo e prática. Não adianta tentar consertar muitos problemas numa única iteração - não vai dar certo!

A Retrospectiva Feita nos Dojos



É um costume em coding dojos fazer uma retrospectiva no fim. Sempre que chega no tempo combinado da duração do dojo, é feito uma retrospectiva. A maneira mais básica de fazer a retrospectiva é dividir o quadro (ou flip chart) em duas colunas: O Que Foi Bom, O Que Foi Ruim. Algumas pessoas gostam de colocar uma divisão entre as duas colunas pra pegar informações sobre o que pode ser melhorado.

Um exemplo de uma imagem de retrospectiva de um dojo com duas colunas pode ser visto na seguinte imagem:

Imagem de uma retrospectiva


O problema é que na retrospectiva que acontece nos dojos ficam muitas palavras ao vento. Na maioria das vezes não dá pra criar um plano de ações para melhorar o processo. A retrospectiva acaba ficando mais como lição e compartilhamento de visões, sem ter, de fato, ações de melhorias. O ponto é que a maioria das retrospectivas feitas nos dojos são, a meu ver, mal aproveitadas.



Como Olhar Para O Passado



Há algumas maneiras de recolher informações do passado. O objetivo nesse momento da retrospectiva é entender o que aconteceu, e os membros da equipe precisam compartilhar suas histórias individuais e integrá-las com as dos outros membros. Algumas maneiras de alcançar tal objetivo são:

Linha de tempo colorida: É criada uma linha de tempo no quadro ou em algum lugar onde possa ser colado post-its e escrever os acontecimentos na linha de tempo. Post-its coloridos com frases descritivas são usados para indicar os sentimentos da equipe em determinado lugar na linha de tempo. Normalmente é usada a cor verde para o que foi proveitoso, rosa ou vermelho para o que foi estressante e amarelo para o que for neutro. Talvez seja necessário colocar uma legenda para as cores ao lado da linha de tempo pra que ninguém se perca.

Galeria de arte (art gallery): O facilitador pede a equipe que cada um desenhe uma imagem do que o projeto se parece pra eles, depois cola as imagens em algum lugar visível a todos. Assim que todos terminarem o facilitador pede que cada explique o seu desenho. Pode parecer estranho, mas as pessoas são muito boas em encontrar metáforas pro que é difícil de ser explicado com palavras. Um relato interessante citado no livro Agile Coaching foi de uma retrospectiva em que um membro desenhou um boneco de palitinhos dentro de uma caixa, e quando foi explicar pra equipe o desenho ele disse que era assim que ele se sentia no projeto - ele trabalhou muito isolado dos outros, e era como se ele não fizesse mais parte do projeto.

Há uma variação de art gallery que o Patrick Kua desenvolveu que é muito interessante, o nome é Mr. Squiggle.

Funciona da seguinte maneira: o facilitador desenha alguns traços em papéis (podem ser usados post-its) e entrega um papel pra cada membro da equipe, contendo os mesmos traços criados pelo facilitador. Dê a equipe 5 minutos pra desenharem nos papéis o que o projeto representa pra eles, usando os rabiscos que o facilitador colocou no papel. Depois peça que cada um explique seu desenho para a equipe.

O interessante do Mr. Squiggle é que cada um faz um desenho totalmente diferente, mesmo iniciando com os mesmos traços.

Bad Smells



"If it stinks, change it"
Avó do Kent Beck, discutindo sobre como criar os filhos


Assim como com código, é possível ver Bad Smells em retrospectivas - aqueles indícios de que há algo errado.

Idéias da última iteração são ignoradas É pedido a equipe novas idéias sem discutir o que aconteceu na última iteração. Isso não funciona, pois os problemas são evitados.

Palavras ao vento Vários itens estão nas colunas "O que foi bom" e "O que não foi bom", mas nenhuma ação é tomada em relação aos dados recolhidos. No fim das contas a retrospectiva serviu apenas como uma conversa e lição de vida.

Mudar o mundo Algumas equipes criam listas com coisas a serem melhoradas sem considerar a viabilidade de fazer aquelas ações na próxima iteração. Isso traz desapontamento à equipe, porque não conseguiram fazer o que planejaram, e a cada retrospectiva são adicionadas mais ações.

Ações sem "Donos" Ações que foram criadas e não possuem donos, algo como "Melhorar a comunicação" e "Fazer mais refactoring", não deveriam ser ações, pois são problemas que devem ser trabalhados. Se não houver discussão, a equipe não vai saber como implementar tais "pseudoações".

Falta de tempo para melhorar A equipe leva cinco minutos depois de uma apresentação de uma release ou demo pra conversar brevemente sobre os acontecimentos e chama isso de retrospectiva. Esse é um sinal de que a equipe não vê benefícios em retrospectivas.

Peneirando Informações



Depois que foram recolhidas informações suficientes da equipe é necessário gerar insights. Caso haja alguma informação que ainda não foi compreendida, a equipe deve esclarecê-la - não deve ser pedido diretamente para a pessoa que escreveu a nota explicar, deve ser pedido à equipe. Caso haja frases genéricas como "Ambiente de testes quebrado" ou "Cliente muito ocupado", deve ser pedido exemplos pra tornar mais fácil de ilustrar o problema pra todos.

Depois de andar sobre a timeline procurando por insights é a hora de escolher os tópicos mais importantes pra focar. Uma das técnicas é votação por pontos (dot voting). Cada membro da equipe tem três pontos que pode colocar em qualquer tópico que ache que é mais prioritário - inclusive pode usar os três pontos em um tópico só. Os tópicos com maior pontuação farão parte do planejamento de ações (action planning).

Após extrair os tópicos que a equipe quer focar, procura-se por melhorias no processo que a equipe possa fazer na próxima iteração.

Olhando pro Futuro



A segunda metade da retrospectiva deve olhar pra próxima iteração, que é quando a equipe vai trabalhar o gostaria de mudar no processo. Será necessário mais que concordar que mudanças são necessárias, a equipe deve trabalhar nas ações levantadas pra implantar as mudanças.

Antes de começar a criar ações novas, um tempo deve ser dedicado para revisar o que aconteceu com as ações da última retrospectiva. Se não foram terminadas a equipe precisa entender o motivo antes de adicionar criar mais ações. Na maioria dos casos é porque as ações não tinham dono ou porque a equipe "não teve tempo".

Um tempo deve ser investido na retrospectiva pra trabalhar num plano de ações realista, que seja claro pra todos da equipe. Para que as ações fiquem prontas a equipe precisa terminá-las. O facilitador combina com a equipe quanto tempo será gasto com as melhorias no processo na próxima interação, lembrando que as ações serão feitas enquanto a equipe continua trabalhando no plano do release, ou seja, enquanto continuam a desenvolver software.

Como Criar O Plano de Ações



Assim como no desenvolvimento de software, a equipe deve dar passos de bebê (baby steps) na hora de criar as ações pra serem implementadas na próxima iteração. Nem sempre as ações são problemas que podem ser corrigidos - às vezes são estudos sobre algum problema, estabilizar um estilo de código, etc.

Bas Vodde tem um texto excelente de como criar planos de ação, que as autoras do livro Agile Coaching resumiram no livro.

Para ter ações que funcionam, a equipe precisa, além de identificar o que precisa ser alterado, dizer como serão implementadas as mudanças. O processo de recolher as ações que Bas Vodde usa é o seguinte: cada ação tem um objetivo a longo prazo e uma ação para ser feita agora. Por exemplo:

Objetivo a longo prazo: Ter testes de aceitação automatizados
Ação para agora: Fulano vai automatizar o teste ABC usando XYZ.


No exemplo citado por Bas Vodde a equipe consiste de oito membros. Inicialmente cada membro gera um conjunto de ações - separadamente - cada uma com um objetivo a longo prazo e uma ação para ser feita; a equipe tem 10 minutos pra gerar as ações.

Após geradas as ações, a equipe se divide em duplas. Durante 10 minutos cada dupla agrupa suas ações e seleciona as 5 mais prioritárias.

Depois que as duplas selecionarem 5 ações, são gerados grupos de 4 pessoas. Cada grupo agrupa suas ações e seleciona apenas 4 de todas as 10 ações selecionadas (2 duplas selecionaram 5 ações cada) - durante o limite de 10 minutos.

Para finalizar, a equipe inteira reúne-se e de todas as 8 ações selecionadas (2 grupos de 4 pessoas e cada grupo selecionou 4 ações), seleciona as 3 mais importantes pra serem implementadas na próxima iteração.

A vantagem dessa técnica é que ela reúne tanto esforço individual quanto em grupo, além de ter que haver um consenso entre todos os membros da equipe sobre quais são as prioridades. Devagar e com passos de bebê. Independente do número de ações geradas inicialmente, no fim, apenas três ações são selecionadas. Selecionar ações demais é um erro, que já foi descrito anteriormente como bad smell (Mudar o Mundo).

Depois da retrospectiva as ações precisam ser planejadas na próxima iteração. A equipe combina como serão priorizadas as ações e post-its com as ações podem ser grudados no quadro, para que não sejam esquecidos durante a próxima iteração.

Um Formato Pra Começar



Há vários formatos de retrospectivas, alguns mais complicados que outros. Acima foi descrito um formato, mas não é recomendável que seja usado da primeira vez. Antes da retrospectiva começar é necessário arrumar uma sala pra fazer a retrospectiva e material como canetas, papel e post-its - um quadro seria muito bom.

Um exemplo de como dividir a retrospectiva, citado no livro Agile Coaching segue:
  • Revise o objetivo do encontro, e relembre a equipe das regras básicas (5 minutos)
  • Crie uma linha de tempo (15 minutos)
  • Pegue insights baseado na linha de tempo (15 minutos)
  • Selecione tópicos para focar (10 minutos)
  • Revise o progresso de ações prévias (5 minutos)
  • Gere idéias para melhorias (15 minutos)
  • Faça um planejamento de ações (15 minutos)

Esse formato é recomendável pra quem quer iniciar retrospectivas, mas usar o mesmo formato sempre não é interessante, pois se torna chato, tanto pra equipe quanto pro facilitador. Então, varie os formatos. Há vários formatos listados na wiki Agile Retrospective e podem ser encontrados em http://agileretrospectivewiki.org/index.php?title=Retrospective_Plans.

Diretriz Primária (Prime Directive)



Tratando-se de retrospectivas há algumas regras básicas, como em qualquer outra reunião, como: não usar computadores, colocar os telefones no silencioso, esperar a vez pra falar. Além das regras básicas há uma diretriz que é chamada de prime directive, que diz: "Independente do que nós descobrirmos, entendemos e acreditamos que todos fizeram o melhor que podiam, dado o que sabiam na época, seus conhecimentos e habilidades, os recursos disponíveis, e a situação em questão".

É claro que o mundo não é perfeito e as pessoas cometem erros. Apesar da diretriz primária parecer dizer que problemas não serão causados por indivídios, é bom deixar claro que as retrospectivas não são o melhor lugar para discutir problemas de perfomance dos membros. Retrospectivas devem focar em como melhorar o processo; caso a performance de algum indíviduo venha à tona, mude o foco de volta para as ações da equipe.

Rachel Davies e Liz Sedley recomendam que na primeira vez que for feita uma retrospectiva, seja colado na parede a prime directive e que você explique para a equipe o que ela significa.

Minha Tentativa Com O Mr. Squiggle



Ontem (20/05/2010) eu não esperava, mas o Gustavo Rezende me pediu pra fazer uma retrospectiva com os aspiras lá no NSI, sem preparar nada. Eu havia comentado com ele sobre essa técnica de desenhos e ele achou interessante e falou pra eu fazer. Bem, eu não havia preparado nada e era o fim de uma release de um projeto que os nossos aspiras estavam fazendo. Eles fizeram uma demonstração para o suposto cliente, que era o Ronaldo Amaral. Eles pecaram em várias coisas, mas era a primeira vez que eles trabalhavam em equipes e não conheciam as tecnologias e métodos ágeis 3 semanas atrás.

O interessante é que foi uma retrospectiva de fechamento, e no fim, eu usei os mesmos rabiscos que o Patrick Kua (porém numa disposição diferente): uma bolinha, uma reta na horizontal e outra na vertical.


Mr. Squiggle com Aspiras do NSI


Foi muito interessante ver que todos fizeram desenhos totalmente diferentes, mas que acabaram refletindo uma coisa só: o quanto eles tinha aprendido enquanto trabalhavam no projeto. Todos relataram sobre o quanto aprenderam, como foi o trabalho em equipe, como estudaram as tecnologias e etc. Como a idéia não era ter próxima iteração, pra mim não havia sentido fazer um planejamento de ações, porque o projeto que eles iniciaram iria parar ali. Mas Ronaldo achou melhor dar continuidade até na sexta-feira (mais 2 dias).

Pode parecer muito estranho de primeira, mas esse formato com desenhos funciona.

Checklist



No livro Agile Coaching há no fim de cada capítulo uma checklist que mostra os pontos principais pra executar com sucesso o que foi descrito no capítulo. No capítulo sobre retrospectivas a checklist se resume a:
  • Comece a retrospectiva olhando pro passado para entender o que aconteceu o o porquê. Dê tempo suficiente à equipe para contar a história inteira

  • Gaste a segunda metade da retrospectiva olhando pro futuro e decidindo o que irá no plano de ações

  • Procure por bad smells que estão atrapalhando a equipe a ser mais efetiva. Se as retrospectivas não estão melhorando o processo, pense em como você poderia melhorá-las

  • Ache os problemas que a equipe mais quer consertar. Use a votação por pontos para focar no que a equipe gastará suas energias

  • Não adicione mais ações durante a iteração antes da próxima retrospectiva. Até mesmo duas ou três ações terminadas a cada iteração podem causar um impacto significante por vários meses

  • Se as ações da última retrospectiva não foram finalizadas, procure saber os motivos antes de adicionar mais




Referências



O livro Agile Coaching é excelente, a maior parte do conteúdo do post é baseado no capítulo 13 dele. Há um livro só sobre retrospectivas, Agile Retrospectives. Tem um livro que eu nunca li, o Project Retrospectives, mas já fiz umas pesquisas no site deles, que por sinal tem um material muito bom.


Updates:

Adicionada foto dos desenhos feitos pelos aspiras na retrospeciva (Mr. Squiggle)



quinta-feira, 13 de maio de 2010

Gerenciando ambientes virtuais e pacotes python de forma fácil

Bem, eu estou devendo há um tempo um post sobre integração entre a Python C/API e a Ruby C/API, mas esse post vai ficar no forno mais um tempinho, porque eu tive um insight maneiro e quero compartilhar.

Ontem eu estava dando uma olhada no virtualenvwrapper, por recomendação do Hugo Maia Vieira e aproveitei pra fazer umas brincadeirinhas com ele junto ao pip.
Vou explicar a idéia de cada projeto envolvido nessa brincadeira e mostrar como criar uma maneira simples de usar ambientes virtuais personalizados e gerenciar pacotes Python (python packages).



pip


pip significa "pip install [Python] packages", ou seja, é um instalador de pacotes Python. O instalador de pacotes que já está padronizado entre os pythonistas é o easy_install, eu sei. Porém, quem nunca teve problemas com o easy_install? Quem nunca teve problemas pra desinstalar um pacote? Oh shit! Como assim o easy_install não desinstala? A maneira de "desinstalar" pacotes no easy_install é dizer que o pacote é multiversionado, e ele ainda reside no sistema mesmo assim. O que eu costumava fazer era ir lá na pasta onde ficavam meus pacotes python e remover os arquivos e remover a entrada do easy-install.pth (que guarda as referências do caminhos dos pacotes). Eu até criei um easy_uninstall pra remover meus pacotes :-).

Esse ano eu estou participando do Google Summer of Code e vou trabalhar no pip! Muito provavelmente vou blogar (num futuro próximo) sobre o pip e o que eu ando fazendo nele e o que eu tenho aprendido com o pessoal do projeto. Vai ser uma grande oportunidade pra mim e vou tentar aproveitar o máximo.

O objetivo do pip é ser um substituto do easy_install, mas com muito mais funcionalidades. Vou citar algumas coisas que o pip faz, pondo o nome do comando no cabeçalho.



pip install


O nome já diz tudo: instala algum pacote (ou alguns).

$ pip install PACOTE_DESEJADO

pip uninstall


Uma coisa básica é que o pip desinstala pacotes! Que maravilha, não? O easy_install não faz nem isso!


$ pip uninstall PACOTE_DESEJADO

pip freeze



A idéia é que você às vezes precisa saber quais pacotes você tem instalado no sistema, e o comando freeze lista todos os pacotes instalados no python em que o pip foi rodado.
$ pip freeze


pip bundle



O pip consegue criar bundles. Bundles são pacotes que contém vários pacotes. A idéia é criar um pacotão com tudo necessário pra instalar um software - dependências e etc. Ano passado eu trabalhei em um sistema que ia ser implantado em Angola e no local que ia ser instalado o sistema não havia conexão de internet boa (era 56k) e não era garantido de chegar lá em Angola e conseguir usar a internet. O que a minha equipe fez foi criar um pacotão com todas dependências de sistema e outro pacotão com todas as dependências dos pacotes python. Os meus amigos Diego Manhães e Vanderson Mota ficaram responsáveis por isso, e eu garanto que não foi trivial.

Usando o pip essa tarefa se torna fácil, porque é possível criar um pybundle com os pacotes (e suas respectivas dependências). Por exemplo:

$ pip bundle pycukes.pybundle pycukes


E para instalar no sistema (sem a necessidade de uma conexão de internet), basta levar o arquivo pycukes.pybundle num pendrive ou dvd e fazer:

$ pip install pycukes.pybundle


E nesse caso todas as dependências serão instaladas junto ao pycukes.

pip search



Sabe aquele dia que um apt-cache search salva a sua vida? Então, o pip também tem um comando search que pode salvar você! É como se você tivesse ido ao PyPI e digitado alguma coisa no campo de busca e clicado no botão Search. Você pode ver os nomes dos pacotes e as descrições dos mesmos.

$ pip search TERMO_DA_BUSCA



virtualenv


O virtualenv cria ambientes virtuais pra você usar um interpretador Python sem ser o do sistema. Quem nunca bagunçou o Python do sistema quando quis fazer alguma brincadeira? Então, o virtualenv veio pra solucionar esse e outros problemas. Você não precisa mais de ser superusuário pra instalar pacotes. Você pode ter quantos interpretadores python você quiser, e cada um deles pode ter pacotes diferentes. Ou seja, você consegue isolar um ambiente pra instalar e usar pacotes python.


Criar um ambiente virtual é muito simples:

$ virtualenv meu_ambiente


Porém, pra usar algum ambiente virtual é necessário ativar esse ambiente. Você pode fazer da seguinte forma:

$ source CAMINHO/PARA/meu_ambiente/bin/activate

ou

$ . CAMINHO/PARA/meu_ambiente/bin/activate


Após isso você verá que que o texto do seu terminal foi modificado (variável de ambiente $PS1), e lá tem o nome do seu ambiente entre parênteses. Agora você pode instalar o que quiser ali e apagar o que quiser! Fazer qualquer tipo de experimento.

O único problema nessa abordagem é que você ainda aproveita os pacotes instalados no python do sistema. A maneira de solucionar isso é dizendo que você quer criar um ambiente virtual que não tem nenhum pacote aproveitado do sistema:

$ virtualenv --no-site-packages meu_ambiente


Imagina que você criou um ambiente virtual e quer usar o pip nele, você só precisa USAR! O virtualenv já vem com o pip instalado. Mas caso você queira atualizar o pip, faça um:

$ pip install -U pip


Sempre que você quiser sair do ambiente virtual, chame o deactivate:

$ deactivate


E voltará ao ambiente normal.

Agora você já pode ser feliz com seus pacotes python e fazer o experimento que quiser, e ter quantos ambientes virtuais (isolados) você quiser. Bom, não?!



virtualenvwrapper



Quem já está acostumado a usar o virtualenv sabe que é um saco ter que lembrar os caminhos dos ambientes e ficar dando source no caminho do activate. Outra coisa chata é quando você precisa ir pra pasta de site-packages do ambiente virtual. Pensando nessas coisinhas enjoadas um cara pegou e criou um script que adiciona várias funcionalidades ao virtualenv, o virtualenvwrapper. A instalação do virtualenvwrapper é simples:

$ pip install virtualenvwrapper


Porém, ainda não dá pra sair usando. Você precisa carregar o script (virtualenvwrapper.sh) sempre que quiser usar os recursos do virtualenvwrapper. No fim das contas é melhor adicionar ao seu ~/.bashrc. Depois de instalar o virtualenvwrapper com o pip ou easy_install (eu usei o python do sistema), faça:

$ echo "source `which virtualenvwrapper.sh`" >> ~/.bashrc
$ mkdir ~/.virtualenvs

E você criará uma pasta (a padrão) pra armazenar os ambientes virtuais e sempre terá os comandos do virtualenvwrapper disponíveis.

Depois de reiniciar o terminal, você já pode usar o virtualenvwrapper! Digite:

$ workon


E você provavelmente vai ver uma linha em branco, porque você ainda não tem nenhum ambiente virtual criado com o virtualenvwrapper.


mkvirtualenv


O comando mkvirtualenv cria um ambiente virtual baseado no nome que você passar, e você pode passar os mesmos parâmetros que são passados ao virtualenv.

$ mkvirtualenv --no-site-packages meu_ambiente


Quando você digitar o comando acima criará um ambiente virtual com nome de meu_ambiente, que não compartilha pacotes com o python do sistema e irá automaticamente ativar o ambiente.


rmvirtualenv

Quando não houver mais interesse em usar um ambiente virtual, ele pode ser apagado com o comando rmvirtualenv. É necessário estar com o ambiente em questão desativado - caso esteja ativado use o deactivate.

$ rmvirtualenv meu_ambiente


workon



O comando workon quando chamado sem parâmetros mostra todos os ambientes virtuais existentes. Mas quando chamado com o nome do ambiente virtual, ativa o ambiente e executa os hooks (caso existam).

$ workon # lista os ambientes virtuais
$ workon meu_ambiente # ativa o ambiente virtual meu_ambiente


cdvirtualenv


Muda o diretório atual para o diretório do ambiente virtual. Por exemplo, você está na pasta /tmp e quer ir pra pasta do ambiente meu_ambiente:

(meu_ambiente)hugo@hugo-laptop:/tmp$ pwd
/tmp
(meu_ambiente)hugo@hugo-laptop:/tmp$ cdvirtualenv
(meu_ambiente)hugo@hugo-laptop:~/.virtualenvs/meu_ambiente $ pwd
/home/hugo/.virtualenvs/meu_ambiente


cdsitepackages

O comando cdsitepackages muda do diretório atual para o diretório de site-packages do ambiente virtual.

$ cdsitepackages



lssitepackages

O comando lssitepackages faz um ls na pasta site-packages.

$ lssitepackages



cpvirtualenv

Quando houver necessidade de clonar um ambiente virtual, seja porque você precisa basear-se nos pacotes já instalados ou por qualquer outro motivo, use o cpvirtualenv.

$ cpvirtualenv meu_ambiente meu_ambiente_clonado




Hooks



Hooks são scripts que são ativados antes, depois ou durante o acontecimento de um evento. Por exemplo, no Git você pode criar um script pra que após cada push executado no repositório diga ao servidor de integração contínua pra rodar o build.

No virtualenvwrapper existem hooks também, com a mesma idéia. A documentação do virtualenvwrapper documenta os hooks na área de Per-User Customization. Vou explicar apenas dois deles, o postactivate e o mpostmkvirtualenv.

postactivate



É um shell script que você deve colocar na sua $WORKON_HOME/postactivate - no nosso caso $WORKON_HOME será ~/.virtualenvs. O caso abaixo muda o diretório corrente para o diretório PASTA sempre que algum ambiente virtual for ativado:

$ echo 'cd PASTA_QUALQUER' >> $WORKON_HOME/postactivate


postmkvirtualenv



Uma das dicas que o Doug Hellmann, o autor do virtualenvwrapper, dá na documentação é que às vezes você precisa instalar alguns pacotes pra ter seu ambiente virtual pronto pra usar. Eu fiz isso. Sempre que eu crio um ambiente virtual alguns pacotes são instalados. No meu caso eu ainda fiz mais, eu adicionei um link pra um pacote python que é instalado junto ao Ubuntu (no caso o GTK e o Cairo, pra eu usar o pynotify no ambiente virtual).

Vamos fazer um caso simples: atualizar o pip, instalar o ipython e o nosetests.

$ echo 'pip install -U pip' >> $WORKON_HOME/postmkvirtualenv
$ echo 'pip install ipython nose' >> $WORKON_HOME/postmkvirtualenv


Agora sempre que um ambiente virtual for criado ele atualizará o pip do ambiente virtual e instalará no mesmo ambiente o pacote ipython e nose.


Peon



Imagine que você quer executar algum comando sempre que algum arquivo for modificado num determinado diretório. Como faz? Bem, você pode criar um script que cria um checksum baseado no somatório do tamanho de cada arquivo e na data de modificação. Bem, é assim que todo mundo faz. O Jeff Winkler teve a idéia de fazer um script que ficava procurando por mudanças em arquivos terminados em .py e quando havia modificação, rodava o nosetests. Ele chamou o script de nosy.



O Bernardo Heynemann acabou pegando a idéia do Jeff e criando o peon, que busca recursivamente por modificações em arquivos terminados em .py e usa o pynotify pra mostrar um alerta, caso o comando passado retorne algum status code diferente de zero.

Pra instalar o peon você pode baixar o projeto no github, cloná-lo ou instalá-lo através do arquivo compactado gerado pelo github:

$ git clone http://github.com/heynemann/peon.git
$ cd peon
$ pip install .

ou

$ pip install http://github.com/heynemann/peon/zipball/master


Para usar o peon é super simples, basta chamá-lo passando o comando que você quer que seja executado quando alguma modificação for feita. No meu caso, eu queria que o peon rodasse um script que fazia build e rodava os testes de um projeto, e caso houvesse alguma falha ou erro no script de build, mostrasse a notificação com o pynotify. No meu caso era um Makefile que o peon rodava. Era basicamente:

$ peon make


O meu problema



O pynotify é um pacote instalado pelo Ubuntu, sob o pacote do GTK e quando eu criava um ambiente virtual totalmente isolado (--no-site-packages) eu não tinha acesso ao GTK e nem ao Cairo (dependência) e assim, não tinha como usar o pynotify pra exibir os alertas.

A minha solução



A primeira coisa é que eu precisava instalar o peon sempre que eu criasse um ambiente virtual. Fiz isso usando o postmkvirtualenv. Outra coisa que eu acabei fazendo foi criar um link simbólico dentro dos meus site-packages apontando pro GTK e pro Cairo. A solução que eu cheguei foi usar o postmkvirtualenv pra criar os links simbólicos e adicionar às entradas devidas no easy-install.pth.

Ok, falei um monte de coisas. Mas... e aí, como eu faço isso? A primeira coisa é instalar o peon. Uma das features do github é que ele oferece download dos repositórios de forma compactada. Assim, pra instalar o peon basta um:

$ echo 'pip install http://github.com/heynemann/peon/zipball/master' >>\
> $WORKON_HOME/postmkvirtualenv


Agora a parte complicada é fazer os links simbólicos e adicionar as entradas no easy-install.pth.

$ echo "
> cwd=`pwd`
> cdsitepackages
> ln -s /usr/lib/pymodules/python2.6/gtk-2.0 .
> ln -s /usr/lib/pymodules/python2.6/cairo .
> sed -i '1a ./gtk-2.0' easy-install.pth
> sed -i '1a ./cairo' easy-install.pth
> cd $cwd
> " >> $WORKON_HOME/postmkvirtualenv


A primeira linha, cwd=`pwd`, e a última, cd $cwd foram adicionadas pra ser possível voltar pro diretório atual depois de executar o hook.

Agora já é possível usar o peon com ambientes virtuais sem problemas!

Faça o teste ;-)



O meu objetivo com isso



No fim das contas eu acabei criando um postmkvirtualenv que instala alguns pacotes, inclusive o peon, e cria os links simbólicos. Eu sempre crio os links e instalo o peon porque o meu objetivo com os ambientes virtuais é ter um ambiente virtual pra cada projeto que eu contribuo, assim, cada projeto é totalmente isolado do outro e eu tenho um alerta caso os testes não sejam executados com sucesso em algum momento.


Observações



Tudo que eu falei aqui está relacionado a Python 2.x. Todos os lugares onde o pip foi usado apenas pra fazer instalação de pacotes do PyPI, o easy_install poderia ter sido usado (apesar de desencorajado!).


Referências



A documentação do pip tem bastante informação e o pessoal (inclusive eu) está sempre online no #pip na freenode.


Há um post excelente pra quem quer ver o virtualenvwrapper na prática: http://mathematism.com/2009/jul/30/presentation-pip-and-virtualenv/

Nesse mesmo post há um screencast muito interessante também!


Até o próximo post ;-)





Updates:

  • corrigido erro relacionado a aspas no echo. Valeu Hugo Maia e Álvaro!

  • corrigido erro de portugues: s/enjuado/enjoado/g Valeu Hugo Maia!