<commit_before>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
  NewCops: enable

Bundler:
  Severity: error

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
  # don't specify required_ruby_version in the rest to reduce
  # maintenance pain when updating ruby versions
  Enabled: false

Layout:
  Severity: error

Lint:
  Severity: error
Lint/AmbiguousBlockAssociation:
  IgnoredMethods:
    - change
    - not_change
    - raise_error
Lint/NoFileUtilsRmRf:
  Severity: warning # intended for specs; not enforced
Lint/NoSleep:
  Severity: warning # intended for specs; not enforced
Lint/NonLocalExitFromIterator:
  Enabled: false # SnR is too low because of how often this construct is used
Lint/RedundantCopDisableDirective:
  Enabled: false # can't have this enabled until https://github.com/rubocop/rubocop/issues/10263
Lint/SafeNavigationConsistency:
  Enabled: false # https://github.com/rubocop/rubocop/issues/9816
Lint/UnusedBlockArgument:
  AutoCorrect: false # force the engineer to think about how come it's unused, instead of silently _ prefixing it
Lint/UnusedMethodArgument:
  AllowUnusedKeywordArguments: true # there's no way to mark a kwarg as unused
  AutoCorrect: false # force the engineer to think about how come it's unused, instead of silently _ prefixing it

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

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

Naming:
  Severity: error
Naming/HeredocDelimiterNaming:
  ForbiddenDelimiters:
    # negative regex - these are the _allowed_ delimiters
    # any you add should describe the format of the data, not describe
    # what the data is for. this allows editors to syntax highlight
    - ^(?!AST|BASE64|CSV|GQL|HTML|JS|MD|PEM|REGEX|RUBY|SQL|SRT|TEXT|XML|YAML|PATTERN).+$

Performance:
  Severity: error
Performance/Casecmp:
  Enabled: false # casecmp(other).zero? is a bad suggestion because it's not Unicode-aware (also it's less clear)
Performance/CollectionLiteralInLoop:
  Severity: convention # not auto-correctable; can be a pain to fix and isn't necessarily performance critical
Performance/MethodObjectAsBlock:
  Enabled: false # decreases expressiveness

Rails:
  Severity: error
Rails/ApplicationRecord:
  Enabled: false # we never bothered creating an ApplicationRecord
Rails/Blank:
  UnlessPresent: false # allow `unless foo.present?`
Rails/ContentTag:
  Exclude:
    - "**/db/migrate/*" # this cop is for views, not migrations, where it gets confused with outrigger
    - "doc/**/*"
Rails/DynamicFindBy:
  AllowedMethods:
    - find_by_confirmation_code # CommunicationChannel
    - find_by_signature # AssetSignature
    - find_by_domain # Account
    - find_by_name # PluginSetting
    - find_by_asset_string # ApplicationRecord
    - find_by_pseudonym_credentials # SessionPersistenceToken
    - find_by_quiz # Quizzes::OutstandingQuizSubmissionManager
Rails/HasManyOrHasOneDependent:
  Enabled: false # legacy code + most things we soft delete anyway
Rails/HelperInstanceVariable:
  Enabled: false # legacy code
Rails/NegateInclude:
  Enabled: false # exclude? isn't as intuitive as !include?
Rails/Present:
  UnlessBlank: false # allow `unless foo.blank?`
Rails/SkipsModelValidations:
  Enabled: false # Canvas skips validations in many places for optimization reasons
Rails/WhereExists:
  EnforcedStyle: where

RSpec:
  Severity: error
RSpec/AnyInstance:
  Enabled: false # while using an instance double would be preferable, it's a pain
RSpec/DescribedClass:
  Enabled: false # we haven't used it, and it seems antithetical to RSpec/NamedSubject
RSpec/ExampleLength:
  Enabled: false # this is a Metrics-style cop
RSpec/ExpectInHook:
  Enabled: false # follows RSpec/MultipleExpectations
RSpec/InstanceVariable:
  Enabled: false # legacy code
RSpec/MessageSpies:
  Enabled: false # we don't use spies
RSpec/MultipleExpectations:
  Enabled: false # we don't write specs in this style
RSpec/MultipleMemoizedHelpers:
  Enabled: false # complicated setup is sometimes necessary
RSpec/NestedGroups:
  Enabled: false # legacy code
RSpec/SubjectStub:
  Enabled: false # yes, canvas is big and complicated sometimes
RSpec/StubbedMock:
  Enabled: false # this style goes along with spies

RSpec/Rails:
  Severity: error

Security:
  Severity: error
Security/YAMLLoad:
  # technically even YAML.load is fairly safe in Canvas because we override it and only allow certain types
  # but still avoid it if you can.
  Severity: warning
  AutoCorrect: false

Specs/EnsureSpecExtension:
  Exclude:
    - spec/shared_examples/**/*

Style:
  Severity: error
Style/Alias:
  EnforcedStyle: prefer_alias_method # https://github.com/rubocop/ruby-style-guide/issues/821
Style/BlockDelimiters:
  IgnoredMethods: []
Style/Documentation:
  Enabled: false # most things don't need to be documented
Style/DoubleNegation:
  Enabled: false # we use double negation, even outside of return context, to get an actual true/false for various API results
Style/EmptyElse:
  EnforcedStyle: empty # explicit nil indicates programmer intent
Style/FloatDivision:
  Enabled: false # inherently dangerous cop because the args may not even be integers, and only upside is maybe saving 4 characters
Style/FormatStringToken:
  Enabled: false # I18n requires template style, but ohter code uses annotated style, and there are some trivial unannotted that don't really need to be annotated
Style/HashSyntax:
  EnforcedStyle: ruby19_no_mixed_keys
Style/IfUnlessModifier:
  # see also https://github.com/rubocop/rubocop/discussions/10048
  Enabled: false # can obscure important decisions or put too much code in a line
Style/MultilineBlockChain:
  Enabled: false # this is common when building up a large API result
Style/NumericPredicate:
  Enabled: false # `> 0` can be easier to read than `.positive?`
Style/ParallelAssignment:
  Enabled: false # most uses are legitimate deconstruction or value swapping
Style/PercentQLiterals:
  EnforcedStyle: upper_case_q
Style/PerlBackrefs:
  Enabled: false # Regexp.last_match(1) is far worse than $1
Style/RescueStandardError:
  EnforcedStyle: implicit
Style/ReturnNil:
  Enabled: false # explicit nil is okay when a method is expected to have a return value
Style/SpecialGlobalVars:
  Enabled: false # $! and $? are fine
Style/StringLiterals:
  EnforcedStyle: double_quotes
Style/StringLiteralsInInterpolation:
  EnforcedStyle: double_quotes
Style/SymbolArray:
  MinSize: 3
Style/TernaryParentheses:
  EnforcedStyle: require_parentheses_when_complex
Style/WhileUntilModifier:<commit_msg>rubocop: reconfigure Style/SoleNestedConditional<commit_after>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
  NewCops: enable

Bundler:
  Severity: error

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
  # don't specify required_ruby_version in the rest to reduce
  # maintenance pain when updating ruby versions
  Enabled: false

Layout:
  Severity: error

Lint:
  Severity: error
Lint/AmbiguousBlockAssociation:
  IgnoredMethods:
    - change
    - not_change
    - raise_error
Lint/NoFileUtilsRmRf:
  Severity: warning # intended for specs; not enforced
Lint/NoSleep:
  Severity: warning # intended for specs; not enforced
Lint/NonLocalExitFromIterator:
  Enabled: false # SnR is too low because of how often this construct is used
Lint/RedundantCopDisableDirective:
  Enabled: false # can't have this enabled until https://github.com/rubocop/rubocop/issues/10263
Lint/SafeNavigationConsistency:
  Enabled: false # https://github.com/rubocop/rubocop/issues/9816
Lint/UnusedBlockArgument:
  AutoCorrect: false # force the engineer to think about how come it's unused, instead of silently _ prefixing it
Lint/UnusedMethodArgument:
  AllowUnusedKeywordArguments: true # there's no way to mark a kwarg as unused
  AutoCorrect: false # force the engineer to think about how come it's unused, instead of silently _ prefixing it

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

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

Naming:
  Severity: error
Naming/HeredocDelimiterNaming:
  ForbiddenDelimiters:
    # negative regex - these are the _allowed_ delimiters
    # any you add should describe the format of the data, not describe
    # what the data is for. this allows editors to syntax highlight
    - ^(?!AST|BASE64|CSV|GQL|HTML|JS|MD|PEM|REGEX|RUBY|SQL|SRT|TEXT|XML|YAML|PATTERN).+$

Performance:
  Severity: error
Performance/Casecmp:
  Enabled: false # casecmp(other).zero? is a bad suggestion because it's not Unicode-aware (also it's less clear)
Performance/CollectionLiteralInLoop:
  Severity: convention # not auto-correctable; can be a pain to fix and isn't necessarily performance critical
Performance/MethodObjectAsBlock:
  Enabled: false # decreases expressiveness

Rails:
  Severity: error
Rails/ApplicationRecord:
  Enabled: false # we never bothered creating an ApplicationRecord
Rails/Blank:
  UnlessPresent: false # allow `unless foo.present?`
Rails/ContentTag:
  Exclude:
    - "**/db/migrate/*" # this cop is for views, not migrations, where it gets confused with outrigger
    - "doc/**/*"
Rails/DynamicFindBy:
  AllowedMethods:
    - find_by_confirmation_code # CommunicationChannel
    - find_by_signature # AssetSignature
    - find_by_domain # Account
    - find_by_name # PluginSetting
    - find_by_asset_string # ApplicationRecord
    - find_by_pseudonym_credentials # SessionPersistenceToken
    - find_by_quiz # Quizzes::OutstandingQuizSubmissionManager
Rails/HasManyOrHasOneDependent:
  Enabled: false # legacy code + most things we soft delete anyway
Rails/HelperInstanceVariable:
  Enabled: false # legacy code
Rails/NegateInclude:
  Enabled: false # exclude? isn't as intuitive as !include?
Rails/Present:
  UnlessBlank: false # allow `unless foo.blank?`
Rails/SkipsModelValidations:
  Enabled: false # Canvas skips validations in many places for optimization reasons
Rails/WhereExists:
  EnforcedStyle: where

RSpec:
  Severity: error
RSpec/AnyInstance:
  Enabled: false # while using an instance double would be preferable, it's a pain
RSpec/DescribedClass:
  Enabled: false # we haven't used it, and it seems antithetical to RSpec/NamedSubject
RSpec/ExampleLength:
  Enabled: false # this is a Metrics-style cop
RSpec/ExpectInHook:
  Enabled: false # follows RSpec/MultipleExpectations
RSpec/InstanceVariable:
  Enabled: false # legacy code
RSpec/MessageSpies:
  Enabled: false # we don't use spies
RSpec/MultipleExpectations:
  Enabled: false # we don't write specs in this style
RSpec/MultipleMemoizedHelpers:
  Enabled: false # complicated setup is sometimes necessary
RSpec/NestedGroups:
  Enabled: false # legacy code
RSpec/SubjectStub:
  Enabled: false # yes, canvas is big and complicated sometimes
RSpec/StubbedMock:
  Enabled: false # this style goes along with spies

RSpec/Rails:
  Severity: error

Security:
  Severity: error
Security/YAMLLoad:
  # technically even YAML.load is fairly safe in Canvas because we override it and only allow certain types
  # but still avoid it if you can.
  Severity: warning
  AutoCorrect: false

Specs/EnsureSpecExtension:
  Exclude:
    - spec/shared_examples/**/*

Style:
  Severity: error
Style/Alias:
  EnforcedStyle: prefer_alias_method # https://github.com/rubocop/ruby-style-guide/issues/821
Style/BlockDelimiters:
  IgnoredMethods: []
Style/Documentation:
  Enabled: false # most things don't need to be documented
Style/DoubleNegation:
  Enabled: false # we use double negation, even outside of return context, to get an actual true/false for various API results
Style/EmptyElse:
  EnforcedStyle: empty # explicit nil indicates programmer intent
Style/FloatDivision:
  Enabled: false # inherently dangerous cop because the args may not even be integers, and only upside is maybe saving 4 characters
Style/FormatStringToken:
  Enabled: false # I18n requires template style, but ohter code uses annotated style, and there are some trivial unannotted that don't really need to be annotated
Style/HashSyntax:
  EnforcedStyle: ruby19_no_mixed_keys
Style/IfUnlessModifier:
  # see also https://github.com/rubocop/rubocop/discussions/10048
  Enabled: false # can obscure important decisions or put too much code in a line
Style/MultilineBlockChain:
  Enabled: false # this is common when building up a large API result
Style/NumericPredicate:
  Enabled: false # `> 0` can be easier to read than `.positive?`
Style/ParallelAssignment:
  Enabled: false # most uses are legitimate deconstruction or value swapping
Style/PercentQLiterals:
  EnforcedStyle: upper_case_q
Style/PerlBackrefs:
  Enabled: false # Regexp.last_match(1) is far worse than $1
Style/RescueStandardError:
  EnforcedStyle: implicit
Style/ReturnNil:
  Enabled: false # explicit nil is okay when a method is expected to have a return value
Style/SoleNestedConditional:
  AllowModifier: true # it makes lines too long and complicated otherwise
Style/SpecialGlobalVars:
  Enabled: false # $! and $? are fine
Style/StringLiterals:
  EnforcedStyle: double_quotes
Style/StringLiteralsInInterpolation:
  EnforcedStyle: double_quotes
Style/SymbolArray:
  MinSize: 3
Style/TernaryParentheses:
  EnforcedStyle: require_parentheses_when_complex
Style/WhileUntilModifier:
{'fraction_non_alphanumeric': 0.06792936485331814, 'fraction_numerical': 0.004272287097692965, 'mean_word_length': 4.665590964098427, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 5, 'https://': 8, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3651882', 'n_tokens_mistral': 4395, 'n_tokens_neox': 4177, 'n_words': 1420}