Skip to content
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

Rule Configuration using annotations #3637

Merged
merged 19 commits into from
Apr 8, 2021

Conversation

marschwar
Copy link
Contributor

This PR relates to #3562 and makes it possible to configure a Rule using a @Configuration annotation on properties in conjunction with a config delegate.

Advantages

  • The default value for a config parameter is detected automatically
  • The name for a config parameter is automatically the same as the property
  • There is no need to call valueOrDefault as this is done by the delegate automatically

Limitations / Points to discuss

  • Right now this is only implemented on one rule ComplexMethod to illustrate what it would look like.
  • Currently only String, Boolean, Int, Long and List are supported as configuration properties. Which types did I miss?
  • The default value can only be inferred when it is definied directly in the delegate expression or as a constant in the rules companion object. (see Type resolution in generator module #3628)
  • The formatting of lists of strings in the default-detekt-config.yml is inconsistent ([run, let, apply] vs. ['**/test/**', '**/androidTest/**']) so I opted for the version with quotes. Is that a problem?
  • I disabled the checks in ConfigAssert for rules that use @Configuration as they are not needed IMO.

@BraisGabin
Copy link
Member

This PR relates to #3562 and makes it possible to configure a Rule using a @Configuration annotation on properties in conjunction with a config delegate.

Advantages

* The default value for a config parameter is detected automatically

* The name for a config parameter is automatically the same as the property

* There is no need to call `valueOrDefault` as this is done by the delegate automatically

Limitations / Points to discuss

  • Currently only String, Boolean, Int, Long and List are supported as configuration properties. Which types did I miss?

Regex? It's the same as String but maybe we could use it to make more clear what type of String we expect there. But this is out of scope of this PR. It could be done as a follow up.

I don't know how to help you here. Are there a lot of these cases? Could we simplify them to use always values in the same file?

  • The formatting of lists of strings in the default-detekt-config.yml is inconsistent ([run, let, apply] vs. ['**/test/**', '**/androidTest/**']) so I opted for the version with quotes. Is that a problem?

This is not a problem at all. I was wondering about other configurations where we use this syntax:

    exceptionNames:
     - ArrayIndexOutOfBoundsException
     - Error
     - Exception
     - IllegalMonitorStateException
     - NullPointerException
     - IndexOutOfBoundsException
     - RuntimeException
     - Throwable

Could it be possible to use both? I mean, the one-line syntax in this example would be really difficult to maintain and works really bad with git.

But again this don't need to be faced in this PR if it makes it more complex.

@codecov
Copy link

codecov bot commented Mar 30, 2021

Codecov Report

Merging #3637 (d97e8d7) into main (4495b36) will decrease coverage by 0.01%.
The diff coverage is 77.50%.

❗ Current head d97e8d7 differs from pull request most recent head f91f3a6. Consider uploading reports for the commit f91f3a6 to get more accurate results
Impacted file tree graph

@@             Coverage Diff              @@
##               main    #3637      +/-   ##
============================================
- Coverage     77.97%   77.95%   -0.02%     
- Complexity     2837     2870      +33     
============================================
  Files           467      470       +3     
  Lines          9139     9245     +106     
  Branches       1737     1761      +24     
============================================
+ Hits           7126     7207      +81     
- Misses         1071     1077       +6     
- Partials        942      961      +19     
Impacted Files Coverage Δ Complexity Δ
...t/generator/collection/RuleSetProviderCollector.kt 75.47% <0.00%> (-1.89%) 4.00 <0.00> (ø)
...ekt/generator/collection/DocumentationCollector.kt 70.00% <70.00%> (ø) 15.00 <15.00> (?)
...ekt/generator/collection/ConfigurationCollector.kt 70.58% <70.58%> (ø) 20.00 <20.00> (?)
...b/arturbosch/detekt/api/internal/ConfigProperty.kt 80.00% <80.00%> (ø) 0.00 <0.00> (?)
...urbosch/detekt/generator/collection/Annotations.kt 71.42% <100.00%> (+16.88%) 0.00 <0.00> (ø)
...urbosch/detekt/generator/collection/RuleVisitor.kt 89.65% <100.00%> (+6.01%) 33.00 <9.00> (-2.00) ⬆️
...rturbosch/detekt/rules/complexity/ComplexMethod.kt 95.34% <100.00%> (+1.06%) 13.00 <2.00> (ø)

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 4495b36...f91f3a6. Read the comment docs.

@marschwar
Copy link
Contributor Author

I don't think there are many cases where the default is defined outside the rule class itself. I don't see this as a huge problem as of know.

List format: Maybe it always should be the line-per-item syntax for all list parameters?

@BraisGabin
Copy link
Member

List format: Maybe it always should be the line-per-item syntax for all list parameters?

I'm not sure about this either. We have some configurations that will probably never change ([run, let, apply]) and they looks better in just one line... But this should not be a blocker. We can fix this later.

@chao2zhang
Copy link
Member

Could someone confirm that I have left comments before on this PR?

Instead of git push --force, what I would recommend is to git fetch + git merge when we want to add more commits to a published PR. This will preserve the conversation history while force-push may wipe out all the conversations.

@marschwar
Copy link
Contributor Author

marschwar commented Apr 6, 2021

As far as I know you had not commented on this PR but rather #3608. I created an entirely new PR. I probably should have referenced it in the description.

I did force push multiple times after rebasing onto master.

Copy link
Member

@chao2zhang chao2zhang left a comment

Choose a reason for hiding this comment

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

PR looks great to me!

class ComplexMethod(config: Config = Config.empty) : Rule(config) {

@Configuration("McCabe's Cyclomatic Complexity (MCC) number for a method.")
private val threshold: Int by config(DEFAULT_THRESHOLD_METHOD_COMPLEXITY)
Copy link
Member

Choose a reason for hiding this comment

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

I would personally inline 15.. I guess that's violated by the MagicNumber rule.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I am torn. I really think it is redundant since it is clearly the default value and does not need extra naming. But on the other hand I dislike us excessively suppressing our own rules.

Copy link
Member

@BraisGabin BraisGabin left a comment

Choose a reason for hiding this comment

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

And after this we need to make the migration and then remove the old code. Are you traking the remaining taask somewhere? I could help you with this more "mechanical" work.

.github/CONTRIBUTING.md Outdated Show resolved Hide resolved
@BraisGabin
Copy link
Member

And, of course, this is a huge improvement!

Co-authored-by: Brais Gabín <braisgabin@gmail.com>
@marschwar
Copy link
Contributor Author

Are you traking the remaining taask somewhere?

What would be a good format for this? Create an issue per task or one for all?

@BraisGabin
Copy link
Member

What would be a good format for this? Create an issue per task or one for all?

That's your call. Both seem fine to me.

@chao2zhang chao2zhang added this to the 1.17.0 milestone Apr 8, 2021
@chao2zhang chao2zhang merged commit cbee5e7 into detekt:main Apr 8, 2021
@marschwar marschwar deleted the annotations-configuration branch April 9, 2021 11:16
@cortinico cortinico added the notable changes Marker for notable changes in the changelog label May 1, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
notable changes Marker for notable changes in the changelog
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants