gash 0.1 → 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +2 -0
- data/Rakefile +1 -0
- data/gash.gemspec +6 -6
- data/lib/gash.rb +113 -35
- metadata +5 -5
data/CHANGELOG
CHANGED
data/Rakefile
CHANGED
data/gash.gemspec
CHANGED
@@ -1,18 +1,18 @@
|
|
1
1
|
|
2
|
-
# Gem::Specification for Gash-0.1
|
2
|
+
# Gem::Specification for Gash-0.1.1
|
3
3
|
# Originally generated by Echoe
|
4
4
|
|
5
5
|
--- !ruby/object:Gem::Specification
|
6
6
|
name: gash
|
7
7
|
version: !ruby/object:Gem::Version
|
8
|
-
version:
|
8
|
+
version: 0.1.1
|
9
9
|
platform: ruby
|
10
10
|
authors:
|
11
11
|
- Magnus Holm
|
12
12
|
autorequire:
|
13
13
|
bindir: bin
|
14
14
|
|
15
|
-
date: 2008-09-
|
15
|
+
date: 2008-09-27 00:00:00 +02:00
|
16
16
|
default_executable:
|
17
17
|
dependencies:
|
18
18
|
- !ruby/object:Gem::Dependency
|
@@ -66,14 +66,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
66
66
|
version:
|
67
67
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
68
68
|
requirements:
|
69
|
-
- - "
|
69
|
+
- - ">="
|
70
70
|
- !ruby/object:Gem::Version
|
71
|
-
version: "
|
71
|
+
version: "0"
|
72
72
|
version:
|
73
73
|
requirements: []
|
74
74
|
|
75
75
|
rubyforge_project: dojo
|
76
|
-
rubygems_version: 1.
|
76
|
+
rubygems_version: 1.3.0
|
77
77
|
specification_version: 2
|
78
78
|
summary: Git + Hash
|
79
79
|
test_files: []
|
data/lib/gash.rb
CHANGED
@@ -3,13 +3,15 @@ require 'delegate'
|
|
3
3
|
# == What is Gash?
|
4
4
|
#
|
5
5
|
# * Gash lets you access a Git-repo as a Hash.
|
6
|
+
# * Gash doesn't touch your working directory
|
6
7
|
# * Gash only cares about the data, not the commits.
|
7
8
|
# * Gash only cares about the _latest_ data.
|
8
9
|
# * Gash can commit.
|
9
|
-
# * Gash doesn't touch your working directory
|
10
10
|
# * Gash will automatically create branches if they don't exists.
|
11
11
|
# * Gash only loads what it needs, so it handles large repos well.
|
12
12
|
#
|
13
|
+
# Some of these "rules" might change it the future.
|
14
|
+
#
|
13
15
|
# == How do you use it?
|
14
16
|
#
|
15
17
|
# gash = Gash.new
|
@@ -19,16 +21,12 @@ require 'delegate'
|
|
19
21
|
# It's also important to remember that a Gash is simply a Tree, so you can
|
20
22
|
# also call those methods.
|
21
23
|
#
|
22
|
-
# <
|
23
|
-
#
|
24
|
-
# == Limitation
|
25
|
-
#
|
26
|
-
# The only Hash-like features which currently works is #[] and #[]=,
|
27
|
-
# so don't try #merge or something like that.
|
24
|
+
# <b>See also</b>: #new, #commit, Tree
|
28
25
|
class Gash < SimpleDelegator
|
29
26
|
module Errors
|
30
27
|
# This error is raised when the Git-command fails.
|
31
28
|
class Git < StandardError; end
|
29
|
+
class NoGitRepo < StandardError; end
|
32
30
|
end
|
33
31
|
|
34
32
|
# Some common methods used by both Tree and Blob.
|
@@ -55,28 +53,63 @@ class Gash < SimpleDelegator
|
|
55
53
|
# Checks if this object has been changed (since last commit).
|
56
54
|
def changed?; !@sha1 end
|
57
55
|
# Mark this, and all parents as changed.
|
58
|
-
def changed!; @sha1 = nil;parent.changed! end
|
56
|
+
def changed!; @sha1 = nil;parent.changed! if parent end
|
59
57
|
# Returns the Gash-object (top-parent).
|
60
|
-
def gash; parent.gash end
|
58
|
+
def gash; parent.gash if parent end
|
59
|
+
|
60
|
+
# Converts the +value+ to a Tree or a Blob, using some rules:
|
61
|
+
#
|
62
|
+
# == If +value+ is already a Tree or a Blob:
|
63
|
+
#
|
64
|
+
# * If +value+ comes from another repo, we load it and return a deep copy.
|
65
|
+
# * If +value+ got no parent, we simply return the same tree.
|
66
|
+
# * If +value+'s parent is +self+, we also return the same tree.
|
67
|
+
# * If +value+'s parent is something else, we return a duplicated tree.
|
68
|
+
#
|
69
|
+
# == If it's something else:
|
70
|
+
#
|
71
|
+
# * If +value+ is a Hash, we create a Tree from it.
|
72
|
+
# * If it's not any of the former rules, we turn it into a string and create a Blob from it.
|
73
|
+
def normalize(value)
|
74
|
+
case value
|
75
|
+
when Tree, Blob, Gash
|
76
|
+
if value.parent && value.parent != self
|
77
|
+
if (g = value.gash) && self.gash == g
|
78
|
+
value.dup
|
79
|
+
else
|
80
|
+
normalize(value.tree? ? value.to_hash : value.to_s)
|
81
|
+
end
|
82
|
+
else
|
83
|
+
value
|
84
|
+
end
|
85
|
+
when Hash
|
86
|
+
Tree[value]
|
87
|
+
else
|
88
|
+
Blob.new(:content => value.to_s)
|
89
|
+
end
|
90
|
+
end
|
61
91
|
end
|
62
92
|
|
63
93
|
# A Tree is a Hash which can store other instances of Tree and Blob.
|
64
94
|
#
|
65
|
-
# <
|
95
|
+
# <b>See also</b>: Helpers, Blob
|
66
96
|
class Tree < Hash
|
67
97
|
include Helpers
|
68
98
|
|
69
99
|
# Retrieves the _value_ stored as +key+:
|
70
100
|
#
|
71
|
-
# tree["FILE"] ==
|
72
|
-
# tree["DIR/FILE"] == tree["DIR"]["FILE"]
|
101
|
+
# tree["FILE"] == File.read("FILE")
|
102
|
+
# tree["DIR/FILE"] == tree["DIR"]["FILE"] == File.read("DIR/FILE")
|
103
|
+
#
|
104
|
+
# ==== Lazy loading
|
73
105
|
#
|
74
|
-
#
|
75
|
-
#
|
106
|
+
# By default, this method will automatically load the blob/tree from
|
107
|
+
# the repo. If you rather want to load it later, simply set +lazy+ to
|
108
|
+
# +true+:
|
76
109
|
#
|
77
|
-
# blob = tree["FILE", true]
|
110
|
+
# blob = tree["FILE", true]
|
78
111
|
# # do some other stuff...
|
79
|
-
# blob.
|
112
|
+
# blob.load! # Load it now!
|
80
113
|
def [](key, lazy = nil)
|
81
114
|
ret = if key.include?("/")
|
82
115
|
key, rest = key.split("/", 2)
|
@@ -91,23 +124,27 @@ class Gash < SimpleDelegator
|
|
91
124
|
end
|
92
125
|
alias / []
|
93
126
|
|
94
|
-
# Stores the given _value_
|
127
|
+
# Stores the given _value_ at +key+:
|
95
128
|
#
|
96
129
|
# tree["FILE"] = "Content"
|
97
130
|
#
|
98
|
-
#
|
99
|
-
#
|
131
|
+
# It uses Helpers#normalize in order convert it to a blob/tree, and will
|
132
|
+
# always set the parent to itself:
|
100
133
|
#
|
101
134
|
# tree["FILE"] = "Content"
|
102
135
|
# # is the same as:
|
103
136
|
# tree["FILE"] = Gash::Blob.new(:content => "Content", :parent => tree)
|
104
137
|
#
|
105
|
-
#
|
106
|
-
#
|
107
|
-
#
|
108
|
-
#
|
109
|
-
# +not_changed
|
138
|
+
# ==== Mark as changed
|
139
|
+
#
|
140
|
+
# By default, the object will be marked as changed (using
|
141
|
+
# <code>Helpers#changed!</code>). If this is not what you want, simply set
|
142
|
+
# +not_changed+ to +true+.
|
143
|
+
#
|
144
|
+
# However, if you give it three arguments, then the second one will act as
|
145
|
+
# +not_changed+, not the third:
|
110
146
|
#
|
147
|
+
# 1 2 3
|
111
148
|
# tree["FILE", true] = "Test"
|
112
149
|
# tree["FILE"].changed? # => false
|
113
150
|
def []=(key, value, not_changed = nil)
|
@@ -125,18 +162,47 @@ class Gash < SimpleDelegator
|
|
125
162
|
memo[i, true]
|
126
163
|
end[name, not_changed] = value
|
127
164
|
else
|
128
|
-
value =
|
129
|
-
when Tree, Blob
|
130
|
-
value
|
131
|
-
else
|
132
|
-
Blob.new(:content => value.to_s)
|
133
|
-
end
|
165
|
+
value = normalize(value)
|
134
166
|
value.parent = self
|
135
167
|
super(key, value)
|
136
168
|
end
|
137
169
|
ensure
|
138
170
|
self.changed! unless not_changed
|
139
171
|
end
|
172
|
+
|
173
|
+
# Converts the tree to a Hash.
|
174
|
+
def to_hash
|
175
|
+
inject({}) do |memo, (key, value)|
|
176
|
+
memo[key] = value.respond_to?(:to_hash) ? value.to_hash : value.to_s
|
177
|
+
memo
|
178
|
+
end
|
179
|
+
end
|
180
|
+
|
181
|
+
def self.[](*val) # :nodoc:
|
182
|
+
new.merge!(Hash[*val])
|
183
|
+
end
|
184
|
+
|
185
|
+
def merge(hash) # :nodoc:
|
186
|
+
tree = self.dup
|
187
|
+
tree.merge!(hash)
|
188
|
+
end
|
189
|
+
|
190
|
+
def merge!(hash) # :nodoc:
|
191
|
+
hash.each do |key, value|
|
192
|
+
self[key] = value
|
193
|
+
end
|
194
|
+
self
|
195
|
+
end
|
196
|
+
alias update merge!
|
197
|
+
|
198
|
+
def replace(hash) # :nodoc:
|
199
|
+
if hash.is_a?(Gash::Tree)
|
200
|
+
super
|
201
|
+
else
|
202
|
+
clear
|
203
|
+
merge!(hash)
|
204
|
+
end
|
205
|
+
end
|
140
206
|
end
|
141
207
|
|
142
208
|
# A Blob represent a string:
|
@@ -160,9 +226,9 @@ class Gash < SimpleDelegator
|
|
160
226
|
#
|
161
227
|
# tree["FILE"] = Gash::Blob.new(:sha1 => a_sha1)
|
162
228
|
#
|
163
|
-
# <
|
229
|
+
# <b>See also</b>: Helpers, Tree
|
164
230
|
class Blob < Delegator
|
165
|
-
include Helpers
|
231
|
+
include Helpers, Comparable
|
166
232
|
attr_accessor :content
|
167
233
|
|
168
234
|
# Loads the file from Git, unless it's already been loaded.
|
@@ -174,6 +240,14 @@ class Gash < SimpleDelegator
|
|
174
240
|
@content ? @content.inspect : (@sha1 ? "#<Blob:#{@sha1}>" : to_s.inspect)
|
175
241
|
end
|
176
242
|
|
243
|
+
def <=>(other) #:nodoc:
|
244
|
+
if other.is_a?(Blob) && sha1 && other.sha1
|
245
|
+
sha1 <=> other.sha1
|
246
|
+
else
|
247
|
+
__getobj__ <=> other
|
248
|
+
end
|
249
|
+
end
|
250
|
+
|
177
251
|
def __getobj__ #:nodoc:
|
178
252
|
@content ||= @sha1 ? load! : ''
|
179
253
|
end
|
@@ -184,9 +258,9 @@ class Gash < SimpleDelegator
|
|
184
258
|
|
185
259
|
# Opens the +repo+ with the specified +branch+.
|
186
260
|
#
|
187
|
-
# <
|
261
|
+
# <b>Please note:</b> The +repo+ must link to the actual repo,
|
188
262
|
# not the working directory!
|
189
|
-
def initialize(
|
263
|
+
def initialize(repo = ".git", branch = "master")
|
190
264
|
@branch = branch
|
191
265
|
@repository = File.expand_path(repo)
|
192
266
|
__setobj__(Tree.new(:parent => self))
|
@@ -330,7 +404,11 @@ class Gash < SimpleDelegator
|
|
330
404
|
result, status = run_git(cmd, *rest, &block)
|
331
405
|
|
332
406
|
if status != 0
|
333
|
-
|
407
|
+
if result =~ /Not a git repository/
|
408
|
+
raise Errors::NoGitRepo.new("No Git repository at: " + @repository)
|
409
|
+
else
|
410
|
+
raise Errors::Git.new("Error: #{cmd} returned #{status}. Result: #{result}")
|
411
|
+
end
|
334
412
|
end
|
335
413
|
result
|
336
414
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: gash
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 0.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Magnus Holm
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2008-09-
|
12
|
+
date: 2008-09-27 00:00:00 +02:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -63,14 +63,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
63
63
|
version:
|
64
64
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
|
-
- - "
|
66
|
+
- - ">="
|
67
67
|
- !ruby/object:Gem::Version
|
68
|
-
version: "
|
68
|
+
version: "0"
|
69
69
|
version:
|
70
70
|
requirements: []
|
71
71
|
|
72
72
|
rubyforge_project: dojo
|
73
|
-
rubygems_version: 1.
|
73
|
+
rubygems_version: 1.3.0
|
74
74
|
signing_key:
|
75
75
|
specification_version: 2
|
76
76
|
summary: Git + Hash
|