Extract Projects::ImportService service from RepositoryImportWorker
This commit is contained in:
parent
cae0929a28
commit
6dd88e090e
|
@ -0,0 +1,71 @@
|
||||||
|
module Projects
|
||||||
|
class ImportService < BaseService
|
||||||
|
include Gitlab::ShellAdapter
|
||||||
|
|
||||||
|
class Error < StandardError; end
|
||||||
|
|
||||||
|
ALLOWED_TYPES = [
|
||||||
|
'bitbucket',
|
||||||
|
'fogbugz',
|
||||||
|
'gitlab',
|
||||||
|
'github',
|
||||||
|
'google_code'
|
||||||
|
]
|
||||||
|
|
||||||
|
def execute
|
||||||
|
if unknown_url?
|
||||||
|
# In this case, we only want to import issues, not a repository.
|
||||||
|
create_repository
|
||||||
|
else
|
||||||
|
import_repository
|
||||||
|
end
|
||||||
|
|
||||||
|
import_data
|
||||||
|
|
||||||
|
success
|
||||||
|
rescue Error => e
|
||||||
|
error(e.message)
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def create_repository
|
||||||
|
unless project.create_repository
|
||||||
|
raise Error, 'The repository could not be created.'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def import_repository
|
||||||
|
begin
|
||||||
|
gitlab_shell.import_repository(project.path_with_namespace, project.import_url)
|
||||||
|
rescue Gitlab::Shell::Error => e
|
||||||
|
raise Error, e.message
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def import_data
|
||||||
|
return unless has_importer?
|
||||||
|
|
||||||
|
unless importer.execute
|
||||||
|
raise Error, 'The remote data could not be imported.'
|
||||||
|
end
|
||||||
|
|
||||||
|
if project.import_type == 'bitbucket'
|
||||||
|
Gitlab::BitbucketImport::KeyDeleter.new(project).execute
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def has_importer?
|
||||||
|
ALLOWED_TYPES.include?(project.import_type)
|
||||||
|
end
|
||||||
|
|
||||||
|
def importer
|
||||||
|
class_name = "Gitlab::#{project.import_type.camelize}Import::Importer"
|
||||||
|
class_name.constantize.new(project)
|
||||||
|
end
|
||||||
|
|
||||||
|
def unknown_url?
|
||||||
|
project.import_url == Project::UNKNOWN_IMPORT_URL
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -4,52 +4,20 @@ class RepositoryImportWorker
|
||||||
|
|
||||||
sidekiq_options queue: :gitlab_shell
|
sidekiq_options queue: :gitlab_shell
|
||||||
|
|
||||||
|
attr_accessor :project, :current_user
|
||||||
|
|
||||||
def perform(project_id)
|
def perform(project_id)
|
||||||
project = Project.find(project_id)
|
@project = Project.find(project_id)
|
||||||
|
@current_user = @project.creator
|
||||||
|
|
||||||
if project.import_url == Project::UNKNOWN_IMPORT_URL
|
result = Projects::ImportService.new(project, current_user).execute
|
||||||
# In this case, we only want to import issues, not a repository.
|
|
||||||
unless project.create_repository
|
|
||||||
project.update(import_error: "The repository could not be created.")
|
|
||||||
project.import_fail
|
|
||||||
return
|
|
||||||
end
|
|
||||||
else
|
|
||||||
begin
|
|
||||||
gitlab_shell.import_repository(project.path_with_namespace, project.import_url)
|
|
||||||
rescue Gitlab::Shell::Error => e
|
|
||||||
project.update(import_error: e.message)
|
|
||||||
project.import_fail
|
|
||||||
return
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
data_import_result =
|
if result[:status] == :error
|
||||||
case project.import_type
|
project.update(import_error: result[:message])
|
||||||
when 'github'
|
|
||||||
Gitlab::GithubImport::Importer.new(project).execute
|
|
||||||
when 'gitlab'
|
|
||||||
Gitlab::GitlabImport::Importer.new(project).execute
|
|
||||||
when 'bitbucket'
|
|
||||||
Gitlab::BitbucketImport::Importer.new(project).execute
|
|
||||||
when 'google_code'
|
|
||||||
Gitlab::GoogleCodeImport::Importer.new(project).execute
|
|
||||||
when 'fogbugz'
|
|
||||||
Gitlab::FogbugzImport::Importer.new(project).execute
|
|
||||||
else
|
|
||||||
true
|
|
||||||
end
|
|
||||||
|
|
||||||
unless data_import_result
|
|
||||||
project.update(import_error: "The remote issue data could not be imported.")
|
|
||||||
project.import_fail
|
project.import_fail
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
if project.import_type == 'bitbucket'
|
|
||||||
Gitlab::BitbucketImport::KeyDeleter.new(project).execute
|
|
||||||
end
|
|
||||||
|
|
||||||
project.import_finish
|
project.import_finish
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -0,0 +1,106 @@
|
||||||
|
require 'spec_helper'
|
||||||
|
|
||||||
|
describe Projects::ImportService, services: true do
|
||||||
|
let!(:project) { create(:empty_project) }
|
||||||
|
let(:user) { project.creator }
|
||||||
|
|
||||||
|
subject { described_class.new(project, user) }
|
||||||
|
|
||||||
|
describe '#execute' do
|
||||||
|
context 'with unknown url' do
|
||||||
|
before do
|
||||||
|
project.import_url = Project::UNKNOWN_IMPORT_URL
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'succeeds if repository is created successfully' do
|
||||||
|
expect(project).to receive(:create_repository).and_return(true)
|
||||||
|
|
||||||
|
result = subject.execute
|
||||||
|
|
||||||
|
expect(result[:status]).to eq :success
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'fails if repository creation fails' do
|
||||||
|
expect(project).to receive(:create_repository).and_return(false)
|
||||||
|
|
||||||
|
result = subject.execute
|
||||||
|
|
||||||
|
expect(result[:status]).to eq :error
|
||||||
|
expect(result[:message]).to eq 'The repository could not be created.'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'with known url' do
|
||||||
|
before do
|
||||||
|
project.import_url = 'https://github.com/vim/vim.git'
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'succeeds if repository import is successfully' do
|
||||||
|
expect_any_instance_of(Gitlab::Shell).to receive(:import_repository).with(project.path_with_namespace, project.import_url).and_return(true)
|
||||||
|
|
||||||
|
result = subject.execute
|
||||||
|
|
||||||
|
expect(result[:status]).to eq :success
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'fails if repository import fails' do
|
||||||
|
expect_any_instance_of(Gitlab::Shell).to receive(:import_repository).with(project.path_with_namespace, project.import_url).and_raise(Gitlab::Shell::Error.new('Failed to import the repository'))
|
||||||
|
|
||||||
|
result = subject.execute
|
||||||
|
|
||||||
|
expect(result[:status]).to eq :error
|
||||||
|
expect(result[:message]).to eq 'Failed to import the repository'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'with valid importer' do
|
||||||
|
before do
|
||||||
|
stub_github_omniauth_provider
|
||||||
|
|
||||||
|
project.import_url = 'https://github.com/vim/vim.git'
|
||||||
|
project.import_type = 'github'
|
||||||
|
|
||||||
|
allow(project).to receive(:import_data).and_return(double.as_null_object)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'succeeds if importer succeeds' do
|
||||||
|
expect_any_instance_of(Gitlab::Shell).to receive(:import_repository).with(project.path_with_namespace, project.import_url).and_return(true)
|
||||||
|
expect_any_instance_of(Gitlab::GithubImport::Importer).to receive(:execute).and_return(true)
|
||||||
|
|
||||||
|
result = subject.execute
|
||||||
|
|
||||||
|
expect(result[:status]).to eq :success
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'fails if importer fails' do
|
||||||
|
expect_any_instance_of(Gitlab::Shell).to receive(:import_repository).with(project.path_with_namespace, project.import_url).and_return(true)
|
||||||
|
expect_any_instance_of(Gitlab::GithubImport::Importer).to receive(:execute).and_return(false)
|
||||||
|
|
||||||
|
result = subject.execute
|
||||||
|
|
||||||
|
expect(result[:status]).to eq :error
|
||||||
|
expect(result[:message]).to eq 'The remote data could not be imported.'
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'fails if importer raise an error' do
|
||||||
|
expect_any_instance_of(Gitlab::Shell).to receive(:import_repository).with(project.path_with_namespace, project.import_url).and_return(true)
|
||||||
|
expect_any_instance_of(Gitlab::GithubImport::Importer).to receive(:execute).and_raise(Projects::ImportService::Error.new('Github: failed to connect API'))
|
||||||
|
|
||||||
|
result = subject.execute
|
||||||
|
|
||||||
|
expect(result[:status]).to eq :error
|
||||||
|
expect(result[:message]).to eq 'Github: failed to connect API'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def stub_github_omniauth_provider
|
||||||
|
provider = OpenStruct.new(
|
||||||
|
name: 'github',
|
||||||
|
app_id: 'asd123',
|
||||||
|
app_secret: 'asd123'
|
||||||
|
)
|
||||||
|
|
||||||
|
Gitlab.config.omniauth.providers << provider
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
Loading…
Reference in New Issue