Extract Projects::ImportService service from RepositoryImportWorker
This commit is contained in:
parent
cae0929a28
commit
6dd88e090e
3 changed files with 184 additions and 39 deletions
71
app/services/projects/import_service.rb
Normal file
71
app/services/projects/import_service.rb
Normal file
|
@ -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
|
||||
|
||||
attr_accessor :project, :current_user
|
||||
|
||||
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
|
||||
# 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
|
||||
result = Projects::ImportService.new(project, current_user).execute
|
||||
|
||||
data_import_result =
|
||||
case project.import_type
|
||||
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.")
|
||||
if result[:status] == :error
|
||||
project.update(import_error: result[:message])
|
||||
project.import_fail
|
||||
return
|
||||
end
|
||||
|
||||
if project.import_type == 'bitbucket'
|
||||
Gitlab::BitbucketImport::KeyDeleter.new(project).execute
|
||||
end
|
||||
|
||||
project.import_finish
|
||||
end
|
||||
end
|
||||
|
|
106
spec/services/projects/import_service_spec.rb
Normal file
106
spec/services/projects/import_service_spec.rb
Normal file
|
@ -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 a new issue