I am working on a tool to analyze how rubocop is used (enabled/disabled) and fixed (excluded into todo lists) in certain areas of the codebase. Given the multitude of config options, I think I am looking for a way to programmatically ask RuboCop whether given a file or folder, a certain rule is enabled and whether this file is excluded via a todo or not. Is there an API for this?
I have so far spelunked in https://github.com/rubocop/rubocop to see if I could find an API... Searched via SO and google and can't find anything.
I don't think there's public interface for what you want. This mobilize_team
method in the Runner is what instantiates a RuboCop::Cop::Team
. The team object determines the cops to use in this roundup_relevant_cops
method. Both of these methods are private, but you could use send
to work around that.
For example, say that we have a project with two files called test_one.rb
and test_two.rb
.
The .rubocop_todo.yml
says that one of the files still needs to be handled:
# .rubocop_todo.yml
Style/FrozenStringLiteralComment:
Exclude:
- 'test_two.rb'
The .rubocop.yml
config says that we just care about Style/FrozenStringLiteralComment
:
# .rubocop.yml
inherit_from: .rubocop_todo.yml
AllCops:
DisabledByDefault: true
Style/FrozenStringLiteralComment:
Enabled: true
We can see the cops that RuboCop will apply to each file if we do this:
require 'rubocop'
# Set up the Runner. Assumes no special command line options are involved.
options, _paths = RuboCop::Options.new.parse([])
config_store = RuboCop::ConfigStore.new
runner = RuboCop::Runner.new(options, config_store)
# For each file, figure out which cops are enabled for that file
['test_one.rb', 'test_two.rb'].each do |filename|
full_path = File.join(Dir.pwd, filename)
config = config_store.for_file(full_path)
source = RuboCop::ProcessedSource.from_file(full_path, config.target_ruby_version)
team = runner.send(:mobilize_team, source)
cops = team.send(:roundup_relevant_cops, source)
puts "#{filename}: #{cops.map(&:name).join(', ')}"
end
This will show this output:
test_one.rb: Lint/Syntax, Style/FrozenStringLiteralComment
test_two.rb: Lint/Syntax
Because of this special condition in enable_cop?
the Lint/Syntax
cop is always enabled. And since test_one.rb
isn't included in the TODO list, it is the only file that qualifies for the Style/FrozenStringLiteralComment
cop.