Class: Woods::Extractors::StateMachineExtractor

Inherits:
Object
  • Object
show all
Includes:
SharedDependencyScanner, SharedUtilityMethods
Defined in:
lib/woods/extractors/state_machine_extractor.rb

Overview

StateMachineExtractor scans app/models for state machine DSL definitions.

Supports three state machine gems:

  • AASM: files that include AASM with aasm do…end blocks

  • Statesman: files that include Statesman::Machine with state/transition calls

  • state_machines: files using the state_machine :attr do…end DSL

Produces one ExtractedUnit per state machine definition found. A single model file can produce multiple units (e.g., two state_machine blocks).

Examples:

extractor = StateMachineExtractor.new
units = extractor.extract_all
order_sm = units.find { |u| u.identifier == "Order::aasm" }
order_sm.[:states]  # => ["pending", "processing", "completed"]
order_sm.[:gem_detected]  # => "aasm"

Constant Summary collapse

MODEL_DIRECTORIES =
%w[app/models].freeze

Constants included from SharedDependencyScanner

Woods::Extractors::SharedDependencyScanner::FORM_ACTION_HELPER, Woods::Extractors::SharedDependencyScanner::ROUTE_HELPER_PATTERN

Instance Method Summary collapse

Methods included from SharedDependencyScanner

#extract_constantize_targets, #scan_common_dependencies, #scan_form_dependencies, #scan_job_dependencies, #scan_mailer_dependencies, #scan_model_dependencies, #scan_navigation_dependencies, #scan_service_dependencies

Methods included from SharedUtilityMethods

#app_source?, #condition_label, #count_loc, #detect_entry_points, #extract_action_filter_actions, #extract_callback_conditions, #extract_class_methods, #extract_class_name, #extract_custom_errors, #extract_initialize_params, #extract_namespace, #extract_parent_class, #extract_public_methods, #resolve_source_location, #skip_file?

Constructor Details

#initializeStateMachineExtractor

Returns a new instance of StateMachineExtractor.



31
32
33
# File 'lib/woods/extractors/state_machine_extractor.rb', line 31

def initialize
  @directories = MODEL_DIRECTORIES.map { |d| Rails.root.join(d) }.select(&:directory?)
end

Instance Method Details

#extract_allArray<ExtractedUnit>

Extract all state machine definitions from model files.

Returns:



38
39
40
41
42
# File 'lib/woods/extractors/state_machine_extractor.rb', line 38

def extract_all
  @directories.flat_map do |dir|
    Dir[dir.join('**/*.rb')].flat_map { |file| extract_model_file(file) }
  end
end

#extract_model_file(file_path) ⇒ Array<ExtractedUnit>

Extract state machine definitions from a single model file.

Returns an Array because one model file may contain multiple state machine definitions (e.g., multiple state_machine blocks for different attributes).

Parameters:

  • file_path (String)

    Path to the model file

Returns:

  • (Array<ExtractedUnit>)

    List of state machine units (empty if none detected)



51
52
53
54
55
56
57
58
59
60
61
62
63
# File 'lib/woods/extractors/state_machine_extractor.rb', line 51

def extract_model_file(file_path)
  source = File.read(file_path)
  class_name = detect_class_name(source, file_path)

  units = []
  units.concat(extract_aasm_units(source, class_name, file_path))
  units.concat(extract_statesman_units(source, class_name, file_path))
  units.concat(extract_state_machines_units(source, class_name, file_path))
  units
rescue StandardError => e
  Rails.logger.error("Failed to extract state machines from #{file_path}: #{e.message}")
  []
end