Class: RuboCop::Cop::Seams::MigrationComments

Inherits:
Base
  • Object
show all
Defined in:
lib/seams/cops/migration_comments.rb

Overview

Requires every migration to start with a leading comment block so that future readers know what the migration does, why it was needed, and what its data/downtime implications are.

Constant Summary collapse

MSG =
"Migration `%<name>s` must be preceded by a comment block explaining " \
"what changes and why (data implications, downtime risk, rollback notes)."
MAGIC_COMMENT =

Comments that look like directives, not documentation. We strip these out before deciding whether the migration carries a real doc block.

The Parser associator already drops the encoding/shebang/frozen_string_literal family of magic comments (skip_directives), so this regex only has to cover the directives Parser leaves attached: Sorbet sigils, RuboCop disable/enable, shareable_constant_value, warn_indent.

/
  \A\s*\#\s*
  (?:
    frozen_string_literal
    | encoding
    | warn_indent
    | shareable_constant_value
    | typed
    | rubocop:(?:disable|enable|todo)
  )
/x

Instance Method Summary collapse

Instance Method Details

#migration_class?(node) ⇒ Object



35
36
37
# File 'lib/seams/cops/migration_comments.rb', line 35

def_node_matcher :migration_class?, <<~PATTERN
  (class (const nil? $_) (send (const (const _ :ActiveRecord) :Migration) :[] _) ...)
PATTERN

#on_class(node) ⇒ Object



39
40
41
42
43
44
45
# File 'lib/seams/cops/migration_comments.rb', line 39

def on_class(node)
  name = migration_class?(node)
  return unless name
  return if leading_comment?(node)

  add_offense(node, message: format(MSG, name: name))
end