Matheus Tardivo

Code is poetry.

Deploying Rails Applications Using Capistrano

About Capistrano:

Capistrano is a utility and framework for executing commands in parallel on multiple remote machines, via SSH. It uses a simple DSL (borrowed in part from Rake) that allows you to define tasks, which may be applied to machines in certain roles. It also supports tunneling connections via some gateway machine to allow operations to be performed behind VPN’s and firewalls.

Capistrano was originally designed to simplify and automate deployment of web applications to distributed environments, and originally came bundled with a set of tasks designed for deploying Rails applications.

In the project that I’m working for, I’d set up Capistrano to deploy our Rails application to development environment.

The first step is install Capistrano, using the follow command gem install capistrano.

Next step is setup is Rails application for use Capistrano, and you can do it running the follow command in the root folder of your Rails application capify .

1
2
3
[add] writing './Capfile'
[add] writing './config/deploy.rb'
[done] capified!

Capfile contents:

1
2
3
4
5
6
7
8
load 'deploy' if respond_to?(:namespace) # cap2 differentiator

# Uncomment if you are using Rails' asset pipeline
# load 'deploy/assets'

Dir['vendor/gems/*/recipes/*.rb','vendor/plugins/*/recipes/*.rb'].each { |plugin| load(plugin) }

load 'config/deploy' # remove this line to skip loading any of the default tasks

And the deploy.rb contents:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
set :use_sudo, false

# RVM
$:.unshift(File.expand_path('./lib', ENV['rvm_path']))
require "rvm/capistrano"
set :rvm_ruby_string, '1.9.3'

# bundle install
require "bundler/capistrano"

set :application, "yourappname"
set :repository,  "https://yourdeployuser@bitbucket.org/matheustardivo/yourappname.git"
set :user,        "yourusername"
set :password,    "yourpassword"
set :deploy_to,   "/opt/deploy/yourappname"
set :scm,         :git
set :scm_verbose, true

default_run_options[:pty] = true

# http and https proxy
default_environment['http_proxy'] = 'proxy.dev.infra:3128'
default_environment['https_proxy'] = 'proxy.dev.infra:3128'

# bypass git ssl certificate verification
default_environment['GIT_SSL_NO_VERIFY'] = 'true'

role :web, "prov-dev-1.dev.infra"
role :app, "prov-dev-1.dev.infra"
role :db,  "prov-dev-1.dev.infra", :primary => true

pid_file = "/opt/deploy/yourappname/shared/pids/unicorn.pid"
start_command = "unicorn_rails -D -E development -c /opt/deploy/yourappname/current/config/deploy/unicorn.rb"
stop_command = "kill -s QUIT `cat #{pid_file}`"
stop_condition = "if [[ -f #{pid_file} ]]; then #{stop_command}; fi"

namespace :deploy do
  task :start do
    run start_command
  end

  task :stop do
    run stop_condition
  end

  task :restart do
    run stop_condition
    sleep 2
    run start_command
  end
end

And finally, here is my unicorn.rb configuration file:

1
2
3
4
5
6
7
worker_processes 2
working_directory "/opt/deploy/yourappname/current"
listen "/opt/deploy/yourappname/shared/yourappname.socket", :backlog => 64
timeout 300
pid "/opt/deploy/yourappname/shared/pids/unicorn.pid"
stderr_path "/opt/deploy/yourappname/shared/log/unicorn.log"
stdout_path "/opt/deploy/yourappname/shared/log/unicorn.log"

About Unicorn:

Unicorn is an HTTP server for Rack applications designed to only serve fast clients on low-latency, high-bandwidth connections and take advantage of features in Unix/Unix-like kernels. Slow clients should only be served by placing a reverse proxy capable of fully buffering both the the request and response in between Unicorn and slow clients.

Now that we have our configuration done, just run cap deploy:setup and then cap deploy. You will see a lot of information and at the end, your application will be deployed to your development environment.

Other files that I use to deploy is the nginx configuration file and the nginx application configuration file. Here is the nginx.conf

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
user  nginx;
worker_processes  10;
worker_rlimit_nofile 100000;

error_log   /var/log/nginx/error.log;
pid        /var/run/nginx.pid;

events {
    worker_connections  1024;
    use epoll;
}

http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile        on;
    tcp_nopush      on;
    tcp_nodelay     on;
    server_tokens   off;
    gzip            on;
    gzip_static     on;
    gzip_comp_level 5;
    gzip_min_length 1024;
    keepalive_timeout  65;
    limit_zone   myzone  $binary_remote_addr  10m;

    # Load config files from the /etc/nginx/conf.d directory
    include /etc/nginx/conf.d/*.conf;

    server {
        limit_conn   myzone  10;
        listen       80;
        server_name  _;

        location / {
            root   /usr/share/nginx/html;
            index  index.html index.htm;
        }

        error_page  404              /404.html;
        location = /404.html {
            root   /usr/share/nginx/html;
        }

        error_page   500 502 503 504  /50x.html;

        location = /50x.html {
            root   /usr/share/nginx/html;
        }
    }
}

And the yourappname.conf

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
upstream yourappname {
  server unix:/opt/deploy/yourappname/shared/yourappname.socket fail_timeout=0;
}

server {
  listen 80 default deferred;
  # server_name example.com;
  root /opt/deploy/yourappname/current/public;
  try_files $uri/index.html $uri @yourappname;
  location @yourappname {
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Host $http_host;
    proxy_redirect off;
    proxy_pass http://yourappname;
  }

  error_page 400 404 500 502 503 504 http://errorpage.yourdomain.com.br;
  client_max_body_size 4G;
  keepalive_timeout 10;
}

Then I created symbolic links for each configuration files for nginx:

1
2
$ ln -s /opt/deploy/yourappname/current/config/deploy/nginx.conf /etc/nginx/nginx.conf
$ ln -s /opt/deploy/yourappname/current/config/deploy/yourappname.conf /etc/nginx/conf.d/yourappname.conf

That’s all.

Pull Request Driven Development

Recentemente li um post muito interessante escrito pelo Zach Holman com o seguinte título: How GitHub Works: Be Asynchronous.

Esse é o segundo post de um total de três falando um pouco do modo de trabalho no Github. Segue os links para os outros posts:

A imagem acima não tem nada haver com o assunto desse post, mas não resisti colocar ela aqui. Essa é uma foto do Octobeer, o Kegerator do escritório do Github. Ou seja, enquanto aqui no iG convidamos os colegas de trabalho para tomar um café, lá eles tomam um choppinho – claro ou escuro :)

Bom, voltando ao assunto… Pela primeira vez tenho a oportunidade de trabalhar em um projeto com vários desenvolvedores que usam o Github como repositório de código. Até então usavamos o Mercurial. Apesar da semelhança entre o Git e o Mercurial, tivemos algum trabalho com a utilização do Mercurial que esperamos acabar ou pelo menos reduzir usando o Github.

E é ai que entra uma parte do texto do Holman: tornar o workflow de desenvolvimento assíncrono envolve a utilização de Pull Requests. Segue abaixo uma breve descrição dessa funcionalidade retirada do site do Github:

Pull Requests are living discussions that streamline the process of discussing, reviewing, and managing changes to code.

PRDD na prática

Uau… PRDD… Muito boa essa sigla ein? Já pensou você falando numa entrevista de emprego assim: Já trabalhei num projeto usando Rails, com BDD + TDD e PRDD. Com certeza será contratado na hora :)

Brincadeiras a parte, vamos entender na prática como funciona a utilização de Pull Requests no workflow de desenvolvimento.

Quando você for trabalhar na inclusão de uma nova funcionalidade ou então em algo que traga algum impacto no codebase do projeto, então crie um novo branch para isso. Um exemplo: um desenvolvedor vai trabalhar numa funcionalidade de streaming para o projeto resque-pastie (esse projeto é uma só uma brincadeira que fiz aqui para testar o Resque com Rails). Então vamos criar o novo branch streaming e já mudar para ele com o seguinte comando:

1
git checkout -b streaming

E faça o push desse branch para o repositório remoto:

1
git push github streaming

Quando terminar a codificação da funcionalidade, crie um Pull Request para esse branch: Acesse o repositório no Github e mude o branch de master para streaming e depois clique no botão Pull Request que fica a direita da tela. Veja a figura abaixo:

Revise o seu Pull Request e coloque os comentários necessários. Lembrando que o texto desse comentário será parseado pelo Github Flavored Markdown. Então você pode formatar o texto, incluir imagens, blocos de código e tudo mais que o parser do GFM suportar. Agora basta clicar no botão Send pull request para criá-lo.

O workflow agora está no ponto onde os demais desenvolvedores do projeto fazem a revisão do Pull Request criado. Você ainda pode fazer um deploy parcial desse branch em um ambiente de QA ou até mesmo em algumas máquinas de produção para testar o que foi feito, verificar se tudo está ok e então fazer o merge para o master. Segue uma imagem da tela de revisão do Pull Request:

Veja que neste caso, como a alteração realizada no código foi bem simples, o Github exibe um botão para fazer o merge automático do código.

Mesmo depois de criado o Pull Request, você e os outros desenvolvedores ainda podem fazer alterações e incluir outros commits nesse mesmo Pull Request. Basta fazer o push desses commit no mesmo branch, neste caso o branch streaming. Veja na figura abaixo que um outro commit foi incluído no mesmo Pull Request:

Agora vamos fazer o merge automático desse pull request. Para isso é só clicar em Merge pull request e depois em Confirm merge. Veja que o Pull Request foi fechado e as alterações feitas naquele branch agora estão no master.

Você também pode fazer o merge desse Pull Request manualmente pelo terminal. Para isso criei um outro branch com o nome de manual, fiz o commit do código alterado, o push desse branch para o repositório e criei um novo Pull Request.

Agora vamos fazer o merge:

O primeiro passo é mudar para o branch master:

1
2
$ git checkout master
Switched to branch 'master'

Não se esqueça de fazer o pull para obter as últimas alterações:

1
2
3
4
5
6
7
$ git pull github master
From github.com:matheustardivo/resque-pastie
 * branch            master     -> FETCH_HEAD
Updating d33046c..e63d721
Fast-forward
 README.md |    4 ++++
 1 files changed, 4 insertions(+), 0 deletions(-)

Agora faça o fetch do branch que originou o Pull Request:

1
2
3
$ git fetch github manual
From github.com:matheustardivo/resque-pastie
 * branch            manual     -> FETCH_HEAD

Faça o merge do brach:

1
2
3
4
$ git merge manual
Merge made by recursive.
 README.md |    2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)

E finalmente o push para o master:

1
2
3
4
5
6
$ git push github master
Counting objects: 1, done.
Writing objects: 100% (1/1), 227 bytes, done.
Total 1 (delta 0), reused 0 (delta 0)
To git@github.com:matheustardivo/resque-pastie.git
  e63d721..e2ad64a  master -> master

Entre no Github e você verá que o código do branch manual foi incorporado no master e o Pull Request foi fechado.

Bom, a ideia é essa. No decorrer da utilização do PRDD no nosso dia-a-dia com certeza irão surgir alguns problemas e talvez outras maneiras de lidar com o workflow de desenvolvimento, mas é importante ver o que ganhamos usando os Pull Requests: comunicação assíncrona, revisão do código por outros desenvolvedores, organização do repositório por funcionalidades desenvolvidas, possibilidade de testar tais funcionalidades isoladamente de forma simples e etc.

Não deixe de ler a documentação do Github sobre Pull Requests:

Endereço Novo, De Novo

Pois é… Mais uma mudança de endereço. Se alguém ainda lê esse blog deve estar se perguntando: “Por que esse cara não para quieto ein?”

Pra responder essa pergunta, vamos fazer uma retrospectiva das minhas indas e vindas em meus blogs.

No ano de 2006 eu ainda era um participante assíduo do fórum do GUJ e via que uma boa parte dos participantes do fórum também escreviam coisas interessantes em seus blogs. Bom, eu também quero um :)

Grande partes desses blogs estavam no wordpress.com, então foi assim que eu criei o meu primeiro blog.

A princípio o wordpress me atendia perfeitamente e não via necessidade nenhuma de ter meu próprio domínio. Mas um tempo depois percebi que grande parte desses caras que tinham um blog agora tinham também um domínio.

Então pensei:

Bom, tudo bem vai. Não vamos fazer tanto drama. Eu não preciso de um domínio…

Mas agora que estou fazendo uns projetinhos com Ruby on Rails, eu podia aproveitar pra comprar um domínio e um host que suporte Rails.

E olha só… Tem aqui um serviço de hospedagem baratinho que suporta Rails e também PHP. Posso colocar meus projetinhos e também usar o Wordpress.

Brilhante! Vou comprar.

E foi assim que em 2009 comprei o domínio Tardivo.org

Matheus Tardivo.org

Agora sim estou na moda de novo. Tenho meu blog, meu domínio e posso hospedar meus projetinhos pessoais.

Continuei postando coisas novas durante um tempo, geralmente assuntos relacionados com métodos ágeis de desenvolvimento de software porque era onde eu concentrava meus estudos naquele momento.

Foi então que eu mudei de emprego, mudei de cidade e com isso veio uma grande carga de trabalho e viagens que antes eu não tinha. Resultado: em 2 anos foram apenas 2 novos posts. E o pior é que eu fiquei pagando a hospedagem e o domínio (pouco… mas pagando).

E finalmente, a mudança pra cá

Com o surgimento do Heroku a necessidade de ficar pagando a hospedagem para hospedar meus projetinhos pessoais se foi (aliás, desde o dia 25 de agosto o Heroku está oficialmente suportando Java).

Fazer o deploy de uma aplicação em Rails ou Sinatra no Heroku é tão simples e prático que acabei esquecendo do meu host pessoal e passei a utilizar apenas o Heroku.

Mas e o blog? Simples: poderia voltar para o Wordpress ou então usar qualquer outro serviço das dezenas disponíveis. Foi ai que li muita gente abandonando o Wordpress por N motivos diferentes e passando a usar uma engine simples de geração de conteúdo estático, o Jekyll.

Pra entender melhor o que é o Jekyll, vou colocar aqui a descrição feita pelo próprio autor:

Jekyll is a simple, blog aware, static site generator. It takes a template directory (representing the raw form of a website), runs it through Textile or Markdown and Liquid converters, and spits out a complete, static website suitable for serving with Apache or your favorite web server. This is also the engine behind GitHub Pages, which you can use to host your project’s page or blog right here from GitHub.

E o mais legal de tudo: feito em Ruby :)

Outro detalhe: o autor do Jekyll é o Tom Preston-Werner, Cofounder do GitHub.

Foi então que resolvi fazer um teste utilizando o Jekyll e hospedar o blog no GitHub Pages. O processo todo foi muito simples e pra incluir um novo post basta escrever o texto no seu editor preferido (no meu caso o TextMate), git commit e git push. Pronto! Muito mais nerd que o Wordpress… com certeza.

A única coisa que não curti muito no Jekyll foi o fato dele não ter um layout padrão mais legal. E não é que já tinham pensado nisso?

Octopress

Mais uma vez, segue a descrição do autor (do Octopress, duh):

Octopress is a framework designed by Brandon Mathis for Jekyll, the blog aware static site generator powering Github Pages. To start blogging with Jekyll, you have to write your own HTML templates, CSS, Javascripts and set up your configuration. But with Octopress All of that is already taken care of. Simply clone or fork Octopress, install dependencies and the theme, and you’re set.

Ou seja, usar o Jekyll já com um tema bem legal IMHO e também com diversos outros enhancements. Para mais detalhes, veja a documentação.

Então só faltava importar os meus posts antigos do Wordpress pro Octopress e subir pro github. Obviamente que alguém já tinha feito isso. Encontrei esse post: Migrated To Octopress do Martin Elwin onde ele descreve como fez a migração e o script que ele usou pra importar seus posts.

Vou aproveitar pra colocar aqui também o gist que ele disponibilizou com o script de importação.

Agora já posso parar de pagar a toa o domínio e a hospedagem (na verdade já parei… assim que terminar o período que paguei, já era).

Muito bem. É isso… Depois desse trabalho todo é só voltar a escrever alguns posts de vez em quando.

[update] Pra manter um padrão, já que quase todos os meus contatos são matheustardivo (email, twitter, facebook, linkedin) resolvi manter um domínio matheustardivo.com [/update]

Movendo Um Branch Para O Master No Github

Quando eu começei a estudar Rails resolvi fazer um projetinho para botar em prática o que eu estava estudando. Pensei num projeto que também me ajudasse de alguma forma, e naquele momento, um grande problema que eu tinha era meu controle financeiro – veja bem, problemas financeiros eu ainda tenho e acho que sempre vou ter, mas estou falando apenas de controle :D

Na época a grande maioria dos livros só falavam sobre a versão 2 do Rails e por isso iniciei meu projeto nessa versão – no meu último post tem as fontes de estudo que usei.

Logo percebi que eu estava investindo muito tempo estudando uma versão antiga do Rails e resolvi passar a estudar a versão 3. Por consequência, eu tive que fazer uma mudança razoável na estrutura do meu projeto. Como a mudança foi grande pensei que fazer o merge desse código no master do repositório do github seria muito complicado, então resolvi criar um branch para a versão nova e trabalhar nele.

A questão é que esse novo branch acabou virando o principal e achei que a coisa ficou meio desorganizada. Solução: mover o branch para o master e renomear o branch para “rails2”. Cheguei até a cadastrar um issue para isso no github e ele ficou lá por muito tempo, até que hoje resolvi acertar esse problema.

Encontrei uma referência que me ajudou bastante a fazer essa mudança, mas no meu caso tive que fazer algumas pequenas alterações:

  1. No seu repositório do github, clicar em Admin e mudar o branch default para o branch de desenvolvimento.
  2. Renomear os branches locais (executar os comandos abaixo na sua cópia local sem clonar seu repositório depois da alteração do branch default):
    1
    2
    
    git branch -m master rails2
    git branch -m v1.1.0.rails3 master
    
    Onde: rails2 é o novo branch para manter o código antigo e v1.1.0.rails3 é o branch de desenvolvimento atual
  3. Ao invés de remover o master remoto, fiz o push forçado do código atual:
    1
    
    git push -f origin master
    
  4. Mudar novamente o repositório default no github para o master e depois apagar o branch antigo:
    1
    
    git branch origin :v1.1.0.rails3
    

E pronto! Agora o repositório ficou organizado da seguinte forma:

  • master: Código de desenvolvimento com o Rails na versão 3
  • rails2: Código da versão inicial utilizando Rails 2

E o branch v1.1.0.rails3 que era o de desenvolvimento se foi :D

Espero que isso seja útil pra quem também fez cagada confusão com seu repositório ou esteja tentando renomear um branch.

Ruby Inside Brasil

Ruby Inside é a mais popular fonte de noticias sobre Ruby e Rails do mundo. Abrange todas as tecnologias associadas ao Ruby (incluindo Ruby on Rails, Merb, IronRuby, JRuby, Rubinius e outros) e assuntos relacionados à comunidade Ruby em geral. Publica as últimas noticias sobre a linguagem de programação Ruby, dicas e compilações de recursos e referencias sobre a linguagem.

Texto retirado do link “Sobre Nós” do site do Ruby Inside Brasil.

Mas algumas pessoas devem estar se perguntando: -Que negócio é esse de Ruby on Rails? -Você nunca falou sobre isso aqui nesse blog e agora me vem postando sobre uma fonte de notícias desse tal de Ruby e Rails.

Pra quem me conhece sabe que estou estudando bastante sobre Ruby e Rails e sabe também que estou tentando divulgar esse assunto. Pois bem, acho que essa é uma ótima oportunidade de começar. :D

Então, pra quem nunca ouviu falar sobre esse tal de Ruby on Rails, segue uma pequena descrição:

O que é o Rails?

O Rails é um framework de desenvolvimento web escrito na linguagem Ruby. Ele é designado para tornar a programação de aplicações web mais fácil, fazendo várias suposições sobre o que cada desenvolvedor precisa para começar. Ele permite que você escreva menos código enquanto faz mais que muitas outras linguagens e frameworks. Desenvolvedores Rails mais experientes também dizem que ele torna o desenvolvimento de aplicações web mais divertido.

O Rails é um software com opinião. Isto é, ele supõe que existe um modo melhor para fazer as coisas, e ele é desenhado para encorajar este modo – e em alguns casos desencorajando alternativas. Se você aprender “O Modo Rails” vai provavelmente descobrir um aumento tremendo de produtividade. Se persistir em trazer velhos hábitos das outras linguages para o desenvolvimento Rails, tentando usar padrões que aprendeu em outros lugares, você pode ter uma experiência menos divertida.

A filosifia Rails inclui diversos princípios guia:

  • DRY - “Don’t Repeat Yourself” - sugere que escrever o mesmo código várias vezes é uma coisa ruim.
  • Convenção ao invés de Configuração - significa que o Rails faz suposições sobre o que você quer fazer e como você estará fazendo isto, em vez de deixá-lo mudar cada minúscula coisa através de intermináveis arquivos de configuração.
  • REST é o melhor modelo para aplicações web - organizar sua aplicação em torno de recursos e verbos HTTP padrão é o modo mais rápido para proceder.

Texto retirado do Rails Guides, traduzido para português.

Quem se interessou pelo assunto e quer aprender mais sobre Ruby e Rails vou colocar algumas fontes que estou usando nos meus estudos:

Outra alternativa pra quem quer aprender Ruby e Rails e não tem tempo nem disciplina pra estudar sozinho, são os workshops mão na massa Ruby e Rails Tempo Real. Segue link para notícia do Ruby Inside Brasil que está divulgando os workshops.

E, claro, para quem ajudar a divulgar o Ruby Inside Brasil, conforme escrito no post acima, também estará concorrendo a inscrições para os workshops.

Pois é. Eu já estou concorrendo! :D

Novo Endereço

Depois de muito tempo sem postar, resolvi retomar as atividades, mas agora em um novo endereço.

Não se esqueçam de atualizar os seus feeds.

Obrigado a todos pela audiência :)

O Mercado Esta Mudando Ou é Impressão Minha?

[edit] O Vinícius Teles acabou de postar no blog dele o mesmo texto. Tirando a minha introdução – e incluindo a dele, o conteúdo é o mesmo. Segue o link para o post: O mercado está mudando? [/edit]

O título desse post é o assunto de um email, enviado para a lista Scrum-Brasil, que gerou uma discussão bem interessante.

Pra quem, assim como eu, tem interesse em métodos ágeis de desenvolvimento de software, o texto abaixo serve para mostrar o quanto é complicado conseguir mudar a cultura das empresas que utilizam métodos ultrapassados tradicionais.

Continuo acreditando e defendendo a idéia que Scrum, XP, (coloque aqui sua métodologia ágil preferida), dão uma visão muito mais realista para o desenvolvimento de software, afinal, desenvolver software é essencialmente diferente de construir prédios. Infelizmente, comparar o desenvolvimento de software com a construção civil ainda é a análogia mais usada – tanto na prática quanto no meio acadêmico.

O texto abaixo foi escrito pelo Vinícius Teles que é uma das pessoas com mais experiência no assunto “ágil” no Brasil. Pra quem já leu algum post desse blog já deve ter lido sobre ele.

É um texto extenso, mas de leitura obrigatória pra quem tem interesse por metodologias ágeis e quer ter uma idéia realista do que terá que enfrentar na maioria das empresas brasileiras.

“Minha resposta curta para a sua pergunta é: sim, o mercado está mudando. Ele está sempre mudando. :–) Mas, talvez não tanto assim quanto gostaríamos e, possivelmente, não na direção que desejamos. Uma das mudanças mais perceptíveis é que cada vez mais gente tem ouvido falar de desenvolvimento ágil. Mas, isso não quer dizer necessariamente que cada vez mais gente esteja adotando métodos ágeis. Certamente, cada vez mais gente DIZ estar usando métodos ágeis. Mas, a distância entre o DIZER e o FAZER é imensa, sobretudo nesta área. Acredito que, daqui por diante, veremos cada vez mais gente falando sobre desenvolvimento ágil, mas continuaremos a ver poucos usando. Há algumas razões fundamentais para isso.

Desenvolvimento ágil não tem a ver com Scrum, XP, FDD, Lean ou seja lá qual for o nome. Tem a ver, acima de tudo, com a maneira como encaramos desenvolvimento de software. Tem a ver com a compreensão da verdadeira NATUREZA do desenvolvimento de software. Os anos passam, mas a maioria absoluta das pessoas não consegue se livrar da idéia de que desenvolver software seja igual a construir prédio. As conseqüências desta dissonância cognitiva são infinitamente mais sérias do que a maioria de nós gostaria de acreditar. Escrevi exaustivamente sobre isso na minha dissertação (http://www.improveit.com.br/xp/dissertacaoXP.pdf, cápitulos 3 e 4), então, não vou me estender aqui. Apenas resumirei porque isso é tão prejudicial.

O que uma empresa produz é resultado de como ela está estruturada. Quem tem autoridade para dizer como deve ser a estrutura de uma empresa é quem está no topo. Então, a estrutura de qualquer é empresa é, no fim das contas, o resultado do modo de pensar, da mentalidade, de quem está no comando. A mentalidade da maioria dos empresários, diretores e gerentes no mundo inteiro é, com raríssimas exceções, arcaica e incompatível com o trabalho de desenvolver software. Quando o topo da empresa não entende o tipo de mentalidade necessária para se desenvolver software de forma bem sucedida, não há santo que possa fazer milagre. E eu garanto, a maioria absoluta das pessoas que estão no comando das empresas não entende uma vírgula do que significa desenvolver software. Isso inclui, certamente, a maioria absoluta dos CIOs. Não é à toa que eles buscam recorrentemente coisas como CMMI, PMBOK, MPS.BR, ITIL etc, todos absolutamente incompatíveis com a NATUREZA do desenvolvimento de software. A mentalidade por trás destas aberrações é inútil, quando o assunto é software, mas casa perfeitamente com a mentalidade da maioria dos gestores. E não pára por aí. Nas universidades, a situação é igual ou pior.

Veja o caso da UFRJ, por exemplo. Neste semestre, o professor de engenharia de software, percebendo a crescente movimentação em torno de métodos ágeis, resolveu gastar boa parte do seu tempo para mostrar aos alunos que métodos como o XP não funcionam. Afinal, se fôssemos fazer um prédio com XP, aconteceria mil e uma coisas horrendas. Nisso ele está certo. O problema, como sempre, é a maldita distinção entre construir prédio e desenvolver software, a qual, seria óbvia para uma criança, mas é impossível de ser percebida por um Ph.D(eus). Olha que loucura, em uma universidade do quilate da UFRJ, o cidadão, só porque é Ph.D.(eus), não precisa se dar ao trabalho de estudar sobre métodos ágeis, nem muito menos usá-lo, para já saber, desde criancinha, que não pode dar certo. E claro, um conhecimento destes, tão valioso, não pode ser mantido só para ele. Também é preciso passar adiante para os alunos, como se fosse necessário. Afinal, eles já estão todos estagiando em empresas entupidas de documentos e péssimas práticas de desenvolvimento até o último fio de cabelo.

Sempre fui muito otimista, em tudo. Mas, em se tratando de desenvolvimento ágil, acho que meu otimismo se foi. Foram precisos seis anos para isso acontecer, devo dizer, mas se foi. E a razão está lá em cima, no topo das empresas, no topo das universidades. Está lá onde a mediocridade e a incompetência imperam, ao menos em se tratando de desenvolvimento de software e gestão de pessoas. Percebi, com o tempo, que podemos fazer diferença na base, sim, mas é muito pequena e, freqüentemente efêmera.

Fiquei tempo suficiente nesta área para ver equipes adotarem XP, funcionarem super bem durante algum tempo e, mais a frente, serem impedidas de continuar porque a organização passa minar o andamento do grupo. É como um corpo estranho, que é expelido naturalmente pelas nossas células. Só para dar um exemplo. Em 2003, nós fizemos um projeto XP para a Vale do Rio Doce. Foi um projeto lindo, com tudo que se tinha direito. Até contrato de escopo negociável. As áreas de negócio amaram tudo o que foi feito. Adoravam os desenvolvedores. Depois que o sistema foi colocado no ar, foram encontrados apenas 3 bugs durante os seis meses seguintes. Isso é nada em um projeto de mais de um ano, com mais de dez pessoas envolvidas. O projeto foi um sucesso em praticamente todos os quesitos que se pudesse imaginar. Mas, aí é que estava o problema. A última coisa que alguém quer é um projeto de sucesso! Afinal, como ficam os demais? Quando o projeto acabou, tudo foi feito dentro da Vale para que nunca mais isso se repetisse. Acredite, não foi a única vez que vi isso acontecer. Em seis anos, eu vi muita coisa começar bem e, mais a frente, acabar. Por que?

Porque desenvolver software com a mentalidade ágil não é compatível com a mentalidade de quem manda. Isso é mais do que suficiente para limitar as mudanças na área de software. Acredito que vai levar muito tempo para que as empresas passem a ter gestores que compreendam não apenas o que é fazer software. Mas, o que é fazer um trabalho do conhecimento. A maioria absoluta dos gestores tratam seus funcionários como se fossem crianças. Fica parecendo que os piores imbecis são justamente os que mais freqüentemente são escolhidos para comandar as empresas. Não parece apenas, isso realmente acontece e dói ver o quanto isso é comum. Enquanto estes estiverem lá em cima, vamos ouvir falar muito sobre desenvolvimento ágil. Mas é só. Aliás, não é não. Tem coisa pior. Vamos ver pessoas fazendo barbaridades e dizendo que estão usando desenvolvimento ágil.

Para quem ainda estiver no ramo de consultoria, isso não é necessariamente ruim. Essa área vai bombar. Vamos ter cada vez mais espaço para cursos e consultoria em desenvolvimento ágil. O interesse só vai crescer daqui por diante. Não necessariamente pelos méritos, mas porque alguém ouviu dizer que agora o grande lance é fazer software com a ___________ (preencha com a metodologia ágil preferida).

O problema dos gestores não afeta apenas o desenvolvimento de software. Ele é muito mais sério e muito mais abrangente que isso. Entre em qualquer empresa grande e o que você verá é um bando de trabalhadores do conhecimento sendo tratados como pedreiros por um bando de incompetentes que não conseguem fazer nada melhor que jogar tempo e dinheiro na lata de lixo. O nível de desperdício de talento, tempo, dinheiro, oportunidades etc é tão colossal que eu realmente não consigo compreender como alguém consegue trabalhar em uma empresa grande atualmente. Claro, existem exceções. Pouquíssimas, mas existem. São apenas isso, exceções.

Desejo muita sorte e sucesso para quem continua lutando para mudar este panorama. Não tenho dúvidas de que as coisas irão melhorar ao longo do tempo. Mas, acho bastante improvável que uma mudança significativa aconteça no curto ou médio prazo. Enquanto as pessoas chegarem no topo das empresas com a mentalidade que temos hoje em dia, enquanto os professores universitários continuarem ensinando lixo, enquanto as empresas continuarem a ganhar dinheiro apesar das práticas de administração arcaicas que utilizam, enquanto nós aceitarmos trabalhar para estes idiotas, vai ser complicado.

Desculpa pelo pessimismo. Não foi sempre assim. Foram necessários seis anos, seis turmas de XP na UFRJ, literalmente centenas de apresentações de XP em todo o Brasil, um mestrado, não sei quantos cursos, vários mentorings, alguns projetos de desenvolvimento XP, algumas conferências no exterior, um livro e mais um monte de coisas que eu não lembro, para me dobrar. E antes que alguém pense que o problema era o XP e que tudo poderia ser diferente se tivesse sido Scrum, FDD, Lean etc, não se enganem. O buraco é mais embaixo. Se você conseguiu chegar até aqui e prestou atenção ao que estou dizendo, tudo se resume a uma coisa: mudar é difícil? É. Mas, ainda é a parte fácil. O difícil mesmo é mudar de vez.

O Kent Beck tem um exemplo ótimo. Segundo ele, parar de fumar é fácil. Tanto que tem gente que já parou várias vezes. :–) O problema é parar e nunca mais voltar a fumar. É a mesma coisa. Um monte de gente vai conseguir mudar para desenvolvimento ágil. Poucos conseguirão sustentar esta mudança. E eu adoraria estar falando isso de orelhada. Mas, é que eu vi as pessoas voltarem a fumar um número suficiente de vezes para saber que é ótimo ver mais movimentação atualmente sobre desenvolvimento ágil. Mas, acredito que seja ingênuo achar que isso implique em uma mudança significativa. Muitos tentarão e a maioria vai voltar às práticas antigas, simplesmente porque todos os incentivos nas empresas giram em torno delas e isso continuará assim por muito tempo.

Apesar de tudo o que disse, torço, profundamente, para estar absolutamente equivocado! No mais, redobrem seus esforços! O desafio é bem maior do que parece à primeira vista.

Pra quem quiser ler a discussão na íntegra, segue o link: http://br.groups.yahoo.com/group/scrum-brasil/message/656 E pra quem quiser se inscrever na lista de discussão Scrum-Brasil, segue o link: http://br.groups.yahoo.com/group/scrum-brasil

Fábricas De… Software?

É impressionante ver que em pleno ano de 2008 existem pessoas que ainda acreditam em fábricas de software. Geralmente, estas pessoas tendem a permanecer alheias as novas metodologias – sei que o termo “novas” foi um pouco forte, afinal, pra ter uma idéia, o artigo “The New Methodology” de Martin Fowler foi escrito no ano de 2000.

Fábricas de software sugerem que os desenvolvedores são apenas recursos que executam tarefas manuais, determinísticas e altamente especializadas. Isso funciona bem para carros, sapatos, mas não para software. A explicação para isso pode se tornar extensa e gera várias discussões, mas, no meu ponto de vista, é algo simples de entender: desenvolver software é essencialmente um trabalho de criação, que se assemelha mais a pintar um quadro ou escrever um livro.

Tentar tornar o trabalho de desenvolvimento de software altamente especializado e determinístico NÃO FUNCIONA!

A especialização é uma teoria que surgiu na revolução industrial e funciona muito bem para o trabalho manual. Nela cada recurso executa uma pequena parte de um trabalho, muito especifico – como apertar parafusos. Neste caso, o recurso pode ser facilmente substituído. No desenvolvimento de software o trabalho é essencialmente um processo de criação, uma arte. Por isso, essa teoria não encaixa.

A forma de especialização mais conhecida na área de desenvolvimento é a separação entre analista e programador. O analista é responsável por estudar os requisitos do sistema e gerar artefatos que transmitam a idéia para o programador – estes artefatos geralmente são diagramas UML (diagramas de classes, diagramas de seqüência, diagramas de iteração) e casos de uso. Em posse desses artefatos, o programador apenas “transforma” tudo isso em código. Simples não? Parece ser. Mas então por que isso não funciona? Aliás, acabei de ler mais um ótimo post do Phillip Calçado sobre este assunto: Quando eu crescer quero ser Analista de Sistemas.

O processo de criação de um software exige que a análise e o desenvolvimento andem o tempo todo juntos e sejam feitos de maneira incremental. A análise é feita a medida que o desenvolvimento evoluí. Algo que foi analisado hoje, pode não ser mais válido daqui uma semana – ou até mesmo num tempo menor.

Para entender como funciona o processo de desenvolvimento incremental, ou melhor, iterativo, precisamos antes nos lembras dos velhos tempos: o estilo cascata.

“O estilo em cascata subdivide um projeto com base na atividades. Para construir software, você precisa realizar certas atividades: análise dos requisitos, projeto, codificação e teste. Assim, nosso projeto de um ano poderia ter uma fase de análise de dois meses, seguida de uma fase de projeto de quatro meses, após a qual viria uma fase de codificação de três meses, seguida de uma fase de teste de mais três meses. No desenvolvimento em cascata, normalmente existe alguma espécie de transferência formal entre cada fase, mas freqüentemente existem refluxos. Durante a codificação, pode surgir algo que o faça rever a análise e o projeto. Você certamente não deve supor que todo o projeto esteja concluído, quando a codificação começa. É inevitável que as decisões de análise e projeto tenham de ser revistas nas fases posteriores. Entretanto, esses refluxos são exceções e devem ser minimizados o máximo possível.”

Essa definição sobre o estilo em cascata foi tirada do livro UML Distilled: A Brief Guide to the Standard Object Modeling Language de Martin Fowler. Então, nada mais justo que expor a definição sobre o estilo iterativo deste mesmo livro:

“O estilo iterativo subdivide um projeto em subconjuntos de funcionalidades. Você poderia pegar um ano e dividi-lo em iterações de três meses. Na primeira iteração, você pegaria um quarto dos requisitos e faria o ciclo de vida do software completo para esse quarto: análise, projeto, código e teste. No final da primeira iteração você teria um sistema que faria um quarto da funcionalidade necessária. Então, você faria uma segunda iteração tal que, no final de seis meses, tivesse um sistema que fizesse metade da funcionalidade. É claro que o exposto é uma descrição simplificada, mas é a essência da diferença. Na prática, evidentemente, vazam algumas impurezas no processo. No estilo iterativo, você normalmente vê alguma forma de atividade exploratória, antes que as iterações reais comecem. No mínimo, isso fornecerá uma visão de alto nível dos requisitos: pelo menos o suficiente para subdividi-los nas iterações que se seguirão. Algumas decisões de projeto de alto nível também podem ocorrer durante a exploração. Por outro lado, embora cada iteração deva gerar software integrado pronto para produção, freqüentemente ela não chega a esse ponto e precisa de um período de estabilização para eliminar os últimos erros. Além disso, algumas atividades, como o treinamento dos usuários, são deixadas para o final. Você pode não colocar o sistema em produção ao final de cada iteração, mas eles devem ter qualidade de produção. Freqüentemente, entretanto, você pode colocar o sistema em produção em intervalos regulares; isso é bom, porque você avalia o sistema antecipadamente e obtém um retorno de melhor qualidade. Nessa situação, muitas vezes você ouve falar de um projeto com múltiplas versões, cada uma das quais subdivididas em várias iterações.”

Parando e refletindo sobre o assunto é interessante observar que muita coisa exposta neste texto e nos links abaixo não são exatamente grandes novidades. Essa é a realidade do desenvolvimento de software. Quem não entende isso ou não quer entender está completamente fora dessa realidade e deveria rever seus conceitos.

Alguns links sobre o assunto:

Improve It Fecha as Portas Para Consultorias Em Metodologias Ágeis

Uma notícia preocupante – pelo menos pra mim, que estava realmente acreditando no sucesso dessa empresa por causa dos trabalhos com desenvolvimento ágil. Mas que também serve para mostrar as inúmeras dificuldades que esse tipo de metodologia (ou filosofia de trabalho) enfrenta no nosso país. Ou não será só aqui?

Alguns pontos que eu gostaria de salientar: recentemente passei a estudar e defender as práticas de metodologias ágeis, principalmente o XP. Na equipe que trabalho, como todos também tem interesse em metodologias ágeis, decidimos aplicar práticas do XP no nosso dia-a-dia. Tentamos aplicar o que está ao nosso alcance: programação em par, refactoring, desenvolvimento guiados pelos testes, código coletivo, padrões de codificação, iterações e releases curtos, entre outras. Como a metodologia oficial adotada pela empresa não é XP (dizem que é RUP, mas na verdade é puro Waterfall) temos que procurar oportunidades para utilizar as práticas do XP, e posso dizer que estamos conseguindo. Ficamos satisfeitos (pelo menos eu estou) com os resultados que estamos obtendo com isso.

Mas, quando falamos de metodologias ágeis, existem alguns pontos críticos. Segue abaixo um trecho do texto publicado pelo Vinícius (desenvolvedor de software e fundador da Improve It) falando sobre isso:

“À medida que este ano termina, algumas coisas ficam claras para mim. Primeiro, é preciso admitir que comercialmente XP é muito ruim. Há uma resistência enorme ao seu uso, baseada nas mais diversas interpretações equivocadas. A maioria das pessoas não sabe o que é, mas pelo nome, é melhor nem saber mesmo. Com certeza não é coisa boa. Segundo, não tem certificação, o que é um pecado capital neste país. Terceiro, demanda das pessoas, das equipes, das empresas, um nível de atitude social e comportamental que parece ser avançado demais para o pensamento pequenino que reina nas empresas brasileiras, com raras exceções.”

Pra mim, tudo se resume neste texto: uma boa parte das pessoas que eu converso, mesmo sem realmente entender as propostas do XP, prontamente concluem que é algo ruim. Que não funciona. Quanto a isso, o que fica claro pra mim é que essas pessoas ou pensam que conhecem XP, ou apenas ouviram falar.

Recomendo que todos leiam a notícia na íntegra e tirem as suas conclusões. Fica claro que a atitude que a Improve It tomou não é baseada em problemas ou insucessos causados pelas metodologias ágeis, muito pelo contrário, pois isso deu condições à eles de tomarem esse novo rumo. Apenas mudaram o foco comercial de serviços para produtos – que, com certeza, continuaram a serem desenvolvidos utilizando metodologias ágeis.

Na notícia o Vinícius cita o caso de sucesso da 37signals: “Sem dúvidas esta empresa é, atualmente, nossa principal inspiração.” Pra que não conhece, David Heinemeier Hansson da 37signals é o criador do Ruby on Rails – e diversos outros produtos como o Basecamp.

Mas uma notícia como essa, principalmente com o conteúdo colocado, me deixa um pouco preocupado. Acredito não ser o único a ter essa preocupação pois vi mais pessoas acreditando no modelo de serviços que a Improve It vinha apostando. Segue um trecho de um post do Phillip Calçado num “Momento Mãe Diná 2008”:

“Vai ser o ano das consultorias pequenas. As ImproveIt, TriadWorks e Caelum da vida vão mostrar ao mercado brasileiro o que o internacional já sabe: times pequenos com foco em qualidade são melhores que enormes fábricas de software que simplesmente não conseguem entregar projetos”

Já conhecia a Improve It através dos artigos sobre XP, mas passei a ter admiração através do livro de XP do Vinícius – que virou uma fonte de referência para todos da equipe que trabalho, e pelo movimento para disseminar as técnicas ágeis no Brasil.

Boa sorte e sucesso para o pessoal da Improve It.

Aliás, vale a pena ler o artigo do Danilo Sato sobre essa notícia: Os Valores Ágeis não se Expressam em Palavras, mas em Ações.

O Meu Chefe Tem Um Jatinho. O Seu Também Tem?

Mais uma thread para entrar na história do GUJ. A intenção do tópico era de anunciar o framework Space4J que tem como objetivo “ser um banco de dados simples que vai te permitir trabalhar com Java Collections em memória”.

Acontece que, para dar continuidade a tradição, o assunto do tópico mudou de rumo. Mas, na minha opinião, para um rumo interessante. A essência da discussão gira em torno de: qual é a verdadeira importância de um projeto ter uma suíte de testes? Mais uma vez, na minha opinião, é MUITO importante para qualquer projeto ter uma suíte de testes.

A maioria dos projetos que trabalhei não tinham uma suíte de testes – apesar de eu não me conformar com isso e desenvolver testes para partes isoladas. O que eu não me engano é da importância que eles representam para um projeto. Como já foi falado, boas práticas de orientação a objetos e “programação defensiva” (!) não basta para garantir que algo que estava funcionando, deixe repentinamente de funcionar por alterações que o sistema sofreu.

Vale a pena ler sobre Test-driven development e Behavior driven development. Mas é bom deixar claro que existe uma grande diferença entre fazer Test-Driven Development e testar. “TDD é sobre modelagem de objetos e especificações, não sobre testes (tanto que Behaviour Driven Development está se consolidando como algo mais eficiente que TDD) apesar de que no final você acaba ganhando uma suíte de testes de graça.” (trecho retirado do post do Phillip – veja o final deste post).

Outra coisa que sempre acontece nesse tipo de discussão são as pérolas que surgem. Para justificar a ausência dos testes, as pessoas apelam pra todo tipo de absurdo: “em um mundo capitalizado não há tempo para testes”, “não agrega nada para o cliente”, ou até mesmo uma das maiores pérolas que já vi: “Agora, se me permite, vou voltar ao trabalho, pois o meu chefe, que também gosta do (coloque aqui um framework sem testes) e tem o seu próprio jato particular e não está nem um pouco preocupado com os testes unitários…”

Deixando um pouco o circo de lado, toda essa discussão incentivou mais um ótimo post do Phillip Calçado – que aliás, está de malas prontas para trabalhar na ThoughtWorks. Leiam: Programadores Profissionais Escrevem Testes, Ponto Final.