Class: ArchSpec::Rules::ZeitwerkNamingRule

Inherits:
Object
  • Object
show all
Defined in:
lib/archspec/rules/zeitwerk_rule.rb

Overview

Backs ArchSpec::DSL::Context#verify_zeitwerk_names!. Flags files that do not define the constant their path implies under Zeitwerk.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(only: nil) ⇒ ZeitwerkNamingRule

only: globs restricting which files are checked. Default is every file ArchSpec can name, but lib autoloading is opt-in, so apps that require lib manually scope this to app/.



13
14
15
# File 'lib/archspec/rules/zeitwerk_rule.rb', line 13

def initialize(only: nil)
  @only = Array(only).flatten.compact.map(&:to_s)
end

Instance Attribute Details

#onlyObject (readonly)

Returns the value of attribute only.



8
9
10
# File 'lib/archspec/rules/zeitwerk_rule.rb', line 8

def only
  @only
end

Instance Method Details

#evaluate(graph) ⇒ Object



21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
# File 'lib/archspec/rules/zeitwerk_rule.rb', line 21

def evaluate(graph)
  scoped_paths = scoped_paths(graph)

  graph.files.values.filter_map do |file|
    next unless file.expected_constant
    next if scoped_paths && !scoped_paths.include?(file.path)

    defined = graph.constants_for_path(file.path).map(&:name)
    next if defined.include?(file.expected_constant)

    Diagnostic.new(
      rule: id,
      message: "#{file.relative_path} should define #{file.expected_constant}",
      location: SourceLocation.new(file.path, 1, 1),
      evidence: "defined constants: #{defined.empty? ? '(none)' : defined.join(', ')}"
    )
  end
end

#idObject



17
18
19
# File 'lib/archspec/rules/zeitwerk_rule.rb', line 17

def id
  'zeitwerk.naming'
end