gaga 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -60,6 +60,46 @@ Returns an array of commit messages along with meta data about each key/value sa
60
60
  ]
61
61
  ```
62
62
 
63
+ ### Options
64
+
65
+ Custom commit options can be set globally when creating a new Gaga instance, or
66
+ passed in with calls to #set, #delete, or #clear.
67
+
68
+ Examples:
69
+
70
+ ```ruby
71
+ # Global options
72
+ store1 = Gaga.new(
73
+ :repo => '/path/to/repo/',
74
+ :branch => :example,
75
+ :author => {
76
+ :name => 'Jim Bob',
77
+ :email => 'jbob@example.com'
78
+ },
79
+ :committer => {
80
+ :name => 'Jane Doe',
81
+ :email => 'jdoe@example.com'
82
+ }
83
+ )
84
+
85
+ # Custom message when storing a key/value
86
+ store1.set('key_1', 'Hello World', {:message => 'This is a custom commit log message'})
87
+
88
+ store2 = Gaga.new(:repo => '/path/to/repo/', :branch => :example)
89
+
90
+ # Assigns an author when storing a key/value
91
+ store2.set('key_1', 'Goodbye', {
92
+ :message => 'Another custom log message',
93
+ :author => {
94
+ :name => 'Sally',
95
+ :email => 'sally@example.com'
96
+ }
97
+ })
98
+
99
+ # Delete operations can also have a custom message
100
+ store2.delete('key_1', {:message => 'Farewell message'})
101
+ ```
102
+
63
103
  Installing Gaga
64
104
  ----------
65
105
 
@@ -5,9 +5,14 @@ require 'gaga/version'
5
5
  class Gaga
6
6
 
7
7
  def initialize(options = {})
8
+ @author = options.delete(:author)
9
+ @committer = options.delete(:committer)
8
10
  @options = options
9
- unless ::File.exists?(File.join(path,'.git'))
10
- Grit::Repo.init(path)
11
+
12
+ if path.end_with?('.git/')
13
+ Grit::Repo.init_bare(path) unless File.exists?(File.join(path,'refs'))
14
+ else
15
+ Grit::Repo.init(path) unless File.exists?(File.join(path,'.git'))
11
16
  end
12
17
  end
13
18
 
@@ -17,9 +22,11 @@ class Gaga
17
22
  # @store.set('key', 'value')
18
23
  #
19
24
  # Returns nothing
20
- def set(key, value)
21
- save("set '#{key}'") do |index|
22
- index.add(key_for(key), encode(value))
25
+ def set(key, value, opts = {})
26
+ unless value == get(key)
27
+ save(setup_commit_options({:message => "set '#{key}'"}.merge(opts))) do |index|
28
+ index.add(key_for(key), encode(value))
29
+ end
23
30
  end
24
31
  end
25
32
 
@@ -68,17 +75,18 @@ class Gaga
68
75
  # @store.delete('key')
69
76
  #
70
77
  # Returns nothing
71
- def delete(key, *)
78
+ def delete(key, opts = {})
79
+ options = setup_commit_options({:message => "deleted #{key}"}.merge(opts))
72
80
  self[key].tap do
73
- save("deleted #{key}") {|index| index.delete(key_for(key)) }
81
+ save(options) {|index| index.delete(key_for(key)) }
74
82
  end
75
83
  end
76
84
 
77
85
  # Deletes all contents of the store
78
86
  #
79
87
  # Returns nothing
80
- def clear
81
- save("all clear") do |index|
88
+ def clear(opts = {})
89
+ save(setup_commit_options({:message => "all clear"}.merge(opts))) do |index|
82
90
  if tree = index.current_tree
83
91
  tree.contents.each do |entry|
84
92
  index.delete(key_for(entry.name))
@@ -108,6 +116,13 @@ class Gaga
108
116
  end
109
117
 
110
118
  private
119
+
120
+ def setup_commit_options(opts = {})
121
+ {
122
+ :author => @author,
123
+ :committer => @committer
124
+ }.merge(opts)
125
+ end
111
126
 
112
127
  # Format the given key so that it ensures it's git worthy
113
128
  def key_for(key)
@@ -121,7 +136,7 @@ class Gaga
121
136
 
122
137
  # The git branch to use for this store
123
138
  def branch
124
- @options[:branch].to_s || 'master'
139
+ (@options[:branch] || 'master').to_s
125
140
  end
126
141
 
127
142
  # Checks out the branch on the repo
@@ -130,14 +145,17 @@ class Gaga
130
145
  end
131
146
 
132
147
  # Commits the the value into the git repository with the given commit message
133
- def save(message)
148
+ def save(options)
149
+ author = options[:author] ? Grit::Actor.new(options[:author][:name], options[:author][:email]) : nil
150
+ committer = options[:committer] ? Grit::Actor.new(options[:committer][:name], options[:committer][:email]) : nil
151
+
134
152
  index = git.index
135
153
  if head
136
154
  commit = head.commit
137
155
  index.current_tree = commit.tree
138
156
  end
139
157
  yield index
140
- index.commit(message, :parents => Array(commit), :head => branch) if index.tree.any?
158
+ index.commit(options[:message], :parents => Array(commit), :author => author, :committer => committer, :head => branch) if index.tree.any?
141
159
  end
142
160
 
143
161
  # Converts the value to yaml format
@@ -1,3 +1,3 @@
1
1
  class Gaga
2
- VERSION = "0.0.2"
2
+ VERSION = "0.0.3"
3
3
  end
@@ -23,10 +23,59 @@ describe Gaga do
23
23
  @store[key] = "value"
24
24
  @store[key].must_equal "value"
25
25
  end
26
+
27
+ it "writes String values to keys with explicit custom log data" do
28
+ @store.set(key, "value", {:message => "Custom message", :author => {:name => 'Test', :email => 'test@example.com'} })
29
+ @store[key].must_equal "value"
30
+
31
+ entry = @store.log(key).first
32
+ entry['message'].must_equal "Custom message"
33
+ entry['author'].must_equal({'name' => 'Test', 'email' => 'test@example.com'})
34
+ end
35
+
36
+ it "writes String values to keys with global custom log data" do
37
+ store = Gaga.new(
38
+ :repo => tmp_dir,
39
+ :branch => :lady,
40
+ :author => {:name => 'Test', :email => 'test@example.com'},
41
+ :committer => {:name => 'Test2', :email => 'test2@example.com'}
42
+ )
43
+
44
+ store.set(key, "value", {:message => "Custom message"})
45
+ store[key].must_equal "value"
46
+
47
+ entry = store.log(key).first
48
+ entry['message'].must_equal "Custom message"
49
+ entry['author'].must_equal({'name' => 'Test', 'email' => 'test@example.com'})
50
+ entry['committer'].must_equal({'name' => 'Test2', 'email' => 'test2@example.com'})
51
+ end
52
+
53
+ it "does not create empty commit" do
54
+ grit = Grit::Repo.new(tmp_dir)
55
+ initial_count = grit.commit_count
56
+
57
+ @master.set(key, "value", {:message => 'First commit'})
58
+ @master.set(key, "value", {:message => 'Second commit'})
59
+
60
+ current_count = grit.commit_count
61
+
62
+ (current_count - initial_count).must_equal 1
63
+ @master[key].must_equal "value"
64
+ end
26
65
 
27
66
  it "reads from keys" do
28
67
  @store[key].must_be_nil
29
68
  end
69
+
70
+ it "should default to master when no branch is specified" do
71
+ value = 'testing'
72
+ @master[key] = value
73
+ @master[key].must_equal value
74
+ @store[key].must_be_nil
75
+
76
+ tmp = Gaga.new(:repo => tmp_dir, :branch => :master)
77
+ tmp[key].must_equal value
78
+ end
30
79
 
31
80
  it 'guarantess the key is stored in the right branch' do
32
81
  @store[key] = 'value'
@@ -70,6 +119,15 @@ describe Gaga do
70
119
  @store.delete(key).must_equal "value"
71
120
  @store.key?(key).must_equal false
72
121
  end
122
+
123
+ it "removes a key using a custom commit message" do
124
+ @store[key] = "value"
125
+ @store.delete(key, {:message => "Removed it"}).must_equal "value"
126
+ @store.key?(key).must_equal false
127
+
128
+ entry = @store.log(key).first
129
+ entry['message'].must_equal "Removed it"
130
+ end
73
131
 
74
132
  it "returns nil from delete if an element for a key does not exist" do
75
133
  @store.delete(key).must_be_nil
@@ -82,6 +140,19 @@ describe Gaga do
82
140
  @store.key?(key).wont_equal true
83
141
  @store.key?(key2).wont_equal true
84
142
  end
143
+
144
+ it "removes all keys from the store with clear and custom commit message" do
145
+ @store[key] = "value"
146
+ @store[key2] = "value2"
147
+ @store.clear({:message => "All gone"})
148
+ @store.key?(key).wont_equal true
149
+ @store.key?(key2).wont_equal true
150
+
151
+ [key, key2].each do |k|
152
+ entry = @store.log(k).first
153
+ entry['message'].must_equal "All gone"
154
+ end
155
+ end
85
156
 
86
157
  it "does not run the block if the #{type} key is available" do
87
158
  @store[key] = "value"
@@ -99,7 +170,24 @@ describe Gaga do
99
170
  @store[key] = "value"
100
171
  @store.log(key).first['message'].must_equal("set '#{key}'")
101
172
  end
102
-
173
+ end
174
+
175
+ it 'creates a bare repository' do
176
+ bare = Gaga.new(:repo => tmp_bare, :branch => :lady)
177
+ File.exists?(File.join(tmp_bare, '.git')).must_equal false
178
+ File.exists?(File.join(tmp_bare, 'refs')).must_equal true
179
+ bare['key1'] = 'Value 1'
180
+ bare['key2'] = 'Value 2'
181
+ bare['key3'] = 'Value 3'
182
+ bare['key1'].must_equal 'Value 1'
183
+ bare['key2'].must_equal 'Value 2'
184
+ bare.keys.must_equal %w(key1 key2 key3)
185
+ bare.delete('key1')
186
+ bare['key1'].must_be_nil
187
+ bare.clear
188
+ bare.keys.must_equal []
189
+
190
+ remove_tmpdir!(tmp_bare)
103
191
  end
104
192
 
105
193
  end
@@ -10,11 +10,16 @@ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
10
10
  require 'gaga'
11
11
 
12
12
  TMP_DIR = '/tmp/gaga_test'
13
+ TMP_BARE = '/tmp/gaga_test_bare.git'
13
14
 
14
15
  def tmp_dir
15
16
  TMP_DIR
16
17
  end
17
18
 
19
+ def tmp_bare
20
+ TMP_BARE
21
+ end
22
+
18
23
  def remove_tmpdir!(passed_dir = nil)
19
24
  FileUtils.rm_rf(passed_dir || tmp_dir)
20
25
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: gaga
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.3
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2011-11-23 00:00:00.000000000 Z
12
+ date: 2011-12-06 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: grit
16
- requirement: &70351841569680 !ruby/object:Gem::Requirement
16
+ requirement: &70238515496040 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,7 +21,7 @@ dependencies:
21
21
  version: '0'
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *70351841569680
24
+ version_requirements: *70238515496040
25
25
  description: Gaga is a Git-backed key/value store
26
26
  email:
27
27
  - matt@mattsears.com