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.
Inline # rubocop:disable Cop/Name 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
t.jsonb :diff_files, default: [] # rubocop:disable DevDoc/Migration/AvoidColumnDefault
✔ 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_yml ⇒ Object
105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 |
# File 'lib/dev_doc/test/lints/no_file_excludes.rb', line 105 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?, "`.rubocop.yml` Exclude lists must contain only globs " \ "(category patterns), not literal file paths. A literal-path " \ "exclude hides the suppression from readers of the file. " \ "Use `# rubocop:disable Cop/Name` at the violation line(s) " \ "instead — visible to readers, scoped to the specific lines.\n\n" \ "Offenders:\n#{result.join("\n")}" end |