Skip to content

config/default: Stop disabling all cops by default #117

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 22 commits into from

Conversation

issyl0
Copy link
Member

@issyl0 issyl0 commented Oct 10, 2022

  • This is incredibly confusing behaviour, it turns out: https://github.com/github/code-scanning/issues/7361, https://github.com/github/github/pull/241104.

  • People have been adding cops to github/github and they've not been running because with DisabledByDefault, nothing runs unless there's an explicit config stanza or it's already declared upstream in this gem.

  • Since github/github's RuboCop config also had DisabledByDefault and we wanted to set EnabledByDefault there to alleviate the above confusion, we couldn't: "cops cannot be both enabled by default and disabled by default".

  • This flips DisabledByDefault: true to EnabledByDefault: true falls back to the RuboCop default enable/disable settings, so that RuboCop config is easier to understand and the behaviour is more in line with what normal users expect.

  • I understand that DisabledByDefault was set to avoid RuboCop versions changing which have new cops set up, or existing cop config changes, that cause linting violations everywhere, but it's way worse for understanding how things work, as the issues/PRs above reveal! If there's something that causes a lot of violations, we can disable it either here or in the downstream app codebase. This shouldn't be too much of an issue because bumping this gem version or a RuboCop version requires an explicit PR/approval/deploy workflow with CI, so we can catch the really noisy things.

  • Part of https://github.com/github/code-scanning/issues/7361.

- This is _incredibly_ confusing behaviour, it turns out:
  github/code-scanning#7361,
  github/github#241104.
- People have been adding cops to `github/github` and they've not been
  running because with `DisabledByDefault`, nothing runs unless there's
  an explicit config stanza or it's already declared upstream in this
  gem.
- Since `github/github`'s RuboCop config also had `DisabledByDefault`
  and we wanted to set `EnabledByDefault` there to alleviate the above
  confusion, we couldn't: "cops cannot be both enabled by default and
  disabled by default".
- This flips `DisabledByDefault: true` to `EnabledByDefault: true`, so
  that RuboCop config is easier to understand and the behaviour is more
  in line with what normal users expect.
- I understand that `DisabledByDefault` was set to avoid RuboCop versions
  changing which have new cops set up, or existing cop config changes,
  that cause linting violations everywhere, but it's way worse for
  understanding how things work, as the issues/PRs above reveal! If
  there's something that causes a lot of violations, we can disable it
  either here or in the downstream app codebase. This shouldn't be too
  much of an issue because bumping this gem version or a RuboCop version
  requires an explicit PR/approval/deploy workflow with CI, so we can
  catch the really noisy things.
@issyl0
Copy link
Member Author

issyl0 commented Oct 10, 2022

Ah, good, now I have to go through all the new rules (at least the ones I can tell that showed up problems in this codebase) and either fix them here or disable them.

issyl0 added 19 commits October 10, 2022 12:30
- Since `EnabledByDefault: true`, we can slim this down to only the ones
  we want to disable either because the styleguide doesn't like the
  rules, or because the styleguide has no opinion yet.
- I added some more `Enabled: false` here for cops that are failing in
  the code in this gem and others, based on the information or lack of
  in our styleguide.
- This works because the RuboCop rule for line length isn't enabled by
  default (it never was in this gem for some reason). Some of these
  lines are pretty long now!
- Either the styleguide has no opinion on them (yet), or it doesn't like
  them, or they'd be quite disruptive.
- These either seemed arbitrary or had no accompanying styleguide rule that we've written yet.
@issyl0 issyl0 requested a review from a team October 10, 2022 13:45
@issyl0
Copy link
Member Author

issyl0 commented Oct 10, 2022

The code in this repo should now pass RuboCop. There are some arbitrary, and some styleguide-motivated Enabled: false for cops, and several TODOs that we should actually fix the things but they're really noisy so I chose not to do that now.

Lint/AssignmentInCondition is a great one, because it's a footgun, but it raises a lot of problems in this codebase alone so I dread to think of its impact on the monolith. Maybe that one can be our second rule enablement in this engineering initiative?

@@ -3,182 +3,68 @@ require:
- rubocop-performance

AllCops:
DisabledByDefault: true
EnabledByDefault: true
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that this repository should not declare either DisabledByDefault nor EnabledByDefault and leave that to the downstream inheritor of this configuration.

That way this ruleset can be completely verbose of "these are the baseline rules", and inheriting projects can choose to further inherit all of the Rubocop rules however they want.

I'm not 100% sure on this, I think it will have the same effect in this repository, but will effect downstream repositories.

Copy link
Member Author

@issyl0 issyl0 Oct 10, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Relevant to our chat earlier, maybe setting DisabledByDefault was so that whichever team first made this gem would be an authority on Ruby at GitHub, and other downstream consumers diverged for their own code style requirements. Is that maybe why it's not 100% compatible with the styleguide now?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oops, I shouldn't have written "this repository"; I specifically meant config/default.yml shouldn't define neither DisabledByDefault nor EnabledByDefault.

The rules for this repository, .rubocop.yml should probably have EnabledByDefault.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Riiiight. I see. Makes sense, I think?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So, to recap:

  • You'd like .rubocop.yml in this repository (the RuboCop config for the code in this gem) to set EnabledByDefault.
  • You would like config/default.yml (which all of the downstream consumers of this gem inherit their rules from) to not set either EnabledbyDefault or DisabledByDefault? That means that it's just using the default RuboCop behaviour, which is probably a safe bet.

I'm not sure what benefit this first thing has, since the RuboCop defaults are similar enough?

- This doesn't go back to `DisabledByDefault: true`, it takes a neutral
  stance to match whatever RuboCop's defaults are for enabling (or not)
  cops. Then it's up to the maintainers of this gem (us, the Hubber
  community, I guess) to decide the settings for the rules to include,
  and/or it's up to the downstream consumers of this gem to decide
  whether they want all the rules or just some of the rules as they are
  defined in here.
- I hope I'm understanding this correctly? I did go and read the sourc
  RuboCop configuration file for this:
  https://github.com/rubocop/rubocop/blob/d1270c468cdb9a211229e36aef8d568ae3bfe607/config/default.yml#L91-L102
@issyl0
Copy link
Member Author

issyl0 commented Oct 10, 2022

I guess now we get to decide who makes decisions about enabling new cops?

The following cops were added to RuboCop, but are not configured. Please set Enabled to either `true` or `false` in your `.rubocop.yml` file.

Please also note that you can opt-in to new cops by default by adding this to your config:
  AllCops:
    NewCops: enable
Gemspec/DeprecatedAttributeAssignment: # new in 1.30
  Enabled: true
Layout/LineContinuationLeadingSpace: # new in 1.31
  Enabled: true
Layout/LineContinuationSpacing: # new in 1.31
  Enabled: true
Layout/LineEndStringConcatenationIndentation: # new in 1.[18](https://github.com/github/rubocop-github/actions/runs/3221469313/jobs/5269442850#step:5:19)
  Enabled: true
Layout/SpaceBeforeBrackets: # new in 1.7
  Enabled: true
Lint/AmbiguousAssignment: # new in 1.7
  Enabled: true
Lint/AmbiguousOperatorPrecedence: # new in 1.21
  Enabled: true
Lint/AmbiguousRange: # new in 1.[19](https://github.com/github/rubocop-github/actions/runs/3221469313/jobs/5269442850#step:5:20)
  Enabled: true
Lint/ConstantOverwrittenInRescue: # new in 1.31
  Enabled: true
Lint/DeprecatedConstants: # new in 1.8
  Enabled: true
Lint/DuplicateRegexpCharacterClassElement: # new in 1.1
  Enabled: true
Lint/EmptyBlock: # new in 1.1
  Enabled: true
Lint/EmptyClass: # new in 1.3
  Enabled: true
Lint/EmptyInPattern: # new in 1.16
  Enabled: true
Lint/IncompatibleIoSelectWithFiberScheduler: # new in 1.[21](https://github.com/github/rubocop-github/actions/runs/3221469313/jobs/5269442850#step:5:22)
  Enabled: true
Lint/LambdaWithoutLiteralBlock: # new in 1.8
  Enabled: true
Lint/NoReturnInBeginEndBlocks: # new in 1.2
  Enabled: true
Lint/NonAtomicFileOperation: # new in 1.31
  Enabled: true
Lint/NumberedParameterAssignment: # new in 1.9
  Enabled: true
Lint/OrAssignmentToConstant: # new in 1.9
  Enabled: true
Lint/RedundantDirGlobSort: # new in 1.8
  Enabled: true
Lint/RefinementImportMethods: # new in 1.27
  Enabled: true
Lint/RequireRelativeSelfPath: # new in 1.[22](https://github.com/github/rubocop-github/actions/runs/3221469313/jobs/5269442850#step:5:23)
  Enabled: true
Lint/SymbolConversion: # new in 1.9
  Enabled: true
Lint/ToEnumArguments: # new in 1.1
  Enabled: true
Lint/TripleQuotes: # new in 1.9
  Enabled: true
Lint/UnexpectedBlockArity: # new in 1.5
  Enabled: true
Lint/UnmodifiedReduceAccumulator: # new in 1.1
  Enabled: true
Lint/UselessRuby2Keywords: # new in 1.[23](https://github.com/github/rubocop-github/actions/runs/3221469313/jobs/5269442850#step:5:24)
  Enabled: true
Naming/BlockForwarding: # new in 1.[24](https://github.com/github/rubocop-github/actions/runs/3221469313/jobs/5269442850#step:5:25)
  Enabled: true
Security/CompoundHash: # new in 1.28
  Enabled: true
Security/IoMethods: # new in 1.22
  Enabled: true
Style/ArgumentsForwarding: # new in 1.1
  Enabled: true
Style/CollectionCompact: # new in 1.2
  Enabled: true
Style/DocumentDynamicEvalDefinition: # new in 1.1
  Enabled: true
Style/EndlessMethod: # new in 1.8
  Enabled: true
Style/EnvHome: # new in 1.29
  Enabled: true
Style/FetchEnvVar: # new in 1.28
  Enabled: true
Style/FileRead: # new in 1.24
  Enabled: true
Style/FileWrite: # new in 1.24
  Enabled: true
Style/HashConversion: # new in 1.10
  Enabled: true
Style/HashExcept: # new in 1.7
  Enabled: true
Style/IfWithBooleanLiteralBranches: # new in 1.9
  Enabled: true
Style/InPatternThen: # new in 1.16
  Enabled: true
Style/MapCompactWithConditionalBlock: # new in 1.30
  Enabled: true
Style/MapToHash: # new in 1.24
  Enabled: true
Style/MultilineInPatternThen: # new in 1.16
  Enabled: true
Style/NegatedIfElseCondition: # new in 1.2
  Enabled: true
Style/NestedFileDirname: # new in 1.[26](https://github.com/github/rubocop-github/actions/runs/3221469313/jobs/5269442850#step:5:27)
  Enabled: true
Style/NilLambda: # new in 1.3
  Enabled: true
Style/NumberedParameters: # new in 1.22
  Enabled: true
Style/NumberedParametersLimit: # new in 1.22
  Enabled: true
Style/ObjectThen: # new in 1.28
  Enabled: true
Style/OpenStructUse: # new in 1.23
  Enabled: true
Style/QuotedSymbols: # new in 1.16
  Enabled: true
Style/RedundantArgument: # new in 1.4
  Enabled: true
Style/RedundantInitialize: # new in 1.[27](https://github.com/github/rubocop-github/actions/runs/3221469313/jobs/5269442850#step:5:28)
  Enabled: true
Style/RedundantSelfAssignmentBranch: # new in 1.19
  Enabled: true
Style/SelectByRegexp: # new in 1.22
  Enabled: true
Style/StringChars: # new in 1.12
  Enabled: true
Style/SwapValues: # new in 1.1
  Enabled: true
Performance/AncestorsInclude: # new in 1.7
  Enabled: true
Performance/BigDecimalWithNumericArgument: # new in 1.7
  Enabled: true
Performance/BlockGivenWithExplicitBlock: # new in 1.9
  Enabled: true
Performance/CollectionLiteralInLoop: # new in 1.8
  Enabled: true
Performance/ConcurrentMonotonicTime: # new in 1.12
  Enabled: true
Performance/ConstantRegexp: # new in 1.9
  Enabled: true
Performance/MapCompact: # new in 1.11
  Enabled: true
Performance/MethodObjectAsBlock: # new in 1.9
  Enabled: true
Performance/RedundantEqualityComparisonBlock: # new in 1.10
  Enabled: true
Performance/RedundantSortBlock: # new in 1.7
  Enabled: true
Performance/RedundantSplitRegexpArgument: # new in 1.10
  Enabled: true
Performance/RedundantStringChars: # new in 1.7
  Enabled: true
Performance/ReverseFirst: # new in 1.7
  Enabled: true
Performance/SortReverse: # new in 1.7
  Enabled: true
Performance/Squeeze: # new in 1.7
  Enabled: true
Performance/StringIdentifierArgument: # new in 1.13
  Enabled: true
Performance/StringInclude: # new in 1.7
  Enabled: true
Performance/Sum: # new in 1.8
  Enabled: true

@issyl0
Copy link
Member Author

issyl0 commented Oct 10, 2022

We could automatically opt-in, and for every new RuboCop version we update to we could say "how noisy is this to autofix" and make a decision then (ie, in the downstream consumer project), and then eventually bubble those choices up to here?

Comment on lines -8 to +6
Bundler/DuplicatedGem:
Enabled: true

Bundler/OrderedGems:
Enabled: true

GitHub/InsecureHashAlgorithm:
Enabled: true
Gemspec/DependencyVersion:
Enabled: false
Copy link
Member Author

@issyl0 issyl0 Oct 10, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For some of these new ones that fail RuboCop in the code in this gem: should we put them in here, the global config for the gem and the one that all its downstream consumers use, or should we put them in .rubocop.yml inside this repo only?

I guess I'm now concerned, after @bensheldon's comments, about this gem's config not being a reflection of the styleguide? Who gets to make decisions on what we include in the styleguide, and hence who gets to "control" what sensible default RuboCop configuration we send out into the world?

@issyl0
Copy link
Member Author

issyl0 commented Oct 10, 2022

I also don't want to conflate our two projects here. The engineering initiative that I'm working on was focused on github/github and moving the needle on styleguide compliance there, and also enforcing more RuboCop rules so that humans didn't have to do so much boring, tedious style linting on PRs.

To some extent it feels like wading in here is too much. But we do need to remove DisabledByDefault from this gem for us to be able to continue with the github/github work, since the inheritance and the state of the world is really hard to understand.

@bensheldon
Copy link
Contributor

@issyl0 I hope this is a helpful set of suggestions to move this PR forward:

  • limit this PR to just removing the DisabledByDefault rule.
  • don't change any other rules in default/config.yml
  • autocorrect/correct the resulting lint errors in this repo

@issyl0
Copy link
Member Author

issyl0 commented Oct 10, 2022

Very helpful, thanks!

@issyl0
Copy link
Member Author

issyl0 commented Oct 10, 2022

I'll close this and open another set of PRs as this one has got long and messy. But the conversation is still super valuable!

@bensheldon
Copy link
Contributor

@issyl0 great! One other suggestion: if, during correcting, you discover there are some rules that you don't like, add them to this project's .rubocop.yml (which I don't think requires any review.

Then separately, we can decide which things should go into config/default.yml for everyone.

I think that'll keep the core/necessary changes flowing through.

@issyl0 issyl0 closed this Oct 10, 2022
@issyl0 issyl0 deleted the rubocop-enabled-by-default branch October 10, 2022 18:58
issyl0 added a commit that referenced this pull request Oct 10, 2022
- The `DisabledByDefault` config option made it so that "all cops in the
  default configuration are disabled, and only cops in user configuration
  are enabled", which makes cops "opt-in rather than opt-out"
  (source: https://github.com/rubocop/rubocop/blob/d1270c468cdb9a211229e36aef8d568ae3bfe607/config/default.yml#L91-L102).

- It's not immediately obvious that this gem has this config option,
  and it's used in a lot of GitHub Ruby projects. This means that
  people may write new, custom cops in downstream projects, with no
  configuration in `.rubocop.yml`, and then they never run because all
  cops are disabled unless explicitly enabled or otherwise configured
  with `Include`/`Exclude`.

- This change is a follow-up to the great conversations had in
  #117, and makes this gem
  take a more neutral stance to match whatever RuboCop's defaults are
  for enabling (or not) cops. Then it's up to the maintainers of this
  gem and the deciders of our styleguide to pick the settings for the
  rules to include, and/or it's up to the downstream consumers of this
  gem to decide whether they want all the rules or just some of the rules
  as they are defined in here.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants