rubocop: go back to a single .rubocop.yml

it was just too confusing on which one an editor is using, double comments
in jenkins, etc.

this is accomplished by several things:
 * required cops are just marked as severe, instead of using a separate
   config for them, and failing if anything shows up from that config
 * get rid of all the logic to only include certain directories for
   certain cops. turns out it's not _that_ ominous to correct errors
   across the entire repository before marking a cop as required.
 * but still auto-generate config to turn _off_ autocorrect for
   non-severe cops. this is important because auto-correct must run
   for entire files, and we don't want it auto-correcting optional
   things that you didn't touch.
 * update gergich to get more details from the parsed comments.
   this plus the prior point means we _don't_ have to have heavy mode when
   in autocorrecting, but we still display out-of-context lines that were
   autocorrected

this also makes it so we can use per-dir .rubocop.yml files again, so
take some of the exceptions out of the root and put them in their own
directory

Change-Id: Ie936d1a9920b68910acd250ba817c7b4a670b958
Reviewed-on: https://gerrit.instructure.com/c/canvas-lms/+/274394
Tested-by: Service Cloud Jenkins <svc.cloudjenkins@instructure.com>
Reviewed-by: Simon Williams <simon@instructure.com>
QA-Review: Cody Cutrer <cody@instructure.com>
Product-Review: Cody Cutrer <cody@instructure.com>
This commit is contained in:
Cody Cutrer 2021-09-24 10:29:32 -06:00
parent 432f3cde03
commit b68d11de70
17 changed files with 228 additions and 277 deletions

View File

@ -10,10 +10,15 @@ require:
AllCops:
TargetRubyVersion: 2.7
NewCops: enable
Bundler:
Severity: error
Bundler/OrderedGems:
Enabled: false # this isn't good for us because of how we pin dependencies
Gemspec:
Severity: error
Gemspec/RequiredRubyVersion:
# all the gemspecs in this repo are non-published gems
# the root Gemfile enforces the Ruby version, and we purposely
@ -21,12 +26,8 @@ Gemspec/RequiredRubyVersion:
# maintenance pain when updating ruby versions
Enabled: false
Layout/EmptyLineAfterMagicComment:
Exclude:
- gems/tatl_tael/spec/lib/tatl_tael/linters/fixtures/**/* # fixtures purposely have errors
Layout/IndentationConsistency:
Exclude:
- "**/Gemfile.d/*" # we purposely indent dependent gems
Layout:
Severity: error
Layout/LineLength:
Enabled: false # TODO. Maybe.
@ -48,18 +49,21 @@ 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
Rails/ApplicationRecord:
Enabled: false # we never bothered creating an ApplicationRecord
Rails/HasManyOrHasOneDependent:
Enabled: false # legacy code + most things we soft delete anyway
Rails/SkipsModelValidations:
Enabled: false # Canvas skips validations in many places for optimization reasons
RSpec/DescribedClass:
Enabled: false # we haven't used it, and it seems antithetical to RSpec/NamedSubject
RSpec/EmptyExampleGroup:
Severity: error
RSpec/ExampleLength:
Enabled: false # this is a Metrics-style cop
RSpec/ExampleWording:
Severity: error
RSpec/InstanceVariable:
Enabled: false # legacy code
RSpec/MessageSpies:
@ -80,11 +84,110 @@ Style/Documentation:
Enabled: false # most things don't need to be documented
Style/FrozenStringLiteralComment:
Severity: error
Style/HashSyntax:
Enabled: false # TODO. Maybe.
Style/PerlBackrefs:
Enabled: false # Regexp.last_match(1) is far worse than $1
Style/SpecialGlobalVars:
Enabled: false # $! and $? are fine
# the following cops are currently silenced, but we may want to enable them IF
# we correct all instances in the codebase first
Lint/AmbiguousBlockAssociation: # TODO
Exclude:
- spec/**/*
Naming/VariableNumber: # TODO
Enabled: false
Rails/ReadWriteAttribute: # TODO: autocorrect (unsafe)
Enabled: false # accessors are often defined in terms of read_attribute
Rails/TimeZone: # TODO: autocorrect (unsafe)
Enabled: false
RSpec/ContextWording: # TODO
Enabled: false
RSpec/DescribeClass: # TODO
Enabled: false
RSpec/ExpectChange: # TODO: autocorrect (unsafe)
Enabled: false
RSpec/HookArgument: # TODO: autocorrect
Enabled: false
RSpec/NamedSubject: # TODO
Enabled: false
RSpec/NotToNot: # TODO: autocorrect
Enabled: false
RSpec/ScatteredSetup: # TODO: investigate if these are required
Enabled: false
RSpec/VerifiedDoubles: # TODO
Enabled: false
Style/BlockDelimiters: # TODO: autocorrect
Enabled: true
Exclude:
- spec/**/*_spec.rb
- spec/shared_examples/**/*.rb
AutoCorrect: false
Style/ClassAndModuleChildren: # TODO: autocorrect (unsafe)
Enabled: false
Style/DoubleNegation: # TODO: autocorrect (unsafe)
Enabled: false
Style/Dir: # TODO: autocorrect
Enabled: false
Style/FormatStringToken: # TODO: investigate if this complains about our i18n library
Enabled: false
Style/GuardClause: # TODO
Enabled: false
Style/HashSyntax:
EnforcedStyle: ruby19_no_mixed_keys
Enabled: false # TODO: autocorrect
Style/IfUnlessModifier: # TODO: autocorrect
Enabled: false
Style/Lambda: # TODO: autocorrect
Enabled: false
Style/MethodCallWithArgsParentheses: # TODO: autocorrect
Enabled: false
Style/MethodCallWithoutArgsParentheses: # TODO: autocorrect
Enabled: false
Style/NumericLiterals: # TODO: autocorrect
Enabled: false
Style/NumericPredicate: # TODO: autocorrect (unsafe)
Enabled: false
Style/ParallelAssignment: # TODO: autocorrect (with probable exceptions)
Enabled: false
Style/PercentLiteralDelimiters: # TODO: autocorrect
Enabled: false
Style/PercentQLiterals: # TODO: autocorrect
Enabled: false
Style/RedundantSelf: # TODO: autocorrect
Enabled: false
Style/RegexpLiteral: # TODO: autocorrect
Enabled: false
Style/RescueModifier: # TODO
Severity: warning
AutoCorrect: false
Style/RescueStandardError: # TODO: autocorrect
EnforcedStyle: implicit
Enabled: false
Style/ReturnNil: # TODO: autocorrect (investigate violations)
Enabled: false
Style/SignalException: # TODO: autocorrect
Enabled: false
Style/StderrPuts: # TODO: autocorrect
Enabled: false
Style/StringLiterals:
Enabled: false # TODO. Maybe.
EnforcedStyle: double_quotes
Enabled: false # TODO: auotcorrect
Style/SymbolArray: # TODO: autocorrect
Enabled: false
Style/TrailingCommaInArguments: # TODO: autocorrect
Enabled: false
Style/TrailingCommaInArrayLiteral: # TODO: autocorrect
Enabled: false
Style/TrailingCommaInHashLiteral: # TODO: autocorrect
Enabled: false
Style/WhileUntilModifier: # TODO: autocorrect
Enabled: false
Style/WordArray: # TODO: autocorrect
Enabled: false
Style/ZeroLengthPredicate: # TODO: autocorrect (unsafe)
Enabled: false

View File

@ -1,94 +0,0 @@
inherit_from: .rubocop.common.yml
inherit_mode:
merge:
- Exclude
AllCops:
NewCops: disable
<%=
# if you want to see what this all evaluates to, you can run
# `require 'erb'; puts ERB.new(File.read(".rubocop.enforced.yml")).result(binding)` from IRB
# 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,
'Bundler' => nil,
'Gemspec' => nil,
'Layout' => nil,
'RSpec/ExampleWording' => nil
}.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'
require 'rubocop'
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)
next if ENV['RUBOCOP_INCLUDE_AUTOCORRECTS'] && cop.support_autocorrect? && cop.new.safe_autocorrect?
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/, "")
%>

View File

@ -1,100 +1,30 @@
inherit_from: .rubocop.common.yml
# if you want to see what this all evaluates to, you can run
# `require 'erb'; puts ERB.new(File.read(".rubocop.yml")).result(binding)` from IRB
AllCops:
NewCops: enable # TODO
inherit_from:
- .rubocop.common.yml
Lint/AmbiguousBlockAssociation: # TODO
Exclude:
- spec/**/*
<%=
Naming/VariableNumber: # TODO
Enabled: false
# disable auto-correct on all non-explicitly-configured cops
unless ENV['RUBOCOP_INCLUDE_AUTOCORRECTS']
require 'yaml'
Rails/HasManyOrHasOneDependent: # TODO
Enabled: false
Rails/ReadWriteAttribute: # TODO: autocorrect (unsafe)
Enabled: false # accessors are often defined in terms of read_attribute
Rails/TimeZone: # TODO: autocorrect (unsafe)
Enabled: false
require 'rubocop'
common_config = YAML.safe_load(File.read(".rubocop.common.yml"))
common_config["require"].each { |f| require f }
already_configured_cops = common_config.keys.select { |k| k.include?("/") && !common_config[k]['Exclude'] }.to_set
already_configured_departments = common_config.keys.select { |k| !k.include?("/") }.map(&:to_sym).to_set
RSpec/ContextWording: # TODO
Enabled: false
RSpec/DescribeClass: # TODO
Enabled: false
RSpec/DescribedClass: # TODO: autocorrect (unsafe)
Enabled: false
RSpec/ExpectChange: # TODO: autocorrect (unsafe)
Enabled: false
RSpec/HookArgument: # TODO: autocorrect
Enabled: false
RSpec/NamedSubject: # TODO
Enabled: false
RSpec/NotToNot: # TODO: autocorrect
Enabled: false
RSpec/ScatteredSetup: # TODO: investigate if these are required
Enabled: false
RSpec/VerifiedDoubles: # TODO
Enabled: false
config = {}
RuboCop::Cop::Registry.all.each do |cop|
next if already_configured_departments.include?(cop.department)
next if already_configured_cops.include?(cop.cop_name)
next unless cop.support_autocorrect?
Style/BlockDelimiters: # TODO: autocorrect
Enabled: true
Exclude:
- spec/**/*_spec.rb
- spec/shared_examples/**/*.rb
Style/ClassAndModuleChildren: # TODO: autocorrect (unsafe)
Enabled: false
Style/DoubleNegation: # TODO: autocorrect (unsafe)
Enabled: false
Style/Dir: # TODO: autocorrect
Enabled: false
Style/FormatStringToken: # TODO: investigate if this complains about our i18n library
Enabled: false
Style/GuardClause: # TODO
Enabled: false
Style/IfUnlessModifier: # TODO: autocorrect
Enabled: false
Style/Lambda: # TODO: autocorrect
Enabled: false
Style/MethodCallWithArgsParentheses: # TODO: autocorrect
Enabled: false
Style/MethodCallWithoutArgsParentheses: # TODO: autocorrect
Enabled: false
Style/NumericLiterals: # TODO: autocorrect
Enabled: false
Style/NumericPredicate: # TODO: autocorrect (unsafe)
Enabled: false
Style/ParallelAssignment: # TODO: autocorrect (with probable exceptions)
Enabled: false
Style/PercentLiteralDelimiters: # TODO: autocorrect
Enabled: false
Style/PercentQLiterals: # TODO: autocorrect
Enabled: false
Style/RedundantSelf: # TODO: autocorrect
Enabled: false
Style/RegexpLiteral: # TODO: autocorrect
Enabled: false
Style/RescueModifier: # TODO
Severity: warning
Style/RescueStandardError: # TODO: autocorrect
EnforcedStyle: implicit
Enabled: false
Style/ReturnNil: # TODO: autocorrect (investigate violations)
Enabled: false
Style/SignalException: # TODO: autocorrect
Enabled: false
Style/StderrPuts: # TODO: autocorrect
Enabled: false
Style/SymbolArray: # TODO: autocorrect
Enabled: false
Style/TrailingCommaInArguments: # TODO: autocorrect
Enabled: false
Style/TrailingCommaInArrayLiteral: # TODO: autocorrect
Enabled: false
Style/TrailingCommaInHashLiteral: # TODO: autocorrect
Enabled: false
Style/WhileUntilModifier: # TODO: autocorrect
Enabled: false
Style/WordArray: # TODO: autocorrect
Enabled: false
Style/ZeroLengthPredicate: # TODO: autocorrect (unsafe)
Enabled: false
config[cop.cop_name] = { "AutoCorrect" => false }
end
config.to_yaml.sub(/^---\n/, "")
end
%>

8
Gemfile.d/.rubocop.yml Normal file
View File

@ -0,0 +1,8 @@
inherit_from:
- ../.rubocop.yml
Layout/IndentationConsistency:
Enabled: false # we purposely indent dependent gems
Rails:
Enabled: false # Rails isn't loaded yet

View File

@ -23,7 +23,7 @@
group :test do
dedicated_gemfile = ENV['BUNDLE_GEMFILE']&.end_with?('rubocop.rb')
gem 'gergich', '1.2.3', require: false
gem 'gergich', '2.0.0', require: false
gem 'mime-types-data', '3.2021.0901', require: false
gem 'rubocop', '1.19.1', require: false

View File

@ -22,7 +22,7 @@ GEM
zeitwerk (~> 2.2, >= 2.2.2)
ast (2.4.2)
concurrent-ruby (1.1.9)
gergich (1.2.3)
gergich (2.0.0)
httparty (~> 0.17)
sqlite3 (~> 1.4)
httparty (0.18.1)
@ -79,7 +79,7 @@ PLATFORMS
x86_64-darwin-20
DEPENDENCIES
gergich (= 1.2.3)
gergich (= 2.0.0)
mime-types-data (= 3.2021.0901)
rainbow (= 3.0.0)
rubocop (= 1.19.1)

View File

@ -27,8 +27,7 @@ gergich capture i18nliner 'rake i18n:check'
ruby script/brakeman
ruby script/tatl_tael
ruby script/stylelint
ruby script/rlint --optional --no-fail-on-offense
ruby script/rlint --boy-scout --heavy --no-fail-on-offense
ruby script/rlint --no-fail-on-offense
[ "${SKIP_ESLINT-}" != "true" ] && ruby script/eslint
ruby script/lint_commit_message

View File

@ -1,4 +1,3 @@
# coding: utf-8
# frozen_string_literal: true
lib = File.expand_path('../lib', __FILE__)
@ -15,7 +14,9 @@ Gem::Specification.new do |spec|
spec.test_files = spec.files.grep(%r{^spec/})
spec.require_paths = ["lib"]
spec.add_dependency "gergich", "1.2.1"
spec.add_dependency "gergich", "2.0.0"
spec.add_development_dependency "byebug", "~> 11.1"
spec.add_development_dependency "pry"
spec.add_development_dependency "pry-nav"
spec.add_development_dependency "rspec", "~> 3.5.0"

View File

@ -22,13 +22,13 @@ module DrDiff
attr_reader :diff
attr_reader :campsite
# campsite = true: consider relevant the severe linter errors near lines changed
def initialize(input, raw = true, campsite = true)
# campsite = true: consider relevant linter errors near lines changed
def initialize(input, raw: true, campsite: true)
@diff = (raw ? parse_raw_diff(input) : input)
@campsite = campsite
end
def relevant?(path, line_number, severe = false)
def relevant?(path, line_number, severe: false)
return false unless diff[path]
return true if line_number == 1 # whole-file comments are addressed to line 1

View File

@ -21,30 +21,25 @@ require "forwardable"
module DrDiff
class Manager
attr_reader :git
attr_reader :git, :git_dir, :campsite, :heavy, :base_dir, :severe_anywhere
private :git
attr_reader :git_dir
private :git_dir
attr_reader :campsite
private :campsite
attr_reader :heavy
private :heavy
attr_reader :base_dir
private :base_dir
private :severe_anywhere
# all levels: %w(error warn info)
SEVERE_LEVELS = %w(error warn).freeze
def initialize(git: nil, git_dir: nil, sha: nil, campsite: true, heavy: false, base_dir: nil)
def initialize(git: nil, git_dir: nil, sha: nil, campsite: true, heavy: false, base_dir: nil, severe_anywhere: true)
@git_dir = git_dir
@git = git || GitProxy.new(git_dir: git_dir, sha: sha)
@campsite = campsite
@heavy = heavy
@base_dir = base_dir || ""
@severe_anywhere = severe_anywhere
end
extend Forwardable
@ -67,17 +62,21 @@ module DrDiff
severe_levels: SEVERE_LEVELS)
command_comments = CommandCapture.run(format, command)
diff = DiffParser.new(git.diff, true, campsite)
diff = DiffParser.new(git.diff, raw: true, campsite: campsite)
result = []
command_comments.each do |comment|
path = comment[:path]
path = path[git_dir.length..-1] if git_dir
if heavy || diff.relevant?(path, comment[:position], severe?(comment[:severity], severe_levels))
comment[:path] = path unless include_git_dir_in_output
result << comment
end
severe = severe?(comment[:severity], severe_levels)
next unless heavy ||
severe && severe_anywhere ||
diff.relevant?(path, comment[:position], severe: severe) ||
comment[:corrected]
comment[:path] = path unless include_git_dir_in_output
result << comment
end
result

View File

@ -161,30 +161,30 @@ module DrDiff
end
it "is relevant anywhere in ranges if severe" do
expect(parser.relevant?("some_file.rb", 56, true)).to be(false)
expect(parser.relevant?("some_file.rb", 57, true)).to be(true)
expect(parser.relevant?("some_file.rb", 66, true)).to be(true)
expect(parser.relevant?("some_file.rb", 67, true)).to be(false)
expect(parser.relevant?("some_file.rb", 56, severe: true)).to be(false)
expect(parser.relevant?("some_file.rb", 57, severe: true)).to be(true)
expect(parser.relevant?("some_file.rb", 66, severe: true)).to be(true)
expect(parser.relevant?("some_file.rb", 67, severe: true)).to be(false)
end
context "with campsite mode turned off" do
let(:parser) { described_class.new(add_diff, true, false) }
let(:parser) { described_class.new(add_diff, raw: true, campsite: false) }
it "is only true for touched lines" do
expect(parser.relevant?("some_file.rb", 60, true)).to be(true)
expect(parser.relevant?("some_file.rb", 61, true)).to be(true)
expect(parser.relevant?("some_file.rb", 62, true)).to be(true)
expect(parser.relevant?("some_file.rb", 60, severe: true)).to be(true)
expect(parser.relevant?("some_file.rb", 61, severe: true)).to be(true)
expect(parser.relevant?("some_file.rb", 62, severe: true)).to be(true)
end
it "is not relevant for files in ranges that are not touched" do
expect(parser.relevant?("some_file.rb", 57, true)).to be(false)
expect(parser.relevant?("some_file.rb", 58, true)).to be(false)
expect(parser.relevant?("some_file.rb", 59, true)).to be(false)
expect(parser.relevant?("some_file.rb", 63, true)).to be(false)
expect(parser.relevant?("some_file.rb", 64, true)).to be(false)
expect(parser.relevant?("some_file.rb", 65, true)).to be(false)
expect(parser.relevant?("some_file.rb", 66, true)).to be(false)
expect(parser.relevant?("some_file.rb", 67, true)).to be(false)
expect(parser.relevant?("some_file.rb", 57, severe: true)).to be(false)
expect(parser.relevant?("some_file.rb", 58, severe: true)).to be(false)
expect(parser.relevant?("some_file.rb", 59, severe: true)).to be(false)
expect(parser.relevant?("some_file.rb", 63, severe: true)).to be(false)
expect(parser.relevant?("some_file.rb", 64, severe: true)).to be(false)
expect(parser.relevant?("some_file.rb", 65, severe: true)).to be(false)
expect(parser.relevant?("some_file.rb", 66, severe: true)).to be(false)
expect(parser.relevant?("some_file.rb", 67, severe: true)).to be(false)
end
end
end
@ -193,20 +193,20 @@ module DrDiff
let(:parser) { described_class.new(subtractive_diff) }
it 'respects the boundary of a removed diff set' do
expect(parser.relevant?("some_file.rb", 55, true)).to be(false)
expect(parser.relevant?("some_file.rb", 56, true)).to be(true)
expect(parser.relevant?("some_file.rb", 60, true)).to be(true)
expect(parser.relevant?("some_file.rb", 61, true)).to be(false)
expect(parser.relevant?("some_file.rb", 55, severe: true)).to be(false)
expect(parser.relevant?("some_file.rb", 56, severe: true)).to be(true)
expect(parser.relevant?("some_file.rb", 60, severe: true)).to be(true)
expect(parser.relevant?("some_file.rb", 61, severe: true)).to be(false)
end
context "with campsite mode turned off" do
let(:parser) { described_class.new(subtractive_diff, true, false) }
let(:parser) { described_class.new(subtractive_diff, raw: true, campsite: false) }
it "does not count deletions as relevant" do
expect(parser.relevant?("some_file.rb", 55, true)).to be(false)
expect(parser.relevant?("some_file.rb", 56, true)).to be(false)
expect(parser.relevant?("some_file.rb", 60, true)).to be(false)
expect(parser.relevant?("some_file.rb", 61, true)).to be(false)
expect(parser.relevant?("some_file.rb", 55, severe: true)).to be(false)
expect(parser.relevant?("some_file.rb", 56, severe: true)).to be(false)
expect(parser.relevant?("some_file.rb", 60, severe: true)).to be(false)
expect(parser.relevant?("some_file.rb", 61, severe: true)).to be(false)
end
end
end

View File

@ -75,12 +75,12 @@ spec/dr_diff_spec.rb}
:message =>
"[rubocop] Avoid using sleep.\n\n sleep 1\n ^^^^^^^\n",
:position => 5,
:severity => "warn" }
:severity => "convention" }
]
end
before :each do
expect(DiffParser).to receive(:new).with(git.diff, true, true).and_return(diff_parser)
expect(DiffParser).to receive(:new).with(git.diff, raw: true, campsite: true).and_return(diff_parser)
expect(CommandCapture).to receive(:run).with(format, command).and_return(command_capture_comments)
allow(diff_parser).to receive(:relevant?).and_return(true)
end
@ -105,7 +105,7 @@ spec/dr_diff_spec.rb}
path_without_git_dir = comment[:path][git_dir.length..-1]
expect(diff_parser).to receive(:relevant?).with(path_without_git_dir,
comment[:position],
true)
severe: false)
subject.comments(format: format, command: command)
end
@ -134,7 +134,7 @@ spec/dr_diff_spec.rb}
comment = command_capture_comments.first
expect(diff_parser).to receive(:relevant?).with(comment[:path],
comment[:position],
true)
severe: false)
subject.comments(format: format, command: command)
end
end

View File

@ -17,5 +17,6 @@
# You should have received a copy of the GNU Affero General Public License along
# with this program. If not, see <http://www.gnu.org/licenses/>.
$LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
require 'dr_diff'
require "byebug"

View File

@ -0,0 +1,5 @@
inherit_from:
- ../../../../../../../.rubocop.yml
Layout/EmptyLineAfterMagicComment:
Enabled: false # fixtures purposely have errors

View File

@ -9,6 +9,7 @@ linter_options = {
format: 'brakeman',
command: 'bundle exec brakeman --rails6 --quiet --format json --confidence-level 2',
append_files_to_command: false,
severe_anywhere: false
}
brakeman = Linter.new(linter_options)

View File

@ -42,7 +42,8 @@ class Linter
plugin: ENV['GERRIT_PROJECT'],
skip_file_size_check: false,
skip_wips: false,
base_dir: nil
base_dir: nil,
severe_anywhere: true
}.freeze
def initialize(options = {})
@ -87,7 +88,7 @@ class Linter
private
attr_reader *DEFAULT_OPTIONS.keys
attr_reader(*DEFAULT_OPTIONS.keys)
def git_dir
@git_dir ||= plugin && "gems/plugins/#{plugin}/"
@ -98,7 +99,7 @@ class Linter
end
def dr_diff
@dr_diff ||= ::DrDiff::Manager.new(git_dir: git_dir, sha: env_sha, campsite: campsite_mode, heavy: heavy_mode, base_dir: base_dir)
@dr_diff ||= ::DrDiff::Manager.new(git_dir: git_dir, sha: env_sha, campsite: campsite_mode, heavy: heavy_mode, base_dir: base_dir, severe_anywhere: severe_anywhere)
end
def wip?
@ -172,9 +173,13 @@ class Linter
end
comments.each do |comment|
message = +"[#{comment[:source]}] "
message << "#{comment[:rule]}: " if comment[:rule]
message << comment[:message]
draft.add_comment comment[:path],
comment[:position],
comment[:message],
message,
comment[:severity]
end
@ -189,12 +194,18 @@ class Linter
end
def pretty_comment(comment)
message = ""
message += "[#{comment[:severity]}]".colorize(:yellow)
message = +""
severity_color = severe_levels.include?(comment[:severity]) ? :red : :yellow
severity_color = :green if comment[:corrected]
message << "[#{comment[:severity]}]".colorize(severity_color)
unless comment[:cover_message]
message += " #{comment[:path].colorize(:light_blue)}:#{comment[:position]}"
message << " #{comment[:path].colorize(:light_blue)}:#{comment[:position]}"
end
message += " => #{comment[:message].colorize(:green)}"
message << " => "
message << "[Correctable] ".colorize(:yellow) if comment[:correctable]
message << "[Corrected] ".colorize(:green) if comment[:corrected]
message << "#{comment[:rule]}: " if comment[:rule]
message << comment[:message].colorize(:green)
puts message
end
end

View File

@ -18,14 +18,12 @@ linter_options = {
boyscout_mode: false
}
no_fail = false
optional = false
OptionParser.new do |opts|
# boy scout means treat everything as an error
opts.on("--boy-scout", "Treat all comments as errors") { linter_options[:boyscout_mode] = true }
# heavy means inspect entire files if a file was changed
opts.on("--heavy") { linter_options[:heavy_mode] = true }
opts.on("--optional", "Run against the optional rubocop ruleset, instead of the default") { optional = true }
opts.on("--plugin PLUGIN", "Inspect changes from the given plugin, instead of canvas-lms") do |v|
linter_options[:plugin] = v
end
@ -42,10 +40,7 @@ OptionParser.new do |opts|
end
opts.on("--summary", "Print a summary of offense counts by cop, instead of individual offenses") do
linter_options[:comment_post_processing] = proc do |comments|
grouped_comments = comments.group_by do |comment|
comment[:message] =~ %r{^\[rubocop\]( \[Corrected\])?( \[Correctable\])? ([A-Za-z/]+)}
$3
end
grouped_comments = comments.group_by { |comment| comment[:rule] }
require 'pp'
pp grouped_comments.transform_values(&:length).to_a.sort_by(&:last).reverse.to_h
@ -54,17 +49,14 @@ OptionParser.new do |opts|
end
opts.on("-a", "--auto-correct") do |_v|
linter_options[:auto_correct] = true
linter_options[:heavy_mode] = true
linter_options[:command] << " -a"
end
opts.on("-A", "--auto-correct-all") do |_v|
linter_options[:auto_correct] = true
linter_options[:heavy_mode] = true
linter_options[:command] << " -A"
end
opts.on("-x", "--fix-layout") do
linter_options[:auto_correct] = true
linter_options[:heavy_mode] = true
linter_options[:command] << " -x"
end
opts.on("-h", "--help", "Display this usage information") do
@ -73,10 +65,5 @@ OptionParser.new do |opts|
end
end.parse!
# without optional, we only run against the "enforced" config. this makes it so
# that jenkins will warn about a larger config, but the pre-commit hook can
# auto-correct against a much smaller config.
linter_options[:command] << " -c .rubocop.enforced.yml" unless optional
rlint = Linter.new(linter_options)
exit 1 if !rlint.run && !no_fail