gash 0.1 → 0.1.1
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/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
|