Module: RuboCop::Cop::ViewComponent::TemplateAnalyzer

Included in:
PreferPrivateMethods
Defined in:
lib/rubocop/cop/view_component/template_analyzer.rb

Overview

Helper module for analyzing ViewComponent ERB templates

Instance Method Summary collapse

Instance Method Details

#extract_method_calls(template_path) ⇒ Set<Symbol>

Extract method calls from an ERB template

Parameters:

  • template_path (String)

    Path to the ERB template file

Returns:

  • (Set<Symbol>)

    Set of method names called in the template



44
45
46
47
48
49
50
51
52
53
54
55
56
# File 'lib/rubocop/cop/view_component/template_analyzer.rb', line 44

def extract_method_calls(template_path)
  return Set.new unless File.exist?(template_path)

  source = File.read(template_path)
  ruby_code = Herb.extract_ruby(source)

  # Parse the extracted Ruby code
  parse_ruby_for_method_calls(ruby_code)
rescue => e
  # Graceful degradation on parse errors
  warn "Warning: Failed to parse template #{template_path}: #{e.message}" if ENV["RUBOCOP_DEBUG"]
  Set.new
end

#template_paths_for(component_path) ⇒ Array<String>

Find template file paths for a component

Parameters:

  • component_path (String)

    Path to the component Ruby file

Returns:

  • (Array<String>)

    Array of template file paths



13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
# File 'lib/rubocop/cop/view_component/template_analyzer.rb', line 13

def template_paths_for(component_path)
  return [] unless component_path

  base_path = component_path.sub(/\.rb$/, "")
  component_dir = File.dirname(component_path)
  component_name = File.basename(component_path, ".rb")

  paths = []

  # Check for sibling template: same_name.html.erb
  sibling_template = "#{base_path}.html.erb"
  paths << sibling_template if File.exist?(sibling_template)

  # Check for sidecar template: same_name/same_name.html.erb
  sidecar_template = File.join(component_dir, component_name, "#{component_name}.html.erb")
  paths << sidecar_template if File.exist?(sidecar_template)

  # Check for variants: same_name.*.html.erb
  variant_pattern = "#{base_path}.*.html.erb"
  paths.concat(Dir.glob(variant_pattern))

  # Check for sidecar variants: same_name/same_name.*.html.erb
  sidecar_variant_pattern = File.join(component_dir, component_name, "#{component_name}.*.html.erb")
  paths.concat(Dir.glob(sidecar_variant_pattern))

  paths.uniq
end