From 03f41e2820d76d272aa7357cf726b5d131bb80e0 Mon Sep 17 00:00:00 2001
From: Dmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com>
Date: Tue, 2 Apr 2013 22:37:20 +0300
Subject: [PATCH] Gitlab::Git::Tree & Blob added

---
 app/controllers/refs_controller.rb |  2 +-
 app/helpers/tree_helper.rb         |  5 ++---
 app/models/merge_request.rb        |  2 +-
 app/models/tree.rb                 |  6 +-----
 app/views/commits/_diffs.html.haml |  8 +++----
 app/views/tree/_tree.html.haml     |  2 +-
 lib/extracts_path.rb               |  2 +-
 lib/gitlab/git/blob.rb             | 30 ++++++++++++++++++++++++++
 lib/gitlab/git/tree.rb             | 34 +++++++++++++++++++++---------
 9 files changed, 65 insertions(+), 26 deletions(-)
 create mode 100644 lib/gitlab/git/blob.rb

diff --git a/app/controllers/refs_controller.rb b/app/controllers/refs_controller.rb
index c67912b97a6..e116bc358c9 100644
--- a/app/controllers/refs_controller.rb
+++ b/app/controllers/refs_controller.rb
@@ -30,7 +30,7 @@ class RefsController < ProjectResourceController
   end
 
   def logs_tree
-    contents = @tree.contents
+    contents = @tree.entries
     @logs = contents.map do |content|
       file = params[:path] ? File.join(params[:path], content.name) : content.name
       last_commit = @repo.commits(@commit.id, file, 1).last
diff --git a/app/helpers/tree_helper.rb b/app/helpers/tree_helper.rb
index 1cba9476179..f21783d0005 100644
--- a/app/helpers/tree_helper.rb
+++ b/app/helpers/tree_helper.rb
@@ -3,9 +3,9 @@ module TreeHelper
   # their corresponding partials
   #
   # contents - A Grit::Tree object for the current tree
-  def render_tree(contents)
+  def render_tree(tree)
     # Render Folders before Files/Submodules
-    folders, files = contents.partition { |v| v.kind_of?(Grit::Tree) }
+    folders, files = tree.trees, tree.blobs
 
     tree = ""
 
@@ -91,5 +91,4 @@ module TreeHelper
     file = File.join(tree.path, "..")
     tree_join(tree.ref, file)
   end
-
 end
diff --git a/app/models/merge_request.rb b/app/models/merge_request.rb
index 0bab88313c1..105d9239cf6 100644
--- a/app/models/merge_request.rb
+++ b/app/models/merge_request.rb
@@ -152,7 +152,7 @@ class MergeRequest < ActiveRecord::Base
   end
 
   def commits
-    load_commits(st_commits) || []
+    load_commits(st_commits || [])
   end
 
   def probably_merged?
diff --git a/app/models/tree.rb b/app/models/tree.rb
index e726c596f7e..042050527c1 100644
--- a/app/models/tree.rb
+++ b/app/models/tree.rb
@@ -1,14 +1,10 @@
 class Tree
-  attr_accessor :path, :tree, :ref
+  attr_accessor :raw
 
   def initialize(repository, sha, ref = nil, path = nil)
     @raw = Gitlab::Git::Tree.new(repository, sha, ref, path)
   end
 
-  def invalid?
-    @raw.nil?
-  end
-
   def method_missing(m, *args, &block)
     @raw.send(m, *args, &block)
   end
diff --git a/app/views/commits/_diffs.html.haml b/app/views/commits/_diffs.html.haml
index c95215036ae..26098173d05 100644
--- a/app/views/commits/_diffs.html.haml
+++ b/app/views/commits/_diffs.html.haml
@@ -16,8 +16,8 @@
   - unless @suppress_diff
     - diffs.each_with_index do |diff, i|
       - next if diff.diff.empty?
-      - file = Tree.new(@repository, @commit.id, @ref, diff.new_path)
-      - file = Tree.new(@repository, @commit.parent_id, @ref, diff.old_path) unless file
+      - file = Gitlab::Git::Blob.new(@repository, @commit.id, @ref, diff.new_path)
+      - file = Gitlab::Git::Blob.new(@repository, @commit.parent_id, @ref, diff.old_path) unless file.exists?
       - next unless file
       .file{id: "diff-#{i}"}
         .header
@@ -25,7 +25,7 @@
             %span= diff.old_path
 
             - if @commit.parent_ids.present?
-              = link_to project_tree_path(@project, tree_join(@commit.prev_commit_id, diff.new_path)), {:class => 'btn btn-tiny pull-right view-file'} do
+              = link_to project_tree_path(@project, tree_join(@commit.parent_id, diff.new_path)), {:class => 'btn btn-tiny pull-right view-file'} do
                 View file @
                 %span.commit-short-id= @commit.short_id(6)
           - else
@@ -43,7 +43,7 @@
           - if file.text?
             = render "commits/text_file", diff: diff, index: i
           - elsif file.image?
-            - old_file = Tree.new(@repository, @commit.parent_id, @ref, diff.old_path) if @commit.parent_id
+            - old_file = Gitlab::Git::Blob.new(@repository, @commit.parent_id, @ref, diff.old_path) if @commit.parent_id
             = render "commits/image", diff: diff, old_file: old_file, file: file, index: i
           - else
             %p.nothing_here_message No preview for this file type
diff --git a/app/views/tree/_tree.html.haml b/app/views/tree/_tree.html.haml
index caab6e45bb4..7b1479515f9 100644
--- a/app/views/tree/_tree.html.haml
+++ b/app/views/tree/_tree.html.haml
@@ -32,7 +32,7 @@
           %td
           %td
 
-      = render_tree(tree.contents)
+      = render_tree(tree)
 
     - if tree.readme
       = render "tree/readme", readme: tree.readme
diff --git a/lib/extracts_path.rb b/lib/extracts_path.rb
index c3e2441ff21..009c5fcada9 100644
--- a/lib/extracts_path.rb
+++ b/lib/extracts_path.rb
@@ -104,7 +104,7 @@ module ExtractsPath
 
     @tree = Tree.new(@project.repository, @commit.id, @ref, @path)
 
-    raise InvalidPathError if @tree.invalid?
+    raise InvalidPathError unless @tree.exists?
   rescue RuntimeError, NoMethodError, InvalidPathError
     not_found!
   end
diff --git a/lib/gitlab/git/blob.rb b/lib/gitlab/git/blob.rb
new file mode 100644
index 00000000000..405cbddad90
--- /dev/null
+++ b/lib/gitlab/git/blob.rb
@@ -0,0 +1,30 @@
+module Gitlab
+  module Git
+    class Blob
+      include Linguist::BlobHelper
+
+      attr_accessor :raw_blob
+
+      delegate :name, to: :raw_blob
+
+      def initialize(repository, sha, ref, path)
+        @repository, @sha, @ref = repository, sha, ref
+
+        @commit = @repository.commit(sha)
+        @raw_blob = @repository.tree(@commit, path)
+      end
+
+      def data
+        if raw_blob
+          raw_blob.data
+        else
+          nil
+        end
+      end
+
+      def exists?
+        @raw_blob
+      end
+    end
+  end
+end
diff --git a/lib/gitlab/git/tree.rb b/lib/gitlab/git/tree.rb
index b81ce550f4c..8bcf71ea217 100644
--- a/lib/gitlab/git/tree.rb
+++ b/lib/gitlab/git/tree.rb
@@ -1,28 +1,36 @@
 module Gitlab
   module Git
     class Tree
-      include Linguist::BlobHelper
-
-      attr_accessor :repository, :sha, :path, :ref, :raw_tree
+      attr_accessor :repository, :sha, :path, :ref, :raw_tree, :id
 
       def initialize(repository, sha, ref = nil, path = nil)
-        @repository, @sha, @ref = repository, sha, ref
+        @repository, @sha, @ref, @path = repository, sha, ref, path
+
+        @path = nil if @path.blank?
 
         # Load tree from repository
-        @commit = @repository.commit(sha)
-        @raw_tree = @repository.tree(@commit, path)
+        @commit = @repository.commit(@sha)
+        @raw_tree = @repository.tree(@commit, @path)
+      end
+
+      def exists?
+        raw_tree
       end
 
       def empty?
         data.blank?
       end
 
-      def data
-        raw_tree.data
+      def trees
+        entries.select { |t| t.is_a?(Grit::Tree) }
+      end
+
+      def blobs
+        entries.select { |t| t.is_a?(Grit::Blob) }
       end
 
       def is_blob?
-        tree.is_a?(Grit::Blob)
+        raw_tree.is_a?(Grit::Blob)
       end
 
       def up_dir?
@@ -30,7 +38,13 @@ module Gitlab
       end
 
       def readme
-        @readme ||= contents.find { |c| c.is_a?(Grit::Blob) and c.name =~ /^readme/i }
+        @readme ||= entries.find { |c| c.is_a?(Grit::Blob) and c.name =~ /^readme/i }
+      end
+
+      protected
+
+      def entries
+        raw_tree.contents
       end
     end
   end
-- 
GitLab