georgi-git_store 0.1.1 → 0.2
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/.gitignore +1 -0
- data/README.md +137 -40
- data/git_store.gemspec +7 -2
- data/lib/git_store/blob.rb +64 -0
- data/lib/git_store/handlers.rb +57 -0
- data/lib/git_store/pack.rb +417 -0
- data/lib/git_store/tree.rb +207 -0
- data/lib/git_store.rb +267 -187
- data/test/benchmark.rb +30 -0
- data/test/git_store_spec.rb +212 -0
- metadata +7 -2
- data/spec/git_store_spec.rb +0 -117
@@ -0,0 +1,212 @@
|
|
1
|
+
require 'git_store'
|
2
|
+
require 'yaml'
|
3
|
+
require 'pp'
|
4
|
+
|
5
|
+
describe GitStore do
|
6
|
+
|
7
|
+
REPO = File.expand_path(File.dirname(__FILE__) + '/repo')
|
8
|
+
|
9
|
+
before do
|
10
|
+
FileUtils.rm_rf REPO
|
11
|
+
Dir.mkdir REPO
|
12
|
+
Dir.chdir REPO
|
13
|
+
end
|
14
|
+
|
15
|
+
def store
|
16
|
+
@store
|
17
|
+
end
|
18
|
+
|
19
|
+
def file(file, data)
|
20
|
+
FileUtils.mkpath(File.dirname(file))
|
21
|
+
open(file, 'w') { |io| io << data }
|
22
|
+
if @use_git
|
23
|
+
`git add #{file}`
|
24
|
+
`git commit -m 'added #{file}'`
|
25
|
+
File.unlink(file)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.it(text, &block)
|
30
|
+
super "#{text} with git" do
|
31
|
+
`git init`
|
32
|
+
@use_git = true
|
33
|
+
@store = GitStore.new(REPO)
|
34
|
+
instance_eval(&block)
|
35
|
+
end
|
36
|
+
|
37
|
+
super "#{text} without git" do
|
38
|
+
@use_git = false
|
39
|
+
@store = GitStore::FileStore.new(REPO)
|
40
|
+
instance_eval(&block)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
it 'should have a head commit' do
|
45
|
+
next unless @use_git
|
46
|
+
|
47
|
+
file 'a', 'Hello'
|
48
|
+
|
49
|
+
store.read_head.should_not be_nil
|
50
|
+
File.should be_exist(store.object_path(store.read_head))
|
51
|
+
end
|
52
|
+
|
53
|
+
it 'should detect changes' do
|
54
|
+
next unless @use_git
|
55
|
+
|
56
|
+
file 'a', 'Hello'
|
57
|
+
|
58
|
+
store.should be_changed
|
59
|
+
end
|
60
|
+
|
61
|
+
it 'should find modified entries' do
|
62
|
+
store['a'] = 'Hello'
|
63
|
+
|
64
|
+
store.root.should be_modified
|
65
|
+
store.root.table['a'].should be_modified
|
66
|
+
|
67
|
+
store.commit
|
68
|
+
|
69
|
+
store['a'] = 'Bello'
|
70
|
+
|
71
|
+
store.root.table['a'].should be_modified
|
72
|
+
end
|
73
|
+
|
74
|
+
it 'should load a repo' do
|
75
|
+
file 'a', 'Hello'
|
76
|
+
file 'b', 'World'
|
77
|
+
|
78
|
+
store.load
|
79
|
+
|
80
|
+
store['a'].should == 'Hello'
|
81
|
+
store['b'].should == 'World'
|
82
|
+
end
|
83
|
+
|
84
|
+
it 'should rollback a transaction' do
|
85
|
+
next if not @use_git
|
86
|
+
|
87
|
+
file 'a/b', 'Hello'
|
88
|
+
file 'c/d', 'World'
|
89
|
+
|
90
|
+
begin
|
91
|
+
store.transaction do
|
92
|
+
store['a/b'] = 'Changed'
|
93
|
+
store['x/a'] = 'Added'
|
94
|
+
raise
|
95
|
+
end
|
96
|
+
rescue
|
97
|
+
end
|
98
|
+
|
99
|
+
store['a/b'].should == 'Hello'
|
100
|
+
store['c/d'].should == 'World'
|
101
|
+
store['x/a'].should be_nil
|
102
|
+
end
|
103
|
+
|
104
|
+
it 'should commit a transaction' do
|
105
|
+
next if not @use_git
|
106
|
+
|
107
|
+
file 'a/b', 'Hello'
|
108
|
+
file 'c/d', 'World'
|
109
|
+
|
110
|
+
store.transaction do
|
111
|
+
store['a/b'] = 'Changed'
|
112
|
+
store['x/a'] = 'Added'
|
113
|
+
end
|
114
|
+
|
115
|
+
store.load
|
116
|
+
|
117
|
+
store['a/b'].should == 'Changed'
|
118
|
+
store['c/d'].should == 'World'
|
119
|
+
store['x/a'].should == 'Added'
|
120
|
+
end
|
121
|
+
|
122
|
+
it 'should allow only one transaction' do
|
123
|
+
next if not @use_git
|
124
|
+
|
125
|
+
file 'a/b', 'Hello'
|
126
|
+
|
127
|
+
ready = false
|
128
|
+
|
129
|
+
store.transaction do
|
130
|
+
Thread.start do
|
131
|
+
store.transaction do
|
132
|
+
store['a/b'] = 'Changed by second thread'
|
133
|
+
end
|
134
|
+
ready = true
|
135
|
+
end
|
136
|
+
store['a/b'] = 'Changed'
|
137
|
+
end
|
138
|
+
|
139
|
+
sleep 0.01 until ready
|
140
|
+
|
141
|
+
store.load
|
142
|
+
|
143
|
+
store['a/b'].should == 'Changed by second thread'
|
144
|
+
end
|
145
|
+
|
146
|
+
it 'should load folders' do
|
147
|
+
file 'x/a', 'Hello'
|
148
|
+
file 'y/b', 'World'
|
149
|
+
|
150
|
+
store.load
|
151
|
+
store['x'].should be_kind_of(GitStore::Tree)
|
152
|
+
store['y'].should be_kind_of(GitStore::Tree)
|
153
|
+
|
154
|
+
store['x']['a'].should == 'Hello'
|
155
|
+
store['y']['b'].should == 'World'
|
156
|
+
end
|
157
|
+
|
158
|
+
it 'should commit added files' do
|
159
|
+
next if not @use_git
|
160
|
+
|
161
|
+
store.load
|
162
|
+
store['c'] = 'Hello'
|
163
|
+
store['d'] = 'World'
|
164
|
+
store.commit
|
165
|
+
|
166
|
+
`git checkout`
|
167
|
+
|
168
|
+
File.should be_exist('c')
|
169
|
+
File.should be_exist('d')
|
170
|
+
|
171
|
+
File.read('c').should == 'Hello'
|
172
|
+
File.read('d').should == 'World'
|
173
|
+
end
|
174
|
+
|
175
|
+
it 'should load yaml' do
|
176
|
+
file 'x/a.yml', '[1, 2, 3, 4]'
|
177
|
+
|
178
|
+
store.load
|
179
|
+
|
180
|
+
store['x']['a.yml'].should == [1,2,3,4]
|
181
|
+
store['x']['a.yml'] = [1,2,3,4,5]
|
182
|
+
end
|
183
|
+
|
184
|
+
it 'should resolv paths' do
|
185
|
+
file 'x/a', 'Hello'
|
186
|
+
file 'y/b', 'World'
|
187
|
+
|
188
|
+
store.load
|
189
|
+
|
190
|
+
store['x/a'].should == 'Hello'
|
191
|
+
store['y/b'].should == 'World'
|
192
|
+
|
193
|
+
store['y/b'] = 'Now this'
|
194
|
+
|
195
|
+
store['y']['b'].should == 'Now this'
|
196
|
+
end
|
197
|
+
|
198
|
+
it 'should create new trees' do
|
199
|
+
store['new/tree'] = 'This tree'
|
200
|
+
store['this', 'tree'] = 'Another'
|
201
|
+
store['new/tree'].should == 'This tree'
|
202
|
+
store['this/tree'].should == 'Another'
|
203
|
+
end
|
204
|
+
|
205
|
+
it 'should delete entries' do
|
206
|
+
store['a'] = 'Hello'
|
207
|
+
store.delete('a')
|
208
|
+
|
209
|
+
store['a'].should be_nil
|
210
|
+
end
|
211
|
+
|
212
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: georgi-git_store
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: "0.2"
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Matthias Georgi
|
@@ -27,7 +27,12 @@ files:
|
|
27
27
|
- README.md
|
28
28
|
- git_store.gemspec
|
29
29
|
- lib/git_store.rb
|
30
|
-
-
|
30
|
+
- lib/git_store/blob.rb
|
31
|
+
- lib/git_store/tree.rb
|
32
|
+
- lib/git_store/handlers.rb
|
33
|
+
- lib/git_store/pack.rb
|
34
|
+
- test/git_store_spec.rb
|
35
|
+
- test/benchmark.rb
|
31
36
|
has_rdoc: true
|
32
37
|
homepage: http://github.com/georgi/git_store
|
33
38
|
post_install_message:
|
data/spec/git_store_spec.rb
DELETED
@@ -1,117 +0,0 @@
|
|
1
|
-
$:.unshift(File.expand_path(File.dirname(__FILE__) + '/../lib'))
|
2
|
-
|
3
|
-
require 'git_store'
|
4
|
-
require 'yaml'
|
5
|
-
|
6
|
-
describe GitStore do
|
7
|
-
|
8
|
-
REPO = File.expand_path(File.dirname(__FILE__) + '/test_repo')
|
9
|
-
|
10
|
-
before do
|
11
|
-
FileUtils.rm_rf REPO
|
12
|
-
Dir.mkdir REPO
|
13
|
-
Dir.chdir REPO
|
14
|
-
`git init`
|
15
|
-
end
|
16
|
-
|
17
|
-
def store
|
18
|
-
@store or
|
19
|
-
begin
|
20
|
-
@store = GitStore.new(REPO)
|
21
|
-
@store.load
|
22
|
-
@store
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
|
-
def file(file, data)
|
27
|
-
FileUtils.mkpath(File.dirname(file))
|
28
|
-
open(file, 'w') { |io| io << data }
|
29
|
-
`git add #{file}`
|
30
|
-
`git commit -m 'added #{file}'`
|
31
|
-
File.unlink(file)
|
32
|
-
end
|
33
|
-
|
34
|
-
it 'should load a repo' do
|
35
|
-
file 'a', 'Hello'
|
36
|
-
file 'b', 'World'
|
37
|
-
|
38
|
-
store['a'].should == 'Hello'
|
39
|
-
store['b'].should == 'World'
|
40
|
-
end
|
41
|
-
|
42
|
-
it 'should load folders' do
|
43
|
-
file 'x/a', 'Hello'
|
44
|
-
file 'y/b', 'World'
|
45
|
-
|
46
|
-
store['x'].should be_kind_of(GitStore::Tree)
|
47
|
-
store['y'].should be_kind_of(GitStore::Tree)
|
48
|
-
|
49
|
-
store['x']['a'].should == 'Hello'
|
50
|
-
store['y']['b'].should == 'World'
|
51
|
-
end
|
52
|
-
|
53
|
-
it 'should commit added files' do
|
54
|
-
store['c'] = 'Hello'
|
55
|
-
store['d'] = 'World'
|
56
|
-
store.commit
|
57
|
-
|
58
|
-
`git checkout`
|
59
|
-
|
60
|
-
File.should be_exist('c')
|
61
|
-
File.should be_exist('d')
|
62
|
-
|
63
|
-
File.read('c').should == 'Hello'
|
64
|
-
File.read('d').should == 'World'
|
65
|
-
end
|
66
|
-
|
67
|
-
it 'should load yaml' do
|
68
|
-
file 'x/a.yml', '[1, 2, 3, 4]'
|
69
|
-
|
70
|
-
store['x']['a.yml'].should == [1,2,3,4]
|
71
|
-
|
72
|
-
store['x']['a.yml'] = [1,2,3,4,5]
|
73
|
-
|
74
|
-
store.commit
|
75
|
-
store.load
|
76
|
-
|
77
|
-
store['x']['a.yml'].should == [1,2,3,4,5]
|
78
|
-
end
|
79
|
-
|
80
|
-
it 'should resolv paths' do
|
81
|
-
file 'x/a', 'Hello'
|
82
|
-
file 'y/b', 'World'
|
83
|
-
|
84
|
-
store['x/a'].should == 'Hello'
|
85
|
-
store['y/b'].should == 'World'
|
86
|
-
|
87
|
-
store['y/b'] = 'Now this'
|
88
|
-
|
89
|
-
store['y']['b'].should == 'Now this'
|
90
|
-
store.commit
|
91
|
-
store.load
|
92
|
-
|
93
|
-
store['y/b'].should == 'Now this'
|
94
|
-
end
|
95
|
-
|
96
|
-
it 'should create new trees' do
|
97
|
-
store['new/tree'] = 'This tree'
|
98
|
-
store['this', 'tree'] = 'Another'
|
99
|
-
store.commit
|
100
|
-
store.load
|
101
|
-
|
102
|
-
store['new/tree'].should == 'This tree'
|
103
|
-
store['this/tree'].should == 'Another'
|
104
|
-
end
|
105
|
-
|
106
|
-
it 'should preserve loaded trees' do
|
107
|
-
tree = store['tree'] = GitStore::Tree.new
|
108
|
-
store['tree']['example'] = 'Example'
|
109
|
-
store.commit
|
110
|
-
store.load
|
111
|
-
|
112
|
-
store['tree'].should == tree
|
113
|
-
end
|
114
|
-
|
115
|
-
end
|
116
|
-
|
117
|
-
|