Class: Rubyfocus::Patch
- Inherits:
-
Object
- Object
- Rubyfocus::Patch
- Includes:
- Comparable
- Defined in:
- lib/rubyfocus/patch.rb
Overview
The patch class represents a text-file patch, storing update, delete, and creation operations. It should also be able to apply itself to an existing document.
Instance Attribute Summary collapse
-
#create ⇒ Object
Operations to be performed on a document.
-
#delete ⇒ Object
Operations to be performed on a document.
-
#fetcher ⇒ Object
The fetcher this patch belongs to.
-
#file ⇒ Object
The file the patch loads from.
-
#from_ids ⇒ Object
These record the transformation in terms of patch ID values.
-
#time ⇒ Object
The time the file was submitted.
-
#to_id ⇒ Object
These record the transformation in terms of patch ID values.
-
#update ⇒ Object
Update, delete and create methods.
Class Method Summary collapse
-
.from_string(fetcher, str) ⇒ Object
Load from a string.
Instance Method Summary collapse
- #<=>(o) ⇒ Object
-
#apply_to(document) ⇒ Object
Apply this patch to a document.
-
#apply_to!(document) ⇒ Object
Apply this patch to a document.
-
#can_patch?(document) ⇒ Boolean
Can we apply this patch to a given document?.
-
#initialize(fetcher = nil, file = nil) ⇒ Patch
constructor
By default we initialize patches from a file.
-
#load_data(str = nil) ⇒ Object
Loads data from the file.
-
#to_s ⇒ Object
String representation.
Constructor Details
#initialize(fetcher = nil, file = nil) ⇒ Patch
By default we initialize patches from a file. To initialize from a string, use the .from_string method. This class will lazily load data from the file proper
22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
# File 'lib/rubyfocus/patch.rb', line 22 def initialize(fetcher=nil, file=nil) @fetcher = fetcher @file = file @update = [] @create = [] @delete = [] if file if File.basename(file) =~ /^(\d+)=(.*)\./ time_string = $1 self.time = if (time_string == "00000000000000") Time.at(0) else Time.parse(time_string) end ids = $2.split("+") self.to_id = ids.pop self.from_ids = ids else raise ArgumentError, "Constructed patch from a malformed patch file: #{file}." end end end |
Instance Attribute Details
#create ⇒ Object
Operations to be performed on a document
9 10 11 |
# File 'lib/rubyfocus/patch.rb', line 9 def create @create end |
#delete ⇒ Object
Operations to be performed on a document
9 10 11 |
# File 'lib/rubyfocus/patch.rb', line 9 def delete @delete end |
#fetcher ⇒ Object
The fetcher this patch belongs to. We mainly use this to work out how to fetch content for the patch proper
6 7 8 |
# File 'lib/rubyfocus/patch.rb', line 6 def fetcher @fetcher end |
#file ⇒ Object
The file the patch loads from
12 13 14 |
# File 'lib/rubyfocus/patch.rb', line 12 def file @file end |
#from_ids ⇒ Object
These record the transformation in terms of patch ID values.
15 16 17 |
# File 'lib/rubyfocus/patch.rb', line 15 def from_ids @from_ids end |
#time ⇒ Object
The time the file was submitted
18 19 20 |
# File 'lib/rubyfocus/patch.rb', line 18 def time @time end |
#to_id ⇒ Object
These record the transformation in terms of patch ID values.
15 16 17 |
# File 'lib/rubyfocus/patch.rb', line 15 def to_id @to_id end |
#update ⇒ Object
Update, delete and create methods
9 10 11 |
# File 'lib/rubyfocus/patch.rb', line 9 def update @update end |
Class Method Details
.from_string(fetcher, str) ⇒ Object
Load from a string.
48 49 50 51 52 |
# File 'lib/rubyfocus/patch.rb', line 48 def self.from_string(fetcher, str) n = new(fetcher) n.load_data(str) n end |
Instance Method Details
#<=>(o) ⇒ Object
120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 |
# File 'lib/rubyfocus/patch.rb', line 120 def <=> o if self.time.nil? if o.time.nil? 0 else -1 end else if o.time.nil? 1 else self.time <=> o.time end end end |
#apply_to(document) ⇒ Object
Apply this patch to a document. Check to make sure ids match
88 89 90 91 92 93 94 |
# File 'lib/rubyfocus/patch.rb', line 88 def apply_to(document) if can_patch?(document) apply_to!(document) else raise RuntimeError, "Patch ID mismatch (patch from_ids: [#{self.from_ids.join(", ")}], document.patch_id: #{document.patch_id}" end end |
#apply_to!(document) ⇒ Object
Apply this patch to a document.
97 98 99 100 101 102 103 104 105 106 107 108 109 |
# File 'lib/rubyfocus/patch.rb', line 97 def apply_to!(document) # Updates modify elements self.update.each{ |node| document.update_element(node) } # Deletes remove elements self.delete.each{ |node| document.remove_element(node["id"]) } # Creates make new elements self.create.each{ |node| document.update_element(node) } # Modify current patch_id to show new value document.patch_id = self.to_id end |
#can_patch?(document) ⇒ Boolean
Can we apply this patch to a given document?
83 84 85 |
# File 'lib/rubyfocus/patch.rb', line 83 def can_patch?(document) self.from_ids.include?(document.patch_id) end |
#load_data(str = nil) ⇒ Object
Loads data from the file. Optional argument str if you want to supply your own data, otherwise will load file data
56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 |
# File 'lib/rubyfocus/patch.rb', line 56 def load_data(str=nil) return if @data_loaded @data_loaded = true str ||= fetcher.patch(self.file) doc = Nokogiri::XML(str) doc.root.children.select{ |n| !n.text?}.each do |child| case child["op"] when "update" @update << child when "delete" @delete << child when "reference" # Ignore! when nil @create << child else raise RuntimeError, "Rubyfocus::Patch encountered unknown operation type #{child["op"]}." end end end |
#to_s ⇒ Object
String representation
112 113 114 115 116 117 118 |
# File 'lib/rubyfocus/patch.rb', line 112 def to_s if from_ids.size == 1 "(#{from_ids.first} -> #{to_id})" else "([#{from_ids.join(", ")}] -> #{to_id})" end end |