-
Notifications
You must be signed in to change notification settings - Fork 521
/
tree.rb
123 lines (106 loc) · 3.13 KB
/
tree.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
module Grit
class Tree
lazy_reader :contents
attr_reader :id
attr_reader :mode
attr_reader :name
# Construct the contents of the tree
# +repo+ is the Repo
# +treeish+ is the reference
# +paths+ is an optional Array of directory paths to restrict the tree
#
# Returns Grit::Tree (baked)
def self.construct(repo, treeish, paths = [])
output = repo.git.ls_tree({}, treeish, *paths)
self.allocate.construct_initialize(repo, treeish, output)
end
def construct_initialize(repo, id, text)
@repo = repo
@id = id
@contents = []
text.split("\n").each do |line|
@contents << content_from_string(repo, line)
end
@contents.compact!
self
end
def lazy_source
Tree.construct(@repo, @id, [])
end
# Create an unbaked Tree containing just the specified attributes
# +repo+ is the Repo
# +atts+ is a Hash of instance variable data
#
# Returns Grit::Tree (unbaked)
def self.create(repo, atts)
self.allocate.create_initialize(repo, atts)
end
# Initializer for Tree.create
# +repo+ is the Repo
# +atts+ is a Hash of instance variable data
#
# Returns Grit::Tree (unbaked)
def create_initialize(repo, atts)
@repo = repo
atts.each do |k, v|
instance_variable_set("@#{k}", v)
end
self
end
# Parse a content item and create the appropriate object
# +repo+ is the Repo
# +text+ is the single line containing the items data in `git ls-tree` format
#
# Returns Grit::Blob or Grit::Tree
def content_from_string(repo, text)
mode, type, id, name = text.split(" ", 4)
case type
when "tree"
Tree.create(repo, :id => id, :mode => mode, :name => name)
when "blob"
Blob.create(repo, :id => id, :mode => mode, :name => name)
when "link"
Blob.create(repo, :id => id, :mode => mode, :name => name)
when "commit"
Submodule.create(repo, :id => id, :mode => mode, :name => name)
else
raise Grit::InvalidObjectType, type
end
end
# Find the named object in this tree's contents
#
# Examples
# Repo.new('/path/to/grit').tree/'lib'
# # => #<Grit::Tree "6cc23ee138be09ff8c28b07162720018b244e95e">
# Repo.new('/path/to/grit').tree/'README.txt'
# # => #<Grit::Blob "8b1e02c0fb554eed2ce2ef737a68bb369d7527df">
#
# Returns Grit::Blob or Grit::Tree or nil if not found
def /(file)
if file =~ /\//
file.split("/").inject(self) { |acc, x| acc/x } rescue nil
else
self.contents.find { |c| c.name == file }
end
end
def basename
File.basename(name)
end
# Pretty object inspection
def inspect
%Q{#<Grit::Tree "#{@id}">}
end
# Find only Tree objects from contents
def trees
contents.select {|v| v.kind_of? Tree}
end
# Find only Blob objects from contents
def blobs
contents.select {|v| v.kind_of? Blob}
end
# Compares trees by name
def <=>(other)
name <=> other.name
end
end # Tree
end # Grit