-
Notifications
You must be signed in to change notification settings - Fork 0
DT-462: Add RFC for Reek configuration #5
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
base: main
Are you sure you want to change the base?
Changes from 2 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
# Default Reek Configuration | ||
|
||
## The Problem | ||
|
||
We like to use Reek in many of our projects as one of the tools to aid in improving the code quality, but we do not have a clear expected way to use Reek in the different projects we use and we have no clear guidelines about when to make exception or changes to its configuration. | ||
|
||
## Proposed initial Reek configuration | ||
|
||
This RFC is a proposal of a default Reek configuration file that we would use in established projects to reduce the number of warnings and the need of exceptions that we see with the [default configuration](https://github.com/troessner/reek/blob/a8649370ced77dd0e798b00dc97ff916f68bb002/docs/defaults.reek.yml), and to also define some guideline or expectation on how we can decide when to add exceptions and modifications for different needs. | ||
|
||
### Default .reek configuration file | ||
|
||
This file is meant to be added in the root of the project as `.reek.yml` to handle common cases of Reek warnings that will want either disabled or reconfigured based on what we've seen in many projects. | ||
|
||
It's a combination of the [official `rails-friendly` configuration recommended in the Reek's README](https://github.com/troessner/reek?tab=readme-ov-file#working-with-rails) and some changes to the default rules. | ||
|
||
```yml | ||
detectors: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think this is useful too.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. sounds good There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I wonder if we should also add There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. added these 3 accepted short names There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I wonder if we should add There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sounds good to me |
||
IrresponsibleModule: | ||
enabled: false # we don't really add module descriptions ever | ||
TooManyStatements: | ||
max_statements: 10 # original is 5 | ||
DuplicateMethodCall: | ||
max_calls: 3 # original is 1 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is this enough for tests? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. what do you mean? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe I am wrong, but from what I remember the duplicate method calls happen often in tests when you are calling a method several times?? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I just tried calling a method multiple times in a single test and reek doesn't complain about it I'm not sure how it works internally but it seems it won't complain during tests? we can always change this later to disable it for the test and spec directories I guess if it starts creating issues (maybe there's some edge case I don't know how to trigger) |
||
NilCheck: | ||
enabled: false # in some projects were this was enabled, it was a false positive being ignored | ||
UnusedPrivateMethod: | ||
enabled: true # default is false, we are still disabling it for controllers and models below | ||
UtilityFunction: | ||
public_methods_only: true # original is false | ||
|
||
directories: # reek's recommendation for Rails applications unless a comment is added | ||
"app/controllers": | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In the past I have found the following helpful in controllers too:
FeatureEnvy: It is easy for controller methods to interact with other parts of the application There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. do you think those are better fully disabled or maybe add as exceptions when needed? I'm running There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. maybe we can disable TooManyMethods for controllers and models too? I don't think it adds that much value (I think we are already good at not putting methods where they don't belong, and when they are in the right place it would be annoying to have reek complain just because of the number) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I am onboard with disabling |
||
NestedIterators: | ||
max_allowed_nesting: 2 | ||
UnusedPrivateMethod: | ||
enabled: false | ||
Comment on lines
+41
to
+42
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm wondering if it wouldn't be better to have it be true. Even in controllers and models, if it's unused, wouldn't we want to remove them? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. the problem with this rule is that (at least from my tests), it's not smart enough to detect that you are referencing a private method in a callback, as in we have that enabled above in general, but we are disabling them for controllers and models There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. it was showing many false positives saying a private method was not used when it was used in a callback |
||
InstanceVariableAssumption: | ||
enabled: false | ||
TooManyInstanceVariables: | ||
enabled: false # instance variables are the way to pass data to views, it's expected | ||
"app/helpers": | ||
UtilityFunction: | ||
enabled: false | ||
"app/mailers": | ||
InstanceVariableAssumption: | ||
enabled: false | ||
"app/models": | ||
InstanceVariableAssumption: | ||
enabled: false | ||
UnusedPrivateMethod: | ||
enabled: false | ||
"db/migrate": | ||
FeatureEnvy: | ||
enabled: false # keeps complaining about `t.string :col_name` as feature envy calling `t` more than `self` | ||
UncommunicativeVariableName: | ||
enabled: false # complains `t` is uncommunicative, but it's a common short name for `table` | ||
TooManyStatements: | ||
enabled: false # long tables require many statements, reek keeps complaining about them | ||
DuplicateMethodCall: | ||
enabled: false # complains about duplicated methods when a migration creates more than 1 table, which cannot be "fixed" | ||
UtilityFunction: | ||
enabled: false # complains about utility functions in generated migrations, it's ok to have utility functions in migrations | ||
|
||
exclude_paths: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. we are already disabling many checks for the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't know if there is much value in reeking |
||
- node_modules # in case any node package has a .rb file (like the styleguide) | ||
- vendor # in case gems are bundle inside the project's folder vendor folder | ||
``` | ||
|
||
### Exceptions and :reek:\* Comments | ||
|
||
When applying this configuration, projects will still need exceptions in some cases where the code smell is not flagging code we want to change or when there's a warning on code that's in the same file but out of the scope of the work done. | ||
|
||
It is expected that the team working on a given project will keep an eye when these exceptions are used, and there should be a clear explanation to skip a code smell instead of fixing it (which is a valid thing to do, but shouldn't be done just in order to not address it). | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think I'd like some examples of this. I don't know of any off the top of my head, but I'm only thinking that, situationally, if a smell requires a fix that we know the client doesn't really care about or that, in our evaluation, isn't worth the time out of the project it would take to fix it, then we could skip it. Is that it? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this is not for client project, it's only for our internal projects and example here will be that with these defaults, when we run reek in fastruby.io/ombulabs.com/points we will have reek code smells, if something reek complains about is not worth the time to fix it (maybe a method is long because it has to be long, or maybe it makes total sense to have a utility function in a file and moving it somewhere else would make it less readable), then we can add reek comments to skip it There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. another example could be a private method in some class that is not used explicitly but because it's used by some There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. the main idea for this is to not encourage people to just add There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. and this can also help use improve these defaults, if we see something that gets skipped a lot, we might be able to change these defaults based on those reasons, but we need a reason |
||
|
||
## How is this going to impact our internal teams and their day to day? | ||
|
||
In the near future we plan to adapt this configuration in these projects: | ||
|
||
- FastRuby.io | ||
- OmbuLabs.com | ||
- Points | ||
|
||
Other project will not adapt this configuration. We expect Ruby and Rails projects to reach certain maturity before we adapt these standards. | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm curious about this part, while I understand not wanting to slow down development in these smaller, newer projects...at what point do you add this, and how much time does it then take to go back and make sure everything is agreeing with reek standards? Where will the line fall for us? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I feel like this is answered below, somewhat, but now I'm wondering at what point do we consider a project is not an MVP/Prototype or a one off internal tool that might be obsolete in a year... There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. cc @etagwerker @ABizzinotto here, I don't know if we have a clear definition of when this crosses that line (for example, in that list we are not listing UpgradeJS.com) one thing though is that when we want to add reek to a project, it can be added with TODOs to address things gradually, it doesn't need to be something like "we add reek and now we have to fix all the smells", it's more like "we add reek, and we can address the smells gradually over time along with other changes" There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Won't that break the build though? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. if we add the reek ignore comments it shouldn't break the builds, it would be useful to flag the comments as something that is agreed to be ignore vs the ones we ignore to deal with them later with a TODO |
||
## What projects are not a good fit for this new standard? | ||
|
||
We do NOT want to adapt this standard on these types of projects: | ||
|
||
- Prototypes | ||
- Unproven MVPs that might be discarded | ||
- One-off internal tools that might be obsolete in a year | ||
|
||
## What this file is NOT | ||
|
||
There will never be a single Reek configuration file to match the needs of all projects we have, this file is only a starting point with some known generic settings. | ||
|
||
## What we are looking as comments | ||
|
||
For this RFC we are expecting comments of different types: | ||
|
||
- if you disagree with any of the proposed defaults, let us know | ||
- if you think another setting that is not listed here should have a different config, let us know | ||
- if you think it's not clear when a code smell can be skipped and you have some examples from public projects, we can try to discuss and improve the guidelines on when to skip them with links | ||
- if you think any other common rails directory should have different rules, let us know |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
would it be possible to propose a new rule? if so, where is the best place to do it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
comments here in the PR is the place for that