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
Add the option to instantiate the same rule more than once #6738
Comments
Hey, I just stumbled upon this issue. I think I have a use case:
I have a custom annotation for suppressing the rule that forbids Am I correct in my understanding that there is currently no other workaround, since there can only be one instance of |
You are correct, that's exactly the use case. Could I ask you how do you imagine the configuration should look like to make your use case work? |
I need to write down all my thoughts about Rule/Issue/Finding and all that part of the detekt API: We need to talk about rule ids. Right now it's easy! Every That works when you only have one instance per rule. But once you have multiple instance of the same rule the thing gets messy really quick. First of all the rules need 2
The first one can be hardcode. It can even be the
So, if we need two different ids for a rule both should be inside An issue right now is: class Issue(
val id: String,
val description: String,
) I would propouse: class Issue(
val id: String,
val ruleId: String,
val description: String,
) Where So, how would this look like on the yaml? style:
ForbiddenJavaIoFile:
active: true
rule: ForbiddenImport
ignoreAnnotated:
- "JavaIoFileIsOk"
imports:
- value: "java.io.File"
reason: 'case-sensitivity issues'
ForbiddenImport:
active: true
imports:
- value: "some.unrelated.import"
reason: "some other reason" A configuration like that will create this two instances like this: listOf(
ForbiddenImport(
Issue(id = "ForbiddenJavaIoFile", ruleId = "ForbiddenImport", ...),
...
),
ForbiddenImport(
Issue(id = "ForbiddenImport", ruleId = "ForbiddenImport", ...),
...
),
) Also I would vote to use |
Sounds good. I like the proposal. |
@BraisGabin Thanks for sharing your ideas! There are two potential issues I see from the user's perspective: Issue 1: It seems messy and counterintuitive for there to be one "main" rule instance (which does not need to set the Here is my idea for how to possibly solve this issue: style:
active: true
rules:
- rule: ForbiddenImport
id: ForbiddenJavaIoFile # optional, defaults to ForbiddenImport-1
active: true
ignoreAnnotated:
- "JavaIoFileIsOk"
imports:
- value: "java.io.File"
reason: 'case-sensitivity issues'
- rule: ForbiddenImport
# in this example id is not defined, so it defaults to something like ForbiddenImport-1 or ForbiddenImport-2
active: true
imports:
- value: "some.unrelated.import"
reason: "some other reason" Issue 2: Users may want some sort of inheritance of parameter values between instances. Here I have two instances for complexity:
active: true
TooManyFunctions:
active: true
thresholdInFiles: 116
thresholdInObjects: 22
thresholdInClasses: 74
thresholdInInterfaces: 51
thresholdInEnums: 3
TooManyPublicFunctions:
ignorePrivate: true
active: true
thresholdInFiles: 50
thresholdInObjects: 22
thresholdInClasses: 74
thresholdInInterfaces: 51
thresholdInEnums: 3 As you can see, I just wanted to have a limit of 50 public functions per file, but for the rest of the scopes, I wanted to keep the numbers the same. The issue is that the numbers that stayed the same had to be written twice. I have to admit, I don't know if there is already a built-in feature in YAML that would solve this issue. If there is not though, maybe we would want to provide our own "templates" or other inheritance mechanism in the configuration files. |
There is the concept of anchors that you might be able to use. |
My proposal about implement config in case user need a the rule twice or more time. We add special char for separate rule name and the rule id. style:
MaxLineLength:
maxLineLength: 100
MaxLineLength%some_id:
maxLineLength: 100 On parsing stage we can check the key for contains % and split the string to rule name. Then add two rule to ruleset.
I use a Is the proposal have any sence ? |
It does have sense. I like it! I would say that style:
MaxLineLength:
maxLineLength: 100
MaxLineLength:some_id:
maxLineLength: 100 The only problem with that is that Other char options: |
I suggest a |
I think
What about |
I don't agree with the @ special character, this character is used in so many programs for communication as a special character, (slack, discord, github, mail...) This will be inconvenient for people when communicating about their detekt rules. Each time you type the @ some program suggest a popup. |
Interesting point. Well, I did check GitHub and slack, and I only get the popup for both if I type the |
Ok, I think we need other options in discussion:) One more point about works with ids, Do the [special char] must the valid id itself? I think it should, because otherwise we will need extra validation of yaml parsing. |
Do we know if anyone is using yaml schema validation for the detekt config? I think auto-complete should still work for the general rule instance, but validation would fail. But I guess that is already the case for 3rd party rules. We should take into account #4162, when thinking about this. |
|
This is a feature that we want to have for detekt 2.0
Needed changes
There are multiple changes that should be made to make this possible. Here a list with all the changes that we need:
RuleSet
s shouldn't instantiate the rules. They should provider factories to pass a confguration to create that rule.Rule
s shouldn't pick their own configuration from its parent configuration. We should provide their configuration directly.Rule
id can't be hardcoded. If a rule can have multiple instances the id should change between those instances.Config
class should provide an API to read all the subconfigurations inside it.Config
and instantiate the rules from there.This is a huge change. There is code that assumes that the rules have a hardcoded id or that the there is only one instance of each. And this is a breaking change, we need to change the API for 3 main classes/interfaces:
RuleSet
,Rule
andConfig
. This will impact every single third party rule out there.Also, those are the big "chunks" that should be done, then a lot of minor changes should be made on the way to be able to make those possible.
The text was updated successfully, but these errors were encountered: