epitools 0.5.43 → 0.5.44

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 18aedb7dadd9b9a8cdfe9b619d228dc250ff2c0b
4
- data.tar.gz: 41feba1a86b88e3f0790151ef815e5f1c1ebf680
3
+ metadata.gz: c0522a13977563b564bdb275aeadf28428699aef
4
+ data.tar.gz: b0cdb112d922ea85c3a08f3ce56c44a58b2bfc12
5
5
  SHA512:
6
- metadata.gz: abf447f70c70e0b79f3b949a1faca4569f45325244dce43fffd1c139d94ff31c03151aec3368a6b18b8e528dec558572db31bc0385a993589297063fd7f6bf4f
7
- data.tar.gz: 55c84b31bb1f3182ea56354649036df86add2c3d72c4a80aba726f8db7ee4ad01692fb523dd80d353fe3a0d10c0652f8b5a941f64f22cc642ead7a567a32e439
6
+ metadata.gz: de0eff660c20c27c0769628ae29452e04832a3b7a279dfcde50b365984fca0a3057f692f83ce0f7b60e7ff76fcc49c8fbb2bdc88ff170098ddc879b1dc64e02f
7
+ data.tar.gz: da662e207de10d2f5a6f79492d18423114ec853e7dfd5694048128fa6690e72635f45160b0d4e4746d26830c926e2fa439e780bffe7fc031ae4a89ada4651aed
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.5.43
1
+ 0.5.44
@@ -224,5 +224,69 @@ class Hash
224
224
  end
225
225
  alias_method :mql, :query
226
226
 
227
+
228
+ #
229
+ # Return all the changes necessary to transform `self` into `other`. (Works on nested hashes.) The result is a hash of {:key => [old value, new value]} pairs.
230
+ #
231
+ # (NOTE: Since "nil" is used to denote a value was removed, you can't use this method to diff hashes where a value is "nil".)
232
+ #
233
+ def diff(other)
234
+ (self.keys + other.keys).uniq.inject({}) do |memo, key|
235
+ unless self[key] == other[key]
236
+ if self[key].kind_of?(Hash) && other[key].kind_of?(Hash)
237
+ memo[key] = self[key].diff(other[key])
238
+ else
239
+ memo[key] = [self[key], other[key]]
240
+ end
241
+ end
242
+ memo
243
+ end
244
+ end
245
+
246
+ #
247
+ # Applies a Hash#diff changeset to this hash.
248
+ #
249
+ def apply_diff!(changes)
250
+ path = [[self, changes]]
251
+ pos, local_changes = path.pop
252
+
253
+ while local_changes
254
+ local_changes.each_pair do |key, change|
255
+ if change.kind_of?(Array)
256
+ if change[1].nil?
257
+ pos.delete key
258
+ else
259
+ pos[key] = change[1]
260
+ end
261
+ else
262
+ path.push([pos[key], change])
263
+ end
264
+ end
265
+
266
+ pos, local_changes = path.pop
267
+ end
268
+
269
+ self
270
+ end
271
+
272
+ #
273
+ # Applies a Hash#diff changeset and returns the transformed hash.
274
+ #
275
+ def apply_diff(changes)
276
+ deep_dup.apply_diff!(changes)
277
+ end
278
+
279
+ #
280
+ # Duplicate this hash, including hashes nested inside of it.
281
+ #
282
+ def deep_dup
283
+ duplicate = self.dup
284
+ duplicate.each_pair do |k,v|
285
+ tv = duplicate[k]
286
+ duplicate[k] = tv.is_a?(Hash) && v.is_a?(Hash) ? tv.deep_dup : v
287
+ end
288
+ duplicate
289
+ end
290
+
227
291
  end
228
292
 
@@ -182,7 +182,7 @@ class Numeric
182
182
  result = "%0.2d:%0.2d" % [minutes,seconds]
183
183
  result = ("%0.2d:" % hours) + result if hours > 0 or days > 0
184
184
  result = ("%0.2d:" % days) + result if days > 0
185
- result += ("." + frac.round(2).to_s.split(".").last[0..1]) if frac > 0
185
+ result += ("." + frac.round(2).to_s.split(".").last) if frac > 0
186
186
 
187
187
  result
188
188
  end
data/lib/epitools/path.rb CHANGED
@@ -492,6 +492,22 @@ class Path
492
492
  end
493
493
  alias_method :xattrs, :attrs
494
494
 
495
+ #
496
+ # Set this file's xattrs. (Optimized so that only changed attrs are written to disk.)
497
+ #
498
+ def attrs=(new_attrs)
499
+ changes = attrs.diff(new_attrs)
500
+
501
+ changes.each do |key, (old, new)|
502
+ case new
503
+ when String, Numeric, Boolean, nil
504
+ self[key] = new
505
+ else
506
+ raise "Error: Can't use a #{new.class} as an xattr value. Try passing a String."
507
+ end
508
+ end
509
+ end
510
+
495
511
  #
496
512
  # Retrieve one of this file's xattrs
497
513
  #
@@ -507,7 +523,6 @@ class Path
507
523
  @attrs = nil
508
524
  end
509
525
 
510
-
511
526
  ###############################################################################
512
527
  # Opening/Reading files
513
528
  ###############################################################################
@@ -412,24 +412,24 @@ end
412
412
 
413
413
  describe Enumerable do
414
414
 
415
- it "maps deeply" do
416
- [["a\n", "b\n"], ["c\n", "d\n"]].map_recursively(&:strip).should == [ %w[a b], %w[c d] ]
415
+ # it "maps deeply" do
416
+ # [["a\n", "b\n"], ["c\n", "d\n"]].map_recursively(&:strip).should == [ %w[a b], %w[c d] ]
417
417
 
418
- [[1,2],[3,4]].deep_map {|e| e ** 2}.should == [[1,4],[9,16]]
419
- [1,2,3,4].deep_map {|e| e ** 2}.should == [1,4,9,16]
420
- [[],[],1,2,3,4].deep_map {|e| e ** 2}.should == [[], [], 1, 4, 9, 16]
418
+ # [[1,2],[3,4]].deep_map {|e| e ** 2}.should == [[1,4],[9,16]]
419
+ # [1,2,3,4].deep_map {|e| e ** 2}.should == [1,4,9,16]
420
+ # [[],[],1,2,3,4].deep_map {|e| e ** 2}.should == [[], [], 1, 4, 9, 16]
421
421
 
422
- {1=>2, 3=>{4=>5, 6=>7}}.deep_map {|k,v| [k, v**2] }.should == [ [1,4], [3, [[4,25], [6,49]]] ]
423
- end
422
+ # {1=>2, 3=>{4=>5, 6=>7}}.deep_map {|k,v| [k, v**2] }.should == [ [1,4], [3, [[4,25], [6,49]]] ]
423
+ # end
424
424
 
425
- it "selects deeply" do
426
- [[1,2],[3,4]].deep_select {|e| e % 2 == 0 }.should == [[2],[4]]
427
- puts
425
+ # it "selects deeply" do
426
+ # [[1,2],[3,4]].deep_select {|e| e % 2 == 0 }.should == [[2],[4]]
427
+ # puts
428
428
 
429
- {1=>2, 3=>{4=>5, 6=>7}}.deep_select {|k,v| k == 1 }.should == {1=>2}
430
- #[1,2,3,4].deep_select {|e| e ** 2}.should == [1,4,9,16]
431
- #[[],[],1,2,3,4].deep_select {|e| e ** 2}.should == [[], [], 1, 4, 9, 16]
432
- end
429
+ # {1=>2, 3=>{4=>5, 6=>7}}.deep_select {|k,v| k == 1 }.should == {1=>2}
430
+ # #[1,2,3,4].deep_select {|e| e ** 2}.should == [1,4,9,16]
431
+ # #[[],[],1,2,3,4].deep_select {|e| e ** 2}.should == [[], [], 1, 4, 9, 16]
432
+ # end
433
433
 
434
434
  it "splits" do
435
435
  [1,2,3,4,5].split_at {|e| e == 3}.should == [ [1,2], [4,5] ]
@@ -568,6 +568,18 @@ describe Hash do
568
568
  @h.key?("key1").should == true
569
569
  @h.includes?("key1").should == true
570
570
  end
571
+
572
+ it "diffs" do
573
+ a = {a: {c: 1, b: 2}, b: 2}
574
+ b = {a: {c: 2, b: 2}}
575
+
576
+ changes = a.diff(b)
577
+ changes.should == {:a=>{:c=>[1, 2]}, :b=>[2, nil]}
578
+ a.apply_diff(changes).should == b
579
+
580
+ a.apply_diff!(changes)
581
+ a.should == b
582
+ end
571
583
 
572
584
  end
573
585
 
data/spec/path_spec.rb CHANGED
@@ -504,6 +504,7 @@ describe Path do
504
504
  end
505
505
 
506
506
  it "xattrs" do
507
+
507
508
  file = Path["~/test"]
508
509
  file.touch
509
510
  file["nothing"].should == nil
@@ -518,6 +519,12 @@ describe Path do
518
519
  Path.getfattr(file)["user.test"].should == nil
519
520
 
520
521
  lambda { file["blahblahblah"] = "whee" }.should raise_error
522
+
523
+ # Test assigning an entire hash of attributes, using diffing
524
+ attrs = file.attrs
525
+ attrs["user.diff_element"] = "newtest"
526
+ file.attrs = attrs
527
+ file["user.newtest"].should == "newtest"
521
528
  end
522
529
 
523
530
  it "changes mtime/atime" do
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: epitools
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.43
4
+ version: 0.5.44
5
5
  platform: ruby
6
6
  authors:
7
7
  - epitron
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-12-21 00:00:00.000000000 Z
11
+ date: 2013-12-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rspec