Gradle - Build feliz

Durante anos utilizamos o Maven para cuidar da automação do processo de build. Essa ferramenta se tornou um padrão de mercado e ajudou inúmeros times. Porém, não podemos negar que ela também tem suas deficiências. A escolha de XML para o descritor de projeto tem seus problemas. Quantas vezes perdemos horas olhando para um XML, só para tentar descobrir como funciona o build? Além disso é difícil adicionar alguma lógica no build. O Maven é construído com a idéia de convention-over-configuration. O que por si só é muito bom. Porém, quando tentamos configurar projetos de maneira diferente do padrão enfrentamos muitos problemas. Isso pode ser bem doloroso.

Se você já enfrentou problemas utilizando o Maven com certeza deve ter se perguntado se não existia uma maneira melhor de se trabalhar. Acreditamos que existe sim, uma forma simples e sustentável de se automatizar builds. Nossa recomendação é a utilização do Gradle.

Por que o Gradle?

Os scripts do Gradle são declarativos, de fácil leitura, e espressivo. Escrever o código em Groovy ao invés de XML, e seguir a filosofia que o Gradle define de build-by-convention reduz significativamente o tamanho de um script e é muito mais legível (figura).

Gradle_img_2

É impressionante vermos que com bem menos código você pode atingir o mesmo objetivo. Com Gradle você não é obrigado a seguir convenções ou regras. No caso de outras ferramentas de build como o Maven, é necessário seguir suas convenções e padrões, Gradle DSL permite total flexibilidade, adaptando estruturas de projetos "não convencionais".

Podemos também notar como o Gradle tem se tornado cada vez mais utilizado em grandes projetos e incorporado por grandes empresas. O Google definiu seu uso como o padrão para o build de projetos Android, é altamente usado por projetos open sources, como os projetos da Pivotal e em projetos de grandes empresas, como o Linkedin, Twitter, Oracle e Netflix. Com tudo isso podemos perceber que aderir ao Gradle acaba sendo uma indicação da própria indústria, como realmente uma ferramenta evolutiva para o build.

Vamos dar uma olhada no que diferencia o Gradle de seus concorrentes: seu conjunto de recursos nativos (figura). Essa imagem mostra muito bem o que o Gradle tem que o diferencia de outras ferramentas existentes no mercado.

Gradle

DSL expressiva e API rica

A chave para utilizar todo o poder do Gradle é conhecer a fundo sua API, nela podemos encontrar todas as classes e entender bem tudo o que o Gradle já nos entrega nativamente para trabalharmos de forma eficiente e rápida. Como toda documentação no mundo Java, ela tem sua pagina HTML para ser acessada a qualquer momento. Segue o link: Gradle Docs.

Gradle é Groovy

Ant e Maven são puro XML, e XML pode ser de primeiro encontro muito simples para escrever e ler, porém, com o tempo pode se tornar muito difícil para dar manutenção e fazer melhorias. Gradle é escrito em Groovy, uma linguagem que utiliza o melhor do Java para ser o mais simples e dinâmica possível, por esse motivo temos uma facilidade muito grande em escrever nosso arquivo de build em forma de script.

Convenções flexíveis

Uma das grandes ideias de Gradle é ser flexível quanto a padrões para seus projetos. Cada projeto Java tem uma convenção básica e o Gradle sabe exatamente onde fica o código fonte e as classes de teste dessa convenção, e como compilar o código, executar testes unitários, gerar o javadoc, e criar uma release do seu código. Essas tarefas são totalmente integrada no ciclo de vida do build. Se você manter a mesma convenção de projetos Maven, ele automaticamente vai saber onde está o código, com isso há um esforço mínimo de configuração de sua parte. Na verdade, o seu build terá somente uma linha.

Gestão de dependências robusta

Gradle fornece uma infraestrutura para gerenciar a forma como é resolvida, recuperada, e armazenada as dependências de um projeto. Uma vez que foram baixadas e colocadas em seu cache local, elas são disponibilizadas para o seu projeto. Um requisito fundamental para os builds é a reprodutibilidade. Você já ouviu alguma vez o seu colega de trabalho dizer: "Mas funciona na minha maquina"? Os builds tem que produzir o mesmo resultado em diferentes ambientes, independente do conteúdo de seu cache local. Gerenciadores de dependência como Ivy e Maven ainda não podem garantir totalmente a reprodutibilidade do build. Por que isso acontece? Sempre que uma dependência é baixada e armazenado no cache local, ela não leva em conta a origem do artefato. Em situações em que o repositório de código é modificado para um projeto sem a alteração da sua versão, a dependência em cache é considerada resolvida, mesmo que o conteúdo do artefato seja ligeiramente diferente. Na pior das hipóteses, isso irá ocasionar uma falha no build que é extremamente difícil de depurar. Outra queixa específica para o Ivy é o fato de que as versões -snapshot, não são atualizadas corretamente no cache local, ainda que alterado no repositório e marcado como mudado. Há muitos mais cenários em que as soluções atuais ficam aquém. Gradle prove sua própria solução de gerenciamento de dependência configurável, confiável e eficiente.

Grandes projetos geralmente consistem de vários módulos para separar suas funcionalidades. No Gradle, cada um dos sub-módulos é considerado um projeto que pode ser dependência ou outro módulo para outros projetos. Além disso, cada subprojeto podem ser executados individualmente. Gradle descobre para você qual subprojeto precisa ser reconstruídos, sem ter que ficar armazenando o artefato do subprojeto no cache local.

Builds escaláveis

Em algumas empresas, os projetos podem conter centenas de módulos em sua estrutura. Construir e testar pequenas mudanças de código pode consumir muito tempo. Você deve saber por experiência pessoal, que a exclusão de qualquer classe, deveria naturalmente chamar uma task de clean no projeto pra apagar seus registros. Muitas vezes, você se enfurece por sua ferramenta de build não fazer essas mudanças de forma automática. O que você precisa é de uma ferramenta que seja inteligente o suficiente para reconstruir as partes do seu software que realmente mudaram. Gradle suporta compilações incrementais. Ele sabe  quais tarefas precisam ser ignoradas, buildadas, ou parcialmente reconstruída. O mesmo conceito se traduz em projetos multi-modulares, chamando os builds parciais. Devido a sua clara definição de dependências entre os submodulos do projeto, Gradle cuida de fazer o build apenas das partes necessárias. Até que enfim não precisamos mais rodar uma target de clean na mão!

Desenvolvedores rodam o build muitas vezes durante o processo de desenvolvimento. Isso significa iniciar o Gradle, carregando todas as suas dependências internas e executando toda a lógica de build. Você vai notar que, geralmente, leva um alguns segundos até que o script realmente comece a ser executado. Para melhorar o desempenho de inicialização, Gradle pode ser executado em modo daemon. Invocações subsequentes do build iram fazer a chamada para o processo do Gradle, que já vai estar rodando em background, assim evitando o custo de executar todo o processo de inicialização quando um build for rodar.

Como resultado, você vai notar que o build irá executar aproximadamente 25% mais rápido.

Fácil de extender

A maioria das empresas tem uma forma diferente de fazer o build, e uma forma diferente de resolver os mesmos problemas. Uma vez que você já passou da fase inicial de criação de seus scripts, você pode querer implementar alguma lógica própria. Gradle não é opinativo sobre a maneira de implementar essa lógica. Em vez disso, ele lhe dá várias opções para você escolher, dependendo do seu caso de uso específico. A maneira mais fácil de implementar lógica personalizada é escrevendo uma task. As tasks podem ser definidas diretamente no script do seu build, sem dificuldade alguma. Se você sentir que sua task está ficando complexa, você pode criar uma classe pra encapsular o código, tornando a estrutura fácil de entender e sustentável. Se você quiser reutilizar o código entre os builds/projetos, plugins são a sua melhor escolha. Representando o mais poderoso mecanismo de extensão do Gradle, plugins lhe dão acesso total a API do Gradle e pode ser escrito, testado e distribuído como qualquer outra parte do software. Escrever um plugin é surpreendentemente fácil.

Integração com outras ferramentas

Não seria ótimo poder integrar o Gradle com sua ferramenta de build atual? Gradle lhe dá essa opção, ele funciona perfeitamente com o Ant, Maven e Ivy.

Se você está vindo de uma ferramenta como o Ant, o Gradle não força você a migrar totalmente o seu build, ao invés, ele permite você importar a lógica do seu script Ant e reutilizar seus targets. O Gradle é 100% compatível com os repositórios Maven e Ivy. Você pode recuperar as dependências e publicar seus próprios artefatos. Gradle prove um conversor para projetos existentes em Maven que pode traduzir o XML em um script Gradle, utilizando o Build Init Plugin.

Orientado pela comunidade e suporte corporativo

Gradle é uma solução totalmente open source com a Apache License 2.0. Depois do seu primeiro Release em Abril de 2008, a comunidade abraçou o projeto e deu andamento ao seu desenvolvimento. O código está no GitHub, algo que foi muito benéfico para o Gradle. Mudanças para o código podem ser feitas via Pull Request e serem revistas pelos Core Commiters. Se você estiver vindo do Maven, você deve saber que os plugins são padrões e alterações feitas são burocráticas, as vezes, podendo parecer como uma JSR(Java Specification Request). No Gradle as alterações e funcionalidades são praticamente lançadas todos os dias.

O Gradle tem a Gradle Inc. como empresa que cuida diretamente da padronização do Gradle e de suas funcionalidades, contratando os principais commiters da comunidade e entregando soluções de build para todo o tipo de empresa com o Gradle.

Build Contínuo

Na versão 2.5, foi lançada uma nova funcionalidade ao Gradle, o continuous build, essa funcionalidade permite iniciar automaticamente um build em resposta a mudanças no código do projeto.

O Gradle não irá terminar o processo de build, em vez disso, vai esperar por arquivos que são processados pelo build mudar. Quando for detectada qualquer alteração, vai voltar a executar a compilação anterior com a mesma seleção de tarefa.

Cereja do bolo: funcionalidades adicionais

Você não odeia ter que instalar a ferramenta de build que você vai utilizar localmente? Gradle Wrapper é a solução pra esses problemas, é uma task do Gradle, onde o Wrapper empacota junto ao projeto o Gradle instalado na sua maquina, sendo assim perfeito pra poder rodar em outras maquinas sem a necessidade de instalação, ou melhor ainda, em ambientes CI onde isso pode ser a melhor solução.

Gradle é também equipado com uma rica interface de linha de comando. Usando as opções da linha de comando, você pode fazer tudo o que você precisar, apresentar o nível de log desejado, orquestrar os testes, apresentar mensagens de ajuda, etc. Até ai nada demais, pois as outras ferramentas possuem isso. Mas, claro, o Gradle tem algumas funcionalidades a mais, como por exemplo, o Gradle utiliza a abreviação de nomenclatura de tasks no padrão camel-cased. Ná pratica, uma task com o nome rodeMinhaIncrivelTask poderia ser chamada da seguinte forma rMIT. Muito bom, não é?

Conclusão

Bom, isso é somente a ponta do Iceberg, uma breve introdução ao conceito do Gradle e suas diferenças com as outras ferramentas de build. Outras ferramentas resolvem a maioria dos problemas, mas são burocráticas e não são escaláveis, Gradle veio para resolver os problemas que não são resolvidos por essas ferramentas e ser elegante, ou seja, é uma evolução para as ferramentas de build, que com toda a certeza atende a todas as necessidades que possam aparecer em um processo de build.

A principal intenção desse artigo, é fomentar a vontade no leitor de aprender sobre o Gradle. Atualmente muitos projetos seguem o conceito de Continuous Delivery, dessa forma sendo necessário o uso de ferramentas que facilitem todo esse processo que necessita ser automatizado.

No mínimo experimente a utilização do Gradle em algum projeto, isso com certeza não irá adicionar nenhuma complexidade ao projeto e a curva de aprendizado será bem curta, será benéfico para o projeto, e pode se tornar uma ótima motivação para o desenvolvedor aprender o Groovy.

Groovy é uma linguagem orientada a objetos desenvolvida para a plataforma Java, utiliza a sintaxe semelhante do Java e integra-se transparentemente com outros códigos e bibliotecas Java. Ou seja, no final das contas aprender o Gradle só vai trazer benefícios e melhores resultados.

Recomendamos a sua adoção.