Tips & Tricks for Clean Code: Adding Rubocop to an Open-Source SDK

Holly Stotelmyer
The PayPal Technology Blog
4 min readSep 14, 2021
Image of a Ruby by Joshua Fuller via Unsplash

RuboCop is a handy style checking and formatting library that helps report and fix errors and/or style issues in your code. As a developer, this can help you improve your code before peer review and eventual public or production release.

Additionally, when supporting an open-source (OS) library like the Braintree Ruby SDK, RuboCop helps ensure the SDK is more readable to the thousands of Ruby developers that use it and may need to dive deeper into the code.

The Braintree Ruby SDK is a mature library that is more than ten years old, which means there could be hundreds or thousands of “offenses” — linting errors — that would need to resolved, reviewed in a pull request (PR), and released in a new SDK version. Here is how I made the process as painless as possible for myself and my team when I added RuboCop to the Braintree Ruby SDK.

Image of a person working on a computer by The Gender Spectrum Collection via Creative Commons License

Research

There are a lot of rules that RuboCop can enforce for you, but is it worth enforcing all of them? Are there other OS libraries that your code uses that also use RuboCop? Are there other teams that you work with that use Ruby in their code? Do they currently use RuboCop or have used it in an earlier project?

These are great questions that you should ask yourself when preparing to implement RuboCop in your codebase. For the Braintree Ruby SDK, I lucked out because several other engineering teams that regularly contribute to our SDK also used Ruby and RuboCop on a regular basis. This meant that I could review RuboCop YAML files from their projects for any rules that I may have wanted to implement, too. Additionally, my colleagues would be accustomed to any rules I added, as they have already been using them in other projects. In other words, my changes wouldn’t result in a time burden and would be more likely to be accepted and merged.

Detailed image of hard drive by Michael Dziedzic via Unsplash

Git Strategy

When I know I’m going to be submitting a decent chunk of changes for review with my team, I follow a git strategy proposed by my colleague. Her strategy helps break things up into smaller chunks for review while not putting a repository’s main branch into a broken state.

First, create one base branch that will be submitted for review against the main or master branch of your library. As an example, we could call the branch for all RuboCop additions add-rubocop.

Then, break work into small chunks and assign these commits to new sub-branches. These sub-branches are then reviewed and merged to the add-rubocop branch. For example, in a branch called style-rules, only style-type rules and the code changes to resolve any offenses generated from those rules are committed and sent for review. Similar branches could be created and reviewed separately for layout, Gemspec, or other type rules.

This allows my team to review work more closely because I’ve broken it up into contextually meaningful parts, which ultimately leads to easier and faster reviews (and happier teammates!).

When all sub-branches are merged into the main add-rubocop branch, only a brief check for any passing or failing tests needs to be performed before merging to a main/master branch, because all the code was previously reviewed in earlier PRs.

Implementation Strategy

I used the following steps to add rules to the rubocop.yml file in our SDK:

  1. Update the YAML file with new rules
  2. Run the command to have RuboCop screen for offenses and auto correct as many violations as possible:
    $ rubocop –a
  3. Review and update any remaining offenses that couldn’t be autocorrected
  4. Repeat Steps 2&3 until there are no more offenses
  5. Commit these changes and create a PR

Fortunately, most offenses in the SDK were easily auto corrected, which means that everyone maintaining the Ruby SDK was vigilant in reviewing for potential bugs or unforeseen side effects (go team!).

Hands typing on a keyboard image by Kelly Sikkema via Unsplash

Other Considerations

The SDK’s code doesn’t live in a vacuum — it’s always changing and evolving with the language, the Ruby community, and PayPal. This means my RuboCop implementation should be available for anyone working in the library and applied to any changes sent for review.

PayPal’s Braintree SDKs include Rakefiles with command-line interface (CLI) commands for running tests, so I added a new rake command to run RuboCop:

$ rake lint

I also made sure that RuboCop is run as part of our continuous integration (CI) builds, so that PRs are checked for offenses. This way, our work stays clean and readable for everyone in the future.

And finally, I made sure to update the SDK’s README file with a link to RuboCop’s documentation and how to use the rake command I added. This way I’m helping myself and others use my work.

These strategies helped make adding RuboCop to the Braintree Ruby SDK an easy project. I hope they help you in your linting ventures, too!

--

--