mirror of
https://github.com/wahyd4/gitlabhq.git
synced 2026-08-27 21:46:16 +10:00
lots of refactoring to reuse import service
This commit is contained in:
@@ -12,12 +12,10 @@ class Import::GitlabProjectsController < Import::BaseController
|
||||
return redirect_back_or_default(options: { alert: "You need to upload a GitLab project export archive." })
|
||||
end
|
||||
|
||||
@project = Project.create_from_import_job(current_user_id: current_user.id,
|
||||
tmp_file: File.expand_path(params[:file].path),
|
||||
namespace_id: project_params[:namespace_id],
|
||||
project_path: project_params[:path])
|
||||
|
||||
@project = Gitlab::GitlabImport::ProjectCreator.new(repo, namespace, current_user, access_params).execute
|
||||
@project = Gitlab::GitlabImport::ProjectCreator.new(Namespace.find(project_params[:namespace_id]),
|
||||
current_user,
|
||||
File.expand_path(params[:file].path),
|
||||
project_params[:path]).execute
|
||||
|
||||
flash[:notice] = "The project import has been started."
|
||||
|
||||
|
||||
@@ -190,7 +190,7 @@ class ProjectsController < Projects::ApplicationController
|
||||
|
||||
redirect_to(
|
||||
edit_project_path(@project),
|
||||
notice: "Project export successfully started"
|
||||
notice: "Project export successfully started."
|
||||
)
|
||||
end
|
||||
|
||||
|
||||
@@ -492,6 +492,10 @@ class Project < ActiveRecord::Base
|
||||
Gitlab::UrlSanitizer.new(import_url).masked_url
|
||||
end
|
||||
|
||||
def gitlab_project_import?
|
||||
import_type == 'gitlab_project'
|
||||
end
|
||||
|
||||
def check_limit
|
||||
unless creator.can_create_project? or namespace.kind == 'group'
|
||||
projects_limit = creator.projects_limit
|
||||
|
||||
@@ -45,10 +45,6 @@ class Todo < ActiveRecord::Base
|
||||
target_type == "Commit"
|
||||
end
|
||||
|
||||
def for_project?
|
||||
target_type == "Project"
|
||||
end
|
||||
|
||||
# override to return commits, which are not active record
|
||||
def target
|
||||
if for_commit?
|
||||
|
||||
@@ -52,9 +52,11 @@ module Projects
|
||||
|
||||
save_project_and_import_data(import_data)
|
||||
|
||||
@project.import_url = download_export_namespace_project_path(@project.namespace, @project) if @project.gitlab_project_import?
|
||||
|
||||
@project.import_start if @project.import?
|
||||
|
||||
after_create_actions if @project.persisted?
|
||||
after_create_actions if @project.persisted? && !@project.gitlab_project_import?
|
||||
|
||||
if @project.errors.empty?
|
||||
@project.add_import_job if @project.import?
|
||||
|
||||
@@ -9,7 +9,8 @@ module Projects
|
||||
'fogbugz',
|
||||
'gitlab',
|
||||
'github',
|
||||
'google_code'
|
||||
'google_code',
|
||||
'gitlab_project'
|
||||
]
|
||||
|
||||
def execute
|
||||
@@ -37,7 +38,7 @@ module Projects
|
||||
|
||||
def import_repository
|
||||
begin
|
||||
gitlab_shell.import_repository(project.path_with_namespace, project.import_url)
|
||||
gitlab_shell.import_repository(project.path_with_namespace, project.import_url) unless @project.gitlab_project_import?
|
||||
rescue Gitlab::Shell::Error => e
|
||||
raise Error, "Error importing repository #{project.import_url} into #{project.path_with_namespace} - #{e.message}"
|
||||
end
|
||||
@@ -58,6 +59,8 @@ module Projects
|
||||
end
|
||||
|
||||
def importer
|
||||
return Gitlab::ImportExport::Importer if @project.gitlab_project_import?
|
||||
|
||||
class_name = "Gitlab::#{project.import_type.camelize}Import::Importer"
|
||||
class_name.constantize.new(project)
|
||||
end
|
||||
|
||||
@@ -120,6 +120,19 @@
|
||||
= link_to 'Housekeeping', housekeeping_namespace_project_path(@project.namespace, @project),
|
||||
method: :post, class: "btn btn-save"
|
||||
%hr
|
||||
.row.prepend-top-default
|
||||
.col-lg-3
|
||||
%h4.prepend-top-0
|
||||
Export project
|
||||
%p.append-bottom-0
|
||||
%p
|
||||
Generates a compressed export file of the project and sends a link to download the export.
|
||||
.col-lg-9
|
||||
|
||||
= link_to 'Generate new export', export_namespace_project_path(@project.namespace, @project),
|
||||
method: :post, class: "btn btn-default"
|
||||
|
||||
%hr
|
||||
- if can? current_user, :archive_project, @project
|
||||
.row.prepend-top-default
|
||||
.col-lg-3
|
||||
|
||||
@@ -7,10 +7,10 @@ class ProjectImportWorker
|
||||
def perform(current_user_id, tmp_file, namespace_id, path)
|
||||
current_user = User.find(current_user_id)
|
||||
|
||||
project = Gitlab::ImportExport::ImportService.execute(archive_file: tmp_file,
|
||||
owner: current_user,
|
||||
namespace_id: namespace_id,
|
||||
project_path: path)
|
||||
project = Gitlab::ImportExport::Importer.execute(archive_file: tmp_file,
|
||||
owner: current_user,
|
||||
namespace_id: namespace_id,
|
||||
project_path: path)
|
||||
if project
|
||||
project.repository.after_import
|
||||
else
|
||||
|
||||
@@ -3,24 +3,21 @@ module Gitlab
|
||||
class ProjectCreator
|
||||
attr_reader :repo, :namespace, :current_user, :session_data
|
||||
|
||||
def initialize(repo, namespace, current_user, session_data)
|
||||
@repo = repo
|
||||
@namespace = namespace
|
||||
def initialize(namespace_id, current_user, file, project_path)
|
||||
@namespace_id = namespace_id
|
||||
@current_user = current_user
|
||||
@session_data = session_data
|
||||
@file = file
|
||||
@project_path = project_path
|
||||
end
|
||||
|
||||
def execute
|
||||
::Projects::CreateService.new(
|
||||
current_user,
|
||||
name: repo["name"],
|
||||
path: repo["path"],
|
||||
description: repo["description"],
|
||||
namespace_id: namespace.id,
|
||||
visibility_level: repo["visibility_level"],
|
||||
import_type: "gitlab",
|
||||
import_source: repo["path_with_namespace"],
|
||||
import_url: repo["http_url_to_repo"].sub("://", "://oauth2:#{@session_data[:gitlab_access_token]}@")
|
||||
name: @project_path,
|
||||
path: @project_path,
|
||||
namespace_id: namespace_id,
|
||||
import_type: "gitlab_project",
|
||||
import_source: @file
|
||||
).execute
|
||||
end
|
||||
end
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
module Gitlab
|
||||
module ImportExport
|
||||
class FileImporter
|
||||
include Gitlab::ImportExport::CommandLineUtil
|
||||
|
||||
def self.import(*args)
|
||||
new(*args).import
|
||||
end
|
||||
|
||||
def initialize(archive_file:, shared:)
|
||||
@archive_file = archive_file
|
||||
@shared = shared
|
||||
end
|
||||
|
||||
def import
|
||||
FileUtils.mkdir_p(@shared.export_path)
|
||||
decompress_archive
|
||||
rescue => e
|
||||
@shared.error(e)
|
||||
false
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def decompress_archive
|
||||
untar_zxf(archive: @archive_file, dir: @shared.export_path)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -30,8 +30,6 @@ project_tree:
|
||||
# Only include the following attributes for the models specified.
|
||||
included_attributes:
|
||||
project:
|
||||
- :name
|
||||
- :path
|
||||
- :description
|
||||
- :issues_enabled
|
||||
- :merge_requests_enabled
|
||||
|
||||
@@ -1,81 +0,0 @@
|
||||
module Gitlab
|
||||
module ImportExport
|
||||
class ImportService
|
||||
|
||||
def self.execute(*args)
|
||||
new(*args).execute
|
||||
end
|
||||
|
||||
def initialize(archive_file:, owner:, namespace_id:, project_path:)
|
||||
@archive_file = archive_file
|
||||
@current_user = owner
|
||||
@namespace = Namespace.find(namespace_id)
|
||||
@shared = Gitlab::ImportExport::Shared.new(relative_path: path_with_namespace(project_path), project_path: project_path)
|
||||
end
|
||||
|
||||
def execute
|
||||
Gitlab::ImportExport::Importer.import(archive_file: @archive_file,
|
||||
shared: @shared)
|
||||
if check_version! && [project_tree, repo_restorer, wiki_restorer, uploads_restorer].all?(&:restore)
|
||||
project_tree.project
|
||||
else
|
||||
project_tree.project.destroy if project_tree.project
|
||||
nil
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def check_version!
|
||||
Gitlab::ImportExport::VersionChecker.check!(shared: @shared)
|
||||
end
|
||||
|
||||
def project_tree
|
||||
@project_tree ||= Gitlab::ImportExport::ProjectTreeRestorer.new(user: @current_user,
|
||||
shared: @shared,
|
||||
namespace_id: @namespace.id)
|
||||
end
|
||||
|
||||
def repo_restorer
|
||||
Gitlab::ImportExport::RepoRestorer.new(path_to_bundle: repo_path,
|
||||
shared: @shared,
|
||||
project: project_tree.project)
|
||||
end
|
||||
|
||||
def wiki_restorer
|
||||
Gitlab::ImportExport::RepoRestorer.new(path_to_bundle: wiki_repo_path,
|
||||
shared: @shared,
|
||||
project: ProjectWiki.new(project_tree.project),
|
||||
wiki: true)
|
||||
end
|
||||
|
||||
def uploads_restorer
|
||||
Gitlab::ImportExport::UploadsRestorer.new(project: project_tree.project, shared: @shared)
|
||||
end
|
||||
|
||||
def path_with_namespace(project_path)
|
||||
File.join(@namespace.path, project_path)
|
||||
end
|
||||
|
||||
def repo_path
|
||||
File.join(@shared.export_path, 'project.bundle')
|
||||
end
|
||||
|
||||
def wiki_repo_path
|
||||
File.join(@shared.export_path, 'project.wiki.bundle')
|
||||
end
|
||||
|
||||
def attributes_for_todo
|
||||
{ user_id: @current_user.id,
|
||||
project_id: project_tree.project.id,
|
||||
target_type: 'Project',
|
||||
target: project_tree.project,
|
||||
action: Todo::IMPORTED,
|
||||
author_id: @current_user.id,
|
||||
state: :pending,
|
||||
target_id: project_tree.project.id
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,29 +1,79 @@
|
||||
module Gitlab
|
||||
module ImportExport
|
||||
class Importer
|
||||
include Gitlab::ImportExport::CommandLineUtil
|
||||
|
||||
def self.import(*args)
|
||||
new(*args).import
|
||||
def self.execute(*args)
|
||||
new(*args).execute
|
||||
end
|
||||
|
||||
def initialize(archive_file:, shared:)
|
||||
@archive_file = archive_file
|
||||
@shared = shared
|
||||
def initialize(project)
|
||||
@archive_file = project.import_source
|
||||
@current_user = project.creator
|
||||
@shared = Gitlab::ImportExport::Shared.new(relative_path: path_with_namespace(@project.path))
|
||||
end
|
||||
|
||||
def import
|
||||
FileUtils.mkdir_p(@shared.export_path)
|
||||
decompress_archive
|
||||
rescue => e
|
||||
@shared.error(e)
|
||||
false
|
||||
def execute
|
||||
Gitlab::ImportExport::FileImporter.import(archive_file: @archive_file,
|
||||
shared: @shared)
|
||||
if check_version! && [project_tree, repo_restorer, wiki_restorer, uploads_restorer].all?(&:restore)
|
||||
project_tree.project
|
||||
else
|
||||
project_tree.project.destroy if project_tree.project
|
||||
nil
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def decompress_archive
|
||||
untar_zxf(archive: @archive_file, dir: @shared.export_path)
|
||||
def check_version!
|
||||
Gitlab::ImportExport::VersionChecker.check!(shared: @shared)
|
||||
end
|
||||
|
||||
def project_tree
|
||||
@project_tree ||= Gitlab::ImportExport::ProjectTreeRestorer.new(user: @current_user,
|
||||
shared: @shared,
|
||||
project: @project)
|
||||
end
|
||||
|
||||
def repo_restorer
|
||||
Gitlab::ImportExport::RepoRestorer.new(path_to_bundle: repo_path,
|
||||
shared: @shared,
|
||||
project: project_tree.project)
|
||||
end
|
||||
|
||||
def wiki_restorer
|
||||
Gitlab::ImportExport::RepoRestorer.new(path_to_bundle: wiki_repo_path,
|
||||
shared: @shared,
|
||||
project: ProjectWiki.new(project_tree.project),
|
||||
wiki: true)
|
||||
end
|
||||
|
||||
def uploads_restorer
|
||||
Gitlab::ImportExport::UploadsRestorer.new(project: project_tree.project, shared: @shared)
|
||||
end
|
||||
|
||||
def path_with_namespace(project_path)
|
||||
File.join(@namespace.path, project_path)
|
||||
end
|
||||
|
||||
def repo_path
|
||||
File.join(@shared.export_path, 'project.bundle')
|
||||
end
|
||||
|
||||
def wiki_repo_path
|
||||
File.join(@shared.export_path, 'project.wiki.bundle')
|
||||
end
|
||||
|
||||
def attributes_for_todo
|
||||
{ user_id: @current_user.id,
|
||||
project_id: project_tree.project.id,
|
||||
target_type: 'Project',
|
||||
target: project_tree.project,
|
||||
action: Todo::IMPORTED,
|
||||
author_id: @current_user.id,
|
||||
state: :pending,
|
||||
target_id: project_tree.project.id
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,41 +0,0 @@
|
||||
module Gitlab
|
||||
module ImportExport
|
||||
module ProjectFactory
|
||||
extend self
|
||||
|
||||
def create(project_params:, user:, namespace_id:)
|
||||
project = Project.new(project_params.except('id'))
|
||||
project.creator = user
|
||||
check_namespace(namespace_id, project, user)
|
||||
end
|
||||
|
||||
def check_namespace(namespace_id, project, user)
|
||||
if namespace_id
|
||||
# Find matching namespace and check if it allowed
|
||||
# for current user if namespace_id passed.
|
||||
if allowed_namespace?(user, namespace_id)
|
||||
project.namespace_id = namespace_id
|
||||
else
|
||||
project.namespace_id = nil
|
||||
deny_namespace(project)
|
||||
end
|
||||
else
|
||||
# Set current user namespace if namespace_id is nil
|
||||
project.namespace_id = user.namespace_id
|
||||
end
|
||||
project
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def allowed_namespace?(user, namespace_id)
|
||||
namespace = Namespace.find_by(id: namespace_id)
|
||||
user.can?(:create_projects, namespace)
|
||||
end
|
||||
|
||||
def deny_namespace(project)
|
||||
project.errors.add(:namespace, "is not valid")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -2,12 +2,11 @@ module Gitlab
|
||||
module ImportExport
|
||||
class ProjectTreeRestorer
|
||||
|
||||
def initialize(user:, shared:, namespace_id:)
|
||||
def initialize(user:, shared:, project:)
|
||||
@path = File.join(shared.export_path, 'project.json')
|
||||
@user = user
|
||||
@project_path = shared.opts[:project_path]
|
||||
@namespace_id = namespace_id
|
||||
@shared = shared
|
||||
@project = project
|
||||
end
|
||||
|
||||
def restore
|
||||
@@ -21,7 +20,7 @@ module Gitlab
|
||||
end
|
||||
|
||||
def project
|
||||
@project ||= create_project
|
||||
@restored_project ||= restore_project
|
||||
end
|
||||
|
||||
private
|
||||
@@ -57,14 +56,10 @@ module Gitlab
|
||||
end
|
||||
end
|
||||
|
||||
def create_project
|
||||
def restore_project
|
||||
project_params = @tree_hash.reject { |_key, value| value.is_a?(Array) }
|
||||
project = Gitlab::ImportExport::ProjectFactory.create(
|
||||
project_params: project_params, user: @user, namespace_id: @namespace_id)
|
||||
project.path = @project_path
|
||||
project.name = @project_path
|
||||
project.save!
|
||||
project
|
||||
@project.update(project_params)
|
||||
@project
|
||||
end
|
||||
|
||||
# Given a relation hash containing one or more models and its relationships,
|
||||
|
||||
Reference in New Issue
Block a user