require_relative './gitlab_client.rb' require_relative './highline_cli.rb' module GitHelper class GitLabMergeRequest def create begin # Ask these questions right away base_branch new_mr_title options = { source_branch: local_branch, target_branch: base_branch, description: new_mr_body } puts "Creating merge request: #{new_mr_title}" mr = gitlab_client.create_merge_request(local_repo, new_mr_title, options) if mr.diff_refs.base_sha == mr.diff_refs.head_sha puts "Merge request was created, but no commits have been pushed to GitLab: #{mr.web_url}" else puts "Merge request successfully created: #{mr.web_url}" end rescue Gitlab::Error::Conflict => e puts 'Could not create merge request:' puts ' A merge request already exists for this branch' rescue Exception => e puts 'Could not create merge request:' puts e.message end end def merge begin # Ask these questions right away mr_id options = {} options[:should_remove_source_branch] = remove_source_branch? options[:squash] = squash_merge_request? options[:squash_commit_message] = existing_mr_title puts "Merging merge request: #{mr_id}" merge = gitlab_client.accept_merge_request(local_repo, mr_id, options) puts "Merge request successfully merged: #{merge.merge_commit_sha}" rescue Gitlab::Error::MethodNotAllowed => e puts 'Could not merge merge request:' puts ' The merge request is not mergeable' rescue Gitlab::Error::NotFound => e puts 'Could not merge merge request:' puts " Could not a locate a merge request to merge with ID #{mr_id}" rescue Exception => e puts 'Could not merge merge request:' puts e.message end end private def local_repo # Get the repository by looking in the remote URLs for the full repository name remotes = `git remote -v` return remotes.scan(/\S[\s]*[\S]+.com[\S]{1}([\S]*).git/).first.first end private def local_branch # Get the current branch by looking in the list of branches for the * branches = `git branch` return branches.scan(/\*\s([\S]*)/).first.first end private def read_template if mr_template_options.count == 1 apply_template?(mr_template_options.first) ? File.open(mr_template_options.first).read : '' else template_file_name_to_apply = template_to_apply template_file_name_to_apply == "None" ? '' : File.open(template_file_name_to_apply).read end end private def mr_id @mr_id ||= cli.ask('Merge Request ID?') end private def existing_mr_title @existing_mr_title ||= gitlab_client.merge_request(local_repo, mr_id).title end private def new_mr_title @new_mr_title ||= accept_autogenerated_title? ? autogenerated_title : cli.ask('Title?') end private def new_mr_body @new_mr_body ||= mr_template_options.empty? ? '' : read_template end private def base_branch @base_branch ||= base_branch_default? ? default_branch : cli.ask('Base branch?') end private def autogenerated_title @autogenerated_title ||= local_branch.split('_')[0..-1].join(' ').capitalize end private def default_branch @default_branch ||= gitlab_client.branches(local_repo).select { |branch| branch.default }.first.name end private def template_to_apply return @template_to_apply if @template_to_apply complete_options = mr_template_options << 'None' index = cli.ask_options("Which merge request template should be applied?", complete_options) @template_to_apply = complete_options[index] end private def mr_template_options return @mr_template_options if @mr_template_options nested_templates = Dir.glob(File.join("**/merge_request_templates", "*.md"), File::FNM_DOTMATCH | File::FNM_CASEFOLD) non_nested_templates = Dir.glob(File.join("**", "merge_request_template.md"), File::FNM_DOTMATCH | File::FNM_CASEFOLD) @mr_template_options = nested_templates.concat(non_nested_templates) end private def base_branch_default? answer = cli.ask("Is '#{default_branch}' the correct base branch for your new merge request? (y/n)") !!(answer =~ /^y/i) end private def accept_autogenerated_title? answer = cli.ask("Accept the autogenerated merge request title '#{autogenerated_title}'? (y/n)") !!(answer =~ /^y/i) end private def squash_merge_request? answer = cli.ask('Squash merge request? (y/n)') !!(answer =~ /^y/i) end private def remove_source_branch? answer = cli.ask('Remove source branch after merging? (y/n)') !!(answer =~ /^y/i) end private def apply_template?(template_file_name) answer = cli.ask("Apply the merge request template from #{template_file_name}? (y/n)") !!(answer =~ /^y/i) end private def gitlab_client @gitlab_client ||= GitHelper::GitLabClient.new.client end private def cli @cli ||= GitHelper::HighlineCli.new end end end