From f54bf00309e310cabb2fec55d860f0670f3b79ac Mon Sep 17 00:00:00 2001
From: Gabriel Mazetto <gabriel@gitlab.com>
Date: Thu, 17 Mar 2016 00:24:12 -0300
Subject: [PATCH] =?UTF-8?q?Back-porting=20PostReceive=20refactor=20made=20?=
 =?UTF-8?q?for=20EE=20=F0=9F=8D=BA?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 app/workers/post_receive.rb    | 46 +++++++++++---------------
 lib/gitlab/git_post_receive.rb | 60 ++++++++++++++++++++++++++++++++++
 2 files changed, 79 insertions(+), 27 deletions(-)
 create mode 100644 lib/gitlab/git_post_receive.rb

diff --git a/app/workers/post_receive.rb b/app/workers/post_receive.rb
index 14d7813412e..3cc232ef1ae 100644
--- a/app/workers/post_receive.rb
+++ b/app/workers/post_receive.rb
@@ -1,6 +1,5 @@
 class PostReceive
   include Sidekiq::Worker
-  include Gitlab::Identifier
 
   sidekiq_options queue: :post_receive
 
@@ -11,51 +10,44 @@ class PostReceive
       log("Check gitlab.yml config for correct gitlab_shell.repos_path variable. \"#{Gitlab.config.gitlab_shell.repos_path}\" does not match \"#{repo_path}\"")
     end
 
-    repo_path.gsub!(/\.git\z/, "")
-    repo_path.gsub!(/\A\//, "")
+    post_received = Gitlab::GitPostReceive.new(repo_path, identifier, changes)
 
-    project = Project.find_with_namespace(repo_path)
-
-    if project.nil?
+    if post_received.project.nil?
       log("Triggered hook for non-existing project with full path \"#{repo_path} \"")
       return false
     end
 
-    changes = Base64.decode64(changes) unless changes.include?(" ")
-    changes = utf8_encode_changes(changes)
-    changes = changes.lines
+    if post_received.wiki?
+      # Nothing defined here yet.
+    elsif post_received.regular_project?
+      process_project_changes(post_received)
+    else
+      log("Triggered hook for unidentifiable repository type with full path \"#{repo_path} \"")
+      false
+    end
+  end
 
-    changes.each do |change|
+  def process_project_changes(post_received)
+    post_received.changes.each do |change|
       oldrev, newrev, ref = change.strip.split(' ')
 
-      @user ||= identify(identifier, project, newrev)
+      @user ||= post_received.identify(newrev)
 
       unless @user
-        log("Triggered hook for non-existing user \"#{identifier} \"")
+        log("Triggered hook for non-existing user \"#{post_received.identifier} \"")
         return false
       end
 
       if Gitlab::Git.tag_ref?(ref)
-        GitTagPushService.new.execute(project, @user, oldrev, newrev, ref)
+        GitTagPushService.new.execute(post_received.project, @user, oldrev, newrev, ref)
       else
-        GitPushService.new(project, @user, oldrev: oldrev, newrev: newrev, ref: ref).execute
+        GitPushService.new(post_received.project, @user, oldrev: oldrev, newrev: newrev, ref: ref).execute
       end
     end
   end
 
-  def utf8_encode_changes(changes)
-    changes = changes.dup
-
-    changes.force_encoding("UTF-8")
-    return changes if changes.valid_encoding?
-
-    # Convert non-UTF-8 branch/tag names to UTF-8 so they can be dumped as JSON.
-    detection = CharlockHolmes::EncodingDetector.detect(changes)
-    return changes unless detection && detection[:encoding]
-
-    CharlockHolmes::Converter.convert(changes, detection[:encoding], 'UTF-8')
-  end
-
+  private
+  
   def log(message)
     Gitlab::GitLogger.error("POST-RECEIVE: #{message}")
   end
diff --git a/lib/gitlab/git_post_receive.rb b/lib/gitlab/git_post_receive.rb
new file mode 100644
index 00000000000..a088e19d1e7
--- /dev/null
+++ b/lib/gitlab/git_post_receive.rb
@@ -0,0 +1,60 @@
+module Gitlab
+  class GitPostReceive
+    include Gitlab::Identifier
+    attr_reader :repo_path, :identifier, :changes, :project
+
+    def initialize(repo_path, identifier, changes)
+      repo_path.gsub!(/\.git\z/, '')
+      repo_path.gsub!(/\A\//, '')
+
+      @repo_path = repo_path
+      @identifier = identifier
+      @changes = deserialize_changes(changes)
+
+      retrieve_project_and_type
+    end
+
+    def wiki?
+      @type == :wiki
+    end
+
+    def regular_project?
+      @type == :project
+    end
+
+    def identify(revision)
+      super(identifier, project, revision)
+    end
+
+    private
+
+    def retrieve_project_and_type
+      @type = :project
+      @project = Project.find_with_namespace(@repo_path)
+
+      if @repo_path.end_with?('.wiki') && !@project
+        @type = :wiki
+        @project = Project.find_with_namespace(@repo_path.gsub(/\.wiki\z/, ''))
+      end
+    end
+
+    def deserialize_changes(changes)
+      changes = Base64.decode64(changes) unless changes.include?(' ')
+      changes = utf8_encode_changes(changes)
+      changes.lines
+    end
+
+    def utf8_encode_changes(changes)
+      changes = changes.dup
+
+      changes.force_encoding('UTF-8')
+      return changes if changes.valid_encoding?
+
+      # Convert non-UTF-8 branch/tag names to UTF-8 so they can be dumped as JSON.
+      detection = CharlockHolmes::EncodingDetector.detect(changes)
+      return changes unless detection && detection[:encoding]
+
+      CharlockHolmes::Converter.convert(changes, detection[:encoding], 'UTF-8')
+    end
+  end
+end
-- 
GitLab