RuboCop is a Ruby static code analyzer (a.k.a. linter) and code formatter. Out of the box it will enforce many of the guidelines outlined in the community Ruby Style Guide. Apart from reporting the problems discovered in your code, RuboCop can also automatically fix many of them for you.
RuboCop v1.0 was released in the end of 2020, but many users are using older versions because up to version 1 it was painful to upgrade the RuboCop. But in September 2021, the RubyKaigi Takeout 2021 conference was held, at which Koichi ITO, a member of the RuboCop core team and technical manager of ESM, Inc., made a presentation called RuboCop in 2021: Stable and Beyond.
Through this talk, you will know about benefits and considerations for upgrading RuboCop to v1.x and a little bit about changes planned for RuboCop v2.0.
1. Stable
1.1 Interface compatibility between releases
One big characteristic is it’s interface compatibility between releases. There are no breaking changes. Before RuboCop v1, when new rules were added or when the cop’s name changed, they cause problems. From v1.0 on, developers are mindful to maintain compatibility. When a new cop is introduced, it will not be enabled from the get-go, but it will first be introduced as cops with pending status. With this, devs tried to reduce the upgrade pain. In the past, default behavior was that the new rule will be applied from the get-go even if one was unsure if that rule suits one’s projects. Now the new rule will have a pending status so that the user can choose to enable it or not.
Another characteristic about v1 is that for the new cops introduced in minor releases, users can choose to enable them or not on their own. A conservative RuboCop upgrading practice thats documented is to specify the version numbers loosely. Before v1.0, users needed to specify the patch version but from v1 on, one only needs to designate up to minor versions.
v1.x:
gem 'rubocop', '~> 1.19', require: false
v0.x:
gem 'rubocop', '~> 0.78.0', require: false
During 1.x, even one continues to upgrade, code won’t break because of compatibility issues. When RuboCop is executed, a warning like this will get displayed.
This indicates the cops that are not enabled by default.
The newly introduced RuboCop, the version is shown alongside. This information can be copied and pasted.
If you want to enabled the cop, choose Enable: true
, if not, choose Enable: false
.
This will set your .rubocop.yml file accordingly.
If you want to enabled all new RuboCops at once instead of setting them one by one, a new attribute called NewCops is available. In your .rubocop.yml file you can enable or disable the newly added cops.
1.2 Autocorrections
From v1.0 on, more than 14 new cops have been added there for autocorrection. The layout can be autocorrected with almost no change to code semantics. For example, you can check if autocorrect works for layouts by next command:
% cd path/to/rubocop
% bin/console
RuboCop::Cop::Registry.global.with_department(:Layout).reject(&:support_autocorrect?)
The next point of autocorrections is concept of case and unsafe. Safe means that even if the code is autocorrected, the code semantics will not change. Unsafe means that if autocorrect changes the behavior and changes the return value, then those are regarded as unsafe. There are some elements that cannot be autocorrected to begin with variable names, source of code comments that are left are some examples of that. These corrections cannot be determined automatically, so those will remain as something that cannot be autocorrected.
There is a newly added option called -A: this option applies safe and unsafe auto-correction (e.g. Style/FrozenStringLiteralComment). That option is the same -a behavior of RuboCop v0.86 and lower.
1.3 Performance
RuboCop can be accelerated by using parallel gem as a parallel processing option. When developers made a test of this feature, the results was impressive: 1300 files was analized in 10 seconds (61 sec without parallels), what means that it became 6 times faster.
The improvement depends on the machine spec, number of cores, and the number of target files. Since the target files will be assigned to cores, the more cores there are and the higher the machine spec, the higher the improvement rate. Regarding performance tuning, memory profiles and StackProf are used to tune the performance of significantly slow cops.
1.4 Bug fixes
-
Ruby static analysis without static typing struggling against false positives and false negatives. Many of these types of bugs have been fixed.
-
Auto-corrected code may trigger unexpected behaviors because of bugs, so if you come across a case that you think is strange, stop and review it again.
-
In the past, RuboCop suggested to change
expr and return
toexpr && return
by default what looked weird, so developers changed the configuration to acceptexpr and return
by default.
2. Beyond
Now lets talk about the future of RuboCop.
At first we cover some destructive changes that will be introduced for 2.0. From RuboCop v1.0, custom cops official parent class became Base
instead of Cop
class. At rubocop.org, pretty much all of the third-party cops have already been migrated. There are only two core cops that haven’t been migrated yet.
The next point touches the naming of cops.
This is feature for developers when you are implementing custom cops. For some cop and option names, better names often pop up after the release. For version one, the names cannot be changed because it will be a distructive change, but this will be changed in version two.
For third-party API during version one, there will be a warning sent before version two and it will be changed or removed in version two. For RuboCop Rails, there was Rails department dependency to the core. When this is carved out as gem, part of the API remains in the core. This may be affected, so be mindful.
Also, as we mentioned above that new cops will have pending status initially for 1.0. At the time of 2.0 major version upgrade, all pending cops will be enabled by default. From one to the latest 1.9 there are about 40 new cops. It will be tough to supervise all 40 at the same time, so upgrade in small chunks as need might be better.
Final Words
The developers of version 1 tried to make an update that would make using and upgrading of RuboCop more user friendly. Now RuboCop has a compatibility between releases so it won’t be so painful to make an update it in your projects.
Except that was done big step to improving performance what gives you more time to develop, not waiting.
So, you can upgrade RuboCop in your projects to version 1.x with no fear that something will be wrong, and enjoy the development.
You can investigate the original content there: