diff --git a/changelog/new_allow_excluding_some_constants_from.md b/changelog/new_allow_excluding_some_constants_from.md new file mode 100644 index 00000000000..a247a074e02 --- /dev/null +++ b/changelog/new_allow_excluding_some_constants_from.md @@ -0,0 +1 @@ +* [#9219](https://github.com/rubocop-hq/rubocop/pull/9219): Allow excluding some constants from Style/Documentation. ([@fsateler][]) diff --git a/config/default.yml b/config/default.yml index 01d3bccb37c..cd30e5c7aff 100644 --- a/config/default.yml +++ b/config/default.yml @@ -3174,6 +3174,7 @@ Style/Documentation: Description: 'Document classes and non-namespace modules.' Enabled: true VersionAdded: '0.9' + AllowedConstants: [] Exclude: - 'spec/**/*' - 'test/**/*' diff --git a/lib/rubocop/cop/style/documentation.rb b/lib/rubocop/cop/style/documentation.rb index 1a740cece5d..2ab3f609bed 100644 --- a/lib/rubocop/cop/style/documentation.rb +++ b/lib/rubocop/cop/style/documentation.rb @@ -60,6 +60,15 @@ module Style # extend Foo # end # + # @example AllowedConstants: ['ClassMethods'] + # + # # good + # module A + # module ClassMethods + # # ... + # end + # end + # class Documentation < Base include DocumentationComment @@ -85,14 +94,19 @@ def on_module(node) def check(node, body, type) return if namespace?(body) - return if documentation_comment?(node) || nodoc_comment?(node) - return if compact_namespace?(node) && - nodoc_comment?(outer_module(node).first) + return if documentation_comment?(node) + return if constant_allowed?(node) + return if nodoc_self_or_outer_module?(node) return if macro_only?(body) add_offense(node.loc.keyword, message: format(MSG, type: type)) end + def nodoc_self_or_outer_module?(node) + nodoc_comment?(node) || + compact_namespace?(node) && nodoc_comment?(outer_module(node).first) + end + def macro_only?(body) body.respond_to?(:macro?) && body.macro? || body.respond_to?(:children) && body.children&.all? { |child| macro_only?(child) } @@ -112,6 +126,10 @@ def constant_declaration?(node) constant_definition?(node) || constant_visibility_declaration?(node) end + def constant_allowed?(node) + allowed_constants.include?(node.identifier.short_name) + end + def compact_namespace?(node) /::/.match?(node.loc.name.source) end @@ -138,6 +156,10 @@ def nodoc?(comment, require_all: false) def nodoc(node) processed_source.ast_with_comments[node.children.first].first end + + def allowed_constants + @allowed_constants ||= cop_config.fetch('AllowedConstants', []).map(&:intern) + end end end end diff --git a/spec/rubocop/cli/auto_gen_config_spec.rb b/spec/rubocop/cli/auto_gen_config_spec.rb index 35b9383e2a6..bec8fd77be5 100644 --- a/spec/rubocop/cli/auto_gen_config_spec.rb +++ b/spec/rubocop/cli/auto_gen_config_spec.rb @@ -698,6 +698,7 @@ def a; end " - 'example1.rb'", '', '# Offense count: 1', + '# Configuration parameters: AllowedConstants.', 'Style/Documentation:', ' Exclude:', " - 'spec/**/*'", # Copied from default configuration @@ -1067,6 +1068,7 @@ def a; end ' Exclude:', " - 'example1.rb'", '', + '# Configuration parameters: AllowedConstants.', 'Style/Documentation:', ' Exclude:', " - 'spec/**/*'", # Copied from default configuration diff --git a/spec/rubocop/cop/style/documentation_spec.rb b/spec/rubocop/cop/style/documentation_spec.rb index a06a1a58dd6..3f3fef0c36f 100644 --- a/spec/rubocop/cop/style/documentation_spec.rb +++ b/spec/rubocop/cop/style/documentation_spec.rb @@ -411,6 +411,21 @@ class Test < Parent RUBY end end + + describe 'when AllowedConstants is configured' do + before { config['Style/Documentation'] = { 'AllowedConstants' => ['ClassMethods'] } } + + it 'ignores the constants in the config' do + expect_no_offenses(<<~RUBY) + module A + module ClassMethods + def do_something + end + end + end + RUBY + end + end end end end