@@ -33,6 +33,7 @@ func rulesConfigForCheckConfig(
3333 allRules []Rule ,
3434 allCategories []Category ,
3535 ruleType check.RuleType ,
36+ relatedCheckConfigs []bufconfig.CheckConfig ,
3637) (* rulesConfig , error ) {
3738 return newRulesConfig (
3839 checkConfig .UseIDsAndCategories (),
@@ -42,6 +43,7 @@ func rulesConfigForCheckConfig(
4243 allRules ,
4344 allCategories ,
4445 ruleType ,
46+ relatedCheckConfigs ,
4547 )
4648}
4749
@@ -94,13 +96,9 @@ type rulesConfig struct {
9496 //
9597 // A plugin is unused if no rules from the plugin are configured.
9698 //
97- // This map will *not* contain plugins that have Rules with RuleTypes other than the given
98- // RuleType. We need to account for this to properly print warnings. It is possible that
99- // a plugin is not used in the lint section, for example, but does have breaking rules configured.
100- // In client.Lint and client.Breaking, we only have the Lint or Breaking config, and we don't know
101- // the state of the other config. If a plugin is unused for lint, but has both lint and breaking
102- // Rules, we don't warn for this plugin, as it may have had rules configured in breaking that
103- // we haven't accounted for.
99+ // The caller can provide additional related check configs to check if the plugin has rules
100+ // configured. If the plugin has rules configured in any of the additional check configs
101+ // provided, then we don't warn.
104102 //
105103 // The Rule IDs will be sorted.
106104 // This will only contain RuleIDs of the given RuleType.
@@ -124,6 +122,7 @@ func newRulesConfig(
124122 allRules []Rule ,
125123 allCategories []Category ,
126124 ruleType check.RuleType ,
125+ relatedCheckConfigs []bufconfig.CheckConfig ,
127126) (* rulesConfig , error ) {
128127 allRulesForType := rulesForType (allRules , ruleType )
129128 if len (allRulesForType ) == 0 {
@@ -292,7 +291,6 @@ func newRulesConfig(
292291 return nil , err
293292 }
294293
295- pluginNameToOtherRuleTypes := getPluginNameToOtherRuleTypes (allRules , ruleType )
296294 // This map initially contains a map from plugin name to ALL Rule IDs, but we will
297295 // then delete the used plugin names, and then delete the plugins with other rule types.
298296 //
@@ -305,11 +303,31 @@ func newRulesConfig(
305303 delete (unusedPluginNameToRuleIDs , pluginName )
306304 }
307305 }
308- for pluginName := range unusedPluginNameToRuleIDs {
309- // If the rule had other plugin types (see the comment on UnusedPluginNameToRuleIDs),
310- // delete the plugin name from the map
311- if _ , ok := pluginNameToOtherRuleTypes [pluginName ]; ok {
312- delete (unusedPluginNameToRuleIDs , pluginName )
306+ // We check additional check configs. If rules are set in the related check configs, then
307+ // the plugin is not considered unused. We check against all rules for all rule types.
308+ allRuleIDToRule , err := getIDToRuleOrCategory (allRules )
309+ if err != nil {
310+ return nil , err
311+ }
312+ allRuleIDToCategoryIDs , err := getRuleIDToCategoryIDs (allRules )
313+ if err != nil {
314+ return nil , err
315+ }
316+ allCategoryIDToRuleIDs := getCategoryIDToRuleIDs (allRuleIDToCategoryIDs )
317+ for _ , checkConfig := range relatedCheckConfigs {
318+ checkConfigUseRuleIDs , err := transformRuleOrCategoryIDsToRuleIDs (
319+ checkConfig .UseIDsAndCategories (),
320+ allRuleIDToCategoryIDs ,
321+ allCategoryIDToRuleIDs ,
322+ )
323+ if err != nil {
324+ return nil , err
325+ }
326+ for _ , checkConfigRuleID := range checkConfigUseRuleIDs {
327+ // If a rule from a non-builtin plugin is found, then we remove it from the unused plugins.
328+ if rule , ok := allRuleIDToRule [checkConfigRuleID ]; rule .PluginName () != "" && ok {
329+ delete (unusedPluginNameToRuleIDs , rule .PluginName ())
330+ }
313331 }
314332 }
315333
@@ -422,23 +440,6 @@ func getIDToRuleOrCategory[R RuleOrCategory](ruleOrCategories []R) (map[string]R
422440 return m , nil
423441}
424442
425- func getPluginNameToOtherRuleTypes (allRules []Rule , ruleType check.RuleType ) map [string ]map [check.RuleType ]struct {} {
426- m := make (map [string ]map [check.RuleType ]struct {})
427- for _ , rule := range allRules {
428- if pluginName := rule .PluginName (); pluginName != "" {
429- if rule .Type () != ruleType {
430- otherRuleTypes , ok := m [pluginName ]
431- if ! ok {
432- otherRuleTypes = make (map [check.RuleType ]struct {})
433- m [pluginName ] = otherRuleTypes
434- }
435- otherRuleTypes [rule .Type ()] = struct {}{}
436- }
437- }
438- }
439- return m
440- }
441-
442443func getPluginNameToRuleOrCategoryIDs [R RuleOrCategory ](ruleOrCategories []R ) map [string ][]string {
443444 m := make (map [string ][]string )
444445 for _ , ruleOrCategory := range ruleOrCategories {
0 commit comments