Class: Woods::Extractors::ViewTemplateExtractor

Inherits:
Object
  • Object
show all
Includes:
RouteHelperResolver
Defined in:
lib/woods/extractors/view_template_extractor.rb

Overview

ViewTemplateExtractor orchestrates view-template extraction across per-engine implementations under ViewEngines.

For each configured view directory the orchestrator walks every extension any registered engine handles, finds the first engine whose Woods::Extractors::ViewEngines::Base#handles? returns true for a given file, and delegates parsing, scanning, and partial-identifier resolution to that engine. The orchestrator itself owns filesystem walking, identifier construction, controller inference, route-helper edge resolution, and dependency assembly.

Engines are registered via ENGINES. Add a new engine by creating a Woods::Extractors::ViewEngines::Base subclass and appending it to that list.

Examples:

extractor = ViewTemplateExtractor.new
units = extractor.extract_all
index = units.find { |u| u.identifier == "users/index.html.erb" }

Constant Summary collapse

VIEW_DIRECTORIES =

Directories to scan for view templates.

%w[
  app/views
].freeze
ENGINES =

Registered view-template engines, in precedence order. The first engine whose Woods::Extractors::ViewEngines::Base#handles? returns true for a file wins — place more specific engines before more general ones if overlap is ever introduced.

[ViewEngines::Erb].freeze

Constants included from RouteHelperResolver

RouteHelperResolver::IGNORED_HELPER_PREFIXES

Class Method Summary collapse

Instance Method Summary collapse

Methods included from RouteHelperResolver

#build_route_helper_map, #resolve_route_helper, #safe_rails_application_routes

Constructor Details

#initializeViewTemplateExtractor

Returns a new instance of ViewTemplateExtractor.



53
54
55
56
57
58
# File 'lib/woods/extractors/view_template_extractor.rb', line 53

def initialize
  @directories = VIEW_DIRECTORIES.map { |d| Rails.root.join(d) }
                                 .select(&:directory?)
  @engines = self.class::ENGINES.map(&:new)
  build_route_helper_map
end

Class Method Details

.supported_template_enginesArray<Symbol>

Template engine names the extraction pipeline currently understands — aggregated from ENGINES so the list stays honest as engines are added or removed. Surfaced through the MCP ‘structure` tool.

Returns:

  • (Array<Symbol>)


49
50
51
# File 'lib/woods/extractors/view_template_extractor.rb', line 49

def self.supported_template_engines
  ENGINES.map { |klass| klass.new.name }.uniq.freeze
end

Instance Method Details

#extract_allArray<ExtractedUnit>

Extract all view templates across the registered engines.

Returns:



63
64
65
66
67
68
69
# File 'lib/woods/extractors/view_template_extractor.rb', line 63

def extract_all
  extensions = @engines.flat_map(&:extensions).uniq
  @directories.flat_map do |dir|
    files = extensions.flat_map { |ext| Dir[dir.join("**/*#{ext}")] }
    files.uniq.filter_map { |file| extract_view_template_file(file) }
  end
end

#extract_view_template_file(file_path) ⇒ ExtractedUnit?

Extract a single view template file.

Parameters:

  • file_path (String)

    Path to the template file

Returns:

  • (ExtractedUnit, nil)

    The extracted unit, or nil if no registered engine handles the file



76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
# File 'lib/woods/extractors/view_template_extractor.rb', line 76

def extract_view_template_file(file_path)
  engine = engine_for(file_path)
  return nil unless engine

  source = File.read(file_path)
  identifier = build_identifier(file_path)
  namespace = extract_view_namespace(file_path)

  unit = ExtractedUnit.new(
    type: :view_template,
    identifier: identifier,
    file_path: file_path
  )

  unit.namespace = namespace
  unit.source_code = source
  partials = engine.scan_partials(source)
  unit. = (engine, source, file_path, partials)
  unit.dependencies = build_dependencies(engine, source, file_path, identifier, partials)

  unit
rescue StandardError => e
  Rails.logger.error("Failed to extract view template #{file_path}: #{e.message}")
  nil
end