Refactoring Github import to avoid memory leak

parent 104144f3
...@@ -9,6 +9,24 @@ module Github ...@@ -9,6 +9,24 @@ module Github
self.reset_callbacks :validate self.reset_callbacks :validate
end end
class Issue < ::Issue
self.table_name = 'issues'
self.reset_callbacks :save
self.reset_callbacks :commit
self.reset_callbacks :update
self.reset_callbacks :validate
end
class Note < ::Note
self.table_name = 'notes'
self.reset_callbacks :save
self.reset_callbacks :commit
self.reset_callbacks :update
self.reset_callbacks :validate
end
attr_reader :project, :repository, :cached_user_ids, :errors attr_reader :project, :repository, :cached_user_ids, :errors
def initialize(project) def initialize(project)
...@@ -22,7 +40,7 @@ module Github ...@@ -22,7 +40,7 @@ module Github
# Fetch repository # Fetch repository
begin begin
project.create_repository project.create_repository
project.repository.add_remote('github', "https://#{token}@github.com/#{owner}/#{repo}.git") project.repository.add_remote('github', "https://881a01d03026458e51285a4c7038c9fe4daa5561@github.com/#{owner}/#{repo}.git")
project.repository.set_remote_as_mirror('github') project.repository.set_remote_as_mirror('github')
project.repository.fetch_remote('github', forced: true) project.repository.fetch_remote('github', forced: true)
project.repository.remove_remote('github') project.repository.remove_remote('github')
...@@ -31,23 +49,35 @@ module Github ...@@ -31,23 +49,35 @@ module Github
end end
# Fetch labels # Fetch labels
labels = Github::Labels.new(owner, repo).fetch url = "/repos/#{owner}/#{repo}/labels"
loop do
response = Github::Client.new.get(url)
labels.each do |raw| response.body.each do |raw|
begin begin
label = Github::Representation::Label.new(raw) label = Github::Representation::Label.new(raw)
next if project.labels.where(title: label.title).exists?
project.labels.create!(title: label.title, color: label.color) project.labels.create!(title: label.title, color: label.color)
rescue => e rescue => e
error(:label, label.url, e.message) error(:label, label.url, e.message)
end end
end end
break unless url = response.rels[:next]
end
# Fetch milestones # Fetch milestones
milestones = Github::Milestones.new(owner, repo).fetch url = "/repos/#{owner}/#{repo}/milestones"
loop do
response = Github::Client.new.get(url, state: :all)
milestones.each do |raw| response.body.each do |raw|
begin begin
milestone = Github::Representation::Milestone.new(raw) milestone = Github::Representation::Milestone.new(raw)
next if project.milestones.where(iid: milestone.iid).exists?
project.milestones.create!( project.milestones.create!(
iid: milestone.iid, iid: milestone.iid,
...@@ -63,44 +93,85 @@ module Github ...@@ -63,44 +93,85 @@ module Github
end end
end end
break unless url = response.rels[:next]
end
# Fetch pull requests # Fetch pull requests
pull_requests = Github::PullRequests.new(owner, repo).fetch url = "/repos/#{owner}/#{repo}/pulls"
loop do
response = Github::Client.new.get(url, state: :all, sort: :created, direction: :asc)
pull_requests.each do |raw| response.body.each do |raw|
pull_request = Github::Representation::PullRequest.new(project, raw) pull_request = Github::Representation::PullRequest.new(project, raw)
next unless pull_request.valid? merge_request = MergeRequest.find_or_initialize_by(iid: pull_request.iid, source_project_id: project.id)
next unless merge_request.new_record? && pull_request.valid?
begin begin
restore_source_branch(pull_request) unless pull_request.source_branch_exists? restore_source_branch(pull_request) unless pull_request.source_branch_exists?
restore_target_branch(pull_request) unless pull_request.target_branch_exists? restore_target_branch(pull_request) unless pull_request.target_branch_exists?
merge_request = MergeRequest.find_or_initialize_by(iid: pull_request.iid, source_project_id: project.id) do |record| merge_request.iid = pull_request.iid
record.iid = pull_request.iid merge_request.title = pull_request.title
record.title = pull_request.title merge_request.description = pull_request.description
record.description = pull_request.description merge_request.source_project = pull_request.source_project
record.source_project = pull_request.source_project merge_request.source_branch = pull_request.source_branch_name
record.source_branch = pull_request.source_branch_name merge_request.source_branch_sha = pull_request.source_branch_sha
record.source_branch_sha = pull_request.source_branch_sha merge_request.target_project = pull_request.target_project
record.target_project = pull_request.target_project merge_request.target_branch = pull_request.target_branch_name
record.target_branch = pull_request.target_branch_name merge_request.target_branch_sha = pull_request.target_branch_sha
record.target_branch_sha = pull_request.target_branch_sha merge_request.state = pull_request.state
record.state = pull_request.state merge_request.milestone_id = milestone_id(pull_request.milestone)
record.milestone_id = milestone_id(pull_request.milestone) merge_request.author_id = user_id(pull_request.author, project.creator_id)
record.author_id = user_id(pull_request.author, project.creator_id) merge_request.assignee_id = user_id(pull_request.assignee)
record.assignee_id = user_id(pull_request.assignee) merge_request.created_at = pull_request.created_at
record.created_at = pull_request.created_at merge_request.updated_at = pull_request.updated_at
record.updated_at = pull_request.updated_at
end
merge_request.save(validate: false) merge_request.save(validate: false)
merge_request.merge_request_diffs.create merge_request.merge_request_diffs.create
rescue => e rescue => e
error(:pull_request, pull_request.url, "#{e.message}\n\n#{e.exception.backtrace.join('\n')}") error(:pull_request, pull_request.url, e.message)
ensure ensure
clean_up_restored_branches(pull_request) clean_up_restored_branches(pull_request)
end end
end end
break unless url = response.rels[:next]
end
# Fetch issues
url = "/repos/#{owner}/#{repo}/issues"
loop do
response = Github::Client.new.get(url, state: :all, sort: :created, direction: :asc)
response.body.each do |raw|
representation = Github::Representation::Issue.new(raw)
next if representation.pull_request?
next if Issue.where(iid: representation.iid, project_id: project.id).exists?
begin
issue = Issue.new
issue.iid = representation.iid
issue.project_id = project.id
issue.title = representation.title
issue.description = representation.description
issue.state = representation.state
issue.milestone_id = milestone_id(representation.milestone)
issue.author_id = user_id(representation.author, project.creator_id)
issue.assignee_id = user_id(representation.assignee)
issue.created_at = representation.created_at
issue.updated_at = representation.updated_at
issue.save(validate: false)
rescue => e
error(:issue, representation.url, e.message)
end
end
break unless url = response.rels[:next]
end
repository.expire_content_cache repository.expire_content_cache
errors errors
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment