Rubocop: Como instalar e configurar
Tags: ruby, rubocop, rails, linters
Published: 2022-01-09 17:20:54

Qualidade de código é importante, e toda equipe de alta performance sabe disso, mas você segue algum guia para padronizar sua base de código e garantir que todos estão indo e olhando pra mesma direção?

Fazendo uma breve introdução, este é o objetivo de um linter: Uma ferramenta para analisar seu código-fonte e identificar erros de programação, bugs e inconsistências *([Wikipedia](https://en.wikipedia.org/wiki/Lint_(software))).*

O objetivo principal é garantir que seu código siga as mesmas regras e práticas, para parecer que todo o código foi escrito pela mesma pessoa.

Em uma grande variedade de linters de Ruby, temos o **[RuboCop](https://github.com/rubocop/rubocop/)** (disponível como uma gem) que segue as boas práticas descritas no [The Ruby Style Guide](https://rubystyle.guide/)

Uma das vantagens de usar um linter, é salvar tempo revisando código, pois ele previne pequenos problemas como inconsistências em nomes de variáveis e práticas durante o processo de desenvolvimento. Com isso, a revisão de código é mais eficiente, e pode ser focada nas implementações e requisitos de funcionalidades.

Começar a usar o Rubocop é bastante simples e não depende de ninguém mais para configura-lo. Você pode instalar a gem e roda-la instantaneamente no seu fluxo de trabalho.

## Instalação

Para instalar o **Rubocop**, é bem rápido e simples. Vamos considerar aqui que todo o seu setup Ruby esteja funcional, então execute o seguinte comando para instalar a última versão disponível:

```
$ gem install rubocop
```

*RuboCop oficialmente suporta as implementações **MRI 2.5+** e **jRuby 9.2+**. Você também pode instala-lo diretamente no seu projeto usando o Bundler, adicionando a gem ao seu arquivo `Gemfile`, e rodando `bundle install`.*

## Configuração

O comportamento do **Rubocop** pode ser controlado pelo arquivo `.rubocop.yml` na raiz do projeto onde você deseja executá-lo. É nesse arquivo que você consegue habilitar/desabilitar certas cops (regras) ou alterar seu comportamento.

Todas as cops são agrupadas em departamentos: **Style**, **Layout**, **Lint**, **Naming**, **Security**, **Metrics**, **Migration**, **Bundler,** e **Gemspec**. Você pode ler melhores sobre as cops e seus agrupamentos na [documentação](https://docs.rubocop.org/rubocop/cops.html). Por propósitos de referência, você pode consultar o arquivo que usamos na [SourceLevel](https://sourcelevel.io/) em nosso [repositório](https://github.com/sourcelevel/linters/blob/main/.rubocop.yml) de configuração de linters.

O arquivo `.rubocop.yml` tem a seguinte estrutura:

```
inherit_from: ../.rubocop.yml

require: rubocop-rails

Style/Encoding:
  Enabled: false

Layout/LineLength:
  Max: 99
...
```

*Nota 1: Usamos o `inherit_from` para usar as cops já definidas de um outro arquivo. Mais detalhes na [documentação](https://docs.rubocop.org/rubocop/configuration.html#inheritance).
Nota 2:* Se você usa **Rails***, é importante fazer o require da extensão `rubocop-rails` (Lembre-se de adiciona-la em seu arquivo`Gemfile`), que vai forçar o RuboCop a seguir as [convenções e boas práticas](https://rails.rubystyle.guide/) definidas pela comunidade Rails.*

Por padrão quando executado, o RuboCop procura por um arquivo`.rubocop.yml` no diretório atual, logo depois em seu home path (`~/.rubocop.yml`), e em último caso vai usar as configurações padrões. Mais detalhes sobre a configuração do Rubocop podem ser encontradas na [documentação oficial](https://docs.rubocop.org/rubocop/configuration.html).

Se você deseja criar seu próprio arquivo de configuração, o que é recomendável, um bom ponto de partida é usar o [arquivo](https://github.com/rubocop/rubocop/blob/master/.rubocop.yml) disponível no repositório do Rubocop como referência. Você pode revisar regra por regra e configurar o que melhor funciona para você. Apenas lembre-se de verificar a disponibilidade da regra para a versão do RuboCop que você esteja usando.

Mantenha em mente que as regras pertencentes ao agrupamento `Style` são configuráveis e opcionais. Uma boa recomendação é que essas regras sejam discutidas e definidas com toda a equipe, e não somente por uma pessoa.

É bom mencionar que você pode escrever suas próprias cops, chamadas **Custom Cops**. Com elas, você pode definir suas próprias regras e práticas para garantir que elas serão seguidas. Você pode encontrar mais informações sobre como criar uma Custom Cop na [documentação](https://docs.rubocop.org/rubocop/development.html).

## Uso

Para usar o RuboCop você só precisa navegar até o diretório onde deseja rodar o linter e executar:

```
$ rubocop
```

Você pode especificar um arquivo/diretório:

```
$ rubocop lib/file.rb
```

Também é possível especificar uma lista de arquivos e diretórios:

```
$ rubocop app/ spec/ lib/file.rb
```

Após rodar o RuboCop, você deve obter uma saída com as possíveis ofensas, algo como:

```
Offenses:

test.rb:1:1: C: Style/FrozenStringLiteralComment: Missing magic comment # frozen_string_literal: true.
def badName
^
test.rb:1:5: C: Naming/MethodName: Use snake_case for method names.
def badName
    ^^^^^^^
test.rb:2:3: C: Style/GuardClause: Use a guard clause instead of wrapping the code inside a conditional expression.
  if something
  ^^
test.rb:2:3: C: Style/IfUnlessModifier: Favor modifier if usage when having a single-line body. Another good alternative is the usage of control flow &&/||.
  if something
  ^^
test.rb:4:5: W: Layout/EndAlignment: end at 4, 4 is not aligned with if at 2, 2.
    end
    ^^^

1 file inspected, 5 offenses detected
```

### Autocorreção

Uma ótima funcionalidade do RuboCop é a autocorreção. Essa opção corrige automaticamente todas as possíveis ofensas no seu código, baseando-se nas regras definidas. Em nosso caso, usamos o argumento `-a` para corrigir as ofensas consideradas seguras de serem corrigidas, mas você pode ser mais otimistas e usar o argumento`-A` para corrigir todas as ofensas possíveis (incluindo as que talvez a correção não seja tão segura), mas você precisa usa-lo com cautela.

Para usa-la você precisa rodar o RuboCop com o argumento de autocorreção:

```
$ rubocop --auto-correct
# ou
$ rubocop -a
```

Você pode verificar todos os argumentos aceitos pelo **RuboCop** usando `--help`:

```
$ rubocop --help
```

Apenas para propósitos de lincagem, você pode checar a [documentação](https://docs.rubocop.org/rubocop/usage/auto_correct.html) para saber mais a respeito da funcionalidade de autocorreção.

## Integrando com outras ferramentas

O RuboCop Integra-se com muitas outras ferramentas. Você pode integra-lo no seu editor de código para roda-lo toda vez que você salvar um arquivo, e assim obter uma resposta imediata

Para uma lista de editores de códigos suportados, você pode verificar [esta página](https://docs.rubocop.org/rubocop/integration_with_other_tools.html#editor-integration) na documentação, e caso o seu favorito não esteja listado, é uma ótima oportunidade para contribuir com o RuboCop implementando uma integração.

Outra ótima integração é criar um [Git Hook](https://git-scm.com/book/en/v2/Customizing-Git-Git-Hooks) para rodar o RuboCop após cada commit. Você também pode configurar o RuboCop para ser executado em seu serviço de Integração Continua (CI), como GitHub Actions, para ter insights após cada interação com um Pull Request. Em todos os casos, você pode encontrar mais detalhes na [documentação](https://docs.rubocop.org/rubocop/integration_with_other_tools.html#git-pre-commit-hook-integration-with-pre-commit).

Você tem algum caso de uso legal para compartilhar? Sinta-se a vontade para me contatar via [Twitter](https://twitter.com/garaujodev) ou use a sessão de comentários abaixo.

Espero que você tenha gostado do conteúdo, e obrigado por ler.