lib/rubocop_challenger/pull_request.rb
# frozen_string_literal: true
module RubocopChallenger
# Creates a pull request
class PullRequest
# @param user_name [String]
# The author name which use at the git commit
# @param user_email [String]
# The email address which use at the git commit
# @param options [Hash]
# Optional parameters
# @option base_branch [String]
# The Branch to merge into
# @option labels [Array<String>]
# Will create a pull request with the labels
# @option dry_run [Boolean]
# Does not create a pull request when given `true`
# @option project_column_name [String]
# A project column name. You can add the created PR to the GitHub project
# @option project_id [Integer]
# A target project ID. If does not supplied, this method will find a
# project which associated the repository. When the repository has
# multiple projects, you should supply this.
# @option verbose [Boolean]
# Displays executing command.
def initialize(user_name:, user_email:, **options) # rubocop:disable Metrics/MethodLength
@pr_comet = PrComet.new(
base: options[:base_branch],
branch: "rubocop-challenge/#{timestamp}",
user_name: user_name,
user_email: user_email,
verbose: options[:verbose]
)
@labels = options[:labels]
@dry_run = options[:dry_run]
@project_column_name = options[:project_column_name]
@project_id = options[:project_id]
end
# Add and commit local files to the pull request
#
# @param message [String] The commit message
# @yield Some commands where modify local files
# @return [Object] Return result of yield if you use &block
def commit!(message, &block)
pr_comet.commit message, &block
end
# Creates a pull request for the Rubocop Challenge
#
# @param rule [Rubocop::Rule]
# The corrected rule
# @param template_file_path [String, nil]
# The template file name which use to generate the pull request body
# @return [Boolean]
# Return true if its successed
def create_rubocop_challenge_pr!(rule, template_file_path = nil)
create_pull_request!(
title: "#{rule.title}-#{timestamp}",
body: Github::PrTemplate.new(rule, template_file_path).generate
)
end
# Creates a pull request which re-generate ".rubocop_todo.yml" with new
# version RuboCop.
#
# @param before_version [String]
# The version of RuboCop which created ".rubocop_todo.yml" before
# re-generate.
# @param after_version [String]
# The version of RuboCop which created ".rubocop_todo.yml" after
# re-generate
# @return [Boolean]
# Return true if its successed
def create_regenerate_todo_pr!(before_version, after_version)
create_pull_request!(
title: "Re-generate .rubocop_todo.yml with RuboCop v#{after_version}",
body: generate_pull_request_body(before_version, after_version)
)
end
private
attr_reader :pr_comet, :labels, :dry_run, :project_column_name, :project_id
# Create a PR with description of what modification were made.
#
# @params pr_comet_options [Hash]
def create_pull_request!(pr_comet_options)
options = {
labels: labels,
project_column_name: project_column_name,
project_id: project_id
}.merge(pr_comet_options)
pr_comet.create!(**options) unless dry_run
end
# @param before_version [String]
# @param after_version [String]
def generate_pull_request_body(before_version, after_version)
<<~MARKDOWN
Re-generated the .rubocop_todo.yml because it was generated by old version RuboCop.
* Using RuboCop version: [`#{before_version}...#{after_version}`](#{compare_page_url(before_version, after_version)})
* [Release Note](#{release_page_url(after_version)})
Auto generated by [rubocop_challenger](https://github.com/ryz310/rubocop_challenger)
MARKDOWN
end
RUBOCOP_REPO_URL = 'https://github.com/rubocop-hq/rubocop'
# Generates GitHub release note page URL
#
# @param after_version [String]
def release_page_url(after_version)
"#{RUBOCOP_REPO_URL}/releases/tag/v#{after_version}"
end
# Generates GitHub compare page URL
#
# @param before_version [String]
# @param after_version [String]
def compare_page_url(before_version, after_version)
"#{RUBOCOP_REPO_URL}/compare/v#{before_version}...v#{after_version}"
end
def timestamp
@timestamp ||= Time.now.strftime('%Y%m%d%H%M%S')
end
end
end