OSDN Git Service

Use gitlab-shell to move repos. Requires gitlab-shell v1.1.0
authorDmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com>
Tue, 12 Mar 2013 10:37:53 +0000 (12:37 +0200)
committerDmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com>
Tue, 12 Mar 2013 10:37:53 +0000 (12:37 +0200)
app/services/project_transfer_service.rb
lib/gitlab/backend/shell.rb
lib/gitlab/project_mover.rb [deleted file]
spec/lib/project_mover_spec.rb [deleted file]
spec/services/git_push_service_spec.rb [moved from spec/services/git_push_service.rb with 100% similarity]
spec/services/project_transfer_service_spec.rb [new file with mode: 0644]

index 35d9517..bbea6d2 100644 (file)
@@ -3,29 +3,27 @@
 # Used for transfer project to another namespace
 #
 class ProjectTransferService
+  include Gitolited
+
   attr_accessor :project
 
   def transfer(project, new_namespace)
     Project.transaction do
-      old_namespace = project.namespace
-      project.namespace = new_namespace
-
-      old_dir = old_namespace.try(:path) || ''
-      new_dir = new_namespace.try(:path) || ''
-
-      old_repo = if old_dir.present?
-                   File.join(old_dir, project.path)
-                 else
-                   project.path
-                 end
+      old_path = project.path_with_namespace
+      new_path = File.join(new_namespace.try(:path) || '', project.path)
 
       if Project.where(path: project.path, namespace_id: new_namespace.try(:id)).present?
         raise TransferError.new("Project with same path in target namespace already exists")
       end
 
-      Gitlab::ProjectMover.new(project, old_dir, new_dir).execute
-
+      project.namespace = new_namespace
       project.save!
+
+      unless gitlab_shell.mv_repository(old_path, new_path)
+        raise TransferError.new('Cannot move project')
+      end
+
+      true
     end
   rescue Gitlab::ProjectMover::ProjectMoveError => ex
     raise Project::TransferError.new(ex.message)
index 9ea08cc..a230886 100644 (file)
@@ -24,6 +24,18 @@ module Gitlab
       system("#{gitlab_shell_user_home}/gitlab-shell/bin/gitlab-projects import-project #{name}.git #{url}")
     end
 
+    # Move repository
+    #
+    # path - project path with namespace
+    # new_path - new project path with namespace
+    #
+    # Ex.
+    #   mv_repository("gitlab/gitlab-ci", "randx/gitlab-ci-new.git")
+    #
+    def mv_repository(path, new_path)
+      system("#{gitlab_shell_user_home}/gitlab-shell/bin/gitlab-projects mv-project #{path}.git #{new_path}.git")
+    end
+
     # Remove repository from file system
     #
     # name - project path with namespace
@@ -56,7 +68,7 @@ module Gitlab
     def url_to_repo path
       Gitlab.config.gitlab_shell.ssh_path_prefix + "#{path}.git"
     end
-   
+
     def gitlab_shell_user_home
       File.expand_path("~#{Gitlab.config.gitlab_shell.ssh_user}")
     end
diff --git a/lib/gitlab/project_mover.rb b/lib/gitlab/project_mover.rb
deleted file mode 100644 (file)
index e21f45c..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-# ProjectMover class
-#
-# Used for moving project repositories from one subdir to another
-module Gitlab
-  class ProjectMover
-    class ProjectMoveError < StandardError; end
-
-    attr_reader :project, :old_dir, :new_dir
-
-    def initialize(project, old_dir, new_dir)
-      @project = project
-      @old_dir = old_dir
-      @new_dir = new_dir
-    end
-
-    def execute
-      # Create new dir if missing
-      new_dir_path = File.join(Gitlab.config.gitlab_shell.repos_path, new_dir)
-      FileUtils.mkdir( new_dir_path, mode: 0770 ) unless File.exists?(new_dir_path)
-
-      old_path = File.join(Gitlab.config.gitlab_shell.repos_path, old_dir, "#{project.path}.git")
-      new_path = File.join(new_dir_path, "#{project.path}.git")
-
-      if File.exists? new_path
-        raise ProjectMoveError.new("Destination #{new_path} already exists")
-      end
-
-      begin
-        FileUtils.mv( old_path, new_path )
-        log_info "Project #{project.name} was moved from #{old_path} to #{new_path}"
-        true
-      rescue Exception => e
-        message = "Project #{project.name} cannot be moved from #{old_path} to #{new_path}"
-        log_info "Error! #{message} (#{e.message})"
-        raise ProjectMoveError.new(message)
-      end
-    end
-
-  protected
-
-    def log_info message
-      Gitlab::AppLogger.info message
-    end
-  end
-end
diff --git a/spec/lib/project_mover_spec.rb b/spec/lib/project_mover_spec.rb
deleted file mode 100644 (file)
index 9202bef..0000000
+++ /dev/null
@@ -1,66 +0,0 @@
-require 'spec_helper'
-
-describe Gitlab::ProjectMover do
-  let(:base_path) { Rails.root.join('tmp', 'rspec-sandbox') }
-
-  before do
-    FileUtils.rm_rf base_path if File.exists? base_path
-    FileUtils.mkdir_p base_path
-
-    Gitlab.config.gitlab_shell.stub(repos_path: base_path)
-
-    @project = create(:project)
-  end
-
-  after do
-    FileUtils.rm_rf base_path
-  end
-
-  it "should move project to subdir" do
-    mk_dir base_path, '', @project.path
-    mover = Gitlab::ProjectMover.new(@project, '', 'opensource')
-
-    mover.execute.should be_true
-    moved?('opensource', @project.path).should be_true
-  end
-
-  it "should move project from one subdir to another" do
-    mk_dir base_path, 'vsizov', @project.path
-    mover = Gitlab::ProjectMover.new(@project, 'vsizov', 'randx')
-
-    mover.execute.should be_true
-    moved?('randx', @project.path).should be_true
-  end
-
-  it "should move project from subdir to base" do
-    mk_dir base_path, 'vsizov', @project.path
-    mover = Gitlab::ProjectMover.new(@project, 'vsizov', '')
-
-    mover.execute.should be_true
-    moved?('', @project.path).should be_true
-  end
-
-  it "should raise if destination exists" do
-    mk_dir base_path, '', @project.path
-    mk_dir base_path, 'vsizov', @project.path
-    mover = Gitlab::ProjectMover.new(@project, 'vsizov', '')
-
-    expect { mover.execute }.to raise_error(Gitlab::ProjectMover::ProjectMoveError)
-  end
-
-  it "should raise if move failed" do
-    mk_dir base_path
-    mover = Gitlab::ProjectMover.new(@project, 'vsizov', '')
-
-    expect { mover.execute }.to raise_error(Gitlab::ProjectMover::ProjectMoveError)
-  end
-
-
-  def mk_dir base_path, namespace = '', project_path = ''
-    FileUtils.mkdir_p File.join(base_path, namespace, project_path + ".git")
-  end
-
-  def moved? namespace, path
-    File.exists?(File.join(base_path, namespace, path + '.git'))
-  end
-end
diff --git a/spec/services/project_transfer_service_spec.rb b/spec/services/project_transfer_service_spec.rb
new file mode 100644 (file)
index 0000000..dea0b0b
--- /dev/null
@@ -0,0 +1,47 @@
+require 'spec_helper'
+
+describe ProjectTransferService do
+  context 'namespace -> namespace' do
+    let(:user) { create(:user) }
+    let(:group) { create(:group) }
+    let(:project) { create(:project, namespace: user.namespace) }
+
+    before do
+      @result = service.transfer(project, group)
+    end
+
+    it { @result.should be_true }
+    it { project.namespace.should == group }
+  end
+
+  context 'namespace -> no namespace' do
+    let(:user) { create(:user) }
+    let(:project) { create(:project, namespace: user.namespace) }
+
+    before do
+      @result = service.transfer(project, nil)
+    end
+
+    it { @result.should be_true }
+    it { project.namespace.should == nil }
+  end
+
+  context 'no namespace -> namespace' do
+    let(:project) { create(:project) }
+    let(:user) { create(:user) }
+
+    before do
+      @result = service.transfer(project, user.namespace)
+    end
+
+    it { @result.should be_true }
+    it { project.namespace.should == user.namespace }
+  end
+
+  def service
+    service = ProjectTransferService.new
+    service.gitlab_shell.stub(mv_repository: true)
+    service
+  end
+end
+