GitLab API | gitlab gem で Issueの一覧から Issue を登録するためのソースコードを生成する

# GitLab API | gitlab gem で Issueの一覧から Issue を登録するためのソースコードを生成する
## 概要
gitlab gem で Issueの一覧から Issue を登録するためのソースコードを生成します。

## 経緯
なんでこんな妙なことをしているかというと、GitLabサーバーAのデータを別マシンの
GitLabサーバーBに移行したかったのですが、
公式の手順でうまくいかなかったのでAPIで対応することにしました。

前提としてプロジェクトやユーザーの情報は移行済みです。
※プロジェクトやユーザーは基本的な登録内容は同じだが、id が変わっていることに注意。

## コードジェネレーター

generate_create_issues_code.rb

~~~ruby
require 'gitlab'

Gitlab.configure do |config|
  config.endpoint       = 'http://from_server_path/api/v3' 
  config.private_token  = 'from server token'
end

# コード生成のためのメソッドを GitLab API の Ruby ラッパーのクラスをオープンして追加します
module Gitlab
  class ObjectifiedHash
    # 1件の Issue を追加するためのコード生成
    def create_issue_code(project_name, title)
      options = options_code
      # 新旧サーバーで id が変わるためにプロジェクト名から id を取得するコードを生成しています。
      "Gitlab.create_issue(Gitlab.projects(per_page: 100).select { |e|e.name == '#{project_name}' }.first.id, '#{title}'#{options})"
    end

    # オプションのコード( milestone_id は使ってなかったので含めてません)
    def options_code
      options = %w{description state assignee_id labels}
      codes = options.each_with_object([]) do |option, memo|
        option_code = send("#{option}_option")
        next if option_code.empty?
        memo << option_code
      end
      codes.size == 0 ? '' : ", #{codes.join(', ')}"
    end

    def description_option
      return '' unless description
      "description: \"#{description}\""
    end

    def assignee_id_option
      return '' unless assignee
      # 新旧サーバーで id が変わるためにユーザー名から id を取得するコードを生成しています。
      "assignee_id: Gitlab.users.select { |e|e.name == '#{assignee.name}' }.first.id"
    end

    def labels_option
      return '' if labels.size == 0
      "labels:'#{labels.join(',')}'"
    end
  end
end

# プロジェクトごとにIssueを生成
projects = Gitlab.projects(per_page: 100)
projects.each do |project|
  project_name = project.name
  issues =  Gitlab.issues(project.id, per_page: 100)
  issues.each do |issue|
    puts issue.create_issue_code(project_name, issue.title)
  end
end
~~~

## 出力
~~~
# : 
# : 多数の出力
# : 
Gitlab.create_issue(Gitlab.projects(per_page: 100).select { |e|e.name == 'project1' }.first.id, 'title1', description: "sample", assignee_id: Gitlab.users.select { |e|e.name == 'user1' }.first.id)
Gitlab.create_issue(Gitlab.projects(per_page: 100).select { |e|e.name == 'project2' }.first.id, 'title2', description: "sample", assignee_id: Gitlab.users.select { |e|e.name == 'user2' }.first.id, labels:'ruby,gitlab')
# : 
# : 多数の出力
# : 
~~~

## コードジェネレーターで生成されたコードを利用して Issue の登録

create_issues.rb

~~~ruby
require 'gitlab'

Gitlab.configure do |config|
  config.endpoint       = 'http://to_server_path/api/v3' 
  config.private_token  = 'to server token'
end
puts Gitlab.issues.size

# : 
# : 多数の自動生成コードを貼り付け
# :
Gitlab.create_issue(Gitlab.projects(per_page: 100).select { |e|e.name == 'project1' }.first.id, 'title1', description: "sample", assignee_id: Gitlab.users.select { |e|e.name == 'user1' }.first.id)
Gitlab.create_issue(Gitlab.projects(per_page: 100).select { |e|e.name == 'project2' }.first.id, 'title2', description: "sample", assignee_id: Gitlab.users.select { |e|e.name == 'user2' }.first.id, labels:'ruby,gitlab')
# : 
# : 多数の自動生成コードを貼り付け
# :

puts Gitlab.issues.size # 件数分増加する
~~~

## 補足
* 新規登録時のステータスの反映はサポートされていないため、別途更新する必要がある
* *project* は 100 件以下の想定。それ以上ある場合は、ページング処理が必要
* *user* は 20 件以下の想定。それ以上ある場合は、 *per_page* を変更するかページング処理が必要

## 参照
* GitLab gem RubyGems
https://rubygems.org/gems/gitlab

* GitLab gem GitHub
https://github.com/NARKOZ/gitlab