gitlab-org--gitlab-foss/lib/gitlab/github_import/importer.rb
Douglas Barbosa Alexandre b5f9541778 Skip wiki creation when GitHub project has wiki enabled
If the GitHub project repository has wiki, we should not create
the default wiki. Otherwise the GitHub importer will fail because
the wiki repository already exist.

This bug was introduced here
https://gitlab.com/gitlab-org/gitlab-ce/commit/892dea67717c0efbd6a28f763
9f34535ec0a8747
2016-10-04 13:06:45 -03:00

200 lines
6.4 KiB
Ruby

module Gitlab
module GithubImport
class Importer
include Gitlab::ShellAdapter
attr_reader :client, :errors, :project, :repo, :repo_url
def initialize(project)
@project = project
@repo = project.import_source
@repo_url = project.import_url
@errors = []
@labels = {}
if credentials
@client = Client.new(credentials[:user])
else
raise Projects::ImportService::Error, "Unable to find project import data credentials for project ID: #{@project.id}"
end
end
def execute
import_labels
import_milestones
import_issues
import_pull_requests
import_comments
import_wiki
import_releases
handle_errors
true
end
private
def credentials
@credentials ||= project.import_data.credentials if project.import_data
end
def handle_errors
return unless errors.any?
project.update_column(:import_error, {
message: 'The remote data could not be fully imported.',
errors: errors
}.to_json)
end
def import_labels
client.labels(repo, per_page: 100) do |labels|
labels.each do |raw|
begin
label = LabelFormatter.new(project, raw).create!
@labels[label.title] = label.id
rescue => e
errors << { type: :label, url: Gitlab::UrlSanitizer.sanitize(raw.url), errors: e.message }
end
end
end
end
def import_milestones
client.milestones(repo, state: :all, per_page: 100) do |milestones|
milestones.each do |raw|
begin
MilestoneFormatter.new(project, raw).create!
rescue => e
errors << { type: :milestone, url: Gitlab::UrlSanitizer.sanitize(raw.url), errors: e.message }
end
end
end
end
def import_issues
client.issues(repo, state: :all, sort: :created, direction: :asc, per_page: 100) do |issues|
issues.each do |raw|
gh_issue = IssueFormatter.new(project, raw)
if gh_issue.valid?
begin
issue = gh_issue.create!
apply_labels(issue, raw)
rescue => e
errors << { type: :issue, url: Gitlab::UrlSanitizer.sanitize(raw.url), errors: e.message }
end
end
end
end
end
def import_pull_requests
client.pull_requests(repo, state: :all, sort: :created, direction: :asc, per_page: 100) do |pull_requests|
pull_requests.each do |raw|
pull_request = PullRequestFormatter.new(project, raw)
next unless pull_request.valid?
begin
restore_source_branch(pull_request) unless pull_request.source_branch_exists?
restore_target_branch(pull_request) unless pull_request.target_branch_exists?
merge_request = pull_request.create!
apply_labels(merge_request, raw)
rescue => e
errors << { type: :pull_request, url: Gitlab::UrlSanitizer.sanitize(pull_request.url), errors: e.message }
ensure
clean_up_restored_branches(pull_request)
end
end
end
project.repository.after_remove_branch
end
def restore_source_branch(pull_request)
project.repository.fetch_ref(repo_url, "pull/#{pull_request.number}/head", pull_request.source_branch_name)
end
def restore_target_branch(pull_request)
project.repository.create_branch(pull_request.target_branch_name, pull_request.target_branch_sha)
end
def remove_branch(name)
project.repository.delete_branch(name)
rescue Rugged::ReferenceError
errors << { type: :remove_branch, name: name }
end
def clean_up_restored_branches(pull_request)
remove_branch(pull_request.source_branch_name) unless pull_request.source_branch_exists?
remove_branch(pull_request.target_branch_name) unless pull_request.target_branch_exists?
end
def apply_labels(issuable, raw_issuable)
if raw_issuable.labels.count > 0
label_ids = raw_issuable.labels
.map { |attrs| @labels[attrs.name] }
.compact
issuable.update_attribute(:label_ids, label_ids)
end
end
def import_comments
client.issues_comments(repo, per_page: 100) do |comments|
create_comments(comments, :issue)
end
client.pull_requests_comments(repo, per_page: 100) do |comments|
create_comments(comments, :pull_request)
end
end
def create_comments(comments, issuable_type)
ActiveRecord::Base.no_touching do
comments.each do |raw|
begin
comment = CommentFormatter.new(project, raw)
issuable_class = issuable_type == :issue ? Issue : MergeRequest
iid = raw.send("#{issuable_type}_url").split('/').last # GH doesn't return parent ID directly
issuable = issuable_class.find_by_iid(iid)
next unless issuable
issuable.notes.create!(comment.attributes)
rescue => e
errors << { type: :comment, url: Gitlab::UrlSanitizer.sanitize(raw.url), errors: e.message }
end
end
end
end
def import_wiki
unless project.wiki.repository_exists?
wiki = WikiFormatter.new(project)
gitlab_shell.import_repository(project.repository_storage_path, wiki.path_with_namespace, wiki.import_url)
end
rescue Gitlab::Shell::Error => e
# GitHub error message when the wiki repo has not been created,
# this means that repo has wiki enabled, but have no pages. So,
# we can skip the import.
if e.message !~ /repository not exported/
errors << { type: :wiki, errors: e.message }
end
end
def import_releases
client.releases(repo, per_page: 100) do |releases|
releases.each do |raw|
begin
gh_release = ReleaseFormatter.new(project, raw)
gh_release.create! if gh_release.valid?
rescue => e
errors << { type: :release, url: Gitlab::UrlSanitizer.sanitize(raw.url), errors: e.message }
end
end
end
end
end
end
end