Class: Woods::FlowPrecomputer

Inherits:
Object
  • Object
show all
Defined in:
lib/woods/flow_precomputer.rb

Overview

Orchestrates pre-computation of request flow maps for all controller actions.

After the dependency graph is built, FlowPrecomputer iterates controller units, runs FlowAssembler for each action, and writes flow documents to disk.

Examples:

precomputer = FlowPrecomputer.new(units: all_units, graph: dep_graph, output_dir: out)
flow_map = precomputer.precompute
flow_map["OrdersController#create"] #=> "/tmp/woods/flows/OrdersController_create.json"

Constant Summary collapse

DEFAULT_MAX_DEPTH =

Default maximum recursion depth for flow assembly

3

Instance Method Summary collapse

Constructor Details

#initialize(units:, graph:, output_dir:, max_depth: DEFAULT_MAX_DEPTH) ⇒ FlowPrecomputer

Returns a new instance of FlowPrecomputer.

Parameters:

  • units (Array<ExtractedUnit>)

    All extracted units

  • graph (DependencyGraph)

    The dependency graph

  • output_dir (String)

    Base output directory

  • max_depth (Integer) (defaults to: DEFAULT_MAX_DEPTH)

    Maximum flow assembly depth



26
27
28
29
30
31
32
# File 'lib/woods/flow_precomputer.rb', line 26

def initialize(units:, graph:, output_dir:, max_depth: DEFAULT_MAX_DEPTH)
  @units = units
  @graph = graph
  @output_dir = output_dir
  @max_depth = max_depth
  @flows_dir = File.join(output_dir, 'flows')
end

Instance Method Details

#precomputeHash{String => String}

Pre-compute flow documents for all controller actions.

Returns:

  • (Hash{String => String})

    Map of entry_point to flow file path



37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
# File 'lib/woods/flow_precomputer.rb', line 37

def precompute
  FileUtils.mkdir_p(@flows_dir)

  assembler = FlowAssembler.new(graph: @graph, extracted_dir: @output_dir)
  flow_map = {}

  controller_units.each do |unit|
    actions = unit.[:actions] || unit.['actions'] || []
    unit_flow_paths = {}

    actions.each do |action|
      entry_point = "#{unit.identifier}##{action}"
      flow_path = assemble_and_write(assembler, entry_point, unit.identifier, action)
      next unless flow_path

      flow_map[entry_point] = flow_path
      unit_flow_paths[action] = flow_path
    end

    unit.[:flow_paths] = unit_flow_paths if unit_flow_paths.any?
  end

  write_flow_index(flow_map)

  flow_map
end