Automate RuboCop ToDo fix
Tags: ruby, rubocop, refactoring
Published: 2022-07-30 09:26:25

---
title: Automate RuboCop ToDo fix
published: true
description:
tags:
  - ruby
  - rubocop
  - refactoring
---

Let me introduce [rubocop-todo-corrector](https://github.com/r7kamura/rubocop-todo-corrector) in this article.

## ToDo list based linting

These days, many projects are using Lint tools to self-diagnose their code.

e.g.

- ESLint for JavaScript
- rustfmt for Rust
- RuboCop for Ruby
- etc.

RuboCop has the ability to detect existing offenses and automatically generate a file named `.rubocop_todo.yml`. This file acts as a to-do list, so we can gradually fix the offenses.

This mechanism is very powerful when introducing a new Lint tool in the middle of an existing project, or when introducing new rules by upgrading the existing Lint tool.

## Automate it

The improvement process cycle would look like this:

1. Select one lint rule from ToDo list
2. Autocorrect existing offenses (or disable the rule)
3. Re-generate ToDo
4. Create a Pull Request
5. Review and merge the Pull Request
6. Repeat from 1.

However, it's difficult to do this manually. So, let's automate with [rubocop-todo-corrector](https://github.com/r7kamura/rubocop-todo-corrector) custom GitHub action.

## rubocop-todo-corrector

It's easy to use, just place the following YAML file in your repository.

```yaml
# .github/workflows/rubocop-todo-corrector.yml
name: rubocop-todo-corrector

on:
  pull_request:
    types:
      - closed
  workflow_dispatch:
    inputs:
      cop_name:
        description: Pass cop name if you want to pick a specific cop.
        required: false
        type: string
      ignore:
        description: Check this with cop_name if you want to ignore a specific cop.
        required: false
        type: boolean
jobs:
  run:
    runs-on: ubuntu-latest
    steps:
      - uses: r7kamura/rubocop-todo-corrector@v0
        with:
          ignore: ${{ inputs.ignore }}
          label: rubocop-todo-corrector
```

then create "rubocop-todo-corrector" label on your repository.

Now you can run this workflow by "Run workflow" button on actions page:

![actions page](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hq74x4rs1w8frpz3xhf8.png)

After the workflow is complete, a pull request is created as follows:

![pull request](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ztq4p5am60za0biwqp4b.png)

Review this pull request, and if it looks good, press the Merge button.

The next pull request will then be automatically created. That is, all we have to do is to press the Merge button, and the code automatically gets refactored more and more. What an easy job!

## Our story

In our huge Rails app, which has been running for about 10 years, we introduced RuboCop in the middle of the process, and at first there were 200,000 offenses.

![chart](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/37165rqvfo505oh497cm.png)

(I also described how to make this chart at [Aggregate offenses count in .rubocop_todo.yml - DEV Community](https://dev.to/r7kamura/aggregate-offenses-count-in-rubocoptodoyml-4oda))

There were so many offenses that we almost gave up on fixing them, but recently we introduced rubocop-todo-corrector and the offenses slowly started decreasing.

Since its introduction about 2 months ago, we have been able to correct about 40,000+ offenses. The developers are getting used to the review & merge process, which is gradually accelerating, and it looks like we will be able to reduce offenses to almost zero in another year or so.

## Wrapping up

In this article, I introduced the background and usage of a custom GitHub action called [rubocop-todo-corrector](https://github.com/r7kamura/rubocop-todo-corrector).

There are other features that were not covered in this article, such as automatic reviewer assignment and disabling as well as fixing violations, so if you are interested please read the README.

Automating the refactoring process is a powerful mechanism. Let's automate more and more and keep the good code quality.