Skip to content

Commit

Permalink
rubocop: split configuration
Browse files Browse the repository at this point in the history
 * remove spurious .rubocop.yml override files
 * split the configuration into an enforced and optional
 * run both configurations in jenkins (may result in some duplicate
   comments at different levels)
 * auto-correct the enforced configuration in the pre-commit hook
 * fix comments for Gemfile.d and the root dir; enforced configuration
   is only applied to that directory for now

Change-Id: I8da21073d74e19138b1b580d66c7aae6465348d4
Reviewed-on: https://gerrit.instructure.com/c/canvas-lms/+/273898
Reviewed-by: Simon Williams <[email protected]>
Tested-by: Service Cloud Jenkins <[email protected]>
QA-Review: Cody Cutrer <[email protected]>
Product-Review: Cody Cutrer <[email protected]>
  • Loading branch information
ccutrer committed Sep 21, 2021
1 parent aa71e6f commit e9d6339
Show file tree
Hide file tree
Showing 23 changed files with 303 additions and 258 deletions.
71 changes: 71 additions & 0 deletions .rubocop.common.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
require:
- rubocop-rails
- rubocop-rake
- rubocop-rspec
- rubocop-performance
# this odd relative path is so that rubocop works when run without "bundle
# exec", such as from most editors/IDEs.
- ./gems/rubocop-canvas/lib/rubocop_canvas
- outrigger/cops/migration/tagged

AllCops:
TargetRubyVersion: 2.7

Bundler/OrderedGems:
Enabled: false # this isn't good for us because of how we pin dependencies

Gemspec/OrderedDependencies:
Enabled: false # this isn't good for us because of how we pin dependencies

Layout/IndentationConsistency:
Exclude:
- "**/Gemfile.d/*" # we purposely indent dependent gems

Lint/Debugger:
Severity: error

Metrics:
Enabled: false # SnR is just too low to have this enabled

Migration/Tagged:
Severity: error
AllowedTags:
- predeploy
- postdeploy
- cassandra
- dynamodb

Naming/FileName:
Exclude:
- "**/Gemfile.d/~after.rb"

Rails:
Exclude:
- "**/Gemfile.d/*" # Rails isn't loaded yet, so can't use their helpers in the Gemfile

RSpec/EmptyExampleGroup:
Severity: error
RSpec/ExampleLength:
Enabled: false
RSpec/InstanceVariable:
Enabled: false
RSpec/MultipleExpectations:
Enabled: false
RSpec/NestedGroups:
Max: 5
RSpec/RepeatedDescription:
Severity: error

Specs/EnsureSpecExtension:
Exclude:
- spec/shared_examples/**/*
Style/AsciiComments:
Enabled: false
Style/Documentation:
Enabled: false
Style/FrozenStringLiteralComment:
Severity: error
Style/SpecialGlobalVars:
Enabled: false
Style/StringLiterals:
Enabled: false
85 changes: 85 additions & 0 deletions .rubocop.enforced.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
inherit_from: .rubocop.common.yml

inherit_mode:
merge:
- Exclude

AllCops:
NewCops: disable

<%=
# keys are cops you want to opt in for (nil being all cops)
# values are an array of directories to opt in for (nil being all directories)
OPT_IN = {
nil => %w[Gemfile.d].freeze
}.freeze
# this code generates a configuration that disables all cops for all files
# _unless_ the cop is already configured in .rubocop.common.yml, OR the file
# is in one of the OPT_IN directories. It does this by generating an Exclude
# configuration for every cop (except already configured) that lists all
# directories (except OPT_IN). AllCops does not support an Include, and
# even if it did, inheritance to individual cops would not work correctly.
def generate_excludes(opt_in_array)
return nil unless opt_in_array
excludes = []
dirs_to_exclude_siblings_of = []
opt_in_array.each do |dir|
components = dir.split("/")
(0...components.length).each do |i|
ancestor = components[0..i].join("/")
exclude = "#{ancestor}/*"
excludes << exclude unless excludes.include?(exclude) || opt_in_array.include?(ancestor)
dirs_to_exclude_siblings_of << ancestor unless dirs_to_exclude_siblings_of.include?(ancestor)
end
end
dirs_to_find_siblings_of = dirs_to_exclude_siblings_of.map do |dir|
File.dirname(dir)
end.uniq
dirs_to_find_siblings_of.each do |dir|
dirs = Dir["#{dir}/*"]
.select { |dir| File.directory?(dir) }
.map { |dir| dir.sub(%r{^\./}, "") }
dirs -= dirs_to_exclude_siblings_of
excludes.concat(dirs.map { |d| "#{d}/**/*" })
end
excludes.sort
end
resolved_excludes = OPT_IN.transform_values do |dirs|
next nil unless dirs
generate_excludes((Array(dirs) + OPT_IN[nil]).uniq)
end
require 'yaml'
common_config = YAML.safe_load(File.read(".rubocop.common.yml"))
common_config["require"].each { |f| require f }
# already configured cops in common.yml are intended to apply to all files already
already_configured_cops = common_config.keys.select { |k| k.include?("/") && !common_config[k]['Exclude'] }.to_set
config = {}
RuboCop::Cop::Registry.all.each do |cop|
next if cop.department == :Metrics
next if cop.cop_name == 'Lint/Syntax'
next if already_configured_cops.include?(cop.cop_name)
key = [cop.cop_name, cop.department.to_s, nil].find do |key|
resolved_excludes.key?(key)
end
excludes = resolved_excludes[key]
next if excludes.nil?
config[cop.cop_name] = { "Exclude" => excludes }
end
config.to_yaml.sub(/^---\n/, "")
%>
Loading

0 comments on commit e9d6339

Please sign in to comment.