diff options
Diffstat (limited to 'lib/gitlab/google_code_import/importer.rb')
-rw-r--r-- | lib/gitlab/google_code_import/importer.rb | 373 |
1 files changed, 0 insertions, 373 deletions
diff --git a/lib/gitlab/google_code_import/importer.rb b/lib/gitlab/google_code_import/importer.rb deleted file mode 100644 index 4da2004b74f..00000000000 --- a/lib/gitlab/google_code_import/importer.rb +++ /dev/null @@ -1,373 +0,0 @@ -# frozen_string_literal: true - -module Gitlab - module GoogleCodeImport - class Importer - attr_reader :project, :repo, :closed_statuses - - NICE_LABEL_COLOR_HASH = - { - 'Status: New' => '#428bca', - 'Status: Accepted' => '#5cb85c', - 'Status: Started' => '#8e44ad', - 'Priority: Critical' => '#ffcfcf', - 'Priority: High' => '#deffcf', - 'Priority: Medium' => '#fff5cc', - 'Priority: Low' => '#cfe9ff', - 'Type: Defect' => '#d9534f', - 'Type: Enhancement' => '#44ad8e', - 'Type: Task' => '#4b6dd0', - 'Type: Review' => '#8e44ad', - 'Type: Other' => '#7f8c8d' - }.freeze - - def initialize(project) - @project = project - - import_data = project.import_data.try(:data) - repo_data = import_data["repo"] if import_data - @repo = GoogleCodeImport::Repository.new(repo_data) - - @closed_statuses = [] - @known_labels = Set.new - end - - def execute - return true unless repo.valid? - - import_status_labels - - import_labels - - import_issues - - true - end - - private - - def user_map - @user_map ||= begin - user_map = Hash.new do |hash, user| - # Replace ... by \.\.\., so `johnsm...@gmail.com` isn't autolinked. - Client.mask_email(user).sub("...", "\\.\\.\\.") - end - - import_data = project.import_data.try(:data) - stored_user_map = import_data["user_map"] if import_data - user_map.update(stored_user_map) if stored_user_map - - user_map - end - end - - def import_status_labels - repo.raw_data["issuesConfig"]["statuses"].each do |status| - closed = !status["meansOpen"] - @closed_statuses << status["status"] if closed - - name = nice_status_name(status["status"]) - create_label(name) - @known_labels << name - end - end - - def import_labels - repo.raw_data["issuesConfig"]["labels"].each do |label| - name = nice_label_name(label["label"]) - create_label(name) - @known_labels << name - end - end - - # rubocop: disable CodeReuse/ActiveRecord - def import_issues - return unless repo.issues - - while raw_issue = repo.issues.shift - author = user_map[raw_issue["author"]["name"]] - date = DateTime.parse(raw_issue["published"]).to_formatted_s(:long) - - comments = raw_issue["comments"]["items"] - issue_comment = comments.shift - - content = format_content(issue_comment["content"]) - attachments = format_attachments(raw_issue["id"], 0, issue_comment["attachments"]) - - body = format_issue_body(author, date, content, attachments) - labels = import_issue_labels(raw_issue) - - assignee_id = nil - if raw_issue.key?("owner") - username = user_map[raw_issue["owner"]["name"]] - - if username.start_with?("@") - username = username[1..-1] - - if user = UserFinder.new(username).find_by_username - assignee_id = user.id - end - end - end - - issue = Issue.create!( - iid: raw_issue['id'], - project_id: project.id, - title: raw_issue['title'], - description: body, - author_id: project.creator_id, - assignee_ids: [assignee_id], - state_id: raw_issue['state'] == 'closed' ? Issue.available_states[:closed] : Issue.available_states[:opened] - ) - - issue_labels = ::LabelsFinder.new(nil, project_id: project.id, title: labels).execute(skip_authorization: true) - issue.update_attribute(:label_ids, issue_labels.pluck(:id)) - - import_issue_comments(issue, comments) - end - end - # rubocop: enable CodeReuse/ActiveRecord - - def import_issue_labels(raw_issue) - labels = [] - - raw_issue["labels"].each do |label| - name = nice_label_name(label) - labels << name - - unless @known_labels.include?(name) - create_label(name) - @known_labels << name - end - end - - labels << nice_status_name(raw_issue["status"]) - labels - end - - def import_issue_comments(issue, comments) - Note.transaction do - while raw_comment = comments.shift - next if raw_comment.key?("deletedBy") - - content = format_content(raw_comment["content"]) - updates = format_updates(raw_comment["updates"]) - attachments = format_attachments(issue.iid, raw_comment["id"], raw_comment["attachments"]) - - next if content.blank? && updates.blank? && attachments.blank? - - author = user_map[raw_comment["author"]["name"]] - date = DateTime.parse(raw_comment["published"]).to_formatted_s(:long) - - body = format_issue_comment_body( - raw_comment["id"], - author, - date, - content, - updates, - attachments - ) - - # Needs to match order of `comment_columns` below. - Note.create!( - project_id: project.id, - noteable_type: "Issue", - noteable_id: issue.id, - author_id: project.creator_id, - note: body - ) - end - end - end - - def nice_label_color(name) - NICE_LABEL_COLOR_HASH[name] || - case name - when /\AComponent:/ - '#fff39e' - when /\AOpSys:/ - '#e2e2e2' - when /\AMilestone:/ - '#fee3ff' - when *closed_statuses.map { |s| nice_status_name(s) } - '#cfcfcf' - else - '#e2e2e2' - end - end - - def nice_label_name(name) - name.sub("-", ": ") - end - - def nice_status_name(name) - "Status: #{name}" - end - - def linkify_issues(str) - str = str.gsub(/([Ii]ssue) ([0-9]+)/, '\1 #\2') - str = str.gsub(/([Cc]omment) #([0-9]+)/, '\1 \2') - str - end - - def escape_for_markdown(str) - # No headings and lists - str = str.gsub(/^#/, "\\#") - str = str.gsub(/^-/, "\\-") - - # No inline code - str = str.gsub("`", "\\`") - - # Carriage returns make me sad - str = str.delete("\r") - - # Markdown ignores single newlines, but we need them as <br />. - str = str.gsub("\n", " \n") - - str - end - - def create_label(name) - params = { name: name, color: nice_label_color(name) } - ::Labels::FindOrCreateService.new(nil, project, params).execute(skip_authorization: true) - end - - def format_content(raw_content) - linkify_issues(escape_for_markdown(raw_content)) - end - - def format_updates(raw_updates) - updates = [] - - if raw_updates.key?("status") - updates << "*Status: #{raw_updates["status"]}*" - end - - if raw_updates.key?("owner") - updates << "*Owner: #{user_map[raw_updates["owner"]]}*" - end - - if raw_updates.key?("cc") - cc = raw_updates["cc"].map do |l| - deleted = l.start_with?("-") - l = l[1..-1] if deleted - l = user_map[l] - l = "~~#{l}~~" if deleted - l - end - - updates << "*Cc: #{cc.join(", ")}*" - end - - if raw_updates.key?("labels") - labels = raw_updates["labels"].map do |l| - deleted = l.start_with?("-") - l = l[1..-1] if deleted - l = nice_label_name(l) - l = "~~#{l}~~" if deleted - l - end - - updates << "*Labels: #{labels.join(", ")}*" - end - - if raw_updates.key?("mergedInto") - updates << "*Merged into: ##{raw_updates["mergedInto"]}*" - end - - if raw_updates.key?("blockedOn") - blocked_ons = raw_updates["blockedOn"].map do |raw_blocked_on| - format_blocking_updates(raw_blocked_on) - end - - updates << "*Blocked on: #{blocked_ons.join(", ")}*" - end - - if raw_updates.key?("blocking") - blockings = raw_updates["blocking"].map do |raw_blocked_on| - format_blocking_updates(raw_blocked_on) - end - - updates << "*Blocking: #{blockings.join(", ")}*" - end - - updates - end - - def format_blocking_updates(raw_blocked_on) - name, id = raw_blocked_on.split(":", 2) - - deleted = name.start_with?("-") - name = name[1..-1] if deleted - - text = - if name == project.import_source - "##{id}" - else - "#{project.namespace.full_path}/#{name}##{id}" - end - - text = "~~#{text}~~" if deleted - text - end - - def format_attachments(issue_id, comment_id, raw_attachments) - return [] unless raw_attachments - - raw_attachments.map do |attachment| - next if attachment["isDeleted"] - - filename = attachment["fileName"] - link = "https://storage.googleapis.com/google-code-attachments/#{@repo.name}/issue-#{issue_id}/comment-#{comment_id}/#{filename}" - - text = "[#{filename}](#{link})" - text = "!#{text}" if filename =~ /\.(png|jpg|jpeg|gif|bmp|tiff)\z/i - text - end.compact - end - - def format_issue_comment_body(id, author, date, content, updates, attachments) - body = [] - body << "*Comment #{id} by #{author} on #{date}*" - body << "---" - - if content.blank? - content = "*(No comment has been entered for this change)*" - end - - body << content - - if updates.any? - body << "---" - body += updates - end - - if attachments.any? - body << "---" - body += attachments - end - - body.join("\n\n") - end - - def format_issue_body(author, date, content, attachments) - body = [] - body << "*By #{author} on #{date} (imported from Google Code)*" - body << "---" - - if content.blank? - content = "*(No description has been entered for this issue)*" - end - - body << content - - if attachments.any? - body << "---" - body += attachments - end - - body.join("\n\n") - end - end - end -end |