git_helper 3.3.1 → 3.3.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +2 -0
  3. data/Gemfile.lock +20 -0
  4. data/Guardfile +3 -1
  5. data/README.md +1 -1
  6. data/Rakefile +2 -0
  7. data/bin/git-helper +18 -13
  8. data/lib/git_helper.rb +5 -1
  9. data/lib/git_helper/change_remote.rb +11 -3
  10. data/lib/git_helper/checkout_default.rb +2 -0
  11. data/lib/git_helper/clean_branches.rb +2 -0
  12. data/lib/git_helper/code_request.rb +29 -16
  13. data/lib/git_helper/empty_commit.rb +2 -0
  14. data/lib/git_helper/forget_local_commits.rb +2 -0
  15. data/lib/git_helper/git_config_reader.rb +3 -5
  16. data/lib/git_helper/gitlab_client.rb +2 -0
  17. data/lib/git_helper/highline_cli.rb +3 -1
  18. data/lib/git_helper/local_code.rb +18 -8
  19. data/lib/git_helper/merge_request.rb +86 -66
  20. data/lib/git_helper/new_branch.rb +2 -0
  21. data/lib/git_helper/octokit_client.rb +2 -0
  22. data/lib/git_helper/pull_request.rb +94 -63
  23. data/lib/git_helper/setup.rb +37 -17
  24. data/lib/git_helper/version.rb +3 -1
  25. data/spec/git_helper/change_remote_spec.rb +17 -17
  26. data/spec/git_helper/checkout_default_spec.rb +2 -0
  27. data/spec/git_helper/clean_branches_spec.rb +2 -0
  28. data/spec/git_helper/code_request_spec.rb +2 -0
  29. data/spec/git_helper/empty_commit_spec.rb +2 -0
  30. data/spec/git_helper/forget_local_commits_spec.rb +2 -0
  31. data/spec/git_helper/git_config_reader_spec.rb +4 -2
  32. data/spec/git_helper/gitlab_client_spec.rb +2 -0
  33. data/spec/git_helper/highline_cli_spec.rb +7 -5
  34. data/spec/git_helper/local_code_spec.rb +2 -0
  35. data/spec/git_helper/merge_request_spec.rb +8 -7
  36. data/spec/git_helper/new_branch_spec.rb +2 -0
  37. data/spec/git_helper/octokit_client_spec.rb +2 -0
  38. data/spec/git_helper/pull_request_spec.rb +5 -3
  39. data/spec/git_helper/setup_spec.rb +12 -7
  40. data/spec/spec_helper.rb +3 -1
  41. metadata +17 -3
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module GitHelper
2
4
  class GitLabMergeRequest
3
5
  attr_accessor :local_project, :local_branch, :local_code, :cli, :base_branch, :new_mr_title
@@ -9,70 +11,74 @@ module GitHelper
9
11
  @cli = options[:cli]
10
12
  end
11
13
 
14
+ # rubocop:disable Metrics/MethodLength
15
+ # rubocop:disable Metrics/AbcSize
12
16
  def create(options)
13
17
  @base_branch = options[:base_branch]
14
18
  @new_mr_title = options[:new_title]
15
19
 
16
- begin
17
- options = {
18
- source_branch: local_branch,
19
- target_branch: base_branch,
20
- squash: squash_merge_request,
21
- remove_source_branch: remove_source_branch,
22
- description: new_mr_body
23
- }
24
-
25
- puts "Creating merge request: #{new_mr_title}"
26
- mr = gitlab_client.create_merge_request(local_project, new_mr_title, options)
27
-
28
- if mr.diff_refs.base_sha == mr.diff_refs.head_sha
29
- puts "Merge request was created, but no commits have been pushed to GitLab: #{mr.web_url}"
30
- else
31
- puts "Merge request successfully created: #{mr.web_url}"
32
- end
33
- rescue Gitlab::Error::Conflict => e
34
- puts 'Could not create merge request:'
35
- puts ' A merge request already exists for this branch'
36
- rescue Exception => e
37
- puts 'Could not create merge request:'
38
- puts e.message
20
+ options = {
21
+ source_branch: local_branch,
22
+ target_branch: base_branch,
23
+ squash: squash_merge_request,
24
+ remove_source_branch: remove_source_branch,
25
+ description: new_mr_body
26
+ }
27
+
28
+ puts "Creating merge request: #{new_mr_title}"
29
+ mr = gitlab_client.create_merge_request(local_project, new_mr_title, options)
30
+
31
+ if mr.diff_refs.base_sha == mr.diff_refs.head_sha
32
+ puts "Merge request was created, but no commits have been pushed to GitLab: #{mr.web_url}"
33
+ else
34
+ puts "Merge request successfully created: #{mr.web_url}"
39
35
  end
36
+ rescue Gitlab::Error::Conflict
37
+ puts 'Could not create merge request:'
38
+ puts ' A merge request already exists for this branch'
39
+ rescue StandardError => e
40
+ puts 'Could not create merge request:'
41
+ puts e.message
40
42
  end
43
+ # rubocop:enable Metrics/AbcSize
44
+ # rubocop:enable Metrics/MethodLength
41
45
 
46
+ # rubocop:disable Metrics/MethodLength
47
+ # rubocop:disable Metrics/AbcSize
42
48
  def merge
43
- begin
44
- mr_id
45
- options = {
46
- should_remove_source_branch: existing_mr.should_remove_source_branch || existing_mr.force_remove_source_branch,
47
- squash: existing_mr.squash,
48
- squash_commit_message: existing_mr.title
49
- }
50
-
51
- puts "Merging merge request: #{mr_id}"
49
+ mr_id
50
+ options = {
51
+ should_remove_source_branch: existing_mr.should_remove_source_branch || existing_mr.force_remove_source_branch,
52
+ squash: existing_mr.squash,
53
+ squash_commit_message: existing_mr.title
54
+ }
55
+
56
+ puts "Merging merge request: #{mr_id}"
57
+ merge = gitlab_client.accept_merge_request(local_project, mr_id, options)
58
+
59
+ if merge.merge_commit_sha.nil?
60
+ options[:squash] = true
52
61
  merge = gitlab_client.accept_merge_request(local_project, mr_id, options)
62
+ end
53
63
 
54
- if merge.merge_commit_sha.nil?
55
- options[:squash] = true
56
- merge = gitlab_client.accept_merge_request(local_project, mr_id, options)
57
- end
58
-
59
- if merge.merge_commit_sha.nil?
60
- puts 'Could not merge merge request:'
61
- puts " #{merge.merge_error}"
62
- else
63
- puts "Merge request successfully merged: #{merge.merge_commit_sha}"
64
- end
65
- rescue Gitlab::Error::MethodNotAllowed => e
66
- puts 'Could not merge merge request:'
67
- puts ' The merge request is not mergeable'
68
- rescue Gitlab::Error::NotFound => e
64
+ if merge.merge_commit_sha.nil?
69
65
  puts 'Could not merge merge request:'
70
- puts " Could not a locate a merge request to merge with ID #{mr_id}"
71
- rescue Exception => e
72
- puts 'Could not merge merge request:'
73
- puts e.message
66
+ puts " #{merge.merge_error}"
67
+ else
68
+ puts "Merge request successfully merged: #{merge.merge_commit_sha}"
74
69
  end
70
+ rescue Gitlab::Error::MethodNotAllowed
71
+ puts 'Could not merge merge request:'
72
+ puts ' The merge request is not mergeable'
73
+ rescue Gitlab::Error::NotFound
74
+ puts 'Could not merge merge request:'
75
+ puts " Could not a locate a merge request to merge with ID #{mr_id}"
76
+ rescue StandardError => e
77
+ puts 'Could not merge merge request:'
78
+ puts e.message
75
79
  end
80
+ # rubocop:enable Metrics/AbcSize
81
+ # rubocop:enable Metrics/MethodLength
76
82
 
77
83
  private def new_mr_body
78
84
  @new_mr_body ||= template_name_to_apply ? local_code.read_template(template_name_to_apply) : ''
@@ -80,27 +86,38 @@ module GitHelper
80
86
 
81
87
  private def template_name_to_apply
82
88
  return @template_name_to_apply if @template_name_to_apply
89
+
83
90
  @template_name_to_apply = nil
84
91
 
85
- unless mr_template_options.empty?
86
- if mr_template_options.count == 1
87
- apply_single_template = cli.ask_yes_no("Apply the merge request template from #{mr_template_options.first}? (y/n)")
88
- @template_name_to_apply = mr_template_options.first if apply_single_template
89
- else
90
- response = cli.ask_options("Which merge request template should be applied?", mr_template_options << 'None')
91
- @template_name_to_apply = response unless response == 'None'
92
- end
93
- end
92
+ determine_template unless mr_template_options.empty?
94
93
 
95
94
  @template_name_to_apply
96
95
  end
97
96
 
97
+ # rubocop:disable Metrics/MethodLength
98
+ private def determine_template
99
+ if mr_template_options.count == 1
100
+ apply_single_template = cli.ask_yes_no(
101
+ "Apply the merge request template from #{mr_template_options.first}? (y/n)"
102
+ )
103
+ @template_name_to_apply = mr_template_options.first if apply_single_template
104
+ else
105
+ response = cli.ask_options(
106
+ 'Which merge request template should be applied?', mr_template_options << 'None'
107
+ )
108
+ @template_name_to_apply = response unless response == 'None'
109
+ end
110
+ end
111
+ # rubocop:enable Metrics/MethodLength
112
+
98
113
  private def mr_template_options
99
- @mr_template_options ||= local_code.template_options({
100
- template_directory: '.gitlab',
101
- nested_directory_name: 'merge_request_templates',
102
- non_nested_file_name: 'merge_request_template'
103
- })
114
+ @mr_template_options ||= local_code.template_options(
115
+ {
116
+ template_directory: '.gitlab',
117
+ nested_directory_name: 'merge_request_templates',
118
+ non_nested_file_name: 'merge_request_template'
119
+ }
120
+ )
104
121
  end
105
122
 
106
123
  private def mr_id
@@ -112,7 +129,10 @@ module GitHelper
112
129
  end
113
130
 
114
131
  private def remove_source_branch
115
- @remove_source_branch ||= existing_project.remove_source_branch_after_merge || cli.ask_yes_no('Remove source branch after merging? (y/n)')
132
+ @remove_source_branch ||=
133
+ existing_project.remove_source_branch_after_merge || cli.ask_yes_no(
134
+ 'Remove source branch after merging? (y/n)'
135
+ )
116
136
  end
117
137
 
118
138
  private def existing_project
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module GitHelper
2
4
  class NewBranch
3
5
  def execute(new_branch_name = nil)
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module GitHelper
2
4
  class OctokitClient
3
5
  def client
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module GitHelper
2
4
  class GitHubPullRequest
3
5
  attr_accessor :local_repo, :local_branch, :local_code, :cli, :base_branch, :new_pr_title
@@ -9,67 +11,79 @@ module GitHelper
9
11
  @cli = options[:cli]
10
12
  end
11
13
 
14
+ # rubocop:disable Metrics/MethodLength
15
+ # rubocop:disable Metrics/AbcSize
12
16
  def create(options)
13
17
  @base_branch = options[:base_branch]
14
18
  @new_pr_title = options[:new_title]
15
19
 
16
- begin
17
- new_pr_body
20
+ new_pr_body
18
21
 
19
- puts "Creating pull request: #{new_pr_title}"
20
- pr = octokit_client.create_pull_request(local_repo, base_branch, local_branch, new_pr_title, new_pr_body)
21
- puts "Pull request successfully created: #{pr.html_url}"
22
- rescue Octokit::UnprocessableEntity => e
23
- puts 'Could not create pull request:'
24
- if e.message.include?('pull request already exists')
25
- puts ' A pull request already exists for this branch'
26
- elsif e.message.include?('No commits between')
27
- puts ' No commits have been pushed to GitHub'
28
- else
29
- puts e.message
30
- end
31
- rescue Exception => e
32
- puts 'Could not create pull request:'
22
+ puts "Creating pull request: #{new_pr_title}"
23
+ pr = octokit_client.create_pull_request(
24
+ local_repo,
25
+ base_branch,
26
+ local_branch,
27
+ new_pr_title,
28
+ new_pr_body
29
+ )
30
+ puts "Pull request successfully created: #{pr.html_url}"
31
+ rescue Octokit::UnprocessableEntity => e
32
+ puts 'Could not create pull request:'
33
+ if e.message.include?('pull request already exists')
34
+ puts ' A pull request already exists for this branch'
35
+ elsif e.message.include?('No commits between')
36
+ puts ' No commits have been pushed to GitHub'
37
+ else
33
38
  puts e.message
34
39
  end
40
+ rescue StandardError => e
41
+ puts 'Could not create pull request:'
42
+ puts e.message
35
43
  end
44
+ # rubocop:enable Metrics/AbcSize
45
+ # rubocop:enable Metrics/MethodLength
36
46
 
47
+ # rubocop:disable Metrics/MethodLength
48
+ # rubocop:disable Metrics/AbcSize
37
49
  def merge
38
- begin
39
- pr_id
40
- merge_method
41
-
42
- puts "Merging pull request: #{pr_id}"
43
- merge = octokit_client.merge_pull_request(local_repo, pr_id, existing_pr.title, { merge_method: merge_method })
44
- puts "Pull request successfully merged: #{merge.sha}"
45
- rescue Octokit::UnprocessableEntity => e
46
- puts 'Could not merge pull request:'
47
- puts e.message
48
- rescue Octokit::NotFound => e
49
- puts 'Could not merge pull request:'
50
- puts " Could not a locate a pull request to merge with ID #{pr_id}"
51
- rescue Octokit::MethodNotAllowed => e
52
- puts 'Could not merge pull request:'
53
- if e.message.include?('405 - Required status check')
54
- puts ' A required status check has not passed'
55
- elsif e.message.include?('405 - Base branch was modified')
56
- puts ' The base branch has been modified'
57
- elsif e.message.include?('405 - Pull Request is not mergeable')
58
- puts ' The pull request is not mergeable'
59
- elsif e.message.include?('405 - Rebase merges are not allowed on this repository')
60
- puts ' Rebase merges are not allowed on this repository'
61
- elsif e.message.include?('405 - Merge commits are not allowed on this repository')
62
- puts ' Merge commits are not allowed on this repository'
63
- elsif e.message.include?('405 - Squash commits are not allowed on this repository')
64
- puts ' Squash merges are not allowed on this repository'
65
- else
66
- puts e.message
67
- end
68
- rescue Exception => e
69
- puts 'Could not merge pull request:'
50
+ pr_id
51
+ merge_method
52
+
53
+ puts "Merging pull request: #{pr_id}"
54
+ merge = octokit_client.merge_pull_request(
55
+ local_repo,
56
+ pr_id,
57
+ existing_pr.title,
58
+ { merge_method: merge_method }
59
+ )
60
+ puts "Pull request successfully merged: #{merge.sha}"
61
+ rescue Octokit::NotFound
62
+ puts 'Could not merge pull request:'
63
+ puts " Could not a locate a pull request to merge with ID #{pr_id}"
64
+ rescue Octokit::MethodNotAllowed => e
65
+ puts 'Could not merge pull request:'
66
+ if e.message.include?('405 - Required status check')
67
+ puts ' A required status check has not passed'
68
+ elsif e.message.include?('405 - Base branch was modified')
69
+ puts ' The base branch has been modified'
70
+ elsif e.message.include?('405 - Pull Request is not mergeable')
71
+ puts ' The pull request is not mergeable'
72
+ elsif e.message.include?('405 - Rebase merges are not allowed on this repository')
73
+ puts ' Rebase merges are not allowed on this repository'
74
+ elsif e.message.include?('405 - Merge commits are not allowed on this repository')
75
+ puts ' Merge commits are not allowed on this repository'
76
+ elsif e.message.include?('405 - Squash commits are not allowed on this repository')
77
+ puts ' Squash merges are not allowed on this repository'
78
+ else
70
79
  puts e.message
71
80
  end
81
+ rescue StandardError => e
82
+ puts 'Could not merge pull request:'
83
+ puts e.message
72
84
  end
85
+ # rubocop:enable Metrics/AbcSize
86
+ # rubocop:enable Metrics/MethodLength
73
87
 
74
88
  private def new_pr_body
75
89
  @new_pr_body ||= template_name_to_apply ? local_code.read_template(template_name_to_apply) : ''
@@ -77,27 +91,38 @@ module GitHelper
77
91
 
78
92
  private def template_name_to_apply
79
93
  return @template_name_to_apply if @template_name_to_apply
94
+
80
95
  @template_name_to_apply = nil
81
96
 
82
- unless pr_template_options.empty?
83
- if pr_template_options.count == 1
84
- apply_single_template = cli.ask_yes_no("Apply the pull request template from #{pr_template_options.first}? (y/n)")
85
- @template_name_to_apply = pr_template_options.first if apply_single_template
86
- else
87
- response = cli.ask_options("Which pull request template should be applied?", pr_template_options << 'None')
88
- @template_name_to_apply = response unless response == 'None'
89
- end
90
- end
97
+ determine_template unless pr_template_options.empty?
91
98
 
92
99
  @template_name_to_apply
93
100
  end
94
101
 
102
+ # rubocop:disable Metrics/MethodLength
103
+ private def determine_template
104
+ if pr_template_options.count == 1
105
+ apply_single_template = cli.ask_yes_no(
106
+ "Apply the pull request template from #{pr_template_options.first}? (y/n)"
107
+ )
108
+ @template_name_to_apply = pr_template_options.first if apply_single_template
109
+ else
110
+ response = cli.ask_options(
111
+ 'Which pull request template should be applied?', pr_template_options << 'None'
112
+ )
113
+ @template_name_to_apply = response unless response == 'None'
114
+ end
115
+ end
116
+ # rubocop:enable Metrics/MethodLength
117
+
95
118
  private def pr_template_options
96
- @pr_template_options ||= local_code.template_options({
97
- template_directory: '.github',
98
- nested_directory_name: 'PULL_REQUEST_TEMPLATE',
99
- non_nested_file_name: 'pull_request_template'
100
- })
119
+ @pr_template_options ||= local_code.template_options(
120
+ {
121
+ template_directory: '.github',
122
+ nested_directory_name: 'PULL_REQUEST_TEMPLATE',
123
+ non_nested_file_name: 'pull_request_template'
124
+ }
125
+ )
101
126
  end
102
127
 
103
128
  private def pr_id
@@ -105,11 +130,17 @@ module GitHelper
105
130
  end
106
131
 
107
132
  private def merge_method
108
- @merge_method ||= merge_options.length == 1 ? merge_options.first : cli.ask_options('Merge method?', merge_options)
133
+ @merge_method ||=
134
+ if merge_options.length == 1
135
+ merge_options.first
136
+ else
137
+ cli.ask_options('Merge method?', merge_options)
138
+ end
109
139
  end
110
140
 
111
141
  private def merge_options
112
142
  return @merge_options if @merge_options
143
+
113
144
  merge_options = []
114
145
  merge_options << 'merge' if existing_project.allow_merge_commit
115
146
  merge_options << 'squash' if existing_project.allow_squash_merge
@@ -1,25 +1,37 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module GitHelper
2
4
  class Setup
3
5
  def execute
6
+ execute_config_file
7
+ execute_plugins
8
+ end
9
+
10
+ private def execute_config_file
4
11
  if config_file_exists?
5
- answer = highline.ask_yes_no("It looks like the #{config_file} file already exists. Do you wish to replace it? (y/n)")
12
+ answer = highline.ask_yes_no(
13
+ "It looks like the #{config_file} file already exists. Do you wish to replace it? (y/n)"
14
+ )
6
15
  puts
7
16
  else
8
17
  answer = true
9
18
  end
10
19
 
11
20
  create_or_update_config_file if answer
21
+ end
12
22
 
23
+ private def execute_plugins
13
24
  answer = highline.ask_yes_no(
14
- "Do you wish to set up the Git Helper plugins? (y/n) (This process will " \
15
- "attempt to use your GitHub personal access token to authenticate)"
25
+ 'Do you wish to set up the Git Helper plugins? (y/n) (This process will ' \
26
+ 'attempt to use your GitHub personal access token to authenticate)'
16
27
  )
17
28
 
18
- if answer
19
- create_or_update_plugin_files
20
- puts "\nNow add this line to your ~/.bash_profile:\n export PATH=/path/to/computer/home/.git_helper/plugins:$PATH"
21
- puts "\nDone!"
22
- end
29
+ return unless answer
30
+
31
+ create_or_update_plugin_files
32
+ puts "\nNow add this line to your ~/.bash_profile:\n" \
33
+ ' export PATH=/path/to/computer/home/.git_helper/plugins:$PATH'
34
+ puts "\nDone!"
23
35
  end
24
36
 
25
37
  private def create_or_update_config_file
@@ -30,28 +42,32 @@ module GitHelper
30
42
  end
31
43
 
32
44
  private def config_file_exists?
33
- File.exists?(config_file)
45
+ File.exist?(config_file)
34
46
  end
35
47
 
48
+ # rubocop:disable Metrics/MethodLength
36
49
  private def generate_file_contents
37
- file_contents = ''
50
+ file_contents = ''.dup
38
51
 
39
- if highline.ask_yes_no("Do you wish to set up GitHub credentials? (y/n)")
52
+ if highline.ask_yes_no('Do you wish to set up GitHub credentials? (y/n)')
40
53
  file_contents << ":github_user: #{ask_question('GitHub username?')}\n"
41
- file_contents << ":github_token: " \
54
+ file_contents << ':github_token: ' \
42
55
  "#{ask_question('GitHub personal access token? (Navigate to https://github.com/settings/tokens ' \
43
56
  'to create a new personal access token)')}\n"
44
57
  end
45
58
 
46
59
  if highline.ask_yes_no("\nDo you wish to set up GitLab credentials? (y/n)")
47
60
  file_contents << ":gitlab_user: #{ask_question('GitLab username?')}\n"
48
- file_contents << ":gitlab_token: " \
49
- "#{ask_question('GitLab personal access token? (Navigate to https://gitlab.com/-/profile/personal_access_tokens ' \
50
- 'to create a new personal access token)')}\n"
61
+ file_contents << ':gitlab_token: ' \
62
+ "#{ask_question(
63
+ 'GitLab personal access token? (Navigate to https://gitlab.com/-/profile/personal_access_tokens' \
64
+ ' to create a new personal access token)'
65
+ )}\n"
51
66
  end
52
67
 
53
68
  file_contents.strip
54
69
  end
70
+ # rubocop:enable Metrics/MethodLength
55
71
 
56
72
  private def ask_question(prompt)
57
73
  answer = highline.ask("\n#{prompt}")
@@ -64,14 +80,16 @@ module GitHelper
64
80
  end
65
81
  end
66
82
 
83
+ # rubocop:disable Metrics/MethodLength
84
+ # rubocop:disable Metrics/AbcSize
67
85
  private def create_or_update_plugin_files
68
- plugins_dir = "#{Dir.pwd.scan(/\A\/[\w]*\/[\w]*\//).first}/.git_helper/plugins"
86
+ plugins_dir = "#{Dir.pwd.scan(%r{\A/\w*/\w*/}).first}.git_helper/plugins"
69
87
  plugins_url = 'https://api.github.com/repos/emmahsax/git_helper/contents/plugins'
70
88
  header = 'Accept: application/vnd.github.v3.raw'
71
89
  token = git_config_reader.github_token
72
90
  user = git_config_reader.github_user
73
91
 
74
- Dir.mkdir(plugins_dir) unless File.exists?(plugins_dir)
92
+ Dir.mkdir(plugins_dir) unless File.exist?(plugins_dir)
75
93
 
76
94
  all_plugins = JSON.parse(`curl -s -u #{user}:#{token} -H "#{header}" -L "#{plugins_url}"`)
77
95
 
@@ -80,6 +98,8 @@ module GitHelper
80
98
  File.open("#{plugins_dir}/#{plugin['name']}", 'w') { |file| file.puts plugin_content }
81
99
  end
82
100
  end
101
+ # rubocop:enable Metrics/MethodLength
102
+ # rubocop:enable Metrics/AbcSize
83
103
 
84
104
  private def config_file
85
105
  git_config_reader.git_config_file_path