Class: Gran::TreeTransformer
- Inherits:
-
Object
- Object
- Gran::TreeTransformer
- Includes:
- Loggable
- Defined in:
- lib/gran/tree_transformer.rb
Overview
A framework for transforming source file trees into destination trees through three distinct phases:
-
SCAN - Examine source tree, collect metadata (read-only)
-
TRANSFORM - Convert source nodes to destination nodes (core work)
-
FINALIZE - Generate derived outputs, aggregations (post-processing)
Usage
transformer = Gran::TreeTransformer.new(
src: "/path/to/source",
dst: "/path/to/destination",
transformer: MyTransformer.new,
traversal: :preorder # optional, default :preorder
)
# Register scanners and finalizers
transformer.add_scanner(MyScanner.new)
transformer.add_finalizer(MyFinalizer.new)
# Run all phases
transformer.run(abort_on_exc: true)
Transformer Interface
Transformers must implement:
def transform(src_node, dst_tree, context)
# Required: perform transformation, mutate dst_tree
end
def should_transform?(src_node, context)
# Optional: return true/false to filter nodes
# Default: true (process all nodes)
end
Scanner Interface
Scanners must implement:
def scan(src_tree, context)
# Examine source tree, collect metadata
# Mutate context to share data with transform/finalize phases
end
Finalizer Interface
Finalizers must implement:
def finalize(src_tree, dst_tree, transformer, context)
# Generate derived outputs, copy assets, etc.
end
Instance Attribute Summary collapse
-
#context ⇒ Object
readonly
Returns the value of attribute context.
-
#dst_tree ⇒ Object
readonly
Returns the value of attribute dst_tree.
-
#src_tree ⇒ Object
readonly
Returns the value of attribute src_tree.
-
#transformer ⇒ Object
readonly
Returns the value of attribute transformer.
Instance Method Summary collapse
-
#add_finalizer(finalizer) ⇒ Object
Add a finalizer to be run during the finalize phase.
-
#add_scanner(scanner) ⇒ Object
Add a scanner to be run during the scan phase.
-
#initialize(src:, dst:, transformer:, traversal: :preorder, context: {}) ⇒ TreeTransformer
constructor
Create a new TreeTransformer.
-
#run(abort_on_exc: true) ⇒ Object
Run all three transformation phases.
Methods included from Loggable
Constructor Details
#initialize(src:, dst:, transformer:, traversal: :preorder, context: {}) ⇒ TreeTransformer
Create a new TreeTransformer
79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 |
# File 'lib/gran/tree_transformer.rb', line 79 def initialize(src:, dst:, transformer:, traversal: :preorder, context: {}) @transformer = transformer @traversal = traversal @context = context # Build or accept source tree @src_tree = if src.is_a?(PathTree) src else src_path = Pathname.new(src).cleanpath raise ArgumentError, "Source path does not exist: #{src_path}" unless src_path.exist? PathTree.build_from_fs(src_path, prune: false) end # Create destination tree dst_path = Pathname.new(dst).cleanpath @dst_tree = PathTree.new(dst_path) # Store root references in context for convenience @context[:src_root] = @src_tree @context[:dst_root] = @dst_tree # Phase handlers @scanners = [] @finalizers = [] # Validate traversal method unless @src_tree.respond_to?(:"traverse_#{@traversal}") raise ArgumentError, "Invalid traversal order: #{@traversal}" end end |
Instance Attribute Details
#context ⇒ Object (readonly)
Returns the value of attribute context.
64 65 66 |
# File 'lib/gran/tree_transformer.rb', line 64 def context @context end |
#dst_tree ⇒ Object (readonly)
Returns the value of attribute dst_tree.
64 65 66 |
# File 'lib/gran/tree_transformer.rb', line 64 def dst_tree @dst_tree end |
#src_tree ⇒ Object (readonly)
Returns the value of attribute src_tree.
64 65 66 |
# File 'lib/gran/tree_transformer.rb', line 64 def src_tree @src_tree end |
#transformer ⇒ Object (readonly)
Returns the value of attribute transformer.
64 65 66 |
# File 'lib/gran/tree_transformer.rb', line 64 def transformer @transformer end |
Instance Method Details
#add_finalizer(finalizer) ⇒ Object
Add a finalizer to be run during the finalize phase
128 129 130 131 132 |
# File 'lib/gran/tree_transformer.rb', line 128 def add_finalizer(finalizer) raise ArgumentError, "Finalizer must respond to #finalize" unless finalizer.respond_to?(:finalize) @finalizers << finalizer end |
#add_scanner(scanner) ⇒ Object
Add a scanner to be run during the scan phase
117 118 119 120 121 |
# File 'lib/gran/tree_transformer.rb', line 117 def add_scanner(scanner) raise ArgumentError, "Scanner must respond to #scan" unless scanner.respond_to?(:scan) @scanners << scanner end |
#run(abort_on_exc: true) ⇒ Object
Run all three transformation phases
139 140 141 142 143 144 145 146 147 |
# File 'lib/gran/tree_transformer.rb', line 139 def run(abort_on_exc: true) logger.info { "Starting tree transformation: #{@src_tree.pathname} -> #{@dst_tree.pathname}" } run_scan_phase run_transform_phase(abort_on_exc: abort_on_exc) run_finalize_phase(abort_on_exc: abort_on_exc) logger.info { "Tree transformation complete" } end |