Class: Treet::Repo
- Inherits:
-
Object
- Object
- Treet::Repo
- Defined in:
- lib/treet/repo.rb
Direct Known Subclasses
Instance Attribute Summary collapse
-
#root ⇒ Object
readonly
Returns the value of attribute root.
Class Method Summary collapse
-
.filefor(keyname) ⇒ Object
patch keys can look like name.first emails[] (address syntax has been eliminated, we recognize array elements by matching the entire content).
Instance Method Summary collapse
- #compare(target) ⇒ Object
-
#initialize(path, opts = {}) ⇒ Repo
constructor
A new instance of Repo.
-
#patch(diffs) ⇒ Object
Patching a repo is not the same as patching a hash.
- #to_hash ⇒ Object
Constructor Details
#initialize(path, opts = {}) ⇒ Repo
Returns a new instance of Repo.
6 7 8 9 10 |
# File 'lib/treet/repo.rb', line 6 def initialize(path, opts = {}) raise Errno::ENOENT, "Missing or invalid source path #{path}" unless File.directory?(path) @root = path end |
Instance Attribute Details
#root ⇒ Object (readonly)
Returns the value of attribute root.
4 5 6 |
# File 'lib/treet/repo.rb', line 4 def root @root end |
Class Method Details
.filefor(keyname) ⇒ Object
patch keys can look like
name.first
emails[]
(address syntax has been eliminated, we recognize array elements by matching the entire content)
24 25 26 27 28 29 30 31 32 33 34 35 36 |
# File 'lib/treet/repo.rb', line 24 def self.filefor(keyname) if keyname =~ /\[/ keyname = keyname.match(/^(.*)\[\]$/).captures.first [keyname, '', nil] elsif keyname =~ /\./ # subelement # negative lookbehind; don't split on a dot at beginning of string filename,field = keyname.split(/(?<!^)\./) ['.', filename, field] else ['.', keyname] end end |
Instance Method Details
#compare(target) ⇒ Object
16 17 18 |
# File 'lib/treet/repo.rb', line 16 def compare(target) Treet::Hash.diff(to_hash, target.to_hash) end |
#patch(diffs) ⇒ Object
Patching a repo is not the same as patching a hash. Make the changes directly to the data files.
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 71 72 73 74 75 76 77 78 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 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 |
# File 'lib/treet/repo.rb', line 40 def patch(diffs) @hash = nil # invalidate any cached image Dir.chdir(root) do diffs.each do |diff| flag, key, v1, _ = diff # if key =~ /\[/ # keyname = key.match(/^(.*)\[\]$/).captures # elsif key =~ /\./ # keyname, subkey = key.match(/^(.*)\.(.*)$/).captures # else # keyname = key # end dirname, filename, fieldname = Treet::Repo.filefor(key) filepath = "#{dirname}/#{filename}" case flag when '~' # change a value in place # load the current data & overwrite with the new value # idempotent: this will overwrite the file with the same contents if fieldname # hash entry data = File.exists?(filepath) ? JSON.load(File.open(filepath)) : {} data[fieldname] = v1 File.open(filepath, "w") {|f| f << JSON.pretty_generate(data)} else # string entry File.open(filepath, "w") {|f| f << v1} end when '+' # add something if fieldname # writing a value into a hash # idempotent: this will overwrite the file with the same contents data = File.exists?(filepath) ? JSON.load(File.open(filepath)) : {} data[fieldname] = v1 Dir.mkdir(dirname) unless Dir.exists?(dirname) File.open(filepath, "w") {|f| f << JSON.pretty_generate(data)} else # writing an entire hash into an array entry # idempotent: this will overwrite the file with the same contents subfile = "#{dirname}/#{Treet::Hash.digestify(v1)}" Dir.mkdir(dirname) unless Dir.exists?(dirname) case v1 when Hash # hash entry File.open(subfile, "w") {|f| f << JSON.pretty_generate(v1)} else # string entry - create empty file with this name FileUtils.touch(subfile) end end when '-' # remove something if fieldname # this is a key in a subhash if File.exists?(filepath) # if the subhash is missing, there's nothing to remove, so do nothing (for idempotence) data = JSON.load(File.open(filepath)) data.delete(fieldname) if data.empty? # all keys have been removed, clean up the file File.delete(filename) else File.open(filepath, "w") {|f| f << JSON.pretty_generate(data)} end end elsif dirname == "." # this is a top-level string File.delete(filename) if File.exists?(filename) # need the existence check for idempotence else # this is an array, we look for a match on the entire contents via digest subfile = "#{dirname}/#{Treet::Hash.digestify(v1)}" File.delete(subfile) if File.exists?(subfile) # need the existence check for idempotence # TODO: if dirname is now empty, should it be removed? is that worthwhile? end end end end to_hash # ?? return the patched data? or no return value? true/false for success? end |
#to_hash ⇒ Object
12 13 14 |
# File 'lib/treet/repo.rb', line 12 def to_hash (root) end |