Rubocop Challenger
If you introduce rubocop
to an existing Rails project later, you will use $ rubocop --auto-gen-config
. But it will make a huge .rubocop_todo.yml
and make you despair.
On the other hand, rubocop
has --autocorrect
option, it is possible to automatically repair the writing which does not conform to the rule. But since it occasionally destroys your code, it is quite dangerous to apply all at once.
It is ideal that to remove a disabled rule from .rubocop_todo.yml
every day, to check whether it passes test, and can be obtained consent from the team. But it requires strong persistence and time.
I call such work Rubocop Challenge. And the RubocopChallenger is a gem to support this challenge!
The history of RubocopChallenger with decrease of offense codes
The following chart shows the history of RubocopChallenger and decrease of offense codes at a .rubocop_todo.yml
. The project was released at 5 years ago, and then it was introduced the RuboCop gem for huge source code including a lots of offense codes. Before using the RubocopChallenger, it was not maintain to reduce offense codes. One day, I felt a crisis and started maintain with manual. I made a lots of Pull Requests to reduce them but it's a load for me and reviewers. So I created a script for automation the flow, which is the predecessor of Rubocop Challenger gem. It brought reducing the offense codes continuously. After 8 months, finally it has done. There is no autocorrectable offense codes.
But there are many offenses which is un-autocorrectable yet. I will try to reduce it with the RubocopChallenger. The RubocopChallenger will
be continued to evolve.
Rubocop Challenge Flow
- Run RubocopChallenger periodically from CI tool etc.
- When RubocopChallenger starts, delete a disabled rule from
.rubocop_todo.yml
existing in your project, execute$ rubocop --autocorrect
and create a PR which include modified results - You confirm the PR passes testing and then merge it if there is no problem
Usage
1. Configure .circleci/config.yml
Configure your .circleci/config.yml
to run rubocop_challenger, for example:
# .circleci/config.yml
version: 2
jobs:
rubocop_challenge:
docker:
- image: circleci/ruby:3.0
working_directory: ~/repo
steps:
- checkout
- run:
name: Rubocop Challenge
command: |
gem install rubocop_challenger
rubocop_challenger go \
--email=rubocop-challenger@example.com \
--name="Rubocop Challenger"
workflows:
version: 2
nightly:
triggers:
- schedule:
cron: "30 23 * * 1,2,3" # 8:30am every Tuesday, Wednesday and Thursday (JST)
filters:
branches:
only:
- master
jobs:
- rubocop_challenge
Should not append gem 'rubocop_challenger'
on your Gemfile.
I have seen cases where errors occur due to compatibility issues with other gems.
2. Setting GitHub personal access token
GitHub personal access token is required for sending pull requests to your repository.
- Go to your account's settings page and generate a new token with "repo" scope
- On CircleCI dashboard, go to your application's "Project Settings" -> "Environment Variables"
- Add an environment variable
GITHUB_ACCESS_TOKEN
with your GitHub personal access token
Want to use on GitHub Actions?
Here is a sample workflow:
name: "RuboCop Challenge"
on:
workflow_dispatch:
schedule:
# 10am PST Tuesdays and Thursdays
- cron: 0 17 * * 2,4
jobs:
create-rubocop-challenger-pr:
name: Create Rubocop Challenger Pull Request
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: ruby/setup-ruby@v1
with:
bundler-cache: true
- name: Set git configuration
run: git config remote.origin.url "git@github.com:your_org/your_repo.git"
- name: Create RuboCop challenge pull request
env:
GITHUB_ACCESS_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
gem install rubocop_challenger
rubocop_challenger go --email="rubocop-challenger@example.com" --name="Rubocop Challenger" --mode=random --only-exclude
You will need to make sure the following setting is enabled by going to Settings -> Actions -> General and checking Allow GitHub Actions to create and approve pull requests
CLI command references
$ rubocop_challenger help
Commands:
rubocop_challenger go --email=EMAIL --name=NAME # Run `$ rubocop --autocorrect` and create a PR to GitHub repo
rubocop_challenger help [COMMAND] # Describe available commands or one specific command
rubocop_challenger version # Show current version
Command-line Flags
$ rubocop_challenger help go
Usage:
rubocop_challenger go --email=EMAIL --name=NAME
Options:
--email=EMAIL # The Pull Request committer email
--name=NAME # The Pull Request committer name
f, [--file-path=FILE_PATH] # Set your ".rubocop_todo.yml" path
# Default: .rubocop_todo.yml
t, [--template=TEMPLATE] # A Pull Request template `erb` file path.You can use variable that `title`, `rubydoc_url`, `description` and `examples` into the erb file.
[--mode=MODE] # Mode to select deletion target. You can choice "most_occurrence", "least_occurrence", or "random". If you set --no-offense-counts, the mode to be forced to "random".
# Default: most_occurrence
b, [--base-branch=BASE_BRANCH] # The Branch to merge into
# Default: master
l, [--labels=one two three] # Label to give to Pull Request
# Default: ["rubocop challenge"]
[--project-column-name=PROJECT_COLUMN_NAME] # A project column name. You can add the created PR to the GitHub project
[--project-id=N] # A target project ID. If does not supplied, this method will find a project which associated the repository. When the repository has multiple projects, you should supply this.
[--create-pr], [--no-create-pr] # If you set --no-create-pr, no create a pull request (for testing)
# Default: true
[--exclude-limit=N] # For how many exclude properties on create .rubocop_todo.yml
[--auto-gen-timestamp], [--no-auto-gen-timestamp] # Include the date and time in .rubocop_todo.yml
# Default: true
[--offense-counts], [--no-offense-counts] # Include offense counts in .rubocop_todo.yml
# Default: true
[--only-safe-autocorrect], [--no-only-safe-autocorrect] # If given `true`, it executes `rubocop --autocorrect`,it means to correct safe cops only.
[--only-exclude], [--no-only-exclude] # If you set --only-exclude, exclude files instead of generating Max parameters in Metrics cops when creating .rubocop_todo.yml automatically.
[--verbose], [--no-verbose] # Displays executing command.
Run `$ rubocop --autocorrect` and create a PR to GitHub repo
Requirement
- Ruby 3.0 or higher
Development
After checking out the repo, run bin/setup
to install dependencies. Then, run rake spec
to run the tests. You can also run bin/console
for an interactive prompt that will allow you to experiment.
To install this gem onto your local machine, run bundle exec rake install
. To release a new version, update the version number in version.rb
, and then run bundle exec rake release
, which will create a git tag for the version, push git commits and tags, and push the .gem
file to rubygems.org.
Contributing
Bug reports and pull requests are welcome on GitHub at https://github.com/ryz310/rubocop_challenger. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the Contributor Covenant code of conduct.
License
The gem is available as open source under the terms of the MIT License.
Code of Conduct
Everyone interacting in the RubocopChallenger project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the code of conduct.