Class: GitStore::Tree

Inherits:
Object
  • Object
show all
Includes:
Enumerable
Defined in:
lib/git_store/tree.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(store, id = nil, data = nil) ⇒ Tree

Initialize a tree



10
11
12
13
14
15
16
# File 'lib/git_store/tree.rb', line 10

def initialize(store, id = nil, data = nil)
  @store = store
  @id = id
  @table = {}
  @mode = "040000"
  parse(data) if data
end

Instance Attribute Details

#dataObject

Returns the value of attribute data.



7
8
9
# File 'lib/git_store/tree.rb', line 7

def data
  @data
end

#idObject

Returns the value of attribute id.



7
8
9
# File 'lib/git_store/tree.rb', line 7

def id
  @id
end

#modeObject

Returns the value of attribute mode.



7
8
9
# File 'lib/git_store/tree.rb', line 7

def mode
  @mode
end

#storeObject (readonly)

Returns the value of attribute store.



6
7
8
# File 'lib/git_store/tree.rb', line 6

def store
  @store
end

#tableObject (readonly)

Returns the value of attribute table.



6
7
8
# File 'lib/git_store/tree.rb', line 6

def table
  @table
end

Instance Method Details

#==(other) ⇒ Object



18
19
20
# File 'lib/git_store/tree.rb', line 18

def ==(other)
  Tree === other and id == other.id
end

#[](path) ⇒ Object

Read a value on specified path.



107
108
109
110
111
# File 'lib/git_store/tree.rb', line 107

def [](path)
  normalize_path(path).inject(self) do |tree, key|
    tree.get(key) or return nil
  end
end

#[]=(path, value) ⇒ Object

Write a value on specified path.



114
115
116
117
118
# File 'lib/git_store/tree.rb', line 114

def []=(path, value)
  list = normalize_path(path)
  tree = list[0..-2].to_a.inject(self) { |tree, name| tree.tree(name) }
  tree.put(list.last, value)
end

#delete(path) ⇒ Object

Delete a value on specified path.



121
122
123
124
125
126
127
128
129
# File 'lib/git_store/tree.rb', line 121

def delete(path)
  list = normalize_path(path)

  tree = list[0..-2].to_a.inject(self) do |tree, key|
    tree.get(key) or return
  end

  tree.remove(list.last)
end

#dumpObject



45
46
47
# File 'lib/git_store/tree.rb', line 45

def dump
  @table.map { |k, v| "#{ v.mode } #{ k }\0#{ [v.write].pack("H*") }" }.join
end

#each(path = [], &block) ⇒ Object

Iterate over all objects found in this subtree.



132
133
134
135
136
137
138
139
140
141
142
143
144
# File 'lib/git_store/tree.rb', line 132

def each(path = [], &block)
  @table.sort.each do |name, entry|
    child_path = path + [name]
    case entry
    when Blob
      entry.object ||= handler_for(name).read(entry.data)
      yield child_path.join("/"), entry.object

    when Tree
      entry.each(child_path, &block)
    end
  end
end

#each_blob(path = [], &block) ⇒ Object



146
147
148
149
150
151
152
153
154
155
156
157
158
# File 'lib/git_store/tree.rb', line 146

def each_blob(path = [], &block)
  @table.sort.each do |name, entry|
    child_path = path + [name]

    case entry
    when Blob
      yield child_path.join("/"), entry

    when Tree
      entry.each_blob(child_path, &block)
    end
  end
end

#get(name) ⇒ Object

Read entry with specified name.



59
60
61
62
63
64
65
66
67
68
69
# File 'lib/git_store/tree.rb', line 59

def get(name)
  entry = @table[name]

  case entry
  when Blob
    entry.object ||= handler_for(name).read(entry.data)

  when Tree
    entry
  end
end

#handler_for(name) ⇒ Object



71
72
73
# File 'lib/git_store/tree.rb', line 71

def handler_for(name)
  store.handler_for(name)
end

#has_key?(name) ⇒ Boolean

Does this key exist in the table?

Returns:

  • (Boolean)


98
99
100
# File 'lib/git_store/tree.rb', line 98

def has_key?(name)
  @table.has_key?(name.to_s)
end

#inspectObject



180
181
182
# File 'lib/git_store/tree.rb', line 180

def inspect
  "#<GitStore::Tree #{id} #{mode} #{to_hash.inspect}>"
end

#modified?Boolean

Has this tree been modified?

Returns:

  • (Boolean)


23
24
25
# File 'lib/git_store/tree.rb', line 23

def modified?
  @modified or @table.values.any? { |entry| Tree === entry and entry.modified? }
end

#normalize_path(path) ⇒ Object



102
103
104
# File 'lib/git_store/tree.rb', line 102

def normalize_path(path)
  (path[0, 1] == '/' ? path[1..-1] : path).split('/')
end

#parse(data) ⇒ Object

Read the contents of a raw git object.



33
34
35
36
37
38
39
40
41
42
43
# File 'lib/git_store/tree.rb', line 33

def parse(data)
  @table.clear

  while data.size > 0
    mode, data = data.split(" ", 2)
    name, data = data.split("\0", 2)
    id = data.slice!(0, 20).unpack("H*").first

    @table[name] = store.get(id)
  end
end

#pathsObject



160
161
162
# File 'lib/git_store/tree.rb', line 160

def paths
  map { |path, data| path }
end

#put(name, value) ⇒ Object

Write entry with specified name.



76
77
78
79
80
81
82
83
84
85
86
87
88
89
# File 'lib/git_store/tree.rb', line 76

def put(name, value)
  if value.is_a?(Tree)
    @modified = true
    @table[name] = value
  else
    data = handler_for(name).write(value)
    if @table[name].nil? or data != @table[name].data
      @modified = true
      @table[name] = Blob.new(store, nil, data)
    end
  end

  value
end

#remove(name) ⇒ Object

Remove entry with specified name.



92
93
94
95
# File 'lib/git_store/tree.rb', line 92

def remove(name)
  @modified = true
  @table.delete(name.to_s)
end

#to_hashObject

Convert this tree into a hash object.



169
170
171
172
173
174
175
176
177
178
# File 'lib/git_store/tree.rb', line 169

def to_hash
  @table.inject({}) do |hash, (name, entry)|
    if entry.is_a?(Tree)
      hash[name] = entry.to_hash
    else
      hash[name] = entry.object ||= handler_for(name).read(entry.data)
    end
    hash
  end
end

#tree(name) ⇒ Object

Find or create a subtree with specified name.



28
29
30
# File 'lib/git_store/tree.rb', line 28

def tree(name)
  get(name) or put(name, Tree.new(store))
end

#valuesObject



164
165
166
# File 'lib/git_store/tree.rb', line 164

def values
  map { |path, data| data }
end

#writeObject

Write this treetree back to the git repository.

Returns the object id of the tree.



52
53
54
55
56
# File 'lib/git_store/tree.rb', line 52

def write
  return id if not modified?
  @modified = false
  @id = store.put(self)
end