Class: Ask::Tools::Shell::FileMutationQueue
- Inherits:
-
Object
- Object
- Ask::Tools::Shell::FileMutationQueue
- Defined in:
- lib/ask/tools/shell/file_mutation_queue.rb
Overview
Queues file mutations and applies them atomically. Rollback on any failure — no partial writes.
queue = FileMutationQueue.new
queue.stage("path/to/file.rb", ->(content) {
content.gsub("old", "new")
})
queue.apply! # reads all staged files, applies transforms, writes back
Defined Under Namespace
Classes: ApplyError
Instance Method Summary collapse
-
#apply! ⇒ Array<Hash>
Apply all staged mutations atomically.
-
#clear! ⇒ Object
Clear all staged mutations without applying.
-
#initialize(operations: nil) ⇒ FileMutationQueue
constructor
A new instance of FileMutationQueue.
-
#size ⇒ Object
Number of staged mutations.
-
#stage(path) {|content| ... } ⇒ Object
Stage a mutation for a file.
Constructor Details
#initialize(operations: nil) ⇒ FileMutationQueue
Returns a new instance of FileMutationQueue.
18 19 20 21 |
# File 'lib/ask/tools/shell/file_mutation_queue.rb', line 18 def initialize(operations: nil) @staged = [] @operations = operations || DefaultEditOperations.new end |
Instance Method Details
#apply! ⇒ Array<Hash>
Apply all staged mutations atomically. Reads all files, applies transforms, then writes all back. If any write fails, all written files are rolled back to original.
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 63 64 65 66 67 68 69 70 |
# File 'lib/ask/tools/shell/file_mutation_queue.rb', line 37 def apply! snapshots = [] # Phase 1: read all files and apply transforms @staged.each do |entry| path = entry[:path] original = @operations.read_file(path) modified = entry[:block].call(original) snapshots << { path: path, original: original, modified: modified } end # Phase 2: write all files, track rollback info written = [] begin snapshots.each do |s| @operations.write_file(s[:path], s[:modified]) written << s[:path] end rescue => e # Rollback: restore originals for files we already wrote written.each do |path| snapshot = snapshots.find { |s| s[:path] == path } @operations.write_file(path, snapshot[:original]) if snapshot rescue => rb_e $stderr.puts "[FileMutationQueue] Rollback failed for #{path}: #{rb_e.}" end raise ApplyError, "Mutation failed at #{e.class}: #{e.}. Rolled back #{written.size} files." end snapshots.map do |s| { path: s[:path], original_size: s[:original].length, new_size: s[:modified].length, success: true } end end |
#clear! ⇒ Object
Clear all staged mutations without applying.
73 74 75 |
# File 'lib/ask/tools/shell/file_mutation_queue.rb', line 73 def clear! @staged.clear end |
#size ⇒ Object
Number of staged mutations.
78 79 80 |
# File 'lib/ask/tools/shell/file_mutation_queue.rb', line 78 def size @staged.size end |
#stage(path) {|content| ... } ⇒ Object
Stage a mutation for a file.
28 29 30 |
# File 'lib/ask/tools/shell/file_mutation_queue.rb', line 28 def stage(path, &block) @staged << { path: File.(path), block: block } end |