Now in Typescript, I haven't found a lot of tools to calculate,visualize and track these stats. Metric-fu was amazing.
That said, I tend to take a much more lean approach to linting these days. I try to only include lints that are actionable, likely to lead to real bugs, and have no false positives. Everything else feels like it's better handled in code review. If you don't know why your function is too complex and difficult to read, I don't want you to rewrite it just to satisfy a robot that's following arbitrary rules! I want to be able to have a discussion with you about proper techniques for splitting apart code.
But there's definitely people who go the other way entirely and build incredibly strict ESLint configurations, so looking for those might help you if that's what you want.
--
I think the best thing that these tools give, above all else, is a way to settle petty opinions in a team. It’s why there is value in rules that either conflict with each other or are configurable so as to meet the expectations of a given team.
I kept telling him that the whackamole is a sign to rework things at a higher level - that the Rubocop rule catches symptoms, and that he needed to address the cause, but…
PS - to be clear, I love Rubocop and swear by it. In that circumstance, I needed to introduce it differently, is all.
Yeah this is huge. So often I get my PRs rejected because one dev has their own personal preference for formatting something. With Rubocop I can tell them to go submit a PR themselves to make that preference a rule and we can all discuss it and enforce it / autoformat it going forward. But for now, it won't be blocking my change going out.
[1] https://github.com/rails/rubocop-rails-omakase [2] https://github.com/standardrb/standard
> ...
> # - For small loops, you can just use normal conditions instead of `next`.
This rule will just end up with devs writing this:
array.each do |elem|
if condition
if another_condition
if yet_another_condition
do_something
end
end
end
end
Rather than the much easier to parse: array.each do |elem|
next if !condition
next if !another_condition
next if !yet_another_condition
do_something
end
You may think it really really doesn't matter, to the point that whatever form should be accepted. But then, would you accept my "def foo (x =true ,y= false )"? I've seen enough PRs with that kind of code to know that people will submit it one day.
For Python, I use ruff to autoreformat my code into a consistent style. The CI pipeline fails the PR if the style is violated it. Fixing it is a one-liner. Actually, if you use VSCode’s ruff extension, a zero-liner, since it auto-formats on save.
For Java, I use Diffplug Spotless for a similar experience.
One advantage of forcing the code to be auto-formatted, is it makes diffs cleaner - you eliminate diffs where someone just changed the code style, since the code style never changes.
But I do personally appreciate the tidiness of code-consistency.
this is an override in your project's .rubocop.yml
For me it's a bit opposite, I use and appreciate rubocop for simple formatting, not all of the rules but some of them, where autocorrect works. Recently I reformatted a big old project which was written by pretty sloppy developers who didn't care about whitespace, and it's just easier to work with now.
But I truly hate when rubocop tries to be smart about method calls, amount of lines in methods and amount methods or some other "code smell" metric.
yes, the tool allows to check for it, but it's not THAT smart. I have reasons. I'd happy to explain those reasons on code review to a human, but I'm not that happy to appease a dumb tool.
So, please do it as rails does, use bare minimals, something like https://github.com/rails/rubocop-rails-omakase
and ask other developers to stay away from .rubocop.yml
Even worse, it gives simple tools to write plugins to sniff more logic related stuff, and I've seen projects where developers really went overboard with it.