public
Fork of Caged/gitnub
Description: A Gitk-like application written in RubyCocoa that looks like it belongs on a Mac. See the wiki for downloads and screenshots.
Homepage: http://alternateidea.com
Clone URL: git://github.com/benstiglitz/gitnub.git
gitnub / grit / lib / grit / tree.rb
100644 110 lines (95 sloc) 2.87 kb
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
module Grit
  
  class Tree
    include Lazy
    
    lazy_reader :contents
    attr_reader :id
    attr_reader :mode
    attr_reader :name
    
    def initialize
      @contents = nil
      @__baked__ = nil
    end
    
    # 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 = []
      @__baked__ = nil
      
      text.split("\n").each do |line|
        @contents << content_from_string(repo, line)
      end
      @contents.compact!
      __baked__
      self
    end
    
    def __bake__
      temp = Tree.construct(@repo, @id, [])
      @contents = temp.contents
    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
      @contents = nil
      @__baked__ = nil
      
      atts.each do |k, v|
        instance_variable_set("@#{k}".to_sym, 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 "commit"
          nil
        else
          raise "Invalid type: #{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)
      self.contents.select { |c| c.name == file }.first
    end
    
    # Pretty object inspection
    def inspect
      %Q{#<Grit::Tree "#{@id}">}
    end
  end # Tree
  
end # Grit