gibbler 0.5.2 → 0.5.3
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.
- data/CHANGES.txt +8 -1
- data/README.rdoc +14 -0
- data/gibbler.gemspec +7 -1
- data/lib/gibbler/aliases.rb +29 -0
- data/lib/gibbler/history.rb +22 -19
- data/lib/gibbler/object.rb +39 -0
- data/lib/gibbler.rb +10 -2
- data/tryouts/10_basic_tryouts.rb +14 -1
- data/tryouts/51_hash_history_tryouts.rb +2 -2
- data/tryouts/80_performance_tryouts.rb +1 -1
- data/tryouts/90_alias_tryouts.rb +60 -0
- metadata +16 -4
data/CHANGES.txt
CHANGED
@@ -1,7 +1,14 @@
|
|
1
1
|
GIBBLER, CHANGES
|
2
2
|
|
3
|
+
#### 0.5.3 (2009-07-12) #################################
|
3
4
|
|
4
|
-
|
5
|
+
* FIXED: Updated gemspec to fix missing files (aliases)
|
6
|
+
* CHANGE: conversion to attic instead of weirdo instance
|
7
|
+
variables (@__gibbler__ and @__gibbler_history)
|
8
|
+
* NEW DEPENDENCY: attic
|
9
|
+
|
10
|
+
|
11
|
+
#### 0.5.2 (2009-07-07) #################################
|
5
12
|
|
6
13
|
* CHANGE: Moved Gibbler instance methods to Gibbler::Object
|
7
14
|
* ADDED: Proc.gibbler which is included by default
|
data/README.rdoc
CHANGED
@@ -144,6 +144,20 @@ The gibbler_revert! method modifies the object in place so this was an important
|
|
144
144
|
* gibbler or gibbled? must be called at least once before gibbled? will be able to return a useful value (otherwise there is no previous digest value to compare to)
|
145
145
|
|
146
146
|
|
147
|
+
== Installation
|
148
|
+
|
149
|
+
Via Rubygems, one of:
|
150
|
+
|
151
|
+
$ gem install gibbler
|
152
|
+
$ gem install delano-gibbler
|
153
|
+
|
154
|
+
|
155
|
+
or via download:
|
156
|
+
* gibbler-latest.tar.gz[http://github.com/delano/gibbler/tarball/latest]
|
157
|
+
* gibbler-latest.zip[http://github.com/delano/gibbler/zipball/latest]
|
158
|
+
|
159
|
+
|
160
|
+
|
147
161
|
== More Info
|
148
162
|
|
149
163
|
* Codes[http://github.com/delano/gibbler]
|
data/gibbler.gemspec
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
@spec = Gem::Specification.new do |s|
|
2
2
|
s.name = "gibbler"
|
3
3
|
s.rubyforge_project = "gibbler"
|
4
|
-
s.version = "0.5.
|
4
|
+
s.version = "0.5.3"
|
5
5
|
s.summary = "Gibbler: Git-like hashes for Ruby objects"
|
6
6
|
s.description = s.summary
|
7
7
|
s.author = "Delano Mandelbaum"
|
@@ -23,6 +23,9 @@
|
|
23
23
|
# Update --main to reflect the default page to display
|
24
24
|
s.rdoc_options = ["--line-numbers", "--title", s.summary, "--main", "README.rdoc"]
|
25
25
|
|
26
|
+
# = DEPENDENCIES =
|
27
|
+
s.add_dependency 'attic'
|
28
|
+
|
26
29
|
# = MANIFEST =
|
27
30
|
s.files = %w(
|
28
31
|
CHANGES.txt
|
@@ -31,10 +34,12 @@
|
|
31
34
|
Rakefile
|
32
35
|
gibbler.gemspec
|
33
36
|
lib/gibbler.rb
|
37
|
+
lib/gibbler/aliases.rb
|
34
38
|
lib/gibbler/digest.rb
|
35
39
|
lib/gibbler/history.rb
|
36
40
|
lib/gibbler/mixins.rb
|
37
41
|
lib/gibbler/mixins/string.rb
|
42
|
+
lib/gibbler/object.rb
|
38
43
|
tryouts/01_mixins_tryouts.rb
|
39
44
|
tryouts/05_gibbler_digest_tryouts.rb
|
40
45
|
tryouts/10_basic_tryouts.rb
|
@@ -46,6 +51,7 @@
|
|
46
51
|
tryouts/57_arbitrary_history_tryouts.rb
|
47
52
|
tryouts/59_history_exceptions_tryouts.rb
|
48
53
|
tryouts/80_performance_tryouts.rb
|
54
|
+
tryouts/90_alias_tryouts.rb
|
49
55
|
tryouts/object_hash_demo.rb
|
50
56
|
)
|
51
57
|
|
@@ -0,0 +1,29 @@
|
|
1
|
+
|
2
|
+
|
3
|
+
module Gibbler
|
4
|
+
|
5
|
+
|
6
|
+
module Object
|
7
|
+
alias :digest :gibbler
|
8
|
+
alias :changed? :gibbled?
|
9
|
+
end
|
10
|
+
|
11
|
+
#--
|
12
|
+
# Aliases for Gibbler::History methods
|
13
|
+
#
|
14
|
+
# NOTE: we explicitly define the methods rather than use "alias"
|
15
|
+
# in the event that the require 'gibbler/aliases' appears before
|
16
|
+
# require 'gibbler/history' (alias complains about unknown methods)
|
17
|
+
#++
|
18
|
+
module History
|
19
|
+
def history(*args, &b); gibbler_history(*args, &b); end
|
20
|
+
def commit; gibbler_commit; end
|
21
|
+
def object(*args, &b); gibbler_object(*args, &b); end
|
22
|
+
def stamp(*args, &b); gibbler_stamp(*args, &b); end
|
23
|
+
def revert!(*args, &b); gibbler_revert!(*args, &b); end
|
24
|
+
def history?; gibbler_history?; end
|
25
|
+
def valid?(*args, &b); gibbler_valid?(*args, &b); end
|
26
|
+
def find_long(*args, &b); gibbler_find_long(*args, &b); end
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
data/lib/gibbler/history.rb
CHANGED
@@ -13,6 +13,9 @@ module Gibbler
|
|
13
13
|
end
|
14
14
|
|
15
15
|
module History
|
16
|
+
extend Attic
|
17
|
+
|
18
|
+
attic :__gibbler_history
|
16
19
|
|
17
20
|
@@mutex = Mutex.new
|
18
21
|
|
@@ -23,15 +26,15 @@ module Gibbler
|
|
23
26
|
# to the short 8 character digests.
|
24
27
|
def gibbler_history(short=false)
|
25
28
|
# Only a single thread should attempt to initialize the store.
|
26
|
-
if
|
29
|
+
if self.__gibbler_history.nil?
|
27
30
|
@@mutex.synchronize {
|
28
|
-
|
31
|
+
self.__gibbler_history ||= { :history => [], :objects => {}, :stamp => {} }
|
29
32
|
}
|
30
33
|
end
|
31
34
|
if short == false
|
32
|
-
|
35
|
+
self.__gibbler_history[:history]
|
33
36
|
else
|
34
|
-
|
37
|
+
self.__gibbler_history[:history].collect { |g| g.short }
|
35
38
|
end
|
36
39
|
end
|
37
40
|
|
@@ -42,7 +45,7 @@ module Gibbler
|
|
42
45
|
g = self.gibbler_history.last if g.nil?
|
43
46
|
|
44
47
|
return unless gibbler_valid? g
|
45
|
-
|
48
|
+
self.__gibbler_history[:objects][ g ]
|
46
49
|
end
|
47
50
|
|
48
51
|
# Returns the timestamp (a Time object) when the digest +g+ was committed.
|
@@ -51,7 +54,7 @@ module Gibbler
|
|
51
54
|
g = gibbler_find_long g
|
52
55
|
g = self.gibbler_history.last if g.nil?
|
53
56
|
return unless gibbler_valid? g
|
54
|
-
|
57
|
+
self.__gibbler_history[:stamp][ g ]
|
55
58
|
end
|
56
59
|
|
57
60
|
# Stores a clone of the current object instance using the current
|
@@ -68,17 +71,17 @@ module Gibbler
|
|
68
71
|
def gibbler_commit
|
69
72
|
now, digest, point = nil,nil,nil
|
70
73
|
|
71
|
-
if
|
74
|
+
if self.__gibbler_history.nil?
|
72
75
|
@@mutex.synchronize {
|
73
|
-
|
76
|
+
self.__gibbler_history ||= { :history => [], :objects => {}, :stamp => {} }
|
74
77
|
}
|
75
78
|
end
|
76
79
|
|
77
80
|
@@mutex.synchronize {
|
78
81
|
now, digest, point = Time.now, self.gibbler, self.clone
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
+
self.__gibbler_history[:history] << digest
|
83
|
+
self.__gibbler_history[:stamp][digest] = now
|
84
|
+
self.__gibbler_history[:objects][digest] = point
|
82
85
|
}
|
83
86
|
|
84
87
|
digest
|
@@ -101,7 +104,7 @@ module Gibbler
|
|
101
104
|
#
|
102
105
|
# Returns the new digest (+g+).
|
103
106
|
def gibbler_revert!(g=nil)
|
104
|
-
raise NoRevert unless self.respond_to?
|
107
|
+
raise NoRevert unless self.respond_to? :__gibbler_revert!
|
105
108
|
raise NoHistory, self.class unless gibbler_history?
|
106
109
|
raise BadDigest, g if !g.nil? && !gibbler_valid?(g)
|
107
110
|
|
@@ -109,16 +112,16 @@ module Gibbler
|
|
109
112
|
g = gibbler_find_long g
|
110
113
|
|
111
114
|
# Do nothing if the given digest matches the current gibble.
|
112
|
-
# NOTE: We use __gibbler b/c it doesn't update
|
115
|
+
# NOTE: We use __gibbler b/c it doesn't update self.__gibbler_cache.
|
113
116
|
unless self.__gibbler == g
|
114
117
|
@@mutex.synchronize {
|
115
|
-
# Always make sure
|
116
|
-
|
118
|
+
# Always make sure self.gibbler_digest is a Gibbler::Digest
|
119
|
+
self.__gibbler_cache = g.is_a?(Gibbler::Digest) ? g : Gibbler::Digest.new(g)
|
117
120
|
self.__gibbler_revert!
|
118
121
|
}
|
119
122
|
end
|
120
123
|
|
121
|
-
|
124
|
+
self.__gibbler_cache
|
122
125
|
end
|
123
126
|
|
124
127
|
# Is the given digest +g+ contained in the history for this object?
|
@@ -147,7 +150,7 @@ class Hash
|
|
147
150
|
include Gibbler::History
|
148
151
|
def __gibbler_revert!
|
149
152
|
self.clear
|
150
|
-
self.merge! self.gibbler_object
|
153
|
+
self.merge! self.gibbler_object(self.__gibbler_cache)
|
151
154
|
end
|
152
155
|
end
|
153
156
|
|
@@ -155,7 +158,7 @@ class Array
|
|
155
158
|
include Gibbler::History
|
156
159
|
def __gibbler_revert!
|
157
160
|
self.clear
|
158
|
-
self.push *(self.gibbler_object
|
161
|
+
self.push *(self.gibbler_object self.__gibbler_cache)
|
159
162
|
end
|
160
163
|
end
|
161
164
|
|
@@ -163,7 +166,7 @@ class String
|
|
163
166
|
include Gibbler::History
|
164
167
|
def __gibbler_revert!
|
165
168
|
self.clear
|
166
|
-
self << (self.gibbler_object
|
169
|
+
self << (self.gibbler_object self.__gibbler_cache)
|
167
170
|
end
|
168
171
|
end
|
169
172
|
|
@@ -0,0 +1,39 @@
|
|
1
|
+
|
2
|
+
|
3
|
+
module Gibbler
|
4
|
+
|
5
|
+
module Object
|
6
|
+
extend Attic
|
7
|
+
|
8
|
+
attic :__gibbler_cache
|
9
|
+
|
10
|
+
# Calculates a digest for the current object instance.
|
11
|
+
# Objects that are a kind of Hash or Array are processed
|
12
|
+
# recursively. The length of the returned String depends
|
13
|
+
# on the digest type.
|
14
|
+
def gibbler
|
15
|
+
gibbler_debug :GIBBLER, self.class, self
|
16
|
+
self.__gibbler_cache = Gibbler::Digest.new self.__gibbler
|
17
|
+
end
|
18
|
+
|
19
|
+
# Has this object been modified?
|
20
|
+
#
|
21
|
+
# This method compares the return value from digest with the
|
22
|
+
# previous value returned by gibbler (the value is stored in
|
23
|
+
# the attic as <tt>__gibbler_cache</tt>).
|
24
|
+
# See Attic[http://github.com/delano/attic]
|
25
|
+
def gibbled?
|
26
|
+
self.__gibbler_cache ||= self.gibbler
|
27
|
+
was, now = self.__gibbler_cache.clone, self.gibbler
|
28
|
+
gibbler_debug :gibbled?, was, now
|
29
|
+
was != now
|
30
|
+
end
|
31
|
+
|
32
|
+
def gibbler_debug(*args)
|
33
|
+
return unless Gibbler.debug?
|
34
|
+
p args
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
data/lib/gibbler.rb
CHANGED
@@ -1,12 +1,19 @@
|
|
1
1
|
|
2
|
+
local_libs = %w{attic}
|
3
|
+
local_libs.each { |dir| $:.unshift File.join(File.dirname(__FILE__), '..', '..', dir, 'lib') }
|
4
|
+
|
2
5
|
require 'digest/sha1'
|
6
|
+
require 'attic'
|
3
7
|
|
4
8
|
# = Gibbler
|
5
9
|
#
|
6
10
|
# "Hola, Tanneritos"
|
7
11
|
#
|
8
12
|
module Gibbler
|
9
|
-
|
13
|
+
#include Attic
|
14
|
+
extend Attic
|
15
|
+
|
16
|
+
VERSION = "0.5.3"
|
10
17
|
|
11
18
|
require 'gibbler/object'
|
12
19
|
require 'gibbler/digest'
|
@@ -75,7 +82,7 @@ module Gibbler
|
|
75
82
|
end
|
76
83
|
|
77
84
|
def __gibbler_revert!
|
78
|
-
state = self.gibbler_object
|
85
|
+
state = self.gibbler_object self.__gibbler_cache
|
79
86
|
state.instance_variables do |n|
|
80
87
|
v = state.instance_variable_get n
|
81
88
|
self.instance_variable_set v
|
@@ -86,6 +93,7 @@ module Gibbler
|
|
86
93
|
|
87
94
|
module String
|
88
95
|
include Gibbler::Object
|
96
|
+
|
89
97
|
# Creates a digest based on: <tt>CLASS:LENGTH:VALUE</tt>.
|
90
98
|
# This method can be used for any class where the <tt>to_s</tt>
|
91
99
|
# method returns an appropriate unique value for this instance.
|
data/tryouts/10_basic_tryouts.rb
CHANGED
@@ -52,7 +52,7 @@ tryouts "Basic syntax with SHA1" do
|
|
52
52
|
|
53
53
|
dream :gibbler, "884e5713aa70468333459f80aea1bb05394ca4ba"
|
54
54
|
drill "Populated Array instance" do
|
55
|
-
[1,
|
55
|
+
[1, 2, :runtime, [3, "four", [Object, true]]]
|
56
56
|
end
|
57
57
|
|
58
58
|
drill "Knows when a Hash has not changed", false do
|
@@ -84,9 +84,22 @@ tryouts "Basic syntax with SHA1" do
|
|
84
84
|
a = {}
|
85
85
|
a.gibbler # We need to gibbler first so it sets a value to the instance var
|
86
86
|
val = Tryouts.sysinfo.ruby[1] == 9 ? :'@__gibbler_digest__' : '@__gibbler_digest__'
|
87
|
+
stash :ivars, a.instance_variables
|
88
|
+
stash :smeths, Gibbler.singleton_methods
|
87
89
|
a.instance_variables.member? val
|
88
90
|
end
|
89
91
|
|
92
|
+
drill "previous digest", 'c8027100ecc54945ab15ddac529230e38b1ba6a1' do
|
93
|
+
a = "kimmy"
|
94
|
+
a.gibbler
|
95
|
+
#stash :methods, a.methods.sort
|
96
|
+
#
|
97
|
+
#stash :string_methods, String.methods.sort
|
98
|
+
#stash :gstring_methods, Gibbler::String.methods.sort
|
99
|
+
#stash :class_methods, a.class.methods.sort
|
100
|
+
stash :ivars, a.instance_variables
|
101
|
+
a.__gibbler_cache
|
102
|
+
end
|
90
103
|
|
91
104
|
end
|
92
105
|
|
@@ -16,10 +16,10 @@ tryouts "Hash History" do
|
|
16
16
|
end
|
17
17
|
end
|
18
18
|
|
19
|
-
drill "doesn't reveal
|
19
|
+
drill "doesn't reveal self.__gibbler_history instance variable", false do
|
20
20
|
a = {}
|
21
21
|
a.gibbler # We need to gibbler first so it sets a value to the instance var
|
22
|
-
val = Tryouts.sysinfo.ruby[1] == 9 ? :'
|
22
|
+
val = Tryouts.sysinfo.ruby[1] == 9 ? :'self.__gibbler_history' : 'self.__gibbler_history'
|
23
23
|
a.instance_variables.member? val
|
24
24
|
end
|
25
25
|
|
@@ -0,0 +1,60 @@
|
|
1
|
+
|
2
|
+
group "Aliases"
|
3
|
+
|
4
|
+
library :gibbler, 'lib'
|
5
|
+
library 'gibbler/aliases', 'lib'
|
6
|
+
library 'gibbler/history', 'lib'
|
7
|
+
|
8
|
+
tryouts "Gibbler::Object Aliases" do
|
9
|
+
|
10
|
+
drill "has digest", true do
|
11
|
+
:kimmy.gibbler == :kimmy.digest
|
12
|
+
end
|
13
|
+
|
14
|
+
drill "has changed?", true do
|
15
|
+
a = "kimmy"
|
16
|
+
a.digest
|
17
|
+
a << '+ dj'
|
18
|
+
a.gibbled?
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
22
|
+
|
23
|
+
|
24
|
+
tryouts "Gibbler::History Aliases" do
|
25
|
+
|
26
|
+
dream "d7049916ddb25e6cc438b1028fb957e5139f9910"
|
27
|
+
drill "can convert short digest into long" do
|
28
|
+
a = { :magic => :original }
|
29
|
+
g = a.commit.short
|
30
|
+
stash :short, g
|
31
|
+
a.find_long g
|
32
|
+
end
|
33
|
+
|
34
|
+
dream :class, Time
|
35
|
+
drill "can return most recent stamp" do
|
36
|
+
a = { :magic => :original }
|
37
|
+
a.commit
|
38
|
+
stash :hist, a.history
|
39
|
+
a.stamp
|
40
|
+
end
|
41
|
+
|
42
|
+
dream ["d7049916ddb25e6cc438b1028fb957e5139f9910", "0b11c377fccd44554a601e5d2b135c46dc1c4cb1"]
|
43
|
+
drill "can return history" do
|
44
|
+
a = { :magic => :original }
|
45
|
+
a.commit
|
46
|
+
a[:magic] = :changed
|
47
|
+
a.commit
|
48
|
+
a.history
|
49
|
+
end
|
50
|
+
|
51
|
+
dream ["d7049916", "0b11c377"]
|
52
|
+
drill "can return history (short)" do
|
53
|
+
a = { :magic => :original }
|
54
|
+
a.commit
|
55
|
+
a[:magic] = :changed
|
56
|
+
a.commit
|
57
|
+
a.history(:short)
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: gibbler
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.5.
|
4
|
+
version: 0.5.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Delano Mandelbaum
|
@@ -9,10 +9,19 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-07-
|
12
|
+
date: 2009-07-12 00:00:00 -04:00
|
13
13
|
default_executable:
|
14
|
-
dependencies:
|
15
|
-
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: attic
|
17
|
+
type: :runtime
|
18
|
+
version_requirement:
|
19
|
+
version_requirements: !ruby/object:Gem::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">="
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: "0"
|
24
|
+
version:
|
16
25
|
description: "Gibbler: Git-like hashes for Ruby objects"
|
17
26
|
email: delano@solutious.com
|
18
27
|
executables: []
|
@@ -29,10 +38,12 @@ files:
|
|
29
38
|
- Rakefile
|
30
39
|
- gibbler.gemspec
|
31
40
|
- lib/gibbler.rb
|
41
|
+
- lib/gibbler/aliases.rb
|
32
42
|
- lib/gibbler/digest.rb
|
33
43
|
- lib/gibbler/history.rb
|
34
44
|
- lib/gibbler/mixins.rb
|
35
45
|
- lib/gibbler/mixins/string.rb
|
46
|
+
- lib/gibbler/object.rb
|
36
47
|
- tryouts/01_mixins_tryouts.rb
|
37
48
|
- tryouts/05_gibbler_digest_tryouts.rb
|
38
49
|
- tryouts/10_basic_tryouts.rb
|
@@ -44,6 +55,7 @@ files:
|
|
44
55
|
- tryouts/57_arbitrary_history_tryouts.rb
|
45
56
|
- tryouts/59_history_exceptions_tryouts.rb
|
46
57
|
- tryouts/80_performance_tryouts.rb
|
58
|
+
- tryouts/90_alias_tryouts.rb
|
47
59
|
- tryouts/object_hash_demo.rb
|
48
60
|
has_rdoc: true
|
49
61
|
homepage: http://github.com/delano/gibbler
|