git_helper 1.3.1 → 2.0.0
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.
- checksums.yaml +4 -4
- data/Gemfile.lock +17 -13
- data/README.md +24 -38
- data/bin/git-helper +12 -23
- data/lib/git_helper/change_remote.rb +56 -40
- data/lib/git_helper/checkout_default.rb +3 -1
- data/lib/git_helper/clean_branches.rb +3 -4
- data/lib/git_helper/code_request.rb +100 -0
- data/lib/git_helper/empty_commit.rb +3 -1
- data/lib/git_helper/forget_local_commits.rb +9 -0
- data/lib/git_helper/highline_cli.rb +20 -15
- data/lib/git_helper/local_code.rb +67 -19
- data/lib/git_helper/merge_request.rb +44 -70
- data/lib/git_helper/new_branch.rb +2 -10
- data/lib/git_helper/pull_request.rb +33 -65
- data/lib/git_helper/version.rb +1 -1
- data/spec/git_helper/change_remote_spec.rb +172 -0
- data/spec/git_helper/checkout_default_spec.rb +18 -0
- data/spec/git_helper/clean_branches_spec.rb +18 -0
- data/spec/git_helper/code_request_spec.rb +258 -0
- data/spec/git_helper/empty_commit_spec.rb +18 -0
- data/spec/git_helper/forget_local_commits_spec.rb +18 -0
- data/spec/git_helper/git_config_reader_spec.rb +59 -0
- data/spec/git_helper/gitlab_client_spec.rb +25 -0
- data/spec/git_helper/highline_cli_spec.rb +214 -0
- data/spec/git_helper/local_code_spec.rb +230 -0
- data/spec/git_helper/merge_request_spec.rb +233 -0
- data/spec/git_helper/new_branch_spec.rb +43 -0
- data/spec/git_helper/octokit_client_spec.rb +25 -0
- data/spec/git_helper/pull_request_spec.rb +245 -0
- data/spec/spec_helper.rb +0 -6
- metadata +36 -20
@@ -6,6 +6,15 @@ module GitHelper
|
|
6
6
|
ask('New branch name?')
|
7
7
|
end
|
8
8
|
|
9
|
+
def process_directory_remotes?(directory)
|
10
|
+
answer = ask("Found git directory: #{directory}. Do you wish to proceed in updating #{directory}'s remote URLs? (y/n)")
|
11
|
+
answer.empty? ? true : !!(answer =~ /^y/i)
|
12
|
+
end
|
13
|
+
|
14
|
+
def conflicting_remote_clarification
|
15
|
+
ask('Found git remotes for both GitHub and GitLab. Would you like to proceed with GitLab or GitHub? (github/gitlab)').downcase
|
16
|
+
end
|
17
|
+
|
9
18
|
def title
|
10
19
|
ask('Title?')
|
11
20
|
end
|
@@ -14,33 +23,29 @@ module GitHelper
|
|
14
23
|
ask('Base branch?')
|
15
24
|
end
|
16
25
|
|
17
|
-
def
|
18
|
-
ask(
|
19
|
-
end
|
20
|
-
|
21
|
-
def pull_request_id
|
22
|
-
ask('Pull Request ID?')
|
26
|
+
def code_request_id(request_type)
|
27
|
+
ask("#{request_type} Request ID?")
|
23
28
|
end
|
24
29
|
|
25
30
|
def accept_autogenerated_title?(autogenerated_title)
|
26
31
|
return false unless autogenerated_title
|
27
|
-
answer = ask("Accept the autogenerated
|
28
|
-
!!(answer =~ /^y/i)
|
32
|
+
answer = ask("Accept the autogenerated code request title '#{autogenerated_title}'? (y/n)")
|
33
|
+
answer.empty? ? true : !!(answer =~ /^y/i)
|
29
34
|
end
|
30
35
|
|
31
36
|
def base_branch_default?(default_branch)
|
32
|
-
answer = ask("Is '#{default_branch}' the correct base branch for your new
|
33
|
-
!!(answer =~ /^y/i)
|
37
|
+
answer = ask("Is '#{default_branch}' the correct base branch for your new code request? (y/n)")
|
38
|
+
answer.empty? ? true : !!(answer =~ /^y/i)
|
34
39
|
end
|
35
40
|
|
36
41
|
def squash_merge_request?
|
37
42
|
answer = ask('Squash merge request? (y/n)')
|
38
|
-
!!(answer =~ /^y/i)
|
43
|
+
answer.empty? ? true : !!(answer =~ /^y/i)
|
39
44
|
end
|
40
45
|
|
41
46
|
def remove_source_branch?
|
42
47
|
answer = ask('Remove source branch after merging? (y/n)')
|
43
|
-
!!(answer =~ /^y/i)
|
48
|
+
answer.empty? ? true : !!(answer =~ /^y/i)
|
44
49
|
end
|
45
50
|
|
46
51
|
def merge_method(merge_options)
|
@@ -48,9 +53,9 @@ module GitHelper
|
|
48
53
|
merge_options[index]
|
49
54
|
end
|
50
55
|
|
51
|
-
def apply_template?(template_file_name)
|
52
|
-
answer = ask("Apply the
|
53
|
-
!!(answer =~ /^y/i)
|
56
|
+
def apply_template?(template_file_name, request_type)
|
57
|
+
answer = ask("Apply the #{request_type} request template from #{template_file_name}? (y/n)")
|
58
|
+
answer.empty? ? true : !!(answer =~ /^y/i)
|
54
59
|
end
|
55
60
|
|
56
61
|
def template_to_apply(template_options, request_type)
|
@@ -1,5 +1,25 @@
|
|
1
1
|
module GitHelper
|
2
2
|
class LocalCode
|
3
|
+
def checkout_default
|
4
|
+
system("git checkout $(git symbolic-ref refs/remotes/origin/HEAD | sed \"s@^refs/remotes/origin/@@\")")
|
5
|
+
end
|
6
|
+
|
7
|
+
def forget_local_commits
|
8
|
+
system("git pull")
|
9
|
+
system("git reset --hard origin/HEAD")
|
10
|
+
end
|
11
|
+
|
12
|
+
def empty_commit
|
13
|
+
system("git commit --allow-empty -m \"Empty commit\"")
|
14
|
+
end
|
15
|
+
|
16
|
+
def clean_branches
|
17
|
+
system("git checkout $(git symbolic-ref refs/remotes/origin/HEAD | sed \"s@^refs/remotes/origin/@@\")")
|
18
|
+
system("git pull")
|
19
|
+
system("git fetch -p")
|
20
|
+
system("git branch -vv | grep \"origin/.*: gone]\" | awk '{print \$1}' | grep -v \"*\" | xargs git branch -D")
|
21
|
+
end
|
22
|
+
|
3
23
|
def new_branch(branch_name)
|
4
24
|
system("git pull")
|
5
25
|
system("git branch --no-track #{branch_name}")
|
@@ -7,7 +27,51 @@ module GitHelper
|
|
7
27
|
system("git push --set-upstream origin #{branch_name}")
|
8
28
|
end
|
9
29
|
|
10
|
-
def
|
30
|
+
def change_remote(remote_name, remote_url)
|
31
|
+
`git remote set-url #{remote_name} #{remote_url}`
|
32
|
+
end
|
33
|
+
|
34
|
+
def remotes
|
35
|
+
`git remote -v`.split("\n")
|
36
|
+
end
|
37
|
+
|
38
|
+
def remote_name(remote)
|
39
|
+
remote.scan(/([a-zA-z]+)/).first.first
|
40
|
+
end
|
41
|
+
|
42
|
+
def ssh_remote?(remote)
|
43
|
+
remote.scan(/(git@)/).any?
|
44
|
+
end
|
45
|
+
|
46
|
+
def https_remote?(remote)
|
47
|
+
remote.scan(/(https:\/\/)/).any?
|
48
|
+
end
|
49
|
+
|
50
|
+
def remote_project(remote)
|
51
|
+
if https_remote?(remote)
|
52
|
+
remote.scan(/https:\/\/[\S]+\/([\S]*).git/).first.first
|
53
|
+
elsif ssh_remote?(remote)
|
54
|
+
remote.scan(/\/([\S]*).git/).first.first
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def remote_source(remote)
|
59
|
+
if https_remote?(remote)
|
60
|
+
remote.scan(/https:\/\/([a-zA-z.]+)\//).first.first
|
61
|
+
elsif ssh_remote?(remote)
|
62
|
+
remote.scan(/git@([a-zA-z.]+):/).first.first
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def github_repo?
|
67
|
+
remotes.select { |remote| remote.include?('github') }.any?
|
68
|
+
end
|
69
|
+
|
70
|
+
def gitlab_project?
|
71
|
+
remotes.select { |remote| remote.include?('gitlab') }.any?
|
72
|
+
end
|
73
|
+
|
74
|
+
def project_name
|
11
75
|
# Get the repo/project name by looking in the remote URLs for the full name
|
12
76
|
`git remote -v`.scan(/\S[\s]*[\S]+.com[\S]{1}([\S]*).git/).first.first
|
13
77
|
end
|
@@ -17,24 +81,8 @@ module GitHelper
|
|
17
81
|
`git branch`.scan(/\*\s([\S]*)/).first.first
|
18
82
|
end
|
19
83
|
|
20
|
-
def default_branch
|
21
|
-
|
22
|
-
external_client.repository(project_name).default_branch
|
23
|
-
elsif client_type == :gitlab # GitLab project
|
24
|
-
page_number = 1
|
25
|
-
counter = 1
|
26
|
-
branches = []
|
27
|
-
|
28
|
-
while counter > 0
|
29
|
-
break if default_branch = branches.select { |branch| branch.default }.first
|
30
|
-
page_branches = external_client.branches(project_name, page: page_number, per_page: 100)
|
31
|
-
branches = page_branches
|
32
|
-
counter = page_branches.count
|
33
|
-
page_number += 1
|
34
|
-
end
|
35
|
-
|
36
|
-
default_branch.name
|
37
|
-
end
|
84
|
+
def default_branch
|
85
|
+
`git symbolic-ref refs/remotes/origin/HEAD | sed "s@^refs/remotes/origin/@@" | tr -d "\n"`
|
38
86
|
end
|
39
87
|
|
40
88
|
def template_options(template_identifiers)
|
@@ -4,11 +4,20 @@ require_relative './local_code.rb'
|
|
4
4
|
|
5
5
|
module GitHelper
|
6
6
|
class GitLabMergeRequest
|
7
|
-
|
7
|
+
attr_accessor :local_project, :local_branch, :local_code, :cli, :base_branch, :new_mr_title
|
8
|
+
|
9
|
+
def initialize(options)
|
10
|
+
@local_project = options[:local_project]
|
11
|
+
@local_branch = options[:local_branch]
|
12
|
+
@local_code = options[:local_code]
|
13
|
+
@cli = options[:cli]
|
14
|
+
end
|
15
|
+
|
16
|
+
def create(options)
|
17
|
+
@base_branch = options[:base_branch]
|
18
|
+
@new_mr_title = options[:new_title]
|
19
|
+
|
8
20
|
begin
|
9
|
-
# Ask these questions right away
|
10
|
-
base_branch
|
11
|
-
new_mr_title
|
12
21
|
options = {
|
13
22
|
source_branch: local_branch,
|
14
23
|
target_branch: base_branch,
|
@@ -36,12 +45,12 @@ module GitHelper
|
|
36
45
|
|
37
46
|
def merge
|
38
47
|
begin
|
39
|
-
# Ask these questions right away
|
40
48
|
mr_id
|
41
|
-
options = {
|
42
|
-
|
43
|
-
|
44
|
-
|
49
|
+
options = {
|
50
|
+
should_remove_source_branch: existing_mr.should_remove_source_branch || existing_mr.force_remove_source_branch,
|
51
|
+
squash: existing_mr.squash,
|
52
|
+
squash_commit_message: existing_mr.title
|
53
|
+
}
|
45
54
|
|
46
55
|
puts "Merging merge request: #{mr_id}"
|
47
56
|
merge = gitlab_client.accept_merge_request(local_project, mr_id, options)
|
@@ -51,7 +60,12 @@ module GitHelper
|
|
51
60
|
merge = gitlab_client.accept_merge_request(local_project, mr_id, options)
|
52
61
|
end
|
53
62
|
|
54
|
-
|
63
|
+
if merge.merge_commit_sha.nil?
|
64
|
+
puts 'Could not merge merge request:'
|
65
|
+
puts " #{merge.merge_error}"
|
66
|
+
else
|
67
|
+
puts "Merge request successfully merged: #{merge.merge_commit_sha}"
|
68
|
+
end
|
55
69
|
rescue Gitlab::Error::MethodNotAllowed => e
|
56
70
|
puts 'Could not merge merge request:'
|
57
71
|
puts ' The merge request is not mergeable'
|
@@ -64,31 +78,36 @@ module GitHelper
|
|
64
78
|
end
|
65
79
|
end
|
66
80
|
|
67
|
-
private def
|
68
|
-
@
|
81
|
+
private def new_mr_body
|
82
|
+
@new_mr_body ||= template_name_to_apply ? local_code.read_template(template_name_to_apply) : ''
|
69
83
|
end
|
70
84
|
|
71
|
-
private def
|
72
|
-
@
|
73
|
-
|
85
|
+
private def template_name_to_apply
|
86
|
+
return @template_name_to_apply if @template_name_to_apply
|
87
|
+
@template_name_to_apply = nil
|
74
88
|
|
75
|
-
|
76
|
-
|
77
|
-
|
89
|
+
unless mr_template_options.empty?
|
90
|
+
if mr_template_options.count == 1
|
91
|
+
apply_single_template = cli.apply_template?(mr_template_options.first, 'merge')
|
92
|
+
@template_name_to_apply = mr_template_options.first if apply_single_template
|
93
|
+
else
|
94
|
+
response = cli.template_to_apply(mr_template_options, 'merge')
|
95
|
+
@template_name_to_apply = response unless response == 'None'
|
96
|
+
end
|
97
|
+
end
|
78
98
|
|
79
|
-
|
80
|
-
@default_branch ||= local_code.default_branch(local_project, gitlab_client, :gitlab)
|
99
|
+
@template_name_to_apply
|
81
100
|
end
|
82
101
|
|
83
102
|
private def mr_template_options
|
84
103
|
@mr_template_options ||= local_code.template_options({
|
85
|
-
nested_directory_name:
|
86
|
-
non_nested_file_name:
|
104
|
+
nested_directory_name: 'merge_request_templates',
|
105
|
+
non_nested_file_name: 'merge_request_template'
|
87
106
|
})
|
88
107
|
end
|
89
108
|
|
90
109
|
private def mr_id
|
91
|
-
@mr_id ||= cli.
|
110
|
+
@mr_id ||= cli.code_request_id('Merge')
|
92
111
|
end
|
93
112
|
|
94
113
|
private def squash_merge_request
|
@@ -99,61 +118,16 @@ module GitHelper
|
|
99
118
|
@remove_source_branch ||= existing_project.remove_source_branch_after_merge || cli.remove_source_branch?
|
100
119
|
end
|
101
120
|
|
102
|
-
private def
|
103
|
-
@
|
104
|
-
autogenerated_title
|
105
|
-
else
|
106
|
-
cli.title
|
107
|
-
end
|
108
|
-
end
|
109
|
-
|
110
|
-
private def base_branch
|
111
|
-
@base_branch ||= if cli.base_branch_default?(default_branch)
|
112
|
-
default_branch
|
113
|
-
else
|
114
|
-
cli.base_branch
|
115
|
-
end
|
116
|
-
end
|
117
|
-
|
118
|
-
private def new_mr_body
|
119
|
-
@new_mr_body ||= template_name_to_apply ? local_code.read_template(template_name_to_apply) : ''
|
120
|
-
end
|
121
|
-
|
122
|
-
private def template_name_to_apply
|
123
|
-
return @template_name_to_apply if @template_name_to_apply
|
124
|
-
@template_name_to_apply = nil
|
125
|
-
|
126
|
-
unless mr_template_options.empty?
|
127
|
-
if mr_template_options.count == 1
|
128
|
-
apply_single_template = cli.apply_template?(mr_template_options.first)
|
129
|
-
@template_name_to_apply = mr_template_options.first if apply_single_template
|
130
|
-
else
|
131
|
-
response = cli.template_to_apply(mr_template_options, 'merge')
|
132
|
-
@template_name_to_apply = response unless response == "None"
|
133
|
-
end
|
134
|
-
end
|
135
|
-
|
136
|
-
@template_name_to_apply
|
121
|
+
private def existing_project
|
122
|
+
@existing_project ||= gitlab_client.project(local_project)
|
137
123
|
end
|
138
124
|
|
139
125
|
private def existing_mr
|
140
126
|
@existing_mr ||= gitlab_client.merge_request(local_project, mr_id)
|
141
127
|
end
|
142
128
|
|
143
|
-
private def existing_project
|
144
|
-
@existing_project ||= gitlab_client.project(local_project)
|
145
|
-
end
|
146
|
-
|
147
129
|
private def gitlab_client
|
148
130
|
@gitlab_client ||= GitHelper::GitLabClient.new.client
|
149
131
|
end
|
150
|
-
|
151
|
-
private def cli
|
152
|
-
@cli ||= GitHelper::HighlineCli.new
|
153
|
-
end
|
154
|
-
|
155
|
-
private def local_code
|
156
|
-
@local_code ||= GitHelper::LocalCode.new
|
157
|
-
end
|
158
132
|
end
|
159
133
|
end
|
@@ -4,17 +4,9 @@ require_relative './local_code.rb'
|
|
4
4
|
module GitHelper
|
5
5
|
class NewBranch
|
6
6
|
def execute(new_branch_name = nil)
|
7
|
-
branch_name = new_branch_name ||
|
7
|
+
branch_name = new_branch_name || GitHelper::HighlineCli.new.new_branch_name
|
8
8
|
puts "Attempting to create a new branch: #{branch_name}"
|
9
|
-
|
10
|
-
end
|
11
|
-
|
12
|
-
private def cli
|
13
|
-
@cli ||= GitHelper::HighlineCli.new
|
14
|
-
end
|
15
|
-
|
16
|
-
private def local_code
|
17
|
-
@local_code ||= GitHelper::LocalCode.new
|
9
|
+
GitHelper::LocalCode.new.new_branch(branch_name)
|
18
10
|
end
|
19
11
|
end
|
20
12
|
end
|
@@ -4,11 +4,20 @@ require_relative './local_code.rb'
|
|
4
4
|
|
5
5
|
module GitHelper
|
6
6
|
class GitHubPullRequest
|
7
|
-
|
7
|
+
attr_accessor :local_repo, :local_branch, :local_code, :cli, :base_branch, :new_pr_title
|
8
|
+
|
9
|
+
def initialize(options)
|
10
|
+
@local_repo = options[:local_project]
|
11
|
+
@local_branch = options[:local_branch]
|
12
|
+
@local_code = options[:local_code]
|
13
|
+
@cli = options[:cli]
|
14
|
+
end
|
15
|
+
|
16
|
+
def create(options)
|
17
|
+
@base_branch = options[:base_branch]
|
18
|
+
@new_pr_title = options[:new_title]
|
19
|
+
|
8
20
|
begin
|
9
|
-
# Ask these questions right away
|
10
|
-
base_branch
|
11
|
-
new_pr_title
|
12
21
|
new_pr_body
|
13
22
|
|
14
23
|
puts "Creating pull request: #{new_pr_title}"
|
@@ -31,7 +40,6 @@ module GitHelper
|
|
31
40
|
|
32
41
|
def merge
|
33
42
|
begin
|
34
|
-
# Ask these questions right away
|
35
43
|
pr_id
|
36
44
|
merge_method
|
37
45
|
|
@@ -67,31 +75,36 @@ module GitHelper
|
|
67
75
|
end
|
68
76
|
end
|
69
77
|
|
70
|
-
private def
|
71
|
-
@
|
78
|
+
private def new_pr_body
|
79
|
+
@new_pr_body ||= template_name_to_apply ? local_code.read_template(template_name_to_apply) : ''
|
72
80
|
end
|
73
81
|
|
74
|
-
private def
|
75
|
-
@
|
76
|
-
|
82
|
+
private def template_name_to_apply
|
83
|
+
return @template_name_to_apply if @template_name_to_apply
|
84
|
+
@template_name_to_apply = nil
|
77
85
|
|
78
|
-
|
79
|
-
|
80
|
-
|
86
|
+
unless pr_template_options.empty?
|
87
|
+
if pr_template_options.count == 1
|
88
|
+
apply_single_template = cli.apply_template?(pr_template_options.first, 'pull')
|
89
|
+
@template_name_to_apply = pr_template_options.first if apply_single_template
|
90
|
+
else
|
91
|
+
response = cli.template_to_apply(pr_template_options, 'pull')
|
92
|
+
@template_name_to_apply = response unless response == 'None'
|
93
|
+
end
|
94
|
+
end
|
81
95
|
|
82
|
-
|
83
|
-
@default_branch ||= local_code.default_branch(local_repo, octokit_client, :octokit)
|
96
|
+
@template_name_to_apply
|
84
97
|
end
|
85
98
|
|
86
99
|
private def pr_template_options
|
87
100
|
@pr_template_options ||= local_code.template_options({
|
88
|
-
nested_directory_name:
|
89
|
-
non_nested_file_name:
|
101
|
+
nested_directory_name: 'PULL_REQUEST_TEMPLATE',
|
102
|
+
non_nested_file_name: 'pull_request_template'
|
90
103
|
})
|
91
104
|
end
|
92
105
|
|
93
106
|
private def pr_id
|
94
|
-
@pr_id ||= cli.
|
107
|
+
@pr_id ||= cli.code_request_id('Pull')
|
95
108
|
end
|
96
109
|
|
97
110
|
private def merge_method
|
@@ -107,61 +120,16 @@ module GitHelper
|
|
107
120
|
@merge_options = merge_options
|
108
121
|
end
|
109
122
|
|
110
|
-
private def
|
111
|
-
@
|
112
|
-
autogenerated_title
|
113
|
-
else
|
114
|
-
cli.title
|
115
|
-
end
|
116
|
-
end
|
117
|
-
|
118
|
-
private def base_branch
|
119
|
-
@base_branch ||= if cli.base_branch_default?(default_branch)
|
120
|
-
default_branch
|
121
|
-
else
|
122
|
-
cli.base_branch
|
123
|
-
end
|
124
|
-
end
|
125
|
-
|
126
|
-
private def new_pr_body
|
127
|
-
@new_pr_body ||= template_name_to_apply ? local_code.read_template(template_name_to_apply) : ''
|
128
|
-
end
|
129
|
-
|
130
|
-
private def template_name_to_apply
|
131
|
-
return @template_name_to_apply if @template_name_to_apply
|
132
|
-
@template_name_to_apply = nil
|
133
|
-
|
134
|
-
unless pr_template_options.empty?
|
135
|
-
if pr_template_options.count == 1
|
136
|
-
apply_single_template = cli.apply_template?(pr_template_options.first)
|
137
|
-
@template_name_to_apply = pr_template_options.first if apply_single_template
|
138
|
-
else
|
139
|
-
response = cli.template_to_apply(pr_template_options, 'pull')
|
140
|
-
@template_name_to_apply = response unless response == "None"
|
141
|
-
end
|
142
|
-
end
|
143
|
-
|
144
|
-
@template_name_to_apply
|
123
|
+
private def existing_project
|
124
|
+
@existing_project ||= octokit_client.repository(local_repo)
|
145
125
|
end
|
146
126
|
|
147
127
|
private def existing_pr
|
148
128
|
@existing_pr ||= octokit_client.pull_request(local_repo, pr_id)
|
149
129
|
end
|
150
130
|
|
151
|
-
private def existing_project
|
152
|
-
@existing_project ||= octokit_client.repository(local_repo)
|
153
|
-
end
|
154
|
-
|
155
131
|
private def octokit_client
|
156
132
|
@octokit_client ||= GitHelper::OctokitClient.new.client
|
157
133
|
end
|
158
|
-
|
159
|
-
private def cli
|
160
|
-
@cli ||= GitHelper::HighlineCli.new
|
161
|
-
end
|
162
|
-
|
163
|
-
private def local_code
|
164
|
-
@local_code ||= GitHelper::LocalCode.new
|
165
|
-
end
|
166
134
|
end
|
167
135
|
end
|