sexta-feira, 15 de setembro de 2017

Automatização de tarefas com C# e Cake

Você já se pegou fazendo uma tarefa chata e trabalhosa, e tendo que repeti-la diversas vezes? Nossa vida desenvolvendo software está cheia de tarefas assim: copiar arquivos de uma pasta pra outra, rodar analisadores de código, subir um servidor após compilar a aplicação, etc. Toda vez que eu me pego repetindo tarefas eu paro e penso: como eu posso automatizar isso? E minha resposta foi: com o Cake!
Aqui na Lambda3 é quase regra que os projetos tenham scripts de automatização para tarefas repetitivas. Atualmente estou trabalhando em um projeto Xamarin e queria automatizar algumas tarefas, olhei algumas ferramentas com as quais já mexi pra entender se alguma delas me serviria:
Gulp: O Gulp já é muito maduro e tem uma comunidade muito ativa, isso conta muito pra mim, mas eu achei que não fazia sentido utilizar Javascript para automatizar tarefas num projeto puramente C#, em que conhecimento de Javascript não é obrigatório.
psake: O psake é uma ferramenta em que você escreve as tarefas em Powershell, é muito usada em outros projetos aqui na Lambda3 e eu teria grandes chances de encontrar ajuda se tivesse problemas, mas acho a sintaxe do Powershell muito ruim e contra-intuitiva, além disso, por mais que Powershell seja cross platform open source eu preferia algo que já fosse mais maduro no conceito de cross platform, já que é um projeto Xamarin, um pré-requisito meu era que as tarefas fossem facilmente executáveis no Windows e no Mac.

Cake

Pesquisando uma ferramenta que me atendesse, me lembrei de uma que já vi muitos projetos usando: Cake. O nome é um trocadilho delicioso (C# Make), e atende a todos meus pré-requisitos: você escreve as tarefas em C#, é cross platform desde o início, é open source e tem uma comunidade muito ativa. Parece perfeito para um projeto Xamarin.

C#

O código do Cake em si é todo feito em C#, além disso, você também escreve as tarefas em C#. Por exemplo, esse é um exemplo de uma tarefa Cake:
1
2
3
4
5
Task("Default")
  .Does(() =>
{
  Information("Hello World!");
});
Neste caso estamos definindo uma task “Default”, que exibe uma informação no console quando executada. O ponto importante aqui é que o código acima deve ser familiar para quem programa em C#: declaração de métodos, chamadas de funções, lambda expressions. Tudo é apenas o C# que você já conhece!

Cross platform e Open Source

O Cake é cross platform desde sua criação, suportando Windows, Mac e Linux, além disso, todo seu código está no GitHub, aberto para contribuições. O projeto é muito bem mantido, com uma boa cobertura de testes e continuous integration em todos os ambientes.

Simplicidade com Aliases

O Cake suporta “Aliases”, que são métodos prontos para você utilizar na sua Task, ele já vem com aliases para as operações mais comuns. No exemplo de Task que usei acima, eu usei um método Information, esse método faz parte dos aliases de Logging e já está disponível por padrão no Cake. Além de Logging, ele já tem aliases para fazer build de projetos .NET, rodar testes com NUnit, XUnit ou MSTest, restaurar pacotes NuGet, etc. Você pode ver todos os aliases built-in aqui, além desses, o Cake suporta Addins, feitos pela comunidade, que facilitam ainda mais a criação de tasks.

Extensibilidade

Mas e se você precisa de um comando que não foi implementado no Cake e não tem Addin? Simples, você pode criar o seu próprio Alias, que nada mais é que um extension method para o Cake. Você ainda pode distribuí-lo por NuGet para que outras pessoas consigam usá-lo.
Mas não se esqueça, Cake é C#! Isso significa que você pode executar código C# nas suas tasks e fazer o tratamento sem precisar criar aliases. Maravilhoso ♥.
1
2
3
4
5
6
7
8
9
10
11
12
13
Task("Default")
    .Does(() =>
    {
        var directoryInfo = new DirectoryInfo("C:/Repos/MeuApp");
        // com LINQ e tudo!
        var configFiles = directoryInfo.GetFiles("*.config")
                                       .Where(x => !x.IsReadOnly).ToList();
 
        foreach (var file in configFiles)
        {
            Information(file.Name);
        }
    });

Meu primeiro exemplo com Cake

Vendo tudo isso, Cake pareceu ser perfeito para o meu projeto, mas como ele realmente se comporta no mundo real? Decidi testar.
O Cake já vem com um bootstrapper para cada plataforma, isso é muito importante para um projeto Xamarin, que é inerentemente cross platform, e pessoas podem estar usando um Mac ou Windows durante o desenvolvimento.
No Windows, numa janela PowerShell executei:
Invoke-WebRequest https://cakebuild.net/download/bootstrapper/windows -OutFile build.ps1
No Mac, executei:
curl -Lsfo build.sh https://cakebuild.net/download/bootstrapper/osx
Com isso já tinha o Bootstrap pronto para interpretar e executar scripts Cake.
Peguei o exemplo mais simples, criei um arquivo build.cake na raíz do meu projeto com esse conteúdo:
1
2
3
4
5
6
7
8
9
var target = Argument("target", "Default");
 
Task("Default")
  .Does(() =>
{
  Information("Hello World!");
});
 
RunTarget(target);
Agora é só rodar e ver o resultado. No Windows a execução é feita automaticamente usando o build.ps1, no Mac o equivalente é o build.sh.
console output da tarefa Cake
Pronto! Agora a automatização das tarefas do meu projeto são todas feitas na mesma linguagem em que todas as pessoas do time já sabem usar!

Conclusão

Cake satisfez todas minhas necessidades para esse projeto, sendo muito simples de usar, ele tem funcionado perfeitamente no Mac. Caso queira começar a testá-lo, sugiro começar pela própria documentação do Cake para novos projetos, e pesquisar sempre se já não existe um alias built-in na plataforma para facilitar sua vida.
Outros links interessantes:
Num próximo post compartilharei algumas tasks que estou usando e tem me ajudado bastante no dia-a-dia, até lá, teste no seu projeto e conte como foi!
Imagem usada no post: Food plate chocolate dessertPexels

Nenhum comentário:

Postar um comentário