gash 0.1 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (5) hide show
  1. data/CHANGELOG +2 -0
  2. data/Rakefile +1 -0
  3. data/gash.gemspec +6 -6
  4. data/lib/gash.rb +113 -35
  5. metadata +5 -5
data/CHANGELOG CHANGED
@@ -1 +1,3 @@
1
+ v0.1.1. Tree got more Hash-methods. Better documentation.
2
+
1
3
  v0.1. First version.
data/Rakefile CHANGED
@@ -8,6 +8,7 @@ Echoe.new('gash') do |p|
8
8
  p.summary = "Git + Hash"
9
9
  p.url = "http://dojo.rubyforge.org/gash/"
10
10
  p.rdoc_options += ["--main", "Gash", "--title", "Gash"]
11
+ p.rubygems_version = nil
11
12
  end
12
13
 
13
14
  Rake::Task[:publish_docs].instance_eval do
@@ -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: "0.1"
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-04 00:00:00 +02:00
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: "1.2"
71
+ version: "0"
72
72
  version:
73
73
  requirements: []
74
74
 
75
75
  rubyforge_project: dojo
76
- rubygems_version: 1.2.0
76
+ rubygems_version: 1.3.0
77
77
  specification_version: 2
78
78
  summary: Git + Hash
79
79
  test_files: []
@@ -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
- # <strong>See also</strong>: #new, #commit, Tree
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
- # <strong>See also</strong>: Helpers, Blob
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"] == the file
72
- # tree["DIR/FILE"] == tree["DIR"]["FILE"] = another 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
- # It will automatically call the +load!+-method in order to load
75
- # it from the repo. Set +lazy+ to +true+ if this is not what you want:
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] == #<Blob:1234...>
110
+ # blob = tree["FILE", true]
78
111
  # # do some other stuff...
79
- # blob.laod! # Load it now!
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
- # Unless it's already a Tree or a Blob, it will be converted to a Blob,
99
- # and the parent will _always_ be set to +self+.
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
- # It will also mark the object as changed (using <code>Helpers#changed!</code>).
106
- # Set +not_changed+ to +true+ if this is not what you want.
107
- #
108
- # (If you give it three arguments, then the second one will act as
109
- # +not_changed+, not the third):
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 = case 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
- # <strong>See also</strong>: Helpers, Tree
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
- # <strong>Please note:</strong> The +repo+ must link to the actual repo,
261
+ # <b>Please note:</b> The +repo+ must link to the actual repo,
188
262
  # not the working directory!
189
- def initialize(branch = "master", repo = ".git")
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
- raise Errors::Git.new("Error: #{cmd} returned #{status}. Result: #{result}")
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: "0.1"
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-04 00:00:00 +02:00
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: "1.2"
68
+ version: "0"
69
69
  version:
70
70
  requirements: []
71
71
 
72
72
  rubyforge_project: dojo
73
- rubygems_version: 1.2.0
73
+ rubygems_version: 1.3.0
74
74
  signing_key:
75
75
  specification_version: 2
76
76
  summary: Git + Hash