Module: DevDoc::Test::Lints::NoFileExcludes

Defined in:
lib/dev_doc/test/lints/no_file_excludes.rb

Overview

Reject literal-file entries in any Exclude: list under .rubocop.yml.

Rationale

A literal-path Exclude: makes the suppression invisible to anyone reading the excluded file. They see the violating code, see no # rubocop:disable annotation near it, and reasonably conclude the pattern is acceptable for new code in the same file. That sets the wrong expectation and lets violations multiply.

An inline rubocop:disable Cop/Name directive at the violation line(s) keeps the suppression visible to anyone reading the code AND scopes it to the specific lines — a fresh violation in the same file still gets flagged. The rationale for the suppression lives next to the code it describes, so a future reader sees it without having to cross-check .rubocop.yml.

Globs (vendor/**/*, db/migrate/**/*.rb, bin/*) remain fine because they target a category, not a file someone might be reading.

❌ Hides the suppression from readers of the file

DevDoc/Migration/AvoidColumnDefault:
Exclude:
  - "db/migrate/20260505035728_create_pr_reviews.rb"

✔ Visible inline, scoped to the specific line(s)

# db/migrate/20260505035728_create_pr_reviews.rb
# rubocop:disable DevDoc/Migration/AvoidColumnDefault -- <reason>
t.jsonb :diff_files, default: []

✔ Glob — still acceptable, targets a category not a specific file

AllCops:
Exclude:
  - "vendor/**/*"

Usage

Include this module in a Minitest test class. To allowlist additional auto-generated literal paths (e.g. a project-specific generated file), redefine ALLOWED_FILE_EXCLUDES on the test class.

class RubocopConfigTest < ActiveSupport::TestCase
include DevDoc::Test::Lints::NoFileExcludes
# ALLOWED_FILE_EXCLUDES = %w[db/schema.rb Gemfile.lock].freeze
end

Constant Summary collapse

ALLOWED_FILE_EXCLUDES =

Default allowlist. Per-project override: redefine the constant on the test class that includes this module.

NoFileExcludesChecker::DEFAULT_ALLOWED_FILES

Instance Method Summary collapse

Instance Method Details

#test_no_file_excludes_in_rubocop_ymlObject



112
113
114
115
116
117
118
119
120
# File 'lib/dev_doc/test/lints/no_file_excludes.rb', line 112

def test_no_file_excludes_in_rubocop_yml
  result = NoFileExcludesChecker
           .new(rubocop_yml_path, allowed_files: self.class::ALLOWED_FILE_EXCLUDES)
           .offenders

  skip "no #{rubocop_yml_path} found" if result == NoFileExcludesChecker::MissingFile

  assert result.empty?, no_file_excludes_message(result)
end